aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-21 15:06:09 +0200
committerIngo Molnar <mingo@elte.hu>2008-07-21 15:06:09 +0200
commite66d90fb4abd0a27ee96f57a32fb561221c4d6ae (patch)
tree3337cba94c7444b06fdb0e8b487287d07b71f4a0 /drivers
parent55ca089e2579de90f048aca2a3030b8b2f864813 (diff)
parent14b395e35d1afdd8019d11b92e28041fad591b71 (diff)
Merge branch 'linus' into xen-64bit
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile4
-rw-r--r--drivers/acpi/bay.c3
-rw-r--r--drivers/acpi/dock.c3
-rw-r--r--drivers/acpi/glue.c3
-rw-r--r--drivers/atm/Kconfig79
-rw-r--r--drivers/atm/Makefile39
-rw-r--r--drivers/atm/fore200e.c130
-rw-r--r--drivers/atm/fore200e.h3
-rw-r--r--drivers/atm/fore200e_firmware_copyright31
-rw-r--r--drivers/atm/fore200e_mkfirm.c154
-rw-r--r--drivers/atm/he.c152
-rw-r--r--drivers/atm/he.h26
-rw-r--r--drivers/atm/iphase.c30
-rw-r--r--drivers/atm/pca200e.data850
-rw-r--r--drivers/atm/pca200e_ecd.data906
-rw-r--r--drivers/atm/sba200e_ecd.data928
-rw-r--r--drivers/atm/suni.c130
-rw-r--r--drivers/atm/suni.h40
-rw-r--r--drivers/block/ataflop.c4
-rw-r--r--drivers/bluetooth/Kconfig1
-rw-r--r--drivers/bluetooth/hci_bcsp.c44
-rw-r--r--drivers/bluetooth/hci_ldisc.c6
-rw-r--r--drivers/char/cyclades.c342
-rw-r--r--drivers/char/epca.c110
-rw-r--r--drivers/char/epca.h7
-rw-r--r--drivers/char/esp.c272
-rw-r--r--drivers/char/generic_serial.c158
-rw-r--r--drivers/char/ip2/i2lib.c4
-rw-r--r--drivers/char/ip2/ip2main.c7
-rw-r--r--drivers/char/isicom.c215
-rw-r--r--drivers/char/istallion.c116
-rw-r--r--drivers/char/moxa.c93
-rw-r--r--drivers/char/mxser.c284
-rw-r--r--drivers/char/n_hdlc.c6
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/nvram.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c32
-rw-r--r--drivers/char/pty.c10
-rw-r--r--drivers/char/rio/cirrus.h3
-rw-r--r--drivers/char/rio/cmdblk.h6
-rw-r--r--drivers/char/rio/cmdpkt.h6
-rw-r--r--drivers/char/rio/daemon.h6
-rw-r--r--drivers/char/rio/errors.h6
-rw-r--r--drivers/char/rio/func.h6
-rw-r--r--drivers/char/rio/map.h4
-rw-r--r--drivers/char/rio/param.h5
-rw-r--r--drivers/char/rio/parmmap.h7
-rw-r--r--drivers/char/rio/pci.h4
-rw-r--r--drivers/char/rio/protsts.h7
-rw-r--r--drivers/char/rio/rio_linux.c25
-rw-r--r--drivers/char/rio/rioboard.h6
-rw-r--r--drivers/char/rio/riocmd.c13
-rw-r--r--drivers/char/rio/rioctrl.c4
-rw-r--r--drivers/char/rio/riodrvr.h4
-rw-r--r--drivers/char/rio/rioinfo.h4
-rw-r--r--drivers/char/rio/rioinit.c3
-rw-r--r--drivers/char/rio/riointr.c14
-rw-r--r--drivers/char/rio/rioparam.c6
-rw-r--r--drivers/char/rio/rioroute.c3
-rw-r--r--drivers/char/rio/riospace.h4
-rw-r--r--drivers/char/rio/riotable.c3
-rw-r--r--drivers/char/rio/riotty.c20
-rw-r--r--drivers/char/rio/route.h6
-rw-r--r--drivers/char/rio/unixrup.h4
-rw-r--r--drivers/char/riscom8.c187
-rw-r--r--drivers/char/riscom8.h10
-rw-r--r--drivers/char/rocket.c139
-rw-r--r--drivers/char/rocket.h4
-rw-r--r--drivers/char/rocket_int.h11
-rw-r--r--drivers/char/selection.c3
-rw-r--r--drivers/char/specialix.c153
-rw-r--r--drivers/char/specialix_io8.h8
-rw-r--r--drivers/char/stallion.c160
-rw-r--r--drivers/char/sx.c115
-rw-r--r--drivers/char/synclink.c246
-rw-r--r--drivers/char/synclink_gt.c247
-rw-r--r--drivers/char/synclinkmp.c250
-rw-r--r--drivers/char/tty_io.c420
-rw-r--r--drivers/char/tty_ioctl.c16
-rw-r--r--drivers/dio/dio-driver.c14
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c4
-rw-r--r--drivers/input/keyboard/atakbd.c2
-rw-r--r--drivers/input/serio/serport.c2
-rw-r--r--drivers/isdn/capi/capi.c4
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c2
-rw-r--r--drivers/isdn/i4l/isdn_net.c2
-rw-r--r--drivers/media/Kconfig5
-rw-r--r--drivers/media/common/ir-functions.c26
-rw-r--r--drivers/media/common/saa7146_core.c4
-rw-r--r--drivers/media/common/saa7146_hlp.c2
-rw-r--r--drivers/media/common/saa7146_i2c.c34
-rw-r--r--drivers/media/common/saa7146_video.c4
-rw-r--r--drivers/media/common/tuners/Kconfig1
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c2
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c25
-rw-r--r--drivers/media/common/tuners/xc5000.c7
-rw-r--r--drivers/media/dvb/Kconfig1
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h2
-rw-r--r--drivers/media/dvb/dvb-core/demux.h2
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c17
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c6
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c78
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h12
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig15
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c553
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.h304
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.c83
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.h22
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c146
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h8
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.c38
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.h2
-rw-r--r--drivers/media/dvb/frontends/au8522.c1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c47
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h1
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c24
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c1
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c1
-rw-r--r--drivers/media/dvb/frontends/tda10023.c197
-rw-r--r--drivers/media/dvb/frontends/tda1002x.h41
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c2
-rw-r--r--drivers/media/dvb/siano/Kconfig26
-rw-r--r--drivers/media/dvb/siano/Makefile8
-rw-r--r--drivers/media/dvb/siano/sms-cards.c102
-rw-r--r--drivers/media/dvb/siano/sms-cards.h45
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c1251
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h434
-rw-r--r--drivers/media/dvb/siano/smsdvb.c449
-rw-r--r--drivers/media/dvb/siano/smsusb.c459
-rw-r--r--drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/Makefile7
-rw-r--r--drivers/media/dvb/ttpci/av7110.c47
-rw-r--r--drivers/media/dvb/ttpci/av7110.h1
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h3
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c12
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c24
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c44
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c22
-rw-r--r--drivers/media/radio/radio-si470x.c483
-rw-r--r--drivers/media/video/Kconfig99
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/bt819.c2
-rw-r--r--drivers/media/video/bt8xx/bt832.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c51
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c49
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c6
-rw-r--r--drivers/media/video/bt8xx/bttv.h1
-rw-r--r--drivers/media/video/bt8xx/bttvp.h9
-rw-r--r--drivers/media/video/cafe_ccic.c18
-rw-r--r--drivers/media/video/compat_ioctl32.c1
-rw-r--r--drivers/media/video/cs5345.c1
-rw-r--r--drivers/media/video/cs53l32a.c2
-rw-r--r--drivers/media/video/cx18/cx18-audio.c15
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c12
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c225
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h16
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c72
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c152
-rw-r--r--drivers/media/video/cx18/cx18-cards.c89
-rw-r--r--drivers/media/video/cx18/cx18-cards.h9
-rw-r--r--drivers/media/video/cx18/cx18-controls.c216
-rw-r--r--drivers/media/video/cx18/cx18-controls.h7
-rw-r--r--drivers/media/video/cx18/cx18-driver.c21
-rw-r--r--drivers/media/video/cx18/cx18-driver.h7
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c10
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c90
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c25
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c1179
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.h6
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c1
-rw-r--r--drivers/media/video/cx18/cx18-streams.c12
-rw-r--r--drivers/media/video/cx18/cx23418.h5
-rw-r--r--drivers/media/video/cx2341x.c180
-rw-r--r--drivers/media/video/cx23885/Kconfig2
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c701
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c13
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c10
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c42
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c24
-rw-r--r--drivers/media/video/cx23885/cx23885.h1
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c158
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h3
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c152
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c1
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c19
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c1
-rw-r--r--drivers/media/video/cx88/cx88-video.c24
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c74
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c25
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c1
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c87
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c32
-rw-r--r--drivers/media/video/em28xx/em28xx.h12
-rw-r--r--drivers/media/video/gspca/Kconfig13
-rw-r--r--drivers/media/video/gspca/Makefile29
-rw-r--r--drivers/media/video/gspca/conex.c1051
-rw-r--r--drivers/media/video/gspca/etoms.c956
-rw-r--r--drivers/media/video/gspca/gspca.c1905
-rw-r--r--drivers/media/video/gspca/gspca.h176
-rw-r--r--drivers/media/video/gspca/jpeg.h301
-rw-r--r--drivers/media/video/gspca/mars.c464
-rw-r--r--drivers/media/video/gspca/ov519.c2186
-rw-r--r--drivers/media/video/gspca/pac207.c622
-rw-r--r--drivers/media/video/gspca/pac7311.c760
-rw-r--r--drivers/media/video/gspca/sonixb.c1477
-rw-r--r--drivers/media/video/gspca/sonixj.c1671
-rw-r--r--drivers/media/video/gspca/spca500.c1216
-rw-r--r--drivers/media/video/gspca/spca501.c2229
-rw-r--r--drivers/media/video/gspca/spca505.c951
-rw-r--r--drivers/media/video/gspca/spca506.c847
-rw-r--r--drivers/media/video/gspca/spca508.c1791
-rw-r--r--drivers/media/video/gspca/spca561.c1052
-rw-r--r--drivers/media/video/gspca/stk014.c592
-rw-r--r--drivers/media/video/gspca/sunplus.c1677
-rw-r--r--drivers/media/video/gspca/t613.c1038
-rw-r--r--drivers/media/video/gspca/tv8532.c670
-rw-r--r--drivers/media/video/gspca/vc032x.c1818
-rw-r--r--drivers/media/video/gspca/zc3xx-reg.h261
-rw-r--r--drivers/media/video/gspca/zc3xx.c7623
-rw-r--r--drivers/media/video/ir-kbd-i2c.c82
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c75
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h3
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c225
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.h6
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c19
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c25
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c2184
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.h9
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c3
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c86
-rw-r--r--drivers/media/video/m52790.c1
-rw-r--r--drivers/media/video/meye.c18
-rw-r--r--drivers/media/video/msp3400-driver.c3
-rw-r--r--drivers/media/video/msp3400-kthreads.c1
-rw-r--r--drivers/media/video/mt9v022.c1
-rw-r--r--drivers/media/video/ov7670.c28
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-context.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debug.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c11
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-eeprom.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c75
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-io.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-std.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c461
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-util.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2.h1
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c2
-rw-r--r--drivers/media/video/pwc/pwc-ioctl.h1
-rw-r--r--drivers/media/video/pxa_camera.c27
-rw-r--r--drivers/media/video/s2255drv.c2495
-rw-r--r--drivers/media/video/saa5246a.c1
-rw-r--r--drivers/media/video/saa5249.c1
-rw-r--r--drivers/media/video/saa6588.c1
-rw-r--r--drivers/media/video/saa7115.c4
-rw-r--r--drivers/media/video/saa711x.c584
-rw-r--r--drivers/media/video/saa7127.c43
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c105
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c181
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c10
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c86
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c81
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h1
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c35
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c82
-rw-r--r--drivers/media/video/saa7134/saa7134.h6
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c657
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h2
-rw-r--r--drivers/media/video/soc_camera.c64
-rw-r--r--drivers/media/video/soc_camera_platform.c198
-rw-r--r--drivers/media/video/stk-webcam.c18
-rw-r--r--drivers/media/video/tcm825x.c6
-rw-r--r--drivers/media/video/tcm825x.h1
-rw-r--r--drivers/media/video/tda7432.c1
-rw-r--r--drivers/media/video/tda9840.c1
-rw-r--r--drivers/media/video/tda9875.c2
-rw-r--r--drivers/media/video/tea6415c.c1
-rw-r--r--drivers/media/video/tea6420.c1
-rw-r--r--drivers/media/video/tlv320aic23b.c1
-rw-r--r--drivers/media/video/tuner-core.c1
-rw-r--r--drivers/media/video/tvaudio.c13
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c4
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c5
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c30
-rw-r--r--drivers/media/video/uvc/Kconfig17
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c1
-rw-r--r--drivers/media/video/uvc/uvc_driver.c31
-rw-r--r--drivers/media/video/uvc/uvc_queue.c1
-rw-r--r--drivers/media/video/uvc/uvc_status.c20
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c3
-rw-r--r--drivers/media/video/uvc/uvc_video.c117
-rw-r--r--drivers/media/video/uvc/uvcvideo.h3
-rw-r--r--drivers/media/video/videobuf-dma-contig.c418
-rw-r--r--drivers/media/video/videobuf-dma-sg.c8
-rw-r--r--drivers/media/video/videobuf-dvb.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/videodev.c735
-rw-r--r--drivers/media/video/vivi.c37
-rw-r--r--drivers/media/video/vp27smpx.c1
-rw-r--r--drivers/media/video/wm8739.c1
-rw-r--r--drivers/media/video/wm8775.c2
-rw-r--r--drivers/media/video/zoran_card.c34
-rw-r--r--drivers/media/video/zoran_driver.c5
-rw-r--r--drivers/media/video/zr364xx.c16
-rw-r--r--drivers/mfd/Kconfig2
-rw-r--r--drivers/mfd/asic3.c388
-rw-r--r--drivers/net/3c503.c14
-rw-r--r--drivers/net/3c515.c4
-rw-r--r--drivers/net/3c523.c37
-rw-r--r--drivers/net/3c527.c45
-rw-r--r--drivers/net/8139cp.c44
-rw-r--r--drivers/net/8139too.c66
-rw-r--r--drivers/net/8390.h19
-rw-r--r--drivers/net/8390p.c66
-rw-r--r--drivers/net/Kconfig200
-rw-r--r--drivers/net/Makefile15
-rw-r--r--drivers/net/a2065.c4
-rw-r--r--drivers/net/acenic.c21
-rw-r--r--drivers/net/acenic.h1
-rw-r--r--drivers/net/amd8111e.c137
-rw-r--r--drivers/net/ariadne.c47
-rw-r--r--drivers/net/arm/ixp4xx_eth.c3
-rw-r--r--drivers/net/atarilance.c2
-rw-r--r--drivers/net/atlx/atl1.c3
-rw-r--r--drivers/net/au1000_eth.c2
-rw-r--r--drivers/net/b44.c140
-rw-r--r--drivers/net/bfin_mac.c2
-rw-r--r--drivers/net/bnx2.c1339
-rw-r--r--drivers/net/bnx2.h115
-rw-r--r--drivers/net/bnx2_fw.h80
-rw-r--r--drivers/net/bnx2_fw2.h8858
-rw-r--r--drivers/net/bnx2x.c9988
-rw-r--r--drivers/net/bnx2x.h1585
-rw-r--r--drivers/net/bnx2x_fw_defs.h483
-rw-r--r--drivers/net/bnx2x_hsi.h1101
-rw-r--r--drivers/net/bnx2x_init.h352
-rw-r--r--drivers/net/bnx2x_init_values.h19186
-rw-r--r--drivers/net/bnx2x_link.c4527
-rw-r--r--drivers/net/bnx2x_link.h168
-rw-r--r--drivers/net/bnx2x_main.c10294
-rw-r--r--drivers/net/bnx2x_reg.h1969
-rw-r--r--drivers/net/bonding/bond_alb.c6
-rw-r--r--drivers/net/bonding/bond_main.c824
-rw-r--r--drivers/net/bonding/bond_sysfs.c103
-rw-r--r--drivers/net/bonding/bonding.h17
-rw-r--r--drivers/net/chelsio/cxgb2.c2
-rw-r--r--drivers/net/chelsio/sge.c70
-rw-r--r--drivers/net/cpmac.c35
-rw-r--r--drivers/net/cxgb3/adapter.h18
-rw-r--r--drivers/net/cxgb3/common.h1
-rw-r--r--drivers/net/cxgb3/cxgb3_ctl_defs.h5
-rw-r--r--drivers/net/cxgb3/cxgb3_ioctl.h1
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c19
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c32
-rw-r--r--drivers/net/cxgb3/l2t.c2
-rw-r--r--drivers/net/cxgb3/regs.h10
-rw-r--r--drivers/net/cxgb3/sge.c391
-rw-r--r--drivers/net/cxgb3/t3_cpl.h51
-rw-r--r--drivers/net/cxgb3/t3cdev.h4
-rw-r--r--drivers/net/declance.c4
-rw-r--r--drivers/net/dl2k.c10
-rw-r--r--drivers/net/dm9000.c1161
-rw-r--r--drivers/net/dm9000.h11
-rw-r--r--drivers/net/e1000/e1000_main.c64
-rw-r--r--drivers/net/e1000e/e1000.h4
-rw-r--r--drivers/net/e1000e/netdev.c84
-rw-r--r--drivers/net/fealnx.c43
-rw-r--r--drivers/net/fec_mpc52xx.c2
-rw-r--r--drivers/net/forcedeth.c82
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c33
-rw-r--r--drivers/net/gianfar.c82
-rw-r--r--drivers/net/gianfar.h11
-rw-r--r--drivers/net/hamachi.c12
-rw-r--r--drivers/net/hamradio/6pack.c28
-rw-r--r--drivers/net/hamradio/bpqether.c14
-rw-r--r--drivers/net/hamradio/mkiss.c4
-rw-r--r--drivers/net/hp.c14
-rw-r--r--drivers/net/hplance.c4
-rw-r--r--drivers/net/ibm_emac/Kconfig70
-rw-r--r--drivers/net/ibm_emac/Makefile11
-rw-r--r--drivers/net/ibm_emac/ibm_emac.h329
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.c2263
-rw-r--r--drivers/net/ibm_emac/ibm_emac_core.h222
-rw-r--r--drivers/net/ibm_emac/ibm_emac_debug.c211
-rw-r--r--drivers/net/ibm_emac/ibm_emac_debug.h62
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.c570
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.h267
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.c398
-rw-r--r--drivers/net/ibm_emac/ibm_emac_phy.h80
-rw-r--r--drivers/net/ibm_emac/ibm_emac_rgmii.c200
-rw-r--r--drivers/net/ibm_emac/ibm_emac_rgmii.h64
-rw-r--r--drivers/net/ibm_emac/ibm_emac_tah.c110
-rw-r--r--drivers/net/ibm_emac/ibm_emac_tah.h87
-rw-r--r--drivers/net/ibm_emac/ibm_emac_zmii.c253
-rw-r--r--drivers/net/ibm_emac/ibm_emac_zmii.h82
-rw-r--r--drivers/net/ibm_newemac/core.c4
-rw-r--r--drivers/net/ifb.c14
-rw-r--r--drivers/net/igb/e1000_82575.c446
-rw-r--r--drivers/net/igb/e1000_82575.h36
-rw-r--r--drivers/net/igb/e1000_defines.h38
-rw-r--r--drivers/net/igb/e1000_hw.h16
-rw-r--r--drivers/net/igb/e1000_mac.c144
-rw-r--r--drivers/net/igb/e1000_mac.h1
-rw-r--r--drivers/net/igb/e1000_nvm.c52
-rw-r--r--drivers/net/igb/e1000_phy.c138
-rw-r--r--drivers/net/igb/e1000_regs.h9
-rw-r--r--drivers/net/igb/igb.h51
-rw-r--r--drivers/net/igb/igb_ethtool.c203
-rw-r--r--drivers/net/igb/igb_main.c1284
-rw-r--r--drivers/net/ipg.c105
-rw-r--r--drivers/net/ipg.h83
-rw-r--r--drivers/net/irda/ali-ircc.h2
-rw-r--r--drivers/net/irda/au1000_ircc.h1
-rw-r--r--drivers/net/irda/donauboe.c6
-rw-r--r--drivers/net/irda/irtty-sir.c2
-rw-r--r--drivers/net/irda/smsc-ircc2.c1
-rw-r--r--drivers/net/irda/smsc-ircc2.h1
-rw-r--r--drivers/net/irda/via-ircc.h1
-rw-r--r--drivers/net/ixgb/Makefile2
-rw-r--r--drivers/net/ixgb/ixgb.h21
-rw-r--r--drivers/net/ixgb/ixgb_ee.c28
-rw-r--r--drivers/net/ixgb/ixgb_ee.h12
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c120
-rw-r--r--drivers/net/ixgb/ixgb_hw.c40
-rw-r--r--drivers/net/ixgb/ixgb_hw.h2
-rw-r--r--drivers/net/ixgb/ixgb_ids.h10
-rw-r--r--drivers/net/ixgb/ixgb_main.c499
-rw-r--r--drivers/net/ixgb/ixgb_osdep.h4
-rw-r--r--drivers/net/ixgb/ixgb_param.c44
-rw-r--r--drivers/net/ixgbe/ixgbe.h9
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c27
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c191
-rw-r--r--drivers/net/ixp2000/ixpdev.c4
-rw-r--r--drivers/net/lib8390.c100
-rw-r--r--drivers/net/loopback.c8
-rw-r--r--drivers/net/mac8390.c8
-rw-r--r--drivers/net/macb.c8
-rw-r--r--drivers/net/macsonic.c19
-rw-r--r--drivers/net/macvlan.c30
-rw-r--r--drivers/net/mv643xx_eth.c4557
-rw-r--r--drivers/net/myri10ge/myri10ge.c1076
-rw-r--r--drivers/net/natsemi.c4
-rw-r--r--drivers/net/ne.c14
-rw-r--r--drivers/net/ne2.c16
-rw-r--r--drivers/net/netconsole.c10
-rw-r--r--drivers/net/niu.c203
-rw-r--r--drivers/net/niu.h2
-rw-r--r--drivers/net/ns83820.c9
-rw-r--r--drivers/net/pci-skeleton.c1
-rw-r--r--drivers/net/pcmcia/3c574_cs.c47
-rw-r--r--drivers/net/pcmcia/3c589_cs.c49
-rw-r--r--drivers/net/pcmcia/axnet_cs.c70
-rw-r--r--drivers/net/pcnet32.c6
-rw-r--r--drivers/net/phy/Kconfig9
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/broadcom.c201
-rw-r--r--drivers/net/phy/mdio-bitbang.c2
-rw-r--r--drivers/net/phy/mdio-ofgpio.c205
-rw-r--r--drivers/net/ppp_async.c2
-rw-r--r--drivers/net/ppp_generic.c22
-rw-r--r--drivers/net/ppp_synctty.c2
-rw-r--r--drivers/net/ps3_gelic_net.c10
-rw-r--r--drivers/net/ps3_gelic_net.h2
-rw-r--r--drivers/net/ps3_gelic_wireless.c236
-rw-r--r--drivers/net/ps3_gelic_wireless.h7
-rw-r--r--drivers/net/qla3xxx.c4
-rw-r--r--drivers/net/r8169.c145
-rw-r--r--drivers/net/s2io.c183
-rw-r--r--drivers/net/s2io.h3
-rw-r--r--drivers/net/saa9730.c1139
-rw-r--r--drivers/net/saa9730.h384
-rw-r--r--drivers/net/sb1250-mac.c2
-rw-r--r--drivers/net/sfc/Kconfig2
-rw-r--r--drivers/net/sfc/Makefile2
-rw-r--r--drivers/net/sfc/boards.c2
-rw-r--r--drivers/net/sfc/boards.h3
-rw-r--r--drivers/net/sfc/efx.c6
-rw-r--r--drivers/net/sfc/falcon.c74
-rw-r--r--drivers/net/sfc/i2c-direct.c381
-rw-r--r--drivers/net/sfc/i2c-direct.h91
-rw-r--r--drivers/net/sfc/net_driver.h11
-rw-r--r--drivers/net/sfc/sfe4001.c126
-rw-r--r--drivers/net/sh_eth.c1174
-rw-r--r--drivers/net/sh_eth.h464
-rw-r--r--drivers/net/sis190.c2
-rw-r--r--drivers/net/sis900.c2
-rw-r--r--drivers/net/sky2.c241
-rw-r--r--drivers/net/sky2.h24
-rw-r--r--drivers/net/slip.c2
-rw-r--r--drivers/net/smc911x.c422
-rw-r--r--drivers/net/smc911x.h494
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/starfire.c111
-rw-r--r--drivers/net/sunlance.c4
-rw-r--r--drivers/net/tc35815.c2
-rw-r--r--drivers/net/tehuti.c2
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tg3.c1268
-rw-r--r--drivers/net/tg3.h40
-rw-r--r--drivers/net/tlan.c490
-rw-r--r--drivers/net/tlan.h26
-rw-r--r--drivers/net/tokenring/3c359.c20
-rw-r--r--drivers/net/tokenring/3c359.h2
-rw-r--r--drivers/net/tsi108_eth.c11
-rw-r--r--drivers/net/tulip/21142.c6
-rw-r--r--drivers/net/tulip/de2104x.c10
-rw-r--r--drivers/net/tulip/eeprom.c6
-rw-r--r--drivers/net/tulip/interrupt.c5
-rw-r--r--drivers/net/tulip/media.c5
-rw-r--r--drivers/net/tulip/pnic.c5
-rw-r--r--drivers/net/tulip/pnic2.c5
-rw-r--r--drivers/net/tulip/timer.c6
-rw-r--r--drivers/net/tulip/tulip.h4
-rw-r--r--drivers/net/tulip/tulip_core.c8
-rw-r--r--drivers/net/tun.c458
-rw-r--r--drivers/net/typhoon.c3
-rw-r--r--drivers/net/ucc_geth.c33
-rw-r--r--drivers/net/ucc_geth_ethtool.c4
-rw-r--r--drivers/net/usb/Kconfig10
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/hso.c2836
-rw-r--r--drivers/net/usb/rndis_host.c14
-rw-r--r--drivers/net/via-rhine.c27
-rw-r--r--drivers/net/via-velocity.c183
-rw-r--r--drivers/net/via-velocity.h5
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/wan/Kconfig3
-rw-r--r--drivers/net/wan/c101.c6
-rw-r--r--drivers/net/wan/dscc4.c22
-rw-r--r--drivers/net/wan/farsync.c70
-rw-r--r--drivers/net/wan/hd6457x.c33
-rw-r--r--drivers/net/wan/hdlc.c2
-rw-r--r--drivers/net/wan/hdlc_cisco.c4
-rw-r--r--drivers/net/wan/hdlc_fr.c54
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c2
-rw-r--r--drivers/net/wan/hdlc_x25.c6
-rw-r--r--drivers/net/wan/pc300_drv.c71
-rw-r--r--drivers/net/wan/pc300_tty.c10
-rw-r--r--drivers/net/wan/wanxl.c26
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/net/wireless/Kconfig25
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/adm8211.c58
-rw-r--r--drivers/net/wireless/adm8211.h1
-rw-r--r--drivers/net/wireless/airo.c156
-rw-r--r--drivers/net/wireless/arlan-main.c40
-rw-r--r--drivers/net/wireless/arlan.h1
-rw-r--r--drivers/net/wireless/ath5k/Kconfig3
-rw-r--r--drivers/net/wireless/ath5k/base.c377
-rw-r--r--drivers/net/wireless/ath5k/base.h36
-rw-r--r--drivers/net/wireless/ath5k/hw.c4
-rw-r--r--drivers/net/wireless/atmel.c70
-rw-r--r--drivers/net/wireless/b43/b43.h49
-rw-r--r--drivers/net/wireless/b43/debugfs.c436
-rw-r--r--drivers/net/wireless/b43/debugfs.h24
-rw-r--r--drivers/net/wireless/b43/dma.c119
-rw-r--r--drivers/net/wireless/b43/dma.h3
-rw-r--r--drivers/net/wireless/b43/lo.c731
-rw-r--r--drivers/net/wireless/b43/lo.h115
-rw-r--r--drivers/net/wireless/b43/main.c450
-rw-r--r--drivers/net/wireless/b43/main.h7
-rw-r--r--drivers/net/wireless/b43/nphy.c2
-rw-r--r--drivers/net/wireless/b43/phy.c291
-rw-r--r--drivers/net/wireless/b43/phy.h16
-rw-r--r--drivers/net/wireless/b43/pio.c44
-rw-r--r--drivers/net/wireless/b43/pio.h8
-rw-r--r--drivers/net/wireless/b43/rfkill.c27
-rw-r--r--drivers/net/wireless/b43/xmit.c88
-rw-r--r--drivers/net/wireless/b43/xmit.h4
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h17
-rw-r--r--drivers/net/wireless/b43legacy/dma.c172
-rw-r--r--drivers/net/wireless/b43legacy/dma.h7
-rw-r--r--drivers/net/wireless/b43legacy/main.c72
-rw-r--r--drivers/net/wireless/b43legacy/phy.c14
-rw-r--r--drivers/net/wireless/b43legacy/pio.c27
-rw-r--r--drivers/net/wireless/b43legacy/pio.h7
-rw-r--r--drivers/net/wireless/b43legacy/radio.c12
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c28
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c70
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h2
-rw-r--r--drivers/net/wireless/hostap/hostap.h3
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c21
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c32
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c19
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c63
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c20
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h14
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig32
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c146
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c131
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h634
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c1233
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.h105
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c4004
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h134
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1580
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c802
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h84
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h (renamed from drivers/net/wireless/iwlwifi/iwl-4965-commands.h)462
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1259
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h219
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c103
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h (renamed from drivers/net/wireless/iwlwifi/iwl-4965.h)567
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c171
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h206
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h391
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h92
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c209
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c423
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h333
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c106
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1321
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c931
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c712
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1519
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c535
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c5004
-rw-r--r--drivers/net/wireless/libertas/Makefile8
-rw-r--r--drivers/net/wireless/libertas/assoc.c8
-rw-r--r--drivers/net/wireless/libertas/cmd.c192
-rw-r--r--drivers/net/wireless/libertas/cmd.h8
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c25
-rw-r--r--drivers/net/wireless/libertas/decl.h8
-rw-r--r--drivers/net/wireless/libertas/defs.h14
-rw-r--r--drivers/net/wireless/libertas/dev.h8
-rw-r--r--drivers/net/wireless/libertas/host.h17
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h4
-rw-r--r--drivers/net/wireless/libertas/if_cs.c315
-rw-r--r--drivers/net/wireless/libertas/if_usb.c22
-rw-r--r--drivers/net/wireless/libertas/main.c254
-rw-r--r--drivers/net/wireless/libertas/persistcfg.c453
-rw-r--r--drivers/net/wireless/libertas/rx.c4
-rw-r--r--drivers/net/wireless/libertas/scan.c36
-rw-r--r--drivers/net/wireless/libertas/types.h30
-rw-r--r--drivers/net/wireless/libertas/wext.c32
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c515
-rw-r--r--drivers/net/wireless/orinoco.c30
-rw-r--r--drivers/net/wireless/p54/p54.h2
-rw-r--r--drivers/net/wireless/p54/p54common.c138
-rw-r--r--drivers/net/wireless/p54/p54common.h1
-rw-r--r--drivers/net/wireless/p54/p54pci.c2
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c49
-rw-r--r--drivers/net/wireless/rndis_wlan.c205
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig63
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c352
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c312
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c307
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h47
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h105
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c362
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h78
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c172
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c231
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h45
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c413
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h136
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h145
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c114
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c361
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h69
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c344
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c270
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h7
-rw-r--r--drivers/net/wireless/rtl8180_dev.c71
-rw-r--r--drivers/net/wireless/rtl8187.h119
-rw-r--r--drivers/net/wireless/rtl8187_dev.c558
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.c250
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.h15
-rw-r--r--drivers/net/wireless/rtl818x.h36
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/net/wireless/wl3501_cs.c10
-rw-r--r--drivers/net/wireless/zd1201.c21
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c262
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h16
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c29
-rw-r--r--drivers/s390/net/qeth_l3_main.c4
-rw-r--r--drivers/serial/21285.c12
-rw-r--r--drivers/serial/68328serial.c30
-rw-r--r--drivers/serial/68360serial.c52
-rw-r--r--drivers/serial/8250.c8
-rw-r--r--drivers/serial/8250.h2
-rw-r--r--drivers/serial/8250_pci.c2
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/amba-pl010.c8
-rw-r--r--drivers/serial/amba-pl011.c4
-rw-r--r--drivers/serial/atmel_serial.c21
-rw-r--r--drivers/serial/bfin_5xx.c10
-rw-r--r--drivers/serial/bfin_sport_uart.c4
-rw-r--r--drivers/serial/clps711x.c9
-rw-r--r--drivers/serial/crisv10.c79
-rw-r--r--drivers/serial/dz.c4
-rw-r--r--drivers/serial/imx.c2
-rw-r--r--drivers/serial/ioc3_serial.c14
-rw-r--r--drivers/serial/ioc4_serial.c21
-rw-r--r--drivers/serial/ip22zilog.c4
-rw-r--r--drivers/serial/jsm/jsm_neo.c2
-rw-r--r--drivers/serial/jsm/jsm_tty.c8
-rw-r--r--drivers/serial/m32r_sio.c6
-rw-r--r--drivers/serial/mcf.c2
-rw-r--r--drivers/serial/mcfserial.c32
-rw-r--r--drivers/serial/mpc52xx_uart.c2
-rw-r--r--drivers/serial/mpsc.c6
-rw-r--r--drivers/serial/mux.c2
-rw-r--r--drivers/serial/netx-serial.c2
-rw-r--r--drivers/serial/pmac_zilog.c4
-rw-r--r--drivers/serial/pnx8xxx_uart.c4
-rw-r--r--drivers/serial/pxa.c2
-rw-r--r--drivers/serial/sa1100.c9
-rw-r--r--drivers/serial/sb1250-duart.c2
-rw-r--r--drivers/serial/sc26xx.c2
-rw-r--r--drivers/serial/serial_core.c82
-rw-r--r--drivers/serial/serial_ks8695.c2
-rw-r--r--drivers/serial/serial_lh7a40x.c2
-rw-r--r--drivers/serial/sh-sci.c8
-rw-r--r--drivers/serial/sn_console.c2
-rw-r--r--drivers/serial/sunhv.c2
-rw-r--r--drivers/serial/sunsab.c2
-rw-r--r--drivers/serial/sunsu.c4
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/serial/uartlite.c4
-rw-r--r--drivers/serial/ucc_uart.c2
-rw-r--r--drivers/serial/v850e_uart.c4
-rw-r--r--drivers/serial/vr41xx_siu.c2
-rw-r--r--drivers/serial/zs.c2
-rw-r--r--drivers/ssb/Kconfig2
-rw-r--r--drivers/ssb/main.c75
-rw-r--r--drivers/ssb/pci.c20
-rw-r--r--drivers/video/amifb.c3
-rw-r--r--drivers/video/atafb.c5
-rw-r--r--drivers/video/c2p.c3
-rw-r--r--drivers/zorro/proc.c4
-rw-r--r--drivers/zorro/zorro-sysfs.c10
-rw-r--r--drivers/zorro/zorro.c2
-rw-r--r--drivers/zorro/zorro.ids2
808 files changed, 123129 insertions, 64039 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index fda44679dff..808e0ae66aa 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -10,7 +10,6 @@ obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_PARISC) += parisc/
obj-$(CONFIG_RAPIDIO) += rapidio/
obj-y += video/
-obj-y += gpu/
obj-$(CONFIG_ACPI) += acpi/
# PnP must come after ACPI since it will eventually need to check if acpi
# was used and do nothing if so
@@ -23,6 +22,9 @@ obj-$(CONFIG_XEN) += xen/
# default.
obj-y += char/
+# gpu/ comes after char for AGP vs DRM startup
+obj-y += gpu/
+
obj-$(CONFIG_CONNECTOR) += connector/
# i810fb and intelfb depend on char/agp/
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index e6caf5d42e0..61b6c5beb2d 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -380,9 +380,6 @@ static int __init bay_init(void)
if (acpi_disabled)
return -ENODEV;
- if (acpi_disabled)
- return -ENODEV;
-
/* look for dockable drive bays */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_bay, &bays, NULL);
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 1e872e79db3..bb7c51f712b 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -920,9 +920,6 @@ static int __init dock_init(void)
if (acpi_disabled)
return 0;
- if (acpi_disabled)
- return 0;
-
/* look for a dock station */
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_dock, &num, NULL);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 0f2dd81736b..2f173e83f8a 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -338,9 +338,6 @@ static int __init acpi_rtc_init(void)
if (acpi_disabled)
return 0;
- if (acpi_disabled)
- return 0;
-
if (dev) {
rtc_wake_setup();
rtc_info.wake_on = rtc_wake_on;
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index b554edac1ce..f197a193633 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -294,7 +294,7 @@ config ATM_HORIZON_DEBUG
config ATM_IA
tristate "Interphase ATM PCI x575/x525/x531"
- depends on PCI && !64BIT
+ depends on PCI
---help---
This is a driver for the Interphase (i)ChipSAR adapter cards
which include a variety of variants in term of the size of the
@@ -325,81 +325,22 @@ config ATM_IA_DEBUG
speed of the driver, and the size of your syslog files! When
inactive, they will have only a modest impact on performance.
-config ATM_FORE200E_MAYBE
+config ATM_FORE200E
tristate "FORE Systems 200E-series"
- depends on PCI || SBUS
+ depends on (PCI || SBUS)
+ select FW_LOADER
---help---
This is a driver for the FORE Systems 200E-series ATM adapter
cards. It simultaneously supports PCA-200E and SBA-200E models
on PCI and SBUS hosts. Say Y (or M to compile as a module
named fore_200e) here if you have one of these ATM adapters.
- Note that the driver will actually be compiled only if you
- additionally enable the support for PCA-200E and/or SBA-200E
- cards.
-
See the file <file:Documentation/networking/fore200e.txt> for
further details.
-config ATM_FORE200E_PCA
- bool "PCA-200E support"
- depends on ATM_FORE200E_MAYBE && PCI
- help
- Say Y here if you want your PCA-200E cards to be probed.
-
-config ATM_FORE200E_PCA_DEFAULT_FW
- bool "Use default PCA-200E firmware (normally enabled)"
- depends on ATM_FORE200E_PCA
- help
- Use the default PCA-200E firmware data shipped with the driver.
-
- Normal users do not have to deal with the firmware stuff, so
- they should say Y here.
-
-config ATM_FORE200E_PCA_FW
- string "Pathname of user-supplied binary firmware"
- depends on ATM_FORE200E_PCA && !ATM_FORE200E_PCA_DEFAULT_FW
- default ""
- help
- This defines the pathname of an alternative PCA-200E binary
- firmware image supplied by the user. This pathname may be
- absolute or relative to the drivers/atm directory.
-
- The driver comes with an adequate firmware image, so normal users do
- not have to supply an alternative one. They just say Y to "Use
- default PCA-200E firmware" instead.
-
-config ATM_FORE200E_SBA
- bool "SBA-200E support"
- depends on ATM_FORE200E_MAYBE && SBUS
- help
- Say Y here if you want your SBA-200E cards to be probed.
-
-config ATM_FORE200E_SBA_DEFAULT_FW
- bool "Use default SBA-200E firmware (normally enabled)"
- depends on ATM_FORE200E_SBA
- help
- Use the default SBA-200E firmware data shipped with the driver.
-
- Normal users do not have to deal with the firmware stuff, so
- they should say Y here.
-
-config ATM_FORE200E_SBA_FW
- string "Pathname of user-supplied binary firmware"
- depends on ATM_FORE200E_SBA && !ATM_FORE200E_SBA_DEFAULT_FW
- default ""
- help
- This defines the pathname of an alternative SBA-200E binary
- firmware image supplied by the user. This pathname may be
- absolute or relative to the drivers/atm directory.
-
- The driver comes with an adequate firmware image, so normal users do
- not have to supply an alternative one. They just say Y to "Use
- default SBA-200E firmware", above.
-
config ATM_FORE200E_USE_TASKLET
bool "Defer interrupt work to a tasklet"
- depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA)
+ depends on ATM_FORE200E
default n
help
This defers work to be done by the interrupt handler to a
@@ -408,7 +349,7 @@ config ATM_FORE200E_USE_TASKLET
config ATM_FORE200E_TX_RETRY
int "Maximum number of tx retries"
- depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA)
+ depends on ATM_FORE200E
default "16"
---help---
Specifies the number of times the driver attempts to transmit
@@ -425,7 +366,7 @@ config ATM_FORE200E_TX_RETRY
config ATM_FORE200E_DEBUG
int "Debugging level (0-3)"
- depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA)
+ depends on ATM_FORE200E
default "0"
help
Specifies the level of debugging messages issued by the driver.
@@ -436,12 +377,6 @@ config ATM_FORE200E_DEBUG
the performances of the driver, and the size of your syslog files!
Keep the debugging level to 0 during normal operations.
-config ATM_FORE200E
- tristate
- depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA)
- default m if ATM_FORE200E_MAYBE!=y
- default y if ATM_FORE200E_MAYBE=y
-
config ATM_HE
tristate "ForeRunner HE Series"
depends on PCI
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index 749266e955c..0bfb31748ec 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -3,14 +3,6 @@
#
fore_200e-objs := fore200e.o
-hostprogs-y := fore200e_mkfirm
-
-# Files generated that shall be removed upon make clean
-clean-files := pca200e.bin pca200e.bin1 pca200e.bin2 pca200e_ecd.bin \
- pca200e_ecd.bin1 pca200e_ecd.bin2 sba200e_ecd.bin sba200e_ecd.bin1 \
- sba200e_ecd.bin2
-# Firmware generated that shall be removed upon make clean
-clean-files += fore200e_pca_fw.c fore200e_sba_fw.c
obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o
obj-$(CONFIG_ATM_NICSTAR) += nicstar.o
@@ -36,38 +28,7 @@ obj-$(CONFIG_ATM_TCP) += atmtcp.o
obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
obj-$(CONFIG_ATM_LANAI) += lanai.o
-ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
- fore_200e-objs += fore200e_pca_fw.o
- # guess the target endianess to choose the right PCA-200E firmware image
- ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y)
- byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h
- CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) $(KBUILD_CPPFLAGS) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2)
- endif
-endif
-
-ifeq ($(CONFIG_ATM_FORE200E_SBA),y)
- fore_200e-objs += fore200e_sba_fw.o
- ifeq ($(CONFIG_ATM_FORE200E_SBA_DEFAULT_FW),y)
- CONFIG_ATM_FORE200E_SBA_FW := $(obj)/sba200e_ecd.bin2
- endif
-endif
obj-$(CONFIG_ATM_HE) += he.o
ifeq ($(CONFIG_ATM_HE_USE_SUNI),y)
obj-$(CONFIG_ATM_HE) += suni.o
endif
-
-# FORE Systems 200E-series firmware magic
-$(obj)/fore200e_pca_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_PCA_FW)) \
- $(obj)/fore200e_mkfirm
- $(obj)/fore200e_mkfirm -k -b _fore200e_pca_fw \
- -i $(CONFIG_ATM_FORE200E_PCA_FW) -o $@
-
-$(obj)/fore200e_sba_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_SBA_FW)) \
- $(obj)/fore200e_mkfirm
- $(obj)/fore200e_mkfirm -k -b _fore200e_sba_fw \
- -i $(CONFIG_ATM_FORE200E_SBA_FW) -o $@
-
-# deal with the various suffixes of the binary firmware images
-$(obj)/%.bin $(obj)/%.bin1 $(obj)/%.bin2: $(src)/%.data
- objcopy -Iihex $< -Obinary $@.gz
- gzip -n -df $@.gz
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 432181ed7bb..d5c1bbfbe79 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -36,6 +36,7 @@
#include <linux/atm_suni.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
+#include <linux/firmware.h>
#include <asm/io.h>
#include <asm/string.h>
#include <asm/page.h>
@@ -45,7 +46,7 @@
#include <asm/uaccess.h>
#include <asm/atomic.h>
-#ifdef CONFIG_ATM_FORE200E_SBA
+#ifdef CONFIG_SBUS
#include <asm/idprom.h>
#include <asm/sbus.h>
#include <asm/openprom.h>
@@ -382,9 +383,6 @@ fore200e_shutdown(struct fore200e* fore200e)
case FORE200E_STATE_START_FW:
/* nothing to do for that state */
- case FORE200E_STATE_LOAD_FW:
- /* nothing to do for that state */
-
case FORE200E_STATE_RESET:
/* nothing to do for that state */
@@ -405,7 +403,7 @@ fore200e_shutdown(struct fore200e* fore200e)
}
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
static u32 fore200e_pca_read(volatile u32 __iomem *addr)
{
@@ -658,10 +656,10 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
}
-#endif /* CONFIG_ATM_FORE200E_PCA */
+#endif /* CONFIG_PCI */
-#ifdef CONFIG_ATM_FORE200E_SBA
+#ifdef CONFIG_SBUS
static u32
fore200e_sba_read(volatile u32 __iomem *addr)
@@ -907,7 +905,7 @@ fore200e_sba_proc_read(struct fore200e* fore200e, char *page)
return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name);
}
-#endif /* CONFIG_ATM_FORE200E_SBA */
+#endif /* CONFIG_SBUS */
static void
@@ -2552,13 +2550,53 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str)
while (fore200e_monitor_getc(fore200e) >= 0);
}
+#ifdef __LITTLE_ENDIAN
+#define FW_EXT ".bin"
+#else
+#define FW_EXT "_ecd.bin2"
+#endif
static int __devinit
-fore200e_start_fw(struct fore200e* fore200e)
-{
- int ok;
- char cmd[ 48 ];
- struct fw_header* fw_header = (struct fw_header*) fore200e->bus->fw_data;
+fore200e_load_and_start_fw(struct fore200e* fore200e)
+{
+ const struct firmware *firmware;
+ struct device *device;
+ struct fw_header *fw_header;
+ u32 *fw_data, fw_size;
+ u32 __iomem *load_addr;
+ char buf[48];
+ int err = -ENODEV;
+
+ if (strcmp(fore200e->bus->model_name, "PCA-200E") == 0)
+ device = &((struct pci_dev *) fore200e->bus_dev)->dev;
+#ifdef CONFIG_SBUS
+ else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0)
+ device = &((struct sbus_dev *) fore200e->bus_dev)->ofdev.dev;
+#endif
+ else
+ return err;
+
+ sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
+ if (request_firmware(&firmware, buf, device) == 1) {
+ printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name);
+ return err;
+ }
+
+ fw_data = (u32 *) firmware->data;
+ fw_size = firmware->size / sizeof(u32);
+ fw_header = (struct fw_header *) firmware->data;
+ load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
+
+ DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
+ fore200e->name, load_addr, fw_size);
+
+ if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
+ printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
+ goto release;
+ }
+
+ for (; fw_size--; fw_data++, load_addr++)
+ fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
DPRINTK(2, "device %s firmware being started\n", fore200e->name);
@@ -2567,46 +2605,22 @@ fore200e_start_fw(struct fore200e* fore200e)
fore200e_spin(100);
#endif
- sprintf(cmd, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
+ sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
+ fore200e_monitor_puts(fore200e, buf);
- fore200e_monitor_puts(fore200e, cmd);
-
- ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000);
- if (ok == 0) {
+ if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) {
printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
- return -ENODEV;
+ goto release;
}
printk(FORE200E "device %s firmware started\n", fore200e->name);
fore200e->state = FORE200E_STATE_START_FW;
- return 0;
-}
+ err = 0;
-
-static int __devinit
-fore200e_load_fw(struct fore200e* fore200e)
-{
- __le32* fw_data = (__le32*) fore200e->bus->fw_data;
- u32 fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32);
-
- struct fw_header* fw_header = (struct fw_header*) fw_data;
-
- u32 __iomem *load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
-
- DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
- fore200e->name, load_addr, fw_size);
-
- if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
- printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
- return -ENODEV;
- }
-
- for (; fw_size--; fw_data++, load_addr++)
- fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
-
- fore200e->state = FORE200E_STATE_LOAD_FW;
- return 0;
+release:
+ release_firmware(firmware);
+ return err;
}
@@ -2652,10 +2666,7 @@ fore200e_init(struct fore200e* fore200e)
if (fore200e_reset(fore200e, 1) < 0)
return -ENODEV;
- if (fore200e_load_fw(fore200e) < 0)
- return -ENODEV;
-
- if (fore200e_start_fw(fore200e) < 0)
+ if (fore200e_load_and_start_fw(fore200e) < 0)
return -ENODEV;
if (fore200e_initialize(fore200e) < 0)
@@ -2689,7 +2700,7 @@ fore200e_init(struct fore200e* fore200e)
return 0;
}
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
static int __devinit
fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
{
@@ -2804,7 +2815,7 @@ fore200e_module_init(void)
}
}
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
if (!pci_register_driver(&fore200e_pca_driver))
return 0;
#endif
@@ -2821,7 +2832,7 @@ fore200e_module_cleanup(void)
{
struct fore200e *fore200e, *next;
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
pci_unregister_driver(&fore200e_pca_driver);
#endif
@@ -3140,19 +3151,9 @@ static const struct atmdev_ops fore200e_ops =
};
-#ifdef CONFIG_ATM_FORE200E_PCA
-extern const unsigned char _fore200e_pca_fw_data[];
-extern const unsigned int _fore200e_pca_fw_size;
-#endif
-#ifdef CONFIG_ATM_FORE200E_SBA
-extern const unsigned char _fore200e_sba_fw_data[];
-extern const unsigned int _fore200e_sba_fw_size;
-#endif
-
static const struct fore200e_bus fore200e_bus[] = {
-#ifdef CONFIG_ATM_FORE200E_PCA
+#ifdef CONFIG_PCI
{ "PCA-200E", "pca200e", 32, 4, 32,
- _fore200e_pca_fw_data, &_fore200e_pca_fw_size,
fore200e_pca_read,
fore200e_pca_write,
fore200e_pca_dma_map,
@@ -3173,9 +3174,8 @@ static const struct fore200e_bus fore200e_bus[] = {
fore200e_pca_proc_read,
},
#endif
-#ifdef CONFIG_ATM_FORE200E_SBA
+#ifdef CONFIG_SBUS
{ "SBA-200E", "sba200e", 32, 64, 32,
- _fore200e_sba_fw_data, &_fore200e_sba_fw_size,
fore200e_sba_read,
fore200e_sba_write,
fore200e_sba_dma_map,
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h
index 8dd4aa76c3b..5c6e7adcb19 100644
--- a/drivers/atm/fore200e.h
+++ b/drivers/atm/fore200e.h
@@ -754,7 +754,6 @@ typedef enum fore200e_state {
FORE200E_STATE_CONFIGURE, /* bus interface configured */
FORE200E_STATE_MAP, /* board space mapped in host memory */
FORE200E_STATE_RESET, /* board resetted */
- FORE200E_STATE_LOAD_FW, /* firmware loaded */
FORE200E_STATE_START_FW, /* firmware started */
FORE200E_STATE_INITIALIZE, /* initialize command successful */
FORE200E_STATE_INIT_CMDQ, /* command queue initialized */
@@ -803,8 +802,6 @@ typedef struct fore200e_bus {
int descr_alignment; /* tpd/rpd/rbd DMA alignment requirement */
int buffer_alignment; /* rx buffers DMA alignment requirement */
int status_alignment; /* status words DMA alignment requirement */
- const unsigned char* fw_data; /* address of firmware data start */
- const unsigned int* fw_size; /* address of firmware data size */
u32 (*read)(volatile u32 __iomem *);
void (*write)(u32, volatile u32 __iomem *);
u32 (*dma_map)(struct fore200e*, void*, int, int);
diff --git a/drivers/atm/fore200e_firmware_copyright b/drivers/atm/fore200e_firmware_copyright
deleted file mode 100644
index d58e6490836..00000000000
--- a/drivers/atm/fore200e_firmware_copyright
+++ /dev/null
@@ -1,31 +0,0 @@
-
-These microcode data are placed under the terms of the GNU General Public License.
-
-We would prefer you not to distribute modified versions of it and not to ask
-for assembly or other microcode source.
-
-Copyright (c) 1995-2000 FORE Systems, Inc., as an unpublished work. This
-notice does not imply unrestricted or public access to these materials which
-are a trade secret of FORE Systems, Inc. or its subsidiaries or affiliates
-(together referred to as "FORE"), and which may not be reproduced, used, sold
-or transferred to any third party without FORE's prior written consent. All
-rights reserved.
-
-U.S. Government Restricted Rights. If you are licensing the Software on
-behalf of the U.S. Government ("Government"), the following provisions apply
-to you. If the software is supplied to the Department of Defense ("DoD"), it
-is classified as "Commercial Computer Software" under paragraph 252.227-7014
-of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any
-successor regulations) and the Government is acquiring only the license
-rights granted herein (the license rights customarily provided to non-Government
-users). If the Software is supplied to any unit or agency of the Government
-other than the DoD, it is classified as "Restricted Computer Software" and
-the Government's rights in the Software are defined in paragraph 52.227-19 of
-the Federal Acquisition Regulations ("FAR") (or any successor regulations) or,
-in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR
-(or any successor regulations).
-
-FORE Systems is a registered trademark, and ForeRunner, ForeRunnerLE, and
-ForeThought are trademarks of FORE Systems, Inc. All other brands or product
-names are trademarks or registered trademarks of their respective holders.
-
diff --git a/drivers/atm/fore200e_mkfirm.c b/drivers/atm/fore200e_mkfirm.c
deleted file mode 100644
index 520e14b488f..00000000000
--- a/drivers/atm/fore200e_mkfirm.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- mkfirm.c: generates a C readable file from a binary firmware image
-
- Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <time.h>
-
-char* default_basename = "pca200e"; /* was initially written for the PCA-200E firmware */
-char* default_infname = "<stdin>";
-char* default_outfname = "<stdout>";
-
-char* progname;
-int verbose = 0;
-int inkernel = 0;
-
-
-void usage(void)
-{
- fprintf(stderr,
- "%s: [-v] [-k] [-b basename ] [-i firmware.bin] [-o firmware.c]\n",
- progname);
- exit(-1);
-}
-
-
-int main(int argc, char** argv)
-{
- time_t now;
- char* infname = NULL;
- char* outfname = NULL;
- char* basename = NULL;
- FILE* infile;
- FILE* outfile;
- unsigned firmsize;
- int c;
-
- progname = *(argv++);
-
- while (argc > 1) {
- if ((*argv)[0] == '-') {
- switch ((*argv)[1]) {
- case 'i':
- if (argc-- < 3)
- usage();
- infname = *(++argv);
- break;
- case 'o':
- if (argc-- < 3)
- usage();
- outfname = *(++argv);
- break;
- case 'b':
- if (argc-- < 3)
- usage();
- basename = *(++argv);
- break;
- case 'v':
- verbose = 1;
- break;
- case 'k':
- inkernel = 1;
- break;
- default:
- usage();
- }
- }
- else {
- usage();
- }
- argc--;
- argv++;
- }
-
- if (infname != NULL) {
- infile = fopen(infname, "r");
- if (infile == NULL) {
- fprintf(stderr, "%s: can't open %s for reading\n",
- progname, infname);
- exit(-2);
- }
- }
- else {
- infile = stdin;
- infname = default_infname;
- }
-
- if (outfname) {
- outfile = fopen(outfname, "w");
- if (outfile == NULL) {
- fprintf(stderr, "%s: can't open %s for writing\n",
- progname, outfname);
- exit(-3);
- }
- }
- else {
- outfile = stdout;
- outfname = default_outfname;
- }
-
- if (basename == NULL)
- basename = default_basename;
-
- if (verbose) {
- fprintf(stderr, "%s: input file = %s\n", progname, infname );
- fprintf(stderr, "%s: output file = %s\n", progname, outfname );
- fprintf(stderr, "%s: firmware basename = %s\n", progname, basename );
- }
-
- time(&now);
- fprintf(outfile, "/*\n generated by %s from %s on %s"
- " DO NOT EDIT!\n*/\n\n",
- progname, infname, ctime(&now));
-
- if (inkernel)
- fprintf(outfile, "#include <linux/init.h>\n\n" );
-
- /* XXX force 32 bit alignment? */
- fprintf(outfile, "const unsigned char%s %s_data[] = {\n",
- inkernel ? " __initdata" : "", basename );
-
- c = getc(infile);
- fprintf(outfile,"\t0x%02x", c);
- firmsize = 1;
-
- while ((c = getc(infile)) >= 0) {
-
- if (firmsize++ % 8)
- fprintf(outfile,", 0x%02x", c);
- else
- fprintf(outfile,",\n\t0x%02x", c);
- }
-
- fprintf(outfile, "\n};\n\n");
-
- fprintf(outfile, "const unsigned int%s %s_size = %u;\n",
- inkernel ? " __initdata" : "", basename, firmsize );
-
- if (infile != stdin)
- fclose(infile);
- if (outfile != stdout)
- fclose(outfile);
-
- if(verbose)
- fprintf(stderr, "%s: firmware size = %u\n", progname, firmsize);
-
- exit(0);
-}
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index ea495b21f91..bdbad7edf68 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -75,14 +75,8 @@
#include <linux/atm.h>
#include <linux/sonet.h>
-#define USE_TASKLET
#undef USE_SCATTERGATHER
#undef USE_CHECKSUM_HW /* still confused about this */
-#define USE_RBPS
-#undef USE_RBPS_POOL /* if memory is tight try this */
-#undef USE_RBPL_POOL /* if memory is tight try this */
-#define USE_TPD_POOL
-/* #undef CONFIG_ATM_HE_USE_SUNI */
/* #undef HE_DEBUG */
#include "he.h"
@@ -388,9 +382,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
he_dev->atm_dev->dev_data = he_dev;
atm_dev->dev_data = he_dev;
he_dev->number = atm_dev->number;
-#ifdef USE_TASKLET
tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev);
-#endif
spin_lock_init(&he_dev->global_lock);
if (he_start(atm_dev)) {
@@ -787,23 +779,13 @@ he_init_group(struct he_dev *he_dev, int group)
{
int i;
-#ifdef USE_RBPS
/* small buffer pool */
-#ifdef USE_RBPS_POOL
he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev,
CONFIG_RBPS_BUFSIZE, 8, 0);
if (he_dev->rbps_pool == NULL) {
hprintk("unable to create rbps pages\n");
return -ENOMEM;
}
-#else /* !USE_RBPS_POOL */
- he_dev->rbps_pages = pci_alloc_consistent(he_dev->pci_dev,
- CONFIG_RBPS_SIZE * CONFIG_RBPS_BUFSIZE, &he_dev->rbps_pages_phys);
- if (he_dev->rbps_pages == NULL) {
- hprintk("unable to create rbps page pool\n");
- return -ENOMEM;
- }
-#endif /* USE_RBPS_POOL */
he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev,
CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys);
@@ -818,14 +800,9 @@ he_init_group(struct he_dev *he_dev, int group)
dma_addr_t dma_handle;
void *cpuaddr;
-#ifdef USE_RBPS_POOL
cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
-#else
- cpuaddr = he_dev->rbps_pages + (i * CONFIG_RBPS_BUFSIZE);
- dma_handle = he_dev->rbps_pages_phys + (i * CONFIG_RBPS_BUFSIZE);
-#endif
he_dev->rbps_virt[i].virt = cpuaddr;
he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF);
@@ -844,30 +821,14 @@ he_init_group(struct he_dev *he_dev, int group)
RBP_QSIZE(CONFIG_RBPS_SIZE - 1) |
RBP_INT_ENB,
G0_RBPS_QI + (group * 32));
-#else /* !USE_RBPS */
- he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
- he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
- he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
- he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
- G0_RBPS_BS + (group * 32));
-#endif /* USE_RBPS */
/* large buffer pool */
-#ifdef USE_RBPL_POOL
he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev,
CONFIG_RBPL_BUFSIZE, 8, 0);
if (he_dev->rbpl_pool == NULL) {
hprintk("unable to create rbpl pool\n");
return -ENOMEM;
}
-#else /* !USE_RBPL_POOL */
- he_dev->rbpl_pages = (void *) pci_alloc_consistent(he_dev->pci_dev,
- CONFIG_RBPL_SIZE * CONFIG_RBPL_BUFSIZE, &he_dev->rbpl_pages_phys);
- if (he_dev->rbpl_pages == NULL) {
- hprintk("unable to create rbpl pages\n");
- return -ENOMEM;
- }
-#endif /* USE_RBPL_POOL */
he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev,
CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys);
@@ -882,14 +843,9 @@ he_init_group(struct he_dev *he_dev, int group)
dma_addr_t dma_handle;
void *cpuaddr;
-#ifdef USE_RBPL_POOL
cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
-#else
- cpuaddr = he_dev->rbpl_pages + (i * CONFIG_RBPL_BUFSIZE);
- dma_handle = he_dev->rbpl_pages_phys + (i * CONFIG_RBPL_BUFSIZE);
-#endif
he_dev->rbpl_virt[i].virt = cpuaddr;
he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
@@ -1475,7 +1431,6 @@ he_start(struct atm_dev *dev)
he_init_tpdrq(he_dev);
-#ifdef USE_TPD_POOL
he_dev->tpd_pool = pci_pool_create("tpd", he_dev->pci_dev,
sizeof(struct he_tpd), TPD_ALIGNMENT, 0);
if (he_dev->tpd_pool == NULL) {
@@ -1484,20 +1439,6 @@ he_start(struct atm_dev *dev)
}
INIT_LIST_HEAD(&he_dev->outstanding_tpds);
-#else
- he_dev->tpd_base = (void *) pci_alloc_consistent(he_dev->pci_dev,
- CONFIG_NUMTPDS * sizeof(struct he_tpd), &he_dev->tpd_base_phys);
- if (!he_dev->tpd_base)
- return -ENOMEM;
-
- for (i = 0; i < CONFIG_NUMTPDS; ++i) {
- he_dev->tpd_base[i].status = (i << TPD_ADDR_SHIFT);
- he_dev->tpd_base[i].inuse = 0;
- }
-
- he_dev->tpd_head = he_dev->tpd_base;
- he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS - 1];
-#endif
if (he_init_group(he_dev, 0) != 0)
return -ENOMEM;
@@ -1606,9 +1547,7 @@ he_stop(struct he_dev *he_dev)
gen_cntl_0 &= ~(INT_PROC_ENBL | INIT_ENB);
pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-#ifdef USE_TASKLET
tasklet_disable(&he_dev->tasklet);
-#endif
/* disable recv and transmit */
@@ -1638,7 +1577,6 @@ he_stop(struct he_dev *he_dev)
he_dev->hsp, he_dev->hsp_phys);
if (he_dev->rbpl_base) {
-#ifdef USE_RBPL_POOL
int i;
for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
@@ -1647,22 +1585,14 @@ he_stop(struct he_dev *he_dev)
pci_pool_free(he_dev->rbpl_pool, cpuaddr, dma_handle);
}
-#else
- pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE
- * CONFIG_RBPL_BUFSIZE, he_dev->rbpl_pages, he_dev->rbpl_pages_phys);
-#endif
pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE
* sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys);
}
-#ifdef USE_RBPL_POOL
if (he_dev->rbpl_pool)
pci_pool_destroy(he_dev->rbpl_pool);
-#endif
-#ifdef USE_RBPS
if (he_dev->rbps_base) {
-#ifdef USE_RBPS_POOL
int i;
for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
@@ -1671,20 +1601,12 @@ he_stop(struct he_dev *he_dev)
pci_pool_free(he_dev->rbps_pool, cpuaddr, dma_handle);
}
-#else
- pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE
- * CONFIG_RBPS_BUFSIZE, he_dev->rbps_pages, he_dev->rbps_pages_phys);
-#endif
pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE
* sizeof(struct he_rbp), he_dev->rbps_base, he_dev->rbps_phys);
}
-#ifdef USE_RBPS_POOL
if (he_dev->rbps_pool)
pci_pool_destroy(he_dev->rbps_pool);
-#endif
-
-#endif /* USE_RBPS */
if (he_dev->rbrq_base)
pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
@@ -1698,14 +1620,8 @@ he_stop(struct he_dev *he_dev)
pci_free_consistent(he_dev->pci_dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq),
he_dev->tpdrq_base, he_dev->tpdrq_phys);
-#ifdef USE_TPD_POOL
if (he_dev->tpd_pool)
pci_pool_destroy(he_dev->tpd_pool);
-#else
- if (he_dev->tpd_base)
- pci_free_consistent(he_dev->pci_dev, CONFIG_NUMTPDS * sizeof(struct he_tpd),
- he_dev->tpd_base, he_dev->tpd_base_phys);
-#endif
if (he_dev->pci_dev) {
pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command);
@@ -1720,7 +1636,6 @@ he_stop(struct he_dev *he_dev)
static struct he_tpd *
__alloc_tpd(struct he_dev *he_dev)
{
-#ifdef USE_TPD_POOL
struct he_tpd *tpd;
dma_addr_t dma_handle;
@@ -1735,27 +1650,6 @@ __alloc_tpd(struct he_dev *he_dev)
tpd->iovec[2].addr = 0; tpd->iovec[2].len = 0;
return tpd;
-#else
- int i;
-
- for (i = 0; i < CONFIG_NUMTPDS; ++i) {
- ++he_dev->tpd_head;
- if (he_dev->tpd_head > he_dev->tpd_end) {
- he_dev->tpd_head = he_dev->tpd_base;
- }
-
- if (!he_dev->tpd_head->inuse) {
- he_dev->tpd_head->inuse = 1;
- he_dev->tpd_head->status &= TPD_MASK;
- he_dev->tpd_head->iovec[0].addr = 0; he_dev->tpd_head->iovec[0].len = 0;
- he_dev->tpd_head->iovec[1].addr = 0; he_dev->tpd_head->iovec[1].len = 0;
- he_dev->tpd_head->iovec[2].addr = 0; he_dev->tpd_head->iovec[2].len = 0;
- return he_dev->tpd_head;
- }
- }
- hprintk("out of tpds -- increase CONFIG_NUMTPDS (%d)\n", CONFIG_NUMTPDS);
- return NULL;
-#endif
}
#define AAL5_LEN(buf,len) \
@@ -1804,11 +1698,9 @@ he_service_rbrq(struct he_dev *he_dev, int group)
RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "",
RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : "");
-#ifdef USE_RBPS
if (RBRQ_ADDR(he_dev->rbrq_head) & RBP_SMALLBUF)
rbp = &he_dev->rbps_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))];
else
-#endif
rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))];
buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
@@ -1887,12 +1779,10 @@ he_service_rbrq(struct he_dev *he_dev, int group)
for (iov = he_vcc->iov_head;
iov < he_vcc->iov_tail; ++iov) {
-#ifdef USE_RBPS
if (iov->iov_base & RBP_SMALLBUF)
memcpy(skb_put(skb, iov->iov_len),
he_dev->rbps_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
else
-#endif
memcpy(skb_put(skb, iov->iov_len),
he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len);
}
@@ -1937,11 +1827,9 @@ return_host_buffers:
for (iov = he_vcc->iov_head;
iov < he_vcc->iov_tail; ++iov) {
-#ifdef USE_RBPS
if (iov->iov_base & RBP_SMALLBUF)
rbp = &he_dev->rbps_base[RBP_INDEX(iov->iov_base)];
else
-#endif
rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)];
rbp->status &= ~RBP_LOANED;
@@ -1977,9 +1865,7 @@ he_service_tbrq(struct he_dev *he_dev, int group)
he_dev->hsp->group[group].tbrq_tail);
struct he_tpd *tpd;
int slot, updated = 0;
-#ifdef USE_TPD_POOL
struct he_tpd *__tpd;
-#endif
/* 2.1.6 transmit buffer return queue */
@@ -1991,7 +1877,6 @@ he_service_tbrq(struct he_dev *he_dev, int group)
TBRQ_TPD(he_dev->tbrq_head),
TBRQ_EOS(he_dev->tbrq_head) ? " EOS" : "",
TBRQ_MULTIPLE(he_dev->tbrq_head) ? " MULTIPLE" : "");
-#ifdef USE_TPD_POOL
tpd = NULL;
list_for_each_entry(__tpd, &he_dev->outstanding_tpds, entry) {
if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) {
@@ -2006,9 +1891,6 @@ he_service_tbrq(struct he_dev *he_dev, int group)
TBRQ_TPD(he_dev->tbrq_head));
goto next_tbrq_entry;
}
-#else
- tpd = &he_dev->tpd_base[ TPD_INDEX(TBRQ_TPD(he_dev->tbrq_head)) ];
-#endif
if (TBRQ_EOS(he_dev->tbrq_head)) {
HPRINTK("wake_up(tx_waitq) cid 0x%x\n",
@@ -2038,12 +1920,8 @@ he_service_tbrq(struct he_dev *he_dev, int group)
}
next_tbrq_entry:
-#ifdef USE_TPD_POOL
if (tpd)
pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
-#else
- tpd->inuse = 0;
-#endif
he_dev->tbrq_head = (struct he_tbrq *)
((unsigned long) he_dev->tbrq_base |
TBRQ_MASK(++he_dev->tbrq_head));
@@ -2086,7 +1964,6 @@ he_service_rbpl(struct he_dev *he_dev, int group)
he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T);
}
-#ifdef USE_RBPS
static void
he_service_rbps(struct he_dev *he_dev, int group)
{
@@ -2113,7 +1990,6 @@ he_service_rbps(struct he_dev *he_dev, int group)
if (moved)
he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T);
}
-#endif /* USE_RBPS */
static void
he_tasklet(unsigned long data)
@@ -2124,9 +2000,7 @@ he_tasklet(unsigned long data)
int updated = 0;
HPRINTK("tasklet (0x%lx)\n", data);
-#ifdef USE_TASKLET
spin_lock_irqsave(&he_dev->global_lock, flags);
-#endif
while (he_dev->irq_head != he_dev->irq_tail) {
++updated;
@@ -2141,9 +2015,7 @@ he_tasklet(unsigned long data)
case ITYPE_RBRQ_TIMER:
if (he_service_rbrq(he_dev, group)) {
he_service_rbpl(he_dev, group);
-#ifdef USE_RBPS
he_service_rbps(he_dev, group);
-#endif /* USE_RBPS */
}
break;
case ITYPE_TBRQ_THRESH:
@@ -2156,9 +2028,7 @@ he_tasklet(unsigned long data)
he_service_rbpl(he_dev, group);
break;
case ITYPE_RBPS_THRESH:
-#ifdef USE_RBPS
he_service_rbps(he_dev, group);
-#endif /* USE_RBPS */
break;
case ITYPE_PHY:
HPRINTK("phy interrupt\n");
@@ -2186,9 +2056,7 @@ he_tasklet(unsigned long data)
he_service_rbrq(he_dev, 0);
he_service_rbpl(he_dev, 0);
-#ifdef USE_RBPS
he_service_rbps(he_dev, 0);
-#endif /* USE_RBPS */
he_service_tbrq(he_dev, 0);
break;
default:
@@ -2210,9 +2078,7 @@ he_tasklet(unsigned long data)
IRQ_TAIL(he_dev->irq_tail), IRQ0_HEAD);
(void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata; flush posted writes */
}
-#ifdef USE_TASKLET
spin_unlock_irqrestore(&he_dev->global_lock, flags);
-#endif
}
static irqreturn_t
@@ -2244,11 +2110,7 @@ he_irq_handler(int irq, void *dev_id)
if (he_dev->irq_head != he_dev->irq_tail) {
handled = 1;
-#ifdef USE_TASKLET
tasklet_schedule(&he_dev->tasklet);
-#else
- he_tasklet((unsigned long) he_dev);
-#endif
he_writel(he_dev, INT_CLEAR_A, INT_FIFO); /* clear interrupt */
(void) he_readl(he_dev, INT_FIFO); /* flush posted writes */
}
@@ -2305,23 +2167,14 @@ __enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid)
dev_kfree_skb_any(tpd->skb);
atomic_inc(&tpd->vcc->stats->tx_err);
}
-#ifdef USE_TPD_POOL
pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
-#else
- tpd->inuse = 0;
-#endif
return;
}
}
/* 2.1.5 transmit packet descriptor ready queue */
-#ifdef USE_TPD_POOL
list_add_tail(&tpd->entry, &he_dev->outstanding_tpds);
he_dev->tpdrq_tail->tpd = TPD_ADDR(tpd->status);
-#else
- he_dev->tpdrq_tail->tpd = he_dev->tpd_base_phys +
- (TPD_INDEX(tpd->status) * sizeof(struct he_tpd));
-#endif
he_dev->tpdrq_tail->cid = cid;
wmb();
@@ -2511,13 +2364,8 @@ he_open(struct atm_vcc *vcc)
goto open_failed;
}
-#ifdef USE_RBPS
rsr1 = RSR1_GROUP(0);
rsr4 = RSR4_GROUP(0);
-#else /* !USE_RBPS */
- rsr1 = RSR1_GROUP(0)|RSR1_RBPL_ONLY;
- rsr4 = RSR4_GROUP(0)|RSR4_RBPL_ONLY;
-#endif /* USE_RBPS */
rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ?
(RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0;
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
index b87d6ccabac..c2983e0d4ec 100644
--- a/drivers/atm/he.h
+++ b/drivers/atm/he.h
@@ -51,8 +51,6 @@
#define CONFIG_IRQ_SIZE 128
#define CONFIG_IRQ_THRESH (CONFIG_IRQ_SIZE/2)
-#define CONFIG_NUMTPDS 256
-
#define CONFIG_TPDRQ_SIZE 512
#define TPDRQ_MASK(x) (((unsigned long)(x))&((CONFIG_TPDRQ_SIZE<<3)-1))
@@ -140,12 +138,7 @@ struct he_tpd {
struct sk_buff *skb;
struct atm_vcc *vcc;
-#ifdef USE_TPD_POOL
struct list_head entry;
-#else
- u32 inuse;
- char padding[32 - sizeof(u32) - (2*sizeof(void*))];
-#endif
};
#define TPD_ALIGNMENT 64
@@ -291,16 +284,9 @@ struct he_dev {
volatile unsigned *irq_tailoffset;
int irq_peak;
-#ifdef USE_TASKLET
struct tasklet_struct tasklet;
-#endif
-#ifdef USE_TPD_POOL
struct pci_pool *tpd_pool;
struct list_head outstanding_tpds;
-#else
- struct he_tpd *tpd_head, *tpd_base, *tpd_end;
- dma_addr_t tpd_base_phys;
-#endif
dma_addr_t tpdrq_phys;
struct he_tpdrq *tpdrq_base, *tpdrq_tail, *tpdrq_head;
@@ -311,25 +297,13 @@ struct he_dev {
struct he_rbrq *rbrq_base, *rbrq_head;
int rbrq_peak;
-#ifdef USE_RBPL_POOL
struct pci_pool *rbpl_pool;
-#else
- void *rbpl_pages;
- dma_addr_t rbpl_pages_phys;
-#endif
dma_addr_t rbpl_phys;
struct he_rbp *rbpl_base, *rbpl_tail;
struct he_virt *rbpl_virt;
int rbpl_peak;
-#ifdef USE_RBPS
-#ifdef USE_RBPS_POOL
struct pci_pool *rbps_pool;
-#else
- void *rbps_pages;
- dma_addr_t rbps_pages_phys;
-#endif
-#endif
dma_addr_t rbps_phys;
struct he_rbp *rbps_base, *rbps_tail;
struct he_virt *rbps_virt;
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 139fce6968a..24df73ad326 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -65,12 +65,7 @@
#include "iphase.h"
#include "suni.h"
#define swap(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
-struct suni_priv {
- struct k_sonet_stats sonet_stats; /* link diagnostics */
- unsigned char loop_mode; /* loopback mode */
- struct atm_dev *dev; /* device back-pointer */
- struct suni_priv *next; /* next SUNI */
-};
+
#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
@@ -94,10 +89,6 @@ module_param(IADebugFlag, uint, 0644);
MODULE_LICENSE("GPL");
-#if BITS_PER_LONG != 32
-# error FIXME: this driver only works on 32-bit platforms
-#endif
-
/**************************** IA_LIB **********************************/
static void ia_init_rtn_q (IARTN_Q *que)
@@ -1411,7 +1402,6 @@ static int rx_init(struct atm_dev *dev)
struct abr_vc_table *abr_vc_table;
u16 *vc_table;
u16 *reass_table;
- u16 *ptr16;
int i,j, vcsize_sel;
u_short freeq_st_adr;
u_short *freeq_start;
@@ -1426,14 +1416,15 @@ static int rx_init(struct atm_dev *dev)
printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n");
goto err_out;
}
- iadev->rx_dle_q.start = (struct dle*)dle_addr;
+ iadev->rx_dle_q.start = (struct dle *)dle_addr;
iadev->rx_dle_q.read = iadev->rx_dle_q.start;
iadev->rx_dle_q.write = iadev->rx_dle_q.start;
- iadev->rx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
+ iadev->rx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
/* the end of the dle q points to the entry after the last
DLE that can be used. */
/* write the upper 20 bits of the start address to rx list address register */
+ /* We know this is 32bit bus addressed so the following is safe */
writel(iadev->rx_dle_dma & 0xfffff000,
iadev->dma + IPHASE5575_RX_LIST_ADDR);
IF_INIT(printk("Tx Dle list addr: 0x%08x value: 0x%0x\n",
@@ -1587,11 +1578,12 @@ static int rx_init(struct atm_dev *dev)
Set Packet Aging Interval count register to overflow in about 4 us
*/
writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT );
- ptr16 = (u16*)j;
- i = ((u32)ptr16 >> 6) & 0xff;
- ptr16 += j - 1;
- i |=(((u32)ptr16 << 2) & 0xff00);
+
+ i = (j >> 6) & 0xFF;
+ j += 2 * (j - 1);
+ i |= ((j << 2) & 0xFF00);
writew(i, iadev->reass_reg+TMOUT_RANGE);
+
/* initiate the desc_tble */
for(i=0; i<iadev->num_tx_desc;i++)
iadev->desc_tbl[i].timestamp = 0;
@@ -1914,7 +1906,7 @@ static int tx_init(struct atm_dev *dev)
iadev->tx_dle_q.start = (struct dle*)dle_addr;
iadev->tx_dle_q.read = iadev->tx_dle_q.start;
iadev->tx_dle_q.write = iadev->tx_dle_q.start;
- iadev->tx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
+ iadev->tx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
/* write the upper 20 bits of the start address to tx list address register */
writel(iadev->tx_dle_dma & 0xfffff000,
@@ -2907,7 +2899,7 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
dev_kfree_skb_any(skb);
return 0;
}
- if ((u32)skb->data & 3) {
+ if ((unsigned long)skb->data & 3) {
printk("Misaligned SKB\n");
if (vcc->pop)
vcc->pop(vcc, skb);
diff --git a/drivers/atm/pca200e.data b/drivers/atm/pca200e.data
deleted file mode 100644
index e78e83becd9..00000000000
--- a/drivers/atm/pca200e.data
+++ /dev/null
@@ -1,850 +0,0 @@
-:150000001F8B0808AB5A10380203706361323030652E62696E4D
-:150015007D00E43A0D7014D7796FA5BDE84EC86211A7333020EE
-:15002A00AD89C00A23EA83AA589C7E7C38D8152EB887477677D3
-:15003F0095C39C3DB2AB388CA324C4A509352BFBB085BBD0C73F
-:150054007210B903C92991CCD1B1C242255BCCD81EA5C34C6826
-:1500690006271AC6D36A3A31B976D4A9A683DB4B07BB38265C56
-:15007E00BFEFBDB7777BA7030B2733994C35737AFBBEF7BDEFE7
-:15009300EF7DDFF7BEF7769FFEEAD79F221221E1ED844C3E4677
-:1500A8007EA3BFF036F827CF8597C3AF0C7E920B16595BCE5AA8
-:1500BD00296B6483D83E9F7DBE8FF50BE74A0B45FB1F274FAA79
-:1500D200D82E2867139DF637FD937EF1D55FB0769FE8678BDAFB
-:1500E7007D9BD8885451515172FE27E4138E9FC9949CBFF026BC
-:1500FC00741DF83ECE59823FF23BF89346493F6B4F17C1B3A7CE
-:15011100B3B79C97D3275B5ABFEC3CF9579457703B3CBFEFD600
-:15012600FC38236CA91B5E347EDBFA67F7ED4397956EA4D3C5F4
-:15013B007CE6A567799EFFF5CFC4FF7BDF938BF83E83EDE59F02
-:15015000FEAC24BF8A3C3F2FF9FDFF933CF51EF2FFEC2FEBFA11
-:150165002341C38CBC5F4EAA265F5EAF04BC51F0059FD1419ED8
-:15017A00063493D465A2384E66A0171C30231F40AB5CB5646FC8
-:15018F005CBFB633DECCC614D2DAF622F15D3189EFEA3EE28B83
-:1501A4007D99F8DABE4D7C2418A438AF3129015D7507F1032EBA
-:1501B900E174827F46C82229AE2BC63A9D50E9253960EC005FCA
-:1501CE00F2EDFE0AF12A9D5EBD6A35F1B5AC441A49BAD94F22C6
-:1501E300DECB544F180D1A51FACD8C4A7C034B93DAFD6455A8F9
-:1501F8009AAC5AB74C9542EF11E23DB0946A0F1B0DA10BF0CC0C
-:15020D00F9A4A8097BCA1D751474A02FEC02593C75C9E870D176
-:15022200B8CF352EC3783C379E1C2893C98017C6A57B3CDD0E4D
-:15023700CE32426A9CB99F03FC2E81BF46AD0D06544FD0190B08
-:15024C00C0580B8E897EFDF490DE08FD652E9CFAE911DD5F24FE
-:15026100CF832469DAB1116BE0F3C437B686F8D275C437AC9220
-:150276000542BFF6CC0320B22AB7237E1F5B97A4E927A397490C
-:15028B0064C43AFF0CD8ACCE8886D37F632A7F4C16005E289CAF
-:1502A0003E491DDAFB083513C6B0A6B8E4929626F531E0877479
-:1502B50082E58C9E2503DDD45DC4777E3BF1051F253E09684E42
-:1502CA00C3BAC26825AC39F5225F6598EE23B366227C52ABFC3A
-:1502DF00BC2754E61BD1FFEBAE6DCDFE8D49AAEA38EE89A35A1B
-:1502F4009DF0DCF4254234681BBB09E98536033F2F3C5F835F24
-:15030900107E147E1AE8AA0406A36989DB63C95ADE9F9272EBA7
-:15031E00C17C6131AC4519193457028723BE118D0433D6F063E5
-:150333005C6E1C77EC2981FD118663B2FA3A455F8D11A2D66BC0
-:15034800AFE9B096E6D4A38454D70D004ECA8235541117C7A5F2
-:15035D002D26F8E4B07D3848BA956402FC7BF8EC956CB6B6D35F
-:1503720091EB21B280C218CAB04122B5957583D126189B7D88FF
-:15038700FB2BDA46560F52056C867C6CE85FF1135F19E0C948D1
-:15039C0023873342916798F3A6E45FA58C9021887DB9A8DF9307
-:1503B1002EECF7421F693AB054DE6F73F4FDF414E83A6B66B2C0
-:1503C6000B11C3BA0E45D0D1074E3318C92C24FE074FF267E847
-:1503DB00E03AE67193D635C40D9FD66A65B471CABA5AC66D9C17
-:1503F00081B68DE4F5200AEA316B3E3EF5F8D4CAF0C902BFBC6E
-:1504050003FD12ED00BE39F8E7C4E765F2A6F8BCC8083DA6B648
-:15041A00335DAAA0AFC4DEA66A6CDC8418EA26910FAD6A0821BE
-:15042F0012B4A9C269D1DDAC9DB05A98BD06B91D807702D6021B
-:15044400F02CA479BF88CD3D82BE3F92D49137C262E0EB5969BB
-:15045900D6AC8DA4F4A3A0EB808FEB8570E6F34897F9F77CE4C2
-:15046E0071E4E07C73F2C0FC256AC3208B2D5C834D43BA3F060F
-:15048300F39566B386103FC611E321E23D02F1168A79426C3DFD
-:15049800E159DA32AAA34C083FBA62DC2474847A94BF031D86A2
-:1504AD00ACE5EAEB969CDC4FF3F3216F03DE5414FD8ED3DA3050
-:1504C2005F5AC953795A804F2146D05612811C0DB6A0BC0E67DE
-:1504D7007C6E471FC3A5CFA04B06639EFA201E11FA182E7D3E53
-:1504EC009556913E89227D129F511FDBA5CF05970CF63CF54199
-:15050100BCE097B83EB64B9F4FA555A4CF60913E839F511F752A
-:1505160026AF4FCB4C5E0684CF471FC48B75737DF079C37C69B3
-:15052B0015E973BC489FE32E7DC231AFD997FEF15925301975DC
-:150540007CBC5E33F5D918F2E53E82FD69D1B745FF82E8237F22
-:15055500EC4FB07ED2A4626FD8C3F7363321FA29D11F14FD6938
-:15056A00D13F2EFA9D40678FFA1ACBD131181B507F88FBA8451E
-:15057F00E179507D8362EC4FC2734A7D8786D5D526CF431356CC
-:1505940010E6D51152BB2CE6690F243DED35694FBB17D6017487
-:1505A900B251C766F514A3D3037337AB67189D043C77A9E728AB
-:1505BE00CE3FCFE5A0C8B347ED17F9CDB09A812EE4A09AFBC861
-:1505D30005F3ECCE1F76B0B8059C6AD51342D87777BEC16093F7
-:1505E8002ED82B3BDF613094C9813DB7F3A50E87FE6A95AF1F58
-:1505FD00D259C69E53B447F047991EAA1FDDE8D0747091968332
-:15061200EBC88AB2D5095CA4FB07AA87ED030961D37494DB348F
-:15062700C27225D77D497EBF32958271CE6F8DA0D12CF612E37F
-:15063C00718ED32568206F3FDF874C7B477EAC4DD8310AE35B40
-:15065100C17E683B139EA3EA6178A6D65B4CA65926E72EF555F4
-:150666007A82D977D06A9A610E58F3D80D4F6BFDF4DDFAC37506
-:15067B00E7D67D672AA93DD881720C301B55C6E4D0860EB97506
-:150690007D5DFF3A0A636BD898CDE4AD4C7A42CBDE915B037587
-:1506A50087D7593056DDC1E5477B55429CDCF8B5DCFAAB15AFBD
-:1506BA00AE3B0263FFD3EE69AF8C5584FEF3FD0FDA90E6BFADE7
-:1506CF0030DB70FEBF9C186B43DC4BEFBFDE4682BD8C27C86F5A
-:1506E400B3BC185CC264063DED086BF730DA2418B655D6F63110
-:1506F900394850B53126EEFCD1AC2EBD1B83F83B6D56056C5662
-:15070E0027F079B3565739DFC3A2AC8D591AB48B37FD4097B6BD
-:150723007D4527CA41F38E00D6C48665887A30CEDA5E6BA09CE8
-:15073800EF7568CF8A7EC03FF80DC05F6B56078280AFB25C86D9
-:15074D00F863ACEDB32658DBC26CBEE04780FFEEB7017F9BB98C
-:15076200301001FCB0C5E54E5A0DD0BEC8D6618FD53893DFDBC0
-:15077700489D0A781A5B9B27616DFAD4435409C08E179C365B01
-:15078C00B86D2C5EB34E5BCDD0CEC0B98106CBBA25A29A87AEC7
-:1507A100676BD0977601BC4A7DCDC2BA15ED575E1DD7B78610CF
-:1507B6008FC715EE954F0A5CB4B78837139F9F079E8AEFA21E32
-:1507CB00DF9814679714AB9163E99F59FEBDE3263A704FFA4DF8
-:1507E0000BFAD400D9FCE1115DF1C541C7772D591DB7BA1C7929
-:1507F500D4BBCC1B9F701EC761BE22E4A1429EB736E6E5C1BDA9
-:15080A00EE92C09D74C933790B79222E79BA401EE8535A429E39
-:15081F00F3ABF2F23C2B785CC43812F24C0A799A5CF2E05E759D
-:15083400BFC0457F73E4C1E79BC91376C9B319E4813E4D9690D5
-:15084900A7D925CFE55F711E6D33B8A771799007CA73BC252F86
-:15085E000FEE3567392EE35506B935DE3E625D87B3AC9363DDC5
-:15087300675D387B325FEEC53DCA370CF1D064D2707F1F9E1BAD
-:15088800BCCC7732962CFCB60AF76B17AFD80C1694A4D6EBDAB7
-:15089D0047E58DFC1CEB75E1E10563311E21B6794C95704FA00C
-:1508B20031EEBF8BC93DD0270326EC0F8A54674771FCCEF0B040
-:1508C7007E67F81CD864D8EA401CC819480FE1811DBC76E5FDFE
-:1508DC00733A83FDD508D6AA24406D9DCF3FA75FCC66FD65D592
-:1508F100FDFAEE7BF332F5F0FDC225936D769033AD01550A3A24
-:15090600BCF12CBF86F184F305E007567C68E59EDB3FCCF1498D
-:15091B00D79F692B73E8803CC25E4CAEDA152370463A4A2DE42F
-:15093000AB34998BC0DE1BD01C0AA7C5715314ED0FC74F4B510E
-:150945005ED2BDC9319893001F18B3A2AE734B17D4E2CFA89EB1
-:15095A00D6B7245E6394E2F350520E95A6DD6079943780F65B70
-:15096F00507B1C857AE36D0B6B12491D8133EA88E6D41A72B92A
-:15098400A835607E52D421448C255D7548EE0F723FD656E84744
-:15099900CA3D28974DE33C4751AF90CFEB9603D61BE545BA8197
-:1509AE00906D2A44D446CA190BE550DE5F85B273DF637264CCC1
-:1509C300C15E487501388B928C8974B4ED9C4E8FD80F395D9B32
-:1509D800D9A7F6FDFD5482B3B6141B358F92514D3A30CEEA2EE8
-:1509ED003EC7B6108744E478BE6ECB98555F46FA54D0E77A23D8
-:150A0200FDE876AE1FE7932AE0C3EC226CC2EC98E676BC7347DE
-:150A1700DC0A446C361675F3A48267306C72595A4C85D9A5D310
-:150A2C006467AB60D0E4761AA00C1E19A6CFDE057584F27DAC4C
-:150A4100810A64F09F5845DD6B073896ACC05936324E1D3FC1D0
-:150A56001C843796C7485C2391FD168998CC2EAC0E807119F419
-:150A6B00A52D86899716E555719D1E5CABF77860FDA686D87D2E
-:150A8000881FD74839ABCBEADB34C06AE6FC196F49F9DC3367A7
-:150A9500FF9653FCBCE83E774E9DC198FD9433E7203F734E0EF2
-:150AAA00E7CE9BECEC19F9BEE5F8961C30A2634DFCFEA0D0B70D
-:150ABF00B82FA14CBDC23E6C6D4249E6574419B2081DA247F1E2
-:150AD400AE02FC0A7D81D9CC00FA74C84ADCC82E72F9336B3524
-:150AE90075186487D8A757CCC5B06FE37D56B5BAAAF912D674D6
-:150AFE0012F13EA3AE0D5D83985C9FF6B7B3DAEE31CEB713DA06
-:150B130045E420F33B90DB12700BE117C47D4058E0468A700568
-:150B2800DC42F87111EF0EFD1E316777D11C01B710DE2BE8F75C
-:150B3D000A5CA30857C02D84B709FA2B05FD06818B78F8BCDCC9
-:150B5200956F1A5D63F88C67293C4379C18FCAAB46C037862CF0
-:150B6700B497ACBCA2E37A07D5613B00F6AA091FED901553AFF3
-:150B7C00EDBFA257A9A7AC65C6076D814DFFADCBB131EB44D2FC
-:150B9100D3ED8D9966269B5D0C355EAB1CBB62393E5B09B92DA1
-:150BA6007D3DEB73C7C0B7A0CE95599D4AE7C4A388AF5C5E4121
-:150BBB001ACAA1213D513EACA16C353B1A2C279ED9DA634E30EB
-:150BD0002027A4DFC63C22E273C22A8E67F405C61362C61D27AE
-:150BE5002FDE11D7C365DC0F1591D33E2D4E5E82FD3B17230768
-:150BFA008634CC078AD84F31565642CAC2B3E0D3AC9E17310500
-:150C0F00F1F318F89BA8DF73B0FBC5B9E2E6B1D4226269A8F448
-:150C2400FD8D2B9E7ABEF0DBCFD57473E2296C3D2DEC7EBCF2E1
-:150C3900AE00DF13950DDEA802CFB7FA713CC25A35E0ECA52AC3
-:150C4E00D412F544A96ED2E3655F78CA23E0B4C678CA19C73BC6
-:150C63007A25DCF084ECD008279EA8719E37E5E1B9FD8ADDB182
-:150C78000DC0764CD423AADC4D73B519BFDF7C84EDF7B3589BA5
-:150C8D002978178F2324729206D4F666ACDF181C6C7FFDBEF62F
-:150CA2003F04FFB4091D3E8BEDE2C8A08EF7A1481361354A427E
-:150CB700BF0075C79CFD52F0EFBA09FFF58CFF80C9F2281DB6EB
-:150CCC00918E943ECEE946809780E173BA047D6A637DC3E9E326
-:150CE100FD30D41426ABD5A0BF066353F5B7AD57AB426111E732
-:150CF6002175793BD0A435CA01DD9101E36E51513FF72CF85916
-:150D0B00533FD0D6AB0F846AD4079A03EAAAD056276FA94F71C2
-:150D2000DA82A6E43B3E87AEF48FB786AD4E2F6F75EEA36584E2
-:150D3500837D8F64208743DE10F7CD8B56A7E5565C0F7627CD82
-:150D4A0071E811C84132E2404C200ECA9A85BA8E1AFB35425244
-:150D5F00980BCDECDF9F97C1AF71CF55D02E2C2EA660BF823D2D
-:150D74006135190E61FC6476BEDEE1BEA7FD9C787F107F84E908
-:150D89005860EF2C9930495D2A9AA76D08DAB6C1624F81FD644F
-:150D9E0072445B638C94A45D2168373E42BCEE7D285F5F65CC2D
-:150DB300E4D7B03E3172F5C9FCF381CDF301E856321F28AE3A51
-:150DC80028771E688C4A5BD641CD07B107B58A72379C210E6DFD
-:150DDD00D477415EF648712D0AAD1C4846132A3F977C1772DDE5
-:150DF200B1E4C7CDE4EA10BDF6B5FC7B8D3D5FFFDDFEA623C476
-:150E070037F149D60767196DF37D72BB73D787F76764B77176CD
-:150E1C0012DFEDED4E9E9D62ED24C612B4E9B319F6CE0FCEC553
-:150E310060A795E28EC5592B49ACD55EA03DFBA77C1F408D2F19
-:150E4600C19925111ED61AB1FD22D431CC768DCC76686BC46913
-:150E5B00025948755C5BFE89B05F4C62F603E3079A805E15C03F
-:150E70007F7E9F7C2F5BCFEDA2BE82166B17AC59900EF6BB59E8
-:150E85003D95F781473ED50706C49DFE70491F5072FB7DC6422E
-:150E9A009DC136B6B08D2D6C630BDBD8689B72C8E56E9F99AF8B
-:150EAF003DF1DD13D451C14A757F10CEF8BE3C6C2DC00E06535C
-:150EC40005B03F02D8D1E09803AB42582DC056042711C6EE3D4A
-:150ED900B87DDFFB18EC09763DFFF15CBBBEF730F18D7D8C764C
-:150EEE006DB877BE7ACD579F7809FF2813FE1105BE17B615CA1F
-:150F0300D922135F23C8E20159979490B511E67899AC4DF7DEFF
-:150F1800CE1ACC57DEDE12F2960B795F0759976C9BEBCF06FAC8
-:150F2D004B095F8E5DCBFACA408FC8B5B97AC4804EF81AEAE194
-:150F4200BFF7767DE976F4E929A18F2CF4F9F956E2EB84DF675D
-:150F5700E1BFF97F4127B5812A6A1365EFE620074AB029B701EC
-:150F6C001CFB32E934357C0E6AA60AD659AEEA96A26EFA5B76F9
-:150F8100970E79676B6C88BD2B8E7D53DCF73CC76A5433FD0D60
-:150F9600A89D643847E33B55DC9401EF62EC9455F5C419EBC295
-:150FAB00479C3601BAD9858639057D89F7BD631F15CA33267057
-:150FC000DF83B68B244DBFCAF9118DF3433EC8CFDE5DC86F3932
-:150FD500E0553D71CADA0AFC3441837EC4F9C5043FE87BDDF609
-:150FEA0054843DCD3FE1EFB8AF3E440AC61789F15D62FCBDA29D
-:150FFF00F11A31BE558C8F158D2F16E34D623CC1C63366D79E29
-:15101400FC793F0B3A5202FB37ECD5DEE52452707687BF81A5FC
-:15102900B646E14C41EA923BF0AC5963EC5F87EFF53591D70ED8
-:15103E002C9DD53AC22F873A5DF7E92F4C3CF113B4D573BB2F35
-:1510530075045DF0CBAFFEF57584B7EEF84987FBFE7DFA8D6F83
-:151068009D40F893FFF0E30EC2BE871834E3FFFC179BFC0163E8
-:15107D0047B297F8269F24BE3972BAEE17827F59B87FCB380E23
-:15109200F9167388548D39197231C24AECC74EAE81B351FBEE40
-:1510A7002DE2DE07700F6C19D52A638F065F811671F66EE7672C
-:1510BC003C1C73CE320C5644AF8EDFF7F1EF332E0FE8F683F8F2
-:1510D1001D01FB1640C47E8ADD2918BE51B6571056CB2419BE69
-:1510E6005F39CDEE52768B7B1784A9EA283B4BED71C18202D67F
-:1510FB00E7823509D8DE99FCB707866B1CED4B26086954472D8C
-:15111000370CBF436C2882554932692E84518A67BFD838550E10
-:151125008DEA2D3826F4C6EF6508BD9BD99D8AF91FDC58F453B2
-:15113A002F9B9FF345D18A7E649C4A07F09C0338ECFD3DE713EE
-:15114F005647E93EA827B19EC2F3EE65F0B7441FE9C6F74ED3D0
-:15116400397FE1B66DACE2760DA74FE6E40CA74FD3FE2DE3DA2C
-:151179006675DC72D37C79E98086FB33D28C15ECEFA3ECEE6226
-:15118E00AB80ED1132EE113206605F6732E27B2576864DE1DED8
-:1511A300CF6A05B6F78BB51C106B298B6F2998CDA06605DE16C5
-:1511B8007EFF9280338317CFA17866127A7845AB14B5176F64D1
-:1511CD000BEA546EDF93EC5E0EF76903F4C3332E3E3B30F2F086
-:1511E2005C58991BC6EAE794D509272B493C6F56381C6C66A124
-:1511F700DD6A33CCCE0143C8C160013B1AD89812E727389FC223
-:15120C009C5A03D60DD688B591717321D2A3A356297C52029F42
-:15122100E4F0DFE4F605183C5B7B9DCFF944FCBD20F4E4B19C55
-:1512360062758BE4E804CF57A514F3F7A03F3FFEF296FCB8034D
-:15124B007BA9044C7E782ECCE386B9623AE7DF22A69C7875C78E
-:15126000727F512C633B25C66E36C72831C7196BC4F68BF9B97C
-:151275009590BB8DBBC902278FA04D5E747C0E9EEBA7E37AAC39
-:15128A00687CC1E594CE69A4CC1648B68998A71B7CAC06F7016D
-:15129F0073733E27A17F605C38637DEE31F6ED1BA7C35A178D76
-:1512B400CE221A8E0DB80F7298510C037A2F38307F1E66948027
-:1512C900555617C250A7FD2E9D1D58BC04ACBCDA0D334CBB4EC1
-:1512DE0026E1D5C23EB08F60CEC0B8F483CF634D85DFE4B17ECD
-:1512F3002015AD75BD4B225584BD3342FFF533FF1D311D3FAFDB
-:151308003C84DF1BD87400BFB50BF35C568A8672DB34600CF7B2
-:15131D00176514F12C2D1717498AF91CF3E12ECC25D0C77907C1
-:1513320097A634461F7DC54F6829B8E2829B6EFC25A5E10AC018
-:151347007B9DEFDEEA788E75DB6BAB74137BF94BEBBAE0B20DCC
-:15135C0067E4D1BE83504BB03C301FBBFD1669A19EB75A03F3CC
-:1513710076E4FACCB40AD7D51679DED9AB793E2EB475613E2E11
-:15138600210BCCE1B2A44CD602ED85480F6ABE927628814F729C
-:15139B00F885F2ED75F91DC6AF543D37BE49F5DCF82EAB9E1BB7
-:1513B000CBA404EC15DFDCF8F654CF8D65B90886F847DC73F32E
-:1513C500EF3C2B79FD8531CEF706B469BD6BEF83D6D825BEDF9F
-:1513DA0020AEBD50291A935D63FEA231AF6B6C49D158956B6C58
-:1513EF00B922F611E52D4A1493CAEA307BCFC4BF63A4F41A6BD3
-:1514040007E9F532BEE765581B34A1A82072F5889E30C635FCEE
-:151419005676B13CA21F2B1FD78E854735AC55BE639CD3BC1730
-:15142E003FD0192E201F360E68CA5653AF81BC5CE97AFF8BDFE1
-:151443008FCAE638833F17AB0ACDB8D613DFFBFFD37DFC7B9AE7
-:1514580058EEDB1B80CFF0335F65F2D7CDCB92DFC4EF4EC4B7BF
-:15146D003313ECBB277E5F3EC1BF8D080E50FEBD0C1538830C25
-:15148200A7D7F57E03DF9F3F2BF84CCEE17347011FFE7DCD0460
-:15149700FB7ECAE1630B3E5D820FC719345551A725A13D119479
-:1514AC00BA2B0E8DE8FEF02AFD353C9FC4EE6E0BC42A425745A7
-:1514C1007C5D8ADD139A85672FD8BF5E8BEBD433DA5719F3B4AB
-:1514D600E33A292ABE8B033BBE097935297577A9A72C388AD66C
-:1514EB00C8CA5A88EB03B42E7CB0ED30665CA5DFC46F5D37FF53
-:151500003B9CEB22BFB41AD45F5ACEFBE836F58015560F5BFEA9
-:15151500F408FDBFF6BE3E3A8AEBCAF355AB5A6A498DA816ADA6
-:15152A0046C2209588708447715A422648964C43182F78306934
-:15153F00639CAD12C26EDB644C1C26A3DD61E7704E58BB255AC4
-:1515540020E10729D548462638B4B064E30938322B123C47248E
-:1515690062E275F02C61B48CC390C4269D19C626332456BC4A65
-:15157E0086CD38F4DEDFABAAEE9210FE9839B367FF58D5D1A9A8
-:15159300EA57EFE3BE7BEFBBEFDEF7EEBB657887B6D5087BF17D
-:1515A800081FA63A83A941B22B5F3491CE945E0EDF6E779BEBA1
-:1515BD00BF3ED0EC2E5FA1FD996EDA75A02C9E5157FCDBF00DF9
-:1515D200AF6E8D4C2B5F4CE523EA336693FA8A5DBE77C6F2D17B
-:1515E700E31818D5AD80254CEF6AD47623AC7673ACFB9A2CD1D0
-:1515FC00A6A93F37BD12FC228E7293F5B5C9B184594CF2CC8307
-:151611007DE9E8A0E98BF59AFED8A869EDDBB8F9F8A4CDC7F152
-:15162600297C9CE1DFB1214D71F16F51CCDB98E151EC1B61AFE5
-:15163B008478348FE466095BA45B7DABB6FA16196876F3735093
-:15165000ED364231F94E6BBFC1E0F0E51DF97BAC8FC45BA1DF9D
-:15166500AF6E60F987CA929AA22E16B459053AC0F5491D31629D
-:15167A00EA5123A26EE04A68756B1FE9A75864EF1B7F41737C57
-:15168F00777BEDF1DB6FF95B14BBFD285AA9BF3945A7743575DF
-:1516A4008C67CB1C31B9ED0FE7E415FB9AE349AD9878DC5D3E9C
-:1516B900AAF61A1BA87D8DE0D0D483F47FD56853AB8CED6A8D70
-:1516CE001157EB8D2EB5C930D45544BB477493FD595B754AEC79
-:1516E3009FB6F553FEA43A6A1C51B9D1F7EC515EC28EE97336A4
-:1516F8003DCB17BC759527367D92772E58CC776DAAE5BB9F6D89
-:15170D00E05D6FADE04F2F38CEB166F2B91FC0892426ECBAFDF3
-:15172200CF9EE2FED387F59EB7F6F262B677A91B2E3205F38BA3
-:15173700D455CD99B46807AF92587EB13B4D74A083F39BA4BF13
-:15174C0071217D43BA16EB3032FB606FDDF89E191DFCFD821912
-:15176100EA235E1B79279D5F953C6C88B1053FE0CB37DAD7F014
-:151776008388129F788B3A85AE7290F2BC1FCCFA9DF8A6FB9DCA
-:15178B0010AF1E14B65E3B7C7A4CE13F4D63DF4B32A32F49FA86
-:1517A0006CD3104F596B5EA6DF3A5F31A744D87D9326DEAB6A39
-:1517B500027BA94167BC63FD5E8B55124FE0EC483B8FBBDA56CD
-:1517CA0066F0C3F1C5A85D3127C44DEC57F6A9528B323AC0AF33
-:1517DF00D96D627F734A9BF4DE37ADCDE9FB071B5CED3357FB1F
-:1517F400EA0CEDCBAEF6E7CFD07ED5C76C1FFE3589863077601A
-:15180900010C3BE65830CCA7B6A6B7AF8CBE28DA526303A46BCC
-:15181E000CB732A5D384EF8F4CB67188DA9D1F1B309E5EF06B13
-:15183300E1D331E9F6F371EDCFAC7D2AEB3F22E52774A9ECA464
-:15184800BE7EACB3D1B78E0B5D46B92FA995EC18E1511F8B60C6
-:15185D007C96EC18E4317A866F01F21B296F0B337E6D62EF18A4
-:15187200699E6969D4D712C77F24188AB5865929DFD939B88DCC
-:15188700190F70F08FFA790234A4B5FACEEDA1F64EF292D096AF
-:15189C00D6B93B8EF208B5118C5B3A33F2083F10E3707FF1B807
-:1518B10021F67738C13277473D27B9DDD6B177ADF0F3098696FE
-:1518C600B576DCFB29FD3CE1E9B598E74ECFA5FF20CE4084AD8B
-:1518DB00730562BF0D739DBD9F2CF6434331A9B94059AFA36E52
-:1518F00094654A3397A5C37AA7381BF0B258170EC2C732BA3C2A
-:15190500B35621C717E9589F484C785A426F35F0D08A7B74362A
-:15191A003E6286562CB6FD5AC4BA96B557611C3597624F3D3A72
-:15192F0018BF4DDDB4043693D88735068633FFCA603C4875F9B3
-:15194400F32BF52BE974E08DE57AD3E34F7A9A1C5A5DA0BEB02D
-:15195900F0761BEEB69BC2EDB954A1CBA79337C21E5E6686ED09
-:15196E00F593E9F04346032FE883D59719FA30FE0D731DFA6039
-:151983003C175F29FA10113028D1B80EF80D35A70577C08F3B83
-:15199800F15EC92CCC25E37BF8E0EFD285428F540EC7C7976FC2
-:1519AD00AA1FA5BEADA2BE39EF77FCCE75D410FE24048BAFE8E2
-:1519C200A8E085B93B4EF00999C598B16838A00CEA993335F4F6
-:1519D7005B8D25E8FD31FE3EDEC37710FB414A3B6C06E386DFF9
-:1519EC006E7FA97D597EF71525048FB3FA041F233316FB9D6202
-:151A0100BF69D883FD6A137BBB57D3E950D6FF89C6CBBFB17C5F
-:151A1600625F767D5894CF961DB6FF8DCCFFB4F5E2B6988F27FD
-:151A2B0053DF3715E2733535305C1CDA4EF56CE1C154A5312B41
-:151A400095D3B22AB5D80884DA88DE63A2CE10CDC92CFAFBFC5E
-:151A55003519FBF21A87AF8EFCFA2384C752BE16FABD021FF809
-:151A6A00A8F0B5EA8DD7697F1EA96DBE47F5349FF75EE1A1C844
-:151A7F002797826E1BD2E9C249C9B193BA8D3CD02D2AEF32DA11
-:151A9400E013B89683D6C85743F9CEDAF9C2A91554EF6A739572
-:151AA900C573C38286F6BD26760FEF16FB8295246F5682A68619
-:151ABE0045C3A9F70E09EB8657787A391C7107881F3FAD4DE607
-:151AD30058F517F101FD41755663B13AABF6A5CA924673E18293
-:151AE800C657F18EE018BC9E2E5CA84A8D024E85F4B072A3D58F
-:151AFD00C7FAF9E51FA7F333E7F1C60F5B7B8DE387CD4365D585
-:151B12001AF58C63BFABD7AE9FCA37A32E8DEA72F23AF9B6524A
-:151B27009E7D6B06B45D34C6D0875B49E64D6F6BFB8FAD3D8A0C
-:151B3C00522AFFAA64C185737B5D180BE37163BE7F500FFE6E98
-:151B5100BF8101BE3AF5A2619DD34A3333F282D647F5CEF3D710
-:151B6600E8A42B97C0D7BC865DE189C837DB70F62E89B1BB66B3
-:151B7B00B16E12AD72D990EE25FEC7DE506364A89129CF59B491
-:151B9000B1F5378C6159F0994A70455A05FCCA73E69B3F4AE70C
-:151BA5001FF558FD5C49B46E9A81A6B751DBD3FB34F8A3B4D82E
-:151BBA0013443D5BEDF2F36252A3779C6440740FF7F8137A2424
-:151BCF00B59F375D4AE73B6573699CE02CDDA88D779CE714B2F2
-:151BE40080F0E0E4E9A777E2D9788AC77F98B6CE3F529E37DF4D
-:151BF9009F8A7BF0E04CB012FE4B4A53ED46FD050BE783D3CA28
-:151C0E008D02FFE07371566D0F77708D3371AB530326C73E7BDE
-:151C2300785ABF5957A6DF472F5AFD06ED515F1BD55763D34CAD
-:151C3800F0E6A0C59BF04B97D6FCBE1EA5F7B73AFC67D3C2C2FA
-:151C4D0063B60EEDA2056B1BF1C4C8BF583C31CF5FAF8706A432
-:151C6200468737B662BC5BE73B6DDE209D3F32A42D64279AC1E8
-:151C770017C18661C10F667CA1E6EB7E519769AE5C68F381E5DB
-:151C8C00F73A95EEA493FA42CA61E2F9765E447C116CAFD595EC
-:151CA100376C7C3BE3C15506F6D44CF8BE1DE39DF203E737B4A5
-:151CB60043E3E928D5E9F8D3E4BA78631BF186FAA6C51B12E1DB
-:151CCB0057B67963EDDF5AF8157B568493CBBFCDD20FF5CD8A7C
-:151CE0006ED1B59F7CA99E649C599D5A6356A5569824E74C9214
-:151CF50083C60CFB4DE21C33F4143FD901C2276E063F6FD2937B
-:151D0A00785E51B7DE06BF4CD2DFA09749F9033AF6B5BAEC73CC
-:151D1F000BF02D7B50F8330D0B5B4AF877E34C34D94F87CA4E3B
-:151D34006ACC1812BEDE4AB2D384BDBB2A794AE877F1E410782A
-:151D4900728EA2769AABD453A641F712E388FEAA6ABD67954398
-:151D5E00FCF24DF43FD8438150B4750FE66FA58A17939CAF263F
-:151D73003BE676F8E23B7633D96915DA55BD27B2BF0DF8F35FD4
-:151D8800C8DACDADEA7DE6DB3F93EE94957BF52A7505AF225DD7
-:151D9D00FE92EA6D0ED2FD5BF04514E36C0F2F3D9FCE7FAD5214
-:151DB2006E249BDC207BD698C78EDD15211B50B6694D76AC01A8
-:151DC70059D9E44A433E25146EA53ACD2ED5DFECF8589692BDD0
-:151DDC009BC72C3D0DBF8F52DDBB95A7DAA08F55CF618580CB48
-:151DF1006D67BA6DCCE80FAD71D029F257F36BC5AC9029EF99AF
-:151E0600412A0399E186C9E2BF7A7E3BCD0B800F7004D5970D68
-:151E1B00F4218F781FEBE76C7C31749E6068C5A774F41D7A90B7
-:151E3000F774834E6085AAA82E21038C1E1E559FE1AFCE26DABE
-:151E45002BC46754DE6907766090F41F4A33DD6DDE934E8B36D0
-:151E5A00855EA51C364748472B8FD9B22C6AC939D4D9361BEBFD
-:151E6F00F6614A3B2CE0F2B2BD7A0FE08AEE3121A71CBA396BC1
-:151E84001ED13740BBF704ED707E5C55498F573A877DEA1DA687
-:151E99007705E940D1BDA26EE8F5D0E9FDEAB366CD75A929AB9C
-:151EAE00CF583470F0EDA6C360C0F2BFBCD97B1E60856E7A0042
-:151EC3009EB1BFA139D2A117E495526526D6701D7AD4E49355C5
-:151ED800774DE7D7A87D9E2F9E7AC72C095D6CCD49922D7DFE54
-:151EED000A8D8D2FF00AED4FF425B16FF37D9D27DAC43E90ED91
-:151F0200971EA6BBB087B08608C28CC1C77DD80C8BB3DCDF30DF
-:151F1700E684CE50BB3F249952DAEA8B3D493AED72CC2B66C792
-:151F2C00BD0F918E7BBFD171EFBD7A774A024E857E9B87392E76
-:151F41001CB5F5DB2ECB2F8FC66CCCF6B31F16F76ADB0638627B
-:151F56008CDC073B2B4265B6087D3A2D7C44525C444EC819E394
-:151F6B00E1582D9F9DCC69093CBB9E074EB7E852F2040F40BFA2
-:151F8000879E7C1F7CD25F163EB87DEC9B1ACABD4FCA53DF677C
-:151F9500BF69EDA7517DFBD97734B6ED1847F4903EF66D0DBA40
-:151FAA0018E4771F7B4D832F2DE089920E87FC80E55689059E76
-:151FBF00227915185BA9DF4DFDF12B8FE8B2FA9C81BE3A7E50F6
-:151FD4002C7A9FD931EB5EE1039C4F3031638DD9C70632FE501A
-:151FE90028CFA2CF99AF125FFACE8DE86CA4D384FD04FA0FDB39
-:151FFE007BCC68ABE8524AEFCD7941E8F56BB1AE3C72CC1C63DA
-:15201300225F1CFA3CFCE2B0B78867D80758AF213917C7BC7364
-:15202800ADE27073B9EA69F49D233DBCFE18A7726DED852B5BE4
-:15203D00A05F930D5A124DBD635468DFD3674BCF0B9DD8E33F85
-:15205200A1236F09FC1BEA87903F7270672FCD457DC236050FD3
-:15206700887764234E923CF49D3BA8CF3BF79CCE2607054C382D
-:15207C00EF437C2564FC1FC6D6365978F986E13BFD72960F9219
-:15209100DE0C1F84C007842787F6BEC82ABDABCD63D111F4336D
-:1520A600BA4D879E4FB31735879E2CFA0D73103ABACD2B53F1A0
-:1520BB0067E1EDABAFFF9186337253717644E0ACA44DF848DBB0
-:1520D000381B06CE026CFC581CBEDAD79EBC7789A80FB6CCA84C
-:1520E5008533165D346CFD77F65B733B1B9E3B7A42E047AC7FA6
-:1520FA0019C7CC02E8C5935FE16F104B127F9414A53CCDC0ED45
-:15210F00E39E2796FE69CA736728E66976F30978C373E91DDDF8
-:1521240027BDA077AB599C04A78C0DCBF6035D2D7EB6C60AF085
-:1521390094E1F5E9769FBDEF6EAAEBEFF49DBBAAC367D9EAA701
-:15214E00C1710644E83FE1301778D9F669AB7FCA401C6BEB2D2E
-:15216300EA034BB0FFE1659D7A70C75745FFD8E6E778EFD81756
-:15217800493E7CD174D93BFDC2D6C19E36E18245474CA78E203C
-:15218D00D951852E5C8C117F2797AF6FBA7EDDC2C76FCA9FA8EE
-:1521A200DD40FA96859FBFD7EBA4273F003FDF27FC3CFFEF82DF
-:1521B7009F97809F7577E98E6D9E6661CE267F6EE1836CE6DE14
-:1521CC0038EC050B1F0BD8223DF8FE62818F9C68A95E1E2F6F3A
-:1521E100BE45CC71FB782CF5AEB9ED97B0974B5BE9D9807CB1CE
-:1521F600EC1FC21BFBE32C0F2A583310FF84BB0117EE5E369D99
-:15220B00F6A6E3AE9770B78D70F77736EE2E12EED07EC8D5FE2D
-:15222000B55F586D4F6DF7056D5FFE505666DC5C56CC71C98A24
-:15223500A64C3EEBEC74667C2CC4BAEEBAE7333244D8E7E3545F
-:15224A002E3EA44D2EF70AD8204B204722A4E3418E604D0A67B3
-:15225F002050EEE9944B9EE4BCA461FF0FE736F05EBCB3E449EC
-:15227400896FDD4BFA016A5BC8946D4362CC627D0A7D2E76F53C
-:1522890059A63EBB65CD74FFA551F8E6285C2FBA64E801D20F34
-:15229E00FA9232F547354EDE27F4CA906B8F8C063EE99034B72D
-:1522B3000357276DFE4079DF42962F8FEFD495F33BB5A9FEFC1E
-:1522C80086B0357697F56B42B7945917703526D65C86E20BB10B
-:1522DD00A743632327752C2EA74EC47D7ED27308BF05F1A1C669
-:1522F200E2A841F301E73D29B94556137CAEF217382B182AC2CA
-:1523070019BA0C4C5161776CC799BBF2D5ADD0B1587958D821CF
-:15231C00D095271EB07C67AFE15EBE8CE6DDDF3F207CF7C2EA17
-:15233100F1D40333FB731B87B07ED12FD62F76931E5C34D629A3
-:15234600D609D8B89C301A8E58B04787E245F06FB4D33DB1A12D
-:15235B00B8D2302CFAD7C3F66A384FE85B47F3883104BD08739A
-:152370008C41735BA67FC591C146A7ACB58F9B79BE019E6B8741
-:15238500B2EB31BBCB86B5A2B80D8F711378285D215B1AB0B83F
-:15239A00DB94ACFD988ECC5A8DBD3F8FBD68567ED2DAF7B4FD65
-:1523AF00110977167EACB5F4A978543A0F4CF12FA27110BF1F74
-:1523C4007D305A31164897E928B77CA2E21D94DE1B4D6ABE22CE
-:1523D9004B2F4B114C5772E258F32AC4FBE87ACB96C1DAC1428D
-:1523EE00DB8F6AB5E09123F1FBE89D03BB809BF26BEBC51EA3A5
-:15240300D8075C6BE7D35DF956A45EE8A0FF38D28DF558CFF983
-:15241800761CF31EFA82FD4FC0D1BB73480B8ED9F050BAD3EE10
-:15242D0016BBBE9E19DAED77B5BBD5CEF78C2BDF4A6A17F99220
-:15244200AE7C6D76BE8119E05B99FA661C67108E0818BF1BC70A
-:152457001ED815824521F89E16BC734CF8CDF47E8F6065D6BA3B
-:15246C00E01517ACDBECBA5F9C01D661170CDBED7C2FCF00EB9F
-:152481004957BE1D76BE573E0056D0D881F5EA87C07AD5056B9E
-:15249600CAAEBBFDFE1B61EDBA3F0BC3653B5FF7FD37A1E7FD24
-:1524AB00597A5EBE093D2FBBDABDE2D0738676FB5DED5E75E845
-:1524C000799376B76CC0F81A050E8C0977BBE8AFBD7E8F74875A
-:1524D500E71FA7FCFBD95086E737782D9E7F5FB2783EB621DB46
-:1524EA0076D46BB5FDF0860F681BFBA576BB4E7B93AE7E6EB0F7
-:1524FF00EBF8E2CC751818B38E6FCEB5E9328FE4CBE5C1ACBCF8
-:1525140013E359ACCD22E69421FC099832624057F1F93BF5DD6E
-:152529006586A6D0FCA0AC3DA597F213FA3E9A12DC32E809EAA9
-:15253E00D74CB2C729179286B4FDA437825F2CFFC7BD644B24A5
-:152553003BE0EFBD52D4959D1BEAA82E0FCD0B19B94A7A896F04
-:15256800DD9090A9429E3AF3451CF27448C853650DC14F725439
-:15257D00723D4F9D8FB0DFDBAF4965869EC61A18F6DAADB37498
-:15259200F6DC346CB56FD8F234DA678A35D5F121C3EACBA0069B
-:1525A7007F17EC0B189897C85E99ABBCA2FB48E7C6DC34E37C24
-:1525BC0032945D0FC73A1CF6944270D7856FBEFD9BE6F339D379
-:1525D100D7C2AD75DCA3864CF348A0419C756301E917FA933497
-:1525E600B72D10BAC911331264D1D7688EF6150D0A9F0E2B1601
-:1525FB0058B5D807DA5DA66AAC7E2F6F13FB0B3D64EF579AE254
-:152610004CDCFFEDFFC3BD1C30B36DEFF238D159C0EE7ABF99F3
-:15262500F4B6E5F4FECBEC1F9722C609FAB0ABEC88735E5915B9
-:15263A007D237D48F44321BBE2E3FE0FF4F29215EFEAD9B4A1AD
-:15264F00E175B1F412A7AD0ACDB2D53F4A5BF1E48D7535C6BE43
-:152664002BEA8A7E40F918952B5D33B5DCEDB18796587433CC8C
-:15267900D5A09B5D2E4C79FDD3F2D6C52AECBC2A17FB43365DAB
-:15268E006591AFC75C3061C77B237CE26C5D5D2CAF51ECBDC060
-:1526A3007F53E44F7092F13109F989A7113746B6E2C319880F2E
-:1526B80027CE3F132F89B399E383A67B3FA9F5886B3F087BA603
-:1526CD00DB388F603F272A6C1B71BE5251E0FF613FAB3807990B
-:1526E200DD0FEA75955F18931B9D3D21D421AFE17A8F589B1E44
-:1526F7001C9E74EDA33AECEF63A3F96FC977E57CD9F39EF47519
-:15270C00E951E9335250BAC6FE8EFD35FB2E7B990DB1AF319314
-:1527210075B30EB683FD2929DA5F628FB147D9436C23D3D8036A
-:152736006C3DFB1CBB97FD015BCDEE66ABD84AB6822D67CDACF0
-:15274B008935B206B68C2D6577B07AB684D5B15A16669F66B73C
-:15276000B34FB11ABA7E8FDDC616D355CD3E49D7AD6C115D55E8
-:15277500747D82AE857455D2A5D25521AE72BA16886BBEB86E5A
-:15278A0011D73CFB2A1357A97DCDCD5C21FB2AC95C41D735C7EC
-:15279F0075154FB902D32EE5866BF60D57D18CD7AC9B5EFE0F7A
-:1527B400BC0A3FF42AF8C857FE875E3E26CE181FB7D6B754E111
-:1527C9008B4EBA3DE9F151A61E475A15A519F673353D8FDBCFB4
-:1527DE0035F4AC48F48C35BEF26ACA1FE1065BCDC7C95E5024A0
-:1527F3008D2BEAC2E34A8CFE93F49F5A785C8C2BB11E522DF667
-:15280800DB55D54ECBB7D3244A8BD96905769A87D292765AA167
-:15281D009D964369A88FDA14B02B2C1AB6EB825F60D8AE037E98
-:152832008061BB2CFCFEC254262AC16651F9F04B5828BD8D33C0
-:1528470075E1016F6899A8272AE2EED41AC549A9CE776631CD9E
-:15285C006B95077C671A843C887FC0BBE10F78073F38BC2BA2B2
-:1528710077946E225D7EBD41176D8F2F361DDC3938473FC66D43
-:15288600189561411343153E7661037E200CFD1465C2ADC02FED
-:15289B0070A878ACFCA96FDBEF99CA9BD485A661D7C35EB1D235
-:1528B000A3942F8A754A65A129FBC8A6BFC93D2A65F38CBB9EA0
-:1528C500154FF6D9B0D345FD63E9D988ED64F947AA7C42ACE7CD
-:1528DA00A8563C48B12EAA8A5891B9F6B3F043F310AF617D2323
-:1528EF00BC8C477FE16109CF32332FA4B6CA91067DA2B241C487
-:15290400A998F8AEF70EE004BFE12B3046E5FC6C19CEE49A35C6
-:15291900840B529EB84FAD33F3D86D04FB6DA63714691D9F2168
-:15292E004D91AC34A6BE67C2BEAACE99AE9FA98648037FD3FD64
-:152943004155AA9389664ABCBD4E86FF8C5209F9ED634A2D354B
-:15295800B9CCA81171196A4DA6002E55C012F594521B8B0DB4AE
-:15296D002F9F29D595F8E27ADC7DF1C575B847D1D7F1B090F94B
-:15298200C82BF818F29DF489B81813CB7844F8D946901E4BCFE8
-:152997005E4D79A2464CAC776BF659FC188F88B5932DD699FCEB
-:1529AC00709B75469E6DB7E3F076D9677810F764360195205DD9
-:1529C1002461182CA141FFC1EFF796CB77B0F10EC3AFCA752C4C
-:1529D600BAD39844BFC655C35A07B2CE2DD7A472EA449D549F2D
-:1529EB00386783E768AFD15516D72431FFF59A9973E3D1FFDE24
-:152A00008FFECD579F3664F575D21913464495EF78E9A197A820
-:152A1500FED7FA918EB41A4A3B302DAD94D2764D4BDBB69CE0E0
-:152A2A0052DEEEFFF243EFD49262C6FDEA25633B3BC3E7AF7812
-:152A3F00476FA9F869EDD7965DB17DA5E362BD6D41FC027C739B
-:152A5400845EB160C5395D4E0E1A9EF223ADAAFAAD7E664C9A2E
-:152A6900BEAE5EA193637EF68DF52D0D618EA47698F10DF3161F
-:152A7E00E91D1D7828603FAD1D7EE8974B0906A2E92582EB9C07
-:152A930021F17DFAD736BDCD6F89D05CACEC330967F1EBCB57B1
-:152AA800D5FABAA9BDE8CE617624176BE5C33E1F7483DD077C9B
-:152ABD00ABDFA1F4FD07ACDF2FD8BFBF7DE00CCDB7C9EBD3C29B
-:152AD20060477FD89FF09C3180B7ED6C8CC7BF935BF7C413B97E
-:152AE70075581F3830FE356DDEF9FD5ACEB937F4BBD985DA799A
-:152AFC0063A774C41685FE62AD2F8E8BBE96287FAE4F3E7CC918
-:152B11009C27BD46EF2F98BEF8B1A5D88342DD130F9F337CC974
-:152B2600DCBA912773EF10671887451C98E3090FD90CCA090325
-:152B3B007DF9EDA1CEFAD069AA5BF9078EFE28803BFABD611FD5
-:152B5000620529BB8F2B02FEEF1F7F9BC66081BAB70B6BB57987
-:152B65006A67BC27CE3589F49389CA1F1AD05192A4777CD58762
-:152B7A00F83ABC6BA2F2D726E5DDF34BB5E68E28E5DF115B5586
-:152B8F0007BB4A8C2DE59821279F2519E9AD8B8D1DAD63C60920
-:152BA4006302BC47EF317ED653BA9C3C46FCD3297C13ABEDD81E
-:152BB9006D62AC197BC53E47B5186706F725F7D2388B73996858
-:152BCE00AB305E8FBB8FF13ADC113FCA97ECA33AC68C36EC2BC0
-:152BE300261386E4231C85C74CFC061F627C9CF92EDE0D923EE6
-:152BF800493A7F3261DE16E7227D8CD2F11BFBC81395DCF0C751
-:152C0D00E4BA00E96B1827139583E63CB22746AF7BEF205C9AE6
-:152C220067DE4FFB1482A789DAB8807115EEE71324839BA85E80
-:152C3700963C68BE91F1E7EE32FC8481300177A193D733E374C9
-:152C4C00BFF0632179D61D39A7FDE51772EBFA59A7D61FEFD3ED
-:152C61007E5925DFD14FF6DADC44AFDEB3936B3D0D17C55EB4FD
-:152C7600927ABAFFB645E59F11BA5B383E8C9824810509C4C806
-:152C8B0032E627459FAC182F3EE8A37111C3A55AC6DEFBDB8611
-:152CA000B41AF18A5F357BC6B806FF415FF22095DB0D3C8B58F6
-:152CB50057A5A9A7CDF9A9AF9BD5849BF9D4D7642EF634778BAF
-:152CCA00F159ADEE16BEF1A20E85236E9FAF54FDAA217CF63673
-:152CDF00714EE50CC806393662D4A7BE437977D358E9A579EE05
-:152CF400A08E3A3D6787442CE5B6BF60AC0CF62FD980885722D7
-:152D0900AFDBA5539F0E78D6EDD3B7E4B1A9E3631CB16EBAF850
-:152D1E0057DE92BFFFB424E82262000553F033EA177E46C029AE
-:152D3300E2FE045942AC5F8A78669FB77CBF906E8EF56AA5A9CF
-:152D48005DFDE1D4F3496505D77DA403E7ACE5BAAC72D3EF4371
-:152D5D008CB783BC3AD2B714EBBE25EDC43FEA102F8DE3F709B1
-:152D72003364FF464C0D4BEE937D9AF2D7210DEBC2BE8CFF7CCB
-:152D8700BF8881E3016EC67B8D2A4107EB8CA2447637CEE55AC6
-:152D9C006713AD3DBD37A92E896000ED413FA9EB981E5AD069C0
-:152DB100EE8F58E7DA104346FA032EF47445D0D1107E6A8AE003
-:152DC600EBE78E5F1636449788B723A748868D4F0A3C07C84604
-:152DDB00F60B1F837E116FC72362565BBE6BCC78CA443C46C088
-:152DF00029A5BEC2AB539FA875CB76C874D04FC8F58C4C27F975
-:152E0500BE25B72598FA8D29E22C1E07FFED32F7FC2E5D520F81
-:152E1A003F3B9B06C07130B5CFF0F05E3DD068C5BCF3906C4040
-:152E2F00DC763FEB5DE2271E99C77A6B41BFAD2EDEDC6AD1C9B0
-:152E4400D88E7BF99556C15B4437FC96C5B982B888E3047A8367
-:152E5900BE22361FC632D1733A2D6551D6A2C387E1F623D3083F
-:152E6E003470E3DEA1C7C7A04181A041BF1DE7284B8B0FA58182
-:152E83006B6E75F03FF62DC4A72C0ABB69511CFB64ADB04BA3BE
-:152E9800EDC3D79EFCE452259647F368BB01DB13B28A7F25B730
-:152EAD00EEE2BF38F2C79217A544ABE205DC94A84FA01DFA68E6
-:152EC200C53AB2DA407BA83B130F23A31F59F42873D1628780A9
-:152ED700A7CB3AB740EF11574B49ED33253521F808BF35D77979
-:152EEC00E0A0AB7CF0F399F8E022AE783F1B12FB163ED0BC7DCA
-:152F010048F3AB5E218B15F007C99EB288257B32E38EFA2C6D48
-:152F1600C1FC4BF735E7040E689C06FB7F6BF53735EDB313D89E
-:152F2B00A3290D75B596D1DCAFB2E4F1301B3B1E61A9E3D72E7F
-:152F4000A4F3E93E4CBF87297D58B3CBDF2CFF9137A7E6AFB6EC
-:152F5500F3631E1FFD8DDBFF14F32C8BBACB8AB8C362CF8D1B4F
-:152F6A00D79F94EF6882BF8B3A1AFFEA99535A2E9917B2DADB5D
-:152F7F0085B84805EAAB5D38FF68F9838F8933508A3A42764A45
-:152F9400C2F0A716D5C97F93CE071ECE5E4AE74FAFD30D9B3808
-:152FA9003B48659BD4678CC99F71D2890C1173C9E2C33F330520
-:152FBE00EF5AB19D267A483FAC233DE8E3F0E6C4CF7A8D84A7CE
-:152FD300CB6047E496899F7133E1E9379BD41EF337D7313EE251
-:152FE800B62DD26E5E86EE13361CBDD48AEB6E1C34A0034B3494
-:152FFD006E003BFD3677FC17D2FBC25113FAAE83B39387B2F8C4
-:153012006EFD7516BFF3110B22544A7A79BB7196E0DECE629CE6
-:15302700A5C2FDD88FF2A7AA8DDCD3B5FAB7E28B6B3B972D9B72
-:15303C00A22BE631F8892E13FA539EF428C98F35869A8AF63372
-:15305100E557A6CF57A9C3D7D4D213172E2D205BC453AE8936F5
-:15306600105F167AB6B7BD562F8AD4D617509B472BEE5C3A3F3C
-:15307B00A5D25C576D94A6C286E46FD43B9FADE5DE31B2FBC612
-:153090009799CE1E37621B0A5D5D6927FDB1AA56C65E6AF49146
-:1530A50061663C7CC0D785F301FF49DC53CB3D7764D7834AED9C
-:1530BA00B882D5B69C0A939C5AA6414F9FA74A61118F54C869C1
-:1530CF00B241A83FB22B2695357F3E3F5C3676502FB3D7338382
-:1530E400340F63BE65E3AF9801E9B25E5759F419567EA695B16D
-:1530F9002B5C61FFB03428BDABEF53BD75D005C32413E74B43AF
-:15310E007A49E864AB2FF20F4BE6D3DD73AE4FF8AD601D6FEEF2
-:153123000AC4C23B69FBC7C4F9159AD78BE327F4C07CD24B94E8
-:153138008EE18FFA3F97746FDCFB97E7D517C7F2C82679C5604B
-:15314D00A9E78FBF41E3687EEA6903B24AC411A0FE07683EBE55
-:153162005AD6BB2442BA0CE69B07BC86D05F7EFC0CAF75749694
-:15317700ABBF4BDF546719FEDFE99BEA2CCB6EA6B344DFE129A5
-:15318C00E7FC27640CE1CA57F985A505620F0F783BB53478FAFC
-:1531A1001754FF29BE9E70B77F99E19CA917780AC54732780A6C
-:1531B600A516D5FAAE604FB963587EFD14E473685E6A562DFD13
-:1531CB00368A5325E25E905A20EE06C9F199FA4FF369BD67F568
-:1531E000BBFAE56B691FF080BED6D87D9F78DFEAFBFC19FA8E7C
-:1531F50032C3D73E7EFF1710DD4B2147A33DFD6DBF9966BF5070
-:15320A001FC55AAA8B9E6BDD79A27DC63DAC9F6F201D3DF78709
-:15321F00BD4B54F5345920295E2C91DEA55C3083365FCA381F10
-:15323400A4FCC4DCCE2EF280745587DCBB65C5BB7A78EC3BF5FD
-:15324900B73458F8BC85BD63F975517BB7C05E095F143805CF3D
-:15325E00C1BF133EA2E5296F9D9367EEE94B19BCCFA5B28ADA53
-:15327300DE1F2F4CB420EF56ECE54447FA117B31E7CC29BC3BCF
-:15328800E0397B4A37D26427D1FB6AF50B4B71073C93CBF3EE4B
-:15329D00D8F6D04F491FFC89E1535F3E50A3FEC85C3669F73195
-:1532B200BA6BD88FF8AAC9F5DC7A86ADB46BF8CA72ABFC49C28D
-:1532C7005BD0AEEBDAF2C796DECE5EA813B68E2B2FCAA20E77B1
-:1532DC00B9B394A7E3A90B5A58FD8F4B908EF99154E5CFE1F98C
-:1532F10019CC91D15D49E89F285B803D65C225BE1F33BFE7B062
-:15330600C0EB3C957402BBFEA229CF736B3DD6737F813ABB967E
-:15331B00EE86A7C8D2CB51BFE7EB7B74A1037C876405E9576696
-:15333000E4794D8924F4529A3B443C16C53A83F361FF34A7745C
-:15334500495DEB75F8193265A7987794129A3FEC7947CC41785F
-:15335A00F731E61F67EEB1E7A119E71FCC3D9883EAC599FBCC51
-:15336F005CC3D5316BAEB1DA5159A9FA2B730E74099A977C6AF3
-:15338400B7B9E5BDB4AF20C9BB0A08EEFA48A2CEB1FF4A691EE8
-:15339900439ED5EF39F4EE349AEA2CBB716254BC37F03E4CF834
-:1533AE00417996BC6C486557881F39D98D5D3C37998817533BB2
-:1533C3004A72A41F632E27758AA34EF01A78AE5AFDD901F0D4A9
-:1533D800C5F71DFDCC8699607DA3E7591AC3EDC6D65F58F3BB94
-:1533ED005897A5B6467F951D5F8190E5EFE1B3CF1924432C9F18
-:1534020074CFFC2B01EB77DCCBF23748AC707B0ECBC77986F8A2
-:15341700D8D46F3B4DFC2D4D4C1711129DBA46FF6DF46FD0FFC6
-:15342C0030FD8FD3FF04FD2B3FA2F73FB2F28ABD83A0EAC46896
-:15344100E467C7F0E1884A1DB1F06F555B97B0FA5F755EA47C51
-:1534560015FDCF100EAE926CBE6AB2FA761EFB4B7B9DAD7E8045
-:15346B0027E9B947F5B62834AEC7DE465F470DC4BC14E73EEA46
-:15348000BB39DAA977F43BCA1FA7FCB7B2BDCDE299DA539A5FFA
-:15349500340CF4433961C0BF36B4E298CE627B39DEA3EC7EF867
-:1534AA0063217634D5592CEA7C45B429621B7D601DC77851E412
-:1534BF005433F2A3CDB9A11BFDA9597082F7B2ECFEADF0DF0892
-:1534D40066CFECBF799A1AA43993D59FE216AEE1DB316CF5B34B
-:1534E9007E888B36C73B0DAC81948C1DD3156AB7247E54878F79
-:1534FE009EAC4E4DC31A888FD202E35D7ACF84A7C5FDCE47EF92
-:1535130042CA7FD3FD64878E601FD4D97725F8FCCC155F697AF0
-:153528000CA57FE37B9C131A0922364775EB55BA7B953A1D3188
-:15353D0072FDB14A3397CA5C0BB142F9BFB61B56BC617917D2C3
-:153552000629CD1F1BA03967917E71B9749757E9D0C7290DF1AC
-:153567004BBB903F5669E07C8D8A73A29426C706CC61A4D3B355
-:15357C00417C7B9164217CFC6BE63271C68307B23609CE1C5FF6
-:15359100F558F1B2B6219DE007C079471077F45DAE9C7F464330
-:1535A6003F4AE11BA48C709FFF98BE8E6CB339AADC92973A2800
-:1535BB00E2B610FCC5A114F2EFED90BA7B853F27CE18DE966C99
-:1535D0005AA2F82D5F0BC466982DEA1C3AE0A33C3E2B4FB034D1
-:1535E500292F918EDC589645F304DE0C9AF7AAE658DF8082FF11
-:1535FA00BDC3E7E373E0979EC8F887C9EAA4D95A427822B92460
-:15360F00137EA2F4CC66F0E72F25BC5BDF3CF96B737BEA6F0F36
-:15362400C897DAF5CBC553EBC7F744DAECFABDA1B156CA6B50E9
-:15363900DE7ED4B58764E75A196B3AED343E2254FF6AEE53F13D
-:15364E001C6D853FB7447A2EE9C2A65FD5CDB504838C33722494
-:15366300A7F17D95F96A3B87DCDC537646C37AECAAD43F13CFF4
-:15367800FEC05C4DF724F1C25ABAAF4E7DA61FB410FEE76AEDB5
-:15368D00011FD5514FF59706587E581DE0169C5FE8079C388F73
-:1536A200BD92F475D8309EF258EB9EB2360DF23E42EDC4A82EF4
-:1536B700CA773C4AF7CDF41FA1FA733167184D7C436AB919A3B7
-:1536CC0076A2A9FDFD38F3B09ADA89AA3D070E521E8DDA3AAA9F
-:1536E100D8676C4987403B84C0923D6549AD551D306304D7662A
-:1536F600AA7F82F07335C00A7D54E632DD714E9EF8CFBC46CFF7
-:15370B00ABA88E8900CE1924F8167A7E35007E575BDFA4FB6AE1
-:153720004A93296D989EFD418B46D371ECA697F7525CDF4C7926
-:153735008B55B939C745CFB03A48B8867F31F68427699C0F9A63
-:15374A008A4A73DA349A875F9B2AAFE12FA284734806776564EA
-:15375F00301C123057DF4DD38107E71CB78D7051CE386594ECF6
-:1537740018B4E4DCB663960C8AEE35E0D33217320A6B58888D3C
-:1537890019957765DADD3669CBEF1E9249581B3C684A65713D24
-:15379E00E37F4678A0692F9FE62E23389BE5E3AC06D9408DFDF8
-:1537B30012CB273E32A89F8D7E1AC705EA82CFACCA63F9F3E96C
-:1537C80019DF929195DDFA28F169BFC20ABFCCAA1A494008FC7C
-:1537DD003E42CF09C5C26B39AB6A8EDA721FB240C04675602E4B
-:1537F20088501E12E685CBE8AE282FEA997874341F5FA8686FF7
-:1538070084CFA788BD46F7ABCBBDCD0AE5DB5A7CE31872C60954
-:15381C00F6CC300E2798F50D3C278F9FF860A7FD9DBA72D5DBD0
-:153831005C4DF5E4975F213A1D9A820B85FA73167CA3DC26CE74
-:15384600D0EC8AE13B033DC613915ED1FFFC4FD3FC46F800FFDC
-:15385B002D25B4416F7FB508E30EFD7AD1C01CD1C83A455EA932
-:153870002CAC77E663AD63C0AC72FAA5741B32E916D5E0BD40AC
-:1538850017740503FE7E0AD581323EF5457AFF2B33BFC82AC7C6
-:15389A0094174DE0783BE5CF75CD5B6AD1D4F59B6B45AC3048CA
-:1538AF0079268AC0F35546428C936A314EE0DF0499FBE6F5749D
-:1538C4003EFC750AE289466FB45A57D54AE3CA72A97994CAD023
-:1538D900382EF4BAEA2FB6CFD665ED55D598781B01B576EAA8ED
-:1538EE005B39FF7B22D6307CB5B09624931C95A9BE2292F7E8B6
-:15390300C7C44303F50FD2337CAD64711EC8D603E0E3F536F634
-:15391800F82CF8E5D810C9A4170D712EDDD255D3C53407E3FBCC
-:15392D0055B2FA8C69CB9300BE0D09F926C33FC2FEFEC424D5C1
-:15394200F3E318F1606CC85E334EA7FF6A6CB0D14FBF713687E5
-:1539570045DBF9F642969F5B4934B4EBFE2DF5DDE90BD67050D7
-:15396C008785AB230257F0FB0DB1458D4E7F0AA80F93158B9A3D
-:1539810071CE7372162BACB8981D3F326414D96517C986FC2802
-:15399600FDC4FE9B809FF409C0E21D233B3B3A4A750D4057248D
-:1539AB003C7467FC45BC946FB480E5DFA30276AB6F778D250892
-:1539C000B735A60337F611FFC7B19F1CC5FA83A82F84B58C55BA
-:1539D50007A03FE3BD903D36BEEAA7ED4F59E36515B7F15B828E
-:1539EA00FD0F3FE5298EC9CD9B73B26347C9AFC1B7BB047ED1E3
-:1539FF00D6BCB141D2A306B1A79816E71AE9AF3CF242E3453F3E
-:153A140070F373DD194F23F6F95EE80781F1A7F4C0F9255AB02E
-:153A2900BD419F97929A049F19DD7C07CDEFBE50360E0960AEE7
-:153A3E00639F6A862E3096EFD0CDEAFB6FD177AA0BF97136C947
-:153A53001FB3E28A20CDDBB448C46C9745DC120BA6BF2298E058
-:153A6800DF081AECC7593A9A0333F44D791BA103CAA9534601AC
-:153A7D007BA57132ED6D9E97F23607A7F58164880F78925343FB
-:153A920037A72BE1183038FCE84F9D30FA52DE9650D3908009B9
-:153AA7007066F4D570B5A08B22F42AC0FD29EC41091CCD8B0F3C
-:153ABC00D43B78D94C32D76BD3CD473A5451A5D468F5CDC2C5E5
-:153AD10075C1E30306C64D89DDCE3F52F98FD3DF85D4DFAA4288
-:153AE600F437ABCF839FB723662FF1815F75F529F6B2D117930E
-:153AFB00B27D52AD3E59F850459F9CF3D2363D44BF0CD798284B
-:153B100076E10E7A01F0E6F4674EE84A2BC9419A7F7F6EE6B539
-:153B2500D3F852F6F0373C969E087C6C60D9710F19B839730EAD
-:153B3A00D7D28BC4B96ABBDC412A071E49A28C4B9E857F379504
-:153B4F00FFFDEA51923983FC4F2343B5CA8E11D12F5FB2D374B5
-:153B6400FA0C79017E2F16B1E59F35DDB20973899C7CD6EC230E
-:153B79005D5321FB3E4032DF9F841CE3A6D5CFE12C9D934346AA
-:153B8E00A8E984C04788FA60AF6F171440BE8AF1C5752BEEFC13
-:153BA30015D1DEC2152FB8C697859FA2D38322FE2F70F7C8C3D1
-:153BB80096BF2BEAFF0EDB4B7C3068049A3A6DFE1FCCF0FF61C9
-:153BCD00E27FC0073B05EB7C820F62E003C3E683D10CDFCFCFB8
-:153BE2009FCAF747057F0E66E9AF8E18A82BCBD3832EFA774D11
-:153BF700A33FE0D96BF537293763ECB8C70C7ECB49C4324A1863
-:153C0C004F936CB360B6FAB98BF8DAE1E110C1574C7CEBC07AA5
-:153C21008D602D2758DB7C37F2ECABBF01BFBAE08D11BC311723
-:153C3600BCAA1B5E4B36BAF502A5A953C0EBC8216B6EE8123030
-:153C4B00CB31CB87CF8824DA8A5C7362EADA541EC4B91256DF0C
-:153C60006BE0FB53B01DB5FF952ECCF01FD92E6F2256C061F98F
-:153C75004E2566D92FC591A33AA972C52595724BE07CBFE6913D
-:153C8A0058600EDE8D8F18CAF9A426930D739CE055C8E6958910
-:153C9F00C7B0AEE5F321561CE721A2A74AB64FFCA9DE960EA415
-:153CB40077FD33E6910EDFD953629FF44AC5DE3BD8F8A8618648
-:153CC900A516D4539ED88B98C1C1B988EF41E9896EEC77ED3513
-:153CDE0065AA0F7B61E237B52B8BB5FABDA62887B68CBD387FDC
-:153CF3003CA73C2937B65B653AE26413E16C936F2DD785BF237A
-:153D08007C526C9B08B0A2FE9DABB996B36E528FD370E9FD2C8B
-:153D1D00D7D06799CA94278E6D02FC98CF010B60036F2E2318BE
-:153D32004ACE9FD4E662CE7FFD59BD98719A2F92DAB7302FD91C
-:153D470075E2FB086DD4579473FABE8BEAEFDA7742F851827F75
-:153D5C0044DEE84887AFFB9FF51460A33EA12F6CF220CE5EA6C6
-:153D71008107D29D39F0B9142C4BEF1D5C5CCCE0C16A2B830789
-:153D8600ACDF8D5B78087D576EEC5A873DC921DE4EE9BD185FB6
-:153D9B008413A4C13644AC330BDE538483631AEACF59F76B7D0D
-:153DB00087C0C3312D40FD030E149C3BC6DA3BF4326A0B310BAB
-:153DC500C3D47E39C941271EA1751E24CED93B8CED29EBD2DED5
-:153DDA0023DD754198FD61952ADFE5C45B1FFEBC88472874DE64
-:153DEF00D5C2AE5A7420286268EE16DF804059E2EB7CFA3D8C92
-:153E04007DC0F17F72C5B3251B113184845E087F7AF8A685976F
-:153E190071863C4ADD01D249C6E2D5DE16C957A3CB91C5FA20AF
-:153E2E00C18AF80B48AFD0FA750573907A6FA34FFDA346457D70
-:153E4300A0598EAA3ADEA54847C77DB3388FF4E722966149836F
-:153E58006A5AF51E860E34B68CDE5568861E8E0F36D6501DD54A
-:153E6D00544795FA40A35347A9783FB58DCBCB1F10F5FA45BD41
-:153E8200BFEA70F25ABF0F1B89E57D778A33DA0D13565B510BB7
-:153E97007EE0EAACF0EFAF36A3948E39F62A6385D2EAC5BA120B
-:153EAC00818E68F793F20D8A7C61BE01E58DC526F28ECD90178A
-:153EC1006D6F07ED92569E8337C9B30163D3CEB3FD2679C294B6
-:153ED600C76FE7D9302D4FAE522FBE37847CE095ADCB7F762708
-:153EEB006425FA21533F719F43F2DCA79AE64CEB596166FBCB27
-:153F0000638C2A8363D86F147A0B3DE34CAD88371B8D0BDE2D37
-:153F1500B1CECE67D68424C9E2B74CBD549FEAAC1F093F34B224
-:153F2A004F7F90C3B07E029FEF94A06FB6BC150BEB8881746A9C
-:153F3F00D3AA9FDE958C3FA707CF3FA7C1462DA1B1126C1A1181
-:153F54006397F836A0B013F598673FF7560E53E3234B133497BD
-:153F6900FBC9362A461F146E5A3E6FC233A400318BFDF1634B40
-:153F7E00A04B237F10F53B700839DE65C11749D48BEFFDD9F533
-:153F9300CE8F0F2EAD99566FC60EA6B941949F617DE61FEDF10C
-:153FA800877EC15626788B2F63DC2855D9F2EE785B347E71160F
-:153FBD00EB9F662877745A391A9F379C27B4CA1FE23F9FA1FCAC
-:153FD200D68F50FEDD19CAD57F28BC87F89519CABDCF3EBCBDF5
-:153FE700D434FD0AFC1274F31FD6D5FFC9F54DBA19DEC7AF7EC8
-:153FFC00F0FB890F7BFFEF5DFFB4F77EF778F8A0F5D6FFFFFE71
-:154011005FF55E71E1BF789A7CFA7F077E9B3FA69D399A78FFE4
-:15402600C6F1F061F5B9F94D2A3BA2F779129B3F2ABF61BCCE52
-:15403B009155FE79711EAABAB553896D5E49C3DA1FF8828EF8BF
-:1540500077F80EB8FFEE6E1D631E3A823FB0459FB5AA5B57D5B8
-:154065002FF15977B7EBC1755CF34B957AB0A8524F90CE66CB4D
-:15407A00874DD7482F5102D53AEAFBD7D675680DD786E173B5CB
-:15408F00AE4A877F33BC776435A7E57192F925FE4ABD605D8D23
-:1540A400FEF5358BB58A758BB5907FB3DE99F37B1AF6A316C828
-:1540B90031C4C70922AF2C7D4217EB40ABDA850C822CAA284A4F
-:1540CE0068F08372DE178BF78B756F202EF4DA8A07E3BAF0CFA1
-:1540E3002438CFCED0FE4ABBFD426AFF10B55FE26A1BED9653F3
-:1540F800FBC827EAA5FADD6D5FB3EB9D70D59B4EFF34ED474C7B
-:15410D00C55AD6B29E4C18D41DCF8971E022CDACBA6EA7297B4C
-:154122002EE1C54F6DE6AF5D4CF8A9D416F86BF4F99F965BBC93
-:15413700AC7D63C51FCB2D87662704FEB12E457378106BA2B712
-:15414C0009DD240BBB881D01FD90C59F147D2398CEDA308DA2A4
-:15416100EFFE0D7AC5BEF5BA54E4C096BEEEC0D648B095FA2B21
-:15417600457A9C14638756F94535BA5FC0D4AD2D284AE83D3BB9
-:15418B00F764F80078FE6D3A6DC3C0443F71F6CEDA779D78128F
-:1541A000ED8EDB7048655DF8269C6F36B76008ECABD203D41E5E
-:1541B500FAD662FBB8C3394CE0252F8B970AE29BC2B54D7AC9E4
-:1541CA00BA7A01CFEE9C6EAD80F052E84FE8B92CB1718FCD975C
-:1541DF000B45DFB3ED5EA1B60C7A17207C11DD8B1D1840FB8A9B
-:1541F400D51B34D8DC15EB3668D3E94F83275020CE13B2828A7C
-:154209003307C57BE95C8D5EF2604C97D997F45994E780C44203
-:15421E005EFB791F3D17AE23F8884F0A8BEA75FEBD06EDD0EB49
-:154233000D5AE1B9B57A09A7B47DAB74FED97B88DFEFD140FB92
-:1542480012C265C55A0B07724C6A51D9165E4F38F34A0FEBFE75
-:15425D00580E62F807F3B15753BEBA7596F4A8EE9757EAFE153F
-:15427200D4D6DD8FEBFE55F7E87B73566A5823975764F3E7852A
-:15428700AC3324227FA2D6CAFFDA1775FFAB0DFADE9DB59A97C5
-:15429C00E6ECC0F7366B159FCE69C177627CF1DA8DF9630D1B06
-:1542B1009FC6B78679AD5E71EE615D3ADBA073CA2BF9B2F8DF16
-:1542C60086311D12674E362176B4AF9DCA9D6ED828ECDA65ACCF
-:1542DB00253710DE981758B6B1A26BBDB69B6401E982C5BBE8C3
-:1542F000FE879031FFF331DDBFAB41870DA1AA8F72B16F98F838
-:15430500A22EADFD922EDEBDD640EF6BF5BD842FD01C7C0DFB89
-:15431A00ABE09B524BC539C21F6FD74BCE7D512F3CDB2DE8DE86
-:15432F0043749F45F42E88F08D6E39045A835EC25FD7A623F818
-:15434400F06E82A505F0138E11377A1D3D2772B66AB3A81DC03C
-:15435900DFB9D37ABEFB7ABA0472C8F98DBC34AF6C3A4869289B
-:15436E000B7E36C98C04FE20E7C8BE9CE3F0D276CA237CAB09C3
-:1543830086ADF41CF8DE7CADE26C29E1B3549F896F7EC9B27C78
-:15439800F377CCE21BE0BD80F826E4DF2A70F1759B77C03725B1
-:1543AD009CD2A6F14E77FCBEC70A425B8826B1D66EF6E863B372
-:1543C20042D156C9FFB8EEFC2E8C3CFA186833AB7DFD46F67A95
-:1543D700CB46E75EF1AE477C1FA220BE7E63E158CB46299FE89F
-:1543EC00FC894AEE25DC5F277A0367B70BFC7B5A0A7907E1FE98
-:1544010071C2FD1E21B7DDF8CFB1F19FB0BE4B11947C9FA0B6CC
-:15441600A39BCE085A8057A29B46A7D102DF6D7BD0A605C9D76D
-:15442B00E2F52E5ADCEAA2C57BC287303B8677D2F8ED75D106C1
-:15444000EB55A03BD277D8F4394FB471E8B1659AFFE787D1E3D1
-:15445500828B1E7F65D30363B8C4A6C50D7420DAB86991177966
-:15446A00E4B1DCC8FAC7D876D6E21F7B64E32C65CBC63CF69F69
-:15447F001F2B88FFC946FFD8A3E277C51F8B315AEC67F43BF207
-:15449400258177794725F7908CBD9E17E5050EDE696C16FA775A
-:1544A900929CBB5F2F5CFBD414BC17CC84F7AE85A0B90BEF3177
-:1544BE008177A7BF6EFC936C2FBEDBC63FD67C30361CFC17BBB3
-:1544D300F0EF116B37167E7B6DFC164136D13BEC33BBF9DE2957
-:1544E800FF4B21FF2D9AA19C887B69D3C1C279FD14589E408C43
-:1544FD00AAA4D48273D5099237B954C72304C3A17B37EB15EBF0
-:154512009A34256789969773A7061EF693BC61AF376C3CF4031B
-:154527007A776EAD569CF3592D3FE70FAC77D2CA8D6CCD3D1BF6
-:15453C0077C73C2D806B2170522ED6B603B9AA47CC8548473C72
-:1545510037C7A641FBD89BCA71E6687B9E403EF80E03AEB7C9AB
-:15456600ECA43C99F1FE1A8D77CC5117D26905EB41D003684EA5
-:15457B000BBE6AE7FF163D57BC2BE35E7CD2EA77C1FF01EF9849
-:06459000C0E6B892000035
-:00000001FF
diff --git a/drivers/atm/pca200e_ecd.data b/drivers/atm/pca200e_ecd.data
deleted file mode 100644
index eca84aa7e0c..00000000000
--- a/drivers/atm/pca200e_ecd.data
+++ /dev/null
@@ -1,906 +0,0 @@
-:150000001F8B0808AC5A10380203706361323030655F65636428
-:150015002E62696E327D00DC3A0D7054459AFD261333136278A4
-:15002A00192663E02479728060A10E9063213F64F0700F3DE05E
-:15003F009E6CDC7B2F3514B35EF0A28B9A5A731E554B91474C5C
-:1500540034E11AB6692618B7609D8404A2121CA8648D7551435D
-:150069009DA578A56C8AF276A9AB829DF3AC92DD52CC5EB177A0
-:15007E00D4CA32F77DDD6F665E263FA25B775B7753D5E9F7BEA8
-:15009300FEFAFBEBEFFBFAEB7E79F4A91F6C270A21A1870849C1
-:1500A8007C974CFA8536C11F37B9A99FFEAD9C49302569258321
-:1500BD00D8EF4EEE6E14EF59E3B3EDFED3E3C735EC67E50822CC
-:1500D200A9FE0FFD29BF7CEA97A26F4EC993D537AF13234A5E2D
-:1500E7005EDE94F3BF245F4AFCF1F129E7CF9E866E0ADE2C3919
-:1500FC002BF0237F849F3240F688FEB5EC75792D39E3BCB43E9B
-:15011100C9A9F54BDE24FFBC9C3C6987DDCD33F3938CB0674E4E
-:1501260078D6F8D7D63FD9DC8CEEABDC4824B2F9DC949E391965
-:15013B00FED7BF11FF975E7267F17D1CFB4BE77E3625BFBC0C26
-:150150003F0FF9BFFF5372CB72671A1F3D3EF99DF51312ECCF0D
-:15016500C070095C0E5FF8FFFE4B3A7E246851FDD31C5230FA46
-:15017A00FC0A35E009832F79ADB5E45140A3A4743C8CE3E39F62
-:15018F00C35BB09DEAFF05BD7A95BB3DADE6B56DADE538465425
-:1501A40052C90E11EF08B4773A8857FB013CB7112F090619CEAC
-:1501B9005B125380AEB695F80197D874FE9A9022A5D554ADE572
-:1501CE002661CA73EE80B5F5F26AE22D7F9A78FC814838484AB5
-:1501E300E8B36DBD4D843D4C4930CE42B06FCC091861CFB9BDAD
-:1501F8002621C3B438D010BE6DD7091AF29090DFEA334930C6AA
-:15020D001187E86D9CB09E2EDF18033C8DD220A9BB6D57390DB4
-:1502220011D2D8B26F23C02CEA0FAC0EB76CBADB3C4F48F1BBF2
-:150237001157A5EBD25FC0FCCB804A3412ECA211D133EA167DD2
-:15024C003B8518510311A53A5FDD62226D9C4BD46AEA567ACCA9
-:15026100362DB78EE8A7683E21017F201E4E927EEAB6169944DB
-:15027600AFE1ADE3AEBAC0C53534B0EE4194CF8AC2FE47C6065E
-:15028B007960DD5253D1FA6834346000BC45C0D909BE0A681025
-:1502A000BDD7BA4BDBBA12ED8A7C09EB8EA79BDA6BF9816681AC
-:1502B500F70EF3723259F4518D59F578B3AB0A66E7A3597F0E69
-:1502CA00BA90E04E5BEEC669E5765D2A33DD6762936427C1D5C0
-:1502DF005CDA40CA8A7AA03EA807AC0147BBA02E52A72974180E
-:1502F4007B956F461DD851EB3EA14348C8A0EA9689F2332DA72B
-:150309000E7B941FFB00D8FFD6801526637B69AB8FCC22A5F03C
-:15031E00ACF65863355BCB4740B7F5A05B6A3CEC239954156CC1
-:15033300E7B09E9AA7F084F085DB760DD171378910B6285EA406
-:15034800F64A5F403DE05D8BB4C2F800BD8EE3418BAF06B8AA3D
-:15035D00EE81F5E96393DE6D3B92E0385D564748698085091946
-:15037200A79EC256E0D34F49792B1D759310AC032BD6FBCDCEAF
-:1503870038D845EFE5456A87F95932097ABB5B050D98BFE30F8A
-:15039C009CDF2BE6B767E667E6C6EDC6D24DB7E7A56AA4888777
-:1503B1003626DE3B6D253EE5C5810BE19CD8095A7CFEB241D8BF
-:1503C600765A663C6DAE8CBC4EF7B70D35420264F51833C16105
-:1503DB00A6438F32018C232C303A64E29A23DCADBDCAE604CE52
-:1503F000C2DAFC0BE48392B027D20C3E546386122FF0964DDB3D
-:15040500C0A7BEC35A366D323B120AE8B357F8531ECA1ED46DF0
-:15041A007F6AE732A6800FFA49302E6321B8C48EB97E560BEFE0
-:15042F00458110CC6910FE9B84D825C10415992A67940623CBF7
-:15044400E9EC584E5DD1912DB4E84C9DA9C486689188ABB8F0F0
-:15045900BD43E494A124DEA49DE43503E75D87B4D6F9E7F81CCD
-:15046E00E748EF05F296419A062866F84EF23AC04791363CBF24
-:150483000BCFC31CE5D213EF71C44759162BA4E81F2077148DF9
-:15049800DE677E1BF429501F117ABAB5A3E037FD527EFD21DE68
-:1504AD0072EB2653890C502FC844D803BC937403BD7E2113CE66
-:1504C20027FA51FE0EC4AAE7DCA04906DB38E62BF04FDB0E52E9
-:1504D700EFC24B09339A731CE3886F2C203A191CE0A344E0591A
-:1504EC00183F514DC49F88258C471F213EC2FAAC68A8CFB85650
-:15050100D6535DAAB92A3CE7C0EFCB0728CC6BDC33EBBE3AF4E9
-:15051600E76BC964B19EF8949519FF64CE568E091F74150C995D
-:15052B00885B1C83D82FEF43FCD0E167A306513B39C4E31CF4C7
-:150540000131A6FE965F4D26FD9E7387CD79E78E9AE46AAF90F1
-:1505550009FC2A0E7E2562E5D1C8C62AB40BFA87E7CCA98C1F9A
-:15056A00E07CDB0F02E0079ED07A136DD5DEE892EB27D74DDAA8
-:15057F009075F0D47A1E222F1BA9F524FAABBC1763C2F6998923
-:15059400F69376FBD1FB4F007E4396CDFA85CD8A1BD166C3B678
-:1505A900CDE268B322323660755A03C6B5E64D2B053DCC1D2390
-:1505BE00D266445F1497ADAD0B68E03E15BF6D6448D8278AEB56
-:1505D300C80678BEF73EB0C30FE947E092E01FC585095735DAFE
-:1505E800F671D7EE55CF245C958188AB5ADA037C046D01BEE121
-:1505FD00BAF4A9E9518E9B1D5AC626FE09B121732DAEABB48BBB
-:150612008C15B459DAD7B3F32CC428FA34D7B6547ACE7D067369
-:15062700345B4F0631B39A266B102748855D9AEE95FAA9DD5677
-:15063C00D4EA35EAB4875792D2583897B499FE5D3F12FA91FA31
-:15065100A3343AFA18E487C7B823BF7489DC027E87B620FA20D5
-:150666004FD1F043DE9AE5B0C528F877AC664BD58D1BD21EFFFA
-:15067B0059BA7B79AD423CD23EFF6EAE509A67B0CF7B609F6360
-:15069000FF23F63989F6D9BCD64CED8550E85072F557D21EB076
-:1506A5004745AD6EE339DB1EF3C922D37F7DA9B0478E5E629653
-:1506BA005AA5D57F827B8FBE9F46125FF04F66E1FE5412866761
-:1506CF0086F945D818ED469ECAF8A08A7BB46860BB6E87ED4EC3
-:1506E400F114BF6CDB45C1764D60BB8F6DDB5D00DB21FF8083E0
-:1506F9007F83CD7B22DFE3C67E6F5F26674C9F2BE638724555DF
-:15070E001A0F7DDA111F0B20A778361F4BE710B11F8EC13CAB3F
-:15072300CFB85A932B64C35C82792494788F611E51E60E9B4A3C
-:1507380007E413987728E1C8273927219F0C603EF1E1B81893A8
-:15074D00F9A4D8B3F9A4F963E02D724A539F88D97980873AFBA5
-:150762001C3A37E59359CE5C33A1781D3BC1DC9B7BCDA235ED12
-:15077700A29E2C523E379B4988CE17BAF7F3909FE8EF821F7925
-:15078C000AB11608D25AE1474B445DF7FC5CCD20E5FB68A3A870
-:1507A100170E70A2DF010DFCFD7FBBF54429CA4C9ABEA016F86E
-:1507B6008190DD315E0F7E5103E34F925FAF825A94A30ECFCD41
-:1507CB00EDC7BD45FA3FEA06F6167AA890B7BE6EEB8ED2E275F7
-:1507E0005F9819585F7C7324B932C5ABCC90B5C0CDF0B262939A
-:1507F500695544DE16B4F419E647605EC90313E7DD13D9B652B6
-:15080A00AE1BE31B70DDEC7941C02DC8C25D1129B371352AEAA4
-:15081F003D7B5DDD02EF009F3F4EEA549887F684FAAA68452469
-:15083400AF42D45290DF570BFC56BA0BF015C4D73BF911F04B90
-:1508490037E243DE03FC62DCA7D1977CA206EDE5CEFA7063BDC6
-:15085E00A3BEDB4CC197290D617DA68BDC791A7B55055EA967AE
-:150873000D7A477DD7EA98BF20E2AE48D57848C3FD00350F601C
-:150888007C421EC69849CFB37FEA060FC6604F20B001CE496318
-:15089D00F45BB141FAE3B6A126DC2B99A8E7346641AFCCBD0C5D
-:1508B200FC9F80B3D24E383761AD1C83FDE1320F41BEF0EFBA70
-:1508C7005F9C89FC501BE39EAAC2D98AE8F5D48775DE582DD4FD
-:1508DC0079C130D653FB649EE04837404E899AD0B2CF592B7220
-:1508F10048F13F47DC707EFA7B13EB3699AF0DFBFCA4DB755C24
-:150906003B75477AA046AD605EF541B3E5D6BBCD36A0A978FFF8
-:15091B00C6DC8B750C9CBB3007DDB2E7553337827B40B7D80387
-:150930008A033190A792DF42FECCF4C379E3167106B1EBAEB1A5
-:150945001EEEC7F307D45D9DA1DE74BD05671CBE429CA18E43BC
-:15095A00BE5B682CD0CC95E2ACA1F6C4DD381FFA828EE5E21D9F
-:15096F00CF4F17DE36CBDB9B95EA476A72D279D11F53A6CF9FA5
-:150984002F7597077ACCF25BD6C49886A7633517D785EC80E7CC
-:15099900C4DF12320AAD0BDA4E683AB425D008B40B301E87C6CB
-:1509AE00A0E9625E4FDC6EB04FF43059BBFD16CF2CA13DDE56FB
-:1509C30043BEDBB50EF83FC2317F3629F20C3409C7410F71268F
-:1509D8008F2F88CBF60A4BF1D9381D5E9ADF82B8362D3FA475C3
-:1509ED00BA4BD293F8E3643ABE8067E39C2533D1CBD03A3C13A1
-:150A02009E8DD33425BF89326D9C964E46A68553D2C9D040BBF7
-:150A17007F55C31A995C3D2CF1C7A25CE40D8CB1E29881790360
-:150A2C00623586F12B629A58F412FA289C3F647C34424C9608E5
-:150A41007F9B2E4E5E8138715DFA8579CB9E939363247D66979D
-:150A5600B181F1823501C620C60CC64E3A56ACA39958518FC96B
-:150A6B00B3FA18D457D69F1A6B2156F09CCE223913E224153FF3
-:150A80001F431E9A8D7990EDA5175CF2ACFE817D7D38027114D6
-:150A950081380A7D8D38DA6CC751C3639938FA009E23DF07232E
-:150AAA004223D0128F43850E8D416B8016825602ED1AE0753D49
-:150ABF0036318EC41D03C412CAEFD9DF938E27E09B965B03B992
-:150AD400F7BCFF8A21C70726C557AA05537E9F8DEBE047317E33
-:150AE900DEEF81F157441D23C75BE2B2C13A3649FEF5022F9BEF
-:150AFE004E8B23CE5AE21F91E9F8B54C8AB35E320D3D874FEF6F
-:150B13009A915E86969EC69B420F382B230E9D92DF4499668A69
-:150B28008D7A32959D60BE4D7FE194E3683F394E74A0F3154D74
-:150B3D00CE4DE17F988EBFD4BA8B38D4FBB846C8AC542C4EA83B
-:150B520027713FDF91D98F156FABA86DB78CB65588BD1DFC5798
-:150B67007D286614EF1AA4BA479E078B77F5D28847D6AE88CF94
-:150B7C00B0C665526784B9B260E38E7DBC445B88674CB6E10A5C
-:150B910021EE75DDA61F635A2DC718F12B780796AE33FA999E1D
-:150BA60043484524B702756A8067E58101519721BC73FE108595
-:150BBB009862B92AE8AF77F3DBB513DC1D6B73DC635914F1AC84
-:150BD00087F12E56D25A75B3B4622F6768017E1CF67CBF1E338F
-:150BE50015C85F985FE2F23B9EE0F375F4B11CFA743964B06EE9
-:150BFA00521FC48BD74A7D2C873E5F492B4B9FC12C7D06BFA10A
-:150C0F003E71873E671D32C46F521FC44B7C47EA1377E8F3954C
-:150C2400B4B2F419CED267F81BEAA35EC9E8B3E44A460684DF02
-:150C39008C3E88A7DAFAE0F3AA9BA595A5CF48963E230E7D4207
-:150C4E00F6FDA61A180DA77CBCCCA066BB897CA58FE0FB4EFBF0
-:150C63003D6EBF37D8EFC81FDF0DF11EA3C29781C7CE1CD1D360
-:150C780041FBBDDF7E1FB6DF2FD8EF23F6FB6AA0B3533BC6C47E
-:150C8D007E0B63EDDA49BC1BE40C9EBBB49FE2F99F8FC273BFE6
-:150CA200F6160B698BA97DE6E61ACC2B857D695E24B73A10CB76
-:150CB700ADF62572AB3DB00E78DE451DCBB597059D7A98BB5EAC
-:150CCC003B25E844E1B9567B83E1FC77A41C0C79D66B7B98A408
-:150CE1006BF18540B710724F0D394B4F6F3BB916715096422D36
-:150CF600B702613FD9F653011B75C0F66E7B4BC050A614EC99A4
-:150D0B006DCFAD4DD15FACC9F5433AF3C4733FABB7F9A34C0FC4
-:150D2000960DAC49D14CE122AD146E4A5694ADD4C645BAF768FE
-:150D3500B9D5381EB56DAA3D216D1ABA22EF6F904789BD3FE19D
-:150D4A00B8BEC3392EF9DD65D358286174F44989B3DEA681BC57
-:150D5F00FD4803C6C69FC88C55D9760CC3F846B01FDA8EC2739B
-:150D7400583BC0F0DC392264BA2CE4DCA1BDC88E08FB76F1DBED
-:150D8900AF0807F47DF7466E65D9853BCDCDA56F2C7F612C6631
-:150D9E007C7B2DCAD12E6C940F67B9556BDD952B4AF72C6730C3
-:150DB3007697188B0B79F363B915F3DE7257064A0F2CE7305641
-:150DC800B856CA8FF6CA8738B9F17B77E5EFE6BFB8FC208CFDBE
-:150DDD0047756E753E9C577F7DF1F32AA4F9F17C5A85F3FFF557
-:150DF200C86015E29EBF78026AAD06C113E48F5BA22F113283A0
-:150E07009E715DF43B056D120CC555D1370A39E07C18C798B8BB
-:150E1C00EDCC6553F93002F1F71A2D10DF7F625CCEBBCC6B45C5
-:150E31002F6D4482116E403F67DD5153D9F47DA8B3F6D15B712C
-:150E4600AF04BB49BE31DE2AFA06DE2EFA2E61CFBC3D80BFEF5E
-:150E5B0069C0BF9B16068280AF895C26F2ADE81BF9B0E8570B92
-:150E70009BCF3A03F81FFE10F037D1D9011DF0435CCA1DE37EDB
-:150E8500E89F15EBB093975CC9EC6DA454033C43ACCD23B0367D
-:150E9A008DDA7EA606C6007681AE96B6E141D15FE0E5D037AD30
-:150EAF00245E1674D52944A3FBAF277DE84B3B005EA01D83BA29
-:150EC400C112F6CB81B3F8ED77209E8C2BDC2B1FB171D1DE7613
-:150ED900BC517CDE0D3C55EF0766EB9A98FD6DB39F22BF48E2BF
-:150EEE0067DCBF6B08EB5F529F789DC33BB340367FA8CF54BDFC
-:150F0300782FF021776B43FC9315B63CDA1DF4C69792C76198CC
-:150F1800AFDAF2305B1EAA65E4C1BDEEBC8D3BEA9067740679E9
-:150F2D0074873CB5200FBC3336853CB50E799EB4797C807164D6
-:150F4200CB336ACB73BD2C230FEE55F7D9B8E86F2979F0793A72
-:150F570079420E79D6833CF0CE6253C8F3CEF28C3C977E277943
-:150F6C002CBB827B9A940779A03C3B1CF2E05E735AE20A5E2E36
-:150F8100C8ADADD57DFC7A32994CE55867F917D10659443B01F6
-:150F960039BA96AA810DE1CE35FD14FF4FA873ECB821758973F1
-:150FAB00DDCE291BAFE0A505F1791CFB6658EB6539856F9A5A59
-:150FC00002CE58E939FD7C839D8F53B806E04521B67D901B9DD8
-:150FD500F3752DCA6A81BF017218DA61689FB1466D21DBA92DFB
-:150FEA00039F2967ED5A15ACD57A56663C627272B07149A28F90
-:150FFF0046ADBEC62EC08F6923AC5FA3ACF3C8095A4C06CC398E
-:151014005B8FD0F9173FA3AD5BEFA46DF397D2E7B62EA7CF1F57
-:151029005943DB2FAEA387E69FA6783FF357BFC8C198A6F8BFCB
-:15103E00542F1C7993169CE9310F5CDC07F5C0BE554EB9CEDE5D
-:1510530043BC85DAFAEA344C6FA1E5F712AFCF09130AB4D0C3DD
-:15106800D3C06BAF2527C18D480BC37C89F6F12F9E621E6BA1D1
-:15107D00CBD64C01875AE093F9C4BB30D6C3704D312FD45EC9C3
-:15109200D405E99F3AC2884A995B13DF2FD855FCC78E2063D72D
-:1510A70044DFC5AEBB64AD33EE92DF494812EAA2C23E336A0D67
-:1510BC0019F87D638EBBCF3C9433641C0A0D189DB0962F586F8B
-:1510D100189E0F3E1777C9F825E280D561A81BA9897E90EF9079
-:1510E6000FCFF76E3A24E0CF440A2A3E49FD7B8D9D377E5E23CE
-:1510FB00F7C7487A2F8D31947F01EC63F9B1DF97CF8BFD1DEE8E
-:1511100023F65E382CEA18B97F0DCB5C073693FB1FB371BA04B5
-:151125004E43669F14F1F0A4CD6774129F5B27F091FBE5B0A8F2
-:15113A0087527CE2369FF5361F89D345651EEE67B171428E04DB
-:15114F0095BABCFD7DA63FB4C83C06BAFA2277560560AFBA7A78
-:1511640043EA7B3E726FC56578F680FDCB0C3807E50E34C29EFD
-:1511790055AD94F687550DBF8B04E9D8DB9027624A5DADF6326D
-:15118E00DED9F9DCEADDB00F75B0D2D0BEAA0324DA48D43DD4DD
-:1511A30055DA15762F851A4DFF0D5FA8FD86BB6C5B57691D3C31
-:1511B800A41DE0FE441F63B97D4DCBB46E8E79C51A053D12BD56
-:1511CD004C059A08276A94C281CBE3E4B9E527DDD5CEF965C6B7
-:1511E2004193DB34702E3E232D1D68B94B97844359F37D303FCA
-:1511F700A4BDC8A186B0E747A79CAFFE23EE4D4BC2284B10C611
-:15120C0096419D11D43AC45D3427AD8D86F62B9EAB609E3B411A
-:1512210039E96C74475AB90FF66017D6BB7A2FF744A2BC2032BB
-:1512360022EE9C27FAF1B0EDC7D6043F4EFBEF689FA13AFCB79B
-:15124B00106A85B48F821FE0FAA18FE6ED1F308BC92253EAB616
-:1512600044EA16EAAE76FAB35FEB608188BBD28DE768C2A807ED
-:15127500D6A3E94EE2C5F7E7E7B61B259B89F7A5B93143D596FA
-:15128A008AB5598FEB0073D9FAE876EC73578BFF21CABF23206C
-:15129F0069AAAB3C61159E676A128F885E0BA4E4D620EECA880B
-:1512B4005AB8CC6C752DDD9E6BC399CFDA9E1AC7FF6352430BCD
-:1512C900BFE74ED10845BFE74B3DAFCBC0459C801EF81D11EF02
-:1512DE00CD0E6AEE3A96DE9BE4BDD916BCABB2EFA5314E08DEDD
-:1512F300AFE9C75940AB2EC7B51570BD8F5DAFA95E29EEFB990A
-:15130800BCE39FA37799F8BD016922CCA746CDB3C9A47F527EA9
-:15131D00B2F9D74EE2DF6EDF9D4B39EE127766BD71A4A3240E38
-:151332004BBA3A7E4790307C4E4C419FC571FF91F4D500F0620B
-:1513470094E2BE68D3F4F9347FD50AADA02264E78D0AEDF66A05
-:15135C00A0C97C6A47FAEE1068B3A2ACF7F4B3CD8F8F1D355654
-:1513710068F757F8B4FBCB03DAA28AD47DEB0A6DBBA46DD35490
-:15138600BC8727D155DE9F19B638717B25D610F8EC4638D8F716
-:15139B00207ECF8950FC3E731ABFE72C4EB82B713D104791385F
-:1513B000EC20E660C4D1FB38E2A0ACA501AC11A1B67B88903162
-:1513C5000236FE4BE255C5DD690CCF9BEA79D24FF15ED2F20E35
-:1513DA0088EF6B44AC7B4CE0FBD5D7E47730FBDC81304D1BA0C3
-:1513EF00E28CE280056D58A303B6CC8635E0D9B754F0E33B1C7E
-:15140400E3E2FF0C865D648936C09D30DC971766C188CB4DCA55
-:1514190027C2583DF46A6488A910CBABB3C712CAF87016AC0146
-:15142E0060235930F7BF29E3A3593002B0771066AFF37F13F3E9
-:1514430084C1511569F6242F3203617CC0644C280C0F0C1AF656
-:15145800229960D0640871E2A297502C37025AEFB141264ADC60
-:15146D00E0A1CC4156D92DEE7CC144126CB07926122DDD9DB8D3
-:1514820099327844070F14B7425DEE8E73BD2D6A2B6559B7D497
-:151497009D52B355DE15578538BAE8B2559C73DFD7DD6FE6CDD5
-:1514AC006450F1F6EA7E4CBD37DDFDBEEFEBAFBFFEBEAFFBFBA7
-:1514C100BA31DE44D82DB80EE738919E4FBE9AF31B37FF6E8C0B
-:1514D600D97D8E4A1BC19FE113CC3500EB7D15DAA8986B25E05C
-:1514EB0087B471F62449D02133CEFDA473208FA0ED37A19F74B0
-:151500003663C7C458757D99E6E3144ABE9AA12F947C9BF50CD4
-:151515008CEBAB1D34234CD447180B4298111E57823AA4431D81
-:15152A006768C3D7CAB2AD92C6AD92463FE63CA91C16DF3FF7EC
-:15153F00E1FF709CDAB90469291BFD5236446E9DE415D833C0CF
-:151554000DBEEBAB6C10E61C105FC6F58DEC875B3ED5BCE799CF
-:15156900AF3269B70EFEBE8AB2C2569792B0D97682E72DADE6FD
-:15157E00717D5146D64D2F2B7296012DDCE704CDE492EFAB5527
-:15159300511E4ABE0134BEC1CA529CCF7E53D2C1CBC0E6F81BA9
-:1515A800C7A4FE495015BE293361DC608CF8337C825E8FF0D8F6
-:1515BD00B855A83D29D09E64DABF2DF80B65F06EEDC9F843208F
-:1515D200770BC03B94FDC477DE271FD06EF709DE2FB9C6F8FCD9
-:1515E70009F8B2F5FBDAB2F576D9D305CA9475D3CB4A9C65796F
-:1515FC00F1542EDF728EDAF3DFA91B7AF274033EA764DDD5BE7C
-:15161100310B7C63D755E3F3FBD96FD1EE4ECD27B36CBD843CC7
-:1516260079CA9639785F78B6D748E4D5CF3A3766081863B4A142
-:15163B001CFCA948C92615F7A301D6853FCFEA38940F9C17769B
-:15165000DD94B30E78E19670F8D301632C0F86CD032183A2CC22
-:15166500CC2F03787BED325FB6CC2C5036D39B5B867DEA73F4B0
-:15167A00D92EEB2D5056EC7596993451A9105621F9436214752A
-:15168F0006CE4B1FC83CC6CA306EC2FFFBC7DACB1C6B51524A3A
-:1516A400F89A13E5D7C7E5374E6D399F7910F72B13AC1DE6BA33
-:1516B9003F2474592118EA35C380BA700CDFB19DA53BD60968C7
-:1516CE001F501F6E475D02FFF1BB0315633A878FB2E223AC503C
-:1516E300B9EA28A7CEF6E585CB5528EF92712E94FB7C7E617C84
-:1516F800B820BF7C85FB3AEB5CC21832C7A3072A123AD703DF1D
-:15170D00866F7F4258D8CFAF1B037A2D747D6758B9E39A907AAE
-:15172200DEB6FD421FE7F23A571F17A005BE11B48C51FE04D841
-:15173700D7233CF06F0AF2A1407B92699F4BDF1E87DCE1FC7519
-:15174C0079A7CF6FE29D3EBF8BBCD3E7322950B6DF337D7E97A8
-:1517610078A7CF6525AF0CDB3FE7FC36BB26E13ABB92CF716123
-:151776001B90A70B1DB60FE3E0DD72AF86386CA19A57A738EAD9
-:15178B007C79756E475D795E5DA9A36E812AED48204577F72309
-:1517A0005D268F1F667D8F380BDA7BE6DCDF88338C69E058640C
-:1517B500FD8D98217C8BDCDC45A266737E547F75BBABAD8E9F57
-:1517CA0067C09C7AF516428A0E361AC9CFD31E5843EA53F054F3
-:1517DF00802798FB87FB643F03997A3EF6C77A726984BDD79F79
-:1517F4008DAFB70EFCFFFECEB7104F0DD0CA423DFAEA3B9555D3
-:1518090076EC09E339A4DB7C7312CFA274C7DE9CE2CF495CDB6C
-:15181E00C033F9668A9F5101FFF25EB157E2F039A98B8C9F43E4
-:151833007E52807D39C4E339D2CEF6839D1D053B0BCFEF8FEA65
-:151848008277D59C77B6CD8D7D96F6106FAFCE3E93FC8BB8384D
-:15185D00FF50FF35013C13CA3FBC53B903F1EDB957CC93DDF0B5
-:15187200447F12734E79CC08FEAFCFF137E36CCD771C7335E3A0
-:15188700FFA62CEC2BF024217992903C49489E249027C5B09E3B
-:15189C00BE16FEE15CF26A4B0233B5BEC04BC58257A2EC562824
-:1518B1003B1018CB295B01654381E3765929969541D98D8149CF
-:1518C6002CE3FBEE829F7A0AF8077C6C4D4DE7E3A53B89A721F4
-:1518DB00857CACBAE34FDD9FFE02F25024E5610FE03DDF9C4B45
-:1518F0006783423C473F853903B4BEF4E9745A5BE11BFA29D2CB
-:151905005AF3AD69B5E391DF86DEED05E82D96F49E015A1B9ABF
-:15191A00A7CBAF8939BE0564F7E38B694F11F4E3838BD3FB616C
-:15192F00029CD317B11FBE6BEA47E63CEEB7EC4F5781FE28B23F
-:151944003F5756114F17FCBE0BFEF73E813E69554CD56A18D73C
-:15195900FDA0F35CCB09998472FCAF9056FA21BE0774AA017723
-:15196E00166886A56A2D2F22FE08E899B511DC0F8C51DC35426B
-:151983009B98A262AD12DB0FB65831C11EF6F3FD2C0AEDCE4436
-:151998008E58A51DC7ACB512762F3CD3D79B74233C5DE2BFBBA6
-:1519AD00218F9E06D95687E746F0357D9AC04774810FF120BED8
-:1519C200E833B9F81640BBD28E23D65AC0F7E10501C327F17D8A
-:1519D7007C41E083FF6E273F55C9CFA34D44D437919CFA39B6C6
-:1519EC00FE93F59756E6D6CF95F5DB65FD0779F5F364FD5A59A5
-:151A01007F9CD7A7A8EFD9ECF9A334F491913E1DF790DC68A32C
-:151A1600F3CE1BF5833FC4F0CC47656C7333EE2F997D75959A13
-:151A2B0012D4A53E1BA838AF3787F6055B1DF1DCBD273B7E8D0B
-:151A4000BC7ABCFBFDE680A3FCDC0BCF5CC1F2959B7FDDEC8CD9
-:151A5500FF9E7DEBA72F63F983FFF8AB665289B1C761DAFBDB56
-:151A6A00275A7C7E7373EC87C433761FF14CA3D391AF9B7A36C9
-:151A7F00D73E0B5F2365A10E7179C53A8C97A9B97DB3FD236C72
-:151A94003713647D3028721BB0ED40DBB83E33725F607F1BD7AA
-:151AA900E5CCB47539D4719D0F3079591E3C5C6F52B02D5D5C15
-:151ABE0086ED35183306CD2A1DF7BDC16FF4F457C4F4BBC89216
-:151AD300A0972CA99BAFB98298233650C1F4756655F0BD0C5F2F
-:151AE800C6F83EC46CCE0FB6177D9412F0F546F3EA3D8E7A059E
-:151AFD00EA7BB37CED2F5248BF1BEA5DB5307EB2CD7C6ECFC40A
-:151B1200B7D741FB8DB2FDF740FFFBB592805DE787BA0622E42F
-:151B270009FF2F3C3B6254C3FFF98E360BCFC60D5F1E3DF7C0A8
-:151B3C0038252271CB0DBAB6FECBB4277625EDD9FA557A96EC0C
-:151B5100DFAA49D0D3203F397AC527E574B491F079134A3E4B1F
-:151B660093256416CA19FAC136EC27619E610C4775D0E5AA8842
-:151B7B0019C723DCFED2808C3FEF01B8D5C0FFDE45C493AA12E9
-:151B9000B27FB20160CB7D72226DF99364980E4E8EEA336F4273
-:151BA5009B1EA0C297D5E43E6D35C576459EB8F1AF8B7E50EF22
-:151BBA006B8CB1062BEB6F45E0BD669090283C1B9E23C484E70C
-:151BCF0065F895C3FB65F885E0C79E13FB5D08A7F53FD29ED399
-:151BE400B82693FFDDE7D39EE3F89F8DB079303E181BA8E47B6F
-:151BF9000929EBF4FD843C87B6818D58367FED75C669919FC22E
-:151C0E0061281AC6285EC77C7A9ABA8F102FEA228C9B711FF33D
-:151C230088E56AA306EE2763EC8AE7CAAB23B8B75AD6E4A0E3B9
-:151C3800AC9BCCC2D82AE2C7734FB857B100EAC73CD25E713CCB
-:151C4D000798CA7535A326FC5FF05F609F501F89FC8B0C2D99AC
-:151C6200B39958F63B570AF0F17D3CC5F18E7B97F63BEE59F2DD
-:151C7700B80FFC1F73C4B96C783E76C4405D904A5FCFE71EC6BA
-:151C8C004486FEF9282F23A9EB89EFDD51F10E7F701CB36D6341
-:151CA10016C65186268FEA650ADF43B1447C2566613CA5C94103
-:151CB600B7D8BF1CA60F4C3D30B5787234472E67A35C227D20D4
-:151CCB009BBB6F271E1EAF0C1F61E8F7EDD7560510861B73A2DD
-:151CE00022A798163941FDFC9CD3179697E700279862EF075FF5
-:151CF50014F916FC5C82DAC3F74C791C397CCC7A5CCEC76BF51C
-:151D0A00279B1CFCFA661A246E3CAB84F80BCC81F25560EBE5AC
-:151D1F00FC60B8F7AC522E5764B288801D328662CA263C7B40E5
-:151D3400EFE5716FBFBD6E9B43460CD46BC85B2AE9C3EFCFDEF8
-:151D4900463CCAD45386FAFE53BA5347E2792466821EE76BBC5A
-:151D5E007E9AFEBBD30AC626152EFBA6581F4D017FCCB87E3379
-:151D7300190DE299C5D496A3CDCE71B94EEA8BEE159C0779F150
-:151D8800175CBFD9704D0E374D4ED2CC99447594611CED7B66CF
-:151D9D00BC20EC191276F90A92B38F9B858F79A4FD745FC5B0E0
-:151DB200CECFC7838E45FA63FCEC42DC5C8CEB03C0519C1C3729
-:151DC70095E409D35D1A37704F7026E09B1B66862B42E9A1A492
-:151DDC00B249D17AE90DEA2F8D33E9B4DF1B5382D9757098A279
-:151DF1005FBBDB85BAB015CAAAF9790D9EAE8B3EC3FD620D515C
-:151E06008ECFCA06983B77BFC8D75A01ED4D727F017AC13E46AC
-:151E1B000EA37D1CE6F6715FC549DD3BD9773BC737A5F4B2C6FC
-:151E300031417B386E7AD1DF93E54591B8A9362678FF0E9103BC
-:151E4500BA05F2EA5E07F38DC5AD9BC51955E68A8C67FA3737FD
-:151E5A00341AB4BF15FA2AF33E8D9EF70E67F371F7817FE13540
-:151E6F00253DEC2AF440B90AFA176971E2748978EADE9C3334E2
-:151E8400A82741C648E549B18F20FD33E09DE08FC82DC8E5A33C
-:151E9900DAF762CE7E3DCCBDC806EC036BC7791A4A1EDE5B29A3
-:151EAE00D681E683503E188EE96EAFD86B4B024DE78B4D3CA3AA
-:151EC3003E0BEB03EB458E0CDAB0C572EDD8CA6564CCAC833ABB
-:151ED8009B764E37B46F58CFFD6C1EC75F2BDB353ADAB5245FE1
-:151EED00DD0B3F13CBA3EB798CC4C43831F605D7AA48C7E05399
-:151F020071DD3729F704A1DCC6DB25E1FD5501BCBB1D78B7CB1C
-:151F1700763F71B4BB0BF0623BD3D12E2ADBF514A0EFAEE41B6C
-:151F2C0026CEB17E4EE3DF9B685FDC408B0AF43DCF65679CEF03
-:151F4100430FFE13D04AC4397EB783D66E097BA000ADCC41C374
-:151F56006ED9EE50015A871DEDF6C8762F7C0DAD38C636ADA5E6
-:151F6B00DF406BA983D6A484DDB1613AAD5D1BB2347C2CDB6D89
-:151F8000DB7095F1DC901D4FE52AE3A938F09EB7C7B300DEDD56
-:151F95000EBC17ECF1BC0ADED68D38BF2690074C75E2C5FECA8E
-:151FAA00FB36B0DC96F935D0FE308967647E638990F92B2E21E2
-:151FBF00F3A18D59DCE11281BB65E3D7E006BC3E89D7C6E77309
-:151FD400F473A384D1561806C3396BEF7597E7EB3CD02FC75F90
-:151FE900CAEA3B3E9FF95D0A4719B767784F8E7A9CA11FE92EF7
-:151FFE00ED33F6815FAA826D53D79E32CAE909E32021739C3A1C
-:15201300E86FA05F85748FFD9DDF15D70F9BE33ACA8B88271E8C
-:15202800D0613DBC17D7BF77715859DBB01C6015815DC8E8D5B4
-:15203D00D0B8EE5E17E73A95EB53DB5E98A84FE35C9FAA6D40B2
-:152052003FE85197E33DA7BF9598AF31ACBB2A9881E7F178AE2F
-:152067008CB0F9D23625047E26F5697848F8946063455F46F90A
-:15207C00F9097E3E08ED52641CECD23B863B7682A26D2A684F28
-:152091005ECEAE1F193FC7D46BF8319C8E7B15F2FFA5747A5E1E
-:1520A600FE5A52EC77F278BD359C02FDEA81B915AEA12CD41386
-:1520BB00455DEC2E163A59917E7C293CA37F486772FF588AE7B0
-:1520D000E79539F3C6944671EF4CABA31D5EF893DF0E6DC2F3A4
-:1520E5001A9E5B3AC910CE83987F510BFF8167E877BB2A13EDD1
-:1520FA00587F4368D4B821F40ECA8CD5CC7345C618C2C372FF1D
-:15210F00E6B895FDFF8EC1CBFE3A8E3E0BF1B38421BE7F076D69
-:15212400BAAFC8DB631CFF324BD3608AFB4D0E9A12B4991C5B1C
-:15213900E9D75C011B37DEBDC3F34230FF1ADAFB6FFCC2CABCBE
-:15214E00AFFA228327B9F058535126EF07D6AB320F1BE92ABB9B
-:15216300310E7EFE10B3F819D31A3A07F87D3BB24315B044DB21
-:152178003186FC07B368A9EAD330D6C7E19B414BD18E5BED0E8D
-:15218D00BF12D6DDE411AD64E5844BAE8B0BE05983BE4B41D8DD
-:1521A200555689FA16C09EA0840D594AEC94856704C4797E691E
-:1521B700BB51BF15CBF98B396DF25C0091759305FD19915B88C8
-:1521CC0072746106D29560ED226798B9257D6E271D682B8B05AC
-:1521E1005C7F30415522CF2AA8C72CA443FD6889C56D51868E26
-:1521F60014ED8A65E51BE11CBD4FC0194C09F8026E82F3A7EC3D
-:15220B00A33EE68235223F8347C6753C138F3EB0F82661619B93
-:152220009C7900F03F8C65FD1FBBDF083F719FE89FC0339683D4
-:15223500C7DE73C0B69C8F49C1C71B36F75AFE7082D7259C38A8
-:15224A0033E7914354D0D24055CE975679875080BA653E202FCF
-:15225F000F8FB28717A1EFFA0ACF4773D2E07B7909738E1DB4DE
-:15227400B114F508C6FE992D27E80BE30D65CF935E9DDFD31477
-:15228900A69C2FFCAC05D42BD05FD660525C841797F61AECC022
-:15229E00ADC607FF96F690A911BEBEF7E118A96F1A8A768AF9BB
-:1522B30023E24E017B0D535E3C7D1DD5D37624735E3EB39E9A77
-:1522C8003A66DD7EADEBA9F06B962D539847365C22D6BDB93243
-:1522DD002564086919967CE163128C7179E2EB5958C7A33D4393
-:1522F200794219E0BC32C51AFEA5AF44AE52A1F504CF1B0EC06E
-:15230700DC6717E83C7FA01DF767BCDA92FAF7D19EC23AFC1118
-:15231C00EDD6E0659893CB93BE55DC36DE2FF37DEEC74B4F0E1C
-:1523310070B9E3F960A2DCC2F2F7E4FA3622DB46F3DACA720B9E
-:15234600CBEDF3B836FC5EF9CD60DE37B2DCC2F22E09BF5FB607
-:15235B008DE5B595E51696DBEBD4C512FE6AD916DBE1FB028718
-:15237000BE6975D4E13B9E6DC2334D6E90A362B0558A36622134
-:15238500BF1475BF81E31DD046F19EA9B9734343CD0AAC57CB16
-:15239A007A2E18A5DA116BBEF94993BFE55343891CB75E8E95C9
-:1523AF006C72C39A0BECF1BC9991192B95C805CB96D999A0DB1C
-:1523C4009257709F2E3B077E0A3652E1E746D8B4F928E757464D
-:1523D900AF200CF5E08831583CAA236D73375759F67CE632C014
-:1523EE00CFE58EF3BB8BF8592FA147ACFCF92CF2400127CC19EB
-:15240300E73C796A76AF91F8ADD84754A54EFBA679F27480DF1E
-:152418008D23E6C8C008CF89518BB3F98F8B31F7007C8D07F85F
-:15242D00DE7E36AEB50EE4CD67CBCDFF36BEE9984FAD45FF072C
-:152442003A3ACF9F086B23ACC4DBC7F9F912C06BFAD4E10B5CB6
-:15245700CCB3BB400BB611FB20A6C5F7472AC7DA4B0EC68D21C8
-:15246C009015B5294E93220662B9C57E29BF37096D33D66BB0B8
-:152481006E4FA17D97F0307EAB4716B1622FDE75D743272F66C3
-:1524960071AB05FC107704F0F23D0AD3C2F11A02BBAF4E8CD0AA
-:1524AB00CB12278E6F0E4EA877E7E1CCED7F75FB4607FE900352
-:1524C000BF5600BFE2C0BFA000FEAA6BC48FFE456F6380DAB4A9
-:1524D500200D139F081A1600AE7CFCEAC4118E4B8B8CC0DA3C30
-:1524EA00D10E6B6F0B7D1F45E377CACC5B101961CF83DF833679
-:1524FF00ED92D3CFC1589F5A65F5B65103EF74BBF46455338FA4
-:152514002756DFB4B4AA6D6B50FB6143E366ED9EBF587FB7B6A6
-:15252900E127BBBA3B1FDDA5ADEFDCDED9B1AB33A8B56CB9679D
-:15253E00C7CECE8D5D3B7EFCA3AEEE2DF5CB6E5B16D0AA1FD909
-:15255300D5B56DE7CE1D8F6DE978BC235457D75877DBD23F5BD6
-:15256800AE3DBC6D7BE72E2DD0585BD750DB7807BC04EB03C11A
-:15257D00FADBB4AA4CFCCCC6575BBBB533BAA3BBF6A11D8F4646
-:152592006B3BB67644773D51FB68C7B6C76A77ED7CA8B6735700
-:1525A700B4F6E1276A3B3AB6F3B2ED3B764497EDBAA96E857601
-:1525BC00ABD6B9755BB7B6B5F3E18E1F6FEFD61EEAEA78EC478C
-:1525D1009D5AF5EEEECEDDDD4B11CBB783BF75E7B6C73B77D624
-:1525E6003E0CDDDAD2D1FDE896AD3B1F5FF6D04D2B1AAE063F10
-:1525FB00039E9F6799E30FB7EFC77D42B58ACEF537B4576BF5C9
-:152610006C199EE5B1F3F423CACA85FA05E350E870B4880CD334
-:15262500F63FA63379FAEDDABDD67FFECEB552517F6054692D59
-:15263A00B40AE6DE39D0253E78BE85BA539ECBEEFA22ED797785
-:15264F009112DCA81D613550379F8C3787B401C6EBC3CAD30165
-:1526640028437DD3E428C3762AD8408069F56BA5AB6C9B500E21
-:15267900BA710611BE04FEBF02B0F7A9CF44D14F1CFE657A16F7
-:15268E00D2E5CC6B77E6B4C72E8B585C1F6F5F4DBBA03D513FA2
-:1526A300B77CF0CD04E68D39F0B328E1676797B9C85CA40FE9F8
-:1526B800F069C718F66106AC53317F8E4C2DC538ACCFDF72AB4E
-:1526CD00817DC77B164BFEA1D1C02B54AA0096D8AF3A44C3DAC6
-:1526E2000BB4FE6DC00DFE940FBEB7F1E0391EBCB301CA2C2721
-:1526F700CE35E934C7C9EF6D04FFEA783A3DA732E2127B6AE153
-:15270C00017A1DD80584997C0BF3660350F60AA7AB04ECE521AB
-:152721007E6FC47EDC972BB3C7CD3E6311FB038EDDE77CEC30F5
-:152736007EA36930EFD4BE845B5B6195B41C85F13EC061E33C5F
-:15274B00C43958AABD6CD57CE56ACAFAAB620C6C7E3BC7C1F730
-:152760004EDAFD75F5574EA66739C703E951811E9F63BCA211D6
-:15277500378D257F65A920875A722431D7BF1BDA76515F7211DD
-:15278A009B9D2CDEB43AB914E435DA8E776AE01D89782F0E0997
-:15279F00DF4DDF55709DA453F465947F79D0C07B36D662FC4621
-:1527B400C533BB61EE8B0E9ACBF5D74275ABD66845ABDE2F396E
-:1527C9004FFDA15BF83E63EFEBE959975C765ED6009B9133FE04
-:1527DE006B29DE5D89EDDAA1DD19D92E906C01B8ADD66A11DF97
-:1527F30048F03B29E5B326B2860EF0BC9145D485F77F014FC4CC
-:152808009D94B9CFBD2E71278EB8E76B047CE95AFD52B180EFB5
-:15281D00A523C603DAECE05C6D76DDEB8BCA82D6E21B83A7B1E3
-:152832000EE3BAE3E9598B355790D3A90E50DC8376C3BC3C0DA3
-:15284700F320137F9B7A45D8E7A957AC9F5754EB7CBF1874E630
-:15285C00A0840FDFF3BDD47E8065B7B5DB6D873607DBF0BEB4B9
-:1528710012DE07DCDFCDC7A57F21E6512B7CCFE358324E77F2F6
-:1528860028C233D982D251C3F7DF87190A4E6B12CF389FE7E720
-:15289B00A9ACD0ABFA10C09D5F5A632C07BEE2D9D81A729EF631
-:1528B00086DE88624C2D896B83B6A5860563751DC84EC99E710C
-:1528C5008AB90441DCFF507F21C646CE65F4A915BE2ED380AECD
-:1528DA00503BA75FFD85357129ED395A24FA79178C75538131D3
-:1528EF00857575597E9F7A2FA5790E09C2D92EBF9F0F73AE6456
-:15290400CA34F0BEBA2258A784928729FD4DDA637F8B730575F3
-:15291900E284E43BC66F911701E083DD6618EAF83B7B864652D2
-:15292E006911EF8436A54773798F325888569CC7E5C91EE6FB92
-:152943004CF0FC83BFCDFD6E02F98F72CE75C37E6AF37A1078EE
-:15295800DD9A1CB1265E933E80B3DFB83724FB4D7F2FFA8D63CC
-:15296D008FF0A200AF468E1997CD51219B788ED6D576B71186B2
-:15298200FA9B6DF9936321F89885D1F07B416B1464E2E3D78499
-:152997004CCC2FAD37FC23AEA02D1B78CC3B2AE2B952364EE849
-:1529AC00E8DF2D262756A15CF81A135C1E2C73B1EE1E386228C5
-:1529C100A073174B3910FB02B9E37E12F8EC575F0199EFA15EF8
-:1529D600900B5F4F9D91BA28F96DCF07C737181B2FC4EF6538A7
-:1529EB00DFA13DE7793E1E984F9837649F7FB9CE211BDD201B4B
-:152A0000D13342365C781796940DCC8343DEF01C07CCEB782D44
-:152A15003B7E086F76B8CBD0FFFD2FEB41C759D5C936AB2AD9BA
-:152A2A0062819EB3400FB202F909FC5E665CEF946A553CC61AE4
-:152A3F002BB00F06FA9BCEF00E1891728C1B8DB5A3DFE6F28C47
-:152A540018B89FA6CB73D6E8833FC0F79712FCAC18DFFF8275A5
-:152A69003B9E0FFB79C54958ABC6F95E981AEBB3300F7275EC6C
-:152A7E0014F7FFCC581C65729EAAF559ABB553168367191B3372
-:152A93004E6BA29E2C8AD38FAFE21FBAC984E723A5B9F8B1A2B3
-:152AA800CF5D3F73FD4F7B4F1B1DC575DD9BD5AC342B0D627676
-:152ABD00D95D495848232C12C9519C5DB1C8922CC242A88FEC13
-:152AD20010654B9D744612F63AB603B19D84B634C7E784C42B00
-:152AE7005889058FF03015F65A266695480E6E209539909014D9
-:152AFC0092A5761C9152B2E1381C9AA4F638716C9AB8B6EC6293
-:152B110087A436DB7BEFCCAC56027F25ED39FDD13367CECCFB72
-:152B2600BEEFDEF7EEBBEFBDFBEEBB95BB86F37317D82FD98F5D
-:152B3B00D9F7D9636C823DC40CB69D6D619BD917D84676275BBC
-:152B5000CF6E6537B33EA6B04FB0B5ECE3EC63ECA3AC9B5DC784
-:152B650056B3556C255BC196C38CB29375B076D6C696B1085B45
-:152B7A00CA5A599885D887D8D5EC83AC059E0FB0AB58333C4D64
-:152B8F00ECFDF0BC8F2D81A7119E2BE1590C4F033C323CF5F4B3
-:152BA400D4C1B3889E5A7AAEA067A1FDD4D0536D3F558527687B
-:152BB9003F81C2E32F7A16143DBE598F77CE235DF2CCBFE4A91D
-:152BCE00BCEC33EF2D1FF16D9F8A777CCADFF5E379C747C0C3D7
-:152BE300535AF6BB963D6099CEB280EC52D7DE1F63F241F46BAC
-:152BF800043FDDFE6F82FF9CFDDF02FF1207FFC863EA9A207EDC
-:152C0D0054D359B7968349B2C4299A242F3E28C5E1CDC06B2E5B
-:152C22003E487602C97E6C13D9BE9365DBCF63FB71E017B7FD26
-:152C3700CA6D3F17F8656CBF0ADBAF04FC303F2893CE264A2C4B
-:152C4C0016B2F342BDE2909D07EA1187ECB4A8371C8234310E91
-:152C6100F768656DE3B751D0BA4A83D9F6A81BE41AF48BD1B952
-:152C7600FFB0EECB70ADC25433F081865161AA83EC1B26DE2674
-:152C8B006CF26DC2C81E0B84554218F81BE8CF9FE850A9EC5CF1
-:152CA000B3E1E0CEC139D62367C3983B4234D1659A8787749C89
-:152CB500F731AC27A509F5237E118792CB8A3F99B5C3813776CE
-:152CCA00C98B0DDDC9E7B8E51F837831E49BD262831740067A12
-:152CDF008B6F8C9B89932BFA975C33FFBAED4FF8CFE6E7A36DBF
-:152CF40009EB3CB7AC4D93FD5BD9D2E720DD4999743D4AED7F28
-:152D09003A37EB82B686F66043EDC03B5D2CE96A37CA609ECA75
-:152D1E00473BD4E9860E5A9F9BFEBE7B19E204DDB8469A857495
-:152D3300226B471D6CA30570018C5613E456A38C5D05B05F65E1
-:152D4800B883D1FEDC65FC24CEF263F2AB06F2DAA6B96B14217A
-:152D5D0059273F6CDFF0BD49E65A79A099941868E571BE2C35E6
-:152D7200A03D4A18CFC35064BBDE42EB5061834908974CB0C425
-:152D87005CD55046B38EE5F353D5AA94688EE0574834B7E23778
-:152D9C008675CD8548A6C6B8D48ED15E6528A425A84FB46B511B
-:152DB100D26D8AA27F3C3FBF1BE2C4C88E24CAD0D659D8B8163F
-:152DC600A573001BAC33B1A18D961E14BBDBBE272065EB48E02C
-:152DDB003AEF7C002A09F397A4AEB3A482FB3DE87E7505BF8CF3
-:152DF000E5B6E8A2CCB7B2D856FD3CD62B27EB96DD5C4B6FAAC7
-:152E0500C52C69A53C213F5A57C2FFD8889EAA49281CD9F31C8E
-:152E1A00310A7A20B11FA4B17EB5F2FD3A2F9F30989E84791408
-:152E2F00BFEC9B377F13F27F328DFEE8D7027EA373FCAAC16F26
-:152E4400688EDFA6150097F47CFA7337BF1006815913E5A7F5FB
-:152E5900BBD99456BBF205B5B7FE99F043EDE7ECB316093A3FF3
-:152E6E00BC287106EF0EA075B3452B4FA97C665C77C1B828CBA6
-:152E8300DF4A33FDBC21A44668AE836B6D4276775B10E7515087
-:152E98000ED3BF615CC1BDA0221ECAD933E1C99B5F6A031880EB
-:152EAD00A64F035CA7744EDBA93EB4EE79ED8AA806ED68A70154
-:152EC200384B5C5CB13A2C6C87F2625B27D9BE52B42D3E2908A7
-:152ED70068EB74DBA8D0FD02F83F306AB9BF6EBBBF3D3A95CFC1
-:152EEC00073217E75CF311FB693AE99AD2116F77B3AC96F85E05
-:152F010069EB97BF5CDA8AFA10A3B9879485A71F504A4E3DA5BB
-:152F16005EC7CE8417668FA964672DA4DB76067354D780F4F77E
-:152F2B00EAF95B9E3616724F42F81943481C68C3392CE63D7D7E
-:152F4000CB295DC894B61EBAA77419CA26C447A4B18349570694
-:152F5500E87C58C7BAFC61EF6024781CF2967EAD617D24843B52
-:152F6A00F6F8A4807B23D2B68312C1FFC383CF431F2C978753B1
-:152F7F0068DBBA4C1E4CEC4A680AD7A3411FFDA98E3657E38FD5
-:152F940031769F80FB095A6ABAE13503E2EE78496E591683F8DE
-:152FA9009BE3AB5B518EA1BE251DD0F9CC578047BA5BE3D9FD8E
-:152FBE00AD4C3FAC4F63DB8370EC3F6BC19FCF1C80F63348B612
-:152FD300299A6CDB31D4D7F461B20BDF44FD0C64DBCC30F4B3E3
-:152FE80084C6036D25A645F02B30AD15BFB85F266476431E596D
-:152FFD00B2C55A9D49EA9C00380A65C9862AB643EC1FFBA6308D
-:153012006CDC88A1CC9D491A572534F2CF803FBA512E9C6ED029
-:153027007431CEB77A4176C47E32DD306E2C0C66FA8F5E742F22
-:15303C00035C1A536FE40509E0E98232CE60BF0AA5B52CF0E088
-:153051002EC89765F6184F15CEF7A47411301002E09E1FD42243
-:153066004C3F9EA67929F0B3EDD153CAE9DB4B5BD36C504927FD
-:15307B00762B171BF965E9E8B052951C51776DD5945D1D6749C3
-:15309000B694CCFBD39D4BEAAEA13DA3506212D762BD8B92B8B7
-:1530A50027A8D766A84ED69AB680F67513B466DDCEA32CFDBCA3
-:1530BA00CE75A38EE113C6AEACA6E07AA190D903E9B6219E69A5
-:1530CF006FAFDABCDFA8351F369A0037B550D75C298805108ECA
-:1530E400FDB349DE46B63C280F49439B4E42B57C9F4E36F7D6B9
-:1530F900691AA4D39137F0F1437AC4FC1EC4DD66A00D4E616AB7
-:15310E008F8A79BA4E4E908E5AEC71C66A70BF3F74846C05F0F8
-:153123003D432AD469D4D5B3534D95B1D9FD23876BFB29ED8BE7
-:15313800FFC6FFF0618EE8427B1E7EF311D203A45B7670CD1FF4
-:15314D00FD5892F4B5B0CED6FE478AF63F8CEC88526D0EA543D0
-:15316200E6231969A5A60AD76B6AC91A4DE565CD1005DCD3DEE3
-:15317700A3354577B7E1B9B1C000B41F98B75627D07DD808DA47
-:15318C006E3CD36EF1FDDD86DF145BD18FEC8D16F643D2B4E610
-:1531A100EF42DCE446F446A28375C69963FB34D4CBB6CE365B69
-:1531B6007720FC02F2E2D6A0CE5E86E8C7A50EA8C14583C60317
-:1531CB0051EB5C2CAE9DBB7A2CDBCB3716D921E03EAA912D62AA
-:1531E0000969AB7FED20D93284FAE33A346F022FCB9D277C7B31
-:1531F5004DBE57A4B9439AF6195CA46B6ADDB101F35C03ED4235
-:15320A0021BC9CF945ADC95C102EE6F1C8DB918EC4DF0BBC1DC8
-:15321F00F8FC86D25EBFF9BA4176DBFE11DBE190B1E5CD7CA012
-:15323400E54DECBB162D10D77E73A7EED246546FA7B5D7EF02FD
-:153249001E81F7CB886C64A9086D65211B09231DB5A236AA591F
-:15325E00F4D2D3A4F375AE9FDA18D00FDD3CB3F45F5336DD9182
-:15327300CE9806DD48D7B934251AD8F478271CBF5B5AFD4FD299
-:15328800A29C6891B6F7796668F28EB4281A6B1D3AE8DF477B45
-:15329D005995A1629AF8E2EF0F93DDEDD8C0E4857BDEDF26C538
-:1532B200CB605C1DD0D1B636F2AECD5F2C6D9DFA2F871F59FCB0
-:1532C700A31A68E65BA4191CF04DA421D6D5DAF3B1CAC0F230DC
-:1532DC00EFC2B9A882BC64D1A5A688269B099E94657705C27175
-:1532F1005F5132771A9C9CA4F6846EA5C8BE40A4287DE4930561
-:153306007D5FD2134EB309D2DB6C42DA0F4C28A2EC26DE1C225F
-:15331B003D404DAF895ABCA8D00FA1CEDC061C8FE17BFD29C2BE
-:1533300001F45B7FEA0F567DCD39D76CA18DFBEA60AABF06645E
-:153345000199650E8658F660949907AB7F9BF7C07712DC93E0AA
-:15335A003FD96DA77FABF8CAB9D9F1ABEDF838AEEF7FBDA84C2E
-:15336F00D4C780F947715AB2CF45771668FAC57BF8655DB87E3E
-:153384002E1F4DDC37754C2985E9062F8FA4D04E49B9FC448ADD
-:15339900EC86D37E5096CE544AF22198B72475D15CD27AE3FDB6
-:1533AE00790FE2417B30EF999B67316CA4770869BBE407F5F373
-:1533C300CF6A2023E96403C56A877F6750DBB56CAD4CEF0279DE
-:1533D800B115E4A2F7D236A79F1DD193AE94CEF6F1BDD3CF6A0E
-:1533ED0046D29536BAE45DC6EB17B17F24ECB9C980F11CCA42CA
-:15340200407FDC5F95A18C629C5C787A363E717FD796672D5DEB
-:15341700687D8F8EB23307FD0BEB086E63F5DF82BC188A914D54
-:15342C0074279FEC8F67F2697C2D2FD4E2D9A16035C8F103FAC1
-:153441004928F36E16D798194AE3BA986836E9A5C7C3EAB7121E
-:15345600CDE1C1F6F659B26519C375E276EAF765DCADC067AE49
-:15346B00D765339666D22B862034A8B8D66CC9958BDBCA61EE8B
-:15348000E2AA53A80CB4878769DC0361B5321A8E944399FBEB54
-:15349500AF6DAB3565181B9BF46A33A47362A73AF895B0E6CE17
-:1534AA00C23C31D76E387788A0EE07B374D041DE6C0CF3B8563E
-:1534BF001DFBD424D36F191552B87FF857F43557B896CDACFF5A
-:1534D40057DB7A174D363F0B013F6B5750AEF7C95C88E62A504F
-:1534E9000FDEB11D937B64B226BB47ADB1EF6FF0C3388DE3317F
-:1534FE00CB7DC7F072CFA9AD0D95D7B0BAA97EC6CE6912FB759A
-:153513009B9F7B59DD29BB5B51560C01AFACE526D440F048BF54
-:1535280010FDF5D25AF8BA4EED26BBF4C827AB56A26EC011FBD2
-:15353D00BEA1843605E3BE2F7158F5D682DC52B0CFFCCE6F157A
-:15355200C8E6F84DAF288BF8E2653067F98ECECC470E8E83CCE6
-:15356700556BDEAF23EFC276817BD85E18AF9FAA19591A05598C
-:15357C0007C7A14FB875926FFEE9412DECC8346FBC997F4B99EA
-:1535910026FDFBFC5BCA34ED6F25D3C45ED04CE77C39F21CC0B6
-:1535A60095D0707B5B39E93423DE8EB5F98FFF07E47F4C5B0B28
-:1535BB00B87BA05D776C76109E828943053C05CD2561E11CEEF2
-:1535D000296D99E44F1C437E1D5C68CE0B835BF79901FA969B53
-:1535E5008BE8AB035FBF5CFD619C8DB8BA5F564F5EC80B880779
-:1535FA00AC6B8B5D7766D7BDF63275C734E90BEFBDFE8B80EE1D
-:15360F00D5C85763BBD2B1D7E7CC6FA08E747744113D5B8AE3A5
-:15362400C476EB37B0B47623C8F0CF3F35B254968F4F0297D654
-:153639007C1C8CB7D219C36FB74B1EF505A49F1B77B3B39A97FE
-:15364E007B91EE4FB862E5CB6A28FBBDC8151D163EAF602F502E
-:15366300DBC3FE7A05CE67426709A7D8E6703D17D784EB4C771E
-:15367800AB13A7EAF8D305BC57415A491E48272A92BD18F72EE4
-:15368D005CB28D1D4AA32E4AC9D4310C1B759D3CA6EA799847E0
-:1536A2004178937C7B1B7E119EF32BCA966DBAF91990177FAEFD
-:1536B7000BF263A32DF2BF1AD5E7ED3AC6862645D437CBACD512
-:1536CC00AC7F9C4B0D4D9E5B61A53F0278F3DB795D58B1BEED6D
-:1536E1006AF6F5569A0B15C5C5B49847713AB4F7BEE5DE334AFE
-:1536F60048FECBA5E88FE32588D21FC7FF0771CC8C0D65503E7B
-:15370B00C5B4E5A8630FB8C4F361B5BBBE4A785D28838C60E796
-:153720005F39EBBF2AECB2FED3E5F2FC307C7557A525B763FE8C
-:15373500AE8777A83437FA21F00A90BB8CE8238A144DAAD5302F
-:15374A0096D079BD7761A31F5F1863525C6AAD8AFB984CDA4A08
-:15375F00E3901480F1C41E87684CC2B0F7301E3963913D2E5D94
-:15377400763CC2B108C7A408D9F4288C291A3B618D29563932C9
-:15378900AB965F3116A06C01E394206F37BA5FCD0BE5192D5589
-:15379E000E7047A2C956677E580DE31AC6697AD5A1F7A05EDB5A
-:1537B3006ACD2B733FA0701DC343801F4CCF32CFE97417484EF5
-:1537C8008379654A2BCD24133E2847CA1C4A639F2B318F699847
-:1537DD0027B6356C734DF2B3A3D8A6CEBEE1C86B36CC00EBA1A5
-:1537F2005D5F813E3CA0D37959B439FA5D6B5CDDF3CA4CFFF2E4
-:1538070006ADF32F82BD5F3659C53C208B7AF62DB0DC719E794D
-:15381C0036BB98670A5E4BCE6EB27993A523E2C6BB03FCCE58AA
-:1538310098D136039EFCC73BD45520CFBA07C6D491DC98522753
-:15384600BB3B17CA1FFC30AE9D511AA9592D9C178D3540BBE016
-:15385B0086F87883EE96701D8E1B7A716F73849D1FD0CC1378F1
-:15387000B9D15C797276F9AB12CD4BFFA4722ED1BF09F53756D0
-:15388500B10A495AACA2BE2DEE75476A58855BFA06E9475E9528
-:15389A0079B30B75A7825F0AA3AC4B3A51645F00CFE5423CA71A
-:1538AF003CF4EF02F78CCD6E9AEB94E3BEF81341B47DD3D4FF48
-:1538C4004610F36D253D9F5C35AB10E363C05797A8EF93B98E87
-:1538D90052482FC61B8C0BE0CF7F6940B7F412F921679DC02DFA
-:1538EE006D517F0161685F6F04E340BD704F4F46DD29F0E3E3FC
-:1539030063C651F487FF17618E7ED64E877B5BCF813F7EC78161
-:15391800C6783EF0A8CB3A53398234F74FA31D4656B60FEDE209
-:15392D00BDAC49A71F5450AFB51AE737D2214D100FA83D40DB6E
-:153942000532DF5B66EE21BB48B5C00B8326C61FDEC26D1FA1AC
-:15395700FBE170AE7355A66BA9245A672FD0F6C97CCA736254CD
-:15396C0080388215C75F9DE19772FB2E4DCB6265A4EFAA03DE24
-:153981002201EB4C23EAB7A0DD41DCCF37C18F49C9C2FE1A2F08
-:153996009F37EE02BAF1801711FA66BCCABEA3720E7D437141CA
-:1539AB008B9B3F3CC83F3DA0BEE177F2AD2DE49BB2F38DDBB65E
-:1539C000677700AF385A86B695E47E964B18B4FE2E4534AEAEF2
-:1539D500BD9F379B0CC1443FA095D94EE5579BD306CA4392991B
-:1539EA00813CE3FDB82EB9A3668342BCAA6E637FAD8967CCCFD0
-:1539FF00F6F3F2678DA341AB7D34429A263337DA02E923905F61
-:153A1400D702E609417A0BB63F4B236C68A77415CAA076FB725B
-:153A2900D545FBA3E6EF8C1D3531254A792AFD317043FC83ABCF
-:153A3E00E11B87BC4B614E70A3B9D7889A0FA4BB4D7D34065FA4
-:153A5300DCD38BC17F16C215282BE7B36DF1B20CE1009015D890
-:153A6800519351FACD8C711BE41B07D8FCD85E01572DF015E0BB
-:153A7D008B362E6508AF85FFD590871FBE8D3077DB00FFE716D1
-:153A920060DB065C815F37F8F1C06F9E02BF50D0A2477C8E4D94
-:153AA7005FF7D30915DA5D854FE6979714D18B4378E47103D74A
-:153ABC00A042F2B826E0FFE5F4E5E83C48448BB958C5D5995BCC
-:153AD10022D86F4A3B642D4B3A81CD7A359E6991068C52DA2366
-:153AE600E6869C3C3250667D7A8CCE0570350975C67E4B14E2A1
-:153AFB00453406F90D215EFC4D05DEA69CC231AD5945BBE28BDE
-:153B1000E5DEA56CD32B8353CF32E6E4C3360D68999FD8FB05AF
-:153B25009BC63413FE51074328C0D3A12FC47105C39EB5F48CEF
-:153B3A005B1CFE047ED99FA0AEDEB2E502C00A3207C1EDD09B26
-:153B4F00492097DBE9826CF972B6A983F277F46D310DE45551D0
-:153B6400C9BA280CF32A0B5E8A2FECDF7E6E461F5EC2BB96FCCD
-:153B7900FB0A75ECFA31D6F1807A030C0DD29726F4F88F11604E
-:153B8E00B44D64ADF7EBE0CEC03B096F16DE1CBC26BCD3787B99
-:153BA300758E0CAD3119DE50CE8ACB360D5A75B574E6C9CD7E81
-:153BB80039DB2DCF7147E7B8E373DC8939EECC1C77768EDB9CD5
-:153BCD00E366BF9A53FEAF8A74FA013FDDDC6CFB0393483BFFD1
-:153BE20064C16E531CEA161838AC56D2D9503B1F9873E3DCFA61
-:153BF70086F8BA48E0D8849ECE219D66F03605EEB3F09E83F799
-:153C0C0002BC02D0A71ADE2678DBE1ED86578177C34FACB8ECF6
-:153C2100D004E12DE3D01FDC8837BDC88D784B14B9116F1B8B77
-:153C3600DC88B778911BF1162B7223DEA2456EC45BA8C88D78AC
-:153C4B00938BCBFFD58C5D442A1FDC818E8C816D1BF54BF97BFD
-:153C6000D65DEB9C6B279C5DCE3E03E0576445F89D1BE74F0C29
-:153C750047DE7314E417908DF427E6310FEA1AC29CBA33CD31E8
-:153C8A008F00FFC0673A451823CBE545D73C05E3622DFC231DFB
-:153C9F0079699B7A971778D67C5671076BEC8CCEB778DA4DF0DC
-:153CB4001F996FF1B23AD6B8DCD11B91D1CE2F8CF93AE48138E6
-:153CC9009BAE84F11BD29FAB44D9E1D1193B0A20EF9DA91F80D0
-:153CDE0071793FCA08FAF40AF7F227208EECBDFCF8E48C73B8E8
-:153CF3009789E311A0D1531C4F8472B7DA67BC41DE597E16F2D1
-:153D0800F290FC3E9B8FD502BC9B251C0F51BED8AEEF88E3B99A
-:153D1D009E47F52DD1FD547FCF87DCBD92DCAC23CF6F03B4794F
-:153D320057EEC6B5306DE33C5CCF1FD399FEA81E80B97B271B90
-:153D4700A4F8839E0985AB6987B175CCC07B8078905BC9B66F83
-:153D5C006C587B6A3E8E637ABFE44D511E47459021218D203F57
-:153D7100AAF330167B2A715D6ECC401B0688E746C9923F10D617
-:153D86009C385BBEDB378F553C01F965E6E138D3A827696C6ACA
-:153D9B00A2B109CF137235213A9F7EF662DE539E18E874C79ABA
-:153DB00054596ED05F5CC12DBF0BD24CCDB76422070F3E5B5772
-:153DC5006B66FD43D6A7A7914F6D25BB6B98BF74FA030A9ED3D9
-:153DDA0040987DD1B1A53CC82A3CE4390D79F6824C85E7407863
-:153DEF00D265A57138407607A62D9BA17C7CC21065EBFED03C4A
-:153E0400E9413FAA0580E7F3F26306C6AF043E4AF7A59780FC2C
-:153E19008C770C16DDDF721EF2F8511CDA5E1C6D16587691BFD7
-:153E2E00CBC63A4570E33883B88C9633CFEBD0665F65039D0EF2
-:153E4300EC164EF6116FC23CE8CC045BD2E9C07D1EE046FD401A
-:153E5800A04305DAF9C0B6C1A3DED985BCC7B1FB5D5CA7605144
-:153E6D009D9CF106EB45FBBCC0EF102E777618E039AA511DA462
-:153E8200319C7340BDB7CFD89D8D0F68231EE6B9016075D27CEB
-:153E9700383AD8897BD4FF7CE0E7FB45B9C50890AEA70A7D760A
-:153EAC00B5E1C0CECBFB691E86FF38C64B368ED6D8703A7A6FBD
-:153EC100362E03B8BFD60261BE38BFDC5F32D337244FA36ADD4C
-:153ED600E39AA6F28CE3E3CB5924827BD6796BEF219FFFF2F1E0
-:153EEB0008F82575BC5BC09BBB57F59EBE56918EAF54EB645735
-:153F000017E9B4E6B6A30E89C7533C6EDA70B6B225342E4F0ACC
-:153F1500CCF334D4F167D0F6D8A6AF525E185F405E1F19A77B66
-:153F2A000BE8FC47570B9D7B00395CFF6662AC13CF44207E1FE7
-:153F3F00887374AF9C8D779FCF747756A1BC6E1ED3CFDFFC9DFD
-:153F5400E53F0337D69937272EDFDE0047567BB3DA8F681ED6B2
-:153F6900779BEEDE60D7049587FDCCA2A74C3875F835DFB5043E
-:153F7E00F729315CAFCB8E459CFAC6B8D9ED12F5122EC6B94E46
-:153F930084DBC1DB4BD971E201621C78825DCECF208F775BA70C
-:153FA8003AD3BD3C543EBB2D76BF9EF7AC063A8AF1A2BAC88FA0
-:153FBD00E9A87F56A80BCC61ACFA3715EA8270F05D1FA4BA1001
-:153FD2009EE2636F8927B7D4A8DAEB1E79ACAF707C17E9FAE127
-:153FE700DC688FCBE6138003E0E99E82CDF1DC8076F2BF1C7DE8
-:153FFC00CB16AA13EACF3A696F837448EF34A429E63377BF6960
-:15401100B55751DEAFCBF171ED73D18930968D6D51DA7CD43A54
-:1540260057969B80F9C2A041F6E1A72D5EEEF415DE3C60489E81
-:15403B0009D50B3CF77E985B8926F215CDAEFF9199FA43BBA8E9
-:15405000EA3A46F5AF02BAD9F42D8C21E5C8EFA83F68AA6507E9
-:15406500DCEA0F17D1164AE4D0ACFEF09BEC21B28F82386BBD10
-:15407A00C53AEF8DE53CCC863BA12D5BFDA46BD06AC700EB5097
-:15408F0002CF30EBFDBBC9B6F9B139F4D62D7AD71F5D6E805B09
-:1540A4008C8F17D1F5908E6966E83A6ED72B45F5429EE3ED1A8C
-:1540B900A63A2DCCF0CBB1ED3BB42CB45FF0E333686B3FA90FC2
-:1540CE0041FFB3ECEC5BF5F802B44FA72DFAD8D1CE4A281F618E
-:1540E300B900B02C84B677A86C76DB3BF99FD0EEE422F8E200AC
-:1540F8005FBC083ED981CFE24B84CFAE4182AF982F4C4F5B7B51
-:15410D00C8F8E5E3D69DB37A34B9B1B268CC49FCDE694B85B9DC
-:15412200AB8F454608B768CB223D9DAF28B43D906D7E81BADD7A
-:154137005FE5AF95E2D6FCDB17DDAF3E0969020D7CAFF7745A0A
-:15414C007171CCBB00C3728774E97446E1610E7E10609570CC13
-:1541610081F683EB92828072A7A6058347FA65909112F78EF437
-:154176006E41FFD4EF90876F114E1EA37DF073F5C3CB58EEA8CC
-:15418B006E84B85ECCA72E398C36C1FC5578BF10F827613ECE96
-:1541A000A4618387FC708F93DC502E4F7B2AC306A5C3B2F461E7
-:1541B500D4175D5097E13B07AC345B1230A7C77511618DA6D2CC
-:1541CA00FDBCA87364CFE91156CC7F6BB7A694F49C5713F9BC33
-:1541DF006FE4239A8275E6214D5DF2C03A841FC74E840561C3C2
-:1541F4003D8476802170FA88521587BA9EF88AEA631AF0F08C51
-:15420900F22D1C17EC3CD1FE3CC8C03E4CE7D47D08F24FED3C5F
-:15421E004CF7FE627BA1B8B1435B84EDBF534D840DEA8475C1C0
-:154233007B41912E8807A61FD3109F6DA83600E10E2ECE16F0E9
-:15424800609555C003AEBFE62C3C04BFCF77A67A70AF79421B7B
-:15425D0000FF11EC2F8013F4C3B50D1C832D788F010E0E289865
-:154272007F49CF6BEA66C2C301C50BF5431C48782E05F74EF013
-:15428700CE0D280B6DDA86A0FCBAE0B97EC75EAD65DF04E6FFDB
-:15429C00AF30B6A326A5BCCACE698B42ECD38D32FF61C79E62DB
-:1542B100EE9364AF96ECCE74D31AC19251EB6C608AD245CD6D7D
-:1542C6001AB46D0F7C711FCDC8BD36D3CEF13C18AE55611B6D33
-:1542DB00C1B934EA1E86DA35F61AE9B58DC2989B4D34B97B3965
-:1542F00021A2F289B0BA0760AD5726F19E385D977777D1FC14F6
-:15430500E248C03B44F9639D82FCD94E49FEC4723E26E3789DC3
-:15431A007D0EE461FCF6E35C2AF628D9BC0D74C886953FCA8CB7
-:15432F0063D91084B540FA2648DF08E9D1AF56FE44A79307B46F
-:15434400A74E11C205087F6EC567293F91E666AF6C71E26CC493
-:154359007200267FC7B495B76EC18D388A60DF00385BE467BB1B
-:15436E00F88E901183705C2FE882F934970AAB5202F7D2ACF8F1
-:15438300981FB481000FF9603CD2E77E0DCF015AF769601F6EDA
-:1543980067F6FC1ADBBC346E97B3AF1F6D3254D3D97DCB0FE76F
-:1543AD004CE8876D2260E9B05F325FE2388B9E057FC8BFD6990B
-:1543C200FF901E1F944F7704650CF3B54BE75CD6D9C17D3A8668
-:1543D70021FF015E6B95057102B9AFA9FED35F53505EF5771D0F
-:1543EC00B2EEE580303FCEFDD9611CDFB58FBF50C26AB387DBB4
-:1544010036C2B827DAF30C4B67D09273D066BC9038B0B40A64E3
-:154416004F3FE61BDA67C151E0932982CF1F4D46C83E04B8311D
-:15442B00CFEAE8785B6D519E85B90BF05C4A6FF3CFDFD8ED19DF
-:15444000EB81733B80CDF71CADE934CEA4293E8F48F76DDFA789
-:15445500FDF632E9F6CF4907ED5DBFDC7A52D4DCABFDFB65D2F4
-:15446A00DFF52ED2BF7C997491778477AF76EE32E9DE60EF5C67
-:15447F00DEF49B73F6D3707DA7B8FD01ADA65F9BBDBE31373CC9
-:15449400F1FADB874FBF53F8FF76FE73C2C5E2F6FF76EB03FFC6
-:1544A9001FFE47854B45F8F7CDE54BFF67E0B7DB47ECBDA5C765
-:1544BE00FEB580974916FB24D9B869EA1F94E2B7AD82AE287AF2
-:1544D3006F573508C7BB56C5EBB6AB74D607656EEF0675DEEA92
-:1544E800EDAA2CDFA9CDBB6E40F5F7688AC835A8FECA063509AF
-:1544FD00728BDDA7D75D80B159F236A998DF1F9BD7DEEB35652F
-:154512001275FF7A70EE12D7502389974B7A3F073C392036A83C
-:15452700E53D2DEAC3D7372BF53DCD4A50BC4D1D2CF98082F66E
-:15453C002017F17167AEE2C7F83C77A54A6B0FAB078877200F1F
-:15455100A9AF4C2AA8DFE584FB28BC59757B1324DFD5DF9450C1
-:15456600697FC9BE2F7C2E0CAB6C182A0086BD0043A0A87C2C1D
-:15457B00B70E60C078942FE45F5CF6053BDFE9A27CF3F967F20B
-:15459000229E150FB3DEB578473AE49D28896B888F3CB3F2BAA4
-:1545A5009AB10555801B11CAF4AC69061C35288BC416B5F6430B
-:1545BA007CAF9B0DF4D57F9EEFDD3B3F4934C0759110C0817BDE
-:1545CF00705791DD9019D81126929358E21EAA1BC074D286E933
-:1545E40028D65DBC51ADDFB956E52A1DD8F2171DD83A01B66A62
-:1545F900B181FC1320203AF4F254B6A822C1B45D595499547755
-:15460E006DDD51680B88E73FE4F3360C8CEA893695ACFDE3E983
-:154623007BB0DC9C0D075793C2BBA784F99A05837767A3EA852E
-:15463800F2B06EBDB62E3F2ABD115ECA66F0520F6DA7624D974C
-:15464D001AE889103CDB4AB62BE580970A31A996B264DF0EBB47
-:154662006D2EA6BACF947B0ECAD221CC0BF802BAFB1C1890F65F
-:15467700F5DD372A280BD5F7DCA8CCA53F74226F39ED1BCCF4C2
-:15468C00A7FAA93D148F3BD5A2066E8AAB3CBB539D07711FE630
-:1546A10058D06DFF1BF05FD10370427BA9A88CA8DAE31DCADEFE
-:1546B600131D4AC5A9356A4003BF9DAB55ED233740DBBF41C1A6
-:1546CB003610009CD6AFB170C1C7B95E996DA0B60D729ADFCD92
-:1546E000DDA28AF112BCF7C4EFC1BD9ABAEEFE79DCADAAC8AF72
-:1546F50052C59550DE7577A8E2EA1BD4E192554A04D70156CE75
-:15470A00C42F0B5AE766287E326CC57FF233AAF844873ABC35B0
-:15471F00ACB861DCF53E7E9B52FFA1925EB48D2C24C27D9E6CDC
-:1547340047DFFD684F4A0BABF5A76E51B9931DAA067139618691
-:15474900169BB08F07E99CCD3AB4A5220C40BAE31D7D34D76B64
-:15475E0067BDA5DE505F99B7BDAF3EB556D906BC4106FF21F8F1
-:154773007E1A79CE4FD6ABE250878A72B52CDF8AB29D20263FAF
-:15478800A3726BEE5429ECC90E080FABC38033A43FB6719C93FD
-:15479D0094FF03D75B7F0A70A80DA881539F512B4E6EA736B0B1
-:1547B2000BDAC03CA07D7954EB2BE64B4877A41DE928DB34C57B
-:1547C70036791DC0D28BF0039EF16EBF1EF84F96DCA5CC837208
-:1547DC0010FEC1ADD6FFAA8BF900F225C78D71616C58B7278FDB
-:1547F1006B3856DB36606A85F843BE0773AE054EBBBA1BE290E4
-:154806003E39C070D71CFD4AEFE3B54AFDC96AC06DB57AB97630
-:15481B00F4129B6947BF64563B421A94433B0A8A77115E1EB6C7
-:15483000DB12B6A380067E73DAD2F6C49FAF2F0F6E00FAC4FB9D
-:15484500B7B35BD7CF0BC6FA39F10ED57157446F5D8F749A376F
-:15485A00B0B68F9DE8ED73BEF52FBBE87E9DF2C4DABE8A6C6F1C
-:15486F001FE7019A5FD9A0B9810E1781F688BFAB8916AEDE0ABE
-:154884006D0BD0E10EA0C30EE2E9C5B428B16991B4EEF5F17365
-:15489900C29550766CDD14D105DB4D6CDDD13974019AF86EB218
-:1548AE00E9027CD7B7B6882EEF2BA2CBABA43339D3B7B742BF10
-:1548C3001E29A213D987863680FE9B6D5A9D063A39B4D9F01E37
-:1548D800E971A6881E3FB2E9817D3A60D3E2123A006D8A695101
-:1548ED0016FDD4FAD2E8DAF5EC6ED62B663FD5374FDAD057C62A
-:15490200FE7A7D79E26FFAC4ECADE4AEFF3CF5579FC8C01DBD70
-:1549170093F0CE6F6ED05CC07B2F96C5B47207EFD04F2BC4AD95
-:15492C00C0FFFE42AD5873EF2CBC975F0EEFA9C548F322BCC7E7
-:1549410009EF4E7D8BF10F3CDF779D8D7F5C13C17EE2E0DF5732
-:15495600847F17AD6D58F81DB1F15B897C0AC2F0DEF0E23EE01F
-:15496B00A47F89C6058B66988EECD3DB74B0701E9905CB97015C
-:15498000CF6286EB7D12BE49E03DA59007DE9FBCF763B7A9F5A9
-:154995003D5D8A54B254292BB956C1362C02EF61273AFAF6FE68
-:1549AA000B849D5AA3F84A3EA2784A3E6A8571ABFAD8F537F4B0
-:1549BF006D8BBB7A11AEC5F69DF2D046BCA5B28BC648F4477B35
-:1549D40018CE1C05CB47BB9125CED86D8F1F180F75A511AEE79C
-:1549E900F3793FC429F4FD27A1EFE3D87506A693B85E82F2017F
-:1549FE008C75FE27ECF8DF82FFFA9779FCFA8E505E2975976B5E
-:154A1300FC36D4D3629C7597298C2C795F74FC768369A4F38504
-:104A2800FEFE99F5D6F2FF06E2E5D1A4A89C0000A7
-:00000001FF
diff --git a/drivers/atm/sba200e_ecd.data b/drivers/atm/sba200e_ecd.data
deleted file mode 100644
index d097e743b84..00000000000
--- a/drivers/atm/sba200e_ecd.data
+++ /dev/null
@@ -1,928 +0,0 @@
-:150000001F8B0808AC5A10380203736261323030655F65636426
-:150015002E62696E327D00DC3A0D6C14D7996FD7B3F5AE71CCD4
-:15002A0078592F3F8DD70F0AA949E8DD022E07F61A1644AA40C3
-:15003F00012D88A433EE52268844E8924B571792229D1B0F8EB1
-:15005400013B7DD0C7608813E1640D5E58529C6C909D101DE4AC
-:1500690016357749A4E4BA8A7227541DC9AA17295C4A2F76455E
-:15007E00259438EC7DDF9B19EF7831C4A1524F772B8DDF9BF742
-:15009300BEF7FDBFEFFBDE1B3FFCD3BF7F88B808896E2484FED3
-:1500A8008890844A880EFD1CB4BBA00DB710128396439B8076CC
-:1500BD0018DA4E68B51FC3036D16DA1DB8364E88026DE92FBA6D
-:1500D2001EFE486452BF7C63D90D63AE825E0863FB54E1A984C2
-:1500E700782F999F6AB59F9E3C49B19D522690D8ED9FFB737D9F
-:1500FC00FCD38F45DB66F353D2B6AD1433AEF2F2F209D77F491D
-:15011100BE34E18787275C3FF52678EDF13693B20B7EE47FE17D
-:15012600E71A20BB45FB4AA95D5E29DC72DD983C8589E52B4C68
-:15013B00927E7959B9A987A7DA6E4DCF24842D778E97CC7F63BA
-:15015000F90B6D6DE8BEAEEBF97C299D49C95956A43F7A5BF4D5
-:150165005F7C512AA1FBB7D87EF4AFBF99905E79919E97FCDF83
-:15017A00FFB93C759E5BCDF3F48DEFDA29E89C2A8EA109DC0E0B
-:15018F005FF8FFFE2B387E24ACB3FC6765A432BB6F911CF4C674
-:1501A400C1977CFA72F2308031121A8EE3BC3E026FE14E96FF67
-:1501B900025AF9AA21793BD46B5B3B1A708EC8A429FF1CF1557A
-:1501CE003E4F7C81FDC4977802FA5DC447C2618EEBEA932EC057
-:1501E3004BB79000C012130F873C52EDEA50657DA14AB86BAFA6
-:1501F80014D4B75C5C467C1D4F126F20B8231E269759EF9EFE32
-:15020D009D846F61249CE1FA03844C0B6A716FD52F20EB9C6518
-:1502220035C1447C7AEB6916F59268404FA9249C341086C4F6C2
-:15023700182477ACC79FE300570FFC87E3FBC3A4657AEB6A1692
-:15024C0085F4D4BE7FB34AE4F5AC7D7DB3FA3C213546D2DD045F
-:150261007C32C81F7230EF6A9E22B7A8B81EE7116EDFCCCB8A9D
-:1502760067E549751FF5B490DC6C5641483010844C26EF66BEA1
-:15028B006067FCC3B9C4E721F3D53DC3EE1669F72655BAB04CF6
-:1502A00095B6AC654B008EF03EFD6EBA6531EA08F113F958A63E
-:1502B500F8F4EB015853B966BE7AB950A8FEB04D8DB4FF933BA0
-:1502CA00021254BC2478DA75DB3C456FC2D306E429775C5F2546
-:1502DF0078A202FFB7626115F9D9AB95B5608BFC601B04DD5402
-:1502F4000575C0F90BA1C39DD5640A91FBF4DC8A2D0DE780D715
-:150309001DC0AB3D1FAB26E3C3487898BD07DA0F053964FC6180
-:15031E00B09F6E2C85F4EFDDC054B2B33F93978886ED30B49447
-:15033300768879E085CA723BCEF75CC37918AB1763BB718C8F81
-:15034800E218973A503F887F41CB78FCF545FC0256ACB3E8DA10
-:15035D0034052D8BEE84341DF8D924F1874DFC62BDC065D1B458
-:1503720069396575E2BF52823F5CC47F03AE9BF17F2BFD283F5C
-:15038700BE7DFE1BC41863C362AC4325B1FE8C3D3EF66ED31296
-:15039C00F6BE39FF0257281DAF69ED17F8883C2F83386A5A1923
-:1503B1001BB5E418C30B73E3E48AF573539E9BF37F2BFCD76E07
-:1503C600827FCCEEB1FE1E1B7F838D9FA45929AE521C387FCD8B
-:1503DB00E143B62C02A73CD433A10CE3F647A7B91FAAFA55D204
-:1503F00030CFB4AD06B685FE0DBED990327DD38903EC5BB9A572
-:15040500685F6F5587E09B3474B0AC44A2105B784D2CAD1ECE76
-:15041A00B85B80BE512D77A9570A85A0D33FD6FD99EB3BC4FAF6
-:15042F00CE09D78FAD053C57715DCCE12B18A2352F4BE4DF3E26
-:15044400A3E73F3562F9670D7FEEAC3AFD034D21B14BAC4EB966
-:15045900475D4C7FC5F6DC3B9020F2BF81EF26793FC4F5605035
-:15046E0089631EE0D00FC49222DEE3788D3E00FDB481E324B744
-:15048300A8470EEE8A93DC7B10B366C4F7CDDCA178E9E3ACFDEA
-:15049800FD956A27C4B7F6F7D7837DE688787987152FBF0532CD
-:1504AD00C87598AB92BC1BCF26E134E7D056692EE07F3ED0CF67
-:1504C20033CC96D2CAB56AA12CCB24D72A55EADDC8BAC949C5A3
-:1504D700A50DB0EEB2E30AC28C421A3D4C5E56C05E0CAB886E6F
-:1504EC00F23A8C67712DF4FF45113C02DE68FE6D03E4309096C9
-:15050100DB45AABB203749D1BBD5BB80A7629CBF17F86C6701DD
-:15051600E06D6788F8BC40FB933677C4BBE135950CFEDCC09CF9
-:15052B0087FC728B5FC455F5515EED2E3BA9A05ED65592181934
-:150540001C30B244C0E918E7BB519E705AC4FC2A42FC2496D294
-:1505550047B7F635873457A377C309F0B30106F089DD3F9C0F86
-:15056A00364FF16B85424D9DF26B359AFF9457B94EA8B1FCDB9D
-:15057F009C84327177E57915E18379C83D202BD2385A0672CBE6
-:1505940003461053742C63CEC97F32C0F601EF8697D559078ED5
-:1505A900C3BE4D097EC0EE19B0BBD8136BE99A8829F3A21ECFAA
-:1505BE00CAE3AAB013E634CB4601878D1EADB5725A02721ADA1A
-:1505D30000748276C8A27FA15F800E9016D959D40FEAE5975DB2
-:1505E800DF079D844D9D583CD83A09002E874EAA854E56AC5F7D
-:1505FD002CF0900C0BB60AF9C00FF764AC07F676126B984CB013
-:1506120055E82BFA3CD80FD619159837071F671F423DF547CC48
-:150627009D9ABBB94EF94FD5EDFED9920D9ABB2948DDCDE3ED05
-:15063C007B3FE4F1ACE201DD96CA8CF2A1DC1EB2006AA3679877
-:150651000CB2CABD9BD88E3B896FAFB6B1C9BBE105F0796ED6EE
-:1506660014E1A5ACB002FD803221E3D52B26CFBC5F7F80DEBF28
-:15067B00988492F15AB2470D8C32C12FE9EF63DDD98560AF85B3
-:1506900006ECCF8CF5F4E05E053D0AD9486CD0C0F501D8C35394
-:1506A5001C72BD05754ABA6D6364519B29DBDD753F5B485DC4FE
-:1506BA006BCAFA6BF53A79F216B2E641D6939396B5F5DBC477B6
-:1506CF004CC8FA30C8BAC39435047BBBE1F7A67CB1E3FA532095
-:1506E4005F6DF63BEAD4489390AD2C36430DE9A1E66F635D12CB
-:1506F9003B20628096FFDC38EB2553A0E5B81F85AE5007644910
-:15070E00D12FE4BE8CF5801EFA8A7AC8BD6A209D523DF4801E4A
-:1507230074D043D0D24325E80169074B68831F4E194FF38472E3
-:15073800C0972AEED189F7E6346B6F46C6E6D1C78027EC8760F4
-:15074D00EF3AF72BEE55C253FAB5151EC10BC417D8AF2761BF9D
-:150762007ECADD9543AA6BE659D5D53524F6EC11C79EED297B45
-:15077700C5DEB37E9C3F52DCB335E8FFE8D7CE7D3B0BE05046FB
-:15078C00BF4346AD9C4C71EEE7B1FC943BCDFDC1CBF1EA46B191
-:1507A1005788F48AD452BDAC53F4AB5DEB45BC8E06486C8EF056
-:1507B6005F6EE65EC88572F20A93D6ACC59C974940CE2B4C4D3A
-:1507CB00B05EFDB8C2662694C06E880F77A4541FFA4FCCB0FC60
-:1507E00087C7671D931ABD55AB61BFC6581BD118FA4ADA05352E
-:1507F50041586188A322F20CD3A03568598B1F7CEB04ACF36627
-:15080A008FA9011DF3FFEF0D51CBE01EF84BB6DB3E6764B09B53
-:15081F00E9E04BC89773FE51F0AD1524C1B6E9879693F065A3B1
-:150834001E6581396FB61DCE4A585F7C435A0F9AB4B278CE7380
-:15084900CCAD4A8E3621FE34B9357E5D33D7E74BD637265BC568
-:15085E00FAA513ACA7DA492677758B1C6DCF47110FCCDD958C37
-:1508730034A1FEEDB501FD984A61CE8BF0B1B9803B950925C1C8
-:15088800A6164C8305238BF5A9CC647C22F0A6D48CF11F7DAC82
-:15089D00167D35D76F94D64FEB1E76D43FA2AE642C8AB58F2916
-:1508B200DF196CCD7ACFEA53689DF58F63FD1C0D7D1060A1FEDC
-:1508C700411CD21AA61EC43D0BF2E27E1A572BE3F1F93E2FEEED
-:1508DC0053C31FCCC6F17C5BA75C51FF86BE06E7DDA19D24F6BF
-:1508F10004C39C9E7B40D4893C8BF50E9C875D33CD9A270A7153
-:1509060003EB2B92DB8E7006C2C9C119702E7E5A9C8BA747FA68
-:15091B00C59938181D54B1CEC0F544AE15676212AA8F4F8F3447
-:150930008873309E89CB8066FBFEFBADF3F0BDEAF32EFB3CBC70
-:15094500D43C7BDE10C78B67CF89F2349E3DDFAA29397B62AE9C
-:15095A00B6CFC3B992F33087986B3F373B0F7F4D8C7C4CDB1875
-:15096F00F11C3CA3BA601DC6BA3D10C776BF9B56BC55C7314647
-:150984008A5A40C43898C739A0853569CD9CA4A7C98449A13EBA
-:15099900A222060A9B891858EDADFA15F8C48098DB4EACF36D2F
-:1509AE0091DF1EC423D60B9D9B7024F62763F7BB19657A24259F
-:1509C3006C00670103C726F7FCB3217C16EC1BA8492A585360D5
-:1509D8002C47BF7906F9224BD94BA843FB5EE0366C531F98D827
-:1509ED003613DD0B94C796AA28EB3EBC178056DC0B403BFE5E71
-:150A020060693CEEBAF15EE0EB6CD6FE17B0D944FAE413D8D15A
-:150A17005B750FD830CA2C7939CAEB6D9D6DE290470CBF43DE6A
-:150A2C00042153049FAD7D967D070C8499DC73613C3F729F6190
-:150A4100E39D01786D5BDBF1E9CE478AF1C5E5EB107ADA94DD30
-:150A5600D3689F51E58D49A5A67590C5800FAC0FF04CAA79CD1A
-:150A6B003C8DF05CE80DFC0A748363EE92B161475C9A41E7F61F
-:150A800060CCB93802B97A659F1AD0D07F1A18C81E708580C77E
-:150A950031BED23C564648A3E66944597640DFB5C63C7FE1F838
-:150AAA00E1DA2106B508F7C82F412CEF33EEA4A70D29B9C7210B
-:150ABF0097CE104EFF119EB74C5C4B268B2B79AA880BE087AD61
-:150AD40073A08BE8784634F0DDA6F34DE4D11DF2F43878D02783
-:150AE900290FC2651E30E5D11DF27C2DAE1279AE96C873F536FA
-:150AFE00E5C938E479C7C1436692F2205CFE7E539E8C439EAFE6
-:150B1300C55522CFB51279AEDDA63CC991A23C67478A3CE0F891
-:150B280064E44138D99207FB4B268BAB449ED11279461DF2440C
-:150B3D00ADFB0C19F3B9E5E3750A53EFFB09D2357D04DF975A45
-:150B5200EF19EBBDDE7A47FAF83E43BC2799F065A0B1AB4CB4FF
-:150B6700ECAAF59EB6DEAF59EF17ADF751EBFD1DC0B38B9EE038
-:150B7C00D8D760AE93BECCC5BD03F47BE86B5CD403D04FD337E7
-:150B91007994DEC5CC73C5592303EBE05C51334BF33407939EC7
-:150BA600667FDED3EC053B606D8F3236D05302CF7658BB9ABEDF
-:150BBB002AF074437F337D83E3FAB74C3E38D2DC4E777313AFA4
-:150BD0006E0C025EBC6B5841DE6167B6BEBC5CDC59004C15F5B9
-:150BE50034E2D80B5B5F136359C7D8335BDF1463C8933DF6E484
-:150BFA00D6BDCB6DFC7751D37E886796E8A7F9768B3EF2B4B65E
-:150C0F006E60998DD386455C36ACCD2BF216B26011EF5F514FEF
-:150C2400B3B84BB1743AFC88A9D39CF8EE61CA3EC3CE1F304F8C
-:150C3900C7CD9BF4EEB6700C9A638CFF9D09F3A1850369071099
-:150C4E0007CC651F2DCE452C3DC6617E1DE80F75C7A01FA7072F
-:150C6300399E8FCE099E2E0B3E1FA5CFF15EA1DF1EE3F48870DB
-:150C780040FF03D73D4D7B67526543E88D85CFE692CA0F962315
-:150C8D001F9D424715509B2E592E352D0AED5EC861EE6E319754
-:150CA20011FC56243D8DB3DE949A82A1830B0D98AB5A6EF28FE3
-:150CB700FAAA807D72FD2BA9E98BDAE7161E82B93F367B9A2BEB
-:150CCC00B4F2C6CF2EFD2182387F57CB22B8FEB7BD831184FDD0
-:150CE100E0D269C8FB3B044DE03FA38B7686E019E4CCC444BBDF
-:150CF6004BE026E1682629DA84E0036A8E0CEE89E9172EABAEBD
-:150D0B00F735D87FAFB0CA60268EFA31D75D36368BD6D41109F9
-:150D20006B8602EDB495C755D7FA47A0F6D9CFEEC05C097A3363
-:150D3500E9268D0ED1EE303A45DB23F4590EE705D7FEC701FEB1
-:150D4A007BAC2A1806782A6219C20F8A36619C15ED52A1F32969
-:150D5F001700FEFD7F10B5D5D4600CE0A386C977D2E887F6692B
-:150D740061875D467AA498DB4808EAADB0226CB30D6C93A007C3
-:150D8900B81CCCC1D845B6B4CCBA2B17ED45A301DA9DDF273E14
-:150D9E001E76B7C0318F1D182DF8D1971E85F14A7A02EA055D0D
-:150DB300E8AF0CCE160BBE8370E6BEC25CB9CD82457D5BFB8D79
-:150DC80061FF29A029FBDE533B9625AD6F6D507FC1B896FF8DAF
-:150DDD0011681D62E8C0DBF3AF1BF0CE75E02D104DA9B20FCFF3
-:150DF20039EF1B121D323E69B0F8A1B3D9F52F4D1A4761BD6C70
-:150E0700F1C32D7E8ECE29F283B9EE030B36EBE0277B0B7E623A
-:150E1C000E7E36033FF0CEF904FC6C76F0F39845E33DDC47160B
-:150E31003F598B9F4A073F98AB5659B0E86F363FD8BF193F51AC
-:150E4600073FAB811F78E7C909F8796B71919F8FBE30699C1BBB
-:150E5B00C19C66F28334909FD6D9457E30D79C3161052D37C413
-:150E7000D68EE694310A676A3BC63A3F0F6874906BF434C4E84F
-:150E8500CD4C0EDE173FBC2CCDF0FF560EE74E2AD65D9091B78B
-:150E9A0062CA7F8CE0652EF17B1D79334EFB7959D57995E60779
-:150EAF0058714DDAB868C5631B5601B86ED8DB7E888DCEF53124
-:150EC400DACD37037D05F850E85178AEF0049DCB77D105E03353
-:150ED9000DBC9346C056AB799DB24D35C8A1447D3EC5BAF55427
-:150EEE00A207E093F41C4F53C60FF79E663564409DB6A597D514
-:150F03005EBAC23AB67C97EDA99DCFF66E59C8F6F52E639D97C5
-:150F180056B223B56718DED37CFCDB32DCD30CFFB7E7D9DEF32D
-:150F2D00ACF2C231F5E0A5FD500FEC5FE2E4EB9D30F155D1D593
-:150F4200CD6363B176D6B090F8FCCE3121403B3B7A93F1CDD75E
-:150F57000A378C2B5A3BC77889FA09D44FB08EB7B33B9B26184E
-:150F6C00875AE06A1DF179434911ABC046F2DCE4318EF6C5F74D
-:150F81004F46AC1A413EC789CCB844C51D2BBF8AFF6810E6FCBA
-:150F96009A687BF8A8DBAC7586451B66A4007551554AEDD6878E
-:150FAB00946EBD5F9926A5D4236543CA91E88072186CF9ACFEB4
-:150FC00086E27DEF0FAA8005E0837A9722AF632AFA4185833FB6
-:150FD500BC8390D890187F52AB6CFCC4FE770F2B6EFCFB0A33BF
-:150FEA003F6A63B934C991E73990C72A925F35CC4A3E8179C4C6
-:150FFF00CA8567451D63E6AFB366AC039D99F98F5B303D026617
-:1510140047314F8AFDF09845277B039D3BC6D131F3E559510FD6
-:15102900D97432169D0F2D3A264C0F33E3709A87AF12D21B76BE
-:15103E00B5941F48A981E83CBCDFF3FBB5EF468290ABAE5E372C
-:15105300E5FD40FBEBC6CBD0F782FEEB14380779061290B39AFC
-:151068005DA1745CA678DF1B66C92CC489A4AB65333D652C022E
-:15107D001C92FC3DC8435D3C14DD1F3948BA13788676877AE21E
-:15109200D23D50A3C5468CB974C4705BBA8ED02E234A0F1A8197
-:1510A7007C8A734F6AE702DA67605C895D0039F2FD5C069C38D8
-:1510BC000E276206072EAF93E6A617FA9A9DEBEB9443AA61E19E
-:1510D100C0B5D8475C147049A1FA78B464BD1FD647E97306D4F3
-:1510E60010D6FAEE09D7E7FE1173537D1C7909C3DC02A833C232
-:1510FB00B48BE1DD96413A120AFD2FC3E3C238779A19E470422A
-:15111000D23A0C3FE46037D6BBB17EC3AB751B95DA39718F365C
-:15112500DE8FCF5A7EAC8FF3E331FFCDA614D9E1BF55502B8C04
-:15113A00F928F801DA0F7DB4FCC0805A43E6A9A66CF5A66CD11A
-:15114F00BE66A73F0768170F6A529384E766C29917ECB1733E0C
-:15116400F1E1FBBE999DCAC54DC4F7E2CCA422D3F9C236ABD16A
-:151179000EB096AFEE7E085BCF52F13F2D15B383264E79893719
-:15118E002E43FF568F0947444B8336DF14F65D1D91AB16A81DE5
-:1511A300EEF90F79AC71EED71FB2E7F1FF6AE4E8DC07251B479E
-:1511B800B4FB41BFDD5F591C17FB04E498438E36617E801A931D
-:1511CD004E8BF5604D631CA2520BD51883B37A0061360998CB74
-:1511E200D6779F4EBCA3A0247692076973837DCF82DF034657E0
-:1511F700342F36BFD19B7797884F4E7633C487637EB95B7D077F
-:15120C00713AE82F17B829C33B5949FE0CE87719B80EE95BEBFC
-:1512210032B80EE89D71F62F3AF158BF83B9E39073F0FBEF1552
-:15123600568DF74FFC285B8BFB92DE1B09D2798DCC8A0F3FA1C4
-:15124B000F35EA629F778AEFE5BBA75C413ADC2F3F67DE75C28B
-:1512600018E4AB1A1BBFA4CD6558B309D81F7EDE4272FD7C9ADA
-:1512750003B6C2829520374F16EE10F0BA0AE2DD0B5A5D13D6FA
-:15128A0008E677FE432A9C9E184473435AF339F8E46CD63B4C08
-:15129F00104FA67AF42893454EE83FF3BB42A11AEF06B789B5BD
-:1512B40069B17681B69FD5C84FAB776AE759448333656C9E811D
-:1512C900F489DC6F081EB09F4B19923C5745DC52FEA88DDBE4E5
-:1512DE0011F6DA589FA78C2CD058A44D6FACD2A6477EA04D6DF9
-:1512F30044BE376975CDB67C923C5B2D956F3273820F7BACC455
-:151308007E7C18BF7D9F03DB65E24B08A9C63AC6E53BA7BEE98E
-:15131D00C2FBC734D64D747A10725E6CC8C0DA424A0E31D7BBE7
-:15133200E7D5FF065E7B5CC48BF6C77BF9465AD358456B227E15
-:151347007A47E366D0D32A5ADBB8CEB237E2A8965F1577D4E057
-:15135C000C34289F51CB80C60298AF86BE1BFA088773F6B90BB5
-:15137100E15DD638AE0F26E78571BD8CB2027D19F8284CA5ECCB
-:1513860008E953189C8702AE3EF17DE059F17F5203D67D685A64
-:15139B009CD1719F797D57D4368823337C4755D7CC4EF57052CB
-:1513B0006AA9B9705E9D23EE5933868EDF5E760E88EF34384755
-:1513C5008E0DB1CBE2FB0C65B3C8A9E508432C18F17DA56F880C
-:1513DA00CDD2BE6A126B89398EDF4DF4248EFFBC89C883064DB6
-:1513EF00A6F03B8821AF1950A330EED79AC5B817DEA980AB6D72
-:1514040092F05E22F6BA7118FC026582FD5F8D7715B3A2A71B27
-:15141900C59D456ED038AC4942EF788FF70CC43C5BC6A0252368
-:15142E00CA11B1F27D7D01CF75FF43CC13064755A4D993BC91CC
-:151443001988C3038611280C0F1CD6E045326894648038C168C9
-:151458002556E40688EE7B5CD089266EB450729055768B5B5FCA
-:15146D003081041F5CF34C206BE1DE84CD94932B2203071A3D8B
-:15148200ACCBDE79BB68A5AE721677C7D5B9DEECD69E4779615E
-:151497008D6CDC65AB38E7BEAFBBDFCC9BC9A0E0DED5FD987AC3
-:1514AC006FBEEEF77D5F7FFDF5F77DDDFD7547F5F31B315A88AC
-:1514C1001BB88ED10BB618607BCEF31C0253B2E941318E59B05A
-:1514D600E751CCF18671A03F4CDCB28FC53814642D3F01387A39
-:1514EB00433155770FB3BC0699D9A328ABEF954FB03595493179
-:151500002F4698A20CB3BD8A291B2C2060E47206562A6057702E
-:151515006D46C454576DDF30DD1B292025CAB0698761DCE8CF5F
-:15152A00819102899467C3E8203CE5C8192A83AFA9C032D15E21
-:15153F00DC8F21F4769E6B22BEBFF4E59C7F70B1EFE3D4E291CB
-:151554003FC5FFF019EAE881BE606BC0316AD10929C3F44592AE
-:1515690030FAF4188BBB3F01BB07D1C3168CBB93E9B888CB7601
-:15157E00C1548AC935947C3DCD6728F916EDE819566B6CBC2309
-:151593004EF46F7DA14186B319437E5C0345D9C8C3B42F1C65B4
-:1515A800F07A019F12B1117B029F3EDC2F92193EA6035EFC1FE0
-:1515BD008E1956FFA7447F768BFE64BA60C90D6224A00FF3A197
-:1515D200D7696F826C29B2D96359B4C7259E72CEF3BD2FD3E9DE
-:1515E700C559F685CBFB75B6CF555344C27ADD1915C74C0DDB68
-:1515FC0013E730B2613AACC00E2BC6711C376BC1E339C47B8D20
-:15161100CCE1A1E409E0F7049D3FC9E4EED3053F0C0636CD57B4
-:15162600191773BF8421C3372C8708FA8C3DC3678CD9888F0E7C
-:15163B009BF9EA933CF549BAFE5B5CD600837773773ADE8E53ED
-:151650006931CC3E443BF19DB5C90BBC5B6D82F729479CE97FDA
-:15166500C09B29DF579729B7607BF3C0A40DD3614E3B2C67FFB1
-:15167A0091E9BB1863D6F8B58FED8E9CB18D4FE7C7710DCBAE50
-:15168F00F58D9EE71BABEC255B19C674ED8BC82CCBA6A03CAC55
-:1516A400727C5F72A1536BC8299F85B4EF47DA71A3028C776FB2
-:1516B900C4B945C6BD0EC0157E28639F5037702C5865E5F6325F
-:1516CE0090834BE0614F1B8EA21C1C56FBB9FE71989E0B037C5D
-:1516E3007B2C983703D3F3C0667AB261D8A62E5B9B2D58671E54
-:1516F80058A1C70ED38D4431D8B685423E246AA0FDC0F1E915CD
-:15170D00FA1E4FEB3BC0D017D8D63A4811616B1AA8BF5EA6BF42
-:1517220031C3D2F39907713D3C418FC2B8F785B86DCB8743BE31
-:15173700611C5086397BF230D6331B6CF350B4EF681FB7A15DC2
-:15174C00C1B526F8EEC0C2B8CAF0839EC14490E683CB36B861D9
-:15176100AFBF203F5C0678AB43D8DF626E732D99615C500F659D
-:1517760079E5E5CDDFD6591F27B43E7DB8EDC0C284CA7310AFE4
-:15178B00436EFF8BB8B09D5FD507C68DF0F58D7165F76B42D8B7
-:1517A0007BCB77737B9C2DEB6C7B9C8717F886F302710A3E0187
-:1517B500F76CC4C7F6C3F3C8214F7D92AE9FCDDF6E9BDEE11865
-:1517CA007678A68F71E2993EC60B3CD3C733C903DBEF9E3EC6AB
-:1517DF009D9EE9E359CA8161FD57ECDF66E6BC221EC371CE7D03
-:1517F40003CA7489CDF7C15397785C62129B2F9473CA245B99AC
-:1518090037A7CC652B5B905356642B5B2C0B3F129834E23DC8D7
-:15181E00972EF2CBAD582446838A3390893D6294E5EA425F6464
-:15183300628FA8C6E38C9CD853CEE4C8C8BE924647DD2AE853AA
-:1518480098670742867C3B2105072B357D32E5763A3AD5367878
-:15185D004A20935E85AFC3FE0874EA70F4F7E5646A805EE941AA
-:15187200044EC44576EDFFFFFDD5D610F7D86729370D75A835F8
-:15188700F749EBACBD4DDC2F24EDFA293667688F9E1A67CFD1D9
-:15189C00532CC7AA3D796A929DC989D2C446BE16678B410D07AF
-:1518B10019FE18E539713F71ABF7F3BC65EE67BBC1CF0E829F2F
-:1518C600051FC9E456C2E466F9EA1AE083783AD5F2CF84EC22A0
-:1518DB000E263BB47D51C0E307F847F749AB91D6D98D7C8C8CD2
-:1518F000C013D71B1D0A8B154DFCBF212BF68CD107BF617F17F3
-:15190500B179E0A4896D045924842C12421609218B04CAA2F079
-:15191A005E57A33D7EB95EF9E158F228CB033395AEC0D1422EFD
-:15192F002B0EBB13600702F12CD83D00EB0B9CB66045089B0F62
-:15194400B05B03A30863FB3A5CA6572E810C4196172F4D9765C3
-:15195900C37AE2BE700965E95F7DBDEDBADEF69CCBA30F054261
-:15196E001F3EAA26EEDAEA6C3E2B24E2AE075E9CC0EBDA3CBC7E
-:15198300C6A17E29E3B574F58DF4C1F5F27B3C0FBF8582DF525A
-:15199800A0DD1F9AAEBFFA35F4B77322E52E8076B44F4C6F471A
-:1519AD0012F0344F603BBCAB6F54976EA43DF13CED91447B1A71
-:1519C200818773F7417BBE01FDD6FF8236297E2A2BA594D97E0D
-:1519D700B0798EBB0889001CFF4BA4D6D88DEF01D550403A8B99
-:1519EC0015CD9495EA57D91E33D899FA08AE37478DF001EE1352
-:151A010095837CAE32FE32F86249077FD8CDD64B0DA837161922
-:151A1600328B9A4E9A139F72DC7EC09B9AAD1B53F0DFC1FFBBA4
-:151A2B002E7C9ACDCF0551F70A3C1B20DEF42A9C1E51393DA4D7
-:151A400083F4D02BDBE92D867A454D43663DD0DB2D709CFE9440
-:151A5500D3EB14F4E0BFCB2E4F59C8B3086489E5ED5524AB7C94
-:151A6A008E65FFAA7879434EF95C513E26CACB73CAE789F2E328
-:151A7F00A2DCCBCA278D1A9A39CF92823652D2A5E2DE9D0B7DD7
-:151A940074CEF9956E888768D4B905E28CAD55B8AEA977AD2A29
-:151AA90056A4A02AE29A9E8517D5AAD0BE60AD2D5F60CF48D3BE
-:151ABE000728ABE7DB3FAC0AD8E01FFFF0E5AB085FB3F5832A70
-:151AD3007B7EC18537BFFF1AC29FF8DB9F559162DCDBEE373A7F
-:151AE800FFE5856AAF4FDF4A1E236E974ADCD3F8B4E58F2987E0
-:151AFD00B2FD338F35264DB4210E0F9FC331989CDD362B3EC2C4
-:151B12007A3341D7A7D6F2DC19ACDB5337ACCE8C3C12D85FC732
-:151B2700EC391DB5EC39945967724637E69FEF1B9FA7DCF14B5D
-:151B3C002977661E46B55EDDAFE2BE0AC48DEEEE8551753D59D3
-:151B51001EF490E5AB16298EE0799045CF42AA6ED0FDC17369BF
-:151B6600B9C4D99AC4CD4C1E740FC6284E88F50673CADDB672FB
-:151B7B0009CA3B3372ED2E9048B70BCA1D65D07FA2CE22E6D307
-:151B9000F8B73741FD0651FF0EB0FF3EE1DFB0CC07651584EB9F
-:151BA50013FE5F7261402B81FF8B6C75965C8869DE1C7E1E8494
-:151BBA007E4A4462A60B7C6CF96F53EEE8D594BBF9CBD42CD1C5
-:151BCF00BE7511B0D3A03F5976C52BF45442F9839E86927F6EF3
-:151BE400E84E320BF50CE3600B37AE5FE21EA16CE30B73854FA4
-:151BF90047980F360222BFA108F02E00F97B9712B7EEE7BABFE7
-:151C0E00600DE016FB3054F8F31749BFD13B3AA8BEB90CF7E984
-:151C230002068F654B0C561EA830D07717B863DA0F963E5CEE8D
-:151C3800AD8CD2D65732F1168577A90F2255788EC2EF1CFC9498
-:151C4D005EB0AFF01B17BFD65EBEFE85F82EFE12D7BF94C6F455
-:151C6200BC4CC0A3FFC1E161012F009F5683EF7480CE837E2B7B
-:151C770000FF50CCD618264DE9DB84BC823E830E9896DCADF9D7
-:151C8C000796596D9394037406B3ADD4083C4A48D17FA6DC93CD
-:151CA100249BAEEE22B370AD1BF1FF33CC476702DD31A81376E8
-:151CB600733F65E191051EF932E76DF493947B90E7F5883A101A
-:151CCB0007D1210DC7EC646A361B23B837D6F7F7C7198C4CCED0
-:151CE00026DE9F0EF277F883F2CED48D9AB89FD6377A5C9D2F99
-:151CF500B1F50E93EFB3454DDC575B6BA3C3D71DFB8DC7C61FD8
-:151D0A001B5F363A98A53F37A3FE209FA043814ADCA386B8203C
-:151D1F003C443146DBAFAC0BB01C45CC8D8BBC4B95C819C3C77B
-:151D340072E8BF303D7CED9BF68A7557BE8E3BC2F70C020ADF8D
-:151D49002F40BA387EC227CDE7593FDC40FC373E8438D2F3B0B3
-:151D5E00AFE741D0065A69FA79F475DB3AF0CB69FB17A5E3B899
-:151D7300D62B1BEC9C14192D20E037D8FA3EE0A0631B591E841D
-:151D8800CF9A67CD2103EC0C12CA784CD834FCBEFB5EE296C690
-:151D9D005FD2E40F5F52ED362D6D77D99C6CC448FDD57B923824
-:151DB2003324A32D66F3191AA37790C120E6EA4FFDFB7095BD05
-:151DC7006F6E1263BBA482E45D1FE56B9BBAC03B22F026742EFA
-:151DDC003FC0ABC738DE25C7B3F0CE1078C757E7E0457B08F1E8
-:151DF100D5BE85FD2A3BAF0F3610F126393E7D19EEC9CB83B482
-:151E06003039AC4BC933BAAB28C6D6F966029DB961AA3922869F
-:151E1B007128296D91944EE316F91D6D2C95F279A25230334FC2
-:151E30000D1B1877EE72A0ADAA6DB4CEDD635E358B4B587EE23F
-:151E4500A4A9E2B3B8A291C80FBCCAE64201E554E8D13CED0713
-:151E5A00FF15E847FFD5CFFCD7BE8523AA67B4EB5E466F5CEA4B
-:151E6F00A49571CE7B38A67B301E13F082484C972B13AC7D8726
-:151E8400C801D584B1ECDA30C8F6D1BE85361EFAC411194EB76D
-:151E99006F6E6830687DCBED46FA7D1A3FFDFD997CEC7DE0FFB5
-:151EAE003DBAE0875E831F80CB601F91173B4D07DF4FDF9375AB
-:151EC3002604ED1501BE8B47F83C5FC44F203B2E1F9E4F922D53
-:151ED80047B9EBD5ACFD0B186FC88303FA1AD73F43C9237B8A4E
-:151EED00F95C4DFF25C07BC351D5E5116B64C0D3C5421DCF3873
-:151F0200CFC2F2B64D3C470A7DCC3231BFAB653A12D7FF14CA3C
-:151F17002CDE19DF507FD7261607B33C8E7A51EF7BB67AD5C94A
-:151F2C00D7F7C04F47786213DBD3D0314F00DB82F349E4A3F77A
-:151F4100A598EA1DE5FC20DCA2DB2AF09DCC4377C446779BA8EC
-:151F5600F7B6ADDE7AA08BF5466DF5DA44BD9FE4E16F7DF2845B
-:151F6B008EE3EA1CE3F16F74F403B5789E06F83BCC746798AD4C
-:151F800015F7FE1DF04A0619AFB5365EDB05EEF7F3F03A6EE3A1
-:151F95006197A8F78F7978BD60ABB75BD4FBD7AFE035BA39C326
-:151FAA006BFDD7F05A6FE33529700F6C9ECE6B7C7386875F8943
-:151FBF007A439BAFD19F9B33FD59738DFEACB1D1BD68F5671EA7
-:151FD400BA2336BA13567F5E836E77038EAFB328031AB6D3C5F7
-:151FE900F68AFB3F106EE9FC7EA87F84C4D23ADFE0E43A7FD59C
-:151FFE00C1755E6FC8D00E3B39ED8E86AFA00D741B045D8B5E7B
-:1520130083AD9D0D02474F7E1C14C7ACB516ADE6DA3C3C4FF630
-:152028005AC6DEB1F18CE771E5E394F92FBCB7473E4D31CE73E4
-:15203D00157569FB206E94C197C9F5EF6A0B8C33DA41DCA3B7F4
-:15205200D9A01F40BBF2D91EEB3B9F23A61ED18755D417BEF704
-:15206700774085F9EA1E9C9FAE67B832BEE12EC055007E216DFF
-:15207C005743C3AA6B438CD954664F2D7FA1A33D8D317B2AD7C5
-:1520910001FF60471DB6F7ACF61663BE4EBFEA5848B514E65951
-:1520A600E0BAEF659EFBC57D5382D3A7C29E86FB786C07BE8FF4
-:1520BB00B765909DE791C3BA46D12F4586C12FBDADB9A2670C99
-:1520D000F44D79FDC98F32F33B9ECFD0A9F970BB1AD712C4FFBC
-:1520E500A9546A5EEE5C8FAF47B2FD70B3640AECAB1BC656B88C
-:1520FA00D4A0A18E36B4C5AE426E93252BCEC6F32DBF4BA57368
-:15210F003F9529969F39DF9E372855F27B70545B3DBC8028B73B
-:152124001EFA84C30A9EA11AA188E7093C4355E6C0DBD558FC4D
-:15213900EB284E3462F92DA141ED96D0DBA8336615D6C19800DF
-:15214E00F3A901EEDB1A3333FFDFD618ECCF6218A3101F4D680E
-:15216300FCFBB7D1A77B0B3C1DDA7BBFCDF0E49F6271928DA775
-:152178008451454EAEF1298E80451BEF02BA83D18C52ACEFBB81
-:15218D00F50B33FDBEEE8B349DE492936B0BD2795F309F147980
-:1521A200F8C8D7FC5B3127A28F9AEC2C5729CB19BA17C5217371
-:1521B7005CBC6E9CA2FCC12D9AB2BC17FAFA347CD36B4ACA69E7
-:1521CC00B3D1164F5E7C84906714E79AB30E316FCD43E7218C26
-:1521E1005DF2E2F69B4EF94DC07DD620B4CF94A2EF9A986F8196
-:1521F600EB9F69DF8DF38A42317E11EFB7C57D14A20CFFE7B9AD
-:15220B00EF83E596A21E4DCC40BE127482E78C5397E0CF65E79A
-:1522200003FA1BF945BCBE6082E51BB1BC0FF9A4897CC83F5F73
-:152235008EBC73DD13EBF1150319FD463C138F703CFE298E9FB9
-:15224A00E34D30F9CCFF791775C01C0EEFAFE823C32A9EA3C3D2
-:15225F0098977F9330B14ED63800FCC707ECF7C9F07623FEC926
-:152274004778FB389D78161D6B4D00EB323926B91C6FD9DA6987
-:15228900E23D116C4E63A7993E5F1B32382F1586CCE4526BF06A
-:15229E009C8480E112F9A00C1E1EA44F2DC5D8F518CB47B4F334
-:1522B300E07D6D39B5F71DD431257908F7E6A9A5272CC606DB7A
-:1522C8007A9874AAECDEA8B0C1E4827C61B904EDA515BA819379
-:1522DD00E4C2A24E8D1EB8533B7F21E526E3036CFEEDC53E92E8
-:1522F2004F6992F22EF545F8F9796BEEB2A070FAFCA9A36E8876
-:15230700CDE7B2E650E327CD7B6F740E15FE4BD3D229CC23ECDB
-:15231C0077F2F969B64E711D425E4A845C589F04A33C7F4D1EC1
-:1523310030713E8DFE0CF5097580C94AE773E9A35FA6E6D8F47E
-:15234600384B9F59DE7800C63E9D30E6F9028DB87EE2519697DC
-:15235B007F88FE14E6E9CF287706AFC098BC2BE965E7B07B1FA4
-:15237000E5F4E38FE2251B0798DE610E97809B083F27E6B551F3
-:152385005137915357C04D841F15E3DDC2FF9EF8E67CCE37023B
-:15239A006E22BC55E03F27EA2673EA0AB889F0B502FF3281BF77
-:1523AF0053D4C57AF8BED8666FBA6D65F88E67DBF04C9B0BF426
-:1523C400A8107C95A40C98282F49DEAFA19F092883788676EE70
-:1523D900DC505F9504F3D3F91D135A9132642ED22FADF5557FB6
-:1523EE00A64991D3E66B51E71617CFFB9C373332638D14993002
-:152403002D9D9D09B62D7915D7D13263E0FBE02325766E884EE9
-:152418001B8F627CA5ED0AE2900F0E68BD85832AF23677ABDF7C
-:15242D00B4C633D301B409101B3892EFB2FD46FEFD88993B9E8E
-:1524420079FE24D08431631F272FDDDCA925FE89AFF3C9C2A6AC
-:152457007DDD38D98BB9A2D618E91960392BB2F0A7385696619D
-:15246C006E00C41A8FB1B5F7CCDED306C51910E7A9FEF0FD47F0
-:15248100DB78AA2DF83FB0D139F1445819A04E4F17936729E02E
-:15249600ABFF2CE377E9E7397E1778C13A44EEC03326265B170D
-:1524AB00298E373A0FC6B43ED015796D8CDFCF00B8703D05C6F8
-:1524C000E33C764700F8662CC77BC33087D8F2BFB8BFAA46965F
-:1524D500D2420FDEBDD7618CFF3A435BCE1387B8224097AF4988
-:1524EA0098D85F7DE0F7E5B303C6154113FB378B2694BB7268E4
-:1524FF0066B7BFA4B1C1463F6CA3AFE4A12FD9E82FCE43DF7F80
-:1525140083F431BEE8AC0C18162FC8C3D825CEC362A0954B5FF5
-:152529003E3BC46829910103EF4082B9B789B18FA4F03B8F16DC
-:15253E004706E861887BD0A74DD9E31C5C7393FD66679DA1E108
-:152553005D60532FFAABD87E5FC96D2BFC75CD41E54F2A2AB7BB
-:152568002A0FFEF1A60794CDDFDBD9DEF2EC4E6553CBB696A616
-:15257D009D2D41A5FAF107B7EF686968DDFEDDEFB4B63F5EBE5C
-:15259200F2EE9501A5E4999DAD4FEFD8B1FDB9C79B9E6F0AADAF
-:1525A7005A55B9EAEE157F7497F2D4D3DB5A762A81CAB255156B
-:1525BC006595ABE125581E0896DFADF8D3FB5B16BDB2B2E696EB
-:1525D100B6EDED654F6E7FB6ADACA9B9A96DE70B65CF363DFDA7
-:1525E6005CD9CE1D4F96B5EC6C2B7BEA85B2A6A66D0CB66DFB24
-:1525FB00F6B6953B6F5B758F72A7D2D2FC74BBD2DCF254D3775B
-:15261000B7B52B4FB6363DF79D16A564577BCBAEF61548E5FA76
-:15262500F037EF78FAF9961D654F41B31E6F6A7FF6F1E61DCF95
-:15263A00AF7CF2B67B2AAE853F8D9E9D679AE30B37EE67F71A4D
-:15264F00F88DB9BE8AC612A59CAEC4B35CD6398D88B406EFD1B8
-:1526640038143AD25640FA8DC6DFA7D2E7341A958DE627BF703B
-:15267900AC91E48735BF526DF861EC7D0CB6C40BCF37D176E26F
-:15268E003E09DD6FB47E9172FF74A9146C50866829942D22C3C6
-:1526A3005521A587B2F2B0B4370030B4376B6D30AC27830F04B5
-:1526B8009C66B752B4CEF2090BC036CE203C96C0FF5701F73E78
-:1526CD00F9E5368C13CFFD756A16F2653FD7603FD310BDC2F71F
-:1526E200CABA58FD12A31FEA13F9B2E9856FCE027D3B4FB48D99
-:1526F700B0B3D32B1D642EF2877C78959314DB3003E6A998E3FD
-:15270C0046C657E03EA9D7577DA7866DEF02393A7F52A9E1B5D5
-:152721006A7EC0C5D7AB0E1961E58746CD08D08678CA0BDF5BC8
-:1527360074F01C97B77A850630D34EF3A1548AD1EC62FD72CC9E
-:15274B003C9D4ACDC1FBC4F8BA738F7113F805C439F916AEE733
-:152760000700768CF1E5047F7908F90AEFC775B9F956BF5967CC
-:152775006CA2BFC3BEBBCCFA0EF7571405C69DDC957029F7980F
-:15278A00CEEAE3D0DF07186E1C8738068B94D7CCD22F1D6BED4A
-:15279F00EBBF28734BDEF67EA87927E5FAAAF2D27752B3ECFD49
-:1527B40081FCC8C08FD7D65F6D1197114DFEEC556C93121D4848
-:1527C900CCC13BE7E8622314ED4890E2B6464F926CF14697828B
-:1527DE003F3EC7EEC3F3F96AA1ED0F18787F29CE1DDF9470BE3A
-:1527F300A41A18D348EF3FA3E11D51F5B8CF12C6B3DB611693D4
-:15280800F6EA41D50C55AEDBA414ACFBD079D1F0856E67EB8DA0
-:15281D00462235EB23B12F128AF6D09BB2F4A01EF3BFE763BD01
-:1528320066A8773ABDAF1231F07EEE40B49A12F915EA666D83D9
-:15284700793795F63ADCEB35DC4767F617BEDFE3C0F58C8BFC2C
-:15285C00CEAAE601889DCB204E78925E29242ECFD880F69872A0
-:152871007370AE72F3AA3796CE0FBEBAECD6E018C091DED4894A
-:15288600D4AC658A23C8F8917B0C5C7376C1383C0F7A9FDE0F44
-:15289B001B3FC6FDF1F831F32F1696A86C7D186CE4D142116F97
-:1528B000290EB6761A075C565DAB5E3BD4395837A0E29DA7C812
-:1528C5002FAEE7E6D2C2F18BDFB7C2F7EF39385FB8A679E10D71
-:1528DA001C3F7BE9E2A241CDFBDF47282A4A6D14CFB45F64E72D
-:1528EF00E7CCD0EB6A1FE05D5454AADD8577C28E47D55272D174
-:15290400E80C9D68C33D2E05FBA96E8566429FA0AE38770F1B8D
-:15291900B8B71FC4F58EF08F791F88B18B31B4C4E6610AF015FA
-:15292E006A64FC877F6C8E4DA5DCA70B783BD7439FAECDD37719
-:15294300308F9E9FDBA6DEA914CBE9403CEDE2FB4530C69CE3B3
-:152958003A8C83FD4601CC4B42C923863196725BDFCE80B1811F
-:15296D0036F0AC903BEEA7A22CC22007AB4E3F94B1F7F1970D63
-:15298200CCA762FB8F50A7F48D6CD95F0539E6E315C7ED82680B
-:1529970007F57FCE653E359CFD1D933FEA33B305FB0D4BD6BDC7
-:1529AC0020EBDAE88079F5B8F0F9F676A34E8A761FFD0D6F378E
-:1529C100F63DE2DB05F84A599F458C5D2C6E133AFA2BAEA378CF
-:1529D6007EDA51F780867B86DFB2F450F40997670657E8379C5D
-:1529EB00E736D00DE083E9C6A2A2B59AEF178EA0A523783CBFC9
-:152A00008DEFB30A1D39A3625CB78C9C5987FAE1AD4C30BD3021
-:152A1500F565AAEBFD214D025BBB4CE8035F0FC8EEFF1190B788
-:152A2A004F3EC6E29DD9A01F5EB0BF577E2DE46E8D0BDB37B8AA
-:152A3F00679D4FEE2B717C437D94FD343A30AE7A218EAC17FDA3
-:152A54003EC3A623EDA023AD1F701D71809C25A123E597B99C53
-:152A690059EE01F6FFF14C3F223E4FB84D6BFDB7B672B0676627
-:152A7E0049B4CEF447FFA7BDEF8F8EE2B8F3AC1EF54833D22015
-:152A93005AC3CC20B0905A443892A33833625024598481B05E2D
-:152AA8009910769673B2DD92B0C7B1BD109B64B93B6E1FEF85E7
-:152ABD00C42318890137B8E913589615337224AF7C0B398507C9
-:152AD200397C4F24E2C239B021DC2C211C9764F1388FD8BAACE3
-:152AE700CF283E62E3C466EEFBA9EE1E8D846CECDDBDF7EE8F21
-:152AFC009B7EF3BAEBF7B7BEDF6F557DABEA5BDF5A69AC4D3DC0
-:152B110064AC4ED519D4075AF65353DC2E34E6371EB9869F2B10
-:152B26000ACEB2EE45FDB55654BA5B0DDE817DA2914EC869824F
-:152B3B007B50C5FAD98475AE1E32F7037C3D69949F0DE4EB5DA3
-:152B5000B09131CED8A10527686E3ACCD7BEA454B701BDC4D514
-:152B6500A9935CDE8BA786C193F324B9DB582D9F34747AFBF5F8
-:152B7A0011F5B46C86B3EA61EDEA07C8832E36E6FE07F17305BB
-:152B8F005F77BC253C273C2C7C56F00937D8AFD97F633F64DFE9
-:152BA40063C3EC5966B0DD6C07DBCEFE9A6D618FB38DEC61F62A
-:152BB90020EB600AFB125BCFFE8C7D917D81B5B17BD96AB68A61
-:152BCE00AD642BD8729A41B6B066D6C41AD93216664B59030BD8
-:152BE300B120FB0CBB9B7D9AD5D3F3297617ABA3A7967D929E0F
-:152BF8003BD9127A6AE8F9043D8BE9A9A647A6A78A3F95F42CC7
-:152C0D00E24F057FEEE0CF42EB59C09F72EB999F7B02D6E3CFE1
-:152C22003DBEBC675EDEE39DF694CD78A45B9EB9B73CA5B33E15
-:152C3700733EF0F17CE85372DBA7F8233FEEDB3E2E6E3B338E52
-:152C4C00F3B1C15A4DE6674B4856A96CEA8C32F928FC6AC84FD6
-:152C6100B7BE6BE93B6D7DD7D3B724D037FA96CA5A8A1FD17442
-:152C7600D6A6A569522C098A26C98B8F4A31FAA7E89F597C1419
-:152C8B00E598B6496BB90D3659B6FCDC969F407E31CBAFD8F202
-:152CA00073905FCAF22BB1FC0AC80FF95199FC2CAAC4A2412BC1
-:152CB5002FE8F906AD3CA0D71BB4D2428F374869A202F66465D7
-:152CCA002D880E49BE4BA3D975BF93E469F845B99D8790EE4D6B
-:152CDF00090DAE3375D4FEABFB5D679A558E9F0F091BFD90302C
-:152CF4006E7F87C24A298CFC0DF88B679B555E76BACEB07167CF
-:152D0900E31CF5485B30EA2F719AE8329F770775CCF318EAC994
-:152D1E00D3043B815FE0507298F1E3A7AC70EA135BE5C5866EE7
-:152D3300E593FA2FA67F94E245D15F4A8B0DD105BBA3B3BFA3AF
-:152D4800C2549C74DEB7E498FAD62D7F8EFFF1EC5CE82698E770
-:152D5D00F7656DD2B4C76AEA6D705D4699EB74145ADFFC9CB4E6
-:152D720083788DD11C34D8447DA783251C4D4611ECA1469AD5B9
-:152D8700C9EA66BE1E37F943E732E0046EAC898E533A0F6B8218
-:152D9C004EB4514FB8A08E5673C90D4611BB8B60BFCB700622DC
-:152DB1009DE959FC24C1F463F25B06FADADA996B124159E77EE0
-:152DC600E0EF029CCB151A44A29914EF6A10313F96AAF537A019
-:152DDB003B2F85A8C826BD9EAF3BC17E6C33D7C9803BEA28A727
-:152DF00032EA74942F9E2957A5785D186F57BCAE01EF28EA9AFF
-:152E05000E72191A71391FC3DE6230A8C5799B68D2225CD728D1
-:152E1A0002FF58766E1BC58972FB879095CD33CF312DC2F5F20E
-:152E2F0037F133A82CB8C53C03CDB659F714242D5D08ACEBCEA1
-:152E440025A012345F49E83A4B28D8DF81FBAD15E23296DEA113
-:152E59007B64B1814577C2AE9C8BA565DDB4FF6AEA31D5670A9B
-:152E6E001A789E941F5F47C277B4574F2E882B42AA17DF464EDC
-:152E8300CF23FA5FFB50BF0AF9A02ECA670DA62768DE242EFB76
-:152E9800EE83DFA5FC5FEE833FFCEAC9AF7F865F39F9F5CCF080
-:152EAD00DBBA82E0925EEBFBFA83AF874860D63CF2157D1B3BFC
-:152EC200A355AC7C5D6DAF7A25F46CD3045FB75814BF44F57999
-:152ED7004A5BB4F2BCEABA4FE336CACB2DBBF3934F88CBC4D496
-:152EEC0090EEA0F15196BFDFC7F4EB862B69DAE3E476D4C70FBC
-:152F01003406307FA2F298FEB7C61DC2EB2AF051CC5E098D3CFA
-:152F1600F86623C142B4BD42F09DD7056D9FFAEC86D7B43B22A6
-:152F2B005486B4CF20DCC56FAE581D72ED46F93B47D94821CDB2
-:152F4000E3BE33EA725DA3F05DFDAEB6D7C9FFE97ED3FD3796FB
-:152F5500FB3FF59FC966FD7DF679C0E8CFFB128E333AF0B68DCF
-:152F6A008D6BF11F14367CEB5B850DD07FE84F3FAB2CBCF0B4B0
-:152F7F005270FEA2BA865D0A2D1C3FA9422748F8C900F4F5CCDC
-:152F94003A120D70EED52FFD07F5FA43578C85C2CB14E792E1D4
-:152FA9008A1F69C4BC15F94F3E745E77A50A1B469F285CC6F5AF
-:152FBE00645FE26BDE47138E14D1FAB88E7AFCE1507738708AB3
-:152FD300F2977EA3A12E12608EFE68D485FD1069D75189C3FEC9
-:152FE800E3A3AF513B2C96F726B3244F16C9DDF1FD714D11D6BF
-:152FFD0069D44E7FAEC36E288D00EC2917F610B4E464F5EF0D02
-:153012008ABBE74DB97E5994E26F8FAD6EE0EBAF05E6594D31D5
-:15302700F56DEA279D0DB1F1C30D4C3FAE4F82FFB0BE47E1EB7B
-:15303C00C95F4C1D211EEAE6F6486A2D7B41BCBDE97BB9DDF0EB
-:153051005ADED648AE4DEDA5B616D744A2ABC4B430DE2EA635C4
-:15306600E08D3D3257EA00EC1D733BA2E5A9842EB85EC63C93F4
-:15307B00DB0B052FA28DB8CE216CC88842EE4E258CBBE21AF7B7
-:153090007FEF27541EB921134ED2D4D013131BCA486E445B997A
-:1530A500AC1E321606529D63379DCB0897C6E9F7B22E89E06916
-:1530BA00A5322EA16D05FB349DFAE156CA97A5068C8BBC7E4946
-:1530CF009DDAA91424C0DEEED6C24C3F053BDAA3E82F7747CE85
-:1530E4002BBF7EB4B0A18F752B7DF1034AE91271595F64AF3217
-:1530F9003FD1ABEEDFA929FB9B2F73D952CA1CEC5BB3A4F2B3DC
-:15310E007C8F28181FC5DA6BD9A204F600F58A14AF8FB986EDC6
-:1531230032EDF5E3BB4D24193AF39A2EB411EFEAA78DFDE39A1A
-:1531380082F541576A80D2ED028EF95E5E79E6A0519179CEA8B5
-:15314D0025BC54503D338524165038DA67ADBC8BDB6EE1794811
-:153162009A7191E6A1E5F2533AB7B1B841D3289D8EBE418C1DA2
-:15317700D3C3991F50DC5DD4467A699C1B509167762EF4786000
-:15318C004B80BAFC7327D583F15EC5BBB257756843AA6B7CB87A
-:1531A10011E7E87DA78E98F6BC4F33B6003A00D029A39FB8AE2A
-:1531B60047A57AF73BD6ED53134579776CA4B1D69FD4BEF10F46
-:1531CB00E28F0F0A9C667C0FC4977981EB03F25B806033057EB2
-:1531E0002CC1F5B78013733F24C9F7438CF15EA53CD3D317CC90
-:1531F500BC9092566ABC0F2958ABA9A2AC191E17F6B807B4DAA8
-:15320A00C881469CF3F277116FD1BCB63C0EF7712360B985B33F
-:15321F0003AA392E1C307C194F03FCB0B6EFCAED8FF4F13D009A
-:15323400077097EED56B389DCCF3C9021BD1A0476D9E4B1EE5BE
-:153249007DE9AF282F612DFAB214A7AF903CA20616751B4F47B0
-:15325E00CC73AC584B17BEA071BBBA12A7B3693B5AE23CFF9D4E
-:15327300A35761D392EA8DF56831437D5BFA3AA7435946C4B92C
-:15328800E57980A79CDB5F4A76DA773430FD4903F6C100A7902A
-:15329D00F986569B9917CAEFFBD1E783BEBCDFCFF5F9D4FF6FB5
-:1532B2002A6CF765DEC638C06DAB48991EE3B1F7B37EDFFBE0EC
-:1532C700779306C0B12FB34F7768BD6A598BB9E7EFA07E03F7AF
-:1532DC00DE7858EF520FF1D042D61B02FDCE7D798A77CF59B649
-:1532F1007F2F73DDAF894ECE7B4437B845BEDF11E7FB58A037C4
-:15330600E8CB6D5EA19D133D67D292E3DEA2C3ED70FB9169045F
-:15331B001AE4E3DEA6C7C7A04131A7419FB5CF33458BDBD220BD
-:153330006FECB5F11F1B87BDB4D2603E2DBCB14F86605F8345EF
-:15334500BB466F3CF1C946295644E36C972E901FFAB1CDDF28C2
-:15335A006C38F147FB3CA0D99F9413ADBC8B3443A03A8176A8A8
-:15336F00A3B9E7639681F290B77DBE7D4A7E32E9B1208F16DB67
-:15338400393C49D3EE0E85635F51CAEC3304EBBE1BB8953CFDD8
-:15339900E3AD79E9B77E39A7E7CBF583FBD830D7DBDC049A7748
-:1533AE000D2B1ED9C9FBE92D5C0F50D31744CCBE29D7EEA8CE2A
-:1533C300C2268CCBF4BEEF3CC701B553DFB63F98F5CDCCB8F661
-:1533D8000BF6DCCB03C9CE052413C82C7534C8C68F4658E668BC
-:1533ED00F93F66DDF41E25F728F98F3659E93F28BE32313DBE77
-:15340200CB8A8F717EE0EDBC32B1DF48F391FCB4A80F9F7B51F9
-:153417007D6E92FCD28AF573792CFED499934A2189F6A2DC9BBD
-:15342C00849D9A62F97412679ECDFDA0717EE651928FD13C2606
-:15344100A17B324B1A4E1FC8BA81878167B3EE9979E6C3C6F7CB
-:1534560031296DABFC8C7EFD558D64259C19485A7CF8EF0DCEEC
-:15346B00BB416EB37E723FC98F0D241F7D1CDE9C7CB5574F3836
-:15348000481E1D11DB275FD58C84A3CF6895F71B6FDF44FB88C7
-:153495005B73952EE32A6422A23FF657652A231F2737AE4CC7E0
-:1534AA0027F6772DF9D6D47FD60774C8D202B52FD491DC46F8DA
-:1534BF00DF91FC188C72BBDF763E727A2A1FDFEFB3AE0A9CED31
-:1534D4000994C32EB47E91CADC06BBF91968DC46344FA6562FE1
-:1534E9003C15527F10AF0B753735F13EAB88D1DC287D9F562434
-:1534FE003C4C7DCB9A19B2A6639928DFA7CB99681FEC1CBB5C2A
-:15351300D514DE66C9998B1B8B694EE3A8547859B08B0879DDE3
-:15352800D915524B23A17031953D54754F634546A631B3562FB7
-:15353D00CF0475C1D3A2767F3BA439C769FE986E326C7BD4D0FD
-:1535520001E132BFD445F2674D4874134CD1AF8C32FDA17E5706
-:1535670012FB88FF9ABF332B1CCB6ED5BF29B7F4306AAD7E2D55
-:15357C0048FD5A9302B9DF2B0B413E9709364DD94049BF30BA8B
-:15359100607C405D60DD59E0A3711C63314BBF64940957D55FDC
-:1535A60057977E96914CCED88426B1DF34FA846B6A69B5B301F8
-:1535BB0072648464F60A6158D593DD4A39E618D46FA29F14DD49
-:1535D000AF73FB344CDA31FA00FBEF212ECBC1760CB91792FC9F
-:1535E5008DB7FD5F2817B5E7DC83669A8FF23F9CCD06642ABF7B
-:1535FA00D1CA9FDBF69F257FFB1F4F4DE57DA7FCA73C0DEC3F98
-:15360F0049B566F92E8259B6E250BF1E58287F32945F1FF84BF5
-:15362400DC864D11CDA95ED259E685A33E6AE7C998735945E6DD
-:15363900A08EFE14BC8A7DF5329219DA16F42E8D903C8631F194
-:15364E004B4E9DCB608DCF68215BEEDAF47EF603E52ECFBBD91D
-:153663000F94BB9A6691BB1CE78EA890BD206FD9F2574EEE8AAB
-:153678000C37E28CBB6F25CEBABFAE35DD9CDE1FF23E9368DB97
-:15368D0056FD686331D7C99ED03CEC64A3EFD4FF22584E6A8B1D
-:1536A200334B7278704D38DB6D3CC006D104E1E9DECC1C93BEB6
-:1536B700382B6386EB62F2B87A37A1A1006E2B0C7E080B4085CD
-:1536CC006486DF091AAF3E088F243B841D6DD7D41BEF645DC0D6
-:1536E1002770566FE1B0E63D138715B3E010694EBFF32F8B4708
-:1536F6003FE457C2E3A2C089CECBC063747F5FECF733AE95B49A
-:15370B007065F3FFEDDCF2CCF4D103FA1AD6A7DD4FF39DEFFF58
-:15372000AC77A92C9F1AA5514CF30A24A74A970C9FD54E45E8FD
-:153735005348BF34B6B1CB5A99F0867AC7CA6BEA216A87341F91
-:15374A006FC01AB85466A898FBB2F401CD357E90DE07B53B5395
-:15375F00628397E6805EF6BAEA3D754515F8BD15A3DCBE14B79D
-:15377400AFF4438C1B716D60FC07E13B28DE1D142F30DE13B21D
-:153789006D3F4994066D54A638B63F6C3FC11FEDAB32736F4889
-:15379E009A28E434E736A7CE5EE16D0AF76905327786A6EC5777
-:1537B3005DE1FD43F0D5D2507EF9F2AB81696EE9D5CA696EE8E9
-:1537C8005BCDA7B2E673B8BAF3E03A990757771E5C272DB8FEA1
-:1537DD0084E072E6C175320FAE25A19976B582164FE7E0CAF8FC
-:1537F200A7C3955934CD0D9EA9A0B1B531833E90DF11C9F8DC00
-:153807004700EF8C111DC61AE711CFCC3F457C263F63283769B9
-:15381C009E9E7E5E0F73FB865D7DF192443BDCDBF85D55C7FA7E
-:15383100A00F5570866091BBFA1DE7BECD797284AFDD3CAF0766
-:15384600E5471BCDB897B5EB2B8A96791E7885E629BFD45DF29A
-:15385B00F7FAEBE5FF61C47F37939F7A463DD07F4CADD7CC6F34
-:15387000CCF37B46275698F98C52BE3E2BCF1B2B3636DECDFE86
-:15388500A681CFD3F3E2222DF2C84F778EE2EC78F2921294FFC4
-:15389A006229FC21BFD134EECFF0FD0C64B8684F0AF323A42D33
-:1538AF00C6990FE25D9C27ACD8FF3CE763F4AFA2957FE9B4EFA6
-:1538C400F92187F9DD572CCF0DD15B7770BD769DE7EF786E8FEB
-:1538D900CA714CF3761FC9FF46E405458A24D472C23F3FDF2953
-:1538EE009936FF6FF72799272924D7ABD85767D24E2E1749FE99
-:15390300B862CB455C4642D8C7908F6CD9C8929366958F201BEC
-:1539180041460A731B30391947D3CF99328E598ECCCAE5DF195D
-:15392D00F320EB92DCE492771B23D7B2AEE294962C26B8C3914D
-:153942004483BD76514E7216E224AF8166DD3AAB15DBB75F33B8
-:15395700E5AEF11FF3701DE141C20FD2B3D4555D583041E3BBD3
-:15396C00466D21A915A612712F9523A58EF5A19F04DF214FCC1D
-:15398100DFC17FB5F2ABFDE6BC7E265FF7F2FE653EC9C5DE53D5
-:153996007B492619D3C08315046BEB1FF3E55FAB8E54B7792958
-:1539AB00677BE6CDACBF96E4DD6DBF356556BE1741F09D79D3A5
-:1539C0004C531630CF6FB9ACFDDFD1F9CC4D7329F7C83CD38DB4
-:1539D500F3A3DB1DCC7D86FEE6FCB0D6B28F62EA383953423B4C
-:1539EA00F33569F6D962CF4F894F4E35ABAB683EE6EC1A547BD6
-:1539FF00D3834AA5EC6C59287FFA73580BE669A43A35771E3916
-:153A14005A4D7C24F488B16ADD29615D59E879E3505D985DEFCD
-:153A2900D2B6FC149750CD9C0F4D2F7F55BC6EE93FAB9C5BF459
-:153A3E00C7829D35F35989242D56A12F0E5D0DD843724A7FCB73
-:153A5300F57BEF4ABDDF0ADDBFC03743E8C3B84E1FB761111D23
-:153A680036D6523CBB3CF8B7927BEACE013E472F96024D9DA766
-:153A7D0003B0AF54DBF95E00F936987A72E5ACC4131BA4B1734E
-:153A9200897AA72C34632FD513AB366E90BFF8CD2EDDD4AB1599
-:153AA7007B2E5AF32BA7B443FD1585C13E682FE250BDB0372D1B
-:153ABC0043F78FFCC4D8A031067FFA7EA390B92F5BE98AC87D98
-:153AD10095FCF11E221AC35ED698C33CB3DB0B9AFB26614796E4
-:153AE600158DC02EE7354DBAF08C02BDEC729C75938E692ECFE7
-:153AFB0011751DD1769E2CB6176506349CF3A8A07E349041FC40
-:153B1000BD3B30C60996EDC0BB52AD4B258F797608B675E6F2B3
-:153B25003C87FB711F93CB8CE32B4F894B85915BD3B26811D7DC
-:153B3A00D7D6096F61BF797616FA59B09B0A3D948C1F77C324AA
-:153B4F0072F73188F2756333D14D24BC78A82DC7E89BCDB21F0F
-:153B64001B8CB9B458E6C747C52B5DEA7B3E3BDF8A5CBE492BCA
-:153B7900DF98653B7B0FF52D63458C9F1966E9B8C1F793A4B0E2
-:153B8E00265436758A995AC395811FD12AD3C4CB2FCF4C92FB54
-:153BA3004CA79449519EB14EACB3EF59B049E17D5BE596CE8A23
-:153BB8000C6C185CEE14E5AF196301933F6A284D6D26DD5F4F2A
-:153BCD00E9C3945FEB3CE60E527A13B63FE9036CB0B3BC0A7361
-:153BE20028669F5B8E744632EF187B16449508CF53E98C929B8F
-:153BF700E21F5D4DEF18E55D4873DAFB33878C48E6E9BEB68CD8
-:153C0C00DE1FA537F6A8A3F43D4EE10A9595F65AB6C4598AE365
-:153C210000F64B61F3B13393321EA17C63049B0FFC4AB8AAA7B5
-:153C3600B78BDEB0D12B5378057DAFA63C7CF4AEA1F9DA26FA1D
-:153C4B009E9807DE265C915F1BF989D4D75C24BF60C0A4476CD9
-:153C6000864D72E795B84A7C57E295C5E50579F412008F3C64E5
-:153C7500604D35280F515F3764CC464FF33C53588B3A58C9DDD8
-:153C8A00A987C2683785CDB216E53AAD757A39BF43A8CB30756C
-:153C9F001D841E3B8F149559D537C8CFB5080BE2EA947DA00895
-:153CB400C50B6B8CF2EB015E7CB5B9BE6DE2EF3106D6A9B8178D
-:153CC90061B1DCBE946DFD5DB7F21BC6EC7CD8D62E2DF8736B0E
-:153CDE00FF6BEBA0B685BE7B6467BB2B074FB3BE10E310C27EAD
-:153CF30063EAC9D7DBFD13F9457F0E5DD365CB5D046B8C997058
-:153D0800DBF4E6772A5AE9026CF972B6B599E76FEB8B230DE54F
-:153D1D005552CA5A7918F22A0ADC8A2FB46F9F30759E439A7424
-:153D3200501D4772753C7701753CA2AE8149D46F0EEB9317007C
-:153D4700306C5F99FB57F2CF281AFD23F48FD23F46FF2DF48FD5
-:153D5C00D35FA77F8AFEA3F41FFF9919976DED36EB6A9EF9E018
-:153D71006E7D867B74863B3DC33D39C32DBD36DD1D9CE18ECEF0
-:153D8600706F99E1D667B8475FCB3B9342F86913A6DBB78880A5
-:153D9B0076BED19C5DB049AA97BFEBB85ACACF365BF9548E74A6
-:153DB000626D684D6C43D87F7258AFBD083A4DE14D21F726FA49
-:153DC5006FA37F92FE7DF41FA1FF09FA9FA1FF65FA4FD0FFC613
-:153DDA0045332E3B36CCF196B2E94F6EE04DCF73036FF13C37CD
-:153DEF00F0B625CF0DBCC5F2DCC05B34CF0DBC45F2DCC05B3084
-:153E0400CF0DBCC9F9E5BF36657F93974F6E7F73CA006F433FFD
-:153E19005A7C62C33DB67D048EB3D9EC7F107E3D2C0FBF33E3C5
-:153E2E00FC33C3D1F78C91FC42B2947E7A0E734357B658165B92
-:153E4300FA04E676D137F5332D1E1A238BE5459FBD48E36205B5
-:153E58007D838EA2B44BDD5C467DD65C56F218AB6989CC35FBFF
-:153E6D00B407E83B3CD7ECCB2A59CD725BFF49869D72DCFB4582
-:153E820079006793A5347E53FA8952C80E2F4ED9E92019F152A8
-:153E970055178DCB872123E8932B9CCB4F531CB96CF6F1C91EC9
-:153EAC00E7B0378FF1689299363AEC781E2A77A7659780E49DE9
-:153EC100E597292F3797F7A7F7631504EF7609E321E48BDDFA81
-:153ED6009E18CEA5BDA8EF881CE6F5777FC6D92EC9753AFA7C2A
-:153EEB009C112A5B79006BB9DA9639D89F1AD499FEA2EE178621
-:153F0000D516D6CDE377BB87156141138DAD83460DD54D243929
-:153F150097DB268FEED52ECEC538A6774A65499EC7988764486F
-:153F2A004AE3925FD4451A8BDDA558571EA4BEFC450378AE91FA
-:153F3F004CF903B0A63DD3E5BB9139ACE434E5979A8371A6469B
-:153F54004FF0B1A9968F4D380F2B2C08727B0A976F66DDC5F1B1
-:153F6900AE1667B45695E56AFD8D15C2F2CD94E6CC5C5326B23D
-:153F7E00F1E0B5740FA7F477653D4EBC29A57772BB7EC85FBA96
-:153F9300F02905E78C00B33732B854245945A43C2729CF769297
-:153FA800A9708E49E4BAD87C1C862D490379A0BD8BB161C323AE
-:153FBD009BF7BA66B91EFF8B9A9FFA7C51FE9E81F8B8FB976419
-:153FD200B00D1305243FE3CEC7BCFBA71294C7DFC588F762B02A
-:153FE700B561DA75FFCF6CB0C5436E8C33C065A498B9DF269E84
-:153FFC007D8B75B5D8B09B3819E17D13F2E0677ED892161BEE59
-:15401100EB0437F45D890E25B02303DE100907176F64DDF6BD19
-:1540260005F9750AE4D5C91E6F502FAEB740FD1DE0728ED39C6C
-:15403B00233AA6F13A4883FD34F7A07AEF9EB2731CEBD27ADD53
-:15405000CCBD8660B5D37C2ED2DD029D8B9F1CF9E5618F5C6F8D
-:15406500F8B9AEB24A6D76B561C32ECA87F9BC0DDF18E3250BE4
-:15407A00476B2D386D3D4E0B977EEC15D7539837262EF7154C5C
-:15408F00B50DC95DA39AF7EBF6F1F28C5343CB59380C1D8CAC5D
-:1540A400B96796CD7EEB5498FC123AEE46294B3FA9965DB84765
-:1540B900914EAD542B65472BD7C94EEF864E94DB9D3F6E5A70DC
-:1540CE0036B0257C5C1E7531F715AAE32F88F7D8D6E7795E88FB
-:1540E300EF425F1F1EE2F7AEF0F34BADF5FCDC0EC9E1FA77E3C0
-:1540F800832D38D303FC3E8D7B0B49A6B5F0EEF5669C2DF321EE
-:15410D00AF674EEAD71F7C69F92FC88D3A8B99E1D9F98D706485
-:15412200F29BC93F9ECC71FD40C6D91E681DE6E5A19D99F4946F
-:15413700394EEDFE5A6C5D82B51884EB95E38361BBBE51613A5F
-:15414C005F42CFE6664C6801DC36DEDE1C1FE27D8027467D8299
-:1541610055CE2F288F8F5AA7CA8C7379B0783A2FB6BD9D75AFA9
-:15417600263A7A62797591BFA7439F3257179AC398F5AFCDD556
-:15418B00057088AD9FE675E1788A0D7E209E9C528D6AAD9364C6
-:1541A000515FD7A9FD5C671573A30187D54F100EA84F77E7EEE2
-:1541B5004C487769E7FE68EB0FD7F33A411FDC4EFB08A503BD44
-:1541CA00FB284D7E3FB3ED7D935F3DF2615D8E0D695F8F0C8732
-:1541DF0050367851DA3E669E8B4C0FD37CA11BFB9D567D877409
-:1541F400BBAD88992386E41E56CBA8CF3D48732B4F06FD8A6685
-:15420900D5FFC454FD892FE6B79EE4F59F4F74B3E89B1B438A6B
-:15421E00D1DFF1F6A0C1DE7FAE3DDC840D9FF0B169EDE1B7E3CD
-:15423300C7B85D1FE0ACE121D35E01CA798EED6D215E36DB49B7
-:154248006BB7C9C7046B4F1C67F0F5CE03B8B3217A7206BD7508
-:15425D0093DE5563CB0D727B624379743DA623CD145D87AC7ADB
-:154272002579BDD0E794B5EEE5755A98129783F76D5AE6F89743
-:15428700FCC414EE0A49E83DD4FECC7B42CC7AFC35F1A7CD8B26
-:15429C005E36D6524AE503961B04CB42E2BD6345D379EFDCFF00
-:1542B10026BE93F3E08B117CB13CF8641B3EB35FE2F86CEDE6C9
-:1542C600F0E5F70BF1EBA6CE03DE62CCBC07588F24B694E68D22
-:1542DB0039F1776D5ECACD5DBD2CDCCB710B5B2C7D93D9921C44
-:1542F000EF916CF32B9C55785EBC478A99F36F6FE4B0FA32A58C
-:15430500F1578BED6517FA1487C0CAE6212C7D4C972EA414DCF3
-:15431A00F17094609530E610FF6C06AFBA20776A5A2070A253C4
-:15432F00261929FE646FFB0EF827DF411FBEC375EE24D7DB9887
-:15434400A8DABB8CA5C7742328B4239FCAC45ED89CF3CDC7FD16
-:1543590068E49FC07AB5B4D710293FECCD7337952BF23DC1BDA2
-:15436E00064F87B2F4BDD07F9E87BB95BBCC343BE234A7C7BA03
-:15438300886BAD063D0E3FD7A1B3E6F412BF4F604CDFD9A6299D
-:1543980005EBAEABF16CD6DBFB794D419D454A539938B201F0C4
-:1543AD0063EC042C80CD4F75692218FC174E28F36354D7B3DF2C
-:1543C20056BD4CA33E3CA57C1FE38295A77876402519D88B7446
-:1543D70076DD7B28FFE4BEE3FC1E66F00B8F1B3DB6C3B5FB1DAF
-:1543EC003503D8A84EA80BBB3EA0812EC003D34F6AC06723D44E
-:154401005C28DCC6C5E51C1ECCB27278C07A6DDAC443E08762E3
-:154416004B721D742486B52EF2EF457B219CC00F6B1B18834D1B
-:15442B00784F120E8E28C8BF60DDEFD5ED1C0F479432AA1F70F9
-:1544400020E15C15D5DB853B83A82CD84C0E52F99581894EDBE9
-:154455001EB2699F27AEE9C4837B162495B7D884B628C8FEB2C2
-:15446A0046163F97B3D7F917DC1E32B79BD4C6D70896F49B67EE
-:15447F005B933C5D24B30B7756B8E98D7D6023F6EE149FE33C0E
-:1544940023D6AAC0A3F5984B439736D8A4E937B89E663F8DB948
-:1544A900E3F15A67BBE00AAB623CA40E10AC55CA28EEB9D475D6
-:1544BE00F9402B9F9F521C89FA0E8FFCC51697FCB51649FED26B
-:1544D30072312A63BC1EBF4AF230DE9D984B455FE43695FDCD24
-:1544E800B261E60F9971703C4861F594BE96D2D7507AF855C8F3
-:1544FD005F6AB1F3207E6AF150B88BC2AFAEF81ACFCFC3E766D2
-:15451200BFDB61C7D9827208265FF3A499B76EC20D1C85D136AC
-:1545270008CE7AF9D556B1396864281CEB05AD349F1692215583
-:15453C008A630FD88C8FFC8807FC22E58378FC7C020EA4C7CC33
-:15455100FB80D0869B9835BF06CF4B435639239DB02952CE6D45
-:154566004F987E9833C18FEB1B9A67316E992F098249CF9C3FD4
-:15457B00E55F61CF7FB85E2A95CFEF384B195BDEBD75CE659ECD
-:154590007D1DD11186FE07772CF8ADFEC69FFE8EEABBF01D0521
-:1545A500F2AAAFF59879AF1085F930F767C731BE6BAFFCB680E3
-:1545BA00558C1F6FDC42E39EC79A67983AB0A69C833B095CF13E
-:1545CF00234BE793ECE943BEC111138E5C3F99E4F0F9228930CA
-:1545E400B76F426EE4591E196AACC8CB333777A13E97A7B7FA20
-:1545F900CFDF5AFC8C7A606E47B079AFF2359D9AA934F9E76932
-:15460E00F9FDE74F69FF384BBAC333D211BFEBB3AD27453287BE
-:15462300B4FF394BFACD1F21FDB559D2856F0BEF216D6296747F
-:15463800EFB1DB9737F9FE8CFD27ACEFE4F31FD6FCDF9DBEBE22
-:15464D0031335CFAC38787C76F17FE7F3BFF19E19E7CFEFFB008
-:15466200F581FF1FFE4F0A97F2F0EF9DD92FFD3F03BFC51FD198
-:154677008F971EED6B9E287359ECCBDC46536D67B7147B641541
-:15468C0035454FD9A3AA46E1B82BDA73EF6E15ED14E3A4A76CC6
-:1546A100933A67F56E55961FD7E6DCDBA5FAD6698A47A8567DC5
-:1546B600A5D56A82E416AB4D6FB84163B35456AB22BF7F6A5E9C
-:1546CB0087EED314EC110BEB30778969D0A813E582F6AF539F69
-:1546E000ECF754ABC5EBEAD5E7EEAB53AAD6D52901CF236A774F
-:1546F500C1A714DCC5B8488CD973151FE28BC22754BEF6B0BABF
-:15470A008BF71DE843AA4A130AF413ED702F0FAF539D65712E7A
-:15471F00DF553D1057F9FE1264E459605865C15042301C22180D
-:15473400FC79E5A3DC4A8201F178BE947F7ED937AC7C27F3F2CE
-:15474900CD665FC97A60EB20C4DAD7331640DEF18298067C644E
-:15475E009999D7DD8CCD9B4FB8F15099EEB57584A36A6591A745
-:154773005EADF88CD8EE645D1D557F25B61F9A9BE034C0BA4825
-:1547880090E0C01EDC5DDC76DA14EC5EAE07833DB8F813BC6EA9
-:15479D0004D3390BA631D4DD73BF5AB56FBD2A94DAB0656FDA01
-:1547B200B0B5106CE59E6AEE1F2701D1A697BBB45EF5709876A1
-:1547C7002B8B4A13EAFE9D7B72BC003CFF219BB56060BC9EB026
-:1547DC000966EE374F3E8172D3161CB81FEC0C7DCFD54C18CA91
-:1547F100F6D5A865541EEAD66E9D4D81D226C74BD1145EAA8851
-:15480600774AD6B6AAFE75610ECFAE82DD4A31E1A5C493500B35
-:15481B0059A2638FC59B8B79DDA7CA9DA0B2740A2B237C11DDC4
-:15483000BD360CA07D55DBFD0A64A1AA75F72B33E94F8DA8AC8E
-:1548450098EF1B4CB5A7AA33033C9E70BE5EF53F105345F6B844
-:15485A003A87E23E27B080D3FA36E8BB641DC149FC52521A56D0
-:15486F00B51F352B87CE362B25E7D7AA7E8DFCF6AD56B5CFAF8A
-:1548840021DE5FA38007FC84D3AAB5262EC498D02EB34D9CB7E4
-:15489900494EF3398587544FAC0077EBF8DCD8ABA96CEB9C2374
-:1548AE003CAC7AC455AA67259577EF63AA67F51A756FC12A05F2
-:1548C300FA1EE2CAA9F84501F31C188F9F0899F15FFEAAEA3924
-:1548D800DDACEEDD19529C34EE96FDE811A5EA3305EDB0BDEDB4
-:1548ED008A873ADCE3CD1D07610F4D0BA955E71F528573CDAA2E
-:15490200467105D7142DB6A28D07F8B9B10DB005E4EAA274A731
-:154917009A3BF85CAF89B51796053B8ACA9A3AAA92EB955DD473
-:15492C0037C8E4DF43EFBF449FF3F71B554F4FB30AB95A961F63
-:15494100866CE7F224BEAA0A6B1F5779D8CBCD141E52F712CEDB
-:15495600407FF038E624C5FF5168AF3A4F38D4BA54FFF9AFAA3B
-:15496B0025E776731ED84F3C3087685F1CD13AF2FB25D01DB469
-:15498000E33AF5164DC193F7122CED809FF08CBB49D7D177A2D7
-:1549950060B33287CA01FCDD3BCDEF5537B37EF44BB61B7169FF
-:1549AA006CD83090C51A8EC9DB064DAD803FF47B34E79A67F3A6
-:1549BF00D5368AC3CF47100C9B67E80797FDA842A93A574EB8AA
-:1549D4002D5767E3A337D9141FFD9A997C041A14131F053C9B2E
-:1549E900395E9EB378097CE4D7C86F062FED8EFFF9C6E2C026AC
-:1549FE00A24FAC73377B78E39C40B453F03CA6DAEE92C8C31BD2
-:154A130041A7395DEB3BD8D9F60EFB5D75CDC1EF702A8EAFEF25
-:154A280028196FEF10DC44F34F546B4EA2C34DA23DF07737A785
-:154A3D0085A3BD44DB4174788CE8B087F7E9F9B428B0689130FA
-:154A5200EF8EF209AE4F50D9D10D67385DC037D10D6333E84242
-:154A670034F13E60D185FA5DEFFA3CBADC994797B7B8CEEF5418
-:154A7C00DBDE49EDBA378F4EDCFE38F100FCB75BB4BA803BFF2F
-:154A91002CDA6CFA98F4B894478FBFB3E88136EDB768710B1D40
-:154AA6008836F9B4288A7C65636164FD46B68DB57BC6BFD23197
-:154ABB0047DAD451C4FECDC6E2F8BFEDF08C3FCCDD557FC5DBED
-:154AD000ABD7C3C81D799CE35DDC5EAD39A8EFBD5914D58A6DA5
-:154AE500BC533B2DF1ECA4FEEF5FA9256B9F9C86F7E2D9F09E3E
-:154AFA005C0C9AE7E13DC6F16ED7371FFFD4E77BEFB5F08F35C1
-:154B0F0011B4131BFFDE3CFC3BF8DA8689DF5E0BBFA5E8A7280A
-:154B2400AC92E65AF96DC04EFF261F174C9A211DE8A658743081
-:154B3900711E9E06CBB708CF9E94D0FE32BD13D4F714521EB8D2
-:154B4E00FFFDD0171F51ABD6B52A52C152A5A8E01E053CECA121
-:154B6300BE879D6DEE38F4530A3BBF56F1167C5E71177CC10C75
-:154B7800135675B0FBD674EC8A39DA01D762E084CA261E292BCC
-:154B8D00941D7C8C843FECB9D87314940FBBA705F6D86D8D1FA2
-:154BA20088075D7FC0F55A36EBA338B9B6FF32B57D8C5D9768CE
-:154BB7003A89F512C80734D6F94E5BF1BF4FDF55D744BCBD27B6
-:154BCC00785E4975BF63E8117EC65230EF62A69125EB8D0C3DF1
-:154BE1006A308DEB88C1DF37B5DE5AFC7F00E871AED038A00037
-:014BF60000BE
-:00000001FF
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c
index b1d063cc4fb..6dd3f591996 100644
--- a/drivers/atm/suni.c
+++ b/drivers/atm/suni.c
@@ -1,8 +1,14 @@
-/* drivers/atm/suni.c - PMC PM5346 SUNI (PHY) driver */
+/*
+ * drivers/atm/suni.c - S/UNI PHY driver
+ *
+ * Supports the following:
+ * PMC PM5346 S/UNI LITE
+ * PMC PM5350 S/UNI 155 ULTRA
+ * PMC PM5355 S/UNI 622
+ */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
@@ -29,15 +35,6 @@
#define DPRINTK(format,args...)
#endif
-
-struct suni_priv {
- struct k_sonet_stats sonet_stats; /* link diagnostics */
- int loop_mode; /* loopback mode */
- struct atm_dev *dev; /* device back-pointer */
- struct suni_priv *next; /* next SUNI */
-};
-
-
#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
#define PUT(val,reg) dev->ops->phy_put(dev,val,SUNI_##reg)
@@ -155,25 +152,105 @@ static int get_diag(struct atm_dev *dev,void __user *arg)
static int set_loopback(struct atm_dev *dev,int mode)
{
unsigned char control;
+ int reg, dle, lle;
+
+ if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
+ reg = SUNI_MCM;
+ dle = SUNI_MCM_DLE;
+ lle = SUNI_MCM_LLE;
+ } else {
+ reg = SUNI_MCT;
+ dle = SUNI_MCT_DLE;
+ lle = SUNI_MCT_LLE;
+ }
- control = GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE);
+ control = dev->ops->phy_get(dev, reg) & ~(dle | lle);
switch (mode) {
case ATM_LM_NONE:
break;
case ATM_LM_LOC_PHY:
- control |= SUNI_MCT_DLE;
+ control |= dle;
break;
case ATM_LM_RMT_PHY:
- control |= SUNI_MCT_LLE;
+ control |= lle;
break;
default:
return -EINVAL;
}
- PUT(control,MCT);
+ dev->ops->phy_put(dev, control, reg);
PRIV(dev)->loop_mode = mode;
return 0;
}
+/*
+ * SONET vs. SDH Configuration
+ *
+ * Z0INS (register 0x06): 0 for SONET, 1 for SDH
+ * ENSS (register 0x3D): 0 for SONET, 1 for SDH
+ * LEN16 (register 0x28): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
+ * LEN16 (register 0x50): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
+ * S[1:0] (register 0x46): 00 for SONET, 10 for SDH
+ */
+
+static int set_sonet(struct atm_dev *dev)
+{
+ if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
+ PUT(GET(RPOP_RC) & ~SUNI_RPOP_RC_ENSS, RPOP_RC);
+ PUT(GET(SSTB_CTRL) & ~SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
+ PUT(GET(SPTB_CTRL) & ~SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
+ }
+
+ REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
+ SUNI_TPOP_S_SONET, TPOP_APM);
+
+ return 0;
+}
+
+static int set_sdh(struct atm_dev *dev)
+{
+ if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
+ PUT(GET(RPOP_RC) | SUNI_RPOP_RC_ENSS, RPOP_RC);
+ PUT(GET(SSTB_CTRL) | SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
+ PUT(GET(SPTB_CTRL) | SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
+ }
+
+ REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
+ SUNI_TPOP_S_SDH, TPOP_APM);
+
+ return 0;
+}
+
+
+static int get_framing(struct atm_dev *dev, void __user *arg)
+{
+ int framing;
+ unsigned char s;
+
+
+ s = (GET(TPOP_APM) & SUNI_TPOP_APM_S) >> SUNI_TPOP_APM_S_SHIFT;
+ if (s == SUNI_TPOP_S_SONET)
+ framing = SONET_FRAME_SONET;
+ else
+ framing = SONET_FRAME_SDH;
+
+ return put_user(framing, (int __user *) arg) ? -EFAULT : 0;
+}
+
+static int set_framing(struct atm_dev *dev, void __user *arg)
+{
+ int mode;
+
+ if (get_user(mode, (int __user *) arg))
+ return -EFAULT;
+
+ if (mode == SONET_FRAME_SONET)
+ return set_sonet(dev);
+ else if (mode == SONET_FRAME_SDH)
+ return set_sdh(dev);
+
+ return -EINVAL;
+}
+
static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
@@ -188,14 +265,16 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
case SONET_GETDIAG:
return get_diag(dev,arg);
case SONET_SETFRAMING:
- if ((int)(unsigned long)arg != SONET_FRAME_SONET) return -EINVAL;
- return 0;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ return set_framing(dev, arg);
case SONET_GETFRAMING:
- return put_user(SONET_FRAME_SONET,(int __user *)arg) ?
- -EFAULT : 0;
+ return get_framing(dev, arg);
case SONET_GETFRSENSE:
return -EINVAL;
case ATM_SETLOOP:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
return set_loopback(dev,(int)(unsigned long)arg);
case ATM_GETLOOP:
return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
@@ -229,10 +308,6 @@ static int suni_start(struct atm_dev *dev)
unsigned long flags;
int first;
- if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL)))
- return -ENOMEM;
-
- PRIV(dev)->dev = dev;
spin_lock_irqsave(&sunis_lock,flags);
first = !sunis;
PRIV(dev)->next = sunis;
@@ -293,16 +368,21 @@ int suni_init(struct atm_dev *dev)
{
unsigned char mri;
+ if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL)))
+ return -ENOMEM;
+ PRIV(dev)->dev = dev;
+
mri = GET(MRI); /* reset SUNI */
+ PRIV(dev)->type = (mri & SUNI_MRI_TYPE) >> SUNI_MRI_TYPE_SHIFT;
PUT(mri | SUNI_MRI_RESET,MRI);
PUT(mri,MRI);
PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */
- REG_CHANGE(SUNI_TPOP_APM_S,SUNI_TPOP_APM_S_SHIFT,SUNI_TPOP_S_SONET,
- TPOP_APM); /* use SONET */
+ set_sonet(dev);
REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP,
TACP_IUCHP); /* idle cells */
PUT(SUNI_IDLE_PATTERN,TACP_IUCPOP);
dev->phy = &suni_ops;
+
return 0;
}
diff --git a/drivers/atm/suni.h b/drivers/atm/suni.h
index d14c835abc9..7e3e656b399 100644
--- a/drivers/atm/suni.h
+++ b/drivers/atm/suni.h
@@ -1,14 +1,15 @@
-/* drivers/atm/suni.h - PMC PM5346 SUNI (PHY) declarations */
+/*
+ * drivers/atm/suni.h - S/UNI PHY driver
+ */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
#ifndef DRIVER_ATM_SUNI_H
#define DRIVER_ATM_SUNI_H
#include <linux/atmdev.h>
#include <linux/atmioc.h>
-
+#include <linux/sonet.h>
/* SUNI registers */
@@ -39,7 +40,8 @@
#define SUNI_RLOP_LFM 0x1F /* RLOP Line FEBE MSB */
#define SUNI_TLOP_CTRL 0x20 /* TLOP Control */
#define SUNI_TLOP_DIAG 0x21 /* TLOP Diagnostic */
- /* 0x22-0x2F reserved */
+ /* 0x22-0x27 reserved */
+#define SUNI_SSTB_CTRL 0x28
#define SUNI_RPOP_SC 0x30 /* RPOP Status/Control */
#define SUNI_RPOP_IS 0x31 /* RPOP Interrupt Status */
/* 0x32 reserved */
@@ -52,6 +54,7 @@
#define SUNI_RPOP_PFM 0x3B /* RPOP Path FEBE MSB */
/* 0x3C reserved */
#define SUNI_RPOP_PBC 0x3D /* RPOP Path BIP-8 Configuration */
+#define SUNI_RPOP_RC 0x3D /* RPOP Ring Control (PM5355) */
/* 0x3E-0x3F reserved */
#define SUNI_TPOP_CD 0x40 /* TPOP Control/Diagnostic */
#define SUNI_TPOP_PC 0x41 /* TPOP Pointer Control */
@@ -82,7 +85,8 @@
#define SUNI_TACP_TCC 0x65 /* TACP Transmit Cell Counter */
#define SUNI_TACP_TCCM 0x66 /* TACP Transmit Cell Counter MSB */
#define SUNI_TACP_CFG 0x67 /* TACP Configuration */
- /* 0x68-0x7F reserved */
+#define SUNI_SPTB_CTRL 0x68 /* SPTB Control */
+ /* 0x69-0x7F reserved */
#define SUNI_MT 0x80 /* Master Test */
/* 0x81-0xFF reserved */
@@ -94,9 +98,18 @@
#define SUNI_MRI_ID_SHIFT 0
#define SUNI_MRI_TYPE 0x70 /* R, SUNI type (lite is 011) */
#define SUNI_MRI_TYPE_SHIFT 4
+#define SUNI_MRI_TYPE_PM5346 0x3 /* S/UNI 155 LITE */
+#define SUNI_MRI_TYPE_PM5347 0x4 /* S/UNI 155 PLUS */
+#define SUNI_MRI_TYPE_PM5350 0x7 /* S/UNI 155 ULTRA */
+#define SUNI_MRI_TYPE_PM5355 0x1 /* S/UNI 622 */
#define SUNI_MRI_RESET 0x80 /* RW, reset & power down chip
0: normal operation
1: reset & low power */
+
+/* MCM is reg 0x4 */
+#define SUNI_MCM_LLE 0x20 /* line loopback (PM5355) */
+#define SUNI_MCM_DLE 0x10 /* diagnostic loopback (PM5355) */
+
/* MCT is reg 5 */
#define SUNI_MCT_LOOPT 0x01 /* RW, timing source, 0: from
TRCLK+/- */
@@ -144,6 +157,12 @@
/* TLOP_DIAG is reg 0x21 */
#define SUNI_TLOP_DIAG_DBIP 0x01 /* insert line BIP err (continuously) */
+/* SSTB_CTRL is reg 0x28 */
+#define SUNI_SSTB_CTRL_LEN16 0x01 /* path trace message length bit */
+
+/* RPOP_RC is reg 0x3D (PM5355) */
+#define SUNI_RPOP_RC_ENSS 0x40 /* enable size bit */
+
/* TPOP_DIAG is reg 0x40 */
#define SUNI_TPOP_DIAG_PAIS 0x01 /* insert STS path alarm ind (cont) */
#define SUNI_TPOP_DIAG_DB3 0x02 /* insert path BIP err (continuously) */
@@ -191,6 +210,9 @@
pattern */
#define SUNI_TACP_IUCHP_GFC_SHIFT 4
+/* SPTB_CTRL is reg 0x68 */
+#define SUNI_SPTB_CTRL_LEN16 0x01 /* path trace message length */
+
/* MT is reg 0x80 */
#define SUNI_MT_HIZIO 0x01 /* RW, all but data bus & MP interface
tri-state */
@@ -205,6 +227,14 @@
#ifdef __KERNEL__
+struct suni_priv {
+ struct k_sonet_stats sonet_stats; /* link diagnostics */
+ int loop_mode; /* loopback mode */
+ int type; /* phy type */
+ struct atm_dev *dev; /* device back-pointer */
+ struct suni_priv *next; /* next SUNI */
+};
+
int suni_init(struct atm_dev *dev);
#endif
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 424995073c6..49f274197b1 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1880,11 +1880,11 @@ static int __init atari_floppy_init (void)
if (!MACH_IS_ATARI)
/* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
- return -ENXIO;
+ return -ENODEV;
if (MACH_IS_HADES)
/* Hades doesn't have Atari-compatible floppy */
- return -ENXIO;
+ return -ENODEV;
if (register_blkdev(FLOPPY_MAJOR,"fd"))
return -EBUSY;
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 075598e1c50..a235ca78746 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -71,6 +71,7 @@ config BT_HCIUART_H4
config BT_HCIUART_BCSP
bool "BCSP protocol support"
depends on BT_HCIUART
+ select BITREVERSE
help
BCSP (BlueCore Serial Protocol) is serial protocol for communication
between Bluetooth device and host. This protocol is required for non
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 696f7528f02..4d37bb312ee 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -39,6 +39,8 @@
#include <linux/signal.h>
#include <linux/ioctl.h>
#include <linux/skbuff.h>
+#include <linux/bitrev.h>
+#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@ -124,27 +126,6 @@ static void bcsp_crc_update(u16 *crc, u8 d)
*crc = reg;
}
-/*
- Get reverse of generated crc
-
- Implementation note
- The crc generator (bcsp_crc_init() and bcsp_crc_update())
- creates a reversed crc, so it needs to be swapped back before
- being passed on.
-*/
-static u16 bcsp_crc_reverse(u16 crc)
-{
- u16 b, rev;
-
- for (b = 0, rev = 0; b < 16; b++) {
- rev = rev << 1;
- rev |= (crc & 1);
- crc = crc >> 1;
- }
-
- return (rev);
-}
-
/* ---- BCSP core ---- */
static void bcsp_slip_msgdelim(struct sk_buff *skb)
@@ -235,10 +216,10 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
}
if (hciextn && chan == 5) {
- struct hci_command_hdr *hdr = (struct hci_command_hdr *) data;
+ __le16 opcode = ((struct hci_command_hdr *)data)->opcode;
/* Vendor specific commands */
- if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == 0x3f) {
+ if (hci_opcode_ogf(__le16_to_cpu(opcode)) == 0x3f) {
u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
if ((desc & 0xf0) == 0xc0) {
data += HCI_COMMAND_HDR_SIZE + 1;
@@ -296,7 +277,7 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
/* Put CRC */
if (bcsp->use_crc) {
- bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
+ bcsp_txmsg_crc = bitrev16(bcsp_txmsg_crc);
bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
}
@@ -566,6 +547,11 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
bcsp->rx_skb = NULL;
}
+static u16 bscp_get_crc(struct bcsp_struct *bcsp)
+{
+ return get_unaligned_be16(&bcsp->rx_skb->data[bcsp->rx_skb->len - 2]);
+}
+
/* Recv data */
static int bcsp_recv(struct hci_uart *hu, void *data, int count)
{
@@ -624,14 +610,10 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
continue;
case BCSP_W4_CRC:
- if (bcsp_crc_reverse(bcsp->message_crc) !=
- (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
- bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
-
+ if (bitrev16(bcsp->message_crc) != bscp_get_crc(bcsp)) {
BT_ERR ("Checksum failed: computed %04x received %04x",
- bcsp_crc_reverse(bcsp->message_crc),
- (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
- bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
+ bitrev16(bcsp->message_crc),
+ bscp_get_crc(bcsp));
kfree_skb(bcsp->rx_skb);
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index e5cd856a2fe..69df187d74c 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -282,8 +282,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
/* FIXME: why is this needed. Note don't use ldisc_ref here as the
open path is before the ldisc is referencable */
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
+ if (tty->ldisc.ops->flush_buffer)
+ tty->ldisc.ops->flush_buffer(tty);
tty_driver_flush_buffer(tty);
return 0;
@@ -514,7 +514,7 @@ static unsigned int hci_uart_tty_poll(struct tty_struct *tty,
static int __init hci_uart_init(void)
{
- static struct tty_ldisc hci_uart_ldisc;
+ static struct tty_ldisc_ops hci_uart_ldisc;
int err;
BT_INFO("HCI UART driver ver %s", VERSION);
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6bff9d87dc5..e991dc85f2f 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -762,7 +762,7 @@ static int cy_next_channel; /* next minor available */
/*
* This is used to look up the divisor speeds and the timeouts
* We're normally limited to 15 distinct baud rates. The extra
- * are accessed via settings in info->flags.
+ * are accessed via settings in info->port.flags.
* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
* 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
* HI VHI
@@ -1003,7 +1003,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
cy_writeb(base_addr + (CyCAR << index), save_xir);
/* if there is nowhere to put the data, discard it */
- if (info->tty == NULL) {
+ if (info->port.tty == NULL) {
if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
CyIVRRxEx) { /* exception */
data = readb(base_addr + (CyRDSR << index));
@@ -1015,7 +1015,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
goto end;
}
/* there is an open port for this data */
- tty = info->tty;
+ tty = info->port.tty;
if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
CyIVRRxEx) { /* exception */
data = readb(base_addr + (CyRDSR << index));
@@ -1041,7 +1041,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
readb(base_addr + (CyRDSR <<
index)), TTY_BREAK);
info->icount.rx++;
- if (info->flags & ASYNC_SAK)
+ if (info->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (data & CyFRAME) {
tty_insert_flip_char(tty,
@@ -1145,7 +1145,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
goto end;
}
info = &cinfo->ports[channel + chip * 4];
- if (info->tty == NULL) {
+ if (info->port.tty == NULL) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) & ~CyTxRdy);
goto end;
@@ -1190,13 +1190,13 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
}
goto done;
}
- if (info->xmit_buf == NULL) {
+ if (info->port.xmit_buf == NULL) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto done;
}
- if (info->tty->stopped || info->tty->hw_stopped) {
+ if (info->port.tty->stopped || info->port.tty->hw_stopped) {
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
@@ -1211,7 +1211,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
* character. This is necessary because there may not be room
* for the two chars needed to send a NULL.)
*/
- outch = info->xmit_buf[info->xmit_tail];
+ outch = info->port.xmit_buf[info->xmit_tail];
if (outch) {
info->xmit_cnt--;
info->xmit_tail = (info->xmit_tail + 1) &
@@ -1232,7 +1232,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
}
done:
- tty_wakeup(info->tty);
+ tty_wakeup(info->port.tty);
end:
/* end of service */
cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
@@ -1256,7 +1256,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
mdm_change = readb(base_addr + (CyMISR << index));
mdm_status = readb(base_addr + (CyMSVR1 << index));
- if (!info->tty)
+ if (!info->port.tty)
goto end;
if (mdm_change & CyANY_DELTA) {
@@ -1273,29 +1273,29 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
wake_up_interruptible(&info->delta_msr_wait);
}
- if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) {
+ if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
if (!(mdm_status & CyDCD)) {
- tty_hangup(info->tty);
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
+ tty_hangup(info->port.tty);
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
- if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) {
- if (info->tty->hw_stopped) {
+ if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
+ if (info->port.tty->hw_stopped) {
if (mdm_status & CyCTS) {
/* cy_start isn't used
because... !!! */
- info->tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) |
CyTxRdy);
- tty_wakeup(info->tty);
+ tty_wakeup(info->port.tty);
}
} else {
if (!(mdm_status & CyCTS)) {
/* cy_stop isn't used
because ... !!! */
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) &
~CyTxRdy);
@@ -1449,7 +1449,7 @@ static void cyz_handle_rx(struct cyclades_port *info,
struct BUF_CTRL __iomem *buf_ctrl)
{
struct cyclades_card *cinfo = info->card;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned int char_count;
int len;
#ifdef BLOCKMOVE
@@ -1542,7 +1542,7 @@ static void cyz_handle_tx(struct cyclades_port *info,
struct BUF_CTRL __iomem *buf_ctrl)
{
struct cyclades_card *cinfo = info->card;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
u8 data;
unsigned int char_count;
#ifdef BLOCKMOVE
@@ -1585,7 +1585,7 @@ static void cyz_handle_tx(struct cyclades_port *info,
memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr +
tx_put),
- &info->xmit_buf[info->xmit_tail],
+ &info->port.xmit_buf[info->xmit_tail],
small_count);
tx_put = (tx_put + small_count) & (tx_bufsize - 1);
@@ -1597,7 +1597,7 @@ static void cyz_handle_tx(struct cyclades_port *info,
}
#else
while (info->xmit_cnt && char_count) {
- data = info->xmit_buf[info->xmit_tail];
+ data = info->port.xmit_buf[info->xmit_tail];
info->xmit_cnt--;
info->xmit_tail = (info->xmit_tail + 1) &
(SERIAL_XMIT_SIZE - 1);
@@ -1642,7 +1642,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
special_count = 0;
delta_count = 0;
info = &cinfo->ports[channel];
- tty = info->tty;
+ tty = info->port.tty;
if (tty == NULL)
continue;
@@ -1668,15 +1668,15 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
case C_CM_MDCD:
info->icount.dcd++;
delta_count++;
- if (info->flags & ASYNC_CHECK_CD) {
+ if (info->port.flags & ASYNC_CHECK_CD) {
if ((fw_ver > 241 ? ((u_long) param) :
readl(&ch_ctrl->rs_status)) &
C_RS_DCD) {
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
} else {
- tty_hangup(info->tty);
- wake_up_interruptible(&info->open_wait);
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
+ tty_hangup(info->port.tty);
+ wake_up_interruptible(&info->port.open_wait);
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
}
}
break;
@@ -1814,7 +1814,7 @@ static void cyz_poll(unsigned long arg)
for (port = 0; port < cinfo->nports; port++) {
info = &cinfo->ports[port];
- tty = info->tty;
+ tty = info->port.tty;
buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
if (!info->throttle)
@@ -1853,22 +1853,22 @@ static int startup(struct cyclades_port *info)
spin_lock_irqsave(&card->card_lock, flags);
- if (info->flags & ASYNC_INITIALIZED) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
free_page(page);
goto errout;
}
if (!info->type) {
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
free_page(page);
goto errout;
}
- if (info->xmit_buf)
+ if (info->port.xmit_buf)
free_page(page);
else
- info->xmit_buf = (unsigned char *)page;
+ info->port.xmit_buf = (unsigned char *)page;
spin_unlock_irqrestore(&card->card_lock, flags);
@@ -1909,10 +1909,10 @@ static int startup(struct cyclades_port *info)
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) | CyRxData);
- info->flags |= ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
info->breakon = info->breakoff = 0;
memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
@@ -1994,9 +1994,9 @@ static int startup(struct cyclades_port *info)
/* enable send, recv, modem !!! */
- info->flags |= ASYNC_INITIALIZED;
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ info->port.flags |= ASYNC_INITIALIZED;
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
info->breakon = info->breakoff = 0;
memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
@@ -2065,7 +2065,7 @@ static void shutdown(struct cyclades_port *info)
void __iomem *base_addr;
int chip, channel, index;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
card = info->card;
@@ -2087,14 +2087,14 @@ static void shutdown(struct cyclades_port *info)
/* Clear delta_msr_wait queue to avoid mem leaks. */
wake_up_interruptible(&info->delta_msr_wait);
- if (info->xmit_buf) {
+ if (info->port.xmit_buf) {
unsigned char *temp;
- temp = info->xmit_buf;
- info->xmit_buf = NULL;
+ temp = info->port.xmit_buf;
+ info->port.xmit_buf = NULL;
free_page((unsigned long)temp);
}
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
#ifdef CY_DEBUG_DTR
@@ -2108,9 +2108,9 @@ static void shutdown(struct cyclades_port *info)
/* it may be appropriate to clear _XMIT at
some later date (after testing)!!! */
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+ info->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
@@ -2136,14 +2136,14 @@ static void shutdown(struct cyclades_port *info)
spin_lock_irqsave(&card->card_lock, flags);
- if (info->xmit_buf) {
+ if (info->port.xmit_buf) {
unsigned char *temp;
- temp = info->xmit_buf;
- info->xmit_buf = NULL;
+ temp = info->port.xmit_buf;
+ info->port.xmit_buf = NULL;
free_page((unsigned long)temp);
}
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
cy_writel(&ch_ctrl[channel].rs_control,
(__u32)(readl(&ch_ctrl[channel].rs_control) &
~(C_RS_RTS | C_RS_DTR)));
@@ -2158,9 +2158,9 @@ static void shutdown(struct cyclades_port *info)
#endif
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+ info->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags);
}
@@ -2194,10 +2194,10 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
* If the device is in the middle of being closed, then block
* until it's done, and then try again.
*/
- if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
- wait_event_interruptible(info->close_wait,
- !(info->flags & ASYNC_CLOSING));
- return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
+ if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
+ wait_event_interruptible(info->port.close_wait,
+ !(info->port.flags & ASYNC_CLOSING));
+ return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
/*
@@ -2206,32 +2206,32 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
/*
* Block waiting for the carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
+ * this loop, info->port.count is dropped by one, so that
* cy_close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
- "count = %d\n", info->line, info->count);
+ "count = %d\n", info->line, info->port.count);
#endif
spin_lock_irqsave(&cinfo->card_lock, flags);
if (!tty_hung_up_p(filp))
- info->count--;
+ info->port.count--;
spin_unlock_irqrestore(&cinfo->card_lock, flags);
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
- "%d\n", current->pid, info->count);
+ "%d\n", current->pid, info->port.count);
#endif
- info->blocked_open++;
+ info->port.blocked_open++;
if (!IS_CYC_Z(*cinfo)) {
chip = channel >> 2;
@@ -2260,8 +2260,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(info->flags & ASYNC_INITIALIZED)) {
- retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+ !(info->port.flags & ASYNC_INITIALIZED)) {
+ retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
break;
}
@@ -2269,7 +2269,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
- if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
+ if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
(readb(base_addr +
(CyMSVR1 << index)) & CyDCD))) {
spin_unlock_irqrestore(&cinfo->card_lock, flags);
@@ -2284,7 +2284,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc block_til_ready blocking: "
"ttyC%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
schedule();
}
@@ -2298,7 +2298,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
firm_id = base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
return -EINVAL;
}
@@ -2327,12 +2327,12 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(info->flags & ASYNC_INITIALIZED)) {
- retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+ !(info->port.flags & ASYNC_INITIALIZED)) {
+ retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
break;
}
- if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
+ if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
(readl(&ch_ctrl[channel].rs_status) &
C_RS_DCD))) {
break;
@@ -2344,28 +2344,28 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc block_til_ready blocking: "
"ttyC%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
schedule();
}
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
if (!tty_hung_up_p(filp)) {
- info->count++;
+ info->port.count++;
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
- "count to %d\n", current->pid, info->count);
+ "count to %d\n", current->pid, info->port.count);
#endif
}
- info->blocked_open--;
+ info->port.blocked_open--;
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
- "count = %d\n", info->line, info->count);
+ "count = %d\n", info->line, info->port.count);
#endif
if (retval)
return retval;
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
} /* block_til_ready */
@@ -2456,27 +2456,27 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
#endif
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
if (serial_paranoia_check(info, tty->name, "cy_open"))
return -ENODEV;
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
- info->count);
+ info->port.count);
#endif
- info->count++;
+ info->port.count++;
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
- current->pid, info->count);
+ current->pid, info->port.count);
#endif
/*
* If the port is the middle of closing, bail out now
*/
- if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
- wait_event_interruptible(info->close_wait,
- !(info->flags & ASYNC_CLOSING));
- return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
+ if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
+ wait_event_interruptible(info->port.close_wait,
+ !(info->port.flags & ASYNC_CLOSING));
+ return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
/*
@@ -2641,9 +2641,9 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
}
#ifdef CY_DEBUG_OPEN
printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
- info->count);
+ info->port.count);
#endif
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* Uh, oh. tty->count is 1, which means that the tty
* structure will be freed. Info->count should always
@@ -2652,24 +2652,24 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
* serial port won't be shutdown.
*/
printk(KERN_ERR "cyc:cy_close: bad serial port count; "
- "tty->count is 1, info->count is %d\n", info->count);
- info->count = 1;
+ "tty->count is 1, info->port.count is %d\n", info->port.count);
+ info->port.count = 1;
}
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n",
- current->pid, info->count - 1);
+ current->pid, info->port.count - 1);
#endif
- if (--info->count < 0) {
+ if (--info->port.count < 0) {
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
#endif
- info->count = 0;
+ info->port.count = 0;
}
- if (info->count) {
+ if (info->port.count) {
spin_unlock_irqrestore(&card->card_lock, flags);
return;
}
- info->flags |= ASYNC_CLOSING;
+ info->port.flags |= ASYNC_CLOSING;
/*
* Now we wait for the transmit buffer to clear; and we notify
@@ -2677,8 +2677,8 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
*/
tty->closing = 1;
spin_unlock_irqrestore(&card->card_lock, flags);
- if (info->closing_wait != CY_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, info->closing_wait);
+ if (info->port.closing_wait != CY_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, info->port.closing_wait);
spin_lock_irqsave(&card->card_lock, flags);
@@ -2692,7 +2692,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) & ~CyRxData);
- if (info->flags & ASYNC_INITIALIZED) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
/* Waiting for on-board buffers to be empty before
closing the port */
spin_unlock_irqrestore(&card->card_lock, flags);
@@ -2731,18 +2731,18 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&card->card_lock, flags);
tty->closing = 0;
- info->tty = NULL;
- if (info->blocked_open) {
+ info->port.tty = NULL;
+ if (info->port.blocked_open) {
spin_unlock_irqrestore(&card->card_lock, flags);
- if (info->close_delay) {
+ if (info->port.close_delay) {
msleep_interruptible(jiffies_to_msecs
- (info->close_delay));
+ (info->port.close_delay));
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
spin_lock_irqsave(&card->card_lock, flags);
}
- info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+ info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+ wake_up_interruptible(&info->port.close_wait);
#ifdef CY_DEBUG_OTHER
printk(KERN_DEBUG "cyc:cy_close done\n");
@@ -2777,7 +2777,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (serial_paranoia_check(info, tty->name, "cy_write"))
return 0;
- if (!info->xmit_buf)
+ if (!info->port.xmit_buf)
return 0;
spin_lock_irqsave(&info->card->card_lock, flags);
@@ -2788,7 +2788,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (c <= 0)
break;
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ memcpy(info->port.xmit_buf + info->xmit_head, buf, c);
info->xmit_head = (info->xmit_head + c) &
(SERIAL_XMIT_SIZE - 1);
info->xmit_cnt += c;
@@ -2826,7 +2826,7 @@ static int cy_put_char(struct tty_struct *tty, unsigned char ch)
if (serial_paranoia_check(info, tty->name, "cy_put_char"))
return 0;
- if (!info->xmit_buf)
+ if (!info->port.xmit_buf)
return 0;
spin_lock_irqsave(&info->card->card_lock, flags);
@@ -2835,7 +2835,7 @@ static int cy_put_char(struct tty_struct *tty, unsigned char ch)
return 0;
}
- info->xmit_buf[info->xmit_head++] = ch;
+ info->port.xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= SERIAL_XMIT_SIZE - 1;
info->xmit_cnt++;
info->idle_stats.xmit_bytes++;
@@ -2860,7 +2860,7 @@ static void cy_flush_chars(struct tty_struct *tty)
return;
if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
- !info->xmit_buf)
+ !info->port.xmit_buf)
return;
start_xmit(info);
@@ -2988,27 +2988,27 @@ static void set_line_char(struct cyclades_port *info)
int baud, baud_rate = 0;
int i;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
if (info->line == -1)
return;
- cflag = info->tty->termios->c_cflag;
- iflag = info->tty->termios->c_iflag;
+ cflag = info->port.tty->termios->c_cflag;
+ iflag = info->port.tty->termios->c_iflag;
/*
* Set up the tty->alt_speed kludge
*/
- if (info->tty) {
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->tty->alt_speed = 57600;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- info->tty->alt_speed = 115200;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- info->tty->alt_speed = 230400;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->tty->alt_speed = 460800;
+ if (info->port.tty) {
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ info->port.tty->alt_speed = 57600;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ info->port.tty->alt_speed = 115200;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ info->port.tty->alt_speed = 230400;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ info->port.tty->alt_speed = 460800;
}
card = info->card;
@@ -3020,8 +3020,8 @@ static void set_line_char(struct cyclades_port *info)
index = card->bus_index;
/* baud rate */
- baud = tty_get_baud_rate(info->tty);
- if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+ baud = tty_get_baud_rate(info->port.tty);
+ if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
ASYNC_SPD_CUST) {
if (info->custom_divisor)
baud_rate = info->baud / info->custom_divisor;
@@ -3038,7 +3038,7 @@ static void set_line_char(struct cyclades_port *info)
if (i == 20)
i = 19; /* CD1400_MAX_SPEED */
- if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+ if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
ASYNC_SPD_CUST) {
cyy_baud_calc(info, baud_rate);
} else {
@@ -3059,7 +3059,7 @@ static void set_line_char(struct cyclades_port *info)
/* get it right for 134.5 baud */
info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
2;
- } else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+ } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
ASYNC_SPD_CUST) {
info->timeout = (info->xmit_fifo_size * HZ * 15 /
baud_rate) + 2;
@@ -3108,16 +3108,16 @@ static void set_line_char(struct cyclades_port *info)
/* CTS flow control flag */
if (cflag & CRTSCTS) {
- info->flags |= ASYNC_CTS_FLOW;
+ info->port.flags |= ASYNC_CTS_FLOW;
info->cor2 |= CyCtsAE;
} else {
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
info->cor2 &= ~CyCtsAE;
}
if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
else
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
/***********************************************
The hardware option, CyRtsAO, presents RTS when
@@ -3146,8 +3146,8 @@ static void set_line_char(struct cyclades_port *info)
/* set line characteristics according configuration */
cy_writeb(base_addr + (CySCHR1 << index),
- START_CHAR(info->tty));
- cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->tty));
+ START_CHAR(info->port.tty));
+ cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->port.tty));
cy_writeb(base_addr + (CyCOR1 << index), info->cor1);
cy_writeb(base_addr + (CyCOR2 << index), info->cor2);
cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
@@ -3163,7 +3163,7 @@ static void set_line_char(struct cyclades_port *info)
(info->default_timeout ? info->default_timeout : 0x02));
/* 10ms rx timeout */
- if (C_CLOCAL(info->tty)) {
+ if (C_CLOCAL(info->port.tty)) {
/* without modem intr */
cy_writeb(base_addr + (CySRER << index),
readb(base_addr + (CySRER << index)) | CyMdmCh);
@@ -3226,8 +3226,8 @@ static void set_line_char(struct cyclades_port *info)
#endif
}
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
spin_unlock_irqrestore(&card->card_lock, flags);
} else {
@@ -3250,8 +3250,8 @@ static void set_line_char(struct cyclades_port *info)
buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
/* baud rate */
- baud = tty_get_baud_rate(info->tty);
- if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+ baud = tty_get_baud_rate(info->port.tty);
+ if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
ASYNC_SPD_CUST) {
if (info->custom_divisor)
baud_rate = info->baud / info->custom_divisor;
@@ -3266,7 +3266,7 @@ static void set_line_char(struct cyclades_port *info)
/* get it right for 134.5 baud */
info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
2;
- } else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) ==
+ } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
ASYNC_SPD_CUST) {
info->timeout = (info->xmit_fifo_size * HZ * 15 /
baud_rate) + 2;
@@ -3318,7 +3318,7 @@ static void set_line_char(struct cyclades_port *info)
}
/* As the HW flow control is done in firmware, the driver
doesn't need to care about it */
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
/* XON/XOFF/XANY flow control flags */
sw_flow = 0;
@@ -3337,9 +3337,9 @@ static void set_line_char(struct cyclades_port *info)
/* CD sensitivity */
if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
else
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
if (baud == 0) { /* baud rate is zero, turn off line */
cy_writel(&ch_ctrl->rs_control,
@@ -3361,8 +3361,8 @@ static void set_line_char(struct cyclades_port *info)
"was %x\n", info->line, retval);
}
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
}
} /* set_line_char */
@@ -3381,9 +3381,9 @@ get_serial_info(struct cyclades_port *info,
tmp.port = (info->card - cy_card) * 0x100 + info->line -
cinfo->first_line;
tmp.irq = cinfo->irq;
- tmp.flags = info->flags;
- tmp.close_delay = info->close_delay;
- tmp.closing_wait = info->closing_wait;
+ tmp.flags = info->port.flags;
+ tmp.close_delay = info->port.close_delay;
+ tmp.closing_wait = info->port.closing_wait;
tmp.baud_base = info->baud;
tmp.custom_divisor = info->custom_divisor;
tmp.hub6 = 0; /*!!! */
@@ -3402,13 +3402,13 @@ set_serial_info(struct cyclades_port *info,
old_info = *info;
if (!capable(CAP_SYS_ADMIN)) {
- if (new_serial.close_delay != info->close_delay ||
+ if (new_serial.close_delay != info->port.close_delay ||
new_serial.baud_base != info->baud ||
(new_serial.flags & ASYNC_FLAGS &
~ASYNC_USR_MASK) !=
- (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
+ (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
return -EPERM;
- info->flags = (info->flags & ~ASYNC_USR_MASK) |
+ info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK);
info->baud = new_serial.baud_base;
info->custom_divisor = new_serial.custom_divisor;
@@ -3422,13 +3422,13 @@ set_serial_info(struct cyclades_port *info,
info->baud = new_serial.baud_base;
info->custom_divisor = new_serial.custom_divisor;
- info->flags = (info->flags & ~ASYNC_FLAGS) |
+ info->port.flags = (info->port.flags & ~ASYNC_FLAGS) |
(new_serial.flags & ASYNC_FLAGS);
- info->close_delay = new_serial.close_delay * HZ / 100;
- info->closing_wait = new_serial.closing_wait * HZ / 100;
+ info->port.close_delay = new_serial.close_delay * HZ / 100;
+ info->port.closing_wait = new_serial.closing_wait * HZ / 100;
check_and_exit:
- if (info->flags & ASYNC_INITIALIZED) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
set_line_char(info);
return 0;
} else {
@@ -3971,11 +3971,11 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
break;
#endif /* CONFIG_CYZ_INTR */
case CYSETWAIT:
- info->closing_wait = (unsigned short)arg * HZ / 100;
+ info->port.closing_wait = (unsigned short)arg * HZ / 100;
ret_val = 0;
break;
case CYGETWAIT:
- ret_val = info->closing_wait / (HZ / 100);
+ ret_val = info->port.closing_wait / (HZ / 100);
break;
case TIOCGSERIAL:
ret_val = get_serial_info(info, argp);
@@ -4097,7 +4097,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
*/
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
#endif
} /* cy_set_termios */
@@ -4326,14 +4326,14 @@ static void cy_hangup(struct tty_struct *tty)
cy_flush_buffer(tty);
shutdown(info);
- info->count = 0;
+ info->port.count = 0;
#ifdef CY_DEBUG_COUNT
printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
current->pid);
#endif
- info->tty = NULL;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- wake_up_interruptible(&info->open_wait);
+ info->port.tty = NULL;
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ wake_up_interruptible(&info->port.open_wait);
} /* cy_hangup */
/*
@@ -4376,15 +4376,14 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
for (port = cinfo->first_line; port < cinfo->first_line + nports;
port++) {
info = &cinfo->ports[port - cinfo->first_line];
+ tty_port_init(&info->port);
info->magic = CYCLADES_MAGIC;
info->card = cinfo;
info->line = port;
- info->flags = STD_COM_FLAGS;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->close_delay = 5 * HZ / 10;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
+ info->port.closing_wait = CLOSING_WAIT_DELAY;
+ info->port.close_delay = 5 * HZ / 10;
+ info->port.flags = STD_COM_FLAGS;
init_completion(&info->shutdown_wait);
init_waitqueue_head(&info->delta_msr_wait);
@@ -5237,7 +5236,7 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
for (j = 0; j < cy_card[i].nports; j++) {
info = &cy_card[i].ports[j];
- if (info->count)
+ if (info->port.count)
size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n", info->line,
(cur_jifs - info->idle_stats.in_use) /
@@ -5246,7 +5245,8 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
HZ, info->idle_stats.recv_bytes,
(cur_jifs - info->idle_stats.recv_idle)/
HZ, info->idle_stats.overruns,
- (long)info->tty->ldisc.num);
+ /* FIXME: double check locking */
+ (long)info->port.tty->ldisc.ops->num);
else
size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n",
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 60a4df7dac1..ac9995f6578 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -432,7 +432,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&epca_lock, flags);
return;
}
- if (ch->count-- > 1) {
+ if (ch->port.count-- > 1) {
/* Begin channel is open more than once */
/*
* Return without doing anything. Someone might still
@@ -442,19 +442,19 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
return;
}
/* Port open only once go ahead with shutdown & reset */
- BUG_ON(ch->count < 0);
+ BUG_ON(ch->port.count < 0);
/*
* Let the rest of the driver know the channel is being closed.
* This becomes important if an open is attempted before close
* is finished.
*/
- ch->asyncflags |= ASYNC_CLOSING;
+ ch->port.flags |= ASYNC_CLOSING;
tty->closing = 1;
spin_unlock_irqrestore(&epca_lock, flags);
- if (ch->asyncflags & ASYNC_INITIALIZED) {
+ if (ch->port.flags & ASYNC_INITIALIZED) {
/* Setup an event to indicate when the
transmit buffer empties */
setup_empty_event(tty, ch);
@@ -469,17 +469,17 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&epca_lock, flags);
tty->closing = 0;
ch->event = 0;
- ch->tty = NULL;
+ ch->port.tty = NULL;
spin_unlock_irqrestore(&epca_lock, flags);
- if (ch->blocked_open) {
+ if (ch->port.blocked_open) {
if (ch->close_delay)
msleep_interruptible(jiffies_to_msecs(ch->close_delay));
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
}
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
+ ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
ASYNC_CLOSING);
- wake_up_interruptible(&ch->close_wait);
+ wake_up_interruptible(&ch->port.close_wait);
}
}
@@ -489,7 +489,7 @@ static void shutdown(struct channel *ch)
struct tty_struct *tty;
struct board_chan __iomem *bc;
- if (!(ch->asyncflags & ASYNC_INITIALIZED))
+ if (!(ch->port.flags & ASYNC_INITIALIZED))
return;
spin_lock_irqsave(&epca_lock, flags);
@@ -504,7 +504,7 @@ static void shutdown(struct channel *ch)
*/
if (bc)
writeb(0, &bc->idata);
- tty = ch->tty;
+ tty = ch->port.tty;
/* If we're a modem control device and HUPCL is on, drop RTS & DTR. */
if (tty->termios->c_cflag & HUPCL) {
@@ -518,7 +518,7 @@ static void shutdown(struct channel *ch)
* will have to reinitialized. Set a flag to indicate this.
*/
/* Prevent future Digi programmed interrupts from coming active */
- ch->asyncflags &= ~ASYNC_INITIALIZED;
+ ch->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&epca_lock, flags);
}
@@ -538,12 +538,12 @@ static void pc_hangup(struct tty_struct *tty)
shutdown(ch);
spin_lock_irqsave(&epca_lock, flags);
- ch->tty = NULL;
+ ch->port.tty = NULL;
ch->event = 0;
- ch->count = 0;
- ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
+ ch->port.count = 0;
+ ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
spin_unlock_irqrestore(&epca_lock, flags);
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
}
}
@@ -795,7 +795,7 @@ static int block_til_ready(struct tty_struct *tty,
unsigned long flags;
if (tty_hung_up_p(filp)) {
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
+ if (ch->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
@@ -806,10 +806,10 @@ static int block_til_ready(struct tty_struct *tty,
* If the device is in the middle of being closed, then block until
* it's done, and then try again.
*/
- if (ch->asyncflags & ASYNC_CLOSING) {
- interruptible_sleep_on(&ch->close_wait);
+ if (ch->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&ch->port.close_wait);
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
+ if (ch->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
else
return -ERESTARTSYS;
@@ -820,7 +820,7 @@ static int block_til_ready(struct tty_struct *tty,
* If non-blocking mode is set, then make the check up front
* and then exit.
*/
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ ch->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
if (tty->termios->c_cflag & CLOCAL)
@@ -828,24 +828,24 @@ static int block_til_ready(struct tty_struct *tty,
/* Block waiting for the carrier detect and the line to become free */
retval = 0;
- add_wait_queue(&ch->open_wait, &wait);
+ add_wait_queue(&ch->port.open_wait, &wait);
spin_lock_irqsave(&epca_lock, flags);
/* We dec count so that pc_close will know when to free things */
if (!tty_hung_up_p(filp))
- ch->count--;
- ch->blocked_open++;
+ ch->port.count--;
+ ch->port.blocked_open++;
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(ch->asyncflags & ASYNC_INITIALIZED)) {
- if (ch->asyncflags & ASYNC_HUP_NOTIFY)
+ !(ch->port.flags & ASYNC_INITIALIZED)) {
+ if (ch->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(ch->asyncflags & ASYNC_CLOSING) &&
+ if (!(ch->port.flags & ASYNC_CLOSING) &&
(do_clocal || (ch->imodem & ch->dcd)))
break;
if (signal_pending(current)) {
@@ -864,17 +864,17 @@ static int block_til_ready(struct tty_struct *tty,
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&ch->open_wait, &wait);
+ remove_wait_queue(&ch->port.open_wait, &wait);
if (!tty_hung_up_p(filp))
- ch->count++;
- ch->blocked_open--;
+ ch->port.count++;
+ ch->port.blocked_open--;
spin_unlock_irqrestore(&epca_lock, flags);
if (retval)
return retval;
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ ch->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -933,7 +933,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
* necessary because we do not wish to flush and shutdown the channel
* until the last app holding the channel open, closes it.
*/
- ch->count++;
+ ch->port.count++;
/*
* Set a kernel structures pointer to our local channel structure. This
* way we can get to it when passed only a tty struct.
@@ -957,14 +957,14 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
writew(head, &bc->rout);
/* Set the channels associated tty structure */
- ch->tty = tty;
+ ch->port.tty = tty;
/*
* The below routine generally sets up parity, baud, flow control
* issues, etc.... It effect both control flags and input flags.
*/
epcaparam(tty, ch);
- ch->asyncflags |= ASYNC_INITIALIZED;
+ ch->port.flags |= ASYNC_INITIALIZED;
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
@@ -976,7 +976,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
* waiting for the line...
*/
spin_lock_irqsave(&epca_lock, flags);
- ch->tty = tty;
+ ch->port.tty = tty;
globalwinon(ch);
/* Enable Digi Data events */
writeb(1, &bc->idata);
@@ -1017,8 +1017,8 @@ static void __exit epca_module_exit(void)
}
ch = card_ptr[crd];
for (count = 0; count < bd->numports; count++, ch++) {
- if (ch && ch->tty)
- tty_hangup(ch->tty);
+ if (ch && ch->port.tty)
+ tty_hangup(ch->port.tty);
}
}
pci_unregister_driver(&epca_driver);
@@ -1427,7 +1427,7 @@ static void post_fep_init(unsigned int crd)
ch->boardnum = crd;
ch->channelnum = i;
ch->magic = EPCA_MAGIC;
- ch->tty = NULL;
+ ch->port.tty = NULL;
if (shrinkmem) {
fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
@@ -1510,10 +1510,10 @@ static void post_fep_init(unsigned int crd)
ch->fepstopca = 0;
ch->close_delay = 50;
- ch->count = 0;
- ch->blocked_open = 0;
- init_waitqueue_head(&ch->open_wait);
- init_waitqueue_head(&ch->close_wait);
+ ch->port.count = 0;
+ ch->port.blocked_open = 0;
+ init_waitqueue_head(&ch->port.open_wait);
+ init_waitqueue_head(&ch->port.close_wait);
spin_unlock_irqrestore(&epca_lock, flags);
}
@@ -1633,15 +1633,15 @@ static void doevent(int crd)
if (event & MODEMCHG_IND) {
/* A modem signal change has been indicated */
ch->imodem = mstat;
- if (ch->asyncflags & ASYNC_CHECK_CD) {
+ if (ch->port.flags & ASYNC_CHECK_CD) {
/* We are now receiving dcd */
if (mstat & ch->dcd)
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
else /* No dcd; hangup */
pc_sched_event(ch, EPCA_EVENT_HANGUP);
}
}
- tty = ch->tty;
+ tty = ch->port.tty;
if (tty) {
if (event & BREAK_IND) {
/* A break has been indicated */
@@ -1880,9 +1880,9 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
* that the driver will wait on carrier detect.
*/
if (ts->c_cflag & CLOCAL)
- ch->asyncflags &= ~ASYNC_CHECK_CD;
+ ch->port.flags &= ~ASYNC_CHECK_CD;
else
- ch->asyncflags |= ASYNC_CHECK_CD;
+ ch->port.flags |= ASYNC_CHECK_CD;
mval = ch->m_dtr | ch->m_rts;
} /* End CBAUD not detected */
iflag = termios2digi_i(ch, ts->c_iflag);
@@ -1972,7 +1972,7 @@ static void receive_data(struct channel *ch)
globalwinon(ch);
if (ch->statusflags & RXSTOPPED)
return;
- tty = ch->tty;
+ tty = ch->port.tty;
if (tty)
ts = tty->termios;
bc = ch->brdchan;
@@ -2032,7 +2032,7 @@ static void receive_data(struct channel *ch)
globalwinon(ch);
writew(tail, &bc->rout);
/* Must be called with global data */
- tty_schedule_flip(ch->tty);
+ tty_schedule_flip(ch->port.tty);
}
static int info_ioctl(struct tty_struct *tty, struct file *file,
@@ -2262,8 +2262,8 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
tty_wait_until_sent(tty, 0);
} else {
/* ldisc lock already held in ioctl */
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
+ if (tty->ldisc.ops->flush_buffer)
+ tty->ldisc.ops->flush_buffer(tty);
}
unlock_kernel();
/* Fall Thru */
@@ -2376,7 +2376,7 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
} /* End if channel valid */
}
@@ -2386,13 +2386,13 @@ static void do_softint(struct work_struct *work)
struct channel *ch = container_of(work, struct channel, tqueue);
/* Called in response to a modem change event */
if (ch && ch->magic == EPCA_MAGIC) {
- struct tty_struct *tty = ch->tty;
+ struct tty_struct *tty = ch->port.tty;
if (tty && tty->driver_data) {
if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
tty_hangup(tty);
- wake_up_interruptible(&ch->open_wait);
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
+ wake_up_interruptible(&ch->port.open_wait);
+ ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
}
}
}
diff --git a/drivers/char/epca.h b/drivers/char/epca.h
index 3c77c02b5d6..d414bf2dbf7 100644
--- a/drivers/char/epca.h
+++ b/drivers/char/epca.h
@@ -84,6 +84,7 @@ static char *board_desc[] =
struct channel
{
long magic;
+ struct tty_port port;
unsigned char boardnum;
unsigned char channelnum;
unsigned char omodem; /* FEP output modem status */
@@ -117,10 +118,7 @@ struct channel
unsigned short rxbufhead;
unsigned short rxbufsize;
int close_delay;
- int count;
- int blocked_open;
unsigned long event;
- int asyncflags;
uint dev;
unsigned long statusflags;
unsigned long c_iflag;
@@ -132,9 +130,6 @@ struct channel
struct board_info *board;
struct board_chan __iomem *brdchan;
struct digi_struct digiext;
- struct tty_struct *tty;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
struct work_struct tqueue;
struct global_data __iomem *mailbox;
};
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 84840ba13ff..2eaf09f93e3 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -128,9 +128,9 @@ static struct tty_driver *esp_driver;
#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- tty->name, info->flags, \
+ tty->name, info->port.flags, \
serial_driver.refcount, \
- info->count, tty->count, s)
+ info->port.count, tty->count, s)
#else
#define DBG_CNT(s)
#endif
@@ -172,13 +172,13 @@ static inline int serial_paranoia_check(struct esp_struct *info,
static inline unsigned int serial_in(struct esp_struct *info, int offset)
{
- return inb(info->port + offset);
+ return inb(info->io_port + offset);
}
static inline void serial_out(struct esp_struct *info, int offset,
unsigned char value)
{
- outb(value, info->port+offset);
+ outb(value, info->io_port+offset);
}
/*
@@ -273,7 +273,7 @@ static inline void release_pio_buffer(struct esp_pio_buffer *buf)
static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
int i;
struct esp_pio_buffer *pio_buf;
struct esp_pio_buffer *err_buf;
@@ -295,7 +295,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
for (i = 0; i < num_bytes - 1; i += 2) {
*((unsigned short *)(pio_buf->data + i)) =
- inw(info->port + UART_ESI_RX);
+ inw(info->io_port + UART_ESI_RX);
err_buf->data[i] = serial_in(info, UART_ESI_RWS);
err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask;
err_buf->data[i] &= status_mask;
@@ -308,7 +308,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
}
/* make sure everything is still ok since interrupts were enabled */
- tty = info->tty;
+ tty = info->port.tty;
if (!tty) {
release_pio_buffer(pio_buf);
@@ -325,7 +325,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
if (err_buf->data[i] & 0x04) {
flag = TTY_BREAK;
- if (info->flags & ASYNC_SAK)
+ if (info->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (err_buf->data[i] & 0x02)
flag = TTY_FRAME;
@@ -370,7 +370,7 @@ static void receive_chars_dma(struct esp_struct *info, int num_bytes)
static inline void receive_chars_dma_done(struct esp_struct *info,
int status)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
int num_bytes;
unsigned long flags;
@@ -396,7 +396,7 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
if (status & 0x10) {
statflag = TTY_BREAK;
(info->icount.brk)++;
- if (info->flags & ASYNC_SAK)
+ if (info->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (status & 0x08) {
statflag = TTY_FRAME;
@@ -451,7 +451,7 @@ static inline void transmit_chars_pio(struct esp_struct *info,
for (i = 0; i < space_avail - 1; i += 2) {
outw(*((unsigned short *)(pio_buf->data + i)),
- info->port + UART_ESI_TX);
+ info->io_port + UART_ESI_TX);
}
if (space_avail & 0x0001)
@@ -470,8 +470,8 @@ static inline void transmit_chars_pio(struct esp_struct *info,
}
if (info->xmit_cnt < WAKEUP_CHARS) {
- if (info->tty)
- tty_wakeup(info->tty);
+ if (info->port.tty)
+ tty_wakeup(info->port.tty);
#ifdef SERIAL_DEBUG_INTR
printk("THRE...");
@@ -507,8 +507,8 @@ static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1);
if (info->xmit_cnt < WAKEUP_CHARS) {
- if (info->tty)
- tty_wakeup(info->tty);
+ if (info->port.tty)
+ tty_wakeup(info->port.tty);
#ifdef SERIAL_DEBUG_INTR
printk("THRE...");
@@ -575,18 +575,18 @@ static void check_modem_status(struct esp_struct *info)
wake_up_interruptible(&info->delta_msr_wait);
}
- if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+ if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
printk("ttys%d CD now %s...", info->line,
(status & UART_MSR_DCD) ? "on" : "off");
#endif
if (status & UART_MSR_DCD)
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
else {
#ifdef SERIAL_DEBUG_OPEN
printk("scheduling hangup...");
#endif
- tty_hangup(info->tty);
+ tty_hangup(info->port.tty);
}
}
}
@@ -609,7 +609,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
spin_lock(&info->lock);
- if (!info->tty) {
+ if (!info->port.tty) {
spin_unlock(&info->lock);
return IRQ_NONE;
}
@@ -647,7 +647,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
num_bytes |= serial_in(info, UART_ESI_STAT2);
- num_bytes = tty_buffer_request_room(info->tty, num_bytes);
+ num_bytes = tty_buffer_request_room(info->port.tty, num_bytes);
if (num_bytes) {
if (dma_bytes ||
@@ -661,7 +661,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
(scratch & 0x02) && (info->IER & UART_IER_THRI)) {
- if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+ if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
info->IER &= ~UART_IER_THRI;
serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
serial_out(info, UART_ESI_CMD2, info->IER);
@@ -782,7 +782,7 @@ static int startup(struct esp_struct *info)
spin_lock_irqsave(&info->lock, flags);
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
goto out;
if (!info->xmit_buf) {
@@ -806,7 +806,7 @@ static int startup(struct esp_struct *info)
num_chars |= serial_in(info, UART_ESI_STAT2);
while (num_chars > 1) {
- inw(info->port + UART_ESI_RX);
+ inw(info->io_port + UART_ESI_RX);
num_chars -= 2;
}
@@ -834,9 +834,9 @@ static int startup(struct esp_struct *info)
if (retval) {
if (capable(CAP_SYS_ADMIN)) {
- if (info->tty)
+ if (info->port.tty)
set_bit(TTY_IO_ERROR,
- &info->tty->flags);
+ &info->port.tty->flags);
retval = 0;
}
goto out_unlocked;
@@ -874,30 +874,30 @@ static int startup(struct esp_struct *info)
serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
serial_out(info, UART_ESI_CMD2, info->IER);
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
spin_unlock_irqrestore(&info->lock, flags);
/*
* Set up the tty->alt_speed kludge
*/
- if (info->tty) {
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->tty->alt_speed = 57600;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- info->tty->alt_speed = 115200;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- info->tty->alt_speed = 230400;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->tty->alt_speed = 460800;
+ if (info->port.tty) {
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ info->port.tty->alt_speed = 57600;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ info->port.tty->alt_speed = 115200;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ info->port.tty->alt_speed = 230400;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ info->port.tty->alt_speed = 460800;
}
/*
* set the speed of the serial port
*/
change_speed(info);
- info->flags |= ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
return 0;
out:
@@ -914,7 +914,7 @@ static void shutdown(struct esp_struct *info)
{
unsigned long flags, f;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
#ifdef SERIAL_DEBUG_OPEN
@@ -951,7 +951,7 @@ static void shutdown(struct esp_struct *info)
while (current_port) {
if ((current_port != info) &&
- (current_port->flags & ASYNC_INITIALIZED))
+ (current_port->port.flags & ASYNC_INITIALIZED))
break;
current_port = current_port->next_port;
@@ -974,7 +974,7 @@ static void shutdown(struct esp_struct *info)
serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
serial_out(info, UART_ESI_CMD2, 0x00);
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
info->MCR &= ~UART_MCR_OUT2;
@@ -982,10 +982,10 @@ static void shutdown(struct esp_struct *info)
serial_out(info, UART_ESI_CMD2, UART_MCR);
serial_out(info, UART_ESI_CMD2, info->MCR);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ info->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&info->lock, flags);
}
@@ -1002,10 +1002,10 @@ static void change_speed(struct esp_struct *info)
unsigned char flow1 = 0, flow2 = 0;
unsigned long flags;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
- port = info->port;
+ cflag = info->port.tty->termios->c_cflag;
+ port = info->io_port;
/* byte size and parity */
switch (cflag & CSIZE) {
@@ -1029,9 +1029,9 @@ static void change_speed(struct esp_struct *info)
if (cflag & CMSPAR)
cval |= UART_LCR_SPAR;
#endif
- baud = tty_get_baud_rate(info->tty);
+ baud = tty_get_baud_rate(info->port.tty);
if (baud == 38400 &&
- ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+ ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
quot = info->custom_divisor;
else {
if (baud == 134) /* Special case since 134 is really 134.5 */
@@ -1046,49 +1046,49 @@ static void change_speed(struct esp_struct *info)
if (baud) {
/* Actual rate */
baud = BASE_BAUD/quot;
- tty_encode_baud_rate(info->tty, baud, baud);
+ tty_encode_baud_rate(info->port.tty, baud, baud);
}
info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50);
/* CTS flow control flag and modem status interrupts */
/* info->IER &= ~UART_IER_MSI; */
if (cflag & CRTSCTS) {
- info->flags |= ASYNC_CTS_FLOW;
+ info->port.flags |= ASYNC_CTS_FLOW;
/* info->IER |= UART_IER_MSI; */
flow1 = 0x04;
flow2 = 0x10;
} else
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
else
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
/*
* Set up parity check flag
*/
info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= UART_LSR_BI;
info->ignore_status_mask = 0;
#if 0
/* This should be safe, but for some broken bits of hardware... */
- if (I_IGNPAR(info->tty)) {
+ if (I_IGNPAR(info->port.tty)) {
info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
info->read_status_mask |= UART_LSR_PE | UART_LSR_FE;
}
#endif
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= UART_LSR_BI;
info->read_status_mask |= UART_LSR_BI;
/*
* If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty)) {
+ if (I_IGNPAR(info->port.tty)) {
info->ignore_status_mask |= UART_LSR_OE | \
UART_LSR_PE | UART_LSR_FE;
info->read_status_mask |= UART_LSR_OE | \
@@ -1096,7 +1096,7 @@ static void change_speed(struct esp_struct *info)
}
}
- if (I_IXOFF(info->tty))
+ if (I_IXOFF(info->port.tty))
flow1 |= 0x81;
spin_lock_irqsave(&info->lock, flags);
@@ -1116,10 +1116,10 @@ static void change_speed(struct esp_struct *info)
serial_out(info, UART_ESI_CMD2, flow2);
/* set flow control characters (XON/XOFF only) */
- if (I_IXOFF(info->tty)) {
+ if (I_IXOFF(info->port.tty)) {
serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS);
- serial_out(info, UART_ESI_CMD2, START_CHAR(info->tty));
- serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->tty));
+ serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty));
+ serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty));
serial_out(info, UART_ESI_CMD2, 0x10);
serial_out(info, UART_ESI_CMD2, 0x21);
switch (cflag & CSIZE) {
@@ -1355,9 +1355,9 @@ static int get_serial_info(struct esp_struct *info,
memset(&tmp, 0, sizeof(tmp));
tmp.type = PORT_16550A;
tmp.line = info->line;
- tmp.port = info->port;
+ tmp.port = info->io_port;
tmp.irq = info->irq;
- tmp.flags = info->flags;
+ tmp.flags = info->port.flags;
tmp.xmit_fifo_size = 1024;
tmp.baud_base = BASE_BAUD;
tmp.close_delay = info->close_delay;
@@ -1407,7 +1407,7 @@ static int set_serial_info(struct esp_struct *info,
if ((new_serial.type != PORT_16550A) ||
(new_serial.hub6) ||
- (info->port != new_serial.port) ||
+ (info->io_port != new_serial.port) ||
(new_serial.baud_base != BASE_BAUD) ||
(new_serial.irq > 15) ||
(new_serial.irq < 2) ||
@@ -1425,9 +1425,9 @@ static int set_serial_info(struct esp_struct *info,
if (change_irq ||
(new_serial.close_delay != info->close_delay) ||
((new_serial.flags & ~ASYNC_USR_MASK) !=
- (info->flags & ~ASYNC_USR_MASK)))
+ (info->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
- info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+ info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
info->custom_divisor = new_serial.custom_divisor;
} else {
@@ -1441,9 +1441,9 @@ static int set_serial_info(struct esp_struct *info,
if ((current_async->line >= info->line) &&
(current_async->line < (info->line + 8))) {
if (current_async == info) {
- if (current_async->count > 1)
+ if (current_async->port.count > 1)
return -EBUSY;
- } else if (current_async->count)
+ } else if (current_async->port.count)
return -EBUSY;
}
@@ -1456,7 +1456,7 @@ static int set_serial_info(struct esp_struct *info,
* At this point, we start making changes.....
*/
- info->flags = ((info->flags & ~ASYNC_FLAGS) |
+ info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
(new_serial.flags & ASYNC_FLAGS));
info->custom_divisor = new_serial.custom_divisor;
info->close_delay = new_serial.close_delay * HZ/100;
@@ -1487,18 +1487,18 @@ static int set_serial_info(struct esp_struct *info,
}
}
- if (info->flags & ASYNC_INITIALIZED) {
- if (((old_info.flags & ASYNC_SPD_MASK) !=
- (info->flags & ASYNC_SPD_MASK)) ||
+ if (info->port.flags & ASYNC_INITIALIZED) {
+ if (((old_info.port.flags & ASYNC_SPD_MASK) !=
+ (info->port.flags & ASYNC_SPD_MASK)) ||
(old_info.custom_divisor != info->custom_divisor)) {
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->tty->alt_speed = 57600;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- info->tty->alt_speed = 115200;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
- info->tty->alt_speed = 230400;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->tty->alt_speed = 460800;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ info->port.tty->alt_speed = 57600;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ info->port.tty->alt_speed = 115200;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ info->port.tty->alt_speed = 230400;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ info->port.tty->alt_speed = 460800;
change_speed(info);
}
} else
@@ -1554,9 +1554,9 @@ static int set_esp_config(struct esp_struct *info,
while (current_async) {
if (current_async == info) {
- if (current_async->count > 1)
+ if (current_async->port.count > 1)
return -EBUSY;
- } else if (current_async->count)
+ } else if (current_async->port.count)
return -EBUSY;
current_async = current_async->next_port;
@@ -1578,7 +1578,7 @@ static int set_esp_config(struct esp_struct *info,
spin_unlock_irqrestore(&info->lock, flags);
} else {
/* DMA mode to PIO mode only */
- if (info->count > 1)
+ if (info->port.count > 1)
return -EBUSY;
shutdown(info);
@@ -1634,7 +1634,7 @@ static int set_esp_config(struct esp_struct *info,
spin_unlock_irqrestore(&info->lock, flags);
}
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
retval = startup(info);
return retval;
@@ -1917,9 +1917,9 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
#ifdef SERIAL_DEBUG_OPEN
printk(KERN_DEBUG "rs_close ttys%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
- if (tty->count == 1 && info->count != 1) {
+ if (tty->count == 1 && info->port.count != 1) {
/*
* Uh, oh. tty->count is 1, which means that the tty
* structure will be freed. Info->count should always
@@ -1927,19 +1927,19 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
* one, we've got real problems, since it means the
* serial port won't be shutdown.
*/
- printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->count is %d\n", info->count);
- info->count = 1;
+ printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count);
+ info->port.count = 1;
}
- if (--info->count < 0) {
+ if (--info->port.count < 0) {
printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
- info->line, info->count);
- info->count = 0;
+ info->line, info->port.count);
+ info->port.count = 0;
}
- if (info->count) {
+ if (info->port.count) {
DBG_CNT("before DEC-2");
goto out;
}
- info->flags |= ASYNC_CLOSING;
+ info->port.flags |= ASYNC_CLOSING;
spin_unlock_irqrestore(&info->lock, flags);
/*
@@ -1958,7 +1958,7 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
/* info->IER &= ~UART_IER_RLSI; */
info->IER &= ~UART_IER_RDI;
info->read_status_mask &= ~UART_LSR_DR;
- if (info->flags & ASYNC_INITIALIZED) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
spin_lock_irqsave(&info->lock, flags);
serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
@@ -1981,15 +1981,15 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
rs_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
- info->tty = NULL;
+ info->port.tty = NULL;
- if (info->blocked_open) {
+ if (info->port.blocked_open) {
if (info->close_delay)
msleep_interruptible(jiffies_to_msecs(info->close_delay));
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+ info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ wake_up_interruptible(&info->port.close_wait);
return;
out:
@@ -2047,10 +2047,10 @@ static void esp_hangup(struct tty_struct *tty)
rs_flush_buffer(tty);
shutdown(info);
- info->count = 0;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = NULL;
- wake_up_interruptible(&info->open_wait);
+ info->port.count = 0;
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ info->port.tty = NULL;
+ wake_up_interruptible(&info->port.open_wait);
}
/*
@@ -2071,11 +2071,11 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
* until it's done, and then try again.
*/
if (tty_hung_up_p(filp) ||
- (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
+ (info->port.flags & ASYNC_CLOSING)) {
+ if (info->port.flags & ASYNC_CLOSING)
+ interruptible_sleep_on(&info->port.close_wait);
#ifdef SERIAL_DO_RESTART
- if (info->flags & ASYNC_HUP_NOTIFY)
+ if (info->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
else
return -ERESTARTSYS;
@@ -2090,7 +2090,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -2100,20 +2100,20 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/*
* Block waiting for the carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
+ * this loop, info->port.count is dropped by one, so that
* rs_close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
#ifdef SERIAL_DEBUG_OPEN
printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
spin_lock_irqsave(&info->lock, flags);
if (!tty_hung_up_p(filp))
- info->count--;
- info->blocked_open++;
+ info->port.count--;
+ info->port.blocked_open++;
while (1) {
if ((tty->termios->c_cflag & CBAUD)) {
unsigned int scratch;
@@ -2128,9 +2128,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
}
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(info->flags & ASYNC_INITIALIZED)) {
+ !(info->port.flags & ASYNC_INITIALIZED)) {
#ifdef SERIAL_DO_RESTART
- if (info->flags & ASYNC_HUP_NOTIFY)
+ if (info->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
@@ -2144,7 +2144,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD)
do_clocal = 1;
- if (!(info->flags & ASYNC_CLOSING) &&
+ if (!(info->port.flags & ASYNC_CLOSING) &&
(do_clocal))
break;
if (signal_pending(current)) {
@@ -2153,25 +2153,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
}
#ifdef SERIAL_DEBUG_OPEN
printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
spin_unlock_irqrestore(&info->lock, flags);
schedule();
spin_lock_irqsave(&info->lock, flags);
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
if (!tty_hung_up_p(filp))
- info->count++;
- info->blocked_open--;
+ info->port.count++;
+ info->port.blocked_open--;
spin_unlock_irqrestore(&info->lock, flags);
#ifdef SERIAL_DEBUG_OPEN
printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
if (retval)
return retval;
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -2204,12 +2204,12 @@ static int esp_open(struct tty_struct *tty, struct file *filp)
}
#ifdef SERIAL_DEBUG_OPEN
- printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->count);
+ printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count);
#endif
spin_lock_irqsave(&info->lock, flags);
- info->count++;
+ info->port.count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
spin_unlock_irqrestore(&info->lock, flags);
@@ -2263,7 +2263,7 @@ static int autoconfig(struct esp_struct *info)
int port_detected = 0;
unsigned long flags;
- if (!request_region(info->port, REGION_SIZE, "esp serial"))
+ if (!request_region(info->io_port, REGION_SIZE, "esp serial"))
return -EIO;
spin_lock_irqsave(&info->lock, flags);
@@ -2300,7 +2300,7 @@ static int autoconfig(struct esp_struct *info)
}
}
if (!port_detected)
- release_region(info->port, REGION_SIZE);
+ release_region(info->io_port, REGION_SIZE);
spin_unlock_irqrestore(&info->lock, flags);
return (port_detected);
@@ -2414,7 +2414,7 @@ static int __init espserial_init(void)
offset = 0;
do {
- info->port = esp[i] + offset;
+ info->io_port = esp[i] + offset;
info->irq = irq[i];
info->line = (i * 8) + (offset / 8);
@@ -2425,9 +2425,9 @@ static int __init espserial_init(void)
}
info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf;
- info->flags = STD_COM_FLAGS;
+ info->port.flags = STD_COM_FLAGS;
if (info->custom_divisor)
- info->flags |= ASYNC_SPD_CUST;
+ info->port.flags |= ASYNC_SPD_CUST;
info->magic = ESP_MAGIC;
info->close_delay = 5*HZ/10;
info->closing_wait = 30*HZ;
@@ -2436,13 +2436,13 @@ static int __init espserial_init(void)
info->config.flow_off = flow_off;
info->config.pio_threshold = pio_threshold;
info->next_port = ports;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
+ init_waitqueue_head(&info->port.open_wait);
+ init_waitqueue_head(&info->port.close_wait);
init_waitqueue_head(&info->delta_msr_wait);
init_waitqueue_head(&info->break_wait);
ports = info;
printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
- info->line, info->port, info->irq);
+ info->line, info->io_port, info->irq);
if (info->line % 8) {
printk("secondary port\n");
@@ -2498,8 +2498,8 @@ static void __exit espserial_exit(void)
put_tty_driver(esp_driver);
while (ports) {
- if (ports->port)
- release_region(ports->port, REGION_SIZE);
+ if (ports->io_port)
+ release_region(ports->io_port, REGION_SIZE);
temp_async = ports->next_port;
kfree(ports);
ports = temp_async;
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 252f73e4859..19d3afb0e50 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -60,7 +60,7 @@ int gs_put_char(struct tty_struct * tty, unsigned char ch)
if (!port) return 0;
- if (! (port->flags & ASYNC_INITIALIZED)) return 0;
+ if (! (port->port.flags & ASYNC_INITIALIZED)) return 0;
/* Take a lock on the serial tranmit buffer! */
mutex_lock(& port->port_write_mutex);
@@ -103,7 +103,7 @@ int gs_write(struct tty_struct * tty,
if (!port) return 0;
- if (! (port->flags & ASYNC_INITIALIZED))
+ if (! (port->port.flags & ASYNC_INITIALIZED))
return 0;
/* get exclusive "write" access to this port (problem 3) */
@@ -141,13 +141,13 @@ int gs_write(struct tty_struct * tty,
mutex_unlock(& port->port_write_mutex);
gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n",
- (port->flags & GS_TX_INTEN)?"enabled": "disabled");
+ (port->port.flags & GS_TX_INTEN)?"enabled": "disabled");
if (port->xmit_cnt &&
!tty->stopped &&
!tty->hw_stopped &&
- !(port->flags & GS_TX_INTEN)) {
- port->flags |= GS_TX_INTEN;
+ !(port->port.flags & GS_TX_INTEN)) {
+ port->port.flags |= GS_TX_INTEN;
port->rd->enable_tx_interrupts (port);
}
func_exit ();
@@ -208,7 +208,7 @@ static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port);
if (port) {
gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n",
- port->xmit_cnt, port->xmit_buf, port->tty);
+ port->xmit_cnt, port->xmit_buf, port->port.tty);
}
if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
@@ -217,7 +217,7 @@ static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
return -EINVAL; /* This is an error which we don't know how to handle. */
}
- rcib = gs_real_chars_in_buffer(port->tty);
+ rcib = gs_real_chars_in_buffer(port->port.tty);
if(rcib <= 0) {
gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
@@ -236,7 +236,7 @@ static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
/* the expression is actually jiffies < end_jiffies, but that won't
work around the wraparound. Tricky eh? */
- while ((charsleft = gs_real_chars_in_buffer (port->tty)) &&
+ while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) &&
time_after (end_jiffies, jiffies)) {
/* Units check:
chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
@@ -309,7 +309,7 @@ void gs_flush_chars(struct tty_struct * tty)
}
/* Beats me -- REW */
- port->flags |= GS_TX_INTEN;
+ port->port.flags |= GS_TX_INTEN;
port->rd->enable_tx_interrupts (port);
func_exit ();
}
@@ -329,8 +329,8 @@ void gs_stop(struct tty_struct * tty)
if (port->xmit_cnt &&
port->xmit_buf &&
- (port->flags & GS_TX_INTEN) ) {
- port->flags &= ~GS_TX_INTEN;
+ (port->port.flags & GS_TX_INTEN) ) {
+ port->port.flags &= ~GS_TX_INTEN;
port->rd->disable_tx_interrupts (port);
}
func_exit ();
@@ -349,8 +349,8 @@ void gs_start(struct tty_struct * tty)
if (port->xmit_cnt &&
port->xmit_buf &&
- !(port->flags & GS_TX_INTEN) ) {
- port->flags |= GS_TX_INTEN;
+ !(port->port.flags & GS_TX_INTEN) ) {
+ port->port.flags |= GS_TX_INTEN;
port->rd->enable_tx_interrupts (port);
}
func_exit ();
@@ -365,7 +365,7 @@ static void gs_shutdown_port (struct gs_port *port)
if (!port) return;
- if (!(port->flags & ASYNC_INITIALIZED))
+ if (!(port->port.flags & ASYNC_INITIALIZED))
return;
spin_lock_irqsave(&port->driver_lock, flags);
@@ -375,12 +375,12 @@ static void gs_shutdown_port (struct gs_port *port)
port->xmit_buf = NULL;
}
- if (port->tty)
- set_bit(TTY_IO_ERROR, &port->tty->flags);
+ if (port->port.tty)
+ set_bit(TTY_IO_ERROR, &port->port.tty->flags);
port->rd->shutdown_port (port);
- port->flags &= ~ASYNC_INITIALIZED;
+ port->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&port->driver_lock, flags);
func_exit();
@@ -396,16 +396,16 @@ void gs_hangup(struct tty_struct *tty)
if (!tty) return;
port = tty->driver_data;
- tty = port->tty;
+ tty = port->port.tty;
if (!tty)
return;
gs_shutdown_port (port);
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
- port->tty = NULL;
- port->count = 0;
+ port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
+ port->port.tty = NULL;
+ port->port.count = 0;
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
func_exit ();
}
@@ -424,7 +424,7 @@ int gs_block_til_ready(void *port_, struct file * filp)
if (!port) return 0;
- tty = port->tty;
+ tty = port->port.tty;
if (!tty) return 0;
@@ -433,9 +433,9 @@ int gs_block_til_ready(void *port_, struct file * filp)
* If the device is in the middle of being closed, then block
* until it's done, and then try again.
*/
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY)
+ if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&port->port.close_wait);
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
else
return -ERESTARTSYS;
@@ -449,7 +449,7 @@ int gs_block_til_ready(void *port_, struct file * filp)
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -461,34 +461,34 @@ int gs_block_til_ready(void *port_, struct file * filp)
/*
* Block waiting for the carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, port->count is dropped by one, so that
+ * this loop, port->port.count is dropped by one, so that
* rs_close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&port->open_wait, &wait);
+ add_wait_queue(&port->port.open_wait, &wait);
gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
spin_lock_irqsave(&port->driver_lock, flags);
if (!tty_hung_up_p(filp)) {
- port->count--;
+ port->port.count--;
}
spin_unlock_irqrestore(&port->driver_lock, flags);
- port->blocked_open++;
+ port->port.blocked_open++;
while (1) {
CD = port->rd->get_CD (port);
gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
set_current_state (TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
+ !(port->port.flags & ASYNC_INITIALIZED)) {
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(port->flags & ASYNC_CLOSING) &&
+ if (!(port->port.flags & ASYNC_CLOSING) &&
(do_clocal || CD))
break;
gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n",
@@ -500,17 +500,17 @@ int gs_block_til_ready(void *port_, struct file * filp)
schedule();
}
gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n",
- port->blocked_open);
+ port->port.blocked_open);
set_current_state (TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
+ remove_wait_queue(&port->port.open_wait, &wait);
if (!tty_hung_up_p(filp)) {
- port->count++;
+ port->port.count++;
}
- port->blocked_open--;
+ port->port.blocked_open--;
if (retval)
return retval;
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
func_exit ();
return 0;
}
@@ -529,10 +529,10 @@ void gs_close(struct tty_struct * tty, struct file * filp)
if (!port) return;
- if (!port->tty) {
+ if (!port->port.tty) {
/* This seems to happen when this is called from vhangup. */
- gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n");
- port->tty = tty;
+ gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n");
+ port->port.tty = tty;
}
spin_lock_irqsave(&port->driver_lock, flags);
@@ -545,23 +545,23 @@ void gs_close(struct tty_struct * tty, struct file * filp)
return;
}
- if ((tty->count == 1) && (port->count != 1)) {
+ if ((tty->count == 1) && (port->port.count != 1)) {
printk(KERN_ERR "gs: gs_close port %p: bad port count;"
- " tty->count is 1, port count is %d\n", port, port->count);
- port->count = 1;
+ " tty->count is 1, port count is %d\n", port, port->port.count);
+ port->port.count = 1;
}
- if (--port->count < 0) {
- printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->count);
- port->count = 0;
+ if (--port->port.count < 0) {
+ printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count);
+ port->port.count = 0;
}
- if (port->count) {
- gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->count);
+ if (port->port.count) {
+ gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count);
spin_unlock_irqrestore(&port->driver_lock, flags);
func_exit ();
return;
}
- port->flags |= ASYNC_CLOSING;
+ port->port.flags |= ASYNC_CLOSING;
/*
* Now we wait for the transmit buffer to clear; and we notify
@@ -585,7 +585,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
gs_wait_tx_flushed (port, port->closing_wait);
- port->flags &= ~GS_ACTIVE;
+ port->port.flags &= ~GS_ACTIVE;
gs_flush_buffer(tty);
@@ -595,18 +595,18 @@ void gs_close(struct tty_struct * tty, struct file * filp)
port->event = 0;
port->rd->close (port);
port->rd->shutdown_port (port);
- port->tty = NULL;
+ port->port.tty = NULL;
- if (port->blocked_open) {
+ if (port->port.blocked_open) {
if (port->close_delay) {
spin_unlock_irqrestore(&port->driver_lock, flags);
msleep_interruptible(jiffies_to_msecs(port->close_delay));
spin_lock_irqsave(&port->driver_lock, flags);
}
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
}
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
- wake_up_interruptible(&port->close_wait);
+ port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
+ wake_up_interruptible(&port->port.close_wait);
func_exit ();
}
@@ -626,10 +626,10 @@ void gs_set_termios (struct tty_struct * tty,
port = tty->driver_data;
if (!port) return;
- if (!port->tty) {
+ if (!port->port.tty) {
/* This seems to happen when this is called after gs_close. */
- gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->tty is NULL\n");
- port->tty = tty;
+ gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n");
+ port->port.tty = tty;
}
@@ -651,15 +651,15 @@ void gs_set_termios (struct tty_struct * tty,
baudrate = tty_get_baud_rate(tty);
if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baudrate = 57600;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baudrate = 115200;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
baudrate = 230400;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
baudrate = 460800;
- else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+ else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
baudrate = (port->baud_base / port->custom_divisor);
}
@@ -715,7 +715,7 @@ int gs_init_port(struct gs_port *port)
func_enter ();
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->port.flags & ASYNC_INITIALIZED) {
func_exit ();
return 0;
}
@@ -737,15 +737,15 @@ int gs_init_port(struct gs_port *port)
}
spin_lock_irqsave (&port->driver_lock, flags);
- if (port->tty)
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
+ if (port->port.tty)
+ clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
mutex_init(&port->port_write_mutex);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
spin_unlock_irqrestore(&port->driver_lock, flags);
- gs_set_termios(port->tty, NULL);
+ gs_set_termios(port->port.tty, NULL);
spin_lock_irqsave (&port->driver_lock, flags);
- port->flags |= ASYNC_INITIALIZED;
- port->flags &= ~GS_TX_INTEN;
+ port->port.flags |= ASYNC_INITIALIZED;
+ port->port.flags &= ~GS_TX_INTEN;
spin_unlock_irqrestore(&port->driver_lock, flags);
func_exit ();
@@ -764,11 +764,11 @@ int gs_setserial(struct gs_port *port, struct serial_struct __user *sp)
if ((sio.baud_base != port->baud_base) ||
(sio.close_delay != port->close_delay) ||
((sio.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
+ (port->port.flags & ~ASYNC_USR_MASK)))
return(-EPERM);
}
- port->flags = (port->flags & ~ASYNC_USR_MASK) |
+ port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) |
(sio.flags & ASYNC_USR_MASK);
port->baud_base = sio.baud_base;
@@ -776,7 +776,7 @@ int gs_setserial(struct gs_port *port, struct serial_struct __user *sp)
port->closing_wait = sio.closing_wait;
port->custom_divisor = sio.custom_divisor;
- gs_set_termios (port->tty, NULL);
+ gs_set_termios (port->port.tty, NULL);
return 0;
}
@@ -793,7 +793,7 @@ int gs_getserial(struct gs_port *port, struct serial_struct __user *sp)
struct serial_struct sio;
memset(&sio, 0, sizeof(struct serial_struct));
- sio.flags = port->flags;
+ sio.flags = port->port.flags;
sio.baud_base = port->baud_base;
sio.close_delay = port->close_delay;
sio.closing_wait = port->closing_wait;
@@ -821,10 +821,10 @@ void gs_got_break(struct gs_port *port)
{
func_enter ();
- tty_insert_flip_char(port->tty, 0, TTY_BREAK);
- tty_schedule_flip(port->tty);
- if (port->flags & ASYNC_SAK) {
- do_SAK (port->tty);
+ tty_insert_flip_char(port->port.tty, 0, TTY_BREAK);
+ tty_schedule_flip(port->port.tty);
+ if (port->port.flags & ASYNC_SAK) {
+ do_SAK (port->port.tty);
}
func_exit ();
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 938879cc7bc..0061e18aff6 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -868,11 +868,11 @@ i2Input(i2ChanStrPtr pCh)
amountToMove = count;
}
// Move the first block
- pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
+ pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
&(pCh->Ibuf[stripIndex]), NULL, amountToMove );
// If we needed to wrap, do the second data move
if (count > amountToMove) {
- pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
+ pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
pCh->Ibuf, NULL, count - amountToMove );
}
// Bump and wrap the stripIndex all at once by the amount of data read. This
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 9a2394cda94..5dc74404058 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1289,11 +1289,12 @@ static void do_input(struct work_struct *work)
// code duplicated from n_tty (ldisc)
static inline void isig(int sig, struct tty_struct *tty, int flush)
{
+ /* FIXME: This is completely bogus */
if (tty->pgrp)
kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
- if ( tty->ldisc.flush_buffer )
- tty->ldisc.flush_buffer(tty);
+ if ( tty->ldisc.ops->flush_buffer )
+ tty->ldisc.ops->flush_buffer(tty);
i2InputFlush( tty->driver_data );
}
}
@@ -1342,7 +1343,7 @@ static void do_status(struct work_struct *work)
}
tmp = pCh->pTTY->real_raw;
pCh->pTTY->real_raw = 0;
- pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
+ pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
pCh->pTTY->real_raw = tmp;
}
#endif /* NEVER_HAPPENS_AS_SETUP_XXX */
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 4f3cefa8eb0..d4281df10c2 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -198,17 +198,10 @@ struct isi_board {
struct isi_port {
unsigned short magic;
- unsigned int flags;
- int count;
- int blocked_open;
- int close_delay;
+ struct tty_port port;
u16 channel;
u16 status;
- u16 closing_wait;
struct isi_board *card;
- struct tty_struct *tty;
- wait_queue_head_t close_wait;
- wait_queue_head_t open_wait;
unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
@@ -430,11 +423,11 @@ static void isicom_tx(unsigned long _data)
for (; count > 0; count--, port++) {
/* port not active or tx disabled to force flow control */
- if (!(port->flags & ASYNC_INITIALIZED) ||
+ if (!(port->port.flags & ASYNC_INITIALIZED) ||
!(port->status & ISI_TXOK))
continue;
- tty = port->tty;
+ tty = port->port.tty;
if (tty == NULL)
continue;
@@ -458,7 +451,7 @@ static void isicom_tx(unsigned long _data)
if (residue == YES) {
residue = NO;
if (cnt > 0) {
- wrd |= (port->xmit_buf[port->xmit_tail]
+ wrd |= (port->port.xmit_buf[port->xmit_tail]
<< 8);
port->xmit_tail = (port->xmit_tail + 1)
& (SERIAL_XMIT_SIZE - 1);
@@ -474,14 +467,14 @@ static void isicom_tx(unsigned long _data)
if (cnt <= 0)
break;
word_count = cnt >> 1;
- outsw(base, port->xmit_buf+port->xmit_tail, word_count);
+ outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
port->xmit_tail = (port->xmit_tail
+ (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
txcount -= (word_count << 1);
port->xmit_cnt -= (word_count << 1);
if (cnt & 0x0001) {
residue = YES;
- wrd = port->xmit_buf[port->xmit_tail];
+ wrd = port->port.xmit_buf[port->xmit_tail];
port->xmit_tail = (port->xmit_tail + 1)
& (SERIAL_XMIT_SIZE - 1);
port->xmit_cnt--;
@@ -548,13 +541,13 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
port = card->ports + channel;
- if (!(port->flags & ASYNC_INITIALIZED)) {
+ if (!(port->port.flags & ASYNC_INITIALIZED)) {
outw(0x0000, base+0x04); /* enable interrupts */
spin_unlock(&card->card_lock);
return IRQ_HANDLED;
}
- tty = port->tty;
+ tty = port->port.tty;
if (tty == NULL) {
word_count = byte_count >> 1;
while (byte_count > 1) {
@@ -572,7 +565,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
header = inw(base);
switch (header & 0xff) {
case 0: /* Change in EIA signals */
- if (port->flags & ASYNC_CHECK_CD) {
+ if (port->port.flags & ASYNC_CHECK_CD) {
if (port->status & ISI_DCD) {
if (!(header & ISI_DCD)) {
/* Carrier has been lost */
@@ -585,7 +578,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
/* Carrier has been detected */
pr_dbg("interrupt: DCD->high.\n");
port->status |= ISI_DCD;
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
}
} else {
if (header & ISI_DCD)
@@ -594,17 +587,17 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
port->status &= ~ISI_DCD;
}
- if (port->flags & ASYNC_CTS_FLOW) {
- if (port->tty->hw_stopped) {
+ if (port->port.flags & ASYNC_CTS_FLOW) {
+ if (port->port.tty->hw_stopped) {
if (header & ISI_CTS) {
- port->tty->hw_stopped = 0;
+ port->port.tty->hw_stopped = 0;
/* start tx ing */
port->status |= (ISI_TXOK
| ISI_CTS);
tty_wakeup(tty);
}
} else if (!(header & ISI_CTS)) {
- port->tty->hw_stopped = 1;
+ port->port.tty->hw_stopped = 1;
/* stop tx ing */
port->status &= ~(ISI_TXOK | ISI_CTS);
}
@@ -629,7 +622,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
case 1: /* Received Break !!! */
tty_insert_flip_char(tty, 0, TTY_BREAK);
- if (port->flags & ASYNC_SAK)
+ if (port->port.flags & ASYNC_SAK)
do_SAK(tty);
tty_flip_buffer_push(tty);
break;
@@ -681,7 +674,7 @@ static void isicom_config_port(struct isi_port *port)
shift_count = card->shift_count;
unsigned char flow_ctrl;
- tty = port->tty;
+ tty = port->port.tty;
if (tty == NULL)
return;
@@ -697,7 +690,7 @@ static void isicom_config_port(struct isi_port *port)
/* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
if (baud < 1 || baud > 4)
- port->tty->termios->c_cflag &= ~CBAUDEX;
+ port->port.tty->termios->c_cflag &= ~CBAUDEX;
else
baud += 15;
}
@@ -708,13 +701,13 @@ static void isicom_config_port(struct isi_port *port)
* the 'setserial' utility.
*/
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baud++; /* 57.6 Kbps */
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud += 2; /* 115 Kbps */
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
baud += 3; /* 230 kbps*/
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
baud += 4; /* 460 kbps*/
}
if (linuxb_to_isib[baud] == -1) {
@@ -754,15 +747,15 @@ static void isicom_config_port(struct isi_port *port)
InterruptTheCard(base);
}
if (C_CLOCAL(tty))
- port->flags &= ~ASYNC_CHECK_CD;
+ port->port.flags &= ~ASYNC_CHECK_CD;
else
- port->flags |= ASYNC_CHECK_CD;
+ port->port.flags |= ASYNC_CHECK_CD;
/* flow control settings ...*/
flow_ctrl = 0;
- port->flags &= ~ASYNC_CTS_FLOW;
+ port->port.flags &= ~ASYNC_CTS_FLOW;
if (C_CRTSCTS(tty)) {
- port->flags |= ASYNC_CTS_FLOW;
+ port->port.flags |= ASYNC_CTS_FLOW;
flow_ctrl |= ISICOM_CTSRTS;
}
if (I_IXON(tty))
@@ -809,23 +802,15 @@ static int isicom_setup_port(struct isi_port *port)
struct isi_board *card = port->card;
unsigned long flags;
- if (port->flags & ASYNC_INITIALIZED)
+ if (port->port.flags & ASYNC_INITIALIZED)
return 0;
- if (!port->xmit_buf) {
- /* Relies on BKL */
- unsigned long page = get_zeroed_page(GFP_KERNEL);
- if (page == 0)
- return -ENOMEM;
- if (port->xmit_buf)
- free_page(page);
- else
- port->xmit_buf = (unsigned char *) page;
- }
+ if (tty_port_alloc_xmit_buf(&port->port) < 0)
+ return -ENOMEM;
spin_lock_irqsave(&card->card_lock, flags);
- if (port->tty)
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
- if (port->count == 1)
+ if (port->port.tty)
+ clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
+ if (port->port.count == 1)
card->count++;
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -839,7 +824,7 @@ static int isicom_setup_port(struct isi_port *port)
}
isicom_config_port(port);
- port->flags |= ASYNC_INITIALIZED;
+ port->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&card->card_lock, flags);
return 0;
@@ -855,10 +840,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/* block if port is in the process of being closed */
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
+ if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
pr_dbg("block_til_ready: close in progress.\n");
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY)
+ interruptible_sleep_on(&port->port.close_wait);
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
else
return -ERESTARTSYS;
@@ -869,7 +854,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
pr_dbg("block_til_ready: non-block mode.\n");
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -879,26 +864,26 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/* block waiting for DCD to be asserted, and while
callout dev is busy */
retval = 0;
- add_wait_queue(&port->open_wait, &wait);
+ add_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&card->card_lock, flags);
if (!tty_hung_up_p(filp))
- port->count--;
- port->blocked_open++;
+ port->port.count--;
+ port->port.blocked_open++;
spin_unlock_irqrestore(&card->card_lock, flags);
while (1) {
raise_dtr_rts(port);
set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
+ if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(port->flags & ASYNC_CLOSING) &&
+ if (!(port->port.flags & ASYNC_CLOSING) &&
(do_clocal || (port->status & ISI_DCD))) {
break;
}
@@ -909,15 +894,15 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
schedule();
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
+ remove_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&card->card_lock, flags);
if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
+ port->port.count++;
+ port->port.blocked_open--;
spin_unlock_irqrestore(&card->card_lock, flags);
if (retval)
return retval;
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -947,9 +932,9 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
isicom_setup_board(card);
- port->count++;
+ port->port.count++;
tty->driver_data = port;
- port->tty = tty;
+ port->port.tty = tty;
error = isicom_setup_port(port);
if (error == 0)
error = block_til_ready(tty, filp, port);
@@ -970,18 +955,15 @@ static void isicom_shutdown_port(struct isi_port *port)
struct isi_board *card = port->card;
struct tty_struct *tty;
- tty = port->tty;
+ tty = port->port.tty;
- if (!(port->flags & ASYNC_INITIALIZED))
+ if (!(port->port.flags & ASYNC_INITIALIZED))
return;
- if (port->xmit_buf) {
- free_page((unsigned long) port->xmit_buf);
- port->xmit_buf = NULL;
- }
- port->flags &= ~ASYNC_INITIALIZED;
+ tty_port_free_xmit_buf(&port->port);
+ port->port.flags &= ~ASYNC_INITIALIZED;
/* 3rd October 2000 : Vinayak P Risbud */
- port->tty = NULL;
+ port->port.tty = NULL;
/*Fix done by Anil .S on 30-04-2001
remote login through isi port has dtr toggle problem
@@ -1046,33 +1028,33 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
return;
}
- if (tty->count == 1 && port->count != 1) {
+ if (tty->count == 1 && port->port.count != 1) {
printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
"count tty->count = 1 port count = %d.\n",
- card->base, port->count);
- port->count = 1;
+ card->base, port->port.count);
+ port->port.count = 1;
}
- if (--port->count < 0) {
+ if (--port->port.count < 0) {
printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
"count for channel%d = %d", card->base, port->channel,
- port->count);
- port->count = 0;
+ port->port.count);
+ port->port.count = 0;
}
- if (port->count) {
+ if (port->port.count) {
spin_unlock_irqrestore(&card->card_lock, flags);
return;
}
- port->flags |= ASYNC_CLOSING;
+ port->port.flags |= ASYNC_CLOSING;
tty->closing = 1;
spin_unlock_irqrestore(&card->card_lock, flags);
- if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, port->closing_wait);
+ if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, port->port.closing_wait);
/* indicate to the card that no more data can be received
on this port */
spin_lock_irqsave(&card->card_lock, flags);
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->port.flags & ASYNC_INITIALIZED) {
card->port_status &= ~(1 << port->channel);
outw(card->port_status, card->base + 0x02);
}
@@ -1085,18 +1067,18 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&card->card_lock, flags);
tty->closing = 0;
- if (port->blocked_open) {
+ if (port->port.blocked_open) {
spin_unlock_irqrestore(&card->card_lock, flags);
- if (port->close_delay) {
+ if (port->port.close_delay) {
pr_dbg("scheduling until time out.\n");
msleep_interruptible(
- jiffies_to_msecs(port->close_delay));
+ jiffies_to_msecs(port->port.close_delay));
}
spin_lock_irqsave(&card->card_lock, flags);
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
}
- port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
- wake_up_interruptible(&port->close_wait);
+ port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+ wake_up_interruptible(&port->port.close_wait);
spin_unlock_irqrestore(&card->card_lock, flags);
}
@@ -1112,9 +1094,6 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
if (isicom_paranoia_check(port, tty->name, "isicom_write"))
return 0;
- if (!port->xmit_buf)
- return 0;
-
spin_lock_irqsave(&card->card_lock, flags);
while (1) {
@@ -1123,7 +1102,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
if (cnt <= 0)
break;
- memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
+ memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
- 1);
port->xmit_cnt += cnt;
@@ -1147,16 +1126,13 @@ static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
return 0;
- if (!port->xmit_buf)
- return 0;
-
spin_lock_irqsave(&card->card_lock, flags);
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
spin_unlock_irqrestore(&card->card_lock, flags);
return 0;
}
- port->xmit_buf[port->xmit_head++] = ch;
+ port->port.xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
port->xmit_cnt++;
spin_unlock_irqrestore(&card->card_lock, flags);
@@ -1172,7 +1148,7 @@ static void isicom_flush_chars(struct tty_struct *tty)
return;
if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
- !port->xmit_buf)
+ !port->port.xmit_buf)
return;
/* this tells the transmitter to consider this port for
@@ -1274,23 +1250,23 @@ static int isicom_set_serial_info(struct isi_port *port,
lock_kernel();
- reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
+ reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
(newinfo.flags & ASYNC_SPD_MASK));
if (!capable(CAP_SYS_ADMIN)) {
- if ((newinfo.close_delay != port->close_delay) ||
- (newinfo.closing_wait != port->closing_wait) ||
+ if ((newinfo.close_delay != port->port.close_delay) ||
+ (newinfo.closing_wait != port->port.closing_wait) ||
((newinfo.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK))) {
+ (port->port.flags & ~ASYNC_USR_MASK))) {
unlock_kernel();
return -EPERM;
}
- port->flags = ((port->flags & ~ASYNC_USR_MASK) |
+ port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
(newinfo.flags & ASYNC_USR_MASK));
} else {
- port->close_delay = newinfo.close_delay;
- port->closing_wait = newinfo.closing_wait;
- port->flags = ((port->flags & ~ASYNC_FLAGS) |
+ port->port.close_delay = newinfo.close_delay;
+ port->port.closing_wait = newinfo.closing_wait;
+ port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
(newinfo.flags & ASYNC_FLAGS));
}
if (reconfig_port) {
@@ -1314,10 +1290,10 @@ static int isicom_get_serial_info(struct isi_port *port,
out_info.line = port - isi_ports;
out_info.port = port->card->base;
out_info.irq = port->card->irq;
- out_info.flags = port->flags;
+ out_info.flags = port->port.flags;
/* out_info.baud_base = ? */
- out_info.close_delay = port->close_delay;
- out_info.closing_wait = port->closing_wait;
+ out_info.close_delay = port->port.close_delay;
+ out_info.closing_wait = port->port.closing_wait;
unlock_kernel();
if (copy_to_user(info, &out_info, sizeof(out_info)))
return -EFAULT;
@@ -1454,10 +1430,10 @@ static void isicom_hangup(struct tty_struct *tty)
isicom_shutdown_port(port);
spin_unlock_irqrestore(&port->card->card_lock, flags);
- port->count = 0;
- port->flags &= ~ASYNC_NORMAL_ACTIVE;
- port->tty = NULL;
- wake_up_interruptible(&port->open_wait);
+ port->port.count = 0;
+ port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ port->port.tty = NULL;
+ wake_up_interruptible(&port->port.open_wait);
}
@@ -1736,6 +1712,12 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
if (card_count >= BOARD_COUNT)
goto err;
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "failed to enable\n");
+ goto err;
+ }
+
dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
/* allot the first empty slot in the array */
@@ -1790,6 +1772,7 @@ errunrr:
errdec:
board->base = 0;
card_count--;
+ pci_disable_device(pdev);
err:
return retval;
}
@@ -1806,6 +1789,7 @@ static void __devexit isicom_remove(struct pci_dev *pdev)
pci_release_region(pdev, 3);
board->base = 0;
card_count--;
+ pci_disable_device(pdev);
}
static int __init isicom_init(void)
@@ -1818,14 +1802,13 @@ static int __init isicom_init(void)
isi_card[idx].ports = port;
spin_lock_init(&isi_card[idx].card_lock);
for (channel = 0; channel < 16; channel++, port++) {
+ tty_port_init(&port->port);
port->magic = ISICOM_MAGIC;
port->card = &isi_card[idx];
port->channel = channel;
- port->close_delay = 50 * HZ/100;
- port->closing_wait = 3000 * HZ/100;
+ port->port.close_delay = 50 * HZ/100;
+ port->port.closing_wait = 3000 * HZ/100;
port->status = 0;
- init_waitqueue_head(&port->open_wait);
- init_waitqueue_head(&port->close_wait);
/* . . . */
}
isi_card[idx].base = 0;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 7c8b62f162b..6ef1c565705 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -735,8 +735,8 @@ static void stli_cleanup_ports(struct stlibrd *brdp)
for (j = 0; j < STL_MAXPORTS; j++) {
portp = brdp->ports[j];
if (portp != NULL) {
- if (portp->tty != NULL)
- tty_hangup(portp->tty);
+ if (portp->port.tty != NULL)
+ tty_hangup(portp->port.tty);
kfree(portp);
}
}
@@ -811,9 +811,9 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
* The sleep here does not need interrupt protection since the wakeup
* for it is done with the same context.
*/
- if (portp->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&portp->close_wait);
- if (portp->flags & ASYNC_HUP_NOTIFY)
+ if (portp->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&portp->port.close_wait);
+ if (portp->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
return -ERESTARTSYS;
}
@@ -824,7 +824,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
* requires several commands to the board we will need to wait for any
* other open that is already initializing the port.
*/
- portp->tty = tty;
+ portp->port.tty = tty;
tty->driver_data = portp;
portp->refcount++;
@@ -833,10 +833,10 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
if (signal_pending(current))
return -ERESTARTSYS;
- if ((portp->flags & ASYNC_INITIALIZED) == 0) {
+ if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
set_bit(ST_INITIALIZING, &portp->state);
if ((rc = stli_initopen(brdp, portp)) >= 0) {
- portp->flags |= ASYNC_INITIALIZED;
+ portp->port.flags |= ASYNC_INITIALIZED;
clear_bit(TTY_IO_ERROR, &tty->flags);
}
clear_bit(ST_INITIALIZING, &portp->state);
@@ -851,9 +851,9 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
* The sleep here does not need interrupt protection since the wakeup
* for it is done with the same context.
*/
- if (portp->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&portp->close_wait);
- if (portp->flags & ASYNC_HUP_NOTIFY)
+ if (portp->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&portp->port.close_wait);
+ if (portp->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
return -ERESTARTSYS;
}
@@ -867,7 +867,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
return rc;
}
- portp->flags |= ASYNC_NORMAL_ACTIVE;
+ portp->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -895,7 +895,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
return;
}
- portp->flags |= ASYNC_CLOSING;
+ portp->port.flags |= ASYNC_CLOSING;
/*
* May want to wait for data to drain before closing. The BUSY flag
@@ -911,7 +911,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, portp->closing_wait);
- portp->flags &= ~ASYNC_INITIALIZED;
+ portp->port.flags &= ~ASYNC_INITIALIZED;
brdp = stli_brds[portp->brdnr];
stli_rawclose(brdp, portp, 0, 0);
if (tty->termios->c_cflag & HUPCL) {
@@ -931,16 +931,16 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
stli_flushbuffer(tty);
tty->closing = 0;
- portp->tty = NULL;
+ portp->port.tty = NULL;
if (portp->openwaitcnt) {
if (portp->close_delay)
msleep_interruptible(jiffies_to_msecs(portp->close_delay));
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
}
- portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&portp->close_wait);
+ portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ wake_up_interruptible(&portp->port.close_wait);
}
/*****************************************************************************/
@@ -970,7 +970,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp)
sizeof(asynotify_t), 0)) < 0)
return rc;
- tty = portp->tty;
+ tty = portp->port.tty;
if (tty == NULL)
return -ENODEV;
stli_mkasyport(portp, &aport, tty->termios);
@@ -1169,7 +1169,7 @@ static int stli_setport(struct stliport *portp)
if (portp == NULL)
return -ENODEV;
- if (portp->tty == NULL)
+ if (portp->port.tty == NULL)
return -ENODEV;
if (portp->brdnr >= stli_nrbrds)
return -ENODEV;
@@ -1177,7 +1177,7 @@ static int stli_setport(struct stliport *portp)
if (brdp == NULL)
return -ENODEV;
- stli_mkasyport(portp, &aport, portp->tty->termios);
+ stli_mkasyport(portp, &aport, portp->port.tty->termios);
return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
}
@@ -1196,7 +1196,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
rc = 0;
doclocal = 0;
- if (portp->tty->termios->c_cflag & CLOCAL)
+ if (portp->port.tty->termios->c_cflag & CLOCAL)
doclocal++;
spin_lock_irqsave(&stli_lock, flags);
@@ -1211,14 +1211,14 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
&portp->asig, sizeof(asysigs_t), 0)) < 0)
break;
if (tty_hung_up_p(filp) ||
- ((portp->flags & ASYNC_INITIALIZED) == 0)) {
- if (portp->flags & ASYNC_HUP_NOTIFY)
+ ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
+ if (portp->port.flags & ASYNC_HUP_NOTIFY)
rc = -EBUSY;
else
rc = -ERESTARTSYS;
break;
}
- if (((portp->flags & ASYNC_CLOSING) == 0) &&
+ if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
(doclocal || (portp->sigs & TIOCM_CD))) {
break;
}
@@ -1226,7 +1226,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
rc = -ERESTARTSYS;
break;
}
- interruptible_sleep_on(&portp->open_wait);
+ interruptible_sleep_on(&portp->port.open_wait);
}
spin_lock_irqsave(&stli_lock, flags);
@@ -1548,7 +1548,7 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s
sio.type = PORT_UNKNOWN;
sio.line = portp->portnr;
sio.irq = 0;
- sio.flags = portp->flags;
+ sio.flags = portp->port.flags;
sio.baud_base = portp->baud_base;
sio.close_delay = portp->close_delay;
sio.closing_wait = portp->closing_wait;
@@ -1583,11 +1583,11 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s
if ((sio.baud_base != portp->baud_base) ||
(sio.close_delay != portp->close_delay) ||
((sio.flags & ~ASYNC_USR_MASK) !=
- (portp->flags & ~ASYNC_USR_MASK)))
+ (portp->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
}
- portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
+ portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
(sio.flags & ASYNC_USR_MASK);
portp->baud_base = sio.baud_base;
portp->close_delay = sio.close_delay;
@@ -1751,7 +1751,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
tty->hw_stopped = 0;
if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
}
/*****************************************************************************/
@@ -1834,7 +1834,7 @@ static void stli_hangup(struct tty_struct *tty)
if (brdp == NULL)
return;
- portp->flags &= ~ASYNC_INITIALIZED;
+ portp->port.flags &= ~ASYNC_INITIALIZED;
if (!test_bit(ST_CLOSING, &portp->state))
stli_rawclose(brdp, portp, 0, 0);
@@ -1855,12 +1855,12 @@ static void stli_hangup(struct tty_struct *tty)
clear_bit(ST_TXBUSY, &portp->state);
clear_bit(ST_RXSTOP, &portp->state);
set_bit(TTY_IO_ERROR, &tty->flags);
- portp->tty = NULL;
- portp->flags &= ~ASYNC_NORMAL_ACTIVE;
+ portp->port.tty = NULL;
+ portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
portp->refcount = 0;
spin_unlock_irqrestore(&stli_lock, flags);
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
}
/*****************************************************************************/
@@ -2188,7 +2188,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp)
if (test_bit(ST_RXSTOP, &portp->state))
return;
- tty = portp->tty;
+ tty = portp->port.tty;
if (tty == NULL)
return;
@@ -2362,7 +2362,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
if (ap->notify) {
nt = ap->changed;
ap->notify = 0;
- tty = portp->tty;
+ tty = portp->port.tty;
if (nt.signal & SG_DCD) {
oldsigs = portp->sigs;
@@ -2370,10 +2370,10 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
clear_bit(ST_GETSIGS, &portp->state);
if ((portp->sigs & TIOCM_CD) &&
((oldsigs & TIOCM_CD) == 0))
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
if ((oldsigs & TIOCM_CD) &&
((portp->sigs & TIOCM_CD) == 0)) {
- if (portp->flags & ASYNC_CHECK_CD) {
+ if (portp->port.flags & ASYNC_CHECK_CD) {
if (tty)
tty_hangup(tty);
}
@@ -2392,7 +2392,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
if (tty != NULL) {
tty_insert_flip_char(tty, 0, TTY_BREAK);
- if (portp->flags & ASYNC_SAK) {
+ if (portp->port.flags & ASYNC_SAK) {
do_SAK(tty);
EBRDENABLE(brdp);
}
@@ -2542,17 +2542,17 @@ static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermio
/*
* Start of by setting the baud, char size, parity and stop bit info.
*/
- pp->baudout = tty_get_baud_rate(portp->tty);
+ pp->baudout = tty_get_baud_rate(portp->port.tty);
if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
pp->baudout = 57600;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
pp->baudout = 115200;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
pp->baudout = 230400;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
pp->baudout = 460800;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
pp->baudout = (portp->baud_base / portp->custom_divisor);
}
if (pp->baudout > STL_MAXBAUD)
@@ -2625,9 +2625,9 @@ static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermio
* Set up clocal processing as required.
*/
if (tiosp->c_cflag & CLOCAL)
- portp->flags &= ~ASYNC_CHECK_CD;
+ portp->port.flags &= ~ASYNC_CHECK_CD;
else
- portp->flags |= ASYNC_CHECK_CD;
+ portp->port.flags |= ASYNC_CHECK_CD;
/*
* Transfer any persistent flags into the asyport structure.
@@ -2703,8 +2703,8 @@ static int stli_initports(struct stlibrd *brdp)
portp->baud_base = STL_BAUDBASE;
portp->close_delay = STL_CLOSEDELAY;
portp->closing_wait = 30 * HZ;
- init_waitqueue_head(&portp->open_wait);
- init_waitqueue_head(&portp->close_wait);
+ init_waitqueue_head(&portp->port.open_wait);
+ init_waitqueue_head(&portp->port.close_wait);
init_waitqueue_head(&portp->raw_wait);
panelport++;
if (panelport >= brdp->panels[panelnr]) {
@@ -4246,18 +4246,18 @@ static int stli_portcmdstats(struct stliport *portp)
stli_comstats.panel = portp->panelnr;
stli_comstats.port = portp->portnr;
stli_comstats.state = portp->state;
- stli_comstats.flags = portp->flags;
+ stli_comstats.flags = portp->port.flag;
spin_lock_irqsave(&brd_lock, flags);
- if (portp->tty != NULL) {
- if (portp->tty->driver_data == portp) {
- stli_comstats.ttystate = portp->tty->flags;
+ if (portp->port.tty != NULL) {
+ if (portp->port.tty->driver_data == portp) {
+ stli_comstats.ttystate = portp->port.tty->flags;
stli_comstats.rxbuffered = -1;
- if (portp->tty->termios != NULL) {
- stli_comstats.cflags = portp->tty->termios->c_cflag;
- stli_comstats.iflags = portp->tty->termios->c_iflag;
- stli_comstats.oflags = portp->tty->termios->c_oflag;
- stli_comstats.lflags = portp->tty->termios->c_lflag;
+ if (portp->port.tty->termios != NULL) {
+ stli_comstats.cflags = portp->port.tty->termios->c_cflag;
+ stli_comstats.iflags = portp->port.tty->termios->c_iflag;
+ stli_comstats.oflags = portp->port.tty->termios->c_oflag;
+ stli_comstats.lflags = portp->port.tty->termios->c_lflag;
}
}
}
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index e21346da310..2bba250ffc8 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -130,17 +130,13 @@ struct moxaq_str {
};
struct moxa_port {
+ struct tty_port port;
struct moxa_board_conf *board;
- struct tty_struct *tty;
void __iomem *tableAddr;
int type;
- int close_delay;
- unsigned int count;
- int asyncflags;
int cflag;
unsigned long statusflags;
- wait_queue_head_t open_wait;
u8 DCDState;
u8 lineCtrl;
@@ -348,10 +344,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
if (status & 4)
tmp.dcd = 1;
- if (!p->tty || !p->tty->termios)
+ if (!p->port.tty || !p->port.tty->termios)
tmp.cflag = p->cflag;
else
- tmp.cflag = p->tty->termios->c_cflag;
+ tmp.cflag = p->port.tty->termios->c_cflag;
copy:
if (copy_to_user(argm, &tmp, sizeof(tmp))) {
mutex_unlock(&moxa_openlock);
@@ -825,10 +821,9 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
}
for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) {
+ tty_port_init(&p->port);
p->type = PORT_16550A;
- p->close_delay = 5 * HZ / 10;
p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
- init_waitqueue_head(&p->open_wait);
}
switch (brd->boardType) {
@@ -884,12 +879,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
/* pci hot-un-plug support */
for (a = 0; a < brd->numPorts; a++)
- if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
- tty_hangup(brd->ports[a].tty);
+ if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
+ tty_hangup(brd->ports[a].port.tty);
while (1) {
opened = 0;
for (a = 0; a < brd->numPorts; a++)
- if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
+ if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
opened++;
mutex_unlock(&moxa_openlock);
if (!opened)
@@ -1104,9 +1099,9 @@ static void moxa_close_port(struct moxa_port *ch)
{
moxa_shut_down(ch);
MoxaPortFlushData(ch, 2);
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- ch->tty->driver_data = NULL;
- ch->tty = NULL;
+ ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ ch->port.tty->driver_data = NULL;
+ ch->port.tty = NULL;
}
static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
@@ -1117,7 +1112,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
u8 dcd;
while (1) {
- prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE);
+ prepare_to_wait(&ch->port.open_wait, &wait, TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp)) {
#ifdef SERIAL_DO_RESTART
retval = -ERESTARTSYS;
@@ -1138,7 +1133,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
}
schedule();
}
- finish_wait(&ch->open_wait, &wait);
+ finish_wait(&ch->port.open_wait, &wait);
return retval;
}
@@ -1163,16 +1158,16 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
}
ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
- ch->count++;
+ ch->port.count++;
tty->driver_data = ch;
- ch->tty = tty;
- if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
+ ch->port.tty = tty;
+ if (!(ch->port.flags & ASYNC_INITIALIZED)) {
ch->statusflags = 0;
moxa_set_tty_param(tty, tty->termios);
MoxaPortLineCtrl(ch, 1, 1);
MoxaPortEnable(ch);
MoxaSetFifo(ch, ch->type == PORT_16550A);
- ch->asyncflags |= ASYNC_INITIALIZED;
+ ch->port.flags |= ASYNC_INITIALIZED;
}
mutex_unlock(&moxa_openlock);
@@ -1181,11 +1176,11 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
retval = moxa_block_till_ready(tty, filp, ch);
mutex_lock(&moxa_openlock);
if (retval) {
- if (ch->count) /* 0 means already hung up... */
- if (--ch->count == 0)
+ if (ch->port.count) /* 0 means already hung up... */
+ if (--ch->port.count == 0)
moxa_close_port(ch);
} else
- ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
+ ch->port.flags |= ASYNC_NORMAL_ACTIVE;
mutex_unlock(&moxa_openlock);
return retval;
@@ -1204,21 +1199,21 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
ch = tty->driver_data;
if (ch == NULL)
goto unlock;
- if (tty->count == 1 && ch->count != 1) {
+ if (tty->count == 1 && ch->port.count != 1) {
printk(KERN_WARNING "moxa_close: bad serial port count; "
- "tty->count is 1, ch->count is %d\n", ch->count);
- ch->count = 1;
+ "tty->count is 1, ch->port.count is %d\n", ch->port.count);
+ ch->port.count = 1;
}
- if (--ch->count < 0) {
+ if (--ch->port.count < 0) {
printk(KERN_WARNING "moxa_close: bad serial port count, "
"device=%s\n", tty->name);
- ch->count = 0;
+ ch->port.count = 0;
}
- if (ch->count)
+ if (ch->port.count)
goto unlock;
ch->cflag = tty->termios->c_cflag;
- if (ch->asyncflags & ASYNC_INITIALIZED) {
+ if (ch->port.flags & ASYNC_INITIALIZED) {
moxa_setup_empty_event(tty);
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
}
@@ -1374,7 +1369,7 @@ static void moxa_set_termios(struct tty_struct *tty,
return;
moxa_set_tty_param(tty, old_termios);
if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty))
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
}
static void moxa_stop(struct tty_struct *tty)
@@ -1412,20 +1407,20 @@ static void moxa_hangup(struct tty_struct *tty)
mutex_unlock(&moxa_openlock);
return;
}
- ch->count = 0;
+ ch->port.count = 0;
moxa_close_port(ch);
mutex_unlock(&moxa_openlock);
- wake_up_interruptible(&ch->open_wait);
+ wake_up_interruptible(&ch->port.open_wait);
}
static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{
dcd = !!dcd;
- if (dcd != p->DCDState && p->tty && C_CLOCAL(p->tty)) {
+ if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) {
if (!dcd)
- tty_hangup(p->tty);
+ tty_hangup(p->port.tty);
}
p->DCDState = dcd;
}
@@ -1433,9 +1428,9 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
u16 __iomem *ip)
{
- struct tty_struct *tty = p->tty;
+ struct tty_struct *tty = p->port.tty;
void __iomem *ofsAddr;
- unsigned int inited = p->asyncflags & ASYNC_INITIALIZED;
+ unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
u16 intr;
if (tty) {
@@ -1566,9 +1561,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
static void moxa_shut_down(struct moxa_port *ch)
{
- struct tty_struct *tp = ch->tty;
+ struct tty_struct *tp = ch->port.tty;
- if (!(ch->asyncflags & ASYNC_INITIALIZED))
+ if (!(ch->port.flags & ASYNC_INITIALIZED))
return;
MoxaPortDisable(ch);
@@ -1580,7 +1575,7 @@ static void moxa_shut_down(struct moxa_port *ch)
MoxaPortLineCtrl(ch, 0, 0);
spin_lock_bh(&moxa_lock);
- ch->asyncflags &= ~ASYNC_INITIALIZED;
+ ch->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_bh(&moxa_lock);
}
@@ -1975,7 +1970,7 @@ static int MoxaPortWriteData(struct moxa_port *port,
c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);
if (c > len)
c = len;
- moxaLog.txcnt[port->tty->index] += c;
+ moxaLog.txcnt[port->port.tty->index] += c;
total = c;
if (spage == epage) {
bufhead = readw(ofsAddr + Ofs_txb);
@@ -2017,7 +2012,7 @@ static int MoxaPortWriteData(struct moxa_port *port,
static int MoxaPortReadData(struct moxa_port *port)
{
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
unsigned char *dst;
void __iomem *baseAddr, *ofsAddr, *ofs;
unsigned int count, len, total;
@@ -2124,10 +2119,10 @@ static int moxa_get_serial_info(struct moxa_port *info,
{
struct serial_struct tmp = {
.type = info->type,
- .line = info->tty->index,
- .flags = info->asyncflags,
+ .line = info->port.tty->index,
+ .flags = info->port.flags,
.baud_base = 921600,
- .close_delay = info->close_delay
+ .close_delay = info->port.close_delay
};
return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
}
@@ -2148,13 +2143,13 @@ static int moxa_set_serial_info(struct moxa_port *info,
if (!capable(CAP_SYS_ADMIN)) {
if (((new_serial.flags & ~ASYNC_USR_MASK) !=
- (info->asyncflags & ~ASYNC_USR_MASK)))
+ (info->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
} else
- info->close_delay = new_serial.close_delay * HZ / 100;
+ info->port.close_delay = new_serial.close_delay * HZ / 100;
new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
- new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
+ new_serial.flags |= (info->port.flags & ASYNC_FLAGS);
MoxaSetFifo(info, new_serial.type == PORT_16550A);
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 4b81a85c5b5..6307e301bd2 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -222,8 +222,8 @@ struct mxser_mon_ext {
struct mxser_board;
struct mxser_port {
+ struct tty_port port;
struct mxser_board *board;
- struct tty_struct *tty;
unsigned long ioaddr;
unsigned long opmode_ioaddr;
@@ -234,7 +234,6 @@ struct mxser_port {
int rx_low_water;
int baud_base; /* max. speed */
int type; /* UART type */
- int flags; /* defined in tty.h */
int x_char; /* xon/xoff character */
int IER; /* Interrupt Enable Register */
@@ -244,20 +243,14 @@ struct mxser_port {
unsigned char ldisc_stop_rx;
int custom_divisor;
- int close_delay;
- unsigned short closing_wait;
unsigned char err_shadow;
- unsigned long event;
- int count; /* # of fd on device */
- int blocked_open; /* # of blocked opens */
struct async_icount icount; /* kernel counters for 4 input interrupts */
int timeout;
int read_status_mask;
int ignore_status_mask;
int xmit_fifo_size;
- unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
int xmit_cnt;
@@ -267,7 +260,6 @@ struct mxser_port {
struct mxser_mon mon_data;
spinlock_t slock;
- wait_queue_head_t open_wait;
wait_queue_head_t delta_msr_wait;
};
@@ -575,7 +567,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
*/
if ((filp->f_flags & O_NONBLOCK) ||
test_bit(TTY_IO_ERROR, &tty->flags)) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -585,32 +577,32 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
/*
* Block waiting for the carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, port->count is dropped by one, so that
+ * this loop, port->port.count is dropped by one, so that
* mxser_close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&port->open_wait, &wait);
+ add_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->slock, flags);
if (!tty_hung_up_p(filp))
- port->count--;
+ port->port.count--;
spin_unlock_irqrestore(&port->slock, flags);
- port->blocked_open++;
+ port->port.blocked_open++;
while (1) {
spin_lock_irqsave(&port->slock, flags);
outb(inb(port->ioaddr + UART_MCR) |
UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR);
spin_unlock_irqrestore(&port->slock, flags);
set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
+ if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(port->flags & ASYNC_CLOSING) &&
+ if (!(port->port.flags & ASYNC_CLOSING) &&
(do_clocal ||
(inb(port->ioaddr + UART_MSR) & UART_MSR_DCD)))
break;
@@ -621,13 +613,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
schedule();
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
+ remove_wait_queue(&port->port.open_wait, &wait);
if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
+ port->port.count++;
+ port->port.blocked_open--;
if (retval)
return retval;
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -636,7 +628,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
int quot = 0, baud;
unsigned char cval;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return -1;
if (!(info->ioaddr))
@@ -647,13 +639,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
if (newspd == 134) {
quot = 2 * info->baud_base / 269;
- tty_encode_baud_rate(info->tty, 134, 134);
+ tty_encode_baud_rate(info->port.tty, 134, 134);
} else if (newspd) {
quot = info->baud_base / newspd;
if (quot == 0)
quot = 1;
baud = info->baud_base/quot;
- tty_encode_baud_rate(info->tty, baud, baud);
+ tty_encode_baud_rate(info->port.tty, baud, baud);
} else {
quot = 0;
}
@@ -679,7 +671,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
#ifdef BOTHER
- if (C_BAUD(info->tty) == BOTHER) {
+ if (C_BAUD(info->port.tty) == BOTHER) {
quot = info->baud_base % newspd;
quot *= 8;
if (quot % newspd > newspd / 2) {
@@ -707,14 +699,14 @@ static int mxser_change_speed(struct mxser_port *info,
int ret = 0;
unsigned char status;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return ret;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
if (!(info->ioaddr))
return ret;
- if (mxser_set_baud_method[info->tty->index] == 0)
- mxser_set_baud(info, tty_get_baud_rate(info->tty));
+ if (mxser_set_baud_method[info->port.tty->index] == 0)
+ mxser_set_baud(info, tty_get_baud_rate(info->port.tty));
/* byte size and parity */
switch (cflag & CSIZE) {
@@ -777,15 +769,15 @@ static int mxser_change_speed(struct mxser_port *info,
info->IER &= ~UART_IER_MSI;
info->MCR &= ~UART_MCR_AFE;
if (cflag & CRTSCTS) {
- info->flags |= ASYNC_CTS_FLOW;
+ info->port.flags |= ASYNC_CTS_FLOW;
info->IER |= UART_IER_MSI;
if ((info->type == PORT_16550A) || (info->board->chip_flag)) {
info->MCR |= UART_MCR_AFE;
} else {
status = inb(info->ioaddr + UART_MSR);
- if (info->tty->hw_stopped) {
+ if (info->port.tty->hw_stopped) {
if (status & UART_MSR_CTS) {
- info->tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
if (info->type != PORT_16550A &&
!info->board->chip_flag) {
outb(info->IER & ~UART_IER_THRI,
@@ -795,11 +787,11 @@ static int mxser_change_speed(struct mxser_port *info,
outb(info->IER, info->ioaddr +
UART_IER);
}
- tty_wakeup(info->tty);
+ tty_wakeup(info->port.tty);
}
} else {
if (!(status & UART_MSR_CTS)) {
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
if ((info->type != PORT_16550A) &&
(!info->board->chip_flag)) {
info->IER &= ~UART_IER_THRI;
@@ -810,13 +802,13 @@ static int mxser_change_speed(struct mxser_port *info,
}
}
} else {
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
}
outb(info->MCR, info->ioaddr + UART_MCR);
if (cflag & CLOCAL) {
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
} else {
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
info->IER |= UART_IER_MSI;
}
outb(info->IER, info->ioaddr + UART_IER);
@@ -825,21 +817,21 @@ static int mxser_change_speed(struct mxser_port *info,
* Set up parity check flag
*/
info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= UART_LSR_BI;
info->ignore_status_mask = 0;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= UART_LSR_BI;
info->read_status_mask |= UART_LSR_BI;
/*
* If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty)) {
+ if (I_IGNPAR(info->port.tty)) {
info->ignore_status_mask |=
UART_LSR_OE |
UART_LSR_PE |
@@ -851,16 +843,16 @@ static int mxser_change_speed(struct mxser_port *info,
}
}
if (info->board->chip_flag) {
- mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->tty));
- mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->tty));
- if (I_IXON(info->tty)) {
+ mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty));
+ mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty));
+ if (I_IXON(info->port.tty)) {
mxser_enable_must_rx_software_flow_control(
info->ioaddr);
} else {
mxser_disable_must_rx_software_flow_control(
info->ioaddr);
}
- if (I_IXOFF(info->tty)) {
+ if (I_IXOFF(info->port.tty)) {
mxser_enable_must_tx_software_flow_control(
info->ioaddr);
} else {
@@ -890,15 +882,15 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
port->mon_data.modem_status = status;
wake_up_interruptible(&port->delta_msr_wait);
- if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+ if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
if (status & UART_MSR_DCD)
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
}
- if (port->flags & ASYNC_CTS_FLOW) {
- if (port->tty->hw_stopped) {
+ if (port->port.flags & ASYNC_CTS_FLOW) {
+ if (port->port.tty->hw_stopped) {
if (status & UART_MSR_CTS) {
- port->tty->hw_stopped = 0;
+ port->port.tty->hw_stopped = 0;
if ((port->type != PORT_16550A) &&
(!port->board->chip_flag)) {
@@ -908,11 +900,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
outb(port->IER, port->ioaddr +
UART_IER);
}
- tty_wakeup(port->tty);
+ tty_wakeup(port->port.tty);
}
} else {
if (!(status & UART_MSR_CTS)) {
- port->tty->hw_stopped = 1;
+ port->port.tty->hw_stopped = 1;
if (port->type != PORT_16550A &&
!port->board->chip_flag) {
port->IER &= ~UART_IER_THRI;
@@ -935,23 +927,23 @@ static int mxser_startup(struct mxser_port *info)
spin_lock_irqsave(&info->slock, flags);
- if (info->flags & ASYNC_INITIALIZED) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
free_page(page);
spin_unlock_irqrestore(&info->slock, flags);
return 0;
}
if (!info->ioaddr || !info->type) {
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
free_page(page);
spin_unlock_irqrestore(&info->slock, flags);
return 0;
}
- if (info->xmit_buf)
+ if (info->port.xmit_buf)
free_page(page);
else
- info->xmit_buf = (unsigned char *) page;
+ info->port.xmit_buf = (unsigned char *) page;
/*
* Clear the FIFO buffers and disable them
@@ -973,8 +965,8 @@ static int mxser_startup(struct mxser_port *info)
if (inb(info->ioaddr + UART_LSR) == 0xff) {
spin_unlock_irqrestore(&info->slock, flags);
if (capable(CAP_SYS_ADMIN)) {
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
return 0;
} else
return -ENODEV;
@@ -1012,15 +1004,15 @@ static int mxser_startup(struct mxser_port *info)
(void) inb(info->ioaddr + UART_IIR);
(void) inb(info->ioaddr + UART_MSR);
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/*
* and set the speed of the serial port
*/
mxser_change_speed(info, NULL);
- info->flags |= ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&info->slock, flags);
return 0;
@@ -1034,7 +1026,7 @@ static void mxser_shutdown(struct mxser_port *info)
{
unsigned long flags;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
spin_lock_irqsave(&info->slock, flags);
@@ -1048,15 +1040,15 @@ static void mxser_shutdown(struct mxser_port *info)
/*
* Free the IRQ, if necessary
*/
- if (info->xmit_buf) {
- free_page((unsigned long) info->xmit_buf);
- info->xmit_buf = NULL;
+ if (info->port.xmit_buf) {
+ free_page((unsigned long) info->port.xmit_buf);
+ info->port.xmit_buf = NULL;
}
info->IER = 0;
outb(0x00, info->ioaddr + UART_IER);
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
outb(info->MCR, info->ioaddr + UART_MCR);
@@ -1072,10 +1064,10 @@ static void mxser_shutdown(struct mxser_port *info)
/* read data port to reset things */
(void) inb(info->ioaddr + UART_RX);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ info->port.flags &= ~ASYNC_INITIALIZED;
if (info->board->chip_flag)
SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
@@ -1105,12 +1097,12 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
return -ENODEV;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
*/
spin_lock_irqsave(&info->slock, flags);
- info->count++;
+ info->port.count++;
spin_unlock_irqrestore(&info->slock, flags);
retval = mxser_startup(info);
if (retval)
@@ -1170,42 +1162,42 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&info->slock, flags);
return;
}
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. Info->count should always
+ * structure will be freed. Info->port.count should always
* be one in these conditions. If it's greater than
* one, we've got real problems, since it means the
* serial port won't be shutdown.
*/
printk(KERN_ERR "mxser_close: bad serial port count; "
- "tty->count is 1, info->count is %d\n", info->count);
- info->count = 1;
+ "tty->count is 1, info->port.count is %d\n", info->port.count);
+ info->port.count = 1;
}
- if (--info->count < 0) {
+ if (--info->port.count < 0) {
printk(KERN_ERR "mxser_close: bad serial port count for "
- "ttys%d: %d\n", tty->index, info->count);
- info->count = 0;
+ "ttys%d: %d\n", tty->index, info->port.count);
+ info->port.count = 0;
}
- if (info->count) {
+ if (info->port.count) {
spin_unlock_irqrestore(&info->slock, flags);
return;
}
- info->flags |= ASYNC_CLOSING;
+ info->port.flags |= ASYNC_CLOSING;
spin_unlock_irqrestore(&info->slock, flags);
/*
* Save the termios structure, since this port may have
* separate termios for callout and dialin.
*/
- if (info->flags & ASYNC_NORMAL_ACTIVE)
+ if (info->port.flags & ASYNC_NORMAL_ACTIVE)
info->normal_termios = *tty->termios;
/*
* Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, info->closing_wait);
+ if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, info->port.closing_wait);
/*
* At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the
@@ -1216,7 +1208,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
if (info->board->chip_flag)
info->IER &= ~MOXA_MUST_RECV_ISR;
- if (info->flags & ASYNC_INITIALIZED) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
outb(info->IER, info->ioaddr + UART_IER);
/*
* Before we drop DTR, make sure the UART transmitter
@@ -1236,15 +1228,14 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
tty_ldisc_flush(tty);
tty->closing = 0;
- info->event = 0;
- info->tty = NULL;
- if (info->blocked_open) {
- if (info->close_delay)
- schedule_timeout_interruptible(info->close_delay);
- wake_up_interruptible(&info->open_wait);
+ info->port.tty = NULL;
+ if (info->port.blocked_open) {
+ if (info->port.close_delay)
+ schedule_timeout_interruptible(info->port.close_delay);
+ wake_up_interruptible(&info->port.open_wait);
}
- info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+ info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
}
static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1253,7 +1244,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
struct mxser_port *info = tty->driver_data;
unsigned long flags;
- if (!info->xmit_buf)
+ if (!info->port.xmit_buf)
return 0;
while (1) {
@@ -1262,7 +1253,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
if (c <= 0)
break;
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ memcpy(info->port.xmit_buf + info->xmit_head, buf, c);
spin_lock_irqsave(&info->slock, flags);
info->xmit_head = (info->xmit_head + c) &
(SERIAL_XMIT_SIZE - 1);
@@ -1294,14 +1285,14 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch)
struct mxser_port *info = tty->driver_data;
unsigned long flags;
- if (!info->xmit_buf)
+ if (!info->port.xmit_buf)
return 0;
if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
return 0;
spin_lock_irqsave(&info->slock, flags);
- info->xmit_buf[info->xmit_head++] = ch;
+ info->port.xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= SERIAL_XMIT_SIZE - 1;
info->xmit_cnt++;
spin_unlock_irqrestore(&info->slock, flags);
@@ -1327,7 +1318,7 @@ static void mxser_flush_chars(struct tty_struct *tty)
if (info->xmit_cnt <= 0 ||
tty->stopped ||
- !info->xmit_buf ||
+ !info->port.xmit_buf ||
(tty->hw_stopped &&
(info->type != PORT_16550A) &&
(!info->board->chip_flag)
@@ -1370,13 +1361,13 @@ static int mxser_get_serial_info(struct mxser_port *info,
{
struct serial_struct tmp = {
.type = info->type,
- .line = info->tty->index,
+ .line = info->port.tty->index,
.port = info->ioaddr,
.irq = info->board->irq,
- .flags = info->flags,
+ .flags = info->port.flags,
.baud_base = info->baud_base,
- .close_delay = info->close_delay,
- .closing_wait = info->closing_wait,
+ .close_delay = info->port.close_delay,
+ .closing_wait = info->port.closing_wait,
.custom_divisor = info->custom_divisor,
.hub6 = 0
};
@@ -1403,33 +1394,33 @@ static int mxser_set_serial_info(struct mxser_port *info,
new_serial.port != info->ioaddr)
return -EINVAL;
- flags = info->flags & ASYNC_SPD_MASK;
+ flags = info->port.flags & ASYNC_SPD_MASK;
if (!capable(CAP_SYS_ADMIN)) {
if ((new_serial.baud_base != info->baud_base) ||
- (new_serial.close_delay != info->close_delay) ||
- ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK)))
+ (new_serial.close_delay != info->port.close_delay) ||
+ ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
- info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+ info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
(new_serial.flags & ASYNC_USR_MASK));
} else {
/*
* OK, past this point, all the error checking has been done.
* At this point, we start making changes.....
*/
- info->flags = ((info->flags & ~ASYNC_FLAGS) |
+ info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
(new_serial.flags & ASYNC_FLAGS));
- info->close_delay = new_serial.close_delay * HZ / 100;
- info->closing_wait = new_serial.closing_wait * HZ / 100;
- info->tty->low_latency =
- (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
- info->tty->low_latency = 0;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
+ info->port.close_delay = new_serial.close_delay * HZ / 100;
+ info->port.closing_wait = new_serial.closing_wait * HZ / 100;
+ info->port.tty->low_latency =
+ (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = 0;
+ if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
(new_serial.baud_base != info->baud_base ||
new_serial.custom_divisor !=
info->custom_divisor)) {
baud = new_serial.baud_base / new_serial.custom_divisor;
- tty_encode_baud_rate(info->tty, baud, baud);
+ tty_encode_baud_rate(info->port.tty, baud, baud);
}
}
@@ -1437,8 +1428,8 @@ static int mxser_set_serial_info(struct mxser_port *info,
process_txrx_fifo(info);
- if (info->flags & ASYNC_INITIALIZED) {
- if (flags != (info->flags & ASYNC_SPD_MASK)) {
+ if (info->port.flags & ASYNC_INITIALIZED) {
+ if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
spin_lock_irqsave(&info->slock, sl_flags);
mxser_change_speed(info, NULL);
spin_unlock_irqrestore(&info->slock, sl_flags);
@@ -1693,12 +1684,12 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
continue;
}
- if (!port->tty || !port->tty->termios)
+ if (!port->port.tty || !port->port.tty->termios)
GMStatus[i].cflag =
port->normal_termios.c_cflag;
else
GMStatus[i].cflag =
- port->tty->termios->c_cflag;
+ port->port.tty->termios->c_cflag;
status = inb(port->ioaddr + UART_MSR);
if (status & 0x80 /*UART_MSR_DCD */ )
@@ -1755,14 +1746,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
mon_data_ext.modem_status[i] =
port->mon_data.modem_status;
mon_data_ext.baudrate[i] =
- tty_get_baud_rate(port->tty);
+ tty_get_baud_rate(port->port.tty);
- if (!port->tty || !port->tty->termios) {
+ if (!port->port.tty || !port->port.tty->termios) {
cflag = port->normal_termios.c_cflag;
iflag = port->normal_termios.c_iflag;
} else {
- cflag = port->tty->termios->c_cflag;
- iflag = port->tty->termios->c_iflag;
+ cflag = port->port.tty->termios->c_cflag;
+ iflag = port->port.tty->termios->c_iflag;
}
mon_data_ext.databits[i] = cflag & CSIZE;
@@ -1989,7 +1980,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
else
info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
- if (info->tty->hw_stopped)
+ if (info->port.tty->hw_stopped)
info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
else
info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
@@ -2038,7 +2029,7 @@ static void mxser_stoprx(struct tty_struct *tty)
}
}
- if (info->tty->termios->c_cflag & CRTSCTS) {
+ if (info->port.tty->termios->c_cflag & CRTSCTS) {
info->MCR &= ~UART_MCR_RTS;
outb(info->MCR, info->ioaddr + UART_MCR);
}
@@ -2075,7 +2066,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
}
}
- if (info->tty->termios->c_cflag & CRTSCTS) {
+ if (info->port.tty->termios->c_cflag & CRTSCTS) {
info->MCR |= UART_MCR_RTS;
outb(info->MCR, info->ioaddr + UART_MCR);
}
@@ -2106,7 +2097,7 @@ static void mxser_start(struct tty_struct *tty)
unsigned long flags;
spin_lock_irqsave(&info->slock, flags);
- if (info->xmit_cnt && info->xmit_buf) {
+ if (info->xmit_cnt && info->port.xmit_buf) {
outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
info->IER |= UART_IER_THRI;
outb(info->IER, info->ioaddr + UART_IER);
@@ -2219,11 +2210,10 @@ static void mxser_hangup(struct tty_struct *tty)
mxser_flush_buffer(tty);
mxser_shutdown(info);
- info->event = 0;
- info->count = 0;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = NULL;
- wake_up_interruptible(&info->open_wait);
+ info->port.count = 0;
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ info->port.tty = NULL;
+ wake_up_interruptible(&info->port.open_wait);
}
/*
@@ -2246,7 +2236,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state)
static void mxser_receive_chars(struct mxser_port *port, int *status)
{
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
unsigned char ch, gdl;
int ignored = 0;
int cnt = 0;
@@ -2302,7 +2292,7 @@ intr_old:
flag = TTY_BREAK;
port->icount.brk++;
- if (port->flags & ASYNC_SAK)
+ if (port->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (*status & UART_LSR_PE) {
flag = TTY_PARITY;
@@ -2333,7 +2323,7 @@ intr_old:
} while (*status & UART_LSR_DR);
end_intr:
- mxvar_log.rxcnt[port->tty->index] += cnt;
+ mxvar_log.rxcnt[port->port.tty->index] += cnt;
port->mon_data.rxcnt += cnt;
port->mon_data.up_rxcnt += cnt;
@@ -2354,18 +2344,18 @@ static void mxser_transmit_chars(struct mxser_port *port)
if (port->x_char) {
outb(port->x_char, port->ioaddr + UART_TX);
port->x_char = 0;
- mxvar_log.txcnt[port->tty->index]++;
+ mxvar_log.txcnt[port->port.tty->index]++;
port->mon_data.txcnt++;
port->mon_data.up_txcnt++;
port->icount.tx++;
return;
}
- if (port->xmit_buf == NULL)
+ if (port->port.xmit_buf == NULL)
return;
- if ((port->xmit_cnt <= 0) || port->tty->stopped ||
- (port->tty->hw_stopped &&
+ if ((port->xmit_cnt <= 0) || port->port.tty->stopped ||
+ (port->port.tty->hw_stopped &&
(port->type != PORT_16550A) &&
(!port->board->chip_flag))) {
port->IER &= ~UART_IER_THRI;
@@ -2376,20 +2366,20 @@ static void mxser_transmit_chars(struct mxser_port *port)
cnt = port->xmit_cnt;
count = port->xmit_fifo_size;
do {
- outb(port->xmit_buf[port->xmit_tail++],
+ outb(port->port.xmit_buf[port->xmit_tail++],
port->ioaddr + UART_TX);
port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1);
if (--port->xmit_cnt <= 0)
break;
} while (--count > 0);
- mxvar_log.txcnt[port->tty->index] += (cnt - port->xmit_cnt);
+ mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt);
port->mon_data.txcnt += (cnt - port->xmit_cnt);
port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
port->icount.tx += (cnt - port->xmit_cnt);
if (port->xmit_cnt < WAKEUP_CHARS)
- tty_wakeup(port->tty);
+ tty_wakeup(port->port.tty);
if (port->xmit_cnt <= 0) {
port->IER &= ~UART_IER_THRI;
@@ -2440,9 +2430,9 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
if (iir & UART_IIR_NO_INT)
break;
iir &= MOXA_MUST_IIR_MASK;
- if (!port->tty ||
- (port->flags & ASYNC_CLOSING) ||
- !(port->flags &
+ if (!port->port.tty ||
+ (port->port.flags & ASYNC_CLOSING) ||
+ !(port->port.flags &
ASYNC_INITIALIZED)) {
status = inb(port->ioaddr + UART_LSR);
outb(0x27, port->ioaddr + UART_FCR);
@@ -2550,6 +2540,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
for (i = 0; i < brd->info->nports; i++) {
info = &brd->ports[i];
+ tty_port_init(&info->port);
info->board = brd;
info->stop_rx = 0;
info->ldisc_stop_rx = 0;
@@ -2558,16 +2549,15 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
if (brd->chip_flag != MOXA_OTHER_UART)
mxser_enable_must_enchance_mode(info->ioaddr);
- info->flags = ASYNC_SHARE_IRQ;
+ info->port.flags = ASYNC_SHARE_IRQ;
info->type = brd->uart_type;
process_txrx_fifo(info);
info->custom_divisor = info->baud_base * 16;
- info->close_delay = 5 * HZ / 10;
- info->closing_wait = 30 * HZ;
+ info->port.close_delay = 5 * HZ / 10;
+ info->port.closing_wait = 30 * HZ;
info->normal_termios = mxvar_sdriver->init_termios;
- init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->delta_msr_wait);
memset(&info->mon_data, 0, sizeof(struct mxser_mon));
info->err_shadow = 0;
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index a35bfd7ee80..ed4e03333ab 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -199,7 +199,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty);
#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
#define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
-static struct tty_ldisc n_hdlc_ldisc = {
+static struct tty_ldisc_ops n_hdlc_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "hdlc",
@@ -342,8 +342,8 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
#endif
/* Flush any pending characters in the driver and discipline. */
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
+ if (tty->ldisc.ops->flush_buffer)
+ tty->ldisc.ops->flush_buffer(tty);
tty_driver_flush_buffer(tty);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 90216906233..ae377aa473b 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -143,7 +143,7 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
char *fp, int count);
-static struct tty_ldisc tty_ldisc_N_R3964 = {
+static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "R3964",
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 8096389b0dc..708c2b1dbe5 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1573,7 +1573,7 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
return mask;
}
-struct tty_ldisc tty_ldisc_N_TTY = {
+struct tty_ldisc_ops tty_ldisc_N_TTY = {
.magic = TTY_LDISC_MAGIC,
.name = "n_tty",
.open = n_tty_open,
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 197cd7a0c33..a22662b6a1a 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -444,7 +444,7 @@ nvram_init(void)
/* First test whether the driver should init at all */
if (!CHECK_DRIVER_INIT())
- return -ENXIO;
+ return -ENODEV;
ret = misc_register(&nvram_dev);
if (ret) {
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 1dd0e992c83..b694d430f10 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -514,8 +514,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
return;
ld = tty_ldisc_ref(tty);
if (ld) {
- if (ld->receive_buf)
- ld->receive_buf(tty, data, flags, count);
+ if (ld->ops->receive_buf)
+ ld->ops->receive_buf(tty, data, flags, count);
tty_ldisc_deref(ld);
}
}
@@ -3886,9 +3886,8 @@ static bool rx_get_frame(MGSLPC_INFO *info)
framesize = 0;
#if SYNCLINK_GENERIC_HDLC
{
- struct net_device_stats *stats = hdlc_stats(info->netdev);
- stats->rx_errors++;
- stats->rx_frame_errors++;
+ info->netdev->stats.rx_errors++;
+ info->netdev->stats.rx_frame_errors++;
}
#endif
} else
@@ -4144,7 +4143,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
{
MGSLPC_INFO *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
@@ -4159,8 +4157,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
info->tx_put = info->tx_count = skb->len;
/* update network statistics */
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
/* done with socket buffer, so free it */
dev_kfree_skb(skb);
@@ -4376,14 +4374,13 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static void hdlcdev_tx_timeout(struct net_device *dev)
{
MGSLPC_INFO *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("hdlcdev_tx_timeout(%s)\n",dev->name);
- stats->tx_errors++;
- stats->tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
spin_lock_irqsave(&info->lock,flags);
tx_stop(info);
@@ -4416,27 +4413,26 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
{
struct sk_buff *skb = dev_alloc_skb(size);
struct net_device *dev = info->netdev;
- struct net_device_stats *stats = hdlc_stats(dev);
if (debug_level >= DEBUG_LEVEL_INFO)
printk("hdlcdev_rx(%s)\n",dev->name);
if (skb == NULL) {
printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name);
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
- memcpy(skb_put(skb, size),buf,size);
+ memcpy(skb_put(skb, size), buf, size);
- skb->protocol = hdlc_type_trans(skb, info->netdev);
+ skb->protocol = hdlc_type_trans(skb, dev);
- stats->rx_packets++;
- stats->rx_bytes += size;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += size;
netif_rx(skb);
- info->netdev->last_rx = jiffies;
+ dev->last_rx = jiffies;
}
/**
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 0a05c038ae6..76b27932d22 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun
c = to->receive_room;
if (c > count)
c = count;
- to->ldisc.receive_buf(to, buf, NULL, c);
+ to->ldisc.ops->receive_buf(to, buf, NULL, c);
return c;
}
@@ -149,11 +149,11 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
int count;
/* We should get the line discipline lock for "tty->link" */
- if (!to || !to->ldisc.chars_in_buffer)
+ if (!to || !to->ldisc.ops->chars_in_buffer)
return 0;
/* The ldisc must report 0 if no characters available to be read */
- count = to->ldisc.chars_in_buffer(to);
+ count = to->ldisc.ops->chars_in_buffer(to);
if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
@@ -186,8 +186,8 @@ static void pty_flush_buffer(struct tty_struct *tty)
if (!to)
return;
- if (to->ldisc.flush_buffer)
- to->ldisc.flush_buffer(to);
+ if (to->ldisc.ops->flush_buffer)
+ to->ldisc.ops->flush_buffer(to);
if (to->packet) {
spin_lock_irqsave(&tty->ctrl_lock, flags);
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h
index a03a538a3ef..5ab51679caa 100644
--- a/drivers/char/rio/cirrus.h
+++ b/drivers/char/rio/cirrus.h
@@ -35,9 +35,6 @@
***************************************************************************/
#ifndef _cirrus_h
-#ifndef lint
-/* static char* _cirrus_h_sccs = "@(#)cirrus.h 1.16"; */
-#endif
#define _cirrus_h 1
/* Bit fields for particular registers shared with driver */
diff --git a/drivers/char/rio/cmdblk.h b/drivers/char/rio/cmdblk.h
index c46b2fdb662..9ed4f861675 100644
--- a/drivers/char/rio/cmdblk.h
+++ b/drivers/char/rio/cmdblk.h
@@ -33,12 +33,6 @@
#ifndef __rio_cmdblk_h__
#define __rio_cmdblk_h__
-#ifdef SCCS_LABELS
-#ifndef lint
-static char *_cmdblk_h_sccs_ = "@(#)cmdblk.h 1.2";
-#endif
-#endif
-
/*
** the structure of a command block, used to queue commands destined for
** a rup.
diff --git a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h
index 357ae572243..c1e7a279807 100644
--- a/drivers/char/rio/cmdpkt.h
+++ b/drivers/char/rio/cmdpkt.h
@@ -32,12 +32,6 @@
#ifndef __rio_cmdpkt_h__
#define __rio_cmdpkt_h__
-#ifdef SCCS_LABELS
-#ifndef lint
-static char *_cmdpkt_h_sccs_ = "@(#)cmdpkt.h 1.2";
-#endif
-#endif
-
/*
** overlays for the data area of a packet. Used in both directions
** (to build a packet to send, and to interpret a packet that arrives)
diff --git a/drivers/char/rio/daemon.h b/drivers/char/rio/daemon.h
index 6e63f8b2c47..4af90323fd0 100644
--- a/drivers/char/rio/daemon.h
+++ b/drivers/char/rio/daemon.h
@@ -33,12 +33,6 @@
#ifndef __rio_daemon_h__
#define __rio_daemon_h__
-#ifdef SCCS_LABELS
-#ifndef lint
-static char *_daemon_h_sccs_ = "@(#)daemon.h 1.3";
-#endif
-#endif
-
/*
** structures used on /dev/rio
diff --git a/drivers/char/rio/errors.h b/drivers/char/rio/errors.h
index 1d0d8914433..bdb05234090 100644
--- a/drivers/char/rio/errors.h
+++ b/drivers/char/rio/errors.h
@@ -33,12 +33,6 @@
#ifndef __rio_errors_h__
#define __rio_errors_h__
-#ifdef SCCS_LABELS
-#ifndef lint
-static char *_errors_h_sccs_ = "@(#)errors.h 1.2";
-#endif
-#endif
-
/*
** error codes
*/
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index 9e7283bd81a..078d44f85e4 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -35,12 +35,6 @@
#include <linux/kdev_t.h>
-#ifdef SCCS_LABELS
-#ifndef lint
-static char *_func_h_sccs_ = "@(#)func.h 1.3";
-#endif
-#endif
-
/* rioboot.c */
int RIOBootCodeRTA(struct rio_info *, struct DownLoad *);
int RIOBootCodeHOST(struct rio_info *, struct DownLoad *);
diff --git a/drivers/char/rio/map.h b/drivers/char/rio/map.h
index bdbcd09c8b8..8366978578c 100644
--- a/drivers/char/rio/map.h
+++ b/drivers/char/rio/map.h
@@ -33,10 +33,6 @@
#ifndef __rio_map_h__
#define __rio_map_h__
-#ifdef SCCS_LABELS
-static char *_map_h_sccs_ = "@(#)map.h 1.2";
-#endif
-
/*
** mapping structure passed to and from the config.rio program to
** determine the current topology of the world
diff --git a/drivers/char/rio/param.h b/drivers/char/rio/param.h
index 675c200b245..7e9b6283e8a 100644
--- a/drivers/char/rio/param.h
+++ b/drivers/char/rio/param.h
@@ -33,11 +33,6 @@
#ifndef __rio_param_h__
#define __rio_param_h__
-#ifdef SCCS_LABELS
-static char *_param_h_sccs_ = "@(#)param.h 1.2";
-#endif
-
-
/*
** the param command block, as used in OPEN and PARAM calls.
*/
diff --git a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h
index 9764ef85c5a..acc8fa439df 100644
--- a/drivers/char/rio/parmmap.h
+++ b/drivers/char/rio/parmmap.h
@@ -37,13 +37,6 @@
#ifndef _parmap_h
#define _parmap_h
-
-#ifdef SCCS_LABELS
-#ifndef lint
-/* static char *_rio_parmmap_h_sccs = "@(#)parmmap.h 1.4"; */
-#endif
-#endif
-
typedef struct PARM_MAP PARM_MAP;
struct PARM_MAP {
diff --git a/drivers/char/rio/pci.h b/drivers/char/rio/pci.h
index 1eba9118079..6032f913595 100644
--- a/drivers/char/rio/pci.h
+++ b/drivers/char/rio/pci.h
@@ -33,10 +33,6 @@
#ifndef __rio_pci_h__
#define __rio_pci_h__
-#ifdef SCCS_LABELS
-static char *_pci_h_sccs_ = "@(#)pci.h 1.2";
-#endif
-
/*
** PCI stuff
*/
diff --git a/drivers/char/rio/protsts.h b/drivers/char/rio/protsts.h
index 69fc4bc3415..8ab79401d3e 100644
--- a/drivers/char/rio/protsts.h
+++ b/drivers/char/rio/protsts.h
@@ -37,13 +37,6 @@
#ifndef _protsts_h
#define _protsts_h 1
-
-#ifdef SCCS_LABELS
-#ifndef lint
-/* static char *_rio_protsts_h_sccs = "@(#)protsts.h 1.4"; */
-#endif
-#endif
-
/*************************************************
* ACK bit. Last Packet received OK. Set by
* rxpkt to indicate that the Packet has been
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 412777cd1e6..0cdfee15291 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -25,11 +25,6 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
* USA.
*
- * Revision history:
- * $Log: rio.c,v $
- * Revision 1.1 1999/07/11 10:13:54 wolff
- * Initial revision
- *
* */
#include <linux/module.h>
@@ -436,7 +431,7 @@ static void rio_disable_tx_interrupts(void *ptr)
{
func_enter();
- /* port->gs.flags &= ~GS_TX_INTEN; */
+ /* port->gs.port.flags &= ~GS_TX_INTEN; */
func_exit();
}
@@ -460,7 +455,7 @@ static void rio_enable_tx_interrupts(void *ptr)
* In general we cannot count on "tx empty" interrupts, although
* the interrupt routine seems to be able to tell the difference.
*/
- PortP->gs.flags &= ~GS_TX_INTEN;
+ PortP->gs.port.flags &= ~GS_TX_INTEN;
func_exit();
}
@@ -515,7 +510,7 @@ static void rio_shutdown_port(void *ptr)
func_enter();
PortP = (struct Port *) ptr;
- PortP->gs.tty = NULL;
+ PortP->gs.port.tty = NULL;
func_exit();
}
@@ -534,7 +529,7 @@ static void rio_hungup(void *ptr)
func_enter();
PortP = (struct Port *) ptr;
- PortP->gs.tty = NULL;
+ PortP->gs.port.tty = NULL;
func_exit();
}
@@ -554,12 +549,12 @@ static void rio_close(void *ptr)
riotclose(ptr);
- if (PortP->gs.count) {
- printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.count);
- PortP->gs.count = 0;
+ if (PortP->gs.port.count) {
+ printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.port.count);
+ PortP->gs.port.count = 0;
}
- PortP->gs.tty = NULL;
+ PortP->gs.port.tty = NULL;
func_exit();
}
@@ -854,8 +849,8 @@ static int rio_init_datastructures(void)
/*
* Initializing wait queue
*/
- init_waitqueue_head(&port->gs.open_wait);
- init_waitqueue_head(&port->gs.close_wait);
+ init_waitqueue_head(&port->gs.port.open_wait);
+ init_waitqueue_head(&port->gs.port.close_wait);
}
#else
/* We could postpone initializing them to when they are configured. */
diff --git a/drivers/char/rio/rioboard.h b/drivers/char/rio/rioboard.h
index 822c071a693..252230043c8 100644
--- a/drivers/char/rio/rioboard.h
+++ b/drivers/char/rio/rioboard.h
@@ -29,12 +29,6 @@
/* */
/************************************************************************/
-/* History...
-
-1.0.0 26/04/99 NPV Creation.
-
-*/
-
#ifndef _rioboard_h /* If RIOBOARD.H not already defined */
#define _rioboard_h 1
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 7b96e081488..01f2654d5a2 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -30,9 +30,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
-#endif
#include <linux/module.h>
#include <linux/slab.h>
@@ -487,12 +484,12 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
** If the device is a modem, then check the modem
** carrier.
*/
- if (PortP->gs.tty == NULL)
+ if (PortP->gs.port.tty == NULL)
break;
- if (PortP->gs.tty->termios == NULL)
+ if (PortP->gs.port.tty->termios == NULL)
break;
- if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) {
+ if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) {
rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n");
/*
@@ -509,7 +506,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
** wakeup anyone in WOPEN
*/
if (PortP->State & (PORT_ISOPEN | RIO_WOPEN))
- wake_up_interruptible(&PortP->gs.open_wait);
+ wake_up_interruptible(&PortP->gs.port.open_wait);
}
} else {
/*
@@ -517,7 +514,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
*/
if (PortP->State & RIO_CARR_ON) {
if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN))
- tty_hangup(PortP->gs.tty);
+ tty_hangup(PortP->gs.port.tty);
PortP->State &= ~RIO_CARR_ON;
rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n");
}
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index d65ceb9a434..eecee0f576d 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -29,10 +29,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
-#endif
-
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/char/rio/riodrvr.h b/drivers/char/rio/riodrvr.h
index 3cffe275f21..0907e711b35 100644
--- a/drivers/char/rio/riodrvr.h
+++ b/drivers/char/rio/riodrvr.h
@@ -35,10 +35,6 @@
#include <asm/param.h> /* for HZ */
-#ifdef SCCS_LABELS
-static char *_riodrvr_h_sccs_ = "@(#)riodrvr.h 1.3";
-#endif
-
#define MEMDUMP_SIZE 32
#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT)
diff --git a/drivers/char/rio/rioinfo.h b/drivers/char/rio/rioinfo.h
index 8de7966e603..42ff1e79d96 100644
--- a/drivers/char/rio/rioinfo.h
+++ b/drivers/char/rio/rioinfo.h
@@ -33,10 +33,6 @@
#ifndef __rioinfo_h
#define __rioinfo_h
-#ifdef SCCS_LABELS
-static char *_rioinfo_h_sccs_ = "@(#)rioinfo.h 1.2";
-#endif
-
/*
** Host card data structure
*/
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index add1718295e..be0ba401966 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -29,9 +29,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
-#endif
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index ea21686c69a..71f87600907 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -29,10 +29,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2";
-#endif
-
#include <linux/module.h>
#include <linux/slab.h>
@@ -106,7 +102,7 @@ void RIOTxEnable(char *en)
PortP = (struct Port *) en;
p = (struct rio_info *) PortP->p;
- tty = PortP->gs.tty;
+ tty = PortP->gs.port.tty;
rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt);
@@ -162,7 +158,7 @@ void RIOTxEnable(char *en)
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
- tty_wakeup(PortP->gs.tty);
+ tty_wakeup(PortP->gs.port.tty);
}
@@ -245,7 +241,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP)
** find corresponding tty structure. The process of mapping
** the ports puts these here.
*/
- ttyP = PortP->gs.tty;
+ ttyP = PortP->gs.port.tty;
/*
** Lock the port before we begin working on it.
@@ -339,7 +335,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP)
** find corresponding tty structure. The process of mapping
** the ports puts these here.
*/
- ttyP = PortP->gs.tty;
+ ttyP = PortP->gs.port.tty;
/* If ttyP is NULL, the port is getting closed. Forget about it. */
if (!ttyP) {
rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
@@ -546,7 +542,7 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
intCount++;
- TtyP = PortP->gs.tty;
+ TtyP = PortP->gs.port.tty;
if (!TtyP) {
rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
return;
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index 4810b845cc2..d687c17be15 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -30,10 +30,6 @@
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3";
-#endif
-
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -164,7 +160,7 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
func_enter();
- TtyP = PortP->gs.tty;
+ TtyP = PortP->gs.port.tty;
rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index 7a9df7dcf9a..706c2a25f7a 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -29,9 +29,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_rioroute_c_sccs_ = "@(#)rioroute.c 1.3";
-#endif
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/char/rio/riospace.h b/drivers/char/rio/riospace.h
index 534f1f5b9f5..ffb31d4332b 100644
--- a/drivers/char/rio/riospace.h
+++ b/drivers/char/rio/riospace.h
@@ -33,10 +33,6 @@
#ifndef __rio_riospace_h__
#define __rio_riospace_h__
-#ifdef SCCS_LABELS
-static char *_riospace_h_sccs_ = "@(#)riospace.h 1.2";
-#endif
-
#define RIO_LOCATOR_LEN 16
#define MAX_RIO_BOARDS 4
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
index 2b24488e95f..3d15802dc0f 100644
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -29,9 +29,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_riotable_c_sccs_ = "@(#)riotable.c 1.2";
-#endif
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index c99354843be..2fb49e89b32 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -29,10 +29,6 @@
**
** -----------------------------------------------------------------------------
*/
-#ifdef SCCS_LABELS
-static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3";
-#endif
-
#define __EXPLICIT_DEF_H__
@@ -144,14 +140,14 @@ int riotopen(struct tty_struct *tty, struct file *filp)
tty->driver_data = PortP;
- PortP->gs.tty = tty;
- PortP->gs.count++;
+ PortP->gs.port.tty = tty;
+ PortP->gs.port.count++;
rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt);
retval = gs_init_port(&PortP->gs);
if (retval) {
- PortP->gs.count--;
+ PortP->gs.port.count--;
return -ENXIO;
}
/*
@@ -297,7 +293,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
** insert test for carrier here. -- ???
** I already see that test here. What's the deal? -- REW
*/
- if ((PortP->gs.tty->termios->c_cflag & CLOCAL) ||
+ if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) ||
(PortP->ModemState & RIOC_MSVR1_CD)) {
rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
/*
@@ -305,16 +301,16 @@ int riotopen(struct tty_struct *tty, struct file *filp)
wakeup((caddr_t) &tp->tm.c_canq);
*/
PortP->State |= RIO_CARR_ON;
- wake_up_interruptible(&PortP->gs.open_wait);
+ wake_up_interruptible(&PortP->gs.port.open_wait);
} else { /* no carrier - wait for DCD */
/*
- while (!(PortP->gs.tty->termios->c_state & CARR_ON) &&
+ while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) &&
!(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
*/
while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) {
rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort);
/*
- PortP->gs.tty->termios->c_state |= WOPEN;
+ PortP->gs.port.tty->termios->c_state |= WOPEN;
*/
PortP->State |= RIO_WOPEN;
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -384,7 +380,7 @@ int riotclose(void *ptr)
/* PortP = p->RIOPortp[SysPort]; */
rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP);
/* tp = PortP->TtyP; *//* Get tty */
- tty = PortP->gs.tty;
+ tty = PortP->gs.port.tty;
rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty);
if (PortP->gs.closing_wait)
diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h
index 769744e575a..20ed73f3fd7 100644
--- a/drivers/char/rio/route.h
+++ b/drivers/char/rio/route.h
@@ -37,12 +37,6 @@
#ifndef _route_h
#define _route_h
-#ifdef SCCS_LABELS
-#ifndef lint
-/* static char *_rio_route_h_sccs = "@(#)route.h 1.3"; */
-#endif
-#endif
-
#define MAX_LINKS 4
#define MAX_NODES 17 /* Maximum nodes in a subnet */
#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for
diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h
index 46bd532f774..7abf0cba0f2 100644
--- a/drivers/char/rio/unixrup.h
+++ b/drivers/char/rio/unixrup.h
@@ -33,10 +33,6 @@
#ifndef __rio_unixrup_h__
#define __rio_unixrup_h__
-#ifdef SCCS_LABELS
-static char *_unixrup_h_sccs_ = "@(#)unixrup.h 1.2";
-#endif
-
/*
** UnixRup data structure. This contains pointers to actual RUPs on the
** host card, and all the command/boot control stuff.
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index f073c710ab8..724b2b20f4b 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -322,7 +322,7 @@ static struct riscom_port *rc_get_port(struct riscom_board const *bp,
channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
if (channel < CD180_NCH) {
port = &rc_port[board_No(bp) * RC_NPORT + channel];
- if (port->flags & ASYNC_INITIALIZED)
+ if (port->port.flags & ASYNC_INITIALIZED)
return port;
}
printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
@@ -341,7 +341,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
if (port == NULL)
return;
- tty = port->tty;
+ tty = port->port.tty;
#ifdef RC_REPORT_OVERRUN
status = rc_in(bp, CD180_RCSR);
@@ -364,7 +364,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
printk(KERN_INFO "rc%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
flag = TTY_BREAK;
- if (port->flags & ASYNC_SAK)
+ if (port->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (status & RCSR_PE)
@@ -392,7 +392,7 @@ static void rc_receive(struct riscom_board const *bp)
if (port == NULL)
return;
- tty = port->tty;
+ tty = port->port.tty;
count = rc_in(bp, CD180_RDCR);
@@ -422,7 +422,7 @@ static void rc_transmit(struct riscom_board const *bp)
if (port == NULL)
return;
- tty = port->tty;
+ tty = port->port.tty;
if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
@@ -467,7 +467,7 @@ static void rc_transmit(struct riscom_board const *bp)
count = CD180_NFIFO;
do {
- rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]);
+ rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]);
port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
if (--port->xmit_cnt <= 0)
break;
@@ -492,12 +492,12 @@ static void rc_check_modem(struct riscom_board const *bp)
if (port == NULL)
return;
- tty = port->tty;
+ tty = port->port.tty;
mcr = rc_in(bp, CD180_MCR);
if (mcr & MCR_CDCHG) {
if (rc_in(bp, CD180_MSVR) & MSVR_CD)
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
else
tty_hangup(tty);
}
@@ -632,15 +632,12 @@ static void rc_shutdown_board(struct riscom_board *bp)
*/
static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
{
- struct tty_struct *tty = port->tty;
+ struct tty_struct *tty = port->port.tty;
unsigned long baud;
long tmp;
unsigned char cor1 = 0, cor3 = 0;
unsigned char mcor1 = 0, mcor2 = 0;
- if (tty == NULL || tty->termios == NULL)
- return;
-
port->IER = 0;
port->COR2 = 0;
port->MSVR = MSVR_RTS;
@@ -786,39 +783,30 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
{
unsigned long flags;
- if (port->flags & ASYNC_INITIALIZED)
+ if (port->port.flags & ASYNC_INITIALIZED)
return 0;
- if (!port->xmit_buf) {
- /* We may sleep in get_zeroed_page() */
- unsigned long tmp = get_zeroed_page(GFP_KERNEL);
- if (tmp == 0)
- return -ENOMEM;
- if (port->xmit_buf)
- free_page(tmp);
- else
- port->xmit_buf = (unsigned char *) tmp;
- }
+ if (tty_port_alloc_xmit_buf(&port->port) < 0)
+ return -ENOMEM;
+
spin_lock_irqsave(&riscom_lock, flags);
- if (port->tty)
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
- if (port->count == 1)
+ clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
+ if (port->port.count == 1)
bp->count++;
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
rc_change_speed(bp, port);
- port->flags |= ASYNC_INITIALIZED;
+ port->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&riscom_lock, flags);
return 0;
}
/* Must be called with interrupts disabled */
-static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
+static void rc_shutdown_port(struct tty_struct *tty,
+ struct riscom_board *bp, struct riscom_port *port)
{
- struct tty_struct *tty;
-
- if (!(port->flags & ASYNC_INITIALIZED))
+ if (!(port->port.flags & ASYNC_INITIALIZED))
return;
#ifdef RC_REPORT_OVERRUN
@@ -836,14 +824,8 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
printk("].\n");
}
#endif
- if (port->xmit_buf) {
- free_page((unsigned long) port->xmit_buf);
- port->xmit_buf = NULL;
- }
-
- tty = port->tty;
-
- if (tty == NULL || C_HUPCL(tty)) {
+ tty_port_free_xmit_buf(&port->port);
+ if (C_HUPCL(tty)) {
/* Drop DTR */
bp->DTR |= (1u << port_No(port));
rc_out(bp, RC_DTR, bp->DTR);
@@ -858,9 +840,8 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
port->IER = 0;
rc_out(bp, CD180_IER, port->IER);
- if (tty)
- set_bit(TTY_IO_ERROR, &tty->flags);
- port->flags &= ~ASYNC_INITIALIZED;
+ set_bit(TTY_IO_ERROR, &tty->flags);
+ port->port.flags &= ~ASYNC_INITIALIZED;
if (--bp->count < 0) {
printk(KERN_INFO "rc%d: rc_shutdown_port: "
@@ -890,9 +871,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
* If the device is in the middle of being closed, then block
* until it's done, and then try again.
*/
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY)
+ if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&port->port.close_wait);
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
else
return -ERESTARTSYS;
@@ -904,7 +885,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -919,16 +900,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&port->open_wait, &wait);
+ add_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&riscom_lock, flags);
if (!tty_hung_up_p(filp))
- port->count--;
+ port->port.count--;
spin_unlock_irqrestore(&riscom_lock, flags);
- port->blocked_open++;
+ port->port.blocked_open++;
while (1) {
spin_lock_irqsave(&riscom_lock, flags);
@@ -942,14 +923,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
+ !(port->port.flags & ASYNC_INITIALIZED)) {
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(port->flags & ASYNC_CLOSING) &&
+ if (!(port->port.flags & ASYNC_CLOSING) &&
(do_clocal || CD))
break;
if (signal_pending(current)) {
@@ -959,14 +940,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
schedule();
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
+ remove_wait_queue(&port->port.open_wait, &wait);
if (!tty_hung_up_p(filp))
- port->count++;
- port->blocked_open--;
+ port->port.count++;
+ port->port.blocked_open--;
if (retval)
return retval;
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -990,9 +971,9 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
if (error)
return error;
- port->count++;
+ port->port.count++;
tty->driver_data = port;
- port->tty = tty;
+ port->port.tty = tty;
error = rc_setup_port(bp, port);
if (error == 0)
@@ -1031,28 +1012,28 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
goto out;
bp = port_Board(port);
- if ((tty->count == 1) && (port->count != 1)) {
+ if ((tty->count == 1) && (port->port.count != 1)) {
printk(KERN_INFO "rc%d: rc_close: bad port count;"
" tty->count is 1, port count is %d\n",
- board_No(bp), port->count);
- port->count = 1;
+ board_No(bp), port->port.count);
+ port->port.count = 1;
}
- if (--port->count < 0) {
+ if (--port->port.count < 0) {
printk(KERN_INFO "rc%d: rc_close: bad port count "
"for tty%d: %d\n",
- board_No(bp), port_No(port), port->count);
- port->count = 0;
+ board_No(bp), port_No(port), port->port.count);
+ port->port.count = 0;
}
- if (port->count)
+ if (port->port.count)
goto out;
- port->flags |= ASYNC_CLOSING;
+ port->port.flags |= ASYNC_CLOSING;
/*
* Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
- if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, port->closing_wait);
+ if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, port->port.closing_wait);
/*
* At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the
@@ -1060,7 +1041,7 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
* line status register.
*/
port->IER &= ~IER_RXD;
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->port.flags & ASYNC_INITIALIZED) {
port->IER &= ~IER_TXRDY;
port->IER |= IER_TXEMPTY;
rc_out(bp, CD180_CAR, port_No(port));
@@ -1077,19 +1058,19 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
break;
}
}
- rc_shutdown_port(bp, port);
+ rc_shutdown_port(tty, bp, port);
rc_flush_buffer(tty);
tty_ldisc_flush(tty);
tty->closing = 0;
- port->tty = NULL;
- if (port->blocked_open) {
- if (port->close_delay)
- msleep_interruptible(jiffies_to_msecs(port->close_delay));
- wake_up_interruptible(&port->open_wait);
+ port->port.tty = NULL;
+ if (port->port.blocked_open) {
+ if (port->port.close_delay)
+ msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
+ wake_up_interruptible(&port->port.open_wait);
}
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&port->close_wait);
+ port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ wake_up_interruptible(&port->port.close_wait);
out:
spin_unlock_irqrestore(&riscom_lock, flags);
@@ -1108,9 +1089,6 @@ static int rc_write(struct tty_struct *tty,
bp = port_Board(port);
- if (!tty || !port->xmit_buf)
- return 0;
-
while (1) {
spin_lock_irqsave(&riscom_lock, flags);
@@ -1119,7 +1097,7 @@ static int rc_write(struct tty_struct *tty,
if (c <= 0)
break; /* lock continues to be held */
- memcpy(port->xmit_buf + port->xmit_head, buf, c);
+ memcpy(port->port.xmit_buf + port->xmit_head, buf, c);
port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
port->xmit_cnt += c;
@@ -1151,15 +1129,12 @@ static int rc_put_char(struct tty_struct *tty, unsigned char ch)
if (rc_paranoia_check(port, tty->name, "rc_put_char"))
return 0;
- if (!tty || !port->xmit_buf)
- return 0;
-
spin_lock_irqsave(&riscom_lock, flags);
if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
goto out;
- port->xmit_buf[port->xmit_head++] = ch;
+ port->port.xmit_buf[port->xmit_head++] = ch;
port->xmit_head &= SERIAL_XMIT_SIZE - 1;
port->xmit_cnt++;
ret = 1;
@@ -1177,8 +1152,7 @@ static void rc_flush_chars(struct tty_struct *tty)
if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
return;
- if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
- !port->xmit_buf)
+ if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped)
return;
spin_lock_irqsave(&riscom_lock, flags);
@@ -1317,22 +1291,22 @@ static int rc_set_serial_info(struct riscom_port *port,
return -EINVAL;
#endif
- change_speed = ((port->flags & ASYNC_SPD_MASK) !=
+ change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
if (!capable(CAP_SYS_ADMIN)) {
- if ((tmp.close_delay != port->close_delay) ||
- (tmp.closing_wait != port->closing_wait) ||
+ if ((tmp.close_delay != port->port.close_delay) ||
+ (tmp.closing_wait != port->port.closing_wait) ||
((tmp.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK)))
+ (port->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
- port->flags = ((port->flags & ~ASYNC_USR_MASK) |
+ port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
(tmp.flags & ASYNC_USR_MASK));
} else {
- port->flags = ((port->flags & ~ASYNC_FLAGS) |
+ port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
(tmp.flags & ASYNC_FLAGS));
- port->close_delay = tmp.close_delay;
- port->closing_wait = tmp.closing_wait;
+ port->port.close_delay = tmp.close_delay;
+ port->port.closing_wait = tmp.closing_wait;
}
if (change_speed) {
unsigned long flags;
@@ -1355,10 +1329,10 @@ static int rc_get_serial_info(struct riscom_port *port,
tmp.line = port - rc_port;
tmp.port = bp->base;
tmp.irq = bp->irq;
- tmp.flags = port->flags;
+ tmp.flags = port->port.flags;
tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
- tmp.close_delay = port->close_delay * HZ/100;
- tmp.closing_wait = port->closing_wait * HZ/100;
+ tmp.close_delay = port->port.close_delay * HZ/100;
+ tmp.closing_wait = port->port.closing_wait * HZ/100;
tmp.xmit_fifo_size = CD180_NFIFO;
return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
@@ -1480,7 +1454,7 @@ static void rc_start(struct tty_struct *tty)
spin_lock_irqsave(&riscom_lock, flags);
- if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
+ if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) {
port->IER |= IER_TXRDY;
rc_out(bp, CD180_CAR, port_No(port));
rc_out(bp, CD180_IER, port->IER);
@@ -1498,11 +1472,11 @@ static void rc_hangup(struct tty_struct *tty)
bp = port_Board(port);
- rc_shutdown_port(bp, port);
- port->count = 0;
- port->flags &= ~ASYNC_NORMAL_ACTIVE;
- port->tty = NULL;
- wake_up_interruptible(&port->open_wait);
+ rc_shutdown_port(tty, bp, port);
+ port->port.count = 0;
+ port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ port->port.tty = NULL;
+ wake_up_interruptible(&port->port.open_wait);
}
static void rc_set_termios(struct tty_struct *tty,
@@ -1575,11 +1549,8 @@ static int __init rc_init_drivers(void)
}
memset(rc_port, 0, sizeof(rc_port));
for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
+ tty_port_init(&rc_port[i].port);
rc_port[i].magic = RISCOM8_MAGIC;
- rc_port[i].close_delay = 50 * HZ / 100;
- rc_port[i].closing_wait = 3000 * HZ / 100;
- init_waitqueue_head(&rc_port[i].open_wait);
- init_waitqueue_head(&rc_port[i].close_wait);
}
return 0;
}
diff --git a/drivers/char/riscom8.h b/drivers/char/riscom8.h
index cdfdf439447..c9876b3f971 100644
--- a/drivers/char/riscom8.h
+++ b/drivers/char/riscom8.h
@@ -66,23 +66,15 @@ struct riscom_board {
struct riscom_port {
int magic;
+ struct tty_port port;
int baud_base;
- int flags;
- struct tty_struct * tty;
- int count;
- int blocked_open;
int timeout;
- int close_delay;
- unsigned char * xmit_buf;
int custom_divisor;
int xmit_head;
int xmit_tail;
int xmit_cnt;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
short wakeup_chars;
short break_length;
- unsigned short closing_wait;
unsigned char mark_mask;
unsigned char IER;
unsigned char MSVR;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 743dc80a932..e670eae2f51 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -72,6 +72,7 @@
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
+#include <linux/serial.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
@@ -81,7 +82,7 @@
#include <linux/completion.h>
#include <linux/wait.h>
#include <linux/pci.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/atomic.h>
#include <asm/unaligned.h>
#include <linux/bitops.h>
@@ -434,15 +435,15 @@ static void rp_do_transmit(struct r_port *info)
#endif
if (!info)
return;
- if (!info->tty) {
+ if (!info->port.tty) {
printk(KERN_WARNING "rp: WARNING %s called with "
- "info->tty==NULL\n", __func__);
+ "info->port.tty==NULL\n", __func__);
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
return;
}
spin_lock_irqsave(&info->slock, flags);
- tty = info->tty;
+ tty = info->port.tty;
info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
/* Loop sending data to FIFO until done or FIFO full */
@@ -502,13 +503,13 @@ static void rp_handle_port(struct r_port *info)
"info->flags & NOT_INIT\n");
return;
}
- if (!info->tty) {
+ if (!info->port.tty) {
printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
- "info->tty==NULL\n");
+ "info->port.tty==NULL\n");
return;
}
cp = &info->channel;
- tty = info->tty;
+ tty = info->port.tty;
IntMask = sGetChanIntID(cp) & info->intmask;
#ifdef ROCKET_DEBUG_INTR
@@ -530,7 +531,7 @@ static void rp_handle_port(struct r_port *info)
tty_hangup(tty);
}
info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
#ifdef ROCKET_DEBUG_INTR
if (IntMask & DELTA_CTS) { /* CTS change */
@@ -648,9 +649,9 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
info->board = board;
info->aiop = aiop;
info->chan = chan;
- info->closing_wait = 3000;
- info->close_delay = 50;
- init_waitqueue_head(&info->open_wait);
+ info->port.closing_wait = 3000;
+ info->port.close_delay = 50;
+ init_waitqueue_head(&info->port.open_wait);
init_completion(&info->close_wait);
info->flags &= ~ROCKET_MODE_MASK;
switch (pc104[board][line]) {
@@ -717,7 +718,7 @@ static void configure_r_port(struct r_port *info,
unsigned rocketMode;
int bits, baud, divisor;
CHANNEL_t *cp;
- struct ktermios *t = info->tty->termios;
+ struct ktermios *t = info->port.tty->termios;
cp = &info->channel;
cflag = t->c_cflag;
@@ -750,7 +751,7 @@ static void configure_r_port(struct r_port *info,
}
/* baud rate */
- baud = tty_get_baud_rate(info->tty);
+ baud = tty_get_baud_rate(info->port.tty);
if (!baud)
baud = 9600;
divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
@@ -768,7 +769,7 @@ static void configure_r_port(struct r_port *info,
sSetBaud(cp, divisor);
/* FIXME: Should really back compute a baud rate from the divisor */
- tty_encode_baud_rate(info->tty, baud, baud);
+ tty_encode_baud_rate(info->port.tty, baud, baud);
if (cflag & CRTSCTS) {
info->intmask |= DELTA_CTS;
@@ -793,15 +794,15 @@ static void configure_r_port(struct r_port *info,
* Handle software flow control in the board
*/
#ifdef ROCKET_SOFT_FLOW
- if (I_IXON(info->tty)) {
+ if (I_IXON(info->port.tty)) {
sEnTxSoftFlowCtl(cp);
- if (I_IXANY(info->tty)) {
+ if (I_IXANY(info->port.tty)) {
sEnIXANY(cp);
} else {
sDisIXANY(cp);
}
- sSetTxXONChar(cp, START_CHAR(info->tty));
- sSetTxXOFFChar(cp, STOP_CHAR(info->tty));
+ sSetTxXONChar(cp, START_CHAR(info->port.tty));
+ sSetTxXOFFChar(cp, STOP_CHAR(info->port.tty));
} else {
sDisTxSoftFlowCtl(cp);
sDisIXANY(cp);
@@ -813,24 +814,24 @@ static void configure_r_port(struct r_port *info,
* Set up ignore/read mask words
*/
info->read_status_mask = STMRCVROVRH | 0xFF;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= STMFRAMEH | STMPARITYH;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= STMBREAKH;
/*
* Characters to ignore
*/
info->ignore_status_mask = 0;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= STMBREAKH;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= STMRCVROVRH;
}
@@ -863,7 +864,7 @@ static void configure_r_port(struct r_port *info,
}
}
-/* info->count is considered critical, protected by spinlocks. */
+/* info->port.count is considered critical, protected by spinlocks. */
static int block_til_ready(struct tty_struct *tty, struct file *filp,
struct r_port *info)
{
@@ -897,13 +898,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/*
* Block waiting for the carrier detect and the line to become free. While we are in
- * this loop, info->count is dropped by one, so that rp_close() knows when to free things.
+ * this loop, info->port.count is dropped by one, so that rp_close() knows when to free things.
* We restore it upon exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
#ifdef ROCKET_DEBUG_OPEN
- printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->count);
+ printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->port.count);
#endif
spin_lock_irqsave(&info->slock, flags);
@@ -912,10 +913,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
#else
if (!tty_hung_up_p(filp)) {
extra_count = 1;
- info->count--;
+ info->port.count--;
}
#endif
- info->blocked_open++;
+ info->port.blocked_open++;
spin_unlock_irqrestore(&info->slock, flags);
@@ -940,24 +941,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
}
#ifdef ROCKET_DEBUG_OPEN
printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
- info->line, info->count, info->flags);
+ info->line, info->port.count, info->flags);
#endif
schedule(); /* Don't hold spinlock here, will hang PC */
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
spin_lock_irqsave(&info->slock, flags);
if (extra_count)
- info->count++;
- info->blocked_open--;
+ info->port.count++;
+ info->port.blocked_open--;
spin_unlock_irqrestore(&info->slock, flags);
#ifdef ROCKET_DEBUG_OPEN
printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
if (retval)
return retval;
@@ -1001,9 +1002,9 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
info->xmit_buf = (unsigned char *) page;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
- if (info->count++ == 0) {
+ if (info->port.count++ == 0) {
atomic_inc(&rp_num_ports_open);
#ifdef ROCKET_DEBUG_OPEN
@@ -1012,7 +1013,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
#endif
}
#ifdef ROCKET_DEBUG_OPEN
- printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count);
+ printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
#endif
/*
@@ -1048,13 +1049,13 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
* Set up the tty->alt_speed kludge
*/
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
- info->tty->alt_speed = 57600;
+ info->port.tty->alt_speed = 57600;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
- info->tty->alt_speed = 115200;
+ info->port.tty->alt_speed = 115200;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
- info->tty->alt_speed = 230400;
+ info->port.tty->alt_speed = 230400;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
- info->tty->alt_speed = 460800;
+ info->port.tty->alt_speed = 460800;
configure_r_port(info, NULL);
if (tty->termios->c_cflag & CBAUD) {
@@ -1076,7 +1077,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
}
/*
- * Exception handler that closes a serial port. info->count is considered critical.
+ * Exception handler that closes a serial port. info->port.count is considered critical.
*/
static void rp_close(struct tty_struct *tty, struct file *filp)
{
@@ -1089,14 +1090,14 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
return;
#ifdef ROCKET_DEBUG_OPEN
- printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count);
+ printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
#endif
if (tty_hung_up_p(filp))
return;
spin_lock_irqsave(&info->slock, flags);
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* Uh, oh. tty->count is 1, which means that the tty
* structure will be freed. Info->count should always
@@ -1105,15 +1106,15 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
* serial port won't be shutdown.
*/
printk(KERN_WARNING "rp_close: bad serial port count; "
- "tty->count is 1, info->count is %d\n", info->count);
- info->count = 1;
+ "tty->count is 1, info->port.count is %d\n", info->port.count);
+ info->port.count = 1;
}
- if (--info->count < 0) {
+ if (--info->port.count < 0) {
printk(KERN_WARNING "rp_close: bad serial port count for "
- "ttyR%d: %d\n", info->line, info->count);
- info->count = 0;
+ "ttyR%d: %d\n", info->line, info->port.count);
+ info->port.count = 0;
}
- if (info->count) {
+ if (info->port.count) {
spin_unlock_irqrestore(&info->slock, flags);
return;
}
@@ -1137,8 +1138,8 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
/*
* Wait for the transmit buffer to clear
*/
- if (info->closing_wait != ROCKET_CLOSING_WAIT_NONE)
- tty_wait_until_sent(tty, info->closing_wait);
+ if (info->port.closing_wait != ROCKET_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, info->port.closing_wait);
/*
* Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially
@@ -1167,11 +1168,11 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
- if (info->blocked_open) {
- if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ if (info->port.blocked_open) {
+ if (info->port.close_delay) {
+ msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
} else {
if (info->xmit_buf) {
free_page((unsigned long) info->xmit_buf);
@@ -1327,8 +1328,8 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
memset(&tmp, 0, sizeof (tmp));
tmp.line = info->line;
tmp.flags = info->flags;
- tmp.close_delay = info->close_delay;
- tmp.closing_wait = info->closing_wait;
+ tmp.close_delay = info->port.close_delay;
+ tmp.closing_wait = info->port.closing_wait;
tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
@@ -1353,17 +1354,17 @@ static int set_config(struct r_port *info, struct rocket_config __user *new_info
}
info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
- info->close_delay = new_serial.close_delay;
- info->closing_wait = new_serial.closing_wait;
+ info->port.close_delay = new_serial.close_delay;
+ info->port.closing_wait = new_serial.closing_wait;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
- info->tty->alt_speed = 57600;
+ info->port.tty->alt_speed = 57600;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
- info->tty->alt_speed = 115200;
+ info->port.tty->alt_speed = 115200;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
- info->tty->alt_speed = 230400;
+ info->port.tty->alt_speed = 230400;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
- info->tty->alt_speed = 460800;
+ info->port.tty->alt_speed = 460800;
configure_r_port(info, NULL);
return 0;
@@ -1636,13 +1637,13 @@ static void rp_hangup(struct tty_struct *tty)
rp_flush_buffer(tty);
if (info->flags & ROCKET_CLOSING)
return;
- if (info->count)
+ if (info->port.count)
atomic_dec(&rp_num_ports_open);
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
- info->count = 0;
+ info->port.count = 0;
info->flags &= ~ROCKET_NORMAL_ACTIVE;
- info->tty = NULL;
+ info->port.tty = NULL;
cp = &info->channel;
sDisRxFIFO(cp);
@@ -1653,7 +1654,7 @@ static void rp_hangup(struct tty_struct *tty)
sClrTxXOFF(cp);
info->flags &= ~ROCKET_INITIALIZED;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
/*
@@ -1762,7 +1763,7 @@ static int rp_write(struct tty_struct *tty,
/* Write remaining data into the port's xmit_buf */
while (1) {
- if (!info->tty) /* Seemingly obligatory check... */
+ if (!info->port.tty) /* Seemingly obligatory check... */
goto end;
c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
c = min(c, XMIT_BUF_SIZE - info->xmit_head);
diff --git a/drivers/char/rocket.h b/drivers/char/rocket.h
index ae6b04f90c0..a8b09195ebb 100644
--- a/drivers/char/rocket.h
+++ b/drivers/char/rocket.h
@@ -64,8 +64,8 @@ struct rocket_version {
/*
* For closing_wait and closing_wait2
*/
-#define ROCKET_CLOSING_WAIT_NONE 65535
-#define ROCKET_CLOSING_WAIT_INF 0
+#define ROCKET_CLOSING_WAIT_NONE ASYNC_CLOSING_WAIT_NONE
+#define ROCKET_CLOSING_WAIT_INF ASYNC_CLOSING_WAIT_INF
/*
* Rocketport ioctls -- "RP"
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 143cc432fdb..21f3ff53ba3 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1125,18 +1125,14 @@ Warnings: This function writes the data byte without checking to see if
struct r_port {
int magic;
+ struct tty_port port;
int line;
- int flags;
- int count;
- int blocked_open;
- struct tty_struct *tty;
+ int flags; /* Don't yet match the ASY_ flags!! */
unsigned int board:3;
unsigned int aiop:2;
unsigned int chan:3;
CONTROLLER_t *ctlp;
CHANNEL_t channel;
- int closing_wait;
- int close_delay;
int intmask;
int xmit_fifo_room; /* room in xmit fifo */
unsigned char *xmit_buf;
@@ -1148,8 +1144,7 @@ struct r_port {
int read_status_mask;
int cps;
- wait_queue_head_t open_wait;
- struct completion close_wait;
+ struct completion close_wait; /* Not yet matching the core */
spinlock_t slock;
struct mutex write_mtx;
};
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index d63f5ccc29e..2978a49a172 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -327,7 +327,8 @@ int paste_selection(struct tty_struct *tty)
}
count = sel_buffer_lth - pasted;
count = min(count, tty->receive_room);
- tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count);
+ tty->ldisc.ops->receive_buf(tty, sel_buffer + pasted,
+ NULL, count);
pasted += count;
}
remove_wait_queue(&vc->paste_wait, &wait);
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 2ee4d989375..037dc47e4cb 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -608,9 +608,9 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
if (channel < CD186x_NCH) {
port = &sx_port[board_No(bp) * SX_NPORT + channel];
- dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED);
+ dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",board_No(bp) * SX_NPORT + channel, port, port->port.flags & ASYNC_INITIALIZED);
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->port.flags & ASYNC_INITIALIZED) {
dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
func_exit();
return port;
@@ -637,7 +637,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
func_exit();
return;
}
- tty = port->tty;
+ tty = port->port.tty;
status = sx_in(bp, CD186x_RCSR);
@@ -673,7 +673,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
board_No(bp), port_No(port));
flag = TTY_BREAK;
- if (port->flags & ASYNC_SAK)
+ if (port->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (status & RCSR_PE)
@@ -707,7 +707,7 @@ static inline void sx_receive(struct specialix_board * bp)
func_exit();
return;
}
- tty = port->tty;
+ tty = port->port.tty;
count = sx_in(bp, CD186x_RDCR);
dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
@@ -734,7 +734,7 @@ static inline void sx_transmit(struct specialix_board * bp)
return;
}
dprintk (SX_DEBUG_TX, "port: %p\n", port);
- tty = port->tty;
+ tty = port->port.tty;
if (port->IER & IER_TXEMPTY) {
/* FIFO drained */
@@ -811,7 +811,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
if (!(port = sx_get_port(bp, "Modem")))
return;
- tty = port->tty;
+ tty = port->port.tty;
mcr = sx_in(bp, CD186x_MCR);
printk ("mcr = %02x.\n", mcr);
@@ -821,7 +821,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
if (msvr_cd) {
dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
} else {
dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
tty_hangup(tty);
@@ -1030,7 +1030,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
func_enter();
- if (!(tty = port->tty) || !tty->termios) {
+ if (!(tty = port->port.tty) || !tty->termios) {
func_exit();
return;
}
@@ -1052,9 +1052,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
baud = tty_get_baud_rate(tty);
if (baud == 38400) {
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baud = 57600;
- if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud = 115200;
}
@@ -1244,7 +1244,7 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
func_enter();
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->port.flags & ASYNC_INITIALIZED) {
func_exit();
return 0;
}
@@ -1268,12 +1268,12 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
spin_lock_irqsave(&port->lock, flags);
- if (port->tty)
- clear_bit(TTY_IO_ERROR, &port->tty->flags);
+ if (port->port.tty)
+ clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
sx_change_speed(bp, port);
- port->flags |= ASYNC_INITIALIZED;
+ port->port.flags |= ASYNC_INITIALIZED;
spin_unlock_irqrestore(&port->lock, flags);
@@ -1292,7 +1292,7 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
func_enter();
- if (!(port->flags & ASYNC_INITIALIZED)) {
+ if (!(port->port.flags & ASYNC_INITIALIZED)) {
func_exit();
return;
}
@@ -1315,7 +1315,7 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
- if (!(tty = port->tty) || C_HUPCL(tty)) {
+ if (!(tty = port->port.tty) || C_HUPCL(tty)) {
/* Drop DTR */
sx_out(bp, CD186x_MSVDTR, 0);
}
@@ -1330,7 +1330,7 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
spin_unlock_irqrestore(&bp->lock, flags);
if (tty)
set_bit(TTY_IO_ERROR, &tty->flags);
- port->flags &= ~ASYNC_INITIALIZED;
+ port->port.flags &= ~ASYNC_INITIALIZED;
if (!bp->count)
sx_shutdown_board(bp);
@@ -1354,9 +1354,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
* If the device is in the middle of being closed, then block
* until it's done, and then try again.
*/
- if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&port->close_wait);
- if (port->flags & ASYNC_HUP_NOTIFY) {
+ if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&port->port.close_wait);
+ if (port->port.flags & ASYNC_HUP_NOTIFY) {
func_exit();
return -EAGAIN;
} else {
@@ -1371,7 +1371,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if ((filp->f_flags & O_NONBLOCK) ||
(tty->flags & (1 << TTY_IO_ERROR))) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
func_exit();
return 0;
}
@@ -1387,13 +1387,13 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&port->open_wait, &wait);
+ add_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->lock, flags);
if (!tty_hung_up_p(filp)) {
- port->count--;
+ port->port.count--;
}
spin_unlock_irqrestore(&port->lock, flags);
- port->blocked_open++;
+ port->port.blocked_open++;
while (1) {
spin_lock_irqsave(&bp->lock, flags);
sx_out(bp, CD186x_CAR, port_No(port));
@@ -1410,14 +1410,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
spin_unlock_irqrestore(&bp->lock, flags);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
- !(port->flags & ASYNC_INITIALIZED)) {
- if (port->flags & ASYNC_HUP_NOTIFY)
+ !(port->port.flags & ASYNC_INITIALIZED)) {
+ if (port->port.flags & ASYNC_HUP_NOTIFY)
retval = -EAGAIN;
else
retval = -ERESTARTSYS;
break;
}
- if (!(port->flags & ASYNC_CLOSING) &&
+ if (!(port->port.flags & ASYNC_CLOSING) &&
(do_clocal || CD))
break;
if (signal_pending(current)) {
@@ -1428,19 +1428,19 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&port->open_wait, &wait);
+ remove_wait_queue(&port->port.open_wait, &wait);
spin_lock_irqsave(&port->lock, flags);
if (!tty_hung_up_p(filp)) {
- port->count++;
+ port->port.count++;
}
- port->blocked_open--;
+ port->port.blocked_open--;
spin_unlock_irqrestore(&port->lock, flags);
if (retval) {
func_exit();
return retval;
}
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ port->port.flags |= ASYNC_NORMAL_ACTIVE;
func_exit();
return 0;
}
@@ -1484,10 +1484,10 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
}
spin_lock_irqsave(&bp->lock, flags);
- port->count++;
+ port->port.count++;
bp->count++;
tty->driver_data = port;
- port->tty = tty;
+ port->port.tty = tty;
spin_unlock_irqrestore(&bp->lock, flags);
if ((error = sx_setup_port(bp, port))) {
@@ -1547,15 +1547,15 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
}
bp = port_Board(port);
- if ((tty->count == 1) && (port->count != 1)) {
+ if ((tty->count == 1) && (port->port.count != 1)) {
printk(KERN_ERR "sx%d: sx_close: bad port count;"
" tty->count is 1, port count is %d\n",
- board_No(bp), port->count);
- port->count = 1;
+ board_No(bp), port->port.count);
+ port->port.count = 1;
}
- if (port->count > 1) {
- port->count--;
+ if (port->port.count > 1) {
+ port->port.count--;
bp->count--;
spin_unlock_irqrestore(&port->lock, flags);
@@ -1563,7 +1563,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
func_exit();
return;
}
- port->flags |= ASYNC_CLOSING;
+ port->port.flags |= ASYNC_CLOSING;
/*
* Now we wait for the transmit buffer to clear; and we notify
* the line discipline to only process XON/XOFF characters.
@@ -1571,8 +1571,8 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
tty->closing = 1;
spin_unlock_irqrestore(&port->lock, flags);
dprintk (SX_DEBUG_OPEN, "Closing\n");
- if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
- tty_wait_until_sent(tty, port->closing_wait);
+ if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ tty_wait_until_sent(tty, port->port.closing_wait);
}
/*
* At this point we stop accepting input. To do this, we
@@ -1582,7 +1582,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
*/
dprintk (SX_DEBUG_OPEN, "Closed\n");
port->IER &= ~IER_RXD;
- if (port->flags & ASYNC_INITIALIZED) {
+ if (port->port.flags & ASYNC_INITIALIZED) {
port->IER &= ~IER_TXRDY;
port->IER |= IER_TXEMPTY;
spin_lock_irqsave(&bp->lock, flags);
@@ -1611,10 +1611,10 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
board_No(bp), bp->count, tty->index);
bp->count = 0;
}
- if (--port->count < 0) {
+ if (--port->port.count < 0) {
printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
- board_No(bp), port_No(port), port->count);
- port->count = 0;
+ board_No(bp), port_No(port), port->port.count);
+ port->port.count = 0;
}
sx_shutdown_port(bp, port);
@@ -1622,16 +1622,16 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
tty_ldisc_flush(tty);
spin_lock_irqsave(&port->lock, flags);
tty->closing = 0;
- port->tty = NULL;
+ port->port.tty = NULL;
spin_unlock_irqrestore(&port->lock, flags);
- if (port->blocked_open) {
- if (port->close_delay) {
- msleep_interruptible(jiffies_to_msecs(port->close_delay));
+ if (port->port.blocked_open) {
+ if (port->port.close_delay) {
+ msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
}
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
}
- port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&port->close_wait);
+ port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ wake_up_interruptible(&port->port.close_wait);
func_exit();
}
@@ -1815,7 +1815,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
port_No(port), status, sx_in (bp, CD186x_CAR));
dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
- if (SX_CRTSCTS(port->tty)) {
+ if (SX_CRTSCTS(port->port.tty)) {
result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
| ((status & MSVR_DTR) ? TIOCM_RTS : 0)
| ((status & MSVR_CD) ? TIOCM_CAR : 0)
@@ -1857,7 +1857,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
/* if (set & TIOCM_DTR)
port->MSVR |= MSVR_DTR; */
- if (SX_CRTSCTS(port->tty)) {
+ if (SX_CRTSCTS(port->port.tty)) {
if (set & TIOCM_RTS)
port->MSVR |= MSVR_DTR;
} else {
@@ -1869,7 +1869,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
port->MSVR &= ~MSVR_RTS; */
/* if (clear & TIOCM_DTR)
port->MSVR &= ~MSVR_DTR; */
- if (SX_CRTSCTS(port->tty)) {
+ if (SX_CRTSCTS(port->port.tty)) {
if (clear & TIOCM_RTS)
port->MSVR &= ~MSVR_DTR;
} else {
@@ -1929,27 +1929,27 @@ static inline int sx_set_serial_info(struct specialix_port * port,
lock_kernel();
- change_speed = ((port->flags & ASYNC_SPD_MASK) !=
+ change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
(tmp.flags & ASYNC_SPD_MASK));
change_speed |= (tmp.custom_divisor != port->custom_divisor);
if (!capable(CAP_SYS_ADMIN)) {
- if ((tmp.close_delay != port->close_delay) ||
- (tmp.closing_wait != port->closing_wait) ||
+ if ((tmp.close_delay != port->port.close_delay) ||
+ (tmp.closing_wait != port->port.closing_wait) ||
((tmp.flags & ~ASYNC_USR_MASK) !=
- (port->flags & ~ASYNC_USR_MASK))) {
+ (port->port.flags & ~ASYNC_USR_MASK))) {
func_exit();
unlock_kernel();
return -EPERM;
}
- port->flags = ((port->flags & ~ASYNC_USR_MASK) |
+ port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
(tmp.flags & ASYNC_USR_MASK));
port->custom_divisor = tmp.custom_divisor;
} else {
- port->flags = ((port->flags & ~ASYNC_FLAGS) |
+ port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
(tmp.flags & ASYNC_FLAGS));
- port->close_delay = tmp.close_delay;
- port->closing_wait = tmp.closing_wait;
+ port->port.close_delay = tmp.close_delay;
+ port->port.closing_wait = tmp.closing_wait;
port->custom_divisor = tmp.custom_divisor;
}
if (change_speed) {
@@ -1975,10 +1975,10 @@ static inline int sx_get_serial_info(struct specialix_port * port,
tmp.line = port - sx_port;
tmp.port = bp->base;
tmp.irq = bp->irq;
- tmp.flags = port->flags;
+ tmp.flags = port->port.flags;
tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
- tmp.close_delay = port->close_delay * HZ/100;
- tmp.closing_wait = port->closing_wait * HZ/100;
+ tmp.close_delay = port->port.close_delay * HZ/100;
+ tmp.closing_wait = port->port.closing_wait * HZ/100;
tmp.custom_divisor = port->custom_divisor;
tmp.xmit_fifo_size = CD186x_NFIFO;
unlock_kernel();
@@ -2199,17 +2199,17 @@ static void sx_hangup(struct tty_struct * tty)
sx_shutdown_port(bp, port);
spin_lock_irqsave(&port->lock, flags);
- bp->count -= port->count;
+ bp->count -= port->port.count;
if (bp->count < 0) {
printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
board_No(bp), bp->count, tty->index);
bp->count = 0;
}
- port->count = 0;
- port->flags &= ~ASYNC_NORMAL_ACTIVE;
- port->tty = NULL;
+ port->port.count = 0;
+ port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ port->port.tty = NULL;
spin_unlock_irqrestore(&port->lock, flags);
- wake_up_interruptible(&port->open_wait);
+ wake_up_interruptible(&port->port.open_wait);
func_exit();
}
@@ -2224,10 +2224,6 @@ static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termio
if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
return;
- if (tty->termios->c_cflag == old_termios->c_cflag &&
- tty->termios->c_iflag == old_termios->c_iflag)
- return;
-
bp = port_Board(port);
spin_lock_irqsave(&port->lock, flags);
sx_change_speed(port_Board(port), port);
@@ -2297,10 +2293,7 @@ static int sx_init_drivers(void)
memset(sx_port, 0, sizeof(sx_port));
for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
sx_port[i].magic = SPECIALIX_MAGIC;
- sx_port[i].close_delay = 50 * HZ/100;
- sx_port[i].closing_wait = 3000 * HZ/100;
- init_waitqueue_head(&sx_port[i].open_wait);
- init_waitqueue_head(&sx_port[i].close_wait);
+ tty_port_init(&sx_port[i].port);
spin_lock_init(&sx_port[i].lock);
}
diff --git a/drivers/char/specialix_io8.h b/drivers/char/specialix_io8.h
index 3f2f85bdf51..c63005274d9 100644
--- a/drivers/char/specialix_io8.h
+++ b/drivers/char/specialix_io8.h
@@ -107,23 +107,17 @@ struct specialix_board {
struct specialix_port {
int magic;
+ struct tty_port port;
int baud_base;
int flags;
- struct tty_struct * tty;
- int count;
- int blocked_open;
int timeout;
- int close_delay;
unsigned char * xmit_buf;
int custom_divisor;
int xmit_head;
int xmit_tail;
int xmit_cnt;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
short wakeup_chars;
short break_length;
- unsigned short closing_wait;
unsigned char mark_mask;
unsigned char IER;
unsigned char MSVR;
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index d17be10c5d2..0243efb0be9 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -613,17 +613,17 @@ static void stl_cd_change(struct stlport *portp)
{
unsigned int oldsigs = portp->sigs;
- if (!portp->tty)
+ if (!portp->port.tty)
return;
portp->sigs = stl_getsignals(portp);
if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
- if (portp->flags & ASYNC_CHECK_CD)
- tty_hangup(portp->tty);
+ if (portp->port.flags & ASYNC_CHECK_CD)
+ tty_hangup(portp->port.tty);
}
/*
@@ -734,11 +734,11 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
* On the first open of the device setup the port hardware, and
* initialize the per port data structure.
*/
- portp->tty = tty;
+ portp->port.tty = tty;
tty->driver_data = portp;
- portp->refcount++;
+ portp->port.count++;
- if ((portp->flags & ASYNC_INITIALIZED) == 0) {
+ if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
if (!portp->tx.buf) {
portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
if (!portp->tx.buf)
@@ -752,7 +752,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
stl_enablerxtx(portp, 1, 1);
stl_startrxtx(portp, 1, 0);
clear_bit(TTY_IO_ERROR, &tty->flags);
- portp->flags |= ASYNC_INITIALIZED;
+ portp->port.flags |= ASYNC_INITIALIZED;
}
/*
@@ -761,9 +761,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
* The sleep here does not need interrupt protection since the wakeup
* for it is done with the same context.
*/
- if (portp->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&portp->close_wait);
- if (portp->flags & ASYNC_HUP_NOTIFY)
+ if (portp->port.flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&portp->port.close_wait);
+ if (portp->port.flags & ASYNC_HUP_NOTIFY)
return -EAGAIN;
return -ERESTARTSYS;
}
@@ -777,7 +777,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
if ((rc = stl_waitcarrier(portp, filp)) != 0)
return rc;
- portp->flags |= ASYNC_NORMAL_ACTIVE;
+ portp->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -801,25 +801,25 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
spin_lock_irqsave(&stallion_lock, flags);
- if (portp->tty->termios->c_cflag & CLOCAL)
+ if (portp->port.tty->termios->c_cflag & CLOCAL)
doclocal++;
portp->openwaitcnt++;
if (! tty_hung_up_p(filp))
- portp->refcount--;
+ portp->port.count--;
for (;;) {
/* Takes brd_lock internally */
stl_setsignals(portp, 1, 1);
if (tty_hung_up_p(filp) ||
- ((portp->flags & ASYNC_INITIALIZED) == 0)) {
- if (portp->flags & ASYNC_HUP_NOTIFY)
+ ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
+ if (portp->port.flags & ASYNC_HUP_NOTIFY)
rc = -EBUSY;
else
rc = -ERESTARTSYS;
break;
}
- if (((portp->flags & ASYNC_CLOSING) == 0) &&
+ if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
(doclocal || (portp->sigs & TIOCM_CD)))
break;
if (signal_pending(current)) {
@@ -827,11 +827,11 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
break;
}
/* FIXME */
- interruptible_sleep_on(&portp->open_wait);
+ interruptible_sleep_on(&portp->port.open_wait);
}
if (! tty_hung_up_p(filp))
- portp->refcount++;
+ portp->port.count++;
portp->openwaitcnt--;
spin_unlock_irqrestore(&stallion_lock, flags);
@@ -904,15 +904,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&stallion_lock, flags);
return;
}
- if ((tty->count == 1) && (portp->refcount != 1))
- portp->refcount = 1;
- if (portp->refcount-- > 1) {
+ if ((tty->count == 1) && (portp->port.count != 1))
+ portp->port.count = 1;
+ if (portp->port.count-- > 1) {
spin_unlock_irqrestore(&stallion_lock, flags);
return;
}
- portp->refcount = 0;
- portp->flags |= ASYNC_CLOSING;
+ portp->port.count = 0;
+ portp->port.flags |= ASYNC_CLOSING;
/*
* May want to wait for any data to drain before closing. The BUSY
@@ -930,7 +930,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&stallion_lock, flags);
- portp->flags &= ~ASYNC_INITIALIZED;
+ portp->port.flags &= ~ASYNC_INITIALIZED;
spin_unlock_irqrestore(&stallion_lock, flags);
stl_disableintrs(portp);
@@ -949,16 +949,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
tty_ldisc_flush(tty);
tty->closing = 0;
- portp->tty = NULL;
+ portp->port.tty = NULL;
if (portp->openwaitcnt) {
if (portp->close_delay)
msleep_interruptible(jiffies_to_msecs(portp->close_delay));
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
}
- portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&portp->close_wait);
+ portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ wake_up_interruptible(&portp->port.close_wait);
}
/*****************************************************************************/
@@ -1153,7 +1153,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
memset(&sio, 0, sizeof(struct serial_struct));
sio.line = portp->portnr;
sio.port = portp->ioaddr;
- sio.flags = portp->flags;
+ sio.flags = portp->port.flags;
sio.baud_base = portp->baud_base;
sio.close_delay = portp->close_delay;
sio.closing_wait = portp->closing_wait;
@@ -1194,17 +1194,17 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
if ((sio.baud_base != portp->baud_base) ||
(sio.close_delay != portp->close_delay) ||
((sio.flags & ~ASYNC_USR_MASK) !=
- (portp->flags & ~ASYNC_USR_MASK)))
+ (portp->port.flags & ~ASYNC_USR_MASK)))
return -EPERM;
}
- portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
+ portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
(sio.flags & ASYNC_USR_MASK);
portp->baud_base = sio.baud_base;
portp->close_delay = sio.close_delay;
portp->closing_wait = sio.closing_wait;
portp->custom_divisor = sio.custom_divisor;
- stl_setport(portp, portp->tty->termios);
+ stl_setport(portp, portp->port.tty->termios);
return 0;
}
@@ -1353,7 +1353,7 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old)
stl_start(tty);
}
if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
- wake_up_interruptible(&portp->open_wait);
+ wake_up_interruptible(&portp->port.open_wait);
}
/*****************************************************************************/
@@ -1438,7 +1438,7 @@ static void stl_hangup(struct tty_struct *tty)
if (portp == NULL)
return;
- portp->flags &= ~ASYNC_INITIALIZED;
+ portp->port.flags &= ~ASYNC_INITIALIZED;
stl_disableintrs(portp);
if (tty->termios->c_cflag & HUPCL)
stl_setsignals(portp, 0, 0);
@@ -1452,10 +1452,10 @@ static void stl_hangup(struct tty_struct *tty)
portp->tx.head = NULL;
portp->tx.tail = NULL;
}
- portp->tty = NULL;
- portp->flags &= ~ASYNC_NORMAL_ACTIVE;
- portp->refcount = 0;
- wake_up_interruptible(&portp->open_wait);
+ portp->port.tty = NULL;
+ portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ portp->port.count = 0;
+ wake_up_interruptible(&portp->port.open_wait);
}
/*****************************************************************************/
@@ -1814,8 +1814,8 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
portp->baud_base = STL_BAUDBASE;
portp->close_delay = STL_CLOSEDELAY;
portp->closing_wait = 30 * HZ;
- init_waitqueue_head(&portp->open_wait);
- init_waitqueue_head(&portp->close_wait);
+ init_waitqueue_head(&portp->port.open_wait);
+ init_waitqueue_head(&portp->port.close_wait);
portp->stats.brd = portp->brdnr;
portp->stats.panel = portp->panelnr;
portp->stats.port = portp->portnr;
@@ -1840,8 +1840,8 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
portp = panelp->ports[k];
if (portp == NULL)
continue;
- if (portp->tty != NULL)
- stl_hangup(portp->tty);
+ if (portp->port.tty != NULL)
+ stl_hangup(portp->port.tty);
kfree(portp->tx.buf);
kfree(portp);
}
@@ -2513,7 +2513,7 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
}
portp->stats.state = portp->istate;
- portp->stats.flags = portp->flags;
+ portp->stats.flags = portp->port.flags;
portp->stats.hwid = portp->hwid;
portp->stats.ttystate = 0;
@@ -2524,16 +2524,16 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
portp->stats.rxbuffered = 0;
spin_lock_irqsave(&stallion_lock, flags);
- if (portp->tty != NULL)
- if (portp->tty->driver_data == portp) {
- portp->stats.ttystate = portp->tty->flags;
+ if (portp->port.tty != NULL)
+ if (portp->port.tty->driver_data == portp) {
+ portp->stats.ttystate = portp->port.tty->flags;
/* No longer available as a statistic */
- portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */
- if (portp->tty->termios != NULL) {
- portp->stats.cflags = portp->tty->termios->c_cflag;
- portp->stats.iflags = portp->tty->termios->c_iflag;
- portp->stats.oflags = portp->tty->termios->c_oflag;
- portp->stats.lflags = portp->tty->termios->c_lflag;
+ portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */
+ if (portp->port.tty->termios != NULL) {
+ portp->stats.cflags = portp->port.tty->termios->c_cflag;
+ portp->stats.iflags = portp->port.tty->termios->c_iflag;
+ portp->stats.oflags = portp->port.tty->termios->c_oflag;
+ portp->stats.lflags = portp->port.tty->termios->c_lflag;
}
}
spin_unlock_irqrestore(&stallion_lock, flags);
@@ -2939,15 +2939,15 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
}
baudrate = stl_baudrates[baudrate];
if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baudrate = 57600;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baudrate = 115200;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
baudrate = 230400;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
baudrate = 460800;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
baudrate = (portp->baud_base / portp->custom_divisor);
}
if (baudrate > STL_CD1400MAXBAUD)
@@ -2969,9 +2969,9 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
mcor1 |= MCOR1_DCD;
mcor2 |= MCOR2_DCD;
sreron |= SRER_MODEM;
- portp->flags |= ASYNC_CHECK_CD;
+ portp->port.flags |= ASYNC_CHECK_CD;
} else
- portp->flags &= ~ASYNC_CHECK_CD;
+ portp->port.flags &= ~ASYNC_CHECK_CD;
/*
* Setup cd1400 enhanced modes if we can. In particular we want to
@@ -3242,7 +3242,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
if (portp == NULL)
return;
- tty = portp->tty;
+ tty = portp->port.tty;
if (tty == NULL)
return;
@@ -3304,7 +3304,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
if (portp == NULL)
return;
- tty = portp->tty;
+ tty = portp->port.tty;
if (tty == NULL)
return;
@@ -3503,8 +3503,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
if ((len == 0) || ((len < STL_TXBUFLOW) &&
(test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
set_bit(ASYI_TXLOW, &portp->istate);
- if (portp->tty)
- tty_wakeup(portp->tty);
+ if (portp->port.tty)
+ tty_wakeup(portp->port.tty);
}
if (len == 0) {
@@ -3568,7 +3568,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
return;
}
portp = panelp->ports[(ioack >> 3)];
- tty = portp->tty;
+ tty = portp->port.tty;
if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
outb((RDCR + portp->uartaddr), ioaddr);
@@ -3613,7 +3613,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
if (portp->rxmarkmsk & status) {
if (status & ST_BREAK) {
status = TTY_BREAK;
- if (portp->flags & ASYNC_SAK) {
+ if (portp->port.flags & ASYNC_SAK) {
do_SAK(tty);
BRDENABLE(portp->brdnr, portp->pagenr);
}
@@ -3899,15 +3899,15 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
}
baudrate = stl_baudrates[baudrate];
if ((tiosp->c_cflag & CBAUD) == B38400) {
- if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
baudrate = 57600;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baudrate = 115200;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
baudrate = 230400;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
baudrate = 460800;
- else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+ else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
baudrate = (portp->baud_base / portp->custom_divisor);
}
if (baudrate > STL_SC26198MAXBAUD)
@@ -3922,11 +3922,11 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
* Check what form of modem signaling is required and set it up.
*/
if (tiosp->c_cflag & CLOCAL) {
- portp->flags &= ~ASYNC_CHECK_CD;
+ portp->port.flags &= ~ASYNC_CHECK_CD;
} else {
iopr |= IOPR_DCDCOS;
imron |= IR_IOPORT;
- portp->flags |= ASYNC_CHECK_CD;
+ portp->port.flags |= ASYNC_CHECK_CD;
}
/*
@@ -4174,7 +4174,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
if (portp == NULL)
return;
- tty = portp->tty;
+ tty = portp->port.tty;
if (tty == NULL)
return;
@@ -4243,7 +4243,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
if (portp == NULL)
return;
- tty = portp->tty;
+ tty = portp->port.tty;
if (tty == NULL)
return;
@@ -4421,8 +4421,8 @@ static void stl_sc26198txisr(struct stlport *portp)
if ((len == 0) || ((len < STL_TXBUFLOW) &&
(test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
set_bit(ASYI_TXLOW, &portp->istate);
- if (portp->tty)
- tty_wakeup(portp->tty);
+ if (portp->port.tty)
+ tty_wakeup(portp->port.tty);
}
if (len == 0) {
@@ -4475,7 +4475,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
- tty = portp->tty;
+ tty = portp->port.tty;
ioaddr = portp->ioaddr;
outb(GIBCR, (ioaddr + XP_ADDR));
len = inb(ioaddr + XP_DATA) + 1;
@@ -4527,7 +4527,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
struct tty_struct *tty;
unsigned int ioaddr;
- tty = portp->tty;
+ tty = portp->port.tty;
ioaddr = portp->ioaddr;
if (status & SR_RXPARITY)
@@ -4544,7 +4544,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
if (portp->rxmarkmsk & status) {
if (status & SR_RXBREAK) {
status = TTY_BREAK;
- if (portp->flags & ASYNC_SAK) {
+ if (portp->port.flags & ASYNC_SAK) {
do_SAK(tty);
BRDENABLE(portp->brdnr, portp->pagenr);
}
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index b1a7a8cb65e..d5cffcd6a57 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1,4 +1,3 @@
-
/* sx.c -- driver for the Specialix SX series cards.
*
* This driver will also support the older SI, and XIO cards.
@@ -930,7 +929,7 @@ static int sx_set_real_termios(void *ptr)
func_enter2();
- if (!port->gs.tty)
+ if (!port->gs.port.tty)
return 0;
/* What is this doing here? -- REW
@@ -941,19 +940,19 @@ static int sx_set_real_termios(void *ptr)
sx_set_baud(port);
-#define CFLAG port->gs.tty->termios->c_cflag
+#define CFLAG port->gs.port.tty->termios->c_cflag
sx_write_channel_byte(port, hi_mr1,
- (C_PARENB(port->gs.tty) ? MR1_WITH : MR1_NONE) |
- (C_PARODD(port->gs.tty) ? MR1_ODD : MR1_EVEN) |
- (C_CRTSCTS(port->gs.tty) ? MR1_RTS_RXFLOW : 0) |
+ (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) |
+ (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) |
+ (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) |
(((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) |
(((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) |
(((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) |
(((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0));
sx_write_channel_byte(port, hi_mr2,
- (C_CRTSCTS(port->gs.tty) ? MR2_CTS_TXFLOW : 0) |
- (C_CSTOPB(port->gs.tty) ? MR2_2_STOP :
+ (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) |
+ (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP :
MR2_1_STOP));
switch (CFLAG & CSIZE) {
@@ -976,44 +975,44 @@ static int sx_set_real_termios(void *ptr)
}
sx_write_channel_byte(port, hi_prtcl,
- (I_IXON(port->gs.tty) ? SP_TXEN : 0) |
- (I_IXOFF(port->gs.tty) ? SP_RXEN : 0) |
- (I_IXANY(port->gs.tty) ? SP_TANY : 0) | SP_DCEN);
+ (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) |
+ (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) |
+ (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN);
sx_write_channel_byte(port, hi_break,
- (I_IGNBRK(port->gs.tty) ? BR_IGN : 0 |
- I_BRKINT(port->gs.tty) ? BR_INT : 0));
+ (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 |
+ I_BRKINT(port->gs.port.tty) ? BR_INT : 0));
- sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.tty));
- sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.tty));
- sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.tty));
- sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.tty));
+ sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty));
+ sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty));
+ sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty));
+ sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty));
sx_reconfigure_port(port);
/* Tell line discipline whether we will do input cooking */
- if (I_OTHER(port->gs.tty)) {
- clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
+ if (I_OTHER(port->gs.port.tty)) {
+ clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags);
} else {
- set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags);
+ set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags);
}
sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
- (unsigned int)port->gs.tty->termios->c_iflag,
- I_OTHER(port->gs.tty));
+ (unsigned int)port->gs.port.tty->termios->c_iflag,
+ I_OTHER(port->gs.port.tty));
/* Tell line discipline whether we will do output cooking.
* If OPOST is set and no other output flags are set then we can do output
* processing. Even if only *one* other flag in the O_OTHER group is set
* we do cooking in software.
*/
- if (O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) {
- set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
+ if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) {
+ set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags);
} else {
- clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags);
+ clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags);
}
sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
- (unsigned int)port->gs.tty->termios->c_oflag,
- O_OTHER(port->gs.tty));
+ (unsigned int)port->gs.port.tty->termios->c_oflag,
+ O_OTHER(port->gs.port.tty));
/* port->c_dcd = sx_get_CD (port); */
func_exit();
return 0;
@@ -1102,8 +1101,8 @@ static void sx_transmit_chars(struct sx_port *port)
sx_disable_tx_interrupts(port);
}
- if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
- tty_wakeup(port->gs.tty);
+ if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) {
+ tty_wakeup(port->gs.port.tty);
sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
port->gs.wakeup_chars);
}
@@ -1126,7 +1125,7 @@ static inline void sx_receive_chars(struct sx_port *port)
unsigned char *rp;
func_enter2();
- tty = port->gs.tty;
+ tty = port->gs.port.tty;
while (1) {
rx_op = sx_read_channel_byte(port, hi_rxopos);
c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff;
@@ -1211,12 +1210,12 @@ static inline void sx_check_modem_signals(struct sx_port *port)
/* DCD went UP */
if ((sx_read_channel_byte(port, hi_hstat) !=
HS_IDLE_CLOSED) &&
- !(port->gs.tty->termios->
+ !(port->gs.port.tty->termios->
c_cflag & CLOCAL)) {
/* Are we blocking in open? */
sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
"active, unblocking open\n");
- wake_up_interruptible(&port->gs.
+ wake_up_interruptible(&port->gs.port.
open_wait);
} else {
sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
@@ -1224,10 +1223,10 @@ static inline void sx_check_modem_signals(struct sx_port *port)
}
} else {
/* DCD went down! */
- if (!(port->gs.tty->termios->c_cflag & CLOCAL)){
+ if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){
sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
"dropped. hanging up....\n");
- tty_hangup(port->gs.tty);
+ tty_hangup(port->gs.port.tty);
} else {
sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
"dropped. ignoring.\n");
@@ -1325,7 +1324,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
for (i = 0; i < board->nports; i++) {
port = &board->ports[i];
- if (port->gs.flags & GS_ACTIVE) {
+ if (port->gs.port.flags & GS_ACTIVE) {
if (sx_read_channel_byte(port, hi_state)) {
sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: "
"modem signal change?... \n",i);
@@ -1334,7 +1333,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
if (port->gs.xmit_cnt) {
sx_transmit_chars(port);
}
- if (!(port->gs.flags & SX_RX_THROTTLE)) {
+ if (!(port->gs.port.flags & SX_RX_THROTTLE)) {
sx_receive_chars(port);
}
}
@@ -1373,7 +1372,7 @@ static void sx_disable_tx_interrupts(void *ptr)
struct sx_port *port = ptr;
func_enter2();
- port->gs.flags &= ~GS_TX_INTEN;
+ port->gs.port.flags &= ~GS_TX_INTEN;
func_exit();
}
@@ -1394,7 +1393,7 @@ static void sx_enable_tx_interrupts(void *ptr)
/* XXX Must be "HIGH_WATER" for SI card according to doc. */
if (data_in_buffer < LOW_WATER)
- port->gs.flags &= ~GS_TX_INTEN;
+ port->gs.port.flags &= ~GS_TX_INTEN;
func_exit();
}
@@ -1442,8 +1441,8 @@ static void sx_shutdown_port(void *ptr)
func_enter();
- port->gs.flags &= ~GS_ACTIVE;
- if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {
+ port->gs.port.flags &= ~GS_ACTIVE;
+ if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) {
sx_setsignals(port, 0, 0);
sx_reconfigure_port(port);
}
@@ -1485,8 +1484,8 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
spin_lock_irqsave(&port->gs.driver_lock, flags);
tty->driver_data = port;
- port->gs.tty = tty;
- port->gs.count++;
+ port->gs.port.tty = tty;
+ port->gs.port.count++;
spin_unlock_irqrestore(&port->gs.driver_lock, flags);
sx_dprintk(SX_DEBUG_OPEN, "starting port\n");
@@ -1497,12 +1496,12 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
retval = gs_init_port(&port->gs);
sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n");
if (retval) {
- port->gs.count--;
+ port->gs.port.count--;
return retval;
}
- port->gs.flags |= GS_ACTIVE;
- if (port->gs.count <= 1)
+ port->gs.port.flags |= GS_ACTIVE;
+ if (port->gs.port.count <= 1)
sx_setsignals(port, 1, 1);
#if 0
@@ -1513,12 +1512,12 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
my_hd_io(port->board->base + port->ch_base, sizeof(*port));
#endif
- if (port->gs.count <= 1) {
+ if (port->gs.port.count <= 1) {
if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
printk(KERN_ERR "sx: Card didn't respond to LOPEN "
"command.\n");
spin_lock_irqsave(&port->gs.driver_lock, flags);
- port->gs.count--;
+ port->gs.port.count--;
spin_unlock_irqrestore(&port->gs.driver_lock, flags);
return -EIO;
}
@@ -1526,11 +1525,11 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
retval = gs_block_til_ready(port, filp);
sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n",
- retval, port->gs.count);
+ retval, port->gs.port.count);
if (retval) {
/*
- * Don't lower gs.count here because sx_close() will be called later
+ * Don't lower gs.port.count here because sx_close() will be called later
*/
return retval;
@@ -1571,14 +1570,14 @@ static void sx_close(void *ptr)
}
sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n",
- 5 * HZ - to - 1, port->gs.count);
+ 5 * HZ - to - 1, port->gs.port.count);
- if (port->gs.count) {
+ if (port->gs.port.count) {
sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n",
- port->gs.count);
+ port->gs.port.count);
/*printk("%s SETTING port count to zero: %p count: %d\n",
- __func__, port, port->gs.count);
- port->gs.count = 0;*/
+ __func__, port, port->gs.port.count);
+ port->gs.port.count = 0;*/
}
func_exit();
@@ -1939,7 +1938,7 @@ static void sx_throttle(struct tty_struct *tty)
* control then throttle the port.
*/
if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) {
- port->gs.flags |= SX_RX_THROTTLE;
+ port->gs.port.flags |= SX_RX_THROTTLE;
}
func_exit();
}
@@ -1953,7 +1952,7 @@ static void sx_unthrottle(struct tty_struct *tty)
* this port in case we disabled flow control while the port
* was throttled
*/
- port->gs.flags &= ~SX_RX_THROTTLE;
+ port->gs.port.flags &= ~SX_RX_THROTTLE;
func_exit();
return;
}
@@ -2396,6 +2395,7 @@ static int sx_init_portstructs(int nboards, int nports)
board->ports = port;
for (j = 0; j < boards[i].nports; j++) {
sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j);
+ tty_port_init(&port->gs.port);
port->gs.magic = SX_MAGIC;
port->gs.close_delay = HZ / 2;
port->gs.closing_wait = 30 * HZ;
@@ -2408,9 +2408,6 @@ static int sx_init_portstructs(int nboards, int nports)
/*
* Initializing wait queue
*/
- init_waitqueue_head(&port->gs.open_wait);
- init_waitqueue_head(&port->gs.close_wait);
-
port++;
}
}
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ac5080df256..527d220aa4a 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -180,19 +180,14 @@ struct tx_holding_buffer {
struct mgsl_struct {
int magic;
- int flags;
- int count; /* count of opens */
+ struct tty_port port;
int line;
int hw_version;
- unsigned short close_delay;
- unsigned short closing_wait; /* time to wait before closing */
struct mgsl_icount icount;
- struct tty_struct *tty;
int timeout;
int x_char; /* xon/xoff character */
- int blocked_open; /* # of blocked opens */
u16 read_status_mask;
u16 ignore_status_mask;
unsigned char *xmit_buf;
@@ -200,9 +195,6 @@ struct mgsl_struct {
int xmit_tail;
int xmit_cnt;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
-
wait_queue_head_t status_event_wait_q;
wait_queue_head_t event_wait_q;
struct timer_list tx_timer; /* HDLC transmit timeout timer */
@@ -975,8 +967,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
return;
ld = tty_ldisc_ref(tty);
if (ld) {
- if (ld->receive_buf)
- ld->receive_buf(tty, data, flags, count);
+ if (ld->ops->receive_buf)
+ ld->ops->receive_buf(tty, data, flags, count);
tty_ldisc_deref(ld);
}
}
@@ -1134,7 +1126,7 @@ static void mgsl_bh_receive(struct mgsl_struct *info)
static void mgsl_bh_transmit(struct mgsl_struct *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned long flags;
if ( debug_level >= DEBUG_LEVEL_BH )
@@ -1276,7 +1268,7 @@ static void mgsl_isr_transmit_status( struct mgsl_struct *info )
else
#endif
{
- if (info->tty->stopped || info->tty->hw_stopped) {
+ if (info->port.tty->stopped || info->port.tty->hw_stopped) {
usc_stop_transmitter(info);
return;
}
@@ -1357,29 +1349,29 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
- if ( (info->flags & ASYNC_CHECK_CD) &&
+ if ( (info->port.flags & ASYNC_CHECK_CD) &&
(status & MISCSTATUS_DCD_LATCHED) ) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("%s CD now %s...", info->device_name,
(status & MISCSTATUS_DCD) ? "on" : "off");
if (status & MISCSTATUS_DCD)
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
else {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("doing serial hangup...");
- if (info->tty)
- tty_hangup(info->tty);
+ if (info->port.tty)
+ tty_hangup(info->port.tty);
}
}
- if ( (info->flags & ASYNC_CTS_FLOW) &&
+ if ( (info->port.flags & ASYNC_CTS_FLOW) &&
(status & MISCSTATUS_CTS_LATCHED) ) {
- if (info->tty->hw_stopped) {
+ if (info->port.tty->hw_stopped) {
if (status & MISCSTATUS_CTS) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx start...");
- if (info->tty)
- info->tty->hw_stopped = 0;
+ if (info->port.tty)
+ info->port.tty->hw_stopped = 0;
usc_start_transmitter(info);
info->pending_bh |= BH_TRANSMIT;
return;
@@ -1388,8 +1380,8 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
if (!(status & MISCSTATUS_CTS)) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx stop...");
- if (info->tty)
- info->tty->hw_stopped = 1;
+ if (info->port.tty)
+ info->port.tty->hw_stopped = 1;
usc_stop_transmitter(info);
}
}
@@ -1423,7 +1415,7 @@ static void mgsl_isr_transmit_data( struct mgsl_struct *info )
usc_ClearIrqPendingBits( info, TRANSMIT_DATA );
- if (info->tty->stopped || info->tty->hw_stopped) {
+ if (info->port.tty->stopped || info->port.tty->hw_stopped) {
usc_stop_transmitter(info);
return;
}
@@ -1453,7 +1445,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
u16 status;
int work = 0;
unsigned char DataByte;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
struct mgsl_icount *icount = &info->icount;
if ( debug_level >= DEBUG_LEVEL_ISR )
@@ -1514,7 +1506,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
if (status & RXSTATUS_BREAK_RECEIVED) {
flag = TTY_BREAK;
- if (info->flags & ASYNC_SAK)
+ if (info->port.flags & ASYNC_SAK)
do_SAK(tty);
} else if (status & RXSTATUS_PARITY_ERROR)
flag = TTY_PARITY;
@@ -1771,7 +1763,7 @@ static int startup(struct mgsl_struct * info)
if ( debug_level >= DEBUG_LEVEL_INFO )
printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name);
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
return 0;
if (!info->xmit_buf) {
@@ -1798,8 +1790,8 @@ static int startup(struct mgsl_struct * info)
retval = mgsl_adapter_test(info);
if ( retval ) {
- if (capable(CAP_SYS_ADMIN) && info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (capable(CAP_SYS_ADMIN) && info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
mgsl_release_resources(info);
return retval;
}
@@ -1807,10 +1799,10 @@ static int startup(struct mgsl_struct * info)
/* program hardware for current parameters */
mgsl_change_params(info);
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags |= ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
return 0;
@@ -1827,7 +1819,7 @@ static void shutdown(struct mgsl_struct * info)
{
unsigned long flags;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1864,7 +1856,7 @@ static void shutdown(struct mgsl_struct * info)
/* on the ISA adapter. This has no effect for the PCI adapter */
usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12));
- if (!info->tty || info->tty->termios->c_cflag & HUPCL) {
+ if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
usc_set_serial_signals(info);
}
@@ -1873,10 +1865,10 @@ static void shutdown(struct mgsl_struct * info)
mgsl_release_resources(info);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ info->port.flags &= ~ASYNC_INITIALIZED;
} /* end of shutdown() */
@@ -1908,7 +1900,7 @@ static void mgsl_program_hw(struct mgsl_struct *info)
usc_EnableInterrupts(info, IO_PIN);
usc_get_serial_signals(info);
- if (info->netcount || info->tty->termios->c_cflag & CREAD)
+ if (info->netcount || info->port.tty->termios->c_cflag & CREAD)
usc_start_receiver(info);
spin_unlock_irqrestore(&info->irq_spinlock,flags);
@@ -1921,14 +1913,14 @@ static void mgsl_change_params(struct mgsl_struct *info)
unsigned cflag;
int bits_per_char;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_change_params(%s)\n",
__FILE__,__LINE__, info->device_name );
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
/* if B0 rate (hangup) specified then negate DTR and RTS */
/* otherwise assert DTR and RTS */
@@ -1976,7 +1968,7 @@ static void mgsl_change_params(struct mgsl_struct *info)
* current data rate.
*/
if (info->params.data_rate <= 460800)
- info->params.data_rate = tty_get_baud_rate(info->tty);
+ info->params.data_rate = tty_get_baud_rate(info->port.tty);
if ( info->params.data_rate ) {
info->timeout = (32*HZ*bits_per_char) /
@@ -1985,31 +1977,31 @@ static void mgsl_change_params(struct mgsl_struct *info)
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
- info->flags |= ASYNC_CTS_FLOW;
+ info->port.flags |= ASYNC_CTS_FLOW;
else
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
else
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
/* process tty input control flags */
info->read_status_mask = RXSTATUS_OVERRUN;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= RXSTATUS_BREAK_RECEIVED;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED;
/* If ignoring parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= RXSTATUS_OVERRUN;
}
@@ -3113,32 +3105,32 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_close(%s) entry, count=%d\n",
- __FILE__,__LINE__, info->device_name, info->count);
+ __FILE__,__LINE__, info->device_name, info->port.count);
- if (!info->count)
+ if (!info->port.count)
return;
if (tty_hung_up_p(filp))
goto cleanup;
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* tty->count is 1 and the tty structure will be freed.
- * info->count should be one in this case.
+ * info->port.count should be one in this case.
* if it's not, correct it so that the port is shutdown.
*/
printk("mgsl_close: bad refcount; tty->count is 1, "
- "info->count is %d\n", info->count);
- info->count = 1;
+ "info->port.count is %d\n", info->port.count);
+ info->port.count = 1;
}
- info->count--;
+ info->port.count--;
/* if at least one open remaining, leave hardware active */
- if (info->count)
+ if (info->port.count)
goto cleanup;
- info->flags |= ASYNC_CLOSING;
+ info->port.flags |= ASYNC_CLOSING;
/* set tty->closing to notify line discipline to
* only process XON/XOFF characters. Only the N_TTY
@@ -3148,14 +3140,14 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
/* wait for transmit data to clear all layers */
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_close(%s) calling tty_wait_until_sent\n",
__FILE__,__LINE__, info->device_name );
- tty_wait_until_sent(tty, info->closing_wait);
+ tty_wait_until_sent(tty, info->port.closing_wait);
}
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
mgsl_wait_until_sent(tty, info->timeout);
mgsl_flush_buffer(tty);
@@ -3165,23 +3157,23 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
shutdown(info);
tty->closing = 0;
- info->tty = NULL;
+ info->port.tty = NULL;
- if (info->blocked_open) {
- if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ if (info->port.blocked_open) {
+ if (info->port.close_delay) {
+ msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+ wake_up_interruptible(&info->port.close_wait);
cleanup:
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__,
- tty->driver->name, info->count);
+ tty->driver->name, info->port.count);
} /* end of mgsl_close() */
@@ -3211,7 +3203,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent"))
return;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
goto exit;
orig_jiffies = jiffies;
@@ -3283,11 +3275,11 @@ static void mgsl_hangup(struct tty_struct *tty)
mgsl_flush_buffer(tty);
shutdown(info);
- info->count = 0;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = NULL;
+ info->port.count = 0;
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ info->port.tty = NULL;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
} /* end of mgsl_hangup() */
@@ -3319,7 +3311,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
/* nonblock mode is set or port is not enabled */
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -3328,25 +3320,25 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
/* Wait for carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
+ * this loop, info->port.count is dropped by one, so that
* mgsl_close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):block_til_ready before block on %s count=%d\n",
- __FILE__,__LINE__, tty->driver->name, info->count );
+ __FILE__,__LINE__, tty->driver->name, info->port.count );
spin_lock_irqsave(&info->irq_spinlock, flags);
if (!tty_hung_up_p(filp)) {
extra_count = true;
- info->count--;
+ info->port.count--;
}
spin_unlock_irqrestore(&info->irq_spinlock, flags);
- info->blocked_open++;
+ info->port.blocked_open++;
while (1) {
if (tty->termios->c_cflag & CBAUD) {
@@ -3358,8 +3350,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
- retval = (info->flags & ASYNC_HUP_NOTIFY) ?
+ if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
+ retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS;
break;
}
@@ -3368,7 +3360,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
usc_get_serial_signals(info);
spin_unlock_irqrestore(&info->irq_spinlock,flags);
- if (!(info->flags & ASYNC_CLOSING) &&
+ if (!(info->port.flags & ASYNC_CLOSING) &&
(do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
break;
}
@@ -3380,24 +3372,24 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):block_til_ready blocking on %s count=%d\n",
- __FILE__,__LINE__, tty->driver->name, info->count );
+ __FILE__,__LINE__, tty->driver->name, info->port.count );
schedule();
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
if (extra_count)
- info->count++;
- info->blocked_open--;
+ info->port.count++;
+ info->port.blocked_open--;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):block_til_ready after blocking on %s count=%d\n",
- __FILE__,__LINE__, tty->driver->name, info->count );
+ __FILE__,__LINE__, tty->driver->name, info->port.count );
if (!retval)
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return retval;
@@ -3435,22 +3427,22 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
return -ENODEV;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):mgsl_open(%s), old ref count = %d\n",
- __FILE__,__LINE__,tty->driver->name, info->count);
+ __FILE__,__LINE__,tty->driver->name, info->port.count);
/* If port is closing, signal caller to try again */
- if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
- retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+ if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
+ if (info->port.flags & ASYNC_CLOSING)
+ interruptible_sleep_on(&info->port.close_wait);
+ retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
goto cleanup;
}
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
spin_lock_irqsave(&info->netlock, flags);
if (info->netcount) {
@@ -3458,10 +3450,10 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
spin_unlock_irqrestore(&info->netlock, flags);
goto cleanup;
}
- info->count++;
+ info->port.count++;
spin_unlock_irqrestore(&info->netlock, flags);
- if (info->count == 1) {
+ if (info->port.count == 1) {
/* 1st open on this device, init hardware */
retval = startup(info);
if (retval < 0)
@@ -3484,9 +3476,9 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
cleanup:
if (retval) {
if (tty->count == 1)
- info->tty = NULL; /* tty layer will release tty struct */
- if(info->count)
- info->count--;
+ info->port.tty = NULL; /* tty layer will release tty struct */
+ if(info->port.count)
+ info->port.count--;
}
return retval;
@@ -4332,13 +4324,12 @@ static struct mgsl_struct* mgsl_allocate_device(void)
if (!info) {
printk("Error can't allocate device instance data\n");
} else {
+ tty_port_init(&info->port);
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, mgsl_bh_handler);
info->max_frame_size = 4096;
- info->close_delay = 5*HZ/10;
- info->closing_wait = 30*HZ;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
+ info->port.close_delay = 5*HZ/10;
+ info->port.closing_wait = 30*HZ;
init_waitqueue_head(&info->status_event_wait_q);
init_waitqueue_head(&info->event_wait_q);
spin_lock_init(&info->irq_spinlock);
@@ -6575,7 +6566,7 @@ static bool mgsl_get_rx_frame(struct mgsl_struct *info)
unsigned int framesize = 0;
bool ReturnCode = false;
unsigned long flags;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
bool return_frame = false;
/*
@@ -6640,9 +6631,8 @@ static bool mgsl_get_rx_frame(struct mgsl_struct *info)
framesize = 0;
#if SYNCLINK_GENERIC_HDLC
{
- struct net_device_stats *stats = hdlc_stats(info->netdev);
- stats->rx_errors++;
- stats->rx_frame_errors++;
+ info->netdev->stats.rx_errors++;
+ info->netdev->stats.rx_frame_errors++;
}
#endif
} else
@@ -6774,7 +6764,7 @@ static bool mgsl_get_raw_rx_frame(struct mgsl_struct *info)
unsigned int framesize = 0;
bool ReturnCode = false;
unsigned long flags;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
/*
* current_rx_buffer points to the 1st buffer of the next available
@@ -7711,7 +7701,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
unsigned short new_crctype;
/* return error if TTY interface open */
- if (info->count)
+ if (info->port.count)
return -EBUSY;
switch (encoding)
@@ -7753,7 +7743,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct mgsl_struct *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
@@ -7767,8 +7756,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
mgsl_load_tx_dma_buffer(info, skb->data, skb->len);
/* update network statistics */
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
/* done with socket buffer, so free it */
dev_kfree_skb(skb);
@@ -7808,7 +7797,7 @@ static int hdlcdev_open(struct net_device *dev)
/* arbitrate between network and tty opens */
spin_lock_irqsave(&info->netlock, flags);
- if (info->count != 0 || info->netcount != 0) {
+ if (info->port.count != 0 || info->netcount != 0) {
printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
spin_unlock_irqrestore(&info->netlock, flags);
return -EBUSY;
@@ -7894,7 +7883,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
/* return error if TTY interface open */
- if (info->count)
+ if (info->port.count)
return -EBUSY;
if (cmd != SIOCWANDEV)
@@ -7984,14 +7973,13 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static void hdlcdev_tx_timeout(struct net_device *dev)
{
struct mgsl_struct *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("hdlcdev_tx_timeout(%s)\n",dev->name);
- stats->tx_errors++;
- stats->tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
spin_lock_irqsave(&info->irq_spinlock,flags);
usc_stop_transmitter(info);
@@ -8024,27 +8012,27 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
{
struct sk_buff *skb = dev_alloc_skb(size);
struct net_device *dev = info->netdev;
- struct net_device_stats *stats = hdlc_stats(dev);
if (debug_level >= DEBUG_LEVEL_INFO)
- printk("hdlcdev_rx(%s)\n",dev->name);
+ printk("hdlcdev_rx(%s)\n", dev->name);
if (skb == NULL) {
- printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name);
- stats->rx_dropped++;
+ printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
+ dev->name);
+ dev->stats.rx_dropped++;
return;
}
- memcpy(skb_put(skb, size),buf,size);
+ memcpy(skb_put(skb, size), buf, size);
- skb->protocol = hdlc_type_trans(skb, info->netdev);
+ skb->protocol = hdlc_type_trans(skb, dev);
- stats->rx_packets++;
- stats->rx_bytes += size;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += size;
netif_rx(skb);
- info->netdev->last_rx = jiffies;
+ dev->last_rx = jiffies;
}
/**
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 55c1653be00..2c3e43bb2cc 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -244,11 +244,11 @@ struct _input_signal_events {
*/
struct slgt_info {
void *if_ptr; /* General purpose pointer (used by SPPP) */
+ struct tty_port port;
struct slgt_info *next_device; /* device list link */
int magic;
- int flags;
char device_name[25];
struct pci_dev *pdev;
@@ -260,23 +260,15 @@ struct slgt_info {
/* array of pointers to port contexts on this adapter */
struct slgt_info *port_array[SLGT_MAX_PORTS];
- int count; /* count of opens */
int line; /* tty line instance number */
- unsigned short close_delay;
- unsigned short closing_wait; /* time to wait before closing */
struct mgsl_icount icount;
- struct tty_struct *tty;
int timeout;
int x_char; /* xon/xoff character */
- int blocked_open; /* # of blocked opens */
unsigned int read_status_mask;
unsigned int ignore_status_mask;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
-
wait_queue_head_t status_event_wait_q;
wait_queue_head_t event_wait_q;
struct timer_list tx_timer;
@@ -641,8 +633,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
return;
ld = tty_ldisc_ref(tty);
if (ld) {
- if (ld->receive_buf)
- ld->receive_buf(tty, data, flags, count);
+ if (ld->ops->receive_buf)
+ ld->ops->receive_buf(tty, data, flags, count);
tty_ldisc_deref(ld);
}
}
@@ -672,20 +664,20 @@ static int open(struct tty_struct *tty, struct file *filp)
}
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
- DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->count));
+ DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->port.count));
/* If port is closing, signal caller to try again */
- if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
- retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+ if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
+ if (info->port.flags & ASYNC_CLOSING)
+ interruptible_sleep_on(&info->port.close_wait);
+ retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
goto cleanup;
}
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
spin_lock_irqsave(&info->netlock, flags);
if (info->netcount) {
@@ -693,10 +685,10 @@ static int open(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&info->netlock, flags);
goto cleanup;
}
- info->count++;
+ info->port.count++;
spin_unlock_irqrestore(&info->netlock, flags);
- if (info->count == 1) {
+ if (info->port.count == 1) {
/* 1st open on this device, init hardware */
retval = startup(info);
if (retval < 0)
@@ -714,9 +706,9 @@ static int open(struct tty_struct *tty, struct file *filp)
cleanup:
if (retval) {
if (tty->count == 1)
- info->tty = NULL; /* tty layer will release tty struct */
- if(info->count)
- info->count--;
+ info->port.tty = NULL; /* tty layer will release tty struct */
+ if(info->port.count)
+ info->port.count--;
}
DBGINFO(("%s open rc=%d\n", info->device_name, retval));
@@ -729,32 +721,32 @@ static void close(struct tty_struct *tty, struct file *filp)
if (sanity_check(info, tty->name, "close"))
return;
- DBGINFO(("%s close entry, count=%d\n", info->device_name, info->count));
+ DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count));
- if (!info->count)
+ if (!info->port.count)
return;
if (tty_hung_up_p(filp))
goto cleanup;
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* tty->count is 1 and the tty structure will be freed.
- * info->count should be one in this case.
+ * info->port.count should be one in this case.
* if it's not, correct it so that the port is shutdown.
*/
DBGERR(("%s close: bad refcount; tty->count=1, "
- "info->count=%d\n", info->device_name, info->count));
- info->count = 1;
+ "info->port.count=%d\n", info->device_name, info->port.count));
+ info->port.count = 1;
}
- info->count--;
+ info->port.count--;
/* if at least one open remaining, leave hardware active */
- if (info->count)
+ if (info->port.count)
goto cleanup;
- info->flags |= ASYNC_CLOSING;
+ info->port.flags |= ASYNC_CLOSING;
/* set tty->closing to notify line discipline to
* only process XON/XOFF characters. Only the N_TTY
@@ -764,12 +756,12 @@ static void close(struct tty_struct *tty, struct file *filp)
/* wait for transmit data to clear all layers */
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
- tty_wait_until_sent(tty, info->closing_wait);
+ tty_wait_until_sent(tty, info->port.closing_wait);
}
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
wait_until_sent(tty, info->timeout);
flush_buffer(tty);
tty_ldisc_flush(tty);
@@ -777,21 +769,21 @@ static void close(struct tty_struct *tty, struct file *filp)
shutdown(info);
tty->closing = 0;
- info->tty = NULL;
+ info->port.tty = NULL;
- if (info->blocked_open) {
- if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ if (info->port.blocked_open) {
+ if (info->port.close_delay) {
+ msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+ wake_up_interruptible(&info->port.close_wait);
cleanup:
- DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->count));
+ DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count));
}
static void hangup(struct tty_struct *tty)
@@ -805,11 +797,11 @@ static void hangup(struct tty_struct *tty)
flush_buffer(tty);
shutdown(info);
- info->count = 0;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = NULL;
+ info->port.count = 0;
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ info->port.tty = NULL;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
@@ -959,7 +951,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
if (sanity_check(info, tty->name, "wait_until_sent"))
return;
DBGINFO(("%s wait_until_sent entry\n", info->device_name));
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
goto exit;
orig_jiffies = jiffies;
@@ -1500,7 +1492,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
unsigned short new_crctype;
/* return error if TTY interface open */
- if (info->count)
+ if (info->port.count)
return -EBUSY;
DBGINFO(("%s hdlcdev_attach\n", info->device_name));
@@ -1544,7 +1536,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct slgt_info *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
DBGINFO(("%s hdlc_xmit\n", dev->name));
@@ -1557,8 +1548,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
tx_load(info, skb->data, skb->len);
/* update network statistics */
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
/* done with socket buffer, so free it */
dev_kfree_skb(skb);
@@ -1600,7 +1591,7 @@ static int hdlcdev_open(struct net_device *dev)
/* arbitrate between network and tty opens */
spin_lock_irqsave(&info->netlock, flags);
- if (info->count != 0 || info->netcount != 0) {
+ if (info->port.count != 0 || info->netcount != 0) {
DBGINFO(("%s hdlc_open busy\n", dev->name));
spin_unlock_irqrestore(&info->netlock, flags);
return -EBUSY;
@@ -1685,7 +1676,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
DBGINFO(("%s hdlcdev_ioctl\n", dev->name));
/* return error if TTY interface open */
- if (info->count)
+ if (info->port.count)
return -EBUSY;
if (cmd != SIOCWANDEV)
@@ -1775,13 +1766,12 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static void hdlcdev_tx_timeout(struct net_device *dev)
{
struct slgt_info *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name));
- stats->tx_errors++;
- stats->tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
spin_lock_irqsave(&info->lock,flags);
tx_stop(info);
@@ -1814,26 +1804,25 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
{
struct sk_buff *skb = dev_alloc_skb(size);
struct net_device *dev = info->netdev;
- struct net_device_stats *stats = hdlc_stats(dev);
DBGINFO(("%s hdlcdev_rx\n", dev->name));
if (skb == NULL) {
DBGERR(("%s: can't alloc skb, drop packet\n", dev->name));
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
- memcpy(skb_put(skb, size),buf,size);
+ memcpy(skb_put(skb, size), buf, size);
- skb->protocol = hdlc_type_trans(skb, info->netdev);
+ skb->protocol = hdlc_type_trans(skb, dev);
- stats->rx_packets++;
- stats->rx_bytes += size;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += size;
netif_rx(skb);
- info->netdev->last_rx = jiffies;
+ dev->last_rx = jiffies;
}
/**
@@ -1906,7 +1895,7 @@ static void hdlcdev_exit(struct slgt_info *info)
*/
static void rx_async(struct slgt_info *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
struct mgsl_icount *icount = &info->icount;
unsigned int start, end;
unsigned char *p;
@@ -2057,7 +2046,7 @@ static void bh_handler(struct work_struct *work)
static void bh_transmit(struct slgt_info *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
DBGBH(("%s bh_transmit\n", info->device_name));
if (tty)
@@ -2103,17 +2092,17 @@ static void cts_change(struct slgt_info *info, unsigned short status)
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
- if (info->flags & ASYNC_CTS_FLOW) {
- if (info->tty) {
- if (info->tty->hw_stopped) {
+ if (info->port.flags & ASYNC_CTS_FLOW) {
+ if (info->port.tty) {
+ if (info->port.tty->hw_stopped) {
if (info->signals & SerialSignal_CTS) {
- info->tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
info->pending_bh |= BH_TRANSMIT;
return;
}
} else {
if (!(info->signals & SerialSignal_CTS))
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
}
}
}
@@ -2146,12 +2135,12 @@ static void dcd_change(struct slgt_info *info, unsigned short status)
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
- if (info->flags & ASYNC_CHECK_CD) {
+ if (info->port.flags & ASYNC_CHECK_CD) {
if (info->signals & SerialSignal_DCD)
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
else {
- if (info->tty)
- tty_hangup(info->tty);
+ if (info->port.tty)
+ tty_hangup(info->port.tty);
}
}
}
@@ -2194,12 +2183,12 @@ static void isr_serial(struct slgt_info *info)
if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
info->icount.brk++;
/* process break detection if tty control allows */
- if (info->tty) {
+ if (info->port.tty) {
if (!(status & info->ignore_status_mask)) {
if (info->read_status_mask & MASK_BREAK) {
- tty_insert_flip_char(info->tty, 0, TTY_BREAK);
- if (info->flags & ASYNC_SAK)
- do_SAK(info->tty);
+ tty_insert_flip_char(info->port.tty, 0, TTY_BREAK);
+ if (info->port.flags & ASYNC_SAK)
+ do_SAK(info->port.tty);
}
}
}
@@ -2319,7 +2308,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
else
#endif
{
- if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) {
+ if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
tx_stop(info);
return;
}
@@ -2395,7 +2384,7 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id)
for(i=0; i < info->port_count ; i++) {
struct slgt_info *port = info->port_array[i];
- if (port && (port->count || port->netcount) &&
+ if (port && (port->port.count || port->netcount) &&
port->pending_bh && !port->bh_running &&
!port->bh_requested) {
DBGISR(("%s bh queued\n", port->device_name));
@@ -2414,7 +2403,7 @@ static int startup(struct slgt_info *info)
{
DBGINFO(("%s startup\n", info->device_name));
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
return 0;
if (!info->tx_buf) {
@@ -2432,10 +2421,10 @@ static int startup(struct slgt_info *info)
/* program hardware for current parameters */
change_params(info);
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags |= ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
return 0;
}
@@ -2447,7 +2436,7 @@ static void shutdown(struct slgt_info *info)
{
unsigned long flags;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
DBGINFO(("%s shutdown\n", info->device_name));
@@ -2470,7 +2459,7 @@ static void shutdown(struct slgt_info *info)
slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
- if (!info->tty || info->tty->termios->c_cflag & HUPCL) {
+ if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
set_signals(info);
}
@@ -2479,10 +2468,10 @@ static void shutdown(struct slgt_info *info)
spin_unlock_irqrestore(&info->lock,flags);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ info->port.flags &= ~ASYNC_INITIALIZED;
}
static void program_hw(struct slgt_info *info)
@@ -2511,7 +2500,7 @@ static void program_hw(struct slgt_info *info)
get_signals(info);
if (info->netcount ||
- (info->tty && info->tty->termios->c_cflag & CREAD))
+ (info->port.tty && info->port.tty->termios->c_cflag & CREAD))
rx_start(info);
spin_unlock_irqrestore(&info->lock,flags);
@@ -2525,11 +2514,11 @@ static void change_params(struct slgt_info *info)
unsigned cflag;
int bits_per_char;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
DBGINFO(("%s change_params\n", info->device_name));
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
/* if B0 rate (hangup) specified then negate DTR and RTS */
/* otherwise assert DTR and RTS */
@@ -2561,7 +2550,7 @@ static void change_params(struct slgt_info *info)
bits_per_char = info->params.data_bits +
info->params.stop_bits + 1;
- info->params.data_rate = tty_get_baud_rate(info->tty);
+ info->params.data_rate = tty_get_baud_rate(info->port.tty);
if (info->params.data_rate) {
info->timeout = (32*HZ*bits_per_char) /
@@ -2570,30 +2559,30 @@ static void change_params(struct slgt_info *info)
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
- info->flags |= ASYNC_CTS_FLOW;
+ info->port.flags |= ASYNC_CTS_FLOW;
else
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
else
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
/* process tty input control flags */
info->read_status_mask = IRQ_RXOVER;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= MASK_PARITY | MASK_FRAMING;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= MASK_BREAK;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= MASK_BREAK;
/* If ignoring parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= MASK_OVERRUN;
}
@@ -3144,7 +3133,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
/* nonblock mode is set or port is not enabled */
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -3153,21 +3142,21 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/* Wait for carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
+ * this loop, info->port.count is dropped by one, so that
* close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
spin_lock_irqsave(&info->lock, flags);
if (!tty_hung_up_p(filp)) {
extra_count = true;
- info->count--;
+ info->port.count--;
}
spin_unlock_irqrestore(&info->lock, flags);
- info->blocked_open++;
+ info->port.blocked_open++;
while (1) {
if ((tty->termios->c_cflag & CBAUD)) {
@@ -3179,8 +3168,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
- retval = (info->flags & ASYNC_HUP_NOTIFY) ?
+ if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
+ retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS;
break;
}
@@ -3189,7 +3178,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
get_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
- if (!(info->flags & ASYNC_CLOSING) &&
+ if (!(info->port.flags & ASYNC_CLOSING) &&
(do_clocal || (info->signals & SerialSignal_DCD)) ) {
break;
}
@@ -3204,14 +3193,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
if (extra_count)
- info->count++;
- info->blocked_open--;
+ info->port.count++;
+ info->port.blocked_open--;
if (!retval)
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
return retval;
@@ -3454,14 +3443,13 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
DBGERR(("%s device alloc failed adapter=%d port=%d\n",
driver_name, adapter_num, port_num));
} else {
+ tty_port_init(&info->port);
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
info->raw_rx_size = DMABUFSIZE;
- info->close_delay = 5*HZ/10;
- info->closing_wait = 30*HZ;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
+ info->port.close_delay = 5*HZ/10;
+ info->port.closing_wait = 30*HZ;
init_waitqueue_head(&info->status_event_wait_q);
init_waitqueue_head(&info->event_wait_q);
spin_lock_init(&info->netlock);
@@ -4505,7 +4493,7 @@ static bool rx_get_frame(struct slgt_info *info)
unsigned short status;
unsigned int framesize = 0;
unsigned long flags;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned char addr_field = 0xff;
unsigned int crc_size = 0;
@@ -4577,9 +4565,8 @@ check_again:
#if SYNCLINK_GENERIC_HDLC
if (framesize == 0) {
- struct net_device_stats *stats = hdlc_stats(info->netdev);
- stats->rx_errors++;
- stats->rx_frame_errors++;
+ info->netdev->stats.rx_errors++;
+ info->netdev->stats.rx_frame_errors++;
}
#endif
@@ -4656,7 +4643,7 @@ static bool rx_get_buf(struct slgt_info *info)
DBGDATA(info, info->rbufs[i].buf, count, "rx");
DBGINFO(("rx_get_buf size=%d\n", count));
if (count)
- ldisc_receive_buf(info->tty, info->rbufs[i].buf,
+ ldisc_receive_buf(info->port.tty, info->rbufs[i].buf,
info->flag_buf, count);
free_rbufs(info, i, i);
return true;
@@ -4765,11 +4752,11 @@ static int irq_test(struct slgt_info *info)
{
unsigned long timeout;
unsigned long flags;
- struct tty_struct *oldtty = info->tty;
+ struct tty_struct *oldtty = info->port.tty;
u32 speed = info->params.data_rate;
info->params.data_rate = 921600;
- info->tty = NULL;
+ info->port.tty = NULL;
spin_lock_irqsave(&info->lock, flags);
async_mode(info);
@@ -4797,7 +4784,7 @@ static int irq_test(struct slgt_info *info)
spin_unlock_irqrestore(&info->lock,flags);
info->params.data_rate = speed;
- info->tty = oldtty;
+ info->port.tty = oldtty;
info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure;
return info->irq_occurred ? 0 : -ENODEV;
@@ -4837,7 +4824,7 @@ static int loopback_test(struct slgt_info *info)
int rc = -ENODEV;
unsigned long flags;
- struct tty_struct *oldtty = info->tty;
+ struct tty_struct *oldtty = info->port.tty;
MGSL_PARAMS params;
memcpy(&params, &info->params, sizeof(params));
@@ -4845,7 +4832,7 @@ static int loopback_test(struct slgt_info *info)
info->params.mode = MGSL_MODE_ASYNC;
info->params.data_rate = 921600;
info->params.loopback = 1;
- info->tty = NULL;
+ info->port.tty = NULL;
/* build and send transmit frame */
for (count = 0; count < TESTFRAMESIZE; ++count)
@@ -4883,7 +4870,7 @@ static int loopback_test(struct slgt_info *info)
spin_unlock_irqrestore(&info->lock,flags);
memcpy(&info->params, &params, sizeof(info->params));
- info->tty = oldtty;
+ info->port.tty = oldtty;
info->init_error = rc ? DiagStatus_DmaFailure : 0;
return rc;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index bec54866e0b..5768c413634 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -151,18 +151,15 @@ struct _input_signal_events {
typedef struct _synclinkmp_info {
void *if_ptr; /* General purpose pointer (used by SPPP) */
int magic;
- int flags;
- int count; /* count of opens */
+ struct tty_port port;
int line;
unsigned short close_delay;
unsigned short closing_wait; /* time to wait before closing */
struct mgsl_icount icount;
- struct tty_struct *tty;
int timeout;
int x_char; /* xon/xoff character */
- int blocked_open; /* # of blocked opens */
u16 read_status_mask1; /* break detection (SR1 indications) */
u16 read_status_mask2; /* parity/framing/overun (SR2 indications) */
unsigned char ignore_status_mask1; /* break detection (SR1 indications) */
@@ -172,9 +169,6 @@ typedef struct _synclinkmp_info {
int tx_get;
int tx_count;
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
-
wait_queue_head_t status_event_wait_q;
wait_queue_head_t event_wait_q;
struct timer_list tx_timer; /* HDLC transmit timeout timer */
@@ -462,13 +456,13 @@ static int synclinkmp_device_count = 0;
* .text section address and breakpoint on module load.
* This is useful for use with gdb and add-symbol-file command.
*/
-static int break_on_load=0;
+static int break_on_load = 0;
/*
* Driver major number, defaults to zero to get auto
* assigned major number. May be forced as module parameter.
*/
-static int ttymajor=0;
+static int ttymajor = 0;
/*
* Array of user specified options for ISA adapters.
@@ -712,8 +706,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
return;
ld = tty_ldisc_ref(tty);
if (ld) {
- if (ld->receive_buf)
- ld->receive_buf(tty, data, flags, count);
+ if (ld->ops->receive_buf)
+ ld->ops->receive_buf(tty, data, flags, count);
tty_ldisc_deref(ld);
}
}
@@ -747,22 +741,22 @@ static int open(struct tty_struct *tty, struct file *filp)
}
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s open(), old ref count = %d\n",
- __FILE__,__LINE__,tty->driver->name, info->count);
+ __FILE__,__LINE__,tty->driver->name, info->port.count);
/* If port is closing, signal caller to try again */
- if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
- retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+ if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
+ if (info->port.flags & ASYNC_CLOSING)
+ interruptible_sleep_on(&info->port.close_wait);
+ retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS);
goto cleanup;
}
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
spin_lock_irqsave(&info->netlock, flags);
if (info->netcount) {
@@ -770,10 +764,10 @@ static int open(struct tty_struct *tty, struct file *filp)
spin_unlock_irqrestore(&info->netlock, flags);
goto cleanup;
}
- info->count++;
+ info->port.count++;
spin_unlock_irqrestore(&info->netlock, flags);
- if (info->count == 1) {
+ if (info->port.count == 1) {
/* 1st open on this device, init hardware */
retval = startup(info);
if (retval < 0)
@@ -796,9 +790,9 @@ static int open(struct tty_struct *tty, struct file *filp)
cleanup:
if (retval) {
if (tty->count == 1)
- info->tty = NULL; /* tty layer will release tty struct */
- if(info->count)
- info->count--;
+ info->port.tty = NULL; /* tty layer will release tty struct */
+ if(info->port.count)
+ info->port.count--;
}
return retval;
@@ -816,33 +810,33 @@ static void close(struct tty_struct *tty, struct file *filp)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s close() entry, count=%d\n",
- __FILE__,__LINE__, info->device_name, info->count);
+ __FILE__,__LINE__, info->device_name, info->port.count);
- if (!info->count)
+ if (!info->port.count)
return;
if (tty_hung_up_p(filp))
goto cleanup;
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* tty->count is 1 and the tty structure will be freed.
- * info->count should be one in this case.
+ * info->port.count should be one in this case.
* if it's not, correct it so that the port is shutdown.
*/
printk("%s(%d):%s close: bad refcount; tty->count is 1, "
- "info->count is %d\n",
- __FILE__,__LINE__, info->device_name, info->count);
- info->count = 1;
+ "info->port.count is %d\n",
+ __FILE__,__LINE__, info->device_name, info->port.count);
+ info->port.count = 1;
}
- info->count--;
+ info->port.count--;
/* if at least one open remaining, leave hardware active */
- if (info->count)
+ if (info->port.count)
goto cleanup;
- info->flags |= ASYNC_CLOSING;
+ info->port.flags |= ASYNC_CLOSING;
/* set tty->closing to notify line discipline to
* only process XON/XOFF characters. Only the N_TTY
@@ -852,14 +846,14 @@ static void close(struct tty_struct *tty, struct file *filp)
/* wait for transmit data to clear all layers */
- if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+ if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s close() calling tty_wait_until_sent\n",
__FILE__,__LINE__, info->device_name );
- tty_wait_until_sent(tty, info->closing_wait);
+ tty_wait_until_sent(tty, info->port.closing_wait);
}
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
wait_until_sent(tty, info->timeout);
flush_buffer(tty);
@@ -869,23 +863,23 @@ static void close(struct tty_struct *tty, struct file *filp)
shutdown(info);
tty->closing = 0;
- info->tty = NULL;
+ info->port.tty = NULL;
- if (info->blocked_open) {
- if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ if (info->port.blocked_open) {
+ if (info->port.close_delay) {
+ msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+ info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+ wake_up_interruptible(&info->port.close_wait);
cleanup:
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__,
- tty->driver->name, info->count);
+ tty->driver->name, info->port.count);
}
/* Called by tty_hangup() when a hangup is signaled.
@@ -905,11 +899,11 @@ static void hangup(struct tty_struct *tty)
flush_buffer(tty);
shutdown(info);
- info->count = 0;
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = NULL;
+ info->port.count = 0;
+ info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
+ info->port.tty = NULL;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
/* Set new termios settings
@@ -1123,7 +1117,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
lock_kernel();
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
goto exit;
orig_jiffies = jiffies;
@@ -1636,7 +1630,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
unsigned short new_crctype;
/* return error if TTY interface open */
- if (info->count)
+ if (info->port.count)
return -EBUSY;
switch (encoding)
@@ -1678,7 +1672,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
{
SLMP_INFO *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1692,8 +1685,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
tx_load_dma_buffer(info, skb->data, skb->len);
/* update network statistics */
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
/* done with socket buffer, so free it */
dev_kfree_skb(skb);
@@ -1733,7 +1726,7 @@ static int hdlcdev_open(struct net_device *dev)
/* arbitrate between network and tty opens */
spin_lock_irqsave(&info->netlock, flags);
- if (info->count != 0 || info->netcount != 0) {
+ if (info->port.count != 0 || info->netcount != 0) {
printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
spin_unlock_irqrestore(&info->netlock, flags);
return -EBUSY;
@@ -1819,7 +1812,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
/* return error if TTY interface open */
- if (info->count)
+ if (info->port.count)
return -EBUSY;
if (cmd != SIOCWANDEV)
@@ -1909,14 +1902,13 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static void hdlcdev_tx_timeout(struct net_device *dev)
{
SLMP_INFO *info = dev_to_port(dev);
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("hdlcdev_tx_timeout(%s)\n",dev->name);
- stats->tx_errors++;
- stats->tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
spin_lock_irqsave(&info->lock,flags);
tx_stop(info);
@@ -1949,27 +1941,27 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
{
struct sk_buff *skb = dev_alloc_skb(size);
struct net_device *dev = info->netdev;
- struct net_device_stats *stats = hdlc_stats(dev);
if (debug_level >= DEBUG_LEVEL_INFO)
printk("hdlcdev_rx(%s)\n",dev->name);
if (skb == NULL) {
- printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name);
- stats->rx_dropped++;
+ printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
+ dev->name);
+ dev->stats.rx_dropped++;
return;
}
- memcpy(skb_put(skb, size),buf,size);
+ memcpy(skb_put(skb, size), buf, size);
- skb->protocol = hdlc_type_trans(skb, info->netdev);
+ skb->protocol = hdlc_type_trans(skb, dev);
- stats->rx_packets++;
- stats->rx_bytes += size;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += size;
netif_rx(skb);
- info->netdev->last_rx = jiffies;
+ dev->last_rx = jiffies;
}
/**
@@ -2128,7 +2120,7 @@ static void bh_receive(SLMP_INFO *info)
static void bh_transmit(SLMP_INFO *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if ( debug_level >= DEBUG_LEVEL_BH )
printk( "%s(%d):%s bh_transmit() entry\n",
@@ -2178,7 +2170,7 @@ static void isr_timer(SLMP_INFO * info)
static void isr_rxint(SLMP_INFO * info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
struct mgsl_icount *icount = &info->icount;
unsigned char status = read_reg(info, SR1) & info->ie1_value & (FLGD + IDLD + CDCD + BRKD);
unsigned char status2 = read_reg(info, SR2) & info->ie2_value & OVRN;
@@ -2205,7 +2197,7 @@ static void isr_rxint(SLMP_INFO * info)
if (!(status & info->ignore_status_mask1)) {
if (info->read_status_mask1 & BRKD) {
tty_insert_flip_char(tty, 0, TTY_BREAK);
- if (info->flags & ASYNC_SAK)
+ if (info->port.flags & ASYNC_SAK)
do_SAK(tty);
}
}
@@ -2239,7 +2231,7 @@ static void isr_rxrdy(SLMP_INFO * info)
{
u16 status;
unsigned char DataByte;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
struct mgsl_icount *icount = &info->icount;
if ( debug_level >= DEBUG_LEVEL_ISR )
@@ -2352,7 +2344,7 @@ static void isr_txeom(SLMP_INFO * info, unsigned char status)
else
#endif
{
- if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) {
+ if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
tx_stop(info);
return;
}
@@ -2407,7 +2399,7 @@ static void isr_txrdy(SLMP_INFO * info)
return;
}
- if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) {
+ if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
tx_stop(info);
return;
}
@@ -2554,29 +2546,29 @@ static void isr_io_pin( SLMP_INFO *info, u16 status )
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
- if ( (info->flags & ASYNC_CHECK_CD) &&
+ if ( (info->port.flags & ASYNC_CHECK_CD) &&
(status & MISCSTATUS_DCD_LATCHED) ) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("%s CD now %s...", info->device_name,
(status & SerialSignal_DCD) ? "on" : "off");
if (status & SerialSignal_DCD)
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
else {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("doing serial hangup...");
- if (info->tty)
- tty_hangup(info->tty);
+ if (info->port.tty)
+ tty_hangup(info->port.tty);
}
}
- if ( (info->flags & ASYNC_CTS_FLOW) &&
+ if ( (info->port.flags & ASYNC_CTS_FLOW) &&
(status & MISCSTATUS_CTS_LATCHED) ) {
- if ( info->tty ) {
- if (info->tty->hw_stopped) {
+ if ( info->port.tty ) {
+ if (info->port.tty->hw_stopped) {
if (status & SerialSignal_CTS) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx start...");
- info->tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
tx_start(info);
info->pending_bh |= BH_TRANSMIT;
return;
@@ -2585,7 +2577,7 @@ static void isr_io_pin( SLMP_INFO *info, u16 status )
if (!(status & SerialSignal_CTS)) {
if ( debug_level >= DEBUG_LEVEL_ISR )
printk("CTS tx stop...");
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
tx_stop(info);
}
}
@@ -2701,7 +2693,7 @@ static irqreturn_t synclinkmp_interrupt(int dummy, void *dev_id)
* do not request bottom half processing if the
* device is not open in a normal mode.
*/
- if ( port && (port->count || port->netcount) &&
+ if ( port && (port->port.count || port->netcount) &&
port->pending_bh && !port->bh_running &&
!port->bh_requested ) {
if ( debug_level >= DEBUG_LEVEL_ISR )
@@ -2727,7 +2719,7 @@ static int startup(SLMP_INFO * info)
if ( debug_level >= DEBUG_LEVEL_INFO )
printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name);
- if (info->flags & ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
return 0;
if (!info->tx_buf) {
@@ -2750,10 +2742,10 @@ static int startup(SLMP_INFO * info)
mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10));
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags |= ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
return 0;
}
@@ -2764,7 +2756,7 @@ static void shutdown(SLMP_INFO * info)
{
unsigned long flags;
- if (!(info->flags & ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2786,17 +2778,17 @@ static void shutdown(SLMP_INFO * info)
reset_port(info);
- if (!info->tty || info->tty->termios->c_cflag & HUPCL) {
+ if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
set_signals(info);
}
spin_unlock_irqrestore(&info->lock,flags);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags &= ~ASYNC_INITIALIZED;
+ info->port.flags &= ~ASYNC_INITIALIZED;
}
static void program_hw(SLMP_INFO *info)
@@ -2827,7 +2819,7 @@ static void program_hw(SLMP_INFO *info)
get_signals(info);
- if (info->netcount || (info->tty && info->tty->termios->c_cflag & CREAD) )
+ if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) )
rx_start(info);
spin_unlock_irqrestore(&info->lock,flags);
@@ -2840,14 +2832,14 @@ static void change_params(SLMP_INFO *info)
unsigned cflag;
int bits_per_char;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s change_params()\n",
__FILE__,__LINE__, info->device_name );
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
/* if B0 rate (hangup) specified then negate DTR and RTS */
/* otherwise assert DTR and RTS */
@@ -2895,7 +2887,7 @@ static void change_params(SLMP_INFO *info)
* current data rate.
*/
if (info->params.data_rate <= 460800) {
- info->params.data_rate = tty_get_baud_rate(info->tty);
+ info->params.data_rate = tty_get_baud_rate(info->port.tty);
}
if ( info->params.data_rate ) {
@@ -2905,30 +2897,30 @@ static void change_params(SLMP_INFO *info)
info->timeout += HZ/50; /* Add .02 seconds of slop */
if (cflag & CRTSCTS)
- info->flags |= ASYNC_CTS_FLOW;
+ info->port.flags |= ASYNC_CTS_FLOW;
else
- info->flags &= ~ASYNC_CTS_FLOW;
+ info->port.flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
+ info->port.flags &= ~ASYNC_CHECK_CD;
else
- info->flags |= ASYNC_CHECK_CD;
+ info->port.flags |= ASYNC_CHECK_CD;
/* process tty input control flags */
info->read_status_mask2 = OVRN;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask2 |= PE | FRME;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask1 |= BRKD;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask2 |= PE | FRME;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask1 |= BRKD;
/* If ignoring parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask2 |= OVRN;
}
@@ -3348,7 +3340,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
/* nonblock mode is set or port is not enabled */
/* just verify that callout device is not active */
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return 0;
}
@@ -3357,25 +3349,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/* Wait for carrier detect and the line to become
* free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
+ * this loop, info->port.count is dropped by one, so that
* close() knows when to free things. We restore it upon
* exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s block_til_ready() before block, count=%d\n",
- __FILE__,__LINE__, tty->driver->name, info->count );
+ __FILE__,__LINE__, tty->driver->name, info->port.count );
spin_lock_irqsave(&info->lock, flags);
if (!tty_hung_up_p(filp)) {
extra_count = true;
- info->count--;
+ info->port.count--;
}
spin_unlock_irqrestore(&info->lock, flags);
- info->blocked_open++;
+ info->port.blocked_open++;
while (1) {
if ((tty->termios->c_cflag & CBAUD)) {
@@ -3387,8 +3379,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
- retval = (info->flags & ASYNC_HUP_NOTIFY) ?
+ if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
+ retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
-EAGAIN : -ERESTARTSYS;
break;
}
@@ -3397,7 +3389,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
get_signals(info);
spin_unlock_irqrestore(&info->lock,flags);
- if (!(info->flags & ASYNC_CLOSING) &&
+ if (!(info->port.flags & ASYNC_CLOSING) &&
(do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
break;
}
@@ -3409,24 +3401,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s block_til_ready() count=%d\n",
- __FILE__,__LINE__, tty->driver->name, info->count );
+ __FILE__,__LINE__, tty->driver->name, info->port.count );
schedule();
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
if (extra_count)
- info->count++;
- info->blocked_open--;
+ info->port.count++;
+ info->port.blocked_open--;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s block_til_ready() after, count=%d\n",
- __FILE__,__LINE__, tty->driver->name, info->count );
+ __FILE__,__LINE__, tty->driver->name, info->port.count );
if (!retval)
- info->flags |= ASYNC_NORMAL_ACTIVE;
+ info->port.flags |= ASYNC_NORMAL_ACTIVE;
return retval;
}
@@ -3808,13 +3800,12 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n",
__FILE__,__LINE__, adapter_num, port_num);
} else {
+ tty_port_init(&info->port);
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
- info->close_delay = 5*HZ/10;
- info->closing_wait = 30*HZ;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
+ info->port.close_delay = 5*HZ/10;
+ info->port.closing_wait = 30*HZ;
init_waitqueue_head(&info->status_event_wait_q);
init_waitqueue_head(&info->event_wait_q);
spin_lock_init(&info->netlock);
@@ -4885,7 +4876,7 @@ static bool rx_get_frame(SLMP_INFO *info)
unsigned int framesize = 0;
bool ReturnCode = false;
unsigned long flags;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned char addr_field = 0xff;
SCADESC *desc;
SCADESC_EX *desc_ex;
@@ -4983,9 +4974,8 @@ CheckAgain:
framesize = 0;
#if SYNCLINK_GENERIC_HDLC
{
- struct net_device_stats *stats = hdlc_stats(info->netdev);
- stats->rx_errors++;
- stats->rx_frame_errors++;
+ info->netdev->stats.rx_errors++;
+ info->netdev->stats.rx_frame_errors++;
}
#endif
}
@@ -5293,11 +5283,11 @@ static bool loopback_test(SLMP_INFO *info)
bool rc = false;
unsigned long flags;
- struct tty_struct *oldtty = info->tty;
+ struct tty_struct *oldtty = info->port.tty;
u32 speed = info->params.clock_speed;
info->params.clock_speed = 3686400;
- info->tty = NULL;
+ info->port.tty = NULL;
/* assume failure */
info->init_error = DiagStatus_DmaFailure;
@@ -5341,7 +5331,7 @@ static bool loopback_test(SLMP_INFO *info)
spin_unlock_irqrestore(&info->lock,flags);
info->params.clock_speed = speed;
- info->tty = oldtty;
+ info->port.tty = oldtty;
return rc;
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 047a17339f8..82f6a8c8633 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -95,8 +95,9 @@
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/delay.h>
+#include <linux/seq_file.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/system.h>
#include <linux/kbd_kern.h>
@@ -682,7 +683,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
static DEFINE_SPINLOCK(tty_ldisc_lock);
static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
/* Line disc dispatch table */
-static struct tty_ldisc tty_ldiscs[NR_LDISCS];
+static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
/**
* tty_register_ldisc - install a line discipline
@@ -697,7 +698,7 @@ static struct tty_ldisc tty_ldiscs[NR_LDISCS];
* takes tty_ldisc_lock to guard against ldisc races
*/
-int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
+int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
{
unsigned long flags;
int ret = 0;
@@ -706,10 +707,9 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
return -EINVAL;
spin_lock_irqsave(&tty_ldisc_lock, flags);
- tty_ldiscs[disc] = *new_ldisc;
- tty_ldiscs[disc].num = disc;
- tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
- tty_ldiscs[disc].refcount = 0;
+ tty_ldiscs[disc] = new_ldisc;
+ new_ldisc->num = disc;
+ new_ldisc->refcount = 0;
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
@@ -737,19 +737,56 @@ int tty_unregister_ldisc(int disc)
return -EINVAL;
spin_lock_irqsave(&tty_ldisc_lock, flags);
- if (tty_ldiscs[disc].refcount)
+ if (tty_ldiscs[disc]->refcount)
ret = -EBUSY;
else
- tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
+ tty_ldiscs[disc] = NULL;
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
}
EXPORT_SYMBOL(tty_unregister_ldisc);
+
+/**
+ * tty_ldisc_try_get - try and reference an ldisc
+ * @disc: ldisc number
+ * @ld: tty ldisc structure to complete
+ *
+ * Attempt to open and lock a line discipline into place. Return
+ * the line discipline refcounted and assigned in ld. On an error
+ * report the error code back
+ */
+
+static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
+{
+ unsigned long flags;
+ struct tty_ldisc_ops *ldops;
+ int err = -EINVAL;
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ ld->ops = NULL;
+ ldops = tty_ldiscs[disc];
+ /* Check the entry is defined */
+ if (ldops) {
+ /* If the module is being unloaded we can't use it */
+ if (!try_module_get(ldops->owner))
+ err = -EAGAIN;
+ else {
+ /* lock it */
+ ldops->refcount++;
+ ld->ops = ldops;
+ err = 0;
+ }
+ }
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+ return err;
+}
+
/**
* tty_ldisc_get - take a reference to an ldisc
* @disc: ldisc number
+ * @ld: tty line discipline structure to use
*
* Takes a reference to a line discipline. Deals with refcounts and
* module locking counts. Returns NULL if the discipline is not available.
@@ -760,32 +797,20 @@ EXPORT_SYMBOL(tty_unregister_ldisc);
* takes tty_ldisc_lock to guard against ldisc races
*/
-struct tty_ldisc *tty_ldisc_get(int disc)
+static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
{
- unsigned long flags;
- struct tty_ldisc *ld;
+ int err;
if (disc < N_TTY || disc >= NR_LDISCS)
- return NULL;
-
- spin_lock_irqsave(&tty_ldisc_lock, flags);
-
- ld = &tty_ldiscs[disc];
- /* Check the entry is defined */
- if (ld->flags & LDISC_FLAG_DEFINED) {
- /* If the module is being unloaded we can't use it */
- if (!try_module_get(ld->owner))
- ld = NULL;
- else /* lock it */
- ld->refcount++;
- } else
- ld = NULL;
- spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- return ld;
+ return -EINVAL;
+ err = tty_ldisc_try_get(disc, ld);
+ if (err == -EAGAIN) {
+ request_module("tty-ldisc-%d", disc);
+ err = tty_ldisc_try_get(disc, ld);
+ }
+ return err;
}
-EXPORT_SYMBOL_GPL(tty_ldisc_get);
-
/**
* tty_ldisc_put - drop ldisc reference
* @disc: ldisc number
@@ -797,22 +822,67 @@ EXPORT_SYMBOL_GPL(tty_ldisc_get);
* takes tty_ldisc_lock to guard against ldisc races
*/
-void tty_ldisc_put(int disc)
+static void tty_ldisc_put(struct tty_ldisc_ops *ld)
{
- struct tty_ldisc *ld;
unsigned long flags;
+ int disc = ld->num;
BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
spin_lock_irqsave(&tty_ldisc_lock, flags);
- ld = &tty_ldiscs[disc];
+ ld = tty_ldiscs[disc];
BUG_ON(ld->refcount == 0);
ld->refcount--;
module_put(ld->owner);
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
}
-EXPORT_SYMBOL_GPL(tty_ldisc_put);
+static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
+{
+ return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ (*pos)++;
+ return (*pos < NR_LDISCS) ? pos : NULL;
+}
+
+static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
+{
+ int i = *(loff_t *)v;
+ struct tty_ldisc ld;
+
+ if (tty_ldisc_get(i, &ld) < 0)
+ return 0;
+ seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
+ tty_ldisc_put(ld.ops);
+ return 0;
+}
+
+static const struct seq_operations tty_ldiscs_seq_ops = {
+ .start = tty_ldiscs_seq_start,
+ .next = tty_ldiscs_seq_next,
+ .stop = tty_ldiscs_seq_stop,
+ .show = tty_ldiscs_seq_show,
+};
+
+static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &tty_ldiscs_seq_ops);
+}
+
+const struct file_operations tty_ldiscs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = proc_tty_ldiscs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
/**
* tty_ldisc_assign - set ldisc on a tty
@@ -829,8 +899,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_put);
static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
{
+ ld->refcount = 0;
tty->ldisc = *ld;
- tty->ldisc.refcount = 0;
}
/**
@@ -954,6 +1024,41 @@ static void tty_ldisc_enable(struct tty_struct *tty)
}
/**
+ * tty_ldisc_restore - helper for tty ldisc change
+ * @tty: tty to recover
+ * @old: previous ldisc
+ *
+ * Restore the previous line discipline or N_TTY when a line discipline
+ * change fails due to an open error
+ */
+
+static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
+{
+ char buf[64];
+ struct tty_ldisc new_ldisc;
+
+ /* There is an outstanding reference here so this is safe */
+ tty_ldisc_get(old->ops->num, old);
+ tty_ldisc_assign(tty, old);
+ tty_set_termios_ldisc(tty, old->ops->num);
+ if (old->ops->open && (old->ops->open(tty) < 0)) {
+ tty_ldisc_put(old->ops);
+ /* This driver is always present */
+ if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
+ panic("n_tty: get");
+ tty_ldisc_assign(tty, &new_ldisc);
+ tty_set_termios_ldisc(tty, N_TTY);
+ if (new_ldisc.ops->open) {
+ int r = new_ldisc.ops->open(tty);
+ if (r < 0)
+ panic("Couldn't open N_TTY ldisc for "
+ "%s --- error %d.",
+ tty_name(tty, buf), r);
+ }
+ }
+}
+
+/**
* tty_set_ldisc - set line discipline
* @tty: the terminal to set
* @ldisc: the line discipline
@@ -967,28 +1072,18 @@ static void tty_ldisc_enable(struct tty_struct *tty)
static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
{
- int retval = 0;
- struct tty_ldisc o_ldisc;
- char buf[64];
+ int retval;
+ struct tty_ldisc o_ldisc, new_ldisc;
int work;
unsigned long flags;
- struct tty_ldisc *ld;
struct tty_struct *o_tty;
- if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
- return -EINVAL;
-
restart:
-
- ld = tty_ldisc_get(ldisc);
- /* Eduardo Blanco <ejbs@cs.cs.com.uy> */
- /* Cyrus Durgin <cider@speakeasy.org> */
- if (ld == NULL) {
- request_module("tty-ldisc-%d", ldisc);
- ld = tty_ldisc_get(ldisc);
- }
- if (ld == NULL)
- return -EINVAL;
+ /* This is a bit ugly for now but means we can break the 'ldisc
+ is part of the tty struct' assumption later */
+ retval = tty_ldisc_get(ldisc, &new_ldisc);
+ if (retval)
+ return retval;
/*
* Problem: What do we do if this blocks ?
@@ -996,8 +1091,8 @@ restart:
tty_wait_until_sent(tty, 0);
- if (tty->ldisc.num == ldisc) {
- tty_ldisc_put(ldisc);
+ if (tty->ldisc.ops->num == ldisc) {
+ tty_ldisc_put(new_ldisc.ops);
return 0;
}
@@ -1024,7 +1119,7 @@ restart:
/* Free the new ldisc we grabbed. Must drop the lock
first. */
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- tty_ldisc_put(ldisc);
+ tty_ldisc_put(o_ldisc.ops);
/*
* There are several reasons we may be busy, including
* random momentary I/O traffic. We must therefore
@@ -1038,7 +1133,7 @@ restart:
}
if (o_tty && o_tty->ldisc.refcount) {
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- tty_ldisc_put(ldisc);
+ tty_ldisc_put(o_tty->ldisc.ops);
if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
return -ERESTARTSYS;
goto restart;
@@ -1049,8 +1144,9 @@ restart:
* another ldisc change
*/
if (!test_bit(TTY_LDISC, &tty->flags)) {
+ struct tty_ldisc *ld;
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
- tty_ldisc_put(ldisc);
+ tty_ldisc_put(new_ldisc.ops);
ld = tty_ldisc_ref_wait(tty);
tty_ldisc_deref(ld);
goto restart;
@@ -1060,7 +1156,7 @@ restart:
if (o_tty)
clear_bit(TTY_LDISC, &o_tty->flags);
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-
+
/*
* From this point on we know nobody has an ldisc
* usage reference, nor can they obtain one until
@@ -1070,45 +1166,30 @@ restart:
work = cancel_delayed_work(&tty->buf.work);
/*
* Wait for ->hangup_work and ->buf.work handlers to terminate
+ * MUST NOT hold locks here.
*/
flush_scheduled_work();
/* Shutdown the current discipline. */
- if (tty->ldisc.close)
- (tty->ldisc.close)(tty);
+ if (o_ldisc.ops->close)
+ (o_ldisc.ops->close)(tty);
/* Now set up the new line discipline. */
- tty_ldisc_assign(tty, ld);
+ tty_ldisc_assign(tty, &new_ldisc);
tty_set_termios_ldisc(tty, ldisc);
- if (tty->ldisc.open)
- retval = (tty->ldisc.open)(tty);
+ if (new_ldisc.ops->open)
+ retval = (new_ldisc.ops->open)(tty);
if (retval < 0) {
- tty_ldisc_put(ldisc);
- /* There is an outstanding reference here so this is safe */
- tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num));
- tty_set_termios_ldisc(tty, tty->ldisc.num);
- if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
- tty_ldisc_put(o_ldisc.num);
- /* This driver is always present */
- tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
- tty_set_termios_ldisc(tty, N_TTY);
- if (tty->ldisc.open) {
- int r = tty->ldisc.open(tty);
-
- if (r < 0)
- panic("Couldn't open N_TTY ldisc for "
- "%s --- error %d.",
- tty_name(tty, buf), r);
- }
- }
+ tty_ldisc_put(new_ldisc.ops);
+ tty_ldisc_restore(tty, &o_ldisc);
}
/* At this point we hold a reference to the new ldisc and a
a reference to the old ldisc. If we ended up flipping back
to the existing ldisc we have two references to it */
- if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc)
+ if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
tty->ops->set_ldisc(tty);
- tty_ldisc_put(o_ldisc.num);
+ tty_ldisc_put(o_ldisc.ops);
/*
* Allow ldisc referencing to occur as soon as the driver
@@ -1335,8 +1416,8 @@ void tty_wakeup(struct tty_struct *tty)
if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
ld = tty_ldisc_ref(tty);
if (ld) {
- if (ld->write_wakeup)
- ld->write_wakeup(tty);
+ if (ld->ops->write_wakeup)
+ ld->ops->write_wakeup(tty);
tty_ldisc_deref(ld);
}
}
@@ -1357,8 +1438,8 @@ void tty_ldisc_flush(struct tty_struct *tty)
{
struct tty_ldisc *ld = tty_ldisc_ref(tty);
if (ld) {
- if (ld->flush_buffer)
- ld->flush_buffer(tty);
+ if (ld->ops->flush_buffer)
+ ld->ops->flush_buffer(tty);
tty_ldisc_deref(ld);
}
tty_buffer_flush(tty);
@@ -1386,7 +1467,7 @@ static void tty_reset_termios(struct tty_struct *tty)
* do_tty_hangup - actual handler for hangup events
* @work: tty device
*
- * This can be called by the "eventd" kernel thread. That is process
+k * This can be called by the "eventd" kernel thread. That is process
* synchronous but doesn't hold any locks, so we need to make sure we
* have the appropriate locks for what we're doing.
*
@@ -1449,14 +1530,14 @@ static void do_tty_hangup(struct work_struct *work)
ld = tty_ldisc_ref(tty);
if (ld != NULL) {
/* We may have no line discipline at this point */
- if (ld->flush_buffer)
- ld->flush_buffer(tty);
+ if (ld->ops->flush_buffer)
+ ld->ops->flush_buffer(tty);
tty_driver_flush_buffer(tty);
if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
- ld->write_wakeup)
- ld->write_wakeup(tty);
- if (ld->hangup)
- ld->hangup(tty);
+ ld->ops->write_wakeup)
+ ld->ops->write_wakeup(tty);
+ if (ld->ops->hangup)
+ ld->ops->hangup(tty);
}
/*
* FIXME: Once we trust the LDISC code better we can wait here for
@@ -1825,8 +1906,8 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
/* We want to wait for the line discipline to sort out in this
situation */
ld = tty_ldisc_ref_wait(tty);
- if (ld->read)
- i = (ld->read)(tty, file, buf, count);
+ if (ld->ops->read)
+ i = (ld->ops->read)(tty, file, buf, count);
else
i = -EIO;
tty_ldisc_deref(ld);
@@ -1978,10 +2059,10 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
tty->driver->name);
ld = tty_ldisc_ref_wait(tty);
- if (!ld->write)
+ if (!ld->ops->write)
ret = -EIO;
else
- ret = do_tty_write(ld->write, tty, file, buf, count);
+ ret = do_tty_write(ld->ops->write, tty, file, buf, count);
tty_ldisc_deref(ld);
return ret;
}
@@ -2007,6 +2088,42 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
return tty_write(file, buf, count, ppos);
}
+void tty_port_init(struct tty_port *port)
+{
+ memset(port, 0, sizeof(*port));
+ init_waitqueue_head(&port->open_wait);
+ init_waitqueue_head(&port->close_wait);
+ mutex_init(&port->mutex);
+ port->close_delay = (50 * HZ) / 100;
+ port->closing_wait = (3000 * HZ) / 100;
+}
+EXPORT_SYMBOL(tty_port_init);
+
+int tty_port_alloc_xmit_buf(struct tty_port *port)
+{
+ /* We may sleep in get_zeroed_page() */
+ mutex_lock(&port->mutex);
+ if (port->xmit_buf == NULL)
+ port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
+ mutex_unlock(&port->mutex);
+ if (port->xmit_buf == NULL)
+ return -ENOMEM;
+ return 0;
+}
+EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
+
+void tty_port_free_xmit_buf(struct tty_port *port)
+{
+ mutex_lock(&port->mutex);
+ if (port->xmit_buf != NULL) {
+ free_page((unsigned long)port->xmit_buf);
+ port->xmit_buf = NULL;
+ }
+ mutex_unlock(&port->mutex);
+}
+EXPORT_SYMBOL(tty_port_free_xmit_buf);
+
+
static char ptychar[] = "pqrstuvwxyzabcde";
/**
@@ -2076,6 +2193,7 @@ static int init_dev(struct tty_driver *driver, int idx,
struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
int retval = 0;
+ struct tty_ldisc *ld;
/* check whether we're reopening an existing tty */
if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
@@ -2224,17 +2342,19 @@ static int init_dev(struct tty_driver *driver, int idx,
* If we fail here just call release_tty to clean up. No need
* to decrement the use counts, as release_tty doesn't care.
*/
+
+ ld = &tty->ldisc;
- if (tty->ldisc.open) {
- retval = (tty->ldisc.open)(tty);
+ if (ld->ops->open) {
+ retval = (ld->ops->open)(tty);
if (retval)
goto release_mem_out;
}
- if (o_tty && o_tty->ldisc.open) {
- retval = (o_tty->ldisc.open)(o_tty);
+ if (o_tty && o_tty->ldisc.ops->open) {
+ retval = (o_tty->ldisc.ops->open)(o_tty);
if (retval) {
- if (tty->ldisc.close)
- (tty->ldisc.close)(tty);
+ if (ld->ops->close)
+ (ld->ops->close)(tty);
goto release_mem_out;
}
tty_ldisc_enable(o_tty);
@@ -2378,6 +2498,7 @@ static void release_tty(struct tty_struct *tty, int idx)
static void release_dev(struct file *filp)
{
struct tty_struct *tty, *o_tty;
+ struct tty_ldisc ld;
int pty_master, tty_closing, o_tty_closing, do_sleep;
int devpts;
int idx;
@@ -2611,26 +2732,27 @@ static void release_dev(struct file *filp)
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
/*
* Shutdown the current line discipline, and reset it to N_TTY.
- * N.B. why reset ldisc when we're releasing the memory??
*
* FIXME: this MUST get fixed for the new reflocking
*/
- if (tty->ldisc.close)
- (tty->ldisc.close)(tty);
- tty_ldisc_put(tty->ldisc.num);
+ if (tty->ldisc.ops->close)
+ (tty->ldisc.ops->close)(tty);
+ tty_ldisc_put(tty->ldisc.ops);
/*
* Switch the line discipline back
*/
- tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
+ WARN_ON(tty_ldisc_get(N_TTY, &ld));
+ tty_ldisc_assign(tty, &ld);
tty_set_termios_ldisc(tty, N_TTY);
if (o_tty) {
/* FIXME: could o_tty be in setldisc here ? */
clear_bit(TTY_LDISC, &o_tty->flags);
- if (o_tty->ldisc.close)
- (o_tty->ldisc.close)(o_tty);
- tty_ldisc_put(o_tty->ldisc.num);
- tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY));
+ if (o_tty->ldisc.ops->close)
+ (o_tty->ldisc.ops->close)(o_tty);
+ tty_ldisc_put(o_tty->ldisc.ops);
+ WARN_ON(tty_ldisc_get(N_TTY, &ld));
+ tty_ldisc_assign(o_tty, &ld);
tty_set_termios_ldisc(o_tty, N_TTY);
}
/*
@@ -2899,8 +3021,8 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
return 0;
ld = tty_ldisc_ref_wait(tty);
- if (ld->poll)
- ret = (ld->poll)(tty, filp, wait);
+ if (ld->ops->poll)
+ ret = (ld->ops->poll)(tty, filp, wait);
tty_ldisc_deref(ld);
return ret;
}
@@ -2974,7 +3096,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
if (get_user(ch, p))
return -EFAULT;
ld = tty_ldisc_ref_wait(tty);
- ld->receive_buf(tty, &ch, &mbz, 1);
+ ld->ops->receive_buf(tty, &ch, &mbz, 1);
tty_ldisc_deref(ld);
return 0;
}
@@ -3395,35 +3517,31 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd,
unsigned __user *p)
{
- int retval = -EINVAL;
-
- if (tty->ops->tiocmset) {
- unsigned int set, clear, val;
-
- retval = get_user(val, p);
- if (retval)
- return retval;
-
- set = clear = 0;
- switch (cmd) {
- case TIOCMBIS:
- set = val;
- break;
- case TIOCMBIC:
- clear = val;
- break;
- case TIOCMSET:
- set = val;
- clear = ~val;
- break;
- }
+ int retval;
+ unsigned int set, clear, val;
- set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
- clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+ if (tty->ops->tiocmset == NULL)
+ return -EINVAL;
- retval = tty->ops->tiocmset(tty, file, set, clear);
+ retval = get_user(val, p);
+ if (retval)
+ return retval;
+ set = clear = 0;
+ switch (cmd) {
+ case TIOCMBIS:
+ set = val;
+ break;
+ case TIOCMBIC:
+ clear = val;
+ break;
+ case TIOCMSET:
+ set = val;
+ clear = ~val;
+ break;
}
- return retval;
+ set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+ clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
+ return tty->ops->tiocmset(tty, file, set, clear);
}
/*
@@ -3528,7 +3646,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case TIOCGSID:
return tiocgsid(tty, real_tty, p);
case TIOCGETD:
- return put_user(tty->ldisc.num, (int __user *)p);
+ return put_user(tty->ldisc.ops->num, (int __user *)p);
case TIOCSETD:
return tiocsetd(tty, p);
#ifdef CONFIG_VT
@@ -3581,8 +3699,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
ld = tty_ldisc_ref_wait(tty);
retval = -EINVAL;
- if (ld->ioctl) {
- retval = ld->ioctl(tty, file, cmd, arg);
+ if (ld->ops->ioctl) {
+ retval = ld->ops->ioctl(tty, file, cmd, arg);
if (retval == -ENOIOCTLCMD)
retval = -EINVAL;
}
@@ -3609,8 +3727,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
}
ld = tty_ldisc_ref_wait(tty);
- if (ld->compat_ioctl)
- retval = ld->compat_ioctl(tty, file, cmd, arg);
+ if (ld->ops->compat_ioctl)
+ retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
tty_ldisc_deref(ld);
return retval;
@@ -3782,7 +3900,8 @@ static void flush_to_ldisc(struct work_struct *work)
flag_buf = head->flag_buf_ptr + head->read;
head->read += count;
spin_unlock_irqrestore(&tty->buf.lock, flags);
- disc->receive_buf(tty, char_buf, flag_buf, count);
+ disc->ops->receive_buf(tty, char_buf,
+ flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
/* Restore the queue head */
@@ -3843,9 +3962,12 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
static void initialize_tty_struct(struct tty_struct *tty)
{
+ struct tty_ldisc ld;
memset(tty, 0, sizeof(struct tty_struct));
tty->magic = TTY_MAGIC;
- tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
+ if (tty_ldisc_get(N_TTY, &ld) < 0)
+ panic("n_tty: init_tty");
+ tty_ldisc_assign(tty, &ld);
tty->session = NULL;
tty->pgrp = NULL;
tty->overrun_time = jiffies;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 8f81139d619..ea9fc5d03b9 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -491,8 +491,8 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
ld = tty_ldisc_ref(tty);
if (ld != NULL) {
- if (ld->set_termios)
- (ld->set_termios)(tty, &old_termios);
+ if (ld->ops->set_termios)
+ (ld->ops->set_termios)(tty, &old_termios);
tty_ldisc_deref(ld);
}
mutex_unlock(&tty->termios_mutex);
@@ -552,8 +552,8 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
ld = tty_ldisc_ref(tty);
if (ld != NULL) {
- if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
- ld->flush_buffer(tty);
+ if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
+ ld->ops->flush_buffer(tty);
tty_ldisc_deref(ld);
}
@@ -959,12 +959,12 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
ld = tty_ldisc_ref(tty);
switch (arg) {
case TCIFLUSH:
- if (ld && ld->flush_buffer)
- ld->flush_buffer(tty);
+ if (ld && ld->ops->flush_buffer)
+ ld->ops->flush_buffer(tty);
break;
case TCIOFLUSH:
- if (ld && ld->flush_buffer)
- ld->flush_buffer(tty);
+ if (ld && ld->ops->flush_buffer)
+ ld->ops->flush_buffer(tty);
/* fall through */
case TCOFLUSH:
tty_driver_flush_buffer(tty);
diff --git a/drivers/dio/dio-driver.c b/drivers/dio/dio-driver.c
index 8cd8507b1a8..9c0c9afcd0a 100644
--- a/drivers/dio/dio-driver.c
+++ b/drivers/dio/dio-driver.c
@@ -119,19 +119,7 @@ static int dio_bus_match(struct device *dev, struct device_driver *drv)
if (!ids)
return 0;
- while (ids->id) {
- if (ids->id == DIO_WILDCARD)
- return 1;
- if (DIO_NEEDSSECID(ids->id & 0xff)) {
- if (ids->id == d->id)
- return 1;
- } else {
- if ((ids->id & 0xff) == (d->id & 0xff))
- return 1;
- }
- ids++;
- }
- return 0;
+ return dio_match_device(ids, d) ? 1 : 0;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 1fcc9a898d8..8950e9546f4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -769,7 +769,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
ipoib_mcast_stop_thread(dev, 0);
local_irq_save(flags);
- netif_tx_lock(dev);
+ netif_addr_lock(dev);
spin_lock(&priv->lock);
/*
@@ -846,7 +846,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
}
spin_unlock(&priv->lock);
- netif_tx_unlock(dev);
+ netif_addr_unlock(dev);
local_irq_restore(flags);
/* We have to cancel outside of the spinlock */
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c
index 4e92100c56a..1839194ea98 100644
--- a/drivers/input/keyboard/atakbd.c
+++ b/drivers/input/keyboard/atakbd.c
@@ -220,7 +220,7 @@ static int __init atakbd_init(void)
int i, error;
if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
- return -EIO;
+ return -ENODEV;
// need to init core driver if not already done so
if (atari_keyb_init())
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 7ff71ba7b7c..b9694b6445d 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -216,7 +216,7 @@ static void serport_ldisc_write_wakeup(struct tty_struct * tty)
* The line discipline structure.
*/
-static struct tty_ldisc serport_ldisc = {
+static struct tty_ldisc_ops serport_ldisc = {
.owner = THIS_MODULE,
.name = "input",
.open = serport_ldisc_open,
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 2095153582f..8a35029caca 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -466,7 +466,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
ld = tty_ldisc_ref(mp->tty);
if (ld == NULL)
return -1;
- if (ld->receive_buf == NULL) {
+ if (ld->ops->receive_buf == NULL) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
#endif
@@ -501,7 +501,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
datahandle, skb->len);
#endif
- ld->receive_buf(mp->tty, skb->data, NULL, skb->len);
+ ld->ops->receive_buf(mp->tty, skb->data, NULL, skb->len);
kfree_skb(skb);
tty_ldisc_deref(ld);
return 0;
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 45d1ee93cd3..5e89fa17781 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -766,7 +766,7 @@ gigaset_tty_wakeup(struct tty_struct *tty)
cs_put(cs);
}
-static struct tty_ldisc gigaset_ldisc = {
+static struct tty_ldisc_ops gigaset_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "ser_gigaset",
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index ef1a300068d..bb904a0a98b 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -287,7 +287,7 @@ isdn_net_unbind_channel(isdn_net_local * lp)
BEWARE! This chunk of code cannot be called from hardware
interrupt handler. I hope it is true. --ANK
*/
- qdisc_reset(lp->netdev->dev->qdisc);
+ qdisc_reset_all_tx(lp->netdev->dev);
}
lp->dialstate = 0;
dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 7a7803b5d49..93ea201f426 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -38,7 +38,6 @@ config VIDEO_ALLOW_V4L1
bool "Enable Video For Linux API 1 (DEPRECATED)"
depends on VIDEO_DEV && VIDEO_V4L2_COMMON
default VIDEO_DEV && VIDEO_V4L2_COMMON
- select VIDEO_V4L1_COMPAT
---help---
Enables drivers based on the legacy V4L1 API.
@@ -49,9 +48,9 @@ config VIDEO_ALLOW_V4L1
If you are unsure as to whether this is required, answer Y.
config VIDEO_V4L1_COMPAT
- bool "Enable Video For Linux API 1 compatible Layer"
+ bool "Enable Video For Linux API 1 compatible Layer" if !VIDEO_ALLOW_V4L1
depends on VIDEO_DEV
- default VIDEO_DEV
+ default y
---help---
Enables a compatibility API used by most V4L2 devices to allow
its usage with legacy applications that supports only V4L1 api.
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index 26650520792..16792a68a44 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -66,7 +66,6 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
if (ir_codes)
memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
-
dev->keycode = ir->ir_codes;
dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
dev->keycodemax = IR_KEYTAB_SIZE;
@@ -78,6 +77,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
if (repeat)
set_bit(EV_REP, dev->evbit);
}
+EXPORT_SYMBOL_GPL(ir_input_init);
void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
{
@@ -86,6 +86,7 @@ void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
ir_input_key_event(dev,ir);
}
}
+EXPORT_SYMBOL_GPL(ir_input_nokey);
void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
u32 ir_key, u32 ir_raw)
@@ -104,6 +105,7 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
ir_input_key_event(dev,ir);
}
}
+EXPORT_SYMBOL_GPL(ir_input_keydown);
/* -------------------------------------------------------------------------- */
/* extract mask bits out of data and pack them into the result */
@@ -122,6 +124,7 @@ u32 ir_extract_bits(u32 data, u32 mask)
return value;
}
+EXPORT_SYMBOL_GPL(ir_extract_bits);
static int inline getbit(u32 *samples, int bit)
{
@@ -146,6 +149,7 @@ int ir_dump_samples(u32 *samples, int count)
printk("\n");
return 0;
}
+EXPORT_SYMBOL_GPL(ir_dump_samples);
/* decode raw samples, pulse distance coding used by NEC remotes */
int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
@@ -212,6 +216,7 @@ int ir_decode_pulsedistance(u32 *samples, int count, int low, int high)
return value;
}
+EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
/* decode raw samples, biphase coding, used by rc5 for example */
int ir_decode_biphase(u32 *samples, int count, int low, int high)
@@ -253,6 +258,7 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high)
}
return value;
}
+EXPORT_SYMBOL_GPL(ir_decode_biphase);
/* RC5 decoding stuff, moved from bttv-input.c to share it with
* saa7134 */
@@ -353,6 +359,7 @@ void ir_rc5_timer_end(unsigned long data)
}
}
}
+EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
void ir_rc5_timer_keyup(unsigned long data)
{
@@ -361,21 +368,4 @@ void ir_rc5_timer_keyup(unsigned long data)
dprintk(1, "ir-common: key released\n");
ir_input_nokey(ir->dev, &ir->ir);
}
-
-EXPORT_SYMBOL_GPL(ir_input_init);
-EXPORT_SYMBOL_GPL(ir_input_nokey);
-EXPORT_SYMBOL_GPL(ir_input_keydown);
-
-EXPORT_SYMBOL_GPL(ir_extract_bits);
-EXPORT_SYMBOL_GPL(ir_dump_samples);
-EXPORT_SYMBOL_GPL(ir_decode_biphase);
-EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
-
-EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 89c7660b85d..d01965e9692 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -233,7 +233,7 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
{
- u32 *cpu;
+ __le32 *cpu;
dma_addr_t dma_addr;
cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr);
@@ -250,7 +250,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
struct scatterlist *list, int sglen )
{
- u32 *ptr, fill;
+ __le32 *ptr, fill;
int nr_pages = 0;
int i,p;
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index 9c905399a23..05bde9ccb77 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -338,7 +338,7 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field)
{
struct saa7146_vv *vv = dev->vv_data;
- u32 *clipping = vv->d_clipping.cpu_addr;
+ __le32 *clipping = vv->d_clipping.cpu_addr;
int width = fh->ov.win.w.width;
int height = fh->ov.win.w.height;
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index 35b01ec40a5..c11da4d09cd 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -24,7 +24,7 @@ static inline u32 saa7146_i2c_status(struct saa7146_dev *dev)
sent through the saa7146. have a look at the specifications p. 122 ff
to understand this. it returns the number of u32s to send, or -1
in case of an error. */
-static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
+static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, __le32 *op)
{
int h1, h2;
int i, j, addr;
@@ -47,7 +47,7 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
}
/* be careful: clear out the i2c-mem first */
- memset(op,0,sizeof(u32)*mem);
+ memset(op,0,sizeof(__le32)*mem);
/* loop through all messages */
for(i = 0; i < num; i++) {
@@ -57,16 +57,16 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
so we have to perform a translation */
addr = (m[i].addr*2) + ( (0 != (m[i].flags & I2C_M_RD)) ? 1 : 0);
h1 = op_count/3; h2 = op_count%3;
- op[h1] |= ( (u8)addr << ((3-h2)*8));
- op[h1] |= (SAA7146_I2C_START << ((3-h2)*2));
+ op[h1] |= cpu_to_le32( (u8)addr << ((3-h2)*8));
+ op[h1] |= cpu_to_le32(SAA7146_I2C_START << ((3-h2)*2));
op_count++;
/* loop through all bytes of message i */
for(j = 0; j < m[i].len; j++) {
/* insert the data bytes */
h1 = op_count/3; h2 = op_count%3;
- op[h1] |= ( (u32)((u8)m[i].buf[j]) << ((3-h2)*8));
- op[h1] |= ( SAA7146_I2C_CONT << ((3-h2)*2));
+ op[h1] |= cpu_to_le32( (u32)((u8)m[i].buf[j]) << ((3-h2)*8));
+ op[h1] |= cpu_to_le32( SAA7146_I2C_CONT << ((3-h2)*2));
op_count++;
}
@@ -75,9 +75,9 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
/* have a look at the last byte inserted:
if it was: ...CONT change it to ...STOP */
h1 = (op_count-1)/3; h2 = (op_count-1)%3;
- if ( SAA7146_I2C_CONT == (0x3 & (op[h1] >> ((3-h2)*2))) ) {
- op[h1] &= ~(0x2 << ((3-h2)*2));
- op[h1] |= (SAA7146_I2C_STOP << ((3-h2)*2));
+ if ( SAA7146_I2C_CONT == (0x3 & (le32_to_cpu(op[h1]) >> ((3-h2)*2))) ) {
+ op[h1] &= ~cpu_to_le32(0x2 << ((3-h2)*2));
+ op[h1] |= cpu_to_le32(SAA7146_I2C_STOP << ((3-h2)*2));
}
/* return the number of u32s to send */
@@ -88,7 +88,7 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op)
which bytes were read through the adapter and write them back to the corresponding
i2c-message. but instead, we simply write back all bytes.
fixme: this could be improved. */
-static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op)
+static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, __le32 *op)
{
int i, j;
int op_count = 0;
@@ -101,7 +101,7 @@ static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op)
/* loop throgh all bytes of message i */
for(j = 0; j < m[i].len; j++) {
/* write back all bytes that could have been read */
- m[i].buf[j] = (op[op_count/3] >> ((3-(op_count%3))*8));
+ m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8));
op_count++;
}
}
@@ -174,7 +174,7 @@ static int saa7146_i2c_reset(struct saa7146_dev *dev)
/* this functions writes out the data-byte 'dword' to the i2c-device.
it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
failed badly (e.g. address error) */
-static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay)
+static int saa7146_i2c_writeout(struct saa7146_dev *dev, __le32 *dword, int short_delay)
{
u32 status = 0, mc2 = 0;
int trial = 0;
@@ -186,7 +186,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
- saa7146_write(dev, I2C_TRANSFER, *dword);
+ saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
dev->i2c_op = 1;
SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
@@ -209,7 +209,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
status = saa7146_read(dev, I2C_STATUS);
} else {
saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
- saa7146_write(dev, I2C_TRANSFER, *dword);
+ saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
saa7146_write(dev, MC2, (MASK_00 | MASK_16));
/* do not poll for i2c-status before upload is complete */
@@ -282,7 +282,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
}
/* read back data, just in case we were reading ... */
- *dword = saa7146_read(dev, I2C_TRANSFER);
+ *dword = cpu_to_le32(saa7146_read(dev, I2C_TRANSFER));
DEB_I2C(("after: 0x%08x\n",*dword));
return 0;
@@ -291,7 +291,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
{
int i = 0, count = 0;
- u32* buffer = dev->d_i2c.cpu_addr;
+ __le32 *buffer = dev->d_i2c.cpu_addr;
int err = 0;
int address_err = 0;
int short_delay = 0;
@@ -376,7 +376,7 @@ out:
/* another bug in revision 0: the i2c-registers get uploaded randomly by other
uploads, so we better clear them out before continueing */
if( 0 == dev->revision ) {
- u32 zero = 0;
+ __le32 zero = 0;
saa7146_i2c_reset(dev);
if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
INFO(("revision 0 error. this should never happen.\n"));
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 3cbc6ebbe64..a5e62750eea 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -605,8 +605,8 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
struct saa7146_pgtable *pt1 = &buf->pt[0];
struct saa7146_pgtable *pt2 = &buf->pt[1];
struct saa7146_pgtable *pt3 = &buf->pt[2];
- u32 *ptr1, *ptr2, *ptr3;
- u32 fill;
+ __le32 *ptr1, *ptr2, *ptr3;
+ __le32 fill;
int size = buf->fmt->width*buf->fmt->height;
int i,p,m1,m2,m3,o1,o2;
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 85482960d01..850d5689b14 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -34,6 +34,7 @@ config MEDIA_TUNER
menuconfig MEDIA_TUNER_CUSTOMIZE
bool "Customize analog and hybrid tuner modules to build"
depends on MEDIA_TUNER
+ default n
help
This allows the user to deselect tuner drivers unnecessary
for their hardware from the build. Use this option with care
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index 83e7561960c..ab14ceb9e0c 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -1,5 +1,5 @@
/*
- tda18271-tables.c - driver for the Philips / NXP TDA18271 silicon tuner
+ tda18271-maps.c - driver for the Philips / NXP TDA18271 silicon tuner
Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 30eb07b7f9e..4dd1d2421cc 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <media/tuner.h>
#include <linux/mutex.h>
+#include <asm/unaligned.h>
#include "tuner-i2c.h"
#include "tuner-xc2028.h"
#include "tuner-xc2028-types.h"
@@ -292,10 +293,10 @@ static int load_all_firmwares(struct dvb_frontend *fe)
name[sizeof(name) - 1] = 0;
p += sizeof(name) - 1;
- priv->firm_version = le16_to_cpu(*(__u16 *) p);
+ priv->firm_version = get_unaligned_le16(p);
p += 2;
- n_array = le16_to_cpu(*(__u16 *) p);
+ n_array = get_unaligned_le16(p);
p += 2;
tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
@@ -324,26 +325,26 @@ static int load_all_firmwares(struct dvb_frontend *fe)
}
/* Checks if there's enough bytes to read */
- if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
- tuner_err("Firmware header is incomplete!\n");
- goto corrupt;
- }
+ if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
+ goto header;
- type = le32_to_cpu(*(__u32 *) p);
+ type = get_unaligned_le32(p);
p += sizeof(type);
- id = le64_to_cpu(*(v4l2_std_id *) p);
+ id = get_unaligned_le64(p);
p += sizeof(id);
if (type & HAS_IF) {
- int_freq = le16_to_cpu(*(__u16 *) p);
+ int_freq = get_unaligned_le16(p);
p += sizeof(int_freq);
+ if (endp - p < sizeof(size))
+ goto header;
}
- size = le32_to_cpu(*(__u32 *) p);
+ size = get_unaligned_le32(p);
p += sizeof(size);
- if ((!size) || (size + p > endp)) {
+ if (!size || size > endp - p) {
tuner_err("Firmware type ");
dump_firm_type(type);
printk("(%x), id %llx is corrupted "
@@ -382,6 +383,8 @@ static int load_all_firmwares(struct dvb_frontend *fe)
goto done;
+header:
+ tuner_err("Firmware header is incomplete!\n");
corrupt:
rc = -EINVAL;
tuner_err("Error: firmware file is corrupted!\n");
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 4878d6477a8..5f99de0ad61 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -36,6 +36,10 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+static int xc5000_load_fw_on_attach;
+module_param_named(init_fw, xc5000_load_fw_on_attach, int, 0644);
+MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization.");
+
#define dprintk(level,fmt, arg...) if (debug >= level) \
printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
@@ -972,6 +976,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
fe->tuner_priv = priv;
+ if (xc5000_load_fw_on_attach)
+ xc5000_init(fe);
+
return fe;
}
EXPORT_SYMBOL(xc5000_attach);
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 7b21b49f194..8bc1445bd33 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -21,6 +21,7 @@ source "drivers/media/dvb/dvb-usb/Kconfig"
source "drivers/media/dvb/ttusb-budget/Kconfig"
source "drivers/media/dvb/ttusb-dec/Kconfig"
source "drivers/media/dvb/cinergyT2/Kconfig"
+source "drivers/media/dvb/siano/Kconfig"
comment "Supported FlexCopII (B2C2) Adapters"
depends on DVB_CORE && (PCI || USB) && I2C
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index a7ad0841e6f..d6ba4d19520 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/
+obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index 375fd2892a1..d19b59299d7 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -128,7 +128,7 @@ struct bt878 {
dma_addr_t buf_dma;
u32 risc_size;
- u32 *risc_cpu;
+ __le32 *risc_cpu;
dma_addr_t risc_dma;
u32 risc_pos;
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index b0d347daae4..eb91fd808c1 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -247,7 +247,7 @@ struct dmx_demux {
void* priv; /* Pointer to private data of the API client */
int (*open) (struct dmx_demux* demux);
int (*close) (struct dmx_demux* demux);
- int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
+ int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count);
int (*allocate_ts_feed) (struct dmx_demux* demux,
struct dmx_ts_feed** feed,
dmx_ts_cb callback);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index df5bef6a251..1cf9fcb6f51 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -96,7 +96,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
if (avail > todo)
avail = todo;
- ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1);
+ ret = dvb_ringbuffer_read_user(src, buf, avail);
if (ret < 0)
break;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 588fbe105c2..8e5dd7b1f03 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1357,7 +1357,7 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
while (idx != -1) {
- dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0);
+ dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
if (connection_id == -1)
connection_id = hdr[0];
if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
@@ -1438,7 +1438,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
goto exit;
}
- dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0);
+ dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
if (connection_id == -1)
connection_id = hdr[0];
if (hdr[0] == connection_id) {
@@ -1449,8 +1449,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
fraglen -= 2;
}
- if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2,
- (u8 *)buf + pktlen, fraglen, 1)) < 0) {
+ if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2,
+ buf + pktlen, fraglen)) < 0) {
goto exit;
}
pktlen += fraglen;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 934e15fffc5..e2eca0b1fe7 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1056,16 +1056,27 @@ static int dvbdmx_close(struct dmx_demux *demux)
return 0;
}
-static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count)
+static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count)
{
struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
+ void *p;
if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
return -EINVAL;
- if (mutex_lock_interruptible(&dvbdemux->mutex))
+ p = kmalloc(count, GFP_USER);
+ if (!p)
+ return -ENOMEM;
+ if (copy_from_user(p, buf, count)) {
+ kfree(p);
+ return -EFAULT;
+ }
+ if (mutex_lock_interruptible(&dvbdemux->mutex)) {
+ kfree(p);
return -ERESTARTSYS;
- dvb_dmx_swfilter(dvbdemux, (u8 *)buf, count);
+ }
+ dvb_dmx_swfilter(dvbdemux, p, count);
+ kfree(p);
mutex_unlock(&dvbdemux->mutex);
if (signal_pending(current))
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index c2334aef414..c93019ca519 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -606,7 +606,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
if (priv->ule_dbit) {
/* Set D-bit for CRC32 verification,
* if it was set originally. */
- ulen |= 0x0080;
+ ulen |= htons(0x8000);
}
ule_crc = iov_crc32(ule_crc, iov, 3);
@@ -1133,7 +1133,7 @@ static void wq_set_multicast_list (struct work_struct *work)
dvb_net_feed_stop(dev);
priv->rx_mode = RX_MODE_UNI;
- netif_tx_lock_bh(dev);
+ netif_addr_lock_bh(dev);
if (dev->flags & IFF_PROMISC) {
dprintk("%s: promiscuous mode\n", dev->name);
@@ -1158,7 +1158,7 @@ static void wq_set_multicast_list (struct work_struct *work)
}
}
- netif_tx_unlock_bh(dev);
+ netif_addr_unlock_bh(dev);
dvb_net_feed_start(dev);
}
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 872985b7912..584bbd194dc 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -107,35 +107,43 @@ void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
wake_up(&rbuf->queue);
}
-
-
-ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
+ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
{
size_t todo = len;
size_t split;
split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
if (split > 0) {
- if (!usermem)
- memcpy(buf, rbuf->data+rbuf->pread, split);
- else
- if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
- return -EFAULT;
+ if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
+ return -EFAULT;
buf += split;
todo -= split;
rbuf->pread = 0;
}
- if (!usermem)
- memcpy(buf, rbuf->data+rbuf->pread, todo);
- else
- if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
- return -EFAULT;
+ if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
+ return -EFAULT;
rbuf->pread = (rbuf->pread + todo) % rbuf->size;
return len;
}
+void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
+{
+ size_t todo = len;
+ size_t split;
+
+ split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
+ if (split > 0) {
+ memcpy(buf, rbuf->data+rbuf->pread, split);
+ buf += split;
+ todo -= split;
+ rbuf->pread = 0;
+ }
+ memcpy(buf, rbuf->data+rbuf->pread, todo);
+
+ rbuf->pread = (rbuf->pread + todo) % rbuf->size;
+}
ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
@@ -171,8 +179,8 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le
return status;
}
-ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
- int offset, u8* buf, size_t len, int usermem)
+ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
+ int offset, u8 __user *buf, size_t len)
{
size_t todo;
size_t split;
@@ -187,21 +195,40 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
todo = len;
split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
if (split > 0) {
- if (!usermem)
- memcpy(buf, rbuf->data+idx, split);
- else
- if (copy_to_user(buf, rbuf->data+idx, split))
- return -EFAULT;
+ if (copy_to_user(buf, rbuf->data+idx, split))
+ return -EFAULT;
buf += split;
todo -= split;
idx = 0;
}
- if (!usermem)
- memcpy(buf, rbuf->data+idx, todo);
- else
- if (copy_to_user(buf, rbuf->data+idx, todo))
- return -EFAULT;
+ if (copy_to_user(buf, rbuf->data+idx, todo))
+ return -EFAULT;
+
+ return len;
+}
+ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
+ int offset, u8* buf, size_t len)
+{
+ size_t todo;
+ size_t split;
+ size_t pktlen;
+
+ pktlen = rbuf->data[idx] << 8;
+ pktlen |= rbuf->data[(idx + 1) % rbuf->size];
+ if (offset > pktlen) return -EINVAL;
+ if ((offset + len) > pktlen) len = pktlen - offset;
+
+ idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
+ todo = len;
+ split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
+ if (split > 0) {
+ memcpy(buf, rbuf->data+idx, split);
+ buf += split;
+ todo -= split;
+ idx = 0;
+ }
+ memcpy(buf, rbuf->data+idx, todo);
return len;
}
@@ -266,5 +293,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_empty);
EXPORT_SYMBOL(dvb_ringbuffer_free);
EXPORT_SYMBOL(dvb_ringbuffer_avail);
EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
+EXPORT_SYMBOL(dvb_ringbuffer_read_user);
EXPORT_SYMBOL(dvb_ringbuffer_read);
EXPORT_SYMBOL(dvb_ringbuffer_write);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index 89082626296..41f04dae69b 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -61,7 +61,7 @@ struct dvb_ringbuffer {
** *** read min. 1000, max. <bufsize> bytes ***
** avail = dvb_ringbuffer_avail(rbuf);
** if (avail >= 1000)
-** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0);
+** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
** else
** ...
**
@@ -114,8 +114,10 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
** <usermem> specifies whether <buf> resides in user space
** returns number of bytes transferred or -EFAULT
*/
-extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
- size_t len, int usermem);
+extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
+ u8 __user *buf, size_t len);
+extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
+ u8 *buf, size_t len);
/* write routines & macros */
@@ -157,8 +159,10 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
* <usermem> Set to 1 if <buf> is in userspace.
* returns Number of bytes read, or -EFAULT.
*/
+extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
+ int offset, u8 __user *buf, size_t len);
extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
- int offset, u8* buf, size_t len, int usermem);
+ int offset, u8 *buf, size_t len);
/**
* Dispose of a packet in the ring buffer.
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index f00a0eb4042..a577c0f89f6 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -76,6 +76,7 @@ config DVB_USB_DIB0700
select DVB_DIB3000MC
select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
select DVB_TUNER_DIB0070
help
Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
@@ -107,6 +108,8 @@ config DVB_USB_CXUSB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -120,6 +123,8 @@ config DVB_USB_M920X
depends on DVB_USB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
+ select DVB_TDA1004X if !DVB_FE_CUSTOMISE
help
Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
Currently, only devices with a product id of
@@ -241,3 +246,13 @@ config DVB_USB_AF9005_REMOTE
Say Y here to support the default remote control decoding for the
Afatech AF9005 based receiver.
+config DVB_USB_ANYSEE
+ tristate "Anysee DVB-T/C USB2.0 support"
+ depends on DVB_USB
+ select DVB_PLL if !DVB_FE_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ help
+ Say Y here to support the Anysee E30, Anysee E30 Plus or
+ Anysee E30 C Plus DVB USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index c6511a6c0ab..44c11e45e56 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -61,6 +61,9 @@ obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
dvb-usb-af9005-remote-objs = af9005-remote.o
obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
+dvb-usb-anysee-objs = anysee.o
+obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
+
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
new file mode 100644
index 00000000000..adfd4fc82ef
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -0,0 +1,553 @@
+/*
+ * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * 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.
+ *
+ * TODO:
+ * - add smart card reader support for Conditional Access (CA)
+ *
+ * Card reader in Anysee is nothing more than ISO 7816 card reader.
+ * There is no hardware CAM in any Anysee device sold.
+ * In my understanding it should be implemented by making own module
+ * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
+ * module registers serial interface that can be used to communicate
+ * with any ISO 7816 smart card.
+ *
+ * Any help according to implement serial smart card reader support
+ * is highly welcome!
+ */
+
+#include "anysee.h"
+#include "tda1002x.h"
+#include "mt352.h"
+#include "mt352_priv.h"
+#include "zl10353.h"
+
+/* debug */
+static int dvb_usb_anysee_debug;
+module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct mutex anysee_usb_mutex;
+
+static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
+ u8 *rbuf, u8 rlen)
+{
+ struct anysee_state *state = d->priv;
+ int act_len, ret;
+ u8 buf[64];
+
+ if (slen > sizeof(buf))
+ slen = sizeof(buf);
+ memcpy(&buf[0], sbuf, slen);
+ buf[60] = state->seq++;
+
+ if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
+ return -EAGAIN;
+
+ /* We need receive one message more after dvb_usb_generic_rw due
+ to weird transaction flow, which is 1 x send + 2 x receive. */
+ ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
+
+ if (!ret) {
+ /* receive 2nd answer */
+ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
+ d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
+ &act_len, 2000);
+ if (ret)
+ err("%s: recv bulk message failed: %d", __func__, ret);
+ else {
+ deb_xfer("<<< ");
+ debug_dump(buf, act_len, deb_xfer);
+ }
+ }
+
+ /* read request, copy returned data to return buf */
+ if (!ret && rbuf && rlen)
+ memcpy(rbuf, buf, rlen);
+
+ mutex_unlock(&anysee_usb_mutex);
+
+ return ret;
+}
+
+static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
+{
+ u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
+ int ret;
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
+ deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
+ return ret;
+}
+
+static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
+{
+ u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
+ deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
+ return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
+{
+ u8 buf[] = {CMD_GET_HW_INFO};
+ return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
+}
+
+static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
+ deb_info("%s: onoff:%02x\n", __func__, onoff);
+ return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
+{
+ u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
+ deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
+ return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
+{
+ u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
+ deb_info("%s: onoff:%02x\n", __func__, onoff);
+ return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+}
+
+static int anysee_init(struct dvb_usb_device *d)
+{
+ int ret;
+ /* LED light */
+ ret = anysee_led_ctrl(d, 0x01, 0x03);
+ if (ret)
+ return ret;
+
+ /* enable IR */
+ ret = anysee_ir_ctrl(d, 1);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+/* I2C */
+static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int ret, inc, i = 0;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ while (i < num) {
+ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+ u8 buf[6];
+ buf[0] = CMD_I2C_READ;
+ buf[1] = msg[i].addr + 1;
+ buf[2] = msg[i].buf[0];
+ buf[3] = 0x00;
+ buf[4] = 0x00;
+ buf[5] = 0x01;
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
+ msg[i+1].len);
+ inc = 2;
+ } else {
+ u8 buf[4+msg[i].len];
+ buf[0] = CMD_I2C_WRITE;
+ buf[1] = msg[i].addr;
+ buf[2] = msg[i].len;
+ buf[3] = 0x01;
+ memcpy(&buf[4], msg[i].buf, msg[i].len);
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+ inc = 1;
+ }
+ if (ret)
+ return ret;
+
+ i += inc;
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+
+ return i;
+}
+
+static u32 anysee_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm anysee_i2c_algo = {
+ .master_xfer = anysee_master_xfer,
+ .functionality = anysee_i2c_func,
+};
+
+static int anysee_mt352_demod_init(struct dvb_frontend *fe)
+{
+ static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
+ static u8 reset [] = { RESET, 0x80 };
+ static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+ static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
+ static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
+ static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+ mt352_write(fe, clock_config, sizeof(clock_config));
+ udelay(200);
+ mt352_write(fe, reset, sizeof(reset));
+ mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
+
+ mt352_write(fe, agc_cfg, sizeof(agc_cfg));
+ mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
+ mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+ return 0;
+}
+
+/* Callbacks for DVB USB */
+static struct tda10023_config anysee_tda10023_config = {
+ .demod_address = 0x1a,
+ .invert = 0,
+ .xtal = 16000000,
+ .pll_m = 11,
+ .pll_p = 3,
+ .pll_n = 1,
+ .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
+ .deltaf = 0xfeeb,
+};
+
+static struct mt352_config anysee_mt352_config = {
+ .demod_address = 0x1e,
+ .demod_init = anysee_mt352_demod_init,
+};
+
+static struct zl10353_config anysee_zl10353_config = {
+ .demod_address = 0x1e,
+ .parallel_ts = 1,
+};
+
+static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ struct anysee_state *state = adap->dev->priv;
+ u8 hw_info[3];
+ u8 io_d; /* IO port D */
+
+ /* check which hardware we have
+ We must do this call two times to get reliable values (hw bug). */
+ ret = anysee_get_hw_info(adap->dev, hw_info);
+ if (ret)
+ return ret;
+ ret = anysee_get_hw_info(adap->dev, hw_info);
+ if (ret)
+ return ret;
+
+ /* Meaning of these info bytes are guessed. */
+ info("firmware version:%d.%d.%d hardware id:%d",
+ 0, hw_info[1], hw_info[2], hw_info[0]);
+
+ ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */
+ if (ret)
+ return ret;
+ deb_info("%s: IO port D:%02x\n", __func__, io_d);
+
+ /* Select demod using trial and error method. */
+
+ /* Try to attach demodulator in following order:
+ model demod hw firmware
+ 1. E30 MT352 02 0.2.1
+ 2. E30 ZL10353 02 0.2.1
+ 3. E30 Plus ZL10353 06 0.1.0
+ 4. E30C Plus TDA10023 0a 0.1.0 rev 0.2
+ 4. E30C Plus TDA10023 0f 0.1.2 rev 0.4
+ */
+
+ /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
+ adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe != NULL) {
+ state->tuner = DVB_PLL_THOMSON_DTT7579;
+ return 0;
+ }
+
+ /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
+ adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe != NULL) {
+ state->tuner = DVB_PLL_THOMSON_DTT7579;
+ return 0;
+ }
+
+ /* connect demod on IO port D for TDA10023 & ZL10353 */
+ ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
+ if (ret)
+ return ret;
+
+ /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
+ adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe != NULL) {
+ state->tuner = DVB_PLL_THOMSON_DTT7579;
+ return 0;
+ }
+
+ /* IO port E - E30C rev 0.4 board requires this */
+ ret = anysee_write_reg(adap->dev, 0xb1, 0xa7);
+ if (ret)
+ return ret;
+
+ /* Philips TDA10023 DVB-C demod */
+ adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
+ &adap->dev->i2c_adap, 0x48);
+ if (adap->fe != NULL) {
+ state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
+ return 0;
+ }
+
+ /* return IO port D to init value for safe */
+ ret = anysee_write_reg(adap->dev, 0xb0, io_d);
+ if (ret)
+ return ret;
+
+ err("Unkown Anysee version: %02x %02x %02x. "\
+ "Please report the <linux-dvb@linuxtv.org>.",
+ hw_info[0], hw_info[1], hw_info[2]);
+
+ return -ENODEV;
+}
+
+static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ struct anysee_state *state = adap->dev->priv;
+ deb_info("%s: \n", __func__);
+
+ switch (state->tuner) {
+ case DVB_PLL_THOMSON_DTT7579:
+ /* Thomson dtt7579 (not sure) PLL inside of:
+ Samsung DNOS404ZH102A NIM
+ Samsung DNOS404ZH103A NIM */
+ dvb_attach(dvb_pll_attach, adap->fe, 0x61,
+ NULL, DVB_PLL_THOMSON_DTT7579);
+ break;
+ case DVB_PLL_SAMSUNG_DTOS403IH102A:
+ /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */
+ dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
+ &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+ break;
+ }
+
+ return 0;
+}
+
+static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 buf[] = {CMD_GET_IR_CODE};
+ struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+ u8 ircode[2];
+ int i, ret;
+
+ ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2);
+ if (ret)
+ return ret;
+
+ *event = 0;
+ *state = REMOTE_NO_KEY_PRESSED;
+
+ for (i = 0; i < d->props.rc_key_map_size; i++) {
+ if (keymap[i].custom == ircode[0] &&
+ keymap[i].data == ircode[1]) {
+ *event = keymap[i].event;
+ *state = REMOTE_KEY_PRESSED;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static struct dvb_usb_rc_key anysee_rc_keys[] = {
+ { 0x01, 0x00, KEY_0 },
+ { 0x01, 0x01, KEY_1 },
+ { 0x01, 0x02, KEY_2 },
+ { 0x01, 0x03, KEY_3 },
+ { 0x01, 0x04, KEY_4 },
+ { 0x01, 0x05, KEY_5 },
+ { 0x01, 0x06, KEY_6 },
+ { 0x01, 0x07, KEY_7 },
+ { 0x01, 0x08, KEY_8 },
+ { 0x01, 0x09, KEY_9 },
+ { 0x01, 0x0a, KEY_POWER },
+ { 0x01, 0x0b, KEY_DOCUMENTS }, /* * */
+ { 0x01, 0x19, KEY_FAVORITES },
+ { 0x01, 0x20, KEY_SLEEP },
+ { 0x01, 0x21, KEY_MODE }, /* 4:3 / 16:9 select */
+ { 0x01, 0x22, KEY_ZOOM },
+ { 0x01, 0x47, KEY_TEXT },
+ { 0x01, 0x16, KEY_TV }, /* TV / radio select */
+ { 0x01, 0x1e, KEY_LANGUAGE }, /* Second Audio Program */
+ { 0x01, 0x1a, KEY_SUBTITLE },
+ { 0x01, 0x1b, KEY_CAMERA }, /* screenshot */
+ { 0x01, 0x42, KEY_MUTE },
+ { 0x01, 0x0e, KEY_MENU },
+ { 0x01, 0x0f, KEY_EPG },
+ { 0x01, 0x17, KEY_INFO },
+ { 0x01, 0x10, KEY_EXIT },
+ { 0x01, 0x13, KEY_VOLUMEUP },
+ { 0x01, 0x12, KEY_VOLUMEDOWN },
+ { 0x01, 0x11, KEY_CHANNELUP },
+ { 0x01, 0x14, KEY_CHANNELDOWN },
+ { 0x01, 0x15, KEY_OK },
+ { 0x01, 0x1d, KEY_RED },
+ { 0x01, 0x1f, KEY_GREEN },
+ { 0x01, 0x1c, KEY_YELLOW },
+ { 0x01, 0x44, KEY_BLUE },
+ { 0x01, 0x0c, KEY_SHUFFLE }, /* snapshot */
+ { 0x01, 0x48, KEY_STOP },
+ { 0x01, 0x50, KEY_PLAY },
+ { 0x01, 0x51, KEY_PAUSE },
+ { 0x01, 0x49, KEY_RECORD },
+ { 0x01, 0x18, KEY_PREVIOUS }, /* |<< */
+ { 0x01, 0x0d, KEY_NEXT }, /* >>| */
+ { 0x01, 0x24, KEY_PROG1 }, /* F1 */
+ { 0x01, 0x25, KEY_PROG2 }, /* F2 */
+};
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties anysee_properties;
+
+static int anysee_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct dvb_usb_device *d;
+ struct usb_host_interface *alt;
+ int ret;
+
+ mutex_init(&anysee_usb_mutex);
+
+ /* There is one interface with two alternate settings.
+ Alternate setting 0 is for bulk transfer.
+ Alternate setting 1 is for isochronous transfer.
+ We use bulk transfer (alternate setting 0). */
+ if (intf->num_altsetting < 1)
+ return -ENODEV;
+
+ ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
+ adapter_nr);
+ if (ret)
+ return ret;
+
+ alt = usb_altnum_to_altsetting(intf, 0);
+ if (alt == NULL) {
+ deb_info("%s: no alt found!\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
+ alt->desc.bAlternateSetting);
+ if (ret)
+ return ret;
+
+ if (d)
+ ret = anysee_init(d);
+
+ return ret;
+}
+
+static struct usb_device_id anysee_table [] = {
+ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
+ { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, anysee_table);
+
+static struct dvb_usb_device_properties anysee_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+
+ .size_of_priv = sizeof(struct anysee_state),
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .streaming_ctrl = anysee_streaming_ctrl,
+ .frontend_attach = anysee_frontend_attach,
+ .tuner_attach = anysee_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+ }
+ },
+
+ .rc_key_map = anysee_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(anysee_rc_keys),
+ .rc_query = anysee_rc_query,
+ .rc_interval = 200, /* windows driver uses 500ms */
+
+ .i2c_algo = &anysee_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 1,
+
+ .num_device_descs = 1,
+ .devices = {
+ {
+ .name = "Anysee DVB USB2.0",
+ .cold_ids = {NULL},
+ .warm_ids = {&anysee_table[0],
+ &anysee_table[1], NULL},
+ },
+ }
+};
+
+static struct usb_driver anysee_driver = {
+ .name = "dvb_usb_anysee",
+ .probe = anysee_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = anysee_table,
+};
+
+/* module stuff */
+static int __init anysee_module_init(void)
+{
+ int ret;
+
+ ret = usb_register(&anysee_driver);
+ if (ret)
+ err("%s: usb_register failed. Error number %d", __func__, ret);
+
+ return ret;
+}
+
+static void __exit anysee_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&anysee_driver);
+}
+
+module_init(anysee_module_init);
+module_exit(anysee_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h
new file mode 100644
index 00000000000..7ca01ff6e13
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/anysee.h
@@ -0,0 +1,304 @@
+/*
+ * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
+ *
+ * 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.
+ *
+ * TODO:
+ * - add smart card reader support for Conditional Access (CA)
+ *
+ * Card reader in Anysee is nothing more than ISO 7816 card reader.
+ * There is no hardware CAM in any Anysee device sold.
+ * In my understanding it should be implemented by making own module
+ * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
+ * module registers serial interface that can be used to communicate
+ * with any ISO 7816 smart card.
+ *
+ * Any help according to implement serial smart card reader support
+ * is highly welcome!
+ */
+
+#ifndef _DVB_USB_ANYSEE_H_
+#define _DVB_USB_ANYSEE_H_
+
+#define DVB_USB_LOG_PREFIX "anysee"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
+#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args)
+#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args)
+#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args)
+#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args)
+
+enum cmd {
+ CMD_I2C_READ = 0x33,
+ CMD_I2C_WRITE = 0x31,
+ CMD_REG_READ = 0xb0,
+ CMD_REG_WRITE = 0xb1,
+ CMD_STREAMING_CTRL = 0x12,
+ CMD_LED_AND_IR_CTRL = 0x16,
+ CMD_GET_IR_CODE = 0x41,
+ CMD_GET_HW_INFO = 0x19,
+ CMD_SMARTCARD = 0x34,
+};
+
+struct anysee_state {
+ u8 tuner;
+ u8 seq;
+};
+
+#endif
+
+/***************************************************************************
+ * USB API description (reverse engineered)
+ ***************************************************************************
+
+Transaction flow:
+=================
+BULK[00001] >>> REQUEST PACKET 64 bytes
+BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
+BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
+
+General reply packet(s) are always used if not own reply defined.
+
+============================================================================
+| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
+============================================================================
+| 00 | reply data (if any) from previous transaction
+| | Just same reply packet as returned during previous transaction.
+| | Needed only if reply is missed in previous transaction.
+| | Just skip normally.
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
+============================================================================
+| 00 | reply data (if any)
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | I2C WRITE REQUEST PACKET
+============================================================================
+| 00 | 0x31 I2C write command
+----------------------------------------------------------------------------
+| 01 | i2c address
+----------------------------------------------------------------------------
+| 02 | data length
+| | 0x02 (for typical I2C reg / val pair)
+----------------------------------------------------------------------------
+| 03 | 0x01
+----------------------------------------------------------------------------
+| 04- | data
+----------------------------------------------------------------------------
+| -59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | I2C READ REQUEST PACKET
+============================================================================
+| 00 | 0x33 I2C read command
+----------------------------------------------------------------------------
+| 01 | i2c address + 1
+----------------------------------------------------------------------------
+| 02 | register
+----------------------------------------------------------------------------
+| 03 | 0x00
+----------------------------------------------------------------------------
+| 04 | 0x00
+----------------------------------------------------------------------------
+| 05 | 0x01
+----------------------------------------------------------------------------
+| 06-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
+============================================================================
+| 00 | 0xb1 register write command
+----------------------------------------------------------------------------
+| 01-02 | register
+----------------------------------------------------------------------------
+| 03 | 0x01
+----------------------------------------------------------------------------
+| 04 | value
+----------------------------------------------------------------------------
+| 05-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
+============================================================================
+| 00 | 0xb0 register read command
+----------------------------------------------------------------------------
+| 01-02 | register
+----------------------------------------------------------------------------
+| 03 | 0x01
+----------------------------------------------------------------------------
+| 04-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | LED CONTROL REQUEST PACKET
+============================================================================
+| 00 | 0x16 LED and IR control command
+----------------------------------------------------------------------------
+| 01 | 0x01 (LED)
+----------------------------------------------------------------------------
+| 03 | 0x00 blink
+| | 0x01 lights continuously
+----------------------------------------------------------------------------
+| 04 | blink interval
+| | 0x00 fastest (looks like LED lights continuously)
+| | 0xff slowest
+----------------------------------------------------------------------------
+| 05-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | IR CONTROL REQUEST PACKET
+============================================================================
+| 00 | 0x16 LED and IR control command
+----------------------------------------------------------------------------
+| 01 | 0x02 (IR)
+----------------------------------------------------------------------------
+| 03 | 0x00 IR disabled
+| | 0x01 IR enabled
+----------------------------------------------------------------------------
+| 04-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | STREAMING CONTROL REQUEST PACKET
+============================================================================
+| 00 | 0x12 streaming control command
+----------------------------------------------------------------------------
+| 01 | 0x00 streaming disabled
+| | 0x01 streaming enabled
+----------------------------------------------------------------------------
+| 02 | 0x00
+----------------------------------------------------------------------------
+| 03-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | REMOTE CONTROL REQUEST PACKET
+============================================================================
+| 00 | 0x41 remote control command
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | REMOTE CONTROL REPLY PACKET
+============================================================================
+| 00 | 0x00 code not received
+| | 0x01 code received
+----------------------------------------------------------------------------
+| 01 | remote control code
+----------------------------------------------------------------------------
+| 02-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GET HARDWARE INFO REQUEST PACKET
+============================================================================
+| 00 | 0x19 get hardware info command
+----------------------------------------------------------------------------
+| 01-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | GET HARDWARE INFO REPLY PACKET
+============================================================================
+| 00 | hardware id
+----------------------------------------------------------------------------
+| 01-02 | firmware version
+----------------------------------------------------------------------------
+| 03-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+============================================================================
+| 00-63 | SMART CARD READER PACKET
+============================================================================
+| 00 | 0x34 smart card reader command
+----------------------------------------------------------------------------
+| xx |
+----------------------------------------------------------------------------
+| xx-59 | don't care
+----------------------------------------------------------------------------
+| 60 | packet sequence number
+----------------------------------------------------------------------------
+| 61-63 | don't care
+----------------------------------------------------------------------------
+
+*/
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c
index 2ccb90fa60c..eb34cc3894e 100644
--- a/drivers/media/dvb/dvb-usb/au6610.c
+++ b/drivers/media/dvb/dvb-usb/au6610.c
@@ -1,24 +1,31 @@
-/* DVB USB compliant linux driver for Sigmatek DVB-110 DVB-T USB2.0 receiver
+/*
+ * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
*
* Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
*
- * 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, version 2.
+ * 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.
*
- * see Documentation/dvb/README.dvb-usb for more information
+ * 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 "au6610.h"
-
#include "zl10353.h"
#include "qt1010.h"
/* debug */
static int dvb_usb_au6610_debug;
module_param_named(debug, dvb_usb_au6610_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
-
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
@@ -42,9 +49,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
}
ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
- USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, usb_buf,
- sizeof(usb_buf), AU6610_USB_TIMEOUT);
-
+ USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
+ usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT);
if (ret < 0)
return ret;
@@ -116,15 +122,6 @@ static struct i2c_algorithm au6610_i2c_algo = {
};
/* Callbacks for DVB USB */
-static int au6610_identify_state(struct usb_device *udev,
- struct dvb_usb_device_properties *props,
- struct dvb_usb_device_description **desc,
- int *cold)
-{
- *cold = 0;
- return 0;
-}
-
static struct zl10353_config au6610_zl10353_config = {
.demod_address = 0x0f,
.no_tuner = 1,
@@ -133,12 +130,12 @@ static struct zl10353_config au6610_zl10353_config = {
static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
{
- if ((adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config,
- &adap->dev->i2c_adap)) != NULL) {
- return 0;
- }
+ adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe == NULL)
+ return -ENODEV;
- return -EIO;
+ return 0;
}
static struct qt1010_config au6610_qt1010_config = {
@@ -171,7 +168,7 @@ static int au6610_probe(struct usb_interface *intf,
alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING);
if (alt == NULL) {
- deb_rc("no alt found!\n");
+ deb_info("%s: no alt found!\n", __func__);
return -ENODEV;
}
ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
@@ -181,18 +178,19 @@ static int au6610_probe(struct usb_interface *intf,
return ret;
}
-
static struct usb_device_id au6610_table [] = {
{ USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, au6610_table);
+MODULE_DEVICE_TABLE(usb, au6610_table);
static struct dvb_usb_device_properties au6610_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
.usb_ctrl = DEVICE_SPECIFIC,
- .size_of_priv = 0,
- .identify_state = au6610_identify_state,
+
+ .size_of_priv = 0,
+
.num_adapters = 1,
.adapter = {
{
@@ -206,20 +204,22 @@ static struct dvb_usb_device_properties au6610_properties = {
.u = {
.isoc = {
.framesperurb = 40,
- .framesize = 942, /* maximum packet size */
- .interval = 1.25, /* 125 us */
+ .framesize = 942,
+ .interval = 1,
}
}
},
}
},
+
.i2c_algo = &au6610_i2c_algo,
+
.num_device_descs = 1,
.devices = {
{
- "Sigmatek DVB-110 DVB-T USB2.0",
- { &au6610_table[0], NULL },
- { NULL },
+ .name = "Sigmatek DVB-110 DVB-T USB2.0",
+ .cold_ids = {NULL},
+ .warm_ids = {&au6610_table[0], NULL},
},
}
};
@@ -236,12 +236,11 @@ static int __init au6610_module_init(void)
{
int ret;
- if ((ret = usb_register(&au6610_driver))) {
+ ret = usb_register(&au6610_driver);
+ if (ret)
err("usb_register failed. Error number %d", ret);
- return ret;
- }
- return 0;
+ return ret;
}
static void __exit au6610_module_exit(void)
@@ -250,10 +249,10 @@ static void __exit au6610_module_exit(void)
usb_deregister(&au6610_driver);
}
-module_init (au6610_module_init);
-module_exit (au6610_module_exit);
+module_init(au6610_module_init);
+module_exit(au6610_module_exit);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_DESCRIPTION("Driver Sigmatek DVB-110 DVB-T USB2.0 / AU6610");
+MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h
index 4161b054c71..7849abe2c61 100644
--- a/drivers/media/dvb/dvb-usb/au6610.h
+++ b/drivers/media/dvb/dvb-usb/au6610.h
@@ -1,10 +1,30 @@
+/*
+ * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
+ *
+ * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *
+ * 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.
+ */
+
#ifndef _DVB_USB_AU6610_H_
#define _DVB_USB_AU6610_H_
#define DVB_USB_LOG_PREFIX "au6610"
#include "dvb-usb.h"
-#define deb_rc(args...) dprintk(dvb_usb_au6610_debug,0x01,args)
+#define deb_info(args...) dprintk(dvb_usb_au6610_debug, 0x01, args)
#define AU6610_REQ_I2C_WRITE 0x14
#define AU6610_REQ_I2C_READ 0x13
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 0286156704f..578afce6884 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -35,6 +35,7 @@
#include "zl10353.h"
#include "tuner-xc2028.h"
#include "tuner-simple.h"
+#include "mxl5005s.h"
/* debug */
static int dvb_usb_cxusb_debug;
@@ -43,9 +44,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_ST
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args)
-#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \
- dprintk(dvb_usb_cxusb_debug,0x01,args)
+#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
+#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
static int cxusb_ctrl_msg(struct dvb_usb_device *d,
u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
@@ -202,6 +202,46 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
}
+static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ int ret;
+ if (!onoff)
+ return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
+ if (d->state == DVB_USB_STATE_INIT &&
+ usb_set_interface(d->udev, 0, 0) < 0)
+ err("set interface failed");
+ do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
+ !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
+ !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
+ if (!ret) {
+ /* FIXME: We don't know why, but we need to configure the
+ * lgdt3303 with the register settings below on resume */
+ int i;
+ u8 buf, bufs[] = {
+ 0x0e, 0x2, 0x00, 0x7f,
+ 0x0e, 0x2, 0x02, 0xfe,
+ 0x0e, 0x2, 0x02, 0x01,
+ 0x0e, 0x2, 0x00, 0x03,
+ 0x0e, 0x2, 0x0d, 0x40,
+ 0x0e, 0x2, 0x0e, 0x87,
+ 0x0e, 0x2, 0x0f, 0x8e,
+ 0x0e, 0x2, 0x10, 0x01,
+ 0x0e, 0x2, 0x14, 0xd7,
+ 0x0e, 0x2, 0x47, 0x88,
+ };
+ msleep(20);
+ for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
+ ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
+ bufs+i, 4, &buf, 1);
+ if (ret)
+ break;
+ if (buf != 0x8)
+ return -EREMOTEIO;
+ }
+ }
+ return ret;
+}
+
static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 b = 0;
@@ -233,6 +273,16 @@ static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return 0;
}
+static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+ if (onoff)
+ cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
+ else
+ cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
+ NULL, 0, NULL, 0);
+ return 0;
+}
+
static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
@@ -423,6 +473,12 @@ static struct lgdt330x_config cxusb_lgdt3303_config = {
.demod_chip = LGDT3303,
};
+static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
+ .demod_address = 0x0e,
+ .demod_chip = LGDT3303,
+ .clock_polarity_flip = 2,
+};
+
static struct mt352_config cxusb_dee1601_config = {
.demod_address = 0x0f,
.demod_init = cxusb_dee1601_demod_init,
@@ -453,6 +509,24 @@ static struct mt352_config cxusb_mt352_xc3028_config = {
.demod_init = cxusb_mt352_demod_init,
};
+/* FIXME: needs tweaking */
+static struct mxl5005s_config aver_a868r_tuner = {
+ .i2c_address = 0x63,
+ .if_freq = 6000000UL,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_C,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
+};
+
/* Callbacks for DVB USB */
static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
{
@@ -533,6 +607,13 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
return 0;
}
+static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ dvb_attach(mxl5005s_attach, adap->fe,
+ &adap->dev->i2c_adap, &aver_a868r_tuner);
+ return 0;
+}
+
static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
{
u8 b;
@@ -562,6 +643,16 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
return -EIO;
}
+static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe != NULL)
+ return 0;
+
+ return -EIO;
+}
+
static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
{
/* used in both lgz201 and th7579 */
@@ -736,6 +827,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
+static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
static int cxusb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -756,7 +848,10 @@ static int cxusb_probe(struct usb_interface *intf,
THIS_MODULE, NULL, adapter_nr) ||
0 == dvb_usb_device_init(intf,
&cxusb_bluebird_nano2_needsfirmware_properties,
- THIS_MODULE, NULL, adapter_nr))
+ THIS_MODULE, NULL, adapter_nr) ||
+ 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
+ THIS_MODULE, NULL, adapter_nr) ||
+ 0)
return 0;
return -EINVAL;
@@ -779,6 +874,7 @@ static struct usb_device_id cxusb_table [] = {
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
{} /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1182,6 +1278,48 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
}
};
+static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .streaming_ctrl = cxusb_aver_streaming_ctrl,
+ .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
+ .tuner_attach = cxusb_mxl5003s_tuner_attach,
+ /* parameter for the MPEG2-data transfer */
+ .stream = {
+ .type = USB_BULK,
+ .count = 5,
+ .endpoint = 0x04,
+ .u = {
+ .bulk = {
+ .buffersize = 8192,
+ }
+ }
+ },
+
+ },
+ },
+ .power_ctrl = cxusb_aver_power_ctrl,
+
+ .i2c_algo = &cxusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ .num_device_descs = 1,
+ .devices = {
+ { "AVerMedia AVerTVHD Volar (A868R)",
+ { NULL },
+ { &cxusb_table[16], NULL },
+ },
+ }
+};
+
static struct usb_driver cxusb_driver = {
.name = "dvb_usb_cxusb",
.probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 4768a2c3551..1a51eafd31b 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -20,6 +20,9 @@
#define CMD_STREAMING_ON 0x36
#define CMD_STREAMING_OFF 0x37
+#define CMD_AVER_STREAM_ON 0x18
+#define CMD_AVER_STREAM_OFF 0x19
+
#define CMD_GET_IR_CODE 0x47
#define CMD_ANALOG 0x50
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index c4d40fe01d5..3dd20bfbed3 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1117,6 +1117,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
{ USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1372,7 +1373,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
- .num_device_descs = 2,
+ .num_device_descs = 3,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@@ -1381,6 +1382,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Pinnacle PCTV Dual DVB-T Diversity Stick",
{ &dib0700_usb_id_table[18], NULL },
{ NULL },
+ },
+ { "Hauppauge Nova-TD Stick (52009)",
+ { &dib0700_usb_id_table[35], NULL },
+ { NULL },
}
}
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 23428cd3075..326f7608954 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -20,11 +20,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
}
strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
-#else
d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
-#endif
d->i2c_adap.algo = d->props.i2c_algo;
d->i2c_adap.algo_data = NULL;
d->i2c_adap.dev.parent = &d->udev->dev;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 34245d1b7dd..e5238b31e94 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -14,6 +14,7 @@
#define USB_VID_AFATECH 0x15a4
#define USB_VID_ALCOR_MICRO 0x058f
#define USB_VID_ALINK 0x05e3
+#define USB_VID_AMT 0x1c73
#define USB_VID_ANCHOR 0x0547
#define USB_VID_ANSONIC 0x10b9
#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
@@ -57,6 +58,7 @@
#define USB_PID_AFATECH_AF9005 0x9020
#define USB_VID_ALINK_DTU 0xf170
#define USB_PID_ANSONIC_DVBT_USB 0x6000
+#define USB_PID_ANYSEE 0x861f
#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
@@ -132,9 +134,15 @@
#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
#define USB_PID_HAUPPAUGE_MYTV_T 0x7080
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
+#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200
#define USB_PID_AVERMEDIA_EXPRESS 0xb568
#define USB_PID_AVERMEDIA_VOLAR 0xa807
#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
+#define USB_PID_AVERMEDIA_VOLAR_A868R 0xa868
+#define USB_PID_AVERMEDIA_MCE_USB_M038 0x1228
+#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039
+#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039
+#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c
index 037f7ffb47b..6f596ed4176 100644
--- a/drivers/media/dvb/dvb-usb/gl861.c
+++ b/drivers/media/dvb/dvb-usb/gl861.c
@@ -1,8 +1,8 @@
/* DVB USB compliant linux driver for GL861 USB2.0 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, version 2.
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, version 2.
*
* see Documentation/dvb/README.dvb-usb for more information
*/
@@ -13,9 +13,9 @@
/* debug */
static int dvb_usb_gl861_debug;
-module_param_named(debug,dvb_usb_gl861_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
-
+module_param_named(debug, dvb_usb_gl861_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))."
+ DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
@@ -70,7 +70,7 @@ static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
/* write/read request */
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
- msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
+ msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
break;
i++;
} else
@@ -102,12 +102,13 @@ static struct zl10353_config gl861_zl10353_config = {
static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
{
- if ((adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
- &adap->dev->i2c_adap)) != NULL) {
- return 0;
- }
- return -EIO;
+ adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe == NULL)
+ return -EIO;
+
+ return 0;
}
static struct qt1010_config gl861_qt1010_config = {
@@ -156,7 +157,7 @@ static struct usb_device_id gl861_table [] = {
{ USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) },
{ } /* Terminating entry */
};
-MODULE_DEVICE_TABLE (usb, gl861_table);
+MODULE_DEVICE_TABLE(usb, gl861_table);
static struct dvb_usb_device_properties gl861_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
@@ -180,7 +181,7 @@ static struct dvb_usb_device_properties gl861_properties = {
}
}
},
- }},
+ } },
.i2c_algo = &gl861_i2c_algo,
.num_device_descs = 2,
@@ -210,12 +211,11 @@ static int __init gl861_module_init(void)
{
int ret;
- if ((ret = usb_register(&gl861_driver))) {
+ ret = usb_register(&gl861_driver);
+ if (ret)
err("usb_register failed. Error number %d", ret);
- return ret;
- }
- return 0;
+ return ret;
}
static void __exit gl861_module_exit(void)
@@ -224,8 +224,8 @@ static void __exit gl861_module_exit(void)
usb_deregister(&gl861_driver);
}
-module_init (gl861_module_init);
-module_exit (gl861_module_exit);
+module_init(gl861_module_init);
+module_exit(gl861_module_exit);
MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/dvb/dvb-usb/gl861.h
index 72a51afd5ee..c54855e2c23 100644
--- a/drivers/media/dvb/dvb-usb/gl861.h
+++ b/drivers/media/dvb/dvb-usb/gl861.h
@@ -4,7 +4,7 @@
#define DVB_USB_LOG_PREFIX "gl861"
#include "dvb-usb.h"
-#define deb_rc(args...) dprintk(dvb_usb_gl861_debug,0x01,args)
+#define deb_rc(args...) dprintk(dvb_usb_gl861_debug, 0x01, args)
#define GL861_WRITE 0x40
#define GL861_READ 0xc0
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index 03900d241a7..f7b71657f0f 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
-#include "dvb-pll.h"
#include "au8522.h"
struct au8522_state {
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index a054894ff48..ea058153ebf 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -343,6 +343,52 @@ static struct dvb_pll_desc dvb_pll_opera1 = {
}
};
+static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf,
+ const struct dvb_frontend_parameters *params)
+{
+ struct dvb_pll_priv *priv = fe->tuner_priv;
+ struct i2c_msg msg = {
+ .addr = priv->pll_i2c_address,
+ .flags = 0,
+ .buf = buf,
+ .len = 4
+ };
+ int result;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ result = i2c_transfer(priv->i2c, &msg, 1);
+ if (result != 1)
+ printk(KERN_ERR "%s: i2c_transfer failed:%d",
+ __func__, result);
+
+ buf[2] = 0x9e;
+ buf[3] = 0x90;
+
+ return;
+}
+
+/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
+static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
+ .name = "Samsung DTOS403IH102A",
+ .min = 44250000,
+ .max = 858000000,
+ .iffreq = 36125000,
+ .count = 8,
+ .set = samsung_dtos403ih102a_set,
+ .entries = {
+ { 135000000, 62500, 0xbe, 0x01 },
+ { 177000000, 62500, 0xf6, 0x01 },
+ { 370000000, 62500, 0xbe, 0x02 },
+ { 450000000, 62500, 0xf6, 0x02 },
+ { 466000000, 62500, 0xfe, 0x02 },
+ { 538000000, 62500, 0xbe, 0x08 },
+ { 826000000, 62500, 0xf6, 0x08 },
+ { 999999999, 62500, 0xfe, 0x08 },
+ }
+};
+
/* ----------------------------------------------------------- */
static struct dvb_pll_desc *pll_list[] = {
@@ -360,6 +406,7 @@ static struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
[DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
[DVB_PLL_OPERA1] = &dvb_pll_opera1,
+ [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
};
/* ----------------------------------------------------------- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 872ca29e7cf..05239f579cc 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -22,6 +22,7 @@
#define DVB_PLL_SAMSUNG_TBMV 11
#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
#define DVB_PLL_OPERA1 13
+#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
/**
* Attach a dvb-pll to the supplied frontend structure.
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index f0195c8272f..056387b41a8 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -226,11 +226,16 @@ static int lgdt330x_init(struct dvb_frontend* fe)
0x4c, 0x14
};
- static u8 flip_lgdt3303_init_data[] = {
+ static u8 flip_1_lgdt3303_init_data[] = {
0x4c, 0x14,
0x87, 0xf3
};
+ static u8 flip_2_lgdt3303_init_data[] = {
+ 0x4c, 0x14,
+ 0x87, 0xda
+ };
+
struct lgdt330x_state* state = fe->demodulator_priv;
char *chip_name;
int err;
@@ -243,10 +248,19 @@ static int lgdt330x_init(struct dvb_frontend* fe)
break;
case LGDT3303:
chip_name = "LGDT3303";
- if (state->config->clock_polarity_flip) {
- err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
- sizeof(flip_lgdt3303_init_data));
- } else {
+ switch (state->config->clock_polarity_flip) {
+ case 2:
+ err = i2c_write_demod_bytes(state,
+ flip_2_lgdt3303_init_data,
+ sizeof(flip_2_lgdt3303_init_data));
+ break;
+ case 1:
+ err = i2c_write_demod_bytes(state,
+ flip_1_lgdt3303_init_data,
+ sizeof(flip_1_lgdt3303_init_data));
+ break;
+ case 0:
+ default:
err = i2c_write_demod_bytes(state, lgdt3303_init_data,
sizeof(lgdt3303_init_data));
}
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index b999ec424ff..5ddb2dca305 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
-#include "dvb-pll.h"
#include "s5h1409.h"
struct s5h1409_state {
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index eb5bfc99d4e..cff360ce1ba 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
-#include "dvb-pll.h"
#include "s5h1411.h"
struct s5h1411_state {
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
index c6ff5b82ff8..a3c34eecdee 100644
--- a/drivers/media/dvb/frontends/tda10023.c
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -38,75 +38,29 @@
#include "dvb_frontend.h"
#include "tda1002x.h"
+#define REG0_INIT_VAL 0x23
struct tda10023_state {
struct i2c_adapter* i2c;
/* configuration settings */
- const struct tda1002x_config* config;
+ const struct tda10023_config *config;
struct dvb_frontend frontend;
u8 pwm;
u8 reg0;
-};
+ /* clock settings */
+ u32 xtal;
+ u8 pll_m;
+ u8 pll_p;
+ u8 pll_n;
+ u32 sysclk;
+};
#define dprintk(x...)
static int verbose;
-#define XTAL 28920000UL
-#define PLL_M 8UL
-#define PLL_P 4UL
-#define PLL_N 1UL
-#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
-
-static u8 tda10023_inittab[]={
- // reg mask val
- 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
- 0xff,0x64,0x00, // Sleep 100ms
- 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
- 0xff,0x64,0x00, // Sleep 100ms
- 0x28,0xff,PLL_M-1, // PLL1 M=8
- 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
- 0x00,0xff,0x23, // GPR FSAMPLING=1
- 0x2a,0xff,0x08, // PLL3 PSACLK=1
- 0xff,0x64,0x00, // Sleep 100ms
- 0x1f,0xff,0x00, // RESET
- 0xff,0x64,0x00, // Sleep 100ms
- 0xe6,0x0c,0x04, // RSCFG_IND
- 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
-
- 0x0e,0xff,0x82, // GAIN1
- 0x03,0x08,0x08, // CLKCONF DYN=1
- 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
- 0x01,0xff,0x30, // AGCREF
- 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
- 0x1b,0xff,0xc8, // ADC TWOS=1
- 0x3b,0xff,0xff, // IFMAX
- 0x3c,0xff,0x00, // IFMIN
- 0x34,0xff,0x00, // PWMREF
- 0x35,0xff,0xff, // TUNMAX
- 0x36,0xff,0x00, // TUNMIN
- 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
- 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
- 0x37,0xff,0xf6, // DELTAF_LSB
- 0x38,0xff,0xff, // DELTAF_MSB
- 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
- 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
- 0x04,0x10,0x00, // SWRAMP=1
- 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
- 0x2b,0x01,0xa1, // INTS1
- 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
- 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
- 0xc4,0xff,0x00,
- 0xc3,0x30,0x00,
- 0xb5,0xff,0x19, // ERAGC_THD
- 0x00,0x03,0x01, // GPR, CLBS soft reset
- 0x00,0x03,0x03, // GPR, CLBS soft reset
- 0xff,0x64,0x00, // Sleep 100ms
- 0xff,0xff,0xff
-};
-
static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
{
u8 b0 [] = { reg };
@@ -219,30 +173,34 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
s16 SFIL=0;
u16 NDEC = 0;
- if (sr < (u32)(SYSCLK/98.40)) {
+ /* avoid floating point operations multiplying syscloc and divider
+ by 10 */
+ u32 sysclk_x_10 = state->sysclk * 10;
+
+ if (sr < (u32)(sysclk_x_10/984)) {
NDEC=3;
SFIL=1;
- } else if (sr<(u32)(SYSCLK/64.0)) {
+ } else if (sr < (u32)(sysclk_x_10/640)) {
NDEC=3;
SFIL=0;
- } else if (sr<(u32)(SYSCLK/49.2)) {
+ } else if (sr < (u32)(sysclk_x_10/492)) {
NDEC=2;
SFIL=1;
- } else if (sr<(u32)(SYSCLK/32.0)) {
+ } else if (sr < (u32)(sysclk_x_10/320)) {
NDEC=2;
SFIL=0;
- } else if (sr<(u32)(SYSCLK/24.6)) {
+ } else if (sr < (u32)(sysclk_x_10/246)) {
NDEC=1;
SFIL=1;
- } else if (sr<(u32)(SYSCLK/16.0)) {
+ } else if (sr < (u32)(sysclk_x_10/160)) {
NDEC=1;
SFIL=0;
- } else if (sr<(u32)(SYSCLK/12.3)) {
+ } else if (sr < (u32)(sysclk_x_10/123)) {
NDEC=0;
SFIL=1;
}
- BDRI=SYSCLK*16;
+ BDRI = (state->sysclk)*16;
BDRI>>=NDEC;
BDRI +=sr/2;
BDRI /=sr;
@@ -255,11 +213,12 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
BDRX=1<<(24+NDEC);
BDRX*=sr;
- do_div(BDRX,SYSCLK); // BDRX/=SYSCLK;
+ do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
BDR=(s32)BDRX;
}
-// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC);
+ dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
+ sr, BDR, BDRI, NDEC);
tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
tda10023_writereg (state, 0x0a, BDR&255);
tda10023_writereg (state, 0x0b, (BDR>>8)&255);
@@ -272,8 +231,67 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
static int tda10023_init (struct dvb_frontend *fe)
{
struct tda10023_state* state = fe->demodulator_priv;
+ u8 tda10023_inittab[] = {
+/* reg mask val */
+/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */
+/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */
+/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+ /* PLL1 */
+/* 012 */ 0x28, 0xff, (state->pll_m-1),
+ /* PLL2 */
+/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
+ /* GPR FSAMPLING=1 */
+/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
+/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */
+/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 027 */ 0x1f, 0xff, 0x00, /* RESET */
+/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */
+/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */
+
+/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */
+/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */
+/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
+ PPWMTUN=0 PPWMIF=0 */
+/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */
+/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */
+/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */
+/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */
+/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */
+/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */
+/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */
+/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */
+/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
+/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */
+/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */
+/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */
+/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */
+/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
+/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */
+/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /*
+ INTP1 POCLKP=1 FEL=1 MFS=0 */
+/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */
+/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
+/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */
+/* 105 */ 0xc4, 0xff, 0x00,
+/* 108 */ 0xc3, 0x30, 0x00,
+/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */
+/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */
+/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */
+/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 123 */ 0xff, 0xff, 0xff
+};
+ dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
+
+ /* override default values if set in config */
+ if (state->config->deltaf) {
+ tda10023_inittab[80] = (state->config->deltaf & 0xff);
+ tda10023_inittab[83] = (state->config->deltaf >> 8);
+ }
- dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num);
+ if (state->config->output_mode)
+ tda10023_inittab[95] = state->config->output_mode;
tda10023_writetab(state, tda10023_inittab);
@@ -460,12 +478,11 @@ static void tda10023_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops tda10023_ops;
-struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
- struct i2c_adapter* i2c,
+struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
+ struct i2c_adapter *i2c,
u8 pwm)
{
struct tda10023_state* state = NULL;
- int i;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
@@ -474,22 +491,40 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
/* setup the state */
state->config = config;
state->i2c = i2c;
- memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
- state->pwm = pwm;
- for (i=0; i < ARRAY_SIZE(tda10023_inittab);i+=3) {
- if (tda10023_inittab[i] == 0x00) {
- state->reg0 = tda10023_inittab[i+2];
- break;
- }
- }
- // Wakeup if in standby
+ /* wakeup if in standby */
tda10023_writereg (state, 0x00, 0x33);
/* check if the demod is there */
if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+ state->pwm = pwm;
+ state->reg0 = REG0_INIT_VAL;
+ if (state->config->xtal) {
+ state->xtal = state->config->xtal;
+ state->pll_m = state->config->pll_m;
+ state->pll_p = state->config->pll_p;
+ state->pll_n = state->config->pll_n;
+ } else {
+ /* set default values if not defined in config */
+ state->xtal = 28920000;
+ state->pll_m = 8;
+ state->pll_p = 4;
+ state->pll_n = 1;
+ }
+
+ /* calc sysclk */
+ state->sysclk = (state->xtal * state->pll_m / \
+ (state->pll_n * state->pll_p));
+
+ state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
+ state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
+
+ dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
+ __func__, state->xtal, state->pll_m, state->pll_p,
+ state->pll_n);
+
state->frontend.demodulator_priv = state;
return &state->frontend;
@@ -504,10 +539,10 @@ static struct dvb_frontend_ops tda10023_ops = {
.name = "Philips TDA10023 DVB-C",
.type = FE_QAM,
.frequency_stepsize = 62500,
- .frequency_min = 47000000,
+ .frequency_min = 47000000,
.frequency_max = 862000000,
- .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */
- .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */
+ .symbol_rate_min = 0, /* set in tda10023_attach */
+ .symbol_rate_max = 0, /* set in tda10023_attach */
.caps = 0x400 | //FE_CAN_QAM_4
FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
FE_CAN_QAM_128 | FE_CAN_QAM_256 |
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h
index 1bcc0d44b90..04d19418bf2 100644
--- a/drivers/media/dvb/frontends/tda1002x.h
+++ b/drivers/media/dvb/frontends/tda1002x.h
@@ -26,13 +26,37 @@
#include <linux/dvb/frontend.h>
-struct tda1002x_config
-{
+struct tda1002x_config {
/* the demodulator's i2c address */
u8 demod_address;
u8 invert;
};
+enum tda10023_output_mode {
+ TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0,
+ TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1,
+ TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0,
+ TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */
+};
+
+struct tda10023_config {
+ /* the demodulator's i2c address */
+ u8 demod_address;
+ u8 invert;
+
+ /* clock settings */
+ u32 xtal; /* defaults: 28920000 */
+ u8 pll_m; /* defaults: 8 */
+ u8 pll_p; /* defaults: 4 */
+ u8 pll_n; /* defaults: 1 */
+
+ /* MPEG2 TS output mode */
+ u8 output_mode;
+
+ /* input freq offset + baseband conversion type */
+ u16 deltaf;
+};
+
#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c, u8 pwm);
@@ -45,12 +69,15 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config*
}
#endif // CONFIG_DVB_TDA10021
-#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
- struct i2c_adapter* i2c, u8 pwm);
+#if defined(CONFIG_DVB_TDA10023) || \
+ (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda10023_attach(
+ const struct tda10023_config *config,
+ struct i2c_adapter *i2c, u8 pwm);
#else
-static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
- struct i2c_adapter* i2c, u8 pwm)
+static inline struct dvb_frontend *tda10023_attach(
+ const struct tda10023_config *config,
+ struct i2c_adapter *i2c, u8 pwm)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 960ed5763ae..1360403b88b 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -234,7 +234,7 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable)
static void pluto_set_dma_addr(struct pluto *pluto)
{
- pluto_writereg(pluto, REG_PCAR, cpu_to_le32(pluto->dma_addr));
+ pluto_writereg(pluto, REG_PCAR, pluto->dma_addr);
}
static int __devinit pluto_dma_map(struct pluto *pluto)
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
new file mode 100644
index 00000000000..dd863f26167
--- /dev/null
+++ b/drivers/media/dvb/siano/Kconfig
@@ -0,0 +1,26 @@
+#
+# Siano Mobile Silicon Digital TV device configuration
+#
+
+config DVB_SIANO_SMS1XXX
+ tristate "Siano SMS1XXX USB dongle support"
+ depends on DVB_CORE && USB
+ ---help---
+ Choose Y here if you have a USB dongle with a SMS1XXX chipset.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sms1xxx.
+
+config DVB_SIANO_SMS1XXX_SMS_IDS
+ bool "Enable support for Siano Mobile Silicon default USB IDs"
+ depends on DVB_SIANO_SMS1XXX
+ default y
+ ---help---
+ Choose Y here if you have a USB dongle with a SMS1XXX chipset
+ that uses Siano Mobile Silicon's default usb vid:pid.
+
+ Choose N here if you would prefer to use Siano's external driver.
+
+ Further documentation on this driver can be found on the WWW at
+ <http://www.siano-ms.com/>.
+
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
new file mode 100644
index 00000000000..ee0737af98c
--- /dev/null
+++ b/drivers/media/dvb/siano/Makefile
@@ -0,0 +1,8 @@
+sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o
+
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
+
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
+
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
new file mode 100644
index 00000000000..e7a8ac0c404
--- /dev/null
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -0,0 +1,102 @@
+/*
+ * Card-specific functions for the Siano SMS1xxx USB dongle
+ *
+ * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation;
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ * 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 "sms-cards.h"
+
+struct usb_device_id smsusb_id_table[] = {
+#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
+ { USB_DEVICE(0x187f, 0x0010),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0100),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0200),
+ .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
+ { USB_DEVICE(0x187f, 0x0201),
+ .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
+ { USB_DEVICE(0x187f, 0x0300),
+ .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
+#endif
+ { USB_DEVICE(0x2040, 0x1700),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
+ { USB_DEVICE(0x2040, 0x1800),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
+ { USB_DEVICE(0x2040, 0x1801),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
+ { USB_DEVICE(0x2040, 0x5500),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5580),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5590),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+
+static struct sms_board sms_boards[] = {
+ [SMS_BOARD_UNKNOWN] = {
+ .name = "Unknown board",
+ },
+ [SMS1XXX_BOARD_SIANO_STELLAR] = {
+ .name = "Siano Stellar Digital Receiver",
+ .type = SMS_STELLAR,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
+ },
+ [SMS1XXX_BOARD_SIANO_NOVA_A] = {
+ .name = "Siano Nova A Digital Receiver",
+ .type = SMS_NOVA_A0,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
+ },
+ [SMS1XXX_BOARD_SIANO_NOVA_B] = {
+ .name = "Siano Nova B Digital Receiver",
+ .type = SMS_NOVA_B0,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
+ },
+ [SMS1XXX_BOARD_SIANO_VEGA] = {
+ .name = "Siano Vega Digital Receiver",
+ .type = SMS_VEGA,
+ },
+ [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
+ .name = "Hauppauge Catamount",
+ .type = SMS_STELLAR,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
+ },
+ [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
+ .name = "Hauppauge Okemo-A",
+ .type = SMS_NOVA_A0,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
+ },
+ [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
+ .name = "Hauppauge Okemo-B",
+ .type = SMS_NOVA_B0,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
+ },
+ [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
+ .name = "Hauppauge WinTV-Nova-T-MiniStick",
+ .type = SMS_NOVA_B0,
+ .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw",
+ },
+};
+
+struct sms_board *sms_get_board(int id)
+{
+ BUG_ON(id >= ARRAY_SIZE(sms_boards));
+
+ return &sms_boards[id];
+}
+
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
new file mode 100644
index 00000000000..83b39bc203f
--- /dev/null
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -0,0 +1,45 @@
+/*
+ * Card-specific functions for the Siano SMS1xxx USB dongle
+ *
+ * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation;
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ * 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 __SMS_CARDS_H__
+#define __SMS_CARDS_H__
+
+#include <linux/usb.h>
+#include "smscoreapi.h"
+
+#define SMS_BOARD_UNKNOWN 0
+#define SMS1XXX_BOARD_SIANO_STELLAR 1
+#define SMS1XXX_BOARD_SIANO_NOVA_A 2
+#define SMS1XXX_BOARD_SIANO_NOVA_B 3
+#define SMS1XXX_BOARD_SIANO_VEGA 4
+#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
+#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
+#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
+#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
+
+struct sms_board {
+ enum sms_device_type_st type;
+ char *name, *fw[DEVICE_MODE_MAX];
+};
+
+struct sms_board *sms_get_board(int id);
+
+extern struct usb_device_id smsusb_id_table[];
+
+#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
new file mode 100644
index 00000000000..b4b8ed795c9
--- /dev/null
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -0,0 +1,1251 @@
+/*
+ * Siano core API module
+ *
+ * This file contains implementation for the interface to sms core component
+ *
+ * author: Anatoly Greenblat
+ *
+ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation;
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <linux/firmware.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+int sms_debug;
+module_param_named(debug, sms_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+struct smscore_device_notifyee_t {
+ struct list_head entry;
+ hotplug_t hotplug;
+};
+
+struct smscore_idlist_t {
+ struct list_head entry;
+ int id;
+ int data_type;
+};
+
+struct smscore_client_t {
+ struct list_head entry;
+ struct smscore_device_t *coredev;
+ void *context;
+ struct list_head idlist;
+ onresponse_t onresponse_handler;
+ onremove_t onremove_handler;
+};
+
+struct smscore_device_t {
+ struct list_head entry;
+
+ struct list_head clients;
+ struct list_head subclients;
+ spinlock_t clientslock;
+
+ struct list_head buffers;
+ spinlock_t bufferslock;
+ int num_buffers;
+
+ void *common_buffer;
+ int common_buffer_size;
+ dma_addr_t common_buffer_phys;
+
+ void *context;
+ struct device *device;
+
+ char devpath[32];
+ unsigned long device_flags;
+
+ setmode_t setmode_handler;
+ detectmode_t detectmode_handler;
+ sendrequest_t sendrequest_handler;
+ preload_t preload_handler;
+ postload_t postload_handler;
+
+ int mode, modes_supported;
+
+ struct completion version_ex_done, data_download_done, trigger_done;
+ struct completion init_device_done, reload_start_done, resume_done;
+
+ int board_id;
+};
+
+void smscore_set_board_id(struct smscore_device_t *core, int id)
+{
+ core->board_id = id;
+}
+
+int smscore_get_board_id(struct smscore_device_t *core)
+{
+ return core->board_id;
+}
+
+struct smscore_registry_entry_t {
+ struct list_head entry;
+ char devpath[32];
+ int mode;
+ enum sms_device_type_st type;
+};
+
+struct list_head g_smscore_notifyees;
+struct list_head g_smscore_devices;
+struct mutex g_smscore_deviceslock;
+
+struct list_head g_smscore_registry;
+struct mutex g_smscore_registrylock;
+
+static int default_mode = 4;
+
+module_param(default_mode, int, 0644);
+MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
+
+static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
+{
+ struct smscore_registry_entry_t *entry;
+ struct list_head *next;
+
+ kmutex_lock(&g_smscore_registrylock);
+ for (next = g_smscore_registry.next;
+ next != &g_smscore_registry;
+ next = next->next) {
+ entry = (struct smscore_registry_entry_t *) next;
+ if (!strcmp(entry->devpath, devpath)) {
+ kmutex_unlock(&g_smscore_registrylock);
+ return entry;
+ }
+ }
+ entry = (struct smscore_registry_entry_t *)
+ kmalloc(sizeof(struct smscore_registry_entry_t),
+ GFP_KERNEL);
+ if (entry) {
+ entry->mode = default_mode;
+ strcpy(entry->devpath, devpath);
+ list_add(&entry->entry, &g_smscore_registry);
+ } else
+ sms_err("failed to create smscore_registry.");
+ kmutex_unlock(&g_smscore_registrylock);
+ return entry;
+}
+
+int smscore_registry_getmode(char *devpath)
+{
+ struct smscore_registry_entry_t *entry;
+
+ entry = smscore_find_registry(devpath);
+ if (entry)
+ return entry->mode;
+ else
+ sms_err("No registry found.");
+
+ return default_mode;
+}
+
+static enum sms_device_type_st smscore_registry_gettype(char *devpath)
+{
+ struct smscore_registry_entry_t *entry;
+
+ entry = smscore_find_registry(devpath);
+ if (entry)
+ return entry->type;
+ else
+ sms_err("No registry found.");
+
+ return -1;
+}
+
+void smscore_registry_setmode(char *devpath, int mode)
+{
+ struct smscore_registry_entry_t *entry;
+
+ entry = smscore_find_registry(devpath);
+ if (entry)
+ entry->mode = mode;
+ else
+ sms_err("No registry found.");
+}
+
+static void smscore_registry_settype(char *devpath,
+ enum sms_device_type_st type)
+{
+ struct smscore_registry_entry_t *entry;
+
+ entry = smscore_find_registry(devpath);
+ if (entry)
+ entry->type = type;
+ else
+ sms_err("No registry found.");
+}
+
+
+static void list_add_locked(struct list_head *new, struct list_head *head,
+ spinlock_t *lock)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(lock, flags);
+
+ list_add(new, head);
+
+ spin_unlock_irqrestore(lock, flags);
+}
+
+/**
+ * register a client callback that called when device plugged in/unplugged
+ * NOTE: if devices exist callback is called immediately for each device
+ *
+ * @param hotplug callback
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_hotplug(hotplug_t hotplug)
+{
+ struct smscore_device_notifyee_t *notifyee;
+ struct list_head *next, *first;
+ int rc = 0;
+
+ kmutex_lock(&g_smscore_deviceslock);
+
+ notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
+ GFP_KERNEL);
+ if (notifyee) {
+ /* now notify callback about existing devices */
+ first = &g_smscore_devices;
+ for (next = first->next;
+ next != first && !rc;
+ next = next->next) {
+ struct smscore_device_t *coredev =
+ (struct smscore_device_t *) next;
+ rc = hotplug(coredev, coredev->device, 1);
+ }
+
+ if (rc >= 0) {
+ notifyee->hotplug = hotplug;
+ list_add(&notifyee->entry, &g_smscore_notifyees);
+ } else
+ kfree(notifyee);
+ } else
+ rc = -ENOMEM;
+
+ kmutex_unlock(&g_smscore_deviceslock);
+
+ return rc;
+}
+
+/**
+ * unregister a client callback that called when device plugged in/unplugged
+ *
+ * @param hotplug callback
+ *
+ */
+void smscore_unregister_hotplug(hotplug_t hotplug)
+{
+ struct list_head *next, *first;
+
+ kmutex_lock(&g_smscore_deviceslock);
+
+ first = &g_smscore_notifyees;
+
+ for (next = first->next; next != first;) {
+ struct smscore_device_notifyee_t *notifyee =
+ (struct smscore_device_notifyee_t *) next;
+ next = next->next;
+
+ if (notifyee->hotplug == hotplug) {
+ list_del(&notifyee->entry);
+ kfree(notifyee);
+ }
+ }
+
+ kmutex_unlock(&g_smscore_deviceslock);
+}
+
+static void smscore_notify_clients(struct smscore_device_t *coredev)
+{
+ struct smscore_client_t *client;
+
+ /* the client must call smscore_unregister_client from remove handler */
+ while (!list_empty(&coredev->clients)) {
+ client = (struct smscore_client_t *) coredev->clients.next;
+ client->onremove_handler(client->context);
+ }
+}
+
+static int smscore_notify_callbacks(struct smscore_device_t *coredev,
+ struct device *device, int arrival)
+{
+ struct list_head *next, *first;
+ int rc = 0;
+
+ /* note: must be called under g_deviceslock */
+
+ first = &g_smscore_notifyees;
+
+ for (next = first->next; next != first; next = next->next) {
+ rc = ((struct smscore_device_notifyee_t *) next)->
+ hotplug(coredev, device, arrival);
+ if (rc < 0)
+ break;
+ }
+
+ return rc;
+}
+
+static struct
+smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
+ dma_addr_t common_buffer_phys)
+{
+ struct smscore_buffer_t *cb =
+ kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
+ if (!cb) {
+ sms_info("kmalloc(...) failed");
+ return NULL;
+ }
+
+ cb->p = buffer;
+ cb->offset_in_common = buffer - (u8 *) common_buffer;
+ cb->phys = common_buffer_phys + cb->offset_in_common;
+
+ return cb;
+}
+
+/**
+ * creates coredev object for a device, prepares buffers,
+ * creates buffer mappings, notifies registered hotplugs about new device.
+ *
+ * @param params device pointer to struct with device specific parameters
+ * and handlers
+ * @param coredev pointer to a value that receives created coredev object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_device(struct smsdevice_params_t *params,
+ struct smscore_device_t **coredev)
+{
+ struct smscore_device_t *dev;
+ u8 *buffer;
+
+ dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
+ if (!dev) {
+ sms_info("kzalloc(...) failed");
+ return -ENOMEM;
+ }
+
+ /* init list entry so it could be safe in smscore_unregister_device */
+ INIT_LIST_HEAD(&dev->entry);
+
+ /* init queues */
+ INIT_LIST_HEAD(&dev->clients);
+ INIT_LIST_HEAD(&dev->buffers);
+
+ /* init locks */
+ spin_lock_init(&dev->clientslock);
+ spin_lock_init(&dev->bufferslock);
+
+ /* init completion events */
+ init_completion(&dev->version_ex_done);
+ init_completion(&dev->data_download_done);
+ init_completion(&dev->trigger_done);
+ init_completion(&dev->init_device_done);
+ init_completion(&dev->reload_start_done);
+ init_completion(&dev->resume_done);
+
+ /* alloc common buffer */
+ dev->common_buffer_size = params->buffer_size * params->num_buffers;
+ dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
+ &dev->common_buffer_phys,
+ GFP_KERNEL | GFP_DMA);
+ if (!dev->common_buffer) {
+ smscore_unregister_device(dev);
+ return -ENOMEM;
+ }
+
+ /* prepare dma buffers */
+ for (buffer = dev->common_buffer;
+ dev->num_buffers < params->num_buffers;
+ dev->num_buffers++, buffer += params->buffer_size) {
+ struct smscore_buffer_t *cb =
+ smscore_createbuffer(buffer, dev->common_buffer,
+ dev->common_buffer_phys);
+ if (!cb) {
+ smscore_unregister_device(dev);
+ return -ENOMEM;
+ }
+
+ smscore_putbuffer(dev, cb);
+ }
+
+ sms_info("allocated %d buffers", dev->num_buffers);
+
+ dev->mode = DEVICE_MODE_NONE;
+ dev->context = params->context;
+ dev->device = params->device;
+ dev->setmode_handler = params->setmode_handler;
+ dev->detectmode_handler = params->detectmode_handler;
+ dev->sendrequest_handler = params->sendrequest_handler;
+ dev->preload_handler = params->preload_handler;
+ dev->postload_handler = params->postload_handler;
+
+ dev->device_flags = params->flags;
+ strcpy(dev->devpath, params->devpath);
+
+ smscore_registry_settype(dev->devpath, params->device_type);
+
+ /* add device to devices list */
+ kmutex_lock(&g_smscore_deviceslock);
+ list_add(&dev->entry, &g_smscore_devices);
+ kmutex_unlock(&g_smscore_deviceslock);
+
+ *coredev = dev;
+
+ sms_info("device %p created", dev);
+
+ return 0;
+}
+
+/**
+ * sets initial device mode and notifies client hotplugs that device is ready
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_start_device(struct smscore_device_t *coredev)
+{
+ int rc = smscore_set_device_mode(
+ coredev, smscore_registry_getmode(coredev->devpath));
+ if (rc < 0) {
+ sms_info("set device mode faile , rc %d", rc);
+ return rc;
+ }
+
+ kmutex_lock(&g_smscore_deviceslock);
+
+ rc = smscore_notify_callbacks(coredev, coredev->device, 1);
+
+ sms_info("device %p started, rc %d", coredev, rc);
+
+ kmutex_unlock(&g_smscore_deviceslock);
+
+ return rc;
+}
+
+static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
+ void *buffer, size_t size,
+ struct completion *completion)
+{
+ int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
+ if (rc < 0) {
+ sms_info("sendrequest returned error %d", rc);
+ return rc;
+ }
+
+ return wait_for_completion_timeout(completion,
+ msecs_to_jiffies(10000)) ?
+ 0 : -ETIME;
+}
+
+static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
+ void *buffer, size_t size)
+{
+ struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
+ struct SmsMsgHdr_ST *msg;
+ u32 mem_address = firmware->StartAddress;
+ u8 *payload = firmware->Payload;
+ int rc = 0;
+
+ sms_info("loading FW to addr 0x%x size %d",
+ mem_address, firmware->Length);
+ if (coredev->preload_handler) {
+ rc = coredev->preload_handler(coredev->context);
+ if (rc < 0)
+ return rc;
+ }
+
+ /* PAGE_SIZE buffer shall be enough and dma aligned */
+ msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
+ if (!msg)
+ return -ENOMEM;
+
+ if (coredev->mode != DEVICE_MODE_NONE) {
+ sms_debug("sending reload command.");
+ SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
+ sizeof(struct SmsMsgHdr_ST));
+ rc = smscore_sendrequest_and_wait(coredev, msg,
+ msg->msgLength,
+ &coredev->reload_start_done);
+ mem_address = *(u32 *) &payload[20];
+ }
+
+ while (size && rc >= 0) {
+ struct SmsDataDownload_ST *DataMsg =
+ (struct SmsDataDownload_ST *) msg;
+ int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
+
+ SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
+ (u16)(sizeof(struct SmsMsgHdr_ST) +
+ sizeof(u32) + payload_size));
+
+ DataMsg->MemAddr = mem_address;
+ memcpy(DataMsg->Payload, payload, payload_size);
+
+ if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
+ (coredev->mode == DEVICE_MODE_NONE))
+ rc = coredev->sendrequest_handler(
+ coredev->context, DataMsg,
+ DataMsg->xMsgHeader.msgLength);
+ else
+ rc = smscore_sendrequest_and_wait(
+ coredev, DataMsg,
+ DataMsg->xMsgHeader.msgLength,
+ &coredev->data_download_done);
+
+ payload += payload_size;
+ size -= payload_size;
+ mem_address += payload_size;
+ }
+
+ if (rc >= 0) {
+ if (coredev->mode == DEVICE_MODE_NONE) {
+ struct SmsMsgData_ST *TriggerMsg =
+ (struct SmsMsgData_ST *) msg;
+
+ SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
+ sizeof(struct SmsMsgHdr_ST) +
+ sizeof(u32) * 5);
+
+ TriggerMsg->msgData[0] = firmware->StartAddress;
+ /* Entry point */
+ TriggerMsg->msgData[1] = 5; /* Priority */
+ TriggerMsg->msgData[2] = 0x200; /* Stack size */
+ TriggerMsg->msgData[3] = 0; /* Parameter */
+ TriggerMsg->msgData[4] = 4; /* Task ID */
+
+ if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
+ rc = coredev->sendrequest_handler(
+ coredev->context, TriggerMsg,
+ TriggerMsg->xMsgHeader.msgLength);
+ msleep(100);
+ } else
+ rc = smscore_sendrequest_and_wait(
+ coredev, TriggerMsg,
+ TriggerMsg->xMsgHeader.msgLength,
+ &coredev->trigger_done);
+ } else {
+ SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
+ sizeof(struct SmsMsgHdr_ST));
+
+ rc = coredev->sendrequest_handler(coredev->context,
+ msg, msg->msgLength);
+ }
+ msleep(500);
+ }
+
+ sms_debug("rc=%d, postload=%p ", rc,
+ coredev->postload_handler);
+
+ kfree(msg);
+
+ return ((rc >= 0) && coredev->postload_handler) ?
+ coredev->postload_handler(coredev->context) :
+ rc;
+}
+
+/**
+ * loads specified firmware into a buffer and calls device loadfirmware_handler
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param filename null-terminated string specifies firmware file name
+ * @param loadfirmware_handler device handler that loads firmware
+ *
+ * @return 0 on success, <0 on error.
+ */
+static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
+ char *filename,
+ loadfirmware_t loadfirmware_handler)
+{
+ int rc = -ENOENT;
+ const struct firmware *fw;
+ u8 *fw_buffer;
+
+ if (loadfirmware_handler == NULL && !(coredev->device_flags &
+ SMS_DEVICE_FAMILY2))
+ return -EINVAL;
+
+ rc = request_firmware(&fw, filename, coredev->device);
+ if (rc < 0) {
+ sms_info("failed to open \"%s\"", filename);
+ return rc;
+ }
+ sms_info("read FW %s, size=%zd", filename, fw->size);
+ fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
+ GFP_KERNEL | GFP_DMA);
+ if (fw_buffer) {
+ memcpy(fw_buffer, fw->data, fw->size);
+
+ rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+ smscore_load_firmware_family2(coredev,
+ fw_buffer,
+ fw->size) :
+ loadfirmware_handler(coredev->context,
+ fw_buffer, fw->size);
+
+ kfree(fw_buffer);
+ } else {
+ sms_info("failed to allocate firmware buffer");
+ rc = -ENOMEM;
+ }
+
+ release_firmware(fw);
+
+ return rc;
+}
+
+/**
+ * notifies all clients registered with the device, notifies hotplugs,
+ * frees all buffers and coredev object
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+void smscore_unregister_device(struct smscore_device_t *coredev)
+{
+ struct smscore_buffer_t *cb;
+ int num_buffers = 0;
+ int retry = 0;
+
+ kmutex_lock(&g_smscore_deviceslock);
+
+ smscore_notify_clients(coredev);
+ smscore_notify_callbacks(coredev, NULL, 0);
+
+ /* at this point all buffers should be back
+ * onresponse must no longer be called */
+
+ while (1) {
+ while ((cb = smscore_getbuffer(coredev))) {
+ kfree(cb);
+ num_buffers++;
+ }
+ if (num_buffers == coredev->num_buffers)
+ break;
+ if (++retry > 10) {
+ sms_info("exiting although "
+ "not all buffers released.");
+ break;
+ }
+
+ sms_info("waiting for %d buffer(s)",
+ coredev->num_buffers - num_buffers);
+ msleep(100);
+ }
+
+ sms_info("freed %d buffers", num_buffers);
+
+ if (coredev->common_buffer)
+ dma_free_coherent(NULL, coredev->common_buffer_size,
+ coredev->common_buffer,
+ coredev->common_buffer_phys);
+
+ list_del(&coredev->entry);
+ kfree(coredev);
+
+ kmutex_unlock(&g_smscore_deviceslock);
+
+ sms_info("device %p destroyed", coredev);
+}
+
+static int smscore_detect_mode(struct smscore_device_t *coredev)
+{
+ void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
+ GFP_KERNEL | GFP_DMA);
+ struct SmsMsgHdr_ST *msg =
+ (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
+ int rc;
+
+ if (!buffer)
+ return -ENOMEM;
+
+ SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
+ sizeof(struct SmsMsgHdr_ST));
+
+ rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
+ &coredev->version_ex_done);
+ if (rc == -ETIME) {
+ sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
+
+ if (wait_for_completion_timeout(&coredev->resume_done,
+ msecs_to_jiffies(5000))) {
+ rc = smscore_sendrequest_and_wait(
+ coredev, msg, msg->msgLength,
+ &coredev->version_ex_done);
+ if (rc < 0)
+ sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
+ "second try, rc %d", rc);
+ } else
+ rc = -ETIME;
+ }
+
+ kfree(buffer);
+
+ return rc;
+}
+
+static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
+ /*Stellar NOVA A0 Nova B0 VEGA*/
+ /*DVBT*/
+ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+ /*DVBH*/
+ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+ /*TDMB*/
+ {"none", "tdmb_nova_12mhz.inp", "none", "none"},
+ /*DABIP*/
+ {"none", "none", "none", "none"},
+ /*BDA*/
+ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
+ /*ISDBT*/
+ {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"},
+ /*ISDBTBDA*/
+ {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
+ /*CMMB*/
+ {"none", "none", "none", "cmmb_vega_12mhz.inp"}
+};
+
+static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
+ int mode, enum sms_device_type_st type)
+{
+ char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
+ return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
+}
+
+/**
+ * calls device handler to change mode of operation
+ * NOTE: stellar/usb may disconnect when changing mode
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param mode requested mode of operation
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
+{
+ void *buffer;
+ int rc = 0;
+ enum sms_device_type_st type;
+
+ sms_debug("set device mode to %d", mode);
+ if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
+ if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
+ sms_err("invalid mode specified %d", mode);
+ return -EINVAL;
+ }
+
+ smscore_registry_setmode(coredev->devpath, mode);
+
+ if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
+ rc = smscore_detect_mode(coredev);
+ if (rc < 0) {
+ sms_err("mode detect failed %d", rc);
+ return rc;
+ }
+ }
+
+ if (coredev->mode == mode) {
+ sms_info("device mode %d already set", mode);
+ return 0;
+ }
+
+ if (!(coredev->modes_supported & (1 << mode))) {
+ char *fw_filename;
+
+ type = smscore_registry_gettype(coredev->devpath);
+ fw_filename = sms_get_fw_name(coredev, mode, type);
+
+ rc = smscore_load_firmware_from_file(coredev,
+ fw_filename, NULL);
+ if (rc < 0) {
+ sms_warn("error %d loading firmware: %s, "
+ "trying again with default firmware",
+ rc, fw_filename);
+
+ /* try again with the default firmware */
+ fw_filename = smscore_fw_lkup[mode][type];
+ rc = smscore_load_firmware_from_file(coredev,
+ fw_filename, NULL);
+
+ if (rc < 0) {
+ sms_warn("error %d loading "
+ "firmware: %s", rc,
+ fw_filename);
+ return rc;
+ }
+ }
+ sms_log("firmware download success: %s", fw_filename);
+ } else
+ sms_info("mode %d supported by running "
+ "firmware", mode);
+
+ buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
+ SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+ if (buffer) {
+ struct SmsMsgData_ST *msg =
+ (struct SmsMsgData_ST *)
+ SMS_ALIGN_ADDRESS(buffer);
+
+ SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
+ sizeof(struct SmsMsgData_ST));
+ msg->msgData[0] = mode;
+
+ rc = smscore_sendrequest_and_wait(
+ coredev, msg, msg->xMsgHeader.msgLength,
+ &coredev->init_device_done);
+
+ kfree(buffer);
+ } else {
+ sms_err("Could not allocate buffer for "
+ "init device message.");
+ rc = -ENOMEM;
+ }
+ } else {
+ if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
+ sms_err("invalid mode specified %d", mode);
+ return -EINVAL;
+ }
+
+ smscore_registry_setmode(coredev->devpath, mode);
+
+ if (coredev->detectmode_handler)
+ coredev->detectmode_handler(coredev->context,
+ &coredev->mode);
+
+ if (coredev->mode != mode && coredev->setmode_handler)
+ rc = coredev->setmode_handler(coredev->context, mode);
+ }
+
+ if (rc >= 0) {
+ coredev->mode = mode;
+ coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
+ }
+
+ if (rc != 0)
+ sms_err("return error code %d.", rc);
+ return rc;
+}
+
+/**
+ * calls device handler to get current mode of operation
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ *
+ * @return current mode
+ */
+int smscore_get_device_mode(struct smscore_device_t *coredev)
+{
+ return coredev->mode;
+}
+
+/**
+ * find client by response id & type within the clients list.
+ * return client handle or NULL.
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param data_type client data type (SMS_DONT_CARE for all types)
+ * @param id client id (SMS_DONT_CARE for all id)
+ *
+ */
+static struct
+smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
+ int data_type, int id)
+{
+ struct smscore_client_t *client = NULL;
+ struct list_head *next, *first;
+ unsigned long flags;
+ struct list_head *firstid, *nextid;
+
+
+ spin_lock_irqsave(&coredev->clientslock, flags);
+ first = &coredev->clients;
+ for (next = first->next;
+ (next != first) && !client;
+ next = next->next) {
+ firstid = &((struct smscore_client_t *)next)->idlist;
+ for (nextid = firstid->next;
+ nextid != firstid;
+ nextid = nextid->next) {
+ if ((((struct smscore_idlist_t *)nextid)->id == id) &&
+ (((struct smscore_idlist_t *)nextid)->data_type == data_type ||
+ (((struct smscore_idlist_t *)nextid)->data_type == 0))) {
+ client = (struct smscore_client_t *) next;
+ break;
+ }
+ }
+ }
+ spin_unlock_irqrestore(&coredev->clientslock, flags);
+ return client;
+}
+
+/**
+ * find client by response id/type, call clients onresponse handler
+ * return buffer to pool on error
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param cb pointer to response buffer descriptor
+ *
+ */
+void smscore_onresponse(struct smscore_device_t *coredev,
+ struct smscore_buffer_t *cb)
+{
+ struct SmsMsgHdr_ST *phdr =
+ (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset);
+ struct smscore_client_t *client =
+ smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
+ int rc = -EBUSY;
+
+ static unsigned long last_sample_time; /* = 0; */
+ static int data_total; /* = 0; */
+ unsigned long time_now = jiffies_to_msecs(jiffies);
+
+ if (!last_sample_time)
+ last_sample_time = time_now;
+
+ if (time_now - last_sample_time > 10000) {
+ sms_debug("\ndata rate %d bytes/secs",
+ (int)((data_total * 1000) /
+ (time_now - last_sample_time)));
+
+ last_sample_time = time_now;
+ data_total = 0;
+ }
+
+ data_total += cb->size;
+ /* If no client registered for type & id,
+ * check for control client where type is not registered */
+ if (client)
+ rc = client->onresponse_handler(client->context, cb);
+
+ if (rc < 0) {
+ switch (phdr->msgType) {
+ case MSG_SMS_GET_VERSION_EX_RES:
+ {
+ struct SmsVersionRes_ST *ver =
+ (struct SmsVersionRes_ST *) phdr;
+ sms_debug("MSG_SMS_GET_VERSION_EX_RES "
+ "id %d prots 0x%x ver %d.%d",
+ ver->FirmwareId, ver->SupportedProtocols,
+ ver->RomVersionMajor, ver->RomVersionMinor);
+
+ coredev->mode = ver->FirmwareId == 255 ?
+ DEVICE_MODE_NONE : ver->FirmwareId;
+ coredev->modes_supported = ver->SupportedProtocols;
+
+ complete(&coredev->version_ex_done);
+ break;
+ }
+ case MSG_SMS_INIT_DEVICE_RES:
+ sms_debug("MSG_SMS_INIT_DEVICE_RES");
+ complete(&coredev->init_device_done);
+ break;
+ case MSG_SW_RELOAD_START_RES:
+ sms_debug("MSG_SW_RELOAD_START_RES");
+ complete(&coredev->reload_start_done);
+ break;
+ case MSG_SMS_DATA_DOWNLOAD_RES:
+ complete(&coredev->data_download_done);
+ break;
+ case MSG_SW_RELOAD_EXEC_RES:
+ sms_debug("MSG_SW_RELOAD_EXEC_RES");
+ break;
+ case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
+ sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
+ complete(&coredev->trigger_done);
+ break;
+ case MSG_SMS_SLEEP_RESUME_COMP_IND:
+ complete(&coredev->resume_done);
+ break;
+ default:
+ break;
+ }
+ smscore_putbuffer(coredev, cb);
+ }
+}
+
+/**
+ * return pointer to next free buffer descriptor from core pool
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ *
+ * @return pointer to descriptor on success, NULL on error.
+ */
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
+{
+ struct smscore_buffer_t *cb = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&coredev->bufferslock, flags);
+
+ if (!list_empty(&coredev->buffers)) {
+ cb = (struct smscore_buffer_t *) coredev->buffers.next;
+ list_del(&cb->entry);
+ }
+
+ spin_unlock_irqrestore(&coredev->bufferslock, flags);
+
+ return cb;
+}
+
+/**
+ * return buffer descriptor to a pool
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param cb pointer buffer descriptor
+ *
+ */
+void smscore_putbuffer(struct smscore_device_t *coredev,
+ struct smscore_buffer_t *cb)
+{
+ list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
+}
+
+static int smscore_validate_client(struct smscore_device_t *coredev,
+ struct smscore_client_t *client,
+ int data_type, int id)
+{
+ struct smscore_idlist_t *listentry;
+ struct smscore_client_t *registered_client;
+
+ if (!client) {
+ sms_err("bad parameter.");
+ return -EFAULT;
+ }
+ registered_client = smscore_find_client(coredev, data_type, id);
+ if (registered_client == client)
+ return 0;
+
+ if (registered_client) {
+ sms_err("The msg ID already registered to another client.");
+ return -EEXIST;
+ }
+ listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
+ if (!listentry) {
+ sms_err("Can't allocate memory for client id.");
+ return -ENOMEM;
+ }
+ listentry->id = id;
+ listentry->data_type = data_type;
+ list_add_locked(&listentry->entry, &client->idlist,
+ &coredev->clientslock);
+ return 0;
+}
+
+/**
+ * creates smsclient object, check that id is taken by another client
+ *
+ * @param coredev pointer to a coredev object from clients hotplug
+ * @param initial_id all messages with this id would be sent to this client
+ * @param data_type all messages of this type would be sent to this client
+ * @param onresponse_handler client handler that is called to
+ * process incoming messages
+ * @param onremove_handler client handler that is called when device is removed
+ * @param context client-specific context
+ * @param client pointer to a value that receives created smsclient object
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smscore_register_client(struct smscore_device_t *coredev,
+ struct smsclient_params_t *params,
+ struct smscore_client_t **client)
+{
+ struct smscore_client_t *newclient;
+ /* check that no other channel with same parameters exists */
+ if (smscore_find_client(coredev, params->data_type,
+ params->initial_id)) {
+ sms_err("Client already exist.");
+ return -EEXIST;
+ }
+
+ newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
+ if (!newclient) {
+ sms_err("Failed to allocate memory for client.");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&newclient->idlist);
+ newclient->coredev = coredev;
+ newclient->onresponse_handler = params->onresponse_handler;
+ newclient->onremove_handler = params->onremove_handler;
+ newclient->context = params->context;
+ list_add_locked(&newclient->entry, &coredev->clients,
+ &coredev->clientslock);
+ smscore_validate_client(coredev, newclient, params->data_type,
+ params->initial_id);
+ *client = newclient;
+ sms_debug("%p %d %d", params->context, params->data_type,
+ params->initial_id);
+
+ return 0;
+}
+
+/**
+ * frees smsclient object and all subclients associated with it
+ *
+ * @param client pointer to smsclient object returned by
+ * smscore_register_client
+ *
+ */
+void smscore_unregister_client(struct smscore_client_t *client)
+{
+ struct smscore_device_t *coredev = client->coredev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&coredev->clientslock, flags);
+
+
+ while (!list_empty(&client->idlist)) {
+ struct smscore_idlist_t *identry =
+ (struct smscore_idlist_t *) client->idlist.next;
+ list_del(&identry->entry);
+ kfree(identry);
+ }
+
+ sms_info("%p", client->context);
+
+ list_del(&client->entry);
+ kfree(client);
+
+ spin_unlock_irqrestore(&coredev->clientslock, flags);
+}
+
+/**
+ * verifies that source id is not taken by another client,
+ * calls device handler to send requests to the device
+ *
+ * @param client pointer to smsclient object returned by
+ * smscore_register_client
+ * @param buffer pointer to a request buffer
+ * @param size size (in bytes) of request buffer
+ *
+ * @return 0 on success, <0 on error.
+ */
+int smsclient_sendrequest(struct smscore_client_t *client,
+ void *buffer, size_t size)
+{
+ struct smscore_device_t *coredev;
+ struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
+ int rc;
+
+ if (client == NULL) {
+ sms_err("Got NULL client");
+ return -EINVAL;
+ }
+
+ coredev = client->coredev;
+
+ /* check that no other channel with same id exists */
+ if (coredev == NULL) {
+ sms_err("Got NULL coredev");
+ return -EINVAL;
+ }
+
+ rc = smscore_validate_client(client->coredev, client, 0,
+ phdr->msgSrcId);
+ if (rc < 0)
+ return rc;
+
+ return coredev->sendrequest_handler(coredev->context, buffer, size);
+}
+
+
+int smscore_module_init(void)
+{
+ int rc = 0;
+
+ INIT_LIST_HEAD(&g_smscore_notifyees);
+ INIT_LIST_HEAD(&g_smscore_devices);
+ kmutex_init(&g_smscore_deviceslock);
+
+ INIT_LIST_HEAD(&g_smscore_registry);
+ kmutex_init(&g_smscore_registrylock);
+
+ /* USB Register */
+ rc = smsusb_register();
+
+ /* DVB Register */
+ rc = smsdvb_register();
+
+ sms_debug("rc %d", rc);
+
+ return rc;
+}
+
+void smscore_module_exit(void)
+{
+
+ kmutex_lock(&g_smscore_deviceslock);
+ while (!list_empty(&g_smscore_notifyees)) {
+ struct smscore_device_notifyee_t *notifyee =
+ (struct smscore_device_notifyee_t *)
+ g_smscore_notifyees.next;
+
+ list_del(&notifyee->entry);
+ kfree(notifyee);
+ }
+ kmutex_unlock(&g_smscore_deviceslock);
+
+ kmutex_lock(&g_smscore_registrylock);
+ while (!list_empty(&g_smscore_registry)) {
+ struct smscore_registry_entry_t *entry =
+ (struct smscore_registry_entry_t *)
+ g_smscore_registry.next;
+
+ list_del(&entry->entry);
+ kfree(entry);
+ }
+ kmutex_unlock(&g_smscore_registrylock);
+
+ /* DVB UnRegister */
+ smsdvb_unregister();
+
+ /* Unregister USB */
+ smsusb_unregister();
+
+ sms_debug("");
+}
+
+module_init(smscore_module_init);
+module_exit(smscore_module_exit);
+
+MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
+MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
new file mode 100644
index 00000000000..c1f8f1dccb1
--- /dev/null
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -0,0 +1,434 @@
+/*
+ * Driver for the Siano SMS1xxx USB dongle
+ *
+ * author: Anatoly Greenblat
+ *
+ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation;
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ * 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 __smscoreapi_h__
+#define __smscoreapi_h__
+
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+#include <asm/page.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include <linux/mutex.h>
+
+#define kmutex_init(_p_) mutex_init(_p_)
+#define kmutex_lock(_p_) mutex_lock(_p_)
+#define kmutex_trylock(_p_) mutex_trylock(_p_)
+#define kmutex_unlock(_p_) mutex_unlock(_p_)
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define SMS_ALLOC_ALIGNMENT 128
+#define SMS_DMA_ALIGNMENT 16
+#define SMS_ALIGN_ADDRESS(addr) \
+ ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
+
+#define SMS_DEVICE_FAMILY2 1
+#define SMS_ROM_NO_RESPONSE 2
+#define SMS_DEVICE_NOT_READY 0x8000000
+
+enum sms_device_type_st {
+ SMS_STELLAR = 0,
+ SMS_NOVA_A0,
+ SMS_NOVA_B0,
+ SMS_VEGA,
+ SMS_NUM_OF_DEVICE_TYPES
+};
+
+struct smscore_device_t;
+struct smscore_client_t;
+struct smscore_buffer_t;
+
+typedef int (*hotplug_t)(struct smscore_device_t *coredev,
+ struct device *device, int arrival);
+
+typedef int (*setmode_t)(void *context, int mode);
+typedef void (*detectmode_t)(void *context, int *mode);
+typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
+typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
+typedef int (*preload_t)(void *context);
+typedef int (*postload_t)(void *context);
+
+typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
+typedef void (*onremove_t)(void *context);
+
+struct smscore_buffer_t {
+ /* public members, once passed to clients can be changed freely */
+ struct list_head entry;
+ int size;
+ int offset;
+
+ /* private members, read-only for clients */
+ void *p;
+ dma_addr_t phys;
+ unsigned long offset_in_common;
+};
+
+struct smsdevice_params_t {
+ struct device *device;
+
+ int buffer_size;
+ int num_buffers;
+
+ char devpath[32];
+ unsigned long flags;
+
+ setmode_t setmode_handler;
+ detectmode_t detectmode_handler;
+ sendrequest_t sendrequest_handler;
+ preload_t preload_handler;
+ postload_t postload_handler;
+
+ void *context;
+ enum sms_device_type_st device_type;
+};
+
+struct smsclient_params_t {
+ int initial_id;
+ int data_type;
+ onresponse_t onresponse_handler;
+ onremove_t onremove_handler;
+
+ void *context;
+};
+
+/* GPIO definitions for antenna frequency domain control (SMS8021) */
+#define SMS_ANTENNA_GPIO_0 1
+#define SMS_ANTENNA_GPIO_1 0
+
+#define BW_8_MHZ 0
+#define BW_7_MHZ 1
+#define BW_6_MHZ 2
+#define BW_5_MHZ 3
+#define BW_ISDBT_1SEG 4
+#define BW_ISDBT_3SEG 5
+
+#define MSG_HDR_FLAG_SPLIT_MSG 4
+
+#define MAX_GPIO_PIN_NUMBER 31
+
+#define HIF_TASK 11
+#define SMS_HOST_LIB 150
+#define DVBT_BDA_CONTROL_MSG_ID 201
+
+#define SMS_MAX_PAYLOAD_SIZE 240
+#define SMS_TUNE_TIMEOUT 500
+
+#define MSG_SMS_GPIO_CONFIG_REQ 507
+#define MSG_SMS_GPIO_CONFIG_RES 508
+#define MSG_SMS_GPIO_SET_LEVEL_REQ 509
+#define MSG_SMS_GPIO_SET_LEVEL_RES 510
+#define MSG_SMS_GPIO_GET_LEVEL_REQ 511
+#define MSG_SMS_GPIO_GET_LEVEL_RES 512
+#define MSG_SMS_RF_TUNE_REQ 561
+#define MSG_SMS_RF_TUNE_RES 562
+#define MSG_SMS_INIT_DEVICE_REQ 578
+#define MSG_SMS_INIT_DEVICE_RES 579
+#define MSG_SMS_ADD_PID_FILTER_REQ 601
+#define MSG_SMS_ADD_PID_FILTER_RES 602
+#define MSG_SMS_REMOVE_PID_FILTER_REQ 603
+#define MSG_SMS_REMOVE_PID_FILTER_RES 604
+#define MSG_SMS_DAB_CHANNEL 607
+#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
+#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
+#define MSG_SMS_GET_STATISTICS_REQ 615
+#define MSG_SMS_GET_STATISTICS_RES 616
+#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
+#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
+#define MSG_SMS_GET_STATISTICS_EX_REQ 653
+#define MSG_SMS_GET_STATISTICS_EX_RES 654
+#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
+#define MSG_SMS_DATA_DOWNLOAD_REQ 660
+#define MSG_SMS_DATA_DOWNLOAD_RES 661
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
+#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666
+#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667
+#define MSG_SMS_GET_VERSION_EX_REQ 668
+#define MSG_SMS_GET_VERSION_EX_RES 669
+#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670
+#define MSG_SMS_I2C_SET_FREQ_REQ 685
+#define MSG_SMS_GENERIC_I2C_REQ 687
+#define MSG_SMS_GENERIC_I2C_RES 688
+#define MSG_SMS_DVBT_BDA_DATA 693
+#define MSG_SW_RELOAD_REQ 697
+#define MSG_SMS_DATA_MSG 699
+#define MSG_SW_RELOAD_START_REQ 702
+#define MSG_SW_RELOAD_START_RES 703
+#define MSG_SW_RELOAD_EXEC_REQ 704
+#define MSG_SW_RELOAD_EXEC_RES 705
+#define MSG_SMS_SPI_INT_LINE_SET_REQ 710
+#define MSG_SMS_ISDBT_TUNE_REQ 776
+#define MSG_SMS_ISDBT_TUNE_RES 777
+
+#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
+ (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
+ (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
+} while (0)
+#define SMS_INIT_MSG(ptr, type, len) \
+ SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
+
+enum SMS_DEVICE_MODE {
+ DEVICE_MODE_NONE = -1,
+ DEVICE_MODE_DVBT = 0,
+ DEVICE_MODE_DVBH,
+ DEVICE_MODE_DAB_TDMB,
+ DEVICE_MODE_DAB_TDMB_DABIP,
+ DEVICE_MODE_DVBT_BDA,
+ DEVICE_MODE_ISDBT,
+ DEVICE_MODE_ISDBT_BDA,
+ DEVICE_MODE_CMMB,
+ DEVICE_MODE_RAW_TUNER,
+ DEVICE_MODE_MAX,
+};
+
+struct SmsMsgHdr_ST {
+ u16 msgType;
+ u8 msgSrcId;
+ u8 msgDstId;
+ u16 msgLength; /* Length of entire message, including header */
+ u16 msgFlags;
+};
+
+struct SmsMsgData_ST {
+ struct SmsMsgHdr_ST xMsgHeader;
+ u32 msgData[1];
+};
+
+struct SmsDataDownload_ST {
+ struct SmsMsgHdr_ST xMsgHeader;
+ u32 MemAddr;
+ u8 Payload[SMS_MAX_PAYLOAD_SIZE];
+};
+
+struct SmsVersionRes_ST {
+ struct SmsMsgHdr_ST xMsgHeader;
+
+ u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
+ u8 Step; /* 0 - Step A */
+ u8 MetalFix; /* 0 - Metal 0 */
+
+ u8 FirmwareId; /* 0xFF � ROM, otherwise the
+ * value indicated by
+ * SMSHOSTLIB_DEVICE_MODES_E */
+ u8 SupportedProtocols; /* Bitwise OR combination of
+ * supported protocols */
+
+ u8 VersionMajor;
+ u8 VersionMinor;
+ u8 VersionPatch;
+ u8 VersionFieldPatch;
+
+ u8 RomVersionMajor;
+ u8 RomVersionMinor;
+ u8 RomVersionPatch;
+ u8 RomVersionFieldPatch;
+
+ u8 TextLabel[34];
+};
+
+struct SmsFirmware_ST {
+ u32 CheckSum;
+ u32 Length;
+ u32 StartAddress;
+ u8 Payload[1];
+};
+
+struct SMSHOSTLIB_STATISTICS_ST {
+ u32 Reserved; /* Reserved */
+
+ /* Common parameters */
+ u32 IsRfLocked; /* 0 - not locked, 1 - locked */
+ u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
+ u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+
+ /* Reception quality */
+ s32 SNR; /* dB */
+ u32 BER; /* Post Viterbi BER [1E-5] */
+ u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
+ u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A,
+ * valid only for DVB-T/H */
+ u32 MFER; /* DVB-H frame error rate in percentage,
+ * 0xFFFFFFFF indicate N/A, valid only for DVB-H */
+ s32 RSSI; /* dBm */
+ s32 InBandPwr; /* In band power in dBM */
+ s32 CarrierOffset; /* Carrier Offset in bin/1024 */
+
+ /* Transmission parameters, valid only for DVB-T/H */
+ u32 Frequency; /* Frequency in Hz */
+ u32 Bandwidth; /* Bandwidth in MHz */
+ u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
+ * for DVB-T/H FFT mode carriers in Kilos */
+ u32 ModemState; /* from SMS_DvbModemState_ET */
+ u32 GuardInterval; /* Guard Interval, 1 divided by value */
+ u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */
+ u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */
+ u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */
+ u32 Constellation; /* Constellation from SMS_Constellation_ET */
+
+ /* Burst parameters, valid only for DVB-H */
+ u32 BurstSize; /* Current burst size in bytes */
+ u32 BurstDuration; /* Current burst duration in mSec */
+ u32 BurstCycleTime; /* Current burst cycle time in mSec */
+ u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec,
+ * as calculated by demodulator */
+ u32 NumOfRows; /* Number of rows in MPE table */
+ u32 NumOfPaddCols; /* Number of padding columns in MPE table */
+ u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */
+ /* Burst parameters */
+ u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
+ u32 TotalTSPackets; /* Total number of transport-stream packets */
+ u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
+ * errors after MPE RS decoding */
+ u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors
+ * after MPE RS decoding */
+ u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected
+ * by MPE RS decoding */
+
+ /* Common params */
+ u32 BERErrorCount; /* Number of errornous SYNC bits. */
+ u32 BERBitCount; /* Total number of SYNC bits. */
+
+ /* Interface information */
+ u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+
+ /* DAB/T-DMB */
+ u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
+
+ /* DVB-H TPS parameters */
+ u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+ * if set to 0xFFFFFFFF cell_id not yet recovered */
+
+};
+
+struct SmsMsgStatisticsInfo_ST {
+ u32 RequestResult;
+
+ struct SMSHOSTLIB_STATISTICS_ST Stat;
+
+ /* Split the calc of the SNR in DAB */
+ u32 Signal; /* dB */
+ u32 Noise; /* dB */
+
+};
+
+
+struct smsdvb_client_t {
+ struct list_head entry;
+
+ struct smscore_device_t *coredev;
+ struct smscore_client_t *smsclient;
+
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dvb_frontend frontend;
+
+ fe_status_t fe_status;
+ int fe_ber, fe_snr, fe_signal_strength;
+
+ struct completion tune_done, stat_done;
+
+ /* todo: save freq/band instead whole struct */
+ struct dvb_frontend_parameters fe_params;
+
+};
+
+extern void smscore_registry_setmode(char *devpath, int mode);
+extern int smscore_registry_getmode(char *devpath);
+
+extern int smscore_register_hotplug(hotplug_t hotplug);
+extern void smscore_unregister_hotplug(hotplug_t hotplug);
+
+extern int smscore_register_device(struct smsdevice_params_t *params,
+ struct smscore_device_t **coredev);
+extern void smscore_unregister_device(struct smscore_device_t *coredev);
+
+extern int smscore_start_device(struct smscore_device_t *coredev);
+extern int smscore_load_firmware(struct smscore_device_t *coredev,
+ char *filename,
+ loadfirmware_t loadfirmware_handler);
+
+extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
+extern int smscore_get_device_mode(struct smscore_device_t *coredev);
+
+extern int smscore_register_client(struct smscore_device_t *coredev,
+ struct smsclient_params_t *params,
+ struct smscore_client_t **client);
+extern void smscore_unregister_client(struct smscore_client_t *client);
+
+extern int smsclient_sendrequest(struct smscore_client_t *client,
+ void *buffer, size_t size);
+extern void smscore_onresponse(struct smscore_device_t *coredev,
+ struct smscore_buffer_t *cb);
+
+
+extern
+struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
+extern void smscore_putbuffer(struct smscore_device_t *coredev,
+ struct smscore_buffer_t *cb);
+
+void smscore_set_board_id(struct smscore_device_t *core, int id);
+int smscore_get_board_id(struct smscore_device_t *core);
+
+/* smsdvb.c */
+int smsdvb_register(void);
+void smsdvb_unregister(void);
+
+/* smsusb.c */
+int smsusb_register(void);
+void smsusb_unregister(void);
+
+/* ------------------------------------------------------------------------ */
+
+extern int sms_debug;
+
+#define DBG_INFO 1
+#define DBG_ADV 2
+
+#define sms_printk(kern, fmt, arg...) \
+ printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define dprintk(kern, lvl, fmt, arg...) do {\
+ if (sms_debug & lvl) \
+ sms_printk(kern, fmt, ##arg); } while (0)
+
+#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
+#define sms_err(fmt, arg...) \
+ sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
+#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg)
+#define sms_info(fmt, arg...) \
+ dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
+#define sms_debug(fmt, arg...) \
+ dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
+
+
+#endif /* __smscoreapi_h__ */
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
new file mode 100644
index 00000000000..6f9c1856386
--- /dev/null
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -0,0 +1,449 @@
+/*
+ * Driver for the Siano SMS1xxx USB dongle
+ *
+ * author: Anatoly Greenblat
+ *
+ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation;
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct list_head g_smsdvb_clients;
+struct mutex g_smsdvb_clientslock;
+
+static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
+{
+ struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
+ struct SmsMsgHdr_ST *phdr =
+ (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset);
+
+ switch (phdr->msgType) {
+ case MSG_SMS_DVBT_BDA_DATA:
+ dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
+ cb->size - sizeof(struct SmsMsgHdr_ST));
+ break;
+
+ case MSG_SMS_RF_TUNE_RES:
+ complete(&client->tune_done);
+ break;
+
+ case MSG_SMS_GET_STATISTICS_RES:
+ {
+ struct SmsMsgStatisticsInfo_ST *p =
+ (struct SmsMsgStatisticsInfo_ST *)(phdr + 1);
+
+ if (p->Stat.IsDemodLocked) {
+ client->fe_status = FE_HAS_SIGNAL |
+ FE_HAS_CARRIER |
+ FE_HAS_VITERBI |
+ FE_HAS_SYNC |
+ FE_HAS_LOCK;
+
+ client->fe_snr = p->Stat.SNR;
+ client->fe_ber = p->Stat.BER;
+
+ if (p->Stat.InBandPwr < -95)
+ client->fe_signal_strength = 0;
+ else if (p->Stat.InBandPwr > -29)
+ client->fe_signal_strength = 100;
+ else
+ client->fe_signal_strength =
+ (p->Stat.InBandPwr + 95) * 3 / 2;
+ } else {
+ client->fe_status = 0;
+ client->fe_snr =
+ client->fe_ber =
+ client->fe_signal_strength = 0;
+ }
+
+ complete(&client->stat_done);
+ break;
+ } }
+
+ smscore_putbuffer(client->coredev, cb);
+
+ return 0;
+}
+
+static void smsdvb_unregister_client(struct smsdvb_client_t *client)
+{
+ /* must be called under clientslock */
+
+ list_del(&client->entry);
+
+ smscore_unregister_client(client->smsclient);
+ dvb_unregister_frontend(&client->frontend);
+ dvb_dmxdev_release(&client->dmxdev);
+ dvb_dmx_release(&client->demux);
+ dvb_unregister_adapter(&client->adapter);
+ kfree(client);
+}
+
+static void smsdvb_onremove(void *context)
+{
+ kmutex_lock(&g_smsdvb_clientslock);
+
+ smsdvb_unregister_client((struct smsdvb_client_t *) context);
+
+ kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+static int smsdvb_start_feed(struct dvb_demux_feed *feed)
+{
+ struct smsdvb_client_t *client =
+ container_of(feed->demux, struct smsdvb_client_t, demux);
+ struct SmsMsgData_ST PidMsg;
+
+ sms_debug("add pid %d(%x)",
+ feed->pid, feed->pid);
+
+ PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+ PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+ PidMsg.xMsgHeader.msgFlags = 0;
+ PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ;
+ PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+ PidMsg.msgData[0] = feed->pid;
+
+ return smsclient_sendrequest(client->smsclient,
+ &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct smsdvb_client_t *client =
+ container_of(feed->demux, struct smsdvb_client_t, demux);
+ struct SmsMsgData_ST PidMsg;
+
+ sms_debug("remove pid %d(%x)",
+ feed->pid, feed->pid);
+
+ PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+ PidMsg.xMsgHeader.msgDstId = HIF_TASK;
+ PidMsg.xMsgHeader.msgFlags = 0;
+ PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ;
+ PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
+ PidMsg.msgData[0] = feed->pid;
+
+ return smsclient_sendrequest(client->smsclient,
+ &PidMsg, sizeof(PidMsg));
+}
+
+static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
+ void *buffer, size_t size,
+ struct completion *completion)
+{
+ int rc = smsclient_sendrequest(client->smsclient, buffer, size);
+ if (rc < 0)
+ return rc;
+
+ return wait_for_completion_timeout(completion,
+ msecs_to_jiffies(2000)) ?
+ 0 : -ETIME;
+}
+
+static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
+{
+ struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
+ DVBT_BDA_CONTROL_MSG_ID,
+ HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 };
+ return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+ &client->stat_done);
+}
+
+static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ int rc = smsdvb_send_statistics_request(client);
+
+ if (!rc)
+ *stat = client->fe_status;
+
+ return rc;
+}
+
+static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ int rc = smsdvb_send_statistics_request(client);
+
+ if (!rc)
+ *ber = client->fe_ber;
+
+ return rc;
+}
+
+static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ int rc = smsdvb_send_statistics_request(client);
+
+ if (!rc)
+ *strength = client->fe_signal_strength;
+
+ return rc;
+}
+
+static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ int rc = smsdvb_send_statistics_request(client);
+
+ if (!rc)
+ *snr = client->fe_snr;
+
+ return rc;
+}
+
+static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *tune)
+{
+ sms_debug("");
+
+ tune->min_delay_ms = 400;
+ tune->step_size = 250000;
+ tune->max_drift = 0;
+ return 0;
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+
+ struct {
+ struct SmsMsgHdr_ST Msg;
+ u32 Data[3];
+ } Msg;
+
+ Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+ Msg.Msg.msgDstId = HIF_TASK;
+ Msg.Msg.msgFlags = 0;
+ Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
+ Msg.Msg.msgLength = sizeof(Msg);
+ Msg.Data[0] = fep->frequency;
+ Msg.Data[2] = 12000000;
+
+ sms_debug("freq %d band %d",
+ fep->frequency, fep->u.ofdm.bandwidth);
+
+ switch (fep->u.ofdm.bandwidth) {
+ case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break;
+ case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break;
+ case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break;
+ case BANDWIDTH_AUTO: return -EOPNOTSUPP;
+ default: return -EINVAL;
+ }
+
+ return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+ &client->tune_done);
+}
+
+static int smsdvb_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+
+ sms_debug("");
+
+ /* todo: */
+ memcpy(fep, &client->fe_params,
+ sizeof(struct dvb_frontend_parameters));
+ return 0;
+}
+
+static void smsdvb_release(struct dvb_frontend *fe)
+{
+ /* do nothing */
+}
+
+static struct dvb_frontend_ops smsdvb_fe_ops = {
+ .info = {
+ .name = "Siano Mobile Digital SMS1xxx",
+ .type = FE_OFDM,
+ .frequency_min = 44250000,
+ .frequency_max = 867250000,
+ .frequency_stepsize = 250000,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_RECOVER |
+ FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .release = smsdvb_release,
+
+ .set_frontend = smsdvb_set_frontend,
+ .get_frontend = smsdvb_get_frontend,
+ .get_tune_settings = smsdvb_get_tune_settings,
+
+ .read_status = smsdvb_read_status,
+ .read_ber = smsdvb_read_ber,
+ .read_signal_strength = smsdvb_read_signal_strength,
+ .read_snr = smsdvb_read_snr,
+};
+
+static int smsdvb_hotplug(struct smscore_device_t *coredev,
+ struct device *device, int arrival)
+{
+ struct smsclient_params_t params;
+ struct smsdvb_client_t *client;
+ int rc;
+
+ /* device removal handled by onremove callback */
+ if (!arrival)
+ return 0;
+
+ if (smscore_get_device_mode(coredev) != 4) {
+ sms_err("SMS Device mode is not set for "
+ "DVB operation.");
+ return 0;
+ }
+
+ client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
+ if (!client) {
+ sms_err("kmalloc() failed");
+ return -ENOMEM;
+ }
+
+ /* register dvb adapter */
+ rc = dvb_register_adapter(&client->adapter,
+ sms_get_board(
+ smscore_get_board_id(coredev))->name,
+ THIS_MODULE, device, adapter_nr);
+ if (rc < 0) {
+ sms_err("dvb_register_adapter() failed %d", rc);
+ goto adapter_error;
+ }
+
+ /* init dvb demux */
+ client->demux.dmx.capabilities = DMX_TS_FILTERING;
+ client->demux.filternum = 32; /* todo: nova ??? */
+ client->demux.feednum = 32;
+ client->demux.start_feed = smsdvb_start_feed;
+ client->demux.stop_feed = smsdvb_stop_feed;
+
+ rc = dvb_dmx_init(&client->demux);
+ if (rc < 0) {
+ sms_err("dvb_dmx_init failed %d", rc);
+ goto dvbdmx_error;
+ }
+
+ /* init dmxdev */
+ client->dmxdev.filternum = 32;
+ client->dmxdev.demux = &client->demux.dmx;
+ client->dmxdev.capabilities = 0;
+
+ rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
+ if (rc < 0) {
+ sms_err("dvb_dmxdev_init failed %d", rc);
+ goto dmxdev_error;
+ }
+
+ /* init and register frontend */
+ memcpy(&client->frontend.ops, &smsdvb_fe_ops,
+ sizeof(struct dvb_frontend_ops));
+
+ rc = dvb_register_frontend(&client->adapter, &client->frontend);
+ if (rc < 0) {
+ sms_err("frontend registration failed %d", rc);
+ goto frontend_error;
+ }
+
+ params.initial_id = 1;
+ params.data_type = MSG_SMS_DVBT_BDA_DATA;
+ params.onresponse_handler = smsdvb_onresponse;
+ params.onremove_handler = smsdvb_onremove;
+ params.context = client;
+
+ rc = smscore_register_client(coredev, &params, &client->smsclient);
+ if (rc < 0) {
+ sms_err("smscore_register_client() failed %d", rc);
+ goto client_error;
+ }
+
+ client->coredev = coredev;
+
+ init_completion(&client->tune_done);
+ init_completion(&client->stat_done);
+
+ kmutex_lock(&g_smsdvb_clientslock);
+
+ list_add(&client->entry, &g_smsdvb_clients);
+
+ kmutex_unlock(&g_smsdvb_clientslock);
+
+ sms_info("success");
+
+ return 0;
+
+client_error:
+ dvb_unregister_frontend(&client->frontend);
+
+frontend_error:
+ dvb_dmxdev_release(&client->dmxdev);
+
+dmxdev_error:
+ dvb_dmx_release(&client->demux);
+
+dvbdmx_error:
+ dvb_unregister_adapter(&client->adapter);
+
+adapter_error:
+ kfree(client);
+ return rc;
+}
+
+int smsdvb_register(void)
+{
+ int rc;
+
+ INIT_LIST_HEAD(&g_smsdvb_clients);
+ kmutex_init(&g_smsdvb_clientslock);
+
+ rc = smscore_register_hotplug(smsdvb_hotplug);
+
+ sms_debug("");
+
+ return rc;
+}
+
+void smsdvb_unregister(void)
+{
+ smscore_unregister_hotplug(smsdvb_hotplug);
+
+ kmutex_lock(&g_smsdvb_clientslock);
+
+ while (!list_empty(&g_smsdvb_clients))
+ smsdvb_unregister_client(
+ (struct smsdvb_client_t *) g_smsdvb_clients.next);
+
+ kmutex_unlock(&g_smsdvb_clientslock);
+}
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
new file mode 100644
index 00000000000..c10b1849c6a
--- /dev/null
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -0,0 +1,459 @@
+/*
+ * Driver for the Siano SMS1xxx USB dongle
+ *
+ * author: Anatoly Greenblat
+ *
+ * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation;
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+#define USB1_BUFFER_SIZE 0x1000
+#define USB2_BUFFER_SIZE 0x4000
+
+#define MAX_BUFFERS 50
+#define MAX_URBS 10
+
+struct smsusb_device_t;
+
+struct smsusb_urb_t {
+ struct smscore_buffer_t *cb;
+ struct smsusb_device_t *dev;
+
+ struct urb urb;
+};
+
+struct smsusb_device_t {
+ struct usb_device *udev;
+ struct smscore_device_t *coredev;
+
+ struct smsusb_urb_t surbs[MAX_URBS];
+
+ int response_alignment;
+ int buffer_size;
+};
+
+static int smsusb_submit_urb(struct smsusb_device_t *dev,
+ struct smsusb_urb_t *surb);
+
+static void smsusb_onresponse(struct urb *urb)
+{
+ struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
+ struct smsusb_device_t *dev = surb->dev;
+
+ if (urb->status < 0) {
+ sms_err("error, urb status %d, %d bytes",
+ urb->status, urb->actual_length);
+ return;
+ }
+
+ if (urb->actual_length > 0) {
+ struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p;
+
+ if (urb->actual_length >= phdr->msgLength) {
+ surb->cb->size = phdr->msgLength;
+
+ if (dev->response_alignment &&
+ (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) {
+
+ surb->cb->offset =
+ dev->response_alignment +
+ ((phdr->msgFlags >> 8) & 3);
+
+ /* sanity check */
+ if (((int) phdr->msgLength +
+ surb->cb->offset) > urb->actual_length) {
+ sms_err("invalid response "
+ "msglen %d offset %d "
+ "size %d",
+ phdr->msgLength,
+ surb->cb->offset,
+ urb->actual_length);
+ goto exit_and_resubmit;
+ }
+
+ /* move buffer pointer and
+ * copy header to its new location */
+ memcpy((char *) phdr + surb->cb->offset,
+ phdr, sizeof(struct SmsMsgHdr_ST));
+ } else
+ surb->cb->offset = 0;
+
+ smscore_onresponse(dev->coredev, surb->cb);
+ surb->cb = NULL;
+ } else {
+ sms_err("invalid response "
+ "msglen %d actual %d",
+ phdr->msgLength, urb->actual_length);
+ }
+ }
+
+exit_and_resubmit:
+ smsusb_submit_urb(dev, surb);
+}
+
+static int smsusb_submit_urb(struct smsusb_device_t *dev,
+ struct smsusb_urb_t *surb)
+{
+ if (!surb->cb) {
+ surb->cb = smscore_getbuffer(dev->coredev);
+ if (!surb->cb) {
+ sms_err("smscore_getbuffer(...) returned NULL");
+ return -ENOMEM;
+ }
+ }
+
+ usb_fill_bulk_urb(
+ &surb->urb,
+ dev->udev,
+ usb_rcvbulkpipe(dev->udev, 0x81),
+ surb->cb->p,
+ dev->buffer_size,
+ smsusb_onresponse,
+ surb
+ );
+ surb->urb.transfer_dma = surb->cb->phys;
+ surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ return usb_submit_urb(&surb->urb, GFP_ATOMIC);
+}
+
+static void smsusb_stop_streaming(struct smsusb_device_t *dev)
+{
+ int i;
+
+ for (i = 0; i < MAX_URBS; i++) {
+ usb_kill_urb(&dev->surbs[i].urb);
+
+ if (dev->surbs[i].cb) {
+ smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
+ dev->surbs[i].cb = NULL;
+ }
+ }
+}
+
+static int smsusb_start_streaming(struct smsusb_device_t *dev)
+{
+ int i, rc;
+
+ for (i = 0; i < MAX_URBS; i++) {
+ rc = smsusb_submit_urb(dev, &dev->surbs[i]);
+ if (rc < 0) {
+ sms_err("smsusb_submit_urb(...) failed");
+ smsusb_stop_streaming(dev);
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static int smsusb_sendrequest(void *context, void *buffer, size_t size)
+{
+ struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
+ int dummy;
+
+ return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
+ buffer, size, &dummy, 1000);
+}
+
+static char *smsusb1_fw_lkup[] = {
+ "dvbt_stellar_usb.inp",
+ "dvbh_stellar_usb.inp",
+ "tdmb_stellar_usb.inp",
+ "none",
+ "dvbt_bda_stellar_usb.inp",
+};
+
+static inline char *sms_get_fw_name(int mode, int board_id)
+{
+ char **fw = sms_get_board(board_id)->fw;
+ return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode];
+}
+
+static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id)
+{
+ const struct firmware *fw;
+ u8 *fw_buffer;
+ int rc, dummy;
+ char *fw_filename;
+
+ if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) {
+ sms_err("invalid firmware id specified %d", id);
+ return -EINVAL;
+ }
+
+ fw_filename = sms_get_fw_name(id, board_id);
+
+ rc = request_firmware(&fw, fw_filename, &udev->dev);
+ if (rc < 0) {
+ sms_warn("failed to open \"%s\" mode %d, "
+ "trying again with default firmware", fw_filename, id);
+
+ fw_filename = smsusb1_fw_lkup[id];
+ rc = request_firmware(&fw, fw_filename, &udev->dev);
+ if (rc < 0) {
+ sms_warn("failed to open \"%s\" mode %d",
+ fw_filename, id);
+
+ return rc;
+ }
+ }
+
+ fw_buffer = kmalloc(fw->size, GFP_KERNEL);
+ if (fw_buffer) {
+ memcpy(fw_buffer, fw->data, fw->size);
+
+ rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2),
+ fw_buffer, fw->size, &dummy, 1000);
+
+ sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc);
+
+ kfree(fw_buffer);
+ } else {
+ sms_err("failed to allocate firmware buffer");
+ rc = -ENOMEM;
+ }
+ sms_info("read FW %s, size=%zd", fw_filename, fw->size);
+
+ release_firmware(fw);
+
+ return rc;
+}
+
+static void smsusb1_detectmode(void *context, int *mode)
+{
+ char *product_string =
+ ((struct smsusb_device_t *) context)->udev->product;
+
+ *mode = DEVICE_MODE_NONE;
+
+ if (!product_string) {
+ product_string = "none";
+ sms_err("product string not found");
+ } else if (strstr(product_string, "DVBH"))
+ *mode = 1;
+ else if (strstr(product_string, "BDA"))
+ *mode = 4;
+ else if (strstr(product_string, "DVBT"))
+ *mode = 0;
+ else if (strstr(product_string, "TDMB"))
+ *mode = 2;
+
+ sms_info("%d \"%s\"", *mode, product_string);
+}
+
+static int smsusb1_setmode(void *context, int mode)
+{
+ struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK,
+ sizeof(struct SmsMsgHdr_ST), 0 };
+
+ if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
+ sms_err("invalid firmware id specified %d", mode);
+ return -EINVAL;
+ }
+
+ return smsusb_sendrequest(context, &Msg, sizeof(Msg));
+}
+
+static void smsusb_term_device(struct usb_interface *intf)
+{
+ struct smsusb_device_t *dev =
+ (struct smsusb_device_t *) usb_get_intfdata(intf);
+
+ if (dev) {
+ smsusb_stop_streaming(dev);
+
+ /* unregister from smscore */
+ if (dev->coredev)
+ smscore_unregister_device(dev->coredev);
+
+ kfree(dev);
+
+ sms_info("device %p destroyed", dev);
+ }
+
+ usb_set_intfdata(intf, NULL);
+}
+
+static int smsusb_init_device(struct usb_interface *intf, int board_id)
+{
+ struct smsdevice_params_t params;
+ struct smsusb_device_t *dev;
+ int i, rc;
+
+ /* create device object */
+ dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
+ if (!dev) {
+ sms_err("kzalloc(sizeof(struct smsusb_device_t) failed");
+ return -ENOMEM;
+ }
+
+ memset(&params, 0, sizeof(params));
+ usb_set_intfdata(intf, dev);
+ dev->udev = interface_to_usbdev(intf);
+
+ params.device_type = sms_get_board(board_id)->type;
+
+ switch (params.device_type) {
+ case SMS_STELLAR:
+ dev->buffer_size = USB1_BUFFER_SIZE;
+
+ params.setmode_handler = smsusb1_setmode;
+ params.detectmode_handler = smsusb1_detectmode;
+ break;
+ default:
+ sms_err("Unspecified sms device type!");
+ /* fall-thru */
+ case SMS_NOVA_A0:
+ case SMS_NOVA_B0:
+ case SMS_VEGA:
+ dev->buffer_size = USB2_BUFFER_SIZE;
+ dev->response_alignment =
+ dev->udev->ep_in[1]->desc.wMaxPacketSize -
+ sizeof(struct SmsMsgHdr_ST);
+
+ params.flags |= SMS_DEVICE_FAMILY2;
+ break;
+ }
+
+ params.device = &dev->udev->dev;
+ params.buffer_size = dev->buffer_size;
+ params.num_buffers = MAX_BUFFERS;
+ params.sendrequest_handler = smsusb_sendrequest;
+ params.context = dev;
+ snprintf(params.devpath, sizeof(params.devpath),
+ "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath);
+
+ /* register in smscore */
+ rc = smscore_register_device(&params, &dev->coredev);
+ if (rc < 0) {
+ sms_err("smscore_register_device(...) failed, rc %d", rc);
+ smsusb_term_device(intf);
+ return rc;
+ }
+
+ smscore_set_board_id(dev->coredev, board_id);
+
+ /* initialize urbs */
+ for (i = 0; i < MAX_URBS; i++) {
+ dev->surbs[i].dev = dev;
+ usb_init_urb(&dev->surbs[i].urb);
+ }
+
+ sms_info("smsusb_start_streaming(...).");
+ rc = smsusb_start_streaming(dev);
+ if (rc < 0) {
+ sms_err("smsusb_start_streaming(...) failed");
+ smsusb_term_device(intf);
+ return rc;
+ }
+
+ rc = smscore_start_device(dev->coredev);
+ if (rc < 0) {
+ sms_err("smscore_start_device(...) failed");
+ smsusb_term_device(intf);
+ return rc;
+ }
+
+ sms_info("device %p created", dev);
+
+ return rc;
+}
+
+static int smsusb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ char devpath[32];
+ int i, rc;
+
+ rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
+ rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
+
+ if (intf->num_altsetting > 0) {
+ rc = usb_set_interface(
+ udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
+ if (rc < 0) {
+ sms_err("usb_set_interface failed, rc %d", rc);
+ return rc;
+ }
+ }
+
+ sms_info("smsusb_probe %d",
+ intf->cur_altsetting->desc.bInterfaceNumber);
+ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
+ sms_info("endpoint %d %02x %02x %d", i,
+ intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
+ intf->cur_altsetting->endpoint[i].desc.bmAttributes,
+ intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
+
+ if ((udev->actconfig->desc.bNumInterfaces == 2) &&
+ (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
+ sms_err("rom interface 0 is not used");
+ return -ENODEV;
+ }
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+ snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
+ udev->bus->busnum, udev->devpath);
+ sms_info("stellar device was found.");
+ return smsusb1_load_firmware(
+ udev, smscore_registry_getmode(devpath),
+ id->driver_info);
+ }
+
+ rc = smsusb_init_device(intf, id->driver_info);
+ sms_info("rc %d", rc);
+ return rc;
+}
+
+static void smsusb_disconnect(struct usb_interface *intf)
+{
+ smsusb_term_device(intf);
+}
+
+static struct usb_driver smsusb_driver = {
+ .name = "sms1xxx",
+ .probe = smsusb_probe,
+ .disconnect = smsusb_disconnect,
+ .id_table = smsusb_id_table,
+};
+
+int smsusb_register(void)
+{
+ int rc = usb_register(&smsusb_driver);
+ if (rc)
+ sms_err("usb_register failed. Error number %d", rc);
+
+ sms_debug("");
+
+ return rc;
+}
+
+void smsusb_unregister(void)
+{
+ sms_debug("");
+ /* Regular USB Cleanup */
+ usb_deregister(&smsusb_driver);
+}
+
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 07643e01009..87c973ac668 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -106,6 +106,8 @@ config DVB_BUDGET_CI
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
select VIDEO_IR
help
Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index d7483f1a9b3..71451237294 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -3,7 +3,11 @@
# and the AV7110 DVB device driver
#
-dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o av7110_ir.o
+dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o
+
+ifdef CONFIG_INPUT_EVDEV
+dvb-ttpci-objs += av7110_ir.o
+endif
obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o
obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o
@@ -14,6 +18,7 @@ obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
+EXTRA_CFLAGS += -Idrivers/media/common/tuners
hostprogs-y := fdump
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index f05d43d8b5c..0777e8f9544 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -587,7 +587,7 @@ static void gpioirq(unsigned long data)
}
DVB_RINGBUFFER_SKIP(cibuf, 2);
- dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0);
+ dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
@@ -1198,7 +1198,6 @@ static int start_ts_capture(struct av7110 *budget)
if (budget->feeding1)
return ++budget->feeding1;
memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
- budget->tsf = 0xff;
budget->ttbp = 0;
SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
@@ -2403,18 +2402,18 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
saa7146_write(dev, MC1, MASK_29);
/* RPS1 timeout disable */
saa7146_write(dev, RPS_TOV1, 0);
- WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
- WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
- WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
- WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+ WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(GPIO3_MSK);
+ WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
#if RPS_IRQ
/* issue RPS1 interrupt to increment counter */
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
#endif
- WRITE_RPS1(cpu_to_le32(CMD_STOP));
+ WRITE_RPS1(CMD_STOP);
/* Jump to begin of RPS program as safety measure (p37) */
- WRITE_RPS1(cpu_to_le32(CMD_JUMP));
- WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
+ WRITE_RPS1(CMD_JUMP);
+ WRITE_RPS1(dev->d_rps1.dma_handle);
#if RPS_IRQ
/* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
@@ -2472,11 +2471,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
get recognized before the main driver is fully loaded */
saa7146_write(dev, GPIO_CTRL, 0x500000);
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-#endif
strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
@@ -2527,28 +2522,28 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
count = 0;
/* Wait Source Line Counter Threshold (p36) */
- WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
+ WRITE_RPS1(CMD_PAUSE | EVT_HS);
/* Set GPIO3=1 (p42) */
- WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
- WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
- WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(GPIO3_MSK);
+ WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
#if RPS_IRQ
/* issue RPS1 interrupt */
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
#endif
/* Wait reset Source Line Counter Threshold (p36) */
- WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
+ WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
/* Set GPIO3=0 (p42) */
- WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
- WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
- WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(GPIO3_MSK);
+ WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
#if RPS_IRQ
/* issue RPS1 interrupt */
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
#endif
/* Jump to begin of RPS program (p37) */
- WRITE_RPS1(cpu_to_le32(CMD_JUMP));
- WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
+ WRITE_RPS1(CMD_JUMP);
+ WRITE_RPS1(dev->d_rps1.dma_handle);
/* Fix VSYNC level */
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index e494e04eeee..55f23ddcb99 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -188,7 +188,6 @@ struct av7110 {
struct dvb_net dvb_net1;
spinlock_t feedlock1;
int feeding1;
- u8 tsf;
u32 ttbp;
unsigned char *grabbing;
struct saa7146_pgtable pt;
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index ec55a968f20..184647ad1c7 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -269,7 +269,7 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
return -1;
}
- dvb_ringbuffer_read(buf, dest, (size_t) blen, 0);
+ dvb_ringbuffer_read(buf, dest, (size_t) blen);
dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
(unsigned long) buf->pread, (unsigned long) buf->pwrite);
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index c58e3fc509e..261135ded48 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
return -EINVAL;
DVB_RINGBUFFER_SKIP(cibuf, 2);
- return dvb_ringbuffer_read(cibuf, (u8 *)buf, len, 1);
+ return dvb_ringbuffer_read_user(cibuf, buf, len);
}
static int dvb_ca_open(struct inode *inode, struct file *file)
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 74d940f75da..ca99e5c1fc8 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -305,7 +305,6 @@ enum av7110_command_type {
#define IRQ_STATE (DPRAM_BASE + 0x0F4)
#define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6)
#define MSGSTATE (DPRAM_BASE + 0x0F8)
-#define FILT_STATE (DPRAM_BASE + 0x0FA)
#define COMMAND (DPRAM_BASE + 0x0FC)
#define COM_BUFF (DPRAM_BASE + 0x100)
#define COM_BUFF_SIZE 0x20
@@ -332,8 +331,6 @@ enum av7110_command_type {
/* firmware status area */
#define STATUS_BASE (DPRAM_BASE + 0x1FC0)
-#define STATUS_SCR (STATUS_BASE + 0x00)
-#define STATUS_MODES (STATUS_BASE + 0x04)
#define STATUS_LOOPS (STATUS_BASE + 0x08)
#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C)
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index b30a5288e48..b7d1f2f18d3 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -667,6 +667,11 @@ static struct tda1002x_config philips_cu1216_config_altaddress = {
.invert = 0,
};
+static struct tda10023_config philips_cu1216_tda10023_config = {
+ .demod_address = 0x0c,
+ .invert = 1,
+};
+
static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
{
struct budget *budget = (struct budget *) fe->dvb->priv;
@@ -1019,9 +1024,10 @@ static void frontend_init(struct budget_av *budget_av)
case SUBID_DVBC_KNC1_PLUS_MK3:
budget_av->reinitialise_demod = 1;
budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
- fe = dvb_attach(tda10023_attach, &philips_cu1216_config,
- &budget_av->budget.i2c_adap,
- read_pwm(budget_av));
+ fe = dvb_attach(tda10023_attach,
+ &philips_cu1216_tda10023_config,
+ &budget_av->budget.i2c_adap,
+ read_pwm(budget_av));
if (fe) {
fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
}
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 6530323d540..060e7c78532 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -46,6 +46,8 @@
#include "lnbp21.h"
#include "bsbe1.h"
#include "bsru6.h"
+#include "tda1002x.h"
+#include "tda827x.h"
/*
* Regarding DEBIADDR_IR:
@@ -225,6 +227,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
break;
case 0x1010:
case 0x1017:
+ case 0x101a:
/* for the Technotrend 1500 bundled remote */
ir_input_init(input_dev, &budget_ci->ir.state,
IR_TYPE_RC5, ir_codes_tt_1500);
@@ -1056,6 +1059,15 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = {
.stop_during_read = 1,
};
+static struct tda10023_config tda10023_config = {
+ .demod_address = 0xc,
+ .invert = 0,
+ .xtal = 16000000,
+ .pll_m = 11,
+ .pll_p = 3,
+ .pll_n = 1,
+ .deltaf = 0xa511,
+};
@@ -1126,7 +1138,17 @@ static void frontend_init(struct budget_ci *budget_ci)
budget_ci->budget.dvb_frontend = NULL;
}
}
+ break;
+ case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
+ budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
+ if (budget_ci->budget.dvb_frontend) {
+ if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
+ printk(KERN_ERR "%s: No tda827x found!\n", __func__);
+ dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+ budget_ci->budget.dvb_frontend = NULL;
+ }
+ }
break;
}
@@ -1216,6 +1238,7 @@ MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1224,6 +1247,7 @@ static struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
+ MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
{
.vendor = 0,
}
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 18cac4b12ab..6f4ddb643fe 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -497,11 +497,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
if (bi->type != BUDGET_FS_ACTIVY)
saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- budget->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-#endif
strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 9a155396d6a..39bd0a20f53 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -431,22 +431,22 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
// in budget patch GPIO3 is connected to VSYNC_B
count = 0;
#if 0
- WRITE_RPS1(cpu_to_le32(CMD_UPLOAD |
- MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ));
+ WRITE_RPS1(CMD_UPLOAD |
+ MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
#endif
- WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
- WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
- WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
- WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+ WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(GPIO3_MSK);
+ WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
#if RPS_IRQ
// issue RPS1 interrupt to increment counter
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
// at least a NOP is neede between two interrupts
- WRITE_RPS1(cpu_to_le32(CMD_NOP));
+ WRITE_RPS1(CMD_NOP);
// interrupt again
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
#endif
- WRITE_RPS1(cpu_to_le32(CMD_STOP));
+ WRITE_RPS1(CMD_STOP);
#if RPS_IRQ
// set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
@@ -558,28 +558,28 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
// Wait Source Line Counter Threshold (p36)
- WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
+ WRITE_RPS1(CMD_PAUSE | EVT_HS);
// Set GPIO3=1 (p42)
- WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
- WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
- WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(GPIO3_MSK);
+ WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
#if RPS_IRQ
// issue RPS1 interrupt
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
#endif
// Wait reset Source Line Counter Threshold (p36)
- WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
+ WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
// Set GPIO3=0 (p42)
- WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
- WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
- WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(GPIO3_MSK);
+ WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
#if RPS_IRQ
// issue RPS1 interrupt
- WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+ WRITE_RPS1(CMD_INTERRUPT);
#endif
// Jump to begin of RPS program (p37)
- WRITE_RPS1(cpu_to_le32(CMD_JUMP));
- WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
+ WRITE_RPS1(CMD_JUMP);
+ WRITE_RPS1(dev->d_rps1.dma_handle);
// Fix VSYNC level
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index bc2043e44eb..e6c9cd2e3b9 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/wait.h>
+#include <linux/fs.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/delay.h>
@@ -990,22 +991,9 @@ static int stc_open(struct inode *inode, struct file *file)
}
static ssize_t stc_read(struct file *file, char *buf, size_t count,
- loff_t * offset)
+ loff_t *offset)
{
- int tc = count;
-
- if ((tc + *offset) > 8192)
- tc = 8192 - *offset;
-
- if (tc < 0)
- return 0;
-
- if (copy_to_user(buf, stc_firmware + *offset, tc))
- return -EFAULT;
-
- *offset += tc;
-
- return tc;
+ return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
}
static int stc_release(struct inode *inode, struct file *file)
@@ -1693,11 +1681,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-#endif
ttusb->i2c_adap.algo = &ttusb_dec_algo;
ttusb->i2c_adap.algo_data = NULL;
ttusb->i2c_adap.dev.parent = &udev->dev;
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 77354ca6e8e..dc93a882b38 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -24,6 +24,19 @@
/*
+ * User Notes:
+ * - USB Audio is provided by the alsa snd_usb_audio module.
+ * For listing you have to redirect the sound, for example using:
+ * arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
+ * - regarding module parameters in /sys/module/radio_si470x/parameters:
+ * the contents of read-only files (0444) are not updated, even if
+ * space, band and de are changed using private video controls
+ * - increase tune_timeout, if you often get -EIO errors
+ * - hw_freq_seek returns -EAGAIN, when timed out or band limit is reached
+ */
+
+
+/*
* History:
* 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.0
@@ -85,10 +98,14 @@
* Oliver Neukum <oliver@neukum.org>
* Version 1.0.7
* - usb autosuspend support
- * - unplugging fixed
+ * - unplugging fixed
+ * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Version 1.0.8
+ * - hardware frequency seek support
+ * - afc indication
+ * - more safety checks, let si470x_get_freq return errno
*
* ToDo:
- * - add seeking support
* - add firmware download/update support
* - RDS support: interrupt mode, instead of polling
* - add LED status output (check if that's not already done in firmware)
@@ -98,10 +115,10 @@
/* driver definitions */
#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
#define DRIVER_NAME "radio-si470x"
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 7)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8)
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.7"
+#define DRIVER_VERSION "1.0.8"
/* kernel includes */
@@ -175,6 +192,11 @@ static unsigned int tune_timeout = 3000;
module_param(tune_timeout, uint, 0);
MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
+/* Seek timeout */
+static unsigned int seek_timeout = 5000;
+module_param(seek_timeout, uint, 0);
+MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
+
/* RDS buffer blocks */
static unsigned int rds_buf = 100;
module_param(rds_buf, uint, 0);
@@ -425,7 +447,8 @@ struct si470x_device {
/* driver management */
unsigned int users;
- unsigned char disconnected;
+ unsigned char disconnected;
+ struct mutex disconnect_lock;
/* Silabs internal registers (0..15) */
unsigned short registers[RADIO_REGISTER_NUM];
@@ -442,12 +465,6 @@ struct si470x_device {
/*
- * Lock to prevent kfree of data before all users have releases the device.
- */
-static DEFINE_MUTEX(open_close_lock);
-
-
-/*
* The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
* 62.5 kHz otherwise.
* The tuner is able to have a channel spacing of 50, 100 or 200 kHz.
@@ -476,11 +493,11 @@ static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
report[0], 2,
buf, size, usb_timeout);
+
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
": si470x_get_report: usb_control_msg returned %d\n",
retval);
-
return retval;
}
@@ -499,11 +516,11 @@ static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
report[0], 2,
buf, size, usb_timeout);
+
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
": si470x_set_report: usb_control_msg returned %d\n",
retval);
-
return retval;
}
@@ -521,8 +538,7 @@ static int si470x_get_register(struct si470x_device *radio, int regnr)
retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
if (retval >= 0)
- radio->registers[regnr] = be16_to_cpu(get_unaligned(
- (unsigned short *) &buf[1]));
+ radio->registers[regnr] = get_unaligned_be16(&buf[1]);
return (retval < 0) ? -EINVAL : 0;
}
@@ -537,8 +553,7 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
int retval;
buf[0] = REGISTER_REPORT(regnr);
- put_unaligned(cpu_to_be16(radio->registers[regnr]),
- (unsigned short *) &buf[1]);
+ put_unaligned_be16(radio->registers[regnr], &buf[1]);
retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
@@ -561,9 +576,8 @@ static int si470x_get_all_registers(struct si470x_device *radio)
if (retval >= 0)
for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
- radio->registers[regnr] = be16_to_cpu(get_unaligned(
- (unsigned short *)
- &buf[regnr * RADIO_REGISTER_SIZE + 1]));
+ radio->registers[regnr] = get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
return (retval < 0) ? -EINVAL : 0;
}
@@ -585,7 +599,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
usb_rcvintpipe(radio->usbdev, 1),
(void *) &buf, sizeof(buf), &size, usb_timeout);
if (size != sizeof(buf))
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
"return size differs: %d != %zu\n", size, sizeof(buf));
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
@@ -594,8 +608,8 @@ static int si470x_get_rds_registers(struct si470x_device *radio)
if (retval >= 0)
for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
radio->registers[STATUSRSSI + regnr] =
- be16_to_cpu(get_unaligned((unsigned short *)
- &buf[regnr * RADIO_REGISTER_SIZE + 1]));
+ get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
return (retval < 0) ? -EINVAL : 0;
}
@@ -615,33 +629,39 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
radio->registers[CHANNEL] |= CHANNEL_TUNE | chan;
retval = si470x_set_register(radio, CHANNEL);
if (retval < 0)
- return retval;
+ goto done;
- /* wait till seek operation has completed */
+ /* wait till tune operation has completed */
timeout = jiffies + msecs_to_jiffies(tune_timeout);
do {
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
- return retval;
+ goto stop;
timed_out = time_after(jiffies, timeout);
} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
(!timed_out));
+ if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
+ printk(KERN_WARNING DRIVER_NAME ": tune does not complete\n");
if (timed_out)
printk(KERN_WARNING DRIVER_NAME
- ": seek does not finish after %u ms\n", tune_timeout);
+ ": tune timed out after %u ms\n", tune_timeout);
+stop:
/* stop tuning */
radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
- return si470x_set_register(radio, CHANNEL);
+ retval = si470x_set_register(radio, CHANNEL);
+
+done:
+ return retval;
}
/*
* si470x_get_freq - get the frequency
*/
-static unsigned int si470x_get_freq(struct si470x_device *radio)
+static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
{
- unsigned int spacing, band_bottom, freq;
+ unsigned int spacing, band_bottom;
unsigned short chan;
int retval;
@@ -667,14 +687,12 @@ static unsigned int si470x_get_freq(struct si470x_device *radio)
/* read channel */
retval = si470x_get_register(radio, READCHAN);
- if (retval < 0)
- return retval;
chan = radio->registers[READCHAN] & READCHAN_READCHAN;
/* Frequency (MHz) = Spacing (kHz) x Channel + Bottom of Band (MHz) */
- freq = chan * spacing + band_bottom;
+ *freq = chan * spacing + band_bottom;
- return freq;
+ return retval;
}
@@ -714,6 +732,62 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
/*
+ * si470x_set_seek - set seek
+ */
+static int si470x_set_seek(struct si470x_device *radio,
+ unsigned int wrap_around, unsigned int seek_upward)
+{
+ int retval = 0;
+ unsigned long timeout;
+ bool timed_out = 0;
+
+ /* start seeking */
+ radio->registers[POWERCFG] |= POWERCFG_SEEK;
+ if (wrap_around == 1)
+ radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
+ else
+ radio->registers[POWERCFG] |= POWERCFG_SKMODE;
+ if (seek_upward == 1)
+ radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
+ else
+ radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
+ retval = si470x_set_register(radio, POWERCFG);
+ if (retval < 0)
+ goto done;
+
+ /* wait till seek operation has completed */
+ timeout = jiffies + msecs_to_jiffies(seek_timeout);
+ do {
+ retval = si470x_get_register(radio, STATUSRSSI);
+ if (retval < 0)
+ goto stop;
+ timed_out = time_after(jiffies, timeout);
+ } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
+ (!timed_out));
+ if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
+ printk(KERN_WARNING DRIVER_NAME ": seek does not complete\n");
+ if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
+ printk(KERN_WARNING DRIVER_NAME
+ ": seek failed / band limit reached\n");
+ if (timed_out)
+ printk(KERN_WARNING DRIVER_NAME
+ ": seek timed out after %u ms\n", seek_timeout);
+
+stop:
+ /* stop seeking */
+ radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
+ retval = si470x_set_register(radio, POWERCFG);
+
+done:
+ /* try again, if timed out */
+ if ((retval == 0) && timed_out)
+ retval = -EAGAIN;
+
+ return retval;
+}
+
+
+/*
* si470x_start - switch on radio
*/
static int si470x_start(struct si470x_device *radio)
@@ -725,27 +799,30 @@ static int si470x_start(struct si470x_device *radio)
POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM;
retval = si470x_set_register(radio, POWERCFG);
if (retval < 0)
- return retval;
+ goto done;
/* sysconfig 1 */
radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
retval = si470x_set_register(radio, SYSCONFIG1);
if (retval < 0)
- return retval;
+ goto done;
/* sysconfig 2 */
radio->registers[SYSCONFIG2] =
- (0x3f << 8) | /* SEEKTH */
- (band << 6) | /* BAND */
- (space << 4) | /* SPACE */
- 15; /* VOLUME (max) */
+ (0x3f << 8) | /* SEEKTH */
+ ((band << 6) & SYSCONFIG2_BAND) | /* BAND */
+ ((space << 4) & SYSCONFIG2_SPACE) | /* SPACE */
+ 15; /* VOLUME (max) */
retval = si470x_set_register(radio, SYSCONFIG2);
if (retval < 0)
- return retval;
+ goto done;
/* reset last channel */
- return si470x_set_chan(radio,
+ retval = si470x_set_chan(radio,
radio->registers[CHANNEL] & CHANNEL_CHAN);
+
+done:
+ return retval;
}
@@ -760,13 +837,16 @@ static int si470x_stop(struct si470x_device *radio)
radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
retval = si470x_set_register(radio, SYSCONFIG1);
if (retval < 0)
- return retval;
+ goto done;
/* powercfg */
radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
/* POWERCFG_ENABLE has to automatically go low */
radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE;
- return si470x_set_register(radio, POWERCFG);
+ retval = si470x_set_register(radio, POWERCFG);
+
+done:
+ return retval;
}
@@ -843,7 +923,7 @@ static void si470x_rds(struct si470x_device *radio)
};
/* Fill the V4L2 RDS buffer */
- put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf);
+ put_unaligned_le16(rds, &tmpbuf);
tmpbuf[2] = blocknum; /* offset name */
tmpbuf[2] |= blocknum << 3; /* received offset */
if (bler > max_rds_errors)
@@ -883,8 +963,9 @@ static void si470x_work(struct work_struct *work)
struct si470x_device *radio = container_of(work, struct si470x_device,
work.work);
- if (radio->disconnected)
- return;
+ /* safety checks */
+ if (radio->disconnected)
+ return;
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
return;
@@ -917,11 +998,15 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
/* block if no new data available */
while (radio->wr_index == radio->rd_index) {
- if (file->f_flags & O_NONBLOCK)
- return -EWOULDBLOCK;
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EWOULDBLOCK;
+ goto done;
+ }
if (wait_event_interruptible(radio->read_queue,
- radio->wr_index != radio->rd_index) < 0)
- return -EINTR;
+ radio->wr_index != radio->rd_index) < 0) {
+ retval = -EINTR;
+ goto done;
+ }
}
/* calculate block count from byte count */
@@ -950,6 +1035,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
}
mutex_unlock(&radio->lock);
+done:
return retval;
}
@@ -961,6 +1047,7 @@ static unsigned int si470x_fops_poll(struct file *file,
struct poll_table_struct *pts)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
/* switch on rds reception */
if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
@@ -972,9 +1059,9 @@ static unsigned int si470x_fops_poll(struct file *file,
poll_wait(file, &radio->read_queue, pts);
if (radio->rd_index != radio->wr_index)
- return POLLIN | POLLRDNORM;
+ retval = POLLIN | POLLRDNORM;
- return 0;
+ return retval;
}
@@ -991,17 +1078,18 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
retval = usb_autopm_get_interface(radio->intf);
if (retval < 0) {
radio->users--;
- return -EIO;
+ retval = -EIO;
+ goto done;
}
if (radio->users == 1) {
retval = si470x_start(radio);
if (retval < 0)
usb_autopm_put_interface(radio->intf);
- return retval;
}
- return 0;
+done:
+ return retval;
}
@@ -1011,20 +1099,23 @@ static int si470x_fops_open(struct inode *inode, struct file *file)
static int si470x_fops_release(struct inode *inode, struct file *file)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
- int retval = 0;
+ int retval = 0;
- if (!radio)
- return -ENODEV;
+ /* safety check */
+ if (!radio) {
+ retval = -ENODEV;
+ goto done;
+ }
- mutex_lock(&open_close_lock);
+ mutex_lock(&radio->disconnect_lock);
radio->users--;
if (radio->users == 0) {
- if (radio->disconnected) {
- video_unregister_device(radio->videodev);
- kfree(radio->buffer);
- kfree(radio);
- goto done;
- }
+ if (radio->disconnected) {
+ video_unregister_device(radio->videodev);
+ kfree(radio->buffer);
+ kfree(radio);
+ goto unlock;
+ }
/* stop rds reception */
cancel_delayed_work_sync(&radio->work);
@@ -1036,9 +1127,11 @@ static int si470x_fops_release(struct inode *inode, struct file *file)
usb_autopm_put_interface(radio->intf);
}
+unlock:
+ mutex_unlock(&radio->disconnect_lock);
+
done:
- mutex_unlock(&open_close_lock);
- return retval;
+ return retval;
}
@@ -1116,7 +1209,8 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
sprintf(capability->bus_info, "USB");
capability->version = DRIVER_KERNEL_VERSION;
- capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
+ V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -1125,7 +1219,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
/*
* si470x_vidioc_g_input - get input
*/
-static int si470x_vidioc_g_input(struct file *filp, void *priv,
+static int si470x_vidioc_g_input(struct file *file, void *priv,
unsigned int *i)
{
*i = 0;
@@ -1137,12 +1231,18 @@ static int si470x_vidioc_g_input(struct file *filp, void *priv,
/*
* si470x_vidioc_s_input - set input
*/
-static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
+ int retval = 0;
+
+ /* safety checks */
if (i != 0)
- return -EINVAL;
+ retval = -EINVAL;
- return 0;
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": set input failed with %d\n", retval);
+ return retval;
}
@@ -1155,17 +1255,22 @@ static int si470x_vidioc_queryctrl(struct file *file, void *priv,
unsigned char i;
int retval = -EINVAL;
+ /* safety checks */
+ if (!qc->id)
+ goto done;
+
for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
- if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) {
+ if (qc->id == si470x_v4l2_queryctrl[i].id) {
memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
retval = 0;
break;
}
}
+
+done:
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
- ": query control failed with %d\n", retval);
-
+ ": query controls failed with %d\n", retval);
return retval;
}
@@ -1177,9 +1282,13 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
- if (radio->disconnected)
- return -EIO;
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
@@ -1190,9 +1299,15 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
ctrl->value = ((radio->registers[POWERCFG] &
POWERCFG_DMUTE) == 0) ? 1 : 0;
break;
+ default:
+ retval = -EINVAL;
}
- return 0;
+done:
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": get control failed with %d\n", retval);
+ return retval;
}
@@ -1203,10 +1318,13 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
- int retval;
+ int retval = 0;
- if (radio->disconnected)
- return -EIO;
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
@@ -1224,10 +1342,11 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
default:
retval = -EINVAL;
}
+
+done:
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
": set control failed with %d\n", retval);
-
return retval;
}
@@ -1238,13 +1357,22 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
static int si470x_vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- if (audio->index > 1)
- return -EINVAL;
+ int retval = 0;
+
+ /* safety checks */
+ if (audio->index != 0) {
+ retval = -EINVAL;
+ goto done;
+ }
strcpy(audio->name, "Radio");
audio->capability = V4L2_AUDCAP_STEREO;
- return 0;
+done:
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": get audio failed with %d\n", retval);
+ return retval;
}
@@ -1254,10 +1382,19 @@ static int si470x_vidioc_g_audio(struct file *file, void *priv,
static int si470x_vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- if (audio->index != 0)
- return -EINVAL;
+ int retval = 0;
- return 0;
+ /* safety checks */
+ if (audio->index != 0) {
+ retval = -EINVAL;
+ goto done;
+ }
+
+done:
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": set audio failed with %d\n", retval);
+ return retval;
}
@@ -1268,20 +1405,23 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
- int retval;
+ int retval = 0;
- if (radio->disconnected)
- return -EIO;
- if (tuner->index > 0)
- return -EINVAL;
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
+ if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
+ retval = -EINVAL;
+ goto done;
+ }
- /* read status rssi */
retval = si470x_get_register(radio, STATUSRSSI);
if (retval < 0)
- return retval;
+ goto done;
strcpy(tuner->name, "FM");
- tuner->type = V4L2_TUNER_RADIO;
switch (band) {
/* 0: 87.5 - 108 MHz (USA, Europe, default) */
default:
@@ -1313,9 +1453,14 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
* 0x0101;
/* automatic frequency control: -1: freq to low, 1 freq to high */
- tuner->afc = 0;
+ /* AFCRL does only indicate that freq. differs, not if too low/high */
+ tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
- return 0;
+done:
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": get tuner failed with %d\n", retval);
+ return retval;
}
@@ -1326,12 +1471,17 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
- int retval;
+ int retval = 0;
- if (radio->disconnected)
- return -EIO;
- if (tuner->index > 0)
- return -EINVAL;
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
+ if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
+ retval = -EINVAL;
+ goto done;
+ }
if (tuner->audmode == V4L2_TUNER_MODE_MONO)
radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
@@ -1339,10 +1489,11 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
retval = si470x_set_register(radio, POWERCFG);
+
+done:
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
": set tuner failed with %d\n", retval);
-
return retval;
}
@@ -1354,14 +1505,25 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *freq)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
- if (radio->disconnected)
- return -EIO;
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
+ if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+ retval = -EINVAL;
+ goto done;
+ }
- freq->type = V4L2_TUNER_RADIO;
- freq->frequency = si470x_get_freq(radio);
+ retval = si470x_get_freq(radio, &freq->frequency);
- return 0;
+done:
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": get frequency failed with %d\n", retval);
+ return retval;
}
@@ -1372,19 +1534,55 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *freq)
{
struct si470x_device *radio = video_get_drvdata(video_devdata(file));
- int retval;
+ int retval = 0;
- if (radio->disconnected)
- return -EIO;
- if (freq->type != V4L2_TUNER_RADIO)
- return -EINVAL;
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
+ if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+ retval = -EINVAL;
+ goto done;
+ }
retval = si470x_set_freq(radio, freq->frequency);
+
+done:
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
": set frequency failed with %d\n", retval);
+ return retval;
+}
- return 0;
+
+/*
+ * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
+ */
+static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
+ struct v4l2_hw_freq_seek *seek)
+{
+ struct si470x_device *radio = video_get_drvdata(video_devdata(file));
+ int retval = 0;
+
+ /* safety checks */
+ if (radio->disconnected) {
+ retval = -EIO;
+ goto done;
+ }
+ if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) {
+ retval = -EINVAL;
+ goto done;
+ }
+
+ retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
+
+done:
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME
+ ": set hardware frequency seek failed with %d\n",
+ retval);
+ return retval;
}
@@ -1408,6 +1606,7 @@ static struct video_device si470x_viddev_template = {
.vidioc_s_tuner = si470x_vidioc_s_tuner,
.vidioc_g_frequency = si470x_vidioc_g_frequency,
.vidioc_s_frequency = si470x_vidioc_s_frequency,
+ .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
.owner = THIS_MODULE,
};
@@ -1424,31 +1623,36 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct si470x_device *radio;
- int retval = -ENOMEM;
+ int retval = 0;
- /* private data allocation */
+ /* private data allocation and initialization */
radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
- if (!radio)
+ if (!radio) {
+ retval = -ENOMEM;
goto err_initial;
+ }
+ radio->users = 0;
+ radio->disconnected = 0;
+ radio->usbdev = interface_to_usbdev(intf);
+ radio->intf = intf;
+ mutex_init(&radio->disconnect_lock);
+ mutex_init(&radio->lock);
- /* video device allocation */
+ /* video device allocation and initialization */
radio->videodev = video_device_alloc();
- if (!radio->videodev)
+ if (!radio->videodev) {
+ retval = -ENOMEM;
goto err_radio;
-
- /* initial configuration */
+ }
memcpy(radio->videodev, &si470x_viddev_template,
sizeof(si470x_viddev_template));
- radio->users = 0;
- radio->usbdev = interface_to_usbdev(intf);
- radio->intf = intf;
- mutex_init(&radio->lock);
video_set_drvdata(radio->videodev, radio);
/* show some infos about the specific device */
- retval = -EIO;
- if (si470x_get_all_registers(radio) < 0)
+ if (si470x_get_all_registers(radio) < 0) {
+ retval = -EIO;
goto err_all;
+ }
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
radio->registers[DEVICEID], radio->registers[CHIPID]);
@@ -1474,8 +1678,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* rds buffer allocation */
radio->buf_size = rds_buf * 3;
radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
- if (!radio->buffer)
+ if (!radio->buffer) {
+ retval = -EIO;
goto err_all;
+ }
/* rds buffer configuration */
radio->wr_index = 0;
@@ -1487,6 +1693,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
/* register video device */
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
+ retval = -EIO;
printk(KERN_WARNING DRIVER_NAME
": Could not register video device\n");
goto err_all;
@@ -1546,16 +1753,16 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf)
{
struct si470x_device *radio = usb_get_intfdata(intf);
- mutex_lock(&open_close_lock);
- radio->disconnected = 1;
+ mutex_lock(&radio->disconnect_lock);
+ radio->disconnected = 1;
cancel_delayed_work_sync(&radio->work);
usb_set_intfdata(intf, NULL);
- if (radio->users == 0) {
- video_unregister_device(radio->videodev);
- kfree(radio->buffer);
- kfree(radio);
- }
- mutex_unlock(&open_close_lock);
+ if (radio->users == 0) {
+ video_unregister_device(radio->videodev);
+ kfree(radio->buffer);
+ kfree(radio);
+ }
+ mutex_unlock(&radio->disconnect_lock);
}
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 5ccb0aeca8c..f606d2951fd 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -24,21 +24,21 @@ config VIDEOBUF_VMALLOC
select VIDEOBUF_GEN
tristate
+config VIDEOBUF_DMA_CONTIG
+ depends on HAS_DMA
+ select VIDEOBUF_GEN
+ tristate
+
config VIDEOBUF_DVB
tristate
select VIDEOBUF_GEN
- select VIDEOBUF_DMA_SG
config VIDEO_BTCX
tristate
-config VIDEO_IR_I2C
- tristate
-
config VIDEO_IR
tristate
depends on INPUT
- select VIDEO_IR_I2C if I2C
config VIDEO_TVEEPROM
tristate
@@ -84,6 +84,19 @@ config VIDEO_HELPER_CHIPS_AUTO
In doubt, say Y.
+config VIDEO_IR_I2C
+ tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO
+ depends on I2C && VIDEO_IR
+ default y
+ ---help---
+ Most boards have an IR chip directly connected via GPIO. However,
+ some video boards have the IR connected via I2C bus.
+
+ If your board doesn't have an I2C IR chip, you may disable this
+ option.
+
+ In doubt, say Y.
+
#
# Encoder / Decoder module configuration
#
@@ -600,9 +613,6 @@ config VIDEO_STRADIS
driver for PCI. There is a product page at
<http://www.stradis.com/>.
-config VIDEO_ZORAN_ZR36060
- tristate
-
config VIDEO_ZORAN
tristate "Zoran ZR36057/36067 Video For Linux"
depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS
@@ -616,61 +626,64 @@ config VIDEO_ZORAN
To compile this driver as a module, choose M here: the
module will be called zr36067.
+config VIDEO_ZORAN_DC30
+ tristate "Pinnacle/Miro DC30(+) support"
+ depends on VIDEO_ZORAN
+ select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO
+ help
+ Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
+ card. This also supports really old DC10 cards based on the
+ zr36050 MJPEG codec and zr36016 VFE.
+
+config VIDEO_ZORAN_ZR36060
+ tristate "Zoran ZR36060"
+ depends on VIDEO_ZORAN
+ help
+ Say Y to support Zoran boards based on 36060 chips.
+ This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33
+ and 33 R10 and AverMedia 6 boards.
+
config VIDEO_ZORAN_BUZ
tristate "Iomega Buz support"
- depends on VIDEO_ZORAN
+ depends on VIDEO_ZORAN_ZR36060
select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ZORAN_ZR36060
help
Support for the Iomega Buz MJPEG capture/playback card.
config VIDEO_ZORAN_DC10
tristate "Pinnacle/Miro DC10(+) support"
- depends on VIDEO_ZORAN
- select VIDEO_SAA7110
+ depends on VIDEO_ZORAN_ZR36060
+ select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ZORAN_ZR36060
help
Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback
card.
-config VIDEO_ZORAN_DC30
- tristate "Pinnacle/Miro DC30(+) support"
- depends on VIDEO_ZORAN
- select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO
- help
- Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
- card. This also supports really old DC10 cards based on the
- zr36050 MJPEG codec and zr36016 VFE.
-
config VIDEO_ZORAN_LML33
tristate "Linux Media Labs LML33 support"
- depends on VIDEO_ZORAN
+ depends on VIDEO_ZORAN_ZR36060
select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ZORAN_ZR36060
help
Support for the Linux Media Labs LML33 MJPEG capture/playback
card.
config VIDEO_ZORAN_LML33R10
tristate "Linux Media Labs LML33R10 support"
- depends on VIDEO_ZORAN
+ depends on VIDEO_ZORAN_ZR36060
select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ZORAN_ZR36060
help
support for the Linux Media Labs LML33R10 MJPEG capture/playback
card.
config VIDEO_ZORAN_AVS6EYES
tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
- depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1
+ depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1
select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_ZORAN_ZR36060
help
Support for the AverMedia 6 Eyes video surveillance card.
@@ -801,6 +814,8 @@ config USB_VIDEO_CLASS
For more information see: <http://linux-uvc.berlios.de/>
+source "drivers/media/video/gspca/Kconfig"
+
source "drivers/media/video/pvrusb2/Kconfig"
source "drivers/media/video/em28xx/Kconfig"
@@ -905,12 +920,21 @@ config USB_STKWEBCAM
To compile this driver as a module, choose M here: the
module will be called stkwebcam.
+config USB_S2255
+ tristate "USB Sensoray 2255 video capture device"
+ depends on VIDEO_V4L2
+ select VIDEOBUF_VMALLOC
+ default n
+ help
+ Say Y here if you want support for the Sensoray 2255 USB device.
+ This driver can be compiled as a module, called s2255drv.
+
endif # V4L_USB_DRIVERS
config SOC_CAMERA
tristate "SoC camera support"
depends on VIDEO_V4L2 && HAS_DMA
- select VIDEOBUF_DMA_SG
+ select VIDEOBUF_GEN
help
SoC Camera is a common API to several cameras, not connecting
over a bus like PCI or USB. For example some i2c camera connected
@@ -945,11 +969,26 @@ config MT9V022_PCA9536_SWITCH
Select this if your MT9V022 camera uses a PCA9536 I2C GPIO
extender to switch between 8 and 10 bit datawidth modes
+config SOC_CAMERA_PLATFORM
+ tristate "platform camera support"
+ depends on SOC_CAMERA
+ help
+ This is a generic SoC camera platform driver, useful for testing
+
config VIDEO_PXA27x
tristate "PXA27x Quick Capture Interface driver"
depends on VIDEO_DEV && PXA27x
select SOC_CAMERA
+ select VIDEOBUF_DMA_SG
---help---
This is a v4l2 driver for the PXA27x Quick Capture Interface
+config VIDEO_SH_MOBILE_CEU
+ tristate "SuperH Mobile CEU Interface driver"
+ depends on VIDEO_DEV
+ select SOC_CAMERA
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ This is a v4l2 driver for the SuperH Mobile CEU Interface
+
endif # VIDEO_CAPTURE_DRIVERS
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index ecbbfaab24d..45d5db5abb1 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o
obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
+obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o
obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
@@ -117,11 +118,13 @@ obj-$(CONFIG_USB_SN9C102) += sn9c102/
obj-$(CONFIG_USB_ET61X251) += et61x251/
obj-$(CONFIG_USB_PWC) += pwc/
obj-$(CONFIG_USB_ZC0301) += zc0301/
+obj-$(CONFIG_USB_GSPCA) += gspca/
obj-$(CONFIG_USB_IBMCAM) += usbvideo/
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
obj-$(CONFIG_USB_VICAM) += usbvideo/
obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
+obj-$(CONFIG_USB_S2255) += s2255drv.o
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_CX18) += cx18/
@@ -130,9 +133,11 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
obj-$(CONFIG_VIDEO_AU0828) += au0828/
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 8bfd5c75cb3..ddd2a7964de 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -516,7 +516,7 @@ bt819_detect_client (struct i2c_adapter *adapter,
dprintk(1,
KERN_INFO
- "saa7111.c: detecting bt819 client on address 0x%x\n",
+ "bt819: detecting bt819 client on address 0x%x\n",
address << 1);
/* Check if the adapter supports the needed features */
diff --git a/drivers/media/video/bt8xx/bt832.c b/drivers/media/video/bt8xx/bt832.c
index f92f06dec0d..216fc9680e8 100644
--- a/drivers/media/video/bt8xx/bt832.c
+++ b/drivers/media/video/bt8xx/bt832.c
@@ -179,7 +179,6 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1);
-
if(! bt832_init(&t->client)) {
bt832_detach(&t->client);
return -1;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 0165aac533b..0ea559a7fe5 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2448,7 +2448,7 @@ pix_format_set_size (struct v4l2_pix_format * f,
}
}
-static int bttv_g_fmt_cap(struct file *file, void *priv,
+static int bttv_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct bttv_fh *fh = priv;
@@ -2461,7 +2461,7 @@ static int bttv_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int bttv_g_fmt_overlay(struct file *file, void *priv,
+static int bttv_g_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
struct bttv_fh *fh = priv;
@@ -2472,7 +2472,7 @@ static int bttv_g_fmt_overlay(struct file *file, void *priv,
return 0;
}
-static int bttv_try_fmt_cap(struct file *file, void *priv,
+static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
const struct bttv_format *fmt;
@@ -2532,7 +2532,7 @@ static int bttv_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int bttv_try_fmt_overlay(struct file *file, void *priv,
+static int bttv_try_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
struct bttv_fh *fh = priv;
@@ -2542,7 +2542,7 @@ static int bttv_try_fmt_overlay(struct file *file, void *priv,
/* adjust_crop */ 0);
}
-static int bttv_s_fmt_cap(struct file *file, void *priv,
+static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
int retval;
@@ -2556,7 +2556,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
if (0 != retval)
return retval;
- retval = bttv_try_fmt_cap(file, priv, f);
+ retval = bttv_try_fmt_vid_cap(file, priv, f);
if (0 != retval)
return retval;
@@ -2591,7 +2591,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int bttv_s_fmt_overlay(struct file *file, void *priv,
+static int bttv_s_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
struct bttv_fh *fh = priv;
@@ -2661,7 +2661,7 @@ static int bttv_querycap(struct file *file, void *priv,
return 0;
}
-static int bttv_enum_fmt_vbi(struct file *file, void *priv,
+static int bttv_enum_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (0 != f->index)
@@ -2692,7 +2692,7 @@ static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f)
return i;
}
-static int bttv_enum_fmt_cap(struct file *file, void *priv,
+static int bttv_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
int rc = bttv_enum_fmt_cap_ovr(f);
@@ -2703,7 +2703,7 @@ static int bttv_enum_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int bttv_enum_fmt_overlay(struct file *file, void *priv,
+static int bttv_enum_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
int rc;
@@ -3362,18 +3362,18 @@ static struct video_device bttv_video_template =
.fops = &bttv_fops,
.minor = -1,
.vidioc_querycap = bttv_querycap,
- .vidioc_enum_fmt_cap = bttv_enum_fmt_cap,
- .vidioc_g_fmt_cap = bttv_g_fmt_cap,
- .vidioc_try_fmt_cap = bttv_try_fmt_cap,
- .vidioc_s_fmt_cap = bttv_s_fmt_cap,
- .vidioc_enum_fmt_overlay = bttv_enum_fmt_overlay,
- .vidioc_g_fmt_overlay = bttv_g_fmt_overlay,
- .vidioc_try_fmt_overlay = bttv_try_fmt_overlay,
- .vidioc_s_fmt_overlay = bttv_s_fmt_overlay,
- .vidioc_enum_fmt_vbi = bttv_enum_fmt_vbi,
- .vidioc_g_fmt_vbi = bttv_g_fmt_vbi,
- .vidioc_try_fmt_vbi = bttv_try_fmt_vbi,
- .vidioc_s_fmt_vbi = bttv_s_fmt_vbi,
+ .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = bttv_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = bttv_s_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_overlay = bttv_enum_fmt_vid_overlay,
+ .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay,
+ .vidioc_enum_fmt_vbi_cap = bttv_enum_fmt_vbi_cap,
+ .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap,
+ .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap,
+ .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap,
.vidioc_g_audio = bttv_g_audio,
.vidioc_s_audio = bttv_s_audio,
.vidioc_cropcap = bttv_cropcap,
@@ -3705,7 +3705,7 @@ static void bttv_risc_disasm(struct bttv *btv,
for (i = 0; i < (risc->size >> 2); i += n) {
printk("%s: 0x%lx: ", btv->c.name,
(unsigned long)(risc->dma + (i<<2)));
- n = bttv_risc_decode(risc->cpu[i]);
+ n = bttv_risc_decode(le32_to_cpu(risc->cpu[i]));
for (j = 1; j < n; j++)
printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
@@ -3774,8 +3774,8 @@ static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
btv->c.nr,
(unsigned long)btv->main.dma,
- (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1],
- (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1],
+ (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_VBI+1]),
+ (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_FIELD+1]),
(unsigned long)rc);
if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
@@ -4188,6 +4188,7 @@ static struct video_device *vdev_init(struct bttv *btv,
vfd->dev = &btv->c.pci->dev;
vfd->release = video_device_release;
vfd->type = type;
+ vfd->debug = bttv_debug;
snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
type_name, bttv_tvcards[btv->c.type].name);
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index 4d5b8035e46..bcd2cd240a1 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -36,11 +36,6 @@
#include <linux/jiffies.h>
#include <asm/io.h>
-static struct i2c_algo_bit_data bttv_i2c_algo_bit_template;
-static struct i2c_adapter bttv_i2c_adap_sw_template;
-static struct i2c_adapter bttv_i2c_adap_hw_template;
-static struct i2c_client bttv_i2c_client_template;
-
static int attach_inform(struct i2c_client *client);
static int i2c_debug;
@@ -104,7 +99,7 @@ static int bttv_bit_getsda(void *data)
return state;
}
-static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
+static struct i2c_algo_bit_data __devinitdata bttv_i2c_algo_bit_template = {
.setsda = bttv_bit_setsda,
.setscl = bttv_bit_setscl,
.getsda = bttv_bit_getsda,
@@ -113,14 +108,6 @@ static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
.timeout = 200,
};
-static struct i2c_adapter bttv_i2c_adap_sw_template = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
- .name = "bttv",
- .id = I2C_HW_B_BT848,
- .client_register = attach_inform,
-};
-
/* ----------------------------------------------------------------------- */
/* I2C functions - hardware i2c */
@@ -270,20 +257,11 @@ static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int
return retval;
}
-static struct i2c_algorithm bttv_algo = {
+static const struct i2c_algorithm bttv_algo = {
.master_xfer = bttv_i2c_xfer,
.functionality = functionality,
};
-static struct i2c_adapter bttv_i2c_adap_hw_template = {
- .owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
- .name = "bt878",
- .id = I2C_HW_B_BT848 /* FIXME */,
- .algo = &bttv_algo,
- .client_register = attach_inform,
-};
-
/* ----------------------------------------------------------------------- */
/* I2C functions - common stuff */
@@ -332,10 +310,6 @@ void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
}
-static struct i2c_client bttv_i2c_client_template = {
- .name = "bttv internal",
-};
-
/* read I2C */
int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
@@ -417,29 +391,34 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
/* init + register i2c algo-bit adapter */
int __devinit init_bttv_i2c(struct bttv *btv)
{
- memcpy(&btv->i2c_client, &bttv_i2c_client_template,
- sizeof(bttv_i2c_client_template));
+ strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);
if (i2c_hw)
btv->use_i2c_hw = 1;
if (btv->use_i2c_hw) {
/* bt878 */
- memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_hw_template,
- sizeof(bttv_i2c_adap_hw_template));
+ strlcpy(btv->c.i2c_adap.name, "bt878",
+ sizeof(btv->c.i2c_adap.name));
+ btv->c.i2c_adap.id = I2C_HW_B_BT848; /* FIXME */
+ btv->c.i2c_adap.algo = &bttv_algo;
} else {
/* bt848 */
/* Prevents usage of invalid delay values */
if (i2c_udelay<5)
i2c_udelay=5;
- bttv_i2c_algo_bit_template.udelay=i2c_udelay;
- memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template,
- sizeof(bttv_i2c_adap_sw_template));
+ strlcpy(btv->c.i2c_adap.name, "bttv",
+ sizeof(btv->c.i2c_adap.name));
+ btv->c.i2c_adap.id = I2C_HW_B_BT848;
memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
sizeof(bttv_i2c_algo_bit_template));
+ btv->i2c_algo.udelay = i2c_udelay;
btv->i2c_algo.data = btv;
btv->c.i2c_adap.algo_data = &btv->i2c_algo;
}
+ btv->c.i2c_adap.owner = THIS_MODULE;
+ btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG;
+ btv->c.i2c_adap.client_register = attach_inform;
btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index bfdbc469e30..68f28e5fa04 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -303,7 +303,7 @@ static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm,
return 0;
}
-int bttv_try_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
+int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
{
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
@@ -321,7 +321,7 @@ int bttv_try_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
}
-int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
+int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
{
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
@@ -369,7 +369,7 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
}
-int bttv_g_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt)
+int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
{
struct bttv_fh *fh = f;
const struct bttv_tvnorm *tvnorm;
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index f2393202904..6d93d16c96e 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -299,7 +299,6 @@ extern int bttv_write_gpio(unsigned int card,
/* ---------------------------------------------------------- */
/* sysfs/driver-moded based gpio access interface */
-
struct bttv_sub_device {
struct device dev;
struct bttv_core *core;
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 27da7b42327..08ef54a22c9 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -39,7 +39,6 @@
#include <linux/scatterlist.h>
#include <asm/io.h>
#include <media/v4l2-common.h>
-
#include <linux/device.h>
#include <media/videobuf-dma-sg.h>
#include <media/tveeprom.h>
@@ -254,21 +253,19 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
/* ---------------------------------------------------------- */
/* bttv-vbi.c */
-int bttv_try_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f);
-int bttv_g_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f);
-int bttv_s_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f);
+int bttv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
+int bttv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
+int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
extern struct videobuf_queue_ops bttv_vbi_qops;
/* ---------------------------------------------------------- */
/* bttv-gpio.c */
-
extern struct bus_type bttv_sub_bus_type;
int bttv_sub_add_device(struct bttv_core *core, char *name);
int bttv_sub_del_devices(struct bttv_core *core);
-
/* ---------------------------------------------------------- */
/* bttv-driver.c */
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 5195b1f3378..d99453faaab 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1593,7 +1593,7 @@ static struct v4l2_pix_format cafe_def_pix_format = {
.sizeimage = VGA_WIDTH*VGA_HEIGHT*2,
};
-static int cafe_vidioc_enum_fmt_cap(struct file *filp,
+static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_fmtdesc *fmt)
{
struct cafe_camera *cam = priv;
@@ -1608,7 +1608,7 @@ static int cafe_vidioc_enum_fmt_cap(struct file *filp,
}
-static int cafe_vidioc_try_fmt_cap (struct file *filp, void *priv,
+static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *fmt)
{
struct cafe_camera *cam = priv;
@@ -1620,7 +1620,7 @@ static int cafe_vidioc_try_fmt_cap (struct file *filp, void *priv,
return ret;
}
-static int cafe_vidioc_s_fmt_cap(struct file *filp, void *priv,
+static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *fmt)
{
struct cafe_camera *cam = priv;
@@ -1635,7 +1635,7 @@ static int cafe_vidioc_s_fmt_cap(struct file *filp, void *priv,
/*
* See if the formatting works in principle.
*/
- ret = cafe_vidioc_try_fmt_cap(filp, priv, fmt);
+ ret = cafe_vidioc_try_fmt_vid_cap(filp, priv, fmt);
if (ret)
return ret;
/*
@@ -1670,7 +1670,7 @@ static int cafe_vidioc_s_fmt_cap(struct file *filp, void *priv,
* The V4l2 spec wants us to be smarter, and actually get this from
* the camera (and not mess with it at open time). Someday.
*/
-static int cafe_vidioc_g_fmt_cap(struct file *filp, void *priv,
+static int cafe_vidioc_g_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *f)
{
struct cafe_camera *cam = priv;
@@ -1780,10 +1780,10 @@ static struct video_device cafe_v4l_template = {
.release = cafe_v4l_dev_release,
.vidioc_querycap = cafe_vidioc_querycap,
- .vidioc_enum_fmt_cap = cafe_vidioc_enum_fmt_cap,
- .vidioc_try_fmt_cap = cafe_vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = cafe_vidioc_s_fmt_cap,
- .vidioc_g_fmt_cap = cafe_vidioc_g_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = cafe_vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = cafe_vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = cafe_vidioc_g_fmt_vid_cap,
.vidioc_enum_input = cafe_vidioc_enum_input,
.vidioc_g_input = cafe_vidioc_g_input,
.vidioc_s_input = cafe_vidioc_s_input,
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
index cefd1381e8d..54de0cd482e 100644
--- a/drivers/media/video/compat_ioctl32.c
+++ b/drivers/media/video/compat_ioctl32.c
@@ -884,6 +884,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_G_INPUT32:
case VIDIOC_S_INPUT32:
case VIDIOC_TRY_FMT32:
+ case VIDIOC_S_HW_FREQ_SEEK:
ret = do_video_ioctl(file, cmd, arg);
break;
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 03411503457..1c3fa3a7470 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -173,4 +173,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.probe = cs5345_probe,
.id_table = cs5345_id,
};
-
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index d965af860ab..645b339152d 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -43,7 +43,6 @@ MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
-
I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -189,4 +188,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.probe = cs53l32a_probe,
.id_table = cs53l32a_id,
};
-
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 1adc404d955..6d5b94fc708 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -26,13 +26,17 @@
#include "cx18-cards.h"
#include "cx18-audio.h"
+#define CX18_AUDIO_ENABLE 0xc72014
+
/* Selects the audio input and output according to the current
settings. */
int cx18_audio_set_io(struct cx18 *cx)
{
struct v4l2_routing route;
u32 audio_input;
+ u32 val;
int mux_input;
+ int err;
/* Determine which input to use */
if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
@@ -51,8 +55,17 @@ int cx18_audio_set_io(struct cx18 *cx)
cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
route.input = audio_input;
- return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
+ err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ if (err)
+ return err;
+
+ val = read_reg(CX18_AUDIO_ENABLE) & ~0x30;
+ val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
+ (audio_input << 4);
+ write_reg(val | 0xb00, CX18_AUDIO_ENABLE);
+ cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
+ return 0;
}
void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index 2dc3a5dd170..c40a286de1b 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -34,7 +34,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
cx18_av_write(cx, 0x127, 0x50);
- if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
switch (freq) {
case 32000:
/* VID_PLL and AUX_PLL */
@@ -148,7 +148,7 @@ void cx18_av_audio_set_path(struct cx18 *cx)
/* Mute everything to prevent the PFFT! */
cx18_av_write(cx, 0x8d3, 0x1f);
- if (state->aud_input == CX18_AV_AUDIO_SERIAL) {
+ if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
/* Set Path1 to Serial Audio Input */
cx18_av_write4(cx, 0x8d0, 0x01011012);
@@ -165,7 +165,7 @@ void cx18_av_audio_set_path(struct cx18 *cx)
/* deassert soft reset */
cx18_av_and_or(cx, 0x810, ~0x1, 0x00);
- if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
/* When the microcontroller detects the
* audio format, it will unmute the lines */
cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
@@ -271,7 +271,7 @@ static void set_mute(struct cx18 *cx, int mute)
{
struct cx18_av_state *state = &cx->av_state;
- if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
/* Must turn off microcontroller in order to mute sound.
* Not sure if this is the best method, but it does work.
* If the microcontroller is running, then it will undo any
@@ -298,14 +298,14 @@ int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
switch (cmd) {
case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- if (state->aud_input != CX18_AV_AUDIO_SERIAL) {
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
cx18_av_and_or(cx, 0x803, ~0x10, 0);
cx18_av_write(cx, 0x8d3, 0x1f);
}
cx18_av_and_or(cx, 0x810, ~0x1, 1);
retval = set_audclk_freq(cx, *(u32 *)arg);
cx18_av_and_or(cx, 0x810, ~0x1, 0);
- if (state->aud_input != CX18_AV_AUDIO_SERIAL)
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2)
cx18_av_and_or(cx, 0x803, ~0x10, 0x10);
return retval;
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index faca43eb940..3b0a2c45060 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -69,58 +69,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value);
}
-int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask)
-{
- int retval;
- u32 saved_reg[8] = {0};
-
- if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
- saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL);
- saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL);
- }
-
- if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
- saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1);
- saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC);
- }
-
- if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
- saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL);
- saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL);
- saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG);
- saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG);
- }
-
- retval = cx18_av_write(cx, addr, value);
-
- if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
- cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]);
- cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]);
- }
-
- if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]);
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]);
- }
-
- if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
- cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]);
- cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]);
- cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]);
- cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]);
- }
-
- return retval;
-}
-
-int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask,
- u8 or_value, int no_acfg_mask)
-{
- return cx18_av_write_no_acfg(cx, addr,
- (cx18_av_read(cx, addr) & and_mask) |
- or_value, no_acfg_mask);
-}
-
/* ----------------------------------------------------------------------- */
static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
@@ -132,6 +80,7 @@ static void log_video_status(struct cx18 *cx);
static void cx18_av_initialize(struct cx18 *cx)
{
+ struct cx18_av_state *state = &cx->av_state;
u32 v;
cx18_av_loadfw(cx);
@@ -211,6 +160,149 @@ static void cx18_av_initialize(struct cx18 *cx)
/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
/* } */
cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
+ state->default_volume = 228 - cx18_av_read(cx, 0x8d4);
+ state->default_volume = ((state->default_volume / 2) + 23) << 9;
+}
+
+/* ----------------------------------------------------------------------- */
+
+void cx18_av_std_setup(struct cx18 *cx)
+{
+ struct cx18_av_state *state = &cx->av_state;
+ v4l2_std_id std = state->std;
+ int hblank, hactive, burst, vblank, vactive, sc;
+ int vblank656, src_decimation;
+ int luma_lpf, uv_lpf, comb;
+ u32 pll_int, pll_frac, pll_post;
+
+ /* datasheet startup, step 8d */
+ if (std & ~V4L2_STD_NTSC)
+ cx18_av_write(cx, 0x49f, 0x11);
+ else
+ cx18_av_write(cx, 0x49f, 0x14);
+
+ if (std & V4L2_STD_625_50) {
+ hblank = 132;
+ hactive = 720;
+ burst = 93;
+ vblank = 36;
+ vactive = 580;
+ vblank656 = 40;
+ src_decimation = 0x21f;
+
+ luma_lpf = 2;
+ if (std & V4L2_STD_PAL) {
+ uv_lpf = 1;
+ comb = 0x20;
+ sc = 688739;
+ } else if (std == V4L2_STD_PAL_Nc) {
+ uv_lpf = 1;
+ comb = 0x20;
+ sc = 556453;
+ } else { /* SECAM */
+ uv_lpf = 0;
+ comb = 0;
+ sc = 672351;
+ }
+ } else {
+ hactive = 720;
+ hblank = 122;
+ vactive = 487;
+ luma_lpf = 1;
+ uv_lpf = 1;
+ vblank = 26;
+ vblank656 = 26;
+
+ src_decimation = 0x21f;
+ if (std == V4L2_STD_PAL_60) {
+ burst = 0x5b;
+ luma_lpf = 2;
+ comb = 0x20;
+ sc = 688739;
+ } else if (std == V4L2_STD_PAL_M) {
+ burst = 0x61;
+ comb = 0x20;
+ sc = 555452;
+ } else {
+ burst = 0x5b;
+ comb = 0x66;
+ sc = 556063;
+ }
+ }
+
+ /* DEBUG: Displays configured PLL frequency */
+ pll_int = cx18_av_read(cx, 0x108);
+ pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
+ pll_post = cx18_av_read(cx, 0x109);
+ CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
+ pll_int, pll_frac, pll_post);
+
+ if (pll_post) {
+ int fin, fsc;
+ int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
+
+ pll >>= 25;
+ pll /= pll_post;
+ CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
+ pll / 1000000, pll % 1000000);
+ CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
+ pll / 8000000, (pll / 8) % 1000000);
+
+ fin = ((u64)src_decimation * pll) >> 12;
+ CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
+ fin / 1000000, fin % 1000000);
+
+ fsc = (((u64)sc) * pll) >> 24L;
+ CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
+ fsc / 1000000, fsc % 1000000);
+
+ CX18_DEBUG_INFO("hblank %i, hactive %i, "
+ "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
+ "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
+ " sc 0x%06x\n",
+ hblank, hactive, vblank, vactive, vblank656,
+ src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+ }
+
+ /* Sets horizontal blanking delay and active lines */
+ cx18_av_write(cx, 0x470, hblank);
+ cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
+ (hactive << 4)));
+ cx18_av_write(cx, 0x472, hactive >> 4);
+
+ /* Sets burst gate delay */
+ cx18_av_write(cx, 0x473, burst);
+
+ /* Sets vertical blanking delay and active duration */
+ cx18_av_write(cx, 0x474, vblank);
+ cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
+ (vactive << 4)));
+ cx18_av_write(cx, 0x476, vactive >> 4);
+ cx18_av_write(cx, 0x477, vblank656);
+
+ /* Sets src decimation rate */
+ cx18_av_write(cx, 0x478, 0xff & src_decimation);
+ cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
+
+ /* Sets Luma and UV Low pass filters */
+ cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
+
+ /* Enables comb filters */
+ cx18_av_write(cx, 0x47b, comb);
+
+ /* Sets SC Step*/
+ cx18_av_write(cx, 0x47c, sc);
+ cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
+ cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
+
+ /* Sets VBI parameters */
+ if (std & V4L2_STD_625_50) {
+ cx18_av_write(cx, 0x47f, 0x01);
+ state->vbi_line_offset = 5;
+ } else {
+ cx18_av_write(cx, 0x47f, 0x00);
+ state->vbi_line_offset = 8;
+ }
}
/* ----------------------------------------------------------------------- */
@@ -221,16 +313,9 @@ static void input_change(struct cx18 *cx)
v4l2_std_id std = state->std;
/* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
- if (std & V4L2_STD_SECAM)
- cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL);
- else {
- cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL);
- cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
- }
- cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0,
- CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
- cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60,
- CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
+ cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
+ cx18_av_and_or(cx, 0x401, ~0x60, 0);
+ cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
if (std & V4L2_STD_525_60) {
if (std == V4L2_STD_NTSC_M_JP) {
@@ -300,7 +385,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
}
switch (aud_input) {
- case CX18_AV_AUDIO_SERIAL:
+ case CX18_AV_AUDIO_SERIAL1:
+ case CX18_AV_AUDIO_SERIAL2:
/* do nothing, use serial audio input */
break;
case CX18_AV_AUDIO4: reg &= ~0x30; break;
@@ -316,8 +402,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
cx18_av_write(cx, 0x103, reg);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
- cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02,
- CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
+ cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
@@ -373,13 +458,13 @@ static int set_v4lstd(struct cx18 *cx)
This happens for example with the Yuan MPC622. */
if (fmt >= 4 && fmt < 8) {
/* Set format to NTSC-M */
- cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE);
+ cx18_av_and_or(cx, 0x400, ~0xf, 1);
/* Turn off LCOMB */
cx18_av_and_or(cx, 0x47b, ~6, 0);
}
- cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE);
- cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL);
- cx18_av_vbi_setup(cx);
+ cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
+ cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
+ cx18_av_std_setup(cx);
input_change(cx);
return 0;
}
@@ -618,6 +703,8 @@ int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
switch (qc->id) {
case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535,
+ 65535 / 100, state->default_volume);
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index c172823ce1d..eb61fa1e096 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -62,7 +62,8 @@ enum cx18_av_video_input {
enum cx18_av_audio_input {
/* Audio inputs: serial or In4-In8 */
- CX18_AV_AUDIO_SERIAL,
+ CX18_AV_AUDIO_SERIAL1,
+ CX18_AV_AUDIO_SERIAL2,
CX18_AV_AUDIO4 = 4,
CX18_AV_AUDIO5,
CX18_AV_AUDIO6,
@@ -78,6 +79,7 @@ struct cx18_av_state {
u32 audclk_freq;
int audmode;
int vbi_line_offset;
+ int default_volume;
u32 id;
u32 rev;
int is_initialized;
@@ -295,25 +297,16 @@ struct cx18_av_state {
#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
-/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/
-#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */
-#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */
-#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */
-#define CXADEC_NO_ACFG_ALL 0x07
-
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
-int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value,
- int no_acfg_mask);
u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
-int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value,
- int no_acfg_mask);
int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
+void cx18_av_std_setup(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-firmware.c */
@@ -326,7 +319,6 @@ void cx18_av_audio_set_path(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-vbi.c */
-void cx18_av_vbi_setup(struct cx18 *cx);
int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index a1a6af6c1c8..834b9248242 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -22,6 +22,7 @@
#include "cx18-driver.h"
#include <linux/firmware.h>
+#define CX18_AUDIO_ENABLE 0xc72014
#define FWFILE "v4l-cx23418-dig.fw"
int cx18_av_loadfw(struct cx18 *cx)
@@ -31,40 +32,58 @@ int cx18_av_loadfw(struct cx18 *cx)
u32 v;
const u8 *ptr;
int i;
+ int retries = 0;
if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
CX18_ERR("unable to open firmware %s\n", FWFILE);
return -EINVAL;
}
- cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
- cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); /* Byte 0 */
-
- /* Reset the Mako core (Register is undocumented.) */
- cx18_av_write4(cx, 0x8100, 0x00010000);
-
- /* Put the 8051 in reset and enable firmware upload */
- cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000);
-
- ptr = fw->data;
- size = fw->size;
-
- for (i = 0; i < size; i++) {
- u32 dl_control = 0x0F000000 | ((u32)ptr[i] << 16);
- u32 value = 0;
- int retries;
-
- for (retries = 0; retries < 5; retries++) {
- cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
- value = cx18_av_read4(cx, CXADEC_DL_CTL);
- if ((value & 0x3F00) == (dl_control & 0x3F00))
+ /* The firmware load often has byte errors, so allow for several
+ retries, both at byte level and at the firmware load level. */
+ while (retries < 5) {
+ cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000);
+ cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6);
+
+ /* Reset the Mako core (Register is undocumented.) */
+ cx18_av_write4(cx, 0x8100, 0x00010000);
+
+ /* Put the 8051 in reset and enable firmware upload */
+ cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000);
+
+ ptr = fw->data;
+ size = fw->size;
+
+ for (i = 0; i < size; i++) {
+ u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16);
+ u32 value = 0;
+ int retries;
+
+ for (retries = 0; retries < 5; retries++) {
+ cx18_av_write4(cx, CXADEC_DL_CTL, dl_control);
+ udelay(10);
+ value = cx18_av_read4(cx, CXADEC_DL_CTL);
+ if (value == dl_control)
+ break;
+ /* Check if we can correct the byte by changing
+ the address. We can only write the lower
+ address byte of the address. */
+ if ((value & 0x3F00) != (dl_control & 0x3F00)) {
+ retries = 5;
+ break;
+ }
+ }
+ if (retries >= 5)
break;
}
- if (retries >= 5) {
- CX18_ERR("unable to load firmware %s\n", FWFILE);
- release_firmware(fw);
- return -EIO;
- }
+ if (i == size)
+ break;
+ retries++;
+ }
+ if (retries >= 5) {
+ CX18_ERR("unable to load firmware %s\n", FWFILE);
+ release_firmware(fw);
+ return -EIO;
}
cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size);
@@ -100,7 +119,6 @@ int cx18_av_loadfw(struct cx18 *cx)
have a name in the spec. */
cx18_av_write4(cx, 0x09CC, 1);
-#define CX18_AUDIO_ENABLE 0xc72014
v = read_reg(CX18_AUDIO_ENABLE);
/* If bit 11 is 1 */
if (v & 0x800)
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index d09f1daf4eb..02fdf57bb67 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -83,150 +83,6 @@ static int decode_vps(u8 *dst, u8 *p)
return err & 0xf0;
}
-void cx18_av_vbi_setup(struct cx18 *cx)
-{
- struct cx18_av_state *state = &cx->av_state;
- v4l2_std_id std = state->std;
- int hblank, hactive, burst, vblank, vactive, sc;
- int vblank656, src_decimation;
- int luma_lpf, uv_lpf, comb;
- u32 pll_int, pll_frac, pll_post;
-
- /* datasheet startup, step 8d */
- if (std & ~V4L2_STD_NTSC)
- cx18_av_write(cx, 0x49f, 0x11);
- else
- cx18_av_write(cx, 0x49f, 0x14);
-
- if (std & V4L2_STD_625_50) {
- hblank = 0x084;
- hactive = 0x2d0;
- burst = 0x5d;
- vblank = 0x024;
- vactive = 0x244;
- vblank656 = 0x28;
- src_decimation = 0x21f;
-
- luma_lpf = 2;
- if (std & V4L2_STD_SECAM) {
- uv_lpf = 0;
- comb = 0;
- sc = 0x0a425f;
- } else if (std == V4L2_STD_PAL_Nc) {
- uv_lpf = 1;
- comb = 0x20;
- sc = 556453;
- } else {
- uv_lpf = 1;
- comb = 0x20;
- sc = 0x0a8263;
- }
- } else {
- hactive = 720;
- hblank = 122;
- vactive = 487;
- luma_lpf = 1;
- uv_lpf = 1;
-
- src_decimation = 0x21f;
- if (std == V4L2_STD_PAL_60) {
- vblank = 26;
- vblank656 = 26;
- burst = 0x5b;
- luma_lpf = 2;
- comb = 0x20;
- sc = 0x0a8263;
- } else if (std == V4L2_STD_PAL_M) {
- vblank = 20;
- vblank656 = 24;
- burst = 0x61;
- comb = 0x20;
-
- sc = 555452;
- } else {
- vblank = 26;
- vblank656 = 26;
- burst = 0x5b;
- comb = 0x66;
- sc = 556063;
- }
- }
-
- /* DEBUG: Displays configured PLL frequency */
- pll_int = cx18_av_read(cx, 0x108);
- pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
- pll_post = cx18_av_read(cx, 0x109);
- CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
-
- if (pll_post) {
- int fin, fsc;
- int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac);
-
- pll >>= 25;
- pll /= pll_post;
- CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
- pll / 8000000, (pll / 8) % 1000000);
-
- fin = ((u64)src_decimation * pll) >> 12;
- CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
- fin / 1000000, fin % 1000000);
-
- fsc = (((u64)sc) * pll) >> 24L;
- CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
- fsc / 1000000, fsc % 1000000);
-
- CX18_DEBUG_INFO("hblank %i, hactive %i, "
- "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
- " sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
- }
-
- /* Sets horizontal blanking delay and active lines */
- cx18_av_write(cx, 0x470, hblank);
- cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) |
- (hactive << 4)));
- cx18_av_write(cx, 0x472, hactive >> 4);
-
- /* Sets burst gate delay */
- cx18_av_write(cx, 0x473, burst);
-
- /* Sets vertical blanking delay and active duration */
- cx18_av_write(cx, 0x474, vblank);
- cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) |
- (vactive << 4)));
- cx18_av_write(cx, 0x476, vactive >> 4);
- cx18_av_write(cx, 0x477, vblank656);
-
- /* Sets src decimation rate */
- cx18_av_write(cx, 0x478, 0xff & src_decimation);
- cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8));
-
- /* Sets Luma and UV Low pass filters */
- cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
-
- /* Enables comb filters */
- cx18_av_write(cx, 0x47b, comb);
-
- /* Sets SC Step*/
- cx18_av_write(cx, 0x47c, sc);
- cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
- cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
-
- /* Sets VBI parameters */
- if (std & V4L2_STD_625_50) {
- cx18_av_write(cx, 0x47f, 0x01);
- state->vbi_line_offset = 5;
- } else {
- cx18_av_write(cx, 0x47f, 0x00);
- state->vbi_line_offset = 8;
- }
-}
-
int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
{
struct cx18_av_state *state = &cx->av_state;
@@ -292,8 +148,8 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
/* raw VBI */
memset(svbi, 0, sizeof(*svbi));
- /* Setup VBI */
- cx18_av_vbi_setup(cx);
+ /* Setup standard */
+ cx18_av_std_setup(cx);
/* VBI Offset */
cx18_av_write(cx, 0x47f, vbi_offset);
@@ -304,8 +160,8 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
for (x = 0; x <= 23; x++)
lcr[x] = 0x00;
- /* Setup VBI */
- cx18_av_vbi_setup(cx);
+ /* Setup standard */
+ cx18_av_std_setup(cx);
/* Sliced VBI */
cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index c26e0ef5b07..8fe5f38c4d7 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -27,6 +27,8 @@
#include "cx18-i2c.h"
#include <media/cs5345.h>
+#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
+
/********************** card configuration *******************************/
/* usual i2c tuner addresses to probe */
@@ -65,12 +67,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
{ CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
+ CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
{ CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
+ CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
+ CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
.ddr = {
/* ESMT M13S128324A-5B memory */
.chip_config = 0x003,
@@ -86,6 +88,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
.active_lo_mask = 0x3001,
.msecs_asserted = 10,
.msecs_recovery = 40,
+ .ir_reset_mask = 0x0001,
},
.i2c = &cx18_i2c_std,
};
@@ -110,12 +113,12 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
{ CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
+ CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
{ CX18_CARD_INPUT_LINE_IN2,
- CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
+ CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
+ CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
.ddr = {
/* Samsung K4D263238G-VC33 memory */
.chip_config = 0x003,
@@ -131,6 +134,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
.active_lo_mask = 0x3001,
.msecs_asserted = 10,
.msecs_recovery = 40,
+ .ir_reset_mask = 0x0001,
},
.i2c = &cx18_i2c_std,
};
@@ -161,10 +165,10 @@ static const struct cx18_card cx18_card_h900 = {
{ CX18_CARD_INPUT_AUD_TUNER,
CX18_AV_AUDIO8, 0 },
{ CX18_CARD_INPUT_LINE_IN1,
- CX18_AV_AUDIO_SERIAL, 0 },
+ CX18_AV_AUDIO_SERIAL1, 0 },
},
.radio_input = { CX18_CARD_INPUT_AUD_TUNER,
- CX18_AV_AUDIO_SERIAL, 0 },
+ CX18_AV_AUDIO_SERIAL1, 0 },
.tuners = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
},
@@ -194,7 +198,7 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
static const struct cx18_card cx18_card_mpc718 = {
.type = CX18_CARD_YUAN_MPC718,
.name = "Yuan MPC718",
- .comment = "Some Composite and S-Video inputs are currently working.\n",
+ .comment = "Analog video capture works; some audio line in may not.\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
@@ -209,11 +213,11 @@ static const struct cx18_card cx18_card_mpc718 = {
{ CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 },
},
.audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
- { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 },
- { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 },
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 0 },
+ { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL1, 0 },
},
- .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 },
+ .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 0 },
.tuners = {
/* XC3028 tuner */
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
@@ -227,16 +231,73 @@ static const struct cx18_card cx18_card_mpc718 = {
.tune_lane = 0,
.initial_emrs = 2,
},
- .xceive_pin = 15,
+ .xceive_pin = 0,
.pci_list = cx18_pci_mpc718,
.i2c = &cx18_i2c_std,
};
+/* ------------------------------------------------------------------------- */
+
+/* Conexant Raptor PAL/SECAM: note that this card is analog only! */
+
+static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 },
+ { 0, 0, 0 }
+};
+
+static const struct cx18_card cx18_card_cnxt_raptor_pal = {
+ .type = CX18_CARD_CNXT_RAPTOR_PAL,
+ .name = "Conexant Raptor PAL/SECAM",
+ .comment = "VBI is not yet supported\n",
+ .v4l2_capabilities = CX18_CAP_ENCODER,
+ .hw_audio_ctrl = CX18_HW_CX23418,
+ .hw_muxer = CX18_HW_GPIO,
+ .hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+ .video_inputs = {
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
+ { CX18_CARD_INPUT_SVIDEO1, 1,
+ CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
+ { CX18_CARD_INPUT_SVIDEO2, 2,
+ CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
+ { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
+ },
+ .audio_inputs = {
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
+ { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
+ },
+ .tuners = {
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ },
+ .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 },
+ .ddr = {
+ /* MT 46V16M16 memory */
+ .chip_config = 0x50306,
+ .refresh = 0x753,
+ .timing1 = 0x33220953,
+ .timing2 = 0x09,
+ .tune_lane = 0,
+ .initial_emrs = 0,
+ },
+ .gpio_init.initial_value = 0x1002,
+ .gpio_init.direction = 0xf002,
+ .gpio_audio_input = { .mask = 0xf002,
+ .tuner = 0x1002, /* LED D1 Tuner AF */
+ .linein = 0x2000, /* LED D2 Line In 1 */
+ .radio = 0x4002 }, /* LED D3 Tuner AF */
+ .pci_list = cx18_pci_cnxt_raptor_pal,
+ .i2c = &cx18_i2c_std,
+};
+
+/* ------------------------------------------------------------------------- */
+
static const struct cx18_card *cx18_card_list[] = {
&cx18_card_hvr1600_esmt,
&cx18_card_hvr1600_samsung,
&cx18_card_h900,
&cx18_card_mpc718,
+ &cx18_card_cnxt_raptor_pal,
};
const struct cx18_card *cx18_get_card(u16 index)
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index dc2dd945d4c..32155f6e6fe 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -83,6 +83,14 @@ struct cx18_gpio_i2c_slave_reset {
u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
int msecs_asserted; /* time period reset must remain asserted */
int msecs_recovery; /* time after deassert for chips to be ready */
+ u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */
+};
+
+struct cx18_gpio_audio_input { /* select tuner/line in input */
+ u32 mask; /* leave to 0 if not supported */
+ u32 tuner;
+ u32 linein;
+ u32 radio;
};
struct cx18_card_tuner {
@@ -123,6 +131,7 @@ struct cx18_card {
u8 xceive_pin; /* XCeive tuner GPIO reset pin */
struct cx18_gpio_init gpio_init;
struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
+ struct cx18_gpio_audio_input gpio_audio_input;
struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
struct cx18_card_tuner_i2c *i2c;
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 87cf4102166..f46c7e5ed74 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -51,12 +51,11 @@ static const u32 *ctrl_classes[] = {
NULL
};
-static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl)
+int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
const char *name;
- CX18_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
-
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
@@ -91,21 +90,35 @@ static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl)
return 0;
}
-static int cx18_querymenu(struct cx18 *cx, struct v4l2_querymenu *qmenu)
+int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
struct v4l2_queryctrl qctrl;
qctrl.id = qmenu->id;
- cx18_queryctrl(cx, &qctrl);
- return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
+ cx18_queryctrl(file, fh, &qctrl);
+ return v4l2_ctrl_query_menu(qmenu, &qctrl,
+ cx2341x_ctrl_get_menu(&cx->params, qmenu->id));
}
-static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
+static int cx18_try_ctrl(struct file *file, void *fh,
+ struct v4l2_ext_control *vctrl)
{
- s32 v = vctrl->value;
-
- CX18_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
+ struct v4l2_queryctrl qctrl;
+ const char **menu_items = NULL;
+ int err;
+
+ qctrl.id = vctrl->id;
+ err = cx18_queryctrl(file, fh, &qctrl);
+ if (err)
+ return err;
+ if (qctrl.type == V4L2_CTRL_TYPE_MENU)
+ menu_items = v4l2_ctrl_get_menu(qctrl.id);
+ return v4l2_ctrl_check(vctrl, &qctrl, menu_items);
+}
+static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
+{
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
@@ -123,7 +136,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
default:
- CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+ CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
@@ -131,8 +144,6 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
{
- CX18_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
-
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
@@ -149,7 +160,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_LOUDNESS:
return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
default:
- CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+ CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
@@ -194,113 +205,110 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt
return 0;
}
-int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
struct v4l2_control ctrl;
- switch (cmd) {
- case VIDIOC_QUERYMENU:
- CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
- return cx18_querymenu(cx, arg);
-
- case VIDIOC_QUERYCTRL:
- return cx18_queryctrl(cx, arg);
-
- case VIDIOC_S_CTRL:
- return cx18_s_ctrl(cx, arg);
-
- case VIDIOC_G_CTRL:
- return cx18_g_ctrl(cx, arg);
-
- case VIDIOC_S_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
-
- if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
- int i;
- int err = 0;
-
- for (i = 0; i < c->count; i++) {
- ctrl.id = c->controls[i].id;
- ctrl.value = c->controls[i].value;
- err = cx18_s_ctrl(cx, &ctrl);
- c->controls[i].value = ctrl.value;
- if (err) {
- c->error_idx = i;
- break;
- }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
+
+ for (i = 0; i < c->count; i++) {
+ ctrl.id = c->controls[i].id;
+ ctrl.value = c->controls[i].value;
+ err = cx18_g_ctrl(cx, &ctrl);
+ c->controls[i].value = ctrl.value;
+ if (err) {
+ c->error_idx = i;
+ break;
}
- return err;
}
- CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- struct cx2341x_mpeg_params p = cx->params;
- int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd);
+ return err;
+ }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+ return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS);
+ return -EINVAL;
+}
- if (err)
- return err;
+int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
+ struct v4l2_control ctrl;
- if (p.video_encoding != cx->params.video_encoding) {
- int is_mpeg1 = p.video_encoding ==
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_format fmt;
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
- /* fix videodecoder resolution */
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1);
- fmt.fmt.pix.height = cx->params.height;
- cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
+
+ for (i = 0; i < c->count; i++) {
+ ctrl.id = c->controls[i].id;
+ ctrl.value = c->controls[i].value;
+ err = cx18_s_ctrl(cx, &ctrl);
+ c->controls[i].value = ctrl.value;
+ if (err) {
+ c->error_idx = i;
+ break;
}
- err = cx2341x_update(cx, cx18_api_func, &cx->params, &p);
- if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
- err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
- cx->params = p;
- cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
- cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
- return err;
}
- return -EINVAL;
+ return err;
}
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ struct cx2341x_mpeg_params p = cx->params;
+ int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
+ c, VIDIOC_S_EXT_CTRLS);
- case VIDIOC_G_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
-
- if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
- int i;
- int err = 0;
-
- for (i = 0; i < c->count; i++) {
- ctrl.id = c->controls[i].id;
- ctrl.value = c->controls[i].value;
- err = cx18_g_ctrl(cx, &ctrl);
- c->controls[i].value = ctrl.value;
- if (err) {
- c->error_idx = i;
- break;
- }
- }
+ if (err)
return err;
+
+ if (p.video_encoding != cx->params.video_encoding) {
+ int is_mpeg1 = p.video_encoding ==
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+ struct v4l2_format fmt;
+
+ /* fix videodecoder resolution */
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = cx->params.width
+ / (is_mpeg1 ? 2 : 1);
+ fmt.fmt.pix.height = cx->params.height;
+ cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
}
- CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
- return cx2341x_ext_ctrls(&cx->params, 0, arg, cmd);
- return -EINVAL;
+ err = cx2341x_update(cx, cx18_api_func, &cx->params, &p);
+ if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
+ err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
+ cx->params = p;
+ cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
+ cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
+ return err;
}
+ return -EINVAL;
+}
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
+int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
- return cx2341x_ext_ctrls(&cx->params,
- atomic_read(&cx->ana_capturing), arg, cmd);
- return -EINVAL;
- }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
- default:
- return -EINVAL;
+ for (i = 0; i < c->count; i++) {
+ err = cx18_try_ctrl(file, fh, &c->controls[i]);
+ if (err) {
+ c->error_idx = i;
+ break;
+ }
+ }
+ return err;
}
- return 0;
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+ return cx2341x_ext_ctrls(&cx->params,
+ atomic_read(&cx->ana_capturing),
+ c, VIDIOC_TRY_EXT_CTRLS);
+ return -EINVAL;
}
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
index 6e985cf422a..e46323700b8 100644
--- a/drivers/media/video/cx18/cx18-controls.h
+++ b/drivers/media/video/cx18/cx18-controls.h
@@ -21,4 +21,9 @@
* 02111-1307 USA
*/
-int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
+int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
+int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
+int cx18_try_ext_ctrls(struct file *file, void *fh,
+ struct v4l2_ext_controls *a);
+int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 2b810bb2a4c..22434aadde3 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -120,6 +120,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n"
"\t\t\t 3 = Compro VideoMate H900\n"
"\t\t\t 4 = Yuan MPC718\n"
+ "\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -420,6 +421,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
mutex_init(&cx->serialize_lock);
mutex_init(&cx->i2c_bus_lock[0]);
mutex_init(&cx->i2c_bus_lock[1]);
+ mutex_init(&cx->gpio_lock);
spin_lock_init(&cx->lock);
spin_lock_init(&cx->dma_reg_lock);
@@ -435,7 +437,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
(cx->params.video_temporal_filter_mode << 1) |
(cx->params.video_median_filter_type << 2);
cx->params.port = CX2341X_PORT_MEMORY;
- cx->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
+ cx->params.capabilities = CX2341X_CAP_HAS_TS;
init_waitqueue_head(&cx->cap_w);
init_waitqueue_head(&cx->mb_apu_waitq);
init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -614,7 +616,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx18_cards[cx18_cards_active] = cx;
cx->dev = dev;
cx->num = cx18_cards_active++;
- snprintf(cx->name, sizeof(cx->name) - 1, "cx18-%d", cx->num);
+ snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
CX18_INFO("Initializing card #%d\n", cx->num);
spin_unlock(&cx18_cards_lock);
@@ -721,6 +723,12 @@ static int __devinit cx18_probe(struct pci_dev *dev,
/* if no tuner was found, then pick the first tuner in the card list */
if (cx->options.tuner == -1 && cx->card->tuners[0].std) {
cx->std = cx->card->tuners[0].std;
+ if (cx->std & V4L2_STD_PAL)
+ cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
+ else if (cx->std & V4L2_STD_NTSC)
+ cx->std = V4L2_STD_NTSC_M;
+ else if (cx->std & V4L2_STD_SECAM)
+ cx->std = V4L2_STD_SECAM_L;
cx->options.tuner = cx->card->tuners[0].tuner;
}
if (cx->options.radio == -1)
@@ -818,6 +826,9 @@ int cx18_init_on_first_open(struct cx18 *cx)
int video_input;
int fw_retry_count = 3;
struct v4l2_frequency vf;
+ struct cx18_open_id fh;
+
+ fh.cx = cx;
if (test_bit(CX18_F_I_FAILED, &cx->i_flags))
return -ENXIO;
@@ -869,13 +880,13 @@ int cx18_init_on_first_open(struct cx18 *cx)
video_input = cx->active_input;
cx->active_input++; /* Force update of input */
- cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_INPUT, &video_input);
+ cx18_s_input(NULL, &fh, video_input);
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
in one place. */
cx->std++; /* Force full standard initialization */
- cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_STD, &cx->tuner_std);
- cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_FREQUENCY, &vf);
+ cx18_s_std(NULL, &fh, &cx->tuner_std);
+ cx18_s_frequency(NULL, &fh, &vf);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index de14ab59a20..45e31b04730 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -75,7 +75,8 @@
#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
-#define CX18_CARD_LAST 3
+#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
+#define CX18_CARD_LAST 4
#define CX18_ENC_STREAM_TYPE_MPG 0
#define CX18_ENC_STREAM_TYPE_TS 1
@@ -94,6 +95,7 @@
#define CX18_PCI_ID_HAUPPAUGE 0x0070
#define CX18_PCI_ID_COMPRO 0x185b
#define CX18_PCI_ID_YUAN 0x12ab
+#define CX18_PCI_ID_CONEXANT 0x14f1
/* ======================================================================== */
/* ========================== START USER SETTABLE DMA VARIABLES =========== */
@@ -228,9 +230,7 @@ struct cx18_dvb {
struct dvb_net dvbnet;
int enabled;
int feeding;
-
struct mutex feedlock;
-
};
struct cx18; /* forward reference */
@@ -427,6 +427,7 @@ struct cx18 {
/* gpio */
u32 gpio_dir;
u32 gpio_val;
+ struct mutex gpio_lock;
/* v4l2 and User settings */
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 2694ce35063..2d630d9f749 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -41,9 +41,6 @@
#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
-#define CX18_AUDIO_ENABLE 0xc72014
-#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
-
#define CX18_FAST_CLOCK_PLL_INT 0xc78000
#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
#define CX18_FAST_CLOCK_PLL_POST 0xc78008
@@ -90,7 +87,7 @@
#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
/* Encoder/decoder firmware sizes */
-#define CX18_FW_CPU_SIZE (174716)
+#define CX18_FW_CPU_SIZE (158332)
#define CX18_FW_APU_SIZE (141200)
#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
@@ -345,6 +342,11 @@ int cx18_firmware_init(struct cx18 *cx)
int sz = load_apu_fw_direct("v4l-cx23418-apu.fw",
cx->enc_mem, cx, CX18_FW_APU_SIZE);
+ write_enc(0xE51FF004, 0);
+ write_enc(0xa00000, 4); /* todo: not hardcoded */
+ write_reg(0x00010000, CX18_PROC_SOFT_RESET); /* Start APU */
+ cx18_msleep_timeout(500, 0);
+
sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw",
cx->enc_mem, cx, CX18_FW_CPU_SIZE);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index b302833f6f9..3d495dba498 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -69,6 +69,7 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
/* Assuming that the masks are a subset of the bits in gpio_dir */
/* Assert */
+ mutex_lock(&cx->gpio_lock);
cx->gpio_val =
(cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
gpio_write(cx);
@@ -79,10 +80,53 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
(cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
gpio_write(cx);
schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+ mutex_unlock(&cx->gpio_lock);
}
+void cx18_reset_ir_gpio(void *data)
+{
+ struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
+ const struct cx18_gpio_i2c_slave_reset *p;
+
+ p = &cx->card->gpio_i2c_slave_reset;
+
+ if (p->ir_reset_mask == 0)
+ return;
+
+ CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+
+ /*
+ Assert timing for the Z8F0811 on HVR-1600 boards:
+ 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
+ 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
+ (6,601,085 nanoseconds ~= 7 milliseconds)
+ 3. DBG pin must be high before chip exits reset for normal operation.
+ DBG is open drain and hopefully pulled high since we don't
+ normally drive it (GPIO 1?) for the HVR-1600
+ 4. Z8F0811 won't exit reset until RESET is deasserted
+ */
+ mutex_lock(&cx->gpio_lock);
+ cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
+ gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+
+ /*
+ Zilog comes out of reset, loads reset vector address and executes
+ from there. Required recovery delay unknown.
+ */
+ mutex_lock(&cx->gpio_lock);
+ cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
+ gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+}
+EXPORT_SYMBOL(cx18_reset_ir_gpio);
+/* This symbol is exported for use by an infrared module for the IR-blaster */
+
void cx18_gpio_init(struct cx18 *cx)
{
+ mutex_lock(&cx->gpio_lock);
cx->gpio_dir = cx->card->gpio_init.direction;
cx->gpio_val = cx->card->gpio_init.initial_value;
@@ -91,14 +135,17 @@ void cx18_gpio_init(struct cx18 *cx)
cx->gpio_val |= 1 << cx->card->xceive_pin;
}
- if (cx->gpio_dir == 0)
+ if (cx->gpio_dir == 0) {
+ mutex_unlock(&cx->gpio_lock);
return;
+ }
CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
}
/* Xceive tuner reset function */
@@ -112,13 +159,52 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
return 0;
CX18_DEBUG_INFO("Resetting tuner\n");
+ mutex_lock(&cx->gpio_lock);
cx->gpio_val &= ~(1 << cx->card->xceive_pin);
-
gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
schedule_timeout_interruptible(msecs_to_jiffies(1));
+ mutex_lock(&cx->gpio_lock);
cx->gpio_val |= 1 << cx->card->xceive_pin;
gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
schedule_timeout_interruptible(msecs_to_jiffies(1));
return 0;
}
+
+int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
+{
+ struct v4l2_routing *route = arg;
+ u32 mask, data;
+
+ switch (command) {
+ case VIDIOC_INT_S_AUDIO_ROUTING:
+ if (route->input > 2)
+ return -EINVAL;
+ mask = cx->card->gpio_audio_input.mask;
+ switch (route->input) {
+ case 0:
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ case 1:
+ data = cx->card->gpio_audio_input.linein;
+ break;
+ case 2:
+ default:
+ data = cx->card->gpio_audio_input.radio;
+ break;
+ }
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ if (mask) {
+ mutex_lock(&cx->gpio_lock);
+ cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
+ gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
+ }
+ return 0;
+}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index 525c328f748..22cd7ddf855 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -22,4 +22,6 @@
void cx18_gpio_init(struct cx18 *cx);
void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
+void cx18_reset_ir_gpio(void *data);
int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
+int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 680bc4e35b7..6023ba3bd3a 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -39,10 +39,6 @@
#define GETSCL_BIT 0x0004
#define GETSDL_BIT 0x0008
-#ifndef I2C_ADAP_CLASS_TV_ANALOG
-#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
-#endif
-
#define CX18_CS5345_I2C_ADDR 0x4c
/* This array should match the CX18_HW_ defines */
@@ -311,8 +307,12 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
{
int addr;
- if (hw == CX18_HW_GPIO || hw == 0)
+ if (hw == 0)
return 0;
+
+ if (hw == CX18_HW_GPIO)
+ return cx18_gpio(cx, cmd, arg);
+
if (hw == CX18_HW_CX23418)
return cx18_av_cmd(cx, cmd, arg);
@@ -350,6 +350,8 @@ void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
cx18_av_cmd(cx, cmd, arg);
i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
+ if (cx->hw_flags & CX18_HW_GPIO)
+ cx18_gpio(cx, cmd, arg);
}
/* init + register i2c algo-bit adapter */
@@ -358,6 +360,18 @@ int init_cx18_i2c(struct cx18 *cx)
int i;
CX18_DEBUG_I2C("i2c init\n");
+ /* Sanity checks for the I2C hardware arrays. They must be the
+ * same size and GPIO/CX23418 must be the last entries.
+ */
+ if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
+ ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
+ CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
+ CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
+ hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
+ CX18_ERR("Mismatched I2C hardware arrays\n");
+ return -ENODEV;
+ }
+
for (i = 0; i < 2; i++) {
memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
sizeof(struct i2c_adapter));
@@ -391,6 +405,7 @@ int init_cx18_i2c(struct cx18 *cx)
write_reg_sync(0x00c000c0, 0xc7001c);
mdelay(10);
write_reg_sync(0x00c00000, 0xc7001c);
+ mdelay(10);
write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */
write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 4151f1e5493..0d74e59e503 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -100,19 +100,6 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
}
}
-static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
- set |= fmt->service_lines[f][l];
- }
- }
- return set != 0;
-}
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
{
@@ -126,35 +113,167 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
return set;
}
-static const struct {
- v4l2_std_id std;
- char *name;
-} enum_stds[] = {
- { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" },
- { V4L2_STD_PAL_DK, "PAL-DK" },
- { V4L2_STD_PAL_I, "PAL-I" },
- { V4L2_STD_PAL_M, "PAL-M" },
- { V4L2_STD_PAL_N, "PAL-N" },
- { V4L2_STD_PAL_Nc, "PAL-Nc" },
- { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" },
- { V4L2_STD_SECAM_DK, "SECAM-DK" },
- { V4L2_STD_SECAM_L, "SECAM-L" },
- { V4L2_STD_SECAM_LC, "SECAM-L'" },
- { V4L2_STD_NTSC_M, "NTSC-M" },
- { V4L2_STD_NTSC_M_JP, "NTSC-J" },
- { V4L2_STD_NTSC_M_KR, "NTSC-K" },
-};
-
-static const struct v4l2_standard cx18_std_60hz = {
- .frameperiod = {.numerator = 1001, .denominator = 30000},
- .framelines = 525,
-};
-
-static const struct v4l2_standard cx18_std_50hz = {
- .frameperiod = { .numerator = 1, .denominator = 25 },
- .framelines = 625,
-};
+static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+
+ pixfmt->width = cx->params.width;
+ pixfmt->height = cx->params.height;
+ pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ pixfmt->field = V4L2_FIELD_INTERLACED;
+ pixfmt->priv = 0;
+ if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
+ pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
+ /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
+ pixfmt->sizeimage =
+ pixfmt->height * pixfmt->width +
+ pixfmt->height * (pixfmt->width / 2);
+ pixfmt->bytesperline = 720;
+ } else {
+ pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
+ pixfmt->sizeimage = 128 * 1024;
+ pixfmt->bytesperline = 0;
+ }
+ return 0;
+}
+
+static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
+
+ vbifmt->sampling_rate = 27000000;
+ vbifmt->offset = 248;
+ vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4;
+ vbifmt->sample_format = V4L2_PIX_FMT_GREY;
+ vbifmt->start[0] = cx->vbi.start[0];
+ vbifmt->start[1] = cx->vbi.start[1];
+ vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
+ vbifmt->flags = 0;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ return 0;
+}
+
+static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ return -EINVAL;
+}
+
+static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+
+ int w = fmt->fmt.pix.width;
+ int h = fmt->fmt.pix.height;
+
+ w = min(w, 720);
+ w = max(w, 1);
+ h = min(h, cx->is_50hz ? 576 : 480);
+ h = max(h, 2);
+ cx18_g_fmt_vid_cap(file, fh, fmt);
+ fmt->fmt.pix.width = w;
+ fmt->fmt.pix.height = h;
+ return 0;
+}
+
+static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ return cx18_g_fmt_vbi_cap(file, fh, fmt);
+}
+
+static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ return -EINVAL;
+}
+
+static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
+ int w = fmt->fmt.pix.width;
+ int h = fmt->fmt.pix.height;
+
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
+
+ ret = cx18_try_fmt_vid_cap(file, fh, fmt);
+ if (ret)
+ return ret;
+
+ if (cx->params.width == w && cx->params.height == h)
+ return 0;
+
+ if (atomic_read(&cx->ana_capturing) > 0)
+ return -EBUSY;
+
+ cx->params.width = w;
+ cx->params.height = h;
+ cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+ return cx18_g_fmt_vid_cap(file, fh, fmt);
+}
+
+static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
+
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
+
+ if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
+ cx->vbi.sliced_in->service_set &&
+ atomic_read(&cx->ana_capturing) > 0)
+ return -EBUSY;
+
+ cx->vbi.sliced_in->service_set = 0;
+ cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
+ return cx18_g_fmt_vbi_cap(file, fh, fmt);
+}
+
+static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_format *fmt)
+{
+ return -EINVAL;
+}
+static int cx18_g_chip_ident(struct file *file, void *fh,
+ struct v4l2_chip_ident *chip)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (chip->match_type == V4L2_CHIP_MATCH_HOST) {
+ if (v4l2_chip_match_host(chip->match_type, chip->match_chip))
+ chip->ident = V4L2_IDENT_CX23418;
+ return 0;
+ }
+ if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ return cx18_i2c_id(cx, chip->match_chip, VIDIOC_G_CHIP_IDENT,
+ chip);
+ if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
+ return cx18_call_i2c_client(cx, chip->match_chip,
+ VIDIOC_G_CHIP_IDENT, chip);
+ return -EINVAL;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
{
struct v4l2_register *regs = arg;
@@ -174,665 +293,478 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
return 0;
}
-static int cx18_get_fmt(struct cx18 *cx, int streamtype, struct v4l2_format *fmt)
-{
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- fmt->fmt.pix.width = cx->params.width;
- fmt->fmt.pix.height = cx->params.height;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
- if (streamtype == CX18_ENC_STREAM_TYPE_YUV) {
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- fmt->fmt.pix.sizeimage =
- fmt->fmt.pix.height * fmt->fmt.pix.width +
- fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
- } else {
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- fmt->fmt.pix.sizeimage = 128 * 1024;
- }
- break;
-
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- fmt->fmt.vbi.sampling_rate = 27000000;
- fmt->fmt.vbi.offset = 248;
- fmt->fmt.vbi.samples_per_line = cx->vbi.raw_decoder_line_size - 4;
- fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- fmt->fmt.vbi.start[0] = cx->vbi.start[0];
- fmt->fmt.vbi.start[1] = cx->vbi.start[1];
- fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = cx->vbi.count;
- break;
+static int cx18_g_register(struct file *file, void *fh,
+ struct v4l2_register *reg)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+
+ if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
+ if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER,
+ reg);
+ return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER,
+ reg);
+}
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- {
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+static int cx18_s_register(struct file *file, void *fh,
+ struct v4l2_register *reg)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+
+ if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
+ if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER,
+ reg);
+ return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER,
+ reg);
+}
+#endif
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
- memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
+static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- cx18_av_cmd(cx, VIDIOC_G_FMT, fmt);
- vbifmt->service_set = cx18_get_service_set(vbifmt);
- break;
- }
- default:
- return -EINVAL;
- }
+ *p = v4l2_prio_max(&cx->prio);
return 0;
}
-static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype,
- struct v4l2_format *fmt, int set_fmt)
+static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- u16 set;
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
- /* set window size */
- if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
+ return v4l2_prio_change(&cx->prio, &id->prio, prio);
+}
- if (w > 720)
- w = 720;
- else if (w < 1)
- w = 1;
- if (h > (cx->is_50hz ? 576 : 480))
- h = (cx->is_50hz ? 576 : 480);
- else if (h < 2)
- h = 2;
- cx18_get_fmt(cx, streamtype, fmt);
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
+static int cx18_querycap(struct file *file, void *fh,
+ struct v4l2_capability *vcap)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- if (!set_fmt || (cx->params.width == w && cx->params.height == h))
- return 0;
- if (atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
-
- cx->params.width = w;
- cx->params.height = h;
- if (w != 720 || h != (cx->is_50hz ? 576 : 480))
- cx->params.video_temporal_filter = 0;
- else
- cx->params.video_temporal_filter = 8;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
- return cx18_get_fmt(cx, streamtype, fmt);
- }
+ strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
+ strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
+ strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info));
+ vcap->version = CX18_DRIVER_VERSION; /* version */
+ vcap->capabilities = cx->v4l2_cap; /* capabilities */
+ return 0;
+}
- /* set raw VBI format */
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI &&
- cx->vbi.sliced_in->service_set &&
- atomic_read(&cx->ana_capturing) > 0)
- return -EBUSY;
- if (set_fmt) {
- cx->vbi.sliced_in->service_set = 0;
- cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
- }
- return cx18_get_fmt(cx, streamtype, fmt);
- }
+static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- /* any else but sliced VBI capture is an error */
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
+ return cx18_get_audio_input(cx, vin->index, vin);
+}
- /* TODO: implement sliced VBI, for now silently return 0 */
- return 0;
+static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- /* set sliced VBI capture format */
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
+ vin->index = cx->audio_input;
+ return cx18_get_audio_input(cx, vin->index, vin);
+}
- if (vbifmt->service_set)
- cx18_expand_service_set(vbifmt, cx->is_50hz);
- set = check_service_set(vbifmt, cx->is_50hz);
- vbifmt->service_set = cx18_get_service_set(vbifmt);
+static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- if (!set_fmt)
- return 0;
- if (set == 0)
+ if (vout->index >= cx->nof_audio_inputs)
return -EINVAL;
- if (atomic_read(&cx->ana_capturing) > 0 && cx->vbi.sliced_in->service_set == 0)
- return -EBUSY;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
- memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
+ cx->audio_input = vout->index;
+ cx18_audio_set_io(cx);
return 0;
}
-static int cx18_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
+static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
{
- struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
- struct cx18 *cx = id->cx;
- struct v4l2_register *reg = arg;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- switch (cmd) {
- /* ioctls to allow direct access to the encoder registers for testing */
- case VIDIOC_DBG_G_REGISTER:
- if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
- return cx18_cxc(cx, cmd, arg);
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
- return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
- return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
-
- case VIDIOC_DBG_S_REGISTER:
- if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
- return cx18_cxc(cx, cmd, arg);
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
- return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
- return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
-
- case VIDIOC_G_CHIP_IDENT: {
- struct v4l2_chip_ident *chip = arg;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
- struct v4l2_chip_ident *chip = arg;
-
- chip->ident = V4L2_IDENT_CX23418;
- }
- return 0;
- }
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
- return cx18_i2c_id(cx, reg->match_chip, cmd, arg);
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
- return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg);
- return -EINVAL;
- }
-
- case VIDIOC_INT_S_AUDIO_ROUTING: {
- struct v4l2_routing *route = arg;
+ /* set it to defaults from our table */
+ return cx18_get_input(cx, vin->index, vin);
+}
- cx18_audio_set_route(cx, route);
- break;
- }
+static int cx18_cropcap(struct file *file, void *fh,
+ struct v4l2_cropcap *cropcap)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- default:
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- }
+ cropcap->bounds.top = cropcap->bounds.left = 0;
+ cropcap->bounds.width = 720;
+ cropcap->bounds.height = cx->is_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
+ cropcap->defrect = cropcap->bounds;
return 0;
}
-int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg)
+static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
{
- struct cx18_open_id *id = NULL;
-
- if (filp)
- id = (struct cx18_open_id *)filp->private_data;
-
- switch (cmd) {
- case VIDIOC_G_PRIORITY:
- {
- enum v4l2_priority *p = arg;
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
- *p = v4l2_prio_max(&cx->prio);
- break;
- }
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
- case VIDIOC_S_PRIORITY:
- {
- enum v4l2_priority *prio = arg;
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
+}
- return v4l2_prio_change(&cx->prio, &id->prio, *prio);
- }
+static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- case VIDIOC_QUERYCAP:{
- struct v4l2_capability *vcap = arg;
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
+}
- memset(vcap, 0, sizeof(*vcap));
- strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
- strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
- strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info));
- vcap->version = CX18_DRIVER_VERSION; /* version */
- vcap->capabilities = cx->v4l2_cap; /* capabilities */
+static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_fmtdesc *fmt)
+{
+ static struct v4l2_fmtdesc formats[] = {
+ { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
+ "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
+ },
+ { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
+ "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
+ }
+ };
- /* reserved.. must set to 0! */
- vcap->reserved[0] = vcap->reserved[1] =
- vcap->reserved[2] = vcap->reserved[3] = 0;
- break;
- }
+ if (fmt->index > 1)
+ return -EINVAL;
+ *fmt = formats[fmt->index];
+ return 0;
+}
- case VIDIOC_ENUMAUDIO:{
- struct v4l2_audio *vin = arg;
+static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- return cx18_get_audio_input(cx, vin->index, vin);
- }
+ *i = cx->active_input;
+ return 0;
+}
- case VIDIOC_G_AUDIO:{
- struct v4l2_audio *vin = arg;
+int cx18_s_input(struct file *file, void *fh, unsigned int inp)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
- vin->index = cx->audio_input;
- return cx18_get_audio_input(cx, vin->index, vin);
- }
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
- case VIDIOC_S_AUDIO:{
- struct v4l2_audio *vout = arg;
+ if (inp < 0 || inp >= cx->nof_inputs)
+ return -EINVAL;
- if (vout->index >= cx->nof_audio_inputs)
- return -EINVAL;
- cx->audio_input = vout->index;
- cx18_audio_set_io(cx);
- break;
+ if (inp == cx->active_input) {
+ CX18_DEBUG_INFO("Input unchanged\n");
+ return 0;
}
- case VIDIOC_ENUMINPUT:{
- struct v4l2_input *vin = arg;
-
- /* set it to defaults from our table */
- return cx18_get_input(cx, vin->index, vin);
- }
+ CX18_DEBUG_INFO("Changing input from %d to %d\n",
+ cx->active_input, inp);
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT: {
- struct v4l2_format *fmt = arg;
+ cx->active_input = inp;
+ /* Set the audio input to whatever is appropriate for the input type. */
+ cx->audio_input = cx->card->video_inputs[inp].audio_index;
- return cx18_try_or_set_fmt(cx, id->type, fmt, cmd == VIDIOC_S_FMT);
- }
+ /* prevent others from messing with the streams until
+ we're finished changing inputs. */
+ cx18_mute(cx);
+ cx18_video_set_io(cx);
+ cx18_audio_set_io(cx);
+ cx18_unmute(cx);
+ return 0;
+}
- case VIDIOC_G_FMT: {
- struct v4l2_format *fmt = arg;
- int type = fmt->type;
+static int cx18_g_frequency(struct file *file, void *fh,
+ struct v4l2_frequency *vf)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- memset(fmt, 0, sizeof(*fmt));
- fmt->type = type;
- return cx18_get_fmt(cx, id->type, fmt);
- }
+ if (vf->tuner != 0)
+ return -EINVAL;
- case VIDIOC_CROPCAP: {
- struct v4l2_cropcap *cropcap = arg;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- cropcap->bounds.height = cx->is_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
- cropcap->defrect = cropcap->bounds;
- return 0;
- }
+ cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf);
+ return 0;
+}
- case VIDIOC_S_CROP: {
- struct v4l2_crop *crop = arg;
+int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- return cx18_av_cmd(cx, VIDIOC_S_CROP, arg);
- }
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
- case VIDIOC_G_CROP: {
- struct v4l2_crop *crop = arg;
+ if (vf->tuner != 0)
+ return -EINVAL;
- if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- return cx18_av_cmd(cx, VIDIOC_G_CROP, arg);
- }
+ cx18_mute(cx);
+ CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
+ cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
+ cx18_unmute(cx);
+ return 0;
+}
- case VIDIOC_ENUM_FMT: {
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
- };
- struct v4l2_fmtdesc *fmt = arg;
- enum v4l2_buf_type type = fmt->type;
-
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- break;
- default:
- return -EINVAL;
- }
- if (fmt->index > 1)
- return -EINVAL;
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
- }
+static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- case VIDIOC_G_INPUT:{
- *(int *)arg = cx->active_input;
- break;
- }
+ *std = cx->std;
+ return 0;
+}
- case VIDIOC_S_INPUT:{
- int inp = *(int *)arg;
+int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
- if (inp < 0 || inp >= cx->nof_inputs)
- return -EINVAL;
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
- if (inp == cx->active_input) {
- CX18_DEBUG_INFO("Input unchanged\n");
- break;
- }
- CX18_DEBUG_INFO("Changing input from %d to %d\n",
- cx->active_input, inp);
+ if ((*std & V4L2_STD_ALL) == 0)
+ return -EINVAL;
- cx->active_input = inp;
- /* Set the audio input to whatever is appropriate for the
- input type. */
- cx->audio_input = cx->card->video_inputs[inp].audio_index;
+ if (*std == cx->std)
+ return 0;
- /* prevent others from messing with the streams until
- we're finished changing inputs. */
- cx18_mute(cx);
- cx18_video_set_io(cx);
- cx18_audio_set_io(cx);
- cx18_unmute(cx);
- break;
+ if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
+ atomic_read(&cx->ana_capturing) > 0) {
+ /* Switching standard would turn off the radio or mess
+ with already running streams, prevent that by
+ returning EBUSY. */
+ return -EBUSY;
}
- case VIDIOC_G_FREQUENCY:{
- struct v4l2_frequency *vf = arg;
+ cx->std = *std;
+ cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
+ cx->params.is_50hz = cx->is_50hz = !cx->is_60hz;
+ cx->params.width = 720;
+ cx->params.height = cx->is_50hz ? 576 : 480;
+ cx->vbi.count = cx->is_50hz ? 18 : 12;
+ cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
+ cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
+ cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
+ CX18_DEBUG_INFO("Switching standard to %llx.\n",
+ (unsigned long long) cx->std);
+
+ /* Tuner */
+ cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+ return 0;
+}
- if (vf->tuner != 0)
- return -EINVAL;
- cx18_call_i2c_clients(cx, cmd, arg);
- break;
- }
+static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
- case VIDIOC_S_FREQUENCY:{
- struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
- if (vf.tuner != 0)
- return -EINVAL;
+ if (vt->index != 0)
+ return -EINVAL;
- cx18_mute(cx);
- CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
- cx18_call_i2c_clients(cx, cmd, &vf);
- cx18_unmute(cx);
- break;
- }
+ /* Setting tuner can only set audio mode */
+ cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
- case VIDIOC_ENUMSTD:{
- struct v4l2_standard *vs = arg;
- int idx = vs->index;
+ return 0;
+}
- if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
- return -EINVAL;
+static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
- cx18_std_60hz : cx18_std_50hz;
- vs->index = idx;
- vs->id = enum_stds[idx].std;
- strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
- break;
- }
+ if (vt->index != 0)
+ return -EINVAL;
- case VIDIOC_G_STD:{
- *(v4l2_std_id *) arg = cx->std;
- break;
+ cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
+
+ if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
+ strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
+ vt->type = V4L2_TUNER_RADIO;
+ } else {
+ strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
+ vt->type = V4L2_TUNER_ANALOG_TV;
}
- case VIDIOC_S_STD: {
- v4l2_std_id std = *(v4l2_std_id *) arg;
+ return 0;
+}
- if ((std & V4L2_STD_ALL) == 0)
- return -EINVAL;
+static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_sliced_vbi_cap *cap)
+{
+ return -EINVAL;
+}
- if (std == cx->std)
- break;
+static int cx18_g_enc_index(struct file *file, void *fh,
+ struct v4l2_enc_idx *idx)
+{
+ return -EINVAL;
+}
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
- atomic_read(&cx->ana_capturing) > 0) {
- /* Switching standard would turn off the radio or mess
- with already running streams, prevent that by
- returning EBUSY. */
- return -EBUSY;
- }
+static int cx18_encoder_cmd(struct file *file, void *fh,
+ struct v4l2_encoder_cmd *enc)
+{
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
- cx->std = std;
- cx->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
- cx->params.is_50hz = cx->is_50hz = !cx->is_60hz;
- cx->params.width = 720;
- cx->params.height = cx->is_50hz ? 576 : 480;
- cx->vbi.count = cx->is_50hz ? 18 : 12;
- cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
- cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
- cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
- CX18_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)cx->std);
-
- /* Tuner */
- cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+ switch (enc->cmd) {
+ case V4L2_ENC_CMD_START:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
+ enc->flags = 0;
+ return cx18_start_capture(id);
+
+ case V4L2_ENC_CMD_STOP:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
+ enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
+ cx18_stop_capture(id,
+ enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
break;
- }
-
- case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
- struct v4l2_tuner *vt = arg;
- if (vt->index != 0)
- return -EINVAL;
-
- cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
+ case V4L2_ENC_CMD_PAUSE:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
+ enc->flags = 0;
+ if (!atomic_read(&cx->ana_capturing))
+ return -EPERM;
+ if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
+ return 0;
+ cx18_mute(cx);
+ cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx));
break;
- }
-
- case VIDIOC_G_TUNER: {
- struct v4l2_tuner *vt = arg;
-
- if (vt->index != 0)
- return -EINVAL;
-
- memset(vt, 0, sizeof(*vt));
- cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
- strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_RADIO;
- } else {
- strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_ANALOG_TV;
- }
+ case V4L2_ENC_CMD_RESUME:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
+ enc->flags = 0;
+ if (!atomic_read(&cx->ana_capturing))
+ return -EPERM;
+ if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
+ return 0;
+ cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx));
+ cx18_unmute(cx);
break;
- }
- case VIDIOC_G_SLICED_VBI_CAP: {
- struct v4l2_sliced_vbi_cap *cap = arg;
- int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
- int f, l;
- enum v4l2_buf_type type = cap->type;
-
- memset(cap, 0, sizeof(*cap));
- cap->type = type;
- if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- if (valid_service_line(f, l, cx->is_50hz))
- cap->service_lines[f][l] = set;
- }
- }
- return 0;
- }
+ default:
+ CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
return -EINVAL;
}
+ return 0;
+}
- case VIDIOC_ENCODER_CMD:
- case VIDIOC_TRY_ENCODER_CMD: {
- struct v4l2_encoder_cmd *enc = arg;
- int try = cmd == VIDIOC_TRY_ENCODER_CMD;
-
- memset(&enc->raw, 0, sizeof(enc->raw));
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- enc->flags = 0;
- if (try)
- return 0;
- return cx18_start_capture(id);
-
- case V4L2_ENC_CMD_STOP:
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- if (try)
- return 0;
- cx18_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
- return 0;
+static int cx18_try_encoder_cmd(struct file *file, void *fh,
+ struct v4l2_encoder_cmd *enc)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- case V4L2_ENC_CMD_PAUSE:
- enc->flags = 0;
- if (try)
- return 0;
- if (!atomic_read(&cx->ana_capturing))
- return -EPERM;
- if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- return 0;
- cx18_mute(cx);
- cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx));
- break;
-
- case V4L2_ENC_CMD_RESUME:
- enc->flags = 0;
- if (try)
- return 0;
- if (!atomic_read(&cx->ana_capturing))
- return -EPERM;
- if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
- return 0;
- cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx));
- cx18_unmute(cx);
- break;
- default:
- return -EINVAL;
- }
+ switch (enc->cmd) {
+ case V4L2_ENC_CMD_START:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
+ enc->flags = 0;
break;
- }
- case VIDIOC_LOG_STATUS:
- {
- struct v4l2_input vidin;
- struct v4l2_audio audin;
- int i;
+ case V4L2_ENC_CMD_STOP:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
+ enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
+ break;
- CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
- if (cx->hw_flags & CX18_HW_TVEEPROM) {
- struct tveeprom tv;
+ case V4L2_ENC_CMD_PAUSE:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
+ enc->flags = 0;
+ break;
- cx18_read_eeprom(cx, &tv);
- }
- cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
- cx18_get_input(cx, cx->active_input, &vidin);
- cx18_get_audio_input(cx, cx->audio_input, &audin);
- CX18_INFO("Video Input: %s\n", vidin.name);
- CX18_INFO("Audio Input: %s\n", audin.name);
- CX18_INFO("Tuner: %s\n",
- test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?
- "Radio" : "TV");
- cx2341x_log_status(&cx->params, cx->name);
- CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
- for (i = 0; i < CX18_MAX_STREAMS; i++) {
- struct cx18_stream *s = &cx->streams[i];
-
- if (s->v4l2dev == NULL || s->buffers == 0)
- continue;
- CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
- s->name, s->s_flags,
- (s->buffers - s->q_free.buffers) * 100 / s->buffers,
- (s->buffers * s->buf_size) / 1024, s->buffers);
- }
- CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
- (long long)cx->mpg_data_received,
- (long long)cx->vbi_data_inserted);
- CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
+ case V4L2_ENC_CMD_RESUME:
+ CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
+ enc->flags = 0;
break;
- }
default:
+ CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
return -EINVAL;
}
return 0;
}
-static int cx18_v4l2_do_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, void *arg)
+static int cx18_log_status(struct file *file, void *fh)
{
- struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
- struct cx18 *cx = id->cx;
- int ret;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_input vidin;
+ struct v4l2_audio audin;
+ int i;
+
+ CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
+ if (cx->hw_flags & CX18_HW_TVEEPROM) {
+ struct tveeprom tv;
+
+ cx18_read_eeprom(cx, &tv);
+ }
+ cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
+ cx18_get_input(cx, cx->active_input, &vidin);
+ cx18_get_audio_input(cx, cx->audio_input, &audin);
+ CX18_INFO("Video Input: %s\n", vidin.name);
+ CX18_INFO("Audio Input: %s\n", audin.name);
+ mutex_lock(&cx->gpio_lock);
+ CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n",
+ cx->gpio_dir, cx->gpio_val);
+ mutex_unlock(&cx->gpio_lock);
+ CX18_INFO("Tuner: %s\n",
+ test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
+ cx2341x_log_status(&cx->params, cx->name);
+ CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
+ for (i = 0; i < CX18_MAX_STREAMS; i++) {
+ struct cx18_stream *s = &cx->streams[i];
+
+ if (s->v4l2dev == NULL || s->buffers == 0)
+ continue;
+ CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
+ s->name, s->s_flags,
+ (s->buffers - s->q_free.buffers) * 100 / s->buffers,
+ (s->buffers * s->buf_size) / 1024, s->buffers);
+ }
+ CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
+ (long long)cx->mpg_data_received,
+ (long long)cx->vbi_data_inserted);
+ CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
+ return 0;
+}
+
+static int cx18_default(struct file *file, void *fh, int cmd, void *arg)
+{
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
- /* check priority */
switch (cmd) {
- case VIDIOC_S_CTRL:
- case VIDIOC_S_STD:
- case VIDIOC_S_INPUT:
- case VIDIOC_S_TUNER:
- case VIDIOC_S_FREQUENCY:
- case VIDIOC_S_FMT:
- case VIDIOC_S_CROP:
- case VIDIOC_S_EXT_CTRLS:
- ret = v4l2_prio_check(&cx->prio, &id->prio);
- if (ret)
- return ret;
+ case VIDIOC_INT_S_AUDIO_ROUTING: {
+ struct v4l2_routing *route = arg;
+
+ CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
+ route->input, route->output);
+ cx18_audio_set_route(cx, route);
+ break;
}
- switch (cmd) {
- case VIDIOC_DBG_G_REGISTER:
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_G_CHIP_IDENT:
- case VIDIOC_INT_S_AUDIO_ROUTING:
- case VIDIOC_INT_RESET:
- if (cx18_debug & CX18_DBGFLG_IOCTL) {
- printk(KERN_INFO "cx18%d ioctl: ", cx->num);
- v4l_printk_ioctl(cmd);
- }
- return cx18_debug_ioctls(filp, cmd, arg);
-
- case VIDIOC_G_PRIORITY:
- case VIDIOC_S_PRIORITY:
- case VIDIOC_QUERYCAP:
- case VIDIOC_ENUMINPUT:
- case VIDIOC_G_INPUT:
- case VIDIOC_S_INPUT:
- case VIDIOC_G_FMT:
- case VIDIOC_S_FMT:
- case VIDIOC_TRY_FMT:
- case VIDIOC_ENUM_FMT:
- case VIDIOC_CROPCAP:
- case VIDIOC_G_CROP:
- case VIDIOC_S_CROP:
- case VIDIOC_G_FREQUENCY:
- case VIDIOC_S_FREQUENCY:
- case VIDIOC_ENUMSTD:
- case VIDIOC_G_STD:
- case VIDIOC_S_STD:
- case VIDIOC_S_TUNER:
- case VIDIOC_G_TUNER:
- case VIDIOC_ENUMAUDIO:
- case VIDIOC_S_AUDIO:
- case VIDIOC_G_AUDIO:
- case VIDIOC_G_SLICED_VBI_CAP:
- case VIDIOC_LOG_STATUS:
- case VIDIOC_G_ENC_INDEX:
- case VIDIOC_ENCODER_CMD:
- case VIDIOC_TRY_ENCODER_CMD:
- if (cx18_debug & CX18_DBGFLG_IOCTL) {
- printk(KERN_INFO "cx18%d ioctl: ", cx->num);
- v4l_printk_ioctl(cmd);
- }
- return cx18_v4l2_ioctls(cx, filp, cmd, arg);
-
- case VIDIOC_QUERYMENU:
- case VIDIOC_QUERYCTRL:
- case VIDIOC_S_CTRL:
- case VIDIOC_G_CTRL:
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_G_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- if (cx18_debug & CX18_DBGFLG_IOCTL) {
- printk(KERN_INFO "cx18%d ioctl: ", cx->num);
- v4l_printk_ioctl(cmd);
- }
- return cx18_control_ioctls(cx, cmd, arg);
+ case VIDIOC_INT_RESET: {
+ u32 val = *(u32 *)arg;
+
+ if ((val == 0) || (val & 0x01))
+ cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
+ break;
+ }
- case 0x00005401: /* Handle isatty() calls */
- return -EINVAL;
default:
- return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
- cx18_v4l2_do_ioctl);
+ return -EINVAL;
}
return 0;
}
@@ -840,12 +772,65 @@ static int cx18_v4l2_do_ioctl(struct inode *inode, struct file *filp,
int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
+ struct video_device *vfd = video_devdata(filp);
struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data;
struct cx18 *cx = id->cx;
int res;
mutex_lock(&cx->serialize_lock);
- res = video_usercopy(inode, filp, cmd, arg, cx18_v4l2_do_ioctl);
+
+ if (cx18_debug & CX18_DBGFLG_IOCTL)
+ vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
+ res = video_ioctl2(inode, filp, cmd, arg);
+ vfd->debug = 0;
mutex_unlock(&cx->serialize_lock);
return res;
}
+
+void cx18_set_funcs(struct video_device *vdev)
+{
+ vdev->vidioc_querycap = cx18_querycap;
+ vdev->vidioc_g_priority = cx18_g_priority;
+ vdev->vidioc_s_priority = cx18_s_priority;
+ vdev->vidioc_s_audio = cx18_s_audio;
+ vdev->vidioc_g_audio = cx18_g_audio;
+ vdev->vidioc_enumaudio = cx18_enumaudio;
+ vdev->vidioc_enum_input = cx18_enum_input;
+ vdev->vidioc_cropcap = cx18_cropcap;
+ vdev->vidioc_s_crop = cx18_s_crop;
+ vdev->vidioc_g_crop = cx18_g_crop;
+ vdev->vidioc_g_input = cx18_g_input;
+ vdev->vidioc_s_input = cx18_s_input;
+ vdev->vidioc_g_frequency = cx18_g_frequency;
+ vdev->vidioc_s_frequency = cx18_s_frequency;
+ vdev->vidioc_s_tuner = cx18_s_tuner;
+ vdev->vidioc_g_tuner = cx18_g_tuner;
+ vdev->vidioc_g_enc_index = cx18_g_enc_index;
+ vdev->vidioc_g_std = cx18_g_std;
+ vdev->vidioc_s_std = cx18_s_std;
+ vdev->vidioc_log_status = cx18_log_status;
+ vdev->vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap;
+ vdev->vidioc_encoder_cmd = cx18_encoder_cmd;
+ vdev->vidioc_try_encoder_cmd = cx18_try_encoder_cmd;
+ vdev->vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap;
+ vdev->vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap;
+ vdev->vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap;
+ vdev->vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap;
+ vdev->vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap;
+ vdev->vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap;
+ vdev->vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap;
+ vdev->vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap;
+ vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap;
+ vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap;
+ vdev->vidioc_g_chip_ident = cx18_g_chip_ident;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ vdev->vidioc_g_register = cx18_g_register;
+ vdev->vidioc_s_register = cx18_s_register;
+#endif
+ vdev->vidioc_default = cx18_default;
+ vdev->vidioc_queryctrl = cx18_queryctrl;
+ vdev->vidioc_querymenu = cx18_querymenu;
+ vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls;
+ vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls;
+ vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls;
+}
diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h
index 9f4c7eb2897..2222f679d86 100644
--- a/drivers/media/video/cx18/cx18-ioctl.h
+++ b/drivers/media/video/cx18/cx18-ioctl.h
@@ -24,7 +24,9 @@
u16 cx18_service2vbi(int type);
void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt);
+void cx18_set_funcs(struct video_device *vdev);
+int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std);
+int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
+int cx18_s_input(struct file *file, void *fh, unsigned int inp);
int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
-int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd,
- void *arg);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 2a5ccef9185..93177514e84 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = {
API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
+ API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST),
API_ENTRY(0, 0, 0),
};
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 1b921a33609..1728b1d832a 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -39,6 +39,7 @@ static struct file_operations cx18_v4l2_enc_fops = {
.owner = THIS_MODULE,
.read = cx18_v4l2_read,
.open = cx18_v4l2_open,
+ /* FIXME change to video_ioctl2 if serialization lock can be removed */
.ioctl = cx18_v4l2_ioctl,
.compat_ioctl = v4l_compat_ioctl32,
.release = cx18_v4l2_close,
@@ -189,14 +190,15 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
s->v4l2dev->type =
VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT |
VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER;
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18%d %s",
- cx->num, s->name);
+ snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
+ cx->num);
s->v4l2dev->minor = minor;
s->v4l2dev->dev = &cx->dev->dev;
s->v4l2dev->fops = cx18_stream_info[type].fops;
s->v4l2dev->release = video_device_release;
-
+ s->v4l2dev->tvnorms = V4L2_STD_ALL;
+ cx18_set_funcs(s->v4l2dev);
return 0;
}
@@ -309,8 +311,10 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
/* Teardown all streams */
for (type = 0; type < CX18_MAX_STREAMS; type++) {
- if (cx->streams[type].dvb.enabled)
+ if (cx->streams[type].dvb.enabled) {
cx18_dvb_unregister(&cx->streams[type]);
+ cx->streams[type].dvb.enabled = false;
+ }
vdev = cx->streams[type].v4l2dev;
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 33f78da9dba..e7ed053059a 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -52,6 +52,11 @@
#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
+#define APU_CMD_MASK 0x10000000
+#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
+
+#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
+
/* Description: This command indicates that a Memory Descriptor List has been
filled with the requested channel type
IN[0] - Task handle. Handle of the task
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index c592899a231..22847a0444f 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -77,10 +77,65 @@ const u32 cx2341x_mpeg_ctrls[] = {
};
EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
+static const struct cx2341x_mpeg_params default_params = {
+ /* misc */
+ .capabilities = 0,
+ .port = CX2341X_PORT_MEMORY,
+ .width = 720,
+ .height = 480,
+ .is_50hz = 0,
+
+ /* stream */
+ .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+ .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ .stream_insert_nav_packets = 0,
+
+ /* audio */
+ .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+ .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+ .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
+ .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+ .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+ .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
+ .audio_mute = 0,
+
+ /* video */
+ .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+ .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
+ .video_b_frames = 2,
+ .video_gop_size = 12,
+ .video_gop_closure = 1,
+ .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .video_bitrate = 6000000,
+ .video_bitrate_peak = 8000000,
+ .video_temporal_decimation = 0,
+ .video_mute = 0,
+ .video_mute_yuv = 0x008080, /* YCbCr value for black */
+
+ /* encoding filters */
+ .video_spatial_filter_mode =
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
+ .video_spatial_filter = 0,
+ .video_luma_spatial_filter_type =
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
+ .video_chroma_spatial_filter_type =
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
+ .video_temporal_filter_mode =
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
+ .video_temporal_filter = 8,
+ .video_median_filter_type =
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
+ .video_luma_median_filter_top = 255,
+ .video_luma_median_filter_bottom = 0,
+ .video_chroma_median_filter_top = 255,
+ .video_chroma_median_filter_bottom = 0,
+};
+
/* Map the control ID to the correct field in the cx2341x_mpeg_params
struct. Return -EINVAL if the ID is unknown, else return 0. */
-static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
+static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
struct v4l2_ext_control *ctrl)
{
switch (ctrl->id) {
@@ -420,7 +475,7 @@ static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
return 0;
}
-int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
+int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
struct v4l2_queryctrl *qctrl)
{
int err;
@@ -430,13 +485,13 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+ default_params.audio_encoding);
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
return v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_L2_BITRATE_192K,
V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_L2_BITRATE_224K);
+ default_params.audio_l2_bitrate);
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
@@ -479,17 +534,22 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return cx2341x_ctrl_query_fill(qctrl,
V4L2_MPEG_STREAM_VBI_FMT_NONE,
V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
- V4L2_MPEG_STREAM_VBI_FMT_NONE);
+ default_params.stream_vbi_fmt);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
+ params->is_50hz ? 12 : 15);
/* CX23415/6 specific */
case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
return cx2341x_ctrl_query_fill(qctrl,
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
+ default_params.video_spatial_filter_mode);
case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
- cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
+ cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
+ default_params.video_spatial_filter);
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
if (params->video_spatial_filter_mode ==
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
@@ -501,7 +561,7 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
1,
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
+ default_params.video_luma_spatial_filter_type);
if (params->video_spatial_filter_mode ==
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
@@ -512,7 +572,7 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
1,
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
+ default_params.video_chroma_spatial_filter_type);
if (params->video_spatial_filter_mode ==
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
@@ -522,10 +582,11 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return cx2341x_ctrl_query_fill(qctrl,
V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
+ default_params.video_temporal_filter_mode);
case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
- cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
+ cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
+ default_params.video_temporal_filter);
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
if (params->video_temporal_filter_mode ==
V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
@@ -536,10 +597,11 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return cx2341x_ctrl_query_fill(qctrl,
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
+ default_params.video_median_filter_type);
case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_luma_median_filter_top);
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
if (params->video_median_filter_type ==
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
@@ -547,7 +609,8 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return 0;
case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_luma_median_filter_bottom);
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
if (params->video_median_filter_type ==
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
@@ -555,7 +618,8 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return 0;
case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_chroma_median_filter_top);
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
if (params->video_median_filter_type ==
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
@@ -563,7 +627,8 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return 0;
case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
- cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_chroma_median_filter_bottom);
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
if (params->video_median_filter_type ==
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
@@ -571,7 +636,8 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
return 0;
case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
- return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+ return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
+ default_params.stream_insert_nav_packets);
default:
return v4l2_ctrl_query_fill_std(qctrl);
@@ -580,9 +646,9 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
}
EXPORT_SYMBOL(cx2341x_ctrl_query);
-const char **cx2341x_ctrl_get_menu(u32 id)
+const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
{
- static const char *mpeg_stream_type[] = {
+ static const char *mpeg_stream_type_without_ts[] = {
"MPEG-2 Program Stream",
"",
"MPEG-1 System Stream",
@@ -592,6 +658,16 @@ const char **cx2341x_ctrl_get_menu(u32 id)
NULL
};
+ static const char *mpeg_stream_type_with_ts[] = {
+ "MPEG-2 Program Stream",
+ "MPEG-2 Transport Stream",
+ "MPEG-1 System Stream",
+ "MPEG-2 DVD-compatible Stream",
+ "MPEG-1 VCD-compatible Stream",
+ "MPEG-2 SVCD-compatible Stream",
+ NULL
+ };
+
static const char *cx2341x_video_spatial_filter_mode_menu[] = {
"Manual",
"Auto",
@@ -630,7 +706,8 @@ const char **cx2341x_ctrl_get_menu(u32 id)
switch (id) {
case V4L2_CID_MPEG_STREAM_TYPE:
- return mpeg_stream_type;
+ return (p->capabilities & CX2341X_CAP_HAS_TS) ?
+ mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return NULL;
@@ -690,7 +767,7 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
if (err)
break;
if (qctrl.type == V4L2_CTRL_TYPE_MENU)
- menu_items = cx2341x_ctrl_get_menu(qctrl.id);
+ menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
if (err)
break;
@@ -714,61 +791,6 @@ EXPORT_SYMBOL(cx2341x_ext_ctrls);
void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
{
- static struct cx2341x_mpeg_params default_params = {
- /* misc */
- .capabilities = 0,
- .port = CX2341X_PORT_MEMORY,
- .width = 720,
- .height = 480,
- .is_50hz = 0,
-
- /* stream */
- .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
- .stream_insert_nav_packets = 0,
-
- /* audio */
- .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
- .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
- .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
- .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
- .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
- .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
- .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
- .audio_mute = 0,
-
- /* video */
- .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
- .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
- .video_b_frames = 2,
- .video_gop_size = 12,
- .video_gop_closure = 1,
- .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- .video_bitrate = 6000000,
- .video_bitrate_peak = 8000000,
- .video_temporal_decimation = 0,
- .video_mute = 0,
- .video_mute_yuv = 0x008080, /* YCbCr value for black */
-
- /* encoding filters */
- .video_spatial_filter_mode =
- V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
- .video_spatial_filter = 0,
- .video_luma_spatial_filter_type =
- V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
- .video_chroma_spatial_filter_type =
- V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
- .video_temporal_filter_mode =
- V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
- .video_temporal_filter = 8,
- .video_median_filter_type =
- V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
- .video_luma_median_filter_top = 255,
- .video_luma_median_filter_bottom = 0,
- .video_chroma_median_filter_top = 255,
- .video_chroma_median_filter_bottom = 0,
- };
-
*p = default_params;
cx2341x_calc_audio_properties(p);
}
@@ -933,9 +955,9 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
}
EXPORT_SYMBOL(cx2341x_update);
-static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
+static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
{
- const char **menu = cx2341x_ctrl_get_menu(id);
+ const char **menu = cx2341x_ctrl_get_menu(p, id);
struct v4l2_ext_control ctrl;
if (menu == NULL)
@@ -952,7 +974,7 @@ invalid:
return "<invalid>";
}
-void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
+void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
{
int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
int temporal = p->video_temporal_filter;
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 7bf14c9a15c..5cfb46bbdaa 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -9,11 +9,13 @@ config VIDEO_CX23885
select VIDEO_TVEEPROM
select VIDEO_IR
select VIDEOBUF_DVB
+ select VIDEOBUF_DMA_SG
select VIDEO_CX25840
select VIDEO_CX2341X
select DVB_DIB7000P if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
+ select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index acdd3b6b3e7..e7ef093265a 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -1173,379 +1173,404 @@ static int cx23885_querymenu(struct cx23885_dev *dev,
qctrl.id = qmenu->id;
cx23885_queryctrl(dev, &qctrl);
return v4l2_ctrl_query_menu(qmenu, &qctrl,
- cx2341x_ctrl_get_menu(qmenu->id));
+ cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
}
-int cx23885_do_ioctl(struct inode *inode, struct file *file, int radio,
- struct cx23885_dev *dev, unsigned int cmd, void *arg,
- v4l2_kioctl driver_ioctl)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
{
- int err;
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+ unsigned int i;
- switch (cmd) {
- /* ---------- tv norms ---------- */
- case VIDIOC_ENUMSTD:
- {
- struct v4l2_standard *e = arg;
- unsigned int i;
-
- i = e->index;
- if (i >= ARRAY_SIZE(cx23885_tvnorms))
- return -EINVAL;
- err = v4l2_video_std_construct(e,
- cx23885_tvnorms[e->index].id,
- cx23885_tvnorms[e->index].name);
- e->index = i;
- if (err < 0)
- return err;
- return 0;
- }
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
+ for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
+ if (*id & cx23885_tvnorms[i].id)
+ break;
+ if (i == ARRAY_SIZE(cx23885_tvnorms))
+ return -EINVAL;
+ dev->encodernorm = cx23885_tvnorms[i];
+ return 0;
+}
- *id = dev->encodernorm.id;
- return 0;
- }
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
- unsigned int i;
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+ struct cx23885_input *input;
+ unsigned int n;
- for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++)
- if (*id & cx23885_tvnorms[i].id)
- break;
- if (i == ARRAY_SIZE(cx23885_tvnorms))
- return -EINVAL;
- dev->encodernorm = cx23885_tvnorms[i];
+ n = i->index;
- return 0;
- }
+ if (n >= 4)
+ return -EINVAL;
- /* ------ input switching ---------- */
- case VIDIOC_ENUMINPUT:
- {
- struct cx23885_input *input;
- struct v4l2_input *i = arg;
- unsigned int n;
-
- n = i->index;
- if (n >= 4)
- return -EINVAL;
- input = &cx23885_boards[dev->board].input[n];
- if (input->type == 0)
- return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = n;
- /* FIXME
- * strcpy(i->name, input->name); */
- strcpy(i->name, "unset");
- if (input->type == CX23885_VMUX_TELEVISION ||
- input->type == CX23885_VMUX_CABLE)
- i->type = V4L2_INPUT_TYPE_TUNER;
- else
- i->type = V4L2_INPUT_TYPE_CAMERA;
+ input = &cx23885_boards[dev->board].input[n];
- for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++)
- i->std |= cx23885_tvnorms[n].id;
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- unsigned int *i = arg;
+ if (input->type == 0)
+ return -EINVAL;
- *i = dev->input;
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- unsigned int *i = arg;
+ memset(i, 0, sizeof(*i));
+ i->index = n;
- if (*i >= 4)
- return -EINVAL;
+ /* FIXME
+ * strcpy(i->name, input->name); */
+ strcpy(i->name, "unset");
- return 0;
- }
+ if (input->type == CX23885_VMUX_TELEVISION ||
+ input->type == CX23885_VMUX_CABLE)
+ i->type = V4L2_INPUT_TYPE_TUNER;
+ else
+ i->type = V4L2_INPUT_TYPE_CAMERA;
- /* --- tuner ioctls ------------------------------------------ */
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
+ for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++)
+ i->std |= cx23885_tvnorms[n].id;
+ return 0;
+}
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (0 != t->index)
- return -EINVAL;
- memset(t, 0, sizeof(*t));
- strcpy(t->name, "Television");
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
+ *i = dev->input;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i >= 4)
+ return -EINVAL;
- if (UNSET == dev->tuner_type)
- return -EINVAL;
+ return 0;
+}
- /* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *t)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- return 0;
- }
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+ if (0 != t->index)
+ return -EINVAL;
+ memset(t, 0, sizeof(*t));
+ strcpy(t->name, "Television");
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
- memset(f, 0, sizeof(*f));
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = dev->freq;
+ dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1],
- VIDIOC_G_FREQUENCY, f);
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
-
- dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n",
- dev->tuner_type);
- dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n",
- f->tuner, f->type);
- if (UNSET == dev->tuner_type)
- return -EINVAL;
- if (f->tuner != 0)
- return -EINVAL;
- if (f->type != V4L2_TUNER_ANALOG_TV)
- return -EINVAL;
- dev->freq = f->frequency;
-
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1],
- VIDIOC_S_FREQUENCY, f);
- return 0;
- }
- case VIDIOC_S_CTRL:
- {
- /* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, arg);
- return 0;
- }
- default:
- /* Convert V4L ioctl to V4L2 and call mpeg_do_ioctl
- * (driver_ioctl) */
- return v4l_compat_translate_ioctl(inode, file, cmd, arg,
- driver_ioctl);
- }
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *t)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+
+ /* Update the A/V core */
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ memset(f, 0, sizeof(*f));
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = dev->freq;
+
+ /* Assumption that tuner is always on bus 1 */
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
+ CX23885_END_NOW, CX23885_MPEG_CAPTURE,
+ CX23885_RAW_BITS_NONE);
+
+ dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n",
+ dev->tuner_type);
+ dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n",
+ f->tuner, f->type);
+ if (UNSET == dev->tuner_type)
+ return -EINVAL;
+ if (f->tuner != 0)
+ return -EINVAL;
+ if (f->type != V4L2_TUNER_ANALOG_TV)
+ return -EINVAL;
+ dev->freq = f->frequency;
+
+ /* Assumption that tuner is always on bus 1 */
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+
+ cx23885_initialize_codec(dev);
return 0;
}
-static int mpeg_do_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, void *arg)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctl)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
+
+ /* Update the A/V core */
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
{
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_tsport *tsport = &dev->ts1;
- if (v4l_debug > 1)
- v4l_print_ioctl(dev->name, cmd);
+ memset(cap, 0, sizeof(*cap));
+ strcpy(cap->driver, dev->name);
+ strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
+ sizeof(cap->card));
+ sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
+ cap->version = CX23885_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING |
+ 0;
+ if (UNSET != dev->tuner_type)
+ cap->capabilities |= V4L2_CAP_TUNER;
- switch (cmd) {
+ return 0;
+}
- /* --- capabilities ------------------------------------------ */
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
-
- memset(cap, 0, sizeof(*cap));
- strcpy(cap->driver, dev->name);
- strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
- sizeof(cap->card));
- sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cap->version = CX23885_VERSION_CODE;
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- 0;
- if (UNSET != dev->tuner_type)
- cap->capabilities |= V4L2_CAP_TUNER;
-
- return 0;
- }
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ int index;
- /* --- capture ioctls ---------------------------------------- */
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
- int index;
-
- index = f->index;
- if (index != 0)
- return -EINVAL;
-
- memset(f, 0, sizeof(*f));
- f->index = index;
- strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->pixelformat = V4L2_PIX_FMT_MPEG;
- return 0;
- }
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
-
- memset(f, 0, sizeof(*f));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.width = dev->ts1.width;
- f->fmt.pix.height = dev->ts1.height;
- f->fmt.pix.field = fh->mpegq.field;
- dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->mpegq.field);
- return 0;
- }
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = arg;
-
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.sizeimage =
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
- dev->ts1.width, dev->ts1.height, fh->mpegq.field);
- return 0;
- }
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
-
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage =
- dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.colorspace = 0;
- dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
- f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
- return 0;
- }
+ index = f->index;
+ if (index != 0)
+ return -EINVAL;
- /* --- streaming capture ------------------------------------- */
- case VIDIOC_REQBUFS:
- return videobuf_reqbufs(&fh->mpegq, arg);
+ memset(f, 0, sizeof(*f));
+ f->index = index;
+ strlcpy(f->description, "MPEG", sizeof(f->description));
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->pixelformat = V4L2_PIX_FMT_MPEG;
- case VIDIOC_QUERYBUF:
- return videobuf_querybuf(&fh->mpegq, arg);
+ return 0;
+}
- case VIDIOC_QBUF:
- return videobuf_qbuf(&fh->mpegq, arg);
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- case VIDIOC_DQBUF:
- return videobuf_dqbuf(&fh->mpegq, arg,
- file->f_flags & O_NONBLOCK);
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage =
+ dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
+ f->fmt.pix.colorspace = 0;
+ f->fmt.pix.width = dev->ts1.width;
+ f->fmt.pix.height = dev->ts1.height;
+ f->fmt.pix.field = fh->mpegq.field;
+ dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
+ dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+ return 0;
+}
- case VIDIOC_STREAMON:
- return videobuf_streamon(&fh->mpegq);
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- case VIDIOC_STREAMOFF:
- return videobuf_streamoff(&fh->mpegq);
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage =
+ dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
+ f->fmt.pix.sizeimage =
+ f->fmt.pix.colorspace = 0;
+ dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
+ dev->ts1.width, dev->ts1.height, fh->mpegq.field);
+ return 0;
+}
- case VIDIOC_G_EXT_CTRLS:
- {
- struct v4l2_ext_controls *f = arg;
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx23885_fh *fh = file->private_data;
+ struct cx23885_dev *dev = fh->dev;
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, cmd);
- }
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *f = arg;
- struct cx2341x_mpeg_params p;
- int err;
-
- if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- p = dev->mpeg_params;
- err = cx2341x_ext_ctrls(&p, 0, f, cmd);
- if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) {
- err = cx2341x_update(dev, cx23885_mbox_func,
- &dev->mpeg_params, &p);
- dev->mpeg_params = p;
- }
- return err;
- }
- case VIDIOC_S_FREQUENCY:
- {
- cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
- CX23885_END_NOW, CX23885_MPEG_CAPTURE,
- CX23885_RAW_BITS_NONE);
- cx23885_do_ioctl(inode, file, 0, dev, cmd, arg,
- mpeg_do_ioctl);
- cx23885_initialize_codec(dev);
-
- return 0;
- }
- case VIDIOC_LOG_STATUS:
- {
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO
- "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
- NULL);
- cx2341x_log_status(&dev->mpeg_params, name);
- printk(KERN_INFO
- "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
- }
- case VIDIOC_QUERYMENU:
- return cx23885_querymenu(dev, arg);
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *c = arg;
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.sizeimage =
+ dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
+ f->fmt.pix.colorspace = 0;
+ dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
+ f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
+ return 0;
+}
- return cx23885_queryctrl(dev, c);
- }
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+{
+ struct cx23885_fh *fh = file->private_data;
- default:
- return cx23885_do_ioctl(inode, file, 0, dev, cmd, arg,
- mpeg_do_ioctl);
+ return videobuf_reqbufs(&fh->mpegq, p);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_querybuf(&fh->mpegq, p);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_qbuf(&fh->mpegq, p);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct cx23885_fh *fh = priv;
+
+ return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK);
+}
+
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type i)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_streamon(&fh->mpegq);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct cx23885_fh *fh = file->private_data;
+
+ return videobuf_streamoff(&fh->mpegq);
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+
+ if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+ return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
+}
+
+static int vidioc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+ struct cx2341x_mpeg_params p;
+ int err;
+
+ if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ p = dev->mpeg_params;
+ err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
+
+ if (err == 0) {
+ err = cx2341x_update(dev, cx23885_mbox_func,
+ &dev->mpeg_params, &p);
+ dev->mpeg_params = p;
}
+ return err;
+}
+
+static int vidioc_try_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *f)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+ struct cx2341x_mpeg_params p;
+ int err;
+
+ if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ p = dev->mpeg_params;
+ err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
+ return err;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+ char name[32 + 2];
+
+ snprintf(name, sizeof(name), "%s/2", dev->name);
+ printk(KERN_INFO
+ "%s/2: ============ START LOG STATUS ============\n",
+ dev->name);
+ cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
+ NULL);
+ cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
+ NULL);
+ cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
+ NULL);
+ cx2341x_log_status(&dev->mpeg_params, name);
+ printk(KERN_INFO
+ "%s/2: ============= END LOG STATUS =============\n",
+ dev->name);
return 0;
}
-static int mpeg_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int vidioc_querymenu(struct file *file, void *priv,
+ struct v4l2_querymenu *a)
+{
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+
+ return cx23885_querymenu(dev, a);
+}
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *c)
{
- return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl);
+ struct cx23885_fh *fh = priv;
+ struct cx23885_dev *dev = fh->dev;
+
+ return cx23885_queryctrl(dev, c);
}
static int mpeg_open(struct inode *inode, struct file *file)
@@ -1670,7 +1695,7 @@ static struct file_operations mpeg_fops = {
.read = mpeg_read,
.poll = mpeg_poll,
.mmap = mpeg_mmap,
- .ioctl = mpeg_ioctl,
+ .ioctl = video_ioctl2,
.llseek = no_llseek,
};
@@ -1682,6 +1707,32 @@ static struct video_device cx23885_mpeg_template = {
VID_TYPE_MPEG_ENCODER,
.fops = &mpeg_fops,
.minor = -1,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
+ .vidioc_log_status = vidioc_log_status,
+ .vidioc_querymenu = vidioc_querymenu,
+ .vidioc_queryctrl = vidioc_queryctrl,
};
void cx23885_417_unregister(struct cx23885_dev *dev)
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 20e05f23054..fd7112c11d3 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -143,6 +143,10 @@ struct cx23885_board cx23885_boards[] = {
.name = "Hauppauge WinTV-HVR1400",
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = {
+ .name = "DViCO FusionHDTV7 Dual Express",
+ .portc = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -210,6 +214,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x0070,
.subdevice = 0x8010,
.card = CX23885_BOARD_HAUPPAUGE_HVR1400,
+ },{
+ .subvendor = 0x18ac,
+ .subdevice = 0xd618,
+ .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -477,6 +485,11 @@ void cx23885_card_setup(struct cx23885_dev *dev)
}
switch (dev->board) {
+ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+ ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ /* break omitted intentionally */
case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index c4cc2f3b887..d17343ea0d3 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -291,9 +291,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
lines = 6;
BUG_ON(lines < 2);
- cx_write(8 + 0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) );
- cx_write(8 + 4, cpu_to_le32(8) );
- cx_write(8 + 8, cpu_to_le32(0) );
+ cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+ cx_write(8 + 4, 8);
+ cx_write(8 + 8, 0);
/* write CDT */
for (i = 0; i < lines; i++) {
@@ -408,11 +408,11 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port,
dev->name, risc->cpu, (unsigned long)risc->dma);
for (i = 0; i < (risc->size >> 2); i += n) {
printk("%s: %04d: ", dev->name, i);
- n = cx23885_risc_decode(risc->cpu[i]);
+ n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i]));
for (j = 1; j < n; j++)
printk("%s: %04d: 0x%08x [ arg #%d ]\n",
dev->name, i + j, risc->cpu[i + j], j);
- if (risc->cpu[i] == RISC_JUMP)
+ if (risc->cpu[i] == cpu_to_le32(RISC_JUMP))
break;
}
}
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 022aa391937..0a2e6558cd6 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -31,6 +31,7 @@
#include <media/v4l2-common.h>
#include "s5h1409.h"
+#include "s5h1411.h"
#include "mt2131.h"
#include "tda8290.h"
#include "tda18271.h"
@@ -164,12 +165,38 @@ static struct s5h1409_config hauppauge_hvr1500q_config = {
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};
+static struct s5h1409_config dvico_s5h1409_config = {
+ .demod_address = 0x32 >> 1,
+ .output_mode = S5H1409_SERIAL_OUTPUT,
+ .gpio = S5H1409_GPIO_ON,
+ .qam_if = 44000,
+ .inversion = S5H1409_INVERSION_OFF,
+ .status_mode = S5H1409_DEMODLOCKING,
+ .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
+static struct s5h1411_config dvico_s5h1411_config = {
+ .output_mode = S5H1411_SERIAL_OUTPUT,
+ .gpio = S5H1411_GPIO_ON,
+ .qam_if = S5H1411_IF_44000,
+ .vsb_if = S5H1411_IF_44000,
+ .inversion = S5H1411_INVERSION_OFF,
+ .status_mode = S5H1411_DEMODLOCKING,
+ .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
.i2c_address = 0x61,
.if_khz = 5380,
.tuner_callback = cx23885_tuner_callback
};
+static struct xc5000_config dvico_xc5000_tunerconfig = {
+ .i2c_address = 0x64,
+ .if_khz = 5380,
+ .tuner_callback = cx23885_tuner_callback
+};
+
static struct tda829x_config tda829x_no_probe = {
.probe_tuner = TDA829X_DONT_PROBE,
};
@@ -453,6 +480,21 @@ static int dvb_register(struct cx23885_tsport *port)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
+ case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
+ i2c_bus = &dev->i2c_bus[port->nr - 1];
+
+ port->dvb.frontend = dvb_attach(s5h1409_attach,
+ &dvico_s5h1409_config,
+ &i2c_bus->i2c_adap);
+ if (port->dvb.frontend == NULL)
+ port->dvb.frontend = dvb_attach(s5h1411_attach,
+ &dvico_s5h1411_config,
+ &i2c_bus->i2c_adap);
+ if (port->dvb.frontend != NULL)
+ dvb_attach(xc5000_attach, port->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ &dvico_xc5000_tunerconfig, i2c_bus);
+ break;
default:
printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->name);
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 84652210a28..043fc4e5c58 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -915,7 +915,7 @@ static void init_controls(struct cx23885_dev *dev)
/* ------------------------------------------------------------------ */
/* VIDEO IOCTLS */
-static int vidioc_g_fmt_cap(struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = priv;
@@ -932,7 +932,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
@@ -983,7 +983,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx23885_fh *fh = priv;
@@ -991,7 +991,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
int err;
dprintk(2, "%s()\n", __func__);
- err = vidioc_try_fmt_cap(file, priv, f);
+ err = vidioc_try_fmt_vid_cap(file, priv, f);
if (0 != err)
return err;
@@ -1025,7 +1025,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap(struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (unlikely(f->index >= ARRAY_SIZE(formats)))
@@ -1440,13 +1440,13 @@ static struct video_device cx23885_video_template = {
.fops = &video_fops,
.minor = -1,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
- .vidioc_g_fmt_vbi = cx23885_vbi_fmt,
- .vidioc_try_fmt_vbi = cx23885_vbi_fmt,
- .vidioc_s_fmt_vbi = cx23885_vbi_fmt,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt,
+ .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt,
+ .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 32af87f25e7..00dfdc89d64 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -63,6 +63,7 @@
#define CX23885_BOARD_HAUPPAUGE_HVR1200 7
#define CX23885_BOARD_HAUPPAUGE_HVR1700 8
#define CX23885_BOARD_HAUPPAUGE_HVR1400 9
+#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 1da6f134888..e7bf4f4c131 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -50,7 +50,6 @@ MODULE_LICENSE("GPL");
static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
int cx25840_debug;
module_param_named(debug,cx25840_debug, int, 0644);
@@ -238,7 +237,7 @@ static void cx25840_initialize(struct i2c_client *client)
cx25840_write(client, 0x8d3, 0x1f);
cx25840_write(client, 0x8e3, 0x03);
- cx25840_vbi_setup(client);
+ cx25840_std_setup(client);
/* trial and error says these are needed to get audio */
cx25840_write(client, 0x914, 0xa0);
@@ -338,7 +337,7 @@ static void cx23885_initialize(struct i2c_client *client)
finish_wait(&state->fw_wait, &wait);
destroy_workqueue(q);
- cx25840_vbi_setup(client);
+ cx25840_std_setup(client);
/* (re)set input */
set_input(client, state->vid_input, state->aud_input);
@@ -349,6 +348,153 @@ static void cx23885_initialize(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
+void cx25840_std_setup(struct i2c_client *client)
+{
+ struct cx25840_state *state = i2c_get_clientdata(client);
+ v4l2_std_id std = state->std;
+ int hblank, hactive, burst, vblank, vactive, sc;
+ int vblank656, src_decimation;
+ int luma_lpf, uv_lpf, comb;
+ u32 pll_int, pll_frac, pll_post;
+
+ /* datasheet startup, step 8d */
+ if (std & ~V4L2_STD_NTSC)
+ cx25840_write(client, 0x49f, 0x11);
+ else
+ cx25840_write(client, 0x49f, 0x14);
+
+ if (std & V4L2_STD_625_50) {
+ hblank = 132;
+ hactive = 720;
+ burst = 93;
+ vblank = 36;
+ vactive = 580;
+ vblank656 = 40;
+ src_decimation = 0x21f;
+ luma_lpf = 2;
+
+ if (std & V4L2_STD_SECAM) {
+ uv_lpf = 0;
+ comb = 0;
+ sc = 0x0a425f;
+ } else if (std == V4L2_STD_PAL_Nc) {
+ uv_lpf = 1;
+ comb = 0x20;
+ sc = 556453;
+ } else {
+ uv_lpf = 1;
+ comb = 0x20;
+ sc = 688739;
+ }
+ } else {
+ hactive = 720;
+ hblank = 122;
+ vactive = 487;
+ luma_lpf = 1;
+ uv_lpf = 1;
+
+ src_decimation = 0x21f;
+ if (std == V4L2_STD_PAL_60) {
+ vblank = 26;
+ vblank656 = 26;
+ burst = 0x5b;
+ luma_lpf = 2;
+ comb = 0x20;
+ sc = 688739;
+ } else if (std == V4L2_STD_PAL_M) {
+ vblank = 20;
+ vblank656 = 24;
+ burst = 0x61;
+ comb = 0x20;
+ sc = 555452;
+ } else {
+ vblank = 26;
+ vblank656 = 26;
+ burst = 0x5b;
+ comb = 0x66;
+ sc = 556063;
+ }
+ }
+
+ /* DEBUG: Displays configured PLL frequency */
+ pll_int = cx25840_read(client, 0x108);
+ pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;
+ pll_post = cx25840_read(client, 0x109);
+ v4l_dbg(1, cx25840_debug, client,
+ "PLL regs = int: %u, frac: %u, post: %u\n",
+ pll_int, pll_frac, pll_post);
+
+ if (pll_post) {
+ int fin, fsc;
+ int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;
+
+ pll /= pll_post;
+ v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
+ pll / 1000000, pll % 1000000);
+ v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
+ pll / 8000000, (pll / 8) % 1000000);
+
+ fin = ((u64)src_decimation * pll) >> 12;
+ v4l_dbg(1, cx25840_debug, client,
+ "ADC Sampling freq = %d.%06d MHz\n",
+ fin / 1000000, fin % 1000000);
+
+ fsc = (((u64)sc) * pll) >> 24L;
+ v4l_dbg(1, cx25840_debug, client,
+ "Chroma sub-carrier freq = %d.%06d MHz\n",
+ fsc / 1000000, fsc % 1000000);
+
+ v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
+ "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
+ "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, "
+ "sc 0x%06x\n",
+ hblank, hactive, vblank, vactive, vblank656,
+ src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+ }
+
+ /* Sets horizontal blanking delay and active lines */
+ cx25840_write(client, 0x470, hblank);
+ cx25840_write(client, 0x471,
+ 0xff & (((hblank >> 8) & 0x3) | (hactive << 4)));
+ cx25840_write(client, 0x472, hactive >> 4);
+
+ /* Sets burst gate delay */
+ cx25840_write(client, 0x473, burst);
+
+ /* Sets vertical blanking delay and active duration */
+ cx25840_write(client, 0x474, vblank);
+ cx25840_write(client, 0x475,
+ 0xff & (((vblank >> 8) & 0x3) | (vactive << 4)));
+ cx25840_write(client, 0x476, vactive >> 4);
+ cx25840_write(client, 0x477, vblank656);
+
+ /* Sets src decimation rate */
+ cx25840_write(client, 0x478, 0xff & src_decimation);
+ cx25840_write(client, 0x479, 0xff & (src_decimation >> 8));
+
+ /* Sets Luma and UV Low pass filters */
+ cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));
+
+ /* Enables comb filters */
+ cx25840_write(client, 0x47b, comb);
+
+ /* Sets SC Step*/
+ cx25840_write(client, 0x47c, sc);
+ cx25840_write(client, 0x47d, 0xff & sc >> 8);
+ cx25840_write(client, 0x47e, 0xff & sc >> 16);
+
+ /* Sets VBI parameters */
+ if (std & V4L2_STD_625_50) {
+ cx25840_write(client, 0x47f, 0x01);
+ state->vbi_line_offset = 5;
+ } else {
+ cx25840_write(client, 0x47f, 0x00);
+ state->vbi_line_offset = 8;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
static void input_change(struct i2c_client *client)
{
struct cx25840_state *state = i2c_get_clientdata(client);
@@ -566,7 +712,7 @@ static int set_v4lstd(struct i2c_client *client)
}
cx25840_and_or(client, 0x400, ~0xf, fmt);
cx25840_and_or(client, 0x403, ~0x3, pal_m);
- cx25840_vbi_setup(client);
+ cx25840_std_setup(client);
if (!state->is_cx25836)
input_change(client);
return 0;
@@ -1058,6 +1204,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
switch (qc->id) {
case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535,
+ 65535 / 100, state->default_volume);
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
@@ -1265,6 +1413,8 @@ static int cx25840_probe(struct i2c_client *client,
state->pvr150_workaround = 0;
state->audmode = V4L2_TUNER_MODE_LANG1;
state->unmute_volume = -1;
+ state->default_volume = 228 - cx25840_read(client, 0x8d4);
+ state->default_volume = ((state->default_volume / 2) + 23) << 9;
state->vbi_line_offset = 8;
state->id = id;
state->rev = device_id;
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 8bf797f48b0..72916ba975a 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -44,6 +44,7 @@ struct cx25840_state {
u32 audclk_freq;
int audmode;
int unmute_volume; /* -1 if not muted */
+ int default_volume;
int vbi_line_offset;
u32 id;
u32 rev;
@@ -61,6 +62,7 @@ int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
u8 cx25840_read(struct i2c_client *client, u16 addr);
u32 cx25840_read4(struct i2c_client *client, u16 addr);
int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value);
+void cx25840_std_setup(struct i2c_client *client);
/* ----------------------------------------------------------------------- */
/* cx25850-firmware.c */
@@ -73,7 +75,6 @@ void cx25840_audio_set_path(struct i2c_client *client);
/* ----------------------------------------------------------------------- */
/* cx25850-vbi.c */
-void cx25840_vbi_setup(struct i2c_client *client);
int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
#endif
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index c754b9d1336..69f2bbdbb92 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -82,150 +82,6 @@ static int decode_vps(u8 * dst, u8 * p)
return err & 0xf0;
}
-void cx25840_vbi_setup(struct i2c_client *client)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
- v4l2_std_id std = state->std;
- int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation;
- int luma_lpf,uv_lpf, comb;
- u32 pll_int,pll_frac,pll_post;
-
- /* datasheet startup, step 8d */
- if (std & ~V4L2_STD_NTSC) {
- cx25840_write(client, 0x49f, 0x11);
- } else {
- cx25840_write(client, 0x49f, 0x14);
- }
-
- if (std & V4L2_STD_625_50) {
- hblank=0x084;
- hactive=0x2d0;
- burst=0x5d;
- vblank=0x024;
- vactive=0x244;
- vblank656=0x28;
- src_decimation=0x21f;
-
- luma_lpf=2;
- if (std & V4L2_STD_SECAM) {
- uv_lpf=0;
- comb=0;
- sc=0x0a425f;
- } else if (std == V4L2_STD_PAL_Nc) {
- uv_lpf=1;
- comb=0x20;
- sc=556453;
- } else {
- uv_lpf=1;
- comb=0x20;
- sc=0x0a8263;
- }
- } else {
- hactive=720;
- hblank=122;
- vactive=487;
- luma_lpf=1;
- uv_lpf=1;
-
- src_decimation=0x21f;
- if (std == V4L2_STD_PAL_60) {
- vblank=26;
- vblank656=26;
- burst=0x5b;
- luma_lpf=2;
- comb=0x20;
- sc=0x0a8263;
- } else if (std == V4L2_STD_PAL_M) {
- vblank=20;
- vblank656=24;
- burst=0x61;
- comb=0x20;
-
- sc=555452;
- } else {
- vblank=26;
- vblank656=26;
- burst=0x5b;
- comb=0x66;
- sc=556063;
- }
- }
-
- /* DEBUG: Displays configured PLL frequency */
- pll_int=cx25840_read(client, 0x108);
- pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff;
- pll_post=cx25840_read(client, 0x109);
- v4l_dbg(1, cx25840_debug, client,
- "PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int,pll_frac,pll_post);
-
- if (pll_post) {
- int fin, fsc;
- int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L;
-
- pll/=pll_post;
- v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n",
- pll/1000000, pll%1000000);
- v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n",
- pll/8000000, (pll/8)%1000000);
-
- fin=((u64)src_decimation*pll)>>12;
- v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = "
- "%d.%06d MHz\n",
- fin/1000000,fin%1000000);
-
- fsc= (((u64)sc)*pll) >> 24L;
- v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = "
- "%d.%06d MHz\n",
- fsc/1000000,fsc%1000000);
-
- v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, "
- "vblank %i, vactive %i, vblank656 %i, src_dec %i, "
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
- " sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
- }
-
- /* Sets horizontal blanking delay and active lines */
- cx25840_write(client, 0x470, hblank);
- cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4)));
- cx25840_write(client, 0x472, hactive>>4);
-
- /* Sets burst gate delay */
- cx25840_write(client, 0x473, burst);
-
- /* Sets vertical blanking delay and active duration */
- cx25840_write(client, 0x474, vblank);
- cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4)));
- cx25840_write(client, 0x476, vactive>>4);
- cx25840_write(client, 0x477, vblank656);
-
- /* Sets src decimation rate */
- cx25840_write(client, 0x478, 0xff&src_decimation);
- cx25840_write(client, 0x479, 0xff&(src_decimation>>8));
-
- /* Sets Luma and UV Low pass filters */
- cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30));
-
- /* Enables comb filters */
- cx25840_write(client, 0x47b, comb);
-
- /* Sets SC Step*/
- cx25840_write(client, 0x47c, sc);
- cx25840_write(client, 0x47d, 0xff&sc>>8);
- cx25840_write(client, 0x47e, 0xff&sc>>16);
-
- /* Sets VBI parameters */
- if (std & V4L2_STD_625_50) {
- cx25840_write(client, 0x47f, 0x01);
- state->vbi_line_offset = 5;
- } else {
- cx25840_write(client, 0x47f, 0x00);
- state->vbi_line_offset = 8;
- }
-}
-
int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct cx25840_state *state = i2c_get_clientdata(client);
@@ -292,8 +148,8 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
/* raw VBI */
memset(svbi, 0, sizeof(*svbi));
- /* Setup VBI */
- cx25840_vbi_setup(client);
+ /* Setup standard */
+ cx25840_std_setup(client);
/* VBI Offset */
cx25840_write(client, 0x47f, vbi_offset);
@@ -304,8 +160,8 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
for (x = 0; x <= 23; x++)
lcr[x] = 0x00;
- /* Setup VBI */
- cx25840_vbi_setup(client);
+ /* Setup standard */
+ cx25840_std_setup(client);
/* Sliced VBI */
cx25840_write(client, 0x404, 0x32); /* Ancillary data */
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 80c8883e54b..06f171ab614 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -82,7 +82,6 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
-
/****************************************************************************
Module global static vars
****************************************************************************/
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 6c0c94c5ef9..bfdca584776 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -715,7 +715,8 @@ static int vidioc_querymenu (struct file *file, void *priv,
qctrl.id = qmenu->id;
blackbird_queryctrl(dev, &qctrl);
- return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
+ return v4l2_ctrl_query_menu(qmenu, &qctrl,
+ cx2341x_ctrl_get_menu(&dev->params, qmenu->id));
}
static int vidioc_querycap (struct file *file, void *priv,
@@ -737,7 +738,7 @@ static int vidioc_querycap (struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap (struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (f->index != 0)
@@ -749,7 +750,7 @@ static int vidioc_enum_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_g_fmt_cap (struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx8802_fh *fh = priv;
@@ -768,7 +769,7 @@ static int vidioc_g_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap (struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx8802_fh *fh = priv;
@@ -784,7 +785,7 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap (struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx8802_fh *fh = priv;
@@ -1181,10 +1182,10 @@ static struct video_device cx8802_mpeg_template =
.minor = -1,
.vidioc_querymenu = vidioc_querymenu,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index cb6a096069c..d7406a994f0 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -103,7 +103,6 @@ static int attach_inform(struct i2c_client *client)
dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
client->driver->driver.name, client->addr, client->name);
-
return 0;
}
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index eea23f95edb..0fed5cd2cce 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1045,7 +1045,7 @@ static void init_controls(struct cx88_core *core)
/* ------------------------------------------------------------------ */
/* VIDEO IOCTLS */
-static int vidioc_g_fmt_cap (struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx8800_fh *fh = priv;
@@ -1061,7 +1061,7 @@ static int vidioc_g_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap (struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core;
@@ -1112,11 +1112,11 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap (struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cx8800_fh *fh = priv;
- int err = vidioc_try_fmt_cap (file,priv,f);
+ int err = vidioc_try_fmt_vid_cap (file,priv,f);
if (0 != err)
return err;
@@ -1147,7 +1147,7 @@ static int vidioc_querycap (struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap (struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (unlikely(f->index >= ARRAY_SIZE(formats)))
@@ -1690,13 +1690,13 @@ static struct video_device cx8800_video_template =
.fops = &video_fops,
.minor = -1,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
- .vidioc_g_fmt_vbi = cx8800_vbi_fmt,
- .vidioc_try_fmt_vbi = cx8800_vbi_fmt,
- .vidioc_s_fmt_vbi = cx8800_vbi_fmt,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt,
+ .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt,
+ .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
index 6ce5af48847..20800425c51 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -30,7 +30,6 @@
#include "cx88.h"
#include "cx88-vp3054-i2c.h"
-
MODULE_DESCRIPTION("driver for cx2388x VP3054 design");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 8cbda43727c..05f0d5a1505 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -173,6 +173,27 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
+ [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = {
+ .name = "Hauppauge WinTV HVR 900 (R2)",
+ .vchannels = 3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XC2028,
+ .mts_firmware = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
[EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
.name = "Hauppauge WinTV HVR 950",
.vchannels = 3,
@@ -196,6 +217,29 @@ struct em28xx_board em28xx_boards[] = {
.amux = 1,
} },
},
+ [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = {
+ .name = "Pinnacle PCTV HD Pro Stick",
+ .vchannels = 3,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_XC2028,
+ .mts_firmware = 1,
+ .has_12mhz_i2s = 1,
+ .has_dvb = 1,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = 0,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = 1,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = 1,
+ } },
+ },
[EM2880_BOARD_TERRATEC_HYBRID_XS] = {
.name = "Terratec Hybrid XS",
.vchannels = 3,
@@ -382,6 +426,19 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
+ [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = {
+ .name = "PointNix Intra-Oral Camera",
+ .has_snapshot_button = 1,
+ .vchannels = 1,
+ .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_SAA7113,
+ .input = { {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = 0,
+ } },
+ },
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
@@ -417,10 +474,12 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
{ USB_DEVICE(0x2304, 0x021a),
.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
+ { USB_DEVICE(0x2304, 0x0227),
+ .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
{ USB_DEVICE(0x2040, 0x6500),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
{ USB_DEVICE(0x2040, 0x6502),
- .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
+ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 },
{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */
@@ -476,6 +535,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash [] = {
static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
+ {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
};
int em28xx_tuner_callback(void *ptr, int command, int arg)
@@ -508,6 +568,7 @@ static void em28xx_set_model(struct em28xx *dev)
dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
dev->has_dvb = em28xx_boards[dev->model].has_dvb;
+ dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button;
}
/* Since em28xx_pre_card_setup() requires a proper dev->model,
@@ -542,8 +603,10 @@ void em28xx_pre_card_setup(struct em28xx *dev)
switch (dev->model) {
case EM2880_BOARD_TERRATEC_PRODIGY_XS:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
case EM2880_BOARD_TERRATEC_HYBRID_XS:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1);
em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
msleep(50);
@@ -576,7 +639,12 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
ctl->demod = XC3028_FE_ZARLINK456;
break;
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
+ /* djh - Not sure which demod we need here */
+ ctl->demod = XC3028_FE_DEFAULT;
+ break;
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
/* FIXME: Better to specify the needed IF */
ctl->demod = XC3028_FE_DEFAULT;
break;
@@ -754,6 +822,7 @@ void em28xx_card_setup(struct em28xx *dev)
switch (dev->model) {
case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
{
struct tveeprom tv;
@@ -787,6 +856,9 @@ void em28xx_card_setup(struct em28xx *dev)
em28xx_set_model(dev);
}
+ if (dev->has_snapshot_button)
+ em28xx_register_snapshot_button(dev);
+
/* Allow override tuner type by a module parameter */
if (tuner >= 0)
dev->tuner_type = tuner;
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 0b2333ee07f..cc61cfb23a4 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -5,6 +5,7 @@
(c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com>
- Fixes for the driver to properly work with HVR-950
+ - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick
(c) 2008 Aidan Thornton <makosoft@googlemail.com>
@@ -26,6 +27,9 @@
#include "lgdt330x.h"
#include "zl10353.h"
+#ifdef EM28XX_DRX397XD_SUPPORT
+#include "drx397xD.h"
+#endif
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -227,6 +231,13 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = {
.if2 = 45600,
};
+#ifdef EM28XX_DRX397XD_SUPPORT
+/* [TODO] djh - not sure yet what the device config needs to contain */
+static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
+ .demod_address = (0xe0 >> 1),
+};
+#endif
+
/* ------------------------------------------------------------------ */
static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -399,6 +410,7 @@ static int dvb_init(struct em28xx *dev)
/* init frontend */
switch (dev->model) {
case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
+ case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
dvb->frontend = dvb_attach(lgdt330x_attach,
&em2880_lgdt3303_dev,
&dev->i2c_adap);
@@ -416,6 +428,19 @@ static int dvb_init(struct em28xx *dev)
goto out_free;
}
break;
+ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
+#ifdef EM28XX_DRX397XD_SUPPORT
+ /* We don't have the config structure properly populated, so
+ this is commented out for now */
+ dvb->frontend = dvb_attach(drx397xD_attach,
+ &em28xx_drx397xD_with_xc3028,
+ &dev->i2c_adap);
+ if (attach_xc3028(0x61, dev) < 0) {
+ result = -EINVAL;
+ goto out_free;
+ }
+ break;
+#endif
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
" isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 6a78fd294ca..97853384c94 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -432,7 +432,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-
/*
* attach_inform()
* gets called when a device attaches to the i2c bus
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index bb5807159b8..eab3d9511af 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -30,6 +30,10 @@
#include "em28xx.h"
+#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
+#define EM28XX_SBUTTON_QUERY_INTERVAL 500
+#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20
+
static unsigned int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
@@ -124,6 +128,89 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
return 1;
}
+static void em28xx_query_sbutton(struct work_struct *work)
+{
+ /* Poll the register and see if the button is depressed */
+ struct em28xx *dev =
+ container_of(work, struct em28xx, sbutton_query_work.work);
+ int ret;
+
+ ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP);
+
+ if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) {
+ u8 cleared;
+ /* Button is depressed, clear the register */
+ cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT;
+ em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1);
+
+ /* Not emulate the keypress */
+ input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
+ 1);
+ /* Now unpress the key */
+ input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY,
+ 0);
+ }
+
+ /* Schedule next poll */
+ schedule_delayed_work(&dev->sbutton_query_work,
+ msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
+}
+
+void em28xx_register_snapshot_button(struct em28xx *dev)
+{
+ struct input_dev *input_dev;
+ int err;
+
+ em28xx_info("Registering snapshot button...\n");
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ em28xx_errdev("input_allocate_device failed\n");
+ return;
+ }
+
+ usb_make_path(dev->udev, dev->snapshot_button_path,
+ sizeof(dev->snapshot_button_path));
+ strlcat(dev->snapshot_button_path, "/sbutton",
+ sizeof(dev->snapshot_button_path));
+ INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton);
+
+ input_dev->name = "em28xx snapshot button";
+ input_dev->phys = dev->snapshot_button_path;
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+ set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit);
+ input_dev->keycodesize = 0;
+ input_dev->keycodemax = 0;
+ input_dev->id.bustype = BUS_USB;
+ input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+ input_dev->id.version = 1;
+ input_dev->dev.parent = &dev->udev->dev;
+
+ err = input_register_device(input_dev);
+ if (err) {
+ em28xx_errdev("input_register_device failed\n");
+ input_free_device(input_dev);
+ return;
+ }
+
+ dev->sbutton_input_dev = input_dev;
+ schedule_delayed_work(&dev->sbutton_query_work,
+ msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL));
+ return;
+
+}
+
+void em28xx_deregister_snapshot_button(struct em28xx *dev)
+{
+ if (dev->sbutton_input_dev != NULL) {
+ em28xx_info("Deregistering snapshot button\n");
+ cancel_rearming_delayed_work(&dev->sbutton_query_work);
+ input_unregister_device(dev->sbutton_input_dev);
+ dev->sbutton_input_dev = NULL;
+ }
+ return;
+}
+
/* ----------------------------------------------------------------------
* Local variables:
* c-basic-offset: 8
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 285bc62bbe4..2d9f14d2a00 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -683,7 +683,7 @@ static void get_scale(struct em28xx *dev,
IOCTL vidioc handling
------------------------------------------------------------------*/
-static int vidioc_g_fmt_cap(struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -706,7 +706,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -766,7 +766,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -777,7 +777,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
if (rc < 0)
return rc;
- vidioc_try_fmt_cap(file, priv, f);
+ vidioc_try_fmt_vid_cap(file, priv, f);
mutex_lock(&dev->lock);
@@ -826,7 +826,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
/* Adjusts width/height, if needed */
f.fmt.pix.width = dev->width;
f.fmt.pix.height = dev->height;
- vidioc_try_fmt_cap(file, priv, &f);
+ vidioc_try_fmt_vid_cap(file, priv, &f);
mutex_lock(&dev->lock);
@@ -1277,7 +1277,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap(struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtd)
{
if (fmtd->index != 0)
@@ -1292,7 +1292,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv,
}
/* Sliced VBI ioctls */
-static int vidioc_g_fmt_vbi_capture(struct file *file, void *priv,
+static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -1316,7 +1316,7 @@ static int vidioc_g_fmt_vbi_capture(struct file *file, void *priv,
return rc;
}
-static int vidioc_try_set_vbi_capture(struct file *file, void *priv,
+static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct em28xx_fh *fh = priv;
@@ -1590,6 +1590,8 @@ static void em28xx_release_resources(struct em28xx *dev)
dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
list_del(&dev->devlist);
+ if (dev->sbutton_input_dev)
+ em28xx_deregister_snapshot_button(dev);
if (dev->radio_dev) {
if (-1 != dev->radio_dev->minor)
video_unregister_device(dev->radio_dev);
@@ -1776,17 +1778,17 @@ static const struct video_device em28xx_video_template = {
.minor = -1,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio,
.vidioc_cropcap = vidioc_cropcap,
- .vidioc_g_fmt_vbi_capture = vidioc_g_fmt_vbi_capture,
- .vidioc_try_fmt_vbi_capture = vidioc_try_set_vbi_capture,
- .vidioc_s_fmt_vbi_capture = vidioc_try_set_vbi_capture,
+ .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+ .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 002f170b211..89842c5d64a 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -55,6 +55,9 @@
#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14
#define EM2800_BOARD_VGEAR_POCKETTV 15
#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16
+#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17
+#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18
+#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -247,6 +250,7 @@ struct em28xx_board {
unsigned int has_12mhz_i2s:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
+ unsigned int has_snapshot_button:1;
enum em28xx_decoder decoder;
@@ -326,6 +330,7 @@ struct em28xx {
unsigned int has_12mhz_i2s:1;
unsigned int max_range_640_480:1;
unsigned int has_dvb:1;
+ unsigned int has_snapshot_button:1;
/* Some older em28xx chips needs a waiting time after writing */
unsigned int wait_after_write;
@@ -416,6 +421,11 @@ struct em28xx {
/* Caches GPO and GPIO registers */
unsigned char reg_gpo, reg_gpio;
+ /* Snapshot button */
+ char snapshot_button_path[30]; /* path of the input dev */
+ struct input_dev *sbutton_input_dev;
+ struct delayed_work sbutton_query_work;
+
struct em28xx_dvb *dvb;
};
@@ -481,6 +491,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
u32 *ir_raw);
+void em28xx_register_snapshot_button(struct em28xx *dev);
+void em28xx_deregister_snapshot_button(struct em28xx *dev);
/* printk macros */
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
new file mode 100644
index 00000000000..42b90742b40
--- /dev/null
+++ b/drivers/media/video/gspca/Kconfig
@@ -0,0 +1,13 @@
+config USB_GSPCA
+ tristate "USB GSPCA driver"
+ depends on VIDEO_V4L2
+ ---help---
+ Say Y here if you want support for various USB webcams.
+
+ See <file:Documentation/video4linux/gspca.txt> for more info.
+
+ This driver uses the Video For Linux API. You must say Y or M to
+ "Video For Linux" to use this driver.
+
+ To compile this driver as modules, choose M here: the
+ modules will be called gspca_xxxx.
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
new file mode 100644
index 00000000000..e68a8965297
--- /dev/null
+++ b/drivers/media/video/gspca/Makefile
@@ -0,0 +1,29 @@
+obj-$(CONFIG_USB_GSPCA) += gspca_main.o \
+ gspca_conex.o gspca_etoms.o gspca_mars.o \
+ gspca_ov519.o gspca_pac207.o gspca_pac7311.o \
+ gspca_sonixb.o gspca_sonixj.o gspca_spca500.o gspca_spca501.o \
+ gspca_spca505.o gspca_spca506.o gspca_spca508.o gspca_spca561.o \
+ gspca_sunplus.o gspca_stk014.o gspca_t613.o gspca_tv8532.o \
+ gspca_vc032x.o gspca_zc3xx.o
+
+gspca_main-objs := gspca.o
+gspca_conex-objs := conex.o
+gspca_etoms-objs := etoms.o
+gspca_mars-objs := mars.o
+gspca_ov519-objs := ov519.o
+gspca_pac207-objs := pac207.o
+gspca_pac7311-objs := pac7311.o
+gspca_sonixb-objs := sonixb.o
+gspca_sonixj-objs := sonixj.o
+gspca_spca500-objs := spca500.o
+gspca_spca501-objs := spca501.o
+gspca_spca505-objs := spca505.o
+gspca_spca506-objs := spca506.o
+gspca_spca508-objs := spca508.o
+gspca_spca561-objs := spca561.o
+gspca_stk014-objs := stk014.o
+gspca_sunplus-objs := sunplus.o
+gspca_t613-objs := t613.o
+gspca_tv8532-objs := tv8532.o
+gspca_vc032x-objs := vc032x.o
+gspca_zc3xx-objs := zc3xx.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
new file mode 100644
index 00000000000..013d593b0c6
--- /dev/null
+++ b/drivers/media/video/gspca/conex.c
@@ -0,0 +1,1051 @@
+/*
+ * Connexant Cx11646 library
+ * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "conex"
+
+#include "gspca.h"
+#define CONEX_CAM 1 /* special JPEG header */
+#include "jpeg.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+
+ unsigned char qindex;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 0xd4
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0x0a,
+ .maximum = 0x1f,
+ .step = 1,
+#define CONTRAST_DEF 0x0c
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 7,
+ .step = 1,
+#define COLOR_DEF 3
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+/* the read bytes are found in gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 index,
+ __u16 len)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (len > sizeof gspca_dev->usb_buf) {
+ err("reg_r: buffer overflow");
+ return;
+ }
+#endif
+ usb_control_msg(dev,
+ usb_rcvctrlpipe(dev, 0),
+ 0,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0,
+ index, gspca_dev->usb_buf, len,
+ 500);
+ PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
+ index, gspca_dev->usb_buf[0]);
+}
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static void reg_w_val(struct gspca_dev *gspca_dev,
+ __u16 index,
+ __u8 val)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ gspca_dev->usb_buf[0] = val;
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0,
+ index, gspca_dev->usb_buf, 1, 500);
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ __u16 index,
+ const __u8 *buffer,
+ __u16 len)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (len > sizeof gspca_dev->usb_buf) {
+ err("reg_w: buffer overflow");
+ return;
+ }
+ PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
+#endif
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0,
+ index, gspca_dev->usb_buf, len, 500);
+}
+
+static const __u8 cx_sensor_init[][4] = {
+ {0x88, 0x11, 0x01, 0x01},
+ {0x88, 0x12, 0x70, 0x01},
+ {0x88, 0x0f, 0x00, 0x01},
+ {0x88, 0x05, 0x01, 0x01},
+ {}
+};
+
+static const __u8 cx11646_fw1[][3] = {
+ {0x00, 0x02, 0x00},
+ {0x01, 0x43, 0x00},
+ {0x02, 0xA7, 0x00},
+ {0x03, 0x8B, 0x01},
+ {0x04, 0xE9, 0x02},
+ {0x05, 0x08, 0x04},
+ {0x06, 0x08, 0x05},
+ {0x07, 0x07, 0x06},
+ {0x08, 0xE7, 0x06},
+ {0x09, 0xC6, 0x07},
+ {0x0A, 0x86, 0x08},
+ {0x0B, 0x46, 0x09},
+ {0x0C, 0x05, 0x0A},
+ {0x0D, 0xA5, 0x0A},
+ {0x0E, 0x45, 0x0B},
+ {0x0F, 0xE5, 0x0B},
+ {0x10, 0x85, 0x0C},
+ {0x11, 0x25, 0x0D},
+ {0x12, 0xC4, 0x0D},
+ {0x13, 0x45, 0x0E},
+ {0x14, 0xE4, 0x0E},
+ {0x15, 0x64, 0x0F},
+ {0x16, 0xE4, 0x0F},
+ {0x17, 0x64, 0x10},
+ {0x18, 0xE4, 0x10},
+ {0x19, 0x64, 0x11},
+ {0x1A, 0xE4, 0x11},
+ {0x1B, 0x64, 0x12},
+ {0x1C, 0xE3, 0x12},
+ {0x1D, 0x44, 0x13},
+ {0x1E, 0xC3, 0x13},
+ {0x1F, 0x24, 0x14},
+ {0x20, 0xA3, 0x14},
+ {0x21, 0x04, 0x15},
+ {0x22, 0x83, 0x15},
+ {0x23, 0xE3, 0x15},
+ {0x24, 0x43, 0x16},
+ {0x25, 0xA4, 0x16},
+ {0x26, 0x23, 0x17},
+ {0x27, 0x83, 0x17},
+ {0x28, 0xE3, 0x17},
+ {0x29, 0x43, 0x18},
+ {0x2A, 0xA3, 0x18},
+ {0x2B, 0x03, 0x19},
+ {0x2C, 0x63, 0x19},
+ {0x2D, 0xC3, 0x19},
+ {0x2E, 0x22, 0x1A},
+ {0x2F, 0x63, 0x1A},
+ {0x30, 0xC3, 0x1A},
+ {0x31, 0x23, 0x1B},
+ {0x32, 0x83, 0x1B},
+ {0x33, 0xE2, 0x1B},
+ {0x34, 0x23, 0x1C},
+ {0x35, 0x83, 0x1C},
+ {0x36, 0xE2, 0x1C},
+ {0x37, 0x23, 0x1D},
+ {0x38, 0x83, 0x1D},
+ {0x39, 0xE2, 0x1D},
+ {0x3A, 0x23, 0x1E},
+ {0x3B, 0x82, 0x1E},
+ {0x3C, 0xC3, 0x1E},
+ {0x3D, 0x22, 0x1F},
+ {0x3E, 0x63, 0x1F},
+ {0x3F, 0xC1, 0x1F},
+ {}
+};
+static void cx11646_fw(struct gspca_dev*gspca_dev)
+{
+ int i = 0;
+
+ reg_w_val(gspca_dev, 0x006a, 0x02);
+ while (cx11646_fw1[i][1]) {
+ reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
+ i++;
+ }
+ reg_w_val(gspca_dev, 0x006a, 0x00);
+}
+
+static const __u8 cxsensor[] = {
+ 0x88, 0x12, 0x70, 0x01,
+ 0x88, 0x0d, 0x02, 0x01,
+ 0x88, 0x0f, 0x00, 0x01,
+ 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
+ 0x88, 0x02, 0x10, 0x01,
+ 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
+ 0x88, 0x0B, 0x00, 0x01,
+ 0x88, 0x0A, 0x0A, 0x01,
+ 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
+ 0x88, 0x05, 0x01, 0x01,
+ 0xA1, 0x18, 0x00, 0x01,
+ 0x00
+};
+
+static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
+static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
+static const __u8 reg10[] = { 0xb1, 0xb1 };
+static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
+static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
+ /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
+static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
+ /* 320{0x04,0x0c,0x05,0x0f}; //320 */
+static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
+static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
+
+static void cx_sensor(struct gspca_dev*gspca_dev)
+{
+ int i = 0;
+ int length;
+ const __u8 *ptsensor = cxsensor;
+
+ reg_w(gspca_dev, 0x0020, reg20, 8);
+ reg_w(gspca_dev, 0x0028, reg28, 8);
+ reg_w(gspca_dev, 0x0010, reg10, 8);
+ reg_w_val(gspca_dev, 0x0092, 0x03);
+
+ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ case 0:
+ reg_w(gspca_dev, 0x0071, reg71a, 4);
+ break;
+ case 1:
+ reg_w(gspca_dev, 0x0071, reg71b, 4);
+ break;
+ default:
+/* case 2: */
+ reg_w(gspca_dev, 0x0071, reg71c, 4);
+ break;
+ case 3:
+ reg_w(gspca_dev, 0x0071, reg71d, 4);
+ break;
+ }
+ reg_w(gspca_dev, 0x007b, reg7b, 6);
+ reg_w_val(gspca_dev, 0x00f8, 0x00);
+ reg_w(gspca_dev, 0x0010, reg10, 8);
+ reg_w_val(gspca_dev, 0x0098, 0x41);
+ for (i = 0; i < 11; i++) {
+ if (i == 3 || i == 5 || i == 8)
+ length = 8;
+ else
+ length = 4;
+ reg_w(gspca_dev, 0x00e5, ptsensor, length);
+ if (length == 4)
+ reg_r(gspca_dev, 0x00e8, 1);
+ else
+ reg_r(gspca_dev, 0x00e8, length);
+ ptsensor += length;
+ }
+ reg_r(gspca_dev, 0x00e7, 8);
+}
+
+static const __u8 cx_inits_176[] = {
+ 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
+ 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
+ 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
+ 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
+ 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
+ 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+static const __u8 cx_inits_320[] = {
+ 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
+ 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
+ 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
+ 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
+ 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
+ 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+static const __u8 cx_inits_352[] = {
+ 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
+ 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
+ 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
+ 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
+ 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
+ 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
+ 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+static const __u8 cx_inits_640[] = {
+ 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
+ 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
+ 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
+ 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
+ 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static void cx11646_initsize(struct gspca_dev *gspca_dev)
+{
+ const __u8 *cxinit;
+ static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
+ static const __u8 reg17[] =
+ { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
+
+ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ case 0:
+ cxinit = cx_inits_640;
+ break;
+ case 1:
+ cxinit = cx_inits_352;
+ break;
+ default:
+/* case 2: */
+ cxinit = cx_inits_320;
+ break;
+ case 3:
+ cxinit = cx_inits_176;
+ break;
+ }
+ reg_w_val(gspca_dev, 0x009a, 0x01);
+ reg_w_val(gspca_dev, 0x0010, 0x10);
+ reg_w(gspca_dev, 0x0012, reg12, 5);
+ reg_w(gspca_dev, 0x0017, reg17, 8);
+ reg_w_val(gspca_dev, 0x00c0, 0x00);
+ reg_w_val(gspca_dev, 0x00c1, 0x04);
+ reg_w_val(gspca_dev, 0x00c2, 0x04);
+
+ reg_w(gspca_dev, 0x0061, cxinit, 8);
+ cxinit += 8;
+ reg_w(gspca_dev, 0x00ca, cxinit, 8);
+ cxinit += 8;
+ reg_w(gspca_dev, 0x00d2, cxinit, 8);
+ cxinit += 8;
+ reg_w(gspca_dev, 0x00da, cxinit, 6);
+ cxinit += 8;
+ reg_w(gspca_dev, 0x0041, cxinit, 8);
+ cxinit += 8;
+ reg_w(gspca_dev, 0x0049, cxinit, 8);
+ cxinit += 8;
+ reg_w(gspca_dev, 0x0051, cxinit, 2);
+
+ reg_r(gspca_dev, 0x0010, 1);
+}
+
+static const __u8 cx_jpeg_init[][8] = {
+ {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
+ {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
+ {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
+ {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
+ {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
+ {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
+ {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
+ {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
+ {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
+ {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
+ {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
+ {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
+ {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
+ {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
+ {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
+ {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
+ {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
+ {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
+ {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
+ {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
+ {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
+ {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
+ {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
+ {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
+ {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
+ {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
+ {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
+ {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
+ {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
+ {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
+ {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
+ {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
+ {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
+ {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
+ {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
+ {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
+ {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
+ {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
+ {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
+ {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
+ {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
+ {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
+ {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
+ {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
+ {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
+ {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
+ {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
+ {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
+ {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
+ {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
+ {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
+ {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
+ {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
+ {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
+ {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
+ {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
+ {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
+ {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
+ {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
+ {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
+ {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
+ {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
+ {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
+ {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
+ {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
+ {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
+ {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
+ {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
+ {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
+ {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
+ {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
+ {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
+ {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
+ {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
+};
+
+
+static const __u8 cxjpeg_640[][8] = {
+ {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
+ {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
+ {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
+ {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
+ {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
+ {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
+ {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
+ {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
+ {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
+ {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
+ {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
+ {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
+ {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
+ {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
+ {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
+ {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
+ {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
+ {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
+ {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
+ {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
+ {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
+ {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
+ {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
+ {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
+ {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
+ {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
+ {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
+};
+static const __u8 cxjpeg_352[][8] = {
+ {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
+ {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
+ {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
+ {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
+ {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
+ {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
+ {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
+ {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
+ {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
+ {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
+ {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
+ {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
+ {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
+ {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
+ {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
+ {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
+ {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
+ {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
+ {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
+ {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
+ {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
+ {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
+ {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
+ {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
+ {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
+ {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
+ {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+static const __u8 cxjpeg_320[][8] = {
+ {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
+ {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
+ {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
+ {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
+ {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
+ {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
+ {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
+ {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
+ {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
+ {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
+ {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
+ {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
+ {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
+ {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
+ {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
+ {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
+ {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
+ {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
+ {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
+ {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
+ {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
+ {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
+ {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
+ {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
+ {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
+ {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
+ {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
+};
+static const __u8 cxjpeg_176[][8] = {
+ {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
+ {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
+ {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
+ {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
+ {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
+ {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
+ {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
+ {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
+ {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
+ {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
+ {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
+ {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
+ {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
+ {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
+ {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
+ {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
+ {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
+ {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
+ {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
+ {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
+ {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
+ {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
+ {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
+ {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
+ {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
+ {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
+ {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
+/* 640 take with the zcx30x part */
+static const __u8 cxjpeg_qtable[][8] = {
+ {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
+ {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
+ {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
+ {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
+ {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
+ {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
+ {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
+ {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
+ {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
+ {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
+ {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
+ {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
+ {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
+ {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
+ {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
+ {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
+ {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
+ {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
+};
+
+
+static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
+{
+ int i;
+ int length;
+
+ reg_w_val(gspca_dev, 0x00c0, 0x01);
+ reg_w_val(gspca_dev, 0x00c3, 0x00);
+ reg_w_val(gspca_dev, 0x00c0, 0x00);
+ reg_r(gspca_dev, 0x0001, 1);
+ length = 8;
+ for (i = 0; i < 79; i++) {
+ if (i == 78)
+ length = 6;
+ reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
+ }
+ reg_r(gspca_dev, 0x0002, 1);
+ reg_w_val(gspca_dev, 0x0055, 0x14);
+}
+
+static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
+static const __u8 regE5_8[] =
+ { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
+static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
+static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
+static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
+static const __u8 reg51[] = { 0x77, 0x03 };
+#define reg70 0x03
+
+static void cx11646_jpeg(struct gspca_dev*gspca_dev)
+{
+ int i;
+ int length;
+ __u8 Reg55;
+ int retry;
+
+ reg_w_val(gspca_dev, 0x00c0, 0x01);
+ reg_w_val(gspca_dev, 0x00c3, 0x00);
+ reg_w_val(gspca_dev, 0x00c0, 0x00);
+ reg_r(gspca_dev, 0x0001, 1);
+ length = 8;
+ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ case 0:
+ for (i = 0; i < 27; i++) {
+ if (i == 26)
+ length = 2;
+ reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
+ }
+ Reg55 = 0x28;
+ break;
+ case 1:
+ for (i = 0; i < 27; i++) {
+ if (i == 26)
+ length = 2;
+ reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
+ }
+ Reg55 = 0x16;
+ break;
+ default:
+/* case 2: */
+ for (i = 0; i < 27; i++) {
+ if (i == 26)
+ length = 2;
+ reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
+ }
+ Reg55 = 0x14;
+ break;
+ case 3:
+ for (i = 0; i < 27; i++) {
+ if (i == 26)
+ length = 2;
+ reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
+ }
+ Reg55 = 0x0B;
+ break;
+ }
+
+ reg_r(gspca_dev, 0x0002, 1);
+ reg_w_val(gspca_dev, 0x0055, Reg55);
+ reg_r(gspca_dev, 0x0002, 1);
+ reg_w(gspca_dev, 0x0010, reg10, 2);
+ reg_w_val(gspca_dev, 0x0054, 0x02);
+ reg_w_val(gspca_dev, 0x0054, 0x01);
+ reg_w_val(gspca_dev, 0x0000, 0x94);
+ reg_w_val(gspca_dev, 0x0053, 0xc0);
+ reg_w_val(gspca_dev, 0x00fc, 0xe1);
+ reg_w_val(gspca_dev, 0x0000, 0x00);
+ /* wait for completion */
+ retry = 50;
+ while (retry--) {
+ reg_r(gspca_dev, 0x0002, 1);
+ /* 0x07 until 0x00 */
+ if (gspca_dev->usb_buf[0] == 0x00)
+ break;
+ reg_w_val(gspca_dev, 0x0053, 0x00);
+ }
+ if (retry == 0)
+ PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
+ /* send the qtable now */
+ reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
+ length = 8;
+ for (i = 0; i < 18; i++) {
+ if (i == 17)
+ length = 2;
+ reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
+
+ }
+ reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
+ reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
+ reg_w_val(gspca_dev, 0x0054, 0x02);
+ reg_w_val(gspca_dev, 0x0054, 0x01);
+ reg_w_val(gspca_dev, 0x0000, 0x94);
+ reg_w_val(gspca_dev, 0x0053, 0xc0);
+
+ reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
+ reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
+ reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
+ reg_w(gspca_dev, 0x0012, reg12, 5);
+ reg_w(gspca_dev, 0x00e5, regE5_8, 8);
+ reg_r(gspca_dev, 0x00e8, 8);
+ reg_w(gspca_dev, 0x00e5, regE5a, 4);
+ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
+ reg_w_val(gspca_dev, 0x009a, 0x01);
+ reg_w(gspca_dev, 0x00e5, regE5b, 4);
+ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
+ reg_w(gspca_dev, 0x00e5, regE5c, 4);
+ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
+
+ reg_w(gspca_dev, 0x0051, reg51, 2);
+ reg_w(gspca_dev, 0x0010, reg10, 2);
+ reg_w_val(gspca_dev, 0x0070, reg70);
+}
+
+static void cx11646_init1(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ reg_w_val(gspca_dev, 0x0010, 0x00);
+ reg_w_val(gspca_dev, 0x0053, 0x00);
+ reg_w_val(gspca_dev, 0x0052, 0x00);
+ reg_w_val(gspca_dev, 0x009b, 0x2f);
+ reg_w_val(gspca_dev, 0x009c, 0x10);
+ reg_r(gspca_dev, 0x0098, 1);
+ reg_w_val(gspca_dev, 0x0098, 0x40);
+ reg_r(gspca_dev, 0x0099, 1);
+ reg_w_val(gspca_dev, 0x0099, 0x07);
+ reg_w_val(gspca_dev, 0x0039, 0x40);
+ reg_w_val(gspca_dev, 0x003c, 0xff);
+ reg_w_val(gspca_dev, 0x003f, 0x1f);
+ reg_w_val(gspca_dev, 0x003d, 0x40);
+/* reg_w_val(gspca_dev, 0x003d, 0x60); */
+ reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
+
+ while (cx_sensor_init[i][0]) {
+ reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
+ reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
+ if (i == 1) {
+ reg_w_val(gspca_dev, 0x00ed, 0x01);
+ reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
+ }
+ i++;
+ }
+ reg_w_val(gspca_dev, 0x00c3, 0x00);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+
+ sd->qindex = 0; /* set the quantization */
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLOR_DEF;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ cx11646_init1(gspca_dev);
+ cx11646_initsize(gspca_dev);
+ cx11646_fw(gspca_dev);
+ cx_sensor(gspca_dev);
+ cx11646_jpegInit(gspca_dev);
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ cx11646_initsize(gspca_dev);
+ cx11646_fw(gspca_dev);
+ cx_sensor(gspca_dev);
+ cx11646_jpeg(gspca_dev);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ int retry = 50;
+
+ reg_w_val(gspca_dev, 0x0000, 0x00);
+ reg_r(gspca_dev, 0x0002, 1);
+ reg_w_val(gspca_dev, 0x0053, 0x00);
+
+ while (retry--) {
+/* reg_r(gspca_dev, 0x0002, 1);*/
+ reg_r(gspca_dev, 0x0053, 1);
+ if (gspca_dev->usb_buf[0] == 0)
+ break;
+ }
+ reg_w_val(gspca_dev, 0x0000, 0x00);
+ reg_r(gspca_dev, 0x0002, 1);
+
+ reg_w_val(gspca_dev, 0x0010, 0x00);
+ reg_r(gspca_dev, 0x0033, 1);
+ reg_w_val(gspca_dev, 0x00fc, 0xe0);
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ if (data[0] == 0xff && data[1] == 0xd8) {
+
+ /* start of frame */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
+
+ /* put the JPEG header in the new frame */
+ jpeg_put_header(gspca_dev, frame,
+ ((struct sd *) gspca_dev)->qindex,
+ 0x22);
+ data += 2;
+ len -= 2;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static void setbrightness(struct gspca_dev*gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
+ __u8 reg51c[2];
+ __u8 bright;
+ __u8 colors;
+
+ bright = sd->brightness;
+ regE5cbx[2] = bright;
+ reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
+ reg_r(gspca_dev, 0x00e8, 8);
+ reg_w(gspca_dev, 0x00e5, regE5c, 4);
+ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
+
+ colors = sd->colors;
+ reg51c[0] = 0x77;
+ reg51c[1] = colors;
+ reg_w(gspca_dev, 0x0051, reg51c, 2);
+ reg_w(gspca_dev, 0x0010, reg10, 2);
+ reg_w_val(gspca_dev, 0x0070, reg70);
+}
+
+static void setcontrast(struct gspca_dev*gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
+/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
+ __u8 reg51c[2];
+
+ regE5acx[2] = sd->contrast;
+ reg_w(gspca_dev, 0x00e5, regE5acx, 4);
+ reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
+ reg51c[0] = 0x77;
+ reg51c[1] = sd->colors;
+ reg_w(gspca_dev, 0x0051, reg51c, 2);
+ reg_w(gspca_dev, 0x0010, reg10, 2);
+ reg_w_val(gspca_dev, 0x0070, reg70);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming) {
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+ }
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+/* sub-driver description */
+static struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
new file mode 100644
index 00000000000..8ab4ea7201a
--- /dev/null
+++ b/drivers/media/video/gspca/etoms.c
@@ -0,0 +1,956 @@
+/*
+ * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004)
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "etoms"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("Etoms USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char autogain;
+
+ char sensor;
+#define SENSOR_PAS106 0
+#define SENSOR_TAS5130CXX 1
+ signed char ag_cnt;
+#define AG_CNT_START 13
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 1,
+ .maximum = 127,
+ .step = 1,
+#define BRIGHTNESS_DEF 63
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define CONTRAST_DEF 127
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 15,
+ .step = 1,
+#define COLOR_DEF 7
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define AUTOGAIN_DEF 1
+ .default_value = AUTOGAIN_DEF,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+/* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}, */
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+#define ETOMS_ALT_SIZE_1000 12
+
+#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */
+#define ET_GPIO_OUT 0x05 /* Only IO data */
+#define ET_GPIO_IN 0x06 /* Read Only IO data */
+#define ET_RESET_ALL 0x03
+#define ET_ClCK 0x01
+#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */
+
+#define ET_COMP 0x12 /* Compression register */
+#define ET_MAXQt 0x13
+#define ET_MINQt 0x14
+#define ET_COMP_VAL0 0x02
+#define ET_COMP_VAL1 0x03
+
+#define ET_REG1d 0x1d
+#define ET_REG1e 0x1e
+#define ET_REG1f 0x1f
+#define ET_REG20 0x20
+#define ET_REG21 0x21
+#define ET_REG22 0x22
+#define ET_REG23 0x23
+#define ET_REG24 0x24
+#define ET_REG25 0x25
+/* base registers for luma calculation */
+#define ET_LUMA_CENTER 0x39
+
+#define ET_G_RED 0x4d
+#define ET_G_GREEN1 0x4e
+#define ET_G_BLUE 0x4f
+#define ET_G_GREEN2 0x50
+#define ET_G_GR_H 0x51
+#define ET_G_GB_H 0x52
+
+#define ET_O_RED 0x34
+#define ET_O_GREEN1 0x35
+#define ET_O_BLUE 0x36
+#define ET_O_GREEN2 0x37
+
+#define ET_SYNCHRO 0x68
+#define ET_STARTX 0x69
+#define ET_STARTY 0x6a
+#define ET_WIDTH_LOW 0x6b
+#define ET_HEIGTH_LOW 0x6c
+#define ET_W_H_HEIGTH 0x6d
+
+#define ET_REG6e 0x6e /* OBW */
+#define ET_REG6f 0x6f /* OBW */
+#define ET_REG70 0x70 /* OBW_AWB */
+#define ET_REG71 0x71 /* OBW_AWB */
+#define ET_REG72 0x72 /* OBW_AWB */
+#define ET_REG73 0x73 /* Clkdelay ns */
+#define ET_REG74 0x74 /* test pattern */
+#define ET_REG75 0x75 /* test pattern */
+
+#define ET_I2C_CLK 0x8c
+#define ET_PXL_CLK 0x60
+
+#define ET_I2C_BASE 0x89
+#define ET_I2C_COUNT 0x8a
+#define ET_I2C_PREFETCH 0x8b
+#define ET_I2C_REG 0x88
+#define ET_I2C_DATA7 0x87
+#define ET_I2C_DATA6 0x86
+#define ET_I2C_DATA5 0x85
+#define ET_I2C_DATA4 0x84
+#define ET_I2C_DATA3 0x83
+#define ET_I2C_DATA2 0x82
+#define ET_I2C_DATA1 0x81
+#define ET_I2C_DATA0 0x80
+
+#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */
+#define PAS106_REG3 0x03 /* line/frame H [11..4] */
+#define PAS106_REG4 0x04 /* line/frame L [3..0] */
+#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */
+#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */
+#define PAS106_REG7 0x07 /* signbit Dac (default 0) */
+#define PAS106_REG9 0x09
+#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */
+#define PAS106_REG13 0x13 /* end i2c write */
+
+static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
+
+static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d };
+
+static const __u8 I2c3[] = { 0x12, 0x05 };
+
+static const __u8 I2c4[] = { 0x41, 0x08 };
+
+/* read 'len' bytes to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 index,
+ __u16 len)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (len > sizeof gspca_dev->usb_buf) {
+ err("reg_r: buffer overflow");
+ return;
+ }
+#endif
+ usb_control_msg(dev,
+ usb_rcvctrlpipe(dev, 0),
+ 0,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0,
+ index, gspca_dev->usb_buf, len, 500);
+ PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
+ index, gspca_dev->usb_buf[0]);
+}
+
+static void reg_w_val(struct gspca_dev *gspca_dev,
+ __u16 index,
+ __u8 val)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ gspca_dev->usb_buf[0] = val;
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0,
+ index, gspca_dev->usb_buf, 1, 500);
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ __u16 index,
+ const __u8 *buffer,
+ __u16 len)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (len > sizeof gspca_dev->usb_buf) {
+ err("reg_w: buffer overflow");
+ return;
+ }
+ PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
+#endif
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0, index, gspca_dev->usb_buf, len, 500);
+}
+
+static int i2c_w(struct gspca_dev *gspca_dev,
+ __u8 reg,
+ const __u8 *buffer,
+ int len, __u8 mode)
+{
+ /* buffer should be [D0..D7] */
+ __u8 ptchcount;
+
+ /* set the base address */
+ reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
+ /* sensor base for the pas106 */
+ /* set count and prefetch */
+ ptchcount = ((len & 0x07) << 4) | (mode & 0x03);
+ reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount);
+ /* set the register base */
+ reg_w_val(gspca_dev, ET_I2C_REG, reg);
+ while (--len >= 0)
+ reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]);
+ return 0;
+}
+
+static int i2c_r(struct gspca_dev *gspca_dev,
+ __u8 reg)
+{
+ /* set the base address */
+ reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
+ /* sensor base for the pas106 */
+ /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */
+ reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11);
+ reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */
+ reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */
+ reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00);
+ reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */
+ return 0;
+}
+
+static int Et_WaitStatus(struct gspca_dev *gspca_dev)
+{
+ int retry = 10;
+
+ while (retry--) {
+ reg_r(gspca_dev, ET_ClCK, 1);
+ if (gspca_dev->usb_buf[0] != 0)
+ return 1;
+ }
+ return 0;
+}
+
+static int et_video(struct gspca_dev *gspca_dev,
+ int on)
+{
+ int ret;
+
+ reg_w_val(gspca_dev, ET_GPIO_OUT,
+ on ? 0x10 /* startvideo - set Bit5 */
+ : 0); /* stopvideo */
+ ret = Et_WaitStatus(gspca_dev);
+ if (ret != 0)
+ PDEBUG(D_ERR, "timeout video on/off");
+ return ret;
+}
+
+static void Et_init2(struct gspca_dev *gspca_dev)
+{
+ __u8 value;
+ static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
+
+ PDEBUG(D_STREAM, "Open Init2 ET");
+ reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
+ reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
+ reg_r(gspca_dev, ET_GPIO_IN, 1);
+ reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */
+ reg_w_val(gspca_dev, ET_CTRL, 0x1b);
+
+ /* compression et subsampling */
+ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
+ value = ET_COMP_VAL1; /* 320 */
+ else
+ value = ET_COMP_VAL0; /* 640 */
+ reg_w_val(gspca_dev, ET_COMP, value);
+ reg_w_val(gspca_dev, ET_MAXQt, 0x1f);
+ reg_w_val(gspca_dev, ET_MINQt, 0x04);
+ /* undocumented registers */
+ reg_w_val(gspca_dev, ET_REG1d, 0xff);
+ reg_w_val(gspca_dev, ET_REG1e, 0xff);
+ reg_w_val(gspca_dev, ET_REG1f, 0xff);
+ reg_w_val(gspca_dev, ET_REG20, 0x35);
+ reg_w_val(gspca_dev, ET_REG21, 0x01);
+ reg_w_val(gspca_dev, ET_REG22, 0x00);
+ reg_w_val(gspca_dev, ET_REG23, 0xff);
+ reg_w_val(gspca_dev, ET_REG24, 0xff);
+ reg_w_val(gspca_dev, ET_REG25, 0x0f);
+ /* colors setting */
+ reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */
+ reg_w_val(gspca_dev, 0x31, 0x40);
+ reg_w_val(gspca_dev, 0x32, 0x00);
+ reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */
+ reg_w_val(gspca_dev, ET_O_GREEN1, 0x00);
+ reg_w_val(gspca_dev, ET_O_BLUE, 0x00);
+ reg_w_val(gspca_dev, ET_O_GREEN2, 0x00);
+ /*************/
+ reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */
+ reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
+ reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
+ reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
+ reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
+ reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */
+ /* Window control registers */
+ reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */
+ reg_w_val(gspca_dev, 0x62, 0x02);
+ reg_w_val(gspca_dev, 0x63, 0x03);
+ reg_w_val(gspca_dev, 0x64, 0x14);
+ reg_w_val(gspca_dev, 0x65, 0x0e);
+ reg_w_val(gspca_dev, 0x66, 0x02);
+ reg_w_val(gspca_dev, 0x67, 0x02);
+
+ /**************************************/
+ reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */
+ reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */
+ reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */
+ reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80);
+ reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0);
+ reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */
+ reg_w_val(gspca_dev, ET_REG6e, 0x86);
+ reg_w_val(gspca_dev, ET_REG6f, 0x01);
+ reg_w_val(gspca_dev, ET_REG70, 0x26);
+ reg_w_val(gspca_dev, ET_REG71, 0x7a);
+ reg_w_val(gspca_dev, ET_REG72, 0x01);
+ /* Clock Pattern registers ***************** */
+ reg_w_val(gspca_dev, ET_REG73, 0x00);
+ reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */
+ reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */
+ /**********************************************/
+ reg_w_val(gspca_dev, 0x8a, 0x20);
+ reg_w_val(gspca_dev, 0x8d, 0x0f);
+ reg_w_val(gspca_dev, 0x8e, 0x08);
+ /**************************************/
+ reg_w_val(gspca_dev, 0x03, 0x08);
+ reg_w_val(gspca_dev, ET_PXL_CLK, 0x03);
+ reg_w_val(gspca_dev, 0x81, 0xff);
+ reg_w_val(gspca_dev, 0x80, 0x00);
+ reg_w_val(gspca_dev, 0x81, 0xff);
+ reg_w_val(gspca_dev, 0x80, 0x20);
+ reg_w_val(gspca_dev, 0x03, 0x01);
+ reg_w_val(gspca_dev, 0x03, 0x00);
+ reg_w_val(gspca_dev, 0x03, 0x08);
+ /********************************************/
+
+/* reg_r(gspca_dev, ET_I2C_BASE, 1);
+ always 0x40 as the pas106 ??? */
+ /* set the sensor */
+ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
+ value = 0x04; /* 320 */
+ else /* 640 */
+ value = 0x1e; /* 0x17 * setting PixelClock
+ * 0x03 mean 24/(3+1) = 6 Mhz
+ * 0x05 -> 24/(5+1) = 4 Mhz
+ * 0x0b -> 24/(11+1) = 2 Mhz
+ * 0x17 -> 24/(23+1) = 1 Mhz
+ */
+ reg_w_val(gspca_dev, ET_PXL_CLK, value);
+ /* now set by fifo the FormatLine setting */
+ reg_w(gspca_dev, 0x62, FormLine, 6);
+
+ /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */
+ reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */
+ reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */
+ /* Pedro change */
+ /* Brightness change Brith+ decrease value */
+ /* Brigth- increase value */
+ /* original value = 0x70; */
+ reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */
+ reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d };
+ __u8 i2cflags = 0x01;
+ /* __u8 green = 0; */
+ __u8 colors = sd->colors;
+
+ I2cc[3] = colors; /* red */
+ I2cc[0] = 15 - colors; /* blue */
+ /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */
+ /* I2cc[1] = I2cc[2] = green; */
+ if (sd->sensor == SENSOR_PAS106) {
+ i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
+ i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
+ }
+/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
+ I2cc[3], I2cc[0], green); */
+}
+
+static void getcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor == SENSOR_PAS106) {
+/* i2c_r(gspca_dev, PAS106_REG9); * blue */
+ i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */
+ sd->colors = gspca_dev->usb_buf[0] & 0x0f;
+ }
+}
+
+static void Et_init1(struct gspca_dev *gspca_dev)
+{
+ __u8 value;
+/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */
+ __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 };
+ /* try 1/120 0x6d 0xcd 0x40 */
+/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00};
+ * 1/60000 hmm ?? */
+
+ PDEBUG(D_STREAM, "Open Init1 ET");
+ reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
+ reg_r(gspca_dev, ET_GPIO_IN, 1);
+ reg_w_val(gspca_dev, ET_RESET_ALL, 1);
+ reg_w_val(gspca_dev, ET_RESET_ALL, 0);
+ reg_w_val(gspca_dev, ET_ClCK, 0x10);
+ reg_w_val(gspca_dev, ET_CTRL, 0x19);
+ /* compression et subsampling */
+ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
+ value = ET_COMP_VAL1;
+ else
+ value = ET_COMP_VAL0;
+ PDEBUG(D_STREAM, "Open mode %d Compression %d",
+ gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
+ value);
+ reg_w_val(gspca_dev, ET_COMP, value);
+ reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
+ reg_w_val(gspca_dev, ET_MINQt, 0x02);
+ /* undocumented registers */
+ reg_w_val(gspca_dev, ET_REG1d, 0xff);
+ reg_w_val(gspca_dev, ET_REG1e, 0xff);
+ reg_w_val(gspca_dev, ET_REG1f, 0xff);
+ reg_w_val(gspca_dev, ET_REG20, 0x35);
+ reg_w_val(gspca_dev, ET_REG21, 0x01);
+ reg_w_val(gspca_dev, ET_REG22, 0x00);
+ reg_w_val(gspca_dev, ET_REG23, 0xf7);
+ reg_w_val(gspca_dev, ET_REG24, 0xff);
+ reg_w_val(gspca_dev, ET_REG25, 0x07);
+ /* colors setting */
+ reg_w_val(gspca_dev, ET_G_RED, 0x80);
+ reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
+ reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
+ reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
+ reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
+ reg_w_val(gspca_dev, ET_G_GB_H, 0x00);
+ /* Window control registers */
+ reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0);
+ reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */
+ reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */
+ reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60);
+ reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20);
+ reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50);
+ reg_w_val(gspca_dev, ET_REG6e, 0x86);
+ reg_w_val(gspca_dev, ET_REG6f, 0x01);
+ reg_w_val(gspca_dev, ET_REG70, 0x86);
+ reg_w_val(gspca_dev, ET_REG71, 0x14);
+ reg_w_val(gspca_dev, ET_REG72, 0x00);
+ /* Clock Pattern registers */
+ reg_w_val(gspca_dev, ET_REG73, 0x00);
+ reg_w_val(gspca_dev, ET_REG74, 0x00);
+ reg_w_val(gspca_dev, ET_REG75, 0x0a);
+ reg_w_val(gspca_dev, ET_I2C_CLK, 0x04);
+ reg_w_val(gspca_dev, ET_PXL_CLK, 0x01);
+ /* set the sensor */
+ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ I2c0[0] = 0x06;
+ i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
+ i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
+ value = 0x06;
+ i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
+ i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
+ /* value = 0x1f; */
+ value = 0x04;
+ i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
+ } else {
+ I2c0[0] = 0x0a;
+
+ i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
+ i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
+ value = 0x0a;
+ i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
+ i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
+ value = 0x04;
+ /* value = 0x10; */
+ i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
+ /* bit 2 enable bit 1:2 select 0 1 2 3
+ value = 0x07; * curve 0 *
+ i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1);
+ */
+ }
+
+/* value = 0x01; */
+/* value = 0x22; */
+/* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */
+ /* magnetude and sign bit for DAC */
+ i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1);
+ /* now set by fifo the whole colors setting */
+ reg_w(gspca_dev, ET_G_RED, GainRGBG, 6);
+ getcolors(gspca_dev);
+ setcolors(gspca_dev);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 vendor;
+ __u16 product;
+
+ vendor = id->idVendor;
+ product = id->idProduct;
+/* switch (vendor) { */
+/* case 0x102c: * Etoms */
+ switch (product) {
+ case 0x6151:
+ sd->sensor = SENSOR_PAS106; /* Etoms61x151 */
+ break;
+ case 0x6251:
+ sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */
+ break;
+/* } */
+/* break; */
+ }
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 1;
+ if (sd->sensor == SENSOR_PAS106) {
+ cam->cam_mode = sif_mode;
+ cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ } else {
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ }
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLOR_DEF;
+ sd->autogain = AUTOGAIN_DEF;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor == SENSOR_PAS106)
+ Et_init1(gspca_dev);
+ else
+ Et_init2(gspca_dev);
+ reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
+ et_video(gspca_dev, 0); /* video off */
+ return 0;
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor == SENSOR_PAS106)
+ Et_init1(gspca_dev);
+ else
+ Et_init2(gspca_dev);
+
+ reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
+ et_video(gspca_dev, 1); /* video on */
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ et_video(gspca_dev, 0); /* video off */
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ __u8 brightness = sd->brightness;
+
+ for (i = 0; i < 4; i++)
+ reg_w_val(gspca_dev, ET_O_RED + i, brightness);
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ int brightness = 0;
+
+ for (i = 0; i < 4; i++) {
+ reg_r(gspca_dev, ET_O_RED + i, 1);
+ brightness += gspca_dev->usb_buf[0];
+ }
+ sd->brightness = brightness >> 3;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
+ __u8 contrast = sd->contrast;
+
+ memset(RGBG, contrast, sizeof(RGBG) - 2);
+ reg_w(gspca_dev, ET_G_RED, RGBG, 6);
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ int contrast = 0;
+
+ for (i = 0; i < 4; i++) {
+ reg_r(gspca_dev, ET_G_RED + i, 1);
+ contrast += gspca_dev->usb_buf[0];
+ }
+ sd->contrast = contrast >> 2;
+}
+
+static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor == SENSOR_PAS106) {
+ i2c_r(gspca_dev, PAS106_REG0e);
+ PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]);
+ return gspca_dev->usb_buf[0];
+ }
+ return 0x1f;
+}
+
+static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor == SENSOR_PAS106) {
+ __u8 i2cflags = 0x01;
+
+ i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
+ i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1);
+ }
+}
+
+#define BLIMIT(bright) \
+ (__u8)((bright > 0x1f)?0x1f:((bright < 4)?3:bright))
+#define LIMIT(color) \
+ (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color))
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+ __u8 luma = 0;
+ __u8 luma_mean = 128;
+ __u8 luma_delta = 20;
+ __u8 spring = 4;
+ int Gbright = 0;
+ __u8 r, g, b;
+
+ Gbright = Et_getgainG(gspca_dev);
+ reg_r(gspca_dev, ET_LUMA_CENTER, 4);
+ g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
+ r = gspca_dev->usb_buf[1];
+ b = gspca_dev->usb_buf[2];
+ r = ((r << 8) - (r << 4) - (r << 3)) >> 10;
+ b = ((b << 7) >> 10);
+ g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
+ luma = LIMIT(r + g + b);
+ PDEBUG(D_FRAM, "Etoms luma G %d", luma);
+ if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
+ Gbright += (luma_mean - luma) >> spring;
+ Gbright = BLIMIT(Gbright);
+ PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright);
+ Et_setgainG(gspca_dev, (__u8) Gbright);
+ }
+}
+
+#undef BLIMIT
+#undef LIMIT
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd;
+ int seqframe;
+
+ seqframe = data[0] & 0x3f;
+ len = (int) (((data[0] & 0xc0) << 2) | data[1]);
+ if (seqframe == 0x3f) {
+ PDEBUG(D_FRAM,
+ "header packet found datalength %d !!", len);
+ PDEBUG(D_FRAM, "G %d R %d G %d B %d",
+ data[2], data[3], data[4], data[5]);
+ data += 30;
+ /* don't change datalength as the chips provided it */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+ sd = (struct sd *) gspca_dev;
+ if (sd->ag_cnt >= 0) {
+ if (--sd->ag_cnt < 0) {
+ sd->ag_cnt = AG_CNT_START;
+ setautogain(gspca_dev);
+ }
+ }
+ return;
+ }
+ if (len) {
+ data += 8;
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+ } else { /* Drop Packet */
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ }
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcontrast(gspca_dev);
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcolors(gspca_dev);
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (val)
+ sd->ag_cnt = AG_CNT_START;
+ else
+ sd->ag_cnt = -1;
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+/* sub-driver description */
+static struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static __devinitdata struct usb_device_id device_table[] = {
+#ifndef CONFIG_USB_ET61X251
+ {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")},
+#endif
+ {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
new file mode 100644
index 00000000000..16e367cec76
--- /dev/null
+++ b/drivers/media/video/gspca/gspca.c
@@ -0,0 +1,1905 @@
+/*
+ * Main USB camera driver
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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.
+ */
+
+#define MODULE_NAME "gspca"
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pagemap.h>
+#include <linux/io.h>
+#include <asm/page.h>
+#include <linux/uaccess.h>
+#include <linux/jiffies.h>
+
+#include "gspca.h"
+
+/* global values */
+#define DEF_NURBS 2 /* default number of URBs */
+
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
+MODULE_DESCRIPTION("GSPCA USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+static int video_nr = -1;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int gspca_debug = D_ERR | D_PROBE;
+EXPORT_SYMBOL(gspca_debug);
+
+static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h)
+{
+ if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') {
+ PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d",
+ txt,
+ pixfmt & 0xff,
+ (pixfmt >> 8) & 0xff,
+ (pixfmt >> 16) & 0xff,
+ pixfmt >> 24,
+ w, h);
+ } else {
+ PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d",
+ txt,
+ pixfmt,
+ w, h);
+ }
+}
+#else
+#define PDEBUG_MODE(txt, pixfmt, w, h)
+#endif
+
+/* specific memory types - !! should different from V4L2_MEMORY_xxx */
+#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */
+#define GSPCA_MEMORY_READ 7
+
+#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)
+
+/*
+ * VMA operations.
+ */
+static void gspca_vm_open(struct vm_area_struct *vma)
+{
+ struct gspca_frame *frame = vma->vm_private_data;
+
+ frame->vma_use_count++;
+ frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED;
+}
+
+static void gspca_vm_close(struct vm_area_struct *vma)
+{
+ struct gspca_frame *frame = vma->vm_private_data;
+
+ if (--frame->vma_use_count <= 0)
+ frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED;
+}
+
+static struct vm_operations_struct gspca_vm_ops = {
+ .open = gspca_vm_open,
+ .close = gspca_vm_close,
+};
+
+/*
+ * fill a video frame from an URB and resubmit
+ */
+static void fill_frame(struct gspca_dev *gspca_dev,
+ struct urb *urb)
+{
+ struct gspca_frame *frame;
+ __u8 *data; /* address of data in the iso message */
+ int i, j, len, st;
+ cam_pkt_op pkt_scan;
+
+ if (urb->status != 0) {
+ PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
+ return; /* disconnection ? */
+ }
+ pkt_scan = gspca_dev->sd_desc->pkt_scan;
+ for (i = 0; i < urb->number_of_packets; i++) {
+
+ /* check the availability of the frame buffer */
+ j = gspca_dev->fr_i;
+ j = gspca_dev->fr_queue[j];
+ frame = &gspca_dev->frame[j];
+ if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
+ != V4L2_BUF_FLAG_QUEUED) {
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ break;
+ }
+
+ /* check the packet status and length */
+ len = urb->iso_frame_desc[i].actual_length;
+ if (len == 0)
+ continue;
+ st = urb->iso_frame_desc[i].status;
+ if (st) {
+ PDEBUG(D_ERR,
+ "ISOC data error: [%d] len=%d, status=%d",
+ i, len, st);
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ continue;
+ }
+
+ /* let the packet be analyzed by the subdriver */
+ PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
+ i, urb->iso_frame_desc[i].offset, len);
+ data = (__u8 *) urb->transfer_buffer
+ + urb->iso_frame_desc[i].offset;
+ pkt_scan(gspca_dev, frame, data, len);
+ }
+
+ /* resubmit the URB */
+ urb->status = 0;
+ st = usb_submit_urb(urb, GFP_ATOMIC);
+ if (st < 0)
+ PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st);
+}
+
+/*
+ * ISOC message interrupt from the USB device
+ *
+ * Analyse each packet and call the subdriver for copy to the frame buffer.
+ */
+static void isoc_irq(struct urb *urb
+)
+{
+ struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
+
+ PDEBUG(D_PACK, "isoc irq");
+ if (!gspca_dev->streaming)
+ return;
+ fill_frame(gspca_dev, urb);
+}
+
+/*
+ * add data to the current frame
+ *
+ * This function is called by the subdrivers at interrupt level.
+ *
+ * To build a frame, these ones must add
+ * - one FIRST_PACKET
+ * - 0 or many INTER_PACKETs
+ * - one LAST_PACKET
+ * DISCARD_PACKET invalidates the whole frame.
+ * On LAST_PACKET, a new frame is returned.
+ */
+struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
+ int packet_type,
+ struct gspca_frame *frame,
+ const __u8 *data,
+ int len)
+{
+ int i, j;
+
+ PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
+
+ /* when start of a new frame, if the current frame buffer
+ * is not queued, discard the whole frame */
+ if (packet_type == FIRST_PACKET) {
+ if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
+ != V4L2_BUF_FLAG_QUEUED) {
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ return frame;
+ }
+ frame->data_end = frame->data;
+ jiffies_to_timeval(get_jiffies_64(),
+ &frame->v4l2_buf.timestamp);
+ frame->v4l2_buf.sequence = ++gspca_dev->sequence;
+ } else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
+ return frame;
+ }
+
+ /* append the packet to the frame buffer */
+ if (len > 0) {
+ if (frame->data_end - frame->data + len
+ > frame->v4l2_buf.length) {
+ PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d",
+ frame->data_end - frame->data + len,
+ frame->v4l2_buf.length);
+ packet_type = DISCARD_PACKET;
+ } else {
+ memcpy(frame->data_end, data, len);
+ frame->data_end += len;
+ }
+ }
+ gspca_dev->last_packet_type = packet_type;
+
+ /* if last packet, wake the application and advance in the queue */
+ if (packet_type == LAST_PACKET) {
+ frame->v4l2_buf.bytesused = frame->data_end - frame->data;
+ frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
+ frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
+ atomic_inc(&gspca_dev->nevent);
+ wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
+ i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
+ gspca_dev->fr_i = i;
+ PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
+ frame->v4l2_buf.bytesused,
+ gspca_dev->fr_q,
+ i,
+ gspca_dev->fr_o);
+ j = gspca_dev->fr_queue[i];
+ frame = &gspca_dev->frame[j];
+ }
+ return frame;
+}
+EXPORT_SYMBOL(gspca_frame_add);
+
+static int gspca_is_compressed(__u32 format)
+{
+ switch (format) {
+ case V4L2_PIX_FMT_MJPEG:
+ case V4L2_PIX_FMT_JPEG:
+ case V4L2_PIX_FMT_SPCA561:
+ case V4L2_PIX_FMT_PAC207:
+ return 1;
+ }
+ return 0;
+}
+
+static void *rvmalloc(unsigned long size)
+{
+ void *mem;
+ unsigned long adr;
+
+/* size = PAGE_ALIGN(size); (already done) */
+ mem = vmalloc_32(size);
+ if (mem != NULL) {
+ adr = (unsigned long) mem;
+ while ((long) size > 0) {
+ SetPageReserved(vmalloc_to_page((void *) adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ }
+ return mem;
+}
+
+static void rvfree(void *mem, long size)
+{
+ unsigned long adr;
+
+ adr = (unsigned long) mem;
+ while (size > 0) {
+ ClearPageReserved(vmalloc_to_page((void *) adr));
+ adr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+ vfree(mem);
+}
+
+static int frame_alloc(struct gspca_dev *gspca_dev,
+ unsigned int count)
+{
+ struct gspca_frame *frame;
+ unsigned int frsz;
+ int i;
+
+ i = gspca_dev->curr_mode;
+ frsz = gspca_dev->cam.cam_mode[i].sizeimage;
+ PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
+ frsz = PAGE_ALIGN(frsz);
+ gspca_dev->frsz = frsz;
+ if (count > GSPCA_MAX_FRAMES)
+ count = GSPCA_MAX_FRAMES;
+ gspca_dev->frbuf = rvmalloc(frsz * count);
+ if (!gspca_dev->frbuf) {
+ err("frame alloc failed");
+ return -ENOMEM;
+ }
+ gspca_dev->nframes = count;
+ for (i = 0; i < count; i++) {
+ frame = &gspca_dev->frame[i];
+ frame->v4l2_buf.index = i;
+ frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ frame->v4l2_buf.flags = 0;
+ frame->v4l2_buf.field = V4L2_FIELD_NONE;
+ frame->v4l2_buf.length = frsz;
+ frame->v4l2_buf.memory = gspca_dev->memory;
+ frame->v4l2_buf.sequence = 0;
+ frame->data = frame->data_end =
+ gspca_dev->frbuf + i * frsz;
+ frame->v4l2_buf.m.offset = i * frsz;
+ }
+ gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ gspca_dev->sequence = 0;
+ atomic_set(&gspca_dev->nevent, 0);
+ return 0;
+}
+
+static void frame_free(struct gspca_dev *gspca_dev)
+{
+ int i;
+
+ PDEBUG(D_STREAM, "frame free");
+ if (gspca_dev->frbuf != NULL) {
+ rvfree(gspca_dev->frbuf,
+ gspca_dev->nframes * gspca_dev->frsz);
+ gspca_dev->frbuf = NULL;
+ for (i = 0; i < gspca_dev->nframes; i++)
+ gspca_dev->frame[i].data = NULL;
+ }
+ gspca_dev->nframes = 0;
+}
+
+static void destroy_urbs(struct gspca_dev *gspca_dev)
+{
+ struct urb *urb;
+ unsigned int i;
+
+ PDEBUG(D_STREAM, "kill transfer");
+ for (i = 0; i < MAX_NURBS; ++i) {
+ urb = gspca_dev->urb[i];
+ if (urb == NULL)
+ break;
+
+ gspca_dev->urb[i] = NULL;
+ usb_kill_urb(urb);
+ if (urb->transfer_buffer != NULL)
+ usb_buffer_free(gspca_dev->dev,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer,
+ urb->transfer_dma);
+ usb_free_urb(urb);
+ }
+}
+
+/*
+ * search an input isochronous endpoint in an alternate setting
+ */
+static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt,
+ __u8 epaddr)
+{
+ struct usb_host_endpoint *ep;
+ int i, attr;
+
+ epaddr |= USB_DIR_IN;
+ for (i = 0; i < alt->desc.bNumEndpoints; i++) {
+ ep = &alt->endpoint[i];
+ if (ep->desc.bEndpointAddress == epaddr) {
+ attr = ep->desc.bmAttributes
+ & USB_ENDPOINT_XFERTYPE_MASK;
+ if (attr == USB_ENDPOINT_XFER_ISOC)
+ return ep;
+ break;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * search an input isochronous endpoint
+ *
+ * The endpoint is defined by the subdriver.
+ * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep).
+ * This routine may be called many times when the bandwidth is too small
+ * (the bandwidth is checked on urb submit).
+ */
+struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev)
+{
+ struct usb_interface *intf;
+ struct usb_host_endpoint *ep;
+ int i, ret;
+
+ intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
+ ep = NULL;
+ i = gspca_dev->alt; /* previous alt setting */
+ while (--i > 0) { /* alt 0 is unusable */
+ ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr);
+ if (ep)
+ break;
+ }
+ if (ep == NULL) {
+ err("no ISOC endpoint found");
+ return NULL;
+ }
+ PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x",
+ i, ep->desc.bEndpointAddress);
+ ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
+ if (ret < 0) {
+ err("set interface err %d", ret);
+ return NULL;
+ }
+ gspca_dev->alt = i; /* memorize the current alt setting */
+ return ep;
+}
+
+/*
+ * create the isochronous URBs
+ */
+static int create_urbs(struct gspca_dev *gspca_dev,
+ struct usb_host_endpoint *ep)
+{
+ struct urb *urb;
+ int n, nurbs, i, psize, npkt, bsize;
+
+ /* calculate the packet size and the number of packets */
+ psize = le16_to_cpu(ep->desc.wMaxPacketSize);
+
+ /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
+ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ npkt = ISO_MAX_SIZE / psize;
+ if (npkt > ISO_MAX_PKT)
+ npkt = ISO_MAX_PKT;
+ bsize = psize * npkt;
+ PDEBUG(D_STREAM,
+ "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize);
+ nurbs = DEF_NURBS;
+ gspca_dev->nurbs = nurbs;
+ for (n = 0; n < nurbs; n++) {
+ urb = usb_alloc_urb(npkt, GFP_KERNEL);
+ if (!urb) {
+ err("usb_alloc_urb failed");
+ return -ENOMEM;
+ }
+ urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev,
+ bsize,
+ GFP_KERNEL,
+ &urb->transfer_dma);
+
+ if (urb->transfer_buffer == NULL) {
+ usb_free_urb(urb);
+ destroy_urbs(gspca_dev);
+ err("usb_buffer_urb failed");
+ return -ENOMEM;
+ }
+ gspca_dev->urb[n] = urb;
+ urb->dev = gspca_dev->dev;
+ urb->context = gspca_dev;
+ urb->pipe = usb_rcvisocpipe(gspca_dev->dev,
+ ep->desc.bEndpointAddress);
+ urb->transfer_flags = URB_ISO_ASAP
+ | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = ep->desc.bInterval;
+ urb->complete = isoc_irq;
+ urb->number_of_packets = npkt;
+ urb->transfer_buffer_length = bsize;
+ for (i = 0; i < npkt; i++) {
+ urb->iso_frame_desc[i].length = psize;
+ urb->iso_frame_desc[i].offset = psize * i;
+ }
+ }
+ return 0;
+}
+
+/*
+ * start the USB transfer
+ */
+static int gspca_init_transfer(struct gspca_dev *gspca_dev)
+{
+ struct usb_host_endpoint *ep;
+ int n, ret;
+
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+
+ /* set the higher alternate setting and
+ * loop until urb submit succeeds */
+ gspca_dev->alt = gspca_dev->nbalt;
+ for (;;) {
+ PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
+ ep = get_isoc_ep(gspca_dev);
+ if (ep == NULL) {
+ ret = -EIO;
+ goto out;
+ }
+ ret = create_urbs(gspca_dev, ep);
+ if (ret < 0)
+ goto out;
+
+ /* start the cam */
+ gspca_dev->sd_desc->start(gspca_dev);
+ gspca_dev->streaming = 1;
+ atomic_set(&gspca_dev->nevent, 0);
+
+ /* submit the URBs */
+ for (n = 0; n < gspca_dev->nurbs; n++) {
+ ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
+ if (ret < 0) {
+ PDEBUG(D_ERR|D_STREAM,
+ "usb_submit_urb [%d] err %d", n, ret);
+ gspca_dev->streaming = 0;
+ destroy_urbs(gspca_dev);
+ if (ret == -ENOSPC)
+ break; /* try the previous alt */
+ goto out;
+ }
+ }
+ if (ret >= 0)
+ break;
+ }
+out:
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
+}
+
+static int gspca_set_alt0(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
+ if (ret < 0)
+ PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret);
+ return ret;
+}
+
+/* Note both the queue and the usb lock should be hold when calling this */
+static void gspca_stream_off(struct gspca_dev *gspca_dev)
+{
+ gspca_dev->streaming = 0;
+ atomic_set(&gspca_dev->nevent, 0);
+ if (gspca_dev->present) {
+ gspca_dev->sd_desc->stopN(gspca_dev);
+ destroy_urbs(gspca_dev);
+ gspca_set_alt0(gspca_dev);
+ gspca_dev->sd_desc->stop0(gspca_dev);
+ PDEBUG(D_STREAM, "stream off OK");
+ }
+}
+
+static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
+{
+ int i;
+
+ i = gspca_dev->cam.nmodes - 1; /* take the highest mode */
+ gspca_dev->curr_mode = i;
+ gspca_dev->width = gspca_dev->cam.cam_mode[i].width;
+ gspca_dev->height = gspca_dev->cam.cam_mode[i].height;
+ gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat;
+}
+
+static int wxh_to_mode(struct gspca_dev *gspca_dev,
+ int width, int height)
+{
+ int i;
+
+ for (i = gspca_dev->cam.nmodes; --i > 0; ) {
+ if (width >= gspca_dev->cam.cam_mode[i].width
+ && height >= gspca_dev->cam.cam_mode[i].height)
+ break;
+ }
+ return i;
+}
+
+/*
+ * search a mode with the right pixel format
+ */
+static int gspca_get_mode(struct gspca_dev *gspca_dev,
+ int mode,
+ int pixfmt)
+{
+ int modeU, modeD;
+
+ modeU = modeD = mode;
+ while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) {
+ if (--modeD >= 0) {
+ if (gspca_dev->cam.cam_mode[modeD].pixelformat
+ == pixfmt)
+ return modeD;
+ }
+ if (++modeU < gspca_dev->cam.nmodes) {
+ if (gspca_dev->cam.cam_mode[modeU].pixelformat
+ == pixfmt)
+ return modeU;
+ }
+ }
+ return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *fmtdesc)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int i, j, index;
+ __u32 fmt_tb[8];
+
+ /* give an index to each format */
+ index = 0;
+ j = 0;
+ for (i = gspca_dev->cam.nmodes; --i >= 0; ) {
+ fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat;
+ j = 0;
+ for (;;) {
+ if (fmt_tb[j] == fmt_tb[index])
+ break;
+ j++;
+ }
+ if (j == index) {
+ if (fmtdesc->index == index)
+ break; /* new format */
+ index++;
+ if (index >= sizeof fmt_tb / sizeof fmt_tb[0])
+ return -EINVAL;
+ }
+ }
+ if (i < 0)
+ return -EINVAL; /* no more format */
+
+ fmtdesc->pixelformat = fmt_tb[index];
+ if (gspca_is_compressed(fmt_tb[index]))
+ fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
+ fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
+ fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
+ fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
+ fmtdesc->description[3] = fmtdesc->pixelformat >> 24;
+ fmtdesc->description[4] = '\0';
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *fmt)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int mode;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ mode = gspca_dev->curr_mode;
+ memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode],
+ sizeof fmt->fmt.pix);
+ return 0;
+}
+
+static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
+ struct v4l2_format *fmt)
+{
+ int w, h, mode, mode2;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ w = fmt->fmt.pix.width;
+ h = fmt->fmt.pix.height;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (gspca_debug & D_CONF)
+ PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h);
+#endif
+ /* search the closest mode for width and height */
+ mode = wxh_to_mode(gspca_dev, w, h);
+
+ /* OK if right palette */
+ if (gspca_dev->cam.cam_mode[mode].pixelformat
+ != fmt->fmt.pix.pixelformat) {
+
+ /* else, search the closest mode with the same pixel format */
+ mode2 = gspca_get_mode(gspca_dev, mode,
+ fmt->fmt.pix.pixelformat);
+ if (mode2 >= 0)
+ mode = mode2;
+/* else
+ ; * no chance, return this mode */
+ }
+ memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode],
+ sizeof fmt->fmt.pix);
+ return mode; /* used when s_fmt */
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file,
+ void *priv,
+ struct v4l2_format *fmt)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int ret;
+
+ ret = try_fmt_vid_cap(gspca_dev, fmt);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *fmt)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int ret;
+
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+
+ ret = try_fmt_vid_cap(gspca_dev, fmt);
+ if (ret < 0)
+ goto out;
+
+ if (gspca_dev->nframes != 0
+ && fmt->fmt.pix.sizeimage > gspca_dev->frsz) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (ret == gspca_dev->curr_mode) {
+ ret = 0;
+ goto out; /* same mode */
+ }
+
+ if (gspca_dev->streaming) {
+ ret = -EBUSY;
+ goto out;
+ }
+ gspca_dev->width = fmt->fmt.pix.width;
+ gspca_dev->height = fmt->fmt.pix.height;
+ gspca_dev->pixfmt = fmt->fmt.pix.pixelformat;
+ gspca_dev->curr_mode = ret;
+
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ return ret;
+}
+
+static int dev_open(struct inode *inode, struct file *file)
+{
+ struct gspca_dev *gspca_dev;
+ int ret;
+
+ PDEBUG(D_STREAM, "%s open", current->comm);
+ gspca_dev = (struct gspca_dev *) video_devdata(file);
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* if not done yet, initialize the sensor */
+ if (gspca_dev->users == 0) {
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+ ret = gspca_dev->sd_desc->open(gspca_dev);
+ mutex_unlock(&gspca_dev->usb_lock);
+ if (ret != 0) {
+ PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
+ goto out;
+ }
+ } else if (gspca_dev->users > 4) { /* (arbitrary value) */
+ ret = -EBUSY;
+ goto out;
+ }
+ gspca_dev->users++;
+ file->private_data = gspca_dev;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ /* activate the v4l2 debug */
+ if (gspca_debug & D_V4L2)
+ gspca_dev->vdev.debug |= 3;
+ else
+ gspca_dev->vdev.debug &= ~3;
+#endif
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ if (ret != 0)
+ PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret);
+ else
+ PDEBUG(D_STREAM, "open done");
+ return ret;
+}
+
+static int dev_close(struct inode *inode, struct file *file)
+{
+ struct gspca_dev *gspca_dev = file->private_data;
+
+ PDEBUG(D_STREAM, "%s close", current->comm);
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+ gspca_dev->users--;
+
+ /* if the file did the capture, free the streaming resources */
+ if (gspca_dev->capt_file == file) {
+ mutex_lock(&gspca_dev->usb_lock);
+ if (gspca_dev->streaming)
+ gspca_stream_off(gspca_dev);
+ gspca_dev->sd_desc->close(gspca_dev);
+ mutex_unlock(&gspca_dev->usb_lock);
+ frame_free(gspca_dev);
+ gspca_dev->capt_file = NULL;
+ gspca_dev->memory = GSPCA_MEMORY_NO;
+ }
+ file->private_data = NULL;
+ mutex_unlock(&gspca_dev->queue_lock);
+ PDEBUG(D_STREAM, "close done");
+ return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct gspca_dev *gspca_dev = priv;
+
+ memset(cap, 0, sizeof *cap);
+ strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
+ strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card);
+ strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
+ sizeof cap->bus_info);
+ cap->version = DRIVER_VERSION_NUMBER;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
+ | V4L2_CAP_STREAMING
+ | V4L2_CAP_READWRITE;
+ return 0;
+}
+
+/* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *q_ctrl)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int i;
+ u32 id;
+
+ id = q_ctrl->id;
+ if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
+ id &= V4L2_CTRL_ID_MASK;
+ id++;
+ for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
+ if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) {
+ memcpy(q_ctrl,
+ &gspca_dev->sd_desc->ctrls[i].qctrl,
+ sizeof *q_ctrl);
+ return 0;
+ }
+ }
+ return -EINVAL;
+ }
+ for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
+ if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) {
+ memcpy(q_ctrl,
+ &gspca_dev->sd_desc->ctrls[i].qctrl,
+ sizeof *q_ctrl);
+ return 0;
+ }
+ }
+ if (id >= V4L2_CID_BASE
+ && id <= V4L2_CID_LASTP1) {
+ q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct gspca_dev *gspca_dev = priv;
+ const struct ctrl *ctrls;
+ int i, ret;
+
+ for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
+ i < gspca_dev->sd_desc->nctrls;
+ i++, ctrls++) {
+ if (ctrl->id != ctrls->qctrl.id)
+ continue;
+ if (ctrl->value < ctrls->qctrl.minimum
+ && ctrl->value > ctrls->qctrl.maximum)
+ return -ERANGE;
+ PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ ret = ctrls->set(gspca_dev, ctrl->value);
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct gspca_dev *gspca_dev = priv;
+
+ const struct ctrl *ctrls;
+ int i, ret;
+
+ for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
+ i < gspca_dev->sd_desc->nctrls;
+ i++, ctrls++) {
+ if (ctrl->id != ctrls->qctrl.id)
+ continue;
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ ret = ctrls->get(gspca_dev, &ctrl->value);
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_querymenu(struct file *file, void *priv,
+ struct v4l2_querymenu *qmenu)
+{
+ struct gspca_dev *gspca_dev = priv;
+
+ if (!gspca_dev->sd_desc->querymenu)
+ return -EINVAL;
+ return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu);
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ struct gspca_dev *gspca_dev = priv;
+
+ if (input->index != 0)
+ return -EINVAL;
+ memset(input, 0, sizeof *input);
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+ strncpy(input->name, gspca_dev->sd_desc->name,
+ sizeof input->name);
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i > 0)
+ return -EINVAL;
+ return (0);
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int i, ret = 0;
+
+ if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ switch (rb->memory) {
+ case GSPCA_MEMORY_READ: /* (internal call) */
+ case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_USERPTR:
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+
+ if (gspca_dev->memory != GSPCA_MEMORY_NO
+ && gspca_dev->memory != rb->memory) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ /* only one file may do the capture */
+ if (gspca_dev->capt_file != NULL
+ && gspca_dev->capt_file != file) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ /* if allocated, the buffers must not be mapped */
+ for (i = 0; i < gspca_dev->nframes; i++) {
+ if (gspca_dev->frame[i].vma_use_count) {
+ ret = -EBUSY;
+ goto out;
+ }
+ }
+
+ /* stop streaming */
+ if (gspca_dev->streaming) {
+ mutex_lock(&gspca_dev->usb_lock);
+ gspca_stream_off(gspca_dev);
+ mutex_unlock(&gspca_dev->usb_lock);
+ }
+
+ /* free the previous allocated buffers, if any */
+ if (gspca_dev->nframes != 0) {
+ frame_free(gspca_dev);
+ gspca_dev->capt_file = NULL;
+ }
+ if (rb->count == 0) /* unrequest */
+ goto out;
+ gspca_dev->memory = rb->memory;
+ ret = frame_alloc(gspca_dev, rb->count);
+ if (ret == 0) {
+ rb->count = gspca_dev->nframes;
+ gspca_dev->capt_file = file;
+ }
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count);
+ return ret;
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *v4l2_buf)
+{
+ struct gspca_dev *gspca_dev = priv;
+ struct gspca_frame *frame;
+
+ if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || v4l2_buf->index < 0
+ || v4l2_buf->index >= gspca_dev->nframes)
+ return -EINVAL;
+
+ frame = &gspca_dev->frame[v4l2_buf->index];
+ memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
+ return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type buf_type)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int ret;
+
+ if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+ if (gspca_dev->nframes == 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (!gspca_dev->streaming) {
+ ret = gspca_init_transfer(gspca_dev);
+ if (ret < 0)
+ goto out;
+ }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (gspca_debug & D_STREAM) {
+ PDEBUG_MODE("stream on OK",
+ gspca_dev->pixfmt,
+ gspca_dev->width,
+ gspca_dev->height);
+ }
+#endif
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ return ret;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type buf_type)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int i, ret;
+
+ if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (!gspca_dev->streaming)
+ return 0;
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+
+ /* stop streaming */
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
+ ret = -ERESTARTSYS;
+ goto out;
+ }
+ gspca_stream_off(gspca_dev);
+ mutex_unlock(&gspca_dev->usb_lock);
+
+ /* empty the application queues */
+ for (i = 0; i < gspca_dev->nframes; i++)
+ gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS;
+ gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ gspca_dev->sequence = 0;
+ atomic_set(&gspca_dev->nevent, 0);
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ return ret;
+}
+
+static int vidioc_g_jpegcomp(struct file *file, void *priv,
+ struct v4l2_jpegcompression *jpegcomp)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int ret;
+
+ if (!gspca_dev->sd_desc->get_jcomp)
+ return -EINVAL;
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
+}
+
+static int vidioc_s_jpegcomp(struct file *file, void *priv,
+ struct v4l2_jpegcompression *jpegcomp)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int ret;
+
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->sd_desc->set_jcomp)
+ return -EINVAL;
+ ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
+}
+
+static int vidioc_g_parm(struct file *filp, void *priv,
+ struct v4l2_streamparm *parm)
+{
+ struct gspca_dev *gspca_dev = priv;
+
+ memset(parm, 0, sizeof *parm);
+ parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ parm->parm.capture.readbuffers = gspca_dev->nbufread;
+ return 0;
+}
+
+static int vidioc_s_parm(struct file *filp, void *priv,
+ struct v4l2_streamparm *parm)
+{
+ struct gspca_dev *gspca_dev = priv;
+ int n;
+
+ n = parm->parm.capture.readbuffers;
+ if (n == 0 || n > GSPCA_MAX_FRAMES)
+ parm->parm.capture.readbuffers = gspca_dev->nbufread;
+ else
+ gspca_dev->nbufread = n;
+ return 0;
+}
+
+static int vidioc_s_std(struct file *filp, void *priv,
+ v4l2_std_id *parm)
+{
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *priv,
+ struct video_mbuf *mbuf)
+{
+ struct gspca_dev *gspca_dev = file->private_data;
+ int i;
+
+ PDEBUG(D_STREAM, "cgmbuf");
+ if (gspca_dev->nframes == 0) {
+ int ret;
+
+ {
+ struct v4l2_format fmt;
+
+ memset(&fmt, 0, sizeof fmt);
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ i = gspca_dev->cam.nmodes - 1; /* highest mode */
+ fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width;
+ fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height;
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
+ ret = vidioc_s_fmt_vid_cap(file, priv, &fmt);
+ if (ret != 0)
+ return ret;
+ }
+ {
+ struct v4l2_requestbuffers rb;
+
+ memset(&rb, 0, sizeof rb);
+ rb.count = 4;
+ rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ rb.memory = V4L2_MEMORY_MMAP;
+ ret = vidioc_reqbufs(file, priv, &rb);
+ if (ret != 0)
+ return ret;
+ }
+ }
+ mbuf->frames = gspca_dev->nframes;
+ mbuf->size = gspca_dev->frsz * gspca_dev->nframes;
+ for (i = 0; i < mbuf->frames; i++)
+ mbuf->offsets[i] = gspca_dev->frame[i].v4l2_buf.m.offset;
+ return 0;
+}
+#endif
+
+static int dev_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct gspca_dev *gspca_dev = file->private_data;
+ struct gspca_frame *frame;
+ struct page *page;
+ unsigned long addr, start, size;
+ int i, ret;
+
+ start = vma->vm_start;
+ size = vma->vm_end - vma->vm_start;
+ PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);
+
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+ if (gspca_dev->capt_file != file) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ frame = NULL;
+ for (i = 0; i < gspca_dev->nframes; ++i) {
+ if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) {
+ PDEBUG(D_STREAM, "mmap bad memory type");
+ break;
+ }
+ if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT)
+ == vma->vm_pgoff) {
+ frame = &gspca_dev->frame[i];
+ break;
+ }
+ }
+ if (frame == NULL) {
+ PDEBUG(D_STREAM, "mmap no frame buffer found");
+ ret = -EINVAL;
+ goto out;
+ }
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ /* v4l1 maps all the buffers */
+ if (i != 0
+ || size != frame->v4l2_buf.length * gspca_dev->nframes)
+#endif
+ if (size != frame->v4l2_buf.length) {
+ PDEBUG(D_STREAM, "mmap bad size");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * - VM_IO marks the area as being a mmaped region for I/O to a
+ * device. It also prevents the region from being core dumped.
+ */
+ vma->vm_flags |= VM_IO;
+
+ addr = (unsigned long) frame->data;
+ while (size > 0) {
+ page = vmalloc_to_page((void *) addr);
+ ret = vm_insert_page(vma, start, page);
+ if (ret < 0)
+ goto out;
+ start += PAGE_SIZE;
+ addr += PAGE_SIZE;
+ size -= PAGE_SIZE;
+ }
+
+ vma->vm_ops = &gspca_vm_ops;
+ vma->vm_private_data = frame;
+ gspca_vm_open(vma);
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ return ret;
+}
+
+/*
+ * wait for a video frame
+ *
+ * If a frame is ready, its index is returned.
+ */
+static int frame_wait(struct gspca_dev *gspca_dev,
+ int nonblock_ing)
+{
+ struct gspca_frame *frame;
+ int i, j, ret;
+
+ /* check if a frame is ready */
+ i = gspca_dev->fr_o;
+ j = gspca_dev->fr_queue[i];
+ frame = &gspca_dev->frame[j];
+ if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) {
+ atomic_dec(&gspca_dev->nevent);
+ goto ok;
+ }
+ if (nonblock_ing) /* no frame yet */
+ return -EAGAIN;
+
+ /* wait till a frame is ready */
+ for (;;) {
+ ret = wait_event_interruptible_timeout(gspca_dev->wq,
+ atomic_read(&gspca_dev->nevent) > 0,
+ msecs_to_jiffies(3000));
+ if (ret <= 0) {
+ if (ret < 0)
+ return ret; /* interrupt */
+ return -EIO; /* timeout */
+ }
+ atomic_dec(&gspca_dev->nevent);
+ if (!gspca_dev->streaming || !gspca_dev->present)
+ return -EIO;
+ i = gspca_dev->fr_o;
+ j = gspca_dev->fr_queue[i];
+ frame = &gspca_dev->frame[j];
+ if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
+ break;
+ }
+ok:
+ gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
+ PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
+ gspca_dev->fr_q,
+ gspca_dev->fr_i,
+ gspca_dev->fr_o);
+
+ if (gspca_dev->sd_desc->dq_callback) {
+ mutex_lock(&gspca_dev->usb_lock);
+ gspca_dev->sd_desc->dq_callback(gspca_dev);
+ mutex_unlock(&gspca_dev->usb_lock);
+ }
+ return j;
+}
+
+/*
+ * dequeue a video buffer
+ *
+ * If nonblock_ing is false, block until a buffer is available.
+ */
+static int vidioc_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *v4l2_buf)
+{
+ struct gspca_dev *gspca_dev = priv;
+ struct gspca_frame *frame;
+ int i, ret;
+
+ PDEBUG(D_FRAM, "dqbuf");
+ if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (v4l2_buf->memory != gspca_dev->memory)
+ return -EINVAL;
+
+ /* if not streaming, be sure the application will not loop forever */
+ if (!(file->f_flags & O_NONBLOCK)
+ && !gspca_dev->streaming && gspca_dev->users == 1)
+ return -EINVAL;
+
+ /* only the capturing file may dequeue */
+ if (gspca_dev->capt_file != file)
+ return -EINVAL;
+
+ /* only one dequeue / read at a time */
+ if (mutex_lock_interruptible(&gspca_dev->read_lock))
+ return -ERESTARTSYS;
+
+ ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK);
+ if (ret < 0)
+ goto out;
+ i = ret; /* frame index */
+ frame = &gspca_dev->frame[i];
+ if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
+ if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr,
+ frame->data,
+ frame->v4l2_buf.bytesused)) {
+ PDEBUG(D_ERR|D_STREAM,
+ "dqbuf cp to user failed");
+ ret = -EFAULT;
+ goto out;
+ }
+ }
+ frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
+ memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
+ PDEBUG(D_FRAM, "dqbuf %d", i);
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->read_lock);
+ return ret;
+}
+
+/*
+ * queue a video buffer
+ *
+ * Attempting to queue a buffer that has already been
+ * queued will return -EINVAL.
+ */
+static int vidioc_qbuf(struct file *file, void *priv,
+ struct v4l2_buffer *v4l2_buf)
+{
+ struct gspca_dev *gspca_dev = priv;
+ struct gspca_frame *frame;
+ int i, index, ret;
+
+ PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
+ if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock))
+ return -ERESTARTSYS;
+
+ index = v4l2_buf->index;
+ if ((unsigned) index >= gspca_dev->nframes) {
+ PDEBUG(D_FRAM,
+ "qbuf idx %d >= %d", index, gspca_dev->nframes);
+ ret = -EINVAL;
+ goto out;
+ }
+ if (v4l2_buf->memory != gspca_dev->memory) {
+ PDEBUG(D_FRAM, "qbuf bad memory type");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ frame = &gspca_dev->frame[index];
+ if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) {
+ PDEBUG(D_FRAM, "qbuf bad state");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
+/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */
+
+ if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {
+ frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
+ frame->v4l2_buf.length = v4l2_buf->length;
+ }
+
+ /* put the buffer in the 'queued' queue */
+ i = gspca_dev->fr_q;
+ gspca_dev->fr_queue[i] = index;
+ gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
+ PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
+ gspca_dev->fr_q,
+ gspca_dev->fr_i,
+ gspca_dev->fr_o);
+
+ v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
+ v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE;
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ return ret;
+}
+
+/*
+ * allocate the resources for read()
+ */
+static int read_alloc(struct gspca_dev *gspca_dev,
+ struct file *file)
+{
+ struct v4l2_buffer v4l2_buf;
+ int i, ret;
+
+ PDEBUG(D_STREAM, "read alloc");
+ if (gspca_dev->nframes == 0) {
+ struct v4l2_requestbuffers rb;
+
+ memset(&rb, 0, sizeof rb);
+ rb.count = gspca_dev->nbufread;
+ rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ rb.memory = GSPCA_MEMORY_READ;
+ ret = vidioc_reqbufs(file, gspca_dev, &rb);
+ if (ret != 0) {
+ PDEBUG(D_STREAM, "read reqbuf err %d", ret);
+ return ret;
+ }
+ memset(&v4l2_buf, 0, sizeof v4l2_buf);
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ v4l2_buf.memory = GSPCA_MEMORY_READ;
+ for (i = 0; i < gspca_dev->nbufread; i++) {
+ v4l2_buf.index = i;
+ ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
+ if (ret != 0) {
+ PDEBUG(D_STREAM, "read qbuf err: %d", ret);
+ return ret;
+ }
+ }
+ gspca_dev->memory = GSPCA_MEMORY_READ;
+ }
+
+ /* start streaming */
+ ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ if (ret != 0)
+ PDEBUG(D_STREAM, "read streamon err %d", ret);
+ return ret;
+}
+
+static unsigned int dev_poll(struct file *file, poll_table *wait)
+{
+ struct gspca_dev *gspca_dev = file->private_data;
+ int i, ret;
+
+ PDEBUG(D_FRAM, "poll");
+
+ poll_wait(file, &gspca_dev->wq, wait);
+ if (!gspca_dev->present)
+ return POLLERR;
+
+ /* if reqbufs is not done, the user would use read() */
+ if (gspca_dev->nframes == 0) {
+ if (gspca_dev->memory != GSPCA_MEMORY_NO)
+ return POLLERR; /* not the 1st time */
+ ret = read_alloc(gspca_dev, file);
+ if (ret != 0)
+ return POLLERR;
+ }
+
+ if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
+ return POLLERR;
+ if (!gspca_dev->present) {
+ ret = POLLERR;
+ goto out;
+ }
+
+ /* check the next incoming buffer */
+ i = gspca_dev->fr_o;
+ i = gspca_dev->fr_queue[i];
+ if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
+ ret = POLLIN | POLLRDNORM; /* something to read */
+ else
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->queue_lock);
+ return ret;
+}
+
+static ssize_t dev_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct gspca_dev *gspca_dev = file->private_data;
+ struct gspca_frame *frame;
+ struct v4l2_buffer v4l2_buf;
+ struct timeval timestamp;
+ int n, ret, ret2;
+
+ PDEBUG(D_FRAM, "read (%zd)", count);
+ if (!gspca_dev->present)
+ return -ENODEV;
+ switch (gspca_dev->memory) {
+ case GSPCA_MEMORY_NO: /* first time */
+ ret = read_alloc(gspca_dev, file);
+ if (ret != 0)
+ return ret;
+ break;
+ case GSPCA_MEMORY_READ:
+ if (gspca_dev->capt_file == file)
+ break;
+ /* fall thru */
+ default:
+ return -EINVAL;
+ }
+
+ /* get a frame */
+ jiffies_to_timeval(get_jiffies_64(), &timestamp);
+ timestamp.tv_sec--;
+ n = 2;
+ for (;;) {
+ memset(&v4l2_buf, 0, sizeof v4l2_buf);
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ v4l2_buf.memory = GSPCA_MEMORY_READ;
+ ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
+ if (ret != 0) {
+ PDEBUG(D_STREAM, "read dqbuf err %d", ret);
+ return ret;
+ }
+
+ /* if the process slept for more than 1 second,
+ * get anewer frame */
+ frame = &gspca_dev->frame[v4l2_buf.index];
+ if (--n < 0)
+ break; /* avoid infinite loop */
+ if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)
+ break;
+ ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
+ if (ret != 0) {
+ PDEBUG(D_STREAM, "read qbuf err %d", ret);
+ return ret;
+ }
+ }
+
+ /* copy the frame */
+ if (count > frame->v4l2_buf.bytesused)
+ count = frame->v4l2_buf.bytesused;
+ ret = copy_to_user(data, frame->data, count);
+ if (ret != 0) {
+ PDEBUG(D_ERR|D_STREAM,
+ "read cp to user lack %d / %zd", ret, count);
+ ret = -EFAULT;
+ goto out;
+ }
+ ret = count;
+out:
+ /* in each case, requeue the buffer */
+ ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
+ if (ret2 != 0)
+ return ret2;
+ return ret;
+}
+
+static void dev_release(struct video_device *vfd)
+{
+ /* nothing */
+}
+
+static struct file_operations dev_fops = {
+ .owner = THIS_MODULE,
+ .open = dev_open,
+ .release = dev_close,
+ .read = dev_read,
+ .mmap = dev_mmap,
+ .ioctl = video_ioctl2,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = v4l_compat_ioctl32,
+#endif
+ .llseek = no_llseek,
+ .poll = dev_poll,
+};
+
+static struct video_device gspca_template = {
+ .name = "gspca main driver",
+ .type = VID_TYPE_CAPTURE,
+ .fops = &dev_fops,
+ .release = dev_release, /* mandatory */
+ .minor = -1,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_querymenu = vidioc_querymenu,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
+ .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
+ .vidioc_g_parm = vidioc_g_parm,
+ .vidioc_s_parm = vidioc_s_parm,
+ .vidioc_s_std = vidioc_s_std,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
+
+/*
+ * probe and create a new gspca device
+ *
+ * This function must be called by the sub-driver when it is
+ * called for probing a new device.
+ */
+int gspca_dev_probe(struct usb_interface *intf,
+ const struct usb_device_id *id,
+ const struct sd_desc *sd_desc,
+ int dev_size,
+ struct module *module)
+{
+ struct usb_interface_descriptor *interface;
+ struct gspca_dev *gspca_dev;
+ struct usb_device *dev = interface_to_usbdev(intf);
+ int ret;
+
+ PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);
+
+ /* we don't handle multi-config cameras */
+ if (dev->descriptor.bNumConfigurations != 1)
+ return -ENODEV;
+ interface = &intf->cur_altsetting->desc;
+ if (interface->bInterfaceNumber > 0)
+ return -ENODEV;
+
+ /* create the device */
+ if (dev_size < sizeof *gspca_dev)
+ dev_size = sizeof *gspca_dev;
+ gspca_dev = kzalloc(dev_size, GFP_KERNEL);
+ if (gspca_dev == NULL) {
+ err("couldn't kzalloc gspca struct");
+ return -EIO;
+ }
+ gspca_dev->dev = dev;
+ gspca_dev->iface = interface->bInterfaceNumber;
+ gspca_dev->nbalt = intf->num_altsetting;
+ gspca_dev->sd_desc = sd_desc;
+/* gspca_dev->users = 0; (done by kzalloc) */
+ gspca_dev->nbufread = 2;
+
+ /* configure the subdriver */
+ ret = gspca_dev->sd_desc->config(gspca_dev, id);
+ if (ret < 0)
+ goto out;
+ ret = gspca_set_alt0(gspca_dev);
+ if (ret < 0)
+ goto out;
+ gspca_set_default_mode(gspca_dev);
+
+ mutex_init(&gspca_dev->usb_lock);
+ mutex_init(&gspca_dev->read_lock);
+ mutex_init(&gspca_dev->queue_lock);
+ init_waitqueue_head(&gspca_dev->wq);
+
+ /* init video stuff */
+ memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
+ gspca_dev->vdev.dev = &dev->dev;
+ memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
+ gspca_dev->vdev.fops = &gspca_dev->fops;
+ gspca_dev->fops.owner = module; /* module protection */
+ ret = video_register_device(&gspca_dev->vdev,
+ VFL_TYPE_GRABBER,
+ video_nr);
+ if (ret < 0) {
+ err("video_register_device err %d", ret);
+ goto out;
+ }
+
+ gspca_dev->present = 1;
+ usb_set_intfdata(intf, gspca_dev);
+ PDEBUG(D_PROBE, "probe ok");
+ return 0;
+out:
+ kfree(gspca_dev);
+ return ret;
+}
+EXPORT_SYMBOL(gspca_dev_probe);
+
+/*
+ * USB disconnection
+ *
+ * This function must be called by the sub-driver
+ * when the device disconnects, after the specific resources are freed.
+ */
+void gspca_disconnect(struct usb_interface *intf)
+{
+ struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
+
+ if (!gspca_dev)
+ return;
+ gspca_dev->present = 0;
+ mutex_lock(&gspca_dev->queue_lock);
+ mutex_lock(&gspca_dev->usb_lock);
+ gspca_dev->streaming = 0;
+ destroy_urbs(gspca_dev);
+ mutex_unlock(&gspca_dev->usb_lock);
+ mutex_unlock(&gspca_dev->queue_lock);
+ while (gspca_dev->users != 0) { /* wait until fully closed */
+ atomic_inc(&gspca_dev->nevent);
+ wake_up_interruptible(&gspca_dev->wq); /* wake processes */
+ schedule();
+ }
+/* We don't want people trying to open up the device */
+ video_unregister_device(&gspca_dev->vdev);
+/* Free the memory */
+ kfree(gspca_dev);
+ PDEBUG(D_PROBE, "disconnect complete");
+}
+EXPORT_SYMBOL(gspca_disconnect);
+
+/* -- cam driver utility functions -- */
+
+/* auto gain and exposure algorithm based on the knee algorithm described here:
+ http://ytse.tricolour.net/docs/LowLightOptimization.html
+
+ Returns 0 if no changes were made, 1 if the gain and or exposure settings
+ where changed. */
+int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
+ int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee)
+{
+ int i, steps, gain, orig_gain, exposure, orig_exposure, autogain;
+ const struct ctrl *gain_ctrl = NULL;
+ const struct ctrl *exposure_ctrl = NULL;
+ const struct ctrl *autogain_ctrl = NULL;
+ int retval = 0;
+
+ for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
+ if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
+ gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
+ if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
+ exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
+ if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_AUTOGAIN)
+ autogain_ctrl = &gspca_dev->sd_desc->ctrls[i];
+ }
+ if (!gain_ctrl || !exposure_ctrl || !autogain_ctrl) {
+ PDEBUG(D_ERR, "Error: gspca_auto_gain_n_exposure called "
+ "on cam without (auto)gain/exposure");
+ return 0;
+ }
+
+ if (gain_ctrl->get(gspca_dev, &gain) ||
+ exposure_ctrl->get(gspca_dev, &exposure) ||
+ autogain_ctrl->get(gspca_dev, &autogain) || !autogain)
+ return 0;
+
+ orig_gain = gain;
+ orig_exposure = exposure;
+
+ /* If we are of a multiple of deadzone, do multiple steps to reach the
+ desired lumination fast (with the risc of a slight overshoot) */
+ steps = abs(desired_avg_lum - avg_lum) / deadzone;
+
+ PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n",
+ avg_lum, desired_avg_lum, steps);
+
+ for (i = 0; i < steps; i++) {
+ if (avg_lum > desired_avg_lum) {
+ if (gain > gain_knee)
+ gain--;
+ else if (exposure > exposure_knee)
+ exposure--;
+ else if (gain > gain_ctrl->qctrl.default_value)
+ gain--;
+ else if (exposure > exposure_ctrl->qctrl.minimum)
+ exposure--;
+ else if (gain > gain_ctrl->qctrl.minimum)
+ gain--;
+ else
+ break;
+ } else {
+ if (gain < gain_ctrl->qctrl.default_value)
+ gain++;
+ else if (exposure < exposure_knee)
+ exposure++;
+ else if (gain < gain_knee)
+ gain++;
+ else if (exposure < exposure_ctrl->qctrl.maximum)
+ exposure++;
+ else if (gain < gain_ctrl->qctrl.maximum)
+ gain++;
+ else
+ break;
+ }
+ }
+
+ if (gain != orig_gain) {
+ gain_ctrl->set(gspca_dev, gain);
+ retval = 1;
+ }
+ if (exposure != orig_exposure) {
+ exposure_ctrl->set(gspca_dev, exposure);
+ retval = 1;
+ }
+
+ return retval;
+}
+EXPORT_SYMBOL(gspca_auto_gain_n_exposure);
+
+/* -- module insert / remove -- */
+static int __init gspca_init(void)
+{
+ info("main v%s registered", version);
+ return 0;
+}
+static void __exit gspca_exit(void)
+{
+ info("main deregistered");
+}
+
+module_init(gspca_init);
+module_exit(gspca_exit);
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+module_param_named(debug, gspca_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+ "Debug (bit) 0x01:error 0x02:probe 0x04:config"
+ " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout"
+ " 0x0100: v4l2");
+#endif
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
new file mode 100644
index 00000000000..3fd2c4eee20
--- /dev/null
+++ b/drivers/media/video/gspca/gspca.h
@@ -0,0 +1,176 @@
+#ifndef GSPCAV2_H
+#define GSPCAV2_H
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+/* GSPCA our debug messages */
+extern int gspca_debug;
+#define PDEBUG(level, fmt, args...) \
+ do {\
+ if (gspca_debug & (level)) \
+ printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
+ } while (0)
+#define D_ERR 0x01
+#define D_PROBE 0x02
+#define D_CONF 0x04
+#define D_STREAM 0x08
+#define D_FRAM 0x10
+#define D_PACK 0x20
+#define D_USBI 0x40
+#define D_USBO 0x80
+#define D_V4L2 0x0100
+#else
+#define PDEBUG(level, fmt, args...)
+#endif
+#undef err
+#define err(fmt, args...) \
+ do {\
+ printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
+ } while (0)
+#undef info
+#define info(fmt, args...) \
+ do {\
+ printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
+ } while (0)
+#undef warn
+#define warn(fmt, args...) \
+ do {\
+ printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
+ } while (0)
+
+#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
+/* ISOC transfers */
+#define MAX_NURBS 16 /* max number of URBs */
+#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */
+#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */
+
+/* device information - set at probe time */
+struct cam {
+ char *dev_name;
+ struct v4l2_pix_format *cam_mode; /* size nmodes */
+ char nmodes;
+ __u8 epaddr;
+};
+
+struct gspca_dev;
+struct gspca_frame;
+
+/* subdriver operations */
+typedef int (*cam_op) (struct gspca_dev *);
+typedef void (*cam_v_op) (struct gspca_dev *);
+typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *);
+typedef int (*cam_jpg_op) (struct gspca_dev *,
+ struct v4l2_jpegcompression *);
+typedef int (*cam_qmnu_op) (struct gspca_dev *,
+ struct v4l2_querymenu *);
+typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame,
+ __u8 *data,
+ int len);
+
+struct ctrl {
+ struct v4l2_queryctrl qctrl;
+ int (*set)(struct gspca_dev *, __s32);
+ int (*get)(struct gspca_dev *, __s32 *);
+};
+
+/* subdriver description */
+struct sd_desc {
+/* information */
+ const char *name; /* sub-driver name */
+/* controls */
+ const struct ctrl *ctrls;
+ int nctrls;
+/* operations */
+ cam_cf_op config; /* called on probe */
+ cam_op open; /* called on open */
+ cam_v_op start; /* called on stream on */
+ cam_v_op stopN; /* called on stream off - main alt */
+ cam_v_op stop0; /* called on stream off - alt 0 */
+ cam_v_op close; /* called on close */
+ cam_pkt_op pkt_scan;
+/* optional operations */
+ cam_v_op dq_callback; /* called when a frame has been dequeued */
+ cam_jpg_op get_jcomp;
+ cam_jpg_op set_jcomp;
+ cam_qmnu_op querymenu;
+};
+
+/* packet types when moving from iso buf to frame buf */
+#define DISCARD_PACKET 0
+#define FIRST_PACKET 1
+#define INTER_PACKET 2
+#define LAST_PACKET 3
+
+struct gspca_frame {
+ __u8 *data; /* frame buffer */
+ __u8 *data_end; /* end of frame while filling */
+ int vma_use_count;
+ struct v4l2_buffer v4l2_buf;
+};
+
+struct gspca_dev {
+ struct video_device vdev; /* !! must be the first item */
+ struct file_operations fops;
+ struct usb_device *dev;
+ struct file *capt_file; /* file doing video capture */
+
+ struct cam cam; /* device information */
+ const struct sd_desc *sd_desc; /* subdriver description */
+
+ __u8 usb_buf[8]; /* buffer for USB exchanges */
+ struct urb *urb[MAX_NURBS];
+
+ __u8 *frbuf; /* buffer for nframes */
+ struct gspca_frame frame[GSPCA_MAX_FRAMES];
+ __u32 frsz; /* frame size */
+ char nframes; /* number of frames */
+ char fr_i; /* frame being filled */
+ char fr_q; /* next frame to queue */
+ char fr_o; /* next frame to dequeue */
+ signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
+ char last_packet_type;
+
+ __u8 iface; /* USB interface number */
+ __u8 alt; /* USB alternate setting */
+ __u8 curr_mode; /* current camera mode */
+ __u32 pixfmt; /* current mode parameters */
+ __u16 width;
+ __u16 height;
+
+ atomic_t nevent; /* number of frames done */
+ wait_queue_head_t wq; /* wait queue */
+ struct mutex usb_lock; /* usb exchange protection */
+ struct mutex read_lock; /* read protection */
+ struct mutex queue_lock; /* ISOC queue protection */
+ __u32 sequence; /* frame sequence number */
+ char streaming;
+ char users; /* number of opens */
+ char present; /* device connected */
+ char nbufread; /* number of buffers for read() */
+ char nurbs; /* number of allocated URBs */
+ char memory; /* memory type (V4L2_MEMORY_xxx) */
+ __u8 nbalt; /* number of USB alternate settings */
+};
+
+int gspca_dev_probe(struct usb_interface *intf,
+ const struct usb_device_id *id,
+ const struct sd_desc *sd_desc,
+ int dev_size,
+ struct module *module);
+void gspca_disconnect(struct usb_interface *intf);
+struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
+ int packet_type,
+ struct gspca_frame *frame,
+ const __u8 *data,
+ int len);
+int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
+ int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
+#endif /* GSPCAV2_H */
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
new file mode 100644
index 00000000000..d823b47bd4e
--- /dev/null
+++ b/drivers/media/video/gspca/jpeg.h
@@ -0,0 +1,301 @@
+#ifndef JPEG_H
+#define JPEG_H 1
+/*
+ * Insert a JPEG header at start of frame
+ *
+ * This module is used by the gspca subdrivers.
+ * A special case is done for Conexant webcams.
+ *
+ * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr)
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* start of jpeg frame + quantization table */
+static const unsigned char quant[][0x88] = {
+/* index 0 - Q40*/
+ {
+ 0xff, 0xd8, /* jpeg */
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0, /* quantization table part 1 */
+ 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
+ 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
+ 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
+ 109,
+ 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
+ 126, 129, 124,
+1, /* quantization table part 2 */
+ 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124,
+ 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+ 124, 124, 124},
+/* index 1 - Q50 */
+ {
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
+ 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
+ 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
+ 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
+ 103, 99,
+1,
+ 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
+/* index 2 Q60 */
+ {
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
+ 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
+ 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
+ 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
+1,
+ 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
+/* index 3 - Q70 */
+ {
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
+ 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
+ 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
+ 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
+1,
+ 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+ 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
+/* index 4 - Q80 */
+ {
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
+ 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
+ 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
+ 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
+1,
+ 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
+/* index 5 - Q85 */
+ {
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
+ 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
+ 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
+ 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
+1,
+ 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
+/* index 6 - 86 */
+{
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
+ 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
+ 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
+ 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
+ 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
+ 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
+ 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
+ 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
+1,
+ 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
+ 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ },
+/* index 7 - 88 */
+{
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
+ 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
+ 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
+ 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
+ 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
+ 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
+ 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
+ 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
+1,
+ 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
+ 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+},
+/* index 8 - ?? */
+{
+ 0xff, 0xd8,
+ 0xff, 0xdb, 0x00, 0x84, /* DQT */
+0,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
+ 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
+ 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
+ 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
+ 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
+ 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
+1,
+ 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
+ 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
+}
+};
+
+/* huffman table + start of SOF0 */
+static unsigned char huffman[] = {
+ 0xff, 0xc4, 0x01, 0xa2,
+ 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+ 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03,
+ 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00,
+ 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04,
+ 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
+ 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81,
+ 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15,
+ 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82,
+ 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
+ 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
+ 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
+ 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76,
+ 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86,
+ 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
+ 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
+ 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
+ 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
+ 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+ 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
+ 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02,
+ 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
+ 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
+ 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06,
+ 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
+ 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1,
+ 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62,
+ 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
+ 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
+ 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
+ 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
+ 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
+ 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
+ 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2,
+ 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
+#ifdef CONEX_CAM
+/* the Conexant frames start with SOF0 */
+#else
+ 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
+ 0x08, /* data precision */
+#endif
+};
+
+#ifndef CONEX_CAM
+/* variable part:
+ * 0x01, 0xe0, height
+ * 0x02, 0x80, width
+ * 0x03, component number
+ * 0x01,
+ * 0x21, samples Y
+ */
+
+/* end of header */
+static unsigned char eoh[] = {
+ 0x00, /* quant Y */
+ 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
+ 0x03, 0x11, 0x01,
+
+ 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
+ 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
+};
+#endif
+
+/* -- output the JPEG header -- */
+static void jpeg_put_header(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame,
+ int qindex,
+ int samplesY)
+{
+#ifndef CONEX_CAM
+ unsigned char tmpbuf[8];
+#endif
+
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ (unsigned char *) quant[qindex], sizeof quant[0]);
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ (unsigned char *) huffman, sizeof huffman);
+#ifndef CONEX_CAM
+ tmpbuf[0] = gspca_dev->height >> 8;
+ tmpbuf[1] = gspca_dev->height & 0xff;
+ tmpbuf[2] = gspca_dev->width >> 8;
+ tmpbuf[3] = gspca_dev->width & 0xff;
+ tmpbuf[4] = 0x03; /* component number */
+ tmpbuf[5] = 0x01; /* first component */
+ tmpbuf[6] = samplesY;
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ tmpbuf, 7);
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ eoh, sizeof eoh);
+#endif
+}
+#endif
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
new file mode 100644
index 00000000000..88c2b02f380
--- /dev/null
+++ b/drivers/media/video/gspca/mars.c
@@ -0,0 +1,464 @@
+/*
+ * Mars-Semi MR97311A library
+ * Copyright (C) 2005 <bradlch@hotmail.com>
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "mars"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ char qindex;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 589,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+};
+
+/* MI Register table //elvis */
+enum {
+ REG_HW_MI_0,
+ REG_HW_MI_1,
+ REG_HW_MI_2,
+ REG_HW_MI_3,
+ REG_HW_MI_4,
+ REG_HW_MI_5,
+ REG_HW_MI_6,
+ REG_HW_MI_7,
+ REG_HW_MI_9 = 0x09,
+ REG_HW_MI_B = 0x0B,
+ REG_HW_MI_C,
+ REG_HW_MI_D,
+ REG_HW_MI_1E = 0x1E,
+ REG_HW_MI_20 = 0x20,
+ REG_HW_MI_2B = 0x2B,
+ REG_HW_MI_2C,
+ REG_HW_MI_2D,
+ REG_HW_MI_2E,
+ REG_HW_MI_35 = 0x35,
+ REG_HW_MI_5F = 0x5f,
+ REG_HW_MI_60,
+ REG_HW_MI_61,
+ REG_HW_MI_62,
+ REG_HW_MI_63,
+ REG_HW_MI_64,
+ REG_HW_MI_F1 = 0xf1,
+ ATTR_TOTAL_MI_REG = 0xf2
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int reg_w(struct gspca_dev *gspca_dev,
+ __u16 index, int len)
+{
+ int rc;
+
+ rc = usb_control_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ 0x12,
+ 0xc8, /* ?? */
+ 0, /* value */
+ index, gspca_dev->usb_buf, len, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
+ return rc;
+}
+
+static int reg_w_buf(struct gspca_dev *gspca_dev,
+ __u16 index, __u8 *buf, int len)
+{
+ int rc;
+
+ rc = usb_control_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ 0x12,
+ 0xc8, /* ?? */
+ 0, /* value */
+ index, buf, len, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
+ return rc;
+}
+
+static void bulk_w(struct gspca_dev *gspca_dev,
+ __u16 *pch,
+ __u16 Address)
+{
+ gspca_dev->usb_buf[0] = 0x1f;
+ gspca_dev->usb_buf[1] = 0; /* control byte */
+ gspca_dev->usb_buf[2] = Address;
+ gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
+ gspca_dev->usb_buf[4] = *pch; /* low byte */
+
+ reg_w(gspca_dev, Address, 5);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ sd->qindex = 1; /* set the quantization table */
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ int err_code;
+ __u8 *data;
+ __u16 *MI_buf;
+ int h_size, v_size;
+ int intpipe;
+
+ PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
+ if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) {
+ PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
+ return;
+ }
+
+ data = gspca_dev->usb_buf;
+ data[0] = 0x01; /* address */
+ data[1] = 0x01;
+
+ err_code = reg_w(gspca_dev, data[0], 2);
+ if (err_code < 0)
+ return;
+
+ /*
+ Initialize the MR97113 chip register
+ */
+ data = kmalloc(16, GFP_KERNEL);
+ data[0] = 0x00; /* address */
+ data[1] = 0x0c | 0x01; /* reg 0 */
+ data[2] = 0x01; /* reg 1 */
+ h_size = gspca_dev->width;
+ v_size = gspca_dev->height;
+ data[3] = h_size / 8; /* h_size , reg 2 */
+ data[4] = v_size / 8; /* v_size , reg 3 */
+ data[5] = 0x30; /* reg 4, MI, PAS5101 :
+ * 0x30 for 24mhz , 0x28 for 12mhz */
+ data[6] = 4; /* reg 5, H start */
+ data[7] = 0xc0; /* reg 6, gamma 1.5 */
+ data[8] = 3; /* reg 7, V start */
+/* if (h_size == 320 ) */
+/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
+/* else */
+ data[9] = 0x52; /* reg 8, 24MHz, no scale down */
+ data[10] = 0x5d; /* reg 9, I2C device address
+ * [for PAS5101 (0x40)] [for MI (0x5d)] */
+
+ err_code = reg_w_buf(gspca_dev, data[0], data, 11);
+ kfree(data);
+ if (err_code < 0)
+ return;
+
+ data = gspca_dev->usb_buf;
+ data[0] = 0x23; /* address */
+ data[1] = 0x09; /* reg 35, append frame header */
+
+ err_code = reg_w(gspca_dev, data[0], 2);
+ if (err_code < 0)
+ return;
+
+ data[0] = 0x3c; /* address */
+/* if (gspca_dev->width == 1280) */
+/* data[1] = 200; * reg 60, pc-cam frame size
+ * (unit: 4KB) 800KB */
+/* else */
+ data[1] = 50; /* 50 reg 60, pc-cam frame size
+ * (unit: 4KB) 200KB */
+ err_code = reg_w(gspca_dev, data[0], 2);
+ if (err_code < 0)
+ return;
+
+ if (0) { /* fixed dark-gain */
+ data[1] = 0; /* reg 94, Y Gain (1.75) */
+ data[2] = 0; /* reg 95, UV Gain (1.75) */
+ data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable
+ * auto dark-gain */
+ data[4] = 0; /* reg 97, set fixed dark level */
+ data[5] = 0; /* reg 98, don't care */
+ } else { /* auto dark-gain */
+ data[1] = 0; /* reg 94, Y Gain (auto) */
+ data[2] = 0; /* reg 95, UV Gain (1.75) */
+ data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable
+ * auto dark-gain */
+ switch (gspca_dev->width) {
+/* case 1280: */
+/* data[4] = 154;
+ * reg 97, %3 shadow point (unit: 256 pixel) */
+/* data[5] = 51;
+ * reg 98, %1 highlight point
+ * (uint: 256 pixel) */
+/* break; */
+ default:
+/* case 640: */
+ data[4] = 36; /* reg 97, %3 shadow point
+ * (unit: 256 pixel) */
+ data[5] = 12; /* reg 98, %1 highlight point
+ * (uint: 256 pixel) */
+ break;
+ case 320:
+ data[4] = 9; /* reg 97, %3 shadow point
+ * (unit: 256 pixel) */
+ data[5] = 3; /* reg 98, %1 highlight point
+ * (uint: 256 pixel) */
+ break;
+ }
+ }
+ /* auto dark-gain */
+ data[0] = 0x5e; /* address */
+
+ err_code = reg_w(gspca_dev, data[0], 6);
+ if (err_code < 0)
+ return;
+
+ data[0] = 0x67;
+ data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
+ err_code = reg_w(gspca_dev, data[0], 2);
+ if (err_code < 0)
+ return;
+
+ /*
+ * initialize the value of MI sensor...
+ */
+ MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
+ MI_buf[REG_HW_MI_1] = 0x000a;
+ MI_buf[REG_HW_MI_2] = 0x000c;
+ MI_buf[REG_HW_MI_3] = 0x0405;
+ MI_buf[REG_HW_MI_4] = 0x0507;
+ /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */
+ MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */
+ MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */
+ /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */
+ MI_buf[REG_HW_MI_7] = 0x0002;
+ /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */
+ /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */
+ MI_buf[REG_HW_MI_9] = 0x0374;
+ MI_buf[REG_HW_MI_B] = 0x0000;
+ MI_buf[REG_HW_MI_C] = 0x0000;
+ MI_buf[REG_HW_MI_D] = 0x0000;
+ MI_buf[REG_HW_MI_1E] = 0x8000;
+/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */
+ MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */
+ MI_buf[REG_HW_MI_2B] = 0x0008;
+/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */
+ MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */
+ MI_buf[REG_HW_MI_2D] = 0x0008;
+ MI_buf[REG_HW_MI_2E] = 0x0008;
+ MI_buf[REG_HW_MI_35] = 0x0051;
+ MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */
+ MI_buf[REG_HW_MI_60] = 0x0000;
+ MI_buf[REG_HW_MI_61] = 0x0000;
+ MI_buf[REG_HW_MI_62] = 0x0498;
+ MI_buf[REG_HW_MI_63] = 0x0000;
+ MI_buf[REG_HW_MI_64] = 0x0000;
+ MI_buf[REG_HW_MI_F1] = 0x0001;
+ /* changing while setting up the different value of dx/dy */
+
+ if (gspca_dev->width != 1280) {
+ MI_buf[0x01] = 0x010a;
+ MI_buf[0x02] = 0x014c;
+ MI_buf[0x03] = 0x01e5;
+ MI_buf[0x04] = 0x0287;
+ }
+ MI_buf[0x20] = 0x1104;
+
+ bulk_w(gspca_dev, MI_buf + 1, 1);
+ bulk_w(gspca_dev, MI_buf + 2, 2);
+ bulk_w(gspca_dev, MI_buf + 3, 3);
+ bulk_w(gspca_dev, MI_buf + 4, 4);
+ bulk_w(gspca_dev, MI_buf + 5, 5);
+ bulk_w(gspca_dev, MI_buf + 6, 6);
+ bulk_w(gspca_dev, MI_buf + 7, 7);
+ bulk_w(gspca_dev, MI_buf + 9, 9);
+ bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
+ bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
+ bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
+ bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
+ bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
+ bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
+ bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
+ bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
+ bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
+ bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
+ bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
+ bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
+ bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
+ bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
+ bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
+ bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
+ bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
+ kfree(MI_buf);
+
+ intpipe = usb_sndintpipe(gspca_dev->dev, 0);
+ err_code = usb_clear_halt(gspca_dev->dev, intpipe);
+
+ data[0] = 0x00;
+ data[1] = 0x4d; /* ISOC transfering enable... */
+ reg_w(gspca_dev, data[0], 2);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ int result;
+
+ gspca_dev->usb_buf[0] = 1;
+ gspca_dev->usb_buf[1] = 0;
+ result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
+ if (result < 0)
+ PDEBUG(D_ERR, "Camera Stop failed");
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int p;
+
+ if (len < 6) {
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ for (p = 0; p < len - 6; p++) {
+ if (data[0 + p] == 0xff
+ && data[1 + p] == 0xff
+ && data[2 + p] == 0x00
+ && data[3 + p] == 0xff
+ && data[4 + p] == 0x96) {
+ if (data[5 + p] == 0x64
+ || data[5 + p] == 0x65
+ || data[5 + p] == 0x66
+ || data[5 + p] == 0x67) {
+ PDEBUG(D_PACK, "sof offset: %d leng: %d",
+ p, len);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET,
+ frame, data, 0);
+
+ /* put the JPEG header */
+ jpeg_put_header(gspca_dev, frame,
+ sd->qindex, 0x21);
+ data += 16;
+ len -= 16;
+ break;
+ }
+ }
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
new file mode 100644
index 00000000000..08d99c3b78e
--- /dev/null
+++ b/drivers/media/video/gspca/ov519.c
@@ -0,0 +1,2186 @@
+/**
+ * OV519 driver
+ *
+ * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
+ *
+ * (This module is adapted from the ov51x-jpeg package)
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#define MODULE_NAME "ov519"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
+MODULE_DESCRIPTION("OV519 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* global parameters */
+static int frame_rate;
+
+/* Number of times to retry a failed I2C transaction. Increase this if you
+ * are getting "Failed to read sensor ID..." */
+static int i2c_detect_tries = 10;
+
+/* ov519 device descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ /* Determined by sensor type */
+ short maxwidth;
+ short maxheight;
+
+ unsigned char primary_i2c_slave; /* I2C write id of sensor */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+
+ char compress; /* Should the next frame be compressed? */
+ char compress_inited; /* Are compression params uploaded? */
+ char stopped; /* Streaming is temporarily paused */
+
+ char frame_rate; /* current Framerate (OV519 only) */
+ char clockdiv; /* clockdiv override for OV519 only */
+
+ char sensor; /* Type of image sensor chip (SEN_*) */
+#define SEN_UNKNOWN 0
+#define SEN_OV6620 1
+#define SEN_OV6630 2
+#define SEN_OV7610 3
+#define SEN_OV7620 4
+#define SEN_OV7630 5
+#define SEN_OV7640 6
+#define SEN_OV7670 7
+#define SEN_OV76BE 8
+#define SEN_OV8610 9
+
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 127,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 127,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_COLOR 2
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 127,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 589,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 8 + 589,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 8 + 589,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+/* OV519 Camera interface register numbers */
+#define OV519_CAM_H_SIZE 0x10
+#define OV519_CAM_V_SIZE 0x11
+#define OV519_CAM_X_OFFSETL 0x12
+#define OV519_CAM_X_OFFSETH 0x13
+#define OV519_CAM_Y_OFFSETL 0x14
+#define OV519_CAM_Y_OFFSETH 0x15
+#define OV519_CAM_DIVIDER 0x16
+#define OV519_CAM_DFR 0x20
+#define OV519_CAM_FORMAT 0x25
+
+/* OV519 System Controller register numbers */
+#define OV519_SYS_RESET1 0x51
+#define OV519_SYS_EN_CLK1 0x54
+
+#define OV519_GPIO_DATA_OUT0 0x71
+#define OV519_GPIO_IO_CTRL0 0x72
+
+#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
+
+/* I2C registers */
+#define R51x_I2C_W_SID 0x41
+#define R51x_I2C_SADDR_3 0x42
+#define R51x_I2C_SADDR_2 0x43
+#define R51x_I2C_R_SID 0x44
+#define R51x_I2C_DATA 0x45
+#define R518_I2C_CTL 0x47 /* OV518(+) only */
+
+/* I2C ADDRESSES */
+#define OV7xx0_SID 0x42
+#define OV8xx0_SID 0xa0
+#define OV6xx0_SID 0xc0
+
+/* OV7610 registers */
+#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
+#define OV7610_REG_SAT 0x03 /* saturation */
+#define OV8610_REG_HUE 0x04 /* 04 reserved */
+#define OV7610_REG_CNT 0x05 /* Y contrast */
+#define OV7610_REG_BRT 0x06 /* Y brightness */
+#define OV7610_REG_COM_C 0x14 /* misc common regs */
+#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */
+#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */
+#define OV7610_REG_COM_I 0x29 /* misc settings */
+
+/* OV7670 registers */
+#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
+#define OV7670_REG_BLUE 0x01 /* blue gain */
+#define OV7670_REG_RED 0x02 /* red gain */
+#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */
+#define OV7670_REG_COM1 0x04 /* Control 1 */
+#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */
+#define OV7670_REG_COM3 0x0c /* Control 3 */
+#define OV7670_REG_COM4 0x0d /* Control 4 */
+#define OV7670_REG_COM5 0x0e /* All "reserved" */
+#define OV7670_REG_COM6 0x0f /* Control 6 */
+#define OV7670_REG_AECH 0x10 /* More bits of AEC value */
+#define OV7670_REG_CLKRC 0x11 /* Clock control */
+#define OV7670_REG_COM7 0x12 /* Control 7 */
+#define OV7670_COM7_FMT_VGA 0x00
+#define OV7670_COM7_YUV 0x00 /* YUV */
+#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */
+#define OV7670_COM7_FMT_MASK 0x38
+#define OV7670_COM7_RESET 0x80 /* Register reset */
+#define OV7670_REG_COM8 0x13 /* Control 8 */
+#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */
+#define OV7670_COM8_AWB 0x02 /* White balance enable */
+#define OV7670_COM8_AGC 0x04 /* Auto gain enable */
+#define OV7670_COM8_BFILT 0x20 /* Band filter enable */
+#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */
+#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */
+#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */
+#define OV7670_REG_COM10 0x15 /* Control 10 */
+#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */
+#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */
+#define OV7670_REG_VSTART 0x19 /* Vert start high bits */
+#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */
+#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */
+#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */
+#define OV7670_REG_AEW 0x24 /* AGC upper limit */
+#define OV7670_REG_AEB 0x25 /* AGC lower limit */
+#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */
+#define OV7670_REG_HREF 0x32 /* HREF pieces */
+#define OV7670_REG_TSLB 0x3a /* lots of stuff */
+#define OV7670_REG_COM11 0x3b /* Control 11 */
+#define OV7670_COM11_EXP 0x02
+#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */
+#define OV7670_REG_COM12 0x3c /* Control 12 */
+#define OV7670_REG_COM13 0x3d /* Control 13 */
+#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */
+#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */
+#define OV7670_REG_COM14 0x3e /* Control 14 */
+#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */
+#define OV7670_REG_COM15 0x40 /* Control 15 */
+#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */
+#define OV7670_REG_COM16 0x41 /* Control 16 */
+#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */
+#define OV7670_REG_BRIGHT 0x55 /* Brightness */
+#define OV7670_REG_CONTRAS 0x56 /* Contrast control */
+#define OV7670_REG_GFIX 0x69 /* Fix gain control */
+#define OV7670_REG_RGB444 0x8c /* RGB 444 control */
+#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */
+#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */
+#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */
+#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */
+#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */
+#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */
+#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */
+#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */
+#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */
+
+struct ovsensor_window {
+ short x;
+ short y;
+ short width;
+ short height;
+/* int format; */
+ short quarter; /* Scale width and height down 2x */
+ short clockdiv; /* Clock divisor setting */
+};
+
+static unsigned char ov7670_abs_to_sm(unsigned char v)
+{
+ if (v > 127)
+ return v & 0x7f;
+ return (128 - v) | 0x80;
+}
+
+/* Write a OV519 register */
+static int reg_w(struct sd *sd, __u16 index, __u8 value)
+{
+ int ret;
+
+ sd->gspca_dev.usb_buf[0] = value;
+ ret = usb_control_msg(sd->gspca_dev.dev,
+ usb_sndctrlpipe(sd->gspca_dev.dev, 0),
+ 1, /* REQ_IO (ov518/519) */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, index,
+ sd->gspca_dev.usb_buf, 1, 500);
+ if (ret < 0)
+ PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value);
+ return ret;
+}
+
+/* Read from a OV519 register */
+/* returns: negative is error, pos or zero is data */
+static int reg_r(struct sd *sd, __u16 index)
+{
+ int ret;
+
+ ret = usb_control_msg(sd->gspca_dev.dev,
+ usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
+ 1, /* REQ_IO */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, index, sd->gspca_dev.usb_buf, 1, 500);
+
+ if (ret >= 0)
+ ret = sd->gspca_dev.usb_buf[0];
+ else
+ PDEBUG(D_ERR, "Read reg [0x%02x] failed", index);
+ return ret;
+}
+
+/* Read 8 values from a OV519 register */
+static int reg_r8(struct sd *sd,
+ __u16 index)
+{
+ int ret;
+
+ ret = usb_control_msg(sd->gspca_dev.dev,
+ usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
+ 1, /* REQ_IO */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, index, sd->gspca_dev.usb_buf, 8, 500);
+
+ if (ret >= 0)
+ ret = sd->gspca_dev.usb_buf[0];
+ else
+ PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index);
+ return ret;
+}
+
+/*
+ * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
+ * the same position as 1's in "mask" are cleared and set to "value". Bits
+ * that are in the same position as 0's in "mask" are preserved, regardless
+ * of their respective state in "value".
+ */
+static int reg_w_mask(struct sd *sd,
+ __u16 index,
+ __u8 value,
+ __u8 mask)
+{
+ int ret;
+ __u8 oldval;
+
+ if (mask != 0xff) {
+ value &= mask; /* Enforce mask on value */
+ ret = reg_r(sd, index);
+ if (ret < 0)
+ return ret;
+
+ oldval = ret & ~mask; /* Clear the masked bits */
+ value |= oldval; /* Set the desired bits */
+ }
+ return reg_w(sd, index, value);
+}
+
+/*
+ * The OV518 I2C I/O procedure is different, hence, this function.
+ * This is normally only called from i2c_w(). Note that this function
+ * always succeeds regardless of whether the sensor is present and working.
+ */
+static int i2c_w(struct sd *sd,
+ __u8 reg,
+ __u8 value)
+{
+ int rc;
+
+ PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+
+ /* Select camera register */
+ rc = reg_w(sd, R51x_I2C_SADDR_3, reg);
+ if (rc < 0)
+ return rc;
+
+ /* Write "value" to I2C data port of OV511 */
+ rc = reg_w(sd, R51x_I2C_DATA, value);
+ if (rc < 0)
+ return rc;
+
+ /* Initiate 3-byte write cycle */
+ rc = reg_w(sd, R518_I2C_CTL, 0x01);
+
+ /* wait for write complete */
+ msleep(4);
+ if (rc < 0)
+ return rc;
+ return reg_r8(sd, R518_I2C_CTL);
+}
+
+/*
+ * returns: negative is error, pos or zero is data
+ *
+ * The OV518 I2C I/O procedure is different, hence, this function.
+ * This is normally only called from i2c_r(). Note that this function
+ * always succeeds regardless of whether the sensor is present and working.
+ */
+static int i2c_r(struct sd *sd, __u8 reg)
+{
+ int rc, value;
+
+ /* Select camera register */
+ rc = reg_w(sd, R51x_I2C_SADDR_2, reg);
+ if (rc < 0)
+ return rc;
+
+ /* Initiate 2-byte write cycle */
+ rc = reg_w(sd, R518_I2C_CTL, 0x03);
+ if (rc < 0)
+ return rc;
+
+ /* Initiate 2-byte read cycle */
+ rc = reg_w(sd, R518_I2C_CTL, 0x05);
+ if (rc < 0)
+ return rc;
+ value = reg_r(sd, R51x_I2C_DATA);
+ PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+ return value;
+}
+
+/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
+ * the same position as 1's in "mask" are cleared and set to "value". Bits
+ * that are in the same position as 0's in "mask" are preserved, regardless
+ * of their respective state in "value".
+ */
+static int i2c_w_mask(struct sd *sd,
+ __u8 reg,
+ __u8 value,
+ __u8 mask)
+{
+ int rc;
+ __u8 oldval;
+
+ value &= mask; /* Enforce mask on value */
+ rc = i2c_r(sd, reg);
+ if (rc < 0)
+ return rc;
+ oldval = rc & ~mask; /* Clear the masked bits */
+ value |= oldval; /* Set the desired bits */
+ return i2c_w(sd, reg, value);
+}
+
+/* Temporarily stops OV511 from functioning. Must do this before changing
+ * registers while the camera is streaming */
+static inline int ov51x_stop(struct sd *sd)
+{
+ PDEBUG(D_STREAM, "stopping");
+ sd->stopped = 1;
+ return reg_w(sd, OV519_SYS_RESET1, 0x0f);
+}
+
+/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
+ * actually stopped (for performance). */
+static inline int ov51x_restart(struct sd *sd)
+{
+ PDEBUG(D_STREAM, "restarting");
+ if (!sd->stopped)
+ return 0;
+ sd->stopped = 0;
+
+ /* Reinitialize the stream */
+ return reg_w(sd, OV519_SYS_RESET1, 0x00);
+}
+
+/* This does an initial reset of an OmniVision sensor and ensures that I2C
+ * is synchronized. Returns <0 on failure.
+ */
+static int init_ov_sensor(struct sd *sd)
+{
+ int i, success;
+
+ /* Reset the sensor */
+ if (i2c_w(sd, 0x12, 0x80) < 0)
+ return -EIO;
+
+ /* Wait for it to initialize */
+ msleep(150);
+
+ for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
+ if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
+ i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
+ success = 1;
+ continue;
+ }
+
+ /* Reset the sensor */
+ if (i2c_w(sd, 0x12, 0x80) < 0)
+ return -EIO;
+ /* Wait for it to initialize */
+ msleep(150);
+ /* Dummy read to sync I2C */
+ if (i2c_r(sd, 0x00) < 0)
+ return -EIO;
+ }
+ if (!success)
+ return -EIO;
+ PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
+ return 0;
+}
+
+/* Switch on standard JPEG compression. Returns 0 for success. */
+static int ov519_init_compression(struct sd *sd)
+{
+ if (!sd->compress_inited) {
+ if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) {
+ PDEBUG(D_ERR, "Error switching to compressed mode");
+ return -EIO;
+ }
+ sd->compress_inited = 1;
+ }
+ return 0;
+}
+
+/* Set the read and write slave IDs. The "slave" argument is the write slave,
+ * and the read slave will be set to (slave + 1).
+ * This should not be called from outside the i2c I/O functions.
+ * Sets I2C read and write slave IDs. Returns <0 for error
+ */
+static int ov51x_set_slave_ids(struct sd *sd,
+ __u8 slave)
+{
+ int rc;
+
+ rc = reg_w(sd, R51x_I2C_W_SID, slave);
+ if (rc < 0)
+ return rc;
+ return reg_w(sd, R51x_I2C_R_SID, slave + 1);
+}
+
+struct ov_regvals {
+ __u8 reg;
+ __u8 val;
+};
+struct ov_i2c_regvals {
+ __u8 reg;
+ __u8 val;
+};
+
+static int write_regvals(struct sd *sd,
+ const struct ov_regvals *regvals,
+ int n)
+{
+ int rc;
+
+ while (--n >= 0) {
+ rc = reg_w(sd, regvals->reg, regvals->val);
+ if (rc < 0)
+ return rc;
+ regvals++;
+ }
+ return 0;
+}
+
+static int write_i2c_regvals(struct sd *sd,
+ const struct ov_i2c_regvals *regvals,
+ int n)
+{
+ int rc;
+
+ while (--n >= 0) {
+ rc = i2c_w(sd, regvals->reg, regvals->val);
+ if (rc < 0)
+ return rc;
+ regvals++;
+ }
+ return 0;
+}
+
+/****************************************************************************
+ *
+ * OV511 and sensor configuration
+ *
+ ***************************************************************************/
+
+/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
+ * the same register settings as the OV8610, since they are very similar.
+ */
+static int ov8xx0_configure(struct sd *sd)
+{
+ int rc;
+ static const struct ov_i2c_regvals norm_8610[] = {
+ { 0x12, 0x80 },
+ { 0x00, 0x00 },
+ { 0x01, 0x80 },
+ { 0x02, 0x80 },
+ { 0x03, 0xc0 },
+ { 0x04, 0x30 },
+ { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */
+ { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */
+ { 0x0a, 0x86 },
+ { 0x0b, 0xb0 },
+ { 0x0c, 0x20 },
+ { 0x0d, 0x20 },
+ { 0x11, 0x01 },
+ { 0x12, 0x25 },
+ { 0x13, 0x01 },
+ { 0x14, 0x04 },
+ { 0x15, 0x01 }, /* Lin and Win think different about UV order */
+ { 0x16, 0x03 },
+ { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */
+ { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */
+ { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */
+ { 0x1a, 0xf5 },
+ { 0x1b, 0x00 },
+ { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */
+ { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */
+ { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */
+ { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */
+ { 0x26, 0xa2 },
+ { 0x27, 0xea },
+ { 0x28, 0x00 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x80 },
+ { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */
+ { 0x2c, 0xac },
+ { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */
+ { 0x2e, 0x80 },
+ { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */
+ { 0x4c, 0x00 },
+ { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */
+ { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */
+ { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */
+ { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */
+ { 0x63, 0xff },
+ { 0x64, 0x53 }, /* new windrv 090403 says 0x57,
+ * maybe thats wrong */
+ { 0x65, 0x00 },
+ { 0x66, 0x55 },
+ { 0x67, 0xb0 },
+ { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */
+ { 0x69, 0x02 },
+ { 0x6a, 0x22 },
+ { 0x6b, 0x00 },
+ { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but
+ deleting bit7 colors the first images red */
+ { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */
+ { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */
+ { 0x6f, 0x01 },
+ { 0x70, 0x8b },
+ { 0x71, 0x00 },
+ { 0x72, 0x14 },
+ { 0x73, 0x54 },
+ { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */
+ { 0x75, 0x0e },
+ { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */
+ { 0x77, 0xff },
+ { 0x78, 0x80 },
+ { 0x79, 0x80 },
+ { 0x7a, 0x80 },
+ { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */
+ { 0x7c, 0x00 },
+ { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */
+ { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */
+ { 0x7f, 0xfb },
+ { 0x80, 0x28 },
+ { 0x81, 0x00 },
+ { 0x82, 0x23 },
+ { 0x83, 0x0b },
+ { 0x84, 0x00 },
+ { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */
+ { 0x86, 0xc9 },
+ { 0x87, 0x00 },
+ { 0x88, 0x00 },
+ { 0x89, 0x01 },
+ { 0x12, 0x20 },
+ { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */
+ };
+
+ PDEBUG(D_PROBE, "starting ov8xx0 configuration");
+
+ if (init_ov_sensor(sd) < 0)
+ PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID");
+ else
+ PDEBUG(D_PROBE, "OV86x0 initialized");
+
+ /* Detect sensor (sub)type */
+ rc = i2c_r(sd, OV7610_REG_COM_I);
+ if (rc < 0) {
+ PDEBUG(D_ERR, "Error detecting sensor type");
+ return -1;
+ }
+ if ((rc & 3) == 1) {
+ PDEBUG(D_PROBE, "Sensor is an OV8610");
+ sd->sensor = SEN_OV8610;
+ } else {
+ PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
+ return -1;
+ }
+ PDEBUG(D_PROBE, "Writing 8610 registers");
+ if (write_i2c_regvals(sd,
+ norm_8610,
+ sizeof norm_8610 / sizeof norm_8610[0]))
+ return -1;
+
+ /* Set sensor-specific vars */
+ sd->maxwidth = 640;
+ sd->maxheight = 480;
+ return 0;
+}
+
+/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
+ * the same register settings as the OV7610, since they are very similar.
+ */
+static int ov7xx0_configure(struct sd *sd)
+{
+ int rc, high, low;
+
+ /* Lawrence Glaister <lg@jfm.bc.ca> reports:
+ *
+ * Register 0x0f in the 7610 has the following effects:
+ *
+ * 0x85 (AEC method 1): Best overall, good contrast range
+ * 0x45 (AEC method 2): Very overexposed
+ * 0xa5 (spec sheet default): Ok, but the black level is
+ * shifted resulting in loss of contrast
+ * 0x05 (old driver setting): very overexposed, too much
+ * contrast
+ */
+ static const struct ov_i2c_regvals norm_7610[] = {
+ { 0x10, 0xff },
+ { 0x16, 0x06 },
+ { 0x28, 0x24 },
+ { 0x2b, 0xac },
+ { 0x12, 0x00 },
+ { 0x38, 0x81 },
+ { 0x28, 0x24 }, /* 0c */
+ { 0x0f, 0x85 }, /* lg's setting */
+ { 0x15, 0x01 },
+ { 0x20, 0x1c },
+ { 0x23, 0x2a },
+ { 0x24, 0x10 },
+ { 0x25, 0x8a },
+ { 0x26, 0xa2 },
+ { 0x27, 0xc2 },
+ { 0x2a, 0x04 },
+ { 0x2c, 0xfe },
+ { 0x2d, 0x93 },
+ { 0x30, 0x71 },
+ { 0x31, 0x60 },
+ { 0x32, 0x26 },
+ { 0x33, 0x20 },
+ { 0x34, 0x48 },
+ { 0x12, 0x24 },
+ { 0x11, 0x01 },
+ { 0x0c, 0x24 },
+ { 0x0d, 0x24 },
+ };
+
+ static const struct ov_i2c_regvals norm_7620[] = {
+ { 0x00, 0x00 }, /* gain */
+ { 0x01, 0x80 }, /* blue gain */
+ { 0x02, 0x80 }, /* red gain */
+ { 0x03, 0xc0 }, /* OV7670_REG_VREF */
+ { 0x06, 0x60 },
+ { 0x07, 0x00 },
+ { 0x0c, 0x24 },
+ { 0x0c, 0x24 },
+ { 0x0d, 0x24 },
+ { 0x11, 0x01 },
+ { 0x12, 0x24 },
+ { 0x13, 0x01 },
+ { 0x14, 0x84 },
+ { 0x15, 0x01 },
+ { 0x16, 0x03 },
+ { 0x17, 0x2f },
+ { 0x18, 0xcf },
+ { 0x19, 0x06 },
+ { 0x1a, 0xf5 },
+ { 0x1b, 0x00 },
+ { 0x20, 0x18 },
+ { 0x21, 0x80 },
+ { 0x22, 0x80 },
+ { 0x23, 0x00 },
+ { 0x26, 0xa2 },
+ { 0x27, 0xea },
+ { 0x28, 0x20 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x10 },
+ { 0x2b, 0x00 },
+ { 0x2c, 0x88 },
+ { 0x2d, 0x91 },
+ { 0x2e, 0x80 },
+ { 0x2f, 0x44 },
+ { 0x60, 0x27 },
+ { 0x61, 0x02 },
+ { 0x62, 0x5f },
+ { 0x63, 0xd5 },
+ { 0x64, 0x57 },
+ { 0x65, 0x83 },
+ { 0x66, 0x55 },
+ { 0x67, 0x92 },
+ { 0x68, 0xcf },
+ { 0x69, 0x76 },
+ { 0x6a, 0x22 },
+ { 0x6b, 0x00 },
+ { 0x6c, 0x02 },
+ { 0x6d, 0x44 },
+ { 0x6e, 0x80 },
+ { 0x6f, 0x1d },
+ { 0x70, 0x8b },
+ { 0x71, 0x00 },
+ { 0x72, 0x14 },
+ { 0x73, 0x54 },
+ { 0x74, 0x00 },
+ { 0x75, 0x8e },
+ { 0x76, 0x00 },
+ { 0x77, 0xff },
+ { 0x78, 0x80 },
+ { 0x79, 0x80 },
+ { 0x7a, 0x80 },
+ { 0x7b, 0xe2 },
+ { 0x7c, 0x00 },
+ };
+
+ /* 7640 and 7648. The defaults should be OK for most registers. */
+ static const struct ov_i2c_regvals norm_7640[] = {
+ { 0x12, 0x80 },
+ { 0x12, 0x14 },
+ };
+
+ /* 7670. Defaults taken from OmniVision provided data,
+ * as provided by Jonathan Corbet of OLPC */
+ static const struct ov_i2c_regvals norm_7670[] = {
+ { OV7670_REG_COM7, OV7670_COM7_RESET },
+ { OV7670_REG_TSLB, 0x04 }, /* OV */
+ { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */
+ { OV7670_REG_CLKRC, 0x1 },
+ /*
+ * Set the hardware window. These values from OV don't entirely
+ * make sense - hstop is less than hstart. But they work...
+ */
+ { OV7670_REG_HSTART, 0x13 }, { OV7670_REG_HSTOP, 0x01 },
+ { OV7670_REG_HREF, 0xb6 }, { OV7670_REG_VSTART, 0x02 },
+ { OV7670_REG_VSTOP, 0x7a }, { OV7670_REG_VREF, 0x0a },
+
+ { OV7670_REG_COM3, 0 }, { OV7670_REG_COM14, 0 },
+ /* Mystery scaling numbers */
+ { 0x70, 0x3a }, { 0x71, 0x35 },
+ { 0x72, 0x11 }, { 0x73, 0xf0 },
+ { 0xa2, 0x02 },
+/* jfm */
+/* { OV7670_REG_COM10, 0x0 }, */
+
+ /* Gamma curve values */
+ { 0x7a, 0x20 },
+/* jfm:win 7b=1c */
+ { 0x7b, 0x10 },
+/* jfm:win 7c=28 */
+ { 0x7c, 0x1e },
+/* jfm:win 7d=3c */
+ { 0x7d, 0x35 },
+ { 0x7e, 0x5a }, { 0x7f, 0x69 },
+ { 0x80, 0x76 }, { 0x81, 0x80 },
+ { 0x82, 0x88 }, { 0x83, 0x8f },
+ { 0x84, 0x96 }, { 0x85, 0xa3 },
+ { 0x86, 0xaf }, { 0x87, 0xc4 },
+ { 0x88, 0xd7 }, { 0x89, 0xe8 },
+
+ /* AGC and AEC parameters. Note we start by disabling those features,
+ then turn them only after tweaking the values. */
+ { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ | OV7670_COM8_AECSTEP
+ | OV7670_COM8_BFILT },
+ { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 },
+ { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */
+/* jfm:win 14=38 */
+ { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */
+ { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 },
+ { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 },
+ { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 },
+ { OV7670_REG_HAECC2, 0x68 },
+/* jfm:win a1=0b */
+ { 0xa1, 0x03 }, /* magic */
+ { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 },
+ { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 },
+ { OV7670_REG_HAECC7, 0x94 },
+ { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ | OV7670_COM8_AECSTEP
+ | OV7670_COM8_BFILT
+ | OV7670_COM8_AGC
+ | OV7670_COM8_AEC },
+
+ /* Almost all of these are magic "reserved" values. */
+ { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b },
+ { 0x16, 0x02 },
+/* jfm */
+/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */
+ { OV7670_REG_MVFP, 0x07 },
+ { 0x21, 0x02 }, { 0x22, 0x91 },
+ { 0x29, 0x07 }, { 0x33, 0x0b },
+ { 0x35, 0x0b }, { 0x37, 0x1d },
+ { 0x38, 0x71 }, { 0x39, 0x2a },
+ { OV7670_REG_COM12, 0x78 }, { 0x4d, 0x40 },
+ { 0x4e, 0x20 }, { OV7670_REG_GFIX, 0 },
+ { 0x6b, 0x4a }, { 0x74, 0x10 },
+ { 0x8d, 0x4f }, { 0x8e, 0 },
+ { 0x8f, 0 }, { 0x90, 0 },
+ { 0x91, 0 }, { 0x96, 0 },
+ { 0x9a, 0 }, { 0xb0, 0x84 },
+ { 0xb1, 0x0c }, { 0xb2, 0x0e },
+ { 0xb3, 0x82 }, { 0xb8, 0x0a },
+
+ /* More reserved magic, some of which tweaks white balance */
+ { 0x43, 0x0a }, { 0x44, 0xf0 },
+ { 0x45, 0x34 }, { 0x46, 0x58 },
+ { 0x47, 0x28 }, { 0x48, 0x3a },
+ { 0x59, 0x88 }, { 0x5a, 0x88 },
+ { 0x5b, 0x44 }, { 0x5c, 0x67 },
+ { 0x5d, 0x49 }, { 0x5e, 0x0e },
+ { 0x6c, 0x0a }, { 0x6d, 0x55 },
+ { 0x6e, 0x11 }, { 0x6f, 0x9f },
+ /* "9e for advance AWB" */
+ { 0x6a, 0x40 }, { OV7670_REG_BLUE, 0x40 },
+ { OV7670_REG_RED, 0x60 },
+ { OV7670_REG_COM8, OV7670_COM8_FASTAEC
+ | OV7670_COM8_AECSTEP
+ | OV7670_COM8_BFILT
+ | OV7670_COM8_AGC
+ | OV7670_COM8_AEC
+ | OV7670_COM8_AWB },
+
+ /* Matrix coefficients */
+ { 0x4f, 0x80 }, { 0x50, 0x80 },
+ { 0x51, 0 }, { 0x52, 0x22 },
+ { 0x53, 0x5e }, { 0x54, 0x80 },
+ { 0x58, 0x9e },
+
+ { OV7670_REG_COM16, OV7670_COM16_AWBGAIN },
+ { OV7670_REG_EDGE, 0 },
+ { 0x75, 0x05 }, { 0x76, 0xe1 },
+ { 0x4c, 0 }, { 0x77, 0x01 },
+ { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 },
+ { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 },
+ { 0x56, 0x40 },
+
+ { 0x34, 0x11 },
+ { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO },
+ { 0xa4, 0x88 }, { 0x96, 0 },
+ { 0x97, 0x30 }, { 0x98, 0x20 },
+ { 0x99, 0x30 }, { 0x9a, 0x84 },
+ { 0x9b, 0x29 }, { 0x9c, 0x03 },
+ { 0x9d, 0x4c }, { 0x9e, 0x3f },
+ { 0x78, 0x04 },
+
+ /* Extra-weird stuff. Some sort of multiplexor register */
+ { 0x79, 0x01 }, { 0xc8, 0xf0 },
+ { 0x79, 0x0f }, { 0xc8, 0x00 },
+ { 0x79, 0x10 }, { 0xc8, 0x7e },
+ { 0x79, 0x0a }, { 0xc8, 0x80 },
+ { 0x79, 0x0b }, { 0xc8, 0x01 },
+ { 0x79, 0x0c }, { 0xc8, 0x0f },
+ { 0x79, 0x0d }, { 0xc8, 0x20 },
+ { 0x79, 0x09 }, { 0xc8, 0x80 },
+ { 0x79, 0x02 }, { 0xc8, 0xc0 },
+ { 0x79, 0x03 }, { 0xc8, 0x40 },
+ { 0x79, 0x05 }, { 0xc8, 0x30 },
+ { 0x79, 0x26 },
+
+ /* Format YUV422 */
+ { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */
+ { OV7670_REG_RGB444, 0 }, /* No RGB444 please */
+ { OV7670_REG_COM1, 0 },
+ { OV7670_REG_COM15, OV7670_COM15_R00FF },
+ { OV7670_REG_COM9, 0x18 },
+ /* 4x gain ceiling; 0x8 is reserved bit */
+ { 0x4f, 0x80 }, /* "matrix coefficient 1" */
+ { 0x50, 0x80 }, /* "matrix coefficient 2" */
+ { 0x52, 0x22 }, /* "matrix coefficient 4" */
+ { 0x53, 0x5e }, /* "matrix coefficient 5" */
+ { 0x54, 0x80 }, /* "matrix coefficient 6" */
+ { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT },
+};
+
+ PDEBUG(D_PROBE, "starting OV7xx0 configuration");
+
+/* jfm:already done? */
+ if (init_ov_sensor(sd) < 0)
+ PDEBUG(D_ERR, "Failed to read sensor ID");
+ else
+ PDEBUG(D_PROBE, "OV7xx0 initialized");
+
+ /* Detect sensor (sub)type */
+ rc = i2c_r(sd, OV7610_REG_COM_I);
+
+ /* add OV7670 here
+ * it appears to be wrongly detected as a 7610 by default */
+ if (rc < 0) {
+ PDEBUG(D_ERR, "Error detecting sensor type");
+ return -1;
+ }
+ if ((rc & 3) == 3) {
+ /* quick hack to make OV7670s work */
+ high = i2c_r(sd, 0x0a);
+ low = i2c_r(sd, 0x0b);
+ /* info("%x, %x", high, low); */
+ if (high == 0x76 && low == 0x73) {
+ PDEBUG(D_PROBE, "Sensor is an OV7670");
+ sd->sensor = SEN_OV7670;
+ } else {
+ PDEBUG(D_PROBE, "Sensor is an OV7610");
+ sd->sensor = SEN_OV7610;
+ }
+ } else if ((rc & 3) == 1) {
+ /* I don't know what's different about the 76BE yet. */
+ if (i2c_r(sd, 0x15) & 1)
+ PDEBUG(D_PROBE, "Sensor is an OV7620AE");
+ else
+ PDEBUG(D_PROBE, "Sensor is an OV76BE");
+
+ /* OV511+ will return all zero isoc data unless we
+ * configure the sensor as a 7620. Someone needs to
+ * find the exact reg. setting that causes this. */
+ sd->sensor = SEN_OV76BE;
+ } else if ((rc & 3) == 0) {
+ /* try to read product id registers */
+ high = i2c_r(sd, 0x0a);
+ if (high < 0) {
+ PDEBUG(D_ERR, "Error detecting camera chip PID");
+ return high;
+ }
+ low = i2c_r(sd, 0x0b);
+ if (low < 0) {
+ PDEBUG(D_ERR, "Error detecting camera chip VER");
+ return low;
+ }
+ if (high == 0x76) {
+ if (low == 0x30) {
+ PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635");
+ sd->sensor = SEN_OV7630;
+ } else if (low == 0x40) {
+ PDEBUG(D_PROBE, "Sensor is an OV7645");
+ sd->sensor = SEN_OV7640; /* FIXME */
+ } else if (low == 0x45) {
+ PDEBUG(D_PROBE, "Sensor is an OV7645B");
+ sd->sensor = SEN_OV7640; /* FIXME */
+ } else if (low == 0x48) {
+ PDEBUG(D_PROBE, "Sensor is an OV7648");
+ sd->sensor = SEN_OV7640; /* FIXME */
+ } else {
+ PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low);
+ return -1;
+ }
+ } else {
+ PDEBUG(D_PROBE, "Sensor is an OV7620");
+ sd->sensor = SEN_OV7620;
+ }
+ } else {
+ PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3);
+ return -1;
+ }
+
+ if (sd->sensor == SEN_OV7620) {
+ PDEBUG(D_PROBE, "Writing 7620 registers");
+ if (write_i2c_regvals(sd, norm_7620,
+ sizeof norm_7620 / sizeof norm_7620[0]))
+ return -1;
+ } else if (sd->sensor == SEN_OV7630) {
+ PDEBUG(D_ERR, "7630 is not supported by this driver version");
+ return -1;
+ } else if (sd->sensor == SEN_OV7640) {
+ PDEBUG(D_PROBE, "Writing 7640 registers");
+ if (write_i2c_regvals(sd, norm_7640,
+ sizeof norm_7640 / sizeof norm_7640[0]))
+ return -1;
+ } else if (sd->sensor == SEN_OV7670) {
+ PDEBUG(D_PROBE, "Writing 7670 registers");
+ if (write_i2c_regvals(sd, norm_7670,
+ sizeof norm_7670 / sizeof norm_7670[0]))
+ return -1;
+ } else {
+ PDEBUG(D_PROBE, "Writing 7610 registers");
+ if (write_i2c_regvals(sd, norm_7610,
+ sizeof norm_7610 / sizeof norm_7610[0]))
+ return -1;
+ }
+
+ /* Set sensor-specific vars */
+ sd->maxwidth = 640;
+ sd->maxheight = 480;
+ return 0;
+}
+
+/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
+static int ov6xx0_configure(struct sd *sd)
+{
+ int rc;
+ static const struct ov_i2c_regvals norm_6x20[] = {
+ { 0x12, 0x80 }, /* reset */
+ { 0x11, 0x01 },
+ { 0x03, 0x60 },
+ { 0x05, 0x7f }, /* For when autoadjust is off */
+ { 0x07, 0xa8 },
+ /* The ratio of 0x0c and 0x0d controls the white point */
+ { 0x0c, 0x24 },
+ { 0x0d, 0x24 },
+ { 0x0f, 0x15 }, /* COMS */
+ { 0x10, 0x75 }, /* AEC Exposure time */
+ { 0x12, 0x24 }, /* Enable AGC */
+ { 0x14, 0x04 },
+ /* 0x16: 0x06 helps frame stability with moving objects */
+ { 0x16, 0x06 },
+/* { 0x20, 0x30 }, * Aperture correction enable */
+ { 0x26, 0xb2 }, /* BLC enable */
+ /* 0x28: 0x05 Selects RGB format if RGB on */
+ { 0x28, 0x05 },
+ { 0x2a, 0x04 }, /* Disable framerate adjust */
+/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */
+ { 0x2d, 0x99 },
+ { 0x33, 0xa0 }, /* Color Processing Parameter */
+ { 0x34, 0xd2 }, /* Max A/D range */
+ { 0x38, 0x8b },
+ { 0x39, 0x40 },
+
+ { 0x3c, 0x39 }, /* Enable AEC mode changing */
+ { 0x3c, 0x3c }, /* Change AEC mode */
+ { 0x3c, 0x24 }, /* Disable AEC mode changing */
+
+ { 0x3d, 0x80 },
+ /* These next two registers (0x4a, 0x4b) are undocumented.
+ * They control the color balance */
+ { 0x4a, 0x80 },
+ { 0x4b, 0x80 },
+ { 0x4d, 0xd2 }, /* This reduces noise a bit */
+ { 0x4e, 0xc1 },
+ { 0x4f, 0x04 },
+/* Do 50-53 have any effect? */
+/* Toggle 0x12[2] off and on here? */
+ };
+
+ static const struct ov_i2c_regvals norm_6x30[] = {
+ { 0x12, 0x80 }, /* Reset */
+ { 0x00, 0x1f }, /* Gain */
+ { 0x01, 0x99 }, /* Blue gain */
+ { 0x02, 0x7c }, /* Red gain */
+ { 0x03, 0xc0 }, /* Saturation */
+ { 0x05, 0x0a }, /* Contrast */
+ { 0x06, 0x95 }, /* Brightness */
+ { 0x07, 0x2d }, /* Sharpness */
+ { 0x0c, 0x20 },
+ { 0x0d, 0x20 },
+ { 0x0e, 0x20 },
+ { 0x0f, 0x05 },
+ { 0x10, 0x9a },
+ { 0x11, 0x00 }, /* Pixel clock = fastest */
+ { 0x12, 0x24 }, /* Enable AGC and AWB */
+ { 0x13, 0x21 },
+ { 0x14, 0x80 },
+ { 0x15, 0x01 },
+ { 0x16, 0x03 },
+ { 0x17, 0x38 },
+ { 0x18, 0xea },
+ { 0x19, 0x04 },
+ { 0x1a, 0x93 },
+ { 0x1b, 0x00 },
+ { 0x1e, 0xc4 },
+ { 0x1f, 0x04 },
+ { 0x20, 0x20 },
+ { 0x21, 0x10 },
+ { 0x22, 0x88 },
+ { 0x23, 0xc0 }, /* Crystal circuit power level */
+ { 0x25, 0x9a }, /* Increase AEC black ratio */
+ { 0x26, 0xb2 }, /* BLC enable */
+ { 0x27, 0xa2 },
+ { 0x28, 0x00 },
+ { 0x29, 0x00 },
+ { 0x2a, 0x84 }, /* 60 Hz power */
+ { 0x2b, 0xa8 }, /* 60 Hz power */
+ { 0x2c, 0xa0 },
+ { 0x2d, 0x95 }, /* Enable auto-brightness */
+ { 0x2e, 0x88 },
+ { 0x33, 0x26 },
+ { 0x34, 0x03 },
+ { 0x36, 0x8f },
+ { 0x37, 0x80 },
+ { 0x38, 0x83 },
+ { 0x39, 0x80 },
+ { 0x3a, 0x0f },
+ { 0x3b, 0x3c },
+ { 0x3c, 0x1a },
+ { 0x3d, 0x80 },
+ { 0x3e, 0x80 },
+ { 0x3f, 0x0e },
+ { 0x40, 0x00 }, /* White bal */
+ { 0x41, 0x00 }, /* White bal */
+ { 0x42, 0x80 },
+ { 0x43, 0x3f }, /* White bal */
+ { 0x44, 0x80 },
+ { 0x45, 0x20 },
+ { 0x46, 0x20 },
+ { 0x47, 0x80 },
+ { 0x48, 0x7f },
+ { 0x49, 0x00 },
+ { 0x4a, 0x00 },
+ { 0x4b, 0x80 },
+ { 0x4c, 0xd0 },
+ { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
+ { 0x4e, 0x40 },
+ { 0x4f, 0x07 }, /* UV avg., col. killer: max */
+ { 0x50, 0xff },
+ { 0x54, 0x23 }, /* Max AGC gain: 18dB */
+ { 0x55, 0xff },
+ { 0x56, 0x12 },
+ { 0x57, 0x81 },
+ { 0x58, 0x75 },
+ { 0x59, 0x01 }, /* AGC dark current comp.: +1 */
+ { 0x5a, 0x2c },
+ { 0x5b, 0x0f }, /* AWB chrominance levels */
+ { 0x5c, 0x10 },
+ { 0x3d, 0x80 },
+ { 0x27, 0xa6 },
+ { 0x12, 0x20 }, /* Toggle AWB */
+ { 0x12, 0x24 },
+ };
+
+ PDEBUG(D_PROBE, "starting sensor configuration");
+
+ if (init_ov_sensor(sd) < 0) {
+ PDEBUG(D_ERR, "Failed to read sensor ID.");
+ return -1;
+ }
+ PDEBUG(D_PROBE, "OV6xx0 sensor detected");
+
+ /* Detect sensor (sub)type */
+ rc = i2c_r(sd, OV7610_REG_COM_I);
+ if (rc < 0) {
+ PDEBUG(D_ERR, "Error detecting sensor type");
+ return -1;
+ }
+
+ /* Ugh. The first two bits are the version bits, but
+ * the entire register value must be used. I guess OVT
+ * underestimated how many variants they would make. */
+ if (rc == 0x00) {
+ sd->sensor = SEN_OV6630;
+ PDEBUG(D_ERR,
+ "WARNING: Sensor is an OV66308. Your camera may have");
+ PDEBUG(D_ERR, "been misdetected in previous driver versions.");
+ } else if (rc == 0x01) {
+ sd->sensor = SEN_OV6620;
+ PDEBUG(D_PROBE, "Sensor is an OV6620");
+ } else if (rc == 0x02) {
+ sd->sensor = SEN_OV6630;
+ PDEBUG(D_PROBE, "Sensor is an OV66308AE");
+ } else if (rc == 0x03) {
+ sd->sensor = SEN_OV6630;
+ PDEBUG(D_PROBE, "Sensor is an OV66308AF");
+ } else if (rc == 0x90) {
+ sd->sensor = SEN_OV6630;
+ PDEBUG(D_ERR,
+ "WARNING: Sensor is an OV66307. Your camera may have");
+ PDEBUG(D_ERR, "been misdetected in previous driver versions.");
+ } else {
+ PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc);
+ return -1;
+ }
+
+ /* Set sensor-specific vars */
+ sd->maxwidth = 352;
+ sd->maxheight = 288;
+
+ if (sd->sensor == SEN_OV6620) {
+ PDEBUG(D_PROBE, "Writing 6x20 registers");
+ if (write_i2c_regvals(sd, norm_6x20,
+ sizeof norm_6x20 / sizeof norm_6x20[0]))
+ return -1;
+ } else {
+ PDEBUG(D_PROBE, "Writing 6x30 registers");
+ if (write_i2c_regvals(sd, norm_6x30,
+ sizeof norm_6x30 / sizeof norm_6x30[0]))
+ return -1;
+ }
+ return 0;
+}
+
+/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */
+static void ov51x_led_control(struct sd *sd, int on)
+{
+ PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off");
+
+/* if (sd->bridge == BRG_OV511PLUS) */
+/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */
+/* else if (sd->bridge == BRG_OV519) */
+ reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */
+/* else if (sd->bclass == BCL_OV518) */
+/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+/* (from ov519_configure) */
+ static const struct ov_regvals init_519[] = {
+ { 0x5a, 0x6d }, /* EnableSystem */
+/* jfm trace usbsnoop3-1.txt */
+/* jfm 53 = fb */
+ { 0x53, 0x9b },
+ { 0x54, 0xff }, /* set bit2 to enable jpeg */
+ { 0x5d, 0x03 },
+ { 0x49, 0x01 },
+ { 0x48, 0x00 },
+ /* Set LED pin to output mode. Bit 4 must be cleared or sensor
+ * detection will fail. This deserves further investigation. */
+ { OV519_GPIO_IO_CTRL0, 0xee },
+ { 0x51, 0x0f }, /* SetUsbInit */
+ { 0x51, 0x00 },
+ { 0x22, 0x00 },
+ /* windows reads 0x55 at this point*/
+ };
+
+ if (write_regvals(sd, init_519, ARRAY_SIZE(init_519)))
+ goto error;
+/* jfm: not seen in windows trace */
+ if (ov519_init_compression(sd))
+ goto error;
+ ov51x_led_control(sd, 0); /* turn LED off */
+
+ /* Test for 76xx */
+ sd->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0)
+ goto error;
+
+ /* The OV519 must be more aggressive about sensor detection since
+ * I2C write will never fail if the sensor is not present. We have
+ * to try to initialize the sensor to detect its presence */
+ if (init_ov_sensor(sd) < 0) {
+ /* Test for 6xx0 */
+ sd->primary_i2c_slave = OV6xx0_SID;
+ if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0)
+ goto error;
+
+ if (init_ov_sensor(sd) < 0) {
+ /* Test for 8xx0 */
+ sd->primary_i2c_slave = OV8xx0_SID;
+ if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0)
+ goto error;
+
+ if (init_ov_sensor(sd) < 0) {
+ PDEBUG(D_ERR,
+ "Can't determine sensor slave IDs");
+ goto error;
+ } else {
+ if (ov8xx0_configure(sd) < 0) {
+ PDEBUG(D_ERR,
+ "Failed to configure OV8xx0 sensor");
+ goto error;
+ }
+ }
+ } else {
+ if (ov6xx0_configure(sd) < 0) {
+ PDEBUG(D_ERR, "Failed to configure OV6xx0");
+ goto error;
+ }
+ }
+ } else {
+ if (ov7xx0_configure(sd) < 0) {
+ PDEBUG(D_ERR, "Failed to configure OV7xx0");
+ goto error;
+ }
+ }
+
+ cam = &gspca_dev->cam;
+ cam->epaddr = OV511_ENDPOINT_ADDRESS;
+ if (sd->maxwidth == 640) {
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ } else {
+ cam->cam_mode = sif_mode;
+ cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ }
+ cam->dev_name = (char *) id->driver_info;
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ return 0;
+error:
+ PDEBUG(D_ERR, "OV519 Config failed");
+ return -EBUSY;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+/* Sets up the OV519 with the given image parameters
+ *
+ * OV519 needs a completely different approach, until we can figure out what
+ * the individual registers do.
+ *
+ * Do not put any sensor-specific code in here (including I2C I/O functions)
+ */
+static int ov519_mode_init_regs(struct sd *sd,
+ int width, int height)
+{
+ static const struct ov_regvals mode_init_519_ov7670[] = {
+ { 0x5d, 0x03 }, /* Turn off suspend mode */
+ { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
+ { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { 0xa2, 0x20 }, /* a2-a5 are undocumented */
+ { 0xa3, 0x18 },
+ { 0xa4, 0x04 },
+ { 0xa5, 0x28 },
+ { 0x37, 0x00 }, /* SetUsbInit */
+ { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
+ /* Enable both fields, YUV Input, disable defect comp (why?) */
+ { 0x20, 0x0c },
+ { 0x21, 0x38 },
+ { 0x22, 0x1d },
+ { 0x17, 0x50 }, /* undocumented */
+ { 0x37, 0x00 }, /* undocumented */
+ { 0x40, 0xff }, /* I2C timeout counter */
+ { 0x46, 0x00 }, /* I2C clock prescaler */
+ { 0x59, 0x04 }, /* new from windrv 090403 */
+ { 0xff, 0x00 }, /* undocumented */
+ /* windows reads 0x55 at this point, why? */
+ };
+
+ static const struct ov_regvals mode_init_519[] = {
+ { 0x5d, 0x03 }, /* Turn off suspend mode */
+ { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */
+ { 0x54, 0x0f }, /* bit2 (jpeg enable) */
+ { 0xa2, 0x20 }, /* a2-a5 are undocumented */
+ { 0xa3, 0x18 },
+ { 0xa4, 0x04 },
+ { 0xa5, 0x28 },
+ { 0x37, 0x00 }, /* SetUsbInit */
+ { 0x55, 0x02 }, /* 4.096 Mhz audio clock */
+ /* Enable both fields, YUV Input, disable defect comp (why?) */
+ { 0x22, 0x1d },
+ { 0x17, 0x50 }, /* undocumented */
+ { 0x37, 0x00 }, /* undocumented */
+ { 0x40, 0xff }, /* I2C timeout counter */
+ { 0x46, 0x00 }, /* I2C clock prescaler */
+ { 0x59, 0x04 }, /* new from windrv 090403 */
+ { 0xff, 0x00 }, /* undocumented */
+ /* windows reads 0x55 at this point, why? */
+ };
+
+/* int hi_res; */
+
+ PDEBUG(D_CONF, "mode init %dx%d", width, height);
+
+/* if (width >= 800 && height >= 600)
+ hi_res = 1;
+ else
+ hi_res = 0; */
+
+/* if (ov51x_stop(sd) < 0)
+ return -EIO; */
+
+ /******** Set the mode ********/
+ if (sd->sensor != SEN_OV7670) {
+ if (write_regvals(sd, mode_init_519,
+ ARRAY_SIZE(mode_init_519)))
+ return -EIO;
+ } else {
+ if (write_regvals(sd, mode_init_519_ov7670,
+ ARRAY_SIZE(mode_init_519_ov7670)))
+ return -EIO;
+ }
+
+ if (sd->sensor == SEN_OV7640) {
+ /* Select 8-bit input mode */
+ reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10);
+ }
+
+ reg_w(sd, OV519_CAM_H_SIZE, width >> 4);
+ reg_w(sd, OV519_CAM_V_SIZE, height >> 3);
+ reg_w(sd, OV519_CAM_X_OFFSETL, 0x00);
+ reg_w(sd, OV519_CAM_X_OFFSETH, 0x00);
+ reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00);
+ reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00);
+ reg_w(sd, OV519_CAM_DIVIDER, 0x00);
+ reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */
+ reg_w(sd, 0x26, 0x00); /* Undocumented */
+
+ /******** Set the framerate ********/
+ if (frame_rate > 0)
+ sd->frame_rate = frame_rate;
+
+/* FIXME: These are only valid at the max resolution. */
+ sd->clockdiv = 0;
+ if (sd->sensor == SEN_OV7640) {
+ switch (sd->frame_rate) {
+/*jfm: default was 30 fps */
+ case 30:
+ reg_w(sd, 0xa4, 0x0c);
+ reg_w(sd, 0x23, 0xff);
+ break;
+ case 25:
+ reg_w(sd, 0xa4, 0x0c);
+ reg_w(sd, 0x23, 0x1f);
+ break;
+ case 20:
+ reg_w(sd, 0xa4, 0x0c);
+ reg_w(sd, 0x23, 0x1b);
+ break;
+ default:
+/* case 15: */
+ reg_w(sd, 0xa4, 0x04);
+ reg_w(sd, 0x23, 0xff);
+ sd->clockdiv = 1;
+ break;
+ case 10:
+ reg_w(sd, 0xa4, 0x04);
+ reg_w(sd, 0x23, 0x1f);
+ sd->clockdiv = 1;
+ break;
+ case 5:
+ reg_w(sd, 0xa4, 0x04);
+ reg_w(sd, 0x23, 0x1b);
+ sd->clockdiv = 1;
+ break;
+ }
+ } else if (sd->sensor == SEN_OV8610) {
+ switch (sd->frame_rate) {
+ default: /* 15 fps */
+/* case 15: */
+ reg_w(sd, 0xa4, 0x06);
+ reg_w(sd, 0x23, 0xff);
+ break;
+ case 10:
+ reg_w(sd, 0xa4, 0x06);
+ reg_w(sd, 0x23, 0x1f);
+ break;
+ case 5:
+ reg_w(sd, 0xa4, 0x06);
+ reg_w(sd, 0x23, 0x1b);
+ break;
+ }
+ sd->clockdiv = 0;
+ } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */
+ PDEBUG(D_STREAM, "Setting framerate to %d fps",
+ (sd->frame_rate == 0) ? 15 : sd->frame_rate);
+ switch (sd->frame_rate) {
+ case 30:
+ reg_w(sd, 0xa4, 0x10);
+ reg_w(sd, 0x23, 0xff);
+ break;
+ case 20:
+ reg_w(sd, 0xa4, 0x10);
+ reg_w(sd, 0x23, 0x1b);
+ break;
+ default: /* 15 fps */
+/* case 15: */
+ reg_w(sd, 0xa4, 0x10);
+ reg_w(sd, 0x23, 0xff);
+ sd->clockdiv = 1;
+ break;
+ }
+ }
+
+/* if (ov51x_restart(sd) < 0)
+ return -EIO; */
+
+ /* Reset it just for good measure */
+/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0)
+ return -EIO; */
+ return 0;
+}
+
+static int mode_init_ov_sensor_regs(struct sd *sd,
+ struct ovsensor_window *win)
+{
+ int qvga = win->quarter;
+
+ /******** Mode (VGA/QVGA) and sensor specific regs ********/
+ switch (sd->sensor) {
+ case SEN_OV8610:
+ /* For OV8610 qvga means qsvga */
+ i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5);
+ break;
+ case SEN_OV7610:
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+ break;
+ case SEN_OV7620:
+/* i2c_w(sd, 0x2b, 0x00); */
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+ i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
+ i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a);
+ i2c_w(sd, 0x25, qvga ? 0x30 : 0x60);
+ i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40);
+ i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
+ i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
+ break;
+ case SEN_OV76BE:
+/* i2c_w(sd, 0x2b, 0x00); */
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+ break;
+ case SEN_OV7640:
+/* i2c_w(sd, 0x2b, 0x00); */
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+ i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20);
+/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */
+/* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */
+/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */
+/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */
+/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */
+ break;
+ case SEN_OV7670:
+ /* set COM7_FMT_VGA or COM7_FMT_QVGA
+ * do we need to set anything else?
+ * HSTART etc are set in set_ov_sensor_window itself */
+ i2c_w_mask(sd, OV7670_REG_COM7,
+ qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA,
+ OV7670_COM7_FMT_MASK);
+ break;
+ case SEN_OV6620:
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+ break;
+ case SEN_OV6630:
+ i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /******** Palette-specific regs ********/
+/* Need to do work here for the OV7670 */
+
+ if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
+ /* not valid on the OV6620/OV7620/6630? */
+ i2c_w_mask(sd, 0x0e, 0x00, 0x40);
+ }
+
+ /* The OV518 needs special treatment. Although both the OV518
+ * and the OV6630 support a 16-bit video bus, only the 8 bit Y
+ * bus is actually used. The UV bus is tied to ground.
+ * Therefore, the OV6630 needs to be in 8-bit multiplexed
+ * output mode */
+
+ /* OV7640 is 8-bit only */
+
+ if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640)
+ i2c_w_mask(sd, 0x13, 0x00, 0x20);
+/* } */
+
+ /******** Clock programming ********/
+ /* The OV6620 needs special handling. This prevents the
+ * severe banding that normally occurs */
+ if (sd->sensor == SEN_OV6620) {
+
+ /* Clock down */
+ i2c_w(sd, 0x2a, 0x04);
+ i2c_w(sd, 0x11, win->clockdiv);
+ i2c_w(sd, 0x2a, 0x84);
+ /* This next setting is critical. It seems to improve
+ * the gain or the contrast. The "reserved" bits seem
+ * to have some effect in this case. */
+ i2c_w(sd, 0x2d, 0x85);
+ } else if (win->clockdiv >= 0) {
+ i2c_w(sd, 0x11, win->clockdiv);
+ }
+
+ /******** Special Features ********/
+/* no evidence this is possible with OV7670, either */
+ /* Test Pattern */
+ if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670)
+ i2c_w_mask(sd, 0x12, 0x00, 0x02);
+
+ /* Enable auto white balance */
+ if (sd->sensor == SEN_OV7670)
+ i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB,
+ OV7670_COM8_AWB);
+ else
+ i2c_w_mask(sd, 0x12, 0x04, 0x04);
+
+ /* This will go away as soon as ov51x_mode_init_sensor_regs() */
+ /* is fully tested. */
+ /* 7620/6620/6630? don't have register 0x35, so play it safe */
+ if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) {
+ if (win->width == 640 /*&& win->height == 480*/)
+ i2c_w(sd, 0x35, 0x9e);
+ else
+ i2c_w(sd, 0x35, 0x1e);
+ }
+ return 0;
+}
+
+static int set_ov_sensor_window(struct sd *sd,
+ struct ovsensor_window *win)
+{
+ int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale;
+ int ret, hstart, hstop, vstop, vstart;
+ __u8 v;
+
+ /* The different sensor ICs handle setting up of window differently.
+ * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */
+ switch (sd->sensor) {
+ case SEN_OV8610:
+ hwsbase = 0x1e;
+ hwebase = 0x1e;
+ vwsbase = 0x02;
+ vwebase = 0x02;
+ break;
+ case SEN_OV7610:
+ case SEN_OV76BE:
+ hwsbase = 0x38;
+ hwebase = 0x3a;
+ vwsbase = vwebase = 0x05;
+ break;
+ case SEN_OV6620:
+ case SEN_OV6630:
+ hwsbase = 0x38;
+ hwebase = 0x3a;
+ vwsbase = 0x05;
+ vwebase = 0x06;
+ break;
+ case SEN_OV7620:
+ hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
+ hwebase = 0x2f;
+ vwsbase = vwebase = 0x05;
+ break;
+ case SEN_OV7640:
+ hwsbase = 0x1a;
+ hwebase = 0x1a;
+ vwsbase = vwebase = 0x03;
+ break;
+ case SEN_OV7670:
+ /*handling of OV7670 hardware sensor start and stop values
+ * is very odd, compared to the other OV sensors */
+ vwsbase = vwebase = hwebase = hwsbase = 0x00;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (sd->sensor) {
+ case SEN_OV6620:
+ case SEN_OV6630:
+ if (win->quarter) { /* QCIF */
+ hwscale = 0;
+ vwscale = 0;
+ } else { /* CIF */
+ hwscale = 1;
+ vwscale = 1; /* The datasheet says 0;
+ * it's wrong */
+ }
+ break;
+ case SEN_OV8610:
+ if (win->quarter) { /* QSVGA */
+ hwscale = 1;
+ vwscale = 1;
+ } else { /* SVGA */
+ hwscale = 2;
+ vwscale = 2;
+ }
+ break;
+ default: /* SEN_OV7xx0 */
+ if (win->quarter) { /* QVGA */
+ hwscale = 1;
+ vwscale = 0;
+ } else { /* VGA */
+ hwscale = 2;
+ vwscale = 1;
+ }
+ }
+
+ ret = mode_init_ov_sensor_regs(sd, win);
+ if (ret < 0)
+ return ret;
+
+ if (sd->sensor == SEN_OV8610) {
+ i2c_w_mask(sd, 0x2d, 0x05, 0x40);
+ /* old 0x95, new 0x05 from windrv 090403 */
+ /* bits 5-7: reserved */
+ i2c_w_mask(sd, 0x28, 0x20, 0x20);
+ /* bit 5: progressive mode on */
+ }
+
+ /* The below is wrong for OV7670s because their window registers
+ * only store the high bits in 0x17 to 0x1a */
+
+ /* SRH Use sd->max values instead of requested win values */
+ /* SCS Since we're sticking with only the max hardware widths
+ * for a given mode */
+ /* I can hard code this for OV7670s */
+ /* Yes, these numbers do look odd, but they're tested and work! */
+ if (sd->sensor == SEN_OV7670) {
+ if (win->quarter) { /* QVGA from ov7670.c by
+ * Jonathan Corbet */
+ hstart = 164;
+ hstop = 20;
+ vstart = 14;
+ vstop = 494;
+ } else { /* VGA */
+ hstart = 158;
+ hstop = 14;
+ vstart = 10;
+ vstop = 490;
+ }
+ /* OV7670 hardware window registers are split across
+ * multiple locations */
+ i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff);
+ i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff);
+ v = i2c_r(sd, OV7670_REG_HREF);
+ v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07);
+ msleep(10); /* need to sleep between read and write to
+ * same reg! */
+ i2c_w(sd, OV7670_REG_HREF, v);
+
+ i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff);
+ i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff);
+ v = i2c_r(sd, OV7670_REG_VREF);
+ v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03);
+ msleep(10); /* need to sleep between read and write to
+ * same reg! */
+ i2c_w(sd, OV7670_REG_VREF, v);
+
+ } else {
+ i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale));
+ i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale));
+ i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale));
+ i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale));
+ }
+ return 0;
+}
+
+static int ov_sensor_mode_setup(struct sd *sd,
+ int width, int height)
+{
+ struct ovsensor_window win;
+
+/* win.format = mode; */
+
+ /* Unless subcapture is enabled,
+ * center the image window and downsample
+ * if possible to increase the field of view */
+ /* NOTE: OV518(+) and OV519 does downsampling on its own */
+ win.width = width;
+ win.height = height;
+ if (width == sd->maxwidth)
+ win.quarter = 0;
+ else
+ win.quarter = 1;
+
+ /* Center it */
+ win.x = (win.width - width) / 2;
+ win.y = (win.height - height) / 2;
+
+ /* Clock is determined by OV519 frame rate code */
+ win.clockdiv = sd->clockdiv;
+
+ PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv);
+ return set_ov_sensor_window(sd, &win);
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int ret;
+
+
+ ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height);
+ if (ret < 0)
+ goto out;
+ ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height);
+ if (ret < 0)
+ goto out;
+
+ ret = ov51x_restart((struct sd *) gspca_dev);
+ if (ret < 0)
+ goto out;
+ PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
+ ov51x_led_control(sd, 1);
+ return;
+out:
+ PDEBUG(D_ERR, "camera start error:%d", ret);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ ov51x_stop((struct sd *) gspca_dev);
+ ov51x_led_control((struct sd *) gspca_dev, 0);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ /* Header of ov519 is 16 bytes:
+ * Byte Value Description
+ * 0 0xff magic
+ * 1 0xff magic
+ * 2 0xff magic
+ * 3 0xXX 0x50 = SOF, 0x51 = EOF
+ * 9 0xXX 0x01 initial frame without data,
+ * 0x00 standard frame with image
+ * 14 Lo in EOF: length of image data / 8
+ * 15 Hi
+ */
+
+ if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) {
+ switch (data[3]) {
+ case 0x50: /* start of frame */
+#define HDRSZ 16
+ data += HDRSZ;
+ len -= HDRSZ;
+#undef HDRSZ
+ if (data[0] == 0xff || data[1] == 0xd8)
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ else
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ return;
+ case 0x51: /* end of frame */
+ if (data[9] != 0)
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
+ return;
+ }
+ }
+
+ /* intermediate packet */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data, len);
+}
+
+/* -- management routines -- */
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int val;
+/* int was_streaming; */
+
+ val = sd->brightness;
+ PDEBUG(D_CONF, "brightness:%d", val);
+/* was_streaming = gspca_dev->streaming;
+ * if (was_streaming)
+ * ov51x_stop(sd); */
+ switch (sd->sensor) {
+ case SEN_OV8610:
+ case SEN_OV7610:
+ case SEN_OV76BE:
+ case SEN_OV6620:
+ case SEN_OV6630:
+ case SEN_OV7640:
+ i2c_w(sd, OV7610_REG_BRT, val);
+ break;
+ case SEN_OV7620:
+ /* 7620 doesn't like manual changes when in auto mode */
+/*fixme
+ * if (!sd->auto_brt) */
+ i2c_w(sd, OV7610_REG_BRT, val);
+ break;
+ case SEN_OV7670:
+/*jfm - from windblows
+ * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */
+ i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val));
+ break;
+ }
+/* if (was_streaming)
+ * ov51x_restart(sd); */
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int val;
+/* int was_streaming; */
+
+ val = sd->contrast;
+ PDEBUG(D_CONF, "contrast:%d", val);
+/* was_streaming = gspca_dev->streaming;
+ if (was_streaming)
+ ov51x_stop(sd); */
+ switch (sd->sensor) {
+ case SEN_OV7610:
+ case SEN_OV6620:
+ i2c_w(sd, OV7610_REG_CNT, val);
+ break;
+ case SEN_OV6630:
+ i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f);
+ case SEN_OV8610: {
+ static const __u8 ctab[] = {
+ 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f
+ };
+
+ /* Use Y gamma control instead. Bit 0 enables it. */
+ i2c_w(sd, 0x64, ctab[val >> 5]);
+ break;
+ }
+ case SEN_OV7620: {
+ static const __u8 ctab[] = {
+ 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
+ 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
+ };
+
+ /* Use Y gamma control instead. Bit 0 enables it. */
+ i2c_w(sd, 0x64, ctab[val >> 4]);
+ break;
+ }
+ case SEN_OV7640:
+ /* Use gain control instead. */
+ i2c_w(sd, OV7610_REG_GAIN, val >> 2);
+ break;
+ case SEN_OV7670:
+ /* check that this isn't just the same as ov7610 */
+ i2c_w(sd, OV7670_REG_CONTRAS, val >> 1);
+ break;
+ }
+/* if (was_streaming)
+ ov51x_restart(sd); */
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int val;
+/* int was_streaming; */
+
+ val = sd->colors;
+ PDEBUG(D_CONF, "saturation:%d", val);
+/* was_streaming = gspca_dev->streaming;
+ if (was_streaming)
+ ov51x_stop(sd); */
+ switch (sd->sensor) {
+ case SEN_OV8610:
+ case SEN_OV7610:
+ case SEN_OV76BE:
+ case SEN_OV6620:
+ case SEN_OV6630:
+ i2c_w(sd, OV7610_REG_SAT, val);
+ break;
+ case SEN_OV7620:
+ /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
+/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e);
+ if (rc < 0)
+ goto out; */
+ i2c_w(sd, OV7610_REG_SAT, val);
+ break;
+ case SEN_OV7640:
+ i2c_w(sd, OV7610_REG_SAT, val & 0xf0);
+ break;
+ case SEN_OV7670:
+ /* supported later once I work out how to do it
+ * transparently fail now! */
+ /* set REG_COM13 values for UV sat auto mode */
+ break;
+ }
+/* if (was_streaming)
+ ov51x_restart(sd); */
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")},
+ {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")},
+ {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")},
+ {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")},
+ {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")},
+ {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")},
+ {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")},
+ {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")},
+ {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")},
+ {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")},
+ {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")},
+ {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")},
+ {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")},
+ {}
+};
+#undef DVNAME
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
+
+module_param(frame_rate, int, 0644);
+MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)");
+
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
new file mode 100644
index 00000000000..fa7abc41109
--- /dev/null
+++ b/drivers/media/video/gspca/pac207.c
@@ -0,0 +1,622 @@
+/*
+ * Pixart PAC207BCA library
+ *
+ * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
+ * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
+ * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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
+ *
+ */
+
+#define MODULE_NAME "pac207"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
+MODULE_DESCRIPTION("Pixart PAC207");
+MODULE_LICENSE("GPL");
+
+#define PAC207_CTRL_TIMEOUT 100 /* ms */
+
+#define PAC207_BRIGHTNESS_MIN 0
+#define PAC207_BRIGHTNESS_MAX 255
+#define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */
+
+/* An exposure value of 4 also works (3 does not) but then we need to lower
+ the compression balance setting when in 352x288 mode, otherwise the usb
+ bandwidth is not enough and packets get dropped resulting in corrupt
+ frames. The problem with this is that when the compression balance gets
+ lowered below 0x80, the pac207 starts using a different compression
+ algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix
+ and currently we do not know how to decompress these lines, so for now
+ we use a minimum exposure value of 5 */
+#define PAC207_EXPOSURE_MIN 5
+#define PAC207_EXPOSURE_MAX 26
+#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 ?? */
+#define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */
+
+#define PAC207_GAIN_MIN 0
+#define PAC207_GAIN_MAX 31
+#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */
+#define PAC207_GAIN_KNEE 20
+
+#define PAC207_AUTOGAIN_DEADZONE 30
+/* We calculating the autogain at the end of the transfer of a frame, at this
+ moment a frame with the old settings is being transmitted, and a frame is
+ being captured with the old settings. So if we adjust the autogain we must
+ ignore atleast the 2 next frames for the new settings to come into effect
+ before doing any other adjustments */
+#define PAC207_AUTOGAIN_IGNORE_FRAMES 3
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ u8 mode;
+
+ u8 brightness;
+ u8 exposure;
+ u8 autogain;
+ u8 gain;
+
+ u8 sof_read;
+ u8 header_read;
+ u8 autogain_ignore_frames;
+
+ atomic_t avg_lum;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = PAC207_BRIGHTNESS_MIN,
+ .maximum = PAC207_BRIGHTNESS_MAX,
+ .step = 1,
+ .default_value = PAC207_BRIGHTNESS_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_EXPOSURE 1
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = PAC207_EXPOSURE_MIN,
+ .maximum = PAC207_EXPOSURE_MAX,
+ .step = 1,
+ .default_value = PAC207_EXPOSURE_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setexposure,
+ .get = sd_getexposure,
+ },
+#define SD_AUTOGAIN 2
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ .flags = 0,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+#define SD_GAIN 3
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = PAC207_GAIN_MIN,
+ .maximum = PAC207_GAIN_MAX,
+ .step = 1,
+ .default_value = PAC207_GAIN_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setgain,
+ .get = sd_getgain,
+ },
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = (176 + 2) * 144,
+ /* uncompressed, add 2 bytes / line for line header */
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ /* compressed, but only when needed (not compressed
+ when the framerate is low) */
+ .sizeimage = (352 + 2) * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+static const __u8 pac207_sensor_init[][8] = {
+ {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},
+ {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
+ {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
+ {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
+ {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
+};
+
+ /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
+static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
+
+static const unsigned char pac207_sof_marker[5] =
+ { 0xff, 0xff, 0x00, 0xff, 0x96 };
+
+static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
+ const u8 *buffer, u16 length)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int err;
+
+ memcpy(gspca_dev->usb_buf, buffer, length);
+
+ err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x00, index,
+ gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT);
+ if (err < 0)
+ PDEBUG(D_ERR,
+ "Failed to write registers to index 0x%04X, error %d)",
+ index, err);
+
+ return err;
+}
+
+
+int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int err;
+
+ err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
+ if (err)
+ PDEBUG(D_ERR, "Failed to write a register (index 0x%04X,"
+ " value 0x%02X, error %d)", index, value, err);
+
+ return err;
+}
+
+
+int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int res;
+
+ res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x00, index,
+ gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT);
+ if (res < 0) {
+ PDEBUG(D_ERR,
+ "Failed to read a register (index 0x%04X, error %d)",
+ index, res);
+ return res;
+ }
+
+ return gspca_dev->usb_buf[0];
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ u8 idreg[2];
+
+ idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
+ idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
+ idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
+ idreg[1] = idreg[1] & 0x0f;
+ PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
+ idreg[0], idreg[1]);
+
+ if (idreg[0] != 0x27) {
+ PDEBUG(D_PROBE, "Error invalid sensor ID!");
+ return -ENODEV;
+ }
+
+ pac207_write_reg(gspca_dev, 0x41, 0x00);
+ /* Bit_0=Image Format,
+ * Bit_1=LED,
+ * Bit_2=Compression test mode enable */
+ pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
+ pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
+
+ PDEBUG(D_PROBE,
+ "Pixart PAC207BCA Image Processor and Control Chip detected"
+ " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x05;
+ cam->cam_mode = sif_mode;
+ cam->nmodes = ARRAY_SIZE(sif_mode);
+ sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
+ sd->exposure = PAC207_EXPOSURE_DEFAULT;
+ sd->gain = PAC207_GAIN_DEFAULT;
+
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = 1;
+ return 0;
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 mode;
+
+ pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */
+ pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
+ pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
+ pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
+ pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8);
+ pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
+ pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
+
+ /* Compression Balance */
+ if (gspca_dev->width == 176)
+ pac207_write_reg(gspca_dev, 0x4a, 0xff);
+ else
+ pac207_write_reg(gspca_dev, 0x4a, 0x88);
+ pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
+ pac207_write_reg(gspca_dev, 0x08, sd->brightness);
+
+ /* PGA global gain (Bit 4-0) */
+ pac207_write_reg(gspca_dev, 0x0e, sd->gain);
+ pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */
+
+ mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
+ if (gspca_dev->width == 176) { /* 176x144 */
+ mode |= 0x01;
+ PDEBUG(D_STREAM, "pac207_start mode 176x144");
+ } else { /* 352x288 */
+ PDEBUG(D_STREAM, "pac207_start mode 352x288");
+ }
+ pac207_write_reg(gspca_dev, 0x41, mode);
+
+ pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
+ pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
+ msleep(10);
+ pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */
+
+ sd->sof_read = 0;
+ sd->autogain_ignore_frames = 0;
+ atomic_set(&sd->avg_lum, -1);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
+ pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
+ pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int avg_lum = atomic_read(&sd->avg_lum);
+
+ if (avg_lum == -1)
+ return;
+
+ if (sd->autogain_ignore_frames > 0)
+ sd->autogain_ignore_frames--;
+ else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
+ 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
+ PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
+ sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES;
+}
+
+static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
+ unsigned char *m, int len)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+
+ /* Search for the SOF marker (fixed part) in the header */
+ for (i = 0; i < len; i++) {
+ if (m[i] == pac207_sof_marker[sd->sof_read]) {
+ sd->sof_read++;
+ if (sd->sof_read == sizeof(pac207_sof_marker)) {
+ PDEBUG(D_STREAM,
+ "SOF found, bytes to analyze: %u."
+ " Frame starts at byte #%u",
+ len, i + 1);
+ sd->sof_read = 0;
+ return m + i + 1;
+ }
+ } else {
+ sd->sof_read = 0;
+ }
+ }
+
+ return NULL;
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame,
+ __u8 *data,
+ int len)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned char *sof;
+
+ sof = pac207_find_sof(gspca_dev, data, len);
+ if (sof) {
+ int n;
+
+ /* finish decoding current frame */
+ n = sof - data;
+ if (n > sizeof pac207_sof_marker)
+ n -= sizeof pac207_sof_marker;
+ else
+ n = 0;
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, n);
+ sd->header_read = 0;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
+ len -= sof - data;
+ data = sof;
+ }
+ if (sd->header_read < 11) {
+ int needed;
+
+ /* get average lumination from frame header (byte 5) */
+ if (sd->header_read < 5) {
+ needed = 5 - sd->header_read;
+ if (len >= needed)
+ atomic_set(&sd->avg_lum, data[needed - 1]);
+ }
+ /* skip the rest of the header */
+ needed = 11 - sd->header_read;
+ if (len <= needed) {
+ sd->header_read += len;
+ return;
+ }
+ data += needed;
+ len -= needed;
+ sd->header_read = 11;
+ }
+
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ pac207_write_reg(gspca_dev, 0x08, sd->brightness);
+ pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
+ pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
+}
+
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ pac207_write_reg(gspca_dev, 0x02, sd->exposure);
+ pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
+ pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
+}
+
+static void setgain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ pac207_write_reg(gspca_dev, 0x0e, sd->gain);
+ pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
+ pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->exposure = val;
+ if (gspca_dev->streaming)
+ setexposure(gspca_dev);
+ return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->exposure;
+ return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gain = val;
+ if (gspca_dev->streaming)
+ setgain(gspca_dev);
+ return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gain;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ /* when switching to autogain set defaults to make sure
+ we are on a valid point of the autogain gain /
+ exposure knee graph, and give this change time to
+ take effect before doing autogain. */
+ if (sd->autogain) {
+ sd->exposure = PAC207_EXPOSURE_DEFAULT;
+ sd->gain = PAC207_GAIN_DEFAULT;
+ if (gspca_dev->streaming) {
+ sd->autogain_ignore_frames =
+ PAC207_AUTOGAIN_IGNORE_FRAMES;
+ setexposure(gspca_dev);
+ setgain(gspca_dev);
+ }
+ }
+
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .dq_callback = pac207_do_auto_gain,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")},
+ {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")},
+ {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")},
+ {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")},
+ {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")},
+ {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")},
+ {USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")},
+ {USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")},
+ {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
new file mode 100644
index 00000000000..5c052e31be4
--- /dev/null
+++ b/drivers/media/video/gspca/pac7311.c
@@ -0,0 +1,760 @@
+/*
+ * Pixart PAC7311 library
+ * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "pac7311"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
+MODULE_DESCRIPTION("Pixart PAC7311");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ int avg_lum;
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char autogain;
+
+ char ffseq;
+ signed char ag_cnt;
+#define AG_CNT_START 13
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+#define BRIGHTNESS_MAX 0x20
+ .maximum = BRIGHTNESS_MAX,
+ .step = 1,
+#define BRIGHTNESS_DEF 0x10
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define CONTRAST_DEF 127
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define COLOR_DEF 127
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define AUTOGAIN_DEF 1
+ .default_value = AUTOGAIN_DEF,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+#define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */
+
+static const __u8 pac7311_jpeg_header[] = {
+ 0xff, 0xd8,
+ 0xff, 0xe0, 0x00, 0x03, 0x20,
+ 0xff, 0xc0, 0x00, 0x11, 0x08,
+ 0x01, 0xe0, /* 12: height */
+ 0x02, 0x80, /* 14: width */
+ 0x03, /* 16 */
+ 0x01, 0x21, 0x00,
+ 0x02, 0x11, 0x01,
+ 0x03, 0x11, 0x01,
+ 0xff, 0xdb, 0x00, 0x84,
+ 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d,
+ 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16,
+ 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d,
+ 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40,
+ 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f,
+ 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64,
+ 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18,
+ 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
+ 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31,
+ 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32,
+ 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52,
+ 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
+ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
+ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+ 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+ 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
+ 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01,
+ 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
+ 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14,
+ 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
+ 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
+ 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
+ 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
+ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+ 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
+ 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03,
+ 0x11, 0x00, 0x3f, 0x00
+};
+
+static void reg_w_buf(struct gspca_dev *gspca_dev,
+ __u16 index,
+ const char *buffer, __u16 len)
+{
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 1, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, len,
+ 500);
+}
+
+static __u8 reg_r(struct gspca_dev *gspca_dev,
+ __u16 index)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, 1,
+ 500);
+ return gspca_dev->usb_buf[0];
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ __u16 index,
+ __u8 value)
+{
+ gspca_dev->usb_buf[0] = value;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, gspca_dev->usb_buf, 1,
+ 500);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ PDEBUG(D_CONF, "Find Sensor PAC7311");
+ reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x27, 0x80);
+ reg_w(gspca_dev, 0x28, 0xca);
+ reg_w(gspca_dev, 0x29, 0x53);
+ reg_w(gspca_dev, 0x2a, 0x0e);
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x3e, 0x20);
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x05;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLOR_DEF;
+ sd->autogain = AUTOGAIN_DEF;
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int brightness;
+
+/*jfm: inverted?*/
+ brightness = BRIGHTNESS_MAX - sd->brightness;
+ reg_w(gspca_dev, 0xff, 0x04);
+/* reg_w(gspca_dev, 0x0e, 0x00); */
+ reg_w(gspca_dev, 0x0f, brightness);
+ /* load registers to sensor (Bit 0, auto clear) */
+ reg_w(gspca_dev, 0x11, 0x01);
+ PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x80, sd->contrast);
+ /* load registers to sensor (Bit 0, auto clear) */
+ reg_w(gspca_dev, 0x11, 0x01);
+ PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x10, sd->colors);
+ /* load registers to sensor (Bit 0, auto clear) */
+ reg_w(gspca_dev, 0x11, 0x01);
+ PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8);
+ reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8);
+ reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8);
+ reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8);
+ reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8);
+ reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3);
+ reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8);
+ reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8);
+ reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8);
+ reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8);
+ reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8);
+ reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2);
+ reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6);
+ reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8);
+ reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8);
+ reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2);
+ reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3);
+ reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4);
+ reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8);
+ reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5);
+
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x02, 0x04);
+ reg_w(gspca_dev, 0x03, 0x54);
+ reg_w(gspca_dev, 0x04, 0x07);
+ reg_w(gspca_dev, 0x05, 0x2b);
+ reg_w(gspca_dev, 0x06, 0x09);
+ reg_w(gspca_dev, 0x07, 0x0f);
+ reg_w(gspca_dev, 0x08, 0x09);
+ reg_w(gspca_dev, 0x09, 0x00);
+ reg_w(gspca_dev, 0x0c, 0x07);
+ reg_w(gspca_dev, 0x0d, 0x00);
+ reg_w(gspca_dev, 0x0e, 0x00);
+ reg_w(gspca_dev, 0x0f, 0x62);
+ reg_w(gspca_dev, 0x10, 0x08);
+ reg_w(gspca_dev, 0x12, 0x07);
+ reg_w(gspca_dev, 0x13, 0x00);
+ reg_w(gspca_dev, 0x14, 0x00);
+ reg_w(gspca_dev, 0x15, 0x00);
+ reg_w(gspca_dev, 0x16, 0x00);
+ reg_w(gspca_dev, 0x17, 0x00);
+ reg_w(gspca_dev, 0x18, 0x00);
+ reg_w(gspca_dev, 0x19, 0x00);
+ reg_w(gspca_dev, 0x1a, 0x00);
+ reg_w(gspca_dev, 0x1b, 0x03);
+ reg_w(gspca_dev, 0x1c, 0xa0);
+ reg_w(gspca_dev, 0x1d, 0x01);
+ reg_w(gspca_dev, 0x1e, 0xf4);
+ reg_w(gspca_dev, 0x21, 0x00);
+ reg_w(gspca_dev, 0x22, 0x08);
+ reg_w(gspca_dev, 0x24, 0x03);
+ reg_w(gspca_dev, 0x26, 0x00);
+ reg_w(gspca_dev, 0x27, 0x01);
+ reg_w(gspca_dev, 0x28, 0xca);
+ reg_w(gspca_dev, 0x29, 0x10);
+ reg_w(gspca_dev, 0x2a, 0x06);
+ reg_w(gspca_dev, 0x2b, 0x78);
+ reg_w(gspca_dev, 0x2c, 0x00);
+ reg_w(gspca_dev, 0x2d, 0x00);
+ reg_w(gspca_dev, 0x2e, 0x00);
+ reg_w(gspca_dev, 0x2f, 0x00);
+ reg_w(gspca_dev, 0x30, 0x23);
+ reg_w(gspca_dev, 0x31, 0x28);
+ reg_w(gspca_dev, 0x32, 0x04);
+ reg_w(gspca_dev, 0x33, 0x11);
+ reg_w(gspca_dev, 0x34, 0x00);
+ reg_w(gspca_dev, 0x35, 0x00);
+ reg_w(gspca_dev, 0x11, 0x01);
+ setcontrast(gspca_dev);
+ setbrightness(gspca_dev);
+ setcolors(gspca_dev);
+
+ /* set correct resolution */
+ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ case 2: /* 160x120 */
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x02, 0x03);
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x08, 0x09);
+ reg_w(gspca_dev, 0x17, 0x20);
+ reg_w(gspca_dev, 0x1b, 0x00);
+/* reg_w(gspca_dev, 0x80, 0x69); */
+ reg_w(gspca_dev, 0x87, 0x10);
+ break;
+ case 1: /* 320x240 */
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x02, 0x03);
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x08, 0x09);
+ reg_w(gspca_dev, 0x17, 0x30);
+/* reg_w(gspca_dev, 0x80, 0x3f); */
+ reg_w(gspca_dev, 0x87, 0x11);
+ break;
+ case 0: /* 640x480 */
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x02, 0x03);
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x08, 0x08);
+ reg_w(gspca_dev, 0x17, 0x00);
+/* reg_w(gspca_dev, 0x80, 0x1c); */
+ reg_w(gspca_dev, 0x87, 0x12);
+ break;
+ }
+
+ /* start stream */
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x78, 0x04);
+ reg_w(gspca_dev, 0x78, 0x05);
+
+ if (sd->autogain) {
+ sd->ag_cnt = AG_CNT_START;
+ sd->avg_lum = 0;
+ } else {
+ sd->ag_cnt = -1;
+ }
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x27, 0x80);
+ reg_w(gspca_dev, 0x28, 0xca);
+ reg_w(gspca_dev, 0x29, 0x53);
+ reg_w(gspca_dev, 0x2a, 0x0e);
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x3e, 0x20);
+ reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x27, 0x80);
+ reg_w(gspca_dev, 0x28, 0xca);
+ reg_w(gspca_dev, 0x29, 0x53);
+ reg_w(gspca_dev, 0x2a, 0x0e);
+ reg_w(gspca_dev, 0xff, 0x01);
+ reg_w(gspca_dev, 0x3e, 0x20);
+ reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
+ reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */
+}
+
+static void setautogain(struct gspca_dev *gspca_dev, int luma)
+{
+ int luma_mean = 128;
+ int luma_delta = 20;
+ __u8 spring = 5;
+ int Gbright;
+
+ Gbright = reg_r(gspca_dev, 0x02);
+ PDEBUG(D_FRAM, "luma mean %d", luma);
+ if (luma < luma_mean - luma_delta ||
+ luma > luma_mean + luma_delta) {
+ Gbright += (luma_mean - luma) >> spring;
+ if (Gbright > 0x1a)
+ Gbright = 0x1a;
+ else if (Gbright < 4)
+ Gbright = 4;
+ PDEBUG(D_FRAM, "gbright %d", Gbright);
+ reg_w(gspca_dev, 0xff, 0x04);
+ reg_w(gspca_dev, 0x0f, Gbright);
+ /* load registers to sensor (Bit 0, auto clear) */
+ reg_w(gspca_dev, 0x11, 0x01);
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned char tmpbuf[4];
+ int i, p, ffseq;
+
+/* if (len < 5) { */
+ if (len < 6) {
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+
+ ffseq = sd->ffseq;
+
+ for (p = 0; p < len - 6; p++) {
+ if ((data[0 + p] == 0xff)
+ && (data[1 + p] == 0xff)
+ && (data[2 + p] == 0x00)
+ && (data[3 + p] == 0xff)
+ && (data[4 + p] == 0x96)) {
+
+ /* start of frame */
+ if (sd->ag_cnt >= 0 && p > 28) {
+ sd->avg_lum += data[p - 23];
+ if (--sd->ag_cnt < 0) {
+ sd->ag_cnt = AG_CNT_START;
+ setautogain(gspca_dev,
+ sd->avg_lum / AG_CNT_START);
+ sd->avg_lum = 0;
+ }
+ }
+
+ /* copy the end of data to the current frame */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, p);
+
+ /* put the JPEG header in the new frame */
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ (unsigned char *) pac7311_jpeg_header,
+ 12);
+ tmpbuf[0] = gspca_dev->height >> 8;
+ tmpbuf[1] = gspca_dev->height & 0xff;
+ tmpbuf[2] = gspca_dev->width >> 8;
+ tmpbuf[3] = gspca_dev->width & 0xff;
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ tmpbuf, 4);
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ (unsigned char *) &pac7311_jpeg_header[16],
+ PAC7311_JPEG_HEADER_SIZE - 16);
+
+ data += p + 7;
+ len -= p + 7;
+ ffseq = 0;
+ break;
+ }
+ }
+
+ /* remove the 'ff ff ff xx' sequences */
+ switch (ffseq) {
+ case 3:
+ data += 1;
+ len -= 1;
+ break;
+ case 2:
+ if (data[0] == 0xff) {
+ data += 2;
+ len -= 2;
+ frame->data_end -= 2;
+ }
+ break;
+ case 1:
+ if (data[0] == 0xff
+ && data[1] == 0xff) {
+ data += 3;
+ len -= 3;
+ frame->data_end -= 1;
+ }
+ break;
+ }
+ for (i = 0; i < len - 4; i++) {
+ if (data[i] == 0xff
+ && data[i + 1] == 0xff
+ && data[i + 2] == 0xff) {
+ memmove(&data[i], &data[i + 4], len - i - 4);
+ len -= 4;
+ }
+ }
+ ffseq = 0;
+ if (data[len - 4] == 0xff) {
+ if (data[len - 3] == 0xff
+ && data[len - 2] == 0xff) {
+ len -= 4;
+ }
+ } else if (data[len - 3] == 0xff) {
+ if (data[len - 2] == 0xff
+ && data[len - 1] == 0xff)
+ ffseq = 3;
+ } else if (data[len - 2] == 0xff) {
+ if (data[len - 1] == 0xff)
+ ffseq = 2;
+ } else if (data[len - 1] == 0xff)
+ ffseq = 1;
+ sd->ffseq = ffseq;
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+/* sd->brightness = reg_r(gspca_dev, 0x08);
+ return sd->brightness; */
+/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */
+}
+
+
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+/* getcontrast(gspca_dev); */
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+/* getcolors(gspca_dev); */
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (val) {
+ sd->ag_cnt = AG_CNT_START;
+ sd->avg_lum = 0;
+ } else {
+ sd->ag_cnt = -1;
+ }
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+/* sub-driver description */
+static struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")},
+ {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")},
+ {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")},
+ {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")},
+ {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")},
+ /* and also ', Trust WB-3350p, SIGMA cam 2350' */
+ {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")},
+ {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
new file mode 100644
index 00000000000..dbeebe8625c
--- /dev/null
+++ b/drivers/media/video/gspca/sonixb.c
@@ -0,0 +1,1477 @@
+/*
+ * sonix sn9c102 (bayer) library
+ * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
+ * Add Pas106 Stefano Mozzi (C) 2004
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "sonixb"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8)
+static const char version[] = "2.1.8";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ struct sd_desc sd_desc; /* our nctrls differ dependend upon the
+ sensor, so we use a per cam copy */
+ atomic_t avg_lum;
+
+ unsigned char gain;
+ unsigned char exposure;
+ unsigned char brightness;
+ unsigned char autogain;
+ unsigned char autogain_ignore_frames;
+ unsigned char freq; /* light freq filter setting */
+ unsigned char saturation;
+ unsigned char hue;
+ unsigned char contrast;
+
+ unsigned char fr_h_sz; /* size of frame header */
+ char sensor; /* Type of image sensor chip */
+#define SENSOR_HV7131R 0
+#define SENSOR_OV6650 1
+#define SENSOR_OV7630 2
+#define SENSOR_OV7630_3 3
+#define SENSOR_PAS106 4
+#define SENSOR_PAS202 5
+#define SENSOR_TAS5110 6
+#define SENSOR_TAS5130CXX 7
+ char sensor_has_gain;
+ __u8 sensor_addr;
+};
+
+#define COMP2 0x8f
+#define COMP 0xc7 /* 0x87 //0x07 */
+#define COMP1 0xc9 /* 0x89 //0x09 */
+
+#define MCK_INIT 0x63
+#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
+
+#define SYS_CLK 0x04
+
+/* We calculate the autogain at the end of the transfer of a frame, at this
+ moment a frame with the old settings is being transmitted, and a frame is
+ being captured with the old settings. So if we adjust the autogain we must
+ ignore atleast the 2 next frames for the new settings to come into effect
+ before doing any other adjustments */
+#define AUTOGAIN_IGNORE_FRAMES 3
+#define AUTOGAIN_DEADZONE 1000
+#define DESIRED_AVG_LUM 7000
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define GAIN_DEF 127
+#define GAIN_KNEE 200
+ .default_value = GAIN_DEF,
+ },
+ .set = sd_setgain,
+ .get = sd_getgain,
+ },
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
+#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = EXPOSURE_DEF,
+ .flags = 0,
+ },
+ .set = sd_setexposure,
+ .get = sd_getexposure,
+ },
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Automatic Gain (and Exposure)",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define AUTOGAIN_DEF 1
+ .default_value = AUTOGAIN_DEF,
+ .flags = 0,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+ {
+ {
+ .id = V4L2_CID_POWER_LINE_FREQUENCY,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "Light frequency filter",
+ .minimum = 0,
+ .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
+ .step = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
+ },
+ .set = sd_setfreq,
+ .get = sd_getfreq,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define SATURATION_DEF 127
+ .default_value = SATURATION_DEF,
+ },
+ .set = sd_setsaturation,
+ .get = sd_getsaturation,
+ },
+ {
+ {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define HUE_DEF 127
+ .default_value = HUE_DEF,
+ },
+ .set = sd_sethue,
+ .get = sd_gethue,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define CONTRAST_DEF 127
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+static const __u8 probe_ov7630[] = {0x08, 0x44};
+
+static const __u8 initHv7131[] = {
+ 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */
+ 0x28, 0x1e, 0x60, 0x8a, 0x20,
+ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
+};
+static const __u8 hv7131_sensor_init[][8] = {
+ {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
+ {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
+ {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
+ {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
+ {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
+};
+static const __u8 initOv6650[] = {
+ 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
+ 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
+};
+static const __u8 ov6650_sensor_init[][8] =
+{
+ /* Bright, contrast, etc are set througth SCBB interface.
+ * AVCAP on win2 do not send any data on this controls. */
+ /* Anyway, some registers appears to alter bright and constrat */
+
+ /* Reset sensor */
+ {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
+ /* Set clock register 0x11 low nibble is clock divider */
+ {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
+ /* Next some unknown stuff */
+ {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
+/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
+ * THIS SET GREEN SCREEN
+ * (pixels could be innverted in decode kind of "brg",
+ * but blue wont be there. Avoid this data ... */
+ {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
+ {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
+ {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
+ /* Enable rgb brightness control */
+ {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
+ /* HDG: Note windows uses the line below, which sets both register 0x60
+ and 0x61 I believe these registers of the ov6650 are identical as
+ those of the ov7630, because if this is true the windows settings
+ add a bit additional red gain and a lot additional blue gain, which
+ matches my findings that the windows settings make blue much too
+ blue and red a little too red.
+ {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
+ /* Some more unknown stuff */
+ {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
+ {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
+};
+
+static const __u8 initOv7630[] = {
+ 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
+ 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
+ 0x28, 0x1e, /* H & V sizes r15 .. r16 */
+ 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */
+ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
+};
+static const __u8 initOv7630_3[] = {
+ 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
+ 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
+ 0x28, 0x1e, /* H & V sizes r15 .. r16 */
+ 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
+ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
+ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
+ 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
+};
+static const __u8 ov7630_sensor_init_com[][8] = {
+ {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
+/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
+ {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
+ {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
+ {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
+ {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
+ {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
+ {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
+ {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
+ {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
+ {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
+/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
+ {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
+ {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
+ {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
+ {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
+ {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
+ {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
+};
+static const __u8 ov7630_sensor_init[][8] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
+ {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */
+ {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
+ {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
+ {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */
+};
+static const __u8 ov7630_sensor_init_3[][8] = {
+ {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10},
+ {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10},
+};
+
+static const __u8 initPas106[] = {
+ 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
+ 0x16, 0x12, 0x28, COMP1, MCK_INIT1,
+ 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
+};
+/* compression 0x86 mckinit1 0x2b */
+static const __u8 pas106_data[][2] = {
+ {0x02, 0x04}, /* Pixel Clock Divider 6 */
+ {0x03, 0x13}, /* Frame Time MSB */
+/* {0x03, 0x12}, * Frame Time MSB */
+ {0x04, 0x06}, /* Frame Time LSB */
+/* {0x04, 0x05}, * Frame Time LSB */
+ {0x05, 0x65}, /* Shutter Time Line Offset */
+/* {0x05, 0x6d}, * Shutter Time Line Offset */
+/* {0x06, 0xb1}, * Shutter Time Pixel Offset */
+ {0x06, 0xcd}, /* Shutter Time Pixel Offset */
+ {0x07, 0xc1}, /* Black Level Subtract Sign */
+/* {0x07, 0x00}, * Black Level Subtract Sign */
+ {0x08, 0x06}, /* Black Level Subtract Level */
+ {0x08, 0x06}, /* Black Level Subtract Level */
+/* {0x08, 0x01}, * Black Level Subtract Level */
+ {0x09, 0x05}, /* Color Gain B Pixel 5 a */
+ {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */
+ {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */
+ {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */
+ {0x0d, 0x00}, /* Color GainH Pixel */
+ {0x0e, 0x0e}, /* Global Gain */
+ {0x0f, 0x00}, /* Contrast */
+ {0x10, 0x06}, /* H&V synchro polarity */
+ {0x11, 0x06}, /* ?default */
+ {0x12, 0x06}, /* DAC scale */
+ {0x14, 0x02}, /* ?default */
+ {0x13, 0x01}, /* Validate Settings */
+};
+static const __u8 initPas202[] = {
+ 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */
+ 0x28, 0x1e, 0x28, 0x89, 0x30,
+ 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
+};
+static const __u8 pas202_sensor_init[][8] = {
+ {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
+ {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
+ {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
+ {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
+ {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
+ {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
+ {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
+ {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
+ {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
+ {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
+ {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
+
+ {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
+ {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
+ {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
+ {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
+ {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
+ {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
+ {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
+ {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
+};
+
+static const __u8 initTas5110[] = {
+ 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */
+ 0x16, 0x12, 0x60, 0x86, 0x2b,
+ 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
+};
+static const __u8 tas5110_sensor_init[][8] = {
+ {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
+ {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
+ {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
+};
+
+static const __u8 initTas5130[] = {
+ 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
+ 0x28, 0x1e, 0x60, COMP, MCK_INIT,
+ 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
+};
+static const __u8 tas5130_sensor_init[][8] = {
+/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
+ * shutter 0x47 short exposure? */
+ {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
+ /* shutter 0x01 long exposure */
+ {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
+};
+
+/* get one byte in gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 value)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value,
+ 0, /* index */
+ gspca_dev->usb_buf, 1,
+ 500);
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ __u16 value,
+ const __u8 *buffer,
+ int len)
+{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (len > sizeof gspca_dev->usb_buf) {
+ PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
+ return;
+ }
+#endif
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value,
+ 0, /* index */
+ gspca_dev->usb_buf, len,
+ 500);
+}
+
+static void reg_w_big(struct gspca_dev *gspca_dev,
+ __u16 value,
+ const __u8 *buffer,
+ int len)
+{
+ __u8 *tmpbuf;
+
+ tmpbuf = kmalloc(len, GFP_KERNEL);
+ memcpy(tmpbuf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value,
+ 0, /* index */
+ tmpbuf, len,
+ 500);
+ kfree(tmpbuf);
+}
+
+static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
+{
+ int retry = 60;
+
+ /* is i2c ready */
+ reg_w(gspca_dev, 0x08, buffer, 8);
+ while (retry--) {
+ msleep(10);
+ reg_r(gspca_dev, 0x08);
+ if (gspca_dev->usb_buf[0] & 0x04) {
+ if (gspca_dev->usb_buf[0] & 0x08)
+ return -1;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static void i2c_w_vector(struct gspca_dev *gspca_dev,
+ const __u8 buffer[][8], int len)
+{
+ for (;;) {
+ reg_w(gspca_dev, 0x08, *buffer, 8);
+ len -= 8;
+ if (len <= 0)
+ break;
+ buffer++;
+ }
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 value;
+
+ switch (sd->sensor) {
+ case SENSOR_OV6650:
+ case SENSOR_OV7630_3:
+ case SENSOR_OV7630: {
+ __u8 i2cOV[] =
+ {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
+
+ /* change reg 0x06 */
+ i2cOV[1] = sd->sensor_addr;
+ i2cOV[3] = sd->brightness;
+ if (i2c_w(gspca_dev, i2cOV) < 0)
+ goto err;
+ break;
+ }
+ case SENSOR_PAS106: {
+ __u8 i2c1[] =
+ {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
+
+ i2c1[3] = sd->brightness >> 3;
+ i2c1[2] = 0x0e;
+ if (i2c_w(gspca_dev, i2c1) < 0)
+ goto err;
+ i2c1[3] = 0x01;
+ i2c1[2] = 0x13;
+ if (i2c_w(gspca_dev, i2c1) < 0)
+ goto err;
+ break;
+ }
+ case SENSOR_PAS202: {
+ /* __u8 i2cpexpo1[] =
+ {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
+ __u8 i2cpexpo[] =
+ {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
+ __u8 i2cp202[] =
+ {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
+ static __u8 i2cpdoit[] =
+ {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
+
+ /* change reg 0x10 */
+ i2cpexpo[4] = 0xff - sd->brightness;
+/* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
+ goto err; */
+/* if(i2c_w(gspca_dev,i2cpdoit) < 0)
+ goto err; */
+ if (i2c_w(gspca_dev, i2cpexpo) < 0)
+ goto err;
+ if (i2c_w(gspca_dev, i2cpdoit) < 0)
+ goto err;
+ i2cp202[3] = sd->brightness >> 3;
+ if (i2c_w(gspca_dev, i2cp202) < 0)
+ goto err;
+ if (i2c_w(gspca_dev, i2cpdoit) < 0)
+ goto err;
+ break;
+ }
+ case SENSOR_TAS5130CXX: {
+ __u8 i2c[] =
+ {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
+
+ value = 0xff - sd->brightness;
+ i2c[4] = value;
+ PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
+ if (i2c_w(gspca_dev, i2c) < 0)
+ goto err;
+ break;
+ }
+ case SENSOR_TAS5110:
+ /* FIXME figure out howto control brightness on TAS5110 */
+ break;
+ }
+ return;
+err:
+ PDEBUG(D_ERR, "i2c error brightness");
+}
+
+static void setsensorgain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned char gain = sd->gain;
+
+ switch (sd->sensor) {
+
+ case SENSOR_TAS5110: {
+ __u8 i2c[] =
+ {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
+
+ i2c[4] = 255 - gain;
+ if (i2c_w(gspca_dev, i2c) < 0)
+ goto err;
+ break;
+ }
+
+ case SENSOR_OV6650:
+ gain >>= 1;
+ /* fall thru */
+ case SENSOR_OV7630_3: {
+ __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
+
+ i2c[1] = sd->sensor_addr;
+ i2c[3] = gain >> 2;
+ if (i2c_w(gspca_dev, i2c) < 0)
+ goto err;
+ break;
+ }
+ }
+ return;
+err:
+ PDEBUG(D_ERR, "i2c error gain");
+}
+
+static void setgain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 gain;
+ __u8 rgb_value;
+
+ gain = sd->gain >> 4;
+
+ /* red and blue gain */
+ rgb_value = gain << 4 | gain;
+ reg_w(gspca_dev, 0x10, &rgb_value, 1);
+ /* green gain */
+ rgb_value = gain;
+ reg_w(gspca_dev, 0x11, &rgb_value, 1);
+
+ if (sd->sensor_has_gain)
+ setsensorgain(gspca_dev);
+}
+
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+ case SENSOR_TAS5110: {
+ __u8 reg;
+
+ /* register 19's high nibble contains the sn9c10x clock divider
+ The high nibble configures the no fps according to the
+ formula: 60 / high_nibble. With a maximum of 30 fps */
+ reg = 120 * sd->exposure / 1000;
+ if (reg < 2)
+ reg = 2;
+ else if (reg > 15)
+ reg = 15;
+ reg = (reg << 4) | 0x0b;
+ reg_w(gspca_dev, 0x19, &reg, 1);
+ break;
+ }
+ case SENSOR_OV6650:
+ case SENSOR_OV7630_3: {
+ /* The ov6650 / ov7630 have 2 registers which both influence
+ exposure, register 11, whose low nibble sets the nr off fps
+ according to: fps = 30 / (low_nibble + 1)
+
+ The fps configures the maximum exposure setting, but it is
+ possible to use less exposure then what the fps maximum
+ allows by setting register 10. register 10 configures the
+ actual exposure as quotient of the full exposure, with 0
+ being no exposure at all (not very usefull) and reg10_max
+ being max exposure possible at that framerate.
+
+ The code maps our 0 - 510 ms exposure ctrl to these 2
+ registers, trying to keep fps as high as possible.
+ */
+ __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10};
+ int reg10, reg11;
+ /* ov6645 datasheet says reg10_max is 9a, but that uses
+ tline * 2 * reg10 as formula for calculating texpo, the
+ ov6650 probably uses the same formula as the 7730 which uses
+ tline * 4 * reg10, which explains why the reg10max we've
+ found experimentally for the ov6650 is exactly half that of
+ the ov6645. The ov7630 datasheet says the max is 0x41. */
+ const int reg10_max = (sd->sensor == SENSOR_OV6650)
+ ? 0x4d : 0x41;
+
+ reg11 = (60 * sd->exposure + 999) / 1000;
+ if (reg11 < 1)
+ reg11 = 1;
+ else if (reg11 > 16)
+ reg11 = 16;
+
+ /* frame exposure time in ms = 1000 * reg11 / 30 ->
+ reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
+ reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
+
+ /* Don't allow this to get below 10 when using autogain, the
+ steps become very large (relatively) when below 10 causing
+ the image to oscilate from much too dark, to much too bright
+ and back again. */
+ if (sd->autogain && reg10 < 10)
+ reg10 = 10;
+ else if (reg10 > reg10_max)
+ reg10 = reg10_max;
+
+ /* Write reg 10 and reg11 low nibble */
+ i2c[1] = sd->sensor_addr;
+ i2c[3] = reg10;
+ i2c[4] |= reg11 - 1;
+ if (sd->sensor == SENSOR_OV7630_3) {
+ __u8 reg76 = reg10 & 0x03;
+ __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x10};
+ reg10 >>= 2;
+ i2c_reg76[3] = reg76;
+ if (i2c_w(gspca_dev, i2c_reg76) < 0)
+ PDEBUG(D_ERR, "i2c error exposure");
+ }
+ if (i2c_w(gspca_dev, i2c) < 0)
+ PDEBUG(D_ERR, "i2c error exposure");
+ break;
+ }
+ }
+}
+
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+ case SENSOR_OV6650:
+ case SENSOR_OV7630_3: {
+ /* Framerate adjust register for artificial light 50 hz flicker
+ compensation, identical to ov6630 0x2b register, see ov6630
+ datasheet.
+ 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */
+ __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
+ switch (sd->freq) {
+ default:
+/* case 0: * no filter*/
+/* case 2: * 60 hz */
+ i2c[3] = 0;
+ break;
+ case 1: /* 50 hz */
+ i2c[3] = (sd->sensor == SENSOR_OV6650)
+ ? 0x4f : 0x8a;
+ break;
+ }
+ i2c[1] = sd->sensor_addr;
+ if (i2c_w(gspca_dev, i2c) < 0)
+ PDEBUG(D_ERR, "i2c error setfreq");
+ break;
+ }
+ }
+}
+
+static void setsaturation(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+/* case SENSOR_OV6650: */
+ case SENSOR_OV7630_3:
+ case SENSOR_OV7630: {
+ __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10};
+ i2c[1] = sd->sensor_addr;
+ i2c[3] = sd->saturation & 0xf0;
+ if (i2c_w(gspca_dev, i2c) < 0)
+ PDEBUG(D_ERR, "i2c error setsaturation");
+ else
+ PDEBUG(D_CONF, "saturation set to: %d",
+ (int)sd->saturation);
+ break;
+ }
+ }
+}
+
+static void sethue(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+/* case SENSOR_OV6650: */
+ case SENSOR_OV7630_3:
+ case SENSOR_OV7630: {
+ __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10};
+ i2c[1] = sd->sensor_addr;
+ i2c[3] = 0x20 | (sd->hue >> 3);
+ if (i2c_w(gspca_dev, i2c) < 0)
+ PDEBUG(D_ERR, "i2c error setsaturation");
+ else
+ PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue);
+ break;
+ }
+ }
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+/* case SENSOR_OV6650: */
+ case SENSOR_OV7630_3:
+ case SENSOR_OV7630: {
+ __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10};
+ i2c[1] = sd->sensor_addr;
+ i2c[3] = 0x20 | (sd->contrast >> 3);
+ if (i2c_w(gspca_dev, i2c) < 0)
+ PDEBUG(D_ERR, "i2c error setcontrast");
+ else
+ PDEBUG(D_CONF, "contrast set to: %d",
+ (int)sd->contrast);
+ break;
+ }
+ }
+}
+
+
+static void do_autogain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int avg_lum = atomic_read(&sd->avg_lum);
+
+ if (avg_lum == -1)
+ return;
+
+ if (sd->autogain_ignore_frames > 0)
+ sd->autogain_ignore_frames--;
+ else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
+ sd->brightness * DESIRED_AVG_LUM / 127,
+ AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
+ PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
+ (int)sd->gain, (int)sd->exposure);
+ sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
+ }
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 product;
+ int sif = 0;
+
+ /* nctrls depends upon the sensor, so we use a per cam copy */
+ memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
+ gspca_dev->sd_desc = &sd->sd_desc;
+
+ sd->fr_h_sz = 12; /* default size of the frame header */
+ sd->sd_desc.nctrls = 2; /* default nb of ctrls */
+ sd->autogain = AUTOGAIN_DEF; /* default is autogain active */
+
+ product = id->idProduct;
+/* switch (id->idVendor) { */
+/* case 0x0c45: * Sonix */
+ switch (product) {
+ case 0x6001: /* SN9C102 */
+ case 0x6005: /* SN9C101 */
+ case 0x6007: /* SN9C101 */
+ sd->sensor = SENSOR_TAS5110;
+ sd->sensor_has_gain = 1;
+ sd->sd_desc.nctrls = 4;
+ sd->sd_desc.dq_callback = do_autogain;
+ sif = 1;
+ break;
+ case 0x6009: /* SN9C101 */
+ case 0x600d: /* SN9C101 */
+ case 0x6029: /* SN9C101 */
+ sd->sensor = SENSOR_PAS106;
+ sif = 1;
+ break;
+ case 0x6011: /* SN9C101 - SN9C101G */
+ sd->sensor = SENSOR_OV6650;
+ sd->sensor_has_gain = 1;
+ sd->sensor_addr = 0x60;
+ sd->sd_desc.nctrls = 5;
+ sd->sd_desc.dq_callback = do_autogain;
+ sif = 1;
+ break;
+ case 0x6019: /* SN9C101 */
+ case 0x602c: /* SN9C102 */
+ case 0x602e: /* SN9C102 */
+ sd->sensor = SENSOR_OV7630;
+ sd->sensor_addr = 0x21;
+ break;
+ case 0x60b0: /* SN9C103 */
+ sd->sensor = SENSOR_OV7630_3;
+ sd->sensor_addr = 0x21;
+ sd->fr_h_sz = 18; /* size of frame header */
+ sd->sensor_has_gain = 1;
+ sd->sd_desc.nctrls = 8;
+ sd->sd_desc.dq_callback = do_autogain;
+ sd->autogain = 0;
+ break;
+ case 0x6024: /* SN9C102 */
+ case 0x6025: /* SN9C102 */
+ sd->sensor = SENSOR_TAS5130CXX;
+ break;
+ case 0x6028: /* SN9C102 */
+ sd->sensor = SENSOR_PAS202;
+ break;
+ case 0x602d: /* SN9C102 */
+ sd->sensor = SENSOR_HV7131R;
+ break;
+ case 0x60af: /* SN9C103 */
+ sd->sensor = SENSOR_PAS202;
+ sd->fr_h_sz = 18; /* size of frame header (?) */
+ break;
+ }
+/* break; */
+/* } */
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ if (!sif) {
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+ if (sd->sensor == SENSOR_OV7630_3) {
+ /* We only have 320x240 & 640x480 */
+ cam->cam_mode++;
+ cam->nmodes--;
+ }
+ } else {
+ cam->cam_mode = sif_mode;
+ cam->nmodes = ARRAY_SIZE(sif_mode);
+ }
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->gain = GAIN_DEF;
+ sd->exposure = EXPOSURE_DEF;
+ sd->freq = FREQ_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->saturation = SATURATION_DEF;
+ sd->hue = HUE_DEF;
+ if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */
+ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630);
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ reg_r(gspca_dev, 0x00);
+ if (gspca_dev->usb_buf[0] != 0x10)
+ return -ENODEV;
+ return 0;
+}
+
+static void pas106_i2cinit(struct gspca_dev *gspca_dev)
+{
+ int i;
+ const __u8 *data;
+ __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
+
+ i = ARRAY_SIZE(pas106_data);
+ data = pas106_data[0];
+ while (--i >= 0) {
+ memcpy(&i2c1[2], data, 2);
+ /* copy 2 bytes from the template */
+ if (i2c_w(gspca_dev, i2c1) < 0)
+ PDEBUG(D_ERR, "i2c error pas106");
+ data += 2;
+ }
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int mode, l;
+ const __u8 *sn9c10x;
+ __u8 reg01, reg17;
+ __u8 reg17_19[3];
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ sn9c10x = initHv7131;
+ reg17_19[0] = 0x60;
+ reg17_19[1] = (mode << 4) | 0x8a;
+ reg17_19[2] = 0x20;
+ break;
+ case SENSOR_OV6650:
+ sn9c10x = initOv6650;
+ reg17_19[0] = 0x68;
+ reg17_19[1] = (mode << 4) | 0x8b;
+ reg17_19[2] = 0x20;
+ break;
+ case SENSOR_OV7630:
+ sn9c10x = initOv7630;
+ reg17_19[0] = 0x68;
+ reg17_19[1] = (mode << 4) | COMP2;
+ reg17_19[2] = MCK_INIT1;
+ break;
+ case SENSOR_OV7630_3:
+ sn9c10x = initOv7630_3;
+ reg17_19[0] = 0x68;
+ reg17_19[1] = (mode << 4) | COMP2;
+ reg17_19[2] = MCK_INIT1;
+ break;
+ case SENSOR_PAS106:
+ sn9c10x = initPas106;
+ reg17_19[0] = 0x24; /* 0x28 */
+ reg17_19[1] = (mode << 4) | COMP1;
+ reg17_19[2] = MCK_INIT1;
+ break;
+ case SENSOR_PAS202:
+ sn9c10x = initPas202;
+ reg17_19[0] = mode ? 0x24 : 0x20;
+ reg17_19[1] = (mode << 4) | 0x89;
+ reg17_19[2] = 0x20;
+ break;
+ case SENSOR_TAS5110:
+ sn9c10x = initTas5110;
+ reg17_19[0] = 0x60;
+ reg17_19[1] = (mode << 4) | 0x86;
+ reg17_19[2] = 0x2b; /* 0xf3; */
+ break;
+ default:
+/* case SENSOR_TAS5130CXX: */
+ sn9c10x = initTas5130;
+ reg17_19[0] = 0x60;
+ reg17_19[1] = (mode << 4) | COMP;
+ reg17_19[2] = mode ? 0x23 : 0x43;
+ break;
+ }
+ switch (sd->sensor) {
+ case SENSOR_OV7630:
+ reg01 = 0x06;
+ reg17 = 0x29;
+ l = sizeof initOv7630;
+ break;
+ case SENSOR_OV7630_3:
+ reg01 = 0x44;
+ reg17 = 0x68;
+ l = sizeof initOv7630_3;
+ break;
+ default:
+ reg01 = sn9c10x[0];
+ reg17 = sn9c10x[0x17 - 1];
+ l = 0x1f;
+ break;
+ }
+
+ /* reg 0x01 bit 2 video transfert on */
+ reg_w(gspca_dev, 0x01, &reg01, 1);
+ /* reg 0x17 SensorClk enable inv Clk 0x60 */
+ reg_w(gspca_dev, 0x17, &reg17, 1);
+/*fixme: for ov7630 102
+ reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */
+ /* Set the registers from the template */
+ reg_w_big(gspca_dev, 0x01, sn9c10x, l);
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ i2c_w_vector(gspca_dev, hv7131_sensor_init,
+ sizeof hv7131_sensor_init);
+ break;
+ case SENSOR_OV6650:
+ i2c_w_vector(gspca_dev, ov6650_sensor_init,
+ sizeof ov6650_sensor_init);
+ break;
+ case SENSOR_OV7630:
+ i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
+ sizeof ov7630_sensor_init_com);
+ msleep(200);
+ i2c_w_vector(gspca_dev, ov7630_sensor_init,
+ sizeof ov7630_sensor_init);
+ break;
+ case SENSOR_OV7630_3:
+ i2c_w_vector(gspca_dev, ov7630_sensor_init_com,
+ sizeof ov7630_sensor_init_com);
+ msleep(200);
+ i2c_w(gspca_dev, ov7630_sensor_init_3[mode]);
+ break;
+ case SENSOR_PAS106:
+ pas106_i2cinit(gspca_dev);
+ break;
+ case SENSOR_PAS202:
+ i2c_w_vector(gspca_dev, pas202_sensor_init,
+ sizeof pas202_sensor_init);
+ break;
+ case SENSOR_TAS5110:
+ i2c_w_vector(gspca_dev, tas5110_sensor_init,
+ sizeof tas5110_sensor_init);
+ break;
+ default:
+/* case SENSOR_TAS5130CXX: */
+ i2c_w_vector(gspca_dev, tas5130_sensor_init,
+ sizeof tas5130_sensor_init);
+ break;
+ }
+ /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
+ reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
+ /* compression register */
+ reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
+ /* H_start */
+ reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
+ /* V_START */
+ reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
+ /* reset 0x17 SensorClk enable inv Clk 0x60 */
+ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
+ reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
+ /*MCKSIZE ->3 */ /*fixme: not ov7630*/
+ reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
+ /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
+ reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
+ /* Enable video transfert */
+ reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
+ /* Compression */
+ reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
+ msleep(20);
+
+ setgain(gspca_dev);
+ setbrightness(gspca_dev);
+ setexposure(gspca_dev);
+ setfreq(gspca_dev);
+ setsaturation(gspca_dev);
+ sethue(gspca_dev);
+ setcontrast(gspca_dev);
+
+ sd->autogain_ignore_frames = 0;
+ atomic_set(&sd->avg_lum, -1);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ __u8 ByteSend;
+
+ ByteSend = 0x09; /* 0X00 */
+ reg_w(gspca_dev, 0x01, &ByteSend, 1);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ unsigned char *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ int i;
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* frames start with:
+ * ff ff 00 c4 c4 96 synchro
+ * 00 (unknown)
+ * xx (frame sequence / size / compression)
+ * (xx) (idem - extra byte for sn9c103)
+ * ll mm brightness sum inside auto exposure
+ * ll mm brightness sum outside auto exposure
+ * (xx xx xx xx xx) audio values for snc103
+ */
+ if (len > 6 && len < 24) {
+ for (i = 0; i < len - 6; i++) {
+ if (data[0 + i] == 0xff
+ && data[1 + i] == 0xff
+ && data[2 + i] == 0x00
+ && data[3 + i] == 0xc4
+ && data[4 + i] == 0xc4
+ && data[5 + i] == 0x96) { /* start of frame */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET,
+ frame, data, 0);
+ if (len - i < sd->fr_h_sz) {
+ atomic_set(&sd->avg_lum, -1);
+ PDEBUG(D_STREAM, "packet too short to"
+ " get avg brightness");
+ } else if (sd->fr_h_sz == 12) {
+ atomic_set(&sd->avg_lum,
+ data[i + 8] +
+ (data[i + 9] << 8));
+ } else {
+ atomic_set(&sd->avg_lum,
+ data[i + 9] +
+ (data[i + 10] << 8));
+ }
+ data += i + sd->fr_h_sz;
+ len -= i + sd->fr_h_sz;
+ gspca_frame_add(gspca_dev, FIRST_PACKET,
+ frame, data, len);
+ return;
+ }
+ }
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET,
+ frame, data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gain = val;
+ if (gspca_dev->streaming)
+ setgain(gspca_dev);
+ return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gain;
+ return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->exposure = val;
+ if (gspca_dev->streaming)
+ setexposure(gspca_dev);
+ return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->exposure;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ /* when switching to autogain set defaults to make sure
+ we are on a valid point of the autogain gain /
+ exposure knee graph, and give this change time to
+ take effect before doing autogain. */
+ if (sd->autogain) {
+ sd->exposure = EXPOSURE_DEF;
+ sd->gain = GAIN_DEF;
+ if (gspca_dev->streaming) {
+ sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
+ setexposure(gspca_dev);
+ setgain(gspca_dev);
+ }
+ }
+
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->freq = val;
+ if (gspca_dev->streaming)
+ setfreq(gspca_dev);
+ return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->freq;
+ return 0;
+}
+
+static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->saturation = val;
+ if (gspca_dev->streaming)
+ setsaturation(gspca_dev);
+ return 0;
+}
+
+static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->saturation;
+ return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->hue = val;
+ if (gspca_dev->streaming)
+ sethue(gspca_dev);
+ return 0;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->hue;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu)
+{
+ switch (menu->id) {
+ case V4L2_CID_POWER_LINE_FREQUENCY:
+ switch (menu->index) {
+ case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+ strcpy((char *) menu->name, "NoFliker");
+ return 0;
+ case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+ strcpy((char *) menu->name, "50 Hz");
+ return 0;
+ case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ strcpy((char *) menu->name, "60 Hz");
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+ .querymenu = sd_querymenu,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static __devinitdata struct usb_device_id device_table[] = {
+#ifndef CONFIG_USB_SN9C102
+ {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
+ {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
+ {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
+ {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
+ {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
+#endif
+ {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
+#ifndef CONFIG_USB_SN9C102
+ {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
+ {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
+ {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
+ {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
+ {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
+ {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
+ {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
+ {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
+ {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
+ {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
+#endif
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
new file mode 100644
index 00000000000..3e68b992695
--- /dev/null
+++ b/drivers/media/video/gspca/sonixj.c
@@ -0,0 +1,1671 @@
+/*
+ * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
+ * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "sonixj"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ int avg_lum;
+ unsigned int exposure;
+
+ unsigned short brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char autogain;
+
+ signed char ag_cnt;
+#define AG_CNT_START 13
+
+ char qindex;
+ unsigned char bridge;
+#define BRIDGE_SN9C102P 0
+#define BRIDGE_SN9C105 1
+#define BRIDGE_SN9C110 2
+#define BRIDGE_SN9C120 3
+#define BRIDGE_SN9C325 4
+ char sensor; /* Type of image sensor chip */
+#define SENSOR_HV7131R 0
+#define SENSOR_MI0360 1
+#define SENSOR_MO4000 2
+#define SENSOR_OV7648 3
+#define SENSOR_OV7660 4
+ unsigned char i2c_base;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 0xffff,
+ .step = 1,
+#define BRIGHTNESS_DEF 0x7fff
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+#define CONTRAST_DEF 63
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define COLOR_DEF 127
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define AUTOGAIN_DEF 1
+ .default_value = AUTOGAIN_DEF,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+/*Data from sn9c102p+hv71331r */
+static const __u8 sn_hv7131[] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
+ 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11,
+/* rega regb regc regd rege regf reg10 reg11 */
+ 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */
+/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
+ 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00,
+/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const __u8 sn_mi0360[] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
+ 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d,
+/* rega regb regc regd rege regf reg10 reg11 */
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
+/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
+ 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00,
+/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const __u8 sn_mo4000[] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
+ 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81,
+/* reg9 rega regb regc regd rege regf reg10 reg11*/
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
+ 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00,
+/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b,
+ 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
+ 0xd3, 0xdf, 0xea, 0xf5
+};
+
+static const __u8 sn_ov7648[] = {
+ 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65,
+ 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const __u8 sn_ov7660[] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81,
+/* reg9 rega regb regc regd rege regf reg10 reg11*/
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
+ 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00,
+/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* sequence specific to the sensors - !! index = SENSOR_xxx */
+static const __u8 *sn_tb[] = {
+ sn_hv7131,
+ sn_mi0360,
+ sn_mo4000,
+ sn_ov7648,
+ sn_ov7660
+};
+
+static const __u8 regsn20[] = {
+ 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
+ 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
+};
+static const __u8 regsn20_sn9c120[] = {
+ 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90,
+ 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff
+};
+static const __u8 regsn20_sn9c325[] = {
+ 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
+ 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
+};
+
+static const __u8 reg84[] = {
+ 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
+ 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
+/* 0x00, 0x00, 0x00, 0x00, 0x00 */
+ 0xf7, 0x0f, 0x0a, 0x00, 0x00
+};
+static const __u8 reg84_sn9c120_1[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x00, 0x00
+};
+static const __u8 reg84_sn9c120_2[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x02, 0x3b
+};
+static const __u8 reg84_sn9c120_3[] = {
+ 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f,
+ 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f,
+ 0xf5, 0x0f, 0x0c, 0x02, 0x3b
+};
+static const __u8 reg84_sn9c325[] = {
+ 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
+ 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
+ 0xf8, 0x0f, 0x00, 0x00, 0x00
+};
+
+static const __u8 hv7131r_sensor_init[][8] = {
+ {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
+ {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
+ {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
+ {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
+ {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+
+ {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
+ {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
+ {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
+ {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
+ {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
+ {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
+
+ {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
+
+ {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {}
+};
+static const __u8 mi0360_sensor_init[][8] = {
+ {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+ {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
+ {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
+ {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+ {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
+ {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+ {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
+ {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+ {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
+ {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+ {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+ {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
+ {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
+
+ {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
+ {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
+ {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+ {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
+ {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
+/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
+/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
+ {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+ {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+ {}
+};
+static const __u8 mo4000_sensor_init[][8] = {
+ {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
+ {}
+};
+static const __u8 ov7660_sensor_init[][8] = {
+ {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
+ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
+ /* Outformat ?? rawRGB */
+ {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
+ {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
+/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */
+ /* GAIN BLUE RED VREF */
+ {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
+ /* COM 1 BAVE GEAVE AECHH */
+ {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
+ {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
+ {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10},
+/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */
+ /* AECH CLKRC COM7 COM8 */
+ {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
+ {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
+ /* HSTART HSTOP VSTRT VSTOP */
+ {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
+ {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
+ {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
+ /* BOS GBOS GROS ROS (BGGR offset) */
+ {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10},
+/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */
+ /* AEW AEB VPT BBIAS */
+ {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
+ /* GbBIAS RSVD EXHCH EXHCL */
+ {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
+ /* RBIAS ADVFL ASDVFH YAVE */
+ {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
+ /* HSYST HSYEN HREF */
+ {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
+ {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
+ /* ADC ACOM OFON TSLB */
+ {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
+ /* COM11 COM12 COM13 COM14 */
+ {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
+ /* EDGE COM15 COM16 COM17 */
+ {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
+ {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
+ {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
+ {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
+ {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
+ {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
+ {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
+ {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
+ {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
+ {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
+ /* LCC1 LCC2 LCC3 LCC4 */
+ {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
+ {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10},
+ {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
+ /* band gap reference [0..3] DBLV */
+ {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
+ {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
+ {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
+ {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
+ {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
+ {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
+ {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
+ {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
+ {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
+ {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10},
+/****** (some exchanges in the win trace) ******/
+ {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
+ /* bits[3..0]reserved */
+ {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
+ /* VREF vertical frame ctrl */
+ {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */
+ {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
+/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */
+ {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10},
+/****** (some exchanges in the win trace) ******/
+ {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
+ {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */
+ {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},
+/****** (some exchanges in the win trace) ******/
+/**********startsensor KO if changed !!****/
+ {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
+/* here may start the isoc exchanges */
+ {}
+};
+/* reg0x04 reg0x07 reg 0x10 */
+/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */
+
+static const __u8 ov7648_sensor_init[][8] = {
+ {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
+ {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
+ {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
+ {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
+ {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
+ {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
+ {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
+ {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
+ {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
+ {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
+ {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
+ {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
+ {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
+ {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
+ {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
+ {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
+ {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
+ {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
+ {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
+ /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
+ * This is currently setting a
+ * blue tint, and some things more , i leave it here for future test if
+ * somene is having problems with color on this sensor
+ {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
+ {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
+ {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
+ {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
+ {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
+ {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
+ {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
+/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
+ {}
+};
+
+static const __u8 qtable4[] = {
+ 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
+ 0x06, 0x08, 0x0A, 0x11,
+ 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
+ 0x19, 0x19, 0x17, 0x15,
+ 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
+ 0x21, 0x2E, 0x21, 0x23,
+ 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
+ 0x25, 0x29, 0x2C, 0x29,
+ 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
+ 0x17, 0x1B, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0x29, 0x29
+};
+
+/* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 value, int len)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, 0,
+ gspca_dev->usb_buf, len,
+ 500);
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ __u16 value,
+ const __u8 *buffer,
+ int len)
+{
+ if (len <= sizeof gspca_dev->usb_buf) {
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, 0,
+ gspca_dev->usb_buf, len,
+ 500);
+ } else {
+ __u8 *tmpbuf;
+
+ tmpbuf = kmalloc(len, GFP_KERNEL);
+ memcpy(tmpbuf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, 0,
+ tmpbuf, len,
+ 500);
+ kfree(tmpbuf);
+ }
+}
+
+/* I2C write 2 bytes */
+static void i2c_w2(struct gspca_dev *gspca_dev,
+ const __u8 *buffer)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 mode[8];
+
+ /* is i2c ready */
+ mode[0] = 0x81 | (2 << 4);
+ mode[1] = sd->i2c_base;
+ mode[2] = buffer[0];
+ mode[3] = buffer[1];
+ mode[4] = 0;
+ mode[5] = 0;
+ mode[6] = 0;
+ mode[7] = 0x10;
+ reg_w(gspca_dev, 0x08, mode, 8);
+}
+
+/* I2C write 8 bytes */
+static void i2c_w8(struct gspca_dev *gspca_dev,
+ const __u8 *buffer)
+{
+ reg_w(gspca_dev, 0x08, buffer, 8);
+ msleep(1);
+}
+
+/* read 5 bytes in gspca_dev->usb_buf */
+static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 mode[8];
+
+ mode[0] = 0x81 | 0x10;
+ mode[1] = sd->i2c_base;
+ mode[2] = reg;
+ mode[3] = 0;
+ mode[4] = 0;
+ mode[5] = 0;
+ mode[6] = 0;
+ mode[7] = 0x10;
+ i2c_w8(gspca_dev, mode);
+ mode[0] = 0x81 | (5 << 4) | 0x02;
+ mode[2] = 0;
+ i2c_w8(gspca_dev, mode);
+ reg_r(gspca_dev, 0x0a, 5);
+}
+
+static int probesensor(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 reg02;
+ static const __u8 datasend[] = { 2, 0 };
+ /* reg val1 val2 val3 val4 */
+
+ i2c_w2(gspca_dev, datasend);
+/* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */
+ msleep(10);
+ reg02 = 0x66;
+ reg_w(gspca_dev, 0x02, &reg02, 1); /* Gpio on */
+ msleep(10);
+ i2c_r5(gspca_dev, 0); /* read sensor id */
+ if (gspca_dev->usb_buf[0] == 0x02
+ && gspca_dev->usb_buf[1] == 0x09
+ && gspca_dev->usb_buf[2] == 0x01
+ && gspca_dev->usb_buf[3] == 0x00
+ && gspca_dev->usb_buf[4] == 0x00) {
+ PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
+ sd->sensor = SENSOR_HV7131R;
+ return SENSOR_HV7131R;
+ }
+ PDEBUG(D_PROBE, "Find Sensor %d %d %d",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
+ gspca_dev->usb_buf[2]);
+ PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
+ return -ENODEV;
+}
+
+static int configure_gpio(struct gspca_dev *gspca_dev,
+ const __u8 *sn9c1xx)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 data;
+ __u8 regF1;
+ const __u8 *reg9a;
+ static const __u8 reg9a_def[] =
+ {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
+ static const __u8 reg9a_sn9c120[] = /* from win trace */
+ {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
+ static const __u8 reg9a_sn9c325[] =
+ {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
+
+
+ regF1 = 0x00;
+ reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/
+
+ /* configure gpio */
+ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
+ reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
+ reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm was 3 */
+ switch (sd->bridge) {
+ case BRIDGE_SN9C325:
+ reg9a = reg9a_sn9c325;
+ break;
+ case BRIDGE_SN9C120:
+ reg9a = reg9a_sn9c120;
+ break;
+ default:
+ reg9a = reg9a_def;
+ break;
+ }
+ reg_w(gspca_dev, 0x9a, reg9a, 6);
+
+ data = 0x60; /*fixme:jfm 60 00 00 (3) */
+ reg_w(gspca_dev, 0xd4, &data, 1);
+
+ reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
+
+ switch (sd->bridge) {
+ case BRIDGE_SN9C120: /* from win trace */
+ data = 0x61;
+ reg_w(gspca_dev, 0x01, &data, 1);
+ data = 0x20;
+ reg_w(gspca_dev, 0x17, &data, 1);
+ data = 0x60;
+ reg_w(gspca_dev, 0x01, &data, 1);
+ break;
+ case BRIDGE_SN9C325:
+ data = 0x43;
+ reg_w(gspca_dev, 0x01, &data, 1);
+ data = 0xae;
+ reg_w(gspca_dev, 0x17, &data, 1);
+ data = 0x42;
+ reg_w(gspca_dev, 0x01, &data, 1);
+ break;
+ default:
+ data = 0x43;
+ reg_w(gspca_dev, 0x01, &data, 1);
+ data = 0x61;
+ reg_w(gspca_dev, 0x17, &data, 1);
+ data = 0x42;
+ reg_w(gspca_dev, 0x01, &data, 1);
+ }
+
+ if (sd->sensor == SENSOR_HV7131R) {
+ if (probesensor(gspca_dev) < 0)
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+ static const __u8 SetSensorClk[] = /* 0x08 Mclk */
+ { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
+
+ while (hv7131r_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
+ i++;
+ }
+ i2c_w8(gspca_dev, SetSensorClk);
+}
+
+static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ while (mi0360_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, mi0360_sensor_init[i]);
+ i++;
+ }
+}
+
+static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ while (mo4000_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, mo4000_sensor_init[i]);
+ i++;
+ }
+}
+
+static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ while (ov7648_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, ov7648_sensor_init[i]);
+ i++;
+ }
+}
+
+static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ while (ov7660_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, ov7660_sensor_init[i]);
+ i++;
+ }
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 vendor;
+ __u16 product;
+
+ vendor = id->idVendor;
+ product = id->idProduct;
+ sd->sensor = -1;
+ switch (vendor) {
+ case 0x0458: /* Genius */
+/* switch (product) {
+ case 0x7025: */
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_MI0360;
+ sd->i2c_base = 0x5d;
+/* break;
+ } */
+ break;
+ case 0x045e:
+/* switch (product) {
+ case 0x00f5:
+ case 0x00f7: */
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_OV7660;
+ sd->i2c_base = 0x21;
+/* break;
+ } */
+ break;
+ case 0x0471: /* Philips */
+/* switch (product) {
+ case 0x0327:
+ case 0x0328:
+ case 0x0330: */
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_MI0360;
+ sd->i2c_base = 0x5d;
+/* break;
+ } */
+ break;
+ case 0x0c45: /* Sonix */
+ switch (product) {
+ case 0x6040:
+ sd->bridge = BRIDGE_SN9C102P;
+/* sd->sensor = SENSOR_MI0360; * from BW600.inf */
+/*fixme: MI0360 base=5d ? */
+ sd->sensor = SENSOR_HV7131R; /* gspcav1 value */
+ sd->i2c_base = 0x11;
+ break;
+/* case 0x607a: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C102P;
+ sd->sensor = SENSOR_OV7648;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x607c:
+ sd->bridge = BRIDGE_SN9C102P;
+ sd->sensor = SENSOR_HV7131R;
+ sd->i2c_base = 0x11;
+ break;
+/* case 0x607e: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C102P;
+ sd->sensor = SENSOR_OV7630;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x60c0:
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_MI0360;
+ sd->i2c_base = 0x5d;
+ break;
+/* case 0x60c8: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_OM6801;
+ sd->i2c_base = 0x??;
+ break; */
+/* case 0x60cc: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_HV7131GP;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x60ec:
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_MO4000;
+ sd->i2c_base = 0x21;
+ break;
+/* case 0x60ef: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_ICM105C;
+ sd->i2c_base = 0x??;
+ break; */
+/* case 0x60fa: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_OV7648;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x60fb:
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_OV7660;
+ sd->i2c_base = 0x21;
+ break;
+ case 0x60fc:
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_HV7131R;
+ sd->i2c_base = 0x11;
+ break;
+/* case 0x60fe: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C105;
+ sd->sensor = SENSOR_OV7630;
+ sd->i2c_base = 0x??;
+ break; */
+/* case 0x6108: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_OM6801;
+ sd->i2c_base = 0x??;
+ break; */
+/* case 0x6122: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C110;
+ sd->sensor = SENSOR_ICM105C;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x612a:
+/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */
+ sd->bridge = BRIDGE_SN9C325;
+ sd->sensor = SENSOR_OV7648;
+ sd->i2c_base = 0x21;
+/*fixme: sensor_init has base = 00 et 6e!*/
+ break;
+/* case 0x6123: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C110;
+ sd->sensor = SENSOR_SanyoCCD;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x612c:
+ sd->bridge = BRIDGE_SN9C110;
+ sd->sensor = SENSOR_MO4000;
+ sd->i2c_base = 0x21;
+ break;
+/* case 0x612e: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C110;
+ sd->sensor = SENSOR_OV7630;
+ sd->i2c_base = 0x??;
+ break; */
+/* case 0x612f: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C110;
+ sd->sensor = SENSOR_ICM105C;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x6130:
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_MI0360;
+ sd->i2c_base = 0x5d;
+ break;
+ case 0x6138:
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_MO4000;
+ sd->i2c_base = 0x21;
+ break;
+/* case 0x613a: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_OV7648;
+ sd->i2c_base = 0x??;
+ break; */
+ case 0x613b:
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_OV7660;
+ sd->i2c_base = 0x21;
+ break;
+ case 0x613c:
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_HV7131R;
+ sd->i2c_base = 0x11;
+ break;
+/* case 0x613e: * from BW600.inf
+ sd->bridge = BRIDGE_SN9C120;
+ sd->sensor = SENSOR_OV7630;
+ sd->i2c_base = 0x??;
+ break; */
+ }
+ break;
+ }
+ if (sd->sensor < 0) {
+ PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
+ vendor, product);
+ return -EINVAL;
+ }
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+
+ sd->qindex = 4; /* set the quantization table */
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLOR_DEF;
+ sd->autogain = AUTOGAIN_DEF;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+/* const __u8 *sn9c1xx; */
+ __u8 regF1;
+ __u8 regGpio[] = { 0x29, 0x74 };
+
+ /* setup a selector by bridge */
+ regF1 = 0x01;
+ reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
+ regF1 = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0xf1, &regF1, 1);
+ reg_r(gspca_dev, 0x00, 1);
+ regF1 = gspca_dev->usb_buf[0];
+ switch (sd->bridge) {
+ case BRIDGE_SN9C102P:
+ if (regF1 != 0x11)
+ return -ENODEV;
+ reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+ break;
+ case BRIDGE_SN9C105:
+ if (regF1 != 0x11)
+ return -ENODEV;
+ reg_w(gspca_dev, 0x02, regGpio, 2);
+ break;
+ case BRIDGE_SN9C110:
+ if (regF1 != 0x12)
+ return -ENODEV;
+ regGpio[1] = 0x62;
+ reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+ break;
+ case BRIDGE_SN9C120:
+ if (regF1 != 0x12)
+ return -ENODEV;
+ regGpio[1] = 0x70;
+ reg_w(gspca_dev, 0x02, regGpio, 2);
+ break;
+ default:
+/* case BRIDGE_SN9C325: */
+ if (regF1 != 0x12)
+ return -ENODEV;
+ regGpio[1] = 0x62;
+ reg_w(gspca_dev, 0x02, &regGpio[1], 1);
+ break;
+ }
+
+ regF1 = 0x01;
+ reg_w(gspca_dev, 0xf1, &regF1, 1);
+
+ return 0;
+}
+
+static unsigned int setexposure(struct gspca_dev *gspca_dev,
+ unsigned int expo)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ static const __u8 doit[] = /* update sensor */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
+ static const __u8 sensorgo[] = /* sensor on */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
+ static const __u8 gainMo[] =
+ { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R: {
+ __u8 Expodoit[] =
+ { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
+
+ Expodoit[3] = expo >> 16;
+ Expodoit[4] = expo >> 8;
+ Expodoit[5] = expo;
+ i2c_w8(gspca_dev, Expodoit);
+ break;
+ }
+ case SENSOR_MI0360: {
+ __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
+ { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+
+ if (expo > 0x0635)
+ expo = 0x0635;
+ else if (expo < 0x0001)
+ expo = 0x0001;
+ expoMi[3] = expo >> 8;
+ expoMi[4] = expo;
+ i2c_w8(gspca_dev, expoMi);
+ i2c_w8(gspca_dev, doit);
+ i2c_w8(gspca_dev, sensorgo);
+ break;
+ }
+ case SENSOR_MO4000: {
+ __u8 expoMof[] =
+ { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
+ __u8 expoMo10[] =
+ { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+
+ if (expo > 0x1fff)
+ expo = 0x1fff;
+ else if (expo < 0x0001)
+ expo = 0x0001;
+ expoMof[3] = (expo & 0x03fc) >> 2;
+ i2c_w8(gspca_dev, expoMof);
+ expoMo10[3] = ((expo & 0x1c00) >> 10)
+ | ((expo & 0x0003) << 4);
+ i2c_w8(gspca_dev, expoMo10);
+ i2c_w8(gspca_dev, gainMo);
+ PDEBUG(D_CONF, "set exposure %d",
+ ((expoMo10[3] & 0x07) << 10)
+ | (expoMof[3] << 2)
+ | ((expoMo10[3] & 0x30) >> 4));
+ break;
+ }
+ }
+ return expo;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned int expo;
+ __u8 k2;
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ expo = sd->brightness << 4;
+ if (expo > 0x002dc6c0)
+ expo = 0x002dc6c0;
+ else if (expo < 0x02a0)
+ expo = 0x02a0;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
+ case SENSOR_MI0360:
+ expo = sd->brightness >> 4;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
+ case SENSOR_MO4000:
+ expo = sd->brightness >> 4;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
+ case SENSOR_OV7660:
+ return; /*jfm??*/
+ }
+
+ k2 = sd->brightness >> 10;
+ reg_w(gspca_dev, 0x96, &k2, 1);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 k2;
+ __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
+
+ if (sd->sensor == SENSOR_OV7660)
+ return; /*jfm??*/
+ k2 = sd->contrast;
+ contrast[2] = k2;
+ contrast[0] = (k2 + 1) >> 1;
+ contrast[4] = (k2 + 1) / 5;
+ reg_w(gspca_dev, 0x84, contrast, 6);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 data;
+ int colour;
+
+ colour = sd->colors - 128;
+ if (colour > 0)
+ data = (colour + 32) & 0x7f; /* blue */
+ else
+ data = (-colour + 32) & 0x7f; /* red */
+ reg_w(gspca_dev, 0x05, &data, 1);
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ __u8 data;
+ __u8 reg1;
+ __u8 reg17;
+ const __u8 *sn9c1xx;
+ int mode;
+ static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c };
+ static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
+ static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+ static const __u8 CA_sn9c120[] =
+ { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
+ static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
+ static const __u8 CE_sn9c325[] =
+ { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
+
+ sn9c1xx = sn_tb[(int) sd->sensor];
+ configure_gpio(gspca_dev, sn9c1xx);
+
+/*fixme:jfm this sequence should appear at end of sd_start */
+/* with
+ data = 0x44;
+ reg_w(gspca_dev, 0x01, &data, 1); */
+ reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1);
+ reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1);
+ reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1);
+ reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1);
+ reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
+ reg_w(gspca_dev, 0xd2, &DC29[0], 1);
+ reg_w(gspca_dev, 0xd3, &DC29[1], 1);
+ reg_w(gspca_dev, 0xc6, &DC29[2], 1);
+ reg_w(gspca_dev, 0xc7, &DC29[3], 1);
+ reg_w(gspca_dev, 0xc8, &DC29[4], 1);
+ reg_w(gspca_dev, 0xc9, &DC29[5], 1);
+/*fixme:jfm end of ending sequence */
+ reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1);
+ switch (sd->bridge) {
+ case BRIDGE_SN9C325:
+ data = 0xae;
+ break;
+ case BRIDGE_SN9C120:
+ data = 0xa0;
+ break;
+ default:
+ data = 0x60;
+ break;
+ }
+ reg_w(gspca_dev, 0x17, &data, 1);
+ reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1);
+ reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1);
+ reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1);
+ reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1);
+ switch (sd->bridge) {
+ case BRIDGE_SN9C325:
+ reg_w(gspca_dev, 0x20, regsn20_sn9c325,
+ sizeof regsn20_sn9c325);
+ for (i = 0; i < 8; i++)
+ reg_w(gspca_dev, 0x84, reg84_sn9c325,
+ sizeof reg84_sn9c325);
+ data = 0x0a;
+ reg_w(gspca_dev, 0x9a, &data, 1);
+ data = 0x60;
+ reg_w(gspca_dev, 0x99, &data, 1);
+ break;
+ case BRIDGE_SN9C120:
+ reg_w(gspca_dev, 0x20, regsn20_sn9c120,
+ sizeof regsn20_sn9c120);
+ for (i = 0; i < 2; i++)
+ reg_w(gspca_dev, 0x84, reg84_sn9c120_1,
+ sizeof reg84_sn9c120_1);
+ for (i = 0; i < 6; i++)
+ reg_w(gspca_dev, 0x84, reg84_sn9c120_2,
+ sizeof reg84_sn9c120_2);
+ reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
+ sizeof reg84_sn9c120_3);
+ data = 0x05;
+ reg_w(gspca_dev, 0x9a, &data, 1);
+ data = 0x5b;
+ reg_w(gspca_dev, 0x99, &data, 1);
+ break;
+ default:
+ reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
+ for (i = 0; i < 8; i++)
+ reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
+ data = 0x08;
+ reg_w(gspca_dev, 0x9a, &data, 1);
+ data = 0x59;
+ reg_w(gspca_dev, 0x99, &data, 1);
+ break;
+ }
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg1 = 0x02;
+ reg17 = 0x61;
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ hv7131R_InitSensor(gspca_dev);
+ if (mode)
+ reg1 = 0x46; /* 320 clk 48Mhz */
+ else
+ reg1 = 0x06; /* 640 clk 24Mz */
+ break;
+ case SENSOR_MI0360:
+ mi0360_InitSensor(gspca_dev);
+ if (mode)
+ reg1 = 0x46; /* 320 clk 48Mhz */
+ else
+ reg1 = 0x06; /* 640 clk 24Mz */
+ break;
+ case SENSOR_MO4000:
+ mo4000_InitSensor(gspca_dev);
+ if (mode) {
+/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
+ reg1 = 0x06; /* clk 24Mz */
+ } else {
+ reg17 = 0x22; /* 640 MCKSIZE */
+ reg1 = 0x06; /* 640 clk 24Mz */
+ }
+ break;
+ case SENSOR_OV7648:
+ reg17 = 0xa2;
+ reg1 = 0x44;
+ ov7648_InitSensor(gspca_dev);
+/* if (mode)
+ ; * 320x2...
+ else
+ ; * 640x... */
+ break;
+ default:
+/* case SENSOR_OV7660: */
+ ov7660_InitSensor(gspca_dev);
+ if (mode) {
+/* reg17 = 0x21; * 320 */
+/* reg1 = 0x44; */
+ reg1 = 0x46;
+ } else {
+ reg17 = 0xa2; /* 640 */
+ reg1 = 0x40;
+ }
+ break;
+ }
+ reg_w(gspca_dev, 0xc0, C0, 6);
+ switch (sd->bridge) {
+ case BRIDGE_SN9C120: /*jfm ?? */
+ reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
+ break;
+ default:
+ reg_w(gspca_dev, 0xca, CA, 4);
+ break;
+ }
+ switch (sd->bridge) {
+ case BRIDGE_SN9C120: /*jfm ?? */
+ case BRIDGE_SN9C325:
+ reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
+ break;
+ default:
+ reg_w(gspca_dev, 0xce, CE, 4);
+ /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
+ break;
+ }
+
+ /* here change size mode 0 -> VGA; 1 -> CIF */
+ data = 0x40 | sn9c1xx[0x18] | (mode << 4);
+ reg_w(gspca_dev, 0x18, &data, 1);
+
+ reg_w(gspca_dev, 0x100, qtable4, 0x40);
+ reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
+
+ data = sn9c1xx[0x18] | (mode << 4);
+ reg_w(gspca_dev, 0x18, &data, 1);
+
+ reg_w(gspca_dev, 0x17, &reg17, 1);
+ reg_w(gspca_dev, 0x01, &reg1, 1);
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ static const __u8 stophv7131[] =
+ { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
+ static const __u8 stopmi0360[] =
+ { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
+ __u8 regF1;
+ __u8 data;
+ const __u8 *sn9c1xx;
+
+ data = 0x0b;
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ i2c_w8(gspca_dev, stophv7131);
+ data = 0x2b;
+ break;
+ case SENSOR_MI0360:
+ i2c_w8(gspca_dev, stopmi0360);
+ data = 0x29;
+ break;
+ case SENSOR_MO4000:
+ break;
+ case SENSOR_OV7648:
+ data = 0x29;
+ break;
+ default:
+/* case SENSOR_OV7660: */
+ break;
+ }
+ sn9c1xx = sn_tb[(int) sd->sensor];
+ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
+ reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1);
+ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1);
+ reg_w(gspca_dev, 0x01, &data, 1);
+ regF1 = 0x01;
+ reg_w(gspca_dev, 0xf1, &regF1, 1);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ /* Thanks S., without your advice, autobright should not work :) */
+ int delta;
+ int expotimes = 0;
+ __u8 luma_mean = 130;
+ __u8 luma_delta = 20;
+
+ delta = sd->avg_lum;
+ if (delta < luma_mean - luma_delta ||
+ delta > luma_mean + luma_delta) {
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ expotimes = sd->exposure >> 8;
+ expotimes += (luma_mean - delta) >> 4;
+ if (expotimes < 0)
+ expotimes = 0;
+ sd->exposure = setexposure(gspca_dev,
+ (unsigned int) (expotimes << 8));
+ break;
+ case SENSOR_MO4000:
+ case SENSOR_MI0360:
+ expotimes = sd->exposure;
+ expotimes += (luma_mean - delta) >> 6;
+ if (expotimes < 0)
+ expotimes = 0;
+ sd->exposure = setexposure(gspca_dev,
+ (unsigned int) expotimes);
+ setcolors(gspca_dev);
+ break;
+ }
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int sof, avg_lum;
+
+ sof = len - 64;
+ if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
+
+ /* end of frame */
+ gspca_frame_add(gspca_dev, LAST_PACKET,
+ frame, data, sof + 2);
+ if (sd->ag_cnt < 0)
+ return;
+ if (--sd->ag_cnt >= 0)
+ return;
+ sd->ag_cnt = AG_CNT_START;
+/* w1 w2 w3 */
+/* w4 w5 w6 */
+/* w7 w8 */
+/* w4 */
+ avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
+/* w6 */
+ avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
+/* w2 */
+ avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
+/* w8 */
+ avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
+/* w5 */
+ avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
+ avg_lum >>= 4;
+ sd->avg_lum = avg_lum;
+ PDEBUG(D_PACK, "mean lum %d", avg_lum);
+ setautogain(gspca_dev);
+ return;
+ }
+ if (gspca_dev->last_packet_type == LAST_PACKET) {
+
+ /* put the JPEG 422 header */
+ jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static unsigned int getexposure(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 hexpo, mexpo, lexpo;
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ /* read sensor exposure */
+ i2c_r5(gspca_dev, 0x25);
+ return (gspca_dev->usb_buf[0] << 16)
+ | (gspca_dev->usb_buf[1] << 8)
+ | gspca_dev->usb_buf[2];
+ case SENSOR_MI0360:
+ /* read sensor exposure */
+ i2c_r5(gspca_dev, 0x09);
+ return (gspca_dev->usb_buf[0] << 8)
+ | gspca_dev->usb_buf[1];
+ case SENSOR_MO4000:
+ i2c_r5(gspca_dev, 0x0e);
+ hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
+ mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
+ lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
+ PDEBUG(D_CONF, "exposure %d",
+ (hexpo << 10) | (mexpo << 2) | lexpo);
+ return (hexpo << 10) | (mexpo << 2) | lexpo;
+ default:
+/* case SENSOR_OV7660: */
+ /* read sensor exposure */
+ i2c_r5(gspca_dev, 0x04);
+ hexpo = gspca_dev->usb_buf[3] & 0x2f;
+ lexpo = gspca_dev->usb_buf[0] & 0x02;
+ i2c_r5(gspca_dev, 0x08);
+ mexpo = gspca_dev->usb_buf[2];
+ return (hexpo << 10) | (mexpo << 2) | lexpo;
+ }
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* hardcoded registers seem not readable */
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+/* sd->brightness = 0x7fff; */
+ sd->brightness = getexposure(gspca_dev) >> 4;
+ break;
+ case SENSOR_MI0360:
+ sd->brightness = getexposure(gspca_dev) << 4;
+ break;
+ case SENSOR_MO4000:
+/* sd->brightness = 0x1fff; */
+ sd->brightness = getexposure(gspca_dev) << 4;
+ break;
+ }
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (val)
+ sd->ag_cnt = AG_CNT_START;
+ else
+ sd->ag_cnt = -1;
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+#ifndef CONFIG_USB_SN9C102
+ {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
+ {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
+ {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
+ {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
+ {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
+#endif
+ {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
+ {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
+ {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
+ {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
+ {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
+ {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
+ {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
+ {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
+ {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
+#ifndef CONFIG_USB_SN9C102
+ {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
+ {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
+ {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
+ {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
+#endif
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ info("v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ info("deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
new file mode 100644
index 00000000000..15620611879
--- /dev/null
+++ b/drivers/media/video/gspca/spca500.c
@@ -0,0 +1,1216 @@
+/*
+ * SPCA500 chip based cameras initialization data
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define MODULE_NAME "spca500"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ __u8 packet[ISO_MAX_SIZE + 128];
+ /* !! no more than 128 ff in an ISO packet */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+
+ char qindex;
+ char subtype;
+#define AgfaCl20 0
+#define AiptekPocketDV 1
+#define BenqDC1016 2
+#define CreativePCCam300 3
+#define DLinkDSC350 4
+#define Gsmartmini 5
+#define IntelPocketPCCamera 6
+#define KodakEZ200 7
+#define LogitechClickSmart310 8
+#define LogitechClickSmart510 9
+#define LogitechTraveler 10
+#define MustekGsmart300 11
+#define Optimedia 12
+#define PalmPixDC85 13
+#define ToptroIndus 14
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+#define CONTRAST_DEF 31
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+#define COLOR_DEF 31
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+/* Frame packet header offsets for the spca500 */
+#define SPCA500_OFFSET_PADDINGLB 2
+#define SPCA500_OFFSET_PADDINGHB 3
+#define SPCA500_OFFSET_MODE 4
+#define SPCA500_OFFSET_IMGWIDTH 5
+#define SPCA500_OFFSET_IMGHEIGHT 6
+#define SPCA500_OFFSET_IMGMODE 7
+#define SPCA500_OFFSET_QTBLINDEX 8
+#define SPCA500_OFFSET_FRAMSEQ 9
+#define SPCA500_OFFSET_CDSPINFO 10
+#define SPCA500_OFFSET_GPIO 11
+#define SPCA500_OFFSET_AUGPIO 12
+#define SPCA500_OFFSET_DATA 16
+
+
+static const __u16 spca500_visual_defaults[][3] = {
+ {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
+ * hue (H byte) = 0,
+ * saturation/hue enable,
+ * brightness/contrast enable.
+ */
+ {0x00, 0x0000, 0x8167}, /* brightness = 0 */
+ {0x00, 0x0020, 0x8168}, /* contrast = 0 */
+ {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync,
+ * hue (H byte) = 0, saturation/hue enable,
+ * brightness/contrast enable.
+ * was 0x0003, now 0x0000.
+ */
+ {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */
+ {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */
+ {0x00, 0x0050, 0x8157}, /* edge gain high threshold */
+ {0x00, 0x0030, 0x8158}, /* edge gain low threshold */
+ {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */
+ {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */
+ {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */
+ {0x0c, 0x0004, 0x0000},
+ /* set interface */
+ {}
+};
+static const __u16 Clicksmart510_defaults[][3] = {
+ {0x00, 0x00, 0x8211},
+ {0x00, 0x01, 0x82c0},
+ {0x00, 0x10, 0x82cb},
+ {0x00, 0x0f, 0x800d},
+ {0x00, 0x82, 0x8225},
+ {0x00, 0x21, 0x8228},
+ {0x00, 0x00, 0x8203},
+ {0x00, 0x00, 0x8204},
+ {0x00, 0x08, 0x8205},
+ {0x00, 0xf8, 0x8206},
+ {0x00, 0x28, 0x8207},
+ {0x00, 0xa0, 0x8208},
+ {0x00, 0x08, 0x824a},
+ {0x00, 0x08, 0x8214},
+ {0x00, 0x80, 0x82c1},
+ {0x00, 0x00, 0x82c2},
+ {0x00, 0x00, 0x82ca},
+ {0x00, 0x80, 0x82c1},
+ {0x00, 0x04, 0x82c2},
+ {0x00, 0x00, 0x82ca},
+ {0x00, 0xfc, 0x8100},
+ {0x00, 0xfc, 0x8105},
+ {0x00, 0x30, 0x8101},
+ {0x00, 0x00, 0x8102},
+ {0x00, 0x00, 0x8103},
+ {0x00, 0x66, 0x8107},
+ {0x00, 0x00, 0x816b},
+ {0x00, 0x00, 0x8155},
+ {0x00, 0x01, 0x8156},
+ {0x00, 0x60, 0x8157},
+ {0x00, 0x40, 0x8158},
+ {0x00, 0x0a, 0x8159},
+ {0x00, 0x06, 0x815a},
+ {0x00, 0x00, 0x813f},
+ {0x00, 0x00, 0x8200},
+ {0x00, 0x19, 0x8201},
+ {0x00, 0x00, 0x82c1},
+ {0x00, 0xa0, 0x82c2},
+ {0x00, 0x00, 0x82ca},
+ {0x00, 0x00, 0x8117},
+ {0x00, 0x00, 0x8118},
+ {0x00, 0x65, 0x8119},
+ {0x00, 0x00, 0x811a},
+ {0x00, 0x00, 0x811b},
+ {0x00, 0x55, 0x811c},
+ {0x00, 0x65, 0x811d},
+ {0x00, 0x55, 0x811e},
+ {0x00, 0x16, 0x811f},
+ {0x00, 0x19, 0x8120},
+ {0x00, 0x80, 0x8103},
+ {0x00, 0x83, 0x816b},
+ {0x00, 0x25, 0x8168},
+ {0x00, 0x01, 0x820f},
+ {0x00, 0xff, 0x8115},
+ {0x00, 0x48, 0x8116},
+ {0x00, 0x50, 0x8151},
+ {0x00, 0x40, 0x8152},
+ {0x00, 0x78, 0x8153},
+ {0x00, 0x40, 0x8154},
+ {0x00, 0x00, 0x8167},
+ {0x00, 0x20, 0x8168},
+ {0x00, 0x00, 0x816a},
+ {0x00, 0x03, 0x816b},
+ {0x00, 0x20, 0x8169},
+ {0x00, 0x60, 0x8157},
+ {0x00, 0x00, 0x8190},
+ {0x00, 0x00, 0x81a1},
+ {0x00, 0x00, 0x81b2},
+ {0x00, 0x27, 0x8191},
+ {0x00, 0x27, 0x81a2},
+ {0x00, 0x27, 0x81b3},
+ {0x00, 0x4b, 0x8192},
+ {0x00, 0x4b, 0x81a3},
+ {0x00, 0x4b, 0x81b4},
+ {0x00, 0x66, 0x8193},
+ {0x00, 0x66, 0x81a4},
+ {0x00, 0x66, 0x81b5},
+ {0x00, 0x79, 0x8194},
+ {0x00, 0x79, 0x81a5},
+ {0x00, 0x79, 0x81b6},
+ {0x00, 0x8a, 0x8195},
+ {0x00, 0x8a, 0x81a6},
+ {0x00, 0x8a, 0x81b7},
+ {0x00, 0x9b, 0x8196},
+ {0x00, 0x9b, 0x81a7},
+ {0x00, 0x9b, 0x81b8},
+ {0x00, 0xa6, 0x8197},
+ {0x00, 0xa6, 0x81a8},
+ {0x00, 0xa6, 0x81b9},
+ {0x00, 0xb2, 0x8198},
+ {0x00, 0xb2, 0x81a9},
+ {0x00, 0xb2, 0x81ba},
+ {0x00, 0xbe, 0x8199},
+ {0x00, 0xbe, 0x81aa},
+ {0x00, 0xbe, 0x81bb},
+ {0x00, 0xc8, 0x819a},
+ {0x00, 0xc8, 0x81ab},
+ {0x00, 0xc8, 0x81bc},
+ {0x00, 0xd2, 0x819b},
+ {0x00, 0xd2, 0x81ac},
+ {0x00, 0xd2, 0x81bd},
+ {0x00, 0xdb, 0x819c},
+ {0x00, 0xdb, 0x81ad},
+ {0x00, 0xdb, 0x81be},
+ {0x00, 0xe4, 0x819d},
+ {0x00, 0xe4, 0x81ae},
+ {0x00, 0xe4, 0x81bf},
+ {0x00, 0xed, 0x819e},
+ {0x00, 0xed, 0x81af},
+ {0x00, 0xed, 0x81c0},
+ {0x00, 0xf7, 0x819f},
+ {0x00, 0xf7, 0x81b0},
+ {0x00, 0xf7, 0x81c1},
+ {0x00, 0xff, 0x81a0},
+ {0x00, 0xff, 0x81b1},
+ {0x00, 0xff, 0x81c2},
+ {0x00, 0x03, 0x8156},
+ {0x00, 0x00, 0x8211},
+ {0x00, 0x20, 0x8168},
+ {0x00, 0x01, 0x8202},
+ {0x00, 0x30, 0x8101},
+ {0x00, 0x00, 0x8111},
+ {0x00, 0x00, 0x8112},
+ {0x00, 0x00, 0x8113},
+ {0x00, 0x00, 0x8114},
+ {}
+};
+
+static const __u8 qtable_creative_pccam[2][64] = {
+ { /* Q-table Y-components */
+ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
+ 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
+ 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
+ 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
+ 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
+ 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
+ 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
+ 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
+ { /* Q-table C-components */
+ 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
+};
+
+static const __u8 qtable_kodak_ez200[2][64] = {
+ { /* Q-table Y-components */
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
+ 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
+ 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
+ 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
+ 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
+ 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
+ 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
+ { /* Q-table C-components */
+ 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
+};
+
+static const __u8 qtable_pocketdv[2][64] = {
+ { /* Q-table Y-components start registers 0x8800 */
+ 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
+ 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
+ 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
+ 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
+ 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
+ 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
+ 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
+ 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
+ },
+ { /* Q-table C-components start registers 0x8840 */
+ 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
+ 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
+ 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
+};
+
+/* read 'len' bytes to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 index,
+ __u16 length)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, length, 500);
+}
+
+static int reg_w(struct gspca_dev *gspca_dev,
+ __u16 req, __u16 index, __u16 value)
+{
+ int ret;
+
+ PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 500);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write: error %d", ret);
+ return ret;
+}
+
+/* returns: negative is error, pos or zero is data */
+static int reg_r_12(struct gspca_dev *gspca_dev,
+ __u16 req, /* bRequest */
+ __u16 index, /* wIndex */
+ __u16 length) /* wLength (1 or 2 only) */
+{
+ int ret;
+
+ gspca_dev->usb_buf[1] = 0;
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, length,
+ 500); /* timeout */
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_r_12 err %d", ret);
+ return -1;
+ }
+ return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
+}
+
+/*
+ * Simple function to wait for a given 8-bit value to be returned from
+ * a reg_read call.
+ * Returns: negative is error or timeout, zero is success.
+ */
+static int reg_r_wait(struct gspca_dev *gspca_dev,
+ __u16 reg, __u16 index, __u16 value)
+{
+ int ret, cnt = 20;
+
+ while (--cnt > 0) {
+ ret = reg_r_12(gspca_dev, reg, index, 1);
+ if (ret == value)
+ return 0;
+ msleep(50);
+ }
+ return -EIO;
+}
+
+static int write_vector(struct gspca_dev *gspca_dev,
+ const __u16 data[][3])
+{
+ int ret, i = 0;
+
+ while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
+ if (ret < 0)
+ return ret;
+ i++;
+ }
+ return 0;
+}
+
+static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
+ unsigned int request,
+ unsigned int ybase,
+ unsigned int cbase,
+ const __u8 qtable[2][64])
+{
+ int i, err;
+
+ /* loop over y components */
+ for (i = 0; i < 64; i++) {
+ err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
+ if (err < 0)
+ return err;
+ }
+
+ /* loop over c components */
+ for (i = 0; i < 64; i++) {
+ err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+static void spca500_ping310(struct gspca_dev *gspca_dev)
+{
+ reg_r(gspca_dev, 0x0d04, 2);
+ PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+}
+
+static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
+{
+ reg_r(gspca_dev, 0x0d05, 2);
+ PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
+ spca500_ping310(gspca_dev);
+
+ reg_w(gspca_dev, 0x00, 0x8168, 0x22);
+ reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
+ reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
+ reg_w(gspca_dev, 0x00, 0x8169, 0x25);
+ reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
+ reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
+ reg_w(gspca_dev, 0x00, 0x813f, 0x03);
+ reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
+ reg_w(gspca_dev, 0x00, 0x8153, 0x78);
+ reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
+ /* 00 for adjust shutter */
+ reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
+ reg_w(gspca_dev, 0x00, 0x8169, 0x25);
+ reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
+}
+
+static void spca500_setmode(struct gspca_dev *gspca_dev,
+ __u8 xmult, __u8 ymult)
+{
+ int mode;
+
+ /* set x multiplier */
+ reg_w(gspca_dev, 0, 0x8001, xmult);
+
+ /* set y multiplier */
+ reg_w(gspca_dev, 0, 0x8002, ymult);
+
+ /* use compressed mode, VGA, with mode specific subsample */
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg_w(gspca_dev, 0, 0x8003, mode << 4);
+}
+
+static int spca500_full_reset(struct gspca_dev *gspca_dev)
+{
+ int err;
+
+ /* send the reset command */
+ err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
+ if (err < 0)
+ return err;
+
+ /* wait for the reset to complete */
+ err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
+ if (err < 0)
+ return err;
+ err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
+ if (err < 0)
+ return err;
+ err = reg_r_wait(gspca_dev, 0x06, 0, 0);
+ if (err < 0) {
+ PDEBUG(D_ERR, "reg_r_wait() failed");
+ return err;
+ }
+ /* all ok */
+ return 0;
+}
+
+/* Synchro the Bridge with sensor */
+/* Maybe that will work on all spca500 chip */
+/* because i only own a clicksmart310 try for that chip */
+/* using spca50x_set_packet_size() cause an Ooops here */
+/* usb_set_interface from kernel 2.6.x clear all the urb stuff */
+/* up-port the same feature as in 2.4.x kernel */
+static int spca500_synch310(struct gspca_dev *gspca_dev)
+{
+ if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
+ PDEBUG(D_ERR, "Set packet size: set interface error");
+ goto error;
+ }
+ spca500_ping310(gspca_dev);
+
+ reg_r(gspca_dev, 0x0d00, 1);
+
+ /* need alt setting here */
+ PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
+
+ /* Windoze use pipe with altsetting 6 why 7 here */
+ if (usb_set_interface(gspca_dev->dev,
+ gspca_dev->iface,
+ gspca_dev->alt) < 0) {
+ PDEBUG(D_ERR, "Set packet size: set interface error");
+ goto error;
+ }
+ return 0;
+error:
+ return -EBUSY;
+}
+
+static void spca500_reinit(struct gspca_dev *gspca_dev)
+{
+ int err;
+ __u8 Data;
+
+ /* some unknow command from Aiptek pocket dv and family300 */
+
+ reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
+ reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
+ reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
+
+ /* enable drop packet */
+ reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+
+ err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
+ qtable_pocketdv);
+ if (err < 0)
+ PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init");
+
+ /* set qtable index */
+ reg_w(gspca_dev, 0x00, 0x8880, 2);
+ /* family cam Quicksmart stuff */
+ reg_w(gspca_dev, 0x00, 0x800a, 0x00);
+ /* Set agc transfer: synced inbetween frames */
+ reg_w(gspca_dev, 0x00, 0x820f, 0x01);
+ /* Init SDRAM - needed for SDRAM access */
+ reg_w(gspca_dev, 0x00, 0x870a, 0x04);
+ /*Start init sequence or stream */
+ reg_w(gspca_dev, 0, 0x8003, 0x00);
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+ msleep(2000);
+ if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+ }
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 vendor;
+ __u16 product;
+
+ vendor = id->idVendor;
+ product = id->idProduct;
+ switch (vendor) {
+ case 0x040a: /* Kodak cameras */
+/* switch (product) { */
+/* case 0x0300: */
+ sd->subtype = KodakEZ200;
+/* break; */
+/* } */
+ break;
+ case 0x041e: /* Creative cameras */
+/* switch (product) { */
+/* case 0x400a: */
+ sd->subtype = CreativePCCam300;
+/* break; */
+/* } */
+ break;
+ case 0x046d: /* Logitech Labtec */
+ switch (product) {
+ case 0x0890:
+ sd->subtype = LogitechTraveler;
+ break;
+ case 0x0900:
+ sd->subtype = LogitechClickSmart310;
+ break;
+ case 0x0901:
+ sd->subtype = LogitechClickSmart510;
+ break;
+ }
+ break;
+ case 0x04a5: /* Benq */
+/* switch (product) { */
+/* case 0x300c: */
+ sd->subtype = BenqDC1016;
+/* break; */
+/* } */
+ break;
+ case 0x04fc: /* SunPlus */
+/* switch (product) { */
+/* case 0x7333: */
+ sd->subtype = PalmPixDC85;
+/* break; */
+/* } */
+ break;
+ case 0x055f: /* Mustek cameras */
+ switch (product) {
+ case 0xc200:
+ sd->subtype = MustekGsmart300;
+ break;
+ case 0xc220:
+ sd->subtype = Gsmartmini;
+ break;
+ }
+ break;
+ case 0x06bd: /* Agfa Cl20 */
+/* switch (product) { */
+/* case 0x0404: */
+ sd->subtype = AgfaCl20;
+/* break; */
+/* } */
+ break;
+ case 0x06be: /* Optimedia */
+/* switch (product) { */
+/* case 0x0800: */
+ sd->subtype = Optimedia;
+/* break; */
+/* } */
+ break;
+ case 0x084d: /* D-Link / Minton */
+/* switch (product) { */
+/* case 0x0003: * DSC-350 / S-Cam F5 */
+ sd->subtype = DLinkDSC350;
+/* break; */
+/* } */
+ break;
+ case 0x08ca: /* Aiptek */
+/* switch (product) { */
+/* case 0x0103: */
+ sd->subtype = AiptekPocketDV;
+/* break; */
+/* } */
+ break;
+ case 0x2899: /* ToptroIndustrial */
+/* switch (product) { */
+/* case 0x012c: */
+ sd->subtype = ToptroIndus;
+/* break; */
+/* } */
+ break;
+ case 0x8086: /* Intel */
+/* switch (product) { */
+/* case 0x0630: * Pocket PC Camera */
+ sd->subtype = IntelPocketPCCamera;
+/* break; */
+/* } */
+ break;
+ }
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ if (sd->subtype != LogitechClickSmart310) {
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ } else {
+ cam->cam_mode = sif_mode;
+ cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ }
+ sd->qindex = 5;
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLOR_DEF;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* initialisation of spca500 based cameras is deferred */
+ PDEBUG(D_STREAM, "SPCA500 init");
+ if (sd->subtype == LogitechClickSmart310)
+ spca500_clksmart310_init(gspca_dev);
+/* else
+ spca500_initialise(gspca_dev); */
+ PDEBUG(D_STREAM, "SPCA500 init done");
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int err;
+ __u8 Data;
+ __u8 xmult, ymult;
+
+ if (sd->subtype == LogitechClickSmart310) {
+ xmult = 0x16;
+ ymult = 0x12;
+ } else {
+ xmult = 0x28;
+ ymult = 0x1e;
+ }
+
+ /* is there a sensor here ? */
+ reg_r(gspca_dev, 0x8a04, 1);
+ PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
+ gspca_dev->usb_buf[0]);
+ PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
+ gspca_dev->curr_mode, xmult, ymult);
+
+ /* setup qtable */
+ switch (sd->subtype) {
+ case LogitechClickSmart310:
+ spca500_setmode(gspca_dev, xmult, ymult);
+
+ /* enable drop packet */
+ reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ reg_w(gspca_dev, 0x00, 0x8880, 3);
+ err = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x8800, 0x8840,
+ qtable_creative_pccam);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+ /* Init SDRAM - needed for SDRAM access */
+ reg_w(gspca_dev, 0x00, 0x870a, 0x04);
+
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+ msleep(500);
+ if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
+ PDEBUG(D_ERR, "reg_r_wait() failed");
+
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+
+ spca500_synch310(gspca_dev);
+
+ write_vector(gspca_dev, spca500_visual_defaults);
+ spca500_setmode(gspca_dev, xmult, ymult);
+ /* enable drop packet */
+ reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ PDEBUG(D_ERR, "failed to enable drop packet");
+ reg_w(gspca_dev, 0x00, 0x8880, 3);
+ err = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x8800, 0x8840,
+ qtable_creative_pccam);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+
+ /* Init SDRAM - needed for SDRAM access */
+ reg_w(gspca_dev, 0x00, 0x870a, 0x04);
+
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+
+ if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
+ PDEBUG(D_ERR, "reg_r_wait() failed");
+
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+ break;
+ case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */
+ case IntelPocketPCCamera: /* FIXME: Temporary fix for
+ * Intel Pocket PC Camera
+ * - NWG (Sat 29th March 2003) */
+
+ /* do a full reset */
+ err = spca500_full_reset(gspca_dev);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca500_full_reset failed");
+
+ /* enable drop packet */
+ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ if (err < 0)
+ PDEBUG(D_ERR, "failed to enable drop packet");
+ reg_w(gspca_dev, 0x00, 0x8880, 3);
+ err = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x8800, 0x8840,
+ qtable_creative_pccam);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+
+ spca500_setmode(gspca_dev, xmult, ymult);
+ reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
+
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+
+ if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
+ PDEBUG(D_ERR, "reg_r_wait() failed");
+
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+
+/* write_vector(gspca_dev, spca500_visual_defaults); */
+ break;
+ case KodakEZ200: /* Kodak EZ200 */
+
+ /* do a full reset */
+ err = spca500_full_reset(gspca_dev);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca500_full_reset failed");
+ /* enable drop packet */
+ reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ reg_w(gspca_dev, 0x00, 0x8880, 0);
+ err = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x8800, 0x8840,
+ qtable_kodak_ez200);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+ spca500_setmode(gspca_dev, xmult, ymult);
+
+ reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
+
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+
+ if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
+ PDEBUG(D_ERR, "reg_r_wait() failed");
+
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+
+/* write_vector(gspca_dev, spca500_visual_defaults); */
+ break;
+
+ case BenqDC1016:
+ case DLinkDSC350: /* FamilyCam 300 */
+ case AiptekPocketDV: /* Aiptek PocketDV */
+ case Gsmartmini: /*Mustek Gsmart Mini */
+ case MustekGsmart300: /* Mustek Gsmart 300 */
+ case PalmPixDC85:
+ case Optimedia:
+ case ToptroIndus:
+ case AgfaCl20:
+ spca500_reinit(gspca_dev);
+ reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
+ /* enable drop packet */
+ reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+
+ err = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x8800, 0x8840, qtable_pocketdv);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+ reg_w(gspca_dev, 0x00, 0x8880, 2);
+
+ /* familycam Quicksmart pocketDV stuff */
+ reg_w(gspca_dev, 0x00, 0x800a, 0x00);
+ /* Set agc transfer: synced inbetween frames */
+ reg_w(gspca_dev, 0x00, 0x820f, 0x01);
+ /* Init SDRAM - needed for SDRAM access */
+ reg_w(gspca_dev, 0x00, 0x870a, 0x04);
+
+ spca500_setmode(gspca_dev, xmult, ymult);
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+
+ reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
+
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+ break;
+ case LogitechTraveler:
+ case LogitechClickSmart510:
+ reg_w(gspca_dev, 0x02, 0x00, 0x00);
+ /* enable drop packet */
+ reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+
+ err = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x8800,
+ 0x8840, qtable_creative_pccam);
+ if (err < 0)
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+ reg_w(gspca_dev, 0x00, 0x8880, 3);
+ reg_w(gspca_dev, 0x00, 0x800a, 0x00);
+ /* Init SDRAM - needed for SDRAM access */
+ reg_w(gspca_dev, 0x00, 0x870a, 0x04);
+
+ spca500_setmode(gspca_dev, xmult, ymult);
+
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+ reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
+
+ reg_r(gspca_dev, 0x816b, 1);
+ Data = gspca_dev->usb_buf[0];
+ reg_w(gspca_dev, 0x00, 0x816b, Data);
+ write_vector(gspca_dev, Clicksmart510_defaults);
+ break;
+ }
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 0, 0x8003, 0x00);
+
+ /* switch to video camera mode */
+ reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
+ reg_r(gspca_dev, 0x8000, 1);
+ PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
+ gspca_dev->usb_buf[0]);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ __u8 *s, *d;
+ static __u8 ffd9[] = {0xff, 0xd9};
+
+/* frames are jpeg 4.1.1 without 0xff escape */
+ if (data[0] == 0xff) {
+ if (data[1] != 0x01) { /* drop packet */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ ffd9, 2);
+
+ /* put the JPEG header in the new frame */
+ jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
+
+ data += SPCA500_OFFSET_DATA;
+ len -= SPCA500_OFFSET_DATA;
+ } else {
+ data += 1;
+ len -= 1;
+ }
+
+ /* add 0x00 after 0xff */
+ for (i = len; --i >= 0; )
+ if (data[i] == 0xff)
+ break;
+ if (i < 0) { /* no 0xff */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+ return;
+ }
+ s = data;
+ d = sd->packet;
+ for (i = 0; i < len; i++) {
+ *d++ = *s++;
+ if (s[-1] == 0xff)
+ *d++ = 0x00;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ sd->packet, d - sd->packet);
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0x00, 0x8167,
+ (__u8) (sd->brightness - 128));
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int ret;
+
+ ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
+ if (ret >= 0)
+ sd->brightness = ret + 128;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int ret;
+
+ ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
+ if (ret >= 0)
+ sd->contrast = ret;
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
+}
+
+static void getcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int ret;
+
+ ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
+ if (ret >= 0)
+ sd->colors = ret;
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcontrast(gspca_dev);
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcolors(gspca_dev);
+ *val = sd->colors;
+ return 0;
+}
+
+/* sub-driver description */
+static struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")},
+ {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")},
+ {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")},
+ {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")},
+ {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")},
+ {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")},
+ {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")},
+ {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")},
+ {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")},
+ {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")},
+ {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")},
+ {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")},
+ {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")},
+ {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")},
+ {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
new file mode 100644
index 00000000000..50e929de020
--- /dev/null
+++ b/drivers/media/video/gspca/spca501.c
@@ -0,0 +1,2229 @@
+/*
+ * SPCA501 chip based cameras initialization data
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define MODULE_NAME "spca501"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned short contrast;
+ __u8 brightness;
+ __u8 colors;
+
+ char subtype;
+#define Arowana300KCMOSCamera 0
+#define IntelCreateAndShare 1
+#define KodakDVC325 2
+#define MystFromOriUnknownCamera 3
+#define SmileIntlCamera 4
+#define ThreeComHomeConnectLite 5
+#define ViewQuestM318B 6
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define MY_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 127,
+ .step = 1,
+ .default_value = 63,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define MY_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0xffff,
+ .step = 1,
+ .default_value = 0xaa00,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define MY_COLOR 2
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+ .default_value = 31,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {320, 240, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+#define SPCA50X_REG_USB 0x2 /* spca505 501 */
+/*
+ * Data to initialize a SPCA501. From a capture file provided by Bill Roehl
+ * With SPCA501 chip description
+ */
+#define CCDSP_SET /* set CCDSP parameters */
+#define TG_SET /* set time generator set */
+#undef DSPWIN_SET /* set DSP windows parameters */
+#undef ALTER_GAMA /* Set alternate set to YUV transform coeffs. */
+#define SPCA501_SNAPBIT 0x80
+#define SPCA501_SNAPCTRL 0x10
+/* Frame packet header offsets for the spca501 */
+#define SPCA501_OFFSET_GPIO 1
+#define SPCA501_OFFSET_TYPE 2
+#define SPCA501_OFFSET_TURN3A 3
+#define SPCA501_OFFSET_FRAMSEQ 4
+#define SPCA501_OFFSET_COMPRESS 5
+#define SPCA501_OFFSET_QUANT 6
+#define SPCA501_OFFSET_QUANT2 7
+#define SPCA501_OFFSET_DATA 8
+
+#define SPCA501_PROP_COMP_ENABLE(d) ((d) & 1)
+#define SPCA501_PROP_SNAP(d) ((d) & 0x40)
+#define SPCA501_PROP_SNAP_CTRL(d) ((d) & 0x10)
+#define SPCA501_PROP_COMP_THRESH(d) (((d) & 0x0e) >> 1)
+#define SPCA501_PROP_COMP_QUANT(d) (((d) & 0x70) >> 4)
+
+/* SPCA501 CCDSP control */
+#define SPCA501_REG_CCDSP 0x01
+/* SPCA501 control/status registers */
+#define SPCA501_REG_CTLRL 0x02
+
+/* registers for color correction and YUV transformation */
+#define SPCA501_A11 0x08
+#define SPCA501_A12 0x09
+#define SPCA501_A13 0x0A
+#define SPCA501_A21 0x0B
+#define SPCA501_A22 0x0C
+#define SPCA501_A23 0x0D
+#define SPCA501_A31 0x0E
+#define SPCA501_A32 0x0F
+#define SPCA501_A33 0x10
+
+/* Data for video camera initialization before capturing */
+static const __u16 spca501_open_data[][3] = {
+ /* bmRequest,value,index */
+
+ {0x2, 0x50, 0x00}, /* C/S enable soft reset */
+ {0x2, 0x40, 0x00}, /* C/S disable soft reset */
+ {0x2, 0x02, 0x05}, /* C/S general purpose I/O data */
+ {0x2, 0x03, 0x05}, /* C/S general purpose I/O data */
+
+#ifdef CCDSP_SET
+ {0x1, 0x38, 0x01}, /* CCDSP options */
+ {0x1, 0x05, 0x02}, /* CCDSP Optical black level for user settings */
+ {0x1, 0xC0, 0x03}, /* CCDSP Optical black settings */
+
+ {0x1, 0x67, 0x07},
+ {0x1, 0x63, 0x3f}, /* CCDSP CCD gamma enable */
+ {0x1, 0x03, 0x56}, /* Add gamma correction */
+
+ {0x1, 0xFF, 0x15}, /* CCDSP High luminance for white balance */
+ {0x1, 0x01, 0x16}, /* CCDSP Low luminance for white balance */
+
+/* Color correction and RGB-to-YUV transformation coefficients changing */
+#ifdef ALTER_GAMA
+ {0x0, 0x00, 0x08}, /* A11 */
+ {0x0, 0x00, 0x09}, /* A12 */
+ {0x0, 0x90, 0x0A}, /* A13 */
+ {0x0, 0x12, 0x0B}, /* A21 */
+ {0x0, 0x00, 0x0C}, /* A22 */
+ {0x0, 0x00, 0x0D}, /* A23 */
+ {0x0, 0x00, 0x0E}, /* A31 */
+ {0x0, 0x02, 0x0F}, /* A32 */
+ {0x0, 0x00, 0x10}, /* A33 */
+#else
+ {0x1, 0x2a, 0x08}, /* A11 0x31 */
+ {0x1, 0xf8, 0x09}, /* A12 f8 */
+ {0x1, 0xf8, 0x0A}, /* A13 f8 */
+ {0x1, 0xf8, 0x0B}, /* A21 f8 */
+ {0x1, 0x14, 0x0C}, /* A22 0x14 */
+ {0x1, 0xf8, 0x0D}, /* A23 f8 */
+ {0x1, 0xf8, 0x0E}, /* A31 f8 */
+ {0x1, 0xf8, 0x0F}, /* A32 f8 */
+ {0x1, 0x20, 0x10}, /* A33 0x20 */
+#endif
+ {0x1, 0x00, 0x11}, /* R offset */
+ {0x1, 0x00, 0x12}, /* G offset */
+ {0x1, 0x00, 0x13}, /* B offset */
+ {0x1, 0x00, 0x14}, /* GB offset */
+
+#endif
+
+#ifdef TG_SET
+ /* Time generator manipulations */
+ {0x0, 0xfc, 0x0}, /* Set up high bits of shutter speed */
+ {0x0, 0x01, 0x1}, /* Set up low bits of shutter speed */
+
+ {0x0, 0xe4, 0x04}, /* DCLK*2 clock phase adjustment */
+ {0x0, 0x08, 0x05}, /* ADCK phase adjustment, inv. ext. VB */
+ {0x0, 0x03, 0x06}, /* FR phase adjustment */
+ {0x0, 0x01, 0x07}, /* FCDS phase adjustment */
+ {0x0, 0x39, 0x08}, /* FS phase adjustment */
+ {0x0, 0x88, 0x0a}, /* FH1 phase and delay adjustment */
+ {0x0, 0x03, 0x0f}, /* pixel identification */
+ {0x0, 0x00, 0x11}, /* clock source selection (default) */
+
+ /*VERY strange manipulations with
+ * select DMCLP or OBPX to be ADCLP output (0x0C)
+ * OPB always toggle or not (0x0D) but they allow
+ * us to set up brightness
+ */
+ {0x0, 0x01, 0x0c},
+ {0x0, 0xe0, 0x0d},
+ /* Done */
+#endif
+
+#ifdef DSPWIN_SET
+ {0x1, 0xa0, 0x01}, /* Setting image processing parameters */
+ {0x1, 0x1c, 0x17}, /* Changing Windows positions X1 */
+ {0x1, 0xe2, 0x19}, /* X2 */
+ {0x1, 0x1c, 0x1b}, /* X3 */
+ {0x1, 0xe2, 0x1d}, /* X4 */
+ {0x1, 0x5f, 0x1f}, /* X5 */
+ {0x1, 0x32, 0x20}, /* Y5 */
+ {0x1, 0x01, 0x10}, /* Changing A33 */
+#endif
+
+ {0x2, 0x204a, 0x07},/* Setting video compression & resolution 160x120 */
+ {0x2, 0x94, 0x06}, /* Setting video no compression */
+ {}
+};
+
+/*
+ The SPCAxxx docs from Sunplus document these values
+ in tables, one table per register number. In the data
+ below, dmRequest is the register number, index is the Addr,
+ and value is a combination of Bit values.
+ Bit Value (hex)
+ 0 01
+ 1 02
+ 2 04
+ 3 08
+ 4 10
+ 5 20
+ 6 40
+ 7 80
+ */
+
+/* Data for chip initialization (set default values) */
+static const __u16 spca501_init_data[][3] = {
+ /* Set all the values to powerup defaults */
+ /* bmRequest,value,index */
+ {0x0, 0xAA, 0x00},
+ {0x0, 0x02, 0x01},
+ {0x0, 0x01, 0x02},
+ {0x0, 0x02, 0x03},
+ {0x0, 0xCE, 0x04},
+ {0x0, 0x00, 0x05},
+ {0x0, 0x00, 0x06},
+ {0x0, 0x00, 0x07},
+ {0x0, 0x00, 0x08},
+ {0x0, 0x00, 0x09},
+ {0x0, 0x90, 0x0A},
+ {0x0, 0x12, 0x0B},
+ {0x0, 0x00, 0x0C},
+ {0x0, 0x00, 0x0D},
+ {0x0, 0x00, 0x0E},
+ {0x0, 0x02, 0x0F},
+ {0x0, 0x00, 0x10},
+ {0x0, 0x00, 0x11},
+ {0x0, 0x00, 0x12},
+ {0x0, 0x00, 0x13},
+ {0x0, 0x00, 0x14},
+ {0x0, 0x00, 0x15},
+ {0x0, 0x00, 0x16},
+ {0x0, 0x00, 0x17},
+ {0x0, 0x00, 0x18},
+ {0x0, 0x00, 0x19},
+ {0x0, 0x00, 0x1A},
+ {0x0, 0x00, 0x1B},
+ {0x0, 0x00, 0x1C},
+ {0x0, 0x00, 0x1D},
+ {0x0, 0x00, 0x1E},
+ {0x0, 0x00, 0x1F},
+ {0x0, 0x00, 0x20},
+ {0x0, 0x00, 0x21},
+ {0x0, 0x00, 0x22},
+ {0x0, 0x00, 0x23},
+ {0x0, 0x00, 0x24},
+ {0x0, 0x00, 0x25},
+ {0x0, 0x00, 0x26},
+ {0x0, 0x00, 0x27},
+ {0x0, 0x00, 0x28},
+ {0x0, 0x00, 0x29},
+ {0x0, 0x00, 0x2A},
+ {0x0, 0x00, 0x2B},
+ {0x0, 0x00, 0x2C},
+ {0x0, 0x00, 0x2D},
+ {0x0, 0x00, 0x2E},
+ {0x0, 0x00, 0x2F},
+ {0x0, 0x00, 0x30},
+ {0x0, 0x00, 0x31},
+ {0x0, 0x00, 0x32},
+ {0x0, 0x00, 0x33},
+ {0x0, 0x00, 0x34},
+ {0x0, 0x00, 0x35},
+ {0x0, 0x00, 0x36},
+ {0x0, 0x00, 0x37},
+ {0x0, 0x00, 0x38},
+ {0x0, 0x00, 0x39},
+ {0x0, 0x00, 0x3A},
+ {0x0, 0x00, 0x3B},
+ {0x0, 0x00, 0x3C},
+ {0x0, 0x00, 0x3D},
+ {0x0, 0x00, 0x3E},
+ {0x0, 0x00, 0x3F},
+ {0x0, 0x00, 0x40},
+ {0x0, 0x00, 0x41},
+ {0x0, 0x00, 0x42},
+ {0x0, 0x00, 0x43},
+ {0x0, 0x00, 0x44},
+ {0x0, 0x00, 0x45},
+ {0x0, 0x00, 0x46},
+ {0x0, 0x00, 0x47},
+ {0x0, 0x00, 0x48},
+ {0x0, 0x00, 0x49},
+ {0x0, 0x00, 0x4A},
+ {0x0, 0x00, 0x4B},
+ {0x0, 0x00, 0x4C},
+ {0x0, 0x00, 0x4D},
+ {0x0, 0x00, 0x4E},
+ {0x0, 0x00, 0x4F},
+ {0x0, 0x00, 0x50},
+ {0x0, 0x00, 0x51},
+ {0x0, 0x00, 0x52},
+ {0x0, 0x00, 0x53},
+ {0x0, 0x00, 0x54},
+ {0x0, 0x00, 0x55},
+ {0x0, 0x00, 0x56},
+ {0x0, 0x00, 0x57},
+ {0x0, 0x00, 0x58},
+ {0x0, 0x00, 0x59},
+ {0x0, 0x00, 0x5A},
+ {0x0, 0x00, 0x5B},
+ {0x0, 0x00, 0x5C},
+ {0x0, 0x00, 0x5D},
+ {0x0, 0x00, 0x5E},
+ {0x0, 0x00, 0x5F},
+ {0x0, 0x00, 0x60},
+ {0x0, 0x00, 0x61},
+ {0x0, 0x00, 0x62},
+ {0x0, 0x00, 0x63},
+ {0x0, 0x00, 0x64},
+ {0x0, 0x00, 0x65},
+ {0x0, 0x00, 0x66},
+ {0x0, 0x00, 0x67},
+ {0x0, 0x00, 0x68},
+ {0x0, 0x00, 0x69},
+ {0x0, 0x00, 0x6A},
+ {0x0, 0x00, 0x6B},
+ {0x0, 0x00, 0x6C},
+ {0x0, 0x00, 0x6D},
+ {0x0, 0x00, 0x6E},
+ {0x0, 0x00, 0x6F},
+ {0x0, 0x00, 0x70},
+ {0x0, 0x00, 0x71},
+ {0x0, 0x00, 0x72},
+ {0x0, 0x00, 0x73},
+ {0x0, 0x00, 0x74},
+ {0x0, 0x00, 0x75},
+ {0x0, 0x00, 0x76},
+ {0x0, 0x00, 0x77},
+ {0x0, 0x00, 0x78},
+ {0x0, 0x00, 0x79},
+ {0x0, 0x00, 0x7A},
+ {0x0, 0x00, 0x7B},
+ {0x0, 0x00, 0x7C},
+ {0x0, 0x00, 0x7D},
+ {0x0, 0x00, 0x7E},
+ {0x0, 0x00, 0x7F},
+ {0x0, 0x00, 0x80},
+ {0x0, 0x00, 0x81},
+ {0x0, 0x00, 0x82},
+ {0x0, 0x00, 0x83},
+ {0x0, 0x00, 0x84},
+ {0x0, 0x00, 0x85},
+ {0x0, 0x00, 0x86},
+ {0x0, 0x00, 0x87},
+ {0x0, 0x00, 0x88},
+ {0x0, 0x00, 0x89},
+ {0x0, 0x00, 0x8A},
+ {0x0, 0x00, 0x8B},
+ {0x0, 0x00, 0x8C},
+ {0x0, 0x00, 0x8D},
+ {0x0, 0x00, 0x8E},
+ {0x0, 0x00, 0x8F},
+ {0x0, 0x00, 0x90},
+ {0x0, 0x00, 0x91},
+ {0x0, 0x00, 0x92},
+ {0x0, 0x00, 0x93},
+ {0x0, 0x00, 0x94},
+ {0x0, 0x00, 0x95},
+ {0x0, 0x00, 0x96},
+ {0x0, 0x00, 0x97},
+ {0x0, 0x00, 0x98},
+ {0x0, 0x00, 0x99},
+ {0x0, 0x00, 0x9A},
+ {0x0, 0x00, 0x9B},
+ {0x0, 0x00, 0x9C},
+ {0x0, 0x00, 0x9D},
+ {0x0, 0x00, 0x9E},
+ {0x0, 0x00, 0x9F},
+ {0x0, 0x00, 0xA0},
+ {0x0, 0x00, 0xA1},
+ {0x0, 0x00, 0xA2},
+ {0x0, 0x00, 0xA3},
+ {0x0, 0x00, 0xA4},
+ {0x0, 0x00, 0xA5},
+ {0x0, 0x00, 0xA6},
+ {0x0, 0x00, 0xA7},
+ {0x0, 0x00, 0xA8},
+ {0x0, 0x00, 0xA9},
+ {0x0, 0x00, 0xAA},
+ {0x0, 0x00, 0xAB},
+ {0x0, 0x00, 0xAC},
+ {0x0, 0x00, 0xAD},
+ {0x0, 0x00, 0xAE},
+ {0x0, 0x00, 0xAF},
+ {0x0, 0x00, 0xB0},
+ {0x0, 0x00, 0xB1},
+ {0x0, 0x00, 0xB2},
+ {0x0, 0x00, 0xB3},
+ {0x0, 0x00, 0xB4},
+ {0x0, 0x00, 0xB5},
+ {0x0, 0x00, 0xB6},
+ {0x0, 0x00, 0xB7},
+ {0x0, 0x00, 0xB8},
+ {0x0, 0x00, 0xB9},
+ {0x0, 0x00, 0xBA},
+ {0x0, 0x00, 0xBB},
+ {0x0, 0x00, 0xBC},
+ {0x0, 0x00, 0xBD},
+ {0x0, 0x00, 0xBE},
+ {0x0, 0x00, 0xBF},
+ {0x0, 0x00, 0xC0},
+ {0x0, 0x00, 0xC1},
+ {0x0, 0x00, 0xC2},
+ {0x0, 0x00, 0xC3},
+ {0x0, 0x00, 0xC4},
+ {0x0, 0x00, 0xC5},
+ {0x0, 0x00, 0xC6},
+ {0x0, 0x00, 0xC7},
+ {0x0, 0x00, 0xC8},
+ {0x0, 0x00, 0xC9},
+ {0x0, 0x00, 0xCA},
+ {0x0, 0x00, 0xCB},
+ {0x0, 0x00, 0xCC},
+ {0x1, 0xF4, 0x00},
+ {0x1, 0x38, 0x01},
+ {0x1, 0x40, 0x02},
+ {0x1, 0x0A, 0x03},
+ {0x1, 0x40, 0x04},
+ {0x1, 0x40, 0x05},
+ {0x1, 0x40, 0x06},
+ {0x1, 0x67, 0x07},
+ {0x1, 0x31, 0x08},
+ {0x1, 0x00, 0x09},
+ {0x1, 0x00, 0x0A},
+ {0x1, 0x00, 0x0B},
+ {0x1, 0x14, 0x0C},
+ {0x1, 0x00, 0x0D},
+ {0x1, 0x00, 0x0E},
+ {0x1, 0x00, 0x0F},
+ {0x1, 0x1E, 0x10},
+ {0x1, 0x00, 0x11},
+ {0x1, 0x00, 0x12},
+ {0x1, 0x00, 0x13},
+ {0x1, 0x00, 0x14},
+ {0x1, 0xFF, 0x15},
+ {0x1, 0x01, 0x16},
+ {0x1, 0x32, 0x17},
+ {0x1, 0x23, 0x18},
+ {0x1, 0xCE, 0x19},
+ {0x1, 0x23, 0x1A},
+ {0x1, 0x32, 0x1B},
+ {0x1, 0x8D, 0x1C},
+ {0x1, 0xCE, 0x1D},
+ {0x1, 0x8D, 0x1E},
+ {0x1, 0x00, 0x1F},
+ {0x1, 0x00, 0x20},
+ {0x1, 0xFF, 0x3E},
+ {0x1, 0x02, 0x3F},
+ {0x1, 0x00, 0x40},
+ {0x1, 0x00, 0x41},
+ {0x1, 0x00, 0x42},
+ {0x1, 0x00, 0x43},
+ {0x1, 0x00, 0x44},
+ {0x1, 0x00, 0x45},
+ {0x1, 0x00, 0x46},
+ {0x1, 0x00, 0x47},
+ {0x1, 0x00, 0x48},
+ {0x1, 0x00, 0x49},
+ {0x1, 0x00, 0x4A},
+ {0x1, 0x00, 0x4B},
+ {0x1, 0x00, 0x4C},
+ {0x1, 0x00, 0x4D},
+ {0x1, 0x00, 0x4E},
+ {0x1, 0x00, 0x4F},
+ {0x1, 0x00, 0x50},
+ {0x1, 0x00, 0x51},
+ {0x1, 0x00, 0x52},
+ {0x1, 0x00, 0x53},
+ {0x1, 0x00, 0x54},
+ {0x1, 0x00, 0x55},
+ {0x1, 0x00, 0x56},
+ {0x1, 0x00, 0x57},
+ {0x1, 0x00, 0x58},
+ {0x1, 0x00, 0x59},
+ {0x1, 0x00, 0x5A},
+ {0x2, 0x03, 0x00},
+ {0x2, 0x00, 0x01},
+ {0x2, 0x00, 0x05},
+ {0x2, 0x00, 0x06},
+ {0x2, 0x00, 0x07},
+ {0x2, 0x00, 0x10},
+ {0x2, 0x00, 0x11},
+ /* Strange - looks like the 501 driver doesn't do anything
+ * at insert time except read the EEPROM
+ */
+ {}
+};
+
+/* Data for video camera init before capture.
+ * Capture and decoding by Colin Peart.
+ * This is is for the 3com HomeConnect Lite which is spca501a based.
+ */
+static const __u16 spca501_3com_open_data[][3] = {
+ /* bmRequest,value,index */
+ {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */
+ {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */
+ {0x2, 0x0002, 0x0005}, /* C/S GPIO */
+ {0x2, 0x0003, 0x0005}, /* C/S GPIO */
+
+#ifdef CCDSP_SET
+ {0x1, 0x0020, 0x0001}, /* CCDSP Options */
+
+ {0x1, 0x0020, 0x0002}, /* CCDSP Black Level */
+ {0x1, 0x006e, 0x0007}, /* CCDSP Gamma options */
+ {0x1, 0x0090, 0x0015}, /* CCDSP Luminance Low */
+ {0x1, 0x00ff, 0x0016}, /* CCDSP Luminance High */
+ {0x1, 0x0003, 0x003F}, /* CCDSP Gamma correction toggle */
+
+#ifdef ALTER_GAMMA
+ {0x1, 0x0010, 0x0008}, /* CCDSP YUV A11 */
+ {0x1, 0x0000, 0x0009}, /* CCDSP YUV A12 */
+ {0x1, 0x0000, 0x000a}, /* CCDSP YUV A13 */
+ {0x1, 0x0000, 0x000b}, /* CCDSP YUV A21 */
+ {0x1, 0x0010, 0x000c}, /* CCDSP YUV A22 */
+ {0x1, 0x0000, 0x000d}, /* CCDSP YUV A23 */
+ {0x1, 0x0000, 0x000e}, /* CCDSP YUV A31 */
+ {0x1, 0x0000, 0x000f}, /* CCDSP YUV A32 */
+ {0x1, 0x0010, 0x0010}, /* CCDSP YUV A33 */
+ {0x1, 0x0000, 0x0011}, /* CCDSP R Offset */
+ {0x1, 0x0000, 0x0012}, /* CCDSP G Offset */
+ {0x1, 0x0001, 0x0013}, /* CCDSP B Offset */
+ {0x1, 0x0001, 0x0014}, /* CCDSP BG Offset */
+ {0x1, 0x003f, 0x00C1}, /* CCDSP Gamma Correction Enable */
+#endif
+#endif
+
+#ifdef TG_SET
+ {0x0, 0x00fc, 0x0000}, /* TG Shutter Speed High Bits */
+ {0x0, 0x0000, 0x0001}, /* TG Shutter Speed Low Bits */
+ {0x0, 0x00e4, 0x0004}, /* TG DCLK*2 Adjust */
+ {0x0, 0x0008, 0x0005}, /* TG ADCK Adjust */
+ {0x0, 0x0003, 0x0006}, /* TG FR Phase Adjust */
+ {0x0, 0x0001, 0x0007}, /* TG FCDS Phase Adjust */
+ {0x0, 0x0039, 0x0008}, /* TG FS Phase Adjust */
+ {0x0, 0x0088, 0x000a}, /* TG MH1 */
+ {0x0, 0x0003, 0x000f}, /* TG Pixel ID */
+
+ /* Like below, unexplained toglleing */
+ {0x0, 0x0080, 0x000c},
+ {0x0, 0x0000, 0x000d},
+ {0x0, 0x0080, 0x000c},
+ {0x0, 0x0004, 0x000d},
+ {0x0, 0x0000, 0x000c},
+ {0x0, 0x0000, 0x000d},
+ {0x0, 0x0040, 0x000c},
+ {0x0, 0x0017, 0x000d},
+ {0x0, 0x00c0, 0x000c},
+ {0x0, 0x0000, 0x000d},
+ {0x0, 0x0080, 0x000c},
+ {0x0, 0x0006, 0x000d},
+ {0x0, 0x0080, 0x000c},
+ {0x0, 0x0004, 0x000d},
+ {0x0, 0x0002, 0x0003},
+#endif
+
+#ifdef DSPWIN_SET
+ {0x1, 0x001c, 0x0017}, /* CCDSP W1 Start X */
+ {0x1, 0x00e2, 0x0019}, /* CCDSP W2 Start X */
+ {0x1, 0x001c, 0x001b}, /* CCDSP W3 Start X */
+ {0x1, 0x00e2, 0x001d}, /* CCDSP W4 Start X */
+ {0x1, 0x00aa, 0x001f}, /* CCDSP W5 Start X */
+ {0x1, 0x0070, 0x0020}, /* CCDSP W5 Start Y */
+#endif
+ {0x0, 0x0001, 0x0010}, /* TG Start Clock */
+
+/* {0x2, 0x006a, 0x0001}, * C/S Enable ISOSYNCH Packet Engine */
+ {0x2, 0x0068, 0x0001}, /* C/S Diable ISOSYNCH Packet Engine */
+ {0x2, 0x0000, 0x0005},
+ {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */
+ {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */
+ {0x2, 0x0002, 0x0005}, /* C/S GPIO */
+ {0x2, 0x0003, 0x0005}, /* C/S GPIO */
+
+ {0x2, 0x006a, 0x0001}, /* C/S Enable ISOSYNCH Packet Engine */
+ {}
+};
+
+/*
+ * Data used to initialize a SPCA501C with HV7131B sensor.
+ * From a capture file taken with USBSnoop v 1.5
+ * I have a "SPCA501C pc camera chipset" manual by sunplus, but some
+ * of the value meanings are obscure or simply "reserved".
+ * to do list:
+ * 1) Understand what every value means
+ * 2) Understand why some values seem to appear more than once
+ * 3) Write a small comment for each line of the following arrays.
+ */
+static const __u16 spca501c_arowana_open_data[][3] = {
+ /* bmRequest,value,index */
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x01, 0x0006, 0x0011},
+ {0x01, 0x00ff, 0x0012},
+ {0x01, 0x0014, 0x0013},
+ {0x01, 0x0000, 0x0014},
+ {0x01, 0x0042, 0x0051},
+ {0x01, 0x0040, 0x0052},
+ {0x01, 0x0051, 0x0053},
+ {0x01, 0x0040, 0x0054},
+ {0x01, 0x0000, 0x0055},
+ {0x00, 0x0025, 0x0000},
+ {0x00, 0x0026, 0x0000},
+ {0x00, 0x0001, 0x0000},
+ {0x00, 0x0027, 0x0000},
+ {0x00, 0x008a, 0x0000},
+ {}
+};
+
+static const __u16 spca501c_arowana_init_data[][3] = {
+ /* bmRequest,value,index */
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x01, 0x0006, 0x0011},
+ {0x01, 0x00ff, 0x0012},
+ {0x01, 0x0014, 0x0013},
+ {0x01, 0x0000, 0x0014},
+ {0x01, 0x0042, 0x0051},
+ {0x01, 0x0040, 0x0052},
+ {0x01, 0x0051, 0x0053},
+ {0x01, 0x0040, 0x0054},
+ {0x01, 0x0000, 0x0055},
+ {0x00, 0x0025, 0x0000},
+ {0x00, 0x0026, 0x0000},
+ {0x00, 0x0001, 0x0000},
+ {0x00, 0x0027, 0x0000},
+ {0x00, 0x008a, 0x0000},
+ {0x02, 0x0000, 0x0005},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x000c, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0000, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021},
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023},
+ {0x00, 0x0000, 0x0024},
+ {0x00, 0x00d5, 0x0025},
+ {0x00, 0x0000, 0x0026},
+ {0x00, 0x000b, 0x0027},
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+ {0xff, 0x0000, 0x00d0},
+ {0xff, 0x00d8, 0x00d1},
+ {0xff, 0x0000, 0x00d4},
+ {0xff, 0x0000, 0x00d5},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003},
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0x00fd, 0x000a},
+ {0x01, 0x0038, 0x000b},
+ {0x01, 0x00d1, 0x000c},
+ {0x01, 0x00f7, 0x000d},
+ {0x01, 0x00ed, 0x000e},
+ {0x01, 0x00d8, 0x000f},
+ {0x01, 0x0038, 0x0010},
+ {0x01, 0x00ff, 0x0015},
+ {0x01, 0x0001, 0x0016},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020},
+ {0x01, 0x00ff, 0x003e},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0060, 0x0057},
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059},
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x100a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x000c, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0000, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021},
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023},
+ {0x00, 0x0000, 0x0024},
+ {0x00, 0x00d5, 0x0025},
+ {0x00, 0x0000, 0x0026},
+ {0x00, 0x000b, 0x0027},
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+ {0xff, 0x0000, 0x00d0},
+ {0xff, 0x00d8, 0x00d1},
+ {0xff, 0x0000, 0x00d4},
+ {0xff, 0x0000, 0x00d5},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003},
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0x00fd, 0x000a},
+ {0x01, 0x0038, 0x000b},
+ {0x01, 0x00d1, 0x000c},
+ {0x01, 0x00f7, 0x000d},
+ {0x01, 0x00ed, 0x000e},
+ {0x01, 0x00d8, 0x000f},
+ {0x01, 0x0038, 0x0010},
+ {0x01, 0x00ff, 0x0015},
+ {0x01, 0x0001, 0x0016},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020},
+ {0x01, 0x00ff, 0x003e},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0060, 0x0057},
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059},
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x100a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0xfffd, 0x000a},
+ {0x01, 0x0023, 0x000b},
+ {0x01, 0xffea, 0x000c},
+ {0x01, 0xfff4, 0x000d},
+ {0x01, 0xfffc, 0x000e},
+ {0x01, 0xffe3, 0x000f},
+ {0x01, 0x001f, 0x0010},
+ {0x01, 0x00a8, 0x0001},
+ {0x01, 0x0067, 0x0007},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x00c8, 0x0015},
+ {0x01, 0x0032, 0x0016},
+ {0x01, 0x0000, 0x0011},
+ {0x01, 0x0000, 0x0012},
+ {0x01, 0x0000, 0x0013},
+ {0x01, 0x000a, 0x0003},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xc000, 0x0001},
+ {0x02, 0x0000, 0x0005},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x000c, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0000, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021},
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023},
+ {0x00, 0x0000, 0x0024},
+ {0x00, 0x00d5, 0x0025},
+ {0x00, 0x0000, 0x0026},
+ {0x00, 0x000b, 0x0027},
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+ {0xff, 0x0000, 0x00d0},
+ {0xff, 0x00d8, 0x00d1},
+ {0xff, 0x0000, 0x00d4},
+ {0xff, 0x0000, 0x00d5},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003},
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0x00fd, 0x000a},
+ {0x01, 0x0038, 0x000b},
+ {0x01, 0x00d1, 0x000c},
+ {0x01, 0x00f7, 0x000d},
+ {0x01, 0x00ed, 0x000e},
+ {0x01, 0x00d8, 0x000f},
+ {0x01, 0x0038, 0x0010},
+ {0x01, 0x00ff, 0x0015},
+ {0x01, 0x0001, 0x0016},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020},
+ {0x01, 0x00ff, 0x003e},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0060, 0x0057},
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059},
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x100a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x000c, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0000, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021},
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023},
+ {0x00, 0x0000, 0x0024},
+ {0x00, 0x00d5, 0x0025},
+ {0x00, 0x0000, 0x0026},
+ {0x00, 0x000b, 0x0027},
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+ {0xff, 0x0000, 0x00d0},
+ {0xff, 0x00d8, 0x00d1},
+ {0xff, 0x0000, 0x00d4},
+ {0xff, 0x0000, 0x00d5},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003},
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0x00fd, 0x000a},
+ {0x01, 0x0038, 0x000b},
+ {0x01, 0x00d1, 0x000c},
+ {0x01, 0x00f7, 0x000d},
+ {0x01, 0x00ed, 0x000e},
+ {0x01, 0x00d8, 0x000f},
+ {0x01, 0x0038, 0x0010},
+ {0x01, 0x00ff, 0x0015},
+ {0x01, 0x0001, 0x0016},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020},
+ {0x01, 0x00ff, 0x003e},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0060, 0x0057},
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059},
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x100a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x000f, 0x0000},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0xfffd, 0x000a},
+ {0x01, 0x0023, 0x000b},
+ {0x01, 0xffea, 0x000c},
+ {0x01, 0xfff4, 0x000d},
+ {0x01, 0xfffc, 0x000e},
+ {0x01, 0xffe3, 0x000f},
+ {0x01, 0x001f, 0x0010},
+ {0x01, 0x00a8, 0x0001},
+ {0x01, 0x0067, 0x0007},
+ {0x01, 0x0042, 0x0051},
+ {0x01, 0x0051, 0x0053},
+ {0x01, 0x000a, 0x0003},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xc000, 0x0001},
+ {0x02, 0x0000, 0x0005},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x000c, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0000, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021},
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023},
+ {0x00, 0x0000, 0x0024},
+ {0x00, 0x00d5, 0x0025},
+ {0x00, 0x0000, 0x0026},
+ {0x00, 0x000b, 0x0027},
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+ {0xff, 0x0000, 0x00d0},
+ {0xff, 0x00d8, 0x00d1},
+ {0xff, 0x0000, 0x00d4},
+ {0xff, 0x0000, 0x00d5},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003},
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0x00fd, 0x000a},
+ {0x01, 0x0038, 0x000b},
+ {0x01, 0x00d1, 0x000c},
+ {0x01, 0x00f7, 0x000d},
+ {0x01, 0x00ed, 0x000e},
+ {0x01, 0x00d8, 0x000f},
+ {0x01, 0x0038, 0x0010},
+ {0x01, 0x00ff, 0x0015},
+ {0x01, 0x0001, 0x0016},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020},
+ {0x01, 0x00ff, 0x003e},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0060, 0x0057},
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059},
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x100a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x000c, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0000, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021},
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023},
+ {0x00, 0x0000, 0x0024},
+ {0x00, 0x00d5, 0x0025},
+ {0x00, 0x0000, 0x0026},
+ {0x00, 0x000b, 0x0027},
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+ {0xff, 0x0000, 0x00d0},
+ {0xff, 0x00d8, 0x00d1},
+ {0xff, 0x0000, 0x00d4},
+ {0xff, 0x0000, 0x00d5},
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003},
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0x00fd, 0x000a},
+ {0x01, 0x0038, 0x000b},
+ {0x01, 0x00d1, 0x000c},
+ {0x01, 0x00f7, 0x000d},
+ {0x01, 0x00ed, 0x000e},
+ {0x01, 0x00d8, 0x000f},
+ {0x01, 0x0038, 0x0010},
+ {0x01, 0x00ff, 0x0015},
+ {0x01, 0x0001, 0x0016},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020},
+ {0x01, 0x00ff, 0x003e},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0060, 0x0057},
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059},
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x100a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x001e, 0x0000},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x0011, 0x0008},
+ {0x01, 0x0032, 0x0009},
+ {0x01, 0xfffd, 0x000a},
+ {0x01, 0x0023, 0x000b},
+ {0x01, 0xffea, 0x000c},
+ {0x01, 0xfff4, 0x000d},
+ {0x01, 0xfffc, 0x000e},
+ {0x01, 0xffe3, 0x000f},
+ {0x01, 0x001f, 0x0010},
+ {0x01, 0x00a8, 0x0001},
+ {0x01, 0x0067, 0x0007},
+ {0x01, 0x0042, 0x0051},
+ {0x01, 0x0051, 0x0053},
+ {0x01, 0x000a, 0x0003},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x0007, 0x0005},
+ {0x01, 0x0042, 0x0051},
+ {0x01, 0x0051, 0x0053},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x002d, 0x0000},
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0001, 0x0056},
+ {0x02, 0xc000, 0x0001},
+ {0x02, 0x0000, 0x0005},
+ {}
+};
+
+/* Unknow camera from Ori Usbid 0x0000:0x0000 */
+/* Based on snoops from Ori Cohen */
+static const __u16 spca501c_mysterious_open_data[][3] = {
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+/* DSP Registers */
+ {0x01, 0x0016, 0x0011}, /* RGB offset */
+ {0x01, 0x0000, 0x0012},
+ {0x01, 0x0006, 0x0013},
+ {0x01, 0x0078, 0x0051},
+ {0x01, 0x0040, 0x0052},
+ {0x01, 0x0046, 0x0053},
+ {0x01, 0x0040, 0x0054},
+ {0x00, 0x0025, 0x0000},
+/* {0x00, 0x0000, 0x0000 }, */
+/* Part 2 */
+/* TG Registers */
+ {0x00, 0x0026, 0x0000},
+ {0x00, 0x0001, 0x0000},
+ {0x00, 0x0027, 0x0000},
+ {0x00, 0x008a, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x2000, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0015, 0x0001},
+ {0x05, 0x00ea, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0023, 0x0001},
+ {0x05, 0x0003, 0x0000},
+ {0x05, 0x0030, 0x0001},
+ {0x05, 0x002b, 0x0000},
+ {0x05, 0x0031, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0032, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0033, 0x0001},
+ {0x05, 0x0023, 0x0000},
+ {0x05, 0x0034, 0x0001},
+ {0x05, 0x0002, 0x0000},
+ {0x05, 0x0050, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0051, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0052, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0054, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {}
+};
+
+/* Based on snoops from Ori Cohen */
+static const __u16 spca501c_mysterious_init_data[][3] = {
+/* Part 3 */
+/* TG registers */
+/* {0x00, 0x0000, 0x0000}, */
+ {0x00, 0x0000, 0x0001},
+ {0x00, 0x0000, 0x0002},
+ {0x00, 0x0006, 0x0003},
+ {0x00, 0x0000, 0x0004},
+ {0x00, 0x0090, 0x0005},
+ {0x00, 0x0000, 0x0006},
+ {0x00, 0x0040, 0x0007},
+ {0x00, 0x00c0, 0x0008},
+ {0x00, 0x004a, 0x0009},
+ {0x00, 0x0000, 0x000a},
+ {0x00, 0x0000, 0x000b},
+ {0x00, 0x0001, 0x000c},
+ {0x00, 0x0001, 0x000d},
+ {0x00, 0x0000, 0x000e},
+ {0x00, 0x0002, 0x000f},
+ {0x00, 0x0001, 0x0010},
+ {0x00, 0x0000, 0x0011},
+ {0x00, 0x0001, 0x0012},
+ {0x00, 0x0002, 0x0020},
+ {0x00, 0x0080, 0x0021}, /* 640 */
+ {0x00, 0x0001, 0x0022},
+ {0x00, 0x00e0, 0x0023}, /* 480 */
+ {0x00, 0x0000, 0x0024}, /* Offset H hight */
+ {0x00, 0x00d3, 0x0025}, /* low */
+ {0x00, 0x0000, 0x0026}, /* Offset V */
+ {0x00, 0x000d, 0x0027}, /* low */
+ {0x00, 0x0000, 0x0046},
+ {0x00, 0x0000, 0x0047},
+ {0x00, 0x0000, 0x0048},
+ {0x00, 0x0000, 0x0049},
+ {0x00, 0x0008, 0x004a},
+/* DSP Registers */
+ {0x01, 0x00a6, 0x0000},
+ {0x01, 0x0028, 0x0001},
+ {0x01, 0x0000, 0x0002},
+ {0x01, 0x000a, 0x0003}, /* Level Calc bit7 ->1 Auto */
+ {0x01, 0x0040, 0x0004},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x000f, 0x0008}, /* A11 Color correction coeff */
+ {0x01, 0x002d, 0x0009}, /* A12 */
+ {0x01, 0x0005, 0x000a}, /* A13 */
+ {0x01, 0x0023, 0x000b}, /* A21 */
+ {0x01, 0x00e0, 0x000c}, /* A22 */
+ {0x01, 0x00fd, 0x000d}, /* A23 */
+ {0x01, 0x00f4, 0x000e}, /* A31 */
+ {0x01, 0x00e4, 0x000f}, /* A32 */
+ {0x01, 0x0028, 0x0010}, /* A33 */
+ {0x01, 0x00ff, 0x0015}, /* Reserved */
+ {0x01, 0x0001, 0x0016}, /* Reserved */
+ {0x01, 0x0032, 0x0017}, /* Win1 Start begin */
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x0000, 0x001f},
+ {0x01, 0x0000, 0x0020}, /* Win1 Start end */
+ {0x01, 0x00ff, 0x003e}, /* Reserved begin */
+ {0x01, 0x0002, 0x003f},
+ {0x01, 0x0000, 0x0040},
+ {0x01, 0x0035, 0x0041},
+ {0x01, 0x0053, 0x0042},
+ {0x01, 0x0069, 0x0043},
+ {0x01, 0x007c, 0x0044},
+ {0x01, 0x008c, 0x0045},
+ {0x01, 0x009a, 0x0046},
+ {0x01, 0x00a8, 0x0047},
+ {0x01, 0x00b4, 0x0048},
+ {0x01, 0x00bf, 0x0049},
+ {0x01, 0x00ca, 0x004a},
+ {0x01, 0x00d4, 0x004b},
+ {0x01, 0x00dd, 0x004c},
+ {0x01, 0x00e7, 0x004d},
+ {0x01, 0x00ef, 0x004e},
+ {0x01, 0x00f8, 0x004f},
+ {0x01, 0x00ff, 0x0050},
+ {0x01, 0x0003, 0x0056}, /* Reserved end */
+ {0x01, 0x0060, 0x0057}, /* Edge Gain */
+ {0x01, 0x0040, 0x0058},
+ {0x01, 0x0011, 0x0059}, /* Edge Bandwidth */
+ {0x01, 0x0001, 0x005a},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0x0007, 0x0005},
+ {0x02, 0x0015, 0x0006},
+ {0x02, 0x200a, 0x0007},
+ {0x02, 0xa048, 0x0000},
+ {0x02, 0xc000, 0x0001},
+ {0x02, 0x000f, 0x0005},
+ {0x02, 0xa048, 0x0000},
+ {0x05, 0x0022, 0x0004},
+ {0x05, 0x0025, 0x0001},
+ {0x05, 0x0000, 0x0000},
+/* Part 4 */
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0001, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x05, 0x0021, 0x0001},
+ {0x05, 0x00d2, 0x0000},
+ {0x05, 0x0020, 0x0001},
+ {0x05, 0x0000, 0x0000},
+ {0x00, 0x0090, 0x0005},
+ {0x01, 0x00a6, 0x0000},
+ {0x02, 0x0000, 0x0005},
+ {0x05, 0x0026, 0x0001},
+ {0x05, 0x0001, 0x0000},
+ {0x05, 0x0027, 0x0001},
+ {0x05, 0x004e, 0x0000},
+/* Part 5 */
+ {0x01, 0x0003, 0x003f},
+ {0x01, 0x0001, 0x0056},
+ {0x01, 0x000f, 0x0008},
+ {0x01, 0x002d, 0x0009},
+ {0x01, 0x0005, 0x000a},
+ {0x01, 0x0023, 0x000b},
+ {0x01, 0xffe0, 0x000c},
+ {0x01, 0xfffd, 0x000d},
+ {0x01, 0xfff4, 0x000e},
+ {0x01, 0xffe4, 0x000f},
+ {0x01, 0x0028, 0x0010},
+ {0x01, 0x00a8, 0x0001},
+ {0x01, 0x0066, 0x0007},
+ {0x01, 0x0032, 0x0017},
+ {0x01, 0x0023, 0x0018},
+ {0x01, 0x00ce, 0x0019},
+ {0x01, 0x0023, 0x001a},
+ {0x01, 0x0032, 0x001b},
+ {0x01, 0x008d, 0x001c},
+ {0x01, 0x00ce, 0x001d},
+ {0x01, 0x008d, 0x001e},
+ {0x01, 0x00c8, 0x0015}, /* c8 Poids fort Luma */
+ {0x01, 0x0032, 0x0016}, /* 32 */
+ {0x01, 0x0016, 0x0011}, /* R 00 */
+ {0x01, 0x0016, 0x0012}, /* G 00 */
+ {0x01, 0x0016, 0x0013}, /* B 00 */
+ {0x01, 0x000a, 0x0003},
+ {0x02, 0xc002, 0x0001},
+ {0x02, 0x0007, 0x0005},
+ {}
+};
+
+static int reg_write(struct usb_device *dev,
+ __u16 req, __u16 index, __u16 value)
+{
+ int ret;
+
+ ret = usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ req,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 500);
+ PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x",
+ req, index, value);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write: error %d", ret);
+ return ret;
+}
+
+/* returns: negative is error, pos or zero is data */
+static int reg_read(struct gspca_dev *gspca_dev,
+ __u16 req, /* bRequest */
+ __u16 index, /* wIndex */
+ __u16 length) /* wLength (1 or 2 only) */
+{
+ int ret;
+
+ gspca_dev->usb_buf[1] = 0;
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, length,
+ 500); /* timeout */
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_read err %d", ret);
+ return -1;
+ }
+ return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
+}
+
+static int write_vector(struct gspca_dev *gspca_dev,
+ const __u16 data[][3])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, i = 0;
+
+ while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
+ if (ret < 0) {
+ PDEBUG(D_ERR,
+ "Reg write failed for 0x%02x,0x%02x,0x%02x",
+ data[i][0], data[i][1], data[i][2]);
+ return ret;
+ }
+ i++;
+ }
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness);
+ reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
+ reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness);
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 brightness;
+
+ brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2);
+ sd->brightness = brightness << 1;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_write(gspca_dev->dev, 0x00, 0x00,
+ (sd->contrast >> 8) & 0xff);
+ reg_write(gspca_dev->dev, 0x00, 0x01,
+ sd->contrast & 0xff);
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+/* spca50x->contrast = 0xaa01; */
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors);
+}
+
+static void getcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2);
+/* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */
+/* 2) & 0xFF) << 8; */
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 vendor;
+ __u16 product;
+
+ vendor = id->idVendor;
+ product = id->idProduct;
+ switch (vendor) {
+ case 0x0000: /* Unknow Camera */
+/* switch (product) { */
+/* case 0x0000: */
+ sd->subtype = MystFromOriUnknownCamera;
+/* break; */
+/* } */
+ break;
+ case 0x040a: /* Kodak cameras */
+/* switch (product) { */
+/* case 0x0002: */
+ sd->subtype = KodakDVC325;
+/* break; */
+/* } */
+ break;
+ case 0x0497: /* Smile International */
+/* switch (product) { */
+/* case 0xc001: */
+ sd->subtype = SmileIntlCamera;
+/* break; */
+/* } */
+ break;
+ case 0x0506: /* 3COM cameras */
+/* switch (product) { */
+/* case 0x00df: */
+ sd->subtype = ThreeComHomeConnectLite;
+/* break; */
+/* } */
+ break;
+ case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
+ switch (product) {
+ case 0x0401:
+ sd->subtype = IntelCreateAndShare;
+ break;
+ case 0x0402:
+ sd->subtype = ViewQuestM318B;
+ break;
+ }
+ break;
+ case 0x1776: /* Arowana */
+/* switch (product) { */
+/* case 0x501c: */
+ sd->subtype = Arowana300KCMOSCamera;
+/* break; */
+/* } */
+ break;
+ }
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
+ sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value;
+
+ switch (sd->subtype) {
+ case Arowana300KCMOSCamera:
+ case SmileIntlCamera:
+ /* Arowana 300k CMOS Camera data */
+ if (write_vector(gspca_dev, spca501c_arowana_init_data))
+ goto error;
+ break;
+ case MystFromOriUnknownCamera:
+ /* UnKnow Ori CMOS Camera data */
+ if (write_vector(gspca_dev, spca501c_mysterious_open_data))
+ goto error;
+ break;
+ default:
+ /* generic spca501 init data */
+ if (write_vector(gspca_dev, spca501_init_data))
+ goto error;
+ break;
+ }
+ return 0;
+error:
+ return -EINVAL;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->subtype) {
+ case ThreeComHomeConnectLite:
+ /* Special handling for 3com data */
+ write_vector(gspca_dev, spca501_3com_open_data);
+ break;
+ case Arowana300KCMOSCamera:
+ case SmileIntlCamera:
+ /* Arowana 300k CMOS Camera data */
+ write_vector(gspca_dev, spca501c_arowana_open_data);
+ break;
+ case MystFromOriUnknownCamera:
+ /* UnKnow CMOS Camera data */
+ write_vector(gspca_dev, spca501c_mysterious_init_data);
+ break;
+ default:
+ /* Generic 501 open data */
+ write_vector(gspca_dev, spca501_open_data);
+ }
+ PDEBUG(D_STREAM, "Initializing SPCA501 finished");
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int mode;
+
+ /* memorize the wanted pixel format */
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+
+ /* Enable ISO packet machine CTRL reg=2,
+ * index=1 bitmask=0x2 (bit ordinal 1) */
+ reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94);
+ switch (mode) {
+ case 0: /* 640x480 */
+ reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a);
+ break;
+ case 1: /* 320x240 */
+ reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a);
+ break;
+ default:
+/* case 2: * 160x120 */
+ reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a);
+ break;
+ }
+ reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02);
+
+ /* HDG atleast the Intel CreateAndShare needs to have one of its
+ * brightness / contrast / color set otherwise it assumes what seems
+ * max contrast. Note that strange enough setting any of these is
+ * enough to fix the max contrast problem, to be sure we set all 3 */
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+ setcolors(gspca_dev);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ /* Disable ISO packet
+ * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */
+ reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+ reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ switch (data[0]) {
+ case 0: /* start of frame */
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ data, 0);
+ data += SPCA501_OFFSET_DATA;
+ len -= SPCA501_OFFSET_DATA;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ return;
+ case 0xff: /* drop */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ data++;
+ len--;
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcontrast(gspca_dev);
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcolors(gspca_dev);
+ *val = sd->colors;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")},
+ {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")},
+ {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")},
+ {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")},
+ {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")},
+ {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")},
+ {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
new file mode 100644
index 00000000000..ddea6e140aa
--- /dev/null
+++ b/drivers/media/video/gspca/spca505.c
@@ -0,0 +1,951 @@
+/*
+ * SPCA505 chip based cameras initialization data
+ *
+ * V4L2 by Jean-Francis Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define MODULE_NAME "spca505"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ int buflen;
+ unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */
+ unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */
+
+ unsigned char brightness;
+
+ char subtype;
+#define IntelPCCameraPro 0
+#define Nxultra 1
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 127,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 160 * 2,
+ .sizeimage = 160 * 120 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 5},
+ {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 176 * 2,
+ .sizeimage = 176 * 144 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+ {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 320 * 2,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 352 * 2,
+ .sizeimage = 352 * 288 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 640 * 2,
+ .sizeimage = 640 * 480 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+#define SPCA50X_OFFSET_DATA 10
+
+#define SPCA50X_REG_USB 0x02 /* spca505 501 */
+
+#define SPCA50X_USB_CTRL 0x00 /* spca505 */
+#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
+#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
+#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
+#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
+
+#define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */
+#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
+#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */
+
+/*
+ * Data to initialize a SPCA505. Common to the CCD and external modes
+ */
+static const __u16 spca505_init_data[][3] = {
+ /* line bmRequest,value,index */
+ /* 1819 */
+ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
+ /* Sensor reset */
+ /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
+ /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
+ /* Block USB reset */
+ /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL,
+ SPCA50X_GLOBAL_MISC0},
+
+ /* 1831 */ {0x5, 0x01, 0x10},
+ /* Maybe power down some stuff */
+ /* 1834 */ {0x5, 0x0f, 0x11},
+
+ /* Setup internal CCD ? */
+ /* 1837 */ {0x6, 0x10, 0x08},
+ /* 1840 */ {0x6, 0x00, 0x09},
+ /* 1843 */ {0x6, 0x00, 0x0a},
+ /* 1846 */ {0x6, 0x00, 0x0b},
+ /* 1849 */ {0x6, 0x10, 0x0c},
+ /* 1852 */ {0x6, 0x00, 0x0d},
+ /* 1855 */ {0x6, 0x00, 0x0e},
+ /* 1858 */ {0x6, 0x00, 0x0f},
+ /* 1861 */ {0x6, 0x10, 0x10},
+ /* 1864 */ {0x6, 0x02, 0x11},
+ /* 1867 */ {0x6, 0x00, 0x12},
+ /* 1870 */ {0x6, 0x04, 0x13},
+ /* 1873 */ {0x6, 0x02, 0x14},
+ /* 1876 */ {0x6, 0x8a, 0x51},
+ /* 1879 */ {0x6, 0x40, 0x52},
+ /* 1882 */ {0x6, 0xb6, 0x53},
+ /* 1885 */ {0x6, 0x3d, 0x54},
+ {}
+};
+
+/*
+ * Data to initialize the camera using the internal CCD
+ */
+static const __u16 spca505_open_data_ccd[][3] = {
+ /* line bmRequest,value,index */
+ /* Internal CCD data set */
+ /* 1891 */ {0x3, 0x04, 0x01},
+ /* This could be a reset */
+ /* 1894 */ {0x3, 0x00, 0x01},
+
+ /* Setup compression and image registers. 0x6 and 0x7 seem to be
+ related to H&V hold, and are resolution mode specific */
+ /* 1897 */ {0x4, 0x10, 0x01},
+ /* DIFF(0x50), was (0x10) */
+ /* 1900 */ {0x4, 0x00, 0x04},
+ /* 1903 */ {0x4, 0x00, 0x05},
+ /* 1906 */ {0x4, 0x20, 0x06},
+ /* 1909 */ {0x4, 0x20, 0x07},
+
+ /* 1912 */ {0x8, 0x0a, 0x00},
+ /* DIFF (0x4a), was (0xa) */
+
+ /* 1915 */ {0x5, 0x00, 0x10},
+ /* 1918 */ {0x5, 0x00, 0x11},
+ /* 1921 */ {0x5, 0x00, 0x00},
+ /* DIFF not written */
+ /* 1924 */ {0x5, 0x00, 0x01},
+ /* DIFF not written */
+ /* 1927 */ {0x5, 0x00, 0x02},
+ /* DIFF not written */
+ /* 1930 */ {0x5, 0x00, 0x03},
+ /* DIFF not written */
+ /* 1933 */ {0x5, 0x00, 0x04},
+ /* DIFF not written */
+ /* 1936 */ {0x5, 0x80, 0x05},
+ /* DIFF not written */
+ /* 1939 */ {0x5, 0xe0, 0x06},
+ /* DIFF not written */
+ /* 1942 */ {0x5, 0x20, 0x07},
+ /* DIFF not written */
+ /* 1945 */ {0x5, 0xa0, 0x08},
+ /* DIFF not written */
+ /* 1948 */ {0x5, 0x0, 0x12},
+ /* DIFF not written */
+ /* 1951 */ {0x5, 0x02, 0x0f},
+ /* DIFF not written */
+ /* 1954 */ {0x5, 0x10, 0x46},
+ /* DIFF not written */
+ /* 1957 */ {0x5, 0x8, 0x4a},
+ /* DIFF not written */
+
+ /* 1960 */ {0x3, 0x08, 0x03},
+ /* DIFF (0x3,0x28,0x3) */
+ /* 1963 */ {0x3, 0x08, 0x01},
+ /* 1966 */ {0x3, 0x0c, 0x03},
+ /* DIFF not written */
+ /* 1969 */ {0x3, 0x21, 0x00},
+ /* DIFF (0x39) */
+
+/* Extra block copied from init to hopefully ensure CCD is in a sane state */
+ /* 1837 */ {0x6, 0x10, 0x08},
+ /* 1840 */ {0x6, 0x00, 0x09},
+ /* 1843 */ {0x6, 0x00, 0x0a},
+ /* 1846 */ {0x6, 0x00, 0x0b},
+ /* 1849 */ {0x6, 0x10, 0x0c},
+ /* 1852 */ {0x6, 0x00, 0x0d},
+ /* 1855 */ {0x6, 0x00, 0x0e},
+ /* 1858 */ {0x6, 0x00, 0x0f},
+ /* 1861 */ {0x6, 0x10, 0x10},
+ /* 1864 */ {0x6, 0x02, 0x11},
+ /* 1867 */ {0x6, 0x00, 0x12},
+ /* 1870 */ {0x6, 0x04, 0x13},
+ /* 1873 */ {0x6, 0x02, 0x14},
+ /* 1876 */ {0x6, 0x8a, 0x51},
+ /* 1879 */ {0x6, 0x40, 0x52},
+ /* 1882 */ {0x6, 0xb6, 0x53},
+ /* 1885 */ {0x6, 0x3d, 0x54},
+ /* End of extra block */
+
+ /* 1972 */ {0x6, 0x3f, 0x1},
+ /* Block skipped */
+ /* 1975 */ {0x6, 0x10, 0x02},
+ /* 1978 */ {0x6, 0x64, 0x07},
+ /* 1981 */ {0x6, 0x10, 0x08},
+ /* 1984 */ {0x6, 0x00, 0x09},
+ /* 1987 */ {0x6, 0x00, 0x0a},
+ /* 1990 */ {0x6, 0x00, 0x0b},
+ /* 1993 */ {0x6, 0x10, 0x0c},
+ /* 1996 */ {0x6, 0x00, 0x0d},
+ /* 1999 */ {0x6, 0x00, 0x0e},
+ /* 2002 */ {0x6, 0x00, 0x0f},
+ /* 2005 */ {0x6, 0x10, 0x10},
+ /* 2008 */ {0x6, 0x02, 0x11},
+ /* 2011 */ {0x6, 0x00, 0x12},
+ /* 2014 */ {0x6, 0x04, 0x13},
+ /* 2017 */ {0x6, 0x02, 0x14},
+ /* 2020 */ {0x6, 0x8a, 0x51},
+ /* 2023 */ {0x6, 0x40, 0x52},
+ /* 2026 */ {0x6, 0xb6, 0x53},
+ /* 2029 */ {0x6, 0x3d, 0x54},
+ /* 2032 */ {0x6, 0x60, 0x57},
+ /* 2035 */ {0x6, 0x20, 0x58},
+ /* 2038 */ {0x6, 0x15, 0x59},
+ /* 2041 */ {0x6, 0x05, 0x5a},
+
+ /* 2044 */ {0x5, 0x01, 0xc0},
+ /* 2047 */ {0x5, 0x10, 0xcb},
+ /* 2050 */ {0x5, 0x80, 0xc1},
+ /* */
+ /* 2053 */ {0x5, 0x0, 0xc2},
+ /* 4 was 0 */
+ /* 2056 */ {0x5, 0x00, 0xca},
+ /* 2059 */ {0x5, 0x80, 0xc1},
+ /* */
+ /* 2062 */ {0x5, 0x04, 0xc2},
+ /* 2065 */ {0x5, 0x00, 0xca},
+ /* 2068 */ {0x5, 0x0, 0xc1},
+ /* */
+ /* 2071 */ {0x5, 0x00, 0xc2},
+ /* 2074 */ {0x5, 0x00, 0xca},
+ /* 2077 */ {0x5, 0x40, 0xc1},
+ /* */
+ /* 2080 */ {0x5, 0x17, 0xc2},
+ /* 2083 */ {0x5, 0x00, 0xca},
+ /* 2086 */ {0x5, 0x80, 0xc1},
+ /* */
+ /* 2089 */ {0x5, 0x06, 0xc2},
+ /* 2092 */ {0x5, 0x00, 0xca},
+ /* 2095 */ {0x5, 0x80, 0xc1},
+ /* */
+ /* 2098 */ {0x5, 0x04, 0xc2},
+ /* 2101 */ {0x5, 0x00, 0xca},
+
+ /* 2104 */ {0x3, 0x4c, 0x3},
+ /* 2107 */ {0x3, 0x18, 0x1},
+
+ /* 2110 */ {0x6, 0x70, 0x51},
+ /* 2113 */ {0x6, 0xbe, 0x53},
+ /* 2116 */ {0x6, 0x71, 0x57},
+ /* 2119 */ {0x6, 0x20, 0x58},
+ /* 2122 */ {0x6, 0x05, 0x59},
+ /* 2125 */ {0x6, 0x15, 0x5a},
+
+ /* 2128 */ {0x4, 0x00, 0x08},
+ /* Compress = OFF (0x1 to turn on) */
+ /* 2131 */ {0x4, 0x12, 0x09},
+ /* 2134 */ {0x4, 0x21, 0x0a},
+ /* 2137 */ {0x4, 0x10, 0x0b},
+ /* 2140 */ {0x4, 0x21, 0x0c},
+ /* 2143 */ {0x4, 0x05, 0x00},
+ /* was 5 (Image Type ? ) */
+ /* 2146 */ {0x4, 0x00, 0x01},
+
+ /* 2149 */ {0x6, 0x3f, 0x01},
+
+ /* 2152 */ {0x4, 0x00, 0x04},
+ /* 2155 */ {0x4, 0x00, 0x05},
+ /* 2158 */ {0x4, 0x40, 0x06},
+ /* 2161 */ {0x4, 0x40, 0x07},
+
+ /* 2164 */ {0x6, 0x1c, 0x17},
+ /* 2167 */ {0x6, 0xe2, 0x19},
+ /* 2170 */ {0x6, 0x1c, 0x1b},
+ /* 2173 */ {0x6, 0xe2, 0x1d},
+ /* 2176 */ {0x6, 0xaa, 0x1f},
+ /* 2179 */ {0x6, 0x70, 0x20},
+
+ /* 2182 */ {0x5, 0x01, 0x10},
+ /* 2185 */ {0x5, 0x00, 0x11},
+ /* 2188 */ {0x5, 0x01, 0x00},
+ /* 2191 */ {0x5, 0x05, 0x01},
+ /* 2194 */ {0x5, 0x00, 0xc1},
+ /* */
+ /* 2197 */ {0x5, 0x00, 0xc2},
+ /* 2200 */ {0x5, 0x00, 0xca},
+
+ /* 2203 */ {0x6, 0x70, 0x51},
+ /* 2206 */ {0x6, 0xbe, 0x53},
+ {}
+};
+
+/*
+ Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
+ * SPCA505b chip based cameras initialization data
+ *
+ */
+/* jfm */
+#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
+/* #define initial_brightness 0x0 //0x0(white)-0xff(black) */
+/*
+ * Data to initialize a SPCA505. Common to the CCD and external modes
+ */
+static const __u16 spca505b_init_data[][3] = {
+/* start */
+ {0x02, 0x00, 0x00}, /* init */
+ {0x02, 0x00, 0x01},
+ {0x02, 0x00, 0x02},
+ {0x02, 0x00, 0x03},
+ {0x02, 0x00, 0x04},
+ {0x02, 0x00, 0x05},
+ {0x02, 0x00, 0x06},
+ {0x02, 0x00, 0x07},
+ {0x02, 0x00, 0x08},
+ {0x02, 0x00, 0x09},
+ {0x03, 0x00, 0x00},
+ {0x03, 0x00, 0x01},
+ {0x03, 0x00, 0x02},
+ {0x03, 0x00, 0x03},
+ {0x03, 0x00, 0x04},
+ {0x03, 0x00, 0x05},
+ {0x03, 0x00, 0x06},
+ {0x04, 0x00, 0x00},
+ {0x04, 0x00, 0x02},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x00, 0x06},
+ {0x04, 0x00, 0x07},
+ {0x04, 0x00, 0x08},
+ {0x04, 0x00, 0x09},
+ {0x04, 0x00, 0x0a},
+ {0x04, 0x00, 0x0b},
+ {0x04, 0x00, 0x0c},
+ {0x07, 0x00, 0x00},
+ {0x07, 0x00, 0x03},
+ {0x08, 0x00, 0x00},
+ {0x08, 0x00, 0x01},
+ {0x08, 0x00, 0x02},
+ {0x00, 0x01, 0x00},
+ {0x00, 0x01, 0x01},
+ {0x00, 0x01, 0x34},
+ {0x00, 0x01, 0x35},
+ {0x06, 0x18, 0x08},
+ {0x06, 0xfc, 0x09},
+ {0x06, 0xfc, 0x0a},
+ {0x06, 0xfc, 0x0b},
+ {0x06, 0x18, 0x0c},
+ {0x06, 0xfc, 0x0d},
+ {0x06, 0xfc, 0x0e},
+ {0x06, 0xfc, 0x0f},
+ {0x06, 0x18, 0x10},
+ {0x06, 0xfe, 0x12},
+ {0x06, 0x00, 0x11},
+ {0x06, 0x00, 0x14},
+ {0x06, 0x00, 0x13},
+ {0x06, 0x28, 0x51},
+ {0x06, 0xff, 0x53},
+ {0x02, 0x00, 0x08},
+
+ {0x03, 0x00, 0x03},
+ {0x03, 0x10, 0x03},
+ {}
+};
+
+/*
+ * Data to initialize the camera using the internal CCD
+ */
+static const __u16 spca505b_open_data_ccd[][3] = {
+
+/* {0x02,0x00,0x00}, */
+ {0x03, 0x04, 0x01}, /* rst */
+ {0x03, 0x00, 0x01},
+ {0x03, 0x00, 0x00},
+ {0x03, 0x21, 0x00},
+ {0x03, 0x00, 0x04},
+ {0x03, 0x00, 0x03},
+ {0x03, 0x18, 0x03},
+ {0x03, 0x08, 0x01},
+ {0x03, 0x1c, 0x03},
+ {0x03, 0x5c, 0x03},
+ {0x03, 0x5c, 0x03},
+ {0x03, 0x18, 0x01},
+
+/* same as 505 */
+ {0x04, 0x10, 0x01},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x20, 0x06},
+ {0x04, 0x20, 0x07},
+
+ {0x08, 0x0a, 0x00},
+
+ {0x05, 0x00, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x00, 0x12},
+ {0x05, 0x6f, 0x00},
+ {0x05, initial_brightness >> 6, 0x00},
+ {0x05, initial_brightness << 2, 0x01},
+ {0x05, 0x00, 0x02},
+ {0x05, 0x01, 0x03},
+ {0x05, 0x00, 0x04},
+ {0x05, 0x03, 0x05},
+ {0x05, 0xe0, 0x06},
+ {0x05, 0x20, 0x07},
+ {0x05, 0xa0, 0x08},
+ {0x05, 0x00, 0x12},
+ {0x05, 0x02, 0x0f},
+ {0x05, 128, 0x14}, /* max exposure off (0=on) */
+ {0x05, 0x01, 0xb0},
+ {0x05, 0x01, 0xbf},
+ {0x03, 0x02, 0x06},
+ {0x05, 0x10, 0x46},
+ {0x05, 0x08, 0x4a},
+
+ {0x06, 0x00, 0x01},
+ {0x06, 0x10, 0x02},
+ {0x06, 0x64, 0x07},
+ {0x06, 0x18, 0x08},
+ {0x06, 0xfc, 0x09},
+ {0x06, 0xfc, 0x0a},
+ {0x06, 0xfc, 0x0b},
+ {0x04, 0x00, 0x01},
+ {0x06, 0x18, 0x0c},
+ {0x06, 0xfc, 0x0d},
+ {0x06, 0xfc, 0x0e},
+ {0x06, 0xfc, 0x0f},
+ {0x06, 0x11, 0x10}, /* contrast */
+ {0x06, 0x00, 0x11},
+ {0x06, 0xfe, 0x12},
+ {0x06, 0x00, 0x13},
+ {0x06, 0x00, 0x14},
+ {0x06, 0x9d, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0x7c, 0x53},
+ {0x06, 0x40, 0x54},
+ {0x06, 0x02, 0x57},
+ {0x06, 0x03, 0x58},
+ {0x06, 0x15, 0x59},
+ {0x06, 0x05, 0x5a},
+ {0x06, 0x03, 0x56},
+ {0x06, 0x02, 0x3f},
+ {0x06, 0x00, 0x40},
+ {0x06, 0x39, 0x41},
+ {0x06, 0x69, 0x42},
+ {0x06, 0x87, 0x43},
+ {0x06, 0x9e, 0x44},
+ {0x06, 0xb1, 0x45},
+ {0x06, 0xbf, 0x46},
+ {0x06, 0xcc, 0x47},
+ {0x06, 0xd5, 0x48},
+ {0x06, 0xdd, 0x49},
+ {0x06, 0xe3, 0x4a},
+ {0x06, 0xe8, 0x4b},
+ {0x06, 0xed, 0x4c},
+ {0x06, 0xf2, 0x4d},
+ {0x06, 0xf7, 0x4e},
+ {0x06, 0xfc, 0x4f},
+ {0x06, 0xff, 0x50},
+
+ {0x05, 0x01, 0xc0},
+ {0x05, 0x10, 0xcb},
+ {0x05, 0x40, 0xc1},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x40, 0xc1},
+ {0x05, 0x09, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0xc0, 0xc1},
+ {0x05, 0x09, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x40, 0xc1},
+ {0x05, 0x59, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x04, 0x00, 0x01},
+ {0x05, 0x80, 0xc1},
+ {0x05, 0xec, 0xc2},
+ {0x05, 0x0, 0xca},
+
+ {0x06, 0x02, 0x57},
+ {0x06, 0x01, 0x58},
+ {0x06, 0x15, 0x59},
+ {0x06, 0x0a, 0x5a},
+ {0x06, 0x01, 0x57},
+ {0x06, 0x8a, 0x03},
+ {0x06, 0x0a, 0x6c},
+ {0x06, 0x30, 0x01},
+ {0x06, 0x20, 0x02},
+ {0x06, 0x00, 0x03},
+
+ {0x05, 0x8c, 0x25},
+
+ {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */
+ {0x06, 0x84, 0x53}, /* making green (84) */
+ {0x06, 0x00, 0x57}, /* sharpness (1) */
+ {0x06, 0x18, 0x08},
+ {0x06, 0xfc, 0x09},
+ {0x06, 0xfc, 0x0a},
+ {0x06, 0xfc, 0x0b},
+ {0x06, 0x18, 0x0c}, /* maybe hue (18) */
+ {0x06, 0xfc, 0x0d},
+ {0x06, 0xfc, 0x0e},
+ {0x06, 0xfc, 0x0f},
+ {0x06, 0x18, 0x10}, /* maybe contrast (18) */
+
+ {0x05, 0x01, 0x02},
+
+ {0x04, 0x00, 0x08}, /* compression */
+ {0x04, 0x12, 0x09},
+ {0x04, 0x21, 0x0a},
+ {0x04, 0x10, 0x0b},
+ {0x04, 0x21, 0x0c},
+ {0x04, 0x1d, 0x00}, /* imagetype (1d) */
+ {0x04, 0x41, 0x01}, /* hardware snapcontrol */
+
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x10, 0x06},
+ {0x04, 0x10, 0x07},
+ {0x04, 0x40, 0x06},
+ {0x04, 0x40, 0x07},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+
+ {0x06, 0x1c, 0x17},
+ {0x06, 0xe2, 0x19},
+ {0x06, 0x1c, 0x1b},
+ {0x06, 0xe2, 0x1d},
+ {0x06, 0x5f, 0x1f},
+ {0x06, 0x32, 0x20},
+
+ {0x05, initial_brightness >> 6, 0x00},
+ {0x05, initial_brightness << 2, 0x01},
+ {0x05, 0x06, 0xc1},
+ {0x05, 0x58, 0xc2},
+ {0x05, 0x0, 0xca},
+ {0x05, 0x0, 0x11},
+ {}
+};
+
+static int reg_write(struct usb_device *dev,
+ __u16 reg, __u16 index, __u16 value)
+{
+ int ret;
+
+ ret = usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ reg,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 500);
+ PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x",
+ reg, index, value, ret);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write: error %d", ret);
+ return ret;
+}
+
+/* returns: negative is error, pos or zero is data */
+static int reg_read(struct gspca_dev *gspca_dev,
+ __u16 reg, /* bRequest */
+ __u16 index, /* wIndex */
+ __u16 length) /* wLength (1 or 2 only) */
+{
+ int ret;
+
+ gspca_dev->usb_buf[1] = 0;
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ reg,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ (__u16) 0, /* value */
+ (__u16) index,
+ gspca_dev->usb_buf, length,
+ 500); /* timeout */
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_read err %d", ret);
+ return -1;
+ }
+ return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
+}
+
+static int write_vector(struct gspca_dev *gspca_dev,
+ const __u16 data[][3])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, i = 0;
+
+ while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
+ if (ret < 0) {
+ PDEBUG(D_ERR,
+ "Register write failed for 0x%x,0x%x,0x%x",
+ data[i][0], data[i][1], data[i][2]);
+ return ret;
+ }
+ i++;
+ }
+ return 0;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 vendor;
+ __u16 product;
+
+ vendor = id->idVendor;
+ product = id->idProduct;
+ switch (vendor) {
+ case 0x041e: /* Creative cameras */
+/* switch (product) { */
+/* case 0x401d: * here505b */
+ sd->subtype = Nxultra;
+/* break; */
+/* } */
+ break;
+ case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
+/* switch (product) { */
+/* case 0x0430: */
+/* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */
+ sd->subtype = IntelPCCameraPro;
+/* break; */
+/* } */
+ break;
+ }
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = vga_mode;
+ if (sd->subtype != IntelPCCameraPro)
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ else /* no 640x480 for IntelPCCameraPro */
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1;
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+
+ if (sd->subtype == Nxultra) {
+ if (write_vector(gspca_dev, spca505b_init_data))
+ return -EIO;
+ } else {
+ if (write_vector(gspca_dev, spca505_init_data))
+ return -EIO;
+ }
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int ret;
+
+ PDEBUG(D_STREAM, "Initializing SPCA505");
+ if (sd->subtype == Nxultra)
+ write_vector(gspca_dev, spca505b_open_data_ccd);
+ else
+ write_vector(gspca_dev, spca505_open_data_ccd);
+ ret = reg_read(gspca_dev, 6, 0x16, 2);
+
+ if (ret < 0) {
+ PDEBUG(D_ERR|D_STREAM,
+ "register read failed for after vector read err = %d",
+ ret);
+ return -EIO;
+ }
+ PDEBUG(D_STREAM,
+ "After vector read returns : 0x%x should be 0x0101",
+ ret & 0xffff);
+
+ ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d",
+ ret);
+ return -EIO;
+ }
+ reg_write(gspca_dev->dev, 5, 0xc2, 18);
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ /* necessary because without it we can see stream
+ * only once after loading module */
+ /* stopping usb registers Tomasz change */
+ reg_write(dev, 0x02, 0x0, 0x0);
+ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ case 0:
+ reg_write(dev, 0x04, 0x00, 0x00);
+ reg_write(dev, 0x04, 0x06, 0x10);
+ reg_write(dev, 0x04, 0x07, 0x10);
+ break;
+ case 1:
+ reg_write(dev, 0x04, 0x00, 0x01);
+ reg_write(dev, 0x04, 0x06, 0x1a);
+ reg_write(dev, 0x04, 0x07, 0x1a);
+ break;
+ case 2:
+ reg_write(dev, 0x04, 0x00, 0x02);
+ reg_write(dev, 0x04, 0x06, 0x1c);
+ reg_write(dev, 0x04, 0x07, 0x1d);
+ break;
+ case 4:
+ reg_write(dev, 0x04, 0x00, 0x04);
+ reg_write(dev, 0x04, 0x06, 0x34);
+ reg_write(dev, 0x04, 0x07, 0x34);
+ break;
+ default:
+/* case 5: */
+ reg_write(dev, 0x04, 0x00, 0x05);
+ reg_write(dev, 0x04, 0x06, 0x40);
+ reg_write(dev, 0x04, 0x07, 0x40);
+ break;
+ }
+/* Enable ISO packet machine - should we do this here or in ISOC init ? */
+ ret = reg_write(dev, SPCA50X_REG_USB,
+ SPCA50X_USB_CTRL,
+ SPCA50X_CUSB_ENABLE);
+
+/* reg_write(dev, 0x5, 0x0, 0x0); */
+/* reg_write(dev, 0x5, 0x0, 0x1); */
+/* reg_write(dev, 0x5, 0x11, 0x2); */
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ /* Disable ISO packet machine */
+ reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+ /* This maybe reset or power control */
+ reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
+ reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
+ reg_write(gspca_dev->dev, 0x03, 0x00, 0x1);
+ reg_write(gspca_dev->dev, 0x05, 0x10, 0x1);
+ reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
+}
+
+/* convert YYUV per line to YUYV (YUV 4:2:2) */
+static void yyuv_decode(unsigned char *out,
+ unsigned char *in,
+ int width,
+ int height)
+{
+ unsigned char *Ui, *Vi, *yi, *yi1;
+ unsigned char *out1;
+ int i, j;
+
+ yi = in;
+ for (i = height / 2; --i >= 0; ) {
+ out1 = out + width * 2; /* next line */
+ yi1 = yi + width;
+ Ui = yi1 + width;
+ Vi = Ui + width / 2;
+ for (j = width / 2; --j >= 0; ) {
+ *out++ = 128 + *yi++;
+ *out++ = 128 + *Ui;
+ *out++ = 128 + *yi++;
+ *out++ = 128 + *Vi;
+
+ *out1++ = 128 + *yi1++;
+ *out1++ = 128 + *Ui++;
+ *out1++ = 128 + *yi1++;
+ *out1++ = 128 + *Vi++;
+ }
+ yi += width * 2;
+ out = out1;
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (data[0]) {
+ case 0: /* start of frame */
+ if (gspca_dev->last_packet_type == FIRST_PACKET) {
+ yyuv_decode(sd->tmpbuf2, sd->tmpbuf,
+ gspca_dev->width,
+ gspca_dev->height);
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ sd->tmpbuf2,
+ gspca_dev->width
+ * gspca_dev->height
+ * 2);
+ }
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, 0);
+ data += SPCA50X_OFFSET_DATA;
+ len -= SPCA50X_OFFSET_DATA;
+ if (len > 0)
+ memcpy(sd->tmpbuf, data, len);
+ else
+ len = 0;
+ sd->buflen = len;
+ return;
+ case 0xff: /* drop */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ data += 1;
+ len -= 1;
+ memcpy(&sd->tmpbuf[sd->buflen], data, len);
+ sd->buflen += len;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ __u8 brightness = sd->brightness;
+ reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6);
+ reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);
+
+}
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = 255
+ - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
+ + (reg_read(gspca_dev, 5, 0x0, 1) << 6));
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")},
+ {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
new file mode 100644
index 00000000000..143203c1fd9
--- /dev/null
+++ b/drivers/media/video/gspca/spca506.c
@@ -0,0 +1,847 @@
+/*
+ * SPCA506 chip based cameras function
+ * M Xhaard 15/04/2004 based on different work Mark Taylor and others
+ * and my own snoopy file on a pv-321c donate by a german compagny
+ * "Firma Frank Gmbh" from Saarbruecken
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "spca506"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ int buflen;
+ __u8 tmpbuf[640 * 480 * 3]; /* YYUV per line */
+ __u8 tmpbuf2[640 * 480 * 2]; /* YUYV */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char hue;
+ char norme;
+ char channel;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x80,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x47,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_COLOR 2
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x40,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+#define SD_HUE 3
+ {
+ {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = sd_sethue,
+ .get = sd_gethue,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 160 * 2,
+ .sizeimage = 160 * 120 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 5},
+ {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 176 * 2,
+ .sizeimage = 176 * 144 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+ {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 320 * 2,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 352 * 2,
+ .sizeimage = 352 * 288 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 640 * 2,
+ .sizeimage = 640 * 480 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+#define SPCA50X_OFFSET_DATA 10
+
+#define SAA7113_bright 0x0a /* defaults 0x80 */
+#define SAA7113_contrast 0x0b /* defaults 0x47 */
+#define SAA7113_saturation 0x0c /* defaults 0x40 */
+#define SAA7113_hue 0x0d /* defaults 0x00 */
+#define SAA7113_I2C_BASE_WRITE 0x4a
+
+/* read 'len' bytes to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 req,
+ __u16 index,
+ __u16 length)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, length,
+ 500);
+}
+
+static void reg_w(struct usb_device *dev,
+ __u16 req,
+ __u16 value,
+ __u16 index)
+{
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index,
+ NULL, 0, 500);
+}
+
+static void spca506_Initi2c(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
+}
+
+static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
+ __u16 reg)
+{
+ int retry = 60;
+
+ reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
+ reg_w(gspca_dev->dev, 0x07, valeur, 0x0000);
+ while (retry--) {
+ reg_r(gspca_dev, 0x07, 0x0003, 2);
+ if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
+ break;
+ }
+}
+
+static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
+{
+ int retry = 60;
+
+ reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
+ reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
+ reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
+ while (--retry) {
+ reg_r(gspca_dev, 0x07, 0x0003, 2);
+ if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
+ break;
+ }
+ if (retry == 0)
+ return -1;
+ reg_r(gspca_dev, 0x07, 0x0000, 1);
+ return gspca_dev->usb_buf[0];
+}
+
+static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
+ __u16 norme,
+ __u16 channel)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+/* fixme: check if channel == 0..3 and 6..9 (8 values) */
+ __u8 setbit0 = 0x00;
+ __u8 setbit1 = 0x00;
+ __u8 videomask = 0x00;
+
+ PDEBUG(D_STREAM, "** Open Set Norme **");
+ spca506_Initi2c(gspca_dev);
+ /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
+ /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
+ /* and exclude SAA7113 reserved channel set default 0 otherwise */
+ if (norme & V4L2_STD_NTSC)
+ setbit0 = 0x01;
+ if (channel == 4 || channel == 5 || channel > 9)
+ channel = 0;
+ if (channel < 4)
+ setbit1 = 0x02;
+ videomask = (0x48 | setbit0 | setbit1);
+ reg_w(gspca_dev->dev, 0x08, videomask, 0x0000);
+ spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02);
+
+ if (norme & V4L2_STD_NTSC)
+ spca506_WriteI2c(gspca_dev, 0x33, 0x0e);
+ /* Chrominance Control NTSC N */
+ else if (norme & V4L2_STD_SECAM)
+ spca506_WriteI2c(gspca_dev, 0x53, 0x0e);
+ /* Chrominance Control SECAM */
+ else
+ spca506_WriteI2c(gspca_dev, 0x03, 0x0e);
+ /* Chrominance Control PAL BGHIV */
+
+ sd->norme = norme;
+ sd->channel = channel;
+ PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask);
+ PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel);
+}
+
+static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
+ __u16 *norme, __u16 *channel)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* Read the register is not so good value change so
+ we use your own copy in spca50x struct */
+ *norme = sd->norme;
+ *channel = sd->channel;
+ PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel);
+}
+
+static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
+ __u16 xmult, __u16 ymult)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ PDEBUG(D_STREAM, "** SetSize **");
+ reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
+ /* Soft snap 0x40 Hard 0x41 */
+ reg_w(dev, 0x04, 0x41, 0x0001);
+ reg_w(dev, 0x04, 0x00, 0x0002);
+ /* reserved */
+ reg_w(dev, 0x04, 0x00, 0x0003);
+
+ /* reserved */
+ reg_w(dev, 0x04, 0x00, 0x0004);
+ /* reserved */
+ reg_w(dev, 0x04, 0x01, 0x0005);
+ /* reserced */
+ reg_w(dev, 0x04, xmult, 0x0006);
+ /* reserved */
+ reg_w(dev, 0x04, ymult, 0x0007);
+ /* compression 1 */
+ reg_w(dev, 0x04, 0x00, 0x0008);
+ /* T=64 -> 2 */
+ reg_w(dev, 0x04, 0x00, 0x0009);
+ /* threshold2D */
+ reg_w(dev, 0x04, 0x21, 0x000a);
+ /* quantization */
+ reg_w(dev, 0x04, 0x00, 0x000b);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->hue = sd_ctrls[SD_HUE].qctrl.default_value;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ reg_w(dev, 0x03, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0xFF, 0x0003);
+ reg_w(dev, 0x03, 0x00, 0x0000);
+ reg_w(dev, 0x03, 0x1c, 0x0001);
+ reg_w(dev, 0x03, 0x18, 0x0001);
+ /* Init on PAL and composite input0 */
+ spca506_SetNormeInput(gspca_dev, 0, 0);
+ reg_w(dev, 0x03, 0x1c, 0x0001);
+ reg_w(dev, 0x03, 0x18, 0x0001);
+ reg_w(dev, 0x05, 0x00, 0x0000);
+ reg_w(dev, 0x05, 0xef, 0x0001);
+ reg_w(dev, 0x05, 0x00, 0x00c1);
+ reg_w(dev, 0x05, 0x00, 0x00c2);
+ reg_w(dev, 0x06, 0x18, 0x0002);
+ reg_w(dev, 0x06, 0xf5, 0x0011);
+ reg_w(dev, 0x06, 0x02, 0x0012);
+ reg_w(dev, 0x06, 0xfb, 0x0013);
+ reg_w(dev, 0x06, 0x00, 0x0014);
+ reg_w(dev, 0x06, 0xa4, 0x0051);
+ reg_w(dev, 0x06, 0x40, 0x0052);
+ reg_w(dev, 0x06, 0x71, 0x0053);
+ reg_w(dev, 0x06, 0x40, 0x0054);
+ /************************************************/
+ reg_w(dev, 0x03, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0x00, 0x0003);
+ reg_w(dev, 0x03, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0xFF, 0x0003);
+ reg_w(dev, 0x02, 0x00, 0x0000);
+ reg_w(dev, 0x03, 0x60, 0x0000);
+ reg_w(dev, 0x03, 0x18, 0x0001);
+ /* for a better reading mx :) */
+ /*sdca506_WriteI2c(value,register) */
+ spca506_Initi2c(gspca_dev);
+ spca506_WriteI2c(gspca_dev, 0x08, 0x01);
+ spca506_WriteI2c(gspca_dev, 0xc0, 0x02);
+ /* input composite video */
+ spca506_WriteI2c(gspca_dev, 0x33, 0x03);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x04);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x05);
+ spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
+ spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
+ spca506_WriteI2c(gspca_dev, 0x98, 0x08);
+ spca506_WriteI2c(gspca_dev, 0x03, 0x09);
+ spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
+ spca506_WriteI2c(gspca_dev, 0x47, 0x0b);
+ spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
+ spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */
+ spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x10);
+ spca506_WriteI2c(gspca_dev, 0x0c, 0x11);
+ spca506_WriteI2c(gspca_dev, 0xb8, 0x12);
+ spca506_WriteI2c(gspca_dev, 0x01, 0x13);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x14);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x15);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x16);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x17);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x18);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x19);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
+ spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
+ spca506_WriteI2c(gspca_dev, 0x02, 0x40);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x41);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x42);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x43);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x44);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x45);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x46);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x47);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x48);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x49);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x50);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x51);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x52);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x53);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x54);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x55);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x56);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x57);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x58);
+ spca506_WriteI2c(gspca_dev, 0x54, 0x59);
+ spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
+ spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x60);
+ spca506_WriteI2c(gspca_dev, 0x05, 0x61);
+ spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
+ PDEBUG(D_STREAM, "** Close Init *");
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ __u16 norme;
+ __u16 channel;
+
+ /**************************************/
+ reg_w(dev, 0x03, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0x00, 0x0003);
+ reg_w(dev, 0x03, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0xFF, 0x0003);
+ reg_w(dev, 0x02, 0x00, 0x0000);
+ reg_w(dev, 0x03, 0x60, 0x0000);
+ reg_w(dev, 0x03, 0x18, 0x0001);
+
+ /*sdca506_WriteI2c(value,register) */
+ spca506_Initi2c(gspca_dev);
+ spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */
+/* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */
+ spca506_WriteI2c(gspca_dev, 0x33, 0x03);
+ /* Analog Input Control 2 */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x04);
+ /* Analog Input Control 3 */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x05);
+ /* Analog Input Control 4 */
+ spca506_WriteI2c(gspca_dev, 0x0d, 0x06);
+ /* Horizontal Sync Start 0xe9-0x0d */
+ spca506_WriteI2c(gspca_dev, 0xf0, 0x07);
+ /* Horizontal Sync Stop 0x0d-0xf0 */
+
+ spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */
+/* Defaults value */
+ spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */
+ spca506_WriteI2c(gspca_dev, 0x80, 0x0a);
+ /* Luminance Brightness */
+ spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */
+ spca506_WriteI2c(gspca_dev, 0x48, 0x0c);
+ /* Chrominance Saturation */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x0d);
+ /* Chrominance Hue Control */
+ spca506_WriteI2c(gspca_dev, 0x2a, 0x0f);
+ /* Chrominance Gain Control */
+ /**************************************/
+ spca506_WriteI2c(gspca_dev, 0x00, 0x10);
+ /* Format/Delay Control */
+ spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */
+ spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */
+ spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */
+ spca506_WriteI2c(gspca_dev, 0x00, 0x18);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x19);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1a);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1b);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1c);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1d);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x1e);
+ spca506_WriteI2c(gspca_dev, 0xa1, 0x1f);
+ spca506_WriteI2c(gspca_dev, 0x02, 0x40);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x41);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x42);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x43);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x44);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x45);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x46);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x47);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x48);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x49);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4a);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4b);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4c);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4d);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4e);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x4f);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x50);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x51);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x52);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x53);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x54);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x55);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x56);
+ spca506_WriteI2c(gspca_dev, 0xff, 0x57);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x58);
+ spca506_WriteI2c(gspca_dev, 0x54, 0x59);
+ spca506_WriteI2c(gspca_dev, 0x07, 0x5a);
+ spca506_WriteI2c(gspca_dev, 0x83, 0x5b);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5c);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5d);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5e);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x5f);
+ spca506_WriteI2c(gspca_dev, 0x00, 0x60);
+ spca506_WriteI2c(gspca_dev, 0x05, 0x61);
+ spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
+ /**************************************/
+ reg_w(dev, 0x05, 0x00, 0x0003);
+ reg_w(dev, 0x05, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0x10, 0x0001);
+ reg_w(dev, 0x03, 0x78, 0x0000);
+ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ case 0:
+ spca506_Setsize(gspca_dev, 0, 0x10, 0x10);
+ break;
+ case 1:
+ spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a);
+ break;
+ case 2:
+ spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c);
+ break;
+ case 4:
+ spca506_Setsize(gspca_dev, 4, 0x34, 0x34);
+ break;
+ default:
+/* case 5: */
+ spca506_Setsize(gspca_dev, 5, 0x40, 0x40);
+ break;
+ }
+
+ /* compress setting and size */
+ /* set i2c luma */
+ reg_w(dev, 0x02, 0x01, 0x0000);
+ reg_w(dev, 0x03, 0x12, 0x0000);
+ reg_r(gspca_dev, 0x04, 0x0001, 2);
+ PDEBUG(D_STREAM, "webcam started");
+ spca506_GetNormeInput(gspca_dev, &norme, &channel);
+ spca506_SetNormeInput(gspca_dev, norme, channel);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ reg_w(dev, 0x02, 0x00, 0x0000);
+ reg_w(dev, 0x03, 0x00, 0x0004);
+ reg_w(dev, 0x03, 0x00, 0x0003);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+/* convert YYUV per line to YUYV (YUV 4:2:2) */
+static void yyuv_decode(unsigned char *out,
+ unsigned char *in,
+ int width,
+ int height)
+{
+ unsigned char *Ui, *Vi, *yi, *yi1;
+ unsigned char *out1;
+ int i, j;
+
+ yi = in;
+ for (i = height / 2; --i >= 0; ) {
+ out1 = out + width * 2; /* next line */
+ yi1 = yi + width;
+ Ui = yi1 + width;
+ Vi = Ui + width / 2;
+ for (j = width / 2; --j >= 0; ) {
+ *out++ = 128 + *yi++;
+ *out++ = 128 + *Ui;
+ *out++ = 128 + *yi++;
+ *out++ = 128 + *Vi;
+
+ *out1++ = 128 + *yi1++;
+ *out1++ = 128 + *Ui++;
+ *out1++ = 128 + *yi1++;
+ *out1++ = 128 + *Vi++;
+ }
+ yi += width * 2;
+ out = out1;
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (data[0]) {
+ case 0: /* start of frame */
+ if (gspca_dev->last_packet_type == FIRST_PACKET) {
+ yyuv_decode(sd->tmpbuf2, sd->tmpbuf,
+ gspca_dev->width,
+ gspca_dev->height);
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ sd->tmpbuf2,
+ gspca_dev->width
+ * gspca_dev->height
+ * 2);
+ }
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, 0);
+ data += SPCA50X_OFFSET_DATA;
+ len -= SPCA50X_OFFSET_DATA;
+ if (len > 0)
+ memcpy(sd->tmpbuf, data, len);
+ else
+ len = 0;
+ sd->buflen = len;
+ return;
+ case 0xff: /* drop */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ data += 1;
+ len -= 1;
+ memcpy(&sd->tmpbuf[sd->buflen], data, len);
+ sd->buflen += len;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ spca506_Initi2c(gspca_dev);
+ spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright);
+ spca506_WriteI2c(gspca_dev, 0x01, 0x09);
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ spca506_Initi2c(gspca_dev);
+ spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast);
+ spca506_WriteI2c(gspca_dev, 0x01, 0x09);
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ spca506_Initi2c(gspca_dev);
+ spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation);
+ spca506_WriteI2c(gspca_dev, 0x01, 0x09);
+}
+
+static void getcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation);
+}
+
+static void sethue(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ spca506_Initi2c(gspca_dev);
+ spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue);
+ spca506_WriteI2c(gspca_dev, 0x01, 0x09);
+}
+
+static void gethue(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcontrast(gspca_dev);
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcolors(gspca_dev);
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->hue = val;
+ if (gspca_dev->streaming)
+ sethue(gspca_dev);
+ return 0;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ gethue(gspca_dev);
+ *val = sd->hue;
+ return 0;
+}
+
+/* sub-driver description */
+static struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")},
+/* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */
+ {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")},
+ {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
new file mode 100644
index 00000000000..d8cd93866a4
--- /dev/null
+++ b/drivers/media/video/gspca/spca508.c
@@ -0,0 +1,1791 @@
+/*
+ * SPCA508 chip based cameras subdriver
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "spca508"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ int buflen;
+ unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */
+ unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */
+
+ unsigned char brightness;
+
+ char subtype;
+#define CreativeVista 0
+#define HamaUSBSightcam 1
+#define HamaUSBSightcam2 2
+#define IntelEasyPCCamera 3
+#define MicroInnovationIC200 4
+#define ViewQuestVQ110 5
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 128
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 160 * 2,
+ .sizeimage = 160 * 120 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 3},
+ {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 176 * 2,
+ .sizeimage = 176 * 144 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 320 * 2,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
+ .bytesperline = 352 * 2,
+ .sizeimage = 352 * 288 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/* Frame packet header offsets for the spca508 */
+#define SPCA508_OFFSET_TYPE 1
+#define SPCA508_OFFSET_COMPRESS 2
+#define SPCA508_OFFSET_FRAMSEQ 8
+#define SPCA508_OFFSET_WIN1LUM 11
+#define SPCA508_OFFSET_DATA 37
+
+#define SPCA508_SNAPBIT 0x20
+#define SPCA508_SNAPCTRL 0x40
+/*************** I2c ****************/
+#define SPCA508_INDEX_I2C_BASE 0x8800
+
+/*
+ * Initialization data: this is the first set-up data written to the
+ * device (before the open data).
+ */
+static const __u16 spca508_init_data[][3] =
+#define IGN(x) /* nothing */
+{
+ /* line URB value, index */
+ /* 44274 1804 */ {0x0000, 0x870b},
+
+ /* 44299 1805 */ {0x0020, 0x8112},
+ /* Video drop enable, ISO streaming disable */
+ /* 44324 1806 */ {0x0003, 0x8111},
+ /* Reset compression & memory */
+ /* 44349 1807 */ {0x0000, 0x8110},
+ /* Disable all outputs */
+ /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */
+ /* 44398 1809 */ {0x0000, 0x8114},
+ /* SW GPIO data */
+ /* 44423 1810 */ {0x0008, 0x8110},
+ /* Enable charge pump output */
+ /* 44527 1811 */ {0x0002, 0x8116},
+ /* 200 kHz pump clock */
+ /* 44555 1812 */
+ /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */
+ /* 44590 1813 */ {0x0003, 0x8111},
+ /* Reset compression & memory */
+ /* 44615 1814 */ {0x0000, 0x8111},
+ /* Normal mode (not reset) */
+ /* 44640 1815 */ {0x0098, 0x8110},
+ /* Enable charge pump output, sync.serial,external 2x clock */
+ /* 44665 1816 */ {0x000d, 0x8114},
+ /* SW GPIO data */
+ /* 44690 1817 */ {0x0002, 0x8116},
+ /* 200 kHz pump clock */
+ /* 44715 1818 */ {0x0020, 0x8112},
+ /* Video drop enable, ISO streaming disable */
+/* --------------------------------------- */
+ /* 44740 1819 */ {0x000f, 0x8402},
+ /* memory bank */
+ /* 44765 1820 */ {0x0000, 0x8403},
+ /* ... address */
+/* --------------------------------------- */
+/* 0x88__ is Synchronous Serial Interface. */
+/* TBD: This table could be expressed more compactly */
+/* using spca508_write_i2c_vector(). */
+/* TBD: Should see if the values in spca50x_i2c_data */
+/* would work with the VQ110 instead of the values */
+/* below. */
+ /* 44790 1821 */ {0x00c0, 0x8804},
+ /* SSI slave addr */
+ /* 44815 1822 */ {0x0008, 0x8802},
+ /* 375 Khz SSI clock */
+ /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 44888 1825 */ {0x0008, 0x8802},
+ /* 375 Khz SSI clock */
+ /* 44913 1826 */ {0x0012, 0x8801},
+ /* SSI reg addr */
+ /* 44938 1827 */ {0x0080, 0x8800},
+ /* SSI data to write */
+ /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45035 1831 */ {0x0008, 0x8802},
+ /* 375 Khz SSI clock */
+ /* 45060 1832 */ {0x0012, 0x8801},
+ /* SSI reg addr */
+ /* 45085 1833 */ {0x0000, 0x8800},
+ /* SSI data to write */
+ /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45182 1837 */ {0x0008, 0x8802},
+ /* 375 Khz SSI clock */
+ /* 45207 1838 */ {0x0011, 0x8801},
+ /* SSI reg addr */
+ /* 45232 1839 */ {0x0040, 0x8800},
+ /* SSI data to write */
+ /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45329 1843 */ {0x0008, 0x8802},
+ /* 45354 1844 */ {0x0013, 0x8801},
+ /* 45379 1845 */ {0x0000, 0x8800},
+ /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45476 1849 */ {0x0008, 0x8802},
+ /* 45501 1850 */ {0x0014, 0x8801},
+ /* 45526 1851 */ {0x0000, 0x8800},
+ /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45623 1855 */ {0x0008, 0x8802},
+ /* 45648 1856 */ {0x0015, 0x8801},
+ /* 45673 1857 */ {0x0001, 0x8800},
+ /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45770 1861 */ {0x0008, 0x8802},
+ /* 45795 1862 */ {0x0016, 0x8801},
+ /* 45820 1863 */ {0x0003, 0x8800},
+ /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 45917 1867 */ {0x0008, 0x8802},
+ /* 45942 1868 */ {0x0017, 0x8801},
+ /* 45967 1869 */ {0x0036, 0x8800},
+ /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46064 1873 */ {0x0008, 0x8802},
+ /* 46089 1874 */ {0x0018, 0x8801},
+ /* 46114 1875 */ {0x00ec, 0x8800},
+ /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46211 1879 */ {0x0008, 0x8802},
+ /* 46236 1880 */ {0x001a, 0x8801},
+ /* 46261 1881 */ {0x0094, 0x8800},
+ /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46358 1885 */ {0x0008, 0x8802},
+ /* 46383 1886 */ {0x001b, 0x8801},
+ /* 46408 1887 */ {0x0000, 0x8800},
+ /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46505 1891 */ {0x0008, 0x8802},
+ /* 46530 1892 */ {0x0027, 0x8801},
+ /* 46555 1893 */ {0x00a2, 0x8800},
+ /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46652 1897 */ {0x0008, 0x8802},
+ /* 46677 1898 */ {0x0028, 0x8801},
+ /* 46702 1899 */ {0x0040, 0x8800},
+ /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46799 1903 */ {0x0008, 0x8802},
+ /* 46824 1904 */ {0x002a, 0x8801},
+ /* 46849 1905 */ {0x0084, 0x8800},
+ /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 46946 1909 */ {0x0008, 0x8802},
+ /* 46971 1910 */ {0x002b, 0x8801},
+ /* 46996 1911 */ {0x00a8, 0x8800},
+ /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47093 1915 */ {0x0008, 0x8802},
+ /* 47118 1916 */ {0x002c, 0x8801},
+ /* 47143 1917 */ {0x00fe, 0x8800},
+ /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47240 1921 */ {0x0008, 0x8802},
+ /* 47265 1922 */ {0x002d, 0x8801},
+ /* 47290 1923 */ {0x0003, 0x8800},
+ /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47387 1927 */ {0x0008, 0x8802},
+ /* 47412 1928 */ {0x0038, 0x8801},
+ /* 47437 1929 */ {0x0083, 0x8800},
+ /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47534 1933 */ {0x0008, 0x8802},
+ /* 47559 1934 */ {0x0033, 0x8801},
+ /* 47584 1935 */ {0x0081, 0x8800},
+ /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47681 1939 */ {0x0008, 0x8802},
+ /* 47706 1940 */ {0x0034, 0x8801},
+ /* 47731 1941 */ {0x004a, 0x8800},
+ /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47828 1945 */ {0x0008, 0x8802},
+ /* 47853 1946 */ {0x0039, 0x8801},
+ /* 47878 1947 */ {0x0000, 0x8800},
+ /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 47975 1951 */ {0x0008, 0x8802},
+ /* 48000 1952 */ {0x0010, 0x8801},
+ /* 48025 1953 */ {0x00a8, 0x8800},
+ /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 48122 1957 */ {0x0008, 0x8802},
+ /* 48147 1958 */ {0x0006, 0x8801},
+ /* 48172 1959 */ {0x0058, 0x8800},
+ /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 48269 1963 */ {0x0008, 0x8802},
+ /* 48294 1964 */ {0x0000, 0x8801},
+ /* 48319 1965 */ {0x0004, 0x8800},
+ /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 48416 1969 */ {0x0008, 0x8802},
+ /* 48441 1970 */ {0x0040, 0x8801},
+ /* 48466 1971 */ {0x0080, 0x8800},
+ /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 48563 1975 */ {0x0008, 0x8802},
+ /* 48588 1976 */ {0x0041, 0x8801},
+ /* 48613 1977 */ {0x000c, 0x8800},
+ /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 48710 1981 */ {0x0008, 0x8802},
+ /* 48735 1982 */ {0x0042, 0x8801},
+ /* 48760 1983 */ {0x000c, 0x8800},
+ /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 48857 1987 */ {0x0008, 0x8802},
+ /* 48882 1988 */ {0x0043, 0x8801},
+ /* 48907 1989 */ {0x0028, 0x8800},
+ /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49004 1993 */ {0x0008, 0x8802},
+ /* 49029 1994 */ {0x0044, 0x8801},
+ /* 49054 1995 */ {0x0080, 0x8800},
+ /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49151 1999 */ {0x0008, 0x8802},
+ /* 49176 2000 */ {0x0045, 0x8801},
+ /* 49201 2001 */ {0x0020, 0x8800},
+ /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49298 2005 */ {0x0008, 0x8802},
+ /* 49323 2006 */ {0x0046, 0x8801},
+ /* 49348 2007 */ {0x0020, 0x8800},
+ /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49445 2011 */ {0x0008, 0x8802},
+ /* 49470 2012 */ {0x0047, 0x8801},
+ /* 49495 2013 */ {0x0080, 0x8800},
+ /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49592 2017 */ {0x0008, 0x8802},
+ /* 49617 2018 */ {0x0048, 0x8801},
+ /* 49642 2019 */ {0x004c, 0x8800},
+ /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49739 2023 */ {0x0008, 0x8802},
+ /* 49764 2024 */ {0x0049, 0x8801},
+ /* 49789 2025 */ {0x0084, 0x8800},
+ /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 49886 2029 */ {0x0008, 0x8802},
+ /* 49911 2030 */ {0x004a, 0x8801},
+ /* 49936 2031 */ {0x0084, 0x8800},
+ /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 50033 2035 */ {0x0008, 0x8802},
+ /* 50058 2036 */ {0x004b, 0x8801},
+ /* 50083 2037 */ {0x0084, 0x8800},
+ /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* --------------------------------------- */
+ /* 50132 2039 */ {0x0012, 0x8700},
+ /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
+ /* 50157 2040 */ {0x0000, 0x8701},
+ /* CKx1 clock delay adj */
+ /* 50182 2041 */ {0x0000, 0x8701},
+ /* CKx1 clock delay adj */
+ /* 50207 2042 */ {0x0001, 0x870c},
+ /* CKOx2 output */
+ /* --------------------------------------- */
+ /* 50232 2043 */ {0x0080, 0x8600},
+ /* Line memory read counter (L) */
+ /* 50257 2044 */ {0x0001, 0x8606},
+ /* reserved */
+ /* 50282 2045 */ {0x0064, 0x8607},
+ /* Line memory read counter (H) 0x6480=25,728 */
+ /* 50307 2046 */ {0x002a, 0x8601},
+ /* CDSP sharp interpolation mode,
+ * line sel for color sep, edge enhance enab */
+ /* 50332 2047 */ {0x0000, 0x8602},
+ /* optical black level for user settng = 0 */
+ /* 50357 2048 */ {0x0080, 0x8600},
+ /* Line memory read counter (L) */
+ /* 50382 2049 */ {0x000a, 0x8603},
+ /* optical black level calc mode: auto; optical black offset = 10 */
+ /* 50407 2050 */ {0x00df, 0x865b},
+ /* Horiz offset for valid pixels (L)=0xdf */
+ /* 50432 2051 */ {0x0012, 0x865c},
+ /* Vert offset for valid lines (L)=0x12 */
+
+/* The following two lines seem to be the "wrong" resolution. */
+/* But perhaps these indicate the actual size of the sensor */
+/* rather than the size of the current video mode. */
+ /* 50457 2052 */ {0x0058, 0x865d},
+ /* Horiz valid pixels (*4) (L) = 352 */
+ /* 50482 2053 */ {0x0048, 0x865e},
+ /* Vert valid lines (*4) (L) = 288 */
+
+ /* 50507 2054 */ {0x0015, 0x8608},
+ /* A11 Coef ... */
+ /* 50532 2055 */ {0x0030, 0x8609},
+ /* 50557 2056 */ {0x00fb, 0x860a},
+ /* 50582 2057 */ {0x003e, 0x860b},
+ /* 50607 2058 */ {0x00ce, 0x860c},
+ /* 50632 2059 */ {0x00f4, 0x860d},
+ /* 50657 2060 */ {0x00eb, 0x860e},
+ /* 50682 2061 */ {0x00dc, 0x860f},
+ /* 50707 2062 */ {0x0039, 0x8610},
+ /* 50732 2063 */ {0x0001, 0x8611},
+ /* R offset for white balance ... */
+ /* 50757 2064 */ {0x0000, 0x8612},
+ /* 50782 2065 */ {0x0001, 0x8613},
+ /* 50807 2066 */ {0x0000, 0x8614},
+ /* 50832 2067 */ {0x005b, 0x8651},
+ /* R gain for white balance ... */
+ /* 50857 2068 */ {0x0040, 0x8652},
+ /* 50882 2069 */ {0x0060, 0x8653},
+ /* 50907 2070 */ {0x0040, 0x8654},
+ /* 50932 2071 */ {0x0000, 0x8655},
+ /* 50957 2072 */ {0x0001, 0x863f},
+ /* Fixed gamma correction enable, USB control,
+ * lum filter disable, lum noise clip disable */
+ /* 50982 2073 */ {0x00a1, 0x8656},
+ /* Window1 size 256x256, Windows2 size 64x64,
+ * gamma look-up disable, new edge enhancement enable */
+ /* 51007 2074 */ {0x0018, 0x8657},
+ /* Edge gain high thresh */
+ /* 51032 2075 */ {0x0020, 0x8658},
+ /* Edge gain low thresh */
+ /* 51057 2076 */ {0x000a, 0x8659},
+ /* Edge bandwidth high threshold */
+ /* 51082 2077 */ {0x0005, 0x865a},
+ /* Edge bandwidth low threshold */
+ /* -------------------------------- */
+ /* 51107 2078 */ {0x0030, 0x8112},
+ /* Video drop enable, ISO streaming enable */
+ /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 51180 2081 */ {0xa908, 0x8802},
+ /* 51205 2082 */ {0x0034, 0x8801},
+ /* SSI reg addr */
+ /* 51230 2083 */ {0x00ca, 0x8800},
+ /* SSI data to write */
+ /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 51327 2087 */ {0x1f08, 0x8802},
+ /* 51352 2088 */ {0x0006, 0x8801},
+ /* 51377 2089 */ {0x0080, 0x8800},
+ /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+
+/* ----- Read back coefs we wrote earlier. */
+ /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */
+ /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */
+ /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */
+ /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */
+ /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */
+ /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */
+ /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */
+ /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */
+ /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */
+ /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */
+ /* 51690 2102 */ {0xb008, 0x8802},
+ /* 51715 2103 */ {0x0006, 0x8801},
+ /* 51740 2104 */ {0x007d, 0x8800},
+ /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+
+
+ /* This chunk is seemingly redundant with */
+ /* earlier commands (A11 Coef...), but if I disable it, */
+ /* the image appears too dark. Maybe there was some kind of */
+ /* reset since the earlier commands, so this is necessary again. */
+ /* 51789 2106 */ {0x0015, 0x8608},
+ /* 51814 2107 */ {0x0030, 0x8609},
+ /* 51839 2108 */ {0xfffb, 0x860a},
+ /* 51864 2109 */ {0x003e, 0x860b},
+ /* 51889 2110 */ {0xffce, 0x860c},
+ /* 51914 2111 */ {0xfff4, 0x860d},
+ /* 51939 2112 */ {0xffeb, 0x860e},
+ /* 51964 2113 */ {0xffdc, 0x860f},
+ /* 51989 2114 */ {0x0039, 0x8610},
+ /* 52014 2115 */ {0x0018, 0x8657},
+
+ /* 52039 2116 */ {0x0000, 0x8508},
+ /* Disable compression. */
+ /* Previous line was:
+ * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */
+ /* 52064 2117 */ {0x0032, 0x850b},
+ /* compression stuff */
+ /* 52089 2118 */ {0x0003, 0x8509},
+ /* compression stuff */
+ /* 52114 2119 */ {0x0011, 0x850a},
+ /* compression stuff */
+ /* 52139 2120 */ {0x0021, 0x850d},
+ /* compression stuff */
+ /* 52164 2121 */ {0x0010, 0x850c},
+ /* compression stuff */
+ /* 52189 2122 */ {0x0003, 0x8500},
+ /* *** Video mode: 160x120 */
+ /* 52214 2123 */ {0x0001, 0x8501},
+ /* Hardware-dominated snap control */
+ /* 52239 2124 */ {0x0061, 0x8656},
+ /* Window1 size 128x128, Windows2 size 128x128,
+ * gamma look-up disable, new edge enhancement enable */
+ /* 52264 2125 */ {0x0018, 0x8617},
+ /* Window1 start X (*2) */
+ /* 52289 2126 */ {0x0008, 0x8618},
+ /* Window1 start Y (*2) */
+ /* 52314 2127 */ {0x0061, 0x8656},
+ /* Window1 size 128x128, Windows2 size 128x128,
+ * gamma look-up disable, new edge enhancement enable */
+ /* 52339 2128 */ {0x0058, 0x8619},
+ /* Window2 start X (*2) */
+ /* 52364 2129 */ {0x0008, 0x861a},
+ /* Window2 start Y (*2) */
+ /* 52389 2130 */ {0x00ff, 0x8615},
+ /* High lum thresh for white balance */
+ /* 52414 2131 */ {0x0000, 0x8616},
+ /* Low lum thresh for white balance */
+ /* 52439 2132 */ {0x0012, 0x8700},
+ /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
+ /* 52464 2133 */ {0x0012, 0x8700},
+ /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */
+ /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */
+ /* 52513 2135 */ {0x0028, 0x8802},
+ /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
+ /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
+ /* 52586 2138 */ {0x1f28, 0x8802},
+ /* 375 Khz SSI clock, SSI r/w sync with VSYNC */
+ /* 52611 2139 */ {0x0010, 0x8801},
+ /* SSI reg addr */
+ /* 52636 2140 */ {0x003e, 0x8800},
+ /* SSI data to write */
+ /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 52685 2142 */ {0x0028, 0x8802},
+ /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
+ /* 52758 2145 */ {0x1f28, 0x8802},
+ /* 52783 2146 */ {0x0000, 0x8801},
+ /* 52808 2147 */ {0x001f, 0x8800},
+ /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 52857 2149 */ {0x0001, 0x8602},
+ /* optical black level for user settning = 1 */
+
+ /* Original: */
+ /* 52882 2150 */ {0x0023, 0x8700},
+ /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */
+ /* 52907 2151 */ {0x000f, 0x8602},
+ /* optical black level for user settning = 15 */
+
+ /* 52932 2152 */ {0x0028, 0x8802},
+ /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */
+ /* 53005 2155 */ {0x1f28, 0x8802},
+ /* 53030 2156 */ {0x0010, 0x8801},
+ /* 53055 2157 */ {0x007b, 0x8800},
+ /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */
+ /* 53104 2159 */ {0x002f, 0x8651},
+ /* R gain for white balance ... */
+ /* 53129 2160 */ {0x0080, 0x8653},
+ /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */
+ /* 53178 2162 */ {0x0000, 0x8655},
+
+ /* 53203 2163 */ {0x0030, 0x8112},
+ /* Video drop enable, ISO streaming enable */
+ /* 53228 2164 */ {0x0020, 0x8112},
+ /* Video drop enable, ISO streaming disable */
+ /* 53252 2165 */
+ /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */
+ {}
+};
+
+
+/*
+ * Initialization data for Intel EasyPC Camera CS110
+ */
+static const __u16 spca508cs110_init_data[][3] = {
+ {0x0000, 0x870b}, /* Reset CTL3 */
+ {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
+ {0x0000, 0x8111}, /* Normal operation on reset */
+ {0x0090, 0x8110},
+ /* External Clock 2x & Synchronous Serial Interface Output */
+ {0x0020, 0x8112}, /* Video Drop packet enable */
+ {0x0000, 0x8114}, /* Software GPIO output data */
+ {0x0001, 0x8114},
+ {0x0001, 0x8114},
+ {0x0001, 0x8114},
+ {0x0003, 0x8114},
+
+ /* Initial sequence Synchronous Serial Interface */
+ {0x000f, 0x8402}, /* Memory bank Address */
+ {0x0000, 0x8403}, /* Memory bank Address */
+ {0x00ba, 0x8804}, /* SSI Slave address */
+ {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
+ {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */
+
+ {0x0001, 0x8801},
+ {0x000a, 0x8805},/* a - NWG: Dunno what this is about */
+ {0x0000, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0002, 0x8801},
+ {0x0000, 0x8805},
+ {0x0000, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0003, 0x8801},
+ {0x0027, 0x8805},
+ {0x0001, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0004, 0x8801},
+ {0x0065, 0x8805},
+ {0x0001, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0005, 0x8801},
+ {0x0003, 0x8805},
+ {0x0000, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0006, 0x8801},
+ {0x001c, 0x8805},
+ {0x0000, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0007, 0x8801},
+ {0x002a, 0x8805},
+ {0x0000, 0x8800},
+ {0x0010, 0x8802},
+
+ {0x0002, 0x8704}, /* External input CKIx1 */
+ {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
+ {0x009a, 0x8600}, /* Line memory Read Counter (L) */
+ {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
+ {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */
+ {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */
+
+ {0x0006, 0x8660}, /* Nibble data + input order */
+
+ {0x000a, 0x8602}, /* Optical black level set to 0x0a */
+/* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */
+
+/* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */
+/* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */
+/* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */
+/* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */
+
+ {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */
+ {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */
+ {0x0035, 0x8653}, /* 26 RED gain for white balance */
+ {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */
+ {0x0041, 0x863f},
+ /* Fixed Gamma correction enabled (makes colours look better) */
+
+/* 2422 */ {0x0000, 0x8655},
+ /* High bits for white balance*****brightness control*** */
+ {}
+};
+
+static const __u16 spca508_sightcam_init_data[][3] = {
+/* This line seems to setup the frame/canvas */
+ /*368 */ {0x000f, 0x8402},
+
+/* Theese 6 lines are needed to startup the webcam */
+ /*398 */ {0x0090, 0x8110},
+ /*399 */ {0x0001, 0x8114},
+ /*400 */ {0x0001, 0x8114},
+ /*401 */ {0x0001, 0x8114},
+ /*402 */ {0x0003, 0x8114},
+ /*403 */ {0x0080, 0x8804},
+
+/* This part seems to make the pictures darker? (autobrightness?) */
+ /*436 */ {0x0001, 0x8801},
+ /*437 */ {0x0004, 0x8800},
+ /*439 */ {0x0003, 0x8801},
+ /*440 */ {0x00e0, 0x8800},
+ /*442 */ {0x0004, 0x8801},
+ /*443 */ {0x00b4, 0x8800},
+ /*445 */ {0x0005, 0x8801},
+ /*446 */ {0x0000, 0x8800},
+
+ /*448 */ {0x0006, 0x8801},
+ /*449 */ {0x00e0, 0x8800},
+ /*451 */ {0x0007, 0x8801},
+ /*452 */ {0x000c, 0x8800},
+
+/* This section is just needed, it probably
+ * does something like the previous section,
+ * but the cam won't start if it's not included.
+ */
+ /*484 */ {0x0014, 0x8801},
+ /*485 */ {0x0008, 0x8800},
+ /*487 */ {0x0015, 0x8801},
+ /*488 */ {0x0067, 0x8800},
+ /*490 */ {0x0016, 0x8801},
+ /*491 */ {0x0000, 0x8800},
+ /*493 */ {0x0017, 0x8801},
+ /*494 */ {0x0020, 0x8800},
+ /*496 */ {0x0018, 0x8801},
+ /*497 */ {0x0044, 0x8800},
+
+/* Makes the picture darker - and the
+ * cam won't start if not included
+ */
+ /*505 */ {0x001e, 0x8801},
+ /*506 */ {0x00ea, 0x8800},
+ /*508 */ {0x001f, 0x8801},
+ /*509 */ {0x0001, 0x8800},
+ /*511 */ {0x0003, 0x8801},
+ /*512 */ {0x00e0, 0x8800},
+
+/* seems to place the colors ontop of each other #1 */
+ /*517 */ {0x0006, 0x8704},
+ /*518 */ {0x0001, 0x870c},
+ /*519 */ {0x0016, 0x8600},
+ /*520 */ {0x0002, 0x8606},
+
+/* if not included the pictures becomes _very_ dark */
+ /*521 */ {0x0064, 0x8607},
+ /*522 */ {0x003a, 0x8601},
+ /*523 */ {0x0000, 0x8602},
+
+/* seems to place the colors ontop of each other #2 */
+ /*524 */ {0x0016, 0x8600},
+ /*525 */ {0x0018, 0x8617},
+ /*526 */ {0x0008, 0x8618},
+ /*527 */ {0x00a1, 0x8656},
+
+/* webcam won't start if not included */
+ /*528 */ {0x0007, 0x865b},
+ /*529 */ {0x0001, 0x865c},
+ /*530 */ {0x0058, 0x865d},
+ /*531 */ {0x0048, 0x865e},
+
+/* adjusts the colors */
+ /*541 */ {0x0049, 0x8651},
+ /*542 */ {0x0040, 0x8652},
+ /*543 */ {0x004c, 0x8653},
+ /*544 */ {0x0040, 0x8654},
+ {}
+};
+
+static const __u16 spca508_sightcam2_init_data[][3] = {
+/* 35 */ {0x0020, 0x8112},
+
+/* 36 */ {0x000f, 0x8402},
+/* 37 */ {0x0000, 0x8403},
+
+/* 38 */ {0x0008, 0x8201},
+/* 39 */ {0x0008, 0x8200},
+/* 40 */ {0x0001, 0x8200},
+/* 43 */ {0x0009, 0x8201},
+/* 44 */ {0x0008, 0x8200},
+/* 45 */ {0x0001, 0x8200},
+/* 48 */ {0x000a, 0x8201},
+/* 49 */ {0x0008, 0x8200},
+/* 50 */ {0x0001, 0x8200},
+/* 53 */ {0x000b, 0x8201},
+/* 54 */ {0x0008, 0x8200},
+/* 55 */ {0x0001, 0x8200},
+/* 58 */ {0x000c, 0x8201},
+/* 59 */ {0x0008, 0x8200},
+/* 60 */ {0x0001, 0x8200},
+/* 63 */ {0x000d, 0x8201},
+/* 64 */ {0x0008, 0x8200},
+/* 65 */ {0x0001, 0x8200},
+/* 68 */ {0x000e, 0x8201},
+/* 69 */ {0x0008, 0x8200},
+/* 70 */ {0x0001, 0x8200},
+/* 73 */ {0x0007, 0x8201},
+/* 74 */ {0x0008, 0x8200},
+/* 75 */ {0x0001, 0x8200},
+/* 78 */ {0x000f, 0x8201},
+/* 79 */ {0x0008, 0x8200},
+/* 80 */ {0x0001, 0x8200},
+
+/* 84 */ {0x0018, 0x8660},
+/* 85 */ {0x0010, 0x8201},
+
+/* 86 */ {0x0008, 0x8200},
+/* 87 */ {0x0001, 0x8200},
+/* 90 */ {0x0011, 0x8201},
+/* 91 */ {0x0008, 0x8200},
+/* 92 */ {0x0001, 0x8200},
+
+/* 95 */ {0x0000, 0x86b0},
+/* 96 */ {0x0034, 0x86b1},
+/* 97 */ {0x0000, 0x86b2},
+/* 98 */ {0x0049, 0x86b3},
+/* 99 */ {0x0000, 0x86b4},
+/* 100 */ {0x0000, 0x86b4},
+
+/* 101 */ {0x0012, 0x8201},
+/* 102 */ {0x0008, 0x8200},
+/* 103 */ {0x0001, 0x8200},
+/* 106 */ {0x0013, 0x8201},
+/* 107 */ {0x0008, 0x8200},
+/* 108 */ {0x0001, 0x8200},
+
+/* 111 */ {0x0001, 0x86b0},
+/* 112 */ {0x00aa, 0x86b1},
+/* 113 */ {0x0000, 0x86b2},
+/* 114 */ {0x00e4, 0x86b3},
+/* 115 */ {0x0000, 0x86b4},
+/* 116 */ {0x0000, 0x86b4},
+
+/* 118 */ {0x0018, 0x8660},
+
+/* 119 */ {0x0090, 0x8110},
+/* 120 */ {0x0001, 0x8114},
+/* 121 */ {0x0001, 0x8114},
+/* 122 */ {0x0001, 0x8114},
+/* 123 */ {0x0003, 0x8114},
+
+/* 124 */ {0x0080, 0x8804},
+/* 157 */ {0x0003, 0x8801},
+/* 158 */ {0x0012, 0x8800},
+/* 160 */ {0x0004, 0x8801},
+/* 161 */ {0x0005, 0x8800},
+/* 163 */ {0x0005, 0x8801},
+/* 164 */ {0x0000, 0x8800},
+/* 166 */ {0x0006, 0x8801},
+/* 167 */ {0x0000, 0x8800},
+/* 169 */ {0x0007, 0x8801},
+/* 170 */ {0x0000, 0x8800},
+/* 172 */ {0x0008, 0x8801},
+/* 173 */ {0x0005, 0x8800},
+/* 175 */ {0x000a, 0x8700},
+/* 176 */ {0x000e, 0x8801},
+/* 177 */ {0x0004, 0x8800},
+/* 179 */ {0x0005, 0x8801},
+/* 180 */ {0x0047, 0x8800},
+/* 182 */ {0x0006, 0x8801},
+/* 183 */ {0x0000, 0x8800},
+/* 185 */ {0x0007, 0x8801},
+/* 186 */ {0x00c0, 0x8800},
+/* 188 */ {0x0008, 0x8801},
+/* 189 */ {0x0003, 0x8800},
+/* 191 */ {0x0013, 0x8801},
+/* 192 */ {0x0001, 0x8800},
+/* 194 */ {0x0009, 0x8801},
+/* 195 */ {0x0000, 0x8800},
+/* 197 */ {0x000a, 0x8801},
+/* 198 */ {0x0000, 0x8800},
+/* 200 */ {0x000b, 0x8801},
+/* 201 */ {0x0000, 0x8800},
+/* 203 */ {0x000c, 0x8801},
+/* 204 */ {0x0000, 0x8800},
+/* 206 */ {0x000e, 0x8801},
+/* 207 */ {0x0004, 0x8800},
+/* 209 */ {0x000f, 0x8801},
+/* 210 */ {0x0000, 0x8800},
+/* 212 */ {0x0010, 0x8801},
+/* 213 */ {0x0006, 0x8800},
+/* 215 */ {0x0011, 0x8801},
+/* 216 */ {0x0006, 0x8800},
+/* 218 */ {0x0012, 0x8801},
+/* 219 */ {0x0000, 0x8800},
+/* 221 */ {0x0013, 0x8801},
+/* 222 */ {0x0001, 0x8800},
+
+/* 224 */ {0x000a, 0x8700},
+/* 225 */ {0x0000, 0x8702},
+/* 226 */ {0x0000, 0x8703},
+/* 227 */ {0x00c2, 0x8704},
+/* 228 */ {0x0001, 0x870c},
+
+/* 229 */ {0x0044, 0x8600},
+/* 230 */ {0x0002, 0x8606},
+/* 231 */ {0x0064, 0x8607},
+/* 232 */ {0x003a, 0x8601},
+/* 233 */ {0x0008, 0x8602},
+/* 234 */ {0x0044, 0x8600},
+/* 235 */ {0x0018, 0x8617},
+/* 236 */ {0x0008, 0x8618},
+/* 237 */ {0x00a1, 0x8656},
+/* 238 */ {0x0004, 0x865b},
+/* 239 */ {0x0002, 0x865c},
+/* 240 */ {0x0058, 0x865d},
+/* 241 */ {0x0048, 0x865e},
+/* 242 */ {0x0012, 0x8608},
+/* 243 */ {0x002c, 0x8609},
+/* 244 */ {0x0002, 0x860a},
+/* 245 */ {0x002c, 0x860b},
+/* 246 */ {0x00db, 0x860c},
+/* 247 */ {0x00f9, 0x860d},
+/* 248 */ {0x00f1, 0x860e},
+/* 249 */ {0x00e3, 0x860f},
+/* 250 */ {0x002c, 0x8610},
+/* 251 */ {0x006c, 0x8651},
+/* 252 */ {0x0041, 0x8652},
+/* 253 */ {0x0059, 0x8653},
+/* 254 */ {0x0040, 0x8654},
+/* 255 */ {0x00fa, 0x8611},
+/* 256 */ {0x00ff, 0x8612},
+/* 257 */ {0x00f8, 0x8613},
+/* 258 */ {0x0000, 0x8614},
+/* 259 */ {0x0001, 0x863f},
+/* 260 */ {0x0000, 0x8640},
+/* 261 */ {0x0026, 0x8641},
+/* 262 */ {0x0045, 0x8642},
+/* 263 */ {0x0060, 0x8643},
+/* 264 */ {0x0075, 0x8644},
+/* 265 */ {0x0088, 0x8645},
+/* 266 */ {0x009b, 0x8646},
+/* 267 */ {0x00b0, 0x8647},
+/* 268 */ {0x00c5, 0x8648},
+/* 269 */ {0x00d2, 0x8649},
+/* 270 */ {0x00dc, 0x864a},
+/* 271 */ {0x00e5, 0x864b},
+/* 272 */ {0x00eb, 0x864c},
+/* 273 */ {0x00f0, 0x864d},
+/* 274 */ {0x00f6, 0x864e},
+/* 275 */ {0x00fa, 0x864f},
+/* 276 */ {0x00ff, 0x8650},
+/* 277 */ {0x0060, 0x8657},
+/* 278 */ {0x0010, 0x8658},
+/* 279 */ {0x0018, 0x8659},
+/* 280 */ {0x0005, 0x865a},
+/* 281 */ {0x0018, 0x8660},
+/* 282 */ {0x0003, 0x8509},
+/* 283 */ {0x0011, 0x850a},
+/* 284 */ {0x0032, 0x850b},
+/* 285 */ {0x0010, 0x850c},
+/* 286 */ {0x0021, 0x850d},
+/* 287 */ {0x0001, 0x8500},
+/* 288 */ {0x0000, 0x8508},
+/* 289 */ {0x0012, 0x8608},
+/* 290 */ {0x002c, 0x8609},
+/* 291 */ {0x0002, 0x860a},
+/* 292 */ {0x0039, 0x860b},
+/* 293 */ {0x00d0, 0x860c},
+/* 294 */ {0x00f7, 0x860d},
+/* 295 */ {0x00ed, 0x860e},
+/* 296 */ {0x00db, 0x860f},
+/* 297 */ {0x0039, 0x8610},
+/* 298 */ {0x0012, 0x8657},
+/* 299 */ {0x000c, 0x8619},
+/* 300 */ {0x0004, 0x861a},
+/* 301 */ {0x00a1, 0x8656},
+/* 302 */ {0x00c8, 0x8615},
+/* 303 */ {0x0032, 0x8616},
+
+/* 306 */ {0x0030, 0x8112},
+/* 313 */ {0x0020, 0x8112},
+/* 314 */ {0x0020, 0x8112},
+/* 315 */ {0x000f, 0x8402},
+/* 316 */ {0x0000, 0x8403},
+
+/* 317 */ {0x0090, 0x8110},
+/* 318 */ {0x0001, 0x8114},
+/* 319 */ {0x0001, 0x8114},
+/* 320 */ {0x0001, 0x8114},
+/* 321 */ {0x0003, 0x8114},
+/* 322 */ {0x0080, 0x8804},
+
+/* 355 */ {0x0003, 0x8801},
+/* 356 */ {0x0012, 0x8800},
+/* 358 */ {0x0004, 0x8801},
+/* 359 */ {0x0005, 0x8800},
+/* 361 */ {0x0005, 0x8801},
+/* 362 */ {0x0047, 0x8800},
+/* 364 */ {0x0006, 0x8801},
+/* 365 */ {0x0000, 0x8800},
+/* 367 */ {0x0007, 0x8801},
+/* 368 */ {0x00c0, 0x8800},
+/* 370 */ {0x0008, 0x8801},
+/* 371 */ {0x0003, 0x8800},
+/* 373 */ {0x000a, 0x8700},
+/* 374 */ {0x000e, 0x8801},
+/* 375 */ {0x0004, 0x8800},
+/* 377 */ {0x0005, 0x8801},
+/* 378 */ {0x0047, 0x8800},
+/* 380 */ {0x0006, 0x8801},
+/* 381 */ {0x0000, 0x8800},
+/* 383 */ {0x0007, 0x8801},
+/* 384 */ {0x00c0, 0x8800},
+/* 386 */ {0x0008, 0x8801},
+/* 387 */ {0x0003, 0x8800},
+/* 389 */ {0x0013, 0x8801},
+/* 390 */ {0x0001, 0x8800},
+/* 392 */ {0x0009, 0x8801},
+/* 393 */ {0x0000, 0x8800},
+/* 395 */ {0x000a, 0x8801},
+/* 396 */ {0x0000, 0x8800},
+/* 398 */ {0x000b, 0x8801},
+/* 399 */ {0x0000, 0x8800},
+/* 401 */ {0x000c, 0x8801},
+/* 402 */ {0x0000, 0x8800},
+/* 404 */ {0x000e, 0x8801},
+/* 405 */ {0x0004, 0x8800},
+/* 407 */ {0x000f, 0x8801},
+/* 408 */ {0x0000, 0x8800},
+/* 410 */ {0x0010, 0x8801},
+/* 411 */ {0x0006, 0x8800},
+/* 413 */ {0x0011, 0x8801},
+/* 414 */ {0x0006, 0x8800},
+/* 416 */ {0x0012, 0x8801},
+/* 417 */ {0x0000, 0x8800},
+/* 419 */ {0x0013, 0x8801},
+/* 420 */ {0x0001, 0x8800},
+/* 422 */ {0x000a, 0x8700},
+/* 423 */ {0x0000, 0x8702},
+/* 424 */ {0x0000, 0x8703},
+/* 425 */ {0x00c2, 0x8704},
+/* 426 */ {0x0001, 0x870c},
+/* 427 */ {0x0044, 0x8600},
+/* 428 */ {0x0002, 0x8606},
+/* 429 */ {0x0064, 0x8607},
+/* 430 */ {0x003a, 0x8601},
+/* 431 */ {0x0008, 0x8602},
+/* 432 */ {0x0044, 0x8600},
+/* 433 */ {0x0018, 0x8617},
+/* 434 */ {0x0008, 0x8618},
+/* 435 */ {0x00a1, 0x8656},
+/* 436 */ {0x0004, 0x865b},
+/* 437 */ {0x0002, 0x865c},
+/* 438 */ {0x0058, 0x865d},
+/* 439 */ {0x0048, 0x865e},
+/* 440 */ {0x0012, 0x8608},
+/* 441 */ {0x002c, 0x8609},
+/* 442 */ {0x0002, 0x860a},
+/* 443 */ {0x002c, 0x860b},
+/* 444 */ {0x00db, 0x860c},
+/* 445 */ {0x00f9, 0x860d},
+/* 446 */ {0x00f1, 0x860e},
+/* 447 */ {0x00e3, 0x860f},
+/* 448 */ {0x002c, 0x8610},
+/* 449 */ {0x006c, 0x8651},
+/* 450 */ {0x0041, 0x8652},
+/* 451 */ {0x0059, 0x8653},
+/* 452 */ {0x0040, 0x8654},
+/* 453 */ {0x00fa, 0x8611},
+/* 454 */ {0x00ff, 0x8612},
+/* 455 */ {0x00f8, 0x8613},
+/* 456 */ {0x0000, 0x8614},
+/* 457 */ {0x0001, 0x863f},
+/* 458 */ {0x0000, 0x8640},
+/* 459 */ {0x0026, 0x8641},
+/* 460 */ {0x0045, 0x8642},
+/* 461 */ {0x0060, 0x8643},
+/* 462 */ {0x0075, 0x8644},
+/* 463 */ {0x0088, 0x8645},
+/* 464 */ {0x009b, 0x8646},
+/* 465 */ {0x00b0, 0x8647},
+/* 466 */ {0x00c5, 0x8648},
+/* 467 */ {0x00d2, 0x8649},
+/* 468 */ {0x00dc, 0x864a},
+/* 469 */ {0x00e5, 0x864b},
+/* 470 */ {0x00eb, 0x864c},
+/* 471 */ {0x00f0, 0x864d},
+/* 472 */ {0x00f6, 0x864e},
+/* 473 */ {0x00fa, 0x864f},
+/* 474 */ {0x00ff, 0x8650},
+/* 475 */ {0x0060, 0x8657},
+/* 476 */ {0x0010, 0x8658},
+/* 477 */ {0x0018, 0x8659},
+/* 478 */ {0x0005, 0x865a},
+/* 479 */ {0x0018, 0x8660},
+/* 480 */ {0x0003, 0x8509},
+/* 481 */ {0x0011, 0x850a},
+/* 482 */ {0x0032, 0x850b},
+/* 483 */ {0x0010, 0x850c},
+/* 484 */ {0x0021, 0x850d},
+/* 485 */ {0x0001, 0x8500},
+/* 486 */ {0x0000, 0x8508},
+
+/* 487 */ {0x0012, 0x8608},
+/* 488 */ {0x002c, 0x8609},
+/* 489 */ {0x0002, 0x860a},
+/* 490 */ {0x0039, 0x860b},
+/* 491 */ {0x00d0, 0x860c},
+/* 492 */ {0x00f7, 0x860d},
+/* 493 */ {0x00ed, 0x860e},
+/* 494 */ {0x00db, 0x860f},
+/* 495 */ {0x0039, 0x8610},
+/* 496 */ {0x0012, 0x8657},
+/* 497 */ {0x0064, 0x8619},
+
+/* This line starts it all, it is not needed here */
+/* since it has been build into the driver */
+/* jfm: don't start now */
+/* 590 * {0x0030, 0x8112}, */
+ {}
+};
+
+/*
+ * Initialization data for Creative Webcam Vista
+ */
+static const __u16 spca508_vista_init_data[][3] = {
+ {0x0008, 0x8200}, /* Clear register */
+ {0x0000, 0x870b}, /* Reset CTL3 */
+ {0x0020, 0x8112}, /* Video Drop packet enable */
+ {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
+ {0x0000, 0x8110}, /* Disable everything */
+ {0x0000, 0x8114}, /* Software GPIO output data */
+ {0x0000, 0x8114},
+
+ {0x0003, 0x8111},
+ {0x0000, 0x8111},
+ {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */
+ {0x0020, 0x8112},
+ {0x0000, 0x8114},
+ {0x0001, 0x8114},
+ {0x0001, 0x8114},
+ {0x0001, 0x8114},
+ {0x0003, 0x8114},
+
+ {0x000f, 0x8402}, /* Memory bank Address */
+ {0x0000, 0x8403}, /* Memory bank Address */
+ {0x00ba, 0x8804}, /* SSI Slave address */
+ {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */
+ {0x0020, 0x8801}, /* Register address for SSI read/write */
+ {0x0044, 0x8805}, /* DATA2 */
+ {0x0004, 0x8800}, /* DATA1 -> write triggered */
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0009, 0x8801},
+ {0x0042, 0x8805},
+ {0x0001, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x003c, 0x8801},
+ {0x0001, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0001, 0x8801},
+ {0x000a, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0002, 0x8801},
+ {0x0000, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0003, 0x8801},
+ {0x0027, 0x8805},
+ {0x0001, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0004, 0x8801},
+ {0x0065, 0x8805},
+ {0x0001, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0005, 0x8801},
+ {0x0003, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0006, 0x8801},
+ {0x001c, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0007, 0x8801},
+ {0x002a, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x000e, 0x8801},
+ {0x0000, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0028, 0x8801},
+ {0x002e, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0039, 0x8801},
+ {0x0013, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x003b, 0x8801},
+ {0x000c, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0035, 0x8801},
+ {0x0028, 0x8805},
+ {0x0000, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+ /* READ { 0, 0x0001, 0x8802 } ->
+ 0000: 10 */
+ {0x0010, 0x8802},
+ {0x0009, 0x8801},
+ {0x0042, 0x8805},
+ {0x0001, 0x8800},
+ /* READ { 0, 0x0001, 0x8803 } ->
+ 0000: 00 */
+
+ {0x0050, 0x8703},
+ {0x0002, 0x8704}, /* External input CKIx1 */
+ {0x0001, 0x870C}, /* Select CKOx2 output */
+ {0x009A, 0x8600}, /* Line memory Read Counter (L) */
+ {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
+ {0x0023, 0x8601},
+ {0x0010, 0x8602},
+ {0x000A, 0x8603},
+ {0x009A, 0x8600},
+ {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */
+ {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */
+ {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */
+ {0x0048, 0x865E}, /* Vertical valid lines window (L) */
+ {0x0000, 0x865F},
+
+ {0x0006, 0x8660},
+ /* Enable nibble data input, select nibble input order */
+
+ {0x0013, 0x8608}, /* A11 Coeficients for color correction */
+ {0x0028, 0x8609},
+ /* Note: these values are confirmed at the end of array */
+ {0x0005, 0x860A}, /* ... */
+ {0x0025, 0x860B},
+ {0x00E1, 0x860C},
+ {0x00FA, 0x860D},
+ {0x00F4, 0x860E},
+ {0x00E8, 0x860F},
+ {0x0025, 0x8610}, /* A33 Coef. */
+ {0x00FC, 0x8611}, /* White balance offset: R */
+ {0x0001, 0x8612}, /* White balance offset: Gr */
+ {0x00FE, 0x8613}, /* White balance offset: B */
+ {0x0000, 0x8614}, /* White balance offset: Gb */
+
+ {0x0064, 0x8651}, /* R gain for white balance (L) */
+ {0x0040, 0x8652}, /* Gr gain for white balance (L) */
+ {0x0066, 0x8653}, /* B gain for white balance (L) */
+ {0x0040, 0x8654}, /* Gb gain for white balance (L) */
+ {0x0001, 0x863F}, /* Enable fixed gamma correction */
+
+ {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
+ /* UV division: UV no change, Enable New edge enhancement */
+ {0x0018, 0x8657}, /* Edge gain high threshold */
+ {0x0020, 0x8658}, /* Edge gain low threshold */
+ {0x000A, 0x8659}, /* Edge bandwidth high threshold */
+ {0x0005, 0x865A}, /* Edge bandwidth low threshold */
+ {0x0064, 0x8607}, /* UV filter enable */
+
+ {0x0016, 0x8660},
+ {0x0000, 0x86B0}, /* Bad pixels compensation address */
+ {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */
+ {0x0000, 0x86B2},
+ {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */
+ {0x0000, 0x86B4},
+
+ {0x0001, 0x86B0},
+ {0x00F5, 0x86B1},
+ {0x0000, 0x86B2},
+ {0x00C6, 0x86B3},
+ {0x0000, 0x86B4},
+
+ {0x0002, 0x86B0},
+ {0x001C, 0x86B1},
+ {0x0001, 0x86B2},
+ {0x00D7, 0x86B3},
+ {0x0000, 0x86B4},
+
+ {0x0003, 0x86B0},
+ {0x001C, 0x86B1},
+ {0x0001, 0x86B2},
+ {0x00D8, 0x86B3},
+ {0x0000, 0x86B4},
+
+ {0x0004, 0x86B0},
+ {0x001D, 0x86B1},
+ {0x0001, 0x86B2},
+ {0x00D8, 0x86B3},
+ {0x0000, 0x86B4},
+ {0x001E, 0x8660},
+
+ /* READ { 0, 0x0000, 0x8608 } ->
+ 0000: 13 */
+ /* READ { 0, 0x0000, 0x8609 } ->
+ 0000: 28 */
+ /* READ { 0, 0x0000, 0x8610 } ->
+ 0000: 05 */
+ /* READ { 0, 0x0000, 0x8611 } ->
+ 0000: 25 */
+ /* READ { 0, 0x0000, 0x8612 } ->
+ 0000: e1 */
+ /* READ { 0, 0x0000, 0x8613 } ->
+ 0000: fa */
+ /* READ { 0, 0x0000, 0x8614 } ->
+ 0000: f4 */
+ /* READ { 0, 0x0000, 0x8615 } ->
+ 0000: e8 */
+ /* READ { 0, 0x0000, 0x8616 } ->
+ 0000: 25 */
+ {}
+};
+
+static int reg_write(struct usb_device *dev,
+ __u16 index, __u16 value)
+{
+ int ret;
+
+ ret = usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ 0, /* request */
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 500);
+ PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x",
+ index, value);
+ if (ret < 0)
+ PDEBUG(D_ERR|D_USBO, "reg write: error %d", ret);
+ return ret;
+}
+
+/* read 1 byte */
+/* returns: negative is error, pos or zero is data */
+static int reg_read(struct gspca_dev *gspca_dev,
+ __u16 index) /* wIndex */
+{
+ int ret;
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0, /* register */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, 1,
+ 500); /* timeout */
+ PDEBUG(D_USBI, "reg read i:%04x --> %02x",
+ index, gspca_dev->usb_buf[0]);
+ if (ret < 0) {
+ PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret);
+ return ret;
+ }
+ return gspca_dev->usb_buf[0];
+}
+
+static int write_vector(struct gspca_dev *gspca_dev,
+ const __u16 data[][3])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, i = 0;
+
+ while (data[i][1] != 0) {
+ ret = reg_write(dev, data[i][1], data[i][0]);
+ if (ret < 0)
+ return ret;
+ i++;
+ }
+ return 0;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 product;
+ int data1, data2;
+
+ product = id->idProduct;
+ switch (id->idVendor) {
+ case 0x0130: /* Clone webcam */
+/* switch (product) { */
+/* case 0x0130: */
+ sd->subtype = HamaUSBSightcam; /* same as Hama 0010 */
+/* break; */
+/* } */
+ break;
+ case 0x041e: /* Creative cameras */
+/* switch (product) { */
+/* case 0x4018: */
+ sd->subtype = CreativeVista;
+/* break; */
+/* } */
+ break;
+ case 0x0461: /* MicroInnovation */
+/* switch (product) { */
+/* case 0x0815: */
+ sd->subtype = MicroInnovationIC200;
+/* break; */
+/* } */
+ break;
+ case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
+/* switch (product) { */
+/* case 0x110: */
+ sd->subtype = ViewQuestVQ110;
+/* break; */
+/* } */
+ break;
+ case 0x0af9: /* Hama cameras */
+ switch (product) {
+ case 0x0010:
+ sd->subtype = HamaUSBSightcam;
+ break;
+ case 0x0011:
+ sd->subtype = HamaUSBSightcam2;
+ break;
+ }
+ break;
+ case 0x8086: /* Intel */
+/* switch (product) { */
+/* case 0x0110: */
+ sd->subtype = IntelEasyPCCamera;
+/* break; */
+/* } */
+ break;
+ }
+
+ /* Read from global register the USB product and vendor IDs, just to
+ * prove that we can communicate with the device. This works, which
+ * confirms at we are communicating properly and that the device
+ * is a 508. */
+ data1 = reg_read(gspca_dev, 0x8104);
+ data2 = reg_read(gspca_dev, 0x8105);
+ PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1);
+
+ data1 = reg_read(gspca_dev, 0x8106);
+ data2 = reg_read(gspca_dev, 0x8107);
+ PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1);
+
+ data1 = reg_read(gspca_dev, 0x8621);
+ PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ cam->cam_mode = sif_mode;
+ cam->nmodes = ARRAY_SIZE(sif_mode);
+ sd->brightness = BRIGHTNESS_DEF;
+
+ switch (sd->subtype) {
+ case ViewQuestVQ110:
+ if (write_vector(gspca_dev, spca508_init_data))
+ return -1;
+ break;
+ default:
+/* case MicroInnovationIC200: */
+/* case IntelEasyPCCamera: */
+ if (write_vector(gspca_dev, spca508cs110_init_data))
+ return -1;
+ break;
+ case HamaUSBSightcam:
+ if (write_vector(gspca_dev, spca508_sightcam_init_data))
+ return -1;
+ break;
+ case HamaUSBSightcam2:
+ if (write_vector(gspca_dev, spca508_sightcam2_init_data))
+ return -1;
+ break;
+ case CreativeVista:
+ if (write_vector(gspca_dev, spca508_vista_init_data))
+ return -1;
+ break;
+ }
+ return 0; /* success */
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+/* write_vector(gspca_dev, spca508_open_data); */
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ int mode;
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg_write(gspca_dev->dev, 0x8500, mode);
+ switch (mode) {
+ case 0:
+ case 1:
+ reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */
+ break;
+ default:
+/* case 2: */
+/* case 3: */
+ reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */
+ break;
+ }
+ reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ /* Video ISO disable, Video Drop Packet enable: */
+ reg_write(gspca_dev->dev, 0x8112, 0x20);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+/* convert YUVY per line to YUYV (YUV 4:2:2) */
+static void yuvy_decode(unsigned char *out,
+ unsigned char *in,
+ int width,
+ int height)
+{
+ unsigned char *Ui, *Vi, *yi, *yi1;
+ unsigned char *out1;
+ int i, j;
+
+ yi = in;
+ for (i = height / 2; --i >= 0; ) {
+ out1 = out + width * 2; /* next line */
+ Ui = yi + width;
+ Vi = Ui + width / 2;
+ yi1 = Vi + width / 2;
+ for (j = width / 2; --j >= 0; ) {
+ *out++ = 128 + *yi++;
+ *out++ = 128 + *Ui;
+ *out++ = 128 + *yi++;
+ *out++ = 128 + *Vi;
+
+ *out1++ = 128 + *yi1++;
+ *out1++ = 128 + *Ui++;
+ *out1++ = 128 + *yi1++;
+ *out1++ = 128 + *Vi++;
+ }
+ yi += width * 2;
+ out = out1;
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (data[0]) {
+ case 0: /* start of frame */
+ if (gspca_dev->last_packet_type == FIRST_PACKET) {
+ yuvy_decode(sd->tmpbuf2, sd->tmpbuf,
+ gspca_dev->width,
+ gspca_dev->height);
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ sd->tmpbuf2,
+ gspca_dev->width
+ * gspca_dev->height
+ * 2);
+ }
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, 0);
+ data += SPCA508_OFFSET_DATA;
+ len -= SPCA508_OFFSET_DATA;
+ if (len > 0)
+ memcpy(sd->tmpbuf, data, len);
+ else
+ len = 0;
+ sd->buflen = len;
+ return;
+ case 0xff: /* drop */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ data += 1;
+ len -= 1;
+ memcpy(&sd->tmpbuf[sd->buflen], data, len);
+ sd->buflen += len;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 brightness = sd->brightness;
+
+ /* MX seem contrast */
+ reg_write(gspca_dev->dev, 0x8651, brightness);
+ reg_write(gspca_dev->dev, 0x8652, brightness);
+ reg_write(gspca_dev->dev, 0x8653, brightness);
+ reg_write(gspca_dev->dev, 0x8654, brightness);
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = reg_read(gspca_dev, 0x8651);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")},
+ {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")},
+ {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")},
+ {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")},
+ {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")},
+ {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")},
+ {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
new file mode 100644
index 00000000000..b659bd0f788
--- /dev/null
+++ b/drivers/media/video/gspca/spca561.c
@@ -0,0 +1,1052 @@
+/*
+ * Sunplus spca561 subdriver
+ *
+ * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "spca561"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned short contrast;
+ __u8 brightness;
+ __u8 autogain;
+
+ __u8 chip_revision;
+ signed char ag_cnt;
+#define AG_CNT_START 13
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 63,
+ .step = 1,
+ .default_value = 32,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0x3fff,
+ .step = 1,
+ .default_value = 0x2000,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_AUTOGAIN 2
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 3},
+ {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 4 / 8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 4 / 8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/*
+ * Initialization data
+ * I'm not very sure how to split initialization from open data
+ * chunks. For now, we'll consider everything as initialization
+ */
+/* Frame packet header offsets for the spca561 */
+#define SPCA561_OFFSET_SNAP 1
+#define SPCA561_OFFSET_TYPE 2
+#define SPCA561_OFFSET_COMPRESS 3
+#define SPCA561_OFFSET_FRAMSEQ 4
+#define SPCA561_OFFSET_GPIO 5
+#define SPCA561_OFFSET_USBBUFF 6
+#define SPCA561_OFFSET_WIN2GRAVE 7
+#define SPCA561_OFFSET_WIN2RAVE 8
+#define SPCA561_OFFSET_WIN2BAVE 9
+#define SPCA561_OFFSET_WIN2GBAVE 10
+#define SPCA561_OFFSET_WIN1GRAVE 11
+#define SPCA561_OFFSET_WIN1RAVE 12
+#define SPCA561_OFFSET_WIN1BAVE 13
+#define SPCA561_OFFSET_WIN1GBAVE 14
+#define SPCA561_OFFSET_FREQ 15
+#define SPCA561_OFFSET_VSYNC 16
+#define SPCA561_OFFSET_DATA 1
+#define SPCA561_INDEX_I2C_BASE 0x8800
+#define SPCA561_SNAPBIT 0x20
+#define SPCA561_SNAPCTRL 0x40
+enum {
+ Rev072A = 0,
+ Rev012A,
+};
+
+static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value)
+{
+ int ret;
+
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0, /* request */
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 500);
+ PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write: error %d", ret);
+}
+
+static void write_vector(struct gspca_dev *gspca_dev,
+ const __u16 data[][2])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int i;
+
+ i = 0;
+ while (data[i][1] != 0) {
+ reg_w_val(dev, data[i][1], data[i][0]);
+ i++;
+ }
+}
+
+/* read 'len' bytes to gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 index, __u16 length)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, length, 500);
+}
+
+static void reg_w_buf(struct gspca_dev *gspca_dev,
+ __u16 index, const __u8 *buffer, __u16 len)
+{
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, len, 500);
+}
+
+static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode)
+{
+ reg_w_val(gspca_dev->dev, 0x92, 0x8804);
+ reg_w_val(gspca_dev->dev, mode, 0x8802);
+}
+
+static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg)
+{
+ int retry = 60;
+ __u8 DataLow;
+ __u8 DataHight;
+
+ DataLow = valeur;
+ DataHight = valeur >> 8;
+ reg_w_val(gspca_dev->dev, reg, 0x8801);
+ reg_w_val(gspca_dev->dev, DataLow, 0x8805);
+ reg_w_val(gspca_dev->dev, DataHight, 0x8800);
+ while (retry--) {
+ reg_r(gspca_dev, 0x8803, 1);
+ if (!gspca_dev->usb_buf[0])
+ break;
+ }
+}
+
+static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
+{
+ int retry = 60;
+ __u8 value;
+ __u8 vallsb;
+
+ reg_w_val(gspca_dev->dev, 0x92, 0x8804);
+ reg_w_val(gspca_dev->dev, reg, 0x8801);
+ reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802);
+ while (retry--) {
+ reg_r(gspca_dev, 0x8803, 1);
+ if (!gspca_dev->usb_buf)
+ break;
+ }
+ if (retry == 0)
+ return -1;
+ reg_r(gspca_dev, 0x8800, 1);
+ value = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8805, 1);
+ vallsb = gspca_dev->usb_buf[0];
+ return ((int) value << 8) | vallsb;
+}
+
+static const __u16 spca561_init_data[][2] = {
+ {0x0000, 0x8114}, /* Software GPIO output data */
+ {0x0001, 0x8114}, /* Software GPIO output data */
+ {0x0000, 0x8112}, /* Some kind of reset */
+ {0x0003, 0x8701}, /* PCLK clock delay adjustment */
+ {0x0001, 0x8703}, /* HSYNC from cmos inverted */
+ {0x0011, 0x8118}, /* Enable and conf sensor */
+ {0x0001, 0x8118}, /* Conf sensor */
+ {0x0092, 0x8804}, /* I know nothing about these */
+ {0x0010, 0x8802}, /* 0x88xx registers, so I won't */
+ /***************/
+ {0x000d, 0x8805}, /* sensor default setting */
+ {0x0001, 0x8801}, /* 1 <- 0x0d */
+ {0x0000, 0x8800},
+ {0x0018, 0x8805},
+ {0x0002, 0x8801}, /* 2 <- 0x18 */
+ {0x0000, 0x8800},
+ {0x0065, 0x8805},
+ {0x0004, 0x8801}, /* 4 <- 0x01 0x65 */
+ {0x0001, 0x8800},
+ {0x0021, 0x8805},
+ {0x0005, 0x8801}, /* 5 <- 0x21 */
+ {0x0000, 0x8800},
+ {0x00aa, 0x8805},
+ {0x0007, 0x8801}, /* 7 <- 0xaa */
+ {0x0000, 0x8800},
+ {0x0004, 0x8805},
+ {0x0020, 0x8801}, /* 0x20 <- 0x15 0x04 */
+ {0x0015, 0x8800},
+ {0x0002, 0x8805},
+ {0x0039, 0x8801}, /* 0x39 <- 0x02 */
+ {0x0000, 0x8800},
+ {0x0010, 0x8805},
+ {0x0035, 0x8801}, /* 0x35 <- 0x10 */
+ {0x0000, 0x8800},
+ {0x0049, 0x8805},
+ {0x0009, 0x8801}, /* 0x09 <- 0x10 0x49 */
+ {0x0010, 0x8800},
+ {0x000b, 0x8805},
+ {0x0028, 0x8801}, /* 0x28 <- 0x0b */
+ {0x0000, 0x8800},
+ {0x000f, 0x8805},
+ {0x003b, 0x8801}, /* 0x3b <- 0x0f */
+ {0x0000, 0x8800},
+ {0x0000, 0x8805},
+ {0x003c, 0x8801}, /* 0x3c <- 0x00 */
+ {0x0000, 0x8800},
+ /***************/
+ {0x0018, 0x8601}, /* Pixel/line selection for color separation */
+ {0x0000, 0x8602}, /* Optical black level for user setting */
+ {0x0060, 0x8604}, /* Optical black horizontal offset */
+ {0x0002, 0x8605}, /* Optical black vertical offset */
+ {0x0000, 0x8603}, /* Non-automatic optical black level */
+ {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
+ {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */
+ {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */
+ {0x0090, 0x865e}, /* Vertical valid lines window (x2) */
+ {0x00e0, 0x8406}, /* Memory buffer threshold */
+ {0x0000, 0x8660}, /* Compensation memory stuff */
+ {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
+ {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
+ {0x0001, 0x8200}, /* OprMode to be executed by hardware */
+ {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */
+ {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
+ {0x0001, 0x8200}, /* OprMode to be executed by hardware */
+ {0x0010, 0x8660}, /* Compensation memory stuff */
+ {0x0018, 0x8660}, /* Compensation memory stuff */
+
+ {0x0004, 0x8611}, /* R offset for white balance */
+ {0x0004, 0x8612}, /* Gr offset for white balance */
+ {0x0007, 0x8613}, /* B offset for white balance */
+ {0x0000, 0x8614}, /* Gb offset for white balance */
+ {0x008c, 0x8651}, /* R gain for white balance */
+ {0x008c, 0x8652}, /* Gr gain for white balance */
+ {0x00b5, 0x8653}, /* B gain for white balance */
+ {0x008c, 0x8654}, /* Gb gain for white balance */
+ {0x0002, 0x8502}, /* Maximum average bit rate stuff */
+
+ {0x0011, 0x8802},
+ {0x0087, 0x8700}, /* Set master clock (96Mhz????) */
+ {0x0081, 0x8702}, /* Master clock output enable */
+
+ {0x0000, 0x8500}, /* Set image type (352x288 no compression) */
+ /* Originally was 0x0010 (352x288 compression) */
+
+ {0x0002, 0x865b}, /* Horizontal offset for valid pixels */
+ {0x0003, 0x865c}, /* Vertical offset for valid lines */
+ /***************//* sensor active */
+ {0x0003, 0x8801}, /* 0x03 <- 0x01 0x21 //289 */
+ {0x0021, 0x8805},
+ {0x0001, 0x8800},
+ {0x0004, 0x8801}, /* 0x04 <- 0x01 0x65 //357 */
+ {0x0065, 0x8805},
+ {0x0001, 0x8800},
+ {0x0005, 0x8801}, /* 0x05 <- 0x2f */
+ {0x002f, 0x8805},
+ {0x0000, 0x8800},
+ {0x0006, 0x8801}, /* 0x06 <- 0 */
+ {0x0000, 0x8805},
+ {0x0000, 0x8800},
+ {0x000a, 0x8801}, /* 0x0a <- 2 */
+ {0x0002, 0x8805},
+ {0x0000, 0x8800},
+ {0x0009, 0x8801}, /* 0x09 <- 0x1061 */
+ {0x0061, 0x8805},
+ {0x0010, 0x8800},
+ {0x0035, 0x8801}, /* 0x35 <-0x14 */
+ {0x0014, 0x8805},
+ {0x0000, 0x8800},
+ {0x0030, 0x8112}, /* ISO and drop packet enable */
+ {0x0000, 0x8112}, /* Some kind of reset ???? */
+ {0x0009, 0x8118}, /* Enable sensor and set standby */
+ {0x0000, 0x8114}, /* Software GPIO output data */
+ {0x0000, 0x8114}, /* Software GPIO output data */
+ {0x0001, 0x8114}, /* Software GPIO output data */
+ {0x0000, 0x8112}, /* Some kind of reset ??? */
+ {0x0003, 0x8701},
+ {0x0001, 0x8703},
+ {0x0011, 0x8118},
+ {0x0001, 0x8118},
+ /***************/
+ {0x0092, 0x8804},
+ {0x0010, 0x8802},
+ {0x000d, 0x8805},
+ {0x0001, 0x8801},
+ {0x0000, 0x8800},
+ {0x0018, 0x8805},
+ {0x0002, 0x8801},
+ {0x0000, 0x8800},
+ {0x0065, 0x8805},
+ {0x0004, 0x8801},
+ {0x0001, 0x8800},
+ {0x0021, 0x8805},
+ {0x0005, 0x8801},
+ {0x0000, 0x8800},
+ {0x00aa, 0x8805},
+ {0x0007, 0x8801}, /* mode 0xaa */
+ {0x0000, 0x8800},
+ {0x0004, 0x8805},
+ {0x0020, 0x8801},
+ {0x0015, 0x8800}, /* mode 0x0415 */
+ {0x0002, 0x8805},
+ {0x0039, 0x8801},
+ {0x0000, 0x8800},
+ {0x0010, 0x8805},
+ {0x0035, 0x8801},
+ {0x0000, 0x8800},
+ {0x0049, 0x8805},
+ {0x0009, 0x8801},
+ {0x0010, 0x8800},
+ {0x000b, 0x8805},
+ {0x0028, 0x8801},
+ {0x0000, 0x8800},
+ {0x000f, 0x8805},
+ {0x003b, 0x8801},
+ {0x0000, 0x8800},
+ {0x0000, 0x8805},
+ {0x003c, 0x8801},
+ {0x0000, 0x8800},
+ {0x0002, 0x8502},
+ {0x0039, 0x8801},
+ {0x0000, 0x8805},
+ {0x0000, 0x8800},
+
+ {0x0087, 0x8700}, /* overwrite by start */
+ {0x0081, 0x8702},
+ {0x0000, 0x8500},
+/* {0x0010, 0x8500}, -- Previous line was this */
+ {0x0002, 0x865b},
+ {0x0003, 0x865c},
+ /***************/
+ {0x0003, 0x8801}, /* 0x121-> 289 */
+ {0x0021, 0x8805},
+ {0x0001, 0x8800},
+ {0x0004, 0x8801}, /* 0x165 -> 357 */
+ {0x0065, 0x8805},
+ {0x0001, 0x8800},
+ {0x0005, 0x8801}, /* 0x2f //blanking control colonne */
+ {0x002f, 0x8805},
+ {0x0000, 0x8800},
+ {0x0006, 0x8801}, /* 0x00 //blanking mode row */
+ {0x0000, 0x8805},
+ {0x0000, 0x8800},
+ {0x000a, 0x8801}, /* 0x01 //0x02 */
+ {0x0001, 0x8805},
+ {0x0000, 0x8800},
+ {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock
+ * 0001 0 | 000 0110 0001 */
+ {0x0061, 0x8805}, /* 61 31 */
+ {0x0008, 0x8800}, /* 08 */
+ {0x0035, 0x8801}, /* 0x14 - set gain general */
+ {0x001f, 0x8805}, /* 0x14 */
+ {0x0000, 0x8800},
+ {0x0030, 0x8112},
+ {}
+};
+
+static void sensor_reset(struct gspca_dev *gspca_dev)
+{
+ reg_w_val(gspca_dev->dev, 0x8631, 0xc8);
+ reg_w_val(gspca_dev->dev, 0x8634, 0xc8);
+ reg_w_val(gspca_dev->dev, 0x8112, 0x00);
+ reg_w_val(gspca_dev->dev, 0x8114, 0x00);
+ reg_w_val(gspca_dev->dev, 0x8118, 0x21);
+ i2c_init(gspca_dev, 0x14);
+ i2c_write(gspca_dev, 1, 0x0d);
+ i2c_write(gspca_dev, 0, 0x0d);
+}
+
+/******************** QC Express etch2 stuff ********************/
+static const __u16 Pb100_1map8300[][2] = {
+ /* reg, value */
+ {0x8320, 0x3304},
+
+ {0x8303, 0x0125}, /* image area */
+ {0x8304, 0x0169},
+ {0x8328, 0x000b},
+ {0x833c, 0x0001},
+
+ {0x832f, 0x0419},
+ {0x8307, 0x00aa},
+ {0x8301, 0x0003},
+ {0x8302, 0x000e},
+ {}
+};
+static const __u16 Pb100_2map8300[][2] = {
+ /* reg, value */
+ {0x8339, 0x0000},
+ {0x8307, 0x00aa},
+ {}
+};
+
+static const __u16 spca561_161rev12A_data1[][2] = {
+ {0x21, 0x8118},
+ {0x01, 0x8114},
+ {0x00, 0x8112},
+ {0x92, 0x8804},
+ {0x04, 0x8802}, /* windows uses 08 */
+ {}
+};
+static const __u16 spca561_161rev12A_data2[][2] = {
+ {0x21, 0x8118},
+ {0x10, 0x8500},
+ {0x07, 0x8601},
+ {0x07, 0x8602},
+ {0x04, 0x8501},
+ {0x21, 0x8118},
+
+ {0x07, 0x8201}, /* windows uses 02 */
+ {0x08, 0x8200},
+ {0x01, 0x8200},
+
+ {0x00, 0x8114},
+ {0x01, 0x8114}, /* windows uses 00 */
+
+ {0x90, 0x8604},
+ {0x00, 0x8605},
+ {0xb0, 0x8603},
+
+ /* sensor gains */
+ {0x00, 0x8610}, /* *red */
+ {0x00, 0x8611}, /* 3f *green */
+ {0x00, 0x8612}, /* green *blue */
+ {0x00, 0x8613}, /* blue *green */
+ {0x35, 0x8614}, /* green *red */
+ {0x35, 0x8615}, /* 40 *green */
+ {0x35, 0x8616}, /* 7a *blue */
+ {0x35, 0x8617}, /* 40 *green */
+
+ {0x0c, 0x8620}, /* 0c */
+ {0xc8, 0x8631}, /* c8 */
+ {0xc8, 0x8634}, /* c8 */
+ {0x23, 0x8635}, /* 23 */
+ {0x1f, 0x8636}, /* 1f */
+ {0xdd, 0x8637}, /* dd */
+ {0xe1, 0x8638}, /* e1 */
+ {0x1d, 0x8639}, /* 1d */
+ {0x21, 0x863a}, /* 21 */
+ {0xe3, 0x863b}, /* e3 */
+ {0xdf, 0x863c}, /* df */
+ {0xf0, 0x8505},
+ {0x32, 0x850a},
+ {}
+};
+
+static void sensor_mapwrite(struct gspca_dev *gspca_dev,
+ const __u16 sensormap[][2])
+{
+ int i = 0;
+ __u8 usbval[2];
+
+ while (sensormap[i][0]) {
+ usbval[0] = sensormap[i][1];
+ usbval[1] = sensormap[i][1] >> 8;
+ reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2);
+ i++;
+ }
+}
+static void init_161rev12A(struct gspca_dev *gspca_dev)
+{
+ sensor_reset(gspca_dev);
+ write_vector(gspca_dev, spca561_161rev12A_data1);
+ sensor_mapwrite(gspca_dev, Pb100_1map8300);
+ write_vector(gspca_dev, spca561_161rev12A_data2);
+ sensor_mapwrite(gspca_dev, Pb100_2map8300);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ __u16 vendor, product;
+ __u8 data1, data2;
+
+ /* Read frm global register the USB product and vendor IDs, just to
+ * prove that we can communicate with the device. This works, which
+ * confirms at we are communicating properly and that the device
+ * is a 561. */
+ reg_r(gspca_dev, 0x8104, 1);
+ data1 = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8105, 1);
+ data2 = gspca_dev->usb_buf[0];
+ vendor = (data2 << 8) | data1;
+ reg_r(gspca_dev, 0x8106, 1);
+ data1 = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8107, 1);
+ data2 = gspca_dev->usb_buf[0];
+ product = (data2 << 8) | data1;
+ if (vendor != id->idVendor || product != id->idProduct) {
+ PDEBUG(D_PROBE, "Bad vendor / product from device");
+ return -EINVAL;
+ }
+ switch (product) {
+ case 0x0928:
+ case 0x0929:
+ case 0x092a:
+ case 0x092b:
+ case 0x092c:
+ case 0x092d:
+ case 0x092e:
+ case 0x092f:
+ case 0x403b:
+ sd->chip_revision = Rev012A;
+ break;
+ default:
+/* case 0x0561:
+ case 0x0815: * ?? in spca508.c
+ case 0x401a:
+ case 0x7004:
+ case 0x7e50:
+ case 0xa001:
+ case 0xcdee: */
+ sd->chip_revision = Rev072A;
+ break;
+ }
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+ gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
+ cam->cam_mode = sif_mode;
+ cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->chip_revision) {
+ case Rev072A:
+ PDEBUG(D_STREAM, "Chip revision id: 072a");
+ write_vector(gspca_dev, spca561_init_data);
+ break;
+ default:
+/* case Rev012A: */
+ PDEBUG(D_STREAM, "Chip revision id: 012a");
+ init_161rev12A(gspca_dev);
+ break;
+ }
+ return 0;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 lowb;
+ int expotimes;
+
+ switch (sd->chip_revision) {
+ case Rev072A:
+ lowb = sd->contrast >> 8;
+ reg_w_val(dev, lowb, 0x8651);
+ reg_w_val(dev, lowb, 0x8652);
+ reg_w_val(dev, lowb, 0x8653);
+ reg_w_val(dev, lowb, 0x8654);
+ break;
+ case Rev012A: {
+ __u8 Reg8391[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 };
+
+ /* Write camera sensor settings */
+ expotimes = (sd->contrast >> 5) & 0x07ff;
+ Reg8391[0] = expotimes & 0xff; /* exposure */
+ Reg8391[1] = 0x18 | (expotimes >> 8);
+ Reg8391[2] = sd->brightness; /* gain */
+ reg_w_buf(gspca_dev, 0x8391, Reg8391, 8);
+ reg_w_buf(gspca_dev, 0x8390, Reg8391, 8);
+ break;
+ }
+ }
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int Clck;
+ __u8 Reg8307[] = { 0xaa, 0x00 };
+ int mode;
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ switch (sd->chip_revision) {
+ case Rev072A:
+ switch (mode) {
+ default:
+/* case 0:
+ case 1: */
+ Clck = 0x25;
+ break;
+ case 2:
+ Clck = 0x22;
+ break;
+ case 3:
+ Clck = 0x21;
+ break;
+ }
+ reg_w_val(dev, 0x8500, mode); /* mode */
+ reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
+ reg_w_val(dev, 0x8112, 0x10 | 0x20);
+ break;
+ default:
+/* case Rev012A: */
+ switch (mode) {
+ case 0:
+ case 1:
+ Clck = 0x8a;
+ break;
+ case 2:
+ Clck = 0x85;
+ break;
+ default:
+ Clck = 0x83;
+ break;
+ }
+ if (mode <= 1) {
+ /* Use compression on 320x240 and above */
+ reg_w_val(dev, 0x8500, 0x10 | mode);
+ } else {
+ /* I couldn't get the compression to work below 320x240
+ * Fortunately at these resolutions the bandwidth
+ * is sufficient to push raw frames at ~20fps */
+ reg_w_val(dev, 0x8500, mode);
+ } /* -- qq@kuku.eu.org */
+ reg_w_buf(gspca_dev, 0x8307, Reg8307, 2);
+ reg_w_val(gspca_dev->dev, 0x8700, Clck);
+ /* 0x8f 0x85 0x27 clock */
+ reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
+ reg_w_val(gspca_dev->dev, 0x850b, 0x03);
+ setcontrast(gspca_dev);
+ break;
+ }
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ reg_w_val(gspca_dev->dev, 0x8112, 0x20);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+ reg_w_val(gspca_dev->dev, 0x8114, 0);
+}
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int expotimes = 0;
+ int pixelclk = 0;
+ int gainG = 0;
+ __u8 R, Gr, Gb, B;
+ int y;
+ __u8 luma_mean = 110;
+ __u8 luma_delta = 20;
+ __u8 spring = 4;
+
+ switch (sd->chip_revision) {
+ case Rev072A:
+ reg_r(gspca_dev, 0x8621, 1);
+ Gr = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8622, 1);
+ R = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8623, 1);
+ B = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8624, 1);
+ Gb = gspca_dev->usb_buf[0];
+ y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
+ /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
+ /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
+ /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
+
+ if (y < luma_mean - luma_delta ||
+ y > luma_mean + luma_delta) {
+ expotimes = i2c_read(gspca_dev, 0x09, 0x10);
+ pixelclk = 0x0800;
+ expotimes = expotimes & 0x07ff;
+ /* PDEBUG(D_PACK,
+ "Exposition Times 0x%03X Clock 0x%04X ",
+ expotimes,pixelclk); */
+ gainG = i2c_read(gspca_dev, 0x35, 0x10);
+ /* PDEBUG(D_PACK,
+ "reading Gain register %d", gainG); */
+
+ expotimes += (luma_mean - y) >> spring;
+ gainG += (luma_mean - y) / 50;
+ /* PDEBUG(D_PACK,
+ "compute expotimes %d gain %d",
+ expotimes,gainG); */
+
+ if (gainG > 0x3f)
+ gainG = 0x3f;
+ else if (gainG < 4)
+ gainG = 3;
+ i2c_write(gspca_dev, gainG, 0x35);
+
+ if (expotimes >= 0x0256)
+ expotimes = 0x0256;
+ else if (expotimes < 4)
+ expotimes = 3;
+ i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
+ }
+ break;
+ case Rev012A:
+ /* sensor registers is access and memory mapped to 0x8300 */
+ /* readind all 0x83xx block the sensor */
+ /*
+ * The data from the header seem wrong where is the luma
+ * and chroma mean value
+ * at the moment set exposure in contrast set
+ */
+ break;
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (data[0]) {
+ case 0: /* start of frame */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
+ if (sd->ag_cnt >= 0) {
+ if (--sd->ag_cnt < 0) {
+ sd->ag_cnt = AG_CNT_START;
+ setautogain(gspca_dev);
+ }
+ }
+ data += SPCA561_OFFSET_DATA;
+ len -= SPCA561_OFFSET_DATA;
+ if (data[1] & 0x10) {
+ /* compressed bayer */
+ gspca_frame_add(gspca_dev, FIRST_PACKET,
+ frame, data, len);
+ } else {
+ /* raw bayer (with a header, which we skip) */
+ data += 20;
+ len -= 20;
+ gspca_frame_add(gspca_dev, FIRST_PACKET,
+ frame, data, len);
+ }
+ return;
+ case 0xff: /* drop */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ data++;
+ len--;
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 value;
+
+ switch (sd->chip_revision) {
+ case Rev072A:
+ value = sd->brightness;
+ reg_w_val(gspca_dev->dev, value, 0x8611);
+ reg_w_val(gspca_dev->dev, value, 0x8612);
+ reg_w_val(gspca_dev->dev, value, 0x8613);
+ reg_w_val(gspca_dev->dev, value, 0x8614);
+ break;
+ default:
+/* case Rev012A: */
+ setcontrast(gspca_dev);
+ break;
+ }
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 tot;
+
+ switch (sd->chip_revision) {
+ case Rev072A:
+ tot = 0;
+ reg_r(gspca_dev, 0x8611, 1);
+ tot += gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8612, 1);
+ tot += gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8613, 1);
+ tot += gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8614, 1);
+ tot += gspca_dev->usb_buf[0];
+ sd->brightness = tot >> 2;
+ break;
+ default:
+/* case Rev012A: */
+ /* no way to read sensor settings */
+ break;
+ }
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 tot;
+
+ switch (sd->chip_revision) {
+ case Rev072A:
+ tot = 0;
+ reg_r(gspca_dev, 0x8651, 1);
+ tot += gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8652, 1);
+ tot += gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8653, 1);
+ tot += gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0x8654, 1);
+ tot += gspca_dev->usb_buf[0];
+ sd->contrast = tot << 6;
+ break;
+ default:
+/* case Rev012A: */
+ /* no way to read sensor settings */
+ break;
+ }
+ PDEBUG(D_CONF, "get contrast %d", sd->contrast);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcontrast(gspca_dev);
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (val)
+ sd->ag_cnt = AG_CNT_START;
+ else
+ sd->ag_cnt = -1;
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")},
+ {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")},
+ {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")},
+ {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")},
+ {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")},
+ {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")},
+ {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")},
+ {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")},
+ {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")},
+ {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")},
+ {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")},
+ {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")},
+ {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")},
+ {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")},
+ {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
new file mode 100644
index 00000000000..c78ee0d3e59
--- /dev/null
+++ b/drivers/media/video/gspca/stk014.c
@@ -0,0 +1,592 @@
+/*
+ * Syntek DV4000 (STK014) subdriver
+ *
+ * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr)
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "stk014"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
+MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char lightfreq;
+};
+
+/* global parameters */
+static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define CONTRAST_DEF 127
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define COLOR_DEF 127
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_POWER_LINE_FREQUENCY,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "Light frequency filter",
+ .minimum = 1,
+ .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
+ .step = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
+ },
+ .set = sd_setfreq,
+ .get = sd_getfreq,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+/* -- read a register -- */
+static int reg_r(struct gspca_dev *gspca_dev,
+ __u16 index)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ 0x00,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00,
+ index,
+ gspca_dev->usb_buf, 1,
+ 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_r err %d", ret);
+ return ret;
+ }
+ return gspca_dev->usb_buf[0];
+}
+
+/* -- write a register -- */
+static int reg_w(struct gspca_dev *gspca_dev,
+ __u16 index, __u16 value)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x01,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ index,
+ NULL,
+ 0,
+ 500);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg_w err %d", ret);
+ return ret;
+}
+
+/* -- get a bulk value (4 bytes) -- */
+static int rcv_val(struct gspca_dev *gspca_dev,
+ int ads)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int alen, ret;
+
+ reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff);
+ reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff);
+ reg_w(gspca_dev, 0x636, ads & 0xff);
+ reg_w(gspca_dev, 0x637, 0);
+ reg_w(gspca_dev, 0x638, 4); /* len & 0xff */
+ reg_w(gspca_dev, 0x639, 0); /* len >> 8 */
+ reg_w(gspca_dev, 0x63a, 0);
+ reg_w(gspca_dev, 0x63b, 0);
+ reg_w(gspca_dev, 0x630, 5);
+ ret = usb_bulk_msg(dev,
+ usb_rcvbulkpipe(dev, 5),
+ gspca_dev->usb_buf,
+ 4, /* length */
+ &alen,
+ 500); /* timeout in milliseconds */
+ return ret;
+}
+
+/* -- send a bulk value -- */
+static int snd_val(struct gspca_dev *gspca_dev,
+ int ads,
+ unsigned int val)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int alen, ret;
+ __u8 seq = 0;
+
+ if (ads == 0x003f08) {
+ ret = reg_r(gspca_dev, 0x0704);
+ if (ret < 0)
+ goto ko;
+ ret = reg_r(gspca_dev, 0x0705);
+ if (ret < 0)
+ goto ko;
+ seq = ret; /* keep the sequence number */
+ ret = reg_r(gspca_dev, 0x0650);
+ if (ret < 0)
+ goto ko;
+ reg_w(gspca_dev, 0x654, seq);
+ } else {
+ reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff);
+ }
+ reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff);
+ reg_w(gspca_dev, 0x656, ads & 0xff);
+ reg_w(gspca_dev, 0x657, 0);
+ reg_w(gspca_dev, 0x658, 0x04); /* size */
+ reg_w(gspca_dev, 0x659, 0);
+ reg_w(gspca_dev, 0x65a, 0);
+ reg_w(gspca_dev, 0x65b, 0);
+ reg_w(gspca_dev, 0x650, 5);
+ gspca_dev->usb_buf[0] = val >> 24;
+ gspca_dev->usb_buf[1] = val >> 16;
+ gspca_dev->usb_buf[2] = val >> 8;
+ gspca_dev->usb_buf[3] = val;
+ ret = usb_bulk_msg(dev,
+ usb_sndbulkpipe(dev, 6),
+ gspca_dev->usb_buf,
+ 4,
+ &alen,
+ 500); /* timeout in milliseconds */
+ if (ret < 0)
+ goto ko;
+ if (ads == 0x003f08) {
+ seq += 4;
+ seq &= 0x3f;
+ reg_w(gspca_dev, 0x705, seq);
+ }
+ return ret;
+ko:
+ PDEBUG(D_ERR, "snd_val err %d", ret);
+ return ret;
+}
+
+/* set a camera parameter */
+static int set_par(struct gspca_dev *gspca_dev,
+ int parval)
+{
+ return snd_val(gspca_dev, 0x003f08, parval);
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int parval;
+
+ parval = 0x06000000 /* whiteness */
+ + (sd->brightness << 16);
+ set_par(gspca_dev, parval);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int parval;
+
+ parval = 0x07000000 /* contrast */
+ + (sd->contrast << 16);
+ set_par(gspca_dev, parval);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int parval;
+
+ parval = 0x08000000 /* saturation */
+ + (sd->colors << 16);
+ set_par(gspca_dev, parval);
+}
+
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ set_par(gspca_dev, sd->lightfreq == 1
+ ? 0x33640000 /* 50 Hz */
+ : 0x33780000); /* 60 Hz */
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam = &gspca_dev->cam;
+
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x02;
+ gspca_dev->cam.cam_mode = vga_mode;
+ gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLOR_DEF;
+ sd->lightfreq = FREQ_DEF;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ /* check if the device responds */
+ usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
+ ret = reg_r(gspca_dev, 0x0740);
+ if (ret < 0)
+ return ret;
+ if (ret != 0xff) {
+ PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret);
+ return -1;
+ }
+ return 0;
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ int ret, value;
+
+ /* work on alternate 1 */
+ usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
+
+ set_par(gspca_dev, 0x10000000);
+ set_par(gspca_dev, 0x00000000);
+ set_par(gspca_dev, 0x8002e001);
+ set_par(gspca_dev, 0x14000000);
+ if (gspca_dev->width > 320)
+ value = 0x8002e001; /* 640x480 */
+ else
+ value = 0x4001f000; /* 320x240 */
+ set_par(gspca_dev, value);
+ ret = usb_set_interface(gspca_dev->dev,
+ gspca_dev->iface,
+ gspca_dev->alt);
+ if (ret < 0) {
+ PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed",
+ gspca_dev->iface, gspca_dev->alt);
+ goto out;
+ }
+ ret = reg_r(gspca_dev, 0x0630);
+ if (ret < 0)
+ goto out;
+ rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
+ ret = reg_r(gspca_dev, 0x0650);
+ if (ret < 0)
+ goto out;
+ snd_val(gspca_dev, 0x000020, 0xffffffff);
+ reg_w(gspca_dev, 0x0620, 0);
+ reg_w(gspca_dev, 0x0630, 0);
+ reg_w(gspca_dev, 0x0640, 0);
+ reg_w(gspca_dev, 0x0650, 0);
+ reg_w(gspca_dev, 0x0660, 0);
+ setbrightness(gspca_dev); /* whiteness */
+ setcontrast(gspca_dev); /* contrast */
+ setcolors(gspca_dev); /* saturation */
+ set_par(gspca_dev, 0x09800000); /* Red ? */
+ set_par(gspca_dev, 0x0a800000); /* Green ? */
+ set_par(gspca_dev, 0x0b800000); /* Blue ? */
+ set_par(gspca_dev, 0x0d030000); /* Gamma ? */
+ setfreq(gspca_dev); /* light frequency */
+
+ /* start the video flow */
+ set_par(gspca_dev, 0x01000000);
+ set_par(gspca_dev, 0x01000000);
+ PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
+ return;
+out:
+ PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ set_par(gspca_dev, 0x02000000);
+ set_par(gspca_dev, 0x02000000);
+ usb_set_interface(dev, gspca_dev->iface, 1);
+ reg_r(gspca_dev, 0x0630);
+ rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */
+ reg_r(gspca_dev, 0x0650);
+ snd_val(gspca_dev, 0x000020, 0xffffffff);
+ reg_w(gspca_dev, 0x0620, 0);
+ reg_w(gspca_dev, 0x0630, 0);
+ reg_w(gspca_dev, 0x0640, 0);
+ reg_w(gspca_dev, 0x0650, 0);
+ reg_w(gspca_dev, 0x0660, 0);
+ PDEBUG(D_STREAM, "camera stopped");
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ static unsigned char ffd9[] = {0xff, 0xd9};
+
+ /* a frame starts with:
+ * - 0xff 0xfe
+ * - 0x08 0x00 - length (little endian ?!)
+ * - 4 bytes = size of whole frame (BE - including header)
+ * - 0x00 0x0c
+ * - 0xff 0xd8
+ * - .. JPEG image with escape sequences (ff 00)
+ * (without ending - ff d9)
+ */
+ if (data[0] == 0xff && data[1] == 0xfe) {
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ ffd9, 2);
+
+ /* put the JPEG 411 header */
+ jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+
+ /* beginning of the frame */
+#define STKHDRSZ 12
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data + STKHDRSZ, len - STKHDRSZ);
+#undef STKHDRSZ
+ return;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->lightfreq = val;
+ if (gspca_dev->streaming)
+ setfreq(gspca_dev);
+ return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->lightfreq;
+ return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu)
+{
+ switch (menu->id) {
+ case V4L2_CID_POWER_LINE_FREQUENCY:
+ switch (menu->index) {
+ case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+ strcpy((char *) menu->name, "50 Hz");
+ return 0;
+ case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ strcpy((char *) menu->name, "60 Hz");
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+ .querymenu = sd_querymenu,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ info("v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ info("deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
+
+module_param_named(quant, sd_quant, int, 0644);
+MODULE_PARM_DESC(quant, "Quantization index (0..8)");
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
new file mode 100644
index 00000000000..abd7bef9b3d
--- /dev/null
+++ b/drivers/media/video/gspca/sunplus.c
@@ -0,0 +1,1677 @@
+/*
+ * Sunplus spca504(abc) spca533 spca536 library
+ * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "sunplus"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8)
+static const char version[] = "2.1.8";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ __u8 packet[ISO_MAX_SIZE + 128];
+ /* !! no more than 128 ff in an ISO packet */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char autogain;
+
+ char qindex;
+ char bridge;
+#define BRIDGE_SPCA504 0
+#define BRIDGE_SPCA504B 1
+#define BRIDGE_SPCA504C 2
+#define BRIDGE_SPCA533 3
+#define BRIDGE_SPCA536 4
+ char subtype;
+#define AiptekMiniPenCam13 1
+#define LogitechClickSmart420 2
+#define LogitechClickSmart820 3
+#define MegapixV4 4
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x20,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_COLOR 2
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 0xff,
+ .step = 1,
+ .default_value = 0x1a,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+#define SD_AUTOGAIN 3
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+};
+
+static struct v4l2_pix_format custom_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 464,
+ .sizeimage = 464 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+};
+
+static struct v4l2_pix_format vga_mode2[] = {
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 4},
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+ {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+};
+
+#define SPCA50X_OFFSET_DATA 10
+#define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3
+#define SPCA504_PCCAM600_OFFSET_COMPRESS 4
+#define SPCA504_PCCAM600_OFFSET_MODE 5
+#define SPCA504_PCCAM600_OFFSET_DATA 14
+ /* Frame packet header offsets for the spca533 */
+#define SPCA533_OFFSET_DATA 16
+#define SPCA533_OFFSET_FRAMSEQ 15
+/* Frame packet header offsets for the spca536 */
+#define SPCA536_OFFSET_DATA 4
+#define SPCA536_OFFSET_FRAMSEQ 1
+
+/* Initialisation data for the Creative PC-CAM 600 */
+static const __u16 spca504_pccam600_init_data[][3] = {
+/* {0xa0, 0x0000, 0x0503}, * capture mode */
+ {0x00, 0x0000, 0x2000},
+ {0x00, 0x0013, 0x2301},
+ {0x00, 0x0003, 0x2000},
+ {0x00, 0x0001, 0x21ac},
+ {0x00, 0x0001, 0x21a6},
+ {0x00, 0x0000, 0x21a7}, /* brightness */
+ {0x00, 0x0020, 0x21a8}, /* contrast */
+ {0x00, 0x0001, 0x21ac}, /* sat/hue */
+ {0x00, 0x0000, 0x21ad}, /* hue */
+ {0x00, 0x001a, 0x21ae}, /* saturation */
+ {0x00, 0x0002, 0x21a3}, /* gamma */
+ {0x30, 0x0154, 0x0008},
+ {0x30, 0x0004, 0x0006},
+ {0x30, 0x0258, 0x0009},
+ {0x30, 0x0004, 0x0000},
+ {0x30, 0x0093, 0x0004},
+ {0x30, 0x0066, 0x0005},
+ {0x00, 0x0000, 0x2000},
+ {0x00, 0x0013, 0x2301},
+ {0x00, 0x0003, 0x2000},
+ {0x00, 0x0013, 0x2301},
+ {0x00, 0x0003, 0x2000},
+ {}
+};
+
+/* Creative PC-CAM 600 specific open data, sent before using the
+ * generic initialisation data from spca504_open_data.
+ */
+static const __u16 spca504_pccam600_open_data[][3] = {
+ {0x00, 0x0001, 0x2501},
+ {0x20, 0x0500, 0x0001}, /* snapshot mode */
+ {0x00, 0x0003, 0x2880},
+ {0x00, 0x0001, 0x2881},
+ {}
+};
+
+/* Initialisation data for the logitech clicksmart 420 */
+static const __u16 spca504A_clicksmart420_init_data[][3] = {
+/* {0xa0, 0x0000, 0x0503}, * capture mode */
+ {0x00, 0x0000, 0x2000},
+ {0x00, 0x0013, 0x2301},
+ {0x00, 0x0003, 0x2000},
+ {0x00, 0x0001, 0x21ac},
+ {0x00, 0x0001, 0x21a6},
+ {0x00, 0x0000, 0x21a7}, /* brightness */
+ {0x00, 0x0020, 0x21a8}, /* contrast */
+ {0x00, 0x0001, 0x21ac}, /* sat/hue */
+ {0x00, 0x0000, 0x21ad}, /* hue */
+ {0x00, 0x001a, 0x21ae}, /* saturation */
+ {0x00, 0x0002, 0x21a3}, /* gamma */
+ {0x30, 0x0004, 0x000a},
+ {0xb0, 0x0001, 0x0000},
+
+
+ {0x0a1, 0x0080, 0x0001},
+ {0x30, 0x0049, 0x0000},
+ {0x30, 0x0060, 0x0005},
+ {0x0c, 0x0004, 0x0000},
+ {0x00, 0x0000, 0x0000},
+ {0x00, 0x0000, 0x2000},
+ {0x00, 0x0013, 0x2301},
+ {0x00, 0x0003, 0x2000},
+ {0x00, 0x0000, 0x2000},
+
+ {}
+};
+
+/* clicksmart 420 open data ? */
+static const __u16 spca504A_clicksmart420_open_data[][3] = {
+ {0x00, 0x0001, 0x2501},
+ {0x20, 0x0502, 0x0000},
+ {0x06, 0x0000, 0x0000},
+ {0x00, 0x0004, 0x2880},
+ {0x00, 0x0001, 0x2881},
+/* look like setting a qTable */
+ {0x00, 0x0006, 0x2800},
+ {0x00, 0x0004, 0x2801},
+ {0x00, 0x0004, 0x2802},
+ {0x00, 0x0006, 0x2803},
+ {0x00, 0x000a, 0x2804},
+ {0x00, 0x0010, 0x2805},
+ {0x00, 0x0014, 0x2806},
+ {0x00, 0x0018, 0x2807},
+ {0x00, 0x0005, 0x2808},
+ {0x00, 0x0005, 0x2809},
+ {0x00, 0x0006, 0x280a},
+ {0x00, 0x0008, 0x280b},
+ {0x00, 0x000a, 0x280c},
+ {0x00, 0x0017, 0x280d},
+ {0x00, 0x0018, 0x280e},
+ {0x00, 0x0016, 0x280f},
+
+ {0x00, 0x0006, 0x2810},
+ {0x00, 0x0005, 0x2811},
+ {0x00, 0x0006, 0x2812},
+ {0x00, 0x000a, 0x2813},
+ {0x00, 0x0010, 0x2814},
+ {0x00, 0x0017, 0x2815},
+ {0x00, 0x001c, 0x2816},
+ {0x00, 0x0016, 0x2817},
+ {0x00, 0x0006, 0x2818},
+ {0x00, 0x0007, 0x2819},
+ {0x00, 0x0009, 0x281a},
+ {0x00, 0x000c, 0x281b},
+ {0x00, 0x0014, 0x281c},
+ {0x00, 0x0023, 0x281d},
+ {0x00, 0x0020, 0x281e},
+ {0x00, 0x0019, 0x281f},
+
+ {0x00, 0x0007, 0x2820},
+ {0x00, 0x0009, 0x2821},
+ {0x00, 0x000f, 0x2822},
+ {0x00, 0x0016, 0x2823},
+ {0x00, 0x001b, 0x2824},
+ {0x00, 0x002c, 0x2825},
+ {0x00, 0x0029, 0x2826},
+ {0x00, 0x001f, 0x2827},
+ {0x00, 0x000a, 0x2828},
+ {0x00, 0x000e, 0x2829},
+ {0x00, 0x0016, 0x282a},
+ {0x00, 0x001a, 0x282b},
+ {0x00, 0x0020, 0x282c},
+ {0x00, 0x002a, 0x282d},
+ {0x00, 0x002d, 0x282e},
+ {0x00, 0x0025, 0x282f},
+
+ {0x00, 0x0014, 0x2830},
+ {0x00, 0x001a, 0x2831},
+ {0x00, 0x001f, 0x2832},
+ {0x00, 0x0023, 0x2833},
+ {0x00, 0x0029, 0x2834},
+ {0x00, 0x0030, 0x2835},
+ {0x00, 0x0030, 0x2836},
+ {0x00, 0x0028, 0x2837},
+ {0x00, 0x001d, 0x2838},
+ {0x00, 0x0025, 0x2839},
+ {0x00, 0x0026, 0x283a},
+ {0x00, 0x0027, 0x283b},
+ {0x00, 0x002d, 0x283c},
+ {0x00, 0x0028, 0x283d},
+ {0x00, 0x0029, 0x283e},
+ {0x00, 0x0028, 0x283f},
+
+ {0x00, 0x0007, 0x2840},
+ {0x00, 0x0007, 0x2841},
+ {0x00, 0x000a, 0x2842},
+ {0x00, 0x0013, 0x2843},
+ {0x00, 0x0028, 0x2844},
+ {0x00, 0x0028, 0x2845},
+ {0x00, 0x0028, 0x2846},
+ {0x00, 0x0028, 0x2847},
+ {0x00, 0x0007, 0x2848},
+ {0x00, 0x0008, 0x2849},
+ {0x00, 0x000a, 0x284a},
+ {0x00, 0x001a, 0x284b},
+ {0x00, 0x0028, 0x284c},
+ {0x00, 0x0028, 0x284d},
+ {0x00, 0x0028, 0x284e},
+ {0x00, 0x0028, 0x284f},
+
+ {0x00, 0x000a, 0x2850},
+ {0x00, 0x000a, 0x2851},
+ {0x00, 0x0016, 0x2852},
+ {0x00, 0x0028, 0x2853},
+ {0x00, 0x0028, 0x2854},
+ {0x00, 0x0028, 0x2855},
+ {0x00, 0x0028, 0x2856},
+ {0x00, 0x0028, 0x2857},
+ {0x00, 0x0013, 0x2858},
+ {0x00, 0x001a, 0x2859},
+ {0x00, 0x0028, 0x285a},
+ {0x00, 0x0028, 0x285b},
+ {0x00, 0x0028, 0x285c},
+ {0x00, 0x0028, 0x285d},
+ {0x00, 0x0028, 0x285e},
+ {0x00, 0x0028, 0x285f},
+
+ {0x00, 0x0028, 0x2860},
+ {0x00, 0x0028, 0x2861},
+ {0x00, 0x0028, 0x2862},
+ {0x00, 0x0028, 0x2863},
+ {0x00, 0x0028, 0x2864},
+ {0x00, 0x0028, 0x2865},
+ {0x00, 0x0028, 0x2866},
+ {0x00, 0x0028, 0x2867},
+ {0x00, 0x0028, 0x2868},
+ {0x00, 0x0028, 0x2869},
+ {0x00, 0x0028, 0x286a},
+ {0x00, 0x0028, 0x286b},
+ {0x00, 0x0028, 0x286c},
+ {0x00, 0x0028, 0x286d},
+ {0x00, 0x0028, 0x286e},
+ {0x00, 0x0028, 0x286f},
+
+ {0x00, 0x0028, 0x2870},
+ {0x00, 0x0028, 0x2871},
+ {0x00, 0x0028, 0x2872},
+ {0x00, 0x0028, 0x2873},
+ {0x00, 0x0028, 0x2874},
+ {0x00, 0x0028, 0x2875},
+ {0x00, 0x0028, 0x2876},
+ {0x00, 0x0028, 0x2877},
+ {0x00, 0x0028, 0x2878},
+ {0x00, 0x0028, 0x2879},
+ {0x00, 0x0028, 0x287a},
+ {0x00, 0x0028, 0x287b},
+ {0x00, 0x0028, 0x287c},
+ {0x00, 0x0028, 0x287d},
+ {0x00, 0x0028, 0x287e},
+ {0x00, 0x0028, 0x287f},
+
+ {0xa0, 0x0000, 0x0503},
+ {}
+};
+
+static const __u8 qtable_creative_pccam[2][64] = {
+ { /* Q-table Y-components */
+ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
+ 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
+ 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
+ 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
+ 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
+ 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
+ 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
+ 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
+ { /* Q-table C-components */
+ 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
+};
+
+/* FIXME: This Q-table is identical to the Creative PC-CAM one,
+ * except for one byte. Possibly a typo?
+ * NWG: 18/05/2003.
+ */
+static const __u8 qtable_spca504_default[2][64] = {
+ { /* Q-table Y-components */
+ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
+ 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
+ 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
+ 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
+ 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
+ 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
+ 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
+ 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e,
+ },
+ { /* Q-table C-components */
+ 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
+};
+
+static void reg_r(struct usb_device *dev,
+ __u16 req,
+ __u16 index,
+ __u8 *buffer, __u16 length)
+{
+ usb_control_msg(dev,
+ usb_rcvctrlpipe(dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, buffer, length,
+ 500);
+}
+
+static void reg_w(struct usb_device *dev,
+ __u16 req,
+ __u16 value,
+ __u16 index,
+ __u8 *buffer, __u16 length)
+{
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, buffer, length,
+ 500);
+}
+
+/* write req / index / value */
+static int reg_w_riv(struct usb_device *dev,
+ __u16 req, __u16 index, __u16 value)
+{
+ int ret;
+
+ ret = usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0, 500);
+ PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
+ req, index, value, ret);
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write: error %d", ret);
+ return ret;
+}
+
+/* read 1 byte */
+static int reg_r_1(struct gspca_dev *gspca_dev,
+ __u16 value) /* wValue */
+{
+ int ret;
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0x20, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value,
+ 0, /* index */
+ gspca_dev->usb_buf, 1,
+ 500); /* timeout */
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_r_1 err %d", ret);
+ return 0;
+ }
+ return gspca_dev->usb_buf[0];
+}
+
+/* read 1 or 2 bytes - returns < 0 if error */
+static int reg_r_12(struct gspca_dev *gspca_dev,
+ __u16 req, /* bRequest */
+ __u16 index, /* wIndex */
+ __u16 length) /* wLength (1 or 2 only) */
+{
+ int ret;
+
+ gspca_dev->usb_buf[1] = 0;
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, length,
+ 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_read err %d", ret);
+ return -1;
+ }
+ return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
+}
+
+static int write_vector(struct gspca_dev *gspca_dev,
+ const __u16 data[][3])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, i = 0;
+
+ while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
+ if (ret < 0) {
+ PDEBUG(D_ERR,
+ "Register write failed for 0x%x,0x%x,0x%x",
+ data[i][0], data[i][1], data[i][2]);
+ return ret;
+ }
+ i++;
+ }
+ return 0;
+}
+
+static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
+ unsigned int request,
+ unsigned int ybase,
+ unsigned int cbase,
+ const __u8 qtable[2][64])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int i, err;
+
+ /* loop over y components */
+ for (i = 0; i < 64; i++) {
+ err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
+ if (err < 0)
+ return err;
+ }
+
+ /* loop over c components */
+ for (i = 0; i < 64; i++) {
+ err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
+
+static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
+ __u16 req, __u16 idx, __u16 val)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 notdone;
+
+ reg_w_riv(dev, req, idx, val);
+ notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+ reg_w_riv(dev, req, idx, val);
+
+ PDEBUG(D_FRAM, "before wait 0x%x", notdone);
+
+ msleep(200);
+ notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+ PDEBUG(D_FRAM, "after wait 0x%x", notdone);
+}
+
+static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
+ __u16 req,
+ __u16 idx, __u16 val, __u8 stat, __u8 count)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 status;
+ __u8 endcode;
+
+ reg_w_riv(dev, req, idx, val);
+ status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+ endcode = stat;
+ PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
+ if (!count)
+ return;
+ count = 200;
+ while (--count > 0) {
+ msleep(10);
+ /* gsmart mini2 write a each wait setting 1 ms is enought */
+/* reg_w_riv(dev, req, idx, val); */
+ status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+ if (status == endcode) {
+ PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
+ status, 200 - count);
+ break;
+ }
+ }
+}
+
+static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
+{
+ int count = 10;
+
+ while (--count > 0) {
+ reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1);
+ if ((gspca_dev->usb_buf[0] & 0x01) == 0)
+ break;
+ msleep(10);
+ }
+ return gspca_dev->usb_buf[0];
+}
+
+static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int count = 50;
+
+ while (--count > 0) {
+ reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
+ if (gspca_dev->usb_buf[0] != 0) {
+ gspca_dev->usb_buf[0] = 0;
+ reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
+ spca504B_PollingDataReady(gspca_dev);
+ break;
+ }
+ msleep(10);
+ }
+}
+
+static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 *data;
+
+ data = kmalloc(64, GFP_KERNEL);
+ reg_r(dev, 0x20, 0, data, 5);
+ PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
+ data[0], data[1], data[2], data[3], data[4]);
+ reg_r(dev, 0x23, 0, data, 64);
+ reg_r(dev, 0x23, 1, data, 64);
+ kfree(data);
+}
+
+static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 Size;
+ __u8 Type;
+ int rc;
+
+ Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ Type = 0;
+ switch (sd->bridge) {
+ case BRIDGE_SPCA533:
+ reg_w(dev, 0x31, 0, 0, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
+ spca50x_GetFirmware(gspca_dev);
+ gspca_dev->usb_buf[0] = 2; /* type */
+ reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1);
+
+ gspca_dev->usb_buf[0] = Size;
+ reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */
+ rc = spca504B_PollingDataReady(gspca_dev);
+
+ /* Init the cam width height with some values get on init ? */
+ reg_w(dev, 0x31, 0, 4, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
+ break;
+ default:
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA536: */
+ gspca_dev->usb_buf[0] = Size;
+ reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */
+ Type = 6;
+ gspca_dev->usb_buf[0] = Type;
+ reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */
+ rc = spca504B_PollingDataReady(gspca_dev);
+ break;
+ case BRIDGE_SPCA504:
+ Size += 3;
+ if (sd->subtype == AiptekMiniPenCam13) {
+ /* spca504a aiptek */
+ spca504A_acknowledged_command(gspca_dev,
+ 0x08, Size, 0,
+ 0x80 | (Size & 0x0f), 1);
+ spca504A_acknowledged_command(gspca_dev,
+ 1, 3, 0, 0x9f, 0);
+ } else {
+ spca504_acknowledged_command(gspca_dev, 0x08, Size, 0);
+ }
+ break;
+ case BRIDGE_SPCA504C:
+ /* capture mode */
+ reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00);
+ reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f));
+ break;
+ }
+}
+
+static void spca504_wait_status(struct gspca_dev *gspca_dev)
+{
+ int cnt;
+
+ cnt = 256;
+ while (--cnt > 0) {
+ /* With this we get the status, when return 0 it's all ok */
+ if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
+ return;
+ msleep(10);
+ }
+}
+
+static void spca504B_setQtable(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ gspca_dev->usb_buf[0] = 3;
+ reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1);
+ spca504B_PollingDataReady(gspca_dev);
+}
+
+static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int pollreg = 1;
+
+ switch (sd->bridge) {
+ case BRIDGE_SPCA504:
+ case BRIDGE_SPCA504C:
+ pollreg = 0;
+ /* fall thru */
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+ reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */
+ reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */
+ reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */
+ reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */
+ reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */
+ reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */
+ break;
+ case BRIDGE_SPCA536:
+ reg_w(dev, 0, 0, 0x20f0, NULL, 0);
+ reg_w(dev, 0, 0x21, 0x20f1, NULL, 0);
+ reg_w(dev, 0, 0x40, 0x20f5, NULL, 0);
+ reg_w(dev, 0, 1, 0x20f4, NULL, 0);
+ reg_w(dev, 0, 0x40, 0x20f6, NULL, 0);
+ reg_w(dev, 0, 0, 0x2089, NULL, 0);
+ break;
+ }
+ if (pollreg)
+ spca504B_PollingDataReady(gspca_dev);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ struct cam *cam;
+ __u16 vendor;
+ __u16 product;
+ __u8 fw;
+
+ vendor = id->idVendor;
+ product = id->idProduct;
+ switch (vendor) {
+ case 0x041e: /* Creative cameras */
+/* switch (product) { */
+/* case 0x400b: */
+/* case 0x4012: */
+/* case 0x4013: */
+/* sd->bridge = BRIDGE_SPCA504C; */
+/* break; */
+/* } */
+ break;
+ case 0x0458: /* Genius KYE cameras */
+/* switch (product) { */
+/* case 0x7006: */
+ sd->bridge = BRIDGE_SPCA504B;
+/* break; */
+/* } */
+ break;
+ case 0x0461: /* MicroInnovation */
+/* switch (product) { */
+/* case 0x0821: */
+ sd->bridge = BRIDGE_SPCA533;
+/* break; */
+/* } */
+ break;
+ case 0x046d: /* Logitech Labtec */
+ switch (product) {
+ case 0x0905:
+ sd->subtype = LogitechClickSmart820;
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x0960:
+ sd->subtype = LogitechClickSmart420;
+ sd->bridge = BRIDGE_SPCA504C;
+ break;
+ }
+ break;
+ case 0x0471: /* Philips */
+/* switch (product) { */
+/* case 0x0322: */
+ sd->bridge = BRIDGE_SPCA504B;
+/* break; */
+/* } */
+ break;
+ case 0x04a5: /* Benq */
+ switch (product) {
+ case 0x3003:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ case 0x3008:
+ case 0x300a:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ }
+ break;
+ case 0x04f1: /* JVC */
+/* switch (product) { */
+/* case 0x1001: */
+ sd->bridge = BRIDGE_SPCA504B;
+/* break; */
+/* } */
+ break;
+ case 0x04fc: /* SunPlus */
+ switch (product) {
+ case 0x500c:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ case 0x504a:
+/* try to get the firmware as some cam answer 2.0.1.2.2
+ * and should be a spca504b then overwrite that setting */
+ reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
+ fw = gspca_dev->usb_buf[0];
+ if (fw == 1) {
+ sd->subtype = AiptekMiniPenCam13;
+ sd->bridge = BRIDGE_SPCA504;
+ } else if (fw == 2) {
+ sd->bridge = BRIDGE_SPCA504B;
+ } else
+ return -ENODEV;
+ break;
+ case 0x504b:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ case 0x5330:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x5360:
+ sd->bridge = BRIDGE_SPCA536;
+ break;
+ case 0xffff:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ }
+ break;
+ case 0x052b: /* ?? Megapix */
+/* switch (product) { */
+/* case 0x1513: */
+ sd->subtype = MegapixV4;
+ sd->bridge = BRIDGE_SPCA533;
+/* break; */
+/* } */
+ break;
+ case 0x0546: /* Polaroid */
+ switch (product) {
+ case 0x3155:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x3191:
+ case 0x3273:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ }
+ break;
+ case 0x055f: /* Mustek cameras */
+ switch (product) {
+ case 0xc211:
+ sd->bridge = BRIDGE_SPCA536;
+ break;
+ case 0xc230:
+ case 0xc232:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0xc360:
+ sd->bridge = BRIDGE_SPCA536;
+ break;
+ case 0xc420:
+ sd->bridge = BRIDGE_SPCA504;
+ break;
+ case 0xc430:
+ case 0xc440:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0xc520:
+ sd->bridge = BRIDGE_SPCA504;
+ break;
+ case 0xc530:
+ case 0xc540:
+ case 0xc630:
+ case 0xc650:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ }
+ break;
+ case 0x05da: /* Digital Dream cameras */
+/* switch (product) { */
+/* case 0x1018: */
+ sd->bridge = BRIDGE_SPCA504B;
+/* break; */
+/* } */
+ break;
+ case 0x06d6: /* Trust */
+/* switch (product) { */
+/* case 0x0031: */
+ sd->bridge = BRIDGE_SPCA533; /* SPCA533A */
+/* break; */
+/* } */
+ break;
+ case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */
+ switch (product) {
+ case 0x1311:
+ case 0x1314:
+ case 0x2211:
+ case 0x2221:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x3261:
+ case 0x3281:
+ sd->bridge = BRIDGE_SPCA536;
+ break;
+ }
+ break;
+ case 0x08ca: /* Aiptek */
+ switch (product) {
+ case 0x0104:
+ case 0x0106:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x2008:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ case 0x2010:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x2016:
+ case 0x2018:
+ sd->bridge = BRIDGE_SPCA504B;
+ break;
+ case 0x2020:
+ case 0x2022:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x2024:
+ sd->bridge = BRIDGE_SPCA536;
+ break;
+ case 0x2028:
+ sd->bridge = BRIDGE_SPCA533;
+ break;
+ case 0x2040:
+ case 0x2042:
+ case 0x2050:
+ case 0x2060:
+ sd->bridge = BRIDGE_SPCA536;
+ break;
+ }
+ break;
+ case 0x0d64: /* SunPlus */
+/* switch (product) { */
+/* case 0x0303: */
+ sd->bridge = BRIDGE_SPCA536;
+/* break; */
+/* } */
+ break;
+ }
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA536: */
+ cam->cam_mode = vga_mode;
+ cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ break;
+ case BRIDGE_SPCA533:
+ cam->cam_mode = custom_mode;
+ cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
+ break;
+ case BRIDGE_SPCA504C:
+ cam->cam_mode = vga_mode2;
+ cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
+ break;
+ }
+ sd->qindex = 5; /* set the quantization table */
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int rc;
+ __u8 i;
+ __u8 info[6];
+ int err_code;
+
+ switch (sd->bridge) {
+ case BRIDGE_SPCA504B:
+ reg_w(dev, 0x1d, 0, 0, NULL, 0);
+ reg_w(dev, 0, 1, 0x2306, NULL, 0);
+ reg_w(dev, 0, 0, 0x0d04, NULL, 0);
+ reg_w(dev, 0, 0, 0x2000, NULL, 0);
+ reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
+ reg_w(dev, 0, 0, 0x2306, NULL, 0);
+ /* fall thru */
+ case BRIDGE_SPCA533:
+ rc = spca504B_PollingDataReady(gspca_dev);
+ spca50x_GetFirmware(gspca_dev);
+ break;
+ case BRIDGE_SPCA536:
+ spca50x_GetFirmware(gspca_dev);
+ reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
+ gspca_dev->usb_buf[0] = 0;
+ reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
+ reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
+ rc = spca504B_PollingDataReady(gspca_dev);
+ reg_w(dev, 0x34, 0, 0, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ break;
+ case BRIDGE_SPCA504C: /* pccam600 */
+ PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
+ reg_w_riv(dev, 0xe0, 0x0000, 0x0000);
+ reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */
+ spca504_wait_status(gspca_dev);
+ if (sd->subtype == LogitechClickSmart420)
+ write_vector(gspca_dev,
+ spca504A_clicksmart420_open_data);
+ else
+ write_vector(gspca_dev, spca504_pccam600_open_data);
+ err_code = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x2800,
+ 0x2840, qtable_creative_pccam);
+ if (err_code < 0) {
+ PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
+ return err_code;
+ }
+ break;
+ default:
+/* case BRIDGE_SPCA504: */
+ PDEBUG(D_STREAM, "Opening SPCA504");
+ if (sd->subtype == AiptekMiniPenCam13) {
+ /*****************************/
+ for (i = 0; i < 6; i++)
+ info[i] = reg_r_1(gspca_dev, i);
+ PDEBUG(D_STREAM,
+ "Read info: %d %d %d %d %d %d."
+ " Should be 1,0,2,2,0,0",
+ info[0], info[1], info[2],
+ info[3], info[4], info[5]);
+ /* spca504a aiptek */
+ /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 8, 3, 0x9e, 1);
+ /* Twice sequencial need status 0xff->0x9e->0x9d */
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 8, 3, 0x9e, 0);
+
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 0, 0, 0x9d, 1);
+ /******************************/
+ /* spca504a aiptek */
+ spca504A_acknowledged_command(gspca_dev, 0x08,
+ 6, 0, 0x86, 1);
+/* reg_write (dev, 0, 0x2000, 0); */
+/* reg_write (dev, 0, 0x2883, 1); */
+/* spca504A_acknowledged_command (gspca_dev, 0x08,
+ 6, 0, 0x86, 1); */
+/* spca504A_acknowledged_command (gspca_dev, 0x24,
+ 0, 0, 0x9D, 1); */
+ reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
+ reg_w_riv(dev, 0x0, 0x2310, 0x05);
+ spca504A_acknowledged_command(gspca_dev, 0x01,
+ 0x0f, 0, 0xff, 0);
+ }
+ /* setup qtable */
+ reg_w_riv(dev, 0, 0x2000, 0);
+ reg_w_riv(dev, 0, 0x2883, 1);
+ err_code = spca50x_setup_qtable(gspca_dev,
+ 0x00, 0x2800,
+ 0x2840,
+ qtable_spca504_default);
+ if (err_code < 0) {
+ PDEBUG(D_ERR, "spca50x_setup_qtable failed");
+ return err_code;
+ }
+ break;
+ }
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int rc;
+ int enable;
+ __u8 i;
+ __u8 info[6];
+
+ if (sd->bridge == BRIDGE_SPCA504B)
+ spca504B_setQtable(gspca_dev);
+ spca504B_SetSizeType(gspca_dev);
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA536: */
+ if (sd->subtype == MegapixV4 ||
+ sd->subtype == LogitechClickSmart820) {
+ reg_w(dev, 0xf0, 0, 0, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ reg_r(dev, 0xf0, 4, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ } else {
+ reg_w(dev, 0x31, 0, 4, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ rc = spca504B_PollingDataReady(gspca_dev);
+ }
+ break;
+ case BRIDGE_SPCA504:
+ if (sd->subtype == AiptekMiniPenCam13) {
+ for (i = 0; i < 6; i++)
+ info[i] = reg_r_1(gspca_dev, i);
+ PDEBUG(D_STREAM,
+ "Read info: %d %d %d %d %d %d."
+ " Should be 1,0,2,2,0,0",
+ info[0], info[1], info[2],
+ info[3], info[4], info[5]);
+ /* spca504a aiptek */
+ /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 8, 3, 0x9e, 1);
+ /* Twice sequencial need status 0xff->0x9e->0x9d */
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 8, 3, 0x9e, 0);
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 0, 0, 0x9d, 1);
+ } else {
+ spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
+ for (i = 0; i < 6; i++)
+ info[i] = reg_r_1(gspca_dev, i);
+ PDEBUG(D_STREAM,
+ "Read info: %d %d %d %d %d %d."
+ " Should be 1,0,2,2,0,0",
+ info[0], info[1], info[2],
+ info[3], info[4], info[5]);
+ spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
+ spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
+ }
+ spca504B_SetSizeType(gspca_dev);
+ reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
+ reg_w_riv(dev, 0x0, 0x2310, 0x05);
+ break;
+ case BRIDGE_SPCA504C:
+ if (sd->subtype == LogitechClickSmart420) {
+ write_vector(gspca_dev,
+ spca504A_clicksmart420_init_data);
+ } else {
+ write_vector(gspca_dev, spca504_pccam600_init_data);
+ }
+ enable = (sd->autogain ? 0x04 : 0x01);
+ reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */
+ reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */
+
+ /* set default exposure compensation and whiteness balance */
+ reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */
+ reg_w_riv(dev, 0x30, 0x0002, 1600);
+ spca504B_SetSizeType(gspca_dev);
+ break;
+ }
+ sp5xx_initContBrigHueRegisters(gspca_dev);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA536: */
+/* case BRIDGE_SPCA504B: */
+ reg_w(dev, 0x31, 0, 0, NULL, 0);
+ spca504B_WaitCmdStatus(gspca_dev);
+ spca504B_PollingDataReady(gspca_dev);
+ break;
+ case BRIDGE_SPCA504:
+ case BRIDGE_SPCA504C:
+ reg_w_riv(dev, 0x00, 0x2000, 0x0000);
+
+ if (sd->subtype == AiptekMiniPenCam13) {
+ /* spca504a aiptek */
+/* spca504A_acknowledged_command(gspca_dev, 0x08,
+ 6, 0, 0x86, 1); */
+ spca504A_acknowledged_command(gspca_dev, 0x24,
+ 0x00, 0x00, 0x9d, 1);
+ spca504A_acknowledged_command(gspca_dev, 0x01,
+ 0x0f, 0x00, 0xff, 1);
+ } else {
+ spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
+ reg_w_riv(dev, 0x01, 0x000f, 0x00);
+ }
+ break;
+ }
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, sof = 0;
+ unsigned char *s, *d;
+ static unsigned char ffd9[] = {0xff, 0xd9};
+
+/* frames are jpeg 4.1.1 without 0xff escape */
+ switch (sd->bridge) {
+ case BRIDGE_SPCA533:
+ if (data[0] == 0xff) {
+ if (data[1] != 0x01) { /* drop packet */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ }
+ sof = 1;
+ data += SPCA533_OFFSET_DATA;
+ len -= SPCA533_OFFSET_DATA;
+ } else {
+ data += 1;
+ len -= 1;
+ }
+ break;
+ case BRIDGE_SPCA536:
+ if (data[0] == 0xff) {
+ sof = 1;
+ data += SPCA536_OFFSET_DATA;
+ len -= SPCA536_OFFSET_DATA;
+ } else {
+ data += 2;
+ len -= 2;
+ }
+ break;
+ default:
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504B: */
+ switch (data[0]) {
+ case 0xfe: /* start of frame */
+ sof = 1;
+ data += SPCA50X_OFFSET_DATA;
+ len -= SPCA50X_OFFSET_DATA;
+ break;
+ case 0xff: /* drop packet */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ default:
+ data += 1;
+ len -= 1;
+ break;
+ }
+ break;
+ case BRIDGE_SPCA504C:
+ switch (data[0]) {
+ case 0xfe: /* start of frame */
+ sof = 1;
+ data += SPCA504_PCCAM600_OFFSET_DATA;
+ len -= SPCA504_PCCAM600_OFFSET_DATA;
+ break;
+ case 0xff: /* drop packet */
+/* gspca_dev->last_packet_type = DISCARD_PACKET; */
+ return;
+ default:
+ data += 1;
+ len -= 1;
+ break;
+ }
+ break;
+ }
+ if (sof) { /* start of frame */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ ffd9, 2);
+
+ /* put the JPEG header in the new frame */
+ jpeg_put_header(gspca_dev, frame,
+ ((struct sd *) gspca_dev)->qindex,
+ 0x22);
+ }
+
+ /* add 0x00 after 0xff */
+ for (i = len; --i >= 0; )
+ if (data[i] == 0xff)
+ break;
+ if (i < 0) { /* no 0xff */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+ return;
+ }
+ s = data;
+ d = sd->packet;
+ for (i = 0; i < len; i++) {
+ *d++ = *s++;
+ if (s[-1] == 0xff)
+ *d++ = 0x00;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ sd->packet, d - sd->packet);
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504C: */
+ reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
+ break;
+ case BRIDGE_SPCA536:
+ reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
+ break;
+ }
+}
+
+static void getbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 brightness = 0;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504C: */
+ brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
+ break;
+ case BRIDGE_SPCA536:
+ brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
+ break;
+ }
+ sd->brightness = ((brightness & 0xff) - 128) % 255;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504C: */
+ reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
+ break;
+ case BRIDGE_SPCA536:
+ reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
+ break;
+ }
+}
+
+static void getcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504C: */
+ sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
+ break;
+ case BRIDGE_SPCA536:
+ sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
+ break;
+ }
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504C: */
+ reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
+ break;
+ case BRIDGE_SPCA536:
+ reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
+ break;
+ }
+}
+
+static void getcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->bridge) {
+ default:
+/* case BRIDGE_SPCA533: */
+/* case BRIDGE_SPCA504B: */
+/* case BRIDGE_SPCA504: */
+/* case BRIDGE_SPCA504C: */
+ sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
+ break;
+ case BRIDGE_SPCA536:
+ sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
+ break;
+ }
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getbrightness(gspca_dev);
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcontrast(gspca_dev);
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ getcolors(gspca_dev);
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")},
+ {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")},
+ {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")},
+ {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")},
+ {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")},
+ {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")},
+ {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")},
+ {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")},
+ {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")},
+ {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")},
+ {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")},
+ {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")},
+ {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")},
+ {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")},
+ {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")},
+ {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")},
+ {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")},
+ {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")},
+ {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")},
+ {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")},
+ {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")},
+ {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")},
+ {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")},
+ {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")},
+ {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")},
+ {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")},
+ {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")},
+ {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")},
+ {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")},
+ {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")},
+ {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")},
+ {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")},
+ {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")},
+ {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")},
+ {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")},
+ {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")},
+ {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")},
+ {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")},
+ {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")},
+ {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")},
+ {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")},
+ {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")},
+ {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")},
+ {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")},
+ {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")},
+ {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")},
+ {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")},
+ {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")},
+ {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")},
+ {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")},
+ {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")},
+ {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")},
+ {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")},
+ {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")},
+ {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")},
+ {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")},
+ {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
new file mode 100644
index 00000000000..00f47e463a0
--- /dev/null
+++ b/drivers/media/video/gspca/t613.c
@@ -0,0 +1,1038 @@
+/*
+ *Notes: * t613 + tas5130A
+ * * Focus to light do not balance well as in win.
+ * Quality in win is not good, but its kinda better.
+ * * Fix some "extraneous bytes", most of apps will show the image anyway
+ * * Gamma table, is there, but its really doing something?
+ * * 7~8 Fps, its ok, max on win its 10.
+ * Costantino Leandro
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "t613"
+#include "gspca.h"
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+#define MAX_GAMMA 0x10 /* 0 to 15 */
+
+/* From LUVCVIEW */
+#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3)
+
+MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
+MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned char brightness;
+ unsigned char contrast;
+ unsigned char colors;
+ unsigned char autogain;
+ unsigned char gamma;
+ unsigned char sharpness;
+ unsigned char freq;
+ unsigned char whitebalance;
+ unsigned char mirror;
+ unsigned char effect;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 0x0f,
+ .step = 1,
+ .default_value = 0x09,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0x0d,
+ .step = 1,
+ .default_value = 0x07,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_COLOR 2
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 0,
+ .maximum = 0x0f,
+ .step = 1,
+ .default_value = 0x05,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+#define SD_GAMMA 3
+ {
+ {
+ .id = V4L2_CID_GAMMA, /* (gamma on win) */
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma (Untested)",
+ .minimum = 0,
+ .maximum = MAX_GAMMA,
+ .step = 1,
+ .default_value = 0x09,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
+#define SD_AUTOGAIN 4
+ {
+ {
+ .id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
+ * some apps dont bring up the
+ * backligth_compensation control) */
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Low Light",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0x01,
+ },
+ .set = sd_setlowlight,
+ .get = sd_getlowlight,
+ },
+#define SD_MIRROR 5
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Mirror Image",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = sd_setflip,
+ .get = sd_getflip
+ },
+#define SD_LIGHTFREQ 6
+ {
+ {
+ .id = V4L2_CID_POWER_LINE_FREQUENCY,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "Light Frequency Filter",
+ .minimum = 1, /* 1 -> 0x50, 2->0x60 */
+ .maximum = 2,
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = sd_setfreq,
+ .get = sd_getfreq},
+
+#define SD_WHITE_BALANCE 7
+ {
+ {
+ .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "White Balance",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = sd_setwhitebalance,
+ .get = sd_getwhitebalance
+ },
+#define SD_SHARPNESS 8 /* (aka definition on win) */
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = MAX_GAMMA, /* 0 to 16 */
+ .step = 1,
+ .default_value = 0x06,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
+#define SD_EFFECTS 9
+ {
+ {
+ .id = V4L2_CID_EFFECTS,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "Webcam Effects",
+ .minimum = 0,
+ .maximum = 4,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = sd_seteffect,
+ .get = sd_geteffect
+ },
+};
+
+static char *effects_control[] = {
+ "Normal",
+ "Emboss", /* disabled */
+ "Monochrome",
+ "Sepia",
+ "Sketch",
+ "Sun Effect", /* disabled */
+ "Negative",
+};
+
+static struct v4l2_pix_format vga_mode_t16[] = {
+ {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 4},
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+#define T16_OFFSET_DATA 631
+#define MAX_EFFECTS 7
+/* easily done by soft, this table could be removed,
+ * i keep it here just in case */
+static const __u8 effects_table[MAX_EFFECTS][6] = {
+ {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
+ {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
+ {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
+ {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */
+ {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */
+ {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */
+ {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
+};
+
+static const __u8 gamma_table[MAX_GAMMA][34] = {
+ {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,
+ 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
+ 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
+ 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75,
+ 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD,
+ 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4,
+ 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B,
+ 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6,
+ 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0,
+ 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,
+ 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E,
+ 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB,
+ 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55,
+ 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
+ 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6,
+ 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48,
+ 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
+ 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE,
+ 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,
+ 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
+ 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
+ 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,
+ 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70,
+ 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0,
+ 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,
+ 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79,
+ 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6,
+ 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,
+ 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
+ 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
+ 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44,
+ 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E,
+ 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4,
+ 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52,
+ 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B,
+ 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB,
+ 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E,
+ 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8,
+ 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3,
+ 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6,
+ 0xA0, 0xFF},
+ {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83,
+ 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7,
+ 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC,
+ 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A,
+ 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6,
+ 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3,
+ 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA,
+ 0xa0, 0xff},
+ {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7,
+ 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8,
+ 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED,
+ 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC,
+ 0xA0, 0xFF}
+};
+
+static const __u8 tas5130a_sensor_init[][8] = {
+ {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
+ {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
+ {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
+ {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
+ {},
+};
+
+/* read 1 byte */
+static int reg_r_1(struct gspca_dev *gspca_dev,
+ __u16 index)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, 1, 500);
+ return gspca_dev->usb_buf[0];
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ __u16 value,
+ __u16 index,
+ const __u8 *buffer, __u16 len)
+{
+ if (buffer == NULL) {
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, index,
+ NULL, 0, 500);
+ return;
+ }
+ if (len <= sizeof gspca_dev->usb_buf) {
+ memcpy(gspca_dev->usb_buf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, index,
+ gspca_dev->usb_buf, len, 500);
+ } else {
+ __u8 *tmpbuf;
+
+ tmpbuf = kmalloc(len, GFP_KERNEL);
+ memcpy(tmpbuf, buffer, len);
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ value, index,
+ tmpbuf, len, 500);
+ kfree(tmpbuf);
+ }
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+
+ cam->cam_mode = vga_mode_t16;
+ cam->nmodes = ARRAY_SIZE(vga_mode_t16);
+
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value;
+ sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
+ sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
+ sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
+ sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
+ sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
+ return 0;
+}
+
+static int init_default_parameters(struct gspca_dev *gspca_dev)
+{
+ /* some of this registers are not really neded, because
+ * they are overriden by setbrigthness, setcontrast, etc,
+ * but wont hurt anyway, and can help someone with similar webcam
+ * to see the initial parameters.*/
+ int i = 0;
+ __u8 test_byte;
+
+ static const __u8 read_indexs[] =
+ { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
+ 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
+ static const __u8 n1[6] =
+ {0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
+ static const __u8 n2[2] =
+ {0x08, 0x00};
+ static const __u8 nset[6] =
+ { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
+ static const __u8 n3[6] =
+ {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
+ static const __u8 n4[0x46] =
+ {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
+ 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
+ 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
+ 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
+ 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
+ 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
+ 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
+ 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
+ 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
+ static const __u8 nset4[18] = {
+ 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
+ 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
+ 0xe8, 0xe0
+ };
+ /* ojo puede ser 0xe6 en vez de 0xe9 */
+ static const __u8 nset2[20] = {
+ 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
+ 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
+ 0xd8, 0xc8, 0xd9, 0xfc
+ };
+ static const __u8 missing[8] =
+ { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
+ static const __u8 nset3[18] = {
+ 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
+ 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
+ 0xcf, 0xe0
+ };
+ static const __u8 nset5[4] =
+ { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
+ static const __u8 nset6[34] = {
+ 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54,
+ 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
+ 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca,
+ 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2,
+ 0xa0, 0xff
+ }; /* Gamma */
+ static const __u8 nset7[4] =
+ { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
+ static const __u8 nset9[4] =
+ { 0x0b, 0x04, 0x0a, 0x78 };
+ static const __u8 nset8[6] =
+ { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
+ static const __u8 nset10[6] =
+ { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
+
+ reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06);
+ reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06);
+ reg_r_1(gspca_dev, 0x0063);
+ reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02);
+
+ while (read_indexs[i] != 0x00) {
+ test_byte = reg_r_1(gspca_dev, read_indexs[i]);
+ PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i],
+ test_byte);
+ i++;
+ }
+
+ reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06);
+ reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46);
+ reg_r_1(gspca_dev, 0x0080);
+ reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0);
+ reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
+ reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
+ reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
+ reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
+ reg_w(gspca_dev, 0x00, 0x3880, NULL, 0);
+ reg_w(gspca_dev, 0x00, 0x338e, NULL, 0);
+ reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04);
+ reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0);
+ reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22);
+ reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0);
+ reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
+
+ reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08);
+
+ reg_w(gspca_dev, 0x00, 0x2087, NULL, 0);
+ reg_w(gspca_dev, 0x00, 0x2088, NULL, 0);
+ reg_w(gspca_dev, 0x00, 0x2089, NULL, 0);
+
+ reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04);
+ reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06);
+ reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06);
+ reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04);
+
+ reg_w(gspca_dev, 0x00, 0x2880, NULL, 0);
+ reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14);
+ reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12);
+ reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12);
+
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned int brightness;
+ __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 };
+ brightness = sd->brightness;
+
+ if (brightness < 7) {
+ set6[3] = 0x70 - (brightness * 0xa);
+ } else {
+ set6[1] = 0x24;
+ set6[3] = 0x00 + ((brightness - 7) * 0xa);
+ }
+
+ reg_w(gspca_dev, 0x01, 0x0000, set6, 4);
+}
+
+static void setflip(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ __u8 flipcmd[8] =
+ { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 };
+
+ if (sd->mirror == 1)
+ flipcmd[3] = 0x01;
+
+ reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8);
+}
+
+static void seteffect(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06);
+ if (sd->effect == 1 || sd->effect == 5) {
+ PDEBUG(D_CONF,
+ "This effect have been disabled for webcam \"safety\"");
+ return;
+ }
+
+ if (sd->effect == 1 || sd->effect == 4)
+ reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0);
+ else
+ reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0);
+}
+
+static void setwhitebalance(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ __u8 white_balance[8] =
+ { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
+
+ if (sd->whitebalance == 1)
+ white_balance[7] = 0x3c;
+
+ reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8);
+}
+
+static void setlightfreq(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
+
+ if (sd->freq == 2) /* 60hz */
+ freq[1] = 0x00;
+
+ reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned int contrast = sd->contrast;
+ __u16 reg_to_write = 0x00;
+
+ if (contrast < 7)
+ reg_to_write = 0x8ea9 - (0x200 * contrast);
+ else
+ reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
+
+ reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 reg_to_write;
+
+ reg_to_write = 0xc0bb + sd->colors * 0x100;
+ reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
+}
+
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 reg_to_write;
+
+ reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
+
+ reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return *val;
+}
+
+static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->whitebalance = val;
+ if (gspca_dev->streaming)
+ setwhitebalance(gspca_dev);
+ return 0;
+}
+
+static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->whitebalance;
+ return *val;
+}
+
+static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->mirror = val;
+ if (gspca_dev->streaming)
+ setflip(gspca_dev);
+ return 0;
+}
+
+static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->mirror;
+ return *val;
+}
+
+static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->effect = val;
+ if (gspca_dev->streaming)
+ seteffect(gspca_dev);
+ return 0;
+}
+
+static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->effect;
+ return *val;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return *val;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming)
+ setcolors(gspca_dev);
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming)
+ setgamma(gspca_dev);
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ *val = sd->gamma;
+ return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->freq = val;
+ if (gspca_dev->streaming)
+ setlightfreq(gspca_dev);
+ return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->freq;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming)
+ setsharpness(gspca_dev);
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
+/* Low Light set here......*/
+static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (val != 0)
+ reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0);
+ else
+ reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0);
+ return 0;
+}
+
+static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ int mode;
+
+ static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
+ __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+ static const __u8 t3[] =
+ { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
+ 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
+ static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
+ switch (mode) {
+ case 1: /* 352x288 */
+ t2[1] = 0x40;
+ break;
+ case 2: /* 320x240 */
+ t2[1] = 0x10;
+ break;
+ case 3: /* 176x144 */
+ t2[1] = 0x50;
+ break;
+ case 4: /* 160x120 */
+ t2[1] = 0x20;
+ break;
+ default: /* 640x480 (0x00) */
+ break;
+ }
+
+ reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8);
+ reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8);
+ reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8);
+ reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
+ reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
+ /* just in case and to keep sync with logs (for mine) */
+ reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8);
+ reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0);
+ /* just in case and to keep sync with logs (for mine) */
+ reg_w(gspca_dev, 0x01, 0x0000, t1, 4);
+ reg_w(gspca_dev, 0x01, 0x0000, t2, 6);
+ reg_r_1(gspca_dev, 0x0012);
+ reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10);
+ reg_w(gspca_dev, 0x00, 0x0013, NULL, 0);
+ reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4);
+ /* restart on each start, just in case, sometimes regs goes wrong
+ * when using controls from app */
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+ setcolors(gspca_dev);
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ int sof = 0;
+ static __u8 ffd9[] = { 0xff, 0xd9 };
+
+ if (data[0] == 0x5a) {
+ /* Control Packet, after this came the header again,
+ * but extra bytes came in the packet before this,
+ * sometimes an EOF arrives, sometimes not... */
+ return;
+ }
+
+ if (data[len - 1] == 0xff && data[len] == 0xd9) {
+ /* Just in case, i have seen packets with the marker,
+ * other's do not include it... */
+ data += 2;
+ len -= 4;
+ } else if (data[2] == 0xff && data[3] == 0xd8) {
+ sof = 1;
+ data += 2;
+ len -= 2;
+ } else {
+ data += 2;
+ len -= 2;
+ }
+
+ if (sof) {
+ /* extra bytes....., could be processed too but would be
+ * a waste of time, right now leave the application and
+ * libjpeg do it for ourserlves.. */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ ffd9, 2);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
+ return;
+ }
+
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu)
+{
+ switch (menu->id) {
+ case V4L2_CID_POWER_LINE_FREQUENCY:
+ switch (menu->index) {
+ case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+ strcpy((char *) menu->name, "50 Hz");
+ return 0;
+ case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ strcpy((char *) menu->name, "60 Hz");
+ return 0;
+ }
+ break;
+ case V4L2_CID_EFFECTS:
+ if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
+ strncpy((char *) menu->name,
+ effects_control[menu->index], 32);
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ init_default_parameters(gspca_dev);
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+ .querymenu = sd_querymenu,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
new file mode 100644
index 00000000000..0b793899095
--- /dev/null
+++ b/drivers/media/video/gspca/tv8532.c
@@ -0,0 +1,670 @@
+/*
+ * Quickcam cameras initialization data
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#define MODULE_NAME "tv8532"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("TV8532 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ int buflen; /* current length of tmpbuf */
+ __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */
+ __u8 tmpbuf2[352 * 288]; /* no protection... */
+
+ unsigned short brightness;
+ unsigned short contrast;
+
+ char packet;
+ char synchro;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 1,
+ .maximum = 0x2ff,
+ .step = 1,
+ .default_value = 0x18f,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 0xffff,
+ .step = 1,
+ .default_value = 0x7fff,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/*
+ * Initialization data: this is the first set-up data written to the
+ * device (before the open data).
+ */
+#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */
+#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */
+#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */
+#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */
+#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */
+#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */
+#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */
+#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */
+#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */
+#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */
+#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */
+#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */
+#define EXPOL 0x8f /* reg 0x1c -> 0x8f */
+#define EXPOH 0x01 /* reg 0x1d -> 0x01 */
+#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */
+#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */
+#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */
+#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */
+#define TV8532_CMD_UPDATE 0x84
+
+#define TV8532_EEprom_Add 0x03
+#define TV8532_EEprom_DataL 0x04
+#define TV8532_EEprom_DataM 0x05
+#define TV8532_EEprom_DataH 0x06
+#define TV8532_EEprom_TableLength 0x07
+#define TV8532_EEprom_Write 0x08
+#define TV8532_PART_CTRL 0x00
+#define TV8532_CTRL 0x01
+#define TV8532_CMD_EEprom_Open 0x30
+#define TV8532_CMD_EEprom_Close 0x29
+#define TV8532_UDP_UPDATE 0x31
+#define TV8532_GPIO 0x39
+#define TV8532_GPIO_OE 0x3B
+#define TV8532_REQ_RegWrite 0x02
+#define TV8532_REQ_RegRead 0x03
+
+#define TV8532_ADWIDTH_L 0x0C
+#define TV8532_ADWIDTH_H 0x0D
+#define TV8532_ADHEIGHT_L 0x0E
+#define TV8532_ADHEIGHT_H 0x0F
+#define TV8532_EXPOSURE 0x1C
+#define TV8532_QUANT_COMP 0x28
+#define TV8532_MODE_PACKET 0x29
+#define TV8532_SETCLK 0x2C
+#define TV8532_POINT_L 0x2D
+#define TV8532_POINT_H 0x2E
+#define TV8532_POINTB_L 0x2F
+#define TV8532_POINTB_H 0x30
+#define TV8532_BUDGET_L 0x2A
+#define TV8532_BUDGET_H 0x2B
+#define TV8532_VID_L 0x34
+#define TV8532_VID_H 0x35
+#define TV8532_PID_L 0x36
+#define TV8532_PID_H 0x37
+#define TV8532_DeviceID 0x83
+#define TV8532_AD_SLOPE 0x91
+#define TV8532_AD_BITCTRL 0x94
+#define TV8532_AD_COLBEGIN_L 0x10
+#define TV8532_AD_COLBEGIN_H 0x11
+#define TV8532_AD_ROWBEGIN_L 0x14
+#define TV8532_AD_ROWBEGIN_H 0x15
+
+static const __u32 tv_8532_eeprom_data[] = {
+/* add dataL dataM dataH */
+ 0x00010001, 0x01018011, 0x02050014, 0x0305001c,
+ 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b,
+ 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9,
+ 0x0c0509f1, 0
+};
+
+static int reg_r(struct gspca_dev *gspca_dev,
+ __u16 index)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ TV8532_REQ_RegRead,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, 1,
+ 500);
+ return gspca_dev->usb_buf[0];
+}
+
+/* write 1 byte */
+static void reg_w_1(struct gspca_dev *gspca_dev,
+ __u16 index, __u8 value)
+{
+ gspca_dev->usb_buf[0] = value;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ TV8532_REQ_RegWrite,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, 1, 500);
+}
+
+/* write 2 bytes */
+static void reg_w_2(struct gspca_dev *gspca_dev,
+ __u16 index, __u8 val1, __u8 val2)
+{
+ gspca_dev->usb_buf[0] = val1;
+ gspca_dev->usb_buf[1] = val2;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ TV8532_REQ_RegWrite,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, /* value */
+ index, gspca_dev->usb_buf, 2, 500);
+}
+
+static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+ __u8 reg, data0, data1, data2;
+
+ reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
+ reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
+/* msleep(1); */
+ while (tv_8532_eeprom_data[i]) {
+ reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
+ reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
+ /* msleep(1); */
+ data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
+ reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
+ /* msleep(1); */
+ data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
+ reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
+ /* msleep(1); */
+ data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
+ reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
+ /* msleep(1); */
+ reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
+ /* msleep(10); */
+ i++;
+ }
+ reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
+/* msleep(1); */
+ reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
+ msleep(10);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+
+ tv_8532WriteEEprom(gspca_dev);
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 1;
+ cam->cam_mode = sif_mode;
+ cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ return 0;
+}
+
+static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
+{
+ __u8 data;
+
+ data = reg_r(gspca_dev, 0x0001);
+ PDEBUG(D_USBI, "register 0x01-> %x", data);
+ data = reg_r(gspca_dev, 0x0002);
+ PDEBUG(D_USBI, "register 0x02-> %x", data);
+ reg_r(gspca_dev, TV8532_ADWIDTH_L);
+ reg_r(gspca_dev, TV8532_ADWIDTH_H);
+ reg_r(gspca_dev, TV8532_QUANT_COMP);
+ reg_r(gspca_dev, TV8532_MODE_PACKET);
+ reg_r(gspca_dev, TV8532_SETCLK);
+ reg_r(gspca_dev, TV8532_POINT_L);
+ reg_r(gspca_dev, TV8532_POINT_H);
+ reg_r(gspca_dev, TV8532_POINTB_L);
+ reg_r(gspca_dev, TV8532_POINTB_H);
+ reg_r(gspca_dev, TV8532_BUDGET_L);
+ reg_r(gspca_dev, TV8532_BUDGET_H);
+ reg_r(gspca_dev, TV8532_VID_L);
+ reg_r(gspca_dev, TV8532_VID_H);
+ reg_r(gspca_dev, TV8532_PID_L);
+ reg_r(gspca_dev, TV8532_PID_H);
+ reg_r(gspca_dev, TV8532_DeviceID);
+ reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
+ reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
+ reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
+ reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
+}
+
+static void tv_8532_setReg(struct gspca_dev *gspca_dev)
+{
+ reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
+ ADCBEGINL); /* 0x10 */
+ reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
+ ADCBEGINH); /* also digital gain */
+ reg_w_1(gspca_dev, TV8532_PART_CTRL,
+ TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+
+ reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
+ /******************************************************/
+ reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
+ reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
+ reg_w_2(gspca_dev, TV8532_EXPOSURE,
+ EXPOL, EXPOH); /* 350d 0x014c; 1c */
+ reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
+ ADCBEGINL); /* 0x10 */
+ reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
+ ADCBEGINH); /* also digital gain */
+ reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
+ ADRBEGINL); /* 0x14 */
+
+ reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
+ reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */
+
+ reg_w_1(gspca_dev, TV8532_CTRL,
+ TV8532_CMD_EEprom_Close); /* 0x01 */
+
+ reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
+ reg_w_1(gspca_dev, TV8532_PART_CTRL,
+ TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+}
+
+static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
+{
+ int i;
+
+ /* strange polling from tgc */
+ for (i = 0; i < 10; i++) {
+ reg_w_1(gspca_dev, TV8532_SETCLK,
+ TESTCLK); /* 0x48; //0x08; 0x2c */
+ reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+ reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ }
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
+ reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ tv_8532ReadRegisters(gspca_dev);
+ reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
+ ADHEIGHH); /* 401d 0x0169; 0e */
+ reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
+ EXPOH); /* 350d 0x014c; 1c */
+ reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
+ reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+
+ /*******************************************************************/
+ reg_w_1(gspca_dev, TV8532_QUANT_COMP,
+ TESTCOMP); /* 0x72 compressed mode 0x28 */
+ reg_w_1(gspca_dev, TV8532_MODE_PACKET,
+ TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+
+ /************************************************/
+ reg_w_1(gspca_dev, TV8532_SETCLK,
+ TESTCLK); /* 0x48; //0x08; 0x2c */
+ reg_w_1(gspca_dev, TV8532_POINT_L,
+ TESTPTL); /* 0x38; 0x2d */
+ reg_w_1(gspca_dev, TV8532_POINT_H,
+ TESTPTH); /* 0x04; 0x2e */
+ reg_w_1(gspca_dev, TV8532_POINTB_L,
+ TESTPTBL); /* 0x04; 0x2f */
+ reg_w_1(gspca_dev, TV8532_POINTB_H,
+ TESTPTBH); /* 0x04; 0x30 */
+ reg_w_1(gspca_dev, TV8532_PART_CTRL,
+ TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ /*************************************************/
+ reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ msleep(200);
+ reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ /*************************************************/
+ tv_8532_setReg(gspca_dev);
+ /*************************************************/
+ reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ /*************************************************/
+ tv_8532_setReg(gspca_dev);
+ /*************************************************/
+ tv_8532_PollReg(gspca_dev);
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int brightness = sd->brightness;
+
+ reg_w_2(gspca_dev, TV8532_EXPOSURE,
+ brightness >> 8, brightness); /* 1c */
+ reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+}
+
+/* -- start the camera -- */
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
+ reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ tv_8532ReadRegisters(gspca_dev);
+ reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
+ ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */
+/* reg_w_2(gspca_dev, TV8532_EXPOSURE,
+ EXPOL, EXPOH); * 350d 0x014c; 1c */
+ setbrightness(gspca_dev);
+
+ reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
+ reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+
+ /************************************************/
+ reg_w_1(gspca_dev, TV8532_QUANT_COMP,
+ TESTCOMP); /* 0x72 compressed mode 0x28 */
+ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
+ /* 176x144 */
+ reg_w_1(gspca_dev, TV8532_MODE_PACKET,
+ QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ } else {
+ /* 352x288 */
+ reg_w_1(gspca_dev, TV8532_MODE_PACKET,
+ TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ }
+ /************************************************/
+ reg_w_1(gspca_dev, TV8532_SETCLK,
+ TESTCLK); /* 0x48; //0x08; 0x2c */
+ reg_w_1(gspca_dev, TV8532_POINT_L,
+ TESTPTL); /* 0x38; 0x2d */
+ reg_w_1(gspca_dev, TV8532_POINT_H,
+ TESTPTH); /* 0x04; 0x2e */
+ reg_w_1(gspca_dev, TV8532_POINTB_L,
+ TESTPTBL); /* 0x04; 0x2f */
+ reg_w_1(gspca_dev, TV8532_POINTB_H,
+ TESTPTBH); /* 0x04; 0x30 */
+ reg_w_1(gspca_dev, TV8532_PART_CTRL,
+ TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ /************************************************/
+ reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ msleep(200);
+ reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ /************************************************/
+ tv_8532_setReg(gspca_dev);
+ /************************************************/
+ reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ /************************************************/
+ tv_8532_setReg(gspca_dev);
+ /************************************************/
+ tv_8532_PollReg(gspca_dev);
+ reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void tv8532_preprocess(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+/* we should received a whole frame with header and EOL marker
+ * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2
+ * sequence 2bytes header the Alternate pixels bayer GB 4 bytes
+ * Alternate pixels bayer RG 4 bytes EOL */
+ int width = gspca_dev->width;
+ int height = gspca_dev->height;
+ unsigned char *dst = sd->tmpbuf2;
+ unsigned char *data = sd->tmpbuf;
+ int i;
+
+ /* precompute where is the good bayer line */
+ if (((data[3] + data[width + 7]) >> 1)
+ + (data[4] >> 2)
+ + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)
+ + (data[3] >> 2)
+ + (data[width + 5] >> 1))
+ data += 3;
+ else
+ data += 2;
+ for (i = 0; i < height / 2; i++) {
+ memcpy(dst, data, width);
+ data += width + 3;
+ dst += width;
+ memcpy(dst, data, width);
+ data += width + 7;
+ dst += width;
+ }
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (data[0] != 0x80) {
+ sd->packet++;
+ if (sd->buflen + len > sizeof sd->tmpbuf) {
+ if (gspca_dev->last_packet_type != DISCARD_PACKET) {
+ PDEBUG(D_PACK, "buffer overflow");
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ }
+ return;
+ }
+ memcpy(&sd->tmpbuf[sd->buflen], data, len);
+ sd->buflen += len;
+ return;
+ }
+
+ /* here we detect 0x80 */
+ /* counter is limited so we need few header for a frame :) */
+
+ /* header 0x80 0x80 0x80 0x80 0x80 */
+ /* packet 00 63 127 145 00 */
+ /* sof 0 1 1 0 0 */
+
+ /* update sequence */
+ if (sd->packet == 63 || sd->packet == 127)
+ sd->synchro = 1;
+
+ /* is there a frame start ? */
+ if (sd->packet >= (gspca_dev->height >> 1) - 1) {
+ PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro,
+ sd->packet);
+ if (!sd->synchro) { /* start of frame */
+ if (gspca_dev->last_packet_type == FIRST_PACKET) {
+ tv8532_preprocess(gspca_dev);
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame, sd->tmpbuf2,
+ gspca_dev->width *
+ gspca_dev->width);
+ }
+ gspca_frame_add(gspca_dev, FIRST_PACKET,
+ frame, data, 0);
+ memcpy(sd->tmpbuf, data, len);
+ sd->buflen = len;
+ sd->packet = 0;
+ return;
+ }
+ if (gspca_dev->last_packet_type != DISCARD_PACKET) {
+ PDEBUG(D_PACK,
+ "Warning wrong TV8532 frame detection %d",
+ sd->packet);
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ }
+ return;
+ }
+
+ if (!sd->synchro) {
+ /* Drop packet frame corrupt */
+ PDEBUG(D_PACK, "DROP SOF %d packet %d",
+ sd->synchro, sd->packet);
+ sd->packet = 0;
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ return;
+ }
+ sd->synchro = 1;
+ sd->packet++;
+ memcpy(&sd->tmpbuf[sd->buflen], data, len);
+ sd->buflen += len;
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")},
+ {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")},
+ {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")},
+ {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")},
+ {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
new file mode 100644
index 00000000000..fcf2c9e3257
--- /dev/null
+++ b/drivers/media/video/gspca/vc032x.c
@@ -0,0 +1,1818 @@
+/*
+ * Z-star vc0321 library
+ * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl
+ * Copyright (C) 2006 Michel Xhaard
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "vc032x"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
+MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ unsigned char autogain;
+ unsigned char lightfreq;
+
+ char qindex;
+ char bridge;
+#define BRIDGE_VC0321 0
+#define BRIDGE_VC0323 1
+ char sensor;
+#define SENSOR_HV7131R 0
+#define SENSOR_MI1320 1
+#define SENSOR_MI1310_SOC 2
+#define SENSOR_OV7660 3
+#define SENSOR_OV7670 4
+#define SENSOR_PO3130NC 5
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+#define AUTOGAIN_DEF 1
+ .default_value = AUTOGAIN_DEF,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+ {
+ {
+ .id = V4L2_CID_POWER_LINE_FREQUENCY,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "Light frequency filter",
+ .minimum = 0,
+ .maximum = 2, /* 0: No, 1: 50Hz, 2:60Hz */
+ .step = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
+ .default_value = 1,
+ },
+ .set = sd_setfreq,
+ .get = sd_getfreq,
+ },
+};
+
+static struct v4l2_pix_format vc0321_mode[] = {
+ {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
+ .bytesperline = 320 * 2,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE,
+ .bytesperline = 640 * 2,
+ .sizeimage = 640 * 480 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+static struct v4l2_pix_format vc0323_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+static const __u8 mi1310_socinitVGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x65, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x03, 0xcc},
+ {0xb3, 0x23, 0xc0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x65, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd0, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x2f, 0xde, 0x20, 0xbb},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x20, 0x03, 0x02, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x05, 0x00, 0x07, 0xbb},
+ {0x34, 0x00, 0x00, 0xbb},
+ {0x35, 0xff, 0x00, 0xbb},
+ {0xdc, 0x07, 0x02, 0xbb},
+ {0xdd, 0x3c, 0x18, 0xbb},
+ {0xde, 0x92, 0x6d, 0xbb},
+ {0xdf, 0xcd, 0xb1, 0xbb},
+ {0xe0, 0xff, 0xe7, 0xbb},
+ {0x06, 0xf0, 0x0d, 0xbb},
+ {0x06, 0x70, 0x0e, 0xbb},
+ {0x4c, 0x00, 0x01, 0xbb},
+ {0x4d, 0x00, 0x01, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x2e, 0x0c, 0x55, 0xbb},
+ {0x21, 0xb6, 0x6e, 0xbb},
+ {0x36, 0x30, 0x10, 0xbb},
+ {0x37, 0x00, 0xc1, 0xbb},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x07, 0x00, 0x84, 0xbb},
+ {0x08, 0x02, 0x4a, 0xbb},
+ {0x05, 0x01, 0x10, 0xbb},
+ {0x06, 0x00, 0x39, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x58, 0x02, 0x67, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x5a, 0x02, 0x67, 0xbb},
+ {0x59, 0x02, 0x00, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x39, 0x06, 0x18, 0xbb},
+ {0x3a, 0x06, 0x18, 0xbb},
+ {0x3b, 0x06, 0x18, 0xbb},
+ {0x3c, 0x06, 0x18, 0xbb},
+ {0x64, 0x7b, 0x5b, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x36, 0x30, 0x10, 0xbb},
+ {0x37, 0x00, 0xc0, 0xbb},
+ {0xbc, 0x0e, 0x00, 0xcc},
+ {0xbc, 0x0f, 0x05, 0xcc},
+ {0xbc, 0x10, 0xc0, 0xcc},
+ {0xbc, 0x11, 0x03, 0xcc},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x02, 0xcc},
+ {0xb6, 0x02, 0x80, 0xcc},
+ {0xb6, 0x05, 0x01, 0xcc},
+ {0xb6, 0x04, 0xe0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x25, 0xcc},
+ {0xb6, 0x18, 0x02, 0xcc},
+ {0xb6, 0x17, 0x58, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x80, 0x00, 0x03, 0xbb},
+ {0x81, 0xc7, 0x14, 0xbb},
+ {0x82, 0xeb, 0xe8, 0xbb},
+ {0x83, 0xfe, 0xf4, 0xbb},
+ {0x84, 0xcd, 0x10, 0xbb},
+ {0x85, 0xf3, 0xee, 0xbb},
+ {0x86, 0xff, 0xf1, 0xbb},
+ {0x87, 0xcd, 0x10, 0xbb},
+ {0x88, 0xf3, 0xee, 0xbb},
+ {0x89, 0x01, 0xf1, 0xbb},
+ {0x8a, 0xe5, 0x17, 0xbb},
+ {0x8b, 0xe8, 0xe2, 0xbb},
+ {0x8c, 0xf7, 0xed, 0xbb},
+ {0x8d, 0x00, 0xff, 0xbb},
+ {0x8e, 0xec, 0x10, 0xbb},
+ {0x8f, 0xf0, 0xed, 0xbb},
+ {0x90, 0xf9, 0xf2, 0xbb},
+ {0x91, 0x00, 0x00, 0xbb},
+ {0x92, 0xe9, 0x0d, 0xbb},
+ {0x93, 0xf4, 0xf2, 0xbb},
+ {0x94, 0xfb, 0xf5, 0xbb},
+ {0x95, 0x00, 0xff, 0xbb},
+ {0xb6, 0x0f, 0x08, 0xbb},
+ {0xb7, 0x3d, 0x16, 0xbb},
+ {0xb8, 0x0c, 0x04, 0xbb},
+ {0xb9, 0x1c, 0x07, 0xbb},
+ {0xba, 0x0a, 0x03, 0xbb},
+ {0xbb, 0x1b, 0x09, 0xbb},
+ {0xbc, 0x17, 0x0d, 0xbb},
+ {0xbd, 0x23, 0x1d, 0xbb},
+ {0xbe, 0x00, 0x28, 0xbb},
+ {0xbf, 0x11, 0x09, 0xbb},
+ {0xc0, 0x16, 0x15, 0xbb},
+ {0xc1, 0x00, 0x1b, 0xbb},
+ {0xc2, 0x0e, 0x07, 0xbb},
+ {0xc3, 0x14, 0x10, 0xbb},
+ {0xc4, 0x00, 0x17, 0xbb},
+ {0x06, 0x74, 0x8e, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xf4, 0x8e, 0xbb},
+ {0x00, 0x00, 0x50, 0xdd},
+ {0x06, 0x74, 0x8e, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x24, 0x50, 0x20, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x34, 0x0c, 0x50, 0xbb},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x03, 0x03, 0xc0, 0xbb},
+ {},
+};
+static const __u8 mi1310_socinitQVGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
+ {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
+ {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
+ {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
+ {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
+ {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
+ {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
+ {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
+ {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
+ {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
+ {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
+ {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
+ {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
+ {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
+ {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
+ {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
+ {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
+ {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
+ {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
+ {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
+ {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
+ {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
+ {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
+ {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
+ {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
+ {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
+ {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
+ {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
+ {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
+ {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
+ {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
+ {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
+ {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
+ {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
+ {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
+ {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
+ {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
+ {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
+ {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
+ {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
+ {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
+ {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
+ {0x03, 0x03, 0xc0, 0xbb},
+ {},
+};
+
+static const __u8 mi1320_gamma[17] = {
+ 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+ 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
+};
+static const __u8 mi1320_matrix[9] = {
+ 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52
+};
+static const __u8 mi1320_initVGA_data[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
+ {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
+ {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
+ {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
+ {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
+ {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
+ {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb},
+ {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
+ {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb},
+ {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb},
+ {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb},
+ {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb},
+ {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb},
+ {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb},
+ {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb},
+ {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb},
+ {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb},
+ {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb},
+ {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb},
+ {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb},
+ {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb},
+ {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb},
+ {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb},
+ {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb},
+ {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb},
+ {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb},
+ {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb},
+ {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb},
+ {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb},
+ {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb},
+ {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd},
+ {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
+ {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
+ {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
+ {}
+};
+static const __u8 mi1320_initQVGA_data[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
+ {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
+ {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
+ {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
+ {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb},
+ {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb},
+ {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb},
+ {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb},
+ {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb},
+ {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb},
+ {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb},
+ {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb},
+ {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb},
+ {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb},
+ {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb},
+ {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb},
+ {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
+ {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb},
+ {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb},
+ {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb},
+ {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb},
+ {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb},
+ {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb},
+ {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb},
+ {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb},
+ {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb},
+ {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb},
+ {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb},
+ {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb},
+ {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
+ {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {}
+};
+
+static const __u8 po3130_gamma[17] = {
+ 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+ 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
+};
+static const __u8 po3130_matrix[9] = {
+ 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
+};
+
+static const __u8 po3130_initVGA_data[][4] = {
+ {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
+ {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
+ {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc},
+ {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc},
+ {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
+ {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
+ {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc},
+ {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
+ {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa},
+ {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa},
+ {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa},
+ {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa},
+ {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa},
+ {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa},
+ {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa},
+ {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa},
+ {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x5a, 0x04, 0xaa},
+ {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa},
+ {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa},
+ {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa},
+ {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa},
+ {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa},
+ {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa},
+ {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa},
+ {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa},
+ {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa},
+ {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa},
+ {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa},
+ {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa},
+ {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa},
+ {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa},
+ {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa},
+ {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa},
+ {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
+ {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
+ {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
+ {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
+ {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
+ {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
+ {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa},
+ {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa},
+ {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa},
+ {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa},
+ {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa},
+ {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa},
+ {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa},
+ {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
+ {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
+ {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
+ {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
+ {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
+ {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
+ {0x00, 0x7e, 0xea, 0xaa},
+ {0x00, 0x4c, 0x07, 0xaa},
+ {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa},
+ {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa},
+/* {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa},
+ {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, */
+ {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0x20, 0xc4, 0xaa},
+ {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc},
+ {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
+ {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
+ {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc},
+ {0xb9, 0x08, 0x3c, 0xcc}, {0x00, 0x05, 0x00, 0xaa},
+ {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
+ {}
+};
+static const __u8 po3130_rundata[][4] = {
+ {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa},
+ {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa},
+ {0x00, 0x44, 0x40, 0xaa},
+/* {0x00, 0xd5, 0x7c, 0xaa}, */
+ {0x00, 0xad, 0x04, 0xaa}, {0x00, 0xae, 0x00, 0xaa},
+ {0x00, 0xb0, 0x78, 0xaa}, {0x00, 0x98, 0x02, 0xaa},
+ {0x00, 0x94, 0x25, 0xaa}, {0x00, 0x95, 0x25, 0xaa},
+ {0x00, 0x59, 0x68, 0xaa}, {0x00, 0x44, 0x20, 0xaa},
+ {0x00, 0x17, 0x50, 0xaa}, {0x00, 0x19, 0x50, 0xaa},
+ {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0xd1, 0x3c, 0xaa},
+ {0x00, 0x1e, 0x06, 0xaa}, {0x00, 0x1e, 0x06, 0xaa},
+ {}
+};
+
+static const __u8 po3130_initQVGA_data[][4] = {
+ {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
+ {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc},
+ {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc},
+ {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc}, {0xb8, 0x08, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc},
+ {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc},
+ {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
+ {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
+ {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc},
+ {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
+ {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa},
+ {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa},
+ {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa},
+ {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa},
+ {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa},
+ {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa},
+ {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa},
+ {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa},
+ {0x00, 0x59, 0x6f, 0xaa}, {0x00, 0x5a, 0x04, 0xaa},
+ {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa},
+ {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa},
+ {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa},
+ {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa},
+ {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa},
+ {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa},
+ {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa},
+ {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa},
+ {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa},
+ {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa},
+ {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa},
+ {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa},
+ {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa},
+ {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa},
+ {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa},
+ {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa},
+ {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
+ {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
+ {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
+ {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
+ {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
+ {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
+ {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa},
+ {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa},
+ {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa},
+ {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa},
+ {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa},
+ {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa},
+ {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa},
+ {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa},
+ {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa},
+ {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa},
+ {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa},
+ {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa},
+ {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa},
+ {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0x4c, 0x07, 0xaa},
+ {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa},
+ {0x00, 0x59, 0x66, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa},
+ {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa},
+ {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc},
+ {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
+ {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
+ {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc},
+ {0xb9, 0x08, 0x3c, 0xcc}, {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc}, {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc}, {0x00, 0x05, 0x00, 0xaa},
+ {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
+ {}
+};
+
+static const __u8 hv7131r_gamma[17] = {
+/* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+ * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */
+ 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1,
+ 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff
+};
+static const __u8 hv7131r_matrix[9] = {
+ 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
+};
+static const __u8 hv7131r_initVGA_data[][4] = {
+ {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
+ {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x01, 0x45, 0xcc}, {0xb3, 0x03, 0x0b, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc}, {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x35, 0x91, 0xcc}, {0xb3, 0x00, 0x27, 0xcc},
+ {0xbc, 0x00, 0x73, 0xcc},
+ {0xb8, 0x00, 0x23, 0xcc}, {0x00, 0x01, 0x0c, 0xaa},
+ {0x00, 0x14, 0x01, 0xaa}, {0x00, 0x15, 0xe6, 0xaa},
+ {0x00, 0x16, 0x02, 0xaa},
+ {0x00, 0x17, 0x86, 0xaa}, {0x00, 0x23, 0x00, 0xaa},
+ {0x00, 0x25, 0x09, 0xaa}, {0x00, 0x26, 0x27, 0xaa},
+ {0x00, 0x27, 0xc0, 0xaa},
+ {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
+ {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
+ {0xb8, 0x30, 0x50, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc},
+ {0xb8, 0x33, 0xf8, 0xcc}, {0xb8, 0x34, 0x65, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc},
+ {0xb8, 0xff, 0x28, 0xcc}, {0xb9, 0x00, 0x28, 0xcc},
+ {0xb9, 0x01, 0x28, 0xcc},
+ {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
+ {0xb9, 0x06, 0x3c, 0xcc},
+ {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
+ {0x00, 0x30, 0x18, 0xaa},
+ {}
+};
+
+static const __u8 hv7131r_initQVGA_data[][4] = {
+ {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
+ {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x03, 0x0b, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0x91, 0xcc},
+ {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc},
+ {0xb8, 0x00, 0x21, 0xcc},
+ {0x00, 0x01, 0x0c, 0xaa}, {0x00, 0x14, 0x01, 0xaa},
+ {0x00, 0x15, 0xe6, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
+ {0x00, 0x17, 0x86, 0xaa},
+ {0x00, 0x23, 0x00, 0xaa}, {0x00, 0x25, 0x01, 0xaa},
+ {0x00, 0x26, 0xd4, 0xaa}, {0x00, 0x27, 0xc0, 0xaa},
+ {0xbc, 0x02, 0x08, 0xcc},
+ {0xbc, 0x03, 0x70, 0xcc}, {0xbc, 0x04, 0x08, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x3c, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x04, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb8, 0xfe, 0x02, 0xcc},
+ {0xb8, 0xff, 0x07, 0xcc}, {0xb9, 0x00, 0x14, 0xcc},
+ {0xb9, 0x01, 0x14, 0xcc}, {0xb9, 0x02, 0x14, 0xcc},
+ {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x02, 0xcc}, {0xb9, 0x05, 0x05, 0xcc},
+ {0xb9, 0x06, 0x0f, 0xcc}, {0xb9, 0x07, 0x0f, 0xcc},
+ {0xb9, 0x08, 0x0f, 0xcc},
+ {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
+ {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
+ {0xb8, 0x30, 0x50, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc},
+ {0xb8, 0x33, 0xf8, 0xcc},
+ {0xb8, 0x34, 0x65, 0xcc}, {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc},
+ {0xb8, 0xff, 0x28, 0xcc},
+ {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
+ {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x00, 0xcc},
+ {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc},
+ {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc}, {0x00, 0x30, 0x18, 0xaa},
+ {}
+};
+
+static const __u8 ov7660_gamma[17] = {
+ 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+ 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
+};
+static const __u8 ov7660_matrix[9] = {
+ 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62
+};
+static const __u8 ov7660_initVGA_data[][4] = {
+ {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
+ {0x00, 0x00, 0x50, 0xdd},
+ {0xb0, 0x03, 0x01, 0xcc},
+ {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc},
+ {0xb3, 0x1f, 0x02, 0xcc},
+ {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
+ {0xb8, 0x00, 0x33, 0xcc}, /* 13 */
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x8f, 0x50, 0xcc},
+ {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
+ {0x00, 0x12, 0x80, 0xaa},
+ {0x00, 0x12, 0x05, 0xaa},
+ {0x00, 0x1e, 0x01, 0xaa},
+ {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
+ {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
+ {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
+ {0x00, 0x13, 0xa7, 0xaa},
+ {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa},
+ {0x00, 0x36, 0x00, 0xaa},
+ {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa},
+ {0x00, 0x39, 0x43, 0xaa},
+ {0x00, 0x8d, 0xcf, 0xaa},
+ {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa},
+ {0x00, 0x0f, 0x62, 0xaa},
+ {0x00, 0x35, 0x84, 0xaa},
+ {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */
+ {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/
+ {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */
+ {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc},
+ {0x00, 0x01, 0x80, 0xaa},
+ {0x00, 0x02, 0x80, 0xaa},
+ {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc},
+ {0xb9, 0x00, 0x28, 0xcc},
+ {0xb9, 0x01, 0x28, 0xcc}, {0xb9, 0x02, 0x28, 0xcc},
+ {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x00, 0xcc},
+ {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc},
+ {0xb9, 0x07, 0x3c, 0xcc},
+ {0xb9, 0x08, 0x3c, 0xcc},
+
+ {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
+
+ {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc},
+ {}
+};
+static const __u8 ov7660_initQVGA_data[][4] = {
+ {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
+ {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
+ {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc},
+ {0xb3, 0x1f, 0x02, 0xcc}, {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
+ {0xb8, 0x00, 0x33, 0xcc}, /* 13 */
+ {0xb8, 0x01, 0x7d, 0xcc},
+/* sizer */
+ {0xbc, 0x00, 0xd3, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc},
+ {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa},
+ {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa},
+ {0x00, 0x1e, 0x01, 0xaa},
+ {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */
+ {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */
+ {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa},
+ {0x00, 0x13, 0xa7, 0xaa},
+ {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa},
+ {0x00, 0x36, 0x00, 0xaa},
+ {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa},
+ {0x00, 0x39, 0x43, 0xaa}, {0x00, 0x8d, 0xcf, 0xaa},
+ {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa},
+ {0x00, 0x0f, 0x62, 0xaa}, {0x00, 0x35, 0x84, 0xaa},
+ {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */
+ {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/
+ {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */
+ {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc},
+ {0x00, 0x01, 0x80, 0xaa},
+ {0x00, 0x02, 0x80, 0xaa},
+/* sizer filters */
+ {0xbc, 0x02, 0x08, 0xcc},
+ {0xbc, 0x03, 0x70, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
+ {0xbc, 0x04, 0x08, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x3c, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x04, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+/* */
+ {0xb8, 0xfe, 0x00, 0xcc},
+ {0xb8, 0xff, 0x28, 0xcc},
+/* */
+ {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
+ {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
+ {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
+ {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc},
+ {0xb9, 0x08, 0x3c, 0xcc},
+/* */
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc}, /* ff */
+ {0x00, 0x29, 0x3c, 0xaa},
+ {0xb3, 0x01, 0x45, 0xcc}, /* 45 */
+ {}
+};
+
+static const __u8 ov7660_50HZ[][4] = {
+ {0x00, 0x3b, 0x08, 0xaa},
+ {0x00, 0x9d, 0x40, 0xaa},
+ {0x00, 0x13, 0xa7, 0xaa},
+ {}
+};
+
+static const __u8 ov7660_60HZ[][4] = {
+ {0x00, 0x3b, 0x00, 0xaa},
+ {0x00, 0x9e, 0x40, 0xaa},
+ {0x00, 0x13, 0xa7, 0xaa},
+ {}
+};
+
+static const __u8 ov7660_NoFliker[][4] = {
+ {0x00, 0x13, 0x87, 0xaa},
+ {}
+};
+
+static const __u8 ov7670_initVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x05, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
+ {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0x41, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa},
+ {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa},
+ {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa},
+ {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa},
+ {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa},
+ {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa},
+ {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa},
+ {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa},
+ {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa},
+ {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa},
+ {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa},
+ {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa},
+ {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa},
+ {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa},
+ {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa},
+ {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa},
+ {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa},
+ {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa},
+ {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa},
+ {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa},
+ {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa},
+ {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
+ {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa},
+ {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
+ {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa},
+ {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa},
+ {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa},
+ {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa},
+ {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa},
+ {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa},
+ {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa},
+ {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa},
+ {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa},
+ {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa},
+ {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
+ {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa},
+ {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa},
+ {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa},
+ {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa},
+ {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa},
+ {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa},
+ {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa},
+ {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa},
+ {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa},
+ {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa},
+ {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa},
+ {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa},
+ {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa},
+ {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa},
+ {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa},
+ {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa},
+ {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa},
+ {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa},
+ {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa},
+ {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa},
+ {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa},
+ {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa},
+ {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa},
+ {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa},
+ {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa},
+ {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa},
+ {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa},
+ {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa},
+ {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa},
+ {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa},
+ {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa},
+ {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa},
+ {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa},
+ {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa},
+ {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa},
+ {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa},
+ {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa},
+ {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa},
+ {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa},
+ {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa},
+ {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa},
+ {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa},
+ {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa},
+ {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa},
+ {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa},
+ {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa},
+ {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa},
+ {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa},
+ {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa},
+ {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa},
+ {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa},
+ {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa},
+ {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa},
+ {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
+ {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
+ {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa},
+ {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa},
+ {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa},
+ {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa},
+ {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa},
+ {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa},
+ {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa},
+ {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa},
+ {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa},
+ {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa},
+ {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc},
+ {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x13, 0xcc},
+ {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc},
+ {0x00, 0x77, 0x05, 0xaa},
+ {},
+};
+
+static const __u8 ov7670_initQVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd},
+ {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
+ {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
+ {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa},
+ {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa},
+ {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa},
+ {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa},
+ {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa},
+ {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa},
+ {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa},
+ {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa},
+ {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa},
+ {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa},
+ {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa},
+ {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa},
+ {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa},
+ {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa},
+ {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa},
+ {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa},
+ {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa},
+ {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa},
+ {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa},
+ {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa},
+ {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa},
+ {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
+ {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa},
+ {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
+ {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa},
+ {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa},
+ {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa},
+ {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa},
+ {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa},
+ {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa},
+ {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa},
+ {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa},
+ {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa},
+ {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa},
+ {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
+ {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa},
+ {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa},
+ {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa},
+ {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa},
+ {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa},
+ {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa},
+ {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa},
+ {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa},
+ {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa},
+ {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa},
+ {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa},
+ {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa},
+ {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa},
+ {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa},
+ {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa},
+ {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa},
+ {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa},
+ {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa},
+ {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa},
+ {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa},
+ {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa},
+ {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa},
+ {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa},
+ {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa},
+ {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa},
+ {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa},
+ {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa},
+ {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa},
+ {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa},
+ {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa},
+ {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa},
+ {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa},
+ {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa},
+ {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa},
+ {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa},
+ {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa},
+ {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa},
+ {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa},
+ {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa},
+ {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa},
+ {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa},
+ {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa},
+ {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa},
+ {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa},
+ {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa},
+ {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa},
+ {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa},
+ {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa},
+ {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa},
+ {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa},
+ {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa},
+ {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa},
+ {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa},
+ {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa},
+ {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa},
+ {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa},
+ {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa},
+ {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa},
+ {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa},
+ {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa},
+ {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa},
+ {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa},
+ {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa},
+ {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa},
+ {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa},
+ {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x21, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc},
+ {0x00, 0x77, 0x05, 0xaa },
+ {},
+};
+
+struct sensor_info {
+ int sensorId;
+ __u8 I2cAdd;
+ __u8 IdAdd;
+ __u16 VpId;
+ __u8 m1;
+ __u8 m2;
+ __u8 op;
+ };
+
+static const struct sensor_info sensor_info_data[] = {
+/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
+ {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+ {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+ {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01},
+ {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
+ {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
+ {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
+};
+
+/* read 'len' bytes in gspca_dev->usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ __u16 req,
+ __u16 index,
+ __u16 len)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 1, /* value */
+ index, gspca_dev->usb_buf, len,
+ 500);
+}
+
+static void reg_w(struct usb_device *dev,
+ __u16 req,
+ __u16 value,
+ __u16 index)
+{
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0,
+ 500);
+}
+
+static void read_sensor_register(struct gspca_dev *gspca_dev,
+ __u16 address, __u16 *value)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 ldata, mdata, hdata;
+ int retry = 50;
+
+ *value = 0;
+
+ reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+ /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */
+ if (!(gspca_dev->usb_buf[0] & 0x02)) {
+ PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
+ gspca_dev->usb_buf[0] & 0x02);
+ return;
+ }
+ reg_w(dev, 0xa0, address, 0xb33a);
+ reg_w(dev, 0xa0, 0x02, 0xb339);
+
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ while (retry-- && gspca_dev->usb_buf[0]) {
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
+ msleep(1);
+ }
+ reg_r(gspca_dev, 0xa1, 0xb33e, 1);
+ hdata = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0xa1, 0xb33d, 1);
+ mdata = gspca_dev->usb_buf[0];
+ reg_r(gspca_dev, 0xa1, 0xb33c, 1);
+ ldata = gspca_dev->usb_buf[0];
+ PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)",
+ hdata, mdata, ldata);
+ reg_r(gspca_dev, 0xa1, 0xb334, 1);
+ if (gspca_dev->usb_buf[0] == 0x02)
+ *value = (ldata << 8) + mdata;
+ else
+ *value = ldata;
+}
+
+static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int i;
+ __u16 value;
+ const struct sensor_info *ptsensor_info;
+
+ reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
+ PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]);
+ for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
+ ptsensor_info = &sensor_info_data[i];
+ reg_w(dev, 0xa0, 0x02, 0xb334);
+ reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300);
+ reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300);
+ reg_w(dev, 0xa0, 0x01, 0xb308);
+ reg_w(dev, 0xa0, 0x0c, 0xb309);
+ reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
+/* PDEBUG(D_PROBE,
+ "check sensor VC032X -> %d Add -> ox%02X!",
+ i, ptsensor_info->I2cAdd); */
+ reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
+ read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
+ if (value == ptsensor_info->VpId) {
+/* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!",
+ ptsensor_info->VpId); */
+ return ptsensor_info->sensorId;
+ }
+ }
+ return -1;
+}
+
+static __u8 i2c_write(struct gspca_dev *gspca_dev,
+ __u8 reg, const __u8 *val, __u8 size)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ if (size > 3 || size < 1)
+ return -EINVAL;
+ reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+ reg_w(dev, 0xa0, size, 0xb334);
+ reg_w(dev, 0xa0, reg, 0xb33a);
+ switch (size) {
+ case 1:
+ reg_w(dev, 0xa0, val[0], 0xb336);
+ break;
+ case 2:
+ reg_w(dev, 0xa0, val[0], 0xb336);
+ reg_w(dev, 0xa0, val[1], 0xb337);
+ break;
+ case 3:
+ reg_w(dev, 0xa0, val[0], 0xb336);
+ reg_w(dev, 0xa0, val[1], 0xb337);
+ reg_w(dev, 0xa0, val[2], 0xb338);
+ break;
+ default:
+ reg_w(dev, 0xa0, 0x01, 0xb334);
+ return -EINVAL;
+ }
+ reg_w(dev, 0xa0, 0x01, 0xb339);
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ return gspca_dev->usb_buf[0] == 0;
+}
+
+static void put_tab_to_reg(struct gspca_dev *gspca_dev,
+ const __u8 *tab, __u8 tabsize, __u16 addr)
+{
+ int j;
+ __u16 ad = addr;
+
+ for (j = 0; j < tabsize; j++)
+ reg_w(gspca_dev->dev, 0xa0, tab[j], ad++);
+}
+
+static void usb_exchange(struct gspca_dev *gspca_dev,
+ const __u8 data[][4])
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int i = 0;
+
+ for (;;) {
+ switch (data[i][3]) {
+ default:
+ return;
+ case 0xcc: /* normal write */
+ reg_w(dev, 0xa0, data[i][2],
+ ((data[i][0])<<8) | data[i][1]);
+ break;
+ case 0xaa: /* i2c op */
+ i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
+ break;
+ case 0xbb: /* i2c op */
+ i2c_write(gspca_dev, data[i][0], &data[i][1], 2);
+ break;
+ case 0xdd:
+ msleep(data[i][2] + 10);
+ break;
+ }
+ i++;
+ }
+ /*not reached*/
+}
+
+/*
+ "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff
+ "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66
+ */
+
+static void vc0321_reset(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d);
+ reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301);
+ msleep(100);
+ reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003);
+ msleep(100);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ struct cam *cam;
+ int sensor;
+ __u16 product;
+
+ product = id->idProduct;
+ sd->bridge = BRIDGE_VC0321;
+ switch (id->idVendor) {
+ case 0x0ac8: /* Vimicro z-star */
+ switch (product) {
+ case 0x0323:
+ sd->bridge = BRIDGE_VC0323;
+ break;
+ }
+ break;
+ case 0x17ef: /* Lenovo */
+/* switch (product) { */
+/* case 0x4802: * Lenovo MI1310_SOC */
+ sd->bridge = BRIDGE_VC0323;
+/* break; */
+/* } */
+ break;
+ }
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x02;
+ if (sd->bridge == BRIDGE_VC0321) {
+ cam->cam_mode = vc0321_mode;
+ cam->nmodes = ARRAY_SIZE(vc0321_mode);
+ } else {
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode);
+ }
+
+ vc0321_reset(gspca_dev);
+ sensor = vc032x_probe_sensor(gspca_dev);
+ switch (sensor) {
+ case -1:
+ PDEBUG(D_PROBE, "Unknown sensor...");
+ return -EINVAL;
+ case SENSOR_HV7131R:
+ PDEBUG(D_PROBE, "Find Sensor HV7131R");
+ sd->sensor = SENSOR_HV7131R;
+ break;
+ case SENSOR_MI1310_SOC:
+ PDEBUG(D_PROBE, "Find Sensor MI1310_SOC");
+ sd->sensor = SENSOR_MI1310_SOC;
+ break;
+ case SENSOR_MI1320:
+ PDEBUG(D_PROBE, "Find Sensor MI1320");
+ sd->sensor = SENSOR_MI1320;
+ break;
+ case SENSOR_OV7660:
+ PDEBUG(D_PROBE, "Find Sensor OV7660");
+ sd->sensor = SENSOR_OV7660;
+ break;
+ case SENSOR_OV7670:
+ PDEBUG(D_PROBE, "Find Sensor OV7670");
+ sd->sensor = SENSOR_OV7670;
+ break;
+ case SENSOR_PO3130NC:
+ PDEBUG(D_PROBE, "Find Sensor PO3130NC");
+ sd->sensor = SENSOR_PO3130NC;
+ break;
+ }
+
+ sd->qindex = 7;
+ sd->autogain = AUTOGAIN_DEF;
+ sd->lightfreq = FREQ_DEF;
+
+ if (sd->bridge == BRIDGE_VC0321) {
+ reg_r(gspca_dev, 0x8a, 0, 3);
+ reg_w(dev, 0x87, 0x00, 0x0f0f);
+
+ reg_r(gspca_dev, 0x8b, 0, 3);
+ reg_w(dev, 0x88, 0x00, 0x0202);
+ }
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+static void setquality(struct gspca_dev *gspca_dev)
+{
+}
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+}
+
+static void setlightfreq(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ static const __u8 (*ov7660_freq_tb[3])[4] =
+ {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ};
+
+ if (sd->sensor != SENSOR_OV7660)
+ return;
+ usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]);
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ const __u8 *GammaT = NULL;
+ const __u8 *MatrixT = NULL;
+ int mode;
+
+ /* Assume start use the good resolution from gspca_dev->mode */
+ if (sd->bridge == BRIDGE_VC0321) {
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec);
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed);
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee);
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef);
+ }
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ GammaT = hv7131r_gamma;
+ MatrixT = hv7131r_matrix;
+ if (mode) {
+ /* 320x240 */
+ usb_exchange(gspca_dev, hv7131r_initQVGA_data);
+ } else {
+ /* 640x480 */
+ usb_exchange(gspca_dev, hv7131r_initVGA_data);
+ }
+ break;
+ case SENSOR_OV7660:
+ GammaT = ov7660_gamma;
+ MatrixT = ov7660_matrix;
+ if (mode) {
+ /* 320x240 */
+ usb_exchange(gspca_dev, ov7660_initQVGA_data);
+ } else {
+ /* 640x480 */
+ usb_exchange(gspca_dev, ov7660_initVGA_data);
+ }
+ break;
+ case SENSOR_OV7670:
+ /*GammaT = ov7660_gamma; */
+ /*MatrixT = ov7660_matrix; */
+ if (mode) {
+ /* 320x240 */
+ usb_exchange(gspca_dev, ov7670_initQVGA_JPG);
+ } else {
+ /* 640x480 */
+ usb_exchange(gspca_dev, ov7670_initVGA_JPG);
+ }
+ break;
+ case SENSOR_MI1310_SOC:
+ if (mode) {
+ /* 320x240 */
+ usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG);
+ } else {
+ /* 640x480 */
+ usb_exchange(gspca_dev, mi1310_socinitVGA_JPG);
+ }
+ break;
+ case SENSOR_MI1320:
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ if (mode) {
+ /* 320x240 */
+ usb_exchange(gspca_dev, mi1320_initQVGA_data);
+ } else {
+ /* 640x480 */
+ usb_exchange(gspca_dev, mi1320_initVGA_data);
+ }
+ break;
+ case SENSOR_PO3130NC:
+ GammaT = po3130_gamma;
+ MatrixT = po3130_matrix;
+ if (mode) {
+ /* 320x240 */
+ usb_exchange(gspca_dev, po3130_initQVGA_data);
+ } else {
+ /* 640x480 */
+ usb_exchange(gspca_dev, po3130_initVGA_data);
+ }
+ usb_exchange(gspca_dev, po3130_rundata);
+ break;
+ default:
+ PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
+ return;
+ }
+ if (GammaT && MatrixT) {
+ put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
+ put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
+ put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
+ put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
+
+ /* Seem SHARPNESS */
+ /*
+ reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a);
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b);
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e);
+ */
+ /* all 0x40 ??? do nothing
+ reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822);
+ reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823);
+ reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
+ */
+ /* Only works for HV7131R ??
+ reg_r (gspca_dev, 0xa1, 0xb881, 1);
+ reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
+ reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
+ */
+ /* only hv7131r et ov7660
+ reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827);
+ reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80
+ reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
+ */
+ /* set the led on 0x0892 0x0896 */
+ reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
+ msleep(100);
+ setquality(gspca_dev);
+ setautogain(gspca_dev);
+ setlightfreq(gspca_dev);
+ }
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ reg_w(dev, 0x89, 0xffff, 0xffff);
+ reg_w(dev, 0xa0, 0x01, 0xb301);
+ reg_w(dev, 0xa0, 0x09, 0xb003);
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+
+ reg_w(dev, 0x89, 0xffff, 0xffff);
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+/* struct usb_device *dev = gspca_dev->dev;
+ __u8 buffread;
+
+ reg_w(dev, 0x89, 0xffff, 0xffff);
+ reg_w(dev, 0xa0, 0x01, 0xb301);
+ reg_w(dev, 0xa0, 0x09, 0xb303);
+ reg_w(dev, 0x89, 0xffff, 0xffff);
+*/
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso pkt length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (data[0] == 0xff && data[1] == 0xd8) {
+ PDEBUG(D_PACK,
+ "vc032x header packet found len %d", len);
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
+ if (sd->bridge == BRIDGE_VC0321) {
+#define VCHDRSZ 46
+ data += VCHDRSZ;
+ len -= VCHDRSZ;
+#undef VCHDRSZ
+ }
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ data, len);
+ return;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (gspca_dev->streaming)
+ setautogain(gspca_dev);
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->lightfreq = val;
+ if (gspca_dev->streaming)
+ setlightfreq(gspca_dev);
+ return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->lightfreq;
+ return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu)
+{
+ switch (menu->id) {
+ case V4L2_CID_POWER_LINE_FREQUENCY:
+ switch (menu->index) {
+ case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+ strcpy((char *) menu->name, "NoFliker");
+ return 0;
+ case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+ strcpy((char *) menu->name, "50 Hz");
+ return 0;
+ case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ strcpy((char *) menu->name, "60 Hz");
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+ .querymenu = sd_querymenu,
+};
+
+/* -- module initialisation -- */
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")},
+ {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")},
+ {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")},
+ {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")},
+ {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")},
+ {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")},
+ {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")},
+ {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h
new file mode 100644
index 00000000000..f52e09c2cc1
--- /dev/null
+++ b/drivers/media/video/gspca/zc3xx-reg.h
@@ -0,0 +1,261 @@
+/*
+ * zc030x registers
+ *
+ * Copyright (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
+ * The register aliases used here came from this driver:
+ * http://zc0302.sourceforge.net/zc0302.php
+ *
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
+/* Define the register map */
+#define ZC3XX_R000_SYSTEMCONTROL 0x0000
+#define ZC3XX_R001_SYSTEMOPERATING 0x0001
+
+/* Picture size */
+#define ZC3XX_R002_CLOCKSELECT 0x0002
+#define ZC3XX_R003_FRAMEWIDTHHIGH 0x0003
+#define ZC3XX_R004_FRAMEWIDTHLOW 0x0004
+#define ZC3XX_R005_FRAMEHEIGHTHIGH 0x0005
+#define ZC3XX_R006_FRAMEHEIGHTLOW 0x0006
+
+/* JPEG control */
+#define ZC3XX_R008_CLOCKSETTING 0x0008
+
+/* Test mode */
+#define ZC3XX_R00B_TESTMODECONTROL 0x000b
+
+/* Frame retreiving */
+#define ZC3XX_R00C_LASTACQTIME 0x000c
+#define ZC3XX_R00D_MONITORRES 0x000d
+#define ZC3XX_R00E_TIMESTAMPHIGH 0x000e
+#define ZC3XX_R00F_TIMESTAMPLOW 0x000f
+#define ZC3XX_R018_FRAMELOST 0x0018
+#define ZC3XX_R019_AUTOADJUSTFPS 0x0019
+#define ZC3XX_R01A_LASTFRAMESTATE 0x001a
+#define ZC3XX_R025_DATACOUNTER 0x0025
+
+/* Stream and sensor specific */
+#define ZC3XX_R010_CMOSSENSORSELECT 0x0010
+#define ZC3XX_R011_VIDEOSTATUS 0x0011
+#define ZC3XX_R012_VIDEOCONTROLFUNC 0x0012
+
+/* Horizontal and vertical synchros */
+#define ZC3XX_R01D_HSYNC_0 0x001d
+#define ZC3XX_R01E_HSYNC_1 0x001e
+#define ZC3XX_R01F_HSYNC_2 0x001f
+#define ZC3XX_R020_HSYNC_3 0x0020
+
+/* Target picture size in byte */
+#define ZC3XX_R022_TARGETPICTSIZE_0 0x0022
+#define ZC3XX_R023_TARGETPICTSIZE_1 0x0023
+#define ZC3XX_R024_TARGETPICTSIZE_2 0x0024
+
+/* Audio registers */
+#define ZC3XX_R030_AUDIOADC 0x0030
+#define ZC3XX_R031_AUDIOSTREAMSTATUS 0x0031
+#define ZC3XX_R032_AUDIOSTATUS 0x0032
+
+/* Sensor interface */
+#define ZC3XX_R080_HBLANKHIGH 0x0080
+#define ZC3XX_R081_HBLANKLOW 0x0081
+#define ZC3XX_R082_RESETLEVELADDR 0x0082
+#define ZC3XX_R083_RGAINADDR 0x0083
+#define ZC3XX_R084_GGAINADDR 0x0084
+#define ZC3XX_R085_BGAINADDR 0x0085
+#define ZC3XX_R086_EXPTIMEHIGH 0x0086
+#define ZC3XX_R087_EXPTIMEMID 0x0087
+#define ZC3XX_R088_EXPTIMELOW 0x0088
+#define ZC3XX_R089_RESETBLACKHIGH 0x0089
+#define ZC3XX_R08A_RESETWHITEHIGH 0x008a
+#define ZC3XX_R08B_I2CDEVICEADDR 0x008b
+#define ZC3XX_R08C_I2CIDLEANDNACK 0x008c
+#define ZC3XX_R08D_COMPABILITYMODE 0x008d
+#define ZC3XX_R08E_COMPABILITYMODE2 0x008e
+
+/* I2C control */
+#define ZC3XX_R090_I2CCOMMAND 0x0090
+#define ZC3XX_R091_I2CSTATUS 0x0091
+#define ZC3XX_R092_I2CADDRESSSELECT 0x0092
+#define ZC3XX_R093_I2CSETVALUE 0x0093
+#define ZC3XX_R094_I2CWRITEACK 0x0094
+#define ZC3XX_R095_I2CREAD 0x0095
+#define ZC3XX_R096_I2CREADACK 0x0096
+
+/* Window inside the sensor array */
+#define ZC3XX_R097_WINYSTARTHIGH 0x0097
+#define ZC3XX_R098_WINYSTARTLOW 0x0098
+#define ZC3XX_R099_WINXSTARTHIGH 0x0099
+#define ZC3XX_R09A_WINXSTARTLOW 0x009a
+#define ZC3XX_R09B_WINHEIGHTHIGH 0x009b
+#define ZC3XX_R09C_WINHEIGHTLOW 0x009c
+#define ZC3XX_R09D_WINWIDTHHIGH 0x009d
+#define ZC3XX_R09E_WINWIDTHLOW 0x009e
+#define ZC3XX_R119_FIRSTYHIGH 0x0119
+#define ZC3XX_R11A_FIRSTYLOW 0x011a
+#define ZC3XX_R11B_FIRSTXHIGH 0x011b
+#define ZC3XX_R11C_FIRSTXLOW 0x011c
+
+/* Max sensor array size */
+#define ZC3XX_R09F_MAXXHIGH 0x009f
+#define ZC3XX_R0A0_MAXXLOW 0x00a0
+#define ZC3XX_R0A1_MAXYHIGH 0x00a1
+#define ZC3XX_R0A2_MAXYLOW 0x00a2
+#define ZC3XX_R0A3_EXPOSURETIMEHIGH 0x00a3
+#define ZC3XX_R0A4_EXPOSURETIMELOW 0x00a4
+#define ZC3XX_R0A5_EXPOSUREGAIN 0x00a5
+#define ZC3XX_R0A6_EXPOSUREBLACKLVL 0x00a6
+
+/* Other registers */
+#define ZC3XX_R100_OPERATIONMODE 0x0100
+#define ZC3XX_R101_SENSORCORRECTION 0x0101
+
+/* Gains */
+#define ZC3XX_R116_RGAIN 0x0116
+#define ZC3XX_R117_GGAIN 0x0117
+#define ZC3XX_R118_BGAIN 0x0118
+#define ZC3XX_R11D_GLOBALGAIN 0x011d
+#define ZC3XX_R1A8_DIGITALGAIN 0x01a8
+#define ZC3XX_R1A9_DIGITALLIMITDIFF 0x01a9
+#define ZC3XX_R1AA_DIGITALGAINSTEP 0x01aa
+
+/* Auto correction */
+#define ZC3XX_R180_AUTOCORRECTENABLE 0x0180
+#define ZC3XX_R181_WINXSTART 0x0181
+#define ZC3XX_R182_WINXWIDTH 0x0182
+#define ZC3XX_R183_WINXCENTER 0x0183
+#define ZC3XX_R184_WINYSTART 0x0184
+#define ZC3XX_R185_WINYWIDTH 0x0185
+#define ZC3XX_R186_WINYCENTER 0x0186
+
+/* Gain range */
+#define ZC3XX_R187_MAXGAIN 0x0187
+#define ZC3XX_R188_MINGAIN 0x0188
+
+/* Auto exposure and white balance */
+#define ZC3XX_R189_AWBSTATUS 0x0189
+#define ZC3XX_R18A_AWBFREEZE 0x018a
+#define ZC3XX_R18B_AESTATUS 0x018b
+#define ZC3XX_R18C_AEFREEZE 0x018c
+#define ZC3XX_R18F_AEUNFREEZE 0x018f
+#define ZC3XX_R190_EXPOSURELIMITHIGH 0x0190
+#define ZC3XX_R191_EXPOSURELIMITMID 0x0191
+#define ZC3XX_R192_EXPOSURELIMITLOW 0x0192
+#define ZC3XX_R195_ANTIFLICKERHIGH 0x0195
+#define ZC3XX_R196_ANTIFLICKERMID 0x0196
+#define ZC3XX_R197_ANTIFLICKERLOW 0x0197
+
+/* What is this ? */
+#define ZC3XX_R18D_YTARGET 0x018d
+#define ZC3XX_R18E_RESETLVL 0x018e
+
+/* Color */
+#define ZC3XX_R1A0_REDMEANAFTERAGC 0x01a0
+#define ZC3XX_R1A1_GREENMEANAFTERAGC 0x01a1
+#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2
+#define ZC3XX_R1A3_REDMEANAFTERAWB 0x01a3
+#define ZC3XX_R1A4_GREENMEANAFTERAWB 0x01a4
+#define ZC3XX_R1A5_BLUEMEANAFTERAWB 0x01a5
+#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6
+#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7
+
+#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2
+
+/* Matrixes */
+
+/* Color matrix is like :
+ R' = R * RGB00 + G * RGB01 + B * RGB02 + RGB03
+ G' = R * RGB10 + G * RGB11 + B * RGB22 + RGB13
+ B' = R * RGB20 + G * RGB21 + B * RGB12 + RGB23
+ */
+#define ZC3XX_R10A_RGB00 0x010a
+#define ZC3XX_R10B_RGB01 0x010b
+#define ZC3XX_R10C_RGB02 0x010c
+#define ZC3XX_R113_RGB03 0x0113
+#define ZC3XX_R10D_RGB10 0x010d
+#define ZC3XX_R10E_RGB11 0x010e
+#define ZC3XX_R10F_RGB12 0x010f
+#define ZC3XX_R114_RGB13 0x0114
+#define ZC3XX_R110_RGB20 0x0110
+#define ZC3XX_R111_RGB21 0x0111
+#define ZC3XX_R112_RGB22 0x0112
+#define ZC3XX_R115_RGB23 0x0115
+
+/* Gamma matrix */
+#define ZC3XX_R120_GAMMA00 0x0120
+#define ZC3XX_R121_GAMMA01 0x0121
+#define ZC3XX_R122_GAMMA02 0x0122
+#define ZC3XX_R123_GAMMA03 0x0123
+#define ZC3XX_R124_GAMMA04 0x0124
+#define ZC3XX_R125_GAMMA05 0x0125
+#define ZC3XX_R126_GAMMA06 0x0126
+#define ZC3XX_R127_GAMMA07 0x0127
+#define ZC3XX_R128_GAMMA08 0x0128
+#define ZC3XX_R129_GAMMA09 0x0129
+#define ZC3XX_R12A_GAMMA0A 0x012a
+#define ZC3XX_R12B_GAMMA0B 0x012b
+#define ZC3XX_R12C_GAMMA0C 0x012c
+#define ZC3XX_R12D_GAMMA0D 0x012d
+#define ZC3XX_R12E_GAMMA0E 0x012e
+#define ZC3XX_R12F_GAMMA0F 0x012f
+#define ZC3XX_R130_GAMMA10 0x0130
+#define ZC3XX_R131_GAMMA11 0x0131
+#define ZC3XX_R132_GAMMA12 0x0132
+#define ZC3XX_R133_GAMMA13 0x0133
+#define ZC3XX_R134_GAMMA14 0x0134
+#define ZC3XX_R135_GAMMA15 0x0135
+#define ZC3XX_R136_GAMMA16 0x0136
+#define ZC3XX_R137_GAMMA17 0x0137
+#define ZC3XX_R138_GAMMA18 0x0138
+#define ZC3XX_R139_GAMMA19 0x0139
+#define ZC3XX_R13A_GAMMA1A 0x013a
+#define ZC3XX_R13B_GAMMA1B 0x013b
+#define ZC3XX_R13C_GAMMA1C 0x013c
+#define ZC3XX_R13D_GAMMA1D 0x013d
+#define ZC3XX_R13E_GAMMA1E 0x013e
+#define ZC3XX_R13F_GAMMA1F 0x013f
+
+/* Luminance gamma */
+#define ZC3XX_R140_YGAMMA00 0x0140
+#define ZC3XX_R141_YGAMMA01 0x0141
+#define ZC3XX_R142_YGAMMA02 0x0142
+#define ZC3XX_R143_YGAMMA03 0x0143
+#define ZC3XX_R144_YGAMMA04 0x0144
+#define ZC3XX_R145_YGAMMA05 0x0145
+#define ZC3XX_R146_YGAMMA06 0x0146
+#define ZC3XX_R147_YGAMMA07 0x0147
+#define ZC3XX_R148_YGAMMA08 0x0148
+#define ZC3XX_R149_YGAMMA09 0x0149
+#define ZC3XX_R14A_YGAMMA0A 0x014a
+#define ZC3XX_R14B_YGAMMA0B 0x014b
+#define ZC3XX_R14C_YGAMMA0C 0x014c
+#define ZC3XX_R14D_YGAMMA0D 0x014d
+#define ZC3XX_R14E_YGAMMA0E 0x014e
+#define ZC3XX_R14F_YGAMMA0F 0x014f
+#define ZC3XX_R150_YGAMMA10 0x0150
+#define ZC3XX_R151_YGAMMA11 0x0151
+
+#define ZC3XX_R1C5_SHARPNESSMODE 0x01c5
+#define ZC3XX_R1C6_SHARPNESS00 0x01c6
+#define ZC3XX_R1C7_SHARPNESS01 0x01c7
+#define ZC3XX_R1C8_SHARPNESS02 0x01c8
+#define ZC3XX_R1C9_SHARPNESS03 0x01c9
+#define ZC3XX_R1CA_SHARPNESS04 0x01ca
+#define ZC3XX_R1CB_SHARPNESS05 0x01cb
+
+/* Synchronization */
+#define ZC3XX_R190_SYNC00LOW 0x0190
+#define ZC3XX_R191_SYNC00MID 0x0191
+#define ZC3XX_R192_SYNC00HIGH 0x0192
+#define ZC3XX_R195_SYNC01LOW 0x0195
+#define ZC3XX_R196_SYNC01MID 0x0196
+#define ZC3XX_R197_SYNC01HIGH 0x0197
+
+/* Dead pixels */
+#define ZC3XX_R250_DEADPIXELSMODE 0x0250
+
+/* EEPROM */
+#define ZC3XX_R300_EEPROMCONFIG 0x0300
+#define ZC3XX_R301_EEPROMACCESS 0x0301
+#define ZC3XX_R302_EEPROMSTATUS 0x0302
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
new file mode 100644
index 00000000000..b761b11c5c6
--- /dev/null
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -0,0 +1,7623 @@
+/*
+ * Z-Star/Vimicro zc301/zc302p/vc30x library
+ * Copyright (C) 2004 2005 2006 Michel Xhaard
+ * mxhaard@magic.fr
+ *
+ * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ *
+ * 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.
+ */
+
+#define MODULE_NAME "zc3xx"
+
+#include "gspca.h"
+
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7)
+static const char version[] = "2.1.7";
+
+MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
+ "Serge A. Suchkov <Serge.A.S@tochka.ru>");
+MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+static int force_sensor = -1;
+
+#include "jpeg.h"
+#include "zc3xx-reg.h"
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ __u8 brightness;
+ __u8 contrast;
+ __u8 gamma;
+ __u8 autogain;
+ __u8 lightfreq;
+ __u8 sharpness;
+
+ char qindex;
+ char sensor; /* Type of image sensor chip */
+/* !! values used in different tables */
+#define SENSOR_CS2102 0
+#define SENSOR_CS2102K 1
+#define SENSOR_GC0305 2
+#define SENSOR_HDCS2020 3
+#define SENSOR_HDCS2020b 4
+#define SENSOR_HV7131B 5
+#define SENSOR_HV7131C 6
+#define SENSOR_ICM105A 7
+#define SENSOR_MC501CB 8
+#define SENSOR_OV7620 9
+/*#define SENSOR_OV7648 9 - same values */
+#define SENSOR_OV7630C 10
+#define SENSOR_PAS106 11
+#define SENSOR_PB0330 12
+#define SENSOR_PO2030 13
+#define SENSOR_TAS5130CK 14
+#define SENSOR_TAS5130CXX 15
+#define SENSOR_TAS5130C_VF0250 16
+#define SENSOR_MAX 17
+ unsigned short chip_revision;
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
+static struct ctrl sd_ctrls[] = {
+#define SD_BRIGHTNESS 0
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+#define SD_CONTRAST 1
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 256,
+ .step = 1,
+ .default_value = 128,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+#define SD_GAMMA 2
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 1,
+ .maximum = 6,
+ .step = 1,
+ .default_value = 4,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
+#define SD_AUTOGAIN 3
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Auto Gain",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = sd_setautogain,
+ .get = sd_getautogain,
+ },
+#define SD_FREQ 4
+ {
+ {
+ .id = V4L2_CID_POWER_LINE_FREQUENCY,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .name = "Light frequency filter",
+ .minimum = 0,
+ .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
+ .step = 1,
+ .default_value = 1,
+ },
+ .set = sd_setfreq,
+ .get = sd_getfreq,
+ },
+#define SD_SHARPNESS 5
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+ .default_value = 2,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+static struct v4l2_pix_format sif_mode[] = {
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+};
+
+/* usb exchanges */
+struct usb_action {
+ __u8 req;
+ __u8 val;
+ __u16 idx;
+};
+
+static const struct usb_action cs2102_Initial[] = {
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH},
+ {0xa0, 0x21, ZC3XX_R081_HBLANKLOW},
+ {0xa0, 0x30, ZC3XX_R083_RGAINADDR},
+ {0xa0, 0x31, ZC3XX_R084_GGAINADDR},
+ {0xa0, 0x32, ZC3XX_R085_BGAINADDR},
+ {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH},
+ {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xaa, 0x02, 0x0008},
+ {0xaa, 0x03, 0x0000},
+ {0xaa, 0x11, 0x0000},
+ {0xaa, 0x12, 0x0089},
+ {0xaa, 0x13, 0x0000},
+ {0xaa, 0x14, 0x00e9},
+ {0xaa, 0x20, 0x0000},
+ {0xaa, 0x22, 0x0000},
+ {0xaa, 0x0b, 0x0004},
+ {0xaa, 0x30, 0x0030},
+ {0xaa, 0x31, 0x0030},
+ {0xaa, 0x32, 0x0030},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x10, 0x01ae},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x68, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x00, 0x01ad},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */
+ {0xa0, 0x44, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x64, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x84, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x9d, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xb2, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xc4, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xd3, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xe0, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xeb, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x18, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x20, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0e, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x23, 0x0001},
+ {0xaa, 0x24, 0x0055},
+ {0xaa, 0x25, 0x00cc},
+ {0xaa, 0x21, 0x003f},
+ {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x39, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x70, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {}
+};
+
+static const struct usb_action cs2102_InitialScale[] = {
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH},
+ {0xa0, 0x21, ZC3XX_R081_HBLANKLOW},
+ {0xa0, 0x30, ZC3XX_R083_RGAINADDR},
+ {0xa0, 0x31, ZC3XX_R084_GGAINADDR},
+ {0xa0, 0x32, ZC3XX_R085_BGAINADDR},
+ {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH},
+ {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xaa, 0x02, 0x0008},
+ {0xaa, 0x03, 0x0000},
+ {0xaa, 0x11, 0x0001},
+ {0xaa, 0x12, 0x0087},
+ {0xaa, 0x13, 0x0001},
+ {0xaa, 0x14, 0x00e7},
+ {0xaa, 0x20, 0x0000},
+ {0xaa, 0x22, 0x0000},
+ {0xaa, 0x0b, 0x0004},
+ {0xaa, 0x30, 0x0030},
+ {0xaa, 0x31, 0x0030},
+ {0xaa, 0x32, 0x0030},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x68, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x00, 0x01ad},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */
+ {0xa0, 0x44, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x64, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x84, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x9d, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xb2, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xc4, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xd3, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xe0, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xeb, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x18, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x20, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0e, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x23, 0x0000},
+ {0xaa, 0x24, 0x00aa},
+ {0xaa, 0x25, 0x00e6},
+ {0xaa, 0x21, 0x003f},
+ {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x55, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xcc, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x18, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x6a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x3f, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {}
+};
+static const struct usb_action cs2102_50HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */
+ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
+ {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */
+ {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
+ {0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
+ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
+ {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */
+ {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
+ {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
+ {}
+};
+static const struct usb_action cs2102_50HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */
+ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
+ {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */
+ {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
+ {0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
+ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
+ {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
+ {0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */
+ {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */
+ {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */
+ {}
+};
+static const struct usb_action cs2102_60HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */
+ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
+ {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */
+ {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
+ {0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
+ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
+ {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
+ {0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */
+ {}
+};
+static const struct usb_action cs2102_60HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */
+ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
+ {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */
+ {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
+ {0xaa, 0x11, 0x00be}, /* 00,11,be,aa */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
+ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
+ {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
+ {0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */
+ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
+ {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
+ {}
+};
+static const struct usb_action cs2102_NoFliker[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */
+ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
+ {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */
+ {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
+ {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
+ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
+ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+ {}
+};
+static const struct usb_action cs2102_NoFlikerScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */
+ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */
+ {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */
+ {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */
+ {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */
+ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */
+ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+ {}
+};
+
+/* CS2102_KOCOM */
+static const struct usb_action cs2102K_Initial[] = {
+ {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x01, 0x01b1},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x4c, ZC3XX_R118_BGAIN},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x4c, ZC3XX_R118_BGAIN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {}
+};
+
+static const struct usb_action cs2102K_InitialScale[] = {
+ {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x01, 0x01b1},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x4c, ZC3XX_R118_BGAIN},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x4c, ZC3XX_R118_BGAIN},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x01, 0x01b1},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x4c, ZC3XX_R118_BGAIN},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x4c, ZC3XX_R118_BGAIN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {}
+};
+
+static const struct usb_action gc0305_Initial[] = { /* 640x480 */
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */
+ {0xaa, 0x13, 0x0002}, /* 00,13,02,aa */
+ {0xaa, 0x15, 0x0003}, /* 00,15,03,aa */
+ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
+ {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */
+ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
+ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */
+ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
+ {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */
+ {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */
+ {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */
+ {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */
+ {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */
+ {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
+ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */
+ {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */
+ {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */
+ {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */
+ {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */
+ {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
+ {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */
+ {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */
+ {0xaa, 0x17, 0x00e6}, /* 00,17,e6,aa */
+ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */
+ {0xaa, 0x19, 0x0086}, /* 00,19,86,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */
+ {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
+ {0xa0, 0x85, ZC3XX_R18D_YTARGET}, /* 01,8d,85,cc */
+ {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */
+ {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */
+ {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */
+ {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
+ {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */
+ {}
+};
+static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */
+ {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */
+ {0xaa, 0x15, 0x0001}, /* 00,15,01,aa */
+ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
+ {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */
+ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
+ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */
+ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */
+ {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */
+ {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */
+ {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */
+ {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */
+ {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */
+ {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
+ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */
+ {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */
+ {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */
+ {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */
+ {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */
+ {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
+ {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */
+ {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */
+ {0xaa, 0x17, 0x00e8}, /* 00,17,e8,aa */
+ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */
+ {0xaa, 0x19, 0x0088}, /* 00,19,88,aa */
+ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */
+ {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */
+ {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
+ {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */
+ {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */
+ {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */
+ {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
+ {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */
+ {}
+};
+static const struct usb_action gc0305_50HZ[] = {
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */
+ {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */
+ {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
+ /* win: 01,92,10 */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc */
+ /* win: 01,97,ec */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
+/* {0xa0, 0x85, ZC3XX_R18D_YTARGET}, * 01,8d,85,cc *
+ * if 640x480 */
+ {}
+};
+static const struct usb_action gc0305_60HZ[] = {
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
+ {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */
+ {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0xec, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,ec,cc */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
+ {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */
+ {}
+};
+
+static const struct usb_action gc0305_NoFliker[] = {
+ {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
+ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,00,cc */
+ {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,48,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */
+ {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */
+ {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */
+ {}
+};
+
+/* play poker with registers at your own risk !! */
+static const struct usb_action hdcs2020xx_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ /* D0 ?? E0 did not start */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
+ {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xaa, 0x02, 0x0002},
+ {0xaa, 0x07, 0x0006},
+ {0xaa, 0x08, 0x0002},
+ {0xaa, 0x09, 0x0006},
+ {0xaa, 0x0a, 0x0001},
+ {0xaa, 0x0b, 0x0001},
+ {0xaa, 0x0c, 0x0008},
+ {0xaa, 0x0d, 0x0000},
+ {0xaa, 0x10, 0x0000},
+ {0xaa, 0x12, 0x0005},
+ {0xaa, 0x13, 0x0063},
+ {0xaa, 0x15, 0x0070},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4 */
+ {0xa0, 0x37, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x58, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x91, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa6, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb8, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc7, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd3, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xde, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xed, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x23, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+
+ {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf5, ZC3XX_R10B_RGB01},
+ {0xa0, 0xff, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf9, ZC3XX_R10D_RGB10},
+ {0xa0, 0x51, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf5, ZC3XX_R10F_RGB12},
+ {0xa0, 0xfb, ZC3XX_R110_RGB20},
+ {0xa0, 0xed, ZC3XX_R111_RGB21},
+ {0xa0, 0x5f, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
+ {0xaa, 0x20, 0x0004},
+ {0xaa, 0x21, 0x003d},
+ {0xaa, 0x03, 0x0041},
+ {0xaa, 0x04, 0x0010},
+ {0xaa, 0x05, 0x003d},
+ {0xaa, 0x0e, 0x0001},
+ {0xaa, 0x0f, 0x0000},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x41, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xad, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0195},
+ {0xa1, 0x01, 0x0196},
+ {0xa1, 0x01, 0x0197},
+ {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x1d, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x85, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0116},
+ {0xa1, 0x01, 0x0118},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x1d, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x85, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0116},
+ {0xa1, 0x01, 0x0118},
+/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {0xa0, 0x00, 0x0007},
+ {}
+};
+
+static const struct usb_action hdcs2020xx_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
+ {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
+ {0xaa, 0x02, 0x0002},
+ {0xaa, 0x07, 0x0006},
+ {0xaa, 0x08, 0x0002},
+ {0xaa, 0x09, 0x0006},
+ {0xaa, 0x0a, 0x0001},
+ {0xaa, 0x0b, 0x0001},
+ {0xaa, 0x0c, 0x0008},
+ {0xaa, 0x0d, 0x0000},
+ {0xaa, 0x10, 0x0000},
+ {0xaa, 0x12, 0x0005},
+ {0xaa, 0x13, 0x0063},
+ {0xaa, 0x15, 0x0070},
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4*/
+ {0xa0, 0x37, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x58, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x91, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa6, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb8, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc7, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd3, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xde, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xed, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x23, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xff, ZC3XX_R10B_RGB01},
+ {0xa0, 0xff, ZC3XX_R10C_RGB02},
+ {0xa0, 0xff, ZC3XX_R10D_RGB10},
+ {0xa0, 0x60, ZC3XX_R10E_RGB11},
+ {0xa0, 0xff, ZC3XX_R10F_RGB12},
+ {0xa0, 0xff, ZC3XX_R110_RGB20},
+ {0xa0, 0xff, ZC3XX_R111_RGB21},
+ {0xa0, 0x60, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
+ {0xaa, 0x20, 0x0002},
+ {0xaa, 0x21, 0x001b},
+ {0xaa, 0x03, 0x0044},
+ {0xaa, 0x04, 0x0008},
+ {0xaa, 0x05, 0x001b},
+ {0xaa, 0x0e, 0x0001},
+ {0xaa, 0x0f, 0x0000},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x44, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xad, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xeb, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0195},
+ {0xa1, 0x01, 0x0196},
+ {0xa1, 0x01, 0x0197},
+ {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x1d, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x99, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0116},
+ {0xa1, 0x01, 0x0118},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x1d, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x99, ZC3XX_R118_BGAIN},
+/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {0xa0, 0x00, 0x0007},
+/* {0xa0, 0x18, 0x00fe}, */
+ {}
+};
+static const struct usb_action hdcs2020xb_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */
+ {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xaa, 0x1c, 0x0000},
+ {0xaa, 0x0a, 0x0001},
+ {0xaa, 0x0b, 0x0006},
+ {0xaa, 0x0c, 0x007b},
+ {0xaa, 0x0d, 0x00a7},
+ {0xaa, 0x03, 0x00fb},
+ {0xaa, 0x05, 0x0000},
+ {0xaa, 0x06, 0x0003},
+ {0xaa, 0x09, 0x0008},
+
+ {0xaa, 0x0f, 0x0018}, /* set sensor gain */
+ {0xaa, 0x10, 0x0018},
+ {0xaa, 0x11, 0x0018},
+ {0xaa, 0x12, 0x0018},
+
+ {0xaa, 0x15, 0x004e},
+ {0xaa, 0x1c, 0x0004},
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+
+ {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xed, ZC3XX_R10B_RGB01},
+ {0xa0, 0xed, ZC3XX_R10C_RGB02},
+ {0xa0, 0xed, ZC3XX_R10D_RGB10},
+ {0xa0, 0x66, ZC3XX_R10E_RGB11},
+ {0xa0, 0xed, ZC3XX_R10F_RGB12},
+ {0xa0, 0xed, ZC3XX_R110_RGB20},
+ {0xa0, 0xed, ZC3XX_R111_RGB21},
+ {0xa0, 0x66, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x13, 0x0031},
+ {0xaa, 0x14, 0x0001},
+ {0xaa, 0x0e, 0x0004},
+ {0xaa, 0x19, 0x00cd},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 0x14 */
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x18, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x41, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {}
+};
+static const struct usb_action hdcs2020xb_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xaa, 0x1c, 0x0000},
+ {0xaa, 0x0a, 0x0001},
+ {0xaa, 0x0b, 0x0006},
+ {0xaa, 0x0c, 0x007a},
+ {0xaa, 0x0d, 0x00a7},
+ {0xaa, 0x03, 0x00fb},
+ {0xaa, 0x05, 0x0000},
+ {0xaa, 0x06, 0x0003},
+ {0xaa, 0x09, 0x0008},
+ {0xaa, 0x0f, 0x0018}, /* original setting */
+ {0xaa, 0x10, 0x0018},
+ {0xaa, 0x11, 0x0018},
+ {0xaa, 0x12, 0x0018},
+ {0xaa, 0x15, 0x004e},
+ {0xaa, 0x1c, 0x0004},
+ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xed, ZC3XX_R10B_RGB01},
+ {0xa0, 0xed, ZC3XX_R10C_RGB02},
+ {0xa0, 0xed, ZC3XX_R10D_RGB10},
+ {0xa0, 0x66, ZC3XX_R10E_RGB11},
+ {0xa0, 0xed, ZC3XX_R10F_RGB12},
+ {0xa0, 0xed, ZC3XX_R110_RGB20},
+ {0xa0, 0xed, ZC3XX_R111_RGB21},
+ {0xa0, 0x66, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ /**** set exposure ***/
+ {0xaa, 0x13, 0x0031},
+ {0xaa, 0x14, 0x0001},
+ {0xaa, 0x0e, 0x0004},
+ {0xaa, 0x19, 0x00cd},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x18, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x41, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {}
+};
+static const struct usb_action hdcs2020b_50HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
+ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
+ {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */
+ {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
+ {0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */
+ {0xa0, 0x05, ZC3XX_R01D_HSYNC_0}, /* 00,1d,05,cc */
+ {0xa0, 0x1a, ZC3XX_R01E_HSYNC_1}, /* 00,1e,1a,cc */
+ {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */
+ {}
+};
+static const struct usb_action hdcs2020b_60HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
+ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
+ {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
+ {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
+ {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */
+ {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, /* 00,1e,18,cc */
+ {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */
+ {}
+};
+static const struct usb_action hdcs2020b_NoFliker[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
+ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
+ {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */
+ {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
+ {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */
+ {0xa0, 0x17, ZC3XX_R01E_HSYNC_1}, /* 00,1e,17,cc */
+ {0xa0, 0x2a, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2a,cc */
+ {}
+};
+
+static const struct usb_action hv7131bxx_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xaa, 0x30, 0x002d},
+ {0xaa, 0x01, 0x0005},
+ {0xaa, 0x11, 0x0000},
+ {0xaa, 0x13, 0x0001}, /* {0xaa, 0x13, 0x0000}, */
+ {0xaa, 0x14, 0x0001},
+ {0xaa, 0x15, 0x00e8},
+ {0xaa, 0x16, 0x0002},
+ {0xaa, 0x17, 0x0086},
+ {0xaa, 0x31, 0x0038},
+ {0xaa, 0x32, 0x0038},
+ {0xaa, 0x33, 0x0038},
+ {0xaa, 0x5b, 0x0001},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x68, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0xc0, 0x019b},
+ {0xa0, 0xa0, 0x019c},
+ {0xa0, 0x02, ZC3XX_R188_MINGAIN},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xa1, 0x01, 0x0095},
+ {0xa1, 0x01, 0x0096},
+
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x25, 0x0007},
+ {0xaa, 0x26, 0x00a1},
+ {0xaa, 0x27, 0x0020},
+ {0xaa, 0x20, 0x0000},
+ {0xaa, 0x21, 0x00a0},
+ {0xaa, 0x22, 0x0016},
+ {0xaa, 0x23, 0x0040},
+
+ {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
+ {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x07, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x16, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x40, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa1, 0x01, 0x001d},
+ {0xa1, 0x01, 0x001e},
+ {0xa1, 0x01, 0x001f},
+ {0xa1, 0x01, 0x0020},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {}
+};
+
+static const struct usb_action hv7131bxx_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xaa, 0x30, 0x002d},
+ {0xaa, 0x01, 0x0005},
+ {0xaa, 0x11, 0x0001},
+ {0xaa, 0x13, 0x0000}, /* {0xaa, 0x13, 0x0001}; */
+ {0xaa, 0x14, 0x0001},
+ {0xaa, 0x15, 0x00e6},
+ {0xaa, 0x16, 0x0002},
+ {0xaa, 0x17, 0x0086},
+ {0xaa, 0x31, 0x0038},
+ {0xaa, 0x32, 0x0038},
+ {0xaa, 0x33, 0x0038},
+ {0xaa, 0x5b, 0x0001},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x70, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0xc0, 0x019b},
+ {0xa0, 0xa0, 0x019c},
+ {0xa0, 0x02, ZC3XX_R188_MINGAIN},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xa1, 0x01, 0x0095},
+ {0xa1, 0x01, 0x0096},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x25, 0x0007},
+ {0xaa, 0x26, 0x00a1},
+ {0xaa, 0x27, 0x0020},
+ {0xaa, 0x20, 0x0000},
+ {0xaa, 0x21, 0x0040},
+ {0xaa, 0x22, 0x0013},
+ {0xaa, 0x23, 0x004c},
+ {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */
+ {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x00, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x40, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0x13, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0x4c, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa1, 0x01, 0x001d},
+ {0xa1, 0x01, 0x001e},
+ {0xa1, 0x01, 0x001f},
+ {0xa1, 0x01, 0x0020},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */
+ {}
+};
+
+static const struct usb_action hv7131cxx_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xaa, 0x01, 0x000c},
+ {0xaa, 0x11, 0x0000},
+ {0xaa, 0x13, 0x0000},
+ {0xaa, 0x14, 0x0001},
+ {0xaa, 0x15, 0x00e8},
+ {0xaa, 0x16, 0x0002},
+ {0xaa, 0x17, 0x0088},
+
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x89, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0xc0, 0x019b},
+ {0xa0, 0xa0, 0x019c},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xa1, 0x01, 0x0095},
+ {0xa1, 0x01, 0x0096},
+
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf0, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf0, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf0, ZC3XX_R10D_RGB10},
+ {0xa0, 0x60, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf0, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf0, ZC3XX_R110_RGB20},
+ {0xa0, 0xf0, ZC3XX_R111_RGB21},
+ {0xa0, 0x60, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x25, 0x0007},
+ {0xaa, 0x26, 0x0053},
+ {0xaa, 0x27, 0x0000},
+
+ {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 9b */
+ {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 80 */
+ {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x13, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa1, 0x01, 0x001d},
+ {0xa1, 0x01, 0x001e},
+ {0xa1, 0x01, 0x001f},
+ {0xa1, 0x01, 0x0020},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+
+static const struct usb_action hv7131cxx_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 1e0 */
+
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xaa, 0x01, 0x000c},
+ {0xaa, 0x11, 0x0000},
+ {0xaa, 0x13, 0x0000},
+ {0xaa, 0x14, 0x0001},
+ {0xaa, 0x15, 0x00e8},
+ {0xaa, 0x16, 0x0002},
+ {0xaa, 0x17, 0x0088},
+
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00 */
+
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x89, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0xc0, 0x019b},
+ {0xa0, 0xa0, 0x019c},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
+ /* read the i2c chips ident */
+ {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xa1, 0x01, 0x0095},
+ {0xa1, 0x01, 0x0096},
+
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf0, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf0, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf0, ZC3XX_R10D_RGB10},
+ {0xa0, 0x60, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf0, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf0, ZC3XX_R110_RGB20},
+ {0xa0, 0xf0, ZC3XX_R111_RGB21},
+ {0xa0, 0x60, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x25, 0x0007},
+ {0xaa, 0x26, 0x0053},
+ {0xaa, 0x27, 0x0000},
+
+ {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 9b */
+ {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 80 */
+
+ {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW},
+
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x13, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa1, 0x01, 0x001d},
+ {0xa1, 0x01, 0x001e},
+ {0xa1, 0x01, 0x001f},
+ {0xa1, 0x01, 0x0020},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+
+static const struct usb_action icm105axx_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH},
+ {0xa0, 0x01, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH},
+ {0xa0, 0x01, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x01, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x01, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xaa, 0x01, 0x0010},
+ {0xaa, 0x03, 0x0000},
+ {0xaa, 0x04, 0x0001},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0001},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0001},
+ {0xaa, 0x04, 0x0011},
+ {0xaa, 0x05, 0x00a0},
+ {0xaa, 0x06, 0x0001},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0002},
+ {0xaa, 0x04, 0x0013},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0001},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0003},
+ {0xaa, 0x04, 0x0015},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0004},
+ {0xaa, 0x04, 0x0017},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x000d},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0005},
+ {0xaa, 0x04, 0x0019},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0006},
+ {0xaa, 0x04, 0x0017},
+ {0xaa, 0x05, 0x0026},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0007},
+ {0xaa, 0x04, 0x0019},
+ {0xaa, 0x05, 0x0022},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0008},
+ {0xaa, 0x04, 0x0021},
+ {0xaa, 0x05, 0x00aa},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0009},
+ {0xaa, 0x04, 0x0023},
+ {0xaa, 0x05, 0x00aa},
+ {0xaa, 0x06, 0x000d},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x000a},
+ {0xaa, 0x04, 0x0025},
+ {0xaa, 0x05, 0x00aa},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x000b},
+ {0xaa, 0x04, 0x00ec},
+ {0xaa, 0x05, 0x002e},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x000c},
+ {0xaa, 0x04, 0x00fa},
+ {0xaa, 0x05, 0x002a},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x07, 0x000d},
+ {0xaa, 0x01, 0x0005},
+ {0xaa, 0x94, 0x0002},
+ {0xaa, 0x90, 0x0000},
+ {0xaa, 0x91, 0x001f},
+ {0xaa, 0x10, 0x0064},
+ {0xaa, 0x9b, 0x00f0},
+ {0xaa, 0x9c, 0x0002},
+ {0xaa, 0x14, 0x001a},
+ {0xaa, 0x20, 0x0080},
+ {0xaa, 0x22, 0x0080},
+ {0xaa, 0x24, 0x0080},
+ {0xaa, 0x26, 0x0080},
+ {0xaa, 0x00, 0x0084},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xaa, 0xa8, 0x00c0},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0008},
+
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf7, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf7, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf7, ZC3XX_R10D_RGB10},
+ {0xa0, 0x52, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf7, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf7, ZC3XX_R110_RGB20},
+ {0xa0, 0xf7, ZC3XX_R111_RGB21},
+ {0xa0, 0x52, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x0d, 0x0003},
+ {0xaa, 0x0c, 0x008c},
+ {0xaa, 0x0e, 0x0095},
+ {0xaa, 0x0f, 0x0002},
+ {0xaa, 0x1c, 0x0094},
+ {0xaa, 0x1d, 0x0002},
+ {0xaa, 0x20, 0x0080},
+ {0xaa, 0x22, 0x0080},
+ {0xaa, 0x24, 0x0080},
+ {0xaa, 0x26, 0x0080},
+ {0xaa, 0x00, 0x0084},
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xec, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0xc0, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {}
+};
+
+static const struct usb_action icm105axx_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH},
+ {0xa0, 0x02, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH},
+ {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x02, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
+ {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xaa, 0x01, 0x0010},
+ {0xaa, 0x03, 0x0000},
+ {0xaa, 0x04, 0x0001},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0001},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0001},
+ {0xaa, 0x04, 0x0011},
+ {0xaa, 0x05, 0x00a0},
+ {0xaa, 0x06, 0x0001},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0002},
+ {0xaa, 0x04, 0x0013},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0001},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0003},
+ {0xaa, 0x04, 0x0015},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0004},
+ {0xaa, 0x04, 0x0017},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x000d},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0005},
+ {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x19, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xaa, 0x05, 0x0020},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0006},
+ {0xaa, 0x04, 0x0017},
+ {0xaa, 0x05, 0x0026},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0007},
+ {0xaa, 0x04, 0x0019},
+ {0xaa, 0x05, 0x0022},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0008},
+ {0xaa, 0x04, 0x0021},
+ {0xaa, 0x05, 0x00aa},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x0009},
+ {0xaa, 0x04, 0x0023},
+ {0xaa, 0x05, 0x00aa},
+ {0xaa, 0x06, 0x000d},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x000a},
+ {0xaa, 0x04, 0x0025},
+ {0xaa, 0x05, 0x00aa},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x000b},
+ {0xaa, 0x04, 0x00ec},
+ {0xaa, 0x05, 0x002e},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x03, 0x000c},
+ {0xaa, 0x04, 0x00fa},
+ {0xaa, 0x05, 0x002a},
+ {0xaa, 0x06, 0x0005},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x07, 0x000d},
+ {0xaa, 0x01, 0x0005},
+ {0xaa, 0x94, 0x0002},
+ {0xaa, 0x90, 0x0000},
+ {0xaa, 0x91, 0x0010},
+ {0xaa, 0x10, 0x0064},
+ {0xaa, 0x9b, 0x00f0},
+ {0xaa, 0x9c, 0x0002},
+ {0xaa, 0x14, 0x001a},
+ {0xaa, 0x20, 0x0080},
+ {0xaa, 0x22, 0x0080},
+ {0xaa, 0x24, 0x0080},
+ {0xaa, 0x26, 0x0080},
+ {0xaa, 0x00, 0x0084},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xaa, 0xa8, 0x0080},
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {0xa1, 0x01, 0x0008},
+
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf7, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf7, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf7, ZC3XX_R10D_RGB10},
+ {0xa0, 0x52, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf7, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf7, ZC3XX_R110_RGB20},
+ {0xa0, 0xf7, ZC3XX_R111_RGB21},
+ {0xa0, 0x52, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x0d, 0x0003},
+ {0xaa, 0x0c, 0x0020},
+ {0xaa, 0x0e, 0x000e},
+ {0xaa, 0x0f, 0x0002},
+ {0xaa, 0x1c, 0x000d},
+ {0xaa, 0x1d, 0x0002},
+ {0xaa, 0x20, 0x0080},
+ {0xaa, 0x22, 0x0080},
+ {0xaa, 0x24, 0x0080},
+ {0xaa, 0x26, 0x0080},
+ {0xaa, 0x00, 0x0084},
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R116_RGAIN},
+ {0xa0, 0x40, ZC3XX_R117_GGAIN},
+ {0xa0, 0x40, ZC3XX_R118_BGAIN},
+ {}
+};
+static const struct usb_action icm105a_50HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
+ {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */
+ {0xaa, 0x0e, 0x000e}, /* 00,0e,0e,aa */
+ {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
+ {0xaa, 0x1c, 0x000d}, /* 00,1c,0d,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
+ {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
+ {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
+ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
+ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
+ {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,0d,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,1a,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4b,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
+ {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
+ {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d8,cc */
+ {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {}
+};
+static const struct usb_action icm105a_50HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
+ {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */
+ {0xaa, 0x0e, 0x0095}, /* 00,0e,95,aa */
+ {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
+ {0xaa, 0x1c, 0x0094}, /* 00,1c,94,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
+ {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
+ {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
+ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
+ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
+ {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,94,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,84,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
+ {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e3,cc */
+ {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, /* 00,1e,ec,cc */
+ {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f5,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */
+ {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
+ {}
+};
+static const struct usb_action icm105a_60HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
+ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
+ {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */
+ {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
+ {0xaa, 0x1c, 0x0008}, /* 00,1c,08,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
+ {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
+ {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
+ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
+ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
+ {0xa0, 0x08, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,08,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x41, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,41,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
+ {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */
+ {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */
+ {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {}
+};
+static const struct usb_action icm105a_60HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
+ {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */
+ {0xaa, 0x0e, 0x0086}, /* 00,0e,86,aa */
+ {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
+ {0xaa, 0x1c, 0x0085}, /* 00,1c,85,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
+ {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
+ {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
+ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
+ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
+ {0xa0, 0x85, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,85,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,08,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */
+ {0xa0, 0xc2, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c2,cc */
+ {0xa0, 0xd6, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d6,cc */
+ {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */
+ {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
+ {}
+};
+static const struct usb_action icm105a_NoFliker[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
+ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
+ {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */
+ {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
+ {0xaa, 0x1c, 0x0000}, /* 00,1c,00,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
+ {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
+ {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
+ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
+ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
+ {0xa0, 0x00, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,00,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */
+ {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */
+ {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {}
+};
+static const struct usb_action icm105a_NoFlikerScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */
+ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */
+ {0xaa, 0x0e, 0x0081}, /* 00,0e,81,aa */
+ {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */
+ {0xaa, 0x1c, 0x0080}, /* 00,1c,80,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */
+ {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */
+ {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */
+ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */
+ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */
+ {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */
+ {0xa0, 0x80, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,80,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */
+ {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */
+ {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */
+ {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */
+ {}
+};
+
+static const struct usb_action MC501CB_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
+ {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */
+ {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */
+ {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */
+ {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
+ {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */
+ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
+ {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
+ {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
+ {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */
+ {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */
+ {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
+ {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */
+ {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */
+ {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */
+ {0xaa, 0x18, 0x00de}, /* 00,18,de,aa */
+ {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
+ {0xaa, 0x1a, 0x0086}, /* 00,1a,86,aa */
+ {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */
+ {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
+ {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */
+ {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */
+ {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */
+ {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */
+ {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */
+ {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */
+ {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */
+ {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */
+ {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */
+ {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */
+ {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */
+ {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */
+ {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */
+ {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */
+ {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */
+ {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
+ {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
+ {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
+ {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */
+ {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
+ {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
+ {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
+ {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */
+ {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */
+ {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */
+ {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */
+ {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */
+ {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */
+ {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */
+ {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */
+ {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */
+ {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */
+ {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */
+ {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */
+ {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */
+ {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */
+ {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
+ {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */
+ {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */
+ {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x1c, 0x0050}, /* 00,1C,50,aa */
+ {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */
+ {0xaa, 0x3b, 0x001d}, /* 00,3b,1D,aa */
+ {0xaa, 0x3c, 0x004c}, /* 00,3c,4C,aa */
+ {0xaa, 0x3d, 0x0018}, /* 00,3d,18,aa */
+ {0xaa, 0x3e, 0x006a}, /* 00,3e,6A,aa */
+ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
+ {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */
+ {0xaa, 0x51, 0x0027}, /* 00,51,27,aa */
+ {0xaa, 0x52, 0x0020}, /* 00,52,20,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */
+ {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */
+ {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */
+ {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
+ {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
+ {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
+
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
+ {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
+ {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_Initial[] = { /* 320x240 */
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */
+ {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */
+ {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */
+ {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
+ {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */
+ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */
+ {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
+ {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */
+ {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */
+ {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */
+ {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
+ {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */
+ {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */
+ {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */
+ {0xaa, 0x18, 0x00d8}, /* 00,18,d8,aa */
+ {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
+ {0xaa, 0x1a, 0x0088}, /* 00,1a,88,aa */
+ {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */
+ {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */
+ {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */
+ {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */
+ {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */
+ {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */
+ {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */
+ {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */
+ {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */
+ {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */
+ {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */
+ {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */
+ {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */
+ {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */
+ {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */
+ {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */
+ {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */
+ {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
+ {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
+ {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
+ {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */
+ {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
+ {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
+ {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
+ {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */
+ {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */
+ {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */
+ {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */
+ {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */
+ {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */
+ {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */
+ {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */
+ {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */
+ {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */
+ {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */
+ {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */
+ {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */
+ {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */
+ {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */
+ {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */
+ {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */
+ {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x1c, 0x0050}, /* 00,1c,50,aa */
+ {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */
+ {0xaa, 0x3b, 0x003a}, /* 00,3b,3A,aa */
+ {0xaa, 0x3c, 0x0098}, /* 00,3c,98,aa */
+ {0xaa, 0x3d, 0x0030}, /* 00,3d,30,aa */
+ {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
+ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */
+ {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */
+ {0xaa, 0x51, 0x004e}, /* 00,51,4E,aa */
+ {0xaa, 0x52, 0x0041}, /* 00,52,41,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */
+ {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */
+ {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */
+ {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
+ {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
+ {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
+ {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
+ {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_50HZ[] = {
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
+ {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
+ {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
+ {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */
+ {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */
+ {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
+ {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */
+ {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_50HZScale[] = {
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
+ {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */
+ {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */
+ {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */
+ {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */
+ {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
+ {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
+ {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_60HZ[] = {
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
+ {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
+ {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
+ {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
+ {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
+ {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
+ {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
+ {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_60HZScale[] = {
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
+ {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
+ {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
+ {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
+ {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
+ {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
+ {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
+ {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_NoFliker[] = {
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
+ {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
+ {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
+ {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
+ {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
+ {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
+ {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
+ {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
+ {}
+};
+
+static const struct usb_action MC501CB_NoFlikerScale[] = {
+ {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
+ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
+ {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
+ {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
+ {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
+ {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
+ {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
+ {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
+ {}
+};
+
+/* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */
+static const struct usb_action OV7620_mode0[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */
+ {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */
+ {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */
+ {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */
+ {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */
+ {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */
+ {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */
+ {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */
+ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
+ {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
+ {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */
+ {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
+ {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
+ {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
+ {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */
+ {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */
+ {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
+ {0xaa, 0x1a, 0x00f1}, /* 00,1a,f1,aa */
+ {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */
+ {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */
+ {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */
+ {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */
+ {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */
+ {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
+ {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */
+ {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
+ {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
+ {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */
+ {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */
+ {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */
+ {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */
+ {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */
+ {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */
+ {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */
+ {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
+ {0xa0, 0x40, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,40,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
+ {}
+};
+
+/* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */
+static const struct usb_action OV7620_mode1[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */
+ /* mx change? */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */
+ {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */
+ {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */
+ {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */
+ {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */
+ {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */
+ {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xd6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d6,cc */
+ /* OV7648 00,9c,d8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */
+ {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */
+ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
+ {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
+ {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */
+ {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */
+ {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */
+ {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
+ {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */
+ {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */
+ {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */
+ {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */
+ {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */
+ {0xaa, 0x1a, 0x00f2}, /* 00,1a,f2,aa */
+ {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */
+ {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */
+ {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */
+ {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
+ {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */
+ {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
+ {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
+ {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */
+ {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */
+ {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */
+ {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */
+ {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */
+ {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */
+ {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */
+ {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */
+ {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,50,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */
+ {}
+};
+
+/* from zs211.inf - HKR,%OV7620%\AE,50HZ */
+static const struct usb_action OV7620_50HZ[] = {
+ {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */
+ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
+ {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
+ {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */
+ {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */
+/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc
+ if mode0 (640x480) */
+ {}
+};
+
+/* from zs211.inf - HKR,%OV7620%\AE,60HZ */
+static const struct usb_action OV7620_60HZ[] = {
+ {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
+ /* (bug in zs211.inf) */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */
+ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */
+ {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */
+ {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */
+ {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */
+/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc
+ * if mode0 (640x480) */
+/* ?? in gspca v1, it was
+ {0xa0, 0x00, 0x0039}, * 00,00,00,dd *
+ {0xa1, 0x01, 0x0037}, */
+ {}
+};
+
+/* from zs211.inf - HKR,%OV7620%\AE,NoFliker */
+static const struct usb_action OV7620_NoFliker[] = {
+ {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */
+ /* (bug in zs211.inf) */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */
+ {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */
+ {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */
+ {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,01,cc */
+/* {0xa0, 0x44, ZC3XX_R002_CLOCKSELECT}, * 00,02,44,cc
+ - if mode1 (320x240) */
+/* ?? was
+ {0xa0, 0x00, 0x0039}, * 00,00,00,dd *
+ {0xa1, 0x01, 0x0037}, */
+ {}
+};
+
+static const struct usb_action ov7630c_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xaa, 0x12, 0x0080},
+ {0xa0, 0x02, ZC3XX_R083_RGAINADDR},
+ {0xa0, 0x01, ZC3XX_R085_BGAINADDR},
+ {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH},
+ {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xaa, 0x12, 0x0069},
+ {0xaa, 0x04, 0x0020},
+ {0xaa, 0x06, 0x0050},
+ {0xaa, 0x13, 0x0083},
+ {0xaa, 0x14, 0x0000},
+ {0xaa, 0x15, 0x0024},
+ {0xaa, 0x17, 0x0018},
+ {0xaa, 0x18, 0x00ba},
+ {0xaa, 0x19, 0x0002},
+ {0xaa, 0x1a, 0x00f6},
+ {0xaa, 0x1b, 0x0002},
+ {0xaa, 0x20, 0x00c2},
+ {0xaa, 0x24, 0x0060},
+ {0xaa, 0x25, 0x0040},
+ {0xaa, 0x26, 0x0030},
+ {0xaa, 0x27, 0x00ea},
+ {0xaa, 0x28, 0x00a0},
+ {0xaa, 0x21, 0x0000},
+ {0xaa, 0x2a, 0x0081},
+ {0xaa, 0x2b, 0x0096},
+ {0xaa, 0x2d, 0x0094},
+ {0xaa, 0x2f, 0x003d},
+ {0xaa, 0x30, 0x0024},
+ {0xaa, 0x60, 0x0000},
+ {0xaa, 0x61, 0x0040},
+ {0xaa, 0x68, 0x007c},
+ {0xaa, 0x6f, 0x0015},
+ {0xaa, 0x75, 0x0088},
+ {0xaa, 0x77, 0x00b5},
+ {0xaa, 0x01, 0x0060},
+ {0xaa, 0x02, 0x0060},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x46, ZC3XX_R118_BGAIN},
+ {0xa0, 0x04, ZC3XX_R113_RGB03},
+/* 0x10, */
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+/* 0x03, */
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x01, ZC3XX_R120_GAMMA00}, /* gamma 2 ?*/
+ {0xa0, 0x0c, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x1f, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x3a, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x53, ZC3XX_R124_GAMMA04},
+ {0xa0, 0x6d, ZC3XX_R125_GAMMA05},
+ {0xa0, 0x85, ZC3XX_R126_GAMMA06},
+ {0xa0, 0x9c, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xb0, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xc2, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xd1, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xde, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xe9, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf2, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xf9, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x05, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x0f, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x16, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1a, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x19, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x19, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x17, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x15, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x12, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x10, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x0e, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x0b, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x09, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x08, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x06, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x03, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xaa, 0x10, 0x001b},
+ {0xaa, 0x76, 0x0002},
+ {0xaa, 0x2a, 0x0081},
+ {0xaa, 0x2b, 0x0000},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xb8, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x37, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xaa, 0x13, 0x0083}, /* 40 */
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+
+static const struct usb_action ov7630c_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+
+ {0xaa, 0x12, 0x0080},
+ {0xa0, 0x02, ZC3XX_R083_RGAINADDR},
+ {0xa0, 0x01, ZC3XX_R085_BGAINADDR},
+ {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH},
+ {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
+ {0xaa, 0x12, 0x0069}, /* i2c */
+ {0xaa, 0x04, 0x0020},
+ {0xaa, 0x06, 0x0050},
+ {0xaa, 0x13, 0x00c3},
+ {0xaa, 0x14, 0x0000},
+ {0xaa, 0x15, 0x0024},
+ {0xaa, 0x19, 0x0003},
+ {0xaa, 0x1a, 0x00f6},
+ {0xaa, 0x1b, 0x0002},
+ {0xaa, 0x20, 0x00c2},
+ {0xaa, 0x24, 0x0060},
+ {0xaa, 0x25, 0x0040},
+ {0xaa, 0x26, 0x0030},
+ {0xaa, 0x27, 0x00ea},
+ {0xaa, 0x28, 0x00a0},
+ {0xaa, 0x21, 0x0000},
+ {0xaa, 0x2a, 0x0081},
+ {0xaa, 0x2b, 0x0096},
+ {0xaa, 0x2d, 0x0084},
+ {0xaa, 0x2f, 0x003d},
+ {0xaa, 0x30, 0x0024},
+ {0xaa, 0x60, 0x0000},
+ {0xaa, 0x61, 0x0040},
+ {0xaa, 0x68, 0x007c},
+ {0xaa, 0x6f, 0x0015},
+ {0xaa, 0x75, 0x0088},
+ {0xaa, 0x77, 0x00b5},
+ {0xaa, 0x01, 0x0060},
+ {0xaa, 0x02, 0x0060},
+ {0xaa, 0x17, 0x0018},
+ {0xaa, 0x18, 0x00ba},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R116_RGAIN},
+ {0xa0, 0x46, ZC3XX_R118_BGAIN},
+ {0xa0, 0x04, ZC3XX_R113_RGB03},
+
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xfe, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf7, ZC3XX_R10D_RGB10},
+ {0xa0, 0x4d, ZC3XX_R10E_RGB11},
+ {0xa0, 0xfc, ZC3XX_R10F_RGB12},
+ {0xa0, 0x00, ZC3XX_R110_RGB20},
+ {0xa0, 0xf6, ZC3XX_R111_RGB21},
+ {0xa0, 0x4a, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x16, ZC3XX_R120_GAMMA00}, /* gamma ~4 */
+ {0xa0, 0x3a, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x5b, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x7c, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x94, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa9, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xbb, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xca, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd7, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xe1, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xea, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xf1, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf7, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xfc, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x20, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xfe, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf7, ZC3XX_R10D_RGB10},
+ {0xa0, 0x4d, ZC3XX_R10E_RGB11},
+ {0xa0, 0xfc, ZC3XX_R10F_RGB12},
+ {0xa0, 0x00, ZC3XX_R110_RGB20},
+ {0xa0, 0xf6, ZC3XX_R111_RGB21},
+ {0xa0, 0x4a, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xaa, 0x10, 0x000d},
+ {0xaa, 0x76, 0x0002},
+ {0xaa, 0x2a, 0x0081},
+ {0xaa, 0x2b, 0x0000},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xd8, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x1b, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xaa, 0x13, 0x00c3},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+
+static const struct usb_action pas106b_Initial_com[] = {
+/* Sream and Sensor specific */
+ {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */
+/* System */
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */
+/* Picture size */
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* ClockSelect */
+ {0xa0, 0x03, 0x003a},
+ {0xa0, 0x0c, 0x003b},
+ {0xa0, 0x04, 0x0038},
+ {}
+};
+
+static const struct usb_action pas106b_Initial[] = { /* 176x144 */
+/* JPEG control */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+/* Sream and Sensor specific */
+ {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */
+/* Picture size */
+ {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh 00 */
+ {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow B0 */
+ {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh 00 */
+ {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow 90 */
+/* System */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */
+/* Sream and Sensor specific */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+/* Sensor Interface */
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */
+/* Window inside sensor array */
+ {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */
+ {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */
+ {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */
+ {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */
+/* Init the sensor */
+ {0xaa, 0x02, 0x0004},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x09, 0x0005},
+ {0xaa, 0x0a, 0x0002},
+ {0xaa, 0x0b, 0x0002},
+ {0xaa, 0x0c, 0x0005},
+ {0xaa, 0x0d, 0x0000},
+ {0xaa, 0x0e, 0x0002},
+ {0xaa, 0x14, 0x0081},
+
+/* Other registors */
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */
+/* Frame retreiving */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */
+/* Gains */
+ {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */
+/* Unknown */
+ {0xa0, 0x00, 0x01ad},
+/* Sharpness */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */
+/* Other registors */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+/* Auto exposure and white balance */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+/*Dead pixels */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+/* EEPROM */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+/* JPEG control */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+/* Other registers */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+/* Auto exposure and white balance */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+/*Dead pixels */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+/* EEPROM */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+/* JPEG control */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+/* Auto correction */
+ {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */
+ {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */
+ {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */
+ {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */
+ {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */
+ {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+
+/* Auto exposure and white balance */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh */
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */
+ {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow */
+ {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze */
+/* sensor on */
+ {0xaa, 0x07, 0x00b1},
+ {0xaa, 0x05, 0x0003},
+ {0xaa, 0x04, 0x0001},
+ {0xaa, 0x03, 0x003b},
+/* Gains */
+ {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */
+ {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
+/* Auto correction */
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+/* Gains */
+ {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */
+ {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */
+ {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */
+ {}
+};
+
+static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */
+/* JPEG control */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+/* Sream and Sensor specific */
+ {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */
+/* Picture size */
+ {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh */
+ {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh */
+ {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow */
+/* System */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */
+/* Sream and Sensor specific */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */
+/* Sensor Interface */
+ {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */
+/* Window inside sensor array */
+ {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */
+ {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */
+ {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */
+ {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */
+/* Init the sensor */
+ {0xaa, 0x02, 0x0004},
+ {0xaa, 0x08, 0x0000},
+ {0xaa, 0x09, 0x0005},
+ {0xaa, 0x0a, 0x0002},
+ {0xaa, 0x0b, 0x0002},
+ {0xaa, 0x0c, 0x0005},
+ {0xaa, 0x0d, 0x0000},
+ {0xaa, 0x0e, 0x0002},
+ {0xaa, 0x14, 0x0081},
+
+/* Other registors */
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */
+/* Frame retreiving */
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */
+/* Gains */
+ {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */
+/* Unknown */
+ {0xa0, 0x00, 0x01ad},
+/* Sharpness */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */
+/* Other registors */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+/* Auto exposure and white balance */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+ {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* ????????? */
+/*Dead pixels */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+/* EEPROM */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+/* JPEG control */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+/* Other registers */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */
+/* Auto exposure and white balance */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */
+/*Dead pixels */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */
+/* EEPROM */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */
+/* JPEG control */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf4, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf4, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf4, ZC3XX_R10D_RGB10},
+ {0xa0, 0x58, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf4, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf4, ZC3XX_R110_RGB20},
+ {0xa0, 0xf4, ZC3XX_R111_RGB21},
+ {0xa0, 0x58, ZC3XX_R112_RGB22},
+/* Auto correction */
+ {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */
+ {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */
+ {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */
+ {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */
+ {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */
+ {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+
+/* Auto exposure and white balance */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh 0 */
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */
+ {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow 0xb1 */
+
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh 0x00 */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow 0x00 */
+ {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow 0x87 */
+
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze 0x10 0x0c */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze 0x30 0x18 */
+/* sensor on */
+ {0xaa, 0x07, 0x00b1},
+ {0xaa, 0x05, 0x0003},
+ {0xaa, 0x04, 0x0001},
+ {0xaa, 0x03, 0x003b},
+/* Gains */
+ {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */
+ {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */
+/* Auto correction */
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+ {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */
+/* Gains */
+ {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */
+ {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */
+ {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */
+
+ {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */
+ {0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */
+ {}
+};
+static const struct usb_action pas106b_50HZ[] = {
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
+ {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,54,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,87,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */
+ {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */
+ {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */
+ {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */
+ {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */
+ {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */
+ {}
+};
+static const struct usb_action pas106b_60HZ[] = {
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
+ {0xa0, 0x2e, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,2e,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x71, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,71,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */
+ {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */
+ {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */
+ {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */
+ {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */
+ {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */
+ {}
+};
+static const struct usb_action pas106b_NoFliker[] = {
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */
+ {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */
+ {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */
+ {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */
+ {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {}
+};
+
+static const struct usb_action pb03303x_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xaa, 0x01, 0x0001},
+ {0xaa, 0x06, 0x0000},
+ {0xaa, 0x08, 0x0483},
+ {0xaa, 0x01, 0x0004},
+ {0xaa, 0x08, 0x0006},
+ {0xaa, 0x02, 0x0011},
+ {0xaa, 0x03, 0x01e7},
+ {0xaa, 0x04, 0x0287},
+ {0xaa, 0x07, 0x3002},
+ {0xaa, 0x20, 0x1100},
+ {0xaa, 0x35, 0x0050},
+ {0xaa, 0x30, 0x0005},
+ {0xaa, 0x31, 0x0000},
+ {0xaa, 0x58, 0x0078},
+ {0xaa, 0x62, 0x0411},
+ {0xaa, 0x2b, 0x0028},
+ {0xaa, 0x2c, 0x0030},
+ {0xaa, 0x2d, 0x0030},
+ {0xaa, 0x2e, 0x0028},
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x61, ZC3XX_R116_RGAIN},
+ {0xa0, 0x65, ZC3XX_R118_BGAIN},
+
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x0d, 0x003a},
+ {0xa0, 0x02, 0x003b},
+ {0xa0, 0x00, 0x0038},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x05, 0x0009},
+ {0xaa, 0x09, 0x0134},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+
+static const struct usb_action pb03303x_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xaa, 0x01, 0x0001},
+ {0xaa, 0x06, 0x0000},
+ {0xaa, 0x08, 0x0483},
+ {0xaa, 0x01, 0x0004},
+ {0xaa, 0x08, 0x0006},
+ {0xaa, 0x02, 0x0011},
+ {0xaa, 0x03, 0x01e7},
+ {0xaa, 0x04, 0x0287},
+ {0xaa, 0x07, 0x3002},
+ {0xaa, 0x20, 0x1100},
+ {0xaa, 0x35, 0x0050},
+ {0xaa, 0x30, 0x0005},
+ {0xaa, 0x31, 0x0000},
+ {0xaa, 0x58, 0x0078},
+ {0xaa, 0x62, 0x0411},
+ {0xaa, 0x2b, 0x0028},
+ {0xaa, 0x2c, 0x0030},
+ {0xaa, 0x2d, 0x0030},
+ {0xaa, 0x2e, 0x0028},
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x61, ZC3XX_R116_RGAIN},
+ {0xa0, 0x65, ZC3XX_R118_BGAIN},
+
+ {0xa1, 0x01, 0x0002},
+
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+
+ {0xa0, 0x0d, 0x003a},
+ {0xa0, 0x02, 0x003b},
+ {0xa0, 0x00, 0x0038},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
+ {0xa0, 0x38, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x59, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x79, ZC3XX_R123_GAMMA03},
+ {0xa0, 0x92, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x26, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x22, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x20, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x16, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x13, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x10, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x05, 0x0009},
+ {0xaa, 0x09, 0x0134},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+static const struct usb_action pb0330xx_Initial[] = {
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xaa, 0x01, 0x0006},
+ {0xaa, 0x02, 0x0011},
+ {0xaa, 0x03, 0x01e7},
+ {0xaa, 0x04, 0x0287},
+ {0xaa, 0x06, 0x0003},
+ {0xaa, 0x07, 0x3002},
+ {0xaa, 0x20, 0x1100},
+ {0xaa, 0x2f, 0xf7b0},
+ {0xaa, 0x30, 0x0005},
+ {0xaa, 0x31, 0x0000},
+ {0xaa, 0x34, 0x0100},
+ {0xaa, 0x35, 0x0060},
+ {0xaa, 0x3d, 0x068f},
+ {0xaa, 0x40, 0x01e0},
+ {0xaa, 0x58, 0x0078},
+ {0xaa, 0x62, 0x0411},
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x6c, ZC3XX_R18D_YTARGET},
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xa1, 0x01, 0x0095},
+ {0xa1, 0x01, 0x0096},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x05, 0x0066},
+ {0xaa, 0x09, 0x02b2},
+ {0xaa, 0x10, 0x0002},
+
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0007},
+/* {0xa0, 0x30, 0x0007}, */
+/* {0xa0, 0x00, 0x0007}, */
+ {}
+};
+
+static const struct usb_action pb0330xx_InitialScale[] = {
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 10 */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xaa, 0x01, 0x0006},
+ {0xaa, 0x02, 0x0011},
+ {0xaa, 0x03, 0x01e7},
+ {0xaa, 0x04, 0x0287},
+ {0xaa, 0x06, 0x0003},
+ {0xaa, 0x07, 0x3002},
+ {0xaa, 0x20, 0x1100},
+ {0xaa, 0x2f, 0xf7b0},
+ {0xaa, 0x30, 0x0005},
+ {0xaa, 0x31, 0x0000},
+ {0xaa, 0x34, 0x0100},
+ {0xaa, 0x35, 0x0060},
+ {0xaa, 0x3d, 0x068f},
+ {0xaa, 0x40, 0x01e0},
+ {0xaa, 0x58, 0x0078},
+ {0xaa, 0x62, 0x0411},
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x6c, ZC3XX_R18D_YTARGET},
+ {0xa1, 0x01, 0x0002},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
+ {0xa1, 0x01, 0x0091},
+ {0xa1, 0x01, 0x0095},
+ {0xa1, 0x01, 0x0096},
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf8, ZC3XX_R10B_RGB01},
+ {0xa0, 0xf8, ZC3XX_R10C_RGB02},
+ {0xa0, 0xf8, ZC3XX_R10D_RGB10},
+ {0xa0, 0x50, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf8, ZC3XX_R10F_RGB12},
+ {0xa0, 0xf8, ZC3XX_R110_RGB20},
+ {0xa0, 0xf8, ZC3XX_R111_RGB21},
+ {0xa0, 0x50, ZC3XX_R112_RGB22},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0x05, 0x0066},
+ {0xaa, 0x09, 0x02b2},
+ {0xaa, 0x10, 0x0002},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0008},
+ {0xa1, 0x01, 0x0007},
+/* {0xa0, 0x30, 0x0007}, */
+/* {0xa0, 0x00, 0x0007}, */
+ {}
+};
+static const struct usb_action pb0330_50HZ[] = {
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
+ {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */
+ {}
+};
+static const struct usb_action pb0330_50HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
+ {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */
+ {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */
+ {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
+ {}
+};
+static const struct usb_action pb0330_60HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
+ {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */
+ {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
+ {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+ {}
+};
+static const struct usb_action pb0330_60HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
+ {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */
+ {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */
+ {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+ {}
+};
+static const struct usb_action pb0330_NoFliker[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */
+ {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
+ {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+ {}
+};
+static const struct usb_action pb0330_NoFlikerScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */
+ {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */
+ {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */
+ {}
+};
+
+/* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */
+static const struct usb_action PO2030_mode0[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */
+ {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */
+ {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */
+ {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */
+ {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */
+ {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */
+ {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */
+ {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
+ {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xaa, 0x09, 0x00ce}, /* 00,09,ce,aa */
+ {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */
+ {0xaa, 0x0d, 0x0054}, /* 00,0d,54,aa */
+ {0xaa, 0x0f, 0x00eb}, /* 00,0f,eb,aa */
+ {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */
+ {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */
+ {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */
+ {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */
+ {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */
+ {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */
+ {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */
+ {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */
+ {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */
+ {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */
+ {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */
+ {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */
+ {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */
+ {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */
+ {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */
+ {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */
+ {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
+ {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */
+ {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */
+ {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */
+ {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */
+ {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */
+ {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */
+ {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */
+ {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */
+ {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */
+ {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */
+ {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */
+ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */
+ {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */
+ {}
+};
+
+/* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */
+static const struct usb_action PO2030_mode1[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */
+ {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */
+ {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */
+ {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */
+ {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */
+ {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */
+ {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */
+ {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
+ {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xaa, 0x09, 0x00cc}, /* 00,09,cc,aa */
+ {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */
+ {0xaa, 0x0d, 0x0058}, /* 00,0d,58,aa */
+ {0xaa, 0x0f, 0x00ed}, /* 00,0f,ed,aa */
+ {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */
+ {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */
+ {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */
+ {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */
+ {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */
+ {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */
+ {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */
+ {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */
+ {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */
+ {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */
+ {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */
+ {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */
+ {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */
+ {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */
+ {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */
+ {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */
+ {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */
+ {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */
+ {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */
+ {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */
+ {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */
+ {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */
+ {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */
+ {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */
+ {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */
+ {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */
+ {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */
+ {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */
+ {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */
+ {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */
+ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */
+ {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */
+ {}
+};
+
+static const struct usb_action PO2030_50HZ[] = {
+ {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
+ {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */
+ {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */
+ {0xaa, 0x1c, 0x00b0}, /* 00,1c,b0,aa */
+ {0xa0, 0x05, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,05,cc */
+ {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,35,cc */
+ {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x85, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,85,cc */
+ {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,58,cc */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */
+ {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
+ {}
+};
+
+static const struct usb_action PO2030_60HZ[] = {
+ {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */
+ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
+ {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */
+ {0xaa, 0x1c, 0x0040}, /* 00,1c,40,aa */
+ {0xa0, 0x08, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,08,cc */
+ {0xa0, 0xae, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,ae,cc */
+ {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x6f, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,6f,cc */
+ {0xa0, 0x20, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,20,cc */
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */
+ {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */
+ {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */
+ /* win: 01,8d,80 */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */
+ {}
+};
+
+static const struct usb_action PO2030_NoFliker[] = {
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */
+ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */
+ {0xaa, 0x1b, 0x0002}, /* 00,1b,02,aa */
+ {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */
+ {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */
+ {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */
+ {}
+};
+
+/* TEST */
+static const struct usb_action tas5130CK_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x01, 0x003b},
+ {0xa0, 0x0e, 0x003a},
+ {0xa0, 0x01, 0x0038},
+ {0xa0, 0x0b, 0x0039},
+ {0xa0, 0x00, 0x0038},
+ {0xa0, 0x0b, 0x0039},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x83, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x06, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x02, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xE7, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x87, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x02, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x07, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x30, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x51, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x35, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x30, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x05, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x31, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x58, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x78, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x62, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2B, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2c, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2D, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2e, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x6c, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x61, ZC3XX_R116_RGAIN},
+ {0xa0, 0x65, ZC3XX_R118_BGAIN},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf1, ZC3XX_R10B_RGB01},
+ {0xa0, 0x03, ZC3XX_R10C_RGB02},
+ {0xa0, 0xfe, ZC3XX_R10D_RGB10},
+ {0xa0, 0x51, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf1, ZC3XX_R10F_RGB12},
+ {0xa0, 0xec, ZC3XX_R110_RGB20},
+ {0xa0, 0x03, ZC3XX_R111_RGB21},
+ {0xa0, 0x51, ZC3XX_R112_RGB22},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x38, ZC3XX_R120_GAMMA00}, /* gamma > 5 */
+ {0xa0, 0x51, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x6e, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x8c, ZC3XX_R123_GAMMA03},
+ {0xa0, 0xa2, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xb6, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xc8, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xd6, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xe2, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xed, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xf5, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xfc, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x12, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x1b, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x1d, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1a, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x15, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x12, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x0f, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x05, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf1, ZC3XX_R10B_RGB01},
+ {0xa0, 0x03, ZC3XX_R10C_RGB02},
+ {0xa0, 0xfe, ZC3XX_R10D_RGB10},
+ {0xa0, 0x51, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf1, ZC3XX_R10F_RGB12},
+ {0xa0, 0xec, ZC3XX_R110_RGB20},
+ {0xa0, 0x03, ZC3XX_R111_RGB21},
+ {0xa0, 0x51, ZC3XX_R112_RGB22},
+ {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x09, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x34, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+
+static const struct usb_action tas5130CK_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x01, 0x003b},
+ {0xa0, 0x0e, 0x003a},
+ {0xa0, 0x01, 0x0038},
+ {0xa0, 0x0b, 0x0039},
+ {0xa0, 0x00, 0x0038},
+ {0xa0, 0x0b, 0x0039},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x83, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x06, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x02, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xe5, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x85, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x02, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x07, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x30, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x51, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x35, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x50, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x30, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x05, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x31, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x58, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x78, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x62, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2B, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2C, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2D, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x2e, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x6c, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x61, ZC3XX_R116_RGAIN},
+ {0xa0, 0x65, ZC3XX_R118_BGAIN},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf1, ZC3XX_R10B_RGB01},
+ {0xa0, 0x03, ZC3XX_R10C_RGB02},
+ {0xa0, 0xfe, ZC3XX_R10D_RGB10},
+ {0xa0, 0x51, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf1, ZC3XX_R10F_RGB12},
+ {0xa0, 0xec, ZC3XX_R110_RGB20},
+ {0xa0, 0x03, ZC3XX_R111_RGB21},
+ {0xa0, 0x51, ZC3XX_R112_RGB22},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+ {0xa0, 0x38, ZC3XX_R120_GAMMA00}, /* gamma > 5 */
+ {0xa0, 0x51, ZC3XX_R121_GAMMA01},
+ {0xa0, 0x6e, ZC3XX_R122_GAMMA02},
+ {0xa0, 0x8c, ZC3XX_R123_GAMMA03},
+ {0xa0, 0xa2, ZC3XX_R124_GAMMA04},
+ {0xa0, 0xb6, ZC3XX_R125_GAMMA05},
+ {0xa0, 0xc8, ZC3XX_R126_GAMMA06},
+ {0xa0, 0xd6, ZC3XX_R127_GAMMA07},
+ {0xa0, 0xe2, ZC3XX_R128_GAMMA08},
+ {0xa0, 0xed, ZC3XX_R129_GAMMA09},
+ {0xa0, 0xf5, ZC3XX_R12A_GAMMA0A},
+ {0xa0, 0xfc, ZC3XX_R12B_GAMMA0B},
+ {0xa0, 0xff, ZC3XX_R12C_GAMMA0C},
+ {0xa0, 0xff, ZC3XX_R12D_GAMMA0D},
+ {0xa0, 0xff, ZC3XX_R12E_GAMMA0E},
+ {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
+ {0xa0, 0x12, ZC3XX_R130_GAMMA10},
+ {0xa0, 0x1b, ZC3XX_R131_GAMMA11},
+ {0xa0, 0x1d, ZC3XX_R132_GAMMA12},
+ {0xa0, 0x1a, ZC3XX_R133_GAMMA13},
+ {0xa0, 0x15, ZC3XX_R134_GAMMA14},
+ {0xa0, 0x12, ZC3XX_R135_GAMMA15},
+ {0xa0, 0x0f, ZC3XX_R136_GAMMA16},
+ {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
+ {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
+ {0xa0, 0x09, ZC3XX_R139_GAMMA19},
+ {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
+ {0xa0, 0x05, ZC3XX_R13B_GAMMA1B},
+ {0xa0, 0x00, ZC3XX_R13C_GAMMA1C},
+ {0xa0, 0x00, ZC3XX_R13D_GAMMA1D},
+ {0xa0, 0x00, ZC3XX_R13E_GAMMA1E},
+ {0xa0, 0x01, ZC3XX_R13F_GAMMA1F},
+ {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xf1, ZC3XX_R10B_RGB01},
+ {0xa0, 0x03, ZC3XX_R10C_RGB02},
+ {0xa0, 0xfe, ZC3XX_R10D_RGB10},
+ {0xa0, 0x51, ZC3XX_R10E_RGB11},
+ {0xa0, 0xf1, ZC3XX_R10F_RGB12},
+ {0xa0, 0xec, ZC3XX_R110_RGB20},
+ {0xa0, 0x03, ZC3XX_R111_RGB21},
+ {0xa0, 0x51, ZC3XX_R112_RGB22},
+ {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0x62, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
+ {0xa0, 0xaa, ZC3XX_R093_I2CSETVALUE},
+ {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK},
+ {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x09, 0x01ad},
+ {0xa0, 0x15, 0x01ae},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x30, 0x0007},
+ {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x00, 0x0007},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {}
+};
+
+static const struct usb_action tas5130cxx_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
+ {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
+
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+
+ {0xa0, 0x04, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x04, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE},
+ {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x68, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xec, ZC3XX_R10B_RGB01},
+ {0xa0, 0xec, ZC3XX_R10C_RGB02},
+ {0xa0, 0xec, ZC3XX_R10D_RGB10},
+ {0xa0, 0x68, ZC3XX_R10E_RGB11},
+ {0xa0, 0xec, ZC3XX_R10F_RGB12},
+ {0xa0, 0xec, ZC3XX_R110_RGB20},
+ {0xa0, 0xec, ZC3XX_R111_RGB21},
+ {0xa0, 0x68, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x018d},
+ {0xa0, 0x90, ZC3XX_R18D_YTARGET}, /* 90 */
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+
+ {0xaa, 0xa3, 0x0001},
+ {0xaa, 0xa4, 0x0077},
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW},
+
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 00 */
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 03 */
+ {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* e8 */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 0 */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 0 */
+ {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 7d */
+
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 08 */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 24 */
+ {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
+ {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW},
+ {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 50 */
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+static const struct usb_action tas5130cxx_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
+ {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT},
+
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa1, 0x01, 0x0008},
+
+ {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
+ {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN},
+ {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL},
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
+ {0xa0, 0x05, ZC3XX_R098_WINYSTARTLOW},
+ {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW},
+ {0xa0, 0x05, ZC3XX_R11A_FIRSTYLOW},
+ {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW},
+ {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW},
+ {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH},
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW},
+ {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE},
+ {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION},
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
+ {0xa0, 0x68, ZC3XX_R18D_YTARGET},
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},
+ {0xa0, 0x00, 0x01ad},
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
+ {0xa1, 0x01, 0x0002},
+ {0xa1, 0x01, 0x0008},
+
+ {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
+ {0xa1, 0x01, 0x0008}, /* clock ? */
+ {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
+ {0xa1, 0x01, 0x01c8},
+ {0xa1, 0x01, 0x01c9},
+ {0xa1, 0x01, 0x01ca},
+ {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
+
+ {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */
+ {0xa0, 0xec, ZC3XX_R10B_RGB01},
+ {0xa0, 0xec, ZC3XX_R10C_RGB02},
+ {0xa0, 0xec, ZC3XX_R10D_RGB10},
+ {0xa0, 0x68, ZC3XX_R10E_RGB11},
+ {0xa0, 0xec, ZC3XX_R10F_RGB12},
+ {0xa0, 0xec, ZC3XX_R110_RGB20},
+ {0xa0, 0xec, ZC3XX_R111_RGB21},
+ {0xa0, 0x68, ZC3XX_R112_RGB22},
+
+ {0xa1, 0x01, 0x018d},
+ {0xa0, 0x90, ZC3XX_R18D_YTARGET},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
+ {0xaa, 0xa3, 0x0001},
+ {0xaa, 0xa4, 0x0063},
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
+ {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW},
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID},
+ {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW},
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
+ {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},
+ {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE},
+ {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE},
+ {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF},
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},
+ {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0},
+ {0xa0, 0xda, ZC3XX_R01E_HSYNC_1},
+ {0xa0, 0xea, ZC3XX_R01F_HSYNC_2},
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3},
+ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH},
+ {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW},
+ {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN},
+ {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE},
+ {0xa1, 0x01, 0x0180},
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
+ {}
+};
+static const struct usb_action tas5130cxx_50HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
+ {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
+ {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */
+ {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */
+ {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */
+ {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+ {}
+};
+static const struct usb_action tas5130cxx_50HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
+ {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
+ {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
+ {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
+ {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */
+ {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */
+ {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+ {}
+};
+static const struct usb_action tas5130cxx_60HZ[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
+ {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
+ {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */
+ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
+ {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+ {}
+};
+static const struct usb_action tas5130cxx_60HZScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
+ {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
+ {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
+ {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */
+ {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */
+ {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */
+ {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */
+ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
+ {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */
+ {}
+};
+static const struct usb_action tas5130cxx_NoFliker[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
+ {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
+ {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
+ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
+ {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
+ {}
+};
+
+static const struct usb_action tas5130cxx_NoFlikerScale[] = {
+ {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
+ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */
+ {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */
+ {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */
+ {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */
+ {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */
+ {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */
+ {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */
+ {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */
+ {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */
+ {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */
+ {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */
+ {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */
+ {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */
+ {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */
+ {}
+};
+
+static const struct usb_action tas5130c_vf0250_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
+ {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc,
+ * 0<->10 */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */
+ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc,
+ * 6<->8 */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc,
+ * 6<->8 */
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */
+ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
+ {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */
+ {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */
+ {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */
+ {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
+ {0xaa, 0x01, 0x0000},
+ {0xaa, 0x01, 0x0000},
+ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
+ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
+ {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */
+ {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */
+ {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */
+ {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */
+ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */
+ {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */
+ {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */
+ {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */
+ {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */
+ {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */
+ {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */
+ {0xa0, 0x00, 0x0039},
+ {0xa1, 0x01, 0x0037},
+ {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
+ {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */
+ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
+ {0xaa, 0x19, 0x0088}, /* 00,19,86,aa, */
+ {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */
+ {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */
+ {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */
+ {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */
+ {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
+ {}
+};
+
+static const struct usb_action tas5130c_vf0250_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */
+ {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */
+ {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc, */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */
+ {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */
+ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */
+ {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc,
+ * 8<->6 */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc,
+ * 8<->6 */
+ {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */
+ {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */
+ {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */
+ {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */
+ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */
+ {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */
+ {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */
+ {0xaa, 0x01, 0x0000},
+ {0xaa, 0x01, 0x0000},
+ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */
+ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */
+ {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */
+ {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */
+ {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */
+ {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */
+ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */
+ {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */
+ {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */
+ {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */
+ {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */
+ {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */
+ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */
+ {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */
+ {0xa0, 0x00, 0x0039},
+ {0xa1, 0x01, 0x0037},
+ {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */
+ {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */
+ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */
+ {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */
+ {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */
+ {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */
+ {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */
+ {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */
+ {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */
+ {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */
+ {}
+};
+/* "50HZ" light frequency banding filter */
+static const struct usb_action tas5130c_vf0250_50HZ[] = {
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
+ {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
+ {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */
+ {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
+ {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */
+ {}
+};
+
+/* "50HZScale" light frequency banding filter */
+static const struct usb_action tas5130c_vf0250_50HZScale[] = {
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */
+ {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
+ {0xa0, 0x0d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */
+ {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
+ {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc, */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */
+ {}
+};
+
+/* "60HZ" light frequency banding filter */
+static const struct usb_action tas5130c_vf0250_60HZ[] = {
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */
+ {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
+ {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */
+ {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
+ {0xa0, 0x3b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3b,cc, */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */
+ {}
+};
+
+/* "60HZScale" light frequency banding ilter */
+static const struct usb_action tas5130c_vf0250_60HZScale[] = {
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */
+ {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
+ {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */
+ {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,5,00,cc, */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,6,00,cc, */
+ {0xa0, 0x76, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,7,76,cc, */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,c,0e,cc, */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,f,15,cc, */
+ {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,9,10,cc, */
+ {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,a,24,cc, */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,d,62,cc, */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,e,90,cc, */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,f,c8,cc, */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */
+ {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */
+ {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,d,78,cc */
+ {}
+};
+
+/* "NoFliker" light frequency banding flter */
+static const struct usb_action tas5130c_vf0250_NoFliker[] = {
+ {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
+ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */
+ {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */
+ {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
+ {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */
+ {}
+};
+
+/* "NoFlikerScale" light frequency banding filter */
+static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
+ {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */
+ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */
+ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */
+ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */
+ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */
+ {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc, */
+ {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc, */
+ {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */
+ {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */
+ {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */
+ {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */
+ {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */
+ {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */
+ {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */
+ {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */
+ {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */
+ {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */
+ {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */
+ {}
+};
+
+static int reg_r_i(struct gspca_dev *gspca_dev,
+ __u16 index)
+{
+ usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0xa1,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x01, /* value */
+ index, gspca_dev->usb_buf, 1,
+ 500);
+ return gspca_dev->usb_buf[0];
+}
+
+static int reg_r(struct gspca_dev *gspca_dev,
+ __u16 index)
+{
+ int ret;
+
+ ret = reg_r_i(gspca_dev, index);
+ PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
+ return ret;
+}
+
+static void reg_w_i(struct usb_device *dev,
+ __u8 value,
+ __u16 index)
+{
+ usb_control_msg(dev,
+ usb_sndctrlpipe(dev, 0),
+ 0xa0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0,
+ 500);
+}
+
+static void reg_w(struct usb_device *dev,
+ __u8 value,
+ __u16 index)
+{
+ PDEBUG(D_USBO, "reg w %02x -> [%04x]", value, index);
+ reg_w_i(dev, value, index);
+}
+
+static __u16 i2c_read(struct gspca_dev *gspca_dev,
+ __u8 reg)
+{
+ __u8 retbyte;
+ __u8 retval[2];
+
+ reg_w_i(gspca_dev->dev, reg, 0x92);
+ reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
+ msleep(25);
+ retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
+ retval[0] = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
+ retval[1] = reg_r_i(gspca_dev, 0x0096); /* read Hightbyte */
+ PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x",
+ reg, retbyte, retval[1], retval[0]);
+ return (retval[1] << 8) | retval[0];
+}
+
+static __u8 i2c_write(struct gspca_dev *gspca_dev,
+ __u8 reg,
+ __u8 valL,
+ __u8 valH)
+{
+ __u8 retbyte;
+
+ reg_w_i(gspca_dev->dev, reg, 0x92);
+ reg_w_i(gspca_dev->dev, valL, 0x93);
+ reg_w_i(gspca_dev->dev, valH, 0x94);
+ reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */
+ msleep(5);
+ retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
+ PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)",
+ reg, valH, valL, retbyte);
+ return retbyte;
+}
+
+static void usb_exchange(struct gspca_dev *gspca_dev,
+ const struct usb_action *action)
+{
+ while (action->req) {
+ switch (action->req) {
+ case 0xa0: /* write register */
+ reg_w(gspca_dev->dev, action->val, action->idx);
+ break;
+ case 0xa1: /* read status */
+ reg_r(gspca_dev, action->idx);
+ break;
+ case 0xaa:
+ i2c_write(gspca_dev,
+ action->val, /* reg */
+ action->idx & 0xff, /* valL */
+ action->idx >> 8); /* valH */
+ break;
+ default:
+/* case 0xdd: * delay */
+ msleep(action->val / 64 + 10);
+ break;
+ }
+ action++;
+/* msleep(1); */
+ }
+}
+
+static void setmatrix(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ const __u8 *matrix;
+ static const __u8 gc0305_matrix[9] =
+ {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
+ static const __u8 ov7620_matrix[9] =
+ {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58};
+ static const __u8 po2030_matrix[9] =
+ {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60};
+
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+ matrix = gc0305_matrix;
+ break;
+ case SENSOR_MC501CB:
+ return; /* no matrix? */
+ case SENSOR_OV7620:
+/* case SENSOR_OV7648: */
+ matrix = ov7620_matrix;
+ break;
+ case SENSOR_PO2030:
+ matrix = po2030_matrix;
+ break;
+ case SENSOR_TAS5130C_VF0250: /* no matrix? */
+ return;
+ default: /* matrix already loaded */
+ return;
+ }
+ for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++)
+ reg_w(gspca_dev->dev, matrix[i], 0x010a + i);
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 brightness;
+
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+ case SENSOR_OV7620:
+ case SENSOR_PO2030:
+ return;
+ }
+/*fixme: is it really write to 011d and 018d for all other sensors? */
+ brightness = sd->brightness;
+ reg_w(gspca_dev->dev, brightness, 0x011d);
+ if (brightness < 0x70)
+ brightness += 0x10;
+ else
+ brightness = 0x80;
+ reg_w(gspca_dev->dev, brightness, 0x018d);
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int sharpness;
+ static const __u8 sharpness_tb[][2] = {
+ {0x02, 0x03},
+ {0x04, 0x07},
+ {0x08, 0x0f},
+ {0x10, 0x1e}
+ };
+
+ sharpness = sd->sharpness;
+ reg_w(dev, sharpness_tb[sharpness][0], 0x01c6);
+ reg_r(gspca_dev, 0x01c8);
+ reg_r(gspca_dev, 0x01c9);
+ reg_r(gspca_dev, 0x01ca);
+ reg_w(dev, sharpness_tb[sharpness][1], 0x01cb);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ const __u8 *Tgamma, *Tgradient;
+ int g, i, k;
+ static const __u8 kgamma_tb[16] = /* delta for contrast */
+ {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08};
+ static const __u8 kgrad_tb[16] =
+ {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04};
+ static const __u8 Tgamma_1[16] =
+ {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f,
+ 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff};
+ static const __u8 Tgradient_1[16] =
+ {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a,
+ 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06};
+ static const __u8 Tgamma_2[16] =
+ {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c,
+ 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff};
+ static const __u8 Tgradient_2[16] =
+ {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15,
+ 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03};
+ static const __u8 Tgamma_3[16] =
+ {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac,
+ 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff};
+ static const __u8 Tgradient_3[16] =
+ {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12,
+ 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03};
+ static const __u8 Tgamma_4[16] =
+ {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+ 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff};
+ static const __u8 Tgradient_4[16] =
+ {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d,
+ 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02};
+ static const __u8 Tgamma_5[16] =
+ {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2,
+ 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff};
+ static const __u8 Tgradient_5[16] =
+ {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b,
+ 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02};
+ static const __u8 Tgamma_6[16] = /* ?? was gamma 5 */
+ {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3,
+ 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff};
+ static const __u8 Tgradient_6[16] =
+ {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e,
+ 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01};
+ static const __u8 *gamma_tb[] = {
+ NULL, Tgamma_1, Tgamma_2,
+ Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6
+ };
+ static const __u8 *gradient_tb[] = {
+ NULL, Tgradient_1, Tgradient_2,
+ Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6
+ };
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ __u8 v[16];
+#endif
+
+ Tgamma = gamma_tb[sd->gamma];
+ Tgradient = gradient_tb[sd->gamma];
+
+ k = (sd->contrast - 128) /* -128 / 128 */
+ * Tgamma[0];
+ PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128",
+ sd->gamma, sd->contrast, k);
+ for (i = 0; i < 16; i++) {
+ g = Tgamma[i] + kgamma_tb[i] * k / 128;
+ if (g > 0xff)
+ g = 0xff;
+ else if (g <= 0)
+ g = 1;
+ reg_w(dev, g, 0x0120 + i); /* gamma */
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (gspca_debug & D_CONF)
+ v[i] = g;
+#endif
+ }
+ PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x",
+ v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
+ PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
+ for (i = 0; i < 16; i++) {
+ g = Tgradient[i] - kgrad_tb[i] * k / 128;
+ if (g > 0xff)
+ g = 0xff;
+ else if (g <= 0) {
+ if (i != 15)
+ g = 0;
+ else
+ g = 1;
+ }
+ reg_w(dev, g, 0x0130 + i); /* gradient */
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ if (gspca_debug & D_CONF)
+ v[i] = g;
+#endif
+ }
+ PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
+ PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]);
+}
+
+static void setquality(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 quality;
+ __u8 frxt;
+
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+ case SENSOR_OV7620:
+ case SENSOR_PO2030:
+ return;
+ }
+/*fixme: is it really 0008 0007 0018 for all other sensors? */
+ quality = sd->qindex;
+ reg_w(dev, quality, 0x0008);
+ frxt = 0x30;
+ reg_w(dev, frxt, 0x0007);
+ switch (quality) {
+ case 0:
+ case 1:
+ case 2:
+ frxt = 0xff;
+ break;
+ case 3:
+ frxt = 0xf0;
+ break;
+ case 4:
+ frxt = 0xe0;
+ break;
+ case 5:
+ frxt = 0x20;
+ break;
+ }
+ reg_w(dev, frxt, 0x0018);
+}
+
+/* Matches the sensor's internal frame rate to the lighting frequency.
+ * Valid frequencies are:
+ * 50Hz, for European and Asian lighting (default)
+ * 60Hz, for American lighting
+ * 0 = No Fliker (for outdoore usage)
+ * Returns: 0 for success
+ */
+static int setlightfreq(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, mode;
+ const struct usb_action *zc3_freq;
+ static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
+/* SENSOR_CS2102 0 */
+ {cs2102_NoFliker, cs2102_NoFlikerScale,
+ cs2102_50HZ, cs2102_50HZScale,
+ cs2102_60HZ, cs2102_60HZScale},
+/* SENSOR_CS2102K 1 */
+ {cs2102_NoFliker, cs2102_NoFlikerScale,
+ cs2102_50HZ, cs2102_50HZScale,
+ cs2102_60HZ, cs2102_60HZScale},
+/* SENSOR_GC0305 2 */
+ {gc0305_NoFliker, gc0305_NoFliker,
+ gc0305_50HZ, gc0305_50HZ,
+ gc0305_60HZ, gc0305_60HZ},
+/* SENSOR_HDCS2020 3 */
+ {NULL, NULL,
+ NULL, NULL,
+ NULL, NULL},
+/* SENSOR_HDCS2020b 4 */
+ {hdcs2020b_NoFliker, hdcs2020b_NoFliker,
+ hdcs2020b_50HZ, hdcs2020b_50HZ,
+ hdcs2020b_60HZ, hdcs2020b_60HZ},
+/* SENSOR_HV7131B 5 */
+ {NULL, NULL,
+ NULL, NULL,
+ NULL, NULL},
+/* SENSOR_HV7131C 6 */
+ {NULL, NULL,
+ NULL, NULL,
+ NULL, NULL},
+/* SENSOR_ICM105A 7 */
+ {icm105a_NoFliker, icm105a_NoFlikerScale,
+ icm105a_50HZ, icm105a_50HZScale,
+ icm105a_60HZ, icm105a_60HZScale},
+/* SENSOR_MC501CB 8 */
+ {MC501CB_NoFliker, MC501CB_NoFlikerScale,
+ MC501CB_50HZ, MC501CB_50HZScale,
+ MC501CB_60HZ, MC501CB_60HZScale},
+/* SENSOR_OV7620 9 */
+ {OV7620_NoFliker, OV7620_NoFliker,
+ OV7620_50HZ, OV7620_50HZ,
+ OV7620_60HZ, OV7620_60HZ},
+/* SENSOR_OV7630C 10 */
+ {NULL, NULL,
+ NULL, NULL,
+ NULL, NULL},
+/* SENSOR_PAS106 11 */
+ {pas106b_NoFliker, pas106b_NoFliker,
+ pas106b_50HZ, pas106b_50HZ,
+ pas106b_60HZ, pas106b_60HZ},
+/* SENSOR_PB0330 12 */
+ {pb0330_NoFliker, pb0330_NoFlikerScale,
+ pb0330_50HZ, pb0330_50HZScale,
+ pb0330_60HZ, pb0330_60HZScale},
+/* SENSOR_PO2030 13 */
+ {PO2030_NoFliker, PO2030_NoFliker,
+ PO2030_50HZ, PO2030_50HZ,
+ PO2030_60HZ, PO2030_60HZ},
+/* SENSOR_TAS5130CK 14 */
+ {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
+ tas5130cxx_50HZ, tas5130cxx_50HZScale,
+ tas5130cxx_60HZ, tas5130cxx_60HZScale},
+/* SENSOR_TAS5130CXX 15 */
+ {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
+ tas5130cxx_50HZ, tas5130cxx_50HZScale,
+ tas5130cxx_60HZ, tas5130cxx_60HZScale},
+/* SENSOR_TAS5130C_VF0250 16 */
+ {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
+ tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
+ tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
+ };
+
+ i = sd->lightfreq * 2;
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ if (!mode)
+ i++; /* 640x480 */
+ zc3_freq = freq_tb[(int) sd->sensor][i];
+ if (zc3_freq != NULL) {
+ usb_exchange(gspca_dev, zc3_freq);
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+ if (mode /* if 320x240 */
+ && sd->lightfreq == 1) /* and 50Hz */
+ reg_w(gspca_dev->dev, 0x85, 0x018d);
+ /* win: 0x80, 0x018d */
+ break;
+ case SENSOR_OV7620:
+ if (!mode) { /* if 640x480 */
+ if (sd->lightfreq != 0) /* and 50 or 60 Hz */
+ reg_w(gspca_dev->dev, 0x40, 0x0002);
+ else
+ reg_w(gspca_dev->dev, 0x44, 0x0002);
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 autoval;
+
+ if (sd->autogain)
+ autoval = 0x42;
+ else
+ autoval = 0x02;
+ reg_w(gspca_dev->dev, autoval, 0x0180);
+}
+
+static void send_unknown(struct usb_device *dev, int sensor)
+{
+ reg_w(dev, 0x01, 0x0000); /* led off */
+ switch (sensor) {
+ case SENSOR_PAS106:
+ reg_w(dev, 0x03, 0x003a);
+ reg_w(dev, 0x0c, 0x003b);
+ reg_w(dev, 0x08, 0x0038);
+ break;
+ case SENSOR_GC0305:
+ case SENSOR_OV7620:
+ case SENSOR_PB0330:
+ case SENSOR_PO2030:
+ reg_w(dev, 0x0d, 0x003a);
+ reg_w(dev, 0x02, 0x003b);
+ reg_w(dev, 0x00, 0x0038);
+ break;
+ }
+}
+
+/* start probe 2 wires */
+static void start_2wr_probe(struct usb_device *dev, int sensor)
+{
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, sensor, 0x0010);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0x03, 0x0012);
+ reg_w(dev, 0x01, 0x0012);
+/* msleep(2); */
+}
+
+static int sif_probe(struct gspca_dev *gspca_dev)
+{
+ __u16 checkword;
+
+ start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */
+ reg_w(gspca_dev->dev, 0x08, 0x008d);
+ msleep(150);
+ checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4)
+ | ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4);
+ PDEBUG(D_PROBE, "probe sif 0x%04x", checkword);
+ if (checkword == 0x0007) {
+ send_unknown(gspca_dev->dev, SENSOR_PAS106);
+ return 0x0f; /* PAS106 */
+ }
+ return -1;
+}
+
+static int vga_2wr_probe(struct gspca_dev *gspca_dev)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ __u8 retbyte;
+ __u16 checkword;
+
+ start_2wr_probe(dev, 0x00); /* HV7131B */
+ i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
+ retbyte = i2c_read(gspca_dev, 0x01);
+ if (retbyte != 0)
+ return 0x00; /* HV7131B */
+
+ start_2wr_probe(dev, 0x04); /* CS2102 */
+ i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
+ retbyte = i2c_read(gspca_dev, 0x01);
+ if (retbyte != 0)
+ return 0x04; /* CS2102 */
+
+ start_2wr_probe(dev, 0x06); /* OmniVision */
+ reg_w(dev, 0x08, 0x8d);
+ i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
+ retbyte = i2c_read(gspca_dev, 0x11);
+ if (retbyte != 0) {
+ /* (should have returned 0xaa) --> Omnivision? */
+ /* reg_r 0x10 -> 0x06 --> */
+ goto ov_check;
+ }
+
+ start_2wr_probe(dev, 0x08); /* HDCS2020 */
+ i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
+ retbyte = i2c_read(gspca_dev, 0x15);
+ if (retbyte != 0)
+ return 0x08; /* HDCS2020 */
+
+ start_2wr_probe(dev, 0x0a); /* PB0330 */
+ i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
+ retbyte = i2c_read(gspca_dev, 0x07);
+ if (retbyte != 0)
+ return 0x0a; /* PB0330 */
+ retbyte = i2c_read(gspca_dev, 0x03);
+ if (retbyte != 0)
+ return 0x0a; /* PB0330 ?? */
+ retbyte = i2c_read(gspca_dev, 0x04);
+ if (retbyte != 0)
+ return 0x0a; /* PB0330 ?? */
+
+ start_2wr_probe(dev, 0x0c); /* ICM105A */
+ i2c_write(gspca_dev, 0x01, 0x11, 0x00);
+ retbyte = i2c_read(gspca_dev, 0x01);
+ if (retbyte != 0)
+ return 0x0c; /* ICM105A */
+
+ start_2wr_probe(dev, 0x0e); /* PAS202BCB */
+ reg_w(dev, 0x08, 0x8d);
+ i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
+ msleep(500);
+ retbyte = i2c_read(gspca_dev, 0x03);
+ if (retbyte != 0)
+ return 0x0e; /* PAS202BCB */
+
+ start_2wr_probe(dev, 0x02); /* ?? */
+ i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
+ retbyte = i2c_read(gspca_dev, 0x01);
+ if (retbyte != 0)
+ return 0x02; /* ?? */
+ov_check:
+ reg_r(gspca_dev, 0x0010); /* ?? */
+ reg_r(gspca_dev, 0x0010);
+
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0x06, 0x0010); /* OmniVision */
+ reg_w(dev, 0xa1, 0x008b);
+ reg_w(dev, 0x08, 0x008d);
+ msleep(500);
+ reg_w(dev, 0x01, 0x0012);
+ i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
+ retbyte = i2c_read(gspca_dev, 0x0a);
+ checkword = retbyte << 8;
+ retbyte = i2c_read(gspca_dev, 0x0b);
+ checkword |= retbyte;
+ PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
+ switch (checkword) {
+ case 0x7631: /* OV7630C */
+ reg_w(dev, 0x06, 0x0010);
+ break;
+ case 0x7620: /* OV7620 */
+ case 0x7648: /* OV7648 */
+ break;
+ default:
+ return -1; /* not OmniVision */
+ }
+ return checkword;
+}
+
+struct sensor_by_chipset_revision {
+ __u16 revision;
+ __u8 internal_sensor_id;
+};
+static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
+ {0xc001, 0x13}, /* MI0360 */
+ {0xe001, 0x13},
+ {0x8001, 0x13},
+ {0x8000, 0x14}, /* CS2102K */
+ {0x8400, 0x15}, /* TAS5130K */
+ {0, 0}
+};
+
+static int vga_3wr_probe(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int i;
+ __u8 retbyte;
+ __u16 checkword;
+
+/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
+ reg_w(dev, 0x02, 0x0010);
+ reg_r(gspca_dev, 0x10);
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x00, 0x0010);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0x91, 0x008b);
+ reg_w(dev, 0x03, 0x0012);
+ reg_w(dev, 0x01, 0x0012);
+ reg_w(dev, 0x05, 0x0012);
+ retbyte = i2c_read(gspca_dev, 0x14);
+ if (retbyte != 0)
+ return 0x11; /* HV7131R */
+ retbyte = i2c_read(gspca_dev, 0x15);
+ if (retbyte != 0)
+ return 0x11; /* HV7131R */
+ retbyte = i2c_read(gspca_dev, 0x16);
+ if (retbyte != 0)
+ return 0x11; /* HV7131R */
+
+ reg_w(dev, 0x02, 0x0010);
+ retbyte = reg_r(gspca_dev, 0x000b);
+ checkword = retbyte << 8;
+ retbyte = reg_r(gspca_dev, 0x000a);
+ checkword |= retbyte;
+ PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
+ reg_r(gspca_dev, 0x0010);
+ /* this is tested only once anyway */
+ i = 0;
+ while (chipset_revision_sensor[i].revision) {
+ if (chipset_revision_sensor[i].revision == checkword) {
+ sd->chip_revision = checkword;
+ send_unknown(dev, SENSOR_PB0330);
+ return chipset_revision_sensor[i].internal_sensor_id;
+ }
+ i++;
+ }
+
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0xdd, 0x008b);
+ reg_w(dev, 0x0a, 0x0010);
+ reg_w(dev, 0x03, 0x0012);
+ reg_w(dev, 0x01, 0x0012);
+ retbyte = i2c_read(gspca_dev, 0x00);
+ if (retbyte != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
+ return 0x0a; /* ?? */
+ }
+
+ reg_w(dev, 0x01, 0x0000);
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0x98, 0x008b);
+ reg_w(dev, 0x01, 0x0010);
+ reg_w(dev, 0x03, 0x0012);
+ msleep(2);
+ reg_w(dev, 0x01, 0x0012);
+ retbyte = i2c_read(gspca_dev, 0x00);
+ if (retbyte != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
+ send_unknown(dev, SENSOR_GC0305);
+ return retbyte; /* 0x29 = gc0305 - should continue? */
+ }
+
+ reg_w(dev, 0x01, 0x0000); /* check OmniVision */
+ reg_w(dev, 0x01, 0x0001);
+ reg_w(dev, 0xa1, 0x008b);
+ reg_w(dev, 0x08, 0x008d);
+ reg_w(dev, 0x06, 0x0010);
+ reg_w(dev, 0x01, 0x0012);
+ reg_w(dev, 0x05, 0x0012);
+ if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */
+ && i2c_read(gspca_dev, 0x1d) == 0xa2) {
+ send_unknown(dev, SENSOR_OV7620);
+ return 0x06; /* OmniVision confirm ? */
+ }
+
+ reg_w(dev, 0x01, 0x00);
+ reg_w(dev, 0x00, 0x02);
+ reg_w(dev, 0x01, 0x10);
+ reg_w(dev, 0x01, 0x01);
+ reg_w(dev, 0xee, 0x8b);
+ reg_w(dev, 0x03, 0x12);
+/* msleep(150); */
+ reg_w(dev, 0x01, 0x12);
+ reg_w(dev, 0x05, 0x12);
+ retbyte = i2c_read(gspca_dev, 0x00); /* ID 0 */
+ checkword = retbyte << 8;
+ retbyte = i2c_read(gspca_dev, 0x01); /* ID 1 */
+ checkword |= retbyte;
+ PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
+ if (checkword == 0x2030) {
+ retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
+ PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
+ send_unknown(dev, SENSOR_PO2030);
+ return checkword;
+ }
+
+ reg_w(dev, 0x01, 0x00);
+ reg_w(dev, 0x0a, 0x10);
+ reg_w(dev, 0xd3, 0x8b);
+ reg_w(dev, 0x01, 0x01);
+ reg_w(dev, 0x03, 0x12);
+ reg_w(dev, 0x01, 0x12);
+ reg_w(dev, 0x05, 0x01);
+ reg_w(dev, 0xd3, 0x8b);
+ retbyte = i2c_read(gspca_dev, 0x01);
+ if (retbyte != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
+ return 0x0a; /* ?? */
+ }
+ return -1;
+}
+
+static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int sensor, sensor2;
+
+ switch (sd->sensor) {
+ case SENSOR_MC501CB:
+ case SENSOR_TAS5130C_VF0250:
+ return -1; /* don't probe */
+ }
+ sensor = vga_2wr_probe(gspca_dev);
+ if (sensor >= 0) {
+ if (sensor < 0x7600)
+ return sensor;
+ /* next probe is needed for OmniVision ? */
+ }
+ sensor2 = vga_3wr_probe(gspca_dev);
+ if (sensor2 >= 0) {
+ if (sensor >= 0)
+ return sensor;
+ return sensor2;
+ }
+ return sif_probe(gspca_dev);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam;
+ int sensor;
+ int vga = 1; /* 1: vga, 0: sif */
+ static const __u8 gamma[SENSOR_MAX] = {
+ 5, /* SENSOR_CS2102 0 */
+ 5, /* SENSOR_CS2102K 1 */
+ 4, /* SENSOR_GC0305 2 */
+ 4, /* SENSOR_HDCS2020 3 */
+ 4, /* SENSOR_HDCS2020b 4 */
+ 4, /* SENSOR_HV7131B 5 */
+ 4, /* SENSOR_HV7131C 6 */
+ 4, /* SENSOR_ICM105A 7 */
+ 4, /* SENSOR_MC501CB 8 */
+ 3, /* SENSOR_OV7620 9 */
+ 4, /* SENSOR_OV7630C 10 */
+ 4, /* SENSOR_PAS106 11 */
+ 4, /* SENSOR_PB0330 12 */
+ 4, /* SENSOR_PO2030 13 */
+ 4, /* SENSOR_TAS5130CK 14 */
+ 4, /* SENSOR_TAS5130CXX 15 */
+ 3, /* SENSOR_TAS5130C_VF0250 16 */
+ };
+
+ /* define some sensors from the vendor/product */
+ sd->sharpness = 2;
+ switch (id->idVendor) {
+ case 0x041e: /* Creative */
+ switch (id->idProduct) {
+ case 0x4051: /* zc301 chips */
+ case 0x4053:
+ sd->sensor = SENSOR_TAS5130C_VF0250;
+ break;
+ }
+ break;
+ case 0x046d: /* Logitech Labtec */
+ switch (id->idProduct) {
+ case 0x08dd:
+ sd->sensor = SENSOR_MC501CB;
+ break;
+ }
+ break;
+ case 0x0ac8: /* Vimicro z-star */
+ switch (id->idProduct) {
+ case 0x305b:
+ sd->sensor = SENSOR_TAS5130C_VF0250;
+ break;
+ }
+ break;
+ }
+ sensor = zcxx_probeSensor(gspca_dev);
+ if (sensor >= 0)
+ PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
+ if ((unsigned) force_sensor < SENSOR_MAX) {
+ sd->sensor = force_sensor;
+ PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
+ } else {
+ switch (sensor) {
+ case -1:
+ switch (sd->sensor) {
+ case SENSOR_MC501CB:
+ PDEBUG(D_PROBE, "Sensor MC501CB");
+ break;
+ case SENSOR_TAS5130C_VF0250:
+ PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)");
+ break;
+ default:
+ PDEBUG(D_PROBE,
+ "Sensor UNKNOW_0 force Tas5130");
+ sd->sensor = SENSOR_TAS5130CXX;
+ }
+ break;
+ case 0:
+ PDEBUG(D_PROBE, "Find Sensor HV7131B");
+ sd->sensor = SENSOR_HV7131B;
+ break;
+ case 0x04:
+ PDEBUG(D_PROBE, "Find Sensor CS2102");
+ sd->sensor = SENSOR_CS2102;
+ break;
+ case 0x08:
+ PDEBUG(D_PROBE, "Find Sensor HDCS2020(b)");
+ sd->sensor = SENSOR_HDCS2020b;
+ break;
+ case 0x0a:
+ PDEBUG(D_PROBE,
+ "Find Sensor PB0330. Chip revision %x",
+ sd->chip_revision);
+ sd->sensor = SENSOR_PB0330;
+ break;
+ case 0x0c:
+ PDEBUG(D_PROBE, "Find Sensor ICM105A");
+ sd->sensor = SENSOR_ICM105A;
+ break;
+ case 0x0e:
+ PDEBUG(D_PROBE, "Find Sensor HDCS2020");
+ sd->sensor = SENSOR_HDCS2020;
+ sd->sharpness = 1;
+ break;
+ case 0x0f:
+ PDEBUG(D_PROBE, "Find Sensor PAS106");
+ sd->sensor = SENSOR_PAS106;
+ vga = 0; /* SIF */
+ break;
+ case 0x10:
+ case 0x12:
+ PDEBUG(D_PROBE, "Find Sensor TAS5130");
+ sd->sensor = SENSOR_TAS5130CXX;
+ break;
+ case 0x11:
+ PDEBUG(D_PROBE, "Find Sensor HV7131R(c)");
+ sd->sensor = SENSOR_HV7131C;
+ break;
+ case 0x13:
+ PDEBUG(D_PROBE,
+ "Find Sensor MI0360. Chip revision %x",
+ sd->chip_revision);
+ sd->sensor = SENSOR_PB0330;
+ break;
+ case 0x14:
+ PDEBUG(D_PROBE,
+ "Find Sensor CS2102K?. Chip revision %x",
+ sd->chip_revision);
+ sd->sensor = SENSOR_CS2102K;
+ break;
+ case 0x15:
+ PDEBUG(D_PROBE,
+ "Find Sensor TAS5130CK?. Chip revision %x",
+ sd->chip_revision);
+ sd->sensor = SENSOR_TAS5130CK;
+ break;
+ case 0x29:
+ PDEBUG(D_PROBE, "Find Sensor GC0305");
+ sd->sensor = SENSOR_GC0305;
+ break;
+ case 0x2030:
+ PDEBUG(D_PROBE, "Find Sensor PO2030");
+ sd->sensor = SENSOR_PO2030;
+ sd->sharpness = 0; /* from win traces */
+ break;
+ case 0x7620:
+ PDEBUG(D_PROBE, "Find Sensor OV7620");
+ sd->sensor = SENSOR_OV7620;
+ break;
+ case 0x7648:
+ PDEBUG(D_PROBE, "Find Sensor OV7648");
+ sd->sensor = SENSOR_OV7620; /* same sensor (?) */
+ break;
+ default:
+ PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor);
+ return -EINVAL;
+ }
+ }
+ if (sensor < 0x20) {
+ if (sensor == -1 || sensor == 0x10 || sensor == 0x12)
+ reg_w(gspca_dev->dev, 0x02, 0x0010);
+ else
+ reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010);
+ reg_r(gspca_dev, 0x0010);
+ }
+
+ cam = &gspca_dev->cam;
+ cam->dev_name = (char *) id->driver_info;
+ cam->epaddr = 0x01;
+/*fixme:test*/
+ gspca_dev->nbalt--;
+ if (vga) {
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+ } else {
+ cam->cam_mode = sif_mode;
+ cam->nmodes = ARRAY_SIZE(sif_mode);
+ }
+ sd->qindex = 1;
+ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->gamma = gamma[(int) sd->sensor];
+ sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
+ sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
+ sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
+
+ /* switch the led off */
+ reg_w(gspca_dev->dev, 0x01, 0x0000);
+ return 0;
+}
+
+/* this function is called at open time */
+static int sd_open(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev->dev, 0x01, 0x0000);
+ return 0;
+}
+
+static void sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ const struct usb_action *zc3_init;
+ int mode;
+ static const struct usb_action *init_tb[SENSOR_MAX][2] = {
+ {cs2102_InitialScale, cs2102_Initial}, /* 0 */
+ {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
+ {gc0305_Initial, gc0305_InitialScale}, /* 2 */
+ {hdcs2020xx_InitialScale, hdcs2020xx_Initial}, /* 3 */
+ {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */
+ {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */
+ {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
+ {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
+ {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */
+ {OV7620_mode0, OV7620_mode1}, /* 9 */
+ {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */
+ {pas106b_InitialScale, pas106b_Initial}, /* 11 */
+ {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
+/* or {pb03303x_InitialScale, pb03303x_Initial}, */
+ {PO2030_mode0, PO2030_mode1}, /* 13 */
+ {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */
+ {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */
+ {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
+ /* 16 */
+ };
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ zc3_init = init_tb[(int) sd->sensor][mode];
+ switch (sd->sensor) {
+ case SENSOR_HV7131B:
+ case SENSOR_HV7131C:
+ zcxx_probeSensor(gspca_dev);
+ break;
+ case SENSOR_PAS106:
+ usb_exchange(gspca_dev, pas106b_Initial_com);
+ break;
+ case SENSOR_PB0330:
+ if (mode) {
+ if (sd->chip_revision == 0xc001
+ || sd->chip_revision == 0xe001
+ || sd->chip_revision == 0x8001)
+ zc3_init = pb03303x_Initial;
+ } else {
+ if (sd->chip_revision == 0xc001
+ || sd->chip_revision == 0xe001
+ || sd->chip_revision == 0x8001)
+ zc3_init = pb03303x_InitialScale;
+ }
+ break;
+ }
+ usb_exchange(gspca_dev, zc3_init);
+
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+ case SENSOR_OV7620:
+ case SENSOR_PO2030:
+ msleep(100); /* ?? */
+ reg_r(gspca_dev, 0x0002); /* --> 0x40 */
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ reg_w(dev, 0x0d, 0x003a);
+ reg_w(dev, 0x02, 0x003b);
+ reg_w(dev, 0x00, 0x0038);
+ break;
+ }
+
+ setmatrix(gspca_dev);
+ setbrightness(gspca_dev);
+ switch (sd->sensor) {
+ case SENSOR_OV7620:
+ reg_r(gspca_dev, 0x0008);
+ reg_w(dev, 0x00, 0x0008);
+ break;
+ case SENSOR_GC0305:
+ reg_r(gspca_dev, 0x0008);
+ /* fall thru */
+ case SENSOR_PO2030:
+ reg_w(dev, 0x03, 0x0008);
+ break;
+ }
+ setsharpness(gspca_dev);
+
+ /* set the gamma tables when not set */
+ switch (sd->sensor) {
+ case SENSOR_CS2102: /* gamma set in xxx_Initial */
+ case SENSOR_CS2102K:
+ case SENSOR_HDCS2020:
+ case SENSOR_HDCS2020b:
+ case SENSOR_PB0330: /* pb with chip_revision - see above */
+ case SENSOR_OV7630C:
+ case SENSOR_TAS5130CK:
+ break;
+ default:
+ setcontrast(gspca_dev);
+ break;
+ }
+ setmatrix(gspca_dev); /* one more time? */
+ switch (sd->sensor) {
+ case SENSOR_OV7620:
+ reg_r(gspca_dev, 0x0180); /* from win */
+ reg_w(dev, 0x00, 0x0180);
+ break;
+ default:
+ setquality(gspca_dev);
+ break;
+ }
+ setlightfreq(gspca_dev);
+
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+ case SENSOR_OV7620:
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ sd->autogain = 0;
+ break;
+ case SENSOR_PO2030:
+ reg_w(dev, 0x40, 0x0117); /* (from win traces) */
+ reg_r(gspca_dev, 0x0180);
+ break;
+ }
+
+ setautogain(gspca_dev);
+ switch (sd->sensor) {
+ case SENSOR_GC0305:
+/* setlightfreq(gspca_dev); ?? (end: 80 -> [18d]) */
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ reg_w(dev, 0x40, 0x0180);
+ reg_w(dev, 0x40, 0x0117);
+ reg_r(gspca_dev, 0x0180);
+ sd->autogain = 1;
+ setautogain(gspca_dev);
+ break;
+ case SENSOR_OV7620:
+ i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */
+ i2c_write(gspca_dev, 0x13, 0xa3, 0x00);
+ /*fixme: returned value to send? */
+ reg_w(dev, 0x40, 0x0117); /* (from win traces) */
+ reg_r(gspca_dev, 0x0180);
+ setautogain(gspca_dev);
+ msleep(500);
+ break;
+ case SENSOR_PO2030:
+ msleep(500);
+ reg_r(gspca_dev, 0x0008);
+ reg_r(gspca_dev, 0x0007);
+ reg_w(dev, 0x00, 0x0007); /* (from win traces) */
+ reg_w(dev, 0x02, 0x0008);
+ break;
+ }
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ send_unknown(gspca_dev->dev, sd->sensor);
+}
+
+/* this function is called at close time */
+static void sd_close(struct gspca_dev *gspca_dev)
+{
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame,
+ __u8 *data,
+ int len)
+{
+
+ if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, 0);
+ /* put the JPEG header in the new frame */
+ jpeg_put_header(gspca_dev, frame,
+ ((struct sd *) gspca_dev)->qindex,
+ 0x21);
+ /* remove the webcam's header:
+ * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
+ * - 'ss ss' is the frame sequence number (BE)
+ * - 'ww ww' and 'hh hh' are the window dimensions (BE)
+ * - 'pp pp' is the packet sequence number (BE)
+ */
+ data += 18;
+ len -= 18;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ if (gspca_dev->streaming)
+ setautogain(gspca_dev);
+ return 0;
+}
+
+static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
+static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->lightfreq = val;
+ if (gspca_dev->streaming)
+ setlightfreq(gspca_dev);
+ return 0;
+}
+
+static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->lightfreq;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming)
+ setsharpness(gspca_dev);
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
+static int sd_querymenu(struct gspca_dev *gspca_dev,
+ struct v4l2_querymenu *menu)
+{
+ switch (menu->id) {
+ case V4L2_CID_POWER_LINE_FREQUENCY:
+ switch (menu->index) {
+ case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
+ strcpy((char *) menu->name, "NoFliker");
+ return 0;
+ case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
+ strcpy((char *) menu->name, "50 Hz");
+ return 0;
+ case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ strcpy((char *) menu->name, "60 Hz");
+ return 0;
+ }
+ break;
+ }
+ return -EINVAL;
+}
+
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
+ .config = sd_config,
+ .open = sd_open,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .stop0 = sd_stop0,
+ .close = sd_close,
+ .pkt_scan = sd_pkt_scan,
+ .querymenu = sd_querymenu,
+};
+
+#define DVNM(name) .driver_info = (kernel_ulong_t) name
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")},
+ {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")},
+ {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")},
+ {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")},
+#endif
+ {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")},
+ {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")},
+ {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")},
+ {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")},
+#endif
+ {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")},
+ {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")},
+ {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")},
+ {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")},
+#endif
+ {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")},
+ {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")},
+ {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")},
+ {USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")},
+ {USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")},
+ {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")},
+ {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")},
+ {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")},
+ {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")},
+ {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")},
+ {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")},
+#endif
+ {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")},
+ {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")},
+ {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")},
+ {USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")},
+ {USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")},
+ {USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")},
+ {USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")},
+ {USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")},
+ {USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")},
+ {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")},
+ {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")},
+ {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")},
+ {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")},
+#endif
+ {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")},
+ {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")},
+ {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")},
+#endif
+ {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")},
+#ifndef CONFIG_USB_ZC0301
+ {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")},
+ {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")},
+ {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")},
+#endif
+ {} /* end of entry */
+};
+#undef DVNAME
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+/* USB driver */
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+};
+
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "v%s registered", version);
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
+
+module_param(force_sensor, int, 0644);
+MODULE_PARM_DESC(force_sensor,
+ "Force sensor. Only for experts!!!");
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 7b65f5e537f..a30254bed31 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -194,88 +194,6 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-/* Common (grey or coloured) pinnacle PCTV remote handling
- *
- */
-static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
- int parity_offset, int marker, int code_modulo)
-{
- unsigned char b[4];
- unsigned int start = 0,parity = 0,code = 0;
-
- /* poll IR chip */
- if (4 != i2c_master_recv(&ir->c,b,4)) {
- dprintk(2,"read error\n");
- return -EIO;
- }
-
- for (start = 0; start < ARRAY_SIZE(b); start++) {
- if (b[start] == marker) {
- code=b[(start+parity_offset+1)%4];
- parity=b[(start+parity_offset)%4];
- }
- }
-
- /* Empty Request */
- if (parity==0)
- return 0;
-
- /* Repeating... */
- if (ir->old == parity)
- return 0;
-
- ir->old = parity;
-
- /* drop special codes when a key is held down a long time for the grey controller
- In this case, the second bit of the code is asserted */
- if (marker == 0xfe && (code & 0x40))
- return 0;
-
- code %= code_modulo;
-
- *ir_raw = code;
- *ir_key = code;
-
- dprintk(1,"Pinnacle PCTV key %02x\n", code);
-
- return 1;
-}
-
-/* The grey pinnacle PCTV remote
- *
- * There are one issue with this remote:
- * - I2c packet does not change when the same key is pressed quickly. The workaround
- * is to hold down each key for about half a second, so that another code is generated
- * in the i2c packet, and the function can distinguish key presses.
- *
- * Sylvain Pasche <sylvain.pasche@gmail.com>
- */
-int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
-
- return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff);
-}
-
-EXPORT_SYMBOL_GPL(get_key_pinnacle_grey);
-
-
-/* The new pinnacle PCTV remote (with the colored buttons)
- *
- * Ricardo Cerqueira <v4l@cerqueira.org>
- */
-int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE
- *
- * this is the only value that results in 42 unique
- * codes < 128
- */
-
- return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88);
-}
-
-EXPORT_SYMBOL_GPL(get_key_pinnacle_color);
-
/* ----------------------------------------------------------------------- */
static void ir_key_poll(struct IR_i2c *ir)
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 4fb8faefe2c..4e05f91a910 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -40,7 +40,7 @@
#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM)
+#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
/* usual i2c tuner addresses to probe */
static struct ivtv_card_tuner_i2c ivtv_i2c_std = {
@@ -300,7 +300,7 @@ static const struct ivtv_card ivtv_card_mpg600 = {
.gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
.tuners = {
/* The PAL tuner is confirmed */
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
},
.pci_list = ivtv_pci_mpg600,
@@ -341,7 +341,7 @@ static const struct ivtv_card ivtv_card_mpg160 = {
.lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
.gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
.tuners = {
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
},
.pci_list = ivtv_pci_mpg160,
@@ -377,7 +377,7 @@ static const struct ivtv_card ivtv_card_pg600 = {
{ IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
},
.tuners = {
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
},
.pci_list = ivtv_pci_pg600,
@@ -418,7 +418,7 @@ static const struct ivtv_card ivtv_card_avc2410 = {
on the country/region setting of the user to decide which tuner
is available. */
.tuners = {
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
{ .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP,
.tuner = TUNER_PHILIPS_FM1236_MK3 },
{ .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 },
@@ -492,7 +492,7 @@ static const struct ivtv_card ivtv_card_tg5000tv = {
.gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
.composite = 0x0010, .svideo = 0x0020 },
.tuners = {
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
+ { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
},
.pci_list = ivtv_pci_tg5000tv,
.i2c = &ivtv_i2c_std,
@@ -523,7 +523,7 @@ static const struct ivtv_card ivtv_card_va2000 = {
{ IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
},
.tuners = {
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
+ { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
},
.pci_list = ivtv_pci_va2000,
.i2c = &ivtv_i2c_std,
@@ -567,7 +567,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc = {
.gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
.f44100 = 0x4000, .f48000 = 0x8000 },
.tuners = {
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
},
.pci_list = ivtv_pci_cx23416gyc,
@@ -599,7 +599,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
.gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
.f44100 = 0x4000, .f48000 = 0x8000 },
.tuners = {
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
},
.i2c = &ivtv_i2c_std,
@@ -629,7 +629,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
.gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
.f44100 = 0x4000, .f48000 = 0x8000 },
.tuners = {
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
{ .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
},
.i2c = &ivtv_i2c_std,
@@ -669,7 +669,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = {
.gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
.tuners = {
/* This card has the Panasonic VP27 tuner */
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
+ { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
},
.pci_list = ivtv_pci_gv_mvprx,
.i2c = &ivtv_i2c_std,
@@ -706,7 +706,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = {
.gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
.tuners = {
/* This card has the Panasonic VP27 tuner */
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
+ { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
},
.pci_list = ivtv_pci_gv_mvprx2e,
.i2c = &ivtv_i2c_std,
@@ -741,7 +741,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
.gpio_init = { .direction = 0xf000, .initial_value = 0xA000 },
.tuners = {
/* This card has a Philips FQ1216ME MK3 tuner */
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
},
.pci_list = ivtv_pci_gotview_pci_dvd,
.i2c = &ivtv_i2c_std,
@@ -780,7 +780,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
.gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
.tuners = {
/* This card has a Philips FQ1216ME MK5 tuner */
- { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
+ { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
},
.pci_list = ivtv_pci_gotview_pci_dvd2,
.i2c = &ivtv_i2c_std,
@@ -858,7 +858,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = {
.gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
.composite = 0x0010, .svideo = 0x0020},
.tuners = {
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
+ { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
},
.pci_list = ivtv_pci_dctmvtvp1,
.i2c = &ivtv_i2c_std,
@@ -923,7 +923,6 @@ static const struct ivtv_card ivtv_card_club3d = {
{ IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
},
.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */
.xceive_pin = 12,
.tuners = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
@@ -959,7 +958,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
{ IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
},
/* enable line-in */
- .gpio_init = { .direction = 0xe400, .initial_value = 0x4400 },
+ .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
.xceive_pin = 10,
.tuners = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
@@ -1001,7 +1000,7 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
.gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
.tuners = {
/* This card has a Partsnic PTI-5NF05 tuner */
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_TCL_2002N },
+ { .std = V4L2_STD_MN, .tuner = TUNER_TCL_2002N },
},
.pci_list = ivtv_pci_aver_pvr150,
.i2c = &ivtv_i2c_radio,
@@ -1069,7 +1068,7 @@ static const struct ivtv_card ivtv_card_asus_falcon2 = {
},
.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER },
.tuners = {
- { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
+ { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
},
.pci_list = ivtv_pci_asus_falcon2,
.i2c = &ivtv_i2c_std,
@@ -1102,7 +1101,7 @@ static const struct ivtv_card ivtv_card_aver_m104 = {
},
.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
/* enable line-in + reset tuner */
- .gpio_init = { .direction = 0xe400, .initial_value = 0x4000 },
+ .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
.xceive_pin = 10,
.tuners = {
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
@@ -1111,6 +1110,41 @@ static const struct ivtv_card ivtv_card_aver_m104 = {
.i2c = &ivtv_i2c_std,
};
+/* ------------------------------------------------------------------------- */
+
+/* Buffalo PC-MV5L/PCI cards */
+
+static const struct ivtv_card_pci_info ivtv_pci_buffalo[] = {
+ { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x052b },
+ { 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_buffalo = {
+ .type = IVTV_CARD_BUFFALO_MV5L,
+ .name = "Buffalo PC-MV5L/PCI",
+ .v4l2_capabilities = IVTV_CAP_ENCODER,
+ .hw_video = IVTV_HW_CX25840,
+ .hw_audio = IVTV_HW_CX25840,
+ .hw_audio_ctrl = IVTV_HW_CX25840,
+ .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
+ .video_inputs = {
+ { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
+ { IVTV_CARD_INPUT_SVIDEO1, 1,
+ CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
+ { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
+ },
+ .audio_inputs = {
+ { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
+ { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
+ },
+ .xceive_pin = 12,
+ .tuners = {
+ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
+ },
+ .pci_list = ivtv_pci_buffalo,
+ .i2c = &ivtv_i2c_std,
+};
+
static const struct ivtv_card *ivtv_card_list[] = {
&ivtv_card_pvr250,
&ivtv_card_pvr350,
@@ -1137,6 +1171,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
&ivtv_card_aver_pvr150,
&ivtv_card_aver_ezmaker,
&ivtv_card_aver_m104,
+ &ivtv_card_buffalo,
/* Variations of standard cards but with the same PCI IDs.
These cards must come last in this list. */
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 748485dcebb..381af1bceef 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -49,7 +49,8 @@
#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */
#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */
#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
-#define IVTV_CARD_LAST 24
+#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
+#define IVTV_CARD_LAST 25
/* Variants of existing cards but with the same PCI IDs. The driver
detects these based on other device information.
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index c7e449f6397..48e103be718 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -47,12 +47,12 @@ static const u32 *ctrl_classes[] = {
NULL
};
-static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
+
+int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
const char *name;
- IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
-
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
@@ -87,21 +87,35 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
return 0;
}
-static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu)
+int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_queryctrl qctrl;
qctrl.id = qmenu->id;
- ivtv_queryctrl(itv, &qctrl);
- return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
+ ivtv_queryctrl(file, fh, &qctrl);
+ return v4l2_ctrl_query_menu(qmenu, &qctrl,
+ cx2341x_ctrl_get_menu(&itv->params, qmenu->id));
}
-static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
+static int ivtv_try_ctrl(struct file *file, void *fh,
+ struct v4l2_ext_control *vctrl)
{
- s32 v = vctrl->value;
-
- IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
+ struct v4l2_queryctrl qctrl;
+ const char **menu_items = NULL;
+ int err;
+
+ qctrl.id = vctrl->id;
+ err = ivtv_queryctrl(file, fh, &qctrl);
+ if (err)
+ return err;
+ if (qctrl.type == V4L2_CTRL_TYPE_MENU)
+ menu_items = v4l2_ctrl_get_menu(qctrl.id);
+ return v4l2_ctrl_check(vctrl, &qctrl, menu_items);
+}
+static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
+{
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
@@ -119,7 +133,7 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
default:
- IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+ IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
@@ -127,8 +141,6 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
{
- IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
-
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
@@ -145,7 +157,7 @@ static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_LOUDNESS:
return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
default:
- IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+ IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
@@ -191,119 +203,106 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
return 0;
}
-int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
+int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_control ctrl;
- switch (cmd) {
- case VIDIOC_QUERYMENU:
- IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
- return ivtv_querymenu(itv, arg);
-
- case VIDIOC_QUERYCTRL:
- return ivtv_queryctrl(itv, arg);
-
- case VIDIOC_S_CTRL:
- return ivtv_s_ctrl(itv, arg);
-
- case VIDIOC_G_CTRL:
- return ivtv_g_ctrl(itv, arg);
-
- case VIDIOC_S_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
-
- if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
- int i;
- int err = 0;
-
- for (i = 0; i < c->count; i++) {
- ctrl.id = c->controls[i].id;
- ctrl.value = c->controls[i].value;
- err = ivtv_s_ctrl(itv, &ctrl);
- c->controls[i].value = ctrl.value;
- if (err) {
- c->error_idx = i;
- break;
- }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
+
+ for (i = 0; i < c->count; i++) {
+ ctrl.id = c->controls[i].id;
+ ctrl.value = c->controls[i].value;
+ err = ivtv_g_ctrl(itv, &ctrl);
+ c->controls[i].value = ctrl.value;
+ if (err) {
+ c->error_idx = i;
+ break;
}
- return err;
}
- IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- static u32 freqs[3] = { 44100, 48000, 32000 };
- struct cx2341x_mpeg_params p = itv->params;
- int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd);
- unsigned idx;
-
- if (err)
- return err;
-
- if (p.video_encoding != itv->params.video_encoding) {
- int is_mpeg1 = p.video_encoding ==
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_format fmt;
-
- /* fix videodecoder resolution */
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
- fmt.fmt.pix.height = itv->params.height;
- itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
- }
- err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
- if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) {
- err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
+ return err;
+ }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+ return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS);
+ return -EINVAL;
+}
+
+int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_control ctrl;
+
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
+
+ for (i = 0; i < c->count; i++) {
+ ctrl.id = c->controls[i].id;
+ ctrl.value = c->controls[i].value;
+ err = ivtv_s_ctrl(itv, &ctrl);
+ c->controls[i].value = ctrl.value;
+ if (err) {
+ c->error_idx = i;
+ break;
}
- itv->params = p;
- itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
- idx = p.audio_properties & 0x03;
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (idx < sizeof(freqs))
- ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
- return err;
}
- return -EINVAL;
+ return err;
}
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ static u32 freqs[3] = { 44100, 48000, 32000 };
+ struct cx2341x_mpeg_params p = itv->params;
+ int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS);
+ unsigned idx;
- case VIDIOC_G_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
-
- if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
- int i;
- int err = 0;
-
- for (i = 0; i < c->count; i++) {
- ctrl.id = c->controls[i].id;
- ctrl.value = c->controls[i].value;
- err = ivtv_g_ctrl(itv, &ctrl);
- c->controls[i].value = ctrl.value;
- if (err) {
- c->error_idx = i;
- break;
- }
- }
+ if (err)
return err;
+
+ if (p.video_encoding != itv->params.video_encoding) {
+ int is_mpeg1 = p.video_encoding ==
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+ struct v4l2_format fmt;
+
+ /* fix videodecoder resolution */
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
+ fmt.fmt.pix.height = itv->params.height;
+ itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
}
- IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
- return cx2341x_ext_ctrls(&itv->params, 0, arg, cmd);
- return -EINVAL;
+ err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
+ if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
+ err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
+ itv->params = p;
+ itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
+ idx = p.audio_properties & 0x03;
+ /* The audio clock of the digitizer must match the codec sample
+ rate otherwise you get some very strange effects. */
+ if (idx < sizeof(freqs))
+ ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
+ return err;
}
+ return -EINVAL;
+}
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
+int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
- return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd);
- return -EINVAL;
- }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
- default:
- return -EINVAL;
+ for (i = 0; i < c->count; i++) {
+ err = ivtv_try_ctrl(file, fh, &c->controls[i]);
+ if (err) {
+ c->error_idx = i;
+ break;
+ }
+ }
+ return err;
}
- return 0;
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+ return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS);
+ return -EINVAL;
}
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
index bb8a6a5ed2b..1c7721e23c9 100644
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ b/drivers/media/video/ivtv/ivtv-controls.h
@@ -21,6 +21,10 @@
#ifndef IVTV_CONTROLS_H
#define IVTV_CONTROLS_H
-int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg);
+int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
+int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
+int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
+int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
+int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
#endif
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 797e636771d..41fd79279bb 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -191,6 +191,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t23 = AverMedia PVR-150 Plus\n"
"\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
"\t\t\t25 = AverMedia M104 (not yet working)\n"
+ "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
@@ -1019,7 +1020,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
ivtv_cards[ivtv_cards_active] = itv;
itv->dev = dev;
itv->num = ivtv_cards_active++;
- snprintf(itv->name, sizeof(itv->name) - 1, "ivtv%d", itv->num);
+ snprintf(itv->name, sizeof(itv->name), "ivtv%d", itv->num);
IVTV_INFO("Initializing card #%d\n", itv->num);
spin_unlock(&ivtv_cards_lock);
@@ -1127,6 +1128,12 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
/* if no tuner was found, then pick the first tuner in the card list */
if (itv->options.tuner == -1 && itv->card->tuners[0].std) {
itv->std = itv->card->tuners[0].std;
+ if (itv->std & V4L2_STD_PAL)
+ itv->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
+ else if (itv->std & V4L2_STD_NTSC)
+ itv->std = V4L2_STD_NTSC_M;
+ else if (itv->std & V4L2_STD_SECAM)
+ itv->std = V4L2_STD_SECAM_L;
itv->options.tuner = itv->card->tuners[0].tuner;
}
if (itv->options.radio == -1)
@@ -1261,9 +1268,13 @@ err:
int ivtv_init_on_first_open(struct ivtv *itv)
{
struct v4l2_frequency vf;
+ /* Needed to call ioctls later */
+ struct ivtv_open_id fh;
int fw_retry_count = 3;
int video_input;
+ fh.itv = itv;
+
if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
return -ENXIO;
@@ -1311,18 +1322,18 @@ int ivtv_init_on_first_open(struct ivtv *itv)
video_input = itv->active_input;
itv->active_input++; /* Force update of input */
- ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
+ ivtv_s_input(NULL, &fh, video_input);
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
in one place. */
itv->std++; /* Force full standard initialization */
itv->std_out = itv->std;
- ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
+ ivtv_s_frequency(NULL, &fh, &vf);
if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
ivtv_init_mpeg_decoder(itv);
}
- ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
+ ivtv_s_std(NULL, &fh, &itv->tuner_std);
/* On a cx23416 this seems to be able to enable DMA to the chip? */
if (!itv->has_cx23415)
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 9d23b1efd36..a08bb3331cf 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -635,7 +635,6 @@ struct ivtv {
spinlock_t lock; /* lock access to this struct */
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
-
/* Streams */
int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */
struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index db813e071ce..7ec5c99f9ad 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -582,6 +582,19 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
ivtv_queue_init(&q);
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+ /* Start decoder (returns 0 if already started) */
+ mutex_lock(&itv->serialize_lock);
+ rc = ivtv_start_decoding(id, itv->speed);
+ mutex_unlock(&itv->serialize_lock);
+ if (rc) {
+ IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
+
+ /* failure, clean up */
+ clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
+ clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+ return rc;
+ }
+
retry:
/* If possible, just DMA the entire frame - Check the data transfer size
since we may get here before the stream has been fully set-up */
@@ -664,18 +677,6 @@ retry:
ivtv_enqueue(s, buf, &s->q_full);
}
- /* Start decoder (returns 0 if already started) */
- mutex_lock(&itv->serialize_lock);
- rc = ivtv_start_decoding(id, itv->speed);
- mutex_unlock(&itv->serialize_lock);
- if (rc) {
- IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
-
- /* failure, clean up */
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return rc;
- }
if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
if (s->q_full.length >= itv->dma_data_req_size) {
int got_sig;
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index d8ac09f3cce..bc22905ea20 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -146,15 +146,20 @@ int ivtv_reset_tuner_gpio(void *dev, int cmd, int value)
void ivtv_gpio_init(struct ivtv *itv)
{
- if (itv->card->gpio_init.direction == 0)
+ u16 pin = 0;
+
+ if (itv->card->xceive_pin)
+ pin = 1 << itv->card->xceive_pin;
+
+ if ((itv->card->gpio_init.direction | pin) == 0)
return;
IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
/* init output data then direction */
- write_reg(itv->card->gpio_init.initial_value, IVTV_REG_GPIO_OUT);
- write_reg(itv->card->gpio_init.direction, IVTV_REG_GPIO_DIR);
+ write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
+ write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
}
static struct v4l2_queryctrl gpio_ctrl_mute = {
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 32129f3ea83..af154238fb9 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -75,10 +75,6 @@
#define IVTV_REG_I2C_GETSCL_OFFSET 0x7008
#define IVTV_REG_I2C_GETSDA_OFFSET 0x700c
-#ifndef I2C_ADAP_CLASS_TV_ANALOG
-#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG
-#endif /* I2C_ADAP_CLASS_TV_ANALOG */
-
#define IVTV_CS53L32A_I2C_ADDR 0x11
#define IVTV_M52790_I2C_ADDR 0x48
#define IVTV_CX25840_I2C_ADDR 0x44
@@ -139,7 +135,7 @@ static const u8 hw_addrs[] = {
static const char * const hw_devicenames[] = {
"cx25840",
"saa7115",
- "saa7127",
+ "saa7127_auto", /* saa7127 or saa7129 */
"msp3400",
"tuner",
"wm8775",
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 26cc0f6699f..52e00a7f311 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -128,37 +128,6 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
return set;
}
-static const struct {
- v4l2_std_id std;
- char *name;
-} enum_stds[] = {
- { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" },
- { V4L2_STD_PAL_DK, "PAL-DK" },
- { V4L2_STD_PAL_I, "PAL-I" },
- { V4L2_STD_PAL_M, "PAL-M" },
- { V4L2_STD_PAL_N, "PAL-N" },
- { V4L2_STD_PAL_Nc, "PAL-Nc" },
- { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" },
- { V4L2_STD_SECAM_DK, "SECAM-DK" },
- { V4L2_STD_SECAM_L, "SECAM-L" },
- { V4L2_STD_SECAM_LC, "SECAM-L'" },
- { V4L2_STD_NTSC_M, "NTSC-M" },
- { V4L2_STD_NTSC_M_JP, "NTSC-J" },
- { V4L2_STD_NTSC_M_KR, "NTSC-K" },
-};
-
-static const struct v4l2_standard ivtv_std_60hz =
-{
- .frameperiod = {.numerator = 1001, .denominator = 30000},
- .framelines = 525,
-};
-
-static const struct v4l2_standard ivtv_std_50hz =
-{
- .frameperiod = {.numerator = 1, .denominator = 25},
- .framelines = 625,
-};
-
void ivtv_set_osd_alpha(struct ivtv *itv)
{
ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
@@ -345,1073 +314,1219 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
return 0;
}
-static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
+static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct v4l2_register *regs = arg;
- unsigned long flags;
- volatile u8 __iomem *reg_start;
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
- reg_start = itv->reg_mem - IVTV_REG_OFFSET;
- else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
- regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
- reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
- else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
- reg_start = itv->enc_mem;
- else
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
return -EINVAL;
-
- spin_lock_irqsave(&ivtv_cards_lock, flags);
- if (cmd == VIDIOC_DBG_G_REGISTER) {
- regs->val = readl(regs->reg + reg_start);
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ if (itv->is_60hz) {
+ vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+ vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
} else {
- writel(regs->val, regs->reg + reg_start);
+ vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
+ vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
}
- spin_unlock_irqrestore(&ivtv_cards_lock, flags);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
return 0;
}
-static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt)
+static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- fmt->fmt.pix.width = itv->main_rect.width;
- fmt->fmt.pix.height = itv->main_rect.height;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
- case IVTV_YUV_MODE_INTERLACED:
- fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
- V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
- break;
- case IVTV_YUV_MODE_PROGRESSIVE:
- fmt->fmt.pix.field = V4L2_FIELD_NONE;
- break;
- default:
- fmt->fmt.pix.field = V4L2_FIELD_ANY;
- break;
- }
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
- fmt->fmt.pix.bytesperline = 720;
- fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w;
- fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- fmt->fmt.pix.sizeimage =
- 1080 * ((fmt->fmt.pix.height + 31) & ~31);
- } else if (streamtype == IVTV_ENC_STREAM_TYPE_YUV) {
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- fmt->fmt.pix.sizeimage =
- fmt->fmt.pix.height * fmt->fmt.pix.width +
- fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
- } else {
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- fmt->fmt.pix.sizeimage = 128 * 1024;
- }
- break;
-
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- fmt->fmt.pix.width = itv->params.width;
- fmt->fmt.pix.height = itv->params.height;
- fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
- if (streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
- streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- fmt->fmt.pix.sizeimage =
- fmt->fmt.pix.height * fmt->fmt.pix.width +
- fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
- } else {
- fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
- fmt->fmt.pix.sizeimage = 128 * 1024;
- }
- break;
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+
+ pixfmt->width = itv->params.width;
+ pixfmt->height = itv->params.height;
+ pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ pixfmt->field = V4L2_FIELD_INTERLACED;
+ pixfmt->priv = 0;
+ if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
+ pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
+ /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
+ pixfmt->sizeimage =
+ pixfmt->height * pixfmt->width +
+ pixfmt->height * (pixfmt->width / 2);
+ pixfmt->bytesperline = 720;
+ } else {
+ pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
+ pixfmt->sizeimage = 128 * 1024;
+ pixfmt->bytesperline = 0;
+ }
+ return 0;
+}
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- fmt->fmt.win.chromakey = itv->osd_chroma_key;
- fmt->fmt.win.global_alpha = itv->osd_global_alpha;
- break;
+static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
+
+ vbifmt->sampling_rate = 27000000;
+ vbifmt->offset = 248;
+ vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
+ vbifmt->sample_format = V4L2_PIX_FMT_GREY;
+ vbifmt->start[0] = itv->vbi.start[0];
+ vbifmt->start[1] = itv->vbi.start[1];
+ vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
+ vbifmt->flags = 0;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ return 0;
+}
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- fmt->fmt.vbi.sampling_rate = 27000000;
- fmt->fmt.vbi.offset = 248;
- fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
- fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
- fmt->fmt.vbi.start[0] = itv->vbi.start[0];
- fmt->fmt.vbi.start[1] = itv->vbi.start[1];
- fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
- break;
+static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- {
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
- return -EINVAL;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
- memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
- if (itv->is_60hz) {
- vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- } else {
- vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
- vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
- }
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- break;
+ if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
+ vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
+ V4L2_SLICED_VBI_525;
+ ivtv_expand_service_set(vbifmt, itv->is_50hz);
+ return 0;
}
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- {
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+ itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
+ return 0;
+}
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
- memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
+static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
- if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
- vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
- V4L2_SLICED_VBI_525;
- ivtv_expand_service_set(vbifmt, itv->is_50hz);
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+ return -EINVAL;
+ pixfmt->width = itv->main_rect.width;
+ pixfmt->height = itv->main_rect.height;
+ pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ pixfmt->field = V4L2_FIELD_INTERLACED;
+ pixfmt->priv = 0;
+ if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
+ switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
+ case IVTV_YUV_MODE_INTERLACED:
+ pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
+ V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
+ break;
+ case IVTV_YUV_MODE_PROGRESSIVE:
+ pixfmt->field = V4L2_FIELD_NONE;
+ break;
+ default:
+ pixfmt->field = V4L2_FIELD_ANY;
break;
}
-
- itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- break;
- }
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
+ pixfmt->bytesperline = 720;
+ pixfmt->width = itv->yuv_info.v4l2_src_w;
+ pixfmt->height = itv->yuv_info.v4l2_src_h;
+ /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
+ pixfmt->sizeimage =
+ 1080 * ((pixfmt->height + 31) & ~31);
+ } else {
+ pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
+ pixfmt->sizeimage = 128 * 1024;
+ pixfmt->bytesperline = 0;
}
return 0;
}
-static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
- struct v4l2_format *fmt, int set_fmt)
+static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- u16 set;
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_window *winfmt = &fmt->fmt.win;
- if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- struct v4l2_rect r;
- int field;
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+ return -EINVAL;
+ winfmt->chromakey = itv->osd_chroma_key;
+ winfmt->global_alpha = itv->osd_global_alpha;
+ winfmt->field = V4L2_FIELD_INTERLACED;
+ winfmt->clips = NULL;
+ winfmt->clipcount = 0;
+ winfmt->bitmap = NULL;
+ winfmt->w.top = winfmt->w.left = 0;
+ winfmt->w.width = itv->osd_rect.width;
+ winfmt->w.height = itv->osd_rect.height;
+ return 0;
+}
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- field = fmt->fmt.pix.field;
- r.top = 0;
- r.left = 0;
- r.width = fmt->fmt.pix.width;
- r.height = fmt->fmt.pix.height;
- ivtv_get_fmt(itv, streamtype, fmt);
- fmt->fmt.pix.width = r.width;
- fmt->fmt.pix.height = r.height;
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- fmt->fmt.pix.field = field;
- if (fmt->fmt.pix.width < 2)
- fmt->fmt.pix.width = 2;
- if (fmt->fmt.pix.width > 720)
- fmt->fmt.pix.width = 720;
- if (fmt->fmt.pix.height < 2)
- fmt->fmt.pix.height = 2;
- if (fmt->fmt.pix.height > 576)
- fmt->fmt.pix.height = 576;
- }
- if (set_fmt && streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- /* Return now if we already have some frame data */
- if (yi->stream_size)
- return -EBUSY;
+static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
+}
- yi->v4l2_src_w = r.width;
- yi->v4l2_src_h = r.height;
+static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ int w = fmt->fmt.pix.width;
+ int h = fmt->fmt.pix.height;
+
+ w = min(w, 720);
+ w = max(w, 1);
+ h = min(h, itv->is_50hz ? 576 : 480);
+ h = max(h, 2);
+ ivtv_g_fmt_vid_cap(file, fh, fmt);
+ fmt->fmt.pix.width = w;
+ fmt->fmt.pix.height = h;
+ return 0;
+}
- switch (field) {
- case V4L2_FIELD_NONE:
- yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
- break;
- case V4L2_FIELD_ANY:
- yi->lace_mode = IVTV_YUV_MODE_AUTO;
- break;
- case V4L2_FIELD_INTERLACED_BT:
- yi->lace_mode =
- IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
- break;
- case V4L2_FIELD_INTERLACED_TB:
- default:
- yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
- break;
- }
- yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
+static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ return ivtv_g_fmt_vbi_cap(file, fh, fmt);
+}
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- itv->dma_data_req_size =
- 1080 * ((yi->v4l2_src_h + 31) & ~31);
+static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
- /* Force update of yuv registers */
- yi->yuv_forced_update = 1;
- return 0;
- }
- return 0;
- }
+ if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
+ return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
- if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) {
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- if (set_fmt) {
- itv->osd_chroma_key = fmt->fmt.win.chromakey;
- itv->osd_global_alpha = fmt->fmt.win.global_alpha;
- ivtv_set_osd_alpha(itv);
- }
- return 0;
- }
+ /* set sliced VBI capture format */
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
- /* set window size */
- if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- struct cx2341x_mpeg_params *p = &itv->params;
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
-
- if (w > 720) w = 720;
- else if (w < 1) w = 1;
- if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480);
- else if (h < 2) h = 2;
- ivtv_get_fmt(itv, streamtype, fmt);
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
-
- if (!set_fmt || (p->width == w && p->height == h))
- return 0;
- if (atomic_read(&itv->capturing) > 0)
- return -EBUSY;
+ if (vbifmt->service_set)
+ ivtv_expand_service_set(vbifmt, itv->is_50hz);
+ check_service_set(vbifmt, itv->is_50hz);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
+ return 0;
+}
- p->width = w;
- p->height = h;
- if (w != 720 || h != (itv->is_50hz ? 576 : 480))
- p->video_temporal_filter = 0;
- else
- p->video_temporal_filter = 8;
- if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
- fmt->fmt.pix.width /= 2;
- itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
- return ivtv_get_fmt(itv, streamtype, fmt);
- }
+static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv_open_id *id = fh;
+ s32 w, h;
+ int field;
+ int ret;
- /* set raw VBI format */
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- if (set_fmt && atomic_read(&itv->capturing) > 0) {
- return -EBUSY;
- }
- if (set_fmt) {
- itv->vbi.sliced_in->service_set = 0;
- itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
- }
- return ivtv_get_fmt(itv, streamtype, fmt);
- }
+ w = fmt->fmt.pix.width;
+ h = fmt->fmt.pix.height;
+ field = fmt->fmt.pix.field;
+ ret = ivtv_g_fmt_vid_out(file, fh, fmt);
+ fmt->fmt.pix.width = w;
+ fmt->fmt.pix.height = h;
+ if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) {
+ fmt->fmt.pix.field = field;
+ if (fmt->fmt.pix.width < 2)
+ fmt->fmt.pix.width = 2;
+ if (fmt->fmt.pix.width > 720)
+ fmt->fmt.pix.width = 720;
+ if (fmt->fmt.pix.height < 2)
+ fmt->fmt.pix.height = 2;
+ if (fmt->fmt.pix.height > 576)
+ fmt->fmt.pix.height = 576;
+ }
+ return ret;
+}
- /* set sliced VBI output
- In principle the user could request that only certain
- VBI types are output and that the others are ignored.
- I.e., suppress CC in the even fields or only output
- WSS and no VPS. Currently though there is no choice. */
- if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
- return ivtv_get_fmt(itv, streamtype, fmt);
+static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ u32 chromakey = fmt->fmt.win.chromakey;
+ u8 global_alpha = fmt->fmt.win.global_alpha;
- /* any else but sliced VBI capture is an error */
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL;
+ ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
+ fmt->fmt.win.chromakey = chromakey;
+ fmt->fmt.win.global_alpha = global_alpha;
+ return 0;
+}
- if (streamtype == IVTV_DEC_STREAM_TYPE_VBI)
- return ivtv_get_fmt(itv, streamtype, fmt);
+static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
+}
- /* set sliced VBI capture format */
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
+static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct cx2341x_mpeg_params *p = &itv->params;
+ int w = fmt->fmt.pix.width;
+ int h = fmt->fmt.pix.height;
+ int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
- if (vbifmt->service_set)
- ivtv_expand_service_set(vbifmt, itv->is_50hz);
- set = check_service_set(vbifmt, itv->is_50hz);
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
+ if (ret)
+ return ret;
- if (!set_fmt)
+ if (p->width == w && p->height == h)
return 0;
- if (set == 0)
+
+ if (atomic_read(&itv->capturing) > 0)
+ return -EBUSY;
+
+ p->width = w;
+ p->height = h;
+ if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+ fmt->fmt.pix.width /= 2;
+ itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
+ return ivtv_g_fmt_vid_cap(file, fh, fmt);
+}
+
+static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ itv->vbi.sliced_in->service_set = 0;
+ itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
+ return ivtv_g_fmt_vbi_cap(file, fh, fmt);
+}
+
+static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+ if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
+ return ret;
+
+ if (check_service_set(vbifmt, itv->is_50hz) == 0)
return -EINVAL;
- if (atomic_read(&itv->capturing) > 0) {
+ if (atomic_read(&itv->capturing) > 0)
return -EBUSY;
- }
itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
return 0;
}
-static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
+static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
+ struct ivtv_open_id *id = fh;
struct ivtv *itv = id->itv;
- struct v4l2_register *reg = arg;
+ struct yuv_playback_info *yi = &itv->yuv_info;
+ int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
- switch (cmd) {
- /* ioctls to allow direct access to the encoder registers for testing */
- case VIDIOC_DBG_G_REGISTER:
- if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
- return ivtv_itvc(itv, cmd, arg);
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
- return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
- return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
-
- case VIDIOC_DBG_S_REGISTER:
- if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
- return ivtv_itvc(itv, cmd, arg);
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
- return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
- return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
-
- case VIDIOC_G_CHIP_IDENT: {
- struct v4l2_chip_ident *chip = arg;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
- chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
- return 0;
- }
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
- return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
- if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
- return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
- return -EINVAL;
- }
+ if (ret)
+ return ret;
- case VIDIOC_INT_S_AUDIO_ROUTING: {
- struct v4l2_routing *route = arg;
+ if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
+ return 0;
- ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
- break;
- }
+ /* Return now if we already have some frame data */
+ if (yi->stream_size)
+ return -EBUSY;
- case VIDIOC_INT_RESET: {
- u32 val = *(u32 *)arg;
+ yi->v4l2_src_w = fmt->fmt.pix.width;
+ yi->v4l2_src_h = fmt->fmt.pix.height;
- if ((val == 0 && itv->options.newi2c) || (val & 0x01)) {
- ivtv_reset_ir_gpio(itv);
- }
- if (val & 0x02) {
- itv->video_dec_func(itv, cmd, NULL);
- }
+ switch (fmt->fmt.pix.field) {
+ case V4L2_FIELD_NONE:
+ yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
break;
- }
-
+ case V4L2_FIELD_ANY:
+ yi->lace_mode = IVTV_YUV_MODE_AUTO;
+ break;
+ case V4L2_FIELD_INTERLACED_BT:
+ yi->lace_mode =
+ IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
+ break;
+ case V4L2_FIELD_INTERLACED_TB:
default:
- return -EINVAL;
+ yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
+ break;
}
+ yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
+
+ if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
+ itv->dma_data_req_size =
+ 1080 * ((yi->v4l2_src_h + 31) & ~31);
+
+ /* Force update of yuv registers */
+ yi->yuv_forced_update = 1;
return 0;
}
-int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
+static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
{
- struct ivtv_open_id *id = NULL;
- struct yuv_playback_info *yi = &itv->yuv_info;
- u32 data[CX2341X_MBOX_MAX_DATA];
- int streamtype = 0;
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
- if (filp) {
- id = (struct ivtv_open_id *)filp->private_data;
- streamtype = id->type;
+ if (ret == 0) {
+ itv->osd_chroma_key = fmt->fmt.win.chromakey;
+ itv->osd_global_alpha = fmt->fmt.win.global_alpha;
+ ivtv_set_osd_alpha(itv);
}
+ return ret;
+}
- switch (cmd) {
- case VIDIOC_G_PRIORITY:
- {
- enum v4l2_priority *p = arg;
+static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- *p = v4l2_prio_max(&itv->prio);
- break;
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (chip->match_type == V4L2_CHIP_MATCH_HOST) {
+ if (v4l2_chip_match_host(chip->match_type, chip->match_chip))
+ chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
+ return 0;
}
+ if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ return ivtv_i2c_id(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip);
+ if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
+ return ivtv_call_i2c_client(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip);
+ return -EINVAL;
+}
- case VIDIOC_S_PRIORITY:
- {
- enum v4l2_priority *prio = arg;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
+{
+ struct v4l2_register *regs = arg;
+ unsigned long flags;
+ volatile u8 __iomem *reg_start;
- return v4l2_prio_change(&itv->prio, &id->prio, *prio);
- }
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
+ reg_start = itv->reg_mem - IVTV_REG_OFFSET;
+ else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
+ regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
+ reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
+ else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
+ reg_start = itv->enc_mem;
+ else
+ return -EINVAL;
- case VIDIOC_QUERYCAP:{
- struct v4l2_capability *vcap = arg;
+ spin_lock_irqsave(&ivtv_cards_lock, flags);
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ regs->val = readl(regs->reg + reg_start);
+ else
+ writel(regs->val, regs->reg + reg_start);
+ spin_unlock_irqrestore(&ivtv_cards_lock, flags);
+ return 0;
+}
- memset(vcap, 0, sizeof(*vcap));
- strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
- strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
- strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
- vcap->version = IVTV_DRIVER_VERSION; /* version */
- vcap->capabilities = itv->v4l2_cap; /* capabilities */
+static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- /* reserved.. must set to 0! */
- vcap->reserved[0] = vcap->reserved[1] =
- vcap->reserved[2] = vcap->reserved[3] = 0;
- break;
- }
+ if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
+ if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg);
+ return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg);
+}
- case VIDIOC_ENUMAUDIO:{
- struct v4l2_audio *vin = arg;
+static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- return ivtv_get_audio_input(itv, vin->index, vin);
- }
+ if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
+ if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+ return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg);
+ return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg);
+}
+#endif
- case VIDIOC_G_AUDIO:{
- struct v4l2_audio *vin = arg;
+static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- vin->index = itv->audio_input;
- return ivtv_get_audio_input(itv, vin->index, vin);
- }
+ *p = v4l2_prio_max(&itv->prio);
- case VIDIOC_S_AUDIO:{
- struct v4l2_audio *vout = arg;
+ return 0;
+}
- if (vout->index >= itv->nof_audio_inputs)
- return -EINVAL;
- itv->audio_input = vout->index;
- ivtv_audio_set_io(itv);
- break;
- }
+static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
- case VIDIOC_ENUMAUDOUT:{
- struct v4l2_audioout *vin = arg;
+ return v4l2_prio_change(&itv->prio, &id->prio, prio);
+}
- /* set it to defaults from our table */
- return ivtv_get_audio_output(itv, vin->index, vin);
- }
+static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_G_AUDOUT:{
- struct v4l2_audioout *vin = arg;
+ strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
+ strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
+ strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
+ vcap->version = IVTV_DRIVER_VERSION; /* version */
+ vcap->capabilities = itv->v4l2_cap; /* capabilities */
+ return 0;
+}
- vin->index = 0;
- return ivtv_get_audio_output(itv, vin->index, vin);
- }
+static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_S_AUDOUT:{
- struct v4l2_audioout *vout = arg;
+ return ivtv_get_audio_input(itv, vin->index, vin);
+}
- return ivtv_get_audio_output(itv, vout->index, vout);
- }
+static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_ENUMINPUT:{
- struct v4l2_input *vin = arg;
+ vin->index = itv->audio_input;
+ return ivtv_get_audio_input(itv, vin->index, vin);
+}
- /* set it to defaults from our table */
- return ivtv_get_input(itv, vin->index, vin);
- }
+static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_ENUMOUTPUT:{
- struct v4l2_output *vout = arg;
+ if (vout->index >= itv->nof_audio_inputs)
+ return -EINVAL;
- return ivtv_get_output(itv, vout->index, vout);
- }
+ itv->audio_input = vout->index;
+ ivtv_audio_set_io(itv);
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT: {
- struct v4l2_format *fmt = arg;
+ return 0;
+}
- return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
- }
+static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_G_FMT: {
- struct v4l2_format *fmt = arg;
- int type = fmt->type;
+ /* set it to defaults from our table */
+ return ivtv_get_audio_output(itv, vin->index, vin);
+}
- memset(fmt, 0, sizeof(*fmt));
- fmt->type = type;
- return ivtv_get_fmt(itv, id->type, fmt);
- }
+static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_CROPCAP: {
- struct v4l2_cropcap *cropcap = arg;
+ vin->index = 0;
+ return ivtv_get_audio_output(itv, vin->index, vin);
+}
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- cropcap->bounds.height = itv->is_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
- } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- if (yi->track_osd) {
- cropcap->bounds.width = yi->osd_full_w;
- cropcap->bounds.height = yi->osd_full_h;
- } else {
- cropcap->bounds.width = 720;
- cropcap->bounds.height =
- itv->is_out_50hz ? 576 : 480;
- }
- cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ return ivtv_get_audio_output(itv, vout->index, vout);
+}
+
+static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ /* set it to defaults from our table */
+ return ivtv_get_input(itv, vin->index, vin);
+}
+
+static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ return ivtv_get_output(itv, vout->index, vout);
+}
+
+static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct yuv_playback_info *yi = &itv->yuv_info;
+ int streamtype;
+
+ streamtype = id->type;
+
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ return -EINVAL;
+ cropcap->bounds.top = cropcap->bounds.left = 0;
+ cropcap->bounds.width = 720;
+ if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ cropcap->bounds.height = itv->is_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+ } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
+ if (yi->track_osd) {
+ cropcap->bounds.width = yi->osd_full_w;
+ cropcap->bounds.height = yi->osd_full_h;
} else {
- cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+ cropcap->bounds.width = 720;
+ cropcap->bounds.height =
+ itv->is_out_50hz ? 576 : 480;
}
- cropcap->defrect = cropcap->bounds;
- return 0;
+ cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+ } else {
+ cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
+ cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+ cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
}
+ cropcap->defrect = cropcap->bounds;
+ return 0;
+}
+
+static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct yuv_playback_info *yi = &itv->yuv_info;
+ int streamtype;
- case VIDIOC_S_CROP: {
- struct v4l2_crop *crop = arg;
+ streamtype = id->type;
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- yi->main_rect = crop->c;
+ if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
+ printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
+ /* Should be replaced */
+ /* v4l_printk_ioctl(VIDIOC_S_CROP); */
+ }
+
+ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+ if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
+ yi->main_rect = crop->c;
+ return 0;
+ } else {
+ if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+ crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
+ itv->main_rect = crop->c;
return 0;
- } else {
- if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
- itv->main_rect = crop->c;
- return 0;
- }
}
- return -EINVAL;
}
return -EINVAL;
}
+ return -EINVAL;
+}
- case VIDIOC_G_CROP: {
- struct v4l2_crop *crop = arg;
+static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct yuv_playback_info *yi = &itv->yuv_info;
+ int streamtype;
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
- crop->c = yi->main_rect;
- else
- crop->c = itv->main_rect;
- return 0;
+ streamtype = id->type;
+
+ if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+ if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
+ crop->c = yi->main_rect;
+ else
+ crop->c = itv->main_rect;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
+{
+ static struct v4l2_fmtdesc formats[] = {
+ { 0, 0, 0,
+ "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
+ { 0, 0, 0, 0 }
+ },
+ { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
+ "MPEG", V4L2_PIX_FMT_MPEG,
+ { 0, 0, 0, 0 }
}
+ };
+ enum v4l2_buf_type type = fmt->type;
+
+ if (fmt->index > 1)
return -EINVAL;
- }
- case VIDIOC_ENUM_FMT: {
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
- };
- struct v4l2_fmtdesc *fmt = arg;
- enum v4l2_buf_type type = fmt->type;
+ *fmt = formats[fmt->index];
+ fmt->type = type;
+ return 0;
+}
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- break;
- default:
- return -EINVAL;
+static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ static struct v4l2_fmtdesc formats[] = {
+ { 0, 0, 0,
+ "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
+ { 0, 0, 0, 0 }
+ },
+ { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
+ "MPEG", V4L2_PIX_FMT_MPEG,
+ { 0, 0, 0, 0 }
}
- if (fmt->index > 1)
- return -EINVAL;
- *fmt = formats[fmt->index];
- fmt->type = type;
+ };
+ enum v4l2_buf_type type = fmt->type;
+
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+ return -EINVAL;
+
+ if (fmt->index > 1)
+ return -EINVAL;
+
+ *fmt = formats[fmt->index];
+ fmt->type = type;
+
+ return 0;
+}
+
+static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ *i = itv->active_input;
+
+ return 0;
+}
+
+int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ if (inp < 0 || inp >= itv->nof_inputs)
+ return -EINVAL;
+
+ if (inp == itv->active_input) {
+ IVTV_DEBUG_INFO("Input unchanged\n");
return 0;
}
- case VIDIOC_G_INPUT:{
- *(int *)arg = itv->active_input;
- break;
+ if (atomic_read(&itv->capturing) > 0) {
+ return -EBUSY;
}
- case VIDIOC_S_INPUT:{
- int inp = *(int *)arg;
+ IVTV_DEBUG_INFO("Changing input from %d to %d\n",
+ itv->active_input, inp);
- if (inp < 0 || inp >= itv->nof_inputs)
- return -EINVAL;
+ itv->active_input = inp;
+ /* Set the audio input to whatever is appropriate for the
+ input type. */
+ itv->audio_input = itv->card->video_inputs[inp].audio_index;
- if (inp == itv->active_input) {
- IVTV_DEBUG_INFO("Input unchanged\n");
- break;
- }
- if (atomic_read(&itv->capturing) > 0) {
- return -EBUSY;
- }
- IVTV_DEBUG_INFO("Changing input from %d to %d\n",
- itv->active_input, inp);
+ /* prevent others from messing with the streams until
+ we're finished changing inputs. */
+ ivtv_mute(itv);
+ ivtv_video_set_io(itv);
+ ivtv_audio_set_io(itv);
+ ivtv_unmute(itv);
- itv->active_input = inp;
- /* Set the audio input to whatever is appropriate for the
- input type. */
- itv->audio_input = itv->card->video_inputs[inp].audio_index;
+ return 0;
+}
- /* prevent others from messing with the streams until
- we're finished changing inputs. */
- ivtv_mute(itv);
- ivtv_video_set_io(itv);
- ivtv_audio_set_io(itv);
- ivtv_unmute(itv);
- break;
- }
+static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_G_OUTPUT:{
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- *(int *)arg = itv->active_output;
- break;
- }
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+ return -EINVAL;
- case VIDIOC_S_OUTPUT:{
- int outp = *(int *)arg;
- struct v4l2_routing route;
+ *i = itv->active_output;
- if (outp >= itv->card->nof_outputs)
- return -EINVAL;
+ return 0;
+}
- if (outp == itv->active_output) {
- IVTV_DEBUG_INFO("Output unchanged\n");
- break;
- }
- IVTV_DEBUG_INFO("Changing output from %d to %d\n",
- itv->active_output, outp);
+static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_routing route;
- itv->active_output = outp;
- route.input = SAA7127_INPUT_TYPE_NORMAL;
- route.output = itv->card->video_outputs[outp].video_output;
- ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
- break;
+ if (outp >= itv->card->nof_outputs)
+ return -EINVAL;
+
+ if (outp == itv->active_output) {
+ IVTV_DEBUG_INFO("Output unchanged\n");
+ return 0;
}
+ IVTV_DEBUG_INFO("Changing output from %d to %d\n",
+ itv->active_output, outp);
- case VIDIOC_G_FREQUENCY:{
- struct v4l2_frequency *vf = arg;
+ itv->active_output = outp;
+ route.input = SAA7127_INPUT_TYPE_NORMAL;
+ route.output = itv->card->video_outputs[outp].video_output;
+ ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
- if (vf->tuner != 0)
- return -EINVAL;
- ivtv_call_i2c_clients(itv, cmd, arg);
- break;
- }
+ return 0;
+}
- case VIDIOC_S_FREQUENCY:{
- struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
+static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- if (vf.tuner != 0)
- return -EINVAL;
+ if (vf->tuner != 0)
+ return -EINVAL;
- ivtv_mute(itv);
- IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
- ivtv_call_i2c_clients(itv, cmd, &vf);
- ivtv_unmute(itv);
- break;
- }
+ ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf);
+ return 0;
+}
- case VIDIOC_ENUMSTD:{
- struct v4l2_standard *vs = arg;
- int idx = vs->index;
+int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
- return -EINVAL;
+ if (vf->tuner != 0)
+ return -EINVAL;
- *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
- ivtv_std_60hz : ivtv_std_50hz;
- vs->index = idx;
- vs->id = enum_stds[idx].std;
- strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
- break;
- }
+ ivtv_mute(itv);
+ IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
+ ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf);
+ ivtv_unmute(itv);
+ return 0;
+}
- case VIDIOC_G_STD:{
- *(v4l2_std_id *) arg = itv->std;
- break;
- }
+static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- case VIDIOC_S_STD: {
- v4l2_std_id std = *(v4l2_std_id *) arg;
+ *std = itv->std;
+ return 0;
+}
- if ((std & V4L2_STD_ALL) == 0)
- return -EINVAL;
+int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct yuv_playback_info *yi = &itv->yuv_info;
- if (std == itv->std)
- break;
+ if ((*std & V4L2_STD_ALL) == 0)
+ return -EINVAL;
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
- atomic_read(&itv->capturing) > 0 ||
- atomic_read(&itv->decoding) > 0) {
- /* Switching standard would turn off the radio or mess
- with already running streams, prevent that by
- returning EBUSY. */
- return -EBUSY;
- }
+ if (*std == itv->std)
+ return 0;
- itv->std = std;
- itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
- itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
- itv->params.width = 720;
- itv->params.height = itv->is_50hz ? 576 : 480;
- itv->vbi.count = itv->is_50hz ? 18 : 12;
- itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
- itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
- if (itv->hw_flags & IVTV_HW_CX25840) {
- itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
- }
- IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
-
- /* Tuner */
- ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- /* set display standard */
- itv->std_out = std;
- itv->is_out_60hz = itv->is_60hz;
- itv->is_out_50hz = itv->is_50hz;
- ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
- ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
- itv->main_rect.left = itv->main_rect.top = 0;
- itv->main_rect.width = 720;
- itv->main_rect.height = itv->params.height;
- ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- 720, itv->main_rect.height, 0, 0);
- yi->main_rect = itv->main_rect;
- if (!itv->osd_info) {
- yi->osd_full_w = 720;
- yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
- }
+ if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
+ atomic_read(&itv->capturing) > 0 ||
+ atomic_read(&itv->decoding) > 0) {
+ /* Switching standard would turn off the radio or mess
+ with already running streams, prevent that by
+ returning EBUSY. */
+ return -EBUSY;
+ }
+
+ itv->std = *std;
+ itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
+ itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
+ itv->params.width = 720;
+ itv->params.height = itv->is_50hz ? 576 : 480;
+ itv->vbi.count = itv->is_50hz ? 18 : 12;
+ itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
+ itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
+
+ if (itv->hw_flags & IVTV_HW_CX25840)
+ itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
+
+ IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
+
+ /* Tuner */
+ ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
+
+ if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+ /* set display standard */
+ itv->std_out = *std;
+ itv->is_out_60hz = itv->is_60hz;
+ itv->is_out_50hz = itv->is_50hz;
+ ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
+ ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
+ itv->main_rect.left = itv->main_rect.top = 0;
+ itv->main_rect.width = 720;
+ itv->main_rect.height = itv->params.height;
+ ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+ 720, itv->main_rect.height, 0, 0);
+ yi->main_rect = itv->main_rect;
+ if (!itv->osd_info) {
+ yi->osd_full_w = 720;
+ yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
}
- break;
}
+ return 0;
+}
- case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
- struct v4l2_tuner *vt = arg;
+static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
- if (vt->index != 0)
- return -EINVAL;
+ if (vt->index != 0)
+ return -EINVAL;
- ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
- break;
- }
+ ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
- case VIDIOC_G_TUNER: {
- struct v4l2_tuner *vt = arg;
+ return 0;
+}
- if (vt->index != 0)
- return -EINVAL;
+static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- memset(vt, 0, sizeof(*vt));
- ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
+ if (vt->index != 0)
+ return -EINVAL;
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
- strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_RADIO;
- } else {
- strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_ANALOG_TV;
- }
- break;
+ ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
+
+ if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+ strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
+ vt->type = V4L2_TUNER_RADIO;
+ } else {
+ strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
+ vt->type = V4L2_TUNER_ANALOG_TV;
}
- case VIDIOC_G_SLICED_VBI_CAP: {
- struct v4l2_sliced_vbi_cap *cap = arg;
- int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
- int f, l;
- enum v4l2_buf_type type = cap->type;
-
- memset(cap, 0, sizeof(*cap));
- cap->type = type;
- if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- if (valid_service_line(f, l, itv->is_50hz)) {
- cap->service_lines[f][l] = set;
- }
- }
+ return 0;
+}
+
+static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+ int f, l;
+
+ if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ if (valid_service_line(f, l, itv->is_50hz))
+ cap->service_lines[f][l] = set;
}
- return 0;
}
- if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
- if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
- return -EINVAL;
- if (itv->is_60hz) {
- cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- } else {
- cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
- cap->service_lines[0][16] = V4L2_SLICED_VPS;
- }
- return 0;
+ return 0;
+ }
+ if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
+ if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
+ return -EINVAL;
+ if (itv->is_60hz) {
+ cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+ cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+ } else {
+ cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
+ cap->service_lines[0][16] = V4L2_SLICED_VPS;
}
- return -EINVAL;
+ return 0;
}
+ return -EINVAL;
+}
- case VIDIOC_G_ENC_INDEX: {
- struct v4l2_enc_idx *idx = arg;
- struct v4l2_enc_idx_entry *e = idx->entry;
- int entries;
- int i;
-
- entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
- IVTV_MAX_PGM_INDEX;
- if (entries > V4L2_ENC_IDX_ENTRIES)
- entries = V4L2_ENC_IDX_ENTRIES;
- idx->entries = 0;
- for (i = 0; i < entries; i++) {
- *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
- if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
- idx->entries++;
- e++;
- }
+static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_enc_idx_entry *e = idx->entry;
+ int entries;
+ int i;
+
+ entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
+ IVTV_MAX_PGM_INDEX;
+ if (entries > V4L2_ENC_IDX_ENTRIES)
+ entries = V4L2_ENC_IDX_ENTRIES;
+ idx->entries = 0;
+ for (i = 0; i < entries; i++) {
+ *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
+ if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
+ idx->entries++;
+ e++;
}
- itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
- break;
}
+ itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
+ return 0;
+}
- case VIDIOC_ENCODER_CMD:
- case VIDIOC_TRY_ENCODER_CMD: {
- struct v4l2_encoder_cmd *enc = arg;
- int try = cmd == VIDIOC_TRY_ENCODER_CMD;
-
- memset(&enc->raw, 0, sizeof(enc->raw));
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- if (try)
- return 0;
- return ivtv_start_capture(id);
+static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
- case V4L2_ENC_CMD_STOP:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- if (try)
- return 0;
- ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
+
+ switch (enc->cmd) {
+ case V4L2_ENC_CMD_START:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
+ enc->flags = 0;
+ return ivtv_start_capture(id);
+
+ case V4L2_ENC_CMD_STOP:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
+ enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
+ ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
+ return 0;
+
+ case V4L2_ENC_CMD_PAUSE:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
+ enc->flags = 0;
+
+ if (!atomic_read(&itv->capturing))
+ return -EPERM;
+ if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
return 0;
- case V4L2_ENC_CMD_PAUSE:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- if (try)
- return 0;
- if (!atomic_read(&itv->capturing))
- return -EPERM;
- if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- return 0;
- ivtv_mute(itv);
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
- break;
+ ivtv_mute(itv);
+ ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
+ break;
- case V4L2_ENC_CMD_RESUME:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- if (try)
- return 0;
- if (!atomic_read(&itv->capturing))
- return -EPERM;
- if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- return 0;
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
- ivtv_unmute(itv);
- break;
- default:
- IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
+ case V4L2_ENC_CMD_RESUME:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
+ enc->flags = 0;
+
+ if (!atomic_read(&itv->capturing))
+ return -EPERM;
+
+ if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
+ return 0;
+
+ ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
+ ivtv_unmute(itv);
break;
+ default:
+ IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
+ return -EINVAL;
}
- case VIDIOC_G_FBUF: {
- struct v4l2_framebuffer *fb = arg;
- int pixfmt;
- static u32 pixel_format[16] = {
- V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
- V4L2_PIX_FMT_RGB565,
- V4L2_PIX_FMT_RGB555,
- V4L2_PIX_FMT_RGB444,
- V4L2_PIX_FMT_RGB32,
- 0,
- 0,
- 0,
- V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
- V4L2_PIX_FMT_YUV565,
- V4L2_PIX_FMT_YUV555,
- V4L2_PIX_FMT_YUV444,
- V4L2_PIX_FMT_YUV32,
- 0,
- 0,
- 0,
- };
+ return 0;
+}
- memset(fb, 0, sizeof(*fb));
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
- V4L2_FBUF_CAP_GLOBAL_ALPHA;
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
- data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
- pixfmt = (data[0] >> 3) & 0xf;
- fb->fmt.pixelformat = pixel_format[pixfmt];
- fb->fmt.width = itv->osd_rect.width;
- fb->fmt.height = itv->osd_rect.height;
- fb->base = (void *)itv->osd_video_pbase;
- if (itv->osd_chroma_key_state)
- fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
- if (itv->osd_global_alpha_state)
- fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
- pixfmt &= 7;
- /* no local alpha for RGB565 or unknown formats */
- if (pixfmt == 1 || pixfmt > 4)
- break;
+static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+ switch (enc->cmd) {
+ case V4L2_ENC_CMD_START:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
+ enc->flags = 0;
+ return 0;
+
+ case V4L2_ENC_CMD_STOP:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
+ enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
+ return 0;
+
+ case V4L2_ENC_CMD_PAUSE:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
+ enc->flags = 0;
+ return 0;
+
+ case V4L2_ENC_CMD_RESUME:
+ IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
+ enc->flags = 0;
+ return 0;
+ default:
+ IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
+ return -EINVAL;
+ }
+}
+
+static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ u32 data[CX2341X_MBOX_MAX_DATA];
+ struct yuv_playback_info *yi = &itv->yuv_info;
+
+ int pixfmt;
+ static u32 pixel_format[16] = {
+ V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
+ V4L2_PIX_FMT_RGB565,
+ V4L2_PIX_FMT_RGB555,
+ V4L2_PIX_FMT_RGB444,
+ V4L2_PIX_FMT_RGB32,
+ 0,
+ 0,
+ 0,
+ V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
+ V4L2_PIX_FMT_YUV565,
+ V4L2_PIX_FMT_YUV555,
+ V4L2_PIX_FMT_YUV444,
+ V4L2_PIX_FMT_YUV32,
+ 0,
+ 0,
+ 0,
+ };
+
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+ return -EINVAL;
+ if (!itv->osd_video_pbase)
+ return -EINVAL;
+
+ fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
+ V4L2_FBUF_CAP_GLOBAL_ALPHA;
+
+ ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+ data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
+ pixfmt = (data[0] >> 3) & 0xf;
+
+ fb->fmt.pixelformat = pixel_format[pixfmt];
+ fb->fmt.width = itv->osd_rect.width;
+ fb->fmt.height = itv->osd_rect.height;
+ fb->fmt.field = V4L2_FIELD_INTERLACED;
+ fb->fmt.bytesperline = fb->fmt.width;
+ fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ fb->fmt.field = V4L2_FIELD_INTERLACED;
+ fb->fmt.priv = 0;
+ if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
+ fb->fmt.bytesperline *= 2;
+ if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
+ fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
+ fb->fmt.bytesperline *= 2;
+ fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
+ fb->base = (void *)itv->osd_video_pbase;
+ fb->flags = 0;
+
+ if (itv->osd_chroma_key_state)
+ fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
+
+ if (itv->osd_global_alpha_state)
+ fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
+
+ pixfmt &= 7;
+
+ /* no local alpha for RGB565 or unknown formats */
+ if (pixfmt == 1 || pixfmt > 4)
+ return 0;
+
+ /* 16-bit formats have inverted local alpha */
+ if (pixfmt == 2 || pixfmt == 3)
+ fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
+ else
+ fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
+
+ if (itv->osd_local_alpha_state) {
/* 16-bit formats have inverted local alpha */
if (pixfmt == 2 || pixfmt == 3)
- fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
+ fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
else
- fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
- if (itv->osd_local_alpha_state) {
- /* 16-bit formats have inverted local alpha */
- if (pixfmt == 2 || pixfmt == 3)
- fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
- else
- fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
- }
- if (yi->track_osd)
- fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
- break;
+ fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
}
+ if (yi->track_osd)
+ fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
- case VIDIOC_S_FBUF: {
- struct v4l2_framebuffer *fb = arg;
+ return 0;
+}
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
- itv->osd_local_alpha_state =
- (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
- itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
- ivtv_set_osd_alpha(itv);
- yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
- break;
- }
+static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
+ struct yuv_playback_info *yi = &itv->yuv_info;
- case VIDIOC_OVERLAY: {
- int *on = arg;
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+ return -EINVAL;
+ if (!itv->osd_video_pbase)
+ return -EINVAL;
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
- break;
- }
+ itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
+ itv->osd_local_alpha_state =
+ (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
+ itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
+ ivtv_set_osd_alpha(itv);
+ yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
+ return ivtv_g_fbuf(file, fh, fb);
+}
- case VIDIOC_LOG_STATUS:
- {
- int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
- struct v4l2_input vidin;
- struct v4l2_audio audin;
- int i;
+static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
+{
+ struct ivtv_open_id *id = fh;
+ struct ivtv *itv = id->itv;
- IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
- IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
- if (itv->hw_flags & IVTV_HW_TVEEPROM) {
- struct tveeprom tv;
+ if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+ return -EINVAL;
- ivtv_read_eeprom(itv, &tv);
- }
- ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
- ivtv_get_input(itv, itv->active_input, &vidin);
- ivtv_get_audio_input(itv, itv->audio_input, &audin);
- IVTV_INFO("Video Input: %s\n", vidin.name);
- IVTV_INFO("Audio Input: %s%s\n", audin.name,
- (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
- if (has_output) {
- struct v4l2_output vidout;
- struct v4l2_audioout audout;
- int mode = itv->output_mode;
- static const char * const output_modes[5] = {
- "None",
- "MPEG Streaming",
- "YUV Streaming",
- "YUV Frames",
- "Passthrough",
- };
- static const char * const audio_modes[5] = {
- "Stereo",
- "Left",
- "Right",
- "Mono",
- "Swapped"
- };
- static const char * const alpha_mode[4] = {
- "None",
- "Global",
- "Local",
- "Global and Local"
- };
- static const char * const pixel_format[16] = {
- "ARGB Indexed",
- "RGB 5:6:5",
- "ARGB 1:5:5:5",
- "ARGB 1:4:4:4",
- "ARGB 8:8:8:8",
- "5",
- "6",
- "7",
- "AYUV Indexed",
- "YUV 5:6:5",
- "AYUV 1:5:5:5",
- "AYUV 1:4:4:4",
- "AYUV 8:8:8:8",
- "13",
- "14",
- "15",
- };
-
- ivtv_get_output(itv, itv->active_output, &vidout);
- ivtv_get_audio_output(itv, 0, &audout);
- IVTV_INFO("Video Output: %s\n", vidout.name);
- IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
- audio_modes[itv->audio_stereo_mode],
- audio_modes[itv->audio_bilingual_mode]);
- if (mode < 0 || mode > OUT_PASSTHROUGH)
- mode = OUT_NONE;
- IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
- data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
- IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
- data[0] & 1 ? "On" : "Off",
- alpha_mode[(data[0] >> 1) & 0x3],
- pixel_format[(data[0] >> 3) & 0xf]);
- }
- IVTV_INFO("Tuner: %s\n",
- test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
- cx2341x_log_status(&itv->params, itv->name);
- IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- struct ivtv_stream *s = &itv->streams[i];
-
- if (s->v4l2dev == NULL || s->buffers == 0)
- continue;
- IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
- (s->buffers - s->q_free.buffers) * 100 / s->buffers,
- (s->buffers * s->buf_size) / 1024, s->buffers);
- }
- IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
- IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
- break;
+ ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
+
+ return 0;
+}
+
+static int ivtv_log_status(struct file *file, void *fh)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ u32 data[CX2341X_MBOX_MAX_DATA];
+
+ int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
+ struct v4l2_input vidin;
+ struct v4l2_audio audin;
+ int i;
+
+ IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
+ IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
+ if (itv->hw_flags & IVTV_HW_TVEEPROM) {
+ struct tveeprom tv;
+
+ ivtv_read_eeprom(itv, &tv);
+ }
+ ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
+ ivtv_get_input(itv, itv->active_input, &vidin);
+ ivtv_get_audio_input(itv, itv->audio_input, &audin);
+ IVTV_INFO("Video Input: %s\n", vidin.name);
+ IVTV_INFO("Audio Input: %s%s\n", audin.name,
+ (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
+ if (has_output) {
+ struct v4l2_output vidout;
+ struct v4l2_audioout audout;
+ int mode = itv->output_mode;
+ static const char * const output_modes[5] = {
+ "None",
+ "MPEG Streaming",
+ "YUV Streaming",
+ "YUV Frames",
+ "Passthrough",
+ };
+ static const char * const audio_modes[5] = {
+ "Stereo",
+ "Left",
+ "Right",
+ "Mono",
+ "Swapped"
+ };
+ static const char * const alpha_mode[4] = {
+ "None",
+ "Global",
+ "Local",
+ "Global and Local"
+ };
+ static const char * const pixel_format[16] = {
+ "ARGB Indexed",
+ "RGB 5:6:5",
+ "ARGB 1:5:5:5",
+ "ARGB 1:4:4:4",
+ "ARGB 8:8:8:8",
+ "5",
+ "6",
+ "7",
+ "AYUV Indexed",
+ "YUV 5:6:5",
+ "AYUV 1:5:5:5",
+ "AYUV 1:4:4:4",
+ "AYUV 8:8:8:8",
+ "13",
+ "14",
+ "15",
+ };
+
+ ivtv_get_output(itv, itv->active_output, &vidout);
+ ivtv_get_audio_output(itv, 0, &audout);
+ IVTV_INFO("Video Output: %s\n", vidout.name);
+ IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
+ audio_modes[itv->audio_stereo_mode],
+ audio_modes[itv->audio_bilingual_mode]);
+ if (mode < 0 || mode > OUT_PASSTHROUGH)
+ mode = OUT_NONE;
+ IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
+ ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+ data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
+ IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
+ data[0] & 1 ? "On" : "Off",
+ alpha_mode[(data[0] >> 1) & 0x3],
+ pixel_format[(data[0] >> 3) & 0xf]);
}
+ IVTV_INFO("Tuner: %s\n",
+ test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
+ cx2341x_log_status(&itv->params, itv->name);
+ IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
+ for (i = 0; i < IVTV_MAX_STREAMS; i++) {
+ struct ivtv_stream *s = &itv->streams[i];
- default:
- return -EINVAL;
+ if (s->v4l2dev == NULL || s->buffers == 0)
+ continue;
+ IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
+ (s->buffers - s->q_free.buffers) * 100 / s->buffers,
+ (s->buffers * s->buf_size) / 1024, s->buffers);
}
+
+ IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
+ IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
+
return 0;
}
@@ -1433,7 +1548,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
return -EINVAL;
if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
return 0;
- if (ivtv_claim_stream(id, id->type)) {
+ if (ivtv_start_decoding(id, id->type)) {
return -EBUSY;
}
if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
@@ -1607,121 +1722,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
return 0;
}
-static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, void *arg)
+static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
{
- struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
- struct ivtv *itv = id->itv;
- int ret;
-
- /* check priority */
- switch (cmd) {
- case VIDIOC_S_CTRL:
- case VIDIOC_S_STD:
- case VIDIOC_S_INPUT:
- case VIDIOC_S_OUTPUT:
- case VIDIOC_S_TUNER:
- case VIDIOC_S_FREQUENCY:
- case VIDIOC_S_FMT:
- case VIDIOC_S_CROP:
- case VIDIOC_S_AUDIO:
- case VIDIOC_S_AUDOUT:
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_S_FBUF:
- case VIDIOC_OVERLAY:
- ret = v4l2_prio_check(&itv->prio, &id->prio);
- if (ret)
- return ret;
- }
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
switch (cmd) {
- case VIDIOC_DBG_G_REGISTER:
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_G_CHIP_IDENT:
- case VIDIOC_INT_S_AUDIO_ROUTING:
- case VIDIOC_INT_RESET:
- if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
- printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
- v4l_printk_ioctl(cmd);
- printk("\n");
- }
- return ivtv_debug_ioctls(filp, cmd, arg);
+ case VIDIOC_INT_S_AUDIO_ROUTING: {
+ struct v4l2_routing *route = arg;
- case VIDIOC_G_PRIORITY:
- case VIDIOC_S_PRIORITY:
- case VIDIOC_QUERYCAP:
- case VIDIOC_ENUMINPUT:
- case VIDIOC_G_INPUT:
- case VIDIOC_S_INPUT:
- case VIDIOC_ENUMOUTPUT:
- case VIDIOC_G_OUTPUT:
- case VIDIOC_S_OUTPUT:
- case VIDIOC_G_FMT:
- case VIDIOC_S_FMT:
- case VIDIOC_TRY_FMT:
- case VIDIOC_ENUM_FMT:
- case VIDIOC_CROPCAP:
- case VIDIOC_G_CROP:
- case VIDIOC_S_CROP:
- case VIDIOC_G_FREQUENCY:
- case VIDIOC_S_FREQUENCY:
- case VIDIOC_ENUMSTD:
- case VIDIOC_G_STD:
- case VIDIOC_S_STD:
- case VIDIOC_S_TUNER:
- case VIDIOC_G_TUNER:
- case VIDIOC_ENUMAUDIO:
- case VIDIOC_S_AUDIO:
- case VIDIOC_G_AUDIO:
- case VIDIOC_ENUMAUDOUT:
- case VIDIOC_S_AUDOUT:
- case VIDIOC_G_AUDOUT:
- case VIDIOC_G_SLICED_VBI_CAP:
- case VIDIOC_LOG_STATUS:
- case VIDIOC_G_ENC_INDEX:
- case VIDIOC_ENCODER_CMD:
- case VIDIOC_TRY_ENCODER_CMD:
- case VIDIOC_G_FBUF:
- case VIDIOC_S_FBUF:
- case VIDIOC_OVERLAY:
- if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
- printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
- v4l_printk_ioctl(cmd);
- printk("\n");
- }
- return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
+ ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
+ break;
+ }
- case VIDIOC_QUERYMENU:
- case VIDIOC_QUERYCTRL:
- case VIDIOC_S_CTRL:
- case VIDIOC_G_CTRL:
- case VIDIOC_S_EXT_CTRLS:
- case VIDIOC_G_EXT_CTRLS:
- case VIDIOC_TRY_EXT_CTRLS:
- if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
- printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
- v4l_printk_ioctl(cmd);
- printk("\n");
- }
- return ivtv_control_ioctls(itv, cmd, arg);
+ case VIDIOC_INT_RESET: {
+ u32 val = *(u32 *)arg;
- case IVTV_IOC_DMA_FRAME:
- case VIDEO_GET_PTS:
- case VIDEO_GET_FRAME_COUNT:
- case VIDEO_GET_EVENT:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND:
- return ivtv_decoder_ioctls(filp, cmd, arg);
+ if ((val == 0 && itv->options.newi2c) || (val & 0x01))
+ ivtv_reset_ir_gpio(itv);
+ if (val & 0x02)
+ itv->video_dec_func(itv, cmd, NULL);
+ break;
+ }
- case 0x00005401: /* Handle isatty() calls */
- return -EINVAL;
default:
- return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
- ivtv_v4l2_do_ioctl);
+ return -EINVAL;
}
return 0;
}
@@ -1729,7 +1753,11 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
- /* Filter dvb ioctls that cannot be handled by video_usercopy */
+ struct video_device *vfd = video_devdata(filp);
+ struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
+ int ret;
+
+ /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */
switch (cmd) {
case VIDEO_SELECT_SOURCE:
IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
@@ -1758,10 +1786,47 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
return 0;
+ case IVTV_IOC_DMA_FRAME:
+ case VIDEO_GET_PTS:
+ case VIDEO_GET_FRAME_COUNT:
+ case VIDEO_GET_EVENT:
+ case VIDEO_PLAY:
+ case VIDEO_STOP:
+ case VIDEO_FREEZE:
+ case VIDEO_CONTINUE:
+ case VIDEO_COMMAND:
+ case VIDEO_TRY_COMMAND:
+ return ivtv_decoder_ioctls(filp, cmd, (void *)arg);
+
default:
break;
}
- return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
+
+ /* check priority */
+ switch (cmd) {
+ case VIDIOC_S_CTRL:
+ case VIDIOC_S_STD:
+ case VIDIOC_S_INPUT:
+ case VIDIOC_S_OUTPUT:
+ case VIDIOC_S_TUNER:
+ case VIDIOC_S_FREQUENCY:
+ case VIDIOC_S_FMT:
+ case VIDIOC_S_CROP:
+ case VIDIOC_S_AUDIO:
+ case VIDIOC_S_AUDOUT:
+ case VIDIOC_S_EXT_CTRLS:
+ case VIDIOC_S_FBUF:
+ case VIDIOC_OVERLAY:
+ ret = v4l2_prio_check(&itv->prio, &id->prio);
+ if (ret)
+ return ret;
+ }
+
+ if (ivtv_debug & IVTV_DBGFLG_IOCTL)
+ vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
+ ret = video_ioctl2(inode, filp, cmd, arg);
+ vfd->debug = 0;
+ return ret;
}
int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -1776,3 +1841,70 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
mutex_unlock(&itv->serialize_lock);
return res;
}
+
+void ivtv_set_funcs(struct video_device *vdev)
+{
+ vdev->vidioc_querycap = ivtv_querycap;
+ vdev->vidioc_g_priority = ivtv_g_priority;
+ vdev->vidioc_s_priority = ivtv_s_priority;
+ vdev->vidioc_s_audio = ivtv_s_audio;
+ vdev->vidioc_g_audio = ivtv_g_audio;
+ vdev->vidioc_enumaudio = ivtv_enumaudio;
+ vdev->vidioc_s_audout = ivtv_s_audout;
+ vdev->vidioc_g_audout = ivtv_g_audout;
+ vdev->vidioc_enum_input = ivtv_enum_input;
+ vdev->vidioc_enum_output = ivtv_enum_output;
+ vdev->vidioc_enumaudout = ivtv_enumaudout;
+ vdev->vidioc_cropcap = ivtv_cropcap;
+ vdev->vidioc_s_crop = ivtv_s_crop;
+ vdev->vidioc_g_crop = ivtv_g_crop;
+ vdev->vidioc_g_input = ivtv_g_input;
+ vdev->vidioc_s_input = ivtv_s_input;
+ vdev->vidioc_g_output = ivtv_g_output;
+ vdev->vidioc_s_output = ivtv_s_output;
+ vdev->vidioc_g_frequency = ivtv_g_frequency;
+ vdev->vidioc_s_frequency = ivtv_s_frequency;
+ vdev->vidioc_s_tuner = ivtv_s_tuner;
+ vdev->vidioc_g_tuner = ivtv_g_tuner;
+ vdev->vidioc_g_enc_index = ivtv_g_enc_index;
+ vdev->vidioc_g_fbuf = ivtv_g_fbuf;
+ vdev->vidioc_s_fbuf = ivtv_s_fbuf;
+ vdev->vidioc_g_std = ivtv_g_std;
+ vdev->vidioc_s_std = ivtv_s_std;
+ vdev->vidioc_overlay = ivtv_overlay;
+ vdev->vidioc_log_status = ivtv_log_status;
+ vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap;
+ vdev->vidioc_encoder_cmd = ivtv_encoder_cmd;
+ vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd;
+ vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out;
+ vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap;
+ vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap;
+ vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap;
+ vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out;
+ vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay;
+ vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out;
+ vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap;
+ vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap;
+ vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap;
+ vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out;
+ vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay;
+ vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out;
+ vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap;
+ vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap;
+ vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap;
+ vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out;
+ vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay;
+ vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out;
+ vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap;
+ vdev->vidioc_g_chip_ident = ivtv_g_chip_ident;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ vdev->vidioc_g_register = ivtv_g_register;
+ vdev->vidioc_s_register = ivtv_s_register;
+#endif
+ vdev->vidioc_default = ivtv_default;
+ vdev->vidioc_queryctrl = ivtv_queryctrl;
+ vdev->vidioc_querymenu = ivtv_querymenu;
+ vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls;
+ vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls;
+ vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls;
+}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
index 4e67f0ed1fc..70188588b4f 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ b/drivers/media/video/ivtv/ivtv-ioctl.h
@@ -24,10 +24,13 @@
u16 ivtv_service2vbi(int type);
void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg);
-int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
void ivtv_set_osd_alpha(struct ivtv *itv);
int ivtv_set_speed(struct ivtv *itv, int speed);
+void ivtv_set_funcs(struct video_device *vdev);
+int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std);
+int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
+int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
+int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+ unsigned long arg);
#endif
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index c854285a437..f8883b487f4 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
s->v4l2dev->dev = &itv->dev->dev;
s->v4l2dev->fops = ivtv_stream_info[type].fops;
s->v4l2dev->release = video_device_release;
-
+ s->v4l2dev->tvnorms = V4L2_STD_ALL;
+ ivtv_set_funcs(s->v4l2dev);
return 0;
}
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 73be154f7f0..bdfda48e56b 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -367,6 +367,88 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
}
+static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ void *dst;
+ int err = 0;
+ unsigned long total_size;
+ struct ivtv *itv = (struct ivtv *) info->par;
+ unsigned long dma_offset =
+ IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
+ unsigned long dma_size;
+ u16 lead = 0, tail = 0;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ dst = (void __force *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ if (!access_ok(VERIFY_READ, buf, count)) {
+ IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
+ (unsigned long)buf);
+ err = -EFAULT;
+ }
+
+ if (!err) {
+ /* If transfer size > threshold and both src/dst
+ addresses are aligned, use DMA */
+ if (count >= 4096 &&
+ ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
+ /* Odd address = can't DMA. Align */
+ if ((unsigned long)dst & 3) {
+ lead = 4 - ((unsigned long)dst & 3);
+ memcpy(dst, buf, lead);
+ buf += lead;
+ dst += lead;
+ }
+ /* DMA resolution is 32 bits */
+ if ((count - lead) & 3)
+ tail = (count - lead) & 3;
+ /* DMA the data */
+ dma_size = count - lead - tail;
+ err = ivtvfb_prep_dec_dma_to_device(itv,
+ p + lead + dma_offset, (void *)buf, dma_size);
+ dst += dma_size;
+ buf += dma_size;
+ /* Copy any leftover data */
+ if (tail)
+ memcpy(dst, buf, tail);
+ } else {
+ memcpy(dst, buf, count);
+ }
+ }
+
+ if (!err)
+ *ppos += count;
+
+ return (err) ? err : count;
+}
+
static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
DEFINE_WAIT(wait);
@@ -708,6 +790,9 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
else
var->pixclock = pixclock;
+ itv->osd_rect.width = var->xres;
+ itv->osd_rect.height = var->yres;
+
IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
var->xres, var->yres,
var->xres_virtual, var->yres_virtual,
@@ -824,6 +909,7 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info)
static struct fb_ops ivtvfb_ops = {
.owner = THIS_MODULE,
+ .fb_write = ivtvfb_write,
.fb_check_var = ivtvfb_check_var,
.fb_set_par = ivtvfb_set_par,
.fb_setcolreg = ivtvfb_setcolreg,
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index 8e0160d275c..39bf6b114d5 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -171,4 +171,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.remove = m52790_remove,
.id_table = m52790_id,
};
-
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index e7ccbc895d7..2fb5854cf6f 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1253,7 +1253,7 @@ static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
return 0;
}
-static int vidioc_enum_fmt_cap(struct file *file, void *fh,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_fmtdesc *f)
{
if (f->index > 1)
@@ -1283,7 +1283,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *fh,
return 0;
}
-static int vidioc_try_fmt_cap(struct file *file, void *fh,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1316,7 +1316,8 @@ static int vidioc_try_fmt_cap(struct file *file, void *fh,
return 0;
}
-static int vidioc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
+static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *f)
{
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1346,7 +1347,8 @@ static int vidioc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
return 0;
}
-static int vidioc_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f)
+static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
+ struct v4l2_format *f)
{
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1709,10 +1711,10 @@ static struct video_device meye_template = {
.vidioc_queryctrl = vidioc_queryctrl,
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 310dbaba55f..5691e019d19 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -110,6 +110,7 @@ MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END };
+
I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -333,7 +334,6 @@ void msp_set_audio(struct i2c_client *client)
/* ------------------------------------------------------------------------ */
-
static void msp_wake_thread(struct i2c_client *client)
{
struct msp_state *state = i2c_get_clientdata(client);
@@ -1004,7 +1004,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.id_table = msp_id,
};
-
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* ---------------------------------------------------------------------------
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 7f556859279..1622f70e4dd 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -480,7 +480,6 @@ int msp3400c_thread(void *data)
struct msp3400c_carrier_detect *cd;
int count, max1, max2, val1, val2, val, i;
-
v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n");
set_freezable();
for (;;) {
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 1658fe59039..b31ba4e0932 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -815,7 +815,6 @@ static int mt9v022_remove(struct i2c_client *client)
return 0;
}
-
static const struct i2c_device_id mt9v022_id[] = {
{ "mt9v022", 0 },
{ }
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index d7bfd30f74a..ea032f5f2f4 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -682,17 +682,17 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
for (index = 0; index < N_OV7670_FMTS; index++)
if (ov7670_formats[index].pixelformat == pix->pixelformat)
break;
- if (index >= N_OV7670_FMTS)
- return -EINVAL;
+ if (index >= N_OV7670_FMTS) {
+ /* default to first format */
+ index = 0;
+ pix->pixelformat = ov7670_formats[0].pixelformat;
+ }
if (ret_fmt != NULL)
*ret_fmt = ov7670_formats + index;
/*
* Fields: the OV devices claim to be progressive.
*/
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
- else if (pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
+ pix->field = V4L2_FIELD_NONE;
/*
* Round requested image size down to the nearest
* we support, but not below the smallest.
@@ -833,7 +833,7 @@ static int ov7670_store_cmatrix(struct i2c_client *client,
int matrix[CMATRIX_LEN])
{
int i, ret;
- unsigned char signbits;
+ unsigned char signbits = 0;
/*
* Weird crap seems to exist in the upper part of
@@ -1009,7 +1009,7 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
static int ov7670_t_brightness(struct i2c_client *client, int value)
{
- unsigned char com8, v;
+ unsigned char com8 = 0, v;
int ret;
ov7670_read(client, REG_COM8, &com8);
@@ -1022,7 +1022,7 @@ static int ov7670_t_brightness(struct i2c_client *client, int value)
static int ov7670_q_brightness(struct i2c_client *client, __s32 *value)
{
- unsigned char v;
+ unsigned char v = 0;
int ret = ov7670_read(client, REG_BRIGHT, &v);
*value = ov7670_sm_to_abs(v);
@@ -1036,7 +1036,7 @@ static int ov7670_t_contrast(struct i2c_client *client, int value)
static int ov7670_q_contrast(struct i2c_client *client, __s32 *value)
{
- unsigned char v;
+ unsigned char v = 0;
int ret = ov7670_read(client, REG_CONTRAS, &v);
*value = v;
@@ -1046,7 +1046,7 @@ static int ov7670_q_contrast(struct i2c_client *client, __s32 *value)
static int ov7670_q_hflip(struct i2c_client *client, __s32 *value)
{
int ret;
- unsigned char v;
+ unsigned char v = 0;
ret = ov7670_read(client, REG_MVFP, &v);
*value = (v & MVFP_MIRROR) == MVFP_MIRROR;
@@ -1056,7 +1056,7 @@ static int ov7670_q_hflip(struct i2c_client *client, __s32 *value)
static int ov7670_t_hflip(struct i2c_client *client, int value)
{
- unsigned char v;
+ unsigned char v = 0;
int ret;
ret = ov7670_read(client, REG_MVFP, &v);
@@ -1074,7 +1074,7 @@ static int ov7670_t_hflip(struct i2c_client *client, int value)
static int ov7670_q_vflip(struct i2c_client *client, __s32 *value)
{
int ret;
- unsigned char v;
+ unsigned char v = 0;
ret = ov7670_read(client, REG_MVFP, &v);
*value = (v & MVFP_FLIP) == MVFP_FLIP;
@@ -1084,7 +1084,7 @@ static int ov7670_q_vflip(struct i2c_client *client, __s32 *value)
static int ov7670_t_vflip(struct i2c_client *client, int value)
{
- unsigned char v;
+ unsigned char v = 0;
int ret;
ret = ov7670_read(client, REG_MVFP, &v);
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
index 8063e33f1c8..065c2454113 100644
--- a/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ b/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -297,7 +297,6 @@ static int ovcamchip_attach(struct i2c_adapter *adap)
switch (adap->id) {
case I2C_HW_SMBUS_OV511:
case I2C_HW_SMBUS_OV518:
- case I2C_HW_SMBUS_OVFX2:
case I2C_HW_SMBUS_W9968CF:
PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id);
break;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 8d859ccd48e..cdedaa55f15 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
index 536339b6884..ac54eed3721 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c
index 73dcb1c57ae..7c19ff72e6b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.c
@@ -1,5 +1,4 @@
/*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h
index 745e270233c..61801291c2a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-context.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-context.h
@@ -1,5 +1,4 @@
/*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 91a42f2473a..0764fbfffb7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
index c1680053cd6..0371ae6e6e4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 29d50597c88..895859ec495 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
index 54b2844e7a7..66abf77f51f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h
index 707d2d9635d..be79249f862 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debug.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h
@@ -1,5 +1,4 @@
/*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index b53121c78ff..ca892fb78a5 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
index 990b02d35d3..e24ff59f860 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 5bf6d8fda1f..5d036e7e3f0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2007 Mike Isely <isely@pobox.com>
*
@@ -182,7 +181,7 @@ static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
+static struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
.frontend_attach = pvr2_lgdt3303_attach,
.tuner_attach = pvr2_lgh06xf_attach,
};
@@ -242,7 +241,7 @@ static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
+static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
.frontend_attach = pvr2_lgdt3302_attach,
.tuner_attach = pvr2_fcv1236d_attach,
};
@@ -315,7 +314,7 @@ static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
+static struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
.frontend_attach = pvr2_tda10048_attach,
.tuner_attach = pvr2_73xxx_tda18271_8295_attach,
};
@@ -418,12 +417,12 @@ static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-struct pvr2_dvb_props pvr2_750xx_dvb_props = {
+static struct pvr2_dvb_props pvr2_750xx_dvb_props = {
.frontend_attach = pvr2_s5h1409_attach,
.tuner_attach = pvr2_tda18271_8295_attach,
};
-struct pvr2_dvb_props pvr2_751xx_dvb_props = {
+static struct pvr2_dvb_props pvr2_751xx_dvb_props = {
.frontend_attach = pvr2_s5h1411_attach,
.tuner_attach = pvr2_tda18271_8295_attach,
};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index d016f8b6c70..e23ce1d2edd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
index 5ef005947b0..299afa4fa96 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
index 84242975dea..cca3216f94c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index c46d367f747..a1252d673b4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
index 54caf2e3c42..232fefbcd1a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
index abaada31e66..b58369e7f30 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2007 Michael Krufky <mkrufky@linuxtv.org>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index a3fe251d6fd..657f861593b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 0a868888f38..a5217a2cf4c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
@@ -40,6 +39,23 @@
#define TV_MIN_FREQ 55250000L
#define TV_MAX_FREQ 850000000L
+/* This defines a minimum interval that the decoder must remain quiet
+ before we are allowed to start it running. */
+#define TIME_MSEC_DECODER_WAIT 50
+
+/* This defines a minimum interval that the encoder must remain quiet
+ before we are allowed to configure it. I had this originally set to
+ 50msec, but Martin Dauskardt <martin.dauskardt@gmx.de> reports that
+ things work better when it's set to 100msec. */
+#define TIME_MSEC_ENCODER_WAIT 100
+
+/* This defines the minimum interval that the encoder must successfully run
+ before we consider that the encoder has run at least once since its
+ firmware has been loaded. This measurement is in important for cases
+ where we can't do something until we know that the encoder has been run
+ at least once. */
+#define TIME_MSEC_ENCODER_OK 250
+
static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL};
static DEFINE_MUTEX(pvr2_unit_mtx);
@@ -67,6 +83,16 @@ MODULE_PARM_DESC(video_std,"specify initial video standard");
module_param_array(tolerance, int, NULL, 0444);
MODULE_PARM_DESC(tolerance,"specify stream error tolerance");
+/* US Broadcast channel 7 (175.25 MHz) */
+static int default_tv_freq = 175250000L;
+/* 104.3 MHz, a usable FM station for my area */
+static int default_radio_freq = 104300000L;
+
+module_param_named(tv_freq, default_tv_freq, int, 0444);
+MODULE_PARM_DESC(tv_freq, "specify initial television frequency");
+module_param_named(radio_freq, default_radio_freq, int, 0444);
+MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
+
#define PVR2_CTL_WRITE_ENDPOINT 0x01
#define PVR2_CTL_READ_ENDPOINT 0x81
@@ -1701,10 +1727,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
are, but I set them to something usable in the Chicago area just
to make driver testing a little easier. */
- /* US Broadcast channel 7 (175.25 MHz) */
- hdw->freqValTelevision = 175250000L;
- /* 104.3 MHz, a usable FM station for my area */
- hdw->freqValRadio = 104300000L;
+ hdw->freqValTelevision = default_tv_freq;
+ hdw->freqValRadio = default_radio_freq;
// Do not use pvr2_reset_ctl_endpoints() here. It is not
// thread-safe against the normal pvr2_send_request() mechanism.
@@ -1989,7 +2013,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
case V4L2_CTRL_TYPE_MENU:
ciptr->type = pvr2_ctl_enum;
ciptr->def.type_enum.value_names =
- cx2341x_ctrl_get_menu(ciptr->v4l_id);
+ cx2341x_ctrl_get_menu(&hdw->enc_ctl_state,
+ ciptr->v4l_id);
for (cnt1 = 0;
ciptr->def.type_enum.value_names[cnt1] != NULL;
cnt1++) { }
@@ -2428,22 +2453,38 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
struct pvr2_ctrl *cptr;
int disruptive_change;
- /* When video standard changes, reset the hres and vres values -
- but if the user has pending changes there, then let the changes
- take priority. */
+ /* Handle some required side effects when the video standard is
+ changed.... */
if (hdw->std_dirty) {
- /* Rewrite the vertical resolution to be appropriate to the
- video standard that has been selected. */
int nvres;
+ int gop_size;
if (hdw->std_mask_cur & V4L2_STD_525_60) {
nvres = 480;
+ gop_size = 15;
} else {
nvres = 576;
+ gop_size = 12;
}
+ /* Rewrite the vertical resolution to be appropriate to the
+ video standard that has been selected. */
if (nvres != hdw->res_ver_val) {
hdw->res_ver_val = nvres;
hdw->res_ver_dirty = !0;
}
+ /* Rewrite the GOP size to be appropriate to the video
+ standard that has been selected. */
+ if (gop_size != hdw->enc_ctl_state.video_gop_size) {
+ struct v4l2_ext_controls cs;
+ struct v4l2_ext_control c1;
+ memset(&cs, 0, sizeof(cs));
+ memset(&c1, 0, sizeof(c1));
+ cs.controls = &c1;
+ cs.count = 1;
+ c1.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+ c1.value = gop_size;
+ cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,
+ VIDIOC_S_EXT_CTRLS);
+ }
}
if (hdw->input_dirty && hdw->state_pathway_ok &&
@@ -3421,7 +3462,7 @@ static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl)
}
-void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
+static void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff)
{
/* change some GPIO data
*
@@ -3601,7 +3642,9 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw)
the encoder. */
if (!hdw->state_encoder_waitok) {
hdw->encoder_wait_timer.expires =
- jiffies + (HZ*50/1000);
+ jiffies +
+ (HZ * TIME_MSEC_ENCODER_WAIT
+ / 1000);
add_timer(&hdw->encoder_wait_timer);
}
}
@@ -3725,7 +3768,7 @@ static int state_eval_encoder_run(struct pvr2_hdw *hdw)
hdw->state_encoder_run = !0;
if (!hdw->state_encoder_runok) {
hdw->encoder_run_timer.expires =
- jiffies + (HZ*250/1000);
+ jiffies + (HZ * TIME_MSEC_ENCODER_OK / 1000);
add_timer(&hdw->encoder_run_timer);
}
}
@@ -3800,7 +3843,9 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw)
but before we did the pending check. */
if (!hdw->state_decoder_quiescent) {
hdw->quiescent_timer.expires =
- jiffies + (HZ*50/1000);
+ jiffies +
+ (HZ * TIME_MSEC_DECODER_WAIT
+ / 1000);
add_timer(&hdw->quiescent_timer);
}
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 20295e0c199..c04956d304a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
index 49773764383..ccdb429fc7a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
index c650e02ccd0..55f04a0b204 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
index c838df6167f..7fa38683b3b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 793c89a8d67..9d3c18b2474 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
index bd0807b905b..6ef7a1c0e93 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c
index 7aff8b72006..20b6ae0bb40 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-io.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h
index 42fcf8281a8..afb7e87c039 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-io.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-io.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
index c572212c9f1..05a1376405e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
index 1d362f83358..100e0780e1a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 332aced8a5a..ad0d98c2ebb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c
index fdc5a2b49ca..ca9f83a85ca 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h
index 07c39937534..a35c53d0b32 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-std.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-std.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 0ff7a836a8a..46a8c39ba03 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
@@ -71,6 +70,7 @@ struct pvr2_sysfs_ctl_item {
struct device_attribute attr_val;
struct device_attribute attr_custom;
struct pvr2_ctrl *cptr;
+ int ctl_id;
struct pvr2_sysfs *chptr;
struct pvr2_sysfs_ctl_item *item_next;
struct attribute *attr_gen[7];
@@ -83,38 +83,29 @@ struct pvr2_sysfs_class {
struct class class;
};
-static ssize_t show_name(int id,struct device *class_dev,char *buf)
+static ssize_t show_name(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
const char *name;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
-
- name = pvr2_ctrl_get_desc(cptr);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name);
-
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name);
+ name = pvr2_ctrl_get_desc(cip->cptr);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
+ cip->chptr, cip->ctl_id, name);
if (!name) return -EINVAL;
-
- return scnprintf(buf,PAGE_SIZE,"%s\n",name);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", name);
}
-static ssize_t show_type(int id,struct device *class_dev,char *buf)
+static ssize_t show_type(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
const char *name;
enum pvr2_ctl_type tp;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
-
- tp = pvr2_ctrl_get_type(cptr);
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type);
+ tp = pvr2_ctrl_get_type(cip->cptr);
switch (tp) {
case pvr2_ctl_int: name = "integer"; break;
case pvr2_ctl_enum: name = "enum"; break;
@@ -122,403 +113,178 @@ static ssize_t show_type(int id,struct device *class_dev,char *buf)
case pvr2_ctl_bool: name = "boolean"; break;
default: name = "?"; break;
}
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name);
-
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
+ cip->chptr, cip->ctl_id, name);
if (!name) return -EINVAL;
-
- return scnprintf(buf,PAGE_SIZE,"%s\n",name);
+ return scnprintf(buf, PAGE_SIZE, "%s\n", name);
}
-static ssize_t show_min(int id,struct device *class_dev,char *buf)
+static ssize_t show_min(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
long val;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
- val = pvr2_ctrl_get_min(cptr);
-
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val);
-
- return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min);
+ val = pvr2_ctrl_get_min(cip->cptr);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
+ cip->chptr, cip->ctl_id, val);
+ return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
}
-static ssize_t show_max(int id,struct device *class_dev,char *buf)
+static ssize_t show_max(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
long val;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
- val = pvr2_ctrl_get_max(cptr);
-
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val);
-
- return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max);
+ val = pvr2_ctrl_get_max(cip->cptr);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
+ cip->chptr, cip->ctl_id, val);
+ return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
}
-static ssize_t show_val_norm(int id,struct device *class_dev,char *buf)
+static ssize_t show_val_norm(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
- int val,ret;
+ struct pvr2_sysfs_ctl_item *cip;
+ int val;
+ int ret;
unsigned int cnt = 0;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
-
- ret = pvr2_ctrl_get_value(cptr,&val);
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
+ ret = pvr2_ctrl_get_value(cip->cptr, &val);
if (ret < 0) return ret;
-
- ret = pvr2_ctrl_value_to_sym(cptr,~0,val,
- buf,PAGE_SIZE-1,&cnt);
-
+ ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
+ buf, PAGE_SIZE - 1, &cnt);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
- sfp,id,cnt,buf,val);
+ cip->chptr, cip->ctl_id, cnt, buf, val);
buf[cnt] = '\n';
return cnt+1;
}
-static ssize_t show_val_custom(int id,struct device *class_dev,char *buf)
+static ssize_t show_val_custom(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
- int val,ret;
+ struct pvr2_sysfs_ctl_item *cip;
+ int val;
+ int ret;
unsigned int cnt = 0;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
-
- ret = pvr2_ctrl_get_value(cptr,&val);
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
+ ret = pvr2_ctrl_get_value(cip->cptr, &val);
if (ret < 0) return ret;
-
- ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val,
- buf,PAGE_SIZE-1,&cnt);
-
+ ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val,
+ buf, PAGE_SIZE - 1, &cnt);
pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
- sfp,id,cnt,buf,val);
+ cip->chptr, cip->ctl_id, cnt, buf, val);
buf[cnt] = '\n';
return cnt+1;
}
-static ssize_t show_enum(int id,struct device *class_dev,char *buf)
+static ssize_t show_enum(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
long val;
- unsigned int bcnt,ccnt,ecnt;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
- ecnt = pvr2_ctrl_get_cnt(cptr);
+ unsigned int bcnt, ccnt, ecnt;
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum);
+ ecnt = pvr2_ctrl_get_cnt(cip->cptr);
bcnt = 0;
for (val = 0; val < ecnt; val++) {
- pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
+ pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt,
+ PAGE_SIZE - bcnt, &ccnt);
if (!ccnt) continue;
bcnt += ccnt;
if (bcnt >= PAGE_SIZE) break;
buf[bcnt] = '\n';
bcnt++;
}
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
+ cip->chptr, cip->ctl_id);
return bcnt;
}
-static ssize_t show_bits(int id,struct device *class_dev,char *buf)
+static ssize_t show_bits(struct device *class_dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct pvr2_ctrl *cptr;
- struct pvr2_sysfs *sfp;
- int valid_bits,msk;
- unsigned int bcnt,ccnt;
-
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
- if (!sfp) return -EINVAL;
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
- if (!cptr) return -EINVAL;
- valid_bits = pvr2_ctrl_get_mask(cptr);
+ struct pvr2_sysfs_ctl_item *cip;
+ int valid_bits, msk;
+ unsigned int bcnt, ccnt;
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits);
+ valid_bits = pvr2_ctrl_get_mask(cip->cptr);
bcnt = 0;
for (msk = 1; valid_bits; msk <<= 1) {
if (!(msk & valid_bits)) continue;
valid_bits &= ~msk;
- pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt);
+ pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt,
+ PAGE_SIZE - bcnt, &ccnt);
bcnt += ccnt;
if (bcnt >= PAGE_SIZE) break;
buf[bcnt] = '\n';
bcnt++;
}
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
+ cip->chptr, cip->ctl_id);
return bcnt;
}
-static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp,
+static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl,
const char *buf,unsigned int count)
{
- struct pvr2_ctrl *cptr;
int ret;
int mask,val;
-
- cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
if (customfl) {
- ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val);
+ ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count,
+ &mask, &val);
} else {
- ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val);
+ ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count,
+ &mask, &val);
}
if (ret < 0) return ret;
- ret = pvr2_ctrl_set_mask_value(cptr,mask,val);
- pvr2_hdw_commit_ctl(sfp->channel.hdw);
+ ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val);
+ pvr2_hdw_commit_ctl(cip->chptr->channel.hdw);
return ret;
}
-static ssize_t store_val_norm(int id,struct device *class_dev,
- const char *buf,size_t count)
+static ssize_t store_val_norm(struct device *class_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
int ret;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
- sfp,id,(int)count,buf);
- ret = store_val_any(id,0,sfp,buf,count);
+ cip->chptr, cip->ctl_id, (int)count, buf);
+ ret = store_val_any(cip, 0, buf, count);
if (!ret) ret = count;
return ret;
}
-static ssize_t store_val_custom(int id,struct device *class_dev,
- const char *buf,size_t count)
+static ssize_t store_val_custom(struct device *class_dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct pvr2_sysfs *sfp;
+ struct pvr2_sysfs_ctl_item *cip;
int ret;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
- sfp,id,(int)count,buf);
- ret = store_val_any(id,1,sfp,buf,count);
+ cip->chptr, cip->ctl_id, (int)count, buf);
+ ret = store_val_any(cip, 1, buf, count);
if (!ret) ret = count;
return ret;
}
-/*
- Mike Isely <isely@pobox.com> 30-April-2005
-
- This next batch of horrible preprocessor hackery is needed because the
- kernel's device_attribute mechanism fails to pass the actual
- attribute through to the show / store functions, which means we have no
- way to package up any attribute-specific parameters, like for example the
- control id. So we work around this brain-damage by encoding the control
- id into the show / store functions themselves and pick the function based
- on the control id we're setting up. These macros try to ease the pain.
- Yuck.
-*/
-
-#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
-static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
-struct device_attribute *attr, char *buf) \
-{ return sf_name(ctl_id,class_dev,buf); }
-
-#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
-static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
-struct device_attribute *attr, const char *buf, size_t count) \
-{ return sf_name(ctl_id,class_dev,buf,count); }
-
-#define CREATE_BATCH(ctl_id) \
-CREATE_SHOW_INSTANCE(show_name,ctl_id) \
-CREATE_SHOW_INSTANCE(show_type,ctl_id) \
-CREATE_SHOW_INSTANCE(show_min,ctl_id) \
-CREATE_SHOW_INSTANCE(show_max,ctl_id) \
-CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
-CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
-CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
-CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
-CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
-CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
-
-CREATE_BATCH(0)
-CREATE_BATCH(1)
-CREATE_BATCH(2)
-CREATE_BATCH(3)
-CREATE_BATCH(4)
-CREATE_BATCH(5)
-CREATE_BATCH(6)
-CREATE_BATCH(7)
-CREATE_BATCH(8)
-CREATE_BATCH(9)
-CREATE_BATCH(10)
-CREATE_BATCH(11)
-CREATE_BATCH(12)
-CREATE_BATCH(13)
-CREATE_BATCH(14)
-CREATE_BATCH(15)
-CREATE_BATCH(16)
-CREATE_BATCH(17)
-CREATE_BATCH(18)
-CREATE_BATCH(19)
-CREATE_BATCH(20)
-CREATE_BATCH(21)
-CREATE_BATCH(22)
-CREATE_BATCH(23)
-CREATE_BATCH(24)
-CREATE_BATCH(25)
-CREATE_BATCH(26)
-CREATE_BATCH(27)
-CREATE_BATCH(28)
-CREATE_BATCH(29)
-CREATE_BATCH(30)
-CREATE_BATCH(31)
-CREATE_BATCH(32)
-CREATE_BATCH(33)
-CREATE_BATCH(34)
-CREATE_BATCH(35)
-CREATE_BATCH(36)
-CREATE_BATCH(37)
-CREATE_BATCH(38)
-CREATE_BATCH(39)
-CREATE_BATCH(40)
-CREATE_BATCH(41)
-CREATE_BATCH(42)
-CREATE_BATCH(43)
-CREATE_BATCH(44)
-CREATE_BATCH(45)
-CREATE_BATCH(46)
-CREATE_BATCH(47)
-CREATE_BATCH(48)
-CREATE_BATCH(49)
-CREATE_BATCH(50)
-CREATE_BATCH(51)
-CREATE_BATCH(52)
-CREATE_BATCH(53)
-CREATE_BATCH(54)
-CREATE_BATCH(55)
-CREATE_BATCH(56)
-CREATE_BATCH(57)
-CREATE_BATCH(58)
-CREATE_BATCH(59)
-
-struct pvr2_sysfs_func_set {
- ssize_t (*show_name)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*show_type)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*show_min)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*show_max)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*show_enum)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*show_bits)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*show_val_norm)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*store_val_norm)(struct device *,
- struct device_attribute *attr,
- const char *,size_t);
- ssize_t (*show_val_custom)(struct device *,
- struct device_attribute *attr, char *);
- ssize_t (*store_val_custom)(struct device *,
- struct device_attribute *attr,
- const char *,size_t);
-};
-
-#define INIT_BATCH(ctl_id) \
-[ctl_id] = { \
- .show_name = show_name_##ctl_id, \
- .show_type = show_type_##ctl_id, \
- .show_min = show_min_##ctl_id, \
- .show_max = show_max_##ctl_id, \
- .show_enum = show_enum_##ctl_id, \
- .show_bits = show_bits_##ctl_id, \
- .show_val_norm = show_val_norm_##ctl_id, \
- .store_val_norm = store_val_norm_##ctl_id, \
- .show_val_custom = show_val_custom_##ctl_id, \
- .store_val_custom = store_val_custom_##ctl_id, \
-} \
-
-static struct pvr2_sysfs_func_set funcs[] = {
- INIT_BATCH(0),
- INIT_BATCH(1),
- INIT_BATCH(2),
- INIT_BATCH(3),
- INIT_BATCH(4),
- INIT_BATCH(5),
- INIT_BATCH(6),
- INIT_BATCH(7),
- INIT_BATCH(8),
- INIT_BATCH(9),
- INIT_BATCH(10),
- INIT_BATCH(11),
- INIT_BATCH(12),
- INIT_BATCH(13),
- INIT_BATCH(14),
- INIT_BATCH(15),
- INIT_BATCH(16),
- INIT_BATCH(17),
- INIT_BATCH(18),
- INIT_BATCH(19),
- INIT_BATCH(20),
- INIT_BATCH(21),
- INIT_BATCH(22),
- INIT_BATCH(23),
- INIT_BATCH(24),
- INIT_BATCH(25),
- INIT_BATCH(26),
- INIT_BATCH(27),
- INIT_BATCH(28),
- INIT_BATCH(29),
- INIT_BATCH(30),
- INIT_BATCH(31),
- INIT_BATCH(32),
- INIT_BATCH(33),
- INIT_BATCH(34),
- INIT_BATCH(35),
- INIT_BATCH(36),
- INIT_BATCH(37),
- INIT_BATCH(38),
- INIT_BATCH(39),
- INIT_BATCH(40),
- INIT_BATCH(41),
- INIT_BATCH(42),
- INIT_BATCH(43),
- INIT_BATCH(44),
- INIT_BATCH(45),
- INIT_BATCH(46),
- INIT_BATCH(47),
- INIT_BATCH(48),
- INIT_BATCH(49),
- INIT_BATCH(50),
- INIT_BATCH(51),
- INIT_BATCH(52),
- INIT_BATCH(53),
- INIT_BATCH(54),
- INIT_BATCH(55),
- INIT_BATCH(56),
- INIT_BATCH(57),
- INIT_BATCH(58),
- INIT_BATCH(59),
-};
-
-
static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
{
struct pvr2_sysfs_ctl_item *cip;
- struct pvr2_sysfs_func_set *fp;
struct pvr2_ctrl *cptr;
unsigned int cnt,acnt;
int ret;
- if ((ctl_id < 0) || (ctl_id >= ARRAY_SIZE(funcs))) {
- return;
- }
-
- fp = funcs + ctl_id;
cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
if (!cptr) return;
@@ -527,6 +293,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
cip->cptr = cptr;
+ cip->ctl_id = ctl_id;
cip->chptr = sfp;
cip->item_next = NULL;
@@ -539,19 +306,19 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_name.attr.name = "name";
cip->attr_name.attr.mode = S_IRUGO;
- cip->attr_name.show = fp->show_name;
+ cip->attr_name.show = show_name;
cip->attr_type.attr.name = "type";
cip->attr_type.attr.mode = S_IRUGO;
- cip->attr_type.show = fp->show_type;
+ cip->attr_type.show = show_type;
cip->attr_min.attr.name = "min_val";
cip->attr_min.attr.mode = S_IRUGO;
- cip->attr_min.show = fp->show_min;
+ cip->attr_min.show = show_min;
cip->attr_max.attr.name = "max_val";
cip->attr_max.attr.mode = S_IRUGO;
- cip->attr_max.show = fp->show_max;
+ cip->attr_max.show = show_max;
cip->attr_val.attr.name = "cur_val";
cip->attr_val.attr.mode = S_IRUGO;
@@ -561,11 +328,11 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_enum.attr.name = "enum_val";
cip->attr_enum.attr.mode = S_IRUGO;
- cip->attr_enum.show = fp->show_enum;
+ cip->attr_enum.show = show_enum;
cip->attr_bits.attr.name = "bit_val";
cip->attr_bits.attr.mode = S_IRUGO;
- cip->attr_bits.show = fp->show_bits;
+ cip->attr_bits.show = show_bits;
if (pvr2_ctrl_is_writable(cptr)) {
cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
@@ -576,12 +343,12 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
cip->attr_gen[acnt++] = &cip->attr_name.attr;
cip->attr_gen[acnt++] = &cip->attr_type.attr;
cip->attr_gen[acnt++] = &cip->attr_val.attr;
- cip->attr_val.show = fp->show_val_norm;
- cip->attr_val.store = fp->store_val_norm;
+ cip->attr_val.show = show_val_norm;
+ cip->attr_val.store = store_val_norm;
if (pvr2_ctrl_has_custom_symbols(cptr)) {
cip->attr_gen[acnt++] = &cip->attr_custom.attr;
- cip->attr_custom.show = fp->show_val_custom;
- cip->attr_custom.store = fp->store_val_custom;
+ cip->attr_custom.show = show_val_custom;
+ cip->attr_custom.store = store_val_custom;
}
switch (pvr2_ctrl_get_type(cptr)) {
case pvr2_ctl_enum:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
index ff9373b47f8..6d875bfe799 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
index 05e65ce2e3a..07775d1aad4 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-tuner.h
index 556f12aa916..ef4afaf37b0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h
index e53aee416f5..92b75544ee2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-util.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-util.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index e9b5d4e9132..0d72dc470fe 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
index 9a995e2d225..34c011a7b10 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 2433a316004..4059648c705 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
index 2b917fda02e..4ff5b892b30 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index 66b4d36ef76..f6fcf0ac611 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
index 8aaeff4e1e2..80709096125 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h
index 1a9a4baf12b..240de9b3566 100644
--- a/drivers/media/video/pvrusb2/pvrusb2.h
+++ b/drivers/media/video/pvrusb2/pvrusb2.h
@@ -1,6 +1,5 @@
/*
*
- * $Id$
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index ea53316d211..1cccd5c7704 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -1255,7 +1255,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
exactly the same otherwise.
*/
-
/* define local variable for arg */
#define ARG_DEF(ARG_type, ARG_name)\
ARG_type *ARG_name = arg;
@@ -1268,7 +1267,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor)
/* copy local variable to arg */
#define ARG_OUT(ARG_name) /* nothing */
-
int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
{
int ret = 0;
diff --git a/drivers/media/video/pwc/pwc-ioctl.h b/drivers/media/video/pwc/pwc-ioctl.h
index cec66029976..8c0cae7b3da 100644
--- a/drivers/media/video/pwc/pwc-ioctl.h
+++ b/drivers/media/video/pwc/pwc-ioctl.h
@@ -54,7 +54,6 @@
#include <linux/types.h>
#include <linux/version.h>
-
/* Enumeration of image sizes */
#define PSZ_SQCIF 0x00
#define PSZ_QSIF 0x01
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 5ec5bb9a94d..b15f82c4976 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -30,6 +30,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
+#include <media/videobuf-dma-sg.h>
#include <media/soc_camera.h>
#include <linux/videodev2.h>
@@ -582,6 +583,19 @@ static struct videobuf_queue_ops pxa_videobuf_ops = {
.buf_release = pxa_videobuf_release,
};
+static void pxa_camera_init_videobuf(struct videobuf_queue *q,
+ struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct pxa_camera_dev *pcdev = ici->priv;
+
+ /* We must pass NULL as dev pointer, then all pci_* dma operations
+ * transform to normal dma_* ones. */
+ videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
+ sizeof(struct pxa_buffer), icd);
+}
+
static int mclk_get_divisor(struct pxa_camera_dev *pcdev)
{
unsigned int mclk_10khz = pcdev->platform_mclk_10khz;
@@ -983,34 +997,23 @@ static int pxa_camera_querycap(struct soc_camera_host *ici,
return 0;
}
-static spinlock_t *pxa_camera_spinlock_alloc(struct soc_camera_file *icf)
-{
- struct soc_camera_host *ici =
- to_soc_camera_host(icf->icd->dev.parent);
- struct pxa_camera_dev *pcdev = ici->priv;
-
- return &pcdev->lock;
-}
-
static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.owner = THIS_MODULE,
.add = pxa_camera_add_device,
.remove = pxa_camera_remove_device,
.set_fmt_cap = pxa_camera_set_fmt_cap,
.try_fmt_cap = pxa_camera_try_fmt_cap,
+ .init_videobuf = pxa_camera_init_videobuf,
.reqbufs = pxa_camera_reqbufs,
.poll = pxa_camera_poll,
.querycap = pxa_camera_querycap,
.try_bus_param = pxa_camera_try_bus_param,
.set_bus_param = pxa_camera_set_bus_param,
- .spinlock_alloc = pxa_camera_spinlock_alloc,
};
/* Should be allocated dynamically too, but we have only one. */
static struct soc_camera_host pxa_soc_camera_host = {
.drv_name = PXA_CAM_DRV_NAME,
- .vbq_ops = &pxa_videobuf_ops,
- .msize = sizeof(struct pxa_buffer),
.ops = &pxa_soc_camera_host_ops,
};
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
new file mode 100644
index 00000000000..04eb2c3fabd
--- /dev/null
+++ b/drivers/media/video/s2255drv.c
@@ -0,0 +1,2495 @@
+/*
+ * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
+ *
+ * Copyright (C) 2007-2008 by Sensoray Company Inc.
+ * Dean Anderson
+ *
+ * Some video buffer code based on vivi driver:
+ *
+ * Sensoray 2255 device supports 4 simultaneous channels.
+ * The channels are not "crossbar" inputs, they are physically
+ * attached to separate video decoders.
+ *
+ * Because of USB2.0 bandwidth limitations. There is only a
+ * certain amount of data which may be transferred at one time.
+ *
+ * Example maximum bandwidth utilization:
+ *
+ * -full size, color mode YUYV or YUV422P: 2 channels at once
+ *
+ * -full or half size Grey scale: all 4 channels at once
+ *
+ * -half size, color mode YUYV or YUV422P: all 4 channels at once
+ *
+ * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
+ * at once.
+ * (TODO: Incorporate videodev2 frame rate(FR) enumeration,
+ * which is currently experimental.)
+ *
+ * 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 <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+#include <linux/version.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-common.h>
+#include <linux/vmalloc.h>
+#include <linux/usb.h>
+
+#define FIRMWARE_FILE_NAME "f2255usb.bin"
+
+
+
+/* vendor request in */
+#define S2255_VR_IN 0
+/* vendor request out */
+#define S2255_VR_OUT 1
+/* firmware query */
+#define S2255_VR_FW 0x30
+/* USB endpoint number for configuring the device */
+#define S2255_CONFIG_EP 2
+/* maximum time for DSP to start responding after last FW word loaded(ms) */
+#define S2255_DSP_BOOTTIME 400
+/* maximum time to wait for firmware to load (ms) */
+#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
+#define S2255_DEF_BUFS 16
+#define MAX_CHANNELS 4
+#define FRAME_MARKER 0x2255DA4AL
+#define MAX_PIPE_USBBLOCK (40 * 1024)
+#define DEFAULT_PIPE_USBBLOCK (16 * 1024)
+#define MAX_CHANNELS 4
+#define MAX_PIPE_BUFFERS 1
+#define SYS_FRAMES 4
+/* maximum size is PAL full size plus room for the marker header(s) */
+#define SYS_FRAMES_MAXSIZE (720 * 288 * 2 * 2 + 4096)
+#define DEF_USB_BLOCK (4096)
+#define LINE_SZ_4CIFS_NTSC 640
+#define LINE_SZ_2CIFS_NTSC 640
+#define LINE_SZ_1CIFS_NTSC 320
+#define LINE_SZ_4CIFS_PAL 704
+#define LINE_SZ_2CIFS_PAL 704
+#define LINE_SZ_1CIFS_PAL 352
+#define NUM_LINES_4CIFS_NTSC 240
+#define NUM_LINES_2CIFS_NTSC 240
+#define NUM_LINES_1CIFS_NTSC 240
+#define NUM_LINES_4CIFS_PAL 288
+#define NUM_LINES_2CIFS_PAL 288
+#define NUM_LINES_1CIFS_PAL 288
+#define LINE_SZ_DEF 640
+#define NUM_LINES_DEF 240
+
+
+/* predefined settings */
+#define FORMAT_NTSC 1
+#define FORMAT_PAL 2
+
+#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
+#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
+#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
+
+#define COLOR_YUVPL 1 /* YUV planar */
+#define COLOR_YUVPK 2 /* YUV packed */
+#define COLOR_Y8 4 /* monochrome */
+
+/* frame decimation. Not implemented by V4L yet(experimental in V4L) */
+#define FDEC_1 1 /* capture every frame. default */
+#define FDEC_2 2 /* capture every 2nd frame */
+#define FDEC_3 3 /* capture every 3rd frame */
+#define FDEC_5 5 /* capture every 5th frame */
+
+/*-------------------------------------------------------
+ * Default mode parameters.
+ *-------------------------------------------------------*/
+#define DEF_SCALE SCALE_4CIFS
+#define DEF_COLOR COLOR_YUVPL
+#define DEF_FDEC FDEC_1
+#define DEF_BRIGHT 0
+#define DEF_CONTRAST 0x5c
+#define DEF_SATURATION 0x80
+#define DEF_HUE 0
+
+/* usb config commands */
+#define IN_DATA_TOKEN 0x2255c0de
+#define CMD_2255 0xc2255000
+#define CMD_SET_MODE (CMD_2255 | 0x10)
+#define CMD_START (CMD_2255 | 0x20)
+#define CMD_STOP (CMD_2255 | 0x30)
+#define CMD_STATUS (CMD_2255 | 0x40)
+
+struct s2255_mode {
+ u32 format; /* input video format (NTSC, PAL) */
+ u32 scale; /* output video scale */
+ u32 color; /* output video color format */
+ u32 fdec; /* frame decimation */
+ u32 bright; /* brightness */
+ u32 contrast; /* contrast */
+ u32 saturation; /* saturation */
+ u32 hue; /* hue (NTSC only)*/
+ u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
+ u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
+ u32 restart; /* if DSP requires restart */
+};
+
+/* frame structure */
+#define FRAME_STATE_UNUSED 0
+#define FRAME_STATE_FILLING 1
+#define FRAME_STATE_FULL 2
+
+
+struct s2255_framei {
+ unsigned long size;
+
+ unsigned long ulState; /* ulState ==0 unused, 1 being filled, 2 full */
+ void *lpvbits; /* image data */
+ unsigned long cur_size; /* current data copied to it */
+};
+
+/* image buffer structure */
+struct s2255_bufferi {
+ unsigned long dwFrames; /* number of frames in buffer */
+ struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
+};
+
+#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
+ DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
+ DEF_HUE, 0, DEF_USB_BLOCK, 0}
+
+struct s2255_dmaqueue {
+ struct list_head active;
+ /* thread for acquisition */
+ struct task_struct *kthread;
+ int frame;
+ struct s2255_dev *dev;
+ int channel;
+};
+
+/* for firmware loading, fw_state */
+#define S2255_FW_NOTLOADED 0
+#define S2255_FW_LOADED_DSPWAIT 1
+#define S2255_FW_SUCCESS 2
+#define S2255_FW_FAILED 3
+
+struct s2255_fw {
+ int fw_loaded;
+ int fw_size;
+ struct urb *fw_urb;
+ atomic_t fw_state;
+ void *pfw_data;
+ wait_queue_head_t wait_fw;
+ struct timer_list dsp_wait;
+ const struct firmware *fw;
+};
+
+struct s2255_pipeinfo {
+ u32 max_transfer_size;
+ u32 cur_transfer_size;
+ u8 *transfer_buffer;
+ u32 transfer_flags;;
+ u32 state;
+ u32 prev_state;
+ u32 urb_size;
+ void *stream_urb;
+ void *dev; /* back pointer to s2255_dev struct*/
+ u32 err_count;
+ u32 buf_index;
+ u32 idx;
+ u32 priority_set;
+};
+
+struct s2255_fmt; /*forward declaration */
+
+struct s2255_dev {
+ int frames;
+ int users[MAX_CHANNELS];
+ struct mutex lock;
+ struct mutex open_lock;
+ int resources[MAX_CHANNELS];
+ struct usb_device *udev;
+ struct usb_interface *interface;
+ u8 read_endpoint;
+
+ struct s2255_dmaqueue vidq[MAX_CHANNELS];
+ struct video_device *vdev[MAX_CHANNELS];
+ struct list_head s2255_devlist;
+ struct timer_list timer;
+ struct s2255_fw *fw_data;
+ int board_num;
+ int is_open;
+ struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS];
+ struct s2255_bufferi buffer[MAX_CHANNELS];
+ struct s2255_mode mode[MAX_CHANNELS];
+ const struct s2255_fmt *cur_fmt[MAX_CHANNELS];
+ int cur_frame[MAX_CHANNELS];
+ int last_frame[MAX_CHANNELS];
+ u32 cc; /* current channel */
+ int b_acquire[MAX_CHANNELS];
+ unsigned long req_image_size[MAX_CHANNELS];
+ int bad_payload[MAX_CHANNELS];
+ unsigned long frame_count[MAX_CHANNELS];
+ int frame_ready;
+ struct kref kref;
+ spinlock_t slock;
+};
+#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref)
+
+struct s2255_fmt {
+ char *name;
+ u32 fourcc;
+ int depth;
+};
+
+/* buffer for one video frame */
+struct s2255_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ const struct s2255_fmt *fmt;
+};
+
+struct s2255_fh {
+ struct s2255_dev *dev;
+ unsigned int resources;
+ const struct s2255_fmt *fmt;
+ unsigned int width;
+ unsigned int height;
+ struct videobuf_queue vb_vidq;
+ enum v4l2_buf_type type;
+ int channel;
+ /* mode below is the desired mode.
+ mode in s2255_dev is the current mode that was last set */
+ struct s2255_mode mode;
+};
+
+/*
+ * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles.
+ * Limit V4L to one stream at a time.
+ */
+#define S2255_MAX_USERS 1
+
+#define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */
+#define S2255_MAJOR_VERSION 1
+#define S2255_MINOR_VERSION 13
+#define S2255_RELEASE 0
+#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \
+ S2255_MINOR_VERSION, \
+ S2255_RELEASE)
+
+/* vendor ids */
+#define USB_S2255_VENDOR_ID 0x1943
+#define USB_S2255_PRODUCT_ID 0x2255
+#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC)
+/* frame prefix size (sent once every frame) */
+#define PREFIX_SIZE 512
+
+/* Channels on box are in reverse order */
+static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
+
+static LIST_HEAD(s2255_devlist);
+
+static int debug;
+static int *s2255_debug = &debug;
+
+static int s2255_start_readpipe(struct s2255_dev *dev);
+static void s2255_stop_readpipe(struct s2255_dev *dev);
+static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn);
+static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn);
+static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
+ int chn);
+static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
+ struct s2255_mode *mode);
+static int s2255_board_shutdown(struct s2255_dev *dev);
+static void s2255_exit_v4l(struct s2255_dev *dev);
+static void s2255_fwload_start(struct s2255_dev *dev);
+
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (*s2255_debug >= (level)) { \
+ printk(KERN_DEBUG "s2255: " fmt, ##arg); \
+ } \
+ } while (0)
+
+
+static struct usb_driver s2255_driver;
+
+
+/* Declare static vars that will be used as parameters */
+static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
+
+/* start video number */
+static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
+module_param(vid_limit, int, 0644);
+MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
+module_param(video_nr, int, 0644);
+MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
+
+/* USB device table */
+static struct usb_device_id s2255_table[] = {
+ {USB_DEVICE(USB_S2255_VENDOR_ID, USB_S2255_PRODUCT_ID)},
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, s2255_table);
+
+
+#define BUFFER_TIMEOUT msecs_to_jiffies(400)
+
+/* supported controls */
+static struct v4l2_queryctrl s2255_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = -127,
+ .maximum = 128,
+ .step = 1,
+ .default_value = 0,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = DEF_CONTRAST,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = DEF_SATURATION,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = DEF_HUE,
+ .flags = 0,
+ }
+};
+
+static int qctl_regs[ARRAY_SIZE(s2255_qctrl)];
+
+/* image formats. */
+static const struct s2255_fmt formats[] = {
+ {
+ .name = "4:2:2, planar, YUV422P",
+ .fourcc = V4L2_PIX_FMT_YUV422P,
+ .depth = 16
+
+ }, {
+ .name = "4:2:2, packed, YUYV",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = 16
+
+ }, {
+ .name = "4:2:2, packed, UYVY",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = 16
+ }, {
+ .name = "8bpp GREY",
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .depth = 8
+ }
+};
+
+static int norm_maxw(struct video_device *vdev)
+{
+ return (vdev->current_norm & V4L2_STD_NTSC) ?
+ LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
+}
+
+static int norm_maxh(struct video_device *vdev)
+{
+ return (vdev->current_norm & V4L2_STD_NTSC) ?
+ (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
+}
+
+static int norm_minw(struct video_device *vdev)
+{
+ return (vdev->current_norm & V4L2_STD_NTSC) ?
+ LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
+}
+
+static int norm_minh(struct video_device *vdev)
+{
+ return (vdev->current_norm & V4L2_STD_NTSC) ?
+ (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
+}
+
+
+/*
+ * TODO: fixme: move YUV reordering to hardware
+ * converts 2255 planar format to yuyv or uyvy
+ */
+static void planar422p_to_yuv_packed(const unsigned char *in,
+ unsigned char *out,
+ int width, int height,
+ int fmt)
+{
+ unsigned char *pY;
+ unsigned char *pCb;
+ unsigned char *pCr;
+ unsigned long size = height * width;
+ unsigned int i;
+ pY = (unsigned char *)in;
+ pCr = (unsigned char *)in + height * width;
+ pCb = (unsigned char *)in + height * width + (height * width / 2);
+ for (i = 0; i < size * 2; i += 4) {
+ out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
+ out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
+ out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
+ out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
+ }
+ return;
+}
+
+
+/* kickstarts the firmware loading. from probe
+ */
+static void s2255_timer(unsigned long user_data)
+{
+ struct s2255_fw *data = (struct s2255_fw *)user_data;
+ dprintk(100, "s2255 timer\n");
+ if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
+ printk(KERN_ERR "s2255: can't submit urb\n");
+ if (data->fw) {
+ release_firmware(data->fw);
+ data->fw = NULL;
+ }
+ return;
+ }
+}
+
+/* called when DSP is up and running. DSP is guaranteed to
+ be running after S2255_DSP_BOOTTIME */
+static void s2255_dsp_running(unsigned long user_data)
+{
+ struct s2255_fw *data = (struct s2255_fw *)user_data;
+ dprintk(1, "dsp running\n");
+ atomic_set(&data->fw_state, S2255_FW_SUCCESS);
+ wake_up(&data->wait_fw);
+ printk(KERN_INFO "s2255: firmware loaded successfully\n");
+ return;
+}
+
+
+/* this loads the firmware asynchronously.
+ Originally this was done synchroously in probe.
+ But it is better to load it asynchronously here than block
+ inside the probe function. Blocking inside probe affects boot time.
+ FW loading is triggered by the timer in the probe function
+*/
+static void s2255_fwchunk_complete(struct urb *urb)
+{
+ struct s2255_fw *data = urb->context;
+ struct usb_device *udev = urb->dev;
+ int len;
+ dprintk(100, "udev %p urb %p", udev, urb);
+ /* TODO: fixme. reflect change in status */
+ if (urb->status) {
+ dev_err(&udev->dev, "URB failed with status %d", urb->status);
+ return;
+ }
+ if (data->fw_urb == NULL) {
+ dev_err(&udev->dev, "early disconncect\n");
+ return;
+ }
+#define CHUNK_SIZE 512
+ /* all USB transfers must be done with continuous kernel memory.
+ can't allocate more than 128k in current linux kernel, so
+ upload the firmware in chunks
+ */
+ if (data->fw_loaded < data->fw_size) {
+ len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
+ data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
+
+ if (len < CHUNK_SIZE)
+ memset(data->pfw_data, 0, CHUNK_SIZE);
+
+ dprintk(100, "completed len %d, loaded %d \n", len,
+ data->fw_loaded);
+
+ memcpy(data->pfw_data,
+ (char *) data->fw->data + data->fw_loaded, len);
+
+ usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
+ data->pfw_data, CHUNK_SIZE,
+ s2255_fwchunk_complete, data);
+ if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
+ dev_err(&udev->dev, "failed submit URB\n");
+ atomic_set(&data->fw_state, S2255_FW_FAILED);
+ /* wake up anything waiting for the firmware */
+ wake_up(&data->wait_fw);
+ return;
+ }
+ data->fw_loaded += len;
+ } else {
+ init_timer(&data->dsp_wait);
+ data->dsp_wait.function = s2255_dsp_running;
+ data->dsp_wait.data = (unsigned long)data;
+ atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
+ mod_timer(&data->dsp_wait, msecs_to_jiffies(S2255_DSP_BOOTTIME)
+ + jiffies);
+ }
+ dprintk(100, "2255 complete done\n");
+ return;
+
+}
+
+static int s2255_got_frame(struct s2255_dev *dev, int chn)
+{
+ struct s2255_dmaqueue *dma_q = &dev->vidq[chn];
+ struct s2255_buffer *buf;
+ unsigned long flags = 0;
+ int rc = 0;
+ dprintk(2, "wakeup: %p channel: %d\n", &dma_q, chn);
+ spin_lock_irqsave(&dev->slock, flags);
+
+ if (list_empty(&dma_q->active)) {
+ dprintk(1, "No active queue to serve\n");
+ rc = -1;
+ goto unlock;
+ }
+ buf = list_entry(dma_q->active.next,
+ struct s2255_buffer, vb.queue);
+
+ if (!waitqueue_active(&buf->vb.done)) {
+ /* no one active */
+ rc = -1;
+ goto unlock;
+ }
+ list_del(&buf->vb.queue);
+ do_gettimeofday(&buf->vb.ts);
+ dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i);
+
+ s2255_fillbuff(dev, buf, dma_q->channel);
+ wake_up(&buf->vb.done);
+ dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
+unlock:
+ spin_unlock_irqrestore(&dev->slock, flags);
+ return 0;
+}
+
+
+static const struct s2255_fmt *format_by_fourcc(int fourcc)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ if (-1 == formats[i].fourcc)
+ continue;
+ if (formats[i].fourcc == fourcc)
+ return formats + i;
+ }
+ return NULL;
+}
+
+
+
+
+/* video buffer vmalloc implementation based partly on VIVI driver which is
+ * Copyright (c) 2006 by
+ * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
+ * Ted Walther <ted--a.t--enumera.com>
+ * John Sokol <sokol--a.t--videotechnology.com>
+ * http://v4l.videotechnology.com/
+ *
+ */
+static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
+ int chn)
+{
+ int pos = 0;
+ struct timeval ts;
+ const char *tmpbuf;
+ char *vbuf = videobuf_to_vmalloc(&buf->vb);
+ unsigned long last_frame;
+ struct s2255_framei *frm;
+
+ if (!vbuf)
+ return;
+
+ last_frame = dev->last_frame[chn];
+ if (last_frame != -1) {
+ frm = &dev->buffer[chn].frame[last_frame];
+ tmpbuf =
+ (const char *)dev->buffer[chn].frame[last_frame].lpvbits;
+ switch (buf->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
+ vbuf, buf->vb.width,
+ buf->vb.height,
+ buf->fmt->fourcc);
+ break;
+ case V4L2_PIX_FMT_GREY:
+ memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
+ break;
+ case V4L2_PIX_FMT_YUV422P:
+ memcpy(vbuf, tmpbuf,
+ buf->vb.width * buf->vb.height * 2);
+ break;
+ default:
+ printk(KERN_DEBUG "s2255: unknown format?\n");
+ }
+ dev->last_frame[chn] = -1;
+ /* done with the frame, free it */
+ frm->ulState = 0;
+ dprintk(4, "freeing buffer\n");
+ } else {
+ printk(KERN_ERR "s2255: =======no frame\n");
+ return;
+
+ }
+ dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n",
+ (unsigned long)vbuf, pos);
+ /* tell v4l buffer was filled */
+
+ buf->vb.field_count++;
+ do_gettimeofday(&ts);
+ buf->vb.ts = ts;
+ buf->vb.state = VIDEOBUF_DONE;
+}
+
+
+/* ------------------------------------------------------------------
+ Videobuf operations
+ ------------------------------------------------------------------*/
+
+static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct s2255_fh *fh = vq->priv_data;
+
+ *size = fh->width * fh->height * (fh->fmt->depth >> 3);
+
+ if (0 == *count)
+ *count = S2255_DEF_BUFS;
+
+ while (*size * (*count) > vid_limit * 1024 * 1024)
+ (*count)--;
+
+ return 0;
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf)
+{
+ dprintk(4, "%s\n", __func__);
+
+ videobuf_waiton(&buf->vb, 0, 0);
+ videobuf_vmalloc_free(&buf->vb);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct s2255_fh *fh = vq->priv_data;
+ struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
+ int rc;
+ dprintk(4, "%s, field=%d\n", __func__, field);
+ if (fh->fmt == NULL)
+ return -EINVAL;
+
+ if ((fh->width < norm_minw(fh->dev->vdev[fh->channel])) ||
+ (fh->width > norm_maxw(fh->dev->vdev[fh->channel])) ||
+ (fh->height < norm_minh(fh->dev->vdev[fh->channel])) ||
+ (fh->height > norm_maxh(fh->dev->vdev[fh->channel]))) {
+ dprintk(4, "invalid buffer prepare\n");
+ return -EINVAL;
+ }
+
+ buf->vb.size = fh->width * fh->height * (fh->fmt->depth >> 3);
+
+ if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
+ dprintk(4, "invalid buffer prepare\n");
+ return -EINVAL;
+ }
+
+ buf->fmt = fh->fmt;
+ buf->vb.width = fh->width;
+ buf->vb.height = fh->height;
+ buf->vb.field = field;
+
+
+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+ rc = videobuf_iolock(vq, &buf->vb, NULL);
+ if (rc < 0)
+ goto fail;
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+fail:
+ free_buffer(vq, buf);
+ return rc;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
+ struct s2255_fh *fh = vq->priv_data;
+ struct s2255_dev *dev = fh->dev;
+ struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel];
+
+ dprintk(1, "%s\n", __func__);
+
+ buf->vb.state = VIDEOBUF_QUEUED;
+ list_add_tail(&buf->vb.queue, &vidq->active);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
+ struct s2255_fh *fh = vq->priv_data;
+ dprintk(4, "%s %d\n", __func__, fh->channel);
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops s2255_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+
+static int res_get(struct s2255_dev *dev, struct s2255_fh *fh)
+{
+ /* is it free? */
+ mutex_lock(&dev->lock);
+ if (dev->resources[fh->channel]) {
+ /* no, someone else uses it */
+ mutex_unlock(&dev->lock);
+ return 0;
+ }
+ /* it's free, grab it */
+ dev->resources[fh->channel] = 1;
+ dprintk(1, "res: get\n");
+ mutex_unlock(&dev->lock);
+ return 1;
+}
+
+static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh)
+{
+ return dev->resources[fh->channel];
+}
+
+static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
+{
+ dev->resources[fh->channel] = 0;
+ dprintk(1, "res: put\n");
+}
+
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct s2255_fh *fh = file->private_data;
+ struct s2255_dev *dev = fh->dev;
+ strlcpy(cap->driver, "s2255", sizeof(cap->driver));
+ strlcpy(cap->card, "s2255", sizeof(cap->card));
+ strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
+ sizeof(cap->bus_info));
+ cap->version = S2255_VERSION;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ int index = 0;
+ if (f)
+ index = f->index;
+
+ if (index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+ dprintk(4, "name %s\n", formats[index].name);
+ strlcpy(f->description, formats[index].name, sizeof(f->description));
+ f->pixelformat = formats[index].fourcc;
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct s2255_fh *fh = priv;
+
+ f->fmt.pix.width = fh->width;
+ f->fmt.pix.height = fh->height;
+ f->fmt.pix.field = fh->vb_vidq.field;
+ f->fmt.pix.pixelformat = fh->fmt->fourcc;
+ f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3);
+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ const struct s2255_fmt *fmt;
+ enum v4l2_field field;
+ int b_any_field = 0;
+ struct s2255_fh *fh = priv;
+ struct s2255_dev *dev = fh->dev;
+ int is_ntsc;
+
+ is_ntsc =
+ (dev->vdev[fh->channel]->current_norm & V4L2_STD_NTSC) ? 1 : 0;
+
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+
+ if (fmt == NULL)
+ return -EINVAL;
+
+ field = f->fmt.pix.field;
+ if (field == V4L2_FIELD_ANY)
+ b_any_field = 1;
+
+ dprintk(4, "try format %d \n", is_ntsc);
+ /* supports 3 sizes. see s2255drv.h */
+ dprintk(50, "width test %d, height %d\n",
+ f->fmt.pix.width, f->fmt.pix.height);
+ if (is_ntsc) {
+ /* NTSC */
+ if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
+ f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
+ if (b_any_field) {
+ field = V4L2_FIELD_SEQ_TB;
+ } else if (!((field == V4L2_FIELD_INTERLACED) ||
+ (field == V4L2_FIELD_SEQ_TB) ||
+ (field == V4L2_FIELD_INTERLACED_TB))) {
+ dprintk(1, "unsupported field setting\n");
+ return -EINVAL;
+ }
+ } else {
+ f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
+ if (b_any_field) {
+ field = V4L2_FIELD_TOP;
+ } else if (!((field == V4L2_FIELD_TOP) ||
+ (field == V4L2_FIELD_BOTTOM))) {
+ dprintk(1, "unsupported field setting\n");
+ return -EINVAL;
+ }
+
+ }
+ if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
+ f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
+ else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC)
+ f->fmt.pix.width = LINE_SZ_2CIFS_NTSC;
+ else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC)
+ f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
+ else
+ f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
+ } else {
+ /* PAL */
+ if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
+ f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
+ if (b_any_field) {
+ field = V4L2_FIELD_SEQ_TB;
+ } else if (!((field == V4L2_FIELD_INTERLACED) ||
+ (field == V4L2_FIELD_SEQ_TB) ||
+ (field == V4L2_FIELD_INTERLACED_TB))) {
+ dprintk(1, "unsupported field setting\n");
+ return -EINVAL;
+ }
+ } else {
+ f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
+ if (b_any_field) {
+ field = V4L2_FIELD_TOP;
+ } else if (!((field == V4L2_FIELD_TOP) ||
+ (field == V4L2_FIELD_BOTTOM))) {
+ dprintk(1, "unsupported field setting\n");
+ return -EINVAL;
+ }
+ }
+ if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) {
+ dprintk(50, "pal 704\n");
+ f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
+ field = V4L2_FIELD_SEQ_TB;
+ } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) {
+ dprintk(50, "pal 352A\n");
+ f->fmt.pix.width = LINE_SZ_2CIFS_PAL;
+ field = V4L2_FIELD_TOP;
+ } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) {
+ dprintk(50, "pal 352B\n");
+ f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
+ field = V4L2_FIELD_TOP;
+ } else {
+ dprintk(50, "pal 352C\n");
+ f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
+ field = V4L2_FIELD_TOP;
+ }
+ }
+
+ dprintk(50, "width %d height %d field %d \n", f->fmt.pix.width,
+ f->fmt.pix.height, f->fmt.pix.field);
+ f->fmt.pix.field = field;
+ f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
+ f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct s2255_fh *fh = priv;
+ const struct s2255_fmt *fmt;
+ struct videobuf_queue *q = &fh->vb_vidq;
+ int ret;
+ int norm;
+
+ ret = vidioc_try_fmt_vid_cap(file, fh, f);
+
+ if (ret < 0)
+ return ret;
+
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+
+ if (fmt == NULL)
+ return -EINVAL;
+
+ mutex_lock(&q->vb_lock);
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ dprintk(1, "queue busy\n");
+ ret = -EBUSY;
+ goto out_s_fmt;
+ }
+
+ if (res_locked(fh->dev, fh)) {
+ dprintk(1, "can't change format after started\n");
+ ret = -EBUSY;
+ goto out_s_fmt;
+ }
+
+ fh->fmt = fmt;
+ fh->width = f->fmt.pix.width;
+ fh->height = f->fmt.pix.height;
+ fh->vb_vidq.field = f->fmt.pix.field;
+ fh->type = f->type;
+ norm = norm_minw(fh->dev->vdev[fh->channel]);
+ if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) {
+ if (fh->height > norm_minh(fh->dev->vdev[fh->channel]))
+ fh->mode.scale = SCALE_4CIFS;
+ else
+ fh->mode.scale = SCALE_2CIFS;
+
+ } else {
+ fh->mode.scale = SCALE_1CIFS;
+ }
+
+ /* color mode */
+ switch (fh->fmt->fourcc) {
+ case V4L2_PIX_FMT_GREY:
+ fh->mode.color = COLOR_Y8;
+ break;
+ case V4L2_PIX_FMT_YUV422P:
+ fh->mode.color = COLOR_YUVPL;
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ default:
+ fh->mode.color = COLOR_YUVPK;
+ break;
+ }
+ ret = 0;
+out_s_fmt:
+ mutex_unlock(&q->vb_lock);
+ return ret;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+{
+ int rc;
+ struct s2255_fh *fh = priv;
+ rc = videobuf_reqbufs(&fh->vb_vidq, p);
+ return rc;
+}
+
+static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ int rc;
+ struct s2255_fh *fh = priv;
+ rc = videobuf_querybuf(&fh->vb_vidq, p);
+ return rc;
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ int rc;
+ struct s2255_fh *fh = priv;
+ rc = videobuf_qbuf(&fh->vb_vidq, p);
+ return rc;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ int rc;
+ struct s2255_fh *fh = priv;
+ rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK);
+ return rc;
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+ struct s2255_fh *fh = priv;
+
+ return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+}
+#endif
+
+/* write to the configuration pipe, synchronously */
+static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
+ int size)
+{
+ int pipe;
+ int done;
+ long retval = -1;
+ if (udev) {
+ pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
+ retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
+ }
+ return retval;
+}
+
+static u32 get_transfer_size(struct s2255_mode *mode)
+{
+ int linesPerFrame = LINE_SZ_DEF;
+ int pixelsPerLine = NUM_LINES_DEF;
+ u32 outImageSize;
+ u32 usbInSize;
+ unsigned int mask_mult;
+
+ if (mode == NULL)
+ return 0;
+
+ if (mode->format == FORMAT_NTSC) {
+ switch (mode->scale) {
+ case SCALE_4CIFS:
+ linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
+ pixelsPerLine = LINE_SZ_4CIFS_NTSC;
+ break;
+ case SCALE_2CIFS:
+ linesPerFrame = NUM_LINES_2CIFS_NTSC;
+ pixelsPerLine = LINE_SZ_2CIFS_NTSC;
+ break;
+ case SCALE_1CIFS:
+ linesPerFrame = NUM_LINES_1CIFS_NTSC;
+ pixelsPerLine = LINE_SZ_1CIFS_NTSC;
+ break;
+ default:
+ break;
+ }
+ } else if (mode->format == FORMAT_PAL) {
+ switch (mode->scale) {
+ case SCALE_4CIFS:
+ linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
+ pixelsPerLine = LINE_SZ_4CIFS_PAL;
+ break;
+ case SCALE_2CIFS:
+ linesPerFrame = NUM_LINES_2CIFS_PAL;
+ pixelsPerLine = LINE_SZ_2CIFS_PAL;
+ break;
+ case SCALE_1CIFS:
+ linesPerFrame = NUM_LINES_1CIFS_PAL;
+ pixelsPerLine = LINE_SZ_1CIFS_PAL;
+ break;
+ default:
+ break;
+ }
+ }
+ outImageSize = linesPerFrame * pixelsPerLine;
+ if (mode->color != COLOR_Y8) {
+ /* 2 bytes/pixel if not monochrome */
+ outImageSize *= 2;
+ }
+
+ /* total bytes to send including prefix and 4K padding;
+ must be a multiple of USB_READ_SIZE */
+ usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
+ mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
+ /* if size not a multiple of USB_READ_SIZE */
+ if (usbInSize & ~mask_mult)
+ usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
+ return usbInSize;
+}
+
+static void dump_verify_mode(struct s2255_dev *sdev, struct s2255_mode *mode)
+{
+ struct device *dev = &sdev->udev->dev;
+ dev_info(dev, "------------------------------------------------\n");
+ dev_info(dev, "verify mode\n");
+ dev_info(dev, "format: %d\n", mode->format);
+ dev_info(dev, "scale: %d\n", mode->scale);
+ dev_info(dev, "fdec: %d\n", mode->fdec);
+ dev_info(dev, "color: %d\n", mode->color);
+ dev_info(dev, "bright: 0x%x\n", mode->bright);
+ dev_info(dev, "restart: 0x%x\n", mode->restart);
+ dev_info(dev, "usb_block: 0x%x\n", mode->usb_block);
+ dev_info(dev, "single: 0x%x\n", mode->single);
+ dev_info(dev, "------------------------------------------------\n");
+}
+
+/*
+ * set mode is the function which controls the DSP.
+ * the restart parameter in struct s2255_mode should be set whenever
+ * the image size could change via color format, video system or image
+ * size.
+ * When the restart parameter is set, we sleep for ONE frame to allow the
+ * DSP time to get the new frame
+ */
+static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
+ struct s2255_mode *mode)
+{
+ int res;
+ u32 *buffer;
+ unsigned long chn_rev;
+
+ chn_rev = G_chnmap[chn];
+ dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale);
+ dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn],
+ dev->mode[chn].scale);
+ dprintk(2, "mode contrast %x\n", mode->contrast);
+
+ /* save the mode */
+ dev->mode[chn] = *mode;
+ dev->req_image_size[chn] = get_transfer_size(mode);
+ dprintk(1, "transfer size %ld\n", dev->req_image_size[chn]);
+
+ buffer = kzalloc(512, GFP_KERNEL);
+ if (buffer == NULL) {
+ dev_err(&dev->udev->dev, "out of mem\n");
+ return -ENOMEM;
+ }
+
+ /* set the mode */
+ buffer[0] = IN_DATA_TOKEN;
+ buffer[1] = (u32) chn_rev;
+ buffer[2] = CMD_SET_MODE;
+ memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
+ res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
+ if (debug)
+ dump_verify_mode(dev, mode);
+ kfree(buffer);
+ dprintk(1, "set mode done chn %lu, %d\n", chn, res);
+
+ /* wait at least 3 frames before continuing */
+ if (mode->restart)
+ msleep(125);
+
+ /* clear the restart flag */
+ dev->mode[chn].restart = 0;
+
+ return res;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ int res;
+ struct s2255_fh *fh = priv;
+ struct s2255_dev *dev = fh->dev;
+ struct s2255_mode *new_mode;
+ struct s2255_mode *old_mode;
+ int chn;
+ int j;
+ dprintk(4, "%s\n", __func__);
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dev_err(&dev->udev->dev, "invalid fh type0\n");
+ return -EINVAL;
+ }
+ if (i != fh->type) {
+ dev_err(&dev->udev->dev, "invalid fh type1\n");
+ return -EINVAL;
+ }
+
+ if (!res_get(dev, fh)) {
+ dev_err(&dev->udev->dev, "res get busy\n");
+ return -EBUSY;
+ }
+
+ /* send a set mode command everytime with restart.
+ in case we switch resolutions or other parameters */
+ chn = fh->channel;
+ new_mode = &fh->mode;
+ old_mode = &fh->dev->mode[chn];
+
+ if (new_mode->color != old_mode->color)
+ new_mode->restart = 1;
+ else if (new_mode->scale != old_mode->scale)
+ new_mode->restart = 1;
+ else if (new_mode->format != old_mode->format)
+ new_mode->restart = 1;
+
+ s2255_set_mode(dev, chn, new_mode);
+ new_mode->restart = 0;
+ *old_mode = *new_mode;
+ dev->cur_fmt[chn] = fh->fmt;
+ dprintk(1, "%s[%d]\n", __func__, chn);
+ dev->last_frame[chn] = -1;
+ dev->bad_payload[chn] = 0;
+ dev->cur_frame[chn] = 0;
+ for (j = 0; j < SYS_FRAMES; j++) {
+ dev->buffer[chn].frame[j].ulState = 0;
+ dev->buffer[chn].frame[j].cur_size = 0;
+ }
+ res = videobuf_streamon(&fh->vb_vidq);
+ if (res == 0) {
+ s2255_start_acquire(dev, chn);
+ dev->b_acquire[chn] = 1;
+ } else {
+ res_free(dev, fh);
+ }
+ return res;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ int res;
+ struct s2255_fh *fh = priv;
+ struct s2255_dev *dev = fh->dev;
+
+ dprintk(4, "%s\n, channel: %d", __func__, fh->channel);
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ printk(KERN_ERR "invalid fh type0\n");
+ return -EINVAL;
+ }
+ if (i != fh->type) {
+ printk(KERN_ERR "invalid type i\n");
+ return -EINVAL;
+ }
+ s2255_stop_acquire(dev, fh->channel);
+ res = videobuf_streamoff(&fh->vb_vidq);
+ res_free(dev, fh);
+ return res;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
+{
+ struct s2255_fh *fh = priv;
+ struct s2255_mode *mode;
+ struct videobuf_queue *q = &fh->vb_vidq;
+ int ret = 0;
+
+ mutex_lock(&q->vb_lock);
+ if (videobuf_queue_is_busy(q)) {
+ dprintk(1, "queue busy\n");
+ ret = -EBUSY;
+ goto out_s_std;
+ }
+
+ if (res_locked(fh->dev, fh)) {
+ dprintk(1, "can't change standard after started\n");
+ ret = -EBUSY;
+ goto out_s_std;
+ }
+ mode = &fh->mode;
+
+ if (*i & V4L2_STD_NTSC) {
+ dprintk(4, "vidioc_s_std NTSC\n");
+ mode->format = FORMAT_NTSC;
+ } else if (*i & V4L2_STD_PAL) {
+ dprintk(4, "vidioc_s_std PAL\n");
+ mode->format = FORMAT_PAL;
+ } else {
+ ret = -EINVAL;
+ }
+out_s_std:
+ mutex_unlock(&q->vb_lock);
+ return ret;
+}
+
+/* Sensoray 2255 is a multiple channel capture device.
+ It does not have a "crossbar" of inputs.
+ We use one V4L device per channel. The user must
+ be aware that certain combinations are not allowed.
+ For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
+ at once in color(you can do full fps on 4 channels with greyscale.
+*/
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ if (inp->index != 0)
+ return -EINVAL;
+
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ inp->std = S2255_NORMS;
+ strlcpy(inp->name, "Camera", sizeof(inp->name));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ if (i > 0)
+ return -EINVAL;
+ return 0;
+}
+
+/* --- controls ---------------------------------------------- */
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++)
+ if (qc->id && qc->id == s2255_qctrl[i].id) {
+ memcpy(qc, &(s2255_qctrl[i]), sizeof(*qc));
+ return 0;
+ }
+
+ dprintk(4, "query_ctrl -EINVAL %d\n", qc->id);
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++)
+ if (ctrl->id == s2255_qctrl[i].id) {
+ ctrl->value = qctl_regs[i];
+ return 0;
+ }
+ dprintk(4, "g_ctrl -EINVAL\n");
+
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ int i;
+ struct s2255_fh *fh = priv;
+ struct s2255_dev *dev = fh->dev;
+ struct s2255_mode *mode;
+ mode = &fh->mode;
+ dprintk(4, "vidioc_s_ctrl\n");
+ for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) {
+ if (ctrl->id == s2255_qctrl[i].id) {
+ if (ctrl->value < s2255_qctrl[i].minimum ||
+ ctrl->value > s2255_qctrl[i].maximum)
+ return -ERANGE;
+
+ qctl_regs[i] = ctrl->value;
+ /* update the mode to the corresponding value */
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ mode->bright = ctrl->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ mode->contrast = ctrl->value;
+ break;
+ case V4L2_CID_HUE:
+ mode->hue = ctrl->value;
+ break;
+ case V4L2_CID_SATURATION:
+ mode->saturation = ctrl->value;
+ break;
+ }
+ mode->restart = 0;
+ /* set mode here. Note: stream does not need restarted.
+ some V4L programs restart stream unnecessarily
+ after a s_crtl.
+ */
+ s2255_set_mode(dev, fh->channel, mode);
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static int s2255_open(struct inode *inode, struct file *file)
+{
+ int minor = iminor(inode);
+ struct s2255_dev *h, *dev = NULL;
+ struct s2255_fh *fh;
+ struct list_head *list;
+ enum v4l2_buf_type type = 0;
+ int i = 0;
+ int cur_channel = -1;
+ dprintk(1, "s2255: open called (minor=%d)\n", minor);
+
+ list_for_each(list, &s2255_devlist) {
+ h = list_entry(list, struct s2255_dev, s2255_devlist);
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (h->vdev[i]->minor == minor) {
+ cur_channel = i;
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+ }
+ }
+
+ if ((NULL == dev) || (cur_channel == -1)) {
+ dprintk(1, "s2255: openv4l no dev\n");
+ return -ENODEV;
+ }
+
+ mutex_lock(&dev->open_lock);
+
+ dev->users[cur_channel]++;
+ if (dev->users[cur_channel] > S2255_MAX_USERS) {
+ dev->users[cur_channel]--;
+ mutex_unlock(&dev->open_lock);
+ printk(KERN_INFO "s2255drv: too many open handles!\n");
+ return -EBUSY;
+ }
+
+ if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) {
+ err("2255 firmware load failed. retrying.\n");
+ s2255_fwload_start(dev);
+ wait_event_timeout(dev->fw_data->wait_fw,
+ (atomic_read(&dev->fw_data->fw_state)
+ != S2255_FW_NOTLOADED),
+ msecs_to_jiffies(S2255_LOAD_TIMEOUT));
+ if (atomic_read(&dev->fw_data->fw_state)
+ != S2255_FW_SUCCESS) {
+ printk(KERN_INFO "2255 FW load failed after 2 tries\n");
+ mutex_unlock(&dev->open_lock);
+ return -EFAULT;
+ }
+ } else if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_NOTLOADED) {
+ /* give S2255_LOAD_TIMEOUT time for firmware to load in case
+ driver loaded and then device immediately opened */
+ printk(KERN_INFO "%s waiting for firmware load\n", __func__);
+ wait_event_timeout(dev->fw_data->wait_fw,
+ (atomic_read(&dev->fw_data->fw_state)
+ != S2255_FW_NOTLOADED),
+ msecs_to_jiffies(S2255_LOAD_TIMEOUT));
+ if (atomic_read(&dev->fw_data->fw_state)
+ != S2255_FW_SUCCESS) {
+ printk(KERN_INFO "2255 firmware not loaded"
+ "try again\n");
+ mutex_unlock(&dev->open_lock);
+ return -EBUSY;
+ }
+ }
+
+ /* allocate + initialize per filehandle data */
+ fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+ if (NULL == fh) {
+ mutex_unlock(&dev->open_lock);
+ return -ENOMEM;
+ }
+
+ file->private_data = fh;
+ fh->dev = dev;
+ fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fh->mode = dev->mode[cur_channel];
+ fh->fmt = dev->cur_fmt[cur_channel];
+ /* default 4CIF NTSC */
+ fh->width = LINE_SZ_4CIFS_NTSC;
+ fh->height = NUM_LINES_4CIFS_NTSC * 2;
+ fh->channel = cur_channel;
+
+ /* Put all controls at a sane state */
+ for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++)
+ qctl_regs[i] = s2255_qctrl[i].default_value;
+
+ dprintk(1, "s2255drv: open minor=%d type=%s users=%d\n",
+ minor, v4l2_type_names[type], dev->users[cur_channel]);
+ dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n",
+ (unsigned long)fh, (unsigned long)dev,
+ (unsigned long)&dev->vidq[cur_channel]);
+ dprintk(4, "s2255drv: open: list_empty active=%d\n",
+ list_empty(&dev->vidq[cur_channel].active));
+
+ videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
+ NULL, &dev->slock,
+ fh->type,
+ V4L2_FIELD_INTERLACED,
+ sizeof(struct s2255_buffer), fh);
+
+ kref_get(&dev->kref);
+ mutex_unlock(&dev->open_lock);
+ return 0;
+}
+
+
+static unsigned int s2255_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct s2255_fh *fh = file->private_data;
+ int rc;
+ dprintk(100, "%s\n", __func__);
+
+ if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+ return POLLERR;
+
+ rc = videobuf_poll_stream(file, &fh->vb_vidq, wait);
+ return rc;
+}
+
+static void s2255_destroy(struct kref *kref)
+{
+ struct s2255_dev *dev = to_s2255_dev(kref);
+ if (!dev) {
+ printk(KERN_ERR "s2255drv: kref problem\n");
+ return;
+ }
+ /* prevent s2255_disconnect from racing s2255_open */
+ mutex_lock(&dev->open_lock);
+ s2255_exit_v4l(dev);
+ /* device unregistered so no longer possible to open. open_mutex
+ can be unlocked */
+ mutex_unlock(&dev->open_lock);
+
+ /* board shutdown stops the read pipe if it is running */
+ s2255_board_shutdown(dev);
+
+ /* make sure firmware still not trying to load */
+ if (dev->fw_data->fw_urb) {
+ dprintk(2, "kill fw_urb\n");
+ usb_kill_urb(dev->fw_data->fw_urb);
+ usb_free_urb(dev->fw_data->fw_urb);
+ dev->fw_data->fw_urb = NULL;
+ }
+ /*
+ * TODO: fixme(above, below): potentially leaving timers alive.
+ * do not ignore timeout below if
+ * it occurs.
+ */
+
+ /* make sure we aren't waiting for the DSP */
+ if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) {
+ /* if we are, wait for the wakeup for fw_success or timeout */
+ wait_event_timeout(dev->fw_data->wait_fw,
+ (atomic_read(&dev->fw_data->fw_state)
+ == S2255_FW_SUCCESS),
+ msecs_to_jiffies(S2255_LOAD_TIMEOUT));
+ }
+
+ if (dev->fw_data) {
+ if (dev->fw_data->fw)
+ release_firmware(dev->fw_data->fw);
+ kfree(dev->fw_data->pfw_data);
+ kfree(dev->fw_data);
+ }
+
+ usb_put_dev(dev->udev);
+ dprintk(1, "%s", __func__);
+ kfree(dev);
+}
+
+static int s2255_close(struct inode *inode, struct file *file)
+{
+ struct s2255_fh *fh = file->private_data;
+ struct s2255_dev *dev = fh->dev;
+ int minor = iminor(inode);
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->open_lock);
+
+ if (dev->b_acquire[fh->channel])
+ s2255_stop_acquire(dev, fh->channel);
+ res_free(dev, fh);
+ videobuf_mmap_free(&fh->vb_vidq);
+ kfree(fh);
+ dev->users[fh->channel]--;
+ mutex_unlock(&dev->open_lock);
+
+ kref_put(&dev->kref, s2255_destroy);
+ dprintk(1, "s2255: close called (minor=%d, users=%d)\n",
+ minor, dev->users[fh->channel]);
+ return 0;
+}
+
+static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma)
+{
+ struct s2255_fh *fh = file->private_data;
+ int ret;
+
+ if (!fh)
+ return -ENODEV;
+ dprintk(4, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
+
+ ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+ dprintk(4, "vma start=0x%08lx, size=%ld, ret=%d\n",
+ (unsigned long)vma->vm_start,
+ (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
+
+ return ret;
+}
+
+static const struct file_operations s2255_fops_v4l = {
+ .owner = THIS_MODULE,
+ .open = s2255_open,
+ .release = s2255_close,
+ .poll = s2255_poll,
+ .ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .compat_ioctl = v4l_compat_ioctl32,
+ .mmap = s2255_mmap_v4l,
+ .llseek = no_llseek,
+};
+
+static struct video_device template = {
+ .name = "s2255v",
+ .type = VID_TYPE_CAPTURE,
+ .fops = &s2255_fops_v4l,
+ .minor = -1,
+ .release = video_device_release,
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidioc_cgmbuf,
+#endif
+ .tvnorms = S2255_NORMS,
+ .current_norm = V4L2_STD_NTSC_M,
+};
+
+static int s2255_probe_v4l(struct s2255_dev *dev)
+{
+ int ret;
+ int i;
+ int cur_nr = video_nr;
+
+ /* initialize all video 4 linux */
+ list_add_tail(&dev->s2255_devlist, &s2255_devlist);
+ /* register 4 video devices */
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ INIT_LIST_HEAD(&dev->vidq[i].active);
+ dev->vidq[i].dev = dev;
+ dev->vidq[i].channel = i;
+ dev->vidq[i].kthread = NULL;
+ /* register 4 video devices */
+ dev->vdev[i] = video_device_alloc();
+ memcpy(dev->vdev[i], &template, sizeof(struct video_device));
+ dev->vdev[i]->dev = &dev->interface->dev;
+ if (video_nr == -1)
+ ret = video_register_device(dev->vdev[i],
+ VFL_TYPE_GRABBER,
+ video_nr);
+ else
+ ret = video_register_device(dev->vdev[i],
+ VFL_TYPE_GRABBER,
+ cur_nr + i);
+ dev->vdev[i]->priv = dev;
+
+ if (ret != 0) {
+ dev_err(&dev->udev->dev,
+ "failed to register video device!\n");
+ return ret;
+ }
+ }
+ printk(KERN_INFO "Sensoray 2255 V4L driver\n");
+ return ret;
+}
+
+static void s2255_exit_v4l(struct s2255_dev *dev)
+{
+ struct list_head *list;
+ int i;
+ /* unregister the video devices */
+ while (!list_empty(&s2255_devlist)) {
+ list = s2255_devlist.next;
+ list_del(list);
+ }
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (-1 != dev->vdev[i]->minor)
+ video_unregister_device(dev->vdev[i]);
+ else
+ video_device_release(dev->vdev[i]);
+ }
+}
+
+/* this function moves the usb stream read pipe data
+ * into the system buffers.
+ * returns 0 on success, EAGAIN if more data to process( call this
+ * function again).
+ *
+ * Received frame structure:
+ * bytes 0-3: marker : 0x2255DA4AL (FRAME_MARKER)
+ * bytes 4-7: channel: 0-3
+ * bytes 8-11: payload size: size of the frame
+ * bytes 12-payloadsize+12: frame data
+ */
+static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
+{
+ static int dbgsync; /* = 0; */
+ char *pdest;
+ u32 offset = 0;
+ int bsync = 0;
+ int btrunc = 0;
+ char *psrc;
+ unsigned long copy_size;
+ unsigned long size;
+ s32 idx = -1;
+ struct s2255_framei *frm;
+ unsigned char *pdata;
+ unsigned long cur_size;
+ int bsearch = 0;
+ struct s2255_bufferi *buf;
+ dprintk(100, "buffer to user\n");
+
+ idx = dev->cur_frame[dev->cc];
+ buf = &dev->buffer[dev->cc];
+ frm = &buf->frame[idx];
+
+ if (frm->ulState == 0) {
+ frm->ulState = 1;
+ frm->cur_size = 0;
+ bsearch = 1;
+ } else if (frm->ulState == 2) {
+ /* system frame was not freed */
+ dprintk(2, "sys frame not free. overrun ringbuf\n");
+ bsearch = 1;
+ frm->ulState = 1;
+ frm->cur_size = 0;
+ }
+
+ if (bsearch) {
+ if (*(s32 *) pipe_info->transfer_buffer != FRAME_MARKER) {
+ u32 jj;
+ if (dbgsync == 0) {
+ dprintk(3, "not synched, discarding all packets"
+ "until marker\n");
+
+ dbgsync++;
+ }
+ pdata = (unsigned char *)pipe_info->transfer_buffer;
+ for (jj = 0; jj < (pipe_info->cur_transfer_size - 12);
+ jj++) {
+ if (*(s32 *) pdata == FRAME_MARKER) {
+ int cc;
+ dprintk(3,
+ "found frame marker at offset:"
+ " %d [%x %x]\n", jj, pdata[0],
+ pdata[1]);
+ offset = jj;
+ bsync = 1;
+ cc = *(u32 *) (pdata + sizeof(u32));
+ if (cc >= MAX_CHANNELS) {
+ printk(KERN_ERR
+ "bad channel\n");
+ return -EINVAL;
+ }
+ /* reverse it */
+ dev->cc = G_chnmap[cc];
+ break;
+ }
+ pdata++;
+ }
+ if (bsync == 0)
+ return -EINVAL;
+ } else {
+ u32 *pword;
+ u32 payload;
+ int cc;
+ dbgsync = 0;
+ bsync = 1;
+ pword = (u32 *) pipe_info->transfer_buffer;
+ cc = pword[1];
+
+ if (cc >= MAX_CHANNELS) {
+ printk("invalid channel found. "
+ "throwing out data!\n");
+ return -EINVAL;
+ }
+ dev->cc = G_chnmap[cc];
+ payload = pword[2];
+ if (payload != dev->req_image_size[dev->cc]) {
+ dprintk(1, "[%d][%d]unexpected payload: %d"
+ "required: %lu \n", cc, dev->cc,
+ payload, dev->req_image_size[dev->cc]);
+ dev->bad_payload[dev->cc]++;
+ /* discard the bad frame */
+ return -EINVAL;
+ }
+
+ }
+ }
+ /* search done. now find out if should be acquiring
+ on this channel */
+ if (!dev->b_acquire[dev->cc]) {
+ frm->ulState = 0;
+ return -EINVAL;
+ }
+
+ idx = dev->cur_frame[dev->cc];
+ frm = &dev->buffer[dev->cc].frame[idx];
+
+ if (frm->ulState == 0) {
+ frm->ulState = 1;
+ frm->cur_size = 0;
+ } else if (frm->ulState == 2) {
+ /* system frame ring buffer overrun */
+ dprintk(2, "sys frame overrun. overwriting frame %d %d\n",
+ dev->cc, idx);
+ frm->ulState = 1;
+ frm->cur_size = 0;
+ }
+
+ if (bsync) {
+ /* skip the marker 512 bytes (and offset if out of sync) */
+ psrc = (u8 *)pipe_info->transfer_buffer + offset + PREFIX_SIZE;
+ } else {
+ psrc = (u8 *)pipe_info->transfer_buffer;
+ }
+
+ if (frm->lpvbits == NULL) {
+ dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d",
+ frm, dev, dev->cc, idx);
+ return -ENOMEM;
+ }
+
+ pdest = frm->lpvbits + frm->cur_size;
+
+ if (bsync) {
+ copy_size =
+ (pipe_info->cur_transfer_size - offset) - PREFIX_SIZE;
+ if (copy_size > pipe_info->cur_transfer_size) {
+ printk("invalid copy size, overflow!\n");
+ return -ENOMEM;
+ }
+ } else {
+ copy_size = pipe_info->cur_transfer_size;
+ }
+
+ cur_size = frm->cur_size;
+ size = dev->req_image_size[dev->cc];
+
+ if ((copy_size + cur_size) > size) {
+ copy_size = size - cur_size;
+ btrunc = 1;
+ }
+
+ memcpy(pdest, psrc, copy_size);
+ cur_size += copy_size;
+ frm->cur_size += copy_size;
+ dprintk(50, "cur_size size %lu size %lu \n", cur_size, size);
+
+ if (cur_size >= (size - PREFIX_SIZE)) {
+ u32 cc = dev->cc;
+ frm->ulState = 2;
+ dprintk(2, "****************[%d]Buffer[%d]full*************\n",
+ cc, idx);
+ dev->last_frame[cc] = dev->cur_frame[cc];
+ dev->cur_frame[cc]++;
+ /* end of system frame ring buffer, start at zero */
+ if ((dev->cur_frame[cc] == SYS_FRAMES) ||
+ (dev->cur_frame[cc] == dev->buffer[cc].dwFrames))
+ dev->cur_frame[cc] = 0;
+
+ /* signal the semaphore for this channel */
+ if (dev->b_acquire[cc])
+ s2255_got_frame(dev, cc);
+ dev->frame_count[cc]++;
+ }
+ /* frame was truncated */
+ if (btrunc) {
+ /* return more data to process */
+ return EAGAIN;
+ }
+ /* done successfully */
+ return 0;
+}
+
+static void s2255_read_video_callback(struct s2255_dev *dev,
+ struct s2255_pipeinfo *pipe_info)
+{
+ int res;
+ dprintk(50, "callback read video \n");
+
+ if (dev->cc >= MAX_CHANNELS) {
+ dev->cc = 0;
+ dev_err(&dev->udev->dev, "invalid channel\n");
+ return;
+ }
+ /* otherwise copy to the system buffers */
+ res = save_frame(dev, pipe_info);
+ if (res == EAGAIN)
+ save_frame(dev, pipe_info);
+
+ dprintk(50, "callback read video done\n");
+ return;
+}
+
+static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
+ u16 Index, u16 Value, void *TransferBuffer,
+ s32 TransferBufferLength, int bOut)
+{
+ int r;
+ if (!bOut) {
+ r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+ Request,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+ USB_DIR_IN,
+ Value, Index, TransferBuffer,
+ TransferBufferLength, HZ * 5);
+ } else {
+ r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ Value, Index, TransferBuffer,
+ TransferBufferLength, HZ * 5);
+ }
+ return r;
+}
+
+/*
+ * retrieve FX2 firmware version. future use.
+ * @param dev pointer to device extension
+ * @return -1 for fail, else returns firmware version as an int(16 bits)
+ */
+static int s2255_get_fx2fw(struct s2255_dev *dev)
+{
+ int fw;
+ int ret;
+ unsigned char transBuffer[64];
+ ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
+ S2255_VR_IN);
+ if (ret < 0)
+ dprintk(2, "get fw error: %x\n", ret);
+ fw = transBuffer[0] + (transBuffer[1] << 8);
+ dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
+ return fw;
+}
+
+/*
+ * Create the system ring buffer to copy frames into from the
+ * usb read pipe.
+ */
+static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)
+{
+ unsigned long i;
+ unsigned long reqsize;
+ dprintk(1, "create sys buffers\n");
+ if (chn >= MAX_CHANNELS)
+ return -1;
+
+ dev->buffer[chn].dwFrames = SYS_FRAMES;
+
+ /* always allocate maximum size(PAL) for system buffers */
+ reqsize = SYS_FRAMES_MAXSIZE;
+
+ if (reqsize > SYS_FRAMES_MAXSIZE)
+ reqsize = SYS_FRAMES_MAXSIZE;
+
+ for (i = 0; i < SYS_FRAMES; i++) {
+ /* allocate the frames */
+ dev->buffer[chn].frame[i].lpvbits = vmalloc(reqsize);
+
+ dprintk(1, "valloc %p chan %lu, idx %lu, pdata %p\n",
+ &dev->buffer[chn].frame[i], chn, i,
+ dev->buffer[chn].frame[i].lpvbits);
+ dev->buffer[chn].frame[i].size = reqsize;
+ if (dev->buffer[chn].frame[i].lpvbits == NULL) {
+ printk(KERN_INFO "out of memory. using less frames\n");
+ dev->buffer[chn].dwFrames = i;
+ break;
+ }
+ }
+
+ /* make sure internal states are set */
+ for (i = 0; i < SYS_FRAMES; i++) {
+ dev->buffer[chn].frame[i].ulState = 0;
+ dev->buffer[chn].frame[i].cur_size = 0;
+ }
+
+ dev->cur_frame[chn] = 0;
+ dev->last_frame[chn] = -1;
+ return 0;
+}
+
+static int s2255_release_sys_buffers(struct s2255_dev *dev,
+ unsigned long channel)
+{
+ unsigned long i;
+ dprintk(1, "release sys buffers\n");
+ for (i = 0; i < SYS_FRAMES; i++) {
+ if (dev->buffer[channel].frame[i].lpvbits) {
+ dprintk(1, "vfree %p\n",
+ dev->buffer[channel].frame[i].lpvbits);
+ vfree(dev->buffer[channel].frame[i].lpvbits);
+ }
+ dev->buffer[channel].frame[i].lpvbits = NULL;
+ }
+ return 0;
+}
+
+static int s2255_board_init(struct s2255_dev *dev)
+{
+ int j;
+ struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
+ int fw_ver;
+ dprintk(4, "board init: %p", dev);
+
+ for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
+ struct s2255_pipeinfo *pipe = &dev->pipes[j];
+
+ memset(pipe, 0, sizeof(*pipe));
+ pipe->dev = dev;
+ pipe->cur_transfer_size = DEFAULT_PIPE_USBBLOCK;
+ pipe->max_transfer_size = MAX_PIPE_USBBLOCK;
+
+ if (pipe->cur_transfer_size > pipe->max_transfer_size)
+ pipe->cur_transfer_size = pipe->max_transfer_size;
+ pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
+ GFP_KERNEL);
+ if (pipe->transfer_buffer == NULL) {
+ dprintk(1, "out of memory!\n");
+ return -ENOMEM;
+ }
+
+ }
+
+ /* query the firmware */
+ fw_ver = s2255_get_fx2fw(dev);
+
+ printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
+ if (fw_ver < CUR_USB_FWVER)
+ err("usb firmware not up to date %d\n", fw_ver);
+
+ for (j = 0; j < MAX_CHANNELS; j++) {
+ dev->b_acquire[j] = 0;
+ dev->mode[j] = mode_def;
+ dev->cur_fmt[j] = &formats[0];
+ dev->mode[j].restart = 1;
+ dev->req_image_size[j] = get_transfer_size(&mode_def);
+ dev->frame_count[j] = 0;
+ /* create the system buffers */
+ s2255_create_sys_buffers(dev, j);
+ }
+ /* start read pipe */
+ s2255_start_readpipe(dev);
+
+ dprintk(1, "S2255: board initialized\n");
+ return 0;
+}
+
+static int s2255_board_shutdown(struct s2255_dev *dev)
+{
+ u32 i;
+
+ dprintk(1, "S2255: board shutdown: %p", dev);
+
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (dev->b_acquire[i])
+ s2255_stop_acquire(dev, i);
+ }
+
+ s2255_stop_readpipe(dev);
+
+ for (i = 0; i < MAX_CHANNELS; i++)
+ s2255_release_sys_buffers(dev, i);
+
+ /* release transfer buffers */
+ for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
+ struct s2255_pipeinfo *pipe = &dev->pipes[i];
+ kfree(pipe->transfer_buffer);
+ }
+ return 0;
+}
+
+static void read_pipe_completion(struct urb *purb)
+{
+ struct s2255_pipeinfo *pipe_info;
+ struct s2255_dev *dev;
+ int status;
+ int pipe;
+
+ pipe_info = purb->context;
+ dprintk(100, "read pipe completion %p, status %d\n", purb,
+ purb->status);
+ if (pipe_info == NULL) {
+ err("no context !");
+ return;
+ }
+
+ dev = pipe_info->dev;
+ if (dev == NULL) {
+ err("no context !");
+ return;
+ }
+ status = purb->status;
+ if (status != 0) {
+ dprintk(2, "read_pipe_completion: err\n");
+ return;
+ }
+
+ if (pipe_info->state == 0) {
+ dprintk(2, "exiting USB pipe");
+ return;
+ }
+
+ s2255_read_video_callback(dev, pipe_info);
+
+ pipe_info->err_count = 0;
+ pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
+ /* reuse urb */
+ usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
+ pipe,
+ pipe_info->transfer_buffer,
+ pipe_info->cur_transfer_size,
+ read_pipe_completion, pipe_info);
+
+ if (pipe_info->state != 0) {
+ if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
+ dev_err(&dev->udev->dev, "error submitting urb\n");
+ usb_free_urb(pipe_info->stream_urb);
+ }
+ } else {
+ dprintk(2, "read pipe complete state 0\n");
+ }
+ return;
+}
+
+static int s2255_start_readpipe(struct s2255_dev *dev)
+{
+ int pipe;
+ int retval;
+ int i;
+ struct s2255_pipeinfo *pipe_info = dev->pipes;
+ pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
+ dprintk(2, "start pipe IN %d\n", dev->read_endpoint);
+
+ for (i = 0; i < MAX_PIPE_BUFFERS; i++) {
+ pipe_info->state = 1;
+ pipe_info->buf_index = (u32) i;
+ pipe_info->priority_set = 0;
+ pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!pipe_info->stream_urb) {
+ dev_err(&dev->udev->dev,
+ "ReadStream: Unable to alloc URB");
+ return -ENOMEM;
+ }
+ /* transfer buffer allocated in board_init */
+ usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
+ pipe,
+ pipe_info->transfer_buffer,
+ pipe_info->cur_transfer_size,
+ read_pipe_completion, pipe_info);
+
+ pipe_info->urb_size = sizeof(pipe_info->stream_urb);
+ dprintk(4, "submitting URB %p\n", pipe_info->stream_urb);
+ retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
+ if (retval) {
+ printk(KERN_ERR "s2255: start read pipe failed\n");
+ return retval;
+ }
+ }
+
+ return 0;
+}
+
+/* starts acquisition process */
+static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
+{
+ unsigned char *buffer;
+ int res;
+ unsigned long chn_rev;
+ int j;
+ if (chn >= MAX_CHANNELS) {
+ dprintk(2, "start acquire failed, bad channel %lu\n", chn);
+ return -1;
+ }
+
+ chn_rev = G_chnmap[chn];
+ dprintk(1, "S2255: start acquire %lu \n", chn);
+
+ buffer = kzalloc(512, GFP_KERNEL);
+ if (buffer == NULL) {
+ dev_err(&dev->udev->dev, "out of mem\n");
+ return -ENOMEM;
+ }
+
+ dev->last_frame[chn] = -1;
+ dev->bad_payload[chn] = 0;
+ dev->cur_frame[chn] = 0;
+ for (j = 0; j < SYS_FRAMES; j++) {
+ dev->buffer[chn].frame[j].ulState = 0;
+ dev->buffer[chn].frame[j].cur_size = 0;
+ }
+
+ /* send the start command */
+ *(u32 *) buffer = IN_DATA_TOKEN;
+ *((u32 *) buffer + 1) = (u32) chn_rev;
+ *((u32 *) buffer + 2) = (u32) CMD_START;
+ res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
+ if (res != 0)
+ dev_err(&dev->udev->dev, "CMD_START error\n");
+
+ dprintk(2, "start acquire exit[%lu] %d \n", chn, res);
+ kfree(buffer);
+ return 0;
+}
+
+static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
+{
+ unsigned char *buffer;
+ int res;
+ unsigned long chn_rev;
+
+ if (chn >= MAX_CHANNELS) {
+ dprintk(2, "stop acquire failed, bad channel %lu\n", chn);
+ return -1;
+ }
+ chn_rev = G_chnmap[chn];
+
+ buffer = kzalloc(512, GFP_KERNEL);
+ if (buffer == NULL) {
+ dev_err(&dev->udev->dev, "out of mem\n");
+ return -ENOMEM;
+ }
+
+ /* send the stop command */
+ dprintk(4, "stop acquire %lu\n", chn);
+ *(u32 *) buffer = IN_DATA_TOKEN;
+ *((u32 *) buffer + 1) = (u32) chn_rev;
+ *((u32 *) buffer + 2) = CMD_STOP;
+ res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
+
+ if (res != 0)
+ dev_err(&dev->udev->dev, "CMD_STOP error\n");
+
+ dprintk(4, "stop acquire: releasing states \n");
+
+ kfree(buffer);
+ dev->b_acquire[chn] = 0;
+
+ return 0;
+}
+
+static void s2255_stop_readpipe(struct s2255_dev *dev)
+{
+ int j;
+
+ if (dev == NULL) {
+ err("s2255: invalid device");
+ return;
+ }
+ dprintk(4, "stop read pipe\n");
+ for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
+ struct s2255_pipeinfo *pipe_info = &dev->pipes[j];
+ if (pipe_info) {
+ if (pipe_info->state == 0)
+ continue;
+ pipe_info->state = 0;
+ pipe_info->prev_state = 1;
+
+ }
+ }
+
+ for (j = 0; j < MAX_PIPE_BUFFERS; j++) {
+ struct s2255_pipeinfo *pipe_info = &dev->pipes[j];
+ if (pipe_info->stream_urb) {
+ /* cancel urb */
+ usb_kill_urb(pipe_info->stream_urb);
+ usb_free_urb(pipe_info->stream_urb);
+ pipe_info->stream_urb = NULL;
+ }
+ }
+ dprintk(2, "s2255 stop read pipe: %d\n", j);
+ return;
+}
+
+static void s2255_fwload_start(struct s2255_dev *dev)
+{
+ dev->fw_data->fw_size = dev->fw_data->fw->size;
+ atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
+ memcpy(dev->fw_data->pfw_data,
+ dev->fw_data->fw->data, CHUNK_SIZE);
+ dev->fw_data->fw_loaded = CHUNK_SIZE;
+ usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, 2),
+ dev->fw_data->pfw_data,
+ CHUNK_SIZE, s2255_fwchunk_complete,
+ dev->fw_data);
+ mod_timer(&dev->timer, jiffies + HZ);
+}
+
+/* standard usb probe function */
+static int s2255_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct s2255_dev *dev = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int i;
+ int retval = -ENOMEM;
+
+ dprintk(2, "s2255: probe\n");
+
+ /* allocate memory for our device state and initialize it to zero */
+ dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
+ if (dev == NULL) {
+ err("s2255: out of memory");
+ goto error;
+ }
+
+ dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
+ if (!dev->fw_data)
+ goto error;
+
+ mutex_init(&dev->lock);
+ mutex_init(&dev->open_lock);
+
+ /* grab usb_device and save it */
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+ if (dev->udev == NULL) {
+ dev_err(&interface->dev, "null usb device\n");
+ retval = -ENODEV;
+ goto error;
+ }
+ kref_init(&dev->kref);
+ dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref,
+ dev->udev, interface);
+ dev->interface = interface;
+ /* set up the endpoint information */
+ iface_desc = interface->cur_altsetting;
+ dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints);
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+ if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
+ /* we found the bulk in endpoint */
+ dev->read_endpoint = endpoint->bEndpointAddress;
+ }
+ }
+
+ if (!dev->read_endpoint) {
+ dev_err(&interface->dev, "Could not find bulk-in endpoint");
+ goto error;
+ }
+
+ /* set intfdata */
+ usb_set_intfdata(interface, dev);
+
+ dprintk(100, "after intfdata %p\n", dev);
+
+ init_timer(&dev->timer);
+ dev->timer.function = s2255_timer;
+ dev->timer.data = (unsigned long)dev->fw_data;
+
+ init_waitqueue_head(&dev->fw_data->wait_fw);
+
+
+ dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (!dev->fw_data->fw_urb) {
+ dev_err(&interface->dev, "out of memory!\n");
+ goto error;
+ }
+ dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
+ if (!dev->fw_data->pfw_data) {
+ dev_err(&interface->dev, "out of memory!\n");
+ goto error;
+ }
+ /* load the first chunk */
+ if (request_firmware(&dev->fw_data->fw,
+ FIRMWARE_FILE_NAME, &dev->udev->dev)) {
+ printk(KERN_ERR "sensoray 2255 failed to get firmware\n");
+ goto error;
+ }
+
+ /* loads v4l specific */
+ s2255_probe_v4l(dev);
+ /* load 2255 board specific */
+ s2255_board_init(dev);
+
+ dprintk(4, "before probe done %p\n", dev);
+ spin_lock_init(&dev->slock);
+
+ s2255_fwload_start(dev);
+ dev_info(&interface->dev, "Sensoray 2255 detected\n");
+ return 0;
+error:
+ return retval;
+}
+
+/* disconnect routine. when board is removed physically or with rmmod */
+static void s2255_disconnect(struct usb_interface *interface)
+{
+ struct s2255_dev *dev = NULL;
+ dprintk(1, "s2255: disconnect interface %p\n", interface);
+ dev = usb_get_intfdata(interface);
+ if (dev) {
+ kref_put(&dev->kref, s2255_destroy);
+ dprintk(1, "s2255drv: disconnect\n");
+ dev_info(&interface->dev, "s2255usb now disconnected\n");
+ }
+ usb_set_intfdata(interface, NULL);
+}
+
+static struct usb_driver s2255_driver = {
+ .name = "s2255",
+ .probe = s2255_probe,
+ .disconnect = s2255_disconnect,
+ .id_table = s2255_table,
+};
+
+static int __init usb_s2255_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&s2255_driver);
+
+ if (result)
+ err("usb_register failed. Error number %d", result);
+
+ dprintk(2, "s2255_init: done\n");
+ return result;
+}
+
+static void __exit usb_s2255_exit(void)
+{
+ usb_deregister(&s2255_driver);
+}
+
+module_init(usb_s2255_init);
+module_exit(usb_s2255_exit);
+
+MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
+MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 996b49491f5..03e772130b5 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -66,6 +66,7 @@ static struct video_device saa_template; /* Declared near bottom */
/* Addresses to scan */
static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END };
+
I2C_CLIENT_INSMOD;
static struct i2c_client client_template;
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index ec8c65dc840..fde99d9ee71 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -130,6 +130,7 @@ static struct video_device saa_template; /* Declared near bottom */
/* Addresses to scan */
static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END};
+
I2C_CLIENT_INSMOD;
static struct i2c_client client_template;
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 716ee7f64df..f05024259f0 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,6 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
-
#include <media/rds.h>
/* Addresses to scan */
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 435c083cc54..bcd1c8f6cf6 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -67,7 +67,6 @@ static unsigned short normal_i2c[] = {
0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
I2C_CLIENT_END };
-
I2C_CLIENT_INSMOD;
struct saa711x_state {
@@ -1558,7 +1557,7 @@ static int saa7115_remove(struct i2c_client *client)
}
static const struct i2c_device_id saa7115_id[] = {
- { "saa711x", 1 }, /* autodetect */
+ { "saa7115_auto", 1 }, /* autodetect */
{ "saa7111", 0 },
{ "saa7113", 0 },
{ "saa7114", 0 },
@@ -1577,4 +1576,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.id_table = saa7115_id,
};
-
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
deleted file mode 100644
index cedb988574b..00000000000
--- a/drivers/media/video/saa711x.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * saa711x - Philips SAA711x video decoder driver version 0.0.1
- *
- * To do: Now, it handles only saa7113/7114. Should be improved to
- * handle all Philips saa711x devices.
- *
- * Based on saa7113 driver from Dave Perks <dperks@ibm.net>
- *
- * 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 <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/types.h>
-#include <asm/uaccess.h>
-#include <linux/videodev.h>
-
-MODULE_DESCRIPTION("Philips SAA711x video decoder driver");
-MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden");
-MODULE_LICENSE("GPL");
-
-#include <linux/i2c.h>
-
-#define I2C_NAME(s) (s)->name
-
-#include <linux/video_decoder.h>
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
-
-
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
-/* ----------------------------------------------------------------------- */
-
-struct saa711x {
- unsigned char reg[32];
-
- int norm;
- int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
-};
-
-#define I2C_SAA7113 0x4A
-#define I2C_SAA7114 0x42
-
-/* ----------------------------------------------------------------------- */
-
-static inline int
-saa711x_write (struct i2c_client *client,
- u8 reg,
- u8 value)
-{
- struct saa711x *decoder = i2c_get_clientdata(client);
-
- decoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int
-saa711x_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
-{
- int ret = -1;
- u8 reg;
-
- /* the saa711x has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- struct saa711x *decoder = i2c_get_clientdata(client);
- struct i2c_msg msg;
- u8 block_data[32];
-
- msg.addr = client->addr;
- msg.flags = 0;
- while (len >= 2) {
- msg.buf = (char *) block_data;
- msg.len = 0;
- block_data[msg.len++] = reg = data[0];
- do {
- block_data[msg.len++] =
- decoder->reg[reg++] = data[1];
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg &&
- msg.len < 32);
- if ((ret = i2c_transfer(client->adapter,
- &msg, 1)) < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- if ((ret = saa711x_write(client, reg,
- *data++)) < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static int
-saa711x_init_decoder (struct i2c_client *client,
- struct video_decoder_init *init)
-{
- return saa711x_write_block(client, init->data, init->len);
-}
-
-static inline int
-saa711x_read (struct i2c_client *client,
- u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const unsigned char saa711x_i2c_init[] = {
- 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */
- 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
- 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
- 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
- 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
- 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
- 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
- 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
- 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
- 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
- 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
- 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
- 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
- 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
- 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
- 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
- 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
- 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
- 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
- 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
- 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
- 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
- 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
- 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
-};
-
-static int
-saa711x_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
-{
- struct saa711x *decoder = i2c_get_clientdata(client);
-
- switch (cmd) {
-
- case 0:
- case DECODER_INIT:
- {
- struct video_decoder_init *init = arg;
- if (NULL != init)
- return saa711x_init_decoder(client, init);
- else {
- struct video_decoder_init vdi;
- vdi.data = saa711x_i2c_init;
- vdi.len = sizeof(saa711x_i2c_init);
- return saa711x_init_decoder(client, &vdi);
- }
- }
-
- case DECODER_DUMP:
- {
- int i;
-
- for (i = 0; i < 32; i += 16) {
- int j;
-
- printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
- for (j = 0; j < 16; ++j) {
- printk(" %02x",
- saa711x_read(client, i + j));
- }
- printk("\n");
- }
- }
- break;
-
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
-
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- }
- break;
-
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
-
- status = saa711x_read(client, 0x1f);
- dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
- status);
- res = 0;
- if ((status & (1 << 6)) == 0) {
- res |= DECODER_STATUS_GOOD;
- }
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & (1 << 5)) != 0) {
- res |= DECODER_STATUS_NTSC;
- } else {
- res |= DECODER_STATUS_PAL;
- }
- break;
- }
- if ((status & (1 << 0)) != 0) {
- res |= DECODER_STATUS_COLOR;
- }
- *iarg = res;
- }
- break;
-
- case DECODER_SET_GPIO:
- {
- int *iarg = arg;
- if (0 != *iarg) {
- saa711x_write(client, 0x11,
- (decoder->reg[0x11] | 0x80));
- } else {
- saa711x_write(client, 0x11,
- (decoder->reg[0x11] & 0x7f));
- }
- break;
- }
-
- case DECODER_SET_VBI_BYPASS:
- {
- int *iarg = arg;
- if (0 != *iarg) {
- saa711x_write(client, 0x13,
- (decoder->reg[0x13] & 0xf0) | 0x0a);
- } else {
- saa711x_write(client, 0x13,
- (decoder->reg[0x13] & 0xf0));
- }
- break;
- }
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- switch (*iarg) {
-
- case VIDEO_MODE_NTSC:
- saa711x_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x40);
- saa711x_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- case VIDEO_MODE_PAL:
- saa711x_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x00);
- saa711x_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- case VIDEO_MODE_SECAM:
- saa711x_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x00);
- saa711x_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f) | 0x50);
- break;
-
- case VIDEO_MODE_AUTO:
- saa711x_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x80);
- saa711x_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- default:
- return -EINVAL;
-
- }
- decoder->norm = *iarg;
- }
- break;
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
- if (*iarg < 0 || *iarg > 9) {
- return -EINVAL;
- }
- if (decoder->input != *iarg) {
- decoder->input = *iarg;
- /* select mode */
- saa711x_write(client, 0x02,
- (decoder->reg[0x02] & 0xf0) | decoder->input);
- /* bypass chrominance trap for modes 4..7 */
- saa711x_write(client, 0x09,
- (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
- }
- }
- break;
-
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- }
- break;
-
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
-
- /* RJ: If output should be disabled (for
- * playing videos), we also need a open PLL.
- * The input is set to 0 (where no input
- * source is connected), although this
- * is not necessary.
- *
- * If output should be enabled, we have to
- * reverse the above.
- */
-
- if (decoder->enable) {
- saa711x_write(client, 0x02,
- (decoder->
- reg[0x02] & 0xf8) |
- decoder->input);
- saa711x_write(client, 0x08,
- (decoder->reg[0x08] & 0xfb));
- saa711x_write(client, 0x11,
- (decoder->
- reg[0x11] & 0xf3) | 0x0c);
- } else {
- saa711x_write(client, 0x02,
- (decoder->reg[0x02] & 0xf8));
- saa711x_write(client, 0x08,
- (decoder->
- reg[0x08] & 0xfb) | 0x04);
- saa711x_write(client, 0x11,
- (decoder->reg[0x11] & 0xf3));
- }
- }
- }
- break;
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa711x_write(client, 0x0a, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa711x_write(client, 0x0b,
- decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa711x_write(client, 0x0c, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa711x_write(client, 0x0d,
- (decoder->hue - 32768) >> 8);
- }
- }
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-
-/* standard i2c insmod options */
-static unsigned short normal_i2c[] = {
- I2C_SAA7113>>1, /* saa7113 */
- I2C_SAA7114>>1, /* saa7114 */
- I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
-
-
-static struct i2c_driver i2c_driver_saa711x;
-
-static int
-saa711x_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
-{
- int i;
- struct i2c_client *client;
- struct saa711x *decoder;
- struct video_decoder_init vdi;
-
- dprintk(1,
- KERN_INFO
- "saa711x.c: detecting saa711x client on address 0x%x\n",
- address << 1);
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == 0)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa711x;
- strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
- decoder = kzalloc(sizeof(struct saa711x), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
- return -ENOMEM;
- }
- decoder->norm = VIDEO_MODE_NTSC;
- decoder->input = 0;
- decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
- i2c_set_clientdata(client, decoder);
-
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
- vdi.data = saa711x_i2c_init;
- vdi.len = sizeof(saa711x_i2c_init);
- i = saa711x_init_decoder(client, &vdi);
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x at address 0x%x\n",
- I2C_NAME(client), saa711x_read(client, 0x00) >> 4,
- client->addr << 1);
- }
-
- return 0;
-}
-
-static int
-saa711x_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "saa711x.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
-}
-
-static int
-saa711x_detach_client (struct i2c_client *client)
-{
- struct saa711x *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver i2c_driver_saa711x = {
- .driver = {
- .name = "saa711x",
- },
- .id = I2C_DRIVERID_SAA711X,
- .attach_adapter = saa711x_attach_adapter,
- .detach_client = saa711x_detach_client,
- .command = saa711x_command,
-};
-
-static int __init
-saa711x_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa711x);
-}
-
-static void __exit
-saa711x_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa711x);
-}
-
-module_init(saa711x_init);
-module_exit(saa711x_exit);
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 79d11a658bd..d0e83fe0ff5 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -666,7 +666,6 @@ static int saa7127_probe(struct i2c_client *client,
{
struct saa7127_state *state;
struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
- int read_result = 0;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -710,20 +709,29 @@ static int saa7127_probe(struct i2c_client *client,
saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
saa7127_set_video_enable(client, 1);
- /* Detect if it's an saa7129 */
- read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
- saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
- if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
- v4l_info(client, "saa7129 found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
- saa7127_write_inittab(client, saa7129_init_config_extra);
- state->ident = V4L2_IDENT_SAA7129;
- } else {
- v4l_info(client, "saa7127 found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
- state->ident = V4L2_IDENT_SAA7127;
+ if (id->driver_data) { /* Chip type is already known */
+ state->ident = id->driver_data;
+ } else { /* Needs detection */
+ int read_result;
+
+ /* Detect if it's an saa7129 */
+ read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
+ saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
+ if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
+ saa7127_write(client, SAA7129_REG_FADE_KEY_COL2,
+ read_result);
+ state->ident = V4L2_IDENT_SAA7129;
+ strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
+ } else {
+ state->ident = V4L2_IDENT_SAA7127;
+ strlcpy(client->name, "saa7127", I2C_NAME_SIZE);
+ }
}
+
+ v4l_info(client, "%s found @ 0x%x (%s)\n", client->name,
+ client->addr << 1, client->adapter->name);
+ if (state->ident == V4L2_IDENT_SAA7129)
+ saa7127_write_inittab(client, saa7129_init_config_extra);
return 0;
}
@@ -740,7 +748,11 @@ static int saa7127_remove(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
static struct i2c_device_id saa7127_id[] = {
- { "saa7127", 0 },
+ { "saa7127_auto", 0 }, /* auto-detection */
+ { "saa7126", V4L2_IDENT_SAA7127 },
+ { "saa7127", V4L2_IDENT_SAA7127 },
+ { "saa7128", V4L2_IDENT_SAA7129 },
+ { "saa7129", V4L2_IDENT_SAA7129 },
{ }
};
MODULE_DEVICE_TABLE(i2c, saa7127_id);
@@ -753,4 +765,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.remove = saa7127_remove,
.id_table = saa7127_id,
};
-
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 002e70a33a4..707be175509 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/crc32.h>
-
#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
@@ -21,6 +20,7 @@
/* Addresses to scan */
static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
+
I2C_CLIENT_INSMOD;
MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
@@ -448,6 +448,104 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params,
return 0;
}
+static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params,
+ struct v4l2_queryctrl *qctrl)
+{
+ int err;
+
+ switch (qctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_L2_BITRATE_256K,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
+ V4L2_MPEG_AUDIO_L2_BITRATE_256K);
+
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_ASPECT_4x3,
+ V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ err = v4l2_ctrl_query_fill_std(qctrl);
+ if (err == 0 &&
+ params->vi_bitrate_mode ==
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return err;
+
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ return v4l2_ctrl_query_fill_std(qctrl);
+
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params,
+ struct v4l2_querymenu *qmenu)
+{
+ static const char *mpeg_audio_l2_bitrate[] = {
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "256 kbps",
+ "",
+ "384 kbps",
+ NULL
+ };
+ struct v4l2_queryctrl qctrl;
+ int err;
+
+ qctrl.id = qmenu->id;
+ err = saa6752hs_qctrl(params, &qctrl);
+ if (err)
+ return err;
+ if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE)
+ return v4l2_ctrl_query_menu(qmenu, &qctrl,
+ mpeg_audio_l2_bitrate);
+ return v4l2_ctrl_query_menu(qmenu, &qctrl,
+ v4l2_ctrl_get_menu(qmenu->id));
+}
+
static int saa6752hs_init(struct i2c_client* client)
{
unsigned char buf[9], buf2[4];
@@ -609,7 +707,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
i2c_attach_client(&h->client);
v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1);
-
return 0;
}
@@ -662,6 +759,10 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
}
h->params = params;
break;
+ case VIDIOC_QUERYCTRL:
+ return saa6752hs_qctrl(&h->params, arg);
+ case VIDIOC_QUERYMENU:
+ return saa6752hs_qmenu(&h->params, arg);
case VIDIOC_G_FMT:
{
struct v4l2_format *f = arg;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index f118de6e367..9929d20320b 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -80,7 +80,6 @@ typedef struct snd_card_saa7134 {
} snd_card_saa7134_t;
-
/*
* PCM structure
*/
@@ -1121,6 +1120,3 @@ late_initcall(saa7134_alsa_init);
module_exit(saa7134_alsa_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ricardo Cerqueira");
-
-
-
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 2618cfa592e..6893f998d29 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1287,6 +1287,22 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 8,
}},
},
+ [SAA7134_BOARD_AVERMEDIA_M103] = {
+ /* Massimo Piccioni <dafastidio@libero.it> */
+ .name = "AVerMedia MiniPCI DVB-T Hybrid M103",
+ .audio_clock = 0x187de7,
+ .tuner_type = TUNER_XC2028,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ } },
+ },
[SAA7134_BOARD_NOVAC_PRIMETV7133] = {
/* toshii@netbsd.org */
.name = "Noval Prime TV 7133",
@@ -3503,6 +3519,39 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.gpio = 0x0200000,
},
+ },
+ [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = {
+ .name = "ASUSTeK P7131 Analog",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .gpiomask = 1 << 21,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x0000000,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ }, {
+ .name = name_comp2,
+ .vmux = 0,
+ .amux = LINE2,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0200000,
+ },
},
[SAA7134_BOARD_SABRENT_TV_PCB05] = {
.name = "Sabrent PCMCIA TV-PCB05",
@@ -3940,32 +3989,111 @@ struct saa7134_board saa7134_boards[] = {
[SAA7134_BOARD_BEHOLD_M6] = {
/* Igor Kuznetsov <igk@igk.ru> */
/* Andrey Melnikoff <temnota@kmv.ru> */
- .name = "Beholder BeholdTV M6 / BeholdTV M6 Extra",
+ /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV M6",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .inputs = {{
+ .inputs = { {
.name = name_tv,
.vmux = 3,
.amux = TV,
.tv = 1,
- },{
+ }, {
.name = name_comp1,
.vmux = 1,
.amux = LINE1,
- },{
+ }, {
.name = name_svideo,
.vmux = 8,
.amux = LINE1,
- }},
+ } },
.radio = {
.name = name_radio,
.amux = LINE2,
},
.mpeg = SAA7134_MPEG_EMPRESS,
+ .video_out = CCIR656,
+ .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED |
+ SET_CLOCK_NOT_DELAYED |
+ SET_CLOCK_INVERTED |
+ SET_VSYNC_OFF),
+ },
+ [SAA7134_BOARD_BEHOLD_M63] = {
+ /* Igor Kuznetsov <igk@igk.ru> */
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV M63",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ .mpeg = SAA7134_MPEG_EMPRESS,
+ .video_out = CCIR656,
+ .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED |
+ SET_CLOCK_NOT_DELAYED |
+ SET_CLOCK_INVERTED |
+ SET_VSYNC_OFF),
+ },
+ [SAA7134_BOARD_BEHOLD_M6_EXTRA] = {
+ /* Igor Kuznetsov <igk@igk.ru> */
+ /* Andrey Melnikoff <temnota@kmv.ru> */
+ /* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
+ .name = "Beholder BeholdTV M6 Extra",
+ .audio_clock = 0x00187de7,
+ /* FIXME: Must be PHILIPS_FM1216ME_MK5*/
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = { {
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 1,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = LINE2,
+ },
+ .mpeg = SAA7134_MPEG_EMPRESS,
+ .video_out = CCIR656,
+ .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED |
+ SET_CLOCK_NOT_DELAYED |
+ SET_CLOCK_INVERTED |
+ SET_VSYNC_OFF),
},
[SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = {
.name = "Twinhan Hybrid DTV-DVB 3056 PCI",
@@ -4121,9 +4249,9 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.tv = 1,
}, {
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE2,
+ .name = name_comp,
+ .vmux = 0,
+ .amux = LINE1,
}, {
.name = name_svideo,
.vmux = 8,
@@ -4141,6 +4269,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -4150,6 +4279,10 @@ struct saa7134_board saa7134_boards[] = {
.name = name_svideo,
.vmux = 8,
.amux = LINE1,
+ }, {
+ .name = name_comp,
+ .vmux = 0,
+ .amux = LINE1,
} },
.radio = {
.name = name_radio,
@@ -4163,7 +4296,6 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -5226,13 +5358,13 @@ struct pci_device_id saa7134_pci_tbl[] = {
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6193,
- .driver_data = SAA7134_BOARD_BEHOLD_M6,
+ .driver_data = SAA7134_BOARD_BEHOLD_M6_EXTRA,
}, {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6191,
- .driver_data = SAA7134_BOARD_BEHOLD_M6,
+ .driver_data = SAA7134_BOARD_BEHOLD_M63,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -5284,10 +5416,22 @@ struct pci_device_id saa7134_pci_tbl[] = {
}, {
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x5169,
+ .subdevice = 0x1502,
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
+ }, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x5ace,
.subdevice = 0x6290,
.driver_data = SAA7134_BOARD_BEHOLD_H6,
}, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xf636,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
+ }, {
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -5352,6 +5496,7 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
switch (dev->board) {
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ case SAA7134_BOARD_AVERMEDIA_M103:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
saa7134_set_gpio(dev, 23, 1);
@@ -5493,6 +5638,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_FLYDVBT_LR301:
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
+ case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
case SAA7134_BOARD_FLYDVBTDUO:
case SAA7134_BOARD_PROTEUS_2309:
case SAA7134_BOARD_AVERMEDIA_A16AR:
@@ -5560,6 +5706,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
msleep(10);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ case SAA7134_BOARD_AVERMEDIA_M103:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
saa7134_set_gpio(dev, 23, 1);
@@ -5601,6 +5748,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
case SAA7134_BOARD_BEHOLD_607_9FM:
case SAA7134_BOARD_BEHOLD_M6:
+ case SAA7134_BOARD_BEHOLD_M63:
+ case SAA7134_BOARD_BEHOLD_M6_EXTRA:
dev->has_remote = SAA7134_REMOTE_I2C;
break;
case SAA7134_BOARD_AVERMEDIA_A169_B:
@@ -5683,6 +5832,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_AVERMEDIA_A16D:
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ case SAA7134_BOARD_AVERMEDIA_M103:
ctl.demod = XC3028_FE_ZARLINK456;
break;
default:
@@ -5825,6 +5975,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
+ case SAA7134_BOARD_ASUSTeK_TVFM7135:
+ /* The card below is detected as card=53, but is different */
+ if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
+ dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
+ printk(KERN_INFO "%s: P7131 analog only, using "
+ "entry of %s\n",
+ dev->name, saa7134_boards[dev->board].name);
+ }
+ break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
hauppauge_eeprom(dev, dev->eedata+0x80);
/* break intentionally omitted */
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 2c19cd0113c..cfee84ee7a8 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -150,7 +150,6 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value)
#if defined(CONFIG_MODULES) && defined(MODULE)
-
static void request_module_async(struct work_struct *work){
struct saa7134_dev* dev = container_of(work, struct saa7134_dev, request_module_wk);
if (card_is_empress(dev))
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 341b101b035..be48b9b66a6 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1263,6 +1263,7 @@ static int dvb_init(struct saa7134_dev *dev)
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
+ break;
case SAA7134_BOARD_MD7134_BRIDGE_2:
dev->dvb.frontend = dvb_attach(tda10086_attach,
&sd1878_4m, &dev->i2c_adap);
@@ -1290,6 +1291,15 @@ static int dvb_init(struct saa7134_dev *dev)
fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage;
}
break;
+ case SAA7134_BOARD_AVERMEDIA_M103:
+ saa7134_set_gpio(dev, 25, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 25, 1);
+ dev->dvb.frontend = dvb_attach(mt352_attach,
+ &avermedia_xc3028_mt352_dev,
+ &dev->i2c_adap);
+ attach_xc3028 = 1;
+ break;
default:
wprintk("Huh? unknown DVB card?\n");
break;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 3ae71a34082..2a5ab957542 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -208,7 +208,7 @@ static int empress_s_input(struct file *file, void *priv, unsigned int i)
return 0;
}
-static int empress_enum_fmt_cap(struct file *file, void *priv,
+static int empress_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (f->index != 0)
@@ -220,7 +220,7 @@ static int empress_enum_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int empress_g_fmt_cap(struct file *file, void *priv,
+static int empress_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_dev *dev = file->private_data;
@@ -233,7 +233,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int empress_s_fmt_cap(struct file *file, void *priv,
+static int empress_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_dev *dev = file->private_data;
@@ -294,10 +294,20 @@ static int empress_streamoff(struct file *file, void *priv,
return videobuf_streamoff(&dev->empress_tsq);
}
+static int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
+ unsigned int cmd, void *arg)
+{
+ if (dev->mpeg_i2c_client == NULL)
+ return -EINVAL;
+ return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client,
+ cmd, arg);
+}
+
static int empress_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
struct saa7134_dev *dev = file->private_data;
+ int err;
/* count == 0 is abused in saa6752hs.c, so that special
case is handled here explicitly. */
@@ -307,10 +317,10 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, ctrls);
+ err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls);
ts_init_encoder(dev);
- return 0;
+ return err;
}
static int empress_g_ext_ctrls(struct file *file, void *priv,
@@ -320,9 +330,62 @@ static int empress_g_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+ return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+}
- return 0;
+static int empress_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *c)
+{
+ static const u32 user_ctrls[] = {
+ V4L2_CID_USER_CLASS,
+ V4L2_CID_BRIGHTNESS,
+ V4L2_CID_CONTRAST,
+ V4L2_CID_SATURATION,
+ V4L2_CID_HUE,
+ V4L2_CID_AUDIO_VOLUME,
+ V4L2_CID_AUDIO_MUTE,
+ V4L2_CID_HFLIP,
+ 0
+ };
+
+ static const u32 mpeg_ctrls[] = {
+ V4L2_CID_MPEG_CLASS,
+ V4L2_CID_MPEG_STREAM_TYPE,
+ V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+ V4L2_CID_MPEG_AUDIO_ENCODING,
+ V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+ V4L2_CID_MPEG_VIDEO_ENCODING,
+ V4L2_CID_MPEG_VIDEO_ASPECT,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ 0
+ };
+ static const u32 *ctrl_classes[] = {
+ user_ctrls,
+ mpeg_ctrls,
+ NULL
+ };
+ struct saa7134_dev *dev = file->private_data;
+
+ c->id = v4l2_ctrl_next(ctrl_classes, c->id);
+ if (c->id == 0)
+ return -EINVAL;
+ if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
+ return v4l2_ctrl_query_fill_std(c);
+ if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
+ return saa7134_queryctrl(file, priv, c);
+ return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c);
+}
+
+static int empress_querymenu(struct file *file, void *priv,
+ struct v4l2_querymenu *c)
+{
+ struct saa7134_dev *dev = file->private_data;
+
+ if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+ return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
}
static const struct file_operations ts_fops =
@@ -348,9 +411,9 @@ static struct video_device saa7134_empress_template =
.minor = -1,
.vidioc_querycap = empress_querycap,
- .vidioc_enum_fmt_cap = empress_enum_fmt_cap,
- .vidioc_s_fmt_cap = empress_s_fmt_cap,
- .vidioc_g_fmt_cap = empress_g_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
.vidioc_reqbufs = empress_reqbufs,
.vidioc_querybuf = empress_querybuf,
.vidioc_qbuf = empress_qbuf,
@@ -363,7 +426,8 @@ static struct video_device saa7134_empress_template =
.vidioc_g_input = empress_g_input,
.vidioc_s_input = empress_s_input,
- .vidioc_queryctrl = saa7134_queryctrl,
+ .vidioc_queryctrl = empress_queryctrl,
+ .vidioc_querymenu = empress_querymenu,
.vidioc_g_ctrl = saa7134_g_ctrl,
.vidioc_s_ctrl = saa7134_s_ctrl,
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index d8af3863f2d..5f713e63768 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -327,6 +327,8 @@ static int attach_inform(struct i2c_client *client)
d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
client->driver->driver.name, client->addr, client->name);
+ if (client->addr == 0x20 && client->driver && client->driver->command)
+ dev->mpeg_i2c_client = client;
/* Am I an i2c remote control? */
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 76e6501d238..ad08d13dffd 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -198,6 +198,84 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
+/* Common (grey or coloured) pinnacle PCTV remote handling
+ *
+ */
+static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
+ int parity_offset, int marker, int code_modulo)
+{
+ unsigned char b[4];
+ unsigned int start = 0,parity = 0,code = 0;
+
+ /* poll IR chip */
+ if (4 != i2c_master_recv(&ir->c, b, 4)) {
+ i2cdprintk("read error\n");
+ return -EIO;
+ }
+
+ for (start = 0; start < ARRAY_SIZE(b); start++) {
+ if (b[start] == marker) {
+ code=b[(start+parity_offset + 1) % 4];
+ parity=b[(start+parity_offset) % 4];
+ }
+ }
+
+ /* Empty Request */
+ if (parity == 0)
+ return 0;
+
+ /* Repeating... */
+ if (ir->old == parity)
+ return 0;
+
+ ir->old = parity;
+
+ /* drop special codes when a key is held down a long time for the grey controller
+ In this case, the second bit of the code is asserted */
+ if (marker == 0xfe && (code & 0x40))
+ return 0;
+
+ code %= code_modulo;
+
+ *ir_raw = code;
+ *ir_key = code;
+
+ i2cdprintk("Pinnacle PCTV key %02x\n", code);
+
+ return 1;
+}
+
+/* The grey pinnacle PCTV remote
+ *
+ * There are one issue with this remote:
+ * - I2c packet does not change when the same key is pressed quickly. The workaround
+ * is to hold down each key for about half a second, so that another code is generated
+ * in the i2c packet, and the function can distinguish key presses.
+ *
+ * Sylvain Pasche <sylvain.pasche@gmail.com>
+ */
+static int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+
+ return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff);
+}
+
+
+/* The new pinnacle PCTV remote (with the colored buttons)
+ *
+ * Ricardo Cerqueira <v4l@cerqueira.org>
+ */
+static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE
+ *
+ * this is the only value that results in 42 unique
+ * codes < 128
+ */
+
+ return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88);
+}
+
void saa7134_input_irq(struct saa7134_dev *dev)
{
struct card_ir *ir = dev->remote;
@@ -409,6 +487,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
+ case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
ir_codes = ir_codes_asus_pc39;
mask_keydown = 0x0040000;
rc5_gpio = 1;
@@ -540,6 +619,8 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
break;
case SAA7134_BOARD_BEHOLD_607_9FM:
case SAA7134_BOARD_BEHOLD_M6:
+ case SAA7134_BOARD_BEHOLD_M63:
+ case SAA7134_BOARD_BEHOLD_M6_EXTRA:
case SAA7134_BOARD_BEHOLD_H6:
snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV");
ir->get_key = get_key_beholdm6xx;
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index 86f5eefdb0f..cf89d96d729 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -368,6 +368,7 @@
#define SAA7135_DSP_RWCLEAR 0x586
#define SAA7135_DSP_RWCLEAR_RERR 1
+#define SAA7133_I2S_AUDIO_CONTROL 0x591
/* ------------------------------------------------------------------ */
/*
* Local variables:
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 232af598d94..c5d0b44c179 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -477,7 +477,6 @@ static int tvaudio_thread(void *data)
unsigned int i, audio, nscan;
int max1,max2,carrier,rx,mode,lastmode,default_carrier;
-
set_freezable();
for (;;) {
@@ -775,7 +774,6 @@ static int tvaudio_thread_ddep(void *data)
struct saa7134_dev *dev = data;
u32 value, norms;
-
set_freezable();
for (;;) {
tvaudio_sleep(dev,-1);
@@ -873,13 +871,34 @@ void saa7134_enable_i2s(struct saa7134_dev *dev)
if (!card_is_empress(dev))
return;
- i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
- /* enable I2S audio output for the mpeg encoder */
- saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
- saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
- saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
- saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
+ if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+ return;
+
+ /* configure GPIO for out */
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000);
+
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ /* Set I2S format (SONY)  */
+ saa_writeb(SAA7133_I2S_AUDIO_CONTROL, 0x00);
+ /* Start I2S */
+ saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11);
+ break;
+
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
+
+ /* enable I2S audio output for the mpeg encoder */
+ saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
+ saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
+ saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
+ saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
+
+ default:
+ break;
+ }
}
int saa7134_tvaudio_rx2mode(u32 rx)
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 48e1a01718e..1a5137550e7 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1496,7 +1496,7 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
/* ------------------------------------------------------------------ */
-static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv,
+static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
@@ -1516,7 +1516,7 @@ static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv,
return 0;
}
-static int saa7134_g_fmt_cap(struct file *file, void *priv,
+static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
@@ -1532,7 +1532,7 @@ static int saa7134_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int saa7134_g_fmt_overlay(struct file *file, void *priv,
+static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
@@ -1546,7 +1546,7 @@ static int saa7134_g_fmt_overlay(struct file *file, void *priv,
return 0;
}
-static int saa7134_try_fmt_cap(struct file *file, void *priv,
+static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
@@ -1597,7 +1597,7 @@ static int saa7134_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int saa7134_try_fmt_overlay(struct file *file, void *priv,
+static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
@@ -1611,13 +1611,13 @@ static int saa7134_try_fmt_overlay(struct file *file, void *priv,
return verify_preview(dev, &f->fmt.win);
}
-static int saa7134_s_fmt_cap(struct file *file, void *priv,
+static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
int err;
- err = saa7134_try_fmt_cap(file, priv, f);
+ err = saa7134_try_fmt_vid_cap(file, priv, f);
if (0 != err)
return err;
@@ -1628,7 +1628,7 @@ static int saa7134_s_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int saa7134_s_fmt_overlay(struct file *file, void *priv,
+static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_format *f)
{
struct saa7134_fh *fh = priv;
@@ -2028,7 +2028,7 @@ static int saa7134_s_priority(struct file *file, void *f,
return v4l2_prio_change(&dev->prio, &fh->prio, prio);
}
-static int saa7134_enum_fmt_cap(struct file *file, void *priv,
+static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (f->index >= FORMATS)
@@ -2042,7 +2042,7 @@ static int saa7134_enum_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int saa7134_enum_fmt_overlay(struct file *file, void *priv,
+static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (saa7134_no_overlay > 0) {
@@ -2061,7 +2061,7 @@ static int saa7134_enum_fmt_overlay(struct file *file, void *priv,
return 0;
}
-static int saa7134_enum_fmt_vbi(struct file *file, void *priv,
+static int saa7134_enum_fmt_vbi_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (0 != f->index)
@@ -2208,6 +2208,32 @@ static int saa7134_g_parm(struct file *file, void *fh,
return 0;
}
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register (struct file *file, void *priv,
+ struct v4l2_register *reg)
+{
+ struct saa7134_fh *fh = priv;
+ struct saa7134_dev *dev = fh->dev;
+
+ if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return -EINVAL;
+ reg->val = saa_readb(reg->reg);
+ return 0;
+}
+
+static int vidioc_s_register (struct file *file, void *priv,
+ struct v4l2_register *reg)
+{
+ struct saa7134_fh *fh = priv;
+ struct saa7134_dev *dev = fh->dev;
+
+ if (!v4l2_chip_match_host(reg->match_type, reg->match_chip))
+ return -EINVAL;
+ saa_writeb(reg->reg&0xffffff, reg->val);
+ return 0;
+}
+#endif
+
static int radio_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
@@ -2348,18 +2374,18 @@ struct video_device saa7134_video_template =
.fops = &video_fops,
.minor = -1,
.vidioc_querycap = saa7134_querycap,
- .vidioc_enum_fmt_cap = saa7134_enum_fmt_cap,
- .vidioc_g_fmt_cap = saa7134_g_fmt_cap,
- .vidioc_try_fmt_cap = saa7134_try_fmt_cap,
- .vidioc_s_fmt_cap = saa7134_s_fmt_cap,
- .vidioc_enum_fmt_overlay = saa7134_enum_fmt_overlay,
- .vidioc_g_fmt_overlay = saa7134_g_fmt_overlay,
- .vidioc_try_fmt_overlay = saa7134_try_fmt_overlay,
- .vidioc_s_fmt_overlay = saa7134_s_fmt_overlay,
- .vidioc_enum_fmt_vbi = saa7134_enum_fmt_vbi,
- .vidioc_g_fmt_vbi = saa7134_try_get_set_fmt_vbi,
- .vidioc_try_fmt_vbi = saa7134_try_get_set_fmt_vbi,
- .vidioc_s_fmt_vbi = saa7134_try_get_set_fmt_vbi,
+ .vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = saa7134_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = saa7134_s_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_overlay = saa7134_enum_fmt_vid_overlay,
+ .vidioc_g_fmt_vid_overlay = saa7134_g_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_overlay = saa7134_try_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = saa7134_s_fmt_vid_overlay,
+ .vidioc_enum_fmt_vbi_cap = saa7134_enum_fmt_vbi_cap,
+ .vidioc_g_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap,
+ .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap,
+ .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap,
.vidioc_g_audio = saa7134_g_audio,
.vidioc_s_audio = saa7134_s_audio,
.vidioc_cropcap = saa7134_cropcap,
@@ -2391,6 +2417,10 @@ struct video_device saa7134_video_template =
.vidioc_g_parm = saa7134_g_parm,
.vidioc_g_frequency = saa7134_g_frequency,
.vidioc_s_frequency = saa7134_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
.tvnorms = SAA7134_NORMS,
.current_norm = V4L2_STD_PAL,
};
@@ -2458,13 +2488,14 @@ int saa7134_videoport_init(struct saa7134_dev *dev)
int vo = saa7134_boards[dev->board].video_out;
int video_reg;
unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
+
+ /* Configure videoport */
saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
video_reg = video_out[vo][1];
if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
video_reg &= ~VP_T_CODE_P_INVERTED;
saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
- saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
video_reg = video_out[vo][5];
if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
@@ -2481,6 +2512,9 @@ int saa7134_videoport_init(struct saa7134_dev *dev)
saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
+ /* Start videoport */
+ saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
+
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 34ff0d4998f..6927cbea862 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -264,7 +264,10 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_A700_PRO 140
#define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141
#define SAA7134_BOARD_BEHOLD_H6 142
-
+#define SAA7134_BOARD_BEHOLD_M63 143
+#define SAA7134_BOARD_BEHOLD_M6_EXTRA 144
+#define SAA7134_BOARD_AVERMEDIA_M103 145
+#define SAA7134_BOARD_ASUSTeK_P7131_ANALOG 146
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
@@ -552,6 +555,7 @@ struct saa7134_dev {
struct saa7134_ts ts;
struct saa7134_dmaqueue ts_q;
struct saa7134_mpeg_ops *mops;
+ struct i2c_client *mpeg_i2c_client;
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
new file mode 100644
index 00000000000..012005e1a77
--- /dev/null
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -0,0 +1,657 @@
+/*
+ * V4L2 Driver for SuperH Mobile CEU interface
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
+ *
+ * Copyright (C) 2006, Sascha Hauer, Pengutronix
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/moduleparam.h>
+#include <linux/time.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/soc_camera.h>
+#include <media/sh_mobile_ceu.h>
+#include <media/videobuf-dma-contig.h>
+
+/* register offsets for sh7722 / sh7723 */
+
+#define CAPSR 0x00
+#define CAPCR 0x04
+#define CAMCR 0x08
+#define CMCYR 0x0c
+#define CAMOR 0x10
+#define CAPWR 0x14
+#define CAIFR 0x18
+#define CSTCR 0x20 /* not on sh7723 */
+#define CSECR 0x24 /* not on sh7723 */
+#define CRCNTR 0x28
+#define CRCMPR 0x2c
+#define CFLCR 0x30
+#define CFSZR 0x34
+#define CDWDR 0x38
+#define CDAYR 0x3c
+#define CDACR 0x40
+#define CDBYR 0x44
+#define CDBCR 0x48
+#define CBDSR 0x4c
+#define CFWCR 0x5c
+#define CLFCR 0x60
+#define CDOCR 0x64
+#define CDDCR 0x68
+#define CDDAR 0x6c
+#define CEIER 0x70
+#define CETCR 0x74
+#define CSTSR 0x7c
+#define CSRTR 0x80
+#define CDSSR 0x84
+#define CDAYR2 0x90
+#define CDACR2 0x94
+#define CDBYR2 0x98
+#define CDBCR2 0x9c
+
+static DEFINE_MUTEX(camera_lock);
+
+/* per video frame buffer */
+struct sh_mobile_ceu_buffer {
+ struct videobuf_buffer vb; /* v4l buffer must be first */
+ const struct soc_camera_data_format *fmt;
+};
+
+struct sh_mobile_ceu_dev {
+ struct device *dev;
+ struct soc_camera_host ici;
+ struct soc_camera_device *icd;
+
+ unsigned int irq;
+ void __iomem *base;
+ unsigned long video_limit;
+
+ spinlock_t lock;
+ struct list_head capture;
+ struct videobuf_buffer *active;
+
+ struct sh_mobile_ceu_info *pdata;
+};
+
+static void ceu_write(struct sh_mobile_ceu_dev *priv,
+ unsigned long reg_offs, unsigned long data)
+{
+ iowrite32(data, priv->base + reg_offs);
+}
+
+static unsigned long ceu_read(struct sh_mobile_ceu_dev *priv,
+ unsigned long reg_offs)
+{
+ return ioread32(priv->base + reg_offs);
+}
+
+/*
+ * Videobuf operations
+ */
+static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
+ unsigned int *count,
+ unsigned int *size)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
+
+ *size = PAGE_ALIGN(icd->width * icd->height * bytes_per_pixel);
+
+ if (0 == *count)
+ *count = 2;
+
+ if (pcdev->video_limit) {
+ while (*size * *count > pcdev->video_limit)
+ (*count)--;
+ }
+
+ dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+
+ return 0;
+}
+
+static void free_buffer(struct videobuf_queue *vq,
+ struct sh_mobile_ceu_buffer *buf)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+ &buf->vb, buf->vb.baddr, buf->vb.bsize);
+
+ if (in_interrupt())
+ BUG();
+
+ videobuf_dma_contig_free(vq, &buf->vb);
+ dev_dbg(&icd->dev, "%s freed\n", __func__);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
+{
+ ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~1);
+ ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & 0x0317f313);
+ ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | 1);
+
+ ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~0x10000);
+
+ ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10);
+
+ if (pcdev->active) {
+ ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active));
+ ceu_write(pcdev, CAPSR, 0x1); /* start capture */
+ }
+}
+
+static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct sh_mobile_ceu_buffer *buf;
+ int ret;
+
+ buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ /* Added list head initialization on alloc */
+ WARN_ON(!list_empty(&vb->queue));
+
+#ifdef DEBUG
+ /* This can be useful if you want to see if we actually fill
+ * the buffer with something */
+ memset((void *)vb->baddr, 0xaa, vb->bsize);
+#endif
+
+ BUG_ON(NULL == icd->current_fmt);
+
+ if (buf->fmt != icd->current_fmt ||
+ vb->width != icd->width ||
+ vb->height != icd->height ||
+ vb->field != field) {
+ buf->fmt = icd->current_fmt;
+ vb->width = icd->width;
+ vb->height = icd->height;
+ vb->field = field;
+ vb->state = VIDEOBUF_NEEDS_INIT;
+ }
+
+ vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
+ if (0 != vb->baddr && vb->bsize < vb->size) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ ret = videobuf_iolock(vq, vb, NULL);
+ if (ret)
+ goto fail;
+ vb->state = VIDEOBUF_PREPARED;
+ }
+
+ return 0;
+fail:
+ free_buffer(vq, buf);
+out:
+ return ret;
+}
+
+static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ unsigned long flags;
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ vb->state = VIDEOBUF_ACTIVE;
+ spin_lock_irqsave(&pcdev->lock, flags);
+ list_add_tail(&vb->queue, &pcdev->capture);
+
+ if (!pcdev->active) {
+ pcdev->active = vb;
+ sh_mobile_ceu_capture(pcdev);
+ }
+
+ spin_unlock_irqrestore(&pcdev->lock, flags);
+}
+
+static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb));
+}
+
+static struct videobuf_queue_ops sh_mobile_ceu_videobuf_ops = {
+ .buf_setup = sh_mobile_ceu_videobuf_setup,
+ .buf_prepare = sh_mobile_ceu_videobuf_prepare,
+ .buf_queue = sh_mobile_ceu_videobuf_queue,
+ .buf_release = sh_mobile_ceu_videobuf_release,
+};
+
+static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
+{
+ struct sh_mobile_ceu_dev *pcdev = data;
+ struct videobuf_buffer *vb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pcdev->lock, flags);
+
+ vb = pcdev->active;
+ list_del_init(&vb->queue);
+
+ if (!list_empty(&pcdev->capture))
+ pcdev->active = list_entry(pcdev->capture.next,
+ struct videobuf_buffer, queue);
+ else
+ pcdev->active = NULL;
+
+ sh_mobile_ceu_capture(pcdev);
+
+ vb->state = VIDEOBUF_DONE;
+ do_gettimeofday(&vb->ts);
+ vb->field_count++;
+ wake_up(&vb->done);
+ spin_unlock_irqrestore(&pcdev->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ int ret = -EBUSY;
+
+ mutex_lock(&camera_lock);
+
+ if (pcdev->icd)
+ goto err;
+
+ dev_info(&icd->dev,
+ "SuperH Mobile CEU driver attached to camera %d\n",
+ icd->devnum);
+
+ if (pcdev->pdata->enable_camera)
+ pcdev->pdata->enable_camera();
+
+ ret = icd->ops->init(icd);
+ if (ret)
+ goto err;
+
+ ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+ while (ceu_read(pcdev, CSTSR) & 1)
+ msleep(1);
+
+ pcdev->icd = icd;
+err:
+ mutex_unlock(&camera_lock);
+
+ return ret;
+}
+
+static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
+ BUG_ON(icd != pcdev->icd);
+
+ /* disable capture, disable interrupts */
+ ceu_write(pcdev, CEIER, 0);
+ ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+ icd->ops->release(icd);
+ if (pcdev->pdata->disable_camera)
+ pcdev->pdata->disable_camera();
+
+ dev_info(&icd->dev,
+ "SuperH Mobile CEU driver detached from camera %d\n",
+ icd->devnum);
+
+ pcdev->icd = NULL;
+}
+
+static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
+ __u32 pixfmt)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ int ret, buswidth, width, cfszr_width, cdwdr_width;
+ unsigned long camera_flags, common_flags, value;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+ common_flags = soc_camera_bus_param_compatible(camera_flags,
+ pcdev->pdata->flags);
+ if (!common_flags)
+ return -EINVAL;
+
+ ret = icd->ops->set_bus_param(icd, common_flags);
+ if (ret < 0)
+ return ret;
+
+ switch (common_flags & SOCAM_DATAWIDTH_MASK) {
+ case SOCAM_DATAWIDTH_8:
+ buswidth = 8;
+ break;
+ case SOCAM_DATAWIDTH_16:
+ buswidth = 16;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ceu_write(pcdev, CRCNTR, 0);
+ ceu_write(pcdev, CRCMPR, 0);
+
+ value = 0x00000010;
+ value |= (common_flags & SOCAM_VSYNC_ACTIVE_LOW) ? (1 << 1) : 0;
+ value |= (common_flags & SOCAM_HSYNC_ACTIVE_LOW) ? (1 << 0) : 0;
+ value |= (buswidth == 16) ? (1 << 12) : 0;
+ ceu_write(pcdev, CAMCR, value);
+
+ ceu_write(pcdev, CAPCR, 0x00300000);
+ ceu_write(pcdev, CAIFR, 0);
+
+ mdelay(1);
+
+ width = icd->width * (icd->current_fmt->depth / 8);
+ width = (buswidth == 16) ? width / 2 : width;
+ cfszr_width = (buswidth == 8) ? width / 2 : width;
+ cdwdr_width = (buswidth == 16) ? width * 2 : width;
+
+ ceu_write(pcdev, CAMOR, 0);
+ ceu_write(pcdev, CAPWR, (icd->height << 16) | width);
+ ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */
+ ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width);
+ ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */
+ ceu_write(pcdev, CDOCR, 0x00000016);
+
+ ceu_write(pcdev, CDWDR, cdwdr_width);
+ ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
+
+ /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
+ /* in data fetch mode: no need for CDACR, CDBYR, CDBCR */
+
+ return 0;
+}
+
+static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
+ __u32 pixfmt)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ unsigned long camera_flags, common_flags;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+ common_flags = soc_camera_bus_param_compatible(camera_flags,
+ pcdev->pdata->flags);
+ if (!common_flags)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int sh_mobile_ceu_set_fmt_cap(struct soc_camera_device *icd,
+ __u32 pixfmt, struct v4l2_rect *rect)
+{
+ return icd->ops->set_fmt_cap(icd, pixfmt, rect);
+}
+
+static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ /* FIXME: calculate using depth and bus width */
+
+ if (f->fmt.pix.height < 4)
+ f->fmt.pix.height = 4;
+ if (f->fmt.pix.height > 1920)
+ f->fmt.pix.height = 1920;
+ if (f->fmt.pix.width < 2)
+ f->fmt.pix.width = 2;
+ if (f->fmt.pix.width > 2560)
+ f->fmt.pix.width = 2560;
+ f->fmt.pix.width &= ~0x01;
+ f->fmt.pix.height &= ~0x03;
+
+ /* limit to sensor capabilities */
+ return icd->ops->try_fmt_cap(icd, f);
+}
+
+static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf,
+ struct v4l2_requestbuffers *p)
+{
+ int i;
+
+ /* This is for locking debugging only. I removed spinlocks and now I
+ * check whether .prepare is ever called on a linked buffer, or whether
+ * a dma IRQ can occur for an in-work or unlinked buffer. Until now
+ * it hadn't triggered */
+ for (i = 0; i < p->count; i++) {
+ struct sh_mobile_ceu_buffer *buf;
+
+ buf = container_of(icf->vb_vidq.bufs[i],
+ struct sh_mobile_ceu_buffer, vb);
+ INIT_LIST_HEAD(&buf->vb.queue);
+ }
+
+ return 0;
+}
+
+static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
+{
+ struct soc_camera_file *icf = file->private_data;
+ struct sh_mobile_ceu_buffer *buf;
+
+ buf = list_entry(icf->vb_vidq.stream.next,
+ struct sh_mobile_ceu_buffer, vb.stream);
+
+ poll_wait(file, &buf->vb.done, pt);
+
+ if (buf->vb.state == VIDEOBUF_DONE ||
+ buf->vb.state == VIDEOBUF_ERROR)
+ return POLLIN|POLLRDNORM;
+
+ return 0;
+}
+
+static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
+ struct v4l2_capability *cap)
+{
+ strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
+ cap->version = KERNEL_VERSION(0, 0, 5);
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ return 0;
+}
+
+static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
+ struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
+ videobuf_queue_dma_contig_init(q,
+ &sh_mobile_ceu_videobuf_ops,
+ &ici->dev, &pcdev->lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_NONE,
+ sizeof(struct sh_mobile_ceu_buffer),
+ icd);
+}
+
+static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
+ .owner = THIS_MODULE,
+ .add = sh_mobile_ceu_add_device,
+ .remove = sh_mobile_ceu_remove_device,
+ .set_fmt_cap = sh_mobile_ceu_set_fmt_cap,
+ .try_fmt_cap = sh_mobile_ceu_try_fmt_cap,
+ .reqbufs = sh_mobile_ceu_reqbufs,
+ .poll = sh_mobile_ceu_poll,
+ .querycap = sh_mobile_ceu_querycap,
+ .try_bus_param = sh_mobile_ceu_try_bus_param,
+ .set_bus_param = sh_mobile_ceu_set_bus_param,
+ .init_videobuf = sh_mobile_ceu_init_videobuf,
+};
+
+static int sh_mobile_ceu_probe(struct platform_device *pdev)
+{
+ struct sh_mobile_ceu_dev *pcdev;
+ struct resource *res;
+ void __iomem *base;
+ unsigned int irq;
+ int err = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || !irq) {
+ dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
+ err = -ENODEV;
+ goto exit;
+ }
+
+ pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
+ if (!pcdev) {
+ dev_err(&pdev->dev, "Could not allocate pcdev\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ platform_set_drvdata(pdev, pcdev);
+ INIT_LIST_HEAD(&pcdev->capture);
+ spin_lock_init(&pcdev->lock);
+
+ pcdev->pdata = pdev->dev.platform_data;
+ if (!pcdev->pdata) {
+ err = -EINVAL;
+ dev_err(&pdev->dev, "CEU platform data not set.\n");
+ goto exit_kfree;
+ }
+
+ base = ioremap_nocache(res->start, res->end - res->start + 1);
+ if (!base) {
+ err = -ENXIO;
+ dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
+ goto exit_kfree;
+ }
+
+ pcdev->irq = irq;
+ pcdev->base = base;
+ pcdev->video_limit = 0; /* only enabled if second resource exists */
+ pcdev->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res) {
+ err = dma_declare_coherent_memory(&pdev->dev, res->start,
+ res->start,
+ (res->end - res->start) + 1,
+ DMA_MEMORY_MAP |
+ DMA_MEMORY_EXCLUSIVE);
+ if (!err) {
+ dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
+ err = -ENXIO;
+ goto exit_iounmap;
+ }
+
+ pcdev->video_limit = (res->end - res->start) + 1;
+ }
+
+ /* request irq */
+ err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
+ pdev->dev.bus_id, pcdev);
+ if (err) {
+ dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
+ goto exit_release_mem;
+ }
+
+ pcdev->ici.priv = pcdev;
+ pcdev->ici.dev.parent = &pdev->dev;
+ pcdev->ici.nr = pdev->id;
+ pcdev->ici.drv_name = pdev->dev.bus_id,
+ pcdev->ici.ops = &sh_mobile_ceu_host_ops,
+
+ err = soc_camera_host_register(&pcdev->ici);
+ if (err)
+ goto exit_free_irq;
+
+ return 0;
+
+exit_free_irq:
+ free_irq(pcdev->irq, pcdev);
+exit_release_mem:
+ if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
+ dma_release_declared_memory(&pdev->dev);
+exit_iounmap:
+ iounmap(base);
+exit_kfree:
+ kfree(pcdev);
+exit:
+ return err;
+}
+
+static int sh_mobile_ceu_remove(struct platform_device *pdev)
+{
+ struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev);
+
+ soc_camera_host_unregister(&pcdev->ici);
+ free_irq(pcdev->irq, pcdev);
+ if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
+ dma_release_declared_memory(&pdev->dev);
+ iounmap(pcdev->base);
+ kfree(pcdev);
+ return 0;
+}
+
+static struct platform_driver sh_mobile_ceu_driver = {
+ .driver = {
+ .name = "sh_mobile_ceu",
+ },
+ .probe = sh_mobile_ceu_probe,
+ .remove = sh_mobile_ceu_remove,
+};
+
+static int __init sh_mobile_ceu_init(void)
+{
+ return platform_driver_register(&sh_mobile_ceu_driver);
+}
+
+static void __exit sh_mobile_ceu_exit(void)
+{
+ return platform_driver_unregister(&sh_mobile_ceu_driver);
+}
+
+module_init(sh_mobile_ceu_init);
+module_exit(sh_mobile_ceu_exit);
+
+MODULE_DESCRIPTION("SuperH Mobile CEU driver");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 35223e0d7e4..6ff489baacf 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -44,7 +44,6 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), },
@@ -57,7 +56,6 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), },
- { SN9C102_USB_DEVICE(0x0c45, 0x603f, BRIDGE_SN9C102), },
/* SN9C103 */
{ SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), },
{ SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), },
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index d015bfe0095..e39b98f1eca 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -26,6 +26,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
+#include <media/videobuf-core.h>
#include <media/soc_camera.h>
static LIST_HEAD(hosts);
@@ -44,7 +45,7 @@ format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc)
return NULL;
}
-static int soc_camera_try_fmt_cap(struct file *file, void *priv,
+static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -182,7 +183,6 @@ static int soc_camera_open(struct inode *inode, struct file *file)
struct soc_camera_device *icd;
struct soc_camera_host *ici;
struct soc_camera_file *icf;
- spinlock_t *lock;
int ret;
icf = vmalloc(sizeof(*icf));
@@ -209,13 +209,6 @@ static int soc_camera_open(struct inode *inode, struct file *file)
}
icf->icd = icd;
-
- icf->lock = ici->ops->spinlock_alloc(icf);
- if (!icf->lock) {
- ret = -ENOMEM;
- goto esla;
- }
-
icd->use_count++;
/* Now we really have to activate the camera */
@@ -233,21 +226,12 @@ static int soc_camera_open(struct inode *inode, struct file *file)
file->private_data = icf;
dev_dbg(&icd->dev, "camera device open\n");
- /* We must pass NULL as dev pointer, then all pci_* dma operations
- * transform to normal dma_* ones. */
- videobuf_queue_sg_init(&icf->vb_vidq, ici->vbq_ops, NULL, icf->lock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
- ici->msize, icd);
+ ici->ops->init_videobuf(&icf->vb_vidq, icd);
return 0;
/* All errors are entered with the video_lock held */
eiciadd:
- lock = icf->lock;
- icf->lock = NULL;
- if (ici->ops->spinlock_free)
- ici->ops->spinlock_free(lock);
-esla:
module_put(ici->ops->owner);
emgi:
module_put(icd->ops->owner);
@@ -263,15 +247,11 @@ static int soc_camera_close(struct inode *inode, struct file *file)
struct soc_camera_device *icd = icf->icd;
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct video_device *vdev = icd->vdev;
- spinlock_t *lock = icf->lock;
mutex_lock(&video_lock);
icd->use_count--;
if (!icd->use_count)
ici->ops->remove(icd);
- icf->lock = NULL;
- if (ici->ops->spinlock_free)
- ici->ops->spinlock_free(lock);
module_put(icd->ops->owner);
module_put(ici->ops->owner);
mutex_unlock(&video_lock);
@@ -342,7 +322,7 @@ static struct file_operations soc_camera_fops = {
};
-static int soc_camera_s_fmt_cap(struct file *file, void *priv,
+static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -362,7 +342,7 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv,
/* buswidth may be further adjusted by the ici */
icd->buswidth = data_fmt->depth;
- ret = soc_camera_try_fmt_cap(file, icf, f);
+ ret = soc_camera_try_fmt_vid_cap(file, icf, f);
if (ret < 0)
return ret;
@@ -389,7 +369,7 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv,
return ici->ops->set_bus_param(icd, f->fmt.pix.pixelformat);
}
-static int soc_camera_enum_fmt_cap(struct file *file, void *priv,
+static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -408,7 +388,7 @@ static int soc_camera_enum_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int soc_camera_g_fmt_cap(struct file *file, void *priv,
+static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct soc_camera_file *icf = file->private_data;
@@ -767,27 +747,12 @@ static void dummy_release(struct device *dev)
{
}
-static spinlock_t *spinlock_alloc(struct soc_camera_file *icf)
-{
- spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
-
- if (lock)
- spin_lock_init(lock);
-
- return lock;
-}
-
-static void spinlock_free(spinlock_t *lock)
-{
- kfree(lock);
-}
-
int soc_camera_host_register(struct soc_camera_host *ici)
{
int ret;
struct soc_camera_host *ix;
- if (!ici->vbq_ops || !ici->ops->add || !ici->ops->remove)
+ if (!ici->ops->init_videobuf || !ici->ops->add || !ici->ops->remove)
return -EINVAL;
/* Number might be equal to the platform device ID */
@@ -811,11 +776,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
if (ret)
goto edevr;
- if (!ici->ops->spinlock_alloc) {
- ici->ops->spinlock_alloc = spinlock_alloc;
- ici->ops->spinlock_free = spinlock_free;
- }
-
scan_add_host(ici);
return 0;
@@ -925,15 +885,15 @@ int soc_camera_video_start(struct soc_camera_device *icd)
vdev->minor = -1;
vdev->tvnorms = V4L2_STD_UNKNOWN,
vdev->vidioc_querycap = soc_camera_querycap;
- vdev->vidioc_g_fmt_cap = soc_camera_g_fmt_cap;
- vdev->vidioc_enum_fmt_cap = soc_camera_enum_fmt_cap;
- vdev->vidioc_s_fmt_cap = soc_camera_s_fmt_cap;
+ vdev->vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap;
+ vdev->vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap;
+ vdev->vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap;
vdev->vidioc_enum_input = soc_camera_enum_input;
vdev->vidioc_g_input = soc_camera_g_input;
vdev->vidioc_s_input = soc_camera_s_input;
vdev->vidioc_s_std = soc_camera_s_std;
vdev->vidioc_reqbufs = soc_camera_reqbufs;
- vdev->vidioc_try_fmt_cap = soc_camera_try_fmt_cap;
+ vdev->vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap;
vdev->vidioc_querybuf = soc_camera_querybuf;
vdev->vidioc_qbuf = soc_camera_qbuf;
vdev->vidioc_dqbuf = soc_camera_dqbuf;
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
new file mode 100644
index 00000000000..eefb0327ebb
--- /dev/null
+++ b/drivers/media/video/soc_camera_platform.c
@@ -0,0 +1,198 @@
+/*
+ * Generic Platform Camera Driver
+ *
+ * Copyright (C) 2008 Magnus Damm
+ * Based on mt9m001 driver,
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/soc_camera.h>
+
+struct soc_camera_platform_info {
+ int iface;
+ char *format_name;
+ unsigned long format_depth;
+ struct v4l2_pix_format format;
+ unsigned long bus_param;
+ int (*set_capture)(struct soc_camera_platform_info *info, int enable);
+};
+
+struct soc_camera_platform_priv {
+ struct soc_camera_platform_info *info;
+ struct soc_camera_device icd;
+ struct soc_camera_data_format format;
+};
+
+static struct soc_camera_platform_info *
+soc_camera_platform_get_info(struct soc_camera_device *icd)
+{
+ struct soc_camera_platform_priv *priv;
+ priv = container_of(icd, struct soc_camera_platform_priv, icd);
+ return priv->info;
+}
+
+static int soc_camera_platform_init(struct soc_camera_device *icd)
+{
+ return 0;
+}
+
+static int soc_camera_platform_release(struct soc_camera_device *icd)
+{
+ return 0;
+}
+
+static int soc_camera_platform_start_capture(struct soc_camera_device *icd)
+{
+ struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+ return p->set_capture(p, 1);
+}
+
+static int soc_camera_platform_stop_capture(struct soc_camera_device *icd)
+{
+ struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+ return p->set_capture(p, 0);
+}
+
+static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
+ unsigned long flags)
+{
+ return 0;
+}
+
+static unsigned long
+soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
+{
+ struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+ return p->bus_param;
+}
+
+static int soc_camera_platform_set_fmt_cap(struct soc_camera_device *icd,
+ __u32 pixfmt, struct v4l2_rect *rect)
+{
+ return 0;
+}
+
+static int soc_camera_platform_try_fmt_cap(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+
+ f->fmt.pix.width = p->format.width;
+ f->fmt.pix.height = p->format.height;
+ return 0;
+}
+
+static int soc_camera_platform_video_probe(struct soc_camera_device *icd)
+{
+ struct soc_camera_platform_priv *priv;
+ priv = container_of(icd, struct soc_camera_platform_priv, icd);
+
+ priv->format.name = priv->info->format_name;
+ priv->format.depth = priv->info->format_depth;
+ priv->format.fourcc = priv->info->format.pixelformat;
+ priv->format.colorspace = priv->info->format.colorspace;
+
+ icd->formats = &priv->format;
+ icd->num_formats = 1;
+
+ return soc_camera_video_start(icd);
+}
+
+static void soc_camera_platform_video_remove(struct soc_camera_device *icd)
+{
+ soc_camera_video_stop(icd);
+}
+
+static struct soc_camera_ops soc_camera_platform_ops = {
+ .owner = THIS_MODULE,
+ .probe = soc_camera_platform_video_probe,
+ .remove = soc_camera_platform_video_remove,
+ .init = soc_camera_platform_init,
+ .release = soc_camera_platform_release,
+ .start_capture = soc_camera_platform_start_capture,
+ .stop_capture = soc_camera_platform_stop_capture,
+ .set_fmt_cap = soc_camera_platform_set_fmt_cap,
+ .try_fmt_cap = soc_camera_platform_try_fmt_cap,
+ .set_bus_param = soc_camera_platform_set_bus_param,
+ .query_bus_param = soc_camera_platform_query_bus_param,
+};
+
+static int soc_camera_platform_probe(struct platform_device *pdev)
+{
+ struct soc_camera_platform_priv *priv;
+ struct soc_camera_platform_info *p;
+ struct soc_camera_device *icd;
+ int ret;
+
+ p = pdev->dev.platform_data;
+ if (!p)
+ return -EINVAL;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->info = p;
+ platform_set_drvdata(pdev, priv);
+
+ icd = &priv->icd;
+ icd->ops = &soc_camera_platform_ops;
+ icd->control = &pdev->dev;
+ icd->width_min = 0;
+ icd->width_max = priv->info->format.width;
+ icd->height_min = 0;
+ icd->height_max = priv->info->format.height;
+ icd->y_skip_top = 0;
+ icd->iface = priv->info->iface;
+
+ ret = soc_camera_device_register(icd);
+ if (ret)
+ kfree(priv);
+
+ return ret;
+}
+
+static int soc_camera_platform_remove(struct platform_device *pdev)
+{
+ struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev);
+
+ soc_camera_device_unregister(&priv->icd);
+ kfree(priv);
+ return 0;
+}
+
+static struct platform_driver soc_camera_platform_driver = {
+ .driver = {
+ .name = "soc_camera_platform",
+ },
+ .probe = soc_camera_platform_probe,
+ .remove = soc_camera_platform_remove,
+};
+
+static int __init soc_camera_platform_module_init(void)
+{
+ return platform_driver_register(&soc_camera_platform_driver);
+}
+
+static void __exit soc_camera_platform_module_exit(void)
+{
+ return platform_driver_unregister(&soc_camera_platform_driver);
+}
+
+module_init(soc_camera_platform_module_init);
+module_exit(soc_camera_platform_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera Platform driver");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index b12c60cf5a0..f308c38d744 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -981,7 +981,7 @@ static int stk_vidioc_s_ctrl(struct file *filp,
}
-static int stk_vidioc_enum_fmt_cap(struct file *filp,
+static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_fmtdesc *fmtd)
{
fmtd->flags = 0;
@@ -1025,7 +1025,7 @@ static struct stk_size {
{ .w = 176, .h = 144, .m = MODE_QCIF, },
};
-static int stk_vidioc_g_fmt_cap(struct file *filp,
+static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_format *f)
{
struct v4l2_pix_format *pix_format = &f->fmt.pix;
@@ -1054,7 +1054,7 @@ static int stk_vidioc_g_fmt_cap(struct file *filp,
return 0;
}
-static int stk_vidioc_try_fmt_cap(struct file *filp,
+static int stk_vidioc_try_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_format *fmtd)
{
int i;
@@ -1131,7 +1131,7 @@ static int stk_setup_format(struct stk_camera *dev)
return stk_sensor_configure(dev);
}
-static int stk_vidioc_s_fmt_cap(struct file *filp,
+static int stk_vidioc_s_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_format *fmtd)
{
int ret;
@@ -1145,7 +1145,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
return -EBUSY;
if (dev->owner && dev->owner != filp)
return -EBUSY;
- ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
+ ret = stk_vidioc_try_fmt_vid_cap(filp, priv, fmtd);
if (ret)
return ret;
dev->owner = filp;
@@ -1342,10 +1342,10 @@ static struct video_device stk_v4l_data = {
.release = stk_v4l_dev_release,
.vidioc_querycap = stk_vidioc_querycap,
- .vidioc_enum_fmt_cap = stk_vidioc_enum_fmt_cap,
- .vidioc_try_fmt_cap = stk_vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = stk_vidioc_s_fmt_cap,
- .vidioc_g_fmt_cap = stk_vidioc_g_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = stk_vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = stk_vidioc_g_fmt_vid_cap,
.vidioc_enum_input = stk_vidioc_enum_input,
.vidioc_s_input = stk_vidioc_s_input,
.vidioc_g_input = stk_vidioc_g_input,
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 8f0100f67a9..29991d1cf13 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -523,6 +523,9 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s,
if (val < 0)
return val;
+ if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP)
+ val ^= sensor->platform_data->is_upside_down();
+
vc->value = val;
return 0;
}
@@ -556,6 +559,9 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s,
if (lvc == NULL)
return -EINVAL;
+ if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP)
+ val ^= sensor->platform_data->is_upside_down();
+
val = val << lvc->start_bit;
if (tcm825x_write_reg_mask(client, lvc->reg, val))
return -EIO;
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h
index 966765b66b3..770ebacfa34 100644
--- a/drivers/media/video/tcm825x.h
+++ b/drivers/media/video/tcm825x.h
@@ -182,6 +182,7 @@ struct tcm825x_platform_data {
int (*needs_reset)(struct v4l2_int_device *s, void *buf,
struct v4l2_pix_format *fmt);
int (*ifparm)(struct v4l2_ifparm *p);
+ int (*is_upside_down)(void);
};
/* Array of image sizes supported by TCM825X. These must be ordered from
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index b4d10f7a4e5..ae75c187da7 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -72,6 +72,7 @@ static unsigned short normal_i2c[] = {
I2C_ADDR_TDA7432 >> 1,
I2C_CLIENT_END,
};
+
I2C_CLIENT_INSMOD;
/* Structure of address and subaddresses for the tda7432 */
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 0cee0024278..2437c1a269c 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -34,6 +34,7 @@
static int debug; /* insmod parameter */
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
+
#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0)
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 3c0557130a7..7a8ce8fb46d 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -30,7 +30,6 @@
#include <linux/i2c.h>
#include <linux/init.h>
-
#include <media/i2c-addr.h>
static int debug; /* insmod parameter */
@@ -42,6 +41,7 @@ static unsigned short normal_i2c[] = {
I2C_ADDR_TDA9875 >> 1,
I2C_CLIENT_END
};
+
I2C_CLIENT_INSMOD;
/* This is a superset of the TDA9875 */
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 9513d8611e8..421c1445e96 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -36,6 +36,7 @@
static int debug; /* insmod parameter */
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
+
#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0)
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 7fd53367c07..b5c8957d130 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -36,6 +36,7 @@
static int debug; /* insmod parameter */
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
+
#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0)
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 28ab9f9d760..9220378a563 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -39,7 +39,6 @@ MODULE_LICENSE("GPL");
static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END };
-
I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 0d12ace6166..93d879dc510 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1298,7 +1298,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.id_table = tuner_id,
};
-
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index c77914d99d1..463680b1328 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -69,7 +69,6 @@ typedef struct AUDIOCMD {
/* chip description */
struct CHIPDESC {
char *name; /* chip name */
- int id; /* ID */
int addr_lo, addr_hi; /* i2c address range */
int registers; /* # of registers */
@@ -1256,7 +1255,6 @@ module_param(ta8874z, int, 0444);
static struct CHIPDESC chiplist[] = {
{
.name = "tda9840",
- .id = I2C_DRIVERID_TDA9840,
.insmodopt = &tda9840,
.addr_lo = I2C_ADDR_TDA9840 >> 1,
.addr_hi = I2C_ADDR_TDA9840 >> 1,
@@ -1272,7 +1270,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tda9873h",
- .id = I2C_DRIVERID_TDA9873,
.checkit = tda9873_checkit,
.insmodopt = &tda9873,
.addr_lo = I2C_ADDR_TDA985x_L >> 1,
@@ -1293,7 +1290,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tda9874h/a",
- .id = I2C_DRIVERID_TDA9874,
.checkit = tda9874a_checkit,
.initialize = tda9874a_initialize,
.insmodopt = &tda9874a,
@@ -1306,7 +1302,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tda9850",
- .id = I2C_DRIVERID_TDA9850,
.insmodopt = &tda9850,
.addr_lo = I2C_ADDR_TDA985x_L >> 1,
.addr_hi = I2C_ADDR_TDA985x_H >> 1,
@@ -1319,7 +1314,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tda9855",
- .id = I2C_DRIVERID_TDA9855,
.insmodopt = &tda9855,
.addr_lo = I2C_ADDR_TDA985x_L >> 1,
.addr_hi = I2C_ADDR_TDA985x_H >> 1,
@@ -1344,7 +1338,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tea6300",
- .id = I2C_DRIVERID_TEA6300,
.insmodopt = &tea6300,
.addr_lo = I2C_ADDR_TEA6300 >> 1,
.addr_hi = I2C_ADDR_TEA6300 >> 1,
@@ -1365,7 +1358,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tea6320",
- .id = I2C_DRIVERID_TEA6300,
.initialize = tea6320_initialize,
.insmodopt = &tea6320,
.addr_lo = I2C_ADDR_TEA6300 >> 1,
@@ -1387,7 +1379,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tea6420",
- .id = I2C_DRIVERID_TEA6420,
.insmodopt = &tea6420,
.addr_lo = I2C_ADDR_TEA6420 >> 1,
.addr_hi = I2C_ADDR_TEA6420 >> 1,
@@ -1400,7 +1391,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "tda8425",
- .id = I2C_DRIVERID_TDA8425,
.insmodopt = &tda8425,
.addr_lo = I2C_ADDR_TDA8425 >> 1,
.addr_hi = I2C_ADDR_TDA8425 >> 1,
@@ -1424,7 +1414,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "pic16c54 (PV951)",
- .id = I2C_DRIVERID_PIC16C54_PV9,
.insmodopt = &pic16c54,
.addr_lo = I2C_ADDR_PIC16C54 >> 1,
.addr_hi = I2C_ADDR_PIC16C54>> 1,
@@ -1440,8 +1429,6 @@ static struct CHIPDESC chiplist[] = {
},
{
.name = "ta8874z",
- .id = -1,
- /*.id = I2C_DRIVERID_TA8874Z, */
.checkit = ta8874z_checkit,
.insmodopt = &ta8874z,
.addr_lo = I2C_ADDR_TDA9840 >> 1,
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index a9c5e5adba3..abf685464b7 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -169,7 +169,6 @@ static void usbvision_rvfree(void *mem, unsigned long size)
}
-
#if ENABLE_HEXDUMP
static void usbvision_hexdump(const unsigned char *data, int len)
{
@@ -2317,7 +2316,6 @@ static void usbvision_powerOffTimer(unsigned long data)
del_timer(&usbvision->powerOffTimer);
INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off);
(void) schedule_work(&usbvision->powerOffWork);
-
}
void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision)
@@ -2518,7 +2516,6 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
}
}
-
/* Submit all URBs */
for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
@@ -2564,7 +2561,6 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
usbvision->sbuf[bufIdx].urb = NULL;
}
-
PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__);
usbvision->streaming = Stream_Off;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index e2274d77ea2..a6d00858b07 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -190,7 +190,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
}
-
/* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm usbvision_algo = {
@@ -514,11 +513,7 @@ static struct i2c_adapter i2c_adap_template = {
.id = I2C_HW_B_BT848, /* FIXME */
.client_register = attach_inform,
.client_unregister = detach_inform,
-#ifdef I2C_ADAP_CLASS_TV_ANALOG
- .class = I2C_ADAP_CLASS_TV_ANALOG,
-#else
.class = I2C_CLASS_TV_ANALOG,
-#endif
};
static struct i2c_client i2c_client_template = {
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index d97261ab430..cd6c41d6789 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -179,7 +179,6 @@ MODULE_ALIAS(DRIVER_ALIAS);
/* /sys/bus/usb/drivers/USBVision Video Grabber */
/*****************************************************************************/
-
#define YES_NO(x) ((x) ? "Yes" : "No")
static inline struct usb_usbvision *cd_to_usbvision(struct device *cd)
@@ -370,7 +369,6 @@ static void usbvision_remove_sysfs(struct video_device *vdev)
}
}
-
/*
* usbvision_open()
*
@@ -388,7 +386,6 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
PDEBUG(DBG_IO, "open");
-
usbvision_reset_powerOffTimer(usbvision);
if (usbvision->user)
@@ -442,9 +439,6 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
mutex_unlock(&usbvision->lock);
}
- if (errCode) {
- }
-
/* prepare queues */
usbvision_empty_framequeues(usbvision);
@@ -495,8 +489,6 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file)
}
PDEBUG(DBG_IO, "success");
-
-
return 0;
}
@@ -998,7 +990,7 @@ static int vidioc_streamoff(struct file *file,
return 0;
}
-static int vidioc_enum_fmt_cap (struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_fmtdesc *vfd)
{
if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
@@ -1012,7 +1004,7 @@ static int vidioc_enum_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_g_fmt_cap (struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_format *vf)
{
struct video_device *dev = video_devdata(file);
@@ -1030,7 +1022,7 @@ static int vidioc_g_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_try_fmt_cap (struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
struct v4l2_format *vf)
{
struct video_device *dev = video_devdata(file);
@@ -1060,7 +1052,7 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv,
return 0;
}
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *vf)
{
struct video_device *dev = video_devdata(file);
@@ -1068,7 +1060,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
(struct usb_usbvision *) video_get_drvdata(dev);
int ret;
- if( 0 != (ret=vidioc_try_fmt_cap (file, priv, vf)) ) {
+ if( 0 != (ret=vidioc_try_fmt_vid_cap (file, priv, vf)) ) {
return ret;
}
@@ -1346,9 +1338,7 @@ static int usbvision_radio_close(struct inode *inode, struct file *file)
usbvision_release(usbvision);
}
-
PDEBUG(DBG_IO, "success");
-
return errCode;
}
@@ -1360,7 +1350,6 @@ static int usbvision_vbi_open(struct inode *inode, struct file *file)
{
/* TODO */
return -ENODEV;
-
}
static int usbvision_vbi_close(struct inode *inode, struct file *file)
@@ -1407,10 +1396,10 @@ static struct video_device usbvision_video_template = {
.release = video_device_release,
.minor = -1,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
@@ -1899,7 +1888,6 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
}
PDEBUG(DBG_PROBE, "success");
-
}
static struct usb_driver usbvision_driver = {
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig
new file mode 100644
index 00000000000..c2d9760de83
--- /dev/null
+++ b/drivers/media/video/uvc/Kconfig
@@ -0,0 +1,17 @@
+config USB_VIDEO_CLASS
+ tristate "USB Video Class (UVC)"
+ ---help---
+ Support for the USB Video Class (UVC). Currently only video
+ input devices, such as webcams, are supported.
+
+ For more information see: <http://linux-uvc.berlios.de/>
+
+config USB_VIDEO_CLASS_INPUT_EVDEV
+ bool "UVC input events device support"
+ default y
+ depends on USB_VIDEO_CLASS && INPUT
+ ---help---
+ This option makes USB Video Class devices register an input device
+ to report button events.
+
+ If you are in doubt, say Y.
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index f0ee46d1554..3ae95512666 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -1254,3 +1254,4 @@ void uvc_ctrl_init(void)
for (; mapping < mend; ++mapping)
uvc_ctrl_add_mapping(mapping);
}
+
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 60ced589f89..f2b2983fe06 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -298,7 +298,8 @@ static int uvc_parse_format(struct uvc_device *dev,
switch (buffer[2]) {
case VS_FORMAT_UNCOMPRESSED:
case VS_FORMAT_FRAME_BASED:
- if (buflen < 27) {
+ n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28;
+ if (buflen < n) {
uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
"interface %d FORMAT error\n",
dev->udev->devnum,
@@ -1632,13 +1633,16 @@ static void uvc_disconnect(struct usb_interface *intf)
* reference to the uvc_device instance after uvc_v4l2_open() received
* the pointer to the device (video_devdata) but before it got the
* chance to increase the reference count (kref_get).
+ *
+ * Note that the reference can't be released with the lock held,
+ * otherwise a AB-BA deadlock can occur with videodev_lock that
+ * videodev acquires in videodev_open() and video_unregister_device().
*/
mutex_lock(&uvc_driver.open_mutex);
-
dev->state |= UVC_DEV_DISCONNECTED;
- kref_put(&dev->kref, uvc_delete);
-
mutex_unlock(&uvc_driver.open_mutex);
+
+ kref_put(&dev->kref, uvc_delete);
}
static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
@@ -1825,6 +1829,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Asus F9SG */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x8a31,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Syntek (Asus U3S) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1891,6 +1904,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX },
+ /* Medion Akoya Mini E1210 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x5986,
+ .idProduct = 0x0141,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Acer OrbiCam - Unknown vendor */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1953,3 +1975,4 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRIVER_VERSION);
+
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 0923f0e3b3d..7388d0cee3d 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -475,3 +475,4 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
wake_up(&buf->wait);
return nextbuf;
}
+
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index be9084e5eac..75e678ac54e 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -22,6 +22,7 @@
/* --------------------------------------------------------------------------
* Input device
*/
+#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
static int uvc_input_init(struct uvc_device *dev)
{
struct usb_device *udev = dev->udev;
@@ -67,6 +68,19 @@ static void uvc_input_cleanup(struct uvc_device *dev)
input_unregister_device(dev->input);
}
+static void uvc_input_report_key(struct uvc_device *dev, unsigned int code,
+ int value)
+{
+ if (dev->input)
+ input_report_key(dev->input, code, value);
+}
+
+#else
+#define uvc_input_init(dev)
+#define uvc_input_cleanup(dev)
+#define uvc_input_report_key(dev, code, value)
+#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */
+
/* --------------------------------------------------------------------------
* Status interrupt endpoint
*/
@@ -83,8 +97,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
return;
uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n",
data[1], data[3] ? "pressed" : "released", len);
- if (dev->input)
- input_report_key(dev->input, BTN_0, data[3]);
+ uvc_input_report_key(dev, BTN_0, data[3]);
} else {
uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
"len %d.\n", data[1], data[2], data[3], len);
@@ -203,5 +216,6 @@ int uvc_status_resume(struct uvc_device *dev)
if (dev->int_urb == NULL)
return 0;
- return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+ return usb_submit_urb(dev->int_urb, GFP_NOIO);
}
+
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 2e0a66575bb..b5a11eb8f9f 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -1032,7 +1032,7 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
{
struct video_device *vdev = video_devdata(file);
struct uvc_video_device *video = video_get_drvdata(vdev);
- struct uvc_buffer *buffer;
+ struct uvc_buffer *uninitialized_var(buffer);
struct page *page;
unsigned long addr, start, size;
unsigned int i;
@@ -1103,3 +1103,4 @@ struct file_operations uvc_fops = {
.mmap = uvc_v4l2_mmap,
.poll = uvc_v4l2_poll,
};
+
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 6faf1fb2161..ad63794fda7 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -554,9 +554,56 @@ static void uvc_video_complete(struct urb *urb)
}
/*
+ * Free transfer buffers.
+ */
+static void uvc_free_urb_buffers(struct uvc_video_device *video)
+{
+ unsigned int i;
+
+ for (i = 0; i < UVC_URBS; ++i) {
+ if (video->urb_buffer[i]) {
+ usb_buffer_free(video->dev->udev, video->urb_size,
+ video->urb_buffer[i], video->urb_dma[i]);
+ video->urb_buffer[i] = NULL;
+ }
+ }
+
+ video->urb_size = 0;
+}
+
+/*
+ * Allocate transfer buffers. This function can be called with buffers
+ * already allocated when resuming from suspend, in which case it will
+ * return without touching the buffers.
+ *
+ * Return 0 on success or -ENOMEM when out of memory.
+ */
+static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
+ unsigned int size)
+{
+ unsigned int i;
+
+ /* Buffers are already allocated, bail out. */
+ if (video->urb_size)
+ return 0;
+
+ for (i = 0; i < UVC_URBS; ++i) {
+ video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
+ size, GFP_KERNEL, &video->urb_dma[i]);
+ if (video->urb_buffer[i] == NULL) {
+ uvc_free_urb_buffers(video);
+ return -ENOMEM;
+ }
+ }
+
+ video->urb_size = size;
+ return 0;
+}
+
+/*
* Uninitialize isochronous/bulk URBs and free transfer buffers.
*/
-static void uvc_uninit_video(struct uvc_video_device *video)
+static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers)
{
struct urb *urb;
unsigned int i;
@@ -566,19 +613,12 @@ static void uvc_uninit_video(struct uvc_video_device *video)
continue;
usb_kill_urb(urb);
- /* urb->transfer_buffer_length is not touched by USB core, so
- * we can use it here as the buffer length.
- */
- if (video->urb_buffer[i]) {
- usb_buffer_free(video->dev->udev,
- urb->transfer_buffer_length,
- video->urb_buffer[i], urb->transfer_dma);
- video->urb_buffer[i] = NULL;
- }
-
usb_free_urb(urb);
video->urb[i] = NULL;
}
+
+ if (free_buffers)
+ uvc_free_urb_buffers(video);
}
/*
@@ -586,7 +626,7 @@ static void uvc_uninit_video(struct uvc_video_device *video)
* is given by the endpoint.
*/
static int uvc_init_video_isoc(struct uvc_video_device *video,
- struct usb_host_endpoint *ep)
+ struct usb_host_endpoint *ep, gfp_t gfp_flags)
{
struct urb *urb;
unsigned int npackets, i, j;
@@ -610,18 +650,13 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
size = npackets * psize;
+ if (uvc_alloc_urb_buffers(video, size) < 0)
+ return -ENOMEM;
+
for (i = 0; i < UVC_URBS; ++i) {
- urb = usb_alloc_urb(npackets, GFP_KERNEL);
+ urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) {
- uvc_uninit_video(video);
- return -ENOMEM;
- }
-
- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
- size, GFP_KERNEL, &urb->transfer_dma);
- if (video->urb_buffer[i] == NULL) {
- usb_free_urb(urb);
- uvc_uninit_video(video);
+ uvc_uninit_video(video, 1);
return -ENOMEM;
}
@@ -632,6 +667,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
urb->interval = ep->desc.bInterval;
urb->transfer_buffer = video->urb_buffer[i];
+ urb->transfer_dma = video->urb_dma[i];
urb->complete = uvc_video_complete;
urb->number_of_packets = npackets;
urb->transfer_buffer_length = size;
@@ -652,7 +688,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
* given by the endpoint.
*/
static int uvc_init_video_bulk(struct uvc_video_device *video,
- struct usb_host_endpoint *ep)
+ struct usb_host_endpoint *ep, gfp_t gfp_flags)
{
struct urb *urb;
unsigned int pipe, i;
@@ -671,20 +707,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
if (size > psize * UVC_MAX_ISO_PACKETS)
size = psize * UVC_MAX_ISO_PACKETS;
+ if (uvc_alloc_urb_buffers(video, size) < 0)
+ return -ENOMEM;
+
pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress);
for (i = 0; i < UVC_URBS; ++i) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
+ urb = usb_alloc_urb(0, gfp_flags);
if (urb == NULL) {
- uvc_uninit_video(video);
- return -ENOMEM;
- }
-
- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
- size, GFP_KERNEL, &urb->transfer_dma);
- if (video->urb_buffer[i] == NULL) {
- usb_free_urb(urb);
- uvc_uninit_video(video);
+ uvc_uninit_video(video, 1);
return -ENOMEM;
}
@@ -692,6 +723,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
video->urb_buffer[i], size, uvc_video_complete,
video);
urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+ urb->transfer_dma = video->urb_dma[i];
video->urb[i] = urb;
}
@@ -702,7 +734,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
/*
* Initialize isochronous/bulk URBs and allocate transfer buffers.
*/
-static int uvc_init_video(struct uvc_video_device *video)
+static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
{
struct usb_interface *intf = video->streaming->intf;
struct usb_host_interface *alts;
@@ -747,7 +779,7 @@ static int uvc_init_video(struct uvc_video_device *video)
if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0)
return ret;
- ret = uvc_init_video_isoc(video, ep);
+ ret = uvc_init_video_isoc(video, ep, gfp_flags);
} else {
/* Bulk endpoint, proceed to URB initialization. */
ep = uvc_find_endpoint(&intf->altsetting[0],
@@ -755,7 +787,7 @@ static int uvc_init_video(struct uvc_video_device *video)
if (ep == NULL)
return -EIO;
- ret = uvc_init_video_bulk(video, ep);
+ ret = uvc_init_video_bulk(video, ep, gfp_flags);
}
if (ret < 0)
@@ -763,10 +795,10 @@ static int uvc_init_video(struct uvc_video_device *video)
/* Submit the URBs. */
for (i = 0; i < UVC_URBS; ++i) {
- if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) {
+ if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) {
uvc_printk(KERN_ERR, "Failed to submit URB %u "
"(%d).\n", i, ret);
- uvc_uninit_video(video);
+ uvc_uninit_video(video, 1);
return ret;
}
}
@@ -791,7 +823,7 @@ int uvc_video_suspend(struct uvc_video_device *video)
return 0;
video->frozen = 1;
- uvc_uninit_video(video);
+ uvc_uninit_video(video, 0);
usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
return 0;
}
@@ -818,7 +850,7 @@ int uvc_video_resume(struct uvc_video_device *video)
if (!uvc_queue_streaming(&video->queue))
return 0;
- if ((ret = uvc_init_video(video)) < 0)
+ if ((ret = uvc_init_video(video, GFP_NOIO)) < 0)
uvc_queue_enable(&video->queue, 0);
return ret;
@@ -920,7 +952,7 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
int ret;
if (!enable) {
- uvc_uninit_video(video);
+ uvc_uninit_video(video, 1);
usb_set_interface(video->dev->udev,
video->streaming->intfnum, 0);
uvc_queue_enable(&video->queue, 0);
@@ -930,5 +962,6 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
return ret;
- return uvc_init_video(video);
+ return uvc_init_video(video, GFP_KERNEL);
}
+
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index a995a780db1..bafe3406e30 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -602,6 +602,8 @@ struct uvc_video_device {
struct urb *urb[UVC_URBS];
char *urb_buffer[UVC_URBS];
+ dma_addr_t urb_dma[UVC_URBS];
+ unsigned int urb_size;
__u8 last_fid;
};
@@ -794,3 +796,4 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
#endif /* __KERNEL__ */
#endif
+
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
new file mode 100644
index 00000000000..03f20acb668
--- /dev/null
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -0,0 +1,418 @@
+/*
+ * helper functions for physically contiguous capture buffers
+ *
+ * The functions support hardware lacking scatter gather support
+ * (i.e. the buffers must be linear in physical memory)
+ *
+ * Copyright (c) 2008 Magnus Damm
+ *
+ * Based on videobuf-vmalloc.c,
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ *
+ * 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
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <media/videobuf-dma-contig.h>
+
+struct videobuf_dma_contig_memory {
+ u32 magic;
+ void *vaddr;
+ dma_addr_t dma_handle;
+ unsigned long size;
+};
+
+#define MAGIC_DC_MEM 0x0733ac61
+#define MAGIC_CHECK(is, should) \
+ if (unlikely((is) != (should))) { \
+ pr_err("magic mismatch: %x expected %x\n", is, should); \
+ BUG(); \
+ }
+
+static void
+videobuf_vm_open(struct vm_area_struct *vma)
+{
+ struct videobuf_mapping *map = vma->vm_private_data;
+
+ dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
+ map, map->count, vma->vm_start, vma->vm_end);
+
+ map->count++;
+}
+
+static void videobuf_vm_close(struct vm_area_struct *vma)
+{
+ struct videobuf_mapping *map = vma->vm_private_data;
+ struct videobuf_queue *q = map->q;
+ int i;
+
+ dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
+ map, map->count, vma->vm_start, vma->vm_end);
+
+ map->count--;
+ if (0 == map->count) {
+ struct videobuf_dma_contig_memory *mem;
+
+ dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q);
+ mutex_lock(&q->vb_lock);
+
+ /* We need first to cancel streams, before unmapping */
+ if (q->streaming)
+ videobuf_queue_cancel(q);
+
+ for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+ if (NULL == q->bufs[i])
+ continue;
+
+ if (q->bufs[i]->map != map)
+ continue;
+
+ mem = q->bufs[i]->priv;
+ if (mem) {
+ /* This callback is called only if kernel has
+ allocated memory and this memory is mmapped.
+ In this case, memory should be freed,
+ in order to do memory unmap.
+ */
+
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ /* vfree is not atomic - can't be
+ called with IRQ's disabled
+ */
+ dev_dbg(map->q->dev, "buf[%d] freeing %p\n",
+ i, mem->vaddr);
+
+ dma_free_coherent(q->dev, mem->size,
+ mem->vaddr, mem->dma_handle);
+ mem->vaddr = NULL;
+ }
+
+ q->bufs[i]->map = NULL;
+ q->bufs[i]->baddr = 0;
+ }
+
+ kfree(map);
+
+ mutex_unlock(&q->vb_lock);
+ }
+}
+
+static struct vm_operations_struct videobuf_vm_ops = {
+ .open = videobuf_vm_open,
+ .close = videobuf_vm_close,
+};
+
+static void *__videobuf_alloc(size_t size)
+{
+ struct videobuf_dma_contig_memory *mem;
+ struct videobuf_buffer *vb;
+
+ vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
+ if (vb) {
+ mem = vb->priv = ((char *)vb) + size;
+ mem->magic = MAGIC_DC_MEM;
+ }
+
+ return vb;
+}
+
+static void *__videobuf_to_vmalloc(struct videobuf_buffer *buf)
+{
+ struct videobuf_dma_contig_memory *mem = buf->priv;
+
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ return mem->vaddr;
+}
+
+static int __videobuf_iolock(struct videobuf_queue *q,
+ struct videobuf_buffer *vb,
+ struct v4l2_framebuffer *fbuf)
+{
+ struct videobuf_dma_contig_memory *mem = vb->priv;
+
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ switch (vb->memory) {
+ case V4L2_MEMORY_MMAP:
+ dev_dbg(q->dev, "%s memory method MMAP\n", __func__);
+
+ /* All handling should be done by __videobuf_mmap_mapper() */
+ if (!mem->vaddr) {
+ dev_err(q->dev, "memory is not alloced/mmapped.\n");
+ return -EINVAL;
+ }
+ break;
+ case V4L2_MEMORY_USERPTR:
+ dev_dbg(q->dev, "%s memory method USERPTR\n", __func__);
+
+ /* The only USERPTR currently supported is the one needed for
+ read() method.
+ */
+ if (vb->baddr)
+ return -EINVAL;
+
+ mem->size = PAGE_ALIGN(vb->size);
+ mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
+ &mem->dma_handle, GFP_KERNEL);
+ if (!mem->vaddr) {
+ dev_err(q->dev, "dma_alloc_coherent %ld failed\n",
+ mem->size);
+ return -ENOMEM;
+ }
+
+ dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n",
+ mem->vaddr, mem->size);
+ break;
+ case V4L2_MEMORY_OVERLAY:
+ default:
+ dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __videobuf_sync(struct videobuf_queue *q,
+ struct videobuf_buffer *buf)
+{
+ struct videobuf_dma_contig_memory *mem = buf->priv;
+
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
+ DMA_FROM_DEVICE);
+ return 0;
+}
+
+static int __videobuf_mmap_free(struct videobuf_queue *q)
+{
+ unsigned int i;
+
+ dev_dbg(q->dev, "%s\n", __func__);
+ for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+ if (q->bufs[i] && q->bufs[i]->map)
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+ struct vm_area_struct *vma)
+{
+ struct videobuf_dma_contig_memory *mem;
+ struct videobuf_mapping *map;
+ unsigned int first;
+ int retval;
+ unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT;
+
+ dev_dbg(q->dev, "%s\n", __func__);
+ if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
+ return -EINVAL;
+
+ /* look for first buffer to map */
+ for (first = 0; first < VIDEO_MAX_FRAME; first++) {
+ if (!q->bufs[first])
+ continue;
+
+ if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
+ continue;
+ if (q->bufs[first]->boff == offset)
+ break;
+ }
+ if (VIDEO_MAX_FRAME == first) {
+ dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n",
+ offset);
+ return -EINVAL;
+ }
+
+ /* create mapping + update buffer list */
+ map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
+ if (!map)
+ return -ENOMEM;
+
+ q->bufs[first]->map = map;
+ map->start = vma->vm_start;
+ map->end = vma->vm_end;
+ map->q = q;
+
+ q->bufs[first]->baddr = vma->vm_start;
+
+ mem = q->bufs[first]->priv;
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ mem->size = PAGE_ALIGN(q->bufs[first]->bsize);
+ mem->vaddr = dma_alloc_coherent(q->dev, mem->size,
+ &mem->dma_handle, GFP_KERNEL);
+ if (!mem->vaddr) {
+ dev_err(q->dev, "dma_alloc_coherent size %ld failed\n",
+ mem->size);
+ goto error;
+ }
+ dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n",
+ mem->vaddr, mem->size);
+
+ /* Try to remap memory */
+
+ size = vma->vm_end - vma->vm_start;
+ size = (size < mem->size) ? size : mem->size;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ retval = remap_pfn_range(vma, vma->vm_start,
+ mem->dma_handle >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+ if (retval) {
+ dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
+ dma_free_coherent(q->dev, mem->size,
+ mem->vaddr, mem->dma_handle);
+ goto error;
+ }
+
+ vma->vm_ops = &videobuf_vm_ops;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_private_data = map;
+
+ dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
+ map, q, vma->vm_start, vma->vm_end,
+ (long int) q->bufs[first]->bsize,
+ vma->vm_pgoff, first);
+
+ videobuf_vm_open(vma);
+
+ return 0;
+
+error:
+ kfree(map);
+ return -ENOMEM;
+}
+
+static int __videobuf_copy_to_user(struct videobuf_queue *q,
+ char __user *data, size_t count,
+ int nonblocking)
+{
+ struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
+ void *vaddr;
+
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+ BUG_ON(!mem->vaddr);
+
+ /* copy to userspace */
+ if (count > q->read_buf->size - q->read_off)
+ count = q->read_buf->size - q->read_off;
+
+ vaddr = mem->vaddr;
+
+ if (copy_to_user(data, vaddr + q->read_off, count))
+ return -EFAULT;
+
+ return count;
+}
+
+static int __videobuf_copy_stream(struct videobuf_queue *q,
+ char __user *data, size_t count, size_t pos,
+ int vbihack, int nonblocking)
+{
+ unsigned int *fc;
+ struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
+
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ if (vbihack) {
+ /* dirty, undocumented hack -- pass the frame counter
+ * within the last four bytes of each vbi data block.
+ * We need that one to maintain backward compatibility
+ * to all vbi decoding software out there ... */
+ fc = (unsigned int *)mem->vaddr;
+ fc += (q->read_buf->size >> 2) - 1;
+ *fc = q->read_buf->field_count >> 1;
+ dev_dbg(q->dev, "vbihack: %d\n", *fc);
+ }
+
+ /* copy stuff using the common method */
+ count = __videobuf_copy_to_user(q, data, count, nonblocking);
+
+ if ((count == -EFAULT) && (pos == 0))
+ return -EFAULT;
+
+ return count;
+}
+
+static struct videobuf_qtype_ops qops = {
+ .magic = MAGIC_QTYPE_OPS,
+
+ .alloc = __videobuf_alloc,
+ .iolock = __videobuf_iolock,
+ .sync = __videobuf_sync,
+ .mmap_free = __videobuf_mmap_free,
+ .mmap_mapper = __videobuf_mmap_mapper,
+ .video_copy_to_user = __videobuf_copy_to_user,
+ .copy_stream = __videobuf_copy_stream,
+ .vmalloc = __videobuf_to_vmalloc,
+};
+
+void videobuf_queue_dma_contig_init(struct videobuf_queue *q,
+ struct videobuf_queue_ops *ops,
+ struct device *dev,
+ spinlock_t *irqlock,
+ enum v4l2_buf_type type,
+ enum v4l2_field field,
+ unsigned int msize,
+ void *priv)
+{
+ videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
+ priv, &qops);
+}
+EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init);
+
+dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf)
+{
+ struct videobuf_dma_contig_memory *mem = buf->priv;
+
+ BUG_ON(!mem);
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ return mem->dma_handle;
+}
+EXPORT_SYMBOL_GPL(videobuf_to_dma_contig);
+
+void videobuf_dma_contig_free(struct videobuf_queue *q,
+ struct videobuf_buffer *buf)
+{
+ struct videobuf_dma_contig_memory *mem = buf->priv;
+
+ /* mmapped memory can't be freed here, otherwise mmapped region
+ would be released, while still needed. In this case, the memory
+ release should happen inside videobuf_vm_close().
+ So, it should free memory only if the memory were allocated for
+ read() operation.
+ */
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr)
+ return;
+
+ if (!mem)
+ return;
+
+ MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+
+ dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
+ mem->vaddr = NULL;
+}
+EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
+
+MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 03a7b946bd5..bc6d5aba0fe 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -1,7 +1,7 @@
/*
* helper functions for SG DMA video4linux capture buffers
*
- * The functions expect the hardware being able to scatter gatter
+ * The functions expect the hardware being able to scatter gather
* (i.e. the buffers are not linear in physical memory, but fragmented
* into PAGE_SIZE chunks). They also assume the driver does not need
* to touch the video data.
@@ -80,17 +80,15 @@ struct scatterlist*
videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
{
struct scatterlist *sglist;
- int i = 0;
+ int i;
if (NULL == pages[0])
return NULL;
- sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
+ sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL);
if (NULL == sglist)
return NULL;
sg_init_table(sglist, nr_pages);
- if (NULL == pages[0])
- goto nopage;
if (PageHighMem(pages[0]))
/* DMA to highmem pages might not work */
goto highmem;
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 6e4d73ec685..b56cffcbfd4 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -13,7 +13,6 @@
* (at your option) any later version.
*/
-
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
@@ -257,4 +256,3 @@ EXPORT_SYMBOL(videobuf_dvb_unregister);
* compile-command: "make DVB=1"
* End:
*/
-
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index c91e1d8e380..a868b7ed75f 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -1,7 +1,7 @@
/*
* helper functions for vmalloc video4linux capture buffers
*
- * The functions expect the hardware being able to scatter gatter
+ * The functions expect the hardware being able to scatter gather
* (i.e. the buffers are not linear in physical memory, but fragmented
* into PAGE_SIZE chunks). They also assume the driver does not need
* to touch the video data.
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 7649860a388..6616e657055 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -17,15 +17,19 @@
*/
#define dbgarg(cmd, fmt, arg...) \
- if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
+ do { \
+ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
printk(KERN_DEBUG "%s: ", vfd->name); \
v4l_printk_ioctl(cmd); \
printk(" " fmt, ## arg); \
- }
+ } \
+ } while (0)
#define dbgarg2(fmt, arg...) \
- if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
- printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
+ do { \
+ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
+ printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
+ } while (0)
#include <linux/module.h>
#include <linux/types.h>
@@ -138,7 +142,7 @@ EXPORT_SYMBOL(v4l2_video_std_construct);
/* ----------------------------------------------------------------- */
/* some arrays for pretty-printing debug messages of enum types */
-char *v4l2_field_names[] = {
+const char *v4l2_field_names[] = {
[V4L2_FIELD_ANY] = "any",
[V4L2_FIELD_NONE] = "none",
[V4L2_FIELD_TOP] = "top",
@@ -152,19 +156,19 @@ char *v4l2_field_names[] = {
};
EXPORT_SYMBOL(v4l2_field_names);
-char *v4l2_type_names[] = {
- [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
- [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
+const char *v4l2_type_names[] = {
+ [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap",
+ [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay",
+ [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out",
[V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
[V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
[V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
[V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
- [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
+ [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
};
EXPORT_SYMBOL(v4l2_type_names);
-static char *v4l2_memory_names[] = {
+static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP] = "mmap",
[V4L2_MEMORY_USERPTR] = "userptr",
[V4L2_MEMORY_OVERLAY] = "overlay",
@@ -278,6 +282,7 @@ static const char *v4l2_ioctls[] = {
[_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
[_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT",
+ [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
#endif
};
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
@@ -371,6 +376,14 @@ EXPORT_SYMBOL(v4l_printk_ioctl);
* sysfs stuff
*/
+static ssize_t show_index(struct device *cd,
+ struct device_attribute *attr, char *buf)
+{
+ struct video_device *vfd = container_of(cd, struct video_device,
+ class_dev);
+ return sprintf(buf, "%i\n", vfd->index);
+}
+
static ssize_t show_name(struct device *cd,
struct device_attribute *attr, char *buf)
{
@@ -379,6 +392,12 @@ static ssize_t show_name(struct device *cd,
return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
}
+static struct device_attribute video_device_attrs[] = {
+ __ATTR(name, S_IRUGO, show_name, NULL),
+ __ATTR(index, S_IRUGO, show_index, NULL),
+ __ATTR_NULL
+};
+
struct video_device *video_device_alloc(void)
{
struct video_device *vfd;
@@ -407,11 +426,6 @@ static void video_release(struct device *cd)
vfd->release(vfd);
}
-static struct device_attribute video_device_attrs[] = {
- __ATTR(name, S_IRUGO, show_name, NULL),
- __ATTR_NULL
-};
-
static struct class video_class = {
.name = VIDEO_NAME,
.dev_attrs = video_device_attrs,
@@ -650,7 +664,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
p->field, p->sequence,
prt_names(p->memory, v4l2_memory_names),
p->m.userptr, p->length);
- dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
+ dbgarg2("timecode=%02d:%02d:%02d type=%d, "
"flags=0x%08d, frames=%d, userbits=0x%08x\n",
tc->hours,tc->minutes,tc->seconds,
tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
@@ -659,7 +673,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd,
static inline void dbgrect(struct video_device *vfd, char *s,
struct v4l2_rect *r)
{
- dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
+ dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top,
r->width, r->height);
};
@@ -677,40 +691,85 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd,
fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
};
+static inline void v4l_print_ext_ctrls(unsigned int cmd,
+ struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
+{
+ __u32 i;
+
+ if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG))
+ return;
+ dbgarg(cmd, "");
+ printk(KERN_CONT "class=0x%x", c->ctrl_class);
+ for (i = 0; i < c->count; i++) {
+ if (show_vals)
+ printk(KERN_CONT " id/val=0x%x/0x%x",
+ c->controls[i].id, c->controls[i].value);
+ else
+ printk(KERN_CONT " id=0x%x", c->controls[i].id);
+ }
+ printk(KERN_CONT "\n");
+};
+
+static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
+{
+ __u32 i;
+
+ /* zero the reserved fields */
+ c->reserved[0] = c->reserved[1] = 0;
+ for (i = 0; i < c->count; i++) {
+ c->controls[i].reserved2[0] = 0;
+ c->controls[i].reserved2[1] = 0;
+ }
+ /* V4L2_CID_PRIVATE_BASE cannot be used as control class
+ when using extended controls.
+ Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
+ is it allowed for backwards compatibility.
+ */
+ if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE)
+ return 0;
+ /* Check that all controls are from the same control class. */
+ for (i = 0; i < c->count; i++) {
+ if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) {
+ c->error_idx = i;
+ return 0;
+ }
+ }
+ return 1;
+}
static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
{
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_try_fmt_cap)
+ if (vfd->vidioc_try_fmt_vid_cap)
return (0);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_try_fmt_overlay)
+ if (vfd->vidioc_try_fmt_vid_overlay)
return (0);
break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_vbi)
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (vfd->vidioc_try_fmt_vid_out)
return (0);
break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_vbi_output)
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ if (vfd->vidioc_try_fmt_vid_out_overlay)
return (0);
break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_vbi_capture)
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (vfd->vidioc_try_fmt_vbi_cap)
return (0);
break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_try_fmt_video_output)
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (vfd->vidioc_try_fmt_vbi_out)
return (0);
break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_vbi_output)
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (vfd->vidioc_try_fmt_sliced_vbi_cap)
return (0);
break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_try_fmt_output_overlay)
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (vfd->vidioc_try_fmt_sliced_vbi_out)
return (0);
break;
case V4L2_BUF_TYPE_PRIVATE:
@@ -827,46 +886,37 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_enum_fmt_cap)
- ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
+ if (vfd->vidioc_enum_fmt_vid_cap)
+ ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_enum_fmt_overlay)
- ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
+ if (vfd->vidioc_enum_fmt_vid_overlay)
+ ret = vfd->vidioc_enum_fmt_vid_overlay(file,
+ fh, f);
break;
+#if 1
+ /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT
+ * according to the spec. The bttv and saa7134 drivers support
+ * it though, so just warn that this is deprecated and will be
+ * removed in the near future. */
case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_enum_fmt_vbi)
- ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_enum_fmt_vbi_output)
- ret=vfd->vidioc_enum_fmt_vbi_output(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_enum_fmt_vbi_capture)
- ret=vfd->vidioc_enum_fmt_vbi_capture(file,
- fh, f);
+ if (vfd->vidioc_enum_fmt_vbi_cap) {
+ printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n");
+ ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f);
+ }
break;
+#endif
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_enum_fmt_video_output)
- ret=vfd->vidioc_enum_fmt_video_output(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_enum_fmt_vbi_output)
- ret=vfd->vidioc_enum_fmt_vbi_output(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_enum_fmt_output_overlay)
- ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
+ if (vfd->vidioc_enum_fmt_vid_out)
+ ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f);
break;
case V4L2_BUF_TYPE_PRIVATE:
if (vfd->vidioc_enum_fmt_type_private)
- ret=vfd->vidioc_enum_fmt_type_private(file,
+ ret = vfd->vidioc_enum_fmt_type_private(file,
fh, f);
break;
+ default:
+ break;
}
if (!ret)
dbgarg (cmd, "index=%d, type=%d, flags=%d, "
@@ -882,54 +932,56 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_G_FMT:
{
struct v4l2_format *f = (struct v4l2_format *)arg;
- enum v4l2_buf_type type=f->type;
- memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
- f->type=type;
+ memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
/* FIXME: Should be one dump per type */
- dbgarg (cmd, "type=%s\n", prt_names(type,
- v4l2_type_names));
+ dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
- switch (type) {
+ switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_g_fmt_cap)
- ret=vfd->vidioc_g_fmt_cap(file, fh, f);
+ if (vfd->vidioc_g_fmt_vid_cap)
+ ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f);
if (!ret)
- v4l_print_pix_fmt(vfd,&f->fmt.pix);
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_g_fmt_overlay)
- ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_g_fmt_vbi)
- ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_g_fmt_vbi_output)
- ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_g_fmt_vbi_capture)
- ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
+ if (vfd->vidioc_g_fmt_vid_overlay)
+ ret = vfd->vidioc_g_fmt_vid_overlay(file,
+ fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_g_fmt_video_output)
- ret=vfd->vidioc_g_fmt_video_output(file,
- fh, f);
+ if (vfd->vidioc_g_fmt_vid_out)
+ ret = vfd->vidioc_g_fmt_vid_out(file, fh, f);
+ if (!ret)
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_g_fmt_output_overlay)
- ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
+ if (vfd->vidioc_g_fmt_vid_out_overlay)
+ ret = vfd->vidioc_g_fmt_vid_out_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (vfd->vidioc_g_fmt_vbi_cap)
+ ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_g_fmt_vbi_output)
- ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
+ if (vfd->vidioc_g_fmt_vbi_out)
+ ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (vfd->vidioc_g_fmt_sliced_vbi_cap)
+ ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (vfd->vidioc_g_fmt_sliced_vbi_out)
+ ret = vfd->vidioc_g_fmt_sliced_vbi_out(file,
+ fh, f);
break;
case V4L2_BUF_TYPE_PRIVATE:
if (vfd->vidioc_g_fmt_type_private)
- ret=vfd->vidioc_g_fmt_type_private(file,
+ ret = vfd->vidioc_g_fmt_type_private(file,
fh, f);
break;
}
@@ -941,48 +993,50 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_format *f = (struct v4l2_format *)arg;
/* FIXME: Should be one dump per type */
- dbgarg (cmd, "type=%s\n", prt_names(f->type,
- v4l2_type_names));
+ dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- v4l_print_pix_fmt(vfd,&f->fmt.pix);
- if (vfd->vidioc_s_fmt_cap)
- ret=vfd->vidioc_s_fmt_cap(file, fh, f);
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ if (vfd->vidioc_s_fmt_vid_cap)
+ ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_s_fmt_overlay)
- ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_s_fmt_vbi)
- ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_s_fmt_vbi_output)
- ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
- break;
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_s_fmt_vbi_capture)
- ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
+ if (vfd->vidioc_s_fmt_vid_overlay)
+ ret = vfd->vidioc_s_fmt_vid_overlay(file,
+ fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_s_fmt_video_output)
- ret=vfd->vidioc_s_fmt_video_output(file,
- fh, f);
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ if (vfd->vidioc_s_fmt_vid_out)
+ ret = vfd->vidioc_s_fmt_vid_out(file, fh, f);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_s_fmt_output_overlay)
- ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
+ if (vfd->vidioc_s_fmt_vid_out_overlay)
+ ret = vfd->vidioc_s_fmt_vid_out_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ if (vfd->vidioc_s_fmt_vbi_cap)
+ ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f);
break;
case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_s_fmt_vbi_output)
- ret=vfd->vidioc_s_fmt_vbi_output(file,
- fh, f);
+ if (vfd->vidioc_s_fmt_vbi_out)
+ ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ if (vfd->vidioc_s_fmt_sliced_vbi_cap)
+ ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (vfd->vidioc_s_fmt_sliced_vbi_out)
+ ret = vfd->vidioc_s_fmt_sliced_vbi_out(file,
+ fh, f);
break;
case V4L2_BUF_TYPE_PRIVATE:
if (vfd->vidioc_s_fmt_type_private)
- ret=vfd->vidioc_s_fmt_type_private(file,
+ ret = vfd->vidioc_s_fmt_type_private(file,
fh, f);
break;
}
@@ -997,46 +1051,48 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
v4l2_type_names));
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (vfd->vidioc_try_fmt_cap)
- ret=vfd->vidioc_try_fmt_cap(file, fh, f);
+ if (vfd->vidioc_try_fmt_vid_cap)
+ ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f);
if (!ret)
- v4l_print_pix_fmt(vfd,&f->fmt.pix);
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (vfd->vidioc_try_fmt_overlay)
- ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
+ if (vfd->vidioc_try_fmt_vid_overlay)
+ ret = vfd->vidioc_try_fmt_vid_overlay(file,
+ fh, f);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ if (vfd->vidioc_try_fmt_vid_out)
+ ret = vfd->vidioc_try_fmt_vid_out(file, fh, f);
+ if (!ret)
+ v4l_print_pix_fmt(vfd, &f->fmt.pix);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ if (vfd->vidioc_try_fmt_vid_out_overlay)
+ ret = vfd->vidioc_try_fmt_vid_out_overlay(file,
+ fh, f);
break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_vbi)
- ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
+ if (vfd->vidioc_try_fmt_vbi_cap)
+ ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f);
break;
- case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_vbi_output)
- ret=vfd->vidioc_try_fmt_vbi_output(file,
- fh, f);
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ if (vfd->vidioc_try_fmt_vbi_out)
+ ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f);
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- if (vfd->vidioc_try_fmt_vbi_capture)
- ret=vfd->vidioc_try_fmt_vbi_capture(file,
- fh, f);
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (vfd->vidioc_try_fmt_video_output)
- ret=vfd->vidioc_try_fmt_video_output(file,
+ if (vfd->vidioc_try_fmt_sliced_vbi_cap)
+ ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file,
fh, f);
break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (vfd->vidioc_try_fmt_output_overlay)
- ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
- break;
- case V4L2_BUF_TYPE_VBI_OUTPUT:
- if (vfd->vidioc_try_fmt_vbi_output)
- ret=vfd->vidioc_try_fmt_vbi_output(file,
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ if (vfd->vidioc_try_fmt_sliced_vbi_out)
+ ret = vfd->vidioc_try_fmt_sliced_vbi_out(file,
fh, f);
break;
case V4L2_BUF_TYPE_PRIVATE:
if (vfd->vidioc_try_fmt_type_private)
- ret=vfd->vidioc_try_fmt_type_private(file,
+ ret = vfd->vidioc_try_fmt_type_private(file,
fh, f);
break;
}
@@ -1120,29 +1176,29 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_G_FBUF:
{
- struct v4l2_framebuffer *p=arg;
+ struct v4l2_framebuffer *p = arg;
+
if (!vfd->vidioc_g_fbuf)
break;
- ret=vfd->vidioc_g_fbuf(file, fh, arg);
+ ret = vfd->vidioc_g_fbuf(file, fh, arg);
if (!ret) {
- dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
- p->capability,p->flags,
+ dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
+ p->capability, p->flags,
(unsigned long)p->base);
- v4l_print_pix_fmt (vfd, &p->fmt);
+ v4l_print_pix_fmt(vfd, &p->fmt);
}
break;
}
case VIDIOC_S_FBUF:
{
- struct v4l2_framebuffer *p=arg;
+ struct v4l2_framebuffer *p = arg;
+
if (!vfd->vidioc_s_fbuf)
break;
-
- dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
- p->capability,p->flags,(unsigned long)p->base);
- v4l_print_pix_fmt (vfd, &p->fmt);
- ret=vfd->vidioc_s_fbuf(file, fh, arg);
-
+ dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n",
+ p->capability, p->flags, (unsigned long)p->base);
+ v4l_print_pix_fmt(vfd, &p->fmt);
+ ret = vfd->vidioc_s_fbuf(file, fh, arg);
break;
}
case VIDIOC_STREAMON:
@@ -1194,7 +1250,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
v4l2_video_std_construct(p, curr_id, descr);
p->index = index;
- dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
+ dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
"framelines=%d\n", p->index,
(unsigned long long)p->id, p->name,
p->frameperiod.numerator,
@@ -1208,18 +1264,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
{
v4l2_std_id *id = arg;
- *id = vfd->current_norm;
-
- dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id);
+ ret = 0;
+ /* Calls the specific handler */
+ if (vfd->vidioc_g_std)
+ ret = vfd->vidioc_g_std(file, fh, id);
+ else
+ *id = vfd->current_norm;
- ret=0;
+ if (!ret)
+ dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
break;
}
case VIDIOC_S_STD:
{
v4l2_std_id *id = arg,norm;
- dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id);
+ dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);
norm = (*id) & vfd->tvnorms;
if ( vfd->tvnorms && !norm) /* Check if std is supported */
@@ -1295,6 +1355,25 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
}
/* ------ output switching ---------- */
+ case VIDIOC_ENUMOUTPUT:
+ {
+ struct v4l2_output *p = arg;
+ int i = p->index;
+
+ if (!vfd->vidioc_enum_output)
+ break;
+ memset(p, 0, sizeof(*p));
+ p->index = i;
+
+ ret = vfd->vidioc_enum_output(file, fh, p);
+ if (!ret)
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "audioset=0x%x, "
+ "modulator=%d, std=0x%08Lx\n",
+ p->index, p->name, p->type, p->audioset,
+ p->modulator, (unsigned long long)p->std);
+ break;
+ }
case VIDIOC_G_OUTPUT:
{
unsigned int *i = arg;
@@ -1320,132 +1399,172 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
/* --- controls ---------------------------------------------- */
case VIDIOC_QUERYCTRL:
{
- struct v4l2_queryctrl *p=arg;
+ struct v4l2_queryctrl *p = arg;
if (!vfd->vidioc_queryctrl)
break;
- ret=vfd->vidioc_queryctrl(file, fh, p);
-
+ ret = vfd->vidioc_queryctrl(file, fh, p);
if (!ret)
- dbgarg (cmd, "id=%d, type=%d, name=%s, "
- "min/max=%d/%d,"
- " step=%d, default=%d, flags=0x%08x\n",
- p->id,p->type,p->name,p->minimum,
- p->maximum,p->step,p->default_value,
- p->flags);
+ dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, "
+ "step=%d, default=%d, flags=0x%08x\n",
+ p->id, p->type, p->name,
+ p->minimum, p->maximum,
+ p->step, p->default_value, p->flags);
+ else
+ dbgarg(cmd, "id=0x%x\n", p->id);
break;
}
case VIDIOC_G_CTRL:
{
struct v4l2_control *p = arg;
- if (!vfd->vidioc_g_ctrl)
+ if (vfd->vidioc_g_ctrl)
+ ret = vfd->vidioc_g_ctrl(file, fh, p);
+ else if (vfd->vidioc_g_ext_ctrls) {
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+
+ ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
+ ctrls.count = 1;
+ ctrls.controls = &ctrl;
+ ctrl.id = p->id;
+ ctrl.value = p->value;
+ if (check_ext_ctrls(&ctrls, 1)) {
+ ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls);
+ if (ret == 0)
+ p->value = ctrl.value;
+ }
+ } else
break;
- dbgarg(cmd, "Enum for index=%d\n", p->id);
-
- ret=vfd->vidioc_g_ctrl(file, fh, p);
if (!ret)
- dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
+ dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
+ else
+ dbgarg(cmd, "id=0x%x\n", p->id);
break;
}
case VIDIOC_S_CTRL:
{
struct v4l2_control *p = arg;
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+
+ if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls)
+ break;
- if (!vfd->vidioc_s_ctrl)
+ dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value);
+
+ if (vfd->vidioc_s_ctrl) {
+ ret = vfd->vidioc_s_ctrl(file, fh, p);
+ break;
+ }
+ if (!vfd->vidioc_s_ext_ctrls)
break;
- dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
- ret=vfd->vidioc_s_ctrl(file, fh, p);
+ ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id);
+ ctrls.count = 1;
+ ctrls.controls = &ctrl;
+ ctrl.id = p->id;
+ ctrl.value = p->value;
+ if (check_ext_ctrls(&ctrls, 1))
+ ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls);
break;
}
case VIDIOC_G_EXT_CTRLS:
{
struct v4l2_ext_controls *p = arg;
- if (vfd->vidioc_g_ext_ctrls) {
- dbgarg(cmd, "count=%d\n", p->count);
-
- ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
- }
+ p->error_idx = p->count;
+ if (!vfd->vidioc_g_ext_ctrls)
+ break;
+ if (check_ext_ctrls(p, 0))
+ ret = vfd->vidioc_g_ext_ctrls(file, fh, p);
+ v4l_print_ext_ctrls(cmd, vfd, p, !ret);
break;
}
case VIDIOC_S_EXT_CTRLS:
{
struct v4l2_ext_controls *p = arg;
- if (vfd->vidioc_s_ext_ctrls) {
- dbgarg(cmd, "count=%d\n", p->count);
-
- ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
- }
+ p->error_idx = p->count;
+ if (!vfd->vidioc_s_ext_ctrls)
+ break;
+ v4l_print_ext_ctrls(cmd, vfd, p, 1);
+ if (check_ext_ctrls(p, 0))
+ ret = vfd->vidioc_s_ext_ctrls(file, fh, p);
break;
}
case VIDIOC_TRY_EXT_CTRLS:
{
struct v4l2_ext_controls *p = arg;
- if (vfd->vidioc_try_ext_ctrls) {
- dbgarg(cmd, "count=%d\n", p->count);
-
- ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
- }
+ p->error_idx = p->count;
+ if (!vfd->vidioc_try_ext_ctrls)
+ break;
+ v4l_print_ext_ctrls(cmd, vfd, p, 1);
+ if (check_ext_ctrls(p, 0))
+ ret = vfd->vidioc_try_ext_ctrls(file, fh, p);
break;
}
case VIDIOC_QUERYMENU:
{
- struct v4l2_querymenu *p=arg;
+ struct v4l2_querymenu *p = arg;
+
if (!vfd->vidioc_querymenu)
break;
- ret=vfd->vidioc_querymenu(file, fh, p);
+ ret = vfd->vidioc_querymenu(file, fh, p);
if (!ret)
- dbgarg (cmd, "id=%d, index=%d, name=%s\n",
- p->id,p->index,p->name);
+ dbgarg(cmd, "id=0x%x, index=%d, name=%s\n",
+ p->id, p->index, p->name);
+ else
+ dbgarg(cmd, "id=0x%x, index=%d\n",
+ p->id, p->index);
break;
}
/* --- audio ---------------------------------------------- */
case VIDIOC_ENUMAUDIO:
{
- struct v4l2_audio *p=arg;
+ struct v4l2_audio *p = arg;
if (!vfd->vidioc_enumaudio)
break;
- dbgarg(cmd, "Enum for index=%d\n", p->index);
- ret=vfd->vidioc_enumaudio(file, fh, p);
+ ret = vfd->vidioc_enumaudio(file, fh, p);
if (!ret)
- dbgarg2("index=%d, name=%s, capability=%d, "
- "mode=%d\n",p->index,p->name,
+ dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+ "mode=0x%x\n", p->index, p->name,
p->capability, p->mode);
+ else
+ dbgarg(cmd, "index=%d\n", p->index);
break;
}
case VIDIOC_G_AUDIO:
{
- struct v4l2_audio *p=arg;
- __u32 index=p->index;
+ struct v4l2_audio *p = arg;
+ __u32 index = p->index;
if (!vfd->vidioc_g_audio)
break;
- memset(p,0,sizeof(*p));
- p->index=index;
- dbgarg(cmd, "Get for index=%d\n", p->index);
- ret=vfd->vidioc_g_audio(file, fh, p);
+ memset(p, 0, sizeof(*p));
+ p->index = index;
+ ret = vfd->vidioc_g_audio(file, fh, p);
if (!ret)
- dbgarg2("index=%d, name=%s, capability=%d, "
- "mode=%d\n",p->index,
- p->name,p->capability, p->mode);
+ dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+ "mode=0x%x\n", p->index,
+ p->name, p->capability, p->mode);
+ else
+ dbgarg(cmd, "index=%d\n", p->index);
break;
}
case VIDIOC_S_AUDIO:
{
- struct v4l2_audio *p=arg;
+ struct v4l2_audio *p = arg;
if (!vfd->vidioc_s_audio)
break;
- dbgarg(cmd, "index=%d, name=%s, capability=%d, "
- "mode=%d\n", p->index, p->name,
+ dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
+ "mode=0x%x\n", p->index, p->name,
p->capability, p->mode);
- ret=vfd->vidioc_s_audio(file, fh, p);
+ ret = vfd->vidioc_s_audio(file, fh, p);
break;
}
case VIDIOC_ENUMAUDOUT:
@@ -1521,9 +1640,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_crop *p=arg;
if (!vfd->vidioc_g_crop)
break;
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret=vfd->vidioc_g_crop(file, fh, p);
if (!ret) {
- dbgarg(cmd, "type=%d\n", p->type);
dbgrect(vfd, "", &p->c);
}
break;
@@ -1533,21 +1652,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
struct v4l2_crop *p=arg;
if (!vfd->vidioc_s_crop)
break;
- dbgarg(cmd, "type=%d\n", p->type);
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
dbgrect(vfd, "", &p->c);
ret=vfd->vidioc_s_crop(file, fh, p);
break;
}
case VIDIOC_CROPCAP:
{
- struct v4l2_cropcap *p=arg;
+ struct v4l2_cropcap *p = arg;
+
/*FIXME: Should also show v4l2_fract pixelaspect */
if (!vfd->vidioc_cropcap)
break;
- dbgarg(cmd, "type=%d\n", p->type);
- dbgrect(vfd, "bounds ", &p->bounds);
- dbgrect(vfd, "defrect ", &p->defrect);
- ret=vfd->vidioc_cropcap(file, fh, p);
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+ ret = vfd->vidioc_cropcap(file, fh, p);
+ if (!ret) {
+ dbgrect(vfd, "bounds ", &p->bounds);
+ dbgrect(vfd, "defrect ", &p->defrect);
+ }
break;
}
case VIDIOC_G_JPEGCOMP:
@@ -1590,26 +1712,26 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_ENCODER_CMD:
{
- struct v4l2_encoder_cmd *p=arg;
+ struct v4l2_encoder_cmd *p = arg;
if (!vfd->vidioc_encoder_cmd)
break;
- ret=vfd->vidioc_encoder_cmd(file, fh, p);
+ memset(&p->raw, 0, sizeof(p->raw));
+ ret = vfd->vidioc_encoder_cmd(file, fh, p);
if (!ret)
- dbgarg (cmd, "cmd=%d, flags=%d\n",
- p->cmd,p->flags);
+ dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
break;
}
case VIDIOC_TRY_ENCODER_CMD:
{
- struct v4l2_encoder_cmd *p=arg;
+ struct v4l2_encoder_cmd *p = arg;
if (!vfd->vidioc_try_encoder_cmd)
break;
- ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
+ memset(&p->raw, 0, sizeof(p->raw));
+ ret = vfd->vidioc_try_encoder_cmd(file, fh, p);
if (!ret)
- dbgarg (cmd, "cmd=%d, flags=%d\n",
- p->cmd,p->flags);
+ dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
break;
}
case VIDIOC_G_PARM:
@@ -1649,54 +1771,57 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_G_TUNER:
{
- struct v4l2_tuner *p=arg;
- __u32 index=p->index;
+ struct v4l2_tuner *p = arg;
+ __u32 index = p->index;
if (!vfd->vidioc_g_tuner)
break;
- memset(p,0,sizeof(*p));
- p->index=index;
+ memset(p, 0, sizeof(*p));
+ p->index = index;
- ret=vfd->vidioc_g_tuner(file, fh, p);
+ ret = vfd->vidioc_g_tuner(file, fh, p);
if (!ret)
- dbgarg (cmd, "index=%d, name=%s, type=%d, "
- "capability=%d, rangelow=%d, "
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "capability=0x%x, rangelow=%d, "
"rangehigh=%d, signal=%d, afc=%d, "
- "rxsubchans=%d, audmode=%d\n",
+ "rxsubchans=0x%x, audmode=%d\n",
p->index, p->name, p->type,
p->capability, p->rangelow,
- p->rangehigh, p->rxsubchans,
- p->audmode, p->signal, p->afc);
+ p->rangehigh, p->signal, p->afc,
+ p->rxsubchans, p->audmode);
break;
}
case VIDIOC_S_TUNER:
{
- struct v4l2_tuner *p=arg;
+ struct v4l2_tuner *p = arg;
+
if (!vfd->vidioc_s_tuner)
break;
- dbgarg (cmd, "index=%d, name=%s, type=%d, "
- "capability=%d, rangelow=%d, rangehigh=%d, "
- "signal=%d, afc=%d, rxsubchans=%d, "
- "audmode=%d\n",p->index, p->name, p->type,
- p->capability, p->rangelow,p->rangehigh,
- p->rxsubchans, p->audmode, p->signal,
- p->afc);
- ret=vfd->vidioc_s_tuner(file, fh, p);
+ dbgarg(cmd, "index=%d, name=%s, type=%d, "
+ "capability=0x%x, rangelow=%d, "
+ "rangehigh=%d, signal=%d, afc=%d, "
+ "rxsubchans=0x%x, audmode=%d\n",
+ p->index, p->name, p->type,
+ p->capability, p->rangelow,
+ p->rangehigh, p->signal, p->afc,
+ p->rxsubchans, p->audmode);
+ ret = vfd->vidioc_s_tuner(file, fh, p);
break;
}
case VIDIOC_G_FREQUENCY:
{
- struct v4l2_frequency *p=arg;
+ struct v4l2_frequency *p = arg;
+
if (!vfd->vidioc_g_frequency)
break;
- memset(p,0,sizeof(*p));
+ memset(p->reserved, 0, sizeof(p->reserved));
- ret=vfd->vidioc_g_frequency(file, fh, p);
+ ret = vfd->vidioc_g_frequency(file, fh, p);
if (!ret)
- dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
- p->tuner,p->type,p->frequency);
+ dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
+ p->tuner, p->type, p->frequency);
break;
}
case VIDIOC_S_FREQUENCY:
@@ -1711,12 +1836,17 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
}
case VIDIOC_G_SLICED_VBI_CAP:
{
- struct v4l2_sliced_vbi_cap *p=arg;
+ struct v4l2_sliced_vbi_cap *p = arg;
+ __u32 type = p->type;
+
if (!vfd->vidioc_g_sliced_vbi_cap)
break;
- ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
+ memset(p, 0, sizeof(*p));
+ p->type = type;
+ dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
+ ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
if (!ret)
- dbgarg (cmd, "service_set=%d\n", p->service_set);
+ dbgarg2("service_set=%d\n", p->service_set);
break;
}
case VIDIOC_LOG_STATUS:
@@ -1763,13 +1893,23 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret = vfd->vidioc_default(file, fh, cmd, arg);
break;
}
+ case VIDIOC_S_HW_FREQ_SEEK:
+ {
+ struct v4l2_hw_freq_seek *p = arg;
+ if (!vfd->vidioc_s_hw_freq_seek)
+ break;
+ dbgarg(cmd,
+ "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
+ p->tuner, p->type, p->seek_upward, p->wrap_around);
+ ret = vfd->vidioc_s_hw_freq_seek(file, fh, p);
+ break;
+ }
} /* switch */
if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
- if (ret<0) {
- printk("%s: err: on ", vfd->name);
+ if (ret < 0) {
v4l_print_ioctl(vfd->name, cmd);
- printk("\n");
+ printk(KERN_CONT " error %d\n", ret);
}
}
@@ -1871,8 +2011,55 @@ out:
}
EXPORT_SYMBOL(video_ioctl2);
+/**
+ * get_index - assign stream number based on parent device
+ * @vdev: video_device to assign index number to, vdev->dev should be assigned
+ * @num: -1 if auto assign, requested number otherwise
+ *
+ *
+ * returns -ENFILE if num is already in use, a free index number if
+ * successful.
+ */
+static int get_index(struct video_device *vdev, int num)
+{
+ u32 used = 0;
+ const int max_index = sizeof(used) * 8 - 1;
+ int i;
+
+ /* Currently a single v4l driver instance cannot create more than
+ 32 devices.
+ Increase to u64 or an array of u32 if more are needed. */
+ if (num > max_index) {
+ printk(KERN_ERR "videodev: %s num is too large\n", __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
+ if (video_device[i] != NULL &&
+ video_device[i] != vdev &&
+ video_device[i]->dev == vdev->dev) {
+ used |= 1 << video_device[i]->index;
+ }
+ }
+
+ if (num >= 0) {
+ if (used & (1 << num))
+ return -ENFILE;
+ return num;
+ }
+
+ i = ffz(used);
+ return i > max_index ? -ENFILE : i;
+}
+
static const struct file_operations video_fops;
+int video_register_device(struct video_device *vfd, int type, int nr)
+{
+ return video_register_device_index(vfd, type, nr, -1);
+}
+EXPORT_SYMBOL(video_register_device);
+
/**
* video_register_device - register video4linux devices
* @vfd: video device structure we want to register
@@ -1898,7 +2085,8 @@ static const struct file_operations video_fops;
* %VFL_TYPE_RADIO - A radio card
*/
-int video_register_device(struct video_device *vfd, int type, int nr)
+int video_register_device_index(struct video_device *vfd, int type, int nr,
+ int index)
{
int i=0;
int base;
@@ -1955,20 +2143,29 @@ int video_register_device(struct video_device *vfd, int type, int nr)
}
video_device[i]=vfd;
vfd->minor=i;
+
+ ret = get_index(vfd, index);
+ vfd->index = ret;
+
mutex_unlock(&videodev_lock);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: get_index failed\n", __func__);
+ goto fail_minor;
+ }
+
mutex_init(&vfd->lock);
/* sysfs class */
memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
- if (vfd->dev)
- vfd->class_dev.parent = vfd->dev;
vfd->class_dev.class = &video_class;
vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
+ if (vfd->dev)
+ vfd->class_dev.parent = vfd->dev;
sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
ret = device_register(&vfd->class_dev);
if (ret < 0) {
- printk(KERN_ERR "%s: device_register failed\n",
- __func__);
+ printk(KERN_ERR "%s: device_register failed\n", __func__);
goto fail_minor;
}
@@ -1988,7 +2185,7 @@ fail_minor:
mutex_unlock(&videodev_lock);
return ret;
}
-EXPORT_SYMBOL(video_register_device);
+EXPORT_SYMBOL(video_register_device_index);
/**
* video_unregister_device - unregister a video4linux device
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 5ff9a58b613..059b01c11dc 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -39,6 +39,8 @@
#include <linux/highmem.h>
#include <linux/freezer.h>
+#define VIVI_MODULE_NAME "vivi"
+
/* Wake up at about 30 fps */
#define WAKE_NUMERATOR 30
#define WAKE_DENOMINATOR 1001
@@ -47,7 +49,7 @@
#include "font.h"
#define VIVI_MAJOR_VERSION 0
-#define VIVI_MINOR_VERSION 4
+#define VIVI_MINOR_VERSION 5
#define VIVI_RELEASE 0
#define VIVI_VERSION \
KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
@@ -630,7 +632,7 @@ static int vidioc_querycap(struct file *file, void *priv,
return 0;
}
-static int vidioc_enum_fmt_cap(struct file *file, void *priv,
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
if (f->index > 0)
@@ -641,7 +643,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_fmt_cap(struct file *file, void *priv,
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct vivi_fh *fh = priv;
@@ -658,7 +660,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv,
return (0);
}
-static int vidioc_try_fmt_cap(struct file *file, void *priv,
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct vivi_fh *fh = priv;
@@ -706,13 +708,13 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv,
}
/*FIXME: This seems to be generic enough to be at videodev2 */
-static int vidioc_s_fmt_cap(struct file *file, void *priv,
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct vivi_fh *fh = priv;
struct videobuf_queue *q = &fh->vb_vidq;
- int ret = vidioc_try_fmt_cap(file, fh, f);
+ int ret = vidioc_try_fmt_vid_cap(file, fh, f);
if (ret < 0)
return (ret);
@@ -1017,10 +1019,15 @@ static int vivi_release(void)
list_del(list);
dev = list_entry(list, struct vivi_dev, vivi_devlist);
- if (-1 != dev->vfd->minor)
+ if (-1 != dev->vfd->minor) {
video_unregister_device(dev->vfd);
- else
+ printk(KERN_INFO "%s: /dev/video%d unregistered.\n",
+ VIVI_MODULE_NAME, dev->vfd->minor);
+ } else {
video_device_release(dev->vfd);
+ printk(KERN_INFO "%s: /dev/video%d released.\n",
+ VIVI_MODULE_NAME, dev->vfd->minor);
+ }
kfree(dev);
}
@@ -1066,10 +1073,10 @@ static struct video_device vivi_template = {
.release = video_device_release,
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
- .vidioc_g_fmt_cap = vidioc_g_fmt_cap,
- .vidioc_try_fmt_cap = vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
@@ -1131,6 +1138,8 @@ static int __init vivi_init(void)
video_nr++;
dev->vfd = vfd;
+ printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
+ VIVI_MODULE_NAME, vfd->minor);
}
if (ret < 0) {
@@ -1138,7 +1147,9 @@ static int __init vivi_init(void)
printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
} else
printk(KERN_INFO "Video Technology Magazine Virtual Video "
- "Capture Board successfully loaded.\n");
+ "Capture Board ver %u.%u.%u successfully loaded.\n",
+ (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
+ VIVI_VERSION & 0xFF);
return ret;
}
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index a1f76ee032e..cbecb3cbbba 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -166,4 +166,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.remove = vp27smpx_remove,
.id_table = vp27smpx_id,
};
-
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index fc50299caa3..7be47a25585 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -327,4 +327,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.remove = wm8739_remove,
.id_table = wm8739_id,
};
-
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 506378a508b..c2ab70a04a7 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -42,7 +42,6 @@ MODULE_LICENSE("GPL");
static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
-
I2C_CLIENT_INSMOD;
@@ -230,4 +229,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.remove = wm8775_remove,
.id_table = wm8775_id,
};
-
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 006d48847e2..0929edb2d4f 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -59,8 +59,6 @@
#include "zoran_device.h"
#include "zoran_procfs.h"
-#define I2C_NAME(x) (x)->name
-
extern const struct zoran_format zoran_formats[];
static int card[BUZ_MAX] = { -1, -1, -1, -1 };
@@ -360,14 +358,6 @@ i2cid_to_modulename (u16 i2c_id)
case I2C_DRIVERID_VPX3220:
name = "vpx3220";
break;
-/* case I2C_DRIVERID_VPX3224:
- name = "vpx3224";
- break;
- case I2C_DRIVERID_MSE3000:
- name = "mse3000";
- break;*/
- default:
- break;
}
return name;
@@ -388,8 +378,6 @@ codecid_to_modulename (u16 codecid)
case CODEC_TYPE_ZR36016:
name = "zr36016";
break;
- default:
- break;
}
return name;
@@ -430,7 +418,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
.type = DC10_old,
.name = "DC10(old)",
.i2c_decoder = I2C_DRIVERID_VPX3220,
- /*.i2c_encoder = I2C_DRIVERID_MSE3000,*/
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -809,7 +796,7 @@ clientunreg_unlock_and_return:
return res;
}
-static struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
+static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
.setsda = zoran_i2c_setsda,
.setscl = zoran_i2c_setscl,
.getsda = zoran_i2c_getsda,
@@ -818,24 +805,17 @@ static struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
.timeout = 100,
};
-static struct i2c_adapter zoran_i2c_adapter_template = {
- .name = "zr36057",
- .id = I2C_HW_B_ZR36067,
- .algo = NULL,
- .client_register = zoran_i2c_client_register,
- .client_unregister = zoran_i2c_client_unregister,
-};
-
static int
zoran_register_i2c (struct zoran *zr)
{
memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
sizeof(struct i2c_algo_bit_data));
zr->i2c_algo.data = zr;
- memcpy(&zr->i2c_adapter, &zoran_i2c_adapter_template,
- sizeof(struct i2c_adapter));
- strncpy(I2C_NAME(&zr->i2c_adapter), ZR_DEVNAME(zr),
- sizeof(I2C_NAME(&zr->i2c_adapter)) - 1);
+ zr->i2c_adapter.id = I2C_HW_B_ZR36067;
+ zr->i2c_adapter.client_register = zoran_i2c_client_register;
+ zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;
+ strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
+ sizeof(zr->i2c_adapter.name));
i2c_set_adapdata(&zr->i2c_adapter, zr);
zr->i2c_adapter.algo_data = &zr->i2c_algo;
zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
@@ -1147,7 +1127,7 @@ zr36057_init (struct zoran *zr)
goto exit_free;
}
for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */
+ zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */
}
/*
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 5394d7a5cfe..c0675921fe2 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -94,7 +94,6 @@
V4L2_CAP_VIDEO_OVERLAY \
)
-#include <asm/byteorder.h>
#if defined(CONFIG_VIDEO_V4L1_COMPAT)
#define ZFMT(pal, fcc, cs) \
@@ -2795,7 +2794,7 @@ zoran_do_ioctl (struct inode *inode,
{
struct v4l2_format *fmt = arg;
int i, res = 0;
- __u32 printformat;
+ __le32 printformat;
dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ",
ZR_DEVNAME(zr), fmt->type);
@@ -3040,7 +3039,7 @@ zoran_do_ioctl (struct inode *inode,
{
int i, res = 0;
struct v4l2_framebuffer *fb = arg;
- __u32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
+ __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
dprintk(3,
KERN_DEBUG
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index a0e49dc6630..485df2e3613 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -521,7 +521,7 @@ static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv,
return 0;
}
-static int zr364xx_vidioc_enum_fmt_cap(struct file *file,
+static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
void *priv, struct v4l2_fmtdesc *f)
{
if (f->index > 0)
@@ -537,7 +537,7 @@ static int zr364xx_vidioc_enum_fmt_cap(struct file *file,
return 0;
}
-static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv,
+static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct video_device *vdev = video_devdata(file);
@@ -564,7 +564,7 @@ static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv,
+static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct video_device *vdev = video_devdata(file);
@@ -589,7 +589,7 @@ static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv,
return 0;
}
-static int zr364xx_vidioc_s_fmt_cap(struct file *file, void *priv,
+static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct video_device *vdev = video_devdata(file);
@@ -770,10 +770,10 @@ static struct video_device zr364xx_template = {
.minor = -1,
.vidioc_querycap = zr364xx_vidioc_querycap,
- .vidioc_enum_fmt_cap = zr364xx_vidioc_enum_fmt_cap,
- .vidioc_try_fmt_cap = zr364xx_vidioc_try_fmt_cap,
- .vidioc_s_fmt_cap = zr364xx_vidioc_s_fmt_cap,
- .vidioc_g_fmt_cap = zr364xx_vidioc_g_fmt_cap,
+ .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = zr364xx_vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = zr364xx_vidioc_g_fmt_vid_cap,
.vidioc_enum_input = zr364xx_vidioc_enum_input,
.vidioc_g_input = zr364xx_vidioc_g_input,
.vidioc_s_input = zr364xx_vidioc_s_input,
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ae96bd6242f..260bade0a5e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -17,7 +17,7 @@ config MFD_SM501
config MFD_ASIC3
bool "Support for Compaq ASIC3"
- depends on GENERIC_HARDIRQS && ARM
+ depends on GENERIC_HARDIRQS && HAVE_GPIO_LIB && ARM
---help---
This driver supports the ASIC3 multifunction chip found on many
PDAs (mainly iPAQ and HTC based ones)
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index ef8a492766a..3b870e7fb3e 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -9,7 +9,7 @@
*
* Copyright 2001 Compaq Computer Corporation.
* Copyright 2004-2005 Phil Blundell
- * Copyright 2007 OpenedHand Ltd.
+ * Copyright 2007-2008 OpenedHand Ltd.
*
* Authors: Phil Blundell <pb@handhelds.org>,
* Samuel Ortiz <sameo@openedhand.com>
@@ -19,12 +19,26 @@
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/irq.h>
+#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/mfd/asic3.h>
+struct asic3 {
+ void __iomem *mapping;
+ unsigned int bus_shift;
+ unsigned int irq_nr;
+ unsigned int irq_base;
+ spinlock_t lock;
+ u16 irq_bothedge[4];
+ struct gpio_chip gpio;
+ struct device *dev;
+};
+
+static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset);
+
static inline void asic3_write_register(struct asic3 *asic,
unsigned int reg, u32 value)
{
@@ -41,8 +55,8 @@ static inline u32 asic3_read_register(struct asic3 *asic,
/* IRQs */
#define MAX_ASIC_ISR_LOOPS 20
-#define ASIC3_GPIO_Base_INCR \
- (ASIC3_GPIO_B_Base - ASIC3_GPIO_A_Base)
+#define ASIC3_GPIO_BASE_INCR \
+ (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE)
static void asic3_irq_flip_edge(struct asic3 *asic,
u32 base, int bit)
@@ -52,10 +66,10 @@ static void asic3_irq_flip_edge(struct asic3 *asic,
spin_lock_irqsave(&asic->lock, flags);
edge = asic3_read_register(asic,
- base + ASIC3_GPIO_EdgeTrigger);
+ base + ASIC3_GPIO_EDGE_TRIGGER);
edge ^= bit;
asic3_write_register(asic,
- base + ASIC3_GPIO_EdgeTrigger, edge);
+ base + ASIC3_GPIO_EDGE_TRIGGER, edge);
spin_unlock_irqrestore(&asic->lock, flags);
}
@@ -75,7 +89,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
spin_lock_irqsave(&asic->lock, flags);
status = asic3_read_register(asic,
- ASIC3_OFFSET(INTR, PIntStat));
+ ASIC3_OFFSET(INTR, P_INT_STAT));
spin_unlock_irqrestore(&asic->lock, flags);
/* Check all ten register bits */
@@ -87,17 +101,17 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
if (status & (1 << bank)) {
unsigned long base, istat;
- base = ASIC3_GPIO_A_Base
- + bank * ASIC3_GPIO_Base_INCR;
+ base = ASIC3_GPIO_A_BASE
+ + bank * ASIC3_GPIO_BASE_INCR;
spin_lock_irqsave(&asic->lock, flags);
istat = asic3_read_register(asic,
base +
- ASIC3_GPIO_IntStatus);
+ ASIC3_GPIO_INT_STATUS);
/* Clearing IntStatus */
asic3_write_register(asic,
base +
- ASIC3_GPIO_IntStatus, 0);
+ ASIC3_GPIO_INT_STATUS, 0);
spin_unlock_irqrestore(&asic->lock, flags);
for (i = 0; i < ASIC3_GPIOS_PER_BANK; i++) {
@@ -123,7 +137,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) {
/* They start at bit 4 and go up */
if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) {
- desc = irq_desc + + i;
+ desc = irq_desc + asic->irq_base + i;
desc->handle_irq(asic->irq_base + i,
desc);
}
@@ -131,8 +145,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
}
if (iter >= MAX_ASIC_ISR_LOOPS)
- printk(KERN_ERR "%s: interrupt processing overrun\n",
- __func__);
+ dev_err(asic->dev, "interrupt processing overrun\n");
}
static inline int asic3_irq_to_bank(struct asic3 *asic, int irq)
@@ -141,7 +154,7 @@ static inline int asic3_irq_to_bank(struct asic3 *asic, int irq)
n = (irq - asic->irq_base) >> 4;
- return (n * (ASIC3_GPIO_B_Base - ASIC3_GPIO_A_Base));
+ return (n * (ASIC3_GPIO_B_BASE - ASIC3_GPIO_A_BASE));
}
static inline int asic3_irq_to_index(struct asic3 *asic, int irq)
@@ -159,9 +172,9 @@ static void asic3_mask_gpio_irq(unsigned int irq)
index = asic3_irq_to_index(asic, irq);
spin_lock_irqsave(&asic->lock, flags);
- val = asic3_read_register(asic, bank + ASIC3_GPIO_Mask);
+ val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK);
val |= 1 << index;
- asic3_write_register(asic, bank + ASIC3_GPIO_Mask, val);
+ asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val);
spin_unlock_irqrestore(&asic->lock, flags);
}
@@ -173,15 +186,15 @@ static void asic3_mask_irq(unsigned int irq)
spin_lock_irqsave(&asic->lock, flags);
regval = asic3_read_register(asic,
- ASIC3_INTR_Base +
- ASIC3_INTR_IntMask);
+ ASIC3_INTR_BASE +
+ ASIC3_INTR_INT_MASK);
regval &= ~(ASIC3_INTMASK_MASK0 <<
(irq - (asic->irq_base + ASIC3_NUM_GPIOS)));
asic3_write_register(asic,
- ASIC3_INTR_Base +
- ASIC3_INTR_IntMask,
+ ASIC3_INTR_BASE +
+ ASIC3_INTR_INT_MASK,
regval);
spin_unlock_irqrestore(&asic->lock, flags);
}
@@ -196,9 +209,9 @@ static void asic3_unmask_gpio_irq(unsigned int irq)
index = asic3_irq_to_index(asic, irq);
spin_lock_irqsave(&asic->lock, flags);
- val = asic3_read_register(asic, bank + ASIC3_GPIO_Mask);
+ val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK);
val &= ~(1 << index);
- asic3_write_register(asic, bank + ASIC3_GPIO_Mask, val);
+ asic3_write_register(asic, bank + ASIC3_GPIO_MASK, val);
spin_unlock_irqrestore(&asic->lock, flags);
}
@@ -210,15 +223,15 @@ static void asic3_unmask_irq(unsigned int irq)
spin_lock_irqsave(&asic->lock, flags);
regval = asic3_read_register(asic,
- ASIC3_INTR_Base +
- ASIC3_INTR_IntMask);
+ ASIC3_INTR_BASE +
+ ASIC3_INTR_INT_MASK);
regval |= (ASIC3_INTMASK_MASK0 <<
(irq - (asic->irq_base + ASIC3_NUM_GPIOS)));
asic3_write_register(asic,
- ASIC3_INTR_Base +
- ASIC3_INTR_IntMask,
+ ASIC3_INTR_BASE +
+ ASIC3_INTR_INT_MASK,
regval);
spin_unlock_irqrestore(&asic->lock, flags);
}
@@ -236,11 +249,11 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
spin_lock_irqsave(&asic->lock, flags);
level = asic3_read_register(asic,
- bank + ASIC3_GPIO_LevelTrigger);
+ bank + ASIC3_GPIO_LEVEL_TRIGGER);
edge = asic3_read_register(asic,
- bank + ASIC3_GPIO_EdgeTrigger);
+ bank + ASIC3_GPIO_EDGE_TRIGGER);
trigger = asic3_read_register(asic,
- bank + ASIC3_GPIO_TriggerType);
+ bank + ASIC3_GPIO_TRIGGER_TYPE);
asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit;
if (type == IRQT_RISING) {
@@ -251,7 +264,7 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
edge &= ~bit;
} else if (type == IRQT_BOTHEDGE) {
trigger |= bit;
- if (asic3_gpio_get_value(asic, irq - asic->irq_base))
+ if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base))
edge &= ~bit;
else
edge |= bit;
@@ -268,13 +281,13 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
* be careful to not unmask them if mask was also called.
* Probably need internal state for mask.
*/
- printk(KERN_NOTICE "asic3: irq type not changed.\n");
+ dev_notice(asic->dev, "irq type not changed\n");
}
- asic3_write_register(asic, bank + ASIC3_GPIO_LevelTrigger,
+ asic3_write_register(asic, bank + ASIC3_GPIO_LEVEL_TRIGGER,
level);
- asic3_write_register(asic, bank + ASIC3_GPIO_EdgeTrigger,
+ asic3_write_register(asic, bank + ASIC3_GPIO_EDGE_TRIGGER,
edge);
- asic3_write_register(asic, bank + ASIC3_GPIO_TriggerType,
+ asic3_write_register(asic, bank + ASIC3_GPIO_TRIGGER_TYPE,
trigger);
spin_unlock_irqrestore(&asic->lock, flags);
return 0;
@@ -295,11 +308,12 @@ static struct irq_chip asic3_irq_chip = {
.unmask = asic3_unmask_irq,
};
-static int asic3_irq_probe(struct platform_device *pdev)
+static int __init asic3_irq_probe(struct platform_device *pdev)
{
struct asic3 *asic = platform_get_drvdata(pdev);
unsigned long clksel = 0;
unsigned int irq, irq_base;
+ int map_size;
asic->irq_nr = platform_get_irq(pdev, 0);
if (asic->irq_nr < 0)
@@ -323,7 +337,7 @@ static int asic3_irq_probe(struct platform_device *pdev)
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- asic3_write_register(asic, ASIC3_OFFSET(INTR, IntMask),
+ asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK),
ASIC3_INTMASK_GINTMASK);
set_irq_chained_handler(asic->irq_nr, asic3_irq_demux);
@@ -350,149 +364,182 @@ static void asic3_irq_remove(struct platform_device *pdev)
}
/* GPIOs */
-static inline u32 asic3_get_gpio(struct asic3 *asic, unsigned int base,
- unsigned int function)
-{
- return asic3_read_register(asic, base + function);
-}
-
-static void asic3_set_gpio(struct asic3 *asic, unsigned int base,
- unsigned int function, u32 bits, u32 val)
+static int asic3_gpio_direction(struct gpio_chip *chip,
+ unsigned offset, int out)
{
+ u32 mask = ASIC3_GPIO_TO_MASK(offset), out_reg;
+ unsigned int gpio_base;
unsigned long flags;
+ struct asic3 *asic;
+
+ asic = container_of(chip, struct asic3, gpio);
+ gpio_base = ASIC3_GPIO_TO_BASE(offset);
+
+ if (gpio_base > ASIC3_GPIO_D_BASE) {
+ dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
+ gpio_base, offset);
+ return -EINVAL;
+ }
spin_lock_irqsave(&asic->lock, flags);
- val |= (asic3_read_register(asic, base + function) & ~bits);
- asic3_write_register(asic, base + function, val);
+ out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_DIRECTION);
+
+ /* Input is 0, Output is 1 */
+ if (out)
+ out_reg |= mask;
+ else
+ out_reg &= ~mask;
+
+ asic3_write_register(asic, gpio_base + ASIC3_GPIO_DIRECTION, out_reg);
+
spin_unlock_irqrestore(&asic->lock, flags);
+
+ return 0;
+
+}
+
+static int asic3_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return asic3_gpio_direction(chip, offset, 0);
+}
+
+static int asic3_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ return asic3_gpio_direction(chip, offset, 1);
}
-#define asic3_get_gpio_a(asic, fn) \
- asic3_get_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn)
-#define asic3_get_gpio_b(asic, fn) \
- asic3_get_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn)
-#define asic3_get_gpio_c(asic, fn) \
- asic3_get_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn)
-#define asic3_get_gpio_d(asic, fn) \
- asic3_get_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn)
-
-#define asic3_set_gpio_a(asic, fn, bits, val) \
- asic3_set_gpio(asic, ASIC3_GPIO_A_Base, ASIC3_GPIO_##fn, bits, val)
-#define asic3_set_gpio_b(asic, fn, bits, val) \
- asic3_set_gpio(asic, ASIC3_GPIO_B_Base, ASIC3_GPIO_##fn, bits, val)
-#define asic3_set_gpio_c(asic, fn, bits, val) \
- asic3_set_gpio(asic, ASIC3_GPIO_C_Base, ASIC3_GPIO_##fn, bits, val)
-#define asic3_set_gpio_d(asic, fn, bits, val) \
- asic3_set_gpio(asic, ASIC3_GPIO_D_Base, ASIC3_GPIO_##fn, bits, val)
-
-#define asic3_set_gpio_banks(asic, fn, bits, pdata, field) \
- do { \
- asic3_set_gpio_a((asic), fn, (bits), (pdata)->gpio_a.field); \
- asic3_set_gpio_b((asic), fn, (bits), (pdata)->gpio_b.field); \
- asic3_set_gpio_c((asic), fn, (bits), (pdata)->gpio_c.field); \
- asic3_set_gpio_d((asic), fn, (bits), (pdata)->gpio_d.field); \
- } while (0)
-
-int asic3_gpio_get_value(struct asic3 *asic, unsigned gpio)
+static int asic3_gpio_get(struct gpio_chip *chip,
+ unsigned offset)
{
- u32 mask = ASIC3_GPIO_bit(gpio);
-
- switch (gpio >> 4) {
- case ASIC3_GPIO_BANK_A:
- return asic3_get_gpio_a(asic, Status) & mask;
- case ASIC3_GPIO_BANK_B:
- return asic3_get_gpio_b(asic, Status) & mask;
- case ASIC3_GPIO_BANK_C:
- return asic3_get_gpio_c(asic, Status) & mask;
- case ASIC3_GPIO_BANK_D:
- return asic3_get_gpio_d(asic, Status) & mask;
- default:
- printk(KERN_ERR "%s: invalid GPIO value 0x%x",
- __func__, gpio);
+ unsigned int gpio_base;
+ u32 mask = ASIC3_GPIO_TO_MASK(offset);
+ struct asic3 *asic;
+
+ asic = container_of(chip, struct asic3, gpio);
+ gpio_base = ASIC3_GPIO_TO_BASE(offset);
+
+ if (gpio_base > ASIC3_GPIO_D_BASE) {
+ dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
+ gpio_base, offset);
return -EINVAL;
}
+
+ return asic3_read_register(asic, gpio_base + ASIC3_GPIO_STATUS) & mask;
}
-EXPORT_SYMBOL(asic3_gpio_get_value);
-void asic3_gpio_set_value(struct asic3 *asic, unsigned gpio, int val)
+static void asic3_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
{
- u32 mask = ASIC3_GPIO_bit(gpio);
- u32 bitval = 0;
- if (val)
- bitval = mask;
-
- switch (gpio >> 4) {
- case ASIC3_GPIO_BANK_A:
- asic3_set_gpio_a(asic, Out, mask, bitval);
- return;
- case ASIC3_GPIO_BANK_B:
- asic3_set_gpio_b(asic, Out, mask, bitval);
- return;
- case ASIC3_GPIO_BANK_C:
- asic3_set_gpio_c(asic, Out, mask, bitval);
- return;
- case ASIC3_GPIO_BANK_D:
- asic3_set_gpio_d(asic, Out, mask, bitval);
- return;
- default:
- printk(KERN_ERR "%s: invalid GPIO value 0x%x",
- __func__, gpio);
+ u32 mask, out_reg;
+ unsigned int gpio_base;
+ unsigned long flags;
+ struct asic3 *asic;
+
+ asic = container_of(chip, struct asic3, gpio);
+ gpio_base = ASIC3_GPIO_TO_BASE(offset);
+
+ if (gpio_base > ASIC3_GPIO_D_BASE) {
+ dev_err(asic->dev, "Invalid base (0x%x) for gpio %d\n",
+ gpio_base, offset);
return;
}
+
+ mask = ASIC3_GPIO_TO_MASK(offset);
+
+ spin_lock_irqsave(&asic->lock, flags);
+
+ out_reg = asic3_read_register(asic, gpio_base + ASIC3_GPIO_OUT);
+
+ if (value)
+ out_reg |= mask;
+ else
+ out_reg &= ~mask;
+
+ asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg);
+
+ spin_unlock_irqrestore(&asic->lock, flags);
+
+ return;
}
-EXPORT_SYMBOL(asic3_gpio_set_value);
-static int asic3_gpio_probe(struct platform_device *pdev)
+static __init int asic3_gpio_probe(struct platform_device *pdev,
+ u16 *gpio_config, int num)
{
- struct asic3_platform_data *pdata = pdev->dev.platform_data;
struct asic3 *asic = platform_get_drvdata(pdev);
+ u16 alt_reg[ASIC3_NUM_GPIO_BANKS];
+ u16 out_reg[ASIC3_NUM_GPIO_BANKS];
+ u16 dir_reg[ASIC3_NUM_GPIO_BANKS];
+ int i;
+
+ memzero(alt_reg, ASIC3_NUM_GPIO_BANKS * sizeof(u16));
+ memzero(out_reg, ASIC3_NUM_GPIO_BANKS * sizeof(u16));
+ memzero(dir_reg, ASIC3_NUM_GPIO_BANKS * sizeof(u16));
+
+ /* Enable all GPIOs */
+ asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, MASK), 0xffff);
+ asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, MASK), 0xffff);
+ asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, MASK), 0xffff);
+ asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, MASK), 0xffff);
+
+ for (i = 0; i < num; i++) {
+ u8 alt, pin, dir, init, bank_num, bit_num;
+ u16 config = gpio_config[i];
+
+ pin = ASIC3_CONFIG_GPIO_PIN(config);
+ alt = ASIC3_CONFIG_GPIO_ALT(config);
+ dir = ASIC3_CONFIG_GPIO_DIR(config);
+ init = ASIC3_CONFIG_GPIO_INIT(config);
+
+ bank_num = ASIC3_GPIO_TO_BANK(pin);
+ bit_num = ASIC3_GPIO_TO_BIT(pin);
+
+ alt_reg[bank_num] |= (alt << bit_num);
+ out_reg[bank_num] |= (init << bit_num);
+ dir_reg[bank_num] |= (dir << bit_num);
+ }
- asic3_write_register(asic, ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
- asic3_write_register(asic, ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
- asic3_write_register(asic, ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
- asic3_write_register(asic, ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
-
- asic3_set_gpio_a(asic, SleepMask, 0xffff, 0xffff);
- asic3_set_gpio_b(asic, SleepMask, 0xffff, 0xffff);
- asic3_set_gpio_c(asic, SleepMask, 0xffff, 0xffff);
- asic3_set_gpio_d(asic, SleepMask, 0xffff, 0xffff);
-
- if (pdata) {
- asic3_set_gpio_banks(asic, Out, 0xffff, pdata, init);
- asic3_set_gpio_banks(asic, Direction, 0xffff, pdata, dir);
- asic3_set_gpio_banks(asic, SleepMask, 0xffff, pdata,
- sleep_mask);
- asic3_set_gpio_banks(asic, SleepOut, 0xffff, pdata, sleep_out);
- asic3_set_gpio_banks(asic, BattFaultOut, 0xffff, pdata,
- batt_fault_out);
- asic3_set_gpio_banks(asic, SleepConf, 0xffff, pdata,
- sleep_conf);
- asic3_set_gpio_banks(asic, AltFunction, 0xffff, pdata,
- alt_function);
+ for (i = 0; i < ASIC3_NUM_GPIO_BANKS; i++) {
+ asic3_write_register(asic,
+ ASIC3_BANK_TO_BASE(i) +
+ ASIC3_GPIO_DIRECTION,
+ dir_reg[i]);
+ asic3_write_register(asic,
+ ASIC3_BANK_TO_BASE(i) + ASIC3_GPIO_OUT,
+ out_reg[i]);
+ asic3_write_register(asic,
+ ASIC3_BANK_TO_BASE(i) +
+ ASIC3_GPIO_ALT_FUNCTION,
+ alt_reg[i]);
}
- return 0;
+ return gpiochip_add(&asic->gpio);
}
-static void asic3_gpio_remove(struct platform_device *pdev)
+static int asic3_gpio_remove(struct platform_device *pdev)
{
- return;
+ struct asic3 *asic = platform_get_drvdata(pdev);
+
+ return gpiochip_remove(&asic->gpio);
}
/* Core */
-static int asic3_probe(struct platform_device *pdev)
+static int __init asic3_probe(struct platform_device *pdev)
{
struct asic3_platform_data *pdata = pdev->dev.platform_data;
struct asic3 *asic;
struct resource *mem;
unsigned long clksel;
- int ret;
+ int ret = 0;
asic = kzalloc(sizeof(struct asic3), GFP_KERNEL);
- if (!asic)
+ if (asic == NULL) {
+ printk(KERN_ERR "kzalloc failed\n");
return -ENOMEM;
+ }
spin_lock_init(&asic->lock);
platform_set_drvdata(pdev, asic);
@@ -501,49 +548,58 @@ static int asic3_probe(struct platform_device *pdev)
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
ret = -ENOMEM;
- printk(KERN_ERR "asic3: no MEM resource\n");
- goto err_out_1;
+ dev_err(asic->dev, "no MEM resource\n");
+ goto out_free;
}
- asic->mapping = ioremap(mem->start, PAGE_SIZE);
+ map_size = mem->end - mem->start + 1;
+ asic->mapping = ioremap(mem->start, map_size);
if (!asic->mapping) {
ret = -ENOMEM;
- printk(KERN_ERR "asic3: couldn't ioremap\n");
- goto err_out_1;
+ dev_err(asic->dev, "Couldn't ioremap\n");
+ goto out_free;
}
asic->irq_base = pdata->irq_base;
- if (pdata && pdata->bus_shift)
- asic->bus_shift = 2 - pdata->bus_shift;
- else
- asic->bus_shift = 0;
+ /* calculate bus shift from mem resource */
+ asic->bus_shift = 2 - (map_size >> 12);
clksel = 0;
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), clksel);
ret = asic3_irq_probe(pdev);
if (ret < 0) {
- printk(KERN_ERR "asic3: couldn't probe IRQs\n");
- goto err_out_2;
+ dev_err(asic->dev, "Couldn't probe IRQs\n");
+ goto out_unmap;
}
- asic3_gpio_probe(pdev);
- if (pdata->children) {
- int i;
- for (i = 0; i < pdata->n_children; i++) {
- pdata->children[i]->dev.parent = &pdev->dev;
- platform_device_register(pdata->children[i]);
- }
+ asic->gpio.base = pdata->gpio_base;
+ asic->gpio.ngpio = ASIC3_NUM_GPIOS;
+ asic->gpio.get = asic3_gpio_get;
+ asic->gpio.set = asic3_gpio_set;
+ asic->gpio.direction_input = asic3_gpio_direction_input;
+ asic->gpio.direction_output = asic3_gpio_direction_output;
+
+ ret = asic3_gpio_probe(pdev,
+ pdata->gpio_config,
+ pdata->gpio_config_num);
+ if (ret < 0) {
+ dev_err(asic->dev, "GPIO probe failed\n");
+ goto out_irq;
}
- printk(KERN_INFO "ASIC3 Core driver\n");
+ dev_info(asic->dev, "ASIC3 Core driver\n");
return 0;
- err_out_2:
+ out_irq:
+ asic3_irq_remove(pdev);
+
+ out_unmap:
iounmap(asic->mapping);
- err_out_1:
+
+ out_free:
kfree(asic);
return ret;
@@ -551,9 +607,12 @@ static int asic3_probe(struct platform_device *pdev)
static int asic3_remove(struct platform_device *pdev)
{
+ int ret;
struct asic3 *asic = platform_get_drvdata(pdev);
- asic3_gpio_remove(pdev);
+ ret = asic3_gpio_remove(pdev);
+ if (ret < 0)
+ return ret;
asic3_irq_remove(pdev);
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL), 0);
@@ -573,7 +632,6 @@ static struct platform_driver asic3_device_driver = {
.driver = {
.name = "asic3",
},
- .probe = asic3_probe,
.remove = __devexit_p(asic3_remove),
.shutdown = asic3_shutdown,
};
@@ -581,7 +639,7 @@ static struct platform_driver asic3_device_driver = {
static int __init asic3_init(void)
{
int retval = 0;
- retval = platform_driver_register(&asic3_device_driver);
+ retval = platform_driver_probe(&asic3_device_driver, asic3_probe);
return retval;
}
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 9c23336750e..900b0ffdcc6 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -149,7 +149,7 @@ el2_pio_probe(struct net_device *dev)
#ifndef MODULE
struct net_device * __init el2_probe(int unit)
{
- struct net_device *dev = alloc_ei_netdev();
+ struct net_device *dev = alloc_eip_netdev();
int err;
if (!dev)
@@ -340,7 +340,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
dev->stop = &el2_close;
dev->ethtool_ops = &netdev_ethtool_ops;
#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
+ dev->poll_controller = eip_poll;
#endif
retval = register_netdev(dev);
@@ -386,7 +386,7 @@ el2_open(struct net_device *dev)
outb_p(0x00, E33G_IDCFR);
if (*irqp == probe_irq_off(cookie) /* It's a good IRQ line! */
&& ((retval = request_irq(dev->irq = *irqp,
- ei_interrupt, 0, dev->name, dev)) == 0))
+ eip_interrupt, 0, dev->name, dev)) == 0))
break;
}
} while (*++irqp);
@@ -395,13 +395,13 @@ el2_open(struct net_device *dev)
return retval;
}
} else {
- if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+ if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
return retval;
}
}
el2_init_card(dev);
- ei_open(dev);
+ eip_open(dev);
return 0;
}
@@ -412,7 +412,7 @@ el2_close(struct net_device *dev)
dev->irq = ei_status.saved_irq;
outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
- ei_close(dev);
+ eip_close(dev);
return 0;
}
@@ -698,7 +698,7 @@ init_module(void)
if (this_dev != 0) break; /* only autoprobe 1st one */
printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
}
- dev = alloc_ei_netdev();
+ dev = alloc_eip_netdev();
if (!dev)
break;
dev->irq = irq[this_dev];
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 105a8c7ca7e..e4e3241628d 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -572,12 +572,16 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
int irq;
DECLARE_MAC_BUF(mac);
+#ifdef __ISAPNP__
if (idev) {
irq = pnp_irq(idev, 0);
vp->dev = &idev->dev;
} else {
irq = inw(ioaddr + 0x2002) & 15;
}
+#else
+ irq = inw(ioaddr + 0x2002) & 15;
+#endif
dev->base_addr = ioaddr;
dev->irq = irq;
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index 239fc42fb8d..dc6e474229b 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -202,7 +202,6 @@ static void elmc_xmt_int(struct net_device *dev);
static void elmc_rnr_int(struct net_device *dev);
struct priv {
- struct net_device_stats stats;
unsigned long base;
char *memtop;
unsigned long mapped_start; /* Start of ioremap */
@@ -989,18 +988,18 @@ static void elmc_rcv_int(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
- p->stats.rx_packets++;
- p->stats.rx_bytes += totlen;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += totlen;
} else {
- p->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
} else {
printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
- p->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
} else { /* frame !(ok), only with 'save-bad-frames' */
printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
p->rfd_top->status = 0;
p->rfd_top->last = RFD_SUSP;
@@ -1018,7 +1017,7 @@ static void elmc_rnr_int(struct net_device *dev)
{
struct priv *p = (struct priv *) dev->priv;
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
WAIT_4_SCB_CMD(); /* wait for the last cmd */
p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
@@ -1046,24 +1045,24 @@ static void elmc_xmt_int(struct net_device *dev)
printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
}
if (status & STAT_OK) {
- p->stats.tx_packets++;
- p->stats.collisions += (status & TCMD_MAXCOLLMASK);
+ dev->stats.tx_packets++;
+ dev->stats.collisions += (status & TCMD_MAXCOLLMASK);
} else {
- p->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (status & TCMD_LATECOLL) {
printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
- p->stats.collisions++;
+ dev->stats.collisions++;
} else if (status & TCMD_NOCARRIER) {
- p->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
} else if (status & TCMD_LOSTCTS) {
printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
} else if (status & TCMD_UNDERRUN) {
- p->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
} else if (status & TCMD_MAXCOLL) {
printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
- p->stats.collisions += 16;
+ dev->stats.collisions += 16;
}
}
@@ -1215,12 +1214,12 @@ static struct net_device_stats *elmc_get_stats(struct net_device *dev)
ovrn = p->scb->ovrn_errs;
p->scb->ovrn_errs -= ovrn;
- p->stats.rx_crc_errors += crc;
- p->stats.rx_fifo_errors += ovrn;
- p->stats.rx_frame_errors += aln;
- p->stats.rx_dropped += rsc;
+ dev->stats.rx_crc_errors += crc;
+ dev->stats.rx_fifo_errors += ovrn;
+ dev->stats.rx_frame_errors += aln;
+ dev->stats.rx_dropped += rsc;
- return &p->stats;
+ return &dev->stats;
}
/********************************************************
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index fae295b6809..6aca0c640f1 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -158,7 +158,6 @@ struct mc32_local
int slot;
u32 base;
- struct net_device_stats net_stats;
volatile struct mc32_mailbox *rx_box;
volatile struct mc32_mailbox *tx_box;
volatile struct mc32_mailbox *exec_box;
@@ -1093,24 +1092,24 @@ static void mc32_update_stats(struct net_device *dev)
u32 rx_errors=0;
- rx_errors+=lp->net_stats.rx_crc_errors +=st->rx_crc_errors;
+ rx_errors+=dev->stats.rx_crc_errors +=st->rx_crc_errors;
st->rx_crc_errors=0;
- rx_errors+=lp->net_stats.rx_fifo_errors +=st->rx_overrun_errors;
+ rx_errors+=dev->stats.rx_fifo_errors +=st->rx_overrun_errors;
st->rx_overrun_errors=0;
- rx_errors+=lp->net_stats.rx_frame_errors +=st->rx_alignment_errors;
+ rx_errors+=dev->stats.rx_frame_errors +=st->rx_alignment_errors;
st->rx_alignment_errors=0;
- rx_errors+=lp->net_stats.rx_length_errors+=st->rx_tooshort_errors;
+ rx_errors+=dev->stats.rx_length_errors+=st->rx_tooshort_errors;
st->rx_tooshort_errors=0;
- rx_errors+=lp->net_stats.rx_missed_errors+=st->rx_outofresource_errors;
+ rx_errors+=dev->stats.rx_missed_errors+=st->rx_outofresource_errors;
st->rx_outofresource_errors=0;
- lp->net_stats.rx_errors=rx_errors;
+ dev->stats.rx_errors=rx_errors;
/* Number of packets which saw one collision */
- lp->net_stats.collisions+=st->dataC[10];
+ dev->stats.collisions+=st->dataC[10];
st->dataC[10]=0;
/* Number of packets which saw 2--15 collisions */
- lp->net_stats.collisions+=st->dataC[11];
+ dev->stats.collisions+=st->dataC[11];
st->dataC[11]=0;
}
@@ -1178,7 +1177,7 @@ static void mc32_rx_ring(struct net_device *dev)
skb=dev_alloc_skb(length+2);
if(skb==NULL) {
- lp->net_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
goto dropped;
}
@@ -1189,8 +1188,8 @@ static void mc32_rx_ring(struct net_device *dev)
skb->protocol=eth_type_trans(skb,dev);
dev->last_rx = jiffies;
- lp->net_stats.rx_packets++;
- lp->net_stats.rx_bytes += length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length;
netif_rx(skb);
}
@@ -1253,34 +1252,34 @@ static void mc32_tx_ring(struct net_device *dev)
/* Not COMPLETED */
break;
}
- lp->net_stats.tx_packets++;
+ dev->stats.tx_packets++;
if(!(np->status & (1<<6))) /* Not COMPLETED_OK */
{
- lp->net_stats.tx_errors++;
+ dev->stats.tx_errors++;
switch(np->status&0x0F)
{
case 1:
- lp->net_stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
break; /* Max collisions */
case 2:
- lp->net_stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
break;
case 3:
- lp->net_stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
break;
case 4:
- lp->net_stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
break; /* CTS Lost */
case 5:
- lp->net_stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
break; /* Transmit timeout */
}
}
/* Packets are sent in order - this is
basically a FIFO queue of buffers matching
the card ring */
- lp->net_stats.tx_bytes+=lp->tx_ring[t].skb->len;
+ dev->stats.tx_bytes+=lp->tx_ring[t].skb->len;
dev_kfree_skb_irq(lp->tx_ring[t].skb);
lp->tx_ring[t].skb=NULL;
atomic_inc(&lp->tx_count);
@@ -1367,7 +1366,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
case 6:
/* Out of RX buffers stat */
/* Must restart rx */
- lp->net_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
mc32_rx_ring(dev);
mc32_start_transceiver(dev);
break;
@@ -1489,10 +1488,8 @@ static int mc32_close(struct net_device *dev)
static struct net_device_stats *mc32_get_stats(struct net_device *dev)
{
- struct mc32_local *lp = netdev_priv(dev);
-
mc32_update_stats(dev);
- return &lp->net_stats;
+ return &dev->stats;
}
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index a453eda834d..6011d6fabef 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -340,7 +340,6 @@ struct cp_private {
u32 rx_config;
u16 cpcmd;
- struct net_device_stats net_stats;
struct cp_extra_stats cp_stats;
unsigned rx_head ____cacheline_aligned;
@@ -457,8 +456,8 @@ static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
{
skb->protocol = eth_type_trans (skb, cp->dev);
- cp->net_stats.rx_packets++;
- cp->net_stats.rx_bytes += skb->len;
+ cp->dev->stats.rx_packets++;
+ cp->dev->stats.rx_bytes += skb->len;
cp->dev->last_rx = jiffies;
#if CP_VLAN_TAG_USED
@@ -477,17 +476,17 @@ static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
printk (KERN_DEBUG
"%s: rx err, slot %d status 0x%x len %d\n",
cp->dev->name, rx_tail, status, len);
- cp->net_stats.rx_errors++;
+ cp->dev->stats.rx_errors++;
if (status & RxErrFrame)
- cp->net_stats.rx_frame_errors++;
+ cp->dev->stats.rx_frame_errors++;
if (status & RxErrCRC)
- cp->net_stats.rx_crc_errors++;
+ cp->dev->stats.rx_crc_errors++;
if ((status & RxErrRunt) || (status & RxErrLong))
- cp->net_stats.rx_length_errors++;
+ cp->dev->stats.rx_length_errors++;
if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag))
- cp->net_stats.rx_length_errors++;
+ cp->dev->stats.rx_length_errors++;
if (status & RxErrFIFO)
- cp->net_stats.rx_fifo_errors++;
+ cp->dev->stats.rx_fifo_errors++;
}
static inline unsigned int cp_rx_csum_ok (u32 status)
@@ -539,7 +538,7 @@ rx_status_loop:
* that RX fragments are never encountered
*/
cp_rx_err_acct(cp, rx_tail, status, len);
- cp->net_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
cp->cp_stats.rx_frags++;
goto rx_next;
}
@@ -556,7 +555,7 @@ rx_status_loop:
buflen = cp->rx_buf_sz + RX_OFFSET;
new_skb = dev_alloc_skb (buflen);
if (!new_skb) {
- cp->net_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
goto rx_next;
}
@@ -710,20 +709,20 @@ static void cp_tx (struct cp_private *cp)
if (netif_msg_tx_err(cp))
printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
cp->dev->name, status);
- cp->net_stats.tx_errors++;
+ cp->dev->stats.tx_errors++;
if (status & TxOWC)
- cp->net_stats.tx_window_errors++;
+ cp->dev->stats.tx_window_errors++;
if (status & TxMaxCol)
- cp->net_stats.tx_aborted_errors++;
+ cp->dev->stats.tx_aborted_errors++;
if (status & TxLinkFail)
- cp->net_stats.tx_carrier_errors++;
+ cp->dev->stats.tx_carrier_errors++;
if (status & TxFIFOUnder)
- cp->net_stats.tx_fifo_errors++;
+ cp->dev->stats.tx_fifo_errors++;
} else {
- cp->net_stats.collisions +=
+ cp->dev->stats.collisions +=
((status >> TxColCntShift) & TxColCntMask);
- cp->net_stats.tx_packets++;
- cp->net_stats.tx_bytes += skb->len;
+ cp->dev->stats.tx_packets++;
+ cp->dev->stats.tx_bytes += skb->len;
if (netif_msg_tx_done(cp))
printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);
}
@@ -956,7 +955,7 @@ static void cp_set_rx_mode (struct net_device *dev)
static void __cp_get_stats(struct cp_private *cp)
{
/* only lower 24 bits valid; write any value to clear */
- cp->net_stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff);
+ cp->dev->stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff);
cpw32 (RxMissed, 0);
}
@@ -971,7 +970,7 @@ static struct net_device_stats *cp_get_stats(struct net_device *dev)
__cp_get_stats(cp);
spin_unlock_irqrestore(&cp->lock, flags);
- return &cp->net_stats;
+ return &dev->stats;
}
static void cp_stop_hw (struct cp_private *cp)
@@ -1142,7 +1141,7 @@ static void cp_clean_rings (struct cp_private *cp)
PCI_DMA_TODEVICE);
if (le32_to_cpu(desc->opts1) & LastFrag)
dev_kfree_skb(skb);
- cp->net_stats.tx_dropped++;
+ cp->dev->stats.tx_dropped++;
}
}
@@ -1214,7 +1213,6 @@ static int cp_close (struct net_device *dev)
spin_unlock_irqrestore(&cp->lock, flags);
- synchronize_irq(dev->irq);
free_irq(dev->irq, dev);
cp_free_rings(cp);
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 53bd903d232..75317a14ad1 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -107,8 +107,8 @@
#include <linux/mii.h>
#include <linux/completion.h>
#include <linux/crc32.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <asm/irq.h>
#define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION
@@ -134,7 +134,7 @@
#if RTL8139_DEBUG
/* note: prints function name for you */
-# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
#else
# define DPRINTK(fmt, args...)
#endif
@@ -145,7 +145,7 @@
# define assert(expr) \
if(unlikely(!(expr))) { \
printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n", \
- #expr,__FILE__,__FUNCTION__,__LINE__); \
+ #expr, __FILE__, __func__, __LINE__); \
}
#endif
@@ -219,7 +219,7 @@ enum {
#define RTL8139B_IO_SIZE 256
#define RTL8129_CAPS HAS_MII_XCVR
-#define RTL8139_CAPS HAS_CHIP_XCVR|HAS_LNK_CHNG
+#define RTL8139_CAPS (HAS_CHIP_XCVR|HAS_LNK_CHNG)
typedef enum {
RTL8139 = 0,
@@ -574,7 +574,6 @@ struct rtl8139_private {
u32 msg_enable;
struct napi_struct napi;
struct net_device *dev;
- struct net_device_stats stats;
unsigned char *rx_ring;
unsigned int cur_rx; /* RX buf index of next pkt */
@@ -1711,7 +1710,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb(skb);
} else {
dev_kfree_skb(skb);
- tp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
return 0;
}
@@ -1762,27 +1761,27 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
if (netif_msg_tx_err(tp))
printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
dev->name, txstatus);
- tp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (txstatus & TxAborted) {
- tp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
RTL_W32 (TxConfig, TxClearAbt);
RTL_W16 (IntrStatus, TxErr);
wmb();
}
if (txstatus & TxCarrierLost)
- tp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (txstatus & TxOutOfWindow)
- tp->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
} else {
if (txstatus & TxUnderrun) {
/* Add 64 to the Tx FIFO threshold. */
if (tp->tx_flag < 0x00300000)
tp->tx_flag += 0x00020000;
- tp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
}
- tp->stats.collisions += (txstatus >> 24) & 15;
- tp->stats.tx_bytes += txstatus & 0x7ff;
- tp->stats.tx_packets++;
+ dev->stats.collisions += (txstatus >> 24) & 15;
+ dev->stats.tx_bytes += txstatus & 0x7ff;
+ dev->stats.tx_packets++;
}
dirty_tx++;
@@ -1818,7 +1817,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
if (netif_msg_rx_err (tp))
printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
dev->name, rx_status);
- tp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (!(rx_status & RxStatusOK)) {
if (rx_status & RxTooLong) {
DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
@@ -1826,11 +1825,11 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
/* A.C.: The chip hangs here. */
}
if (rx_status & (RxBadSymbol | RxBadAlign))
- tp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (rx_status & (RxRunt | RxTooLong))
- tp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (rx_status & RxCRCErr)
- tp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
} else {
tp->xstats.rx_lost_in_ring++;
}
@@ -1890,7 +1889,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
}
#if RX_BUF_IDX == 3
-static __inline__ void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
+static inline void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
u32 offset, unsigned int size)
{
u32 left = RX_BUF_LEN - offset;
@@ -1913,9 +1912,9 @@ static void rtl8139_isr_ack(struct rtl8139_private *tp)
/* Clear out errors and receive interrupts */
if (likely(status != 0)) {
if (unlikely(status & (RxFIFOOver | RxOverflow))) {
- tp->stats.rx_errors++;
+ tp->dev->stats.rx_errors++;
if (status & RxFIFOOver)
- tp->stats.rx_fifo_errors++;
+ tp->dev->stats.rx_fifo_errors++;
}
RTL_W16_F (IntrStatus, RxAckBits);
}
@@ -2016,8 +2015,8 @@ no_early_rx:
skb->protocol = eth_type_trans (skb, dev);
dev->last_rx = jiffies;
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_size;
+ dev->stats.rx_packets++;
netif_receive_skb (skb);
} else {
@@ -2025,7 +2024,7 @@ no_early_rx:
printk (KERN_WARNING
"%s: Memory squeeze, dropping packet.\n",
dev->name);
- tp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
received++;
@@ -2072,7 +2071,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
assert (ioaddr != NULL);
/* Update the error count. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
if ((status & RxUnderrun) && link_changed &&
@@ -2082,12 +2081,12 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
}
if (status & (RxUnderrun | RxErr))
- tp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (status & PCSTimeout)
- tp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (status & RxUnderrun)
- tp->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
if (status & PCIErr) {
u16 pci_cmd_status;
pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
@@ -2227,12 +2226,11 @@ static int rtl8139_close (struct net_device *dev)
RTL_W16 (IntrMask, 0);
/* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
- synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
rtl8139_tx_clear (tp);
@@ -2472,12 +2470,12 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
if (netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
- return &tp->stats;
+ return &dev->stats;
}
/* Set or clear the multicast filter for this adaptor.
@@ -2561,7 +2559,7 @@ static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
RTL_W8 (ChipCmd, 0);
/* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 04ddec0f4c6..8e209f5e7c1 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -30,8 +30,10 @@ extern int ei_debug;
#ifdef CONFIG_NET_POLL_CONTROLLER
extern void ei_poll(struct net_device *dev);
+extern void eip_poll(struct net_device *dev);
#endif
+/* Without I/O delay - non ISA or later chips */
extern void NS8390_init(struct net_device *dev, int startp);
extern int ei_open(struct net_device *dev);
extern int ei_close(struct net_device *dev);
@@ -42,6 +44,17 @@ static inline struct net_device *alloc_ei_netdev(void)
return __alloc_ei_netdev(0);
}
+/* With I/O delay form */
+extern void NS8390p_init(struct net_device *dev, int startp);
+extern int eip_open(struct net_device *dev);
+extern int eip_close(struct net_device *dev);
+extern irqreturn_t eip_interrupt(int irq, void *dev_id);
+extern struct net_device *__alloc_eip_netdev(int size);
+static inline struct net_device *alloc_eip_netdev(void)
+{
+ return __alloc_eip_netdev(0);
+}
+
/* You have one of these per-board */
struct ei_device {
const char *name;
@@ -69,7 +82,6 @@ struct ei_device {
unsigned char reg0; /* Register '0' in a WD8013 */
unsigned char reg5; /* Register '5' in a WD8013 */
unsigned char saved_irq; /* Original dev->irq value. */
- struct net_device_stats stat; /* The new statistics table. */
u32 *reg_offset; /* Register mapping table */
spinlock_t page_lock; /* Page register locks */
unsigned long priv; /* Private field to store bus IDs etc. */
@@ -116,13 +128,14 @@ struct ei_device {
/*
* Only generate indirect loads given a machine that needs them.
* - removed AMIGA_PCMCIA from this list, handled as ISA io now
+ * - the _p for generates no delay by default 8390p.c overrides this.
*/
#ifndef ei_inb
#define ei_inb(_p) inb(_p)
#define ei_outb(_v,_p) outb(_v,_p)
-#define ei_inb_p(_p) inb_p(_p)
-#define ei_outb_p(_v,_p) outb_p(_v,_p)
+#define ei_inb_p(_p) inb(_p)
+#define ei_outb_p(_v,_p) outb(_v,_p)
#endif
#ifndef EI_SHIFT
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
new file mode 100644
index 00000000000..71f19884c4b
--- /dev/null
+++ b/drivers/net/8390p.c
@@ -0,0 +1,66 @@
+/* 8390 core for ISA devices needing bus delays */
+
+static const char version[] =
+ "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+
+#define ei_inb(_p) inb(_p)
+#define ei_outb(_v,_p) outb(_v,_p)
+#define ei_inb_p(_p) inb_p(_p)
+#define ei_outb_p(_v,_p) outb_p(_v,_p)
+
+#include "lib8390.c"
+
+int eip_open(struct net_device *dev)
+{
+ return __ei_open(dev);
+}
+
+int eip_close(struct net_device *dev)
+{
+ return __ei_close(dev);
+}
+
+irqreturn_t eip_interrupt(int irq, void *dev_id)
+{
+ return __ei_interrupt(irq, dev_id);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void eip_poll(struct net_device *dev)
+{
+ __ei_poll(dev);
+}
+#endif
+
+struct net_device *__alloc_eip_netdev(int size)
+{
+ return ____alloc_ei_netdev(size);
+}
+
+void NS8390p_init(struct net_device *dev, int startp)
+{
+ return __NS8390_init(dev, startp);
+}
+
+EXPORT_SYMBOL(eip_open);
+EXPORT_SYMBOL(eip_close);
+EXPORT_SYMBOL(eip_interrupt);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+EXPORT_SYMBOL(eip_poll);
+#endif
+EXPORT_SYMBOL(NS8390p_init);
+EXPORT_SYMBOL(__alloc_eip_netdev);
+
+#if defined(MODULE)
+
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{
+}
+
+#endif /* MODULE */
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2683ee32fc1..3e5e64c33e1 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -26,14 +26,6 @@ menuconfig NETDEVICES
# that for each of the symbols.
if NETDEVICES
-config NETDEVICES_MULTIQUEUE
- bool "Netdevice multiple hardware queue support"
- ---help---
- Say Y here if you want to allow the network stack to use multiple
- hardware TX queues on an ethernet device.
-
- Most people will say N here.
-
config IFB
tristate "Intermediate Functional Block support"
depends on NET_CLS_ACT
@@ -333,15 +325,6 @@ config APNE
To compile this driver as a module, choose M here: the module
will be called apne.
-config APOLLO_ELPLUS
- tristate "Apollo 3c505 support"
- depends on APOLLO
- help
- Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card.
- If you don't have one made for Apollos, you can use one from a PC,
- except that your Apollo won't be able to boot from it (because the
- code in the ROM will be for a PC).
-
config MAC8390
bool "Macintosh NS 8390 based ethernet cards"
depends on MAC
@@ -524,6 +507,18 @@ config STNIC
If unsure, say N.
+config SH_ETH
+ tristate "Renesas SuperH Ethernet support"
+ depends on SUPERH && \
+ (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712)
+ select CRC32
+ select MII
+ select MDIO_BITBANG
+ select PHYLIB
+ help
+ Renesas SuperH Ethernet device driver.
+ This driver support SH7710 and SH7712.
+
config SUNLANCE
tristate "Sun LANCE support"
depends on SBUS
@@ -926,6 +921,23 @@ config DM9000
To compile this driver as a module, choose M here. The module
will be called dm9000.
+config DM9000_DEBUGLEVEL
+ int "DM9000 maximum debug level"
+ depends on DM9000
+ default 4
+ help
+ The maximum level of debugging code compiled into the DM9000
+ driver.
+
+config DM9000_FORCE_SIMPLE_PHY_POLL
+ bool "Force simple NSR based PHY polling"
+ depends on DM9000
+ ---help---
+ This configuration forces the DM9000 to use the NSR's LinkStatus
+ bit to determine if the link is up or down instead of the more
+ costly MII PHY reads. Note, this will not work if the chip is
+ operating with an external PHY.
+
config ENC28J60
tristate "ENC28J60 support"
depends on EXPERIMENTAL && SPI && NET_ETHERNET
@@ -943,19 +955,11 @@ config ENC28J60_WRITEVERIFY
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
-config DM9000_DEBUGLEVEL
- int "DM9000 maximum debug level"
- depends on DM9000
- default 4
- help
- The maximum level of debugging code compiled into the DM9000
- driver.
-
config SMC911X
tristate "SMSC LAN911[5678] support"
select CRC32
select MII
- depends on ARCH_PXA || SH_MAGIC_PANEL_R2
+ depends on ARCH_PXA || SUPERH
help
This is a driver for SMSC's LAN911x series of Ethernet chipsets
including the new LAN9115, LAN9116, LAN9117, and LAN9118.
@@ -1243,7 +1247,6 @@ config IBMVETH
To compile this driver as a module, choose M here. The module will
be called ibmveth.
-source "drivers/net/ibm_emac/Kconfig"
source "drivers/net/ibm_newemac/Kconfig"
config NET_PCI
@@ -1286,20 +1289,6 @@ config AMD8111_ETH
To compile this driver as a module, choose M here. The module
will be called amd8111e.
-config AMD8111E_NAPI
- bool "Use RX polling (NAPI)"
- depends on AMD8111_ETH
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card. It is
- still somewhat experimental and thus not yet enabled by default.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
- If in doubt, say N.
-
config ADAPTEC_STARFIRE
tristate "Adaptec Starfire/DuraLAN support"
depends on NET_PCI && PCI
@@ -1314,20 +1303,6 @@ config ADAPTEC_STARFIRE
To compile this driver as a module, choose M here: the module
will be called starfire. This is recommended.
-config ADAPTEC_STARFIRE_NAPI
- bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
- depends on ADAPTEC_STARFIRE && EXPERIMENTAL
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card. It is
- still somewhat experimental and thus not yet enabled by default.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
- If in doubt, say N.
-
config AC3200
tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
@@ -1670,7 +1645,7 @@ config SUNDANCE_MMIO
config TLAN
tristate "TI ThunderLAN support"
- depends on NET_PCI && (PCI || EISA) && !64BIT
+ depends on NET_PCI && (PCI || EISA)
---help---
If you have a PCI Ethernet network card based on the ThunderLAN chip
which is supported by this driver, say Y and read the
@@ -1710,26 +1685,6 @@ config VIA_RHINE_MMIO
If unsure, say Y.
-config VIA_RHINE_NAPI
- bool "Use Rx Polling (NAPI)"
- depends on VIA_RHINE
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
-config LAN_SAA9730
- bool "Philips SAA9730 Ethernet support"
- depends on NET_PCI && PCI && MIPS_ATLAS
- help
- The SAA9730 is a combined multimedia and peripheral controller used
- in thin clients, Internet access terminals, and diskless
- workstations.
- See <http://www.semiconductors.philips.com/pip/SAA9730_flyer_1>.
-
config SC92031
tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
depends on NET_PCI && PCI && EXPERIMENTAL
@@ -2013,9 +1968,6 @@ config E1000E
To compile this driver as a module, choose M here. The module
will be called e1000e.
-config E1000E_ENABLED
- def_bool E1000E != n
-
config IP1000
tristate "IP1000 Gigabit Ethernet support"
depends on PCI && EXPERIMENTAL
@@ -2047,6 +1999,15 @@ config IGB
To compile this driver as a module, choose M here. The module
will be called igb.
+config IGB_LRO
+ bool "Use software LRO"
+ depends on IGB && INET
+ select INET_LRO
+ ---help---
+ Say Y here if you want to use large receive offload.
+
+ If in doubt, say N.
+
source "drivers/net/ixp2000/Kconfig"
config MYRI_SBUS
@@ -2104,27 +2065,13 @@ config R8169
To compile this driver as a module, choose M here: the module
will be called r8169. This is recommended.
-config R8169_NAPI
- bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
- depends on R8169 && EXPERIMENTAL
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card. It is
- still somewhat experimental and thus not yet enabled by default.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
- If in doubt, say N.
-
config R8169_VLAN
bool "VLAN support"
depends on R8169 && VLAN_8021Q
---help---
Say Y here for the r8169 driver to support the functions required
by the kernel 802.1Q code.
-
+
If in doubt, say Y.
config SB1250_MAC
@@ -2227,6 +2174,7 @@ config VIA_VELOCITY
config TIGON3
tristate "Broadcom Tigon3 support"
depends on PCI
+ select PHYLIB
help
This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
@@ -2282,6 +2230,19 @@ config GELIC_WIRELESS
the driver automatically distinguishes the models, you can
safely enable this option even if you have a wireless-less model.
+config GELIC_WIRELESS_OLD_PSK_INTERFACE
+ bool "PS3 Wireless private PSK interface (OBSOLETE)"
+ depends on GELIC_WIRELESS
+ help
+ This option retains the obsolete private interface to pass
+ the PSK from user space programs to the driver. The PSK
+ stands for 'Pre Shared Key' and is used for WPA[2]-PSK
+ (WPA-Personal) environment.
+ If WPA[2]-PSK is used and you need to use old programs that
+ support only this old interface, say Y. Otherwise N.
+
+ If unsure, say N.
+
config GIANFAR
tristate "Gianfar Ethernet"
depends on FSL_SOC
@@ -2291,10 +2252,6 @@ config GIANFAR
This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
and MPC86xx family of chips, and the FEC on the 8540.
-config GFAR_NAPI
- bool "Use Rx Polling (NAPI)"
- depends on GIANFAR
-
config UCC_GETH
tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE
@@ -2303,10 +2260,6 @@ config UCC_GETH
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
which is available on some Freescale SOCs.
-config UGETH_NAPI
- bool "Use Rx Polling (NAPI)"
- depends on UCC_GETH
-
config UGETH_MAGIC_PACKET
bool "Magic Packet detection support"
depends on UCC_GETH
@@ -2396,18 +2349,11 @@ config CHELSIO_T1_1G
Enables support for Chelsio's gigabit Ethernet PCI cards. If you
are using only 10G cards say 'N' here.
-config CHELSIO_T1_NAPI
- bool "Use Rx Polling (NAPI)"
- depends on CHELSIO_T1
- default y
- help
- NAPI is a driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card.
-
config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
- depends on PCI
+ depends on PCI && INET
select FW_LOADER
+ select INET_LRO
help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
@@ -2435,7 +2381,8 @@ config EHEA
config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
- depends on PCI
+ depends on PCI && INET
+ select INET_LRO
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2473,20 +2420,6 @@ config IXGB
To compile this driver as a module, choose M here. The module
will be called ixgb.
-config IXGB_NAPI
- bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
- depends on IXGB && EXPERIMENTAL
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card. It is
- still somewhat experimental and thus not yet enabled by default.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
- If in doubt, say N.
-
config S2IO
tristate "S2IO 10Gbe XFrame NIC"
depends on PCI
@@ -2495,20 +2428,6 @@ config S2IO
More specific information on configuring the driver is in
<file:Documentation/networking/s2io.txt>.
-config S2IO_NAPI
- bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
- depends on S2IO && EXPERIMENTAL
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card. It is
- still somewhat experimental and thus not yet enabled by default.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
- If in doubt, say N.
-
config MYRI10GE
tristate "Myricom Myri-10G Ethernet support"
depends on PCI && INET
@@ -2573,6 +2492,7 @@ config BNX2X
tristate "Broadcom NetXtremeII 10Gb support"
depends on PCI
select ZLIB_INFLATE
+ select LIBCRC32C
help
This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9010e58da0f..4b17a9ab786 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -4,7 +4,6 @@
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
-obj-$(CONFIG_IBM_EMAC) += ibm_emac/
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
obj-$(CONFIG_IGB) += igb/
obj-$(CONFIG_IXGBE) += ixgbe/
@@ -67,6 +66,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BNX2) += bnx2.o
obj-$(CONFIG_BNX2X) += bnx2x.o
+bnx2x-objs := bnx2x_main.o bnx2x_link.o
spidernet-y += spider_net.o spider_net_ethtool.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
@@ -80,6 +80,7 @@ obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
obj-$(CONFIG_RIONET) += rionet.o
+obj-$(CONFIG_SH_ETH) += sh_eth.o
#
# end link order section
@@ -105,11 +106,11 @@ ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
endif
obj-$(CONFIG_68360_ENET) += 68360enet.o
obj-$(CONFIG_WD80x3) += wd.o 8390.o
-obj-$(CONFIG_EL2) += 3c503.o 8390.o
-obj-$(CONFIG_NE2000) += ne.o 8390.o
-obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o
-obj-$(CONFIG_HPLAN) += hp.o 8390.o
-obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o
+obj-$(CONFIG_EL2) += 3c503.o 8390p.o
+obj-$(CONFIG_NE2000) += ne.o 8390p.o
+obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o
+obj-$(CONFIG_HPLAN) += hp.o 8390p.o
+obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o
obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
@@ -165,7 +166,6 @@ obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
obj-$(CONFIG_8139CP) += 8139cp.o
obj-$(CONFIG_8139TOO) += 8139too.o
obj-$(CONFIG_ZNET) += znet.o
-obj-$(CONFIG_LAN_SAA9730) += saa9730.o
obj-$(CONFIG_CPMAC) += cpmac.o
obj-$(CONFIG_DEPCA) += depca.o
obj-$(CONFIG_EWRK3) += ewrk3.o
@@ -235,6 +235,7 @@ obj-$(CONFIG_USB_CATC) += usb/
obj-$(CONFIG_USB_KAWETH) += usb/
obj-$(CONFIG_USB_PEGASUS) += usb/
obj-$(CONFIG_USB_RTL8150) += usb/
+obj-$(CONFIG_USB_HSO) += usb/
obj-$(CONFIG_USB_USBNET) += usb/
obj-$(CONFIG_USB_ZD1201) += usb/
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 6c5719ae8cc..9c0837435b6 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -475,16 +475,12 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id)
return IRQ_HANDLED;
}
-struct net_device *last_dev;
-
static int lance_open (struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
int ret;
- last_dev = dev;
-
/* Stop the Lance */
ll->rap = LE_CSR0;
ll->rdp = LE_C0_STOP;
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 6c192650d34..e4483de84e7 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -1457,11 +1457,6 @@ static int __devinit ace_init(struct net_device *dev)
ace_set_txprd(regs, ap, 0);
writel(0, &regs->RxRetCsm);
- /*
- * Zero the stats before starting the interface
- */
- memset(&ap->stats, 0, sizeof(ap->stats));
-
/*
* Enable DMA engine now.
* If we do this sooner, Mckinley box pukes.
@@ -2041,8 +2036,8 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
netif_rx(skb);
dev->last_rx = jiffies;
- ap->stats.rx_packets++;
- ap->stats.rx_bytes += retdesc->size;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += retdesc->size;
idx = (idx + 1) % RX_RETURN_RING_ENTRIES;
}
@@ -2090,8 +2085,8 @@ static inline void ace_tx_int(struct net_device *dev,
}
if (skb) {
- ap->stats.tx_packets++;
- ap->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev_kfree_skb_irq(skb);
info->skb = NULL;
}
@@ -2863,11 +2858,11 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev)
struct ace_mac_stats __iomem *mac_stats =
(struct ace_mac_stats __iomem *)ap->regs->Stats;
- ap->stats.rx_missed_errors = readl(&mac_stats->drop_space);
- ap->stats.multicast = readl(&mac_stats->kept_mc);
- ap->stats.collisions = readl(&mac_stats->coll);
+ dev->stats.rx_missed_errors = readl(&mac_stats->drop_space);
+ dev->stats.multicast = readl(&mac_stats->kept_mc);
+ dev->stats.collisions = readl(&mac_stats->coll);
- return &ap->stats;
+ return &dev->stats;
}
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
index 60ed1837fa8..4487f32759a 100644
--- a/drivers/net/acenic.h
+++ b/drivers/net/acenic.h
@@ -693,7 +693,6 @@ struct ace_private
__attribute__ ((aligned (SMP_CACHE_BYTES)));
u32 last_tx, last_std_rx, last_mini_rx;
#endif
- struct net_device_stats stats;
int pci_using_dac;
};
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 85f7276aaba..c54967f7942 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -101,9 +101,9 @@ Revision History:
#include "amd8111e.h"
#define MODULE_NAME "amd8111e"
-#define MODULE_VERS "3.0.6"
+#define MODULE_VERS "3.0.7"
MODULE_AUTHOR("Advanced Micro Devices, Inc.");
-MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.6");
+MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "MODULE_VERS);
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
module_param_array(speed_duplex, int, NULL, 0);
@@ -671,11 +671,7 @@ This is the receive indication function for packets with vlan tag.
*/
static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag)
{
-#ifdef CONFIG_AMD8111E_NAPI
return vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag);
-#else
- return vlan_hwaccel_rx(skb, lp->vlgrp, vlan_tag);
-#endif /* CONFIG_AMD8111E_NAPI */
}
#endif
@@ -722,7 +718,6 @@ static int amd8111e_tx(struct net_device *dev)
return 0;
}
-#ifdef CONFIG_AMD8111E_NAPI
/* This function handles the driver receive operation in polling mode */
static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
{
@@ -734,7 +729,6 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
int min_pkt_len, status;
unsigned int intr0;
int num_rx_pkt = 0;
- /*int max_rx_pkt = NUM_RX_BUFFERS;*/
short pkt_len;
#if AMD8111E_VLAN_TAG_USED
short vtag;
@@ -850,108 +844,6 @@ rx_not_empty:
return num_rx_pkt;
}
-#else
-/*
-This function will check the ownership of receive buffers and descriptors. It will indicate to kernel up to half the number of maximum receive buffers in the descriptor ring, in a single receive interrupt. It will also replenish the descriptors with new skbs.
-*/
-static int amd8111e_rx(struct net_device *dev)
-{
- struct amd8111e_priv *lp = netdev_priv(dev);
- struct sk_buff *skb,*new_skb;
- int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK;
- int min_pkt_len, status;
- int num_rx_pkt = 0;
- int max_rx_pkt = NUM_RX_BUFFERS;
- short pkt_len;
-#if AMD8111E_VLAN_TAG_USED
- short vtag;
-#endif
-
- /* If we own the next entry, it's a new packet. Send it up. */
- while(++num_rx_pkt <= max_rx_pkt){
- status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
- if(status & OWN_BIT)
- return 0;
-
- /* check if err summary bit is set */
- if(status & ERR_BIT){
- /*
- * There is a tricky error noted by John Murphy,
- * <murf@perftech.com> to Russ Nelson: Even with full-sized
- * buffers it's possible for a jabber packet to use two
- * buffers, with only the last correctly noting the error. */
- /* reseting flags */
- lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
- goto err_next_pkt;
- }
- /* check for STP and ENP */
- if(!((status & STP_BIT) && (status & ENP_BIT))){
- /* reseting flags */
- lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
- goto err_next_pkt;
- }
- pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4;
-
-#if AMD8111E_VLAN_TAG_USED
- vtag = status & TT_MASK;
- /*MAC will strip vlan tag*/
- if(lp->vlgrp != NULL && vtag !=0)
- min_pkt_len =MIN_PKT_LEN - 4;
- else
-#endif
- min_pkt_len =MIN_PKT_LEN;
-
- if (pkt_len < min_pkt_len) {
- lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
- lp->drv_rx_errors++;
- goto err_next_pkt;
- }
- if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){
- /* if allocation fail,
- ignore that pkt and go to next one */
- lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
- lp->drv_rx_errors++;
- goto err_next_pkt;
- }
-
- skb_reserve(new_skb, 2);
- skb = lp->rx_skbuff[rx_index];
- pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index],
- lp->rx_buff_len-2, PCI_DMA_FROMDEVICE);
- skb_put(skb, pkt_len);
- lp->rx_skbuff[rx_index] = new_skb;
- lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev,
- new_skb->data, lp->rx_buff_len-2,PCI_DMA_FROMDEVICE);
-
- skb->protocol = eth_type_trans(skb, dev);
-
-#if AMD8111E_VLAN_TAG_USED
- if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){
- amd8111e_vlan_rx(lp, skb,
- le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info));
- } else
-#endif
-
- netif_rx (skb);
- /*COAL update rx coalescing parameters*/
- lp->coal_conf.rx_packets++;
- lp->coal_conf.rx_bytes += pkt_len;
-
- dev->last_rx = jiffies;
-
-err_next_pkt:
- lp->rx_ring[rx_index].buff_phy_addr
- = cpu_to_le32(lp->rx_dma_addr[rx_index]);
- lp->rx_ring[rx_index].buff_count =
- cpu_to_le16(lp->rx_buff_len-2);
- wmb();
- lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT);
- rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK;
- }
-
- return 0;
-}
-#endif /* CONFIG_AMD8111E_NAPI */
/*
This function will indicate the link status to the kernel.
*/
@@ -1280,29 +1172,22 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
writel(intr0, mmio + INT0);
/* Check if Receive Interrupt has occurred. */
-#ifdef CONFIG_AMD8111E_NAPI
- if(intr0 & RINT0){
- if(netif_rx_schedule_prep(dev, &lp->napi)){
+ if (intr0 & RINT0) {
+ if (netif_rx_schedule_prep(dev, &lp->napi)) {
/* Disable receive interupts */
writel(RINTEN0, mmio + INTEN0);
/* Schedule a polling routine */
__netif_rx_schedule(dev, &lp->napi);
- }
- else if (intren0 & RINTEN0) {
+ } else if (intren0 & RINTEN0) {
printk("************Driver bug! \
interrupt while in poll\n");
/* Fix by disable receive interrupts */
writel(RINTEN0, mmio + INTEN0);
}
}
-#else
- if(intr0 & RINT0){
- amd8111e_rx(dev);
- writel(VAL2 | RDMD0, mmio + CMD0);
- }
-#endif /* CONFIG_AMD8111E_NAPI */
+
/* Check if Transmit Interrupt has occurred. */
- if(intr0 & TINT0)
+ if (intr0 & TINT0)
amd8111e_tx(dev);
/* Check if Link Change Interrupt has occurred. */
@@ -1340,9 +1225,7 @@ static int amd8111e_close(struct net_device * dev)
struct amd8111e_priv *lp = netdev_priv(dev);
netif_stop_queue(dev);
-#ifdef CONFIG_AMD8111E_NAPI
napi_disable(&lp->napi);
-#endif
spin_lock_irq(&lp->lock);
@@ -1374,9 +1257,7 @@ static int amd8111e_open(struct net_device * dev )
dev->name, dev))
return -EAGAIN;
-#ifdef CONFIG_AMD8111E_NAPI
napi_enable(&lp->napi);
-#endif
spin_lock_irq(&lp->lock);
@@ -1384,9 +1265,7 @@ static int amd8111e_open(struct net_device * dev )
if(amd8111e_restart(dev)){
spin_unlock_irq(&lp->lock);
-#ifdef CONFIG_AMD8111E_NAPI
napi_disable(&lp->napi);
-#endif
if (dev->irq)
free_irq(dev->irq, dev);
return -ENOMEM;
@@ -2036,9 +1915,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
dev->irq =pdev->irq;
dev->tx_timeout = amd8111e_tx_timeout;
dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
-#ifdef CONFIG_AMD8111E_NAPI
netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32);
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = amd8111e_poll;
#endif
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 10f3a196be3..29e53eb71c7 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -98,7 +98,6 @@ struct ariadne_private {
volatile u_short *rx_buff[RX_RING_SIZE];
int cur_tx, cur_rx; /* The next free ring entry */
int dirty_tx; /* The ring entries to be free()ed. */
- struct net_device_stats stats;
char tx_full;
};
@@ -378,20 +377,19 @@ static void ariadne_init_ring(struct net_device *dev)
static int ariadne_close(struct net_device *dev)
{
- struct ariadne_private *priv = netdev_priv(dev);
volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
netif_stop_queue(dev);
lance->RAP = CSR112; /* Missed Frame Count */
- priv->stats.rx_missed_errors = swapw(lance->RDP);
+ dev->stats.rx_missed_errors = swapw(lance->RDP);
lance->RAP = CSR0; /* PCnet-ISA Controller Status */
if (ariadne_debug > 1) {
printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
dev->name, lance->RDP);
printk(KERN_DEBUG "%s: %lu packets missed\n", dev->name,
- priv->stats.rx_missed_errors);
+ dev->stats.rx_missed_errors);
}
/* We stop the LANCE here -- it occasionally polls memory if we don't. */
@@ -502,16 +500,16 @@ static irqreturn_t ariadne_interrupt(int irq, void *data)
if (status & TF_ERR) {
/* There was an major error, log it. */
int err_status = priv->tx_ring[entry]->TMD3;
- priv->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (err_status & EF_RTRY)
- priv->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
if (err_status & EF_LCAR)
- priv->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (err_status & EF_LCOL)
- priv->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
if (err_status & EF_UFLO) {
/* Ackk! On FIFO errors the Tx unit is turned off! */
- priv->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
/* Remove this verbosity later! */
printk(KERN_ERR "%s: Tx FIFO error! Status %4.4x.\n",
dev->name, csr0);
@@ -520,8 +518,8 @@ static irqreturn_t ariadne_interrupt(int irq, void *data)
}
} else {
if (status & (TF_MORE|TF_ONE))
- priv->stats.collisions++;
- priv->stats.tx_packets++;
+ dev->stats.collisions++;
+ dev->stats.tx_packets++;
}
dirty_tx++;
}
@@ -547,11 +545,11 @@ static irqreturn_t ariadne_interrupt(int irq, void *data)
/* Log misc errors. */
if (csr0 & BABL) {
handled = 1;
- priv->stats.tx_errors++; /* Tx babble. */
+ dev->stats.tx_errors++; /* Tx babble. */
}
if (csr0 & MISS) {
handled = 1;
- priv->stats.rx_errors++; /* Missed a Rx frame. */
+ dev->stats.rx_errors++; /* Missed a Rx frame. */
}
if (csr0 & MERR) {
handled = 1;
@@ -672,7 +670,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv->cur_tx -= TX_RING_SIZE;
priv->dirty_tx -= TX_RING_SIZE;
}
- priv->stats.tx_bytes += len;
+ dev->stats.tx_bytes += len;
/* Trigger an immediate send poll. */
lance->RAP = CSR0; /* PCnet-ISA Controller Status */
@@ -707,15 +705,15 @@ static int ariadne_rx(struct net_device *dev)
buffers, with only the last correctly noting the error. */
if (status & RF_ENP)
/* Only count a general error at the end of a packet.*/
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (status & RF_FRAM)
- priv->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & RF_OFLO)
- priv->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
if (status & RF_CRC)
- priv->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if (status & RF_BUFF)
- priv->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
priv->rx_ring[entry]->RMD1 &= 0xff00|RF_STP|RF_ENP;
} else {
/* Malloc up new buffer, compatible with net-3. */
@@ -731,7 +729,7 @@ static int ariadne_rx(struct net_device *dev)
break;
if (i > RX_RING_SIZE-2) {
- priv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->rx_ring[entry]->RMD1 |= RF_OWN;
priv->cur_rx++;
}
@@ -764,8 +762,8 @@ static int ariadne_rx(struct net_device *dev)
netif_rx(skb);
dev->last_rx = jiffies;
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
priv->rx_ring[entry]->RMD1 |= RF_OWN;
@@ -783,7 +781,6 @@ static int ariadne_rx(struct net_device *dev)
static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
{
- struct ariadne_private *priv = netdev_priv(dev);
volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
short saved_addr;
unsigned long flags;
@@ -791,11 +788,11 @@ static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
local_irq_save(flags);
saved_addr = lance->RAP;
lance->RAP = CSR112; /* Missed Frame Count */
- priv->stats.rx_missed_errors = swapw(lance->RDP);
+ dev->stats.rx_missed_errors = swapw(lance->RDP);
lance->RAP = saved_addr;
local_irq_restore(flags);
- return &priv->stats;
+ return &dev->stats;
}
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index c617b64c288..9b777d9433c 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -522,7 +522,6 @@ static int eth_poll(struct napi_struct *napi, int budget)
#endif
if ((n = queue_get_desc(rxq, port, 0)) < 0) {
- received = 0; /* No packet received */
#if DEBUG_RX
printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
dev->name);
@@ -543,7 +542,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
printk(KERN_DEBUG "%s: eth_poll all done\n",
dev->name);
#endif
- return 0; /* all work done */
+ return received; /* all work done */
}
desc = rx_desc_ptr(port, n);
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 4cceaac8863..0860cc280b0 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -243,7 +243,7 @@ struct lance_private {
/* Possible memory/IO addresses for probing */
-struct lance_addr {
+static struct lance_addr {
unsigned long memaddr;
unsigned long ioaddr;
int slow_flag;
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 3c798ae5c34..3e22e7817bc 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1859,7 +1859,8 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
- skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(adapter->netdev,
+ adapter->rx_buffer_len + NET_IP_ALIGN);
if (unlikely(!skb)) {
/* Better luck next round */
adapter->net_stats.rx_dropped++;
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 7023d77bf38..3ab61e40e86 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -912,7 +912,7 @@ au1000_adjust_link(struct net_device *dev)
// link state changed
if (phydev->link) // link went up
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
else { // link went down
aup->old_speed = 0;
aup->old_duplex = -1;
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 59dce6aa086..c3bda5ce67c 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -148,9 +148,9 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
unsigned long offset,
enum dma_data_direction dir)
{
- dma_sync_single_range_for_device(sdev->dma_dev, dma_base,
- offset & dma_desc_align_mask,
- dma_desc_sync_size, dir);
+ ssb_dma_sync_single_range_for_device(sdev, dma_base,
+ offset & dma_desc_align_mask,
+ dma_desc_sync_size, dir);
}
static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
@@ -158,9 +158,9 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
unsigned long offset,
enum dma_data_direction dir)
{
- dma_sync_single_range_for_cpu(sdev->dma_dev, dma_base,
- offset & dma_desc_align_mask,
- dma_desc_sync_size, dir);
+ ssb_dma_sync_single_range_for_cpu(sdev, dma_base,
+ offset & dma_desc_align_mask,
+ dma_desc_sync_size, dir);
}
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
@@ -613,10 +613,10 @@ static void b44_tx(struct b44 *bp)
BUG_ON(skb == NULL);
- dma_unmap_single(bp->sdev->dma_dev,
- rp->mapping,
- skb->len,
- DMA_TO_DEVICE);
+ ssb_dma_unmap_single(bp->sdev,
+ rp->mapping,
+ skb->len,
+ DMA_TO_DEVICE);
rp->skb = NULL;
dev_kfree_skb_irq(skb);
}
@@ -653,29 +653,29 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (skb == NULL)
return -ENOMEM;
- mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ mapping = ssb_dma_map_single(bp->sdev, skb->data,
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
/* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */
- if (dma_mapping_error(mapping) ||
+ if (ssb_dma_mapping_error(bp->sdev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
/* Sigh... */
- if (!dma_mapping_error(mapping))
- dma_unmap_single(bp->sdev->dma_dev, mapping,
- RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
+ if (!ssb_dma_mapping_error(bp->sdev, mapping))
+ ssb_dma_unmap_single(bp->sdev, mapping,
+ RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
if (skb == NULL)
return -ENOMEM;
- mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(mapping) ||
+ mapping = ssb_dma_map_single(bp->sdev, skb->data,
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
+ if (ssb_dma_mapping_error(bp->sdev, mapping) ||
mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
- if (!dma_mapping_error(mapping))
- dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
+ if (!ssb_dma_mapping_error(bp->sdev, mapping))
+ ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
return -ENOMEM;
}
@@ -750,9 +750,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
dest_idx * sizeof(dest_desc),
DMA_BIDIRECTIONAL);
- dma_sync_single_for_device(bp->sdev->dma_dev, le32_to_cpu(src_desc->addr),
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr),
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
}
static int b44_rx(struct b44 *bp, int budget)
@@ -772,7 +772,7 @@ static int b44_rx(struct b44 *bp, int budget)
struct rx_header *rh;
u16 len;
- dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
+ ssb_dma_sync_single_for_cpu(bp->sdev, map,
RX_PKT_BUF_SZ,
DMA_FROM_DEVICE);
rh = (struct rx_header *) skb->data;
@@ -806,8 +806,8 @@ static int b44_rx(struct b44 *bp, int budget)
skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
if (skb_size < 0)
goto drop_it;
- dma_unmap_single(bp->sdev->dma_dev, map,
- skb_size, DMA_FROM_DEVICE);
+ ssb_dma_unmap_single(bp->sdev, map,
+ skb_size, DMA_FROM_DEVICE);
/* Leave out rx_header */
skb_put(skb, len + RX_PKT_OFFSET);
skb_pull(skb, RX_PKT_OFFSET);
@@ -966,25 +966,25 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto err_out;
}
- mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
- if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
+ mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
+ if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
struct sk_buff *bounce_skb;
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
- if (!dma_mapping_error(mapping))
- dma_unmap_single(bp->sdev->dma_dev, mapping, len,
- DMA_TO_DEVICE);
+ if (!ssb_dma_mapping_error(bp->sdev, mapping))
+ ssb_dma_unmap_single(bp->sdev, mapping, len,
+ DMA_TO_DEVICE);
bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb)
goto err_out;
- mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
- len, DMA_TO_DEVICE);
- if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
- if (!dma_mapping_error(mapping))
- dma_unmap_single(bp->sdev->dma_dev, mapping,
- len, DMA_TO_DEVICE);
+ mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
+ len, DMA_TO_DEVICE);
+ if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
+ if (!ssb_dma_mapping_error(bp->sdev, mapping))
+ ssb_dma_unmap_single(bp->sdev, mapping,
+ len, DMA_TO_DEVICE);
dev_kfree_skb_any(bounce_skb);
goto err_out;
}
@@ -1082,8 +1082,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL)
continue;
- dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
dev_kfree_skb_any(rp->skb);
rp->skb = NULL;
}
@@ -1094,8 +1094,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL)
continue;
- dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
- DMA_TO_DEVICE);
+ ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(rp->skb);
rp->skb = NULL;
}
@@ -1117,14 +1117,14 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
if (bp->flags & B44_FLAG_RX_RING_HACK)
- dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_BIDIRECTIONAL);
+ ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
if (bp->flags & B44_FLAG_TX_RING_HACK)
- dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_TO_DEVICE);
+ ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
@@ -1144,25 +1144,27 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL;
if (bp->rx_ring) {
if (bp->flags & B44_FLAG_RX_RING_HACK) {
- dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_BIDIRECTIONAL);
+ ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
kfree(bp->rx_ring);
} else
- dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
- bp->rx_ring, bp->rx_ring_dma);
+ ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
+ bp->rx_ring, bp->rx_ring_dma,
+ GFP_KERNEL);
bp->rx_ring = NULL;
bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
if (bp->flags & B44_FLAG_TX_RING_HACK) {
- dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_TO_DEVICE);
+ ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
kfree(bp->tx_ring);
} else
- dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
- bp->tx_ring, bp->tx_ring_dma);
+ ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
+ bp->tx_ring, bp->tx_ring_dma,
+ GFP_KERNEL);
bp->tx_ring = NULL;
bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
@@ -1187,7 +1189,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
goto out_err;
size = DMA_TABLE_BYTES;
- bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->rx_ring_dma, gfp);
+ bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->rx_ring_dma, gfp);
if (!bp->rx_ring) {
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
@@ -1199,11 +1201,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!rx_ring)
goto out_err;
- rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
- DMA_TABLE_BYTES,
- DMA_BIDIRECTIONAL);
+ rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
- if (dma_mapping_error(rx_ring_dma) ||
+ if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
rx_ring_dma + size > DMA_30BIT_MASK) {
kfree(rx_ring);
goto out_err;
@@ -1214,9 +1216,9 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
bp->flags |= B44_FLAG_RX_RING_HACK;
}
- bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->tx_ring_dma, gfp);
+ bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp);
if (!bp->tx_ring) {
- /* Allocation may have failed due to dma_alloc_coherent
+ /* Allocation may have failed due to ssb_dma_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
than necessary... */
struct dma_desc *tx_ring;
@@ -1226,11 +1228,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!tx_ring)
goto out_err;
- tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
+ tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring,
DMA_TABLE_BYTES,
DMA_TO_DEVICE);
- if (dma_mapping_error(tx_ring_dma) ||
+ if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
tx_ring_dma + size > DMA_30BIT_MASK) {
kfree(tx_ring);
goto out_err;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 41443435ab1..a6a3da89f59 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -357,7 +357,7 @@ static void bfin_mac_adjust_link(struct net_device *dev)
if (!lp->old_link) {
new_state = 1;
lp->old_link = 1;
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
}
} else if (lp->old_link) {
new_state = 1;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 367b6d46270..5ebde67d429 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -47,6 +47,7 @@
#include <linux/prefetch.h>
#include <linux/cache.h>
#include <linux/zlib.h>
+#include <linux/log2.h>
#include "bnx2.h"
#include "bnx2_fw.h"
@@ -56,8 +57,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.7.5"
-#define DRV_MODULE_RELDATE "April 29, 2008"
+#define DRV_MODULE_VERSION "1.7.9"
+#define DRV_MODULE_RELDATE "July 18, 2008"
#define RUN_AT(x) (jiffies + (x))
@@ -68,7 +69,7 @@ static char version[] __devinitdata =
"Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
@@ -87,6 +88,7 @@ typedef enum {
BCM5708S,
BCM5709,
BCM5709S,
+ BCM5716,
} board_t;
/* indexed by board_t, above */
@@ -102,9 +104,10 @@ static struct {
{ "Broadcom NetXtreme II BCM5708 1000Base-SX" },
{ "Broadcom NetXtreme II BCM5709 1000Base-T" },
{ "Broadcom NetXtreme II BCM5709 1000Base-SX" },
+ { "Broadcom NetXtreme II BCM5716 1000Base-T" },
};
-static struct pci_device_id bnx2_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
PCI_VENDOR_ID_HP, 0x3101, 0, 0, NC370T },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
@@ -123,6 +126,8 @@ static struct pci_device_id bnx2_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709 },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709S,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709S },
+ { PCI_VENDOR_ID_BROADCOM, 0x163b,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
{ 0, }
};
@@ -226,7 +231,7 @@ static struct flash_spec flash_5709 = {
MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
-static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_napi *bnapi)
+static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
{
u32 diff;
@@ -235,7 +240,7 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_napi *bnapi)
/* The ring uses 256 indices for 255 entries, one of them
* needs to be skipped.
*/
- diff = bp->tx_prod - bnapi->tx_cons;
+ diff = txr->tx_prod - txr->tx_cons;
if (unlikely(diff >= TX_DESC_CNT)) {
diff &= 0xffff;
if (diff == TX_DESC_CNT)
@@ -289,7 +294,6 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
REG_WR(bp, BNX2_CTX_CTX_CTRL,
offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
for (i = 0; i < 5; i++) {
- u32 val;
val = REG_RD(bp, BNX2_CTX_CTX_CTRL);
if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0)
break;
@@ -488,7 +492,7 @@ bnx2_netif_start(struct bnx2 *bp)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
- netif_wake_queue(bp->dev);
+ netif_tx_wake_all_queues(bp->dev);
bnx2_napi_enable(bp);
bnx2_enable_int(bp);
}
@@ -496,99 +500,162 @@ bnx2_netif_start(struct bnx2 *bp)
}
static void
-bnx2_free_mem(struct bnx2 *bp)
+bnx2_free_tx_mem(struct bnx2 *bp)
{
int i;
- for (i = 0; i < bp->ctx_pages; i++) {
- if (bp->ctx_blk[i]) {
- pci_free_consistent(bp->pdev, BCM_PAGE_SIZE,
- bp->ctx_blk[i],
- bp->ctx_blk_mapping[i]);
- bp->ctx_blk[i] = NULL;
+ for (i = 0; i < bp->num_tx_rings; i++) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
+
+ if (txr->tx_desc_ring) {
+ pci_free_consistent(bp->pdev, TXBD_RING_SIZE,
+ txr->tx_desc_ring,
+ txr->tx_desc_mapping);
+ txr->tx_desc_ring = NULL;
}
+ kfree(txr->tx_buf_ring);
+ txr->tx_buf_ring = NULL;
}
- if (bp->status_blk) {
- pci_free_consistent(bp->pdev, bp->status_stats_size,
- bp->status_blk, bp->status_blk_mapping);
- bp->status_blk = NULL;
- bp->stats_blk = NULL;
+}
+
+static void
+bnx2_free_rx_mem(struct bnx2 *bp)
+{
+ int i;
+
+ for (i = 0; i < bp->num_rx_rings; i++) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
+ int j;
+
+ for (j = 0; j < bp->rx_max_ring; j++) {
+ if (rxr->rx_desc_ring[j])
+ pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
+ rxr->rx_desc_ring[j],
+ rxr->rx_desc_mapping[j]);
+ rxr->rx_desc_ring[j] = NULL;
+ }
+ if (rxr->rx_buf_ring)
+ vfree(rxr->rx_buf_ring);
+ rxr->rx_buf_ring = NULL;
+
+ for (j = 0; j < bp->rx_max_pg_ring; j++) {
+ if (rxr->rx_pg_desc_ring[j])
+ pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
+ rxr->rx_pg_desc_ring[i],
+ rxr->rx_pg_desc_mapping[i]);
+ rxr->rx_pg_desc_ring[i] = NULL;
+ }
+ if (rxr->rx_pg_ring)
+ vfree(rxr->rx_pg_ring);
+ rxr->rx_pg_ring = NULL;
}
- if (bp->tx_desc_ring) {
- pci_free_consistent(bp->pdev, TXBD_RING_SIZE,
- bp->tx_desc_ring, bp->tx_desc_mapping);
- bp->tx_desc_ring = NULL;
- }
- kfree(bp->tx_buf_ring);
- bp->tx_buf_ring = NULL;
- for (i = 0; i < bp->rx_max_ring; i++) {
- if (bp->rx_desc_ring[i])
- pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
- bp->rx_desc_ring[i],
- bp->rx_desc_mapping[i]);
- bp->rx_desc_ring[i] = NULL;
- }
- vfree(bp->rx_buf_ring);
- bp->rx_buf_ring = NULL;
- for (i = 0; i < bp->rx_max_pg_ring; i++) {
- if (bp->rx_pg_desc_ring[i])
- pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
- bp->rx_pg_desc_ring[i],
- bp->rx_pg_desc_mapping[i]);
- bp->rx_pg_desc_ring[i] = NULL;
- }
- if (bp->rx_pg_ring)
- vfree(bp->rx_pg_ring);
- bp->rx_pg_ring = NULL;
}
static int
-bnx2_alloc_mem(struct bnx2 *bp)
+bnx2_alloc_tx_mem(struct bnx2 *bp)
{
- int i, status_blk_size;
+ int i;
- bp->tx_buf_ring = kzalloc(SW_TXBD_RING_SIZE, GFP_KERNEL);
- if (bp->tx_buf_ring == NULL)
- return -ENOMEM;
+ for (i = 0; i < bp->num_tx_rings; i++) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
- bp->tx_desc_ring = pci_alloc_consistent(bp->pdev, TXBD_RING_SIZE,
- &bp->tx_desc_mapping);
- if (bp->tx_desc_ring == NULL)
- goto alloc_mem_err;
+ txr->tx_buf_ring = kzalloc(SW_TXBD_RING_SIZE, GFP_KERNEL);
+ if (txr->tx_buf_ring == NULL)
+ return -ENOMEM;
- bp->rx_buf_ring = vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
- if (bp->rx_buf_ring == NULL)
- goto alloc_mem_err;
+ txr->tx_desc_ring =
+ pci_alloc_consistent(bp->pdev, TXBD_RING_SIZE,
+ &txr->tx_desc_mapping);
+ if (txr->tx_desc_ring == NULL)
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int
+bnx2_alloc_rx_mem(struct bnx2 *bp)
+{
+ int i;
+
+ for (i = 0; i < bp->num_rx_rings; i++) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
+ int j;
- memset(bp->rx_buf_ring, 0, SW_RXBD_RING_SIZE * bp->rx_max_ring);
+ rxr->rx_buf_ring =
+ vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
+ if (rxr->rx_buf_ring == NULL)
+ return -ENOMEM;
- for (i = 0; i < bp->rx_max_ring; i++) {
- bp->rx_desc_ring[i] =
- pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
- &bp->rx_desc_mapping[i]);
- if (bp->rx_desc_ring[i] == NULL)
- goto alloc_mem_err;
+ memset(rxr->rx_buf_ring, 0,
+ SW_RXBD_RING_SIZE * bp->rx_max_ring);
- }
+ for (j = 0; j < bp->rx_max_ring; j++) {
+ rxr->rx_desc_ring[j] =
+ pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
+ &rxr->rx_desc_mapping[j]);
+ if (rxr->rx_desc_ring[j] == NULL)
+ return -ENOMEM;
- if (bp->rx_pg_ring_size) {
- bp->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
- bp->rx_max_pg_ring);
- if (bp->rx_pg_ring == NULL)
- goto alloc_mem_err;
+ }
+
+ if (bp->rx_pg_ring_size) {
+ rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
+ bp->rx_max_pg_ring);
+ if (rxr->rx_pg_ring == NULL)
+ return -ENOMEM;
+
+ memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
+ bp->rx_max_pg_ring);
+ }
+
+ for (j = 0; j < bp->rx_max_pg_ring; j++) {
+ rxr->rx_pg_desc_ring[j] =
+ pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
+ &rxr->rx_pg_desc_mapping[j]);
+ if (rxr->rx_pg_desc_ring[j] == NULL)
+ return -ENOMEM;
- memset(bp->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
- bp->rx_max_pg_ring);
+ }
}
+ return 0;
+}
- for (i = 0; i < bp->rx_max_pg_ring; i++) {
- bp->rx_pg_desc_ring[i] =
- pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
- &bp->rx_pg_desc_mapping[i]);
- if (bp->rx_pg_desc_ring[i] == NULL)
- goto alloc_mem_err;
+static void
+bnx2_free_mem(struct bnx2 *bp)
+{
+ int i;
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+
+ bnx2_free_tx_mem(bp);
+ bnx2_free_rx_mem(bp);
+ for (i = 0; i < bp->ctx_pages; i++) {
+ if (bp->ctx_blk[i]) {
+ pci_free_consistent(bp->pdev, BCM_PAGE_SIZE,
+ bp->ctx_blk[i],
+ bp->ctx_blk_mapping[i]);
+ bp->ctx_blk[i] = NULL;
+ }
}
+ if (bnapi->status_blk.msi) {
+ pci_free_consistent(bp->pdev, bp->status_stats_size,
+ bnapi->status_blk.msi,
+ bp->status_blk_mapping);
+ bnapi->status_blk.msi = NULL;
+ bp->stats_blk = NULL;
+ }
+}
+
+static int
+bnx2_alloc_mem(struct bnx2 *bp)
+{
+ int i, status_blk_size, err;
+ struct bnx2_napi *bnapi;
+ void *status_blk;
/* Combine status and statistics blocks into one allocation. */
status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
@@ -598,27 +665,37 @@ bnx2_alloc_mem(struct bnx2 *bp)
bp->status_stats_size = status_blk_size +
sizeof(struct statistics_block);
- bp->status_blk = pci_alloc_consistent(bp->pdev, bp->status_stats_size,
- &bp->status_blk_mapping);
- if (bp->status_blk == NULL)
+ status_blk = pci_alloc_consistent(bp->pdev, bp->status_stats_size,
+ &bp->status_blk_mapping);
+ if (status_blk == NULL)
goto alloc_mem_err;
- memset(bp->status_blk, 0, bp->status_stats_size);
+ memset(status_blk, 0, bp->status_stats_size);
- bp->bnx2_napi[0].status_blk = bp->status_blk;
+ bnapi = &bp->bnx2_napi[0];
+ bnapi->status_blk.msi = status_blk;
+ bnapi->hw_tx_cons_ptr =
+ &bnapi->status_blk.msi->status_tx_quick_consumer_index0;
+ bnapi->hw_rx_cons_ptr =
+ &bnapi->status_blk.msi->status_rx_quick_consumer_index0;
if (bp->flags & BNX2_FLAG_MSIX_CAP) {
for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
- struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct status_block_msix *sblk;
- bnapi->status_blk_msix = (void *)
- ((unsigned long) bp->status_blk +
- BNX2_SBLK_MSIX_ALIGN_SIZE * i);
+ bnapi = &bp->bnx2_napi[i];
+
+ sblk = (void *) (status_blk +
+ BNX2_SBLK_MSIX_ALIGN_SIZE * i);
+ bnapi->status_blk.msix = sblk;
+ bnapi->hw_tx_cons_ptr =
+ &sblk->status_tx_quick_consumer_index;
+ bnapi->hw_rx_cons_ptr =
+ &sblk->status_rx_quick_consumer_index;
bnapi->int_num = i << 24;
}
}
- bp->stats_blk = (void *) ((unsigned long) bp->status_blk +
- status_blk_size);
+ bp->stats_blk = status_blk + status_blk_size;
bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
@@ -634,6 +711,15 @@ bnx2_alloc_mem(struct bnx2 *bp)
goto alloc_mem_err;
}
}
+
+ err = bnx2_alloc_rx_mem(bp);
+ if (err)
+ goto alloc_mem_err;
+
+ err = bnx2_alloc_tx_mem(bp);
+ if (err)
+ goto alloc_mem_err;
+
return 0;
alloc_mem_err:
@@ -993,9 +1079,9 @@ bnx2_copper_linkup(struct bnx2 *bp)
}
static void
-bnx2_init_rx_context0(struct bnx2 *bp)
+bnx2_init_rx_context(struct bnx2 *bp, u32 cid)
{
- u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID);
+ u32 val, rx_cid_addr = GET_CID_ADDR(cid);
val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
@@ -1028,6 +1114,19 @@ bnx2_init_rx_context0(struct bnx2 *bp)
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
}
+static void
+bnx2_init_all_rx_contexts(struct bnx2 *bp)
+{
+ int i;
+ u32 cid;
+
+ for (i = 0, cid = RX_CID; i < bp->num_rx_rings; i++, cid++) {
+ if (i == 1)
+ cid = RX_RSS_CID;
+ bnx2_init_rx_context(bp, cid);
+ }
+}
+
static int
bnx2_set_mac_link(struct bnx2 *bp)
{
@@ -1093,7 +1192,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
if (CHIP_NUM(bp) == CHIP_NUM_5709)
- bnx2_init_rx_context0(bp);
+ bnx2_init_all_rx_contexts(bp);
return 0;
}
@@ -1392,7 +1491,7 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
return adv;
}
-static int bnx2_fw_sync(struct bnx2 *, u32, int);
+static int bnx2_fw_sync(struct bnx2 *, u32, int, int);
static int
bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
@@ -1445,7 +1544,7 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
bnx2_shmem_wr(bp, BNX2_DRV_MB_ARG0, speed_arg);
spin_unlock_bh(&bp->phy_lock);
- bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 0);
+ bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 1, 0);
spin_lock_bh(&bp->phy_lock);
return 0;
@@ -1875,7 +1974,7 @@ bnx2_setup_phy(struct bnx2 *bp, u8 port)
}
static int
-bnx2_init_5709s_phy(struct bnx2 *bp)
+bnx2_init_5709s_phy(struct bnx2 *bp, int reset_phy)
{
u32 val;
@@ -1890,7 +1989,8 @@ bnx2_init_5709s_phy(struct bnx2 *bp)
bnx2_write_phy(bp, MII_BNX2_AER_AER, MII_BNX2_AER_AER_AN_MMD);
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
- bnx2_reset_phy(bp);
+ if (reset_phy)
+ bnx2_reset_phy(bp);
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_SERDES_DIG);
@@ -1924,11 +2024,12 @@ bnx2_init_5709s_phy(struct bnx2 *bp)
}
static int
-bnx2_init_5708s_phy(struct bnx2 *bp)
+bnx2_init_5708s_phy(struct bnx2 *bp, int reset_phy)
{
u32 val;
- bnx2_reset_phy(bp);
+ if (reset_phy)
+ bnx2_reset_phy(bp);
bp->mii_up1 = BCM5708S_UP1;
@@ -1981,9 +2082,10 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
}
static int
-bnx2_init_5706s_phy(struct bnx2 *bp)
+bnx2_init_5706s_phy(struct bnx2 *bp, int reset_phy)
{
- bnx2_reset_phy(bp);
+ if (reset_phy)
+ bnx2_reset_phy(bp);
bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
@@ -2018,11 +2120,12 @@ bnx2_init_5706s_phy(struct bnx2 *bp)
}
static int
-bnx2_init_copper_phy(struct bnx2 *bp)
+bnx2_init_copper_phy(struct bnx2 *bp, int reset_phy)
{
u32 val;
- bnx2_reset_phy(bp);
+ if (reset_phy)
+ bnx2_reset_phy(bp);
if (bp->phy_flags & BNX2_PHY_FLAG_CRC_FIX) {
bnx2_write_phy(bp, 0x18, 0x0c00);
@@ -2070,7 +2173,7 @@ bnx2_init_copper_phy(struct bnx2 *bp)
static int
-bnx2_init_phy(struct bnx2 *bp)
+bnx2_init_phy(struct bnx2 *bp, int reset_phy)
{
u32 val;
int rc = 0;
@@ -2096,14 +2199,14 @@ bnx2_init_phy(struct bnx2 *bp)
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
if (CHIP_NUM(bp) == CHIP_NUM_5706)
- rc = bnx2_init_5706s_phy(bp);
+ rc = bnx2_init_5706s_phy(bp, reset_phy);
else if (CHIP_NUM(bp) == CHIP_NUM_5708)
- rc = bnx2_init_5708s_phy(bp);
+ rc = bnx2_init_5708s_phy(bp, reset_phy);
else if (CHIP_NUM(bp) == CHIP_NUM_5709)
- rc = bnx2_init_5709s_phy(bp);
+ rc = bnx2_init_5709s_phy(bp, reset_phy);
}
else {
- rc = bnx2_init_copper_phy(bp);
+ rc = bnx2_init_copper_phy(bp, reset_phy);
}
setup_phy:
@@ -2159,7 +2262,7 @@ bnx2_set_phy_loopback(struct bnx2 *bp)
}
static int
-bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
+bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
{
int i;
u32 val;
@@ -2169,6 +2272,9 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
+ if (!ack)
+ return 0;
+
/* wait for an acknowledgement. */
for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
msleep(10);
@@ -2345,28 +2451,27 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
}
static void
-bnx2_set_mac_addr(struct bnx2 *bp)
+bnx2_set_mac_addr(struct bnx2 *bp, u8 *mac_addr, u32 pos)
{
u32 val;
- u8 *mac_addr = bp->dev->dev_addr;
val = (mac_addr[0] << 8) | mac_addr[1];
- REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val);
+ REG_WR(bp, BNX2_EMAC_MAC_MATCH0 + (pos * 8), 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);
+ REG_WR(bp, BNX2_EMAC_MAC_MATCH1 + (pos * 8), val);
}
static inline int
-bnx2_alloc_rx_page(struct bnx2 *bp, u16 index)
+bnx2_alloc_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
{
dma_addr_t mapping;
- struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
+ struct sw_pg *rx_pg = &rxr->rx_pg_ring[index];
struct rx_bd *rxbd =
- &bp->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
+ &rxr->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
struct page *page = alloc_page(GFP_ATOMIC);
if (!page)
@@ -2381,9 +2486,9 @@ bnx2_alloc_rx_page(struct bnx2 *bp, u16 index)
}
static void
-bnx2_free_rx_page(struct bnx2 *bp, u16 index)
+bnx2_free_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
{
- struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
+ struct sw_pg *rx_pg = &rxr->rx_pg_ring[index];
struct page *page = rx_pg->page;
if (!page)
@@ -2397,12 +2502,12 @@ bnx2_free_rx_page(struct bnx2 *bp, u16 index)
}
static inline int
-bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, u16 index)
+bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
{
struct sk_buff *skb;
- struct sw_bd *rx_buf = &bp->rx_buf_ring[index];
+ struct sw_bd *rx_buf = &rxr->rx_buf_ring[index];
dma_addr_t mapping;
- struct rx_bd *rxbd = &bp->rx_desc_ring[RX_RING(index)][RX_IDX(index)];
+ struct rx_bd *rxbd = &rxr->rx_desc_ring[RX_RING(index)][RX_IDX(index)];
unsigned long align;
skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
@@ -2422,7 +2527,7 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, u16 index)
rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
- bnapi->rx_prod_bseq += bp->rx_buf_use_size;
+ rxr->rx_prod_bseq += bp->rx_buf_use_size;
return 0;
}
@@ -2430,7 +2535,7 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, u16 index)
static int
bnx2_phy_event_is_set(struct bnx2 *bp, struct bnx2_napi *bnapi, u32 event)
{
- struct status_block *sblk = bnapi->status_blk;
+ struct status_block *sblk = bnapi->status_blk.msi;
u32 new_link_state, old_link_state;
int is_set = 1;
@@ -2466,11 +2571,9 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
{
u16 cons;
- if (bnapi->int_num == 0)
- cons = bnapi->status_blk->status_tx_quick_consumer_index0;
- else
- cons = bnapi->status_blk_msix->status_tx_quick_consumer_index;
-
+ /* Tell compiler that status block fields can change. */
+ barrier();
+ cons = *bnapi->hw_tx_cons_ptr;
if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
cons++;
return cons;
@@ -2479,11 +2582,16 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
static int
bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
{
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
u16 hw_cons, sw_cons, sw_ring_cons;
- int tx_pkt = 0;
+ int tx_pkt = 0, index;
+ struct netdev_queue *txq;
+
+ index = (bnapi - bp->bnx2_napi);
+ txq = netdev_get_tx_queue(bp->dev, index);
hw_cons = bnx2_get_hw_tx_cons(bnapi);
- sw_cons = bnapi->tx_cons;
+ sw_cons = txr->tx_cons;
while (sw_cons != hw_cons) {
struct sw_bd *tx_buf;
@@ -2492,7 +2600,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
sw_ring_cons = TX_RING_IDX(sw_cons);
- tx_buf = &bp->tx_buf_ring[sw_ring_cons];
+ tx_buf = &txr->tx_buf_ring[sw_ring_cons];
skb = tx_buf->skb;
/* partial BD completions possible with TSO packets */
@@ -2522,7 +2630,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
pci_unmap_page(bp->pdev,
pci_unmap_addr(
- &bp->tx_buf_ring[TX_RING_IDX(sw_cons)],
+ &txr->tx_buf_ring[TX_RING_IDX(sw_cons)],
mapping),
skb_shinfo(skb)->frags[i].size,
PCI_DMA_TODEVICE);
@@ -2538,44 +2646,46 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
hw_cons = bnx2_get_hw_tx_cons(bnapi);
}
- bnapi->hw_tx_cons = hw_cons;
- bnapi->tx_cons = sw_cons;
+ txr->hw_tx_cons = hw_cons;
+ txr->tx_cons = sw_cons;
+
/* Need to make the tx_cons update visible to bnx2_start_xmit()
- * before checking for netif_queue_stopped(). Without the
+ * before checking for netif_tx_queue_stopped(). Without the
* memory barrier, there is a small possibility that bnx2_start_xmit()
* will miss it and cause the queue to be stopped forever.
*/
smp_mb();
- if (unlikely(netif_queue_stopped(bp->dev)) &&
- (bnx2_tx_avail(bp, bnapi) > bp->tx_wake_thresh)) {
- netif_tx_lock(bp->dev);
- if ((netif_queue_stopped(bp->dev)) &&
- (bnx2_tx_avail(bp, bnapi) > bp->tx_wake_thresh))
- netif_wake_queue(bp->dev);
- netif_tx_unlock(bp->dev);
+ if (unlikely(netif_tx_queue_stopped(txq)) &&
+ (bnx2_tx_avail(bp, txr) > bp->tx_wake_thresh)) {
+ __netif_tx_lock(txq, smp_processor_id());
+ if ((netif_tx_queue_stopped(txq)) &&
+ (bnx2_tx_avail(bp, txr) > bp->tx_wake_thresh))
+ netif_tx_wake_queue(txq);
+ __netif_tx_unlock(txq);
}
+
return tx_pkt;
}
static void
-bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_napi *bnapi,
+bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
struct sk_buff *skb, int count)
{
struct sw_pg *cons_rx_pg, *prod_rx_pg;
struct rx_bd *cons_bd, *prod_bd;
dma_addr_t mapping;
int i;
- u16 hw_prod = bnapi->rx_pg_prod, prod;
- u16 cons = bnapi->rx_pg_cons;
+ u16 hw_prod = rxr->rx_pg_prod, prod;
+ u16 cons = rxr->rx_pg_cons;
for (i = 0; i < count; i++) {
prod = RX_PG_RING_IDX(hw_prod);
- prod_rx_pg = &bp->rx_pg_ring[prod];
- cons_rx_pg = &bp->rx_pg_ring[cons];
- cons_bd = &bp->rx_pg_desc_ring[RX_RING(cons)][RX_IDX(cons)];
- prod_bd = &bp->rx_pg_desc_ring[RX_RING(prod)][RX_IDX(prod)];
+ prod_rx_pg = &rxr->rx_pg_ring[prod];
+ cons_rx_pg = &rxr->rx_pg_ring[cons];
+ cons_bd = &rxr->rx_pg_desc_ring[RX_RING(cons)][RX_IDX(cons)];
+ prod_bd = &rxr->rx_pg_desc_ring[RX_RING(prod)][RX_IDX(prod)];
if (i == 0 && skb) {
struct page *page;
@@ -2604,25 +2714,25 @@ bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_napi *bnapi,
cons = RX_PG_RING_IDX(NEXT_RX_BD(cons));
hw_prod = NEXT_RX_BD(hw_prod);
}
- bnapi->rx_pg_prod = hw_prod;
- bnapi->rx_pg_cons = cons;
+ rxr->rx_pg_prod = hw_prod;
+ rxr->rx_pg_cons = cons;
}
static inline void
-bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
- u16 cons, u16 prod)
+bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
+ struct sk_buff *skb, u16 cons, u16 prod)
{
struct sw_bd *cons_rx_buf, *prod_rx_buf;
struct rx_bd *cons_bd, *prod_bd;
- cons_rx_buf = &bp->rx_buf_ring[cons];
- prod_rx_buf = &bp->rx_buf_ring[prod];
+ cons_rx_buf = &rxr->rx_buf_ring[cons];
+ prod_rx_buf = &rxr->rx_buf_ring[prod];
pci_dma_sync_single_for_device(bp->pdev,
pci_unmap_addr(cons_rx_buf, mapping),
- bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
+ BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
- bnapi->rx_prod_bseq += bp->rx_buf_use_size;
+ rxr->rx_prod_bseq += bp->rx_buf_use_size;
prod_rx_buf->skb = skb;
@@ -2632,33 +2742,33 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
pci_unmap_addr_set(prod_rx_buf, mapping,
pci_unmap_addr(cons_rx_buf, mapping));
- cons_bd = &bp->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)];
- prod_bd = &bp->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)];
+ cons_bd = &rxr->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)];
+ prod_bd = &rxr->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)];
prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
}
static int
-bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
+bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb,
unsigned int len, unsigned int hdr_len, dma_addr_t dma_addr,
u32 ring_idx)
{
int err;
u16 prod = ring_idx & 0xffff;
- err = bnx2_alloc_rx_skb(bp, bnapi, prod);
+ err = bnx2_alloc_rx_skb(bp, rxr, prod);
if (unlikely(err)) {
- bnx2_reuse_rx_skb(bp, bnapi, skb, (u16) (ring_idx >> 16), prod);
+ bnx2_reuse_rx_skb(bp, rxr, skb, (u16) (ring_idx >> 16), prod);
if (hdr_len) {
unsigned int raw_len = len + 4;
int pages = PAGE_ALIGN(raw_len - hdr_len) >> PAGE_SHIFT;
- bnx2_reuse_rx_skb_pages(bp, bnapi, NULL, pages);
+ bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
}
return err;
}
- skb_reserve(skb, bp->rx_offset);
+ skb_reserve(skb, BNX2_RX_OFFSET);
pci_unmap_single(bp->pdev, dma_addr, bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
@@ -2668,8 +2778,8 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
} else {
unsigned int i, frag_len, frag_size, pages;
struct sw_pg *rx_pg;
- u16 pg_cons = bnapi->rx_pg_cons;
- u16 pg_prod = bnapi->rx_pg_prod;
+ u16 pg_cons = rxr->rx_pg_cons;
+ u16 pg_prod = rxr->rx_pg_prod;
frag_size = len + 4 - hdr_len;
pages = PAGE_ALIGN(frag_size) >> PAGE_SHIFT;
@@ -2680,9 +2790,9 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
if (unlikely(frag_len <= 4)) {
unsigned int tail = 4 - frag_len;
- bnapi->rx_pg_cons = pg_cons;
- bnapi->rx_pg_prod = pg_prod;
- bnx2_reuse_rx_skb_pages(bp, bnapi, NULL,
+ rxr->rx_pg_cons = pg_cons;
+ rxr->rx_pg_prod = pg_prod;
+ bnx2_reuse_rx_skb_pages(bp, rxr, NULL,
pages - i);
skb->len -= tail;
if (i == 0) {
@@ -2696,7 +2806,7 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
}
return 0;
}
- rx_pg = &bp->rx_pg_ring[pg_cons];
+ rx_pg = &rxr->rx_pg_ring[pg_cons];
pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping),
PAGE_SIZE, PCI_DMA_FROMDEVICE);
@@ -2707,11 +2817,12 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
skb_fill_page_desc(skb, i, rx_pg->page, 0, frag_len);
rx_pg->page = NULL;
- err = bnx2_alloc_rx_page(bp, RX_PG_RING_IDX(pg_prod));
+ err = bnx2_alloc_rx_page(bp, rxr,
+ RX_PG_RING_IDX(pg_prod));
if (unlikely(err)) {
- bnapi->rx_pg_cons = pg_cons;
- bnapi->rx_pg_prod = pg_prod;
- bnx2_reuse_rx_skb_pages(bp, bnapi, skb,
+ rxr->rx_pg_cons = pg_cons;
+ rxr->rx_pg_prod = pg_prod;
+ bnx2_reuse_rx_skb_pages(bp, rxr, skb,
pages - i);
return err;
}
@@ -2724,8 +2835,8 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
pg_prod = NEXT_RX_BD(pg_prod);
pg_cons = RX_PG_RING_IDX(NEXT_RX_BD(pg_cons));
}
- bnapi->rx_pg_prod = pg_prod;
- bnapi->rx_pg_cons = pg_cons;
+ rxr->rx_pg_prod = pg_prod;
+ rxr->rx_pg_cons = pg_cons;
}
return 0;
}
@@ -2733,8 +2844,11 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
static inline u16
bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi)
{
- u16 cons = bnapi->status_blk->status_rx_quick_consumer_index0;
+ u16 cons;
+ /* Tell compiler that status block fields can change. */
+ barrier();
+ cons = *bnapi->hw_rx_cons_ptr;
if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
cons++;
return cons;
@@ -2743,13 +2857,14 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi)
static int
bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
{
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
struct l2_fhdr *rx_hdr;
int rx_pkt = 0, pg_ring_used = 0;
hw_cons = bnx2_get_hw_rx_cons(bnapi);
- sw_cons = bnapi->rx_cons;
- sw_prod = bnapi->rx_prod;
+ sw_cons = rxr->rx_cons;
+ sw_prod = rxr->rx_prod;
/* Memory barrier necessary as speculative reads of the rx
* buffer can be ahead of the index in the status block
@@ -2765,7 +2880,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
sw_ring_cons = RX_RING_IDX(sw_cons);
sw_ring_prod = RX_RING_IDX(sw_prod);
- rx_buf = &bp->rx_buf_ring[sw_ring_cons];
+ rx_buf = &rxr->rx_buf_ring[sw_ring_cons];
skb = rx_buf->skb;
rx_buf->skb = NULL;
@@ -2773,7 +2888,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
dma_addr = pci_unmap_addr(rx_buf, mapping);
pci_dma_sync_single_for_cpu(bp->pdev, dma_addr,
- bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
+ BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH,
+ PCI_DMA_FROMDEVICE);
rx_hdr = (struct l2_fhdr *) skb->data;
len = rx_hdr->l2_fhdr_pkt_len;
@@ -2785,7 +2901,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
L2_FHDR_ERRORS_TOO_SHORT |
L2_FHDR_ERRORS_GIANT_FRAME)) {
- bnx2_reuse_rx_skb(bp, bnapi, skb, sw_ring_cons,
+ bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
sw_ring_prod);
goto next_rx;
}
@@ -2805,22 +2921,23 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
new_skb = netdev_alloc_skb(bp->dev, len + 2);
if (new_skb == NULL) {
- bnx2_reuse_rx_skb(bp, bnapi, skb, sw_ring_cons,
+ bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
sw_ring_prod);
goto next_rx;
}
/* aligned copy */
- skb_copy_from_linear_data_offset(skb, bp->rx_offset - 2,
+ skb_copy_from_linear_data_offset(skb,
+ BNX2_RX_OFFSET - 2,
new_skb->data, len + 2);
skb_reserve(new_skb, 2);
skb_put(new_skb, len);
- bnx2_reuse_rx_skb(bp, bnapi, skb,
+ bnx2_reuse_rx_skb(bp, rxr, skb,
sw_ring_cons, sw_ring_prod);
skb = new_skb;
- } else if (unlikely(bnx2_rx_skb(bp, bnapi, skb, len, hdr_len,
+ } else if (unlikely(bnx2_rx_skb(bp, rxr, skb, len, hdr_len,
dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
goto next_rx;
@@ -2869,16 +2986,15 @@ next_rx:
rmb();
}
}
- bnapi->rx_cons = sw_cons;
- bnapi->rx_prod = sw_prod;
+ rxr->rx_cons = sw_cons;
+ rxr->rx_prod = sw_prod;
if (pg_ring_used)
- REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_PG_BDIDX,
- bnapi->rx_pg_prod);
+ REG_WR16(bp, rxr->rx_pg_bidx_addr, rxr->rx_pg_prod);
- REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, sw_prod);
+ REG_WR16(bp, rxr->rx_bidx_addr, sw_prod);
- REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bnapi->rx_prod_bseq);
+ REG_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
mmiowb();
@@ -2892,11 +3008,11 @@ next_rx:
static irqreturn_t
bnx2_msi(int irq, void *dev_instance)
{
- struct net_device *dev = dev_instance;
- struct bnx2 *bp = netdev_priv(dev);
- struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ struct bnx2_napi *bnapi = dev_instance;
+ struct bnx2 *bp = bnapi->bp;
+ struct net_device *dev = bp->dev;
- prefetch(bnapi->status_blk);
+ prefetch(bnapi->status_blk.msi);
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -2913,11 +3029,11 @@ bnx2_msi(int irq, void *dev_instance)
static irqreturn_t
bnx2_msi_1shot(int irq, void *dev_instance)
{
- struct net_device *dev = dev_instance;
- struct bnx2 *bp = netdev_priv(dev);
- struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ struct bnx2_napi *bnapi = dev_instance;
+ struct bnx2 *bp = bnapi->bp;
+ struct net_device *dev = bp->dev;
- prefetch(bnapi->status_blk);
+ prefetch(bnapi->status_blk.msi);
/* Return here if interrupt is disabled. */
if (unlikely(atomic_read(&bp->intr_sem) != 0))
@@ -2931,10 +3047,10 @@ bnx2_msi_1shot(int irq, void *dev_instance)
static irqreturn_t
bnx2_interrupt(int irq, void *dev_instance)
{
- struct net_device *dev = dev_instance;
- struct bnx2 *bp = netdev_priv(dev);
- struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
- struct status_block *sblk = bnapi->status_blk;
+ struct bnx2_napi *bnapi = dev_instance;
+ struct bnx2 *bp = bnapi->bp;
+ struct net_device *dev = bp->dev;
+ struct status_block *sblk = bnapi->status_blk.msi;
/* When using INTx, it is possible for the interrupt to arrive
* at the CPU before the status block posted prior to the
@@ -2968,21 +3084,16 @@ bnx2_interrupt(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-static irqreturn_t
-bnx2_tx_msix(int irq, void *dev_instance)
+static inline int
+bnx2_has_fast_work(struct bnx2_napi *bnapi)
{
- struct net_device *dev = dev_instance;
- struct bnx2 *bp = netdev_priv(dev);
- struct bnx2_napi *bnapi = &bp->bnx2_napi[BNX2_TX_VEC];
-
- prefetch(bnapi->status_blk_msix);
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
- /* Return here if interrupt is disabled. */
- if (unlikely(atomic_read(&bp->intr_sem) != 0))
- return IRQ_HANDLED;
-
- netif_rx_schedule(dev, &bnapi->napi);
- return IRQ_HANDLED;
+ if ((bnx2_get_hw_rx_cons(bnapi) != rxr->rx_cons) ||
+ (bnx2_get_hw_tx_cons(bnapi) != txr->hw_tx_cons))
+ return 1;
+ return 0;
}
#define STATUS_ATTN_EVENTS (STATUS_ATTN_BITS_LINK_STATE | \
@@ -2991,10 +3102,9 @@ bnx2_tx_msix(int irq, void *dev_instance)
static inline int
bnx2_has_work(struct bnx2_napi *bnapi)
{
- struct status_block *sblk = bnapi->status_blk;
+ struct status_block *sblk = bnapi->status_blk.msi;
- if ((bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons) ||
- (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons))
+ if (bnx2_has_fast_work(bnapi))
return 1;
if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) !=
@@ -3004,33 +3114,9 @@ bnx2_has_work(struct bnx2_napi *bnapi)
return 0;
}
-static int bnx2_tx_poll(struct napi_struct *napi, int budget)
-{
- struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
- struct bnx2 *bp = bnapi->bp;
- int work_done = 0;
- struct status_block_msix *sblk = bnapi->status_blk_msix;
-
- do {
- work_done += bnx2_tx_int(bp, bnapi, budget - work_done);
- if (unlikely(work_done >= budget))
- return work_done;
-
- bnapi->last_status_idx = sblk->status_idx;
- rmb();
- } while (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons);
-
- netif_rx_complete(bp->dev, napi);
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- bnapi->last_status_idx);
- return work_done;
-}
-
-static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
- int work_done, int budget)
+static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
{
- struct status_block *sblk = bnapi->status_blk;
+ struct status_block *sblk = bnapi->status_blk.msi;
u32 status_attn_bits = sblk->status_attn_bits;
u32 status_attn_bits_ack = sblk->status_attn_bits_ack;
@@ -3046,24 +3132,60 @@ static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
REG_RD(bp, BNX2_HC_COMMAND);
}
+}
- if (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons)
+static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
+ int work_done, int budget)
+{
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
+
+ if (bnx2_get_hw_tx_cons(bnapi) != txr->hw_tx_cons)
bnx2_tx_int(bp, bnapi, 0);
- if (bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons)
+ if (bnx2_get_hw_rx_cons(bnapi) != rxr->rx_cons)
work_done += bnx2_rx_int(bp, bnapi, budget - work_done);
return work_done;
}
+static int bnx2_poll_msix(struct napi_struct *napi, int budget)
+{
+ struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
+ struct bnx2 *bp = bnapi->bp;
+ int work_done = 0;
+ struct status_block_msix *sblk = bnapi->status_blk.msix;
+
+ while (1) {
+ work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
+ if (unlikely(work_done >= budget))
+ break;
+
+ bnapi->last_status_idx = sblk->status_idx;
+ /* status idx must be read before checking for more work. */
+ rmb();
+ if (likely(!bnx2_has_fast_work(bnapi))) {
+
+ netif_rx_complete(bp->dev, napi);
+ REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ bnapi->last_status_idx);
+ break;
+ }
+ }
+ return work_done;
+}
+
static int bnx2_poll(struct napi_struct *napi, int budget)
{
struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
struct bnx2 *bp = bnapi->bp;
int work_done = 0;
- struct status_block *sblk = bnapi->status_blk;
+ struct status_block *sblk = bnapi->status_blk.msi;
while (1) {
+ bnx2_poll_link(bp, bnapi);
+
work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
if (unlikely(work_done >= budget))
@@ -3106,6 +3228,7 @@ bnx2_set_rx_mode(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
u32 rx_mode, sort_mode;
+ struct dev_addr_list *uc_ptr;
int i;
spin_lock_bh(&bp->phy_lock);
@@ -3161,6 +3284,25 @@ bnx2_set_rx_mode(struct net_device *dev)
sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
}
+ uc_ptr = NULL;
+ if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
+ rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
+ sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
+ BNX2_RPM_SORT_USER0_PROM_VLAN;
+ } else if (!(dev->flags & IFF_PROMISC)) {
+ uc_ptr = dev->uc_list;
+
+ /* Add all entries into to the match filter list */
+ for (i = 0; i < dev->uc_count; i++) {
+ bnx2_set_mac_addr(bp, uc_ptr->da_addr,
+ i + BNX2_START_UNICAST_ADDRESS_INDEX);
+ sort_mode |= (1 <<
+ (i + BNX2_START_UNICAST_ADDRESS_INDEX));
+ uc_ptr = uc_ptr->next;
+ }
+
+ }
+
if (rx_mode != bp->rx_mode) {
bp->rx_mode = rx_mode;
REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
@@ -3213,7 +3355,7 @@ load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len,
}
static int
-load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
+load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
{
u32 offset;
u32 val;
@@ -3297,7 +3439,6 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
static int
bnx2_init_cpus(struct bnx2 *bp)
{
- struct cpu_reg cpu_reg;
struct fw_info *fw;
int rc, rv2p_len;
void *text, *rv2p;
@@ -3333,122 +3474,57 @@ bnx2_init_cpus(struct bnx2 *bp)
load_rv2p_fw(bp, text, rc /* == len */, 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;
-
if (CHIP_NUM(bp) == CHIP_NUM_5709)
fw = &bnx2_rxp_fw_09;
else
fw = &bnx2_rxp_fw_06;
fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_rxp, fw);
if (rc)
goto init_cpu_err;
/* 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;
-
if (CHIP_NUM(bp) == CHIP_NUM_5709)
fw = &bnx2_txp_fw_09;
else
fw = &bnx2_txp_fw_06;
fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_txp, fw);
if (rc)
goto init_cpu_err;
/* 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;
-
if (CHIP_NUM(bp) == CHIP_NUM_5709)
fw = &bnx2_tpat_fw_09;
else
fw = &bnx2_tpat_fw_06;
fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_tpat, fw);
if (rc)
goto init_cpu_err;
/* 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;
-
if (CHIP_NUM(bp) == CHIP_NUM_5709)
fw = &bnx2_com_fw_09;
else
fw = &bnx2_com_fw_06;
fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_com, fw);
if (rc)
goto init_cpu_err;
/* Initialize the Command Processor. */
- cpu_reg.mode = BNX2_CP_CPU_MODE;
- cpu_reg.mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT;
- cpu_reg.mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA;
- cpu_reg.state = BNX2_CP_CPU_STATE;
- cpu_reg.state_value_clear = 0xffffff;
- cpu_reg.gpr0 = BNX2_CP_CPU_REG_FILE;
- cpu_reg.evmask = BNX2_CP_CPU_EVENT_MASK;
- cpu_reg.pc = BNX2_CP_CPU_PROGRAM_COUNTER;
- cpu_reg.inst = BNX2_CP_CPU_INSTRUCTION;
- cpu_reg.bp = BNX2_CP_CPU_HW_BREAKPOINT;
- cpu_reg.spad_base = BNX2_CP_SCRATCH;
- cpu_reg.mips_view_base = 0x8000000;
-
if (CHIP_NUM(bp) == CHIP_NUM_5709)
fw = &bnx2_cp_fw_09;
else
fw = &bnx2_cp_fw_06;
fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_cp, fw);
init_cpu_err:
vfree(text);
@@ -3511,7 +3587,7 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
bp->autoneg = autoneg;
bp->advertising = advertising;
- bnx2_set_mac_addr(bp);
+ bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
val = REG_RD(bp, BNX2_EMAC_MODE);
@@ -3562,7 +3638,8 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
}
if (!(bp->flags & BNX2_FLAG_NO_WOL))
- bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0);
+ bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg,
+ 1, 0);
pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
@@ -4203,35 +4280,43 @@ nvram_write_end:
}
static void
-bnx2_init_remote_phy(struct bnx2 *bp)
+bnx2_init_fw_cap(struct bnx2 *bp)
{
- u32 val;
+ u32 val, sig = 0;
bp->phy_flags &= ~BNX2_PHY_FLAG_REMOTE_PHY_CAP;
- if (!(bp->phy_flags & BNX2_PHY_FLAG_SERDES))
- return;
+ bp->flags &= ~BNX2_FLAG_CAN_KEEP_VLAN;
+
+ if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
+ bp->flags |= BNX2_FLAG_CAN_KEEP_VLAN;
val = bnx2_shmem_rd(bp, BNX2_FW_CAP_MB);
if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
return;
- if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
+ if ((val & BNX2_FW_CAP_CAN_KEEP_VLAN) == BNX2_FW_CAP_CAN_KEEP_VLAN) {
+ bp->flags |= BNX2_FLAG_CAN_KEEP_VLAN;
+ sig |= BNX2_DRV_ACK_CAP_SIGNATURE | BNX2_FW_CAP_CAN_KEEP_VLAN;
+ }
+
+ if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
+ (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE)) {
+ u32 link;
+
bp->phy_flags |= BNX2_PHY_FLAG_REMOTE_PHY_CAP;
- val = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
- if (val & BNX2_LINK_STATUS_SERDES_LINK)
+ link = bnx2_shmem_rd(bp, BNX2_LINK_STATUS);
+ if (link & BNX2_LINK_STATUS_SERDES_LINK)
bp->phy_port = PORT_FIBRE;
else
bp->phy_port = PORT_TP;
- if (netif_running(bp->dev)) {
- u32 sig;
-
- sig = BNX2_DRV_ACK_CAP_SIGNATURE |
- BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
- bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig);
- }
+ sig |= BNX2_DRV_ACK_CAP_SIGNATURE |
+ BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
}
+
+ if (netif_running(bp->dev) && sig)
+ bnx2_shmem_wr(bp, BNX2_DRV_ACK_CAP_MB, sig);
}
static void
@@ -4261,7 +4346,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
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);
+ bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
/* Deposit a driver reset signature so the firmware knows that
* this is a soft reset. */
@@ -4322,13 +4407,13 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
}
/* Wait for the firmware to finish its initialization. */
- rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0);
+ rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 1, 0);
if (rc)
return rc;
spin_lock_bh(&bp->phy_lock);
old_port = bp->phy_port;
- bnx2_init_remote_phy(bp);
+ bnx2_init_fw_cap(bp);
if ((bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) &&
old_port != bp->phy_port)
bnx2_set_default_remote_link(bp);
@@ -4412,7 +4497,7 @@ bnx2_init_chip(struct bnx2 *bp)
bnx2_init_nvram(bp);
- bnx2_set_mac_addr(bp);
+ bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
val = REG_RD(bp, BNX2_MQ_CONFIG);
val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
@@ -4498,15 +4583,25 @@ bnx2_init_chip(struct bnx2 *bp)
BNX2_HC_CONFIG_COLLECT_STATS;
}
- if (bp->flags & BNX2_FLAG_USING_MSIX) {
- u32 base = ((BNX2_TX_VEC - 1) * BNX2_HC_SB_CONFIG_SIZE) +
- BNX2_HC_SB_CONFIG_1;
-
+ if (bp->irq_nvecs > 1) {
REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
BNX2_HC_MSIX_BIT_VECTOR_VAL);
+ val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
+ }
+
+ if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
+ val |= BNX2_HC_CONFIG_ONE_SHOT;
+
+ REG_WR(bp, BNX2_HC_CONFIG, val);
+
+ for (i = 1; i < bp->irq_nvecs; i++) {
+ u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) +
+ BNX2_HC_SB_CONFIG_1;
+
REG_WR(bp, base,
BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
+ BNX2_HC_SB_CONFIG_1_RX_TMR_MODE |
BNX2_HC_SB_CONFIG_1_ONE_SHOT);
REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
@@ -4516,13 +4611,13 @@ bnx2_init_chip(struct bnx2 *bp)
REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
(bp->tx_ticks_int << 16) | bp->tx_ticks);
- val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
- }
+ REG_WR(bp, base + BNX2_HC_RX_QUICK_CONS_TRIP_OFF,
+ (bp->rx_quick_cons_trip_int << 16) |
+ bp->rx_quick_cons_trip);
- if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
- val |= BNX2_HC_CONFIG_ONE_SHOT;
-
- REG_WR(bp, BNX2_HC_CONFIG, val);
+ REG_WR(bp, base + BNX2_HC_RX_TICKS_OFF,
+ (bp->rx_ticks_int << 16) | bp->rx_ticks);
+ }
/* Clear internal stats counters. */
REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
@@ -4538,7 +4633,7 @@ bnx2_init_chip(struct bnx2 *bp)
REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
}
rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
- 0);
+ 1, 0);
REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT);
REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
@@ -4554,23 +4649,27 @@ static void
bnx2_clear_ring_states(struct bnx2 *bp)
{
struct bnx2_napi *bnapi;
+ struct bnx2_tx_ring_info *txr;
+ struct bnx2_rx_ring_info *rxr;
int i;
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
bnapi = &bp->bnx2_napi[i];
+ txr = &bnapi->tx_ring;
+ rxr = &bnapi->rx_ring;
- bnapi->tx_cons = 0;
- bnapi->hw_tx_cons = 0;
- bnapi->rx_prod_bseq = 0;
- bnapi->rx_prod = 0;
- bnapi->rx_cons = 0;
- bnapi->rx_pg_prod = 0;
- bnapi->rx_pg_cons = 0;
+ txr->tx_cons = 0;
+ txr->hw_tx_cons = 0;
+ rxr->rx_prod_bseq = 0;
+ rxr->rx_prod = 0;
+ rxr->rx_cons = 0;
+ rxr->rx_pg_prod = 0;
+ rxr->rx_pg_cons = 0;
}
}
static void
-bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
+bnx2_init_tx_context(struct bnx2 *bp, u32 cid, struct bnx2_tx_ring_info *txr)
{
u32 val, offset0, offset1, offset2, offset3;
u32 cid_addr = GET_CID_ADDR(cid);
@@ -4592,43 +4691,43 @@ bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
bnx2_ctx_wr(bp, cid_addr, offset1, val);
- val = (u64) bp->tx_desc_mapping >> 32;
+ val = (u64) txr->tx_desc_mapping >> 32;
bnx2_ctx_wr(bp, cid_addr, offset2, val);
- val = (u64) bp->tx_desc_mapping & 0xffffffff;
+ val = (u64) txr->tx_desc_mapping & 0xffffffff;
bnx2_ctx_wr(bp, cid_addr, offset3, val);
}
static void
-bnx2_init_tx_ring(struct bnx2 *bp)
+bnx2_init_tx_ring(struct bnx2 *bp, int ring_num)
{
struct tx_bd *txbd;
u32 cid = TX_CID;
struct bnx2_napi *bnapi;
+ struct bnx2_tx_ring_info *txr;
- bp->tx_vec = 0;
- if (bp->flags & BNX2_FLAG_USING_MSIX) {
- cid = TX_TSS_CID;
- bp->tx_vec = BNX2_TX_VEC;
- REG_WR(bp, BNX2_TSCH_TSS_CFG, BNX2_TX_INT_NUM |
- (TX_TSS_CID << 7));
- }
- bnapi = &bp->bnx2_napi[bp->tx_vec];
+ bnapi = &bp->bnx2_napi[ring_num];
+ txr = &bnapi->tx_ring;
+
+ if (ring_num == 0)
+ cid = TX_CID;
+ else
+ cid = TX_TSS_CID + ring_num - 1;
bp->tx_wake_thresh = bp->tx_ring_size / 2;
- txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT];
+ txbd = &txr->tx_desc_ring[MAX_TX_DESC_CNT];
- txbd->tx_bd_haddr_hi = (u64) bp->tx_desc_mapping >> 32;
- txbd->tx_bd_haddr_lo = (u64) bp->tx_desc_mapping & 0xffffffff;
+ txbd->tx_bd_haddr_hi = (u64) txr->tx_desc_mapping >> 32;
+ txbd->tx_bd_haddr_lo = (u64) txr->tx_desc_mapping & 0xffffffff;
- bp->tx_prod = 0;
- bp->tx_prod_bseq = 0;
+ txr->tx_prod = 0;
+ txr->tx_prod_bseq = 0;
- bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
- bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;
+ txr->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
+ txr->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;
- bnx2_init_tx_context(bp, cid);
+ bnx2_init_tx_context(bp, cid, txr);
}
static void
@@ -4656,17 +4755,25 @@ bnx2_init_rxbd_rings(struct rx_bd *rx_ring[], dma_addr_t dma[], u32 buf_size,
}
static void
-bnx2_init_rx_ring(struct bnx2 *bp)
+bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
{
int i;
u16 prod, ring_prod;
- u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID);
- struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ u32 cid, rx_cid_addr, val;
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[ring_num];
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
- bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
+ if (ring_num == 0)
+ cid = RX_CID;
+ else
+ cid = RX_RSS_CID + ring_num - 1;
+
+ rx_cid_addr = GET_CID_ADDR(cid);
+
+ bnx2_init_rxbd_rings(rxr->rx_desc_ring, rxr->rx_desc_mapping,
bp->rx_buf_use_size, bp->rx_max_ring);
- bnx2_init_rx_context0(bp);
+ bnx2_init_rx_context(bp, cid);
if (CHIP_NUM(bp) == CHIP_NUM_5709) {
val = REG_RD(bp, BNX2_MQ_MAP_L2_5);
@@ -4675,54 +4782,101 @@ bnx2_init_rx_ring(struct bnx2 *bp)
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
if (bp->rx_pg_ring_size) {
- bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
- bp->rx_pg_desc_mapping,
+ bnx2_init_rxbd_rings(rxr->rx_pg_desc_ring,
+ rxr->rx_pg_desc_mapping,
PAGE_SIZE, bp->rx_max_pg_ring);
val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
- BNX2_L2CTX_RBDC_JUMBO_KEY);
+ BNX2_L2CTX_RBDC_JUMBO_KEY - ring_num);
- val = (u64) bp->rx_pg_desc_mapping[0] >> 32;
+ val = (u64) rxr->rx_pg_desc_mapping[0] >> 32;
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
- val = (u64) bp->rx_pg_desc_mapping[0] & 0xffffffff;
+ val = (u64) rxr->rx_pg_desc_mapping[0] & 0xffffffff;
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
if (CHIP_NUM(bp) == CHIP_NUM_5709)
REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
}
- val = (u64) bp->rx_desc_mapping[0] >> 32;
+ val = (u64) rxr->rx_desc_mapping[0] >> 32;
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
- val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
+ val = (u64) rxr->rx_desc_mapping[0] & 0xffffffff;
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
- ring_prod = prod = bnapi->rx_pg_prod;
+ ring_prod = prod = rxr->rx_pg_prod;
for (i = 0; i < bp->rx_pg_ring_size; i++) {
- if (bnx2_alloc_rx_page(bp, ring_prod) < 0)
+ if (bnx2_alloc_rx_page(bp, rxr, ring_prod) < 0)
break;
prod = NEXT_RX_BD(prod);
ring_prod = RX_PG_RING_IDX(prod);
}
- bnapi->rx_pg_prod = prod;
+ rxr->rx_pg_prod = prod;
- ring_prod = prod = bnapi->rx_prod;
+ ring_prod = prod = rxr->rx_prod;
for (i = 0; i < bp->rx_ring_size; i++) {
- if (bnx2_alloc_rx_skb(bp, bnapi, ring_prod) < 0) {
+ if (bnx2_alloc_rx_skb(bp, rxr, ring_prod) < 0)
break;
- }
prod = NEXT_RX_BD(prod);
ring_prod = RX_RING_IDX(prod);
}
- bnapi->rx_prod = prod;
+ rxr->rx_prod = prod;
+
+ rxr->rx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_BDIDX;
+ rxr->rx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_BSEQ;
+ rxr->rx_pg_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_PG_BDIDX;
- REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_PG_BDIDX,
- bnapi->rx_pg_prod);
- REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod);
+ REG_WR16(bp, rxr->rx_pg_bidx_addr, rxr->rx_pg_prod);
+ REG_WR16(bp, rxr->rx_bidx_addr, prod);
- REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bnapi->rx_prod_bseq);
+ REG_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
+}
+
+static void
+bnx2_init_all_rings(struct bnx2 *bp)
+{
+ int i;
+ u32 val;
+
+ bnx2_clear_ring_states(bp);
+
+ REG_WR(bp, BNX2_TSCH_TSS_CFG, 0);
+ for (i = 0; i < bp->num_tx_rings; i++)
+ bnx2_init_tx_ring(bp, i);
+
+ if (bp->num_tx_rings > 1)
+ REG_WR(bp, BNX2_TSCH_TSS_CFG, ((bp->num_tx_rings - 1) << 24) |
+ (TX_TSS_CID << 7));
+
+ REG_WR(bp, BNX2_RLUP_RSS_CONFIG, 0);
+ bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, 0);
+
+ for (i = 0; i < bp->num_rx_rings; i++)
+ bnx2_init_rx_ring(bp, i);
+
+ if (bp->num_rx_rings > 1) {
+ u32 tbl_32;
+ u8 *tbl = (u8 *) &tbl_32;
+
+ bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ,
+ BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES);
+
+ for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) {
+ tbl[i % 4] = i % (bp->num_rx_rings - 1);
+ if ((i % 4) == 3)
+ bnx2_reg_wr_ind(bp,
+ BNX2_RXP_SCRATCH_RSS_TBL + i,
+ cpu_to_be32(tbl_32));
+ }
+
+ val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI |
+ BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_ALL_XI;
+
+ REG_WR(bp, BNX2_RLUP_RSS_CONFIG, val);
+
+ }
}
static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size)
@@ -4750,12 +4904,12 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
u32 rx_size, rx_space, jumbo_size;
/* 8 for CRC and VLAN */
- rx_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
+ rx_size = bp->dev->mtu + ETH_HLEN + BNX2_RX_OFFSET + 8;
rx_space = SKB_DATA_ALIGN(rx_size + BNX2_RX_ALIGN) + NET_SKB_PAD +
sizeof(struct skb_shared_info);
- bp->rx_copy_thresh = RX_COPY_THRESH;
+ bp->rx_copy_thresh = BNX2_RX_COPY_THRESH;
bp->rx_pg_ring_size = 0;
bp->rx_max_pg_ring = 0;
bp->rx_max_pg_ring_idx = 0;
@@ -4770,14 +4924,14 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
bp->rx_max_pg_ring = bnx2_find_max_ring(jumbo_size,
MAX_RX_PG_RINGS);
bp->rx_max_pg_ring_idx = (bp->rx_max_pg_ring * RX_DESC_CNT) - 1;
- rx_size = RX_COPY_THRESH + bp->rx_offset;
+ rx_size = BNX2_RX_COPY_THRESH + BNX2_RX_OFFSET;
bp->rx_copy_thresh = 0;
}
bp->rx_buf_use_size = rx_size;
/* hw alignment */
bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
- bp->rx_jumbo_thresh = rx_size - bp->rx_offset;
+ bp->rx_jumbo_thresh = rx_size - BNX2_RX_OFFSET;
bp->rx_ring_size = size;
bp->rx_max_ring = bnx2_find_max_ring(size, MAX_RX_RINGS);
bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
@@ -4788,36 +4942,42 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
{
int i;
- if (bp->tx_buf_ring == NULL)
- return;
-
- for (i = 0; i < TX_DESC_CNT; ) {
- struct sw_bd *tx_buf = &bp->tx_buf_ring[i];
- struct sk_buff *skb = tx_buf->skb;
- int j, last;
+ for (i = 0; i < bp->num_tx_rings; i++) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
+ int j;
- if (skb == NULL) {
- i++;
+ if (txr->tx_buf_ring == NULL)
continue;
- }
- pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+ for (j = 0; j < TX_DESC_CNT; ) {
+ struct sw_bd *tx_buf = &txr->tx_buf_ring[j];
+ struct sk_buff *skb = tx_buf->skb;
+ int k, last;
+
+ if (skb == NULL) {
+ j++;
+ continue;
+ }
+
+ pci_unmap_single(bp->pdev,
+ pci_unmap_addr(tx_buf, mapping),
skb_headlen(skb), PCI_DMA_TODEVICE);
- tx_buf->skb = NULL;
+ tx_buf->skb = NULL;
- last = skb_shinfo(skb)->nr_frags;
- for (j = 0; j < last; j++) {
- tx_buf = &bp->tx_buf_ring[i + j + 1];
- pci_unmap_page(bp->pdev,
- pci_unmap_addr(tx_buf, mapping),
- skb_shinfo(skb)->frags[j].size,
- PCI_DMA_TODEVICE);
+ last = skb_shinfo(skb)->nr_frags;
+ for (k = 0; k < last; k++) {
+ tx_buf = &txr->tx_buf_ring[j + k + 1];
+ pci_unmap_page(bp->pdev,
+ pci_unmap_addr(tx_buf, mapping),
+ skb_shinfo(skb)->frags[j].size,
+ PCI_DMA_TODEVICE);
+ }
+ dev_kfree_skb(skb);
+ j += k + 1;
}
- dev_kfree_skb(skb);
- i += j + 1;
}
-
}
static void
@@ -4825,25 +4985,33 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
{
int i;
- if (bp->rx_buf_ring == NULL)
- return;
+ for (i = 0; i < bp->num_rx_rings; i++) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
+ int j;
- for (i = 0; i < bp->rx_max_ring_idx; i++) {
- struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
- struct sk_buff *skb = rx_buf->skb;
+ if (rxr->rx_buf_ring == NULL)
+ return;
- if (skb == NULL)
- continue;
+ for (j = 0; j < bp->rx_max_ring_idx; j++) {
+ struct sw_bd *rx_buf = &rxr->rx_buf_ring[j];
+ struct sk_buff *skb = rx_buf->skb;
- pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+ if (skb == NULL)
+ continue;
- rx_buf->skb = NULL;
+ pci_unmap_single(bp->pdev,
+ pci_unmap_addr(rx_buf, mapping),
+ bp->rx_buf_use_size,
+ PCI_DMA_FROMDEVICE);
- dev_kfree_skb(skb);
+ rx_buf->skb = NULL;
+
+ dev_kfree_skb(skb);
+ }
+ for (j = 0; j < bp->rx_max_pg_ring_idx; j++)
+ bnx2_free_rx_page(bp, rxr, j);
}
- for (i = 0; i < bp->rx_max_pg_ring_idx; i++)
- bnx2_free_rx_page(bp, i);
}
static void
@@ -4866,14 +5034,12 @@ bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
if ((rc = bnx2_init_chip(bp)) != 0)
return rc;
- bnx2_clear_ring_states(bp);
- bnx2_init_tx_ring(bp);
- bnx2_init_rx_ring(bp);
+ bnx2_init_all_rings(bp);
return 0;
}
static int
-bnx2_init_nic(struct bnx2 *bp)
+bnx2_init_nic(struct bnx2 *bp, int reset_phy)
{
int rc;
@@ -4881,7 +5047,7 @@ bnx2_init_nic(struct bnx2 *bp)
return rc;
spin_lock_bh(&bp->phy_lock);
- bnx2_init_phy(bp);
+ bnx2_init_phy(bp, reset_phy);
bnx2_set_link(bp);
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
bnx2_remote_phy_event(bp);
@@ -5141,11 +5307,13 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
struct l2_fhdr *rx_hdr;
int ret = -ENODEV;
struct bnx2_napi *bnapi = &bp->bnx2_napi[0], *tx_napi;
+ struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
+ struct bnx2_rx_ring_info *rxr = &bnapi->rx_ring;
tx_napi = bnapi;
- if (bp->flags & BNX2_FLAG_USING_MSIX)
- tx_napi = &bp->bnx2_napi[BNX2_TX_VEC];
+ txr = &tx_napi->tx_ring;
+ rxr = &bnapi->rx_ring;
if (loopback_mode == BNX2_MAC_LOOPBACK) {
bp->loopback = MAC_LOOPBACK;
bnx2_set_mac_loopback(bp);
@@ -5183,7 +5351,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
num_pkts = 0;
- txbd = &bp->tx_desc_ring[TX_RING_IDX(bp->tx_prod)];
+ txbd = &txr->tx_desc_ring[TX_RING_IDX(txr->tx_prod)];
txbd->tx_bd_haddr_hi = (u64) map >> 32;
txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff;
@@ -5191,11 +5359,11 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
num_pkts++;
- bp->tx_prod = NEXT_TX_BD(bp->tx_prod);
- bp->tx_prod_bseq += pkt_size;
+ txr->tx_prod = NEXT_TX_BD(txr->tx_prod);
+ txr->tx_prod_bseq += pkt_size;
- REG_WR16(bp, bp->tx_bidx_addr, bp->tx_prod);
- REG_WR(bp, bp->tx_bseq_addr, bp->tx_prod_bseq);
+ REG_WR16(bp, txr->tx_bidx_addr, txr->tx_prod);
+ REG_WR(bp, txr->tx_bseq_addr, txr->tx_prod_bseq);
udelay(100);
@@ -5209,7 +5377,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
- if (bnx2_get_hw_tx_cons(tx_napi) != bp->tx_prod)
+ if (bnx2_get_hw_tx_cons(tx_napi) != txr->tx_prod)
goto loopback_test_done;
rx_idx = bnx2_get_hw_rx_cons(bnapi);
@@ -5217,11 +5385,11 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
goto loopback_test_done;
}
- rx_buf = &bp->rx_buf_ring[rx_start_idx];
+ rx_buf = &rxr->rx_buf_ring[rx_start_idx];
rx_skb = rx_buf->skb;
rx_hdr = (struct l2_fhdr *) rx_skb->data;
- skb_reserve(rx_skb, bp->rx_offset);
+ skb_reserve(rx_skb, BNX2_RX_OFFSET);
pci_dma_sync_single_for_cpu(bp->pdev,
pci_unmap_addr(rx_buf, mapping),
@@ -5269,7 +5437,7 @@ bnx2_test_loopback(struct bnx2 *bp)
bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
spin_lock_bh(&bp->phy_lock);
- bnx2_init_phy(bp);
+ bnx2_init_phy(bp, 1);
spin_unlock_bh(&bp->phy_lock);
if (bnx2_run_loopback(bp, BNX2_MAC_LOOPBACK))
rc |= BNX2_MAC_LOOPBACK_FAILED;
@@ -5531,7 +5699,6 @@ bnx2_restart_timer:
static int
bnx2_request_irq(struct bnx2 *bp)
{
- struct net_device *dev = bp->dev;
unsigned long flags;
struct bnx2_irq *irq;
int rc = 0, i;
@@ -5544,7 +5711,7 @@ bnx2_request_irq(struct bnx2 *bp)
for (i = 0; i < bp->irq_nvecs; i++) {
irq = &bp->irq_tbl[i];
rc = request_irq(irq->vector, irq->handler, flags, irq->name,
- dev);
+ &bp->bnx2_napi[i]);
if (rc)
break;
irq->requested = 1;
@@ -5555,14 +5722,13 @@ bnx2_request_irq(struct bnx2 *bp)
static void
bnx2_free_irq(struct bnx2 *bp)
{
- struct net_device *dev = bp->dev;
struct bnx2_irq *irq;
int i;
for (i = 0; i < bp->irq_nvecs; i++) {
irq = &bp->irq_tbl[i];
if (irq->requested)
- free_irq(irq->vector, dev);
+ free_irq(irq->vector, &bp->bnx2_napi[i]);
irq->requested = 0;
}
if (bp->flags & BNX2_FLAG_USING_MSI)
@@ -5574,7 +5740,7 @@ bnx2_free_irq(struct bnx2 *bp)
}
static void
-bnx2_enable_msix(struct bnx2 *bp)
+bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
{
int i, rc;
struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
@@ -5587,21 +5753,16 @@ bnx2_enable_msix(struct bnx2 *bp)
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
msix_ent[i].entry = i;
msix_ent[i].vector = 0;
+
+ strcpy(bp->irq_tbl[i].name, bp->dev->name);
+ bp->irq_tbl[i].handler = bnx2_msi_1shot;
}
rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
if (rc != 0)
return;
- bp->irq_tbl[BNX2_BASE_VEC].handler = bnx2_msi_1shot;
- bp->irq_tbl[BNX2_TX_VEC].handler = bnx2_tx_msix;
-
- strcpy(bp->irq_tbl[BNX2_BASE_VEC].name, bp->dev->name);
- strcat(bp->irq_tbl[BNX2_BASE_VEC].name, "-base");
- strcpy(bp->irq_tbl[BNX2_TX_VEC].name, bp->dev->name);
- strcat(bp->irq_tbl[BNX2_TX_VEC].name, "-tx");
-
- bp->irq_nvecs = BNX2_MAX_MSIX_VEC;
+ bp->irq_nvecs = msix_vecs;
bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
bp->irq_tbl[i].vector = msix_ent[i].vector;
@@ -5610,13 +5771,16 @@ bnx2_enable_msix(struct bnx2 *bp)
static void
bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
{
+ int cpus = num_online_cpus();
+ int msix_vecs = min(cpus + 1, RX_MAX_RINGS);
+
bp->irq_tbl[0].handler = bnx2_interrupt;
strcpy(bp->irq_tbl[0].name, bp->dev->name);
bp->irq_nvecs = 1;
bp->irq_tbl[0].vector = bp->pdev->irq;
- if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi)
- bnx2_enable_msix(bp);
+ if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi && cpus > 1)
+ bnx2_enable_msix(bp, msix_vecs);
if ((bp->flags & BNX2_FLAG_MSI_CAP) && !dis_msi &&
!(bp->flags & BNX2_FLAG_USING_MSIX)) {
@@ -5631,6 +5795,11 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
bp->irq_tbl[0].vector = bp->pdev->irq;
}
}
+
+ bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
+ bp->dev->real_num_tx_queues = bp->num_tx_rings;
+
+ bp->num_rx_rings = bp->irq_nvecs;
}
/* Called with rtnl_lock */
@@ -5645,29 +5814,19 @@ bnx2_open(struct net_device *dev)
bnx2_set_power_state(bp, PCI_D0);
bnx2_disable_int(bp);
+ bnx2_setup_int_mode(bp, disable_msi);
+ bnx2_napi_enable(bp);
rc = bnx2_alloc_mem(bp);
if (rc)
- return rc;
+ goto open_err;
- bnx2_setup_int_mode(bp, disable_msi);
- bnx2_napi_enable(bp);
rc = bnx2_request_irq(bp);
+ if (rc)
+ goto open_err;
- if (rc) {
- bnx2_napi_disable(bp);
- bnx2_free_mem(bp);
- return rc;
- }
-
- rc = bnx2_init_nic(bp);
-
- if (rc) {
- bnx2_napi_disable(bp);
- bnx2_free_irq(bp);
- bnx2_free_skbs(bp);
- bnx2_free_mem(bp);
- return rc;
- }
+ rc = bnx2_init_nic(bp, 1);
+ if (rc)
+ goto open_err;
mod_timer(&bp->timer, jiffies + bp->current_interval);
@@ -5691,17 +5850,14 @@ bnx2_open(struct net_device *dev)
bnx2_setup_int_mode(bp, 1);
- rc = bnx2_init_nic(bp);
+ rc = bnx2_init_nic(bp, 0);
if (!rc)
rc = bnx2_request_irq(bp);
if (rc) {
- bnx2_napi_disable(bp);
- bnx2_free_skbs(bp);
- bnx2_free_mem(bp);
del_timer_sync(&bp->timer);
- return rc;
+ goto open_err;
}
bnx2_enable_int(bp);
}
@@ -5711,9 +5867,16 @@ bnx2_open(struct net_device *dev)
else if (bp->flags & BNX2_FLAG_USING_MSIX)
printk(KERN_INFO PFX "%s: using MSIX\n", dev->name);
- netif_start_queue(dev);
+ netif_tx_start_all_queues(dev);
return 0;
+
+open_err:
+ bnx2_napi_disable(bp);
+ bnx2_free_skbs(bp);
+ bnx2_free_irq(bp);
+ bnx2_free_mem(bp);
+ return rc;
}
static void
@@ -5726,7 +5889,7 @@ bnx2_reset_task(struct work_struct *work)
bnx2_netif_stop(bp);
- bnx2_init_nic(bp);
+ bnx2_init_nic(bp, 1);
atomic_set(&bp->intr_sem, 1);
bnx2_netif_start(bp);
@@ -5752,6 +5915,8 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
bp->vlgrp = vlgrp;
bnx2_set_rx_mode(dev);
+ if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
+ bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
bnx2_netif_start(bp);
}
@@ -5771,18 +5936,26 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 len, vlan_tag_flags, last_frag, mss;
u16 prod, ring_prod;
int i;
- struct bnx2_napi *bnapi = &bp->bnx2_napi[bp->tx_vec];
+ struct bnx2_napi *bnapi;
+ struct bnx2_tx_ring_info *txr;
+ struct netdev_queue *txq;
- if (unlikely(bnx2_tx_avail(bp, bnapi) <
+ /* Determine which tx ring we will be placed on */
+ i = skb_get_queue_mapping(skb);
+ bnapi = &bp->bnx2_napi[i];
+ txr = &bnapi->tx_ring;
+ txq = netdev_get_tx_queue(dev, i);
+
+ if (unlikely(bnx2_tx_avail(bp, txr) <
(skb_shinfo(skb)->nr_frags + 1))) {
- netif_stop_queue(dev);
+ netif_tx_stop_queue(txq);
printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
dev->name);
return NETDEV_TX_BUSY;
}
len = skb_headlen(skb);
- prod = bp->tx_prod;
+ prod = txr->tx_prod;
ring_prod = TX_RING_IDX(prod);
vlan_tag_flags = 0;
@@ -5844,11 +6017,11 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
- tx_buf = &bp->tx_buf_ring[ring_prod];
+ tx_buf = &txr->tx_buf_ring[ring_prod];
tx_buf->skb = skb;
pci_unmap_addr_set(tx_buf, mapping, mapping);
- txbd = &bp->tx_desc_ring[ring_prod];
+ txbd = &txr->tx_desc_ring[ring_prod];
txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
@@ -5862,12 +6035,12 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
prod = NEXT_TX_BD(prod);
ring_prod = TX_RING_IDX(prod);
- txbd = &bp->tx_desc_ring[ring_prod];
+ txbd = &txr->tx_desc_ring[ring_prod];
len = frag->size;
mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
len, PCI_DMA_TODEVICE);
- pci_unmap_addr_set(&bp->tx_buf_ring[ring_prod],
+ pci_unmap_addr_set(&txr->tx_buf_ring[ring_prod],
mapping, mapping);
txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
@@ -5879,20 +6052,20 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END;
prod = NEXT_TX_BD(prod);
- bp->tx_prod_bseq += skb->len;
+ txr->tx_prod_bseq += skb->len;
- REG_WR16(bp, bp->tx_bidx_addr, prod);
- REG_WR(bp, bp->tx_bseq_addr, bp->tx_prod_bseq);
+ REG_WR16(bp, txr->tx_bidx_addr, prod);
+ REG_WR(bp, txr->tx_bseq_addr, txr->tx_prod_bseq);
mmiowb();
- bp->tx_prod = prod;
+ txr->tx_prod = prod;
dev->trans_start = jiffies;
- if (unlikely(bnx2_tx_avail(bp, bnapi) <= MAX_SKB_FRAGS)) {
- netif_stop_queue(dev);
- if (bnx2_tx_avail(bp, bnapi) > bp->tx_wake_thresh)
- netif_wake_queue(dev);
+ if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) {
+ netif_tx_stop_queue(txq);
+ if (bnx2_tx_avail(bp, txr) > bp->tx_wake_thresh)
+ netif_tx_wake_queue(txq);
}
return NETDEV_TX_OK;
@@ -6095,6 +6268,12 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
!(bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP))
goto err_out_unlock;
+ /* If device is down, we can store the settings only if the user
+ * is setting the currently active port.
+ */
+ if (!netif_running(dev) && cmd->port != bp->phy_port)
+ goto err_out_unlock;
+
if (cmd->autoneg == AUTONEG_ENABLE) {
autoneg |= AUTONEG_SPEED;
@@ -6152,7 +6331,12 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
bp->req_line_speed = req_line_speed;
bp->req_duplex = req_duplex;
- err = bnx2_setup_phy(bp, cmd->port);
+ err = 0;
+ /* If device is down, the new settings will be picked up when it is
+ * brought up.
+ */
+ if (netif_running(dev))
+ err = bnx2_setup_phy(bp, cmd->port);
err_out_unlock:
spin_unlock_bh(&bp->phy_lock);
@@ -6414,7 +6598,7 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
if (netif_running(bp->dev)) {
bnx2_netif_stop(bp);
- bnx2_init_nic(bp);
+ bnx2_init_nic(bp, 0);
bnx2_netif_start(bp);
}
@@ -6457,7 +6641,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
rc = bnx2_alloc_mem(bp);
if (rc)
return rc;
- bnx2_init_nic(bp);
+ bnx2_init_nic(bp, 0);
bnx2_netif_start(bp);
}
return 0;
@@ -6725,7 +6909,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
}
else {
- bnx2_init_nic(bp);
+ bnx2_init_nic(bp, 1);
bnx2_netif_start(bp);
}
@@ -6951,7 +7135,7 @@ bnx2_change_mac_addr(struct net_device *dev, void *p)
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
if (netif_running(dev))
- bnx2_set_mac_addr(bp);
+ bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
return 0;
}
@@ -7108,6 +7292,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
}
pci_set_master(pdev);
+ pci_save_state(pdev);
bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
if (bp->pm_cap == 0) {
@@ -7125,7 +7310,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
INIT_WORK(&bp->reset_task, bnx2_reset_task);
dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
- mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1);
+ mem_len = MB_GET_CID_ADDR(TX_TSS_CID + TX_MAX_TSS_RINGS);
dev->mem_end = dev->mem_start + mem_len;
dev->irq = pdev->irq;
@@ -7272,7 +7457,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
reg &= BNX2_CONDITION_MFW_RUN_MASK;
if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN &&
reg != BNX2_CONDITION_MFW_RUN_NONE) {
- int i;
u32 addr = bnx2_shmem_rd(bp, BNX2_MFW_VER_PTR);
bp->fw_version[j++] = ' ';
@@ -7294,8 +7478,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->mac_addr[4] = (u8) (reg >> 8);
bp->mac_addr[5] = (u8) reg;
- bp->rx_offset = sizeof(struct l2_fhdr) + 2;
-
bp->tx_ring_size = MAX_TX_DESC_CNT;
bnx2_set_rx_ring_size(bp, 255);
@@ -7345,8 +7527,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE;
}
- bnx2_init_remote_phy(bp);
-
} else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
CHIP_NUM(bp) == CHIP_NUM_5708)
bp->phy_flags |= BNX2_PHY_FLAG_CRC_FIX;
@@ -7355,6 +7535,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
CHIP_REV(bp) == CHIP_REV_Bx))
bp->phy_flags |= BNX2_PHY_FLAG_DIS_EARLY_DAC;
+ bnx2_init_fw_cap(bp);
+
if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
(CHIP_ID(bp) == CHIP_ID_5708_B0) ||
(CHIP_ID(bp) == CHIP_ID_5708_B1)) {
@@ -7451,15 +7633,19 @@ static void __devinit
bnx2_init_napi(struct bnx2 *bp)
{
int i;
- struct bnx2_napi *bnapi;
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
- bnapi = &bp->bnx2_napi[i];
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+ int (*poll)(struct napi_struct *, int);
+
+ if (i == 0)
+ poll = bnx2_poll;
+ else
+ poll = bnx2_poll_msix;
+
+ netif_napi_add(bp->dev, &bp->bnx2_napi[i].napi, poll, 64);
bnapi->bp = bp;
}
- netif_napi_add(bp->dev, &bp->bnx2_napi[0].napi, bnx2_poll, 64);
- netif_napi_add(bp->dev, &bp->bnx2_napi[BNX2_TX_VEC].napi, bnx2_tx_poll,
- 64);
}
static int __devinit
@@ -7476,7 +7662,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_INFO "%s", version);
/* dev zeroed in init_etherdev */
- dev = alloc_etherdev(sizeof(*bp));
+ dev = alloc_etherdev_mq(sizeof(*bp), TX_MAX_RINGS);
if (!dev)
return -ENOMEM;
@@ -7491,7 +7677,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->hard_start_xmit = bnx2_start_xmit;
dev->stop = bnx2_close;
dev->get_stats = bnx2_get_stats;
- dev->set_multicast_list = bnx2_set_rx_mode;
+ dev->set_rx_mode = bnx2_set_rx_mode;
dev->do_ioctl = bnx2_ioctl;
dev->set_mac_address = bnx2_change_mac_addr;
dev->change_mtu = bnx2_change_mtu;
@@ -7612,11 +7798,97 @@ bnx2_resume(struct pci_dev *pdev)
bnx2_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
- bnx2_init_nic(bp);
+ bnx2_init_nic(bp, 1);
bnx2_netif_start(bp);
return 0;
}
+/**
+ * bnx2_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2 *bp = netdev_priv(dev);
+
+ rtnl_lock();
+ netif_device_detach(dev);
+
+ if (netif_running(dev)) {
+ bnx2_netif_stop(bp);
+ del_timer_sync(&bp->timer);
+ bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
+ }
+
+ pci_disable_device(pdev);
+ rtnl_unlock();
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * bnx2_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ */
+static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2 *bp = netdev_priv(dev);
+
+ rtnl_lock();
+ if (pci_enable_device(pdev)) {
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset.\n");
+ rtnl_unlock();
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
+
+ if (netif_running(dev)) {
+ bnx2_set_power_state(bp, PCI_D0);
+ bnx2_init_nic(bp, 1);
+ }
+
+ rtnl_unlock();
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * bnx2_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation.
+ */
+static void bnx2_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2 *bp = netdev_priv(dev);
+
+ rtnl_lock();
+ if (netif_running(dev))
+ bnx2_netif_start(bp);
+
+ netif_device_attach(dev);
+ rtnl_unlock();
+}
+
+static struct pci_error_handlers bnx2_err_handler = {
+ .error_detected = bnx2_io_error_detected,
+ .slot_reset = bnx2_io_slot_reset,
+ .resume = bnx2_io_resume,
+};
+
static struct pci_driver bnx2_pci_driver = {
.name = DRV_MODULE_NAME,
.id_table = bnx2_pci_tbl,
@@ -7624,6 +7896,7 @@ static struct pci_driver bnx2_pci_driver = {
.remove = __devexit_p(bnx2_remove_one),
.suspend = bnx2_suspend,
.resume = bnx2_resume,
+ .err_handler = &bnx2_err_handler,
};
static int __init bnx2_init(void)
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 2377cc13bf6..c3c579f98ed 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -309,6 +309,7 @@ struct l2_fhdr {
#endif
};
+#define BNX2_RX_OFFSET (sizeof(struct l2_fhdr) + 2)
/*
* l2_context definition
@@ -4157,6 +4158,23 @@ struct l2_fhdr {
/*
+ * rlup_reg definition
+ * offset: 0x2000
+ */
+#define BNX2_RLUP_RSS_CONFIG 0x0000201c
+#define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_XI (0x3L<<0)
+#define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_OFF_XI (0L<<0)
+#define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI (1L<<0)
+#define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_IP_ONLY_XI (2L<<0)
+#define BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_RES_XI (3L<<0)
+#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_XI (0x3L<<2)
+#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_OFF_XI (0L<<2)
+#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_ALL_XI (1L<<2)
+#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_IP_ONLY_XI (2L<<2)
+#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_RES_XI (3L<<2)
+
+
+/*
* rbuf_reg definition
* offset: 0x200000
*/
@@ -5527,6 +5545,9 @@ struct l2_fhdr {
#define BNX2_HC_TX_QUICK_CONS_TRIP_OFF (BNX2_HC_TX_QUICK_CONS_TRIP_1 - \
BNX2_HC_SB_CONFIG_1)
#define BNX2_HC_TX_TICKS_OFF (BNX2_HC_TX_TICKS_1 - BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_RX_QUICK_CONS_TRIP_OFF (BNX2_HC_RX_QUICK_CONS_TRIP_1 - \
+ BNX2_HC_SB_CONFIG_1)
+#define BNX2_HC_RX_TICKS_OFF (BNX2_HC_RX_TICKS_1 - BNX2_HC_SB_CONFIG_1)
/*
@@ -5855,6 +5876,9 @@ struct l2_fhdr {
#define BNX2_RXP_FTQ_CTL_CUR_DEPTH (0x3ffL<<22)
#define BNX2_RXP_SCRATCH 0x000e0000
+#define BNX2_RXP_SCRATCH_RSS_TBL_SZ 0x000e0038
+#define BNX2_RXP_SCRATCH_RSS_TBL 0x000e003c
+#define BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES 128
/*
@@ -6412,10 +6436,15 @@ struct l2_fhdr {
#define MAX_ETHERNET_PACKET_SIZE 1514
#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
-#define RX_COPY_THRESH 128
+#define BNX2_RX_COPY_THRESH 128
#define BNX2_MISC_ENABLE_DEFAULT 0x17ffffff
+#define BNX2_START_UNICAST_ADDRESS_INDEX 4
+#define BNX2_END_UNICAST_ADDRESS_INDEX 7
+#define BNX2_MAX_UNICAST_ADDRESSES (BNX2_END_UNICAST_ADDRESS_INDEX - \
+ BNX2_START_UNICAST_ADDRESS_INDEX + 1)
+
#define DMA_READ_CHANS 5
#define DMA_WRITE_CHANS 3
@@ -6478,6 +6507,11 @@ struct l2_fhdr {
#define TX_CID 16
#define TX_TSS_CID 32
#define RX_CID 0
+#define RX_RSS_CID 4
+#define RX_MAX_RSS_RINGS 7
+#define RX_MAX_RINGS (RX_MAX_RSS_RINGS + 1)
+#define TX_MAX_TSS_RINGS 7
+#define TX_MAX_RINGS (TX_MAX_TSS_RINGS + 1)
#define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID)
#define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID)
@@ -6556,7 +6590,7 @@ struct flash_spec {
};
#define BNX2_MAX_MSIX_HW_VEC 9
-#define BNX2_MAX_MSIX_VEC 2
+#define BNX2_MAX_MSIX_VEC 9
#define BNX2_BASE_VEC 0
#define BNX2_TX_VEC 1
#define BNX2_TX_INT_NUM (BNX2_TX_VEC << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT)
@@ -6568,24 +6602,56 @@ struct bnx2_irq {
char name[16];
};
-struct bnx2_napi {
- struct napi_struct napi ____cacheline_aligned;
- struct bnx2 *bp;
- struct status_block *status_blk;
- struct status_block_msix *status_blk_msix;
- u32 last_status_idx;
- u32 int_num;
+struct bnx2_tx_ring_info {
+ u32 tx_prod_bseq;
+ u16 tx_prod;
+ u32 tx_bidx_addr;
+ u32 tx_bseq_addr;
+
+ struct tx_bd *tx_desc_ring;
+ struct sw_bd *tx_buf_ring;
u16 tx_cons;
u16 hw_tx_cons;
+ dma_addr_t tx_desc_mapping;
+};
+
+struct bnx2_rx_ring_info {
u32 rx_prod_bseq;
u16 rx_prod;
u16 rx_cons;
+ u32 rx_bidx_addr;
+ u32 rx_bseq_addr;
+ u32 rx_pg_bidx_addr;
+
u16 rx_pg_prod;
u16 rx_pg_cons;
+ struct sw_bd *rx_buf_ring;
+ struct rx_bd *rx_desc_ring[MAX_RX_RINGS];
+ struct sw_pg *rx_pg_ring;
+ struct rx_bd *rx_pg_desc_ring[MAX_RX_PG_RINGS];
+
+ dma_addr_t rx_desc_mapping[MAX_RX_RINGS];
+ dma_addr_t rx_pg_desc_mapping[MAX_RX_PG_RINGS];
+};
+
+struct bnx2_napi {
+ struct napi_struct napi ____cacheline_aligned;
+ struct bnx2 *bp;
+ union {
+ struct status_block *msi;
+ struct status_block_msix *msix;
+ } status_blk;
+ u16 *hw_tx_cons_ptr;
+ u16 *hw_rx_cons_ptr;
+ u32 last_status_idx;
+ u32 int_num;
+
+ struct bnx2_rx_ring_info rx_ring;
+ struct bnx2_tx_ring_info tx_ring;
};
struct bnx2 {
@@ -6612,14 +6678,7 @@ struct bnx2 {
#define BNX2_FLAG_USING_MSI_OR_MSIX (BNX2_FLAG_USING_MSI | \
BNX2_FLAG_USING_MSIX)
#define BNX2_FLAG_JUMBO_BROKEN 0x00000800
-
- /* Put tx producer and consumer fields in separate cache lines. */
-
- u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES)));
- u16 tx_prod;
- u8 tx_vec;
- u32 tx_bidx_addr;
- u32 tx_bseq_addr;
+#define BNX2_FLAG_CAN_KEEP_VLAN 0x00001000
struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC];
@@ -6627,7 +6686,6 @@ struct bnx2 {
struct vlan_group *vlgrp;
#endif
- u32 rx_offset;
u32 rx_buf_use_size; /* useable size */
u32 rx_buf_size; /* with alignment */
u32 rx_copy_thresh;
@@ -6637,14 +6695,7 @@ struct bnx2 {
u32 rx_csum;
- struct sw_bd *rx_buf_ring;
- struct rx_bd *rx_desc_ring[MAX_RX_RINGS];
- struct sw_pg *rx_pg_ring;
- struct rx_bd *rx_pg_desc_ring[MAX_RX_PG_RINGS];
-
/* TX constants */
- struct tx_bd *tx_desc_ring;
- struct sw_bd *tx_buf_ring;
int tx_ring_size;
u32 tx_wake_thresh;
@@ -6722,16 +6773,11 @@ struct bnx2 {
u16 fw_wr_seq;
u16 fw_drv_pulse_wr_seq;
- dma_addr_t tx_desc_mapping;
-
-
int rx_max_ring;
int rx_ring_size;
- dma_addr_t rx_desc_mapping[MAX_RX_RINGS];
int rx_max_pg_ring;
int rx_pg_ring_size;
- dma_addr_t rx_pg_desc_mapping[MAX_RX_PG_RINGS];
u16 tx_quick_cons_trip;
u16 tx_quick_cons_trip_int;
@@ -6750,7 +6796,6 @@ struct bnx2 {
u32 stats_ticks;
- struct status_block *status_blk;
dma_addr_t status_blk_mapping;
struct statistics_block *stats_blk;
@@ -6812,6 +6857,9 @@ struct bnx2 {
struct bnx2_irq irq_tbl[BNX2_MAX_MSIX_VEC];
int irq_nvecs;
+
+ u8 num_tx_rings;
+ u8 num_rx_rings;
};
#define REG_RD(bp, offset) \
@@ -6912,6 +6960,7 @@ struct fw_info {
#define BNX2_DRV_MSG_CODE_DIAG 0x07000000
#define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL 0x09000000
#define BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN 0x0b000000
+#define BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE 0x0d000000
#define BNX2_DRV_MSG_CODE_CMD_SET_LINK 0x10000000
#define BNX2_DRV_MSG_DATA 0x00ff0000
@@ -7240,6 +7289,10 @@ struct fw_info {
#define BNX2_FW_CAP_SIGNATURE_MASK 0xffff0000
#define BNX2_FW_CAP_REMOTE_PHY_CAPABLE 0x00000001
#define BNX2_FW_CAP_REMOTE_PHY_PRESENT 0x00000002
+#define BNX2_FW_CAP_MFW_CAN_KEEP_VLAN 0x00000008
+#define BNX2_FW_CAP_BC_CAN_KEEP_VLAN 0x00000010
+#define BNX2_FW_CAP_CAN_KEEP_VLAN (BNX2_FW_CAP_BC_CAN_KEEP_VLAN | \
+ BNX2_FW_CAP_MFW_CAN_KEEP_VLAN)
#define BNX2_RPHY_SIGNATURE 0x36c
#define BNX2_RPHY_LOAD_SIGNATURE 0x5a5a5a5a
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 3b839d4626f..e4b1de43556 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -886,6 +886,23 @@ static struct fw_info bnx2_com_fw_06 = {
.rodata = bnx2_COM_b06FwRodata,
};
+/* Initialized Values for the Completion Processor. */
+static const struct cpu_reg cpu_reg_com = {
+ .mode = BNX2_COM_CPU_MODE,
+ .mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA,
+ .state = BNX2_COM_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_COM_CPU_REG_FILE,
+ .evmask = BNX2_COM_CPU_EVENT_MASK,
+ .pc = BNX2_COM_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_COM_CPU_INSTRUCTION,
+ .bp = BNX2_COM_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_COM_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
+
static u8 bnx2_CP_b06FwText[] = {
0x9d, 0xbc, 0x0d, 0x78, 0x13, 0xe7, 0x99, 0x2e, 0x7c, 0xcf, 0x48, 0xb2,
0x65, 0x5b, 0xb6, 0xc7, 0xb6, 0x0c, 0x22, 0x65, 0x41, 0x83, 0x47, 0x20,
@@ -2167,6 +2184,22 @@ static struct fw_info bnx2_cp_fw_06 = {
.rodata = bnx2_CP_b06FwRodata,
};
+/* Initialized Values the Command Processor. */
+static const struct cpu_reg cpu_reg_cp = {
+ .mode = BNX2_CP_CPU_MODE,
+ .mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA,
+ .state = BNX2_CP_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_CP_CPU_REG_FILE,
+ .evmask = BNX2_CP_CPU_EVENT_MASK,
+ .pc = BNX2_CP_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_CP_CPU_INSTRUCTION,
+ .bp = BNX2_CP_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_CP_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
static u8 bnx2_RXP_b06FwText[] = {
0xec, 0x5b, 0x5d, 0x70, 0x5c, 0xd7, 0x5d, 0xff, 0xdf, 0xb3, 0x2b, 0x69,
0x2d, 0x4b, 0xf2, 0x95, 0xbc, 0x71, 0x56, 0xa9, 0x92, 0xec, 0x5a, 0x57,
@@ -2946,6 +2979,22 @@ static struct fw_info bnx2_rxp_fw_06 = {
.rodata = bnx2_RXP_b06FwRodata,
};
+/* Initialized Values for the RX Processor. */
+static const struct cpu_reg cpu_reg_rxp = {
+ .mode = BNX2_RXP_CPU_MODE,
+ .mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA,
+ .state = BNX2_RXP_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_RXP_CPU_REG_FILE,
+ .evmask = BNX2_RXP_CPU_EVENT_MASK,
+ .pc = BNX2_RXP_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_RXP_CPU_INSTRUCTION,
+ .bp = BNX2_RXP_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_RXP_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
static u8 bnx2_rv2p_proc1[] = {
/* Date: 12/07/2007 15:02 */
0xd5, 0x56, 0x41, 0x6b, 0x13, 0x51, 0x10, 0x9e, 0xdd, 0x6c, 0xbb, 0xdb,
@@ -3651,6 +3700,22 @@ static struct fw_info bnx2_tpat_fw_06 = {
.rodata = bnx2_TPAT_b06FwRodata,
};
+/* Initialized Values for the TX Patch-up Processor. */
+static const struct cpu_reg cpu_reg_tpat = {
+ .mode = BNX2_TPAT_CPU_MODE,
+ .mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA,
+ .state = BNX2_TPAT_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_TPAT_CPU_REG_FILE,
+ .evmask = BNX2_TPAT_CPU_EVENT_MASK,
+ .pc = BNX2_TPAT_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_TPAT_CPU_INSTRUCTION,
+ .bp = BNX2_TPAT_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_TPAT_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
static u8 bnx2_TXP_b06FwText[] = {
0xad, 0x7b, 0x7f, 0x70, 0x9b, 0x75, 0x7a, 0xe7, 0xe7, 0xd5, 0x0f, 0x5b,
0xb2, 0x65, 0x59, 0x0e, 0x4a, 0x90, 0x77, 0xbd, 0x8d, 0x5e, 0xf4, 0xca,
@@ -4531,3 +4596,18 @@ static struct fw_info bnx2_txp_fw_06 = {
.rodata = bnx2_TXP_b06FwRodata,
};
+/* Initialized Values for the TX Processor. */
+static const struct cpu_reg cpu_reg_txp = {
+ .mode = BNX2_TXP_CPU_MODE,
+ .mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA,
+ .state = BNX2_TXP_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_TXP_CPU_REG_FILE,
+ .evmask = BNX2_TXP_CPU_EVENT_MASK,
+ .pc = BNX2_TXP_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_TXP_CPU_INSTRUCTION,
+ .bp = BNX2_TXP_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_TXP_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
index ed0514cba0e..fe753b6bcb4 100644
--- a/drivers/net/bnx2_fw2.h
+++ b/drivers/net/bnx2_fw2.h
@@ -15,842 +15,848 @@
*/
static u8 bnx2_COM_b09FwText[] = {
- 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x95, 0xde, 0x79, 0x6f, 0x1e, 0xc9,
- 0xe1, 0x88, 0xa2, 0x1e, 0xe9, 0x31, 0x3d, 0x8e, 0xb9, 0xc9, 0x0c, 0xe7,
- 0x91, 0xa2, 0x4d, 0x26, 0xfb, 0xcc, 0x8e, 0x6d, 0x3a, 0x99, 0xb5, 0xc6,
- 0x33, 0x94, 0xad, 0xc4, 0x8c, 0x41, 0x3b, 0xca, 0xd6, 0x28, 0xdc, 0x80,
- 0x1d, 0x52, 0x8e, 0xb3, 0x75, 0xbb, 0x8e, 0x1b, 0xa4, 0x89, 0x11, 0x44,
- 0x93, 0x21, 0xa5, 0x55, 0x82, 0x21, 0x67, 0x22, 0xd3, 0xdc, 0xfc, 0xb1,
- 0x68, 0xc6, 0x43, 0x52, 0x71, 0xb6, 0x23, 0xd1, 0x4e, 0xb2, 0x41, 0x16,
- 0xd8, 0xc0, 0x2c, 0x25, 0xcb, 0xc2, 0x22, 0x2d, 0xdc, 0x34, 0x28, 0x82,
- 0xec, 0xfe, 0x21, 0xc8, 0xce, 0xc6, 0x29, 0xd2, 0xc2, 0xed, 0x06, 0x8d,
- 0x37, 0x48, 0xf2, 0xfa, 0x7d, 0xf7, 0xde, 0x37, 0x1a, 0x8d, 0x68, 0x27,
- 0xdd, 0xfe, 0x53, 0x02, 0x83, 0xfb, 0xde, 0xfd, 0x79, 0xee, 0xb9, 0xe7,
- 0x9e, 0xf3, 0x9d, 0x73, 0xef, 0xe3, 0x3d, 0x22, 0x31, 0x31, 0x7f, 0xfb,
- 0xf1, 0xcb, 0xfc, 0xab, 0x3f, 0x5e, 0xb8, 0xe3, 0x7d, 0xfe, 0xfb, 0xf8,
- 0x6e, 0x77, 0x89, 0xc3, 0x34, 0x82, 0x5f, 0x1c, 0xbf, 0x29, 0xf3, 0xbc,
- 0xd7, 0x9f, 0x8b, 0xdf, 0x9d, 0x96, 0xc8, 0xfc, 0x7f, 0x13, 0xb1, 0x3a,
- 0xca, 0xa2, 0x7b, 0xd4, 0x0f, 0x82, 0xb7, 0xe9, 0xc8, 0xfc, 0xd9, 0xf8,
- 0x25, 0xdf, 0xb9, 0xca, 0xff, 0xf3, 0x5f, 0x44, 0x93, 0xad, 0xe6, 0xcd,
- 0x9f, 0x44, 0xed, 0x6c, 0xfd, 0x81, 0xbc, 0x27, 0xd1, 0x48, 0x76, 0x6d,
- 0x76, 0xc1, 0x13, 0xc9, 0x35, 0x27, 0x92, 0x05, 0xf9, 0x75, 0x50, 0x8a,
- 0x3b, 0xc2, 0xfc, 0xdf, 0xcb, 0xfe, 0xea, 0xab, 0xdf, 0xbd, 0x2b, 0xf5,
- 0x66, 0x3d, 0x22, 0x51, 0x37, 0xfb, 0x96, 0xb8, 0x63, 0x12, 0x1d, 0x46,
- 0x9b, 0x3f, 0x3b, 0x78, 0xc9, 0x96, 0xfe, 0xb0, 0x2f, 0x77, 0x3e, 0x92,
- 0x95, 0xb9, 0x63, 0x95, 0xe3, 0x81, 0xed, 0x49, 0xc9, 0xc9, 0x7a, 0xe3,
- 0x0d, 0xe9, 0x9b, 0xde, 0xca, 0xdc, 0x25, 0x78, 0x9f, 0x3b, 0xd6, 0x8c,
- 0x4a, 0xb9, 0x59, 0xea, 0xb3, 0x3d, 0x0f, 0xa9, 0x44, 0xbb, 0xb3, 0x8b,
- 0xd1, 0x8b, 0x1e, 0xc7, 0xfe, 0x21, 0xc6, 0xbe, 0x45, 0xba, 0xbc, 0x20,
- 0xd8, 0xc2, 0xd8, 0xf7, 0x35, 0x7f, 0x1d, 0x3c, 0xe7, 0xe8, 0x71, 0xed,
- 0xec, 0x93, 0x11, 0xa6, 0x56, 0xf6, 0xf2, 0x03, 0x23, 0x4d, 0xbe, 0x7b,
- 0x3d, 0x9a, 0x4e, 0x37, 0x06, 0x3a, 0xa3, 0x4e, 0x76, 0x2e, 0xb6, 0x8c,
- 0xb4, 0x2b, 0xfb, 0xe8, 0xed, 0x5b, 0xaa, 0xde, 0xeb, 0xa6, 0xde, 0x13,
- 0x5d, 0xba, 0xdd, 0xf8, 0xec, 0x58, 0x93, 0x69, 0x66, 0x76, 0x54, 0xa5,
- 0xd9, 0xd9, 0xb4, 0x4a, 0x73, 0xb3, 0x23, 0x2a, 0x9d, 0x99, 0xf5, 0x54,
- 0xfa, 0xb7, 0x0f, 0xe8, 0xfc, 0x37, 0x1e, 0x48, 0xaa, 0xf4, 0x67, 0x26,
- 0x7d, 0xd3, 0xa4, 0x3f, 0x37, 0xe9, 0x5b, 0x26, 0xfd, 0x95, 0x49, 0x65,
- 0x56, 0xa7, 0x8e, 0xe9, 0x27, 0x6a, 0xde, 0xfb, 0x4c, 0xea, 0x9a, 0x34,
- 0x6e, 0xd2, 0x84, 0x49, 0x87, 0x0d, 0x5d, 0x49, 0x93, 0x7a, 0x26, 0x9d,
- 0x34, 0xe5, 0xbe, 0xa1, 0x77, 0x1a, 0xf4, 0x7e, 0xa1, 0xcb, 0xc8, 0x2a,
- 0xe6, 0x9d, 0x94, 0x85, 0x8a, 0x23, 0xe5, 0x6a, 0x44, 0x0a, 0x6a, 0x0d,
- 0x1f, 0xd9, 0x2f, 0x31, 0x47, 0x96, 0xb6, 0xa3, 0x72, 0x59, 0x89, 0xe8,
- 0x1b, 0xc1, 0x77, 0x0f, 0x4a, 0xc9, 0xce, 0xba, 0xf2, 0xc2, 0x76, 0x5c,
- 0x5e, 0xda, 0x16, 0x6b, 0x2e, 0xd3, 0x2b, 0xf6, 0xe9, 0x77, 0x49, 0xce,
- 0xb5, 0x24, 0xa2, 0x78, 0x9a, 0x94, 0x7c, 0x65, 0x08, 0xef, 0xa9, 0x84,
- 0xc8, 0xe9, 0xfd, 0x7a, 0xfd, 0xa2, 0x12, 0x59, 0xe7, 0x9a, 0x3c, 0x3d,
- 0x7b, 0x71, 0x2d, 0x21, 0xce, 0xea, 0x24, 0xc6, 0xe8, 0x93, 0xae, 0x75,
- 0x19, 0x8e, 0xc8, 0x68, 0xe2, 0x31, 0xd4, 0x98, 0x69, 0x3a, 0x72, 0xb8,
- 0x69, 0x89, 0xe3, 0x45, 0x21, 0x1f, 0x7d, 0xf8, 0xb9, 0xf8, 0xc5, 0xf1,
- 0x4b, 0xe0, 0xf7, 0x97, 0xe8, 0x67, 0x58, 0x0a, 0x4d, 0xf6, 0x89, 0x71,
- 0xab, 0x18, 0xbf, 0x9a, 0x72, 0xe7, 0x85, 0x74, 0x25, 0xe4, 0xbb, 0x07,
- 0x49, 0x97, 0x4b, 0x7a, 0x40, 0x5b, 0xd4, 0xca, 0xaf, 0xc9, 0x93, 0x05,
- 0x5f, 0x92, 0xb6, 0x17, 0x93, 0xa2, 0x6b, 0x25, 0x17, 0xc7, 0x07, 0xa5,
- 0x74, 0x14, 0xe5, 0x55, 0xc9, 0xd9, 0xe8, 0xbf, 0xe8, 0xca, 0xbc, 0x2e,
- 0x63, 0xde, 0x5b, 0xd8, 0xab, 0x29, 0x97, 0x42, 0xfb, 0x52, 0xf5, 0xdb,
- 0x78, 0x66, 0x7f, 0xff, 0xe0, 0x68, 0xba, 0x7f, 0x81, 0x77, 0xe6, 0xff,
- 0x7d, 0x9f, 0x7e, 0xe7, 0x33, 0xeb, 0x86, 0xe3, 0x86, 0xf3, 0xe5, 0xf8,
- 0xe3, 0x98, 0x33, 0x69, 0x08, 0xe7, 0x2c, 0xa5, 0x2e, 0xd0, 0xd2, 0x58,
- 0xeb, 0xb3, 0x36, 0xd6, 0x26, 0xe5, 0x64, 0xf5, 0x1e, 0xc9, 0xfb, 0x41,
- 0xb0, 0xe0, 0x4b, 0xdc, 0x96, 0x51, 0xb7, 0x80, 0x0a, 0xbb, 0x4d, 0xb1,
- 0x1a, 0x15, 0x89, 0xf6, 0x80, 0x2f, 0x3f, 0x59, 0x63, 0xdf, 0x0e, 0xf2,
- 0x86, 0x50, 0xbf, 0xdf, 0xda, 0x5c, 0x03, 0xfd, 0x59, 0xf2, 0x27, 0x08,
- 0x96, 0xfd, 0xd1, 0xc4, 0x22, 0xc6, 0x3c, 0xdf, 0x1c, 0x9d, 0xbe, 0x22,
- 0x2e, 0xfa, 0x1c, 0x44, 0x1d, 0xf2, 0x8a, 0x7d, 0xb1, 0x4f, 0xf6, 0xd7,
- 0x87, 0xb6, 0x71, 0x94, 0x91, 0xae, 0x20, 0xc8, 0xfb, 0x2e, 0xdf, 0x65,
- 0x07, 0xfc, 0xdb, 0x21, 0xff, 0x62, 0xc3, 0xf2, 0x4a, 0x93, 0x63, 0xec,
- 0x45, 0xfb, 0xc4, 0xff, 0x87, 0xb4, 0x27, 0xd0, 0x7f, 0x1c, 0xe9, 0x3e,
- 0xab, 0x51, 0x0b, 0x30, 0x7e, 0x02, 0xcf, 0x7b, 0xcd, 0xe3, 0xb2, 0x5a,
- 0xfb, 0x17, 0xb0, 0xf6, 0x6e, 0x36, 0x2e, 0x2f, 0x6e, 0x0f, 0x63, 0x1e,
- 0x09, 0xf9, 0x06, 0x64, 0x73, 0xe0, 0xce, 0x7d, 0x92, 0x86, 0x6c, 0x72,
- 0xcd, 0xa7, 0xd6, 0x1f, 0x95, 0x62, 0x3c, 0x35, 0x4e, 0x3d, 0x9a, 0x9f,
- 0xea, 0xc1, 0x7c, 0xb5, 0xb6, 0x1a, 0x59, 0x8d, 0x4b, 0x7a, 0x3d, 0x77,
- 0x83, 0x9e, 0x57, 0xdd, 0x92, 0x58, 0x49, 0xec, 0x73, 0x21, 0x6f, 0xc6,
- 0x4d, 0xbd, 0x96, 0x1c, 0x5b, 0xf6, 0x7a, 0x9f, 0x15, 0x59, 0x9f, 0x94,
- 0x13, 0x7b, 0xf0, 0xa4, 0x01, 0x9e, 0xd8, 0xab, 0xa1, 0x9c, 0x3b, 0x78,
- 0x1f, 0x42, 0xdd, 0x7e, 0xcb, 0x59, 0xbf, 0x9e, 0x1f, 0x1b, 0xcd, 0x51,
- 0x7f, 0x17, 0xfc, 0xb0, 0xd7, 0x07, 0x51, 0xe7, 0x7a, 0x7e, 0x34, 0xc0,
- 0x0f, 0x7b, 0x5d, 0xf3, 0xa2, 0x01, 0x5e, 0xd8, 0xa0, 0xb3, 0x01, 0x5e,
- 0xd8, 0xa7, 0x35, 0x2f, 0x1a, 0x66, 0x4f, 0x9c, 0x51, 0xfa, 0x28, 0x07,
- 0x5a, 0x2d, 0xd1, 0x3a, 0x29, 0x27, 0xd4, 0x3d, 0x91, 0xec, 0x0c, 0xf6,
- 0xb2, 0x8d, 0xb9, 0x3a, 0x32, 0x33, 0x65, 0xc9, 0x82, 0x2a, 0x9b, 0x91,
- 0x74, 0xf3, 0x5d, 0x60, 0xd4, 0xc4, 0x38, 0x2c, 0x41, 0xa9, 0x3b, 0xfb,
- 0x1d, 0x7b, 0xb7, 0x12, 0x95, 0x82, 0x93, 0x14, 0x6f, 0x95, 0xfd, 0xcc,
- 0xb7, 0xf5, 0x33, 0x8f, 0x7e, 0x76, 0xc1, 0x0f, 0x0b, 0xba, 0x93, 0x65,
- 0x8f, 0xaa, 0x7d, 0x9d, 0x5e, 0x77, 0x64, 0x74, 0x95, 0x75, 0x4a, 0xf6,
- 0x85, 0xe6, 0xaf, 0x02, 0xdd, 0xef, 0xa3, 0x1c, 0xd3, 0xb5, 0xb3, 0xcb,
- 0xf6, 0xf9, 0xcd, 0x53, 0xf6, 0xcb, 0x4d, 0xf4, 0xdb, 0x24, 0xaf, 0xb1,
- 0x16, 0x55, 0xac, 0x45, 0x15, 0xeb, 0x62, 0xf6, 0x6c, 0x5d, 0xed, 0x9d,
- 0xa4, 0x59, 0x37, 0xd2, 0xc0, 0xb5, 0x4b, 0x60, 0xcd, 0xb8, 0x76, 0x62,
- 0xbd, 0x9a, 0xd9, 0x27, 0x91, 0xd3, 0x11, 0xb5, 0x66, 0x03, 0xeb, 0x1f,
- 0x68, 0xad, 0xd9, 0xc8, 0xd4, 0x81, 0xd6, 0x9a, 0xd9, 0xab, 0xb9, 0x5b,
- 0x6c, 0x39, 0x24, 0x76, 0x16, 0xfc, 0xc9, 0x4c, 0x80, 0x5f, 0x11, 0x94,
- 0xc5, 0xc5, 0x59, 0xcf, 0x21, 0x2f, 0x95, 0x28, 0x82, 0x8f, 0x65, 0xf0,
- 0xb1, 0x28, 0x25, 0xc8, 0xcc, 0xcf, 0x2c, 0xad, 0xdf, 0x7e, 0x29, 0x46,
- 0xb6, 0xdf, 0x91, 0x5f, 0x23, 0xe0, 0x97, 0xf7, 0x3b, 0xf0, 0xcb, 0xd9,
- 0x93, 0x5f, 0xfd, 0x76, 0x27, 0xbf, 0x22, 0xe0, 0x57, 0xd7, 0xef, 0xcc,
- 0x2f, 0xf0, 0x61, 0x4f, 0x5e, 0x45, 0xa1, 0xd7, 0x4a, 0x92, 0xcf, 0x88,
- 0xe4, 0x6b, 0x5a, 0x17, 0x97, 0x94, 0x4e, 0xa6, 0x2e, 0x0a, 0x75, 0x32,
- 0xf5, 0xb1, 0xda, 0x07, 0x56, 0xa1, 0x92, 0x84, 0xae, 0x74, 0x90, 0x3e,
- 0x8f, 0x74, 0x9f, 0x35, 0x57, 0x83, 0x68, 0xf5, 0x07, 0xe2, 0x4e, 0x85,
- 0xf6, 0xb0, 0x94, 0x70, 0xb1, 0x36, 0xee, 0xfb, 0xba, 0x44, 0x86, 0x52,
- 0xe0, 0xd3, 0xcd, 0x28, 0x4f, 0x25, 0x72, 0x92, 0xb1, 0x43, 0xdc, 0x92,
- 0xaf, 0xf4, 0xbe, 0x95, 0x53, 0x4f, 0xcc, 0x67, 0xbb, 0x0c, 0xf2, 0xba,
- 0x64, 0x1e, 0x7a, 0x7e, 0xc6, 0xe3, 0x78, 0xec, 0x3f, 0x39, 0xcf, 0x71,
- 0x0b, 0xcd, 0x50, 0x27, 0x4b, 0x0e, 0x36, 0x1a, 0x65, 0xdc, 0x97, 0xd3,
- 0x56, 0x41, 0xdb, 0x46, 0xf1, 0x9a, 0xed, 0xf6, 0xa3, 0x45, 0x27, 0xf6,
- 0x6b, 0x8e, 0x72, 0x8d, 0xb1, 0x93, 0xd8, 0x73, 0xe5, 0x48, 0xb8, 0x3e,
- 0x4e, 0x76, 0x5a, 0x60, 0x77, 0xa5, 0x5c, 0x61, 0x7f, 0x9f, 0xb1, 0x22,
- 0xe7, 0xc2, 0xfe, 0xc9, 0x47, 0xf6, 0xad, 0xfb, 0x2b, 0x37, 0xdf, 0x30,
- 0x7b, 0x5f, 0xd9, 0x22, 0xf4, 0x57, 0x6a, 0xeb, 0xaf, 0x64, 0x45, 0x56,
- 0xe5, 0x80, 0xd2, 0xf7, 0x47, 0xc9, 0xbf, 0x53, 0x28, 0xbb, 0x2c, 0x11,
- 0xca, 0x8c, 0xda, 0x63, 0xdc, 0xe7, 0x9f, 0xe5, 0x7c, 0xdb, 0x78, 0x3b,
- 0x07, 0x1b, 0xc6, 0xfd, 0x85, 0x35, 0x8e, 0x33, 0xff, 0x2e, 0x43, 0x93,
- 0x23, 0x39, 0xf5, 0xfe, 0xb5, 0x7d, 0xa1, 0x7e, 0xc4, 0x7e, 0x06, 0x6d,
- 0xdf, 0x51, 0x73, 0xb4, 0xb3, 0x59, 0xf0, 0xa6, 0x9d, 0x46, 0x85, 0x05,
- 0xb0, 0xc6, 0xa1, 0x8e, 0x0a, 0xd7, 0x8a, 0xb8, 0xc5, 0xb1, 0x96, 0x2a,
- 0x7d, 0xb0, 0x7f, 0x51, 0x63, 0x63, 0xd9, 0x7e, 0x19, 0xed, 0x99, 0xcf,
- 0xb6, 0x7d, 0xb0, 0xb7, 0x6c, 0xbf, 0x6c, 0xda, 0x5f, 0xb5, 0xbb, 0xdc,
- 0x2b, 0xb4, 0xb9, 0x17, 0x32, 0xc0, 0x3a, 0x6b, 0xb6, 0x14, 0x7c, 0xe0,
- 0x18, 0x7f, 0xd8, 0xec, 0x0b, 0x2d, 0x9b, 0xf7, 0x3a, 0x96, 0xf4, 0x78,
- 0x7b, 0xc9, 0xe6, 0xcb, 0xb6, 0xb6, 0x65, 0x57, 0x65, 0x73, 0x09, 0x3a,
- 0xea, 0x04, 0x64, 0x65, 0xb9, 0x55, 0x8f, 0x72, 0xa9, 0x64, 0x14, 0xb2,
- 0x99, 0x9a, 0xe6, 0x34, 0x2f, 0x34, 0xdb, 0x65, 0x34, 0xec, 0x23, 0xaa,
- 0xe4, 0x40, 0x8f, 0xb3, 0xdc, 0x36, 0xce, 0x72, 0xdb, 0x38, 0x27, 0x0d,
- 0x76, 0x63, 0x3f, 0xda, 0x6e, 0x5e, 0xbe, 0xc6, 0x5e, 0x73, 0xcd, 0x3e,
- 0x8a, 0x3d, 0xa9, 0x65, 0x01, 0x58, 0x4c, 0xaf, 0x41, 0xc5, 0x95, 0xf2,
- 0xf6, 0xd9, 0x70, 0xaf, 0x96, 0x7a, 0x90, 0xff, 0x53, 0xe4, 0x8f, 0xaf,
- 0xb8, 0xb0, 0x43, 0xc4, 0x62, 0x7f, 0x25, 0x5b, 0x15, 0xca, 0xc8, 0x77,
- 0x40, 0x77, 0xda, 0xef, 0xb6, 0xc8, 0xd7, 0xd4, 0xf8, 0x19, 0x49, 0x25,
- 0xcb, 0x32, 0xe1, 0x33, 0x3d, 0x49, 0x45, 0x8d, 0x7a, 0x1a, 0xe3, 0x7c,
- 0x07, 0xf2, 0x27, 0xf2, 0x66, 0xa5, 0x47, 0xec, 0xa9, 0x9f, 0x06, 0xb4,
- 0x73, 0xa7, 0xb6, 0x3b, 0xfb, 0x11, 0x19, 0x5b, 0x51, 0xfd, 0xa0, 0x8f,
- 0xb4, 0x7f, 0x49, 0xf5, 0x17, 0xf6, 0x85, 0x79, 0x4e, 0x75, 0xf6, 0xe7,
- 0xc8, 0x65, 0xd7, 0x46, 0x7f, 0xb7, 0x98, 0x39, 0xf2, 0x19, 0x32, 0xe2,
- 0x3a, 0x48, 0xef, 0xb3, 0x43, 0x99, 0xb1, 0xa7, 0xfe, 0x3a, 0xc8, 0xcd,
- 0x71, 0x6e, 0xff, 0xcc, 0xe4, 0xfd, 0x47, 0x23, 0x6f, 0x52, 0xb3, 0xb3,
- 0xe0, 0x59, 0x66, 0x14, 0xe3, 0xf1, 0x3d, 0x09, 0xfc, 0x23, 0x25, 0xe2,
- 0xaf, 0x62, 0xe5, 0x37, 0x41, 0xce, 0xd1, 0x98, 0x49, 0xaf, 0x3d, 0xcb,
- 0x2d, 0x29, 0xa0, 0xee, 0x92, 0xd1, 0x07, 0x33, 0xcd, 0xcb, 0x8a, 0x7f,
- 0x2f, 0xaa, 0x7d, 0x94, 0x3a, 0x55, 0xa2, 0xde, 0xd8, 0x8e, 0x46, 0xb8,
- 0xc7, 0x5f, 0xf0, 0x37, 0x83, 0xa5, 0x6a, 0x2a, 0x99, 0xb4, 0x47, 0xa5,
- 0x58, 0x1b, 0x2d, 0xd9, 0x48, 0x9f, 0xac, 0x27, 0xe4, 0xc9, 0x0a, 0xfb,
- 0xb9, 0x01, 0x75, 0xa0, 0x88, 0x6c, 0x6c, 0xf2, 0x21, 0xea, 0x1a, 0x8e,
- 0xf9, 0x96, 0xa5, 0xc7, 0xc4, 0x1c, 0xbc, 0x1d, 0xeb, 0x93, 0xcd, 0x0b,
- 0x56, 0xb1, 0xce, 0xf5, 0x47, 0x7e, 0xb3, 0x5d, 0x1f, 0xb5, 0xeb, 0xed,
- 0x50, 0x5f, 0xeb, 0xb5, 0x73, 0xb0, 0xef, 0x6a, 0x95, 0x65, 0xab, 0xbc,
- 0x26, 0x76, 0xde, 0xef, 0x32, 0xf2, 0x68, 0xb9, 0x7a, 0xce, 0x4f, 0x46,
- 0xa8, 0x13, 0x23, 0xde, 0x29, 0xab, 0x5c, 0xb9, 0x55, 0x72, 0x0e, 0x31,
- 0x1c, 0x9f, 0x25, 0x88, 0x64, 0x3d, 0xda, 0x4d, 0x27, 0x92, 0x4d, 0x63,
- 0xbf, 0xb1, 0xce, 0x66, 0xf0, 0x65, 0x8c, 0x33, 0x72, 0x1a, 0xfa, 0xd9,
- 0x7f, 0x0f, 0xfa, 0xe1, 0xf8, 0xbd, 0x78, 0x77, 0xcc, 0xbe, 0xec, 0x42,
- 0xbd, 0x14, 0x36, 0xf7, 0xc5, 0x7e, 0xe9, 0x7f, 0x06, 0x7a, 0x36, 0xec,
- 0x9b, 0x75, 0x12, 0xa6, 0x4e, 0x9f, 0xa9, 0x73, 0x37, 0xca, 0x3f, 0x86,
- 0x7a, 0x29, 0x9f, 0xd0, 0x16, 0x29, 0xf2, 0x06, 0x31, 0x47, 0xd4, 0x6d,
- 0xdc, 0x60, 0xde, 0xc3, 0xf6, 0x77, 0xb6, 0xd5, 0xe5, 0xfb, 0xb5, 0x7a,
- 0x78, 0xbe, 0xa5, 0x87, 0xc9, 0xc3, 0x1c, 0xf4, 0x9e, 0xd8, 0xd8, 0xf7,
- 0x6e, 0x24, 0xcb, 0xfc, 0x69, 0x3c, 0x3f, 0x1f, 0x94, 0xab, 0xd4, 0xfb,
- 0xc0, 0xc1, 0x75, 0xa5, 0xff, 0xd0, 0x6f, 0xce, 0x9a, 0xa9, 0x84, 0xeb,
- 0xc4, 0x79, 0x85, 0xb8, 0x44, 0xf1, 0x0c, 0xf4, 0x26, 0xaf, 0xd2, 0xeb,
- 0x2a, 0x99, 0x40, 0x9e, 0x6f, 0xf2, 0x7a, 0xda, 0xf2, 0x42, 0x9d, 0xf4,
- 0x05, 0xcc, 0x6b, 0x58, 0xad, 0x99, 0x9d, 0x3d, 0x62, 0xe5, 0x15, 0x26,
- 0x0a, 0x82, 0x82, 0xd7, 0x25, 0xc5, 0xc9, 0xa7, 0xc1, 0x2b, 0x96, 0x95,
- 0xdc, 0x88, 0xc2, 0xf1, 0x73, 0x0f, 0x2c, 0x78, 0x29, 0x85, 0x49, 0xf2,
- 0xd0, 0x09, 0x5a, 0x8f, 0x4b, 0x69, 0x00, 0xb4, 0x7b, 0xab, 0xe4, 0xc5,
- 0x66, 0x70, 0x1a, 0xf8, 0x7b, 0x6e, 0x75, 0xc6, 0x1a, 0x59, 0xc5, 0xba,
- 0x0f, 0x59, 0xe0, 0x4b, 0x9f, 0xe4, 0xcf, 0x91, 0x2f, 0xac, 0xc3, 0xfc,
- 0x6e, 0x99, 0x8b, 0x77, 0xda, 0xef, 0x3f, 0x3e, 0x20, 0x31, 0xf2, 0x01,
- 0x75, 0x57, 0x21, 0xec, 0x31, 0x8d, 0x89, 0x47, 0xd6, 0x29, 0x47, 0x33,
- 0xd6, 0x42, 0x85, 0xba, 0xb5, 0x17, 0x36, 0x5b, 0xad, 0x3f, 0xfa, 0x44,
- 0xd9, 0x99, 0xce, 0x3e, 0x3e, 0x1d, 0xd1, 0x7d, 0xb0, 0x5d, 0xd8, 0x47,
- 0x3b, 0x3f, 0xf6, 0x29, 0xdd, 0x3b, 0x98, 0x1d, 0xec, 0xe8, 0x37, 0xd1,
- 0xd6, 0x2f, 0xca, 0xce, 0xfc, 0x34, 0x42, 0x2c, 0xf8, 0x52, 0x15, 0x7c,
- 0x56, 0x73, 0x62, 0x19, 0xdb, 0xcc, 0x58, 0x85, 0xd5, 0x20, 0x98, 0xf3,
- 0x6d, 0x89, 0x0c, 0x85, 0x75, 0xf5, 0xbc, 0x66, 0x30, 0xaf, 0x3c, 0xe6,
- 0x65, 0x0f, 0x75, 0xd2, 0xf4, 0x39, 0x43, 0xd3, 0x60, 0x1b, 0x4d, 0xf1,
- 0x77, 0x98, 0x57, 0x7c, 0x8f, 0x79, 0x9d, 0x1c, 0xd4, 0x7d, 0xc4, 0xdb,
- 0xfa, 0x18, 0xea, 0xe8, 0x03, 0xb6, 0x28, 0xce, 0xf6, 0x43, 0x7b, 0xb4,
- 0xff, 0x49, 0xaf, 0x6e, 0xcf, 0x36, 0xdd, 0xb0, 0x37, 0xc3, 0x46, 0x57,
- 0x3f, 0xd9, 0xa6, 0x5f, 0x9f, 0x84, 0x7e, 0x6d, 0x6f, 0x13, 0xca, 0x65,
- 0xbb, 0x5f, 0x46, 0x9f, 0x2c, 0xc4, 0xaf, 0xef, 0x52, 0xb8, 0xe8, 0x2a,
- 0xae, 0x8f, 0x02, 0x23, 0xf5, 0x01, 0x93, 0xf4, 0xd3, 0xf7, 0x32, 0x38,
- 0x95, 0xbe, 0x18, 0xb1, 0xa9, 0x78, 0x40, 0x76, 0xd0, 0x77, 0xa3, 0x89,
- 0x63, 0x22, 0xca, 0xf7, 0x22, 0xa6, 0xa7, 0x1f, 0xc6, 0x71, 0xe8, 0x87,
- 0x71, 0xdd, 0xf9, 0x5e, 0x68, 0xf9, 0x65, 0xc3, 0xd0, 0x45, 0xc4, 0xe4,
- 0xc4, 0xaf, 0xa1, 0xfd, 0x6b, 0xd7, 0xf1, 0x7b, 0xd1, 0x34, 0xdc, 0x41,
- 0x13, 0xf4, 0x24, 0xfc, 0xc1, 0x25, 0xc8, 0x23, 0x70, 0x32, 0xf4, 0xf2,
- 0xd3, 0xb3, 0x5b, 0x6b, 0x22, 0xc5, 0x26, 0x6d, 0xf6, 0xa4, 0xc0, 0x97,
- 0x03, 0x5d, 0xec, 0x5b, 0xd9, 0x6d, 0xe8, 0xcb, 0xfe, 0x9c, 0x9d, 0x1d,
- 0x85, 0xef, 0xef, 0xc8, 0xa2, 0xa1, 0x6d, 0x5e, 0xf9, 0x8d, 0x7d, 0x48,
- 0x13, 0x4a, 0xae, 0xe6, 0x41, 0x1f, 0x9f, 0xe7, 0x8d, 0xbf, 0x70, 0xac,
- 0xd9, 0x49, 0xdb, 0x0f, 0x41, 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x2d, 0xf8,
- 0x0b, 0xdf, 0x54, 0xfb, 0x32, 0xd4, 0x67, 0x4a, 0x57, 0xd4, 0x4a, 0xf2,
- 0x7c, 0xb0, 0x56, 0xe5, 0xbe, 0x25, 0xae, 0xe8, 0x93, 0x12, 0xd6, 0x6b,
- 0x64, 0x35, 0x95, 0xcc, 0xd9, 0x62, 0xdd, 0x70, 0x27, 0xe5, 0xe9, 0x09,
- 0x19, 0x39, 0x27, 0x96, 0xb3, 0x8a, 0xbd, 0xde, 0x1f, 0x62, 0x3e, 0xce,
- 0xef, 0xdd, 0x98, 0x1f, 0xfa, 0xae, 0x86, 0xf3, 0xeb, 0x93, 0xe2, 0x3a,
- 0xe7, 0xd7, 0x9a, 0x5b, 0x9c, 0x51, 0x98, 0xa7, 0x60, 0x43, 0x30, 0x47,
- 0xd0, 0x38, 0x0d, 0xec, 0xfd, 0x1e, 0x33, 0xa7, 0x3e, 0xcc, 0x09, 0xb8,
- 0x61, 0x95, 0xed, 0x41, 0x17, 0x68, 0x2e, 0xa2, 0x5e, 0x79, 0x95, 0x6b,
- 0x0e, 0x5a, 0xb1, 0xee, 0xc5, 0x26, 0xd7, 0x9e, 0x73, 0xd3, 0x58, 0xc3,
- 0xf1, 0x38, 0x3f, 0xce, 0x73, 0x1c, 0xf3, 0x62, 0x1d, 0xb6, 0xeb, 0x94,
- 0x91, 0xf1, 0x77, 0x58, 0x8f, 0x77, 0x77, 0xac, 0x87, 0x98, 0xf5, 0x88,
- 0x4a, 0xf7, 0xba, 0xf2, 0xd1, 0x15, 0x0d, 0xf4, 0x6b, 0x1c, 0xd0, 0xbf,
- 0xbc, 0x26, 0x93, 0x0c, 0x60, 0xd1, 0x36, 0x20, 0x2f, 0xd3, 0x2d, 0xa3,
- 0xfe, 0x05, 0xc8, 0x55, 0x11, 0xb2, 0x40, 0x1f, 0xe5, 0xa5, 0xaa, 0x5e,
- 0x8b, 0x62, 0x33, 0x26, 0xf6, 0x69, 0x8e, 0x4f, 0x7e, 0x73, 0x6e, 0xae,
- 0x5a, 0x87, 0xf6, 0x75, 0x79, 0xec, 0xba, 0x75, 0xd9, 0x84, 0x1e, 0xa5,
- 0x1e, 0x20, 0x16, 0xa3, 0x2e, 0x08, 0xe3, 0x10, 0x7f, 0xe4, 0xea, 0xfd,
- 0x14, 0xda, 0xc4, 0xcb, 0x2d, 0xcc, 0xfb, 0xa2, 0xf2, 0x1d, 0xf4, 0x9c,
- 0xf2, 0x19, 0xe8, 0xa5, 0xb5, 0x1b, 0xb0, 0x77, 0x68, 0x13, 0x37, 0x83,
- 0x5a, 0xb5, 0x4b, 0xd1, 0x90, 0xf7, 0xfb, 0x89, 0xdf, 0x44, 0xdb, 0x01,
- 0xa6, 0xcc, 0xa7, 0x8d, 0x44, 0x59, 0x86, 0x6b, 0x89, 0xf7, 0x06, 0xdf,
- 0xdb, 0xf5, 0xfe, 0x7f, 0x72, 0xf4, 0x7e, 0x64, 0xec, 0x69, 0x2f, 0x3b,
- 0x78, 0x35, 0xe6, 0xe0, 0xc0, 0x57, 0x2e, 0xaf, 0x05, 0xc0, 0x63, 0xef,
- 0xc1, 0xde, 0xce, 0x49, 0xd1, 0x85, 0x1d, 0x1f, 0xbf, 0x19, 0x7c, 0x9d,
- 0x16, 0x15, 0x67, 0x18, 0xdf, 0x8f, 0xe7, 0x7d, 0xca, 0xa7, 0x29, 0x8e,
- 0xbf, 0x57, 0x72, 0x73, 0xc4, 0x43, 0x8f, 0xcb, 0x3c, 0x6c, 0x6e, 0x71,
- 0x1c, 0x36, 0x31, 0xce, 0x77, 0xe8, 0x25, 0x6f, 0x8c, 0xb1, 0x09, 0xfc,
- 0xfd, 0x1b, 0x13, 0x93, 0x39, 0x88, 0xf7, 0x7d, 0xa8, 0xf3, 0x31, 0x53,
- 0xa7, 0x7f, 0x8f, 0x3a, 0x79, 0xbc, 0xdf, 0x8d, 0x3a, 0x31, 0x8c, 0x01,
- 0x4c, 0x0b, 0x5b, 0x66, 0x7b, 0x1f, 0x46, 0xde, 0x5d, 0xc8, 0xbb, 0x0b,
- 0x79, 0x77, 0xe0, 0xbd, 0x60, 0x62, 0x1d, 0x61, 0x9b, 0x7e, 0xbc, 0x7f,
- 0x01, 0xe5, 0xd0, 0x33, 0xee, 0x25, 0x94, 0xdf, 0xad, 0xda, 0x5d, 0x5b,
- 0x67, 0xb0, 0xe3, 0x7d, 0xcb, 0xd1, 0xb1, 0x11, 0xe6, 0x0d, 0x9b, 0x67,
- 0xb1, 0x96, 0x2b, 0x7c, 0xff, 0xa1, 0x79, 0xbf, 0xb7, 0x23, 0xff, 0x71,
- 0xf3, 0xde, 0xb9, 0xae, 0xb7, 0x61, 0x5d, 0x59, 0xfe, 0xd1, 0x03, 0x7a,
- 0x3d, 0xc6, 0x74, 0xfc, 0xe1, 0x1a, 0x3c, 0xa2, 0x44, 0x11, 0xcf, 0x3b,
- 0xc0, 0x21, 0xc4, 0x26, 0xed, 0xb8, 0x84, 0x34, 0xa9, 0xfa, 0x66, 0x9c,
- 0xe7, 0xfa, 0xc3, 0x71, 0xcb, 0x90, 0x81, 0xc3, 0x6b, 0x61, 0xfe, 0xc5,
- 0xfe, 0x6b, 0xe9, 0xf9, 0x9f, 0x6d, 0xf5, 0xf6, 0xcb, 0xe1, 0x5a, 0x98,
- 0x7f, 0xe8, 0xc0, 0xb5, 0xf5, 0x6e, 0x3e, 0x70, 0x75, 0xae, 0xad, 0x78,
- 0x09, 0x68, 0xfb, 0x8c, 0x7d, 0x15, 0x2b, 0xe5, 0xec, 0xc5, 0xe6, 0x8c,
- 0xad, 0x69, 0x62, 0x1d, 0x94, 0x35, 0x77, 0x06, 0x1c, 0x25, 0xa3, 0x39,
- 0x9b, 0x7e, 0x4a, 0x69, 0x83, 0xcf, 0x37, 0x23, 0x6d, 0x6f, 0x3b, 0x0c,
- 0x7d, 0x9b, 0xb3, 0xf5, 0x9c, 0x3a, 0xdb, 0x87, 0xf2, 0xed, 0xcb, 0x52,
- 0x0d, 0x32, 0xe9, 0xa5, 0xc6, 0x4b, 0xf0, 0x73, 0x17, 0xfc, 0xd4, 0x1c,
- 0x65, 0x16, 0xbe, 0xf0, 0x23, 0x22, 0xb3, 0x52, 0xae, 0x3d, 0x08, 0xec,
- 0x1e, 0xc8, 0x87, 0x60, 0xff, 0xff, 0x25, 0xf0, 0x43, 0x1d, 0xba, 0xa0,
- 0xde, 0xf4, 0xf0, 0x1b, 0x96, 0xaf, 0x57, 0x12, 0xf2, 0x3c, 0x7c, 0x91,
- 0xc6, 0x1a, 0xf5, 0x65, 0xda, 0xfd, 0x90, 0xc8, 0x80, 0x2d, 0xe7, 0xef,
- 0xb2, 0x65, 0x22, 0x39, 0x62, 0xa5, 0x13, 0xf8, 0xb9, 0xdd, 0xf8, 0xcd,
- 0xc0, 0xff, 0xdb, 0x68, 0x32, 0x8e, 0x10, 0x97, 0x3f, 0xdf, 0x4c, 0xe2,
- 0x37, 0x24, 0xff, 0x7e, 0x93, 0xe3, 0x8f, 0x98, 0x34, 0xf4, 0x4d, 0xbe,
- 0x05, 0x1d, 0x71, 0x29, 0x58, 0xae, 0x32, 0x26, 0x14, 0xda, 0xa1, 0x6f,
- 0x29, 0x3b, 0xb4, 0x54, 0x09, 0x8e, 0x6b, 0x1f, 0xdc, 0x83, 0xcf, 0x8d,
- 0xf7, 0xe6, 0x5b, 0x56, 0xa3, 0x35, 0xc7, 0x1d, 0xab, 0x61, 0xd6, 0xad,
- 0xd1, 0x9a, 0x23, 0xca, 0x9b, 0x17, 0x20, 0x0b, 0xd4, 0xbf, 0xa1, 0xee,
- 0xf5, 0x0c, 0x2e, 0x0a, 0xf5, 0x2f, 0xf6, 0x70, 0x4d, 0xa2, 0xf1, 0xec,
- 0x2f, 0x64, 0xed, 0x34, 0xf7, 0x14, 0xed, 0xe5, 0x34, 0x64, 0x31, 0xf5,
- 0x95, 0x12, 0x71, 0xb6, 0xc7, 0x98, 0xc0, 0x25, 0xf4, 0x31, 0x3f, 0xa8,
- 0x65, 0xe7, 0x12, 0xf6, 0xf9, 0xac, 0x38, 0xa7, 0x3f, 0xdf, 0x25, 0xfd,
- 0xc7, 0x65, 0xd9, 0x87, 0x3f, 0x6b, 0x97, 0x82, 0x88, 0xe7, 0x25, 0x0a,
- 0xca, 0xdf, 0x5a, 0x03, 0x5d, 0xdf, 0x03, 0x26, 0x3e, 0xae, 0xfc, 0xba,
- 0x63, 0x35, 0xd6, 0xed, 0xc6, 0x7a, 0xa4, 0x4a, 0x05, 0xac, 0xd5, 0x89,
- 0xf8, 0x05, 0x94, 0x05, 0x81, 0xed, 0x0d, 0x48, 0xb1, 0x1e, 0x3e, 0x43,
- 0xf6, 0x37, 0xff, 0x01, 0x32, 0xc6, 0x67, 0xc0, 0xc4, 0x75, 0x96, 0x8d,
- 0x20, 0x65, 0x39, 0xcb, 0x3c, 0xa5, 0xeb, 0x8a, 0x4d, 0xd2, 0x31, 0x2b,
- 0x85, 0x1a, 0xe7, 0x04, 0xbb, 0x58, 0xbf, 0x14, 0x9c, 0xa8, 0x5e, 0x00,
- 0xaf, 0x38, 0x5e, 0x56, 0x1a, 0x58, 0x8b, 0x72, 0xf3, 0x71, 0x60, 0xfa,
- 0xd7, 0x91, 0x2e, 0x22, 0xbd, 0x8c, 0xf4, 0x09, 0xa4, 0x6f, 0x20, 0xe5,
- 0xbc, 0x1e, 0x97, 0x46, 0x3d, 0xd1, 0x2d, 0x31, 0xf6, 0xf3, 0xd9, 0xd6,
- 0x7c, 0xca, 0xd0, 0x0d, 0xb9, 0x56, 0x3e, 0x9f, 0x99, 0x7e, 0x02, 0xe9,
- 0x47, 0x91, 0xf7, 0x3d, 0x3c, 0x4f, 0x4b, 0xa1, 0xf2, 0x04, 0xec, 0x30,
- 0xb1, 0xea, 0x27, 0x30, 0x2e, 0xc7, 0x7f, 0x19, 0x74, 0xb0, 0x2c, 0x90,
- 0x4f, 0x62, 0x9e, 0xf9, 0xda, 0x71, 0x79, 0xd8, 0xbf, 0x45, 0xa6, 0x1e,
- 0x26, 0x3d, 0xe4, 0x0d, 0xf5, 0xdb, 0x5e, 0xbc, 0x21, 0x5f, 0x42, 0x7e,
- 0xf4, 0x61, 0x5e, 0xd4, 0x55, 0xc4, 0xc6, 0x10, 0xc0, 0x7e, 0x8d, 0x77,
- 0x46, 0xc6, 0x02, 0x79, 0xc8, 0xcf, 0x4a, 0xe4, 0xf4, 0x98, 0x9b, 0xb1,
- 0x27, 0xe0, 0xf9, 0xa4, 0xf1, 0x3b, 0x0e, 0xb9, 0xf4, 0x4e, 0x8d, 0xd8,
- 0x23, 0xa0, 0x09, 0x65, 0x0d, 0x8e, 0x73, 0x29, 0xf8, 0x93, 0xea, 0xab,
- 0xf0, 0xdb, 0xb3, 0x72, 0xa5, 0xf9, 0x2a, 0xe4, 0x83, 0xf4, 0x08, 0xe8,
- 0x9c, 0x95, 0x1f, 0xd7, 0x5e, 0x96, 0x93, 0xe0, 0xfd, 0x6b, 0x48, 0x97,
- 0x6b, 0x25, 0xf0, 0x95, 0xf1, 0x7b, 0xf6, 0x11, 0x60, 0xcd, 0x46, 0xe1,
- 0x6f, 0xdd, 0x96, 0x58, 0xc4, 0xfa, 0xce, 0xbb, 0x81, 0x6c, 0xf9, 0x25,
- 0xd9, 0x9a, 0x46, 0x9b, 0x3a, 0xdb, 0xf7, 0xca, 0x61, 0x95, 0x52, 0xfe,
- 0xfa, 0x31, 0xc7, 0x98, 0xe2, 0xf3, 0x72, 0x35, 0x94, 0x3d, 0xca, 0x61,
- 0xa7, 0xfc, 0x91, 0xee, 0x1d, 0xeb, 0x9b, 0x4d, 0xda, 0xd1, 0xbd, 0x6c,
- 0x62, 0x28, 0x97, 0xb4, 0x8b, 0xed, 0xb2, 0x29, 0xd2, 0xa8, 0x69, 0xff,
- 0xe6, 0x1b, 0xdb, 0x4a, 0xd6, 0xb1, 0x3e, 0xc4, 0xd3, 0x3f, 0x17, 0xe0,
- 0x37, 0xf0, 0x29, 0x8c, 0x2f, 0x6a, 0xbf, 0xab, 0x0e, 0x7a, 0xe1, 0x6b,
- 0x00, 0x2b, 0x88, 0xd4, 0xeb, 0x9f, 0x57, 0xfc, 0xf2, 0x4e, 0x0f, 0x4b,
- 0xad, 0x4a, 0x1e, 0xa7, 0x5c, 0xdb, 0x56, 0xfe, 0x0d, 0x78, 0xeb, 0x41,
- 0x56, 0xc2, 0xf2, 0x14, 0xfc, 0xaf, 0xe3, 0xe2, 0x4e, 0xc5, 0x60, 0xbf,
- 0xf8, 0x2c, 0x32, 0x77, 0xae, 0x13, 0x0b, 0x86, 0x36, 0xa6, 0x1b, 0x7e,
- 0x7e, 0x17, 0x74, 0x41, 0x1f, 0xfc, 0x74, 0xf8, 0xbf, 0x90, 0xa7, 0x3f,
- 0x01, 0x7e, 0x3a, 0xa5, 0x7c, 0x76, 0xee, 0xc3, 0x07, 0x67, 0x47, 0x36,
- 0x99, 0x7e, 0x78, 0x36, 0x5d, 0x67, 0x7a, 0xd4, 0xc4, 0xf5, 0x1f, 0x31,
- 0xf1, 0xfe, 0xf9, 0xd9, 0x83, 0x2a, 0x5d, 0x9c, 0x1d, 0x57, 0xe9, 0xe3,
- 0xb3, 0x57, 0x63, 0x31, 0x17, 0x20, 0xab, 0xa4, 0x4d, 0x9c, 0x62, 0x26,
- 0x23, 0x9b, 0x15, 0x1f, 0x7e, 0xf7, 0x34, 0xf0, 0xc7, 0x34, 0xe4, 0x36,
- 0x0b, 0x7a, 0xa1, 0x7f, 0xb2, 0x3e, 0x52, 0x31, 0x7f, 0x61, 0xbb, 0x6e,
- 0xc6, 0xdd, 0xb8, 0x66, 0xc6, 0x77, 0xf5, 0xe9, 0xbb, 0xb6, 0xff, 0xb1,
- 0x4f, 0xc8, 0x38, 0xed, 0xee, 0xaf, 0xe1, 0x6f, 0xb3, 0x7f, 0xb6, 0x65,
- 0xff, 0x22, 0xbb, 0x6b, 0x12, 0x8d, 0x66, 0xff, 0x5a, 0xa2, 0xcf, 0x06,
- 0xc1, 0x4f, 0xfc, 0xd4, 0x91, 0x92, 0x80, 0x4f, 0x16, 0xf2, 0x37, 0x59,
- 0x46, 0x9d, 0x35, 0xe1, 0x5e, 0x81, 0xcc, 0xe5, 0x8e, 0x8a, 0xbc, 0x82,
- 0xbc, 0xc6, 0x1a, 0xf9, 0xff, 0x3d, 0xf0, 0xdf, 0xac, 0x87, 0xca, 0x63,
- 0x3d, 0xf8, 0x48, 0x71, 0xca, 0xdc, 0x84, 0xdb, 0x83, 0xf6, 0xf5, 0x4d,
- 0xb6, 0x49, 0x4d, 0xf3, 0x98, 0xec, 0x95, 0xcd, 0x0b, 0x4a, 0x5f, 0x75,
- 0x67, 0xc7, 0x19, 0x43, 0x92, 0x8d, 0xb5, 0xdf, 0x04, 0x0b, 0xfe, 0x0e,
- 0x80, 0x5a, 0x0a, 0x72, 0x9f, 0x95, 0xf3, 0xc0, 0x58, 0xe7, 0x2b, 0x69,
- 0xac, 0x0d, 0xf0, 0x6d, 0x82, 0x24, 0x7b, 0xa8, 0xf7, 0x66, 0x37, 0x71,
- 0x6c, 0x9e, 0xe7, 0x47, 0x95, 0x69, 0xd9, 0x6d, 0xce, 0x09, 0xb1, 0x52,
- 0x3e, 0xc3, 0xf9, 0xb4, 0xf3, 0x41, 0xff, 0x15, 0xb1, 0x06, 0x66, 0x7e,
- 0xea, 0x0f, 0x74, 0x62, 0x3f, 0xa1, 0xbd, 0xbf, 0x83, 0xbd, 0x91, 0x82,
- 0x7e, 0x15, 0x07, 0x7e, 0xa2, 0xa4, 0xcf, 0x3a, 0x4e, 0xbe, 0xe2, 0xc8,
- 0xc8, 0x59, 0x6c, 0xa9, 0xac, 0xe1, 0x43, 0x33, 0x94, 0xb1, 0x50, 0xe7,
- 0x51, 0xa6, 0x38, 0xff, 0x54, 0x69, 0x07, 0x8c, 0x1e, 0xcc, 0x5e, 0x94,
- 0x87, 0xd7, 0xf5, 0x7c, 0xed, 0x33, 0xc2, 0xb3, 0x13, 0xb9, 0xb2, 0x96,
- 0xf2, 0x2f, 0x0b, 0xfd, 0x5f, 0x1f, 0x32, 0x72, 0xb1, 0x1b, 0xfb, 0x79,
- 0x3a, 0x67, 0x1f, 0xec, 0xd1, 0xb6, 0xd9, 0xc1, 0x1e, 0x00, 0x4e, 0xac,
- 0xc0, 0x6f, 0xf6, 0x7a, 0xe4, 0x5f, 0x38, 0x78, 0x26, 0x6e, 0x44, 0x9e,
- 0xb1, 0xa3, 0x78, 0xd6, 0xfd, 0x95, 0x31, 0x0f, 0x1d, 0x57, 0xb6, 0xe4,
- 0x61, 0x58, 0x15, 0x41, 0xff, 0x23, 0x66, 0xac, 0x91, 0x33, 0x17, 0xd4,
- 0x7e, 0x4d, 0xaf, 0x67, 0x81, 0xa3, 0x1c, 0xe3, 0x6f, 0x52, 0x4f, 0xc9,
- 0x1e, 0xfe, 0x4a, 0x28, 0xa3, 0x17, 0x82, 0x2f, 0x56, 0xc3, 0x98, 0x40,
- 0x46, 0x46, 0x56, 0xb4, 0x4c, 0x3d, 0x9e, 0x81, 0xce, 0x86, 0x2c, 0x8d,
- 0xac, 0x04, 0xf2, 0x13, 0xdf, 0x97, 0x53, 0xdb, 0x7b, 0xc9, 0x54, 0xe7,
- 0x5f, 0x1f, 0xe8, 0xe4, 0x6f, 0x48, 0x96, 0xfe, 0x14, 0x74, 0x9e, 0x75,
- 0xf1, 0x9c, 0x9a, 0x9b, 0xa7, 0x8f, 0x70, 0x16, 0xba, 0x14, 0xbe, 0xac,
- 0x7d, 0x76, 0x58, 0xd5, 0xb1, 0xcf, 0xc2, 0xc6, 0x41, 0xc6, 0x6c, 0xf0,
- 0xb5, 0x0c, 0x7b, 0x67, 0x9f, 0xed, 0x82, 0x5d, 0xe4, 0x1e, 0x95, 0x41,
- 0x1b, 0xba, 0x80, 0xf5, 0x1b, 0xd8, 0x2b, 0xf6, 0xd9, 0x3e, 0xa4, 0x49,
- 0xd5, 0x57, 0xa3, 0xe2, 0xa9, 0xf6, 0x8d, 0xca, 0xb8, 0x6a, 0xd7, 0xa8,
- 0x4c, 0x22, 0x85, 0x8e, 0xcf, 0xf8, 0xd2, 0x7d, 0x36, 0x23, 0x72, 0xd6,
- 0x92, 0xe2, 0x5c, 0x10, 0xc4, 0x40, 0x7b, 0xec, 0xec, 0x01, 0xb9, 0xac,
- 0xd6, 0x76, 0x4e, 0x46, 0x9e, 0x25, 0xbf, 0xb2, 0xa8, 0x3b, 0x23, 0xe9,
- 0x67, 0x67, 0xc4, 0x7b, 0x96, 0x3c, 0x61, 0xac, 0x7e, 0x57, 0xc9, 0xd4,
- 0x27, 0xe4, 0x28, 0xec, 0x4a, 0x0f, 0xf6, 0x84, 0xe3, 0x96, 0x65, 0x05,
- 0x6b, 0x32, 0xea, 0x1e, 0x86, 0x9c, 0xc9, 0xdb, 0xd6, 0x67, 0x5d, 0xb6,
- 0x61, 0xfd, 0x83, 0x90, 0x17, 0x0f, 0xf5, 0x8f, 0xc2, 0xc6, 0xb4, 0xf3,
- 0x82, 0xfb, 0x2c, 0xf7, 0x0e, 0xf2, 0x17, 0xee, 0xaf, 0x0b, 0xc1, 0xc9,
- 0x2a, 0xf7, 0x18, 0xf7, 0xd7, 0x87, 0xe4, 0x15, 0x6f, 0x4e, 0x76, 0xbd,
- 0x8c, 0x5c, 0x00, 0x0e, 0x7d, 0xd9, 0x9b, 0x91, 0x8b, 0x5e, 0xb4, 0x87,
- 0x31, 0xb6, 0x06, 0x71, 0x72, 0x6b, 0xcd, 0xe2, 0xc6, 0x1f, 0x79, 0x43,
- 0xb6, 0x2a, 0xb4, 0xd5, 0xc1, 0xa1, 0x05, 0xbf, 0x74, 0x33, 0x68, 0x03,
- 0x1d, 0x8c, 0x1b, 0x5c, 0xb5, 0x11, 0x5d, 0xd8, 0x43, 0x1b, 0xca, 0x46,
- 0xf4, 0xd1, 0x46, 0xf8, 0x05, 0xd9, 0x2f, 0xbb, 0x35, 0x1d, 0xd3, 0xcb,
- 0x03, 0x43, 0xed, 0xd6, 0xb9, 0xfe, 0x71, 0xf9, 0x52, 0x95, 0x73, 0x2d,
- 0xdf, 0x10, 0x93, 0x88, 0x1c, 0x51, 0x36, 0xbb, 0x5f, 0xce, 0x6f, 0x02,
- 0xf3, 0x02, 0x7d, 0xd8, 0xb7, 0x32, 0x26, 0x64, 0xab, 0x18, 0x83, 0x0c,
- 0xd0, 0x66, 0xfd, 0x17, 0xf0, 0x88, 0x71, 0x20, 0xcc, 0x71, 0x80, 0xb3,
- 0x09, 0xdf, 0x27, 0x65, 0xb7, 0xc2, 0x67, 0x4b, 0x0a, 0xf0, 0x27, 0x77,
- 0x2b, 0x4c, 0x13, 0x48, 0x4d, 0x8c, 0x5f, 0x61, 0xf8, 0xbf, 0x55, 0xe5,
- 0x3d, 0xde, 0x2c, 0xd6, 0x85, 0x72, 0x8b, 0x74, 0x4b, 0x8f, 0x5b, 0x80,
- 0xcf, 0x5f, 0x9c, 0xec, 0xa5, 0xfd, 0x02, 0x6e, 0x72, 0x64, 0x5e, 0xd5,
- 0xcf, 0xc8, 0xc5, 0xca, 0xcf, 0xcc, 0x3e, 0x99, 0x36, 0xcf, 0x2c, 0x67,
- 0xac, 0x87, 0x3e, 0xcd, 0x91, 0xd9, 0x65, 0xef, 0x03, 0xa6, 0x5c, 0xc5,
- 0x5c, 0xac, 0x0f, 0x02, 0x43, 0x8e, 0xac, 0x74, 0x63, 0x3e, 0xf6, 0x90,
- 0x3e, 0x93, 0x39, 0x24, 0x33, 0xfe, 0x41, 0xd0, 0x7f, 0x40, 0xca, 0xf0,
- 0x95, 0x96, 0xb6, 0xa1, 0x57, 0xc6, 0xe1, 0x13, 0xbb, 0xb7, 0x13, 0xa3,
- 0xa9, 0x98, 0x52, 0xd9, 0x1d, 0x45, 0xda, 0x83, 0xf4, 0x66, 0x29, 0x3f,
- 0x73, 0x43, 0x54, 0xf7, 0xd7, 0xd5, 0xf1, 0xfe, 0x3c, 0xc7, 0x4e, 0x26,
- 0xad, 0xdf, 0x86, 0x07, 0xdb, 0xb1, 0x20, 0xe9, 0xe8, 0x12, 0xef, 0xcb,
- 0x7d, 0x32, 0xba, 0xe2, 0xca, 0xd8, 0x4a, 0x42, 0x0e, 0xae, 0x0c, 0xcb,
- 0xf8, 0x4a, 0x52, 0x6e, 0x5d, 0x09, 0xf1, 0xd8, 0x83, 0xb3, 0x69, 0x63,
- 0x07, 0xbc, 0xdf, 0xd1, 0x0e, 0xdc, 0xda, 0xd4, 0xd8, 0xb4, 0xbc, 0x71,
- 0x01, 0x36, 0x7b, 0x07, 0xfb, 0x37, 0x03, 0x2c, 0xe6, 0x43, 0x27, 0x4d,
- 0x42, 0x27, 0x8d, 0x43, 0x27, 0x4d, 0x53, 0x27, 0x01, 0xff, 0xbd, 0x0a,
- 0xfc, 0x77, 0x8f, 0xbc, 0x06, 0x9d, 0xfb, 0x82, 0xdf, 0xe3, 0xce, 0x81,
- 0x1f, 0x87, 0xd5, 0xb9, 0x57, 0xea, 0x2b, 0x3b, 0x90, 0x81, 0xc6, 0xd7,
- 0x24, 0x3a, 0x00, 0x7d, 0x75, 0xfb, 0x7a, 0x8f, 0x6c, 0xc4, 0x83, 0xe0,
- 0x34, 0xf6, 0xfa, 0x95, 0x8a, 0x96, 0xd9, 0xbc, 0xc7, 0x3d, 0xff, 0x20,
- 0xe6, 0x3e, 0x89, 0xbc, 0x1c, 0x74, 0x98, 0x8e, 0xa3, 0x34, 0x8e, 0x26,
- 0x64, 0xf3, 0xe0, 0x74, 0x47, 0xbd, 0x0c, 0xde, 0xa9, 0x33, 0xfe, 0x39,
- 0xea, 0x53, 0x7f, 0xbb, 0xb2, 0x05, 0x8c, 0x78, 0xe6, 0x60, 0x6a, 0x3a,
- 0x69, 0x53, 0xdf, 0x25, 0xa5, 0xfe, 0xb5, 0x84, 0x6c, 0x54, 0xb5, 0xcd,
- 0x59, 0x00, 0x26, 0x2c, 0x00, 0xef, 0x6e, 0x00, 0x67, 0x15, 0x9a, 0x5a,
- 0xdf, 0xdb, 0xd9, 0x2e, 0x61, 0x7f, 0x85, 0x66, 0x1e, 0xf8, 0x58, 0x9c,
- 0x7c, 0x86, 0x74, 0x4e, 0x24, 0x22, 0x76, 0x0f, 0x64, 0x81, 0xfb, 0xe3,
- 0x41, 0xd8, 0x53, 0x96, 0xd1, 0x36, 0x53, 0xff, 0x3f, 0x15, 0x25, 0xc6,
- 0x2b, 0xf8, 0xc4, 0xd3, 0x79, 0x94, 0xa5, 0x12, 0x69, 0xe4, 0xcf, 0x49,
- 0x5a, 0x9d, 0x21, 0x2d, 0x60, 0xcf, 0x97, 0x15, 0xcd, 0x11, 0xc6, 0xa4,
- 0x28, 0x1e, 0x51, 0x1d, 0x2f, 0x0c, 0xf3, 0x27, 0xdc, 0x22, 0xd6, 0x38,
- 0xc7, 0xbe, 0xab, 0xcc, 0x4b, 0xbb, 0x6c, 0x57, 0xf0, 0xf9, 0x2e, 0xf2,
- 0x91, 0x26, 0xe3, 0x27, 0x51, 0x79, 0xb8, 0xd9, 0x07, 0x9a, 0xba, 0x7f,
- 0x8b, 0x3d, 0x71, 0xdb, 0xec, 0xc9, 0x6e, 0xc2, 0x85, 0x9e, 0x58, 0x34,
- 0x7a, 0xc5, 0x99, 0xd2, 0x18, 0xf8, 0xa5, 0x2a, 0xd6, 0xa8, 0x8a, 0x35,
- 0xaa, 0x62, 0x8d, 0xaa, 0x58, 0xa3, 0x2a, 0xf5, 0x07, 0x75, 0x4d, 0xce,
- 0x9c, 0x31, 0x50, 0x87, 0x3c, 0x8f, 0xb5, 0x9c, 0x93, 0x6f, 0x6f, 0xcf,
- 0xca, 0x5f, 0x6c, 0x1f, 0x01, 0xc6, 0x9e, 0xc1, 0xba, 0xe6, 0xb0, 0xae,
- 0xd3, 0x58, 0xd3, 0xa3, 0x58, 0xd3, 0x2c, 0xcf, 0xd9, 0xe4, 0xcb, 0x95,
- 0xd4, 0x0b, 0x25, 0x85, 0xef, 0xdf, 0xc0, 0xfa, 0x4e, 0x89, 0xb7, 0x3e,
- 0x0c, 0x9d, 0x50, 0x0a, 0xe2, 0x5e, 0x70, 0x08, 0x18, 0x1a, 0xf3, 0x2f,
- 0xa5, 0x1c, 0x45, 0x83, 0xe7, 0x7e, 0x0a, 0x13, 0xbf, 0x21, 0x9b, 0xaa,
- 0x51, 0x3d, 0x6d, 0xd5, 0xc6, 0xa5, 0x78, 0x0e, 0xf5, 0x4f, 0xf7, 0x81,
- 0xdf, 0xc4, 0x6f, 0xa9, 0x52, 0x51, 0x76, 0xa0, 0xcf, 0x72, 0xa0, 0xf1,
- 0xbd, 0x52, 0x8e, 0xa7, 0x9e, 0xe7, 0x3e, 0xbb, 0x71, 0x95, 0xf1, 0x01,
- 0x1b, 0xbc, 0x21, 0xed, 0x78, 0x3e, 0x97, 0x55, 0x31, 0xbe, 0xbc, 0x7f,
- 0xc0, 0xec, 0x63, 0x8d, 0x49, 0xeb, 0xc2, 0x71, 0x39, 0xde, 0x67, 0x64,
- 0x11, 0xb8, 0xcf, 0xce, 0x12, 0x57, 0x78, 0x09, 0x8c, 0x19, 0x5d, 0x38,
- 0xe7, 0x46, 0x17, 0xcf, 0xb1, 0x9f, 0xa8, 0xa4, 0x57, 0xa9, 0x97, 0xd8,
- 0x0f, 0x74, 0x36, 0xfa, 0x8e, 0xa8, 0x33, 0xb5, 0x09, 0xb4, 0xfb, 0x03,
- 0x60, 0x46, 0xcd, 0xc3, 0xfc, 0x69, 0x6d, 0xc7, 0xf2, 0x8d, 0x76, 0xcc,
- 0x06, 0x1d, 0x02, 0x3b, 0x97, 0x6b, 0x68, 0xfc, 0x35, 0xa3, 0xf0, 0x99,
- 0xc6, 0x66, 0x47, 0xe5, 0x50, 0xaf, 0xc4, 0x3c, 0x35, 0x9f, 0xf4, 0xe9,
- 0x1d, 0x62, 0x52, 0x8c, 0xa1, 0xe3, 0xcc, 0x57, 0xe9, 0xce, 0x60, 0x2e,
- 0x37, 0xf7, 0x86, 0x31, 0x41, 0x7b, 0x55, 0x9f, 0x41, 0xd9, 0xe7, 0x7c,
- 0xcc, 0x47, 0x86, 0x18, 0x65, 0xb4, 0x31, 0x87, 0x7b, 0x95, 0x9d, 0x9d,
- 0x62, 0xec, 0x0f, 0xb2, 0x4d, 0xfd, 0x32, 0x84, 0xbd, 0xc1, 0x77, 0x1d,
- 0x53, 0xee, 0xf1, 0x28, 0x2f, 0x71, 0xc8, 0x20, 0x74, 0x4d, 0xff, 0xb0,
- 0xd4, 0xb7, 0x59, 0x36, 0xac, 0xf4, 0xb0, 0x83, 0x35, 0x58, 0xae, 0x04,
- 0x87, 0xf2, 0x7e, 0x09, 0xda, 0x92, 0x3c, 0x27, 0x3f, 0xc8, 0xf7, 0x49,
- 0xd0, 0x46, 0x1e, 0xf7, 0x97, 0xf4, 0xb9, 0xe6, 0x7e, 0x29, 0xd6, 0xa8,
- 0x8b, 0x91, 0xd6, 0xf7, 0x9b, 0xd8, 0x46, 0x5c, 0x72, 0x73, 0x9c, 0x3b,
- 0x7d, 0x13, 0xa0, 0xba, 0xd5, 0x94, 0x5f, 0xb7, 0x67, 0xa5, 0x48, 0xf9,
- 0x84, 0x6e, 0x2c, 0x6e, 0x4e, 0xc9, 0xf2, 0x1a, 0xe3, 0x7d, 0x3c, 0x7b,
- 0x9e, 0x88, 0x4a, 0x7f, 0x10, 0x6c, 0xf9, 0xb4, 0xf3, 0x79, 0x29, 0x20,
- 0xdf, 0x5e, 0x87, 0x9d, 0x3f, 0xaa, 0x79, 0xc7, 0xf9, 0x96, 0x37, 0xfe,
- 0x6f, 0xf8, 0xf8, 0xf6, 0x38, 0x77, 0x66, 0x0f, 0x9c, 0xfb, 0xea, 0x39,
- 0xc8, 0x5f, 0x15, 0xb2, 0x09, 0x9f, 0xe9, 0x2f, 0xaa, 0x90, 0x4d, 0xd8,
- 0x8c, 0x6f, 0x56, 0x21, 0x9b, 0xd8, 0x3b, 0x2f, 0xc2, 0xa7, 0xd1, 0x98,
- 0xe2, 0x11, 0x85, 0x29, 0x4e, 0x54, 0x89, 0xf9, 0x2f, 0x41, 0x96, 0x27,
- 0x21, 0xc7, 0x49, 0xc8, 0xaf, 0x0f, 0xd9, 0x1d, 0x87, 0x3c, 0x7b, 0x90,
- 0xe7, 0x61, 0x15, 0xf7, 0x79, 0x61, 0x3b, 0x2a, 0xf7, 0xc3, 0x9f, 0x38,
- 0x53, 0x23, 0x1f, 0x8f, 0xcb, 0xff, 0x82, 0x2f, 0xb1, 0xeb, 0xef, 0x80,
- 0x87, 0x39, 0x59, 0xf4, 0xc8, 0xaf, 0x9c, 0xbd, 0xe0, 0xd1, 0xd7, 0x70,
- 0xe5, 0xcc, 0x06, 0x7d, 0x04, 0xea, 0x88, 0x57, 0xe5, 0x9b, 0x95, 0x1f,
- 0xc8, 0xb7, 0x80, 0x05, 0x0a, 0xf0, 0x9b, 0x37, 0x9e, 0xa1, 0xcf, 0xa8,
- 0x68, 0x84, 0xdc, 0xc5, 0x65, 0x73, 0xfb, 0x76, 0x79, 0xca, 0xa5, 0x0c,
- 0xc7, 0xa1, 0x5b, 0xf0, 0x7e, 0x90, 0x7a, 0x28, 0x83, 0xfd, 0x09, 0x39,
- 0x87, 0x6e, 0xa8, 0xd9, 0x3c, 0xc3, 0x28, 0x05, 0x03, 0xd4, 0x59, 0x35,
- 0xcf, 0x1d, 0xb1, 0xc9, 0x9b, 0x5b, 0x18, 0x73, 0xfa, 0x0a, 0x84, 0x17,
- 0x79, 0xb4, 0xd9, 0x48, 0xeb, 0xd0, 0x8d, 0xcf, 0x90, 0x8f, 0xf4, 0x61,
- 0xf1, 0xbc, 0xc1, 0xbd, 0xf6, 0x73, 0x15, 0xcb, 0x2d, 0xce, 0xc1, 0x5f,
- 0xdf, 0x20, 0x9f, 0x20, 0x2b, 0xcf, 0x90, 0x8f, 0xe4, 0x9d, 0xe6, 0xe3,
- 0x43, 0x12, 0xf2, 0x90, 0x65, 0x9d, 0x3c, 0xfc, 0x77, 0x90, 0xc3, 0x38,
- 0xe6, 0xfd, 0xd5, 0x28, 0x63, 0x8e, 0x37, 0x7a, 0x5c, 0xf3, 0x57, 0xe5,
- 0xc9, 0x26, 0xc7, 0x7a, 0xd9, 0x8c, 0xf9, 0xfd, 0xe0, 0xe1, 0x38, 0x69,
- 0xe7, 0x7a, 0xee, 0x93, 0xc6, 0x90, 0x6f, 0xe2, 0x2a, 0xbf, 0xcd, 0xde,
- 0xb0, 0x1e, 0x78, 0x0d, 0xbd, 0xf2, 0xad, 0x2a, 0x78, 0x0c, 0xbf, 0xe9,
- 0x1b, 0xf0, 0x9b, 0x18, 0x6b, 0xd4, 0xeb, 0x32, 0x6d, 0xe2, 0xa6, 0x9d,
- 0xf1, 0xd2, 0x24, 0xd6, 0x85, 0xbe, 0x79, 0xaa, 0x74, 0x19, 0xba, 0xef,
- 0x45, 0x9f, 0x71, 0xc4, 0x40, 0xbe, 0xef, 0xb7, 0x6b, 0x37, 0x15, 0x63,
- 0x96, 0x87, 0xa0, 0x0f, 0x1f, 0x86, 0x3e, 0xfc, 0xc8, 0x75, 0xf7, 0x7b,
- 0x28, 0x67, 0x4f, 0xcf, 0x2e, 0xac, 0x8d, 0x96, 0x22, 0xf6, 0xb0, 0xcc,
- 0x5d, 0xa3, 0x1b, 0x19, 0x4f, 0x4c, 0x9a, 0x78, 0x68, 0x3b, 0xfe, 0x0c,
- 0x63, 0x9e, 0x94, 0xe7, 0x40, 0x2e, 0xfa, 0xa5, 0xbe, 0x88, 0x3a, 0x97,
- 0xe6, 0xba, 0xee, 0x85, 0x2d, 0xbf, 0x6d, 0xf6, 0x30, 0x65, 0xab, 0xf3,
- 0xdc, 0x98, 0xe7, 0xd0, 0xfd, 0xf0, 0x13, 0xb8, 0x57, 0x53, 0xc9, 0x1c,
- 0xf6, 0x73, 0x79, 0x9b, 0xfa, 0x9f, 0xd8, 0xb0, 0x9b, 0xf1, 0xbc, 0xf9,
- 0x9e, 0x2c, 0x63, 0x01, 0xfd, 0xf0, 0x3f, 0x7e, 0x24, 0x5b, 0x6b, 0x7f,
- 0xd3, 0xab, 0xf7, 0x91, 0xbe, 0x6f, 0x66, 0x9f, 0xeb, 0x8c, 0x63, 0xd2,
- 0xa6, 0x4a, 0xb4, 0x17, 0x76, 0xf1, 0xd6, 0x67, 0xfb, 0x95, 0xdd, 0xbb,
- 0xcf, 0x77, 0x64, 0x27, 0xce, 0xfe, 0x7e, 0x24, 0x3f, 0x5e, 0x1b, 0x89,
- 0x31, 0xfe, 0xb9, 0x0c, 0x3e, 0xef, 0x2a, 0xdd, 0xf5, 0x20, 0xea, 0x64,
- 0xe5, 0xf5, 0x35, 0xda, 0xd6, 0xb4, 0x7b, 0x46, 0x26, 0x12, 0x67, 0xc0,
- 0xcb, 0x53, 0x68, 0x03, 0x7f, 0x38, 0x98, 0x41, 0xde, 0xcb, 0xf4, 0xb9,
- 0x2d, 0x3e, 0x4f, 0xb8, 0x5f, 0x04, 0x4e, 0xce, 0xb9, 0x69, 0xb7, 0xd7,
- 0xba, 0xa4, 0xce, 0x9d, 0x22, 0x1e, 0xfb, 0x1a, 0x92, 0xc2, 0xa6, 0xa6,
- 0xf1, 0xca, 0x26, 0xc7, 0xe0, 0x5c, 0x48, 0xe3, 0xdf, 0xf0, 0x5c, 0x01,
- 0xf4, 0xdf, 0x06, 0x9f, 0x84, 0x98, 0xe5, 0x12, 0x64, 0x66, 0x08, 0xfa,
- 0x81, 0xbe, 0x0a, 0xcf, 0x2c, 0xc9, 0xb3, 0xcf, 0x03, 0xef, 0xc7, 0x21,
- 0xab, 0xc8, 0xdf, 0xbc, 0xea, 0x1f, 0x2e, 0xb7, 0x70, 0x3d, 0x6d, 0xe3,
- 0x2c, 0x6c, 0xe4, 0xbb, 0x14, 0x3d, 0x47, 0x7c, 0xf8, 0xda, 0xcf, 0x50,
- 0xbe, 0x0e, 0x4a, 0x31, 0x4e, 0x5c, 0x49, 0x7d, 0xb2, 0x9b, 0x88, 0x02,
- 0xd7, 0x46, 0x6f, 0xe7, 0xbe, 0x3b, 0x22, 0xf7, 0x7b, 0x0f, 0xca, 0x07,
- 0xbd, 0x49, 0x99, 0xf1, 0xee, 0x91, 0xc3, 0x5e, 0x5e, 0xee, 0xf3, 0x60,
- 0x9b, 0x14, 0x3e, 0xef, 0xc1, 0x3c, 0x38, 0xf6, 0x90, 0x39, 0xdf, 0xd3,
- 0xf8, 0xf4, 0xeb, 0xdb, 0x5a, 0x27, 0xe5, 0xd7, 0xb2, 0x31, 0xda, 0xe4,
- 0x23, 0xfe, 0x8c, 0xb1, 0xc9, 0xf0, 0xf9, 0x55, 0xbd, 0x19, 0x65, 0xbb,
- 0xcb, 0x9b, 0x73, 0x48, 0x61, 0xc7, 0x37, 0xa7, 0x81, 0xfb, 0xe9, 0x4b,
- 0xe5, 0xf0, 0x7e, 0x0f, 0xde, 0x3f, 0x84, 0xf4, 0x08, 0x52, 0x75, 0xae,
- 0x19, 0xd3, 0xb1, 0xdb, 0xd6, 0xb9, 0x1d, 0xe4, 0xeb, 0xe8, 0xec, 0x42,
- 0x2d, 0x8c, 0x81, 0x1f, 0x92, 0xc7, 0x7d, 0x7d, 0x96, 0x7e, 0x18, 0x7e,
- 0x74, 0x0c, 0xf8, 0xe9, 0x43, 0xcf, 0x4e, 0x49, 0xe4, 0xee, 0x43, 0x62,
- 0xdf, 0x6d, 0xc9, 0xc2, 0x24, 0xe8, 0x9b, 0x1c, 0xc5, 0x3c, 0x86, 0xe5,
- 0xc4, 0xb6, 0xf2, 0x51, 0x0d, 0x5e, 0xa4, 0x1e, 0x07, 0xd6, 0xdd, 0x0e,
- 0x71, 0x63, 0x37, 0x70, 0x05, 0xe3, 0x7b, 0x49, 0x85, 0x77, 0xed, 0x1b,
- 0xb9, 0xbe, 0x7d, 0x92, 0xbf, 0x91, 0xfc, 0x63, 0x1e, 0xfc, 0x9d, 0x1b,
- 0xb5, 0xdd, 0x48, 0xaf, 0x70, 0x6d, 0x7a, 0x4c, 0xec, 0x96, 0x36, 0x80,
- 0xe9, 0x6a, 0xac, 0x85, 0x0b, 0x19, 0x9f, 0xb1, 0x6e, 0x8f, 0x5d, 0xbd,
- 0x67, 0x16, 0xca, 0x73, 0x78, 0x7f, 0xc0, 0x53, 0x38, 0xe7, 0x44, 0xf5,
- 0x05, 0xcc, 0x81, 0x36, 0x3d, 0x22, 0xdd, 0xd0, 0x6b, 0x5b, 0x1e, 0xf7,
- 0x1e, 0x6d, 0xce, 0x11, 0xcc, 0x87, 0x36, 0x9e, 0xb6, 0xfe, 0xde, 0x7e,
- 0xe9, 0xa7, 0x9d, 0x67, 0xfd, 0x24, 0xca, 0x58, 0x97, 0x79, 0x97, 0x51,
- 0x9f, 0xb1, 0x29, 0xf8, 0x3e, 0xd5, 0x45, 0xe8, 0x19, 0x0f, 0xe9, 0xe3,
- 0x48, 0xc7, 0x91, 0x3e, 0x81, 0x54, 0xc7, 0xb1, 0x36, 0x9f, 0x61, 0x2c,
- 0x49, 0xc5, 0x68, 0x14, 0xbe, 0xa0, 0x4d, 0x9c, 0xf3, 0xa9, 0x27, 0x8f,
- 0x8b, 0x3d, 0x75, 0x1b, 0xf2, 0xe8, 0x6b, 0x63, 0xd4, 0xf7, 0x7f, 0xde,
- 0xc4, 0x88, 0x5a, 0x71, 0x25, 0x63, 0x07, 0xd6, 0xd0, 0x17, 0xfb, 0xa1,
- 0x2f, 0xfb, 0x0b, 0x79, 0xf8, 0x9a, 0xd8, 0x5c, 0x2b, 0xde, 0x34, 0x5d,
- 0x50, 0x3a, 0x96, 0x7c, 0x81, 0x7e, 0x75, 0x33, 0xf2, 0xb5, 0xed, 0x01,
- 0xe8, 0xaf, 0x38, 0xb1, 0x26, 0xf0, 0xb6, 0xc6, 0x6e, 0x8b, 0x98, 0x9b,
- 0xb6, 0xef, 0x71, 0xf9, 0xbb, 0xb5, 0x61, 0xf9, 0x71, 0x25, 0x21, 0xaf,
- 0x57, 0x82, 0xe0, 0xa2, 0x9f, 0xf6, 0xef, 0x13, 0xb9, 0xbd, 0x5b, 0x9f,
- 0xfd, 0xa3, 0x86, 0x3e, 0xaf, 0x2f, 0xab, 0x33, 0x7b, 0xd4, 0x83, 0x5e,
- 0x79, 0xbd, 0xf9, 0xf7, 0xe0, 0xaf, 0xee, 0xb3, 0xb3, 0xed, 0xae, 0x6e,
- 0xcb, 0x33, 0xff, 0xc4, 0x8e, 0xa4, 0xcd, 0xdd, 0x81, 0x34, 0xda, 0xa6,
- 0xc7, 0x37, 0x5a, 0xed, 0xd9, 0x36, 0xa3, 0xec, 0x40, 0x71, 0x73, 0x50,
- 0x1a, 0x7f, 0xca, 0xfd, 0x01, 0xbf, 0x53, 0x9d, 0xcb, 0x30, 0xe5, 0x39,
- 0x07, 0xeb, 0x24, 0x4d, 0xf9, 0x88, 0x29, 0xf7, 0x54, 0x6c, 0x70, 0xb9,
- 0x4a, 0x19, 0x85, 0x1f, 0x4a, 0x6c, 0xd8, 0x24, 0x76, 0x0d, 0xe3, 0x61,
- 0xd4, 0xd3, 0xb3, 0x52, 0x56, 0x71, 0x2d, 0xda, 0xa0, 0x5e, 0x15, 0xd3,
- 0xd2, 0xb1, 0x3e, 0x96, 0x3d, 0x2c, 0x73, 0xee, 0x71, 0x19, 0x98, 0xba,
- 0x36, 0x6e, 0xd7, 0xeb, 0x1d, 0x87, 0x6f, 0xa5, 0xec, 0xac, 0xfb, 0x41,
- 0x21, 0x8f, 0xbb, 0x69, 0x17, 0x72, 0xb6, 0x05, 0xdf, 0xf4, 0xcb, 0x19,
- 0x79, 0x7e, 0x3b, 0x95, 0x14, 0xac, 0xd7, 0x07, 0xe1, 0x7b, 0xda, 0xcf,
- 0xe1, 0x9d, 0x71, 0xae, 0x67, 0xe3, 0x12, 0x79, 0x76, 0x58, 0x7a, 0x56,
- 0x88, 0x3f, 0xc8, 0xd3, 0x84, 0x74, 0xaf, 0x10, 0xfb, 0x32, 0x2e, 0x9c,
- 0x9a, 0xbe, 0x22, 0x8c, 0xb7, 0xa4, 0xfc, 0x0b, 0xf8, 0xed, 0x62, 0xde,
- 0x3d, 0xf0, 0x9b, 0xbb, 0xcf, 0xea, 0x76, 0xf6, 0xd6, 0x10, 0x00, 0x1f,
- 0x7c, 0xee, 0x15, 0xfa, 0xd9, 0x4c, 0xe9, 0x77, 0xb3, 0x0c, 0xb2, 0xbd,
- 0x35, 0x62, 0xca, 0xe8, 0x53, 0x73, 0x7c, 0x9e, 0xd9, 0xeb, 0x7b, 0xa0,
- 0xf6, 0x18, 0x7d, 0x52, 0x5f, 0x5e, 0xdc, 0x60, 0x0c, 0xfc, 0x55, 0xf8,
- 0x6f, 0x19, 0x89, 0xac, 0x64, 0x20, 0x87, 0x3e, 0x6c, 0x29, 0x71, 0x1c,
- 0xed, 0x17, 0xf2, 0x61, 0x73, 0x36, 0x9e, 0x51, 0x31, 0x87, 0x92, 0x93,
- 0x85, 0xcc, 0xd5, 0x3f, 0x63, 0x97, 0xdb, 0x6c, 0x54, 0xd9, 0xd8, 0xa8,
- 0xb2, 0xb1, 0x51, 0xe5, 0x66, 0xb8, 0x3f, 0x38, 0xc6, 0x71, 0xd8, 0xd5,
- 0x2e, 0x79, 0x2a, 0x4e, 0x59, 0xd1, 0xb2, 0x17, 0xb1, 0xc7, 0x94, 0xac,
- 0xce, 0xd0, 0xde, 0x3e, 0xe3, 0xee, 0x83, 0xaf, 0x55, 0x52, 0x7b, 0xe3,
- 0x99, 0x50, 0xce, 0x78, 0xe7, 0x33, 0x90, 0x1a, 0xb0, 0x4c, 0xd9, 0xb3,
- 0x64, 0xc9, 0x3b, 0xae, 0xb0, 0xde, 0xc3, 0xe8, 0xe3, 0x49, 0xd3, 0xc7,
- 0x92, 0x8c, 0x19, 0x79, 0xe7, 0xda, 0x44, 0xd5, 0x79, 0xc5, 0x43, 0xfe,
- 0xef, 0xc9, 0xc0, 0x20, 0xd7, 0x93, 0xf2, 0x4f, 0x7c, 0xc1, 0xf5, 0x60,
- 0x8c, 0xff, 0x6d, 0x63, 0xa9, 0xea, 0x0e, 0x5f, 0xa1, 0x42, 0x5b, 0xb2,
- 0x1f, 0xf2, 0x9b, 0x81, 0xff, 0x1d, 0xc6, 0x53, 0xd5, 0xbe, 0x4a, 0xd8,
- 0x36, 0xec, 0xda, 0xd8, 0xd8, 0x78, 0x51, 0x8e, 0x4b, 0x19, 0x7e, 0x2b,
- 0x69, 0x58, 0x82, 0x1d, 0xdb, 0xf0, 0xff, 0x2e, 0xf8, 0x64, 0x3c, 0x55,
- 0x9a, 0x97, 0xce, 0x18, 0x27, 0x7d, 0xf1, 0xb7, 0x8b, 0x73, 0x1e, 0x51,
- 0xfa, 0xf1, 0x5a, 0x2c, 0x15, 0xc6, 0x38, 0xe7, 0x3a, 0x62, 0x9c, 0xfa,
- 0xec, 0xac, 0x27, 0x4b, 0xbd, 0x7e, 0xca, 0xfa, 0x71, 0x26, 0x22, 0x0d,
- 0x60, 0xca, 0xfb, 0x7c, 0x62, 0xa4, 0x92, 0xf5, 0x7a, 0x45, 0xd4, 0x7b,
- 0xc1, 0x8f, 0xe8, 0x58, 0xbb, 0x0b, 0xdb, 0xb2, 0xed, 0x98, 0xb3, 0x22,
- 0x07, 0x79, 0xb6, 0xf2, 0x77, 0x8b, 0x4a, 0x27, 0x27, 0xfa, 0x24, 0x46,
- 0x3d, 0x75, 0x2f, 0xde, 0x79, 0x5e, 0x71, 0xa4, 0x23, 0x7f, 0x67, 0x80,
- 0x7b, 0xac, 0x0c, 0x3c, 0xb6, 0xe4, 0x69, 0x7e, 0x39, 0xe0, 0xf1, 0x0c,
- 0x30, 0xce, 0x95, 0x26, 0x71, 0x6d, 0xcc, 0xe0, 0x5a, 0xe2, 0x26, 0xac,
- 0xd1, 0xf6, 0x28, 0xca, 0x88, 0x9d, 0xe2, 0xca, 0xaf, 0x53, 0x58, 0xca,
- 0x2f, 0x18, 0x3b, 0x41, 0x99, 0xa2, 0x3c, 0x11, 0x93, 0x69, 0x99, 0x5a,
- 0xa8, 0xb8, 0x1d, 0xf2, 0xe4, 0xfe, 0x23, 0xe5, 0xe9, 0xa6, 0x3e, 0x9e,
- 0xf7, 0xbc, 0x84, 0xfd, 0x79, 0x12, 0xf6, 0x74, 0xa3, 0xb6, 0x4f, 0x76,
- 0x6b, 0xa3, 0xc0, 0xc5, 0xcc, 0xe3, 0xbe, 0x4c, 0xc8, 0xfd, 0x95, 0x59,
- 0x39, 0x5c, 0x8b, 0xca, 0xc5, 0x9a, 0x7d, 0x4f, 0x8f, 0x30, 0x46, 0x4d,
- 0xcc, 0xf1, 0x0d, 0xa5, 0xd7, 0x7e, 0xe2, 0x5f, 0x6d, 0xbf, 0x84, 0xf6,
- 0x0d, 0xb4, 0x5f, 0xa8, 0xdd, 0x28, 0x45, 0xd5, 0x7e, 0xfd, 0xba, 0x31,
- 0xae, 0xd6, 0xe9, 0x33, 0xf6, 0x33, 0x3c, 0x97, 0xa4, 0x6d, 0xee, 0xc2,
- 0xbc, 0xe1, 0x27, 0x65, 0x90, 0xd6, 0x79, 0x36, 0x49, 0xdb, 0xfe, 0x47,
- 0xae, 0x4e, 0x13, 0x6d, 0x76, 0x21, 0xd9, 0x66, 0x17, 0xde, 0x68, 0xbb,
- 0x4b, 0xa9, 0xef, 0x65, 0xbf, 0x9c, 0x01, 0xf6, 0xab, 0x0d, 0xb5, 0xdd,
- 0xa9, 0x48, 0x95, 0x68, 0x93, 0x18, 0x0b, 0xdb, 0xac, 0x84, 0xba, 0x3a,
- 0x37, 0xc0, 0x38, 0xfe, 0xb2, 0x4f, 0xbe, 0x4b, 0x32, 0x92, 0xa5, 0xae,
- 0xf7, 0xa3, 0xbb, 0xc0, 0x68, 0x0d, 0x75, 0x4e, 0x1d, 0xc1, 0x0f, 0xb6,
- 0xd0, 0xb1, 0xc4, 0xf5, 0x98, 0x57, 0xd2, 0x58, 0xd7, 0x85, 0xde, 0xb4,
- 0x55, 0x9d, 0x64, 0xde, 0xbf, 0xc9, 0xbc, 0x43, 0xbf, 0x55, 0xde, 0x3b,
- 0x6c, 0x67, 0xff, 0xfb, 0xcd, 0xf9, 0x0c, 0xcf, 0x0e, 0x99, 0x47, 0xcc,
- 0xfb, 0x03, 0x60, 0x5e, 0xde, 0xb7, 0xe5, 0xba, 0xbc, 0x89, 0xf5, 0xbf,
- 0x08, 0xdb, 0xe2, 0x41, 0xaf, 0x3b, 0xb2, 0x90, 0xb9, 0x68, 0xce, 0x2e,
- 0x38, 0xb7, 0x6e, 0xd8, 0xa8, 0x1f, 0xc9, 0xe1, 0xb5, 0x14, 0xb0, 0x4a,
- 0x88, 0xaf, 0xd8, 0xc7, 0xf5, 0xd8, 0xea, 0x44, 0xb5, 0xfd, 0xfc, 0x37,
- 0xbc, 0x3f, 0x4a, 0xd9, 0x50, 0xe7, 0xda, 0x56, 0x81, 0xf1, 0xc0, 0xd5,
- 0x1f, 0x60, 0x9e, 0xa9, 0x53, 0x22, 0x3c, 0xeb, 0x62, 0x9c, 0x17, 0x3e,
- 0xc2, 0x36, 0xf3, 0xe7, 0xd0, 0xf7, 0x0f, 0x78, 0x97, 0x16, 0xfe, 0x93,
- 0x6d, 0xf8, 0xf3, 0xfb, 0xc6, 0xbf, 0x8f, 0x32, 0x36, 0x0a, 0xd9, 0x2f,
- 0x2b, 0xdb, 0x5d, 0x8c, 0x2f, 0x23, 0xfd, 0x1f, 0xc6, 0x56, 0x7f, 0xbd,
- 0x4f, 0xdb, 0x6a, 0xde, 0x03, 0xf9, 0x02, 0xf7, 0x96, 0xa1, 0x9b, 0xf4,
- 0x92, 0xee, 0x2e, 0xe9, 0x3e, 0x4d, 0x9a, 0xbf, 0x82, 0x7a, 0x94, 0x8d,
- 0x83, 0xe6, 0xbe, 0x08, 0xcf, 0xc1, 0xd9, 0x27, 0x6c, 0x84, 0xc2, 0x5b,
- 0x39, 0xa4, 0x6c, 0xb7, 0x86, 0x7a, 0x39, 0xcc, 0x59, 0x61, 0xb0, 0xa1,
- 0x88, 0x84, 0x79, 0xf7, 0x22, 0x8f, 0x3e, 0xe5, 0x4d, 0xf0, 0x29, 0x99,
- 0x97, 0xc7, 0x3b, 0xc7, 0xba, 0xd9, 0x8c, 0x63, 0x30, 0xdd, 0x35, 0x34,
- 0x71, 0x2e, 0xe1, 0x5a, 0x77, 0x9b, 0x33, 0x73, 0xe6, 0xdd, 0x64, 0xf2,
- 0x1c, 0x33, 0xbf, 0x61, 0x73, 0x8f, 0x3d, 0x75, 0x2a, 0x27, 0xa1, 0xec,
- 0x93, 0xbe, 0x68, 0x1b, 0x16, 0xfc, 0x83, 0xc1, 0xab, 0x77, 0x1c, 0x29,
- 0x6b, 0x94, 0xaf, 0x84, 0xba, 0xbf, 0xc7, 0xf3, 0xf2, 0x17, 0x14, 0xfe,
- 0x0e, 0x71, 0x95, 0xd2, 0x65, 0x3c, 0x07, 0xa8, 0xd9, 0xd9, 0x9e, 0xdf,
- 0xf9, 0x3e, 0x5b, 0x24, 0x1b, 0xb6, 0x03, 0x1e, 0x52, 0x6d, 0x92, 0xb2,
- 0xd8, 0x7c, 0xbb, 0xbb, 0x6f, 0xc0, 0x68, 0xd7, 0xdc, 0x67, 0x49, 0x28,
- 0xfd, 0xb3, 0x51, 0x8b, 0x80, 0xbf, 0x43, 0x78, 0xbe, 0x0c, 0x1e, 0x44,
- 0x31, 0x4f, 0xe0, 0xf4, 0xf8, 0x4d, 0xea, 0xbe, 0x4f, 0xc4, 0xbb, 0xa4,
- 0xce, 0x8d, 0x0a, 0xf5, 0x9f, 0xa9, 0xb2, 0xaf, 0xad, 0xf5, 0xf0, 0x0e,
- 0x28, 0x52, 0x9e, 0x43, 0xff, 0x06, 0x32, 0xd8, 0x65, 0x64, 0x10, 0x69,
- 0x9d, 0xf9, 0xb7, 0xc0, 0x87, 0x14, 0xc8, 0x4b, 0x37, 0xb0, 0xbd, 0xf2,
- 0x13, 0x30, 0x9b, 0xab, 0x34, 0x74, 0x67, 0xc3, 0x3b, 0x97, 0x81, 0x1c,
- 0x86, 0x6c, 0x6c, 0x4c, 0x2f, 0x4b, 0x63, 0xba, 0x1d, 0x27, 0x02, 0x07,
- 0xba, 0xa5, 0xa0, 0xe1, 0x31, 0xd6, 0xd7, 0x6f, 0xee, 0xbf, 0x2d, 0x1a,
- 0x6c, 0x47, 0xfe, 0xdb, 0x52, 0x98, 0x5c, 0x52, 0x32, 0xd5, 0x50, 0xeb,
- 0xe0, 0x58, 0xe7, 0xd5, 0xdd, 0x59, 0x8e, 0xc1, 0xfb, 0xb3, 0x11, 0x83,
- 0x71, 0xfe, 0xa9, 0x59, 0xcf, 0xef, 0xf7, 0x85, 0xdf, 0x64, 0x74, 0x65,
- 0x4f, 0xf2, 0xce, 0x08, 0xf0, 0x6b, 0x6d, 0x76, 0xa1, 0x42, 0xbd, 0x16,
- 0x04, 0x0d, 0x7f, 0x07, 0x3d, 0xbe, 0xa9, 0xf0, 0xd9, 0xae, 0x68, 0xfd,
- 0xb9, 0xa4, 0xee, 0xa1, 0x56, 0x66, 0xf3, 0x2a, 0xa6, 0x06, 0xdc, 0xd1,
- 0x3a, 0xbf, 0x78, 0xa7, 0xb3, 0x8b, 0x28, 0xfc, 0xe5, 0x5e, 0xb3, 0xee,
- 0x51, 0xa7, 0x58, 0xe9, 0x73, 0x16, 0xd4, 0xb9, 0xd2, 0xe7, 0xcc, 0xf7,
- 0x2b, 0xa5, 0xd9, 0x74, 0x33, 0xbb, 0x9f, 0x58, 0x9a, 0x31, 0xfd, 0x42,
- 0x85, 0x67, 0x19, 0xba, 0x3c, 0x6d, 0xca, 0x47, 0x9a, 0xaa, 0x4c, 0xc5,
- 0xe4, 0xe0, 0x77, 0xc1, 0xae, 0x30, 0xfe, 0x47, 0xdd, 0x82, 0xfe, 0xe3,
- 0x7a, 0x0e, 0x91, 0xec, 0x32, 0x7c, 0x3b, 0xd2, 0x77, 0x6a, 0x36, 0xbf,
- 0xc6, 0x7b, 0x47, 0x5f, 0x9a, 0xbd, 0x08, 0xff, 0x63, 0xcb, 0xd3, 0x77,
- 0xb5, 0x37, 0x19, 0x3b, 0x62, 0x3b, 0xd5, 0xe7, 0xb2, 0x89, 0x65, 0x9e,
- 0x9c, 0x1d, 0xdd, 0x8c, 0xc8, 0x49, 0xd3, 0x07, 0xdf, 0x93, 0x2d, 0xdf,
- 0x44, 0xe9, 0x3b, 0x60, 0xf0, 0x27, 0x80, 0xc1, 0x63, 0xb0, 0x8b, 0xc4,
- 0xf2, 0xc4, 0xb7, 0x31, 0xec, 0x15, 0x8e, 0xf3, 0xaf, 0xd5, 0x38, 0x11,
- 0x8c, 0xb3, 0xb0, 0x76, 0x40, 0xdd, 0x23, 0xc9, 0x7b, 0x0e, 0xec, 0x34,
- 0xec, 0xa9, 0xc7, 0x58, 0xb2, 0x8d, 0x39, 0x8f, 0x43, 0x1f, 0xf0, 0x6e,
- 0xc7, 0x60, 0x78, 0xef, 0x85, 0x77, 0xad, 0x4c, 0xbb, 0x4f, 0xa3, 0x1d,
- 0x31, 0x38, 0xdb, 0xca, 0x8d, 0xb6, 0x8c, 0x2a, 0xbb, 0xab, 0x75, 0x0e,
- 0x69, 0xa8, 0x63, 0xae, 0xb4, 0x5d, 0xd8, 0x6b, 0x6a, 0x5e, 0x9f, 0x56,
- 0xed, 0xac, 0xec, 0x53, 0xa0, 0x9d, 0xd8, 0x0a, 0x7d, 0x57, 0x75, 0x7c,
- 0xb0, 0xa0, 0xe4, 0x08, 0x72, 0x32, 0x1d, 0xde, 0x17, 0xd1, 0xed, 0xc2,
- 0xfa, 0x23, 0x9b, 0x9f, 0x35, 0xe3, 0xff, 0x32, 0xc8, 0x1d, 0x8d, 0xa9,
- 0xfb, 0x39, 0x2f, 0x5d, 0x73, 0x87, 0x8a, 0x6d, 0xc2, 0x3a, 0x11, 0x23,
- 0x5b, 0x27, 0xda, 0x68, 0xfe, 0x9c, 0x59, 0x73, 0xb6, 0x63, 0xfc, 0x94,
- 0x79, 0x25, 0xe6, 0x39, 0x8b, 0x19, 0xf6, 0xd1, 0x7e, 0xee, 0x32, 0x09,
- 0x5b, 0xae, 0x6d, 0x46, 0x69, 0xdb, 0x83, 0x4d, 0xec, 0xc6, 0xda, 0xd1,
- 0x06, 0x8c, 0x1a, 0xdc, 0xfe, 0x8e, 0x71, 0x49, 0xa7, 0x98, 0x81, 0x1f,
- 0xdf, 0x6a, 0xcf, 0x75, 0x2c, 0xcd, 0x5e, 0xac, 0x78, 0x72, 0xa2, 0xaa,
- 0xef, 0x37, 0x69, 0x3e, 0x50, 0x37, 0x73, 0x6d, 0x93, 0xb2, 0xe0, 0x31,
- 0xfe, 0x91, 0x94, 0x57, 0xbc, 0x76, 0x3d, 0x8d, 0xfa, 0xdb, 0x93, 0xe6,
- 0x8e, 0xf3, 0xa7, 0x31, 0x7f, 0xe2, 0x31, 0x2d, 0x4b, 0x07, 0x61, 0x77,
- 0xfe, 0x83, 0x43, 0x9d, 0xdd, 0x2d, 0x97, 0x9d, 0xf6, 0xf9, 0x85, 0x71,
- 0x6e, 0x2d, 0x97, 0x0e, 0x64, 0x64, 0xb9, 0xc5, 0x77, 0xf8, 0xbf, 0xef,
- 0x1b, 0x83, 0x8e, 0xb7, 0x64, 0x66, 0xd2, 0x4b, 0x2c, 0x31, 0xee, 0xef,
- 0x4e, 0xb8, 0xae, 0xba, 0xa7, 0x97, 0x04, 0xbd, 0x7c, 0x1e, 0x05, 0x06,
- 0xe1, 0x9d, 0x3a, 0xbc, 0xf3, 0x4e, 0x5b, 0xdc, 0x03, 0xbd, 0xae, 0x8a,
- 0xe7, 0x6b, 0x1d, 0xfd, 0xf5, 0xfd, 0x8c, 0xa7, 0x0c, 0x78, 0xe1, 0xda,
- 0xab, 0x7b, 0xcd, 0xe8, 0x3b, 0x62, 0xca, 0x07, 0x5b, 0xfc, 0x97, 0x21,
- 0xa6, 0xad, 0xbb, 0x52, 0x26, 0x6e, 0xc1, 0xfa, 0x9f, 0x51, 0xb4, 0x2c,
- 0x78, 0x41, 0xb0, 0xa8, 0xe6, 0xf3, 0x34, 0x64, 0x21, 0x22, 0xe5, 0x96,
- 0xfc, 0x3e, 0x0d, 0xf9, 0xdd, 0xc7, 0x6b, 0x35, 0x7b, 0xc8, 0x5a, 0x28,
- 0x63, 0x94, 0x2f, 0xca, 0x56, 0xa2, 0x9f, 0x7b, 0xae, 0xd4, 0x5a, 0x77,
- 0x47, 0xd9, 0xd8, 0xa4, 0x1d, 0xae, 0x3b, 0x9f, 0xf7, 0xba, 0x93, 0x14,
- 0xee, 0x8f, 0xcc, 0x3f, 0x62, 0x6d, 0x7d, 0xb3, 0xb6, 0x99, 0xb6, 0x6f,
- 0x0b, 0xc2, 0xfe, 0x18, 0x3b, 0x54, 0xf6, 0x38, 0x21, 0xd0, 0xd9, 0x25,
- 0x7d, 0xbf, 0x57, 0xe1, 0xd6, 0x9c, 0x9b, 0x4f, 0x32, 0x4e, 0x7c, 0x4c,
- 0xee, 0x02, 0xcd, 0xb9, 0xf1, 0x2e, 0xd1, 0x6d, 0xe7, 0xc1, 0xef, 0x1d,
- 0x17, 0xbe, 0x16, 0xcf, 0x6c, 0x2b, 0x8e, 0x6c, 0xa9, 0xb3, 0x47, 0xec,
- 0xd1, 0x98, 0x23, 0xcb, 0x5e, 0xd8, 0x6f, 0x54, 0xea, 0xa8, 0xb3, 0x81,
- 0xb2, 0x93, 0x2d, 0xda, 0x88, 0xd3, 0xe1, 0xa7, 0x78, 0xbf, 0x0c, 0x8a,
- 0xf1, 0x6b, 0xea, 0x9a, 0x7b, 0xfa, 0x8c, 0x77, 0xf4, 0x29, 0x1f, 0xaa,
- 0x00, 0x9f, 0xab, 0x00, 0x7f, 0xab, 0xa0, 0xf4, 0x02, 0xe3, 0x1f, 0x8c,
- 0x4f, 0x95, 0x80, 0xed, 0x4b, 0x41, 0x8f, 0x77, 0x5c, 0xc5, 0xdd, 0x5e,
- 0xd8, 0xa6, 0x0f, 0xe0, 0x25, 0xef, 0x97, 0xd0, 0x86, 0xf4, 0x97, 0xa2,
- 0xd9, 0xf6, 0x18, 0x56, 0x52, 0xc5, 0x80, 0x7a, 0x81, 0x43, 0x1f, 0x87,
- 0xae, 0x7e, 0xd1, 0x67, 0xec, 0xea, 0x56, 0xf2, 0xfb, 0x2b, 0x9c, 0xa4,
- 0x3d, 0x36, 0x29, 0xde, 0x59, 0x6f, 0xfc, 0x7e, 0x21, 0xb6, 0x4f, 0x25,
- 0x8f, 0x90, 0x6f, 0xad, 0xef, 0x04, 0x42, 0xbb, 0x3a, 0x29, 0xa3, 0x67,
- 0x7f, 0xa4, 0xce, 0x04, 0x3e, 0xe2, 0x77, 0xca, 0x86, 0x8a, 0x7d, 0x4d,
- 0x0e, 0xc8, 0x28, 0xfc, 0x4a, 0x81, 0x75, 0xe2, 0x77, 0x03, 0x96, 0x2c,
- 0x67, 0xd4, 0xbb, 0xcc, 0x35, 0x93, 0xe6, 0x9e, 0x25, 0x63, 0x5b, 0x8c,
- 0x8d, 0x71, 0x4d, 0xfb, 0xd4, 0xdd, 0x4a, 0xde, 0xff, 0x9b, 0x69, 0x6a,
- 0x9b, 0x9b, 0x53, 0x77, 0x1c, 0x19, 0x2b, 0x63, 0xcc, 0x4b, 0xdf, 0x9f,
- 0x3b, 0xdc, 0xdc, 0x2b, 0x2e, 0x16, 0xde, 0xf7, 0xd3, 0x76, 0x6b, 0x37,
- 0x73, 0x00, 0xb6, 0xce, 0x55, 0xf1, 0x89, 0xa2, 0x3b, 0x20, 0xc7, 0xc6,
- 0x7b, 0xc0, 0xf3, 0x41, 0x75, 0x17, 0xcd, 0xf6, 0xde, 0x2f, 0x5d, 0xb4,
- 0x9b, 0xae, 0xba, 0x23, 0x6d, 0xf8, 0x7c, 0x07, 0xf2, 0x7e, 0x05, 0xde,
- 0x33, 0xef, 0x63, 0xfd, 0xda, 0x0e, 0x7d, 0x0a, 0x78, 0x9b, 0xf7, 0xca,
- 0xeb, 0x07, 0xf2, 0x6a, 0x3d, 0xe8, 0xf7, 0x86, 0xba, 0x29, 0xbc, 0xff,
- 0x18, 0x85, 0x6d, 0x72, 0xcd, 0x79, 0x71, 0x49, 0x96, 0x88, 0x01, 0x37,
- 0xa9, 0x7f, 0x2c, 0x35, 0xd6, 0xe5, 0xc8, 0xbb, 0xa4, 0x54, 0xdf, 0xeb,
- 0xdc, 0x3b, 0x08, 0xbe, 0xe1, 0xab, 0x3b, 0x97, 0xa7, 0x4a, 0x66, 0x8d,
- 0xf5, 0x37, 0x85, 0x4e, 0xdb, 0x7d, 0xee, 0xa8, 0xd2, 0xbb, 0xb9, 0x41,
- 0x60, 0x15, 0xef, 0xa3, 0xfd, 0x57, 0xef, 0xf0, 0xfd, 0xc6, 0xe0, 0x58,
- 0xde, 0xdf, 0xd3, 0x77, 0xbb, 0xed, 0x46, 0x28, 0x27, 0xf4, 0x9b, 0x89,
- 0x9f, 0x0f, 0xc2, 0xa7, 0x86, 0xde, 0x1c, 0xe2, 0xfb, 0x5f, 0x9a, 0xb6,
- 0x7c, 0x0e, 0xe4, 0xbe, 0xa9, 0xce, 0x33, 0xed, 0x69, 0x7d, 0x0f, 0x3c,
- 0x16, 0xde, 0x73, 0x1f, 0xee, 0xb8, 0x9b, 0xa4, 0xe8, 0x84, 0x3c, 0x85,
- 0x34, 0xe8, 0xb1, 0x0e, 0x83, 0xde, 0x46, 0x2d, 0x21, 0x83, 0x1e, 0x7d,
- 0xc5, 0x88, 0x4c, 0x0d, 0xa6, 0x5a, 0x77, 0xcd, 0x1b, 0x75, 0xd8, 0xfc,
- 0x5a, 0x48, 0xa7, 0xbe, 0x6b, 0xd8, 0xa8, 0xb3, 0x3c, 0x89, 0xb1, 0x7a,
- 0x64, 0x6a, 0x88, 0x7c, 0xee, 0xa4, 0x23, 0x61, 0xee, 0x23, 0x77, 0xe6,
- 0xdf, 0xdd, 0x46, 0xdf, 0xf5, 0xdf, 0x62, 0xea, 0xfb, 0x8f, 0xbc, 0xcb,
- 0x4e, 0x1a, 0x79, 0xce, 0x82, 0x39, 0xfa, 0xa1, 0x6f, 0x11, 0xf2, 0x65,
- 0x50, 0xdd, 0x97, 0x2f, 0xd4, 0xbb, 0x94, 0x5c, 0x2c, 0x64, 0x38, 0x17,
- 0xe2, 0xa0, 0xf0, 0x4e, 0xfc, 0x3f, 0x39, 0xa0, 0xd7, 0xfc, 0x63, 0xe1,
- 0x1c, 0x4d, 0x3e, 0xdb, 0xdf, 0x82, 0x36, 0x5f, 0x0d, 0xd0, 0x3f, 0x83,
- 0x5b, 0xd8, 0xf3, 0x21, 0x36, 0xbf, 0x45, 0xb7, 0x8f, 0x85, 0xdf, 0xe3,
- 0xb5, 0x7f, 0x1f, 0xc0, 0x3d, 0x15, 0xf2, 0x8d, 0x7d, 0x70, 0x7c, 0xd2,
- 0xc1, 0x71, 0x7b, 0xdb, 0xc6, 0x55, 0x3f, 0xff, 0x5a, 0xbd, 0x76, 0x47,
- 0xdb, 0x7c, 0x29, 0x5f, 0xfd, 0xb2, 0x54, 0x8b, 0x49, 0xb9, 0xa6, 0xfc,
- 0x99, 0x71, 0x20, 0x36, 0xe0, 0x39, 0xee, 0x45, 0x75, 0xff, 0xd6, 0xdc,
- 0x2d, 0x0c, 0xf7, 0x64, 0x3f, 0xea, 0xd1, 0x6e, 0x20, 0xad, 0x6b, 0x9d,
- 0x54, 0x97, 0xeb, 0xbf, 0x77, 0x58, 0x6c, 0x7d, 0xef, 0xa0, 0xfd, 0xe3,
- 0x62, 0xeb, 0x6e, 0x46, 0xb4, 0x34, 0x98, 0x6d, 0xbf, 0xef, 0x53, 0x92,
- 0x87, 0xee, 0xe4, 0x77, 0x06, 0x31, 0x23, 0x97, 0xef, 0x37, 0xe3, 0x60,
- 0xbc, 0xd5, 0x69, 0x19, 0x59, 0xfd, 0xbc, 0x14, 0xe7, 0xd4, 0x9d, 0xed,
- 0xb6, 0x3b, 0xfb, 0xa3, 0xe6, 0x3b, 0xa2, 0x9c, 0xc5, 0x3b, 0x20, 0x85,
- 0x55, 0xac, 0xd1, 0x9d, 0xa9, 0xf1, 0xa4, 0xcd, 0x6f, 0x59, 0x1f, 0x95,
- 0x91, 0xf5, 0x69, 0x49, 0xaf, 0x12, 0x27, 0xf0, 0x74, 0x3c, 0xa5, 0xe2,
- 0x8d, 0xe9, 0x73, 0xba, 0x3f, 0x6f, 0x95, 0xe5, 0x69, 0x60, 0x54, 0x96,
- 0x17, 0x12, 0x11, 0x75, 0x82, 0x7e, 0x1b, 0x64, 0xa8, 0xdb, 0x60, 0x00,
- 0x47, 0xf2, 0xab, 0x6c, 0x4f, 0xbc, 0xf1, 0x1c, 0xd6, 0xac, 0x90, 0xb4,
- 0x85, 0x6d, 0x54, 0x7f, 0x78, 0x8e, 0x2a, 0xec, 0x5c, 0xc8, 0x90, 0xd7,
- 0x93, 0xb2, 0xd9, 0xf4, 0xb0, 0x0f, 0xf4, 0x3d, 0xff, 0x62, 0x3d, 0xbc,
- 0x77, 0xf9, 0x90, 0xf9, 0x6e, 0x40, 0xd3, 0x38, 0x53, 0xe9, 0x94, 0xb7,
- 0xc7, 0xcc, 0x7d, 0x7f, 0xce, 0xdb, 0x6d, 0xd7, 0x79, 0xa6, 0xfe, 0x6b,
- 0x07, 0x78, 0x96, 0x4e, 0x9f, 0x68, 0xa4, 0xdd, 0xff, 0x88, 0xc7, 0xcd,
- 0x77, 0x16, 0x61, 0xbd, 0xff, 0x7d, 0x40, 0xdf, 0xd5, 0x27, 0x9f, 0xb2,
- 0x86, 0xe6, 0x29, 0xe5, 0xdf, 0xbc, 0x54, 0x3d, 0x88, 0xb6, 0x5c, 0x27,
- 0xa4, 0x0d, 0x3e, 0x53, 0x6f, 0x1e, 0x31, 0x67, 0x4e, 0x43, 0x6a, 0x2c,
- 0x37, 0xdb, 0xfe, 0x0d, 0x48, 0x6f, 0xdb, 0xf8, 0x9d, 0xf4, 0xf2, 0x9b,
- 0x90, 0x8b, 0x46, 0x5e, 0x58, 0xce, 0xf7, 0xce, 0x3a, 0x87, 0x0e, 0x84,
- 0xe5, 0x4e, 0xeb, 0xbb, 0x01, 0xf2, 0x92, 0xe7, 0x65, 0x48, 0x79, 0x4e,
- 0xa9, 0x9e, 0x91, 0x9a, 0xef, 0x21, 0x9c, 0x55, 0xfe, 0x3a, 0xfb, 0x71,
- 0xd0, 0x77, 0xb8, 0x4f, 0xf7, 0xba, 0x17, 0x43, 0xfd, 0x7b, 0xca, 0xda,
- 0xad, 0x44, 0xe9, 0xef, 0xc8, 0xb1, 0x4c, 0x3f, 0xfc, 0x7d, 0x9b, 0xdf,
- 0x78, 0x32, 0xb6, 0xc9, 0x33, 0x3d, 0x59, 0x54, 0x7a, 0x6d, 0x4c, 0xf4,
- 0xf7, 0xad, 0xbd, 0x32, 0xe3, 0x52, 0x9e, 0xc7, 0x64, 0xb3, 0x3e, 0xd7,
- 0x76, 0x57, 0xb6, 0xdb, 0xc8, 0xd9, 0x2b, 0x5d, 0x12, 0x2b, 0x59, 0x17,
- 0x2a, 0xe1, 0x3e, 0x1e, 0x93, 0x99, 0x7a, 0xfb, 0x7d, 0x68, 0xde, 0xb3,
- 0xa1, 0xdc, 0x0e, 0xb7, 0xed, 0x3d, 0xde, 0x4d, 0x03, 0x96, 0x8a, 0xd3,
- 0x1f, 0x65, 0xbd, 0xfd, 0xc6, 0xc6, 0x7e, 0xd4, 0x95, 0x98, 0x6b, 0x89,
- 0x47, 0xda, 0xfa, 0x4d, 0x5c, 0x3e, 0x2d, 0xf7, 0xc5, 0x4b, 0xf0, 0xc7,
- 0xc6, 0xcc, 0xb8, 0xef, 0xc1, 0x3b, 0xeb, 0x1e, 0x30, 0xe5, 0xb7, 0x98,
- 0xf7, 0x98, 0x79, 0x8f, 0xe0, 0x9d, 0x77, 0xac, 0xd9, 0x27, 0xd3, 0xe7,
- 0x55, 0xdc, 0x65, 0x20, 0x9b, 0x95, 0xae, 0x73, 0x02, 0xdb, 0x14, 0x93,
- 0xc7, 0xea, 0x8a, 0xbf, 0x96, 0xb7, 0x4a, 0x10, 0x70, 0x83, 0x79, 0xbe,
- 0x7e, 0x0f, 0x3e, 0x75, 0xcd, 0x37, 0x47, 0x7f, 0xe8, 0x6a, 0x59, 0x69,
- 0xa7, 0xf7, 0x6e, 0xd0, 0xfa, 0x76, 0xf7, 0x8f, 0x68, 0x97, 0xb4, 0x9f,
- 0x38, 0x53, 0xa1, 0x0e, 0xcc, 0xca, 0xb1, 0x0a, 0x68, 0xad, 0x0d, 0xbb,
- 0xfa, 0x9e, 0x08, 0xf9, 0xa5, 0xef, 0x0d, 0xe6, 0x6b, 0x63, 0xe6, 0x7c,
- 0x97, 0x6d, 0x79, 0x8f, 0x91, 0x7c, 0x8b, 0x76, 0xc4, 0x11, 0x68, 0x7f,
- 0x68, 0x5b, 0xf8, 0x2d, 0x8e, 0x8f, 0xba, 0xcb, 0xd4, 0x35, 0xb0, 0x4d,
- 0x21, 0x7e, 0xf8, 0x82, 0x89, 0x47, 0x85, 0x76, 0x9e, 0xdf, 0x47, 0x8b,
- 0xfc, 0x67, 0x60, 0x57, 0xfb, 0x74, 0xaf, 0x44, 0x4e, 0x87, 0x77, 0x90,
- 0xb8, 0xc6, 0xa3, 0xea, 0x8e, 0xd9, 0x6e, 0xf3, 0xc3, 0x28, 0x0b, 0xcf,
- 0x8a, 0xbb, 0xcc, 0x59, 0x71, 0x28, 0xe7, 0x70, 0x34, 0x62, 0x51, 0xc8,
- 0x38, 0xdb, 0xe7, 0x14, 0x5f, 0x73, 0x71, 0xe2, 0xac, 0x83, 0x26, 0x6e,
- 0xc0, 0xb2, 0x92, 0x0c, 0xdc, 0xf9, 0x61, 0xee, 0x8d, 0x77, 0x47, 0x24,
- 0xfc, 0x8e, 0x40, 0x8d, 0x13, 0xd7, 0xb8, 0x91, 0xdf, 0x57, 0xfb, 0xd8,
- 0x57, 0xfb, 0x76, 0xc2, 0xef, 0x08, 0xce, 0x37, 0x33, 0xea, 0x7b, 0x05,
- 0x9e, 0x25, 0xec, 0xf2, 0x1e, 0xd6, 0x2a, 0xbf, 0xa5, 0xa6, 0x6c, 0x9b,
- 0xef, 0xa8, 0xfb, 0x87, 0xe5, 0xe5, 0xa6, 0xfe, 0xf6, 0x42, 0xdf, 0xed,
- 0x25, 0x3e, 0x4b, 0xa2, 0x9c, 0x77, 0xc7, 0xf8, 0xad, 0x03, 0xff, 0x9f,
- 0xc2, 0x23, 0x48, 0x3f, 0x25, 0x1b, 0x15, 0x1d, 0xcf, 0x2c, 0xc3, 0x7f,
- 0x18, 0x59, 0x75, 0xd5, 0x99, 0xcb, 0xc8, 0xea, 0x0c, 0xc6, 0x0b, 0xbf,
- 0x7d, 0x8e, 0x23, 0x8f, 0xf4, 0x95, 0xcc, 0x1e, 0x0d, 0xef, 0x4b, 0xfc,
- 0x57, 0x97, 0x36, 0xa1, 0xd4, 0xec, 0x43, 0x5d, 0xcb, 0x60, 0x10, 0xe2,
- 0xbb, 0xf0, 0x1b, 0xaf, 0x18, 0x6d, 0x54, 0x40, 0x9d, 0x94, 0xc6, 0x38,
- 0x8d, 0x0a, 0xef, 0x5d, 0xa8, 0xff, 0xc3, 0xe0, 0x16, 0xe9, 0xa3, 0x29,
- 0x1d, 0x9f, 0x1a, 0x9f, 0x97, 0x82, 0xdb, 0x25, 0x09, 0xf5, 0x7f, 0x1d,
- 0x6c, 0xcc, 0x3d, 0xbf, 0xd6, 0xb7, 0x13, 0xc9, 0x72, 0x6e, 0x1c, 0x9b,
- 0xbe, 0x87, 0x9e, 0x0f, 0xbf, 0x19, 0x71, 0xb2, 0xbc, 0xdb, 0xcd, 0xef,
- 0x9e, 0x98, 0x5f, 0x02, 0xce, 0x0a, 0xbf, 0x73, 0xd1, 0xdf, 0x31, 0xcc,
- 0x37, 0x8f, 0xc8, 0x89, 0xca, 0x7e, 0x7e, 0x6f, 0xe1, 0xef, 0x82, 0x6f,
- 0xc7, 0x9a, 0x7d, 0xea, 0x5b, 0x8a, 0xf9, 0x26, 0xef, 0x8f, 0x85, 0xb6,
- 0x87, 0x6b, 0x15, 0x57, 0x67, 0x18, 0x2f, 0xa8, 0x6f, 0x2d, 0xf4, 0x77,
- 0x16, 0x8f, 0xa9, 0xef, 0x16, 0xf4, 0x7e, 0xbf, 0x1e, 0x7b, 0x53, 0x06,
- 0x3f, 0x07, 0x7f, 0x50, 0xeb, 0xdd, 0xfb, 0x32, 0xbc, 0x23, 0x19, 0x04,
- 0xc7, 0x7c, 0xc6, 0x45, 0x73, 0xd3, 0x1b, 0x98, 0xe3, 0x85, 0x3a, 0x78,
- 0x78, 0x94, 0x79, 0xbc, 0x43, 0xd5, 0x23, 0xf9, 0x49, 0xf5, 0x1d, 0xba,
- 0xb5, 0xe1, 0xed, 0x97, 0xf3, 0x35, 0xee, 0x05, 0x07, 0xf3, 0x4e, 0xb9,
- 0x0d, 0xb9, 0x61, 0x80, 0x67, 0x60, 0x87, 0x55, 0xfb, 0x70, 0xbf, 0xeb,
- 0x58, 0xc1, 0xe1, 0x4d, 0xad, 0x4f, 0x78, 0xbf, 0xae, 0xeb, 0xac, 0x58,
- 0x1f, 0xcf, 0x0c, 0xc3, 0xdf, 0xe6, 0x58, 0x69, 0xb4, 0x83, 0xec, 0x24,
- 0xb8, 0xd7, 0x7f, 0x15, 0x34, 0x40, 0xef, 0x95, 0x26, 0x31, 0x3a, 0x70,
- 0xd3, 0x1c, 0xdb, 0x64, 0xc5, 0x5e, 0x61, 0x9d, 0x41, 0xc8, 0x5f, 0x17,
- 0xe6, 0xe3, 0x00, 0xff, 0x1f, 0x90, 0x86, 0xcb, 0x32, 0x3e, 0x27, 0x4c,
- 0x6c, 0x42, 0x7d, 0x23, 0x0c, 0xfe, 0x25, 0x95, 0x4e, 0xca, 0xb9, 0x7a,
- 0x7c, 0xde, 0xe1, 0x5c, 0xa8, 0xcd, 0x62, 0x0f, 0x39, 0x06, 0x8f, 0x39,
- 0xe8, 0xe3, 0xd7, 0xe6, 0xbb, 0x8c, 0x92, 0x14, 0x32, 0x1a, 0x7f, 0x68,
- 0x1b, 0xc3, 0xf3, 0x12, 0x07, 0xf8, 0x3f, 0xdc, 0x97, 0x8f, 0x1d, 0xb8,
- 0xf6, 0xfb, 0x0d, 0x62, 0x97, 0x74, 0xe2, 0x0c, 0xcf, 0xb9, 0xb6, 0x1f,
- 0x94, 0x79, 0xd0, 0x7c, 0xca, 0xcc, 0xf3, 0xfe, 0x8c, 0x27, 0x97, 0xeb,
- 0x68, 0x93, 0x39, 0x88, 0x94, 0x77, 0xfd, 0x48, 0xf3, 0x84, 0xb9, 0xc7,
- 0x98, 0xc5, 0x5c, 0x1f, 0x95, 0xd7, 0x80, 0xa9, 0x5f, 0xaf, 0xa4, 0xfd,
- 0xc3, 0xea, 0x8e, 0x4e, 0x2a, 0x71, 0x5e, 0x26, 0x92, 0xf4, 0xfb, 0x4a,
- 0x6e, 0x2a, 0x71, 0x59, 0x78, 0xd7, 0xe8, 0xb1, 0x01, 0xfe, 0x4f, 0x87,
- 0x06, 0xec, 0xa1, 0xbe, 0x73, 0x94, 0x62, 0x9c, 0x04, 0xef, 0xc3, 0xe6,
- 0xbb, 0x22, 0x8e, 0xc3, 0xb2, 0x61, 0x79, 0xad, 0xd2, 0xb2, 0xbf, 0x1c,
- 0xc7, 0x7c, 0x4b, 0xce, 0xb1, 0xfe, 0xed, 0x00, 0xf5, 0x10, 0xc7, 0xd3,
- 0x7d, 0x84, 0x75, 0xc8, 0x57, 0xbd, 0xc6, 0xf9, 0x8c, 0xfa, 0xae, 0x35,
- 0x29, 0x96, 0x25, 0xdd, 0x1e, 0xe7, 0x7e, 0xd3, 0x80, 0xc6, 0x40, 0x6c,
- 0x97, 0x76, 0xef, 0x53, 0xfd, 0xf1, 0xac, 0x8c, 0xe7, 0x49, 0x61, 0x3f,
- 0xbc, 0x33, 0x84, 0x75, 0x8f, 0x73, 0xbd, 0xdb, 0x69, 0xd0, 0xf6, 0xff,
- 0x35, 0x15, 0xa3, 0x9e, 0x46, 0x7d, 0xda, 0x68, 0xc8, 0x4b, 0x3d, 0xd1,
- 0xfa, 0x36, 0x42, 0xf3, 0x92, 0xcf, 0x8f, 0xb5, 0xbe, 0x4f, 0xb0, 0x6f,
- 0x77, 0x4d, 0x79, 0x88, 0x45, 0x87, 0xb1, 0x5f, 0x1f, 0x95, 0xc6, 0x5a,
- 0x3a, 0xf1, 0x98, 0x84, 0xfd, 0x06, 0x87, 0x78, 0x8e, 0x30, 0x93, 0x99,
- 0x70, 0x97, 0x14, 0x3d, 0xa9, 0x04, 0xef, 0xdd, 0x9e, 0xc7, 0x78, 0x8d,
- 0x66, 0x67, 0xbc, 0x21, 0x95, 0xdb, 0x91, 0xb4, 0xaf, 0xd7, 0x66, 0x4c,
- 0x76, 0xb0, 0x36, 0x5f, 0x32, 0x6b, 0xf3, 0x41, 0xf4, 0xed, 0xad, 0x4c,
- 0x4a, 0x7a, 0x25, 0x9d, 0x3c, 0x25, 0x3c, 0x9b, 0x3b, 0xc0, 0xb8, 0x95,
- 0x75, 0x7f, 0x26, 0x89, 0xf9, 0xa6, 0x30, 0x5f, 0xa4, 0x4d, 0x3e, 0x4f,
- 0xc0, 0x1f, 0xdf, 0xc7, 0xbd, 0x7d, 0x88, 0x3a, 0x93, 0xbc, 0x98, 0x51,
- 0x65, 0x8f, 0x9a, 0xbb, 0x94, 0xdf, 0xe3, 0xfa, 0xa8, 0xb8, 0xdf, 0xe5,
- 0x26, 0xcf, 0xeb, 0x34, 0x7d, 0x05, 0xd0, 0xb7, 0xa8, 0xe9, 0x4b, 0xce,
- 0xb7, 0xf0, 0x6a, 0x2a, 0x71, 0x42, 0x88, 0x97, 0x88, 0x5f, 0x88, 0xe5,
- 0x6f, 0x19, 0xd4, 0xdf, 0x7e, 0xc0, 0x77, 0xbd, 0x3d, 0xd7, 0x9a, 0x7b,
- 0x37, 0xea, 0x5e, 0x80, 0xee, 0xa7, 0xbc, 0x1c, 0x91, 0x0f, 0x48, 0xee,
- 0x91, 0x54, 0x32, 0x67, 0x79, 0x06, 0x03, 0x22, 0xad, 0xf3, 0x99, 0x3a,
- 0xd7, 0x33, 0xd8, 0x82, 0x6b, 0x93, 0xc1, 0x58, 0xfa, 0x3b, 0x92, 0x5d,
- 0xcc, 0x2d, 0xaf, 0x64, 0xed, 0xf7, 0xb1, 0x87, 0xf4, 0xff, 0xb3, 0x38,
- 0x0f, 0x3e, 0x96, 0xc1, 0xc7, 0xc7, 0xaf, 0xc3, 0x60, 0x5d, 0x2d, 0x0c,
- 0xb6, 0xab, 0xc6, 0xb3, 0x40, 0x53, 0xc1, 0x25, 0xfe, 0x2a, 0xb7, 0x64,
- 0x85, 0x34, 0x4d, 0xf2, 0x7f, 0xd2, 0xc8, 0xcb, 0x19, 0xae, 0x07, 0x30,
- 0x18, 0xfa, 0xdb, 0xb8, 0x2a, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e,
- 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x22, 0x68, 0xd9, 0x55,
- 0x72, 0xa0, 0x65, 0x60, 0xb7, 0x1e, 0x7b, 0x07, 0x19, 0xe0, 0x3c, 0x29,
- 0x7f, 0xa1, 0xec, 0xb5, 0xbe, 0x39, 0x87, 0x4f, 0x5b, 0x92, 0xdb, 0xee,
- 0xc8, 0x4a, 0x7e, 0x85, 0x67, 0x4b, 0x62, 0x4d, 0xdc, 0x41, 0x99, 0x24,
- 0x4e, 0x00, 0x86, 0x4c, 0x90, 0xc7, 0x1a, 0x0f, 0xce, 0x3f, 0xb7, 0x1f,
- 0xbf, 0x73, 0x03, 0xbc, 0x5b, 0x92, 0xdf, 0xa2, 0xbe, 0x12, 0xeb, 0xd6,
- 0x3b, 0xb4, 0x4f, 0x78, 0x25, 0x0e, 0x9e, 0xa3, 0x7c, 0xe4, 0xcb, 0xdd,
- 0xd0, 0x57, 0x8e, 0x99, 0x37, 0xdf, 0xc9, 0x57, 0xa4, 0xcf, 0x71, 0x5c,
- 0xed, 0x5f, 0xe8, 0x38, 0x20, 0xf7, 0x45, 0x49, 0x16, 0xa1, 0x0f, 0x16,
- 0x32, 0x31, 0x39, 0x5c, 0x8b, 0xcb, 0x91, 0xca, 0xb4, 0x7c, 0xb1, 0xd2,
- 0xa7, 0x70, 0xc3, 0x9f, 0xfb, 0xe9, 0xc4, 0xb8, 0x15, 0xc8, 0xfd, 0xc0,
- 0x3f, 0xf3, 0xc3, 0xdd, 0xf2, 0xfa, 0xa4, 0xa5, 0xf4, 0xde, 0x15, 0x7e,
- 0x18, 0xed, 0xf2, 0x0e, 0x27, 0xe7, 0x03, 0xbd, 0x6f, 0xc1, 0x17, 0xb0,
- 0x78, 0x6f, 0xaf, 0x4f, 0x1e, 0xf0, 0x91, 0xde, 0xe8, 0xab, 0xef, 0x62,
- 0xcd, 0x77, 0x5c, 0x46, 0x8f, 0x9c, 0x33, 0x63, 0x1f, 0x31, 0x69, 0x6a,
- 0xb0, 0x8d, 0x16, 0x6b, 0x31, 0x13, 0x51, 0xf3, 0x2b, 0xd7, 0xa9, 0xdf,
- 0xd8, 0x06, 0xfa, 0x04, 0x7b, 0xb7, 0x0b, 0x7c, 0xd9, 0x80, 0x7e, 0x29,
- 0xd6, 0xc4, 0xda, 0xca, 0x00, 0x51, 0x7b, 0x1a, 0x7f, 0x16, 0x21, 0x5f,
- 0x0b, 0x35, 0xea, 0xbf, 0x23, 0x90, 0x05, 0xda, 0x6f, 0x87, 0xdf, 0xdc,
- 0x00, 0x43, 0x98, 0x3b, 0x1f, 0x31, 0xc6, 0x40, 0xda, 0x75, 0x58, 0xf8,
- 0x3f, 0x67, 0x3e, 0x3e, 0x28, 0xfd, 0x25, 0xac, 0x4b, 0x88, 0xb9, 0xc1,
- 0x53, 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x88, 0x37,
- 0xda, 0xfd, 0x23, 0xee, 0x59, 0xda, 0x0b, 0x29, 0x45, 0x81, 0x69, 0x7b,
- 0x57, 0x60, 0xbb, 0x6b, 0x59, 0xc8, 0x0a, 0xef, 0xe1, 0x4f, 0x4b, 0x19,
- 0xd8, 0xed, 0xe3, 0xfe, 0xe7, 0xc4, 0x7e, 0xf6, 0xa0, 0x6c, 0xd4, 0x7a,
- 0xc1, 0x0f, 0xda, 0x85, 0x2e, 0xe5, 0x53, 0x5f, 0x39, 0x4a, 0x7b, 0x47,
- 0x5b, 0xa2, 0xd7, 0x62, 0xb7, 0x0e, 0x27, 0x38, 0xa6, 0xf3, 0x76, 0xea,
- 0xa1, 0x2d, 0xe4, 0xf7, 0x34, 0x5d, 0xc6, 0x2e, 0xc7, 0xa0, 0xbb, 0xd7,
- 0xa5, 0xa1, 0xfc, 0x73, 0xce, 0x9f, 0x36, 0xa8, 0x8b, 0xf7, 0xc7, 0xac,
- 0x86, 0xc7, 0xb9, 0xb7, 0xdb, 0x20, 0x8d, 0x3b, 0xdc, 0x3b, 0x39, 0x1e,
- 0xef, 0x26, 0x70, 0x8e, 0x71, 0xe9, 0x3a, 0xf3, 0xa8, 0xd8, 0xf0, 0x5b,
- 0x22, 0xab, 0xc4, 0x7a, 0xd7, 0xfa, 0x2e, 0x91, 0x73, 0x51, 0xf3, 0xfd,
- 0xf0, 0xa8, 0xc6, 0x32, 0x19, 0xa4, 0x8d, 0xf0, 0x9b, 0x62, 0xfe, 0xda,
- 0xed, 0x66, 0xe8, 0x5b, 0xec, 0x69, 0x4b, 0xf1, 0xf7, 0x7f, 0x00, 0xb6,
- 0x9d, 0x3c, 0x32, 0x44, 0x4b, 0x00, 0x00, 0x00 };
+ 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x75, 0xe6, 0x79, 0x6f, 0xde, 0x90,
+ 0x43, 0x8a, 0xa2, 0x1e, 0x99, 0x31, 0x33, 0x8e, 0xd8, 0x7a, 0x86, 0xf3,
+ 0x48, 0xd1, 0x21, 0xe3, 0x3e, 0x33, 0x63, 0x99, 0x76, 0xa6, 0xd6, 0x64,
+ 0x66, 0x28, 0x2b, 0x0e, 0x69, 0xd0, 0x8e, 0x82, 0x4d, 0x01, 0x03, 0xe5,
+ 0x0e, 0xa9, 0x54, 0xd9, 0xf5, 0x22, 0xda, 0x34, 0x45, 0x8a, 0xa2, 0x88,
+ 0x26, 0x24, 0xe5, 0x2a, 0xcd, 0x88, 0x1c, 0xcb, 0x34, 0x1b, 0x14, 0x5e,
+ 0x64, 0x3c, 0xa4, 0x14, 0xb7, 0x1d, 0x89, 0x72, 0xe2, 0x2d, 0xbc, 0x58,
+ 0x07, 0x66, 0xa9, 0x1f, 0x4e, 0x83, 0x14, 0xf0, 0x2e, 0xbc, 0x68, 0x60,
+ 0xa4, 0x80, 0x20, 0xbb, 0x8d, 0xb3, 0xc8, 0x62, 0x83, 0xdd, 0x00, 0x71,
+ 0x02, 0x27, 0x6f, 0xbf, 0xef, 0xde, 0xfb, 0xc8, 0xd1, 0x88, 0x76, 0xd2,
+ 0xfc, 0xb5, 0x04, 0x06, 0xf7, 0xfd, 0xb8, 0x3f, 0xce, 0x3d, 0xf7, 0xdc,
+ 0x73, 0xbe, 0x73, 0xee, 0x79, 0x7c, 0x40, 0xa4, 0x53, 0xcc, 0xdf, 0x5e,
+ 0xfc, 0x32, 0xff, 0xe1, 0xb3, 0xb3, 0x63, 0x77, 0x65, 0xee, 0xc2, 0xe5,
+ 0x87, 0xed, 0xf7, 0x3b, 0x0e, 0x9f, 0x47, 0xf0, 0x8b, 0xe3, 0x37, 0x66,
+ 0xae, 0x77, 0xfb, 0x73, 0xf1, 0x3b, 0x68, 0x89, 0xcc, 0xfc, 0x4f, 0x11,
+ 0xab, 0xe5, 0x5d, 0xec, 0x5d, 0xda, 0xbc, 0xd7, 0x9f, 0xfd, 0x1b, 0xb4,
+ 0xf9, 0xd7, 0xfe, 0x45, 0x34, 0xd9, 0x6a, 0xde, 0xfc, 0x49, 0xcc, 0xce,
+ 0xce, 0x4c, 0xe6, 0x3d, 0x89, 0x45, 0xb2, 0x47, 0xa7, 0x66, 0x3d, 0x91,
+ 0x5c, 0x63, 0x24, 0x59, 0x90, 0x5f, 0x04, 0xe5, 0xb8, 0x23, 0x7c, 0xfe,
+ 0x5b, 0xd9, 0x77, 0xbe, 0xf6, 0xad, 0x7b, 0x53, 0x3f, 0xae, 0x45, 0x24,
+ 0xe6, 0x66, 0xdf, 0x16, 0x77, 0x48, 0x62, 0xfd, 0x68, 0xf3, 0xcc, 0x81,
+ 0x57, 0x6d, 0xe9, 0x0e, 0xfb, 0x72, 0x67, 0x22, 0x59, 0x99, 0x3e, 0x56,
+ 0x39, 0x19, 0xd8, 0x9e, 0x94, 0x9d, 0xac, 0x37, 0x5c, 0x97, 0xae, 0xf1,
+ 0x73, 0x99, 0x7b, 0x05, 0xf7, 0xd3, 0xc7, 0x1a, 0x31, 0x99, 0x6f, 0x94,
+ 0xbb, 0x6c, 0xcf, 0x43, 0x29, 0xb1, 0xb6, 0xec, 0x62, 0xec, 0x9a, 0xc7,
+ 0xb1, 0xbf, 0x8a, 0xb1, 0xf7, 0x4b, 0xd4, 0x0b, 0x82, 0x73, 0x18, 0xfb,
+ 0x70, 0xe3, 0x17, 0xc1, 0xb3, 0x8e, 0x1e, 0xd7, 0xce, 0x9e, 0x88, 0xb0,
+ 0xb4, 0xb2, 0xb5, 0xc9, 0x81, 0x06, 0xef, 0x8b, 0xed, 0x9a, 0x4e, 0xbf,
+ 0x13, 0x74, 0xc6, 0x9c, 0xec, 0x89, 0xce, 0x45, 0x94, 0xd1, 0x6c, 0x7c,
+ 0xec, 0x9c, 0xaa, 0xb7, 0x6e, 0xea, 0x3d, 0x1e, 0xd5, 0xed, 0xde, 0x9a,
+ 0x1c, 0x6a, 0xb0, 0xfc, 0xc9, 0xe4, 0xa0, 0x2a, 0xdf, 0x99, 0x4c, 0xab,
+ 0x52, 0xa6, 0x06, 0x54, 0xe9, 0x4c, 0x79, 0xaa, 0x7c, 0xc6, 0x3c, 0x7f,
+ 0x6e, 0x32, 0xa9, 0xca, 0x86, 0x29, 0x2f, 0x99, 0xf2, 0x05, 0x53, 0xbe,
+ 0x68, 0xca, 0x97, 0x4c, 0xb9, 0x69, 0xca, 0x2b, 0x93, 0xba, 0x9f, 0x6f,
+ 0x9b, 0xfb, 0xef, 0x9a, 0xf2, 0x55, 0x53, 0xbe, 0x66, 0xca, 0xef, 0x99,
+ 0xf2, 0xfb, 0x86, 0xae, 0xeb, 0xa6, 0x7c, 0xd3, 0x94, 0x3f, 0x32, 0xef,
+ 0x7f, 0x6c, 0xe8, 0x7d, 0x1b, 0x74, 0xfd, 0x49, 0xd4, 0xc8, 0x2a, 0xe6,
+ 0x9d, 0x94, 0xd9, 0x8a, 0x23, 0xf3, 0xcb, 0x11, 0x29, 0xa8, 0x35, 0xfc,
+ 0xca, 0x5e, 0xe9, 0x74, 0x64, 0x61, 0x23, 0x26, 0xd7, 0x95, 0x88, 0xbe,
+ 0x15, 0x7c, 0xeb, 0x80, 0x94, 0xed, 0xac, 0x2b, 0x97, 0x36, 0xe2, 0xf2,
+ 0xf2, 0x86, 0x58, 0xd3, 0x99, 0x0e, 0xb1, 0xcf, 0x7e, 0x40, 0x72, 0xae,
+ 0x25, 0x11, 0xc5, 0xd3, 0xa4, 0xe4, 0x2b, 0x7d, 0xb8, 0x4f, 0x25, 0x44,
+ 0xae, 0xee, 0xd5, 0xeb, 0x17, 0x93, 0xc8, 0x2a, 0xd7, 0xe4, 0xfe, 0xa9,
+ 0x6b, 0x2b, 0x09, 0x71, 0x96, 0x46, 0x31, 0x46, 0x97, 0x44, 0x57, 0xa5,
+ 0x3f, 0x22, 0x83, 0x89, 0x4f, 0xa3, 0x46, 0xb1, 0xe1, 0xc8, 0x44, 0xc3,
+ 0x12, 0xc7, 0x8b, 0x41, 0x3e, 0xba, 0xf0, 0x73, 0xf1, 0x8b, 0xe3, 0x97,
+ 0xc0, 0xef, 0x47, 0xe8, 0xa7, 0x5f, 0x0a, 0x0d, 0xf6, 0x89, 0x71, 0x97,
+ 0x31, 0xfe, 0x72, 0xca, 0x9d, 0x11, 0xd2, 0x95, 0x90, 0x6f, 0x1d, 0x20,
+ 0x5d, 0x2e, 0xe9, 0x01, 0x6d, 0x31, 0x2b, 0xbf, 0x22, 0x27, 0x0a, 0xbe,
+ 0x24, 0x6d, 0xaf, 0x53, 0x4a, 0xae, 0x95, 0x9c, 0x1b, 0xee, 0x95, 0xf2,
+ 0x51, 0xbc, 0x5f, 0x96, 0x9c, 0x8d, 0xfe, 0x4b, 0xae, 0xcc, 0xe8, 0x77,
+ 0x7c, 0xf6, 0x36, 0xf6, 0x6a, 0xca, 0xa5, 0xd0, 0xbe, 0xbc, 0xfc, 0xb7,
+ 0xb8, 0x66, 0x7f, 0x3f, 0x77, 0x34, 0xdd, 0x3f, 0xc5, 0x3d, 0x9f, 0x0f,
+ 0x99, 0x79, 0xf0, 0x9a, 0x75, 0xc3, 0x71, 0xc3, 0xf9, 0x72, 0xfc, 0x61,
+ 0xcc, 0x99, 0x34, 0x84, 0x73, 0x96, 0x72, 0x14, 0xb4, 0xd4, 0x57, 0xba,
+ 0xac, 0xb5, 0x95, 0x51, 0x79, 0x62, 0xf9, 0x01, 0xc9, 0xfb, 0x41, 0x30,
+ 0xeb, 0x4b, 0xdc, 0x96, 0x41, 0xb7, 0x80, 0x0a, 0x5b, 0x0d, 0xb1, 0xea,
+ 0x15, 0x89, 0xb5, 0x83, 0x2f, 0x3f, 0x58, 0x61, 0xdf, 0x0e, 0x9e, 0xf5,
+ 0xa1, 0x7e, 0xb7, 0xb5, 0xbe, 0x02, 0xfa, 0xb3, 0xe4, 0x4f, 0x10, 0x2c,
+ 0xfa, 0x83, 0x89, 0x39, 0x8c, 0x79, 0xb9, 0x31, 0x38, 0x7e, 0x43, 0x5c,
+ 0xf4, 0xd9, 0x8b, 0x3a, 0xe4, 0x15, 0xfb, 0x62, 0x9f, 0xec, 0xaf, 0x0b,
+ 0x6d, 0xe3, 0x78, 0x47, 0xba, 0x82, 0x20, 0xef, 0xbb, 0xbc, 0x97, 0x4d,
+ 0xf0, 0x6f, 0x93, 0xfc, 0xeb, 0xec, 0x97, 0x57, 0x1a, 0x1c, 0x63, 0x37,
+ 0xda, 0x47, 0xfe, 0x3f, 0xa4, 0x3d, 0x81, 0xfe, 0xe3, 0x28, 0xf7, 0x58,
+ 0xf5, 0x6a, 0x80, 0xf1, 0x13, 0xb8, 0xde, 0x6d, 0x1e, 0xd7, 0xd5, 0xda,
+ 0x5f, 0xc2, 0xda, 0xbb, 0xd9, 0xb8, 0x3c, 0xbf, 0xd1, 0x8f, 0x79, 0x24,
+ 0xe4, 0x1b, 0x90, 0xcd, 0x9e, 0x83, 0x7b, 0x24, 0x0d, 0xd9, 0xe4, 0x9a,
+ 0x8f, 0xad, 0xce, 0x49, 0x29, 0x9e, 0x1a, 0xa6, 0x1e, 0xcd, 0x8f, 0xed,
+ 0xc3, 0x7c, 0xb5, 0xb6, 0x1a, 0x58, 0xca, 0xed, 0xb7, 0xe5, 0x90, 0xd8,
+ 0x59, 0x8c, 0x9b, 0x19, 0x01, 0x2d, 0x11, 0xbc, 0x8b, 0x8b, 0xb7, 0x9a,
+ 0xc3, 0xb3, 0x54, 0xa2, 0x04, 0x1a, 0xe7, 0x41, 0x63, 0x49, 0xca, 0x62,
+ 0x5f, 0x7c, 0xce, 0x0a, 0xf7, 0x8a, 0xe6, 0xdd, 0xb0, 0xe9, 0x67, 0x5b,
+ 0xce, 0x2d, 0x7b, 0xb5, 0xcb, 0x8a, 0xac, 0x8e, 0xca, 0xa9, 0x5d, 0x78,
+ 0x56, 0x07, 0xcf, 0xec, 0xa5, 0x70, 0x1f, 0x38, 0xb8, 0xef, 0x43, 0xdd,
+ 0x6e, 0xcb, 0x59, 0xbd, 0x95, 0x5f, 0x6b, 0x8d, 0x41, 0x7f, 0x0b, 0xfc,
+ 0xb2, 0x57, 0x7b, 0x51, 0xe7, 0x56, 0x7e, 0xd5, 0xc1, 0x2f, 0x7b, 0x55,
+ 0xf3, 0xaa, 0x0e, 0x5e, 0xd9, 0x4b, 0x71, 0x94, 0x7b, 0x2c, 0xfb, 0xac,
+ 0xe6, 0x55, 0xdd, 0xec, 0x99, 0xf3, 0x4a, 0x5f, 0xe5, 0x40, 0xab, 0x25,
+ 0x5a, 0x67, 0xe5, 0x84, 0xba, 0x29, 0x92, 0x2d, 0x62, 0xaf, 0xdb, 0xe0,
+ 0x85, 0x23, 0xc5, 0x31, 0x4b, 0x66, 0xd5, 0xbb, 0xa2, 0xa4, 0x1b, 0x1f,
+ 0x00, 0x23, 0x47, 0x86, 0x61, 0x29, 0xca, 0x6d, 0xd9, 0x17, 0xed, 0xad,
+ 0x4a, 0x4c, 0x0a, 0x4e, 0x52, 0xbc, 0x25, 0xa5, 0xc7, 0x9b, 0xfa, 0x99,
+ 0x41, 0x3f, 0xdf, 0x01, 0x3f, 0x2c, 0xe8, 0x56, 0xbe, 0x7b, 0x4c, 0xed,
+ 0xfb, 0xf4, 0xaa, 0x23, 0x83, 0x4b, 0xac, 0x53, 0xb6, 0xaf, 0x34, 0xde,
+ 0x09, 0x74, 0xbf, 0x8f, 0x71, 0x4c, 0xd7, 0xce, 0x2e, 0xda, 0x97, 0xd7,
+ 0x4f, 0xdb, 0x57, 0x1b, 0xe8, 0xb7, 0xc1, 0xb5, 0xc0, 0x5a, 0x2d, 0x63,
+ 0xad, 0x96, 0xb1, 0x6e, 0x66, 0x4f, 0xd7, 0xd4, 0xde, 0x4a, 0x9a, 0x75,
+ 0x25, 0x0d, 0x5c, 0xdb, 0x04, 0xd6, 0x94, 0x6b, 0x2b, 0xd6, 0xab, 0x99,
+ 0x3d, 0x12, 0x39, 0x1b, 0x51, 0x6b, 0xda, 0xb3, 0xfa, 0x91, 0xed, 0x35,
+ 0x1d, 0x68, 0x5a, 0x53, 0xfb, 0x5d, 0xd6, 0xd4, 0xd9, 0x65, 0x4d, 0xb7,
+ 0x1a, 0x3f, 0x31, 0x6b, 0xfa, 0x73, 0x31, 0xb2, 0xff, 0x9e, 0xfc, 0x1a,
+ 0x00, 0xbf, 0xbc, 0x5f, 0x83, 0x5f, 0xce, 0xae, 0xfc, 0xea, 0xb3, 0x5b,
+ 0xf9, 0x15, 0x01, 0xbf, 0xa2, 0xbf, 0x36, 0xbf, 0xc0, 0x87, 0x5d, 0x79,
+ 0x15, 0x83, 0xde, 0x2b, 0x4b, 0x3e, 0x23, 0x92, 0xaf, 0x6a, 0x5d, 0x5d,
+ 0x56, 0x3a, 0x9b, 0xba, 0x2a, 0xd4, 0xd9, 0xd4, 0xd7, 0x6a, 0x9f, 0x58,
+ 0x85, 0x4a, 0x12, 0xba, 0xd4, 0x41, 0xf9, 0x1c, 0xca, 0x3d, 0xd6, 0x74,
+ 0xb5, 0x1f, 0x76, 0x36, 0x10, 0x77, 0x2c, 0xb4, 0x97, 0xe5, 0x84, 0x8b,
+ 0xb5, 0x71, 0xef, 0x8a, 0x8a, 0xf4, 0xa5, 0xc0, 0xa7, 0x14, 0xde, 0xa7,
+ 0x12, 0x39, 0xc9, 0xda, 0x21, 0xae, 0xc9, 0x57, 0x3a, 0xde, 0xce, 0xa9,
+ 0x2b, 0x3e, 0x67, 0xbb, 0x0c, 0x9e, 0x45, 0x65, 0x06, 0x76, 0xa0, 0xe8,
+ 0x71, 0x3c, 0xf6, 0x9f, 0x9c, 0xe1, 0xb8, 0x85, 0x46, 0xa8, 0xb3, 0x25,
+ 0x07, 0x1b, 0x8e, 0x77, 0xdc, 0xb7, 0xe3, 0x56, 0x41, 0xd9, 0xa0, 0x8c,
+ 0x78, 0x8d, 0x66, 0xfb, 0xb2, 0x4d, 0x27, 0xf6, 0x73, 0x0e, 0x72, 0x4d,
+ 0xda, 0x92, 0xd8, 0x7b, 0xc7, 0x22, 0xe1, 0xfa, 0x38, 0xd9, 0x71, 0x81,
+ 0x5d, 0x96, 0xf9, 0x0a, 0xfb, 0xfb, 0x63, 0x2b, 0x72, 0x31, 0xec, 0x9f,
+ 0x7c, 0x64, 0xdf, 0xba, 0xbf, 0xf9, 0xc6, 0x5b, 0x46, 0x37, 0x28, 0x5b,
+ 0x85, 0xfe, 0xca, 0x4d, 0xfd, 0x95, 0xad, 0xc8, 0x92, 0xec, 0x53, 0xf6,
+ 0xe0, 0x28, 0xf9, 0x77, 0x1a, 0xef, 0xae, 0x4b, 0x84, 0x32, 0xa3, 0xf6,
+ 0x18, 0xf7, 0xfb, 0x97, 0x38, 0xdf, 0x26, 0xde, 0x4e, 0xc3, 0xc6, 0x71,
+ 0x7f, 0x61, 0x8d, 0xe3, 0x7c, 0x7e, 0xc8, 0xd0, 0xe4, 0x48, 0x4e, 0xdd,
+ 0x7f, 0x63, 0x4f, 0xa8, 0x3f, 0xb1, 0x9f, 0x41, 0xdb, 0x8b, 0x6a, 0x8e,
+ 0x76, 0x36, 0x0b, 0xde, 0x34, 0xd3, 0xc8, 0x79, 0x67, 0xb1, 0xc6, 0xa1,
+ 0x0e, 0x0b, 0xd7, 0x8a, 0xb8, 0xc6, 0xb1, 0x16, 0x2a, 0x5d, 0xb0, 0x8f,
+ 0x31, 0x63, 0x83, 0xd9, 0x7e, 0x11, 0xed, 0xf9, 0x9c, 0x6d, 0xbb, 0x60,
+ 0x8f, 0xd9, 0x7e, 0xd1, 0xb4, 0xdf, 0xb1, 0xcb, 0xdc, 0x2b, 0xb4, 0xc9,
+ 0x57, 0x32, 0xc0, 0x42, 0x2b, 0xb6, 0x14, 0x7c, 0xe0, 0x1c, 0xbf, 0xdf,
+ 0xec, 0x0b, 0x2d, 0x9b, 0x1f, 0x75, 0x2c, 0x69, 0xf7, 0x76, 0x93, 0xcd,
+ 0x7f, 0xb0, 0xb5, 0xad, 0xdb, 0x91, 0xcd, 0x05, 0xe8, 0xa8, 0x53, 0x90,
+ 0x95, 0xc5, 0xed, 0x7a, 0x94, 0x4b, 0x25, 0xa3, 0x90, 0xcd, 0xd4, 0x38,
+ 0xa7, 0x79, 0xa5, 0xd1, 0x2c, 0xa3, 0x61, 0x1f, 0x31, 0x25, 0x07, 0x7a,
+ 0x9c, 0xc5, 0xa6, 0x71, 0x16, 0x9b, 0xc6, 0x59, 0x32, 0xd8, 0x8e, 0xfd,
+ 0x68, 0xbb, 0x7a, 0xfd, 0x26, 0x7b, 0xce, 0x35, 0xfb, 0x24, 0xf6, 0xa4,
+ 0x96, 0x05, 0x60, 0x35, 0xbd, 0x06, 0x15, 0x57, 0xe6, 0x37, 0x2e, 0x84,
+ 0x7b, 0xb5, 0xdc, 0x8e, 0xe7, 0x3f, 0xc4, 0xf3, 0xe1, 0x33, 0x2e, 0xec,
+ 0x14, 0xb1, 0xda, 0x4b, 0x72, 0xae, 0x42, 0x19, 0x79, 0x11, 0x74, 0xa7,
+ 0xfd, 0x36, 0x8b, 0x7c, 0x4d, 0x0d, 0x9f, 0x97, 0x54, 0x72, 0x5e, 0x46,
+ 0x7c, 0x96, 0x4f, 0x88, 0xc2, 0x58, 0xa2, 0x31, 0xd0, 0x8b, 0x90, 0x3f,
+ 0x91, 0x1f, 0x57, 0xda, 0xc5, 0x1e, 0xfb, 0x61, 0x40, 0x3b, 0x78, 0x7a,
+ 0xa3, 0xb5, 0x1f, 0x91, 0xa1, 0x33, 0xaa, 0x1f, 0xf4, 0x91, 0xf6, 0xbf,
+ 0xad, 0xfa, 0x0b, 0xfb, 0xc2, 0x3c, 0xc7, 0x5a, 0xfb, 0x73, 0xe4, 0xba,
+ 0x6b, 0xa3, 0xbf, 0xb4, 0x99, 0x23, 0xaf, 0x21, 0x23, 0xae, 0x83, 0xf2,
+ 0x61, 0x3b, 0x94, 0x19, 0x7b, 0xec, 0x3b, 0x41, 0x6e, 0x9a, 0x73, 0x2b,
+ 0x99, 0x67, 0xff, 0xc3, 0xc8, 0x9b, 0x54, 0xed, 0x2c, 0x78, 0x96, 0x19,
+ 0xc4, 0x78, 0xbc, 0x4f, 0x02, 0x1f, 0x49, 0x99, 0xf8, 0xac, 0x54, 0xf9,
+ 0x65, 0x90, 0x73, 0x34, 0xa6, 0xd2, 0x6b, 0xcf, 0xf7, 0x96, 0x14, 0x50,
+ 0x77, 0xc1, 0xe8, 0x83, 0x62, 0xe3, 0xba, 0xe2, 0xdf, 0xf3, 0x6a, 0x1f,
+ 0xa5, 0x4e, 0x97, 0xa9, 0x37, 0x36, 0xdc, 0x08, 0xf7, 0xf8, 0x25, 0xff,
+ 0xa5, 0x60, 0x61, 0x39, 0x95, 0x4c, 0xda, 0x83, 0x52, 0xaa, 0x0e, 0x96,
+ 0x6d, 0x94, 0x27, 0x6a, 0x09, 0x39, 0x51, 0x61, 0x3f, 0xfb, 0x51, 0x07,
+ 0x8a, 0xc8, 0xc6, 0x26, 0xef, 0xa3, 0xae, 0xe1, 0x98, 0x6f, 0x5b, 0x7a,
+ 0x4c, 0xcc, 0xc1, 0xdb, 0xb4, 0xfe, 0x63, 0xe3, 0x8a, 0x55, 0xaa, 0x71,
+ 0xfd, 0xf1, 0xbc, 0xd1, 0xac, 0x8f, 0x42, 0x5d, 0xb4, 0x83, 0xc5, 0x22,
+ 0xd9, 0x45, 0xab, 0xb4, 0x22, 0x76, 0xde, 0x8f, 0x12, 0x0f, 0x26, 0x45,
+ 0xee, 0x75, 0xf5, 0x3c, 0x3f, 0x19, 0xa1, 0x1e, 0x74, 0xbc, 0xd3, 0xe8,
+ 0xbb, 0x53, 0x72, 0x0e, 0xd7, 0x9f, 0xd7, 0x12, 0x44, 0xb2, 0x1e, 0x6d,
+ 0xa5, 0x13, 0xc9, 0x3a, 0xd8, 0x63, 0xac, 0xf3, 0x52, 0xc0, 0xbd, 0x90,
+ 0xaf, 0x6a, 0x19, 0x29, 0xef, 0x60, 0x2f, 0xd0, 0x9b, 0x83, 0x8e, 0x11,
+ 0x1b, 0x7b, 0xcc, 0x8d, 0x64, 0xf9, 0x7c, 0x1c, 0xd7, 0x9b, 0xa8, 0x4f,
+ 0x1d, 0x0b, 0x4c, 0x5a, 0x53, 0xbc, 0xc3, 0x58, 0x39, 0xab, 0x58, 0x09,
+ 0x79, 0xf2, 0x52, 0xf0, 0xe4, 0x72, 0x88, 0x11, 0x94, 0x6c, 0xc9, 0xc0,
+ 0xd9, 0xa4, 0xd9, 0xd7, 0x5d, 0xdc, 0x73, 0xe4, 0x3f, 0x9e, 0xf9, 0xe6,
+ 0x59, 0x7b, 0xd3, 0xb3, 0x70, 0xff, 0x7f, 0x09, 0xb4, 0xf5, 0x2b, 0xfe,
+ 0xd8, 0xd9, 0x23, 0x56, 0x5e, 0xe1, 0x93, 0x20, 0x28, 0x78, 0x51, 0x29,
+ 0x8d, 0xfe, 0x09, 0xe6, 0xca, 0x77, 0x65, 0x30, 0x9c, 0x76, 0x63, 0x78,
+ 0x72, 0xd6, 0x4b, 0x29, 0xfb, 0x9f, 0xc7, 0xfe, 0xd3, 0x3a, 0x53, 0xca,
+ 0x3d, 0xa0, 0xdd, 0x5b, 0xe2, 0x9a, 0xbc, 0x14, 0x9c, 0x05, 0x16, 0x9e,
+ 0x5e, 0x2a, 0x5a, 0x03, 0xd8, 0x12, 0x76, 0x9f, 0x05, 0x3e, 0x77, 0x49,
+ 0xfe, 0x22, 0xd7, 0x82, 0x75, 0xf8, 0xbc, 0x4d, 0xa6, 0xe3, 0xad, 0xb6,
+ 0xf2, 0xdc, 0x3e, 0xe9, 0x24, 0xbf, 0x51, 0x77, 0xe9, 0xff, 0x46, 0xb4,
+ 0x5e, 0x76, 0x65, 0x60, 0x95, 0x7c, 0x2f, 0x5a, 0xb3, 0x15, 0xea, 0xb1,
+ 0x0e, 0xd8, 0x47, 0x3e, 0x67, 0x9f, 0x78, 0x77, 0xbe, 0xb5, 0x8f, 0xdf,
+ 0x8b, 0xe8, 0x3e, 0xd8, 0x2e, 0xec, 0xa3, 0x99, 0x1f, 0x7b, 0x94, 0x9e,
+ 0xeb, 0xcd, 0xf6, 0xb6, 0xf4, 0x9b, 0x68, 0xea, 0x17, 0xef, 0xce, 0x7f,
+ 0x37, 0x42, 0x5c, 0xf6, 0xf2, 0x32, 0xf8, 0xac, 0xe6, 0xc4, 0x77, 0x6c,
+ 0x53, 0xb4, 0x0a, 0x4b, 0x41, 0x30, 0xed, 0xdb, 0x12, 0xe9, 0x0b, 0xeb,
+ 0xea, 0x79, 0x15, 0x31, 0xaf, 0x3c, 0xe6, 0x65, 0xf7, 0xb5, 0xd2, 0xf4,
+ 0xfb, 0x86, 0xa6, 0xde, 0x26, 0x9a, 0xe2, 0xef, 0x31, 0xaf, 0xf8, 0x2e,
+ 0xf3, 0x7a, 0xa9, 0x57, 0xf7, 0x11, 0x6f, 0xea, 0xa3, 0xaf, 0xa5, 0x0f,
+ 0xe8, 0xfd, 0x38, 0xdb, 0xf7, 0xed, 0xd2, 0xfe, 0x87, 0x1d, 0xba, 0x3d,
+ 0xdb, 0xb4, 0x41, 0xb7, 0xf7, 0x1b, 0xbd, 0x78, 0xa2, 0x49, 0x97, 0x9d,
+ 0x80, 0x2e, 0x6b, 0x6e, 0xd3, 0x2c, 0xff, 0xa1, 0x8f, 0x44, 0xff, 0x28,
+ 0xc4, 0x8a, 0x1f, 0x50, 0x18, 0x64, 0x07, 0x63, 0xc7, 0x80, 0x47, 0xba,
+ 0x60, 0xff, 0xbb, 0xe9, 0x07, 0x19, 0x4c, 0x48, 0xbf, 0x88, 0x38, 0x50,
+ 0x3c, 0xa0, 0x28, 0xe8, 0x96, 0xc1, 0xc4, 0x31, 0x11, 0xe5, 0x07, 0x11,
+ 0x5f, 0xd3, 0x27, 0xe2, 0x38, 0xf4, 0x89, 0xb8, 0xee, 0xbc, 0x2f, 0x6c,
+ 0xfb, 0x48, 0xfd, 0xd8, 0xf7, 0xc4, 0xc7, 0xdc, 0x33, 0xa1, 0xad, 0x69,
+ 0xd6, 0xa7, 0xbb, 0xd1, 0xd4, 0xdf, 0x42, 0x13, 0x74, 0x12, 0x7c, 0xb3,
+ 0x05, 0xc8, 0x23, 0x30, 0x29, 0x74, 0xe0, 0xfd, 0x53, 0xe7, 0x56, 0x44,
+ 0x4a, 0x0d, 0xda, 0xc7, 0x51, 0x81, 0x5f, 0x05, 0xba, 0xd8, 0xb7, 0xb2,
+ 0x91, 0xd0, 0x4d, 0xdd, 0x39, 0x3b, 0x3b, 0x08, 0x3f, 0xdc, 0x91, 0x39,
+ 0x43, 0xdb, 0x8c, 0xf2, 0xe1, 0xba, 0x50, 0x26, 0x94, 0x5c, 0xcd, 0x80,
+ 0x3e, 0x5e, 0xcf, 0x18, 0xec, 0x7e, 0xac, 0xd1, 0x4a, 0xdb, 0xf7, 0x40,
+ 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x02, 0xb0, 0xfb, 0x37, 0xd5, 0xbe, 0x0c,
+ 0x75, 0x17, 0x65, 0x29, 0x55, 0x2d, 0xcb, 0x66, 0xb0, 0xb2, 0xcc, 0x7d,
+ 0x4b, 0x1b, 0xde, 0x25, 0x65, 0xac, 0xd7, 0xc0, 0x52, 0x2a, 0x99, 0xb3,
+ 0xc5, 0x7a, 0xdf, 0x41, 0xca, 0xd3, 0xe3, 0x32, 0x70, 0x51, 0x2c, 0x67,
+ 0x09, 0x7b, 0xbd, 0x3b, 0xc4, 0x57, 0x9c, 0xdf, 0x6f, 0x63, 0x7e, 0xe8,
+ 0x7b, 0x39, 0x9c, 0x5f, 0x97, 0x94, 0x56, 0x39, 0xbf, 0xed, 0xb9, 0xc5,
+ 0x19, 0x11, 0xf9, 0x1c, 0xf4, 0x35, 0xe6, 0x08, 0x1a, 0xc7, 0x81, 0x73,
+ 0xef, 0x30, 0x73, 0xea, 0xc2, 0x9c, 0x60, 0xa3, 0x97, 0xd8, 0x1e, 0x74,
+ 0x81, 0xe6, 0x12, 0xea, 0xcd, 0x2f, 0x71, 0xcd, 0x41, 0x2b, 0xd6, 0xbd,
+ 0xd4, 0xe0, 0xda, 0x73, 0x6e, 0xda, 0xae, 0x3b, 0x1e, 0xe7, 0xc7, 0x79,
+ 0x0e, 0x63, 0x5e, 0xac, 0xc3, 0x76, 0xad, 0x32, 0x32, 0xfc, 0x1e, 0xeb,
+ 0xf1, 0xdb, 0x2d, 0xeb, 0x21, 0x66, 0x3d, 0x62, 0xd2, 0xb6, 0xaa, 0xfc,
+ 0x65, 0x45, 0x03, 0x7d, 0x08, 0x07, 0xf4, 0x2f, 0xae, 0xc8, 0x68, 0x54,
+ 0x48, 0x7b, 0x82, 0xcf, 0x32, 0x6d, 0x32, 0xe8, 0x5f, 0x81, 0x5c, 0x95,
+ 0x20, 0x0b, 0xf4, 0x07, 0x5e, 0x5e, 0xd6, 0x6b, 0x51, 0x6a, 0x74, 0xc2,
+ 0x47, 0xe7, 0xf8, 0xe4, 0x37, 0xe7, 0xe6, 0xaa, 0x75, 0x68, 0x5e, 0x97,
+ 0x4f, 0xdf, 0xb2, 0x2e, 0xd4, 0xbb, 0xd4, 0x03, 0xc4, 0x3d, 0xd4, 0x05,
+ 0x61, 0x4c, 0xa0, 0xe6, 0xea, 0xfd, 0x14, 0xda, 0x9f, 0xeb, 0xdb, 0xf8,
+ 0x52, 0xaf, 0x59, 0xc2, 0xc4, 0x05, 0xba, 0xc4, 0x5e, 0xbd, 0x83, 0x7a,
+ 0x1f, 0xf6, 0x27, 0x9c, 0xdf, 0xef, 0xe0, 0x3e, 0x71, 0xd3, 0x7a, 0xd8,
+ 0x98, 0x93, 0xa3, 0xe6, 0xa8, 0xd6, 0x62, 0x5b, 0xe6, 0xe6, 0x1a, 0x7a,
+ 0x5e, 0xce, 0xd2, 0x1e, 0xb3, 0x1e, 0x31, 0x3c, 0xe3, 0xbc, 0x42, 0x9b,
+ 0xc3, 0x79, 0x91, 0x5e, 0xd7, 0xc8, 0x1c, 0xe7, 0xc3, 0xfd, 0xd7, 0x2c,
+ 0x6b, 0x2f, 0x05, 0xd5, 0xe5, 0xa8, 0x9a, 0x7b, 0xde, 0xef, 0x26, 0x46,
+ 0xa3, 0x8e, 0x34, 0xfa, 0x89, 0xcf, 0x69, 0x07, 0xf1, 0x2e, 0x43, 0x19,
+ 0xc2, 0x7d, 0x9d, 0xf7, 0xcd, 0x36, 0xed, 0x79, 0x47, 0xeb, 0x01, 0xc6,
+ 0x9f, 0xde, 0xdb, 0xd6, 0x45, 0xb3, 0x62, 0xad, 0x57, 0xe8, 0x33, 0x07,
+ 0xc0, 0x5d, 0x77, 0x40, 0xaf, 0x1c, 0x92, 0x92, 0x0b, 0x7b, 0x3d, 0x7c,
+ 0x3b, 0xe6, 0x3c, 0x2e, 0x2a, 0xde, 0x30, 0xbc, 0x17, 0xd7, 0x7b, 0x94,
+ 0xef, 0x52, 0x1a, 0xfe, 0x90, 0xe4, 0xa6, 0x69, 0xd3, 0x7e, 0x5f, 0x66,
+ 0x60, 0x5b, 0x4b, 0xc3, 0x77, 0x82, 0x3e, 0xde, 0x43, 0x27, 0x7a, 0x43,
+ 0x8c, 0x51, 0xe0, 0xef, 0x71, 0x13, 0x9b, 0x39, 0x80, 0xfb, 0x3d, 0xa8,
+ 0xf3, 0x49, 0x53, 0xa7, 0x1b, 0x75, 0x06, 0x5b, 0xea, 0x70, 0xbc, 0xfb,
+ 0x50, 0x07, 0xf6, 0x14, 0x56, 0xd2, 0xf6, 0x0e, 0xe2, 0x37, 0x81, 0x67,
+ 0xf7, 0xe2, 0xd9, 0x3d, 0x78, 0x76, 0x0f, 0xee, 0x7f, 0xd7, 0xc4, 0x3c,
+ 0xc2, 0x36, 0xdd, 0xb8, 0xff, 0x12, 0xde, 0x43, 0xc7, 0xb9, 0xdf, 0xc6,
+ 0xfb, 0xfb, 0xf0, 0x1b, 0x6b, 0xa9, 0xe3, 0xb6, 0xdc, 0x9f, 0x76, 0x74,
+ 0x8c, 0x84, 0xcf, 0x82, 0xc8, 0xce, 0xf5, 0x7f, 0x35, 0xcf, 0xbd, 0xa6,
+ 0xf7, 0x1f, 0x37, 0xd7, 0xad, 0xb2, 0x94, 0x86, 0x2c, 0xf1, 0xfd, 0x57,
+ 0xf6, 0xe9, 0xb5, 0xb8, 0x43, 0xc7, 0x1f, 0x6e, 0xc2, 0x1b, 0x4a, 0xfc,
+ 0x71, 0xbd, 0x09, 0x9c, 0x41, 0xec, 0xd1, 0x8c, 0x3b, 0x48, 0x8b, 0xab,
+ 0xe4, 0xf5, 0xe5, 0xe5, 0xd7, 0xba, 0xf5, 0x18, 0x62, 0xd5, 0x21, 0x73,
+ 0x13, 0x2a, 0x16, 0xf1, 0x33, 0xf3, 0xcc, 0xdb, 0xb7, 0xf3, 0x6e, 0xaf,
+ 0x4c, 0x54, 0xff, 0x68, 0xdf, 0x0e, 0x6d, 0x93, 0x4d, 0xd7, 0x3b, 0x98,
+ 0x02, 0xfe, 0x84, 0xbd, 0x83, 0x77, 0x72, 0xf6, 0x5c, 0xa3, 0x68, 0xeb,
+ 0x71, 0x59, 0x07, 0xef, 0x1a, 0x9b, 0x3d, 0x8e, 0x92, 0xfd, 0x9c, 0x4d,
+ 0x5f, 0xa3, 0xbc, 0xc6, 0xeb, 0xdb, 0x51, 0x36, 0xb7, 0xed, 0x87, 0x1e,
+ 0xcf, 0xd9, 0x9a, 0xee, 0xd6, 0xf6, 0xe1, 0xbe, 0xf1, 0x65, 0xa1, 0x0a,
+ 0x99, 0xf3, 0x52, 0xc3, 0x65, 0xac, 0xdd, 0xac, 0x9f, 0x9a, 0xa6, 0x4c,
+ 0xc2, 0x9f, 0xfd, 0x94, 0xc8, 0xa4, 0xcc, 0x57, 0x1f, 0x06, 0xfe, 0x0e,
+ 0xe4, 0x21, 0xe0, 0x8a, 0x7f, 0x0f, 0x5c, 0x52, 0x83, 0xac, 0xd7, 0x1a,
+ 0x1e, 0x7e, 0xfd, 0xf2, 0x57, 0x95, 0x84, 0x3c, 0x07, 0x7f, 0x02, 0xb2,
+ 0x06, 0x3d, 0x9c, 0x76, 0x1f, 0x12, 0xe9, 0xb1, 0xe5, 0xf2, 0xbd, 0xb6,
+ 0x8c, 0x24, 0x07, 0xac, 0x74, 0x02, 0x3f, 0xb7, 0x0d, 0xbf, 0x22, 0x7c,
+ 0xb8, 0xb5, 0x06, 0x63, 0x01, 0x71, 0xf9, 0xeb, 0xf5, 0x24, 0x7e, 0x7d,
+ 0xf2, 0x37, 0xeb, 0x1c, 0x7f, 0xc0, 0x94, 0x6a, 0x1f, 0xc3, 0xe7, 0x28,
+ 0xcb, 0x62, 0x26, 0x21, 0x0b, 0x95, 0xe0, 0xa4, 0xf6, 0x99, 0x3d, 0xf8,
+ 0xc8, 0xdc, 0xb3, 0x2f, 0x60, 0xcf, 0xe2, 0xb9, 0xc2, 0x9e, 0xa1, 0xdd,
+ 0x7b, 0x01, 0x76, 0x2f, 0x5c, 0x23, 0xce, 0xb3, 0x75, 0x7d, 0xd8, 0x2f,
+ 0xd7, 0x88, 0x7a, 0x9d, 0xba, 0x3c, 0x06, 0xfc, 0x10, 0xea, 0x76, 0xea,
+ 0x08, 0x6f, 0xdb, 0x0f, 0x7d, 0xe4, 0x60, 0x17, 0xb0, 0x86, 0xc4, 0xe2,
+ 0xd9, 0x9f, 0xca, 0xca, 0x59, 0xee, 0x1b, 0xda, 0xe3, 0xbb, 0x21, 0x6f,
+ 0xa9, 0xaf, 0x96, 0x89, 0x99, 0xbd, 0x0c, 0xf8, 0x51, 0x96, 0xe9, 0x83,
+ 0xab, 0xbd, 0x5a, 0x4e, 0x26, 0xc5, 0x39, 0xfb, 0x85, 0xa8, 0x74, 0x9f,
+ 0x94, 0x45, 0x1f, 0x7e, 0xa9, 0x5d, 0x0e, 0x22, 0x9e, 0x97, 0x28, 0x28,
+ 0xbf, 0x69, 0x05, 0x74, 0xc6, 0x64, 0xe2, 0x2c, 0xeb, 0x9c, 0x84, 0x8c,
+ 0xb5, 0x81, 0xe6, 0x76, 0x39, 0x15, 0x4f, 0x95, 0x0b, 0xf0, 0xf7, 0x6d,
+ 0xaf, 0x47, 0x06, 0xea, 0x2c, 0x89, 0x41, 0xfe, 0x37, 0xe4, 0x87, 0xd7,
+ 0xf0, 0x03, 0x57, 0xf9, 0x7c, 0x00, 0x25, 0x9f, 0x7b, 0xd0, 0x2f, 0xe4,
+ 0x07, 0x70, 0xc3, 0xc5, 0xb2, 0x9c, 0xca, 0x4c, 0x4a, 0xbd, 0x2a, 0xd6,
+ 0x42, 0x06, 0x7b, 0xa0, 0x96, 0x95, 0x3a, 0x78, 0x51, 0x6a, 0x1c, 0x87,
+ 0xdf, 0xf9, 0x26, 0xca, 0x39, 0x94, 0xd7, 0x51, 0x3e, 0x8e, 0xf2, 0x2d,
+ 0x94, 0xa4, 0xfd, 0xb8, 0xd4, 0x6b, 0x7b, 0xda, 0xa4, 0x93, 0x7d, 0x6c,
+ 0x18, 0x9a, 0xe1, 0x3b, 0x1e, 0x3c, 0x0e, 0x2c, 0x1a, 0x3e, 0x3f, 0x2e,
+ 0x52, 0xff, 0x0c, 0x7e, 0x0f, 0xaa, 0x7b, 0xfa, 0x96, 0x0b, 0x99, 0x71,
+ 0xe0, 0x7a, 0xb1, 0x4e, 0x65, 0x1e, 0x37, 0xfd, 0x7c, 0x06, 0xe3, 0x5d,
+ 0xc5, 0xd8, 0x31, 0xc8, 0x48, 0x20, 0x8f, 0xf8, 0x27, 0xe5, 0x73, 0xfe,
+ 0x7e, 0x19, 0xeb, 0x8d, 0x95, 0x63, 0x59, 0xce, 0x9f, 0x7a, 0x6a, 0xb7,
+ 0xf9, 0x87, 0xf3, 0xe6, 0x9c, 0xa1, 0x5b, 0x97, 0xf6, 0x6a, 0xdc, 0x6d,
+ 0x7f, 0x39, 0xaa, 0x69, 0xb1, 0x64, 0x60, 0x88, 0xfd, 0x65, 0x25, 0x72,
+ 0x76, 0xc8, 0xcd, 0xd8, 0x23, 0xf0, 0x52, 0xd2, 0xf8, 0x9d, 0x84, 0xfc,
+ 0x79, 0xa7, 0x07, 0xec, 0xdb, 0x40, 0x13, 0xde, 0xd5, 0x39, 0x0e, 0xec,
+ 0xe9, 0x3d, 0xaf, 0x62, 0x6e, 0x65, 0x69, 0xbf, 0x27, 0x2b, 0x37, 0x1a,
+ 0xbc, 0x86, 0x3d, 0xba, 0x30, 0x29, 0xff, 0x5c, 0xbd, 0x2a, 0x4f, 0x54,
+ 0x27, 0xe5, 0x0d, 0x94, 0x8b, 0xd5, 0x32, 0xf8, 0xc8, 0x58, 0x3c, 0xfb,
+ 0x08, 0xb0, 0x2e, 0x83, 0xf0, 0x8d, 0x3e, 0x98, 0x98, 0xc3, 0xfa, 0xcd,
+ 0xb8, 0x81, 0x9c, 0xf3, 0xcb, 0x72, 0x6e, 0x1c, 0x6d, 0x6a, 0x1d, 0x12,
+ 0x7d, 0x96, 0xf3, 0xed, 0x96, 0x02, 0x2c, 0x7a, 0x31, 0x43, 0x9d, 0xd9,
+ 0x29, 0x85, 0x5a, 0xab, 0xdc, 0x51, 0xde, 0xde, 0xb6, 0xea, 0xdb, 0x3a,
+ 0x60, 0xd3, 0xfa, 0x66, 0x83, 0x36, 0x78, 0x37, 0x7b, 0xaa, 0xe5, 0xae,
+ 0x5e, 0xa3, 0x4d, 0xdd, 0x91, 0xbd, 0x3a, 0xfc, 0xb9, 0x7a, 0xf5, 0xba,
+ 0x91, 0x3f, 0x25, 0xb7, 0x58, 0x17, 0x62, 0xf1, 0x9f, 0x08, 0xb0, 0x1f,
+ 0x78, 0x14, 0xc6, 0x09, 0xb5, 0x7f, 0x54, 0x03, 0xad, 0x85, 0x38, 0x71,
+ 0x06, 0xac, 0x5b, 0xed, 0x0b, 0x8a, 0x57, 0xde, 0xd9, 0x7e, 0xa9, 0x2e,
+ 0x93, 0xbf, 0x29, 0xd7, 0xb6, 0x95, 0x4f, 0x02, 0xbe, 0x7a, 0x58, 0x9f,
+ 0xf0, 0x7d, 0x0a, 0x7e, 0xd2, 0x49, 0x71, 0xc7, 0x3a, 0x31, 0x27, 0x5e,
+ 0x8b, 0x4c, 0x5f, 0x6c, 0xc5, 0x91, 0xa1, 0x9d, 0x68, 0x83, 0x3f, 0x1e,
+ 0xc5, 0x5a, 0x76, 0xc1, 0x9f, 0x86, 0x9f, 0x0a, 0x39, 0xfa, 0x33, 0x60,
+ 0xaf, 0xd3, 0xca, 0xb7, 0xe6, 0x9e, 0xea, 0x9e, 0x1a, 0x58, 0x67, 0xb9,
+ 0x77, 0x2a, 0x5d, 0x63, 0x19, 0x9f, 0xd2, 0xbe, 0x64, 0x62, 0x4a, 0xc7,
+ 0xed, 0x93, 0x53, 0x07, 0x54, 0xe9, 0x4d, 0x0d, 0xab, 0x72, 0x78, 0x6a,
+ 0x27, 0x66, 0x42, 0x9e, 0x8a, 0x95, 0xcf, 0x64, 0xa4, 0x58, 0x21, 0x8d,
+ 0xe2, 0x1c, 0x83, 0x3c, 0xcd, 0x01, 0xcb, 0xe4, 0x2b, 0xbe, 0x9c, 0xda,
+ 0xc8, 0x82, 0x66, 0xe8, 0x99, 0xac, 0x8f, 0x52, 0xcc, 0x5f, 0xd8, 0xb6,
+ 0x8d, 0x31, 0x32, 0xae, 0x99, 0xf1, 0x33, 0x7d, 0xfa, 0x99, 0xcd, 0x7f,
+ 0xec, 0x0f, 0xb2, 0x49, 0xfb, 0xf9, 0x0b, 0xf8, 0xc6, 0xe2, 0x94, 0x32,
+ 0x6c, 0xeb, 0xc3, 0x07, 0x17, 0xd9, 0x5a, 0x91, 0x58, 0x2c, 0xfb, 0x1d,
+ 0x89, 0x3d, 0x1d, 0x04, 0x3f, 0xf0, 0x53, 0x47, 0xca, 0x02, 0x5e, 0x59,
+ 0x78, 0xbe, 0xce, 0x77, 0xd4, 0x4d, 0x23, 0xee, 0x0d, 0xc8, 0x5c, 0xee,
+ 0xa8, 0xc8, 0x2b, 0x78, 0x56, 0x5f, 0xe1, 0x1a, 0x7c, 0x17, 0x6b, 0x60,
+ 0xd6, 0x44, 0x3d, 0x63, 0x3d, 0xf8, 0x58, 0x71, 0xce, 0x63, 0xc4, 0x6d,
+ 0x47, 0xfb, 0xda, 0x3a, 0xdb, 0xa4, 0xc6, 0x79, 0xe4, 0xf5, 0xca, 0xba,
+ 0x9e, 0xdf, 0xe1, 0xcc, 0xb0, 0x5c, 0xae, 0xa8, 0x3e, 0x20, 0xeb, 0xbf,
+ 0x44, 0x9b, 0x4d, 0xc8, 0x2d, 0x63, 0x53, 0x59, 0x99, 0x07, 0x4e, 0x9b,
+ 0xaf, 0xa4, 0x21, 0x3b, 0x8e, 0xcc, 0x24, 0x48, 0xb6, 0x27, 0x5b, 0x95,
+ 0x37, 0xdb, 0x88, 0x85, 0xf3, 0x1e, 0xaf, 0xc7, 0x51, 0x67, 0x5a, 0x88,
+ 0xb7, 0xf2, 0x19, 0xce, 0xa9, 0x99, 0x17, 0xfa, 0xaf, 0x84, 0xb5, 0x30,
+ 0x73, 0x54, 0x7f, 0x7a, 0x1c, 0xb4, 0x37, 0xe3, 0x14, 0x01, 0x53, 0xe0,
+ 0x6b, 0x4a, 0xfa, 0x82, 0xe3, 0xe4, 0x2b, 0x8e, 0x0c, 0x5c, 0xc0, 0xb6,
+ 0xca, 0x1a, 0x5e, 0x34, 0x42, 0x59, 0x0b, 0x31, 0x10, 0x65, 0x8b, 0x3c,
+ 0x48, 0x95, 0x37, 0xc1, 0xec, 0xde, 0xec, 0x35, 0x79, 0x74, 0x55, 0xcf,
+ 0xd9, 0x3e, 0x2f, 0x3c, 0x0b, 0x91, 0x1b, 0x2b, 0x29, 0xff, 0x3a, 0xf4,
+ 0x7d, 0x21, 0xee, 0x43, 0x56, 0xfe, 0x4b, 0x1b, 0xf6, 0xf4, 0x78, 0xce,
+ 0xde, 0xdf, 0xae, 0x6d, 0xac, 0x83, 0x3d, 0x01, 0xac, 0x59, 0xc9, 0xa1,
+ 0x4d, 0xbb, 0xfc, 0x5b, 0x07, 0xd7, 0xc4, 0x9e, 0x78, 0x66, 0xec, 0x22,
+ 0xae, 0x75, 0x7f, 0xf3, 0x98, 0x87, 0x8e, 0x03, 0x5b, 0xf2, 0x28, 0x2c,
+ 0x88, 0xa0, 0xff, 0x01, 0x33, 0xd6, 0xc0, 0xf9, 0x50, 0x36, 0x40, 0xf7,
+ 0x6a, 0x16, 0xf8, 0xdd, 0x31, 0x7e, 0x2b, 0x75, 0x8c, 0xec, 0xe2, 0xf7,
+ 0x34, 0xc7, 0x5e, 0x63, 0x2a, 0x4e, 0x47, 0x2c, 0x47, 0xd9, 0x3a, 0x62,
+ 0x64, 0xeb, 0x33, 0x90, 0xad, 0xe3, 0x4a, 0xb6, 0x02, 0xf9, 0x81, 0xef,
+ 0xcb, 0x97, 0x77, 0x95, 0xaf, 0xd6, 0xbf, 0x2e, 0xd0, 0xcb, 0x5f, 0x9f,
+ 0x2c, 0xfc, 0x05, 0xc6, 0xbd, 0xe0, 0xe2, 0x3a, 0x95, 0x9b, 0x11, 0xf2,
+ 0x31, 0x81, 0xeb, 0x18, 0xca, 0x7e, 0x55, 0x67, 0xe0, 0x02, 0xec, 0x1a,
+ 0xe4, 0x8d, 0xfc, 0x9d, 0x87, 0x8d, 0x1b, 0xb8, 0x10, 0x85, 0x2d, 0xe4,
+ 0x9e, 0x95, 0x5e, 0x1b, 0xba, 0x81, 0xf5, 0xeb, 0xd8, 0x3b, 0x03, 0x17,
+ 0xba, 0x50, 0x26, 0x55, 0x5f, 0xf5, 0x8a, 0xa7, 0xda, 0xd7, 0x2b, 0xc3,
+ 0xaa, 0x5d, 0xbd, 0x32, 0x8a, 0x12, 0xfa, 0x3d, 0xe3, 0xcb, 0xd0, 0x85,
+ 0x8c, 0x24, 0x2f, 0x58, 0x52, 0x9a, 0x0e, 0x82, 0x18, 0x68, 0x1f, 0xbe,
+ 0xd0, 0x23, 0xd7, 0xa7, 0x39, 0x37, 0xea, 0x62, 0xb1, 0x16, 0x33, 0xd3,
+ 0xd8, 0x9b, 0xe4, 0x1f, 0xb0, 0xfe, 0x85, 0x22, 0x6c, 0x6e, 0x51, 0x4e,
+ 0xad, 0x90, 0x3f, 0x8c, 0xb5, 0x6f, 0x25, 0x22, 0x92, 0x82, 0x2e, 0x3b,
+ 0x2a, 0x73, 0xd5, 0x76, 0xe8, 0x32, 0xc7, 0xad, 0xcb, 0x13, 0x58, 0xa3,
+ 0x41, 0xca, 0x03, 0xf8, 0x92, 0x45, 0xdf, 0x45, 0x29, 0xa0, 0x4d, 0x71,
+ 0x65, 0xa7, 0x7e, 0x49, 0xda, 0xb1, 0xa7, 0x8e, 0xca, 0xb1, 0x2a, 0xfb,
+ 0x71, 0xdc, 0x79, 0x39, 0x00, 0x19, 0xf2, 0xdc, 0x09, 0xf4, 0x03, 0x1b,
+ 0xd9, 0xf4, 0xc7, 0xfd, 0x97, 0x7b, 0x0f, 0x99, 0x0c, 0xf7, 0x5d, 0xac,
+ 0xdc, 0x96, 0x9d, 0xb6, 0xb6, 0x32, 0xe2, 0xcc, 0x66, 0x1e, 0xb2, 0x5e,
+ 0xc9, 0x64, 0xac, 0x2b, 0x99, 0x9c, 0x75, 0x35, 0x53, 0xb4, 0xae, 0xc1,
+ 0x36, 0xd5, 0x37, 0xde, 0x81, 0xfc, 0x00, 0x4f, 0x10, 0x7b, 0x6f, 0xaf,
+ 0x61, 0xdc, 0xf8, 0x39, 0x6f, 0xc9, 0xb9, 0x0a, 0xed, 0x74, 0x70, 0x68,
+ 0xd6, 0x2f, 0xdf, 0x0e, 0xfa, 0x40, 0x07, 0xe3, 0x11, 0x3b, 0xb6, 0x23,
+ 0x9a, 0x1d, 0x06, 0x4e, 0xa0, 0xed, 0xe8, 0xa2, 0xed, 0xf0, 0x0b, 0xb2,
+ 0x57, 0xb6, 0xaa, 0x3a, 0x2e, 0x97, 0x07, 0x6e, 0xda, 0xaa, 0xc5, 0xe5,
+ 0xcb, 0xcb, 0xa1, 0x2c, 0x71, 0xbe, 0xf3, 0xef, 0xeb, 0x90, 0x88, 0x1c,
+ 0x51, 0xf6, 0xba, 0x5b, 0x2e, 0xaf, 0x03, 0xd3, 0x02, 0x81, 0xd8, 0x77,
+ 0x32, 0xce, 0x63, 0xab, 0xf8, 0x85, 0xf4, 0xf0, 0x3c, 0xf0, 0x1f, 0xc0,
+ 0x2b, 0x9e, 0xd9, 0x61, 0x9e, 0x3d, 0x9c, 0x51, 0x78, 0x3f, 0x8a, 0x3d,
+ 0xc9, 0x6b, 0x4b, 0x0a, 0xc0, 0xed, 0x5b, 0x15, 0x96, 0x09, 0x94, 0x26,
+ 0x56, 0x0f, 0x5d, 0x10, 0xc9, 0xfe, 0xa3, 0x7a, 0xdf, 0xee, 0x89, 0x35,
+ 0x0b, 0x3b, 0x5c, 0x5a, 0xa1, 0x4c, 0xa3, 0x5c, 0xd7, 0x63, 0x17, 0x7c,
+ 0x60, 0xe6, 0xd1, 0x0e, 0xda, 0x37, 0xe0, 0x27, 0xec, 0x7b, 0x85, 0xed,
+ 0x33, 0xd8, 0x73, 0x3f, 0x68, 0xa7, 0x6d, 0x3f, 0xec, 0x8f, 0xcb, 0xb5,
+ 0x0a, 0xaf, 0xf9, 0x3e, 0xe5, 0x8b, 0x8a, 0x1b, 0xc7, 0xa6, 0x16, 0x3d,
+ 0xdf, 0xec, 0x31, 0x15, 0xd3, 0xb1, 0x3e, 0x06, 0xcc, 0x38, 0x70, 0xa6,
+ 0x4d, 0xd2, 0x4f, 0xdb, 0x7d, 0xfa, 0x7c, 0xe5, 0x90, 0x14, 0xfd, 0x03,
+ 0x98, 0xc3, 0x3e, 0x99, 0x87, 0x2f, 0xb6, 0xb0, 0x31, 0x2c, 0xf3, 0xc3,
+ 0xf0, 0xb9, 0xdd, 0xbb, 0x89, 0xd5, 0xf0, 0xeb, 0xc0, 0xf3, 0x41, 0x94,
+ 0xed, 0x28, 0x6f, 0x97, 0xf9, 0xa7, 0xba, 0x63, 0xba, 0xbf, 0x68, 0xcb,
+ 0xfd, 0xb3, 0x1c, 0x3b, 0x99, 0xb4, 0x7e, 0x15, 0x2e, 0x6c, 0xc6, 0x84,
+ 0xa4, 0x23, 0x2a, 0xde, 0x93, 0x5d, 0x32, 0x78, 0xc6, 0x95, 0xa1, 0x33,
+ 0x09, 0x39, 0x70, 0xa6, 0x5f, 0x86, 0xcf, 0x24, 0xe5, 0xce, 0x33, 0x21,
+ 0xfe, 0xea, 0x9e, 0x4a, 0x1b, 0x5b, 0xe1, 0xfd, 0x9a, 0xb6, 0xe2, 0xce,
+ 0x86, 0xc6, 0xa8, 0xf3, 0x6b, 0xc4, 0x74, 0xaf, 0x62, 0xef, 0x6e, 0xaa,
+ 0xf3, 0xca, 0x4b, 0x1b, 0x41, 0x70, 0xc9, 0x6f, 0x77, 0xa7, 0x85, 0xfc,
+ 0xce, 0x00, 0x9f, 0xf9, 0xd0, 0x61, 0xa3, 0xd0, 0x61, 0xe3, 0xca, 0x36,
+ 0xd6, 0xbf, 0x2e, 0xd6, 0xb1, 0xcc, 0x03, 0xb2, 0x06, 0xd9, 0x7e, 0xd0,
+ 0x4f, 0x7d, 0x75, 0x53, 0xf1, 0x47, 0x62, 0x3d, 0xd0, 0x67, 0x77, 0xaf,
+ 0xb6, 0xcb, 0x1b, 0xf1, 0x20, 0x38, 0x0b, 0x1d, 0x50, 0xaf, 0x68, 0xf9,
+ 0xcd, 0x7b, 0xd4, 0x05, 0x0f, 0x61, 0xfe, 0xa3, 0x78, 0x96, 0x33, 0xba,
+ 0xbd, 0x43, 0x6e, 0xc4, 0x13, 0xb2, 0x7e, 0x60, 0xbc, 0xa5, 0x5e, 0x06,
+ 0xf7, 0xc0, 0x3d, 0x8d, 0xdf, 0x23, 0xbf, 0xf0, 0xdc, 0x95, 0x73, 0xf0,
+ 0x99, 0xcf, 0x1f, 0x48, 0x8d, 0x27, 0x6d, 0xea, 0xc3, 0xa4, 0xd4, 0xbe,
+ 0x9e, 0x90, 0xb5, 0x65, 0x6d, 0x97, 0x66, 0xbd, 0x71, 0x29, 0x00, 0xfb,
+ 0xae, 0x2d, 0x67, 0x51, 0xb2, 0x7e, 0xa8, 0x73, 0xb4, 0x5c, 0x16, 0x33,
+ 0x79, 0xec, 0x63, 0xee, 0x0f, 0x6d, 0x77, 0x6c, 0xbb, 0x1d, 0x72, 0xc4,
+ 0x3d, 0xf1, 0x30, 0x9e, 0xe7, 0xb1, 0xaf, 0x69, 0xc7, 0xd3, 0x90, 0xaf,
+ 0xcf, 0xc6, 0x28, 0x1f, 0x05, 0x9f, 0xf8, 0x9a, 0x6d, 0x52, 0x89, 0x34,
+ 0x9e, 0x4f, 0x4b, 0x5a, 0x9d, 0x0b, 0xcd, 0xfa, 0x61, 0x7f, 0x59, 0xa3,
+ 0x17, 0x22, 0x8c, 0x81, 0xe1, 0xef, 0x64, 0x8c, 0xf2, 0x18, 0xf1, 0xc2,
+ 0xe7, 0x23, 0xb0, 0x3d, 0x51, 0x35, 0xc6, 0xfc, 0x32, 0x9f, 0xa5, 0x5d,
+ 0xb6, 0x2f, 0xf8, 0xbc, 0x17, 0xf9, 0x44, 0x83, 0xf1, 0x9a, 0x98, 0x3c,
+ 0xda, 0xe8, 0x02, 0xbd, 0x6d, 0xbf, 0xc2, 0xf6, 0xec, 0xec, 0x73, 0x3b,
+ 0xbb, 0x95, 0x70, 0x95, 0x6e, 0xa1, 0x1e, 0xa1, 0x0e, 0x69, 0x17, 0x67,
+ 0x8c, 0xfb, 0x0c, 0x6b, 0xb2, 0x8c, 0x35, 0x5a, 0xc6, 0x1a, 0x2d, 0x63,
+ 0x8d, 0x96, 0xb1, 0x7e, 0xcb, 0xd4, 0x2d, 0x83, 0xd8, 0xcf, 0x39, 0x73,
+ 0x86, 0x40, 0xfd, 0xf2, 0x1c, 0xd6, 0x76, 0x5a, 0xfe, 0x76, 0x63, 0x52,
+ 0xfe, 0xf3, 0xc6, 0x11, 0xe0, 0xee, 0x22, 0xd6, 0x35, 0x87, 0x75, 0xcd,
+ 0x62, 0x5d, 0x8f, 0x62, 0x5d, 0xc7, 0x55, 0xcc, 0xb3, 0x5a, 0x49, 0x5d,
+ 0x2a, 0x2b, 0x8c, 0xff, 0x16, 0xe4, 0x61, 0x4c, 0x9c, 0xd5, 0x7e, 0xe8,
+ 0x8b, 0x72, 0x10, 0xf7, 0x82, 0x43, 0xc0, 0xd6, 0x18, 0xbb, 0x9c, 0x72,
+ 0x94, 0xee, 0xf3, 0xdc, 0xcf, 0x63, 0xaf, 0xbc, 0x2f, 0x9b, 0xaa, 0x52,
+ 0x75, 0x9d, 0xab, 0x0e, 0x4b, 0xe9, 0x22, 0xea, 0x9f, 0xed, 0x02, 0xad,
+ 0xc4, 0x7c, 0xa9, 0xd3, 0x25, 0xd9, 0x84, 0xbe, 0xcb, 0x81, 0xc6, 0x0f,
+ 0xc9, 0x7c, 0x3c, 0xf5, 0x9c, 0xc8, 0xb8, 0xdc, 0x03, 0x3f, 0x9d, 0xf1,
+ 0xcc, 0x9c, 0x8a, 0xb1, 0xe1, 0xfa, 0x62, 0x16, 0xfe, 0x36, 0x6d, 0xec,
+ 0x3e, 0xe3, 0x87, 0x6b, 0x1c, 0x5b, 0x13, 0x8e, 0xcb, 0xf1, 0xfe, 0x58,
+ 0xe6, 0x80, 0x15, 0xe1, 0xeb, 0x03, 0x8b, 0x78, 0x09, 0x8c, 0x19, 0x9b,
+ 0xbd, 0xe8, 0xc6, 0xe6, 0x2e, 0xb2, 0x9f, 0x98, 0x44, 0x96, 0xa8, 0xb3,
+ 0xd8, 0x0f, 0x74, 0x3b, 0xfa, 0x4e, 0xab, 0x33, 0xb3, 0x11, 0xb4, 0xfb,
+ 0x5d, 0xe0, 0x4c, 0xcd, 0xc7, 0xfc, 0x59, 0x6d, 0xf7, 0xf2, 0xf5, 0x66,
+ 0xac, 0x07, 0xdd, 0x02, 0xbb, 0x98, 0xab, 0x6b, 0xdc, 0x56, 0x54, 0xb8,
+ 0x4e, 0x63, 0xba, 0xa3, 0x72, 0xa8, 0x43, 0x3a, 0x3d, 0x35, 0x9f, 0xc8,
+ 0xd9, 0x4d, 0xe2, 0x58, 0x8c, 0xc1, 0x36, 0xd1, 0x26, 0xba, 0x33, 0xb0,
+ 0xa7, 0xb7, 0x77, 0x50, 0x66, 0x3e, 0x09, 0xdc, 0x38, 0xb0, 0xa4, 0xcf,
+ 0x98, 0x06, 0x2e, 0xfa, 0x98, 0x8f, 0xf4, 0x31, 0xb2, 0x69, 0x63, 0x0e,
+ 0x1f, 0x55, 0x76, 0x79, 0x0c, 0xb6, 0xd8, 0x85, 0xac, 0x53, 0xe7, 0xf4,
+ 0x61, 0xff, 0xf0, 0x9e, 0xba, 0x87, 0x7a, 0x8c, 0x32, 0x13, 0x07, 0x6e,
+ 0x82, 0xfe, 0xe9, 0xee, 0x97, 0xda, 0x06, 0xdf, 0xf5, 0x2b, 0x1d, 0xed,
+ 0x60, 0x0d, 0x16, 0x2b, 0xc1, 0xa1, 0xbc, 0x5f, 0x86, 0x16, 0x25, 0xcf,
+ 0xc9, 0x0f, 0xf2, 0x7d, 0x14, 0xb4, 0x91, 0xc7, 0xdd, 0x65, 0x7d, 0x6e,
+ 0xb9, 0x57, 0x4a, 0x55, 0xea, 0x69, 0x94, 0xb5, 0xbd, 0xf0, 0x9d, 0x5c,
+ 0x85, 0x65, 0x73, 0xd3, 0x9c, 0x7b, 0xac, 0xec, 0x42, 0x6e, 0xdd, 0x83,
+ 0x93, 0x2a, 0xa6, 0x72, 0x79, 0x29, 0xe5, 0xd7, 0x6c, 0x8c, 0x09, 0x9d,
+ 0x69, 0x9f, 0x1f, 0x93, 0xb9, 0x95, 0x6e, 0x19, 0x5c, 0xe5, 0xf9, 0xf2,
+ 0x50, 0x4c, 0xba, 0x83, 0xe0, 0x9c, 0x9f, 0x57, 0xb1, 0xc7, 0x81, 0x55,
+ 0x60, 0x82, 0xa3, 0x9a, 0x77, 0x9c, 0x2f, 0x74, 0xc4, 0xbf, 0x82, 0x8f,
+ 0xef, 0x8e, 0x8f, 0x8b, 0xbb, 0xe0, 0xe3, 0x57, 0x2f, 0x42, 0xfe, 0x96,
+ 0x21, 0x9b, 0xcb, 0x90, 0xcd, 0x65, 0xc8, 0xe6, 0x32, 0x64, 0x73, 0x19,
+ 0xb2, 0x89, 0xfd, 0xf3, 0xfc, 0xf2, 0xb8, 0xc1, 0x1f, 0x9f, 0x82, 0x2c,
+ 0x7f, 0xdb, 0xe0, 0x8f, 0x51, 0xc8, 0x70, 0x12, 0xb2, 0xeb, 0x43, 0x6e,
+ 0x87, 0x21, 0xcb, 0x1e, 0x64, 0xb9, 0x1f, 0x72, 0x9c, 0x50, 0xfe, 0xe3,
+ 0x04, 0xb0, 0xe8, 0x83, 0xf0, 0x41, 0xce, 0x57, 0xfb, 0x65, 0x51, 0xd1,
+ 0x12, 0xc8, 0x96, 0xbf, 0x49, 0x1e, 0x62, 0x5f, 0xd0, 0x3f, 0x77, 0xe5,
+ 0xfc, 0x5a, 0x48, 0xdb, 0xab, 0xf2, 0xcd, 0xca, 0x6b, 0xf2, 0x42, 0x85,
+ 0x34, 0xe6, 0x64, 0x11, 0xef, 0xd6, 0x9e, 0xa2, 0x1f, 0xa9, 0xe8, 0x83,
+ 0xcc, 0x9d, 0x94, 0xff, 0x03, 0x5e, 0xae, 0x6f, 0x7c, 0x58, 0x3e, 0xe7,
+ 0x52, 0x86, 0xe3, 0xd0, 0x35, 0xb8, 0x3f, 0x40, 0xbd, 0x04, 0x3f, 0xb4,
+ 0x92, 0x2a, 0x97, 0xa0, 0x27, 0xaa, 0xf6, 0x08, 0x30, 0x58, 0x39, 0xe8,
+ 0xa1, 0x0e, 0xab, 0x7a, 0xee, 0x80, 0x4d, 0xde, 0xec, 0x87, 0xbc, 0xa4,
+ 0xbe, 0x0a, 0xe1, 0xc5, 0x33, 0xda, 0x73, 0x94, 0x35, 0xe8, 0xcf, 0xa7,
+ 0xc8, 0x47, 0xfa, 0xb5, 0xb8, 0x56, 0xba, 0xf7, 0x27, 0x2a, 0x7e, 0x5c,
+ 0x9a, 0x86, 0x2f, 0xbf, 0x46, 0x3e, 0x41, 0x56, 0x9e, 0x22, 0x1f, 0x49,
+ 0x9f, 0xe6, 0xe3, 0x23, 0x12, 0xf2, 0x90, 0xef, 0x5a, 0x79, 0x08, 0x27,
+ 0xaa, 0x33, 0x8e, 0xb9, 0x7f, 0x2d, 0x66, 0x62, 0xc8, 0xc6, 0x26, 0xbf,
+ 0x2a, 0xd3, 0x0d, 0xce, 0xc7, 0x92, 0xdb, 0xbc, 0xab, 0xf0, 0xa9, 0x38,
+ 0xf6, 0xab, 0xc1, 0xa3, 0x71, 0xce, 0x81, 0xeb, 0xba, 0x47, 0xea, 0x7d,
+ 0xbe, 0x89, 0xaf, 0xfc, 0x2a, 0x5b, 0xc4, 0x7a, 0xe0, 0x3b, 0xf4, 0xcb,
+ 0x0b, 0xcb, 0xe0, 0x37, 0xfc, 0xae, 0x6f, 0xc0, 0xef, 0x62, 0x9c, 0x53,
+ 0xaf, 0xcf, 0xb8, 0x89, 0xd9, 0xb6, 0xc6, 0x6a, 0x93, 0x58, 0x23, 0xfa,
+ 0xed, 0xa9, 0xf2, 0x75, 0xe8, 0xc1, 0xe7, 0x7d, 0xc6, 0xf8, 0x02, 0xf9,
+ 0xef, 0x7e, 0xb3, 0xa6, 0x53, 0xf1, 0x6d, 0x79, 0x04, 0xba, 0xf1, 0x51,
+ 0xe8, 0xc6, 0x4f, 0xdc, 0x92, 0xe7, 0x43, 0x79, 0xbb, 0x7f, 0x6a, 0x76,
+ 0x65, 0xb0, 0x1c, 0xb1, 0xfb, 0x31, 0xa7, 0xe6, 0xb6, 0x8c, 0xf1, 0x25,
+ 0x4d, 0x2c, 0xb6, 0x19, 0xb3, 0x86, 0xf1, 0x56, 0xca, 0x74, 0x20, 0xd7,
+ 0xfc, 0x72, 0x57, 0x44, 0x9d, 0x3f, 0x7b, 0xb4, 0x13, 0xbb, 0xfc, 0xbd,
+ 0xd8, 0xa1, 0xed, 0xf3, 0x5b, 0x46, 0xc6, 0x76, 0x72, 0x99, 0x26, 0x32,
+ 0xe1, 0x99, 0x73, 0x37, 0x6c, 0x1e, 0xf7, 0x6d, 0x2a, 0x99, 0xc3, 0xde,
+ 0x9e, 0xdf, 0xa0, 0x5d, 0x20, 0x9e, 0x6c, 0x63, 0x4c, 0x6f, 0xa6, 0x3d,
+ 0xcb, 0xd8, 0x41, 0x37, 0xfc, 0x97, 0xd7, 0xe5, 0xdc, 0xca, 0x3f, 0x75,
+ 0xe8, 0xfd, 0xa4, 0x73, 0xcf, 0xec, 0x8b, 0xad, 0x71, 0x54, 0xbd, 0x46,
+ 0x85, 0x4c, 0x37, 0x30, 0x0c, 0xfd, 0xa5, 0x6b, 0xca, 0x5f, 0x3a, 0xec,
+ 0x3b, 0xb2, 0x19, 0x67, 0x9f, 0xaf, 0xcb, 0xb1, 0x95, 0xe1, 0x4e, 0xc6,
+ 0x2b, 0x17, 0x97, 0x0f, 0xc8, 0x96, 0xd2, 0x65, 0x0f, 0xa3, 0x6e, 0x16,
+ 0x7b, 0x36, 0x08, 0x26, 0xfc, 0xb4, 0x7b, 0x5e, 0x46, 0x12, 0xe7, 0xc1,
+ 0xd3, 0x3f, 0x43, 0x1b, 0xf8, 0xd4, 0x41, 0x11, 0xcf, 0xae, 0xc2, 0x6f,
+ 0xbf, 0x21, 0xbc, 0x1e, 0x71, 0x4f, 0x43, 0x18, 0x72, 0x6e, 0xda, 0x7d,
+ 0x4b, 0x42, 0xdb, 0x45, 0x3b, 0xc5, 0x33, 0xeb, 0x3e, 0x29, 0xac, 0x6b,
+ 0x5a, 0xe7, 0x41, 0xeb, 0xa9, 0x15, 0x8e, 0xc1, 0x79, 0x91, 0xde, 0x7f,
+ 0xe2, 0x19, 0x07, 0xe6, 0xf2, 0x41, 0x60, 0x59, 0xe2, 0x28, 0x1d, 0x8b,
+ 0x28, 0xa0, 0x8d, 0xc2, 0x5a, 0x3e, 0xcf, 0x2b, 0xc9, 0xc7, 0x2f, 0xc2,
+ 0x6f, 0x88, 0x43, 0x8e, 0xf1, 0x7c, 0xbd, 0x39, 0xe6, 0xcb, 0xfa, 0xfa,
+ 0x1c, 0xed, 0x92, 0xf2, 0x11, 0xf2, 0xc0, 0x85, 0x93, 0xa8, 0xcb, 0x78,
+ 0x67, 0x10, 0x1c, 0xf7, 0xe1, 0xc7, 0x3f, 0x45, 0xd9, 0xbb, 0x53, 0x4a,
+ 0xca, 0xe7, 0x20, 0x86, 0x65, 0xfe, 0xc6, 0x96, 0x1b, 0xc3, 0xfe, 0x9c,
+ 0x86, 0x6d, 0xcb, 0xc3, 0xb6, 0x45, 0xee, 0x3e, 0x02, 0x3c, 0xab, 0xce,
+ 0xd9, 0x60, 0x3f, 0x39, 0xee, 0xc3, 0xd6, 0xdf, 0x67, 0x46, 0x81, 0x6f,
+ 0x1f, 0x00, 0xbe, 0x65, 0x1e, 0x59, 0x1e, 0x18, 0x97, 0xf8, 0xd6, 0x95,
+ 0xbf, 0xda, 0xc8, 0x43, 0xb7, 0x4d, 0x74, 0x52, 0x17, 0x1f, 0xd9, 0xb6,
+ 0xd3, 0x45, 0x63, 0xc7, 0xf7, 0x49, 0x41, 0x9d, 0xbb, 0x15, 0x95, 0xbd,
+ 0x9f, 0x5f, 0x27, 0xae, 0x87, 0xed, 0x5f, 0x87, 0xef, 0x57, 0xa1, 0x8f,
+ 0x96, 0xc3, 0xfd, 0x03, 0xb8, 0x7f, 0x08, 0xe5, 0x11, 0x94, 0xda, 0xf7,
+ 0xb9, 0xb4, 0x1c, 0xe9, 0xd4, 0x31, 0xde, 0x44, 0x93, 0xff, 0x43, 0x39,
+ 0x8c, 0x4f, 0xcd, 0x56, 0xc3, 0x38, 0xfd, 0x21, 0x39, 0xee, 0xeb, 0xb3,
+ 0xf5, 0x09, 0xf8, 0xeb, 0x9d, 0xc0, 0x60, 0x0f, 0x3d, 0x0d, 0x9b, 0x71,
+ 0xdf, 0x21, 0xb1, 0xef, 0xb3, 0x64, 0x76, 0x14, 0x74, 0x8f, 0x0e, 0x42,
+ 0x3f, 0xf7, 0xc3, 0xdf, 0x56, 0x7e, 0xb0, 0xc1, 0x9c, 0xd4, 0xfb, 0x71,
+ 0xf9, 0xf3, 0x8d, 0x10, 0x7b, 0xb6, 0x01, 0xa7, 0x32, 0x56, 0x98, 0x54,
+ 0xb8, 0xd9, 0xbe, 0x8d, 0xeb, 0xdf, 0x25, 0xf9, 0xdb, 0xc8, 0x53, 0x3e,
+ 0x03, 0xa6, 0x51, 0xd7, 0x71, 0x49, 0x9f, 0xe1, 0xba, 0xb5, 0x9b, 0x18,
+ 0x2f, 0x6d, 0x06, 0xcb, 0xbf, 0xec, 0xdc, 0xc6, 0x96, 0x8c, 0x01, 0x59,
+ 0xe3, 0x9d, 0x3b, 0x79, 0x69, 0xa1, 0xdc, 0x87, 0xf9, 0x04, 0x94, 0xff,
+ 0x4b, 0xa0, 0x9f, 0xf6, 0x9e, 0xb6, 0xc1, 0xb5, 0xa2, 0x07, 0x89, 0x05,
+ 0x22, 0xd2, 0xe6, 0x71, 0x9f, 0xd2, 0x4e, 0x1d, 0xc1, 0x9c, 0x88, 0x0d,
+ 0x3e, 0xdf, 0x2d, 0xdd, 0xc4, 0x07, 0x49, 0x3c, 0xbb, 0x8e, 0x7a, 0xbc,
+ 0x67, 0x3d, 0xf8, 0x52, 0xcb, 0x62, 0x45, 0x0e, 0xce, 0x41, 0xae, 0x3d,
+ 0x5c, 0x1f, 0x47, 0x39, 0x8c, 0xf2, 0x71, 0x94, 0xd4, 0x4f, 0x57, 0x65,
+ 0x56, 0xc7, 0x7f, 0x14, 0x0e, 0xa1, 0xed, 0x9c, 0xf6, 0xa9, 0x53, 0x4f,
+ 0x8a, 0x3d, 0xf6, 0x41, 0x3c, 0xa3, 0x1f, 0x8f, 0x91, 0xee, 0xff, 0x82,
+ 0x89, 0x3f, 0x6d, 0xc7, 0xac, 0x8c, 0x4e, 0x5e, 0x51, 0x31, 0xfc, 0xf5,
+ 0xa7, 0xe8, 0x23, 0xff, 0x54, 0x1e, 0xbd, 0x29, 0xb6, 0xb7, 0x1d, 0xcb,
+ 0x1a, 0x2f, 0x28, 0x5d, 0x4c, 0x7e, 0x40, 0x0f, 0xbb, 0x19, 0xf9, 0xfa,
+ 0x46, 0x0f, 0xf4, 0x5b, 0x5c, 0xde, 0x58, 0x09, 0x80, 0xd5, 0xb9, 0x37,
+ 0x47, 0x60, 0x33, 0x5d, 0x83, 0x03, 0xe2, 0xf2, 0x2f, 0x90, 0xf3, 0x7f,
+ 0xae, 0x24, 0xe4, 0xcd, 0x4a, 0x10, 0x5c, 0xf3, 0xd3, 0xfe, 0x61, 0x91,
+ 0xbb, 0xdb, 0x74, 0x0e, 0x00, 0x6a, 0xe8, 0x73, 0xfb, 0x79, 0x75, 0x76,
+ 0x8f, 0x7a, 0xd0, 0x3b, 0x6f, 0x36, 0x7e, 0x01, 0xbe, 0xea, 0x3e, 0x5b,
+ 0xdb, 0x6e, 0xe9, 0xb6, 0x3c, 0xfb, 0x4f, 0x6c, 0x4a, 0xda, 0xe4, 0x10,
+ 0xa4, 0xd1, 0x36, 0x3d, 0xbc, 0xb6, 0xdd, 0x9e, 0x6d, 0x33, 0xca, 0x5e,
+ 0x94, 0xd6, 0x7b, 0xa5, 0xfe, 0x17, 0xdc, 0x2b, 0xf0, 0x63, 0xd5, 0x99,
+ 0x11, 0x4b, 0x9e, 0x55, 0xb0, 0x4e, 0xd2, 0xbc, 0x1f, 0x30, 0xef, 0x3d,
+ 0x85, 0x5f, 0x9d, 0xed, 0x18, 0x20, 0x7c, 0xdb, 0xe5, 0xd4, 0x69, 0x65,
+ 0x47, 0x18, 0xb7, 0x5d, 0xa6, 0x7f, 0x4f, 0x5d, 0x3e, 0x69, 0xec, 0x09,
+ 0x7c, 0x8f, 0xda, 0x71, 0x99, 0x51, 0xd7, 0x9f, 0x90, 0x47, 0x5c, 0xf2,
+ 0xee, 0xa4, 0xf8, 0x63, 0x1a, 0x4b, 0x89, 0x89, 0x09, 0x76, 0x78, 0x27,
+ 0xe1, 0x9b, 0x29, 0x7b, 0xec, 0x7e, 0x4c, 0xc8, 0xe3, 0x36, 0xda, 0x8f,
+ 0x9c, 0x6d, 0x01, 0x83, 0x3d, 0x99, 0x91, 0xe7, 0x36, 0x50, 0x17, 0xeb,
+ 0xf5, 0x31, 0xc1, 0xfd, 0xb3, 0xb8, 0x67, 0x1c, 0xed, 0xe9, 0xb8, 0x44,
+ 0x9e, 0xee, 0x97, 0xf6, 0x33, 0xc4, 0x29, 0xe4, 0x69, 0x42, 0xda, 0xce,
+ 0x10, 0x2f, 0x33, 0xb6, 0x9c, 0x1a, 0xbf, 0x21, 0x8c, 0xe5, 0xa4, 0xfc,
+ 0x2b, 0xf8, 0x6d, 0x61, 0xde, 0xed, 0xf0, 0xc3, 0xdb, 0x2e, 0xe8, 0x76,
+ 0xf6, 0xb9, 0x3e, 0x00, 0xc3, 0x98, 0xd8, 0xf0, 0x59, 0xec, 0x0b, 0x2c,
+ 0xbb, 0x50, 0xf2, 0x1d, 0x48, 0x3a, 0x37, 0x60, 0xde, 0x41, 0x37, 0x5e,
+ 0xe0, 0xf8, 0xb0, 0x8f, 0xbe, 0xce, 0x17, 0x1d, 0x18, 0xf2, 0xe5, 0xd2,
+ 0x1a, 0x65, 0x93, 0x71, 0x74, 0x62, 0x97, 0x57, 0xc5, 0x5e, 0xca, 0x48,
+ 0xe4, 0x4c, 0x06, 0x72, 0xe8, 0xc3, 0xee, 0x12, 0xf3, 0xd1, 0xd6, 0xe1,
+ 0x39, 0xf0, 0x56, 0xfd, 0x29, 0xce, 0xe9, 0xaa, 0xd8, 0xf5, 0x5f, 0x65,
+ 0xc3, 0xc2, 0x7d, 0xc1, 0x31, 0x4e, 0xc2, 0xfe, 0x46, 0xe5, 0x73, 0x71,
+ 0xca, 0x8a, 0x96, 0xbd, 0xb4, 0x3d, 0xa4, 0x64, 0xb5, 0x48, 0xbb, 0xfc,
+ 0xd4, 0xed, 0x7b, 0xe0, 0xa7, 0x9d, 0x2e, 0x6f, 0xcb, 0x18, 0xf3, 0x42,
+ 0x03, 0xa9, 0x02, 0xef, 0xcc, 0x7b, 0x96, 0x2c, 0x78, 0x27, 0x15, 0x1e,
+ 0x7c, 0x14, 0xed, 0x4f, 0x98, 0xf6, 0x0b, 0x32, 0x64, 0x64, 0x5d, 0xc5,
+ 0x11, 0xa0, 0xc7, 0xb8, 0x66, 0xbc, 0xff, 0x2d, 0xf1, 0x7b, 0xb9, 0x9e,
+ 0x27, 0x65, 0x60, 0x4c, 0xe3, 0x90, 0x92, 0x4d, 0x1c, 0xf2, 0xae, 0x71,
+ 0x5a, 0x95, 0xcb, 0x57, 0xa8, 0xd0, 0xce, 0xec, 0x85, 0xfc, 0xc2, 0x27,
+ 0xda, 0x08, 0x63, 0xb5, 0x6a, 0x5f, 0x25, 0x06, 0x6c, 0x4b, 0xbc, 0xa1,
+ 0xa1, 0xe1, 0x12, 0xf0, 0xc9, 0x3c, 0x7c, 0x5e, 0xd2, 0xb1, 0x00, 0x3b,
+ 0xb7, 0xe6, 0xff, 0x4b, 0x70, 0x22, 0x9e, 0x3a, 0x3d, 0xf3, 0xae, 0xf1,
+ 0xfb, 0x30, 0x6e, 0xdf, 0x7c, 0x9e, 0xb2, 0x69, 0xfd, 0x61, 0xe3, 0x88,
+ 0xd2, 0x91, 0x37, 0xe3, 0xae, 0x30, 0x7e, 0x3f, 0x7d, 0x53, 0x1c, 0xb5,
+ 0xd4, 0x08, 0x73, 0xf0, 0x42, 0x3d, 0x7f, 0x1a, 0xba, 0x3a, 0x22, 0x37,
+ 0x80, 0x41, 0x27, 0xc0, 0xbb, 0x73, 0x6b, 0x65, 0xeb, 0x4a, 0x45, 0xd4,
+ 0x7d, 0xc1, 0x67, 0x4e, 0xde, 0x47, 0xc0, 0x3b, 0xd8, 0x98, 0x0d, 0xc7,
+ 0x9c, 0x29, 0x39, 0x78, 0x66, 0x2b, 0x9f, 0xb9, 0xa4, 0x74, 0xf3, 0xe1,
+ 0x2e, 0x9e, 0xb9, 0x5c, 0x5a, 0xfe, 0x28, 0xee, 0x79, 0xf6, 0x71, 0xa4,
+ 0xe5, 0xf9, 0x66, 0x4f, 0x54, 0x63, 0x37, 0xf0, 0x5d, 0xf3, 0xcd, 0x01,
+ 0xbf, 0x8b, 0x8c, 0xe7, 0x35, 0x88, 0x83, 0x3b, 0x0d, 0x0e, 0x26, 0xce,
+ 0xc2, 0x7a, 0x6d, 0x30, 0x0e, 0x43, 0xac, 0x15, 0x57, 0x7e, 0xa1, 0xc2,
+ 0x5e, 0xfe, 0x31, 0x93, 0x7f, 0x71, 0xab, 0x5c, 0xcd, 0x56, 0x42, 0x3c,
+ 0xd7, 0x2c, 0x57, 0xee, 0x6f, 0x20, 0x57, 0x13, 0x5d, 0x3a, 0xdf, 0x81,
+ 0x36, 0xcd, 0x92, 0x37, 0xaa, 0x7b, 0x64, 0xab, 0xfa, 0x20, 0x70, 0xb4,
+ 0xca, 0xfb, 0x90, 0x2d, 0xac, 0xc5, 0x83, 0x95, 0x49, 0x99, 0xa8, 0xc6,
+ 0xe4, 0x5a, 0xd5, 0x7e, 0xa0, 0x5d, 0x18, 0x07, 0x27, 0x36, 0xf9, 0x1b,
+ 0xa5, 0xdf, 0x7e, 0xe0, 0xef, 0xb4, 0xe7, 0xb9, 0xca, 0x0d, 0xb4, 0x9f,
+ 0xad, 0xde, 0x2b, 0x25, 0xd5, 0xbe, 0x7e, 0xcb, 0x18, 0x51, 0x33, 0x46,
+ 0xbd, 0x7a, 0x97, 0x89, 0xdf, 0x95, 0xe5, 0x12, 0xb0, 0xaf, 0x7d, 0x96,
+ 0xf3, 0xbd, 0xc3, 0xe4, 0x77, 0xc5, 0x9a, 0xfc, 0x91, 0xa8, 0xf1, 0x47,
+ 0x7e, 0x06, 0x3d, 0xfe, 0x94, 0x44, 0xbd, 0xb0, 0x2f, 0xe6, 0x6a, 0x27,
+ 0x4c, 0x6e, 0xc7, 0x5e, 0xf4, 0x75, 0x10, 0xef, 0xee, 0xc3, 0xef, 0x49,
+ 0xd4, 0xa3, 0xbd, 0xe2, 0xd9, 0x28, 0x31, 0x02, 0xcf, 0xeb, 0x7a, 0x51,
+ 0xaf, 0x03, 0x58, 0x72, 0xbf, 0x79, 0x16, 0xf6, 0x11, 0xd6, 0x0d, 0xef,
+ 0x9b, 0xcf, 0x53, 0x59, 0x2f, 0xd9, 0x74, 0x9e, 0x0a, 0x45, 0xa5, 0xda,
+ 0x86, 0xb6, 0x36, 0xb4, 0x51, 0xc9, 0x26, 0x1b, 0xf5, 0x56, 0x53, 0x9e,
+ 0xa7, 0xc6, 0x61, 0x57, 0x33, 0x9c, 0x6b, 0x5f, 0x53, 0x0e, 0x4a, 0xaa,
+ 0x4c, 0xfb, 0xc8, 0x78, 0xdf, 0x7a, 0x25, 0xb4, 0x1f, 0xb9, 0x1e, 0x9e,
+ 0x5b, 0x2c, 0xfa, 0x2a, 0x16, 0x97, 0x8c, 0x64, 0x69, 0x7f, 0xfc, 0xd8,
+ 0x16, 0x70, 0x65, 0x5d, 0x9d, 0xeb, 0x47, 0xf0, 0x83, 0x5d, 0x76, 0x2c,
+ 0x71, 0x3d, 0x3e, 0x2b, 0x1b, 0xbd, 0x03, 0x5d, 0x6e, 0xab, 0x3a, 0xc9,
+ 0xbc, 0xdf, 0x67, 0xee, 0x13, 0xb2, 0x56, 0xf9, 0x50, 0xbf, 0x9d, 0xfd,
+ 0x5f, 0xb7, 0xe7, 0x33, 0x3d, 0x3c, 0x7f, 0xc2, 0x33, 0xe2, 0xf5, 0xd7,
+ 0x54, 0x4e, 0xa3, 0xc6, 0x46, 0x0e, 0xcf, 0x2f, 0x81, 0x73, 0x7e, 0x04,
+ 0x9e, 0x84, 0xb8, 0xfb, 0x75, 0x99, 0x50, 0x98, 0xaa, 0x0d, 0xb6, 0xd2,
+ 0x60, 0xaa, 0xee, 0x14, 0x30, 0x15, 0xdb, 0xb7, 0xe2, 0x40, 0xbd, 0x97,
+ 0x22, 0x59, 0x1d, 0x57, 0x6d, 0x89, 0x15, 0x5b, 0x8f, 0x64, 0xc4, 0x3a,
+ 0x81, 0x1f, 0x65, 0xd4, 0x5e, 0x7a, 0x4d, 0xbc, 0xa5, 0x54, 0x95, 0xf9,
+ 0xb1, 0x0b, 0x1b, 0x3c, 0xc7, 0x03, 0x16, 0x4b, 0x50, 0x96, 0xf9, 0x6e,
+ 0x1a, 0x63, 0xbc, 0x06, 0xff, 0x73, 0x0f, 0xf8, 0x6d, 0x1b, 0x1e, 0xf9,
+ 0x26, 0x46, 0x11, 0x63, 0x2c, 0x18, 0x7b, 0x71, 0x5e, 0x61, 0x89, 0x52,
+ 0x7c, 0x11, 0xe5, 0x0f, 0x0d, 0x76, 0x78, 0xbd, 0x2b, 0x3c, 0xb7, 0x2f,
+ 0xc5, 0xbf, 0x84, 0xe7, 0xaf, 0xc3, 0x1f, 0x8c, 0x4a, 0x9b, 0x5a, 0xb3,
+ 0x10, 0x3b, 0xff, 0x3d, 0xea, 0x90, 0xfe, 0x3b, 0x4d, 0x7e, 0x0d, 0xf3,
+ 0x06, 0xd8, 0x1f, 0xec, 0x96, 0xca, 0xe1, 0xca, 0xa1, 0x64, 0x3b, 0xb6,
+ 0x79, 0x05, 0x75, 0x73, 0x98, 0x37, 0x9f, 0x4b, 0x5f, 0x44, 0x9a, 0x9f,
+ 0x7f, 0x14, 0xcf, 0x29, 0x87, 0xef, 0x37, 0x72, 0x18, 0xbe, 0xcb, 0x1b,
+ 0x3e, 0xdd, 0x8e, 0x31, 0xc8, 0xab, 0x66, 0xba, 0x38, 0x9f, 0x70, 0xcd,
+ 0xdb, 0x4c, 0xae, 0x01, 0x9f, 0xbd, 0xdf, 0x3c, 0x73, 0xcc, 0x1c, 0x3f,
+ 0xde, 0x65, 0xb0, 0x04, 0x76, 0x7b, 0xb8, 0x1f, 0x49, 0x67, 0xac, 0x09,
+ 0xb3, 0xfe, 0x61, 0xef, 0x4e, 0x1e, 0x26, 0x65, 0xce, 0x53, 0xb1, 0x23,
+ 0xe6, 0x8f, 0xe5, 0x6c, 0x9d, 0xb3, 0xf1, 0x8d, 0x9b, 0xe2, 0xdd, 0x4a,
+ 0xd7, 0xf2, 0x0c, 0xa4, 0x6a, 0x67, 0xdb, 0x7f, 0xed, 0xbc, 0xbb, 0x48,
+ 0x36, 0x6c, 0x07, 0x9c, 0xa6, 0xda, 0x24, 0x65, 0xae, 0xf1, 0x6e, 0x39,
+ 0x7a, 0xca, 0xbf, 0x30, 0x79, 0x10, 0xfb, 0x55, 0x1e, 0x04, 0xf5, 0xe2,
+ 0x5a, 0x35, 0x02, 0x5e, 0xf7, 0x31, 0x37, 0x0a, 0x7e, 0x4c, 0x0c, 0x73,
+ 0x45, 0x5f, 0xf1, 0xf7, 0xab, 0x5c, 0xa9, 0x88, 0x17, 0xe6, 0xf5, 0x72,
+ 0x1f, 0xde, 0xa1, 0xde, 0x7f, 0x7d, 0xa5, 0x9d, 0xf9, 0xaa, 0x28, 0xb9,
+ 0x47, 0x7f, 0x09, 0xfd, 0x18, 0x95, 0x42, 0xd5, 0x03, 0xfe, 0x89, 0x52,
+ 0x2e, 0xf1, 0x7c, 0x3f, 0xfc, 0x61, 0xc1, 0x3e, 0x69, 0x83, 0x6f, 0xa2,
+ 0x7c, 0x1d, 0xcc, 0x68, 0x87, 0x0e, 0x62, 0x70, 0x9d, 0x1f, 0x1a, 0x40,
+ 0x87, 0xcf, 0xcb, 0xda, 0xf8, 0xa2, 0xd4, 0xc7, 0x9b, 0x31, 0x2c, 0x30,
+ 0xaa, 0x5b, 0x0e, 0xea, 0x9e, 0x8a, 0x65, 0x1a, 0xdd, 0x72, 0xc2, 0xe0,
+ 0x4e, 0xae, 0x83, 0x2d, 0x85, 0xd1, 0x05, 0x25, 0x5f, 0x75, 0xb5, 0x1e,
+ 0x8e, 0x75, 0x59, 0xe5, 0xf9, 0x72, 0x0c, 0xe6, 0xfa, 0x46, 0x0c, 0x0e,
+ 0x3b, 0x65, 0xd6, 0xd5, 0xd9, 0x1b, 0xe6, 0xcc, 0x47, 0xb3, 0x87, 0x99,
+ 0xdb, 0x01, 0x6c, 0x3d, 0x3d, 0x35, 0x5b, 0xa1, 0x2d, 0x0c, 0x82, 0xba,
+ 0xbf, 0x89, 0x1e, 0x7f, 0xac, 0x30, 0xe4, 0x96, 0x68, 0xdd, 0xbe, 0xa0,
+ 0x72, 0x66, 0x27, 0xa7, 0xf2, 0x2a, 0x5e, 0xd8, 0x7c, 0x76, 0xf3, 0x5e,
+ 0xe7, 0x36, 0x31, 0xf8, 0xfe, 0x1d, 0x66, 0xfd, 0x63, 0x4e, 0xa9, 0xd2,
+ 0xe5, 0xcc, 0xaa, 0xb3, 0xb5, 0xac, 0xf9, 0x16, 0x27, 0x37, 0x95, 0x6e,
+ 0x7c, 0x76, 0x2f, 0xb1, 0x3e, 0xcf, 0x31, 0x0a, 0x15, 0x9e, 0xe3, 0xe8,
+ 0xf7, 0x69, 0xf3, 0x7e, 0xa0, 0xa1, 0xde, 0xa9, 0x78, 0x23, 0x63, 0x8c,
+ 0xed, 0x28, 0x6f, 0x54, 0xa8, 0x6b, 0xd0, 0x7f, 0x5c, 0xcf, 0x21, 0x92,
+ 0x2d, 0xc2, 0x3f, 0x25, 0x7d, 0x47, 0xa6, 0xf2, 0x2b, 0xcc, 0xdb, 0x7a,
+ 0x68, 0xea, 0x1a, 0xfc, 0xa5, 0x73, 0x9e, 0xce, 0x2b, 0x5f, 0x67, 0x1c,
+ 0x8c, 0xed, 0x54, 0x9f, 0x45, 0x13, 0xab, 0x3d, 0x3c, 0x35, 0xb8, 0x1e,
+ 0x91, 0x27, 0x4c, 0x1f, 0xbc, 0x4f, 0x6e, 0xfb, 0x52, 0x4a, 0xff, 0xc1,
+ 0x3f, 0x18, 0x85, 0x7f, 0xd0, 0x09, 0x5d, 0x4f, 0x3f, 0x83, 0xf8, 0xbb,
+ 0x13, 0x7b, 0x85, 0xe3, 0xdc, 0xa5, 0xc6, 0x89, 0x60, 0x9c, 0x59, 0xf8,
+ 0x38, 0x8c, 0x47, 0xe6, 0x3d, 0x07, 0x58, 0x02, 0xb6, 0xde, 0x63, 0xbc,
+ 0xdc, 0xc6, 0x9c, 0x87, 0xa1, 0x27, 0x98, 0xa3, 0x32, 0x11, 0xe6, 0x0d,
+ 0xa1, 0x9d, 0x6f, 0xda, 0x1d, 0x44, 0x3b, 0xfa, 0x07, 0x6c, 0x2b, 0xb7,
+ 0xd9, 0x32, 0xa8, 0xb0, 0x81, 0xf6, 0x6b, 0x48, 0x43, 0x0d, 0x73, 0xa5,
+ 0x5d, 0xc5, 0x9e, 0x53, 0xf3, 0x3a, 0xa8, 0xda, 0x59, 0xd9, 0x31, 0xd0,
+ 0x4e, 0xfc, 0x87, 0xbe, 0x97, 0x75, 0xbc, 0xb3, 0xa0, 0xe4, 0x08, 0x72,
+ 0x32, 0x1e, 0xe6, 0xbd, 0xe8, 0x76, 0x61, 0xfd, 0x81, 0xf5, 0x86, 0x19,
+ 0xff, 0xe7, 0x41, 0xee, 0x68, 0xa7, 0xf2, 0xad, 0x5f, 0xbe, 0x29, 0x07,
+ 0x8d, 0x6d, 0xc2, 0x3a, 0x91, 0x30, 0x2f, 0xb9, 0x89, 0xe6, 0xac, 0x59,
+ 0x73, 0xb6, 0x63, 0x6c, 0x58, 0xe5, 0xe2, 0xf3, 0x99, 0x33, 0x97, 0x61,
+ 0x1f, 0xcd, 0x67, 0x4d, 0xa3, 0xc0, 0x19, 0xda, 0x86, 0x94, 0x37, 0x3c,
+ 0xd8, 0xeb, 0x36, 0xac, 0x1d, 0x6d, 0xc2, 0xa0, 0xf1, 0x2d, 0xde, 0x2b,
+ 0xce, 0xca, 0x73, 0xcc, 0x51, 0xf8, 0xf5, 0x61, 0x7b, 0xae, 0x63, 0x6e,
+ 0xea, 0x5a, 0xc5, 0x93, 0x53, 0xcb, 0x3a, 0x3f, 0x4c, 0xf3, 0x81, 0x3a,
+ 0x9b, 0x6b, 0x9b, 0x94, 0x59, 0x8f, 0xb1, 0x9c, 0xa4, 0xbc, 0xe2, 0x35,
+ 0xe7, 0x39, 0xa1, 0xfe, 0xc6, 0xa8, 0xc9, 0xc7, 0x3e, 0x88, 0xf9, 0x13,
+ 0x37, 0x6a, 0x59, 0x3a, 0x00, 0x3b, 0xf4, 0x77, 0x0e, 0x70, 0x21, 0xf6,
+ 0xd3, 0x75, 0xa7, 0x79, 0x7e, 0xdb, 0xf9, 0xdf, 0x4a, 0x2e, 0x1d, 0xc8,
+ 0xc8, 0xe2, 0x36, 0xdf, 0xe1, 0xb7, 0xdf, 0x35, 0x04, 0x7d, 0x6f, 0x49,
+ 0x71, 0xd4, 0x4b, 0x2c, 0xf0, 0x5c, 0xc3, 0x1d, 0x01, 0xca, 0xa7, 0x1f,
+ 0x9d, 0x04, 0xbd, 0xbc, 0x1e, 0x04, 0x3e, 0x62, 0x4e, 0x22, 0xee, 0x99,
+ 0x13, 0x18, 0xf7, 0x40, 0xaf, 0xab, 0xce, 0x2b, 0xb4, 0xce, 0xfe, 0xfe,
+ 0x5e, 0xe6, 0xc0, 0xf5, 0x78, 0xe1, 0xda, 0xab, 0xef, 0xda, 0xd0, 0x77,
+ 0xc4, 0xbc, 0x9f, 0xd8, 0xe6, 0xbf, 0xf4, 0xb1, 0xdc, 0xce, 0x35, 0x33,
+ 0xb1, 0x17, 0xd6, 0x1f, 0x57, 0xb4, 0xcc, 0x42, 0x57, 0xcf, 0xa9, 0xf9,
+ 0xdc, 0x0f, 0x59, 0x88, 0xc8, 0xfc, 0xb6, 0xfc, 0xde, 0x0f, 0xf9, 0xdd,
+ 0xc3, 0x14, 0xcf, 0x5d, 0x64, 0x2d, 0x94, 0x31, 0xca, 0x17, 0x65, 0xeb,
+ 0xe3, 0xdd, 0xdc, 0x73, 0xe5, 0xed, 0x75, 0x77, 0x94, 0xcd, 0x4d, 0xda,
+ 0xe1, 0xba, 0xf3, 0x7a, 0xb7, 0xdc, 0xaa, 0x70, 0x7f, 0x64, 0x7e, 0x83,
+ 0xb5, 0xf5, 0xcd, 0xda, 0x66, 0x9a, 0xbe, 0x83, 0x08, 0xfb, 0x63, 0x0c,
+ 0x94, 0x36, 0x88, 0xe7, 0x50, 0xed, 0x52, 0x56, 0x32, 0x68, 0x29, 0x6c,
+ 0x9d, 0x73, 0xf3, 0x49, 0xc6, 0xbc, 0x8f, 0xc9, 0xbf, 0x03, 0xcd, 0xb9,
+ 0xe1, 0xa8, 0xe8, 0xb6, 0x33, 0xe0, 0xf7, 0xa6, 0x0b, 0x7f, 0x90, 0x67,
+ 0xd6, 0x15, 0x47, 0xce, 0xa9, 0x73, 0x57, 0xec, 0xd1, 0x4e, 0x47, 0x16,
+ 0xbd, 0xed, 0x73, 0x78, 0xa9, 0xa1, 0xce, 0x1a, 0xde, 0x3d, 0xb1, 0x4d,
+ 0x1b, 0xfd, 0x09, 0xf8, 0x52, 0xde, 0xcf, 0x83, 0x52, 0xfc, 0xa6, 0xba,
+ 0x46, 0xaf, 0x33, 0x4e, 0xc3, 0xf3, 0x01, 0x57, 0x0a, 0xf0, 0x0b, 0x0b,
+ 0xf0, 0x09, 0x0b, 0x4a, 0x2f, 0x30, 0x6e, 0xc3, 0x18, 0x5b, 0x19, 0x3e,
+ 0x48, 0x39, 0x68, 0xf7, 0x4e, 0xaa, 0x18, 0xe2, 0xa5, 0x8d, 0x54, 0xb9,
+ 0x2c, 0x5e, 0xf2, 0xc1, 0xed, 0x7c, 0xba, 0xee, 0x72, 0x2c, 0xdb, 0x1c,
+ 0x87, 0x4b, 0xaa, 0x5c, 0xb4, 0x0e, 0x60, 0xe4, 0xe3, 0xd0, 0xd5, 0xcf,
+ 0xfb, 0x8c, 0xbf, 0xdd, 0x49, 0x7e, 0x7f, 0x95, 0x93, 0xb4, 0x87, 0x46,
+ 0xc5, 0xbb, 0xe0, 0x0d, 0x3f, 0x28, 0xf4, 0x3f, 0x52, 0xc9, 0x23, 0xe4,
+ 0xdb, 0xf6, 0x37, 0x0d, 0xa1, 0x7d, 0x1d, 0x95, 0xc1, 0x0b, 0xaf, 0xab,
+ 0x33, 0x8e, 0x4f, 0xf8, 0xad, 0xb2, 0xa1, 0xe2, 0x77, 0xa3, 0x3d, 0x32,
+ 0x08, 0xdf, 0x57, 0x60, 0xa1, 0xf8, 0x8d, 0x83, 0x05, 0xdf, 0x43, 0xdd,
+ 0xcb, 0x74, 0x23, 0x69, 0xf2, 0x54, 0x69, 0x5f, 0x19, 0xdf, 0xd3, 0x79,
+ 0x7a, 0xcc, 0x4d, 0x65, 0xfe, 0x64, 0x51, 0xe5, 0xeb, 0x31, 0xd6, 0xc7,
+ 0x58, 0x1e, 0xe3, 0x7d, 0x8c, 0xdb, 0xe9, 0x5c, 0xbd, 0x89, 0xc6, 0x6e,
+ 0xb1, 0xbd, 0x30, 0x5f, 0x52, 0xdb, 0xad, 0xad, 0xcc, 0x3e, 0xd8, 0x3a,
+ 0x57, 0xc5, 0x4e, 0x4a, 0x6e, 0x8f, 0x1c, 0x1b, 0x6e, 0x07, 0xcf, 0x7b,
+ 0x55, 0x3e, 0x9d, 0xed, 0xdd, 0x0f, 0x1c, 0xcb, 0xf8, 0x1c, 0xb1, 0x69,
+ 0xc8, 0xe7, 0x7b, 0xf0, 0xec, 0x1d, 0xf0, 0x9e, 0xcf, 0x80, 0x5b, 0x95,
+ 0x1d, 0xfa, 0xbc, 0x6c, 0x55, 0x98, 0x03, 0x5f, 0xdb, 0x97, 0x57, 0xeb,
+ 0x41, 0xdf, 0x3c, 0xd4, 0x4d, 0x61, 0xfe, 0x28, 0x7d, 0x2a, 0xd7, 0x9c,
+ 0x93, 0xd3, 0x37, 0xef, 0x85, 0xbf, 0x4e, 0xfd, 0x63, 0xa9, 0xb1, 0xae,
+ 0x47, 0x3e, 0x20, 0xe5, 0xda, 0x6e, 0x67, 0xfe, 0x41, 0xf0, 0x0d, 0x5f,
+ 0xe5, 0xac, 0xc2, 0x9f, 0xd4, 0x6b, 0xac, 0xbf, 0x8f, 0x74, 0x76, 0xf2,
+ 0xcb, 0xe3, 0xda, 0x67, 0xcc, 0xf5, 0x02, 0xb3, 0x78, 0xa7, 0xbb, 0x77,
+ 0xb0, 0xf3, 0x2f, 0x0d, 0xae, 0x25, 0x6e, 0xee, 0x55, 0xd8, 0xc0, 0xae,
+ 0x87, 0x72, 0xc2, 0x7c, 0x1f, 0x62, 0xea, 0x03, 0x92, 0xab, 0x41, 0x6f,
+ 0xf6, 0xf1, 0xfe, 0x47, 0xa6, 0x2d, 0xaf, 0x03, 0x39, 0x3c, 0xd6, 0x7a,
+ 0x96, 0x3f, 0xae, 0x71, 0x7d, 0x67, 0x78, 0x9e, 0x1f, 0xe6, 0xbc, 0xdf,
+ 0x94, 0x5b, 0x0b, 0x79, 0x0a, 0x69, 0xd0, 0x63, 0x4d, 0x80, 0xde, 0x7a,
+ 0x35, 0x21, 0xbd, 0x1e, 0xf3, 0x84, 0x22, 0x32, 0xd6, 0x9b, 0x82, 0x13,
+ 0xaf, 0xe9, 0xa9, 0xd7, 0x60, 0xf3, 0xab, 0x21, 0x9d, 0x1a, 0xe3, 0xd7,
+ 0x6b, 0x7c, 0x9f, 0xc4, 0x58, 0xed, 0x32, 0xd6, 0x47, 0x3e, 0xb7, 0xd2,
+ 0x91, 0x34, 0xf9, 0xdc, 0xad, 0xcf, 0xef, 0x6b, 0xa2, 0xef, 0xd6, 0xef,
+ 0x4a, 0xf3, 0x8c, 0x8b, 0xad, 0xd0, 0x3f, 0x21, 0x8d, 0xbd, 0xd0, 0x73,
+ 0x98, 0xa3, 0x1f, 0xfa, 0x1a, 0x21, 0x5f, 0x42, 0x1f, 0x25, 0xaa, 0xe4,
+ 0x62, 0x36, 0xc3, 0xb9, 0x44, 0x8d, 0xcf, 0x42, 0xba, 0x14, 0x6d, 0x11,
+ 0x9e, 0x25, 0x46, 0xbd, 0xcf, 0xec, 0xd3, 0xeb, 0xff, 0xa4, 0x99, 0xaf,
+ 0x6b, 0xea, 0xb0, 0xaf, 0xfd, 0x68, 0xff, 0xb5, 0x00, 0x63, 0x31, 0x08,
+ 0x87, 0xfd, 0x1f, 0x62, 0xf7, 0xfd, 0xba, 0xaf, 0xce, 0x10, 0xbf, 0x87,
+ 0xdf, 0xa1, 0x91, 0x4e, 0xee, 0xaf, 0x90, 0x87, 0xec, 0xa3, 0xd7, 0xc4,
+ 0x5c, 0x49, 0x43, 0x47, 0x0b, 0x0d, 0x29, 0xff, 0x66, 0x1d, 0x77, 0x4f,
+ 0xd3, 0xdc, 0x29, 0x6b, 0xdd, 0xb2, 0x50, 0xed, 0x94, 0xf9, 0xaa, 0xf2,
+ 0x75, 0x86, 0x45, 0x88, 0xed, 0xb8, 0x2f, 0x55, 0x2e, 0xb3, 0xc9, 0x99,
+ 0x0c, 0xf7, 0x67, 0x37, 0xea, 0xd1, 0x86, 0xa0, 0xac, 0x69, 0xfd, 0x54,
+ 0x93, 0x5b, 0xbf, 0xd3, 0x98, 0x6b, 0xb4, 0xe6, 0xe3, 0x5d, 0x6f, 0xca,
+ 0xc7, 0x6b, 0xce, 0x7f, 0x2a, 0xcb, 0x23, 0x07, 0x3b, 0x64, 0xe0, 0x6c,
+ 0xa7, 0x91, 0xd1, 0xfb, 0xcd, 0x38, 0x18, 0x6f, 0x69, 0x5c, 0x06, 0x96,
+ 0xbe, 0x28, 0xa5, 0x69, 0x95, 0xff, 0xde, 0xf4, 0xfd, 0xc3, 0xa0, 0xf9,
+ 0xfe, 0x29, 0x67, 0x31, 0x17, 0xa6, 0xb0, 0x84, 0xf5, 0x3a, 0x98, 0x1a,
+ 0x4e, 0xda, 0xfc, 0x46, 0xf7, 0x31, 0x19, 0x58, 0x1d, 0x97, 0xf4, 0x12,
+ 0x31, 0x03, 0xb3, 0x01, 0x52, 0x2a, 0x2e, 0x9a, 0xbe, 0xa8, 0xfb, 0xf3,
+ 0x96, 0xf8, 0x3e, 0x0d, 0xbc, 0xca, 0xf7, 0x85, 0x44, 0x44, 0x65, 0x0c,
+ 0x7c, 0x10, 0xf2, 0xd4, 0x66, 0xf0, 0x80, 0x23, 0xf9, 0x25, 0xb6, 0x27,
+ 0xf6, 0xf8, 0x47, 0xac, 0x59, 0x21, 0x69, 0x0b, 0xdb, 0xa8, 0xfe, 0x70,
+ 0x1d, 0xc6, 0xd3, 0xc9, 0xeb, 0x51, 0x59, 0x6f, 0x78, 0xd8, 0x13, 0xfa,
+ 0x9b, 0x89, 0x52, 0x2d, 0xcc, 0x27, 0x7d, 0xc4, 0xc4, 0x00, 0x34, 0x8d,
+ 0xc5, 0x4a, 0xab, 0xec, 0x3d, 0x63, 0xbe, 0x9d, 0xe8, 0x50, 0x67, 0x68,
+ 0x4d, 0xfa, 0xcf, 0xd4, 0xbf, 0xdd, 0x65, 0xde, 0x80, 0x08, 0xdf, 0x37,
+ 0xf9, 0x24, 0xf1, 0xb8, 0xda, 0x07, 0x03, 0xf5, 0xb0, 0xde, 0xa8, 0xab,
+ 0x7d, 0x60, 0xf2, 0x29, 0x6b, 0x68, 0x1e, 0x83, 0xcf, 0xc3, 0x67, 0x07,
+ 0xd0, 0x96, 0xeb, 0x84, 0xb2, 0x7e, 0x40, 0xe5, 0x39, 0x46, 0xb2, 0x47,
+ 0xcc, 0x59, 0x5a, 0x9f, 0x1a, 0xcb, 0xcd, 0xb2, 0xff, 0x50, 0x37, 0x74,
+ 0x34, 0x8d, 0xdf, 0x4a, 0x2f, 0x7d, 0xf8, 0x9f, 0x19, 0x79, 0xe1, 0x7b,
+ 0xde, 0xb7, 0xd6, 0xf9, 0xa3, 0x7d, 0xe1, 0x7b, 0x67, 0xfb, 0x1b, 0x0c,
+ 0xf2, 0x92, 0x67, 0x80, 0x28, 0x2f, 0x32, 0x97, 0x9d, 0xd7, 0x28, 0xcd,
+ 0xb7, 0x25, 0xce, 0x12, 0x7f, 0xad, 0xfd, 0x38, 0xe8, 0x3b, 0xdc, 0xb3,
+ 0xbb, 0xe5, 0x06, 0x51, 0x17, 0x9f, 0xb6, 0xb6, 0x2a, 0x8c, 0x5d, 0x94,
+ 0xe5, 0x58, 0xa6, 0x5b, 0x66, 0xab, 0x36, 0xbf, 0x4d, 0x65, 0x2c, 0x96,
+ 0x67, 0x95, 0x32, 0xa7, 0x74, 0xdc, 0x90, 0xe8, 0xef, 0x76, 0x3b, 0xa4,
+ 0xe8, 0x52, 0x9e, 0x87, 0x64, 0xbd, 0x36, 0xdd, 0x94, 0x03, 0xdc, 0x66,
+ 0xe4, 0xec, 0xef, 0xa2, 0xd2, 0xc9, 0x38, 0x52, 0xb8, 0xa7, 0x87, 0xa4,
+ 0x58, 0x6b, 0x3e, 0x67, 0x60, 0x9e, 0x11, 0xe5, 0xb6, 0xbf, 0x69, 0xef,
+ 0x31, 0x57, 0x0f, 0xb8, 0x2a, 0x4e, 0x9f, 0x95, 0xf5, 0xf6, 0x1a, 0x7b,
+ 0xfb, 0x15, 0xac, 0xc7, 0xfb, 0x2d, 0xf1, 0x48, 0x1b, 0x6c, 0x84, 0xc9,
+ 0x35, 0x3e, 0x1c, 0x2f, 0xc3, 0x3f, 0x1b, 0x32, 0xe3, 0xde, 0x81, 0x7b,
+ 0xd6, 0xdd, 0x67, 0xde, 0xef, 0x37, 0xf7, 0x9d, 0xe6, 0x3e, 0x82, 0x7b,
+ 0xe6, 0x8d, 0xb3, 0x4f, 0x96, 0xfc, 0x9e, 0x88, 0xdf, 0xeb, 0x64, 0x25,
+ 0x7a, 0x11, 0xe8, 0xa9, 0xd1, 0x29, 0x9f, 0xae, 0x29, 0xfe, 0x5a, 0xde,
+ 0x12, 0x01, 0xc1, 0x7e, 0x73, 0x7d, 0xeb, 0x1e, 0xfc, 0xdc, 0x4d, 0xdf,
+ 0x4a, 0x55, 0x8c, 0xac, 0x34, 0xd3, 0x9b, 0x03, 0xad, 0xef, 0x96, 0x83,
+ 0x45, 0x1b, 0xa5, 0xfd, 0xc6, 0x62, 0x45, 0xe7, 0x1a, 0x1d, 0x83, 0xdf,
+ 0x78, 0xb8, 0xfa, 0xa8, 0xab, 0xf3, 0x62, 0xc2, 0x5c, 0xca, 0x4e, 0xcc,
+ 0x6b, 0xc8, 0x9c, 0x5b, 0xb3, 0x2d, 0x73, 0x3a, 0xc3, 0xf3, 0x99, 0x66,
+ 0xac, 0x4a, 0x5b, 0x44, 0x3b, 0xc3, 0xef, 0x9a, 0x7c, 0xd4, 0x5d, 0xa4,
+ 0xae, 0x69, 0xca, 0xcd, 0xff, 0x52, 0x4b, 0x6e, 0x3e, 0xbf, 0xfb, 0x16,
+ 0xf9, 0x6f, 0x0d, 0xc6, 0x95, 0x3a, 0x24, 0x72, 0x36, 0xcc, 0xc1, 0xe2,
+ 0x1a, 0x13, 0x87, 0xf1, 0x7b, 0xef, 0xa9, 0x5d, 0x62, 0x4e, 0xa1, 0x9c,
+ 0x7f, 0xc7, 0x65, 0x7e, 0xab, 0x9b, 0x0d, 0xe3, 0x54, 0xcc, 0xeb, 0x21,
+ 0xe6, 0x3a, 0x60, 0x62, 0x0a, 0x7c, 0x57, 0x96, 0x9e, 0x83, 0x53, 0xdc,
+ 0x1b, 0xbf, 0x1d, 0xd9, 0xce, 0xfd, 0x57, 0xe3, 0xc4, 0x35, 0x86, 0xe4,
+ 0x77, 0xe3, 0x3e, 0xf6, 0xd5, 0x9e, 0xcd, 0xf0, 0x9b, 0x8c, 0xcb, 0x8d,
+ 0x8c, 0xfa, 0xf6, 0x83, 0x67, 0x1e, 0x5b, 0x0d, 0xee, 0x3b, 0x7e, 0x23,
+ 0x9e, 0x55, 0x39, 0x01, 0x5b, 0xe6, 0x9b, 0xe7, 0xab, 0x0d, 0xfd, 0x1d,
+ 0xcb, 0xe2, 0xb2, 0xca, 0xcb, 0x07, 0x56, 0x4b, 0xe2, 0x3d, 0x73, 0xe8,
+ 0xfa, 0x55, 0x2e, 0xc1, 0x7c, 0xe3, 0x53, 0x28, 0x3f, 0x2f, 0x6b, 0x15,
+ 0x1d, 0x7f, 0x9d, 0x6f, 0x30, 0xa7, 0xc0, 0x55, 0x67, 0x44, 0x03, 0x4b,
+ 0x45, 0x8c, 0x17, 0x7e, 0xb3, 0x1d, 0xc7, 0x33, 0xd2, 0x57, 0x36, 0x7b,
+ 0x34, 0xcc, 0x05, 0xe9, 0xea, 0xa1, 0x4d, 0x28, 0x37, 0xba, 0x54, 0x1e,
+ 0x82, 0xc6, 0x23, 0xc4, 0x7a, 0x31, 0xd4, 0xe5, 0x5c, 0x3b, 0x69, 0xaf,
+ 0x02, 0xea, 0xa4, 0x34, 0xc6, 0xa9, 0xab, 0xdc, 0x44, 0xf2, 0xd9, 0x73,
+ 0x4b, 0xf4, 0xd7, 0x94, 0x8e, 0x4f, 0x0d, 0xcf, 0x48, 0xc1, 0x8d, 0xc2,
+ 0x17, 0x9b, 0x57, 0x7e, 0xce, 0xfd, 0xc0, 0xd0, 0x5d, 0x9b, 0x91, 0x2c,
+ 0xe7, 0xc6, 0xb1, 0xe9, 0x87, 0xe8, 0xf9, 0xe8, 0x33, 0x02, 0xb1, 0xe6,
+ 0xd5, 0xf7, 0x8f, 0x7c, 0xce, 0x78, 0x6f, 0xf8, 0xcd, 0x90, 0xfe, 0x26,
+ 0x64, 0xa6, 0x71, 0x44, 0x4e, 0x55, 0xf6, 0xf2, 0x5b, 0x09, 0x7f, 0x0b,
+ 0x7c, 0x3b, 0xd6, 0xe8, 0x52, 0xdf, 0xa5, 0xcc, 0x34, 0x98, 0x3f, 0x17,
+ 0xda, 0x1e, 0xae, 0x55, 0xdc, 0x7c, 0x37, 0x91, 0x30, 0xdf, 0x4d, 0xf0,
+ 0xdb, 0x8f, 0x1f, 0xed, 0x0d, 0xf7, 0xfb, 0xad, 0x38, 0x9c, 0x32, 0xf8,
+ 0xa7, 0xf0, 0x0d, 0xc3, 0x3c, 0x4c, 0xe6, 0x8b, 0x06, 0xc1, 0x31, 0x9f,
+ 0xf1, 0xdb, 0xe9, 0xc3, 0x6b, 0x98, 0xe3, 0x95, 0x1a, 0x78, 0x78, 0x94,
+ 0xcf, 0x98, 0x37, 0xd6, 0x2e, 0xf9, 0xd1, 0x76, 0xea, 0xf2, 0xce, 0x35,
+ 0x6f, 0xaf, 0x5c, 0xae, 0xc6, 0x55, 0x0e, 0x5c, 0x09, 0x38, 0xbf, 0x2e,
+ 0x1f, 0xeb, 0xe1, 0xd9, 0xdd, 0x84, 0x6a, 0x1f, 0xee, 0x77, 0x1d, 0x37,
+ 0x98, 0x58, 0xd7, 0xfa, 0xe4, 0x78, 0x06, 0xb8, 0xe5, 0x82, 0x58, 0x7f,
+ 0x90, 0xe9, 0x87, 0xef, 0xcd, 0xb1, 0xd2, 0x68, 0x07, 0xd9, 0x49, 0x70,
+ 0xaf, 0xbf, 0x13, 0xd4, 0x41, 0xef, 0x8d, 0x06, 0xf1, 0x3a, 0x30, 0xd4,
+ 0x34, 0xdb, 0x64, 0xc5, 0x3e, 0xc3, 0x3a, 0xbd, 0x90, 0xbf, 0x28, 0xe6,
+ 0xe3, 0xc0, 0x17, 0xd8, 0x27, 0x75, 0x97, 0xef, 0x1c, 0x7d, 0xa6, 0x12,
+ 0x0f, 0xfd, 0x94, 0xef, 0x81, 0x7f, 0x49, 0xa5, 0x93, 0xc2, 0xf3, 0x4e,
+ 0xe6, 0xb3, 0xce, 0x56, 0x27, 0xb1, 0x87, 0x1c, 0x83, 0xcd, 0x1c, 0xf4,
+ 0xf1, 0xe1, 0x1e, 0x8d, 0x15, 0x78, 0x1e, 0xaa, 0xb1, 0x88, 0xb6, 0x31,
+ 0x3c, 0xdf, 0x71, 0xe0, 0x0b, 0x84, 0xfb, 0xf2, 0x99, 0x7d, 0x37, 0x7f,
+ 0x0b, 0x43, 0x1c, 0x93, 0x4e, 0x9c, 0xe7, 0x79, 0xdc, 0xc6, 0xc3, 0x32,
+ 0x03, 0x9a, 0x4f, 0x9b, 0x79, 0x3e, 0x98, 0xf1, 0xe4, 0x7a, 0x8d, 0xe7,
+ 0x95, 0x07, 0x50, 0x32, 0xd7, 0x91, 0x34, 0x8f, 0x98, 0x7c, 0xce, 0x2c,
+ 0xe6, 0xfa, 0x98, 0xbc, 0x01, 0x7c, 0xfd, 0x66, 0x25, 0xed, 0x4f, 0xa8,
+ 0x3c, 0xa4, 0x54, 0xe2, 0xb2, 0x8c, 0x24, 0xe9, 0x03, 0x96, 0xdd, 0x54,
+ 0xe2, 0x3a, 0xe4, 0xe1, 0x46, 0xe5, 0x99, 0x1e, 0xfe, 0xaf, 0x8a, 0x3a,
+ 0xec, 0xe1, 0x0d, 0x95, 0x83, 0x94, 0x62, 0xcc, 0x04, 0xf7, 0xfd, 0x26,
+ 0x0f, 0x8a, 0xe3, 0xf0, 0x5d, 0xbf, 0xbc, 0x51, 0xd9, 0xb6, 0xbf, 0x1c,
+ 0xc7, 0x7c, 0x03, 0xcf, 0xb1, 0x2e, 0xf4, 0x50, 0x0f, 0x71, 0x3c, 0xdd,
+ 0x47, 0x58, 0x87, 0x7c, 0x0d, 0xe3, 0x9a, 0xea, 0x5b, 0xcb, 0xa4, 0x58,
+ 0x96, 0xb4, 0x79, 0x9c, 0xfb, 0x54, 0x8f, 0xc6, 0x40, 0x6c, 0x97, 0x76,
+ 0x0f, 0xab, 0xfe, 0x78, 0xb6, 0xc7, 0xf3, 0xaf, 0xb0, 0x1f, 0xe6, 0x43,
+ 0x31, 0xe7, 0x8a, 0xba, 0xaf, 0x99, 0x06, 0x6d, 0xff, 0xdf, 0x50, 0xb1,
+ 0xf4, 0x71, 0xd4, 0xa7, 0x8d, 0x86, 0xbc, 0xd4, 0x12, 0xdb, 0xdf, 0x7c,
+ 0x68, 0x5e, 0xf2, 0xfa, 0x99, 0xed, 0x6f, 0x32, 0xec, 0xbb, 0x5d, 0xf3,
+ 0x3e, 0xc4, 0xa5, 0xfd, 0xd8, 0xaf, 0x8f, 0x49, 0x7d, 0x25, 0x9d, 0xf8,
+ 0xb4, 0x84, 0xfd, 0x06, 0x87, 0x78, 0xde, 0x51, 0xcc, 0x8c, 0xb8, 0x0b,
+ 0x8a, 0x9e, 0x54, 0x82, 0x39, 0xc8, 0x97, 0x31, 0x5e, 0xbd, 0xd1, 0x1a,
+ 0x7b, 0x48, 0xe5, 0x36, 0x25, 0xed, 0xeb, 0xb5, 0x19, 0x92, 0x4d, 0xac,
+ 0xcd, 0x9f, 0x9b, 0xb5, 0xf9, 0x18, 0xfa, 0xf6, 0xce, 0x8c, 0x4a, 0xfa,
+ 0x4c, 0x3a, 0x79, 0x5a, 0x78, 0x96, 0xb8, 0x8f, 0x31, 0x2c, 0xeb, 0xc1,
+ 0x4c, 0x12, 0xf3, 0x4d, 0x61, 0xbe, 0x28, 0x1b, 0xbc, 0x1e, 0x81, 0x6f,
+ 0xbe, 0x87, 0x7b, 0xfb, 0x10, 0x75, 0x26, 0x79, 0x51, 0x54, 0xef, 0x80,
+ 0x4f, 0x9e, 0x26, 0x4d, 0x00, 0xca, 0x9d, 0x29, 0x15, 0x07, 0xbc, 0xde,
+ 0xe0, 0xf9, 0xa2, 0xa6, 0xaf, 0x00, 0xfa, 0xe6, 0x34, 0x7d, 0xc9, 0x99,
+ 0x6d, 0xec, 0x9a, 0x4a, 0x9c, 0x12, 0xe2, 0x25, 0xe2, 0x17, 0xe2, 0xfa,
+ 0x47, 0x7a, 0xc3, 0x6f, 0x5a, 0xf2, 0x77, 0xe7, 0xb6, 0xe7, 0xde, 0x86,
+ 0xba, 0x57, 0x32, 0x2a, 0xbf, 0xd9, 0x3d, 0x22, 0x1f, 0x91, 0xdc, 0xa7,
+ 0x52, 0xc9, 0x9c, 0xe5, 0x19, 0x0c, 0x88, 0xb2, 0xc6, 0x6b, 0xea, 0x5c,
+ 0xcf, 0x60, 0x0b, 0xae, 0x4d, 0x06, 0x63, 0x29, 0xde, 0xc2, 0x67, 0xea,
+ 0x87, 0xcc, 0x53, 0xd6, 0x7e, 0x07, 0x7b, 0x48, 0xff, 0x9f, 0x8e, 0xcb,
+ 0xe0, 0xe3, 0x3c, 0xf8, 0x78, 0xfc, 0x16, 0x0c, 0x16, 0xdd, 0xc6, 0x60,
+ 0x5b, 0x6a, 0xbc, 0x7b, 0x41, 0x53, 0xc1, 0x25, 0xfe, 0x9a, 0xdf, 0x96,
+ 0x15, 0xd2, 0x34, 0xca, 0xff, 0xb5, 0x23, 0x57, 0x33, 0x5c, 0x0f, 0x60,
+ 0x30, 0xf4, 0xb7, 0xb6, 0x23, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e,
+ 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x1a, 0x68, 0xd9, 0x52,
+ 0x72, 0xa0, 0x65, 0x60, 0xab, 0xd6, 0xf9, 0x1e, 0x32, 0xc0, 0x79, 0x52,
+ 0xfe, 0x42, 0xd9, 0xdb, 0xc9, 0xa7, 0xe8, 0x00, 0x4f, 0x3e, 0x78, 0x4f,
+ 0x56, 0xf2, 0x67, 0x78, 0x16, 0x26, 0xd6, 0xc8, 0x3d, 0x94, 0x49, 0xe2,
+ 0x04, 0x60, 0xc8, 0x04, 0x79, 0xac, 0xf1, 0xe0, 0xcc, 0xb3, 0x7b, 0xf1,
+ 0x7b, 0xb3, 0x87, 0x39, 0x33, 0xf9, 0x73, 0xd4, 0x57, 0x62, 0xdd, 0x79,
+ 0x8f, 0xf6, 0x0f, 0x6f, 0xc4, 0xc1, 0x73, 0xbc, 0x1f, 0x78, 0xb2, 0x0d,
+ 0xfa, 0xca, 0x31, 0xf3, 0xe6, 0x3d, 0xf9, 0x8a, 0xf2, 0xd9, 0x29, 0xa3,
+ 0x03, 0xa8, 0x47, 0xc4, 0xec, 0x8b, 0xb2, 0xcc, 0x31, 0x46, 0x9f, 0xe9,
+ 0x94, 0x09, 0xe8, 0xb5, 0x23, 0x95, 0x71, 0xf9, 0x72, 0xa5, 0x4b, 0xe1,
+ 0x86, 0xbf, 0xf6, 0xd3, 0x89, 0x61, 0x2b, 0x90, 0x07, 0x81, 0x7f, 0x66,
+ 0xfa, 0xdb, 0xe4, 0xcd, 0x51, 0x9d, 0xfb, 0x7b, 0x83, 0xc9, 0x8d, 0x2e,
+ 0xf3, 0x55, 0x39, 0x1f, 0xe8, 0x7d, 0x0b, 0xbe, 0x80, 0xd5, 0x2e, 0x33,
+ 0xf1, 0x2e, 0xf9, 0xb8, 0x8f, 0xf2, 0x36, 0x5f, 0x7d, 0x63, 0x9c, 0x8b,
+ 0x37, 0xeb, 0x91, 0x37, 0xcd, 0xd8, 0x5f, 0x34, 0xe5, 0xbf, 0xe9, 0x6d,
+ 0xa2, 0xc5, 0x9a, 0xcb, 0x44, 0xd4, 0xfc, 0xe6, 0x6b, 0xd4, 0x6f, 0x6c,
+ 0x03, 0x7d, 0xd2, 0xe0, 0x39, 0x51, 0x59, 0xd6, 0xa0, 0x5f, 0x4a, 0x55,
+ 0xb1, 0xce, 0x65, 0x80, 0xa8, 0x3d, 0x8d, 0x3f, 0x4b, 0x90, 0xaf, 0xd9,
+ 0xaa, 0x8a, 0x59, 0xaa, 0xbc, 0xed, 0x59, 0x60, 0x5d, 0xf8, 0xc4, 0xc0,
+ 0x10, 0x26, 0x7f, 0xa5, 0x93, 0xf1, 0x90, 0x66, 0x1d, 0x16, 0xfe, 0x2f,
+ 0x9d, 0xff, 0xd4, 0x2b, 0xdd, 0x65, 0xac, 0x4b, 0x88, 0xb9, 0xc1, 0x53,
+ 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x73, 0xbe, 0x78,
+ 0x88, 0x39, 0xb8, 0x67, 0x69, 0x2f, 0xa4, 0x1c, 0x03, 0xa6, 0xed, 0x38,
+ 0x03, 0xdb, 0x5d, 0xcd, 0x42, 0x56, 0xc6, 0x55, 0xde, 0xe7, 0x3c, 0xb0,
+ 0xdb, 0x1f, 0xf8, 0x7f, 0x2a, 0xf6, 0xd3, 0x07, 0x64, 0xad, 0xda, 0x01,
+ 0x7e, 0xd0, 0x2e, 0x44, 0x95, 0x7f, 0x7d, 0xe3, 0x28, 0xed, 0x1d, 0x6d,
+ 0x89, 0x5e, 0x8b, 0xad, 0xda, 0xf7, 0x7a, 0xf5, 0xb7, 0x33, 0x7b, 0x65,
+ 0xb3, 0x16, 0xda, 0x42, 0xf8, 0x87, 0xd5, 0xa8, 0xb1, 0xcb, 0x9d, 0xd0,
+ 0xdd, 0xdf, 0x8f, 0xd6, 0x95, 0xaf, 0xce, 0xf9, 0xd3, 0x06, 0x45, 0x99,
+ 0x17, 0xd7, 0x59, 0xf7, 0x38, 0xf7, 0x66, 0x1b, 0xa4, 0x71, 0x87, 0x7b,
+ 0x90, 0xe3, 0x31, 0x87, 0x82, 0x73, 0x8c, 0x4b, 0xf4, 0xfc, 0x63, 0x62,
+ 0xc3, 0x6f, 0x89, 0x2c, 0x11, 0xeb, 0xdd, 0xec, 0xbb, 0x44, 0x2e, 0xba,
+ 0xe6, 0x5b, 0xec, 0x41, 0x8d, 0x65, 0x32, 0x28, 0xeb, 0xe1, 0xf7, 0xd9,
+ 0xfc, 0x35, 0xdb, 0xcd, 0xd0, 0xb7, 0xd8, 0xd5, 0x96, 0xe2, 0xef, 0xff,
+ 0x01, 0x37, 0x64, 0x26, 0x2b, 0x1c, 0x4c, 0x00, 0x00, 0x00 };
static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e94, 0x08000eec,
- 0x08000f30, 0x08000fc4, 0x08001008, 0x80080100, 0x80080080, 0x80080000,
+ 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e20, 0x08000e78,
+ 0x08000ebc, 0x08000f50, 0x08000f94, 0x80080100, 0x80080080, 0x80080000,
0x00000000 };
static struct fw_info bnx2_com_fw_09 = {
- /* Firmware version: 4.0.5 */
+ /* Firmware version: 4.4.23 */
.ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
+ .ver_minor = 0x4,
+ .ver_fix = 0x17,
.start_addr = 0x080000f8,
.text_addr = 0x08000000,
- .text_len = 0x4b40,
+ .text_len = 0x4c18,
.text_index = 0x0,
.gz_text = bnx2_COM_b09FwText,
.gz_text_len = sizeof(bnx2_COM_b09FwText),
@@ -860,1202 +866,1210 @@ static struct fw_info bnx2_com_fw_09 = {
.data_index = 0x0,
.data = bnx2_COM_b09FwData,
- .sbss_addr = 0x08004ba0,
+ .sbss_addr = 0x08004c60,
.sbss_len = 0x38,
.sbss_index = 0x0,
- .bss_addr = 0x08004bd8,
+ .bss_addr = 0x08004c98,
.bss_len = 0xbc,
.bss_index = 0x0,
- .rodata_addr = 0x08004b40,
+ .rodata_addr = 0x08004c18,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_COM_b09FwRodata,
};
static u8 bnx2_CP_b09FwText[] = {
- 0xad, 0xbc, 0x0f, 0x74, 0x53, 0xd7, 0x95, 0x2e, 0xfe, 0xdd, 0x2b, 0xc9,
- 0x96, 0x6d, 0xd9, 0x96, 0x8d, 0x70, 0xe4, 0xc4, 0x0d, 0x52, 0x7c, 0x05,
- 0x0a, 0x36, 0xe9, 0x95, 0x11, 0x89, 0xd3, 0x77, 0x13, 0x54, 0x70, 0x82,
- 0x49, 0x68, 0xe2, 0x10, 0xa6, 0x75, 0x67, 0x98, 0xa9, 0x1e, 0x21, 0x09,
- 0x49, 0x99, 0x3c, 0xb7, 0xaf, 0xed, 0x23, 0xf9, 0xd1, 0xf1, 0xad, 0xcd,
- 0x1f, 0x03, 0x92, 0x25, 0x1b, 0xf3, 0x27, 0x6f, 0xba, 0x5e, 0x84, 0x31,
- 0x18, 0x12, 0xd9, 0x4e, 0xda, 0x4c, 0x87, 0xbc, 0xd5, 0x79, 0x78, 0x0c,
- 0x24, 0x90, 0x34, 0x7f, 0x9a, 0xb4, 0xab, 0x69, 0xa7, 0x6f, 0xe2, 0x12,
- 0x92, 0x92, 0x7f, 0x94, 0x34, 0x9d, 0x0e, 0x74, 0x86, 0xde, 0xdf, 0xb7,
- 0xaf, 0x24, 0x30, 0x94, 0xa4, 0xed, 0x5a, 0xcf, 0x6b, 0x69, 0x49, 0xf7,
- 0xde, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0xce,
- 0xf5, 0xa7, 0x80, 0x52, 0xe4, 0xff, 0xca, 0xf9, 0xb9, 0x2e, 0xda, 0x71,
- 0x0f, 0xe6, 0x5d, 0xa7, 0xcb, 0xb5, 0xd3, 0x05, 0x27, 0xfe, 0xc4, 0xbf,
- 0xc0, 0x9f, 0x5a, 0x30, 0xff, 0xe7, 0x00, 0xbc, 0x85, 0x36, 0xe5, 0x03,
- 0xb7, 0x6a, 0xac, 0xfb, 0xe2, 0x02, 0x0d, 0x6e, 0x87, 0x11, 0x5d, 0x7e,
- 0x8f, 0x06, 0xc4, 0xb2, 0x0d, 0x81, 0x85, 0x38, 0x67, 0x99, 0x3e, 0x27,
- 0xe4, 0xfe, 0xa7, 0x8c, 0xff, 0x7c, 0xec, 0x9f, 0x6e, 0x08, 0x9e, 0xce,
- 0x38, 0xe0, 0xf6, 0x1a, 0x5f, 0x83, 0x77, 0x26, 0xdc, 0x75, 0xac, 0xf3,
- 0xed, 0x59, 0xb3, 0x55, 0x54, 0x14, 0x64, 0x05, 0xfd, 0x19, 0x04, 0xbd,
- 0x26, 0x82, 0x61, 0x13, 0x88, 0x3b, 0x0d, 0xc4, 0x8b, 0x0d, 0x37, 0x8a,
- 0xb4, 0x22, 0xc4, 0xbd, 0x6b, 0x02, 0xeb, 0xa2, 0xc0, 0x82, 0x84, 0x3b,
- 0x70, 0x3c, 0x0b, 0xdc, 0x93, 0x70, 0x63, 0xd2, 0xe1, 0x09, 0xbc, 0x99,
- 0xbd, 0xb9, 0x32, 0xa7, 0x83, 0x18, 0x1c, 0x1a, 0xe2, 0xaa, 0x21, 0xf7,
- 0x11, 0x58, 0x98, 0x8d, 0x62, 0x7d, 0xca, 0xb2, 0x9c, 0x1a, 0x9c, 0x83,
- 0x8d, 0x0e, 0xc4, 0xbc, 0x0a, 0x76, 0x6b, 0x51, 0x74, 0x8f, 0x05, 0x39,
- 0x58, 0x29, 0x23, 0xed, 0xfc, 0xe6, 0xdc, 0xc6, 0xd4, 0x49, 0xeb, 0x9f,
- 0x66, 0x79, 0xf1, 0xe4, 0x98, 0x0f, 0x07, 0xc7, 0x82, 0xa6, 0x89, 0x2a,
- 0x9c, 0x48, 0x37, 0xe2, 0xa4, 0x56, 0x87, 0x37, 0x35, 0x0b, 0xeb, 0xf5,
- 0x30, 0x54, 0x2d, 0xa8, 0x43, 0xf1, 0x63, 0xd0, 0x1b, 0x0c, 0xc4, 0xc1,
- 0x4e, 0x54, 0x04, 0xc3, 0xe3, 0xac, 0x9b, 0x4a, 0x21, 0x5e, 0x64, 0x38,
- 0x51, 0xa2, 0xdd, 0x8c, 0x53, 0xdb, 0x0c, 0x7c, 0xb0, 0x0d, 0xcb, 0x2b,
- 0x60, 0x59, 0xd9, 0x48, 0xa8, 0x6d, 0xb5, 0xe2, 0x0d, 0x3c, 0x9f, 0x45,
- 0xe0, 0x58, 0x76, 0xaa, 0xde, 0x38, 0x21, 0xd5, 0x6c, 0x27, 0x15, 0xc5,
- 0x4e, 0xf6, 0xcd, 0x3b, 0x2b, 0x8a, 0xf4, 0x18, 0xdb, 0x4e, 0x49, 0x7f,
- 0xfc, 0xf8, 0xa7, 0x59, 0x7f, 0xcd, 0xf9, 0x64, 0x5b, 0x94, 0xbd, 0x21,
- 0xf5, 0x3a, 0xfb, 0x55, 0x87, 0xef, 0x8e, 0xf9, 0xf1, 0x1d, 0xf6, 0xed,
- 0x29, 0x29, 0x37, 0x16, 0x60, 0x1f, 0xab, 0x70, 0x84, 0xfd, 0xfb, 0x21,
- 0xfb, 0xf7, 0x0a, 0xfb, 0xb7, 0x9b, 0xfd, 0x5b, 0xd1, 0x1c, 0xdc, 0x69,
- 0x42, 0xc1, 0xd2, 0xc6, 0x36, 0xe9, 0x1b, 0xc7, 0xc7, 0x8f, 0xaa, 0x22,
- 0x56, 0x1d, 0x0c, 0x07, 0xd4, 0x60, 0x18, 0x76, 0x9f, 0xa5, 0xfd, 0xdf,
- 0x9c, 0x4b, 0xa6, 0x60, 0xba, 0xa9, 0x57, 0x97, 0x71, 0x33, 0xb2, 0xec,
- 0xf3, 0x13, 0xdb, 0x42, 0xcd, 0xab, 0x54, 0x2c, 0xf1, 0xb0, 0xdf, 0x0f,
- 0x46, 0x42, 0x81, 0xd9, 0xec, 0xf7, 0x50, 0x56, 0x55, 0x55, 0xcd, 0x17,
- 0x18, 0xce, 0x2a, 0x88, 0x2d, 0x55, 0x39, 0x7e, 0xb6, 0x9b, 0x62, 0x5f,
- 0x52, 0xec, 0x4b, 0x8a, 0x7d, 0x49, 0x49, 0x9f, 0xc3, 0xec, 0x6f, 0x4e,
- 0xd7, 0x83, 0xd9, 0xcb, 0xf5, 0x35, 0xd8, 0xc3, 0xb9, 0xa4, 0x3e, 0xa5,
- 0xcf, 0x96, 0xf5, 0xaa, 0xbe, 0x88, 0x7d, 0xb0, 0xac, 0x8f, 0x74, 0xe9,
- 0x9b, 0xf4, 0xab, 0x1c, 0x31, 0x5f, 0x8a, 0x73, 0x56, 0xe8, 0x1b, 0x8c,
- 0x6a, 0xcc, 0x30, 0x5d, 0x86, 0xcc, 0xbb, 0xca, 0xfb, 0x21, 0xfd, 0x23,
- 0xc0, 0x1a, 0x8c, 0x7a, 0x03, 0x1b, 0xb2, 0xbe, 0x40, 0x17, 0x75, 0xd9,
- 0x9d, 0x0d, 0xfa, 0xc5, 0x56, 0xff, 0xb0, 0x2f, 0x41, 0x6f, 0xdc, 0x9e,
- 0x53, 0xe9, 0xd3, 0x64, 0x7e, 0x3e, 0x2d, 0xeb, 0x15, 0xdd, 0xcf, 0xb6,
- 0xa5, 0x3f, 0x51, 0xbb, 0xed, 0x0f, 0x75, 0x44, 0xbd, 0x10, 0xbb, 0x08,
- 0x99, 0x3f, 0xb4, 0xed, 0xcb, 0x1b, 0x48, 0x67, 0x59, 0xe6, 0xbc, 0x1c,
- 0x27, 0xc7, 0x0a, 0xb6, 0x65, 0x59, 0xbb, 0xb5, 0xa0, 0x57, 0xda, 0xca,
- 0x8d, 0x51, 0xec, 0x46, 0xec, 0xc4, 0x1f, 0xf7, 0x18, 0x5e, 0xca, 0x44,
- 0xdb, 0xce, 0x64, 0xa7, 0x55, 0xab, 0x89, 0x2e, 0xb5, 0x35, 0xb5, 0x0e,
- 0x4f, 0xf3, 0xa9, 0x79, 0x5f, 0x31, 0xcb, 0xa3, 0x11, 0x94, 0x6a, 0xf0,
- 0x94, 0x68, 0x68, 0xeb, 0x1d, 0x29, 0x35, 0xcb, 0x8c, 0xef, 0xdf, 0x9d,
- 0x1c, 0x71, 0xa3, 0x74, 0x44, 0x43, 0xc9, 0x48, 0xc8, 0x89, 0x0a, 0x03,
- 0x5b, 0xc6, 0xde, 0x71, 0xe4, 0xc6, 0xbb, 0xb0, 0x30, 0x6e, 0xb1, 0x71,
- 0xf7, 0x5b, 0x89, 0xd3, 0x56, 0x91, 0x56, 0xf2, 0x05, 0x87, 0xa1, 0x05,
- 0xf6, 0x02, 0xa7, 0x57, 0x44, 0xfd, 0xe8, 0xa2, 0xcd, 0xce, 0xd0, 0x7e,
- 0xe2, 0x41, 0x45, 0x2b, 0xcc, 0xb1, 0x1a, 0xf1, 0x07, 0xac, 0x4f, 0x58,
- 0x56, 0x91, 0x71, 0xf7, 0xdd, 0x2c, 0xe7, 0xdd, 0x8b, 0x5a, 0x2c, 0xf4,
- 0x62, 0xed, 0xfa, 0xe8, 0xaf, 0x95, 0x7d, 0x03, 0xcb, 0x61, 0x0e, 0xaf,
- 0xe6, 0x47, 0x05, 0xaa, 0xae, 0xbe, 0xda, 0x71, 0xe3, 0x72, 0x74, 0x0f,
- 0xb3, 0xaf, 0xa9, 0x18, 0xed, 0x53, 0x6c, 0x6b, 0x35, 0x36, 0x0d, 0x3f,
- 0x04, 0x73, 0xf7, 0x4a, 0x96, 0x91, 0x31, 0x75, 0xf1, 0xbb, 0x15, 0x8f,
- 0x8d, 0x89, 0x7c, 0xe9, 0xc6, 0xe5, 0xe4, 0xbf, 0x63, 0x2d, 0xf4, 0x89,
- 0x7c, 0x27, 0x36, 0x26, 0xec, 0x79, 0x51, 0x68, 0x9f, 0xe1, 0x13, 0xb4,
- 0x95, 0x6e, 0xdd, 0x40, 0x4f, 0xaa, 0x19, 0x1b, 0x53, 0xb1, 0x20, 0xd1,
- 0x80, 0xf3, 0xd6, 0x06, 0xd5, 0x08, 0xb5, 0x76, 0x41, 0x7c, 0x02, 0x4a,
- 0xa9, 0x01, 0x67, 0x36, 0x3a, 0xe9, 0x7e, 0x31, 0xa1, 0xb5, 0x3f, 0xae,
- 0xb8, 0x10, 0xaf, 0x92, 0x36, 0x26, 0xdd, 0x2f, 0x27, 0x14, 0xfc, 0x52,
- 0x0b, 0x75, 0xbc, 0xab, 0x4c, 0xba, 0x5f, 0xca, 0x7a, 0x51, 0x9b, 0x0c,
- 0xb6, 0x9b, 0x4a, 0x33, 0x9e, 0xc9, 0xfa, 0xe0, 0x4f, 0x1a, 0x38, 0x90,
- 0xd5, 0xb1, 0xff, 0x22, 0x9f, 0xb9, 0xec, 0x9f, 0xe9, 0x60, 0x5f, 0x57,
- 0x26, 0x02, 0xe8, 0xd2, 0xcf, 0x59, 0x31, 0x2f, 0xe2, 0x95, 0xc6, 0xa4,
- 0xfb, 0x83, 0x24, 0x94, 0x0a, 0x43, 0xf3, 0x8f, 0x2a, 0xbf, 0xb0, 0xe2,
- 0x3e, 0x29, 0xc6, 0xfe, 0x8d, 0xc9, 0x58, 0x97, 0x50, 0xef, 0x06, 0xe7,
- 0xfd, 0xb4, 0x55, 0xc6, 0x39, 0x2b, 0x32, 0xae, 0xc4, 0xf0, 0x80, 0x86,
- 0xfd, 0x1c, 0xeb, 0xfb, 0xfa, 0x78, 0xb3, 0x07, 0x5a, 0xdb, 0x7b, 0x08,
- 0xc6, 0x66, 0x2b, 0x06, 0x8e, 0x66, 0x35, 0x0c, 0x25, 0x0c, 0x1c, 0x4a,
- 0xd4, 0x7b, 0xbb, 0x31, 0x17, 0x31, 0x7f, 0x0e, 0x1f, 0x47, 0xd8, 0xef,
- 0xc1, 0x50, 0x1b, 0x2a, 0x8d, 0x66, 0x4c, 0xb0, 0xdf, 0xa7, 0xe6, 0x89,
- 0x1c, 0x1d, 0x2f, 0xfd, 0x09, 0x7d, 0x15, 0xbd, 0x3e, 0xca, 0xbe, 0x36,
- 0xcf, 0x3d, 0x67, 0x61, 0x9a, 0x1b, 0xc7, 0xf5, 0x2b, 0x88, 0x47, 0x30,
- 0x4b, 0x0c, 0xb7, 0xb3, 0x27, 0xe1, 0xc5, 0xbe, 0xac, 0xc7, 0xd9, 0x9d,
- 0xf0, 0x61, 0x77, 0x36, 0x80, 0x5a, 0x03, 0xa6, 0x9f, 0x72, 0x6b, 0xe9,
- 0x4b, 0xa3, 0x03, 0x75, 0x18, 0x1b, 0x08, 0xea, 0x2f, 0x13, 0x7b, 0xf6,
- 0x0e, 0x5d, 0x89, 0x91, 0x01, 0x05, 0xc3, 0x21, 0xf6, 0x9d, 0xbf, 0x9f,
- 0x18, 0xb8, 0x1a, 0xd9, 0x01, 0x07, 0xb6, 0xd8, 0x7a, 0xb5, 0xfd, 0x30,
- 0xff, 0x7d, 0x25, 0x32, 0x43, 0x70, 0xce, 0x4e, 0x7a, 0xf1, 0x78, 0xd6,
- 0xe9, 0xd4, 0x92, 0x3e, 0x0c, 0x65, 0xbf, 0xce, 0x79, 0x13, 0xd9, 0x01,
- 0x0c, 0x26, 0xfe, 0x9a, 0xbf, 0x65, 0x1c, 0xb7, 0x2b, 0xf9, 0xd8, 0x41,
- 0xcc, 0x0e, 0x10, 0x4f, 0x5b, 0xd0, 0x95, 0x72, 0x60, 0x85, 0x8d, 0xeb,
- 0x29, 0x3e, 0x6b, 0xa1, 0xcd, 0x17, 0xe4, 0x0a, 0xbe, 0x07, 0x88, 0xbd,
- 0x47, 0xe9, 0x03, 0x51, 0xda, 0xbf, 0x8e, 0xff, 0x33, 0xd6, 0x88, 0x7f,
- 0x1c, 0x0b, 0xe3, 0x7b, 0x63, 0x1a, 0xfe, 0x81, 0xb8, 0xf4, 0xf4, 0xd8,
- 0x54, 0xff, 0xbf, 0x9b, 0xe3, 0x13, 0x1f, 0x34, 0xb0, 0x2e, 0x55, 0x84,
- 0x0d, 0x03, 0xa5, 0xe8, 0x1e, 0xa8, 0x0f, 0x1f, 0xa2, 0xdd, 0x7c, 0x4f,
- 0xff, 0x1c, 0xc6, 0xab, 0x29, 0x83, 0xfe, 0xbb, 0x89, 0xf7, 0x37, 0x0f,
- 0xd4, 0x53, 0xef, 0x96, 0xa5, 0x46, 0x1a, 0x9a, 0x27, 0x88, 0x59, 0x93,
- 0xbe, 0x60, 0x60, 0x5c, 0x0d, 0x06, 0x62, 0x70, 0x21, 0xd1, 0xa8, 0xc2,
- 0x9c, 0x1e, 0xcc, 0x98, 0xc4, 0x4d, 0x9f, 0x76, 0xb5, 0x22, 0xd8, 0x66,
- 0xaa, 0x06, 0x6d, 0x8e, 0x78, 0xa7, 0xc6, 0xe8, 0x13, 0xa5, 0xf8, 0x60,
- 0x20, 0xd8, 0x63, 0xaa, 0x77, 0xc1, 0xac, 0xb6, 0xac, 0xef, 0x44, 0xd0,
- 0x71, 0x85, 0x81, 0xd8, 0x74, 0x62, 0xc8, 0xd5, 0xc6, 0x12, 0x10, 0x9f,
- 0x71, 0x2a, 0xa9, 0xf9, 0x7f, 0xa2, 0xdc, 0x8d, 0xaf, 0xb7, 0x05, 0x03,
- 0x01, 0xb5, 0xc1, 0xdc, 0xad, 0x36, 0xd3, 0xd4, 0x11, 0xf0, 0x1b, 0xb7,
- 0x61, 0x8d, 0x3d, 0x56, 0x05, 0x5e, 0x2d, 0x86, 0xee, 0x14, 0x2b, 0xf9,
- 0xea, 0xdb, 0xfb, 0xd4, 0xfa, 0x33, 0xba, 0x1a, 0x3c, 0xda, 0xa6, 0x12,
- 0x2f, 0xe6, 0x9e, 0xb2, 0x02, 0x35, 0x96, 0xd5, 0x34, 0x57, 0xda, 0x0c,
- 0xa0, 0x9a, 0x73, 0x53, 0xc5, 0xb9, 0x69, 0x1a, 0x2d, 0xc5, 0xbb, 0x03,
- 0x30, 0xaf, 0x30, 0x82, 0xad, 0x0f, 0xaa, 0xa5, 0x78, 0x67, 0xa8, 0x14,
- 0x6f, 0x0e, 0x38, 0x71, 0x72, 0xc0, 0xb2, 0xee, 0xd5, 0x2b, 0x51, 0x14,
- 0xc1, 0xf4, 0x22, 0x84, 0x4e, 0x0f, 0xc2, 0xc4, 0xef, 0x59, 0xf6, 0x37,
- 0x03, 0x7e, 0xfc, 0xdb, 0xc0, 0x67, 0xf0, 0x74, 0x75, 0xec, 0xd8, 0x34,
- 0xf8, 0x70, 0x86, 0x73, 0x7e, 0x2a, 0x11, 0x6c, 0xaf, 0x75, 0x04, 0xd7,
- 0x00, 0x0d, 0xab, 0x1e, 0x56, 0x82, 0xf1, 0x97, 0x95, 0x60, 0x20, 0xa9,
- 0xf8, 0xf0, 0x1e, 0x6d, 0xeb, 0x44, 0xb6, 0xbe, 0xf9, 0x35, 0xb6, 0xff,
- 0x5b, 0xfd, 0x7b, 0xd6, 0x78, 0x8d, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xa7,
- 0xa8, 0x73, 0xe2, 0xee, 0xf7, 0x52, 0xd4, 0x39, 0xfb, 0xf3, 0xf4, 0x1f,
- 0xe0, 0xa0, 0xcc, 0x57, 0x33, 0x7d, 0xfd, 0x2a, 0xfc, 0x9d, 0x3d, 0xb6,
- 0x63, 0xd6, 0xff, 0xf0, 0xc9, 0xf8, 0x7e, 0x34, 0x3d, 0xe7, 0xe3, 0x32,
- 0xce, 0xa3, 0x56, 0xdc, 0x2b, 0x63, 0x94, 0xb1, 0xda, 0xba, 0x0c, 0x74,
- 0x28, 0xd3, 0x55, 0x94, 0x5a, 0xd6, 0x56, 0x3d, 0xff, 0xdc, 0x57, 0x18,
- 0xeb, 0xbf, 0xd2, 0x0e, 0x64, 0xbc, 0x6b, 0x1d, 0xa2, 0xfb, 0x80, 0xfa,
- 0xaa, 0xf8, 0xbf, 0x19, 0x43, 0xb9, 0x47, 0x62, 0x60, 0xec, 0xfc, 0xf5,
- 0x53, 0x15, 0x17, 0x3f, 0xa7, 0x6d, 0xd9, 0xed, 0xfd, 0x3b, 0xaf, 0x65,
- 0x2c, 0xaf, 0xd0, 0x6e, 0xc4, 0x4e, 0x38, 0x9d, 0x86, 0xd8, 0xcc, 0xa5,
- 0xf6, 0x22, 0xb6, 0xd2, 0x48, 0xbb, 0xfa, 0x17, 0x62, 0x62, 0x07, 0x9e,
- 0xbc, 0xde, 0x2d, 0xd3, 0x1c, 0x70, 0x18, 0x26, 0x3e, 0x1f, 0x75, 0xe0,
- 0xab, 0x51, 0x05, 0xd3, 0xb4, 0x60, 0x06, 0xaa, 0x69, 0x55, 0x91, 0x5b,
- 0x6c, 0xe8, 0x4d, 0x63, 0xc3, 0x18, 0x50, 0xd9, 0x0b, 0x77, 0x85, 0x61,
- 0xe0, 0xa5, 0x24, 0xdc, 0x65, 0xf4, 0xcb, 0x2f, 0x27, 0xeb, 0xc7, 0xdf,
- 0x56, 0x82, 0xb1, 0xd7, 0xa9, 0x4f, 0xea, 0xb5, 0xcd, 0xaf, 0x04, 0x5b,
- 0x57, 0x2b, 0xc1, 0xe6, 0xd9, 0x0a, 0xdc, 0x0a, 0xcb, 0x85, 0xb3, 0x69,
- 0xa4, 0xc6, 0xe4, 0x77, 0x33, 0x66, 0x65, 0xfb, 0xf2, 0x7d, 0x14, 0x3f,
- 0x06, 0x8e, 0xd0, 0xbf, 0x87, 0x9a, 0x15, 0xe2, 0xc9, 0x3b, 0x56, 0xcc,
- 0x47, 0xf9, 0x29, 0xb8, 0x4b, 0x59, 0xe7, 0xb6, 0x64, 0x1a, 0x8c, 0x99,
- 0xee, 0x12, 0xd6, 0xb9, 0x36, 0x09, 0x78, 0x7a, 0x05, 0xf3, 0x83, 0x81,
- 0x6b, 0x94, 0xfa, 0xf6, 0xa4, 0x12, 0x0c, 0xdf, 0xae, 0x34, 0xe8, 0x4f,
- 0x90, 0xb7, 0x6c, 0x40, 0xae, 0x8d, 0x50, 0x36, 0x27, 0xbf, 0x3e, 0x0b,
- 0x65, 0x46, 0x12, 0x9e, 0x5a, 0x6d, 0x26, 0xce, 0x4e, 0xb3, 0xdb, 0x51,
- 0x2a, 0x93, 0x01, 0x3b, 0x96, 0x56, 0x8e, 0x00, 0x2f, 0xf5, 0x5b, 0x38,
- 0x14, 0xa9, 0xa7, 0xbf, 0xb5, 0xc1, 0xcf, 0x32, 0x39, 0x5b, 0xb4, 0xb1,
- 0x42, 0xe9, 0x49, 0xd0, 0xe9, 0xa6, 0xcb, 0xa5, 0x0f, 0xf1, 0xcf, 0x23,
- 0x26, 0xf7, 0x76, 0x26, 0xa0, 0xf4, 0x26, 0x82, 0x3b, 0x01, 0x6d, 0x4d,
- 0x95, 0x23, 0xf6, 0x40, 0x25, 0x3a, 0x31, 0x11, 0x09, 0xc5, 0x07, 0x95,
- 0x50, 0x7b, 0xbf, 0xa2, 0xbb, 0xb7, 0xb0, 0xbd, 0xcd, 0x2c, 0xb3, 0x81,
- 0x9f, 0x45, 0x21, 0xad, 0xf5, 0x43, 0xc4, 0xae, 0x2d, 0x61, 0x99, 0x43,
- 0x7a, 0xe8, 0xcc, 0x6e, 0x84, 0x8e, 0xfe, 0xda, 0xa1, 0xbb, 0x1f, 0xcd,
- 0x8a, 0xac, 0x66, 0x65, 0x68, 0xf4, 0x26, 0x35, 0xe7, 0xfb, 0xff, 0x33,
- 0xaf, 0x83, 0xaf, 0xcb, 0xb5, 0xdd, 0xb6, 0x33, 0x79, 0xb4, 0xf4, 0x0f,
- 0xef, 0x71, 0x92, 0x2e, 0xba, 0xd7, 0xe0, 0x1d, 0xa2, 0xdf, 0x38, 0xb4,
- 0x12, 0xfa, 0xb9, 0xf0, 0x95, 0x58, 0xd8, 0x05, 0xb9, 0xe7, 0x40, 0xc6,
- 0x19, 0xf3, 0x3b, 0xf0, 0x9f, 0x56, 0x6c, 0x99, 0xdc, 0x2b, 0x45, 0xbc,
- 0xad, 0xc1, 0xef, 0x44, 0x43, 0xf3, 0x7a, 0xfa, 0xf0, 0xe4, 0xb2, 0x05,
- 0x7c, 0x16, 0xd2, 0x0f, 0xa1, 0x3e, 0xb0, 0x1e, 0xf2, 0xfb, 0x2c, 0x6d,
- 0x6d, 0x81, 0xd4, 0x65, 0x99, 0x1c, 0x27, 0x13, 0x8c, 0x58, 0xa7, 0x5b,
- 0x78, 0x56, 0x87, 0x59, 0x6c, 0x1c, 0x50, 0x8e, 0x27, 0x7e, 0x6f, 0xc5,
- 0x9c, 0x58, 0x42, 0x7f, 0xd2, 0x35, 0x05, 0x01, 0xb7, 0x11, 0x0a, 0x1c,
- 0x25, 0xfb, 0xa4, 0x6d, 0x28, 0x93, 0xd9, 0x75, 0xca, 0x5b, 0xd9, 0x1e,
- 0xe5, 0x44, 0x56, 0xea, 0x1e, 0x50, 0xde, 0xcc, 0x4a, 0xec, 0xa9, 0x0b,
- 0x1c, 0x61, 0x2c, 0x65, 0x1c, 0x57, 0xbb, 0xc9, 0xda, 0x36, 0xe8, 0x15,
- 0xe4, 0x8e, 0x5a, 0x78, 0x90, 0xfd, 0xdd, 0x13, 0x85, 0xbe, 0x51, 0x77,
- 0x61, 0xd2, 0x0b, 0x4f, 0xb7, 0xee, 0x94, 0x6b, 0xc6, 0x34, 0xa9, 0x5b,
- 0x17, 0x58, 0x9f, 0x3d, 0x47, 0xbf, 0xc8, 0x5d, 0xef, 0x89, 0x16, 0xee,
- 0x7d, 0x64, 0x8d, 0x2f, 0x53, 0x79, 0xfd, 0xa2, 0x8c, 0x9b, 0x75, 0xa7,
- 0x72, 0x45, 0x89, 0xdb, 0x2a, 0xb9, 0x69, 0x15, 0x4c, 0x6f, 0xd0, 0xcc,
- 0x60, 0x09, 0x7d, 0xe7, 0x30, 0xb9, 0xac, 0x9f, 0x71, 0x69, 0x09, 0xb1,
- 0x54, 0x78, 0x98, 0xc2, 0xe7, 0x1e, 0xdc, 0x92, 0xf8, 0x87, 0x3c, 0xc7,
- 0x65, 0x6c, 0xae, 0x71, 0x08, 0x9f, 0xf4, 0xca, 0xdc, 0x1e, 0x4c, 0x4d,
- 0xe5, 0x7e, 0x75, 0x81, 0x93, 0xec, 0x77, 0x89, 0xa6, 0x85, 0x4b, 0x94,
- 0xba, 0xc0, 0x5b, 0xd9, 0x25, 0xf4, 0xcd, 0x77, 0xd9, 0xae, 0x07, 0x6f,
- 0x25, 0x2a, 0xc8, 0x6b, 0x83, 0x31, 0x93, 0x02, 0x6f, 0x25, 0x2f, 0x20,
- 0xbf, 0x98, 0xf2, 0xd7, 0x06, 0xc6, 0x5a, 0x89, 0x87, 0xea, 0xa2, 0x79,
- 0xcd, 0x58, 0x95, 0x85, 0x73, 0x65, 0xd4, 0xc0, 0xbd, 0x8c, 0xa3, 0xf7,
- 0x33, 0x36, 0xad, 0x66, 0xdc, 0xd9, 0x12, 0xe1, 0xd8, 0xaa, 0x2c, 0xab,
- 0x58, 0xeb, 0x14, 0x8e, 0x8c, 0x24, 0xe3, 0xde, 0x3d, 0x9a, 0x13, 0xeb,
- 0xf8, 0xfb, 0xc5, 0xec, 0x7f, 0x58, 0xf7, 0x93, 0xa3, 0x3f, 0x7b, 0x91,
- 0x4c, 0xa8, 0x43, 0x5a, 0x43, 0x78, 0x3d, 0xe3, 0x1e, 0xe5, 0x9a, 0x15,
- 0x86, 0x65, 0x5d, 0x1b, 0x0a, 0xc6, 0x5c, 0x8a, 0x8e, 0x43, 0x23, 0x93,
- 0x56, 0x60, 0xba, 0xf0, 0xf3, 0x42, 0x6c, 0x90, 0xb1, 0x16, 0xf8, 0x9f,
- 0x70, 0xbd, 0xa9, 0x3e, 0xad, 0xe2, 0xd6, 0x01, 0xe1, 0xa6, 0x7e, 0x2c,
- 0x4d, 0x7c, 0x0b, 0x87, 0x1a, 0x9d, 0x68, 0x25, 0x6f, 0x5f, 0x94, 0xf0,
- 0xe0, 0x2e, 0x62, 0xe0, 0xe2, 0x44, 0x31, 0xe7, 0xc6, 0x87, 0xdb, 0x12,
- 0x4e, 0x1c, 0x6e, 0x9c, 0x06, 0xd3, 0x57, 0x8c, 0xf7, 0x74, 0x07, 0x8e,
- 0xe8, 0x5e, 0x64, 0x6c, 0x7f, 0xd8, 0x42, 0xec, 0x0a, 0xe6, 0xf9, 0xa2,
- 0xe8, 0xd0, 0x41, 0x7d, 0xaa, 0x88, 0x9f, 0xd7, 0xe1, 0xe5, 0xb8, 0x60,
- 0x81, 0x07, 0x7e, 0x68, 0xc5, 0xa7, 0x4b, 0x7d, 0x98, 0x1e, 0x43, 0xc6,
- 0x21, 0x5c, 0x4a, 0x47, 0xf7, 0x48, 0x8c, 0x9c, 0x67, 0xea, 0x50, 0x4f,
- 0x93, 0xc7, 0x55, 0xe2, 0x75, 0x4d, 0x78, 0xdc, 0x2b, 0xf0, 0xd2, 0x77,
- 0x7b, 0x46, 0x42, 0x1d, 0xa7, 0x15, 0x07, 0x5e, 0xd4, 0x2a, 0xe2, 0x6e,
- 0xfa, 0xf4, 0xc6, 0x11, 0x38, 0xd7, 0xcf, 0xd3, 0xd1, 0x3b, 0xd2, 0xd5,
- 0x5c, 0x0e, 0x12, 0x9b, 0x79, 0x39, 0xfe, 0xf1, 0x65, 0xea, 0x76, 0x45,
- 0xc4, 0xe6, 0x1f, 0xb9, 0xd8, 0xeb, 0xb5, 0x2c, 0xe6, 0x0c, 0xd4, 0x33,
- 0xb0, 0x2f, 0xaf, 0xe3, 0x3d, 0xfc, 0xdd, 0x93, 0xd7, 0xf1, 0x3a, 0xca,
- 0xa3, 0xff, 0x61, 0xc3, 0x45, 0x9c, 0x21, 0x80, 0x62, 0x43, 0x30, 0x88,
- 0xf8, 0x49, 0x3c, 0x89, 0x51, 0xc7, 0xcf, 0x65, 0x7f, 0xc7, 0xb1, 0x06,
- 0x39, 0xdd, 0x62, 0x4f, 0x8c, 0x85, 0xea, 0x67, 0x1c, 0xc4, 0x55, 0xea,
- 0x41, 0xf4, 0x2c, 0xfa, 0xb5, 0xac, 0x7e, 0x5d, 0x74, 0x2c, 0xfa, 0x16,
- 0xbd, 0xe7, 0xf0, 0x93, 0x7c, 0xbf, 0x07, 0x48, 0xb3, 0xac, 0x83, 0x78,
- 0x69, 0xe0, 0xbb, 0x6d, 0x62, 0x3b, 0xe5, 0x76, 0x8c, 0x9b, 0x33, 0xd3,
- 0xb2, 0x9e, 0x8a, 0x04, 0xf0, 0xbe, 0xd6, 0xd0, 0xdc, 0xa4, 0x06, 0xd9,
- 0xd7, 0x25, 0x48, 0x8c, 0xc5, 0x38, 0x77, 0x57, 0x93, 0x87, 0x8b, 0xad,
- 0xa1, 0xa3, 0xc8, 0xc6, 0x5c, 0xe0, 0x44, 0x42, 0x0b, 0x6f, 0xe0, 0x9c,
- 0xed, 0xf6, 0x2d, 0x23, 0x67, 0x52, 0x5b, 0x98, 0xb5, 0x90, 0xab, 0x68,
- 0xe6, 0x26, 0xbc, 0x6b, 0x65, 0x7c, 0x16, 0xe3, 0x9b, 0x0a, 0xa7, 0x36,
- 0x03, 0x87, 0xbd, 0x0e, 0x3c, 0x1f, 0xae, 0x41, 0xac, 0x4a, 0x41, 0x99,
- 0xf6, 0x4b, 0xeb, 0x05, 0x9f, 0xb4, 0xc3, 0x7c, 0x43, 0xfd, 0x39, 0xfb,
- 0xad, 0xb0, 0x8c, 0xc8, 0x5d, 0x86, 0xae, 0xb1, 0x4b, 0xdb, 0xff, 0x85,
- 0x35, 0xe9, 0x93, 0xf6, 0x83, 0xde, 0x80, 0xfa, 0x49, 0x73, 0xf8, 0xaa,
- 0xf5, 0x5a, 0x4e, 0xa6, 0x1d, 0x7f, 0xa0, 0x8a, 0xbc, 0xc7, 0x39, 0x3e,
- 0x91, 0x59, 0x68, 0x47, 0xfc, 0x6c, 0x3f, 0xef, 0xc9, 0x33, 0xb1, 0x91,
- 0x75, 0x6c, 0xf7, 0x90, 0x85, 0x1a, 0xb9, 0xde, 0x6c, 0x97, 0x35, 0xc7,
- 0x26, 0x16, 0x3b, 0x31, 0x1f, 0xb3, 0x22, 0x0b, 0x16, 0xca, 0x58, 0x54,
- 0x23, 0x16, 0x70, 0xc3, 0xac, 0x71, 0x10, 0x8b, 0xdf, 0x6e, 0x6c, 0xc4,
- 0xc2, 0xec, 0xa4, 0xf5, 0x2e, 0xc1, 0xa5, 0x4b, 0x73, 0x60, 0x9c, 0xe3,
- 0xdb, 0xaf, 0x4b, 0x6e, 0x68, 0x61, 0x51, 0xc4, 0x8c, 0xd3, 0x63, 0xcd,
- 0x72, 0xda, 0x4e, 0xa9, 0x26, 0xf1, 0xb9, 0x02, 0x65, 0x86, 0x33, 0xfc,
- 0x2e, 0x82, 0xfa, 0x16, 0xf2, 0x93, 0x40, 0xd5, 0xac, 0x66, 0x17, 0xb5,
- 0xfb, 0x52, 0x22, 0xd4, 0x7c, 0x44, 0xc9, 0xf9, 0xc3, 0x73, 0x9c, 0xdb,
- 0xd7, 0x13, 0xda, 0x9a, 0x62, 0x47, 0xee, 0xfa, 0xe5, 0xac, 0xe4, 0x23,
- 0x05, 0x7f, 0xf0, 0xe7, 0x71, 0xc3, 0xed, 0x3e, 0x91, 0xc0, 0x69, 0x95,
- 0xf8, 0x53, 0x65, 0xe0, 0x74, 0xb7, 0x9e, 0x51, 0x5c, 0x5a, 0x05, 0x71,
- 0x55, 0xb0, 0xb4, 0x88, 0x31, 0x41, 0x62, 0xb6, 0xdb, 0xfd, 0x2e, 0xcb,
- 0x2c, 0x8e, 0x60, 0x32, 0x7c, 0x63, 0x43, 0xb3, 0x1b, 0x31, 0xb3, 0x98,
- 0x7e, 0x59, 0x6e, 0xf8, 0xdc, 0x73, 0x46, 0xcd, 0x1a, 0x0f, 0xed, 0xba,
- 0xcc, 0x40, 0xcb, 0xac, 0xde, 0xd6, 0x4a, 0x54, 0x34, 0x62, 0xf5, 0x88,
- 0xe4, 0x96, 0x7d, 0x35, 0x2a, 0xfb, 0xea, 0xd2, 0xca, 0xe1, 0xaa, 0x5e,
- 0x3d, 0x5f, 0x35, 0x7e, 0x80, 0xb6, 0xa8, 0xbb, 0x45, 0x1f, 0x9d, 0x9a,
- 0xe3, 0x08, 0x46, 0x9a, 0x35, 0x95, 0xc4, 0xc7, 0x0a, 0x43, 0xf2, 0x9b,
- 0x40, 0xcb, 0xcb, 0x36, 0x7e, 0x7a, 0xc9, 0xc7, 0x7f, 0xe6, 0xff, 0xf3,
- 0xeb, 0x3c, 0x4f, 0x1d, 0x4b, 0x9b, 0xf2, 0x2d, 0xb9, 0x26, 0x9c, 0xcc,
- 0x1d, 0xd1, 0x35, 0xec, 0x61, 0x7e, 0x21, 0x73, 0x03, 0x77, 0x91, 0x11,
- 0xfe, 0xcb, 0x67, 0xe9, 0x17, 0x2e, 0xea, 0x78, 0x93, 0x66, 0x12, 0xce,
- 0x2d, 0x4b, 0x8b, 0x04, 0xfd, 0x45, 0x4a, 0x00, 0x1b, 0x1b, 0x7f, 0x47,
- 0x5b, 0x00, 0xf1, 0x0a, 0x24, 0xab, 0x35, 0x58, 0x37, 0x5c, 0x31, 0xa5,
- 0xde, 0xbe, 0xf3, 0xf5, 0x92, 0x9a, 0x19, 0x97, 0x7a, 0x43, 0x91, 0x60,
- 0xfb, 0x06, 0xd6, 0xdb, 0xcc, 0x7a, 0x31, 0xc6, 0xc8, 0x7b, 0xe9, 0x9b,
- 0x2e, 0xe6, 0x37, 0xeb, 0x99, 0xeb, 0x4c, 0x69, 0xef, 0xaf, 0x0a, 0xf5,
- 0x1e, 0xd5, 0xcc, 0x71, 0xbb, 0xbd, 0xb9, 0xc1, 0x35, 0x45, 0x8e, 0x00,
- 0x7a, 0x59, 0x6f, 0x9c, 0xf5, 0xde, 0x1a, 0xa9, 0xce, 0x97, 0x77, 0x62,
- 0xc3, 0xac, 0x5c, 0xd9, 0x1e, 0xcd, 0xf4, 0x4b, 0x59, 0x67, 0x24, 0xd8,
- 0x7c, 0x1f, 0xb1, 0xba, 0x4b, 0xda, 0x60, 0xdf, 0xde, 0xb2, 0xe3, 0x0a,
- 0x6e, 0x7a, 0x21, 0x91, 0x9a, 0x74, 0x6a, 0x5a, 0xdb, 0x4a, 0x25, 0xa6,
- 0x2c, 0x9e, 0x67, 0xcf, 0xef, 0x4d, 0xc7, 0xb2, 0x9d, 0xd8, 0xa8, 0x4d,
- 0x44, 0x8a, 0x59, 0xef, 0x88, 0x36, 0xe1, 0x77, 0xd1, 0xd7, 0x56, 0xb2,
- 0xed, 0x2e, 0xe6, 0x15, 0x2a, 0x7d, 0x7b, 0xdd, 0xb0, 0xf0, 0x01, 0x9d,
- 0x7c, 0xa3, 0x8e, 0x76, 0x28, 0xfa, 0x91, 0x36, 0x65, 0x9e, 0x45, 0x17,
- 0xc1, 0xf0, 0xb0, 0xad, 0x0b, 0xa5, 0x7a, 0x5f, 0x23, 0x8d, 0xa5, 0x8a,
- 0xfc, 0xab, 0x51, 0x62, 0xa2, 0x42, 0x3c, 0xbe, 0x12, 0x1b, 0xec, 0x3c,
- 0xad, 0x8e, 0x5c, 0xc7, 0xb2, 0xf6, 0xe8, 0x96, 0xf5, 0xac, 0x3e, 0x03,
- 0xfb, 0xf4, 0x60, 0x5c, 0x6c, 0xf3, 0x97, 0xfa, 0x82, 0x6b, 0x5d, 0x08,
- 0x32, 0xe1, 0xff, 0x14, 0xc6, 0x69, 0x2f, 0x25, 0x9a, 0xf8, 0xa0, 0x02,
- 0x7f, 0xc8, 0x19, 0x28, 0x53, 0x2c, 0xb8, 0xe7, 0xce, 0x5c, 0x33, 0x93,
- 0x7a, 0xaa, 0xb8, 0x51, 0xc1, 0x07, 0x73, 0x14, 0x4c, 0xcc, 0x09, 0xf9,
- 0x07, 0x95, 0x72, 0xe2, 0x6d, 0xa8, 0xad, 0x45, 0x31, 0x8f, 0xb2, 0x6e,
- 0xac, 0xd1, 0xc1, 0x7c, 0x5a, 0xa9, 0x24, 0x16, 0xcc, 0x0a, 0x08, 0x1d,
- 0x70, 0x26, 0x43, 0xfe, 0xcd, 0xfc, 0x76, 0x8c, 0x28, 0x18, 0xd1, 0x82,
- 0x31, 0xd8, 0xf2, 0xd9, 0x76, 0x44, 0xc1, 0x75, 0x21, 0xcb, 0x3a, 0x16,
- 0x69, 0xf0, 0x1e, 0xc3, 0x2f, 0x2d, 0x59, 0x4b, 0xf1, 0x87, 0xce, 0xe7,
- 0x06, 0x28, 0x4d, 0x6a, 0xb1, 0x16, 0x65, 0xbb, 0x53, 0x38, 0xc5, 0xaa,
- 0xac, 0xc4, 0xc8, 0x42, 0x7f, 0x0b, 0xb1, 0xd2, 0xb2, 0x7e, 0xa9, 0xe7,
- 0x64, 0x79, 0xa3, 0xc2, 0xcd, 0x66, 0x60, 0x4c, 0x0b, 0xb6, 0x8e, 0x53,
- 0x07, 0x7e, 0xfa, 0x60, 0x2d, 0xe7, 0x7d, 0xd2, 0x15, 0xf4, 0x4e, 0x2a,
- 0x0b, 0xcf, 0xaa, 0x98, 0xbd, 0xea, 0x31, 0xa5, 0xa1, 0xa3, 0x04, 0x5a,
- 0x6c, 0x54, 0xb9, 0x82, 0x3a, 0x31, 0xfd, 0x1e, 0x04, 0xbd, 0x2b, 0x61,
- 0xc7, 0x6d, 0xdc, 0x9e, 0x70, 0xc6, 0xce, 0xa0, 0x9e, 0xfe, 0xa0, 0xb5,
- 0xdf, 0x4f, 0x6e, 0x07, 0x7c, 0x96, 0x84, 0x5f, 0xfa, 0x5a, 0x83, 0xf8,
- 0x5f, 0x58, 0xd6, 0x03, 0xec, 0xeb, 0x16, 0xf6, 0x75, 0x75, 0xe4, 0x7d,
- 0xeb, 0x17, 0xb6, 0xcc, 0x9b, 0x31, 0xa8, 0x5d, 0x2a, 0xf7, 0x3d, 0x0b,
- 0xd3, 0x45, 0xae, 0x0b, 0xb7, 0x4e, 0x67, 0xee, 0x11, 0x15, 0x2c, 0x79,
- 0x84, 0xf9, 0xb9, 0xc8, 0x63, 0x5c, 0x51, 0x2f, 0x8d, 0xcd, 0x0e, 0x30,
- 0xe6, 0xf9, 0xe3, 0x8a, 0x5a, 0x57, 0x06, 0x2f, 0xdc, 0x9a, 0x85, 0x07,
- 0xc9, 0x23, 0x62, 0xd3, 0x2b, 0xf1, 0x90, 0xee, 0x46, 0x79, 0x48, 0xbd,
- 0xd2, 0xc1, 0x39, 0xd9, 0x17, 0x91, 0x6b, 0x17, 0xc6, 0xa7, 0x3b, 0xd0,
- 0x49, 0x7e, 0xe1, 0x0d, 0xa9, 0xb5, 0x72, 0xdf, 0xdd, 0x24, 0xd7, 0xec,
- 0xff, 0x15, 0x0a, 0x1e, 0xa0, 0x55, 0xa8, 0xa1, 0x2e, 0xbf, 0xdc, 0x6f,
- 0xd5, 0xe5, 0x5a, 0x41, 0x7d, 0xc4, 0xc9, 0x79, 0xb1, 0xe0, 0x60, 0xdf,
- 0x4b, 0x43, 0xbc, 0x1f, 0x91, 0xdf, 0xb1, 0x07, 0x38, 0xee, 0xd8, 0x6e,
- 0x45, 0xb0, 0xe7, 0xc7, 0xd6, 0xf3, 0x8c, 0x2d, 0x5e, 0x3e, 0x7f, 0x88,
- 0x6d, 0x1f, 0x8d, 0x3c, 0x6b, 0xd5, 0x12, 0x73, 0x8f, 0x35, 0x07, 0x30,
- 0x63, 0x4e, 0x1d, 0x26, 0xef, 0x96, 0x31, 0x2b, 0x28, 0xd7, 0xca, 0x5d,
- 0x92, 0xe7, 0x55, 0x68, 0x57, 0xe0, 0xd6, 0xbb, 0x72, 0xf7, 0x4a, 0x28,
- 0x2f, 0x4c, 0xdc, 0x2d, 0x99, 0x53, 0x8d, 0x40, 0xfe, 0xde, 0xc2, 0x90,
- 0xb3, 0xad, 0x5c, 0xd1, 0xbc, 0xb7, 0x2b, 0xf2, 0xfc, 0x37, 0xb4, 0x71,
- 0xcb, 0x7a, 0x90, 0xf3, 0x35, 0x2b, 0xe2, 0xc1, 0x29, 0xb6, 0xd3, 0x45,
- 0xfd, 0x2d, 0x39, 0x3f, 0x5f, 0x85, 0xfa, 0xbf, 0xb6, 0x02, 0x7f, 0x21,
- 0x75, 0x45, 0xc6, 0xcc, 0xd6, 0x5b, 0x95, 0xe7, 0x9c, 0x92, 0x33, 0xac,
- 0x8e, 0xd8, 0x3a, 0x63, 0xd9, 0x5a, 0x97, 0x5c, 0x7b, 0xa3, 0xaf, 0x9f,
- 0x5f, 0x7f, 0x39, 0x6d, 0xc7, 0xa8, 0x05, 0x37, 0x7a, 0x31, 0x69, 0x55,
- 0x35, 0x99, 0xde, 0x62, 0x48, 0xac, 0xaa, 0x0f, 0x3f, 0x45, 0xb9, 0xaf,
- 0xe9, 0xb9, 0x38, 0xb6, 0x47, 0x0f, 0xa6, 0x4d, 0xfa, 0x43, 0x9c, 0x39,
- 0x5f, 0x8b, 0xbd, 0x56, 0xb4, 0x87, 0xf3, 0x30, 0x03, 0xc5, 0x4d, 0xc1,
- 0x9e, 0x6b, 0x98, 0x03, 0x39, 0xa2, 0x12, 0xff, 0x64, 0x7e, 0xec, 0x32,
- 0x6c, 0xab, 0x04, 0x0b, 0xd9, 0xc7, 0x48, 0xd3, 0x1f, 0x8b, 0x1d, 0x22,
- 0x47, 0xac, 0x33, 0xd8, 0x13, 0xc3, 0x1f, 0x2b, 0x0b, 0x46, 0x6a, 0xc4,
- 0x1d, 0x86, 0xfb, 0xa6, 0x78, 0x56, 0x25, 0xf7, 0x28, 0xf2, 0x76, 0x45,
- 0x6b, 0xf8, 0x91, 0xe7, 0xce, 0x9b, 0x56, 0x64, 0xcf, 0xaf, 0x29, 0x21,
- 0xad, 0x17, 0x41, 0xbd, 0x4e, 0x70, 0x9c, 0x88, 0xec, 0x95, 0xf1, 0x99,
- 0xcd, 0x5e, 0x3b, 0x87, 0x5e, 0xfb, 0x85, 0x7b, 0xb4, 0xa0, 0xfe, 0x26,
- 0x5b, 0x3c, 0x4c, 0x8e, 0x63, 0xda, 0x9e, 0x21, 0xbe, 0x3e, 0x15, 0x47,
- 0x25, 0xae, 0x88, 0x4c, 0xc1, 0xd0, 0x2b, 0xd1, 0xb7, 0xa3, 0x03, 0x81,
- 0x9a, 0x1c, 0x66, 0xb9, 0x8c, 0xb9, 0xd8, 0x93, 0xde, 0xec, 0xca, 0xf1,
- 0xf2, 0x4e, 0x3c, 0x45, 0x4c, 0xdb, 0xb8, 0x63, 0xa2, 0xb6, 0x8a, 0xba,
- 0xea, 0xd0, 0x1b, 0xf4, 0xd3, 0xb8, 0x83, 0x7e, 0x2e, 0x65, 0x27, 0xbe,
- 0x52, 0x05, 0x29, 0x67, 0xe1, 0x48, 0xa4, 0x06, 0xc9, 0x1d, 0x9f, 0x46,
- 0x66, 0xba, 0xdc, 0x97, 0x7b, 0x6e, 0xe2, 0xb0, 0x0f, 0xeb, 0x77, 0xf8,
- 0x91, 0xf1, 0xc9, 0x5a, 0x99, 0xac, 0x57, 0x0a, 0x36, 0xbf, 0x61, 0x99,
- 0x5e, 0xe9, 0x87, 0xc4, 0xf7, 0x50, 0x73, 0x37, 0x63, 0x9a, 0xd7, 0x88,
- 0x11, 0x3f, 0xc8, 0x3d, 0x46, 0x7f, 0x62, 0x65, 0x6c, 0x0e, 0xef, 0x36,
- 0x85, 0x23, 0x3d, 0xab, 0x35, 0xc4, 0x8e, 0xb0, 0x07, 0xf1, 0xec, 0x7f,
- 0xd2, 0x47, 0x9c, 0xb8, 0x47, 0xfb, 0xb8, 0xfe, 0x7b, 0xd8, 0x3f, 0xb8,
- 0x9d, 0xc4, 0x76, 0xf2, 0x48, 0x62, 0x70, 0xc8, 0x25, 0x31, 0xbf, 0x88,
- 0xed, 0x6f, 0xd9, 0xa1, 0xa0, 0x85, 0x18, 0xb8, 0x99, 0x36, 0xf5, 0x40,
- 0x08, 0xce, 0xd6, 0x39, 0xe4, 0x35, 0xf8, 0x02, 0x73, 0x1a, 0x1f, 0x36,
- 0x0d, 0x63, 0x6e, 0x56, 0x1b, 0xaf, 0xf5, 0xa0, 0xc7, 0x25, 0xdc, 0xd6,
- 0x24, 0xde, 0xe7, 0xe4, 0xec, 0xbb, 0x44, 0x4e, 0x0d, 0x1e, 0xcd, 0xcb,
- 0xd9, 0x49, 0x39, 0x9f, 0x9e, 0x05, 0x67, 0xc5, 0xa7, 0x65, 0x2e, 0x17,
- 0xd2, 0xbf, 0x6a, 0x90, 0xb2, 0xe3, 0x04, 0x79, 0xe0, 0x67, 0xa0, 0x68,
- 0x33, 0x25, 0x67, 0x58, 0x6a, 0xd7, 0xbb, 0xa5, 0x71, 0xfc, 0x4c, 0x15,
- 0xc1, 0xf5, 0xf4, 0xac, 0x71, 0x3a, 0x72, 0x41, 0x27, 0xde, 0x42, 0x5f,
- 0xff, 0xea, 0x42, 0x1b, 0x1c, 0x33, 0xed, 0xcb, 0x1d, 0x95, 0xbe, 0x3d,
- 0x6e, 0xb5, 0x7a, 0x73, 0x73, 0x95, 0xd8, 0x11, 0x0c, 0xb4, 0x51, 0xe7,
- 0x5b, 0xf4, 0xfa, 0xb6, 0x34, 0x29, 0xcc, 0x03, 0x73, 0x3e, 0x4d, 0xdf,
- 0xf7, 0x63, 0xf3, 0x30, 0x6e, 0x18, 0xd1, 0x24, 0xc6, 0x8c, 0x07, 0xcb,
- 0x2f, 0x9a, 0x83, 0xab, 0xa9, 0xef, 0x6a, 0xca, 0x27, 0xbf, 0x9b, 0x55,
- 0xe8, 0x3b, 0xfb, 0x41, 0xfc, 0x7e, 0x74, 0x87, 0xe4, 0xc2, 0x75, 0xe4,
- 0x58, 0x96, 0x75, 0x90, 0x63, 0x68, 0x9e, 0xd5, 0xb0, 0xe6, 0xb8, 0xa3,
- 0x16, 0x93, 0xd3, 0xaf, 0xc4, 0xce, 0x61, 0x89, 0x3f, 0x01, 0xd6, 0x6d,
- 0xaa, 0xcc, 0x71, 0x1b, 0xb8, 0x6e, 0xe5, 0x58, 0x0f, 0xe7, 0xc7, 0xe1,
- 0xd2, 0xc4, 0x26, 0x9a, 0xb0, 0x67, 0xe0, 0xfc, 0xf3, 0xe0, 0x2d, 0xda,
- 0x78, 0xd0, 0xf5, 0x07, 0xb6, 0x32, 0xce, 0xef, 0x0a, 0x89, 0x33, 0x17,
- 0xe9, 0x75, 0xdd, 0xf0, 0x69, 0x7e, 0x57, 0x33, 0x2e, 0xe6, 0xfa, 0xbd,
- 0x6e, 0xf8, 0x5f, 0x79, 0x2d, 0x7d, 0xb7, 0xb0, 0xce, 0xce, 0x63, 0x8a,
- 0x18, 0xdf, 0x04, 0x9b, 0xc5, 0xae, 0x6b, 0x24, 0x8f, 0x6b, 0xce, 0x40,
- 0x62, 0xb3, 0xd8, 0xf2, 0x80, 0xd8, 0x72, 0xd8, 0xa1, 0x00, 0x43, 0xe7,
- 0x6d, 0xb9, 0x13, 0x3f, 0xd0, 0x26, 0xee, 0x2a, 0xc6, 0xc4, 0x17, 0x65,
- 0xad, 0xb8, 0x23, 0x82, 0x63, 0x8b, 0x88, 0x13, 0x6f, 0xe9, 0x05, 0xbd,
- 0x8a, 0x3e, 0x05, 0x43, 0x15, 0x14, 0xd3, 0x66, 0x36, 0x50, 0x8f, 0x45,
- 0xaa, 0x9f, 0xed, 0x5e, 0x8a, 0xa5, 0xd2, 0x7f, 0x1d, 0x7b, 0x12, 0x13,
- 0x0f, 0x17, 0xe3, 0x7f, 0x49, 0x5e, 0xf4, 0xc6, 0x09, 0xca, 0xb9, 0x45,
- 0x17, 0xfd, 0x89, 0xee, 0x0a, 0x32, 0xae, 0x44, 0xef, 0x8e, 0x42, 0x5d,
- 0x05, 0x2f, 0x86, 0xfc, 0xf9, 0xb5, 0xd8, 0x2b, 0x91, 0x1c, 0x9e, 0x38,
- 0x46, 0x2e, 0x44, 0x7d, 0x4e, 0xac, 0xf1, 0xb3, 0x2f, 0xa7, 0x23, 0x05,
- 0xfb, 0x11, 0x9c, 0x98, 0x2a, 0x43, 0xfc, 0x03, 0x4a, 0xc5, 0x4c, 0xac,
- 0xab, 0xa0, 0x1f, 0x64, 0x43, 0x88, 0x97, 0x19, 0x35, 0x48, 0x0c, 0xd3,
- 0xcf, 0x47, 0x8a, 0xe0, 0xbc, 0x5e, 0xec, 0x5e, 0xf8, 0x98, 0xf3, 0xa6,
- 0xe3, 0x89, 0x22, 0x7c, 0x49, 0x3f, 0x67, 0x09, 0x46, 0x1f, 0xd3, 0x70,
- 0x55, 0x11, 0xf5, 0x34, 0x33, 0x12, 0x8a, 0xad, 0x24, 0x3f, 0x38, 0xd2,
- 0xe8, 0xbc, 0xe9, 0x64, 0xf6, 0xb7, 0xe4, 0xbe, 0x97, 0x8e, 0x45, 0xf4,
- 0x81, 0x17, 0x17, 0x87, 0x72, 0x73, 0x4e, 0xde, 0x9f, 0xf7, 0x07, 0x69,
- 0xdf, 0xb2, 0x42, 0x11, 0x1f, 0xed, 0xe2, 0xc2, 0x18, 0xde, 0xd6, 0x0a,
- 0x63, 0xf0, 0x31, 0xb6, 0x2f, 0x21, 0xb7, 0x16, 0xde, 0xef, 0x66, 0x9e,
- 0xeb, 0x64, 0xbe, 0xd0, 0x06, 0xe1, 0xa3, 0x47, 0xc9, 0xab, 0xf6, 0x27,
- 0x80, 0x77, 0xd3, 0x16, 0x16, 0x44, 0xca, 0x89, 0x75, 0x3d, 0x94, 0x2d,
- 0xeb, 0xab, 0x07, 0x94, 0x61, 0xe6, 0xc2, 0x93, 0xce, 0x92, 0x98, 0xca,
- 0xdc, 0x77, 0x5f, 0x36, 0xe4, 0x9f, 0x60, 0x1e, 0xec, 0x66, 0x2e, 0x4e,
- 0xcd, 0x29, 0xfb, 0x99, 0x07, 0xef, 0xce, 0xe7, 0xc1, 0xfb, 0xb2, 0x1e,
- 0x64, 0x69, 0xbc, 0x5b, 0x22, 0xcc, 0xbf, 0xed, 0x75, 0x04, 0x0f, 0xc6,
- 0xd2, 0x2a, 0x4e, 0x45, 0x3e, 0xb0, 0xc6, 0xab, 0x64, 0xcc, 0x3e, 0x3c,
- 0x93, 0xa8, 0xc6, 0x81, 0x81, 0x3a, 0x9c, 0xcd, 0x3e, 0x52, 0x84, 0xd2,
- 0x2b, 0x71, 0x66, 0xa8, 0x02, 0x23, 0x03, 0x9b, 0xf9, 0xbb, 0x11, 0x1f,
- 0x0c, 0xd9, 0x39, 0x38, 0xb1, 0x59, 0xfa, 0x77, 0x40, 0x99, 0xb0, 0x73,
- 0x70, 0x33, 0xc6, 0xdc, 0xbb, 0xb9, 0x27, 0x9f, 0x7b, 0x8f, 0x33, 0xf7,
- 0x3e, 0xc2, 0x36, 0x9f, 0xcb, 0xb7, 0x79, 0xc8, 0xfe, 0x96, 0xbe, 0x48,
- 0xdd, 0xa9, 0xf5, 0x9a, 0x59, 0x0f, 0x18, 0x4e, 0x84, 0xc2, 0x85, 0xba,
- 0xcf, 0xb1, 0xde, 0x91, 0xf3, 0xf5, 0x72, 0x39, 0x35, 0x79, 0x31, 0x36,
- 0x24, 0xec, 0x75, 0x1f, 0xea, 0x23, 0x4c, 0x5d, 0x48, 0x8e, 0x49, 0x7e,
- 0x9e, 0xfd, 0x16, 0xf9, 0xfc, 0x9e, 0x22, 0x54, 0x54, 0x61, 0x61, 0x46,
- 0xd6, 0xb3, 0x4b, 0x98, 0xfb, 0x15, 0xf4, 0x1f, 0x47, 0x32, 0xb5, 0x8a,
- 0xfe, 0x05, 0xb7, 0xc7, 0xc8, 0xfe, 0x55, 0x82, 0xf3, 0xf0, 0x44, 0x68,
- 0xbc, 0xad, 0x1c, 0x95, 0x58, 0x15, 0xb1, 0xf9, 0x23, 0x79, 0x60, 0xb0,
- 0x79, 0x09, 0xe3, 0x9c, 0x23, 0x14, 0x64, 0xcc, 0x02, 0x42, 0x23, 0xcc,
- 0x6f, 0xb2, 0x95, 0xb8, 0x87, 0x79, 0xa6, 0x5a, 0x15, 0x47, 0xcf, 0xf9,
- 0x35, 0x4e, 0xf9, 0x5e, 0x85, 0xee, 0x31, 0x91, 0x17, 0x67, 0xee, 0x50,
- 0x86, 0x45, 0xb9, 0x35, 0x19, 0xb7, 0x9b, 0xb2, 0xdd, 0xa1, 0xf1, 0x30,
- 0x5d, 0x50, 0xdf, 0xc7, 0x1b, 0x87, 0x12, 0x0a, 0x16, 0x68, 0x2e, 0xac,
- 0xf4, 0x56, 0x62, 0x81, 0xfe, 0x3b, 0x6b, 0xd1, 0x32, 0x79, 0x76, 0x61,
- 0xad, 0xb4, 0x98, 0xed, 0xfe, 0x92, 0xf9, 0xc2, 0xb0, 0x78, 0x67, 0x36,
- 0x77, 0xdf, 0xcc, 0x52, 0x36, 0xe5, 0x6e, 0xa0, 0xdc, 0xfb, 0xbc, 0x76,
- 0x2e, 0x9f, 0x2f, 0x37, 0x1e, 0x76, 0x30, 0x3e, 0x49, 0xd9, 0x16, 0xca,
- 0xbd, 0x87, 0x72, 0x7b, 0xbc, 0xd2, 0xbf, 0xdf, 0x59, 0xf7, 0x2d, 0x93,
- 0x67, 0xb9, 0x75, 0x91, 0x9c, 0xdc, 0xac, 0xc8, 0xd5, 0x87, 0xf3, 0x6d,
- 0x4d, 0x24, 0x98, 0xec, 0x11, 0xb3, 0x57, 0x44, 0x43, 0x81, 0x2e, 0x7b,
- 0x4d, 0x3c, 0x80, 0x95, 0xd9, 0x00, 0xee, 0xa5, 0xde, 0x33, 0xce, 0xc2,
- 0x98, 0xec, 0x3e, 0x99, 0x92, 0x17, 0x2c, 0x64, 0xb9, 0xee, 0x3c, 0x7e,
- 0xb7, 0x64, 0xc5, 0xfe, 0x26, 0xf3, 0xf9, 0xa4, 0xc4, 0xb1, 0xba, 0x3c,
- 0x16, 0x38, 0xf1, 0x64, 0xe2, 0x37, 0xe7, 0xfa, 0x52, 0x12, 0x97, 0x65,
- 0xad, 0x27, 0x80, 0x74, 0xf6, 0x2a, 0xd4, 0xf7, 0x7b, 0xb1, 0x42, 0x9f,
- 0x46, 0x9c, 0xf8, 0xd6, 0x79, 0x7b, 0xdc, 0xc7, 0x76, 0xe0, 0xb2, 0xc5,
- 0x2b, 0x4f, 0x66, 0x1b, 0xbc, 0xd5, 0xc4, 0xba, 0x83, 0x17, 0xc5, 0xd7,
- 0x19, 0xb1, 0x32, 0x23, 0xd4, 0xf6, 0x02, 0xe7, 0xbd, 0xc4, 0xce, 0x1b,
- 0xd6, 0x29, 0x19, 0xce, 0xfd, 0xe3, 0xf9, 0xb9, 0xdf, 0x9f, 0x45, 0x71,
- 0x0e, 0xdb, 0xae, 0xc2, 0xac, 0x7e, 0xf9, 0xf6, 0xe2, 0xed, 0x68, 0x29,
- 0xef, 0x5d, 0x85, 0x99, 0x83, 0x57, 0x17, 0xe7, 0xf6, 0xc2, 0x64, 0x7d,
- 0xe1, 0xd2, 0x1c, 0x2a, 0xd8, 0x63, 0xe2, 0x3d, 0xda, 0x44, 0x1d, 0x75,
- 0x26, 0x18, 0x2b, 0xfd, 0xda, 0x74, 0xbe, 0x5f, 0x4f, 0xb0, 0x5f, 0x71,
- 0x97, 0xac, 0xff, 0x4a, 0xbf, 0x94, 0x58, 0x85, 0x51, 0x87, 0x0f, 0x92,
- 0xf0, 0x7a, 0x8d, 0x50, 0xfc, 0x25, 0xfa, 0xca, 0x08, 0xfb, 0x5a, 0x85,
- 0x1e, 0x25, 0x6b, 0xef, 0xfd, 0x1c, 0x60, 0x99, 0xa9, 0x7c, 0x40, 0xfa,
- 0xe9, 0xa4, 0xcd, 0xfd, 0x25, 0x71, 0x58, 0x27, 0x0e, 0x8b, 0xfc, 0x77,
- 0xc8, 0x79, 0xbb, 0x29, 0x7f, 0x09, 0xe7, 0xcf, 0x2d, 0x7b, 0x54, 0x66,
- 0xa9, 0xd1, 0x66, 0x73, 0x6e, 0x27, 0x7d, 0x76, 0x01, 0x6d, 0x6a, 0x7f,
- 0x46, 0xc1, 0x10, 0x95, 0x7e, 0x34, 0x2d, 0x6b, 0xd7, 0x7e, 0xec, 0xcb,
- 0xb8, 0xf0, 0x5c, 0xba, 0x16, 0xc3, 0x99, 0x22, 0x1c, 0x4a, 0x5f, 0x89,
- 0xdd, 0x19, 0x22, 0x67, 0xfa, 0x2a, 0x0c, 0x66, 0xdc, 0x78, 0x23, 0x4d,
- 0x3d, 0x65, 0x4a, 0xf0, 0xd3, 0xf4, 0xa7, 0xf0, 0x4c, 0xa6, 0x14, 0xaf,
- 0xa7, 0xaf, 0xc6, 0x81, 0x4c, 0x19, 0x5e, 0x4e, 0x93, 0x17, 0x67, 0x3c,
- 0x78, 0x29, 0x1d, 0xc0, 0x68, 0xa6, 0x1c, 0x2f, 0xa6, 0x83, 0x18, 0xc9,
- 0x54, 0xe0, 0x07, 0xe9, 0x6b, 0x90, 0xcd, 0x54, 0xe2, 0x85, 0x74, 0x3d,
- 0x9e, 0xa0, 0x0f, 0x3c, 0x9f, 0xd6, 0xf0, 0x78, 0xa6, 0x0a, 0xc7, 0xd2,
- 0x21, 0xb6, 0xeb, 0xc3, 0xd1, 0x81, 0x30, 0xf6, 0x0d, 0xd5, 0xe0, 0xb9,
- 0x81, 0xd9, 0x18, 0x1e, 0xf2, 0xe3, 0xd0, 0x40, 0x23, 0x76, 0x0f, 0x8d,
- 0xdb, 0xfa, 0x39, 0x92, 0x68, 0x39, 0xaf, 0xc7, 0x0d, 0x1f, 0x33, 0xdf,
- 0xaf, 0x24, 0x44, 0x6f, 0x6e, 0xb3, 0x8a, 0x73, 0xf4, 0x64, 0xd6, 0x9e,
- 0x77, 0x68, 0xfd, 0x6d, 0xf4, 0x33, 0x0b, 0xdd, 0xfa, 0x95, 0xcc, 0x47,
- 0x7b, 0x24, 0x1e, 0xd1, 0x16, 0x0e, 0x28, 0x1b, 0x6d, 0x0c, 0xaa, 0x88,
- 0x95, 0x53, 0x97, 0x1c, 0xb6, 0xb7, 0x8c, 0xfe, 0x9c, 0x26, 0x16, 0x98,
- 0x9c, 0xd7, 0x44, 0xf6, 0x80, 0xb2, 0x85, 0xf9, 0xef, 0xb5, 0xfd, 0xa6,
- 0x55, 0x6a, 0x63, 0x71, 0x28, 0x36, 0x9b, 0x3e, 0x17, 0x1e, 0x14, 0x7d,
- 0x96, 0x17, 0x89, 0x3e, 0x8b, 0xb4, 0xcb, 0xd9, 0x49, 0x41, 0xef, 0x3f,
- 0x2e, 0xca, 0xd9, 0xc3, 0xdf, 0x17, 0xe7, 0x72, 0xc9, 0xc2, 0xbc, 0x5b,
- 0x56, 0x9f, 0x5e, 0x98, 0x7b, 0xf2, 0xd8, 0x6a, 0x59, 0x6f, 0x03, 0x63,
- 0x48, 0x15, 0x79, 0x8e, 0xac, 0x45, 0x4c, 0xc5, 0x1b, 0xc4, 0x8a, 0x8d,
- 0x50, 0x60, 0x96, 0x7a, 0x51, 0xfe, 0xea, 0x75, 0xd8, 0xf6, 0x67, 0xda,
- 0x98, 0x75, 0xf8, 0x3c, 0xf6, 0x4c, 0x14, 0x4b, 0x0c, 0xdd, 0x93, 0x90,
- 0xbe, 0x41, 0x2d, 0x92, 0x3e, 0x23, 0x77, 0x0f, 0xa3, 0xb2, 0x9e, 0x77,
- 0x39, 0xbb, 0x53, 0xb1, 0x72, 0xc0, 0x89, 0x2e, 0xfd, 0xbf, 0x48, 0xcc,
- 0x64, 0x3f, 0xea, 0xe8, 0x6f, 0x2a, 0xfe, 0x76, 0x80, 0xf1, 0x25, 0x72,
- 0x37, 0x4c, 0xe2, 0xad, 0x6b, 0xd4, 0x89, 0x15, 0x89, 0x65, 0x7c, 0xee,
- 0x86, 0x3a, 0x4a, 0x56, 0xd1, 0xeb, 0x36, 0x2b, 0x68, 0x33, 0xb2, 0xff,
- 0xd2, 0x3c, 0x66, 0xe2, 0xf0, 0x3c, 0x3f, 0x52, 0x09, 0x59, 0x3f, 0x5d,
- 0x82, 0x9d, 0xa9, 0xd0, 0xaa, 0xb3, 0x8a, 0x1f, 0xc9, 0xac, 0x0b, 0x26,
- 0xe7, 0xbe, 0x9b, 0x7d, 0xf3, 0xf4, 0x7a, 0xd1, 0x3d, 0x54, 0xcd, 0xcf,
- 0xc4, 0x67, 0x3d, 0xc4, 0xea, 0x6e, 0xce, 0x6d, 0xf7, 0x90, 0x07, 0x47,
- 0xf7, 0xb8, 0x51, 0x96, 0x82, 0xf2, 0xec, 0x3c, 0xa2, 0x8d, 0xd6, 0x88,
- 0x17, 0x46, 0x3c, 0x28, 0x25, 0xa7, 0x7d, 0x7e, 0xc4, 0x8b, 0x92, 0xad,
- 0xb4, 0x87, 0x5d, 0x55, 0x28, 0xde, 0xea, 0xc6, 0x73, 0x99, 0x6a, 0xb8,
- 0xb6, 0xde, 0x81, 0xf5, 0x99, 0x69, 0x50, 0xb7, 0x56, 0x63, 0x62, 0x97,
- 0x0f, 0x33, 0x76, 0x18, 0x78, 0x63, 0x4f, 0x0d, 0x6a, 0x77, 0xdc, 0x8c,
- 0x9f, 0xee, 0xf1, 0xa3, 0x92, 0xba, 0x79, 0x79, 0xc4, 0x29, 0xfc, 0x93,
- 0xf3, 0x74, 0xa0, 0x38, 0xbf, 0x6f, 0x1c, 0xbb, 0x94, 0xaf, 0x42, 0x29,
- 0xcc, 0x0d, 0x90, 0xc9, 0xca, 0xfa, 0x68, 0x63, 0x4b, 0x77, 0x62, 0xe4,
- 0x5f, 0x8b, 0x8d, 0x5f, 0xfd, 0x9f, 0xb7, 0xa3, 0x0d, 0xc4, 0x32, 0xf1,
- 0xff, 0x15, 0xab, 0x4b, 0x8c, 0x8e, 0x87, 0xc3, 0xf3, 0x8a, 0xb1, 0xca,
- 0x9e, 0x8f, 0x95, 0xe4, 0x80, 0xcb, 0xd1, 0xbd, 0xa3, 0xa1, 0xed, 0x1e,
- 0xc5, 0x87, 0x58, 0x55, 0x3f, 0xef, 0xa9, 0x79, 0x9f, 0x82, 0x2a, 0xf9,
- 0xba, 0xac, 0x99, 0xa9, 0xa3, 0x8b, 0xf2, 0x7b, 0xa0, 0x3e, 0x7b, 0x0d,
- 0xaa, 0x3b, 0x55, 0xd0, 0xe3, 0x98, 0x65, 0xda, 0xfb, 0x5a, 0xe2, 0xe3,
- 0x4e, 0xac, 0x4c, 0x8c, 0x32, 0x47, 0x11, 0x5d, 0x4a, 0x5f, 0x37, 0x52,
- 0x8e, 0xf4, 0x57, 0x9e, 0x37, 0xc4, 0xaa, 0x3e, 0xb6, 0xbf, 0x85, 0x71,
- 0x75, 0xb3, 0xfc, 0x67, 0xdd, 0x28, 0x95, 0xb2, 0xd2, 0xf7, 0x7a, 0xfe,
- 0x96, 0xfe, 0x5a, 0xd6, 0xc6, 0x8b, 0xe2, 0x54, 0x51, 0xac, 0x94, 0x71,
- 0x6a, 0x7f, 0x22, 0x14, 0x7b, 0x97, 0x78, 0x76, 0x2c, 0xeb, 0x24, 0xf7,
- 0x11, 0xbb, 0x59, 0x47, 0x7b, 0xe9, 0x51, 0x8e, 0x9e, 0xb7, 0x99, 0x42,
- 0x2e, 0xb0, 0x04, 0xe9, 0xd4, 0x54, 0x5f, 0x92, 0xfd, 0x6e, 0x27, 0x5c,
- 0xbd, 0x05, 0xdc, 0x64, 0xac, 0x19, 0x25, 0xbf, 0xcb, 0x3a, 0xe0, 0xe8,
- 0xa7, 0x3d, 0xe8, 0x2a, 0xc7, 0x58, 0xc4, 0x39, 0xaf, 0xe6, 0xc7, 0x6d,
- 0x56, 0x1a, 0x26, 0x4e, 0xcd, 0x2b, 0xc1, 0xa1, 0x5d, 0x57, 0xa1, 0xbc,
- 0x7f, 0xdc, 0xf2, 0xf0, 0x5e, 0xa9, 0x31, 0x1f, 0x4f, 0x44, 0x42, 0xad,
- 0xab, 0x15, 0x13, 0xad, 0xf3, 0xdc, 0x28, 0xd9, 0xe5, 0x40, 0x71, 0x3f,
- 0x79, 0x83, 0x7e, 0x03, 0xc6, 0x7d, 0x39, 0x3c, 0x57, 0x7b, 0x67, 0xdb,
- 0x76, 0x75, 0xcd, 0xa8, 0xdb, 0xf4, 0x1b, 0x13, 0x37, 0xaa, 0x8c, 0xed,
- 0xc5, 0xc3, 0x1e, 0x14, 0xf5, 0x9a, 0x98, 0x71, 0x83, 0xe0, 0x51, 0x23,
- 0x8a, 0x68, 0xaf, 0xae, 0x5e, 0x1f, 0xf3, 0xea, 0x3a, 0xb8, 0xc8, 0xed,
- 0x1c, 0xdb, 0x0d, 0x38, 0xc8, 0xc3, 0xd4, 0xed, 0x37, 0x43, 0x65, 0xd9,
- 0x13, 0x7c, 0x7e, 0x82, 0xfc, 0xf3, 0x04, 0xef, 0x9d, 0x18, 0xae, 0xe1,
- 0xa7, 0x0a, 0xb5, 0xbb, 0xcb, 0x10, 0x5b, 0x2a, 0xeb, 0xac, 0x0e, 0x54,
- 0xf7, 0x8b, 0x7f, 0xaa, 0xb8, 0xab, 0x49, 0x81, 0x7e, 0x1d, 0xdb, 0x9c,
- 0x79, 0x39, 0x5f, 0xbd, 0xd3, 0x8d, 0x8a, 0x2e, 0xb6, 0x77, 0xa9, 0x2f,
- 0x4b, 0xac, 0xba, 0x30, 0x07, 0x01, 0x55, 0x62, 0xb7, 0xcc, 0xd9, 0x27,
- 0xf9, 0xbd, 0x1b, 0xce, 0x5e, 0x99, 0x6b, 0x19, 0xe3, 0x37, 0xdd, 0x39,
- 0x5e, 0x7b, 0xd1, 0x5a, 0x3b, 0xb2, 0x89, 0x25, 0xd8, 0x62, 0x9f, 0x5d,
- 0x08, 0xc0, 0x33, 0x12, 0x6c, 0xcd, 0xe0, 0xf4, 0xb9, 0x9e, 0x94, 0x13,
- 0xf7, 0x26, 0xe5, 0x0c, 0x87, 0x9c, 0x33, 0xe0, 0x58, 0x47, 0xdc, 0x78,
- 0xb0, 0xcf, 0x2d, 0x6b, 0xdc, 0x01, 0x97, 0x56, 0x8b, 0x77, 0x33, 0x82,
- 0x79, 0x25, 0x38, 0x9c, 0xf6, 0xe3, 0x84, 0xfd, 0xbb, 0x94, 0x18, 0x6c,
- 0xa1, 0x45, 0x2f, 0x47, 0xb7, 0xb7, 0x04, 0xc9, 0xf0, 0xcd, 0xc8, 0xdc,
- 0xc5, 0x1c, 0x9a, 0xb6, 0x59, 0x41, 0x4e, 0x41, 0xb7, 0x63, 0x6e, 0xe0,
- 0x40, 0x2a, 0xfc, 0x39, 0x4c, 0x56, 0x39, 0xa9, 0x3f, 0x59, 0x9f, 0x50,
- 0xb1, 0x93, 0x56, 0x45, 0xfc, 0x8b, 0x89, 0xdd, 0x96, 0x27, 0x61, 0x55,
- 0x18, 0x5a, 0x7c, 0x54, 0x09, 0xb5, 0xaf, 0xa7, 0xdf, 0x96, 0x8d, 0x94,
- 0x11, 0x8f, 0x67, 0xa1, 0x74, 0x97, 0xd8, 0xaf, 0x87, 0xd8, 0x70, 0xbd,
- 0xec, 0x07, 0x84, 0x03, 0x8a, 0x07, 0xf7, 0x0d, 0x08, 0xae, 0x2e, 0x47,
- 0xd1, 0x9e, 0x0a, 0x3c, 0x9c, 0x76, 0x12, 0xfb, 0xdc, 0xa8, 0xdd, 0x25,
- 0x3e, 0x5f, 0x89, 0xca, 0xad, 0x07, 0x2d, 0xbf, 0x56, 0x82, 0x4a, 0x5e,
- 0x3f, 0x46, 0x5d, 0x7c, 0x90, 0xfa, 0x1a, 0x46, 0x13, 0xf5, 0x94, 0xdb,
- 0xce, 0xf1, 0xf9, 0xf0, 0x5e, 0xaa, 0x91, 0xb2, 0xfd, 0x78, 0x77, 0x87,
- 0x65, 0xb5, 0x44, 0x62, 0x70, 0x8e, 0x5c, 0x89, 0x5f, 0xf2, 0xf7, 0x71,
- 0xbd, 0x05, 0xea, 0x48, 0x1d, 0xde, 0x4c, 0xb5, 0xc2, 0x31, 0x52, 0x81,
- 0xb3, 0x5b, 0x45, 0xa6, 0x1b, 0x95, 0x7d, 0x5a, 0xf8, 0x0c, 0x6d, 0xdf,
- 0xb5, 0x8b, 0x81, 0xbf, 0x46, 0xda, 0x2f, 0xcc, 0x4f, 0x8e, 0xef, 0x1d,
- 0xcc, 0xcf, 0xcd, 0x38, 0x0a, 0xdc, 0xe9, 0x07, 0xd6, 0x63, 0x4c, 0x67,
- 0x5c, 0xd1, 0x20, 0xba, 0xc3, 0xc7, 0x64, 0xbf, 0x9c, 0xe3, 0x8b, 0x11,
- 0xf3, 0x9f, 0xb5, 0xe4, 0xdc, 0x81, 0x8b, 0xf6, 0x59, 0xac, 0x1d, 0xb2,
- 0x36, 0x2e, 0x93, 0xfb, 0x3f, 0xe7, 0x9c, 0x30, 0x41, 0x31, 0x44, 0xe6,
- 0x16, 0x99, 0x4b, 0xa2, 0xf1, 0xe5, 0x64, 0xfe, 0xa3, 0xf5, 0xe8, 0xf9,
- 0xf2, 0xf0, 0xba, 0xec, 0x75, 0x70, 0x59, 0x87, 0x95, 0xb9, 0x94, 0xf5,
- 0xca, 0x00, 0x56, 0x8d, 0x78, 0xed, 0xdc, 0xf9, 0xdd, 0x84, 0xcc, 0x9f,
- 0x9c, 0xa1, 0xf1, 0x90, 0x9b, 0xe8, 0x28, 0xe5, 0xdc, 0x7d, 0x90, 0x80,
- 0x72, 0x5b, 0xb4, 0x0d, 0xe5, 0xc4, 0xb5, 0x77, 0x12, 0xc1, 0x55, 0x26,
- 0x12, 0x6c, 0x2b, 0x8a, 0x12, 0xd6, 0x79, 0x33, 0xe1, 0x60, 0xbc, 0x6d,
- 0xe6, 0x98, 0xbd, 0xb0, 0x6c, 0xae, 0xbc, 0x0c, 0x33, 0xa8, 0xa7, 0xb3,
- 0x09, 0x03, 0xb5, 0xd4, 0xd3, 0x99, 0x84, 0x13, 0x67, 0xa8, 0x97, 0x53,
- 0x89, 0x00, 0x2a, 0x18, 0x98, 0x8a, 0xfa, 0x2c, 0x4c, 0xe8, 0x95, 0x72,
- 0x3e, 0x02, 0x72, 0xfe, 0xc5, 0x9f, 0xd4, 0x51, 0x9b, 0xac, 0x5f, 0x53,
- 0xeb, 0x70, 0x60, 0xd2, 0xe6, 0x2c, 0x4e, 0xe6, 0xcd, 0xa2, 0x1f, 0x19,
- 0x93, 0x9d, 0xab, 0xb7, 0xca, 0xa1, 0xa6, 0x83, 0x1c, 0x4f, 0x40, 0x29,
- 0x8c, 0x67, 0x19, 0x40, 0x59, 0xa3, 0x89, 0x30, 0x1e, 0x62, 0x5b, 0x6f,
- 0x27, 0x5e, 0xc1, 0xad, 0xfc, 0x7e, 0x3f, 0xf1, 0x23, 0x2c, 0x61, 0x3f,
- 0xde, 0x23, 0x6e, 0xdc, 0x1f, 0xba, 0xad, 0x04, 0xa5, 0x75, 0x58, 0x34,
- 0x72, 0xfa, 0x5c, 0xb7, 0x3d, 0xce, 0x42, 0x4e, 0xe5, 0xc6, 0xfd, 0xe9,
- 0xc2, 0x59, 0xa6, 0x18, 0x7d, 0x58, 0xf0, 0xd5, 0xcd, 0x1c, 0x1e, 0x68,
- 0x4b, 0x7c, 0x23, 0x77, 0x4e, 0x47, 0x95, 0xcf, 0x79, 0x3d, 0x3a, 0x51,
- 0xea, 0xcf, 0xfb, 0x95, 0xf4, 0xe7, 0x93, 0xca, 0x5c, 0xe0, 0xcc, 0xa3,
- 0xb6, 0x7e, 0x65, 0x7d, 0x3e, 0x80, 0xeb, 0x88, 0xe7, 0x27, 0xc9, 0xa1,
- 0x19, 0x93, 0xb1, 0x7a, 0xde, 0x0a, 0xf4, 0xec, 0x11, 0x9d, 0x06, 0xdb,
- 0xd9, 0x87, 0xb6, 0x0c, 0x56, 0x22, 0xb9, 0xc7, 0xc3, 0x31, 0x88, 0xde,
- 0xc9, 0x43, 0xf7, 0xd0, 0xff, 0xd3, 0x7f, 0x83, 0x75, 0xbb, 0xa6, 0xe1,
- 0xad, 0xf4, 0x97, 0xb0, 0x9e, 0x36, 0xe4, 0xa0, 0xef, 0xac, 0xd0, 0xaf,
- 0x42, 0x6e, 0x3f, 0xc3, 0xc7, 0x39, 0x78, 0x9f, 0xbe, 0xb5, 0x0e, 0xef,
- 0x64, 0x67, 0x61, 0x46, 0x9f, 0x8a, 0xc9, 0x69, 0x0a, 0xed, 0x43, 0xf6,
- 0x5e, 0xdc, 0xc4, 0xb7, 0xaf, 0x40, 0xdd, 0x65, 0x62, 0x7d, 0xd4, 0x8d,
- 0xdd, 0xcc, 0x2d, 0x56, 0xc8, 0x7a, 0x98, 0x5d, 0xaf, 0x19, 0x7b, 0x39,
- 0x17, 0x89, 0x04, 0x79, 0x8b, 0x37, 0xa7, 0xe7, 0xf8, 0xf4, 0x62, 0xd6,
- 0xb9, 0xa7, 0xc4, 0xde, 0xcb, 0x50, 0x04, 0x1f, 0x44, 0xcf, 0x05, 0x1d,
- 0x7f, 0x0d, 0x37, 0x26, 0xdf, 0xa7, 0x1d, 0x84, 0xc6, 0xaf, 0x75, 0xfc,
- 0x4f, 0xea, 0x72, 0x1d, 0xe7, 0xf1, 0x6f, 0x30, 0x94, 0xf6, 0xd0, 0x8f,
- 0x64, 0xef, 0x69, 0x2d, 0x8e, 0x6e, 0x8b, 0x33, 0x37, 0x09, 0xea, 0x19,
- 0xf2, 0xfa, 0x4c, 0x95, 0x65, 0x39, 0x22, 0x71, 0x0c, 0x0e, 0x58, 0xd6,
- 0x62, 0x3d, 0xd6, 0x5c, 0x42, 0xfd, 0xde, 0x8f, 0xfd, 0xac, 0xe7, 0xc3,
- 0x91, 0xa1, 0x15, 0xbc, 0x2f, 0x3c, 0x78, 0x2d, 0x1e, 0xe6, 0xf3, 0x2f,
- 0xe9, 0xb1, 0xf1, 0x19, 0x08, 0x72, 0xce, 0x73, 0xcf, 0xc7, 0x86, 0x56,
- 0x7e, 0x4c, 0xbd, 0x0b, 0xfa, 0x7c, 0x22, 0xaf, 0xcf, 0x52, 0xea, 0xf3,
- 0xf6, 0x91, 0xf7, 0xcf, 0x6d, 0x48, 0x05, 0x63, 0x19, 0xc6, 0x98, 0xb7,
- 0xa8, 0xb7, 0x8d, 0xb4, 0x57, 0xe6, 0x1a, 0x38, 0x92, 0x6d, 0xa6, 0x6e,
- 0x5c, 0xe4, 0x44, 0x4e, 0x1c, 0xcb, 0x1a, 0xb4, 0x4d, 0x60, 0x21, 0xe3,
- 0x85, 0xe9, 0xcd, 0xd9, 0x4f, 0xe6, 0xbc, 0x3f, 0x70, 0xee, 0x94, 0x66,
- 0x1c, 0x4f, 0xc8, 0xd8, 0xa5, 0x9c, 0xfd, 0x5c, 0xd6, 0x80, 0xa7, 0x94,
- 0xb9, 0xd0, 0xf6, 0xee, 0x84, 0xf0, 0xf4, 0x00, 0x65, 0x15, 0x53, 0xd6,
- 0xe9, 0x73, 0x9b, 0x52, 0x6d, 0xf6, 0xd9, 0x37, 0xf2, 0x1b, 0x84, 0x69,
- 0xcf, 0xc5, 0x91, 0x32, 0xbc, 0xed, 0x13, 0x19, 0x39, 0x5d, 0x0a, 0x06,
- 0x6e, 0x61, 0x19, 0x79, 0xfe, 0x20, 0x9f, 0xdf, 0x12, 0x29, 0xc2, 0x90,
- 0xb7, 0xb0, 0xee, 0x94, 0xeb, 0x8b, 0x79, 0xbe, 0x9d, 0x6b, 0x2b, 0x73,
- 0x76, 0x55, 0x5c, 0x6a, 0xef, 0x25, 0xd9, 0xdc, 0xaa, 0xee, 0x92, 0xfd,
- 0x3a, 0x89, 0x7f, 0x82, 0x93, 0x39, 0x9c, 0x2d, 0xa1, 0x3d, 0x3d, 0x97,
- 0x90, 0x75, 0x21, 0x93, 0x39, 0x46, 0x18, 0x8b, 0xb2, 0xf6, 0x99, 0x2e,
- 0xc6, 0x37, 0xea, 0x8c, 0xbc, 0x77, 0x65, 0x54, 0xf6, 0xe3, 0x6e, 0xae,
- 0x14, 0x5e, 0xd7, 0x11, 0x95, 0x7c, 0x42, 0x6c, 0xb5, 0x70, 0xcf, 0x8d,
- 0x3d, 0xf9, 0x39, 0x0f, 0xa8, 0x9f, 0x84, 0xfd, 0xaf, 0x5f, 0xc2, 0xf1,
- 0x0a, 0x7b, 0x5a, 0xd2, 0xaf, 0xf3, 0x5c, 0xcf, 0xe6, 0xf5, 0x43, 0xf4,
- 0x37, 0xd3, 0x59, 0x46, 0x7e, 0x27, 0xbc, 0x3e, 0xa4, 0xcf, 0x52, 0x85,
- 0xd3, 0x4b, 0x4e, 0x21, 0x6b, 0x7b, 0x3d, 0xca, 0xde, 0xac, 0xac, 0xef,
- 0x09, 0x9f, 0xbf, 0xdc, 0x1a, 0x9f, 0x9c, 0x8d, 0x93, 0xf8, 0x78, 0xfa,
- 0x5c, 0x7f, 0xaa, 0xcd, 0xde, 0x07, 0x5d, 0xd0, 0x6f, 0xe1, 0x6e, 0xc6,
- 0x82, 0x7b, 0xaa, 0xed, 0x1c, 0x29, 0x9f, 0x8b, 0x9c, 0x3e, 0xb7, 0x33,
- 0xf5, 0x7b, 0x4b, 0xb5, 0xf7, 0x1d, 0x5d, 0x70, 0x6c, 0xd5, 0xce, 0xac,
- 0x20, 0xe7, 0x3b, 0x7b, 0x83, 0xe4, 0x25, 0x2e, 0xc6, 0xc9, 0xff, 0x52,
- 0x2a, 0x7b, 0xe0, 0xe4, 0xcb, 0xb8, 0xa5, 0x3f, 0x86, 0x21, 0xfd, 0x43,
- 0xcb, 0xf4, 0x4d, 0xad, 0xef, 0xc2, 0x92, 0xfe, 0xdf, 0x5b, 0xe5, 0x76,
- 0x7d, 0xad, 0x3d, 0xa9, 0xa8, 0x78, 0x70, 0x9e, 0x0b, 0xb7, 0x0d, 0x86,
- 0xb0, 0xb8, 0x5f, 0x45, 0x78, 0x9e, 0xc8, 0x09, 0xa1, 0x75, 0xb0, 0xde,
- 0x99, 0x5f, 0xd7, 0xc1, 0x22, 0xf6, 0xe3, 0x6d, 0xbd, 0x0c, 0xaf, 0x11,
- 0x77, 0x2b, 0x6c, 0x9e, 0xbd, 0x46, 0x49, 0x09, 0xcf, 0x76, 0xa9, 0x98,
- 0xa6, 0xc1, 0x5b, 0x6d, 0xc4, 0xc8, 0xb1, 0x5b, 0x94, 0xad, 0x99, 0x35,
- 0x4a, 0x7f, 0xb6, 0xd0, 0xbe, 0x07, 0x77, 0x8c, 0x7a, 0x71, 0xc7, 0xde,
- 0x6a, 0x7e, 0x7c, 0xfc, 0xd4, 0xf0, 0xf3, 0x8d, 0xd2, 0xdc, 0xfe, 0xfc,
- 0x12, 0xac, 0x4b, 0x15, 0xec, 0xca, 0xc9, 0xbc, 0x5a, 0x6c, 0x57, 0xea,
- 0x04, 0xb0, 0x97, 0xfc, 0xfc, 0x64, 0x5a, 0xb8, 0xfd, 0x06, 0xea, 0x42,
- 0xd6, 0x99, 0x8b, 0xc9, 0xef, 0xe5, 0x3c, 0x63, 0x24, 0xbf, 0xef, 0x9f,
- 0xb3, 0x1b, 0x9c, 0xb7, 0x1b, 0x17, 0xde, 0xa1, 0x7f, 0xcf, 0x8a, 0xfc,
- 0xbb, 0x35, 0xe9, 0xbd, 0x60, 0x57, 0x17, 0x9e, 0x17, 0xf8, 0xd0, 0xe9,
- 0x73, 0xe9, 0xd4, 0x54, 0x7b, 0x52, 0x50, 0xd4, 0x2f, 0x7c, 0x59, 0xf4,
- 0xe2, 0xc4, 0xab, 0xc4, 0x07, 0x67, 0xff, 0xc4, 0xb5, 0x42, 0xeb, 0x5c,
- 0x7b, 0x63, 0xe8, 0x8e, 0x52, 0xb7, 0x83, 0xa5, 0xc5, 0x39, 0xfb, 0xc8,
- 0xe9, 0x22, 0xa0, 0x0a, 0xbe, 0x78, 0x6c, 0x9e, 0x17, 0x60, 0x2e, 0xa8,
- 0xee, 0x15, 0xce, 0x58, 0xcd, 0x6f, 0xe1, 0xe6, 0xe4, 0x2f, 0x7b, 0x85,
- 0xa7, 0xd7, 0xf0, 0x9b, 0x24, 0xbf, 0x46, 0xec, 0x69, 0x25, 0x7a, 0x18,
- 0x13, 0x8b, 0x43, 0x2b, 0xb1, 0x71, 0xf8, 0x72, 0xb6, 0x95, 0xcb, 0x77,
- 0x0e, 0x5e, 0xb0, 0x6f, 0x69, 0x8f, 0x7d, 0x3a, 0x7d, 0x4e, 0x6c, 0x35,
- 0xc0, 0xb9, 0xda, 0x9d, 0x96, 0x3e, 0x58, 0xe8, 0xd0, 0xc9, 0x8d, 0xe8,
- 0x6b, 0x6a, 0xb5, 0xdc, 0x9f, 0xca, 0x29, 0x0b, 0xb2, 0xa6, 0xde, 0xdb,
- 0x55, 0x2a, 0xeb, 0xec, 0x17, 0xc6, 0x5e, 0x68, 0x43, 0xd6, 0x55, 0x03,
- 0xa8, 0xea, 0x15, 0x3d, 0xca, 0x98, 0x02, 0x70, 0x92, 0x03, 0x56, 0x8d,
- 0x5e, 0x4e, 0x1e, 0x6a, 0x4a, 0xec, 0xf3, 0x83, 0x61, 0xfa, 0x99, 0xc7,
- 0x2c, 0x26, 0x5f, 0x7c, 0x3b, 0x21, 0xe7, 0x32, 0x5b, 0x5b, 0x76, 0x27,
- 0x66, 0x7a, 0x0f, 0xe7, 0xf3, 0xfe, 0x15, 0x70, 0x93, 0xa3, 0x9a, 0x98,
- 0x88, 0x2a, 0x36, 0xde, 0x38, 0xb4, 0x10, 0x16, 0x32, 0xb7, 0xbc, 0x25,
- 0x23, 0xf3, 0xb9, 0x26, 0xbf, 0x26, 0x24, 0xed, 0xc5, 0x94, 0xa1, 0xac,
- 0xe4, 0x05, 0xf0, 0x3a, 0x8d, 0x16, 0x65, 0x5f, 0x46, 0xea, 0xaf, 0xe1,
- 0xbd, 0xc2, 0x9e, 0xf1, 0x12, 0xf4, 0xa7, 0x0a, 0xbe, 0x55, 0xd0, 0x47,
- 0x05, 0x6d, 0x55, 0xf2, 0x3e, 0x13, 0xfa, 0xf5, 0xb5, 0x68, 0x1c, 0x2c,
- 0xc7, 0xed, 0xfd, 0xb9, 0xfd, 0xfa, 0x86, 0xc1, 0x6a, 0xdc, 0xb6, 0x7d,
- 0x39, 0x4a, 0xf7, 0x7a, 0xb1, 0x78, 0xbb, 0xec, 0x0d, 0x2c, 0x43, 0xf1,
- 0xe8, 0xaf, 0x4a, 0xed, 0x9c, 0xbb, 0xb7, 0x99, 0x73, 0xd4, 0x4c, 0xce,
- 0x19, 0x6c, 0x8e, 0x41, 0xd6, 0x3a, 0x0d, 0x14, 0x8d, 0x1a, 0xe4, 0xa6,
- 0x56, 0xe7, 0x0c, 0x83, 0xf3, 0xcc, 0x7e, 0x5e, 0xc3, 0xbc, 0x67, 0x16,
- 0xc7, 0xee, 0xe2, 0xc7, 0xd1, 0x6b, 0x59, 0x67, 0x6f, 0x40, 0x67, 0x19,
- 0xf3, 0x70, 0xc7, 0xe8, 0x55, 0x08, 0x0c, 0x36, 0xa2, 0x76, 0xb4, 0x1a,
- 0xda, 0xa0, 0x0f, 0xad, 0xbd, 0xe2, 0x8b, 0xc1, 0x40, 0x5c, 0x8d, 0xc2,
- 0x3d, 0xca, 0x38, 0xdd, 0xfb, 0x7b, 0xeb, 0x24, 0xe7, 0xba, 0x99, 0x3a,
- 0xbb, 0xb3, 0xb7, 0x15, 0x95, 0xa3, 0xb4, 0xf3, 0xfe, 0x3b, 0x50, 0x31,
- 0xe8, 0x26, 0x4f, 0x0e, 0x20, 0x4b, 0x5e, 0xec, 0x19, 0xf4, 0xa3, 0xb4,
- 0x57, 0x6b, 0xbd, 0x5d, 0x41, 0x6c, 0x26, 0x73, 0xa9, 0x22, 0xb6, 0xe5,
- 0xa2, 0x0f, 0x0d, 0xd2, 0x97, 0x17, 0xd2, 0xcd, 0x3b, 0x7b, 0x05, 0x77,
- 0x44, 0x27, 0x67, 0x6d, 0x9b, 0x5e, 0xd9, 0x7b, 0xf9, 0x33, 0xa3, 0x38,
- 0x7f, 0x66, 0xd4, 0xb4, 0xcf, 0x72, 0x56, 0x1a, 0x50, 0xce, 0xcc, 0xd2,
- 0x7a, 0x6a, 0x79, 0xef, 0x43, 0xc6, 0xfd, 0xaf, 0xf6, 0x7a, 0x18, 0x7f,
- 0x3a, 0xf1, 0xb9, 0xa6, 0xa0, 0x39, 0xaa, 0xbc, 0xc2, 0xf1, 0xff, 0x88,
- 0x01, 0xb7, 0x8e, 0xfd, 0xfc, 0x73, 0xe5, 0x5f, 0xba, 0x26, 0x36, 0xef,
- 0xa2, 0xb5, 0xb4, 0x23, 0xcc, 0x9f, 0xc7, 0x2f, 0x5a, 0x4b, 0x13, 0x2c,
- 0xbd, 0xf4, 0x4c, 0x6d, 0x60, 0xca, 0xfa, 0x8c, 0xcc, 0x99, 0xcc, 0x53,
- 0x61, 0x7d, 0xc6, 0x44, 0xd3, 0xf5, 0x2e, 0x2c, 0xec, 0x97, 0x9c, 0x47,
- 0x62, 0x71, 0x88, 0xb9, 0xc6, 0x66, 0xce, 0x83, 0xbd, 0xae, 0xc2, 0x7b,
- 0x01, 0xe2, 0x4b, 0x80, 0x39, 0x44, 0x92, 0xf7, 0x4a, 0x70, 0x5b, 0x7f,
- 0xb5, 0xbd, 0x87, 0xb5, 0x38, 0x72, 0x15, 0xc2, 0x55, 0xb2, 0xbe, 0x76,
- 0x61, 0x1d, 0x66, 0x0e, 0x73, 0x95, 0x32, 0x1b, 0xbb, 0x16, 0x50, 0xd7,
- 0x57, 0xd1, 0x26, 0x72, 0x78, 0x75, 0xfb, 0x60, 0x0e, 0x97, 0x7a, 0xd9,
- 0xff, 0x71, 0x57, 0xce, 0xde, 0xd2, 0xb4, 0x37, 0xaf, 0xd6, 0xa2, 0xa4,
- 0x33, 0x0d, 0xde, 0x69, 0x97, 0x3d, 0x8b, 0x01, 0x6f, 0xa5, 0x51, 0x38,
- 0x27, 0x4c, 0x4c, 0xcb, 0x3e, 0x58, 0x96, 0xcf, 0xdb, 0x3e, 0xa6, 0xfc,
- 0xc7, 0xe9, 0xeb, 0xfa, 0x3f, 0x51, 0x5f, 0x72, 0xae, 0xac, 0xa0, 0x2f,
- 0x6d, 0xca, 0xd9, 0x88, 0x9c, 0xce, 0xaa, 0x0d, 0x39, 0x4b, 0x78, 0x41,
- 0x67, 0x77, 0x51, 0x67, 0xf5, 0xe7, 0x75, 0x76, 0x5d, 0x5e, 0x67, 0x25,
- 0xd4, 0x59, 0x35, 0x71, 0x57, 0x30, 0xf9, 0x5a, 0x62, 0xf2, 0xb7, 0xec,
- 0x7b, 0xb3, 0xa9, 0x97, 0x9c, 0xce, 0x34, 0xea, 0x6c, 0x2a, 0xde, 0x5f,
- 0x85, 0x76, 0xe2, 0x7d, 0x05, 0xe3, 0x61, 0x99, 0x9c, 0xed, 0xba, 0xe1,
- 0x2a, 0xdc, 0x39, 0x58, 0x82, 0xb9, 0x83, 0x2e, 0xea, 0xd2, 0x8e, 0x01,
- 0xe4, 0xf4, 0xae, 0xf3, 0x7a, 0x6c, 0x18, 0x94, 0x71, 0xad, 0x51, 0x7e,
- 0xc8, 0x71, 0x05, 0x8a, 0x72, 0x7a, 0x7c, 0x25, 0x9b, 0xeb, 0x43, 0xb5,
- 0x26, 0xf1, 0xac, 0x45, 0x79, 0x35, 0x23, 0x38, 0xfb, 0x3d, 0xea, 0x6a,
- 0x0d, 0x9f, 0x35, 0x78, 0x7d, 0xe0, 0x58, 0x3e, 0xf6, 0xbc, 0x9f, 0xe8,
- 0xeb, 0x7b, 0xe7, 0xf5, 0xfa, 0xc7, 0xcb, 0x16, 0xec, 0x4a, 0xce, 0xfb,
- 0x15, 0xf4, 0xa5, 0x4d, 0xc1, 0x48, 0xcb, 0x7a, 0x5a, 0x9f, 0x85, 0x78,
- 0x75, 0x30, 0x2d, 0x6b, 0x46, 0x69, 0xf2, 0x1d, 0x47, 0xaf, 0xf4, 0x59,
- 0x72, 0x03, 0xf5, 0x66, 0xb2, 0xbf, 0x46, 0x07, 0x3a, 0x71, 0x42, 0xd7,
- 0x7a, 0xee, 0xc3, 0xa7, 0xd0, 0xe5, 0xb3, 0xb0, 0x47, 0x6f, 0x67, 0xee,
- 0x53, 0x8a, 0x55, 0x8d, 0x34, 0xf9, 0xbb, 0x62, 0xe8, 0x4b, 0x99, 0xed,
- 0x0e, 0xc8, 0x9a, 0xec, 0xf7, 0xbf, 0x90, 0x08, 0x05, 0xdb, 0x56, 0x2b,
- 0xc0, 0xe2, 0xa4, 0x1b, 0x01, 0xc5, 0xe6, 0x26, 0xe1, 0x7e, 0x55, 0xd6,
- 0x96, 0xb7, 0x17, 0xe5, 0xce, 0x6a, 0xa8, 0x08, 0xd4, 0x48, 0x3b, 0xed,
- 0x30, 0xc7, 0xa4, 0x2e, 0xf5, 0x38, 0x53, 0xc1, 0x6d, 0x33, 0x83, 0x66,
- 0x5c, 0xb1, 0xac, 0xa5, 0x11, 0xa7, 0xfd, 0x7c, 0xcb, 0x58, 0x43, 0xfc,
- 0x6e, 0xf5, 0xe7, 0x96, 0x69, 0xaf, 0x67, 0x07, 0xbd, 0x31, 0xf5, 0x8f,
- 0x8d, 0x93, 0x79, 0x03, 0x73, 0x84, 0xfd, 0xf9, 0x35, 0x5c, 0x97, 0x11,
- 0x5e, 0xbe, 0xc7, 0x5e, 0x47, 0xfe, 0x96, 0x7d, 0x2e, 0x25, 0x9d, 0x92,
- 0x35, 0xc0, 0xa8, 0x07, 0xa5, 0xed, 0xe8, 0x1a, 0xbb, 0x01, 0x23, 0x8d,
- 0xbf, 0xb0, 0x32, 0xb9, 0xbe, 0x8b, 0x79, 0xbb, 0x6b, 0x8d, 0x13, 0x5f,
- 0xb8, 0x71, 0x96, 0x70, 0x47, 0x39, 0x43, 0x4a, 0xde, 0xae, 0xe4, 0xb8,
- 0xec, 0x0c, 0xed, 0x16, 0x1c, 0xbc, 0x48, 0xa6, 0xac, 0x31, 0x14, 0x64,
- 0xb6, 0x51, 0x9e, 0xc8, 0x75, 0x51, 0x57, 0xff, 0x6e, 0x0d, 0xfa, 0xa6,
- 0x96, 0xfb, 0x47, 0x77, 0x2e, 0xc6, 0x49, 0xb9, 0x42, 0xbb, 0xc2, 0xed,
- 0x3e, 0xb0, 0x86, 0x2e, 0x2a, 0xf7, 0x6a, 0x9e, 0x33, 0x3d, 0xe4, 0x91,
- 0x33, 0x2d, 0xe9, 0x54, 0x31, 0xf9, 0xd4, 0x09, 0x6b, 0xef, 0x45, 0x65,
- 0x3e, 0xbc, 0xa4, 0x4c, 0x3d, 0x73, 0xb5, 0x7f, 0xb1, 0x86, 0x2f, 0x2a,
- 0x53, 0x59, 0x7a, 0x71, 0x99, 0x6b, 0x88, 0xb3, 0xaf, 0x5a, 0xbb, 0x2f,
- 0x2a, 0xf3, 0x77, 0x97, 0xc8, 0x99, 0x4b, 0x1b, 0x7f, 0xda, 0xda, 0x97,
- 0x2f, 0xe3, 0x64, 0x99, 0x75, 0xda, 0x53, 0xf9, 0xbc, 0xbc, 0x50, 0xa6,
- 0x70, 0xbf, 0xa4, 0xec, 0xd2, 0xfb, 0x39, 0x99, 0xe1, 0x4b, 0x64, 0x06,
- 0x4d, 0x99, 0x6f, 0x57, 0x53, 0x61, 0xbe, 0xa3, 0xf9, 0xfb, 0xdf, 0x28,
- 0xbb, 0xb8, 0xdc, 0xc4, 0x25, 0xd7, 0x05, 0x79, 0x7f, 0xed, 0xbe, 0xf8,
- 0x7e, 0x65, 0xf1, 0xc5, 0xd7, 0xbb, 0x8b, 0x72, 0xd7, 0x05, 0x9d, 0x6e,
- 0xb9, 0xe4, 0xf9, 0x7f, 0x2b, 0xba, 0xf8, 0xfa, 0xc6, 0xe2, 0xcb, 0xb7,
- 0xf3, 0x93, 0x4b, 0xee, 0x2b, 0x5d, 0xf2, 0xfe, 0x89, 0xc3, 0x50, 0x2b,
- 0xba, 0xa2, 0xab, 0x6e, 0x8a, 0x67, 0x7b, 0x68, 0x9f, 0x62, 0x5b, 0xab,
- 0x6f, 0x5a, 0x91, 0x3d, 0x79, 0x7e, 0x8f, 0x3b, 0xad, 0x2f, 0xf0, 0x7b,
- 0xf1, 0x59, 0xac, 0xb0, 0xf7, 0xd2, 0x64, 0x8d, 0xc7, 0xe4, 0x18, 0xed,
- 0x77, 0x51, 0xdc, 0x8a, 0x11, 0x87, 0x6e, 0x9f, 0x07, 0x5d, 0x89, 0xfa,
- 0xac, 0xbd, 0x8f, 0x17, 0x8e, 0xe3, 0xa0, 0xda, 0xaa, 0x99, 0xf9, 0x73,
- 0x7e, 0xe6, 0x8d, 0x5e, 0xc4, 0xa6, 0xe6, 0xd2, 0x81, 0x61, 0xfb, 0x2c,
- 0x69, 0x07, 0xba, 0xed, 0x73, 0xaa, 0xed, 0xf9, 0xf3, 0xa4, 0xcb, 0xa1,
- 0x65, 0x0b, 0x7c, 0x4b, 0xd6, 0x64, 0xe5, 0x6c, 0x85, 0x45, 0x1f, 0x14,
- 0xfe, 0x70, 0x40, 0x51, 0x93, 0xf6, 0xba, 0xe7, 0x32, 0x07, 0x42, 0xcd,
- 0x2d, 0x0a, 0xe2, 0x25, 0x46, 0x28, 0xf0, 0x4e, 0x1e, 0x2b, 0x5d, 0x23,
- 0xeb, 0x94, 0xa2, 0x91, 0x1e, 0xc5, 0x39, 0x92, 0xc3, 0x4a, 0xc7, 0x88,
- 0xf0, 0xfb, 0x6a, 0x96, 0xf1, 0x62, 0xd6, 0x3c, 0x27, 0x5e, 0x48, 0x54,
- 0xd8, 0xef, 0x34, 0xac, 0x9f, 0x57, 0x84, 0x07, 0x23, 0x0a, 0x5a, 0xe7,
- 0x1c, 0xc6, 0x49, 0xe6, 0x32, 0x87, 0x13, 0x66, 0x64, 0x88, 0x6d, 0x4e,
- 0x24, 0x54, 0x1c, 0x1a, 0x58, 0x17, 0x19, 0xb4, 0xdb, 0x37, 0xd1, 0x6d,
- 0xef, 0x5b, 0x2d, 0xb3, 0x36, 0xa6, 0x96, 0x5b, 0x1b, 0x52, 0x4e, 0xe6,
- 0x9f, 0xd5, 0xf1, 0x4a, 0xd6, 0x3f, 0x39, 0x6f, 0x15, 0x4e, 0xb1, 0xcc,
- 0x48, 0x62, 0x35, 0x3e, 0xc8, 0x7a, 0xed, 0xf5, 0x9a, 0x1f, 0x64, 0x3d,
- 0xcc, 0xa7, 0x5a, 0xf1, 0x42, 0x76, 0x19, 0x9e, 0x1f, 0x90, 0x33, 0xe4,
- 0x2d, 0x58, 0x90, 0x50, 0xb0, 0x38, 0xb4, 0x0c, 0xc7, 0x86, 0x96, 0xe1,
- 0xf0, 0x80, 0xbc, 0x47, 0x70, 0x45, 0xfe, 0xcc, 0xb9, 0x3c, 0x8f, 0xf1,
- 0xf9, 0x52, 0x4c, 0x0c, 0xf9, 0x99, 0x0b, 0xe9, 0x78, 0x33, 0xeb, 0xc3,
- 0x60, 0xa2, 0x11, 0xc7, 0xc9, 0xe7, 0x9f, 0x49, 0x34, 0xe3, 0x2c, 0xaf,
- 0x0f, 0x24, 0x84, 0x07, 0x45, 0x71, 0x26, 0xfb, 0x7d, 0x14, 0x25, 0x6b,
- 0x71, 0xa4, 0xed, 0x69, 0xa8, 0xc9, 0x03, 0xfc, 0xb4, 0xe2, 0xf8, 0x50,
- 0x2b, 0x4e, 0x0c, 0xdc, 0x86, 0x13, 0x43, 0x3f, 0xc3, 0xc9, 0x01, 0xe9,
- 0xaf, 0x9c, 0x2b, 0x17, 0xb9, 0x1a, 0xe5, 0x2e, 0xc3, 0xf8, 0xd0, 0x9f,
- 0x23, 0xfb, 0x3d, 0xeb, 0xc8, 0x32, 0x91, 0xfb, 0xf4, 0x27, 0xc8, 0xce,
- 0xe5, 0x4a, 0x72, 0x66, 0xf4, 0x58, 0xc2, 0x8d, 0xa3, 0x89, 0xf1, 0x6b,
- 0x4b, 0x30, 0x7e, 0x23, 0x91, 0x0e, 0x1b, 0x99, 0xc3, 0x1d, 0x4a, 0xcb,
- 0xba, 0xdf, 0x67, 0x98, 0x17, 0xaf, 0xc3, 0xfa, 0xb1, 0x62, 0xbc, 0x90,
- 0x76, 0x53, 0xc7, 0x37, 0x22, 0x56, 0xd5, 0x4e, 0xfd, 0x79, 0xf0, 0x62,
- 0xc2, 0x87, 0x97, 0x12, 0x0d, 0x8c, 0x0f, 0x4d, 0xc8, 0xad, 0x77, 0x7a,
- 0xa8, 0xef, 0x0e, 0xbb, 0x4f, 0x2f, 0x24, 0x96, 0x59, 0xeb, 0xa9, 0xe3,
- 0x9e, 0xd4, 0xd7, 0xec, 0x33, 0xe1, 0xcf, 0x27, 0xce, 0x30, 0x27, 0x39,
- 0x8a, 0xc7, 0xa9, 0xd3, 0x63, 0x89, 0x38, 0x39, 0x63, 0x1d, 0xe7, 0x68,
- 0x1c, 0x43, 0xd9, 0xb5, 0x78, 0x33, 0xad, 0x1d, 0x5d, 0x81, 0xb5, 0x38,
- 0x9b, 0x29, 0xc6, 0xeb, 0x6c, 0xa3, 0x72, 0xae, 0x13, 0x93, 0xb6, 0xbc,
- 0xb5, 0xf8, 0x20, 0xad, 0x30, 0x8e, 0xaf, 0xc5, 0xfb, 0x7c, 0xf6, 0x32,
- 0x7f, 0x9f, 0x8a, 0xb0, 0x87, 0xf9, 0x67, 0x27, 0xc8, 0xeb, 0x65, 0x7d,
- 0xab, 0x2b, 0xba, 0x16, 0xc7, 0x33, 0xcf, 0x92, 0x0b, 0x57, 0xe2, 0x61,
- 0x7d, 0x1a, 0x9a, 0xa7, 0x91, 0x8b, 0x69, 0xc5, 0x38, 0xc6, 0xe7, 0x33,
- 0x89, 0xbf, 0xe3, 0xde, 0x5c, 0xf9, 0xf7, 0x38, 0x9e, 0x07, 0x29, 0xeb,
- 0xdd, 0xcc, 0x37, 0x29, 0x77, 0x3e, 0xb2, 0x91, 0x6f, 0x52, 0xee, 0xcf,
- 0x30, 0x9c, 0xd7, 0xc7, 0x71, 0x5d, 0xc6, 0xf5, 0xf5, 0x72, 0xc9, 0xa9,
- 0x27, 0x12, 0xdf, 0xe0, 0x77, 0x07, 0x26, 0xb3, 0x3b, 0xf8, 0xfd, 0x03,
- 0xec, 0x63, 0x8c, 0x4e, 0xa4, 0x2e, 0xe5, 0xe3, 0xd3, 0xb1, 0xa9, 0xaf,
- 0x22, 0x5e, 0x45, 0xfb, 0x89, 0x5c, 0x5f, 0x89, 0xd9, 0x91, 0x04, 0x36,
- 0xef, 0x76, 0x62, 0x13, 0xf1, 0x76, 0x73, 0xb2, 0x1a, 0x3b, 0xb7, 0x79,
- 0x91, 0xda, 0x76, 0x25, 0x7a, 0xb7, 0x5d, 0x8d, 0xe4, 0xb6, 0x3a, 0x6c,
- 0xdc, 0x46, 0x9d, 0xcf, 0xb5, 0xac, 0x93, 0x11, 0xcb, 0x3a, 0xcc, 0xcf,
- 0x5e, 0x7e, 0xde, 0xd3, 0xc5, 0x3f, 0x62, 0x08, 0xdb, 0x7e, 0xd2, 0x42,
- 0x3f, 0x91, 0x6f, 0x0d, 0xd7, 0x64, 0xd7, 0x44, 0x66, 0x8e, 0xae, 0x8d,
- 0x34, 0x8c, 0x4e, 0x47, 0x77, 0x5f, 0x0d, 0xd6, 0x6f, 0xab, 0x8e, 0x7b,
- 0xd9, 0x8e, 0xf7, 0x7a, 0x0b, 0x9d, 0xf4, 0x9f, 0x67, 0xf4, 0x9e, 0xc8,
- 0xfc, 0xd1, 0xa7, 0xc9, 0x43, 0x7d, 0xd8, 0xd9, 0xe7, 0x67, 0x1b, 0x0a,
- 0x2a, 0x35, 0xe7, 0xaa, 0x4a, 0x8e, 0xe3, 0x68, 0xe4, 0x00, 0xca, 0x47,
- 0xbf, 0x4f, 0x9e, 0xe7, 0xc3, 0xc6, 0xbe, 0x22, 0x79, 0x4f, 0x08, 0xbd,
- 0x51, 0x0b, 0xef, 0xe9, 0xe3, 0x28, 0xa3, 0xbc, 0xae, 0xbe, 0x0a, 0x74,
- 0x6f, 0xf3, 0x50, 0x66, 0x05, 0x1e, 0xdb, 0x56, 0x1a, 0x2f, 0x32, 0x44,
- 0xde, 0x12, 0xfc, 0x74, 0xe4, 0x6b, 0xd8, 0x34, 0xe6, 0x41, 0x0f, 0xef,
- 0xaf, 0xdb, 0xe6, 0x75, 0xbf, 0xc0, 0x3a, 0xed, 0x6c, 0xeb, 0xbf, 0xf1,
- 0xf3, 0x01, 0xfb, 0x5d, 0x1c, 0x59, 0x83, 0xcd, 0x63, 0xc2, 0x6d, 0x8e,
- 0xc2, 0x3f, 0xda, 0x8a, 0x97, 0x47, 0xda, 0xf0, 0xb7, 0x23, 0xff, 0xea,
- 0x41, 0xc5, 0x32, 0xdc, 0x3f, 0x22, 0xfb, 0xee, 0x71, 0xdc, 0x93, 0x10,
- 0x3c, 0x5a, 0x89, 0x3d, 0x09, 0xd9, 0xbf, 0x6c, 0xc7, 0xb3, 0x09, 0xb1,
- 0xdf, 0xe5, 0xb4, 0xdf, 0x0e, 0xe6, 0x74, 0x92, 0x47, 0x64, 0x22, 0xf5,
- 0xa3, 0xdf, 0x8e, 0x5c, 0x33, 0xfa, 0x73, 0x72, 0xf0, 0xa1, 0x48, 0x68,
- 0x74, 0x27, 0xc7, 0x39, 0x49, 0x5e, 0x7d, 0x82, 0x5c, 0xfb, 0x75, 0x72,
- 0xe1, 0x42, 0x1c, 0xfc, 0xaf, 0xce, 0x5c, 0x8e, 0x52, 0xc8, 0x03, 0x0b,
- 0x6b, 0xed, 0x96, 0xe5, 0x60, 0x9e, 0xb3, 0xd0, 0x2b, 0xb9, 0x42, 0x17,
- 0xd6, 0xef, 0x58, 0x8d, 0x0d, 0x3b, 0x1a, 0xbc, 0x7b, 0x19, 0xb3, 0x62,
- 0x3e, 0xe1, 0xee, 0xf9, 0xfc, 0xee, 0xfc, 0x1a, 0x98, 0xac, 0xd9, 0x77,
- 0xd0, 0xe7, 0xd7, 0xd9, 0xe7, 0x38, 0x4b, 0x35, 0x04, 0x4a, 0xb4, 0xdf,
- 0x5a, 0xb1, 0xf3, 0xf5, 0xdb, 0x2d, 0x59, 0x97, 0x2d, 0x36, 0x14, 0x8c,
- 0x69, 0x6d, 0xf6, 0x7e, 0xd8, 0x71, 0x9b, 0x8f, 0x75, 0x21, 0x35, 0x4c,
- 0x6e, 0xbc, 0x4b, 0xc6, 0xb1, 0x52, 0xc6, 0x61, 0xaa, 0xda, 0x32, 0x6b,
- 0x5d, 0x0a, 0xb7, 0x16, 0x31, 0xbf, 0x58, 0x35, 0x52, 0x84, 0xf8, 0x9e,
- 0x52, 0xdc, 0xb3, 0x6d, 0xb9, 0x95, 0x4a, 0x09, 0xff, 0x96, 0x3c, 0xbb,
- 0x14, 0x9d, 0xbc, 0xb7, 0xa6, 0x4f, 0xf6, 0x21, 0x42, 0x1d, 0xb5, 0x8e,
- 0x52, 0x3c, 0xb4, 0x8b, 0xfd, 0xd8, 0xb5, 0x04, 0xf1, 0x5d, 0x47, 0x60,
- 0x66, 0x54, 0x8c, 0x0c, 0x38, 0xe1, 0x37, 0x4e, 0x93, 0x6f, 0xfd, 0x0c,
- 0xc9, 0x21, 0x15, 0xd9, 0x01, 0x45, 0xdb, 0x18, 0x1a, 0xc5, 0xc6, 0x21,
- 0x27, 0xf6, 0x26, 0x5a, 0xf0, 0x36, 0x71, 0x6e, 0x30, 0x11, 0xc3, 0x71,
- 0xea, 0x76, 0x72, 0xcf, 0x32, 0x7e, 0x3c, 0xf4, 0xf7, 0x83, 0xf4, 0x9d,
- 0x30, 0xba, 0xe9, 0x47, 0x07, 0x13, 0x1a, 0x1e, 0xcb, 0xde, 0x0c, 0x73,
- 0xe8, 0x0e, 0x6c, 0x1e, 0x32, 0xf1, 0xe8, 0x8e, 0x36, 0x7e, 0x1b, 0x78,
- 0x74, 0xe8, 0x6b, 0x58, 0x33, 0x72, 0x14, 0x9b, 0xb2, 0x71, 0xbc, 0x33,
- 0xf2, 0x2c, 0x92, 0x69, 0x9d, 0xbe, 0x21, 0xdc, 0x4d, 0xc1, 0xe6, 0x79,
- 0xcf, 0x62, 0x73, 0xe6, 0x30, 0x36, 0xa6, 0x3b, 0xc9, 0x09, 0x0f, 0x63,
- 0x03, 0x7f, 0xaf, 0x4f, 0x6b, 0xfe, 0x41, 0x1c, 0x46, 0x77, 0x66, 0x2d,
- 0x3a, 0xfb, 0x44, 0x5f, 0x0a, 0xce, 0xde, 0xb0, 0x16, 0x0f, 0xef, 0xea,
- 0xc0, 0x03, 0x23, 0x3f, 0xc0, 0xce, 0xec, 0xb3, 0xe8, 0x4d, 0x27, 0x90,
- 0xda, 0x2a, 0xfa, 0xac, 0xc4, 0x0f, 0x22, 0x78, 0xa0, 0x12, 0xa1, 0xb6,
- 0xa4, 0x22, 0xb2, 0xd6, 0x60, 0x13, 0xfd, 0x7a, 0x63, 0x4a, 0xf4, 0xfb,
- 0x34, 0xdb, 0x3c, 0x40, 0xbc, 0x58, 0x43, 0x7d, 0x3c, 0xc2, 0x4f, 0x61,
- 0xcf, 0x76, 0xea, 0x3e, 0x83, 0xf8, 0x8b, 0xdf, 0xce, 0xe5, 0x4b, 0x7b,
- 0x25, 0xaf, 0x1c, 0x0f, 0x96, 0x92, 0x8b, 0x94, 0xf4, 0x8a, 0x3e, 0xdb,
- 0xad, 0xae, 0xd4, 0xf8, 0x67, 0x4b, 0x20, 0x73, 0x10, 0x20, 0x76, 0xff,
- 0x0c, 0xeb, 0xe9, 0x8f, 0xb7, 0xca, 0xe1, 0x15, 0xc6, 0xa1, 0x43, 0xf4,
- 0xe7, 0xb8, 0xcf, 0xb2, 0x9e, 0xd2, 0x59, 0xad, 0xb7, 0x83, 0x78, 0xe5,
- 0xca, 0xef, 0xc5, 0x8d, 0x5f, 0x5b, 0x41, 0x19, 0xe5, 0xbd, 0x5d, 0x72,
- 0xe6, 0x45, 0xcf, 0xe5, 0xbc, 0x96, 0xb5, 0x25, 0x54, 0xb0, 0x9f, 0xf1,
- 0x6b, 0xcb, 0x31, 0x4d, 0xd6, 0x8f, 0x9b, 0x73, 0xef, 0xc1, 0x9d, 0x63,
- 0x5c, 0xec, 0xc2, 0x96, 0xe1, 0xb6, 0xbc, 0x1d, 0xfd, 0xbf, 0x92, 0x77,
- 0xb9, 0x3d, 0xbe, 0x6b, 0xec, 0x75, 0x1f, 0xd8, 0x67, 0xea, 0x81, 0x7b,
- 0x13, 0xb2, 0x6f, 0xa2, 0xde, 0x40, 0x56, 0x45, 0x0b, 0x2d, 0xc6, 0x61,
- 0xfd, 0x4a, 0x74, 0x93, 0x77, 0xde, 0xa2, 0x17, 0x61, 0xb8, 0xd1, 0xc0,
- 0xa4, 0xd7, 0x6c, 0x13, 0xce, 0x56, 0x66, 0x8c, 0xb7, 0x7f, 0x39, 0x14,
- 0x94, 0xbc, 0x10, 0x61, 0x62, 0x08, 0x6c, 0xce, 0xd6, 0x83, 0x64, 0x4a,
- 0x81, 0x47, 0xbb, 0x03, 0xd9, 0x2a, 0x9f, 0xb4, 0x1f, 0x2e, 0x9c, 0xbf,
- 0x2c, 0xd6, 0xce, 0xe5, 0xdf, 0x7d, 0x5b, 0xc2, 0xf9, 0xa0, 0x6d, 0xcf,
- 0xb4, 0xac, 0xb6, 0x48, 0x00, 0xf5, 0xa1, 0x86, 0x40, 0x95, 0xfa, 0x0b,
- 0xcb, 0x94, 0x3d, 0xa9, 0x31, 0x39, 0x0f, 0x78, 0xb9, 0xfc, 0xfd, 0x21,
- 0x6c, 0xdc, 0x3a, 0x07, 0x93, 0x3e, 0x91, 0xf9, 0x44, 0x79, 0x4e, 0x8e,
- 0xac, 0x5f, 0xbc, 0x5a, 0x81, 0xd2, 0x1e, 0xfa, 0x4a, 0x0f, 0x7a, 0x52,
- 0x2a, 0xdb, 0x78, 0xd3, 0x2a, 0x9e, 0x2e, 0xe3, 0xfe, 0x1f, 0x15, 0xb9,
- 0x32, 0xaf, 0x55, 0x08, 0xbf, 0xd8, 0x94, 0xea, 0xa1, 0xee, 0x54, 0xc6,
- 0x9b, 0x7f, 0xb1, 0x8e, 0xf8, 0xaa, 0xf9, 0x3c, 0x9e, 0x97, 0xb1, 0x4e,
- 0xd6, 0xd1, 0xf4, 0x18, 0xe4, 0xde, 0x2b, 0x2c, 0x2b, 0xfa, 0xea, 0xa1,
- 0x1e, 0x1c, 0xe4, 0x9e, 0x3e, 0x74, 0x7a, 0x73, 0x6b, 0x34, 0x17, 0xc6,
- 0x21, 0x65, 0x64, 0x2c, 0x3d, 0x48, 0xa5, 0x64, 0x1f, 0xe3, 0xac, 0x75,
- 0x6a, 0xba, 0x3c, 0x2f, 0xc9, 0xb7, 0x57, 0x6b, 0xef, 0xad, 0x3d, 0x9a,
- 0x72, 0x4c, 0xe9, 0x9b, 0xd4, 0xb5, 0x65, 0xb3, 0xfe, 0xa7, 0x2e, 0x69,
- 0xd7, 0x6b, 0x73, 0x72, 0xd5, 0x9e, 0xa7, 0x57, 0xf2, 0xe5, 0xcb, 0xcb,
- 0x0b, 0xef, 0x2f, 0xc8, 0xd9, 0xde, 0x0b, 0x6d, 0x4f, 0x2d, 0x23, 0x6b,
- 0x01, 0xb9, 0xba, 0xcd, 0x3b, 0x0a, 0xf2, 0x2d, 0xab, 0x68, 0x6e, 0x3b,
- 0x6d, 0xd4, 0xea, 0x2c, 0x26, 0x46, 0xbe, 0x1d, 0xf5, 0x63, 0x7d, 0x42,
- 0x74, 0xa4, 0xf9, 0xf7, 0x12, 0x03, 0xba, 0x6d, 0x4e, 0xe1, 0x42, 0x57,
- 0xa6, 0x70, 0xde, 0x44, 0xd6, 0x3d, 0xe5, 0xdc, 0x9a, 0xbc, 0x87, 0x43,
- 0x2e, 0xe5, 0x5d, 0x10, 0x70, 0x92, 0x0f, 0xdd, 0x8b, 0xff, 0xe0, 0x5c,
- 0xc8, 0xfb, 0x24, 0xb9, 0x35, 0x91, 0x38, 0x6d, 0x20, 0x17, 0x93, 0x40,
- 0x5f, 0x27, 0x17, 0xca, 0x9f, 0xb3, 0xef, 0xca, 0xfe, 0x87, 0x35, 0x6e,
- 0x9f, 0xb3, 0xbf, 0x70, 0xa6, 0x23, 0xe3, 0x95, 0x77, 0x39, 0x31, 0xe5,
- 0xcc, 0x3d, 0x63, 0x88, 0x26, 0x67, 0xf3, 0x7f, 0x67, 0xad, 0xb8, 0xa8,
- 0xec, 0x78, 0x55, 0xee, 0x1d, 0x94, 0x98, 0xba, 0x40, 0x2b, 0xf0, 0x3b,
- 0xd9, 0x57, 0x12, 0x5e, 0x77, 0x77, 0x65, 0x6e, 0xbd, 0x35, 0xd8, 0xda,
- 0x06, 0xd9, 0xdb, 0x2e, 0xf0, 0x35, 0x4d, 0x9f, 0xad, 0x74, 0x62, 0x56,
- 0xa4, 0x54, 0xde, 0xa9, 0x0d, 0x3a, 0x8d, 0xa0, 0xf7, 0x24, 0x42, 0xe1,
- 0xc3, 0xf6, 0x59, 0x0c, 0xf1, 0x6d, 0x0d, 0xf7, 0x66, 0x1b, 0xa9, 0x1b,
- 0x79, 0x1f, 0x5a, 0x7e, 0xdb, 0xf2, 0xf9, 0x1b, 0xee, 0x72, 0x62, 0xfb,
- 0x48, 0xd2, 0xfc, 0xaf, 0x2e, 0x5b, 0x5e, 0xb0, 0x7d, 0xc8, 0x7e, 0x57,
- 0xa9, 0x20, 0xcf, 0x73, 0x19, 0x79, 0x61, 0xd6, 0x0f, 0x53, 0x96, 0xc8,
- 0xd0, 0x28, 0xe3, 0xd2, 0xf3, 0x39, 0xd3, 0xe3, 0x92, 0x23, 0xef, 0xcb,
- 0xf3, 0xbe, 0xc3, 0x7f, 0x90, 0x23, 0x5f, 0xb6, 0xcd, 0x18, 0xdb, 0x6c,
- 0x2d, 0x55, 0x62, 0x11, 0x79, 0x57, 0xa8, 0x38, 0x12, 0x0a, 0x3f, 0x47,
- 0xe7, 0x74, 0x1a, 0x21, 0xff, 0x90, 0x7d, 0x66, 0x44, 0x77, 0x2f, 0xcc,
- 0xe6, 0xf2, 0x29, 0x73, 0xec, 0x93, 0x75, 0x52, 0xa6, 0x69, 0x6d, 0x0d,
- 0x4a, 0xec, 0x46, 0x22, 0x38, 0xc2, 0x11, 0x04, 0x8a, 0x8c, 0x82, 0x8e,
- 0x42, 0xe1, 0x93, 0x9c, 0xcf, 0x89, 0x68, 0x88, 0x78, 0x29, 0x5c, 0x49,
- 0xf4, 0xa2, 0xbb, 0x73, 0x73, 0xdf, 0x28, 0x9c, 0xda, 0x74, 0x31, 0xee,
- 0x0d, 0x27, 0x64, 0x9d, 0xab, 0xc1, 0xbb, 0x11, 0x55, 0xb4, 0x57, 0xc4,
- 0xba, 0x1b, 0xe3, 0xd8, 0x97, 0x40, 0xcc, 0x31, 0xa7, 0x12, 0x71, 0x92,
- 0x64, 0x87, 0x16, 0x27, 0xef, 0x69, 0x08, 0x6f, 0xa2, 0x0d, 0xca, 0xd9,
- 0x46, 0x13, 0x71, 0x1c, 0x4a, 0x2c, 0xf8, 0x4b, 0x07, 0x4c, 0xbd, 0x0c,
- 0xf2, 0xae, 0x16, 0xbe, 0x78, 0x5b, 0x28, 0x18, 0x78, 0x3e, 0x7f, 0xe6,
- 0xa5, 0x2b, 0xf1, 0x91, 0xbd, 0xa7, 0xe5, 0xd0, 0x3e, 0xa9, 0x8c, 0xdb,
- 0x5e, 0xc7, 0xdd, 0x9b, 0xfe, 0x36, 0xd6, 0x6d, 0x65, 0x1f, 0x99, 0xdf,
- 0x2f, 0xd0, 0x3b, 0xb1, 0x50, 0xf7, 0x60, 0xa5, 0x77, 0x56, 0xb3, 0x9c,
- 0xe9, 0x19, 0xcc, 0xe4, 0xd6, 0x3d, 0xd6, 0xdb, 0x67, 0x6a, 0x06, 0xb0,
- 0x99, 0x3e, 0x56, 0xa2, 0xc9, 0xb9, 0xab, 0x98, 0xb2, 0x39, 0xdb, 0xa2,
- 0x6c, 0xca, 0xaf, 0xb3, 0xf5, 0x64, 0x5f, 0xaf, 0x44, 0xa9, 0x89, 0xe3,
- 0xba, 0xbc, 0x23, 0x29, 0x72, 0x4d, 0x0c, 0x45, 0xff, 0x94, 0x77, 0x25,
- 0x45, 0xa7, 0x6b, 0xd0, 0x3d, 0xf0, 0x08, 0xba, 0x06, 0x5e, 0xb4, 0xcf,
- 0xb6, 0xba, 0x34, 0xb7, 0x79, 0xb5, 0x11, 0x3c, 0x60, 0xe2, 0x69, 0xaf,
- 0xac, 0xe7, 0xd6, 0x18, 0x47, 0xb1, 0xd9, 0x2b, 0xef, 0x00, 0x0e, 0x90,
- 0x03, 0x08, 0xce, 0x2d, 0xc7, 0x97, 0x93, 0x32, 0x87, 0x15, 0xc4, 0xfc,
- 0x60, 0x6c, 0xa5, 0x3d, 0x87, 0x8d, 0x38, 0x36, 0xfa, 0x08, 0xde, 0xde,
- 0xde, 0x09, 0x35, 0x12, 0xf4, 0x2f, 0x82, 0xd5, 0x79, 0x44, 0x8f, 0x99,
- 0x2e, 0x04, 0xf7, 0x39, 0x54, 0xe0, 0xe0, 0x76, 0xc9, 0x69, 0xdb, 0x71,
- 0x23, 0x63, 0x6d, 0xa5, 0x66, 0xcd, 0xff, 0xb7, 0xb9, 0xc1, 0x1e, 0xcd,
- 0x61, 0xfe, 0xf3, 0x74, 0x04, 0xd3, 0xcd, 0xaa, 0xd6, 0x7e, 0xa7, 0x0a,
- 0xc5, 0x63, 0xc8, 0x7b, 0xeb, 0x9d, 0xb8, 0xa3, 0xc9, 0x63, 0x96, 0x1b,
- 0xc1, 0xf4, 0x8b, 0x4a, 0x30, 0x6c, 0xaa, 0x9f, 0xe7, 0x3c, 0x87, 0xf1,
- 0xfc, 0xa8, 0x17, 0xad, 0xbd, 0x3a, 0x16, 0xf7, 0x36, 0xda, 0xb8, 0xa5,
- 0x6a, 0xf5, 0xcd, 0x25, 0x8a, 0x17, 0x8b, 0x46, 0x81, 0x89, 0xcc, 0x72,
- 0xbc, 0xb9, 0x5d, 0x47, 0x0b, 0x9f, 0xf5, 0xa5, 0x9e, 0xaa, 0x94, 0xb3,
- 0x6f, 0x1d, 0xba, 0xd9, 0xa0, 0x22, 0x74, 0xd4, 0xa5, 0x62, 0xc1, 0x0c,
- 0x23, 0x34, 0x3e, 0xdf, 0xe1, 0x44, 0xf3, 0xa8, 0x13, 0x77, 0xb1, 0xcc,
- 0x46, 0x62, 0xfa, 0x9d, 0xbd, 0x6e, 0xf2, 0x87, 0x3a, 0x7c, 0x48, 0xae,
- 0xfb, 0x2b, 0x72, 0xda, 0x49, 0xc6, 0xe6, 0xc9, 0x6c, 0x29, 0xda, 0xfa,
- 0x5d, 0x72, 0x8e, 0x67, 0xdc, 0xc5, 0xb9, 0xa8, 0x68, 0xf2, 0xe1, 0xd4,
- 0x90, 0x1b, 0x9f, 0xdb, 0x1e, 0xdc, 0x39, 0xa9, 0xd6, 0xe0, 0x83, 0xa1,
- 0x52, 0x7b, 0xbd, 0xb2, 0xdc, 0xb0, 0xb0, 0x85, 0x38, 0xfd, 0x1e, 0x9f,
- 0xb5, 0x6c, 0x87, 0x92, 0x9d, 0x77, 0x0d, 0x79, 0xb9, 0xc6, 0xfa, 0x65,
- 0xb8, 0xad, 0x5f, 0xd6, 0x68, 0x54, 0xbc, 0x33, 0xa4, 0xe0, 0x64, 0x46,
- 0xc7, 0x02, 0xb6, 0xd7, 0x9d, 0x3a, 0x68, 0xb9, 0xe9, 0xe7, 0x2b, 0xb2,
- 0x3a, 0xee, 0xcb, 0x34, 0xa2, 0x37, 0xf5, 0x06, 0x39, 0x50, 0x13, 0xde,
- 0xd8, 0xa6, 0x1d, 0x7d, 0xcb, 0x11, 0x1a, 0x9f, 0xe7, 0x68, 0xc2, 0xeb,
- 0x7b, 0x9a, 0xf0, 0xc3, 0xbe, 0xf9, 0xf8, 0x74, 0x53, 0x0c, 0xa7, 0xe7,
- 0x35, 0xe1, 0x95, 0x5d, 0x8d, 0xc4, 0xe8, 0x28, 0x02, 0x23, 0xe3, 0xd8,
- 0x92, 0x6c, 0x46, 0xc3, 0x88, 0x01, 0xad, 0xcf, 0xea, 0x2c, 0x33, 0x3a,
- 0xb1, 0x59, 0x37, 0x30, 0x7b, 0x97, 0xe8, 0xc1, 0xb2, 0x56, 0xce, 0x33,
- 0xf0, 0x5c, 0x5a, 0xa3, 0x9f, 0x1a, 0xd4, 0x43, 0x23, 0x71, 0xd6, 0x40,
- 0x68, 0xab, 0x76, 0x66, 0x37, 0xaf, 0xe7, 0xef, 0x8e, 0xa2, 0x9d, 0xed,
- 0x27, 0x52, 0x31, 0xec, 0x1c, 0x69, 0xe4, 0x98, 0x75, 0x8e, 0xbf, 0xde,
- 0xfc, 0x50, 0x69, 0x41, 0x7a, 0xa4, 0x15, 0xbd, 0x7d, 0x9d, 0x78, 0x31,
- 0xd2, 0x8a, 0x24, 0x65, 0xad, 0x4f, 0xe9, 0xb8, 0xad, 0xb7, 0x15, 0xfb,
- 0x13, 0x72, 0x96, 0x5e, 0x6b, 0xbe, 0x5e, 0x09, 0xe9, 0x27, 0xd1, 0x8a,
- 0xbd, 0xd4, 0xc9, 0x82, 0xfe, 0x25, 0xf6, 0xb9, 0xa1, 0x85, 0xdb, 0x1b,
- 0xf1, 0x58, 0xea, 0x0e, 0xbc, 0x39, 0xac, 0xa3, 0xad, 0x57, 0xf4, 0x2d,
- 0xe7, 0x27, 0xe3, 0x38, 0x92, 0x5a, 0x8b, 0x0f, 0xfb, 0x63, 0xff, 0xcc,
- 0x69, 0x3e, 0xa6, 0xda, 0xfb, 0x5d, 0x2a, 0xae, 0x6b, 0x92, 0x73, 0xad,
- 0x0e, 0xa2, 0x5a, 0xd0, 0xac, 0x54, 0xcd, 0x00, 0xef, 0x9b, 0x4e, 0x75,
- 0x2d, 0xfe, 0xb6, 0xdf, 0x49, 0xde, 0xae, 0x32, 0xdf, 0x30, 0x3b, 0x68,
- 0x1b, 0x66, 0x85, 0x9a, 0x9b, 0x37, 0x7b, 0x7f, 0x40, 0x73, 0x40, 0xce,
- 0xbd, 0x96, 0xb1, 0xde, 0xe2, 0x48, 0x30, 0x56, 0xa2, 0x46, 0xc9, 0x27,
- 0x1e, 0xc1, 0xca, 0xed, 0x8f, 0x60, 0x05, 0x3f, 0x1d, 0xdb, 0xad, 0xce,
- 0x5b, 0x75, 0x05, 0x87, 0x34, 0xab, 0xb3, 0x53, 0xd7, 0x38, 0xb7, 0x32,
- 0xaf, 0x8f, 0x60, 0xcd, 0xde, 0x47, 0xf0, 0x15, 0xda, 0x57, 0x35, 0xfd,
- 0x78, 0x69, 0xaf, 0xd5, 0xf9, 0xe9, 0xa6, 0x30, 0x7e, 0x6d, 0xe7, 0x18,
- 0x62, 0xaf, 0x5b, 0xec, 0xbc, 0x37, 0xa3, 0xca, 0xef, 0xbf, 0xb7, 0x7f,
- 0x9b, 0xea, 0x2b, 0xf9, 0xbd, 0xa8, 0x35, 0xf8, 0x88, 0x72, 0x7f, 0xb3,
- 0xbd, 0x12, 0x5b, 0xab, 0x25, 0x66, 0xb8, 0xcd, 0x12, 0x03, 0x8a, 0x36,
- 0x8f, 0xb9, 0xd4, 0xd6, 0x23, 0x36, 0xdf, 0xf2, 0x45, 0x24, 0xcf, 0x6d,
- 0xd0, 0xd7, 0xa9, 0x37, 0x13, 0xdb, 0xc9, 0xc5, 0x66, 0x7e, 0x1b, 0x49,
- 0xfa, 0xea, 0x96, 0x99, 0xc1, 0x78, 0x12, 0x86, 0xb5, 0x65, 0xfa, 0xc0,
- 0x9f, 0xf1, 0x7e, 0x6c, 0x61, 0xdf, 0x4d, 0xde, 0x91, 0x7d, 0x04, 0x9d,
- 0xdb, 0x65, 0xfe, 0x1f, 0xc1, 0xc3, 0xec, 0xff, 0x9a, 0xfe, 0x47, 0xf0,
- 0x10, 0x6d, 0xa7, 0x6a, 0xee, 0xc4, 0xc3, 0x55, 0x98, 0xc5, 0x4c, 0x68,
- 0xfc, 0x81, 0x6a, 0x39, 0xf3, 0x4a, 0x4c, 0x4c, 0x2a, 0x8f, 0xe0, 0xde,
- 0xc1, 0xfd, 0xf4, 0x45, 0xdb, 0xff, 0x88, 0xc5, 0x85, 0x78, 0xe5, 0xc7,
- 0xca, 0x6c, 0x5d, 0x1e, 0xd7, 0x7d, 0x58, 0x91, 0x78, 0xd2, 0xf6, 0xfd,
- 0x22, 0x63, 0x09, 0xfd, 0xbe, 0x95, 0x7e, 0xdf, 0x42, 0xbf, 0x8f, 0xd1,
- 0xef, 0x0d, 0xfa, 0x7d, 0x33, 0xfd, 0x3e, 0x4a, 0xbf, 0xd7, 0xe9, 0xf7,
- 0x8d, 0xf4, 0xfb, 0xb0, 0xec, 0x47, 0x28, 0x47, 0xa3, 0x47, 0xe0, 0xea,
- 0x73, 0xd3, 0x86, 0x72, 0xef, 0x3d, 0xee, 0x21, 0xfe, 0x1c, 0xd7, 0x67,
- 0xfb, 0x6f, 0x61, 0x2c, 0x1d, 0x22, 0x46, 0x64, 0x86, 0xbf, 0x6d, 0xbf,
- 0x23, 0x97, 0x21, 0xee, 0x3f, 0x4f, 0x7d, 0x2c, 0x8e, 0xd4, 0xeb, 0xfb,
- 0x19, 0xc3, 0x7e, 0xa4, 0x35, 0xf4, 0xf8, 0x58, 0xe6, 0xbb, 0xa9, 0x86,
- 0xf4, 0x34, 0x68, 0x66, 0x93, 0xba, 0x1e, 0x58, 0xea, 0xe3, 0x98, 0x65,
- 0xbf, 0x6e, 0x29, 0x1e, 0x1e, 0x68, 0xc3, 0xdf, 0x0d, 0x78, 0xa9, 0x8b,
- 0xfa, 0xf1, 0x9b, 0x1d, 0xf8, 0xbe, 0x1f, 0x0e, 0xdf, 0x15, 0xc0, 0x7f,
- 0xd6, 0x60, 0xf6, 0x3e, 0x79, 0xcf, 0x3a, 0x53, 0xe3, 0x68, 0x9c, 0x01,
- 0xb1, 0x11, 0x10, 0xa9, 0x1d, 0xcc, 0xf6, 0x66, 0xdb, 0xef, 0x74, 0xc6,
- 0x96, 0x09, 0xa6, 0x97, 0x60, 0x7d, 0xd8, 0xc6, 0xd9, 0x27, 0x65, 0xff,
- 0xb0, 0x86, 0x78, 0xe4, 0x31, 0x5a, 0xb1, 0x21, 0x69, 0x7e, 0xb1, 0x86,
- 0x5c, 0xa9, 0x27, 0x99, 0xd3, 0xc1, 0x03, 0x11, 0xaa, 0xc4, 0x90, 0xff,
- 0x19, 0x01, 0x67, 0x47, 0xb4, 0x19, 0xf7, 0x65, 0x77, 0x22, 0xcd, 0xb1,
- 0xae, 0xa2, 0x9f, 0xad, 0xfc, 0xe3, 0xef, 0xc5, 0xe3, 0xa1, 0x44, 0x80,
- 0xf6, 0x7f, 0xce, 0xca, 0x54, 0xcd, 0x4e, 0xd7, 0x40, 0x5b, 0x73, 0x97,
- 0x7a, 0x3d, 0xf3, 0xd6, 0xe0, 0x01, 0x3e, 0x32, 0xa7, 0xdb, 0xe7, 0xd1,
- 0xdc, 0xb8, 0xa6, 0x1f, 0xca, 0x50, 0xaf, 0xbc, 0xd7, 0xd6, 0x89, 0xbf,
- 0xd1, 0x3f, 0x6f, 0xdb, 0xcf, 0xb8, 0xc3, 0x8b, 0x19, 0xbd, 0x72, 0xdf,
- 0x9a, 0x7f, 0x76, 0x6e, 0x30, 0x1c, 0x70, 0x3c, 0x54, 0x29, 0xfb, 0x12,
- 0xcf, 0x30, 0xce, 0xfa, 0xfb, 0xe7, 0x43, 0x9d, 0xeb, 0xc6, 0xdd, 0x8d,
- 0xe5, 0x88, 0x2f, 0x15, 0x0e, 0x69, 0xef, 0x9b, 0x50, 0x9f, 0x7f, 0x8d,
- 0xfb, 0xf5, 0xa7, 0xc8, 0xd7, 0x76, 0xa2, 0x9f, 0xf8, 0xb5, 0x52, 0xff,
- 0x9c, 0x62, 0xf2, 0xf7, 0x86, 0x94, 0x89, 0x55, 0xfa, 0x6d, 0xc0, 0x5f,
- 0x54, 0xa3, 0x74, 0xbb, 0x94, 0x17, 0xb9, 0x5b, 0x6c, 0x79, 0x7b, 0x52,
- 0xf2, 0xfb, 0xef, 0xf3, 0x6d, 0xde, 0x09, 0x54, 0xbb, 0xed, 0x3c, 0xe7,
- 0x57, 0x33, 0x77, 0x62, 0x6b, 0x0a, 0xdf, 0xaf, 0x44, 0x7d, 0xa6, 0x4f,
- 0x75, 0x7c, 0xff, 0x0a, 0xcc, 0x4e, 0xff, 0x56, 0x95, 0xf9, 0x88, 0xe1,
- 0xbe, 0x99, 0x0a, 0x71, 0x4d, 0x3b, 0x7d, 0x97, 0x1a, 0x34, 0xc7, 0x41,
- 0xf9, 0x63, 0x2f, 0x5a, 0xe3, 0x57, 0xf8, 0xb0, 0x6f, 0x4c, 0xea, 0xb6,
- 0xc1, 0xe2, 0x9c, 0xec, 0xb7, 0xf7, 0xe2, 0x82, 0x47, 0x2d, 0x35, 0x00,
- 0x27, 0xef, 0x9d, 0x1d, 0xd2, 0x99, 0xc7, 0xb7, 0xe1, 0xdf, 0x06, 0x96,
- 0xe2, 0xb7, 0x03, 0xf5, 0x1d, 0x37, 0x28, 0x96, 0x75, 0x28, 0xf2, 0x59,
- 0xfc, 0xb8, 0xda, 0x8b, 0xdd, 0xe4, 0xff, 0xbf, 0x4d, 0x98, 0xb5, 0x57,
- 0x10, 0x0b, 0xfe, 0x3d, 0x11, 0x4c, 0x1f, 0x52, 0xed, 0x77, 0xc6, 0xf5,
- 0x85, 0x6a, 0x70, 0xe7, 0xaf, 0xd8, 0xc6, 0x7d, 0xea, 0x12, 0xfc, 0x3a,
- 0xdb, 0x8a, 0xd3, 0xd9, 0xa9, 0xb6, 0xd0, 0x69, 0xa1, 0x46, 0xec, 0x40,
- 0xec, 0x81, 0xb6, 0x98, 0xa2, 0x2d, 0x92, 0xdf, 0x76, 0x7d, 0x86, 0xf6,
- 0x48, 0x2c, 0xfa, 0x1e, 0x31, 0xea, 0x1f, 0x52, 0xb4, 0x47, 0xfa, 0xcd,
- 0x77, 0xe9, 0x37, 0xdf, 0xa1, 0xdf, 0x3c, 0x45, 0xbf, 0xc9, 0x71, 0xdb,
- 0x36, 0x7b, 0xbd, 0xfe, 0x65, 0xc6, 0xc4, 0xc4, 0xd6, 0x4e, 0x9c, 0x8a,
- 0xd4, 0xaf, 0x1a, 0x45, 0xb0, 0x3d, 0xa9, 0x58, 0x5e, 0xe1, 0x73, 0x5f,
- 0x0b, 0x89, 0x0f, 0xc8, 0xfb, 0x69, 0x7e, 0x3c, 0x3e, 0xdc, 0x59, 0x29,
- 0xef, 0xbb, 0xee, 0xd9, 0xf1, 0x71, 0x3a, 0xfb, 0x07, 0xf6, 0x43, 0xf4,
- 0xf5, 0xe7, 0x8e, 0x5d, 0x74, 0xf9, 0xcf, 0xd6, 0x8f, 0x6b, 0x64, 0xfc,
- 0xcb, 0xf0, 0xfb, 0x81, 0x16, 0x9c, 0x66, 0xfc, 0x7d, 0x7e, 0xee, 0xb8,
- 0xb7, 0x14, 0xc1, 0xb8, 0xaa, 0x1a, 0xc8, 0x66, 0x5b, 0x70, 0x26, 0x61,
- 0xe0, 0x89, 0x44, 0xfd, 0xaa, 0x32, 0xc7, 0xcf, 0xd5, 0x4c, 0xad, 0x58,
- 0x54, 0x0c, 0x27, 0x85, 0x5f, 0x86, 0xda, 0x50, 0x6c, 0x34, 0x63, 0x30,
- 0x2b, 0x76, 0xea, 0xc5, 0x5b, 0x51, 0x5d, 0xde, 0x2f, 0xfb, 0xa3, 0x7f,
- 0xf7, 0xd1, 0x1e, 0x5f, 0x95, 0xff, 0x27, 0xc1, 0x79, 0xf6, 0x1a, 0xcb,
- 0xe0, 0xdc, 0x2e, 0xef, 0xf8, 0x8b, 0x3f, 0x2b, 0xd8, 0xa4, 0x8f, 0x77,
- 0x94, 0x20, 0xf8, 0xe4, 0x4f, 0x68, 0xeb, 0x87, 0x7a, 0xe5, 0x2c, 0x6e,
- 0x0b, 0x7e, 0xc9, 0xf2, 0x95, 0xf4, 0x8b, 0x43, 0x59, 0xa7, 0xf3, 0xc7,
- 0xbd, 0xf2, 0x8e, 0xfa, 0x12, 0xfc, 0x38, 0x3b, 0xa1, 0x7e, 0xe4, 0xd5,
- 0xf1, 0xab, 0xd1, 0xa5, 0xb4, 0x27, 0xc9, 0xe5, 0x63, 0xcc, 0xe5, 0x83,
- 0xde, 0xc7, 0xb1, 0x14, 0xea, 0xde, 0x65, 0xf0, 0x6c, 0x97, 0xf7, 0x67,
- 0x96, 0xa1, 0x8c, 0xbf, 0xfd, 0xdb, 0x2d, 0xcb, 0x39, 0xb7, 0xd2, 0xda,
- 0xb8, 0x4c, 0xe6, 0x4e, 0xf0, 0xe4, 0xff, 0x7a, 0x65, 0x2d, 0x00, 0x7b,
- 0x45, 0xbe, 0x46, 0xf9, 0x4b, 0xe1, 0xde, 0x5e, 0x1f, 0x5e, 0x84, 0xfa,
- 0xd3, 0x2e, 0x65, 0x29, 0xae, 0xde, 0xab, 0x54, 0xa1, 0x54, 0xca, 0x86,
- 0x69, 0x7f, 0x26, 0xe4, 0x9c, 0x74, 0x4b, 0xef, 0xaf, 0xac, 0x19, 0x86,
- 0xbd, 0xbf, 0x86, 0x95, 0xa3, 0x1a, 0xe3, 0x5d, 0x29, 0xe2, 0x83, 0x8f,
- 0x59, 0x95, 0x86, 0x13, 0x2b, 0x46, 0x1b, 0x71, 0x4b, 0xbf, 0x65, 0x9d,
- 0x9a, 0x17, 0x83, 0xc7, 0xf0, 0x10, 0xc3, 0x3c, 0xf8, 0x4a, 0x6f, 0x19,
- 0xbf, 0x2d, 0x14, 0x31, 0x26, 0xcf, 0x52, 0xb5, 0x55, 0xb5, 0x0e, 0xad,
- 0x7d, 0x54, 0x91, 0xb8, 0xef, 0xc1, 0x83, 0x8c, 0xcf, 0x8b, 0x7b, 0xfd,
- 0x88, 0x8f, 0x5a, 0xd6, 0x2b, 0x51, 0x1f, 0x1e, 0x60, 0xfd, 0xd6, 0xde,
- 0x01, 0x74, 0xd1, 0x2e, 0xe2, 0x7b, 0xb5, 0x80, 0x97, 0xf1, 0x7e, 0xe5,
- 0xa8, 0x9b, 0x31, 0xac, 0x1a, 0x8b, 0xb6, 0x07, 0xf0, 0x95, 0x51, 0x0f,
- 0xe3, 0x9b, 0x35, 0xff, 0x4d, 0xdd, 0xbc, 0xd6, 0x01, 0x0d, 0x6b, 0x46,
- 0x7d, 0x58, 0xd2, 0x1b, 0x3c, 0x23, 0xef, 0x5a, 0x9f, 0xd5, 0xc3, 0x58,
- 0x3d, 0xea, 0xc7, 0xed, 0xbd, 0x13, 0x5f, 0x99, 0x01, 0xf3, 0xff, 0xab,
- 0x45, 0x23, 0xbe, 0x3c, 0x5a, 0x47, 0xf9, 0xc1, 0x55, 0x2f, 0x2b, 0x75,
- 0xf8, 0xdb, 0xbd, 0x3a, 0xe5, 0xab, 0xb8, 0x8d, 0x72, 0x6e, 0xed, 0xbd,
- 0x1a, 0x0f, 0xee, 0x8d, 0xe2, 0xbe, 0xd1, 0xb9, 0x58, 0xc8, 0xf8, 0xd4,
- 0xc1, 0xbc, 0x0e, 0x9f, 0x07, 0x6e, 0xef, 0x17, 0xdd, 0x43, 0x79, 0x25,
- 0x3a, 0x0e, 0x37, 0xe3, 0x1d, 0x0d, 0x91, 0xf7, 0x1a, 0xc9, 0xc1, 0x74,
- 0xdc, 0xbe, 0x6b, 0xae, 0xbd, 0x9f, 0x5e, 0x1f, 0x29, 0x46, 0xbc, 0x4d,
- 0x41, 0x4b, 0xbf, 0xc4, 0x59, 0xe1, 0x36, 0x3a, 0xe3, 0x6a, 0x88, 0x6d,
- 0xe8, 0x8c, 0xab, 0xb9, 0xfb, 0x5d, 0x29, 0x39, 0x6b, 0xf5, 0x06, 0xf9,
- 0x52, 0x04, 0x2d, 0x76, 0x8c, 0x76, 0x93, 0x5f, 0x9b, 0x70, 0x32, 0x76,
- 0x47, 0x68, 0xe3, 0xf3, 0x9b, 0x24, 0x56, 0x37, 0x32, 0x4f, 0x34, 0x30,
- 0xd6, 0xa7, 0x75, 0x9c, 0x51, 0x0c, 0x8c, 0xee, 0x92, 0x98, 0xe8, 0xc3,
- 0xea, 0x5e, 0x03, 0x6f, 0xca, 0x59, 0xfa, 0x39, 0xb1, 0xc5, 0x65, 0xd0,
- 0xf4, 0x07, 0x11, 0x32, 0x8f, 0x31, 0xb6, 0x9f, 0xce, 0x54, 0xe3, 0x96,
- 0xed, 0x52, 0xa6, 0x09, 0x6f, 0x0d, 0x39, 0x71, 0x4b, 0xef, 0x5a, 0x3c,
- 0x96, 0x76, 0x60, 0x50, 0xaf, 0xef, 0x51, 0x19, 0x3f, 0x6f, 0x6c, 0x0a,
- 0x7a, 0x9f, 0x21, 0x57, 0x3d, 0x33, 0x97, 0x51, 0xf9, 0x8a, 0x28, 0x5a,
- 0xd8, 0xaf, 0x16, 0x2d, 0x77, 0x96, 0xe2, 0xbe, 0xe8, 0x5a, 0x1c, 0x4b,
- 0x6b, 0xe6, 0x7e, 0xe6, 0xcb, 0xee, 0x26, 0x3e, 0x9f, 0xee, 0x44, 0xb7,
- 0x26, 0x9c, 0xb6, 0x91, 0xbe, 0x25, 0xeb, 0x2a, 0x51, 0xbc, 0x49, 0x7b,
- 0xed, 0xc9, 0xcc, 0x67, 0xec, 0x97, 0x98, 0x2f, 0x67, 0xfd, 0x4c, 0x54,
- 0xde, 0xa0, 0xe0, 0xf8, 0x6e, 0xe1, 0x58, 0xf3, 0xf1, 0x45, 0xea, 0xa9,
- 0xa5, 0x57, 0xc5, 0x8d, 0x7b, 0x97, 0xe3, 0xd4, 0xb6, 0x1c, 0xe7, 0x7a,
- 0x25, 0x62, 0x7e, 0x99, 0x9c, 0xab, 0xbd, 0x9c, 0x9c, 0x8b, 0x5c, 0x2e,
- 0xbc, 0x5a, 0x71, 0x22, 0x34, 0xda, 0x4c, 0x5e, 0x21, 0xfc, 0x82, 0xfe,
- 0x9a, 0x8d, 0x62, 0x51, 0x6f, 0x1d, 0x86, 0xc9, 0xb7, 0x32, 0xc4, 0x8b,
- 0x4c, 0x96, 0x71, 0x65, 0xa8, 0x86, 0x9f, 0x00, 0x3f, 0xd7, 0xf0, 0xa3,
- 0xd9, 0xf7, 0x56, 0xd0, 0x96, 0x63, 0x6d, 0x8a, 0x7d, 0xce, 0x7e, 0x30,
- 0x2b, 0xb1, 0x5a, 0x41, 0x95, 0xf6, 0x17, 0x55, 0x92, 0x67, 0x7a, 0x35,
- 0x05, 0xaf, 0xa5, 0x03, 0xf8, 0x6a, 0xd3, 0x5a, 0x25, 0x56, 0x6d, 0xbf,
- 0xa7, 0x6a, 0x96, 0xb2, 0x6f, 0x8b, 0xe6, 0xc9, 0x3a, 0x64, 0x98, 0x39,
- 0xaf, 0xfc, 0x8f, 0x02, 0x05, 0x0f, 0x30, 0x97, 0x0f, 0x54, 0x05, 0xe4,
- 0x1c, 0x14, 0xfd, 0xdd, 0x87, 0x17, 0x12, 0x71, 0x64, 0x13, 0x0d, 0x3d,
- 0xab, 0x15, 0xd9, 0xef, 0x09, 0x36, 0xc7, 0x95, 0x1c, 0xe7, 0x2f, 0x67,
- 0xdd, 0xdd, 0xf3, 0x3a, 0xd0, 0x41, 0x6e, 0x7f, 0x3a, 0xc7, 0xed, 0x03,
- 0x93, 0xe8, 0xc0, 0xca, 0x84, 0xec, 0x6f, 0xc6, 0xad, 0x2e, 0xce, 0xc1,
- 0xe1, 0x44, 0x07, 0xee, 0x4c, 0x34, 0x74, 0x10, 0x5a, 0x30, 0x7e, 0x57,
- 0x07, 0x5a, 0x12, 0xf5, 0xe3, 0x5b, 0xe5, 0x7f, 0x50, 0x4d, 0xd3, 0x70,
- 0x60, 0x4c, 0x45, 0xad, 0x16, 0x20, 0xf6, 0x07, 0x30, 0x98, 0x6a, 0x38,
- 0xd3, 0xa5, 0xde, 0xa9, 0x4c, 0x5e, 0x21, 0x39, 0x64, 0x33, 0x9e, 0x4f,
- 0x78, 0x50, 0x96, 0x34, 0x69, 0xfb, 0x40, 0xe9, 0x48, 0x94, 0xf9, 0xc3,
- 0x63, 0x56, 0x95, 0x11, 0x4a, 0x8b, 0x5e, 0x4a, 0x46, 0xe6, 0xe3, 0x0d,
- 0xc6, 0xdc, 0xfa, 0xeb, 0x35, 0xef, 0x42, 0x1b, 0x8b, 0x7e, 0x65, 0xd5,
- 0x1a, 0x65, 0x98, 0xb1, 0x2b, 0xd4, 0xdc, 0xc2, 0xf8, 0xda, 0x7c, 0x03,
- 0xed, 0x80, 0xb1, 0xaf, 0xd2, 0xd8, 0xc9, 0x39, 0x16, 0x7b, 0xf2, 0xa0,
- 0x7c, 0xc4, 0x47, 0x1c, 0xa2, 0xe8, 0x11, 0x0d, 0x7b, 0xd9, 0x2f, 0xef,
- 0x88, 0x9c, 0x0b, 0x0a, 0xb6, 0xdf, 0x27, 0xff, 0x53, 0x64, 0x4f, 0xee,
- 0xfc, 0xe1, 0xfb, 0x89, 0xcf, 0x40, 0x92, 0x51, 0xcf, 0x88, 0x07, 0x1f,
- 0x26, 0xe4, 0x0c, 0x1f, 0x69, 0xcd, 0x48, 0x00, 0x55, 0xac, 0xfb, 0x66,
- 0xa2, 0x3e, 0xfd, 0xdf, 0x51, 0x1f, 0xb8, 0x55, 0xad, 0xb4, 0xcf, 0x0a,
- 0x39, 0x47, 0x6e, 0xc2, 0x89, 0x74, 0x70, 0x9c, 0x79, 0xf4, 0xaa, 0x76,
- 0xaa, 0x98, 0xb9, 0xae, 0x79, 0x8d, 0xd2, 0xd0, 0xa1, 0xaa, 0xc1, 0xf0,
- 0xa8, 0x02, 0xca, 0x73, 0xb2, 0x8d, 0x9b, 0xf0, 0x76, 0xba, 0x14, 0x45,
- 0xbb, 0x76, 0xd2, 0xee, 0x8b, 0xb0, 0x78, 0x9b, 0x1b, 0x25, 0x7b, 0xc4,
- 0x56, 0x45, 0xaf, 0x92, 0xef, 0x83, 0xb6, 0x6a, 0x62, 0x6f, 0x74, 0x39,
- 0x9e, 0x1f, 0x90, 0x7d, 0xf4, 0x0b, 0x1c, 0xbc, 0x2d, 0x62, 0xde, 0xae,
- 0x32, 0x06, 0xad, 0x4f, 0x85, 0xe2, 0x25, 0xb4, 0x09, 0x87, 0x11, 0x6a,
- 0xef, 0xe6, 0xd8, 0x1b, 0x46, 0xc5, 0xce, 0x9a, 0xf1, 0x1d, 0x8e, 0xa5,
- 0x9f, 0x36, 0x31, 0x9c, 0xa8, 0xc3, 0x46, 0xda, 0x84, 0x49, 0x9b, 0x30,
- 0x39, 0xff, 0x26, 0x6d, 0xc2, 0xa4, 0x4d, 0x98, 0xb4, 0x09, 0x93, 0x36,
- 0x61, 0x66, 0xe7, 0x63, 0x5f, 0x5a, 0x45, 0xcf, 0x50, 0x19, 0xe2, 0xd5,
- 0xf2, 0x1e, 0xbd, 0x86, 0xb1, 0x54, 0x97, 0x32, 0x79, 0xd7, 0x4d, 0x18,
- 0x4c, 0xdf, 0xcc, 0x8f, 0x82, 0x76, 0xda, 0xc5, 0xce, 0x8c, 0xd8, 0x99,
- 0x1b, 0xdf, 0xcd, 0xce, 0x99, 0x86, 0xd2, 0x5c, 0xac, 0x7c, 0xcc, 0xbe,
- 0xa7, 0x70, 0x8e, 0xdc, 0x78, 0x26, 0x2b, 0xf7, 0x4c, 0x9c, 0xa0, 0xfd,
- 0xf7, 0x50, 0x9e, 0x1a, 0x91, 0xfd, 0x92, 0x28, 0xf9, 0xbe, 0x9c, 0x0b,
- 0xdf, 0xc9, 0x7e, 0x0b, 0xcf, 0x30, 0xb1, 0x65, 0x1e, 0xd0, 0xd4, 0xbf,
- 0x16, 0x0f, 0xf5, 0x61, 0xbc, 0x9c, 0xcf, 0xbe, 0x93, 0xd9, 0x49, 0x1f,
- 0x6e, 0xb4, 0xd7, 0x30, 0xee, 0x6f, 0x52, 0xf0, 0xa5, 0xb4, 0x9c, 0x27,
- 0xaf, 0x8f, 0x6d, 0x44, 0xc4, 0xf6, 0xdb, 0xfe, 0xd4, 0x4e, 0xa4, 0xf8,
- 0xcc, 0x1f, 0x69, 0xa2, 0x4f, 0x56, 0xe3, 0xdd, 0x6d, 0x41, 0xfd, 0x35,
- 0x68, 0xad, 0x23, 0xb0, 0xe6, 0x2f, 0x8c, 0x84, 0xcc, 0x7a, 0xa5, 0x09,
- 0x6d, 0x7b, 0x9b, 0x98, 0x3b, 0x04, 0xf5, 0xd7, 0xe9, 0x73, 0xcf, 0x45,
- 0xe6, 0x33, 0x7f, 0x88, 0xe1, 0x2b, 0xe4, 0xf9, 0x77, 0x0d, 0xaa, 0x1c,
- 0x53, 0xa3, 0xbd, 0xf6, 0xf1, 0x9c, 0xfd, 0x0e, 0x5c, 0x54, 0xce, 0xc8,
- 0x28, 0x0f, 0x12, 0x73, 0x16, 0x27, 0x0f, 0x5a, 0xf2, 0x4e, 0xed, 0xca,
- 0xeb, 0x9a, 0xb1, 0x3f, 0x6b, 0xe0, 0xc9, 0xf4, 0x1b, 0x96, 0xaa, 0xc5,
- 0xce, 0x3a, 0xc9, 0x45, 0x3c, 0xc4, 0x8c, 0x6c, 0x46, 0xfc, 0x5f, 0xf6,
- 0xc0, 0x0d, 0x7c, 0x98, 0xd6, 0xd2, 0x0d, 0x8c, 0x4b, 0xbf, 0xe6, 0xbd,
- 0x9d, 0xc4, 0x11, 0xf7, 0x56, 0xed, 0xa8, 0x4a, 0x0e, 0x3f, 0xdf, 0x61,
- 0xa0, 0x68, 0xb7, 0xcc, 0x81, 0xe0, 0x56, 0x00, 0x63, 0x89, 0x18, 0xee,
- 0xa4, 0xfd, 0x8c, 0x26, 0x5a, 0x70, 0x07, 0x6d, 0x63, 0x24, 0xd1, 0x8a,
- 0xcf, 0x31, 0x37, 0xd8, 0x9d, 0x10, 0x3f, 0x5b, 0x82, 0x85, 0xb4, 0x95,
- 0xfd, 0xa9, 0xff, 0x05, 0x7d, 0x7a, 0x00, 0xbb, 0x6d, 0xae, 0x29, 0xfb,
- 0xd6, 0x50, 0x56, 0x26, 0xdc, 0xcc, 0x6d, 0xe2, 0x56, 0x7f, 0x4a, 0x38,
- 0x50, 0x27, 0x6e, 0x89, 0x34, 0x62, 0x0b, 0xe5, 0x65, 0xc9, 0x75, 0x87,
- 0x98, 0x4f, 0xad, 0xde, 0xb5, 0x9c, 0x98, 0x7c, 0x61, 0xee, 0x4f, 0xeb,
- 0xe6, 0x21, 0x62, 0x41, 0xd8, 0xcf, 0x79, 0x57, 0x69, 0xc3, 0x72, 0xce,
- 0x7c, 0x90, 0x63, 0x9f, 0x43, 0x3c, 0x70, 0xa7, 0xc4, 0x7e, 0x82, 0x47,
- 0x19, 0xf2, 0x1e, 0xae, 0x95, 0x77, 0x15, 0xe8, 0x1b, 0x33, 0x52, 0x56,
- 0xa7, 0x93, 0x71, 0x64, 0x53, 0xb4, 0x0e, 0x07, 0x47, 0x6e, 0x86, 0x77,
- 0x6b, 0x1d, 0x46, 0x93, 0x7e, 0x64, 0x93, 0xa8, 0xf5, 0x42, 0xbd, 0xc1,
- 0x8b, 0x60, 0xf3, 0x21, 0xc6, 0x89, 0xb7, 0x95, 0x86, 0xf6, 0x37, 0x11,
- 0xec, 0xd9, 0xac, 0x04, 0xbd, 0x0d, 0xaa, 0xb4, 0x4d, 0x3c, 0xa1, 0x1f,
- 0x0c, 0xd2, 0xde, 0x33, 0x23, 0xc4, 0x14, 0xd6, 0x75, 0x6d, 0x75, 0xc9,
- 0x3a, 0xf1, 0x78, 0x95, 0xe6, 0xc3, 0x9e, 0x3d, 0xc4, 0xb8, 0x1d, 0xf2,
- 0xbf, 0x03, 0x6a, 0xb0, 0x6f, 0xcf, 0xcd, 0x98, 0xb1, 0x35, 0x80, 0x83,
- 0xbc, 0x57, 0xbb, 0xe3, 0x1a, 0x3c, 0x43, 0x3f, 0xc9, 0xd0, 0x0f, 0x8b,
- 0xb6, 0xaa, 0xd8, 0xbb, 0xe7, 0x26, 0x54, 0x92, 0xd7, 0x9f, 0x0a, 0x29,
- 0x36, 0xf6, 0x26, 0x38, 0xae, 0xdd, 0x29, 0xfb, 0xdc, 0xbc, 0xf2, 0x22,
- 0xf3, 0x81, 0xee, 0x11, 0x1d, 0x9b, 0x79, 0x3f, 0xc5, 0xb9, 0xde, 0x42,
- 0xcc, 0x3d, 0xbe, 0xad, 0x1a, 0xf7, 0x6f, 0xd3, 0x62, 0xd7, 0xa8, 0xd6,
- 0xfc, 0xb7, 0xf4, 0xd0, 0x19, 0x17, 0xe7, 0xd8, 0x62, 0x0e, 0x77, 0xb6,
- 0xef, 0xa0, 0x55, 0x45, 0xac, 0x77, 0x69, 0xf3, 0x31, 0x73, 0x6e, 0x0c,
- 0xaf, 0x47, 0x9b, 0x70, 0x66, 0x97, 0xe8, 0xca, 0x62, 0x0c, 0x90, 0xf8,
- 0x10, 0x45, 0x9c, 0x39, 0xdd, 0x6e, 0xe6, 0x74, 0xf7, 0x30, 0xa7, 0x7b,
- 0xb0, 0x4f, 0x74, 0xdc, 0x89, 0x25, 0x11, 0x83, 0x3a, 0x6c, 0x24, 0x7e,
- 0x19, 0x50, 0xfb, 0xb4, 0xe6, 0xbb, 0x88, 0xf1, 0xc5, 0x76, 0x8e, 0x67,
- 0x10, 0x27, 0x24, 0x4f, 0x30, 0xf0, 0xd3, 0x4c, 0xce, 0xef, 0x6a, 0x19,
- 0xd3, 0x0f, 0x8c, 0xb4, 0xe0, 0xbb, 0xcc, 0xe1, 0x46, 0xfb, 0x42, 0x3b,
- 0x5f, 0x56, 0x5a, 0xf1, 0x5d, 0x3b, 0x5e, 0x88, 0x0d, 0xb7, 0xe2, 0xdd,
- 0x84, 0x16, 0x5f, 0xa8, 0x84, 0xda, 0xd3, 0xbc, 0xff, 0x5e, 0xf6, 0x66,
- 0x72, 0xd8, 0x25, 0x38, 0x4e, 0x1b, 0xee, 0x49, 0x09, 0x96, 0x3b, 0xe1,
- 0xda, 0x76, 0x07, 0xde, 0x1a, 0xce, 0xe5, 0x6e, 0x21, 0xe6, 0x6e, 0x77,
- 0xf6, 0xd3, 0x1e, 0x52, 0x10, 0x6f, 0x60, 0x0e, 0x17, 0x5c, 0x55, 0xc4,
- 0xfc, 0xed, 0xa3, 0x48, 0x2e, 0x7f, 0x8b, 0x57, 0x07, 0xf5, 0x17, 0x15,
- 0x73, 0xa7, 0xbc, 0x7b, 0xf4, 0x1a, 0x72, 0xe7, 0xc6, 0x4f, 0x10, 0x6b,
- 0x37, 0xd1, 0x07, 0xae, 0x8b, 0x48, 0x7e, 0xa7, 0x61, 0x38, 0x65, 0xbf,
- 0xcf, 0xad, 0xff, 0x94, 0xf3, 0xeb, 0xd7, 0xc4, 0x06, 0x1c, 0x38, 0xad,
- 0xd7, 0x7b, 0xbd, 0x0e, 0x07, 0x6e, 0xd1, 0x83, 0xab, 0x8e, 0x20, 0xca,
- 0x79, 0x97, 0xbd, 0xc2, 0x5c, 0x3c, 0x75, 0x26, 0xe5, 0x1d, 0x94, 0x4e,
- 0xbc, 0x35, 0xf7, 0xef, 0xf3, 0x79, 0x58, 0x21, 0x1f, 0x13, 0x9b, 0x6b,
- 0x68, 0x76, 0xa0, 0xde, 0x2c, 0x86, 0x96, 0x49, 0x93, 0x5f, 0xc6, 0x39,
- 0xd7, 0x71, 0x08, 0xf6, 0x37, 0x98, 0x5e, 0x84, 0xed, 0xff, 0xf9, 0xf5,
- 0x7c, 0xc2, 0x3e, 0x03, 0x4a, 0x9c, 0xcb, 0xe1, 0xea, 0x73, 0x89, 0x52,
- 0x80, 0xf8, 0x94, 0xe0, 0xd8, 0x8a, 0x47, 0x4c, 0xb8, 0x0c, 0xfa, 0x57,
- 0x9f, 0x07, 0xea, 0x2e, 0x0f, 0xfc, 0xc9, 0xc7, 0xac, 0x72, 0xe2, 0x6a,
- 0xd9, 0x2e, 0xce, 0x91, 0xc3, 0xb2, 0x9e, 0x9a, 0x27, 0x38, 0x2b, 0x65,
- 0xb5, 0xd6, 0x0f, 0x79, 0xad, 0x11, 0x67, 0x35, 0x62, 0x6b, 0x05, 0xf1,
- 0xb1, 0x3b, 0x59, 0x8d, 0xcd, 0xdb, 0x06, 0xa8, 0x73, 0x2f, 0x1c, 0xbc,
- 0x4e, 0x25, 0xfd, 0x36, 0x76, 0x82, 0xbf, 0x2b, 0xe9, 0x33, 0xa0, 0x9d,
- 0x6d, 0x4d, 0x5a, 0xf3, 0xef, 0x8c, 0x98, 0x7d, 0x95, 0xec, 0xcb, 0x34,
- 0xe2, 0xed, 0xc6, 0x64, 0xd0, 0x7b, 0xab, 0xaa, 0xe0, 0xf6, 0x88, 0xce,
- 0xb6, 0x3d, 0xe8, 0x4b, 0x0a, 0x4e, 0x4c, 0x50, 0x8f, 0x66, 0x43, 0x19,
- 0x75, 0xe9, 0xa2, 0x2e, 0x67, 0xd8, 0xe7, 0x55, 0xeb, 0x50, 0xbe, 0x27,
- 0xca, 0x3e, 0x37, 0x12, 0x8b, 0x4d, 0x6c, 0xe2, 0xcf, 0xf9, 0xbb, 0x97,
- 0xe3, 0xba, 0x6d, 0x76, 0xee, 0xbb, 0x40, 0xf2, 0x99, 0xd7, 0x22, 0x21,
- 0xfd, 0x1e, 0xd5, 0x89, 0xb7, 0xb3, 0x82, 0xb5, 0xf2, 0x3e, 0x3d, 0xc6,
- 0x67, 0x68, 0xcd, 0x58, 0x9a, 0x14, 0x8c, 0xf2, 0x93, 0x67, 0x47, 0xb1,
- 0x24, 0x29, 0xfe, 0x68, 0xe2, 0xb6, 0xeb, 0xeb, 0xf0, 0xfe, 0xf9, 0x75,
- 0x0b, 0x1f, 0x26, 0x89, 0x99, 0x93, 0xc4, 0xcc, 0x49, 0x62, 0xe6, 0xa4,
- 0xbd, 0x16, 0xa1, 0xe2, 0xf4, 0x90, 0x82, 0xf7, 0x6c, 0xfc, 0xdb, 0x69,
- 0x73, 0xa8, 0x27, 0x19, 0xd3, 0xdb, 0xd3, 0x3a, 0x0e, 0xd0, 0x16, 0x92,
- 0x29, 0xb1, 0x35, 0x05, 0x4f, 0xf5, 0x45, 0x50, 0x45, 0xdb, 0xd9, 0x4a,
- 0x9b, 0x7e, 0x78, 0xbb, 0x16, 0x98, 0xef, 0x08, 0xb5, 0xa6, 0xd0, 0x84,
- 0x07, 0x88, 0x57, 0x0f, 0x31, 0x97, 0x39, 0x44, 0x4c, 0xbb, 0x67, 0x70,
- 0x2d, 0x96, 0xf4, 0xa9, 0xc4, 0x2c, 0x62, 0xd5, 0x74, 0xc1, 0x6e, 0xc1,
- 0x4b, 0x79, 0x57, 0x2e, 0x2a, 0xeb, 0x9a, 0xca, 0x5d, 0xc4, 0xaa, 0xc6,
- 0x5e, 0xe1, 0x38, 0xcc, 0x93, 0x18, 0x8b, 0x12, 0xc4, 0xaa, 0x2d, 0x69,
- 0x99, 0xaf, 0x4e, 0xdc, 0x4b, 0xbb, 0x5e, 0x9f, 0x5f, 0x97, 0x98, 0xb3,
- 0x55, 0x3b, 0x73, 0x40, 0xc9, 0x71, 0x9d, 0x5e, 0x5e, 0x1f, 0xee, 0x0b,
- 0x50, 0x0f, 0x06, 0x8e, 0xed, 0x92, 0x3c, 0x48, 0xfa, 0x13, 0xc0, 0x21,
- 0xe2, 0x93, 0x83, 0xba, 0x7e, 0x99, 0xf8, 0x54, 0x49, 0x7c, 0x7a, 0x8d,
- 0xf8, 0x34, 0x8d, 0xf8, 0xf4, 0x6a, 0x1e, 0x9f, 0xaa, 0x47, 0xc4, 0x16,
- 0x72, 0x5c, 0xfb, 0x78, 0xe2, 0xb9, 0x2a, 0xf9, 0x5f, 0x62, 0x82, 0xf3,
- 0x97, 0xc7, 0xff, 0xa5, 0x78, 0x71, 0x00, 0xee, 0x19, 0xe4, 0xb2, 0x16,
- 0xf1, 0xe6, 0x03, 0xc7, 0x52, 0xfc, 0x74, 0xa8, 0xc0, 0x61, 0x27, 0xed,
- 0x5c, 0xb9, 0xdc, 0x90, 0x75, 0x30, 0x59, 0x03, 0xab, 0xcb, 0xef, 0x0b,
- 0x9a, 0xf8, 0xce, 0x3c, 0xe1, 0x8d, 0xb2, 0xae, 0x53, 0x44, 0x7e, 0xd8,
- 0x86, 0xe1, 0x6d, 0xcf, 0x62, 0x53, 0x9f, 0x7a, 0x6b, 0x19, 0xc8, 0x85,
- 0x95, 0x4e, 0x38, 0x22, 0x95, 0x98, 0x19, 0x11, 0x1b, 0x64, 0x2e, 0x32,
- 0xf6, 0x6d, 0x74, 0xef, 0x2e, 0xc3, 0x84, 0xd7, 0xb2, 0x9e, 0xd4, 0x6b,
- 0xe5, 0xdf, 0x00, 0x08, 0x5e, 0x7a, 0x8a, 0x18, 0xa3, 0x6e, 0x1d, 0xfd,
- 0xb8, 0x33, 0xa7, 0x6b, 0xf0, 0xc5, 0xed, 0x8f, 0xa0, 0x7d, 0xfb, 0x37,
- 0xe9, 0x7b, 0x33, 0x7b, 0x6a, 0x69, 0x87, 0xd7, 0x35, 0x8d, 0xe3, 0x44,
- 0x84, 0xb1, 0xcf, 0xa7, 0xe0, 0x87, 0x73, 0x66, 0x8a, 0x1c, 0xfe, 0x7d,
- 0x60, 0x05, 0x6c, 0x79, 0x6f, 0xe5, 0xfd, 0xe3, 0x39, 0x1f, 0xc7, 0x4e,
- 0xd9, 0x27, 0xbc, 0xf9, 0xb3, 0x9b, 0x7f, 0x42, 0x5b, 0x3f, 0x13, 0x19,
- 0xfc, 0x2b, 0xc8, 0x78, 0xdd, 0x8a, 0x2d, 0x93, 0x7a, 0x45, 0xf9, 0x36,
- 0xbe, 0x49, 0x8e, 0x47, 0x9e, 0xa7, 0xf3, 0x7b, 0xf0, 0x59, 0x91, 0xcf,
- 0x67, 0x05, 0xf9, 0x2f, 0x5a, 0xb1, 0x36, 0xb9, 0x96, 0x32, 0x1f, 0xf1,
- 0x99, 0x94, 0x2b, 0x3c, 0x7b, 0x36, 0x2f, 0xa7, 0x18, 0x81, 0xea, 0x9c,
- 0x9c, 0x2f, 0x51, 0xce, 0x69, 0x62, 0x9e, 0x7a, 0xfd, 0x54, 0x59, 0x85,
- 0x76, 0xff, 0xf7, 0x79, 0x59, 0xb9, 0x72, 0x45, 0xd3, 0x51, 0x2a, 0x65,
- 0xa7, 0xae, 0x7b, 0x17, 0xd1, 0x77, 0x43, 0xde, 0xf5, 0xf6, 0x7a, 0xb3,
- 0x8e, 0x15, 0x17, 0xe7, 0x4c, 0xf2, 0xde, 0x1b, 0xb9, 0x82, 0x17, 0x6f,
- 0x33, 0x47, 0xca, 0xad, 0xbf, 0x4b, 0xfe, 0x65, 0xe0, 0xf1, 0x44, 0xb0,
- 0x75, 0xa5, 0xd2, 0x10, 0x9b, 0x4d, 0x6e, 0x81, 0x2a, 0x59, 0x93, 0x6e,
- 0xb6, 0xff, 0x5f, 0x5e, 0x36, 0xd4, 0xcc, 0x3c, 0xcd, 0xa0, 0x2d, 0x05,
- 0x3b, 0x4e, 0xd8, 0xfb, 0x89, 0x06, 0x5e, 0xca, 0xbe, 0x92, 0x3f, 0x8f,
- 0x28, 0x73, 0x1e, 0xe6, 0x9c, 0x4f, 0x5d, 0x13, 0x95, 0xf9, 0x0f, 0xa6,
- 0x33, 0xa8, 0x16, 0x1e, 0x68, 0x9a, 0xd0, 0xe9, 0x37, 0x26, 0x43, 0xd8,
- 0x0d, 0x88, 0xfb, 0x64, 0x6f, 0xc1, 0x97, 0xff, 0x3f, 0x66, 0xac, 0xf7,
- 0x09, 0x6b, 0x3c, 0x60, 0xbd, 0xdc, 0x99, 0x33, 0x1d, 0xe6, 0xd8, 0xd5,
- 0xc8, 0x78, 0x65, 0xfd, 0x00, 0xe6, 0x34, 0x23, 0x00, 0x9f, 0x76, 0x37,
- 0xc7, 0xed, 0xc2, 0x74, 0xe6, 0x47, 0x91, 0x99, 0x0d, 0x6d, 0x4d, 0xea,
- 0x15, 0x88, 0x55, 0xc9, 0x79, 0x22, 0x9d, 0xf6, 0x0f, 0x14, 0xf7, 0xca,
- 0xf9, 0x0d, 0xb3, 0xd5, 0x8d, 0xa0, 0x7f, 0xae, 0xa2, 0xa0, 0x28, 0x04,
- 0xe7, 0xfd, 0x59, 0xf2, 0xb0, 0x99, 0x1f, 0x59, 0x3f, 0xf2, 0xe9, 0xcc,
- 0xe7, 0x0b, 0x7d, 0xd0, 0xf1, 0xf5, 0xd1, 0x4b, 0x33, 0xc8, 0x82, 0xcc,
- 0xf7, 0xad, 0xd8, 0x74, 0x69, 0x5b, 0xe4, 0x7e, 0x52, 0x5f, 0x73, 0x7d,
- 0xfc, 0xa7, 0x59, 0xf5, 0x01, 0x07, 0x2a, 0xb1, 0x5e, 0x37, 0xa6, 0xcb,
- 0xd9, 0xec, 0x7b, 0x65, 0x8d, 0xc5, 0x3e, 0xcf, 0x36, 0xf5, 0x5c, 0xd6,
- 0xd4, 0x75, 0x63, 0x2f, 0xaa, 0x89, 0xe1, 0x25, 0x49, 0xd1, 0xf5, 0x35,
- 0x50, 0xa9, 0xef, 0x63, 0xc4, 0xa2, 0xe2, 0xa4, 0x87, 0x79, 0xab, 0x87,
- 0x58, 0x67, 0xe0, 0xb9, 0x6c, 0x07, 0x5c, 0xe4, 0x4e, 0x13, 0xd9, 0x30,
- 0x5e, 0xcd, 0xce, 0x99, 0x2e, 0xe7, 0x5e, 0xa9, 0x02, 0x38, 0x67, 0xca,
- 0x6f, 0x53, 0xde, 0xe7, 0x53, 0x72, 0xbf, 0xdf, 0xb7, 0xdf, 0x35, 0x77,
- 0x18, 0x2b, 0x71, 0x4f, 0xa2, 0x4a, 0xd6, 0xda, 0x4d, 0x9f, 0x61, 0x5a,
- 0xd3, 0xb4, 0xaa, 0xe9, 0xb9, 0xf3, 0x30, 0xc1, 0xf6, 0xa5, 0xc4, 0x91,
- 0xd5, 0x11, 0xad, 0xed, 0xbf, 0x2b, 0xc1, 0x40, 0x5a, 0x69, 0x63, 0xf9,
- 0x30, 0x36, 0x8f, 0x4a, 0x5d, 0x85, 0xe3, 0x2d, 0xec, 0x57, 0x37, 0x04,
- 0x42, 0xea, 0xaf, 0x0b, 0x67, 0xa1, 0xdd, 0x45, 0x46, 0x1c, 0xcf, 0x26,
- 0xa6, 0xcb, 0xff, 0x2c, 0x90, 0x35, 0x95, 0xbc, 0x4c, 0x8f, 0x59, 0x65,
- 0x48, 0x5b, 0xed, 0x6c, 0xcb, 0x3c, 0xeb, 0x25, 0x86, 0xb8, 0xb4, 0xe0,
- 0xd1, 0xaf, 0x22, 0xb8, 0x66, 0xbe, 0xa3, 0x13, 0x67, 0x22, 0x5a, 0xc7,
- 0x47, 0x6c, 0xa3, 0xca, 0x11, 0x46, 0x6f, 0x5e, 0xbe, 0xfc, 0x9f, 0xd8,
- 0x9c, 0xac, 0x86, 0x55, 0x45, 0xea, 0x69, 0x2b, 0x33, 0x3d, 0x27, 0xbf,
- 0xd8, 0x58, 0xce, 0xfc, 0xd8, 0x43, 0xb9, 0x72, 0xe6, 0x36, 0xb8, 0xf3,
- 0xd7, 0x30, 0xad, 0x6a, 0x4d, 0xeb, 0xf9, 0xaa, 0xda, 0x89, 0x15, 0x4d,
- 0xc1, 0xc0, 0x32, 0xda, 0x48, 0x95, 0x2d, 0x23, 0x16, 0x2e, 0xfa, 0xd8,
- 0x33, 0x71, 0xf4, 0x23, 0xc8, 0xba, 0x23, 0xcb, 0x95, 0xca, 0x99, 0x31,
- 0x79, 0xd7, 0xd4, 0x89, 0x85, 0x8c, 0x6f, 0xf1, 0xc2, 0xff, 0x74, 0xb2,
- 0xf7, 0x86, 0xbe, 0x31, 0xfd, 0xc2, 0xff, 0xd9, 0xfd, 0xff, 0x01, 0x02,
- 0x8b, 0x0c, 0x6e, 0x74, 0x57, 0x00, 0x00, 0x00 };
+ 0xad, 0xbc, 0x0b, 0x74, 0x1c, 0xd5, 0x95, 0x2e, 0xfc, 0x55, 0x75, 0xb7,
+ 0xd4, 0x92, 0xda, 0x52, 0x4b, 0x6e, 0xcb, 0x6d, 0xd0, 0xe0, 0x6a, 0xab,
+ 0xda, 0x6a, 0x2c, 0x01, 0xd5, 0xb2, 0x0c, 0x4d, 0xa6, 0xc0, 0x1d, 0x5b,
+ 0x80, 0x0c, 0x26, 0x11, 0xc6, 0xb9, 0x23, 0xe6, 0x7a, 0xfe, 0xf4, 0x18,
+ 0x03, 0x86, 0x90, 0x5c, 0x33, 0x93, 0x9b, 0x71, 0xb8, 0x9e, 0xeb, 0x8a,
+ 0xe4, 0x87, 0xc0, 0xa5, 0xee, 0x96, 0x90, 0x1f, 0xac, 0x35, 0xeb, 0xa7,
+ 0x2d, 0xcb, 0x92, 0x21, 0xad, 0x16, 0x49, 0x98, 0x19, 0xe7, 0xe6, 0x81,
+ 0xc6, 0xd8, 0x60, 0x93, 0xf0, 0xc8, 0x6b, 0xfd, 0x4c, 0xfe, 0xb9, 0x7f,
+ 0x3c, 0xb6, 0x79, 0x83, 0xe3, 0x3c, 0x47, 0x9e, 0xc1, 0xa9, 0xff, 0xdb,
+ 0xd5, 0xdd, 0xb6, 0xec, 0x40, 0x1e, 0xeb, 0x8e, 0xd6, 0xaa, 0xa5, 0xee,
+ 0xaa, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0x4e,
+ 0xb5, 0x06, 0x54, 0xa3, 0xf4, 0x37, 0x8b, 0xd7, 0xd5, 0x1d, 0x1b, 0xee,
+ 0x5e, 0xdc, 0x7e, 0x75, 0x87, 0x7c, 0xf7, 0xce, 0xf5, 0x7a, 0xf1, 0x61,
+ 0x7f, 0x26, 0x12, 0x97, 0xde, 0xd2, 0x3e, 0xb4, 0xe0, 0x47, 0xfc, 0x25,
+ 0x10, 0x91, 0x7f, 0xad, 0xa5, 0xaf, 0x1e, 0x20, 0x58, 0x6e, 0x5f, 0x2e,
+ 0xf8, 0x55, 0xb3, 0xf3, 0xbf, 0x2e, 0xd3, 0xe1, 0xf7, 0x98, 0x9f, 0xff,
+ 0x8b, 0xbb, 0x75, 0x20, 0x99, 0x6f, 0xd5, 0x96, 0xe3, 0x9c, 0x63, 0x85,
+ 0xbc, 0x90, 0xfb, 0x7f, 0x62, 0x7e, 0xf0, 0xc4, 0xb7, 0xae, 0x8b, 0x9c,
+ 0xc9, 0x79, 0xe0, 0x0f, 0x9a, 0x16, 0x82, 0x0b, 0xe1, 0x6f, 0x62, 0x9d,
+ 0xbf, 0x6b, 0xd9, 0xa6, 0xa2, 0xb6, 0x2c, 0x2b, 0x12, 0xce, 0x21, 0x12,
+ 0xb4, 0x10, 0x89, 0x59, 0x40, 0xca, 0x6b, 0x22, 0x55, 0x69, 0xfa, 0x51,
+ 0xa1, 0x57, 0x20, 0x15, 0xdc, 0xa8, 0x6d, 0xe1, 0x18, 0x97, 0xd9, 0x7e,
+ 0xed, 0x44, 0x1e, 0xb8, 0xdb, 0xf6, 0xe3, 0xb8, 0x27, 0xa0, 0x9d, 0xcc,
+ 0xef, 0xab, 0x2b, 0xea, 0x23, 0x09, 0x8f, 0x8e, 0x94, 0x6a, 0xca, 0x7d,
+ 0x68, 0xcb, 0xf3, 0x48, 0xf9, 0xcc, 0xcf, 0x6b, 0xe3, 0x36, 0xd0, 0x9b,
+ 0x69, 0x36, 0x4e, 0xa0, 0x35, 0x7c, 0x18, 0x95, 0x48, 0x85, 0x22, 0x31,
+ 0xe0, 0x83, 0x73, 0x8f, 0x66, 0x14, 0xf8, 0xf4, 0xd9, 0xe8, 0xdc, 0x0b,
+ 0x3c, 0x92, 0x89, 0x24, 0x75, 0x05, 0xe8, 0x9f, 0x94, 0xba, 0x91, 0x60,
+ 0x8e, 0xcf, 0xb7, 0x64, 0x80, 0xad, 0x99, 0xd9, 0xd8, 0x96, 0x75, 0xf0,
+ 0x9c, 0xd1, 0x1c, 0xdc, 0xc7, 0x16, 0x7a, 0xdd, 0xe7, 0xb3, 0x61, 0xe5,
+ 0xe4, 0xf9, 0x5b, 0xce, 0xb7, 0x5a, 0x82, 0x78, 0x7a, 0x32, 0x84, 0x67,
+ 0x27, 0xeb, 0xf1, 0x48, 0xb6, 0x1e, 0xdb, 0xb3, 0x31, 0xa8, 0xba, 0x83,
+ 0x58, 0x3c, 0x86, 0x8a, 0xeb, 0x1d, 0x9c, 0x34, 0xda, 0xb0, 0x95, 0x82,
+ 0x5f, 0x6d, 0x6b, 0xc4, 0xda, 0x60, 0x13, 0xb6, 0xe8, 0xd7, 0xa1, 0x38,
+ 0xd6, 0x0f, 0xce, 0x65, 0x32, 0xd2, 0x3f, 0xaf, 0xaa, 0xea, 0x37, 0xe2,
+ 0xf4, 0x4e, 0x13, 0xef, 0xef, 0xc4, 0x9a, 0x5a, 0x38, 0x4e, 0x3e, 0x1e,
+ 0xed, 0x7e, 0x50, 0x09, 0x6a, 0x4f, 0xe5, 0xd9, 0xa1, 0x55, 0x5e, 0xca,
+ 0x83, 0x36, 0x92, 0x9f, 0x39, 0x15, 0x6c, 0x2f, 0xc3, 0x76, 0x33, 0xd2,
+ 0x97, 0x30, 0xbe, 0xd5, 0xf2, 0xdf, 0x68, 0x0f, 0xc5, 0x31, 0x6d, 0xcd,
+ 0xbc, 0xc6, 0x3e, 0x69, 0xec, 0x4f, 0x13, 0xbe, 0x36, 0x19, 0xc6, 0x57,
+ 0xd9, 0xb7, 0xaf, 0x4c, 0x4a, 0x1f, 0x23, 0x7b, 0x2c, 0xd4, 0x63, 0x34,
+ 0xdb, 0x84, 0xa7, 0xf5, 0x36, 0x7c, 0x85, 0x7d, 0xec, 0x33, 0x62, 0x58,
+ 0x9b, 0xb8, 0x8b, 0xfd, 0x51, 0xb0, 0xaa, 0xed, 0x2f, 0x4b, 0xfd, 0x8a,
+ 0x68, 0x50, 0x55, 0x24, 0x1b, 0x22, 0x31, 0x4d, 0x15, 0x99, 0x17, 0xfa,
+ 0x3b, 0x90, 0x81, 0xe5, 0x37, 0xa5, 0xcf, 0x37, 0x22, 0xcf, 0xfe, 0x7e,
+ 0x79, 0x67, 0xd4, 0x58, 0xaf, 0x62, 0x65, 0x80, 0x7d, 0x7e, 0x20, 0x1e,
+ 0x4d, 0x2c, 0x62, 0x9f, 0xc7, 0xf3, 0x2a, 0xc7, 0x13, 0xd2, 0xc6, 0xd8,
+ 0xf7, 0xe4, 0x2a, 0x95, 0x7d, 0x67, 0x5f, 0x32, 0xec, 0x4b, 0x86, 0x7d,
+ 0xc9, 0xb0, 0x2f, 0x6e, 0xbf, 0x63, 0xec, 0x73, 0x71, 0x8e, 0x46, 0xf2,
+ 0xc7, 0xd9, 0xdf, 0x99, 0xfd, 0x6c, 0x62, 0xdf, 0x91, 0xaa, 0xe7, 0xbc,
+ 0x35, 0xa7, 0x65, 0xde, 0x1c, 0xe7, 0x55, 0xc3, 0x71, 0x7e, 0x6e, 0x04,
+ 0xa8, 0xbf, 0x0c, 0xed, 0xa0, 0xdc, 0x9f, 0xf9, 0x56, 0x85, 0x89, 0x4e,
+ 0x9a, 0xa0, 0x73, 0xa4, 0x23, 0x9a, 0x68, 0x50, 0x54, 0x78, 0xf5, 0xa0,
+ 0xd6, 0x52, 0x88, 0x18, 0xd4, 0x8f, 0x16, 0x2d, 0x40, 0xd3, 0x0b, 0x94,
+ 0x75, 0x51, 0xbb, 0x91, 0xe0, 0x14, 0xa4, 0x5d, 0x8d, 0xed, 0x1f, 0x2f,
+ 0xcd, 0x9d, 0xc8, 0x0f, 0xb3, 0x4d, 0x69, 0x5f, 0x64, 0x3b, 0xce, 0xcf,
+ 0x0c, 0xe8, 0x41, 0x44, 0xad, 0x41, 0xda, 0x9f, 0xc7, 0x0c, 0x6a, 0x1b,
+ 0xf2, 0x7c, 0x7e, 0x5e, 0x46, 0x71, 0x3e, 0xd6, 0xe6, 0xb5, 0xd2, 0x18,
+ 0x22, 0xec, 0x82, 0xd8, 0x41, 0x38, 0x15, 0x30, 0x83, 0xd2, 0xf7, 0xee,
+ 0x3d, 0x03, 0x9b, 0x9d, 0x79, 0xba, 0xe8, 0x4a, 0xdf, 0x38, 0xcf, 0x13,
+ 0x48, 0x9c, 0x5e, 0xf2, 0x90, 0x35, 0xab, 0x23, 0x8e, 0x6a, 0x1d, 0x81,
+ 0x2a, 0x1d, 0xdd, 0xe9, 0x89, 0x6a, 0xab, 0xc6, 0xfc, 0xe6, 0x9d, 0x03,
+ 0x13, 0x7e, 0x54, 0x4f, 0xe8, 0xa8, 0x9a, 0x78, 0xdc, 0x8b, 0x5a, 0x03,
+ 0x3b, 0x26, 0xff, 0xcc, 0x5b, 0x1c, 0xdb, 0xcd, 0xa5, 0x31, 0xba, 0xb6,
+ 0xef, 0x7f, 0xdd, 0x3e, 0xe3, 0x54, 0xe8, 0x55, 0x7f, 0xe6, 0x31, 0x75,
+ 0x6d, 0x0c, 0x38, 0xb3, 0xb6, 0x63, 0x39, 0x7a, 0x83, 0x0a, 0xe6, 0xeb,
+ 0x7f, 0x32, 0x0b, 0xb5, 0x26, 0xac, 0xc9, 0xc6, 0x54, 0x85, 0x19, 0x4a,
+ 0x71, 0x6e, 0xf0, 0x82, 0x9d, 0x83, 0x6f, 0xc0, 0x71, 0xa4, 0xec, 0x49,
+ 0xdc, 0x79, 0xa7, 0x6a, 0x1e, 0xba, 0xc6, 0x87, 0x4e, 0x96, 0xc7, 0xa6,
+ 0xa3, 0x1d, 0x3f, 0x57, 0xd4, 0x9d, 0xdd, 0xb0, 0xc6, 0x3d, 0x48, 0x06,
+ 0x53, 0xfc, 0x7f, 0xc5, 0x15, 0x2b, 0x13, 0xdd, 0xb0, 0xc7, 0xa7, 0x79,
+ 0xdf, 0xcb, 0x7b, 0x26, 0xd2, 0x99, 0x2b, 0xae, 0xb8, 0x3d, 0x91, 0xc2,
+ 0xc0, 0xb8, 0x7c, 0xf6, 0x62, 0xaa, 0x3e, 0x85, 0xed, 0xbb, 0x35, 0xd4,
+ 0xe9, 0xdd, 0xc8, 0x8c, 0xcb, 0x67, 0xc7, 0x39, 0x65, 0x7c, 0x09, 0x7b,
+ 0xda, 0xe8, 0xff, 0x73, 0xbb, 0xb1, 0x6d, 0xb7, 0x85, 0x4a, 0xdd, 0xa2,
+ 0xee, 0x15, 0xef, 0x3f, 0xb7, 0x29, 0xd0, 0xee, 0x84, 0xb7, 0x42, 0x17,
+ 0xbd, 0x25, 0xbc, 0xf7, 0xd8, 0x66, 0x70, 0xbe, 0xee, 0x38, 0x23, 0xc6,
+ 0x22, 0x7c, 0xba, 0x7b, 0x2d, 0xac, 0x7d, 0x01, 0x58, 0xab, 0xe5, 0x7f,
+ 0x37, 0x75, 0xb8, 0x16, 0xbd, 0xfb, 0xd6, 0xa2, 0xff, 0x31, 0x3a, 0x6e,
+ 0x7d, 0xd0, 0x9d, 0xa7, 0x6f, 0xb5, 0x48, 0x9f, 0xa4, 0x7f, 0x3d, 0xbc,
+ 0x44, 0xb7, 0x5f, 0xe0, 0x7f, 0x29, 0x33, 0xed, 0x60, 0xce, 0x85, 0x32,
+ 0xdb, 0x59, 0x66, 0xdb, 0x45, 0x65, 0x4c, 0x3c, 0x31, 0x29, 0xba, 0x10,
+ 0x95, 0xfd, 0x3e, 0x5d, 0x7c, 0xdb, 0xe9, 0x0d, 0x89, 0x2e, 0xac, 0x1e,
+ 0x1f, 0x22, 0xdd, 0xf7, 0x2a, 0x5e, 0xac, 0x18, 0x00, 0xeb, 0xd0, 0x09,
+ 0xaa, 0x23, 0xc9, 0x85, 0x8a, 0x89, 0xea, 0x01, 0x05, 0x2b, 0xe2, 0x55,
+ 0xd0, 0xea, 0x45, 0xde, 0x8f, 0x1c, 0x2b, 0x28, 0xfd, 0x3d, 0x8a, 0x1a,
+ 0xde, 0x5f, 0x17, 0xff, 0x01, 0xf1, 0x4c, 0xfa, 0x14, 0x67, 0xf9, 0x3b,
+ 0x78, 0xff, 0x95, 0x19, 0xdf, 0xa5, 0x9c, 0xe3, 0xf4, 0x19, 0x06, 0xfa,
+ 0x33, 0x6d, 0xd8, 0x9e, 0x49, 0x46, 0xa8, 0x25, 0xcb, 0x67, 0xf2, 0xbe,
+ 0x19, 0xed, 0xea, 0x85, 0xb4, 0x03, 0xa5, 0xda, 0x84, 0x37, 0xdf, 0x71,
+ 0xdc, 0xff, 0x92, 0xad, 0xf7, 0x3c, 0xa5, 0xf8, 0x68, 0xec, 0xd2, 0xce,
+ 0x71, 0xff, 0x2b, 0xb6, 0x82, 0x37, 0xf5, 0xe8, 0x86, 0x77, 0x94, 0xe3,
+ 0xfe, 0x97, 0xf3, 0x41, 0xcc, 0x1b, 0x88, 0xf4, 0x58, 0x4a, 0x02, 0x5f,
+ 0xcf, 0x87, 0x10, 0x1e, 0x30, 0x71, 0x30, 0x6f, 0xe0, 0xc9, 0x8b, 0x70,
+ 0xe0, 0x43, 0xff, 0x2c, 0x0f, 0xc7, 0xbe, 0xce, 0xd6, 0xd0, 0x6b, 0x9c,
+ 0x73, 0x92, 0x41, 0xa4, 0xea, 0xcc, 0xe3, 0xfe, 0xf7, 0x07, 0xa0, 0xd4,
+ 0x9a, 0x7a, 0xb8, 0xa0, 0xfc, 0xab, 0x93, 0x0a, 0x49, 0x31, 0xf6, 0xcf,
+ 0xc5, 0xb2, 0x24, 0xed, 0xce, 0x20, 0xce, 0x9d, 0x71, 0x6a, 0x68, 0xb3,
+ 0x15, 0xe6, 0x65, 0x18, 0x1f, 0xd6, 0xf1, 0xa4, 0xed, 0x38, 0xef, 0x19,
+ 0x53, 0x89, 0x00, 0xf4, 0xee, 0x77, 0x11, 0x49, 0x2e, 0xa2, 0x5e, 0x8e,
+ 0xe6, 0x75, 0x8c, 0xda, 0x26, 0x9e, 0xb3, 0x9b, 0x83, 0x7d, 0x58, 0x8c,
+ 0x64, 0xb8, 0x18, 0x43, 0x26, 0xd8, 0xef, 0x91, 0x68, 0x37, 0xea, 0xcc,
+ 0x04, 0x0e, 0xb1, 0xdf, 0xa7, 0x97, 0x88, 0x1c, 0x03, 0x2f, 0xff, 0x01,
+ 0x7d, 0x25, 0xbe, 0xe3, 0x71, 0xf6, 0x35, 0xb1, 0xf8, 0x9c, 0x83, 0xd9,
+ 0x7e, 0x9c, 0x30, 0xe6, 0xd2, 0x0e, 0x61, 0x55, 0x99, 0x7e, 0x6f, 0xbf,
+ 0x1d, 0xc4, 0x81, 0x7c, 0xc0, 0xdb, 0x67, 0x87, 0xb0, 0x8f, 0xfe, 0x36,
+ 0x8f, 0xa6, 0x1e, 0xa6, 0xdc, 0x79, 0xc4, 0xb5, 0xc2, 0x70, 0x13, 0x26,
+ 0x87, 0x23, 0xc6, 0x2b, 0x4a, 0x18, 0x63, 0xa3, 0x97, 0x61, 0x62, 0x58,
+ 0xc1, 0x78, 0x94, 0x7d, 0xe7, 0xe7, 0x2f, 0x0f, 0x5f, 0x81, 0xfc, 0xb0,
+ 0x07, 0x3b, 0x5c, 0xbd, 0xba, 0x38, 0x53, 0xfa, 0x7f, 0x19, 0x72, 0xa3,
+ 0xf0, 0x2e, 0x1a, 0x08, 0xe2, 0xa9, 0xbc, 0xd7, 0xab, 0x0f, 0x84, 0x30,
+ 0x9a, 0xff, 0x36, 0xe7, 0x4d, 0x64, 0x6b, 0x18, 0xb1, 0xc7, 0xdc, 0x39,
+ 0xac, 0x33, 0x29, 0xac, 0x18, 0x5f, 0x19, 0xcb, 0x34, 0xc6, 0x99, 0x04,
+ 0x71, 0x48, 0x7c, 0xdc, 0x4f, 0x0c, 0x12, 0x1f, 0x7f, 0x4d, 0x41, 0x6d,
+ 0x02, 0x7d, 0x93, 0xe5, 0xe7, 0x0a, 0xed, 0xdf, 0x8b, 0x75, 0x41, 0x03,
+ 0x76, 0x46, 0xec, 0xb4, 0x8c, 0xcb, 0xf2, 0x59, 0xe6, 0xbf, 0x1a, 0xd6,
+ 0xfe, 0x6a, 0xec, 0xa0, 0x8f, 0x3d, 0xba, 0x53, 0xee, 0x3b, 0xce, 0x7d,
+ 0xf1, 0x3a, 0xda, 0x18, 0x6e, 0xaa, 0x42, 0xd4, 0x78, 0xcb, 0xed, 0x9b,
+ 0x85, 0xb1, 0xbc, 0xc4, 0x50, 0x8d, 0xf1, 0xed, 0x28, 0xdb, 0xea, 0x60,
+ 0x3b, 0x06, 0xbe, 0x3d, 0xd9, 0x86, 0x7f, 0x9c, 0x8c, 0xe1, 0x1f, 0x26,
+ 0x75, 0xfc, 0xfd, 0xa4, 0x86, 0x67, 0x2e, 0xc2, 0xf5, 0x3b, 0xa9, 0x2b,
+ 0xc1, 0x30, 0x03, 0x5b, 0x32, 0x15, 0xd8, 0x36, 0x5c, 0x8d, 0xbe, 0xe1,
+ 0xe6, 0xd8, 0x73, 0xc4, 0xe3, 0x7f, 0x30, 0x6e, 0xc7, 0x54, 0x43, 0x87,
+ 0xeb, 0x33, 0x8f, 0xf0, 0xfe, 0xa3, 0xc3, 0xcd, 0x9c, 0x43, 0xc7, 0x51,
+ 0xe3, 0xad, 0x89, 0x43, 0xc4, 0xf7, 0xe3, 0xa1, 0x88, 0x36, 0xa5, 0x46,
+ 0xb4, 0x24, 0x7c, 0xb0, 0xdb, 0x54, 0x58, 0x73, 0x22, 0x39, 0x7a, 0x31,
+ 0x42, 0xfa, 0x7d, 0x1c, 0x5b, 0x44, 0xb3, 0x54, 0x83, 0xf6, 0xcb, 0x98,
+ 0xa1, 0x76, 0x10, 0x5f, 0xaa, 0xf1, 0xfe, 0x70, 0xa4, 0xdf, 0x52, 0xef,
+ 0x80, 0xd5, 0xe0, 0x38, 0x5f, 0x8d, 0x63, 0xc3, 0x5c, 0x13, 0xc9, 0x39,
+ 0x8c, 0x05, 0x57, 0x98, 0x49, 0x30, 0x8e, 0xe1, 0xf4, 0x80, 0x1e, 0xfe,
+ 0x7f, 0x94, 0x3b, 0xf1, 0xdf, 0xbb, 0x23, 0x9a, 0xa6, 0xb6, 0x5a, 0xfb,
+ 0x54, 0x92, 0x8d, 0x46, 0x68, 0x61, 0xf3, 0x56, 0x6c, 0x74, 0x79, 0x82,
+ 0x82, 0xa0, 0xde, 0x81, 0xbe, 0x0c, 0x2b, 0x85, 0x9a, 0x7b, 0x06, 0xd5,
+ 0xe6, 0x69, 0x43, 0x8d, 0x1c, 0xed, 0x56, 0x89, 0xb7, 0x8b, 0x4f, 0x3b,
+ 0x5a, 0xa3, 0xe3, 0xb4, 0x2f, 0x96, 0x36, 0x35, 0x34, 0x70, 0x9e, 0xeb,
+ 0x39, 0xcf, 0xed, 0x85, 0x6a, 0xbc, 0x33, 0x0c, 0x6b, 0xae, 0x19, 0xe9,
+ 0x7a, 0x40, 0xad, 0xc6, 0xdb, 0xa3, 0xd5, 0x38, 0x39, 0xec, 0xc5, 0x5b,
+ 0xc3, 0x8e, 0x73, 0x8f, 0x51, 0x87, 0x8a, 0x38, 0xe6, 0x54, 0x20, 0x7a,
+ 0x66, 0x04, 0x16, 0x7e, 0xc3, 0xb2, 0xbf, 0x1c, 0x0e, 0xe3, 0x57, 0xc3,
+ 0x1f, 0xc3, 0x33, 0x0d, 0xc9, 0x63, 0xb3, 0x19, 0x23, 0xa7, 0x69, 0x3f,
+ 0xa7, 0xed, 0x48, 0xcf, 0x3c, 0x4f, 0x64, 0x23, 0x79, 0xcb, 0xfa, 0x2f,
+ 0x2a, 0x91, 0xd4, 0x2b, 0x4a, 0x44, 0x1b, 0x50, 0x42, 0x78, 0x97, 0x76,
+ 0x7a, 0x2a, 0xdf, 0x9c, 0xf8, 0x01, 0xdb, 0xff, 0xb5, 0xf1, 0x0f, 0xce,
+ 0x54, 0xa3, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xd3, 0x77, 0xff, 0x91, 0x31,
+ 0xea, 0x1f, 0x32, 0xd4, 0x39, 0xfb, 0xf3, 0xcc, 0x6f, 0xc5, 0x2f, 0x99,
+ 0xaf, 0x04, 0xe7, 0xf1, 0x72, 0xfc, 0x4f, 0x77, 0x6c, 0xc7, 0x9c, 0xbf,
+ 0x09, 0xc9, 0xf8, 0x3a, 0x1b, 0x8b, 0x18, 0x24, 0xe3, 0x3c, 0xea, 0xa4,
+ 0x82, 0x32, 0x46, 0x19, 0xab, 0xab, 0x4b, 0x6d, 0x83, 0xf2, 0x90, 0x8a,
+ 0x6a, 0xc7, 0x79, 0xcc, 0x28, 0x3d, 0x0f, 0x95, 0xc7, 0xfa, 0x31, 0xde,
+ 0x97, 0xf1, 0xbe, 0xe3, 0x11, 0xdd, 0x6b, 0xea, 0xd5, 0xfc, 0x1e, 0xb1,
+ 0x92, 0xb8, 0x33, 0xc0, 0xef, 0xb1, 0xe4, 0xf9, 0xef, 0xde, 0xba, 0x8b,
+ 0x9f, 0xd3, 0x4e, 0xdd, 0xf6, 0xee, 0xe4, 0x77, 0x19, 0xcb, 0xab, 0xb4,
+ 0x9b, 0x0f, 0xb3, 0x13, 0xb1, 0x91, 0x18, 0xed, 0xe9, 0x94, 0xc4, 0x15,
+ 0x2b, 0x64, 0xfa, 0x2d, 0xd5, 0x84, 0x46, 0x9c, 0xf0, 0x2b, 0xe6, 0x06,
+ 0x68, 0x79, 0x0b, 0x9f, 0xea, 0xf0, 0xe0, 0xaf, 0x3a, 0x14, 0xcc, 0xd6,
+ 0x37, 0x20, 0x7b, 0xad, 0xe5, 0xd4, 0xeb, 0x7b, 0x55, 0xf1, 0x81, 0x8a,
+ 0x34, 0x2c, 0xfa, 0x1d, 0x12, 0xe4, 0x4a, 0x75, 0x7f, 0xaa, 0xe0, 0x44,
+ 0x3c, 0x4a, 0x9b, 0xdb, 0x82, 0x6d, 0x9c, 0xf3, 0x59, 0x69, 0xf8, 0x03,
+ 0xa6, 0x09, 0x7b, 0x00, 0xfe, 0x2a, 0xfa, 0xfe, 0x95, 0x03, 0xcd, 0x1b,
+ 0xc6, 0x94, 0x48, 0x22, 0xad, 0x44, 0xba, 0xa9, 0x6f, 0xe3, 0xb4, 0x8b,
+ 0x1b, 0x11, 0xad, 0x42, 0x91, 0x76, 0x4c, 0xb4, 0xe4, 0xb7, 0x60, 0x60,
+ 0x52, 0x3e, 0x27, 0xa0, 0xe7, 0x7f, 0x5c, 0xea, 0x3b, 0xfc, 0x3e, 0xf6,
+ 0x61, 0xbf, 0xfd, 0xba, 0x93, 0x0b, 0x46, 0xb4, 0x9c, 0xfb, 0x7d, 0x3d,
+ 0xbf, 0xc3, 0x5f, 0x61, 0x3e, 0x88, 0xe7, 0xed, 0x37, 0xe7, 0x94, 0xcb,
+ 0x15, 0xfb, 0x7a, 0x69, 0x7f, 0xfe, 0xb7, 0x93, 0x0c, 0xb9, 0xfd, 0xf1,
+ 0xd7, 0xb0, 0x8d, 0xcf, 0x0c, 0xb0, 0x8d, 0x4c, 0xb9, 0x3f, 0x40, 0x20,
+ 0x2d, 0x71, 0x38, 0xa2, 0x2d, 0x50, 0x9a, 0x8d, 0x01, 0x25, 0x12, 0xbb,
+ 0x57, 0x69, 0x4d, 0x8c, 0x91, 0x5f, 0x6e, 0x47, 0xb1, 0x4f, 0xd1, 0x7c,
+ 0xb1, 0x3f, 0x0b, 0xf2, 0x50, 0x3c, 0x03, 0x08, 0xcc, 0xd7, 0x17, 0x62,
+ 0xb3, 0x3b, 0xa7, 0x50, 0xc2, 0x03, 0x1a, 0x6a, 0xc9, 0x5f, 0xc2, 0x13,
+ 0xc0, 0xe4, 0x10, 0xb9, 0x5c, 0xbc, 0x19, 0x9f, 0x63, 0x2c, 0x98, 0xc7,
+ 0x32, 0x5f, 0x0c, 0x9e, 0xc7, 0x2f, 0xa5, 0xdf, 0x26, 0xc0, 0xcc, 0x29,
+ 0xf2, 0xb2, 0xd4, 0x7f, 0x41, 0x52, 0xee, 0x3d, 0x6e, 0x43, 0xc9, 0xd8,
+ 0x91, 0x3d, 0x80, 0x3e, 0x15, 0xf7, 0x24, 0xef, 0x0f, 0x63, 0x33, 0x4e,
+ 0xc7, 0xa3, 0xa9, 0x82, 0x12, 0x35, 0x86, 0x14, 0xc3, 0xbf, 0x8d, 0xed,
+ 0xed, 0x60, 0x99, 0xed, 0xbc, 0x1e, 0x88, 0xea, 0x5d, 0x77, 0x28, 0xc9,
+ 0x2b, 0xab, 0x58, 0xe6, 0xa4, 0x11, 0x25, 0xcf, 0x8c, 0x4e, 0xaf, 0x82,
+ 0xe1, 0x7f, 0x22, 0x2f, 0xb2, 0x12, 0xca, 0x96, 0xc2, 0xe3, 0x6a, 0x11,
+ 0x8f, 0x7e, 0x5d, 0xd2, 0xd9, 0x49, 0xf9, 0xee, 0xb6, 0xed, 0x1d, 0x68,
+ 0xaa, 0xf9, 0xed, 0x7b, 0xda, 0x9c, 0x8b, 0xef, 0xb5, 0x06, 0x47, 0xe9,
+ 0x7f, 0x1e, 0xbd, 0x8a, 0x73, 0x27, 0xfc, 0x28, 0x19, 0xf3, 0x41, 0xee,
+ 0x79, 0x90, 0xf3, 0x26, 0xc3, 0x1e, 0x7c, 0xe0, 0x24, 0x57, 0xcb, 0xbd,
+ 0x6a, 0xa4, 0xba, 0x5b, 0xc3, 0x5e, 0xb4, 0x26, 0xb6, 0x12, 0x0b, 0x8e,
+ 0xaf, 0x5e, 0xc6, 0x67, 0x51, 0xe3, 0x39, 0x34, 0x6b, 0x5b, 0x21, 0x9f,
+ 0xcf, 0xd2, 0x66, 0x97, 0x49, 0x5d, 0x96, 0x29, 0x72, 0x1f, 0xc1, 0x9a,
+ 0x2d, 0x86, 0x83, 0xe7, 0x0d, 0x58, 0x95, 0xe6, 0x41, 0xe5, 0x84, 0xfd,
+ 0x1b, 0x27, 0xe9, 0xc5, 0x4a, 0xfa, 0xa5, 0x41, 0xda, 0xab, 0xf9, 0xcd,
+ 0xa8, 0x76, 0x94, 0x99, 0x82, 0xc7, 0xb4, 0x94, 0xe3, 0xf9, 0x2d, 0xca,
+ 0xeb, 0xf9, 0x7e, 0xe5, 0x54, 0x5e, 0xea, 0x1e, 0x54, 0x4e, 0xe6, 0x25,
+ 0x1e, 0x36, 0x69, 0x47, 0xc8, 0x6f, 0xc8, 0xa9, 0xd4, 0x3e, 0x03, 0xca,
+ 0x36, 0xa3, 0x96, 0x3c, 0x5f, 0x8f, 0x8d, 0xb0, 0xbf, 0xfb, 0x3b, 0x60,
+ 0x6c, 0x37, 0x7c, 0x38, 0x1e, 0x44, 0xa0, 0xcf, 0xf0, 0xca, 0x77, 0xe6,
+ 0x03, 0x52, 0xb7, 0x49, 0xdb, 0x9a, 0x3f, 0x47, 0xff, 0x2a, 0x7e, 0xdf,
+ 0xdf, 0x51, 0xbe, 0xf7, 0x0b, 0x67, 0x6a, 0xb5, 0xca, 0xef, 0x7f, 0xea,
+ 0xe1, 0x50, 0x58, 0x77, 0x26, 0x3f, 0x17, 0x2e, 0xa5, 0x92, 0x3f, 0xd6,
+ 0xc3, 0x0a, 0x46, 0xac, 0x1c, 0x73, 0x85, 0xbe, 0x4c, 0x3b, 0xfd, 0x2d,
+ 0xcc, 0x58, 0x99, 0x24, 0xbe, 0x93, 0xf7, 0xb2, 0xcd, 0x0a, 0x3d, 0x80,
+ 0x9b, 0xec, 0x66, 0x4f, 0x51, 0x7f, 0x2a, 0x31, 0xcc, 0xc3, 0x98, 0x2e,
+ 0x1c, 0xef, 0x52, 0xce, 0xdd, 0xa4, 0xbd, 0xc5, 0x7e, 0x57, 0xe9, 0x7a,
+ 0xac, 0x4a, 0x69, 0xd2, 0x5e, 0xcf, 0x27, 0xe9, 0xe3, 0x3d, 0x6c, 0x37,
+ 0x80, 0xd7, 0xed, 0x5a, 0xe6, 0x20, 0x91, 0xa4, 0x45, 0x81, 0x37, 0x77,
+ 0x84, 0x41, 0xce, 0x37, 0xe3, 0xaf, 0x1b, 0x8c, 0xff, 0x12, 0xa3, 0xd5,
+ 0x5b, 0x96, 0x24, 0xb0, 0x3e, 0x0f, 0xef, 0xba, 0x0e, 0x13, 0xf7, 0x30,
+ 0xb6, 0xdf, 0xc7, 0x78, 0xf9, 0x20, 0x63, 0xe1, 0x8e, 0x38, 0xc7, 0x56,
+ 0xef, 0x38, 0x95, 0xfa, 0x66, 0xc9, 0x67, 0x30, 0xc0, 0x58, 0x7c, 0x37,
+ 0xe3, 0xcb, 0x16, 0x7e, 0x7e, 0x29, 0xff, 0x1f, 0xce, 0x7d, 0xcc, 0xa7,
+ 0x9e, 0xbf, 0x48, 0x26, 0xd4, 0x51, 0xbd, 0x35, 0xb6, 0x95, 0xb1, 0x98,
+ 0x72, 0xad, 0x5a, 0xd3, 0x71, 0xae, 0x8c, 0x46, 0x92, 0x3e, 0xc5, 0xc0,
+ 0x73, 0x13, 0xc7, 0x1d, 0x6d, 0x8e, 0xe4, 0x52, 0xe5, 0x38, 0x28, 0x63,
+ 0x95, 0x1c, 0x41, 0xf0, 0x41, 0xf2, 0x84, 0x99, 0x18, 0xa1, 0xe2, 0xe6,
+ 0x61, 0xc9, 0x13, 0xc2, 0x58, 0x65, 0x7f, 0x09, 0xcf, 0xb5, 0x79, 0xd1,
+ 0xc5, 0x1c, 0xeb, 0x16, 0x3b, 0x80, 0x3b, 0x88, 0xa5, 0x2b, 0x6c, 0xe6,
+ 0x4e, 0xc1, 0x10, 0x6e, 0xb5, 0xbd, 0x38, 0xdc, 0xc6, 0x1c, 0x28, 0x54,
+ 0x89, 0x77, 0x0d, 0x0f, 0x8e, 0x18, 0x41, 0xe4, 0x5c, 0x7f, 0xd8, 0x41,
+ 0x0c, 0xa4, 0x1e, 0x55, 0xc9, 0x1d, 0x44, 0x87, 0x1e, 0xea, 0x53, 0x45,
+ 0xea, 0xbc, 0x0e, 0x3f, 0x2c, 0x17, 0x90, 0x7e, 0x49, 0x3e, 0xf0, 0x33,
+ 0x27, 0x35, 0x47, 0xea, 0xc3, 0x0a, 0x98, 0x32, 0x0e, 0xe1, 0xb7, 0x06,
+ 0xfa, 0x26, 0x3a, 0xc8, 0xed, 0x66, 0x0e, 0xf5, 0x0c, 0xb9, 0x75, 0x1d,
+ 0x5e, 0xd3, 0x85, 0x5b, 0xbf, 0x8a, 0x20, 0x7d, 0xb7, 0x7f, 0x22, 0xba,
+ 0xe1, 0x8c, 0xe2, 0xc1, 0x4b, 0x7a, 0x2d, 0x79, 0x9f, 0x89, 0xed, 0x13,
+ 0xf0, 0x6e, 0x5d, 0x62, 0x20, 0x3d, 0xd1, 0x9b, 0x98, 0xc5, 0xb4, 0xd7,
+ 0xbb, 0xa4, 0xc8, 0x89, 0x3e, 0x43, 0xdd, 0xae, 0x8d, 0xbb, 0x9c, 0xa8,
+ 0xc8, 0x07, 0x82, 0x8e, 0x73, 0x52, 0x17, 0x3d, 0x03, 0x07, 0x4a, 0x3a,
+ 0xde, 0xcf, 0xcf, 0xfd, 0x25, 0x1d, 0x6f, 0xa1, 0x3c, 0xfa, 0x1f, 0xb6,
+ 0x5d, 0xc4, 0x63, 0x34, 0x54, 0x9a, 0xc2, 0x6f, 0x88, 0xc3, 0xc4, 0x93,
+ 0x24, 0x75, 0xfc, 0x42, 0x7e, 0xbd, 0xe0, 0x36, 0xa7, 0xbb, 0xdd, 0xc5,
+ 0xef, 0xa4, 0x7a, 0x80, 0x76, 0x20, 0x7a, 0x78, 0xad, 0x94, 0xdb, 0x38,
+ 0xce, 0x90, 0x21, 0x3a, 0x2e, 0xe7, 0x65, 0xa2, 0xeb, 0x36, 0xc9, 0xb1,
+ 0xfa, 0x81, 0xdf, 0xb0, 0xac, 0x87, 0xb8, 0x6b, 0xe2, 0x6b, 0xdd, 0x62,
+ 0x3b, 0xb3, 0xdc, 0x58, 0x79, 0xd5, 0x42, 0xc7, 0xf9, 0x4a, 0x5c, 0xc3,
+ 0x7b, 0x7a, 0x6b, 0xa2, 0x5d, 0x8d, 0xb0, 0xaf, 0x49, 0xd8, 0x93, 0x1d,
+ 0x9c, 0xbb, 0x2b, 0x90, 0x0c, 0x89, 0xad, 0x61, 0x43, 0x45, 0x11, 0xc3,
+ 0x71, 0xca, 0xd6, 0x63, 0xdb, 0x38, 0x67, 0xfb, 0x42, 0x5d, 0xe4, 0x71,
+ 0x6a, 0x27, 0xd3, 0x7f, 0xf2, 0x27, 0xdd, 0x7a, 0x04, 0xef, 0x38, 0xb9,
+ 0x90, 0xc3, 0x38, 0x29, 0xb9, 0xd1, 0x7c, 0x1c, 0x0e, 0x7a, 0xf0, 0x62,
+ 0xac, 0x11, 0xc9, 0x7a, 0x05, 0x35, 0xfa, 0x9b, 0xce, 0x77, 0x42, 0xd2,
+ 0x0e, 0x73, 0x3c, 0xf5, 0x56, 0x8f, 0xe4, 0x80, 0x5e, 0x5d, 0xe4, 0x76,
+ 0x31, 0xc7, 0xbd, 0xb4, 0xfd, 0x7f, 0x75, 0x8e, 0x87, 0xa4, 0xfd, 0x48,
+ 0x50, 0x53, 0x7f, 0xd7, 0x1c, 0x7e, 0xdf, 0xf9, 0x81, 0x2b, 0x33, 0xe3,
+ 0xea, 0x01, 0xaa, 0xc8, 0x23, 0x54, 0x54, 0x8b, 0xcc, 0x72, 0x3b, 0xe2,
+ 0x67, 0x73, 0x79, 0x4f, 0x9e, 0x89, 0x8d, 0x6c, 0x61, 0xbb, 0xcf, 0x39,
+ 0x68, 0x94, 0xef, 0xd3, 0x1e, 0x29, 0x6b, 0x4d, 0x1e, 0x5a, 0xe1, 0xc5,
+ 0x52, 0xb4, 0xc4, 0x97, 0x2d, 0x97, 0xb1, 0xa8, 0x66, 0x52, 0xf3, 0xc3,
+ 0x6a, 0xf4, 0x10, 0x8b, 0xdf, 0x68, 0x6b, 0xc3, 0x72, 0xe6, 0x8c, 0xef,
+ 0x10, 0x5c, 0x7a, 0x75, 0x0f, 0xa6, 0x38, 0xbe, 0x27, 0x0d, 0x59, 0x2f,
+ 0x70, 0x70, 0x4b, 0xdc, 0x4a, 0xd1, 0x63, 0xad, 0x59, 0xb4, 0x9d, 0x6a,
+ 0x5d, 0xe2, 0x7c, 0x2d, 0x6a, 0x4c, 0x6f, 0xec, 0x1d, 0x44, 0x8c, 0x1d,
+ 0xe4, 0x39, 0x5a, 0x7d, 0x4b, 0xc2, 0x47, 0xed, 0xbe, 0x6c, 0x47, 0x13,
+ 0x47, 0x94, 0xa2, 0x3f, 0xbc, 0xc0, 0xb9, 0x7d, 0xcd, 0xd6, 0x37, 0x56,
+ 0x7a, 0x8a, 0xdf, 0x5f, 0x71, 0xf3, 0xd1, 0xb2, 0x3f, 0x84, 0x4b, 0xb8,
+ 0xe1, 0xf7, 0x9f, 0xb2, 0x71, 0x86, 0x54, 0x88, 0x79, 0x29, 0xce, 0xf4,
+ 0x19, 0x53, 0x8a, 0x4f, 0xaf, 0x25, 0xae, 0x0a, 0x96, 0x56, 0x90, 0x13,
+ 0x4a, 0xec, 0xf7, 0xfb, 0xdf, 0x61, 0x19, 0x72, 0xba, 0xe3, 0xb1, 0xeb,
+ 0x5b, 0x13, 0x7e, 0x24, 0xad, 0x4a, 0xfa, 0xe5, 0x2c, 0x33, 0xe4, 0xbf,
+ 0xaa, 0x60, 0x35, 0x06, 0x68, 0xd7, 0x35, 0xcc, 0x57, 0x5b, 0xd2, 0x13,
+ 0x8c, 0xe1, 0x6d, 0x78, 0x70, 0x82, 0x23, 0x6b, 0x18, 0x6c, 0x54, 0x4d,
+ 0x59, 0x83, 0x08, 0xc2, 0xd7, 0xf0, 0xe0, 0x0d, 0xaa, 0x79, 0x1c, 0x3d,
+ 0x1d, 0xfe, 0xce, 0x44, 0x01, 0xfe, 0x7a, 0x73, 0x13, 0xe2, 0x69, 0xc9,
+ 0x3b, 0x05, 0x23, 0x93, 0x5b, 0x89, 0x5a, 0x8d, 0x75, 0xd7, 0x96, 0xf5,
+ 0x0d, 0xb5, 0xd6, 0x94, 0xfc, 0x53, 0xeb, 0x7c, 0xc5, 0xc5, 0xd2, 0x20,
+ 0xf3, 0x85, 0x1f, 0x87, 0xff, 0xcf, 0xea, 0x27, 0x38, 0x27, 0xd2, 0x17,
+ 0xf9, 0x2f, 0x79, 0x3f, 0xbc, 0x2a, 0xb1, 0xb0, 0x77, 0xdc, 0xcb, 0xfc,
+ 0x4a, 0xe6, 0x4c, 0xe2, 0xf1, 0x6b, 0xff, 0xf5, 0x79, 0xfa, 0x8b, 0x8f,
+ 0xba, 0x7f, 0x44, 0xb7, 0x08, 0xf3, 0x8e, 0xa3, 0xc7, 0x23, 0xe1, 0x0a,
+ 0x45, 0xc3, 0xf6, 0xb6, 0x7f, 0xa7, 0x8d, 0x80, 0x38, 0x06, 0x12, 0xeb,
+ 0x5a, 0x6c, 0x19, 0xaf, 0x98, 0x51, 0xaf, 0x67, 0x4d, 0xb9, 0xde, 0x80,
+ 0x6e, 0xa5, 0xa4, 0xde, 0x68, 0x3c, 0xd2, 0xb3, 0x8d, 0xf5, 0x1e, 0x65,
+ 0xbd, 0x24, 0x63, 0xe7, 0x3d, 0x13, 0x41, 0x37, 0x9f, 0xb3, 0xc6, 0xab,
+ 0x67, 0xb6, 0x77, 0xbe, 0xde, 0xe3, 0xba, 0x35, 0xe5, 0xb6, 0xb7, 0x38,
+ 0xb2, 0xb1, 0xc2, 0xe3, 0x45, 0x9a, 0xf5, 0xa6, 0x58, 0xef, 0xf5, 0x09,
+ 0x59, 0x8f, 0xc0, 0x0d, 0xe3, 0x76, 0xe6, 0xb8, 0x47, 0xd7, 0x83, 0x27,
+ 0x91, 0x24, 0xe6, 0xba, 0x73, 0x79, 0xc3, 0x58, 0x7e, 0x33, 0xb6, 0xeb,
+ 0x87, 0xe2, 0x95, 0xac, 0x77, 0x44, 0x3f, 0x14, 0xf6, 0xd1, 0xaf, 0xd6,
+ 0x51, 0x5e, 0x2f, 0xf3, 0x1a, 0x95, 0xfe, 0xb2, 0x65, 0x5c, 0x62, 0xbf,
+ 0x41, 0x5e, 0x12, 0xa2, 0xcd, 0xc9, 0x98, 0xa5, 0x5d, 0x99, 0x53, 0x19,
+ 0x5f, 0x24, 0x36, 0xee, 0x8e, 0x4f, 0x99, 0x7b, 0x40, 0x72, 0xdd, 0x7a,
+ 0x0b, 0x7d, 0x6d, 0x12, 0xff, 0x14, 0x62, 0x6f, 0x03, 0xf3, 0x4f, 0x69,
+ 0x23, 0x84, 0x6d, 0xf4, 0xed, 0xfd, 0x86, 0xe3, 0x3c, 0x6f, 0xcc, 0xc7,
+ 0x01, 0x23, 0x92, 0x12, 0x3b, 0x7c, 0xd3, 0x58, 0x76, 0xa5, 0xe4, 0x96,
+ 0xc0, 0x9f, 0x60, 0x8a, 0xb6, 0x51, 0xa5, 0x8b, 0xbf, 0x29, 0x08, 0x47,
+ 0xbd, 0x5a, 0x8d, 0xe2, 0xc0, 0xbf, 0x78, 0xe1, 0xc6, 0x85, 0x1c, 0x7b,
+ 0xed, 0xf5, 0x0a, 0xde, 0xbf, 0x4a, 0xc1, 0xa1, 0xab, 0xa2, 0xe1, 0x11,
+ 0x65, 0x16, 0xb1, 0x35, 0xda, 0xdd, 0xa9, 0x58, 0x47, 0x59, 0x37, 0xd9,
+ 0xe6, 0x89, 0x84, 0xa1, 0xd4, 0xd1, 0xef, 0x5b, 0x34, 0x09, 0xfd, 0xde,
+ 0x81, 0x68, 0xf8, 0x51, 0xfe, 0xf7, 0x4c, 0x28, 0x98, 0xd0, 0x23, 0x49,
+ 0xb8, 0xf2, 0xd9, 0x36, 0xd3, 0xce, 0xab, 0xa3, 0x8e, 0x73, 0x2c, 0xde,
+ 0x1a, 0x3c, 0x86, 0x37, 0x89, 0x6d, 0xd2, 0x4e, 0x19, 0xeb, 0xc1, 0x5c,
+ 0x56, 0x4f, 0x76, 0x2a, 0x8e, 0x57, 0xf8, 0xc3, 0xfa, 0xbc, 0xc4, 0xc3,
+ 0x72, 0x7f, 0xcb, 0x71, 0xd1, 0x71, 0xde, 0x34, 0x8a, 0xb2, 0x82, 0x1d,
+ 0x91, 0x14, 0x30, 0x1f, 0x93, 0x7a, 0xa4, 0x6b, 0x8a, 0x3a, 0x08, 0xd3,
+ 0xdf, 0xe6, 0xe9, 0x8d, 0x38, 0xee, 0x8b, 0x04, 0x8f, 0x2b, 0xcb, 0xcf,
+ 0xaa, 0x58, 0xb4, 0xfe, 0x09, 0xa5, 0x75, 0x43, 0x15, 0xf4, 0x64, 0x41,
+ 0x99, 0x2b, 0x3a, 0x09, 0x07, 0xc8, 0xa5, 0xd6, 0xc1, 0x8d, 0xd1, 0xb8,
+ 0xcd, 0xf6, 0x26, 0xa7, 0xd1, 0x4c, 0xdb, 0xd7, 0x7b, 0xee, 0x23, 0x0f,
+ 0x04, 0x3e, 0xce, 0x24, 0x41, 0xfa, 0xda, 0x88, 0xd4, 0xa7, 0x1c, 0xe7,
+ 0x7e, 0xf6, 0x75, 0x07, 0xfb, 0xfa, 0x60, 0xfc, 0x3d, 0xe7, 0x5f, 0x5d,
+ 0x99, 0x37, 0x62, 0x44, 0xbf, 0x54, 0xee, 0xbb, 0xcc, 0xf5, 0x45, 0xae,
+ 0x0f, 0x37, 0xcf, 0x61, 0xbe, 0xd2, 0x21, 0xb8, 0x71, 0xd2, 0x4b, 0xdc,
+ 0xa0, 0x3c, 0xc6, 0x10, 0xf5, 0xd2, 0x38, 0xec, 0x01, 0xe3, 0x5b, 0x38,
+ 0xa5, 0xa8, 0x24, 0x42, 0x41, 0xf8, 0x75, 0x07, 0x0f, 0x90, 0x33, 0x24,
+ 0xe7, 0xd4, 0xe1, 0x73, 0x86, 0x1f, 0xb3, 0xa2, 0xea, 0x65, 0x1e, 0xce,
+ 0xc9, 0x81, 0xb8, 0x7c, 0xf7, 0x61, 0x6a, 0x8e, 0x07, 0x9b, 0xc9, 0x25,
+ 0x82, 0x51, 0x75, 0x9e, 0xdc, 0xf7, 0xb7, 0xcb, 0x77, 0xf6, 0x7f, 0xae,
+ 0x82, 0xfb, 0x69, 0x15, 0x6a, 0xb4, 0x37, 0x2c, 0xf7, 0xbb, 0x0c, 0xf9,
+ 0xae, 0xa0, 0x39, 0xee, 0xe5, 0xbc, 0x38, 0xf0, 0x48, 0x7a, 0x1f, 0xe5,
+ 0xfd, 0xb8, 0x7c, 0x4e, 0xde, 0xcf, 0x71, 0x27, 0xf7, 0x29, 0x82, 0x33,
+ 0x3f, 0x72, 0x5e, 0x64, 0x1c, 0x09, 0xf2, 0xf9, 0xe7, 0xd8, 0xf6, 0xd1,
+ 0xf8, 0xf3, 0xce, 0x3c, 0xe2, 0xeb, 0xb1, 0x84, 0x86, 0xf9, 0x57, 0x35,
+ 0xe1, 0xf8, 0x9d, 0x32, 0x66, 0x05, 0xb3, 0xf4, 0x2f, 0xf8, 0x24, 0xcf,
+ 0xac, 0xd5, 0xe7, 0xe2, 0xe6, 0x3b, 0x8a, 0xf7, 0xaa, 0xa2, 0xb2, 0x4e,
+ 0xa8, 0xa1, 0xea, 0xaa, 0x06, 0x68, 0xa5, 0x7b, 0xcb, 0xa3, 0xde, 0xee,
+ 0x59, 0x8a, 0x1e, 0xbc, 0x4d, 0x91, 0xe7, 0xbf, 0x24, 0xb7, 0x75, 0x9c,
+ 0x07, 0x38, 0x5f, 0x2d, 0xf1, 0x00, 0x4e, 0xb3, 0x9d, 0x5e, 0xea, 0x6f,
+ 0xe5, 0xf9, 0xf9, 0x2a, 0xd7, 0xff, 0xb9, 0xa3, 0x7d, 0x4a, 0xea, 0x8a,
+ 0x8c, 0x85, 0x5d, 0x37, 0x2b, 0x1c, 0x50, 0xb5, 0xe8, 0xd9, 0xd5, 0x19,
+ 0xcb, 0xf6, 0xba, 0xdf, 0x83, 0x1d, 0xaf, 0x9d, 0x5f, 0xf3, 0x3a, 0xe3,
+ 0xc6, 0xa3, 0x65, 0xd7, 0x07, 0x71, 0xdc, 0xa9, 0x6f, 0xb7, 0x82, 0x95,
+ 0x90, 0xb8, 0xd4, 0x1c, 0xfb, 0x0a, 0xe5, 0xfe, 0xc0, 0x28, 0xc6, 0xac,
+ 0xfd, 0x46, 0x24, 0x6b, 0xd1, 0x1f, 0x52, 0xcc, 0x13, 0x3b, 0x25, 0x76,
+ 0x4f, 0xd6, 0xfa, 0x50, 0x3b, 0x1f, 0x95, 0xed, 0x91, 0xfe, 0x05, 0xcc,
+ 0x9b, 0x3c, 0x1d, 0x12, 0xeb, 0x64, 0x7e, 0xdc, 0x32, 0x6c, 0xab, 0x0a,
+ 0xcb, 0xd9, 0xc7, 0x78, 0xfb, 0xef, 0x8b, 0x13, 0x22, 0x47, 0xac, 0x33,
+ 0xd2, 0x9f, 0xc4, 0xef, 0x2b, 0x0b, 0x46, 0x65, 0x59, 0x4f, 0xf2, 0xdf,
+ 0x90, 0xca, 0xab, 0xe4, 0x19, 0x15, 0xc1, 0xde, 0x8e, 0x46, 0x5e, 0xf2,
+ 0xdc, 0x7b, 0xc3, 0xda, 0xfc, 0xf9, 0x75, 0x3c, 0x64, 0x8d, 0x0a, 0xa8,
+ 0x57, 0x0b, 0x66, 0x13, 0x7d, 0x83, 0x32, 0x3e, 0x8b, 0x56, 0x2e, 0x39,
+ 0x7a, 0xe7, 0x5d, 0x77, 0xd3, 0x9f, 0x9f, 0x63, 0x8b, 0xa3, 0xe4, 0x33,
+ 0x96, 0xeb, 0x19, 0xe2, 0xeb, 0x33, 0xd7, 0xf5, 0x24, 0x86, 0x94, 0xd7,
+ 0x06, 0x1b, 0x30, 0xb8, 0xfb, 0x0e, 0x68, 0x8d, 0x45, 0x1c, 0x52, 0xcd,
+ 0xc5, 0x58, 0x96, 0x7d, 0xdb, 0x57, 0xe4, 0xe0, 0xb5, 0x18, 0xd8, 0x1d,
+ 0x47, 0x6e, 0x8e, 0x3c, 0x93, 0x7b, 0x7e, 0x08, 0x4e, 0x6e, 0xdf, 0x7d,
+ 0x99, 0xe4, 0xd4, 0x61, 0x91, 0x9b, 0xa2, 0xef, 0xa8, 0xfa, 0xdb, 0x8e,
+ 0x15, 0x14, 0xf9, 0x87, 0xae, 0xf4, 0x52, 0x87, 0x37, 0xa1, 0xb5, 0x67,
+ 0x0c, 0xa7, 0xc8, 0xeb, 0xdc, 0x35, 0x54, 0xad, 0xd2, 0x9c, 0xba, 0xdf,
+ 0x87, 0x68, 0x6a, 0x9c, 0x38, 0x10, 0x98, 0xf0, 0x93, 0x9f, 0xcc, 0x77,
+ 0xd7, 0x8e, 0x96, 0x91, 0x7f, 0xa4, 0xc8, 0x6d, 0x3f, 0xee, 0xf5, 0xe2,
+ 0x6e, 0x62, 0xc6, 0x7e, 0xbd, 0x75, 0xc3, 0x18, 0x7e, 0x45, 0xac, 0x93,
+ 0xf2, 0x3f, 0x60, 0x7b, 0x22, 0xd3, 0xcb, 0xf6, 0xe0, 0xf7, 0x12, 0x8f,
+ 0xc9, 0x09, 0xbd, 0x3e, 0x3d, 0xed, 0x93, 0xf8, 0x2d, 0xdc, 0x75, 0xc7,
+ 0x6e, 0x05, 0x9d, 0x94, 0xf3, 0x28, 0x6d, 0xe6, 0xfe, 0x28, 0xbc, 0x5d,
+ 0x57, 0x91, 0xa3, 0x90, 0xf3, 0x61, 0x4e, 0x00, 0x8f, 0x8c, 0x23, 0x91,
+ 0xd7, 0xa7, 0xe6, 0x05, 0xf0, 0x26, 0xe5, 0x08, 0xae, 0x57, 0x94, 0xe4,
+ 0xf4, 0xac, 0xb9, 0x58, 0x4e, 0x2d, 0x1e, 0x2f, 0xc9, 0xd9, 0x43, 0x39,
+ 0xd7, 0xb4, 0xc0, 0x5b, 0x7b, 0x8d, 0xcc, 0x55, 0x1b, 0xfd, 0xa7, 0x16,
+ 0x19, 0x17, 0xdb, 0xc9, 0xe9, 0x3e, 0x06, 0x45, 0x5f, 0x28, 0xfc, 0xff,
+ 0x1b, 0x6e, 0xbd, 0x9b, 0xda, 0xa6, 0xa6, 0xeb, 0x09, 0x9e, 0x67, 0x5a,
+ 0xa6, 0xe8, 0xa8, 0x65, 0xdd, 0x34, 0x62, 0xeb, 0xee, 0xea, 0x72, 0x7f,
+ 0xd9, 0x4e, 0xb9, 0x8d, 0x06, 0xde, 0x0b, 0xe1, 0x11, 0xe6, 0x71, 0x37,
+ 0xb1, 0x9d, 0x03, 0x86, 0x70, 0xb1, 0x56, 0xa3, 0x4a, 0x91, 0xbc, 0x36,
+ 0xcc, 0xb8, 0xde, 0x80, 0x3e, 0x37, 0x16, 0x84, 0x59, 0x7f, 0x77, 0x5d,
+ 0x91, 0x4f, 0xc0, 0x77, 0x2b, 0xcb, 0x76, 0xc6, 0x8b, 0xed, 0xf9, 0x74,
+ 0xc9, 0x15, 0xdb, 0xb1, 0x7f, 0xf8, 0xfc, 0xf3, 0xc8, 0x4d, 0xfa, 0xcc,
+ 0xf9, 0x9a, 0x8a, 0x10, 0x4b, 0x2b, 0x50, 0x5d, 0x21, 0x58, 0x7f, 0xd1,
+ 0xd8, 0xb7, 0x8c, 0xff, 0x29, 0xef, 0x57, 0x63, 0xeb, 0xb8, 0x83, 0x2d,
+ 0x6e, 0x9e, 0x50, 0x81, 0xde, 0x36, 0xc1, 0x43, 0xb1, 0xa5, 0x39, 0x92,
+ 0x27, 0x25, 0x72, 0x90, 0x18, 0x27, 0xf6, 0xb3, 0xc6, 0xb5, 0x1f, 0x8f,
+ 0x32, 0xd3, 0x7e, 0x36, 0xe3, 0xbb, 0xfa, 0xa1, 0x3b, 0x2a, 0x71, 0xe8,
+ 0x2e, 0x59, 0xff, 0xde, 0x10, 0xc7, 0xe1, 0x5b, 0xe8, 0x9b, 0xaf, 0x13,
+ 0x5b, 0xb6, 0xb4, 0x30, 0x86, 0xb8, 0x98, 0xa5, 0xa0, 0x92, 0xb1, 0x7d,
+ 0xdb, 0x6e, 0xe6, 0xc0, 0x6a, 0x90, 0x6d, 0x5e, 0x8a, 0x5d, 0xd2, 0x7f,
+ 0x83, 0xb9, 0xee, 0xa1, 0x2f, 0x56, 0x22, 0x20, 0x39, 0xc7, 0x4f, 0x4e,
+ 0x51, 0xc6, 0x4d, 0x46, 0x59, 0x57, 0xa2, 0xa7, 0xb2, 0x9c, 0x06, 0xa4,
+ 0x77, 0x97, 0xeb, 0x2b, 0x78, 0x29, 0x1a, 0x2e, 0xad, 0x3f, 0x37, 0x60,
+ 0x60, 0xfc, 0xd0, 0x31, 0x72, 0x0d, 0x27, 0xd1, 0x72, 0x68, 0x63, 0x98,
+ 0x7d, 0x39, 0x13, 0x2f, 0xcf, 0xa9, 0xf8, 0xe6, 0x4c, 0x19, 0x62, 0xbb,
+ 0x50, 0x6a, 0x17, 0x62, 0x4b, 0x2d, 0x6d, 0x34, 0x1f, 0x45, 0xaa, 0xc6,
+ 0xac, 0x85, 0x3d, 0x4e, 0xdf, 0x9a, 0xa8, 0x80, 0xf7, 0x5a, 0x89, 0x7d,
+ 0xc2, 0x77, 0xbc, 0x37, 0x9c, 0xb0, 0x2b, 0xf0, 0x69, 0xe3, 0x9c, 0x23,
+ 0xb8, 0x78, 0x4c, 0xc7, 0xe5, 0x15, 0xc4, 0xc4, 0x85, 0xf1, 0x68, 0x72,
+ 0x1d, 0xf3, 0xc2, 0x23, 0x6d, 0xde, 0x1b, 0xde, 0xca, 0xff, 0x9a, 0xdc,
+ 0xf2, 0xd2, 0xf1, 0x88, 0x3e, 0x70, 0x74, 0x45, 0x54, 0xda, 0x94, 0xf6,
+ 0xca, 0x36, 0x2a, 0xed, 0x3b, 0x4e, 0x34, 0x1e, 0x70, 0xe7, 0xbc, 0x3c,
+ 0x86, 0x37, 0xf4, 0xf2, 0x18, 0x02, 0x8c, 0xa7, 0x49, 0x72, 0x57, 0xe1,
+ 0xd5, 0x7e, 0xe6, 0x91, 0x5e, 0xf2, 0xf1, 0x6e, 0x08, 0xdf, 0x3b, 0x4a,
+ 0x7e, 0xf2, 0xa4, 0x0d, 0xbc, 0x93, 0x75, 0xb0, 0x2c, 0x3e, 0x8b, 0xf8,
+ 0xd2, 0x4f, 0xd9, 0xb2, 0xa6, 0x76, 0x50, 0x19, 0x67, 0xae, 0x79, 0xdc,
+ 0x5b, 0x95, 0x54, 0x99, 0x5b, 0x1e, 0xc8, 0x47, 0xc3, 0x87, 0x98, 0x67,
+ 0xfa, 0x99, 0xeb, 0x72, 0x06, 0x94, 0x27, 0x99, 0x67, 0xee, 0x2b, 0xe5,
+ 0x99, 0x07, 0xf2, 0x01, 0xe4, 0xb3, 0xc4, 0xc6, 0x38, 0xf3, 0x5b, 0x37,
+ 0x4f, 0x0f, 0x60, 0x32, 0xab, 0x32, 0x1f, 0x7f, 0xdf, 0x99, 0xaa, 0x77,
+ 0xf7, 0x0b, 0xf0, 0x75, 0xbb, 0x01, 0x07, 0x87, 0x9b, 0x70, 0x36, 0x3f,
+ 0x45, 0xbb, 0xb8, 0x0c, 0xd3, 0xa3, 0xb5, 0x98, 0x18, 0x7e, 0x95, 0x9f,
+ 0xdb, 0xf0, 0xfe, 0xa8, 0x9b, 0xe3, 0x12, 0x0f, 0xa5, 0x7f, 0x07, 0x95,
+ 0x43, 0x6e, 0x8e, 0x6b, 0x25, 0x99, 0xdb, 0x26, 0xfa, 0x4b, 0xb9, 0xed,
+ 0x14, 0x73, 0xdb, 0x23, 0x6c, 0xf3, 0x85, 0x52, 0x9b, 0xcf, 0xb9, 0xff,
+ 0xa5, 0x2f, 0x52, 0x77, 0x66, 0xbd, 0x44, 0x52, 0xd6, 0xa6, 0xc7, 0xed,
+ 0x68, 0xac, 0x5c, 0xf7, 0x05, 0xd6, 0x3b, 0x72, 0xbe, 0xde, 0x6a, 0x0c,
+ 0x64, 0xd6, 0x90, 0xe7, 0xcb, 0xda, 0xca, 0x7b, 0x6b, 0x6c, 0xea, 0xf2,
+ 0xcb, 0xd1, 0xa9, 0xee, 0x59, 0xa8, 0xc3, 0xfa, 0xb8, 0x70, 0xa2, 0xb7,
+ 0xc8, 0x89, 0x22, 0x89, 0x95, 0x8c, 0x0f, 0x9e, 0x68, 0x84, 0x58, 0x0f,
+ 0x44, 0x27, 0x98, 0x03, 0xe4, 0xeb, 0x70, 0x37, 0x73, 0x31, 0xb5, 0x7e,
+ 0x75, 0x69, 0x0f, 0xab, 0x94, 0xe3, 0x78, 0xd6, 0xa0, 0x6f, 0x52, 0xe4,
+ 0xad, 0x26, 0xbf, 0xae, 0xc1, 0x2d, 0xc5, 0x75, 0x0b, 0xbf, 0x9f, 0xb2,
+ 0xfd, 0xd1, 0xa9, 0x18, 0x5d, 0xc6, 0x38, 0xc0, 0x1b, 0xcf, 0xd9, 0x0a,
+ 0x96, 0xe9, 0x3e, 0xac, 0x0b, 0xd6, 0x61, 0x99, 0xf1, 0xef, 0xce, 0x2d,
+ 0xab, 0xe5, 0xd9, 0x79, 0x1e, 0xe1, 0xaf, 0x64, 0xbb, 0x6f, 0x92, 0x53,
+ 0x8f, 0xf3, 0xcb, 0x54, 0xbe, 0x78, 0xdf, 0xca, 0x53, 0x36, 0xe5, 0x6e,
+ 0xa3, 0xdc, 0x7b, 0x83, 0x6e, 0xbe, 0x5b, 0x2a, 0x37, 0x15, 0xf3, 0x10,
+ 0xd7, 0xa5, 0x6c, 0x27, 0xe5, 0xde, 0x4d, 0xb9, 0xfd, 0x41, 0xe9, 0xdf,
+ 0xbf, 0x3b, 0xf7, 0xae, 0x96, 0x67, 0xe5, 0x7d, 0x13, 0x29, 0xff, 0x9e,
+ 0xc8, 0x35, 0xc6, 0x4b, 0x6d, 0x1d, 0xb2, 0x91, 0x95, 0xdc, 0x6f, 0x6d,
+ 0x47, 0x54, 0xeb, 0x75, 0xd7, 0xb2, 0x35, 0xac, 0xcb, 0x6b, 0xb8, 0x87,
+ 0xba, 0xcb, 0x79, 0xcb, 0x63, 0x72, 0xfb, 0x64, 0x09, 0x77, 0x5e, 0xce,
+ 0x72, 0x7d, 0x25, 0xdc, 0xee, 0xcc, 0x8b, 0x0d, 0xcd, 0xdc, 0x4f, 0x6a,
+ 0x2a, 0xf9, 0xb3, 0x17, 0x4f, 0xdb, 0x1f, 0x9c, 0x1b, 0xcc, 0x48, 0x3c,
+ 0x93, 0xf5, 0x10, 0x0d, 0xd9, 0xfc, 0xe5, 0x68, 0x1e, 0x0a, 0x62, 0xad,
+ 0x31, 0x9b, 0xbe, 0xfe, 0xa5, 0xf3, 0x36, 0x75, 0x80, 0xed, 0xc0, 0xe7,
+ 0x8a, 0x57, 0x9e, 0xce, 0xb7, 0x06, 0x1b, 0x70, 0xe9, 0x1e, 0xd2, 0xfc,
+ 0x64, 0x8d, 0x19, 0xed, 0xfe, 0x0e, 0xe7, 0xae, 0xca, 0xe5, 0xd0, 0x5b,
+ 0x94, 0x1c, 0xe7, 0xef, 0xa9, 0xd2, 0xfc, 0x3d, 0x99, 0xbf, 0xae, 0xb2,
+ 0x88, 0x45, 0x97, 0xa3, 0x65, 0x48, 0xfe, 0x07, 0xf1, 0x46, 0xc7, 0xc7,
+ 0x79, 0xef, 0x72, 0x2c, 0x1c, 0xf9, 0x54, 0x25, 0xb9, 0xb5, 0x51, 0xcc,
+ 0xc1, 0x2f, 0xcd, 0x33, 0x22, 0xfd, 0x16, 0x16, 0xb0, 0x5c, 0x13, 0x75,
+ 0x26, 0x18, 0x28, 0xfd, 0x7a, 0xe4, 0x7c, 0xbf, 0xbe, 0xcc, 0x7e, 0xa5,
+ 0x7c, 0xb2, 0xd6, 0x2a, 0xfd, 0x52, 0x92, 0xb5, 0x66, 0x13, 0xde, 0x1f,
+ 0x40, 0x30, 0x68, 0x46, 0x53, 0x2f, 0xd3, 0xde, 0x27, 0xd8, 0xd7, 0x7a,
+ 0xf4, 0x2b, 0x79, 0x77, 0xaf, 0xea, 0x20, 0xcb, 0xcc, 0x8c, 0xa3, 0xd2,
+ 0x4f, 0xaf, 0xe4, 0x59, 0x3e, 0xd9, 0x67, 0xf2, 0xe9, 0x22, 0xff, 0x6d,
+ 0x72, 0xc5, 0x3e, 0xca, 0x4f, 0x72, 0xfe, 0xfc, 0x6c, 0x03, 0x56, 0xb5,
+ 0xd9, 0xed, 0x72, 0x55, 0x2f, 0xfd, 0x6e, 0x19, 0x6d, 0xea, 0xc9, 0x9c,
+ 0x82, 0x51, 0x2a, 0xfd, 0x68, 0x56, 0xd6, 0x89, 0xc3, 0x38, 0x90, 0xf3,
+ 0xe1, 0x85, 0xec, 0x3c, 0x8c, 0xe7, 0x2a, 0xf0, 0x5c, 0xf6, 0x32, 0xec,
+ 0xcb, 0x11, 0xfd, 0xb2, 0x97, 0x63, 0x24, 0xe7, 0xc7, 0x4f, 0xb2, 0xd4,
+ 0x53, 0xae, 0x0a, 0xff, 0x9c, 0xfd, 0x13, 0x7c, 0x3d, 0x57, 0x8d, 0xd7,
+ 0xb2, 0x57, 0xe0, 0x60, 0xae, 0x06, 0xaf, 0x64, 0xc9, 0x27, 0x73, 0x01,
+ 0xbc, 0x9c, 0xd5, 0x50, 0xc8, 0xcd, 0xc2, 0x4b, 0xd9, 0x08, 0x26, 0x72,
+ 0xb5, 0xf8, 0x6e, 0x76, 0x01, 0xf2, 0xb9, 0x3a, 0x7c, 0x27, 0xdb, 0x8c,
+ 0x2f, 0xe7, 0x82, 0x78, 0x31, 0xab, 0xe3, 0xa9, 0x5c, 0x3d, 0x8e, 0x65,
+ 0xa3, 0x6c, 0x37, 0x84, 0xa3, 0xc3, 0x31, 0x1c, 0x18, 0x6d, 0xc4, 0x0b,
+ 0xc3, 0x8b, 0x30, 0x3e, 0x1a, 0xc6, 0x73, 0xc3, 0x6d, 0xd8, 0x37, 0xfa,
+ 0x6f, 0x15, 0xa2, 0x9f, 0x23, 0xf6, 0xff, 0x38, 0xaf, 0xc7, 0x6d, 0x1f,
+ 0x31, 0xdf, 0xaf, 0xda, 0xa2, 0x37, 0xbf, 0x55, 0xcf, 0x39, 0x7a, 0x3a,
+ 0xef, 0xce, 0x3b, 0xf4, 0x21, 0x77, 0x7f, 0x06, 0x7d, 0xc6, 0x65, 0xcc,
+ 0xd9, 0xfa, 0x25, 0x7e, 0xd0, 0x16, 0x0e, 0x2a, 0xdb, 0x5d, 0x1c, 0xa9,
+ 0x4d, 0xce, 0xa2, 0x2e, 0x39, 0xec, 0x60, 0x0d, 0x7d, 0x32, 0x4b, 0x7f,
+ 0xb6, 0x38, 0xaf, 0x76, 0xfe, 0xa0, 0xb2, 0x83, 0x39, 0xe2, 0x95, 0x43,
+ 0x96, 0x53, 0xed, 0xe2, 0x69, 0x34, 0xb9, 0x88, 0x3e, 0x17, 0x1b, 0x11,
+ 0x7d, 0xde, 0x59, 0x21, 0xfa, 0xac, 0xd0, 0x3f, 0xcc, 0x4e, 0xca, 0x7a,
+ 0x0f, 0x94, 0xec, 0xe1, 0xfb, 0x95, 0xc5, 0xbc, 0xaa, 0x3c, 0xef, 0x8e,
+ 0x33, 0x68, 0x94, 0xe7, 0x9e, 0xfc, 0xaf, 0x41, 0xd6, 0xa4, 0xc0, 0x58,
+ 0x50, 0x8f, 0x5c, 0x48, 0xf2, 0xf5, 0x99, 0x98, 0x81, 0x64, 0xa5, 0x19,
+ 0xd5, 0x5a, 0xd4, 0x99, 0x7c, 0x45, 0xb0, 0x43, 0xe4, 0x5b, 0x2e, 0xee,
+ 0x1c, 0x3e, 0x8f, 0x1f, 0x67, 0x2b, 0x85, 0xa7, 0xec, 0xb7, 0xa5, 0x6f,
+ 0x50, 0x2b, 0xa4, 0xcf, 0x28, 0xde, 0x43, 0xa1, 0xac, 0xaf, 0x99, 0x76,
+ 0xa7, 0x52, 0xb7, 0x62, 0x7b, 0x5e, 0xfa, 0xc2, 0x72, 0x89, 0x7b, 0xec,
+ 0x47, 0x13, 0x5e, 0xb0, 0x8b, 0x7b, 0x33, 0xe3, 0x79, 0xd1, 0xb7, 0x86,
+ 0xad, 0xe4, 0x5e, 0x87, 0x87, 0x15, 0xea, 0xee, 0x2f, 0x51, 0xdc, 0x3f,
+ 0xf2, 0xd2, 0x57, 0xd7, 0xb2, 0x3c, 0x63, 0x7c, 0x61, 0xda, 0xdd, 0x1b,
+ 0xae, 0x73, 0xf3, 0xee, 0x30, 0x0a, 0x03, 0x1f, 0x9c, 0xdb, 0x96, 0xf9,
+ 0xe5, 0xb9, 0x3d, 0x99, 0x68, 0x4a, 0xf6, 0x67, 0xf2, 0x13, 0x3e, 0xe4,
+ 0xf6, 0x06, 0xf0, 0xd4, 0x84, 0x1f, 0x35, 0x69, 0xc9, 0xf3, 0x83, 0x78,
+ 0x6a, 0xff, 0xa1, 0x15, 0x35, 0x68, 0xe0, 0xff, 0x10, 0xaf, 0x46, 0x5e,
+ 0x01, 0x1c, 0x1b, 0xf5, 0xe3, 0x2d, 0x5b, 0x7c, 0x58, 0xfc, 0xa3, 0x8d,
+ 0xd8, 0x1f, 0x60, 0xbc, 0x55, 0x19, 0x47, 0x9a, 0x70, 0x38, 0x1f, 0xc4,
+ 0xf2, 0x6c, 0x3d, 0x9e, 0xcb, 0x25, 0xf1, 0x44, 0xa6, 0x1e, 0x67, 0x1f,
+ 0xf3, 0x63, 0xde, 0x3e, 0xf1, 0x87, 0x06, 0x9c, 0x1e, 0xfc, 0x04, 0x0a,
+ 0x7b, 0x93, 0xb0, 0x33, 0xb3, 0xb1, 0x63, 0xb0, 0x01, 0xdf, 0x61, 0x99,
+ 0x7e, 0xea, 0xa9, 0x7a, 0xa7, 0x89, 0x17, 0x69, 0x43, 0x55, 0x3b, 0x6f,
+ 0xa4, 0xec, 0x30, 0x7c, 0x03, 0x21, 0x1c, 0xc9, 0x7b, 0x85, 0xd7, 0x71,
+ 0x1e, 0x7f, 0x5a, 0x9c, 0x17, 0x08, 0x6f, 0xbd, 0x98, 0x07, 0x1e, 0x3f,
+ 0xcf, 0x03, 0x81, 0x5c, 0x5e, 0xd6, 0x18, 0xdb, 0x3a, 0xfb, 0xec, 0x89,
+ 0xff, 0xcf, 0x6f, 0xfe, 0xf4, 0xdb, 0x15, 0x4b, 0x0c, 0x62, 0x9d, 0x8c,
+ 0x7f, 0xed, 0x83, 0xd5, 0xe6, 0x86, 0x2f, 0xae, 0x58, 0x52, 0x89, 0xfb,
+ 0xdd, 0xf9, 0xea, 0x81, 0xbd, 0xbb, 0x9b, 0xf1, 0xb5, 0xb5, 0x67, 0x40,
+ 0xb9, 0x02, 0xa9, 0xfa, 0x21, 0xde, 0x53, 0x4b, 0x3e, 0x07, 0x55, 0x6c,
+ 0xad, 0x8e, 0xfa, 0x54, 0x0b, 0x1a, 0x4e, 0xd0, 0xc8, 0x6a, 0xd3, 0x11,
+ 0x4c, 0xd5, 0xcb, 0x38, 0x63, 0xcc, 0xb3, 0x3c, 0xb2, 0x77, 0x8d, 0x4f,
+ 0x33, 0xc6, 0x9d, 0x5d, 0xac, 0x20, 0xf1, 0x67, 0xe2, 0x83, 0xb7, 0x96,
+ 0xf6, 0x80, 0x65, 0x3f, 0x4c, 0xe6, 0xad, 0xac, 0xff, 0xbd, 0xb2, 0xee,
+ 0xc9, 0x3f, 0xc1, 0x0a, 0x2f, 0x0e, 0xdb, 0x39, 0xe6, 0x08, 0x32, 0x07,
+ 0x32, 0xa6, 0xed, 0xac, 0x27, 0xe3, 0x92, 0xe7, 0xad, 0x89, 0xfa, 0x8f,
+ 0x1c, 0x97, 0x8c, 0x67, 0xad, 0x1f, 0xd5, 0x32, 0x86, 0xb2, 0x2e, 0xfa,
+ 0x58, 0xf7, 0x51, 0xde, 0x93, 0x7a, 0x8e, 0xb3, 0xfd, 0xa2, 0x98, 0x55,
+ 0x91, 0xac, 0x66, 0xdf, 0x9f, 0xb4, 0xa3, 0xc9, 0x77, 0x88, 0x8b, 0xc7,
+ 0xa8, 0xc3, 0x51, 0x5b, 0xec, 0x6f, 0x0b, 0xed, 0xae, 0x5f, 0x39, 0x7a,
+ 0xde, 0xf6, 0x80, 0x83, 0xb6, 0xcc, 0xaf, 0xf0, 0x29, 0x19, 0xaf, 0x86,
+ 0xe9, 0x89, 0xa0, 0xcb, 0xc7, 0xdf, 0xb6, 0xc5, 0x26, 0x62, 0xcc, 0xcf,
+ 0xa6, 0xcf, 0xf5, 0x66, 0x0c, 0x1c, 0xe3, 0xdc, 0x9e, 0xb6, 0xab, 0x88,
+ 0x37, 0x1d, 0x90, 0xbd, 0xce, 0xf7, 0xed, 0x04, 0x5e, 0x22, 0x66, 0xbd,
+ 0x47, 0x5b, 0xfb, 0x2e, 0x31, 0xec, 0x5d, 0x5b, 0xc7, 0x77, 0x68, 0x7b,
+ 0xef, 0xd8, 0x31, 0xbc, 0x98, 0xaf, 0xc7, 0x51, 0xe2, 0xd0, 0x49, 0x7e,
+ 0x5e, 0x9e, 0xf7, 0xc1, 0x0a, 0xc9, 0xbe, 0xda, 0x1e, 0x3f, 0x6a, 0x7b,
+ 0xd9, 0xe7, 0x48, 0x97, 0x1c, 0x44, 0x79, 0x96, 0xe3, 0xd3, 0x94, 0x32,
+ 0x0f, 0x29, 0xe7, 0x04, 0x49, 0x64, 0x33, 0x33, 0xb1, 0x21, 0xd2, 0x9f,
+ 0xa3, 0xdd, 0xfa, 0xd2, 0xe5, 0x38, 0xc0, 0xd8, 0x59, 0x10, 0xdb, 0xf6,
+ 0xc0, 0x33, 0x24, 0xf6, 0x7f, 0x0d, 0x75, 0x3d, 0x7d, 0x4e, 0xf6, 0xd2,
+ 0x54, 0x7d, 0x8a, 0xfe, 0x5e, 0x85, 0xde, 0xdc, 0xe5, 0xa8, 0x19, 0x5a,
+ 0x8a, 0xfb, 0xe3, 0xe2, 0xf7, 0x7e, 0xf4, 0xe7, 0x3c, 0xa8, 0x1c, 0x22,
+ 0x77, 0x61, 0xd9, 0xa9, 0x50, 0x31, 0x1e, 0xa9, 0x69, 0xc3, 0xf5, 0x83,
+ 0x05, 0x85, 0x0f, 0xce, 0xd9, 0x99, 0x43, 0xf3, 0x54, 0x4c, 0x9f, 0x4b,
+ 0x67, 0x02, 0xe8, 0xa3, 0x4d, 0xab, 0x69, 0x05, 0x75, 0x7a, 0x88, 0xf9,
+ 0x5f, 0x1b, 0x7a, 0xa9, 0x8b, 0xf9, 0xe9, 0x26, 0x3c, 0x31, 0xd1, 0x88,
+ 0x79, 0xbb, 0x4c, 0x3c, 0x4e, 0xdb, 0x0f, 0xef, 0xba, 0x11, 0x7b, 0x58,
+ 0xee, 0x15, 0x3e, 0x7b, 0x65, 0x7f, 0x03, 0xaf, 0x10, 0xaf, 0x46, 0x5e,
+ 0xf5, 0x18, 0xd8, 0xab, 0x97, 0xce, 0x61, 0x78, 0xd0, 0x30, 0x24, 0xf8,
+ 0xa2, 0xe2, 0x8e, 0x76, 0x05, 0xc6, 0xd5, 0x6c, 0x73, 0xe1, 0x87, 0x61,
+ 0x4d, 0xc3, 0x1f, 0xd0, 0xef, 0x1f, 0x38, 0x53, 0xe7, 0xed, 0xc7, 0x0f,
+ 0x6f, 0xfa, 0xfb, 0xae, 0xfd, 0x2c, 0x28, 0x48, 0x3b, 0xef, 0x12, 0x33,
+ 0xc4, 0x86, 0x7e, 0x17, 0x9e, 0x95, 0xf5, 0xfe, 0xdb, 0x67, 0x2b, 0x70,
+ 0xde, 0xbe, 0x2e, 0x5a, 0x77, 0x47, 0x9e, 0x36, 0xb1, 0xc3, 0x3d, 0x3b,
+ 0x22, 0xb9, 0x4e, 0xa4, 0x2b, 0x47, 0xfd, 0xf4, 0x33, 0x87, 0xb9, 0x87,
+ 0x38, 0xb1, 0x3d, 0x13, 0xb1, 0x2c, 0xb6, 0xe5, 0x23, 0x36, 0x3c, 0x30,
+ 0xe8, 0x97, 0xf5, 0x6e, 0xcd, 0xa7, 0xcf, 0xc3, 0x3b, 0x39, 0xb1, 0xf9,
+ 0x2a, 0x1c, 0xce, 0x86, 0x71, 0xca, 0xfd, 0x5c, 0xcd, 0x58, 0xe3, 0xa0,
+ 0xd3, 0x98, 0x85, 0xbe, 0x60, 0x15, 0x06, 0x62, 0x37, 0x22, 0x77, 0x07,
+ 0x73, 0x6c, 0xfa, 0x58, 0xad, 0xee, 0x47, 0x3a, 0x28, 0xf9, 0x8b, 0x07,
+ 0x99, 0xd8, 0xed, 0x38, 0x5e, 0xef, 0xc5, 0x3c, 0x59, 0x6f, 0xe1, 0xb3,
+ 0x3d, 0x41, 0x28, 0xf4, 0xbd, 0xa4, 0x8f, 0xb8, 0x34, 0x6b, 0x00, 0x4e,
+ 0xad, 0xa9, 0xcb, 0x1e, 0x4c, 0xcf, 0x56, 0xe2, 0x52, 0xcd, 0x44, 0x0d,
+ 0xe3, 0x4e, 0x0b, 0xaa, 0xf7, 0xca, 0x5e, 0x40, 0x00, 0xeb, 0x86, 0xaf,
+ 0x95, 0xbd, 0x81, 0x98, 0xa6, 0x04, 0x70, 0xef, 0xb0, 0xc4, 0x8f, 0x35,
+ 0xa8, 0xd8, 0x5f, 0x8b, 0x2f, 0x66, 0xbd, 0xc4, 0x78, 0xe2, 0x0d, 0xcb,
+ 0xed, 0xc9, 0xd4, 0xa1, 0xee, 0xb1, 0x67, 0x9d, 0x30, 0x75, 0x5c, 0xb7,
+ 0x57, 0xb0, 0x88, 0xb6, 0x9b, 0xf9, 0x3c, 0x0a, 0x76, 0x33, 0xe5, 0xf6,
+ 0x70, 0x7c, 0x21, 0xbc, 0x4b, 0xec, 0xaa, 0x99, 0x08, 0xe3, 0x9d, 0xdd,
+ 0x92, 0xab, 0x24, 0xe1, 0x9d, 0xb8, 0x0c, 0x6f, 0xf2, 0xf3, 0x09, 0xa3,
+ 0x13, 0xea, 0x44, 0x13, 0x4e, 0x66, 0xba, 0xe0, 0x99, 0xa8, 0x2d, 0x62,
+ 0xd8, 0x5e, 0x3f, 0xea, 0x06, 0xf5, 0xd8, 0x34, 0xe7, 0xc8, 0xb7, 0x97,
+ 0x04, 0xa7, 0x51, 0xda, 0x3f, 0x6f, 0xdb, 0xc6, 0x85, 0x7d, 0x87, 0xf2,
+ 0xd9, 0x15, 0xb1, 0xef, 0xef, 0x3a, 0x4f, 0x04, 0xd9, 0xbf, 0x8e, 0x08,
+ 0xfa, 0x62, 0xc7, 0x64, 0x3f, 0x9f, 0xe3, 0x4b, 0x72, 0xee, 0x9f, 0x77,
+ 0xe4, 0x5c, 0x88, 0xcf, 0x94, 0x33, 0x19, 0xcf, 0x39, 0xdb, 0x57, 0xcb,
+ 0xfd, 0xdb, 0xab, 0x50, 0xcd, 0xc4, 0xc9, 0x14, 0x99, 0x3b, 0x64, 0x6e,
+ 0x19, 0x75, 0x3e, 0x4c, 0xe6, 0x3f, 0x3a, 0x8f, 0x9f, 0x2f, 0x8f, 0xa0,
+ 0xcf, 0x5d, 0x13, 0xbf, 0xe0, 0xcb, 0x35, 0x9c, 0xbb, 0xf5, 0x25, 0x5f,
+ 0x7e, 0xc7, 0x96, 0xf9, 0x93, 0xf3, 0x4b, 0x01, 0x72, 0x30, 0x03, 0xd5,
+ 0x9c, 0xbb, 0xf7, 0x6d, 0x28, 0xb7, 0x76, 0x74, 0x63, 0xd6, 0x44, 0x80,
+ 0xbe, 0x1e, 0x59, 0x6f, 0xc1, 0x66, 0x5b, 0x1d, 0xa8, 0x62, 0x9d, 0x93,
+ 0xb6, 0x87, 0x7e, 0x9e, 0xe0, 0x98, 0x83, 0x70, 0x5c, 0x5e, 0xbf, 0x1a,
+ 0xf3, 0xa9, 0xa7, 0xb3, 0xb6, 0x89, 0x79, 0xd4, 0xd3, 0xb4, 0xed, 0x25,
+ 0x4e, 0x34, 0x11, 0x0f, 0x34, 0xd4, 0x12, 0x1b, 0x2b, 0x06, 0x1d, 0x1c,
+ 0x32, 0xea, 0xc8, 0xf5, 0xc5, 0x4e, 0x3b, 0x10, 0x1e, 0x30, 0x30, 0x6f,
+ 0xa0, 0x79, 0xe3, 0x3c, 0x8f, 0x07, 0xc7, 0x7d, 0xc5, 0xd8, 0x93, 0x9b,
+ 0x23, 0xfa, 0x91, 0x31, 0xb9, 0xb9, 0xfc, 0x87, 0x60, 0xc0, 0x6a, 0x80,
+ 0xb2, 0x0a, 0xc4, 0x8c, 0xcf, 0xb1, 0xad, 0x37, 0xec, 0x57, 0x71, 0xf3,
+ 0x84, 0xe0, 0xcb, 0x0f, 0xb1, 0x92, 0xfd, 0x78, 0x97, 0xb8, 0x76, 0x5f,
+ 0xf4, 0x1b, 0x1c, 0x6b, 0x13, 0x6e, 0x99, 0x98, 0x3e, 0xd7, 0xe7, 0x8e,
+ 0xb3, 0x9c, 0xff, 0xf9, 0x71, 0x5f, 0xb6, 0x7c, 0x06, 0x2d, 0x49, 0x9f,
+ 0x91, 0x38, 0xe1, 0x87, 0xf8, 0x4d, 0xb7, 0xbd, 0x0d, 0xc5, 0x78, 0x2e,
+ 0x57, 0x59, 0x8f, 0x3b, 0xbd, 0x92, 0x97, 0x17, 0x7d, 0x43, 0xfa, 0xf3,
+ 0xbb, 0xca, 0x14, 0x7d, 0x43, 0xfc, 0xe2, 0xcb, 0xae, 0x7e, 0x85, 0x77,
+ 0x69, 0xb8, 0x6d, 0xe2, 0x97, 0xc4, 0xc7, 0x48, 0x32, 0x47, 0xcc, 0x7e,
+ 0x9d, 0xfa, 0xdd, 0x4e, 0xfd, 0x32, 0x07, 0x60, 0xbc, 0x4a, 0x50, 0x9f,
+ 0x3e, 0x72, 0x15, 0x2f, 0x31, 0xd3, 0xa4, 0x2e, 0x41, 0x0c, 0x64, 0xee,
+ 0x1e, 0x2c, 0x8e, 0x37, 0x77, 0x7e, 0xfe, 0xd8, 0x96, 0x92, 0xc0, 0x09,
+ 0xfb, 0x87, 0x55, 0x72, 0x26, 0xe8, 0xa4, 0xed, 0x3e, 0x97, 0x35, 0xcd,
+ 0x19, 0x65, 0x2e, 0xb4, 0xbd, 0xcf, 0x16, 0xfe, 0x5c, 0x49, 0xbb, 0xd6,
+ 0x28, 0xaf, 0xa6, 0x84, 0xa9, 0x52, 0x57, 0xf6, 0x60, 0xa5, 0xfd, 0x6e,
+ 0xe1, 0x20, 0x78, 0x83, 0x3e, 0x77, 0xc4, 0xa8, 0xc0, 0xa8, 0x3b, 0x17,
+ 0x62, 0x8f, 0xc5, 0x76, 0x2f, 0xd8, 0x4d, 0xba, 0xae, 0x74, 0x1e, 0xab,
+ 0xba, 0xc8, 0xc9, 0x2e, 0x6d, 0xa3, 0xe2, 0x3f, 0xb1, 0x8d, 0x44, 0xa9,
+ 0x8d, 0x8f, 0x3a, 0xe3, 0x06, 0x3c, 0x65, 0x4b, 0xec, 0x97, 0xfd, 0x0f,
+ 0x0d, 0x8b, 0x26, 0x04, 0x5f, 0xe8, 0xbb, 0x03, 0xd3, 0x2e, 0xf7, 0xcf,
+ 0x41, 0xf6, 0xb6, 0x42, 0xf0, 0x45, 0x35, 0x9c, 0xd2, 0x63, 0x58, 0x58,
+ 0x90, 0xfd, 0xa9, 0x7d, 0x75, 0xc2, 0xe1, 0xce, 0xe8, 0xc2, 0x3b, 0x64,
+ 0xbe, 0xca, 0xf7, 0xfc, 0xd8, 0xaf, 0x17, 0xfb, 0x9a, 0x54, 0x8b, 0xdc,
+ 0xd1, 0x43, 0xee, 0xd8, 0x6b, 0xf8, 0x69, 0x97, 0xad, 0xc1, 0xd9, 0xbf,
+ 0x73, 0x2f, 0xab, 0xdc, 0xdf, 0xdf, 0x57, 0xee, 0xc2, 0x7a, 0x5c, 0xf6,
+ 0xa2, 0xfd, 0x21, 0x19, 0xd3, 0x5c, 0xa0, 0x41, 0xe2, 0x55, 0x91, 0xa3,
+ 0x6e, 0x3d, 0x9f, 0xff, 0x58, 0xca, 0x60, 0xfe, 0x31, 0xd4, 0xeb, 0x0b,
+ 0x50, 0xdf, 0x50, 0xc3, 0xb8, 0x1c, 0xed, 0xa2, 0x7b, 0x4b, 0x2c, 0xb3,
+ 0x82, 0xa6, 0xe4, 0xbf, 0xc2, 0x5b, 0xa5, 0xcd, 0x7e, 0xa5, 0xaa, 0x20,
+ 0xed, 0x1e, 0x54, 0xfc, 0x85, 0x0f, 0x6b, 0x5b, 0xce, 0xfb, 0x4d, 0x9f,
+ 0x1b, 0xca, 0x74, 0xbb, 0x7b, 0x8c, 0xcb, 0x86, 0x1c, 0xdc, 0x69, 0x34,
+ 0xe1, 0xee, 0x06, 0x69, 0xa3, 0x98, 0xc3, 0x68, 0xea, 0x34, 0x39, 0xdc,
+ 0x6f, 0x1c, 0x55, 0x97, 0xcf, 0x3e, 0x78, 0x1e, 0xd3, 0xa7, 0xd7, 0x42,
+ 0xc5, 0xd9, 0xeb, 0x24, 0x9f, 0xf1, 0x91, 0x7f, 0x6d, 0xaa, 0x2e, 0xee,
+ 0x2f, 0x8b, 0x1d, 0x4b, 0x3f, 0xfc, 0xf4, 0xb3, 0x0b, 0xfd, 0xd8, 0xf6,
+ 0x07, 0xf5, 0xc3, 0x8f, 0x9b, 0x86, 0x92, 0x18, 0x35, 0x4e, 0x38, 0x56,
+ 0x68, 0x66, 0xdb, 0x3e, 0xac, 0x1c, 0xfa, 0x8d, 0x33, 0xcb, 0x6d, 0x5b,
+ 0x27, 0xa7, 0x52, 0xf1, 0xc0, 0x12, 0x1f, 0x6e, 0x1d, 0x89, 0x62, 0xc5,
+ 0x90, 0x8a, 0xd8, 0x12, 0xe9, 0x43, 0x14, 0x5d, 0x23, 0xbb, 0xbd, 0xc5,
+ 0xf2, 0xc0, 0x2d, 0x1c, 0xc3, 0x1b, 0x46, 0x0d, 0x7e, 0x40, 0x0c, 0xac,
+ 0x75, 0xb9, 0xfd, 0x46, 0x25, 0x23, 0xdc, 0xde, 0xa7, 0x62, 0xb6, 0x8e,
+ 0x60, 0x83, 0x99, 0xa4, 0xee, 0x3a, 0x95, 0xc7, 0x72, 0x1b, 0x95, 0xa1,
+ 0x7c, 0xb9, 0xef, 0x01, 0x7c, 0xa2, 0x10, 0xc4, 0x27, 0xc6, 0x1a, 0x78,
+ 0x85, 0x78, 0x35, 0xf2, 0x7a, 0xf1, 0xfc, 0xb8, 0xca, 0x67, 0x3c, 0x9f,
+ 0x65, 0x4e, 0xb1, 0xcd, 0xf5, 0x4b, 0x89, 0x0b, 0x9a, 0x9c, 0xd5, 0xc1,
+ 0x5b, 0x59, 0xc9, 0x27, 0xb6, 0xd1, 0x86, 0x65, 0x4d, 0xb8, 0x92, 0x39,
+ 0x45, 0x24, 0x36, 0x85, 0xbf, 0xaa, 0x2e, 0xce, 0x7d, 0xd1, 0x86, 0x71,
+ 0xde, 0x86, 0x7d, 0x78, 0x3b, 0xab, 0xa2, 0x25, 0xfe, 0x6f, 0xce, 0xf1,
+ 0xa0, 0xe0, 0xc9, 0xa5, 0xcf, 0xcb, 0x9c, 0x65, 0xfa, 0x5c, 0x36, 0xd3,
+ 0x34, 0x63, 0x5f, 0x56, 0x41, 0xc5, 0x90, 0xf0, 0xf3, 0xeb, 0x5c, 0xbe,
+ 0xf7, 0x7d, 0xc3, 0x07, 0xef, 0xd0, 0xa1, 0x2b, 0xe5, 0x68, 0x93, 0x6f,
+ 0x8c, 0x71, 0xab, 0x83, 0xf3, 0x32, 0xf2, 0xf1, 0x92, 0xce, 0xca, 0xba,
+ 0x50, 0xdc, 0x35, 0x49, 0xd5, 0x8d, 0xe9, 0x41, 0xa8, 0x63, 0xc2, 0x43,
+ 0xc9, 0x0d, 0xc6, 0x24, 0x1f, 0x08, 0xf1, 0xbf, 0xe4, 0x06, 0x8d, 0xfc,
+ 0xcf, 0xc4, 0xa2, 0x51, 0xe2, 0x78, 0x0f, 0xfa, 0x19, 0x9f, 0x2a, 0xa3,
+ 0x3d, 0xd8, 0x3e, 0xfe, 0x61, 0x31, 0xbf, 0x98, 0x63, 0x3d, 0x7b, 0xde,
+ 0xcf, 0xdc, 0x39, 0x62, 0x9f, 0xa6, 0xcf, 0x89, 0xcf, 0xc8, 0x5c, 0xed,
+ 0xcb, 0x4a, 0x1f, 0x1c, 0x6c, 0x30, 0x6e, 0x64, 0xdb, 0x3e, 0xa8, 0x0d,
+ 0x33, 0xb9, 0xe7, 0x79, 0x3e, 0x4d, 0xdd, 0x6d, 0x54, 0x46, 0x39, 0x27,
+ 0x96, 0xb7, 0x52, 0xd6, 0x87, 0x82, 0x15, 0x9c, 0x93, 0xaf, 0xe4, 0x45,
+ 0x46, 0xa7, 0x32, 0x9e, 0x9b, 0x59, 0x67, 0xa3, 0x32, 0x96, 0xff, 0x55,
+ 0xb5, 0xac, 0x99, 0x5f, 0xd0, 0x4d, 0xb9, 0x0f, 0x62, 0x63, 0x1a, 0xea,
+ 0xd3, 0xa2, 0x67, 0x19, 0xb3, 0x06, 0x2f, 0x79, 0x5c, 0x7d, 0xe1, 0x43,
+ 0xdb, 0x6c, 0xac, 0x72, 0xcf, 0x62, 0xc6, 0x18, 0x8b, 0x02, 0x56, 0x25,
+ 0x39, 0x1f, 0x6d, 0x34, 0xe5, 0x33, 0xbb, 0x3a, 0xf7, 0xd9, 0x0b, 0x83,
+ 0x87, 0x4b, 0x6b, 0x11, 0x6b, 0x21, 0xbc, 0x54, 0x71, 0x71, 0xd6, 0xa3,
+ 0x47, 0xb1, 0x9c, 0xb9, 0xee, 0x4d, 0xb9, 0x62, 0x7f, 0xc7, 0xd8, 0xdf,
+ 0x29, 0xd7, 0xf7, 0x92, 0xca, 0x68, 0x5e, 0x75, 0xfb, 0xed, 0x35, 0xa5,
+ 0xbf, 0x52, 0x97, 0xe3, 0xc9, 0xbf, 0x56, 0xca, 0xa9, 0x92, 0x18, 0xcc,
+ 0xcc, 0xf4, 0x61, 0xe9, 0x73, 0x2d, 0xda, 0x86, 0x3e, 0xa0, 0x9f, 0xc9,
+ 0xbc, 0x0a, 0xfe, 0xcc, 0xc3, 0xca, 0x91, 0x59, 0x68, 0x1d, 0x0a, 0xe3,
+ 0xb6, 0x91, 0x06, 0x2c, 0xda, 0xb5, 0x06, 0xd5, 0x63, 0x41, 0x5c, 0xb9,
+ 0x4b, 0xd6, 0xf8, 0x57, 0xa3, 0xb2, 0x70, 0x5b, 0x8d, 0xe4, 0xb8, 0x7a,
+ 0x3a, 0xc1, 0xf9, 0x4b, 0xa0, 0x22, 0x1d, 0x49, 0x24, 0x21, 0x6b, 0xa4,
+ 0x26, 0x2a, 0x0a, 0x26, 0xf9, 0xa4, 0xb3, 0x79, 0xbe, 0xe9, 0x73, 0xcf,
+ 0x9b, 0x2d, 0x2b, 0xd0, 0xe6, 0x39, 0x6e, 0x1f, 0x2f, 0x4f, 0xda, 0x71,
+ 0xce, 0x5e, 0x87, 0xcd, 0x35, 0x66, 0x13, 0x3c, 0x85, 0xcb, 0x91, 0x1c,
+ 0x69, 0xc3, 0xbc, 0x42, 0x03, 0x3a, 0x47, 0x42, 0x88, 0xa5, 0xc5, 0xc7,
+ 0x23, 0x5a, 0x4a, 0xed, 0x80, 0xbf, 0xc0, 0x78, 0x9a, 0xfe, 0x8d, 0xf3,
+ 0x16, 0xed, 0xa0, 0x87, 0xfa, 0xba, 0x26, 0xdd, 0x85, 0xba, 0x42, 0x00,
+ 0x57, 0x0f, 0x7d, 0x02, 0xb5, 0x23, 0x7e, 0xcc, 0x1a, 0xd2, 0x90, 0x5f,
+ 0xe2, 0x47, 0x60, 0x24, 0x8c, 0xea, 0xb4, 0xde, 0x75, 0x9b, 0x82, 0xe4,
+ 0xc2, 0x25, 0x61, 0xb6, 0x4d, 0x7b, 0xa3, 0x7f, 0x8d, 0x90, 0x7f, 0x2d,
+ 0xef, 0x06, 0x36, 0xa7, 0x05, 0x1b, 0x45, 0x27, 0x9f, 0x72, 0xcf, 0x9f,
+ 0xac, 0x4b, 0x7f, 0x18, 0xce, 0x95, 0xed, 0x5b, 0xfc, 0xdc, 0x72, 0xcf,
+ 0xc4, 0x32, 0x07, 0x52, 0xa6, 0x5b, 0xf4, 0xec, 0x3c, 0xde, 0xfb, 0x39,
+ 0xe3, 0xf3, 0x43, 0xe9, 0x80, 0x55, 0x6b, 0x6e, 0xc6, 0x55, 0xed, 0x11,
+ 0xab, 0xa0, 0xbc, 0xca, 0xf1, 0xff, 0x90, 0x41, 0xbb, 0x89, 0xfd, 0xfc,
+ 0x63, 0xe5, 0x5f, 0xba, 0xce, 0xb6, 0xe4, 0xa2, 0xf5, 0xb9, 0x23, 0xcc,
+ 0xe7, 0xa7, 0x2e, 0x5a, 0x9f, 0x13, 0xbc, 0x2f, 0x9f, 0x83, 0x90, 0xb9,
+ 0xd2, 0x66, 0xd8, 0xb7, 0xac, 0x17, 0x09, 0x36, 0xca, 0x7c, 0x95, 0xd7,
+ 0x8b, 0x7c, 0x58, 0x3e, 0x24, 0xb9, 0x92, 0xca, 0x3c, 0xa1, 0x05, 0xc9,
+ 0xd0, 0xa3, 0x9c, 0x03, 0x77, 0x4d, 0x89, 0xf7, 0x06, 0xf8, 0x59, 0xd6,
+ 0x7b, 0x34, 0xe2, 0x8f, 0x56, 0xca, 0x0b, 0xaa, 0x70, 0xeb, 0x50, 0x83,
+ 0xbb, 0x1f, 0xb5, 0x22, 0x7e, 0x39, 0x62, 0xf5, 0x5f, 0x62, 0x99, 0x0b,
+ 0x6b, 0x43, 0x57, 0x31, 0xdf, 0xa8, 0x71, 0xcf, 0x4a, 0x2c, 0xa3, 0xbe,
+ 0x2f, 0x47, 0xdb, 0x48, 0x11, 0xcf, 0x6e, 0x1b, 0x29, 0xe2, 0x56, 0x5a,
+ 0x6c, 0xce, 0x57, 0xb4, 0xb9, 0x2c, 0x6d, 0x2e, 0xa8, 0x77, 0x2a, 0xd9,
+ 0xdc, 0x47, 0xc5, 0x13, 0x04, 0xeb, 0xcc, 0xf2, 0x99, 0x6a, 0x62, 0x5e,
+ 0xfe, 0x48, 0xcd, 0x1f, 0x16, 0x7f, 0x2e, 0xd5, 0xd9, 0xb5, 0x7f, 0xa4,
+ 0xce, 0xca, 0x31, 0xeb, 0x82, 0xce, 0x06, 0x2f, 0xd1, 0xd9, 0x02, 0xea,
+ 0xa0, 0x41, 0x2f, 0xea, 0x6d, 0xb9, 0x71, 0x19, 0x52, 0xae, 0xde, 0xaa,
+ 0x64, 0x6d, 0x8c, 0xf7, 0x04, 0xaf, 0xe7, 0xe0, 0xfb, 0xc1, 0x2f, 0xb9,
+ 0xf7, 0x16, 0x51, 0x27, 0x45, 0x7d, 0x05, 0xa9, 0xaf, 0x0b, 0xb1, 0x00,
+ 0xea, 0x07, 0xcc, 0xa7, 0x8a, 0xb1, 0x40, 0x74, 0xf7, 0xda, 0xa0, 0x86,
+ 0xba, 0xeb, 0x2e, 0xc7, 0x2b, 0x7b, 0xab, 0xd0, 0x3e, 0xe2, 0xa3, 0x7f,
+ 0x49, 0x7c, 0x28, 0xc6, 0xa4, 0xd6, 0x11, 0x77, 0x3f, 0x8a, 0xf8, 0xda,
+ 0x10, 0xf8, 0xc3, 0x63, 0xb0, 0x8c, 0x47, 0xce, 0xe5, 0xc9, 0xb9, 0x39,
+ 0x19, 0x97, 0x3e, 0xc3, 0x16, 0x1c, 0xe7, 0x19, 0xce, 0x77, 0xaa, 0x21,
+ 0x92, 0x95, 0xf5, 0xa6, 0x2c, 0x39, 0x99, 0x27, 0x2d, 0x3a, 0x13, 0xbe,
+ 0xad, 0xde, 0xe8, 0x81, 0xda, 0xe6, 0xc1, 0x66, 0x9c, 0x32, 0xf4, 0xfe,
+ 0x7b, 0xf1, 0x27, 0xe8, 0x0d, 0x39, 0xd8, 0x6f, 0xac, 0x64, 0x3e, 0x51,
+ 0x8d, 0xf5, 0x6d, 0x34, 0xcf, 0x3b, 0x3a, 0x88, 0x09, 0x56, 0x8f, 0x07,
+ 0xb2, 0x9e, 0xbb, 0xf1, 0x2e, 0x3b, 0x1a, 0xe9, 0x7e, 0x50, 0x01, 0x56,
+ 0x0c, 0xf8, 0xa1, 0x29, 0x2e, 0xdf, 0x89, 0x0d, 0xa9, 0xb2, 0xb6, 0xfc,
+ 0x2f, 0x15, 0xc5, 0xb3, 0x10, 0x2a, 0xb4, 0x46, 0x69, 0x67, 0x25, 0xac,
+ 0xc9, 0x0e, 0x17, 0x4f, 0x6a, 0x16, 0x2a, 0xb8, 0x75, 0x61, 0xc4, 0x4a,
+ 0x29, 0x8e, 0xb3, 0x2a, 0xee, 0x75, 0x9f, 0xef, 0x98, 0x6c, 0x4d, 0xdd,
+ 0xa9, 0xfe, 0x8b, 0x63, 0xb9, 0xeb, 0xd9, 0x91, 0x60, 0x52, 0x65, 0x9f,
+ 0x3f, 0xf2, 0xac, 0xa2, 0x8c, 0x93, 0x5c, 0x9c, 0xbc, 0xfb, 0xc9, 0xd2,
+ 0xfa, 0xaf, 0xcf, 0x5c, 0xff, 0x17, 0xfb, 0x75, 0xc9, 0xf7, 0xbe, 0xe4,
+ 0x9e, 0xfb, 0xc8, 0x66, 0x64, 0xfd, 0xf0, 0xe1, 0x00, 0xaa, 0x57, 0xa2,
+ 0x77, 0xf2, 0x3a, 0x4c, 0xb4, 0xfd, 0xab, 0x93, 0x2b, 0xf6, 0x5d, 0xcc,
+ 0xd0, 0x3f, 0xcf, 0xcc, 0xdd, 0x75, 0x7d, 0x4b, 0x84, 0x1c, 0x5c, 0xce,
+ 0x7a, 0x92, 0x0b, 0x2b, 0x45, 0x1e, 0x3e, 0x5f, 0xbf, 0x09, 0xcf, 0x5e,
+ 0x24, 0x53, 0xd6, 0x12, 0xca, 0x32, 0x77, 0x51, 0x9e, 0xc8, 0x65, 0x3c,
+ 0xd0, 0xff, 0xcd, 0x19, 0x09, 0xcd, 0x2c, 0x17, 0xab, 0x2a, 0xc6, 0x2a,
+ 0x29, 0x57, 0x6e, 0xb7, 0x82, 0xf5, 0xde, 0x77, 0x46, 0x2f, 0x2a, 0xf7,
+ 0xd3, 0x52, 0xb9, 0x67, 0x02, 0x72, 0x66, 0x24, 0x9b, 0x11, 0xce, 0x7a,
+ 0xca, 0x19, 0xbb, 0xa8, 0x4c, 0x4b, 0xf5, 0xc5, 0x65, 0x9a, 0x89, 0xd1,
+ 0xff, 0xaf, 0x33, 0x7e, 0x51, 0x99, 0xe4, 0x25, 0x65, 0x16, 0x10, 0x13,
+ 0xbf, 0xef, 0xec, 0xbb, 0xa8, 0x4c, 0xed, 0x25, 0x65, 0x16, 0xd3, 0x1e,
+ 0x9f, 0x71, 0x0e, 0x5c, 0x54, 0x66, 0xcc, 0x7f, 0x71, 0x19, 0xd9, 0xe3,
+ 0x58, 0xff, 0x17, 0x5b, 0xf4, 0x75, 0x25, 0x9f, 0xbb, 0x70, 0xbf, 0x58,
+ 0xfe, 0xf1, 0x4b, 0xfa, 0x1f, 0xb1, 0x64, 0xbe, 0x7d, 0xed, 0xe5, 0xf9,
+ 0x7e, 0xb8, 0x74, 0xff, 0x7b, 0x35, 0x17, 0x97, 0xbb, 0x22, 0x70, 0x69,
+ 0x3b, 0x45, 0x79, 0x47, 0x2f, 0x69, 0xff, 0xe6, 0xca, 0x8b, 0xbf, 0xbf,
+ 0x5d, 0x51, 0xfc, 0x5e, 0xd6, 0xe9, 0xa1, 0x4b, 0x9e, 0xff, 0x7d, 0xc5,
+ 0xc5, 0xdf, 0x37, 0x54, 0x7e, 0x78, 0x3b, 0xb5, 0x97, 0xb4, 0xa3, 0xf4,
+ 0xca, 0xbb, 0x38, 0x1e, 0x53, 0xad, 0xed, 0xed, 0x58, 0x7f, 0x43, 0x2a,
+ 0xbf, 0x89, 0xf6, 0x29, 0xb6, 0xf5, 0xe0, 0x0d, 0x6b, 0xf3, 0x6f, 0xcd,
+ 0xe0, 0xb1, 0xcb, 0xc2, 0x41, 0x7c, 0x1c, 0x6b, 0xdd, 0xbd, 0x34, 0x95,
+ 0x38, 0x69, 0xb9, 0xb6, 0x40, 0x8e, 0xe9, 0x57, 0xcc, 0x14, 0x0c, 0xf7,
+ 0xbc, 0xe5, 0x3a, 0x34, 0xe7, 0xdd, 0x3d, 0xbb, 0x58, 0x0a, 0xcf, 0xaa,
+ 0x5d, 0xba, 0x55, 0x3a, 0x47, 0x67, 0x5d, 0x1f, 0x44, 0x72, 0x66, 0x7e,
+ 0xaa, 0x8d, 0x23, 0x12, 0xde, 0x86, 0x75, 0xee, 0x59, 0x6b, 0xc5, 0xec,
+ 0x29, 0x9d, 0xd7, 0x5c, 0x03, 0x3d, 0x5f, 0xe6, 0x4d, 0xb2, 0x9e, 0x2b,
+ 0xe7, 0x19, 0x1c, 0xfa, 0xa0, 0xc4, 0xf9, 0x83, 0x8a, 0x3a, 0xe0, 0xae,
+ 0x99, 0xae, 0xf6, 0x20, 0x9a, 0xe8, 0x54, 0x90, 0xaa, 0x32, 0xa3, 0xda,
+ 0xdb, 0x25, 0x4c, 0xf3, 0x4d, 0x6c, 0x51, 0x2a, 0x26, 0xfa, 0x15, 0xef,
+ 0x44, 0x11, 0xd3, 0x3c, 0x13, 0xb2, 0xb6, 0xd0, 0xc0, 0x32, 0x41, 0xb4,
+ 0x2c, 0xf1, 0xe2, 0x3b, 0x76, 0xad, 0xfb, 0x1e, 0xc7, 0xd6, 0x25, 0x15,
+ 0x78, 0x20, 0xae, 0xa0, 0xeb, 0xaa, 0xc3, 0x78, 0x2b, 0x2f, 0xeb, 0x6c,
+ 0x56, 0x7c, 0x94, 0x6d, 0x1e, 0xb2, 0x65, 0xbd, 0x74, 0x4b, 0x7c, 0xc4,
+ 0x6d, 0xff, 0xf3, 0xe8, 0x73, 0xf7, 0xad, 0xba, 0x9d, 0xed, 0x99, 0x1e,
+ 0x67, 0x1b, 0x73, 0x8d, 0x82, 0xdd, 0x90, 0xaa, 0x63, 0xfd, 0xb7, 0x96,
+ 0xac, 0xc7, 0x69, 0x96, 0x99, 0xb0, 0x1f, 0xc4, 0xfb, 0xf9, 0x20, 0xf2,
+ 0xf6, 0x4a, 0x7c, 0x37, 0x1f, 0x60, 0xce, 0xd7, 0x85, 0xef, 0xe4, 0x57,
+ 0xe3, 0xc5, 0x61, 0xf7, 0x7d, 0x29, 0x2c, 0xb3, 0x15, 0xac, 0x88, 0xae,
+ 0xc6, 0xb1, 0xd1, 0xd5, 0x38, 0x3c, 0x2c, 0xef, 0x0e, 0xcc, 0x25, 0x8f,
+ 0x2c, 0xda, 0x9b, 0x4a, 0x8c, 0x59, 0x66, 0xaf, 0xc2, 0xa1, 0xd1, 0x30,
+ 0x73, 0x29, 0x03, 0x27, 0xf3, 0x21, 0x8c, 0xd8, 0x6d, 0x38, 0x91, 0x0f,
+ 0xe3, 0xeb, 0x76, 0x02, 0x67, 0xf9, 0xfd, 0xa0, 0x2d, 0x9c, 0xa5, 0x03,
+ 0xd3, 0xf9, 0x6f, 0x32, 0xcf, 0x99, 0x87, 0x23, 0xdd, 0xcf, 0x30, 0x1c,
+ 0x1d, 0xe4, 0xd5, 0x85, 0x13, 0xa3, 0x5d, 0x38, 0x35, 0x7c, 0x2b, 0x4e,
+ 0x8d, 0xfe, 0x18, 0x6f, 0x0d, 0x4b, 0x7f, 0xe5, 0xfc, 0xb7, 0xc8, 0xd5,
+ 0x29, 0x77, 0x35, 0xa6, 0x46, 0xff, 0x18, 0xd9, 0xef, 0x3a, 0x47, 0x56,
+ 0x8b, 0xdc, 0x67, 0x7e, 0x87, 0x6c, 0xd1, 0xa5, 0x60, 0xbf, 0x1f, 0xc7,
+ 0x6c, 0x3f, 0x8e, 0xda, 0x53, 0x57, 0x56, 0x61, 0xea, 0x7a, 0x22, 0x1d,
+ 0xb6, 0xe7, 0x2b, 0xf1, 0x5c, 0x56, 0xd6, 0xd8, 0x3e, 0x86, 0x64, 0x70,
+ 0x23, 0xb6, 0x4e, 0x56, 0xe2, 0x3b, 0x59, 0x3f, 0x75, 0x7c, 0x3d, 0x92,
+ 0xf5, 0xab, 0xa9, 0xbf, 0x00, 0x5e, 0xb2, 0x43, 0x78, 0xd9, 0x6e, 0x4d,
+ 0x15, 0x94, 0x76, 0x58, 0x2e, 0xfe, 0x07, 0xa8, 0xef, 0x0d, 0x6e, 0x9f,
+ 0xbe, 0x63, 0x77, 0x3b, 0x5b, 0xa9, 0xe3, 0xfe, 0xcc, 0xe7, 0xdd, 0xb3,
+ 0xdb, 0x2f, 0xda, 0xd3, 0x8e, 0xbc, 0x93, 0xf1, 0x14, 0x75, 0x7a, 0xcc,
+ 0x4e, 0x91, 0xdb, 0x35, 0x71, 0x8e, 0xa6, 0x30, 0x4a, 0xbb, 0x3c, 0x99,
+ 0xd5, 0x8f, 0xae, 0xc5, 0x26, 0x9c, 0xcd, 0x55, 0xe2, 0x35, 0xb6, 0x51,
+ 0xb7, 0xd8, 0x8b, 0xe3, 0xae, 0xbc, 0x4d, 0x78, 0x3f, 0xab, 0x30, 0xde,
+ 0x6e, 0xc2, 0x7b, 0x7c, 0xf6, 0x0a, 0x3f, 0x9f, 0x8e, 0xb3, 0x87, 0xa5,
+ 0x67, 0xa7, 0xc8, 0xcf, 0x65, 0xcd, 0xa8, 0xb7, 0x63, 0x13, 0x4e, 0xe4,
+ 0xde, 0x23, 0xa7, 0x75, 0xf0, 0x45, 0x63, 0x36, 0x12, 0xb3, 0xc9, 0x9b,
+ 0xf4, 0x4a, 0x1c, 0xe3, 0xf3, 0x85, 0xc4, 0xdf, 0xe2, 0xfa, 0xd9, 0x26,
+ 0xbc, 0xcb, 0xf1, 0x3c, 0x40, 0x59, 0xef, 0xe4, 0xfe, 0x96, 0x72, 0x97,
+ 0x22, 0x1f, 0xff, 0x5b, 0xca, 0xfd, 0x31, 0xc6, 0x4b, 0xfa, 0x38, 0x61,
+ 0xc8, 0xb8, 0xbe, 0x31, 0x0b, 0xd5, 0x21, 0x8e, 0xe3, 0x9b, 0xfc, 0xbf,
+ 0x01, 0xc7, 0xf3, 0xff, 0x9b, 0xff, 0xbf, 0x8b, 0x03, 0x79, 0x59, 0xaf,
+ 0x9e, 0x19, 0x4b, 0xc5, 0x7f, 0xca, 0x1c, 0x64, 0x0e, 0x32, 0x83, 0xb5,
+ 0xa9, 0xd9, 0xb4, 0xa3, 0xbf, 0xbe, 0xb6, 0x0e, 0xef, 0xc6, 0x2d, 0xec,
+ 0xd8, 0xe7, 0x45, 0x86, 0xb8, 0xbb, 0x63, 0xa0, 0x01, 0x4f, 0xec, 0x0c,
+ 0xe2, 0xf1, 0x9d, 0x97, 0x61, 0xcb, 0xce, 0x2b, 0xb0, 0x67, 0x67, 0x13,
+ 0xd2, 0x3b, 0x1d, 0xe7, 0xfd, 0xc5, 0x8e, 0xb3, 0x88, 0xd7, 0x23, 0xf4,
+ 0x05, 0x3f, 0xff, 0xbf, 0x10, 0x17, 0x3f, 0xd1, 0x71, 0x95, 0xeb, 0x2f,
+ 0x9d, 0xb8, 0xd2, 0xfd, 0x9f, 0xc4, 0xa2, 0xfc, 0xc6, 0xf8, 0xfa, 0xc2,
+ 0xa6, 0xf8, 0x7d, 0x85, 0x39, 0xd8, 0x3a, 0xd8, 0x88, 0xc1, 0x9d, 0x0d,
+ 0xa9, 0x06, 0xb6, 0xb3, 0xea, 0x5a, 0xe1, 0x76, 0x8e, 0x63, 0xb4, 0xf7,
+ 0xc7, 0xd7, 0x16, 0x9e, 0x41, 0x77, 0x21, 0x84, 0xbe, 0xc1, 0x30, 0xdb,
+ 0x92, 0xbd, 0x5c, 0xef, 0xd1, 0x7b, 0xe1, 0x38, 0xd3, 0x8b, 0x0f, 0xe2,
+ 0xae, 0xc2, 0x37, 0xc9, 0x1b, 0x43, 0x48, 0x0f, 0xae, 0x47, 0x66, 0xb2,
+ 0x22, 0xe5, 0x37, 0x1d, 0xbc, 0x14, 0x9f, 0xc2, 0xed, 0x94, 0xf7, 0xe8,
+ 0x60, 0x2d, 0xfb, 0x54, 0x9d, 0xaa, 0x34, 0x25, 0x86, 0x3f, 0xc8, 0x18,
+ 0x25, 0xfc, 0xe2, 0x28, 0x56, 0x30, 0xbf, 0xaa, 0x5f, 0xa2, 0xcf, 0x42,
+ 0x6d, 0xd0, 0x7b, 0xa6, 0x43, 0xec, 0x2f, 0x45, 0xfb, 0x93, 0x7d, 0xf5,
+ 0x75, 0xb8, 0xdb, 0x3d, 0xe7, 0xdd, 0x83, 0xe7, 0x6d, 0xc1, 0x9d, 0x35,
+ 0xd8, 0x6f, 0xaf, 0x63, 0xce, 0x25, 0xf1, 0x7a, 0x25, 0x9a, 0x0b, 0x7f,
+ 0x17, 0xbf, 0xa7, 0xb0, 0x9a, 0x7c, 0xf6, 0x5f, 0x70, 0x53, 0x21, 0xc7,
+ 0x7e, 0x8d, 0xc6, 0xef, 0x2e, 0xec, 0x89, 0xdf, 0x5b, 0xe8, 0xc2, 0x02,
+ 0x37, 0xa7, 0x64, 0xfe, 0x55, 0x90, 0x38, 0x77, 0x9c, 0x5c, 0xf8, 0x14,
+ 0x96, 0x17, 0x5e, 0xc3, 0xcd, 0x05, 0xc1, 0x0d, 0x89, 0x7f, 0x2f, 0x7a,
+ 0x51, 0x2d, 0x71, 0xef, 0x0b, 0xd8, 0xba, 0x3b, 0x85, 0xbe, 0xdd, 0x65,
+ 0x8c, 0x6a, 0x0d, 0xee, 0x13, 0x7c, 0x99, 0xf4, 0x95, 0x62, 0xd4, 0xa7,
+ 0x68, 0x8f, 0x2a, 0x63, 0xa3, 0xac, 0xd3, 0xaf, 0xa3, 0x2f, 0x6f, 0x24,
+ 0x66, 0xca, 0x7a, 0xfc, 0x27, 0x4b, 0xf7, 0x25, 0xd6, 0xcb, 0x5a, 0xbc,
+ 0x86, 0x43, 0x79, 0x77, 0x4f, 0x5b, 0xf3, 0xeb, 0xb7, 0xf3, 0x99, 0xd4,
+ 0xff, 0x02, 0xd2, 0xbb, 0x57, 0x3b, 0x8f, 0x66, 0x8a, 0xfb, 0x66, 0x47,
+ 0xa2, 0x6c, 0x6b, 0x9c, 0xb1, 0x7d, 0x2f, 0xfc, 0xb3, 0x38, 0xb6, 0x89,
+ 0x01, 0x58, 0x1e, 0xbd, 0xdb, 0xd9, 0x92, 0xc1, 0xbd, 0xb3, 0x10, 0xc6,
+ 0xca, 0x89, 0x0a, 0x24, 0xf7, 0x57, 0xe3, 0xb6, 0x9d, 0x3d, 0xb4, 0x65,
+ 0x8b, 0xf6, 0xab, 0x1b, 0x77, 0x2b, 0xd5, 0xb8, 0x99, 0xf7, 0x3e, 0x3d,
+ 0x28, 0x6b, 0x58, 0xd1, 0xa3, 0x27, 0x3c, 0xd5, 0xb8, 0x6b, 0xaf, 0x1f,
+ 0xb9, 0xdc, 0x4a, 0x24, 0xf7, 0x1e, 0x81, 0x95, 0xa3, 0x4d, 0xee, 0x22,
+ 0xce, 0x30, 0xcd, 0x51, 0xcd, 0x1f, 0x63, 0xcf, 0xa8, 0x8a, 0xba, 0x5d,
+ 0xb2, 0xfe, 0xa8, 0xe8, 0xa7, 0xa3, 0x05, 0xa4, 0x47, 0xbd, 0x98, 0x95,
+ 0xee, 0xc4, 0x04, 0xb1, 0x26, 0x90, 0x4e, 0x22, 0x9f, 0xef, 0x46, 0x8e,
+ 0x58, 0x92, 0x1b, 0x0d, 0xa0, 0x26, 0x6d, 0x20, 0xa0, 0xc7, 0xb0, 0x83,
+ 0xfe, 0x52, 0x91, 0xd6, 0xb1, 0x2d, 0x7f, 0x23, 0xac, 0xd1, 0x4f, 0x60,
+ 0xfb, 0x68, 0x37, 0x2f, 0x13, 0x7d, 0xa3, 0x9f, 0xc7, 0xb2, 0x89, 0xa3,
+ 0xe8, 0xcf, 0xa7, 0x68, 0x8f, 0xef, 0x61, 0x7b, 0xee, 0x30, 0x9e, 0xc8,
+ 0x6e, 0xc6, 0xd9, 0xc5, 0x87, 0xf1, 0x38, 0x3f, 0x67, 0xb3, 0xfa, 0xc6,
+ 0xb0, 0x7a, 0x18, 0x99, 0xdc, 0x26, 0x7c, 0x62, 0x50, 0xc1, 0x4b, 0xb4,
+ 0xf5, 0xdb, 0xf7, 0xd2, 0x16, 0x1f, 0xdb, 0x80, 0xae, 0x89, 0xef, 0xc2,
+ 0xce, 0x3f, 0x8f, 0x1d, 0xb9, 0x07, 0xd1, 0x9f, 0x59, 0xcf, 0xfc, 0xff,
+ 0x19, 0xca, 0x39, 0x48, 0x3f, 0xdf, 0xc8, 0x31, 0x3e, 0xcc, 0xeb, 0xc2,
+ 0x1a, 0xe3, 0x85, 0x35, 0x39, 0xfa, 0x7d, 0x46, 0x72, 0xcf, 0x75, 0xc4,
+ 0x89, 0x27, 0x6b, 0x65, 0x5d, 0xb2, 0x4a, 0x9f, 0xb9, 0x56, 0x2f, 0xb6,
+ 0x1f, 0x76, 0x73, 0xed, 0xaa, 0xb4, 0xe4, 0x75, 0x53, 0x91, 0x2a, 0x72,
+ 0x0c, 0x7f, 0x5a, 0x74, 0xd8, 0xe3, 0xf4, 0x66, 0x04, 0x4b, 0x64, 0x3e,
+ 0x34, 0xbc, 0x90, 0xff, 0x31, 0xb6, 0x0e, 0xcf, 0xc6, 0xf2, 0x6c, 0x1b,
+ 0x39, 0xa5, 0xe3, 0x7c, 0x85, 0xbe, 0x66, 0x93, 0xeb, 0xec, 0x18, 0x4c,
+ 0x12, 0x53, 0x66, 0x23, 0x39, 0xa7, 0xc8, 0x4f, 0xc2, 0x69, 0x69, 0xcb,
+ 0x57, 0xda, 0xab, 0x9b, 0xba, 0x32, 0xcc, 0x7b, 0x75, 0x69, 0x99, 0xb7,
+ 0x88, 0xa1, 0xb9, 0xfb, 0x69, 0x8e, 0xf3, 0x52, 0xb4, 0xcc, 0x95, 0xa6,
+ 0xae, 0xac, 0xc3, 0x6c, 0x59, 0x77, 0x4d, 0xc8, 0x39, 0xdf, 0x6f, 0xb5,
+ 0x2c, 0xa7, 0xaf, 0x7e, 0x01, 0x03, 0xe3, 0xe5, 0x77, 0x23, 0xff, 0xb3,
+ 0xe4, 0xdd, 0xf5, 0x9f, 0x2c, 0xaf, 0xbc, 0x07, 0x2a, 0xe7, 0x8c, 0xcb,
+ 0xef, 0x50, 0x8a, 0x2e, 0xaf, 0x90, 0xfd, 0x03, 0xab, 0xb8, 0x4f, 0x0a,
+ 0x1c, 0xb1, 0x2b, 0x18, 0x87, 0xd5, 0xa5, 0x64, 0x63, 0x21, 0x1f, 0x2a,
+ 0x19, 0x2f, 0x1b, 0xd1, 0x47, 0xbe, 0x7a, 0x93, 0x51, 0x81, 0x03, 0x6d,
+ 0x49, 0x39, 0xcf, 0xd7, 0xe3, 0x73, 0x79, 0xea, 0xa6, 0x3f, 0xff, 0x6d,
+ 0x9e, 0xba, 0x09, 0xe9, 0x8c, 0x9c, 0x63, 0xeb, 0xc6, 0x4b, 0xf5, 0xf2,
+ 0x5e, 0xe7, 0x26, 0xf7, 0x9c, 0x70, 0xd5, 0x42, 0x62, 0x46, 0x5c, 0xc3,
+ 0x51, 0xbd, 0x55, 0x6b, 0x50, 0x23, 0x06, 0x94, 0xd7, 0x1d, 0x2b, 0x94,
+ 0x44, 0xff, 0xa4, 0x9c, 0xd5, 0xfb, 0xa8, 0x3d, 0x84, 0xb5, 0xd8, 0xfe,
+ 0x58, 0x07, 0x8e, 0xaf, 0x96, 0xb5, 0xbc, 0x9f, 0x95, 0xde, 0xdb, 0x93,
+ 0x3e, 0x46, 0xea, 0xe4, 0x0c, 0xaa, 0xc8, 0xde, 0x9e, 0x51, 0x19, 0x7b,
+ 0xe2, 0x78, 0x3d, 0xe8, 0x8e, 0x37, 0x56, 0x3e, 0x97, 0x59, 0xa9, 0x2f,
+ 0x2f, 0x95, 0x5f, 0x50, 0x27, 0xbc, 0x64, 0x5b, 0x66, 0x13, 0xb9, 0xb6,
+ 0xf4, 0xe7, 0xd7, 0xce, 0xda, 0x50, 0x03, 0xcb, 0x8e, 0x95, 0x9e, 0x8b,
+ 0xad, 0x45, 0x8c, 0x24, 0xe4, 0x9e, 0xd4, 0x11, 0x9d, 0xcd, 0xac, 0xe3,
+ 0x41, 0xbd, 0x7e, 0x25, 0x1e, 0xa2, 0x8f, 0xcf, 0xd7, 0x5f, 0x76, 0x36,
+ 0xcb, 0x39, 0xcd, 0x85, 0xc1, 0x19, 0x6d, 0x2d, 0x75, 0xfb, 0x52, 0xc9,
+ 0xbe, 0x0c, 0x66, 0xe4, 0xbd, 0x81, 0xb3, 0xce, 0xc2, 0x46, 0x79, 0x7e,
+ 0x5b, 0x6d, 0x51, 0x7e, 0xb3, 0x7b, 0x0e, 0x7b, 0x4f, 0xa6, 0xdc, 0x6f,
+ 0x39, 0xe3, 0x1e, 0x2a, 0xb7, 0x15, 0xbb, 0x30, 0x1e, 0xe9, 0xdb, 0xd7,
+ 0x6a, 0x2f, 0xee, 0xf3, 0x9d, 0xb3, 0xca, 0xef, 0x17, 0xcc, 0x73, 0xeb,
+ 0x94, 0xdb, 0x94, 0x3e, 0x6e, 0xc2, 0xe3, 0x93, 0x97, 0x8e, 0xf1, 0xee,
+ 0x19, 0x63, 0x92, 0x3a, 0x32, 0xae, 0x60, 0xc9, 0x0e, 0x36, 0xb2, 0x8c,
+ 0xd4, 0x91, 0x75, 0x82, 0xa0, 0x9b, 0x3f, 0xd4, 0xed, 0x16, 0x79, 0x22,
+ 0xc3, 0x71, 0xde, 0x70, 0x63, 0xf2, 0x02, 0xb7, 0xcc, 0xe0, 0xe4, 0x6a,
+ 0xfa, 0x91, 0xb3, 0x99, 0xf8, 0xec, 0xbc, 0xd1, 0x11, 0xc6, 0x56, 0x5b,
+ 0x74, 0xad, 0x87, 0xc7, 0x88, 0x4d, 0x7d, 0x2e, 0x9f, 0xf1, 0xa1, 0x37,
+ 0x57, 0x3e, 0xeb, 0x52, 0x29, 0x7b, 0x21, 0x61, 0xd1, 0x79, 0xaf, 0x41,
+ 0x1e, 0x17, 0x5c, 0xa6, 0x79, 0xc9, 0xc5, 0xee, 0xc1, 0x7f, 0xc8, 0xfc,
+ 0xc6, 0x7c, 0xa5, 0x75, 0x93, 0x14, 0xed, 0xa8, 0x18, 0x0f, 0x41, 0xfe,
+ 0x40, 0x1e, 0x56, 0x3a, 0x43, 0xdf, 0x9b, 0xff, 0x0f, 0x67, 0xca, 0x3d,
+ 0x43, 0x7f, 0xe1, 0x2c, 0x4a, 0x2e, 0xe8, 0x38, 0xfb, 0xf8, 0xec, 0xc2,
+ 0x79, 0x7a, 0x72, 0x06, 0x5d, 0xce, 0xdd, 0xff, 0x3b, 0xe7, 0x6e, 0x66,
+ 0xd9, 0xa9, 0xfa, 0xe2, 0xfb, 0x25, 0x49, 0x75, 0x99, 0x5e, 0xc6, 0x6d,
+ 0xd9, 0x27, 0x12, 0xdc, 0x3e, 0x58, 0x57, 0x5c, 0x3f, 0x8e, 0x74, 0x75,
+ 0x43, 0xf6, 0xe4, 0xcb, 0x38, 0xa3, 0x1b, 0x8b, 0x94, 0xcd, 0x68, 0x89,
+ 0x57, 0xcb, 0xf9, 0xba, 0x88, 0xd7, 0x8c, 0x04, 0xdf, 0x42, 0x34, 0x76,
+ 0xd8, 0x3d, 0x43, 0x22, 0xd8, 0xa3, 0xe3, 0x9e, 0xbc, 0x4e, 0x9b, 0x95,
+ 0xf7, 0xd2, 0xe5, 0x73, 0xf1, 0xdd, 0xc7, 0x64, 0x5e, 0xb0, 0xba, 0x87,
+ 0x58, 0x6d, 0xfd, 0xa5, 0xcf, 0x95, 0x17, 0xe9, 0x19, 0x55, 0x22, 0x5d,
+ 0x0f, 0x2a, 0x65, 0x79, 0x81, 0x0f, 0x91, 0x17, 0x63, 0x7d, 0xad, 0xf4,
+ 0x2e, 0xb8, 0x4e, 0x19, 0x97, 0x9e, 0x0d, 0x9a, 0x93, 0x92, 0x3c, 0xfa,
+ 0x40, 0x89, 0x73, 0x1e, 0xfe, 0xad, 0x3c, 0xfa, 0x43, 0xdb, 0x4c, 0xb2,
+ 0xcd, 0xae, 0x6a, 0x25, 0x19, 0x97, 0xf7, 0x80, 0x2a, 0xe3, 0xd1, 0xd8,
+ 0x0b, 0x74, 0x72, 0xaf, 0x19, 0x0d, 0x8f, 0xba, 0x67, 0x5d, 0x0c, 0xff,
+ 0xf2, 0x7c, 0xd1, 0x7f, 0xac, 0xc9, 0xdf, 0xad, 0x93, 0x1a, 0x5d, 0xef,
+ 0x6e, 0x55, 0x92, 0xd7, 0x57, 0x53, 0x4e, 0x2c, 0x0e, 0xad, 0xc2, 0x2c,
+ 0xeb, 0x28, 0x1a, 0x7b, 0x8b, 0xf3, 0x79, 0xa8, 0x23, 0x1a, 0x1e, 0x71,
+ 0x73, 0x74, 0xd1, 0x8b, 0xe1, 0x2f, 0xce, 0xbd, 0x2e, 0x7c, 0xde, 0xf2,
+ 0x31, 0x36, 0x8f, 0xdb, 0x7e, 0x8e, 0xa5, 0x35, 0xb8, 0x1d, 0xf5, 0xb4,
+ 0x71, 0x24, 0xfb, 0xda, 0x18, 0x1f, 0x6c, 0x24, 0x3d, 0x57, 0xd5, 0x21,
+ 0x45, 0x82, 0xee, 0xd1, 0x53, 0xe4, 0x5c, 0xad, 0xb1, 0x47, 0x68, 0xbf,
+ 0xb9, 0x50, 0x24, 0x6c, 0x21, 0x85, 0xe7, 0xec, 0x65, 0x7f, 0xee, 0x81,
+ 0x65, 0xd4, 0x70, 0xa2, 0xab, 0xcd, 0xa9, 0x3f, 0xbf, 0x35, 0x1a, 0xd1,
+ 0x5e, 0x2c, 0x9d, 0xd5, 0xe9, 0xb5, 0x7f, 0xe1, 0xee, 0x51, 0x79, 0xf4,
+ 0xdf, 0x55, 0x46, 0xda, 0xf6, 0x63, 0x2c, 0x9b, 0xc5, 0x96, 0xc7, 0xd8,
+ 0x47, 0xdd, 0xc1, 0x32, 0x63, 0x33, 0x96, 0x1b, 0x01, 0xac, 0x0b, 0xb6,
+ 0x24, 0xe4, 0x2c, 0xd2, 0x48, 0xae, 0xb8, 0x36, 0x52, 0x5c, 0x0b, 0xef,
+ 0xc7, 0xa3, 0x19, 0x37, 0x3e, 0x07, 0xfd, 0x66, 0x52, 0x79, 0x34, 0xdf,
+ 0xa9, 0x3c, 0x52, 0x5a, 0x8f, 0xeb, 0xcf, 0xdf, 0x10, 0x44, 0xb5, 0x85,
+ 0x13, 0x86, 0xbc, 0x47, 0x29, 0x72, 0x2d, 0x8c, 0x76, 0xfc, 0x21, 0xef,
+ 0x53, 0x8a, 0x4e, 0x37, 0xa2, 0x6f, 0xf8, 0x61, 0xf4, 0x0e, 0xbf, 0xe4,
+ 0x9e, 0x65, 0xf5, 0xe9, 0x7e, 0xeb, 0x0a, 0x33, 0x72, 0xd0, 0xc2, 0xbc,
+ 0x7a, 0x59, 0x13, 0x6e, 0x34, 0x8f, 0xe2, 0xd1, 0xa0, 0xbc, 0x27, 0xd8,
+ 0x4f, 0x9e, 0x22, 0xef, 0x9c, 0xad, 0xc1, 0x67, 0x06, 0x64, 0x0e, 0x6b,
+ 0xad, 0x4a, 0x33, 0x92, 0x5c, 0xe7, 0xce, 0x61, 0x1b, 0x8e, 0x15, 0x1e,
+ 0xc6, 0x1b, 0xbb, 0x36, 0x43, 0x8d, 0x47, 0xc2, 0xb7, 0xc0, 0xd9, 0x7c,
+ 0xc4, 0x48, 0x5a, 0x3e, 0x44, 0x0e, 0x78, 0x54, 0xe0, 0xd9, 0x5d, 0x92,
+ 0x4f, 0xf7, 0xe0, 0x7a, 0x72, 0x80, 0x3a, 0xdd, 0x59, 0xfa, 0xab, 0xc5,
+ 0x91, 0x7e, 0xdd, 0x63, 0xfd, 0xd3, 0x1c, 0x44, 0xb2, 0x09, 0x55, 0xef,
+ 0xf9, 0xa4, 0x0a, 0x25, 0x60, 0xca, 0x6f, 0x00, 0x6c, 0xc6, 0x27, 0xda,
+ 0x03, 0xd6, 0x2c, 0x33, 0x92, 0x7d, 0x49, 0x89, 0xc4, 0x2c, 0xf5, 0x1b,
+ 0x9c, 0xe7, 0x18, 0x5e, 0x24, 0xc7, 0xe9, 0x62, 0x6c, 0x5f, 0x21, 0x31,
+ 0xdd, 0xc5, 0xbe, 0xe6, 0x44, 0x95, 0x12, 0xc4, 0x2d, 0x05, 0xe0, 0x50,
+ 0x6e, 0x0d, 0x4e, 0xee, 0x32, 0xd0, 0xc9, 0x67, 0x83, 0x19, 0x02, 0x16,
+ 0x31, 0x60, 0x83, 0x61, 0xb5, 0xaa, 0xe4, 0x16, 0x3e, 0x15, 0xcb, 0xe6,
+ 0x9b, 0xd1, 0xa9, 0xa5, 0x1e, 0x2f, 0x12, 0x05, 0x2f, 0xee, 0x60, 0x99,
+ 0xed, 0x8c, 0x0b, 0x9f, 0x4c, 0xfb, 0xc9, 0x6f, 0x9b, 0xf0, 0x33, 0xf2,
+ 0xec, 0x9f, 0x92, 0x4f, 0x1f, 0x27, 0x5f, 0x38, 0x9e, 0xaf, 0x46, 0xf7,
+ 0x90, 0x4f, 0xce, 0x1f, 0x4d, 0xf9, 0x38, 0x17, 0xb5, 0xed, 0x21, 0x9c,
+ 0x1e, 0xf5, 0xe3, 0xf6, 0x5d, 0x91, 0x3d, 0xc7, 0xd5, 0x46, 0xbc, 0x3f,
+ 0x5a, 0x8d, 0x95, 0x43, 0x7e, 0xf6, 0xcd, 0xc1, 0x0e, 0xe2, 0xff, 0xbb,
+ 0x7c, 0xd6, 0xb9, 0x0b, 0x4a, 0x7e, 0xc9, 0x02, 0xe6, 0x04, 0x3a, 0xeb,
+ 0xd7, 0xe0, 0xd6, 0x21, 0xe1, 0x81, 0x2a, 0xde, 0x1e, 0x55, 0xf0, 0x56,
+ 0xce, 0xc0, 0x32, 0xb6, 0xd7, 0x97, 0x79, 0xd6, 0xf1, 0xd3, 0xcf, 0xd7,
+ 0xe6, 0x0d, 0xdc, 0x9b, 0xd3, 0x19, 0x53, 0x7e, 0xe2, 0x78, 0xf4, 0x76,
+ 0xfc, 0x64, 0xa7, 0x7e, 0xf4, 0x75, 0x4f, 0x74, 0x6a, 0x89, 0xa7, 0x1d,
+ 0xaf, 0xed, 0x6f, 0xc7, 0xf7, 0x06, 0x97, 0xe2, 0x9a, 0xf6, 0x24, 0xce,
+ 0x2c, 0x69, 0xc7, 0xab, 0x7b, 0x75, 0x3c, 0x92, 0xe9, 0x80, 0x36, 0x31,
+ 0x45, 0xfe, 0x9b, 0x40, 0xeb, 0x84, 0x09, 0x7d, 0xd0, 0xd9, 0x5c, 0x63,
+ 0x6e, 0xc6, 0xa3, 0x86, 0x89, 0x45, 0x7b, 0x45, 0x0f, 0x8e, 0xb3, 0x6e,
+ 0x89, 0x89, 0x17, 0xb2, 0x3a, 0xfd, 0xd4, 0xa4, 0x1e, 0x74, 0x3c, 0x9e,
+ 0x31, 0x11, 0x7d, 0x4c, 0x9f, 0xde, 0xc7, 0xef, 0x4b, 0xf7, 0x75, 0xa0,
+ 0x87, 0xed, 0xdb, 0xc4, 0xeb, 0x3d, 0x13, 0x6d, 0x1c, 0xb3, 0xc1, 0xf1,
+ 0x37, 0x5b, 0x3f, 0x53, 0x3a, 0x91, 0x9d, 0xe8, 0x22, 0x9f, 0xdd, 0x4c,
+ 0x1e, 0xdb, 0xe5, 0xee, 0xb9, 0x6f, 0xcd, 0x18, 0xb8, 0x35, 0xdd, 0x85,
+ 0x27, 0x6d, 0x39, 0x3b, 0xaf, 0x27, 0xae, 0x55, 0xe4, 0x1d, 0xdd, 0x2e,
+ 0x8c, 0x51, 0x27, 0xcb, 0x86, 0x56, 0xba, 0xe7, 0x9d, 0x96, 0xef, 0xd2,
+ 0xf1, 0x44, 0xe6, 0x13, 0x38, 0x39, 0x6e, 0xa0, 0x3b, 0x2d, 0xfa, 0x96,
+ 0xf3, 0x9b, 0x29, 0x1c, 0x61, 0x6c, 0xf9, 0xd9, 0x50, 0xf2, 0x9f, 0x38,
+ 0xcd, 0xc7, 0x54, 0xc8, 0x7a, 0x89, 0x8a, 0xab, 0xdb, 0xe5, 0x0c, 0xae,
+ 0x87, 0xa8, 0x16, 0xb1, 0xea, 0x54, 0x4b, 0xe3, 0x7d, 0xcb, 0xab, 0x6e,
+ 0xc2, 0x67, 0x87, 0xbc, 0xcc, 0x19, 0x54, 0xe6, 0x3a, 0xd6, 0x06, 0xda,
+ 0x86, 0x55, 0xab, 0x16, 0xe7, 0xcd, 0xdd, 0x63, 0xd0, 0x3d, 0xd8, 0x61,
+ 0x34, 0x77, 0xd7, 0xb0, 0xde, 0x8a, 0x78, 0x24, 0x59, 0xa5, 0x76, 0x30,
+ 0x0f, 0x7d, 0x18, 0xeb, 0x76, 0x3d, 0x8c, 0xb5, 0xbc, 0x36, 0xec, 0x72,
+ 0x36, 0xdf, 0x6c, 0x28, 0x78, 0x4e, 0x77, 0x36, 0x6f, 0x36, 0x74, 0xce,
+ 0xad, 0xcc, 0xeb, 0xc3, 0xd8, 0x38, 0xf6, 0x30, 0x1e, 0xa2, 0x7d, 0x35,
+ 0xd0, 0x8f, 0x57, 0xa5, 0x9d, 0xcd, 0xd7, 0xb4, 0xc7, 0xf0, 0x73, 0x37,
+ 0xbf, 0x11, 0x7b, 0x3d, 0xe3, 0xe6, 0xdc, 0x39, 0xd5, 0xb5, 0xdd, 0xa0,
+ 0x7c, 0xb6, 0xd4, 0x25, 0xc1, 0x72, 0x6c, 0xf9, 0x05, 0xe5, 0xfe, 0x72,
+ 0x57, 0x1d, 0x1e, 0x6b, 0x90, 0xf8, 0xe1, 0xb7, 0xaa, 0x4c, 0x28, 0xfa,
+ 0x12, 0xe6, 0x71, 0x8f, 0x1d, 0xc1, 0x76, 0xf2, 0xc2, 0x50, 0x5c, 0x72,
+ 0xec, 0x56, 0x63, 0x8b, 0x7a, 0x23, 0xb1, 0x5d, 0xc1, 0xa3, 0x0b, 0xb3,
+ 0x18, 0xa0, 0xaf, 0xee, 0x58, 0x18, 0x49, 0x0d, 0xc0, 0x74, 0x76, 0xcc,
+ 0xe9, 0xff, 0x23, 0xde, 0xa1, 0x2d, 0xef, 0x4b, 0xca, 0x7b, 0xb4, 0x0f,
+ 0x63, 0xf3, 0x2e, 0x99, 0xff, 0x87, 0xf1, 0x45, 0xf6, 0x7f, 0xe3, 0xd0,
+ 0xc3, 0xf8, 0x1c, 0x6d, 0xa7, 0x7e, 0xf1, 0xa1, 0x2f, 0xd6, 0xa3, 0x25,
+ 0x5b, 0x87, 0xa9, 0xfb, 0x1b, 0xe4, 0xbc, 0x2d, 0x31, 0x71, 0x40, 0x79,
+ 0x18, 0xf7, 0x8c, 0xd4, 0xd2, 0x17, 0xdd, 0x31, 0x10, 0x8b, 0xcb, 0xf1,
+ 0x2a, 0x8c, 0x75, 0xf9, 0xa6, 0x12, 0xae, 0x87, 0xb0, 0xd6, 0x3e, 0xe0,
+ 0xfa, 0x7e, 0x85, 0xb9, 0x9a, 0x7e, 0xdf, 0x4d, 0xbf, 0x5f, 0x49, 0xbf,
+ 0xef, 0xa2, 0xdf, 0x77, 0xd2, 0xef, 0x93, 0xf4, 0x7b, 0x93, 0x7e, 0x9f,
+ 0xa0, 0xdf, 0x77, 0xd0, 0xef, 0x0d, 0xd9, 0x3b, 0x54, 0x8e, 0x76, 0x1c,
+ 0x81, 0x6f, 0xd0, 0x4f, 0x1b, 0x2a, 0xbe, 0xd3, 0xb8, 0x9f, 0xf8, 0x73,
+ 0xc2, 0x58, 0x14, 0xbe, 0x89, 0xaa, 0x1a, 0x25, 0x46, 0xe4, 0xc6, 0xff,
+ 0xce, 0x7d, 0xff, 0x2d, 0x47, 0xdc, 0x7f, 0x91, 0xfa, 0x58, 0x11, 0x6f,
+ 0x36, 0x9e, 0x64, 0x0c, 0xfb, 0xa1, 0xde, 0xda, 0x1f, 0x62, 0x99, 0xaf,
+ 0x65, 0x5a, 0xb3, 0xb3, 0xa1, 0x5b, 0xed, 0xea, 0x56, 0x60, 0x55, 0x88,
+ 0x63, 0x96, 0x73, 0xdd, 0xab, 0xf0, 0xc5, 0xe1, 0x6e, 0xfc, 0xcf, 0xe1,
+ 0x20, 0x75, 0xd1, 0x3c, 0x75, 0xa3, 0x07, 0xdf, 0x0c, 0xc3, 0x13, 0x9a,
+ 0x0b, 0x7c, 0xd0, 0x88, 0x45, 0x07, 0xe4, 0x5d, 0xec, 0x5c, 0xa3, 0xa7,
+ 0x6d, 0x3e, 0xc4, 0x46, 0x40, 0xa4, 0xf6, 0x30, 0xd3, 0x5c, 0xe4, 0xbe,
+ 0xaf, 0x99, 0x5c, 0x2d, 0x98, 0x5e, 0x85, 0xad, 0x31, 0x17, 0x67, 0x9f,
+ 0x96, 0xf3, 0xe9, 0x8d, 0xc4, 0xa3, 0x80, 0xd9, 0x85, 0x6d, 0x03, 0xd6,
+ 0x5d, 0x8d, 0x58, 0x89, 0xfe, 0x81, 0xa2, 0x0e, 0xee, 0x8f, 0x13, 0xf2,
+ 0xcc, 0xa8, 0xb6, 0x48, 0x81, 0x77, 0x43, 0x47, 0x02, 0xf7, 0xe6, 0x6d,
+ 0x64, 0x39, 0xc6, 0xf5, 0xf4, 0xb3, 0x75, 0xbf, 0xff, 0x3d, 0x7c, 0x7c,
+ 0xce, 0xd6, 0x68, 0xff, 0xe7, 0x9c, 0x5c, 0xfd, 0xa2, 0x6c, 0x23, 0xf4,
+ 0x8d, 0x77, 0xa8, 0xd7, 0x32, 0x67, 0x8e, 0x1c, 0xe4, 0x23, 0x6b, 0x8e,
+ 0x7b, 0x8e, 0xce, 0x8f, 0x05, 0x43, 0x50, 0x46, 0xd3, 0xf2, 0xce, 0xda,
+ 0x66, 0xfc, 0x5f, 0xc6, 0x37, 0x5c, 0x5b, 0x9a, 0xf2, 0xc8, 0x99, 0x16,
+ 0xb9, 0xef, 0x2c, 0x3d, 0xbb, 0x38, 0x12, 0xd3, 0x3c, 0x3f, 0xa8, 0x93,
+ 0xfd, 0x8b, 0xaf, 0x33, 0xce, 0x86, 0x87, 0x96, 0x42, 0x5d, 0xec, 0xc7,
+ 0x9d, 0x6d, 0xb3, 0x90, 0x5a, 0x25, 0x3c, 0xd4, 0xdd, 0x5f, 0xa1, 0x3e,
+ 0xff, 0x02, 0xf7, 0x19, 0x5f, 0xc1, 0xf1, 0x90, 0x8d, 0x21, 0xe2, 0xd7,
+ 0x3a, 0xe3, 0x76, 0xc5, 0xe2, 0x67, 0xe6, 0x44, 0x58, 0x6f, 0x30, 0xd7,
+ 0xfa, 0x54, 0x03, 0x1a, 0x76, 0x49, 0x79, 0x91, 0x7b, 0xc6, 0x95, 0xb7,
+ 0x3f, 0x23, 0x9f, 0x8b, 0x36, 0x3b, 0xe5, 0xf9, 0x24, 0xd0, 0x20, 0xe7,
+ 0x84, 0x15, 0xbc, 0xbd, 0xd0, 0xc6, 0x63, 0x19, 0x7c, 0xb3, 0x0a, 0xcd,
+ 0xb9, 0x41, 0xd5, 0xf3, 0xcd, 0xb9, 0x58, 0x64, 0xfc, 0x5a, 0x95, 0xf9,
+ 0x48, 0xe2, 0xbe, 0x85, 0x72, 0x1e, 0x4d, 0x3f, 0xf3, 0x3d, 0xfa, 0xd6,
+ 0x71, 0xd8, 0xd8, 0x3e, 0xf9, 0x92, 0x33, 0x35, 0x37, 0x84, 0xa7, 0x26,
+ 0xa5, 0x6e, 0x37, 0x4e, 0x70, 0x4e, 0xbe, 0xec, 0xee, 0xe7, 0x45, 0x92,
+ 0x27, 0x54, 0x79, 0xe7, 0xb0, 0x1b, 0x6f, 0x8d, 0x1a, 0xd8, 0xc7, 0x1c,
+ 0xea, 0x57, 0xc3, 0xab, 0xf0, 0xeb, 0xe1, 0x66, 0xed, 0x6f, 0x14, 0x39,
+ 0x03, 0xff, 0x71, 0xfc, 0xa8, 0x21, 0x88, 0x83, 0xb4, 0xa1, 0x69, 0xbb,
+ 0x0b, 0x6f, 0xdb, 0x56, 0x64, 0x2e, 0x22, 0x7b, 0xbc, 0x9e, 0xc8, 0x01,
+ 0x79, 0xcf, 0x79, 0x9d, 0x1a, 0x39, 0xb8, 0x44, 0x89, 0x58, 0x6f, 0xa8,
+ 0x2b, 0xf1, 0x8b, 0x7c, 0x17, 0xce, 0xe4, 0x67, 0xda, 0xc2, 0x66, 0x07,
+ 0x8d, 0x62, 0x07, 0x62, 0x0f, 0xb4, 0x45, 0xe6, 0x8a, 0xdf, 0x26, 0x8f,
+ 0xee, 0xfd, 0x18, 0xed, 0x31, 0x43, 0x7b, 0xcc, 0xd0, 0x1e, 0x89, 0x49,
+ 0xcf, 0x10, 0xab, 0xbe, 0x96, 0xa1, 0x3d, 0xd2, 0x7f, 0xbe, 0x42, 0xff,
+ 0x29, 0x72, 0xe5, 0x1e, 0x77, 0x4d, 0xff, 0x15, 0xc6, 0x44, 0xfb, 0x31,
+ 0x79, 0x7f, 0xb8, 0x79, 0x7d, 0x01, 0x91, 0x9e, 0x01, 0x65, 0x5d, 0xbd,
+ 0xbc, 0xcf, 0xf1, 0xf9, 0xa8, 0xf8, 0x80, 0xbc, 0x7b, 0x46, 0xbf, 0x1a,
+ 0x3f, 0x55, 0x27, 0xef, 0xb2, 0xee, 0xdf, 0xfd, 0x51, 0x3a, 0xfb, 0x7b,
+ 0xf6, 0x43, 0xf4, 0xf5, 0xc7, 0x8e, 0x5d, 0x74, 0xf9, 0x4f, 0xce, 0x8f,
+ 0x1a, 0x65, 0xfc, 0xab, 0xf1, 0xf3, 0xe1, 0x4e, 0x9c, 0x65, 0xfc, 0xfd,
+ 0x74, 0xfb, 0x94, 0x45, 0x9b, 0xdd, 0x68, 0x78, 0x4c, 0x4c, 0xe6, 0x3b,
+ 0x71, 0xda, 0x36, 0x91, 0xb7, 0x9b, 0xd7, 0x7f, 0x57, 0x79, 0x53, 0xcd,
+ 0xcd, 0x2b, 0xf2, 0xf9, 0xdf, 0x90, 0x5f, 0x1e, 0x6a, 0x91, 0xf7, 0x5d,
+ 0x13, 0x18, 0xc9, 0x8b, 0x9d, 0x06, 0x71, 0xd3, 0x12, 0x43, 0xde, 0x11,
+ 0xfb, 0xbd, 0x7f, 0xf7, 0xd9, 0xb2, 0x97, 0x72, 0xce, 0x99, 0x0a, 0xfa,
+ 0xad, 0x20, 0x7d, 0xd8, 0xb3, 0x4b, 0x7e, 0x07, 0x40, 0xfc, 0x59, 0xc1,
+ 0x67, 0x8c, 0x29, 0xad, 0x06, 0x91, 0xa7, 0x77, 0x33, 0x81, 0x7a, 0x2d,
+ 0x2d, 0x67, 0x88, 0x3b, 0xf1, 0x26, 0xcb, 0x57, 0xd1, 0x2f, 0x5e, 0xcb,
+ 0x7b, 0xbd, 0x3f, 0x4a, 0xcb, 0x7b, 0xec, 0x2b, 0xf1, 0xa3, 0xfc, 0xcb,
+ 0xea, 0x2f, 0x82, 0x06, 0xde, 0x2e, 0xac, 0xc2, 0xfc, 0x5d, 0xb2, 0xbe,
+ 0x90, 0xc4, 0x7e, 0x3b, 0x72, 0xf4, 0x59, 0xac, 0xc2, 0xbc, 0xb1, 0xd5,
+ 0xcc, 0xa3, 0x15, 0xbc, 0x17, 0x5d, 0x8d, 0x00, 0x3f, 0xd7, 0xee, 0x72,
+ 0x9c, 0xc3, 0xf1, 0x3a, 0x67, 0xfb, 0x6a, 0x99, 0x3b, 0xc1, 0x93, 0x65,
+ 0xf5, 0xa8, 0x5d, 0x0d, 0x8c, 0x09, 0x57, 0xd1, 0x71, 0xeb, 0xc0, 0x2a,
+ 0x5c, 0xb1, 0xab, 0x39, 0x76, 0x2b, 0x9a, 0xb3, 0x47, 0x3c, 0xab, 0xd0,
+ 0x30, 0x76, 0x2f, 0xe7, 0x40, 0xca, 0x6a, 0xb4, 0x3f, 0x0b, 0x95, 0xe4,
+ 0x84, 0x9d, 0xe9, 0x9f, 0x3a, 0xf3, 0x4d, 0x77, 0x1f, 0x0e, 0xeb, 0x0a,
+ 0x3a, 0xe3, 0x5d, 0x35, 0x52, 0x23, 0x4f, 0x38, 0x75, 0xa6, 0x17, 0x6b,
+ 0x0b, 0x6d, 0xb8, 0x69, 0xc8, 0x71, 0x4e, 0x2f, 0x49, 0x22, 0x60, 0x06,
+ 0x88, 0x61, 0x01, 0x3c, 0x94, 0xae, 0xe1, 0x7f, 0x07, 0x15, 0x8c, 0xc9,
+ 0x2d, 0xaa, 0xbe, 0x7e, 0x9e, 0x47, 0xef, 0x29, 0x28, 0x12, 0xf7, 0x03,
+ 0x78, 0x80, 0xf1, 0x79, 0x45, 0x3a, 0x8c, 0x54, 0xc1, 0x71, 0x5e, 0xed,
+ 0x08, 0xe1, 0x7e, 0xd6, 0xef, 0x4a, 0xf7, 0xa3, 0x97, 0x76, 0x91, 0x1a,
+ 0xd3, 0xb5, 0x20, 0xe3, 0xfd, 0xba, 0x82, 0x9f, 0x31, 0xac, 0x01, 0xb7,
+ 0xec, 0xd2, 0xf0, 0x50, 0x21, 0xc0, 0xf8, 0xe6, 0x2c, 0x3d, 0x69, 0x58,
+ 0x57, 0x7a, 0xa0, 0x63, 0x63, 0x21, 0x84, 0x95, 0xe9, 0xc8, 0xb4, 0xbc,
+ 0x47, 0x7d, 0xd6, 0x88, 0xe1, 0xc1, 0x42, 0x18, 0xb7, 0xa5, 0x0f, 0x3d,
+ 0x34, 0x1f, 0xd6, 0xff, 0x98, 0x87, 0x36, 0x7c, 0xa6, 0xd0, 0x44, 0xf9,
+ 0x91, 0xf5, 0xaf, 0x28, 0x4d, 0xf8, 0xec, 0x98, 0x41, 0xf9, 0x2a, 0x6e,
+ 0xa5, 0x9c, 0x9b, 0xd3, 0x57, 0xe0, 0x81, 0xb1, 0x0e, 0xdc, 0x5b, 0x58,
+ 0x8c, 0xe5, 0x8c, 0x4f, 0x1b, 0x98, 0x1b, 0xe2, 0xbf, 0x00, 0xb7, 0x0d,
+ 0x89, 0xee, 0xa1, 0xbc, 0xda, 0x31, 0xc5, 0x7c, 0xdc, 0x00, 0x0d, 0x91,
+ 0xf7, 0x74, 0x72, 0x30, 0x03, 0xb7, 0xed, 0x5d, 0xec, 0xee, 0xc9, 0x37,
+ 0xc7, 0x2b, 0x91, 0xea, 0x56, 0xd0, 0x39, 0x24, 0x71, 0x56, 0xb8, 0x8d,
+ 0xc1, 0xb8, 0x1a, 0x65, 0x1b, 0x06, 0xe3, 0x6a, 0xf1, 0x7e, 0x6f, 0x46,
+ 0xd6, 0x2e, 0x7e, 0x42, 0xbe, 0x14, 0x47, 0xa7, 0x1b, 0xa3, 0xfd, 0xe4,
+ 0xd7, 0x16, 0xbc, 0x8c, 0xdd, 0x71, 0xda, 0xf8, 0xd2, 0x76, 0x89, 0xd5,
+ 0x3a, 0x06, 0xe8, 0x0f, 0x93, 0x83, 0xfa, 0x86, 0x69, 0xc5, 0x44, 0x61,
+ 0xaf, 0xc4, 0xc4, 0x10, 0x1e, 0x4c, 0x9b, 0x38, 0x29, 0xe7, 0xf8, 0xaf,
+ 0x4a, 0xae, 0xa8, 0x81, 0x6e, 0x3c, 0x80, 0xa8, 0x75, 0x8c, 0xb1, 0xfd,
+ 0x4c, 0xae, 0x01, 0x37, 0xed, 0x92, 0x32, 0xed, 0x78, 0x7d, 0xd4, 0x8b,
+ 0x9b, 0xd2, 0x9b, 0xf0, 0x44, 0xd6, 0x83, 0x11, 0xa3, 0xb9, 0x5f, 0x65,
+ 0xfc, 0xbc, 0xbe, 0x3d, 0x12, 0xfc, 0x3a, 0xb9, 0xea, 0xf4, 0x62, 0x46,
+ 0xe5, 0xb9, 0x1d, 0xe8, 0x64, 0xbf, 0x3a, 0x75, 0xf1, 0x49, 0x0b, 0xf7,
+ 0x76, 0x6c, 0xc2, 0xb1, 0xac, 0x6e, 0x3d, 0x29, 0xeb, 0x0c, 0xed, 0x7c,
+ 0x3e, 0xc7, 0x8b, 0x3e, 0x5d, 0x38, 0xad, 0x4e, 0xdf, 0x22, 0xeb, 0xd4,
+ 0x3b, 0x70, 0x92, 0xf6, 0xda, 0x9f, 0x5b, 0xca, 0xd8, 0x2f, 0x31, 0xdf,
+ 0x6f, 0x85, 0x59, 0xaf, 0xee, 0x3a, 0x05, 0x27, 0xf6, 0x09, 0xc7, 0x5a,
+ 0x8a, 0xbb, 0xa8, 0xa7, 0xce, 0xb4, 0x8a, 0xeb, 0xc7, 0xd6, 0xe0, 0xf4,
+ 0xce, 0x22, 0xe7, 0x7a, 0x35, 0x6e, 0x7d, 0x86, 0x9c, 0xab, 0x67, 0x16,
+ 0x39, 0x17, 0xb9, 0x5c, 0xec, 0x41, 0xc5, 0x8b, 0x68, 0x21, 0x41, 0x5e,
+ 0x21, 0xfc, 0x22, 0x8c, 0xa7, 0xf2, 0x1d, 0xb8, 0x25, 0xdd, 0x84, 0x71,
+ 0xf2, 0xad, 0x1c, 0xf1, 0x22, 0x97, 0x67, 0x5c, 0x19, 0x6d, 0xe4, 0xa5,
+ 0xf1, 0x5a, 0xc0, 0x4b, 0x77, 0xef, 0xad, 0xa5, 0x2d, 0x27, 0xbb, 0x25,
+ 0x4f, 0x23, 0xff, 0xcd, 0x4b, 0xac, 0x56, 0x98, 0xb7, 0xfe, 0xaf, 0x7a,
+ 0xc9, 0x4d, 0x83, 0xba, 0x82, 0xaf, 0x65, 0x35, 0xfc, 0x55, 0xfb, 0x76,
+ 0x25, 0xd9, 0xe0, 0xbe, 0x83, 0x4a, 0xdf, 0xb6, 0x70, 0x92, 0x63, 0xba,
+ 0x37, 0x2b, 0x76, 0x49, 0x19, 0xcc, 0xd1, 0x8f, 0x19, 0xf5, 0xd0, 0xea,
+ 0x35, 0x39, 0xd7, 0xc4, 0xd8, 0xc1, 0xf8, 0x6b, 0xa7, 0xc8, 0xa3, 0x5a,
+ 0xbb, 0x5b, 0x55, 0x8f, 0xbc, 0x9f, 0x67, 0x68, 0xaa, 0xf8, 0x58, 0x0a,
+ 0x15, 0x69, 0xbf, 0x55, 0x27, 0xf5, 0x97, 0x6c, 0x60, 0x3c, 0x68, 0x5d,
+ 0xff, 0xb2, 0xf0, 0xfb, 0x39, 0x11, 0x6d, 0x0a, 0x1b, 0xb0, 0xce, 0xd6,
+ 0x19, 0x03, 0xd7, 0x38, 0xbd, 0x9c, 0x87, 0x51, 0x7b, 0x03, 0xee, 0xb2,
+ 0x5b, 0xa7, 0x1e, 0xa7, 0x6d, 0xe1, 0xce, 0x0d, 0xe8, 0xe4, 0xb3, 0x91,
+ 0x4c, 0xf3, 0x74, 0x2f, 0x75, 0x7d, 0x7c, 0x76, 0xcc, 0x5d, 0xf7, 0x97,
+ 0x33, 0xe4, 0xa3, 0xe4, 0xd7, 0x5f, 0xcd, 0xb4, 0x26, 0x87, 0xd4, 0x1e,
+ 0x05, 0x73, 0x24, 0x97, 0x4c, 0x90, 0x53, 0x05, 0xf0, 0x99, 0xb4, 0x45,
+ 0x1f, 0x00, 0x6d, 0xae, 0x83, 0x79, 0xc5, 0x13, 0x4e, 0xbd, 0x19, 0x35,
+ 0x44, 0x3f, 0xeb, 0x0b, 0x4b, 0xf1, 0x14, 0x63, 0x6f, 0xf3, 0xb5, 0x7a,
+ 0xf0, 0x39, 0x68, 0xf0, 0x99, 0x3f, 0x75, 0x1a, 0xcc, 0x1a, 0x3c, 0x30,
+ 0x12, 0x4d, 0xdc, 0xc4, 0x38, 0xdb, 0x79, 0xad, 0x7e, 0xf4, 0x14, 0x63,
+ 0xe0, 0x7c, 0xd3, 0x96, 0xf3, 0x26, 0xe4, 0x3b, 0x01, 0xd7, 0xce, 0x4f,
+ 0xdb, 0xe2, 0x27, 0x3a, 0x71, 0x33, 0x84, 0xcf, 0xd1, 0xce, 0xdf, 0xb7,
+ 0x63, 0x98, 0x24, 0xdf, 0xf8, 0x2c, 0xfd, 0xe3, 0x8c, 0x1d, 0x49, 0x5d,
+ 0xa3, 0xea, 0xd8, 0x40, 0xff, 0x78, 0xd7, 0x4e, 0xd0, 0x77, 0x3e, 0xc6,
+ 0xab, 0x8d, 0xfe, 0x10, 0x63, 0x1d, 0x8d, 0x7e, 0x10, 0x72, 0xcf, 0x95,
+ 0x8e, 0x65, 0x9a, 0xbb, 0x1f, 0x42, 0x73, 0xec, 0x66, 0xa5, 0x8e, 0x79,
+ 0x6a, 0x10, 0xf7, 0x14, 0x6e, 0xc0, 0x89, 0x6c, 0x64, 0x9a, 0x39, 0xf9,
+ 0xc6, 0xa5, 0x0a, 0xee, 0x20, 0x67, 0x5b, 0x5f, 0xad, 0xb4, 0x4e, 0x3d,
+ 0xa5, 0x44, 0x68, 0x93, 0x8c, 0x97, 0xf4, 0xcf, 0xcf, 0xb2, 0xcc, 0x99,
+ 0x6c, 0x35, 0x36, 0x8c, 0xd8, 0xe8, 0xcf, 0x54, 0xa0, 0x6a, 0xa7, 0x1f,
+ 0xf7, 0x8f, 0xe9, 0xc8, 0x64, 0x64, 0x1d, 0xd9, 0x6f, 0xd5, 0x12, 0x37,
+ 0x46, 0x89, 0x0d, 0x2f, 0x2d, 0x01, 0xa6, 0xf7, 0xae, 0xc1, 0x81, 0x9d,
+ 0x3a, 0xe3, 0x5d, 0xd1, 0x3e, 0x82, 0x71, 0x97, 0x93, 0xa7, 0x84, 0x93,
+ 0x57, 0x99, 0x12, 0xfb, 0xa2, 0x3d, 0x8f, 0x50, 0x07, 0xb7, 0x15, 0xc4,
+ 0xee, 0x12, 0x9c, 0xa3, 0x30, 0x06, 0x69, 0x23, 0xfb, 0xec, 0x26, 0xe6,
+ 0xe6, 0x01, 0x58, 0xb4, 0x11, 0x4b, 0xde, 0x53, 0xa5, 0x8d, 0x58, 0xb4,
+ 0x11, 0x8b, 0x36, 0x62, 0xd1, 0x46, 0xac, 0xfc, 0x52, 0xe6, 0x4c, 0x3a,
+ 0xc6, 0xd9, 0xe6, 0xb6, 0x51, 0x72, 0xf7, 0xa0, 0xd8, 0x4a, 0x0c, 0x5f,
+ 0xcf, 0xf4, 0x2b, 0xda, 0x9d, 0x37, 0x60, 0x24, 0x7b, 0x23, 0x2f, 0x05,
+ 0xb7, 0xd2, 0x56, 0x1e, 0xcd, 0x89, 0xed, 0xe9, 0xee, 0xef, 0xd3, 0x3c,
+ 0x9b, 0xdf, 0x33, 0x1b, 0xd5, 0xe2, 0x03, 0x8c, 0x45, 0xee, 0x7d, 0x39,
+ 0x73, 0xec, 0xc7, 0x68, 0xfe, 0x82, 0x5f, 0x7c, 0x4f, 0xce, 0xab, 0xb4,
+ 0xcb, 0x6f, 0xc5, 0x74, 0x30, 0x0f, 0x90, 0x73, 0xee, 0x32, 0x4e, 0x19,
+ 0x57, 0x71, 0x4c, 0x55, 0x83, 0x9b, 0xf0, 0xf5, 0x41, 0x9d, 0xb1, 0xca,
+ 0xc0, 0x93, 0x39, 0x89, 0xe5, 0xe2, 0xdf, 0x32, 0x0f, 0xe2, 0xeb, 0x1e,
+ 0xd4, 0xb4, 0x7b, 0x11, 0x70, 0xfd, 0xbc, 0x39, 0xbc, 0x43, 0xb1, 0xe9,
+ 0x3b, 0xba, 0x9c, 0x03, 0x9d, 0x0a, 0xeb, 0x0d, 0x38, 0xbd, 0xbb, 0x1d,
+ 0xff, 0x6d, 0xa7, 0x87, 0x3c, 0xc0, 0x59, 0xfa, 0x52, 0x5c, 0x4f, 0x4e,
+ 0x2b, 0xd1, 0xd8, 0x2c, 0xa5, 0x1d, 0xf7, 0x90, 0xfb, 0x6f, 0x18, 0x8c,
+ 0x74, 0x33, 0x66, 0x1b, 0xb7, 0x28, 0x4b, 0x51, 0xc5, 0x1c, 0xa0, 0x8d,
+ 0x39, 0xc0, 0x83, 0xc4, 0x80, 0xaf, 0x66, 0xbc, 0x68, 0x59, 0x2c, 0xbf,
+ 0x4d, 0xa6, 0xbb, 0x6b, 0x3b, 0x2f, 0x90, 0xa3, 0xce, 0x37, 0x3b, 0xe4,
+ 0x2c, 0x8e, 0x72, 0xf6, 0xba, 0x29, 0x24, 0x28, 0x7f, 0xcc, 0xcd, 0x2f,
+ 0x12, 0x38, 0x98, 0x27, 0x6e, 0x70, 0xdc, 0xaf, 0xb4, 0xfd, 0x84, 0xf9,
+ 0xb0, 0x70, 0x7b, 0x13, 0x13, 0x39, 0x97, 0xff, 0x47, 0xea, 0x88, 0x19,
+ 0xd9, 0x41, 0xbd, 0xcb, 0xaf, 0x9a, 0x78, 0x64, 0xaf, 0xf8, 0xb0, 0x89,
+ 0xf6, 0x21, 0x3d, 0x7c, 0x9b, 0x1a, 0x0d, 0xae, 0xe3, 0xb3, 0x05, 0x9c,
+ 0xcf, 0xc7, 0x33, 0x32, 0x8f, 0x1a, 0x5a, 0x18, 0x9b, 0xdf, 0x9c, 0xd0,
+ 0xb1, 0x88, 0x71, 0xfa, 0x9d, 0x89, 0x18, 0x96, 0x32, 0x66, 0x3b, 0xcc,
+ 0x1f, 0x12, 0x19, 0xf1, 0x45, 0xf2, 0x81, 0x09, 0x8d, 0x71, 0x56, 0xd6,
+ 0x87, 0x9e, 0xc0, 0xd8, 0x6a, 0x0d, 0xfb, 0xdc, 0xf3, 0x7c, 0x7e, 0xab,
+ 0x81, 0x58, 0xd9, 0x39, 0xe0, 0xc7, 0xa7, 0x87, 0x36, 0xe3, 0xf5, 0xc5,
+ 0xc2, 0x95, 0xd6, 0x38, 0xa2, 0x9f, 0xc7, 0x29, 0x73, 0x8c, 0xbc, 0x78,
+ 0x94, 0x79, 0xd7, 0xc2, 0x7d, 0x6b, 0xf0, 0xc9, 0x5d, 0x17, 0xf2, 0xb4,
+ 0x33, 0x71, 0xeb, 0x6e, 0xda, 0xc4, 0xfa, 0x00, 0x6d, 0xa2, 0x96, 0x36,
+ 0x61, 0x67, 0xa2, 0xc9, 0x02, 0x6d, 0x22, 0x46, 0xdc, 0xc8, 0x0e, 0x48,
+ 0x39, 0xf7, 0x9d, 0x99, 0xbb, 0xe4, 0xdd, 0x65, 0x83, 0xbe, 0xb3, 0x75,
+ 0xc0, 0xd9, 0xec, 0x65, 0xbc, 0x79, 0xa4, 0xa3, 0x89, 0xd8, 0x72, 0x23,
+ 0xf6, 0x0c, 0x36, 0xa1, 0x85, 0x31, 0x63, 0x61, 0x1a, 0x77, 0x84, 0xa1,
+ 0xce, 0x0f, 0x23, 0xb2, 0xe1, 0x1d, 0x44, 0xa7, 0xef, 0x56, 0x5a, 0x8f,
+ 0xbe, 0xa8, 0x44, 0x36, 0xfe, 0x84, 0x36, 0x7c, 0x56, 0x91, 0xb6, 0x9b,
+ 0x70, 0x35, 0xfd, 0xe4, 0x2a, 0xfa, 0x84, 0xc6, 0x5c, 0x52, 0x63, 0xdd,
+ 0xfe, 0x41, 0x1f, 0xe6, 0x33, 0xd7, 0x93, 0xb3, 0xca, 0xb1, 0x31, 0x2f,
+ 0xb2, 0x3b, 0xf5, 0xa9, 0x47, 0xd0, 0x08, 0x63, 0xec, 0x46, 0x6c, 0x1d,
+ 0xd4, 0x10, 0xe5, 0xbd, 0xbe, 0x9d, 0x0b, 0xd0, 0x4c, 0xfb, 0xd6, 0xe8,
+ 0xa7, 0xbd, 0x83, 0x2a, 0x16, 0x8c, 0xdd, 0x80, 0x1d, 0x83, 0x0a, 0xee,
+ 0x8b, 0x2a, 0x68, 0x19, 0x91, 0x1c, 0x2c, 0x86, 0xa7, 0x32, 0xc2, 0x15,
+ 0xa1, 0xb4, 0x5c, 0x4b, 0x8e, 0x4c, 0xee, 0xf9, 0x93, 0x9c, 0xcc, 0xb9,
+ 0xe8, 0x53, 0x7e, 0x53, 0xa6, 0x1d, 0x9f, 0xdb, 0xd9, 0x80, 0xab, 0x76,
+ 0xeb, 0xd6, 0x69, 0xc5, 0x59, 0x7a, 0x80, 0x7c, 0xde, 0xaf, 0x16, 0xe7,
+ 0xfc, 0xc1, 0xc1, 0x67, 0x19, 0x2f, 0x7e, 0xe2, 0x04, 0xf5, 0xa5, 0xe8,
+ 0x8b, 0x27, 0xb1, 0xb6, 0xa3, 0x1d, 0x6b, 0xf7, 0x8a, 0xbe, 0x1c, 0xe6,
+ 0x87, 0xcc, 0xfd, 0x26, 0xa7, 0xf0, 0x0e, 0xfd, 0x77, 0x11, 0x39, 0xed,
+ 0x52, 0xc6, 0x89, 0x37, 0x16, 0x9b, 0xd4, 0x9f, 0xee, 0x9e, 0xf5, 0x9b,
+ 0x67, 0x9a, 0xa8, 0x1d, 0xd4, 0x19, 0x67, 0x4c, 0xcc, 0xda, 0x2b, 0xed,
+ 0x99, 0xb8, 0x67, 0x50, 0x4f, 0x3d, 0xcd, 0xb9, 0x14, 0xbb, 0x11, 0xcc,
+ 0xae, 0x61, 0xec, 0x3f, 0x39, 0x29, 0x38, 0xd5, 0x89, 0x13, 0xcc, 0x03,
+ 0xde, 0x7c, 0x2c, 0xda, 0xfd, 0x33, 0xe6, 0x74, 0xef, 0x50, 0x46, 0x96,
+ 0xfd, 0x1b, 0xe0, 0xbc, 0x56, 0xa4, 0xf5, 0x8d, 0xff, 0x8c, 0x28, 0xfd,
+ 0xbb, 0x0b, 0xb5, 0xd4, 0xc9, 0x81, 0xc1, 0x95, 0xf0, 0xd3, 0x16, 0x1e,
+ 0xc9, 0x88, 0xdd, 0x10, 0xbf, 0x77, 0x7e, 0x02, 0x5b, 0xf7, 0x17, 0xf3,
+ 0xbc, 0x7b, 0x06, 0x36, 0xd1, 0xc6, 0x85, 0xb3, 0xc7, 0x68, 0xef, 0x98,
+ 0xe7, 0x43, 0xb2, 0x9e, 0x18, 0x91, 0x58, 0x4e, 0xcc, 0x7c, 0xd4, 0x20,
+ 0xae, 0xd6, 0x47, 0xc2, 0x2d, 0xaa, 0x95, 0x60, 0x5e, 0x17, 0xbe, 0x0f,
+ 0xd2, 0xbe, 0x85, 0x75, 0x4b, 0x36, 0x61, 0x4f, 0xd6, 0x8b, 0xaa, 0xc5,
+ 0x1e, 0xe2, 0xb1, 0x60, 0x94, 0x15, 0x94, 0xe7, 0x6b, 0x21, 0x7e, 0x22,
+ 0xf3, 0xeb, 0xc1, 0x99, 0x78, 0xf3, 0x86, 0xac, 0xfc, 0x96, 0x05, 0x73,
+ 0xbe, 0xcf, 0xa2, 0x83, 0x73, 0x2f, 0xfe, 0x98, 0xc0, 0x3d, 0x63, 0xc2,
+ 0xd5, 0xc8, 0xe7, 0x6c, 0x3f, 0xfe, 0x3a, 0x2b, 0x9c, 0x6e, 0x33, 0xee,
+ 0x69, 0x2f, 0xe7, 0x6e, 0x62, 0x77, 0xad, 0xd3, 0x1e, 0x34, 0x93, 0x93,
+ 0xe9, 0xb9, 0xac, 0x1a, 0xb1, 0x52, 0x88, 0xf4, 0xa7, 0x20, 0x71, 0xa2,
+ 0xd5, 0xe2, 0x0c, 0x53, 0x36, 0xb9, 0xa5, 0xed, 0x41, 0x1d, 0x7d, 0x5c,
+ 0x7e, 0x44, 0xae, 0x9d, 0xf6, 0xf3, 0xac, 0x5d, 0x0d, 0xcd, 0xb5, 0x75,
+ 0x2f, 0x96, 0x16, 0x2c, 0xe2, 0xed, 0x52, 0xb4, 0x3d, 0x16, 0xc0, 0x35,
+ 0xe4, 0x26, 0x57, 0xa7, 0x9f, 0x70, 0x66, 0x11, 0x7b, 0xdb, 0x46, 0xa2,
+ 0xc1, 0x23, 0xe4, 0x81, 0x07, 0x96, 0xfc, 0xd4, 0xf1, 0x98, 0xae, 0x5f,
+ 0x68, 0xf4, 0x00, 0xe7, 0x33, 0x1d, 0xfa, 0xd4, 0x0e, 0x04, 0x90, 0x20,
+ 0x7e, 0x5e, 0x99, 0x69, 0x40, 0xfb, 0xee, 0x7e, 0xce, 0x7f, 0x10, 0x57,
+ 0xf2, 0xfb, 0x62, 0xc6, 0x37, 0x8d, 0xd8, 0xaa, 0xc9, 0xe7, 0x82, 0xd8,
+ 0x4b, 0x98, 0x7e, 0xe4, 0x2c, 0xbd, 0xb3, 0xdd, 0xba, 0x63, 0x36, 0xf5,
+ 0xd5, 0x42, 0x5c, 0x5e, 0x9a, 0x89, 0x6c, 0xbc, 0x59, 0x51, 0xb0, 0xb2,
+ 0xdd, 0x60, 0xdb, 0x01, 0xc4, 0x32, 0xb2, 0x36, 0x70, 0xe8, 0xa1, 0x3a,
+ 0x58, 0xad, 0x01, 0xda, 0xe9, 0x11, 0x45, 0xd6, 0x35, 0x44, 0x6f, 0x4d,
+ 0xb8, 0x8a, 0x7c, 0x44, 0x23, 0x66, 0xc7, 0x0a, 0xa2, 0x43, 0x60, 0x6d,
+ 0x6e, 0x0d, 0xf6, 0x0c, 0x8b, 0x7f, 0x0a, 0x76, 0x3a, 0x4e, 0xe5, 0xe2,
+ 0xa8, 0xf1, 0x36, 0x75, 0xf8, 0xc6, 0x84, 0x60, 0x90, 0x82, 0x79, 0xb4,
+ 0x63, 0x55, 0x97, 0x58, 0x2b, 0xb8, 0x15, 0xa6, 0xdf, 0x76, 0xe0, 0xd3,
+ 0x8c, 0x6d, 0xd5, 0x9c, 0x83, 0x55, 0x4b, 0x9a, 0xe8, 0xbf, 0xc4, 0xc9,
+ 0x89, 0x20, 0xaf, 0x10, 0x8e, 0xef, 0x6f, 0xe4, 0xa5, 0xf1, 0x5a, 0xc0,
+ 0x4b, 0xe7, 0x3d, 0x15, 0x67, 0xf6, 0x93, 0x33, 0xed, 0x15, 0x0e, 0x22,
+ 0x3e, 0xe8, 0xc7, 0xd3, 0x13, 0x20, 0x8f, 0x31, 0xc8, 0x43, 0x04, 0xff,
+ 0x64, 0x9e, 0x98, 0xc7, 0x0c, 0xc6, 0x11, 0x1d, 0x29, 0x72, 0x8e, 0x93,
+ 0xc3, 0x7a, 0xcf, 0x5a, 0x44, 0xb5, 0xbf, 0x26, 0x7e, 0x9d, 0x1a, 0x6d,
+ 0xc7, 0x74, 0x96, 0xb8, 0xb5, 0xb8, 0x1d, 0x6f, 0xe7, 0x36, 0xd1, 0xff,
+ 0x55, 0x9c, 0x25, 0x66, 0x69, 0x73, 0x05, 0xd7, 0x05, 0x43, 0xfd, 0xb4,
+ 0xd7, 0x0e, 0x59, 0x03, 0x55, 0xe2, 0xc4, 0xac, 0x6b, 0xd2, 0xcf, 0x3a,
+ 0xb5, 0x3a, 0x73, 0x2a, 0x35, 0x81, 0x0c, 0x31, 0xcb, 0xce, 0xca, 0x7c,
+ 0x6d, 0xc6, 0x56, 0xe2, 0xd5, 0xd6, 0x9c, 0xd8, 0x37, 0x6d, 0x7a, 0x50,
+ 0x0f, 0x16, 0x68, 0xdb, 0xea, 0x5e, 0x91, 0x61, 0xa2, 0x8f, 0xb1, 0xfd,
+ 0x33, 0x1d, 0x26, 0x76, 0xe4, 0x24, 0x0e, 0x0a, 0x07, 0xd3, 0x98, 0x97,
+ 0x24, 0xd1, 0x43, 0x9c, 0x7a, 0xdb, 0xee, 0xc4, 0x0a, 0xe2, 0xd4, 0x2f,
+ 0x98, 0xa7, 0xdc, 0x49, 0x9c, 0x7a, 0xc3, 0x2e, 0xe2, 0xd4, 0xcd, 0x13,
+ 0x62, 0x0b, 0x45, 0x5e, 0x7e, 0xc2, 0x6e, 0x6b, 0x90, 0xdf, 0x39, 0xab,
+ 0x36, 0x7f, 0x57, 0x5c, 0x58, 0x85, 0x97, 0x86, 0xcb, 0x7b, 0xc5, 0x91,
+ 0xe4, 0xed, 0xe4, 0xcc, 0x47, 0x47, 0xcb, 0x9c, 0xf7, 0xb8, 0x9b, 0x5b,
+ 0xcf, 0x32, 0xcb, 0xfb, 0x96, 0xe5, 0xfd, 0x06, 0x0b, 0x5f, 0x5d, 0x22,
+ 0x3c, 0x53, 0xd6, 0x81, 0x2a, 0xc8, 0x27, 0xbb, 0x31, 0xbe, 0xf3, 0x3d,
+ 0x3c, 0x32, 0xa8, 0xde, 0x5c, 0xc3, 0xd8, 0x7a, 0x8b, 0xb2, 0x19, 0x9e,
+ 0xb8, 0xbc, 0x47, 0x2a, 0x6b, 0xe5, 0xcc, 0x5d, 0x26, 0xb3, 0xe8, 0xdb,
+ 0x57, 0x83, 0x43, 0x41, 0xc7, 0x79, 0xda, 0x98, 0x27, 0x3f, 0x13, 0x20,
+ 0xb8, 0x19, 0xa8, 0xa0, 0x2f, 0xdc, 0xfc, 0x5b, 0xbf, 0xdd, 0x58, 0xde,
+ 0x3b, 0xd8, 0x88, 0xbb, 0x76, 0x3d, 0x8c, 0x9e, 0x5d, 0x7f, 0x8b, 0x4f,
+ 0x0e, 0x2d, 0xec, 0x9f, 0xe7, 0x71, 0x9c, 0xab, 0xdb, 0xa7, 0x70, 0x2a,
+ 0xce, 0xd8, 0x18, 0x52, 0xf0, 0xbd, 0xab, 0x16, 0x8a, 0x1c, 0xfe, 0xbd,
+ 0xef, 0x68, 0xae, 0xbc, 0x5b, 0x4b, 0x3e, 0x92, 0x98, 0xc3, 0xf1, 0x53,
+ 0xf6, 0x8a, 0xfa, 0xd2, 0xbb, 0xc2, 0x7f, 0x40, 0x5b, 0x3f, 0x16, 0x19,
+ 0xfc, 0x2b, 0xcb, 0x78, 0xcd, 0x49, 0xae, 0x96, 0x7a, 0x15, 0xa5, 0x36,
+ 0xfe, 0x96, 0x9c, 0x90, 0xbc, 0xd0, 0xe0, 0xff, 0x91, 0xeb, 0x44, 0x3e,
+ 0x9f, 0x95, 0xe5, 0xbf, 0xe4, 0x24, 0xbb, 0xe5, 0xbb, 0x94, 0x59, 0xc7,
+ 0x67, 0x52, 0xae, 0xfc, 0xec, 0xf9, 0x92, 0x9c, 0x4a, 0x68, 0x0d, 0x45,
+ 0x39, 0x9f, 0xa6, 0x9c, 0x33, 0x8b, 0x93, 0x50, 0xaf, 0x9d, 0x29, 0xab,
+ 0xdc, 0xee, 0xff, 0x3a, 0x2f, 0xab, 0x58, 0xee, 0x6f, 0xe6, 0xc8, 0xbe,
+ 0x80, 0x7a, 0xed, 0xcc, 0x75, 0xf2, 0x0a, 0xfa, 0x6f, 0x34, 0xb8, 0xd5,
+ 0x5d, 0x9f, 0x36, 0xb0, 0xf6, 0xe2, 0x1c, 0x4b, 0xb0, 0x03, 0xe3, 0x76,
+ 0xb0, 0x94, 0x53, 0xc9, 0x2d, 0x13, 0x5f, 0x66, 0xce, 0xf6, 0x94, 0x1d,
+ 0xe9, 0x5a, 0xa7, 0xb4, 0x26, 0x17, 0x31, 0xce, 0xa0, 0x5e, 0xd6, 0xb0,
+ 0x13, 0xee, 0xef, 0xf9, 0xe5, 0xa3, 0x09, 0xe4, 0x69, 0x8f, 0xaf, 0xd8,
+ 0x91, 0x0d, 0xa7, 0xdc, 0xfd, 0x3b, 0x13, 0x2f, 0xe7, 0x5f, 0x2d, 0xed,
+ 0x33, 0x95, 0x7f, 0x4f, 0x6c, 0xe6, 0x1a, 0xaa, 0xcc, 0xbf, 0x9c, 0xb1,
+ 0x6e, 0x90, 0xb5, 0x0a, 0xcb, 0xa2, 0x9f, 0xf7, 0x66, 0xac, 0xb0, 0x8a,
+ 0xeb, 0x90, 0x0a, 0xc9, 0xbe, 0xc4, 0xd6, 0xd2, 0x6f, 0x52, 0xb1, 0xde,
+ 0xef, 0x58, 0x13, 0x02, 0x8c, 0xd2, 0x39, 0xb6, 0x18, 0xac, 0xc9, 0x2b,
+ 0xc8, 0xc5, 0x64, 0xbd, 0x01, 0xd6, 0x6c, 0x53, 0x43, 0x48, 0x3f, 0xcc,
+ 0x71, 0xfb, 0x30, 0x87, 0xf9, 0x54, 0x7c, 0x61, 0x6b, 0x77, 0xbb, 0x3a,
+ 0x57, 0x70, 0x36, 0x98, 0x54, 0x63, 0x12, 0x07, 0x50, 0x99, 0x96, 0xb3,
+ 0x26, 0x56, 0x97, 0x9f, 0x98, 0xba, 0x98, 0xd8, 0x52, 0x11, 0x85, 0xf7,
+ 0xbe, 0xbc, 0x17, 0xc1, 0x85, 0xbf, 0x70, 0x7e, 0x18, 0x8a, 0x61, 0xdb,
+ 0x64, 0xb9, 0x0f, 0x06, 0xfe, 0x7b, 0xe1, 0xd2, 0x8c, 0xb3, 0x2c, 0xf3,
+ 0x3d, 0x27, 0x39, 0x47, 0xda, 0x2e, 0xca, 0xfd, 0xe8, 0xbe, 0x4a, 0x1f,
+ 0xa5, 0xaf, 0xcd, 0x1a, 0x51, 0x15, 0x5b, 0x8d, 0x89, 0x39, 0xf2, 0x9b,
+ 0x3f, 0xf7, 0xb8, 0x67, 0xd3, 0x65, 0x0e, 0xe4, 0xfd, 0xf1, 0x04, 0xee,
+ 0x93, 0xf7, 0x30, 0x19, 0xb3, 0xee, 0xcd, 0xbb, 0xef, 0x77, 0x42, 0x7e,
+ 0x17, 0xf1, 0xde, 0x7c, 0x51, 0x7f, 0x0f, 0xe5, 0x03, 0xe4, 0xdd, 0x01,
+ 0xcb, 0x6b, 0x6e, 0x80, 0x4f, 0x97, 0x33, 0x67, 0x65, 0x5d, 0xfe, 0xdf,
+ 0x73, 0x24, 0x97, 0xff, 0x2a, 0xfd, 0xc9, 0xbb, 0x50, 0x3e, 0x5b, 0xf2,
+ 0xae, 0xa2, 0x52, 0xfc, 0x7c, 0xc6, 0x7d, 0xef, 0x5d, 0x35, 0xd7, 0xd1,
+ 0x2f, 0x67, 0xbb, 0xef, 0xeb, 0x89, 0x7e, 0x42, 0xa6, 0xe5, 0xcc, 0xd6,
+ 0x03, 0xb4, 0x91, 0xde, 0x39, 0xa5, 0x77, 0x0f, 0xba, 0xee, 0x20, 0x8e,
+ 0x2c, 0x22, 0xb7, 0x5a, 0xac, 0x44, 0xb4, 0x55, 0x4a, 0x37, 0xeb, 0x51,
+ 0x4f, 0x05, 0x91, 0xa1, 0xb8, 0xbf, 0xbd, 0xeb, 0xa3, 0x8c, 0xfd, 0x76,
+ 0xab, 0xe6, 0x53, 0x7f, 0x5e, 0x3a, 0x7b, 0x2d, 0x7b, 0xf1, 0x29, 0x3c,
+ 0x6f, 0xcf, 0xc1, 0xd4, 0x6f, 0xc9, 0x3d, 0xbf, 0x66, 0xfd, 0x4f, 0x41,
+ 0x62, 0x88, 0x4f, 0x8f, 0x6c, 0x8c, 0x7b, 0x22, 0xeb, 0xa7, 0xe9, 0xd3,
+ 0x85, 0xb8, 0x9e, 0xfa, 0x1a, 0xdb, 0xf8, 0x3e, 0xb9, 0x85, 0x3d, 0x43,
+ 0x7e, 0x51, 0x56, 0x6b, 0x4f, 0x85, 0x7a, 0xc6, 0x29, 0xbe, 0x77, 0x2d,
+ 0xbf, 0xfb, 0xbb, 0x06, 0xc1, 0xb4, 0xe5, 0x84, 0x28, 0x73, 0xbe, 0x19,
+ 0xd9, 0x53, 0xaf, 0xea, 0xd9, 0xcf, 0xab, 0x9b, 0xb1, 0x56, 0x8e, 0x7c,
+ 0x98, 0x11, 0xed, 0xd3, 0xb4, 0x8f, 0x76, 0x57, 0x46, 0x32, 0x56, 0x81,
+ 0x8f, 0x3a, 0xd3, 0xc6, 0xf1, 0x41, 0xd6, 0x28, 0x59, 0xce, 0xdd, 0xe3,
+ 0x97, 0xf7, 0x77, 0x98, 0x63, 0xdb, 0xf2, 0xbb, 0xa6, 0x6e, 0x33, 0xa5,
+ 0x7d, 0x24, 0xe6, 0xc8, 0x8c, 0x97, 0xf7, 0xc8, 0x6f, 0xc8, 0x55, 0x07,
+ 0x70, 0xaf, 0x2d, 0xeb, 0x0e, 0xff, 0x3f, 0x45, 0x18, 0xff, 0x64, 0x3c,
+ 0x59, 0x00, 0x00, 0x00 };
static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
@@ -2064,1091 +2078,1077 @@ static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b09FwRodata[(0x178/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x080015a0, 0x080015d8, 0x08001600,
- 0x08001600, 0x08001614, 0x080015bc, 0x080018a4, 0x0800186c, 0x080018f8,
- 0x080018f8, 0x08001980, 0x080018b4, 0x80080240, 0x80080100, 0x80080080,
- 0x80080000, 0x08003148, 0x080030b4, 0x08003170, 0x08003198, 0x080031c0,
- 0x080031e4, 0x0800322c, 0x08003208, 0x08003250, 0x0800311c, 0x08003344,
- 0x08003334, 0x080030d0, 0x080030d0, 0x080030d0, 0x080032a4, 0x080032a4,
- 0x080030d0, 0x080030d0, 0x08003324, 0x080030d0, 0x080030d0, 0x080030d0,
- 0x080030d0, 0x08003314, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
- 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
- 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x08003304, 0x080030d0,
- 0x080030d0, 0x080032f4, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
- 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
- 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
- 0x080030d0, 0x080032dc, 0x080030d0, 0x080030d0, 0x080032cc, 0x080032bc,
- 0x08003c0c, 0x08003be8, 0x08003bbc, 0x08003b9c, 0x08003b7c, 0x08003b24,
- 0x80080100, 0x80080080, 0x80080000, 0x80080080, 0x00000000 };
+static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = {
+ 0x80080100, 0x80080080, 0x80080000, 0x08001744, 0x08001744, 0x0800177c,
+ 0x0800177c, 0x08001790, 0x08001760, 0x080019b8, 0x08001984, 0x08001a10,
+ 0x08001a10, 0x08001a98, 0x080019c8, 0x80080240, 0x08003260, 0x080031cc,
+ 0x08003288, 0x080032b0, 0x080032d8, 0x080032fc, 0x08003344, 0x08003320,
+ 0x08003368, 0x08003234, 0x0800345c, 0x0800344c, 0x080031e8, 0x080031e8,
+ 0x080031e8, 0x080033bc, 0x080033bc, 0x080031e8, 0x080031e8, 0x0800343c,
+ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x0800342c, 0x080031e8,
+ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
+ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
+ 0x080031e8, 0x0800341c, 0x080031e8, 0x080031e8, 0x0800340c, 0x080031e8,
+ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
+ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
+ 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080033f4, 0x080031e8,
+ 0x080031e8, 0x080033e4, 0x080033d4, 0x08003d6c, 0x08003d40, 0x08003d0c,
+ 0x08003ce0, 0x08003cc0, 0x08003c74, 0x80080100, 0x80080080, 0x80080000,
+ 0x80080080, 0x00000000 };
static struct fw_info bnx2_cp_fw_09 = {
- /* Firmware version: 4.0.5 */
+ /* Firmware version: 4.4.23 */
.ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
+ .ver_minor = 0x4,
+ .ver_fix = 0x17,
- .start_addr = 0x08000074,
+ .start_addr = 0x08000080,
.text_addr = 0x08000000,
- .text_len = 0x5770,
+ .text_len = 0x5938,
.text_index = 0x0,
.gz_text = bnx2_CP_b09FwText,
.gz_text_len = sizeof(bnx2_CP_b09FwText),
- .data_addr = 0x08005900,
+ .data_addr = 0x08005ac0,
.data_len = 0x84,
.data_index = 0x0,
.data = bnx2_CP_b09FwData,
- .sbss_addr = 0x08005988,
- .sbss_len = 0x99,
+ .sbss_addr = 0x08005b44,
+ .sbss_len = 0x91,
.sbss_index = 0x0,
- .bss_addr = 0x08005a28,
- .bss_len = 0x20c,
+ .bss_addr = 0x08005bd8,
+ .bss_len = 0x19c,
.bss_index = 0x0,
- .rodata_addr = 0x08005770,
- .rodata_len = 0x178,
+ .rodata_addr = 0x08005938,
+ .rodata_len = 0x16c,
.rodata_index = 0x0,
.rodata = bnx2_CP_b09FwRodata,
};
static u8 bnx2_RXP_b09FwText[] = {
- 0xec, 0x5b, 0x7f, 0x70, 0x1c, 0xf5, 0x75, 0xff, 0x7c, 0xf7, 0xf6, 0xa4,
- 0x95, 0x74, 0xba, 0x5b, 0x49, 0x27, 0xf9, 0x14, 0x8c, 0xb5, 0x8b, 0x56,
- 0x27, 0x61, 0x19, 0x77, 0x4f, 0x3a, 0xd9, 0x4a, 0x66, 0x1b, 0x2e, 0xb6,
- 0x63, 0xe4, 0x81, 0x82, 0xb0, 0x09, 0x31, 0x53, 0x26, 0xa8, 0xb6, 0x63,
- 0xc4, 0x8f, 0x34, 0x26, 0x61, 0x06, 0x11, 0x68, 0xd8, 0x48, 0x36, 0xa6,
- 0xf6, 0x9e, 0xd6, 0x36, 0x12, 0xe0, 0x99, 0x74, 0x22, 0x64, 0x59, 0x36,
- 0xe4, 0xa4, 0x33, 0x90, 0x1f, 0x66, 0x5a, 0x6a, 0x81, 0xf9, 0x61, 0x88,
- 0x0d, 0x84, 0x42, 0x02, 0x33, 0x99, 0x89, 0xf9, 0x11, 0xc7, 0x66, 0x68,
- 0x50, 0x5a, 0x92, 0x8a, 0x89, 0xea, 0x6f, 0xdf, 0xbb, 0x93, 0xf8, 0x61,
- 0x3a, 0x4d, 0x3b, 0xd3, 0x3f, 0xf7, 0xcd, 0xdc, 0x68, 0xf7, 0xfb, 0x7d,
- 0xef, 0x7d, 0xdf, 0xef, 0xf7, 0xbe, 0x3b, 0xa3, 0x5b, 0x23, 0x28, 0xc7,
- 0x1c, 0x54, 0xd2, 0x2f, 0xbd, 0xa5, 0xef, 0x5b, 0x1d, 0x4b, 0xed, 0xa5,
- 0xfc, 0x1e, 0x0a, 0x43, 0xe5, 0xbf, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00,
- 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
- 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40,
- 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
- 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
- 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x42, 0x08,
- 0xd0, 0xf9, 0x6f, 0xe5, 0xdc, 0x0f, 0x9a, 0xe2, 0x8c, 0x7c, 0x67, 0x85,
- 0x05, 0x2d, 0xe4, 0xc4, 0xef, 0xd8, 0x68, 0x01, 0x99, 0x5c, 0xab, 0xb1,
- 0x12, 0xff, 0x29, 0xdd, 0xb8, 0x0a, 0x5e, 0x3f, 0xdf, 0x99, 0xfd, 0xc1,
- 0x13, 0xcb, 0xcd, 0xe9, 0x91, 0x10, 0x34, 0xdd, 0x79, 0x39, 0xa5, 0x27,
- 0xa1, 0x2d, 0x24, 0x9a, 0xef, 0x37, 0x6f, 0xab, 0x46, 0x74, 0x9e, 0x17,
- 0x5c, 0xc5, 0x91, 0x72, 0xbf, 0x2d, 0xf1, 0xac, 0xed, 0x8a, 0xae, 0x34,
- 0xdc, 0x90, 0x73, 0x58, 0xdc, 0xe0, 0x9d, 0x95, 0x46, 0xb8, 0x78, 0xb2,
- 0x3a, 0xa1, 0x21, 0xbc, 0x1f, 0xba, 0xea, 0x28, 0x08, 0x5b, 0xe5, 0x28,
- 0x79, 0xb0, 0x02, 0xe1, 0x07, 0x13, 0x28, 0x9d, 0x38, 0x24, 0x7a, 0x46,
- 0x34, 0x9c, 0x0c, 0x1d, 0x16, 0x9b, 0x72, 0xe8, 0x09, 0x3b, 0x33, 0x57,
- 0x8c, 0x12, 0x5d, 0xa6, 0xf0, 0xff, 0x25, 0x53, 0x57, 0x8c, 0xe5, 0xa0,
- 0x87, 0x1c, 0x28, 0xaa, 0xf3, 0x34, 0x3d, 0x33, 0xde, 0xcc, 0x15, 0xfb,
- 0x72, 0xa7, 0xe5, 0x13, 0xcd, 0x71, 0x1c, 0xc9, 0xeb, 0x38, 0x94, 0xff,
- 0x25, 0xc9, 0x61, 0xba, 0x2e, 0x34, 0x57, 0x75, 0x5c, 0x6c, 0x4b, 0x87,
- 0x31, 0xbe, 0xeb, 0xac, 0x0c, 0x59, 0xa6, 0x01, 0xc5, 0xd2, 0x8f, 0x82,
- 0xf0, 0x7c, 0xc2, 0xf3, 0xc3, 0x18, 0x1d, 0x79, 0xb3, 0x1a, 0xe5, 0x09,
- 0x3c, 0xd1, 0xcc, 0xf4, 0x4c, 0xcb, 0x3c, 0x42, 0xb1, 0x79, 0xfa, 0x12,
- 0xa2, 0x7f, 0x26, 0x0d, 0x8c, 0xed, 0xea, 0x26, 0x52, 0x89, 0x01, 0xbb,
- 0x14, 0x1b, 0x74, 0xb8, 0x65, 0x0e, 0xf3, 0x9a, 0xe7, 0xe3, 0x0a, 0x63,
- 0x22, 0xaa, 0x17, 0xf9, 0x40, 0x68, 0x16, 0xdc, 0xd2, 0x73, 0xf6, 0x4f,
- 0xe7, 0xe6, 0xf7, 0xef, 0xa1, 0x73, 0x34, 0xda, 0xef, 0xc5, 0x4f, 0xf2,
- 0x9b, 0xf0, 0xe3, 0xfc, 0xb5, 0x78, 0x2c, 0xdf, 0x4d, 0xe7, 0xde, 0x4a,
- 0xe7, 0x6e, 0xc1, 0x3f, 0xe7, 0x6f, 0xc6, 0x4f, 0xf3, 0x3d, 0xf8, 0x51,
- 0x7e, 0x3d, 0x1e, 0xcd, 0x5f, 0x85, 0x47, 0xf2, 0x28, 0xc8, 0x70, 0x3a,
- 0xdd, 0x22, 0x7e, 0xee, 0x95, 0x41, 0xdd, 0xbd, 0x15, 0x53, 0xb9, 0x30,
- 0xc2, 0xbb, 0x25, 0x76, 0xd9, 0xe6, 0x03, 0x40, 0xb3, 0x1e, 0x86, 0xc0,
- 0x4a, 0xdb, 0x3c, 0x08, 0x7c, 0x01, 0x3d, 0x71, 0xf3, 0x10, 0x50, 0x27,
- 0x5e, 0x19, 0xaa, 0x13, 0x27, 0x86, 0x54, 0xf1, 0xa2, 0x27, 0x10, 0x73,
- 0x10, 0x79, 0x21, 0x2d, 0xe5, 0xa5, 0x6d, 0x52, 0xe6, 0x52, 0x56, 0xd7,
- 0x4b, 0xc2, 0xb4, 0x77, 0x88, 0x45, 0x30, 0x6a, 0xcd, 0xcc, 0x8d, 0x42,
- 0x73, 0xcb, 0x89, 0xff, 0x9a, 0x0e, 0xc0, 0xda, 0x6d, 0x90, 0x1f, 0x58,
- 0xc7, 0x6d, 0xf8, 0x7a, 0x21, 0x26, 0xba, 0x51, 0x63, 0xad, 0xc4, 0xb7,
- 0xbb, 0x6d, 0x8c, 0xe4, 0xa1, 0x55, 0x39, 0x1f, 0x20, 0x35, 0x28, 0x60,
- 0x93, 0xbf, 0x05, 0x3d, 0xdb, 0xb9, 0x27, 0x6b, 0x8a, 0xfe, 0x26, 0xd9,
- 0x7d, 0x92, 0xdd, 0x27, 0xd9, 0x7d, 0xd2, 0xcb, 0x27, 0xbd, 0x7c, 0xd2,
- 0xc1, 0x27, 0xdd, 0x7c, 0xd2, 0xc3, 0x27, 0x3d, 0x7c, 0xd2, 0xd1, 0x67,
- 0x5f, 0xf5, 0x91, 0x0d, 0x22, 0xf8, 0xa5, 0xb7, 0x10, 0x1f, 0x78, 0xe7,
- 0xe3, 0x83, 0xb5, 0x3a, 0x5e, 0x27, 0x19, 0x15, 0xeb, 0xff, 0xca, 0xe3,
- 0xa7, 0x11, 0xf2, 0x91, 0xf1, 0xbf, 0x3f, 0xdb, 0x24, 0x8d, 0xe6, 0x69,
- 0x97, 0xe0, 0x94, 0xf7, 0xb6, 0x2c, 0x59, 0xc0, 0xe7, 0x7e, 0x11, 0x72,
- 0x08, 0x58, 0x34, 0x2c, 0xe5, 0x87, 0xed, 0xbf, 0x96, 0x6f, 0x7c, 0x95,
- 0xf9, 0x39, 0x78, 0x6b, 0x48, 0x41, 0x88, 0xd6, 0x2e, 0xb1, 0xdf, 0x90,
- 0xd7, 0xc7, 0x19, 0xef, 0x8f, 0x11, 0x94, 0xb3, 0xad, 0xa0, 0xd5, 0x38,
- 0xea, 0x1d, 0xdf, 0x4e, 0xc2, 0x8d, 0x3a, 0xaa, 0x78, 0x35, 0x6b, 0x60,
- 0x81, 0x93, 0x41, 0xa5, 0x63, 0xed, 0xba, 0x5f, 0x69, 0xed, 0xab, 0x46,
- 0xe6, 0xc2, 0x18, 0x6c, 0xec, 0xcf, 0xab, 0xe2, 0x78, 0xb6, 0x12, 0xd5,
- 0xbb, 0xad, 0xf5, 0x59, 0xa1, 0xa0, 0xa7, 0x36, 0x83, 0xb1, 0xb4, 0x69,
- 0x8c, 0xc0, 0xc0, 0xfa, 0x36, 0x05, 0x58, 0xe0, 0xe2, 0xee, 0xb4, 0x69,
- 0xbb, 0xe8, 0xc7, 0x54, 0xdc, 0xc6, 0x78, 0x5e, 0xa3, 0xfc, 0x70, 0x71,
- 0x7d, 0x5a, 0x83, 0xdc, 0x95, 0xc1, 0xa9, 0xf6, 0x52, 0x4c, 0x75, 0x73,
- 0x9c, 0xa8, 0x74, 0xf6, 0x76, 0x28, 0xd5, 0xd5, 0xe4, 0x9b, 0xb4, 0x08,
- 0x57, 0x17, 0x52, 0x94, 0xd6, 0x21, 0xfe, 0x35, 0xcd, 0x32, 0x7c, 0x4e,
- 0x1c, 0x1f, 0x8e, 0xa2, 0x7c, 0x58, 0xc3, 0x0f, 0x77, 0xab, 0x58, 0x43,
- 0x3e, 0xbe, 0x3f, 0xa5, 0x1a, 0x37, 0x0a, 0x07, 0x63, 0x79, 0x15, 0xf1,
- 0x6c, 0x3d, 0x8c, 0x2a, 0x0d, 0x8b, 0xb2, 0x2e, 0xde, 0x26, 0xde, 0x7d,
- 0xc4, 0x3b, 0xd6, 0xae, 0xe3, 0x64, 0x6d, 0xd1, 0xbf, 0xb7, 0x78, 0x8d,
- 0xee, 0x6e, 0xa5, 0x04, 0x28, 0x81, 0xab, 0x39, 0x69, 0xdc, 0xe6, 0x35,
- 0x92, 0x1e, 0xd7, 0x60, 0x45, 0x89, 0x86, 0x0d, 0x83, 0xbc, 0xb6, 0x0a,
- 0x98, 0x58, 0x50, 0x89, 0x72, 0xb6, 0x01, 0xe7, 0xf5, 0x4a, 0x7a, 0xe6,
- 0x78, 0xb8, 0x37, 0xce, 0xf6, 0x77, 0x95, 0xff, 0x90, 0x99, 0x38, 0xe3,
- 0x15, 0x73, 0xe5, 0x68, 0x3a, 0x8d, 0xdb, 0xbd, 0xc6, 0xcc, 0x5e, 0xa5,
- 0x06, 0x08, 0x9b, 0x86, 0xa1, 0x40, 0x8b, 0x3b, 0x48, 0x0d, 0x51, 0xdc,
- 0xdc, 0x5b, 0x88, 0x1b, 0xa4, 0xda, 0x73, 0x9c, 0x9f, 0x9a, 0xab, 0x13,
- 0x7e, 0xc3, 0xb2, 0x26, 0xfc, 0xf1, 0x5e, 0xc6, 0x53, 0xf1, 0x3c, 0x3d,
- 0x9f, 0xd9, 0xf7, 0xe6, 0x5c, 0x0d, 0xf9, 0x87, 0x82, 0x7f, 0x0d, 0x65,
- 0xfe, 0x6c, 0x1b, 0xd7, 0x7b, 0x8d, 0x33, 0xdb, 0x15, 0xf2, 0xe1, 0x79,
- 0x11, 0x94, 0x51, 0x1d, 0x0a, 0x13, 0xaf, 0xfd, 0xde, 0x2c, 0xd6, 0xb6,
- 0x99, 0x87, 0xf9, 0xff, 0xce, 0x46, 0xad, 0x22, 0xff, 0x0b, 0x72, 0x36,
- 0x1e, 0xca, 0xdb, 0xd8, 0x48, 0x72, 0xdc, 0x8a, 0x37, 0x81, 0xfa, 0xc5,
- 0xc6, 0x69, 0xe5, 0x2d, 0xe9, 0x5e, 0xc5, 0xfc, 0x16, 0xe2, 0x74, 0x75,
- 0x63, 0xcf, 0x69, 0xc5, 0x1c, 0xb9, 0x47, 0x61, 0x5b, 0x29, 0xf8, 0xab,
- 0xb6, 0x34, 0x46, 0xaa, 0x74, 0x5c, 0xd3, 0xa6, 0xb9, 0x8b, 0x48, 0xa6,
- 0x97, 0x97, 0x6b, 0xa8, 0xdb, 0x93, 0xc1, 0x6b, 0x6d, 0xaf, 0x62, 0x64,
- 0x2d, 0xdb, 0x81, 0xe9, 0x58, 0xe6, 0x04, 0xaa, 0xad, 0x32, 0x54, 0x8f,
- 0x86, 0x11, 0xdb, 0x73, 0x56, 0x26, 0x2c, 0x5e, 0xb7, 0xb6, 0xcc, 0x08,
- 0x96, 0x39, 0x8c, 0xe8, 0xe8, 0xe7, 0xa1, 0x5a, 0x66, 0x0b, 0xf0, 0x8d,
- 0x38, 0xe3, 0x96, 0x58, 0xf3, 0xb2, 0x0b, 0x5c, 0xfa, 0x05, 0x81, 0x1b,
- 0x53, 0x4f, 0xca, 0x4c, 0x2d, 0xd3, 0x3c, 0x46, 0xeb, 0x2c, 0x43, 0xd9,
- 0x4c, 0x06, 0x75, 0x44, 0x33, 0x8f, 0x17, 0x41, 0xef, 0x9e, 0xa2, 0x0c,
- 0x6f, 0x2c, 0xc7, 0x63, 0x1a, 0x3a, 0xd1, 0xec, 0x7f, 0x0f, 0xaf, 0x2d,
- 0x63, 0x9a, 0xef, 0x4d, 0xef, 0x6f, 0xdb, 0x49, 0x36, 0xe1, 0x7a, 0x7a,
- 0xae, 0x5f, 0x78, 0xbf, 0xbb, 0x96, 0xec, 0xd5, 0x02, 0x91, 0xa0, 0x35,
- 0x8e, 0xe1, 0xdd, 0xd2, 0x58, 0x57, 0xf4, 0x4b, 0x29, 0xf1, 0x3b, 0x93,
- 0xee, 0x44, 0x63, 0x56, 0x85, 0xf4, 0x1a, 0xed, 0x5f, 0x87, 0x76, 0xc8,
- 0xa9, 0x6b, 0x79, 0xaf, 0x51, 0x3f, 0x1a, 0x12, 0x58, 0xa1, 0x9a, 0xd3,
- 0x3d, 0x48, 0xe0, 0x20, 0xd5, 0x9a, 0x7a, 0x47, 0xa7, 0xda, 0x13, 0xa7,
- 0x1a, 0x64, 0x88, 0xe6, 0xfb, 0x6d, 0x2c, 0xce, 0x5e, 0x8b, 0x8b, 0x87,
- 0x1d, 0x1c, 0xf6, 0x6d, 0xfc, 0xd0, 0x97, 0xf2, 0x94, 0x2d, 0xe5, 0xfb,
- 0xed, 0x66, 0xef, 0x31, 0x6a, 0x0b, 0x4b, 0x97, 0xb7, 0xf6, 0xc4, 0x42,
- 0x2a, 0xd9, 0xa7, 0xc9, 0xb8, 0x59, 0x98, 0x89, 0x49, 0x61, 0x53, 0xcc,
- 0x75, 0x91, 0xed, 0x0d, 0xec, 0xcb, 0xb7, 0xe0, 0xe1, 0xbc, 0x45, 0xbf,
- 0x25, 0x14, 0x2b, 0x69, 0xaa, 0x6b, 0xac, 0xab, 0x8e, 0xb1, 0x66, 0xca,
- 0x0d, 0x5f, 0xc1, 0x41, 0x9b, 0x72, 0xa0, 0x8a, 0x70, 0xfd, 0xb3, 0xe4,
- 0x3f, 0x0d, 0x2d, 0xbb, 0x33, 0x28, 0x4b, 0xd5, 0xc0, 0xb8, 0xd2, 0xc2,
- 0x98, 0xaf, 0xb9, 0x61, 0x8a, 0xfb, 0x51, 0xef, 0x61, 0x7c, 0x4d, 0x8f,
- 0xa3, 0x9c, 0xec, 0xb7, 0xbe, 0x2d, 0x02, 0xac, 0xe3, 0xbd, 0x08, 0xea,
- 0xad, 0xe7, 0x50, 0x5f, 0x5d, 0x89, 0x92, 0xc5, 0x4f, 0x62, 0x4a, 0x8f,
- 0xa2, 0x94, 0x7a, 0x47, 0x03, 0xe1, 0x34, 0x90, 0xaf, 0x6a, 0x2d, 0x8b,
- 0x78, 0x0a, 0x58, 0x4d, 0x84, 0x4b, 0x39, 0x95, 0x20, 0xdd, 0xc3, 0xcb,
- 0xe3, 0xc8, 0x93, 0xfc, 0x93, 0x9e, 0x94, 0x91, 0xb4, 0xd9, 0xeb, 0x53,
- 0x7e, 0x4e, 0xe4, 0x3a, 0x31, 0x99, 0xbf, 0x9c, 0xea, 0xba, 0x8d, 0x7d,
- 0x9e, 0x83, 0x51, 0x5f, 0x5d, 0xef, 0xc1, 0xec, 0xbe, 0x09, 0x69, 0x3c,
- 0x4c, 0xf1, 0x33, 0xee, 0x9b, 0xc6, 0x53, 0x21, 0x0d, 0xc7, 0xec, 0x0a,
- 0x92, 0x93, 0x72, 0x97, 0x74, 0x7a, 0xdc, 0xbb, 0x0f, 0x56, 0x0d, 0xdb,
- 0x9f, 0xfd, 0x94, 0xc6, 0x01, 0xbf, 0x10, 0xdf, 0x97, 0x6a, 0x70, 0x61,
- 0x77, 0xb0, 0x6f, 0xdc, 0xe9, 0x70, 0x5b, 0xb1, 0x9e, 0x76, 0x77, 0xd8,
- 0x28, 0x1d, 0xec, 0x24, 0xbe, 0x8d, 0xf6, 0x5b, 0xb8, 0x09, 0x53, 0x09,
- 0x17, 0x4b, 0x29, 0xfe, 0x55, 0xe7, 0x81, 0xd4, 0x56, 0xcf, 0x95, 0x31,
- 0xcb, 0xea, 0x7d, 0x49, 0xdc, 0x85, 0xe3, 0x29, 0xae, 0xef, 0x2a, 0xe5,
- 0xbe, 0x8e, 0x9d, 0xf6, 0x2e, 0x9c, 0xc8, 0x7d, 0x09, 0x3d, 0x55, 0x66,
- 0xcb, 0x80, 0xb8, 0x09, 0x87, 0x77, 0x5d, 0x0c, 0x7c, 0x95, 0xf3, 0x84,
- 0x74, 0xb3, 0x6e, 0xc2, 0x91, 0x91, 0xef, 0xe0, 0x99, 0xa1, 0x72, 0x3c,
- 0x6e, 0x55, 0xa3, 0x7e, 0xbc, 0x78, 0xce, 0x97, 0x3b, 0x34, 0x8c, 0x52,
- 0x4e, 0x5f, 0x62, 0xab, 0x38, 0x19, 0xe7, 0x1a, 0x42, 0xb1, 0xd6, 0xf6,
- 0x2d, 0xaa, 0x37, 0x85, 0x16, 0x8c, 0x4d, 0x69, 0x03, 0x9e, 0x97, 0xa1,
- 0x3a, 0x58, 0x86, 0x3d, 0x55, 0x10, 0x1b, 0xa9, 0x97, 0xfd, 0xad, 0xd7,
- 0xd8, 0x3b, 0xa8, 0x54, 0x63, 0xa4, 0x3e, 0x43, 0xbe, 0x10, 0xa8, 0xb3,
- 0x0c, 0x6c, 0xcb, 0x51, 0x25, 0xcd, 0xa9, 0xf8, 0x6e, 0xae, 0x1d, 0x23,
- 0x75, 0x4c, 0x7b, 0x11, 0xa6, 0x0a, 0x7f, 0xc3, 0x38, 0x59, 0x6d, 0x26,
- 0x40, 0x36, 0x1b, 0xf3, 0x55, 0x0c, 0xdb, 0xc3, 0x67, 0x47, 0xd6, 0x9a,
- 0x7a, 0x0f, 0xe5, 0x5b, 0xa8, 0x10, 0xb7, 0xfc, 0x0c, 0x7c, 0xd3, 0xfb,
- 0xbd, 0xfc, 0xa0, 0x70, 0xa6, 0xca, 0xf9, 0x3f, 0xf5, 0x46, 0xe8, 0x8c,
- 0x14, 0xa5, 0xcc, 0xff, 0xf6, 0x68, 0xf1, 0x7f, 0x46, 0x7f, 0xcc, 0xb8,
- 0x19, 0x80, 0xe3, 0x60, 0xc1, 0x27, 0x62, 0x7e, 0xbe, 0x8e, 0x9f, 0x1b,
- 0xd3, 0xc5, 0xfa, 0xa0, 0x2f, 0x63, 0xf9, 0xe6, 0xf3, 0xaf, 0x1a, 0x75,
- 0xe3, 0x4d, 0x28, 0xdb, 0xc3, 0xef, 0xbc, 0x2e, 0x70, 0x41, 0x07, 0xe7,
- 0x5e, 0x13, 0x94, 0xd1, 0x4d, 0xd1, 0x62, 0x7d, 0x9e, 0xaf, 0x1b, 0x7f,
- 0x37, 0x77, 0x6e, 0x61, 0x16, 0xa0, 0xf7, 0x62, 0x7d, 0xfd, 0x6e, 0x9a,
- 0x9f, 0x99, 0xa6, 0x0c, 0xaf, 0xed, 0x33, 0xed, 0x11, 0x65, 0x39, 0xc9,
- 0xc2, 0xf9, 0xca, 0x79, 0x7b, 0xc7, 0x1c, 0x0d, 0xe5, 0x82, 0x7f, 0x50,
- 0xe2, 0x1a, 0xe6, 0x37, 0x4f, 0xdf, 0x84, 0x92, 0x8f, 0xce, 0x55, 0xf1,
- 0x54, 0xfa, 0xdc, 0x73, 0xaf, 0x96, 0xe5, 0x6b, 0xab, 0x29, 0xfe, 0x6a,
- 0xa1, 0x2e, 0xa6, 0x01, 0x40, 0xaf, 0x43, 0x05, 0xe5, 0x73, 0xc8, 0xba,
- 0x52, 0x86, 0xae, 0xe6, 0xf8, 0xd5, 0xdc, 0x88, 0x73, 0x1e, 0x06, 0x77,
- 0x3f, 0x41, 0xbe, 0x8f, 0x72, 0x9c, 0x92, 0xff, 0xcf, 0x43, 0xf6, 0xc1,
- 0x86, 0x28, 0xeb, 0xbb, 0xbe, 0x0d, 0x6e, 0x03, 0xd5, 0xf2, 0xdf, 0xdc,
- 0xdf, 0x2b, 0x47, 0xba, 0x75, 0x3c, 0x9b, 0x5e, 0x49, 0xeb, 0x1c, 0x67,
- 0x36, 0x7e, 0xe4, 0x69, 0xb8, 0x6d, 0x30, 0x41, 0x72, 0x72, 0x0d, 0x2d,
- 0x9b, 0x39, 0xa9, 0xd8, 0x78, 0x8c, 0x62, 0xf4, 0x11, 0x9f, 0x6d, 0xa5,
- 0xe2, 0x82, 0xb6, 0x95, 0xb2, 0xb4, 0x8e, 0xe3, 0x7e, 0x31, 0xd1, 0xe8,
- 0xc4, 0x3b, 0x0a, 0xdd, 0xfa, 0x4b, 0x79, 0x68, 0x2d, 0x3f, 0x5f, 0x48,
- 0x6b, 0x75, 0xf4, 0xf7, 0x2f, 0x64, 0xc5, 0x67, 0xe4, 0xd0, 0xff, 0x3b,
- 0x39, 0x28, 0x1f, 0x4c, 0x7b, 0x33, 0x5a, 0x69, 0x4e, 0x52, 0x91, 0xa1,
- 0xae, 0x39, 0x4e, 0xb1, 0xb1, 0x9d, 0x7a, 0xf4, 0x6f, 0x68, 0x16, 0xdc,
- 0x56, 0x98, 0xb7, 0x0a, 0xe3, 0x5b, 0x61, 0x9e, 0xdb, 0x50, 0x9c, 0xcb,
- 0x34, 0xd5, 0xe2, 0x59, 0x6d, 0x7e, 0x8f, 0x6d, 0xdd, 0x85, 0x0d, 0x43,
- 0x52, 0x6e, 0xb5, 0xe3, 0xc4, 0xa3, 0x1a, 0x5b, 0xad, 0x2e, 0xf4, 0x0e,
- 0x81, 0xf2, 0x5a, 0xca, 0xd2, 0xd4, 0xe2, 0xc4, 0x3b, 0x54, 0xe4, 0x7b,
- 0x74, 0x57, 0x8c, 0xa7, 0x3f, 0x47, 0x76, 0xaa, 0xc0, 0xcf, 0x68, 0xde,
- 0xdb, 0xe1, 0x23, 0xb3, 0x26, 0x55, 0x49, 0xfd, 0x4a, 0x87, 0xef, 0x1b,
- 0x62, 0x72, 0x48, 0x47, 0xd6, 0x3f, 0x2b, 0x8f, 0x37, 0x09, 0xec, 0xef,
- 0x88, 0xe3, 0xf8, 0x18, 0xf3, 0xd7, 0xb1, 0x2d, 0xcf, 0xb3, 0x65, 0x88,
- 0xec, 0xe1, 0x8a, 0x6b, 0xd2, 0xbc, 0x56, 0x01, 0x6b, 0x1f, 0xd7, 0x63,
- 0xcb, 0x9e, 0x11, 0x45, 0x9c, 0xbb, 0xf3, 0xaf, 0xd3, 0x9c, 0x65, 0x50,
- 0x2d, 0x5b, 0x48, 0xf3, 0x55, 0x82, 0x66, 0xa9, 0x38, 0xcd, 0x52, 0xd6,
- 0xdc, 0x7c, 0x68, 0x52, 0x36, 0x4a, 0xf9, 0x18, 0xd5, 0xb2, 0x57, 0xe8,
- 0xf7, 0x01, 0xd5, 0xd3, 0x2a, 0xd2, 0xe5, 0x82, 0x41, 0xd6, 0xc5, 0x15,
- 0x36, 0xd5, 0xdb, 0x8c, 0x52, 0x1e, 0xe3, 0x3e, 0x14, 0x9a, 0x24, 0x5e,
- 0x34, 0x73, 0x6c, 0xf3, 0x81, 0x01, 0x1f, 0xee, 0xd3, 0x94, 0xfb, 0x35,
- 0xe3, 0x51, 0x54, 0x8f, 0xeb, 0x08, 0x8f, 0xb7, 0xd0, 0xbe, 0x86, 0x38,
- 0xbd, 0xbb, 0x34, 0x13, 0xc6, 0x9c, 0x3a, 0xb1, 0xe4, 0xbe, 0x59, 0xb9,
- 0x33, 0xa5, 0xe2, 0xc6, 0x26, 0xb3, 0xeb, 0x4a, 0x81, 0x4c, 0x4b, 0x96,
- 0xf5, 0x2d, 0xa5, 0xdc, 0x94, 0x47, 0xe2, 0x96, 0x94, 0x51, 0x47, 0xde,
- 0x75, 0xa2, 0xc3, 0xb2, 0x4f, 0x80, 0x65, 0x64, 0x1a, 0x5e, 0x77, 0xc5,
- 0xef, 0x3b, 0xac, 0x07, 0x5e, 0x45, 0x12, 0xed, 0xe3, 0xaa, 0xf8, 0xb7,
- 0xec, 0x12, 0xb4, 0x4d, 0x42, 0x2f, 0x71, 0x0e, 0x89, 0x93, 0x0f, 0x1e,
- 0x16, 0xa7, 0x26, 0x48, 0x6e, 0x9f, 0x74, 0xf1, 0x49, 0x17, 0x9f, 0x74,
- 0xf1, 0x49, 0x97, 0xc2, 0x5c, 0xc9, 0xba, 0xb6, 0xd0, 0x3c, 0xf3, 0x7a,
- 0x61, 0xf6, 0xe5, 0x59, 0xb1, 0xca, 0x31, 0x33, 0x2e, 0x58, 0x6f, 0xd6,
- 0x53, 0xca, 0x57, 0xed, 0xa2, 0x3e, 0x2e, 0x95, 0x5b, 0x6d, 0x72, 0xde,
- 0x16, 0x52, 0xfe, 0xbb, 0xcd, 0xb6, 0x60, 0x1d, 0xa5, 0x7c, 0xd4, 0x26,
- 0x9b, 0x12, 0xaf, 0x01, 0x5f, 0x1e, 0x29, 0xb1, 0x2c, 0x63, 0x1c, 0x11,
- 0xd2, 0x2f, 0x4a, 0x7a, 0x69, 0xa4, 0x6b, 0x12, 0x2a, 0xe9, 0x1a, 0x1a,
- 0x87, 0xae, 0x90, 0x3c, 0xc6, 0x28, 0xd9, 0x69, 0xf2, 0xcf, 0xc9, 0xc3,
- 0xfe, 0x71, 0xc5, 0x97, 0x69, 0x3e, 0x51, 0xc9, 0xae, 0x03, 0x14, 0x23,
- 0x3d, 0x2a, 0x8c, 0x52, 0x4b, 0xa1, 0x9e, 0xa8, 0xe1, 0xc0, 0x58, 0x05,
- 0xc6, 0x47, 0x74, 0x8c, 0x8c, 0x41, 0x0f, 0x13, 0x4f, 0x77, 0xe4, 0xb0,
- 0xf8, 0x64, 0x5c, 0x95, 0x3a, 0x5b, 0xf0, 0x0e, 0xd5, 0xa9, 0x41, 0xaf,
- 0x5a, 0x9c, 0xda, 0xa5, 0x61, 0xab, 0xcf, 0xb9, 0x29, 0x71, 0xd4, 0xee,
- 0x4f, 0x10, 0x8a, 0xe8, 0xb7, 0xd7, 0x50, 0x4c, 0x85, 0xb0, 0xd9, 0x42,
- 0x66, 0x9b, 0xdd, 0x05, 0x62, 0x65, 0xec, 0xa5, 0xfa, 0xd7, 0x67, 0xb9,
- 0x7d, 0x34, 0xc6, 0xf4, 0x26, 0x60, 0xae, 0xff, 0xad, 0x30, 0x7b, 0x0e,
- 0x90, 0xfd, 0x37, 0x67, 0x91, 0xd9, 0x99, 0xad, 0x13, 0xef, 0x0e, 0xcd,
- 0xca, 0x35, 0x29, 0x33, 0xd3, 0x4c, 0x6b, 0x95, 0x59, 0x25, 0x59, 0x82,
- 0xfe, 0x8d, 0x84, 0xdb, 0xa2, 0x62, 0x36, 0xb4, 0x3d, 0xd5, 0x5f, 0x45,
- 0x13, 0x90, 0x16, 0xa1, 0x1a, 0xec, 0x35, 0x99, 0x89, 0x1c, 0xad, 0xad,
- 0xa7, 0x7b, 0xcb, 0xf3, 0xb6, 0x79, 0xec, 0x3d, 0x4c, 0x63, 0x83, 0x37,
- 0xad, 0x36, 0xfb, 0x66, 0x5f, 0x24, 0xe4, 0x76, 0x97, 0x41, 0x59, 0x5d,
- 0x81, 0x69, 0xed, 0x4c, 0xd6, 0xb4, 0x2f, 0x13, 0x6e, 0x8b, 0x86, 0xfe,
- 0x46, 0x7a, 0x8f, 0x1c, 0xf3, 0x8a, 0x74, 0x7b, 0xed, 0xfe, 0x27, 0x2b,
- 0x90, 0xec, 0xbb, 0x84, 0x7a, 0xc9, 0x92, 0x90, 0xc4, 0xf5, 0xa9, 0x69,
- 0x7d, 0xb3, 0x37, 0x1b, 0x0a, 0xb7, 0x27, 0xf5, 0x33, 0xc2, 0x4d, 0x94,
- 0x62, 0x3a, 0x7e, 0x45, 0xd6, 0x34, 0x72, 0x48, 0x1e, 0xeb, 0xc2, 0x74,
- 0x62, 0x87, 0x67, 0x4e, 0xdd, 0x8c, 0xe4, 0xfa, 0x64, 0x68, 0x7a, 0x61,
- 0x99, 0x9f, 0xcc, 0x7c, 0x53, 0x24, 0x3b, 0xcb, 0x69, 0x36, 0x1f, 0xa9,
- 0x4d, 0x66, 0xce, 0x14, 0x72, 0x8c, 0xe7, 0x1c, 0x95, 0xe6, 0x9c, 0x2d,
- 0xb8, 0x9d, 0x6c, 0xd2, 0x49, 0x76, 0x9f, 0x58, 0x52, 0x4a, 0xf3, 0x4a,
- 0xa3, 0x1d, 0x0d, 0xb9, 0x9d, 0x61, 0x98, 0xfa, 0x7b, 0x54, 0x8b, 0x27,
- 0xad, 0x19, 0x7b, 0x75, 0x8e, 0xe7, 0x1f, 0x35, 0xb5, 0x94, 0xf2, 0xf5,
- 0x9e, 0xbc, 0xa0, 0x79, 0x91, 0x6d, 0x6a, 0xea, 0x23, 0x74, 0x77, 0x33,
- 0x6a, 0xd8, 0x86, 0x2a, 0xbe, 0x6e, 0xb9, 0x06, 0xe9, 0x6d, 0x33, 0xdd,
- 0x73, 0x30, 0x13, 0xdb, 0xa9, 0x8f, 0x6f, 0xf6, 0x90, 0xb9, 0xd4, 0x7b,
- 0x34, 0x46, 0xf5, 0xb9, 0x17, 0x50, 0x2e, 0xaf, 0x84, 0xdb, 0x57, 0x86,
- 0xfe, 0x75, 0x95, 0x30, 0xed, 0xf7, 0xc4, 0x6c, 0xe8, 0xd2, 0x54, 0xff,
- 0x85, 0x95, 0x98, 0x36, 0x5e, 0xf7, 0x4c, 0xea, 0xf3, 0x12, 0xa3, 0xa9,
- 0xd9, 0xd0, 0x01, 0x7b, 0xda, 0xf2, 0x49, 0xe7, 0xf7, 0xe0, 0x1e, 0x53,
- 0x30, 0xdd, 0xb2, 0xd9, 0x33, 0xbb, 0x96, 0x84, 0x92, 0xdd, 0x09, 0x31,
- 0xbd, 0xe4, 0xa2, 0x6c, 0x32, 0x73, 0x85, 0x48, 0xae, 0x2f, 0x11, 0xbf,
- 0x22, 0x9e, 0xc9, 0xcc, 0x37, 0x04, 0xe7, 0xcf, 0xc9, 0xb9, 0xfb, 0x15,
- 0x32, 0xa3, 0x76, 0x82, 0x62, 0x8f, 0xe3, 0x55, 0x27, 0x3f, 0xf2, 0x3d,
- 0xcb, 0x80, 0xea, 0x58, 0x89, 0x31, 0xba, 0x37, 0xf6, 0x50, 0x1e, 0x1d,
- 0xb4, 0x39, 0xe7, 0xe4, 0x91, 0x52, 0xcb, 0x6a, 0x39, 0x40, 0xb7, 0xd3,
- 0xa3, 0x94, 0xe3, 0x94, 0xf3, 0xc6, 0x24, 0xf5, 0xe2, 0xa9, 0x5a, 0x15,
- 0x55, 0xce, 0x11, 0xca, 0x75, 0x42, 0x2a, 0xb7, 0xf4, 0x3e, 0x30, 0xfe,
- 0x16, 0xa0, 0xd6, 0x00, 0xcd, 0xe6, 0x84, 0x33, 0x23, 0xa7, 0xa8, 0x7e,
- 0x0c, 0xf8, 0x8c, 0x67, 0xf5, 0x3d, 0x82, 0x3f, 0xc8, 0x93, 0x55, 0x8c,
- 0x9f, 0xc1, 0x86, 0x34, 0xc4, 0xe3, 0x76, 0x0c, 0x46, 0x8d, 0x8e, 0x7e,
- 0xea, 0xe7, 0x8a, 0x63, 0xcd, 0x8c, 0x72, 0x7f, 0xab, 0x81, 0x5b, 0x41,
- 0xf3, 0x46, 0x51, 0x86, 0xd3, 0x2c, 0x03, 0xc1, 0x22, 0x71, 0xe3, 0xf0,
- 0x42, 0x71, 0x03, 0xdf, 0x01, 0x52, 0x58, 0x55, 0x86, 0x26, 0xfb, 0x34,
- 0xad, 0x72, 0xce, 0x46, 0x9d, 0x88, 0x38, 0x31, 0x0c, 0x3d, 0x67, 0x53,
- 0xe7, 0xaf, 0x92, 0xf2, 0x60, 0xca, 0x40, 0xde, 0x2e, 0xa1, 0x99, 0x3a,
- 0x8c, 0x2a, 0x0b, 0x7a, 0xc2, 0xb1, 0xee, 0x39, 0x8c, 0xaf, 0xc0, 0xa8,
- 0x43, 0x54, 0xa5, 0x7e, 0x4c, 0x6b, 0x62, 0xdc, 0x2e, 0xa3, 0x39, 0x5f,
- 0x20, 0xe1, 0x24, 0xb0, 0xdd, 0xe7, 0x7a, 0x60, 0xf5, 0x1d, 0xa6, 0x1a,
- 0x50, 0xac, 0x79, 0x3f, 0xa0, 0xb9, 0x47, 0x34, 0x54, 0x3a, 0xbc, 0xcf,
- 0xeb, 0x97, 0xf3, 0x7c, 0x5e, 0x98, 0xc5, 0xb6, 0xd3, 0xbe, 0xe4, 0xde,
- 0x5e, 0x83, 0x18, 0xc9, 0x9b, 0x18, 0xa5, 0xfb, 0x02, 0xdb, 0x28, 0xe2,
- 0x90, 0xe6, 0x75, 0xd0, 0xcb, 0x1c, 0xcb, 0x7d, 0x08, 0x5d, 0x40, 0x35,
- 0xcf, 0x11, 0xd0, 0x4a, 0x1c, 0x1b, 0xcf, 0x7a, 0xdf, 0xa7, 0xb3, 0x90,
- 0x79, 0xd7, 0x86, 0x46, 0xfc, 0x90, 0xa0, 0xbc, 0x8c, 0xb5, 0x53, 0x2c,
- 0x50, 0xff, 0x3f, 0x60, 0x23, 0xd6, 0xe0, 0x58, 0xc7, 0x8e, 0x50, 0x2c,
- 0x18, 0x0b, 0xa0, 0x28, 0xa9, 0x57, 0xc0, 0xf3, 0xbb, 0xea, 0xf0, 0xde,
- 0x04, 0x4e, 0xea, 0x88, 0x95, 0x38, 0x56, 0xd7, 0x38, 0x05, 0x82, 0xee,
- 0x3c, 0x04, 0xbb, 0xaa, 0x90, 0x93, 0xc4, 0xa7, 0x93, 0xf8, 0x80, 0xeb,
- 0xa0, 0x16, 0xa5, 0xe7, 0x17, 0x9b, 0xa4, 0x8c, 0x35, 0x5b, 0xbd, 0x79,
- 0x98, 0x3d, 0x93, 0x42, 0xc5, 0xce, 0xdd, 0x5c, 0xf3, 0xa6, 0x4c, 0x6a,
- 0x9f, 0xd4, 0xb7, 0xa3, 0xa2, 0xe4, 0x3e, 0x05, 0xcd, 0xcb, 0x54, 0xbc,
- 0x48, 0x35, 0xef, 0xd9, 0x14, 0xdf, 0xef, 0x5b, 0x63, 0xc5, 0xb9, 0x9e,
- 0x7c, 0xff, 0x51, 0xbd, 0x98, 0xbf, 0x93, 0x19, 0x54, 0x33, 0xac, 0xae,
- 0x87, 0xb1, 0x4b, 0x1a, 0x55, 0xec, 0x43, 0x9a, 0x85, 0x68, 0xd6, 0xac,
- 0xa4, 0x5a, 0x99, 0xeb, 0xb0, 0x5a, 0x28, 0x9c, 0xdd, 0x8d, 0x1d, 0x0d,
- 0xe4, 0x6f, 0x8e, 0x03, 0x59, 0xa9, 0x14, 0xfc, 0x24, 0xe5, 0x75, 0xe9,
- 0xd6, 0x63, 0x6f, 0x87, 0x0e, 0xd2, 0x9c, 0xcb, 0x36, 0xbe, 0x9c, 0xf6,
- 0xd9, 0xfe, 0x51, 0x91, 0xba, 0xdf, 0xa5, 0xde, 0xc0, 0x67, 0x4a, 0x99,
- 0x6c, 0xa3, 0x83, 0xca, 0x43, 0x34, 0x23, 0x22, 0xf3, 0xba, 0x07, 0x11,
- 0x6b, 0xdf, 0x54, 0xb0, 0xc3, 0xe3, 0x76, 0x2d, 0xc5, 0x01, 0x62, 0x9a,
- 0x63, 0xe9, 0x74, 0x71, 0x56, 0x1a, 0x9c, 0x2a, 0x5c, 0x47, 0xd2, 0x64,
- 0x7d, 0xce, 0xb7, 0x4e, 0xec, 0xf7, 0xf8, 0xfb, 0x47, 0x27, 0x36, 0x12,
- 0x8f, 0x49, 0xcb, 0x22, 0x1d, 0xcd, 0xf5, 0x03, 0x22, 0x2a, 0x9e, 0x1f,
- 0x22, 0x3d, 0x77, 0x33, 0x6f, 0x15, 0xcd, 0x4d, 0x2a, 0x56, 0x35, 0xf1,
- 0x4c, 0x3c, 0x65, 0xaa, 0x60, 0xfd, 0xfe, 0x24, 0x9b, 0xdb, 0x98, 0xce,
- 0xa2, 0xbb, 0x87, 0xa0, 0x5a, 0x97, 0xc5, 0x66, 0x5d, 0xa0, 0xcf, 0xa6,
- 0x28, 0x5e, 0xa0, 0xc2, 0x6e, 0x53, 0xd1, 0x6b, 0xef, 0x05, 0x85, 0x06,
- 0xd5, 0x38, 0x0d, 0x9b, 0xec, 0x2c, 0xdc, 0x38, 0xfb, 0xf2, 0x1f, 0x25,
- 0xae, 0x66, 0xbb, 0xec, 0x98, 0xb3, 0xd1, 0x9e, 0xc2, 0xb7, 0x82, 0x23,
- 0x3e, 0xe3, 0x45, 0xc5, 0xa9, 0x21, 0x57, 0xb0, 0x3e, 0x1f, 0xdb, 0x93,
- 0x75, 0x62, 0x19, 0xea, 0xc4, 0xce, 0x61, 0x64, 0x76, 0x74, 0x48, 0xb9,
- 0x39, 0x65, 0x76, 0xbd, 0x00, 0x05, 0xc9, 0xe1, 0x30, 0x9e, 0x5e, 0xd2,
- 0x27, 0x5d, 0x7d, 0x85, 0x49, 0x79, 0xae, 0x53, 0x54, 0x63, 0xa0, 0xd9,
- 0x9c, 0x59, 0x49, 0x5c, 0x7f, 0xe7, 0x37, 0xe0, 0x0d, 0x9b, 0x62, 0xcc,
- 0x52, 0xfb, 0x3a, 0x43, 0xdc, 0xf7, 0x37, 0x12, 0x9f, 0x26, 0xb7, 0x52,
- 0xb1, 0x7a, 0x26, 0x28, 0xcf, 0x2a, 0x9c, 0x1e, 0xb9, 0xb3, 0x96, 0x63,
- 0x10, 0x4a, 0x34, 0xf5, 0x35, 0x39, 0x55, 0xcb, 0xb1, 0xc8, 0x73, 0x59,
- 0x54, 0xe8, 0xc3, 0x7c, 0x3e, 0xcf, 0x69, 0x2a, 0xc2, 0x49, 0x29, 0xc7,
- 0xed, 0xcd, 0x24, 0x2b, 0xcb, 0x30, 0x2f, 0xeb, 0x26, 0x99, 0xa9, 0x42,
- 0x2c, 0xea, 0x58, 0xbd, 0x93, 0x54, 0xa3, 0x23, 0x4e, 0x2b, 0xdd, 0x7b,
- 0xaf, 0x93, 0xc5, 0x39, 0x94, 0xfb, 0x7e, 0x54, 0x8c, 0x0f, 0x31, 0x0f,
- 0xf6, 0xcd, 0xb9, 0x7a, 0x40, 0xa3, 0xfb, 0x33, 0x26, 0xb2, 0x02, 0xfb,
- 0x52, 0x7d, 0xb2, 0x47, 0x67, 0x7e, 0x51, 0xf1, 0xec, 0xd0, 0xc7, 0x67,
- 0x7e, 0x1a, 0x7f, 0xef, 0x9c, 0x9d, 0xbe, 0x54, 0x8c, 0x09, 0xbf, 0x18,
- 0xa3, 0x25, 0xce, 0xcb, 0x14, 0xfb, 0xca, 0x6a, 0xba, 0x9d, 0x41, 0x4f,
- 0x09, 0x3c, 0xd5, 0x29, 0x70, 0xdd, 0x12, 0x9a, 0xc1, 0x96, 0x5a, 0x14,
- 0x27, 0xd7, 0x48, 0x63, 0xc1, 0x14, 0x05, 0xdc, 0xac, 0x2c, 0x4d, 0xaa,
- 0x78, 0x67, 0x09, 0x25, 0xd1, 0x55, 0x1c, 0xab, 0x0a, 0x5e, 0x20, 0xbc,
- 0xd5, 0x17, 0x59, 0x5d, 0x47, 0x51, 0x01, 0xe3, 0x2b, 0xbc, 0xb6, 0x62,
- 0x43, 0x18, 0xad, 0x09, 0x1d, 0x16, 0xf9, 0xbc, 0x86, 0x67, 0x69, 0x92,
- 0x9f, 0x69, 0xe7, 0x63, 0xdb, 0x2b, 0xc8, 0xd1, 0xbc, 0x8c, 0x9f, 0x59,
- 0xbe, 0x8f, 0xdf, 0x07, 0x86, 0x58, 0x3e, 0xf6, 0x17, 0xf9, 0x9a, 0x64,
- 0x2e, 0x49, 0xcd, 0xc7, 0xc5, 0x6d, 0x73, 0xb2, 0x46, 0x69, 0xae, 0x61,
- 0x9a, 0x62, 0x0c, 0x9d, 0xa0, 0xf8, 0x19, 0xff, 0x08, 0x87, 0x2c, 0x58,
- 0xce, 0xe7, 0x70, 0xac, 0x08, 0x60, 0xad, 0x82, 0xd4, 0x32, 0x9e, 0x11,
- 0x28, 0x06, 0x86, 0xcd, 0x4e, 0x43, 0x59, 0x44, 0xfb, 0x4c, 0x1b, 0x25,
- 0xbf, 0xf3, 0x7b, 0xf1, 0x9c, 0x5b, 0x9a, 0x38, 0xce, 0x5b, 0xe7, 0xfc,
- 0xf1, 0x0b, 0xbd, 0x38, 0xc3, 0x46, 0xa9, 0xe7, 0x81, 0xf6, 0x19, 0x4f,
- 0xc5, 0x1a, 0xc6, 0x49, 0xcd, 0xe3, 0xcc, 0xc7, 0xe8, 0xbf, 0x10, 0xee,
- 0x9f, 0x64, 0xaa, 0x8d, 0xfb, 0x75, 0x54, 0x5c, 0x37, 0xc4, 0xb8, 0x45,
- 0x7b, 0x7f, 0xd8, 0x4c, 0xf8, 0xed, 0xe7, 0xe2, 0xbf, 0xfc, 0x09, 0xfc,
- 0xcf, 0xf4, 0x77, 0x82, 0x2e, 0xb1, 0xc3, 0xa3, 0x0b, 0xbf, 0xa5, 0x5c,
- 0x56, 0x4e, 0x79, 0xfd, 0x10, 0xf5, 0xf9, 0x83, 0x23, 0x5d, 0x62, 0x3b,
- 0x99, 0xe7, 0xc0, 0xd8, 0x2a, 0x71, 0xb7, 0x67, 0xf1, 0x2c, 0x39, 0xd7,
- 0xf3, 0x8b, 0xdf, 0xf7, 0xb6, 0x7d, 0xea, 0xbb, 0x5d, 0xa4, 0x47, 0x77,
- 0xd0, 0x5d, 0x3f, 0x78, 0x97, 0x6c, 0xb0, 0xb8, 0x9e, 0x59, 0x53, 0x17,
- 0x87, 0x22, 0x9d, 0xb1, 0xe5, 0x21, 0x44, 0x2d, 0x74, 0xc7, 0x68, 0xd6,
- 0x7a, 0xb1, 0xd0, 0xe3, 0x0c, 0x18, 0xb9, 0x81, 0xda, 0x62, 0x0c, 0x48,
- 0x49, 0x75, 0x5f, 0xad, 0x74, 0xd0, 0x53, 0xe2, 0x94, 0x68, 0x97, 0x74,
- 0x44, 0x90, 0xeb, 0xe8, 0xaa, 0x3f, 0x9e, 0xbb, 0xac, 0xfe, 0xb9, 0x5c,
- 0x5d, 0x0f, 0xdd, 0x7d, 0xeb, 0x7f, 0xe6, 0x01, 0x67, 0x48, 0x86, 0xb0,
- 0x73, 0xa5, 0xbb, 0x2f, 0x0d, 0xa5, 0xb7, 0xc3, 0x32, 0x16, 0x8b, 0x75,
- 0xeb, 0x48, 0x87, 0xfa, 0x63, 0xb9, 0x3b, 0xd7, 0x85, 0x26, 0xa9, 0xdb,
- 0xe9, 0xb8, 0xf3, 0xed, 0xf4, 0x9d, 0xd8, 0xe2, 0xf5, 0x61, 0x93, 0x17,
- 0x2f, 0xd4, 0xa8, 0x5d, 0x2c, 0x93, 0xcf, 0xdf, 0xec, 0x58, 0xd6, 0x08,
- 0xb6, 0xe6, 0x55, 0xbc, 0x55, 0xd8, 0x33, 0x13, 0xab, 0xf1, 0x31, 0xee,
- 0x67, 0xf1, 0x3e, 0xf9, 0x2d, 0x91, 0x63, 0x06, 0x99, 0xd0, 0xa0, 0x94,
- 0x4a, 0x9a, 0xef, 0x7f, 0xd3, 0x34, 0x0b, 0x73, 0x8d, 0x79, 0x0f, 0xfb,
- 0xad, 0x05, 0xfc, 0x2d, 0x91, 0x21, 0x53, 0x3a, 0xc8, 0x7b, 0xa7, 0xe7,
- 0xf6, 0xde, 0xa1, 0x3d, 0x88, 0x53, 0xd4, 0xab, 0xa8, 0x8e, 0x17, 0xf6,
- 0xcb, 0x07, 0x23, 0xf8, 0x7b, 0x9f, 0x71, 0x4e, 0xce, 0xe1, 0xfc, 0x8a,
- 0x70, 0xe2, 0x58, 0x53, 0x05, 0xb7, 0x92, 0x73, 0x6b, 0x78, 0xfe, 0x5b,
- 0x23, 0xe5, 0x89, 0xfd, 0x61, 0xb4, 0xf8, 0xad, 0x31, 0x2a, 0xb4, 0xfb,
- 0xe8, 0x39, 0xca, 0x71, 0xc8, 0xb1, 0xca, 0xf4, 0xc7, 0x53, 0x45, 0xfa,
- 0x63, 0x29, 0xa6, 0xff, 0x2c, 0x8d, 0x9a, 0x89, 0x0c, 0xc6, 0xa9, 0xfe,
- 0xbe, 0x4b, 0xb5, 0xa0, 0xc8, 0xbb, 0x48, 0xf7, 0x4f, 0x73, 0x74, 0x87,
- 0x89, 0xee, 0x0f, 0x14, 0x87, 0x4c, 0xcb, 0x7a, 0x72, 0x6e, 0xcc, 0xfb,
- 0xaf, 0x45, 0x1c, 0xf2, 0x0c, 0x1c, 0xca, 0xa9, 0x62, 0x1f, 0xd5, 0xda,
- 0x31, 0xba, 0xb7, 0x0c, 0x14, 0xbe, 0xa5, 0xea, 0x64, 0x93, 0x17, 0xaa,
- 0x8a, 0xfe, 0xe2, 0xef, 0xcb, 0x53, 0x58, 0xe1, 0x25, 0xa9, 0xf7, 0x6b,
- 0x05, 0x9d, 0x4a, 0x9d, 0xa7, 0xf1, 0x5b, 0xaa, 0x97, 0xa7, 0x0a, 0xdf,
- 0x6f, 0x9e, 0x46, 0x32, 0xc7, 0x73, 0x8f, 0x25, 0x36, 0x79, 0x46, 0x8f,
- 0x42, 0xbc, 0x57, 0xe5, 0x8a, 0x35, 0x84, 0xfa, 0x5b, 0x86, 0x6a, 0xb3,
- 0x78, 0xa6, 0xf0, 0x5e, 0x43, 0x3d, 0x8f, 0x65, 0xc8, 0x88, 0x44, 0xd2,
- 0x45, 0x43, 0xd2, 0x95, 0xaa, 0x65, 0x1d, 0x53, 0x43, 0x96, 0xfe, 0x4e,
- 0x28, 0x73, 0x8b, 0x82, 0xbb, 0xf0, 0x7e, 0x7b, 0xe6, 0x6f, 0xea, 0xe9,
- 0x6f, 0x65, 0x3b, 0x8c, 0x0a, 0xca, 0xf3, 0x1b, 0x3a, 0x9a, 0x32, 0x2f,
- 0x89, 0xa6, 0xee, 0xac, 0x68, 0x72, 0xd7, 0x88, 0xa6, 0xce, 0x32, 0x61,
- 0x6b, 0xcf, 0x51, 0x13, 0x7f, 0x39, 0x37, 0x6f, 0x07, 0xf6, 0x1f, 0xdb,
- 0x80, 0xc2, 0xdc, 0xb1, 0x32, 0x8b, 0x45, 0x8c, 0xee, 0xfe, 0x9c, 0x0f,
- 0x0d, 0xa0, 0x5e, 0x74, 0x36, 0xd7, 0xd1, 0xba, 0x7e, 0x97, 0x28, 0xa3,
- 0x7a, 0xa0, 0x63, 0x2f, 0xcd, 0x27, 0x0d, 0x16, 0xc7, 0x27, 0x35, 0xc8,
- 0x05, 0x2c, 0xcf, 0xcf, 0x23, 0x45, 0xfd, 0xd6, 0x55, 0x17, 0xf3, 0x4f,
- 0x50, 0x9d, 0x83, 0x16, 0xa3, 0x58, 0x7d, 0x9f, 0xea, 0xda, 0xef, 0x9a,
- 0x8a, 0x71, 0xbb, 0x94, 0xbf, 0x03, 0x17, 0xf0, 0x8e, 0x4b, 0xba, 0x5b,
- 0x91, 0x4e, 0xe7, 0x31, 0x3e, 0xe9, 0x3b, 0x55, 0xfd, 0x69, 0xfa, 0xa2,
- 0x6d, 0x15, 0x9a, 0x01, 0x8e, 0xe4, 0x33, 0x62, 0xb5, 0x87, 0x2d, 0xa1,
- 0x82, 0xfe, 0x06, 0x56, 0xe7, 0xba, 0xc4, 0x2a, 0xcf, 0x32, 0x06, 0xc8,
- 0x06, 0xdb, 0xf4, 0x56, 0x7d, 0x8c, 0xea, 0x16, 0xf1, 0x32, 0x4a, 0x29,
- 0x07, 0x34, 0x67, 0x01, 0xee, 0x99, 0x8b, 0x29, 0xca, 0x0b, 0xb7, 0xcc,
- 0xe9, 0x13, 0x8b, 0x27, 0xf8, 0x95, 0xf8, 0x7c, 0xa4, 0xdf, 0x87, 0x72,
- 0xfb, 0x55, 0xbc, 0xdf, 0x3f, 0xe7, 0x93, 0x9b, 0xf9, 0x4c, 0x7a, 0x3f,
- 0x35, 0x27, 0xc3, 0xff, 0x44, 0x3b, 0x71, 0xfe, 0xa7, 0x69, 0x78, 0xae,
- 0xe3, 0x3b, 0x05, 0xdc, 0x6a, 0x87, 0x67, 0xba, 0x85, 0x73, 0xb1, 0x30,
- 0x4c, 0xbc, 0xb7, 0xe0, 0xca, 0x65, 0x40, 0xf3, 0xe0, 0x42, 0x6c, 0xcf,
- 0x03, 0x2d, 0x83, 0x3c, 0x63, 0xcf, 0xc2, 0xcb, 0x42, 0x2b, 0x73, 0x66,
- 0x70, 0x61, 0xb6, 0xb1, 0xb7, 0x54, 0x98, 0x2d, 0x59, 0x61, 0x76, 0x03,
- 0xad, 0x34, 0x7d, 0x98, 0x89, 0xc5, 0xc2, 0x34, 0x36, 0x83, 0x6d, 0x35,
- 0x8b, 0xa6, 0x42, 0xae, 0xcf, 0xc0, 0x22, 0x7f, 0x77, 0x0f, 0x86, 0xa0,
- 0xb4, 0xfd, 0x8e, 0x6c, 0x66, 0x76, 0x42, 0x2c, 0xa4, 0xf9, 0x96, 0x63,
- 0x72, 0x16, 0x5b, 0xa9, 0x4f, 0xd7, 0x13, 0xce, 0xe7, 0xa9, 0x07, 0x34,
- 0x0e, 0x9a, 0x33, 0x80, 0xd9, 0x77, 0x71, 0xa8, 0xb1, 0xa5, 0x17, 0xe6,
- 0x96, 0x6d, 0x68, 0x9d, 0x7a, 0x46, 0x98, 0x99, 0x19, 0x21, 0x50, 0xda,
- 0x56, 0xe4, 0xb9, 0x74, 0x8e, 0x67, 0x0b, 0xdf, 0x37, 0x0a, 0xb9, 0x45,
- 0x77, 0x92, 0xb6, 0x5f, 0xc8, 0xa9, 0x82, 0xcd, 0xfe, 0x7a, 0x4e, 0xff,
- 0xec, 0x9c, 0x0f, 0xd4, 0xb9, 0xf7, 0x9f, 0x54, 0x73, 0x7d, 0x2f, 0x69,
- 0x2b, 0xcc, 0xe3, 0x14, 0x97, 0x5f, 0x44, 0x3f, 0xcd, 0x7e, 0x99, 0x02,
- 0x7d, 0x17, 0x7a, 0x72, 0x10, 0x9b, 0xbd, 0xa9, 0xd2, 0x67, 0x68, 0xaa,
- 0x1e, 0x29, 0xf0, 0xb9, 0x8c, 0xd6, 0xba, 0xe9, 0xc7, 0x36, 0xfb, 0xaf,
- 0x4a, 0xbe, 0x3d, 0x38, 0xaa, 0xfb, 0x4a, 0xf3, 0xbb, 0xfd, 0x90, 0x5a,
- 0xef, 0xab, 0x27, 0x2d, 0x03, 0x56, 0x37, 0x7d, 0x5b, 0x6a, 0x5b, 0xb2,
- 0xb9, 0x0d, 0xcd, 0x22, 0x7b, 0xb5, 0x4b, 0x1b, 0x84, 0x2c, 0x82, 0xb1,
- 0x65, 0x1b, 0xc7, 0xb8, 0xd6, 0xb5, 0x56, 0xb0, 0x31, 0x18, 0x3b, 0x89,
- 0xec, 0xe1, 0x0f, 0x25, 0x9e, 0x1d, 0xf5, 0x48, 0x20, 0x04, 0xf4, 0x4b,
- 0x12, 0x2c, 0xb0, 0x55, 0x53, 0x6e, 0xf4, 0x00, 0xe2, 0xb4, 0x24, 0xbc,
- 0x99, 0xd4, 0x2a, 0xa9, 0x9a, 0xb1, 0x62, 0xc4, 0x2b, 0x36, 0xc6, 0x9e,
- 0xc9, 0x6c, 0x91, 0x2d, 0xbb, 0xcc, 0x40, 0x00, 0x27, 0x7e, 0xe1, 0xcc,
- 0x4c, 0x2c, 0xc6, 0x89, 0xef, 0x7e, 0xe7, 0xde, 0x6e, 0x10, 0x84, 0xc4,
- 0x35, 0x54, 0xa9, 0xda, 0xdd, 0xf7, 0xf7, 0x3c, 0xbf, 0x73, 0xbe, 0xf3,
- 0x9d, 0x73, 0x7e, 0xd7, 0x92, 0xcb, 0x58, 0xcb, 0xff, 0x0e, 0x9b, 0xed,
- 0x36, 0x45, 0xd1, 0x98, 0x1b, 0xbc, 0x6a, 0x9c, 0x53, 0x2d, 0x1d, 0xb1,
- 0x99, 0x1c, 0xbd, 0x59, 0x9e, 0x25, 0x25, 0x77, 0xb3, 0x3e, 0xe4, 0xf7,
- 0x74, 0x9b, 0xbc, 0xdf, 0x83, 0x67, 0xd2, 0x1e, 0x6c, 0x20, 0xb6, 0xa6,
- 0x4c, 0x6c, 0xbd, 0x1e, 0x1f, 0xd9, 0xd8, 0x6e, 0x05, 0xdb, 0xf5, 0x64,
- 0xb8, 0x53, 0x73, 0xfa, 0xac, 0xa9, 0x2b, 0x8e, 0x26, 0x39, 0x07, 0x91,
- 0xbd, 0xc4, 0x76, 0xd9, 0xd8, 0x57, 0xce, 0x24, 0xac, 0x0c, 0x46, 0x5b,
- 0x95, 0xfe, 0x68, 0x31, 0xe7, 0x8b, 0x28, 0xc9, 0x90, 0x6d, 0x77, 0x29,
- 0xe3, 0xa9, 0x15, 0x8b, 0x56, 0x12, 0x7f, 0xb4, 0x80, 0x66, 0x2b, 0xc1,
- 0xb3, 0x81, 0x39, 0x98, 0x52, 0x97, 0x62, 0x73, 0x20, 0x87, 0x5c, 0x69,
- 0x3f, 0x36, 0xaa, 0xb9, 0xd8, 0x14, 0xf8, 0x0b, 0xe0, 0xe1, 0x3c, 0xea,
- 0xb1, 0xc5, 0x39, 0x73, 0x38, 0x6f, 0x1e, 0x31, 0xe3, 0x39, 0x73, 0xdf,
- 0xe3, 0xb2, 0x57, 0xae, 0xb3, 0x59, 0x49, 0x12, 0xf3, 0x2b, 0x4c, 0xdb,
- 0x9d, 0xf9, 0x7e, 0x28, 0x65, 0xe6, 0x60, 0x5f, 0x5e, 0x6c, 0xca, 0xf9,
- 0xf7, 0xdf, 0xd7, 0xd3, 0xab, 0xcb, 0xc9, 0xd3, 0xa9, 0x3f, 0xcb, 0x11,
- 0xae, 0x5c, 0x82, 0xe7, 0x03, 0x8d, 0x28, 0xd2, 0x9a, 0xf1, 0x6d, 0x35,
- 0x42, 0x4c, 0x1f, 0xc2, 0x77, 0xcc, 0x31, 0x64, 0x3c, 0xb3, 0x66, 0xc4,
- 0x7f, 0xbf, 0xb3, 0x43, 0xfb, 0xba, 0xf8, 0xd2, 0xca, 0xc9, 0xb4, 0xdb,
- 0x9c, 0xe8, 0x19, 0x90, 0x4f, 0x07, 0xbe, 0x13, 0xb2, 0x72, 0xb0, 0xf1,
- 0x21, 0x27, 0x62, 0x03, 0x0e, 0xa4, 0x83, 0x64, 0x3f, 0x95, 0x37, 0x8f,
- 0x3d, 0xc4, 0xb1, 0xad, 0xbc, 0xc5, 0x77, 0x29, 0xd7, 0x73, 0x4e, 0x27,
- 0xb9, 0x10, 0xd4, 0x0a, 0xb6, 0x29, 0x1f, 0x2f, 0x80, 0x7b, 0x48, 0xea,
- 0x4e, 0x93, 0xca, 0x96, 0xb4, 0xd5, 0xe6, 0x7b, 0x52, 0xab, 0xca, 0xb5,
- 0x81, 0xbe, 0x88, 0xdb, 0x75, 0xb0, 0x8d, 0x8b, 0x71, 0x71, 0x3e, 0x6a,
- 0x86, 0x0a, 0xf8, 0xa7, 0xa2, 0xf4, 0x20, 0x1f, 0x8c, 0x37, 0x2b, 0x2f,
- 0x46, 0x03, 0x28, 0x65, 0xbc, 0x5e, 0xd6, 0x64, 0xf5, 0x7f, 0x29, 0xfd,
- 0x75, 0xeb, 0x77, 0xa2, 0xbd, 0x54, 0xce, 0xab, 0x06, 0x85, 0xda, 0x94,
- 0xf1, 0x82, 0x85, 0xf1, 0xa6, 0x2f, 0xed, 0xbe, 0x56, 0xe7, 0x92, 0x35,
- 0x29, 0xc2, 0x5b, 0xd5, 0xf2, 0x26, 0x89, 0x9b, 0xf9, 0xa3, 0x19, 0x77,
- 0xcb, 0x1a, 0x64, 0xec, 0x7c, 0xe4, 0x0e, 0xc9, 0xd8, 0x05, 0xc8, 0xb9,
- 0xb6, 0x16, 0x99, 0x87, 0x61, 0xde, 0xb8, 0xf8, 0x57, 0x99, 0x6f, 0x52,
- 0x19, 0x4c, 0xcb, 0x1a, 0xb2, 0xf3, 0x9e, 0x32, 0x9e, 0x51, 0x0b, 0xe8,
- 0xcf, 0x87, 0x8d, 0x0d, 0x15, 0x86, 0xe1, 0x5f, 0x74, 0xdc, 0x48, 0xad,
- 0x35, 0xb1, 0xd6, 0xd8, 0x9d, 0x70, 0x62, 0x17, 0xe5, 0xb6, 0x39, 0x78,
- 0x58, 0x78, 0x5c, 0xe6, 0x5f, 0x56, 0x6e, 0x47, 0x28, 0xb7, 0xb9, 0x99,
- 0x73, 0x9c, 0x54, 0x8e, 0x5e, 0xf3, 0xf7, 0xb2, 0x46, 0x59, 0x97, 0x82,
- 0x72, 0x4d, 0xd6, 0x65, 0x43, 0x99, 0x96, 0x8f, 0x72, 0xca, 0xa7, 0xcc,
- 0x5c, 0x53, 0xb3, 0xf2, 0x6e, 0x14, 0x6a, 0x09, 0xb9, 0x43, 0xe9, 0xb8,
- 0xb5, 0xae, 0x29, 0xca, 0xe7, 0xcc, 0x35, 0x9d, 0x98, 0x2d, 0x67, 0xa1,
- 0x57, 0x62, 0xd3, 0x33, 0xdf, 0xdf, 0x9a, 0x94, 0x71, 0xed, 0x74, 0x9c,
- 0x0a, 0xb6, 0x87, 0xc4, 0x5f, 0xe0, 0xe5, 0xe5, 0x51, 0x4b, 0x06, 0x36,
- 0xf3, 0x0c, 0xc4, 0x06, 0x64, 0xff, 0xd9, 0xbd, 0x37, 0x2b, 0x4f, 0x45,
- 0xa5, 0xbf, 0x86, 0x1a, 0xb3, 0x9f, 0x15, 0x37, 0xdb, 0xa8, 0x7f, 0xcb,
- 0x79, 0x36, 0xb6, 0x71, 0x4b, 0x37, 0x3d, 0xa9, 0x56, 0xce, 0x2b, 0xe7,
- 0x34, 0xa9, 0x74, 0x72, 0x4e, 0x98, 0x67, 0xfb, 0x5f, 0xcb, 0x2d, 0x5b,
- 0x9f, 0xa4, 0x6d, 0xf2, 0x37, 0xa7, 0x8d, 0xfa, 0x5e, 0x00, 0xc7, 0x90,
- 0xcb, 0xcc, 0xf1, 0xc8, 0xd8, 0xcf, 0x45, 0xcb, 0x90, 0x77, 0x30, 0xdb,
- 0xd7, 0xf2, 0xed, 0x56, 0x8d, 0x30, 0x6b, 0x8f, 0x82, 0x8f, 0xe2, 0x27,
- 0x22, 0x4a, 0xf8, 0x5a, 0x9d, 0x4f, 0x72, 0x5f, 0x52, 0xff, 0xcc, 0xe5,
- 0x7a, 0x24, 0x7f, 0xaa, 0x10, 0x33, 0x6c, 0xc4, 0xe9, 0xe5, 0x1e, 0x07,
- 0x71, 0x6e, 0x03, 0xbe, 0x34, 0x22, 0x15, 0xe1, 0x80, 0x13, 0x56, 0x8c,
- 0xde, 0x8e, 0x5c, 0x58, 0x18, 0x44, 0x2d, 0x8d, 0xd2, 0x1f, 0x73, 0xaf,
- 0xe4, 0x00, 0xe8, 0x4e, 0x7f, 0x69, 0x4c, 0x55, 0x38, 0xe8, 0xf3, 0xaf,
- 0xe5, 0xd6, 0x68, 0x77, 0x86, 0x31, 0xcc, 0x67, 0xbd, 0xe9, 0xec, 0x39,
- 0x91, 0x5b, 0x90, 0x6b, 0x3e, 0xad, 0xfd, 0xbb, 0xb1, 0xfe, 0x86, 0xb6,
- 0x59, 0x6c, 0xb6, 0x62, 0xed, 0x23, 0x26, 0x36, 0x17, 0xa2, 0x77, 0xb7,
- 0x37, 0x99, 0x02, 0x79, 0x8b, 0x66, 0x9b, 0x2b, 0x31, 0x82, 0x1d, 0xde,
- 0xbe, 0x66, 0xc6, 0xfa, 0xc4, 0x4e, 0x4f, 0x0a, 0xff, 0x5c, 0x2e, 0x76,
- 0xc4, 0x78, 0xcd, 0x53, 0x6a, 0x2b, 0x93, 0xb5, 0x9b, 0xab, 0xb2, 0x0f,
- 0xe4, 0x61, 0x43, 0x43, 0x1e, 0x52, 0x6d, 0xc4, 0xac, 0x81, 0x48, 0x2b,
- 0x87, 0x77, 0xe5, 0x37, 0xbd, 0xf5, 0xbd, 0x6f, 0xf8, 0xbd, 0xf4, 0x93,
- 0x40, 0x6e, 0x8c, 0x73, 0x22, 0x83, 0x69, 0x03, 0xde, 0x88, 0xcd, 0x26,
- 0xfd, 0x7f, 0x6b, 0x90, 0x63, 0xb3, 0xaf, 0x8c, 0xc1, 0xb9, 0xff, 0xc8,
- 0x16, 0x24, 0xee, 0xfb, 0xb2, 0x5c, 0xf2, 0x8e, 0x6a, 0xad, 0x82, 0xc2,
- 0x81, 0x42, 0x14, 0x30, 0x4e, 0xdf, 0x55, 0xe9, 0xeb, 0xd0, 0x6d, 0xf9,
- 0x38, 0x7d, 0xd7, 0x7f, 0x41, 0xaa, 0x32, 0x07, 0xae, 0x5a, 0x60, 0x45,
- 0xdc, 0x06, 0x5b, 0x2d, 0xb1, 0x37, 0x04, 0x34, 0x8f, 0xf3, 0xdc, 0x06,
- 0x14, 0x3c, 0x91, 0xb4, 0xe1, 0xc1, 0xa4, 0x1d, 0xab, 0x93, 0xf8, 0xab,
- 0x1a, 0x60, 0xba, 0x1a, 0xfe, 0xf6, 0x19, 0x05, 0x9b, 0x8b, 0x61, 0xfa,
- 0xf8, 0xd6, 0xd5, 0x8c, 0x4b, 0x57, 0x8d, 0x13, 0xcf, 0xd8, 0xd6, 0xc9,
- 0x98, 0xcd, 0xd1, 0x6f, 0x47, 0x75, 0x3f, 0x6e, 0xcf, 0x05, 0x42, 0x4e,
- 0xf8, 0x67, 0xe8, 0x67, 0xca, 0x1c, 0xf0, 0x4f, 0x9d, 0xb7, 0xfb, 0x3b,
- 0xab, 0xed, 0x3c, 0xdc, 0x5a, 0x59, 0x8b, 0x0b, 0x0f, 0x51, 0x9f, 0x6b,
- 0x06, 0xd8, 0xbe, 0xd6, 0x06, 0x55, 0x53, 0x70, 0xe5, 0x71, 0xc9, 0xfb,
- 0xca, 0x33, 0xc9, 0x55, 0x28, 0x28, 0x1e, 0xb0, 0x13, 0xc3, 0xde, 0x34,
- 0x4e, 0x57, 0x0a, 0x7e, 0x03, 0x4f, 0x70, 0x6d, 0x6e, 0xfe, 0xa6, 0xd6,
- 0xba, 0xb0, 0x70, 0xa9, 0x8a, 0x75, 0x43, 0x5f, 0x9a, 0x3a, 0x25, 0xe3,
- 0x38, 0x69, 0x53, 0x39, 0xb4, 0xf1, 0x83, 0x66, 0x0d, 0xd1, 0xc6, 0x3d,
- 0xda, 0x51, 0x30, 0x00, 0xac, 0x8a, 0xe3, 0x91, 0x42, 0xf8, 0xc3, 0xb2,
- 0xc6, 0xba, 0x25, 0x0e, 0xf6, 0x2d, 0x44, 0xeb, 0xb8, 0xd5, 0xef, 0xfe,
- 0xf1, 0x92, 0x0a, 0x2b, 0x07, 0xfe, 0xa7, 0x6b, 0xda, 0x3d, 0x21, 0x3f,
- 0x36, 0x24, 0xa9, 0x73, 0x36, 0x0f, 0x86, 0x32, 0xb9, 0xe8, 0xf5, 0x29,
- 0xef, 0xac, 0x9a, 0xf3, 0xdf, 0x14, 0x66, 0xea, 0xd1, 0xb4, 0x85, 0x19,
- 0x8e, 0x13, 0x51, 0xd6, 0x53, 0x76, 0x43, 0x13, 0x06, 0xa2, 0xba, 0x81,
- 0x31, 0xfe, 0xbd, 0xad, 0x4b, 0xde, 0x63, 0x52, 0x79, 0x26, 0xf6, 0x95,
- 0x11, 0xc9, 0xd8, 0xf3, 0x0f, 0x12, 0x01, 0x65, 0x53, 0x0c, 0x78, 0x95,
- 0xfe, 0xf4, 0x10, 0xff, 0x46, 0x12, 0x92, 0x47, 0xa2, 0xec, 0x69, 0xd7,
- 0xdb, 0x52, 0xc0, 0x70, 0x02, 0xe1, 0xfd, 0x4b, 0x84, 0xc3, 0x17, 0x70,
- 0x3e, 0x5a, 0x0d, 0xdb, 0xa4, 0xf9, 0x77, 0x90, 0x7f, 0x13, 0x3c, 0x53,
- 0xce, 0x87, 0xc0, 0x98, 0x03, 0xe1, 0x31, 0x02, 0xed, 0x58, 0x00, 0x53,
- 0xf4, 0x81, 0x57, 0x47, 0x54, 0x14, 0x1d, 0x2a, 0xc3, 0xa7, 0xa3, 0xc4,
- 0xc7, 0x03, 0x16, 0xef, 0xdf, 0x30, 0x26, 0xf5, 0x42, 0xd9, 0x9f, 0xd4,
- 0xd7, 0xc5, 0x9e, 0xf2, 0x70, 0x28, 0x59, 0x66, 0xd6, 0xd8, 0x2f, 0xe8,
- 0x1c, 0x5b, 0x95, 0xda, 0x68, 0x1b, 0x0e, 0x47, 0x7d, 0x9e, 0x3e, 0xea,
- 0x7c, 0xc4, 0x21, 0x36, 0x16, 0xc2, 0xab, 0xd1, 0x6c, 0x8d, 0xcd, 0xc7,
- 0x78, 0xd7, 0x09, 0x8f, 0xb3, 0x8c, 0xf2, 0x95, 0x67, 0x59, 0x5f, 0x2a,
- 0x7b, 0x96, 0x7c, 0x7e, 0x96, 0xb7, 0xcc, 0xfe, 0xfd, 0xa4, 0x21, 0xb5,
- 0xdf, 0xd7, 0x26, 0xbc, 0x7d, 0x29, 0xe8, 0xa6, 0xaf, 0x1c, 0xad, 0xf3,
- 0x26, 0x23, 0x90, 0xf3, 0x0d, 0x71, 0x0d, 0x1f, 0x53, 0xf7, 0x03, 0x94,
- 0xf5, 0x5f, 0xd3, 0xb7, 0x4b, 0x9e, 0xbc, 0x14, 0xbb, 0xfa, 0xcb, 0xb0,
- 0xb3, 0x3f, 0x82, 0xde, 0x25, 0x6b, 0x71, 0x32, 0x6a, 0x60, 0x43, 0xd0,
- 0xc0, 0xaa, 0xa0, 0x37, 0xf0, 0x03, 0xd4, 0x37, 0x1e, 0xc6, 0x43, 0xe4,
- 0x10, 0x2a, 0x65, 0xf2, 0x24, 0x3e, 0xd8, 0xed, 0xc0, 0xb3, 0xfa, 0x37,
- 0x69, 0xc3, 0x86, 0xf1, 0xab, 0xc5, 0xf3, 0x30, 0x94, 0xa8, 0x57, 0xbb,
- 0xb9, 0xbe, 0xf0, 0x5a, 0x9e, 0x55, 0x83, 0x03, 0x1b, 0xf5, 0xbf, 0x62,
- 0x5b, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b, 0xfd, 0xa9, 0x9c, 0x65, 0x84,
- 0xfa, 0x65, 0xf9, 0xb2, 0x70, 0xa6, 0x3e, 0xf1, 0x6c, 0x48, 0x30, 0xbf,
- 0x10, 0x27, 0x28, 0xb7, 0x37, 0x92, 0x61, 0x49, 0x45, 0x29, 0x1b, 0x43,
- 0x5d, 0x78, 0x8a, 0x7c, 0xe3, 0x03, 0x12, 0x81, 0x7b, 0xe2, 0x0a, 0x1a,
- 0xeb, 0x74, 0x9c, 0x4d, 0x3f, 0x89, 0x77, 0x46, 0x9a, 0xf0, 0x36, 0x7d,
- 0xfa, 0xc2, 0xff, 0xe9, 0x65, 0x2c, 0xef, 0xc1, 0xe9, 0x74, 0x13, 0xde,
- 0x8c, 0x7a, 0xdb, 0x5e, 0x20, 0x3f, 0xfa, 0x79, 0xda, 0x81, 0x3b, 0xe2,
- 0x8c, 0x7b, 0x38, 0x8e, 0x3f, 0xee, 0xc0, 0xc5, 0xb4, 0x8a, 0xc3, 0x3c,
- 0x1f, 0x47, 0x70, 0x21, 0xe3, 0x5e, 0x0f, 0x0e, 0x0e, 0x3e, 0x88, 0xa9,
- 0xd4, 0x83, 0x38, 0x96, 0xfc, 0xc0, 0x70, 0x69, 0x52, 0x27, 0x73, 0xe1,
- 0x22, 0x63, 0xb2, 0x69, 0x4a, 0xa3, 0x70, 0x69, 0x1b, 0xfd, 0xbc, 0x16,
- 0x11, 0xb9, 0xbf, 0xc3, 0xdf, 0xee, 0x89, 0x37, 0x62, 0xff, 0x18, 0x45,
- 0x9a, 0xd0, 0x91, 0x88, 0xc9, 0x5c, 0x21, 0xc4, 0xc8, 0x0b, 0x77, 0xf5,
- 0x1b, 0xf4, 0x17, 0x77, 0x48, 0x0c, 0xa2, 0xb4, 0xd6, 0xfe, 0x73, 0x66,
- 0x1f, 0x8d, 0xb3, 0x6a, 0xa0, 0xf9, 0x3c, 0x1b, 0xca, 0x95, 0xfd, 0xfe,
- 0x77, 0xa2, 0xc1, 0xf4, 0x4d, 0x47, 0xae, 0x9d, 0x47, 0x23, 0xcf, 0xe3,
- 0x49, 0x9c, 0xdd, 0xbd, 0x16, 0xef, 0x10, 0xef, 0x8a, 0x17, 0xfb, 0x3a,
- 0x9d, 0xb6, 0x7a, 0x8e, 0x9d, 0x36, 0x52, 0x95, 0x22, 0xd3, 0xb5, 0xf8,
- 0x65, 0x54, 0x64, 0x9a, 0x26, 0xfe, 0xf9, 0x3c, 0x7e, 0xfb, 0x5b, 0xb4,
- 0x09, 0xb7, 0xad, 0xbb, 0xc1, 0xaa, 0xe9, 0x15, 0x2e, 0x75, 0xe1, 0x92,
- 0xb9, 0x36, 0x59, 0xeb, 0x9f, 0x5b, 0xdf, 0x2f, 0x8d, 0x55, 0x95, 0xb2,
- 0xbe, 0x88, 0x91, 0xa3, 0x69, 0x81, 0x1c, 0x45, 0xfc, 0x6c, 0xc0, 0xac,
- 0x63, 0xd4, 0xc5, 0xbb, 0x60, 0x0f, 0x16, 0x32, 0x3e, 0xf3, 0xce, 0x74,
- 0xe0, 0x1d, 0x5c, 0x9e, 0x70, 0x61, 0x41, 0x3c, 0x80, 0x57, 0x26, 0x72,
- 0x2b, 0x91, 0xff, 0x0b, 0x9c, 0xe7, 0x77, 0x5f, 0xdc, 0xb2, 0xb7, 0xee,
- 0xd0, 0x5a, 0xac, 0x48, 0xcb, 0xfe, 0x9e, 0xe4, 0x44, 0x3a, 0xc2, 0x69,
- 0xd9, 0x67, 0x8c, 0xb6, 0x21, 0xfb, 0x2c, 0xfb, 0x9a, 0x7d, 0xbe, 0xcb,
- 0xb5, 0xcf, 0xa3, 0x2d, 0x65, 0x7d, 0x47, 0x11, 0x0e, 0x26, 0x55, 0x9c,
- 0xd0, 0x8b, 0x70, 0x4e, 0x95, 0x7c, 0xbd, 0x8b, 0x3e, 0xc4, 0x81, 0x66,
- 0xc6, 0x4b, 0xc3, 0xd1, 0x3c, 0x3c, 0xa3, 0x3a, 0x70, 0x4a, 0x77, 0xe0,
- 0x98, 0x7e, 0x1b, 0xb1, 0x5e, 0xe2, 0x08, 0xd3, 0xbf, 0x90, 0x31, 0x65,
- 0xf5, 0x58, 0x9e, 0x17, 0xc2, 0x53, 0x5a, 0x86, 0x37, 0x25, 0xef, 0x68,
- 0xb6, 0x71, 0x49, 0xad, 0x17, 0x87, 0x28, 0xb3, 0x9c, 0x58, 0x39, 0x2e,
- 0xb5, 0x35, 0xde, 0xa2, 0x1f, 0x69, 0xac, 0xf6, 0xb1, 0xb1, 0xb9, 0xf2,
- 0xda, 0x98, 0x1e, 0x28, 0x47, 0x2a, 0x2c, 0x9c, 0xc8, 0xd6, 0xe1, 0xb2,
- 0xbe, 0x6c, 0x76, 0xbf, 0xd9, 0xfb, 0x7c, 0xa1, 0x52, 0xb0, 0xc9, 0x61,
- 0xc6, 0x82, 0x6d, 0xdf, 0xa4, 0x8f, 0xa2, 0xcf, 0x5e, 0xbb, 0x45, 0x62,
- 0x43, 0x5b, 0xd3, 0xba, 0x6f, 0x2e, 0xd7, 0x72, 0x60, 0x37, 0xb9, 0xa0,
- 0xe3, 0x65, 0x8b, 0xbf, 0xbb, 0x5e, 0xd6, 0xcc, 0xcf, 0xc2, 0x97, 0x17,
- 0x98, 0x9f, 0xea, 0xcb, 0xbe, 0xd4, 0x75, 0x5f, 0x66, 0xf1, 0x63, 0xf3,
- 0xae, 0x10, 0xfa, 0xf4, 0x88, 0x72, 0x7f, 0x48, 0x78, 0xe6, 0x6c, 0x8e,
- 0x11, 0x50, 0x4e, 0x45, 0x23, 0x46, 0xb5, 0x96, 0x1f, 0x29, 0x26, 0xf7,
- 0x6e, 0xf4, 0x6b, 0xc4, 0x6a, 0x89, 0xe9, 0x34, 0x9c, 0xe1, 0x79, 0x10,
- 0x62, 0xa9, 0xe3, 0xff, 0x0f, 0xd1, 0xdd, 0x68, 0xcf, 0x37, 0x71, 0xc9,
- 0x30, 0x76, 0x05, 0x25, 0x07, 0x21, 0xe3, 0x3a, 0xf0, 0x11, 0xcf, 0xf9,
- 0x37, 0x23, 0x05, 0xf8, 0x30, 0xa5, 0xe1, 0x5c, 0x7a, 0x2d, 0x76, 0x4c,
- 0x58, 0x1c, 0xe4, 0x58, 0xda, 0xe2, 0x44, 0x12, 0xd3, 0xef, 0x27, 0x47,
- 0x88, 0x25, 0x5e, 0x37, 0xf2, 0x34, 0xdf, 0x94, 0xdf, 0xee, 0xc0, 0xbe,
- 0xf4, 0x34, 0x26, 0xfa, 0x3f, 0x33, 0xec, 0x5a, 0x17, 0x3e, 0x0d, 0x4e,
- 0x63, 0xfc, 0x80, 0xd4, 0x50, 0x43, 0xd8, 0x35, 0x18, 0x40, 0x6f, 0xc2,
- 0x86, 0x9d, 0x4b, 0x5a, 0xb1, 0x6b, 0xa2, 0x05, 0x91, 0x43, 0x1e, 0xec,
- 0x4c, 0xa7, 0x31, 0x35, 0x32, 0x8d, 0x93, 0x49, 0x8d, 0xf1, 0xe4, 0x34,
- 0x4e, 0xa4, 0x38, 0x66, 0xe2, 0x3d, 0x44, 0x38, 0xc6, 0xb6, 0xa4, 0xa6,
- 0x0e, 0x9b, 0x7b, 0x9c, 0x46, 0x77, 0xea, 0x56, 0x39, 0x13, 0xae, 0x27,
- 0xd1, 0xd3, 0x6e, 0xd5, 0x45, 0x88, 0xbd, 0x69, 0x4d, 0xe9, 0xe3, 0xf9,
- 0x1d, 0x4e, 0x67, 0x6b, 0x24, 0x37, 0xe7, 0x4a, 0x42, 0xe8, 0x1b, 0x6c,
- 0x65, 0x9f, 0x00, 0xba, 0x13, 0x52, 0x87, 0xf6, 0x71, 0x4e, 0x03, 0xbf,
- 0xd6, 0xbd, 0xee, 0x05, 0xfc, 0x1c, 0xd5, 0x3b, 0xb1, 0x89, 0x63, 0x4d,
- 0x31, 0x46, 0xd2, 0x14, 0x6f, 0x63, 0x04, 0x76, 0xfc, 0x4a, 0x27, 0x1f,
- 0xaa, 0xb0, 0xe3, 0x55, 0xea, 0x5a, 0xb8, 0xd4, 0x8e, 0xfa, 0x20, 0x7d,
- 0x78, 0xc6, 0xa7, 0x7f, 0x92, 0x54, 0xf0, 0x20, 0xf1, 0xf6, 0x8d, 0x60,
- 0x7d, 0xfb, 0x4a, 0x61, 0x7b, 0x07, 0x14, 0x5c, 0xd6, 0xae, 0x1a, 0x11,
- 0xea, 0x87, 0xcb, 0x9f, 0x3d, 0xa3, 0x7f, 0xc9, 0xe4, 0xf0, 0xbe, 0x34,
- 0xb2, 0xfd, 0x66, 0xb8, 0xc6, 0x27, 0xd8, 0x6f, 0xc1, 0xe2, 0xfa, 0x4e,
- 0xe9, 0xe7, 0x26, 0xde, 0x4b, 0xbf, 0x73, 0x95, 0x8e, 0x59, 0xfd, 0x42,
- 0xd8, 0x36, 0xd8, 0x6c, 0xae, 0x77, 0x7b, 0x02, 0x8b, 0x1c, 0x10, 0x5b,
- 0xab, 0x57, 0x2f, 0x02, 0x5d, 0xd3, 0x7a, 0x09, 0x79, 0x90, 0x3f, 0xf0,
- 0x0c, 0x44, 0x56, 0x12, 0x67, 0xbe, 0x87, 0x9d, 0xd1, 0x11, 0x30, 0xd6,
- 0x24, 0x06, 0xfa, 0xd7, 0x0d, 0x23, 0x85, 0xe7, 0xd3, 0x29, 0xbc, 0x40,
- 0x19, 0x45, 0xcc, 0xbb, 0x62, 0x69, 0x7c, 0x3b, 0xfa, 0x1e, 0x62, 0xe6,
- 0x99, 0x1d, 0xc6, 0xfa, 0xa8, 0xbb, 0x0a, 0xf9, 0xd2, 0x77, 0x25, 0xc7,
- 0x17, 0xb9, 0x7a, 0xdb, 0x22, 0xf8, 0x8a, 0xe3, 0xaf, 0x44, 0xcf, 0xb0,
- 0x61, 0xfc, 0x90, 0xbe, 0xed, 0x2d, 0x72, 0xaf, 0xcb, 0x99, 0x7b, 0x67,
- 0x79, 0x94, 0xb7, 0x66, 0xfa, 0xb8, 0xb5, 0x3c, 0xe7, 0x2a, 0xe1, 0xfc,
- 0x28, 0x1a, 0xd3, 0x94, 0x05, 0x31, 0x39, 0x77, 0x72, 0xca, 0x31, 0x0f,
- 0x9e, 0x20, 0x7f, 0xc9, 0x1d, 0xfd, 0x5b, 0x45, 0xfc, 0x5c, 0xf5, 0x01,
- 0xc6, 0x02, 0x07, 0x3c, 0xca, 0xc2, 0x3d, 0x2e, 0x3c, 0x18, 0x73, 0xe0,
- 0xfe, 0x58, 0x0b, 0x7a, 0xf6, 0x6a, 0x6c, 0xe3, 0xd5, 0xcf, 0x30, 0x5e,
- 0x3d, 0x01, 0x9f, 0x67, 0x98, 0x9c, 0xcb, 0x4d, 0x9c, 0x76, 0x8c, 0x16,
- 0xa3, 0x60, 0x54, 0x85, 0x6d, 0xb4, 0x0c, 0x85, 0xa3, 0x6e, 0x54, 0xd3,
- 0xef, 0xb9, 0xc7, 0xce, 0x62, 0x62, 0x8f, 0xe4, 0x53, 0xbf, 0x30, 0x72,
- 0xc9, 0xcb, 0x3e, 0x0d, 0x06, 0x50, 0x3c, 0xb6, 0x05, 0xe9, 0x58, 0x03,
- 0x0a, 0xc7, 0x48, 0xb3, 0xc6, 0x26, 0x95, 0x7a, 0xce, 0xd9, 0x12, 0xd3,
- 0x38, 0x96, 0xc5, 0x83, 0x56, 0xd2, 0x57, 0xf6, 0x25, 0xbc, 0xeb, 0xa4,
- 0x2e, 0x79, 0x59, 0x3f, 0x8e, 0xbc, 0xfe, 0xec, 0xfd, 0x39, 0x78, 0xf3,
- 0x80, 0x92, 0x1e, 0xdd, 0xdf, 0xb6, 0x11, 0xd6, 0x5d, 0xba, 0xfb, 0x33,
- 0x7b, 0x6a, 0x90, 0x3d, 0x39, 0xd7, 0x52, 0x17, 0xe6, 0xa0, 0x84, 0x7b,
- 0x3a, 0x4f, 0xfd, 0xb9, 0x87, 0xeb, 0xbd, 0xca, 0xb8, 0xb1, 0x33, 0x26,
- 0x7a, 0xff, 0xb7, 0x0a, 0xed, 0x06, 0x33, 0xa9, 0x02, 0x7c, 0x96, 0xf2,
- 0x28, 0x3e, 0xee, 0xe7, 0x3b, 0x7c, 0xfe, 0x6d, 0xee, 0x67, 0xeb, 0x5e,
- 0x6f, 0xdb, 0x51, 0xc5, 0xdb, 0xbe, 0x46, 0xf1, 0xa9, 0x5b, 0x95, 0x42,
- 0x9c, 0x1f, 0x29, 0xc6, 0x45, 0xfa, 0xe9, 0xab, 0x23, 0x65, 0xb8, 0x34,
- 0x52, 0x41, 0x5b, 0xd1, 0x38, 0x86, 0x61, 0x14, 0x69, 0x6e, 0xcc, 0xa4,
- 0x5f, 0x40, 0x49, 0x6c, 0x1e, 0x3e, 0x4b, 0x6f, 0x42, 0x71, 0x4c, 0xf8,
- 0xbc, 0x07, 0x9f, 0xf2, 0xf9, 0x27, 0xe9, 0x71, 0xe4, 0xef, 0xf9, 0x82,
- 0x6d, 0x0c, 0xa3, 0x85, 0x7b, 0xbc, 0x94, 0xee, 0x40, 0xe1, 0x9e, 0x97,
- 0xe0, 0xd8, 0x63, 0x74, 0xf5, 0x04, 0xf1, 0x73, 0x3b, 0xf7, 0xd2, 0xad,
- 0x7b, 0xa7, 0x16, 0xd8, 0x1b, 0x38, 0x86, 0xce, 0x31, 0x27, 0x95, 0x85,
- 0x63, 0x2f, 0xa1, 0x78, 0x8f, 0x07, 0x9b, 0x29, 0xcb, 0x71, 0x68, 0x81,
- 0x35, 0xca, 0x4b, 0xc8, 0x19, 0xb5, 0x64, 0xb0, 0x61, 0xcc, 0xb2, 0x91,
- 0x96, 0x90, 0xe4, 0x94, 0x26, 0x95, 0x61, 0xd3, 0x46, 0xdc, 0x72, 0xd7,
- 0x07, 0xd3, 0xe9, 0x02, 0x9c, 0x4a, 0x89, 0x8c, 0xe4, 0xbe, 0xe0, 0x38,
- 0x72, 0xf7, 0x10, 0x3f, 0x47, 0x74, 0x93, 0x5f, 0x88, 0x6d, 0x8c, 0xa4,
- 0x6f, 0x65, 0x5f, 0x3a, 0x76, 0x26, 0xaa, 0x69, 0x5b, 0xf3, 0xb0, 0x6a,
- 0x8f, 0x61, 0x04, 0x82, 0x53, 0xf7, 0xb8, 0xa8, 0x4d, 0x87, 0xd2, 0xb7,
- 0xb2, 0xad, 0x46, 0xea, 0xa9, 0xb7, 0x35, 0x62, 0xe6, 0xbb, 0x0d, 0x4c,
- 0xeb, 0x93, 0x8a, 0x2d, 0x26, 0xb1, 0xd8, 0x5a, 0xda, 0x7c, 0x1b, 0x7a,
- 0x06, 0xd1, 0xbe, 0x3f, 0x24, 0xb5, 0x70, 0x27, 0x86, 0x19, 0x5b, 0x9d,
- 0x67, 0x3c, 0x42, 0x99, 0xab, 0x39, 0x4d, 0x39, 0x18, 0x1a, 0x71, 0xe1,
- 0x27, 0x23, 0x1e, 0x34, 0xc6, 0xbe, 0x20, 0x66, 0xe4, 0x63, 0x92, 0xf2,
- 0x9e, 0x20, 0x37, 0xfa, 0x34, 0xaa, 0x62, 0x9c, 0x7e, 0xf8, 0x93, 0x68,
- 0x05, 0xc6, 0x18, 0x87, 0x7d, 0x1c, 0xd5, 0x90, 0xe6, 0xd9, 0x7c, 0x44,
- 0xbc, 0xf9, 0x61, 0xba, 0x01, 0xbf, 0x89, 0x36, 0xe0, 0x55, 0xca, 0xb1,
- 0x2e, 0xe6, 0xe6, 0x9a, 0x8e, 0x28, 0x38, 0x30, 0xa9, 0xe4, 0x50, 0x2f,
- 0xfc, 0x31, 0xcd, 0x33, 0x9c, 0xd1, 0x0b, 0x6d, 0xac, 0x8d, 0x76, 0x24,
- 0x77, 0x2d, 0xc4, 0x77, 0x38, 0xf4, 0x61, 0x90, 0xef, 0x35, 0x64, 0x73,
- 0x8b, 0x5e, 0xf7, 0x14, 0xaa, 0x68, 0x4b, 0x5f, 0x19, 0xaa, 0x26, 0x79,
- 0xb4, 0x64, 0xf0, 0x72, 0x54, 0x53, 0x2f, 0x99, 0x7b, 0x88, 0x28, 0xce,
- 0x25, 0x92, 0xa3, 0xd8, 0xca, 0xfd, 0x07, 0x88, 0x19, 0x57, 0xcc, 0x73,
- 0x52, 0xb5, 0xe3, 0x68, 0x30, 0xef, 0xa4, 0x31, 0xd6, 0x5b, 0x72, 0x1c,
- 0x77, 0x1e, 0xf8, 0x3f, 0x55, 0x16, 0x57, 0xa2, 0x6d, 0xdb, 0x6e, 0xce,
- 0x83, 0x49, 0x4e, 0x7d, 0x77, 0xf0, 0x78, 0xf4, 0x37, 0x55, 0x52, 0x6b,
- 0x3b, 0x4a, 0xce, 0xb4, 0x3d, 0x71, 0xab, 0x98, 0xc2, 0xc0, 0x3b, 0xc4,
- 0x97, 0x4b, 0x49, 0xe1, 0x55, 0xc2, 0xa7, 0xba, 0xe8, 0xbb, 0x8a, 0xc8,
- 0x27, 0xe8, 0x67, 0xc9, 0xf9, 0x7d, 0xf1, 0x29, 0xc6, 0x34, 0x77, 0x93,
- 0xd3, 0x15, 0x73, 0x98, 0xf7, 0x39, 0x5f, 0x1b, 0x76, 0xd2, 0x4e, 0xf3,
- 0xb4, 0x05, 0x58, 0x45, 0xbe, 0xe4, 0xd0, 0xe8, 0x6e, 0x1e, 0x11, 0x9f,
- 0x03, 0xd4, 0xc6, 0x55, 0x14, 0x36, 0x69, 0xeb, 0xde, 0xc2, 0x3d, 0x68,
- 0xaf, 0x74, 0x41, 0xea, 0x09, 0x6f, 0x63, 0x19, 0x52, 0x8f, 0x89, 0xef,
- 0xb5, 0x49, 0x7d, 0x2c, 0x72, 0x16, 0x35, 0x26, 0x73, 0xcf, 0x6f, 0x92,
- 0xf5, 0x54, 0xf0, 0x2c, 0x54, 0x5c, 0xa0, 0x8c, 0x2f, 0x46, 0x7d, 0x33,
- 0x2b, 0x50, 0x7f, 0xf2, 0xa2, 0x9d, 0xbc, 0xb0, 0x5c, 0xda, 0x37, 0x40,
- 0xe3, 0x78, 0x9f, 0x47, 0x83, 0xe8, 0x57, 0xe5, 0xbb, 0xf0, 0xcb, 0x36,
- 0x74, 0x0f, 0xcb, 0x1a, 0x0c, 0xa3, 0x8c, 0x58, 0xf9, 0x88, 0x39, 0xbf,
- 0xcc, 0x7d, 0x73, 0x7c, 0x92, 0xf5, 0x7f, 0x12, 0xa3, 0x4c, 0xe3, 0x70,
- 0xd2, 0x03, 0xc7, 0x92, 0xaa, 0x39, 0xc8, 0x9f, 0xc6, 0x48, 0x4a, 0x23,
- 0xf7, 0x2c, 0x80, 0xa7, 0x52, 0xc7, 0x2e, 0xfa, 0xfc, 0x18, 0xdb, 0xa7,
- 0x63, 0x05, 0x88, 0x54, 0x5a, 0x73, 0xde, 0x1d, 0xff, 0xd8, 0x98, 0x7a,
- 0xd8, 0xf4, 0xa1, 0xfc, 0x1e, 0x64, 0x9f, 0x39, 0x72, 0xed, 0x14, 0xcf,
- 0xc6, 0x2e, 0x19, 0x53, 0x6d, 0xb3, 0x7f, 0x2f, 0x35, 0xef, 0x6e, 0x85,
- 0x6d, 0x95, 0xfc, 0xb4, 0xe4, 0xd2, 0x4d, 0xb9, 0x94, 0x68, 0xef, 0x19,
- 0x0f, 0x59, 0x72, 0x99, 0x23, 0xf1, 0x40, 0x6d, 0xfc, 0xf1, 0x39, 0x92,
- 0x6f, 0x15, 0x7f, 0xe6, 0x6a, 0xd2, 0x1a, 0x4f, 0xe2, 0x17, 0xc6, 0xb9,
- 0x1b, 0xc6, 0x29, 0xe7, 0x33, 0xf1, 0x4d, 0xe7, 0x32, 0xf7, 0x00, 0xdc,
- 0x99, 0x98, 0x61, 0x1a, 0x47, 0x93, 0xe2, 0x17, 0x3c, 0x58, 0x2f, 0xf9,
- 0x2a, 0xd5, 0xdb, 0x17, 0xc1, 0x14, 0x39, 0xe2, 0x07, 0x94, 0xbd, 0x22,
- 0xf5, 0x3a, 0xf2, 0xc4, 0xd9, 0xbe, 0x2b, 0x8c, 0x94, 0x59, 0x8f, 0x12,
- 0x6c, 0x9d, 0xc6, 0xf6, 0xa4, 0xd4, 0x4d, 0x3f, 0x23, 0x6f, 0xea, 0x22,
- 0x27, 0x9f, 0x46, 0x4f, 0xaa, 0x05, 0xaf, 0xec, 0x6d, 0x25, 0xde, 0x08,
- 0x6e, 0xfa, 0x4e, 0x9e, 0xb7, 0xb7, 0x60, 0xff, 0xa1, 0x34, 0x52, 0xa3,
- 0xe2, 0x2f, 0xe5, 0x1e, 0x9c, 0xf8, 0xca, 0x00, 0xa2, 0x89, 0x13, 0x88,
- 0xf0, 0x73, 0x67, 0xe2, 0x25, 0x84, 0x47, 0xdf, 0x63, 0x2c, 0x30, 0x8d,
- 0x95, 0xd4, 0xb9, 0x83, 0x98, 0xc6, 0xea, 0x03, 0x1a, 0x92, 0x89, 0x56,
- 0x8e, 0xdf, 0x82, 0xde, 0xbd, 0xde, 0x80, 0xc3, 0x56, 0x42, 0x7f, 0xa5,
- 0x61, 0xdb, 0x44, 0x33, 0x22, 0xc3, 0x56, 0x5d, 0xac, 0x21, 0xee, 0x51,
- 0x3e, 0x21, 0x9f, 0xae, 0x8f, 0x7b, 0x19, 0xc7, 0x79, 0x23, 0xab, 0x15,
- 0x9f, 0x27, 0xc7, 0x66, 0x18, 0xbd, 0xf4, 0x1b, 0x27, 0x75, 0x05, 0x79,
- 0xf7, 0x28, 0x08, 0xd2, 0x8f, 0x79, 0xaa, 0xe8, 0x5f, 0x86, 0x43, 0xe8,
- 0x1d, 0x9c, 0x5d, 0x53, 0x94, 0xf3, 0x7a, 0x80, 0xe3, 0xc9, 0xd9, 0xb5,
- 0xa2, 0x77, 0xc2, 0xd7, 0x71, 0xd2, 0xac, 0x39, 0x4a, 0xbb, 0x6c, 0x1b,
- 0x14, 0x7e, 0x16, 0xf2, 0x06, 0x4a, 0x14, 0x69, 0xbb, 0x95, 0x58, 0x36,
- 0xbb, 0x7d, 0x44, 0x49, 0x2e, 0x21, 0x7f, 0xb5, 0x89, 0x5d, 0x74, 0x9b,
- 0xb6, 0x23, 0xb2, 0xe8, 0x4d, 0x86, 0xa9, 0xd3, 0x3f, 0x35, 0x52, 0x6d,
- 0x6d, 0x5c, 0x67, 0xa3, 0xd4, 0x9c, 0x4c, 0x9e, 0x72, 0x5a, 0xf2, 0x73,
- 0x4e, 0xf1, 0xe3, 0xdd, 0xed, 0x2e, 0xea, 0x53, 0x2e, 0xb1, 0x2a, 0x6f,
- 0xdc, 0x05, 0xd7, 0xc1, 0x02, 0xe4, 0x0e, 0x09, 0x9f, 0x83, 0x5a, 0xdc,
- 0xa4, 0xc2, 0x3e, 0x5e, 0x48, 0x1b, 0xe0, 0x19, 0x8e, 0xd3, 0xc6, 0xa2,
- 0x6e, 0xd4, 0x8c, 0xbb, 0xf1, 0x13, 0xe2, 0x41, 0xf5, 0xb8, 0x86, 0x49,
- 0xe2, 0x81, 0x7b, 0x3c, 0x80, 0x09, 0xe2, 0x41, 0x49, 0x26, 0x47, 0xf2,
- 0x76, 0xfa, 0x65, 0x9e, 0xab, 0xcc, 0x25, 0x72, 0xcc, 0x9e, 0xab, 0x9c,
- 0x69, 0x2b, 0x31, 0x50, 0xce, 0xb7, 0x01, 0x3b, 0x06, 0xd3, 0x58, 0xbe,
- 0xc7, 0xc0, 0xbb, 0x7a, 0xbd, 0x3b, 0x4f, 0x91, 0x78, 0xc2, 0x40, 0x5a,
- 0x97, 0x3b, 0xab, 0xde, 0x75, 0x72, 0xaf, 0xbb, 0xbd, 0xc2, 0x40, 0x4e,
- 0xd0, 0xab, 0x13, 0xf9, 0xd7, 0xe5, 0x29, 0xe2, 0xc3, 0xea, 0x3d, 0x9b,
- 0x30, 0x57, 0x6a, 0x8e, 0xfc, 0xb7, 0x02, 0x9b, 0xc8, 0x1b, 0xf3, 0xb5,
- 0x56, 0xec, 0x2c, 0x8d, 0xb8, 0x2e, 0x87, 0x0c, 0x63, 0x43, 0xf0, 0xf1,
- 0x2a, 0x93, 0x03, 0xda, 0xf6, 0xf1, 0x73, 0x2d, 0xf7, 0x2d, 0x7b, 0xef,
- 0x40, 0x6c, 0xb7, 0x82, 0xb4, 0xbf, 0x03, 0xd1, 0x91, 0x0e, 0xec, 0xda,
- 0x2d, 0x98, 0xd0, 0x47, 0x4c, 0x30, 0xba, 0x36, 0x06, 0x1f, 0xc2, 0x25,
- 0x93, 0x11, 0x48, 0x1f, 0x6f, 0xc0, 0x63, 0x9b, 0x7d, 0x0e, 0x1b, 0xb9,
- 0x7e, 0xcb, 0x76, 0x9a, 0xfb, 0x85, 0x7b, 0xfb, 0xfb, 0x7a, 0x79, 0xfe,
- 0x0f, 0x1f, 0x10, 0xdf, 0x63, 0x18, 0x7d, 0xfa, 0x3c, 0xa0, 0x54, 0xf6,
- 0x10, 0x40, 0x3c, 0x61, 0x7c, 0x56, 0xad, 0xf9, 0x66, 0x76, 0xd1, 0xcf,
- 0x9f, 0xdd, 0x53, 0xbf, 0x69, 0x93, 0x70, 0x9a, 0xc5, 0xc2, 0xf3, 0xd2,
- 0x38, 0x33, 0x7a, 0x27, 0x52, 0x0f, 0x73, 0x3f, 0x3c, 0x2b, 0x67, 0xfc,
- 0x4b, 0x43, 0x78, 0x9d, 0x5d, 0x93, 0x9a, 0x2d, 0xa7, 0x1c, 0xf7, 0xa3,
- 0xa7, 0x14, 0x91, 0xcb, 0x21, 0x99, 0xff, 0xda, 0xfa, 0xb9, 0xdf, 0x16,
- 0xec, 0xda, 0x2b, 0xbc, 0x43, 0x38, 0x9a, 0x2f, 0xf2, 0x11, 0x5a, 0x91,
- 0x9c, 0xb0, 0xe6, 0x8a, 0x26, 0x6e, 0xd6, 0x15, 0x39, 0xf7, 0x13, 0xd8,
- 0x41, 0x8e, 0xe7, 0xe2, 0xf8, 0xf4, 0x35, 0x1c, 0x4f, 0x0b, 0xe4, 0xc9,
- 0x7c, 0xe3, 0x3f, 0x35, 0x76, 0x56, 0x8a, 0x6c, 0x64, 0x7c, 0xcd, 0xc4,
- 0x8c, 0x0d, 0xc1, 0x3f, 0xb7, 0xd7, 0x1a, 0x37, 0xf2, 0xbd, 0xad, 0x96,
- 0x3c, 0xa4, 0xad, 0xf6, 0x27, 0xd6, 0xb3, 0x90, 0xed, 0x64, 0x4d, 0x1d,
- 0xd8, 0xb1, 0x1b, 0x91, 0x7c, 0x4d, 0x6a, 0x0d, 0x1d, 0xe8, 0xa3, 0x7c,
- 0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0x36, 0x3b, 0xa4, 0xbf, 0x51, 0x6d, 0x43,
- 0xdd, 0x8c, 0x1d, 0x53, 0x3f, 0xab, 0x21, 0x9e, 0x2e, 0x5c, 0xec, 0xa7,
- 0x7d, 0x75, 0x20, 0x9e, 0xca, 0x75, 0x9b, 0x35, 0x40, 0x9b, 0xf8, 0x42,
- 0x91, 0x45, 0x27, 0xf2, 0xfb, 0x4f, 0xc0, 0xd9, 0xdf, 0x89, 0x3c, 0xff,
- 0x32, 0xdc, 0x1f, 0x3c, 0x67, 0x5c, 0xd2, 0x1c, 0xee, 0xa3, 0x94, 0xcf,
- 0x1b, 0x0d, 0xd5, 0x8c, 0x3b, 0x1b, 0xb0, 0x6d, 0xf8, 0x36, 0xda, 0x7e,
- 0x23, 0xb9, 0x2f, 0xe7, 0x6a, 0xb2, 0x61, 0xf5, 0x12, 0x89, 0xe9, 0xa5,
- 0x3e, 0x5d, 0x25, 0xf7, 0x10, 0xd4, 0xe7, 0x21, 0xf1, 0x1a, 0x39, 0x59,
- 0x85, 0x07, 0x4f, 0xd3, 0xc6, 0xda, 0x55, 0x79, 0xbe, 0x85, 0x71, 0xc4,
- 0x16, 0x54, 0xc7, 0x22, 0x86, 0xc8, 0xfb, 0x28, 0xc2, 0xdf, 0x93, 0x9a,
- 0x4a, 0xe3, 0x62, 0xff, 0xa6, 0x19, 0x45, 0x74, 0xda, 0xdf, 0x3e, 0xae,
- 0xe8, 0xae, 0x07, 0xc6, 0x14, 0x04, 0xfa, 0x39, 0x56, 0xf0, 0xfd, 0x39,
- 0x56, 0x1e, 0x2d, 0xcb, 0xff, 0xb6, 0x90, 0x33, 0x6c, 0x41, 0x11, 0xfb,
- 0xbb, 0x35, 0xc1, 0x86, 0xf0, 0x7d, 0xc5, 0xec, 0x9f, 0x0e, 0xfa, 0xdb,
- 0x0a, 0x15, 0xe1, 0x46, 0xfe, 0xc6, 0xd5, 0x8a, 0xf0, 0x18, 0xe9, 0xa7,
- 0xbb, 0xea, 0xc6, 0xce, 0x66, 0x6a, 0x66, 0x8d, 0xc4, 0x07, 0x8f, 0x79,
- 0x07, 0xd5, 0xba, 0xaf, 0x95, 0xbd, 0xb3, 0xa4, 0xf2, 0xfc, 0x25, 0xc6,
- 0x38, 0x12, 0x5c, 0x1e, 0x6d, 0x92, 0xfb, 0x21, 0xcb, 0x0e, 0x51, 0xef,
- 0xcf, 0xa3, 0x02, 0xff, 0x10, 0x15, 0x5c, 0xf3, 0xe0, 0x1f, 0xa3, 0xb9,
- 0x12, 0x57, 0xa7, 0x24, 0x6f, 0xf9, 0x66, 0x32, 0x62, 0x50, 0xae, 0xad,
- 0xab, 0xa9, 0x4b, 0x81, 0x60, 0x21, 0x50, 0xd9, 0xfd, 0xb4, 0xd3, 0x8c,
- 0xf3, 0x8b, 0x50, 0x4a, 0x1f, 0xd0, 0x3f, 0xfc, 0xa7, 0x72, 0xb4, 0xef,
- 0x9b, 0xdc, 0xf2, 0xef, 0xea, 0xec, 0xd8, 0x16, 0xfc, 0x57, 0x23, 0x95,
- 0xb9, 0x33, 0x7c, 0x66, 0xb7, 0xe8, 0x69, 0x00, 0xb9, 0xf1, 0xb3, 0xd4,
- 0x49, 0x15, 0xa7, 0xa3, 0x3e, 0x7d, 0x8d, 0xed, 0x49, 0xea, 0x7f, 0xcd,
- 0x0d, 0xd8, 0x5d, 0xa3, 0x3d, 0x88, 0xa7, 0x4c, 0xec, 0x0e, 0xa3, 0x87,
- 0xbe, 0x81, 0x9c, 0x6e, 0xdf, 0xd3, 0x36, 0x15, 0x79, 0x31, 0x9f, 0xea,
- 0xa3, 0x4e, 0xf5, 0x70, 0x0e, 0xe1, 0x9b, 0xe5, 0xe4, 0x83, 0x1b, 0xa3,
- 0xf5, 0x9e, 0x7f, 0xc1, 0x7a, 0xda, 0xa3, 0xcc, 0x21, 0x7b, 0xd2, 0x50,
- 0x18, 0xd7, 0x70, 0x8c, 0xfb, 0xd8, 0x56, 0x6a, 0xcd, 0x5b, 0x9c, 0x19,
- 0x3b, 0x3e, 0x2c, 0x5c, 0x6c, 0x29, 0xd6, 0x98, 0x63, 0xeb, 0xb4, 0x4b,
- 0x0d, 0xfb, 0xe4, 0x6e, 0x7f, 0x9d, 0x86, 0x44, 0xba, 0x19, 0x2f, 0x95,
- 0x79, 0xb0, 0x3f, 0xb1, 0x05, 0x8b, 0x12, 0xf7, 0xe1, 0xd1, 0xb2, 0x88,
- 0xdc, 0x85, 0x41, 0x5e, 0x5c, 0x53, 0xef, 0x54, 0xee, 0xcd, 0xd4, 0x29,
- 0x2a, 0xe0, 0x88, 0x8b, 0xcf, 0xcb, 0xc1, 0x80, 0x3a, 0x17, 0x05, 0xe6,
- 0x9d, 0x4a, 0x6b, 0xec, 0x5d, 0xc3, 0xde, 0x8c, 0x1f, 0x24, 0x6a, 0xc4,
- 0x15, 0xf1, 0xbf, 0x81, 0x17, 0x50, 0xce, 0x38, 0x21, 0x82, 0x9c, 0x26,
- 0x2d, 0xf5, 0x2c, 0xf2, 0x10, 0xa9, 0x12, 0x4c, 0x94, 0x3e, 0xb7, 0xdd,
- 0xb4, 0xa6, 0xb2, 0xcc, 0x9a, 0xb2, 0xcf, 0x31, 0x07, 0xc5, 0xa2, 0x5b,
- 0xc2, 0x35, 0xe4, 0xf7, 0x7c, 0xb4, 0x51, 0x9f, 0x2a, 0xb8, 0xe6, 0x84,
- 0x79, 0x5f, 0xd6, 0xab, 0x47, 0x6c, 0x21, 0xfc, 0x76, 0x8f, 0xa5, 0x83,
- 0xeb, 0x6a, 0x79, 0xfe, 0xc5, 0x21, 0xcc, 0x8c, 0x8a, 0x3f, 0xfb, 0x53,
- 0x67, 0x92, 0xf5, 0xc5, 0x72, 0x2e, 0x22, 0x57, 0xef, 0xc9, 0x0b, 0xa8,
- 0x9f, 0x7a, 0xc2, 0x76, 0xd8, 0x40, 0xb9, 0xc8, 0xf8, 0xb8, 0x5b, 0x62,
- 0x58, 0x1b, 0x79, 0x44, 0x24, 0x7d, 0xc5, 0x2d, 0xbe, 0xd2, 0x11, 0x07,
- 0x6a, 0xe2, 0x11, 0xe4, 0x36, 0x69, 0xfb, 0x2e, 0xdb, 0xaf, 0x1a, 0xed,
- 0x55, 0xb7, 0x31, 0x26, 0xbc, 0xbe, 0xe7, 0x3e, 0xae, 0xdd, 0xae, 0xfd,
- 0xd4, 0x58, 0x51, 0x21, 0x6b, 0xac, 0xae, 0xb6, 0xf2, 0xd1, 0xf3, 0x29,
- 0x97, 0xac, 0x4c, 0x0c, 0xea, 0xcf, 0xff, 0x32, 0xbe, 0x71, 0xc3, 0x73,
- 0xe1, 0x33, 0xa2, 0xa7, 0xb3, 0xef, 0x14, 0x8a, 0xce, 0x7a, 0xa8, 0xa7,
- 0xd3, 0x38, 0x94, 0x6c, 0x44, 0x7f, 0x42, 0x64, 0x1c, 0xc6, 0x79, 0x72,
- 0xc5, 0xda, 0x81, 0x69, 0x0c, 0x91, 0x2b, 0xfa, 0xe2, 0xde, 0x7d, 0x94,
- 0x24, 0x5e, 0x52, 0x97, 0x99, 0x3c, 0xc9, 0xa5, 0x65, 0xd7, 0x70, 0xb7,
- 0x29, 0x77, 0xf1, 0x31, 0x3b, 0xb9, 0xdf, 0x3b, 0xc8, 0x93, 0x9a, 0x63,
- 0xb9, 0xd0, 0x4a, 0x8b, 0x51, 0xa8, 0x49, 0x5d, 0xc3, 0x6a, 0x17, 0xe5,
- 0x5a, 0x0a, 0x34, 0x1f, 0x56, 0x9b, 0x6d, 0x3d, 0xe6, 0xfd, 0x09, 0x47,
- 0x99, 0xf8, 0x60, 0xf1, 0xbb, 0xe4, 0xe2, 0x4b, 0xc4, 0xef, 0x86, 0xb9,
- 0xb6, 0x05, 0x3c, 0xb3, 0x45, 0x70, 0xdf, 0xeb, 0x41, 0xf5, 0xbd, 0xf4,
- 0x91, 0x0b, 0x15, 0x94, 0x2d, 0xf4, 0x47, 0x16, 0xd9, 0x9a, 0x81, 0xaa,
- 0x00, 0xf1, 0x47, 0x33, 0x7a, 0x12, 0x7f, 0xe0, 0x18, 0x1d, 0x30, 0x76,
- 0xe7, 0x63, 0xfd, 0xee, 0x12, 0xea, 0xaa, 0x47, 0xf2, 0xf0, 0x2e, 0x57,
- 0x53, 0x34, 0xe8, 0x8a, 0xd5, 0xeb, 0x4e, 0x65, 0x01, 0xfd, 0xb1, 0x9c,
- 0x9f, 0xcc, 0x7f, 0xd7, 0x0d, 0x7c, 0xa9, 0x9c, 0xfe, 0xed, 0x51, 0x73,
- 0x0d, 0x92, 0x2b, 0x96, 0x7e, 0x7f, 0x7c, 0x4e, 0x53, 0xd7, 0xce, 0xe9,
- 0x4e, 0x38, 0x1e, 0xa9, 0x20, 0xff, 0xba, 0xb5, 0x0f, 0xc9, 0xa3, 0x0f,
- 0xb9, 0x23, 0x66, 0x74, 0x6d, 0x0e, 0x16, 0x48, 0xfe, 0xc8, 0xf4, 0x21,
- 0xed, 0xb6, 0x8d, 0xa6, 0xee, 0x38, 0xb5, 0x1e, 0xca, 0xdb, 0xca, 0x47,
- 0x53, 0x06, 0x73, 0xac, 0xbb, 0xb9, 0xd9, 0xdf, 0x3a, 0xb0, 0x9d, 0x98,
- 0x29, 0x77, 0xea, 0x9d, 0x9a, 0x46, 0xfb, 0xef, 0x40, 0x0f, 0xc7, 0x7c,
- 0x85, 0xb8, 0xd9, 0x4f, 0xdc, 0xbc, 0xba, 0xf8, 0x8d, 0x9f, 0x55, 0xa3,
- 0x2e, 0xe9, 0xc6, 0xd4, 0x5f, 0x97, 0x09, 0x6e, 0x2e, 0xf2, 0x77, 0x5c,
- 0x31, 0x71, 0x53, 0xc6, 0x96, 0xf1, 0x66, 0x8f, 0xfd, 0x3f, 0xf8, 0xdf,
- 0xf9, 0x92, 0x73, 0x34, 0x9c, 0xda, 0xff, 0x35, 0xb6, 0x55, 0xc8, 0x5a,
- 0x6f, 0xb5, 0x0e, 0xc1, 0xda, 0xd9, 0x35, 0xfd, 0x69, 0x62, 0xae, 0x19,
- 0x2f, 0xd0, 0xe7, 0x86, 0xb1, 0x6a, 0x89, 0x8a, 0x4b, 0xd1, 0x69, 0xe4,
- 0x1d, 0xc8, 0xe2, 0x93, 0xb1, 0xec, 0x18, 0xb1, 0x69, 0x08, 0x82, 0x47,
- 0x4d, 0x3c, 0x97, 0x08, 0xed, 0xa4, 0x08, 0xe3, 0x49, 0xb9, 0x47, 0x64,
- 0x60, 0x57, 0xd0, 0x45, 0x6e, 0xdb, 0x7d, 0x34, 0xc7, 0xf4, 0x13, 0x45,
- 0x54, 0xad, 0x2c, 0xef, 0x16, 0xce, 0x2d, 0xf8, 0x23, 0xfc, 0xd8, 0x8e,
- 0x92, 0xc5, 0x92, 0x17, 0xf8, 0xc2, 0xb8, 0xf4, 0x98, 0xb4, 0x9b, 0x87,
- 0xa1, 0xdd, 0xa2, 0x7f, 0x3e, 0x54, 0x6b, 0x67, 0x19, 0x73, 0x80, 0x73,
- 0xda, 0x6e, 0xcf, 0x21, 0x37, 0xee, 0xd2, 0x97, 0xe0, 0x6a, 0x79, 0x0f,
- 0x0a, 0x9a, 0xdc, 0xf8, 0x30, 0x3a, 0x85, 0x43, 0xc4, 0x8f, 0x5c, 0xea,
- 0x50, 0x5e, 0x46, 0xcf, 0x76, 0x0c, 0xcb, 0xfe, 0xaa, 0xb1, 0xd2, 0xb4,
- 0x53, 0x19, 0x63, 0x1a, 0xaf, 0x92, 0xcf, 0x36, 0x2f, 0x11, 0x2e, 0xab,
- 0x63, 0x5f, 0xa2, 0x08, 0x35, 0x83, 0x5d, 0x94, 0x5d, 0x11, 0xaa, 0x87,
- 0xc5, 0xbe, 0xe6, 0x0b, 0x8e, 0xca, 0x05, 0x39, 0xca, 0x43, 0xc5, 0xf6,
- 0x68, 0xbd, 0x7a, 0x81, 0x41, 0x42, 0xf8, 0x9a, 0xaf, 0x77, 0xd3, 0xef,
- 0x30, 0x26, 0xca, 0xe8, 0x85, 0x4a, 0xbd, 0x68, 0xbb, 0xc6, 0xa3, 0xb3,
- 0x7b, 0x99, 0x9d, 0x3f, 0x52, 0xb1, 0x23, 0x6a, 0x62, 0x21, 0xfb, 0xfa,
- 0x02, 0x3e, 0x85, 0x58, 0x3e, 0x26, 0x3a, 0xf6, 0x7e, 0x46, 0xce, 0x79,
- 0xb7, 0x59, 0xf7, 0x5a, 0x36, 0xde, 0xf4, 0x5d, 0x6b, 0x7f, 0x13, 0x67,
- 0x8d, 0x5d, 0x8f, 0xc9, 0x1a, 0x8f, 0xe3, 0x60, 0xf2, 0x8a, 0xdc, 0x9b,
- 0xef, 0x38, 0x03, 0x1b, 0x4e, 0x33, 0x76, 0x19, 0x4b, 0xfd, 0xae, 0x5a,
- 0xde, 0x45, 0xd9, 0x97, 0x98, 0xed, 0x3b, 0xc4, 0x2e, 0x3d, 0x19, 0xbf,
- 0x61, 0xd9, 0x67, 0x69, 0x5c, 0xee, 0xaf, 0x1c, 0x09, 0x3e, 0xcd, 0x73,
- 0xf1, 0x2f, 0xaa, 0x37, 0x73, 0x32, 0xe4, 0xc2, 0x8c, 0x53, 0x04, 0x73,
- 0x23, 0xf4, 0xf9, 0x45, 0xf8, 0x79, 0x52, 0x7c, 0xb0, 0x81, 0x5c, 0xea,
- 0xe3, 0xb9, 0x8a, 0xee, 0xe7, 0x4b, 0x4d, 0x6e, 0x5d, 0x84, 0x32, 0xee,
- 0x73, 0x60, 0xf8, 0x56, 0xba, 0x7e, 0xdd, 0x4f, 0xa4, 0x83, 0x0a, 0x71,
- 0xe3, 0x5f, 0xb9, 0x4e, 0xab, 0xcf, 0x99, 0xa4, 0x0b, 0x9f, 0x06, 0xdb,
- 0x31, 0x55, 0x1a, 0xc6, 0x60, 0x22, 0x0f, 0xed, 0x55, 0x75, 0xe6, 0xbb,
- 0x1d, 0xd5, 0x71, 0x0f, 0xce, 0x46, 0x9d, 0x68, 0x9c, 0xe3, 0x31, 0x73,
- 0x83, 0x36, 0x62, 0xfd, 0x07, 0xd1, 0xb0, 0x69, 0x83, 0xb3, 0x7d, 0x48,
- 0x8e, 0xb6, 0x18, 0x2d, 0x19, 0x9c, 0xdf, 0x9f, 0xf8, 0x82, 0x38, 0x54,
- 0x1c, 0x29, 0x6f, 0x2a, 0xc2, 0x1d, 0x83, 0x72, 0xc7, 0x41, 0xee, 0x64,
- 0x68, 0x33, 0x77, 0x2a, 0x45, 0x58, 0x36, 0x2c, 0x98, 0x2f, 0xb6, 0x9b,
- 0xa6, 0xed, 0xae, 0xe5, 0xb9, 0x75, 0x42, 0xde, 0xd9, 0x78, 0x85, 0xb2,
- 0xb7, 0x2b, 0x46, 0xd7, 0x45, 0x3d, 0x2c, 0xf7, 0x3c, 0x3b, 0x5b, 0x68,
- 0x07, 0x33, 0x41, 0x6f, 0x7b, 0xb9, 0x5d, 0xeb, 0xf8, 0x95, 0xd2, 0x80,
- 0xf1, 0x31, 0xa0, 0x7f, 0x34, 0x80, 0x8f, 0x12, 0x12, 0x03, 0x04, 0xf0,
- 0x1b, 0x72, 0xa3, 0x0b, 0x89, 0x06, 0xfa, 0x0b, 0x6f, 0xf8, 0x39, 0x34,
- 0xe0, 0x43, 0x7e, 0xcf, 0x8d, 0xeb, 0xb8, 0x4c, 0xf9, 0x39, 0xe3, 0x21,
- 0x5c, 0x9c, 0xb8, 0x17, 0x97, 0xf6, 0x2a, 0x78, 0x43, 0xbb, 0x17, 0xe7,
- 0x0f, 0x75, 0x62, 0xf1, 0x5e, 0x79, 0xef, 0xef, 0x48, 0x50, 0xa5, 0xaf,
- 0x78, 0xba, 0xd6, 0xe8, 0x7a, 0x51, 0xaf, 0x83, 0x5e, 0xe6, 0xd5, 0xdb,
- 0x89, 0x09, 0x82, 0xf1, 0x61, 0x9b, 0x9c, 0xa1, 0x9c, 0x65, 0x27, 0x2e,
- 0x99, 0xb8, 0x7e, 0x6b, 0xac, 0xb8, 0x8e, 0xe9, 0x32, 0x8f, 0xe0, 0xcb,
- 0x7c, 0xfc, 0x48, 0x0d, 0x70, 0x1f, 0x6e, 0x72, 0xb1, 0x29, 0xfa, 0xc7,
- 0x3c, 0xe4, 0x56, 0x4a, 0xcd, 0x5a, 0x43, 0x3e, 0x71, 0xe4, 0x14, 0x65,
- 0xb7, 0xaa, 0xd2, 0x6b, 0xc6, 0x3a, 0xb9, 0xf1, 0x06, 0xc6, 0x31, 0xe5,
- 0xf8, 0xe8, 0x06, 0xff, 0xfb, 0x23, 0xe3, 0x51, 0x13, 0xaf, 0x13, 0xb7,
- 0x09, 0x1f, 0x7b, 0x3d, 0xf1, 0xf8, 0x6d, 0x82, 0xdb, 0x92, 0x5f, 0x2c,
- 0xd6, 0xb4, 0x4d, 0xdf, 0x81, 0xbc, 0xff, 0xf6, 0xc6, 0x7f, 0x2b, 0x24,
- 0x4f, 0x7e, 0x31, 0x58, 0x17, 0x29, 0x45, 0x1f, 0x9f, 0x4f, 0x2d, 0x56,
- 0x71, 0x90, 0x9f, 0x7e, 0xb6, 0x6b, 0xe0, 0x3a, 0x3e, 0x36, 0x52, 0xaa,
- 0xcf, 0xf4, 0x25, 0x71, 0xfa, 0xd3, 0xd3, 0xb1, 0xfa, 0xf6, 0x51, 0xe5,
- 0xb2, 0x11, 0xa9, 0xac, 0xe5, 0x6f, 0x15, 0x38, 0x13, 0xf5, 0x4e, 0x1d,
- 0x42, 0xbd, 0x67, 0x46, 0xd9, 0x6f, 0x44, 0x54, 0x39, 0x1f, 0xd9, 0xaf,
- 0xf4, 0x5f, 0xc0, 0xe7, 0xe7, 0x66, 0xe9, 0xe1, 0xf5, 0x38, 0xcc, 0x79,
- 0x4d, 0xff, 0x84, 0xa7, 0x18, 0xcb, 0x46, 0xf4, 0x7a, 0xb5, 0x87, 0xd8,
- 0x10, 0x56, 0x6f, 0xa5, 0x7f, 0x79, 0xd4, 0xbf, 0x30, 0xe3, 0xca, 0x22,
- 0xa8, 0xd6, 0x7b, 0x3d, 0x48, 0x0e, 0xcf, 0xe6, 0x9a, 0xa2, 0x77, 0x16,
- 0x6f, 0x6d, 0x2f, 0xed, 0x3e, 0xea, 0x24, 0x36, 0x25, 0x88, 0xeb, 0x71,
- 0xe2, 0x7a, 0x2e, 0x71, 0xfd, 0xe3, 0x3d, 0xf9, 0x38, 0xbd, 0xa7, 0x11,
- 0xe9, 0x52, 0xe9, 0x63, 0x87, 0x93, 0xbb, 0x4b, 0x65, 0xee, 0x39, 0x54,
- 0x0f, 0xdc, 0x27, 0x77, 0x1e, 0x21, 0x7e, 0x36, 0x27, 0xce, 0xb8, 0xab,
- 0xcd, 0x0e, 0x87, 0xf9, 0x4e, 0x43, 0xc9, 0x0d, 0xfa, 0xe7, 0xd2, 0x72,
- 0xd1, 0x4a, 0x39, 0xe6, 0x6a, 0xbe, 0xb9, 0xd6, 0xdd, 0xbe, 0x22, 0xc6,
- 0x91, 0x72, 0x5f, 0x71, 0xa9, 0xd4, 0x03, 0xd9, 0x5e, 0xfa, 0x49, 0xac,
- 0x63, 0x60, 0x07, 0x35, 0xac, 0xae, 0xd2, 0x40, 0x42, 0x0f, 0xd3, 0x87,
- 0x05, 0x11, 0x26, 0xa7, 0x2f, 0xd4, 0xe4, 0xbb, 0x8a, 0x8b, 0x8c, 0xd3,
- 0xc6, 0x1a, 0x14, 0x7c, 0x7a, 0x97, 0x70, 0x03, 0xbf, 0x7e, 0x5a, 0xc1,
- 0x1c, 0xeb, 0x5d, 0x0a, 0xc1, 0x8c, 0x62, 0x13, 0x33, 0x72, 0x4d, 0x9e,
- 0x34, 0xc7, 0xc4, 0x1b, 0x79, 0x57, 0xac, 0x9a, 0x7e, 0xe8, 0x9e, 0x44,
- 0xfd, 0x94, 0xcf, 0x4e, 0xce, 0xf6, 0xf8, 0x5d, 0xe4, 0x6a, 0x26, 0x67,
- 0x20, 0xfe, 0xbf, 0x9f, 0xe1, 0x15, 0xde, 0xc6, 0x9b, 0xef, 0x90, 0x9e,
- 0xbb, 0x16, 0xa7, 0x5b, 0x7b, 0xe8, 0x1f, 0xfe, 0x9d, 0xd1, 0x76, 0xc3,
- 0xfa, 0xb3, 0xb8, 0xb2, 0x80, 0xdf, 0xa5, 0xbf, 0xd8, 0x1d, 0xf5, 0x22,
- 0xfe, 0x33, 0xe3, 0x29, 0x93, 0xdf, 0xd9, 0xe7, 0xca, 0x1d, 0x51, 0xc7,
- 0xc0, 0x17, 0xb7, 0xc9, 0xfb, 0x13, 0xb6, 0x59, 0x3c, 0xc1, 0xf2, 0xbd,
- 0x17, 0x8c, 0xd5, 0xe6, 0x5a, 0xf3, 0x33, 0xed, 0x24, 0xa6, 0x96, 0xb5,
- 0x28, 0xf8, 0x81, 0x56, 0xaf, 0x9e, 0x42, 0xa1, 0xe0, 0x49, 0x58, 0x6a,
- 0x9f, 0xf9, 0x9a, 0xcf, 0x7d, 0x90, 0x9f, 0xbb, 0xf8, 0xfc, 0xb8, 0xe6,
- 0x68, 0xdc, 0x0c, 0xa9, 0xf7, 0xda, 0x78, 0x56, 0xf5, 0xee, 0x53, 0xf0,
- 0x87, 0x73, 0x95, 0x19, 0xa3, 0xbd, 0x42, 0xda, 0x58, 0x75, 0x5f, 0x28,
- 0x67, 0xcd, 0x7c, 0x8a, 0xa5, 0x33, 0xf3, 0xa8, 0x33, 0x82, 0x5d, 0xc2,
- 0x4d, 0x16, 0x72, 0xef, 0x2a, 0x86, 0x27, 0x80, 0x9c, 0x01, 0x97, 0xc9,
- 0x95, 0xd4, 0xda, 0x5a, 0xcf, 0xb3, 0x58, 0x3e, 0x57, 0xde, 0x01, 0xdb,
- 0xaa, 0xe3, 0x76, 0x1b, 0xde, 0xbb, 0xdd, 0xd6, 0x74, 0xdf, 0x77, 0x5b,
- 0x42, 0x9b, 0x65, 0x5f, 0x44, 0x67, 0x33, 0xb7, 0xeb, 0x96, 0x1a, 0xe5,
- 0x4a, 0xfa, 0xb4, 0x21, 0xc6, 0xfc, 0x2b, 0x1b, 0xfe, 0xdd, 0xf8, 0x96,
- 0x23, 0xec, 0xb1, 0xa3, 0xd6, 0xd3, 0x8b, 0xab, 0x46, 0xaa, 0x42, 0x9e,
- 0xcb, 0x18, 0xf2, 0xae, 0xa7, 0xd4, 0x59, 0x0c, 0xe3, 0x8e, 0x5a, 0x83,
- 0xf1, 0xb4, 0x6d, 0xb9, 0x9d, 0x76, 0x91, 0xab, 0x9d, 0x37, 0xea, 0xaa,
- 0x6a, 0xdd, 0x36, 0xa5, 0x8e, 0xda, 0x51, 0x81, 0x57, 0xa9, 0xbf, 0xaf,
- 0x4e, 0x88, 0x0f, 0x54, 0x71, 0x98, 0x76, 0x7a, 0xa8, 0xce, 0xd7, 0x79,
- 0x89, 0xb1, 0xe5, 0x27, 0xe4, 0xfc, 0x6f, 0x6b, 0xde, 0xf6, 0x93, 0x92,
- 0x93, 0x0c, 0x3a, 0xf0, 0x66, 0xc3, 0x55, 0x33, 0x4f, 0x1c, 0x3b, 0xa0,
- 0x62, 0x28, 0x61, 0xd9, 0xfb, 0x6b, 0xb4, 0xe3, 0xeb, 0x77, 0x1e, 0x42,
- 0xe8, 0x19, 0x14, 0xfb, 0x08, 0x99, 0x76, 0x74, 0x3d, 0x77, 0x24, 0x78,
- 0x2d, 0x76, 0xb1, 0x5e, 0x6a, 0x7e, 0x91, 0x14, 0xc8, 0x6d, 0x06, 0x56,
- 0x92, 0x13, 0x8b, 0xcf, 0x6d, 0x60, 0xfc, 0xeb, 0xa0, 0xfd, 0x9c, 0x64,
- 0x2c, 0xc2, 0xb5, 0x35, 0x19, 0xc6, 0x05, 0xc6, 0x66, 0xc3, 0xa8, 0x57,
- 0x8f, 0x61, 0x0d, 0x79, 0x2d, 0x39, 0xcf, 0x44, 0x0b, 0x76, 0x9a, 0xb1,
- 0x95, 0x4f, 0xbd, 0x5f, 0x59, 0xc4, 0xfd, 0xb7, 0xa0, 0xfb, 0x90, 0x87,
- 0x3e, 0xc1, 0x30, 0x1e, 0xd0, 0xff, 0x12, 0x65, 0x83, 0xdd, 0x9d, 0x65,
- 0x94, 0xc7, 0xe7, 0xc1, 0x48, 0x07, 0x31, 0x7d, 0xd3, 0x31, 0x45, 0xee,
- 0xa5, 0x7e, 0x8b, 0xe7, 0x11, 0x30, 0xf9, 0xf6, 0x8e, 0xc4, 0x03, 0xf4,
- 0x71, 0xff, 0x1d, 0x3b, 0x54, 0x65, 0x19, 0xdd, 0x1d, 0x39, 0x23, 0xfc,
- 0x6a, 0x93, 0x76, 0xf2, 0xbc, 0xfd, 0xfb, 0xd0, 0xe7, 0x34, 0xf2, 0x99,
- 0xf8, 0x79, 0x69, 0x0b, 0x5c, 0x88, 0x76, 0xe2, 0x68, 0x9a, 0x7a, 0x1d,
- 0xed, 0xc3, 0xb1, 0xb4, 0xcc, 0x29, 0x9c, 0xab, 0x01, 0xb1, 0x41, 0x3b,
- 0xc6, 0x75, 0x5f, 0xb8, 0x98, 0x72, 0xc9, 0x0f, 0x7a, 0xc3, 0x6b, 0x88,
- 0xb1, 0x7d, 0xc3, 0x69, 0xbc, 0xb9, 0xdb, 0xdb, 0x5e, 0xa7, 0x68, 0x88,
- 0x4e, 0x40, 0x7d, 0x6e, 0x49, 0x1a, 0xa7, 0x46, 0x1e, 0x86, 0xa7, 0xca,
- 0xeb, 0x59, 0xa9, 0xb4, 0x62, 0xeb, 0xc4, 0xd7, 0xe5, 0x9c, 0x34, 0xce,
- 0xdd, 0x8a, 0x08, 0x65, 0xbf, 0x1d, 0xff, 0x38, 0x57, 0x70, 0xac, 0x77,
- 0xa2, 0x10, 0x35, 0xf4, 0x47, 0xaf, 0x98, 0x7e, 0xd7, 0xb2, 0xa3, 0x6a,
- 0xed, 0x53, 0xe3, 0x89, 0x8c, 0x5f, 0xff, 0xf3, 0xf2, 0xfa, 0xb1, 0x11,
- 0x56, 0x45, 0x5e, 0xd2, 0xaf, 0x9a, 0xdc, 0x40, 0x78, 0x81, 0xe5, 0xbf,
- 0x4b, 0xb5, 0xf7, 0x8d, 0x87, 0xcd, 0x31, 0x46, 0x39, 0x8f, 0xec, 0x29,
- 0x90, 0xd9, 0xb7, 0x8e, 0xdf, 0x46, 0x25, 0xf7, 0xa1, 0xe2, 0x98, 0x2e,
- 0x38, 0xd2, 0x4a, 0x5b, 0x75, 0x62, 0x53, 0x03, 0xcd, 0xd1, 0xac, 0x09,
- 0x4c, 0x63, 0x67, 0xf2, 0xf7, 0xc6, 0xf3, 0xd4, 0xa3, 0x55, 0xe4, 0x34,
- 0x1e, 0xe2, 0xc0, 0x33, 0xc1, 0x07, 0xc8, 0x4b, 0xb9, 0xe7, 0x84, 0x83,
- 0x18, 0xa4, 0x20, 0xd1, 0x48, 0xfb, 0x0f, 0x2e, 0xc4, 0x94, 0xd9, 0xfe,
- 0xb1, 0xb9, 0x56, 0xae, 0xb1, 0x61, 0x9e, 0x15, 0x2b, 0x8a, 0xfc, 0xff,
- 0x23, 0xf2, 0x7b, 0xcd, 0xf0, 0x94, 0x89, 0xfc, 0x1c, 0x70, 0xfb, 0x1b,
- 0xb0, 0x8f, 0x6d, 0xce, 0xec, 0x76, 0x60, 0x40, 0x6b, 0xc5, 0xc0, 0x04,
- 0x3c, 0x9f, 0xb3, 0xcd, 0xbb, 0x23, 0xbf, 0x98, 0x6b, 0x71, 0x87, 0xf7,
- 0xd0, 0x1d, 0x7d, 0xc1, 0x58, 0x5e, 0x26, 0xfb, 0x95, 0x7b, 0x3e, 0x6d,
- 0x6c, 0x9f, 0xcd, 0xfb, 0x3d, 0x6b, 0x3c, 0x62, 0xfa, 0x89, 0x7f, 0x9a,
- 0x2b, 0x75, 0xb9, 0xd7, 0x13, 0x06, 0x2e, 0xea, 0xe7, 0xe4, 0xfd, 0x49,
- 0x93, 0xeb, 0xf5, 0x26, 0xe4, 0x6c, 0x65, 0x6d, 0xc7, 0x32, 0xf2, 0x28,
- 0xa8, 0xba, 0x71, 0xdd, 0x67, 0x33, 0x39, 0x50, 0xe1, 0x10, 0x22, 0xab,
- 0x2c, 0xd7, 0xf0, 0x64, 0xf2, 0x6e, 0xc7, 0xd1, 0x93, 0x94, 0x9a, 0xb9,
- 0xbc, 0x9f, 0x5d, 0x82, 0x17, 0xf5, 0x87, 0xb0, 0xa0, 0xec, 0x0f, 0x9c,
- 0x4f, 0x72, 0x30, 0xad, 0x1c, 0xcf, 0x30, 0x36, 0xea, 0xf5, 0xfa, 0x45,
- 0x7c, 0x13, 0x53, 0x15, 0x21, 0xb3, 0x86, 0x91, 0xd7, 0xe4, 0x51, 0xb4,
- 0x3d, 0x6b, 0xe0, 0x2c, 0xd5, 0x88, 0xfd, 0xa2, 0x93, 0x82, 0x31, 0xb2,
- 0x26, 0xc1, 0x19, 0xc9, 0xf1, 0x4b, 0x4e, 0x3c, 0x12, 0xae, 0x69, 0xea,
- 0x54, 0x1e, 0x64, 0xcc, 0xff, 0x4e, 0x50, 0xde, 0x21, 0xf4, 0xb7, 0xd7,
- 0xd8, 0x90, 0x37, 0x19, 0xca, 0xc5, 0x2f, 0x83, 0x72, 0x9f, 0x1b, 0xae,
- 0xb1, 0xb4, 0x37, 0xd2, 0x68, 0x57, 0x5d, 0x69, 0xb3, 0x56, 0x29, 0xb8,
- 0x9b, 0xa0, 0xcc, 0x89, 0x2d, 0x26, 0xa6, 0xdc, 0x85, 0x15, 0xe6, 0x39,
- 0xab, 0xf4, 0xa7, 0xc2, 0x1b, 0x8e, 0x90, 0x37, 0x00, 0xb9, 0x03, 0xc6,
- 0xb2, 0xe6, 0x60, 0xbd, 0xde, 0x87, 0xdb, 0xc9, 0xfd, 0x97, 0xe1, 0x23,
- 0x5d, 0xea, 0x24, 0x91, 0x6f, 0x39, 0xcc, 0xfb, 0x38, 0x87, 0x83, 0x5b,
- 0xa3, 0x2b, 0xb1, 0x7f, 0x30, 0xa2, 0x38, 0x9b, 0xbc, 0xad, 0x31, 0xf2,
- 0x22, 0x42, 0xba, 0x99, 0x23, 0xdc, 0x41, 0xfe, 0x70, 0x38, 0xd4, 0x89,
- 0xed, 0x7a, 0x2e, 0x7a, 0xf5, 0x70, 0x5e, 0xcf, 0x92, 0x2e, 0xbc, 0xa2,
- 0x17, 0x4a, 0x1e, 0x9e, 0xf8, 0xae, 0x6d, 0x4a, 0xc2, 0xdf, 0xf1, 0x21,
- 0xbc, 0x53, 0x47, 0xc9, 0x41, 0xce, 0xdb, 0x15, 0xf8, 0x97, 0x3a, 0x5c,
- 0xb1, 0xb1, 0x26, 0xec, 0x9b, 0xa8, 0x70, 0xc5, 0xc7, 0x18, 0x0f, 0x4e,
- 0x30, 0x86, 0x61, 0x1c, 0xac, 0x8d, 0xad, 0xc4, 0xb6, 0x61, 0xb9, 0xe3,
- 0x1b, 0xc0, 0xdd, 0x65, 0xe7, 0x8c, 0xa7, 0xfd, 0x82, 0xa3, 0xf3, 0x71,
- 0x67, 0x99, 0xcf, 0xf4, 0x81, 0xed, 0xb6, 0xaf, 0xe3, 0x0f, 0x76, 0x6c,
- 0x0e, 0xfe, 0xc8, 0x08, 0x3f, 0x26, 0x72, 0x7b, 0x9e, 0x67, 0xf4, 0x00,
- 0xb1, 0xd4, 0x92, 0xe1, 0x86, 0x6b, 0x32, 0x0c, 0xa1, 0x7b, 0x30, 0x44,
- 0xfb, 0x71, 0x93, 0x6f, 0x5d, 0x3f, 0x87, 0xf5, 0xba, 0x6f, 0x66, 0x08,
- 0xad, 0x78, 0x65, 0xe2, 0x6f, 0xd8, 0x4f, 0xf2, 0x33, 0x4b, 0xd1, 0x91,
- 0x89, 0x47, 0xc2, 0xb6, 0x02, 0xf2, 0x3f, 0xcb, 0x0f, 0x0c, 0x0c, 0xcb,
- 0x73, 0xef, 0xbe, 0x30, 0xb9, 0xcc, 0x8b, 0x0d, 0x33, 0xd4, 0xc3, 0x48,
- 0xa7, 0xdd, 0x7c, 0x2f, 0xe2, 0xca, 0xf7, 0xdc, 0x75, 0xde, 0x75, 0x33,
- 0x0a, 0xf0, 0x17, 0x31, 0xfa, 0x64, 0x9b, 0xf4, 0x95, 0xb1, 0x9d, 0x38,
- 0xd8, 0x30, 0x1f, 0x53, 0x6b, 0x65, 0x4c, 0x99, 0xcf, 0x30, 0x9e, 0xa3,
- 0x8e, 0xff, 0x00, 0x4e, 0xe4, 0xde, 0x65, 0xc7, 0x39, 0x95, 0xb6, 0xa2,
- 0xff, 0xde, 0x48, 0xd3, 0x57, 0x6e, 0xcd, 0xd8, 0xcc, 0x36, 0xda, 0xcc,
- 0x28, 0x6d, 0xa6, 0x9f, 0x36, 0x73, 0xf7, 0xa2, 0x3b, 0x32, 0x36, 0x23,
- 0xb1, 0xe1, 0x34, 0x1e, 0xe9, 0x57, 0xd1, 0xf6, 0x9f, 0xa6, 0xd1, 0x76,
- 0x20, 0xbb, 0x76, 0xd1, 0xbb, 0xec, 0xfa, 0xa5, 0xde, 0x28, 0xf3, 0xc8,
- 0x1a, 0x65, 0x2f, 0xd9, 0xdf, 0xaf, 0x7f, 0xaf, 0xd6, 0x9c, 0x78, 0xc2,
- 0xdc, 0xd7, 0xdf, 0x57, 0x5b, 0x75, 0xfa, 0xec, 0x7e, 0xc2, 0x37, 0x7d,
- 0xaf, 0xbd, 0xed, 0xc6, 0xef, 0x7b, 0xdd, 0x37, 0x7e, 0x3f, 0x79, 0xd3,
- 0xf3, 0xac, 0x6d, 0x5c, 0x97, 0x69, 0xa7, 0xee, 0xeb, 0x9c, 0xe4, 0x3e,
- 0x3f, 0xba, 0xeb, 0xb0, 0xd1, 0xfe, 0xb0, 0xac, 0x25, 0x40, 0x9e, 0x24,
- 0xeb, 0x7b, 0x0f, 0x0b, 0xfe, 0x68, 0x6d, 0xef, 0x64, 0x6c, 0xc9, 0x7c,
- 0x37, 0xc8, 0xd4, 0xab, 0xd7, 0x27, 0x34, 0xfc, 0xf8, 0x86, 0xfb, 0x8b,
- 0x01, 0x65, 0x47, 0x4c, 0x74, 0xca, 0x11, 0x71, 0x35, 0x41, 0xb9, 0xd3,
- 0x1f, 0xc1, 0x42, 0x7f, 0x17, 0x3e, 0xa2, 0xce, 0xb7, 0x29, 0x1a, 0xe3,
- 0xbb, 0x24, 0xe2, 0x63, 0x5e, 0x7d, 0x13, 0xb1, 0x22, 0x36, 0xf6, 0x97,
- 0x38, 0x91, 0xcc, 0xa7, 0x0e, 0x76, 0x61, 0x65, 0xd0, 0x1b, 0x18, 0xa2,
- 0xef, 0xbd, 0xa0, 0x8b, 0x9d, 0x4a, 0xed, 0xd7, 0x43, 0x0c, 0x0d, 0x08,
- 0x06, 0xaa, 0x29, 0xf1, 0xc9, 0xb4, 0x3d, 0xe1, 0xd8, 0x0e, 0xea, 0xc6,
- 0xd6, 0xe1, 0xb7, 0xd0, 0x12, 0x95, 0x7c, 0xeb, 0x71, 0x3c, 0x9a, 0xa4,
- 0x0f, 0xd2, 0x68, 0xb7, 0x8b, 0x1c, 0xd0, 0xca, 0x24, 0x27, 0xec, 0xc0,
- 0xda, 0xf8, 0x7c, 0x44, 0xaa, 0xa4, 0xae, 0xb2, 0x12, 0xdb, 0x07, 0x15,
- 0xfc, 0x56, 0x6a, 0x98, 0x8c, 0xc1, 0x5f, 0x27, 0x47, 0x9c, 0x8c, 0x6e,
- 0xc1, 0x88, 0x59, 0xa3, 0xd6, 0xfa, 0xaa, 0xed, 0xe1, 0x17, 0x4b, 0xc9,
- 0xb7, 0x13, 0xba, 0xbf, 0x9d, 0xf6, 0xe8, 0x29, 0x6a, 0xf2, 0x87, 0x63,
- 0xca, 0x57, 0xf8, 0x37, 0xf3, 0xae, 0x8d, 0xee, 0xda, 0x44, 0x5d, 0xdf,
- 0x33, 0x2c, 0xfd, 0xb8, 0xc7, 0x5b, 0xe6, 0x3a, 0xac, 0x77, 0xdd, 0xad,
- 0xbc, 0xe4, 0x5b, 0x38, 0x98, 0x76, 0xe1, 0xa9, 0xb8, 0x47, 0xb1, 0xef,
- 0x51, 0xd1, 0x12, 0xf7, 0x9e, 0xbc, 0x60, 0x37, 0x8c, 0xba, 0xc5, 0x25,
- 0x98, 0x21, 0xbf, 0xa8, 0x5c, 0x2c, 0x3e, 0xe1, 0x3f, 0x23, 0x55, 0xd5,
- 0x4c, 0x6c, 0x43, 0xa1, 0x6d, 0x89, 0x57, 0xb7, 0xd9, 0x7d, 0xad, 0x33,
- 0xd8, 0x8a, 0xbc, 0xb1, 0x07, 0xcc, 0x75, 0x7f, 0x23, 0x2e, 0xef, 0x2f,
- 0xd5, 0x53, 0xdf, 0xe8, 0x27, 0x0f, 0x89, 0x0c, 0x11, 0xa9, 0x6c, 0x82,
- 0xa7, 0xa2, 0x69, 0xd7, 0x7c, 0xe4, 0x7f, 0x45, 0xce, 0x3d, 0x8d, 0x89,
- 0xa4, 0xd6, 0x51, 0x62, 0x33, 0x70, 0x3a, 0x78, 0x27, 0x52, 0x66, 0x0d,
- 0x63, 0x25, 0xfa, 0x07, 0x25, 0x3f, 0xaf, 0x40, 0x5b, 0x54, 0x40, 0xce,
- 0xa7, 0x05, 0x5e, 0xb4, 0x49, 0xcd, 0x79, 0x0b, 0xbe, 0xc1, 0xbd, 0xde,
- 0x1f, 0x15, 0x7b, 0xd5, 0xdc, 0x6d, 0x4a, 0xf8, 0xaa, 0x9d, 0x7b, 0xfd,
- 0xb5, 0xee, 0x3f, 0xf9, 0x6b, 0xbb, 0x7f, 0x2a, 0x64, 0xd7, 0x5d, 0x93,
- 0xe3, 0x2a, 0x31, 0xc4, 0x8a, 0x31, 0xd3, 0xe4, 0xb4, 0x85, 0x1c, 0xb7,
- 0x20, 0x78, 0x89, 0xdc, 0x40, 0xc6, 0x5d, 0x3e, 0x0f, 0xc5, 0x2d, 0xe8,
- 0xdf, 0xfb, 0xa1, 0x11, 0x6e, 0x93, 0x39, 0xfe, 0xc0, 0xb8, 0xd4, 0x89,
- 0x95, 0x6b, 0x3d, 0x58, 0x11, 0x97, 0x9c, 0xea, 0x8f, 0x2b, 0x2d, 0xdd,
- 0x92, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xdb, 0xaa, 0x2f, 0x8d, 0x0a, 0x33,
- 0x66, 0xbd, 0x6f, 0xbe, 0xe8, 0x4b, 0x6f, 0xe2, 0x85, 0xf9, 0x62, 0xdf,
- 0xbd, 0x13, 0x4f, 0xbb, 0x2d, 0xbd, 0x7b, 0x99, 0xdf, 0x65, 0x2c, 0x6d,
- 0xdf, 0x16, 0x9c, 0xa9, 0x14, 0x5e, 0xf3, 0xe8, 0xf8, 0xec, 0xf6, 0x56,
- 0xbd, 0xea, 0xf5, 0x6b, 0xb9, 0x1a, 0xa9, 0x13, 0x86, 0x95, 0xb6, 0x68,
- 0xab, 0xb2, 0x3a, 0x2a, 0xb5, 0x42, 0x5b, 0xa8, 0x80, 0x1c, 0xe6, 0x98,
- 0x2e, 0xef, 0xea, 0x65, 0xeb, 0x86, 0x11, 0xa5, 0x2f, 0x44, 0xc6, 0x33,
- 0xd6, 0xac, 0xec, 0x88, 0x96, 0xc9, 0x5d, 0x07, 0xea, 0xa5, 0x83, 0x32,
- 0x75, 0x21, 0x67, 0x54, 0x62, 0xf2, 0x02, 0xe4, 0x1c, 0xd0, 0x90, 0x3b,
- 0xd6, 0x8e, 0x11, 0x32, 0xb8, 0x92, 0xda, 0x72, 0x1c, 0x0a, 0xc8, 0x5d,
- 0x8e, 0x0a, 0x14, 0x09, 0xb6, 0x6a, 0x3d, 0x78, 0xb5, 0x0d, 0x4a, 0x41,
- 0xed, 0x6c, 0x9e, 0x6a, 0xde, 0x5f, 0x57, 0xdd, 0x4d, 0xe2, 0xdb, 0x25,
- 0xc7, 0x6f, 0xd5, 0x1d, 0xcf, 0xa6, 0x37, 0x60, 0x4c, 0xe5, 0xb2, 0xb5,
- 0x7f, 0x33, 0xc6, 0x2b, 0xcc, 0x77, 0x7e, 0xc8, 0x81, 0x0f, 0x93, 0x03,
- 0x1b, 0xcb, 0xba, 0x82, 0x91, 0x9f, 0xd5, 0xc0, 0xdb, 0xa7, 0xdb, 0xbd,
- 0x9e, 0x46, 0x9b, 0xe4, 0x10, 0xa0, 0xe4, 0xd4, 0x46, 0x90, 0x5b, 0x5b,
- 0x18, 0xb1, 0x53, 0xbf, 0xcf, 0xe8, 0x22, 0xfb, 0x2e, 0xec, 0xd4, 0xf3,
- 0xe5, 0x7d, 0xf9, 0x48, 0x31, 0x79, 0x4b, 0x0c, 0x9a, 0x7a, 0x1a, 0xda,
- 0xcc, 0x27, 0xec, 0xb7, 0x82, 0xf6, 0xd0, 0x3d, 0xe6, 0x0d, 0x5f, 0x54,
- 0xbc, 0x53, 0x77, 0xd3, 0x46, 0x5e, 0x19, 0xa3, 0x1d, 0x12, 0x77, 0xfb,
- 0x69, 0x03, 0x7d, 0xb4, 0x85, 0x7d, 0x13, 0x87, 0x84, 0x47, 0xf4, 0xb5,
- 0x2b, 0xd6, 0x3d, 0x4c, 0xab, 0xde, 0x2e, 0x35, 0xb5, 0x88, 0xb2, 0x21,
- 0x24, 0x7e, 0xb0, 0x08, 0xe7, 0x93, 0xc0, 0x91, 0x74, 0x0e, 0x5e, 0x1b,
- 0x41, 0x8b, 0x0d, 0xf6, 0x5e, 0x17, 0xea, 0xd6, 0xa9, 0x78, 0xa3, 0xae,
- 0x40, 0xfe, 0x87, 0x11, 0x15, 0x9d, 0x8c, 0x09, 0xcb, 0xb0, 0x62, 0xb7,
- 0xb1, 0xec, 0xae, 0x45, 0xc6, 0xb2, 0xcd, 0xfa, 0x63, 0x58, 0x63, 0x62,
- 0x4c, 0x77, 0x7b, 0x01, 0xe3, 0xdb, 0x1f, 0x8e, 0x38, 0x91, 0x4a, 0xb1,
- 0x17, 0xe5, 0x35, 0x9c, 0xc2, 0x03, 0x0e, 0x62, 0x27, 0xfd, 0x58, 0x5d,
- 0x71, 0x93, 0xbf, 0xed, 0x6e, 0x85, 0xbc, 0x32, 0x5d, 0x81, 0x54, 0x5a,
- 0xe3, 0x5f, 0x80, 0x7f, 0x0d, 0xfc, 0x6b, 0xc4, 0x9a, 0xa8, 0xe8, 0xa8,
- 0x1b, 0x63, 0xe9, 0x22, 0x7c, 0x98, 0xd4, 0x02, 0x2e, 0xea, 0xcf, 0x88,
- 0x3e, 0x6e, 0x44, 0xda, 0xac, 0x38, 0xe4, 0xf3, 0xa4, 0xe4, 0x74, 0x8a,
- 0xf0, 0x59, 0xea, 0xf4, 0x7c, 0x8b, 0xdb, 0x77, 0xe1, 0x62, 0x30, 0x3f,
- 0x52, 0x6a, 0xfa, 0x1c, 0x6f, 0xe0, 0x35, 0x68, 0xeb, 0xae, 0x70, 0xdf,
- 0xbb, 0xc6, 0x52, 0xc6, 0xb9, 0x0a, 0xb1, 0xf5, 0xe3, 0xf8, 0x49, 0xf2,
- 0x8a, 0x51, 0x23, 0x9c, 0x33, 0x21, 0xf7, 0xf5, 0xad, 0x3c, 0x8b, 0xc4,
- 0x46, 0x85, 0x4b, 0x67, 0x9f, 0xc9, 0x71, 0xa4, 0x53, 0xb3, 0xcf, 0x05,
- 0xed, 0x8e, 0x26, 0x57, 0xc3, 0x8e, 0xa8, 0xfd, 0x4a, 0x3e, 0x79, 0xd4,
- 0xfd, 0x4b, 0x34, 0xbd, 0x4e, 0x71, 0x35, 0xf4, 0xa6, 0x5d, 0x0d, 0x7d,
- 0xd1, 0xd9, 0xe7, 0x7a, 0x44, 0xb1, 0x37, 0xc9, 0x38, 0x7e, 0xc6, 0xdc,
- 0xd9, 0xb1, 0x5c, 0x0d, 0xdd, 0xe9, 0xd9, 0x63, 0x75, 0xa1, 0x23, 0x28,
- 0x67, 0xe4, 0xdd, 0xe4, 0xbc, 0xa1, 0x6e, 0x20, 0x3e, 0xdc, 0x7c, 0xcf,
- 0xa5, 0xe3, 0xbb, 0xd7, 0xfa, 0x6a, 0xc4, 0x32, 0xfa, 0xc5, 0x89, 0xd9,
- 0xfd, 0xa7, 0xf1, 0x6e, 0xd2, 0xfc, 0x7f, 0x06, 0x74, 0x7c, 0xce, 0x18,
- 0xf1, 0x54, 0xf0, 0xb0, 0xe1, 0x29, 0x15, 0x19, 0x1f, 0xc7, 0x07, 0xdc,
- 0x5b, 0xa1, 0xb6, 0xb5, 0xdd, 0xad, 0x69, 0x27, 0x3f, 0xb6, 0x3b, 0x50,
- 0xb7, 0xf4, 0x38, 0x4e, 0xa4, 0xe4, 0x0c, 0x8b, 0xcc, 0x77, 0x6d, 0x27,
- 0x79, 0x06, 0x07, 0x53, 0xc5, 0xb7, 0xcb, 0xfd, 0x75, 0xbb, 0xdc, 0x63,
- 0xc6, 0xff, 0x07, 0xb6, 0x0b, 0xca, 0xea, 0xc4, 0x79, 0x00, 0x00, 0x00 };
+ 0xec, 0x5c, 0x7f, 0x70, 0x1c, 0xd5, 0x7d, 0xff, 0xbc, 0xbd, 0xbd, 0xbb,
+ 0x95, 0x74, 0x3e, 0xed, 0x9d, 0x4e, 0xb2, 0x04, 0x06, 0xef, 0xa2, 0x95,
+ 0x74, 0x58, 0xc6, 0xec, 0x9d, 0x4e, 0xb6, 0x48, 0xb7, 0xc9, 0xd5, 0x36,
+ 0x20, 0x17, 0x52, 0x84, 0xa1, 0xc1, 0xcc, 0x30, 0x9d, 0x1b, 0x63, 0x8c,
+ 0xb0, 0x1d, 0xa2, 0x00, 0x33, 0xc8, 0x29, 0x13, 0x16, 0xfc, 0xb3, 0xf8,
+ 0xa4, 0x93, 0x8d, 0x8c, 0xc9, 0xf4, 0xd7, 0x21, 0xcb, 0x8a, 0x81, 0x93,
+ 0xce, 0x04, 0xda, 0x98, 0x69, 0xa8, 0x15, 0x6c, 0x53, 0x87, 0x5f, 0x21,
+ 0x19, 0x68, 0x4d, 0x9b, 0x99, 0xa8, 0x06, 0x1c, 0xd3, 0xa6, 0xd4, 0xb4,
+ 0x0e, 0xb5, 0x8b, 0xeb, 0xd7, 0xef, 0x77, 0x4f, 0x97, 0x50, 0x42, 0xcb,
+ 0x64, 0xa6, 0x7f, 0xee, 0x77, 0xe6, 0xe6, 0xf6, 0xde, 0xfb, 0xbe, 0xef,
+ 0x7b, 0xdf, 0xdf, 0x9f, 0xb7, 0x1a, 0xfb, 0xbe, 0x08, 0x6a, 0x31, 0x4b,
+ 0x73, 0xe8, 0x93, 0x19, 0x18, 0xbc, 0x27, 0xbd, 0x28, 0xb3, 0x88, 0x1e,
+ 0xbb, 0x02, 0x73, 0x55, 0x95, 0xc7, 0x05, 0x7c, 0xf2, 0xc9, 0x27, 0x9f,
+ 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2,
+ 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27,
+ 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c,
+ 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9,
+ 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xfa, 0xff, 0xa4, 0x00,
+ 0xa0, 0xf3, 0xf7, 0x9c, 0xd9, 0x0f, 0x34, 0xc5, 0x71, 0x37, 0x2e, 0xb5,
+ 0xa0, 0x05, 0x9c, 0x33, 0x1b, 0x6f, 0xb7, 0x80, 0x6c, 0xa9, 0xd3, 0x58,
+ 0x86, 0xff, 0x92, 0x6e, 0x42, 0x05, 0x8f, 0x5f, 0xe2, 0x9c, 0xff, 0xf3,
+ 0x17, 0x96, 0x98, 0xa7, 0x8b, 0x01, 0x68, 0xba, 0xf3, 0x46, 0x4a, 0x6f,
+ 0x87, 0x36, 0x8f, 0xd6, 0xfc, 0x49, 0xc7, 0x95, 0x71, 0x44, 0xab, 0xb2,
+ 0xe0, 0x2a, 0x8e, 0x94, 0xfb, 0x6c, 0x89, 0x97, 0x6c, 0x57, 0xf4, 0x66,
+ 0xe0, 0x06, 0x9c, 0x83, 0xe2, 0xae, 0xfc, 0x05, 0x69, 0x04, 0x2b, 0x3b,
+ 0xab, 0x93, 0x1a, 0x82, 0xfb, 0xa0, 0xab, 0x8e, 0x82, 0xa0, 0x55, 0x8b,
+ 0xd0, 0x13, 0x75, 0x08, 0x3e, 0xd1, 0x8c, 0xf0, 0xe4, 0x01, 0x91, 0x2b,
+ 0x6a, 0x98, 0x09, 0x1c, 0x14, 0x6b, 0x4a, 0xc8, 0x05, 0x9d, 0xb3, 0x37,
+ 0x8c, 0xd1, 0xba, 0xac, 0xf7, 0xef, 0x4b, 0xa6, 0x6f, 0x18, 0x2f, 0x41,
+ 0x0f, 0x38, 0x50, 0x54, 0xe7, 0x08, 0x3d, 0x33, 0xdf, 0xd9, 0x1b, 0xf6,
+ 0x96, 0x4e, 0xc9, 0x17, 0x3a, 0x12, 0x38, 0x54, 0xd6, 0x71, 0xa0, 0xfc,
+ 0x10, 0x9d, 0xc3, 0x74, 0x5d, 0x68, 0xae, 0xea, 0xb8, 0xd8, 0x92, 0x09,
+ 0x62, 0x62, 0xe4, 0x82, 0x0c, 0x58, 0xa6, 0x01, 0xc5, 0xd2, 0x0f, 0x83,
+ 0xf8, 0x0a, 0xc4, 0x57, 0x08, 0x62, 0xac, 0xb8, 0x23, 0x8e, 0xda, 0x66,
+ 0xbc, 0xd0, 0xc1, 0xeb, 0x79, 0x2d, 0xcb, 0xf8, 0x38, 0x5a, 0x5d, 0x1f,
+ 0xa2, 0xf5, 0x47, 0x33, 0xc0, 0xf8, 0x48, 0x1f, 0x2d, 0x95, 0xd8, 0x64,
+ 0x87, 0xb1, 0x5a, 0x87, 0x5b, 0xe3, 0xb0, 0xac, 0xaa, 0x1c, 0x57, 0x18,
+ 0x93, 0xff, 0x5c, 0x5f, 0x91, 0x03, 0xa1, 0x59, 0x70, 0xc3, 0x9f, 0x9a,
+ 0x3f, 0x55, 0xaa, 0xce, 0x6f, 0xa7, 0x7d, 0x34, 0x9a, 0xef, 0xc7, 0x5f,
+ 0x96, 0xd7, 0xe0, 0x2f, 0xca, 0xb7, 0xe1, 0xd9, 0x72, 0x1f, 0xed, 0x7b,
+ 0x1f, 0xed, 0x3b, 0x80, 0xbf, 0x2e, 0x6f, 0xc0, 0x77, 0xcb, 0x39, 0x3c,
+ 0x57, 0x5e, 0x85, 0xef, 0x94, 0x6f, 0xc6, 0x33, 0x65, 0x78, 0x67, 0x38,
+ 0x95, 0x49, 0x8a, 0x1f, 0xe5, 0x6b, 0xa0, 0xee, 0xdc, 0x8c, 0xe9, 0x52,
+ 0x10, 0xc1, 0x9d, 0x12, 0x23, 0xb6, 0xf9, 0x38, 0xd0, 0xa1, 0x07, 0x21,
+ 0xb0, 0xcc, 0x36, 0xf7, 0x03, 0x5f, 0x40, 0x2e, 0x61, 0x1e, 0x00, 0x9a,
+ 0xc4, 0x8f, 0x47, 0x9b, 0xc4, 0x6b, 0xa3, 0xaa, 0x78, 0x3d, 0x2f, 0x50,
+ 0xef, 0x20, 0xf2, 0x72, 0x46, 0xca, 0xeb, 0xd2, 0x52, 0x96, 0x52, 0x56,
+ 0xef, 0x0f, 0x85, 0x69, 0x3f, 0x22, 0x2e, 0x85, 0xd1, 0x68, 0x66, 0xd7,
+ 0x09, 0xcd, 0xad, 0x25, 0xf9, 0x2b, 0xba, 0x01, 0x6b, 0xa7, 0x41, 0x7e,
+ 0x60, 0x1d, 0x37, 0xe1, 0x0e, 0x2f, 0x26, 0xfa, 0xd0, 0x60, 0x2d, 0xc5,
+ 0xbd, 0x7d, 0x36, 0x8a, 0x65, 0x68, 0x31, 0xe7, 0x0c, 0x52, 0xc3, 0x02,
+ 0x36, 0xf9, 0x5b, 0xd0, 0xb3, 0x5d, 0x5a, 0xdf, 0x50, 0xf1, 0x37, 0x9d,
+ 0xbd, 0x40, 0x67, 0x2f, 0xd0, 0xd9, 0x0b, 0xa4, 0x57, 0x81, 0xf4, 0x2a,
+ 0x90, 0x0e, 0x05, 0xd2, 0xad, 0x40, 0x7a, 0x14, 0x48, 0x8f, 0x02, 0xe9,
+ 0x58, 0x60, 0x5f, 0x0d, 0x92, 0x0d, 0x22, 0xf8, 0xbb, 0xfc, 0x3c, 0x9c,
+ 0xe1, 0xcf, 0x4a, 0x1d, 0xc7, 0xe9, 0x8c, 0x8a, 0xf5, 0x9b, 0xca, 0xf8,
+ 0x6e, 0x84, 0x7c, 0x64, 0xfc, 0xe6, 0x7b, 0x2f, 0xc4, 0xc9, 0xfc, 0xbb,
+ 0x32, 0x34, 0x97, 0xf7, 0xfc, 0x22, 0xe4, 0x28, 0x70, 0xe9, 0x6e, 0x29,
+ 0xcf, 0x75, 0xcd, 0xc8, 0xb7, 0x6f, 0x61, 0x59, 0x0e, 0x4e, 0x8c, 0x2a,
+ 0x08, 0xd0, 0xd8, 0xb5, 0xf6, 0xdf, 0xcb, 0x3b, 0x13, 0xcc, 0xf7, 0x51,
+ 0x04, 0xb5, 0x6c, 0x27, 0x68, 0x0d, 0xce, 0xbb, 0x1b, 0xef, 0x6d, 0x87,
+ 0x1b, 0x75, 0x54, 0xf1, 0xe6, 0x90, 0x81, 0xb9, 0x4e, 0x16, 0x73, 0x1c,
+ 0x6b, 0x64, 0x8f, 0xd2, 0x39, 0x18, 0x47, 0xf6, 0xf2, 0x7a, 0xd8, 0xd8,
+ 0x57, 0x56, 0xc5, 0xab, 0x43, 0x73, 0x10, 0xdf, 0x69, 0xad, 0x1a, 0x12,
+ 0x0a, 0x72, 0x8d, 0x59, 0x8c, 0x67, 0x4c, 0xa3, 0x08, 0x03, 0xab, 0xd2,
+ 0x0a, 0x30, 0xd7, 0xc5, 0xd6, 0x8c, 0x69, 0xbb, 0x78, 0x08, 0xd3, 0x09,
+ 0x1b, 0x13, 0x65, 0x8d, 0x72, 0xc3, 0xc5, 0x9d, 0x19, 0x0d, 0x72, 0x24,
+ 0x8b, 0x93, 0x5d, 0x21, 0x4c, 0xf7, 0x71, 0x8c, 0xa8, 0xb4, 0xf7, 0x56,
+ 0x28, 0xf1, 0x38, 0xf9, 0xe5, 0xb0, 0x0c, 0xc6, 0x79, 0x0c, 0xe2, 0x5f,
+ 0x32, 0xbc, 0xff, 0x45, 0xe2, 0xd5, 0xdd, 0x51, 0xd4, 0xee, 0xd6, 0xf0,
+ 0xf4, 0x4e, 0x15, 0x2b, 0xc8, 0xb7, 0x7b, 0x52, 0xaa, 0xb1, 0x4e, 0x38,
+ 0x18, 0x2f, 0xab, 0x48, 0x0c, 0xb5, 0xc0, 0x88, 0x69, 0xb8, 0x74, 0xc8,
+ 0xc5, 0x3b, 0x24, 0x77, 0x90, 0xe4, 0xd6, 0x77, 0xe9, 0x98, 0x69, 0xac,
+ 0xf8, 0xf5, 0xeb, 0xf9, 0x56, 0x77, 0xa7, 0x12, 0x02, 0x42, 0x70, 0x35,
+ 0x27, 0x83, 0xfb, 0xf3, 0xad, 0xa4, 0xc3, 0xad, 0x58, 0x1a, 0xd2, 0xb0,
+ 0x7a, 0x98, 0xc7, 0x96, 0x03, 0x93, 0x73, 0xe7, 0xa0, 0x96, 0xf5, 0xe7,
+ 0x7c, 0x5e, 0x4a, 0xcf, 0x1c, 0x07, 0xbf, 0x9d, 0x60, 0xbb, 0xbb, 0xca,
+ 0x7f, 0xc8, 0x6c, 0x82, 0xf9, 0x2a, 0x39, 0x72, 0x38, 0x93, 0xc1, 0xc6,
+ 0x7c, 0x6b, 0xf6, 0x5b, 0x4a, 0x03, 0x10, 0x34, 0x0d, 0x43, 0x81, 0x96,
+ 0x70, 0x90, 0x1a, 0xa5, 0x78, 0x79, 0xd4, 0x8b, 0x17, 0xa4, 0xba, 0x4a,
+ 0x9c, 0x97, 0x9a, 0xab, 0x13, 0xff, 0xfc, 0xc5, 0x6d, 0xf8, 0xe8, 0x51,
+ 0xe6, 0x53, 0xf1, 0x03, 0x7a, 0x7e, 0x7f, 0xef, 0x8e, 0xd9, 0xda, 0xf1,
+ 0xa7, 0x9e, 0x5f, 0x0d, 0xa5, 0xba, 0xb7, 0x8d, 0x3b, 0xf3, 0xad, 0x67,
+ 0xb7, 0x29, 0xe4, 0xbf, 0x8b, 0x23, 0xa8, 0xa1, 0xfa, 0x13, 0x24, 0x59,
+ 0xfb, 0xf2, 0xe7, 0xb1, 0x32, 0x6d, 0x1e, 0xe4, 0x7f, 0x6f, 0x36, 0x66,
+ 0x55, 0xe4, 0x5f, 0x56, 0xb2, 0xf1, 0x64, 0xd9, 0xc6, 0xed, 0x74, 0x8e,
+ 0xfb, 0xf0, 0x8f, 0x40, 0xcb, 0x02, 0xe3, 0x94, 0x72, 0x42, 0xba, 0x37,
+ 0xb3, 0xbc, 0x79, 0x38, 0x15, 0x6f, 0xcd, 0x9d, 0x52, 0xcc, 0xe2, 0x76,
+ 0x85, 0x6d, 0xa5, 0xe0, 0xcb, 0xe9, 0x0c, 0x8a, 0x31, 0x1d, 0xb7, 0xa6,
+ 0x35, 0xf7, 0x52, 0x3a, 0xd3, 0x1b, 0x4b, 0x34, 0x34, 0xed, 0xca, 0xe2,
+ 0xad, 0xf4, 0x9b, 0x28, 0xae, 0x64, 0x3b, 0xf0, 0x3a, 0x3e, 0x73, 0x33,
+ 0xe2, 0x56, 0x0d, 0xe2, 0x63, 0x41, 0xd4, 0xef, 0xba, 0x20, 0x9b, 0x2d,
+ 0x1e, 0xb7, 0x06, 0xce, 0x0a, 0x3e, 0x73, 0x10, 0xd1, 0xb1, 0xab, 0xa0,
+ 0x5a, 0x66, 0x92, 0x1c, 0x9b, 0x60, 0xde, 0x90, 0x55, 0x3d, 0xbb, 0xc0,
+ 0x75, 0x5f, 0x10, 0x58, 0x97, 0xfa, 0xbe, 0xcc, 0x36, 0xf2, 0x9a, 0x67,
+ 0x68, 0x9c, 0xcf, 0x50, 0x73, 0x36, 0x8b, 0x26, 0x5a, 0x53, 0xe5, 0x8b,
+ 0xa0, 0x7f, 0x57, 0xe5, 0x0c, 0x6f, 0x2f, 0xc1, 0xb3, 0x1a, 0x7a, 0xd0,
+ 0x51, 0x78, 0x08, 0x6f, 0x2d, 0xf6, 0xf6, 0x3f, 0xbd, 0x2f, 0xbd, 0x83,
+ 0x6c, 0xc2, 0x75, 0xf4, 0xd3, 0x7e, 0xe1, 0xf9, 0xff, 0x64, 0x7f, 0x24,
+ 0x21, 0x9a, 0x69, 0x8c, 0xe3, 0x77, 0xa7, 0x34, 0x6e, 0xaa, 0xf8, 0x25,
+ 0x4c, 0xf2, 0xde, 0xcf, 0xf4, 0xa0, 0x75, 0x48, 0x85, 0xcc, 0xb7, 0xda,
+ 0x3f, 0x0d, 0x3c, 0x22, 0xa7, 0x6f, 0xe3, 0xb9, 0x56, 0xfd, 0x70, 0x40,
+ 0x60, 0xa9, 0x6a, 0x9e, 0xce, 0xa1, 0x19, 0xfb, 0xa9, 0xc6, 0xb4, 0x38,
+ 0x3a, 0xd5, 0x9c, 0x04, 0xd5, 0x1e, 0x43, 0x74, 0xec, 0xb1, 0xb1, 0x60,
+ 0xe8, 0x36, 0x7c, 0x69, 0xb7, 0x83, 0x83, 0x05, 0x1b, 0x4f, 0x17, 0xa4,
+ 0x3c, 0x69, 0x4b, 0xf9, 0xaf, 0x5d, 0x66, 0xff, 0x31, 0x6a, 0x07, 0x8b,
+ 0x96, 0x74, 0xe6, 0xea, 0x03, 0x2a, 0xd9, 0xa7, 0xcd, 0xd8, 0x20, 0xcc,
+ 0xe6, 0x29, 0x61, 0x53, 0xcc, 0xf5, 0x92, 0xed, 0x0d, 0xec, 0x2d, 0x27,
+ 0xf1, 0x54, 0xd9, 0xa2, 0xcf, 0x42, 0x8a, 0x95, 0x0c, 0xd5, 0x33, 0xd6,
+ 0x55, 0xc7, 0x78, 0x07, 0xe5, 0x45, 0x41, 0xc1, 0x7e, 0x9b, 0xe2, 0x3f,
+ 0x46, 0xbc, 0x85, 0x0b, 0xe4, 0x3f, 0x0d, 0xc9, 0x9d, 0x59, 0xd4, 0xa4,
+ 0x1a, 0x60, 0xdc, 0x68, 0x61, 0xbc, 0xa0, 0xb9, 0x41, 0x8a, 0xf9, 0xb1,
+ 0xfc, 0x38, 0xfe, 0x40, 0x4f, 0xa0, 0x96, 0xec, 0xb7, 0x2a, 0x1d, 0x01,
+ 0x6e, 0xe2, 0xb9, 0x08, 0x5a, 0xac, 0xef, 0xa3, 0x25, 0x3e, 0x07, 0xa1,
+ 0x05, 0x7f, 0x85, 0x69, 0x3d, 0x8a, 0x30, 0xf5, 0x8c, 0xf9, 0xc4, 0x33,
+ 0x9f, 0x7c, 0xd5, 0x68, 0x59, 0x24, 0x53, 0xc0, 0x6a, 0x23, 0x5e, 0xca,
+ 0xa7, 0x66, 0xd2, 0x3d, 0xb8, 0x24, 0x81, 0x32, 0x9d, 0x7f, 0x2a, 0x2f,
+ 0x65, 0x24, 0x63, 0xf6, 0x17, 0x28, 0x37, 0x27, 0x4b, 0x3d, 0x98, 0x2a,
+ 0xff, 0x1e, 0xd5, 0x73, 0x1b, 0x7b, 0xf3, 0x0e, 0xc6, 0x0a, 0xea, 0xaa,
+ 0x3c, 0xcc, 0xbe, 0xf5, 0xc8, 0xe0, 0x29, 0x8a, 0x9f, 0x89, 0x82, 0x69,
+ 0xbc, 0x18, 0xd0, 0x70, 0xcc, 0xae, 0xa3, 0x73, 0x52, 0xde, 0x92, 0x4e,
+ 0xcf, 0xe7, 0x47, 0x60, 0x35, 0xb0, 0xfd, 0xd9, 0x4f, 0x19, 0x7c, 0xbb,
+ 0xe0, 0xc5, 0xf7, 0x75, 0x1a, 0x5c, 0xd8, 0xdd, 0xec, 0x1b, 0xf7, 0x74,
+ 0x30, 0x5d, 0xa9, 0xa3, 0x7d, 0xdd, 0x36, 0xc2, 0xc3, 0x3d, 0x24, 0xb7,
+ 0xd5, 0x3e, 0x81, 0x3b, 0x30, 0xdd, 0xec, 0x62, 0x11, 0xc5, 0xbf, 0xea,
+ 0x3c, 0x9e, 0xda, 0x9c, 0x77, 0x65, 0xbd, 0x65, 0xf5, 0xff, 0x50, 0x3c,
+ 0x88, 0x57, 0x53, 0x5c, 0xd7, 0x55, 0xca, 0x7b, 0x1d, 0x3b, 0xec, 0x11,
+ 0xbc, 0x56, 0xfa, 0x2d, 0xe4, 0x62, 0x66, 0x72, 0x93, 0x58, 0x8f, 0x83,
+ 0x23, 0x57, 0x01, 0xb7, 0x70, 0x9e, 0x90, 0x6e, 0xd6, 0x7a, 0x1c, 0x2a,
+ 0x7e, 0x03, 0x47, 0x47, 0x6b, 0xf1, 0xbc, 0x15, 0x47, 0xcb, 0x44, 0x65,
+ 0x9f, 0xab, 0xbb, 0x35, 0x8c, 0x51, 0x4e, 0x5f, 0x6b, 0xab, 0x98, 0x49,
+ 0x70, 0xfd, 0xa0, 0x58, 0x4b, 0x6f, 0xa0, 0x5a, 0xe3, 0xb5, 0x5e, 0xac,
+ 0xc9, 0x18, 0xc8, 0xe7, 0xb3, 0x54, 0xff, 0x6a, 0xb0, 0x2b, 0x06, 0x71,
+ 0x3b, 0xf5, 0xb0, 0xbb, 0xf3, 0xad, 0xfd, 0xc3, 0x4a, 0x1c, 0xc5, 0x96,
+ 0x2c, 0xf9, 0x42, 0xa0, 0xc9, 0x32, 0xb0, 0xa5, 0x44, 0x15, 0xb4, 0xa4,
+ 0xe2, 0x9b, 0xa5, 0x2b, 0x50, 0x6c, 0xe2, 0xb5, 0x1d, 0x98, 0xf6, 0xbe,
+ 0x83, 0x98, 0x89, 0x9b, 0xcd, 0x20, 0x9b, 0x8d, 0x17, 0x54, 0xec, 0xb6,
+ 0xf7, 0x5c, 0x28, 0xae, 0x34, 0xf5, 0x1c, 0xe5, 0x5b, 0xc0, 0x8b, 0x5b,
+ 0x7e, 0x06, 0xbe, 0x96, 0xff, 0x50, 0x9e, 0xf1, 0xf6, 0x54, 0x39, 0xff,
+ 0xa7, 0xdf, 0x0e, 0xbc, 0x2f, 0x45, 0x98, 0xe5, 0xdf, 0x1f, 0xad, 0xfc,
+ 0x5b, 0xd1, 0x67, 0x99, 0x37, 0x0b, 0x70, 0x1c, 0xcc, 0xfd, 0x44, 0xcc,
+ 0x57, 0xea, 0x80, 0xbe, 0x98, 0xcf, 0x51, 0xcd, 0xb3, 0x38, 0x9a, 0x26,
+ 0xda, 0x50, 0xb3, 0x8b, 0x7f, 0xf3, 0xb8, 0xc0, 0x65, 0xdd, 0x9c, 0x63,
+ 0x6d, 0x50, 0xc6, 0x56, 0x47, 0x2b, 0x35, 0xb8, 0x5a, 0x1f, 0xfe, 0x70,
+ 0x56, 0xbe, 0xd7, 0xeb, 0xe9, 0x77, 0xa5, 0x86, 0x7e, 0x33, 0xc3, 0xcf,
+ 0xbc, 0xa6, 0x06, 0x6f, 0xed, 0x35, 0xed, 0xa2, 0xb2, 0x84, 0xf7, 0xac,
+ 0xe4, 0x08, 0x36, 0xce, 0xae, 0xa1, 0x98, 0x2f, 0x4c, 0x49, 0xdc, 0xca,
+ 0xf2, 0xaa, 0xeb, 0xdb, 0x10, 0xfa, 0xe5, 0xbe, 0x2a, 0x5e, 0xcc, 0x7c,
+ 0x7a, 0xdf, 0xdb, 0x64, 0xed, 0xca, 0x38, 0xc5, 0x59, 0x23, 0xd4, 0x05,
+ 0xd4, 0xe0, 0xf5, 0x26, 0xd4, 0x51, 0xde, 0x06, 0xac, 0x5b, 0x64, 0xe0,
+ 0x2b, 0x1c, 0xa7, 0x9a, 0x1b, 0x71, 0x2e, 0xc6, 0xf0, 0xce, 0x17, 0xc8,
+ 0xc7, 0x51, 0x8e, 0x47, 0xf2, 0xf3, 0xc5, 0x18, 0x7a, 0xe2, 0x92, 0x28,
+ 0xeb, 0xbb, 0x2a, 0x0d, 0x77, 0x3e, 0xd5, 0xec, 0xf7, 0xf6, 0xdc, 0x2d,
+ 0x8b, 0x7d, 0x3a, 0x5e, 0xca, 0xfc, 0x0e, 0x8d, 0x73, 0x3c, 0xd9, 0x78,
+ 0x2e, 0xaf, 0xe1, 0xfe, 0xe1, 0x66, 0x3a, 0x27, 0xd7, 0xca, 0x9a, 0xb3,
+ 0x33, 0x8a, 0x8d, 0x67, 0x29, 0x16, 0x9f, 0x29, 0xb0, 0xad, 0x54, 0x5c,
+ 0x96, 0x5e, 0x21, 0xc3, 0x4d, 0x1c, 0xdf, 0x49, 0x5a, 0xa3, 0x93, 0xec,
+ 0x28, 0x74, 0x6b, 0x99, 0x3c, 0xb0, 0x92, 0x9f, 0x3b, 0x68, 0xac, 0x89,
+ 0xbe, 0xbb, 0x65, 0xdd, 0xaf, 0x9d, 0x43, 0xff, 0xac, 0x73, 0x50, 0xdc,
+ 0x9b, 0xf6, 0x5a, 0x74, 0x12, 0x0e, 0x52, 0x91, 0xa5, 0x3e, 0x3f, 0x41,
+ 0x31, 0xb0, 0x8d, 0x7a, 0xf0, 0x7b, 0x84, 0xf5, 0xb6, 0x78, 0x78, 0xca,
+ 0x83, 0x67, 0x1e, 0x5e, 0x5b, 0x5d, 0xc1, 0x5d, 0x9a, 0x6a, 0x31, 0x16,
+ 0xab, 0xce, 0x71, 0x9e, 0xf6, 0x62, 0x6c, 0x54, 0xca, 0xcd, 0x76, 0x0b,
+ 0xc9, 0x88, 0x63, 0xb3, 0x45, 0x39, 0x3d, 0xca, 0x6b, 0xa4, 0x4c, 0xa6,
+ 0x16, 0xf4, 0xa8, 0xa2, 0x01, 0x33, 0xba, 0x2b, 0xd6, 0x66, 0x0c, 0xf1,
+ 0xd5, 0x51, 0x15, 0xf9, 0xc2, 0x45, 0x64, 0x2f, 0x29, 0x9f, 0x4a, 0x21,
+ 0xbb, 0x29, 0x55, 0x87, 0x57, 0x8a, 0x3a, 0x72, 0xfa, 0x05, 0xb9, 0xbc,
+ 0xad, 0x17, 0x65, 0x92, 0xf3, 0x41, 0xaa, 0x33, 0x79, 0x44, 0x44, 0x50,
+ 0x4c, 0x44, 0xf0, 0x78, 0x21, 0x81, 0x23, 0xe3, 0x11, 0x6c, 0xa5, 0x18,
+ 0x7d, 0x31, 0xc3, 0x7b, 0x46, 0xf0, 0x70, 0x99, 0x31, 0x55, 0x80, 0x6c,
+ 0xe4, 0x8a, 0x13, 0xde, 0x58, 0x1d, 0x96, 0x17, 0x99, 0xf7, 0x82, 0x6c,
+ 0xb1, 0x2c, 0xbd, 0x25, 0x50, 0xe5, 0x3b, 0x4e, 0xf8, 0xca, 0xa0, 0x5a,
+ 0x36, 0x8f, 0x70, 0x55, 0x33, 0x61, 0xa8, 0x04, 0x61, 0x28, 0x6b, 0x16,
+ 0x17, 0x9a, 0x94, 0x8d, 0x52, 0x3e, 0x4b, 0xb5, 0xec, 0xc7, 0xf4, 0x39,
+ 0x43, 0xf5, 0x34, 0x46, 0x3a, 0x5e, 0x36, 0xcc, 0x3a, 0xba, 0xc2, 0xa6,
+ 0x7a, 0x9b, 0x55, 0x94, 0x7a, 0xee, 0x43, 0x81, 0x29, 0xde, 0x5f, 0xc5,
+ 0x96, 0x02, 0xb0, 0xa9, 0x00, 0xf7, 0x08, 0xe5, 0x7e, 0xc3, 0x44, 0x14,
+ 0xf1, 0x09, 0x1d, 0xc1, 0x89, 0x24, 0xcd, 0x6b, 0x48, 0xd0, 0x6f, 0x97,
+ 0xb0, 0x60, 0xbd, 0xd3, 0x24, 0x16, 0x3e, 0x76, 0x5e, 0xee, 0x48, 0xa9,
+ 0x58, 0xd7, 0x66, 0xf6, 0xde, 0x28, 0x90, 0x4d, 0x0e, 0x49, 0x19, 0x4e,
+ 0x85, 0x29, 0x37, 0xe5, 0xa1, 0x04, 0xe9, 0x1d, 0x75, 0xe4, 0x83, 0xaf,
+ 0x75, 0x5b, 0xf6, 0x6b, 0x20, 0xb9, 0x65, 0x5e, 0xc3, 0xe3, 0xae, 0xf8,
+ 0xb0, 0xdb, 0x7a, 0xfc, 0x4d, 0xb4, 0xa3, 0x6b, 0x42, 0x15, 0xff, 0x36,
+ 0xb4, 0x10, 0xe9, 0x29, 0xe8, 0x21, 0xe7, 0x80, 0x98, 0x79, 0xe2, 0xa0,
+ 0x38, 0x39, 0x49, 0xe7, 0x2e, 0x90, 0x2e, 0x05, 0xd2, 0xa5, 0x40, 0xba,
+ 0x90, 0x5d, 0x9e, 0xf1, 0xf0, 0x24, 0xeb, 0x9a, 0x24, 0x2c, 0x73, 0xdc,
+ 0xc3, 0xbc, 0x8c, 0x11, 0x63, 0x8e, 0x99, 0x75, 0xc1, 0x7a, 0xb3, 0x9e,
+ 0x52, 0xbe, 0x69, 0x57, 0xf4, 0x71, 0xa9, 0xdc, 0x6a, 0x53, 0x55, 0x5b,
+ 0x48, 0xf9, 0xef, 0x36, 0xdb, 0x82, 0x75, 0x94, 0xf2, 0x3b, 0xa4, 0xd3,
+ 0x16, 0xd2, 0x71, 0x53, 0x41, 0x1e, 0x0a, 0x59, 0x96, 0x31, 0x41, 0x67,
+ 0x8b, 0x93, 0x4e, 0x89, 0x09, 0x8d, 0x74, 0x6d, 0x87, 0x4a, 0xba, 0x06,
+ 0x26, 0xa0, 0x2b, 0x74, 0x1e, 0x63, 0x8c, 0xec, 0x34, 0xf5, 0x79, 0xe7,
+ 0x61, 0xcc, 0xef, 0x8a, 0xab, 0x09, 0x9f, 0xa8, 0x64, 0xd7, 0x4d, 0x14,
+ 0x3b, 0x39, 0x15, 0x46, 0xd8, 0x52, 0xa8, 0x27, 0x6a, 0xf8, 0xf6, 0x78,
+ 0x1d, 0x26, 0xc8, 0xef, 0xc5, 0x71, 0xe8, 0x41, 0x92, 0xe9, 0x16, 0x0f,
+ 0x8a, 0x4f, 0xc6, 0x5b, 0xd0, 0x19, 0x20, 0x9c, 0x04, 0x3c, 0x92, 0x8f,
+ 0x8b, 0x89, 0x11, 0x15, 0x9b, 0x0b, 0xa7, 0x49, 0x3f, 0x89, 0xc3, 0xf6,
+ 0xc3, 0xcd, 0xc4, 0x22, 0x1e, 0xb6, 0xcd, 0x1e, 0xe0, 0x2a, 0x8a, 0xb7,
+ 0x00, 0xd6, 0x5a, 0xc8, 0x6e, 0xb3, 0xaf, 0xc2, 0x4c, 0x1f, 0x8c, 0xed,
+ 0xb6, 0xab, 0x87, 0x60, 0x1e, 0xbb, 0x9a, 0x7a, 0xd3, 0x95, 0xa4, 0xcf,
+ 0xa0, 0xe5, 0x0e, 0x50, 0xe1, 0x42, 0xb9, 0x6c, 0xf6, 0x1f, 0x25, 0x5f,
+ 0x94, 0xa8, 0xff, 0x95, 0xca, 0x4d, 0xe2, 0xe9, 0xd1, 0xf3, 0xf2, 0xae,
+ 0x94, 0x99, 0x6d, 0xa3, 0xb1, 0xe0, 0x90, 0x46, 0x38, 0x4d, 0xa3, 0x9c,
+ 0x32, 0x6d, 0x80, 0x6b, 0x03, 0xb4, 0x30, 0xd5, 0xe2, 0x9f, 0x59, 0x47,
+ 0x08, 0xa7, 0x6b, 0x20, 0x0c, 0x8f, 0xa5, 0x23, 0x02, 0xfb, 0x28, 0xc7,
+ 0x27, 0x17, 0x9a, 0xc7, 0x56, 0xc3, 0x9d, 0x6e, 0x81, 0x39, 0x18, 0x0e,
+ 0x9c, 0xc6, 0x07, 0x43, 0x21, 0xc2, 0x0d, 0xed, 0xf6, 0xeb, 0x30, 0xf5,
+ 0x7d, 0x81, 0x5f, 0xc8, 0xfd, 0x09, 0x5c, 0x14, 0xc4, 0x19, 0x69, 0xfc,
+ 0x3e, 0xaf, 0x61, 0xdd, 0x07, 0xb0, 0x2d, 0xc3, 0x38, 0x45, 0x25, 0x9c,
+ 0x02, 0xbc, 0x93, 0x37, 0xb0, 0x7f, 0x61, 0x0d, 0xf5, 0x93, 0xd6, 0x9e,
+ 0x75, 0x70, 0x57, 0xd1, 0xf5, 0x47, 0x8b, 0xd0, 0x5e, 0x79, 0x8a, 0x95,
+ 0x0d, 0x42, 0xe0, 0x29, 0xeb, 0xac, 0xdd, 0x31, 0xc9, 0x18, 0x46, 0x4d,
+ 0x2d, 0xa0, 0x5c, 0xdc, 0x5a, 0x16, 0xd4, 0xdb, 0x4c, 0x7d, 0x06, 0x6c,
+ 0x1b, 0x9d, 0xec, 0x7a, 0x5e, 0x22, 0xc6, 0xba, 0xbb, 0x39, 0xd2, 0x73,
+ 0xd5, 0x16, 0x3a, 0xff, 0x1a, 0xd2, 0xe9, 0x2e, 0xcb, 0xed, 0x21, 0xa9,
+ 0xd4, 0xa3, 0xcc, 0xe6, 0xf7, 0x48, 0xf7, 0xb5, 0x54, 0x47, 0x8a, 0xe5,
+ 0xe7, 0xea, 0xb9, 0x66, 0x4c, 0x94, 0xf9, 0x1e, 0xd7, 0x83, 0xa5, 0xf9,
+ 0x6a, 0x3e, 0xb0, 0xff, 0xd9, 0xf7, 0x1c, 0x0b, 0x1c, 0x33, 0x1c, 0x27,
+ 0x8c, 0xd1, 0x7a, 0x30, 0xda, 0xae, 0x20, 0x9b, 0x90, 0x72, 0xa5, 0x65,
+ 0x8e, 0x70, 0x1d, 0xa7, 0x98, 0xcf, 0xee, 0xb5, 0xeb, 0x29, 0x3f, 0xe1,
+ 0x3e, 0x69, 0x1b, 0x08, 0x39, 0x1c, 0x1b, 0x75, 0x14, 0xeb, 0x11, 0x6c,
+ 0xa3, 0x58, 0xd1, 0x2c, 0x2b, 0x49, 0x97, 0x0d, 0xfd, 0x9d, 0x0c, 0xf1,
+ 0x96, 0x61, 0x94, 0xed, 0x5a, 0xc2, 0x95, 0x2a, 0x62, 0xce, 0x21, 0xd9,
+ 0x60, 0x35, 0xea, 0xd4, 0xb8, 0xf5, 0x7b, 0xb1, 0x9a, 0xee, 0x17, 0x06,
+ 0xea, 0x1c, 0x9e, 0x3f, 0x27, 0x67, 0x62, 0x11, 0x8a, 0x33, 0xe6, 0xb1,
+ 0xdc, 0x67, 0xf0, 0x91, 0x44, 0x9c, 0x79, 0xb3, 0x58, 0x9d, 0x81, 0x38,
+ 0x48, 0x7b, 0xa1, 0x81, 0x73, 0xd7, 0xc0, 0x7c, 0xc7, 0x3a, 0x76, 0x88,
+ 0x7a, 0x8f, 0xd1, 0x00, 0xaa, 0xb9, 0x2a, 0x02, 0x8e, 0xa5, 0xef, 0xc5,
+ 0x51, 0xaf, 0x4e, 0x11, 0x52, 0x17, 0x2b, 0x76, 0xcf, 0x13, 0xbd, 0x84,
+ 0xcd, 0xdb, 0x53, 0x70, 0x34, 0xb4, 0x19, 0x7f, 0x43, 0xa3, 0x9b, 0x29,
+ 0xfe, 0xe7, 0x38, 0x11, 0x51, 0xda, 0x0d, 0xfd, 0x69, 0x5b, 0xa3, 0x3e,
+ 0x2a, 0xe5, 0xd6, 0x94, 0x81, 0x29, 0x9b, 0x70, 0x74, 0x63, 0x10, 0x31,
+ 0x0b, 0xba, 0xee, 0x58, 0x83, 0x07, 0x30, 0xc0, 0xf8, 0x37, 0x3a, 0x9f,
+ 0x7a, 0x25, 0x8d, 0x89, 0x31, 0xbb, 0x06, 0xd9, 0x9b, 0x05, 0x22, 0x4e,
+ 0x82, 0xce, 0x16, 0x42, 0xce, 0x7b, 0x66, 0x1d, 0x91, 0x7d, 0xd7, 0xde,
+ 0x43, 0xfa, 0x8a, 0xf9, 0xb5, 0x0e, 0x8f, 0x59, 0x76, 0x09, 0x77, 0x11,
+ 0x56, 0xa7, 0x21, 0x9a, 0xdf, 0x4c, 0xf3, 0x8f, 0x92, 0xec, 0x5c, 0xdc,
+ 0xbb, 0x87, 0xd6, 0xb7, 0x38, 0xd6, 0xf4, 0xf3, 0xd8, 0x4e, 0x3a, 0x70,
+ 0x8d, 0xe7, 0x31, 0x3e, 0xf3, 0x42, 0x3e, 0x33, 0xf5, 0x78, 0x8e, 0x2b,
+ 0x1b, 0x3f, 0xcb, 0xd3, 0xde, 0x09, 0x64, 0xb7, 0xdb, 0x10, 0x13, 0xf6,
+ 0x6e, 0xc2, 0x2f, 0xa8, 0x8f, 0x3a, 0x56, 0xff, 0x14, 0xa0, 0x44, 0x9c,
+ 0x9d, 0x28, 0xc5, 0x80, 0x47, 0x0b, 0x96, 0x7b, 0x8f, 0x62, 0x0e, 0x26,
+ 0x08, 0x13, 0x9f, 0x21, 0x4c, 0xbf, 0xab, 0x7d, 0xda, 0x8c, 0x83, 0xb1,
+ 0x7e, 0x54, 0xbc, 0xb4, 0x5b, 0x41, 0xc7, 0x62, 0xea, 0x4b, 0x54, 0x4b,
+ 0xae, 0xb1, 0xf9, 0xbe, 0x7c, 0x79, 0x7d, 0x05, 0x2f, 0xff, 0x6f, 0x39,
+ 0x69, 0x92, 0xc5, 0xaa, 0x79, 0x69, 0xf5, 0x3d, 0x8d, 0x3f, 0x93, 0xd9,
+ 0x18, 0xfb, 0x22, 0x42, 0xb5, 0xf8, 0x97, 0xf5, 0x28, 0x39, 0x49, 0xf2,
+ 0x37, 0x75, 0x07, 0x75, 0x8e, 0x19, 0xf2, 0x65, 0xf6, 0x8d, 0x3c, 0x44,
+ 0x7d, 0x9a, 0xf2, 0x2a, 0xc6, 0x7e, 0xe1, 0xfb, 0x3d, 0x19, 0x6f, 0x38,
+ 0x41, 0xba, 0xa9, 0xe8, 0x4a, 0xa3, 0x5e, 0x71, 0xac, 0xb3, 0x63, 0x74,
+ 0xe6, 0x16, 0xa7, 0x1e, 0xe7, 0x1a, 0xb8, 0x36, 0x46, 0xc5, 0x0f, 0x46,
+ 0xcd, 0x1e, 0xc2, 0xc3, 0xab, 0xee, 0x21, 0x1c, 0x75, 0x9f, 0x50, 0xd1,
+ 0x4b, 0x67, 0xb7, 0xda, 0xc8, 0x07, 0x84, 0x4d, 0x12, 0x6d, 0xd3, 0x66,
+ 0x02, 0xd5, 0xf3, 0x5e, 0x90, 0x71, 0xcb, 0x72, 0xe3, 0xca, 0xc7, 0x32,
+ 0x95, 0xe6, 0x18, 0xdf, 0x80, 0x70, 0x5c, 0x20, 0x94, 0x1e, 0xf2, 0x6c,
+ 0x4b, 0x77, 0x2a, 0xd4, 0xa7, 0x1f, 0x62, 0x1f, 0x11, 0x7e, 0x7b, 0x59,
+ 0xe6, 0xbe, 0xc2, 0xba, 0x6d, 0x9f, 0xd5, 0x73, 0x2d, 0xc7, 0x15, 0xfd,
+ 0x96, 0x73, 0xd8, 0xde, 0x87, 0xa8, 0x8e, 0x77, 0x2d, 0xe9, 0xdc, 0x3e,
+ 0xa8, 0x0c, 0x49, 0x63, 0x25, 0xfb, 0x93, 0x2e, 0x37, 0xb5, 0x9e, 0xaf,
+ 0xb5, 0xa8, 0x73, 0x1c, 0xaf, 0x0f, 0x45, 0x45, 0xfd, 0x63, 0xae, 0xd7,
+ 0x53, 0x5f, 0xa3, 0xb3, 0x9c, 0x4c, 0xf1, 0x19, 0x38, 0xc7, 0x8e, 0xe3,
+ 0x8a, 0xd2, 0xed, 0xc4, 0x1b, 0xa0, 0xfd, 0xa1, 0x51, 0xbc, 0x41, 0x52,
+ 0x9f, 0x39, 0xd7, 0x35, 0x25, 0x8d, 0x06, 0x96, 0x4f, 0xb6, 0x1e, 0x65,
+ 0x5b, 0xf3, 0xdd, 0xb2, 0x6a, 0x6f, 0xe6, 0xe7, 0xf5, 0x74, 0xe9, 0x8e,
+ 0xb1, 0xff, 0x50, 0x5f, 0xe7, 0xb0, 0x4d, 0x21, 0x6a, 0x9c, 0x4e, 0x63,
+ 0x81, 0xd8, 0x21, 0xdd, 0x44, 0xb5, 0x86, 0x45, 0xc5, 0x84, 0xb7, 0x9e,
+ 0xf7, 0xfe, 0xf4, 0xfa, 0x26, 0xf1, 0xce, 0x9e, 0xdf, 0xa5, 0x67, 0x2f,
+ 0x46, 0x7a, 0x9f, 0xa2, 0x1c, 0xd2, 0x9c, 0x7e, 0x99, 0x6c, 0xe4, 0x18,
+ 0x83, 0xf2, 0x8a, 0xbd, 0x56, 0xe6, 0x1a, 0x39, 0xd6, 0xe0, 0x26, 0x48,
+ 0xce, 0xae, 0xc7, 0x7e, 0x75, 0x8e, 0xab, 0xdb, 0xa5, 0x9c, 0xb0, 0xd7,
+ 0x90, 0x2d, 0x58, 0x4e, 0xd5, 0x16, 0x7b, 0x66, 0x6d, 0xd3, 0x5e, 0xf1,
+ 0x5f, 0xc1, 0x3b, 0x83, 0x16, 0x72, 0xde, 0xc0, 0x4b, 0x79, 0xa5, 0x89,
+ 0x6e, 0x2b, 0xe8, 0xb3, 0x05, 0x7e, 0xda, 0x43, 0xfa, 0x5d, 0x49, 0x58,
+ 0x65, 0x91, 0x35, 0xdd, 0x1a, 0x58, 0x2f, 0x31, 0x77, 0x9a, 0x82, 0xe3,
+ 0xbc, 0xd4, 0xda, 0x55, 0x84, 0xaf, 0xe0, 0x1e, 0xc5, 0xb6, 0x57, 0xf0,
+ 0x32, 0xf1, 0xad, 0xb8, 0xc2, 0x32, 0x5a, 0x05, 0xf5, 0xb5, 0xbe, 0xa5,
+ 0xe9, 0xe0, 0x2f, 0x63, 0x8f, 0xcf, 0x90, 0xf3, 0x74, 0xe0, 0x18, 0xec,
+ 0x22, 0xdf, 0xe5, 0x56, 0x2a, 0x48, 0x2d, 0x06, 0x61, 0x8d, 0xa8, 0xd8,
+ 0xba, 0x9b, 0xfd, 0xff, 0x3d, 0x9a, 0x67, 0xbe, 0xce, 0x66, 0x1d, 0xd6,
+ 0xaa, 0xc3, 0x74, 0xb1, 0x24, 0x2c, 0x4a, 0xf6, 0xe0, 0xbd, 0xaa, 0x72,
+ 0xaa, 0x32, 0xa2, 0x62, 0x72, 0x94, 0x79, 0x59, 0x17, 0xaa, 0xcd, 0x1c,
+ 0x2b, 0x29, 0x8e, 0x8f, 0x8f, 0x65, 0x47, 0x3a, 0x1a, 0x43, 0x2d, 0xaf,
+ 0x89, 0x0a, 0x7d, 0x0f, 0xcb, 0x85, 0x60, 0x3b, 0xc6, 0x48, 0xff, 0xf6,
+ 0xf4, 0xe5, 0xb3, 0xfa, 0xff, 0xb1, 0x5e, 0xc1, 0x71, 0x51, 0x71, 0xd4,
+ 0xdb, 0xbb, 0x62, 0xa3, 0x49, 0xb2, 0xf5, 0x44, 0xaa, 0xca, 0xf3, 0x38,
+ 0xf1, 0x70, 0x9c, 0x7d, 0x66, 0x4f, 0x22, 0xea, 0x15, 0x8f, 0xe4, 0xe9,
+ 0x92, 0x6a, 0x29, 0xd7, 0xd7, 0x52, 0x9e, 0x3c, 0x49, 0xbd, 0x69, 0x7f,
+ 0xb1, 0x57, 0x6c, 0xcb, 0xeb, 0xd4, 0xa7, 0x96, 0x8b, 0xad, 0x79, 0x8b,
+ 0x71, 0xd1, 0x6c, 0x9f, 0xaa, 0xbc, 0x8b, 0xda, 0x52, 0xfa, 0xe4, 0x3b,
+ 0xa2, 0x48, 0x4e, 0x77, 0xd0, 0x37, 0x7f, 0xf8, 0x41, 0xa9, 0x58, 0xfc,
+ 0x3e, 0xc8, 0x3a, 0x76, 0x22, 0x10, 0xe9, 0xe9, 0x59, 0x12, 0x40, 0xbd,
+ 0x85, 0xbe, 0x66, 0xc2, 0x07, 0x57, 0x7a, 0x35, 0xdd, 0x80, 0x51, 0x6a,
+ 0x6f, 0xac, 0xf8, 0x89, 0xf3, 0x0e, 0x6a, 0xad, 0x83, 0x5c, 0x0d, 0xd5,
+ 0x91, 0x6b, 0xba, 0x43, 0xda, 0xd1, 0xee, 0xde, 0x96, 0xf6, 0xc9, 0xa6,
+ 0x5c, 0xad, 0x73, 0x7d, 0x4b, 0xdb, 0xa4, 0xdb, 0xb2, 0x70, 0x08, 0xf8,
+ 0xf2, 0x90, 0x0e, 0xcd, 0xb9, 0xd1, 0x0d, 0x74, 0x23, 0xa7, 0x52, 0x5c,
+ 0xec, 0xe8, 0xb6, 0x7a, 0xa6, 0xc4, 0x4d, 0x37, 0x91, 0x1e, 0x2d, 0x9d,
+ 0x93, 0x86, 0xb1, 0x39, 0xf3, 0xc0, 0x4d, 0x81, 0x29, 0xee, 0x2f, 0x1b,
+ 0x06, 0xf7, 0xf1, 0x7b, 0x33, 0xba, 0x9b, 0x9e, 0xd0, 0xf1, 0xc0, 0xb2,
+ 0xee, 0x41, 0x0c, 0xe4, 0x1f, 0x40, 0x7f, 0x9e, 0xdf, 0x3b, 0x69, 0x18,
+ 0xe1, 0x1a, 0x5f, 0xe0, 0x77, 0x4e, 0x0f, 0x35, 0x30, 0x6e, 0xdc, 0x5e,
+ 0x56, 0x71, 0xed, 0x10, 0xcf, 0x99, 0xcd, 0xef, 0xa3, 0xca, 0xfb, 0x59,
+ 0x7c, 0x9f, 0xd4, 0x93, 0x6b, 0x1e, 0xb2, 0x81, 0x61, 0x29, 0x95, 0x0c,
+ 0xdf, 0x63, 0x4e, 0x13, 0xd6, 0xe3, 0xbd, 0x7f, 0x4e, 0xbd, 0x71, 0x2e,
+ 0xbf, 0x0b, 0x63, 0xca, 0x86, 0x87, 0x79, 0xee, 0xd4, 0xec, 0xdc, 0xbb,
+ 0x34, 0x07, 0x71, 0x92, 0xea, 0xfa, 0x74, 0x25, 0x2f, 0xb2, 0xb5, 0xc3,
+ 0x1a, 0xfe, 0xa8, 0xc0, 0x3c, 0x33, 0xb3, 0x3c, 0x3f, 0x21, 0x9e, 0x04,
+ 0x56, 0xc4, 0xb8, 0x76, 0x53, 0xce, 0xec, 0xae, 0xbe, 0x2b, 0x93, 0xf2,
+ 0x25, 0xfb, 0xc3, 0x68, 0xe5, 0x5d, 0x59, 0x54, 0x68, 0x8f, 0xd1, 0x33,
+ 0x61, 0x95, 0x50, 0x2a, 0x2a, 0x42, 0x8f, 0xf1, 0xfa, 0x57, 0x53, 0x95,
+ 0xf5, 0xc7, 0x52, 0xbc, 0xfe, 0xd7, 0xd7, 0xa8, 0xd9, 0xc8, 0x30, 0xdd,
+ 0xa9, 0x0a, 0xff, 0x24, 0x77, 0x34, 0x56, 0x64, 0x57, 0xd6, 0x7d, 0x6f,
+ 0x76, 0xdd, 0x41, 0x5a, 0xb7, 0x8f, 0x62, 0x8c, 0xd7, 0xb2, 0x9e, 0x1c,
+ 0xa3, 0xd5, 0xf7, 0x86, 0x49, 0x71, 0x80, 0x7a, 0xf5, 0x81, 0x92, 0x2a,
+ 0xf6, 0x52, 0x1d, 0x1c, 0xcf, 0x13, 0x36, 0xf2, 0xde, 0x05, 0x52, 0xcd,
+ 0x2f, 0x7f, 0x23, 0x56, 0xf1, 0x21, 0xf7, 0xd5, 0x69, 0xea, 0xab, 0xed,
+ 0x54, 0xdf, 0x55, 0x4f, 0xa7, 0xb0, 0x73, 0x84, 0xea, 0xbb, 0xc0, 0x49,
+ 0xaf, 0xbe, 0x1c, 0x41, 0x7b, 0x89, 0xfb, 0x80, 0x25, 0xce, 0x15, 0x8c,
+ 0x5c, 0x33, 0xc9, 0x6e, 0x29, 0x57, 0x6a, 0x03, 0xf5, 0x82, 0x2c, 0xf5,
+ 0x64, 0xf1, 0x62, 0x89, 0x7f, 0x52, 0xf1, 0x8c, 0xf3, 0x19, 0xb2, 0x62,
+ 0x4e, 0xbb, 0x8b, 0xfa, 0x76, 0x97, 0x71, 0xec, 0xc0, 0xf3, 0xc2, 0x9a,
+ 0x3e, 0x27, 0xb2, 0xb7, 0x36, 0xe3, 0x41, 0xfc, 0x3c, 0x95, 0x5d, 0x11,
+ 0xa5, 0x6f, 0xc2, 0xcc, 0x86, 0xc6, 0xef, 0x48, 0xbb, 0xdb, 0x7a, 0x36,
+ 0x88, 0x36, 0xaa, 0x37, 0x6d, 0xee, 0x16, 0xb4, 0x51, 0xcf, 0xb7, 0xb5,
+ 0xc3, 0x25, 0x5b, 0x7b, 0xa3, 0x54, 0xb5, 0x03, 0xc7, 0x29, 0xdb, 0x80,
+ 0x42, 0xdf, 0xb1, 0xb2, 0x0b, 0x04, 0xf5, 0x55, 0xea, 0xbb, 0xc3, 0xd4,
+ 0xb3, 0x2b, 0xf7, 0xce, 0x30, 0xe1, 0x16, 0xde, 0x7b, 0xdd, 0xec, 0xbb,
+ 0x96, 0x7f, 0x90, 0x95, 0x1e, 0xf5, 0x0a, 0xd9, 0x83, 0xcf, 0xfc, 0xa3,
+ 0x48, 0x65, 0xfc, 0x4c, 0x6c, 0xf6, 0xff, 0xf9, 0x21, 0x9c, 0x42, 0xf7,
+ 0xc8, 0x21, 0x81, 0x1d, 0x6d, 0x95, 0x58, 0xee, 0xe4, 0xf7, 0x98, 0xde,
+ 0x7b, 0xb7, 0x2a, 0x4f, 0xc5, 0x86, 0x0a, 0xe1, 0x99, 0x43, 0xe5, 0xac,
+ 0xb8, 0x26, 0x8f, 0x01, 0xea, 0x89, 0xd9, 0x20, 0xf1, 0x5e, 0x53, 0xea,
+ 0x15, 0xcb, 0xf3, 0x96, 0xb1, 0x89, 0x74, 0xdd, 0xa2, 0x77, 0xea, 0xe3,
+ 0x84, 0x21, 0x68, 0x3f, 0x23, 0x4c, 0xf1, 0xaf, 0x39, 0x73, 0xb1, 0x7d,
+ 0x36, 0x76, 0x28, 0x1f, 0x28, 0x7f, 0x06, 0xc5, 0x82, 0x49, 0xfe, 0xa9,
+ 0x7b, 0xb1, 0x5b, 0xd1, 0xe3, 0x9c, 0xdc, 0x76, 0x33, 0xcf, 0x5f, 0x31,
+ 0x6b, 0xfb, 0xa6, 0x38, 0xed, 0x49, 0xbf, 0x47, 0x66, 0xcf, 0xff, 0x7f,
+ 0xad, 0xbd, 0xf6, 0x92, 0xff, 0xb9, 0x66, 0x86, 0xce, 0xc9, 0x18, 0x08,
+ 0x6e, 0xdc, 0x61, 0xfc, 0x33, 0x6f, 0xd6, 0xe7, 0xd4, 0x15, 0xa3, 0x03,
+ 0xb8, 0x71, 0x31, 0xdd, 0x7c, 0xe9, 0x0e, 0xb6, 0x8d, 0x7c, 0x95, 0x1c,
+ 0x66, 0xbd, 0xcf, 0x93, 0xde, 0xd0, 0x6a, 0x9c, 0xb3, 0xb8, 0x7c, 0xa8,
+ 0xb5, 0x3f, 0x2c, 0xcc, 0xe4, 0x90, 0x30, 0xfb, 0xa8, 0xbe, 0xd9, 0x93,
+ 0x30, 0x9b, 0x17, 0x08, 0xd3, 0x58, 0x0b, 0xb6, 0xc9, 0x79, 0xb4, 0x95,
+ 0xf8, 0xfb, 0x2c, 0x2c, 0xf2, 0x6b, 0xdf, 0x70, 0x00, 0x4a, 0xfa, 0x03,
+ 0xb2, 0x2b, 0xe1, 0x35, 0xd1, 0x4c, 0xb9, 0xc4, 0xb1, 0x77, 0x1e, 0x9b,
+ 0xf3, 0xd0, 0x5a, 0x88, 0xe7, 0x2a, 0xaa, 0xd1, 0xad, 0xc3, 0xe6, 0x59,
+ 0xc2, 0x9c, 0x83, 0x5f, 0x0a, 0xb4, 0x26, 0xfb, 0x61, 0x0e, 0x6c, 0x41,
+ 0xe7, 0xf4, 0x51, 0x61, 0x66, 0xcf, 0x12, 0x16, 0x0c, 0xa7, 0x2b, 0x32,
+ 0x17, 0xcd, 0xca, 0x4c, 0x32, 0x3e, 0xf6, 0x72, 0x88, 0x30, 0x74, 0xfa,
+ 0x6f, 0xe5, 0xb4, 0x67, 0xb3, 0xe0, 0xac, 0xfe, 0x4b, 0xe2, 0x15, 0x1f,
+ 0x3c, 0x37, 0x6b, 0x1f, 0x42, 0x24, 0xb5, 0xcc, 0xc7, 0xf7, 0x30, 0x88,
+ 0x35, 0xf9, 0x2f, 0xe2, 0x61, 0xc2, 0x43, 0x59, 0x6f, 0x7d, 0x2f, 0x72,
+ 0x25, 0x88, 0xb5, 0xf9, 0xe9, 0xf0, 0x51, 0x3b, 0x88, 0xa2, 0x27, 0xe7,
+ 0x7a, 0x1a, 0xeb, 0xa3, 0x0f, 0xdb, 0x8c, 0xef, 0xe4, 0x37, 0xd3, 0x73,
+ 0xd6, 0xe3, 0xeb, 0xcf, 0xa3, 0x27, 0x9c, 0x22, 0xdc, 0xe6, 0xf1, 0x79,
+ 0xf7, 0x75, 0xe2, 0x59, 0xce, 0x73, 0x23, 0xfc, 0xae, 0x61, 0x75, 0xa6,
+ 0xcd, 0x78, 0xd8, 0xbb, 0x23, 0x1a, 0x58, 0x53, 0x32, 0x70, 0x07, 0xd5,
+ 0xd5, 0xa2, 0x57, 0x57, 0x7f, 0x85, 0xe7, 0x15, 0xe2, 0x5b, 0x46, 0x7c,
+ 0x9b, 0xbc, 0x31, 0x03, 0xcb, 0x4b, 0xc7, 0xbd, 0x58, 0x51, 0x1d, 0xf6,
+ 0x03, 0xdb, 0x9e, 0xf1, 0x68, 0xf5, 0xae, 0xc6, 0x3e, 0xc9, 0x8a, 0x47,
+ 0xf3, 0xbd, 0x62, 0x67, 0x3e, 0x4a, 0xfb, 0xb9, 0x62, 0x24, 0xa3, 0x8c,
+ 0xc6, 0x20, 0xb1, 0x2c, 0x7d, 0x35, 0xd5, 0x19, 0x2b, 0x69, 0xd1, 0xb5,
+ 0x65, 0x6d, 0x72, 0x2e, 0x61, 0xa7, 0x25, 0x58, 0x97, 0x0c, 0x51, 0xff,
+ 0xfe, 0x16, 0xee, 0xd4, 0xc3, 0xe8, 0x4f, 0xde, 0x0b, 0xdc, 0x58, 0x43,
+ 0xfd, 0xf6, 0x61, 0x0f, 0xb3, 0x86, 0x68, 0xdf, 0x1a, 0xaa, 0x0d, 0x77,
+ 0x79, 0x7a, 0x4f, 0xb1, 0xae, 0x74, 0xce, 0xe5, 0x62, 0x84, 0xea, 0x7d,
+ 0xa2, 0x82, 0x01, 0x36, 0x66, 0x8a, 0xfc, 0x3d, 0xb3, 0xb1, 0xcb, 0xb3,
+ 0xf3, 0x4f, 0x36, 0xda, 0xa5, 0x5f, 0xc4, 0x2b, 0x3d, 0x75, 0x29, 0xb2,
+ 0x8d, 0xdd, 0x58, 0x9f, 0xec, 0xc1, 0x1c, 0x6b, 0x39, 0xbe, 0xaa, 0xbb,
+ 0x88, 0x5a, 0x63, 0xb8, 0xdb, 0x93, 0xc1, 0xf2, 0xbc, 0xbf, 0x6d, 0x10,
+ 0x4d, 0x13, 0xc8, 0xf9, 0xbc, 0xfb, 0x50, 0xe5, 0xdd, 0x42, 0x4e, 0x09,
+ 0x62, 0xd3, 0x2e, 0xfe, 0x56, 0x71, 0x77, 0xa6, 0xf2, 0xce, 0x70, 0x78,
+ 0x2c, 0x88, 0xa1, 0x5d, 0xd4, 0xfb, 0x52, 0x21, 0xb8, 0x8d, 0x9f, 0x96,
+ 0xdd, 0x4f, 0xb2, 0x2b, 0xf7, 0xef, 0xaf, 0x91, 0x5d, 0x67, 0x82, 0x41,
+ 0x34, 0x13, 0x0c, 0x4b, 0x10, 0x4f, 0xc3, 0x54, 0x1d, 0x9a, 0xc7, 0xf8,
+ 0xef, 0x23, 0x07, 0xc5, 0x7d, 0xa5, 0x0a, 0xcf, 0x46, 0xfe, 0x9b, 0x4a,
+ 0x58, 0xc1, 0x7c, 0x8b, 0xd5, 0x55, 0x89, 0x47, 0xa3, 0x7b, 0x5c, 0x2d,
+ 0xe6, 0x8f, 0xd5, 0xd1, 0x47, 0x47, 0x6c, 0x82, 0x26, 0xa6, 0x96, 0x8b,
+ 0xaf, 0xe7, 0x93, 0x88, 0xd1, 0xfd, 0x32, 0xee, 0x54, 0xd6, 0xdf, 0x53,
+ 0xfa, 0xbc, 0xf3, 0x07, 0xff, 0xbb, 0xb2, 0x6f, 0x01, 0x8e, 0xea, 0xbc,
+ 0xd2, 0xfc, 0x6e, 0x3f, 0xa4, 0xd6, 0x93, 0xab, 0x27, 0x2d, 0x1e, 0xa6,
+ 0x9b, 0xbe, 0x2d, 0xb5, 0xad, 0x4e, 0xb8, 0x0d, 0xa2, 0x90, 0x3d, 0xbd,
+ 0xa5, 0x06, 0x0b, 0x5b, 0x04, 0x63, 0xcb, 0xb6, 0x32, 0x83, 0x67, 0x53,
+ 0x63, 0x05, 0x03, 0xc6, 0xd8, 0x33, 0x91, 0x09, 0x35, 0x25, 0xef, 0xce,
+ 0x44, 0x77, 0x25, 0x10, 0x02, 0xf5, 0x4b, 0x12, 0x04, 0x98, 0xaa, 0x2d,
+ 0x37, 0x92, 0x40, 0xd8, 0x69, 0x49, 0x78, 0x92, 0xec, 0x90, 0x4c, 0xd5,
+ 0x58, 0x01, 0x61, 0x20, 0x04, 0xe3, 0xec, 0x4e, 0x6d, 0x91, 0x5d, 0xcf,
+ 0x98, 0xc2, 0x06, 0x9c, 0x18, 0x3f, 0x33, 0x59, 0x8b, 0x78, 0xe2, 0xbb,
+ 0xdf, 0xb9, 0xdd, 0x0d, 0x82, 0x21, 0x99, 0x1a, 0x57, 0x75, 0x89, 0xee,
+ 0x7b, 0xff, 0xff, 0x9e, 0xff, 0xfc, 0xe7, 0x7c, 0xe7, 0x3b, 0xe7, 0xfc,
+ 0xb7, 0x4c, 0x2e, 0x2d, 0xfb, 0xb5, 0x08, 0xc5, 0xda, 0x94, 0xf9, 0x42,
+ 0x96, 0xe3, 0x48, 0x1c, 0xed, 0xbe, 0xd9, 0x8f, 0x11, 0x99, 0x84, 0xcb,
+ 0x41, 0xad, 0x08, 0x4b, 0x9e, 0xc7, 0x1f, 0xad, 0x3c, 0x51, 0x64, 0x90,
+ 0xb9, 0x0b, 0x91, 0x3f, 0x2c, 0x73, 0x17, 0x21, 0xef, 0xa6, 0x2c, 0xf2,
+ 0x1c, 0xa6, 0x5c, 0x13, 0x12, 0x5b, 0xe5, 0x79, 0xc7, 0x95, 0xa1, 0xb4,
+ 0xc8, 0x90, 0x7b, 0xee, 0x59, 0x73, 0xa3, 0x5a, 0xc4, 0x18, 0x3e, 0x62,
+ 0x6e, 0x62, 0x5e, 0xe2, 0x5f, 0xfa, 0x86, 0x99, 0x6a, 0x93, 0xb5, 0xba,
+ 0xcd, 0xbd, 0x09, 0x27, 0xfa, 0xa9, 0xb7, 0xad, 0xa1, 0xa3, 0xc2, 0x67,
+ 0xb3, 0xff, 0xe5, 0xf4, 0xf6, 0x97, 0xd4, 0xdb, 0xa9, 0xec, 0x3e, 0x1e,
+ 0x57, 0x4e, 0xde, 0x8c, 0xf5, 0x22, 0xa3, 0xc8, 0xa5, 0xa0, 0x42, 0x13,
+ 0xb9, 0x6c, 0x28, 0x67, 0xdc, 0xac, 0xa0, 0x7e, 0xca, 0x2d, 0x99, 0x9a,
+ 0x95, 0x9f, 0x47, 0xa1, 0xce, 0x21, 0x17, 0x2c, 0x9b, 0xc8, 0xc8, 0x35,
+ 0x45, 0xfd, 0x5c, 0xb8, 0x69, 0x13, 0xb3, 0xf5, 0x2c, 0x74, 0x46, 0x7c,
+ 0xfa, 0xe2, 0x4b, 0x3b, 0x92, 0x32, 0xaf, 0x5d, 0xf2, 0x04, 0x2b, 0xdf,
+ 0xb3, 0xd1, 0x9e, 0x56, 0x45, 0x33, 0x3a, 0xb0, 0x59, 0x7b, 0x20, 0x3e,
+ 0x20, 0xeb, 0xcf, 0xad, 0xbd, 0x59, 0x79, 0x3a, 0x2a, 0xe3, 0x35, 0x2c,
+ 0xb2, 0xc6, 0x59, 0xfb, 0xce, 0x71, 0x6f, 0x73, 0x5c, 0x80, 0x63, 0x32,
+ 0xb6, 0xe9, 0x49, 0x7d, 0x26, 0x7e, 0xcd, 0x7d, 0x3a, 0xae, 0x74, 0xf2,
+ 0x99, 0xb0, 0xf6, 0xf6, 0xfd, 0xac, 0xaf, 0x1f, 0xa7, 0x6f, 0xf2, 0x37,
+ 0xa7, 0x8d, 0xf6, 0x5e, 0x04, 0xc7, 0xb0, 0xcb, 0xaa, 0x49, 0xc8, 0xdc,
+ 0xcf, 0x45, 0xcb, 0x51, 0x70, 0x24, 0x37, 0x36, 0x13, 0xc3, 0x33, 0xbd,
+ 0xac, 0x9c, 0x3f, 0x0a, 0x3e, 0x0a, 0x76, 0x1b, 0x4a, 0xe4, 0x66, 0x3f,
+ 0x4a, 0x6a, 0x38, 0xd2, 0xa7, 0xcb, 0xa7, 0x3c, 0x52, 0xef, 0x53, 0x88,
+ 0x19, 0xcc, 0x07, 0xd5, 0x55, 0x1e, 0x07, 0x71, 0x6e, 0x13, 0xbe, 0x20,
+ 0xb7, 0x8d, 0x04, 0x9c, 0x96, 0x0f, 0x4b, 0xcd, 0x2f, 0x1f, 0x19, 0x0c,
+ 0x02, 0x86, 0xa3, 0x8c, 0xbb, 0x5c, 0x2b, 0x63, 0x3d, 0xba, 0xd3, 0x5f,
+ 0x98, 0x53, 0x95, 0xcc, 0xd9, 0xb5, 0x9b, 0x35, 0x22, 0xfa, 0x9d, 0x69,
+ 0x8e, 0xf0, 0x5a, 0x6f, 0x3a, 0xb7, 0x4f, 0xe4, 0x10, 0xe4, 0x68, 0xcf,
+ 0x68, 0xbf, 0x35, 0x37, 0xdc, 0x76, 0x6f, 0x0e, 0x9b, 0x73, 0x79, 0xa9,
+ 0x60, 0x73, 0x31, 0x7a, 0xf7, 0x7a, 0x93, 0x29, 0x54, 0x22, 0xa9, 0xd9,
+ 0xe6, 0xd3, 0x4b, 0x98, 0xf5, 0x7b, 0xfb, 0x9a, 0x61, 0xe5, 0xeb, 0x9e,
+ 0x14, 0xfa, 0x2b, 0xc4, 0x8f, 0x9c, 0x5a, 0xbd, 0xa7, 0xcc, 0x56, 0x2e,
+ 0xb2, 0x5b, 0x52, 0xd9, 0x07, 0x0b, 0xb0, 0x89, 0xb9, 0x76, 0xaa, 0x95,
+ 0x98, 0x35, 0x68, 0xb4, 0x70, 0x7a, 0x57, 0x61, 0x38, 0xd5, 0xf9, 0x35,
+ 0xbf, 0x97, 0xf1, 0x10, 0xc8, 0x67, 0xde, 0x7f, 0x09, 0x59, 0x4c, 0x1b,
+ 0xf4, 0x1a, 0x36, 0x9b, 0x8c, 0xff, 0xcc, 0x34, 0xda, 0x64, 0xac, 0xcc,
+ 0xc1, 0x67, 0xff, 0x1b, 0x5f, 0xf0, 0x50, 0x4f, 0x87, 0x2b, 0xa4, 0x7e,
+ 0xa6, 0xd6, 0x92, 0xab, 0x0f, 0x16, 0xa3, 0x88, 0xb9, 0x6b, 0x7f, 0x95,
+ 0xaf, 0x43, 0xb7, 0x15, 0xe2, 0xfc, 0x57, 0xfe, 0x13, 0x52, 0x55, 0x79,
+ 0x70, 0xd5, 0x02, 0x0f, 0xc6, 0x6d, 0xb0, 0xd5, 0x12, 0x7b, 0x1b, 0x80,
+ 0xe6, 0x09, 0xee, 0xdb, 0xa0, 0x82, 0xa7, 0x92, 0x36, 0x3c, 0x9a, 0xb4,
+ 0x63, 0x6d, 0x12, 0xdf, 0x59, 0x04, 0x4c, 0xd7, 0xc0, 0xdf, 0x3e, 0xa3,
+ 0x60, 0x6b, 0x29, 0xfc, 0xad, 0x31, 0xc5, 0xdf, 0xb2, 0x96, 0x39, 0xd3,
+ 0x9a, 0x09, 0xe2, 0x19, 0xef, 0x75, 0x0e, 0x70, 0x5f, 0x07, 0xec, 0xa8,
+ 0x19, 0xc0, 0x3d, 0xf9, 0x40, 0x83, 0x13, 0xfe, 0x19, 0xc6, 0x99, 0x72,
+ 0x07, 0xfc, 0x53, 0x97, 0xed, 0xfe, 0xce, 0x1a, 0x3b, 0x37, 0xb7, 0x56,
+ 0x64, 0x71, 0xe1, 0x31, 0xda, 0xf3, 0xa2, 0x41, 0xde, 0xcf, 0xfc, 0x5d,
+ 0x65, 0x9e, 0xf3, 0xc9, 0x9f, 0x48, 0xfd, 0x52, 0xae, 0x49, 0xef, 0x52,
+ 0x41, 0xe9, 0xa0, 0x9d, 0x18, 0x76, 0xce, 0x3c, 0x5f, 0x25, 0xf8, 0x0d,
+ 0x3c, 0x45, 0xd9, 0xdc, 0xfc, 0x4d, 0xad, 0x25, 0x37, 0x5d, 0xa1, 0x62,
+ 0xfd, 0xb0, 0xdc, 0x0b, 0x6b, 0x1e, 0x27, 0x7d, 0x2a, 0x8f, 0x3e, 0x7e,
+ 0xc4, 0xea, 0x77, 0xd9, 0xb8, 0x46, 0x3b, 0x8a, 0x06, 0x81, 0x35, 0x71,
+ 0x3c, 0x51, 0x0c, 0x7f, 0x44, 0x64, 0xac, 0x5b, 0xee, 0xe0, 0xd8, 0x62,
+ 0xb4, 0x4c, 0x64, 0xc6, 0x3d, 0x3c, 0xf1, 0xa3, 0x8a, 0x4c, 0x2d, 0xf7,
+ 0xf7, 0xf7, 0x5e, 0x7b, 0x1a, 0xfc, 0xd8, 0x94, 0xa4, 0xcd, 0xd9, 0x3c,
+ 0x18, 0xce, 0xd6, 0x54, 0x37, 0xa4, 0xbc, 0xb3, 0x7a, 0xa3, 0xff, 0xbd,
+ 0x38, 0xdb, 0x37, 0xa5, 0x2f, 0xcc, 0x70, 0x1e, 0x43, 0xd9, 0x40, 0xdd,
+ 0x0d, 0x4f, 0x9a, 0x88, 0xea, 0x26, 0xc6, 0xf9, 0x79, 0x53, 0x87, 0x51,
+ 0x44, 0x5f, 0xd8, 0x18, 0xfb, 0xd2, 0x34, 0xb2, 0xfe, 0xfc, 0x4a, 0x22,
+ 0xa0, 0x6c, 0x21, 0x57, 0x7e, 0x95, 0xf1, 0x74, 0x8c, 0x9f, 0x51, 0xe6,
+ 0x70, 0x4e, 0xca, 0x6d, 0xa3, 0x5f, 0xef, 0x4c, 0x01, 0x23, 0xcc, 0xd1,
+ 0x0f, 0x2e, 0x17, 0xfe, 0x5e, 0xc4, 0xe7, 0xd1, 0x6b, 0x78, 0x4f, 0x9a,
+ 0x9f, 0x23, 0xfc, 0x4c, 0x72, 0x4f, 0xf9, 0x3c, 0x04, 0xc6, 0x1d, 0x88,
+ 0x8c, 0x13, 0x68, 0xc7, 0x03, 0x98, 0x62, 0x0c, 0xbc, 0x31, 0xaa, 0xa2,
+ 0x64, 0xac, 0x1c, 0x1f, 0x1d, 0x26, 0x3e, 0x1e, 0xca, 0x70, 0xfe, 0x4d,
+ 0xe3, 0xd2, 0xdf, 0x92, 0xf5, 0x49, 0x1f, 0x58, 0xfc, 0xa9, 0x00, 0x63,
+ 0xa4, 0x1f, 0xd2, 0x0b, 0x7e, 0x57, 0xe7, 0xdc, 0xaa, 0xf4, 0xf1, 0x5a,
+ 0x71, 0x34, 0xea, 0xf3, 0xf4, 0xd1, 0xe6, 0x0d, 0x87, 0xf8, 0x58, 0x03,
+ 0x5e, 0x8d, 0xe6, 0x7a, 0x42, 0xbe, 0x96, 0x9f, 0x4a, 0x3d, 0x83, 0x21,
+ 0x3b, 0x4f, 0x93, 0x6b, 0xb9, 0x58, 0x2a, 0x6b, 0x96, 0xba, 0x74, 0x8e,
+ 0xb7, 0xcc, 0xfe, 0xfd, 0x8c, 0x29, 0x7d, 0xca, 0xd7, 0x26, 0xbd, 0x7d,
+ 0x29, 0xe8, 0x56, 0xac, 0x3c, 0x5c, 0xe7, 0x4d, 0x1a, 0x90, 0xfd, 0x6d,
+ 0xa0, 0x0c, 0xdf, 0xa5, 0xed, 0x07, 0x44, 0xd7, 0x8c, 0xed, 0x52, 0xef,
+ 0x2d, 0x43, 0xff, 0x40, 0x39, 0xf6, 0x0c, 0x18, 0xe8, 0x5d, 0xde, 0x86,
+ 0x33, 0x51, 0x13, 0x9b, 0x42, 0x26, 0xd6, 0x84, 0xbc, 0x81, 0x57, 0x50,
+ 0xdf, 0x78, 0x14, 0x8f, 0x91, 0x43, 0xa8, 0xd4, 0xc9, 0x37, 0xf0, 0xce,
+ 0x5e, 0x07, 0x36, 0xeb, 0x7f, 0x4c, 0x1f, 0x36, 0xcd, 0xf7, 0x96, 0x2d,
+ 0xc0, 0x70, 0xa2, 0x5e, 0xed, 0xa6, 0x7c, 0x91, 0x36, 0xee, 0x55, 0xd0,
+ 0x81, 0x67, 0xf5, 0xef, 0xf0, 0x5e, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b,
+ 0xe3, 0xa9, 0xec, 0xa5, 0x41, 0xfb, 0xca, 0xc4, 0xb2, 0x48, 0xb6, 0xce,
+ 0xbe, 0xb9, 0x41, 0x30, 0xbf, 0x18, 0xa7, 0xa9, 0xb7, 0x13, 0xc9, 0x08,
+ 0xc3, 0x2e, 0x94, 0x67, 0x1b, 0xba, 0xf0, 0x34, 0xf9, 0xc6, 0x3b, 0x24,
+ 0x02, 0xf7, 0xc7, 0x15, 0x34, 0xd6, 0xe9, 0xb8, 0x98, 0xfe, 0x06, 0xde,
+ 0x1a, 0x0d, 0xe3, 0x4d, 0xc6, 0xf4, 0x25, 0xdf, 0xf5, 0x92, 0x83, 0x7a,
+ 0x70, 0x3e, 0x1d, 0xc6, 0xb9, 0xa8, 0xb7, 0xf5, 0x05, 0x65, 0x01, 0x7e,
+ 0x9a, 0x76, 0xe0, 0xde, 0x38, 0xf0, 0x4b, 0xce, 0xe3, 0x8f, 0x3b, 0x70,
+ 0x25, 0xad, 0xe2, 0x28, 0xf7, 0xc7, 0x11, 0x5a, 0x02, 0xa3, 0xcd, 0x83,
+ 0x23, 0x43, 0x8f, 0x62, 0x2a, 0xf5, 0x28, 0x4e, 0x25, 0xdf, 0x31, 0x5d,
+ 0x9a, 0xf4, 0x75, 0x5c, 0xb8, 0xc2, 0x7c, 0x6c, 0x9a, 0xda, 0x28, 0x5e,
+ 0xd1, 0xca, 0x38, 0xaf, 0x19, 0xa2, 0xf7, 0xb7, 0xf8, 0xdb, 0xfd, 0xf1,
+ 0x46, 0x1c, 0x1c, 0xa7, 0x4a, 0x13, 0x3a, 0x12, 0x31, 0x79, 0x56, 0x03,
+ 0x62, 0xe4, 0x85, 0xfd, 0x4c, 0xdb, 0xb7, 0x86, 0xee, 0x95, 0x5c, 0x43,
+ 0x69, 0xa9, 0xed, 0xcf, 0xae, 0xa3, 0x71, 0x56, 0xcf, 0x4e, 0x72, 0x28,
+ 0xea, 0x95, 0xe3, 0xfe, 0x36, 0x11, 0xb4, 0x62, 0xd3, 0xb1, 0x9b, 0xfb,
+ 0xd1, 0xc8, 0xfd, 0xf8, 0x06, 0x2e, 0xee, 0x6d, 0xc3, 0x5b, 0xc4, 0xbb,
+ 0xd2, 0x65, 0xbe, 0x4e, 0xa7, 0xad, 0x9e, 0x73, 0xa7, 0xcd, 0x54, 0x95,
+ 0xe8, 0xb4, 0x0d, 0xbf, 0x88, 0x8a, 0x4e, 0xd3, 0xc4, 0x3f, 0x9f, 0xc7,
+ 0x6f, 0xff, 0xcb, 0x4a, 0xda, 0xb3, 0xad, 0x3b, 0x98, 0xe9, 0x41, 0x15,
+ 0xaf, 0x70, 0xe1, 0xaa, 0x25, 0x9b, 0xc8, 0xfa, 0x87, 0xe4, 0xfb, 0x85,
+ 0xb9, 0xa6, 0x4a, 0xe4, 0x33, 0xcc, 0x3c, 0x4d, 0x0b, 0xe4, 0x29, 0x12,
+ 0x67, 0x03, 0x56, 0x3d, 0xbe, 0x2e, 0xde, 0x05, 0x7b, 0xa8, 0x98, 0x79,
+ 0x98, 0x77, 0xa6, 0x03, 0x6f, 0xe1, 0xda, 0xa4, 0x0b, 0x8b, 0xe3, 0x1a,
+ 0x5e, 0x9e, 0x7c, 0x8d, 0xcf, 0xfa, 0x47, 0x5c, 0xe6, 0x77, 0x5f, 0x3c,
+ 0xe3, 0x6f, 0xdd, 0x0d, 0x6d, 0x78, 0x30, 0x2d, 0xeb, 0xcb, 0xe3, 0x83,
+ 0x74, 0x44, 0xd2, 0xb2, 0xce, 0x18, 0x7d, 0x43, 0xd6, 0x59, 0xfe, 0xef,
+ 0xac, 0xf3, 0xbf, 0x72, 0xbe, 0x05, 0xf4, 0xa5, 0x5c, 0xec, 0x28, 0xc1,
+ 0x91, 0xa4, 0x8a, 0xd3, 0x7a, 0x31, 0x2e, 0xa9, 0x52, 0x5f, 0x76, 0x31,
+ 0x86, 0x38, 0xd0, 0xcc, 0x9c, 0x71, 0x84, 0x9f, 0x8d, 0xcc, 0x7f, 0xce,
+ 0xea, 0x0e, 0x9c, 0xd2, 0x17, 0x10, 0xeb, 0xef, 0xb4, 0x61, 0xb9, 0x46,
+ 0xb2, 0x5f, 0x56, 0x8e, 0x73, 0x52, 0xff, 0xb3, 0xae, 0xbb, 0xa4, 0x2f,
+ 0x89, 0x31, 0xea, 0x2b, 0x2f, 0xf6, 0x1b, 0xf3, 0xaa, 0x85, 0x35, 0x77,
+ 0xca, 0x77, 0xe7, 0x3c, 0x12, 0x82, 0x7f, 0x69, 0x6e, 0xad, 0xca, 0xc6,
+ 0x2e, 0xe5, 0x4f, 0x2b, 0x33, 0x78, 0x21, 0x71, 0xec, 0xef, 0x72, 0xd8,
+ 0x21, 0xf9, 0x64, 0x1b, 0xe3, 0x10, 0xe3, 0xf2, 0xf1, 0x6d, 0x92, 0xe7,
+ 0xd9, 0xc2, 0xef, 0xb5, 0xad, 0xd2, 0xf2, 0x60, 0xb7, 0xf8, 0xde, 0x7b,
+ 0x2f, 0x65, 0x38, 0xfa, 0xfb, 0x2f, 0x69, 0xd6, 0xdf, 0xeb, 0x2f, 0x2d,
+ 0xb6, 0xfe, 0x7e, 0xf2, 0x92, 0x2f, 0x75, 0x2b, 0x5e, 0x65, 0x38, 0xb0,
+ 0x75, 0x6e, 0x05, 0x7d, 0xba, 0xa1, 0x3c, 0xdc, 0x20, 0x5c, 0x72, 0x36,
+ 0x8f, 0x08, 0x28, 0x67, 0xa3, 0x92, 0xa7, 0x15, 0x1a, 0xcc, 0xe3, 0x95,
+ 0x46, 0xbf, 0x46, 0x3c, 0xee, 0x42, 0xc9, 0x32, 0x0d, 0x17, 0xa8, 0x73,
+ 0xc2, 0x28, 0xed, 0xf8, 0xff, 0x20, 0xba, 0x17, 0xed, 0x85, 0x16, 0xf6,
+ 0x98, 0x66, 0x7f, 0x48, 0x6a, 0x0c, 0x32, 0xaf, 0x03, 0x1f, 0x70, 0x2f,
+ 0x7f, 0x35, 0x5a, 0x84, 0xf7, 0x53, 0x1a, 0x2e, 0xa5, 0xdb, 0xb0, 0x7b,
+ 0x32, 0xc3, 0x33, 0x4e, 0x59, 0xfc, 0x5b, 0x63, 0x8e, 0xe9, 0xc0, 0xc1,
+ 0xa8, 0x86, 0x58, 0xe2, 0x75, 0xb3, 0x40, 0xf3, 0x4d, 0xf9, 0xed, 0x0e,
+ 0x1c, 0x48, 0x4f, 0x63, 0x72, 0xe0, 0x63, 0xd3, 0xae, 0x75, 0xe1, 0xa3,
+ 0xd0, 0x34, 0x26, 0x0e, 0x49, 0x5f, 0x4f, 0x47, 0xff, 0x90, 0x86, 0xde,
+ 0x84, 0x0d, 0x7b, 0x96, 0xb7, 0xa0, 0x7f, 0xb2, 0x19, 0xc6, 0x98, 0x07,
+ 0x7b, 0xd2, 0x69, 0x4c, 0x8d, 0x4e, 0xe3, 0x4c, 0x52, 0x6b, 0x2c, 0x50,
+ 0xa6, 0x71, 0x9a, 0xcf, 0xd9, 0x91, 0x78, 0x1b, 0x06, 0xe7, 0xd8, 0x99,
+ 0x94, 0x9a, 0xa4, 0x3c, 0x67, 0x1a, 0xdd, 0xa9, 0xbb, 0xd5, 0x44, 0x28,
+ 0x4f, 0xa2, 0xa7, 0x3d, 0x53, 0xab, 0x27, 0xbe, 0xa6, 0x35, 0xa5, 0x8f,
+ 0xfb, 0x74, 0x34, 0x9d, 0xab, 0xdb, 0xdf, 0x59, 0x0b, 0xd1, 0xd1, 0x37,
+ 0xd4, 0xc2, 0x31, 0x1a, 0xba, 0x13, 0xd2, 0x1b, 0xf5, 0xf1, 0x99, 0x26,
+ 0x7e, 0xa9, 0x7b, 0xdd, 0x8b, 0xf9, 0xf7, 0xb0, 0xde, 0x89, 0x2d, 0x9c,
+ 0x6b, 0x8a, 0x79, 0x90, 0xa6, 0x78, 0x1b, 0x0d, 0xd8, 0xf1, 0x9e, 0x4e,
+ 0xce, 0x53, 0x69, 0xc7, 0xab, 0x7a, 0x09, 0x22, 0x65, 0x76, 0xd4, 0x87,
+ 0x18, 0xa7, 0xb3, 0x71, 0xfb, 0xc3, 0xa4, 0x82, 0x47, 0x89, 0xa9, 0x27,
+ 0x42, 0xf5, 0xed, 0xab, 0x85, 0xd1, 0x1d, 0x52, 0x70, 0x4d, 0xbb, 0x61,
+ 0x1a, 0x8c, 0x5d, 0x2e, 0x7f, 0x6e, 0x8f, 0x7e, 0x6d, 0x66, 0xfa, 0x9b,
+ 0x5f, 0x98, 0xb9, 0x71, 0x33, 0x94, 0xf1, 0x29, 0x8e, 0x5b, 0xbc, 0xac,
+ 0xbe, 0x53, 0xc6, 0xb9, 0x89, 0xe9, 0x32, 0x4e, 0xea, 0xd1, 0xb7, 0xc6,
+ 0xe9, 0xd8, 0x39, 0x14, 0xb1, 0xe4, 0xdd, 0x95, 0xc0, 0x52, 0x07, 0xc4,
+ 0x9f, 0xea, 0xd5, 0x2b, 0x40, 0xd7, 0xb4, 0x3e, 0x87, 0x5c, 0xc7, 0x1f,
+ 0xd8, 0x08, 0xd1, 0x95, 0xe4, 0x92, 0x6f, 0x63, 0x4f, 0x74, 0x14, 0xcc,
+ 0x27, 0x89, 0x73, 0xfe, 0xf5, 0x23, 0x48, 0xe1, 0xf9, 0x74, 0x0a, 0x2f,
+ 0x50, 0x47, 0x86, 0x75, 0x6e, 0x29, 0x8d, 0x3f, 0x8f, 0xbe, 0x8d, 0x98,
+ 0xb5, 0x67, 0x47, 0xb1, 0x21, 0xfa, 0xf7, 0x55, 0xc2, 0x11, 0x77, 0x24,
+ 0x56, 0x72, 0x7e, 0xd1, 0xab, 0xb7, 0xd5, 0xc0, 0x97, 0x9c, 0x7f, 0x25,
+ 0x7a, 0x46, 0x4c, 0xf3, 0x7b, 0x8c, 0x5f, 0x3f, 0x23, 0xbf, 0xba, 0x96,
+ 0x3d, 0x03, 0x55, 0x40, 0x7d, 0x6b, 0x56, 0x1c, 0x6b, 0xe3, 0x3e, 0x57,
+ 0x0b, 0xaf, 0x47, 0xc9, 0xb8, 0xa6, 0x2c, 0x8e, 0xc9, 0xbe, 0x93, 0x37,
+ 0x8e, 0x7b, 0xf0, 0x14, 0x39, 0x4a, 0xfe, 0xe1, 0x1f, 0x28, 0x12, 0xcb,
+ 0x6a, 0x0e, 0x91, 0xef, 0x1f, 0xf2, 0x28, 0x4b, 0xf6, 0xb9, 0xf0, 0x68,
+ 0x4c, 0xea, 0x37, 0xcd, 0xe8, 0xd9, 0xaf, 0xf1, 0x1e, 0xaf, 0x7e, 0x81,
+ 0x39, 0xe9, 0x69, 0xf8, 0x3c, 0x23, 0xe4, 0x55, 0x6e, 0x62, 0xb1, 0xe3,
+ 0x70, 0x29, 0x8a, 0x0e, 0xab, 0xb0, 0x1d, 0x2e, 0x47, 0xf1, 0x61, 0x37,
+ 0x6a, 0x18, 0xdb, 0xdc, 0xe3, 0x17, 0x31, 0xb9, 0x0f, 0x6a, 0x51, 0xf8,
+ 0x73, 0x33, 0x5f, 0x93, 0x3e, 0x5b, 0x00, 0xa5, 0xe3, 0xdb, 0x91, 0x8e,
+ 0x05, 0x51, 0x3c, 0x4e, 0x2a, 0x35, 0x7e, 0x5c, 0xa9, 0xe7, 0x33, 0x1f,
+ 0x8a, 0x69, 0x9c, 0x2b, 0xc3, 0x75, 0x56, 0x73, 0x5c, 0x5f, 0xc2, 0xbb,
+ 0x5e, 0x7a, 0x65, 0xd7, 0xf4, 0x37, 0x50, 0x30, 0x70, 0xeb, 0x2c, 0x97,
+ 0x16, 0xc2, 0x3c, 0x72, 0x91, 0xd6, 0x67, 0x91, 0x39, 0xd7, 0xf5, 0x70,
+ 0x76, 0x4d, 0x41, 0x59, 0x93, 0xb3, 0x8d, 0xb6, 0x30, 0x57, 0xea, 0x5f,
+ 0xb8, 0x4c, 0xfb, 0xb9, 0x9f, 0xf2, 0xde, 0x60, 0x6e, 0xd8, 0x19, 0x13,
+ 0xbb, 0xff, 0x81, 0x42, 0xbf, 0xc1, 0x4c, 0xaa, 0x08, 0x1f, 0xa7, 0x3c,
+ 0x8a, 0x8f, 0xeb, 0xf9, 0x0b, 0x5e, 0xff, 0x73, 0xae, 0x67, 0xc7, 0x7e,
+ 0x6f, 0xeb, 0x49, 0xc5, 0xdb, 0xbe, 0x4e, 0xf1, 0xa9, 0x3b, 0x94, 0x62,
+ 0x5c, 0x1e, 0x2d, 0xc5, 0x15, 0xc6, 0xe2, 0x1b, 0xa3, 0xe5, 0xb8, 0x3a,
+ 0x5a, 0x49, 0x5f, 0xd1, 0x38, 0x87, 0x69, 0x96, 0x68, 0x6e, 0xcc, 0xa4,
+ 0x5f, 0xc0, 0x9c, 0xd8, 0x02, 0x7c, 0x9c, 0xde, 0x82, 0xd2, 0x98, 0x70,
+ 0x76, 0x0f, 0x3e, 0xe2, 0xf5, 0x0f, 0xd3, 0x13, 0x28, 0xdc, 0xf7, 0x39,
+ 0xef, 0x31, 0xcd, 0x87, 0xb8, 0xc6, 0xab, 0xe9, 0x0e, 0x14, 0xef, 0xdb,
+ 0x06, 0xc7, 0x3e, 0xb3, 0xab, 0x27, 0x84, 0x9f, 0xda, 0xb9, 0x96, 0x6e,
+ 0xdd, 0x3b, 0xb5, 0xd8, 0x1e, 0xe4, 0x1c, 0x3a, 0xe7, 0x3c, 0xae, 0x2c,
+ 0x19, 0xdf, 0x86, 0xd2, 0x7d, 0x1e, 0x6c, 0xa5, 0x2e, 0x27, 0xa0, 0x05,
+ 0xd6, 0x29, 0xdb, 0x90, 0x77, 0x38, 0xa3, 0x83, 0x4d, 0xe3, 0x19, 0x1f,
+ 0x79, 0xa8, 0x41, 0xea, 0x43, 0xc7, 0x95, 0x11, 0xcb, 0x47, 0xdc, 0x72,
+ 0xfe, 0x04, 0xd3, 0xe9, 0x22, 0x9c, 0x4d, 0x89, 0x8e, 0xe4, 0xec, 0xda,
+ 0x04, 0xf2, 0xf7, 0x11, 0x23, 0x47, 0x75, 0x8b, 0x43, 0x88, 0x6f, 0x8c,
+ 0xa6, 0xef, 0xe6, 0x5f, 0x41, 0xec, 0x49, 0xd4, 0xd0, 0xb7, 0x16, 0x60,
+ 0xcd, 0x3e, 0xe9, 0x91, 0x4e, 0xdd, 0xef, 0xa2, 0x35, 0x8d, 0xa5, 0xef,
+ 0xe6, 0x5b, 0x0d, 0xb4, 0x53, 0x6f, 0x8b, 0x01, 0x39, 0xab, 0x61, 0x62,
+ 0x5a, 0x3f, 0xae, 0xd8, 0x62, 0x92, 0x6f, 0xb5, 0xd1, 0xe7, 0x5b, 0xd1,
+ 0x33, 0x84, 0xf6, 0x83, 0x0d, 0xd2, 0xb7, 0x75, 0x62, 0x84, 0xf9, 0xd3,
+ 0x65, 0xe6, 0x1c, 0xd4, 0xb9, 0x9a, 0x17, 0xce, 0xc3, 0xf0, 0xa8, 0x0b,
+ 0x3f, 0x1a, 0xf5, 0xa0, 0x31, 0xf6, 0x39, 0x31, 0xa3, 0x10, 0xc7, 0xa9,
+ 0xef, 0x49, 0xf2, 0x9f, 0x8f, 0xa2, 0x2a, 0x26, 0x18, 0x6b, 0x3f, 0x8c,
+ 0x56, 0x62, 0x9c, 0xb9, 0xd6, 0x75, 0xe2, 0x4c, 0x9a, 0x7b, 0xf3, 0x01,
+ 0xf3, 0x8e, 0xef, 0xa5, 0x83, 0xf8, 0x55, 0x34, 0x88, 0x57, 0xa9, 0xc7,
+ 0xba, 0x98, 0x9b, 0x32, 0x1d, 0x53, 0x70, 0xe8, 0xb8, 0x92, 0x47, 0xbb,
+ 0xf0, 0xc7, 0x34, 0xcf, 0x48, 0xd6, 0x2e, 0xb4, 0xf1, 0x56, 0xfa, 0x91,
+ 0xf4, 0xff, 0x25, 0x3e, 0x38, 0xf4, 0x11, 0x90, 0xd3, 0x05, 0x73, 0x75,
+ 0x42, 0xaf, 0x7b, 0x0a, 0x15, 0xf4, 0xa5, 0x2f, 0x4d, 0x55, 0x93, 0x9a,
+ 0x58, 0x32, 0x74, 0x2d, 0xaa, 0xa9, 0x57, 0xad, 0x35, 0x18, 0x8a, 0x73,
+ 0x39, 0x39, 0x46, 0xe5, 0x0e, 0xae, 0x5f, 0x23, 0x66, 0x38, 0xe8, 0x32,
+ 0x26, 0xef, 0xbb, 0x8e, 0xfb, 0x0e, 0xfd, 0x69, 0x75, 0x86, 0x03, 0xd1,
+ 0x9f, 0x6d, 0x77, 0xd6, 0xb1, 0xa4, 0x96, 0xbd, 0x37, 0xf4, 0x46, 0x34,
+ 0x56, 0x2d, 0x3d, 0xa5, 0x93, 0x08, 0x52, 0x2f, 0x77, 0xcb, 0x15, 0x4c,
+ 0xbc, 0x45, 0x4c, 0xb9, 0x9a, 0x14, 0xbe, 0x24, 0x3c, 0xa9, 0x8b, 0x31,
+ 0xa9, 0x84, 0x3c, 0x41, 0xc3, 0x4e, 0x72, 0x79, 0x5f, 0x7c, 0x8a, 0xb9,
+ 0xca, 0x57, 0xc9, 0xd5, 0x4a, 0x39, 0x8d, 0xc1, 0xe7, 0xb5, 0x62, 0x0f,
+ 0x7d, 0xb3, 0x40, 0x5b, 0x8c, 0x35, 0xe4, 0x41, 0x0e, 0x8d, 0xa1, 0xe4,
+ 0x09, 0x89, 0x27, 0x40, 0x6d, 0x5c, 0x95, 0x7e, 0xcf, 0xfa, 0x9f, 0xe1,
+ 0x7e, 0xb4, 0x57, 0xb9, 0x20, 0x3d, 0x9a, 0x37, 0xd1, 0x84, 0xd4, 0xd7,
+ 0xad, 0xde, 0x30, 0xdc, 0x61, 0xcd, 0xb8, 0x88, 0x45, 0x16, 0x23, 0x2f,
+ 0x0c, 0x8b, 0x3c, 0x95, 0xd4, 0xbf, 0x8a, 0x77, 0xa9, 0xd7, 0x2b, 0x51,
+ 0xdf, 0xcc, 0x83, 0xa8, 0x3f, 0x73, 0xc5, 0x2e, 0xfd, 0x2b, 0xb9, 0x3f,
+ 0x08, 0x8d, 0xf3, 0x7d, 0x1a, 0x0d, 0x61, 0x40, 0x95, 0xef, 0xc2, 0x1b,
+ 0x5b, 0xd1, 0x3d, 0x22, 0x32, 0x98, 0x66, 0x39, 0xf1, 0xf1, 0x09, 0xeb,
+ 0xf9, 0xf2, 0xec, 0x3b, 0xf3, 0x0e, 0xaf, 0x6a, 0x20, 0x97, 0x7b, 0x4c,
+ 0xe3, 0x68, 0xd2, 0x03, 0xc7, 0xf2, 0xff, 0x41, 0x3d, 0x4c, 0x63, 0x34,
+ 0xa5, 0x91, 0x53, 0x16, 0xc1, 0x53, 0x15, 0x44, 0x3f, 0xe3, 0x78, 0x8c,
+ 0xf7, 0xa7, 0x63, 0x45, 0x30, 0xaa, 0x32, 0xcf, 0xfc, 0x6a, 0xfc, 0xba,
+ 0x39, 0xf5, 0xb8, 0xcc, 0x29, 0xdf, 0x7f, 0xce, 0x31, 0x73, 0xe5, 0xd8,
+ 0x23, 0x36, 0xc7, 0xae, 0x9a, 0x53, 0xad, 0xb3, 0x7f, 0x2f, 0xb3, 0xce,
+ 0x10, 0x45, 0x6c, 0x55, 0x52, 0x6f, 0xb1, 0xf4, 0xd2, 0x4d, 0xbd, 0xcc,
+ 0xd1, 0xde, 0x36, 0x1f, 0xb3, 0xe4, 0x9a, 0xaa, 0x16, 0x9e, 0x5f, 0x1b,
+ 0xff, 0xbc, 0x5a, 0xea, 0xa5, 0x12, 0xc3, 0x5c, 0x61, 0xad, 0xf1, 0x0c,
+ 0xfe, 0xd1, 0xbc, 0x74, 0xdb, 0x3c, 0x15, 0xbc, 0x26, 0xf1, 0xe8, 0x52,
+ 0xb6, 0x1f, 0xed, 0xce, 0xe6, 0x02, 0xd3, 0x38, 0x99, 0x94, 0x58, 0xe0,
+ 0xc1, 0x06, 0xa9, 0x43, 0xa9, 0xde, 0x3e, 0x03, 0x53, 0xe4, 0x7e, 0xef,
+ 0x50, 0xf7, 0x4c, 0x80, 0xfc, 0x53, 0xe4, 0x7f, 0xb3, 0xe3, 0x55, 0x04,
+ 0xa9, 0x4a, 0xe9, 0x29, 0x08, 0x9e, 0x4e, 0x63, 0x57, 0xf2, 0x75, 0xe2,
+ 0xda, 0xc7, 0xe4, 0x43, 0x5d, 0xe4, 0xda, 0xd3, 0xe8, 0x49, 0x35, 0xe3,
+ 0xe5, 0xfd, 0x2d, 0xc4, 0x18, 0xc1, 0x4a, 0xdf, 0x99, 0xcb, 0xf6, 0x66,
+ 0x1c, 0x1c, 0x4b, 0x23, 0x75, 0x58, 0x62, 0xa4, 0x9c, 0xc7, 0x92, 0xf8,
+ 0xa8, 0x21, 0x9a, 0x38, 0x0d, 0x83, 0x7f, 0xf7, 0x24, 0xb6, 0x21, 0x72,
+ 0xf8, 0x6d, 0x72, 0xfc, 0x69, 0xac, 0x1e, 0xd0, 0xd6, 0x1f, 0xc1, 0x34,
+ 0xd6, 0x32, 0x7e, 0x26, 0x13, 0x2d, 0x9c, 0xbf, 0x19, 0xbd, 0xfb, 0xbd,
+ 0x01, 0x87, 0x6d, 0x0e, 0x63, 0x94, 0x07, 0x3b, 0x27, 0x23, 0x30, 0x46,
+ 0xe4, 0x8c, 0x81, 0x0b, 0xc1, 0xb8, 0x47, 0xf9, 0x90, 0x3c, 0xb9, 0x3e,
+ 0xee, 0x65, 0x7e, 0xe6, 0x35, 0xd6, 0x2a, 0x3e, 0x4f, 0x9e, 0x4d, 0xfa,
+ 0x59, 0x73, 0x70, 0x46, 0x57, 0x50, 0x70, 0xbf, 0x82, 0x10, 0x63, 0x97,
+ 0xa7, 0x9a, 0x31, 0x65, 0x44, 0x47, 0xef, 0x10, 0xd7, 0x7b, 0x73, 0xdf,
+ 0x64, 0xbf, 0x1e, 0xe1, 0x7c, 0xb2, 0x77, 0x2d, 0xe8, 0x9d, 0xf4, 0x75,
+ 0x9c, 0x81, 0xdb, 0xe2, 0x5c, 0xbd, 0x43, 0xb9, 0x7b, 0x50, 0xfc, 0x71,
+ 0x83, 0x37, 0x30, 0x47, 0x91, 0x7b, 0x77, 0x10, 0xbf, 0x66, 0xdf, 0x6f,
+ 0x28, 0xc9, 0xe5, 0xe4, 0xa5, 0x36, 0xf1, 0x8b, 0x6e, 0xcb, 0x5f, 0x44,
+ 0x17, 0xbd, 0xc9, 0x08, 0x6d, 0xfa, 0xc7, 0x66, 0xaa, 0xb5, 0x95, 0x72,
+ 0x36, 0x48, 0xaf, 0xc7, 0xe2, 0x26, 0xe7, 0xa5, 0xee, 0xe6, 0x94, 0xd8,
+ 0xdd, 0xdd, 0xee, 0xa2, 0x3d, 0xe5, 0x13, 0x9f, 0x0a, 0x26, 0x5c, 0x70,
+ 0x1d, 0x29, 0x42, 0xfe, 0xb0, 0xf0, 0x34, 0xa8, 0xa5, 0xcc, 0xfb, 0xe5,
+ 0x3c, 0xc3, 0x30, 0x6d, 0xd4, 0x36, 0x41, 0x1f, 0x8b, 0xba, 0xb1, 0x68,
+ 0xc2, 0x8d, 0x1f, 0x11, 0x03, 0x6a, 0x26, 0x34, 0x1c, 0x27, 0x06, 0xb8,
+ 0x27, 0x02, 0x98, 0x24, 0x06, 0xcc, 0xc9, 0xd6, 0x3e, 0xde, 0x4c, 0xcf,
+ 0x9f, 0x8b, 0x42, 0x79, 0x96, 0xe8, 0x31, 0xb7, 0xaf, 0xb2, 0xa7, 0x2d,
+ 0xc4, 0x3d, 0xd9, 0xdf, 0x00, 0x76, 0x0f, 0xa5, 0xb1, 0x6a, 0x9f, 0x89,
+ 0x9f, 0xeb, 0xf5, 0xee, 0x02, 0x45, 0xf2, 0x04, 0x13, 0x69, 0x5d, 0xce,
+ 0x4d, 0x7a, 0xd7, 0xcb, 0xb9, 0xe2, 0xf6, 0x4a, 0x13, 0x79, 0x21, 0xaf,
+ 0x4e, 0xb4, 0x5f, 0x5f, 0xa0, 0x48, 0xdc, 0xaa, 0xf7, 0x6c, 0xc1, 0x7c,
+ 0x64, 0x7a, 0x65, 0x0f, 0x62, 0x8b, 0xaa, 0xd0, 0x1f, 0x5b, 0xb0, 0xa7,
+ 0xcc, 0x70, 0x5d, 0x6b, 0x30, 0xcd, 0x4d, 0xa1, 0xdf, 0x56, 0x59, 0xb5,
+ 0x65, 0xdb, 0x1f, 0x71, 0xed, 0x6d, 0x5c, 0xb7, 0xac, 0xbd, 0x03, 0xb1,
+ 0xbd, 0x0a, 0xd2, 0xfe, 0x0e, 0x44, 0x47, 0x3b, 0xd0, 0xbf, 0x57, 0x30,
+ 0xa1, 0x8f, 0x98, 0x60, 0x76, 0x3d, 0x1b, 0x7a, 0x0c, 0x57, 0x2d, 0x16,
+ 0x20, 0x63, 0xbc, 0x01, 0x8f, 0x6d, 0xf6, 0x3e, 0xe4, 0x53, 0xfe, 0x8c,
+ 0xef, 0x34, 0x0f, 0x08, 0xa7, 0xf6, 0xf7, 0xf5, 0x72, 0xff, 0x1f, 0x3f,
+ 0x24, 0xf1, 0xc6, 0x34, 0xfb, 0xc8, 0x59, 0x51, 0x26, 0x6b, 0xd0, 0xa4,
+ 0x3e, 0xfe, 0x71, 0x8d, 0xe6, 0x9b, 0xe9, 0x67, 0x6c, 0xbf, 0xb8, 0xaf,
+ 0x7e, 0xcb, 0x16, 0xe1, 0x31, 0xcb, 0x84, 0xdb, 0xa5, 0x71, 0xe1, 0xf0,
+ 0x7d, 0x48, 0x3d, 0xce, 0xf5, 0x70, 0xaf, 0x9c, 0xf1, 0x2f, 0x4c, 0xe1,
+ 0x72, 0x76, 0x4d, 0x53, 0x8f, 0x12, 0xfb, 0x6c, 0x13, 0x7e, 0xf4, 0x94,
+ 0xc1, 0xb8, 0xd6, 0x20, 0xcf, 0xbf, 0x29, 0x3f, 0xd7, 0xdb, 0x8c, 0xfe,
+ 0xfd, 0xc2, 0x35, 0x84, 0x97, 0xf9, 0x8c, 0x0f, 0xd0, 0x82, 0xe4, 0x64,
+ 0xe6, 0x59, 0xd1, 0xc4, 0x9d, 0xb6, 0x22, 0xfb, 0x7e, 0x1a, 0xbb, 0x69,
+ 0x97, 0x2e, 0xce, 0xcf, 0xf8, 0xc2, 0xf9, 0xb4, 0x40, 0x81, 0x3c, 0x6f,
+ 0xe2, 0xc7, 0xe6, 0x9e, 0x2a, 0xd1, 0x8d, 0xcc, 0x7f, 0xba, 0x4a, 0x30,
+ 0x63, 0x53, 0xe8, 0x0f, 0xad, 0xf5, 0x75, 0xfe, 0xf5, 0xb6, 0x64, 0xf4,
+ 0x21, 0xf7, 0x9e, 0xfe, 0x3d, 0xf2, 0x5c, 0xe0, 0x7d, 0x22, 0x53, 0x07,
+ 0x76, 0xef, 0x85, 0x51, 0xa8, 0x49, 0xaf, 0xa0, 0x03, 0x7d, 0xd4, 0xef,
+ 0xce, 0x64, 0x07, 0x0e, 0xd2, 0x67, 0x87, 0xf5, 0x13, 0x35, 0x36, 0xd4,
+ 0xcd, 0xd8, 0x31, 0xf5, 0x93, 0x45, 0xc4, 0xd3, 0x25, 0xcb, 0xfc, 0xf4,
+ 0xaf, 0x0e, 0xc4, 0x53, 0x63, 0x73, 0xad, 0x3e, 0x9f, 0x4d, 0xe2, 0x9f,
+ 0xe8, 0xa2, 0x13, 0x85, 0x03, 0xa7, 0xe1, 0x1c, 0xe8, 0x44, 0x81, 0xbf,
+ 0x09, 0x0f, 0x87, 0x2e, 0x99, 0x57, 0x35, 0x87, 0xfb, 0x24, 0xf5, 0x73,
+ 0x22, 0x58, 0xc3, 0x7c, 0x92, 0x39, 0xcc, 0xc8, 0x3c, 0xfa, 0x7e, 0x03,
+ 0xf9, 0xae, 0xf4, 0xf4, 0x6d, 0x58, 0xbb, 0x5c, 0x72, 0x75, 0x85, 0xb6,
+ 0x5d, 0xcd, 0x5c, 0x53, 0x53, 0x9f, 0xb7, 0xce, 0x5f, 0x90, 0x87, 0x55,
+ 0x7a, 0xf0, 0x8c, 0x75, 0xee, 0x40, 0xae, 0x6f, 0x67, 0x8e, 0xb0, 0x1d,
+ 0x35, 0x31, 0xc3, 0x14, 0x7d, 0x9f, 0x44, 0xe4, 0x25, 0x1b, 0xe5, 0x68,
+ 0x5c, 0xe6, 0xdf, 0x32, 0xa3, 0x88, 0x4d, 0xfb, 0xdb, 0x27, 0x14, 0xdd,
+ 0xf5, 0xc8, 0xb8, 0x82, 0xc0, 0x00, 0xe7, 0x0a, 0xfd, 0xf5, 0xdc, 0x4c,
+ 0x7d, 0x2c, 0xc7, 0xf9, 0xb6, 0x93, 0x27, 0x6c, 0x47, 0x09, 0xc7, 0xbb,
+ 0x35, 0xc1, 0x86, 0xc8, 0x4a, 0xe9, 0xa5, 0xa4, 0x43, 0xfe, 0xd6, 0x62,
+ 0x45, 0xf8, 0x90, 0xbf, 0x71, 0xad, 0x22, 0xdc, 0x45, 0xc6, 0xe9, 0xae,
+ 0xba, 0xf1, 0x8b, 0xd9, 0x9e, 0x57, 0x03, 0xf1, 0xc1, 0x63, 0x9d, 0x85,
+ 0x7c, 0xed, 0xe6, 0x79, 0x89, 0x4c, 0xbd, 0xda, 0x19, 0x97, 0xbc, 0xe2,
+ 0x58, 0x68, 0x55, 0xb4, 0x91, 0x58, 0x67, 0x36, 0x8d, 0xd1, 0xee, 0x2f,
+ 0xa3, 0x12, 0xff, 0x33, 0x2a, 0xb8, 0xe6, 0xc1, 0xff, 0x8a, 0xe6, 0x4b,
+ 0xbe, 0x9c, 0x92, 0x7a, 0xe4, 0xb9, 0xa4, 0x61, 0x52, 0xaf, 0x2d, 0x6b,
+ 0x69, 0x4b, 0x81, 0x50, 0x31, 0x50, 0xd5, 0xfd, 0x8c, 0xd3, 0xca, 0xdf,
+ 0x4b, 0x50, 0xc6, 0x18, 0x30, 0x30, 0xf2, 0xfb, 0x6a, 0xaf, 0xc4, 0xe1,
+ 0x42, 0xa9, 0x81, 0xda, 0xb1, 0x33, 0xf4, 0x2f, 0x66, 0x2a, 0x7b, 0x76,
+ 0xf5, 0xc2, 0x5e, 0xb1, 0xd3, 0x00, 0xf2, 0xe3, 0x17, 0x69, 0x93, 0x2a,
+ 0xce, 0x47, 0x7d, 0xfa, 0x3a, 0xdb, 0x37, 0x68, 0xff, 0x8b, 0x6e, 0xc3,
+ 0xee, 0x45, 0xda, 0xa3, 0x78, 0xda, 0xc2, 0xee, 0x30, 0x7a, 0x18, 0x1b,
+ 0xc8, 0xe3, 0x0e, 0x3c, 0x63, 0x53, 0x51, 0x10, 0xf3, 0xa9, 0x3e, 0xe6,
+ 0xdb, 0x3d, 0x7c, 0x86, 0x70, 0xcc, 0x0a, 0x72, 0xc0, 0x67, 0xa3, 0xf5,
+ 0x9e, 0x5f, 0x63, 0x03, 0xfd, 0x51, 0x9e, 0x21, 0x6b, 0xd2, 0x50, 0xcc,
+ 0xbc, 0xf2, 0x14, 0xd7, 0xb1, 0xb3, 0x2c, 0xf3, 0xdc, 0xd2, 0xec, 0xdc,
+ 0xf1, 0x11, 0xe1, 0x5f, 0x2b, 0xb0, 0xce, 0x9a, 0x3b, 0x68, 0xf9, 0xe6,
+ 0x01, 0x39, 0x5b, 0x5e, 0xa7, 0x21, 0x91, 0x6e, 0xc6, 0xb6, 0xf2, 0x05,
+ 0x38, 0x98, 0xd8, 0x8e, 0xa5, 0xe4, 0xc1, 0x4f, 0x96, 0x1b, 0x8c, 0x8d,
+ 0xc4, 0xa1, 0xb8, 0xa6, 0xde, 0xa7, 0x3c, 0x90, 0xed, 0x3f, 0x54, 0xc2,
+ 0x11, 0x97, 0x98, 0x97, 0x87, 0x41, 0x75, 0x3e, 0x8a, 0xac, 0x33, 0x7f,
+ 0x99, 0xb9, 0xfb, 0x47, 0xbc, 0xd9, 0x38, 0x48, 0xd4, 0x88, 0x5b, 0xe7,
+ 0x2d, 0x02, 0x2f, 0x90, 0x4b, 0xa4, 0x18, 0x01, 0xf3, 0xc2, 0x5a, 0x6a,
+ 0x33, 0x0a, 0x60, 0x54, 0x0b, 0x26, 0xca, 0x98, 0x79, 0x77, 0xc8, 0x54,
+ 0x9e, 0x95, 0x29, 0x77, 0x3d, 0xc5, 0x6b, 0x62, 0x5b, 0xc2, 0x2f, 0xe4,
+ 0xf7, 0x42, 0xb4, 0xd2, 0x9e, 0x2a, 0x29, 0x73, 0xc2, 0x3a, 0xb7, 0xe9,
+ 0xd5, 0x0d, 0x5b, 0x03, 0x3e, 0xdb, 0x97, 0xb1, 0xc1, 0xf5, 0xb5, 0xdc,
+ 0xff, 0xd2, 0x06, 0xcc, 0x1c, 0x96, 0x78, 0xf6, 0xfb, 0xcf, 0x52, 0x18,
+ 0x37, 0xcf, 0x52, 0x88, 0x5e, 0xbd, 0x67, 0xde, 0x45, 0xfd, 0xd4, 0x53,
+ 0xb6, 0xa3, 0x26, 0x2a, 0x44, 0xc7, 0x9b, 0xdd, 0x92, 0x87, 0xda, 0xc8,
+ 0x23, 0x8c, 0x74, 0xd2, 0x2d, 0xb1, 0xd2, 0x11, 0x07, 0x16, 0xc5, 0x0d,
+ 0xe4, 0x87, 0xb5, 0x03, 0xd7, 0xec, 0x37, 0xcc, 0xf6, 0xea, 0x79, 0xcc,
+ 0x03, 0x6f, 0xad, 0xb9, 0x8f, 0xb2, 0xdb, 0xb5, 0x1f, 0x9b, 0x0f, 0x56,
+ 0x8a, 0x8c, 0x3f, 0x72, 0x67, 0xea, 0xcc, 0x0b, 0xa9, 0x97, 0x9c, 0x4e,
+ 0x4c, 0xda, 0xcf, 0xdf, 0x98, 0x5f, 0xbb, 0xed, 0xba, 0xf0, 0x19, 0xb1,
+ 0xd3, 0xd9, 0x67, 0xdb, 0xc4, 0x66, 0x3d, 0xb4, 0xd3, 0x69, 0x8c, 0x25,
+ 0x1b, 0x30, 0x90, 0x10, 0x1d, 0x47, 0x70, 0x99, 0xfc, 0xb0, 0x76, 0x70,
+ 0x1a, 0xc3, 0xe4, 0x87, 0xbe, 0xb8, 0xf7, 0x00, 0x35, 0x89, 0x6d, 0x6a,
+ 0x93, 0xc5, 0x93, 0x5c, 0x5a, 0x4e, 0x86, 0xaf, 0x5a, 0x7a, 0x97, 0x18,
+ 0xb3, 0x87, 0xeb, 0xbd, 0x97, 0x3c, 0xa9, 0x39, 0x96, 0x0f, 0xad, 0xac,
+ 0x14, 0xc5, 0x9a, 0xf4, 0x2b, 0x32, 0xf7, 0x45, 0x29, 0x4b, 0x91, 0xe6,
+ 0xc3, 0x5a, 0xeb, 0x5e, 0x8f, 0x75, 0xae, 0xc1, 0x51, 0x2e, 0x31, 0x58,
+ 0xe2, 0x2e, 0xf9, 0xf7, 0x72, 0x89, 0xbb, 0x61, 0xca, 0xb6, 0x98, 0x7b,
+ 0xb6, 0x14, 0xee, 0x07, 0x3c, 0xa8, 0x79, 0x80, 0x31, 0x72, 0x89, 0x82,
+ 0xf2, 0x25, 0x7e, 0x63, 0xa9, 0xad, 0x19, 0xa8, 0xd6, 0x88, 0x3f, 0x6e,
+ 0xb3, 0x27, 0xf1, 0x3b, 0xce, 0xd1, 0x01, 0x73, 0x6f, 0x21, 0x36, 0xec,
+ 0x9d, 0x43, 0x5b, 0xf5, 0x48, 0x7d, 0xdd, 0xe5, 0x0a, 0x47, 0x43, 0xae,
+ 0x58, 0xbd, 0xee, 0x54, 0x16, 0x33, 0x1e, 0xcb, 0xfe, 0xc9, 0xf3, 0xbf,
+ 0x72, 0x1b, 0x5f, 0xaa, 0x60, 0x7c, 0x7b, 0xd2, 0x92, 0x41, 0x6a, 0xc0,
+ 0x32, 0xee, 0xdf, 0xee, 0xd3, 0xd4, 0xcd, 0x7d, 0xba, 0x0f, 0x8e, 0x27,
+ 0x2a, 0xc9, 0xbf, 0xee, 0x1e, 0x43, 0x0a, 0x18, 0x43, 0xee, 0x8d, 0x99,
+ 0x5d, 0x5b, 0x43, 0x45, 0x52, 0x17, 0xb2, 0x62, 0x48, 0xbb, 0x8d, 0x38,
+ 0x5a, 0x2a, 0x76, 0xe1, 0xab, 0x21, 0xc6, 0xe9, 0x99, 0xdf, 0xc4, 0x3e,
+ 0xac, 0x3a, 0x5e, 0xf6, 0xb7, 0x0e, 0xec, 0x22, 0x66, 0xca, 0xd9, 0x6e,
+ 0xa7, 0xa6, 0xd1, 0xff, 0x3b, 0xd0, 0xc3, 0x39, 0x5f, 0x26, 0x6e, 0x0e,
+ 0x10, 0x37, 0x6f, 0x2c, 0x3b, 0xf1, 0x93, 0x1a, 0xd4, 0xd1, 0x08, 0xa6,
+ 0xfe, 0x5b, 0xb9, 0xe0, 0xe6, 0x52, 0x7f, 0xc7, 0x27, 0x16, 0x6e, 0xca,
+ 0xdc, 0x32, 0xdf, 0xec, 0xb9, 0x17, 0xf2, 0xdf, 0x85, 0x52, 0x4b, 0x34,
+ 0x9d, 0xda, 0xff, 0x36, 0x77, 0x56, 0x8a, 0xac, 0x77, 0x93, 0x43, 0xb0,
+ 0x76, 0x76, 0x4f, 0x7e, 0x9a, 0x98, 0x6b, 0xe5, 0x08, 0x8c, 0xb9, 0x11,
+ 0xac, 0x59, 0xae, 0xe2, 0x6a, 0x74, 0x1a, 0x05, 0x87, 0x72, 0xf8, 0x64,
+ 0x36, 0x9d, 0x22, 0x36, 0x0d, 0x43, 0xf0, 0xa8, 0x91, 0xfb, 0x62, 0xd0,
+ 0x4f, 0x4a, 0x30, 0x91, 0xd4, 0x88, 0x99, 0x26, 0xfa, 0x43, 0x2e, 0x72,
+ 0xdb, 0xee, 0x93, 0x79, 0x56, 0x9c, 0x28, 0x21, 0x86, 0xe7, 0x78, 0xb7,
+ 0x70, 0x6e, 0xc1, 0x1f, 0xe6, 0x18, 0x23, 0x76, 0xe4, 0x2d, 0x93, 0xbc,
+ 0xe2, 0x73, 0xf3, 0x42, 0x9b, 0xdc, 0xb7, 0x00, 0xc3, 0x7b, 0xc5, 0xfe,
+ 0x7c, 0xa8, 0xd1, 0x2e, 0x32, 0xcf, 0x00, 0xde, 0x8f, 0xda, 0xee, 0x71,
+ 0x91, 0x1b, 0x77, 0xe9, 0xcb, 0x71, 0xa3, 0xa2, 0x87, 0x3e, 0xef, 0xe6,
+ 0x6f, 0x53, 0x38, 0x12, 0x75, 0x21, 0xcf, 0xd2, 0x69, 0x29, 0xd7, 0x90,
+ 0xb1, 0xa1, 0x9d, 0xb4, 0xa1, 0x7c, 0xe6, 0x6f, 0x0f, 0x5b, 0xbe, 0x2a,
+ 0xf3, 0x4c, 0xe3, 0x15, 0x72, 0x5a, 0x6d, 0xb9, 0xf0, 0xd9, 0x20, 0xe3,
+ 0x62, 0x09, 0xe2, 0x03, 0x5d, 0x38, 0x1f, 0x2a, 0x41, 0xec, 0x90, 0xf8,
+ 0xd8, 0x02, 0xc1, 0x52, 0x3e, 0xb7, 0x91, 0x3a, 0x51, 0x89, 0x35, 0xf5,
+ 0x9d, 0x76, 0x7b, 0x09, 0x2e, 0x95, 0x31, 0xaf, 0xb5, 0xde, 0xe3, 0x69,
+ 0xc5, 0xc1, 0xac, 0x5d, 0xa8, 0xb4, 0x8b, 0xd6, 0x9b, 0x3c, 0x3a, 0xb7,
+ 0x96, 0x9c, 0xcf, 0x66, 0xfa, 0xe1, 0xbd, 0xe4, 0x36, 0x2f, 0x4b, 0xfd,
+ 0xc8, 0xe6, 0x63, 0x2c, 0x61, 0xce, 0x34, 0x29, 0xfa, 0xfd, 0xeb, 0xb9,
+ 0x19, 0xac, 0x78, 0xa5, 0x26, 0x73, 0x76, 0x25, 0xa7, 0xf7, 0xdc, 0x77,
+ 0x6d, 0x7d, 0xa1, 0xf2, 0x0b, 0x73, 0x6b, 0x95, 0xc8, 0x77, 0x9d, 0x79,
+ 0xda, 0x77, 0xf9, 0xfb, 0x2a, 0xf4, 0x8e, 0xcc, 0x8e, 0x15, 0xe2, 0x87,
+ 0x9e, 0xdb, 0xce, 0xd5, 0x95, 0xc5, 0xe5, 0xdd, 0xa9, 0x63, 0xa1, 0x67,
+ 0xb8, 0x0f, 0xfe, 0xa5, 0xf5, 0x56, 0xdd, 0x85, 0xdc, 0x97, 0x79, 0x89,
+ 0x60, 0xac, 0xc1, 0x18, 0x5f, 0x82, 0x9f, 0x26, 0x25, 0xe6, 0x9a, 0xc8,
+ 0xa7, 0xfd, 0x5d, 0xaa, 0xec, 0x7e, 0xbe, 0xcc, 0xe2, 0xd2, 0x25, 0x28,
+ 0xa7, 0xbd, 0x0f, 0x8e, 0xdc, 0xcd, 0xb6, 0x6f, 0xc5, 0x85, 0x74, 0x48,
+ 0x21, 0x4e, 0xfc, 0x8b, 0xd9, 0xff, 0xf5, 0xcc, 0x98, 0x0b, 0x49, 0x17,
+ 0x3e, 0x0a, 0xb5, 0x63, 0xaa, 0x2c, 0x8c, 0xa1, 0x44, 0x01, 0xda, 0xab,
+ 0xeb, 0xac, 0x77, 0x0a, 0x6a, 0xe2, 0x1e, 0x5c, 0x8c, 0x3a, 0xd1, 0x38,
+ 0xd7, 0x63, 0xd5, 0xd3, 0x6c, 0xf4, 0x85, 0x77, 0xa2, 0x11, 0xcb, 0xe7,
+ 0x66, 0xc7, 0x8c, 0x3c, 0x6d, 0x19, 0x1e, 0xca, 0xe2, 0xfa, 0xc1, 0xc4,
+ 0xe7, 0xc4, 0x9d, 0x52, 0xa3, 0x22, 0x5c, 0x82, 0x7b, 0x87, 0x0c, 0xc1,
+ 0x64, 0xa3, 0x24, 0xac, 0xcd, 0xdc, 0xa7, 0x94, 0xa0, 0x69, 0x44, 0x30,
+ 0x5e, 0x7c, 0x35, 0x4d, 0x5f, 0x6d, 0xe3, 0x1e, 0x75, 0xa2, 0x6e, 0xbf,
+ 0xa5, 0x57, 0xd5, 0xae, 0x98, 0x5d, 0x57, 0xf4, 0x88, 0xce, 0x18, 0xd7,
+ 0xf9, 0x10, 0xed, 0x7e, 0x26, 0xe4, 0x6d, 0xaf, 0xb0, 0x6b, 0x1d, 0xef,
+ 0x29, 0x41, 0x4c, 0x8c, 0x03, 0x03, 0x87, 0x03, 0xf8, 0x20, 0x21, 0x9c,
+ 0x3f, 0x80, 0x5f, 0x4d, 0x06, 0xf1, 0x2e, 0x63, 0x53, 0x41, 0xdc, 0x1b,
+ 0x79, 0x8e, 0x39, 0xdd, 0xfb, 0xfc, 0x9e, 0x1f, 0xd7, 0x71, 0x8d, 0xfa,
+ 0x73, 0xc6, 0x1b, 0x70, 0x65, 0xf2, 0x01, 0x5c, 0xdd, 0xaf, 0xe0, 0x84,
+ 0xf6, 0x00, 0x2e, 0x8f, 0x75, 0x62, 0xd9, 0x7e, 0x39, 0x87, 0x76, 0x2c,
+ 0xa4, 0x32, 0x36, 0x3c, 0x53, 0x6b, 0x76, 0xbd, 0xa8, 0xd7, 0x41, 0x2f,
+ 0xf7, 0xea, 0xed, 0xcc, 0x99, 0x04, 0xd3, 0x23, 0x36, 0xd9, 0x33, 0xd9,
+ 0xbb, 0x4e, 0x5c, 0xb5, 0x70, 0xfc, 0xee, 0xd8, 0x70, 0x0b, 0xc3, 0xe5,
+ 0x39, 0x82, 0x27, 0x0b, 0xf1, 0x7d, 0x26, 0xab, 0x3d, 0xbc, 0xcf, 0x45,
+ 0xec, 0x7b, 0x36, 0x5a, 0x80, 0xfc, 0xaa, 0x52, 0x2b, 0x97, 0x29, 0x8c,
+ 0x07, 0x70, 0x96, 0xba, 0x5b, 0x53, 0xe5, 0xe5, 0x77, 0x89, 0xbb, 0x41,
+ 0xe6, 0x2d, 0x15, 0xf8, 0xe0, 0xb6, 0x78, 0xfb, 0x7d, 0xf3, 0x49, 0x0b,
+ 0x9f, 0xeb, 0xe7, 0x09, 0xff, 0x7a, 0x3d, 0xf1, 0xeb, 0x1a, 0xc1, 0x69,
+ 0xa9, 0x21, 0x96, 0x6a, 0xda, 0x96, 0xbf, 0x80, 0xbc, 0x6f, 0x75, 0xe2,
+ 0x3f, 0x17, 0x93, 0x17, 0xbf, 0x18, 0xaa, 0x33, 0xca, 0xa0, 0xf1, 0xbe,
+ 0xa9, 0x65, 0x2a, 0x56, 0xf1, 0xaf, 0x9f, 0xf7, 0x05, 0x29, 0xc7, 0x75,
+ 0x33, 0xa5, 0xfa, 0xf8, 0xef, 0x05, 0x8c, 0xef, 0xdb, 0x71, 0x3e, 0x56,
+ 0xdf, 0x7e, 0x58, 0xb9, 0x66, 0x1a, 0x55, 0xb5, 0xfc, 0xad, 0x12, 0x17,
+ 0xa2, 0xde, 0xa9, 0x31, 0xd4, 0x7b, 0x66, 0x94, 0x83, 0xa6, 0xa1, 0xca,
+ 0xfe, 0xc8, 0x7a, 0x65, 0xfc, 0x62, 0x5e, 0xbf, 0x34, 0xcb, 0x0e, 0x6f,
+ 0xe5, 0x5d, 0xce, 0x9b, 0xf6, 0x27, 0xbc, 0xc4, 0x6c, 0x1a, 0xd5, 0xeb,
+ 0xd5, 0x1e, 0x62, 0x41, 0x44, 0xbd, 0x9b, 0xfd, 0x15, 0xd0, 0xfe, 0xc2,
+ 0xcc, 0x23, 0x4b, 0xa0, 0x5a, 0xf1, 0xa9, 0x15, 0xc9, 0x91, 0xd9, 0xdc,
+ 0x52, 0xec, 0x2e, 0xc3, 0x53, 0xdb, 0xcb, 0xba, 0x4f, 0x3a, 0x89, 0x45,
+ 0x09, 0xe2, 0x78, 0x9c, 0x38, 0x9e, 0x4f, 0x1c, 0xbf, 0xbe, 0xaf, 0x10,
+ 0xe7, 0xf7, 0x35, 0x22, 0x5d, 0x26, 0x63, 0xec, 0x70, 0x72, 0x75, 0xa9,
+ 0xec, 0x79, 0x85, 0x9a, 0xc1, 0x95, 0x72, 0x8e, 0x13, 0x82, 0x5f, 0x79,
+ 0x71, 0xe6, 0x59, 0xad, 0x76, 0x38, 0xac, 0x33, 0xf6, 0x73, 0x6e, 0xb3,
+ 0x3f, 0x97, 0x96, 0x8f, 0x96, 0x4a, 0xc1, 0x87, 0xd7, 0xe7, 0x49, 0x1c,
+ 0x7d, 0x9d, 0xb2, 0x9c, 0xa4, 0x4d, 0x6f, 0xd4, 0x57, 0x48, 0x5f, 0x8f,
+ 0xf7, 0xcb, 0x38, 0xc9, 0x6d, 0x4c, 0xec, 0xa6, 0x85, 0xd5, 0x55, 0x99,
+ 0x48, 0xe8, 0x61, 0xc6, 0xac, 0x10, 0x22, 0x65, 0x41, 0xc6, 0x2a, 0xf9,
+ 0xae, 0xe2, 0x0a, 0xf3, 0xb2, 0xf1, 0xa0, 0x82, 0x8f, 0xbe, 0x22, 0x5c,
+ 0xc0, 0xaf, 0x9f, 0x57, 0x84, 0x0b, 0xc8, 0x78, 0xc1, 0x88, 0x52, 0x0b,
+ 0x23, 0xf2, 0x2d, 0x5e, 0x34, 0xd7, 0xc2, 0x16, 0x79, 0x47, 0xa9, 0x86,
+ 0x71, 0xe7, 0xfe, 0x44, 0xfd, 0x94, 0xcf, 0x4e, 0x8e, 0xf6, 0x27, 0x5f,
+ 0x21, 0x37, 0xb3, 0x38, 0x02, 0xf1, 0x3e, 0x87, 0x0d, 0x72, 0xee, 0x76,
+ 0xb6, 0x3e, 0x72, 0xe7, 0x72, 0x3d, 0x19, 0xac, 0x2c, 0x15, 0x2e, 0xf7,
+ 0xff, 0xcc, 0xd6, 0xdb, 0xe4, 0xcf, 0xe1, 0xc8, 0x3f, 0xf0, 0xbb, 0x8c,
+ 0x17, 0xbf, 0xa3, 0x5d, 0xc4, 0x7f, 0x62, 0x3e, 0x6d, 0xf1, 0xb9, 0x97,
+ 0xe7, 0xc9, 0xf9, 0x43, 0xc7, 0xe0, 0xd0, 0x3c, 0x39, 0x6f, 0x65, 0x9b,
+ 0xc5, 0x0b, 0x32, 0xb1, 0xf6, 0x5d, 0x73, 0xad, 0x25, 0xeb, 0x91, 0xec,
+ 0x7d, 0x92, 0x43, 0x8b, 0x2c, 0x0a, 0x5e, 0xd1, 0xea, 0xd5, 0xb3, 0x28,
+ 0x16, 0x3c, 0x89, 0x48, 0x0f, 0xb3, 0x50, 0xf3, 0xb9, 0x8f, 0xf0, 0x6f,
+ 0x3f, 0xaf, 0xbf, 0xa1, 0x39, 0x1a, 0xb7, 0x42, 0xfa, 0xb6, 0x36, 0xee,
+ 0x55, 0xbd, 0xfb, 0x2c, 0xfc, 0x91, 0x7c, 0x65, 0xc6, 0x6c, 0xaf, 0x94,
+ 0x7b, 0x32, 0xfd, 0x5b, 0x28, 0x17, 0xad, 0xfa, 0x49, 0xc6, 0x66, 0x16,
+ 0xd0, 0x66, 0x04, 0xbb, 0x84, 0x8b, 0x2c, 0xe1, 0xda, 0x55, 0x8c, 0x4c,
+ 0x02, 0x79, 0x83, 0x2e, 0x8b, 0x1b, 0xa9, 0xb5, 0xb5, 0x9e, 0xcd, 0xf8,
+ 0xe7, 0x79, 0xf2, 0xee, 0xd1, 0x0e, 0x1d, 0xf7, 0xd8, 0xf0, 0xf6, 0x3d,
+ 0xb6, 0xf0, 0xca, 0x6f, 0x3d, 0xd4, 0x90, 0x37, 0x5f, 0xde, 0xff, 0x20,
+ 0xc3, 0x93, 0xfa, 0xad, 0x5b, 0x7a, 0x8d, 0xab, 0x19, 0xc3, 0x86, 0x99,
+ 0xe3, 0xaf, 0x0e, 0xfe, 0xd6, 0xfc, 0xa6, 0x23, 0xe2, 0xb1, 0xa3, 0xd6,
+ 0xd3, 0x8b, 0x1b, 0x66, 0xaa, 0x52, 0xae, 0xcb, 0x1c, 0xf2, 0x6e, 0xa1,
+ 0xf4, 0x4b, 0x4c, 0xf3, 0xde, 0x5a, 0x93, 0xf9, 0xb3, 0x6d, 0x95, 0x9d,
+ 0x7e, 0x91, 0xaf, 0x5d, 0x36, 0xeb, 0xaa, 0x6b, 0xdd, 0x36, 0xa5, 0x8e,
+ 0xd6, 0x51, 0x89, 0x57, 0x69, 0xbf, 0xaf, 0x4e, 0x4a, 0xcc, 0x53, 0x71,
+ 0x94, 0x7e, 0x3a, 0x56, 0xe7, 0xeb, 0xbc, 0xca, 0x5c, 0xf2, 0x43, 0x72,
+ 0xfc, 0x37, 0x35, 0x6f, 0xfb, 0x19, 0xa9, 0x3b, 0x86, 0x1c, 0x38, 0x17,
+ 0xbc, 0x61, 0xd5, 0x82, 0x63, 0x87, 0x54, 0x0c, 0x27, 0x32, 0xfe, 0xfe,
+ 0x1a, 0xfd, 0xf8, 0xd6, 0xd9, 0x05, 0x1d, 0x3d, 0x43, 0xe2, 0x1f, 0x0d,
+ 0x96, 0x1f, 0xdd, 0xaa, 0x15, 0x09, 0x5e, 0x8b, 0x5f, 0x6c, 0x90, 0xde,
+ 0x9d, 0x91, 0x02, 0xb9, 0xcc, 0xe0, 0x6a, 0x72, 0x60, 0x89, 0xb1, 0x01,
+ 0xe6, 0xbb, 0x0e, 0xfa, 0xcf, 0x19, 0xe6, 0x1e, 0x94, 0x2d, 0x6c, 0x9a,
+ 0xef, 0x32, 0x17, 0x1b, 0x41, 0xbd, 0x7a, 0x0a, 0xeb, 0xc8, 0x63, 0xc9,
+ 0x71, 0x26, 0x9b, 0xb1, 0xc7, 0xca, 0xa5, 0x7c, 0xea, 0xc3, 0xca, 0x52,
+ 0xae, 0xbf, 0x19, 0xdd, 0x63, 0x0b, 0x70, 0x80, 0xeb, 0x7a, 0x44, 0xff,
+ 0x2b, 0x94, 0x0f, 0x75, 0x77, 0x96, 0x53, 0x1f, 0x9f, 0x86, 0x8c, 0x0e,
+ 0x62, 0xfa, 0x96, 0x53, 0x4a, 0xfd, 0xfa, 0x98, 0xf2, 0x4d, 0xee, 0x87,
+ 0xd4, 0x47, 0x3c, 0xcc, 0xd3, 0x1f, 0x61, 0x3c, 0xfb, 0x33, 0xec, 0x56,
+ 0x95, 0x26, 0x5b, 0x58, 0x38, 0x22, 0xfc, 0xaa, 0x75, 0x76, 0xf0, 0xbf,
+ 0x40, 0x9f, 0xdb, 0xc0, 0x6b, 0x12, 0xd7, 0xe5, 0x5e, 0x39, 0x37, 0xde,
+ 0x89, 0x93, 0x69, 0xda, 0x75, 0xb4, 0x0f, 0xa7, 0xd2, 0xf2, 0x4c, 0xe1,
+ 0x58, 0x01, 0xc4, 0x86, 0xec, 0x98, 0xd0, 0x7d, 0x91, 0x52, 0xea, 0xa5,
+ 0x30, 0xe4, 0x8d, 0xac, 0x53, 0x02, 0xe4, 0x72, 0x69, 0x9c, 0xdb, 0xeb,
+ 0x6d, 0xaf, 0x63, 0xde, 0x18, 0x9d, 0x84, 0xfa, 0xdc, 0xf2, 0x34, 0xce,
+ 0x8e, 0x3e, 0x0e, 0x4f, 0xb5, 0xd7, 0xb3, 0x5a, 0x69, 0xc1, 0x8e, 0xc9,
+ 0x7f, 0xaf, 0xc6, 0xe4, 0xe1, 0xb3, 0x5b, 0x60, 0x50, 0xf7, 0xbb, 0xf0,
+ 0xad, 0xf9, 0xe2, 0xf3, 0xbd, 0x93, 0xc5, 0x58, 0xc4, 0x78, 0xf4, 0xb2,
+ 0x15, 0x67, 0x33, 0x7e, 0x54, 0xa3, 0x7d, 0x64, 0x3e, 0x95, 0x8d, 0xe1,
+ 0x7f, 0x58, 0x5f, 0x3f, 0x34, 0x23, 0xaa, 0xe8, 0x4b, 0xc6, 0xd5, 0xa0,
+ 0x80, 0xf3, 0xec, 0xce, 0xc6, 0xeb, 0x32, 0xed, 0x9f, 0xcc, 0xc7, 0xad,
+ 0x39, 0x56, 0xce, 0x97, 0x44, 0x61, 0xa7, 0x95, 0xe7, 0xcb, 0xba, 0x75,
+ 0x7c, 0x16, 0x95, 0x5a, 0x87, 0x8a, 0x53, 0xba, 0xe0, 0x48, 0x0b, 0x7d,
+ 0xd5, 0x89, 0x2d, 0x41, 0xba, 0xa3, 0x55, 0xf7, 0x9f, 0xc6, 0x9e, 0xe4,
+ 0xbf, 0x9a, 0xcf, 0xd3, 0x8e, 0xd6, 0x90, 0xc3, 0x78, 0x88, 0x03, 0x1b,
+ 0x43, 0x8f, 0x90, 0x87, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
+ 0x91, 0xfe, 0x1f, 0x5a, 0x82, 0x29, 0xeb, 0xfe, 0x4f, 0xe7, 0x65, 0x6a,
+ 0x8b, 0x67, 0xe6, 0x67, 0x72, 0x43, 0xd1, 0xff, 0x7f, 0x44, 0x7f, 0xaf,
+ 0x99, 0x9e, 0x72, 0xd1, 0x9f, 0x03, 0x6e, 0xc6, 0xad, 0x03, 0xbc, 0xe7,
+ 0xc2, 0x5e, 0x07, 0x06, 0xb5, 0x16, 0x0c, 0x4e, 0xc2, 0xf3, 0x29, 0xef,
+ 0xf9, 0xf9, 0x68, 0xc7, 0xfc, 0x0c, 0x57, 0x78, 0x1b, 0xdd, 0xd1, 0x17,
+ 0xcc, 0x55, 0xe5, 0xb2, 0x5e, 0x39, 0xaf, 0xd3, 0xca, 0xfb, 0x73, 0x75,
+ 0xbe, 0xcd, 0xe6, 0x13, 0x56, 0x9c, 0x78, 0x71, 0xbe, 0xf4, 0xd7, 0x5e,
+ 0x4f, 0x98, 0xb8, 0xa2, 0xf7, 0x58, 0xb9, 0xb9, 0x60, 0x43, 0x6f, 0x42,
+ 0xf6, 0x56, 0x64, 0xfb, 0x66, 0x56, 0x1f, 0x13, 0x55, 0xb7, 0xcb, 0xbd,
+ 0x2a, 0x6b, 0xcb, 0xd2, 0xdf, 0xce, 0xf1, 0x7e, 0xb1, 0x65, 0xb1, 0x63,
+ 0xeb, 0xbd, 0x96, 0xa4, 0xbc, 0xd3, 0xb9, 0x41, 0xfd, 0x1d, 0x9f, 0x21,
+ 0x75, 0x96, 0x16, 0xce, 0x61, 0x9a, 0x9b, 0xf5, 0x7a, 0xcf, 0x29, 0xfc,
+ 0x31, 0x6d, 0x5b, 0xc7, 0xae, 0x21, 0xa9, 0xc3, 0x7a, 0x14, 0xc7, 0xbe,
+ 0x75, 0xb8, 0xc2, 0xf8, 0xbf, 0xc7, 0xb2, 0x43, 0xc1, 0x15, 0x91, 0x43,
+ 0xb0, 0xa5, 0x8d, 0x71, 0x5c, 0x6a, 0xdd, 0x46, 0xa4, 0x26, 0xdc, 0xa9,
+ 0x7c, 0x58, 0xd7, 0x89, 0x63, 0x21, 0xc3, 0x2c, 0xd5, 0xfc, 0xeb, 0x6b,
+ 0x6c, 0x28, 0x98, 0x6c, 0xc8, 0xc7, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
+ 0x69, 0xaf, 0x31, 0xc7, 0xae, 0xba, 0xbe, 0x97, 0xce, 0x62, 0xa5, 0xad,
+ 0x7e, 0xbe, 0xe4, 0x50, 0x49, 0x0b, 0x47, 0xbe, 0x8a, 0x07, 0xad, 0xbd,
+ 0x55, 0x19, 0x43, 0xa5, 0x0e, 0x7c, 0x2c, 0x74, 0x2d, 0x2a, 0x98, 0x62,
+ 0x36, 0x35, 0x87, 0xea, 0xd5, 0x5d, 0xb8, 0x87, 0xd8, 0xd5, 0x84, 0x73,
+ 0xba, 0xf4, 0x3f, 0x8c, 0x6f, 0x3a, 0xac, 0xb3, 0x34, 0x47, 0x43, 0x3b,
+ 0xa2, 0x2b, 0x71, 0x60, 0xc8, 0x50, 0x9c, 0x61, 0x6f, 0x24, 0x46, 0x2e,
+ 0xc4, 0x1c, 0xdd, 0xaa, 0x03, 0x4a, 0x8d, 0x61, 0xb8, 0xa1, 0x13, 0xbb,
+ 0xf4, 0x7c, 0xf4, 0xea, 0x91, 0x82, 0x9e, 0xe5, 0x5d, 0x38, 0xa8, 0x17,
+ 0x1b, 0x8b, 0xc2, 0x06, 0x31, 0x5d, 0xdb, 0x92, 0x84, 0xbf, 0xe5, 0x32,
+ 0x39, 0xc7, 0x49, 0x78, 0x3b, 0x9a, 0xec, 0xc4, 0xdc, 0x15, 0x0e, 0x57,
+ 0x6c, 0xbc, 0x11, 0x89, 0xc9, 0x4a, 0xd7, 0xee, 0xf1, 0x20, 0xe2, 0x93,
+ 0xdc, 0x6f, 0xe6, 0xba, 0x8e, 0xf1, 0x95, 0xe4, 0xa0, 0xa2, 0x47, 0x3b,
+ 0x6d, 0xb1, 0x0e, 0xcf, 0xb5, 0x5e, 0x32, 0x9f, 0xf1, 0x0b, 0x7e, 0x2e,
+ 0xc0, 0x56, 0xd5, 0x67, 0x71, 0xca, 0x88, 0xed, 0x0f, 0xf9, 0x87, 0x9d,
+ 0x36, 0xf7, 0x7d, 0xd3, 0xf3, 0x75, 0xd1, 0x9b, 0x63, 0x01, 0x0a, 0x1f,
+ 0x21, 0x7e, 0xca, 0xbf, 0x45, 0x77, 0xa2, 0x43, 0x13, 0x9b, 0x74, 0xa9,
+ 0xf1, 0x35, 0xd0, 0x67, 0xdc, 0x78, 0x47, 0xbd, 0xb5, 0x0f, 0xcf, 0xea,
+ 0x3e, 0x7d, 0x0c, 0x52, 0xdb, 0x5b, 0xc1, 0x71, 0x52, 0x83, 0x69, 0xc4,
+ 0x4b, 0xd9, 0x9c, 0xc3, 0x63, 0x2b, 0x22, 0xee, 0xe6, 0xe2, 0x88, 0x5c,
+ 0xf7, 0x26, 0x23, 0xb4, 0xd3, 0x6d, 0xc1, 0x19, 0x33, 0x52, 0x6e, 0x74,
+ 0xca, 0xf9, 0x15, 0x77, 0x78, 0xba, 0xd3, 0x5d, 0xe7, 0xed, 0x98, 0x51,
+ 0x80, 0x73, 0x31, 0xc6, 0x61, 0xeb, 0x7f, 0xb1, 0x28, 0x73, 0x3b, 0x31,
+ 0x12, 0x5c, 0x88, 0xf6, 0x36, 0x79, 0x56, 0x33, 0xfa, 0xf6, 0x9b, 0x66,
+ 0x71, 0xc8, 0xa7, 0xa6, 0xe1, 0xc4, 0xc3, 0x41, 0x3b, 0x2e, 0xa9, 0x26,
+ 0x1c, 0xa1, 0x7f, 0x35, 0xc7, 0x19, 0x1f, 0x47, 0xe9, 0x27, 0xbb, 0x69,
+ 0x63, 0xf2, 0xbe, 0x8f, 0x9f, 0x7e, 0x12, 0xa7, 0x9f, 0x9c, 0x0b, 0xdd,
+ 0x97, 0x7d, 0x5f, 0x50, 0x23, 0xaf, 0x98, 0x46, 0xd3, 0x90, 0x8a, 0x4f,
+ 0x57, 0x4c, 0x23, 0x34, 0x92, 0x93, 0x5d, 0xfc, 0x32, 0x27, 0xbf, 0xf4,
+ 0x11, 0x45, 0x76, 0x91, 0x51, 0xd6, 0x22, 0xff, 0xce, 0x5d, 0xcb, 0xfd,
+ 0x26, 0x71, 0xd6, 0x89, 0x56, 0x6b, 0x6d, 0x7f, 0x56, 0x93, 0xc1, 0x8c,
+ 0xdc, 0x9a, 0x2e, 0xb9, 0x6f, 0xff, 0x7e, 0xe2, 0x8e, 0xeb, 0x2b, 0xee,
+ 0xb8, 0xbe, 0x71, 0xde, 0xed, 0xdf, 0x73, 0x3e, 0x71, 0x4b, 0xaf, 0x1d,
+ 0xba, 0x6f, 0xea, 0x18, 0xd7, 0x3a, 0x67, 0xc9, 0x98, 0x79, 0xa9, 0x4c,
+ 0x64, 0x91, 0x3c, 0x36, 0x23, 0xeb, 0xaa, 0xf1, 0xd9, 0xb2, 0xbe, 0x95,
+ 0xed, 0x19, 0x58, 0x67, 0x7c, 0xe9, 0x37, 0x1a, 0x7e, 0x78, 0xdb, 0xb9,
+ 0x43, 0xb1, 0xb5, 0x80, 0xd2, 0x17, 0x93, 0xf7, 0x33, 0x0b, 0xad, 0x77,
+ 0xac, 0x55, 0xbf, 0x81, 0x22, 0xbf, 0xb6, 0x65, 0x8e, 0xad, 0x0b, 0xce,
+ 0xa5, 0x5a, 0xc7, 0xb7, 0x94, 0x24, 0xe2, 0xe3, 0xde, 0xc0, 0x18, 0x75,
+ 0x15, 0x1b, 0xbf, 0xce, 0x5c, 0xbb, 0x0b, 0xcf, 0x85, 0x1c, 0x46, 0x61,
+ 0x58, 0xce, 0x82, 0xae, 0xc2, 0xae, 0x91, 0xbf, 0xc2, 0xe6, 0xa4, 0x70,
+ 0xfc, 0x05, 0xe8, 0x99, 0xb4, 0xe1, 0x04, 0xed, 0xbb, 0x8f, 0xcf, 0x21,
+ 0xfe, 0xb9, 0x53, 0x90, 0xf7, 0x6b, 0x1a, 0x98, 0x37, 0xeb, 0xd6, 0x67,
+ 0xc7, 0xc8, 0xcf, 0xb0, 0x39, 0x6a, 0xe2, 0x53, 0x9d, 0xb1, 0x47, 0x13,
+ 0xf9, 0x1c, 0xd0, 0xca, 0x5b, 0x2d, 0x2c, 0x7d, 0x32, 0xce, 0xfd, 0xac,
+ 0x16, 0x5f, 0x5d, 0x49, 0x9f, 0x55, 0xf0, 0x99, 0xf4, 0x27, 0xcb, 0x29,
+ 0x33, 0xb9, 0xe1, 0xf1, 0xe8, 0x76, 0x8c, 0x5a, 0xfd, 0x67, 0xad, 0xaf,
+ 0xc6, 0x1e, 0x79, 0xb1, 0x8c, 0x3c, 0x3b, 0xa1, 0xfb, 0xdb, 0x2f, 0x28,
+ 0xf0, 0x94, 0x84, 0xfd, 0x8c, 0x33, 0x5f, 0xe2, 0x37, 0xba, 0xd4, 0xd8,
+ 0x74, 0xd7, 0x5a, 0xda, 0xfb, 0xbe, 0x91, 0x80, 0x55, 0x33, 0xf8, 0xe1,
+ 0x5d, 0x6b, 0x1a, 0x99, 0x77, 0xab, 0x33, 0xf5, 0xc7, 0x9f, 0xe1, 0x48,
+ 0xda, 0x85, 0xa7, 0xe2, 0x1e, 0x65, 0xd1, 0x3e, 0x15, 0x0f, 0xc5, 0xbd,
+ 0x53, 0x4d, 0x76, 0xf2, 0x8f, 0x65, 0x73, 0x38, 0x9f, 0x82, 0x1f, 0x2c,
+ 0x95, 0x58, 0xf0, 0x47, 0x30, 0xaa, 0x23, 0x9c, 0x13, 0xc5, 0x79, 0xcb,
+ 0xbd, 0xea, 0x11, 0x9b, 0xcf, 0xfd, 0x1b, 0xec, 0x80, 0x7d, 0xfc, 0x11,
+ 0x74, 0x53, 0xfe, 0x35, 0x71, 0xe9, 0x69, 0xd5, 0x03, 0x65, 0xcd, 0xd8,
+ 0x3d, 0x26, 0xbe, 0x09, 0xa3, 0x2a, 0x0c, 0x4f, 0x65, 0xd8, 0xbf, 0x10,
+ 0x85, 0x5f, 0x92, 0x6b, 0x4f, 0x4b, 0xfe, 0xb9, 0xa5, 0xd4, 0x66, 0x32,
+ 0x7f, 0xb9, 0x2f, 0xdb, 0xab, 0x58, 0x89, 0x1d, 0x43, 0x52, 0x87, 0x27,
+ 0x6e, 0xeb, 0xcc, 0x83, 0xca, 0xb4, 0xc0, 0x46, 0x9b, 0xf4, 0x87, 0xb6,
+ 0xc3, 0x17, 0xdb, 0x8e, 0x40, 0x4c, 0x7c, 0x56, 0x53, 0x3b, 0x10, 0x39,
+ 0x2b, 0xb5, 0xbf, 0x45, 0x21, 0x3f, 0xe5, 0xf2, 0xf7, 0x55, 0xda, 0x75,
+ 0xd7, 0x6b, 0x13, 0x2a, 0xa6, 0xd4, 0x4c, 0x1e, 0x39, 0x96, 0xd4, 0xd6,
+ 0xe7, 0xdb, 0xe4, 0x0c, 0xc5, 0x55, 0xeb, 0x3d, 0xeb, 0x88, 0xed, 0x9f,
+ 0x89, 0x47, 0xcd, 0x18, 0xd8, 0xff, 0x3e, 0x63, 0x90, 0x3c, 0xe3, 0x77,
+ 0xcc, 0xaf, 0x9d, 0x58, 0xdd, 0xe6, 0xc1, 0x83, 0x71, 0xa9, 0x9d, 0xae,
+ 0xaf, 0xca, 0x9c, 0x01, 0x91, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xd9, 0xea,
+ 0x2f, 0xcc, 0x4a, 0x2b, 0x2f, 0xfd, 0xbf, 0x19, 0x9b, 0x49, 0xe4, 0x2d,
+ 0x14, 0x1f, 0xef, 0x9d, 0x64, 0x02, 0x69, 0xd9, 0x5d, 0x15, 0xbf, 0xcb,
+ 0x5c, 0xda, 0x81, 0xed, 0xd8, 0x56, 0x25, 0x7c, 0xe6, 0xc9, 0x89, 0xd9,
+ 0xf7, 0xe7, 0xea, 0x32, 0x95, 0x59, 0x4e, 0x95, 0xb3, 0x37, 0xe9, 0x05,
+ 0x46, 0x94, 0x27, 0xa2, 0x2d, 0xca, 0xda, 0xa8, 0xf4, 0x03, 0x6d, 0xd1,
+ 0x22, 0x72, 0x18, 0xdf, 0x52, 0x13, 0xdf, 0x0e, 0x1d, 0x57, 0x76, 0x5a,
+ 0xe7, 0x66, 0xe5, 0xac, 0x2b, 0x50, 0x3e, 0xd1, 0xac, 0xec, 0x8a, 0x7e,
+ 0x62, 0x6e, 0xb4, 0x7a, 0xf0, 0x79, 0xd6, 0x79, 0x9c, 0xfc, 0x09, 0x17,
+ 0xca, 0x8e, 0xc8, 0xf9, 0x41, 0x0d, 0x15, 0x13, 0x8f, 0x91, 0xb7, 0x0a,
+ 0xd7, 0x31, 0x5a, 0x1c, 0xd6, 0xb9, 0xb6, 0xe6, 0x97, 0x72, 0xe7, 0xda,
+ 0x1c, 0x31, 0x79, 0x1b, 0xd9, 0xfa, 0x8f, 0xb9, 0xd2, 0x51, 0xe6, 0x4a,
+ 0x66, 0xd3, 0xb7, 0x43, 0xc6, 0xee, 0x0a, 0x78, 0x03, 0xe5, 0x36, 0xc3,
+ 0x94, 0x7a, 0xce, 0x6b, 0x24, 0x8c, 0xeb, 0x6a, 0x0d, 0x3c, 0x5c, 0x2b,
+ 0xef, 0x1f, 0xca, 0xbb, 0xc7, 0x5d, 0x38, 0x1a, 0xea, 0xc2, 0x2f, 0xf5,
+ 0x2e, 0xec, 0xd1, 0xe5, 0x4c, 0x43, 0x31, 0x65, 0xd5, 0xa6, 0xa2, 0xd0,
+ 0xf4, 0xb4, 0xa2, 0x9d, 0xb9, 0x0e, 0xef, 0x01, 0x9f, 0xe2, 0x35, 0x56,
+ 0x29, 0x1a, 0xae, 0x8e, 0x7b, 0x67, 0x4a, 0xe9, 0x03, 0x37, 0xc6, 0x03,
+ 0x98, 0x21, 0xae, 0x26, 0x27, 0xe5, 0xfc, 0xc9, 0x02, 0x0c, 0x4d, 0x7e,
+ 0x4d, 0xb8, 0x81, 0x41, 0x4c, 0xb2, 0xce, 0x48, 0x3e, 0x2f, 0xbd, 0x4e,
+ 0x67, 0x30, 0xcb, 0x61, 0x0c, 0x65, 0x53, 0x43, 0x09, 0x6e, 0x30, 0x3a,
+ 0xfd, 0x6d, 0xba, 0x93, 0xf9, 0x1c, 0xde, 0xa8, 0x81, 0xfd, 0x3b, 0x6e,
+ 0xd4, 0x25, 0xe7, 0xe0, 0x44, 0x5d, 0x39, 0xf2, 0x70, 0x6c, 0xf4, 0x45,
+ 0x72, 0xfc, 0xee, 0xf6, 0x52, 0xe6, 0xa7, 0x13, 0xa3, 0x4e, 0xa4, 0x52,
+ 0x52, 0x73, 0xb0, 0x7a, 0x96, 0xd3, 0x0e, 0xfa, 0x52, 0x7f, 0x02, 0x75,
+ 0x35, 0x61, 0x7f, 0xb2, 0xc6, 0xae, 0x72, 0x8e, 0x4a, 0xa4, 0xd2, 0x1a,
+ 0x3f, 0x01, 0x7e, 0x82, 0xfc, 0x34, 0xe2, 0xdb, 0xf4, 0xd9, 0x32, 0xe2,
+ 0xed, 0xf7, 0xd3, 0x25, 0xf8, 0x24, 0xa9, 0x05, 0x74, 0xda, 0xc1, 0x28,
+ 0x73, 0x04, 0xc3, 0xd2, 0x53, 0x09, 0xae, 0xd3, 0x4f, 0x5f, 0x0e, 0x95,
+ 0xc0, 0x4c, 0xdd, 0x2d, 0x27, 0x94, 0xdc, 0x16, 0x6a, 0x61, 0x58, 0xf8,
+ 0xe2, 0x31, 0x25, 0x95, 0x3d, 0xf3, 0xf5, 0xea, 0x38, 0xda, 0xcb, 0xc3,
+ 0xae, 0xe0, 0xea, 0xb8, 0xfd, 0x13, 0x79, 0x9f, 0x75, 0x43, 0x83, 0xbc,
+ 0xf3, 0xe4, 0x0a, 0x3e, 0x3d, 0xe1, 0x0a, 0xae, 0x8f, 0x1f, 0x53, 0x28,
+ 0xcf, 0x81, 0x1a, 0xbb, 0x2b, 0xf8, 0xe4, 0xc4, 0xb1, 0x85, 0x99, 0xbc,
+ 0x0f, 0xca, 0xd3, 0xb5, 0x06, 0x6d, 0x8c, 0x79, 0xef, 0x32, 0xe9, 0xcb,
+ 0x68, 0x9d, 0x57, 0xec, 0x85, 0x46, 0x4d, 0xd8, 0xeb, 0xa9, 0xb1, 0xcb,
+ 0xd9, 0x90, 0x69, 0xc4, 0x93, 0xf2, 0xae, 0x97, 0xd8, 0xfe, 0x3f, 0x99,
+ 0x46, 0x99, 0x9c, 0xf5, 0xe8, 0x44, 0x5c, 0x2b, 0x67, 0xee, 0x24, 0x67,
+ 0xcd, 0x8f, 0x86, 0xa2, 0xb1, 0x62, 0x79, 0x77, 0xb6, 0xe9, 0x7b, 0x21,
+ 0x6f, 0xcb, 0xa0, 0x62, 0x3c, 0x5e, 0x04, 0xd9, 0xd7, 0x2e, 0xe2, 0xb7,
+ 0xa6, 0x3a, 0x15, 0x6f, 0x63, 0x0f, 0x02, 0x38, 0x91, 0x16, 0x5d, 0x07,
+ 0xe5, 0x8c, 0xba, 0xa5, 0xeb, 0x5b, 0x67, 0xae, 0x33, 0xb6, 0xb3, 0x2d,
+ 0xea, 0xe0, 0x5f, 0xb1, 0x17, 0x1b, 0x63, 0x0a, 0xe3, 0x8a, 0x65, 0x33,
+ 0xb7, 0x64, 0x5c, 0x57, 0xdb, 0x85, 0xc9, 0x50, 0xa1, 0xbc, 0x77, 0xcd,
+ 0xb8, 0xee, 0x0d, 0x7c, 0xa2, 0x58, 0xf1, 0xdc, 0x28, 0x62, 0x9c, 0x7d,
+ 0x61, 0xfc, 0xef, 0xcc, 0xf6, 0x6a, 0xc1, 0x2b, 0x3b, 0xc7, 0x5e, 0xc7,
+ 0x6b, 0xa9, 0x5b, 0xe3, 0x5a, 0x38, 0xae, 0x90, 0xe3, 0x8a, 0xc2, 0x92,
+ 0x3b, 0x7a, 0xf5, 0xb5, 0x8a, 0xe6, 0x29, 0x50, 0xa4, 0x57, 0xa6, 0xe1,
+ 0xbd, 0xf4, 0xe4, 0x42, 0xc9, 0x79, 0x7b, 0x27, 0xcb, 0xb1, 0x6e, 0xaf,
+ 0xd9, 0xb4, 0x68, 0xa9, 0xd9, 0x94, 0x0e, 0x45, 0xcd, 0x97, 0xab, 0x64,
+ 0x4f, 0xa5, 0xff, 0x27, 0x63, 0x34, 0xd5, 0xc7, 0x5c, 0xf3, 0x6b, 0x7a,
+ 0x6f, 0xf6, 0xcc, 0x2e, 0xed, 0x9a, 0xcf, 0x38, 0x9d, 0x12, 0x3b, 0xd9,
+ 0xd1, 0xee, 0x62, 0x3e, 0x2a, 0xef, 0x87, 0x1e, 0xe5, 0xfe, 0x1f, 0x49,
+ 0xfd, 0xcd, 0x42, 0x39, 0xc3, 0x2e, 0x67, 0x08, 0x80, 0xff, 0x0f, 0x1d,
+ 0xab, 0x22, 0x97, 0x70, 0x78, 0x00, 0x00, 0x00 };
static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b09FwRodata[(0xb0/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x08005054, 0x08005054, 0x08005130,
- 0x08005104, 0x080050e8, 0x08005024, 0x08005024, 0x08005024, 0x0800505c,
- 0x080073b8, 0x08007404, 0x080073c4, 0x080072ec, 0x080073c4, 0x080073f4,
- 0x080073c4, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec,
- 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080073e4,
- 0x080073d4, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec,
- 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec,
- 0x080072ec, 0x080073d4, 0x00000000 };
+static const u32 bnx2_RXP_b09FwRodata[(0xf0/4) + 1] = {
+ 0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e,
+ 0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080,
+ 0x80080000, 0x08004efc, 0x08004efc, 0x08004fd8, 0x08004fac, 0x08004f90,
+ 0x08004ecc, 0x08004ecc, 0x08004ecc, 0x08004f04, 0x08007220, 0x0800726c,
+ 0x0800722c, 0x08007150, 0x0800722c, 0x0800725c, 0x0800722c, 0x08007150,
+ 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
+ 0x08007150, 0x08007150, 0x08007150, 0x0800724c, 0x0800723c, 0x08007150,
+ 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
+ 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x0800723c,
+ 0x080077f4, 0x080076bc, 0x080077bc, 0x08007718, 0x080076e8, 0x080075a4,
+ 0x00000000 };
static struct fw_info bnx2_rxp_fw_09 = {
- /* Firmware version: 4.0.5 */
+ /* Firmware version: 4.4.23 */
.ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
+ .ver_minor = 0x4,
+ .ver_fix = 0x17,
.start_addr = 0x080031d0,
.text_addr = 0x08000000,
- .text_len = 0x79c0,
+ .text_len = 0x786c,
.text_index = 0x0,
.gz_text = bnx2_RXP_b09FwText,
.gz_text_len = sizeof(bnx2_RXP_b09FwText),
@@ -3158,522 +3158,532 @@ static struct fw_info bnx2_rxp_fw_09 = {
.data_index = 0x0,
.data = bnx2_RXP_b09FwData,
- .sbss_addr = 0x08007aa0,
+ .sbss_addr = 0x08007980,
.sbss_len = 0x58,
.sbss_index = 0x0,
- .bss_addr = 0x08007af8,
+ .bss_addr = 0x080079d8,
.bss_len = 0x1c,
.bss_index = 0x0,
- .rodata_addr = 0x080079c0,
- .rodata_len = 0xb0,
+ .rodata_addr = 0x0800786c,
+ .rodata_len = 0xf0,
.rodata_index = 0x0,
.rodata = bnx2_RXP_b09FwRodata,
};
static u8 bnx2_xi_rv2p_proc1[] = {
- /* Date: 04/25/2008 22:02 */
- 0xbd, 0x56, 0x4f, 0x68, 0x1c, 0x55, 0x18, 0xff, 0x76, 0x76, 0x77, 0x66,
- 0x33, 0x3b, 0xbb, 0xb3, 0xd8, 0x34, 0x4c, 0xb7, 0x2b, 0x59, 0x83, 0x97,
- 0xdd, 0x6c, 0x69, 0xa2, 0x15, 0x04, 0x53, 0x5a, 0x72, 0x09, 0xd8, 0x9e,
- 0x02, 0xb5, 0x52, 0x84, 0xb6, 0x8b, 0xf4, 0x52, 0x5a, 0x28, 0x78, 0x11,
- 0x84, 0x0e, 0x6d, 0x93, 0x82, 0xe8, 0x61, 0xc1, 0x06, 0x12, 0x44, 0xa3,
- 0x07, 0x95, 0x60, 0x61, 0x07, 0x3c, 0x78, 0x10, 0x14, 0x15, 0x11, 0x6c,
- 0x0f, 0x85, 0x88, 0xf6, 0xd2, 0x54, 0x4b, 0x0b, 0x1e, 0x5b, 0x3c, 0xd6,
- 0x8c, 0xef, 0xfb, 0xf3, 0x92, 0x99, 0x97, 0x9d, 0x24, 0xa7, 0x2e, 0xb4,
- 0x3f, 0xbe, 0x37, 0xdf, 0xbf, 0xf7, 0xfd, 0xf9, 0xbd, 0xd4, 0x00, 0xc0,
- 0x82, 0x30, 0x1a, 0x55, 0x08, 0x65, 0x2b, 0x5f, 0x52, 0x90, 0x03, 0xf8,
- 0x1a, 0xf8, 0x57, 0xf4, 0x48, 0x0e, 0x0f, 0x8a, 0x3c, 0xce, 0x10, 0x8e,
- 0xd7, 0xd4, 0xff, 0x17, 0xe0, 0x48, 0x13, 0x31, 0x0f, 0x47, 0x5e, 0x40,
- 0x3c, 0x0c, 0xdf, 0x37, 0x03, 0x85, 0xff, 0xc5, 0x10, 0xa2, 0x3c, 0xdc,
- 0xff, 0x36, 0x2a, 0x93, 0xff, 0x35, 0xb1, 0xff, 0x33, 0xcf, 0xf8, 0x6a,
- 0xa7, 0xc4, 0x7e, 0x04, 0xe1, 0x40, 0x8d, 0x60, 0xb5, 0x87, 0xf2, 0x89,
- 0x13, 0x60, 0xa3, 0x9f, 0x4f, 0x94, 0x02, 0xca, 0x8d, 0x5c, 0x78, 0x40,
- 0xf2, 0xb2, 0x58, 0xef, 0x5e, 0xcf, 0xc7, 0x73, 0xb8, 0x3f, 0x8d, 0xf2,
- 0x3e, 0xf7, 0x5a, 0x0f, 0x31, 0x80, 0x73, 0x25, 0x8f, 0xef, 0x33, 0xca,
- 0x6e, 0xd7, 0xda, 0x68, 0xa7, 0x74, 0xdb, 0xe2, 0xb7, 0x88, 0x7e, 0xff,
- 0x89, 0xd9, 0x2f, 0xfa, 0x4b, 0xfa, 0x69, 0x28, 0x3f, 0x78, 0x6e, 0x4b,
- 0x5e, 0xb6, 0x91, 0x97, 0xad, 0xf2, 0x90, 0x3a, 0x80, 0xce, 0x03, 0x71,
- 0xaf, 0x8a, 0x8b, 0x7e, 0x1f, 0xcb, 0xbd, 0x01, 0x4e, 0x37, 0xc5, 0x7f,
- 0x84, 0xe8, 0xe5, 0xd8, 0x9f, 0xfa, 0x27, 0xf7, 0xd8, 0xea, 0x47, 0xd7,
- 0x29, 0x9d, 0xbf, 0xd3, 0xd1, 0xdf, 0x75, 0x3f, 0x30, 0xce, 0x1d, 0x15,
- 0x27, 0xa9, 0x0f, 0x3b, 0xe8, 0xff, 0xa6, 0xf4, 0xd3, 0x7e, 0xf9, 0xfc,
- 0xd7, 0xcd, 0xf3, 0xd6, 0xa0, 0xba, 0x15, 0x8d, 0xba, 0xfd, 0x28, 0x75,
- 0x9b, 0x81, 0x17, 0xad, 0x80, 0xf4, 0x0a, 0x80, 0xb8, 0x5f, 0x25, 0x80,
- 0xf8, 0xbc, 0xe0, 0x45, 0xc1, 0xcf, 0x04, 0x97, 0x05, 0xf7, 0x0a, 0x0e,
- 0x0b, 0xee, 0x11, 0x7c, 0x4e, 0xf0, 0x6f, 0xc1, 0x9a, 0xa0, 0x2f, 0x58,
- 0x15, 0xbc, 0x27, 0xe8, 0x09, 0x96, 0x0d, 0x7f, 0x75, 0xc1, 0x92, 0x60,
- 0x24, 0xf8, 0x9a, 0x61, 0xef, 0xe6, 0x18, 0x57, 0x45, 0x3e, 0x28, 0xf2,
- 0x49, 0x91, 0xb1, 0xa0, 0x32, 0xf7, 0xa9, 0x7a, 0x7d, 0xbe, 0xd1, 0xdf,
- 0xd5, 0x9e, 0x7c, 0x6f, 0x69, 0xbd, 0x12, 0xd5, 0x0f, 0xda, 0x49, 0xfd,
- 0x8f, 0xb7, 0xd1, 0x67, 0xb5, 0xe9, 0xd6, 0x20, 0xbb, 0x1b, 0x31, 0xe7,
- 0xf1, 0x91, 0xd8, 0x07, 0xfd, 0xef, 0x32, 0xf6, 0x68, 0xaa, 0x63, 0xce,
- 0xd7, 0xa0, 0x3d, 0x7a, 0x45, 0xf6, 0xe8, 0xd0, 0x96, 0xf9, 0xe5, 0x39,
- 0x3d, 0x2a, 0xf6, 0x53, 0x32, 0x9f, 0x8d, 0x0c, 0xbd, 0x30, 0xb1, 0xaf,
- 0x14, 0x2f, 0x63, 0x1f, 0x6e, 0xe6, 0xba, 0x1d, 0x8c, 0x5b, 0x94, 0xb8,
- 0x59, 0xf9, 0xa1, 0xbd, 0xcc, 0x6f, 0x4b, 0xcf, 0x71, 0x7a, 0x7e, 0x79,
- 0x0e, 0x6d, 0x63, 0x0e, 0x2f, 0xed, 0xd0, 0x87, 0xb2, 0x51, 0xcf, 0xf3,
- 0x4a, 0x9f, 0x45, 0xcb, 0x62, 0x5c, 0x62, 0xec, 0x78, 0x76, 0x01, 0xf1,
- 0x90, 0xf7, 0x0b, 0xfb, 0x1b, 0xa5, 0x7b, 0x78, 0xc1, 0x02, 0xed, 0x6d,
- 0x01, 0x16, 0xec, 0x21, 0x85, 0x4f, 0xe3, 0x0f, 0x59, 0xaf, 0x5e, 0xbc,
- 0x4d, 0x18, 0x2c, 0xdd, 0x62, 0xfd, 0x3f, 0x9a, 0x9c, 0xf7, 0x1b, 0xe3,
- 0x60, 0xfc, 0xf4, 0x77, 0xd9, 0x77, 0x1f, 0xe5, 0x7f, 0x73, 0x61, 0xa4,
- 0xe3, 0x88, 0xdd, 0x79, 0xbd, 0x47, 0xfc, 0xbb, 0x62, 0xd7, 0xa8, 0x6e,
- 0xef, 0x47, 0x24, 0x0e, 0x7b, 0xf3, 0xcc, 0xaf, 0x1f, 0x44, 0xfa, 0x3e,
- 0xc2, 0x2b, 0x6d, 0xb6, 0xab, 0x50, 0x9c, 0x3d, 0xfd, 0x65, 0x63, 0x3e,
- 0x9a, 0xbb, 0xe2, 0xd7, 0x27, 0xf1, 0x26, 0xbf, 0x26, 0xef, 0xaf, 0xf9,
- 0xb5, 0x04, 0x67, 0x66, 0x7c, 0x8a, 0x57, 0xb5, 0xd9, 0xcd, 0x9b, 0x3e,
- 0xe3, 0xdb, 0x2e, 0xe3, 0x43, 0x17, 0xeb, 0x13, 0xc7, 0xe7, 0xca, 0x2c,
- 0x9f, 0xad, 0xe8, 0xbd, 0xd6, 0xf6, 0x3a, 0xaf, 0xed, 0xf2, 0xc1, 0xf8,
- 0x3a, 0x8e, 0xce, 0x43, 0xc7, 0x4b, 0xcf, 0x43, 0x76, 0x5c, 0xc6, 0xae,
- 0x95, 0xae, 0xc3, 0xd2, 0x04, 0x63, 0x61, 0x12, 0xf3, 0xfa, 0x21, 0xde,
- 0xd8, 0xeb, 0x56, 0x8d, 0xf4, 0xc6, 0x80, 0xe5, 0x59, 0x99, 0xbf, 0x59,
- 0xda, 0x47, 0xc5, 0x37, 0x16, 0x62, 0x1d, 0x42, 0x7a, 0x6f, 0x2c, 0xf7,
- 0x67, 0x9a, 0x87, 0xbc, 0x9c, 0xab, 0xfa, 0x8f, 0xa5, 0xf7, 0x78, 0x8d,
- 0xe7, 0xad, 0x94, 0x9e, 0xd3, 0x46, 0x3c, 0x78, 0xfe, 0xdd, 0xfe, 0x72,
- 0x6f, 0x50, 0x3f, 0x74, 0x7e, 0x01, 0x74, 0x27, 0xb3, 0xde, 0x09, 0xfd,
- 0x3e, 0x6b, 0x9e, 0xa4, 0xe3, 0x7e, 0x98, 0x4f, 0xdd, 0xfb, 0x28, 0x74,
- 0x06, 0xf9, 0xff, 0x46, 0xbf, 0x7b, 0x03, 0xf6, 0x76, 0xa7, 0xb8, 0x29,
- 0xff, 0x55, 0xb5, 0x39, 0xb0, 0x75, 0xef, 0x1c, 0x63, 0x4f, 0x9f, 0xae,
- 0xf3, 0x9e, 0x36, 0xb6, 0xcc, 0xa7, 0xe6, 0xaf, 0xe6, 0xb6, 0xfc, 0xf5,
- 0xac, 0xf8, 0xca, 0x02, 0xe6, 0x2b, 0x7c, 0x4f, 0xd2, 0x79, 0x3a, 0xfa,
- 0x9e, 0x06, 0x2f, 0xf1, 0xfd, 0xee, 0xaf, 0xef, 0x8e, 0xdf, 0x92, 0x75,
- 0x1a, 0xc4, 0x6f, 0xae, 0xc1, 0x57, 0xbf, 0xaf, 0x6f, 0xf2, 0x1b, 0x7e,
- 0x5f, 0x59, 0xe1, 0xfe, 0xbd, 0x97, 0x98, 0xdf, 0x64, 0xdd, 0x87, 0xa4,
- 0xee, 0x4a, 0x8f, 0xec, 0x6f, 0x1b, 0xf6, 0xba, 0xff, 0xef, 0x08, 0x6f,
- 0x5a, 0x53, 0x3c, 0x7f, 0x4e, 0xf7, 0x91, 0xd1, 0x97, 0xc9, 0x0e, 0xee,
- 0xd5, 0x65, 0x88, 0xa4, 0x6e, 0x77, 0x53, 0xf5, 0xab, 0x08, 0x4f, 0x38,
- 0xf0, 0x55, 0xa4, 0xeb, 0xac, 0xfb, 0xc8, 0xf8, 0x25, 0xe9, 0xd7, 0x76,
- 0xa8, 0x77, 0x0d, 0xbe, 0xd8, 0xe0, 0x41, 0x9f, 0xfc, 0x4d, 0x08, 0xaf,
- 0x9c, 0x91, 0xfd, 0xfe, 0xcb, 0x65, 0xfe, 0xe8, 0x1e, 0xa3, 0x3d, 0x87,
- 0x11, 0xd9, 0xf3, 0x6e, 0x85, 0xe5, 0x7a, 0x85, 0x79, 0x71, 0xc2, 0xf1,
- 0x48, 0xaf, 0x5e, 0x61, 0x1c, 0x29, 0xa3, 0x5d, 0x00, 0x0f, 0x8e, 0x93,
- 0x7a, 0x67, 0xd1, 0x63, 0x7e, 0x5f, 0xbc, 0x25, 0xfc, 0xe3, 0xeb, 0xfa,
- 0xc9, 0x7d, 0x5f, 0xc6, 0xf3, 0x11, 0xb5, 0xcf, 0xc9, 0x7e, 0x28, 0x9d,
- 0x36, 0xe7, 0xf7, 0xa9, 0x64, 0xdf, 0xf4, 0x93, 0xf5, 0xd6, 0xf3, 0xbd,
- 0x9c, 0xd1, 0xa7, 0x99, 0x58, 0xf3, 0xdf, 0xd8, 0x0c, 0xe6, 0xeb, 0x43,
- 0xd5, 0xe1, 0xf9, 0x60, 0x54, 0x7e, 0x2c, 0x07, 0xcd, 0x1a, 0x73, 0xc2,
- 0x27, 0x73, 0x57, 0xc8, 0xcd, 0xf1, 0x39, 0x7d, 0x3e, 0x4d, 0x0b, 0x32,
- 0xbb, 0xf2, 0x13, 0x9d, 0x57, 0xa3, 0x3c, 0x9f, 0x3b, 0xc7, 0x74, 0xbd,
- 0x7c, 0xba, 0xff, 0x02, 0xd7, 0xeb, 0xad, 0x1b, 0x8c, 0xa7, 0xe0, 0x75,
- 0x42, 0x77, 0xc1, 0x63, 0x7e, 0x5c, 0xf4, 0x4a, 0x84, 0x40, 0xf5, 0xb2,
- 0x5e, 0xe2, 0x77, 0xad, 0x28, 0xef, 0xd1, 0x50, 0xa2, 0x8f, 0xe6, 0xfb,
- 0xb1, 0xdb, 0x7e, 0x26, 0xf9, 0x54, 0xbf, 0x6b, 0x39, 0xe3, 0xef, 0xc8,
- 0x8a, 0x31, 0x9f, 0xef, 0x66, 0xcc, 0x67, 0x33, 0x63, 0xbe, 0x4d, 0x5e,
- 0xb9, 0x24, 0x7b, 0x57, 0x80, 0x62, 0x9e, 0x1e, 0x26, 0xaf, 0x70, 0x95,
- 0xfa, 0x6b, 0xcd, 0xf1, 0xbb, 0xee, 0x15, 0xe7, 0x73, 0x54, 0x37, 0x6f,
- 0x9e, 0xf5, 0x0a, 0x7c, 0x1e, 0x68, 0xbc, 0x7e, 0x95, 0xdf, 0x4f, 0x0b,
- 0xfe, 0x07, 0x89, 0x6e, 0x1e, 0x13, 0x00, 0x0d, 0x00, 0x00, 0x00 };
+ /* Date: 06/17/2008 16:52 */
+ 0xbd, 0x56, 0xcf, 0x6b, 0x1c, 0x75, 0x14, 0x7f, 0x3b, 0xbb, 0x33, 0x3b,
+ 0x99, 0x9d, 0xdd, 0x99, 0xda, 0x34, 0x4c, 0xb7, 0x2b, 0xd9, 0x86, 0x5e,
+ 0x36, 0x99, 0x62, 0xa2, 0x11, 0x0a, 0x46, 0x5b, 0x72, 0x09, 0xd8, 0x9e,
+ 0x02, 0x95, 0x22, 0x82, 0x71, 0xa9, 0x3d, 0xd8, 0x96, 0xe2, 0x5f, 0xe0,
+ 0x90, 0x9a, 0x08, 0x45, 0x0f, 0x0b, 0x36, 0x90, 0x20, 0x1a, 0x7b, 0x50,
+ 0x09, 0x0a, 0x3b, 0x07, 0x41, 0x44, 0x2d, 0xa8, 0x88, 0x60, 0x3d, 0x08,
+ 0x85, 0xda, 0x8b, 0x51, 0x8b, 0x8a, 0x07, 0x0f, 0x01, 0x8f, 0x9a, 0xf1,
+ 0xfb, 0x7e, 0x7c, 0x37, 0x33, 0x93, 0xdd, 0x24, 0x27, 0x03, 0xed, 0x87,
+ 0xf7, 0x9d, 0xf7, 0x7d, 0xdf, 0xf7, 0xde, 0xf7, 0xf3, 0x3e, 0xdf, 0xf5,
+ 0x01, 0xc0, 0x80, 0x28, 0x1e, 0x55, 0x08, 0x87, 0x8c, 0xa2, 0xad, 0xa0,
+ 0x00, 0xf0, 0x21, 0xf0, 0x9f, 0xe9, 0x92, 0x1d, 0x3d, 0x22, 0xf6, 0x04,
+ 0x43, 0x34, 0xe1, 0xab, 0xff, 0xaf, 0xc2, 0xe9, 0x26, 0x62, 0x11, 0x4e,
+ 0x1f, 0x47, 0x7c, 0x12, 0x6e, 0x37, 0x03, 0x85, 0xff, 0x26, 0x10, 0xa1,
+ 0x3d, 0xdc, 0xfd, 0x24, 0xae, 0x50, 0xfc, 0x4d, 0xd9, 0xff, 0x63, 0x91,
+ 0xf1, 0x54, 0x68, 0x73, 0x1c, 0x41, 0x38, 0xe9, 0x13, 0xdc, 0xed, 0xa0,
+ 0x7d, 0xfe, 0x3c, 0x58, 0x18, 0xe7, 0x6d, 0xe5, 0x80, 0x76, 0xa3, 0x10,
+ 0x9d, 0x94, 0xbc, 0x0c, 0xf6, 0xfb, 0xa9, 0xe3, 0xe1, 0x3a, 0xfc, 0x3c,
+ 0x8b, 0xf6, 0x51, 0xe7, 0xd5, 0x0e, 0x62, 0x00, 0x97, 0x6c, 0x97, 0xeb,
+ 0x19, 0xe5, 0xb0, 0x9b, 0xe3, 0xb8, 0x4f, 0xf9, 0x8e, 0x4b, 0x5c, 0x13,
+ 0xe3, 0xfe, 0x99, 0x70, 0x5c, 0x8c, 0x97, 0x8e, 0xd3, 0x50, 0x71, 0x70,
+ 0xdd, 0x92, 0xbc, 0xac, 0x5c, 0x5e, 0x96, 0xca, 0x43, 0xfa, 0x00, 0x3a,
+ 0x0f, 0xc4, 0x23, 0xea, 0x5c, 0x8c, 0xbb, 0x25, 0x75, 0x03, 0x3c, 0xdf,
+ 0x94, 0xf8, 0x31, 0xa2, 0x5b, 0xe0, 0x78, 0xea, 0x9f, 0xd4, 0xb1, 0x3b,
+ 0x8e, 0xee, 0x53, 0x36, 0xff, 0x72, 0xa8, 0xbf, 0xeb, 0xfb, 0xc0, 0x73,
+ 0x7e, 0x50, 0xe7, 0xa4, 0xfd, 0x61, 0x1f, 0xff, 0xef, 0x94, 0x7f, 0x36,
+ 0x2e, 0xaf, 0x7f, 0xbb, 0xb3, 0xde, 0xea, 0xd7, 0x37, 0x33, 0xd7, 0xb7,
+ 0x2f, 0xa5, 0x6f, 0x73, 0x70, 0xc2, 0x08, 0xc8, 0xaf, 0x04, 0x88, 0xc7,
+ 0x54, 0x02, 0x88, 0x0f, 0x0b, 0x5e, 0x13, 0xbc, 0x25, 0xf8, 0xae, 0xe0,
+ 0x11, 0xc1, 0x61, 0xc1, 0xc3, 0x82, 0x0f, 0x09, 0x6e, 0x09, 0xfa, 0x82,
+ 0x9e, 0x60, 0x4d, 0xf0, 0x2f, 0x41, 0x57, 0xb0, 0x92, 0x8b, 0x57, 0x17,
+ 0xb4, 0x05, 0x3f, 0x17, 0x7c, 0x22, 0xb7, 0xff, 0x68, 0x81, 0xf1, 0x81,
+ 0xd8, 0x4f, 0x89, 0x7d, 0x41, 0x6c, 0x6c, 0xa8, 0xf0, 0x3e, 0xd3, 0xaf,
+ 0x5b, 0xbd, 0xfb, 0xbd, 0xdb, 0x91, 0xef, 0x2d, 0xed, 0x67, 0x53, 0xff,
+ 0x60, 0x3c, 0xed, 0xff, 0xd6, 0x1e, 0xfe, 0xec, 0x36, 0xdb, 0xea, 0xb7,
+ 0xef, 0x66, 0xc2, 0x79, 0xbc, 0x29, 0xfb, 0x83, 0xee, 0x67, 0x03, 0xe6,
+ 0x68, 0x26, 0xcc, 0xf3, 0xab, 0xdf, 0x1c, 0x3d, 0x2e, 0x73, 0x34, 0xbd,
+ 0x8b, 0xbf, 0xcc, 0xd3, 0x33, 0xb2, 0x7f, 0x46, 0xf8, 0xd9, 0x18, 0xe0,
+ 0x17, 0xa5, 0xe6, 0x95, 0xce, 0x1b, 0x30, 0x0f, 0x1f, 0x15, 0xda, 0x61,
+ 0xc0, 0xfc, 0x89, 0xf6, 0xca, 0x0f, 0xf7, 0x0b, 0x7f, 0x5b, 0x9a, 0xc7,
+ 0x59, 0xfe, 0x32, 0x0f, 0xad, 0x1c, 0x0f, 0x5f, 0xde, 0xe7, 0x1e, 0x2a,
+ 0xb9, 0x7e, 0x5e, 0x56, 0xfe, 0x6c, 0x1a, 0x06, 0xe3, 0x1a, 0x63, 0xe8,
+ 0x5a, 0x25, 0xc4, 0x69, 0xf7, 0x1b, 0x8e, 0x37, 0x4a, 0x75, 0xb8, 0xc1,
+ 0x0a, 0xcd, 0x6d, 0x09, 0x56, 0xac, 0x21, 0x85, 0xff, 0x24, 0x6f, 0xb0,
+ 0x5f, 0xdd, 0xfc, 0x9e, 0x30, 0x58, 0xbb, 0xc3, 0xfe, 0xf7, 0x9a, 0x9c,
+ 0xf7, 0x33, 0x13, 0x90, 0xfb, 0xd3, 0xdf, 0x65, 0xde, 0x3d, 0xb4, 0xff,
+ 0x2e, 0x44, 0xb1, 0x3e, 0x47, 0xf6, 0x5d, 0xd6, 0x73, 0xc4, 0x7f, 0x8b,
+ 0x96, 0x4f, 0xf5, 0xde, 0x88, 0xc9, 0x1c, 0x76, 0x97, 0x7d, 0xfa, 0xfa,
+ 0x7a, 0xac, 0xeb, 0x11, 0x5d, 0x19, 0xd7, 0xf5, 0xf3, 0xfe, 0x2a, 0x9d,
+ 0x77, 0xb8, 0xbb, 0x9e, 0xe3, 0x49, 0xf3, 0x40, 0x3a, 0xbb, 0x95, 0xec,
+ 0xe8, 0x6c, 0xba, 0x0f, 0x5a, 0x67, 0x6d, 0x58, 0x98, 0xf3, 0xe8, 0xdc,
+ 0x9a, 0xc5, 0x61, 0x2e, 0x78, 0x8c, 0x17, 0x1d, 0xc6, 0xdf, 0x1c, 0xec,
+ 0x53, 0x92, 0x5c, 0xaa, 0xb0, 0xfd, 0x42, 0x55, 0xcf, 0xb7, 0xde, 0xaf,
+ 0xf3, 0xda, 0x2b, 0x1f, 0x3c, 0x5f, 0x9f, 0xa3, 0xf3, 0xd0, 0xe7, 0x65,
+ 0x79, 0x31, 0xf8, 0x5c, 0xc6, 0xb6, 0x91, 0xed, 0xc3, 0xda, 0x24, 0x63,
+ 0x69, 0x0a, 0xf3, 0xba, 0x9d, 0xf4, 0xe6, 0xbb, 0xe5, 0x93, 0xdf, 0x18,
+ 0xb0, 0x3d, 0x2f, 0x3c, 0x9c, 0xa7, 0xb9, 0x54, 0xba, 0x63, 0x20, 0xd6,
+ 0x21, 0xa2, 0x77, 0xc7, 0x70, 0xbe, 0x26, 0x5e, 0x14, 0x65, 0x5d, 0xdd,
+ 0xc3, 0x58, 0x76, 0x9e, 0x37, 0x99, 0x77, 0x76, 0x96, 0xaf, 0xc7, 0x84,
+ 0xaf, 0x4e, 0x77, 0xbd, 0xb3, 0xdf, 0x3c, 0x48, 0xc1, 0xbd, 0xfe, 0x6b,
+ 0x3d, 0xd4, 0xef, 0xb2, 0xd6, 0x3d, 0xfa, 0xdc, 0x8d, 0x8a, 0x99, 0x3a,
+ 0xcf, 0x40, 0xd8, 0xef, 0x7e, 0x3f, 0x16, 0x3d, 0x99, 0x16, 0x7d, 0x53,
+ 0x97, 0x18, 0x65, 0xf6, 0xd5, 0x80, 0xf2, 0x29, 0xe7, 0xe6, 0xac, 0xd4,
+ 0x9b, 0x9b, 0x45, 0x6b, 0x80, 0xde, 0x99, 0xfc, 0x7e, 0x2e, 0xcc, 0xe1,
+ 0xb9, 0x76, 0xe3, 0x06, 0xcd, 0x7f, 0x19, 0xfe, 0x70, 0xf9, 0x5e, 0xda,
+ 0x26, 0xda, 0xe6, 0xf0, 0x95, 0x4f, 0x33, 0xfd, 0x01, 0x38, 0xae, 0xdf,
+ 0x97, 0xf4, 0x1c, 0x07, 0xd0, 0x9e, 0x3a, 0xe8, 0x7b, 0x99, 0xe6, 0x7d,
+ 0x6d, 0x17, 0xef, 0xb5, 0x3e, 0x36, 0xc3, 0xf4, 0x9c, 0xe0, 0x3b, 0xc1,
+ 0xf7, 0xcd, 0xfa, 0x54, 0xc9, 0xf7, 0x41, 0xbd, 0x9f, 0xba, 0xbe, 0x7e,
+ 0xef, 0xe8, 0xaf, 0xdb, 0x07, 0xd3, 0xb3, 0x74, 0x9f, 0xfa, 0xe9, 0x99,
+ 0x93, 0xd3, 0xa7, 0x7b, 0xdb, 0x3d, 0x7d, 0x32, 0xfb, 0xd5, 0xff, 0x7f,
+ 0xe8, 0x36, 0xf7, 0xd3, 0x81, 0x74, 0x3d, 0x1b, 0x1b, 0xcc, 0x9f, 0xab,
+ 0xa9, 0x79, 0x49, 0xdf, 0xff, 0x90, 0xf0, 0x45, 0xf9, 0x51, 0x1d, 0x5f,
+ 0x6c, 0xef, 0xe8, 0x72, 0x9a, 0x7f, 0x2f, 0x0a, 0xff, 0x8d, 0x99, 0x75,
+ 0xe6, 0x47, 0xfb, 0xf7, 0xdc, 0x7d, 0x4d, 0x85, 0xc8, 0x97, 0x57, 0x20,
+ 0x96, 0x3c, 0xef, 0x67, 0xf2, 0xad, 0x8a, 0x2e, 0x95, 0xe1, 0x83, 0x58,
+ 0xd7, 0xc5, 0x9f, 0x9b, 0x21, 0xe3, 0xfb, 0xe4, 0xef, 0xef, 0xf3, 0x2e,
+ 0xf9, 0xf0, 0x5e, 0x4f, 0x7f, 0x3d, 0x8a, 0x37, 0x29, 0x3a, 0xb6, 0x20,
+ 0x7a, 0xf2, 0x8b, 0xc3, 0x7a, 0xd5, 0x3e, 0x4b, 0xfc, 0x85, 0x11, 0xd1,
+ 0x95, 0x76, 0x95, 0xed, 0x7a, 0x95, 0x7f, 0xef, 0x4e, 0x96, 0x5d, 0xf2,
+ 0xab, 0x57, 0x19, 0x47, 0x2a, 0xb8, 0x2f, 0x80, 0x07, 0xe7, 0xc8, 0x3d,
+ 0x5c, 0x75, 0xf9, 0x5d, 0x59, 0xbd, 0x23, 0x7a, 0xe7, 0xe9, 0xfe, 0x49,
+ 0xbd, 0x8f, 0xe1, 0xfa, 0x88, 0xd2, 0x0f, 0xb6, 0x99, 0x17, 0x6e, 0x6f,
+ 0x1e, 0xde, 0x91, 0xec, 0x9b, 0x5e, 0xba, 0xdf, 0x7a, 0x2e, 0x3b, 0xb9,
+ 0x3e, 0xeb, 0x7b, 0x3a, 0x95, 0x68, 0xbd, 0x1d, 0x9b, 0xc3, 0x7c, 0x3d,
+ 0xa8, 0x95, 0x99, 0x47, 0x8c, 0x2a, 0x8e, 0x51, 0xc6, 0x6d, 0x8d, 0x25,
+ 0xd1, 0xaf, 0xa5, 0x45, 0x0a, 0x73, 0x6e, 0x49, 0xaf, 0xcf, 0xd2, 0xe0,
+ 0xcc, 0x6f, 0x7c, 0x45, 0xeb, 0xb5, 0xb8, 0xc8, 0xeb, 0xe5, 0xb3, 0xba,
+ 0x5f, 0x1e, 0xd5, 0xbf, 0xc2, 0xfd, 0x7a, 0xee, 0x26, 0xe3, 0xb3, 0xf0,
+ 0x34, 0xa1, 0xb3, 0x22, 0x73, 0xbf, 0xea, 0xda, 0x84, 0x40, 0xfd, 0x32,
+ 0x1e, 0xe5, 0xf7, 0xd4, 0x94, 0x77, 0x70, 0x28, 0x75, 0x8f, 0xf9, 0xf7,
+ 0xea, 0xa0, 0xf7, 0x99, 0xd6, 0x6f, 0xfd, 0x9e, 0x16, 0x72, 0xbf, 0x5f,
+ 0xab, 0x39, 0x7e, 0xbe, 0x34, 0x80, 0x9f, 0x87, 0x06, 0xf0, 0x3b, 0xaf,
+ 0x87, 0x6d, 0x99, 0xff, 0x12, 0x98, 0x45, 0x7a, 0x08, 0xdd, 0xd2, 0x75,
+ 0xba, 0x5f, 0x63, 0x89, 0x7f, 0x4f, 0xb8, 0xe6, 0x72, 0x81, 0xfa, 0xe6,
+ 0x2e, 0xb3, 0x5f, 0x89, 0xd7, 0x03, 0x8d, 0xaf, 0x5d, 0xe7, 0x39, 0x33,
+ 0xe0, 0x3f, 0xdd, 0xd1, 0x99, 0x07, 0x78, 0x0d, 0x00, 0x00, 0x00 };
static u8 bnx2_xi_rv2p_proc2[] = {
- /* Date: 04/25/2008 22:02 */
+ /* Date: 06/17/2008 16:52 */
#define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5
#define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
-#define XI_RV2P_PROC2_BD_PAGE_SIZE ((PAGE_SIZE / 16) - 1)
- 0xad, 0x58, 0x5b, 0x6c, 0x54, 0x55, 0x14, 0x3d, 0xf3, 0xe8, 0xcc, 0xed,
- 0xcc, 0x9d, 0x99, 0xd2, 0xd6, 0xe9, 0x8b, 0x48, 0x69, 0xa5, 0x74, 0x70,
- 0x0a, 0x65, 0x5a, 0x1e, 0x3e, 0x12, 0x49, 0xd1, 0x02, 0x3e, 0x42, 0xa9,
- 0x86, 0x98, 0x18, 0x03, 0x9d, 0x4a, 0xe9, 0x40, 0x4b, 0x2a, 0x25, 0x7c,
- 0xf0, 0xe3, 0x84, 0x62, 0xf9, 0x99, 0x44, 0x4b, 0x80, 0x16, 0x63, 0x48,
- 0x23, 0x3f, 0xc4, 0xbf, 0x26, 0x28, 0x45, 0x3f, 0x4c, 0x88, 0x36, 0x04,
- 0x3e, 0xc0, 0x44, 0x63, 0xfc, 0x21, 0x12, 0xc4, 0x5a, 0xa0, 0xc1, 0x82,
- 0x36, 0xc6, 0x48, 0xeb, 0x3d, 0x7b, 0xed, 0x73, 0xe7, 0xde, 0xe9, 0x2d,
- 0x8f, 0x48, 0x3f, 0x58, 0x9c, 0x73, 0xf7, 0x39, 0x67, 0xef, 0xb5, 0x1f,
- 0x67, 0x9f, 0x29, 0x10, 0x42, 0x78, 0x45, 0x7a, 0x64, 0x91, 0x81, 0x22,
- 0xe8, 0xf6, 0x68, 0x06, 0xcc, 0x0a, 0x91, 0x57, 0x2a, 0xc7, 0xc2, 0x2d,
- 0xf8, 0x6f, 0x59, 0x01, 0xc1, 0x0f, 0x23, 0xf2, 0xbb, 0x5f, 0xbc, 0xe5,
- 0xc6, 0x77, 0xaf, 0x90, 0x18, 0x11, 0x22, 0x2d, 0xb1, 0x80, 0x31, 0xc6,
- 0xe8, 0x72, 0x01, 0x4b, 0x18, 0x5f, 0x61, 0x14, 0x8c, 0xba, 0x1b, 0xe8,
- 0x66, 0xf4, 0xaa, 0x79, 0x5e, 0xaf, 0xf1, 0x7c, 0x3b, 0xe3, 0x76, 0x9e,
- 0xff, 0xdd, 0x40, 0xa5, 0x97, 0x1c, 0x4f, 0xce, 0x8a, 0xb4, 0x8e, 0x6d,
- 0x63, 0x6a, 0x5e, 0x27, 0x48, 0xc7, 0xa0, 0xf7, 0x9b, 0x95, 0xb4, 0xce,
- 0x41, 0x4e, 0xce, 0xdf, 0x98, 0x55, 0xfb, 0x1d, 0xf4, 0xc8, 0xf1, 0x2f,
- 0xc6, 0xd8, 0x25, 0x87, 0xc5, 0x51, 0x6c, 0x53, 0x5c, 0x9a, 0x91, 0xfb,
- 0x78, 0xc4, 0xd0, 0x80, 0x46, 0xac, 0x1c, 0xd7, 0x31, 0x4e, 0x13, 0x1f,
- 0x2e, 0x63, 0xcc, 0xfb, 0x31, 0x96, 0x85, 0x70, 0xee, 0xd6, 0x4a, 0x9c,
- 0xf7, 0xd3, 0xb3, 0x90, 0x4b, 0x47, 0x14, 0xa1, 0xf8, 0xbe, 0x48, 0xf0,
- 0xf7, 0xdd, 0x72, 0x3c, 0xe5, 0x2a, 0x72, 0x81, 0x57, 0xbf, 0x50, 0x7a,
- 0x42, 0xee, 0xea, 0x40, 0xae, 0x3c, 0x0d, 0x3f, 0x4f, 0xaf, 0x50, 0x76,
- 0x00, 0xda, 0x42, 0xc0, 0xa4, 0x07, 0xb8, 0x2e, 0x4e, 0x90, 0x69, 0x67,
- 0x47, 0x36, 0xd7, 0x48, 0x3d, 0x0a, 0x85, 0xd7, 0x2d, 0xf7, 0x5b, 0xa1,
- 0xf9, 0xce, 0x61, 0xfe, 0x6d, 0xd6, 0xeb, 0xbd, 0x00, 0xf0, 0x46, 0x20,
- 0xdf, 0xf8, 0x77, 0x76, 0xb6, 0x23, 0x68, 0xb7, 0x2b, 0x1d, 0xc4, 0xfa,
- 0x31, 0xdd, 0xc9, 0x3e, 0xcf, 0x03, 0xec, 0xc3, 0xba, 0x05, 0x4b, 0xf1,
- 0xf5, 0xe3, 0x0e, 0x8c, 0x2b, 0x4e, 0x49, 0x39, 0x9f, 0x18, 0x1a, 0x71,
- 0xe2, 0x23, 0x77, 0x7f, 0x23, 0x4e, 0x23, 0x38, 0x47, 0x54, 0x69, 0xa4,
- 0x54, 0x3a, 0x0e, 0x14, 0x75, 0x8e, 0xfc, 0x88, 0xe3, 0x4b, 0xe4, 0xbc,
- 0x5b, 0xb4, 0x7a, 0x74, 0x3a, 0xa7, 0x35, 0xa5, 0xe2, 0x02, 0xdf, 0x3b,
- 0x7c, 0x04, 0xa5, 0x6d, 0xfd, 0xd2, 0xde, 0x88, 0xd8, 0xee, 0x8e, 0x90,
- 0x3c, 0xf8, 0xf1, 0x68, 0xfa, 0x97, 0x90, 0xff, 0x66, 0x91, 0x4e, 0x36,
- 0x75, 0x34, 0x60, 0x5d, 0x71, 0x02, 0x78, 0x2c, 0x91, 0x27, 0x21, 0xde,
- 0xd1, 0x4b, 0xc3, 0xe5, 0xd7, 0x57, 0x6a, 0x24, 0x97, 0xae, 0x53, 0x71,
- 0xa7, 0xfc, 0x27, 0xfd, 0x3a, 0x64, 0xc6, 0x99, 0xa8, 0x06, 0xbf, 0xbf,
- 0x2d, 0x91, 0xf2, 0x06, 0xc9, 0x55, 0x38, 0x27, 0xab, 0x9f, 0x35, 0x6e,
- 0x07, 0x2c, 0x71, 0xfb, 0x78, 0xf1, 0xb0, 0x8e, 0xf8, 0x59, 0xc7, 0x3c,
- 0x55, 0x1a, 0x3c, 0x49, 0x5c, 0xe8, 0x4a, 0xd7, 0xd9, 0xfd, 0x74, 0x75,
- 0x20, 0x42, 0xff, 0xbf, 0xd9, 0x54, 0x40, 0x3c, 0x6f, 0xc6, 0xfc, 0x91,
- 0xe6, 0xb3, 0xf0, 0xd3, 0x26, 0xe2, 0x43, 0x04, 0x0e, 0x7d, 0x81, 0x55,
- 0x6d, 0x14, 0xdf, 0xdd, 0x8d, 0x1d, 0x5f, 0x61, 0x9c, 0xf4, 0xc8, 0xf1,
- 0x6e, 0xbd, 0x7d, 0x14, 0xf2, 0x79, 0x7d, 0xe0, 0x7d, 0x33, 0x9f, 0xb2,
- 0xc9, 0x43, 0xf9, 0x94, 0xf1, 0xf5, 0xd1, 0x50, 0x1f, 0xa3, 0xef, 0x05,
- 0xe2, 0xf0, 0x08, 0xbe, 0xef, 0x09, 0x4a, 0x3b, 0xdf, 0x37, 0xf3, 0x2e,
- 0xe5, 0xc3, 0xfa, 0xcc, 0x00, 0xf2, 0x66, 0xe2, 0x8c, 0x1c, 0x6f, 0x8b,
- 0x4f, 0x40, 0x3e, 0x9e, 0xea, 0xe7, 0x8d, 0xdd, 0xe0, 0xf1, 0xa6, 0x1b,
- 0xf2, 0x1c, 0xa6, 0x01, 0x2f, 0xf9, 0xd1, 0x25, 0xf4, 0x66, 0xe0, 0x87,
- 0xf4, 0xfd, 0x5f, 0x57, 0x86, 0x78, 0xdb, 0x1a, 0xf6, 0x9e, 0x55, 0xfc,
- 0x30, 0x46, 0x94, 0x5d, 0xc0, 0x47, 0xcd, 0x83, 0xfe, 0x79, 0xf3, 0x80,
- 0xfd, 0x19, 0x7b, 0x58, 0x1e, 0x00, 0x9b, 0x6b, 0x80, 0xbe, 0x6a, 0x29,
- 0x9f, 0xff, 0x18, 0xf9, 0xc0, 0x7a, 0xcd, 0xc9, 0x37, 0xcc, 0x66, 0xe3,
- 0x94, 0xc0, 0x88, 0x4f, 0x5b, 0xbc, 0x72, 0x7e, 0x2c, 0x36, 0xfc, 0xa0,
- 0xe2, 0x4e, 0x6e, 0xe8, 0x17, 0xbb, 0x79, 0xdf, 0x14, 0xf3, 0xd1, 0xc5,
- 0x7c, 0x4c, 0x32, 0xee, 0x09, 0x2a, 0x1e, 0x80, 0x87, 0x75, 0x9c, 0xdb,
- 0x9a, 0x92, 0x7e, 0x5c, 0xeb, 0x50, 0x3f, 0x55, 0x9d, 0x84, 0x9f, 0x86,
- 0xd8, 0xaf, 0x27, 0xcc, 0x7a, 0xa9, 0xf8, 0x9d, 0xaf, 0x6e, 0xda, 0xf3,
- 0x29, 0xc7, 0xce, 0xcc, 0x77, 0x55, 0x58, 0x5e, 0x58, 0x0d, 0x34, 0xf9,
- 0xad, 0xa1, 0x3c, 0x0e, 0x97, 0x8c, 0x2a, 0xfb, 0xa4, 0x7e, 0xb7, 0x55,
- 0x1e, 0x86, 0x07, 0x0f, 0x12, 0x06, 0x0a, 0x4f, 0xc9, 0x73, 0xca, 0x1d,
- 0xea, 0x8a, 0x3d, 0x9f, 0x73, 0xf9, 0xdd, 0x13, 0xa2, 0x42, 0xdb, 0x78,
- 0x79, 0xdc, 0x9e, 0xb7, 0xc8, 0x4f, 0xbf, 0x19, 0xdf, 0xc5, 0xab, 0xd9,
- 0x0f, 0x8c, 0xd1, 0x35, 0x72, 0xdf, 0x16, 0x3e, 0xa7, 0x9e, 0xcf, 0xd1,
- 0x2d, 0x75, 0x43, 0xea, 0x59, 0x68, 0xd6, 0x0b, 0x15, 0x1f, 0xd9, 0xba,
- 0xa1, 0xfc, 0x40, 0xe7, 0xc7, 0x2f, 0x8f, 0xcb, 0xf5, 0x15, 0x0f, 0xa9,
- 0x23, 0x9a, 0xb9, 0xdf, 0x8f, 0x66, 0x9d, 0x90, 0xdf, 0x83, 0xe2, 0x25,
- 0x1e, 0xda, 0xeb, 0xe1, 0x1f, 0x46, 0x3d, 0x24, 0x3b, 0x34, 0xfd, 0x2c,
- 0xd7, 0xbf, 0x5e, 0x79, 0x4e, 0x29, 0xeb, 0x5d, 0xca, 0x7a, 0x1b, 0xd7,
- 0x73, 0x1d, 0xd7, 0xc9, 0x6d, 0xd6, 0x7a, 0xf7, 0xcf, 0x4c, 0xb6, 0x6e,
- 0xc9, 0xf1, 0xdf, 0x33, 0x73, 0xef, 0x5f, 0x47, 0x5e, 0xd3, 0x22, 0x82,
- 0x3e, 0x23, 0x1d, 0x51, 0x7d, 0x41, 0x6e, 0xfd, 0xcb, 0xb5, 0x03, 0xbc,
- 0xb4, 0xb9, 0x43, 0x24, 0x77, 0xad, 0xc7, 0xde, 0x27, 0xa0, 0x0e, 0x56,
- 0xba, 0xa0, 0xf7, 0x42, 0xd6, 0xdb, 0xd8, 0xaf, 0x8e, 0xf2, 0x41, 0xbb,
- 0xd6, 0x63, 0xd5, 0xfb, 0xfa, 0xcc, 0xfc, 0xe7, 0x39, 0xc7, 0x41, 0x0f,
- 0xdf, 0xaf, 0x49, 0xc4, 0xb1, 0xd6, 0xfe, 0xb5, 0xd2, 0x8b, 0xcf, 0x8f,
- 0x28, 0x3d, 0x74, 0xf2, 0xd3, 0x78, 0xaf, 0xdc, 0xa7, 0x48, 0x70, 0xd8,
- 0x88, 0xee, 0x5a, 0xd4, 0xdf, 0xc9, 0x1d, 0xb0, 0xa3, 0xbb, 0x46, 0xea,
- 0x61, 0x78, 0x25, 0x8d, 0x3c, 0x17, 0x7c, 0x1f, 0x7d, 0x3b, 0xe0, 0xe4,
- 0xd7, 0x4b, 0x2c, 0x57, 0xcc, 0xf6, 0x15, 0xb0, 0x7d, 0x71, 0x91, 0x5b,
- 0xe7, 0xb7, 0x55, 0xd2, 0x7d, 0xc0, 0x72, 0x2f, 0xaa, 0xfb, 0xc0, 0x90,
- 0x93, 0xfb, 0xe4, 0xf1, 0x3e, 0x4e, 0x3c, 0x39, 0xed, 0x33, 0xca, 0x71,
- 0xd0, 0xc9, 0x72, 0x5e, 0x87, 0x7b, 0x05, 0xa3, 0xe9, 0xa5, 0x74, 0xaf,
- 0x9c, 0x3c, 0x40, 0xf7, 0x43, 0xc8, 0x8c, 0x53, 0xbb, 0x1d, 0x67, 0x9e,
- 0x20, 0xef, 0x52, 0x3e, 0x2a, 0x76, 0x86, 0xe7, 0xe3, 0xd7, 0x2b, 0xa7,
- 0x87, 0xa7, 0x46, 0x95, 0x7f, 0x74, 0xb2, 0x77, 0xbc, 0x57, 0xf5, 0xb1,
- 0x56, 0xde, 0xdd, 0x16, 0xde, 0x21, 0xff, 0x74, 0xfc, 0xff, 0xf2, 0xed,
- 0xd4, 0x1f, 0x1c, 0x9d, 0x31, 0xfb, 0x50, 0x9f, 0x53, 0xfd, 0x5f, 0x61,
- 0xc6, 0xcb, 0x5e, 0xee, 0xef, 0xa6, 0x75, 0xfa, 0x4f, 0x62, 0x32, 0x43,
- 0x43, 0xbd, 0xec, 0xb4, 0x94, 0x5b, 0x96, 0xd8, 0xcb, 0x76, 0x5d, 0xf4,
- 0xc0, 0xee, 0xce, 0x1d, 0x18, 0x5f, 0xe6, 0x7a, 0x7d, 0x97, 0xeb, 0xe3,
- 0x16, 0x0d, 0x38, 0x59, 0x4b, 0x7c, 0x24, 0xf6, 0x9e, 0x53, 0xfb, 0xd3,
- 0xbe, 0xfa, 0x34, 0xf3, 0xf9, 0xb2, 0x87, 0xed, 0xac, 0x22, 0x3f, 0x26,
- 0xee, 0x50, 0x3d, 0xf0, 0x8a, 0xa6, 0xc5, 0x12, 0xcb, 0x0c, 0xde, 0x58,
- 0x9f, 0x17, 0x80, 0xad, 0x7e, 0xa6, 0x21, 0x96, 0xeb, 0x67, 0x4c, 0xfb,
- 0xaa, 0x78, 0x7d, 0x1b, 0xc6, 0x7e, 0xae, 0x67, 0x83, 0xac, 0xd7, 0xd1,
- 0x5a, 0x60, 0x38, 0x86, 0x3e, 0x61, 0x9c, 0xee, 0x85, 0x48, 0xa2, 0x77,
- 0x14, 0xf6, 0x74, 0xad, 0x87, 0xbd, 0xf7, 0x98, 0x07, 0xc6, 0xf0, 0x89,
- 0x3e, 0xba, 0x77, 0xc2, 0xfd, 0xe8, 0x33, 0xc2, 0xbe, 0x3e, 0xd8, 0xd1,
- 0x35, 0x8d, 0xf1, 0xbd, 0xe7, 0x80, 0x7f, 0x3d, 0x8f, 0x75, 0xfb, 0x0e,
- 0x30, 0x3f, 0xeb, 0x9d, 0xd7, 0x75, 0xfe, 0x09, 0xb9, 0xee, 0x5a, 0x79,
- 0xfe, 0xbb, 0xc3, 0xdc, 0x7f, 0x88, 0x14, 0xf5, 0x3b, 0xef, 0xe8, 0xd3,
- 0x3c, 0xde, 0xc5, 0xf7, 0xe2, 0x2d, 0xee, 0x17, 0xba, 0x72, 0xfa, 0x85,
- 0x09, 0xd4, 0xe9, 0xe1, 0xe9, 0x8c, 0x9c, 0x30, 0xea, 0x65, 0xbe, 0x93,
- 0x7f, 0xf5, 0x44, 0x09, 0xfb, 0xad, 0x78, 0x15, 0xf0, 0xd8, 0x2a, 0xdc,
- 0xd7, 0x5d, 0xfb, 0x99, 0x9f, 0x46, 0xf2, 0xd3, 0xf2, 0xa9, 0xd1, 0xdc,
- 0xf5, 0x32, 0x7e, 0x3a, 0x8d, 0xf8, 0x51, 0xe7, 0x40, 0x3e, 0x19, 0x92,
- 0xf3, 0xf7, 0xcc, 0xba, 0x3f, 0x41, 0x7a, 0x57, 0x0c, 0x4f, 0xd3, 0xfa,
- 0x72, 0x51, 0x44, 0xf1, 0x57, 0x16, 0x9e, 0x82, 0x1d, 0x89, 0x41, 0xb6,
- 0xbf, 0x67, 0x2d, 0x70, 0x3f, 0xfb, 0x5f, 0xf9, 0xf5, 0xca, 0x1a, 0x9d,
- 0xd6, 0x8d, 0xf7, 0xe2, 0x1c, 0x95, 0x3f, 0xb9, 0xfd, 0xb0, 0x8a, 0x87,
- 0xb2, 0x06, 0x1a, 0x8b, 0xce, 0x7d, 0xf2, 0x9c, 0x90, 0xe1, 0x47, 0x19,
- 0x47, 0x06, 0x47, 0x7c, 0x5f, 0xdb, 0xe3, 0x44, 0xc6, 0x91, 0x8a, 0x57,
- 0x6b, 0x7c, 0x59, 0xe3, 0xc7, 0x1e, 0x37, 0x61, 0xba, 0x57, 0x8c, 0x22,
- 0x90, 0xa6, 0x77, 0x44, 0x62, 0x70, 0xe0, 0xc1, 0xfc, 0x9d, 0x00, 0x7f,
- 0x09, 0xd6, 0x5b, 0x4f, 0x51, 0x1f, 0xfa, 0x94, 0xe8, 0x67, 0x3f, 0x4e,
- 0xd4, 0x72, 0xde, 0x57, 0xc1, 0x8f, 0x3d, 0xcf, 0x40, 0x9f, 0x1e, 0xce,
- 0x9f, 0xdb, 0xdc, 0x5f, 0xc0, 0xff, 0x7e, 0xbd, 0x63, 0x94, 0xfd, 0xcd,
- 0x71, 0xb8, 0x8b, 0x79, 0xb8, 0x05, 0x1e, 0x74, 0xc5, 0x43, 0xca, 0xe4,
- 0x41, 0xd5, 0x19, 0xeb, 0x3e, 0x85, 0x46, 0x1c, 0x49, 0x5c, 0xa0, 0x5f,
- 0xa1, 0x3e, 0x2c, 0x8f, 0xed, 0x36, 0xe4, 0x1a, 0xa4, 0x7d, 0x61, 0xb6,
- 0x2f, 0x24, 0x76, 0x2e, 0xb7, 0xae, 0x0b, 0xf2, 0xba, 0x80, 0xb1, 0x0e,
- 0xf3, 0xc8, 0x53, 0x7d, 0x1e, 0x7e, 0x25, 0x8f, 0x6a, 0xdf, 0xdc, 0x7c,
- 0xb4, 0xf2, 0x49, 0x15, 0x9a, 0xfe, 0x50, 0x87, 0x0c, 0xbf, 0x51, 0xbd,
- 0xd2, 0xcd, 0xfa, 0x73, 0x97, 0xea, 0x79, 0xe0, 0x64, 0x37, 0xea, 0xc5,
- 0xc9, 0xee, 0xd3, 0x7c, 0xff, 0x32, 0x2f, 0x2d, 0xf4, 0x6e, 0x30, 0xb8,
- 0xab, 0xb2, 0xd7, 0x1f, 0xbb, 0x1e, 0x15, 0x16, 0x3d, 0xd4, 0xb9, 0x0f,
- 0xeb, 0x0f, 0xd0, 0x9f, 0x6e, 0xa0, 0xfe, 0x40, 0x33, 0xfb, 0x6c, 0xfb,
- 0x3d, 0x72, 0xeb, 0xfe, 0xe3, 0xde, 0x23, 0x5b, 0x1a, 0xac, 0xe7, 0xc5,
- 0xc4, 0xd8, 0x08, 0xce, 0x69, 0xe1, 0x7b, 0x7b, 0x3b, 0xe7, 0xf7, 0xb5,
- 0x40, 0x84, 0xce, 0x4d, 0xbe, 0x46, 0xf6, 0x8a, 0x68, 0x10, 0xf6, 0x25,
- 0x5f, 0xc7, 0xf7, 0x64, 0x08, 0xf3, 0xe5, 0x21, 0xfc, 0x3e, 0xd0, 0xe2,
- 0xd7, 0x49, 0xbe, 0x3c, 0x04, 0x8c, 0x72, 0x5d, 0x18, 0x33, 0xdf, 0x11,
- 0xc0, 0x21, 0xdf, 0x7c, 0xef, 0x08, 0xbc, 0xc7, 0xce, 0xfb, 0x50, 0x37,
- 0x44, 0x0c, 0xfd, 0x73, 0x53, 0x8d, 0x4e, 0xdf, 0x5b, 0x63, 0xb8, 0x9f,
- 0x51, 0x97, 0xe7, 0xda, 0x55, 0x81, 0x78, 0x2d, 0xcf, 0xbe, 0x37, 0xac,
- 0xef, 0x12, 0x3d, 0x31, 0x68, 0xf6, 0xfd, 0x76, 0x3d, 0x90, 0x67, 0x72,
- 0x7f, 0x1a, 0x1a, 0xfd, 0xf5, 0xa3, 0xbc, 0x47, 0x3c, 0xdc, 0xaf, 0xdd,
- 0x99, 0x45, 0xbc, 0x16, 0x89, 0x0b, 0x23, 0xe0, 0x61, 0x6c, 0xc4, 0x29,
- 0x8f, 0xa5, 0x1e, 0xea, 0x1c, 0xd8, 0xa5, 0xec, 0xcc, 0x9e, 0x0b, 0xbd,
- 0x76, 0xb0, 0xfe, 0xbf, 0xd2, 0xef, 0x17, 0x51, 0xb6, 0x57, 0xee, 0x8b,
- 0xf9, 0x8d, 0xf4, 0x6e, 0xca, 0x13, 0x69, 0x73, 0x6c, 0x7f, 0xcf, 0xb4,
- 0x90, 0x5e, 0x85, 0x7c, 0xaf, 0x47, 0x2d, 0xfd, 0x07, 0xe4, 0x8b, 0xeb,
- 0x81, 0xc7, 0xea, 0x95, 0xdf, 0x94, 0x7f, 0x95, 0x3f, 0xe1, 0xf7, 0xe8,
- 0x4a, 0x12, 0x6b, 0x4c, 0xae, 0xa4, 0x84, 0xaf, 0x4f, 0x4e, 0xa9, 0x7b,
- 0x1e, 0xeb, 0xb7, 0xc4, 0xa5, 0xfc, 0x07, 0xe2, 0xfb, 0x38, 0x2e, 0xd6,
- 0x9f, 0x19, 0xb3, 0xfd, 0xbd, 0xe0, 0x3f, 0xeb, 0x3b, 0xc1, 0x23, 0xce,
- 0xe7, 0xf1, 0x74, 0x83, 0xea, 0x7b, 0xe7, 0x7b, 0xef, 0x48, 0x3b, 0x3e,
- 0xba, 0x9f, 0xdb, 0x47, 0x67, 0xfb, 0x60, 0x65, 0xaf, 0x5c, 0x57, 0xcf,
- 0x71, 0xac, 0x89, 0xa6, 0x0d, 0xf8, 0x7d, 0x23, 0xec, 0x47, 0xde, 0x84,
- 0xfd, 0x4e, 0xef, 0x52, 0x23, 0x8e, 0xf2, 0xa9, 0x60, 0x2c, 0x2c, 0xcc,
- 0x27, 0xfb, 0x8e, 0x5c, 0xbc, 0x44, 0x62, 0x9f, 0x0d, 0x06, 0x31, 0x5f,
- 0xd2, 0x84, 0x63, 0xbc, 0x14, 0xf7, 0x1e, 0x71, 0x08, 0x79, 0xf1, 0xe9,
- 0x31, 0xe0, 0x27, 0xe2, 0x55, 0xec, 0x53, 0x78, 0x90, 0xee, 0x53, 0xad,
- 0x04, 0x34, 0x67, 0x06, 0x39, 0xde, 0x4b, 0xdd, 0xf4, 0xfb, 0xe2, 0xac,
- 0x08, 0x49, 0xf4, 0x99, 0xf9, 0x8b, 0xb8, 0xf6, 0x5a, 0xfc, 0xff, 0xa8,
- 0x71, 0x4e, 0xf5, 0xc9, 0x88, 0x63, 0x6c, 0xc3, 0xf1, 0xae, 0xe5, 0xc6,
- 0xbb, 0xe2, 0xa9, 0xd4, 0xed, 0x18, 0xdf, 0xab, 0xe7, 0xc6, 0xb7, 0xd2,
- 0x4f, 0xf2, 0x7d, 0xd7, 0xbc, 0x3f, 0xe7, 0xee, 0x8f, 0xf7, 0xd3, 0x85,
- 0x27, 0x16, 0xdf, 0xc0, 0x8d, 0xd5, 0xf2, 0xfc, 0x92, 0x39, 0x7d, 0x72,
- 0x6e, 0xfe, 0xa1, 0xde, 0xbd, 0x61, 0xc4, 0xc3, 0x7f, 0x69, 0x4a, 0x77,
- 0x8f, 0xc8, 0x15, 0x00, 0x00, 0x00 };
+#define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
+ 0xad, 0x58, 0x4d, 0x4c, 0x54, 0x57, 0x14, 0xbe, 0xf3, 0xc3, 0xcc, 0x30,
+ 0xbc, 0x99, 0x41, 0x98, 0x0e, 0x7f, 0xa6, 0x22, 0x28, 0x82, 0x1d, 0x14,
+ 0x06, 0xd4, 0xb6, 0x36, 0xa9, 0xc1, 0x06, 0xb5, 0xb5, 0x11, 0x69, 0x63,
+ 0xba, 0x68, 0x8a, 0x60, 0x45, 0x06, 0xc1, 0x10, 0x31, 0x2e, 0xdc, 0x74,
+ 0x02, 0x16, 0xbb, 0x98, 0x85, 0x98, 0xe2, 0x60, 0xd3, 0x18, 0x52, 0x37,
+ 0xa6, 0x3b, 0x92, 0xb6, 0x62, 0xbb, 0x30, 0x31, 0x2d, 0xb1, 0xb6, 0x89,
+ 0x36, 0xb1, 0x7f, 0x9b, 0xa6, 0xa6, 0x5a, 0x8a, 0x4a, 0x2d, 0xda, 0xb2,
+ 0xaa, 0xd0, 0x77, 0xcf, 0x77, 0xee, 0x9b, 0x37, 0x33, 0x6f, 0x44, 0x53,
+ 0xd9, 0x1c, 0xee, 0x7d, 0xe7, 0x9e, 0x7b, 0xce, 0x77, 0x7e, 0xef, 0xe4,
+ 0x0b, 0x21, 0x9c, 0x22, 0x36, 0xbe, 0x4c, 0xa7, 0x62, 0x89, 0xdd, 0xe1,
+ 0xd1, 0xc9, 0x82, 0x10, 0x39, 0xc5, 0x72, 0x2d, 0xec, 0x82, 0xff, 0x56,
+ 0xe7, 0x13, 0xb9, 0x36, 0x2e, 0xbf, 0xbb, 0xc5, 0xeb, 0x76, 0x7c, 0x77,
+ 0x0a, 0x49, 0x03, 0x42, 0xc4, 0x24, 0xcd, 0x67, 0xba, 0x9d, 0xe9, 0x4a,
+ 0x1b, 0xe8, 0x46, 0xa6, 0x51, 0xa6, 0x2b, 0x98, 0xd6, 0xdb, 0x41, 0x57,
+ 0x31, 0xad, 0xe6, 0x7d, 0x8d, 0xcf, 0xd7, 0xf2, 0xfe, 0x7b, 0x4c, 0x8f,
+ 0xf2, 0xbe, 0xa6, 0xf3, 0x29, 0xbd, 0xe4, 0x7a, 0x66, 0x41, 0xc4, 0xf4,
+ 0x33, 0x42, 0xdf, 0xae, 0x51, 0xfb, 0x1a, 0x91, 0x58, 0x0d, 0xf4, 0x7e,
+ 0xad, 0x5c, 0xf2, 0xfd, 0x61, 0xc1, 0x27, 0xf7, 0x6f, 0x2e, 0x28, 0x79,
+ 0x03, 0x0e, 0xb9, 0xfe, 0x55, 0x5f, 0xdb, 0xe4, 0x32, 0x18, 0x82, 0x98,
+ 0x60, 0x71, 0x5c, 0xca, 0x71, 0x88, 0xd1, 0x61, 0x0f, 0xa1, 0x72, 0x52,
+ 0xc3, 0x3a, 0x46, 0x78, 0xd8, 0xf4, 0x35, 0xcb, 0x63, 0x5a, 0xe2, 0xc3,
+ 0xbd, 0xbb, 0xca, 0x71, 0xdf, 0x8f, 0xcf, 0x80, 0x2f, 0x16, 0x50, 0x80,
+ 0xe2, 0xfb, 0x32, 0xc1, 0xdf, 0xf7, 0xcb, 0xf5, 0xac, 0xad, 0xd0, 0x06,
+ 0x5c, 0xdd, 0xcc, 0x65, 0xcf, 0x91, 0xfb, 0xcb, 0x1b, 0x4f, 0x0e, 0x83,
+ 0xbf, 0xad, 0x1c, 0xfb, 0x4f, 0x87, 0xa5, 0x3c, 0x97, 0x88, 0x31, 0x15,
+ 0xb5, 0xa4, 0x97, 0x2d, 0x56, 0x9b, 0x2a, 0xff, 0x97, 0x61, 0xac, 0xda,
+ 0x7d, 0x90, 0xeb, 0x4d, 0x91, 0x1b, 0xca, 0x90, 0xfb, 0x53, 0xae, 0x59,
+ 0xbe, 0xdf, 0x06, 0xf9, 0xde, 0x45, 0xe5, 0x77, 0xf8, 0x40, 0x0b, 0xc3,
+ 0x56, 0xf7, 0xe4, 0x2e, 0xa2, 0x7f, 0xf7, 0xa2, 0xf2, 0x8f, 0x18, 0xfa,
+ 0x2b, 0xff, 0xa9, 0xef, 0xe9, 0x38, 0xd2, 0xf2, 0xe3, 0xd8, 0x5a, 0x16,
+ 0xb3, 0x5a, 0xd9, 0xcf, 0x7a, 0x3a, 0x40, 0x37, 0x85, 0x89, 0xc4, 0xf7,
+ 0x70, 0x80, 0x37, 0x57, 0xc9, 0xfb, 0x0b, 0x84, 0xd3, 0x2e, 0xe5, 0xd5,
+ 0x79, 0x5c, 0xe7, 0xb1, 0xff, 0x06, 0xfb, 0xeb, 0x6d, 0x36, 0xe8, 0xa6,
+ 0x57, 0x02, 0xb4, 0xb0, 0xd0, 0x99, 0xc7, 0xf2, 0xd9, 0xdf, 0xb1, 0x3c,
+ 0x9c, 0x9f, 0xd4, 0xa4, 0x9e, 0x5f, 0xeb, 0xf1, 0x63, 0xe5, 0x7f, 0xc7,
+ 0x43, 0xfc, 0x8f, 0xf3, 0x4b, 0x56, 0xe1, 0xeb, 0xf1, 0x4e, 0xac, 0xcb,
+ 0xce, 0xe4, 0x13, 0x4e, 0xa3, 0xe3, 0x56, 0xf1, 0x92, 0x2e, 0x5f, 0xcf,
+ 0xe3, 0x00, 0xee, 0x11, 0x15, 0x1e, 0x52, 0x0e, 0xf8, 0xea, 0x3c, 0xb5,
+ 0x96, 0x38, 0x89, 0x93, 0x2b, 0xe5, 0xbe, 0x5d, 0xb4, 0x3a, 0x34, 0xba,
+ 0xa7, 0x35, 0xaa, 0xf2, 0x06, 0xdf, 0x3b, 0x5d, 0x44, 0x8a, 0xdb, 0x87,
+ 0xa4, 0xdd, 0x01, 0xb1, 0xdb, 0x1e, 0x20, 0x7e, 0xe0, 0xe4, 0xf0, 0x68,
+ 0x9f, 0x81, 0xff, 0xc2, 0x32, 0x8d, 0x6c, 0xea, 0x6c, 0xc0, 0xb9, 0x60,
+ 0x04, 0x74, 0x24, 0x92, 0x23, 0x49, 0xb8, 0xb3, 0x9f, 0x96, 0x6b, 0x7e,
+ 0xab, 0xf7, 0x10, 0x5f, 0xac, 0x56, 0xe5, 0xa5, 0xf2, 0xa3, 0xc4, 0xed,
+ 0x90, 0x91, 0x87, 0xa2, 0x12, 0x38, 0xff, 0xbe, 0x52, 0xf2, 0xeb, 0x60,
+ 0x57, 0xe0, 0x9e, 0xa4, 0x7e, 0xe6, 0xbc, 0xee, 0x35, 0xe5, 0xf5, 0xe3,
+ 0xc5, 0xc5, 0x26, 0xc2, 0x67, 0x13, 0xe3, 0x54, 0xce, 0x71, 0xb8, 0xd4,
+ 0x22, 0x0e, 0x03, 0xf4, 0xff, 0xad, 0xa6, 0x7c, 0xc2, 0x79, 0x07, 0xf6,
+ 0x4f, 0x34, 0x9f, 0x83, 0x9f, 0xb6, 0x11, 0x1e, 0xc2, 0x7b, 0xf4, 0x53,
+ 0x9c, 0x6a, 0xa7, 0xfc, 0xef, 0x6d, 0xec, 0xfc, 0x1c, 0xeb, 0x0e, 0x87,
+ 0x5c, 0xef, 0xd7, 0xf6, 0x4c, 0x80, 0x3f, 0x67, 0x10, 0xb8, 0xef, 0xe0,
+ 0x5b, 0xb6, 0x39, 0xa8, 0xde, 0xc4, 0x5d, 0x83, 0xb4, 0xd4, 0x26, 0xe9,
+ 0x7b, 0xbe, 0x38, 0x36, 0x8e, 0xef, 0x07, 0xf2, 0xa4, 0x9d, 0xaf, 0x1a,
+ 0x75, 0x29, 0xea, 0xc2, 0xf9, 0xf8, 0x30, 0xea, 0xca, 0xf4, 0x27, 0x72,
+ 0xdd, 0x16, 0x9e, 0x06, 0x7f, 0x38, 0x3a, 0xc4, 0x82, 0xed, 0xc0, 0xf1,
+ 0x96, 0x1d, 0xfc, 0x1c, 0xae, 0x5e, 0x27, 0xf9, 0xd1, 0x26, 0xb4, 0x66,
+ 0xd0, 0x77, 0xe9, 0xfb, 0xbf, 0xb6, 0x38, 0xe1, 0xb6, 0xcb, 0xef, 0x3c,
+ 0xa7, 0xf0, 0x61, 0x1a, 0x50, 0x76, 0x81, 0x3e, 0x6a, 0x3e, 0x0c, 0x69,
+ 0xd9, 0xf2, 0x80, 0xfd, 0x59, 0xb3, 0x58, 0x1e, 0x80, 0x36, 0x57, 0x81,
+ 0xba, 0x2a, 0xa9, 0x9e, 0x3c, 0x46, 0x3e, 0xb0, 0x5e, 0x19, 0xf9, 0x86,
+ 0xdd, 0x64, 0x9c, 0x12, 0xd1, 0xe3, 0x33, 0x25, 0x5e, 0x39, 0x3f, 0x96,
+ 0xeb, 0x7e, 0x50, 0x71, 0x27, 0x05, 0xba, 0xc5, 0x7e, 0x96, 0x1b, 0x65,
+ 0x3c, 0x7a, 0x18, 0x8f, 0x19, 0xa6, 0x07, 0xf2, 0x14, 0x0e, 0xa0, 0xc7,
+ 0x34, 0xdc, 0xdb, 0x1a, 0x95, 0x7e, 0x0c, 0x5a, 0xf4, 0x17, 0xd5, 0x47,
+ 0xe0, 0xa7, 0x51, 0xf6, 0xeb, 0x29, 0xa3, 0x9f, 0x28, 0x7c, 0xb3, 0xf5,
+ 0x95, 0xd4, 0x7c, 0x4a, 0xb3, 0x33, 0xfe, 0x55, 0x05, 0x8e, 0x17, 0x54,
+ 0x82, 0x1a, 0xf8, 0x56, 0x51, 0x1e, 0xfb, 0x8b, 0x26, 0x94, 0x7d, 0x52,
+ 0xbf, 0x3b, 0x2a, 0x0f, 0xfd, 0x89, 0x01, 0xa2, 0xde, 0x82, 0x33, 0xf2,
+ 0x9e, 0x52, 0x8b, 0xba, 0x92, 0x9a, 0xcf, 0xe9, 0xf8, 0x1e, 0xf0, 0x51,
+ 0xc1, 0x6d, 0xbc, 0x32, 0x95, 0x9a, 0xb7, 0xc8, 0x4f, 0xb7, 0x11, 0xdf,
+ 0xc1, 0xf5, 0xec, 0x07, 0xa6, 0xa1, 0x0d, 0x52, 0x6e, 0x0b, 0xdf, 0x53,
+ 0xc7, 0xf7, 0x68, 0xa6, 0xba, 0x21, 0xf5, 0xfc, 0x73, 0x5e, 0xd5, 0x0b,
+ 0x15, 0x1f, 0xc9, 0xba, 0xa1, 0xfc, 0x40, 0xf7, 0x87, 0xaf, 0x4c, 0xc9,
+ 0xf3, 0x65, 0x8b, 0xd4, 0x91, 0x1b, 0x86, 0xbc, 0xef, 0x8d, 0x3a, 0x21,
+ 0xbf, 0xe7, 0x89, 0x17, 0x79, 0x99, 0x5a, 0x0f, 0xff, 0xd2, 0xeb, 0x21,
+ 0xd9, 0xe1, 0xd1, 0xce, 0x71, 0xfd, 0xeb, 0x97, 0xf7, 0x14, 0xb3, 0xde,
+ 0xc5, 0xaa, 0xaf, 0xe9, 0x7a, 0x73, 0x9d, 0x6c, 0x33, 0xd7, 0xbb, 0x1f,
+ 0xe6, 0x93, 0x75, 0x4b, 0xae, 0xaf, 0xcd, 0x67, 0xce, 0x27, 0x96, 0xb8,
+ 0xc6, 0x44, 0x00, 0x73, 0x58, 0x2c, 0x20, 0xcf, 0xe5, 0xd8, 0x32, 0xeb,
+ 0x5f, 0xba, 0x1d, 0xc0, 0xa5, 0xdd, 0xee, 0x23, 0xbe, 0xeb, 0x7d, 0xf2,
+ 0xdc, 0xb4, 0x50, 0xf6, 0xa2, 0x0e, 0x96, 0x73, 0xbf, 0x5f, 0xca, 0x7a,
+ 0xeb, 0xf2, 0x6a, 0x29, 0x1f, 0x3c, 0xd7, 0xfb, 0xcc, 0x7a, 0x5f, 0x98,
+ 0xcf, 0x7e, 0x9f, 0x75, 0x1c, 0xf4, 0x71, 0x9f, 0xe5, 0x39, 0xc1, 0xb3,
+ 0xe7, 0x0b, 0xa5, 0x17, 0xdf, 0x1f, 0x50, 0x7a, 0x68, 0xe4, 0xa7, 0xa9,
+ 0x7e, 0x29, 0xa7, 0x50, 0x70, 0xd8, 0x88, 0xde, 0x6a, 0xd4, 0xdf, 0x99,
+ 0xbd, 0xb0, 0xa3, 0xb7, 0x4a, 0xea, 0xa1, 0x7b, 0x25, 0x86, 0x3c, 0x17,
+ 0xdc, 0x8f, 0xbe, 0x1c, 0xb6, 0xf2, 0xeb, 0xb7, 0xcc, 0x17, 0x64, 0xfb,
+ 0xf2, 0xd9, 0xbe, 0xb0, 0x48, 0xaf, 0xf3, 0x6d, 0xe5, 0xd4, 0x0f, 0x98,
+ 0xef, 0x05, 0xd5, 0x0f, 0x74, 0x3e, 0xc2, 0x99, 0xe5, 0x58, 0xe1, 0x64,
+ 0x25, 0x67, 0x82, 0xe3, 0xa0, 0x8b, 0xf9, 0x9c, 0x59, 0xe7, 0x9b, 0xb9,
+ 0x55, 0xd4, 0x57, 0x4e, 0x1f, 0xa1, 0xfe, 0xe0, 0x33, 0xe2, 0x34, 0xd5,
+ 0x8e, 0xe3, 0x4f, 0x10, 0x77, 0x9a, 0xff, 0xc4, 0x3e, 0x7f, 0x36, 0x7c,
+ 0x9d, 0x72, 0x7b, 0x6c, 0x76, 0x42, 0xf9, 0x47, 0x23, 0x7b, 0xa7, 0xfa,
+ 0xd5, 0x9c, 0x6f, 0xc6, 0xdd, 0x6e, 0xc2, 0x1d, 0xfc, 0x98, 0xef, 0xfe,
+ 0x0f, 0xde, 0x56, 0xf3, 0x41, 0x9f, 0x91, 0x9f, 0x03, 0x2e, 0xab, 0xfa,
+ 0xbf, 0xd6, 0x88, 0x97, 0x83, 0x3c, 0xe7, 0xcd, 0x69, 0xf4, 0x4f, 0x64,
+ 0x26, 0x4e, 0x4b, 0xad, 0xe4, 0xac, 0xe4, 0x5b, 0x1d, 0x39, 0xc8, 0x76,
+ 0x5d, 0x76, 0xc0, 0xee, 0xae, 0xbd, 0x58, 0x5f, 0xe1, 0x7a, 0x7d, 0x8f,
+ 0xeb, 0xe3, 0x4e, 0x0f, 0xe8, 0x4c, 0x35, 0xe1, 0x11, 0x39, 0x78, 0x5e,
+ 0xc9, 0x27, 0xb9, 0xda, 0x1c, 0xe3, 0xf9, 0x92, 0x83, 0xed, 0xac, 0x20,
+ 0x3f, 0x46, 0xee, 0x52, 0x3d, 0x70, 0x8a, 0xa6, 0xe5, 0x92, 0x96, 0xe8,
+ 0xb8, 0xb1, 0x3e, 0x1b, 0x41, 0x5b, 0xd5, 0x80, 0x5f, 0x93, 0xee, 0x67,
+ 0x6c, 0xbb, 0x2a, 0xf8, 0x7c, 0x3b, 0xd6, 0x6e, 0xae, 0x67, 0x09, 0xd6,
+ 0xeb, 0xfd, 0x6a, 0x50, 0x7f, 0x0d, 0xe6, 0x84, 0x29, 0xea, 0x0b, 0x81,
+ 0x48, 0xff, 0x04, 0xec, 0xe9, 0xd9, 0x0c, 0x7b, 0xef, 0x33, 0x0e, 0x4c,
+ 0xfd, 0xa7, 0x06, 0xa9, 0xef, 0xf8, 0x87, 0x30, 0x67, 0xf8, 0x5d, 0x83,
+ 0xb0, 0xa3, 0x67, 0x0e, 0xeb, 0xfb, 0xcf, 0x81, 0xfe, 0xf3, 0x3c, 0xce,
+ 0x1d, 0x3a, 0xc2, 0xf8, 0x6c, 0xb6, 0x3e, 0xd7, 0xf5, 0x37, 0xf8, 0x7a,
+ 0xab, 0xe5, 0xfd, 0x6f, 0x8d, 0xf1, 0xfc, 0x21, 0xa2, 0x34, 0xef, 0xbc,
+ 0xa9, 0xcd, 0xf1, 0xba, 0x9b, 0xfb, 0xe2, 0x6d, 0x9e, 0x17, 0x7a, 0xd2,
+ 0xe6, 0x85, 0x69, 0xd4, 0xe9, 0xb1, 0xb9, 0xb8, 0xdc, 0xd0, 0xeb, 0x65,
+ 0xae, 0x95, 0x7f, 0x7d, 0x91, 0x22, 0xf6, 0x5b, 0x70, 0x1d, 0xe8, 0xc8,
+ 0x3a, 0xf4, 0xeb, 0x9e, 0xc3, 0x8c, 0x4f, 0x23, 0xf9, 0x69, 0xcd, 0xec,
+ 0x44, 0xfa, 0x79, 0x19, 0x3f, 0xed, 0xf3, 0x78, 0x3f, 0x6e, 0xd6, 0xa9,
+ 0xba, 0x0f, 0xe7, 0x3a, 0xe8, 0x7d, 0x71, 0xcf, 0x98, 0x3f, 0xa7, 0x49,
+ 0xff, 0xb2, 0xb1, 0x39, 0x92, 0x53, 0x2a, 0x0a, 0x29, 0x0e, 0x4b, 0xfc,
+ 0xb3, 0xb0, 0x27, 0x92, 0x60, 0x1c, 0xfa, 0x9e, 0x05, 0x3d, 0xcc, 0x71,
+ 0xa0, 0xfc, 0x7b, 0x75, 0x83, 0x46, 0xe7, 0xa6, 0xfa, 0x71, 0x8f, 0xca,
+ 0xa3, 0xf4, 0xb9, 0x58, 0xc5, 0x45, 0x49, 0x03, 0xad, 0x45, 0xd7, 0x21,
+ 0xb2, 0x53, 0xf7, 0xa7, 0x8c, 0x27, 0x1d, 0x2b, 0xee, 0xdb, 0xa9, 0xf1,
+ 0x22, 0xe3, 0x49, 0xc5, 0xad, 0x39, 0xce, 0xcc, 0x71, 0x94, 0x1a, 0x3f,
+ 0x7e, 0xea, 0x2f, 0x7a, 0x31, 0xa0, 0x77, 0x89, 0x2b, 0x92, 0x18, 0x7e,
+ 0x38, 0x8e, 0xa7, 0x80, 0x63, 0x84, 0xf5, 0xd6, 0xa2, 0x34, 0x8f, 0x3e,
+ 0x25, 0x86, 0xd8, 0x9f, 0xd3, 0xd5, 0x9c, 0xff, 0x15, 0xf0, 0x67, 0xdf,
+ 0x0a, 0xe8, 0xd3, 0xc7, 0x79, 0x74, 0x87, 0xe7, 0x0c, 0xc4, 0x81, 0x5b,
+ 0xeb, 0x9c, 0x60, 0xbf, 0x73, 0x3c, 0x76, 0x33, 0x0e, 0xb7, 0x81, 0x83,
+ 0xa6, 0x70, 0x88, 0x1a, 0x38, 0xa8, 0x7a, 0x63, 0x96, 0x53, 0xa0, 0xc7,
+ 0x93, 0xa4, 0x4b, 0xb4, 0xab, 0x34, 0x8f, 0xe5, 0xb0, 0xdd, 0x3a, 0x5f,
+ 0x83, 0xb4, 0xcf, 0xcf, 0xf6, 0xf9, 0xc4, 0xbe, 0x35, 0xe6, 0x73, 0x79,
+ 0x7c, 0xce, 0xab, 0x9f, 0xc3, 0x3e, 0xf2, 0x55, 0xcb, 0x82, 0xaf, 0xc4,
+ 0x51, 0xc9, 0x4d, 0xcf, 0x4b, 0x33, 0x9e, 0x54, 0xa9, 0xe9, 0x0f, 0xf5,
+ 0x48, 0xf7, 0x1b, 0xd5, 0x2d, 0xcd, 0xa8, 0x43, 0xf7, 0xa8, 0xae, 0x7b,
+ 0x4f, 0xf7, 0xa2, 0x6e, 0x9c, 0xee, 0x3d, 0xcb, 0x7d, 0x98, 0x71, 0x69,
+ 0xa1, 0xf7, 0x83, 0x8e, 0x5d, 0x45, 0x6a, 0x1d, 0x4a, 0xd5, 0xa3, 0xcc,
+ 0xa4, 0x87, 0xba, 0x77, 0xb1, 0x39, 0x01, 0x73, 0xea, 0x16, 0x9a, 0x13,
+ 0x3c, 0xc6, 0xbc, 0x9d, 0xda, 0x4f, 0x26, 0x1f, 0x3c, 0x6e, 0x3f, 0xd9,
+ 0xd9, 0x60, 0xbe, 0xaf, 0x46, 0x4c, 0x8e, 0xe3, 0x9e, 0x16, 0xee, 0xdf,
+ 0xbb, 0x39, 0xcf, 0xaf, 0x7b, 0x03, 0x74, 0x6f, 0xc7, 0x2b, 0x64, 0xaf,
+ 0x08, 0xe5, 0xc1, 0xbe, 0x8e, 0xed, 0xf8, 0xde, 0xe1, 0xc3, 0x7e, 0xa9,
+ 0x0f, 0xbf, 0xa3, 0xb4, 0xb8, 0x35, 0xe2, 0x2f, 0xf5, 0x81, 0x86, 0xb8,
+ 0x3e, 0x4c, 0x1a, 0xef, 0x09, 0xd0, 0x51, 0x57, 0xb6, 0xf7, 0x04, 0xde,
+ 0x65, 0x17, 0x5d, 0xa8, 0x1f, 0xa2, 0x06, 0x73, 0x74, 0x53, 0x95, 0x46,
+ 0xdf, 0x5b, 0x6b, 0xd0, 0xa7, 0x51, 0x9f, 0x33, 0xed, 0x2a, 0x43, 0xbc,
+ 0x96, 0x26, 0xdf, 0x1d, 0xe6, 0xf7, 0x89, 0x16, 0x49, 0x18, 0xf3, 0x7f,
+ 0xaa, 0x1e, 0xc8, 0x33, 0x29, 0x9f, 0x96, 0xfa, 0x9c, 0xfd, 0x28, 0xef,
+ 0x12, 0x07, 0xcf, 0x6d, 0x77, 0xf9, 0x77, 0x82, 0x42, 0x71, 0x69, 0x1c,
+ 0x38, 0x4c, 0x8e, 0x5b, 0xe5, 0xb1, 0xd4, 0x43, 0xdd, 0x03, 0xbb, 0x94,
+ 0x9d, 0xc9, 0x7b, 0xa1, 0xd7, 0x5e, 0xd6, 0xff, 0x06, 0xfd, 0x9e, 0x11,
+ 0x62, 0x7b, 0xa5, 0x5c, 0xec, 0x6f, 0xa5, 0xf7, 0x53, 0x8e, 0x88, 0x19,
+ 0xeb, 0xd4, 0x77, 0x4d, 0x0b, 0xe9, 0x55, 0xc0, 0xfd, 0x3d, 0x64, 0x9a,
+ 0x43, 0xc0, 0x1f, 0xac, 0x03, 0x1d, 0xa9, 0x53, 0x7e, 0x53, 0xfe, 0x55,
+ 0xfe, 0x84, 0xdf, 0x43, 0xf5, 0xc4, 0xd6, 0xd8, 0x51, 0x4f, 0x09, 0x5f,
+ 0xd7, 0x31, 0xab, 0xfa, 0x3d, 0xce, 0xef, 0x0c, 0x4b, 0xfe, 0x77, 0xc4,
+ 0x77, 0x61, 0x34, 0xd8, 0x9f, 0x99, 0x26, 0xe7, 0x7c, 0xc1, 0x7f, 0xe6,
+ 0xf7, 0x82, 0x43, 0x5c, 0xcc, 0xe1, 0xed, 0x06, 0x35, 0xff, 0x66, 0x7b,
+ 0xf7, 0x48, 0x3b, 0xba, 0x1f, 0xa4, 0xcf, 0xd3, 0xc9, 0x79, 0x58, 0xd9,
+ 0x2b, 0xcf, 0xd5, 0x71, 0x1c, 0x7b, 0x44, 0xd3, 0x16, 0xfc, 0xce, 0xe1,
+ 0x77, 0x23, 0x6f, 0xfc, 0x6e, 0xab, 0xf7, 0xa9, 0x1e, 0x47, 0xb9, 0x54,
+ 0x30, 0x96, 0x16, 0xe4, 0x92, 0x7d, 0x27, 0x2e, 0x7f, 0x43, 0x6c, 0x1f,
+ 0x25, 0xf2, 0xb0, 0x5f, 0xd4, 0x84, 0x6b, 0x9c, 0x14, 0xf7, 0x0e, 0x71,
+ 0x14, 0x79, 0xf1, 0xe1, 0x08, 0xe8, 0x07, 0xe2, 0x65, 0xc8, 0x29, 0x18,
+ 0xa0, 0xbe, 0xea, 0x29, 0x02, 0xcc, 0xf1, 0x04, 0xc7, 0x7b, 0xb1, 0x9d,
+ 0x7e, 0x87, 0x5d, 0x10, 0x3e, 0xfe, 0x9d, 0x8c, 0xf3, 0x17, 0x71, 0xed,
+ 0x34, 0xf9, 0xff, 0x51, 0xe3, 0x1c, 0xfd, 0x33, 0xc1, 0x7e, 0xe7, 0x78,
+ 0xf7, 0xa4, 0xc7, 0xbb, 0xc2, 0xa9, 0xd8, 0x6e, 0x19, 0xdf, 0xeb, 0x33,
+ 0xe3, 0x5b, 0xe9, 0x97, 0xda, 0x3f, 0x33, 0xe5, 0xe3, 0x1d, 0x75, 0xe9,
+ 0x89, 0xc5, 0x37, 0xe8, 0xd6, 0x4a, 0x79, 0x7f, 0x51, 0xc6, 0xbc, 0x9c,
+ 0x9e, 0x7f, 0xa8, 0x77, 0xd5, 0x7a, 0x3c, 0xfc, 0x07, 0xd7, 0x0d, 0x36,
+ 0x4f, 0xf0, 0x16, 0x00, 0x00, 0x00 };
static u8 bnx2_TPAT_b09FwText[] = {
- 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0xd5, 0x15, 0x3e, 0x73, 0x67, 0xd6, 0x3b,
- 0xb6, 0x9c, 0x78, 0x4c, 0xb6, 0xb0, 0x14, 0x47, 0xcc, 0xc4, 0xe3, 0x9f,
- 0xca, 0x16, 0x0c, 0xe9, 0x96, 0x1a, 0x69, 0x55, 0x0d, 0xbb, 0x1b, 0x63,
- 0xa5, 0x3c, 0x18, 0x29, 0x52, 0x91, 0xa0, 0xc8, 0x5d, 0x13, 0xe0, 0x81,
- 0x87, 0xa0, 0xf6, 0xa1, 0x15, 0x0f, 0x59, 0xd6, 0x9b, 0x90, 0x87, 0x6d,
- 0x06, 0x96, 0x2a, 0x79, 0x68, 0x55, 0x45, 0x0e, 0x8e, 0xa3, 0x76, 0xe5,
- 0x25, 0x48, 0x7d, 0x8c, 0x40, 0xa1, 0x4a, 0x5f, 0x79, 0xa0, 0x15, 0x7d,
- 0x22, 0x52, 0x5f, 0x78, 0xe8, 0x4f, 0x84, 0xd4, 0x16, 0xb5, 0x34, 0xb7,
- 0xdf, 0x77, 0x67, 0xc6, 0x6c, 0x4d, 0x22, 0xc4, 0x4b, 0x57, 0x5a, 0xdd,
- 0x99, 0x7b, 0xcf, 0x39, 0xf7, 0xdc, 0xf3, 0xf3, 0x9d, 0x73, 0xe7, 0x90,
- 0x92, 0x31, 0xc9, 0x7e, 0xfb, 0xf0, 0xaf, 0xfc, 0xe0, 0xc4, 0x8f, 0xbe,
- 0xf5, 0x40, 0xf4, 0x00, 0xdf, 0xad, 0x82, 0x38, 0xf2, 0x7f, 0xfc, 0xd9,
- 0x22, 0x5e, 0xae, 0x07, 0xff, 0xe2, 0xaa, 0xea, 0xda, 0xc1, 0x5a, 0x28,
- 0xae, 0x5d, 0x5d, 0x79, 0x60, 0x3d, 0x14, 0x89, 0xfb, 0x0b, 0x7e, 0x5d,
- 0xfe, 0xa3, 0x5b, 0x25, 0x47, 0x38, 0x7f, 0xb0, 0xfa, 0xd9, 0x83, 0x57,
- 0xbf, 0x1d, 0xdc, 0xbc, 0x60, 0x8b, 0xeb, 0x55, 0xcf, 0xb8, 0xde, 0xac,
- 0xb8, 0x53, 0xe0, 0xf9, 0xc5, 0x5c, 0x6f, 0x44, 0xf6, 0xe7, 0xb2, 0x5a,
- 0x5a, 0x85, 0x37, 0xf4, 0xd5, 0xb9, 0xd0, 0x6b, 0x4b, 0x49, 0xae, 0x0c,
- 0x7c, 0xa9, 0x0d, 0xa6, 0xe4, 0x9d, 0x41, 0x59, 0xde, 0x1e, 0x78, 0xf2,
- 0xd6, 0xc0, 0x91, 0xe3, 0x6f, 0x9c, 0x94, 0x4e, 0x14, 0x94, 0x1b, 0xb6,
- 0x2b, 0xaa, 0x1a, 0x94, 0x9b, 0xe2, 0xcb, 0x56, 0x14, 0x9c, 0x59, 0xb3,
- 0x27, 0x2d, 0xb7, 0xea, 0xca, 0xcb, 0x73, 0x4a, 0x2e, 0x94, 0x9e, 0x96,
- 0xe7, 0xc2, 0x27, 0xf1, 0x77, 0xe4, 0x50, 0xcf, 0xb1, 0xea, 0xe7, 0x1d,
- 0x09, 0x7b, 0x13, 0xf2, 0x58, 0xa4, 0xf5, 0x7a, 0x14, 0x83, 0x7f, 0x7a,
- 0xfe, 0x79, 0x19, 0x95, 0x96, 0x17, 0xac, 0x88, 0x14, 0x48, 0x23, 0xb5,
- 0xa8, 0x20, 0xb1, 0x97, 0x9e, 0xed, 0x82, 0x19, 0x3f, 0xd3, 0x5b, 0xe0,
- 0x1f, 0x0d, 0xf3, 0xf5, 0xbb, 0xb2, 0x75, 0x2f, 0x5b, 0x57, 0x72, 0xe8,
- 0x5c, 0xe0, 0x6f, 0xcb, 0x4c, 0xec, 0x58, 0xb7, 0x74, 0x2d, 0xbc, 0xdb,
- 0xab, 0x6d, 0x3b, 0x32, 0xdd, 0xe3, 0x19, 0x42, 0xaf, 0x2e, 0x1a, 0x3c,
- 0x36, 0x79, 0x1c, 0x55, 0xfd, 0x21, 0x7c, 0x37, 0x13, 0x2b, 0x4b, 0xe4,
- 0x5a, 0xb7, 0xec, 0xd5, 0x06, 0x3f, 0xb6, 0x6a, 0xc9, 0x2d, 0x1d, 0x3b,
- 0x63, 0xa2, 0xc2, 0xd8, 0xaa, 0x6d, 0x53, 0xd6, 0xa8, 0x38, 0x61, 0x11,
- 0x3c, 0xd3, 0x9e, 0x12, 0x8e, 0xb5, 0x6c, 0x9e, 0xb2, 0x1b, 0x78, 0x5e,
- 0xb6, 0xe2, 0x6d, 0xc7, 0xaa, 0x9d, 0x5f, 0xc1, 0xb3, 0x0b, 0x7e, 0xd8,
- 0x26, 0xb2, 0x24, 0x5e, 0xb5, 0xc0, 0xc7, 0x73, 0x7a, 0x78, 0x57, 0x12,
- 0x97, 0x3c, 0xd9, 0xa8, 0x04, 0xe5, 0x96, 0x1c, 0xb5, 0xea, 0xdb, 0x5f,
- 0x70, 0x9c, 0xb7, 0x32, 0xf8, 0xe2, 0x1c, 0x75, 0x79, 0xd4, 0xd1, 0x5a,
- 0x3d, 0x54, 0xcc, 0xce, 0x48, 0x79, 0x71, 0xaa, 0x7f, 0x89, 0xef, 0xd0,
- 0x39, 0x81, 0xee, 0xfd, 0x11, 0xe8, 0xa3, 0x35, 0xf7, 0xa9, 0x85, 0xed,
- 0xd7, 0x14, 0x2c, 0x78, 0x97, 0x04, 0xad, 0xa7, 0x68, 0x8d, 0xb3, 0x07,
- 0xc4, 0x9f, 0x54, 0xa1, 0x92, 0xc0, 0xdb, 0x96, 0x29, 0xd9, 0x48, 0xa6,
- 0xbc, 0x23, 0x49, 0xdb, 0x23, 0x0d, 0xe7, 0xea, 0xa0, 0x39, 0xd2, 0xd7,
- 0xfa, 0x52, 0x74, 0x5f, 0x51, 0xf6, 0xab, 0xc5, 0x82, 0x04, 0x7e, 0x6c,
- 0xf8, 0x64, 0xca, 0x11, 0xca, 0xc4, 0xf3, 0x0e, 0xdf, 0x67, 0x0c, 0xad,
- 0xda, 0xd9, 0x6b, 0xcb, 0xb9, 0x4c, 0x37, 0xfa, 0x43, 0xd1, 0x4e, 0xd9,
- 0xfb, 0xb8, 0x57, 0x3b, 0x9f, 0xdb, 0xdf, 0x9c, 0x07, 0xf6, 0x8e, 0xa4,
- 0x56, 0xc1, 0xb9, 0xee, 0x78, 0xd6, 0x9c, 0x8f, 0x3a, 0x72, 0xef, 0x88,
- 0xe7, 0xd9, 0xd5, 0xf5, 0xa9, 0x2f, 0xe8, 0xda, 0xf2, 0x71, 0x4e, 0xff,
- 0xe7, 0x98, 0xdf, 0xe8, 0x4a, 0x49, 0x09, 0xe3, 0x08, 0xcf, 0x7d, 0xbe,
- 0xcf, 0x20, 0x06, 0xf9, 0xac, 0x24, 0x3c, 0xe7, 0x4a, 0x27, 0x7c, 0xc6,
- 0x96, 0xfd, 0x5a, 0x77, 0x22, 0xc7, 0x6a, 0x9c, 0x7f, 0x31, 0x7b, 0x46,
- 0x0c, 0x27, 0x88, 0xe1, 0x04, 0x31, 0x9d, 0x20, 0x8e, 0x13, 0xf1, 0x54,
- 0xd5, 0x97, 0xab, 0x73, 0xae, 0xdc, 0xb0, 0x11, 0x0b, 0x83, 0x05, 0xef,
- 0x4d, 0xc4, 0x63, 0xec, 0x59, 0x62, 0x87, 0xf1, 0x7c, 0x41, 0xf8, 0x8e,
- 0x38, 0x74, 0xe2, 0xb2, 0x8d, 0x38, 0x8c, 0x8f, 0x71, 0xae, 0x28, 0x6b,
- 0xe6, 0xbc, 0x0b, 0xde, 0x29, 0xa1, 0x9f, 0x6b, 0x58, 0x9b, 0xf6, 0x4f,
- 0x31, 0x60, 0xc7, 0x6a, 0x58, 0xa7, 0xac, 0xc0, 0x6b, 0x81, 0xa2, 0x9d,
- 0x7c, 0x8c, 0x1c, 0x2a, 0x21, 0x6f, 0xe6, 0xca, 0x4a, 0x2c, 0x59, 0x5f,
- 0x84, 0xbd, 0x16, 0x69, 0x57, 0xe6, 0x10, 0x63, 0xf2, 0xef, 0xb3, 0x4e,
- 0x78, 0x12, 0xb1, 0x07, 0x5a, 0xd8, 0xe8, 0x54, 0x32, 0x07, 0xfe, 0xc5,
- 0x22, 0x75, 0xdd, 0x8a, 0x1c, 0xe9, 0x24, 0x57, 0x55, 0x21, 0xfc, 0xa7,
- 0x92, 0xfd, 0x41, 0x2b, 0x86, 0x7f, 0x95, 0x52, 0x25, 0x6e, 0xfd, 0xda,
- 0x00, 0x32, 0x8d, 0xfe, 0x0e, 0xf8, 0xca, 0x99, 0xfe, 0xf4, 0x8d, 0xc8,
- 0x66, 0x37, 0x88, 0x96, 0xa1, 0xdb, 0x35, 0xc4, 0x0e, 0xfd, 0x72, 0x09,
- 0xb6, 0x69, 0x77, 0x2d, 0xe6, 0xbe, 0xb4, 0xfb, 0xa4, 0x33, 0x30, 0xb1,
- 0xe6, 0x54, 0x65, 0xb5, 0xdd, 0x3d, 0xa9, 0xed, 0x50, 0xd6, 0x0a, 0x55,
- 0xfa, 0x76, 0x7c, 0x09, 0xbe, 0x5a, 0x6d, 0xf7, 0xa7, 0x1e, 0xdf, 0xec,
- 0x4a, 0xeb, 0xeb, 0x55, 0x69, 0xd9, 0x15, 0x75, 0xb7, 0x92, 0x09, 0xc8,
- 0xad, 0x62, 0x1f, 0xc6, 0x64, 0xe0, 0xd7, 0xed, 0xa9, 0xc7, 0x2f, 0x76,
- 0xef, 0x47, 0xce, 0xcb, 0x67, 0xb5, 0x4a, 0x08, 0x9b, 0x5f, 0xbb, 0xd7,
- 0x96, 0x50, 0x36, 0x06, 0xae, 0xd4, 0x92, 0x29, 0xe9, 0x0c, 0x24, 0x7e,
- 0x6a, 0x0e, 0xfb, 0x55, 0xf0, 0x3e, 0x58, 0x94, 0xd6, 0x60, 0x6a, 0x4d,
- 0x55, 0x5b, 0x12, 0x0f, 0x3a, 0xf8, 0xbb, 0xd2, 0xe8, 0xba, 0xee, 0xc5,
- 0x6e, 0x8b, 0xfc, 0xae, 0x55, 0xf5, 0xdd, 0x43, 0xfd, 0x9b, 0x8c, 0x2d,
- 0xc8, 0x19, 0xfd, 0x9e, 0xaa, 0x3a, 0xd2, 0x2c, 0x95, 0x20, 0xc3, 0x82,
- 0x4d, 0xa8, 0xeb, 0x3c, 0xf6, 0x4d, 0xc7, 0xd6, 0x80, 0xfe, 0x2b, 0x4a,
- 0x3b, 0x5a, 0x84, 0x9d, 0x60, 0x77, 0xaf, 0x28, 0x1b, 0xe1, 0xa7, 0xfa,
- 0xd9, 0x28, 0x80, 0x8f, 0xf4, 0xfd, 0x35, 0x60, 0x51, 0x0d, 0x26, 0x7d,
- 0x39, 0x2c, 0xcb, 0x29, 0xec, 0x9b, 0xf2, 0x75, 0xa0, 0x03, 0xf9, 0x26,
- 0xc0, 0xd7, 0x00, 0x5f, 0x49, 0x4e, 0x1b, 0xde, 0x09, 0xf0, 0xde, 0xcc,
- 0x78, 0x17, 0xca, 0xcb, 0x12, 0x81, 0x67, 0xda, 0x5f, 0x86, 0x3f, 0xd7,
- 0x4a, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x44, 0x5a, 0x4e, 0x85, 0x72,
- 0x83, 0xf2, 0xb3, 0xcc, 0x25, 0x23, 0xb3, 0x05, 0x99, 0xd0, 0x2b, 0x71,
- 0x21, 0x67, 0x09, 0xe3, 0x07, 0xba, 0x9d, 0x00, 0xb3, 0x4a, 0x7c, 0x7e,
- 0x47, 0xab, 0x2a, 0xe2, 0xb8, 0x12, 0xfa, 0x6d, 0xe1, 0xfb, 0x88, 0xd4,
- 0x91, 0xa3, 0x2a, 0x9c, 0x90, 0xa6, 0x67, 0x59, 0xaa, 0x6a, 0x4b, 0x13,
- 0x51, 0x1c, 0xaf, 0x3a, 0x66, 0x6e, 0x0d, 0x71, 0xa6, 0xaa, 0x5b, 0x76,
- 0x5a, 0x4f, 0x0a, 0xa0, 0x19, 0xc1, 0xfc, 0x38, 0x6c, 0x30, 0x09, 0xda,
- 0x5f, 0x62, 0x7e, 0x06, 0xf8, 0x3b, 0x09, 0x1a, 0x8e, 0xcc, 0x23, 0xda,
- 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60, 0x9b, 0xe1, 0xd4, 0xca,
- 0x7d, 0x0c, 0x9a, 0xc4, 0xc9, 0x72, 0x73, 0x38, 0xdf, 0xf2, 0x75, 0x1f,
- 0xeb, 0xd7, 0xbe, 0xa1, 0xe4, 0xa6, 0xbe, 0x18, 0x32, 0x86, 0xe5, 0xd3,
- 0x46, 0x18, 0x4f, 0xda, 0x06, 0x23, 0x72, 0xac, 0xe0, 0xc8, 0x5a, 0x72,
- 0xf9, 0xe0, 0x7a, 0x68, 0xd9, 0x9d, 0xc5, 0x03, 0xd2, 0x2a, 0x05, 0x51,
- 0x1d, 0xfe, 0xee, 0x24, 0xcc, 0x8d, 0x09, 0x9c, 0x3b, 0x40, 0xd4, 0x4d,
- 0xe3, 0x39, 0xbe, 0x17, 0x3c, 0xf0, 0x63, 0x0b, 0xb2, 0x38, 0x22, 0x66,
- 0x92, 0x00, 0x3a, 0xc2, 0x1e, 0xe1, 0x82, 0x77, 0x84, 0xf1, 0x58, 0xe2,
- 0x1a, 0x6b, 0xd4, 0x65, 0xd4, 0xa8, 0x20, 0x6a, 0x66, 0xb9, 0xf2, 0x2e,
- 0x6c, 0xdb, 0x4e, 0x58, 0x6f, 0xca, 0xc8, 0x15, 0xd6, 0x1b, 0xe6, 0x07,
- 0x63, 0x25, 0xc7, 0x67, 0xf0, 0x84, 0xcc, 0x4f, 0x37, 0xc3, 0xe9, 0x5a,
- 0x86, 0xc1, 0x4b, 0xd0, 0x43, 0xeb, 0x27, 0x80, 0xbf, 0xed, 0xc8, 0xc4,
- 0x67, 0xcb, 0x57, 0xb7, 0xf4, 0xf4, 0x2c, 0x6d, 0xae, 0xf5, 0x89, 0x68,
- 0x19, 0xb4, 0x7f, 0x83, 0xbd, 0x56, 0x80, 0xc1, 0xc4, 0x6d, 0xee, 0x5d,
- 0x75, 0x6b, 0xdd, 0x7d, 0xd0, 0xc5, 0x07, 0x36, 0xc2, 0x06, 0x06, 0xab,
- 0x47, 0x91, 0xef, 0xcc, 0xf9, 0xc0, 0x5f, 0x13, 0xce, 0xcb, 0xa8, 0xc2,
- 0x7b, 0x13, 0x7e, 0xea, 0x54, 0x8e, 0x5a, 0x8d, 0xed, 0x31, 0x27, 0xab,
- 0xf9, 0x13, 0x0a, 0x75, 0xa8, 0x59, 0x22, 0xdf, 0x08, 0xf8, 0xf6, 0x81,
- 0x67, 0x14, 0x6b, 0x05, 0x8c, 0xc3, 0x72, 0x0c, 0xe6, 0x63, 0x2f, 0x1f,
- 0x7b, 0xad, 0x88, 0x53, 0x7d, 0x05, 0xf8, 0x33, 0xe3, 0x37, 0xe4, 0x57,
- 0x76, 0x5a, 0x63, 0xe9, 0x9b, 0xef, 0x0c, 0xf9, 0xc6, 0x17, 0xdb, 0xe4,
- 0xe0, 0x23, 0x59, 0x4c, 0x11, 0x57, 0x1f, 0xce, 0xd6, 0x4b, 0xc0, 0xc7,
- 0x6f, 0x66, 0xf8, 0xef, 0x12, 0x2b, 0xe5, 0x8c, 0xc1, 0xca, 0x11, 0x62,
- 0x25, 0x70, 0xa5, 0xb5, 0x04, 0x7b, 0x47, 0x1f, 0x03, 0x5f, 0xea, 0xf0,
- 0xc4, 0x6f, 0xbb, 0x0e, 0xe2, 0xca, 0x06, 0x3f, 0xeb, 0xf8, 0x77, 0xa1,
- 0x5b, 0xe0, 0x7d, 0x0c, 0xbc, 0x89, 0x8f, 0x31, 0x0f, 0xb4, 0x46, 0xae,
- 0x03, 0xab, 0x66, 0xcb, 0xa7, 0x10, 0xf7, 0x36, 0x70, 0x02, 0x15, 0x19,
- 0xfb, 0xe6, 0x35, 0x37, 0xaf, 0xff, 0xfc, 0xbd, 0x6f, 0xc1, 0xcd, 0xa8,
- 0x93, 0x47, 0x21, 0x63, 0xc6, 0x3f, 0x02, 0x3f, 0x6e, 0x2c, 0x7d, 0x19,
- 0xcf, 0x1f, 0x33, 0x1e, 0xad, 0x1b, 0x15, 0xee, 0x2b, 0xd2, 0xe8, 0xd3,
- 0x0e, 0x11, 0xec, 0x60, 0x30, 0x08, 0x39, 0x1f, 0x21, 0xe7, 0x45, 0x9a,
- 0xc4, 0x0a, 0x60, 0x18, 0x71, 0x6f, 0x03, 0xf4, 0xaa, 0x52, 0x84, 0x5d,
- 0x11, 0x4b, 0x4a, 0x5c, 0xa7, 0x7a, 0xcc, 0xed, 0x80, 0xb6, 0x50, 0x5d,
- 0x75, 0xb7, 0xc2, 0x17, 0x73, 0xdb, 0x03, 0xc7, 0xc4, 0xaa, 0xa5, 0x7e,
- 0xce, 0xe8, 0x1e, 0xcf, 0xe8, 0x56, 0x86, 0xe9, 0x30, 0xdf, 0xc8, 0xe6,
- 0x63, 0xcc, 0xcf, 0x65, 0x36, 0x67, 0x3d, 0x70, 0x51, 0xa3, 0x59, 0x0b,
- 0x02, 0xdf, 0x57, 0x88, 0xb5, 0x3b, 0xd6, 0x81, 0xa5, 0x21, 0xec, 0x16,
- 0x65, 0x7a, 0x92, 0x12, 0x63, 0x72, 0xf8, 0xac, 0xa3, 0x28, 0x34, 0xbb,
- 0xf1, 0x89, 0xdf, 0xdb, 0xd9, 0x3e, 0xa4, 0x25, 0x5e, 0x0f, 0xd3, 0x22,
- 0x8d, 0x42, 0xd6, 0xd4, 0xdb, 0xd9, 0xec, 0x00, 0xd6, 0x90, 0xf3, 0x89,
- 0x2d, 0x8f, 0x3a, 0xcc, 0xef, 0xc3, 0x05, 0x73, 0x0e, 0xd6, 0xe0, 0x9d,
- 0x29, 0x83, 0x33, 0x2b, 0xdd, 0x22, 0x80, 0x7d, 0x5c, 0x8e, 0x23, 0x9f,
- 0x9f, 0x85, 0xef, 0x2f, 0x46, 0x0a, 0x9d, 0x06, 0x6b, 0x8e, 0x46, 0x1c,
- 0x06, 0xc6, 0x17, 0xb5, 0x70, 0x03, 0x91, 0xfc, 0x8a, 0x5c, 0x5b, 0x1c,
- 0x93, 0xc2, 0x25, 0xea, 0xe0, 0x88, 0xb3, 0x39, 0xbc, 0xcf, 0x02, 0xf6,
- 0x99, 0x02, 0x06, 0x3e, 0x82, 0xfa, 0x52, 0x12, 0x67, 0x16, 0x58, 0x9b,
- 0xb8, 0x56, 0x1d, 0xf2, 0xd5, 0x25, 0x9e, 0x9f, 0x18, 0xec, 0x66, 0xb5,
- 0x8d, 0xb9, 0x55, 0x14, 0xbb, 0xf7, 0x67, 0xe4, 0xae, 0x92, 0xf5, 0x8a,
- 0xd6, 0x47, 0xa2, 0xf7, 0x60, 0x5f, 0xcc, 0x6d, 0x72, 0xed, 0x26, 0xe6,
- 0x39, 0x47, 0x19, 0x8c, 0xc5, 0x03, 0xa8, 0x6b, 0xd8, 0xf3, 0x18, 0x79,
- 0x8a, 0xa2, 0x7a, 0xc4, 0x7f, 0x8c, 0x9b, 0x7c, 0xe7, 0x99, 0x88, 0x6d,
- 0x36, 0xc6, 0x31, 0x8c, 0x3c, 0xd3, 0x47, 0x99, 0xaf, 0xf8, 0xac, 0xb5,
- 0x53, 0x1d, 0x97, 0x7a, 0x37, 0x04, 0xc6, 0xce, 0x94, 0x8f, 0x0b, 0xd7,
- 0xf0, 0xde, 0xe7, 0xbc, 0x37, 0x34, 0x8f, 0xe7, 0xbe, 0xd1, 0x59, 0x9c,
- 0xdd, 0xde, 0x67, 0x03, 0x86, 0x2d, 0x60, 0x1f, 0xf6, 0x39, 0xac, 0x7f,
- 0x06, 0xb7, 0xe6, 0xd9, 0xb7, 0x5c, 0xee, 0xb2, 0x16, 0x3a, 0xcc, 0xcb,
- 0x7b, 0x94, 0x1c, 0x90, 0x7a, 0x29, 0x3f, 0x17, 0xe2, 0x38, 0x22, 0xff,
- 0x34, 0xfb, 0x19, 0x8d, 0xbc, 0x2b, 0xdb, 0xa6, 0x6f, 0x9c, 0x89, 0xd9,
- 0x3f, 0x5c, 0xee, 0x23, 0x97, 0x7b, 0x5a, 0x9a, 0xa9, 0x2c, 0x6f, 0x15,
- 0xfd, 0x6f, 0xed, 0x35, 0xd6, 0x40, 0xda, 0xf9, 0x5e, 0xf8, 0x06, 0x18,
- 0xbd, 0xe9, 0xc8, 0xc5, 0x6e, 0x2a, 0x8b, 0x39, 0xf5, 0x42, 0x26, 0xaf,
- 0x21, 0x7f, 0x80, 0x1c, 0xf6, 0x25, 0xec, 0x31, 0xd1, 0x53, 0x9e, 0x73,
- 0x20, 0x8f, 0x36, 0xc0, 0xb5, 0xa0, 0x37, 0x9f, 0xe9, 0x1b, 0x80, 0xce,
- 0x81, 0x4d, 0x69, 0x4b, 0xca, 0x62, 0xac, 0xfd, 0x5b, 0x13, 0x3f, 0x50,
- 0x37, 0xb0, 0x07, 0xde, 0x07, 0x23, 0xe0, 0x99, 0x92, 0x57, 0x13, 0x83,
- 0xa5, 0xde, 0x09, 0x60, 0x52, 0xa3, 0xfb, 0x8f, 0xbc, 0xb6, 0xc4, 0x6d,
- 0xe0, 0xeb, 0xf3, 0x32, 0x2e, 0xce, 0xce, 0xb8, 0xbc, 0x80, 0x5e, 0xb0,
- 0xd0, 0x43, 0x1d, 0x87, 0x0d, 0xd5, 0xd9, 0xd6, 0x3c, 0xfb, 0xb9, 0xb7,
- 0xd8, 0x17, 0x55, 0xc2, 0xc8, 0xb6, 0x66, 0xe5, 0xcc, 0xcf, 0x82, 0xf9,
- 0x6d, 0x93, 0xaf, 0x58, 0xdf, 0xf1, 0xe5, 0x74, 0x3f, 0x94, 0x33, 0x7d,
- 0x0f, 0x7a, 0x79, 0xbb, 0x3d, 0xaf, 0x0a, 0x89, 0xa7, 0x0d, 0xfc, 0x89,
- 0x97, 0x3c, 0x17, 0x6c, 0x5c, 0xa5, 0x4d, 0xd8, 0xe3, 0xd2, 0x7f, 0xc4,
- 0xaf, 0xa3, 0x78, 0x1e, 0x13, 0x1b, 0x67, 0x52, 0x3d, 0xda, 0x82, 0xf6,
- 0x1f, 0xee, 0x93, 0x89, 0x6d, 0x9e, 0xe9, 0x1d, 0x9b, 0x49, 0x9e, 0x7b,
- 0x79, 0x2e, 0x32, 0xcf, 0x1d, 0x6b, 0x19, 0xf6, 0xba, 0x1e, 0x31, 0x1f,
- 0x6f, 0xe9, 0xeb, 0xa6, 0x3f, 0xf3, 0xd8, 0x33, 0x0f, 0xf5, 0x67, 0x79,
- 0x5f, 0xc3, 0x78, 0x2c, 0x0f, 0xe5, 0xe3, 0x0d, 0x93, 0x8b, 0x57, 0x90,
- 0x97, 0xaf, 0x27, 0x65, 0x93, 0x93, 0x87, 0x0e, 0xdf, 0x2e, 0x27, 0x7f,
- 0xfd, 0x15, 0x72, 0xf2, 0xed, 0x2c, 0x27, 0x47, 0x4c, 0xdc, 0xaa, 0xde,
- 0xf0, 0xda, 0x6f, 0xb0, 0xc6, 0x39, 0xde, 0x37, 0x58, 0x43, 0xd1, 0xff,
- 0x3f, 0x4c, 0x1f, 0xe5, 0xfe, 0x49, 0xe3, 0xb0, 0xee, 0x90, 0x06, 0x3e,
- 0xec, 0x8d, 0x8b, 0x7d, 0x96, 0x39, 0x9b, 0xc7, 0x8c, 0x8f, 0x58, 0xcd,
- 0xf9, 0xd1, 0x4f, 0x1e, 0x63, 0x2c, 0x14, 0x4c, 0x5e, 0xd8, 0xd5, 0x9c,
- 0xa6, 0x2c, 0xcb, 0xe8, 0xd5, 0xde, 0xe3, 0xd8, 0x4f, 0x63, 0x65, 0xa4,
- 0xe7, 0xca, 0x4b, 0x73, 0xc4, 0xa6, 0x20, 0xba, 0x06, 0x9d, 0xaf, 0x87,
- 0x25, 0x29, 0xcc, 0x32, 0x5f, 0x59, 0x6d, 0x46, 0x10, 0x43, 0xb8, 0x77,
- 0x25, 0xfa, 0x24, 0xfa, 0x29, 0xdf, 0x81, 0x9f, 0x5f, 0x47, 0x1c, 0x11,
- 0x3b, 0x11, 0x13, 0xf3, 0x9b, 0x88, 0x89, 0xe3, 0x7c, 0x37, 0xfb, 0x16,
- 0x0c, 0xad, 0x6d, 0xf6, 0x2f, 0x41, 0x7f, 0x57, 0x8a, 0xe7, 0x34, 0xee,
- 0x5b, 0x9f, 0xf3, 0x9d, 0x36, 0xf1, 0x0b, 0xac, 0xc0, 0xfc, 0xba, 0x89,
- 0x5f, 0xfa, 0x34, 0xf0, 0x88, 0xf3, 0x7f, 0x32, 0xb9, 0xf1, 0xa1, 0xc9,
- 0xf1, 0xeb, 0x91, 0x89, 0xe7, 0x88, 0xfd, 0xe4, 0xe9, 0xfe, 0xfb, 0x05,
- 0x83, 0x01, 0xc8, 0x8f, 0x53, 0x91, 0x89, 0xb5, 0xf9, 0x2b, 0x38, 0xf6,
- 0x9b, 0x69, 0x2e, 0x0c, 0xc9, 0x99, 0xf6, 0x1e, 0x4b, 0x73, 0xcb, 0xdf,
- 0x30, 0x77, 0x8a, 0x19, 0xf4, 0x43, 0xa0, 0xeb, 0xef, 0xc5, 0x83, 0x49,
- 0x8c, 0xb4, 0xf7, 0x27, 0x90, 0xeb, 0xc1, 0x86, 0x94, 0x43, 0xbd, 0xa9,
- 0xd7, 0xb8, 0x84, 0x67, 0x73, 0x9d, 0x3e, 0x31, 0xba, 0xfc, 0xaf, 0x3c,
- 0xac, 0xef, 0xdc, 0x8e, 0xcf, 0x1b, 0xe2, 0xfb, 0xeb, 0x6d, 0xf8, 0xb0,
- 0xbe, 0x43, 0x9e, 0xb1, 0xdd, 0x5e, 0xa2, 0xbe, 0x1b, 0xd7, 0x31, 0xe2,
- 0x9e, 0xbc, 0x7b, 0xef, 0x79, 0xc3, 0x39, 0x90, 0xd7, 0x70, 0xc6, 0x39,
- 0xf7, 0xcc, 0x63, 0x3d, 0x8f, 0xf1, 0x3c, 0xe6, 0xf3, 0x58, 0x0f, 0xa2,
- 0xe7, 0x24, 0xf5, 0xaf, 0xd3, 0x0b, 0xb0, 0xff, 0xd8, 0x1d, 0xee, 0x26,
- 0x5f, 0x56, 0x8f, 0x24, 0xfe, 0xfc, 0x1e, 0xf8, 0xfb, 0xac, 0x67, 0x74,
- 0x99, 0x6b, 0xf8, 0xb3, 0x4f, 0xbf, 0x89, 0xfa, 0x1f, 0x65, 0xb6, 0x8d,
- 0xb3, 0x31, 0xa5, 0x49, 0xfb, 0xbd, 0x9f, 0x64, 0x98, 0xfb, 0xfd, 0xb4,
- 0xbe, 0x48, 0x9e, 0x53, 0xcc, 0x21, 0x93, 0x53, 0x3c, 0x0f, 0xee, 0xe8,
- 0x5a, 0xaf, 0xc2, 0x8f, 0x2f, 0x45, 0x79, 0x1e, 0x21, 0x9e, 0x0e, 0xe7,
- 0x39, 0x0e, 0x3b, 0x85, 0xb7, 0xb4, 0x33, 0x1b, 0xc3, 0x66, 0xbc, 0x17,
- 0x37, 0xd0, 0x1b, 0xd1, 0x4e, 0x2b, 0xd6, 0x13, 0xbb, 0x77, 0xe1, 0xbd,
- 0x7d, 0x10, 0xed, 0x46, 0xbb, 0x0e, 0xdb, 0x2d, 0x88, 0x26, 0x15, 0x31,
- 0xe0, 0x76, 0x38, 0x91, 0xd7, 0x6b, 0x60, 0xd0, 0x6c, 0x6e, 0xa7, 0xaf,
- 0x5c, 0xb3, 0xe3, 0xf4, 0x3b, 0xc2, 0x5e, 0x7c, 0xd8, 0xb4, 0x87, 0xf0,
- 0xe1, 0x36, 0x3d, 0x25, 0x65, 0xd0, 0x06, 0xa8, 0x5f, 0xa6, 0xcf, 0x60,
- 0x0f, 0x79, 0x4b, 0xdb, 0xa6, 0x9f, 0x24, 0x36, 0xb2, 0x8f, 0xec, 0x8c,
- 0xc8, 0xd8, 0x3e, 0xf3, 0x1e, 0x6f, 0x73, 0x64, 0x4c, 0x48, 0x5a, 0x97,
- 0x8c, 0xfe, 0xcf, 0x64, 0xfa, 0xa7, 0x3a, 0x8b, 0xba, 0x13, 0xa6, 0x51,
- 0x57, 0x0f, 0xba, 0x3e, 0x94, 0xdb, 0xa5, 0xa5, 0xaa, 0x27, 0xa4, 0x51,
- 0x31, 0x77, 0x5b, 0xdc, 0xa5, 0xa0, 0xc3, 0x12, 0xf5, 0x28, 0x43, 0x8f,
- 0x71, 0xdc, 0x3d, 0x82, 0x95, 0x96, 0x04, 0xf1, 0x1a, 0x08, 0xe7, 0x7e,
- 0x4a, 0xbb, 0x3d, 0xed, 0x6e, 0x75, 0x69, 0xb7, 0x27, 0xdd, 0x4e, 0x77,
- 0x1a, 0xfd, 0x5f, 0x00, 0x6f, 0x07, 0xf3, 0x97, 0x84, 0x31, 0xb6, 0x10,
- 0x71, 0x3c, 0x2d, 0xec, 0xb7, 0x9e, 0x76, 0x67, 0xfa, 0x1c, 0x9f, 0x74,
- 0xc3, 0xfe, 0xb0, 0xdc, 0xbf, 0x68, 0x60, 0x62, 0x7c, 0x03, 0x79, 0xf4,
- 0xea, 0x20, 0xdd, 0x1b, 0xf7, 0xbf, 0x4c, 0x2e, 0xe6, 0x92, 0x5c, 0xb6,
- 0x10, 0xa7, 0x28, 0x1b, 0x72, 0xa7, 0xa3, 0xdf, 0x99, 0x3d, 0x78, 0xff,
- 0xb9, 0xd3, 0x1e, 0x77, 0xe7, 0xdf, 0x2e, 0x90, 0x3b, 0x05, 0x83, 0x3d,
- 0x1b, 0x09, 0xee, 0xcc, 0x25, 0xad, 0x9b, 0xe1, 0x87, 0xb0, 0x1d, 0x7a,
- 0x80, 0x45, 0x0f, 0x7f, 0xe0, 0xea, 0x2a, 0xd7, 0xd0, 0x67, 0xe3, 0xae,
- 0xc7, 0xfb, 0xda, 0x46, 0xc2, 0x35, 0xc6, 0x38, 0x7a, 0xc1, 0xc5, 0x8f,
- 0x40, 0xfb, 0x81, 0x6e, 0x0d, 0x94, 0xb9, 0x8f, 0xab, 0x10, 0xf7, 0xac,
- 0x01, 0xfb, 0x15, 0xb1, 0x1a, 0x89, 0xf8, 0xcd, 0x68, 0xc9, 0xdc, 0xc7,
- 0x62, 0xcf, 0xe7, 0x9d, 0x13, 0x3d, 0xe6, 0xe2, 0x50, 0x8f, 0xb9, 0x88,
- 0x1e, 0xf3, 0x9e, 0x22, 0xe2, 0x3c, 0xc6, 0x3d, 0x53, 0x35, 0xd3, 0xbc,
- 0x99, 0xe0, 0x9d, 0xb2, 0x5d, 0x92, 0x7d, 0xe8, 0x9e, 0xa0, 0x5b, 0x88,
- 0xfd, 0xb9, 0x7e, 0x30, 0xfb, 0xee, 0x85, 0x4d, 0xc7, 0x62, 0xd3, 0x6f,
- 0xb5, 0x4b, 0x23, 0xa8, 0xff, 0xa4, 0xb9, 0x2f, 0xa3, 0x79, 0x6e, 0x0f,
- 0xcd, 0xd7, 0x78, 0x46, 0xca, 0x96, 0xe6, 0x1b, 0xcc, 0x3b, 0xd6, 0xd2,
- 0x91, 0x2c, 0xdf, 0x4e, 0xe0, 0xb9, 0x98, 0x3d, 0xe7, 0xf4, 0x87, 0xf7,
- 0xf0, 0x3f, 0xa2, 0xd2, 0x77, 0x3e, 0x53, 0xe7, 0x98, 0x7d, 0x30, 0xe4,
- 0x2d, 0x59, 0xe9, 0xb7, 0x92, 0xf3, 0x38, 0x3b, 0x7d, 0x92, 0xf6, 0x17,
- 0xc0, 0x60, 0x74, 0x57, 0x33, 0xb0, 0xbb, 0xd6, 0xed, 0x25, 0xe2, 0xda,
- 0xc2, 0xfc, 0x11, 0x83, 0x6f, 0x6a, 0x4a, 0x49, 0x8e, 0xb9, 0xc3, 0xcf,
- 0x18, 0x97, 0xcc, 0x37, 0x01, 0xbc, 0xa7, 0x32, 0xb6, 0x70, 0x3f, 0x16,
- 0xe4, 0x70, 0xcb, 0xe8, 0x65, 0xa5, 0xf7, 0x1e, 0xaf, 0xc6, 0x7a, 0x80,
- 0xba, 0xf1, 0x20, 0xf5, 0xda, 0xfd, 0x76, 0xb1, 0x86, 0x5a, 0xf3, 0x2e,
- 0x62, 0x1f, 0xf9, 0x69, 0x7a, 0xa8, 0x2d, 0xf3, 0xed, 0x00, 0x75, 0x08,
- 0xd7, 0xa0, 0x4e, 0xb8, 0xfb, 0x0d, 0x41, 0x2e, 0x80, 0xe6, 0x22, 0xd6,
- 0x4e, 0xf7, 0xf3, 0x9e, 0x16, 0x7d, 0x3c, 0x70, 0x6f, 0x3d, 0xfc, 0x97,
- 0x6e, 0x96, 0x86, 0x69, 0xf9, 0xfb, 0x2f, 0xb4, 0x78, 0xd5, 0x79, 0x38,
+ 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0x7a,
+ 0x6d, 0x39, 0xf1, 0xb8, 0x99, 0x96, 0x4d, 0x63, 0xd4, 0x99, 0x78, 0xfc,
+ 0x43, 0x6d, 0x95, 0x69, 0x59, 0x15, 0x17, 0x56, 0x68, 0xba, 0xbb, 0x71,
+ 0xad, 0xaa, 0xaa, 0x5c, 0x29, 0x88, 0x4a, 0x8d, 0x90, 0x59, 0x37, 0x6d,
+ 0x79, 0x4b, 0x11, 0x0f, 0x48, 0x45, 0xca, 0xb2, 0x76, 0xd2, 0x08, 0x2d,
+ 0x99, 0xd6, 0x85, 0x44, 0x42, 0x7d, 0x88, 0x9c, 0x3a, 0xee, 0xc3, 0xca,
+ 0x9b, 0x8a, 0x07, 0x24, 0xa4, 0xa8, 0x55, 0x80, 0xc0, 0x1b, 0x7d, 0xa8,
+ 0xf8, 0x79, 0x22, 0x12, 0x0f, 0x54, 0x08, 0x90, 0x85, 0x04, 0x2a, 0xa5,
+ 0xe4, 0xf2, 0x7d, 0x77, 0x67, 0x92, 0xc5, 0x4d, 0x41, 0xe5, 0x81, 0x95,
+ 0x56, 0x77, 0xe6, 0xde, 0x73, 0xce, 0x3d, 0xf7, 0xfc, 0x7c, 0xe7, 0xdc,
+ 0x39, 0xec, 0xc8, 0x88, 0x64, 0xbf, 0x7d, 0xf8, 0x57, 0xbe, 0x72, 0xe2,
+ 0xeb, 0x0f, 0xdc, 0x57, 0xb9, 0x0f, 0x8f, 0x0f, 0x3a, 0x77, 0x6b, 0x2d,
+ 0xff, 0xc7, 0x9f, 0x2b, 0xe2, 0xe5, 0x7a, 0xf0, 0x2f, 0x25, 0x55, 0x4d,
+ 0x0e, 0xd6, 0x22, 0x29, 0xb9, 0xd5, 0xea, 0xfc, 0x6a, 0x24, 0x92, 0x74,
+ 0xe7, 0x82, 0xba, 0xfc, 0xd3, 0xb4, 0x7c, 0x2d, 0x9c, 0xff, 0x64, 0xf5,
+ 0x83, 0x4f, 0x5f, 0xf9, 0x6c, 0xb8, 0x7b, 0xc1, 0x95, 0x92, 0x57, 0x3d,
+ 0xa3, 0xbd, 0x69, 0x29, 0x4d, 0x80, 0xe7, 0xd5, 0x99, 0x6f, 0x17, 0x64,
+ 0x7f, 0x2e, 0xab, 0x65, 0x54, 0x74, 0xdd, 0x5c, 0x99, 0x89, 0xbc, 0x36,
+ 0x36, 0xb8, 0xdc, 0x0b, 0xa4, 0xd6, 0x2b, 0xcb, 0x9b, 0x3d, 0x5f, 0xde,
+ 0xe8, 0x69, 0x39, 0xfe, 0xca, 0x49, 0x59, 0x8f, 0xc3, 0x72, 0xc3, 0x2d,
+ 0x89, 0xaa, 0x86, 0xe5, 0xa6, 0x04, 0xb2, 0x15, 0x87, 0xad, 0x15, 0x77,
+ 0xdc, 0x29, 0x55, 0x4b, 0xf2, 0xc2, 0x8c, 0x92, 0x0b, 0xfe, 0x31, 0x79,
+ 0x26, 0x7a, 0x12, 0x7f, 0x2d, 0x6a, 0x43, 0x3b, 0xf5, 0xf3, 0x5a, 0xf4,
+ 0xc6, 0x98, 0x3c, 0x12, 0x1b, 0xb3, 0x1a, 0x27, 0xe0, 0x9f, 0x9c, 0x7d,
+ 0x56, 0x86, 0xa5, 0xe5, 0x85, 0x4b, 0x22, 0x05, 0xd2, 0x48, 0x2d, 0x2e,
+ 0x48, 0xe2, 0xf5, 0xcf, 0x75, 0xc1, 0x8e, 0x1f, 0x98, 0x2d, 0xf0, 0x0f,
+ 0x47, 0xf9, 0xfa, 0x1d, 0xd9, 0xba, 0x97, 0xad, 0x2b, 0x51, 0xe7, 0xc2,
+ 0x60, 0x5b, 0xa6, 0x12, 0xed, 0xdc, 0x30, 0xb5, 0xe8, 0x2e, 0xaf, 0xb6,
+ 0xad, 0xc5, 0xdd, 0xa0, 0xfe, 0x91, 0x57, 0x17, 0x03, 0x1e, 0x97, 0x3c,
+ 0x5a, 0x55, 0xbf, 0x06, 0xbf, 0x4d, 0x25, 0xca, 0x11, 0xb9, 0xda, 0x29,
+ 0x7b, 0xb5, 0xde, 0x37, 0x9c, 0x5a, 0x7a, 0xc3, 0x24, 0x7a, 0x44, 0x54,
+ 0x94, 0x38, 0xb5, 0x6d, 0xca, 0x1a, 0x16, 0x1d, 0x0d, 0x81, 0x67, 0xd2,
+ 0x53, 0xc2, 0xb1, 0x96, 0xcd, 0x53, 0x76, 0x03, 0xcf, 0x8b, 0x4e, 0xb2,
+ 0xad, 0x9d, 0xda, 0xf9, 0x25, 0x3c, 0x97, 0xc0, 0x0f, 0xbb, 0xc4, 0x8e,
+ 0x24, 0xcb, 0x0e, 0xf8, 0x78, 0x4e, 0x0f, 0xef, 0x4a, 0x12, 0xdf, 0x93,
+ 0xb5, 0x4a, 0x58, 0x6e, 0xc9, 0xa3, 0x4e, 0x7d, 0xfb, 0x43, 0x4e, 0xf3,
+ 0x96, 0x7a, 0x1f, 0x9e, 0xa3, 0x2e, 0x0f, 0x6b, 0x63, 0xd4, 0xfd, 0x43,
+ 0xd9, 0x19, 0x29, 0x2f, 0xe9, 0xeb, 0xef, 0xf3, 0x1d, 0x3a, 0xa7, 0xd0,
+ 0xbd, 0x5b, 0x84, 0x3e, 0xc6, 0x70, 0x9f, 0x5a, 0x54, 0x87, 0x9e, 0x09,
+ 0xfe, 0xe1, 0x99, 0x26, 0x42, 0xe1, 0xf0, 0xb9, 0x7d, 0x12, 0x8c, 0x1b,
+ 0xd3, 0x88, 0x43, 0x6f, 0x5b, 0x26, 0x64, 0x2d, 0x9d, 0xf0, 0x8e, 0xa4,
+ 0x6d, 0xac, 0xb7, 0x48, 0x03, 0x7b, 0x88, 0x1c, 0xe9, 0x1a, 0x73, 0x29,
+ 0x3e, 0x50, 0x94, 0xfd, 0x6a, 0xbe, 0x20, 0x61, 0x90, 0x60, 0xee, 0xf0,
+ 0xa5, 0xbd, 0x36, 0xbb, 0x27, 0xd3, 0x81, 0x76, 0xc7, 0x3e, 0xf1, 0xa1,
+ 0xec, 0x7d, 0xd4, 0xab, 0x9d, 0xcf, 0xed, 0x6c, 0xf5, 0x86, 0x5d, 0x63,
+ 0xa9, 0x55, 0xa0, 0xff, 0x47, 0x9e, 0x29, 0xe7, 0xa3, 0x2e, 0xd4, 0x1b,
+ 0xf4, 0xd1, 0x2d, 0x9d, 0x9e, 0xfa, 0x90, 0x4e, 0xd4, 0x47, 0x89, 0x3e,
+ 0x57, 0x92, 0xf5, 0xe8, 0x71, 0x25, 0xfb, 0x8d, 0x59, 0x8f, 0xb5, 0xd3,
+ 0x38, 0x7f, 0x2c, 0x7b, 0x46, 0x1c, 0xa6, 0x88, 0xc3, 0x14, 0x71, 0x99,
+ 0x8a, 0xa7, 0xaa, 0x81, 0x5c, 0x99, 0x29, 0xc9, 0x75, 0x17, 0xfe, 0xec,
+ 0xcd, 0x79, 0xaf, 0x21, 0xa6, 0x12, 0xcf, 0x11, 0x37, 0x4a, 0x66, 0x0b,
+ 0xc2, 0x77, 0xc4, 0x92, 0x4e, 0xca, 0x2e, 0x62, 0x29, 0x39, 0xca, 0xb9,
+ 0x21, 0x59, 0xb1, 0x67, 0x99, 0xf3, 0x4e, 0x09, 0x7d, 0x55, 0xc3, 0xda,
+ 0x64, 0x70, 0x4a, 0x76, 0x11, 0x1f, 0x35, 0xac, 0x53, 0x56, 0xe8, 0xb5,
+ 0x40, 0xd1, 0x4e, 0xdf, 0x45, 0x0e, 0xf8, 0x88, 0xfb, 0x99, 0xb2, 0x12,
+ 0x47, 0x56, 0xe7, 0x61, 0x8b, 0xf9, 0x29, 0xd8, 0x88, 0x39, 0xc1, 0xb8,
+ 0xfa, 0xeb, 0xb4, 0x8e, 0x4e, 0x22, 0x7e, 0x40, 0x8b, 0xf3, 0x9f, 0x4a,
+ 0x67, 0xc0, 0x1f, 0x15, 0xa9, 0xe7, 0x56, 0xac, 0x65, 0x3d, 0xbd, 0xa2,
+ 0x0a, 0xd1, 0xef, 0x1d, 0xd9, 0x1f, 0xb6, 0x12, 0x09, 0x5b, 0x4a, 0x29,
+ 0x9f, 0x5b, 0xbf, 0x84, 0x3c, 0x7a, 0xd3, 0xea, 0xaf, 0xc1, 0x57, 0xce,
+ 0xf4, 0xa7, 0xdd, 0x45, 0x36, 0x3b, 0x61, 0xbc, 0x08, 0xdd, 0xae, 0xc2,
+ 0xff, 0xb4, 0xf9, 0xa5, 0x2e, 0x64, 0x77, 0x1c, 0xe6, 0xae, 0xb4, 0xbb,
+ 0xa4, 0xb3, 0x69, 0xbe, 0xa2, 0xab, 0xb2, 0xdc, 0xee, 0x9c, 0x34, 0x6e,
+ 0x24, 0x2b, 0x85, 0x2a, 0xfd, 0x36, 0xba, 0x00, 0x3f, 0x2c, 0xb7, 0xbb,
+ 0x13, 0x8f, 0x6d, 0x76, 0xa4, 0x75, 0x77, 0x55, 0x5a, 0x6e, 0x45, 0xdd,
+ 0xa5, 0x64, 0x0c, 0x72, 0xab, 0xd8, 0x87, 0x71, 0x15, 0x06, 0x75, 0x77,
+ 0xe2, 0xb1, 0x8b, 0x9d, 0x7b, 0x90, 0xb7, 0xf2, 0x41, 0xad, 0x12, 0x21,
+ 0x77, 0xaf, 0x1e, 0x74, 0x25, 0x92, 0xb5, 0x5e, 0x49, 0x6a, 0xe9, 0x84,
+ 0xac, 0xf7, 0x24, 0x79, 0x6a, 0x06, 0xfb, 0x55, 0xf0, 0xde, 0x9b, 0x97,
+ 0x56, 0x6f, 0x62, 0x45, 0x55, 0x5b, 0x92, 0xf4, 0xd6, 0xf1, 0x2f, 0x49,
+ 0xa3, 0x53, 0x2a, 0x5d, 0xec, 0xb4, 0xc8, 0x5f, 0x72, 0xaa, 0x81, 0x3e,
+ 0xdc, 0xdd, 0x65, 0xdc, 0x40, 0xce, 0xf0, 0x97, 0x54, 0x55, 0x4b, 0xd3,
+ 0xf7, 0x21, 0xc3, 0x81, 0x4d, 0xa8, 0xeb, 0x2c, 0xf6, 0xed, 0x8f, 0xad,
+ 0x1e, 0x7d, 0x37, 0x24, 0xed, 0x78, 0x1e, 0x76, 0x62, 0xd4, 0x0e, 0xc9,
+ 0x5a, 0xf4, 0x9e, 0x79, 0x1a, 0xb1, 0xfa, 0x9a, 0x98, 0x7b, 0x6a, 0xc0,
+ 0x93, 0x1a, 0x4c, 0xfa, 0x42, 0x54, 0x96, 0x53, 0xd8, 0xb7, 0xcf, 0xb7,
+ 0x0e, 0x1d, 0xc8, 0x37, 0x06, 0xbe, 0x06, 0xf8, 0x7c, 0x39, 0x6d, 0x79,
+ 0xc7, 0xc0, 0xbb, 0x9b, 0xf1, 0xce, 0x95, 0x17, 0x25, 0x06, 0xcf, 0x64,
+ 0xb0, 0x08, 0x7f, 0xae, 0xf8, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x54,
+ 0x5a, 0xba, 0x42, 0xb9, 0x61, 0xf9, 0x69, 0xe6, 0x83, 0x95, 0xd9, 0x82,
+ 0x4c, 0xe8, 0x95, 0x96, 0x20, 0x67, 0x01, 0xe3, 0x3b, 0xa6, 0x9d, 0x02,
+ 0x77, 0x7c, 0x3e, 0xbf, 0x69, 0x54, 0x15, 0x31, 0x5a, 0x89, 0x82, 0xb6,
+ 0xf0, 0xbd, 0x28, 0x75, 0xe4, 0x99, 0x8a, 0xc6, 0xa4, 0xe9, 0x39, 0x8e,
+ 0xaa, 0xba, 0xd2, 0x44, 0x84, 0x26, 0xcb, 0xda, 0xce, 0xad, 0x20, 0xce,
+ 0x54, 0xf5, 0x7b, 0xaa, 0x5f, 0x0f, 0x0a, 0xa0, 0x41, 0x6e, 0x46, 0xa3,
+ 0xb0, 0xc1, 0x38, 0x68, 0xcf, 0x62, 0x7e, 0x0a, 0xf8, 0x39, 0x0e, 0x1a,
+ 0x8e, 0xcc, 0x11, 0xda, 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60,
+ 0x9b, 0xc1, 0xb4, 0xc9, 0x7d, 0x0c, 0x9a, 0x54, 0x67, 0x79, 0x37, 0x98,
+ 0x4b, 0xf9, 0x7a, 0x80, 0xf5, 0xab, 0x9f, 0x52, 0xb2, 0x6b, 0x2e, 0x46,
+ 0x8c, 0x61, 0x79, 0xaf, 0x11, 0x25, 0xe3, 0xae, 0xcd, 0xf3, 0x3c, 0xdf,
+ 0x39, 0xb2, 0x16, 0x9c, 0x39, 0xb8, 0x1a, 0x39, 0xee, 0xfa, 0xfc, 0x01,
+ 0x69, 0xf9, 0x61, 0x5c, 0x87, 0xbf, 0xd7, 0x53, 0xe6, 0xc6, 0x18, 0xce,
+ 0x1d, 0x22, 0xea, 0x26, 0xf1, 0x9c, 0x1c, 0x04, 0x0f, 0xfc, 0xd8, 0x82,
+ 0x2c, 0x8e, 0x88, 0x99, 0x34, 0x84, 0x8e, 0xb0, 0x47, 0x34, 0xe7, 0x1d,
+ 0x61, 0x3c, 0xfa, 0x5c, 0x63, 0x8d, 0x79, 0xf5, 0x50, 0x2d, 0x0a, 0xe3,
+ 0x66, 0x96, 0x2b, 0x6f, 0xc1, 0xb6, 0xed, 0x94, 0xf5, 0x22, 0xaf, 0x11,
+ 0xcc, 0x0f, 0xc6, 0x4a, 0x8e, 0xb1, 0xe0, 0x89, 0x98, 0x9f, 0xa5, 0x0c,
+ 0x6b, 0x6b, 0x19, 0x8e, 0x2e, 0x40, 0x0f, 0x63, 0x9e, 0x00, 0x86, 0xb6,
+ 0x63, 0x1b, 0x9f, 0xad, 0x40, 0xdd, 0x30, 0x93, 0xd3, 0xb4, 0xb9, 0x31,
+ 0x27, 0xe2, 0x45, 0xd0, 0xfe, 0x16, 0xf6, 0x5a, 0x02, 0x8e, 0x12, 0x7b,
+ 0xb9, 0x77, 0x55, 0xd7, 0x3a, 0xfb, 0xa0, 0x4b, 0x00, 0x7c, 0x83, 0x0d,
+ 0x2c, 0xde, 0x0e, 0x23, 0xdf, 0x99, 0xf3, 0x61, 0xb0, 0x22, 0x9c, 0x97,
+ 0x61, 0x85, 0xf7, 0x26, 0xfc, 0xb4, 0x5e, 0x79, 0xd4, 0x69, 0x6c, 0xbf,
+ 0x9f, 0xf9, 0x48, 0xc6, 0x14, 0x6a, 0x49, 0xd3, 0x27, 0x5f, 0x11, 0x7c,
+ 0xfb, 0xc0, 0xf3, 0x77, 0xac, 0x15, 0x30, 0x0e, 0xca, 0xb1, 0xb8, 0x8d,
+ 0xbd, 0x02, 0xec, 0xb5, 0x24, 0xba, 0xfa, 0x3c, 0xb0, 0x67, 0x2a, 0x68,
+ 0xc8, 0xf7, 0x55, 0xbf, 0x46, 0xd2, 0x37, 0x5f, 0x18, 0xf0, 0x4d, 0x20,
+ 0xae, 0xcd, 0xc1, 0x87, 0xb2, 0x98, 0x22, 0x66, 0x3e, 0x98, 0xad, 0xfb,
+ 0xc0, 0xbe, 0xcf, 0x64, 0x18, 0x5e, 0x22, 0x0e, 0xca, 0x19, 0x8b, 0x83,
+ 0x45, 0xe2, 0x20, 0x70, 0xa5, 0xb5, 0x00, 0x7b, 0xc7, 0xef, 0x02, 0x5f,
+ 0xea, 0xf0, 0xc4, 0x4f, 0x3a, 0x1a, 0x71, 0xe5, 0x82, 0x9f, 0x75, 0xf8,
+ 0xf3, 0xae, 0x8c, 0x84, 0xde, 0xbb, 0xc0, 0x9b, 0xe4, 0x28, 0xf3, 0xc0,
+ 0x18, 0xe4, 0x3a, 0xb0, 0x6a, 0xba, 0x7c, 0x0a, 0x71, 0xef, 0x02, 0x27,
+ 0xb4, 0x70, 0xdf, 0xbc, 0x6e, 0xe6, 0xf5, 0x9b, 0xbf, 0xb7, 0x1d, 0xb8,
+ 0x19, 0xb5, 0xee, 0x73, 0x90, 0x31, 0x15, 0x1c, 0x81, 0x1f, 0xd7, 0x16,
+ 0xfe, 0x1b, 0xcf, 0x6f, 0x32, 0x1e, 0xd4, 0x90, 0x0a, 0xf7, 0x15, 0x69,
+ 0x74, 0x69, 0x87, 0x18, 0x76, 0xb0, 0x18, 0x84, 0x9c, 0x8f, 0x91, 0xf3,
+ 0x22, 0x4d, 0x62, 0x05, 0x30, 0x8c, 0xb8, 0xb7, 0x06, 0x7a, 0x55, 0x19,
+ 0x82, 0x5d, 0x11, 0x4b, 0x4a, 0x4a, 0xba, 0x7a, 0x54, 0xaf, 0x83, 0xb6,
+ 0x50, 0x5d, 0xd6, 0x5b, 0xd1, 0x31, 0x37, 0xef, 0x97, 0xda, 0x1d, 0x71,
+ 0x6a, 0x7d, 0x3f, 0x67, 0x74, 0x8f, 0x65, 0x74, 0x4b, 0x83, 0x74, 0x98,
+ 0x6f, 0x64, 0xf3, 0x09, 0xe6, 0x3f, 0x91, 0xd9, 0x9c, 0xb5, 0xa0, 0x84,
+ 0x3a, 0xcb, 0x3a, 0x10, 0x06, 0x81, 0xfa, 0x4f, 0x75, 0x60, 0x61, 0x00,
+ 0xbb, 0x45, 0xd9, 0xbe, 0xc2, 0x67, 0x4c, 0x0e, 0x9e, 0x75, 0x58, 0x49,
+ 0x74, 0x33, 0x3e, 0xf1, 0xdb, 0xcc, 0xf6, 0x21, 0x2d, 0xf1, 0x7a, 0x90,
+ 0x16, 0x69, 0x04, 0xbb, 0xa8, 0xb3, 0xb7, 0xb3, 0xd9, 0x01, 0xac, 0x21,
+ 0xe7, 0x53, 0x57, 0x1e, 0xd6, 0xcc, 0xef, 0x7b, 0xb5, 0x3d, 0xc7, 0x0e,
+ 0xe8, 0x77, 0x26, 0x2c, 0xce, 0x2c, 0x75, 0x86, 0x20, 0x7e, 0x54, 0x8e,
+ 0x23, 0x9f, 0x9f, 0x86, 0xef, 0x2f, 0xc6, 0x0a, 0xdd, 0x02, 0x6b, 0x8e,
+ 0x41, 0x1c, 0x86, 0xd6, 0x17, 0xb5, 0x68, 0x0d, 0x91, 0xfc, 0x2d, 0xb9,
+ 0x3a, 0x3f, 0x22, 0x85, 0x4b, 0xd4, 0x01, 0xfd, 0xd2, 0xe6, 0xe0, 0x3e,
+ 0x73, 0xd8, 0x67, 0x02, 0x18, 0x78, 0x3f, 0xea, 0x8b, 0x2f, 0x7a, 0x1a,
+ 0x58, 0x9b, 0x96, 0x9c, 0x3a, 0xe4, 0xab, 0x4b, 0x3c, 0x3f, 0x31, 0xb8,
+ 0x94, 0xd5, 0x36, 0xe6, 0xd6, 0x10, 0x6a, 0xfa, 0x1f, 0x91, 0xbb, 0x4a,
+ 0x56, 0x2b, 0xc6, 0x1c, 0x89, 0x7f, 0x00, 0xfb, 0x62, 0x6e, 0x93, 0x6b,
+ 0xbb, 0x98, 0xe7, 0x1c, 0x65, 0x30, 0x16, 0x0f, 0xa0, 0xae, 0x61, 0xcf,
+ 0xa3, 0xe4, 0x19, 0x42, 0xcd, 0x27, 0xfe, 0x63, 0xdc, 0xe4, 0x3b, 0xcf,
+ 0x44, 0x6c, 0x73, 0x31, 0x8e, 0x60, 0xe4, 0x99, 0x7e, 0x91, 0xf9, 0x8a,
+ 0xcf, 0xc6, 0xe8, 0xea, 0xa8, 0xd4, 0x3b, 0x11, 0x30, 0x76, 0xaa, 0x7c,
+ 0x5c, 0xb8, 0x86, 0xf7, 0x2e, 0xe7, 0xbd, 0x81, 0x79, 0x3c, 0x77, 0xad,
+ 0xce, 0xa8, 0xed, 0x79, 0xff, 0xb2, 0x06, 0xc3, 0xa2, 0xc7, 0xd8, 0x64,
+ 0xaf, 0xc2, 0xfa, 0x67, 0x71, 0x6b, 0x96, 0x7d, 0xca, 0xeb, 0x1d, 0xd6,
+ 0x42, 0xcd, 0xbc, 0x44, 0x00, 0x1c, 0x92, 0xba, 0x9f, 0x9f, 0x0b, 0x71,
+ 0x1c, 0x53, 0x36, 0x65, 0x4c, 0xc2, 0x76, 0xec, 0x47, 0xa2, 0xb2, 0x76,
+ 0xa6, 0x92, 0x26, 0xf9, 0xba, 0x05, 0x29, 0x6c, 0xcc, 0x8b, 0x7b, 0xd6,
+ 0xc8, 0x66, 0x5f, 0x9e, 0xb7, 0x2c, 0xbe, 0xd4, 0x5e, 0xa2, 0x1e, 0x98,
+ 0xdf, 0x61, 0x3d, 0x0c, 0x81, 0x67, 0xc5, 0x6c, 0xdf, 0xb2, 0x34, 0x3b,
+ 0x91, 0xd7, 0x10, 0x8c, 0xdd, 0x3b, 0xe0, 0xbb, 0x22, 0xce, 0xac, 0xe5,
+ 0x62, 0xa7, 0xbf, 0x17, 0x73, 0xee, 0xb9, 0xb8, 0xbf, 0x57, 0x43, 0x7e,
+ 0x89, 0xbd, 0xc4, 0x57, 0xc2, 0x3e, 0x12, 0x7d, 0xe3, 0x39, 0x8d, 0xfd,
+ 0x68, 0xa3, 0x02, 0x7a, 0xdb, 0xd9, 0xec, 0x3c, 0x21, 0xe8, 0x34, 0x6c,
+ 0x4e, 0x5b, 0x73, 0x0f, 0xc6, 0xe2, 0x3f, 0x0c, 0xf1, 0x05, 0x75, 0x05,
+ 0xfa, 0xe2, 0xbd, 0xc7, 0x3d, 0x26, 0xe4, 0xc5, 0xd4, 0x62, 0xad, 0x77,
+ 0x02, 0x98, 0xd5, 0xe8, 0xfc, 0x2d, 0xaf, 0x3d, 0x49, 0x1b, 0xf8, 0xfb,
+ 0xac, 0x8c, 0x8a, 0xde, 0x19, 0x95, 0xe7, 0xd0, 0xef, 0x15, 0x36, 0x50,
+ 0xe7, 0x61, 0x63, 0x75, 0xb6, 0x35, 0xcb, 0x9e, 0xed, 0x32, 0x72, 0x79,
+ 0xb5, 0x12, 0xc5, 0xae, 0x33, 0x2d, 0x67, 0xbe, 0x1b, 0xce, 0x6e, 0xdb,
+ 0x7c, 0xc6, 0xfa, 0x4e, 0x20, 0xa7, 0xbb, 0x91, 0x9c, 0xe9, 0x7a, 0xd0,
+ 0xcb, 0xbb, 0xd5, 0xd7, 0x46, 0xc4, 0xdb, 0x06, 0xfe, 0xc4, 0x53, 0x9e,
+ 0x0b, 0x3e, 0xa8, 0xd2, 0x6e, 0xec, 0x63, 0xe9, 0x5f, 0xe2, 0xdb, 0xa3,
+ 0x78, 0x1e, 0x11, 0xf7, 0x1c, 0xfb, 0x4e, 0xc6, 0x24, 0xfd, 0x33, 0xd8,
+ 0x0b, 0x13, 0xfb, 0x20, 0x73, 0x87, 0xb9, 0x9f, 0xe7, 0x66, 0x9e, 0xab,
+ 0xc4, 0x01, 0xed, 0x2c, 0xc2, 0x5e, 0xd7, 0x62, 0xe6, 0xeb, 0x0d, 0x73,
+ 0xcd, 0xf6, 0x6e, 0x1e, 0xfb, 0xe2, 0x81, 0xde, 0x2d, 0xef, 0x7b, 0x18,
+ 0xaf, 0xe5, 0x81, 0x7c, 0xbd, 0x6e, 0x73, 0xf5, 0x0d, 0xe4, 0xed, 0xcb,
+ 0x69, 0xd9, 0xe6, 0xec, 0xe1, 0x07, 0x6e, 0x97, 0xb3, 0x97, 0x3f, 0x46,
+ 0xce, 0xfe, 0x30, 0xcb, 0xd9, 0xa2, 0x8d, 0x6b, 0xb5, 0x31, 0xb8, 0xf6,
+ 0x23, 0xac, 0x0d, 0x65, 0x77, 0x0a, 0x6d, 0x3b, 0xe8, 0xc3, 0x0f, 0xd2,
+ 0x47, 0xb9, 0x7f, 0xfa, 0x71, 0x5a, 0xd7, 0xa4, 0x81, 0x0f, 0x37, 0x46,
+ 0x11, 0x4f, 0xcc, 0xe9, 0x3c, 0x9e, 0x02, 0xc4, 0x72, 0xce, 0x8f, 0x7e,
+ 0xf3, 0x28, 0x63, 0xa1, 0x60, 0xf3, 0xc6, 0xad, 0xe6, 0x34, 0x65, 0x59,
+ 0x44, 0x2f, 0xf7, 0x63, 0x8e, 0xdd, 0x7e, 0xac, 0x14, 0x37, 0x4a, 0xf2,
+ 0xfc, 0x0c, 0xb1, 0x2b, 0x8c, 0xaf, 0x42, 0xe7, 0x6b, 0x91, 0x2f, 0x85,
+ 0x69, 0xe6, 0x33, 0xab, 0x51, 0x11, 0x31, 0x84, 0xbb, 0x55, 0x6a, 0x4e,
+ 0xa2, 0xdf, 0x0a, 0x34, 0xfc, 0xfc, 0x32, 0xe2, 0x88, 0xd8, 0x8a, 0x98,
+ 0x98, 0xdd, 0x44, 0x4c, 0x1c, 0xe7, 0xbb, 0xdd, 0xb7, 0x60, 0x69, 0x5d,
+ 0xbb, 0xbf, 0x0f, 0xfd, 0x4b, 0x32, 0x74, 0xce, 0xe0, 0x4e, 0x75, 0x8b,
+ 0xef, 0xb4, 0x8d, 0x5f, 0x60, 0x09, 0xe6, 0x57, 0x6d, 0xfc, 0xd2, 0xa7,
+ 0x8c, 0x7b, 0x63, 0x7e, 0x67, 0xf3, 0xe6, 0xd7, 0x16, 0x03, 0xae, 0xc5,
+ 0x36, 0x9e, 0x63, 0xf6, 0x9b, 0xa7, 0xbb, 0x3f, 0xd7, 0x16, 0x23, 0x36,
+ 0x8c, 0x9c, 0x8a, 0x6d, 0xac, 0xcd, 0xbe, 0x81, 0x63, 0xbf, 0xd6, 0xcf,
+ 0x85, 0x01, 0x39, 0x93, 0xde, 0x23, 0x90, 0x83, 0x9a, 0x17, 0xac, 0xb1,
+ 0x3f, 0x88, 0xa7, 0xd0, 0x2f, 0x81, 0xae, 0xbb, 0x17, 0x2f, 0xc6, 0x31,
+ 0xd2, 0xde, 0x7f, 0x80, 0x5c, 0x0f, 0x36, 0xa4, 0x1c, 0xea, 0x4d, 0xbd,
+ 0x46, 0x25, 0x3a, 0x9b, 0xeb, 0xf4, 0x17, 0xab, 0xcb, 0xbf, 0xcb, 0xc3,
+ 0xfa, 0xce, 0xed, 0xf8, 0xbc, 0x01, 0xbe, 0x3f, 0xdf, 0x86, 0x0f, 0xeb,
+ 0x3b, 0xe4, 0x19, 0xb9, 0xd9, 0x6b, 0xd4, 0x6f, 0xc6, 0x75, 0x82, 0xb8,
+ 0x27, 0xef, 0xde, 0xbb, 0xdc, 0x60, 0x0e, 0xe4, 0x35, 0x9e, 0x71, 0xce,
+ 0x3d, 0xf3, 0x58, 0xcf, 0x63, 0x3c, 0x8f, 0xf9, 0x3c, 0xd6, 0xc3, 0xf8,
+ 0x19, 0xe9, 0xfb, 0x57, 0x6f, 0x84, 0xd8, 0x7f, 0xe4, 0x7f, 0xb8, 0xb7,
+ 0x10, 0x23, 0x24, 0xb9, 0x75, 0xd7, 0xfb, 0x69, 0xd6, 0xaf, 0x94, 0x98,
+ 0x6b, 0xf8, 0xb3, 0x8f, 0xdf, 0x45, 0x7f, 0x10, 0x67, 0xb6, 0x4d, 0xb2,
+ 0xb1, 0x4f, 0xd3, 0xef, 0x07, 0xbf, 0x9a, 0x61, 0xf2, 0x17, 0xfb, 0xf5,
+ 0x47, 0xf2, 0x9c, 0x62, 0x0e, 0xd9, 0x9c, 0xe2, 0x79, 0x70, 0x0f, 0x37,
+ 0x66, 0x19, 0x7e, 0x7c, 0x3e, 0xce, 0xf3, 0x08, 0xf1, 0xf4, 0x40, 0x9e,
+ 0xe3, 0xb0, 0x53, 0x74, 0xc3, 0xe8, 0xe9, 0x04, 0x36, 0xe3, 0xdd, 0xb7,
+ 0x81, 0xde, 0x89, 0x76, 0x5a, 0x72, 0x9e, 0xb8, 0x79, 0xdf, 0xdd, 0xdb,
+ 0x27, 0xd1, 0x6e, 0xb4, 0xeb, 0xa0, 0xdd, 0xc2, 0x78, 0x5c, 0x11, 0x03,
+ 0x6e, 0x87, 0x13, 0x79, 0x3d, 0x07, 0x06, 0x4d, 0xe7, 0x76, 0xfa, 0xd8,
+ 0x35, 0x3d, 0xe9, 0x7f, 0x2b, 0xd8, 0x8b, 0x0f, 0xdb, 0xee, 0x00, 0x3e,
+ 0xdc, 0xa6, 0xe7, 0xa4, 0x0c, 0xda, 0x00, 0xf5, 0xcd, 0xf6, 0x21, 0xec,
+ 0x31, 0x6f, 0x18, 0xd7, 0xf6, 0x9b, 0xc4, 0x46, 0xf6, 0x99, 0xdf, 0x2c,
+ 0xc8, 0xc8, 0x3e, 0xfb, 0x9e, 0x6c, 0x73, 0x64, 0x4c, 0x48, 0xbf, 0x6e,
+ 0x59, 0xfd, 0x1f, 0xcf, 0xf4, 0xef, 0xeb, 0x2c, 0xea, 0xa3, 0x30, 0x8d,
+ 0xba, 0x7a, 0xd0, 0x35, 0xcc, 0xed, 0xd2, 0x52, 0xd5, 0x13, 0xd2, 0xa8,
+ 0xb0, 0x5f, 0x12, 0xdc, 0xb5, 0xa0, 0xc3, 0x02, 0xf5, 0x28, 0x43, 0x8f,
+ 0x51, 0xdc, 0x4d, 0xc2, 0xa5, 0x96, 0x84, 0xc9, 0x0a, 0x08, 0x67, 0xbe,
+ 0x43, 0xbb, 0x1d, 0xd3, 0x5b, 0x1d, 0xda, 0xed, 0x49, 0xbd, 0xde, 0x99,
+ 0x44, 0x7f, 0x18, 0xc2, 0xdb, 0xe1, 0xec, 0x25, 0x61, 0x8c, 0xcd, 0xc5,
+ 0x1c, 0x4f, 0x0b, 0xfb, 0xb1, 0x63, 0x7a, 0xaa, 0xcb, 0xf1, 0x49, 0x1d,
+ 0x75, 0x07, 0xe5, 0xfe, 0xc9, 0x00, 0x13, 0x93, 0xeb, 0xc8, 0xa3, 0x17,
+ 0x7b, 0xfd, 0xbd, 0x71, 0x3f, 0xcc, 0xe4, 0x62, 0x2e, 0xcd, 0x65, 0x0b,
+ 0x71, 0x8a, 0xb2, 0x21, 0x77, 0x32, 0xfe, 0x99, 0xdd, 0x83, 0xf7, 0xa3,
+ 0x8f, 0xda, 0xe3, 0xae, 0xfc, 0xfb, 0x04, 0x72, 0xa7, 0x60, 0xb1, 0x67,
+ 0x2d, 0xc5, 0x9d, 0xda, 0x37, 0xa6, 0x19, 0xbd, 0x0d, 0xdb, 0xa1, 0x47,
+ 0x98, 0xf7, 0xf0, 0x07, 0xae, 0x2e, 0x73, 0x0d, 0x7d, 0x38, 0xee, 0x82,
+ 0xbc, 0xcf, 0xad, 0xa5, 0x5c, 0x63, 0x8c, 0xa3, 0x57, 0x9c, 0xff, 0x15,
+ 0x68, 0xdf, 0x31, 0xad, 0x9e, 0xb2, 0xf7, 0x75, 0x15, 0xe1, 0x1e, 0xd6,
+ 0x63, 0x3f, 0x23, 0x4e, 0x23, 0x95, 0xa0, 0x19, 0x2f, 0xd8, 0xfb, 0x5a,
+ 0xe2, 0x05, 0xbc, 0x93, 0xa2, 0x07, 0x9d, 0x1f, 0xe8, 0x41, 0xe7, 0xd1,
+ 0x83, 0x8e, 0x15, 0x11, 0xe7, 0x09, 0xee, 0xa1, 0xaa, 0xd9, 0xcf, 0x9b,
+ 0x31, 0xde, 0x39, 0xdb, 0xbe, 0xec, 0x43, 0x77, 0x05, 0xdd, 0x22, 0xec,
+ 0xcf, 0xf5, 0x3b, 0xb3, 0xef, 0x5a, 0xa3, 0xa0, 0x4f, 0x6c, 0x3f, 0xd6,
+ 0xf6, 0x8b, 0xd2, 0x8c, 0x49, 0x73, 0x28, 0xa3, 0xf9, 0xf2, 0x1e, 0x9a,
+ 0x3b, 0x79, 0x46, 0xca, 0x96, 0xe6, 0x2b, 0xcc, 0x3b, 0xd6, 0xd2, 0x62,
+ 0x96, 0x6f, 0x27, 0xf0, 0x3c, 0x94, 0x3d, 0xe7, 0xf4, 0xf7, 0xee, 0xe1,
+ 0x7f, 0xc8, 0xe9, 0xbf, 0xf3, 0x99, 0x3a, 0x27, 0xec, 0x93, 0x21, 0x6f,
+ 0xc1, 0xe9, 0x7f, 0x27, 0xc1, 0x85, 0x73, 0x84, 0x3e, 0xe9, 0xf7, 0x17,
+ 0xc0, 0x60, 0x74, 0x5f, 0x53, 0xb0, 0xbb, 0x31, 0xed, 0x05, 0xe2, 0xda,
+ 0xdc, 0xec, 0x11, 0x8b, 0x6f, 0x6a, 0x42, 0x49, 0x8e, 0xb9, 0x83, 0xcf,
+ 0x18, 0x17, 0xec, 0x37, 0x03, 0xbc, 0xf7, 0x65, 0x6c, 0xe1, 0xfe, 0x2c,
+ 0xc8, 0xe1, 0x96, 0xd5, 0xcb, 0xe9, 0xdf, 0x8b, 0xbc, 0x1a, 0xeb, 0x01,
+ 0xea, 0xc6, 0x0c, 0xf5, 0xba, 0xf9, 0x6d, 0x63, 0x05, 0xb5, 0xe6, 0x2d,
+ 0xc4, 0x3e, 0xf2, 0xd3, 0xf6, 0x58, 0x5b, 0xf6, 0xdb, 0x02, 0xea, 0xd0,
+ 0x08, 0xee, 0x4b, 0xd1, 0xcd, 0x6f, 0x0c, 0x72, 0x01, 0x34, 0x17, 0xb1,
+ 0x76, 0xba, 0x9b, 0xf7, 0xbc, 0xe8, 0xf3, 0x81, 0x7b, 0xab, 0xd1, 0xfb,
+ 0xa6, 0xe9, 0x0f, 0xd2, 0xf2, 0xf7, 0x2f, 0x97, 0xa2, 0x15, 0x3a, 0x18,
0x15, 0x00, 0x00, 0x00 };
static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
@@ -3681,15 +3691,15 @@ static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
0x00000001, 0x00000000 };
static struct fw_info bnx2_tpat_fw_09 = {
- /* Firmware version: 4.0.5 */
+ /* Firmware version: 4.4.26 */
.ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
+ .ver_minor = 0x4,
+ .ver_fix = 0x1a,
- .start_addr = 0x08000888,
+ .start_addr = 0x08000488,
- .text_addr = 0x08000800,
- .text_len = 0x1534,
+ .text_addr = 0x08000400,
+ .text_len = 0x1514,
.text_index = 0x0,
.gz_text = bnx2_TPAT_b09FwText,
.gz_text_len = sizeof(bnx2_TPAT_b09FwText),
@@ -3699,863 +3709,871 @@ static struct fw_info bnx2_tpat_fw_09 = {
.data_index = 0x0,
.data = bnx2_TPAT_b09FwData,
- .sbss_addr = 0x08001d60,
+ .sbss_addr = 0x08001940,
.sbss_len = 0x48,
.sbss_index = 0x0,
- .bss_addr = 0x08001da8,
- .bss_len = 0x10a0,
+ .bss_addr = 0x08001988,
+ .bss_len = 0x12b4,
.bss_index = 0x0,
- .rodata_addr = 0x08001d34,
+ .rodata_addr = 0x08001914,
.rodata_len = 0x4,
.rodata_index = 0x0,
.rodata = bnx2_TPAT_b09FwRodata,
};
static u8 bnx2_TXP_b09FwText[] = {
- 0xa5, 0x7b, 0x0b, 0x74, 0x1c, 0x55, 0x7a, 0xe6, 0x77, 0xab, 0xba, 0xa5,
- 0xea, 0x56, 0xab, 0x55, 0x92, 0xdb, 0xa6, 0x95, 0xd1, 0xe0, 0x2e, 0x77,
- 0xb5, 0xdc, 0x58, 0xc2, 0x54, 0xcb, 0x2d, 0xd3, 0x44, 0xe5, 0xb8, 0xc7,
- 0x08, 0x5b, 0x06, 0x4d, 0x46, 0x38, 0xca, 0xac, 0x98, 0xc3, 0x2e, 0x1d,
- 0x63, 0x83, 0x30, 0x06, 0x04, 0xc3, 0x66, 0x95, 0x2c, 0x89, 0x6a, 0xe4,
- 0x07, 0x7e, 0xb4, 0xba, 0xf5, 0x32, 0x32, 0xd9, 0x9c, 0xb8, 0x2d, 0xc9,
- 0x96, 0x81, 0x7e, 0xc0, 0x00, 0x33, 0x43, 0x76, 0x67, 0xe9, 0x35, 0x60,
- 0x0c, 0x8c, 0x61, 0x92, 0x3d, 0x67, 0x97, 0xc9, 0x99, 0x49, 0x7c, 0x30,
- 0x78, 0x6c, 0xde, 0x9b, 0x99, 0xdd, 0x15, 0x09, 0x93, 0xda, 0xff, 0xaf,
- 0x96, 0x8c, 0x61, 0xd8, 0x24, 0x9b, 0xd5, 0x39, 0x7d, 0x4a, 0x5d, 0x75,
- 0xeb, 0xde, 0xff, 0xfd, 0x7f, 0xff, 0x7f, 0x6f, 0x47, 0x00, 0x2f, 0x16,
- 0xfe, 0x6a, 0xe9, 0x13, 0x1f, 0x18, 0x7c, 0xb0, 0x7d, 0xb5, 0xb1, 0xda,
- 0xb9, 0xe1, 0x86, 0x8b, 0x1f, 0xae, 0x15, 0x40, 0xea, 0x5d, 0xfc, 0x8b,
- 0xfe, 0xbe, 0xfa, 0x2f, 0x7b, 0x0d, 0x32, 0xa0, 0x2e, 0xd2, 0xc4, 0x1f,
- 0x28, 0x92, 0x99, 0xfb, 0xcd, 0x0d, 0x3a, 0x14, 0xd9, 0xec, 0x5b, 0x77,
- 0xbb, 0x0e, 0x24, 0xf3, 0x2d, 0xa1, 0xeb, 0xf1, 0x2b, 0xdb, 0x0a, 0xb8,
- 0xc0, 0xf7, 0xbf, 0x6a, 0x7e, 0x3a, 0xf4, 0xc3, 0x6b, 0xb5, 0x8f, 0x73,
- 0x32, 0x14, 0xd5, 0x9c, 0x84, 0xda, 0x0c, 0xa5, 0x89, 0xde, 0xf9, 0xd3,
- 0x95, 0xdf, 0x77, 0xc1, 0xbf, 0x38, 0x17, 0x2c, 0xb7, 0x69, 0x60, 0x57,
- 0x76, 0x00, 0x73, 0x71, 0xe0, 0x42, 0x3a, 0x62, 0xec, 0x02, 0x46, 0x25,
- 0x33, 0x12, 0x3a, 0x89, 0x10, 0x66, 0xf3, 0xb0, 0xaa, 0x4d, 0x1d, 0xfb,
- 0x4a, 0x21, 0x5c, 0x4c, 0xff, 0x83, 0x1d, 0x72, 0x0f, 0xe0, 0xed, 0x38,
- 0x94, 0xa0, 0xf9, 0x10, 0x82, 0x59, 0x28, 0xb5, 0xe6, 0x20, 0x0a, 0x23,
- 0xc0, 0x9e, 0xb4, 0x36, 0x00, 0x68, 0x7d, 0x45, 0x11, 0x3e, 0x7d, 0x02,
- 0x5a, 0x4f, 0xa3, 0xdc, 0x92, 0xba, 0x45, 0x68, 0xc9, 0x9d, 0x02, 0x8a,
- 0xa0, 0xb1, 0xab, 0xf2, 0x7c, 0x1d, 0x44, 0x34, 0xaf, 0xe0, 0xac, 0xcc,
- 0xcb, 0x9a, 0x24, 0x67, 0x01, 0x97, 0x6e, 0x60, 0x4f, 0x16, 0x96, 0xcb,
- 0x14, 0xd8, 0x15, 0x8f, 0xa8, 0x33, 0xe0, 0xe7, 0x21, 0x0c, 0x3b, 0xe3,
- 0x34, 0xe2, 0xd8, 0xb6, 0x77, 0x1b, 0xb6, 0x7d, 0xcc, 0xa8, 0x86, 0xa5,
- 0x6a, 0x41, 0x40, 0x60, 0xd8, 0x90, 0x90, 0x54, 0x37, 0x84, 0x5c, 0xd0,
- 0x82, 0xdb, 0xf1, 0xf7, 0xc4, 0x6f, 0x32, 0xea, 0x46, 0x65, 0x7c, 0x0a,
- 0xd5, 0x28, 0xab, 0x15, 0x89, 0x4d, 0xa7, 0x6d, 0xfb, 0x94, 0xee, 0xc2,
- 0x31, 0x92, 0xcd, 0x70, 0xfe, 0xef, 0xed, 0x32, 0xc9, 0x65, 0xb7, 0xbe,
- 0xb8, 0xbe, 0x82, 0x9c, 0x6a, 0xdb, 0x33, 0xf4, 0x6c, 0x6f, 0x7e, 0x51,
- 0xc6, 0xb6, 0x2d, 0xe9, 0xb6, 0x7d, 0xbb, 0xfe, 0x77, 0xf6, 0xd6, 0xcf,
- 0x8d, 0x8d, 0xe1, 0xf1, 0x51, 0x15, 0x4f, 0x64, 0x93, 0xc8, 0xa7, 0x6d,
- 0xc8, 0xa6, 0x0b, 0xfd, 0x23, 0x21, 0xec, 0x2c, 0x74, 0xa2, 0x90, 0xd6,
- 0x52, 0x67, 0xe9, 0xbd, 0xad, 0x71, 0x1d, 0xf7, 0x14, 0xba, 0x30, 0x97,
- 0x86, 0xed, 0x31, 0xf5, 0xb2, 0x47, 0x44, 0x71, 0x67, 0xa1, 0x1b, 0xc5,
- 0xb4, 0x7e, 0x7a, 0x58, 0x44, 0x06, 0x1b, 0x65, 0x17, 0xee, 0x2b, 0xb4,
- 0xe2, 0xde, 0x42, 0x82, 0xde, 0xb1, 0x71, 0x63, 0xac, 0x89, 0xc6, 0xb7,
- 0xe1, 0xb1, 0x49, 0xdb, 0x8e, 0xc6, 0x54, 0xf4, 0x17, 0x0c, 0xcc, 0x8d,
- 0x4a, 0x48, 0x1d, 0x73, 0x21, 0x75, 0x14, 0xb8, 0xf3, 0x68, 0x1b, 0x66,
- 0x46, 0x6d, 0x6c, 0x35, 0x86, 0x1b, 0x25, 0x32, 0xbb, 0x94, 0x2a, 0xe0,
- 0xd6, 0xfd, 0xd8, 0xae, 0x56, 0x68, 0x3f, 0x2b, 0x0b, 0xec, 0x38, 0x1a,
- 0xc5, 0x9b, 0x69, 0x0b, 0x37, 0xb6, 0x07, 0x31, 0x58, 0x08, 0xe0, 0x8d,
- 0x74, 0x80, 0xd6, 0x30, 0xf0, 0x7a, 0x5a, 0xa1, 0x75, 0x5a, 0xf1, 0x62,
- 0x9a, 0xc7, 0xf0, 0x58, 0x1f, 0xb6, 0x15, 0x9a, 0x70, 0x26, 0x1d, 0xa4,
- 0x35, 0x03, 0x78, 0x85, 0xc6, 0xdd, 0x55, 0xd0, 0x71, 0x9a, 0xc6, 0xf5,
- 0x17, 0x42, 0x78, 0x39, 0xed, 0x23, 0x5a, 0x03, 0x38, 0x99, 0x1e, 0xc0,
- 0xae, 0x74, 0xcb, 0xe9, 0xeb, 0x49, 0x86, 0xa1, 0x25, 0xbc, 0x0e, 0xdf,
- 0x7b, 0xdb, 0xee, 0x0e, 0x38, 0x66, 0x42, 0xeb, 0x2c, 0xae, 0x3b, 0x80,
- 0xe1, 0xf4, 0x8b, 0x0b, 0x7e, 0x62, 0x60, 0xff, 0xe8, 0xbc, 0xfd, 0xc3,
- 0x95, 0x4d, 0x38, 0x91, 0x05, 0x1e, 0x9b, 0x01, 0x66, 0xb2, 0x96, 0x5d,
- 0x6b, 0xda, 0xf6, 0x74, 0x7b, 0x2b, 0xc9, 0x4b, 0xef, 0xdb, 0x4a, 0xa3,
- 0x9e, 0x28, 0xb9, 0x80, 0xa3, 0x5a, 0x5f, 0x19, 0x12, 0x72, 0x73, 0x2e,
- 0x54, 0x8d, 0x68, 0x5d, 0x39, 0x68, 0xa7, 0xef, 0x24, 0x4f, 0x3a, 0x96,
- 0xd5, 0x7a, 0x2c, 0x0c, 0xd9, 0x41, 0xb3, 0x39, 0xd4, 0x2a, 0xdb, 0xf0,
- 0x93, 0x2d, 0xa4, 0x5b, 0x6d, 0xbb, 0xee, 0x5a, 0xdb, 0x3e, 0xd3, 0x0e,
- 0x5b, 0x32, 0xf5, 0xd3, 0x25, 0xe8, 0xe5, 0x0f, 0xa0, 0x0f, 0x9e, 0x44,
- 0xf9, 0xab, 0x3e, 0x44, 0xfa, 0xc3, 0x72, 0x64, 0x60, 0x9e, 0xde, 0xad,
- 0x2d, 0x90, 0x29, 0x13, 0x2f, 0x3a, 0xd9, 0x60, 0xa1, 0xa4, 0xc0, 0x45,
- 0xfc, 0xb4, 0x8e, 0xd8, 0xb6, 0x4b, 0xf7, 0xc1, 0x47, 0xf2, 0xdd, 0x74,
- 0xc8, 0xb6, 0xcf, 0x1b, 0x2a, 0xaa, 0x48, 0x37, 0x37, 0x8c, 0xd9, 0x98,
- 0x36, 0x4e, 0x92, 0x3c, 0x05, 0x52, 0x3d, 0x71, 0x7a, 0x27, 0x40, 0xe3,
- 0x13, 0xd8, 0x34, 0x12, 0xc4, 0xe3, 0x59, 0x05, 0x3f, 0x5c, 0x19, 0x45,
- 0x0d, 0xcd, 0xe5, 0x25, 0x59, 0x55, 0x93, 0xfc, 0x50, 0x20, 0x73, 0x2b,
- 0x54, 0xec, 0x11, 0x85, 0xb3, 0xc4, 0x63, 0x10, 0xdf, 0x2d, 0x05, 0xf0,
- 0x54, 0x49, 0xc5, 0x93, 0xa5, 0x26, 0x3c, 0x5f, 0x32, 0x90, 0x1d, 0xd5,
- 0xf6, 0x95, 0x61, 0xa3, 0x96, 0xcc, 0xf9, 0x8d, 0x5c, 0x0c, 0x99, 0x51,
- 0xdb, 0xce, 0x13, 0xcd, 0x5e, 0xe2, 0xe1, 0xf5, 0xdc, 0x95, 0x38, 0x3e,
- 0xe9, 0x42, 0x68, 0x3a, 0x80, 0x27, 0xd2, 0x2e, 0x5c, 0x95, 0xd1, 0xac,
- 0x1c, 0xf4, 0xe8, 0x4e, 0xa1, 0x27, 0x57, 0x09, 0x6d, 0xd4, 0x42, 0x24,
- 0xe4, 0x16, 0x12, 0x9a, 0x8f, 0xbb, 0xa0, 0x17, 0x43, 0x70, 0x37, 0x2b,
- 0xd0, 0x9b, 0xc9, 0x8d, 0xfc, 0x12, 0xaa, 0xc8, 0x2f, 0x36, 0x8d, 0x47,
- 0xe9, 0x5e, 0x80, 0xee, 0xe1, 0xca, 0x6a, 0xc8, 0xcb, 0x64, 0x90, 0xdc,
- 0x74, 0x19, 0x49, 0x97, 0x6d, 0xcb, 0x7a, 0x1b, 0xfa, 0x1e, 0xa1, 0xeb,
- 0x1a, 0x1e, 0xaf, 0x22, 0x5c, 0x24, 0x19, 0x34, 0x13, 0x4d, 0x59, 0xa2,
- 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6, 0xac, 0x4c, 0x36, 0xa3, 0x19, 0xc0,
- 0x1f, 0x92, 0xae, 0x42, 0xc4, 0xdf, 0x9b, 0x8e, 0x9e, 0x9e, 0x2a, 0x05,
- 0x89, 0xfe, 0x90, 0x43, 0xff, 0x63, 0xa3, 0x02, 0x92, 0xae, 0xf5, 0x9c,
- 0xc5, 0x7a, 0x84, 0x63, 0x5a, 0x32, 0x87, 0x24, 0xbd, 0xa7, 0xed, 0xb3,
- 0xa0, 0x75, 0x95, 0x49, 0xff, 0x5b, 0xd5, 0x04, 0xe6, 0xb2, 0x6e, 0xd4,
- 0xe8, 0x5a, 0x88, 0xf4, 0x15, 0x2d, 0x63, 0x09, 0xee, 0x56, 0x69, 0x4e,
- 0xa9, 0x4a, 0x54, 0x62, 0xc8, 0x43, 0x88, 0x8c, 0x4b, 0x98, 0x35, 0x64,
- 0xf2, 0x4f, 0x03, 0x72, 0x33, 0x2d, 0x57, 0x8c, 0xd3, 0x95, 0xe6, 0xcf,
- 0xd2, 0x5a, 0x44, 0x0f, 0xcd, 0x47, 0x7e, 0xc9, 0x72, 0x8c, 0x12, 0x0d,
- 0x7b, 0x1c, 0x7a, 0x9f, 0x2c, 0x75, 0x8b, 0x8a, 0xfd, 0x98, 0x64, 0x2f,
- 0x5a, 0x08, 0x42, 0x8b, 0x86, 0x84, 0x66, 0x24, 0x85, 0x8a, 0x99, 0xd2,
- 0x8f, 0x68, 0x4c, 0xe0, 0xb2, 0x31, 0x3d, 0x18, 0xce, 0x0a, 0x5c, 0xaf,
- 0xdb, 0xd8, 0x60, 0xf4, 0x60, 0x57, 0x69, 0xd1, 0x2f, 0x39, 0x76, 0xa9,
- 0xfe, 0x99, 0x74, 0x27, 0x76, 0x67, 0x43, 0xd8, 0x95, 0x0f, 0xfa, 0xa7,
- 0xd3, 0xfc, 0x4c, 0x27, 0x7f, 0xe7, 0x67, 0x81, 0xcb, 0x9e, 0x35, 0x5d,
- 0xf6, 0x2c, 0x81, 0xe1, 0x89, 0xaf, 0x50, 0x0c, 0xa9, 0xc3, 0x2e, 0xfd,
- 0x63, 0xb2, 0x15, 0x3d, 0xb1, 0x0d, 0x8d, 0x38, 0xab, 0xb6, 0xe2, 0xe0,
- 0x54, 0x37, 0x76, 0x4f, 0xad, 0xc6, 0xfe, 0x89, 0xa6, 0x94, 0xd7, 0x1c,
- 0xa1, 0xf5, 0xc3, 0xc9, 0x6d, 0x42, 0x1b, 0x90, 0x45, 0x38, 0xba, 0x8d,
- 0x6c, 0xb7, 0xb9, 0xde, 0xb6, 0x4f, 0xc6, 0xc8, 0xb6, 0x8d, 0x16, 0x63,
- 0x13, 0x09, 0xa0, 0xdc, 0xa3, 0x75, 0xbd, 0x0d, 0x1f, 0xbe, 0x4e, 0x36,
- 0x37, 0x13, 0xc3, 0x36, 0x19, 0x72, 0xab, 0x0f, 0xbf, 0xb0, 0x8f, 0xba,
- 0x58, 0xee, 0xf6, 0xd0, 0xed, 0xc6, 0x1e, 0xc1, 0x71, 0xae, 0xea, 0x52,
- 0x2c, 0xe1, 0xf9, 0xf9, 0x1d, 0xdb, 0x0e, 0xd3, 0x3c, 0xfd, 0xb1, 0x96,
- 0x44, 0x3f, 0xe6, 0xed, 0xb3, 0xbd, 0xdd, 0xd8, 0x35, 0xb7, 0x1a, 0x07,
- 0x26, 0xdc, 0x48, 0xd6, 0x0b, 0xd4, 0xe9, 0xe1, 0xf2, 0xdd, 0x58, 0x0d,
- 0x6b, 0x86, 0xdf, 0xeb, 0xc6, 0xe1, 0xb9, 0xca, 0xf7, 0xec, 0xa5, 0xef,
- 0x8b, 0xf3, 0x5d, 0x20, 0x9d, 0xb2, 0x3c, 0x39, 0x4e, 0x92, 0x0a, 0xcc,
- 0x16, 0x9c, 0x98, 0x08, 0x90, 0x6e, 0x3b, 0x85, 0xeb, 0xf8, 0x32, 0xbf,
- 0xf7, 0x11, 0x1b, 0xa7, 0x0c, 0xd2, 0x73, 0x76, 0xa3, 0xf0, 0x1e, 0xef,
- 0x12, 0xee, 0xe2, 0x16, 0x51, 0x35, 0xfd, 0x2d, 0xa1, 0x1c, 0x4f, 0x89,
- 0xea, 0x62, 0x2b, 0xc9, 0xbe, 0x4f, 0x78, 0x8e, 0x6b, 0xa1, 0x90, 0xf8,
- 0x03, 0xd2, 0x67, 0xaf, 0x90, 0x8b, 0x50, 0x25, 0x73, 0x50, 0x48, 0x45,
- 0x9a, 0xc3, 0xb1, 0x21, 0x5e, 0x27, 0x48, 0x7a, 0x83, 0x25, 0x9b, 0x03,
- 0xd8, 0x4a, 0x39, 0xe2, 0xa6, 0xb4, 0x89, 0x03, 0xd9, 0x6a, 0x8a, 0x8f,
- 0xec, 0xf7, 0xf3, 0xb4, 0xae, 0x8e, 0x83, 0x25, 0x58, 0x1e, 0xf3, 0x00,
- 0x56, 0x93, 0xbf, 0x9d, 0x89, 0xb1, 0x2f, 0x02, 0xf9, 0x6c, 0x38, 0x79,
- 0x40, 0xd8, 0x76, 0x75, 0xc4, 0x5e, 0x7e, 0xde, 0x68, 0x89, 0xbe, 0x88,
- 0xff, 0x6d, 0xe7, 0x02, 0x03, 0x88, 0xb6, 0x43, 0xa9, 0x36, 0x77, 0xe3,
- 0xe7, 0x69, 0x28, 0x55, 0xa6, 0x85, 0x53, 0x69, 0xc0, 0x37, 0x32, 0xac,
- 0x7a, 0x41, 0x76, 0x80, 0x70, 0xf0, 0xa0, 0xd0, 0x7a, 0xce, 0x51, 0x3a,
- 0x4b, 0xb4, 0x5b, 0x83, 0x12, 0x28, 0x1e, 0x09, 0xad, 0xef, 0x45, 0xb2,
- 0xc7, 0x3f, 0x10, 0x9a, 0x3a, 0x2f, 0xd8, 0x4f, 0x39, 0x97, 0xec, 0x5e,
- 0xc8, 0x29, 0x16, 0xae, 0xba, 0x2c, 0xa7, 0x0c, 0x13, 0x5d, 0x7b, 0x89,
- 0xae, 0x97, 0x0c, 0x2d, 0x38, 0x0d, 0x7b, 0xf9, 0x36, 0x83, 0x9f, 0x99,
- 0xd8, 0x5d, 0xb2, 0x43, 0x2e, 0x93, 0x65, 0x05, 0x4b, 0x31, 0x7f, 0x65,
- 0x0f, 0xc7, 0x55, 0x92, 0x11, 0x79, 0x5a, 0xe1, 0xcb, 0x72, 0xad, 0x8d,
- 0xe5, 0x34, 0xe6, 0x93, 0x6b, 0xe1, 0x6f, 0x2c, 0xb8, 0x52, 0x35, 0x26,
- 0x7a, 0xee, 0x1b, 0xa1, 0xf8, 0xa4, 0x4b, 0x14, 0x9b, 0xf4, 0xc4, 0xbc,
- 0xf0, 0x25, 0xde, 0x8f, 0x7b, 0x04, 0xc5, 0xa6, 0x54, 0xb5, 0x19, 0xec,
- 0xfe, 0x20, 0xef, 0x21, 0xfd, 0xa2, 0x67, 0x67, 0x21, 0xe1, 0x7a, 0x97,
- 0x6c, 0xac, 0x8a, 0x62, 0x29, 0x0a, 0x4d, 0xdd, 0x17, 0x29, 0xff, 0xdc,
- 0x10, 0xf3, 0xfc, 0xab, 0x2a, 0x53, 0xba, 0xd2, 0x83, 0xfb, 0xaf, 0x99,
- 0x4d, 0xd4, 0x51, 0x3c, 0x57, 0x71, 0x3a, 0xde, 0x85, 0xe1, 0x52, 0x35,
- 0xd9, 0xdf, 0xd3, 0xe5, 0x3d, 0x7a, 0x53, 0xf7, 0xbb, 0xe9, 0xe5, 0xf0,
- 0x99, 0xf8, 0xf4, 0x60, 0xbb, 0xde, 0x75, 0x93, 0x38, 0xd9, 0xe8, 0x41,
- 0x9c, 0x6d, 0x5c, 0x99, 0x4f, 0xe3, 0xe3, 0x46, 0x5d, 0xa7, 0xdc, 0xd1,
- 0x3c, 0x70, 0x41, 0x34, 0x27, 0xce, 0x0b, 0x81, 0xf3, 0xad, 0x02, 0x67,
- 0xae, 0x8e, 0x24, 0xcf, 0xc0, 0x03, 0xdc, 0x9c, 0x20, 0xfb, 0x68, 0x4a,
- 0xc9, 0xa6, 0x82, 0x6d, 0x69, 0xf6, 0x63, 0xb2, 0xeb, 0x19, 0x3c, 0x74,
- 0xc4, 0xe8, 0x86, 0x35, 0xc7, 0xb6, 0xd3, 0x8a, 0x23, 0x73, 0x3d, 0xb0,
- 0x4a, 0x32, 0x72, 0x01, 0x93, 0xae, 0x48, 0xb9, 0xcd, 0xd6, 0xce, 0x5c,
- 0x7e, 0xab, 0xbb, 0xe2, 0xbb, 0x24, 0x83, 0xec, 0xbd, 0x7e, 0x78, 0x59,
- 0xbf, 0xa7, 0x49, 0x36, 0xad, 0x78, 0xba, 0x14, 0xa5, 0x18, 0x67, 0x90,
- 0x6c, 0x74, 0x8a, 0x13, 0x21, 0xb2, 0x2b, 0x05, 0x5b, 0x27, 0xb4, 0xc3,
- 0x14, 0x0f, 0x46, 0x73, 0x68, 0x47, 0x32, 0xa0, 0x52, 0xce, 0x3e, 0xb5,
- 0xe0, 0xfb, 0xdb, 0xe9, 0xaa, 0x59, 0x49, 0xe0, 0x45, 0x09, 0x68, 0x6b,
- 0x34, 0x23, 0xfb, 0x1a, 0x49, 0x0f, 0xf5, 0x45, 0x0f, 0xee, 0x9b, 0x68,
- 0xc0, 0xbd, 0x53, 0x5e, 0xec, 0x98, 0xb0, 0xf1, 0x7e, 0x8c, 0x6d, 0x42,
- 0xeb, 0x23, 0x6f, 0xea, 0xac, 0x21, 0xd9, 0x6e, 0x8e, 0x45, 0x12, 0x1e,
- 0xe1, 0x42, 0x75, 0xb1, 0x87, 0x72, 0x7f, 0x92, 0xfd, 0xc1, 0xa0, 0x39,
- 0x42, 0xbb, 0x8c, 0xaf, 0x23, 0x15, 0x50, 0xe0, 0x2e, 0xfa, 0x28, 0x86,
- 0xb0, 0xff, 0xf2, 0xb3, 0x6f, 0x60, 0x6b, 0x95, 0x0f, 0x72, 0x46, 0xc1,
- 0x28, 0xe5, 0x7d, 0x2c, 0xab, 0x42, 0x57, 0xb3, 0x44, 0x9f, 0x80, 0x7f,
- 0x76, 0xb2, 0xc9, 0x7f, 0x8c, 0xe2, 0xea, 0x9d, 0x59, 0x89, 0xd7, 0x61,
- 0x9c, 0x40, 0x73, 0xab, 0x78, 0x8c, 0x62, 0xf4, 0x03, 0x14, 0x77, 0x4e,
- 0x94, 0xf2, 0x82, 0xe3, 0x88, 0xc3, 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f,
- 0x59, 0xe2, 0x8b, 0xe2, 0xc1, 0x93, 0x59, 0xe6, 0xe3, 0x23, 0xf2, 0xcd,
- 0x04, 0xf1, 0xee, 0xc1, 0x76, 0xa2, 0xf7, 0xfe, 0xa9, 0x1a, 0xdc, 0x43,
- 0xf4, 0x16, 0x0d, 0xad, 0xef, 0x2f, 0x84, 0x8d, 0x7c, 0x4c, 0xb3, 0x76,
- 0x0a, 0x2f, 0xa4, 0x66, 0xdb, 0xee, 0x31, 0x98, 0x67, 0xb2, 0x4f, 0xc9,
- 0xe1, 0x79, 0x5f, 0x92, 0xe4, 0xdf, 0x4f, 0xef, 0x6c, 0x9b, 0xc2, 0xa7,
- 0x12, 0xf1, 0xe4, 0x21, 0x1e, 0x0f, 0x18, 0x5a, 0x62, 0x15, 0xc5, 0xf3,
- 0x73, 0x7a, 0xa4, 0x7c, 0x4e, 0xc6, 0xd7, 0x48, 0x1e, 0x06, 0xcb, 0xa3,
- 0x99, 0xf8, 0xb9, 0x8f, 0x30, 0x8e, 0xdf, 0x64, 0x3e, 0x23, 0xd1, 0x5f,
- 0x10, 0xef, 0x91, 0x62, 0xc0, 0x7f, 0xe6, 0x50, 0x93, 0xff, 0xa5, 0x91,
- 0x0a, 0xfd, 0x3b, 0x89, 0xfe, 0xd9, 0x98, 0x8d, 0x83, 0x44, 0xff, 0x13,
- 0x44, 0x7f, 0x3f, 0xc7, 0xf1, 0x05, 0xfa, 0x4f, 0x94, 0x78, 0xdd, 0x2f,
- 0xe3, 0x61, 0x91, 0xfe, 0x06, 0x6c, 0x9d, 0x5a, 0x94, 0x97, 0x6d, 0xdf,
- 0x66, 0x3c, 0x63, 0xff, 0x1e, 0xc9, 0x6c, 0x79, 0x91, 0xe5, 0xc6, 0xf8,
- 0x2d, 0x72, 0xf8, 0x4e, 0xdc, 0x21, 0xc1, 0xeb, 0xc3, 0x92, 0x22, 0xe7,
- 0x80, 0x10, 0x9e, 0x21, 0xfd, 0x3e, 0x4f, 0x39, 0xec, 0xe9, 0xd2, 0xe5,
- 0x39, 0x8d, 0x75, 0x3d, 0x49, 0x3a, 0xd6, 0x72, 0x16, 0xc5, 0xb4, 0x54,
- 0x29, 0x89, 0x3d, 0x53, 0x48, 0xce, 0x1a, 0x7f, 0x46, 0x81, 0x65, 0x19,
- 0x64, 0xbd, 0x3a, 0xa9, 0xea, 0x5e, 0xdc, 0x3e, 0x13, 0xc0, 0x40, 0x69,
- 0x03, 0xb2, 0x14, 0x67, 0x76, 0x52, 0x5c, 0xfe, 0x30, 0x96, 0xdc, 0xe1,
- 0x47, 0x84, 0xf4, 0x1b, 0xc0, 0xdd, 0xf4, 0xce, 0x81, 0x29, 0xa6, 0x5f,
- 0x5d, 0xd0, 0x73, 0x00, 0x77, 0xd2, 0xbd, 0xbd, 0x53, 0x0a, 0x5e, 0x30,
- 0x8e, 0x10, 0x8e, 0xa9, 0xe0, 0x8a, 0x3b, 0xb2, 0x50, 0xc9, 0x2d, 0x09,
- 0xf7, 0x45, 0xa2, 0x2f, 0xd0, 0xf7, 0xed, 0x25, 0xaf, 0x7f, 0x78, 0x12,
- 0xdf, 0x59, 0x6e, 0xfa, 0xb1, 0x84, 0x30, 0xd8, 0x2d, 0x46, 0xa4, 0xbc,
- 0x9e, 0x30, 0xd3, 0x60, 0x49, 0xc2, 0xb7, 0x67, 0xbc, 0x78, 0x60, 0xe2,
- 0x53, 0xbb, 0x2a, 0xee, 0xc2, 0xcd, 0xcd, 0x5e, 0xdc, 0x3f, 0x93, 0xc4,
- 0xbe, 0x29, 0x84, 0xaa, 0x63, 0x63, 0x14, 0xb3, 0x2b, 0x79, 0xa0, 0x86,
- 0x78, 0xdf, 0x3f, 0xe5, 0xf3, 0xf7, 0x1f, 0x62, 0x19, 0x6c, 0x08, 0x92,
- 0x77, 0x94, 0xab, 0x63, 0x32, 0xb6, 0x1b, 0xf2, 0x92, 0x6a, 0x32, 0xf4,
- 0x23, 0x34, 0xdf, 0x34, 0xe4, 0x57, 0x97, 0x23, 0x72, 0xb8, 0x51, 0x2e,
- 0x8f, 0x2e, 0x41, 0x03, 0x1e, 0x98, 0x4b, 0x62, 0x8c, 0x6c, 0xf4, 0xbe,
- 0x89, 0xe1, 0xef, 0xd4, 0x53, 0xec, 0xf0, 0xb7, 0x69, 0xfd, 0x6f, 0x08,
- 0x13, 0xf9, 0x88, 0x07, 0x3b, 0x67, 0x7c, 0xfe, 0x1d, 0x87, 0xec, 0xf5,
- 0x6c, 0x4f, 0x77, 0xcd, 0x35, 0xe0, 0x9e, 0x29, 0xba, 0x37, 0xc1, 0x36,
- 0x4c, 0xb6, 0x16, 0xa9, 0x26, 0xde, 0xc2, 0x49, 0x0f, 0xe1, 0x24, 0x39,
- 0x56, 0x43, 0xf2, 0xf0, 0xe0, 0x4e, 0xc7, 0x16, 0x54, 0x6c, 0x9f, 0xb2,
- 0xf1, 0x96, 0x11, 0xc5, 0x28, 0xd9, 0xf5, 0xe1, 0x29, 0x6d, 0xbe, 0x93,
- 0x30, 0xce, 0x3b, 0xb2, 0x76, 0xb8, 0x59, 0x4e, 0xa2, 0x61, 0x0d, 0xc5,
- 0xf6, 0x06, 0xdb, 0xbe, 0xa3, 0xad, 0x65, 0xe0, 0xc7, 0x44, 0x73, 0xbd,
- 0xb9, 0x0c, 0xe5, 0x7a, 0x6d, 0x14, 0x68, 0x19, 0xac, 0x92, 0xae, 0xc6,
- 0xd9, 0xa5, 0x1c, 0xff, 0x38, 0x86, 0x07, 0xfc, 0x0d, 0x99, 0x4a, 0x6e,
- 0x6b, 0x28, 0x36, 0xf9, 0xeb, 0x33, 0x41, 0x7f, 0x7d, 0x11, 0xfe, 0xaa,
- 0x22, 0xf0, 0x03, 0x8a, 0x2f, 0x4b, 0xd6, 0xfc, 0xca, 0x4e, 0x35, 0x38,
- 0x38, 0xd0, 0xff, 0xdc, 0xa4, 0x66, 0x95, 0xa1, 0xed, 0xa3, 0x70, 0x89,
- 0x47, 0xe7, 0x5c, 0xfe, 0xe3, 0x14, 0x07, 0x1a, 0xf4, 0x28, 0xf6, 0x92,
- 0x3e, 0x87, 0xc8, 0x16, 0x7e, 0xb1, 0x06, 0xd8, 0x9f, 0x09, 0x87, 0x0c,
- 0xd1, 0x47, 0x13, 0x03, 0xbb, 0x8b, 0x14, 0xeb, 0xa5, 0xdf, 0xa2, 0x40,
- 0xa6, 0x45, 0x29, 0x9d, 0x21, 0x9d, 0x71, 0xc3, 0x5a, 0x5a, 0xd1, 0xc9,
- 0x3d, 0xd9, 0xe7, 0x6d, 0xbf, 0xae, 0xe7, 0x8a, 0xa4, 0xb3, 0x07, 0x4b,
- 0x3e, 0x0c, 0x12, 0x0e, 0x58, 0x42, 0xd8, 0xf1, 0x7e, 0xb2, 0x8b, 0xfb,
- 0x26, 0x64, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x56, 0xc1, 0xa0, 0x0f,
- 0xcc, 0xb0, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x43, 0xb9, 0xfe, 0xe9,
- 0xcf, 0x61, 0x0f, 0x4d, 0xb5, 0x2e, 0xe5, 0xfc, 0x8a, 0x3c, 0x86, 0xa7,
- 0x98, 0x67, 0xed, 0x30, 0xa4, 0x24, 0x6e, 0x30, 0x7e, 0x42, 0xb9, 0x80,
- 0x79, 0x27, 0xec, 0x3b, 0x15, 0xc5, 0xc3, 0x59, 0xc2, 0x32, 0xb1, 0xf7,
- 0xed, 0x3b, 0x03, 0x2c, 0x03, 0xe6, 0x27, 0x2e, 0x73, 0xde, 0x6c, 0x20,
- 0xcc, 0xfb, 0xff, 0x6f, 0x77, 0xb7, 0xdb, 0x29, 0x07, 0xc3, 0x12, 0xb6,
- 0x26, 0x7b, 0x4a, 0x5d, 0xb2, 0x9f, 0xfb, 0xed, 0xb3, 0x01, 0xce, 0xd3,
- 0x0d, 0x48, 0x5d, 0xb2, 0x05, 0xb6, 0x25, 0x2c, 0x37, 0xda, 0x76, 0xdd,
- 0xaf, 0x82, 0xed, 0x21, 0x7a, 0x99, 0x3d, 0xb8, 0x89, 0x26, 0x15, 0x3b,
- 0xe6, 0xd8, 0x7e, 0xed, 0x8f, 0x96, 0x9b, 0xff, 0x40, 0x39, 0x42, 0x3f,
- 0xfc, 0x13, 0xdc, 0x48, 0xf7, 0x03, 0xf8, 0x36, 0xf9, 0xd1, 0xdd, 0xc4,
- 0xe7, 0x8e, 0xf6, 0xbb, 0x1d, 0xbf, 0xdd, 0x51, 0xba, 0x8e, 0xee, 0xb3,
- 0xbc, 0x3b, 0xb1, 0x2f, 0x6b, 0x20, 0x9d, 0x2d, 0x3b, 0xf9, 0xc7, 0x65,
- 0xc6, 0xf1, 0x7d, 0x8a, 0xb3, 0xcf, 0x94, 0x18, 0x8b, 0x25, 0x1c, 0x1c,
- 0xf6, 0xbd, 0x52, 0x2b, 0x9e, 0x25, 0x9f, 0x7c, 0x9a, 0x62, 0xee, 0x77,
- 0x1d, 0x7c, 0xe6, 0x12, 0x07, 0xd3, 0x84, 0x45, 0x47, 0x2c, 0xa4, 0xf3,
- 0x21, 0x78, 0x0e, 0x85, 0xf7, 0xed, 0x10, 0xda, 0x0f, 0x48, 0x5e, 0xfe,
- 0xfd, 0xb3, 0x2b, 0x50, 0x7d, 0x48, 0xcb, 0x11, 0xdd, 0xfe, 0x87, 0x67,
- 0x75, 0xc2, 0xd2, 0x41, 0xff, 0xde, 0xbc, 0xea, 0xdf, 0x33, 0x19, 0xf0,
- 0xef, 0x99, 0x6d, 0x20, 0x3f, 0x5a, 0xe6, 0x1f, 0x9e, 0x0d, 0xfa, 0x77,
- 0xa5, 0x9b, 0xfc, 0xbb, 0xf2, 0x6b, 0x10, 0x6a, 0x80, 0xb5, 0x8c, 0x72,
- 0xc4, 0x3d, 0x13, 0xdf, 0x44, 0xae, 0xbe, 0x12, 0xf7, 0x07, 0xc8, 0x36,
- 0xea, 0xc8, 0x0e, 0xaf, 0x91, 0x6e, 0x46, 0x79, 0x69, 0xe5, 0xde, 0xb7,
- 0xe9, 0xde, 0x03, 0x6d, 0xf0, 0xff, 0xa5, 0x13, 0x7b, 0x81, 0x67, 0xc9,
- 0xd6, 0x9e, 0x69, 0xa3, 0x7a, 0xf2, 0x92, 0xad, 0xb9, 0x28, 0xde, 0xda,
- 0xb6, 0xb1, 0x46, 0x20, 0xd8, 0xb6, 0x11, 0x58, 0xb2, 0x58, 0x43, 0x26,
- 0x73, 0xae, 0xb6, 0x24, 0x96, 0xeb, 0x9b, 0x70, 0x44, 0xa5, 0x54, 0xd3,
- 0xf6, 0x35, 0x2c, 0xbc, 0x83, 0x6f, 0x4f, 0x78, 0x90, 0xda, 0xa2, 0x62,
- 0x96, 0x30, 0xca, 0x5d, 0x34, 0xff, 0xca, 0x58, 0x8b, 0x3a, 0x47, 0x7a,
- 0x48, 0xaa, 0x7c, 0x8f, 0x7c, 0xa2, 0x6d, 0x2d, 0xf9, 0x44, 0x65, 0xfd,
- 0xa7, 0x48, 0x5f, 0xa3, 0x73, 0x51, 0xec, 0x29, 0xfd, 0x40, 0xaa, 0xe4,
- 0x17, 0x2d, 0x97, 0xc4, 0x69, 0x67, 0xec, 0x53, 0xd9, 0x37, 0xec, 0x90,
- 0x63, 0x77, 0x02, 0x8f, 0xac, 0x8e, 0xec, 0xfb, 0xef, 0x52, 0x23, 0xf1,
- 0x45, 0xb2, 0xcb, 0x3a, 0xf5, 0x63, 0xdd, 0x15, 0xfa, 0xbf, 0xc5, 0xf7,
- 0x55, 0x96, 0xed, 0xa0, 0xd8, 0x47, 0x75, 0x2a, 0x95, 0x4c, 0x75, 0x4b,
- 0xf4, 0x43, 0x78, 0xba, 0x87, 0xef, 0x05, 0xfc, 0xfb, 0x27, 0x93, 0x52,
- 0x40, 0x87, 0xea, 0x36, 0x3b, 0xc5, 0xfe, 0xd9, 0x65, 0xfe, 0x87, 0x27,
- 0x37, 0x8a, 0x87, 0x67, 0x9b, 0xfc, 0xc3, 0xe9, 0x2e, 0x31, 0x9c, 0xdf,
- 0x22, 0xac, 0xdc, 0xb7, 0x84, 0x35, 0x9b, 0x12, 0x56, 0xbe, 0x8f, 0xae,
- 0xbd, 0x62, 0x32, 0x3f, 0x28, 0xf6, 0xe4, 0x79, 0x7e, 0xd2, 0x15, 0xad,
- 0xf1, 0x3d, 0x8a, 0xbd, 0xcf, 0x52, 0xec, 0x7d, 0x86, 0x62, 0xef, 0xd3,
- 0x64, 0xef, 0xdf, 0xbd, 0x84, 0x6d, 0xd9, 0xc6, 0x93, 0x8c, 0x49, 0xfc,
- 0x7f, 0x51, 0x3c, 0x49, 0xfa, 0x66, 0xd9, 0xfd, 0x27, 0xb2, 0x6d, 0x96,
- 0xc9, 0x03, 0x9c, 0x2b, 0x48, 0x4f, 0x17, 0x1d, 0x5b, 0x7e, 0x64, 0x35,
- 0x63, 0xa8, 0x41, 0xb1, 0x95, 0xe8, 0x4b, 0xba, 0x08, 0xfb, 0xe8, 0x84,
- 0x4b, 0xb2, 0x83, 0xe2, 0x8e, 0x3c, 0xdf, 0x3f, 0x80, 0x9d, 0x54, 0x0b,
- 0x1e, 0x8c, 0x85, 0x7b, 0xb6, 0x11, 0x66, 0xda, 0x4c, 0x98, 0x69, 0x65,
- 0x4c, 0xc1, 0x85, 0xd6, 0x4f, 0x6c, 0x2c, 0x45, 0xf2, 0xde, 0xb8, 0x96,
- 0xcb, 0x55, 0xf2, 0xed, 0x68, 0x06, 0x5c, 0xaf, 0xa3, 0xae, 0x56, 0xd7,
- 0x4e, 0x24, 0x11, 0xde, 0x17, 0x97, 0x60, 0x55, 0x99, 0x6e, 0xdc, 0xe3,
- 0xd4, 0x88, 0x1b, 0x30, 0x31, 0x21, 0xb0, 0xbd, 0x2d, 0xf9, 0x87, 0x6e,
- 0x92, 0xd5, 0x3b, 0xed, 0x08, 0x90, 0x7a, 0x85, 0x42, 0xf5, 0x7c, 0x17,
- 0x49, 0xaf, 0x93, 0x72, 0xee, 0x91, 0xec, 0x5a, 0x34, 0xb6, 0x29, 0xa4,
- 0x43, 0x17, 0x6e, 0x2b, 0xde, 0x40, 0x7a, 0x8c, 0x1c, 0x7e, 0x0e, 0x5e,
- 0xff, 0x0b, 0x93, 0x26, 0x46, 0xb2, 0xf8, 0x8e, 0x8f, 0x6a, 0xb7, 0xbb,
- 0x09, 0x37, 0x7d, 0x97, 0x68, 0xd8, 0xd4, 0x16, 0xe9, 0xa2, 0x1a, 0x5e,
- 0xf5, 0x9a, 0x55, 0x18, 0x6f, 0xf6, 0x43, 0xd5, 0x53, 0xe2, 0x95, 0x7c,
- 0xe4, 0xf0, 0x0e, 0xe9, 0x5b, 0xe2, 0xc7, 0xb3, 0x26, 0x1e, 0x2e, 0xf5,
- 0x89, 0xbf, 0x9c, 0x55, 0x40, 0xba, 0xa1, 0xb8, 0x65, 0xe0, 0x30, 0xd1,
- 0xe5, 0x26, 0x9c, 0xe4, 0xfe, 0x1d, 0x81, 0x2b, 0xf4, 0x24, 0xbe, 0xbd,
- 0x96, 0x7d, 0xa1, 0x12, 0xd3, 0x5c, 0x6b, 0x81, 0x7d, 0x64, 0x93, 0x8d,
- 0x99, 0x4e, 0xb1, 0x9c, 0xfe, 0xbf, 0x40, 0x79, 0x2d, 0x29, 0x75, 0x89,
- 0x46, 0xc2, 0xa4, 0x4b, 0xa7, 0x7b, 0xc5, 0x92, 0x22, 0x63, 0x50, 0xa8,
- 0x4b, 0x49, 0x46, 0x4b, 0x8b, 0xe7, 0xe5, 0x0a, 0xf6, 0x77, 0xb3, 0x2d,
- 0x59, 0x3e, 0x53, 0xf1, 0x1f, 0xa4, 0xd8, 0xbe, 0x23, 0xd6, 0x45, 0xf8,
- 0x98, 0xef, 0x0f, 0x8a, 0x11, 0x92, 0x63, 0xce, 0xed, 0xd8, 0x8e, 0xff,
- 0xc8, 0x24, 0xdc, 0x8d, 0x26, 0x42, 0x55, 0x94, 0x3b, 0xfe, 0xe7, 0x9a,
- 0x88, 0xf5, 0x9c, 0xd4, 0x2d, 0x46, 0xf3, 0x01, 0xff, 0xe1, 0x49, 0xce,
- 0x33, 0x9d, 0xe2, 0x30, 0xe9, 0x3c, 0x4b, 0x3a, 0xcf, 0x92, 0xce, 0x33,
- 0xa4, 0xf3, 0xcc, 0x97, 0xe8, 0x7c, 0x2f, 0xe9, 0x7c, 0x57, 0xfe, 0x63,
- 0x47, 0x87, 0x2e, 0xd3, 0x44, 0x96, 0xf2, 0xf2, 0x78, 0x73, 0x85, 0xbf,
- 0x0f, 0x49, 0x16, 0xa7, 0x62, 0x5f, 0x77, 0xc1, 0x6b, 0x52, 0x6c, 0xed,
- 0xa6, 0x77, 0xbe, 0xb2, 0x60, 0xe3, 0xaa, 0x7f, 0x6c, 0xb2, 0x53, 0x8c,
- 0x91, 0xdf, 0x8d, 0xd3, 0xfc, 0xe3, 0xe4, 0x77, 0xc3, 0xe9, 0x7f, 0x8e,
- 0xdd, 0xb0, 0xdd, 0xc1, 0xf2, 0x52, 0xde, 0xaa, 0x21, 0xbb, 0x74, 0x99,
- 0x6c, 0x43, 0x5b, 0x44, 0xf2, 0xe8, 0xb7, 0x44, 0xf2, 0x58, 0x4a, 0x24,
- 0x0b, 0x7d, 0x74, 0xed, 0x15, 0x37, 0x39, 0xf5, 0xe7, 0xa0, 0xe8, 0x2c,
- 0x04, 0xfc, 0x53, 0xb4, 0xce, 0x14, 0xf1, 0xf1, 0x08, 0xad, 0xf3, 0x88,
- 0x63, 0xbb, 0xe3, 0x2e, 0xce, 0xff, 0xcf, 0x67, 0xd9, 0xce, 0xd8, 0xbe,
- 0xde, 0x25, 0xda, 0xd9, 0x37, 0x2e, 0xf5, 0x76, 0xe8, 0xaf, 0x5d, 0x86,
- 0xbe, 0xc3, 0x55, 0xe1, 0x89, 0x73, 0x3f, 0xe7, 0x7a, 0x8e, 0xc3, 0xaa,
- 0x53, 0x03, 0x3e, 0x73, 0x09, 0x03, 0x30, 0x1e, 0x80, 0xb2, 0xc4, 0x7c,
- 0xb0, 0xe3, 0xdb, 0xcd, 0xff, 0x8b, 0xe6, 0x1b, 0x80, 0xb1, 0x16, 0x4a,
- 0xc0, 0xfc, 0x65, 0xc7, 0x64, 0x33, 0xc5, 0x69, 0x9a, 0x53, 0xc9, 0x00,
- 0x7a, 0x46, 0x60, 0x57, 0x42, 0x10, 0x8e, 0x5d, 0x46, 0x7e, 0xc9, 0xf4,
- 0x6b, 0x5d, 0x49, 0x7a, 0xb6, 0x62, 0x04, 0xca, 0x72, 0x73, 0x27, 0xec,
- 0x2c, 0x94, 0x3a, 0xb3, 0x1f, 0x1f, 0x8d, 0x84, 0x83, 0x5d, 0xd0, 0x52,
- 0xe7, 0x64, 0xad, 0x4c, 0xf9, 0x6d, 0x60, 0x97, 0xd0, 0xfa, 0xe7, 0x05,
- 0xf7, 0x87, 0x18, 0xb3, 0xef, 0x44, 0xab, 0x83, 0xdd, 0xfb, 0xd1, 0x92,
- 0x07, 0xd5, 0xdf, 0x84, 0x6b, 0x69, 0xce, 0x97, 0x8c, 0x0f, 0x38, 0x27,
- 0x24, 0x09, 0x0b, 0x7e, 0x61, 0x2e, 0x10, 0x8e, 0xe1, 0x79, 0x78, 0x8e,
- 0xb0, 0xda, 0x4f, 0xf3, 0xbe, 0x25, 0xb7, 0x0c, 0x0c, 0x0b, 0x2d, 0xf1,
- 0xc5, 0xf9, 0x56, 0xe6, 0x21, 0x56, 0x66, 0x2c, 0xbb, 0x46, 0xf7, 0x32,
- 0x1e, 0x92, 0xce, 0xeb, 0x7a, 0xf2, 0x35, 0x84, 0xb0, 0x92, 0xea, 0xe3,
- 0x68, 0x91, 0x79, 0x18, 0xc2, 0x8b, 0x86, 0xd6, 0x43, 0x55, 0x28, 0xd5,
- 0x2b, 0x9d, 0x38, 0x40, 0xb1, 0xf7, 0xe1, 0x12, 0xf7, 0xb7, 0x06, 0xc5,
- 0xaa, 0x11, 0xf2, 0x4b, 0xc7, 0x9e, 0xa0, 0x34, 0x9a, 0x0f, 0xe2, 0x3a,
- 0x5a, 0xdf, 0x4f, 0x35, 0xcf, 0xeb, 0xb4, 0xbe, 0x94, 0xd1, 0x06, 0x69,
- 0xfd, 0xd4, 0x1b, 0x22, 0x3c, 0x4f, 0x7c, 0xf5, 0xad, 0x97, 0x5b, 0xfa,
- 0x87, 0x84, 0x96, 0x24, 0xd2, 0xc9, 0x8f, 0x79, 0xed, 0x07, 0x99, 0x17,
- 0xba, 0x52, 0x7d, 0x43, 0x76, 0xd4, 0x5c, 0x50, 0x44, 0x64, 0x6c, 0x03,
- 0xf6, 0xcc, 0x6c, 0xc0, 0x6e, 0xf2, 0xc7, 0xfd, 0x46, 0x1d, 0x42, 0xf5,
- 0xa8, 0xad, 0xd3, 0x31, 0x7f, 0x4e, 0x17, 0xf2, 0x8e, 0xd6, 0x26, 0xb2,
- 0xe3, 0x93, 0x8d, 0xd5, 0xf8, 0xd8, 0xde, 0xa6, 0x6f, 0xe8, 0xa2, 0x88,
- 0x78, 0x9d, 0x07, 0x87, 0x64, 0xf2, 0xef, 0x37, 0x7f, 0x41, 0x01, 0xd5,
- 0x63, 0x32, 0x6e, 0x4b, 0x88, 0x8b, 0xf9, 0x53, 0xae, 0x8a, 0x1f, 0x34,
- 0xe3, 0x23, 0x15, 0x75, 0x41, 0x7d, 0x15, 0xe6, 0x55, 0x85, 0xe2, 0x85,
- 0xe5, 0xd4, 0x62, 0x37, 0x8e, 0xf6, 0xa0, 0x91, 0xea, 0xe2, 0xdb, 0x62,
- 0xbf, 0xb0, 0x3f, 0xb9, 0x82, 0xdf, 0xfb, 0x23, 0x4f, 0x25, 0x76, 0x7e,
- 0xd9, 0x1c, 0x71, 0x8a, 0x37, 0x2d, 0x54, 0xc7, 0xd6, 0x50, 0x90, 0xee,
- 0xa2, 0x7c, 0xa4, 0xf5, 0xa5, 0xa9, 0x0e, 0xed, 0x8f, 0xb4, 0x18, 0xb2,
- 0xa8, 0x42, 0x39, 0x10, 0x1e, 0xd8, 0x86, 0xe4, 0x5d, 0xfe, 0x05, 0x3a,
- 0x9e, 0x11, 0x2b, 0xdc, 0xf4, 0x1e, 0xcf, 0x73, 0x99, 0x3d, 0xe5, 0xc9,
- 0x9e, 0xf8, 0x39, 0xff, 0x7f, 0xe9, 0xb9, 0xf2, 0x15, 0xf3, 0x97, 0xe6,
- 0xbf, 0x5f, 0xf9, 0x65, 0xf7, 0x03, 0xeb, 0x7e, 0xfd, 0xfe, 0xff, 0xad,
- 0x9e, 0x2f, 0xd7, 0xbb, 0x1c, 0xcc, 0x90, 0x94, 0xb8, 0x7f, 0xe9, 0x32,
- 0x7d, 0x1d, 0xbb, 0xf5, 0xdf, 0xa0, 0x98, 0xc6, 0xfd, 0x0b, 0xce, 0xd3,
- 0x67, 0x9d, 0xfe, 0xc5, 0xf3, 0x9f, 0xc3, 0xac, 0x1c, 0x5b, 0x3c, 0xa2,
- 0x66, 0xdc, 0xb2, 0x1b, 0xf4, 0xdb, 0xa8, 0xae, 0x19, 0xc2, 0xb6, 0x98,
- 0x81, 0xb1, 0xac, 0xd6, 0x73, 0x33, 0xf4, 0xe4, 0x16, 0x41, 0x13, 0x15,
- 0x3d, 0x42, 0x1e, 0x5f, 0x78, 0x66, 0x58, 0x54, 0xab, 0x95, 0x51, 0x4d,
- 0xb1, 0xc9, 0xa5, 0xab, 0x0a, 0x8a, 0x01, 0xc5, 0x55, 0x0c, 0x2a, 0x55,
- 0xc5, 0x26, 0xa5, 0x9a, 0xc6, 0xf9, 0xc6, 0xb5, 0xf9, 0x9b, 0x31, 0x84,
- 0xf9, 0x35, 0x5e, 0xab, 0xd1, 0xd4, 0xd4, 0x46, 0x79, 0x08, 0xbb, 0x63,
- 0xfc, 0x6e, 0x27, 0xd5, 0x6c, 0x10, 0xf5, 0x19, 0x42, 0xc6, 0xa6, 0xc0,
- 0x9e, 0x76, 0x6d, 0x70, 0x85, 0xa4, 0x77, 0xfd, 0xad, 0x70, 0x29, 0x9e,
- 0x22, 0x84, 0x3f, 0x23, 0xe1, 0x70, 0x3b, 0x3c, 0x9e, 0xb5, 0x5a, 0xff,
- 0x49, 0x31, 0x88, 0x27, 0x62, 0x91, 0x9e, 0xed, 0x22, 0xa4, 0x78, 0xe9,
- 0x99, 0x3b, 0x43, 0xf1, 0x37, 0x63, 0x79, 0xdc, 0x6b, 0xb5, 0xa0, 0x24,
- 0x92, 0xd8, 0xa6, 0xeb, 0xc6, 0x38, 0x14, 0x5a, 0x13, 0xa2, 0x3a, 0xa3,
- 0xcd, 0xbf, 0x45, 0x98, 0xea, 0x93, 0x95, 0x83, 0x68, 0x5b, 0x13, 0xd9,
- 0xd7, 0x27, 0xe9, 0x0a, 0x61, 0x3d, 0xe1, 0xca, 0xf8, 0x70, 0xcd, 0xa1,
- 0xc5, 0x7e, 0x8e, 0x6d, 0x7f, 0x18, 0x2b, 0x93, 0x5e, 0xa0, 0xd4, 0x16,
- 0xa3, 0x8a, 0x8f, 0x70, 0x7d, 0xcb, 0x21, 0xc6, 0x59, 0xb6, 0xbd, 0x23,
- 0x56, 0xfe, 0x9a, 0x17, 0xad, 0xc4, 0x63, 0x0f, 0x66, 0xd2, 0x8c, 0xbb,
- 0x4c, 0x4c, 0x53, 0x4d, 0xa4, 0x8f, 0x34, 0xe1, 0x38, 0xc5, 0xa1, 0xb9,
- 0x34, 0xf7, 0x7d, 0xfa, 0x49, 0xc6, 0x7d, 0x44, 0x7f, 0x2f, 0xd5, 0xc1,
- 0x29, 0x8a, 0x5f, 0x2c, 0xe3, 0x6d, 0x64, 0xf7, 0x50, 0xbc, 0x66, 0xac,
- 0xe3, 0xc6, 0x31, 0x28, 0x1e, 0x73, 0x55, 0xc7, 0x55, 0x87, 0x50, 0x4f,
- 0x79, 0xdf, 0xa4, 0x8a, 0x07, 0xd1, 0x48, 0xc4, 0xb8, 0x80, 0x48, 0xf0,
- 0x25, 0xd2, 0xc7, 0xb0, 0x0e, 0xec, 0x72, 0x6a, 0x6c, 0x17, 0xac, 0x3c,
- 0xd7, 0xcf, 0xf0, 0x54, 0xb7, 0xd7, 0xe3, 0xfc, 0xa8, 0xcb, 0xe9, 0x1d,
- 0x59, 0x54, 0xff, 0xbc, 0x60, 0x68, 0xa9, 0x1c, 0xbd, 0xb7, 0x55, 0xfd,
- 0xd9, 0xde, 0x9a, 0x38, 0x14, 0x8a, 0x69, 0x64, 0x7b, 0x7f, 0xe2, 0x7d,
- 0x8b, 0x6c, 0xf4, 0x96, 0xc9, 0x3f, 0xf5, 0x7e, 0x14, 0xcf, 0x79, 0x3f,
- 0x88, 0xdb, 0x76, 0x82, 0xf0, 0x68, 0x1f, 0xd5, 0xdc, 0x1f, 0x8e, 0x58,
- 0xde, 0x0b, 0x71, 0xee, 0xff, 0xba, 0xf0, 0xdb, 0xf4, 0xfd, 0xb1, 0x11,
- 0x05, 0x9b, 0x0b, 0x8d, 0x70, 0x8f, 0xc9, 0x98, 0x31, 0xae, 0xc7, 0x36,
- 0x55, 0xc2, 0x1d, 0xd1, 0x27, 0xc9, 0x26, 0x25, 0x1a, 0x73, 0x90, 0xbe,
- 0x73, 0x2f, 0xeb, 0x11, 0x6c, 0x57, 0x67, 0xbd, 0xe7, 0xe3, 0x4c, 0x6f,
- 0x88, 0xe9, 0x55, 0x24, 0xfd, 0xeb, 0xd8, 0x7a, 0x33, 0xd7, 0x56, 0xce,
- 0xc7, 0xf3, 0x52, 0x7b, 0x03, 0x8e, 0x8f, 0x36, 0xe2, 0xb9, 0x51, 0xcb,
- 0xf3, 0x5a, 0x7b, 0x14, 0xfd, 0x23, 0x36, 0x5e, 0x36, 0xac, 0xc1, 0x6a,
- 0xb2, 0xf3, 0x04, 0xd5, 0x57, 0xe1, 0x35, 0xdc, 0x43, 0x40, 0x44, 0x46,
- 0x64, 0x80, 0x40, 0xe6, 0xad, 0x14, 0xba, 0x52, 0xb5, 0x54, 0xa7, 0x9d,
- 0x11, 0x76, 0xd5, 0x5d, 0xed, 0x2e, 0xa2, 0x01, 0xd8, 0x58, 0x68, 0x25,
- 0xb9, 0x45, 0xb1, 0x39, 0xa2, 0x60, 0x53, 0xc1, 0xc0, 0x73, 0x69, 0x1f,
- 0x6e, 0x29, 0xc4, 0x09, 0x7b, 0xab, 0x44, 0x7b, 0x02, 0xa5, 0x74, 0x00,
- 0xdf, 0x28, 0x34, 0x91, 0xbc, 0x83, 0xb8, 0xbe, 0x10, 0xc2, 0x89, 0x34,
- 0xe7, 0x6f, 0xd3, 0xb3, 0x35, 0xde, 0x84, 0xae, 0x82, 0x8e, 0xd9, 0x34,
- 0x3c, 0xf7, 0xc5, 0x43, 0xe8, 0x2c, 0x44, 0x51, 0x20, 0x0c, 0xf7, 0x75,
- 0x9a, 0xf3, 0x16, 0xd2, 0x49, 0x6b, 0x21, 0x80, 0x15, 0x11, 0xe0, 0xba,
- 0x82, 0x4f, 0x0c, 0x12, 0xb6, 0x4a, 0x14, 0x1a, 0x70, 0x61, 0x8c, 0xed,
- 0xdc, 0xe8, 0xd8, 0x3d, 0xaa, 0x22, 0x54, 0xc0, 0x35, 0x0a, 0xb0, 0x93,
- 0xaa, 0xc3, 0x54, 0x81, 0xe8, 0x3d, 0xd0, 0x5e, 0xe9, 0xdd, 0xae, 0x2a,
- 0x7c, 0xc6, 0x6f, 0x1d, 0xe9, 0xe9, 0xa3, 0x43, 0xb3, 0xde, 0x4f, 0xe2,
- 0x1c, 0x9b, 0x9a, 0x3a, 0x5e, 0x3f, 0x04, 0x44, 0xa7, 0x98, 0x37, 0x27,
- 0x36, 0x72, 0x3c, 0x6c, 0x55, 0xf0, 0xb7, 0x36, 0xd5, 0xa0, 0xa1, 0x19,
- 0xde, 0x23, 0xd0, 0x7d, 0x44, 0x87, 0x8a, 0x24, 0xad, 0x7d, 0x53, 0xe1,
- 0x7b, 0xf6, 0xd6, 0xa5, 0x41, 0xdc, 0x18, 0xa9, 0xc8, 0xea, 0x0c, 0xe9,
- 0x70, 0x7a, 0xac, 0x11, 0x73, 0x44, 0x83, 0xdb, 0x6c, 0xee, 0x38, 0x36,
- 0x69, 0x63, 0xa3, 0x61, 0x79, 0x5f, 0x6b, 0x5f, 0x85, 0x7b, 0x0f, 0x0d,
- 0x9f, 0xae, 0x22, 0xbd, 0xce, 0x1b, 0xb7, 0xe2, 0xe1, 0x29, 0x5c, 0xd9,
- 0x08, 0x3c, 0x14, 0x04, 0xf7, 0xaa, 0xb5, 0xd0, 0x09, 0x44, 0xba, 0xee,
- 0x43, 0x44, 0xd5, 0x85, 0x66, 0xbc, 0x2c, 0x90, 0xac, 0x31, 0x23, 0xa7,
- 0x6f, 0x02, 0x5e, 0xac, 0x22, 0x0f, 0xbe, 0xa5, 0xe0, 0x22, 0x19, 0x05,
- 0x51, 0x1a, 0xab, 0x82, 0x4c, 0x7e, 0x72, 0x51, 0xc7, 0xc6, 0x3a, 0x92,
- 0xb5, 0x2c, 0x14, 0xd2, 0x73, 0x2b, 0x8e, 0x8d, 0x2c, 0xca, 0xca, 0x87,
- 0x1b, 0x48, 0x86, 0x4f, 0x8c, 0xd8, 0x43, 0x7a, 0x2c, 0x40, 0xb2, 0x56,
- 0x89, 0xbe, 0x45, 0x39, 0xb1, 0xfc, 0x16, 0xe5, 0x74, 0x2b, 0x76, 0xcf,
- 0xb1, 0xdc, 0xfe, 0x5f, 0xe4, 0x35, 0xeb, 0xd8, 0xdd, 0xc6, 0xc9, 0x28,
- 0x1a, 0x0f, 0x5d, 0x92, 0x1d, 0xd3, 0xf7, 0x10, 0xf1, 0xf1, 0x1d, 0xff,
- 0xb5, 0x91, 0xfe, 0xf7, 0x84, 0x8f, 0xe8, 0x51, 0x49, 0x37, 0xef, 0xb9,
- 0x19, 0xbb, 0x93, 0x4c, 0x2e, 0xc9, 0x38, 0x48, 0x32, 0x0e, 0x4e, 0xb1,
- 0xac, 0x9b, 0x48, 0xd6, 0xc0, 0xeb, 0x84, 0xcb, 0xae, 0x8b, 0x45, 0x51,
- 0x7b, 0x48, 0x4b, 0x36, 0xca, 0xe1, 0x44, 0x9d, 0x00, 0x55, 0x25, 0x68,
- 0xad, 0xc5, 0x87, 0x2c, 0x67, 0x83, 0xe4, 0xfc, 0x9d, 0x61, 0xe2, 0x67,
- 0x03, 0xcd, 0xb7, 0x91, 0xe4, 0x9c, 0x24, 0xfe, 0x6f, 0x72, 0xe6, 0x6d,
- 0xa2, 0x79, 0x7b, 0xa9, 0xf6, 0x98, 0xf5, 0x5e, 0x24, 0x7a, 0xa2, 0x9f,
- 0xd1, 0x42, 0x68, 0x3c, 0x12, 0x7c, 0x8f, 0x6a, 0xec, 0xeb, 0x9d, 0x71,
- 0x2a, 0x8d, 0x63, 0xda, 0x7f, 0x5c, 0x2d, 0xe9, 0x5f, 0xd6, 0x67, 0xfe,
- 0x16, 0xb8, 0xe7, 0x60, 0xa1, 0x8f, 0xea, 0x88, 0x5e, 0xaa, 0x95, 0x14,
- 0xca, 0x6d, 0x16, 0xbe, 0x1b, 0xd7, 0xa2, 0xf5, 0x82, 0xe3, 0x9f, 0x45,
- 0x7e, 0x58, 0xa6, 0x3a, 0x29, 0x1c, 0x9a, 0x43, 0x50, 0x91, 0x8a, 0x0a,
- 0xe1, 0xc1, 0x26, 0x45, 0x2e, 0x92, 0xbf, 0x06, 0xfb, 0x08, 0x4f, 0xbb,
- 0xf0, 0x52, 0xde, 0x85, 0x57, 0xd2, 0xbd, 0xd8, 0x5f, 0xf2, 0x10, 0x6e,
- 0xb6, 0x3c, 0xae, 0xb5, 0x7f, 0x56, 0x55, 0x89, 0xc9, 0x2b, 0xd1, 0x3d,
- 0xfe, 0x20, 0x6a, 0x32, 0xae, 0x1e, 0xca, 0xa7, 0xc6, 0x4d, 0x24, 0x97,
- 0x8d, 0x45, 0x7e, 0xde, 0x84, 0x4c, 0x3a, 0x45, 0x18, 0x28, 0x4c, 0x35,
- 0x90, 0x0b, 0xb9, 0xc6, 0x26, 0xa7, 0x9f, 0x3b, 0x4a, 0xf7, 0x46, 0x4b,
- 0x5f, 0xec, 0x33, 0xdf, 0xba, 0xd0, 0x5f, 0xee, 0xc7, 0xde, 0x6c, 0x1f,
- 0x61, 0xd3, 0x5e, 0x8a, 0xef, 0x15, 0x1a, 0x67, 0xe3, 0x3d, 0xd8, 0x9b,
- 0x37, 0x2f, 0xc5, 0x8f, 0x69, 0x27, 0x7e, 0x0c, 0xa0, 0xba, 0x9d, 0xf7,
- 0xad, 0x7a, 0x71, 0x7b, 0x1a, 0x78, 0x37, 0xcd, 0x7d, 0x44, 0xc2, 0x14,
- 0x94, 0x0f, 0x0e, 0x1a, 0x9c, 0x43, 0x7b, 0xb1, 0x22, 0x6f, 0x23, 0x6f,
- 0xd8, 0x38, 0x6d, 0xe8, 0x94, 0xa3, 0x39, 0x57, 0x0f, 0x0a, 0x9d, 0xf2,
- 0xb3, 0xe5, 0x1a, 0x40, 0xa4, 0x9d, 0x75, 0xf4, 0xe0, 0xc2, 0xfe, 0xd3,
- 0x80, 0xb3, 0xff, 0x34, 0x97, 0x96, 0xf1, 0x04, 0x29, 0xe2, 0xb9, 0x6c,
- 0x38, 0xf4, 0x2e, 0xec, 0x21, 0xd9, 0xd4, 0x12, 0x2e, 0x99, 0xf7, 0x65,
- 0x78, 0x5f, 0x4a, 0xef, 0x59, 0x21, 0x6b, 0x46, 0x51, 0xb4, 0xf4, 0xbd,
- 0x8d, 0xf2, 0x26, 0x05, 0x5a, 0xe8, 0x35, 0x44, 0xa2, 0x5d, 0xbc, 0xf7,
- 0x50, 0xaa, 0xe4, 0xee, 0x95, 0x0b, 0xb9, 0x5b, 0xcf, 0x7b, 0x45, 0x78,
- 0x4c, 0x42, 0x6e, 0xc6, 0xb6, 0x24, 0xb2, 0xdf, 0x19, 0x9a, 0xf3, 0x07,
- 0xd9, 0x21, 0x64, 0x63, 0xb6, 0x7d, 0x4b, 0x5c, 0xef, 0x6f, 0x94, 0xf1,
- 0xfb, 0x94, 0xc9, 0x41, 0x36, 0x9f, 0x22, 0x5f, 0x0b, 0xed, 0x68, 0xb7,
- 0xec, 0x2a, 0xa7, 0xae, 0xe0, 0xbe, 0x64, 0xb7, 0x68, 0x2d, 0xf4, 0x8a,
- 0x55, 0x84, 0xdd, 0x42, 0xc7, 0xb6, 0x88, 0xe6, 0xa3, 0x15, 0xec, 0x16,
- 0x29, 0x7c, 0xd6, 0x3b, 0xbd, 0x31, 0x6d, 0x23, 0x4d, 0x7c, 0x3d, 0xf1,
- 0x6b, 0x7c, 0xb1, 0x2e, 0x06, 0x70, 0x55, 0x3b, 0xfb, 0xe2, 0x83, 0x38,
- 0x96, 0x66, 0x3b, 0x1f, 0xc0, 0x6e, 0x92, 0xcf, 0xea, 0x11, 0xde, 0x07,
- 0xd3, 0x4e, 0x0f, 0x23, 0xdc, 0xff, 0xaa, 0xd0, 0xca, 0x05, 0xb4, 0x18,
- 0xb5, 0x32, 0xc7, 0x57, 0x6d, 0xb0, 0x59, 0xae, 0xd0, 0x9f, 0xc8, 0x83,
- 0xe2, 0x69, 0x85, 0x87, 0x6b, 0xf2, 0x2b, 0xc8, 0x56, 0x2d, 0xcf, 0xc5,
- 0x78, 0xcb, 0x40, 0x0d, 0x36, 0x8a, 0x0f, 0x66, 0x43, 0xf0, 0x1e, 0x4a,
- 0x2e, 0xf5, 0xa3, 0x53, 0xbc, 0xeb, 0xd4, 0x8b, 0x5d, 0xe2, 0x7c, 0xbe,
- 0x47, 0xbc, 0x9f, 0xeb, 0x46, 0x64, 0xec, 0x1e, 0xf1, 0x4e, 0x8e, 0xe9,
- 0xec, 0x13, 0x67, 0x67, 0xb9, 0x3f, 0x6a, 0x63, 0xb7, 0xc1, 0xbd, 0xd1,
- 0xa5, 0xd5, 0xf0, 0xdb, 0x38, 0x66, 0xb0, 0x3e, 0xb9, 0x4f, 0x58, 0xe9,
- 0x2f, 0x6d, 0x8c, 0x8f, 0xda, 0x2e, 0x9d, 0x7b, 0xc4, 0x41, 0x87, 0xdf,
- 0x19, 0xc2, 0xd1, 0xb3, 0xb9, 0x5e, 0x71, 0x3c, 0x5f, 0xe1, 0x75, 0x3a,
- 0xcf, 0xf6, 0xab, 0x90, 0x8e, 0xbf, 0x98, 0xa7, 0x2d, 0xa8, 0xed, 0x41,
- 0x54, 0x39, 0xfd, 0x28, 0x1b, 0xe3, 0x46, 0x24, 0xf4, 0x32, 0x82, 0x70,
- 0x15, 0xd9, 0xb6, 0x6d, 0x3c, 0x65, 0xb8, 0x21, 0x8f, 0x2b, 0x24, 0x23,
- 0xb2, 0x25, 0xbf, 0x1b, 0xd2, 0x34, 0xd7, 0x06, 0xeb, 0xab, 0xb9, 0x4f,
- 0x11, 0x92, 0xf8, 0xff, 0x2f, 0xda, 0x9c, 0x9b, 0xf2, 0x01, 0xf7, 0xd5,
- 0xdf, 0xac, 0xaa, 0xd8, 0x5e, 0xa5, 0xb7, 0xeb, 0x31, 0xb9, 0xf7, 0xed,
- 0xac, 0xe7, 0x59, 0xd9, 0xee, 0xc1, 0x3b, 0xa3, 0x55, 0xdc, 0xa2, 0x50,
- 0x6a, 0x28, 0xbe, 0xdd, 0x7d, 0xc8, 0xa6, 0xdc, 0x02, 0x4f, 0xb4, 0xfd,
- 0x4d, 0xfb, 0x00, 0xe5, 0x1d, 0xb7, 0x9e, 0xa0, 0x7c, 0xc5, 0x7b, 0x2d,
- 0xb7, 0x62, 0x7e, 0xd2, 0x25, 0xa9, 0x26, 0xe2, 0x14, 0xf3, 0xec, 0xba,
- 0x35, 0x91, 0x81, 0x8f, 0xc9, 0x36, 0x32, 0xc4, 0xd3, 0x07, 0xa3, 0x21,
- 0xe4, 0xa9, 0x0e, 0xb3, 0x9c, 0x9a, 0xe3, 0xb7, 0x71, 0x6e, 0x54, 0x16,
- 0x3e, 0x13, 0xf2, 0x70, 0xbb, 0x8d, 0x21, 0x23, 0x72, 0xfa, 0x2d, 0x59,
- 0xa1, 0x79, 0x5c, 0x78, 0x34, 0x5f, 0x0f, 0x3f, 0xc5, 0x52, 0x69, 0x6c,
- 0x38, 0xe5, 0xa6, 0xb8, 0xf9, 0xe3, 0xd8, 0x70, 0x50, 0xa5, 0xeb, 0x6d,
- 0x06, 0x4e, 0x11, 0xb4, 0xf9, 0xd1, 0x72, 0xf0, 0x1e, 0x60, 0x64, 0xe0,
- 0xbd, 0x4a, 0xbc, 0xb4, 0x5e, 0x13, 0x6f, 0xda, 0xa3, 0xf9, 0x06, 0xc8,
- 0x63, 0x71, 0x7c, 0x92, 0xf6, 0x89, 0xf5, 0x23, 0xbc, 0xd7, 0xa7, 0x95,
- 0xbb, 0x11, 0x1e, 0x58, 0x2f, 0x63, 0x28, 0x88, 0x48, 0xdf, 0x79, 0xaa,
- 0x03, 0x5f, 0x8a, 0x59, 0xfd, 0x3e, 0x8a, 0xb7, 0xdb, 0x09, 0x6b, 0x3e,
- 0x2e, 0x42, 0x94, 0x9f, 0x58, 0x5e, 0x51, 0xa8, 0x11, 0x85, 0xe4, 0xc8,
- 0xfb, 0x41, 0x16, 0xde, 0x76, 0x64, 0xe6, 0xc1, 0xde, 0x1c, 0xd9, 0x89,
- 0xf4, 0xc5, 0xbe, 0xfd, 0x1f, 0x55, 0xc3, 0xdb, 0xc0, 0x72, 0x5a, 0xe8,
- 0xfb, 0x2d, 0xe2, 0x7d, 0x96, 0x11, 0x63, 0xfe, 0x4a, 0x3d, 0x50, 0x65,
- 0xd6, 0x88, 0x17, 0x46, 0x59, 0x2f, 0x36, 0x9e, 0x36, 0x0c, 0xa6, 0x85,
- 0xea, 0xd6, 0xdf, 0x27, 0x8c, 0xaf, 0x59, 0x0c, 0x95, 0x5f, 0x8a, 0x2b,
- 0x38, 0x31, 0x8a, 0xdf, 0x52, 0x20, 0x37, 0x57, 0xe3, 0x08, 0x15, 0x13,
- 0x2c, 0x3f, 0xb6, 0x37, 0xa3, 0x23, 0x92, 0x83, 0x55, 0x6b, 0x76, 0x21,
- 0xe7, 0xd8, 0x79, 0x8d, 0xb8, 0x9f, 0x64, 0x16, 0x69, 0x23, 0x8c, 0xa9,
- 0x72, 0x2f, 0xc5, 0xa2, 0x58, 0xaf, 0xe0, 0xb6, 0x51, 0xbc, 0xbe, 0x1c,
- 0xf2, 0xa9, 0x46, 0x1c, 0x03, 0xaa, 0x59, 0x9f, 0xfc, 0x3e, 0xe9, 0xce,
- 0xcf, 0xb8, 0x8e, 0xc7, 0xd5, 0x88, 0x1d, 0x63, 0x49, 0x6c, 0x8e, 0xc9,
- 0x84, 0x93, 0xfb, 0x08, 0xbf, 0xf5, 0x11, 0x3e, 0xb5, 0xed, 0xb1, 0x08,
- 0xeb, 0x94, 0x75, 0x66, 0x79, 0xc3, 0xed, 0xad, 0xb8, 0x77, 0xb2, 0x1e,
- 0xae, 0xb1, 0x06, 0x54, 0x8f, 0x05, 0xb1, 0x9d, 0xe8, 0x3d, 0x62, 0x70,
- 0xbf, 0xcd, 0x3a, 0x2d, 0x41, 0x2b, 0xaf, 0x97, 0xb5, 0x7e, 0x55, 0xb6,
- 0xf1, 0xa4, 0xa1, 0x19, 0x4f, 0x0a, 0x2f, 0xde, 0xa0, 0x5a, 0xf0, 0xe3,
- 0xd8, 0xad, 0xc8, 0xcc, 0x31, 0x9d, 0xcd, 0x1d, 0x57, 0xcf, 0xf2, 0x35,
- 0xda, 0xd1, 0xec, 0x5c, 0x57, 0x2d, 0x5c, 0x43, 0x1d, 0x21, 0xe7, 0xda,
- 0x44, 0xd7, 0xc5, 0x1e, 0xef, 0x7f, 0x74, 0xf3, 0x35, 0x09, 0xfe, 0x9c,
- 0x76, 0x57, 0x6c, 0xf0, 0xdf, 0xc0, 0x72, 0xfa, 0x0f, 0x1f, 0x2d, 0x8c,
- 0x81, 0x52, 0x4f, 0xbc, 0xc7, 0xc6, 0x65, 0xc4, 0xdb, 0xa8, 0xf8, 0x6d,
- 0x60, 0x7d, 0xf4, 0x21, 0x43, 0x71, 0xaf, 0x96, 0xe2, 0xde, 0xf1, 0x76,
- 0x81, 0x1f, 0x45, 0x4c, 0xfc, 0x28, 0xcf, 0x71, 0xd0, 0x85, 0x27, 0xd2,
- 0x5a, 0xc8, 0x12, 0xe1, 0x9e, 0x9d, 0x42, 0x42, 0xb2, 0x91, 0x78, 0xa3,
- 0x98, 0x3c, 0x9b, 0xe6, 0x18, 0xec, 0x72, 0xf6, 0xd8, 0xb9, 0xde, 0x48,
- 0x2c, 0xc4, 0xcc, 0x52, 0x5c, 0xb3, 0xfa, 0x28, 0x37, 0x7c, 0x5c, 0xe0,
- 0x39, 0x2d, 0xbc, 0x15, 0x67, 0x79, 0x69, 0xd1, 0x94, 0x74, 0x37, 0x92,
- 0x39, 0xf6, 0x4b, 0x5a, 0x8e, 0xd6, 0x3a, 0x92, 0xad, 0x42, 0x6f, 0xbc,
- 0x5b, 0xdc, 0x56, 0xbc, 0x85, 0xfb, 0xf9, 0xea, 0x12, 0x73, 0x8b, 0xd8,
- 0x30, 0xcd, 0xfd, 0xb8, 0x5e, 0xd1, 0x5b, 0x64, 0x3f, 0x19, 0x14, 0xbf,
- 0x53, 0xbc, 0xbc, 0x37, 0xb7, 0x68, 0x17, 0xdc, 0x93, 0xb3, 0x3c, 0x2f,
- 0x90, 0x5e, 0xee, 0x1f, 0xc5, 0x1f, 0xd7, 0x43, 0xa6, 0x98, 0xd6, 0x8e,
- 0x72, 0xa5, 0xf6, 0xa1, 0xfb, 0x5f, 0xc1, 0x10, 0xe5, 0x57, 0x69, 0x41,
- 0xbf, 0x2b, 0x72, 0x12, 0x3e, 0x59, 0xb3, 0xdf, 0x0e, 0x2d, 0x61, 0xfd,
- 0x12, 0x6e, 0x24, 0xdd, 0xec, 0xce, 0xee, 0xb1, 0xdf, 0x76, 0x7a, 0x6a,
- 0x6c, 0x8f, 0x4e, 0xc9, 0xc4, 0xba, 0xc6, 0x76, 0xf2, 0xb9, 0xc7, 0x47,
- 0x97, 0x41, 0xd1, 0xb9, 0x17, 0x5f, 0x8b, 0xa8, 0xe3, 0x37, 0x1e, 0x14,
- 0x46, 0x19, 0xaf, 0x18, 0x1d, 0xaf, 0x8f, 0x29, 0xf0, 0xd1, 0xb3, 0xd9,
- 0x98, 0xc0, 0xa9, 0xf6, 0xca, 0xfc, 0xcd, 0xb9, 0xab, 0x91, 0x56, 0xbd,
- 0xa8, 0xd3, 0x9b, 0x91, 0x55, 0x7d, 0xb4, 0xee, 0xad, 0x0b, 0x73, 0xfe,
- 0xb8, 0x9a, 0xeb, 0x56, 0xd9, 0xbc, 0xb7, 0xba, 0xa2, 0x0f, 0x45, 0xa9,
- 0xd4, 0x31, 0x8a, 0xe5, 0xa3, 0xb5, 0x0e, 0xb6, 0xf7, 0x62, 0xc7, 0x88,
- 0x4f, 0xbc, 0x92, 0xfe, 0xd7, 0x36, 0xdb, 0xcc, 0x01, 0xb2, 0xe5, 0x2a,
- 0x7d, 0x71, 0xce, 0xd7, 0x9d, 0x77, 0x6b, 0x29, 0x2e, 0x0f, 0x8c, 0x4a,
- 0x08, 0x2c, 0xdc, 0x8f, 0xe7, 0x42, 0x08, 0xb6, 0x09, 0xfa, 0xde, 0x6b,
- 0xe3, 0x0a, 0x05, 0xaa, 0xfe, 0x06, 0x8d, 0x73, 0xd1, 0x55, 0xa1, 0xfa,
- 0xd8, 0xc2, 0xc3, 0xf1, 0x04, 0x2e, 0x10, 0x06, 0xd9, 0x47, 0xf9, 0x72,
- 0x57, 0xda, 0xc4, 0xb9, 0xfc, 0x5f, 0x3b, 0xf3, 0xd4, 0x98, 0x1e, 0x4c,
- 0xe7, 0xbe, 0x48, 0x57, 0x80, 0x68, 0x7d, 0x98, 0x68, 0xe2, 0x67, 0x17,
- 0x9c, 0xda, 0xfa, 0xf9, 0xcb, 0x6a, 0x12, 0x69, 0x9c, 0xfb, 0x31, 0x95,
- 0x38, 0xda, 0x69, 0x28, 0x16, 0xf7, 0xb6, 0xe7, 0x27, 0x2c, 0x9c, 0xbb,
- 0xb6, 0x0e, 0x9f, 0x4c, 0x34, 0xe3, 0xde, 0x51, 0x2f, 0x2e, 0x4e, 0xd8,
- 0xb8, 0x66, 0x0d, 0xee, 0x08, 0x12, 0x8e, 0xa9, 0xa3, 0x78, 0xf1, 0x1a,
- 0xd5, 0x0d, 0x54, 0x53, 0x92, 0xf7, 0x44, 0x12, 0x1b, 0x85, 0x8d, 0x68,
- 0x0c, 0xa9, 0x1b, 0xe2, 0x91, 0xd0, 0x05, 0x7c, 0xc7, 0x26, 0x7d, 0xa8,
- 0xb2, 0xd9, 0x2d, 0x5c, 0xce, 0xde, 0x5c, 0xaf, 0xb3, 0x97, 0x27, 0x4d,
- 0x0f, 0x0a, 0xb9, 0x78, 0xb9, 0xbf, 0x7f, 0x59, 0x0c, 0xe7, 0xb8, 0xcd,
- 0xf5, 0xff, 0xb8, 0xed, 0xd6, 0xb9, 0xcf, 0xb1, 0x45, 0xec, 0xc9, 0x5d,
- 0x8a, 0xeb, 0x97, 0x62, 0xf9, 0xae, 0x85, 0x18, 0x3e, 0x9c, 0x7f, 0xf3,
- 0x0b, 0x18, 0x24, 0xb4, 0xb0, 0x57, 0xc0, 0xb1, 0xdb, 0x23, 0xde, 0x22,
- 0xbf, 0xdb, 0x6b, 0xb0, 0x9f, 0x9d, 0x0c, 0x52, 0x74, 0x85, 0x8b, 0xe4,
- 0x79, 0x3f, 0x9f, 0xcf, 0x08, 0xd8, 0xd8, 0x42, 0x7c, 0x7a, 0x48, 0x8e,
- 0x6b, 0xda, 0xdd, 0xe8, 0xa7, 0x78, 0xee, 0x8e, 0xf9, 0x28, 0x0e, 0xa8,
- 0x78, 0xd5, 0x60, 0x1b, 0xee, 0x59, 0x88, 0xe7, 0xbc, 0x57, 0x55, 0xd9,
- 0x1f, 0xfe, 0x7c, 0xcf, 0x78, 0xd1, 0x36, 0x0d, 0x24, 0x97, 0xc2, 0xfb,
- 0x4e, 0x5c, 0x27, 0xec, 0xad, 0x10, 0xee, 0xde, 0x84, 0xc4, 0x12, 0x8d,
- 0xdb, 0x02, 0x84, 0x5b, 0x2d, 0xfc, 0xd7, 0xf6, 0x7e, 0xdc, 0x33, 0x2e,
- 0xa1, 0x46, 0xe7, 0x3d, 0x1a, 0xb2, 0x83, 0x7a, 0x8e, 0x5f, 0xdd, 0x18,
- 0x1a, 0xf7, 0x88, 0x17, 0xa9, 0x26, 0x39, 0xd2, 0xf3, 0x10, 0x96, 0xb4,
- 0xdd, 0x09, 0x38, 0xb6, 0xc7, 0xff, 0x7f, 0x0b, 0xa9, 0x65, 0xbc, 0x3e,
- 0xf7, 0xa9, 0x04, 0x7c, 0x6d, 0xcc, 0x07, 0xbc, 0xef, 0xd1, 0xfc, 0xdb,
- 0x47, 0x5c, 0xe2, 0x42, 0xfa, 0xa7, 0xf6, 0x89, 0x00, 0xe7, 0x58, 0x7e,
- 0x56, 0x4b, 0xb1, 0x9e, 0xc7, 0xb2, 0x0e, 0x7d, 0x54, 0xd7, 0xf5, 0x63,
- 0x84, 0xe8, 0x3a, 0xe3, 0xcc, 0xf5, 0xbd, 0x05, 0xfa, 0x7d, 0xa2, 0x2e,
- 0xa3, 0x58, 0x41, 0xa2, 0x45, 0xbd, 0xb6, 0x07, 0x75, 0xc5, 0xcb, 0x73,
- 0xd5, 0x5f, 0x29, 0xdc, 0xeb, 0x63, 0xdf, 0xa9, 0x26, 0x5f, 0xf9, 0x79,
- 0x5a, 0xe0, 0xbc, 0x63, 0x7b, 0xdb, 0xd0, 0x9c, 0xa7, 0x1a, 0xda, 0x89,
- 0x21, 0x3c, 0x6e, 0x7d, 0xc5, 0xa6, 0xa5, 0x7e, 0xdc, 0x47, 0xbc, 0xd4,
- 0x12, 0x2f, 0x1f, 0xc6, 0x56, 0xd0, 0x3a, 0x7c, 0x2f, 0xa3, 0x54, 0xec,
- 0x6c, 0x71, 0x2e, 0x2a, 0xc0, 0xfd, 0x5c, 0x2b, 0x45, 0xb0, 0x73, 0x3c,
- 0xd2, 0xe7, 0x93, 0xd8, 0x0e, 0x23, 0xb8, 0x7b, 0xfa, 0x37, 0x3c, 0x54,
- 0x17, 0xd3, 0x5c, 0x41, 0xdc, 0x9e, 0x71, 0x89, 0xb7, 0xa9, 0xd6, 0x78,
- 0x3e, 0x2d, 0x2d, 0x93, 0xf1, 0xac, 0x7d, 0x24, 0x30, 0x84, 0x1b, 0x8c,
- 0x6e, 0xdc, 0x45, 0x36, 0xd8, 0xd9, 0x3c, 0x84, 0x09, 0xb2, 0x81, 0xed,
- 0x0d, 0x54, 0xff, 0xc4, 0x4a, 0xf6, 0xb6, 0x00, 0xcb, 0x51, 0xa0, 0x8b,
- 0xee, 0xd7, 0x53, 0x4d, 0x24, 0xc5, 0xc8, 0xda, 0x1a, 0x04, 0xf9, 0xac,
- 0x36, 0x9a, 0xc4, 0xcf, 0x9d, 0x35, 0xeb, 0xf5, 0xc5, 0xf8, 0xcc, 0x39,
- 0xf6, 0x8b, 0xf4, 0x58, 0x76, 0xb5, 0xae, 0x47, 0x37, 0x49, 0xcd, 0xa3,
- 0x73, 0x64, 0xb3, 0x1b, 0xda, 0x2e, 0x7f, 0x6f, 0x51, 0x46, 0x06, 0xaa,
- 0xda, 0x66, 0xec, 0xb2, 0x3a, 0x0c, 0xb5, 0xed, 0x72, 0xdd, 0x2f, 0xce,
- 0xc1, 0x34, 0x57, 0xe2, 0x5a, 0x48, 0x8a, 0xa8, 0x77, 0xe0, 0x49, 0x5a,
- 0x23, 0x88, 0xad, 0xc5, 0x6e, 0x6c, 0x1b, 0x97, 0x3f, 0xcb, 0xed, 0x7e,
- 0xb6, 0xe5, 0xcf, 0xf8, 0xdf, 0x31, 0x1e, 0xe9, 0xf2, 0x2e, 0xf0, 0x7f,
- 0xd7, 0xf4, 0x67, 0x73, 0x0d, 0x66, 0x38, 0x86, 0xf2, 0x7c, 0x9c, 0x67,
- 0x17, 0xe5, 0x1b, 0xc4, 0x7d, 0xce, 0x7c, 0x5b, 0x3d, 0xec, 0xe3, 0x6e,
- 0xca, 0x95, 0x1b, 0xdb, 0x2c, 0xbc, 0x9a, 0xb8, 0xd7, 0xde, 0xe1, 0xc8,
- 0xa0, 0xc3, 0xc3, 0xef, 0x77, 0x35, 0x9f, 0x5e, 0xd8, 0x43, 0xaf, 0xf4,
- 0x30, 0x9f, 0x2f, 0xb5, 0x3a, 0xfd, 0xf9, 0xef, 0x51, 0x7e, 0x7c, 0xf6,
- 0x73, 0x3d, 0xb2, 0x3b, 0xdd, 0xdc, 0xd7, 0x7f, 0xaa, 0xa4, 0x08, 0xd7,
- 0x78, 0x8d, 0x70, 0x8f, 0x33, 0x6d, 0xff, 0x45, 0xa9, 0xf8, 0xd8, 0x5f,
- 0x23, 0x19, 0xe0, 0x3d, 0xba, 0x8a, 0xfd, 0x47, 0xdb, 0xef, 0x06, 0x8e,
- 0x5a, 0x9e, 0xea, 0xb5, 0xa0, 0x3a, 0xb9, 0xc7, 0xb1, 0x87, 0xa5, 0x66,
- 0x7c, 0xdd, 0xb3, 0xcd, 0x5c, 0x2b, 0x73, 0x5f, 0xad, 0x73, 0xdd, 0x24,
- 0x81, 0xb7, 0xad, 0x2a, 0xaf, 0xa9, 0x9d, 0xe0, 0x5e, 0x37, 0xf7, 0xc0,
- 0x97, 0xeb, 0xf0, 0xd6, 0xaf, 0xb5, 0x3c, 0x4b, 0xd6, 0xba, 0xc4, 0x15,
- 0x99, 0x3e, 0xb2, 0x3d, 0x1d, 0x89, 0x8c, 0xe5, 0x6d, 0x5c, 0x1b, 0xc2,
- 0x03, 0x99, 0x4a, 0x0c, 0x5b, 0x9f, 0x6b, 0x45, 0xeb, 0x14, 0x59, 0x63,
- 0x26, 0x88, 0x96, 0x89, 0xf0, 0xc0, 0xd7, 0xa5, 0xf0, 0xe0, 0xbc, 0xc4,
- 0xcf, 0x7c, 0x1d, 0xd7, 0x38, 0x38, 0x56, 0xed, 0x58, 0xed, 0x5c, 0xe3,
- 0x1d, 0x57, 0xe7, 0x6f, 0x45, 0x7a, 0xce, 0x33, 0x5f, 0x96, 0x6c, 0x3c,
- 0x10, 0x93, 0x70, 0xa3, 0xf1, 0x9f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab,
- 0x9c, 0x9f, 0x9d, 0xe0, 0xbc, 0x7c, 0xad, 0x8e, 0xb5, 0x99, 0x7a, 0x8a,
- 0x49, 0x0d, 0x14, 0x9f, 0xea, 0xf1, 0x11, 0xc5, 0xa4, 0xd5, 0x6b, 0x28,
- 0x3c, 0xae, 0xb1, 0xfa, 0xaf, 0x00, 0xef, 0xdf, 0x6a, 0x56, 0x51, 0x68,
- 0x7d, 0xdd, 0x92, 0xd6, 0xd3, 0x20, 0xa9, 0xb8, 0x2b, 0xc2, 0x73, 0x27,
- 0x3a, 0xd6, 0xe6, 0x2b, 0xf9, 0x74, 0x95, 0x93, 0x3f, 0xf5, 0x8e, 0xab,
- 0x66, 0x2b, 0x79, 0xd6, 0x98, 0xd5, 0x7e, 0x90, 0x92, 0x78, 0xcf, 0xa1,
- 0x0f, 0xe3, 0xd9, 0x14, 0xf6, 0x64, 0x43, 0xf8, 0x45, 0xa6, 0x8a, 0x6c,
- 0x23, 0x6c, 0x7c, 0x17, 0x3c, 0xa6, 0xb5, 0x23, 0x96, 0x0f, 0x47, 0x1f,
- 0x90, 0xfe, 0x1c, 0x65, 0x97, 0x76, 0x98, 0x10, 0x36, 0x72, 0xae, 0x96,
- 0xd0, 0x4b, 0xf8, 0x73, 0x67, 0x8f, 0x0a, 0xa8, 0xf0, 0xd0, 0x9c, 0x07,
- 0x46, 0x33, 0x9e, 0x79, 0x38, 0xfd, 0x4c, 0xde, 0x73, 0x95, 0xb0, 0xc1,
- 0xb8, 0x97, 0xe4, 0x2c, 0xd0, 0xdc, 0x56, 0x8f, 0x72, 0xaf, 0x0b, 0xe3,
- 0x24, 0x13, 0xc5, 0x0c, 0x74, 0x28, 0x23, 0x28, 0x2f, 0xec, 0x27, 0x26,
- 0x64, 0xca, 0xd0, 0x2f, 0x17, 0x81, 0x03, 0x14, 0x3b, 0x36, 0xc7, 0x7e,
- 0x45, 0xb9, 0xa1, 0xb2, 0x7f, 0x91, 0x9e, 0x14, 0x58, 0xa2, 0x27, 0x49,
- 0x1e, 0x2e, 0xff, 0x41, 0xaa, 0xef, 0x0f, 0x96, 0xf8, 0x7d, 0xcf, 0x7c,
- 0xd2, 0x99, 0x3f, 0xb2, 0x6f, 0x85, 0x24, 0xe1, 0xea, 0xb6, 0xa3, 0xc8,
- 0x2d, 0xad, 0xd0, 0x10, 0x24, 0x4c, 0xc0, 0x75, 0x60, 0x03, 0xf1, 0xb8,
- 0xe5, 0x11, 0xee, 0x09, 0x5e, 0xd9, 0x71, 0xdd, 0x14, 0xfb, 0x75, 0xa0,
- 0xe3, 0xe7, 0x69, 0x2d, 0xd9, 0x20, 0x33, 0xae, 0x4c, 0x74, 0xdc, 0x3d,
- 0xc2, 0xb9, 0xad, 0x8d, 0x6b, 0x71, 0xca, 0xcb, 0xda, 0x60, 0xa3, 0xf0,
- 0x89, 0x1b, 0x33, 0x54, 0x8f, 0x13, 0xbd, 0xef, 0x47, 0xb4, 0x20, 0xc9,
- 0xae, 0xeb, 0x4e, 0xd1, 0xcf, 0x78, 0xdf, 0x91, 0xdb, 0x55, 0xf9, 0x0a,
- 0xee, 0x08, 0x2f, 0xe0, 0x90, 0xa8, 0x83, 0x3b, 0x6c, 0x7b, 0x77, 0x8c,
- 0xf3, 0xb8, 0xb3, 0x9f, 0x4e, 0xf7, 0x63, 0x94, 0x77, 0x15, 0x0c, 0x33,
- 0x7d, 0x7c, 0x2e, 0x42, 0xa2, 0x3a, 0x2e, 0x7b, 0x7a, 0x01, 0x97, 0xf8,
- 0xb0, 0x97, 0xee, 0x97, 0x1d, 0x7c, 0xc2, 0x67, 0xfb, 0x56, 0x75, 0xa8,
- 0x8f, 0xf0, 0x79, 0xc0, 0x2b, 0x3b, 0x36, 0x4c, 0x6a, 0x21, 0x89, 0xf8,
- 0xd8, 0xc3, 0x7b, 0xdb, 0x34, 0xe7, 0xac, 0xc1, 0x74, 0xfb, 0x3a, 0xb8,
- 0x97, 0xb9, 0x9c, 0xe8, 0xb6, 0xb3, 0x61, 0xc2, 0x49, 0x15, 0x5b, 0x49,
- 0xe4, 0xa9, 0x22, 0xbe, 0xa2, 0xc2, 0xab, 0x9b, 0x74, 0x72, 0x2c, 0x9d,
- 0xc4, 0xf3, 0xf1, 0x8a, 0x7e, 0xd6, 0xe7, 0xbf, 0x81, 0x54, 0x43, 0x27,
- 0x46, 0xb3, 0xaa, 0x7f, 0x63, 0xa6, 0x13, 0x13, 0xa4, 0xc3, 0x3b, 0x8a,
- 0x41, 0x7f, 0x67, 0x46, 0xc7, 0xb6, 0x22, 0xd7, 0x26, 0xa1, 0x8e, 0xdd,
- 0x93, 0xb9, 0x85, 0x1a, 0xb2, 0x92, 0x4b, 0xf6, 0x67, 0x2a, 0x36, 0x17,
- 0xce, 0x7b, 0xe6, 0x43, 0xa2, 0x32, 0xaf, 0x42, 0xeb, 0x28, 0x23, 0x7f,
- 0x6c, 0x63, 0x29, 0xdb, 0xc2, 0xad, 0x98, 0x9c, 0xf2, 0x5b, 0x57, 0x98,
- 0x2a, 0xd6, 0xb6, 0xbd, 0x41, 0xef, 0xb6, 0xe2, 0x97, 0xc7, 0xbf, 0x86,
- 0xf2, 0x37, 0x5d, 0x78, 0x3c, 0x93, 0x44, 0x4b, 0xdb, 0x4d, 0x48, 0xfd,
- 0xae, 0x82, 0xa7, 0x32, 0x3e, 0x3c, 0x97, 0xa9, 0xec, 0x77, 0x7f, 0x3f,
- 0x4b, 0x7e, 0x48, 0x3e, 0xf0, 0xec, 0x97, 0xee, 0x31, 0x52, 0x3c, 0x97,
- 0x79, 0xff, 0xfb, 0x9f, 0x1e, 0x77, 0xd6, 0x19, 0xe7, 0x11, 0xf5, 0xe3,
- 0x8b, 0xf3, 0xda, 0xd0, 0xdb, 0xfe, 0xb1, 0x77, 0xb4, 0x28, 0x40, 0x31,
- 0xa4, 0x72, 0x3e, 0x40, 0x28, 0xe3, 0xce, 0x9e, 0x0b, 0xe1, 0xdf, 0x88,
- 0x71, 0x0e, 0x16, 0xaa, 0x08, 0x57, 0xad, 0x20, 0x59, 0xe8, 0x99, 0x80,
- 0x5f, 0x2a, 0xaa, 0xf4, 0x69, 0xf2, 0xbb, 0x48, 0x3e, 0xae, 0xe2, 0x0f,
- 0x29, 0xa6, 0xb0, 0x4f, 0x55, 0x72, 0x9c, 0x54, 0xdc, 0xec, 0x85, 0x57,
- 0xa7, 0x6b, 0xc5, 0xa6, 0x43, 0xf9, 0xb7, 0xf9, 0x39, 0xd9, 0x75, 0xe5,
- 0x7b, 0xe4, 0xd2, 0x77, 0xd2, 0xb3, 0x23, 0xb3, 0xdb, 0x68, 0x3c, 0xcb,
- 0xe2, 0x59, 0x3b, 0xb5, 0x85, 0xe5, 0x15, 0xf0, 0xbf, 0x41, 0xf2, 0x9f,
- 0x24, 0x1a, 0xb3, 0xb4, 0xc6, 0xeb, 0xb4, 0x66, 0xa6, 0xd8, 0x47, 0x63,
- 0xf8, 0x19, 0xc9, 0xd9, 0xb1, 0xdd, 0xad, 0x5e, 0xde, 0xdb, 0x7f, 0x2e,
- 0x03, 0xaa, 0xbb, 0x2d, 0xcd, 0xb5, 0x70, 0x16, 0x72, 0x18, 0x8b, 0xf8,
- 0xf1, 0x2e, 0x5c, 0x3f, 0xaa, 0x25, 0x2d, 0xc2, 0x61, 0x29, 0x15, 0xc2,
- 0x65, 0xb2, 0x0d, 0xc7, 0xc9, 0x86, 0x9b, 0x88, 0xa7, 0x70, 0xe8, 0x1c,
- 0x8d, 0xb7, 0x5c, 0x0a, 0xf6, 0x4f, 0xc8, 0x38, 0xc7, 0xfb, 0xaf, 0xa2,
- 0xf2, 0x3e, 0x01, 0x7f, 0x1a, 0xbb, 0xf8, 0x7f, 0x0d, 0xe1, 0xf2, 0x70,
- 0x82, 0xb2, 0x2a, 0xe3, 0x5b, 0x4f, 0xbe, 0xfd, 0x21, 0x1c, 0xa4, 0x3a,
- 0x79, 0x47, 0x2c, 0x84, 0x64, 0x7d, 0x1c, 0x1e, 0xbd, 0x65, 0xe0, 0x22,
- 0xfe, 0x87, 0x5d, 0xe6, 0x3d, 0x6c, 0x11, 0x4e, 0x5c, 0xc4, 0xa7, 0xb6,
- 0xac, 0xeb, 0xa7, 0x67, 0xa0, 0x97, 0xcf, 0xa1, 0x65, 0xf0, 0x13, 0xbc,
- 0x6b, 0xf3, 0xfe, 0xb6, 0x22, 0xcb, 0x78, 0xd1, 0x08, 0xab, 0x2e, 0x04,
- 0x50, 0x0e, 0xc8, 0xd8, 0x6c, 0x30, 0xfe, 0xd7, 0x06, 0x1f, 0x83, 0x36,
- 0x70, 0x5e, 0xb4, 0xf4, 0x7f, 0x88, 0xb3, 0x76, 0xae, 0x9e, 0xd7, 0x15,
- 0x48, 0x5c, 0xdd, 0x72, 0xba, 0x0a, 0x5a, 0x97, 0x5b, 0xe8, 0x89, 0x46,
- 0xf9, 0xaf, 0xec, 0xb3, 0x81, 0x4f, 0x6d, 0x3d, 0xf2, 0x29, 0xe1, 0x20,
- 0x3d, 0x38, 0x4d, 0xb6, 0xdf, 0x8f, 0x45, 0xda, 0x5e, 0x27, 0xfe, 0xa9,
- 0xb0, 0xd3, 0x79, 0x9f, 0xc8, 0xf2, 0xec, 0x25, 0xda, 0x5e, 0x23, 0x1c,
- 0xb0, 0x23, 0x76, 0xd1, 0x4e, 0x2e, 0xe5, 0x1a, 0xe9, 0x67, 0xde, 0x4a,
- 0xff, 0x98, 0x7b, 0x0e, 0xb7, 0xe2, 0x76, 0xc2, 0x77, 0xc3, 0xd9, 0x45,
- 0xbc, 0xe6, 0xa6, 0x18, 0xcc, 0xb1, 0xbf, 0x7c, 0x15, 0x95, 0xd4, 0x12,
- 0x95, 0xc7, 0xd8, 0x4d, 0x71, 0x61, 0x97, 0x93, 0x0b, 0xe0, 0x5d, 0xbe,
- 0xb6, 0x0d, 0x9f, 0x4c, 0x95, 0xbc, 0xe4, 0x4b, 0xeb, 0xf5, 0x35, 0x10,
- 0xc1, 0x8c, 0x25, 0xea, 0x4c, 0x19, 0x1f, 0xb6, 0x6b, 0x5d, 0x92, 0x3c,
- 0x88, 0xab, 0x63, 0x96, 0xed, 0xd3, 0xf5, 0xbe, 0x56, 0x11, 0xe9, 0x29,
- 0x8a, 0x28, 0x6a, 0x8a, 0x3e, 0xa5, 0xa6, 0xd8, 0xaa, 0x78, 0x8b, 0x96,
- 0x47, 0x5d, 0x7b, 0x17, 0xd5, 0xb4, 0x43, 0x58, 0x19, 0xf3, 0x51, 0x3d,
- 0xac, 0x19, 0x17, 0x50, 0x45, 0xf2, 0x0f, 0x61, 0x6f, 0xc9, 0x84, 0x2b,
- 0xb3, 0x13, 0xee, 0x4c, 0x58, 0xdd, 0x83, 0x21, 0x24, 0x83, 0x15, 0x4c,
- 0xab, 0x90, 0xae, 0xaa, 0xdb, 0x19, 0xcb, 0xdc, 0x85, 0xb3, 0x39, 0xc6,
- 0xe7, 0x54, 0x9f, 0xa6, 0xf9, 0x3b, 0xbc, 0x2f, 0xc5, 0x4d, 0x3c, 0x49,
- 0x75, 0x95, 0xa7, 0xad, 0x91, 0xf4, 0xd0, 0x84, 0xe1, 0x92, 0x60, 0xb3,
- 0x22, 0x5d, 0xc0, 0xfb, 0x64, 0xbb, 0x82, 0x03, 0x33, 0x94, 0x48, 0x28,
- 0x5f, 0xb9, 0x32, 0x2a, 0xc5, 0x09, 0xc6, 0xd8, 0x3e, 0xfa, 0x1e, 0xe0,
- 0x33, 0x3f, 0x64, 0x67, 0x57, 0x76, 0xb4, 0x3a, 0xb1, 0xa6, 0x8d, 0x6a,
- 0x9c, 0xa7, 0xbd, 0x95, 0x9a, 0xcb, 0x44, 0xcd, 0xf8, 0x62, 0xad, 0xb8,
- 0xe1, 0xe6, 0x1a, 0xaa, 0xc5, 0x87, 0x4b, 0x8c, 0x03, 0x2b, 0x67, 0x3c,
- 0x37, 0xc4, 0xda, 0x08, 0xb3, 0x8b, 0x05, 0x8c, 0x35, 0xac, 0xf9, 0xb0,
- 0x1e, 0x07, 0xa9, 0x56, 0xf6, 0xeb, 0x5b, 0x91, 0x51, 0xcb, 0xde, 0x37,
- 0xe3, 0x8c, 0x7f, 0xe1, 0xdd, 0x46, 0x18, 0x6a, 0x24, 0xfd, 0x55, 0x8e,
- 0x99, 0x9e, 0x3b, 0xe2, 0x06, 0x0e, 0x8f, 0x52, 0x88, 0xd2, 0xd7, 0xa3,
- 0x6e, 0x4d, 0x37, 0x3e, 0xac, 0x67, 0xfc, 0x4b, 0xb1, 0x8a, 0xe8, 0xd9,
- 0x33, 0x13, 0x70, 0xce, 0x24, 0xec, 0x2d, 0x2d, 0xd2, 0x7c, 0x39, 0xad,
- 0x5f, 0x46, 0x23, 0xcb, 0xe4, 0x9f, 0xa2, 0x91, 0x6c, 0x96, 0x30, 0xcf,
- 0x68, 0x7a, 0x1b, 0x5e, 0x4e, 0xf3, 0xbc, 0xe1, 0xa4, 0x21, 0x54, 0xee,
- 0x6b, 0x3b, 0x32, 0xb1, 0x66, 0x78, 0x0d, 0x5e, 0x7f, 0x71, 0x9d, 0x00,
- 0xf6, 0x7d, 0xa9, 0x3c, 0xfe, 0x39, 0x6b, 0x51, 0xdc, 0x18, 0x5d, 0x4f,
- 0x75, 0x50, 0x14, 0xfa, 0xef, 0x94, 0x49, 0x1f, 0xdc, 0xe7, 0x5d, 0x41,
- 0x98, 0x17, 0x9e, 0x57, 0xe2, 0x7c, 0xee, 0xd7, 0x1e, 0x52, 0x4c, 0xdb,
- 0x76, 0xb7, 0xeb, 0xea, 0x3b, 0x60, 0x3b, 0xf4, 0xf1, 0x7e, 0x81, 0x67,
- 0x4f, 0xbb, 0x0f, 0x07, 0x28, 0x07, 0x3e, 0x91, 0x6e, 0xb1, 0x6e, 0x12,
- 0x7c, 0x7e, 0x89, 0x62, 0xb6, 0x48, 0xd1, 0xbb, 0x37, 0xd6, 0xb0, 0xcf,
- 0xee, 0x2e, 0xed, 0x84, 0x94, 0x89, 0xd4, 0x70, 0x3d, 0x51, 0x45, 0x35,
- 0xf4, 0x70, 0x9a, 0xe9, 0xb5, 0x87, 0x5c, 0x34, 0xd7, 0xae, 0xb8, 0x3e,
- 0x7f, 0x3d, 0xd9, 0x45, 0xa3, 0xc9, 0x72, 0x0c, 0xe0, 0x08, 0x8d, 0x0d,
- 0x95, 0x58, 0x96, 0x7d, 0x35, 0xdc, 0x33, 0xdc, 0x4b, 0xfa, 0xad, 0xcb,
- 0x56, 0xe6, 0xc9, 0x96, 0xfa, 0xb1, 0x62, 0x64, 0xdc, 0x99, 0x87, 0x7d,
- 0xe0, 0xc5, 0xf8, 0x00, 0xf6, 0xa6, 0x03, 0x98, 0x49, 0xb7, 0xa8, 0x2f,
- 0x38, 0xfb, 0xed, 0x95, 0xfe, 0xd2, 0x70, 0x7a, 0x71, 0x4c, 0x00, 0xd3,
- 0x97, 0xfe, 0x67, 0xf9, 0x54, 0xfa, 0x8e, 0x95, 0x7e, 0x80, 0x82, 0x5c,
- 0xa0, 0x82, 0x87, 0x28, 0x56, 0x78, 0x1f, 0x26, 0xbd, 0x9e, 0x27, 0xbd,
- 0x4a, 0xa4, 0xd7, 0x17, 0x8c, 0xef, 0x33, 0x66, 0xf1, 0xec, 0x8e, 0xfb,
- 0x78, 0x8f, 0xc5, 0x22, 0xd0, 0xe2, 0x8c, 0xc9, 0xc4, 0x5d, 0x38, 0x33,
- 0xc2, 0xe7, 0xf9, 0xd4, 0x8e, 0x53, 0x69, 0x7b, 0xfd, 0x5c, 0xac, 0x25,
- 0x75, 0x9e, 0xf0, 0xb4, 0xf5, 0xbb, 0x9a, 0x71, 0x96, 0xfc, 0x34, 0x3b,
- 0xf1, 0xfb, 0x38, 0x5b, 0xdf, 0xa2, 0xfe, 0x98, 0xca, 0xf9, 0x47, 0xe3,
- 0x0f, 0x21, 0x31, 0x41, 0x75, 0xc3, 0x9a, 0x7f, 0x47, 0x4e, 0x16, 0x87,
- 0xac, 0xb7, 0xcc, 0xbf, 0x80, 0xff, 0x86, 0xb3, 0x57, 0x84, 0x8d, 0x17,
- 0xc0, 0x63, 0x2a, 0xf5, 0x78, 0x78, 0xf6, 0x1e, 0x3e, 0x8b, 0x14, 0xe4,
- 0x5a, 0xdb, 0xd9, 0x0b, 0x4a, 0xf3, 0xde, 0x95, 0x40, 0xae, 0x57, 0x0b,
- 0xa5, 0x9c, 0xb3, 0x9f, 0xf0, 0x3e, 0x46, 0x7e, 0x11, 0x1d, 0xe3, 0xf1,
- 0x81, 0x0e, 0x3d, 0x1f, 0x82, 0x4c, 0x18, 0x27, 0x15, 0xd0, 0xba, 0x80,
- 0xa0, 0xff, 0xb1, 0x74, 0x10, 0xfb, 0xb2, 0x2d, 0x3d, 0x51, 0x71, 0xdb,
- 0xc2, 0x9e, 0x31, 0xe7, 0xb9, 0x00, 0xe5, 0x39, 0x2d, 0xf5, 0x18, 0x5a,
- 0xfa, 0x7c, 0xe2, 0x56, 0xa4, 0xea, 0x5b, 0xfa, 0x9f, 0x44, 0x38, 0xe1,
- 0x11, 0x5a, 0xf4, 0x2c, 0x2a, 0xf3, 0xac, 0xcc, 0xcb, 0x40, 0x03, 0xc7,
- 0x99, 0x34, 0x9e, 0x54, 0x65, 0xac, 0x6a, 0xd3, 0xe7, 0xa7, 0xb1, 0x68,
- 0x2f, 0x95, 0x31, 0xeb, 0xf3, 0x34, 0x5e, 0x56, 0xa9, 0x0e, 0xae, 0x82,
- 0xab, 0x81, 0xf7, 0xe3, 0x76, 0x62, 0x47, 0x9a, 0xf3, 0x34, 0xc9, 0x85,
- 0x7c, 0xb3, 0x27, 0xb2, 0x13, 0x03, 0xf9, 0x00, 0x0e, 0x66, 0xc3, 0xfb,
- 0xf6, 0x10, 0xae, 0x1b, 0x2b, 0x85, 0x43, 0xdb, 0x45, 0x80, 0xf4, 0x2d,
- 0x21, 0xd4, 0x10, 0x44, 0xb5, 0xae, 0xd2, 0xa7, 0x52, 0xcf, 0x9c, 0xa2,
- 0x7a, 0xe6, 0x0c, 0xf9, 0x9a, 0x6f, 0xa1, 0x46, 0x5d, 0x99, 0xb3, 0x31,
- 0x17, 0xdb, 0x84, 0xf7, 0x1d, 0x9d, 0x05, 0xc9, 0xc6, 0x38, 0x17, 0x39,
- 0x35, 0xa8, 0xd8, 0x3e, 0x66, 0x79, 0xee, 0x6f, 0x0f, 0x22, 0x9c, 0x61,
- 0xcc, 0x29, 0x7d, 0x53, 0x26, 0x79, 0xcc, 0xe8, 0x43, 0xd8, 0x18, 0x1b,
- 0xc2, 0x80, 0xf1, 0xc7, 0xa8, 0x6a, 0xe0, 0x78, 0xa4, 0x58, 0x75, 0x34,
- 0xef, 0xc5, 0xf6, 0x6e, 0x84, 0x8f, 0x72, 0x0e, 0x6e, 0xa5, 0x1c, 0xcc,
- 0xbe, 0xcb, 0xf3, 0xdf, 0xdf, 0xb1, 0x9a, 0x70, 0x45, 0x6d, 0x7b, 0x25,
- 0xcf, 0x5f, 0x9d, 0x57, 0xb9, 0x8f, 0x43, 0xb5, 0x29, 0xbc, 0x6f, 0x5f,
- 0x6b, 0xe2, 0x51, 0x8a, 0x31, 0x89, 0x35, 0x6e, 0x60, 0x09, 0x9f, 0xf7,
- 0x15, 0x0b, 0x3d, 0x80, 0x40, 0xc7, 0x8a, 0xbc, 0xc0, 0x6c, 0x9c, 0xec,
- 0xe3, 0xd7, 0xce, 0xf7, 0x84, 0x16, 0xce, 0x63, 0x72, 0xff, 0xe4, 0x90,
- 0x9d, 0xe4, 0x33, 0xfa, 0xd2, 0x3b, 0x64, 0x57, 0x5a, 0xb0, 0x8c, 0x9f,
- 0xd5, 0x70, 0x5c, 0x96, 0xf5, 0x45, 0xb9, 0xb3, 0xac, 0x4f, 0xd8, 0xb9,
- 0x05, 0x5d, 0xb8, 0xe8, 0x9d, 0xdd, 0x93, 0xda, 0xe0, 0x1e, 0xb4, 0x0c,
- 0xfc, 0x5c, 0x54, 0x3b, 0xbb, 0x7f, 0xd3, 0xad, 0x48, 0x2d, 0x37, 0x5d,
- 0xbd, 0x9f, 0x64, 0xd7, 0x13, 0x1d, 0xe7, 0x08, 0x84, 0x6e, 0x70, 0xf6,
- 0x88, 0xa6, 0x5b, 0xff, 0x84, 0xe6, 0xe6, 0xff, 0xbb, 0x7c, 0x7c, 0x5e,
- 0xf1, 0xf9, 0xec, 0x73, 0x76, 0x74, 0x69, 0x45, 0x3e, 0x27, 0xc9, 0xf7,
- 0x83, 0xa6, 0x84, 0x46, 0x3d, 0x32, 0xdf, 0x47, 0xdf, 0xff, 0x26, 0x4f,
- 0x68, 0xff, 0xda, 0x7e, 0xfc, 0x24, 0x67, 0x62, 0x3f, 0xe5, 0x81, 0x3a,
- 0x5d, 0x53, 0x73, 0x08, 0x71, 0x2d, 0xed, 0xf0, 0x7f, 0x4d, 0x8e, 0xfc,
- 0xb0, 0x5e, 0x75, 0x6a, 0x8c, 0x0a, 0x7f, 0x3e, 0xe2, 0xef, 0xb7, 0x7c,
- 0xec, 0x0b, 0x84, 0x91, 0xc8, 0x66, 0x52, 0x14, 0x57, 0x5a, 0xa2, 0x54,
- 0xc1, 0x93, 0x1f, 0x68, 0xfb, 0x40, 0xfe, 0x3a, 0x96, 0x66, 0xf9, 0x07,
- 0xfd, 0xdb, 0xf8, 0x48, 0xb0, 0xee, 0xf4, 0x24, 0x8d, 0x90, 0xc4, 0x71,
- 0xd7, 0x89, 0xa7, 0x56, 0x48, 0xfa, 0x51, 0x0d, 0xd3, 0x35, 0x5c, 0x0a,
- 0x07, 0xbd, 0x7c, 0x7e, 0x9e, 0xc0, 0xe1, 0x36, 0xa3, 0x92, 0x2b, 0xe7,
- 0x28, 0x1f, 0xbd, 0x4f, 0x74, 0x1c, 0x8c, 0x35, 0x22, 0x45, 0xf9, 0x28,
- 0xa3, 0x57, 0x6c, 0x49, 0x9f, 0x65, 0x8c, 0xd9, 0x46, 0x18, 0x53, 0x0b,
- 0xb9, 0xe5, 0x96, 0xc1, 0x17, 0xb1, 0xd3, 0x3e, 0x5b, 0xcf, 0x36, 0xe5,
- 0xc6, 0xf1, 0xd6, 0x59, 0xbb, 0x1c, 0x60, 0x7e, 0x65, 0x3c, 0x67, 0x90,
- 0xcd, 0x5c, 0x11, 0x0e, 0x3e, 0x47, 0x39, 0x75, 0x66, 0x41, 0x1f, 0xe1,
- 0xfc, 0xa2, 0x3d, 0xd6, 0xf8, 0xb8, 0x06, 0x4c, 0x41, 0x4f, 0xe4, 0x41,
- 0xc5, 0xb6, 0xb7, 0x39, 0xf8, 0xfe, 0x82, 0xad, 0xae, 0x9e, 0xfd, 0x0f,
- 0xbe, 0x85, 0xdf, 0xb2, 0x38, 0xef, 0x84, 0xf2, 0x9b, 0xe8, 0x3b, 0xcf,
- 0x19, 0x60, 0x2c, 0xc3, 0xe7, 0x9c, 0xbc, 0x3b, 0xda, 0xab, 0xd8, 0x5f,
- 0x54, 0x3e, 0xc7, 0xbf, 0x71, 0x8c, 0x7b, 0xaa, 0x36, 0xe5, 0x67, 0x19,
- 0x7b, 0x2e, 0xfd, 0xce, 0x80, 0xaf, 0x5d, 0xd8, 0x3c, 0xc6, 0xbd, 0x88,
- 0x93, 0xd7, 0x29, 0xf8, 0x3b, 0xca, 0xc3, 0xdc, 0x2b, 0x61, 0x5f, 0x6f,
- 0xea, 0x38, 0x35, 0xc9, 0x39, 0x35, 0xde, 0x71, 0x7b, 0x7a, 0x51, 0xc7,
- 0x97, 0x78, 0x3a, 0x7d, 0x07, 0xc5, 0x9d, 0x4c, 0x5a, 0x1b, 0x8c, 0xc8,
- 0xce, 0xde, 0x54, 0xaa, 0x28, 0xbe, 0x4a, 0x45, 0x1a, 0xcf, 0xa7, 0xfa,
- 0x07, 0x0f, 0x85, 0x90, 0xc9, 0x76, 0xe3, 0x1b, 0x63, 0xb6, 0x5d, 0xb5,
- 0xc6, 0x85, 0x57, 0x46, 0x6c, 0x7c, 0x10, 0x03, 0x5e, 0x1e, 0x09, 0x0f,
- 0x9e, 0x01, 0x7e, 0xaf, 0x8e, 0x6a, 0xe4, 0x56, 0xa1, 0xf5, 0x10, 0x36,
- 0x08, 0xbd, 0x8b, 0x96, 0x60, 0x1e, 0xda, 0xe9, 0x5d, 0x34, 0xdf, 0x4b,
- 0x05, 0xe0, 0x27, 0x05, 0x2f, 0xde, 0x1c, 0xe3, 0x39, 0xbd, 0x38, 0x73,
- 0xb4, 0xc1, 0xbf, 0x93, 0xe6, 0x3a, 0x40, 0xf1, 0xbd, 0xfb, 0x58, 0x02,
- 0x9b, 0x0f, 0x09, 0x44, 0x23, 0x09, 0x74, 0x1d, 0xab, 0xc5, 0xa6, 0x31,
- 0x05, 0xef, 0xc5, 0x6b, 0x71, 0xd3, 0xd1, 0x45, 0x3e, 0x2a, 0x7d, 0x0d,
- 0x3e, 0xe7, 0xc8, 0x67, 0xc8, 0x9e, 0xcc, 0x72, 0xcc, 0xa6, 0x7c, 0x91,
- 0xe5, 0x18, 0x68, 0xdb, 0xc1, 0xf6, 0x4a, 0x9f, 0xe3, 0x29, 0xca, 0x1f,
- 0x8f, 0xb6, 0xeb, 0xc1, 0xa0, 0x64, 0x62, 0xd5, 0x44, 0xf9, 0xb6, 0x3a,
- 0xd8, 0xcf, 0xf3, 0x5e, 0xc0, 0xc7, 0xad, 0xb6, 0xbd, 0x39, 0x1e, 0x99,
- 0xbf, 0xdb, 0xc1, 0xb5, 0x71, 0xf2, 0xa9, 0x26, 0x3c, 0x9a, 0x5d, 0xdc,
- 0x2f, 0xd2, 0xfb, 0x2e, 0xca, 0xd6, 0x90, 0x0a, 0xfb, 0xa3, 0x6a, 0xd3,
- 0xfe, 0xd8, 0x6d, 0x46, 0x82, 0xf7, 0x09, 0x3e, 0x67, 0x11, 0xa2, 0x1a,
- 0xc4, 0xb6, 0xdf, 0x8a, 0xdb, 0x76, 0x21, 0x6e, 0x79, 0x56, 0xaf, 0x55,
- 0x71, 0x6c, 0x25, 0xf7, 0x9c, 0xc3, 0xc9, 0x46, 0xb2, 0x2f, 0xef, 0x4a,
- 0x3d, 0xb8, 0x15, 0x9a, 0x65, 0x51, 0x90, 0x0b, 0x2d, 0xd5, 0xfa, 0x80,
- 0x26, 0xff, 0xc1, 0x91, 0x06, 0x3c, 0x3e, 0xf7, 0x9b, 0x7c, 0xf4, 0x85,
- 0x62, 0x84, 0x8d, 0x8f, 0x0c, 0xac, 0xaf, 0x43, 0x24, 0x79, 0x27, 0xe5,
- 0x02, 0xc9, 0xe4, 0xf3, 0xa0, 0x16, 0x6e, 0x8a, 0xf7, 0x63, 0xc7, 0x18,
- 0xef, 0x51, 0xc5, 0x3a, 0x3e, 0x1a, 0xb3, 0xff, 0xc6, 0x43, 0xf4, 0xaf,
- 0x6f, 0x6f, 0x49, 0x79, 0x9d, 0xdf, 0x05, 0xe9, 0x54, 0x07, 0xd4, 0xa3,
- 0x34, 0xa3, 0x97, 0x97, 0x8b, 0xe4, 0x1b, 0x3e, 0x44, 0x82, 0x8d, 0x14,
- 0xab, 0xe6, 0xc8, 0x77, 0x67, 0x4a, 0x5c, 0x07, 0xac, 0xe9, 0xb0, 0x27,
- 0x96, 0x61, 0x7a, 0x8e, 0xe6, 0xca, 0xea, 0x5d, 0x1f, 0x10, 0xce, 0xab,
- 0x31, 0xed, 0x3a, 0xaf, 0x19, 0x39, 0xdd, 0x22, 0x64, 0xcc, 0xaf, 0xb1,
- 0xed, 0xee, 0x76, 0x7d, 0xb0, 0x56, 0x60, 0x80, 0xe6, 0x4a, 0xb4, 0xca,
- 0xb8, 0x32, 0x88, 0x48, 0xd7, 0x5b, 0x88, 0xf4, 0x9d, 0xa3, 0x18, 0xf6,
- 0x44, 0x89, 0xcf, 0xd8, 0x3e, 0x84, 0xbf, 0x19, 0x5b, 0x8a, 0xe7, 0x67,
- 0x06, 0x16, 0x7a, 0x62, 0xf0, 0x5e, 0xbd, 0xd6, 0xc4, 0xf1, 0xb1, 0x10,
- 0xd9, 0x4f, 0x15, 0xc5, 0x75, 0x05, 0x52, 0x33, 0xf7, 0x48, 0x43, 0x1d,
- 0xb1, 0x47, 0x6c, 0x7b, 0x75, 0x73, 0xa5, 0xe6, 0x59, 0x3d, 0x7b, 0xf9,
- 0xef, 0x02, 0x16, 0xfb, 0x3d, 0x41, 0xd2, 0x5f, 0x4b, 0x6a, 0x87, 0x78,
- 0xd1, 0xb6, 0x7e, 0x57, 0x10, 0xcf, 0x91, 0x5a, 0x78, 0x99, 0x6f, 0x05,
- 0xbb, 0x26, 0x08, 0x94, 0x39, 0xe7, 0x56, 0xe0, 0xed, 0x8a, 0xf3, 0x5e,
- 0x33, 0xeb, 0xa8, 0xec, 0xdd, 0x18, 0xa7, 0x98, 0x28, 0xfc, 0x84, 0xa7,
- 0x2c, 0x4f, 0x27, 0xe5, 0xa7, 0xea, 0x31, 0xfe, 0x8d, 0x82, 0x0f, 0xfb,
- 0x29, 0x6e, 0xbc, 0x6f, 0xd4, 0xe0, 0x60, 0xbd, 0x96, 0xe0, 0x7a, 0xfa,
- 0xb1, 0x12, 0xf7, 0x25, 0x77, 0xe2, 0x2e, 0xfe, 0x8d, 0x47, 0xe9, 0x5a,
- 0xe7, 0x5c, 0x1e, 0xdd, 0x23, 0x6c, 0xc0, 0x74, 0x2c, 0xae, 0xdf, 0x85,
- 0xe5, 0x23, 0xac, 0xc7, 0x40, 0x47, 0x90, 0x64, 0xf4, 0x28, 0xd9, 0x85,
- 0x64, 0x76, 0x42, 0x19, 0xb1, 0xed, 0xeb, 0xe3, 0x97, 0xcf, 0xa1, 0x0f,
- 0x9c, 0x93, 0xa9, 0xbe, 0x93, 0x79, 0x4f, 0x4c, 0x4b, 0x9c, 0x10, 0x97,
- 0xcf, 0xf9, 0x87, 0x44, 0x33, 0xcf, 0x5b, 0xc9, 0x4b, 0xc7, 0x29, 0x2f,
- 0xbd, 0x3c, 0xca, 0x3e, 0xd2, 0xe6, 0xf8, 0x88, 0x44, 0xb1, 0x76, 0x43,
- 0x3a, 0x84, 0x73, 0x06, 0xf4, 0x2a, 0xc4, 0x88, 0xee, 0x48, 0x4f, 0xe7,
- 0x02, 0xe6, 0x73, 0x53, 0xfc, 0x9f, 0x19, 0xe5, 0x7d, 0x2a, 0x81, 0x5a,
- 0x9d, 0x6d, 0xc0, 0xc9, 0x05, 0x14, 0xd3, 0x06, 0x50, 0x77, 0x2d, 0x70,
- 0x71, 0x84, 0xf7, 0xcc, 0x74, 0xec, 0x2f, 0x0d, 0x8a, 0xc6, 0x91, 0x7f,
- 0xb0, 0x43, 0xd5, 0x8b, 0xfb, 0x67, 0x0f, 0xf2, 0xfe, 0x19, 0xd9, 0xc0,
- 0x80, 0x73, 0x46, 0xe6, 0xad, 0x34, 0x9f, 0x91, 0x09, 0x87, 0x36, 0x93,
- 0xef, 0x6c, 0x43, 0x8b, 0x31, 0x4b, 0xd8, 0x79, 0x9e, 0xe8, 0x6c, 0x16,
- 0x95, 0x3d, 0xa2, 0xc8, 0xc2, 0x1e, 0xd7, 0xca, 0x7c, 0x97, 0xa8, 0x2d,
- 0x30, 0x4d, 0x71, 0xa2, 0xa9, 0x53, 0xd4, 0x1c, 0xdb, 0x28, 0x7c, 0xc7,
- 0xba, 0x85, 0x54, 0xe0, 0x98, 0x1c, 0xeb, 0xd8, 0x3d, 0xca, 0xf9, 0x6c,
- 0x8b, 0x70, 0x1d, 0xed, 0x15, 0xde, 0x42, 0x9f, 0xf0, 0x1f, 0xb3, 0x70,
- 0x6f, 0xbc, 0x1b, 0x67, 0xc6, 0xf8, 0x1c, 0xd8, 0x3d, 0xa2, 0x76, 0x61,
- 0x5f, 0xcb, 0x5b, 0x68, 0xf2, 0x17, 0x68, 0x7d, 0xc2, 0x12, 0x1d, 0xe9,
- 0x91, 0x65, 0xfe, 0x27, 0x26, 0x03, 0xfe, 0xc7, 0x26, 0xb5, 0x81, 0xbd,
- 0xc2, 0xb6, 0x77, 0xc6, 0xa6, 0x59, 0x87, 0x76, 0x4b, 0xac, 0x82, 0x0f,
- 0x76, 0x91, 0x3c, 0xb6, 0x53, 0x6e, 0x99, 0x36, 0x5a, 0x16, 0xb0, 0x88,
- 0x96, 0xe2, 0xdf, 0x8b, 0xd1, 0xa7, 0x87, 0x73, 0x1b, 0xef, 0x09, 0xba,
- 0xda, 0x41, 0x71, 0xf7, 0x33, 0x5e, 0x6b, 0x47, 0xf8, 0x7c, 0xd7, 0x00,
- 0xfc, 0x5f, 0xb2, 0x27, 0x76, 0xe6, 0xb3, 0x3d, 0xb1, 0xc4, 0x63, 0x42,
- 0x2b, 0xcf, 0x11, 0xbf, 0xd5, 0xf2, 0xe7, 0xf6, 0xc3, 0x16, 0xf6, 0xc2,
- 0xba, 0x84, 0xaf, 0xc0, 0xf5, 0x79, 0xbc, 0xe3, 0xf5, 0x91, 0x4e, 0xe1,
- 0x3d, 0x36, 0x46, 0xf9, 0x71, 0x23, 0xf1, 0xcc, 0xe7, 0xae, 0xba, 0x85,
- 0xbf, 0xb0, 0x45, 0xf8, 0x88, 0xcf, 0x1a, 0xe2, 0x13, 0xc7, 0x3c, 0xc2,
- 0x4b, 0x3c, 0x7a, 0x88, 0x47, 0xef, 0x02, 0x8f, 0x9e, 0x42, 0xd0, 0x9f,
- 0x4e, 0x37, 0xf8, 0x1f, 0x9e, 0x54, 0xfd, 0x7b, 0x27, 0x6d, 0xfb, 0x3d,
- 0xe3, 0x67, 0x0e, 0x5f, 0xaf, 0x1a, 0x5f, 0xe4, 0xeb, 0x3a, 0xe2, 0xab,
- 0xb2, 0x8f, 0x49, 0x3a, 0x4c, 0xb1, 0x0e, 0xf9, 0x0c, 0xc4, 0x22, 0x5f,
- 0x07, 0xd2, 0xbc, 0x8f, 0xc1, 0x7b, 0x7e, 0x83, 0x62, 0x35, 0xf1, 0x55,
- 0x26, 0xbe, 0xae, 0xf9, 0x12, 0xbe, 0x3e, 0xbc, 0x8c, 0xaf, 0x57, 0xff,
- 0x51, 0xbe, 0x3c, 0x62, 0xd5, 0x18, 0xc7, 0xa1, 0xfb, 0x3b, 0x94, 0x31,
- 0x9b, 0xb0, 0xa3, 0x8c, 0xc7, 0x67, 0x80, 0x62, 0x76, 0x08, 0x0a, 0xc5,
- 0x9b, 0x93, 0xf1, 0x48, 0xe8, 0x15, 0xaa, 0x27, 0x67, 0x4b, 0x5e, 0xb1,
- 0xd2, 0xd9, 0xcf, 0xc4, 0x6a, 0x85, 0x68, 0x9a, 0x73, 0x7e, 0x9f, 0x05,
- 0xa3, 0x4e, 0x67, 0x5d, 0xea, 0xa7, 0xb7, 0x22, 0x52, 0x8e, 0xc8, 0xdd,
- 0x22, 0x51, 0xe0, 0xfd, 0xcb, 0x5e, 0x71, 0x8d, 0xb3, 0x77, 0xd9, 0x25,
- 0xae, 0x2e, 0x74, 0x8a, 0x56, 0xb2, 0x8b, 0x96, 0x63, 0x7c, 0x96, 0x6a,
- 0x8b, 0x68, 0x59, 0x90, 0xc7, 0x2a, 0x92, 0xc7, 0xc8, 0xe7, 0xe4, 0xb1,
- 0xc4, 0xcf, 0xf2, 0xf8, 0x91, 0x71, 0xe1, 0xb2, 0x1e, 0x1a, 0xd7, 0x55,
- 0x94, 0x0d, 0xa9, 0x76, 0xaa, 0x5b, 0xa8, 0x9d, 0xde, 0x8e, 0xf1, 0x19,
- 0x19, 0xcb, 0xae, 0xd5, 0x11, 0x72, 0x99, 0x5a, 0xdf, 0x49, 0xa1, 0xa7,
- 0xee, 0x11, 0xc9, 0xcd, 0x3e, 0xaa, 0x7f, 0x76, 0xc4, 0x22, 0xc9, 0x55,
- 0x22, 0x92, 0x70, 0x09, 0xce, 0x2b, 0x86, 0x52, 0x5d, 0xb4, 0xb0, 0x97,
- 0xe2, 0xdb, 0x4b, 0xa3, 0x12, 0x61, 0x07, 0xfe, 0xcd, 0x96, 0x0b, 0xd7,
- 0xab, 0x3e, 0x1c, 0x21, 0xdc, 0xf1, 0x68, 0xb6, 0x1f, 0x47, 0xf2, 0xdb,
- 0xf0, 0x68, 0xfe, 0xd7, 0x7e, 0x9f, 0xa2, 0x78, 0xcd, 0x9e, 0x6b, 0x2b,
- 0xfb, 0xf8, 0xd1, 0xc4, 0x55, 0x11, 0x96, 0xcd, 0x4f, 0x5b, 0x94, 0x08,
- 0xd7, 0xba, 0x89, 0xeb, 0x7e, 0xae, 0xb3, 0x2f, 0xa6, 0xdb, 0x4f, 0x39,
- 0x58, 0xe4, 0xed, 0xb6, 0x63, 0xce, 0xf9, 0xa2, 0x5f, 0xae, 0xde, 0xed,
- 0xfc, 0x7e, 0x32, 0xb9, 0xf6, 0x76, 0x9d, 0xfd, 0xe1, 0xa7, 0x6b, 0x36,
- 0x38, 0xf9, 0xd5, 0x5c, 0x57, 0xf9, 0x6d, 0x49, 0x62, 0x5d, 0xa5, 0x57,
- 0x13, 0x5f, 0x17, 0x75, 0xae, 0xc9, 0x75, 0x95, 0x7d, 0xe2, 0x9e, 0x75,
- 0xcd, 0xce, 0xb5, 0x6b, 0x5d, 0xc5, 0xa7, 0x3a, 0xd7, 0xe9, 0xce, 0xb5,
- 0x77, 0x5d, 0x25, 0x2f, 0x77, 0xaf, 0x5b, 0x71, 0xe9, 0x37, 0x29, 0xfc,
- 0xf7, 0x7f, 0x00, 0x2f, 0xc1, 0x67, 0x8a, 0x54, 0x3a, 0x00, 0x00, 0x00 };
+ 0xc5, 0x7b, 0x7b, 0x74, 0x1c, 0x55, 0x9a, 0xdf, 0xef, 0x56, 0x3f, 0x54,
+ 0xdd, 0x6a, 0xb5, 0x4a, 0x72, 0xdb, 0x6e, 0xed, 0x68, 0xc6, 0x5d, 0xee,
+ 0x6a, 0xb9, 0xb1, 0x84, 0x5d, 0x2d, 0xb5, 0xec, 0x66, 0x5d, 0xb1, 0x7b,
+ 0x8c, 0xb0, 0x65, 0x10, 0x3b, 0xc2, 0xeb, 0x9d, 0x88, 0x09, 0x27, 0xf4,
+ 0x18, 0x19, 0x64, 0x63, 0x40, 0x30, 0x64, 0xa3, 0xd9, 0x25, 0xeb, 0x1a,
+ 0xf9, 0x81, 0x1f, 0xad, 0xee, 0xd6, 0xc3, 0xc8, 0xec, 0xd9, 0x13, 0x64,
+ 0x49, 0xb6, 0xcc, 0xd0, 0x0f, 0x33, 0xc0, 0xcc, 0x30, 0x27, 0x13, 0x77,
+ 0x8c, 0x01, 0x03, 0x63, 0x98, 0xdd, 0x6c, 0x92, 0x99, 0x3d, 0x49, 0xd6,
+ 0x07, 0xf3, 0xb0, 0xc1, 0x60, 0x32, 0x43, 0x12, 0xb1, 0xcb, 0x4c, 0xe5,
+ 0xfb, 0xaa, 0x25, 0x63, 0x58, 0xb2, 0x9b, 0x6c, 0xfe, 0x88, 0xce, 0xd1,
+ 0xe9, 0xee, 0xaa, 0x5b, 0xf7, 0x7e, 0xef, 0xef, 0xf7, 0x7d, 0xf7, 0x56,
+ 0x04, 0xf0, 0x62, 0xee, 0xaf, 0x86, 0xfe, 0xe3, 0xfd, 0x03, 0x0f, 0xb7,
+ 0xae, 0x88, 0xaf, 0xa0, 0xaf, 0x6d, 0x58, 0xec, 0x74, 0xf2, 0xcd, 0x55,
+ 0x02, 0x48, 0xbd, 0x87, 0x7f, 0xd4, 0xdf, 0x57, 0xff, 0x71, 0x8f, 0xc1,
+ 0x01, 0x28, 0xf3, 0x34, 0xf1, 0x3f, 0x64, 0xc9, 0x30, 0xd7, 0xac, 0xd7,
+ 0x20, 0x3b, 0x8c, 0xc4, 0xda, 0xbb, 0x34, 0x20, 0x99, 0x6f, 0x0e, 0xdd,
+ 0x88, 0xdf, 0x58, 0x66, 0xc0, 0x09, 0xbe, 0xfe, 0x55, 0xe3, 0xd3, 0x5d,
+ 0x3f, 0x5d, 0xad, 0x7e, 0x34, 0xe1, 0x80, 0xac, 0x18, 0x63, 0x50, 0x9a,
+ 0x20, 0x37, 0xd2, 0x33, 0x7f, 0xb6, 0xec, 0x79, 0x27, 0xfc, 0xf3, 0x73,
+ 0xc1, 0x74, 0x19, 0x3a, 0x76, 0x67, 0xfb, 0x31, 0x13, 0x07, 0x2e, 0xa6,
+ 0x23, 0xfa, 0x6e, 0x20, 0x27, 0x19, 0x91, 0xd0, 0x69, 0x84, 0x30, 0x9d,
+ 0x87, 0x59, 0x65, 0x68, 0xd8, 0x5f, 0x0a, 0xe1, 0x52, 0xfa, 0xb7, 0x56,
+ 0xc8, 0xd5, 0x8f, 0xb7, 0xe2, 0x90, 0x83, 0xc6, 0x23, 0x08, 0x66, 0x21,
+ 0xd7, 0x18, 0x03, 0x28, 0x0c, 0x01, 0x7b, 0xd3, 0x6a, 0x3f, 0xa0, 0xf6,
+ 0x14, 0x45, 0xf8, 0xec, 0x09, 0xa8, 0xdd, 0x0d, 0x8e, 0xe6, 0xd4, 0xed,
+ 0x42, 0x4d, 0xee, 0x14, 0x90, 0x05, 0x8d, 0x5d, 0x9e, 0xe7, 0xcf, 0x01,
+ 0x44, 0xf3, 0x32, 0xce, 0x3b, 0x78, 0x59, 0x83, 0xe4, 0x2c, 0xe0, 0xd4,
+ 0x74, 0xec, 0xcd, 0xc2, 0x74, 0x1a, 0x02, 0xbb, 0xe3, 0x11, 0x65, 0x0a,
+ 0x7c, 0x3f, 0x84, 0x41, 0x7b, 0x9c, 0x4a, 0x1c, 0x5b, 0xd6, 0x1e, 0xdd,
+ 0xb2, 0x8e, 0xe9, 0x55, 0x30, 0x15, 0x35, 0x08, 0x08, 0x0c, 0xea, 0x12,
+ 0x92, 0xca, 0xfa, 0x90, 0x13, 0x6a, 0x70, 0x1b, 0xfe, 0x96, 0xf8, 0x4d,
+ 0x46, 0x5d, 0xa8, 0x8c, 0x4f, 0xa1, 0x0a, 0x65, 0xa5, 0x22, 0xb1, 0xc9,
+ 0xb4, 0x65, 0xbd, 0xa4, 0x39, 0x71, 0x8c, 0x64, 0x33, 0x98, 0xff, 0x5b,
+ 0xab, 0x4c, 0x72, 0xd9, 0xa3, 0xcd, 0xaf, 0x2f, 0x63, 0x42, 0xb1, 0xac,
+ 0x29, 0xba, 0xb7, 0x2f, 0x3f, 0x2f, 0x63, 0xcb, 0x92, 0x34, 0xcb, 0xba,
+ 0x4b, 0xfb, 0x1b, 0x6b, 0xeb, 0xe7, 0xc6, 0xc6, 0xf0, 0xfd, 0x9c, 0x82,
+ 0xa7, 0xb2, 0x49, 0xe4, 0xd3, 0x16, 0x1c, 0x86, 0x13, 0x7d, 0x43, 0x21,
+ 0xec, 0x2c, 0x74, 0xa0, 0x90, 0x56, 0x53, 0xe7, 0xe9, 0xb9, 0xad, 0x71,
+ 0x0d, 0xf7, 0x15, 0x3a, 0x31, 0x93, 0x86, 0xe5, 0x31, 0xb4, 0xb2, 0x47,
+ 0x44, 0x71, 0x4f, 0xa1, 0x0b, 0xc5, 0xb4, 0x76, 0x76, 0x50, 0x44, 0x06,
+ 0x1a, 0x1c, 0x4e, 0x3c, 0x50, 0x68, 0xc1, 0xfd, 0x85, 0x04, 0x3d, 0x63,
+ 0xe1, 0xe6, 0x58, 0x23, 0x8d, 0x6f, 0xc5, 0x93, 0x63, 0x96, 0x15, 0x8d,
+ 0x29, 0xe8, 0x2b, 0xe8, 0x98, 0xc9, 0x49, 0x48, 0x1d, 0x73, 0x22, 0x75,
+ 0x14, 0xb8, 0xe7, 0x68, 0x2b, 0xa6, 0x72, 0x16, 0xb6, 0xea, 0x83, 0x0d,
+ 0x12, 0x5c, 0x48, 0x29, 0x02, 0x2e, 0xcd, 0x8f, 0x6d, 0x4a, 0x85, 0xf6,
+ 0xf3, 0x0e, 0x81, 0x1d, 0x47, 0xa3, 0xf8, 0x45, 0xda, 0xc4, 0xcd, 0xed,
+ 0x41, 0x0c, 0x14, 0x02, 0x78, 0x23, 0x1d, 0xa0, 0x35, 0x74, 0xbc, 0x9e,
+ 0x96, 0x69, 0x9d, 0x16, 0x9c, 0x49, 0xf3, 0x18, 0x1e, 0xeb, 0x43, 0x6f,
+ 0xa1, 0x11, 0xe7, 0xd2, 0x41, 0x5a, 0x33, 0x80, 0x57, 0x68, 0xdc, 0xf6,
+ 0x82, 0x86, 0xb3, 0x34, 0xae, 0xaf, 0x10, 0xc2, 0xcb, 0x69, 0x1f, 0xd1,
+ 0x1a, 0xc0, 0xe9, 0x74, 0x3f, 0x76, 0xa7, 0x9b, 0xcf, 0xde, 0x48, 0x32,
+ 0x0c, 0x2d, 0xe0, 0x75, 0xf8, 0xda, 0x5b, 0x56, 0x57, 0xc0, 0x36, 0x13,
+ 0x5a, 0x67, 0x7e, 0xdd, 0x7e, 0x0c, 0xa6, 0xcf, 0xcc, 0xf9, 0x89, 0x8e,
+ 0x03, 0xb9, 0x59, 0xeb, 0xa7, 0xcb, 0x1a, 0x71, 0x22, 0x0b, 0x3c, 0x39,
+ 0x05, 0x4c, 0x65, 0x4d, 0xab, 0xc6, 0xb0, 0xac, 0xc9, 0xf6, 0x16, 0x92,
+ 0x97, 0xd6, 0xb3, 0x95, 0x46, 0x3d, 0x55, 0x72, 0x02, 0x47, 0xd5, 0x9e,
+ 0x32, 0x24, 0x4c, 0xcc, 0x38, 0xe1, 0x1e, 0x52, 0x3b, 0x27, 0xa0, 0x9e,
+ 0xbd, 0x87, 0x3c, 0xe9, 0x58, 0x56, 0xed, 0x36, 0xb1, 0xcb, 0x0a, 0x1a,
+ 0x4d, 0xa1, 0x16, 0x87, 0x05, 0x3f, 0xd9, 0x42, 0xba, 0xc5, 0xb2, 0x6a,
+ 0x57, 0x5b, 0xd6, 0xb9, 0x76, 0x58, 0x92, 0xa1, 0x9d, 0x2d, 0x41, 0x2b,
+ 0x7f, 0x00, 0x6d, 0xe0, 0x34, 0xca, 0x5f, 0xf5, 0x21, 0xd2, 0x17, 0x76,
+ 0x44, 0xfa, 0x67, 0xe9, 0xd9, 0x9a, 0x02, 0x99, 0x32, 0xf1, 0xa2, 0x91,
+ 0x0d, 0x16, 0x4a, 0x32, 0x9c, 0xc4, 0x4f, 0xcb, 0x90, 0x65, 0x39, 0x35,
+ 0x1f, 0x7c, 0x24, 0xdf, 0x8d, 0x87, 0x2d, 0xeb, 0x1d, 0x5d, 0x81, 0x9b,
+ 0x74, 0x73, 0xd3, 0xb0, 0x85, 0x49, 0xfd, 0x34, 0xc9, 0x53, 0x20, 0xd5,
+ 0x1d, 0xa7, 0x67, 0x02, 0x34, 0x3e, 0x81, 0x8d, 0x43, 0x41, 0x7c, 0x3f,
+ 0x2b, 0xe3, 0xa7, 0xcb, 0xa2, 0xa8, 0xa6, 0xb9, 0xbc, 0x24, 0xab, 0x2a,
+ 0x92, 0x1f, 0x0a, 0x64, 0x6e, 0x85, 0x8a, 0x3d, 0xa2, 0x70, 0x9e, 0x78,
+ 0x0c, 0xe2, 0x07, 0xa5, 0x00, 0x9e, 0x2e, 0x29, 0x38, 0x59, 0x6a, 0xc4,
+ 0xa9, 0x92, 0x8e, 0x6c, 0x4e, 0xdd, 0x5f, 0x86, 0x85, 0x1a, 0x32, 0xe7,
+ 0x37, 0x26, 0x62, 0xc8, 0xe4, 0x2c, 0x2b, 0x4f, 0x34, 0x7b, 0x89, 0x87,
+ 0xd7, 0x27, 0xbe, 0x86, 0xe3, 0x63, 0x4e, 0x84, 0x26, 0x03, 0x78, 0x2a,
+ 0xed, 0xc4, 0x75, 0x19, 0xd5, 0x9c, 0x80, 0x16, 0xdd, 0x29, 0xb4, 0xe4,
+ 0x72, 0xa1, 0xe6, 0x4c, 0x44, 0x42, 0x2e, 0x21, 0xa1, 0xe9, 0xb8, 0x13,
+ 0x5a, 0x31, 0x04, 0x57, 0x93, 0x0c, 0xad, 0x89, 0xdc, 0xc8, 0x2f, 0xc1,
+ 0x4d, 0x7e, 0xb1, 0x71, 0x24, 0x4a, 0xd7, 0x02, 0x74, 0x0d, 0x5f, 0xab,
+ 0x82, 0x63, 0x91, 0x03, 0x24, 0x37, 0xcd, 0x81, 0xa4, 0xd3, 0xb2, 0x1c,
+ 0x5a, 0x2b, 0x7a, 0x1e, 0xa3, 0xcf, 0x36, 0x1e, 0xaf, 0x20, 0x5c, 0x24,
+ 0x19, 0x34, 0x11, 0x4d, 0x59, 0xa2, 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6,
+ 0xac, 0x83, 0x6c, 0x46, 0xd5, 0x81, 0x3f, 0x22, 0x5d, 0x85, 0x88, 0xbf,
+ 0x5f, 0xd8, 0x7a, 0x7a, 0xba, 0x14, 0x24, 0xfa, 0x43, 0x36, 0xfd, 0x4f,
+ 0xe6, 0x04, 0x24, 0x4d, 0xed, 0x3e, 0x8f, 0x75, 0x08, 0xc7, 0xd4, 0xe4,
+ 0x04, 0x92, 0xf4, 0x9c, 0xba, 0xdf, 0x84, 0xda, 0x59, 0x26, 0xfd, 0x6f,
+ 0x55, 0x12, 0x98, 0xc9, 0xba, 0x50, 0xad, 0xa9, 0x21, 0xd2, 0x57, 0xb4,
+ 0x8c, 0x05, 0xb8, 0x57, 0xa1, 0x39, 0x25, 0xb7, 0xa8, 0xc4, 0x90, 0x47,
+ 0x10, 0x19, 0x91, 0x30, 0xad, 0x3b, 0xc8, 0x3f, 0x75, 0x38, 0x9a, 0x68,
+ 0xb9, 0x62, 0x9c, 0x3e, 0x69, 0xfe, 0x2c, 0xad, 0x45, 0xf4, 0xd0, 0x7c,
+ 0xe4, 0x97, 0x2c, 0xc7, 0x28, 0xd1, 0xb0, 0xd7, 0xa6, 0xf7, 0x64, 0xa9,
+ 0x4b, 0x54, 0xec, 0xc7, 0x20, 0x7b, 0x51, 0x43, 0x10, 0x6a, 0x34, 0x24,
+ 0x54, 0x3d, 0x29, 0x14, 0x4c, 0x95, 0x7e, 0x46, 0x63, 0x02, 0xd7, 0x8c,
+ 0xe9, 0xc6, 0x60, 0x56, 0xe0, 0x46, 0xcd, 0xc2, 0x7a, 0xbd, 0x1b, 0xbb,
+ 0x4b, 0xf3, 0x7e, 0xc9, 0xb1, 0x4b, 0xf1, 0x4f, 0xa5, 0x3b, 0xb0, 0x27,
+ 0x1b, 0xc2, 0xee, 0x7c, 0xd0, 0x3f, 0x99, 0xe6, 0x7b, 0x1a, 0xf9, 0x3b,
+ 0xdf, 0x0b, 0x5c, 0x73, 0xaf, 0xf1, 0x9a, 0x7b, 0x09, 0x0c, 0x8e, 0x7e,
+ 0x85, 0x62, 0x48, 0x2d, 0x76, 0x6b, 0x1f, 0x91, 0xad, 0x68, 0x89, 0x5e,
+ 0x34, 0xe0, 0xbc, 0xd2, 0x82, 0x43, 0xe3, 0x5d, 0xd8, 0x33, 0xbe, 0x02,
+ 0x07, 0x46, 0x1b, 0x53, 0x5e, 0x63, 0x88, 0xd6, 0x0f, 0x27, 0x7b, 0x85,
+ 0xda, 0xef, 0x10, 0xe1, 0x68, 0x2f, 0xd9, 0x6e, 0x53, 0x9d, 0x65, 0x9d,
+ 0x8e, 0x91, 0x6d, 0xeb, 0xcd, 0xfa, 0x46, 0x12, 0x40, 0xb9, 0x5b, 0xed,
+ 0x7c, 0x0b, 0x3e, 0xdc, 0x4a, 0x36, 0x37, 0x15, 0x43, 0xaf, 0x03, 0x8e,
+ 0x16, 0x1f, 0x7e, 0x6d, 0x1d, 0x75, 0xb2, 0xdc, 0xad, 0x5d, 0x77, 0xe9,
+ 0x7b, 0x05, 0xc7, 0x39, 0xf7, 0xd5, 0x58, 0xc2, 0xf3, 0xf3, 0x33, 0x96,
+ 0x15, 0xa6, 0x79, 0xfa, 0x62, 0xcd, 0x89, 0x3e, 0xcc, 0x5a, 0xe7, 0xb7,
+ 0x74, 0x61, 0xf7, 0xcc, 0x0a, 0x1c, 0x1c, 0x75, 0x21, 0x59, 0x27, 0x50,
+ 0xab, 0x85, 0xcb, 0xf7, 0x62, 0x05, 0xcc, 0x29, 0x7e, 0xae, 0x0b, 0x47,
+ 0x66, 0x2a, 0xbf, 0xb3, 0x57, 0x7f, 0xcf, 0xcf, 0x77, 0x91, 0x74, 0xca,
+ 0xf2, 0xe4, 0x38, 0x49, 0x2a, 0x30, 0x9a, 0x71, 0x62, 0x34, 0x40, 0xba,
+ 0xed, 0x10, 0xce, 0xe3, 0x8b, 0xfc, 0xde, 0xc7, 0x2c, 0xbc, 0xa4, 0x93,
+ 0x9e, 0xb3, 0x1b, 0x84, 0xf7, 0x78, 0xa7, 0x70, 0x15, 0x37, 0x0b, 0xf7,
+ 0xe4, 0xb7, 0x84, 0x7c, 0x3c, 0x25, 0xaa, 0x8a, 0x2d, 0x24, 0xfb, 0x1e,
+ 0xe1, 0x39, 0xae, 0x86, 0x42, 0xe2, 0xbb, 0xa4, 0xcf, 0x2d, 0xc2, 0x51,
+ 0x84, 0x22, 0x19, 0x03, 0x42, 0x2a, 0xd2, 0x1c, 0xb6, 0x0d, 0xf1, 0x3a,
+ 0x41, 0xd2, 0x1b, 0x4c, 0x87, 0xd1, 0x8f, 0xad, 0x94, 0x23, 0x6e, 0x49,
+ 0x1b, 0x38, 0x98, 0xad, 0xa2, 0xf8, 0xc8, 0x7e, 0x3f, 0x4b, 0xeb, 0x6a,
+ 0x38, 0x54, 0x82, 0xe9, 0x31, 0x0e, 0x62, 0x05, 0xf9, 0xdb, 0xb9, 0x18,
+ 0xfb, 0x22, 0x90, 0xcf, 0x86, 0x93, 0x07, 0x85, 0x65, 0x55, 0x45, 0xac,
+ 0x25, 0xef, 0xe8, 0xcd, 0xd1, 0x33, 0xf8, 0x9f, 0xd6, 0x44, 0xa0, 0x1f,
+ 0xd1, 0x76, 0xc8, 0x55, 0xc6, 0x1e, 0xbc, 0x9b, 0x86, 0xec, 0x36, 0x4c,
+ 0xbc, 0x94, 0x06, 0x7c, 0x43, 0x83, 0x8a, 0x17, 0x64, 0x07, 0x08, 0x07,
+ 0x0f, 0x09, 0xb5, 0xfb, 0x02, 0xa5, 0xb3, 0x44, 0xbb, 0x39, 0x20, 0x81,
+ 0xe2, 0x91, 0x50, 0x7b, 0xce, 0x90, 0x3d, 0x7e, 0x57, 0xa8, 0xca, 0xac,
+ 0x60, 0x3f, 0xe5, 0x5c, 0xb2, 0x67, 0x2e, 0xa7, 0x98, 0xb8, 0xee, 0x9a,
+ 0x9c, 0x32, 0x48, 0x74, 0xed, 0x23, 0xba, 0x5e, 0xd4, 0xd5, 0xe0, 0x24,
+ 0xac, 0x25, 0xbd, 0x3a, 0xdf, 0x33, 0xb0, 0xa7, 0x64, 0x85, 0x1c, 0x06,
+ 0xcb, 0x0a, 0xa9, 0x2a, 0x03, 0xa6, 0x6c, 0x28, 0xe4, 0x1b, 0xbf, 0xb1,
+ 0x7a, 0xe3, 0xb2, 0xfe, 0x76, 0x5e, 0x21, 0x79, 0xc1, 0xef, 0x2c, 0x7c,
+ 0x59, 0xde, 0xb5, 0x20, 0x19, 0xbf, 0xb1, 0xee, 0x8c, 0xc3, 0xbf, 0xa4,
+ 0xe0, 0x4c, 0x55, 0x1b, 0xe8, 0x1e, 0x18, 0xda, 0x65, 0x35, 0x68, 0x12,
+ 0xc5, 0x29, 0x8d, 0xe2, 0xba, 0x2f, 0x71, 0xb9, 0xdd, 0x23, 0xce, 0xb5,
+ 0x07, 0xbb, 0x3e, 0xc8, 0x7b, 0x48, 0xcf, 0xe8, 0xde, 0x59, 0x48, 0x38,
+ 0xdf, 0x23, 0x5b, 0x73, 0x53, 0x4c, 0x45, 0xa1, 0xb1, 0xeb, 0x12, 0xe5,
+ 0xa1, 0x9b, 0x62, 0x9e, 0x7f, 0xea, 0x36, 0xa4, 0xaf, 0x79, 0xf0, 0xe0,
+ 0xca, 0xe9, 0x44, 0x2d, 0xc5, 0x75, 0x05, 0x67, 0xe3, 0x9d, 0x18, 0x2c,
+ 0x55, 0x91, 0x1d, 0x3e, 0x53, 0xde, 0xab, 0x35, 0x76, 0xbd, 0x9f, 0x5e,
+ 0xc2, 0x71, 0xe4, 0xd3, 0x7c, 0xbb, 0xd6, 0xbd, 0x53, 0x9c, 0xde, 0xe4,
+ 0x45, 0x1c, 0x07, 0x4a, 0xb2, 0xfc, 0x49, 0x1a, 0x1f, 0x2d, 0xd1, 0xb4,
+ 0xf2, 0x3a, 0x47, 0x53, 0xbf, 0xec, 0x68, 0x1a, 0x70, 0x53, 0x0c, 0xbe,
+ 0x78, 0xbd, 0xc0, 0x4b, 0xd7, 0x47, 0x12, 0x6e, 0xe1, 0xc1, 0xf9, 0xee,
+ 0x04, 0xd9, 0x49, 0x63, 0xca, 0x63, 0x50, 0xfc, 0x20, 0x93, 0x75, 0x68,
+ 0x09, 0xec, 0x9e, 0xc2, 0x23, 0x83, 0x7a, 0x17, 0xcc, 0x19, 0xb6, 0xa1,
+ 0x16, 0x0c, 0xce, 0x74, 0xc3, 0x2c, 0x39, 0x30, 0x11, 0x20, 0xe6, 0x4b,
+ 0x48, 0xb9, 0x8c, 0x96, 0x8e, 0x89, 0x7c, 0xaf, 0xab, 0xe2, 0xc3, 0xc4,
+ 0x7f, 0xf6, 0xa8, 0x1f, 0x5e, 0xd6, 0xf3, 0x59, 0x92, 0x51, 0x0b, 0x9e,
+ 0x29, 0x45, 0x29, 0xd6, 0xe9, 0x24, 0x17, 0x8d, 0xe2, 0x45, 0x88, 0xec,
+ 0x4b, 0xc6, 0xd6, 0x51, 0xf5, 0x08, 0xc5, 0x85, 0xdc, 0x04, 0xda, 0x91,
+ 0x0c, 0x28, 0x94, 0xbb, 0x5f, 0x9a, 0x8b, 0x01, 0xdb, 0xe8, 0x53, 0x35,
+ 0x93, 0xc0, 0x19, 0x09, 0x68, 0x6d, 0x30, 0x22, 0xfb, 0x1b, 0x48, 0x1f,
+ 0x75, 0x45, 0x0f, 0x1e, 0x18, 0xad, 0xc7, 0xfd, 0xe3, 0x5e, 0xec, 0x18,
+ 0xb5, 0x70, 0x39, 0xc6, 0xb6, 0xa1, 0xf6, 0x10, 0x89, 0x1d, 0xd5, 0x24,
+ 0xd7, 0x4d, 0xb1, 0x48, 0xc2, 0x23, 0x9c, 0xa8, 0x2a, 0x76, 0x13, 0x06,
+ 0x48, 0xb2, 0x5f, 0xe8, 0x34, 0x47, 0x68, 0xb7, 0x7e, 0x2b, 0x52, 0x01,
+ 0x19, 0xae, 0xa2, 0x8f, 0x62, 0x09, 0xfb, 0x31, 0xdf, 0xfb, 0x06, 0xb6,
+ 0xba, 0x7d, 0x70, 0x64, 0x64, 0xe4, 0x28, 0xff, 0x63, 0x91, 0x1b, 0x9d,
+ 0x4d, 0x12, 0xfd, 0x07, 0xfc, 0xd3, 0x63, 0x8d, 0xfe, 0x63, 0x14, 0x5f,
+ 0xef, 0xc9, 0x4a, 0xbc, 0x0e, 0xe3, 0x05, 0x9a, 0x5b, 0xc1, 0x93, 0x14,
+ 0xab, 0x1f, 0xa2, 0xf8, 0x73, 0xa2, 0x94, 0x17, 0x1c, 0x4f, 0x6c, 0x7e,
+ 0xb2, 0xc4, 0x5b, 0x96, 0x78, 0xcb, 0x12, 0x5f, 0x14, 0x17, 0x4e, 0x66,
+ 0x99, 0x8f, 0x2b, 0xe4, 0xa3, 0x09, 0xe2, 0xdd, 0x83, 0x6d, 0x44, 0xef,
+ 0x83, 0xe3, 0xd5, 0xb8, 0x8f, 0xe8, 0x2d, 0xea, 0x6a, 0xcf, 0x9f, 0x0b,
+ 0x0b, 0xf9, 0x98, 0x6a, 0xee, 0x14, 0x5e, 0x48, 0x4d, 0x96, 0xd5, 0xad,
+ 0x33, 0xcf, 0x64, 0xa7, 0x92, 0xcd, 0xf3, 0xfe, 0x24, 0x3c, 0xe8, 0xa3,
+ 0x67, 0x7a, 0xc7, 0xf1, 0xa9, 0x44, 0x3c, 0x79, 0x88, 0xc7, 0x83, 0xba,
+ 0x9a, 0x58, 0x4e, 0x71, 0xfd, 0x82, 0x16, 0x29, 0x5f, 0x70, 0xe0, 0xeb,
+ 0x24, 0x0f, 0x9d, 0xe5, 0xd1, 0x44, 0xfc, 0x3c, 0x40, 0x58, 0xc7, 0x6f,
+ 0x30, 0x9f, 0x91, 0xe8, 0xaf, 0x89, 0xf7, 0x48, 0x31, 0xe0, 0x3f, 0x77,
+ 0xb8, 0xd1, 0xff, 0xe2, 0x50, 0x85, 0xfe, 0x9d, 0x44, 0xff, 0x74, 0xcc,
+ 0xc2, 0x21, 0xa2, 0xff, 0x29, 0xa2, 0xbf, 0x8f, 0xe3, 0xf9, 0x1c, 0xfd,
+ 0x27, 0x4a, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x3d, 0xb6, 0x8e,
+ 0xcf, 0xcb, 0xcb, 0xb2, 0xee, 0xd4, 0x9f, 0xb5, 0xbe, 0x4d, 0x32, 0x5b,
+ 0x52, 0x64, 0xb9, 0x31, 0x8e, 0x8b, 0x1c, 0xb9, 0x07, 0x7d, 0x12, 0xbc,
+ 0x3e, 0x2c, 0x28, 0x72, 0x2e, 0x08, 0xe1, 0x59, 0xd2, 0xef, 0x29, 0xca,
+ 0x65, 0xcf, 0x94, 0xae, 0xcd, 0x6d, 0xac, 0xeb, 0x31, 0xd2, 0xb1, 0x3a,
+ 0x61, 0x52, 0x6c, 0x4b, 0x95, 0x92, 0xd8, 0x3b, 0x8e, 0xe4, 0xb4, 0xfe,
+ 0xaf, 0x29, 0xc0, 0x2c, 0x22, 0xfb, 0xaa, 0x4a, 0x2a, 0x9a, 0x17, 0x77,
+ 0x4d, 0x05, 0xd0, 0x5f, 0x5a, 0x8f, 0x2c, 0xc5, 0x9b, 0x9d, 0x14, 0x9f,
+ 0x3f, 0x8c, 0x25, 0x77, 0xf8, 0x11, 0x21, 0xfd, 0x06, 0x70, 0x2f, 0x3d,
+ 0x73, 0x70, 0x9c, 0xe9, 0x57, 0xe6, 0xf4, 0x1c, 0xc0, 0x3d, 0x74, 0x6d,
+ 0xdf, 0xb8, 0x8c, 0x17, 0xf4, 0x27, 0x08, 0xcf, 0x54, 0xf0, 0xc5, 0xdd,
+ 0x59, 0x28, 0xe4, 0x9e, 0x84, 0xff, 0x22, 0xd1, 0x17, 0xe8, 0xf7, 0xb6,
+ 0x92, 0xd7, 0x3f, 0x38, 0x86, 0xef, 0x2d, 0x31, 0xfc, 0x58, 0x40, 0x58,
+ 0xec, 0x76, 0x3d, 0x42, 0x76, 0xef, 0xc4, 0x40, 0x49, 0xc2, 0x77, 0xa6,
+ 0xbc, 0x78, 0x68, 0xf4, 0x53, 0xcb, 0x1d, 0x77, 0xe2, 0xb6, 0x26, 0x2f,
+ 0x1e, 0x9c, 0x4a, 0x62, 0xff, 0x38, 0x42, 0x55, 0xb1, 0x61, 0x8a, 0xdd,
+ 0x95, 0x7c, 0x50, 0x4d, 0xbc, 0x1f, 0x18, 0xf7, 0xf9, 0xfb, 0x0e, 0xb3,
+ 0x0c, 0xd6, 0x07, 0x3d, 0x40, 0xb9, 0x2a, 0xe6, 0xc0, 0x36, 0xdd, 0xb1,
+ 0xa0, 0x8a, 0x0c, 0xfd, 0x09, 0x9a, 0x6f, 0x12, 0x8e, 0x57, 0x97, 0x20,
+ 0x72, 0xa4, 0xc1, 0x51, 0xce, 0x2d, 0x40, 0x3d, 0x1e, 0x9a, 0x49, 0x62,
+ 0x98, 0x6c, 0xf4, 0x81, 0xd1, 0xc1, 0xef, 0xd5, 0x51, 0x0c, 0xf1, 0xb7,
+ 0xaa, 0x7d, 0x6f, 0x08, 0x03, 0xf9, 0x88, 0x07, 0x3b, 0xa7, 0x7c, 0xfe,
+ 0x1d, 0x87, 0xad, 0x75, 0x6c, 0x4f, 0xdb, 0x67, 0xea, 0x71, 0xdf, 0x38,
+ 0x5d, 0x1b, 0x65, 0x1b, 0x26, 0x5b, 0x8b, 0x54, 0x11, 0x6f, 0xe1, 0xa4,
+ 0x87, 0xf0, 0x92, 0x23, 0x56, 0x4d, 0xf2, 0xf0, 0xe0, 0x1e, 0xdb, 0x16,
+ 0x14, 0x6c, 0x1b, 0xb7, 0xf0, 0xa6, 0x1e, 0x45, 0x8e, 0xec, 0xfa, 0xc8,
+ 0xb8, 0x3a, 0xdb, 0x41, 0x58, 0xe7, 0x6d, 0x87, 0x7a, 0xa4, 0xc9, 0x91,
+ 0x44, 0x7d, 0x1b, 0xc5, 0xf8, 0x7a, 0xcb, 0xba, 0xbb, 0xb5, 0xb9, 0xff,
+ 0xe7, 0x44, 0x73, 0x9d, 0xb1, 0x08, 0xe5, 0x3a, 0x35, 0x07, 0x34, 0x0f,
+ 0xb8, 0xa5, 0xeb, 0x71, 0x7e, 0x21, 0xc7, 0x41, 0x8e, 0xe5, 0x01, 0x7f,
+ 0x7d, 0xa6, 0x92, 0xe3, 0xea, 0x8b, 0x8d, 0xfe, 0xba, 0x4c, 0xd0, 0x5f,
+ 0x57, 0x84, 0xdf, 0x5d, 0x04, 0x7e, 0x4c, 0xf1, 0x65, 0x41, 0xdb, 0x6f,
+ 0xac, 0x54, 0xbd, 0x8d, 0x07, 0xfd, 0xcf, 0x8f, 0xa9, 0x66, 0x19, 0xea,
+ 0x7e, 0x0a, 0x9b, 0x78, 0x7c, 0xc6, 0xe9, 0x3f, 0x4e, 0xd8, 0xaf, 0x5e,
+ 0x8b, 0x62, 0x1f, 0xe9, 0x73, 0x17, 0xd9, 0xc2, 0xaf, 0xdb, 0x80, 0x03,
+ 0x99, 0x70, 0x48, 0x17, 0x3d, 0x34, 0x31, 0xb0, 0xa7, 0x48, 0x31, 0x5f,
+ 0x4a, 0x52, 0x10, 0x53, 0xa3, 0x94, 0xd6, 0x90, 0xce, 0xb8, 0x60, 0x2e,
+ 0xac, 0xe8, 0xe4, 0xbe, 0xec, 0x29, 0xcb, 0xaf, 0x69, 0x13, 0x45, 0xd2,
+ 0xd9, 0xc3, 0x25, 0x1f, 0x06, 0x08, 0x0f, 0x2c, 0x20, 0x0c, 0xf9, 0x20,
+ 0xd9, 0xc5, 0x03, 0xa3, 0x0e, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x54,
+ 0xc1, 0xa2, 0x0f, 0x4d, 0xb1, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x4b,
+ 0x39, 0xff, 0x99, 0xcf, 0x61, 0x10, 0x55, 0x31, 0xaf, 0xe6, 0xfe, 0x8a,
+ 0x3c, 0x06, 0xc7, 0x99, 0x67, 0xf5, 0x08, 0xa4, 0x24, 0x6e, 0xd2, 0x7f,
+ 0x49, 0x39, 0x81, 0x79, 0x27, 0x0c, 0x3c, 0x1e, 0xc5, 0xa3, 0x59, 0xc2,
+ 0x34, 0xb1, 0xcb, 0xd6, 0x3d, 0x01, 0x96, 0x01, 0xf3, 0xb3, 0xca, 0xc1,
+ 0xf9, 0xb3, 0x9e, 0xb0, 0xef, 0xff, 0xbb, 0xdd, 0xdd, 0x65, 0xa5, 0x6c,
+ 0x2c, 0x4b, 0x18, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0xb4, 0xce,
+ 0x07, 0x38, 0x5f, 0xd7, 0x23, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x44,
+ 0x6f, 0xdd, 0xfd, 0xa0, 0x02, 0xb6, 0x87, 0xe8, 0x35, 0xf6, 0x50, 0x45,
+ 0x34, 0x29, 0xd8, 0x31, 0xc3, 0xf6, 0x6b, 0x5d, 0x59, 0x62, 0xfc, 0xd6,
+ 0xfa, 0x64, 0xb5, 0x76, 0xe4, 0x97, 0xe8, 0xa2, 0xeb, 0x01, 0x7c, 0x87,
+ 0xfc, 0xe8, 0x5e, 0xe2, 0x73, 0x47, 0xfb, 0xbd, 0xb6, 0xdf, 0xee, 0x28,
+ 0xad, 0xa1, 0xeb, 0x2c, 0xef, 0x0e, 0xec, 0xcf, 0xea, 0x48, 0x67, 0xcb,
+ 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x11, 0xc5, 0xd9, 0x67, 0x4b, 0x8c,
+ 0xc9, 0x12, 0x36, 0x1e, 0xfb, 0x61, 0xa9, 0x05, 0xcf, 0x91, 0x4f, 0x3e,
+ 0x43, 0x31, 0xf7, 0x07, 0x36, 0x4e, 0x73, 0x8a, 0x43, 0x69, 0xc2, 0xa4,
+ 0x43, 0x26, 0xd2, 0xf9, 0x10, 0x3c, 0x87, 0xc3, 0xfb, 0x77, 0x08, 0xf5,
+ 0xc7, 0x24, 0x2f, 0xff, 0x81, 0xe9, 0xa5, 0xa8, 0x3a, 0xac, 0x4e, 0x10,
+ 0xdd, 0xfe, 0x47, 0xa7, 0x35, 0xc2, 0xd4, 0x41, 0xff, 0xbe, 0xbc, 0xe2,
+ 0xdf, 0x3b, 0x16, 0xf0, 0xef, 0x9d, 0xae, 0x27, 0x3f, 0x5a, 0xe4, 0x1f,
+ 0x9c, 0x0e, 0xfa, 0x77, 0xa7, 0x1b, 0xfd, 0xbb, 0xf3, 0x6d, 0x08, 0xd5,
+ 0xc3, 0x5c, 0x44, 0x39, 0xe2, 0xbe, 0xd1, 0x6f, 0x62, 0xa2, 0xae, 0x12,
+ 0xf7, 0xfb, 0xc9, 0x36, 0x6a, 0xc9, 0x0e, 0x57, 0x4a, 0xb7, 0xa1, 0xbc,
+ 0xb0, 0x72, 0xed, 0x3b, 0x74, 0xed, 0xa1, 0x56, 0xf8, 0xff, 0xc2, 0x8e,
+ 0xbd, 0xc0, 0x73, 0x64, 0x6b, 0xcf, 0xb6, 0x52, 0x5d, 0x79, 0xd5, 0xd6,
+ 0x9c, 0x14, 0x6f, 0x2d, 0x4b, 0x6f, 0x13, 0x08, 0xb6, 0x6e, 0x00, 0x16,
+ 0xcc, 0xd7, 0x92, 0xc9, 0x09, 0x67, 0x6b, 0x12, 0x4b, 0xb4, 0x8d, 0x78,
+ 0x42, 0xa1, 0x54, 0xd3, 0xfa, 0x75, 0xcc, 0x3d, 0x83, 0xef, 0x8c, 0x7a,
+ 0x90, 0xda, 0xac, 0x60, 0x9a, 0xb0, 0xca, 0x76, 0x9a, 0x7f, 0x59, 0xac,
+ 0x59, 0x99, 0x21, 0x3d, 0x24, 0x15, 0xbe, 0x46, 0x3e, 0xd1, 0xba, 0x8a,
+ 0x7c, 0xa2, 0xb2, 0xfe, 0xd3, 0xa4, 0xaf, 0xdc, 0x4c, 0x14, 0x7b, 0x4b,
+ 0x3f, 0x91, 0x2a, 0xf9, 0x45, 0x9d, 0x48, 0xe2, 0xac, 0x3d, 0xf6, 0xe9,
+ 0xec, 0x1b, 0x56, 0xc8, 0xb6, 0x3b, 0x81, 0xc7, 0x56, 0x44, 0xf6, 0xff,
+ 0x27, 0xa9, 0x81, 0xf8, 0x22, 0xd9, 0x65, 0xed, 0x3a, 0xb2, 0x76, 0xb1,
+ 0xf6, 0x2f, 0xf0, 0x23, 0x85, 0x65, 0x3b, 0x20, 0xf6, 0x53, 0xbd, 0x4a,
+ 0xa5, 0x53, 0xed, 0x02, 0xed, 0x30, 0x9e, 0xe9, 0xe6, 0x6b, 0x01, 0xff,
+ 0x81, 0xb1, 0xa4, 0x14, 0xd0, 0xa0, 0xb8, 0x8c, 0x0e, 0x71, 0x60, 0x7a,
+ 0x91, 0xff, 0xd1, 0xb1, 0x0d, 0xe2, 0xd1, 0xe9, 0x46, 0xff, 0x60, 0xba,
+ 0x53, 0x0c, 0xe6, 0x37, 0x0b, 0x73, 0xe2, 0x5b, 0xc2, 0x9c, 0x4e, 0x09,
+ 0x33, 0xdf, 0x43, 0x9f, 0x5b, 0xc4, 0x58, 0x7e, 0x40, 0xec, 0xcd, 0xf3,
+ 0xfc, 0xa4, 0x2b, 0x5a, 0xe3, 0x87, 0x14, 0x7b, 0x9f, 0xa3, 0xd8, 0xfb,
+ 0x2c, 0xc5, 0xde, 0x67, 0xc8, 0xde, 0x7f, 0x70, 0x15, 0xe3, 0xb2, 0x8d,
+ 0x27, 0x19, 0x9b, 0xf8, 0xff, 0xbc, 0x78, 0x86, 0xf4, 0xcd, 0xb2, 0xfb,
+ 0x37, 0x64, 0xdb, 0x2c, 0x93, 0x87, 0x38, 0x57, 0x90, 0x9e, 0xde, 0xb7,
+ 0x6d, 0xf9, 0xb1, 0x15, 0x8c, 0xa5, 0x06, 0xc4, 0x56, 0xa2, 0x2f, 0xe9,
+ 0x24, 0x0c, 0xa4, 0x11, 0x3e, 0xc9, 0x0e, 0x88, 0xbb, 0xf3, 0x7c, 0xfd,
+ 0x20, 0x76, 0x52, 0x4d, 0x78, 0x28, 0x16, 0xee, 0xee, 0x25, 0xec, 0xb4,
+ 0x89, 0xb0, 0xd3, 0xb2, 0x98, 0x8c, 0x8b, 0x2d, 0x9f, 0x58, 0x58, 0x88,
+ 0xe4, 0xfd, 0x71, 0x75, 0x62, 0xa2, 0x92, 0x6f, 0x73, 0x19, 0x70, 0xdd,
+ 0x8e, 0xda, 0x1a, 0x4d, 0x3d, 0x91, 0x44, 0x78, 0x7f, 0x5c, 0x82, 0xe9,
+ 0x36, 0x5c, 0xb8, 0xcf, 0xae, 0x15, 0xd7, 0x63, 0x74, 0x54, 0x60, 0x5b,
+ 0x6b, 0xf2, 0x8f, 0x5c, 0x24, 0xab, 0xb7, 0xdb, 0x11, 0x20, 0xf5, 0x0a,
+ 0x99, 0xea, 0xfa, 0x4e, 0x92, 0x5e, 0x07, 0xe5, 0xdc, 0x27, 0xb2, 0xab,
+ 0xd0, 0xd0, 0x2a, 0x93, 0x0e, 0x9d, 0xb8, 0xb3, 0x78, 0x13, 0xe9, 0x31,
+ 0x72, 0xe4, 0x79, 0x78, 0xfd, 0x2f, 0x8c, 0x19, 0x18, 0xca, 0xe2, 0x7b,
+ 0x3e, 0xaa, 0xe1, 0xee, 0x25, 0xfc, 0xf4, 0x03, 0xa2, 0x61, 0x63, 0x6b,
+ 0xa4, 0x93, 0x6a, 0x79, 0xc5, 0x6b, 0xb8, 0x31, 0xd2, 0xe4, 0x87, 0xa2,
+ 0xa5, 0xc4, 0x2b, 0xf9, 0xc8, 0x91, 0x1d, 0xd2, 0xb7, 0xc4, 0xcf, 0xa7,
+ 0x0d, 0x3c, 0x5a, 0xea, 0x11, 0x7f, 0x31, 0x2d, 0x83, 0x74, 0x43, 0x71,
+ 0x4b, 0xc7, 0x11, 0xa2, 0xcb, 0x45, 0x18, 0xc9, 0xf5, 0xfb, 0x02, 0x8b,
+ 0xb5, 0x24, 0xbe, 0xb3, 0x8a, 0x7d, 0xa1, 0x12, 0xd3, 0x9c, 0xab, 0x80,
+ 0xfd, 0x64, 0x93, 0x0d, 0x99, 0x0e, 0xb1, 0x84, 0xbe, 0x5f, 0xa4, 0xbc,
+ 0x96, 0x94, 0x3a, 0x45, 0x03, 0x61, 0xd3, 0x85, 0x93, 0x5b, 0xc4, 0x82,
+ 0x22, 0x63, 0x51, 0x28, 0x0b, 0x49, 0x46, 0x0b, 0x8b, 0x17, 0x1d, 0x95,
+ 0x1a, 0xc0, 0xc5, 0xb6, 0x64, 0xfa, 0x0c, 0xd9, 0x7f, 0x88, 0x62, 0xfb,
+ 0x8e, 0x58, 0x27, 0xe1, 0x64, 0xbe, 0x3e, 0x20, 0x86, 0x48, 0x8e, 0x13,
+ 0x2e, 0xdb, 0x76, 0xfc, 0x4f, 0x8c, 0xc1, 0xd5, 0x60, 0x20, 0xe4, 0xa6,
+ 0xdc, 0xf1, 0xdf, 0xdb, 0x22, 0xe6, 0xf3, 0x52, 0x97, 0xc8, 0xe5, 0x03,
+ 0xfe, 0x23, 0x63, 0x9c, 0x67, 0x3a, 0xc4, 0x11, 0xd2, 0x79, 0x96, 0x74,
+ 0x9e, 0x25, 0x9d, 0x67, 0x48, 0xe7, 0x99, 0x2f, 0xd1, 0xf9, 0x3e, 0xd2,
+ 0xf9, 0xee, 0xfc, 0xaf, 0x6c, 0x1d, 0x3a, 0x0d, 0x03, 0x59, 0xca, 0xcb,
+ 0x23, 0x4d, 0x15, 0xfe, 0x3e, 0x24, 0x59, 0xbc, 0x14, 0xfb, 0x86, 0x13,
+ 0x5e, 0x83, 0x62, 0x6b, 0x17, 0x3d, 0xf3, 0x95, 0x39, 0x1b, 0x57, 0xfc,
+ 0xc3, 0x63, 0x1d, 0x62, 0x98, 0xfc, 0x6e, 0x84, 0xe6, 0x1f, 0x21, 0xbf,
+ 0x1b, 0x4c, 0xff, 0x9f, 0xd8, 0x0d, 0xdb, 0x1d, 0x4c, 0x2f, 0xe5, 0xad,
+ 0x6a, 0xb2, 0x4b, 0xa7, 0xc1, 0x36, 0xb4, 0x59, 0x24, 0x8f, 0x7e, 0x4b,
+ 0x24, 0x8f, 0xa5, 0x44, 0xb2, 0xd0, 0x43, 0x9f, 0x5b, 0xc4, 0x2d, 0x76,
+ 0x1d, 0x3a, 0x20, 0x3a, 0x0a, 0x01, 0xff, 0x38, 0xad, 0x33, 0x4e, 0x7c,
+ 0x3c, 0x46, 0xeb, 0x3c, 0x66, 0xdb, 0x2e, 0x15, 0x99, 0x5e, 0x5e, 0x8b,
+ 0xed, 0x8c, 0xed, 0xeb, 0x32, 0xd1, 0xce, 0xbe, 0x71, 0xb5, 0xc7, 0x43,
+ 0x7f, 0x37, 0x38, 0xa0, 0xed, 0x74, 0x56, 0x78, 0xe2, 0xdc, 0xcf, 0xb9,
+ 0x9e, 0xe3, 0xb0, 0x62, 0xd7, 0x82, 0xcf, 0x5e, 0xc5, 0x00, 0x8c, 0x07,
+ 0x20, 0x2f, 0x30, 0xb6, 0x18, 0xdf, 0x69, 0xfa, 0x1f, 0x34, 0x5f, 0x3f,
+ 0xf4, 0x55, 0x90, 0x03, 0xc6, 0x5f, 0x1a, 0x63, 0x4d, 0x14, 0xa7, 0x69,
+ 0x4e, 0x39, 0x03, 0x68, 0x19, 0x81, 0xdd, 0x09, 0x41, 0x38, 0x76, 0x11,
+ 0xf9, 0x25, 0xd3, 0xaf, 0x76, 0x52, 0x36, 0xc1, 0xd2, 0x21, 0xc8, 0x4b,
+ 0x8c, 0x9d, 0xb0, 0xb2, 0x90, 0x6b, 0x8d, 0x3e, 0x5c, 0x19, 0x0a, 0x07,
+ 0x3b, 0xa1, 0xa6, 0x2e, 0x38, 0xd4, 0x32, 0xe5, 0xb7, 0xfe, 0xdd, 0x42,
+ 0xed, 0x9b, 0x15, 0xdc, 0x27, 0x62, 0xec, 0xbe, 0x13, 0x2d, 0x36, 0x86,
+ 0xef, 0x43, 0x73, 0x1e, 0x54, 0x87, 0x0b, 0xbc, 0x43, 0x73, 0xbe, 0xa8,
+ 0x7f, 0xc0, 0x39, 0x21, 0x49, 0x58, 0xf0, 0x0b, 0x73, 0x81, 0x70, 0x0c,
+ 0xcf, 0xc3, 0x73, 0x84, 0x95, 0x3e, 0x9a, 0xf7, 0x4d, 0x47, 0x73, 0xff,
+ 0xa0, 0x50, 0x13, 0x5f, 0x9c, 0x6f, 0x59, 0x1e, 0x62, 0x59, 0xc6, 0xb4,
+ 0xaa, 0x35, 0x2f, 0xe3, 0x21, 0xe9, 0x1d, 0x4d, 0x4b, 0xbe, 0x86, 0x10,
+ 0x96, 0x51, 0x9d, 0x1c, 0x2d, 0x32, 0x0f, 0xbb, 0x70, 0x46, 0x57, 0xbb,
+ 0xa9, 0x1a, 0xa5, 0xba, 0xa5, 0x03, 0x07, 0x29, 0xf6, 0x3e, 0x5a, 0xe2,
+ 0x3e, 0xd7, 0x80, 0x58, 0x3e, 0x44, 0x7e, 0x69, 0xdb, 0x13, 0xe4, 0x06,
+ 0xe3, 0x61, 0xdc, 0x40, 0xeb, 0xfb, 0xa9, 0xf6, 0x79, 0x9d, 0xd6, 0x97,
+ 0x32, 0xea, 0x00, 0xad, 0x9f, 0x7a, 0x43, 0x84, 0x67, 0x89, 0xaf, 0x9e,
+ 0x75, 0x8e, 0xe6, 0xbe, 0x5d, 0x42, 0x4d, 0x12, 0xe9, 0xe4, 0xc7, 0xbc,
+ 0xf6, 0xc3, 0xcc, 0x0b, 0x7d, 0x52, 0x9d, 0x43, 0x76, 0xd4, 0x54, 0x90,
+ 0x45, 0x64, 0x78, 0x3d, 0xf6, 0x4e, 0xad, 0xc7, 0x1e, 0xf2, 0xc7, 0x03,
+ 0x7a, 0x2d, 0x42, 0x75, 0xa8, 0xa9, 0xd5, 0x30, 0x7b, 0x41, 0x13, 0x8e,
+ 0x1d, 0x2d, 0x8d, 0x64, 0xc7, 0xa7, 0x1b, 0xaa, 0xf0, 0x91, 0xd5, 0xab,
+ 0xad, 0xef, 0xa4, 0x88, 0x78, 0x83, 0x07, 0xe3, 0x0e, 0xf2, 0xef, 0x5f,
+ 0xfc, 0x9a, 0x02, 0xaa, 0xc7, 0x60, 0xdc, 0x96, 0x10, 0x97, 0xf2, 0x67,
+ 0x9d, 0x15, 0x3f, 0x68, 0xc2, 0x15, 0x05, 0xb5, 0x41, 0x6d, 0x39, 0x66,
+ 0x15, 0x99, 0xe2, 0x85, 0x69, 0xd7, 0x64, 0x37, 0xe7, 0xba, 0xd1, 0x40,
+ 0xf5, 0xf1, 0x9d, 0xb1, 0x5f, 0x5b, 0x9f, 0x2c, 0xe6, 0xe7, 0x4e, 0x7a,
+ 0x2a, 0xb1, 0xf3, 0xcb, 0xe6, 0x88, 0x53, 0xbc, 0x69, 0xa6, 0x7a, 0xb6,
+ 0x9a, 0x82, 0x74, 0x27, 0xe5, 0x23, 0xb5, 0x27, 0x4d, 0xf5, 0x68, 0x5f,
+ 0xa4, 0x59, 0x77, 0x08, 0x37, 0xca, 0x81, 0x70, 0x7f, 0x2f, 0x92, 0xdb,
+ 0xfd, 0x73, 0x74, 0x3c, 0x2b, 0x34, 0x17, 0x3d, 0xc7, 0xf3, 0x5c, 0x63,
+ 0x4f, 0x27, 0xc9, 0x9e, 0xf8, 0x3e, 0x7f, 0xbf, 0x7a, 0x5f, 0xfe, 0x8a,
+ 0xf1, 0x97, 0xff, 0xe4, 0x8f, 0x97, 0x7d, 0xd9, 0xf5, 0x8f, 0xbf, 0xe4,
+ 0xfa, 0xff, 0xae, 0xae, 0x2f, 0xd7, 0x39, 0x6d, 0xcc, 0x90, 0x94, 0xb8,
+ 0x8f, 0xe9, 0x34, 0x2e, 0xaf, 0xd9, 0xa3, 0xfd, 0x0e, 0xc5, 0x34, 0xee,
+ 0x63, 0x70, 0x9e, 0x3e, 0x6f, 0xf7, 0x31, 0x4e, 0x7d, 0x0e, 0xb3, 0x72,
+ 0x6c, 0xf1, 0x88, 0xea, 0x11, 0xd3, 0xaa, 0xd7, 0xbe, 0x4d, 0x75, 0xcd,
+ 0x2e, 0xf4, 0xc6, 0x74, 0x0c, 0x67, 0xd5, 0xee, 0xdb, 0xa0, 0x25, 0x37,
+ 0x0b, 0x9a, 0xa8, 0xe8, 0x11, 0x8e, 0x91, 0xb9, 0x7b, 0xba, 0x49, 0xb5,
+ 0x5a, 0x19, 0x55, 0x14, 0x9b, 0x9c, 0x9a, 0x22, 0xa3, 0x18, 0x90, 0x9d,
+ 0xc5, 0xa0, 0xec, 0x2e, 0x36, 0xca, 0x55, 0x34, 0xce, 0x37, 0xa2, 0xce,
+ 0xde, 0x86, 0x5d, 0x98, 0x6d, 0xf3, 0x9a, 0x0d, 0x86, 0xaa, 0x34, 0x38,
+ 0x76, 0x61, 0x4f, 0x8c, 0x9f, 0xed, 0xa0, 0x9a, 0x0d, 0xa2, 0x2e, 0x43,
+ 0xc8, 0xd8, 0x10, 0xd8, 0xdb, 0xae, 0x0e, 0x2c, 0x95, 0xb4, 0xce, 0x5f,
+ 0x09, 0xa7, 0xec, 0x29, 0x42, 0xf8, 0x33, 0x12, 0x8e, 0xb4, 0xc3, 0xe3,
+ 0x59, 0xa5, 0xf6, 0x9d, 0x16, 0x03, 0x78, 0x2a, 0x16, 0xe9, 0xde, 0x26,
+ 0x42, 0xb2, 0x97, 0xee, 0xb9, 0x32, 0x14, 0x7f, 0x33, 0xa6, 0xc7, 0xb5,
+ 0x4a, 0x0d, 0x4a, 0x22, 0x89, 0x5e, 0x4d, 0xd3, 0x47, 0x20, 0xd3, 0x9a,
+ 0x10, 0x55, 0x19, 0x75, 0xf6, 0x4d, 0xc2, 0x54, 0x9f, 0x2c, 0x1b, 0x40,
+ 0x6b, 0x5b, 0x64, 0x7f, 0x8f, 0xa4, 0xc9, 0x84, 0xf5, 0x84, 0x33, 0xe3,
+ 0xc3, 0xca, 0xc3, 0xf3, 0x7d, 0x1d, 0xcb, 0xfa, 0x30, 0x56, 0x26, 0xbd,
+ 0x40, 0xae, 0x29, 0x46, 0x65, 0x1f, 0xe1, 0xfa, 0xe6, 0xc3, 0x8c, 0xb3,
+ 0x2c, 0x6b, 0x47, 0xac, 0xfc, 0x75, 0x2f, 0x5a, 0x88, 0xc7, 0x6e, 0x4c,
+ 0xa5, 0x19, 0x77, 0x19, 0x98, 0xa4, 0x9a, 0x48, 0x1b, 0x6a, 0xc4, 0x71,
+ 0x8a, 0x43, 0x33, 0x69, 0xee, 0xff, 0xf4, 0x91, 0x8c, 0x7b, 0x88, 0xfe,
+ 0x2d, 0x54, 0x0f, 0xa7, 0x28, 0x7e, 0xb1, 0x8c, 0x7b, 0xc9, 0xee, 0x21,
+ 0x7b, 0x8d, 0x3a, 0xe3, 0xe6, 0x61, 0xc8, 0x1e, 0xc3, 0x6b, 0x5c, 0x77,
+ 0x18, 0x75, 0x94, 0xf7, 0x0d, 0xaa, 0x78, 0x10, 0x8d, 0x44, 0xf4, 0x8b,
+ 0x88, 0x04, 0x5f, 0x24, 0x7d, 0x0c, 0x6a, 0xc0, 0x6e, 0xbb, 0xd6, 0x76,
+ 0xc2, 0xcc, 0x73, 0x0d, 0x0d, 0x4f, 0x55, 0x7b, 0x1d, 0xde, 0xc9, 0x45,
+ 0xed, 0x1e, 0x92, 0x49, 0xf5, 0xcf, 0x0b, 0xba, 0x9a, 0x9a, 0xa0, 0xe7,
+ 0xb6, 0x2a, 0xff, 0x65, 0x5f, 0x75, 0x1c, 0x32, 0xc5, 0x34, 0xb2, 0xbd,
+ 0x3f, 0xf5, 0xbe, 0x49, 0x36, 0x7a, 0xfb, 0xd8, 0x9f, 0x79, 0xaf, 0xc4,
+ 0x27, 0xbc, 0x1f, 0xc4, 0x2d, 0x2b, 0x41, 0x78, 0xb4, 0x87, 0xea, 0xed,
+ 0x0f, 0x87, 0x4c, 0xef, 0xc5, 0x38, 0xf7, 0x81, 0x9d, 0xf8, 0x3d, 0xfa,
+ 0xfd, 0xe4, 0x90, 0x8c, 0x4d, 0x85, 0x06, 0xb8, 0x86, 0x1d, 0x98, 0xd2,
+ 0x6f, 0x44, 0xaf, 0x22, 0xe1, 0xee, 0xe8, 0x49, 0xb2, 0x49, 0x89, 0xc6,
+ 0x1c, 0xa2, 0xdf, 0xdc, 0xd3, 0x7a, 0x0c, 0xdb, 0x94, 0x69, 0xef, 0x3b,
+ 0x71, 0xa6, 0x17, 0x4c, 0xaf, 0x2c, 0x69, 0xb7, 0x62, 0xeb, 0x6d, 0x5c,
+ 0x5b, 0xd9, 0xff, 0x9e, 0x17, 0xdb, 0xeb, 0x71, 0x3c, 0xd7, 0x80, 0xe7,
+ 0x73, 0xa6, 0xe7, 0xb5, 0xf6, 0x28, 0xfa, 0x86, 0x2c, 0xbc, 0xac, 0x9b,
+ 0x03, 0x55, 0x64, 0xe7, 0x09, 0xaa, 0xaf, 0xc2, 0x6d, 0xdc, 0x4b, 0x40,
+ 0xc4, 0x81, 0x48, 0x3f, 0x81, 0xcc, 0x3b, 0x28, 0x74, 0xa5, 0x6a, 0xa8,
+ 0x4e, 0x3b, 0x27, 0x2c, 0xf7, 0xf6, 0x76, 0x27, 0xd1, 0x00, 0x6c, 0x28,
+ 0xb4, 0x90, 0xdc, 0xa2, 0xd8, 0x14, 0x91, 0xb1, 0xb1, 0xa0, 0xe3, 0xf9,
+ 0xb4, 0x0f, 0xb7, 0x17, 0xe2, 0x84, 0xbd, 0x15, 0xa2, 0x3d, 0x81, 0x52,
+ 0x3a, 0x80, 0x6f, 0x14, 0x1a, 0x49, 0xde, 0x41, 0xdc, 0x58, 0x08, 0xe1,
+ 0x44, 0x9a, 0xf3, 0xb7, 0xe1, 0xd9, 0x1a, 0x6f, 0x44, 0x67, 0x41, 0xc3,
+ 0x74, 0x1a, 0x9e, 0x07, 0xe2, 0x21, 0x74, 0x14, 0xa2, 0x28, 0x10, 0x86,
+ 0xbb, 0x95, 0xe6, 0xbc, 0x9d, 0x74, 0xd2, 0x52, 0x08, 0x60, 0x69, 0x84,
+ 0x22, 0x72, 0xc1, 0x27, 0x06, 0x08, 0x5b, 0x25, 0x0a, 0xf5, 0xb8, 0x38,
+ 0xcc, 0x76, 0xae, 0x18, 0x7b, 0x72, 0x0a, 0x42, 0x05, 0xac, 0x94, 0x01,
+ 0x0a, 0xd6, 0x91, 0x54, 0x81, 0xe8, 0x3d, 0xd8, 0x5e, 0xe9, 0xe1, 0x2e,
+ 0x2f, 0x7c, 0xc6, 0x6f, 0x2d, 0xe9, 0xe9, 0xca, 0xe1, 0x69, 0xef, 0x27,
+ 0x71, 0x8e, 0x4d, 0x9f, 0xae, 0x79, 0xfd, 0x30, 0x10, 0x1d, 0x67, 0xde,
+ 0xec, 0xd8, 0xc8, 0xf1, 0xb0, 0x45, 0xc6, 0xaf, 0x2c, 0xaa, 0x41, 0x43,
+ 0x53, 0xbc, 0x57, 0xa0, 0xf9, 0x88, 0x0e, 0x05, 0x49, 0x5a, 0xfb, 0x96,
+ 0xc2, 0x0f, 0xad, 0xad, 0x0b, 0x83, 0xb8, 0x39, 0x52, 0x91, 0xd5, 0x39,
+ 0xd2, 0xe1, 0xe4, 0x70, 0x03, 0x66, 0x88, 0x06, 0x97, 0xe1, 0x36, 0x8e,
+ 0x8d, 0x59, 0xd8, 0xa0, 0x9b, 0xde, 0xd7, 0xda, 0x97, 0xe3, 0xfe, 0xc3,
+ 0x83, 0x67, 0xdd, 0xa4, 0xd7, 0x59, 0xfd, 0x0e, 0x3c, 0x3a, 0x8e, 0xaf,
+ 0x35, 0x00, 0x8f, 0x04, 0xc1, 0x3d, 0x6b, 0x35, 0x74, 0x02, 0x91, 0xce,
+ 0x07, 0x10, 0x51, 0x34, 0xa1, 0xea, 0x2f, 0x0b, 0x24, 0xab, 0x8d, 0xc8,
+ 0xd9, 0x5b, 0x80, 0x33, 0x6e, 0xf2, 0xe0, 0xdb, 0x0b, 0x4e, 0x92, 0x51,
+ 0x10, 0xa5, 0x61, 0x37, 0x1c, 0xe4, 0x27, 0x97, 0x34, 0x6c, 0xa8, 0x25,
+ 0x59, 0x3b, 0x84, 0x4c, 0x7a, 0x6e, 0xc1, 0xb1, 0xa1, 0x79, 0x59, 0xf9,
+ 0x70, 0x13, 0xc9, 0xf0, 0xa9, 0x21, 0x6b, 0x97, 0x16, 0x0b, 0x90, 0xac,
+ 0x15, 0xa2, 0x6f, 0x5e, 0x4e, 0x2c, 0xbf, 0x79, 0x39, 0xdd, 0x81, 0x3d,
+ 0x33, 0x2c, 0xb7, 0xff, 0x1b, 0x79, 0x4d, 0xdb, 0x76, 0xb7, 0x61, 0x2c,
+ 0x8a, 0x86, 0xc3, 0x57, 0x65, 0xc7, 0xf4, 0x3d, 0x42, 0x7c, 0x7c, 0xcf,
+ 0xbf, 0x3a, 0xd2, 0xf7, 0xbe, 0xf0, 0x11, 0x3d, 0x0a, 0xe9, 0xe6, 0x03,
+ 0x17, 0x63, 0x77, 0x92, 0xc9, 0x55, 0x19, 0x07, 0x49, 0xc6, 0xc1, 0x71,
+ 0x96, 0xf5, 0xa7, 0x6b, 0xae, 0x90, 0x7c, 0x5f, 0x27, 0x5c, 0x76, 0x43,
+ 0x2c, 0x8a, 0x9a, 0xc3, 0x6a, 0xb2, 0xc1, 0x11, 0x4e, 0xd4, 0x0a, 0x50,
+ 0x55, 0x82, 0x96, 0x1a, 0x7c, 0xc8, 0x72, 0xd6, 0x49, 0xce, 0xdf, 0x1b,
+ 0x24, 0x7e, 0xd6, 0xd3, 0x7c, 0x1b, 0x48, 0xce, 0x49, 0xe2, 0xff, 0x16,
+ 0x7b, 0xde, 0x46, 0x9a, 0x77, 0x0b, 0xd5, 0x1e, 0xd3, 0xde, 0x4b, 0x44,
+ 0x4f, 0xf4, 0x33, 0x5a, 0x08, 0x8d, 0x47, 0x82, 0xef, 0x53, 0x8d, 0x7d,
+ 0xa3, 0x3d, 0x4e, 0xa1, 0x71, 0x4c, 0xfb, 0xcf, 0xab, 0x24, 0xed, 0xcb,
+ 0xfa, 0xcd, 0xdf, 0x02, 0xf7, 0x1c, 0x4c, 0xf4, 0x50, 0x1d, 0xb1, 0x85,
+ 0x6a, 0x25, 0x99, 0x72, 0x9b, 0x89, 0x1f, 0xc4, 0xd5, 0x68, 0x9d, 0xe0,
+ 0xf8, 0x67, 0x92, 0x1f, 0x96, 0xa9, 0x4e, 0x0a, 0x87, 0x66, 0x10, 0x94,
+ 0xa5, 0xa2, 0x4c, 0x78, 0xb0, 0x51, 0x76, 0x14, 0xc9, 0x5f, 0x83, 0x3d,
+ 0x84, 0xa7, 0x9d, 0x78, 0x31, 0xef, 0xc4, 0x2b, 0xe9, 0x2d, 0x38, 0x50,
+ 0xf2, 0x10, 0x6e, 0x36, 0x3d, 0xce, 0x55, 0x13, 0xee, 0x4a, 0x4c, 0x5e,
+ 0x86, 0xae, 0x91, 0x87, 0x51, 0x9d, 0x71, 0x76, 0x53, 0x3e, 0xd5, 0x6f,
+ 0x21, 0xb9, 0x6c, 0x28, 0xf2, 0xfd, 0x46, 0x64, 0xd2, 0x29, 0xc2, 0x40,
+ 0x61, 0xaa, 0x81, 0x9c, 0x98, 0x68, 0x68, 0xb4, 0xfb, 0xba, 0x39, 0xba,
+ 0x96, 0x2b, 0x7d, 0xb1, 0xdf, 0x7c, 0xc7, 0x5c, 0x9f, 0xb9, 0x0f, 0xfb,
+ 0xb2, 0x3d, 0x84, 0x4d, 0xb7, 0x50, 0x7c, 0xaf, 0xd0, 0x38, 0x1d, 0xef,
+ 0xc6, 0xbe, 0xbc, 0x71, 0x35, 0x7e, 0x4c, 0xda, 0xf1, 0xa3, 0x1f, 0x55,
+ 0xed, 0xbc, 0x7f, 0xb5, 0x05, 0x77, 0xa5, 0x81, 0xf7, 0xd2, 0xdc, 0x4f,
+ 0x24, 0x4c, 0x41, 0xf9, 0xe0, 0x90, 0xce, 0x39, 0x74, 0x0b, 0x96, 0xe6,
+ 0x2d, 0xe4, 0x75, 0x0b, 0x67, 0x75, 0x8d, 0x72, 0x34, 0xe7, 0xea, 0x01,
+ 0xa1, 0x51, 0x7e, 0x36, 0x9d, 0xfd, 0x88, 0xb4, 0xb3, 0x8e, 0x1e, 0x9e,
+ 0xdb, 0x87, 0xea, 0xb7, 0xf7, 0xa1, 0x66, 0xd2, 0x0e, 0x3c, 0x45, 0x8a,
+ 0x78, 0x3e, 0x1b, 0x0e, 0xbd, 0x07, 0x6b, 0x97, 0xc3, 0x50, 0x13, 0x4e,
+ 0x07, 0xef, 0xcf, 0xf0, 0xfe, 0x94, 0xd6, 0xbd, 0xd4, 0xa1, 0xea, 0x45,
+ 0xd1, 0xdc, 0xf3, 0x16, 0xca, 0x1b, 0x65, 0xa8, 0xa1, 0xd7, 0x10, 0x89,
+ 0x76, 0xf2, 0x1e, 0x44, 0xa9, 0x92, 0xbb, 0x97, 0xcd, 0xe5, 0x6e, 0x2d,
+ 0xef, 0x15, 0xe1, 0x61, 0x09, 0x13, 0x53, 0x96, 0x29, 0x91, 0xfd, 0x4e,
+ 0xd1, 0x9c, 0x3f, 0xce, 0xee, 0x42, 0x36, 0x66, 0x59, 0xb7, 0xc7, 0xb5,
+ 0xbe, 0x06, 0x07, 0xfe, 0x90, 0x32, 0x39, 0xc8, 0xe6, 0x53, 0xe4, 0x6b,
+ 0xa1, 0x1d, 0xed, 0xa6, 0xe5, 0xb6, 0xeb, 0x0a, 0xee, 0x4f, 0x76, 0x89,
+ 0x96, 0xc2, 0x16, 0xb1, 0x9c, 0xb0, 0x5b, 0xe8, 0xd8, 0x66, 0xd1, 0x74,
+ 0xb4, 0x82, 0xdd, 0x22, 0x85, 0xcf, 0x7a, 0xa8, 0x37, 0xa7, 0x2d, 0xa4,
+ 0x89, 0xaf, 0xa7, 0xfe, 0x0e, 0x5f, 0xac, 0x8b, 0x7e, 0x5c, 0xd7, 0xce,
+ 0xbe, 0xf8, 0x30, 0x8e, 0xa5, 0xd9, 0xce, 0xfb, 0xb1, 0x87, 0xe4, 0xb3,
+ 0x62, 0x88, 0xf7, 0xc3, 0xd4, 0xb3, 0x83, 0x08, 0xf7, 0xbd, 0x2a, 0xd4,
+ 0x72, 0x01, 0xcd, 0x7a, 0x8d, 0x83, 0xe3, 0xab, 0x3a, 0xd0, 0xe4, 0xa8,
+ 0xd0, 0x9f, 0xc8, 0x83, 0xe2, 0x69, 0x85, 0x87, 0x95, 0xf9, 0xa5, 0x64,
+ 0xab, 0xa6, 0xe7, 0x52, 0xbc, 0xb9, 0xbf, 0x1a, 0x1b, 0xc4, 0x07, 0xd3,
+ 0x21, 0x78, 0x0f, 0x27, 0x17, 0xfa, 0xd1, 0x21, 0xde, 0xb3, 0xeb, 0xc5,
+ 0x4e, 0xf1, 0x4e, 0xbe, 0x5b, 0x5c, 0x9e, 0xe8, 0x42, 0x64, 0xf8, 0x3e,
+ 0xf1, 0xf6, 0x04, 0xd3, 0xd9, 0x23, 0xce, 0x4f, 0x73, 0x9f, 0xd4, 0xc2,
+ 0x1e, 0x9d, 0xfb, 0xa2, 0x8b, 0xab, 0xe0, 0xb7, 0x70, 0x4c, 0x67, 0x7d,
+ 0x72, 0x9f, 0xb0, 0xd2, 0x5f, 0xda, 0x10, 0xcf, 0x59, 0x4e, 0x8d, 0x7b,
+ 0xc5, 0x41, 0x9b, 0xdf, 0x29, 0xc2, 0xd1, 0xd3, 0x13, 0x5b, 0xc4, 0xf1,
+ 0x7c, 0x85, 0xd7, 0xc9, 0x3c, 0xdb, 0xaf, 0x4c, 0x3a, 0xfe, 0x62, 0x9e,
+ 0x36, 0xa1, 0xb4, 0x07, 0xe1, 0xb6, 0xfb, 0x51, 0x16, 0x46, 0xf4, 0x48,
+ 0xe8, 0x65, 0x04, 0xe1, 0x2c, 0xb2, 0x6d, 0x5b, 0x78, 0x5a, 0x77, 0xc1,
+ 0x31, 0x22, 0x93, 0x8c, 0xc8, 0x96, 0xfc, 0x2e, 0x48, 0x93, 0x5c, 0x1b,
+ 0x7c, 0xbd, 0x8a, 0xfb, 0x14, 0x21, 0x89, 0xbf, 0x7f, 0xd1, 0xe6, 0x5c,
+ 0x94, 0x0f, 0xb8, 0xbf, 0xfe, 0x57, 0xee, 0x8a, 0xed, 0xb1, 0x5d, 0xcd,
+ 0xf7, 0xc4, 0x29, 0xd7, 0xb6, 0x73, 0x2f, 0xdc, 0x83, 0x99, 0x9c, 0x9b,
+ 0x5b, 0x14, 0x1e, 0x77, 0xbb, 0x85, 0x0b, 0xba, 0x93, 0xea, 0x97, 0x87,
+ 0x28, 0x47, 0x49, 0x90, 0xb5, 0x3b, 0x50, 0x1c, 0x73, 0x4a, 0xbc, 0x5f,
+ 0xf5, 0xb3, 0x18, 0xf7, 0x10, 0x80, 0x43, 0xc4, 0xc3, 0xf7, 0x73, 0x21,
+ 0x6c, 0xa2, 0xba, 0x2b, 0x64, 0xd7, 0x18, 0xbf, 0x87, 0x53, 0x39, 0x87,
+ 0xa0, 0xba, 0xc2, 0x91, 0x58, 0x6d, 0xe1, 0x4a, 0x5b, 0x24, 0xca, 0x7d,
+ 0x68, 0x85, 0x72, 0xd6, 0xde, 0x7c, 0x1d, 0x7e, 0x96, 0xab, 0xc3, 0x2b,
+ 0x39, 0x0b, 0x07, 0x63, 0x83, 0x3d, 0x5e, 0x8a, 0x95, 0xcb, 0x62, 0x2e,
+ 0xec, 0x88, 0x98, 0x8a, 0x17, 0x51, 0x5c, 0x48, 0x5c, 0x87, 0x54, 0x20,
+ 0xdc, 0x39, 0x88, 0x7a, 0xbc, 0x91, 0x03, 0x61, 0x09, 0x78, 0x96, 0xd2,
+ 0x1c, 0x6f, 0xc7, 0xcc, 0x7e, 0x17, 0xe1, 0xd8, 0x9f, 0x0b, 0xc4, 0x6b,
+ 0x60, 0xb9, 0xcf, 0xc4, 0x29, 0x57, 0x17, 0xea, 0xd0, 0x95, 0xab, 0x47,
+ 0x0f, 0xe5, 0xac, 0x75, 0xab, 0xe3, 0x78, 0x2b, 0xeb, 0x13, 0x2b, 0xb3,
+ 0x83, 0x3d, 0x0a, 0xcd, 0xe9, 0x6a, 0x53, 0xfb, 0x9f, 0x22, 0xe0, 0x26,
+ 0x23, 0x4c, 0xe6, 0x8e, 0x07, 0xfc, 0x14, 0x77, 0x8f, 0x8b, 0x4f, 0xf1,
+ 0x04, 0xd9, 0xe3, 0x3d, 0xba, 0x5a, 0xbe, 0xe4, 0x88, 0x9c, 0xdd, 0x08,
+ 0x75, 0xe0, 0x16, 0x61, 0x46, 0x6b, 0x29, 0x9e, 0x34, 0x54, 0x62, 0x85,
+ 0x19, 0x11, 0x32, 0x61, 0x73, 0x27, 0x3c, 0x9a, 0x89, 0xce, 0x76, 0x96,
+ 0xa9, 0x07, 0x9e, 0xa3, 0x64, 0x47, 0xd2, 0x17, 0xfb, 0xfb, 0x75, 0x78,
+ 0x9d, 0xf2, 0xe5, 0xb9, 0x1c, 0xf7, 0xe6, 0xdd, 0xc6, 0xbb, 0x94, 0x03,
+ 0x5e, 0x8a, 0x0d, 0x86, 0x38, 0xf6, 0xe7, 0x63, 0xf8, 0xe7, 0x64, 0x96,
+ 0x8d, 0x3e, 0x5a, 0xf3, 0x2e, 0xc1, 0xeb, 0x20, 0xb9, 0xc4, 0xe0, 0xbe,
+ 0x9c, 0xcd, 0x0f, 0xc5, 0x63, 0xe6, 0xe9, 0xff, 0x27, 0xed, 0x8f, 0x54,
+ 0xc1, 0x5b, 0x4f, 0xba, 0x9c, 0xef, 0x69, 0x5e, 0xdb, 0xcf, 0xe4, 0x7a,
+ 0xa6, 0x82, 0x0f, 0xdd, 0x46, 0xb5, 0x78, 0x21, 0xc7, 0x36, 0x67, 0xe1,
+ 0x19, 0x5d, 0xa7, 0xda, 0x85, 0x6b, 0xf2, 0x7e, 0xaa, 0x5f, 0xb8, 0xcf,
+ 0x64, 0x7a, 0xce, 0x10, 0x85, 0xfb, 0x73, 0x58, 0x2b, 0xc3, 0xb1, 0xa2,
+ 0x0a, 0xe3, 0x98, 0x70, 0x3a, 0x09, 0x73, 0x70, 0xac, 0x65, 0x7f, 0x52,
+ 0x0c, 0x6d, 0x82, 0xeb, 0xcf, 0x4e, 0x98, 0xb6, 0x1f, 0x57, 0x8b, 0xfb,
+ 0xc9, 0x46, 0x5e, 0x8c, 0x55, 0x61, 0x82, 0xea, 0x1f, 0xc9, 0x30, 0x3d,
+ 0xdf, 0xa5, 0xe7, 0x13, 0xa3, 0xd8, 0x17, 0x84, 0xe3, 0x4f, 0x14, 0xfc,
+ 0x19, 0xde, 0x74, 0xc9, 0x74, 0x1d, 0x9e, 0xee, 0xb8, 0xe9, 0xdd, 0x18,
+ 0xaf, 0x16, 0xb7, 0xe6, 0x5a, 0xf0, 0xfe, 0x58, 0x1d, 0xd9, 0x77, 0x3d,
+ 0x96, 0x8c, 0x04, 0xf1, 0x36, 0xd1, 0x32, 0x40, 0xb4, 0x7c, 0xd2, 0x66,
+ 0x0e, 0x34, 0x40, 0xed, 0xa7, 0xba, 0xa8, 0x9b, 0xfb, 0xcd, 0x4f, 0xeb,
+ 0x6a, 0xe7, 0x6d, 0xc2, 0x0b, 0x2d, 0x92, 0x24, 0xd9, 0x5b, 0xd6, 0xb0,
+ 0xde, 0xac, 0xfb, 0xc0, 0xfd, 0xa3, 0x3b, 0x70, 0x68, 0x86, 0x69, 0x71,
+ 0x1b, 0xcb, 0xa7, 0xf9, 0x53, 0x36, 0xae, 0xb3, 0x3f, 0xbd, 0x73, 0x9f,
+ 0x30, 0x42, 0xf6, 0xe7, 0xa7, 0x6b, 0x42, 0xd3, 0xdc, 0xa7, 0x0e, 0x9b,
+ 0x6e, 0xf1, 0x53, 0x17, 0xf7, 0xab, 0x93, 0xe0, 0xff, 0x57, 0x5d, 0x95,
+ 0x7e, 0xdf, 0x1d, 0x30, 0xed, 0x1e, 0xca, 0x15, 0xbb, 0x97, 0x1d, 0x22,
+ 0x37, 0x90, 0x89, 0x3f, 0x99, 0x30, 0x57, 0x20, 0x46, 0x05, 0x7c, 0xbd,
+ 0x6c, 0x2e, 0x31, 0x7a, 0xa8, 0x46, 0x90, 0x89, 0x5f, 0x13, 0xfb, 0xda,
+ 0x05, 0x0e, 0x69, 0x06, 0x5e, 0xcb, 0x73, 0x2c, 0x77, 0xe2, 0xfb, 0x69,
+ 0x35, 0x94, 0x12, 0xe1, 0xce, 0x5b, 0x84, 0x84, 0x50, 0x43, 0x0f, 0x0e,
+ 0x51, 0x5e, 0x99, 0x4e, 0x73, 0x1e, 0x71, 0xda, 0xe7, 0x05, 0x6a, 0x29,
+ 0x0e, 0x7d, 0x38, 0x54, 0x89, 0xfb, 0x85, 0xb8, 0xba, 0xff, 0xf7, 0x48,
+ 0xa7, 0x4f, 0x17, 0x78, 0x4e, 0x13, 0x9f, 0xac, 0x66, 0x1f, 0x56, 0xa3,
+ 0x29, 0xe9, 0x5e, 0x84, 0xa6, 0x38, 0xb6, 0xd0, 0x72, 0xb4, 0xd6, 0x91,
+ 0xac, 0x1b, 0xdd, 0xf1, 0x2e, 0xd1, 0x53, 0xfc, 0x67, 0xbc, 0x27, 0xa1,
+ 0x2c, 0x30, 0x36, 0x8b, 0xf5, 0x93, 0xdc, 0x53, 0xdc, 0x22, 0xba, 0x8b,
+ 0xdc, 0x57, 0x1c, 0x10, 0xbf, 0x5f, 0x64, 0x9f, 0x9f, 0xef, 0x2f, 0xce,
+ 0xeb, 0x9f, 0xfb, 0x8a, 0xa6, 0xe7, 0x05, 0x92, 0xfd, 0x03, 0x39, 0x8e,
+ 0xc9, 0x8e, 0xfb, 0xfd, 0x68, 0xc3, 0x84, 0x0b, 0x9e, 0xd3, 0xf1, 0xaf,
+ 0xe0, 0x76, 0xc2, 0x07, 0x4b, 0xb4, 0x8a, 0xfe, 0xd6, 0x4d, 0x48, 0x48,
+ 0xb4, 0x91, 0xd0, 0x17, 0xb0, 0x4e, 0x7b, 0x29, 0x9e, 0x65, 0xac, 0xbe,
+ 0x00, 0xeb, 0x92, 0xed, 0xcd, 0x2e, 0xf7, 0x28, 0x0e, 0x9b, 0x94, 0x57,
+ 0x3c, 0x98, 0xce, 0x2d, 0xa2, 0xda, 0xc0, 0xc2, 0x7e, 0xbd, 0x06, 0x55,
+ 0x76, 0x0c, 0xf0, 0x10, 0x9e, 0x84, 0xec, 0xa3, 0x79, 0xd2, 0xc3, 0x32,
+ 0xbc, 0x74, 0xef, 0x8c, 0x4e, 0x72, 0x69, 0xaf, 0xcc, 0xdd, 0x3c, 0xb1,
+ 0x12, 0x07, 0xc9, 0xe3, 0x6b, 0xb4, 0x28, 0x86, 0x14, 0x1f, 0xc5, 0x9a,
+ 0x3b, 0xe6, 0xe6, 0xf4, 0xd0, 0x60, 0x5e, 0xaf, 0xbf, 0xaa, 0xa2, 0x87,
+ 0x35, 0x72, 0xa5, 0x06, 0x93, 0xcd, 0x6a, 0x5a, 0x6b, 0x47, 0xfb, 0x16,
+ 0x74, 0x0e, 0xf9, 0xc4, 0x2b, 0xe9, 0xbb, 0xad, 0x50, 0x1d, 0x8d, 0x23,
+ 0x9b, 0x75, 0xcf, 0xd1, 0xdb, 0x34, 0x21, 0xf3, 0x58, 0xee, 0x79, 0xe0,
+ 0xc1, 0x9c, 0x84, 0xc0, 0xdc, 0xf5, 0xf8, 0x44, 0x08, 0x7a, 0x6b, 0x35,
+ 0x50, 0x2f, 0xe8, 0x1a, 0xcf, 0xcd, 0x6b, 0xc8, 0xa8, 0x23, 0x3f, 0xb9,
+ 0x33, 0x9e, 0xc0, 0xbb, 0x59, 0x27, 0x36, 0x52, 0x9e, 0xbf, 0x31, 0x6d,
+ 0xe0, 0x42, 0x29, 0x60, 0xcf, 0x21, 0x19, 0xf3, 0xe3, 0x9c, 0x34, 0xce,
+ 0x83, 0xc9, 0x89, 0x2f, 0xd2, 0x17, 0x20, 0x9a, 0x7f, 0x42, 0xdf, 0xf9,
+ 0xde, 0x45, 0xbb, 0x3f, 0x70, 0xea, 0x9a, 0xba, 0x4a, 0x1a, 0xe1, 0x9e,
+ 0x52, 0x25, 0x17, 0x74, 0xe8, 0xac, 0x4b, 0x3f, 0x66, 0x47, 0x4d, 0x5c,
+ 0x58, 0x5d, 0x8b, 0x4f, 0x46, 0x9b, 0x70, 0x7f, 0xce, 0x8b, 0x4b, 0xa3,
+ 0x16, 0x56, 0xb6, 0xe1, 0xee, 0x20, 0x61, 0xb1, 0x5a, 0xf2, 0xfb, 0xd7,
+ 0xa8, 0xf6, 0xa1, 0x78, 0x4a, 0x94, 0x46, 0x12, 0x1b, 0xc8, 0xae, 0xa3,
+ 0x31, 0xa4, 0x6e, 0x8a, 0x47, 0x42, 0x17, 0xf1, 0x3d, 0x8b, 0x62, 0xb1,
+ 0xe2, 0x30, 0xba, 0x84, 0xd3, 0xde, 0x67, 0xdc, 0x62, 0xef, 0x4b, 0x4a,
+ 0x93, 0x03, 0xc2, 0x51, 0xbc, 0xd6, 0xaf, 0xbf, 0x2c, 0x0f, 0x71, 0xee,
+ 0xe1, 0x1e, 0xc6, 0x88, 0xe5, 0xd2, 0xb8, 0x57, 0xb3, 0x59, 0xec, 0x9d,
+ 0xb8, 0x9a, 0x9b, 0xae, 0xe6, 0xa3, 0xdd, 0x73, 0x79, 0x68, 0x30, 0xff,
+ 0x8b, 0x2f, 0xe0, 0xa8, 0xd0, 0xdc, 0x7e, 0x07, 0xe7, 0x1f, 0x8f, 0x78,
+ 0x93, 0xcc, 0x61, 0x1f, 0xf9, 0xe0, 0x49, 0xfd, 0x74, 0x90, 0x32, 0x04,
+ 0x9c, 0xad, 0x02, 0x0f, 0xf2, 0x59, 0x93, 0x80, 0x85, 0xcd, 0x7a, 0xc5,
+ 0x1e, 0xda, 0xda, 0x5d, 0xe8, 0xa3, 0x9c, 0xe4, 0x8a, 0xf9, 0xc8, 0xd7,
+ 0x15, 0xbc, 0xaa, 0xb3, 0x0d, 0x6f, 0x9e, 0xcb, 0x49, 0xbc, 0x7f, 0x5e,
+ 0xd9, 0xeb, 0xfe, 0x7c, 0xdf, 0x7b, 0xde, 0x36, 0x75, 0x24, 0x17, 0xc2,
+ 0xfb, 0x76, 0x5c, 0xa3, 0xfa, 0x41, 0xa6, 0xda, 0x61, 0x23, 0x12, 0x0b,
+ 0x54, 0x6e, 0x6d, 0x10, 0xf6, 0x36, 0xf1, 0xef, 0xdb, 0xfb, 0x70, 0xdf,
+ 0x88, 0x84, 0x6a, 0x8d, 0xe3, 0xac, 0x89, 0x43, 0x75, 0x1c, 0xa7, 0xba,
+ 0xb0, 0x6b, 0xc4, 0x23, 0xce, 0xe4, 0x9c, 0x78, 0xa2, 0xfb, 0x11, 0x2c,
+ 0x68, 0xbd, 0x07, 0xb0, 0x6d, 0x90, 0xbf, 0x7f, 0x0b, 0xa9, 0x45, 0xbc,
+ 0x3e, 0xf7, 0xda, 0x04, 0x7c, 0xad, 0xcc, 0x07, 0xbc, 0xef, 0xd3, 0xfc,
+ 0xdb, 0x86, 0x9c, 0xe2, 0x62, 0xfa, 0x3f, 0x5b, 0x27, 0x02, 0x8c, 0x13,
+ 0xf8, 0x5e, 0x0d, 0xcc, 0x3a, 0x1e, 0xcb, 0x3a, 0xf4, 0x51, 0x6d, 0xda,
+ 0x87, 0x21, 0xa2, 0xeb, 0x9c, 0x3d, 0xd7, 0x95, 0x39, 0xfa, 0x7d, 0xa2,
+ 0x36, 0x23, 0x9b, 0x41, 0xa2, 0x45, 0x59, 0xdd, 0x8d, 0xda, 0xe2, 0xb5,
+ 0xf9, 0xb6, 0xc6, 0xc3, 0xfd, 0x4a, 0xd2, 0x15, 0xe5, 0x84, 0x5e, 0xbc,
+ 0x9b, 0x16, 0x78, 0xc7, 0xb6, 0xc1, 0x5e, 0x34, 0xe5, 0x6b, 0x00, 0x3b,
+ 0x86, 0xf0, 0xb8, 0xaf, 0x57, 0x6c, 0x5b, 0xea, 0xc3, 0x03, 0xc4, 0x4b,
+ 0x0d, 0xf1, 0xf2, 0x61, 0x6c, 0x29, 0xad, 0xc3, 0xd7, 0xfe, 0x9d, 0x3c,
+ 0x77, 0xd6, 0x68, 0x6e, 0x2e, 0x4a, 0x18, 0x7e, 0xae, 0xf7, 0x22, 0xd8,
+ 0x39, 0x12, 0xe9, 0xf1, 0x49, 0x6c, 0x87, 0x11, 0xdc, 0x3b, 0x79, 0x2b,
+ 0xdd, 0xe7, 0xb9, 0x82, 0xb8, 0x2b, 0xe3, 0x14, 0x6f, 0x51, 0xbd, 0x74,
+ 0x2a, 0x2d, 0x2d, 0x72, 0xe0, 0x39, 0xeb, 0x89, 0xc0, 0x2e, 0xdc, 0xa4,
+ 0x77, 0x61, 0x3b, 0xd9, 0x60, 0x47, 0xd3, 0x2e, 0x8c, 0x92, 0x0d, 0x6c,
+ 0xab, 0xa7, 0x1a, 0x2e, 0x56, 0xb2, 0x7a, 0x03, 0x2c, 0x47, 0x81, 0x4e,
+ 0xba, 0x5e, 0x47, 0x75, 0x9d, 0x14, 0x23, 0x6b, 0x23, 0xbf, 0x90, 0x35,
+ 0x35, 0x97, 0xc4, 0xef, 0xd8, 0x6b, 0xd6, 0x51, 0x9e, 0x76, 0x31, 0x3e,
+ 0xf0, 0x33, 0x4e, 0xf8, 0x22, 0x3d, 0xa6, 0x55, 0xa5, 0x69, 0xd1, 0x8d,
+ 0x52, 0x53, 0x6e, 0x86, 0x6c, 0x76, 0x7d, 0xeb, 0xb5, 0xcf, 0xcd, 0xcb,
+ 0x48, 0x87, 0xbb, 0x75, 0xca, 0x2a, 0x2b, 0x83, 0x50, 0x5a, 0xaf, 0xd5,
+ 0xfd, 0xfc, 0x1c, 0x4c, 0x73, 0x25, 0xae, 0x85, 0xa4, 0x88, 0x72, 0x37,
+ 0x2e, 0xd0, 0x1a, 0x41, 0x6c, 0x2d, 0x76, 0xa1, 0x77, 0xc4, 0xf1, 0x19,
+ 0x3e, 0xf1, 0xb3, 0x2d, 0x7f, 0xc6, 0xff, 0x8e, 0x91, 0x48, 0xa7, 0x77,
+ 0x8e, 0xff, 0xed, 0x93, 0x9f, 0xcd, 0x35, 0x90, 0xe1, 0xbc, 0xca, 0xf3,
+ 0xf1, 0xb9, 0xa1, 0x79, 0xf9, 0x06, 0xf1, 0x80, 0x3d, 0xdf, 0x61, 0x0f,
+ 0xfb, 0xb0, 0x8b, 0x7c, 0x7d, 0x43, 0xab, 0x89, 0x57, 0x13, 0xf7, 0x5b,
+ 0x3b, 0x6c, 0x19, 0xdc, 0x6f, 0x3f, 0xdf, 0xd9, 0x74, 0x76, 0x0e, 0xfb,
+ 0x54, 0xfa, 0xb0, 0xa7, 0x4a, 0x2d, 0xf6, 0x1e, 0xc3, 0x0f, 0x29, 0x0f,
+ 0x3e, 0xf7, 0xb9, 0x3e, 0xdf, 0x76, 0x17, 0xef, 0x4d, 0x3c, 0x5d, 0x92,
+ 0x85, 0x73, 0xa4, 0x5a, 0xb8, 0x46, 0x98, 0xb6, 0x8f, 0xe5, 0x8a, 0x8f,
+ 0xfd, 0x57, 0x24, 0x03, 0xbc, 0xcf, 0x58, 0xb1, 0xff, 0x68, 0xfb, 0xbd,
+ 0xc0, 0x51, 0xd3, 0x53, 0xb5, 0x0a, 0x54, 0xeb, 0x77, 0xdb, 0xf6, 0xb0,
+ 0xd0, 0x08, 0xac, 0x7d, 0xae, 0x89, 0xeb, 0x7d, 0xee, 0x0d, 0x6a, 0x6b,
+ 0xc7, 0x08, 0x80, 0x6e, 0x55, 0x78, 0x4d, 0xf5, 0x04, 0xf7, 0xeb, 0xb9,
+ 0x8f, 0x4f, 0x71, 0xd7, 0x5b, 0xb7, 0xca, 0xf4, 0x2c, 0x58, 0xe5, 0x14,
+ 0x8b, 0x33, 0x3d, 0x64, 0x7b, 0x1a, 0x12, 0x19, 0xd3, 0xdb, 0xb0, 0x2a,
+ 0x84, 0x87, 0x32, 0xf3, 0x31, 0xb9, 0x05, 0x2d, 0xe3, 0xc0, 0x0f, 0x33,
+ 0x41, 0x34, 0x8f, 0x86, 0xfb, 0x6f, 0x95, 0xc2, 0x03, 0xb3, 0x12, 0xdf,
+ 0xbb, 0xbc, 0x66, 0xa5, 0x8d, 0xc5, 0x3f, 0x5a, 0xb3, 0xc2, 0xfe, 0x0c,
+ 0x18, 0xd7, 0xe7, 0xef, 0x40, 0x7a, 0xc6, 0x33, 0x5b, 0x96, 0x2c, 0x3c,
+ 0x14, 0x93, 0x70, 0xb3, 0xfe, 0x6f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab,
+ 0x9c, 0x83, 0xed, 0x60, 0xb6, 0x64, 0x95, 0x86, 0x55, 0x99, 0x3a, 0x8a,
+ 0x49, 0xf5, 0x14, 0x9f, 0xea, 0x70, 0x85, 0x62, 0xd2, 0x8a, 0x36, 0x0b,
+ 0x8b, 0xdb, 0xcc, 0xbe, 0xc5, 0xe0, 0x3d, 0x68, 0xd5, 0x2c, 0x0a, 0xb5,
+ 0xa7, 0x4b, 0x52, 0xbb, 0xeb, 0x25, 0x05, 0xdb, 0x23, 0x3c, 0x77, 0xd0,
+ 0x58, 0x95, 0xaf, 0xe4, 0xd3, 0x4a, 0x5e, 0x75, 0xce, 0xe5, 0x53, 0xb7,
+ 0xa1, 0x4f, 0xab, 0x3f, 0x4e, 0x49, 0xbc, 0x6f, 0xd2, 0x83, 0x91, 0x6c,
+ 0x0a, 0x7b, 0xb3, 0x21, 0xfc, 0x3a, 0xe3, 0x26, 0xdb, 0x08, 0xeb, 0x3f,
+ 0x00, 0x8f, 0xf1, 0x19, 0xb1, 0x7c, 0x38, 0xfa, 0x90, 0xf4, 0x13, 0x94,
+ 0x9d, 0xea, 0x11, 0xaa, 0x12, 0x08, 0x37, 0x34, 0x87, 0x5e, 0xc4, 0x4f,
+ 0xec, 0x7d, 0x36, 0xa0, 0xc2, 0x43, 0x53, 0x1e, 0xc8, 0x65, 0x3c, 0xb3,
+ 0xb0, 0x7b, 0xb2, 0xbc, 0x6f, 0x2c, 0x61, 0xbd, 0x7e, 0x3f, 0xc9, 0x59,
+ 0xa0, 0xa9, 0xb5, 0x0e, 0xe5, 0x2d, 0x4e, 0x8c, 0x64, 0x38, 0x0f, 0x7f,
+ 0xbc, 0x46, 0x1e, 0x42, 0x79, 0x6e, 0x4f, 0x34, 0xe1, 0xa0, 0x0c, 0xfd,
+ 0x72, 0x11, 0x38, 0x48, 0xb1, 0x63, 0x53, 0xec, 0x37, 0x56, 0x05, 0x8f,
+ 0xca, 0xfe, 0xf4, 0x98, 0xc0, 0x02, 0x2d, 0x49, 0xf2, 0x70, 0xfa, 0x0f,
+ 0xa5, 0xa3, 0x76, 0x0e, 0x1e, 0xa1, 0xf9, 0x93, 0xf6, 0xfc, 0x91, 0xfd,
+ 0x4b, 0x25, 0x09, 0xd7, 0xb7, 0x1e, 0xc5, 0xc4, 0xc2, 0x0a, 0x0d, 0x41,
+ 0xc2, 0x04, 0x5c, 0xcb, 0xd6, 0x13, 0x8f, 0x9b, 0x1f, 0xe3, 0xbe, 0xe6,
+ 0x6f, 0xd7, 0xdc, 0x30, 0xce, 0x7e, 0xfd, 0xf1, 0x9a, 0x77, 0xd3, 0x6a,
+ 0xb2, 0x9e, 0xea, 0x87, 0x6a, 0x92, 0xc3, 0xbd, 0x43, 0xdc, 0x4f, 0xa8,
+ 0x37, 0x5e, 0x3f, 0xcc, 0x79, 0x59, 0x1d, 0x68, 0x10, 0x3e, 0x71, 0x73,
+ 0x46, 0xed, 0x63, 0xc2, 0x2f, 0x47, 0xd4, 0x20, 0xc9, 0xae, 0xf3, 0x1e,
+ 0xd1, 0xc7, 0x35, 0x8b, 0x2d, 0xb7, 0xeb, 0xf2, 0x15, 0xdc, 0x11, 0x9e,
+ 0xc3, 0x21, 0x51, 0x1b, 0x77, 0x58, 0xd6, 0x9e, 0x18, 0xe7, 0x71, 0xfb,
+ 0x4c, 0x00, 0x5d, 0xaf, 0x33, 0x96, 0x52, 0x6d, 0x31, 0xc8, 0xf4, 0xf1,
+ 0x19, 0x0f, 0x89, 0x6a, 0xd1, 0xec, 0xab, 0x73, 0xb8, 0xc4, 0x87, 0x7d,
+ 0x74, 0xbd, 0x6c, 0xe3, 0x13, 0x3e, 0xa7, 0xe8, 0x35, 0x94, 0xc7, 0xf8,
+ 0x6c, 0xe3, 0x6f, 0xd7, 0xac, 0x1f, 0x53, 0x43, 0x12, 0xf1, 0xb1, 0x97,
+ 0xf7, 0xe7, 0x69, 0xce, 0x69, 0x9d, 0xe9, 0xbe, 0xbc, 0x86, 0xfb, 0xb1,
+ 0x4b, 0x88, 0x6e, 0x2b, 0x1b, 0x66, 0x0c, 0x6a, 0xdb, 0x4a, 0x22, 0x4f,
+ 0x55, 0xfd, 0xe2, 0x0a, 0xaf, 0x2e, 0xd2, 0xc9, 0xb1, 0x74, 0x12, 0xa7,
+ 0xe2, 0x15, 0xfd, 0xac, 0xcb, 0x7f, 0x03, 0xa9, 0xfa, 0x0e, 0xe4, 0xb2,
+ 0x8a, 0x7f, 0x43, 0xa6, 0x03, 0xa3, 0xa4, 0xc3, 0xbb, 0x8b, 0x41, 0x7f,
+ 0x47, 0x46, 0x43, 0x6f, 0x91, 0xeb, 0x2b, 0x18, 0x7b, 0xc6, 0x26, 0xe7,
+ 0xea, 0xe0, 0x4a, 0x2e, 0x39, 0x90, 0xa9, 0xd8, 0x5c, 0x38, 0xef, 0x99,
+ 0x0d, 0x89, 0xca, 0xbc, 0x32, 0xad, 0x23, 0x0f, 0xfd, 0x89, 0x85, 0x85,
+ 0x6c, 0x0b, 0x77, 0x60, 0x6c, 0xdc, 0x6f, 0x2e, 0x36, 0x14, 0xac, 0x6a,
+ 0xfd, 0x73, 0x7a, 0xb6, 0x05, 0x1f, 0x1f, 0xff, 0x3a, 0xca, 0xdf, 0x24,
+ 0x7c, 0x94, 0x49, 0xa2, 0xb9, 0xf5, 0x16, 0xa4, 0xfe, 0x40, 0xc6, 0xd3,
+ 0x19, 0x1f, 0x9e, 0xcf, 0x54, 0xf6, 0xec, 0x7f, 0x94, 0x25, 0x3f, 0x24,
+ 0x1f, 0x78, 0xee, 0x4b, 0xf7, 0x49, 0x29, 0x9e, 0x3b, 0x78, 0x0f, 0xff,
+ 0x1f, 0x1e, 0x77, 0xde, 0x1e, 0xe7, 0x11, 0x75, 0x23, 0xf3, 0xf3, 0x5a,
+ 0xd0, 0x5a, 0xff, 0xbe, 0x67, 0x08, 0xf3, 0x81, 0x62, 0x48, 0xe5, 0x8c,
+ 0x83, 0x90, 0x47, 0xec, 0x7d, 0x23, 0xc2, 0xb9, 0x11, 0xfd, 0x02, 0x4c,
+ 0xb8, 0x09, 0x5f, 0x2d, 0x25, 0x59, 0x68, 0x99, 0x80, 0x5f, 0x2a, 0x2a,
+ 0xf4, 0xdf, 0xe8, 0x77, 0x92, 0x7c, 0x9c, 0xc5, 0x8f, 0x28, 0xa6, 0xb0,
+ 0x4f, 0x55, 0x72, 0x9c, 0x54, 0x7c, 0xc4, 0x4b, 0xc0, 0x87, 0x3e, 0x2b,
+ 0x36, 0x1d, 0xca, 0x2f, 0xf6, 0x32, 0x96, 0xc9, 0x65, 0x2a, 0xbf, 0x23,
+ 0x57, 0x7f, 0x93, 0x9e, 0x6d, 0x99, 0x8d, 0xd0, 0x6f, 0x96, 0xc5, 0x73,
+ 0x56, 0x6a, 0x33, 0xcb, 0x2b, 0xe0, 0x7f, 0x83, 0xe4, 0x3f, 0x46, 0x34,
+ 0x66, 0x69, 0x8d, 0xd7, 0x69, 0xcd, 0x4c, 0xf1, 0x10, 0x8d, 0xe1, 0x7b,
+ 0x24, 0x67, 0xdb, 0x76, 0x0f, 0x7b, 0xf9, 0x7c, 0xc2, 0xf3, 0x19, 0x60,
+ 0x30, 0x6b, 0xaa, 0xce, 0xb9, 0x73, 0x9d, 0x83, 0x94, 0x2f, 0xab, 0x28,
+ 0x16, 0xbd, 0x19, 0xdf, 0x8e, 0x1b, 0x73, 0x6a, 0xd2, 0x24, 0x3c, 0x96,
+ 0x52, 0x20, 0x48, 0x77, 0x64, 0xc3, 0x01, 0xe3, 0xdd, 0x74, 0x23, 0xf1,
+ 0x14, 0x0e, 0x5d, 0xa0, 0xf1, 0xa6, 0x53, 0xc6, 0x81, 0x51, 0x07, 0x2e,
+ 0xf0, 0x1e, 0xb2, 0xa8, 0x3c, 0x6f, 0x82, 0xc7, 0xce, 0x7f, 0xaf, 0xa6,
+ 0xba, 0x2e, 0x9c, 0xa0, 0xac, 0x6a, 0xd6, 0x10, 0x6e, 0xcf, 0xb7, 0x3f,
+ 0x82, 0x43, 0x54, 0xeb, 0xef, 0x88, 0x85, 0x90, 0xac, 0x8b, 0x53, 0xbd,
+ 0xd1, 0xdc, 0x7f, 0x09, 0xff, 0xcd, 0x2a, 0xf3, 0x3e, 0xbc, 0x08, 0x27,
+ 0x2e, 0xe1, 0x53, 0xcb, 0xa1, 0x69, 0x67, 0xa7, 0xa0, 0x95, 0x2f, 0xa0,
+ 0x79, 0xe0, 0x13, 0xbc, 0x67, 0xf1, 0x1e, 0xbd, 0xec, 0x70, 0x10, 0x06,
+ 0x0c, 0x2b, 0x4e, 0x04, 0x50, 0x0e, 0x38, 0xb0, 0x49, 0xe7, 0xde, 0xb4,
+ 0x3a, 0xf0, 0x24, 0x61, 0xf9, 0x77, 0x44, 0x73, 0xdf, 0x87, 0x38, 0x6f,
+ 0x4d, 0xd4, 0xf1, 0xba, 0x02, 0x89, 0xeb, 0x9b, 0xcf, 0xba, 0xa1, 0x76,
+ 0xba, 0x84, 0x96, 0x68, 0x70, 0xfc, 0x95, 0x75, 0x3e, 0xf0, 0xa9, 0xa5,
+ 0x45, 0x3e, 0x25, 0x1c, 0xa4, 0x05, 0x27, 0xc9, 0xf6, 0xfb, 0x30, 0x4f,
+ 0x9b, 0xa8, 0x86, 0x57, 0x27, 0x1a, 0x18, 0xf7, 0x99, 0x9e, 0x7d, 0x44,
+ 0xdb, 0x6b, 0x84, 0x03, 0x76, 0xc4, 0x2e, 0x59, 0xc9, 0x85, 0x7c, 0xfe,
+ 0x4f, 0xa9, 0xae, 0xf4, 0xc0, 0xb9, 0x6f, 0x72, 0x07, 0xee, 0x4a, 0x3b,
+ 0x49, 0x4e, 0xf3, 0x78, 0xcd, 0x45, 0x31, 0x98, 0x63, 0x7f, 0xf9, 0x3a,
+ 0x2a, 0xcd, 0x24, 0x2a, 0xf1, 0xb1, 0x87, 0xe2, 0xc2, 0x6e, 0x3b, 0x17,
+ 0xc0, 0xbb, 0x64, 0x55, 0x2b, 0x3e, 0x19, 0x7f, 0xd3, 0x4b, 0xbe, 0xb4,
+ 0x4e, 0x6b, 0x83, 0x08, 0x66, 0x4c, 0x51, 0x6b, 0x38, 0xf0, 0x61, 0xbb,
+ 0xda, 0x29, 0x39, 0x06, 0x70, 0x7d, 0xcc, 0xb4, 0x7c, 0x9a, 0xd6, 0xd3,
+ 0x22, 0x22, 0xdd, 0x45, 0x11, 0x45, 0x75, 0xd1, 0x27, 0x57, 0x17, 0x5b,
+ 0x64, 0x6f, 0xd1, 0xf4, 0x28, 0xab, 0xb6, 0x53, 0xdd, 0xb2, 0x8b, 0x6a,
+ 0x5b, 0x1f, 0xd5, 0xd7, 0xaa, 0x7e, 0x11, 0x6e, 0x92, 0x7f, 0x08, 0xfb,
+ 0x4a, 0x06, 0x9c, 0x99, 0x9d, 0x70, 0x65, 0xc2, 0xca, 0x5e, 0xec, 0x42,
+ 0x32, 0x58, 0xc1, 0xb6, 0x32, 0xe9, 0xaa, 0xaa, 0x9d, 0xb1, 0xcc, 0x76,
+ 0x9c, 0x9f, 0x60, 0x7c, 0x9e, 0xc0, 0xd6, 0x34, 0xff, 0x86, 0xf7, 0xc5,
+ 0xb8, 0x81, 0x93, 0x54, 0x3b, 0x79, 0x5a, 0x1b, 0x48, 0x0f, 0x8d, 0x18,
+ 0x2c, 0x09, 0x36, 0x2b, 0xd2, 0x05, 0xbc, 0x27, 0xdb, 0x65, 0x1c, 0x9c,
+ 0xa2, 0x44, 0x42, 0xf9, 0xca, 0x99, 0x51, 0x28, 0x4e, 0xc8, 0xf0, 0x69,
+ 0x3e, 0xfa, 0x1d, 0xe0, 0x73, 0x4b, 0x64, 0x67, 0xbf, 0x5d, 0xd3, 0x62,
+ 0xc7, 0x9a, 0x7a, 0xaa, 0x75, 0xde, 0x21, 0x5e, 0x58, 0x16, 0x06, 0xaa,
+ 0x47, 0xe6, 0x6b, 0xc2, 0xf5, 0xb7, 0x55, 0x23, 0x48, 0x73, 0x32, 0x0e,
+ 0xac, 0x9c, 0x57, 0x5d, 0x1f, 0x6b, 0x45, 0x21, 0x27, 0xe6, 0x30, 0xd6,
+ 0xa0, 0xea, 0xc3, 0x3a, 0x1c, 0xa2, 0xda, 0xdf, 0xaf, 0x6d, 0x45, 0x46,
+ 0x29, 0x7b, 0x7f, 0x11, 0xe7, 0x1a, 0x00, 0xde, 0x5e, 0xc2, 0x50, 0x43,
+ 0xe9, 0xaf, 0x72, 0xcc, 0xf4, 0xdc, 0x1d, 0xd7, 0x71, 0x24, 0x47, 0x21,
+ 0x4a, 0x5b, 0x87, 0xda, 0xb6, 0x2e, 0x7c, 0x58, 0xc7, 0xf8, 0x97, 0x62,
+ 0x15, 0xd1, 0xb3, 0x77, 0x2a, 0x60, 0x9f, 0xab, 0xd8, 0x57, 0x9a, 0xa7,
+ 0xf9, 0x5a, 0x5a, 0xbf, 0x8c, 0x46, 0x96, 0xc9, 0x3f, 0x44, 0x23, 0xd9,
+ 0x2c, 0x61, 0x9e, 0x5c, 0xba, 0x17, 0x2f, 0xa7, 0x79, 0xde, 0x70, 0x52,
+ 0x17, 0x0a, 0xf7, 0xe6, 0x6d, 0x99, 0x98, 0x53, 0xbc, 0x06, 0xaf, 0x3f,
+ 0xbf, 0x4e, 0x80, 0x6a, 0x85, 0x7f, 0xec, 0x5a, 0x14, 0x37, 0x72, 0xeb,
+ 0xa8, 0xee, 0x8c, 0x42, 0xfb, 0xfd, 0x32, 0xe9, 0x83, 0x7b, 0xd5, 0x4b,
+ 0x09, 0xf3, 0xc2, 0xf3, 0x4a, 0x9c, 0xcf, 0x30, 0x5b, 0xbb, 0x64, 0xc3,
+ 0xb2, 0x5c, 0xed, 0x9a, 0xf2, 0x36, 0xd8, 0x0e, 0x7d, 0xbc, 0xe7, 0xe1,
+ 0xd9, 0xdb, 0xee, 0xc3, 0x41, 0xca, 0x81, 0x4f, 0xa5, 0x9b, 0x4d, 0xae,
+ 0xfd, 0xc0, 0x38, 0x54, 0xa4, 0xe8, 0xd9, 0x7f, 0x55, 0xcd, 0x3e, 0xbb,
+ 0xa7, 0xb4, 0x13, 0x52, 0xa6, 0xa7, 0x9a, 0xeb, 0x0d, 0x37, 0xd5, 0xc9,
+ 0x83, 0x69, 0xa6, 0xd7, 0xda, 0xe5, 0xa4, 0xb9, 0x76, 0xc7, 0xb5, 0xd9,
+ 0x1b, 0xc9, 0x2e, 0x1a, 0x0c, 0x96, 0x63, 0x00, 0x4f, 0xd0, 0xd8, 0x50,
+ 0x89, 0x65, 0x79, 0xa8, 0x9a, 0xfb, 0x9e, 0xfb, 0x48, 0xbf, 0xb5, 0xd9,
+ 0xca, 0x3c, 0xd9, 0x52, 0x1f, 0x96, 0x0e, 0xbd, 0x58, 0x5d, 0xa9, 0x7d,
+ 0xb8, 0x2e, 0xef, 0xc7, 0xbe, 0x74, 0x00, 0x53, 0xe9, 0x66, 0xe5, 0x05,
+ 0xfb, 0xcc, 0x40, 0xa5, 0x47, 0x36, 0x98, 0x9e, 0x1f, 0x13, 0xc0, 0xe4,
+ 0xd5, 0xef, 0x2c, 0x9f, 0x4a, 0xef, 0xf4, 0x94, 0x8d, 0xf9, 0x65, 0x4c,
+ 0x04, 0x2a, 0x78, 0x88, 0x62, 0x85, 0xf7, 0x51, 0xd2, 0xeb, 0x3b, 0xa4,
+ 0x57, 0x89, 0xf4, 0xfa, 0x82, 0xfe, 0x23, 0xc6, 0x2c, 0x9e, 0x3d, 0x71,
+ 0x1f, 0xef, 0x13, 0x99, 0x04, 0x5a, 0xec, 0x31, 0x99, 0xb8, 0x13, 0xe7,
+ 0x86, 0xf8, 0x6c, 0xe2, 0x47, 0x6b, 0x5e, 0x4a, 0x5b, 0xeb, 0x66, 0x62,
+ 0xcd, 0xa9, 0x77, 0x08, 0x4f, 0x9b, 0x7f, 0xa0, 0xea, 0xe7, 0xc9, 0x4f,
+ 0xb3, 0xa3, 0x7f, 0x88, 0xf3, 0x75, 0xcd, 0xca, 0xcf, 0x61, 0x7a, 0x1e,
+ 0x8f, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0x6d, 0xff, 0x92, 0x9c, 0x2c,
+ 0x0e, 0x87, 0xd6, 0x3c, 0xfb, 0x02, 0xfe, 0x23, 0xce, 0x2f, 0x0e, 0xeb,
+ 0x2f, 0x80, 0xc7, 0x54, 0xea, 0xf1, 0xf0, 0xf4, 0x7d, 0x7c, 0x9e, 0x2a,
+ 0x48, 0x69, 0xb4, 0xb2, 0x9f, 0x95, 0xe6, 0xfd, 0x37, 0x81, 0x89, 0x2d,
+ 0x54, 0x4b, 0xdb, 0xe7, 0x58, 0xe1, 0x7d, 0x92, 0xfc, 0x22, 0x3a, 0xcc,
+ 0xe3, 0x3f, 0x5e, 0xa3, 0xe5, 0x43, 0x70, 0x10, 0xc6, 0x49, 0x05, 0xd4,
+ 0x4e, 0x20, 0xe8, 0x7f, 0x32, 0x1d, 0xa4, 0x1a, 0xad, 0xb9, 0x3b, 0x2a,
+ 0xee, 0x9c, 0xdb, 0xf7, 0xe6, 0x3c, 0xf7, 0xf1, 0x9a, 0x63, 0x69, 0x35,
+ 0xf5, 0x24, 0x9a, 0x7b, 0x7c, 0xe2, 0x0e, 0xa4, 0xea, 0x9a, 0xfb, 0x4e,
+ 0x22, 0x9c, 0xf0, 0x08, 0x35, 0x7a, 0x1e, 0x95, 0x79, 0x96, 0xe5, 0x1d,
+ 0x54, 0x27, 0x72, 0x9c, 0x49, 0xe3, 0xa4, 0xe2, 0xc0, 0xf2, 0x56, 0x6d,
+ 0x76, 0x12, 0xf3, 0xf6, 0x52, 0x19, 0xb3, 0x2e, 0x4f, 0xe3, 0x1d, 0x0a,
+ 0xd5, 0xfb, 0x6e, 0x38, 0xeb, 0x79, 0x4f, 0x71, 0x27, 0x76, 0xa4, 0x39,
+ 0x4f, 0x93, 0x5c, 0xc8, 0x37, 0xbb, 0x23, 0x3b, 0xd1, 0x9f, 0x0f, 0xe0,
+ 0x50, 0x36, 0xbc, 0x7f, 0x2f, 0xe1, 0xba, 0xe1, 0x52, 0x38, 0xb4, 0x4d,
+ 0x04, 0x48, 0xdf, 0x54, 0xff, 0xd7, 0x07, 0xa9, 0x4e, 0x56, 0xe8, 0xbf,
+ 0x52, 0xcf, 0xbc, 0x44, 0xf5, 0xcc, 0x39, 0xf2, 0x35, 0xdf, 0x5c, 0xad,
+ 0xba, 0x6c, 0xc2, 0xc2, 0x4c, 0x6c, 0x23, 0x2e, 0xdb, 0x3a, 0x0b, 0x92,
+ 0x8d, 0x71, 0x2e, 0xe2, 0xb3, 0x35, 0x1e, 0xb1, 0x6d, 0xd8, 0xf4, 0x3c,
+ 0xd8, 0x1e, 0x44, 0x38, 0xc3, 0x98, 0x53, 0xfa, 0xa6, 0x83, 0xe4, 0x31,
+ 0xa5, 0xed, 0xc2, 0x86, 0xd8, 0x2e, 0xf4, 0xeb, 0x7f, 0x02, 0x77, 0x3d,
+ 0xc7, 0x23, 0xd9, 0xac, 0xa5, 0x79, 0x2f, 0xb5, 0x77, 0x21, 0x7c, 0x94,
+ 0x73, 0x30, 0x55, 0xc3, 0x43, 0xec, 0xbb, 0x3c, 0xff, 0x6d, 0xc6, 0x0a,
+ 0xc2, 0x15, 0x35, 0xed, 0x95, 0x3c, 0x7f, 0x7d, 0x9e, 0xcf, 0x74, 0x82,
+ 0x6a, 0x53, 0x78, 0xdf, 0x5a, 0x6d, 0xe0, 0x71, 0x8a, 0x31, 0x89, 0x36,
+ 0x17, 0xb0, 0x80, 0xcf, 0x2e, 0x57, 0xea, 0x18, 0xe6, 0x77, 0x69, 0x5e,
+ 0x60, 0x3a, 0x4e, 0xf6, 0xf1, 0x77, 0xce, 0x28, 0x85, 0xe6, 0xce, 0x96,
+ 0x72, 0xff, 0xe4, 0xb0, 0x95, 0xe4, 0xf7, 0x0d, 0xa4, 0xa0, 0x8f, 0xe2,
+ 0x6d, 0xb0, 0x0c, 0x2a, 0xea, 0x29, 0x2e, 0x3b, 0xb4, 0x79, 0xb9, 0xb3,
+ 0xac, 0x4f, 0x58, 0x13, 0x73, 0xba, 0x70, 0xd2, 0x33, 0x7b, 0xc6, 0xd4,
+ 0x81, 0xbd, 0x68, 0xee, 0x7f, 0x57, 0x54, 0xd9, 0x3b, 0x98, 0x93, 0x2d,
+ 0x48, 0x2d, 0x31, 0x9c, 0x5b, 0x3e, 0xc9, 0xae, 0x23, 0x3a, 0x2e, 0x10,
+ 0x08, 0x5d, 0x6f, 0xef, 0x73, 0x4d, 0xb6, 0xfc, 0x29, 0xcd, 0xcd, 0xdf,
+ 0xff, 0xd8, 0xc7, 0x67, 0x2e, 0x4f, 0x65, 0x9f, 0xb7, 0xa2, 0x0b, 0x2b,
+ 0xf2, 0x39, 0x4d, 0xbe, 0x1f, 0x34, 0x24, 0x34, 0x68, 0x91, 0xd9, 0x1e,
+ 0xfa, 0xfd, 0xd7, 0x79, 0x42, 0xfb, 0xab, 0xfb, 0xf0, 0xcb, 0x09, 0x03,
+ 0x07, 0x28, 0x0f, 0xd4, 0x6a, 0xaa, 0x32, 0x81, 0x10, 0xd7, 0xd2, 0x36,
+ 0xff, 0x2b, 0x27, 0xc8, 0x0f, 0xeb, 0x14, 0xbb, 0xc6, 0xa8, 0xf0, 0x77,
+ 0x99, 0xf8, 0x7b, 0xd0, 0xc7, 0xbe, 0xb0, 0x84, 0xfc, 0x62, 0x3f, 0xf9,
+ 0xeb, 0x01, 0xb2, 0x35, 0xaa, 0xe0, 0xc9, 0x0f, 0xd4, 0xfd, 0x20, 0x7f,
+ 0x1d, 0x4e, 0xb3, 0xfc, 0x83, 0xfe, 0x5e, 0x3e, 0xde, 0xac, 0xd9, 0x7d,
+ 0x55, 0x3d, 0x24, 0x71, 0xdc, 0xb5, 0xe3, 0xa9, 0x19, 0x92, 0xac, 0x6a,
+ 0xa6, 0x6b, 0xb0, 0x14, 0x0e, 0x7a, 0xf9, 0x5d, 0x00, 0x02, 0x87, 0xbd,
+ 0x7a, 0x25, 0x57, 0xce, 0x50, 0x3e, 0xba, 0x4c, 0x74, 0x1c, 0x8a, 0x35,
+ 0x20, 0x45, 0xf9, 0x28, 0xa3, 0x55, 0x6c, 0x49, 0x9b, 0x66, 0x8c, 0x59,
+ 0x6f, 0x04, 0xc7, 0xd5, 0x90, 0xcb, 0xd1, 0x3c, 0x70, 0x06, 0x3b, 0xad,
+ 0xf3, 0x75, 0x6c, 0x53, 0x2e, 0x1c, 0x6f, 0x99, 0xb6, 0xca, 0x01, 0xe6,
+ 0xd7, 0x81, 0xe7, 0x75, 0xb2, 0x99, 0xc5, 0xe1, 0xe0, 0xf3, 0x94, 0x53,
+ 0xa7, 0xe6, 0xf4, 0x11, 0xce, 0xcf, 0xdb, 0xe3, 0x5a, 0x96, 0x75, 0x34,
+ 0x05, 0x2d, 0x91, 0x47, 0x2f, 0x7d, 0x6f, 0x0a, 0x5e, 0x9e, 0xb3, 0xd5,
+ 0x15, 0xd3, 0xaf, 0xfb, 0xe6, 0xde, 0xcb, 0xb1, 0x9f, 0x09, 0xe5, 0xff,
+ 0x88, 0x7e, 0xf3, 0x9c, 0x01, 0xc6, 0x32, 0x7c, 0x56, 0xcb, 0xbb, 0xa3,
+ 0xdd, 0xcd, 0xfe, 0xa2, 0xf0, 0x3b, 0x09, 0x1b, 0x86, 0xb9, 0x2f, 0xcc,
+ 0x3d, 0x1a, 0x07, 0xf6, 0x5e, 0x7d, 0x67, 0x82, 0x3f, 0x3b, 0xb1, 0x69,
+ 0x98, 0x7b, 0x11, 0xa7, 0x6f, 0x90, 0xf1, 0x37, 0x94, 0x87, 0x65, 0xf6,
+ 0x79, 0xf2, 0xf5, 0x4f, 0xd7, 0xbc, 0x34, 0xc6, 0x39, 0x35, 0x60, 0xdc,
+ 0x95, 0x9e, 0xd7, 0xf1, 0x55, 0x9e, 0xce, 0xde, 0x4d, 0x71, 0x27, 0x93,
+ 0x56, 0x07, 0x22, 0x0e, 0x7b, 0x7f, 0x2d, 0x55, 0x14, 0x5f, 0xa5, 0x22,
+ 0x8d, 0xe7, 0x53, 0xfc, 0x03, 0x87, 0x43, 0xc8, 0x64, 0xbb, 0xf0, 0x8d,
+ 0x61, 0xcb, 0x72, 0xb7, 0x39, 0xf1, 0xca, 0x90, 0x85, 0x0f, 0x62, 0xc0,
+ 0xcb, 0x43, 0xe1, 0x81, 0x73, 0xc0, 0xb7, 0x6b, 0xa9, 0x46, 0x6e, 0x11,
+ 0x6a, 0x37, 0x61, 0x83, 0xd0, 0x7b, 0x68, 0x0e, 0xe6, 0xa1, 0x9e, 0xdd,
+ 0x4d, 0xf3, 0xbd, 0x58, 0x00, 0x7e, 0x59, 0xf0, 0xe2, 0x17, 0xc3, 0x3c,
+ 0xa7, 0x17, 0xe7, 0x8e, 0xd6, 0xfb, 0x77, 0xd2, 0x5c, 0x07, 0x29, 0xbe,
+ 0x77, 0x1d, 0x4b, 0x60, 0xd3, 0x61, 0x81, 0x68, 0x24, 0x81, 0xce, 0x63,
+ 0x35, 0xd8, 0x38, 0x2c, 0xe3, 0xfd, 0x78, 0x0d, 0x6e, 0x39, 0x3a, 0xcf,
+ 0x47, 0xa5, 0xaf, 0xc1, 0x67, 0x35, 0xf9, 0x1c, 0xdc, 0xc9, 0x2c, 0xc7,
+ 0x6c, 0xca, 0x17, 0x59, 0x8e, 0x81, 0x96, 0x15, 0x6c, 0xaf, 0xf4, 0x39,
+ 0x9e, 0xa6, 0xfc, 0xf1, 0x78, 0xbb, 0x16, 0x0c, 0x4a, 0x06, 0x96, 0x8f,
+ 0x96, 0xef, 0xac, 0x85, 0x75, 0x8a, 0xf7, 0x33, 0x3e, 0x6a, 0xb1, 0xac,
+ 0x4d, 0xf1, 0xc8, 0xec, 0xbd, 0x36, 0xae, 0x0d, 0x90, 0x4f, 0x35, 0xe2,
+ 0xf1, 0xec, 0xfc, 0x9e, 0x97, 0xd6, 0x73, 0xc9, 0x61, 0xee, 0x52, 0x60,
+ 0x5d, 0xa9, 0x32, 0xac, 0x8f, 0x5c, 0x46, 0x24, 0xf8, 0x80, 0xe0, 0xb3,
+ 0x22, 0xdc, 0x13, 0xb7, 0xac, 0x37, 0xe3, 0x96, 0x55, 0x88, 0x9b, 0x9e,
+ 0x15, 0xab, 0x14, 0x1c, 0x5b, 0xc6, 0xef, 0x2a, 0x84, 0x93, 0x0d, 0x64,
+ 0x5f, 0xde, 0x65, 0x5a, 0x70, 0x2b, 0x54, 0xd3, 0xa4, 0x20, 0x17, 0x5a,
+ 0xa8, 0xf6, 0x00, 0x8d, 0xfe, 0x43, 0x43, 0xf5, 0xf8, 0xfe, 0xcc, 0xef,
+ 0xf2, 0xf1, 0x1d, 0xbb, 0x9f, 0x76, 0x45, 0xc7, 0xba, 0x5a, 0x44, 0x92,
+ 0xf7, 0x80, 0x7b, 0xa3, 0x7c, 0xa6, 0xd5, 0xc4, 0x2d, 0xf1, 0x3e, 0xec,
+ 0x18, 0xe6, 0x7d, 0xb6, 0x3a, 0xe3, 0xca, 0xb0, 0xf5, 0xd7, 0x1e, 0xa2,
+ 0x7f, 0x5d, 0x7b, 0x73, 0xca, 0x6b, 0xbf, 0xe3, 0xe4, 0x34, 0xd6, 0x8f,
+ 0xd5, 0xa1, 0x34, 0xa5, 0x95, 0x97, 0x88, 0xe4, 0x1b, 0x3e, 0x44, 0x82,
+ 0x0d, 0x14, 0xab, 0x66, 0xc8, 0x77, 0xa7, 0x4a, 0x5c, 0x07, 0x2c, 0x30,
+ 0xac, 0xd1, 0x45, 0x98, 0x9c, 0xa1, 0xb9, 0xb2, 0x5a, 0xe7, 0x07, 0x84,
+ 0xf3, 0xaa, 0x0d, 0xab, 0xd6, 0x6b, 0x44, 0xce, 0x36, 0x0b, 0x07, 0x66,
+ 0xdb, 0x2c, 0xab, 0xab, 0x5d, 0x1b, 0xa8, 0x11, 0xe8, 0x97, 0x0c, 0x2d,
+ 0xd1, 0xe2, 0xc0, 0xd7, 0x82, 0x88, 0x74, 0xbe, 0x89, 0x48, 0xcf, 0x05,
+ 0x8a, 0x61, 0x4f, 0x95, 0xf8, 0x9c, 0xf0, 0x23, 0xf8, 0xeb, 0xe1, 0x85,
+ 0x38, 0x35, 0xd5, 0x3f, 0xd7, 0x13, 0x83, 0xf7, 0xfa, 0x55, 0x06, 0x8e,
+ 0x0f, 0x87, 0xc8, 0x7e, 0xdc, 0x14, 0xd7, 0x65, 0x48, 0x4d, 0x90, 0xeb,
+ 0xa8, 0x4e, 0x88, 0x3d, 0x66, 0x59, 0x2b, 0x9a, 0x2a, 0x35, 0xcf, 0x8a,
+ 0xe9, 0x6b, 0xdf, 0x71, 0x98, 0xef, 0xf7, 0x04, 0x49, 0x7f, 0xcd, 0xa9,
+ 0x1d, 0xe2, 0x8c, 0x65, 0xfe, 0x81, 0x20, 0x9e, 0x7b, 0x6a, 0xe0, 0x65,
+ 0xbe, 0x65, 0xec, 0x1e, 0xe5, 0x3e, 0x1c, 0xeb, 0x0d, 0xde, 0xce, 0x38,
+ 0xef, 0x97, 0xb3, 0x8e, 0xca, 0xde, 0x0d, 0x71, 0x8a, 0x89, 0xc2, 0x4f,
+ 0x78, 0xca, 0xf4, 0x74, 0x50, 0x7e, 0xaa, 0x1a, 0xe6, 0xf7, 0x2d, 0x7c,
+ 0x38, 0x40, 0x71, 0xe3, 0xb2, 0x5e, 0x8d, 0x43, 0x75, 0x6a, 0x82, 0xeb,
+ 0xe9, 0x27, 0x4b, 0xdc, 0x33, 0xdc, 0x89, 0xed, 0xfc, 0xbe, 0x4a, 0x69,
+ 0xb5, 0x7d, 0xb6, 0x90, 0xae, 0x11, 0x36, 0x60, 0x3a, 0xe6, 0xd7, 0xef,
+ 0xc4, 0x92, 0x21, 0xd6, 0xe3, 0xc7, 0x6b, 0x82, 0x24, 0xa3, 0xc7, 0xc9,
+ 0x2e, 0x24, 0xa3, 0x03, 0xf2, 0x90, 0x65, 0xdd, 0x18, 0xbf, 0x76, 0x0e,
+ 0xad, 0xff, 0x82, 0x83, 0xea, 0x3b, 0x07, 0xef, 0xeb, 0xa9, 0x89, 0x13,
+ 0xe2, 0xda, 0x39, 0x0b, 0x35, 0xdc, 0x4f, 0x34, 0xa7, 0x2a, 0x79, 0xe9,
+ 0x38, 0xe5, 0xa5, 0x97, 0x73, 0xec, 0x23, 0xf5, 0x06, 0xfb, 0x88, 0x44,
+ 0xb1, 0x76, 0x7d, 0x3a, 0x84, 0x0b, 0x3a, 0x34, 0x37, 0x62, 0x44, 0x77,
+ 0xa4, 0xbb, 0x63, 0x0e, 0xf3, 0xb9, 0x28, 0xfe, 0x4f, 0xe5, 0x78, 0xaf,
+ 0x4d, 0xa0, 0x46, 0x63, 0x1b, 0xb0, 0x73, 0x01, 0xc5, 0xb4, 0x7e, 0xd4,
+ 0xae, 0x06, 0x2e, 0x0d, 0xf1, 0xfe, 0x8c, 0x86, 0x03, 0xa5, 0x01, 0xd1,
+ 0x30, 0xf4, 0x5b, 0x2b, 0x54, 0x35, 0xbf, 0x07, 0xf8, 0x30, 0xef, 0x01,
+ 0x92, 0x0d, 0xf4, 0xdb, 0xe7, 0x7c, 0xde, 0x4c, 0xf3, 0x39, 0x9f, 0x70,
+ 0x68, 0x13, 0xf9, 0x4e, 0x2f, 0x9a, 0xf5, 0x69, 0xc2, 0xce, 0xb3, 0x44,
+ 0x67, 0x93, 0xa8, 0xec, 0x73, 0x45, 0xe6, 0xf6, 0xe9, 0x96, 0xe5, 0x3b,
+ 0x45, 0x4d, 0x81, 0x69, 0x0a, 0x10, 0x4d, 0x1d, 0xa2, 0xfa, 0xd8, 0x06,
+ 0xe1, 0x3b, 0xd6, 0x25, 0xa4, 0x02, 0xc7, 0xe4, 0x3a, 0x63, 0x4f, 0x8e,
+ 0xf3, 0xd9, 0x66, 0xe1, 0x3c, 0xba, 0x45, 0x78, 0x0b, 0x3d, 0xc2, 0x7f,
+ 0xcc, 0xc4, 0xfd, 0xf1, 0x2e, 0x9c, 0x1b, 0xe6, 0xb3, 0x6c, 0xf7, 0x89,
+ 0x9a, 0xb9, 0xbd, 0x39, 0x6f, 0xa1, 0xd1, 0x5f, 0x48, 0x73, 0x7f, 0xf7,
+ 0xe3, 0x35, 0xe9, 0xa1, 0x45, 0xfe, 0xa7, 0xc6, 0x02, 0xfe, 0x27, 0xc7,
+ 0xd4, 0xfe, 0x7d, 0xc2, 0xb2, 0x76, 0xc6, 0xfe, 0x03, 0xeb, 0xd0, 0x6a,
+ 0x8e, 0x55, 0xf0, 0xc1, 0x6e, 0x92, 0xc7, 0x36, 0xca, 0x2d, 0x93, 0x7a,
+ 0xf3, 0x1c, 0x16, 0x51, 0x53, 0xfc, 0xee, 0x1b, 0xfd, 0x77, 0x73, 0x6e,
+ 0xe3, 0x7d, 0x4d, 0x67, 0x3b, 0x28, 0xee, 0x7e, 0xc6, 0x6b, 0xcd, 0x10,
+ 0x9f, 0x51, 0xeb, 0x87, 0xff, 0x4b, 0xf6, 0xf5, 0xce, 0x7d, 0xb6, 0xaf,
+ 0x97, 0x78, 0x52, 0xa8, 0xe5, 0x19, 0xe2, 0xb7, 0xca, 0xf1, 0xb9, 0x3d,
+ 0xbd, 0xb9, 0xfd, 0xbc, 0x4e, 0xe1, 0x2b, 0x70, 0x7d, 0x1e, 0x30, 0x5e,
+ 0x1f, 0xea, 0x10, 0xde, 0x63, 0xc3, 0x94, 0x1f, 0x37, 0x10, 0xcf, 0x7c,
+ 0x76, 0xac, 0x4b, 0xf8, 0x0b, 0x9b, 0x85, 0x8f, 0xf8, 0xac, 0x26, 0x3e,
+ 0x71, 0xcc, 0x23, 0xbc, 0xc4, 0xa3, 0x87, 0x78, 0xf4, 0xce, 0xf1, 0xe8,
+ 0x29, 0x04, 0xfd, 0xe9, 0x74, 0xbd, 0xff, 0xd1, 0x31, 0xc5, 0xbf, 0x6f,
+ 0xcc, 0xb2, 0xde, 0xd7, 0x15, 0x3f, 0xf3, 0xf5, 0xaa, 0xfe, 0x45, 0xbe,
+ 0x6e, 0x20, 0xbe, 0x2a, 0x7b, 0xb1, 0xa4, 0xc3, 0x14, 0xeb, 0x90, 0xcf,
+ 0x71, 0xcc, 0xf3, 0x75, 0x30, 0xcd, 0xfb, 0x95, 0xbc, 0x6f, 0x39, 0x20,
+ 0x56, 0x10, 0x5f, 0x65, 0xe2, 0x6b, 0xe5, 0x97, 0xf0, 0xf5, 0xe1, 0x35,
+ 0x7c, 0xbd, 0xfa, 0xf7, 0xf2, 0xe5, 0x11, 0xcb, 0x87, 0x39, 0x0e, 0xdd,
+ 0x66, 0xc8, 0xc3, 0x16, 0x61, 0x47, 0x07, 0xbe, 0x3f, 0x05, 0x14, 0xb3,
+ 0xbb, 0x20, 0x53, 0xbc, 0x39, 0x1d, 0x8f, 0x84, 0x5e, 0xa1, 0x7a, 0x72,
+ 0xba, 0xe4, 0x15, 0xcb, 0xec, 0x3d, 0x59, 0xac, 0x90, 0x89, 0xa6, 0x19,
+ 0xfb, 0x5d, 0x33, 0xe8, 0xb5, 0x1a, 0xeb, 0x52, 0x3b, 0xbb, 0x15, 0x91,
+ 0x72, 0xc4, 0xd1, 0x25, 0x12, 0x05, 0xde, 0x83, 0xdd, 0x22, 0x56, 0xda,
+ 0xfb, 0xaf, 0x9d, 0xe2, 0xfa, 0x42, 0x87, 0x68, 0x21, 0xbb, 0x68, 0x3e,
+ 0xc6, 0xe7, 0xc1, 0x36, 0x8b, 0xe6, 0x39, 0x79, 0x2c, 0x27, 0x79, 0x0c,
+ 0x7d, 0x4e, 0x1e, 0x1b, 0x6c, 0x79, 0xfc, 0x4c, 0xbf, 0x78, 0x4d, 0x0f,
+ 0x8d, 0xeb, 0x2a, 0xca, 0x86, 0x54, 0x3b, 0xd5, 0xce, 0xd5, 0x4e, 0x6f,
+ 0xc5, 0xf8, 0x9c, 0x8f, 0x69, 0xd5, 0x68, 0x08, 0x39, 0x0d, 0xb5, 0xe7,
+ 0xb4, 0xd0, 0x52, 0xf7, 0x89, 0xe4, 0x26, 0x1f, 0xd5, 0x3f, 0x3b, 0x62,
+ 0x91, 0xe4, 0x72, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, 0x5d, 0xae, 0x2a,
+ 0x9a, 0xd8, 0x47, 0xf1, 0xed, 0xc5, 0x9c, 0x44, 0xd8, 0x81, 0xdf, 0x3f,
+ 0x73, 0xe2, 0x46, 0x82, 0x12, 0x4f, 0x10, 0xee, 0x78, 0x3c, 0xdb, 0x87,
+ 0x27, 0xf2, 0xbd, 0x78, 0x3c, 0xff, 0x77, 0xde, 0xb5, 0x91, 0xbd, 0x46,
+ 0x63, 0xa2, 0x72, 0x16, 0xe1, 0xe3, 0xc4, 0x75, 0x11, 0x96, 0xcd, 0x89,
+ 0x16, 0x39, 0xc2, 0xb5, 0xae, 0xf3, 0x77, 0xdf, 0xd5, 0xd8, 0x17, 0x7b,
+ 0x56, 0xbd, 0x64, 0x63, 0x91, 0x93, 0x6d, 0xc7, 0xec, 0x33, 0x52, 0xe5,
+ 0x95, 0x7b, 0xec, 0x77, 0x41, 0x7d, 0xab, 0xef, 0xd2, 0xd8, 0x1f, 0x4e,
+ 0xc4, 0xd7, 0xdb, 0xf9, 0xb5, 0x71, 0x6d, 0xe5, 0x3d, 0x99, 0xe0, 0xda,
+ 0x4a, 0xaf, 0x26, 0xb0, 0x36, 0x6a, 0x7f, 0x86, 0xd6, 0x56, 0xf6, 0xba,
+ 0xf5, 0xb5, 0x4d, 0xf6, 0x67, 0x74, 0x6d, 0xc5, 0xa7, 0xb4, 0xb5, 0x9a,
+ 0xfd, 0x19, 0x5f, 0x5b, 0xc9, 0xcb, 0x2d, 0x6b, 0x97, 0x5e, 0x7d, 0xbf,
+ 0x86, 0xff, 0xfe, 0x17, 0x9f, 0xed, 0x4e, 0xb2, 0x20, 0x3b, 0x00, 0x00,
+ 0x00 };
static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
@@ -4564,15 +4582,15 @@ static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
0x00000000 };
static struct fw_info bnx2_txp_fw_09 = {
- /* Firmware version: 4.0.5 */
+ /* Firmware version: 4.4.23 */
.ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
+ .ver_minor = 0x4,
+ .ver_fix = 0x17,
.start_addr = 0x08000094,
.text_addr = 0x08000000,
- .text_len = 0x3a50,
+ .text_len = 0x3b1c,
.text_index = 0x0,
.gz_text = bnx2_TXP_b09FwText,
.gz_text_len = sizeof(bnx2_TXP_b09FwText),
@@ -4582,15 +4600,15 @@ static struct fw_info bnx2_txp_fw_09 = {
.data_index = 0x0,
.data = bnx2_TXP_b09FwData,
- .sbss_addr = 0x08003aa0,
+ .sbss_addr = 0x08003b80,
.sbss_len = 0x6c,
.sbss_index = 0x0,
- .bss_addr = 0x08003b0c,
+ .bss_addr = 0x08003bec,
.bss_len = 0x24c,
.bss_index = 0x0,
- .rodata_addr = 0x08003a50,
+ .rodata_addr = 0x08003b1c,
.rodata_len = 0x30,
.rodata_index = 0x0,
.rodata = bnx2_TXP_b09FwRodata,
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c
deleted file mode 100644
index 70cba64732c..00000000000
--- a/drivers/net/bnx2x.c
+++ /dev/null
@@ -1,9988 +0,0 @@
-/* bnx2x.c: Broadcom Everest network driver.
- *
- * Copyright (c) 2007-2008 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.
- *
- * Maintained by: Eilon Greenstein <eilong@broadcom.com>
- * Written by: Eliezer Tamir
- * Based on code from Michael Chan's bnx2 driver
- * UDP CSUM errata workaround by Arik Gendelman
- * Slowpath rework by Vladislav Zolotarov
- * Statistics and Link management by Yitchak Gertner
- *
- */
-
-/* define this to make the driver freeze on error
- * to allow getting debug info
- * (you will need to reboot afterwards)
- */
-/*#define BNX2X_STOP_ON_ERROR*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/device.h> /* for dev_info() */
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/dma-mapping.h>
-#include <linux/bitops.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <asm/byteorder.h>
-#include <linux/time.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#ifdef NETIF_F_HW_VLAN_TX
- #include <linux/if_vlan.h>
- #define BCM_VLAN 1
-#endif
-#include <net/ip.h>
-#include <net/tcp.h>
-#include <net/checksum.h>
-#include <linux/workqueue.h>
-#include <linux/crc32.h>
-#include <linux/prefetch.h>
-#include <linux/zlib.h>
-#include <linux/version.h>
-#include <linux/io.h>
-
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x.h"
-#include "bnx2x_init.h"
-
-#define DRV_MODULE_VERSION "1.42.4"
-#define DRV_MODULE_RELDATE "2008/4/9"
-#define BNX2X_BC_VER 0x040200
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT (5*HZ)
-
-static char version[] __devinitdata =
- "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver "
- DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-
-MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_MODULE_VERSION);
-
-static int use_inta;
-static int poll;
-static int onefunc;
-static int nomcp;
-static int debug;
-static int use_multi;
-
-module_param(use_inta, int, 0);
-module_param(poll, int, 0);
-module_param(onefunc, int, 0);
-module_param(debug, int, 0);
-MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
-MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(onefunc, "enable only first function");
-MODULE_PARM_DESC(nomcp, "ignore management CPU (Implies onefunc)");
-MODULE_PARM_DESC(debug, "default debug msglevel");
-
-#ifdef BNX2X_MULTI
-module_param(use_multi, int, 0);
-MODULE_PARM_DESC(use_multi, "use per-CPU queues");
-#endif
-
-enum bnx2x_board_type {
- BCM57710 = 0,
-};
-
-/* indexed by board_t, above */
-static struct {
- char *name;
-} board_info[] __devinitdata = {
- { "Broadcom NetXtreme II BCM57710 XGb" }
-};
-
-static const struct pci_device_id bnx2x_pci_tbl[] = {
- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
-
-/****************************************************************************
-* General service functions
-****************************************************************************/
-
-/* used only at init
- * locking is done by mcp
- */
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
-{
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
- pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
- PCICFG_VENDOR_ID_OFFSET);
-}
-
-#ifdef BNX2X_IND_RD
-static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
-{
- u32 val;
-
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
- pci_read_config_dword(bp->pdev, PCICFG_GRC_DATA, &val);
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
- PCICFG_VENDOR_ID_OFFSET);
-
- return val;
-}
-#endif
-
-static const u32 dmae_reg_go_c[] = {
- DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
- DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
- DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
- DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
-};
-
-/* copy command into DMAE command memory and set DMAE command go */
-static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
- int idx)
-{
- u32 cmd_offset;
- int i;
-
- cmd_offset = (DMAE_REG_CMD_MEM + sizeof(struct dmae_command) * idx);
- for (i = 0; i < (sizeof(struct dmae_command)/4); i++) {
- REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i));
-
-/* DP(NETIF_MSG_DMAE, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
- idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i)); */
- }
- REG_WR(bp, dmae_reg_go_c[idx], 1);
-}
-
-static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
- u32 dst_addr, u32 len32)
-{
- struct dmae_command *dmae = &bp->dmae;
- int port = bp->port;
- u32 *wb_comp = bnx2x_sp(bp, wb_comp);
- int timeout = 200;
-
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
- dmae->src_addr_lo = U64_LO(dma_addr);
- dmae->src_addr_hi = U64_HI(dma_addr);
- dmae->dst_addr_lo = dst_addr >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = len32;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_val = BNX2X_WB_COMP_VAL;
-
-/*
- DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
- DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
- "dst_addr [%x:%08x (%08x)]\n"
- DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
- dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
-*/
-/*
- DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
- bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
- bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
-*/
-
- *wb_comp = 0;
-
- bnx2x_post_dmae(bp, dmae, port * 8);
-
- udelay(5);
- /* adjust timeout for emulation/FPGA */
- if (CHIP_REV_IS_SLOW(bp))
- timeout *= 100;
- while (*wb_comp != BNX2X_WB_COMP_VAL) {
-/* DP(NETIF_MSG_DMAE, "wb_comp 0x%08x\n", *wb_comp); */
- udelay(5);
- if (!timeout) {
- BNX2X_ERR("dmae timeout!\n");
- break;
- }
- timeout--;
- }
-}
-
-#ifdef BNX2X_DMAE_RD
-static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
-{
- struct dmae_command *dmae = &bp->dmae;
- int port = bp->port;
- u32 *wb_comp = bnx2x_sp(bp, wb_comp);
- int timeout = 200;
-
- memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
- dmae->src_addr_lo = src_addr >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
- dmae->len = len32;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_val = BNX2X_WB_COMP_VAL;
-
-/*
- DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
- DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
- "dst_addr [%x:%08x (%08x)]\n"
- DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
- dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
-*/
-
- *wb_comp = 0;
-
- bnx2x_post_dmae(bp, dmae, port * 8);
-
- udelay(5);
- while (*wb_comp != BNX2X_WB_COMP_VAL) {
- udelay(5);
- if (!timeout) {
- BNX2X_ERR("dmae timeout!\n");
- break;
- }
- timeout--;
- }
-/*
- DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
- bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
- bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
-*/
-}
-#endif
-
-static int bnx2x_mc_assert(struct bnx2x *bp)
-{
- int i, j, rc = 0;
- char last_idx;
- const char storm[] = {"XTCU"};
- const u32 intmem_base[] = {
- BAR_XSTRORM_INTMEM,
- BAR_TSTRORM_INTMEM,
- BAR_CSTRORM_INTMEM,
- BAR_USTRORM_INTMEM
- };
-
- /* Go through all instances of all SEMIs */
- for (i = 0; i < 4; i++) {
- last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET +
- intmem_base[i]);
- if (last_idx)
- BNX2X_LOG("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
- storm[i], last_idx);
-
- /* print the asserts */
- for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) {
- u32 row0, row1, row2, row3;
-
- row0 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) +
- intmem_base[i]);
- row1 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 4 +
- intmem_base[i]);
- row2 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 8 +
- intmem_base[i]);
- row3 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 12 +
- intmem_base[i]);
-
- if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_LOG("DATA %cSTORM_ASSERT_INDEX 0x%x ="
- " 0x%08x 0x%08x 0x%08x 0x%08x\n",
- storm[i], j, row3, row2, row1, row0);
- rc++;
- } else {
- break;
- }
- }
- }
- return rc;
-}
-
-static void bnx2x_fw_dump(struct bnx2x *bp)
-{
- u32 mark, offset;
- u32 data[9];
- int word;
-
- mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
- mark = ((mark + 0x3) & ~0x3);
- printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
-
- for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
- for (word = 0; word < 8; word++)
- data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
- offset + 4*word));
- data[8] = 0x0;
- printk(KERN_CONT "%s", (char *)data);
- }
- for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
- for (word = 0; word < 8; word++)
- data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
- offset + 4*word));
- data[8] = 0x0;
- printk(KERN_CONT "%s", (char *)data);
- }
- printk("\n" KERN_ERR PFX "end of fw dump\n");
-}
-
-static void bnx2x_panic_dump(struct bnx2x *bp)
-{
- int i;
- u16 j, start, end;
-
- BNX2X_ERR("begin crash dump -----------------\n");
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
- struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
-
- BNX2X_ERR("queue[%d]: tx_pkt_prod(%x) tx_pkt_cons(%x)"
- " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)"
- " *rx_cons_sb(%x) rx_comp_prod(%x)"
- " rx_comp_cons(%x) fp_c_idx(%x) fp_u_idx(%x)"
- " bd data(%x,%x)\n",
- i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
- fp->tx_bd_cons, *fp->tx_cons_sb, *fp->rx_cons_sb,
- fp->rx_comp_prod, fp->rx_comp_cons, fp->fp_c_idx,
- fp->fp_u_idx, hw_prods->packets_prod,
- hw_prods->bds_prod);
-
- start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
- end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
- for (j = start; j < end; j++) {
- struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
-
- BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
- sw_bd->skb, sw_bd->first_bd);
- }
-
- start = TX_BD(fp->tx_bd_cons - 10);
- end = TX_BD(fp->tx_bd_cons + 254);
- for (j = start; j < end; j++) {
- u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
-
- BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
- j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
- }
-
- start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
- end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
- for (j = start; j < end; j++) {
- u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
- struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
-
- BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- j, rx_bd[0], rx_bd[1], sw_bd->skb);
- }
-
- start = RCQ_BD(fp->rx_comp_cons - 10);
- end = RCQ_BD(fp->rx_comp_cons + 503);
- for (j = start; j < end; j++) {
- u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
-
- BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
- j, cqe[0], cqe[1], cqe[2], cqe[3]);
- }
- }
-
- BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
- " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
- " spq_prod_idx(%u)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
- bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
-
-
- bnx2x_mc_assert(bp);
- BNX2X_ERR("end crash dump -----------------\n");
-
- bp->stats_state = STATS_STATE_DISABLE;
- DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
-}
-
-static void bnx2x_int_enable(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
- u32 val = REG_RD(bp, addr);
- int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
-
- if (msix) {
- val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
- val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
- } else {
- val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
- HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_INT_LINE_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
-
- /* Errata A0.158 workaround */
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
-
- REG_WR(bp, addr, val);
-
- val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
- }
-
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
-
- REG_WR(bp, addr, val);
-}
-
-static void bnx2x_int_disable(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
- u32 val = REG_RD(bp, addr);
-
- val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
- HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_INT_LINE_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
-
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
- val, port, addr);
-
- REG_WR(bp, addr, val);
- if (REG_RD(bp, addr) != val)
- BNX2X_ERR("BUG! proper val not read from IGU!\n");
-}
-
-static void bnx2x_int_disable_sync(struct bnx2x *bp)
-{
-
- int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
- int i;
-
- atomic_inc(&bp->intr_sem);
- /* prevent the HW from sending interrupts */
- bnx2x_int_disable(bp);
-
- /* make sure all ISRs are done */
- if (msix) {
- for_each_queue(bp, i)
- synchronize_irq(bp->msix_table[i].vector);
-
- /* one more for the Slow Path IRQ */
- synchronize_irq(bp->msix_table[i].vector);
- } else
- synchronize_irq(bp->pdev->irq);
-
- /* make sure sp_task is not running */
- cancel_work_sync(&bp->sp_task);
-
-}
-
-/* fast path code */
-
-/*
- * general service functions
- */
-
-static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 id,
- u8 storm, u16 index, u8 op, u8 update)
-{
- u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_PORT_BASE * bp->port) * 8;
- struct igu_ack_register igu_ack;
-
- igu_ack.status_block_index = index;
- igu_ack.sb_id_and_flags =
- ((id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
- (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
- (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
- (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
-
-/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
- (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr); */
- REG_WR(bp, BAR_IGU_INTMEM + igu_addr, (*(u32 *)&igu_ack));
-}
-
-static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
-{
- struct host_status_block *fpsb = fp->status_blk;
- u16 rc = 0;
-
- barrier(); /* status block is written to by the chip */
- if (fp->fp_c_idx != fpsb->c_status_block.status_block_index) {
- fp->fp_c_idx = fpsb->c_status_block.status_block_index;
- rc |= 1;
- }
- if (fp->fp_u_idx != fpsb->u_status_block.status_block_index) {
- fp->fp_u_idx = fpsb->u_status_block.status_block_index;
- rc |= 2;
- }
- return rc;
-}
-
-static inline int bnx2x_has_work(struct bnx2x_fastpath *fp)
-{
- u16 rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
-
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
-
- if ((rx_cons_sb != fp->rx_comp_cons) ||
- (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons))
- return 1;
-
- return 0;
-}
-
-static u16 bnx2x_ack_int(struct bnx2x *bp)
-{
- u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_PORT_BASE * bp->port) * 8;
- u32 result = REG_RD(bp, BAR_IGU_INTMEM + igu_addr);
-
-/* DP(NETIF_MSG_INTR, "read 0x%08x from IGU addr 0x%x\n",
- result, BAR_IGU_INTMEM + igu_addr); */
-
-#ifdef IGU_DEBUG
-#warning IGU_DEBUG active
- if (result == 0) {
- BNX2X_ERR("read %x from IGU\n", result);
- REG_WR(bp, TM_REG_TIMER_SOFT_RST, 0);
- }
-#endif
- return result;
-}
-
-
-/*
- * fast path service functions
- */
-
-/* free skb in the packet ring at pos idx
- * return idx of last bd freed
- */
-static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
- u16 idx)
-{
- struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx];
- struct eth_tx_bd *tx_bd;
- struct sk_buff *skb = tx_buf->skb;
- u16 bd_idx = tx_buf->first_bd;
- int nbd;
-
- DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n",
- idx, tx_buf, skb);
-
- /* unmap first bd */
- DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx);
- tx_bd = &fp->tx_desc_ring[bd_idx];
- pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_bd),
- BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
-
- nbd = le16_to_cpu(tx_bd->nbd) - 1;
-#ifdef BNX2X_STOP_ON_ERROR
- if (nbd > (MAX_SKB_FRAGS + 2)) {
- BNX2X_ERR("bad nbd!\n");
- bnx2x_panic();
- }
-#endif
-
- /* Skip a parse bd and the TSO split header bd
- since they have no mapping */
- if (nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
-
- if (tx_bd->bd_flags.as_bitfield & (ETH_TX_BD_FLAGS_IP_CSUM |
- ETH_TX_BD_FLAGS_TCP_CSUM |
- ETH_TX_BD_FLAGS_SW_LSO)) {
- if (--nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
- tx_bd = &fp->tx_desc_ring[bd_idx];
- /* is this a TSO split header bd? */
- if (tx_bd->bd_flags.as_bitfield & ETH_TX_BD_FLAGS_SW_LSO) {
- if (--nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
- }
- }
-
- /* now free frags */
- while (nbd > 0) {
-
- DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx);
- tx_bd = &fp->tx_desc_ring[bd_idx];
- pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_bd),
- BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
- if (--nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
- }
-
- /* release skb */
- BUG_TRAP(skb);
- dev_kfree_skb(skb);
- tx_buf->first_bd = 0;
- tx_buf->skb = NULL;
-
- return bd_idx;
-}
-
-static inline u32 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
-{
- u16 used;
- u32 prod;
- u32 cons;
-
- /* Tell compiler that prod and cons can change */
- barrier();
- prod = fp->tx_bd_prod;
- cons = fp->tx_bd_cons;
-
- used = (NUM_TX_BD - NUM_TX_RINGS + prod - cons +
- (cons / TX_DESC_CNT) - (prod / TX_DESC_CNT));
-
- if (prod >= cons) {
- /* used = prod - cons - prod/size + cons/size */
- used -= NUM_TX_BD - NUM_TX_RINGS;
- }
-
- BUG_TRAP(used <= fp->bp->tx_ring_size);
- BUG_TRAP((fp->bp->tx_ring_size - used) <= MAX_TX_AVAIL);
-
- return (fp->bp->tx_ring_size - used);
-}
-
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
-{
- struct bnx2x *bp = fp->bp;
- u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
- int done = 0;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return;
-#endif
-
- hw_cons = le16_to_cpu(*fp->tx_cons_sb);
- sw_cons = fp->tx_pkt_cons;
-
- while (sw_cons != hw_cons) {
- u16 pkt_cons;
-
- pkt_cons = TX_BD(sw_cons);
-
- /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */
-
- DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %d\n",
- hw_cons, sw_cons, pkt_cons);
-
-/* if (NEXT_TX_IDX(sw_cons) != hw_cons) {
- rmb();
- prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb);
- }
-*/
- bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
- sw_cons++;
- done++;
-
- if (done == work)
- break;
- }
-
- fp->tx_pkt_cons = sw_cons;
- fp->tx_bd_cons = bd_cons;
-
- /* Need to make the tx_cons update visible to start_xmit()
- * before checking for netif_queue_stopped(). Without the
- * memory barrier, there is a small possibility that start_xmit()
- * will miss it and cause the queue to be stopped forever.
- */
- smp_mb();
-
- /* TBD need a thresh? */
- if (unlikely(netif_queue_stopped(bp->dev))) {
-
- netif_tx_lock(bp->dev);
-
- if (netif_queue_stopped(bp->dev) &&
- (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
- netif_wake_queue(bp->dev);
-
- netif_tx_unlock(bp->dev);
-
- }
-}
-
-static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
- union eth_rx_cqe *rr_cqe)
-{
- struct bnx2x *bp = fp->bp;
- int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data);
- int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data);
-
- DP(NETIF_MSG_RX_STATUS,
- "fp %d cid %d got ramrod #%d state is %x type is %d\n",
- fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.type);
-
- bp->spq_left++;
-
- if (fp->index) {
- switch (command | fp->state) {
- case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
- BNX2X_FP_STATE_OPENING):
- DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n",
- cid);
- fp->state = BNX2X_FP_STATE_OPEN;
- break;
-
- case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING):
- DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n",
- cid);
- fp->state = BNX2X_FP_STATE_HALTED;
- break;
-
- default:
- BNX2X_ERR("unexpected MC reply(%d) state is %x\n",
- command, fp->state);
- }
- mb(); /* force bnx2x_wait_ramrod to see the change */
- return;
- }
-
- switch (command | bp->state) {
- case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
- DP(NETIF_MSG_IFUP, "got setup ramrod\n");
- bp->state = BNX2X_STATE_OPEN;
- break;
-
- case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got halt ramrod\n");
- bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE;
- fp->state = BNX2X_FP_STATE_HALTED;
- break;
-
- case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n",
- cid);
- bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
- break;
-
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
- DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
- break;
-
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFUP, "got (un)set mac ramrod\n");
- break;
-
- default:
- BNX2X_ERR("unexpected ramrod (%d) state is %x\n",
- command, bp->state);
- }
-
- mb(); /* force bnx2x_wait_ramrod to see the change */
-}
-
-static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, u16 index)
-{
- struct sk_buff *skb;
- struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index];
- struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
- dma_addr_t mapping;
-
- skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
- if (unlikely(skb == NULL))
- return -ENOMEM;
-
- mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
- PCI_DMA_FROMDEVICE);
- if (unlikely(dma_mapping_error(mapping))) {
-
- dev_kfree_skb(skb);
- return -ENOMEM;
- }
-
- rx_buf->skb = skb;
- pci_unmap_addr_set(rx_buf, mapping, mapping);
-
- rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
-
- return 0;
-}
-
-/* note that we are not allocating a new skb,
- * we are just moving one from cons to prod
- * we are not creating a new mapping,
- * so there is no need to check for dma_mapping_error().
- */
-static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
- struct sk_buff *skb, u16 cons, u16 prod)
-{
- struct bnx2x *bp = fp->bp;
- struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
- struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
- struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons];
- struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
-
- pci_dma_sync_single_for_device(bp->pdev,
- pci_unmap_addr(cons_rx_buf, mapping),
- bp->rx_offset + RX_COPY_THRESH,
- PCI_DMA_FROMDEVICE);
-
- prod_rx_buf->skb = cons_rx_buf->skb;
- pci_unmap_addr_set(prod_rx_buf, mapping,
- pci_unmap_addr(cons_rx_buf, mapping));
- *prod_bd = *cons_bd;
-}
-
-static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
-{
- struct bnx2x *bp = fp->bp;
- u16 bd_cons, bd_prod, comp_ring_cons;
- u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
- int rx_pkt = 0;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return 0;
-#endif
-
- hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb);
- if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- hw_comp_cons++;
-
- bd_cons = fp->rx_bd_cons;
- bd_prod = fp->rx_bd_prod;
- sw_comp_cons = fp->rx_comp_cons;
- sw_comp_prod = fp->rx_comp_prod;
-
- /* Memory barrier necessary as speculative reads of the rx
- * buffer can be ahead of the index in the status block
- */
- rmb();
-
- DP(NETIF_MSG_RX_STATUS,
- "queue[%d]: hw_comp_cons %u sw_comp_cons %u\n",
- fp->index, hw_comp_cons, sw_comp_cons);
-
- while (sw_comp_cons != hw_comp_cons) {
- unsigned int len, pad;
- struct sw_rx_bd *rx_buf;
- struct sk_buff *skb;
- union eth_rx_cqe *cqe;
-
- comp_ring_cons = RCQ_BD(sw_comp_cons);
- bd_prod = RX_BD(bd_prod);
- bd_cons = RX_BD(bd_cons);
-
- cqe = &fp->rx_comp_ring[comp_ring_cons];
-
- DP(NETIF_MSG_RX_STATUS, "hw_comp_cons %u sw_comp_cons %u"
- " comp_ring (%u) bd_ring (%u,%u)\n",
- hw_comp_cons, sw_comp_cons,
- comp_ring_cons, bd_prod, bd_cons);
- DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x"
- " queue %x vlan %x len %x\n",
- cqe->fast_path_cqe.type,
- cqe->fast_path_cqe.error_type_flags,
- cqe->fast_path_cqe.status_flags,
- cqe->fast_path_cqe.rss_hash_result,
- cqe->fast_path_cqe.vlan_tag, cqe->fast_path_cqe.pkt_len);
-
- /* is this a slowpath msg? */
- if (unlikely(cqe->fast_path_cqe.type)) {
- bnx2x_sp_event(fp, cqe);
- goto next_cqe;
-
- /* this is an rx packet */
- } else {
- rx_buf = &fp->rx_buf_ring[bd_cons];
- skb = rx_buf->skb;
-
- len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
- pad = cqe->fast_path_cqe.placement_offset;
-
- pci_dma_sync_single_for_device(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- pad + RX_COPY_THRESH,
- PCI_DMA_FROMDEVICE);
- prefetch(skb);
- prefetch(((char *)(skb)) + 128);
-
- /* is this an error packet? */
- if (unlikely(cqe->fast_path_cqe.error_type_flags &
- ETH_RX_ERROR_FALGS)) {
- /* do we sometimes forward error packets anyway? */
- DP(NETIF_MSG_RX_ERR,
- "ERROR flags(%u) Rx packet(%u)\n",
- cqe->fast_path_cqe.error_type_flags,
- sw_comp_cons);
- /* TBD make sure MC counts this as a drop */
- goto reuse_rx;
- }
-
- /* Since we don't have a jumbo ring
- * copy small packets if mtu > 1500
- */
- if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
- (len <= RX_COPY_THRESH)) {
- struct sk_buff *new_skb;
-
- new_skb = netdev_alloc_skb(bp->dev,
- len + pad);
- if (new_skb == NULL) {
- DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped "
- "because of alloc failure\n");
- /* TBD count this as a drop? */
- goto reuse_rx;
- }
-
- /* aligned copy */
- skb_copy_from_linear_data_offset(skb, pad,
- new_skb->data + pad, len);
- skb_reserve(new_skb, pad);
- skb_put(new_skb, len);
-
- bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
-
- skb = new_skb;
-
- } else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) {
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_use_size,
- PCI_DMA_FROMDEVICE);
- skb_reserve(skb, pad);
- skb_put(skb, len);
-
- } else {
- DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped because "
- "of alloc failure\n");
-reuse_rx:
- bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
- goto next_rx;
- }
-
- skb->protocol = eth_type_trans(skb, bp->dev);
-
- skb->ip_summed = CHECKSUM_NONE;
- if (bp->rx_csum && BNX2X_RX_SUM_OK(cqe))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-
- /* TBD do we pass bad csum packets in promisc */
- }
-
-#ifdef BCM_VLAN
- if ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags)
- & PARSING_FLAGS_NUMBER_OF_NESTED_VLANS)
- && (bp->vlgrp != NULL))
- vlan_hwaccel_receive_skb(skb, bp->vlgrp,
- le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
- else
-#endif
- netif_receive_skb(skb);
-
- bp->dev->last_rx = jiffies;
-
-next_rx:
- rx_buf->skb = NULL;
-
- bd_cons = NEXT_RX_IDX(bd_cons);
- bd_prod = NEXT_RX_IDX(bd_prod);
-next_cqe:
- sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
- sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
- rx_pkt++;
-
- if ((rx_pkt == budget))
- break;
- } /* while */
-
- fp->rx_bd_cons = bd_cons;
- fp->rx_bd_prod = bd_prod;
- fp->rx_comp_cons = sw_comp_cons;
- fp->rx_comp_prod = sw_comp_prod;
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_RCQ_PROD_OFFSET(bp->port, fp->index), sw_comp_prod);
-
- mmiowb(); /* keep prod updates ordered */
-
- fp->rx_pkt += rx_pkt;
- fp->rx_calls++;
-
- return rx_pkt;
-}
-
-static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
-{
- struct bnx2x_fastpath *fp = fp_cookie;
- struct bnx2x *bp = fp->bp;
- struct net_device *dev = bp->dev;
- int index = fp->index;
-
- DP(NETIF_MSG_INTR, "got an msix interrupt on [%d]\n", index);
- bnx2x_ack_sb(bp, index, USTORM_ID, 0, IGU_INT_DISABLE, 0);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return IRQ_HANDLED;
-#endif
-
- prefetch(fp->rx_cons_sb);
- prefetch(fp->tx_cons_sb);
- prefetch(&fp->status_blk->c_status_block.status_block_index);
- prefetch(&fp->status_blk->u_status_block.status_block_index);
-
- netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi));
- return IRQ_HANDLED;
-}
-
-static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
-{
- struct net_device *dev = dev_instance;
- struct bnx2x *bp = netdev_priv(dev);
- u16 status = bnx2x_ack_int(bp);
-
- if (unlikely(status == 0)) {
- DP(NETIF_MSG_INTR, "not our interrupt!\n");
- return IRQ_NONE;
- }
-
- DP(NETIF_MSG_INTR, "got an interrupt status is %u\n", status);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return IRQ_HANDLED;
-#endif
-
- /* Return here if interrupt is shared and is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
- return IRQ_HANDLED;
- }
-
- if (status & 0x2) {
- struct bnx2x_fastpath *fp = &bp->fp[0];
-
- prefetch(fp->rx_cons_sb);
- prefetch(fp->tx_cons_sb);
- prefetch(&fp->status_blk->c_status_block.status_block_index);
- prefetch(&fp->status_blk->u_status_block.status_block_index);
-
- netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi));
-
- status &= ~0x2;
- if (!status)
- return IRQ_HANDLED;
- }
-
- if (unlikely(status & 0x1)) {
-
- schedule_work(&bp->sp_task);
-
- status &= ~0x1;
- if (!status)
- return IRQ_HANDLED;
- }
-
- DP(NETIF_MSG_INTR, "got an unknown interrupt! (status is %u)\n",
- status);
-
- return IRQ_HANDLED;
-}
-
-/* end of fast path */
-
-/* PHY/MAC */
-
-/*
- * General service functions
- */
-
-static void bnx2x_leds_set(struct bnx2x *bp, unsigned int speed)
-{
- int port = bp->port;
-
- NIG_WR(NIG_REG_LED_MODE_P0 + port*4,
- ((bp->hw_config & SHARED_HW_CFG_LED_MODE_MASK) >>
- SHARED_HW_CFG_LED_MODE_SHIFT));
- NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
-
- /* Set blinking rate to ~15.9Hz */
- NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
- LED_BLINK_RATE_VAL);
- NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + port*4, 1);
-
- /* On Ax chip versions for speeds less than 10G
- LED scheme is different */
- if ((CHIP_REV(bp) == CHIP_REV_Ax) && (speed < SPEED_10000)) {
- NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 1);
- NIG_WR(NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, 0);
- NIG_WR(NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + port*4, 1);
- }
-}
-
-static void bnx2x_leds_unset(struct bnx2x *bp)
-{
- int port = bp->port;
-
- NIG_WR(NIG_REG_LED_10G_P0 + port*4, 0);
- NIG_WR(NIG_REG_LED_MODE_P0 + port*4, SHARED_HW_CFG_LED_MAC1);
-}
-
-static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
-{
- u32 val = REG_RD(bp, reg);
-
- val |= bits;
- REG_WR(bp, reg, val);
- return val;
-}
-
-static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
-{
- u32 val = REG_RD(bp, reg);
-
- val &= ~bits;
- REG_WR(bp, reg, val);
- return val;
-}
-
-static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
-{
- u32 cnt;
- u32 lock_status;
- u32 resource_bit = (1 << resource);
- u8 func = bp->port;
-
- /* Validating that the resource is within range */
- if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
- DP(NETIF_MSG_HW,
- "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
- resource, HW_LOCK_MAX_RESOURCE_VALUE);
- return -EINVAL;
- }
-
- /* Validating that the resource is not already taken */
- lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
- if (lock_status & resource_bit) {
- DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
- lock_status, resource_bit);
- return -EEXIST;
- }
-
- /* Try for 1 second every 5ms */
- for (cnt = 0; cnt < 200; cnt++) {
- /* Try to acquire the lock */
- REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8 + 4,
- resource_bit);
- lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
- if (lock_status & resource_bit)
- return 0;
-
- msleep(5);
- }
- DP(NETIF_MSG_HW, "Timeout\n");
- return -EAGAIN;
-}
-
-static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
-{
- u32 lock_status;
- u32 resource_bit = (1 << resource);
- u8 func = bp->port;
-
- /* Validating that the resource is within range */
- if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
- DP(NETIF_MSG_HW,
- "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
- resource, HW_LOCK_MAX_RESOURCE_VALUE);
- return -EINVAL;
- }
-
- /* Validating that the resource is currently taken */
- lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + func*8);
- if (!(lock_status & resource_bit)) {
- DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
- lock_status, resource_bit);
- return -EFAULT;
- }
-
- REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + func*8, resource_bit);
- return 0;
-}
-
-static int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
-{
- /* The GPIO should be swapped if swap register is set and active */
- int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
- REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ bp->port;
- int gpio_shift = gpio_num +
- (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
- u32 gpio_mask = (1 << gpio_shift);
- u32 gpio_reg;
-
- if (gpio_num > MISC_REGISTERS_GPIO_3) {
- BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
- return -EINVAL;
- }
-
- bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
- /* read GPIO and mask except the float bits */
- gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
-
- switch (mode) {
- case MISC_REGISTERS_GPIO_OUTPUT_LOW:
- DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
- gpio_num, gpio_shift);
- /* clear FLOAT and set CLR */
- gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
- gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
- break;
-
- case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
- DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
- gpio_num, gpio_shift);
- /* clear FLOAT and set SET */
- gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
- gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
- break;
-
- case MISC_REGISTERS_GPIO_INPUT_HI_Z :
- DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
- gpio_num, gpio_shift);
- /* set FLOAT */
- gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
- break;
-
- default:
- break;
- }
-
- REG_WR(bp, MISC_REG_GPIO, gpio_reg);
- bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO);
-
- return 0;
-}
-
-static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
-{
- u32 spio_mask = (1 << spio_num);
- u32 spio_reg;
-
- if ((spio_num < MISC_REGISTERS_SPIO_4) ||
- (spio_num > MISC_REGISTERS_SPIO_7)) {
- BNX2X_ERR("Invalid SPIO %d\n", spio_num);
- return -EINVAL;
- }
-
- bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
- /* read SPIO and mask except the float bits */
- spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
-
- switch (mode) {
- case MISC_REGISTERS_SPIO_OUTPUT_LOW :
- DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
- /* clear FLOAT and set CLR */
- spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
- spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
- break;
-
- case MISC_REGISTERS_SPIO_OUTPUT_HIGH :
- DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
- /* clear FLOAT and set SET */
- spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
- spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
- break;
-
- case MISC_REGISTERS_SPIO_INPUT_HI_Z:
- DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
- /* set FLOAT */
- spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
- break;
-
- default:
- break;
- }
-
- REG_WR(bp, MISC_REG_SPIO, spio_reg);
- bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO);
-
- return 0;
-}
-
-static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
-{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 tmp;
- int i, rc;
-
-/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n",
- bp->phy_addr, reg, val); */
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
-
- tmp = ((bp->phy_addr << 21) | (reg << 16) |
- (val & EMAC_MDIO_COMM_DATA) |
- EMAC_MDIO_COMM_COMMAND_WRITE_22 |
- EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
-
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("write phy register failed\n");
-
- rc = -EBUSY;
- } else {
- rc = 0;
- }
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- tmp |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
- }
-
- return rc;
-}
-
-static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
-{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val;
- int i, rc;
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
- }
-
- val = ((bp->phy_addr << 21) | (reg << 16) |
- EMAC_MDIO_COMM_COMMAND_READ_22 |
- EMAC_MDIO_COMM_START_BUSY);
- EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- val &= EMAC_MDIO_COMM_DATA;
- break;
- }
- }
-
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("read phy register failed\n");
-
- *ret_val = 0x0;
- rc = -EBUSY;
- } else {
- *ret_val = val;
- rc = 0;
- }
-
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
-
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
- val |= EMAC_MDIO_MODE_AUTO_POLL;
- EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
- }
-
-/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x ret_val 0x%08x\n",
- bp->phy_addr, reg, *ret_val); */
-
- return rc;
-}
-
-static int bnx2x_mdio45_ctrl_write(struct bnx2x *bp, u32 mdio_ctrl,
- u32 phy_addr, u32 reg, u32 addr, u32 val)
-{
- u32 tmp;
- int i, rc = 0;
-
- /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
- tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
-
- /* address */
- tmp = ((phy_addr << 21) | (reg << 16) | addr |
- EMAC_MDIO_COMM_COMMAND_ADDRESS |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("write phy register failed\n");
-
- rc = -EBUSY;
-
- } else {
- /* data */
- tmp = ((phy_addr << 21) | (reg << 16) | val |
- EMAC_MDIO_COMM_COMMAND_WRITE_45 |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
-
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("write phy register failed\n");
-
- rc = -EBUSY;
- }
- }
-
- /* unset clause 45 mode, set the MDIO clock to a faster value
- * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
- */
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- tmp &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
- tmp |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
- tmp |= EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
-
- return rc;
-}
-
-static int bnx2x_mdio45_write(struct bnx2x *bp, u32 phy_addr, u32 reg,
- u32 addr, u32 val)
-{
- u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- return bnx2x_mdio45_ctrl_write(bp, emac_base, phy_addr,
- reg, addr, val);
-}
-
-static int bnx2x_mdio45_ctrl_read(struct bnx2x *bp, u32 mdio_ctrl,
- u32 phy_addr, u32 reg, u32 addr,
- u32 *ret_val)
-{
- u32 val;
- int i, rc = 0;
-
- /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
- val |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
-
- /* address */
- val = ((phy_addr << 21) | (reg << 16) | addr |
- EMAC_MDIO_COMM_COMMAND_ADDRESS |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("read phy register failed\n");
-
- *ret_val = 0;
- rc = -EBUSY;
-
- } else {
- /* data */
- val = ((phy_addr << 21) | (reg << 16) |
- EMAC_MDIO_COMM_COMMAND_READ_45 |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- val &= EMAC_MDIO_COMM_DATA;
- break;
- }
- }
-
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- BNX2X_ERR("read phy register failed\n");
-
- val = 0;
- rc = -EBUSY;
- }
-
- *ret_val = val;
- }
-
- /* unset clause 45 mode, set the MDIO clock to a faster value
- * (0x13 => 6.25Mhz) and restore the AUTO poll if needed
- */
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val &= ~(EMAC_MDIO_MODE_CLAUSE_45 | EMAC_MDIO_MODE_CLOCK_CNT);
- val |= (0x13 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
- if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG)
- val |= EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
-
- return rc;
-}
-
-static int bnx2x_mdio45_read(struct bnx2x *bp, u32 phy_addr, u32 reg,
- u32 addr, u32 *ret_val)
-{
- u32 emac_base = bp->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- return bnx2x_mdio45_ctrl_read(bp, emac_base, phy_addr,
- reg, addr, ret_val);
-}
-
-static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 phy_addr, u32 reg,
- u32 addr, u32 val)
-{
- int i;
- u32 rd_val;
-
- might_sleep();
- for (i = 0; i < 10; i++) {
- bnx2x_mdio45_write(bp, phy_addr, reg, addr, val);
- msleep(5);
- bnx2x_mdio45_read(bp, phy_addr, reg, addr, &rd_val);
- /* if the read value is not the same as the value we wrote,
- we should write it again */
- if (rd_val == val)
- return 0;
- }
- BNX2X_ERR("MDIO write in CL45 failed\n");
- return -EBUSY;
-}
-
-/*
- * link management
- */
-
-static void bnx2x_pause_resolve(struct bnx2x *bp, u32 pause_result)
-{
- switch (pause_result) { /* ASYM P ASYM P */
- case 0xb: /* 1 0 1 1 */
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case 0xe: /* 1 1 1 0 */
- bp->flow_ctrl = FLOW_CTRL_RX;
- break;
-
- case 0x5: /* 0 1 0 1 */
- case 0x7: /* 0 1 1 1 */
- case 0xd: /* 1 1 0 1 */
- case 0xf: /* 1 1 1 1 */
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- break;
-
- default:
- break;
- }
-}
-
-static u8 bnx2x_ext_phy_resove_fc(struct bnx2x *bp)
-{
- u32 ext_phy_addr;
- u32 ld_pause; /* local */
- u32 lp_pause; /* link partner */
- u32 an_complete; /* AN complete */
- u32 pause_result;
- u8 ret = 0;
-
- ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- /* read twice */
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_STATUS, &an_complete);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_STATUS, &an_complete);
-
- if (an_complete & EXT_PHY_KR_AUTO_NEG_COMPLETE) {
- ret = 1;
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_AUTO_NEG_ADVERT, &ld_pause);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_LP_AUTO_NEG, &lp_pause);
- pause_result = (ld_pause &
- EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 8;
- pause_result |= (lp_pause &
- EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK) >> 10;
- DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
- pause_result);
- bnx2x_pause_resolve(bp, pause_result);
- }
- return ret;
-}
-
-static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
-{
- u32 ld_pause; /* local driver */
- u32 lp_pause; /* link partner */
- u32 pause_result;
-
- bp->flow_ctrl = 0;
-
- /* resolve from gp_status in case of AN complete and not sgmii */
- if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
- (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
- (!(bp->phy_flags & PHY_SGMII_FLAG)) &&
- (XGXS_EXT_PHY_TYPE(bp) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
- &ld_pause);
- bnx2x_mdio22_read(bp,
- MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
- &lp_pause);
- pause_result = (ld_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
- pause_result |= (lp_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
- DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
- bnx2x_pause_resolve(bp, pause_result);
- } else if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) ||
- !(bnx2x_ext_phy_resove_fc(bp))) {
- /* forced speed */
- if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- else
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case FLOW_CTRL_TX:
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case FLOW_CTRL_RX:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_RX;
- break;
-
- case FLOW_CTRL_BOTH:
- if (bp->dev->mtu <= 4500)
- bp->flow_ctrl = FLOW_CTRL_BOTH;
- else
- bp->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case FLOW_CTRL_NONE:
- default:
- break;
- }
- } else { /* forced mode */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
- " req_autoneg 0x%x\n",
- bp->req_flow_ctrl, bp->req_autoneg);
- break;
-
- case FLOW_CTRL_TX:
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- bp->flow_ctrl = bp->req_flow_ctrl;
- break;
-
- case FLOW_CTRL_NONE:
- default:
- break;
- }
- }
- }
- DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl);
-}
-
-static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
-{
- bp->link_status = 0;
-
- if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
- DP(NETIF_MSG_LINK, "phy link up\n");
-
- bp->phy_link_up = 1;
- bp->link_status |= LINK_STATUS_LINK_UP;
-
- if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
- bp->duplex = DUPLEX_FULL;
- else
- bp->duplex = DUPLEX_HALF;
-
- bnx2x_flow_ctrl_resolve(bp, gp_status);
-
- switch (gp_status & GP_STATUS_SPEED_MASK) {
- case GP_STATUS_10M:
- bp->line_speed = SPEED_10;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_10TFD;
- else
- bp->link_status |= LINK_10THD;
- break;
-
- case GP_STATUS_100M:
- bp->line_speed = SPEED_100;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_100TXFD;
- else
- bp->link_status |= LINK_100TXHD;
- break;
-
- case GP_STATUS_1G:
- case GP_STATUS_1G_KX:
- bp->line_speed = SPEED_1000;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_1000TFD;
- else
- bp->link_status |= LINK_1000THD;
- break;
-
- case GP_STATUS_2_5G:
- bp->line_speed = SPEED_2500;
- if (bp->duplex == DUPLEX_FULL)
- bp->link_status |= LINK_2500TFD;
- else
- bp->link_status |= LINK_2500THD;
- break;
-
- case GP_STATUS_5G:
- case GP_STATUS_6G:
- BNX2X_ERR("link speed unsupported gp_status 0x%x\n",
- gp_status);
- break;
-
- case GP_STATUS_10G_KX4:
- case GP_STATUS_10G_HIG:
- case GP_STATUS_10G_CX4:
- bp->line_speed = SPEED_10000;
- bp->link_status |= LINK_10GTFD;
- break;
-
- case GP_STATUS_12G_HIG:
- bp->line_speed = SPEED_12000;
- bp->link_status |= LINK_12GTFD;
- break;
-
- case GP_STATUS_12_5G:
- bp->line_speed = SPEED_12500;
- bp->link_status |= LINK_12_5GTFD;
- break;
-
- case GP_STATUS_13G:
- bp->line_speed = SPEED_13000;
- bp->link_status |= LINK_13GTFD;
- break;
-
- case GP_STATUS_15G:
- bp->line_speed = SPEED_15000;
- bp->link_status |= LINK_15GTFD;
- break;
-
- case GP_STATUS_16G:
- bp->line_speed = SPEED_16000;
- bp->link_status |= LINK_16GTFD;
- break;
-
- default:
- BNX2X_ERR("link speed unsupported gp_status 0x%x\n",
- gp_status);
- break;
- }
-
- bp->link_status |= LINK_STATUS_SERDES_LINK;
-
- if (bp->req_autoneg & AUTONEG_SPEED) {
- bp->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
-
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
- bp->link_status |=
- LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
-
- if (bp->autoneg & AUTONEG_PARALLEL)
- bp->link_status |=
- LINK_STATUS_PARALLEL_DETECTION_USED;
- }
-
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- bp->link_status |= LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
-
- if (bp->flow_ctrl & FLOW_CTRL_RX)
- bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
-
- } else { /* link_down */
- DP(NETIF_MSG_LINK, "phy link down\n");
-
- bp->phy_link_up = 0;
-
- bp->line_speed = 0;
- bp->duplex = DUPLEX_FULL;
- bp->flow_ctrl = 0;
- }
-
- DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %d\n"
- DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x"
- " link_status 0x%x\n",
- gp_status, bp->phy_link_up, bp->line_speed, bp->duplex,
- bp->flow_ctrl, bp->link_status);
-}
-
-static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
-{
- int port = bp->port;
-
- /* first reset all status
- * we assume only one line will be change at a time */
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
- if (bp->phy_link_up) {
- if (is_10g) {
- /* Disable the 10G link interrupt
- * by writing 1 to the status register
- */
- DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_XGXS0_LINK10G);
-
- } else if (bp->phy_flags & PHY_XGXS_FLAG) {
- /* Disable the link interrupt
- * by writing 1 to the relevant lane
- * in the status register
- */
- DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- ((1 << bp->ser_lane) <<
- NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes phy link up\n");
- /* Disable the link interrupt
- * by writing 1 to the status register
- */
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_SERDES0_LINK_STATUS);
- }
-
- } else { /* link_down */
- }
-}
-
-static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp)
-{
- u32 ext_phy_type;
- u32 ext_phy_addr;
- u32 val1 = 0, val2;
- u32 rx_sd, pcs_status;
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- val1 = 1;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
- DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
- val1 = (rx_sd & 0x1);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PCS_DEVAD,
- EXT_PHY_OPT_PCS_STATUS, &pcs_status);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_AUTO_NEG_DEVAD,
- EXT_PHY_OPT_AN_LINK_STATUS, &val2);
-
- DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
- " pcs_status 0x%x 1Gbps link_status 0x%x 0x%x\n",
- rx_sd, pcs_status, val2, (val2 & (1<<1)));
- /* link is up if both bit 0 of pmd_rx_sd and
- * bit 0 of pcs_status are set, or if the autoneg bit
- 1 is set
- */
- val1 = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
-
- /* clear the interrupt LASI status register */
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PCS_DEVAD,
- EXT_PHY_KR_LASI_STATUS, &val2);
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PCS_DEVAD,
- EXT_PHY_KR_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "KR LASI status 0x%x->0x%x\n",
- val2, val1);
- /* Check the LASI */
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- 0x9003, &val2);
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- 0x9003, &val1);
- DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
- val2, val1);
- /* Check the link status */
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PCS_DEVAD,
- EXT_PHY_KR_PCS_STATUS, &val2);
- DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
- /* Check the link status on 1.1.2 */
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_KR_STATUS, &val2);
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_KR_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "KR PMA status 0x%x->0x%x\n", val2, val1);
- val1 = ((val1 & 4) == 4);
- /* If 1G was requested assume the link is up */
- if (!(bp->req_autoneg & AUTONEG_SPEED) &&
- (bp->req_line_speed == SPEED_1000))
- val1 = 1;
- bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val2);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T LASI status 0x%x->0x%x\n", val2, val1);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_KR_STATUS, &val2);
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_KR_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T PMA status 0x%x->0x%x\n", val2, val1);
- val1 = ((val1 & 4) == 4);
- /* if link is up
- * print the AN outcome of the SFX7101 PHY
- */
- if (val1) {
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- 0x21, &val2);
- DP(NETIF_MSG_LINK,
- "SFX7101 AN status 0x%x->%s\n", val2,
- (val2 & (1<<14)) ? "Master" : "Slave");
- }
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- val1 = 0;
- break;
- }
-
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- val1 = 1;
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- val1 = 1;
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- val1 = 0;
- break;
- }
- }
-
- return val1;
-}
-
-static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
-{
- int port = bp->port;
- u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
- NIG_REG_INGRESS_BMAC0_MEM;
- u32 wb_write[2];
- u32 val;
-
- DP(NETIF_MSG_LINK, "enabling BigMAC\n");
- /* reset and unreset the BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- msleep(5);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* enable access for bmac registers */
- NIG_WR(NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
-
- /* XGXS control */
- wb_write[0] = 0x3c;
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
- wb_write, 2);
-
- /* tx MAC SA */
- wb_write[0] = ((bp->dev->dev_addr[2] << 24) |
- (bp->dev->dev_addr[3] << 16) |
- (bp->dev->dev_addr[4] << 8) |
- bp->dev->dev_addr[5]);
- wb_write[1] = ((bp->dev->dev_addr[0] << 8) |
- bp->dev->dev_addr[1]);
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
- wb_write, 2);
-
- /* tx control */
- val = 0xc0;
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- val |= 0x800000;
- wb_write[0] = val;
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_write, 2);
-
- /* set tx mtu */
- wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; /* -CRC */
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_write, 2);
-
- /* mac control */
- val = 0x3;
- if (is_lb) {
- val |= 0x4;
- DP(NETIF_MSG_LINK, "enable bmac loopback\n");
- }
- wb_write[0] = val;
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_write, 2);
-
- /* rx control set to don't strip crc */
- val = 0x14;
- if (bp->flow_ctrl & FLOW_CTRL_RX)
- val |= 0x20;
- wb_write[0] = val;
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_write, 2);
-
- /* set rx mtu */
- wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_write, 2);
-
- /* set cnt max size */
- wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; /* -VLAN */
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
- wb_write, 2);
-
- /* configure safc */
- wb_write[0] = 0x1000200;
- wb_write[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
- wb_write, 2);
-
- /* fix for emulation */
- if (CHIP_REV(bp) == CHIP_REV_EMUL) {
- wb_write[0] = 0xf000;
- wb_write[1] = 0;
- REG_WR_DMAE(bp,
- bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
- wb_write, 2);
- }
-
- /* reset old bmac stats */
- memset(&bp->old_bmac, 0, sizeof(struct bmac_stats));
-
- NIG_WR(NIG_REG_XCM0_OUT_EN + port*4, 0x0);
-
- /* select XGXS */
- NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
- NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
-
- /* disable the NIG in/out to the emac */
- NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0x0);
- NIG_WR(NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
- NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
-
- /* enable the NIG in/out to the bmac */
- NIG_WR(NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
-
- NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0x1);
- val = 0;
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- val = 1;
- NIG_WR(NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
- NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
-
- bp->phy_flags |= PHY_BMAC_FLAG;
-
- bp->stats_state = STATS_STATE_ENABLE;
-}
-
-static void bnx2x_bmac_rx_disable(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
- NIG_REG_INGRESS_BMAC0_MEM;
- u32 wb_write[2];
-
- /* Only if the bmac is out of reset */
- if (REG_RD(bp, MISC_REG_RESET_REG_2) &
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)) {
- /* Clear Rx Enable bit in BMAC_CONTROL register */
-#ifdef BNX2X_DMAE_RD
- bnx2x_read_dmae(bp, bmac_addr +
- BIGMAC_REGISTER_BMAC_CONTROL, 2);
- wb_write[0] = *bnx2x_sp(bp, wb_data[0]);
- wb_write[1] = *bnx2x_sp(bp, wb_data[1]);
-#else
- wb_write[0] = REG_RD(bp,
- bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL);
- wb_write[1] = REG_RD(bp,
- bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL + 4);
-#endif
- wb_write[0] &= ~BMAC_CONTROL_RX_ENABLE;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_write, 2);
- msleep(1);
- }
-}
-
-static void bnx2x_emac_enable(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val;
- int timeout;
-
- DP(NETIF_MSG_LINK, "enabling EMAC\n");
- /* reset and unreset the emac core */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
- msleep(5);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
-
- /* enable emac and not bmac */
- NIG_WR(NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
-
- /* for paladium */
- if (CHIP_REV(bp) == CHIP_REV_EMUL) {
- /* Use lane 1 (of lanes 0-3) */
- NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
- NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
- }
- /* for fpga */
- else if (CHIP_REV(bp) == CHIP_REV_FPGA) {
- /* Use lane 1 (of lanes 0-3) */
- NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
- NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
- }
- /* ASIC */
- else {
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- /* select the master lanes (out of 0-3) */
- NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4,
- bp->ser_lane);
- /* select XGXS */
- NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes\n");
- /* select SerDes */
- NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
- }
- }
-
- /* enable emac */
- NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 1);
-
- /* init emac - use read-modify-write */
- /* self clear reset */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
-
- timeout = 200;
- while (val & EMAC_MODE_RESET) {
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
- if (!timeout) {
- BNX2X_ERR("EMAC timeout!\n");
- break;
- }
- timeout--;
- }
-
- /* reset tx part */
- EMAC_WR(EMAC_REG_EMAC_TX_MODE, EMAC_TX_MODE_RESET);
-
- timeout = 200;
- while (val & EMAC_TX_MODE_RESET) {
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_TX_MODE);
- DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
- if (!timeout) {
- BNX2X_ERR("EMAC timeout!\n");
- break;
- }
- timeout--;
- }
-
- if (CHIP_REV_IS_SLOW(bp)) {
- /* config GMII mode */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
-
- } else { /* ASIC */
- /* pause enable/disable */
- bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
- if (bp->flow_ctrl & FLOW_CTRL_RX)
- bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
-
- bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
- EMAC_TX_MODE_EXT_PAUSE_EN);
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
- EMAC_TX_MODE_EXT_PAUSE_EN);
- }
-
- /* KEEP_VLAN_TAG, promiscuous */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
- val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
- EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
-
- /* identify magic packets */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_MPKT));
-
- /* enable emac for jumbo packets */
- EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
- (EMAC_RX_MTU_SIZE_JUMBO_ENA |
- (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); /* -VLAN */
-
- /* strip CRC */
- NIG_WR(NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
-
- val = ((bp->dev->dev_addr[0] << 8) |
- bp->dev->dev_addr[1]);
- EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
-
- val = ((bp->dev->dev_addr[2] << 24) |
- (bp->dev->dev_addr[3] << 16) |
- (bp->dev->dev_addr[4] << 8) |
- bp->dev->dev_addr[5]);
- EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
-
- /* disable the NIG in/out to the bmac */
- NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0x0);
- NIG_WR(NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
- NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
-
- /* enable the NIG in/out to the emac */
- NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0x1);
- val = 0;
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- val = 1;
- NIG_WR(NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
- NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
-
- if (CHIP_REV(bp) == CHIP_REV_FPGA) {
- /* take the BigMac out of reset */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* enable access for bmac registers */
- NIG_WR(NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
- }
-
- bp->phy_flags |= PHY_EMAC_FLAG;
-
- bp->stats_state = STATS_STATE_ENABLE;
-}
-
-static void bnx2x_emac_program(struct bnx2x *bp)
-{
- u16 mode = 0;
- int port = bp->port;
-
- DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
- bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
- (EMAC_MODE_25G_MODE |
- EMAC_MODE_PORT_MII_10M |
- EMAC_MODE_HALF_DUPLEX));
- switch (bp->line_speed) {
- case SPEED_10:
- mode |= EMAC_MODE_PORT_MII_10M;
- break;
-
- case SPEED_100:
- mode |= EMAC_MODE_PORT_MII;
- break;
-
- case SPEED_1000:
- mode |= EMAC_MODE_PORT_GMII;
- break;
-
- case SPEED_2500:
- mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
- break;
-
- default:
- /* 10G not valid for EMAC */
- BNX2X_ERR("Invalid line_speed 0x%x\n", bp->line_speed);
- break;
- }
-
- if (bp->duplex == DUPLEX_HALF)
- mode |= EMAC_MODE_HALF_DUPLEX;
- bnx2x_bits_en(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
- mode);
-
- bnx2x_leds_set(bp, bp->line_speed);
-}
-
-static void bnx2x_set_sgmii_tx_driver(struct bnx2x *bp)
-{
- u32 lp_up2;
- u32 tx_driver;
-
- /* read precomp */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
- bnx2x_mdio22_read(bp, MDIO_OVER_1G_LP_UP2, &lp_up2);
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_TX0);
- bnx2x_mdio22_read(bp, MDIO_TX0_TX_DRIVER, &tx_driver);
-
- /* bits [10:7] at lp_up2, positioned at [15:12] */
- lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
- MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
- MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
-
- if ((lp_up2 != 0) &&
- (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
- /* replace tx_driver bits [15:12] */
- tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
- tx_driver |= lp_up2;
- bnx2x_mdio22_write(bp, MDIO_TX0_TX_DRIVER, tx_driver);
- }
-}
-
-static void bnx2x_pbf_update(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 init_crd, crd;
- u32 count = 1000;
- u32 pause = 0;
-
- /* disable port */
- REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
-
- /* wait for init credit */
- init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
- crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
- DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
-
- while ((init_crd != crd) && count) {
- msleep(5);
-
- crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
- count--;
- }
- crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
- if (init_crd != crd)
- BNX2X_ERR("BUG! init_crd 0x%x != crd 0x%x\n", init_crd, crd);
-
- if (bp->flow_ctrl & FLOW_CTRL_RX)
- pause = 1;
- REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause);
- if (pause) {
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
- /* update init credit */
- init_crd = 778; /* (800-18-4) */
-
- } else {
- u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)/16;
-
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
- /* update init credit */
- switch (bp->line_speed) {
- case SPEED_10:
- case SPEED_100:
- case SPEED_1000:
- init_crd = thresh + 55 - 22;
- break;
-
- case SPEED_2500:
- init_crd = thresh + 138 - 22;
- break;
-
- case SPEED_10000:
- init_crd = thresh + 553 - 22;
- break;
-
- default:
- BNX2X_ERR("Invalid line_speed 0x%x\n",
- bp->line_speed);
- break;
- }
- }
- REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
- DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
- bp->line_speed, init_crd);
-
- /* probe the credit changes */
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
- msleep(5);
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
-
- /* enable port */
- REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
-}
-
-static void bnx2x_update_mng(struct bnx2x *bp)
-{
- if (!nomcp)
- SHMEM_WR(bp, port_mb[bp->port].link_status,
- bp->link_status);
-}
-
-static void bnx2x_link_report(struct bnx2x *bp)
-{
- if (bp->link_up) {
- netif_carrier_on(bp->dev);
- printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
-
- printk("%d Mbps ", bp->line_speed);
-
- if (bp->duplex == DUPLEX_FULL)
- printk("full duplex");
- else
- printk("half duplex");
-
- if (bp->flow_ctrl) {
- if (bp->flow_ctrl & FLOW_CTRL_RX) {
- printk(", receive ");
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- printk("& transmit ");
- } else {
- printk(", transmit ");
- }
- printk("flow control ON");
- }
- printk("\n");
-
- } else { /* link_down */
- netif_carrier_off(bp->dev);
- printk(KERN_INFO PFX "%s NIC Link is Down\n", bp->dev->name);
- }
-}
-
-static void bnx2x_link_up(struct bnx2x *bp)
-{
- int port = bp->port;
-
- /* PBF - link up */
- bnx2x_pbf_update(bp);
-
- /* disable drain */
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
-
- /* update shared memory */
- bnx2x_update_mng(bp);
-
- /* indicate link up */
- bnx2x_link_report(bp);
-}
-
-static void bnx2x_link_down(struct bnx2x *bp)
-{
- int port = bp->port;
-
- /* notify stats */
- if (bp->stats_state != STATS_STATE_DISABLE) {
- bp->stats_state = STATS_STATE_STOP;
- DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
- }
-
- /* indicate no mac active */
- bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG);
-
- /* update shared memory */
- bnx2x_update_mng(bp);
-
- /* activate nig drain */
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
- /* reset BigMac */
- bnx2x_bmac_rx_disable(bp);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* indicate link down */
- bnx2x_link_report(bp);
-}
-
-static void bnx2x_init_mac_stats(struct bnx2x *bp);
-
-/* This function is called upon link interrupt */
-static void bnx2x_link_update(struct bnx2x *bp)
-{
- int port = bp->port;
- int i;
- u32 gp_status;
- int link_10g;
-
- DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
- " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
- " 10G %x, XGXS_LINK %x\n", port,
- (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask,
- REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
- REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
- );
-
- might_sleep();
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS);
- /* avoid fast toggling */
- for (i = 0; i < 10; i++) {
- msleep(10);
- bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
- }
-
- bnx2x_link_settings_status(bp, gp_status);
-
- /* anything 10 and over uses the bmac */
- link_10g = ((bp->line_speed >= SPEED_10000) &&
- (bp->line_speed <= SPEED_16000));
-
- bnx2x_link_int_ack(bp, link_10g);
-
- /* link is up only if both local phy and external phy are up */
- bp->link_up = (bp->phy_link_up && bnx2x_ext_phy_is_link_up(bp));
- if (bp->link_up) {
- if (link_10g) {
- bnx2x_bmac_enable(bp, 0);
- bnx2x_leds_set(bp, SPEED_10000);
-
- } else {
- bnx2x_emac_enable(bp);
- bnx2x_emac_program(bp);
-
- /* AN complete? */
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- if (!(bp->phy_flags & PHY_SGMII_FLAG))
- bnx2x_set_sgmii_tx_driver(bp);
- }
- }
- bnx2x_link_up(bp);
-
- } else { /* link down */
- bnx2x_leds_unset(bp);
- bnx2x_link_down(bp);
- }
-
- bnx2x_init_mac_stats(bp);
-}
-
-/*
- * Init service functions
- */
-
-static void bnx2x_set_aer_mmd(struct bnx2x *bp)
-{
- u16 offset = (bp->phy_flags & PHY_XGXS_FLAG) ?
- (bp->phy_addr + bp->ser_lane) : 0;
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_AER_BLOCK);
- bnx2x_mdio22_write(bp, MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
-}
-
-static void bnx2x_set_master_ln(struct bnx2x *bp)
-{
- u32 new_master_ln;
-
- /* set the master_ln for AN */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
- bnx2x_mdio22_read(bp, MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
- &new_master_ln);
- bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
- (new_master_ln | bp->ser_lane));
-}
-
-static void bnx2x_reset_unicore(struct bnx2x *bp)
-{
- u32 mii_control;
- int i;
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
- /* reset the unicore */
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control | MDIO_COMBO_IEEO_MII_CONTROL_RESET));
-
- /* wait for the reset to self clear */
- for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
- udelay(5);
-
- /* the reset erased the previous bank value */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
-
- if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
- udelay(5);
- return;
- }
- }
-
- BNX2X_ERR("BUG! %s (0x%x) is still in reset!\n",
- (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
- bp->phy_addr);
-}
-
-static void bnx2x_set_swap_lanes(struct bnx2x *bp)
-{
- /* Each two bits represents a lane number:
- No swap is 0123 => 0x1b no need to enable the swap */
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
- if (bp->rx_lane_swap != 0x1b) {
- bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_RX_LN_SWAP,
- (bp->rx_lane_swap |
- MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
- MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
- } else {
- bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
- }
-
- if (bp->tx_lane_swap != 0x1b) {
- bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TX_LN_SWAP,
- (bp->tx_lane_swap |
- MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
- } else {
- bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
- }
-}
-
-static void bnx2x_set_parallel_detection(struct bnx2x *bp)
-{
- u32 control2;
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
- bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
- &control2);
-
- if (bp->autoneg & AUTONEG_PARALLEL) {
- control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
- } else {
- control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
- }
- bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
- control2);
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT);
-
- bnx2x_mdio22_write(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
-
- bnx2x_mdio22_read(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- &control2);
-
- if (bp->autoneg & AUTONEG_PARALLEL) {
- control2 |=
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
- } else {
- control2 &=
- ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
- }
- bnx2x_mdio22_write(bp,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- control2);
-
- /* Disable parallel detection of HiG */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
- bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
- MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
- MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
- }
-}
-
-static void bnx2x_set_autoneg(struct bnx2x *bp)
-{
- u32 reg_val;
-
- /* CL37 Autoneg */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
- if ((bp->req_autoneg & AUTONEG_SPEED) &&
- (bp->autoneg & AUTONEG_CL37)) {
- /* CL37 Autoneg Enabled */
- reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
- } else {
- /* CL37 Autoneg Disabled */
- reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
- }
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
-
- /* Enable/Disable Autodetection */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
- bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
- reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
-
- if ((bp->req_autoneg & AUTONEG_SPEED) &&
- (bp->autoneg & AUTONEG_SGMII_FIBER_AUTODET)) {
- reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
- } else {
- reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
- }
- bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
-
- /* Enable TetonII and BAM autoneg */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_BAM_NEXT_PAGE);
- bnx2x_mdio22_read(bp, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
- &reg_val);
- if ((bp->req_autoneg & AUTONEG_SPEED) &&
- (bp->autoneg & AUTONEG_CL37) && (bp->autoneg & AUTONEG_BAM)) {
- /* Enable BAM aneg Mode and TetonII aneg Mode */
- reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
- MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
- } else {
- /* TetonII and BAM Autoneg Disabled */
- reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
- MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
- }
- bnx2x_mdio22_write(bp, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
- reg_val);
-
- /* Enable Clause 73 Aneg */
- if ((bp->req_autoneg & AUTONEG_SPEED) &&
- (bp->autoneg & AUTONEG_CL73)) {
- /* Enable BAM Station Manager */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_USERB0);
- bnx2x_mdio22_write(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL1,
- (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
-
- /* Merge CL73 and CL37 aneg resolution */
- bnx2x_mdio22_read(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- &reg_val);
- bnx2x_mdio22_write(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- (reg_val |
- MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
-
- /* Set the CL73 AN speed */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB1);
- bnx2x_mdio22_read(bp, MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
- /* In the SerDes we support only the 1G.
- In the XGXS we support the 10G KX4
- but we currently do not support the KR */
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- /* 10G KX4 */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
- } else {
- DP(NETIF_MSG_LINK, "SerDes\n");
- /* 1000M KX */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
- }
- bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
-
- /* CL73 Autoneg Enabled */
- reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
- } else {
- /* CL73 Autoneg Disabled */
- reg_val = 0;
- }
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0);
- bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
-}
-
-/* program SerDes, forced speed */
-static void bnx2x_program_serdes(struct bnx2x *bp)
-{
- u32 reg_val;
-
- /* program duplex, disable autoneg */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
- reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
- if (bp->req_duplex == DUPLEX_FULL)
- reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
-
- /* program speed
- - needed only if the speed is greater than 1G (2.5G or 10G) */
- if (bp->req_line_speed > SPEED_1000) {
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
- bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_MISC1, &reg_val);
- /* clearing the speed value before setting the right speed */
- reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK;
- reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
- MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
- if (bp->req_line_speed == SPEED_10000)
- reg_val |=
- MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
- bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_MISC1, reg_val);
- }
-}
-
-static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp)
-{
- u32 val = 0;
-
- /* configure the 48 bits for BAM AN */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
-
- /* set extended capabilities */
- if (bp->advertising & ADVERTISED_2500baseX_Full)
- val |= MDIO_OVER_1G_UP1_2_5G;
- if (bp->advertising & ADVERTISED_10000baseT_Full)
- val |= MDIO_OVER_1G_UP1_10G;
- bnx2x_mdio22_write(bp, MDIO_OVER_1G_UP1, val);
-
- bnx2x_mdio22_write(bp, MDIO_OVER_1G_UP3, 0);
-}
-
-static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp)
-{
- u32 an_adv;
-
- /* for AN, we are always publishing full duplex */
- an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
-
- /* resolve pause mode and advertisement
- * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
- if (bp->req_autoneg & AUTONEG_FLOW_CTRL) {
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- if (bp->dev->mtu <= 4500) {
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- }
- break;
-
- case FLOW_CTRL_TX:
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- break;
-
- case FLOW_CTRL_RX:
- if (bp->dev->mtu <= 4500) {
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- }
- break;
-
- case FLOW_CTRL_BOTH:
- if (bp->dev->mtu <= 4500) {
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- } else {
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- }
- break;
-
- case FLOW_CTRL_NONE:
- default:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- }
- } else { /* forced mode */
- switch (bp->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- DP(NETIF_MSG_LINK, "req_flow_ctrl 0x%x while"
- " req_autoneg 0x%x\n",
- bp->req_flow_ctrl, bp->req_autoneg);
- break;
-
- case FLOW_CTRL_TX:
- an_adv |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- bp->advertising |= ADVERTISED_Asym_Pause;
- break;
-
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- bp->advertising |= (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
-
- case FLOW_CTRL_NONE:
- default:
- an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
- bp->advertising &= ~(ADVERTISED_Pause |
- ADVERTISED_Asym_Pause);
- break;
- }
- }
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv);
-}
-
-static void bnx2x_restart_autoneg(struct bnx2x *bp)
-{
- if (bp->autoneg & AUTONEG_CL73) {
- /* enable and restart clause 73 aneg */
- u32 an_ctrl;
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0);
- bnx2x_mdio22_read(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- &an_ctrl);
- bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- (an_ctrl |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
-
- } else {
- /* Enable and restart BAM/CL37 aneg */
- u32 mii_control;
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
- }
-}
-
-static void bnx2x_initialize_sgmii_process(struct bnx2x *bp)
-{
- u32 control1;
-
- /* in SGMII mode, the unicore is always slave */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
- bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
- &control1);
- control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
- /* set sgmii mode (and not fiber) */
- control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
- bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
- control1);
-
- /* if forced speed */
- if (!(bp->req_autoneg & AUTONEG_SPEED)) {
- /* set speed, disable autoneg */
- u32 mii_control;
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK |
- MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
-
- switch (bp->req_line_speed) {
- case SPEED_100:
- mii_control |=
- MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
- break;
- case SPEED_1000:
- mii_control |=
- MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
- break;
- case SPEED_10:
- /* there is nothing to set for 10M */
- break;
- default:
- /* invalid speed for SGMII */
- DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n",
- bp->req_line_speed);
- break;
- }
-
- /* setting the full duplex */
- if (bp->req_duplex == DUPLEX_FULL)
- mii_control |=
- MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- mii_control);
-
- } else { /* AN mode */
- /* enable and restart AN */
- bnx2x_restart_autoneg(bp);
- }
-}
-
-static void bnx2x_link_int_enable(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 ext_phy_type;
- u32 mask;
-
- /* setting the status to report on link up
- for either XGXS or SerDes */
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- mask = (NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_XGXS0_LINK_STATUS);
- DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
-
- } else { /* SerDes */
- mask = NIG_MASK_SERDES0_LINK_STATUS;
- DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
- ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
- if ((ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
- }
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- mask);
- DP(NETIF_MSG_LINK, "port %x, %s, int_status 0x%x,"
- " int_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
- " 10G %x, XGXS_LINK %x\n", port,
- (bp->phy_flags & PHY_XGXS_FLAG)? "XGXS":"SerDes",
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
- REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
- );
-}
-
-static void bnx2x_bcm8072_external_rom_boot(struct bnx2x *bp)
-{
- u32 ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 fw_ver1, fw_ver2;
-
- /* Need to wait 200ms after reset */
- msleep(200);
- /* Boot port from external ROM
- * Set ser_boot_ctl bit in the MISC_CTRL1 register
- */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- EXT_PHY_KR_MISC_CTRL1, 0x0001);
-
- /* Reset internal microprocessor */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
- EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
- /* set micro reset = 0 */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
- EXT_PHY_KR_ROM_MICRO_RESET);
- /* Reset internal microprocessor */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_GEN_CTRL,
- EXT_PHY_KR_ROM_RESET_INTERNAL_MP);
- /* wait for 100ms for code download via SPI port */
- msleep(100);
-
- /* Clear ser_boot_ctl bit */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- EXT_PHY_KR_MISC_CTRL1, 0x0000);
- /* Wait 100ms */
- msleep(100);
-
- /* Print the PHY FW version */
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- 0xca19, &fw_ver1);
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- 0xca1a, &fw_ver2);
- DP(NETIF_MSG_LINK,
- "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
-}
-
-static void bnx2x_bcm8072_force_10G(struct bnx2x *bp)
-{
- u32 ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- /* Force KR or KX */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL,
- 0x2040);
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_CTRL2,
- 0x000b);
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD, EXT_PHY_KR_PMD_CTRL,
- 0x0000);
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD, EXT_PHY_KR_CTRL,
- 0x0000);
-}
-
-static void bnx2x_ext_phy_init(struct bnx2x *bp)
-{
- u32 ext_phy_type;
- u32 ext_phy_addr;
- u32 cnt;
- u32 ctrl;
- u32 val = 0;
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- /* Make sure that the soft reset is off (expect for the 8072:
- * due to the lock, it will be done inside the specific
- * handling)
- */
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)) {
- /* Wait for soft reset to get cleared upto 1 sec */
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_CNTL, &ctrl);
- if (!(ctrl & (1<<15)))
- break;
- msleep(1);
- }
- DP(NETIF_MSG_LINK,
- "control reg 0x%x (after %d ms)\n", ctrl, cnt);
- }
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
-
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PMD_MISC_CNTL,
- 0x8288);
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PHY_IDENTIFIER,
- 0x7fbf);
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_CMU_PLL_BYPASS,
- 0x0100);
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_WIS_DEVAD,
- EXT_PHY_OPT_LASI_CNTL, 0x1);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
-
- if (!(bp->req_autoneg & AUTONEG_SPEED)) {
- /* Force speed */
- if (bp->req_line_speed == SPEED_10000) {
- DP(NETIF_MSG_LINK,
- "XGXS 8706 force 10Gbps\n");
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_PMD_DIGITAL_CNT,
- 0x400);
- } else {
- /* Force 1Gbps */
- DP(NETIF_MSG_LINK,
- "XGXS 8706 force 1Gbps\n");
-
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_CNTL,
- 0x0040);
-
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_CNTL2,
- 0x000D);
- }
-
- /* Enable LASI */
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_CNTL,
- 0x1);
- } else {
- /* AUTONEG */
- /* Allow CL37 through CL73 */
- DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_AUTO_NEG_DEVAD,
- EXT_PHY_OPT_AN_CL37_CL73,
- 0x040c);
-
- /* Enable Full-Duplex advertisment on CL37 */
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_AUTO_NEG_DEVAD,
- EXT_PHY_OPT_AN_CL37_FD,
- 0x0020);
- /* Enable CL37 AN */
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_AUTO_NEG_DEVAD,
- EXT_PHY_OPT_AN_CL37_AN,
- 0x1000);
- /* Advertise 10G/1G support */
- if (bp->advertising &
- ADVERTISED_1000baseT_Full)
- val = (1<<5);
- if (bp->advertising &
- ADVERTISED_10000baseT_Full)
- val |= (1<<7);
-
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_AUTO_NEG_DEVAD,
- EXT_PHY_OPT_AN_ADV, val);
- /* Enable LASI */
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_CNTL,
- 0x1);
-
- /* Enable clause 73 AN */
- bnx2x_mdio45_write(bp, ext_phy_addr,
- EXT_PHY_AUTO_NEG_DEVAD,
- EXT_PHY_OPT_CNTL,
- 0x1200);
- }
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
- /* Wait for soft reset to get cleared upto 1 sec */
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_mdio45_ctrl_read(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_CNTL, &ctrl);
- if (!(ctrl & (1<<15)))
- break;
- msleep(1);
- }
- DP(NETIF_MSG_LINK,
- "8072 control reg 0x%x (after %d ms)\n",
- ctrl, cnt);
-
- bnx2x_bcm8072_external_rom_boot(bp);
- DP(NETIF_MSG_LINK, "Finshed loading 8072 KR ROM\n");
-
- /* enable LASI */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- 0x9000, 0x0400);
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- EXT_PHY_KR_LASI_CNTL, 0x0004);
-
- /* If this is forced speed, set to KR or KX
- * (all other are not supported)
- */
- if (!(bp->req_autoneg & AUTONEG_SPEED)) {
- if (bp->req_line_speed == SPEED_10000) {
- bnx2x_bcm8072_force_10G(bp);
- DP(NETIF_MSG_LINK,
- "Forced speed 10G on 8072\n");
- /* unlock */
- bnx2x_hw_unlock(bp,
- HW_LOCK_RESOURCE_8072_MDIO);
- break;
- } else
- val = (1<<5);
- } else {
-
- /* Advertise 10G/1G support */
- if (bp->advertising &
- ADVERTISED_1000baseT_Full)
- val = (1<<5);
- if (bp->advertising &
- ADVERTISED_10000baseT_Full)
- val |= (1<<7);
- }
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- 0x11, val);
- /* Add support for CL37 ( passive mode ) I */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- 0x8370, 0x040c);
- /* Add support for CL37 ( passive mode ) II */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- 0xffe4, 0x20);
- /* Add support for CL37 ( passive mode ) III */
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- 0xffe0, 0x1000);
- /* Restart autoneg */
- msleep(500);
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_CTRL, 0x1200);
- DP(NETIF_MSG_LINK, "8072 Autoneg Restart: "
- "1G %ssupported 10G %ssupported\n",
- (val & (1<<5)) ? "" : "not ",
- (val & (1<<7)) ? "" : "not ");
-
- /* unlock */
- bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LASI indication\n");
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_LASI_CNTL, 0x1);
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LED to blink on traffic\n");
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- 0xC007, (1<<3));
-
- /* read modify write pause advertizing */
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_AUTO_NEG_ADVERT, &val);
- val &= ~EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH;
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
- if (bp->advertising & ADVERTISED_Pause)
- val |= EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE;
-
- if (bp->advertising & ADVERTISED_Asym_Pause) {
- val |=
- EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC;
- }
- DP(NETIF_MSG_LINK, "SFX7101 AN advertize 0x%x\n", val);
- bnx2x_mdio45_vwrite(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_AUTO_NEG_ADVERT, val);
- /* Restart autoneg */
- bnx2x_mdio45_read(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_CTRL, &val);
- val |= 0x200;
- bnx2x_mdio45_write(bp, ext_phy_addr,
- EXT_PHY_KR_AUTO_NEG_DEVAD,
- EXT_PHY_KR_CTRL, val);
- break;
-
- default:
- BNX2X_ERR("BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- break;
- }
-
- } else { /* SerDes */
-/* ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
-*/
- ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- break;
- }
- }
-}
-
-static void bnx2x_ext_phy_reset(struct bnx2x *bp)
-{
- u32 ext_phy_type;
- u32 ext_phy_addr = ((bp->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
-
- /* The PHY reset is controled by GPIO 1
- * Give it 1ms of reset pulse
- */
- if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
- (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW);
- msleep(1);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH);
- }
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
- bnx2x_mdio45_write(bp, ext_phy_addr,
- EXT_PHY_OPT_PMA_PMD_DEVAD,
- EXT_PHY_OPT_CNTL, 0xa040);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- DP(NETIF_MSG_LINK, "XGXS 8072\n");
- bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
- bnx2x_mdio45_ctrl_write(bp, GRCBASE_EMAC0,
- ext_phy_addr,
- EXT_PHY_KR_PMA_PMD_DEVAD,
- 0, 1<<15);
- bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- break;
- }
-
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- break;
- }
- }
-}
-
-static void bnx2x_link_initialize(struct bnx2x *bp)
-{
- int port = bp->port;
-
- /* disable attentions */
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_SERDES0_LINK_STATUS |
- NIG_MASK_MI_INT));
-
- /* Activate the external PHY */
- bnx2x_ext_phy_reset(bp);
-
- bnx2x_set_aer_mmd(bp);
-
- if (bp->phy_flags & PHY_XGXS_FLAG)
- bnx2x_set_master_ln(bp);
-
- /* reset the SerDes and wait for reset bit return low */
- bnx2x_reset_unicore(bp);
-
- bnx2x_set_aer_mmd(bp);
-
- /* setting the masterLn_def again after the reset */
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- bnx2x_set_master_ln(bp);
- bnx2x_set_swap_lanes(bp);
- }
-
- /* Set Parallel Detect */
- if (bp->req_autoneg & AUTONEG_SPEED)
- bnx2x_set_parallel_detection(bp);
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- if (bp->req_line_speed &&
- bp->req_line_speed < SPEED_1000) {
- bp->phy_flags |= PHY_SGMII_FLAG;
- } else {
- bp->phy_flags &= ~PHY_SGMII_FLAG;
- }
- }
-
- if (!(bp->phy_flags & PHY_SGMII_FLAG)) {
- u16 bank, rx_eq;
-
- rx_eq = ((bp->serdes_config &
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
-
- DP(NETIF_MSG_LINK, "setting rx eq to %d\n", rx_eq);
- for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
- bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0)) {
- MDIO_SET_REG_BANK(bp, bank);
- bnx2x_mdio22_write(bp, MDIO_RX0_RX_EQ_BOOST,
- ((rx_eq &
- MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
- MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
- }
-
- /* forced speed requested? */
- if (!(bp->req_autoneg & AUTONEG_SPEED)) {
- DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
-
- /* disable autoneg */
- bnx2x_set_autoneg(bp);
-
- /* program speed and duplex */
- bnx2x_program_serdes(bp);
-
- } else { /* AN_mode */
- DP(NETIF_MSG_LINK, "not SGMII, AN\n");
-
- /* AN enabled */
- bnx2x_set_brcm_cl37_advertisment(bp);
-
- /* program duplex & pause advertisement (for aneg) */
- bnx2x_set_ieee_aneg_advertisment(bp);
-
- /* enable autoneg */
- bnx2x_set_autoneg(bp);
-
- /* enable and restart AN */
- bnx2x_restart_autoneg(bp);
- }
-
- } else { /* SGMII mode */
- DP(NETIF_MSG_LINK, "SGMII\n");
-
- bnx2x_initialize_sgmii_process(bp);
- }
-
- /* init ext phy and enable link state int */
- bnx2x_ext_phy_init(bp);
-
- /* enable the interrupt */
- bnx2x_link_int_enable(bp);
-}
-
-static void bnx2x_phy_deassert(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 val;
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- val = XGXS_RESET_BITS;
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes\n");
- val = SERDES_RESET_BITS;
- }
-
- val = val << (port*16);
-
- /* reset and unreset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
- msleep(5);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
-}
-
-static int bnx2x_phy_init(struct bnx2x *bp)
-{
- DP(NETIF_MSG_LINK, "started\n");
- if (CHIP_REV(bp) == CHIP_REV_FPGA) {
- bp->phy_flags |= PHY_EMAC_FLAG;
- bp->link_up = 1;
- bp->line_speed = SPEED_10000;
- bp->duplex = DUPLEX_FULL;
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + bp->port*4, 0);
- bnx2x_emac_enable(bp);
- bnx2x_link_report(bp);
- return 0;
-
- } else if (CHIP_REV(bp) == CHIP_REV_EMUL) {
- bp->phy_flags |= PHY_BMAC_FLAG;
- bp->link_up = 1;
- bp->line_speed = SPEED_10000;
- bp->duplex = DUPLEX_FULL;
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + bp->port*4, 0);
- bnx2x_bmac_enable(bp, 0);
- bnx2x_link_report(bp);
- return 0;
-
- } else {
- bnx2x_phy_deassert(bp);
- bnx2x_link_initialize(bp);
- }
-
- return 0;
-}
-
-static void bnx2x_link_reset(struct bnx2x *bp)
-{
- int port = bp->port;
- u32 board = (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK);
-
- /* update shared memory */
- bp->link_status = 0;
- bnx2x_update_mng(bp);
-
- /* disable attentions */
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_SERDES0_LINK_STATUS |
- NIG_MASK_MI_INT));
-
- /* activate nig drain */
- NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
- /* disable nig egress interface */
- NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
- NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
-
- /* Stop BigMac rx */
- bnx2x_bmac_rx_disable(bp);
-
- /* disable emac */
- NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
-
- msleep(10);
-
- /* The PHY reset is controled by GPIO 1
- * Hold it as output low
- */
- if ((board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G) &&
- (board != SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G)) {
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW);
- DP(NETIF_MSG_LINK, "reset external PHY\n");
- }
-
- /* reset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- (0x1ff << (port*16)));
-
- /* reset BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* disable nig ingress interface */
- NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
- NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0);
-
- /* set link down */
- bp->link_up = 0;
-}
-
-#ifdef BNX2X_XGXS_LB
-static void bnx2x_set_xgxs_loopback(struct bnx2x *bp, int is_10g)
-{
- int port = bp->port;
-
- if (is_10g) {
- u32 md_devad;
-
- DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
-
- /* change the uni_phy_addr in the nig */
- REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18),
- &md_devad);
- NIG_WR(NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
-
- /* change the aer mmd */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_AER_BLOCK);
- bnx2x_mdio22_write(bp, MDIO_AER_BLOCK_AER_REG, 0x2800);
-
- /* config combo IEEE0 control reg for loopback */
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0);
- bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- 0x6041);
-
- /* set aer mmd back */
- bnx2x_set_aer_mmd(bp);
-
- /* and md_devad */
- NIG_WR(NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad);
-
- } else {
- u32 mii_control;
-
- DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
-
- MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
- bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
- }
-}
-#endif
-
-/* end of PHY/MAC */
-
-/* slow path */
-
-/*
- * General service functions
- */
-
-/* the slow path queue is odd since completions arrive on the fastpath ring */
-static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
- u32 data_hi, u32 data_lo, int common)
-{
- int port = bp->port;
-
- DP(NETIF_MSG_TIMER,
- "spe (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
- (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
- (void *)bp->spq_prod_bd - (void *)bp->spq), command,
- HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return -EIO;
-#endif
-
- spin_lock(&bp->spq_lock);
-
- if (!bp->spq_left) {
- BNX2X_ERR("BUG! SPQ ring full!\n");
- spin_unlock(&bp->spq_lock);
- bnx2x_panic();
- return -EBUSY;
- }
-
- /* CID needs port number to be encoded int it */
- bp->spq_prod_bd->hdr.conn_and_cmd_data =
- cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
- HW_CID(bp, cid)));
- bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
- if (common)
- bp->spq_prod_bd->hdr.type |=
- cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
-
- bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi);
- bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo);
-
- bp->spq_left--;
-
- if (bp->spq_prod_bd == bp->spq_last_bd) {
- bp->spq_prod_bd = bp->spq;
- bp->spq_prod_idx = 0;
- DP(NETIF_MSG_TIMER, "end of spq\n");
-
- } else {
- bp->spq_prod_bd++;
- bp->spq_prod_idx++;
- }
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(port),
- bp->spq_prod_idx);
-
- spin_unlock(&bp->spq_lock);
- return 0;
-}
-
-/* acquire split MCP access lock register */
-static int bnx2x_lock_alr(struct bnx2x *bp)
-{
- int rc = 0;
- u32 i, j, val;
-
- might_sleep();
- i = 100;
- for (j = 0; j < i*10; j++) {
- val = (1UL << 31);
- REG_WR(bp, GRCBASE_MCP + 0x9c, val);
- val = REG_RD(bp, GRCBASE_MCP + 0x9c);
- if (val & (1L << 31))
- break;
-
- msleep(5);
- }
-
- if (!(val & (1L << 31))) {
- BNX2X_ERR("Cannot acquire nvram interface\n");
-
- rc = -EBUSY;
- }
-
- return rc;
-}
-
-/* Release split MCP access lock register */
-static void bnx2x_unlock_alr(struct bnx2x *bp)
-{
- u32 val = 0;
-
- REG_WR(bp, GRCBASE_MCP + 0x9c, val);
-}
-
-static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
-{
- struct host_def_status_block *def_sb = bp->def_status_blk;
- u16 rc = 0;
-
- barrier(); /* status block is written to by the chip */
-
- if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) {
- bp->def_att_idx = def_sb->atten_status_block.attn_bits_index;
- rc |= 1;
- }
- if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) {
- bp->def_c_idx = def_sb->c_def_status_block.status_block_index;
- rc |= 2;
- }
- if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) {
- bp->def_u_idx = def_sb->u_def_status_block.status_block_index;
- rc |= 4;
- }
- if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) {
- bp->def_x_idx = def_sb->x_def_status_block.status_block_index;
- rc |= 8;
- }
- if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) {
- bp->def_t_idx = def_sb->t_def_status_block.status_block_index;
- rc |= 16;
- }
- return rc;
-}
-
-/*
- * slow path service functions
- */
-
-static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
-{
- int port = bp->port;
- u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8;
- u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
- MISC_REG_AEU_MASK_ATTN_FUNC_0;
- u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
- NIG_REG_MASK_INTERRUPT_PORT0;
-
- if (~bp->aeu_mask & (asserted & 0xff))
- BNX2X_ERR("IGU ERROR\n");
- if (bp->attn_state & asserted)
- BNX2X_ERR("IGU ERROR\n");
-
- DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n",
- bp->aeu_mask, asserted);
- bp->aeu_mask &= ~(asserted & 0xff);
- DP(NETIF_MSG_HW, "after masking: aeu_mask %x\n", bp->aeu_mask);
-
- REG_WR(bp, aeu_addr, bp->aeu_mask);
-
- bp->attn_state |= asserted;
-
- if (asserted & ATTN_HARD_WIRED_MASK) {
- if (asserted & ATTN_NIG_FOR_FUNC) {
-
- /* save nig interrupt mask */
- bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
- REG_WR(bp, nig_int_mask_addr, 0);
-
- bnx2x_link_update(bp);
-
- /* handle unicore attn? */
- }
- if (asserted & ATTN_SW_TIMER_4_FUNC)
- DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n");
-
- if (asserted & GPIO_2_FUNC)
- DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n");
-
- if (asserted & GPIO_3_FUNC)
- DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n");
-
- if (asserted & GPIO_4_FUNC)
- DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n");
-
- if (port == 0) {
- if (asserted & ATTN_GENERAL_ATTN_1) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_2) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_3) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0);
- }
- } else {
- if (asserted & ATTN_GENERAL_ATTN_4) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_5) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_6) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0);
- }
- }
-
- } /* if hardwired */
-
- DP(NETIF_MSG_HW, "about to mask 0x%08x at IGU addr 0x%x\n",
- asserted, BAR_IGU_INTMEM + igu_addr);
- REG_WR(bp, BAR_IGU_INTMEM + igu_addr, asserted);
-
- /* now set back the mask */
- if (asserted & ATTN_NIG_FOR_FUNC)
- REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
-}
-
-static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
-{
- int port = bp->port;
- int reg_offset;
- u32 val;
-
- if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) {
-
- reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
- MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
-
- val = REG_RD(bp, reg_offset);
- val &= ~AEU_INPUTS_ATTN_BITS_SPIO5;
- REG_WR(bp, reg_offset, val);
-
- BNX2X_ERR("SPIO5 hw attention\n");
-
- switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
- /* Fan failure attention */
-
- /* The PHY reset is controled by GPIO 1 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW);
- /* Low power mode is controled by GPIO 2 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW);
- /* mark the failure */
- bp->ext_phy_config &=
- ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
- bp->ext_phy_config |=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
- SHMEM_WR(bp,
- dev_info.port_hw_config[port].
- external_phy_config,
- bp->ext_phy_config);
- /* log the failure */
- printk(KERN_ERR PFX "Fan Failure on Network"
- " Controller %s has caused the driver to"
- " shutdown the card to prevent permanent"
- " damage. Please contact Dell Support for"
- " assistance\n", bp->dev->name);
- break;
-
- default:
- break;
- }
- }
-}
-
-static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
-{
- u32 val;
-
- if (attn & BNX2X_DOORQ_ASSERT) {
-
- val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
- BNX2X_ERR("DB hw attention 0x%x\n", val);
- /* DORQ discard attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from DORQ\n");
- }
-}
-
-static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
-{
- u32 val;
-
- if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
-
- val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
- BNX2X_ERR("CFC hw attention 0x%x\n", val);
- /* CFC error attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from CFC\n");
- }
-
- if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
-
- val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
- BNX2X_ERR("PXP hw attention 0x%x\n", val);
- /* RQ_USDMDP_FIFO_OVERFLOW */
- if (val & 0x18000)
- BNX2X_ERR("FATAL error from PXP\n");
- }
-}
-
-static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
-{
- if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) {
-
- if (attn & BNX2X_MC_ASSERT_BITS) {
-
- BNX2X_ERR("MC assert!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0);
- bnx2x_panic();
-
- } else if (attn & BNX2X_MCP_ASSERT) {
-
- BNX2X_ERR("MCP assert!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0);
- bnx2x_mc_assert(bp);
-
- } else
- BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn);
- }
-
- if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
-
- REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
- BNX2X_ERR("LATCHED attention 0x%x (masked)\n", attn);
- }
-}
-
-static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
-{
- struct attn_route attn;
- struct attn_route group_mask;
- int port = bp->port;
- int index;
- u32 reg_addr;
- u32 val;
-
- /* need to take HW lock because MCP or other port might also
- try to handle this event */
- bnx2x_lock_alr(bp);
-
- attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4);
- attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4);
- attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4);
- attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4);
- DP(NETIF_MSG_HW, "attn %llx\n", (unsigned long long)attn.sig[0]);
-
- for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
- if (deasserted & (1 << index)) {
- group_mask = bp->attn_group[index];
-
- DP(NETIF_MSG_HW, "group[%d]: %llx\n", index,
- (unsigned long long)group_mask.sig[0]);
-
- bnx2x_attn_int_deasserted3(bp,
- attn.sig[3] & group_mask.sig[3]);
- bnx2x_attn_int_deasserted1(bp,
- attn.sig[1] & group_mask.sig[1]);
- bnx2x_attn_int_deasserted2(bp,
- attn.sig[2] & group_mask.sig[2]);
- bnx2x_attn_int_deasserted0(bp,
- attn.sig[0] & group_mask.sig[0]);
-
- if ((attn.sig[0] & group_mask.sig[0] &
- HW_INTERRUT_ASSERT_SET_0) ||
- (attn.sig[1] & group_mask.sig[1] &
- HW_INTERRUT_ASSERT_SET_1) ||
- (attn.sig[2] & group_mask.sig[2] &
- HW_INTERRUT_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block attention"
- " set0 0x%x set1 0x%x"
- " set2 0x%x\n",
- (attn.sig[0] & group_mask.sig[0] &
- HW_INTERRUT_ASSERT_SET_0),
- (attn.sig[1] & group_mask.sig[1] &
- HW_INTERRUT_ASSERT_SET_1),
- (attn.sig[2] & group_mask.sig[2] &
- HW_INTERRUT_ASSERT_SET_2));
-
- if ((attn.sig[0] & group_mask.sig[0] &
- HW_PRTY_ASSERT_SET_0) ||
- (attn.sig[1] & group_mask.sig[1] &
- HW_PRTY_ASSERT_SET_1) ||
- (attn.sig[2] & group_mask.sig[2] &
- HW_PRTY_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block parity attention\n");
- }
- }
-
- bnx2x_unlock_alr(bp);
-
- reg_addr = (IGU_ADDR_ATTN_BITS_CLR + IGU_PORT_BASE * port) * 8;
-
- val = ~deasserted;
-/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
- val, BAR_IGU_INTMEM + reg_addr); */
- REG_WR(bp, BAR_IGU_INTMEM + reg_addr, val);
-
- if (bp->aeu_mask & (deasserted & 0xff))
- BNX2X_ERR("IGU BUG\n");
- if (~bp->attn_state & deasserted)
- BNX2X_ERR("IGU BUG\n");
-
- reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
- MISC_REG_AEU_MASK_ATTN_FUNC_0;
-
- DP(NETIF_MSG_HW, "aeu_mask %x\n", bp->aeu_mask);
- bp->aeu_mask |= (deasserted & 0xff);
-
- DP(NETIF_MSG_HW, "new mask %x\n", bp->aeu_mask);
- REG_WR(bp, reg_addr, bp->aeu_mask);
-
- DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
- bp->attn_state &= ~deasserted;
- DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state);
-}
-
-static void bnx2x_attn_int(struct bnx2x *bp)
-{
- /* read local copy of bits */
- u32 attn_bits = bp->def_status_blk->atten_status_block.attn_bits;
- u32 attn_ack = bp->def_status_blk->atten_status_block.attn_bits_ack;
- u32 attn_state = bp->attn_state;
-
- /* look for changed bits */
- u32 asserted = attn_bits & ~attn_ack & ~attn_state;
- u32 deasserted = ~attn_bits & attn_ack & attn_state;
-
- DP(NETIF_MSG_HW,
- "attn_bits %x attn_ack %x asserted %x deasserted %x\n",
- attn_bits, attn_ack, asserted, deasserted);
-
- if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state))
- BNX2X_ERR("bad attention state\n");
-
- /* handle bits that were raised */
- if (asserted)
- bnx2x_attn_int_asserted(bp, asserted);
-
- if (deasserted)
- bnx2x_attn_int_deasserted(bp, deasserted);
-}
-
-static void bnx2x_sp_task(struct work_struct *work)
-{
- struct bnx2x *bp = container_of(work, struct bnx2x, sp_task);
- u16 status;
-
- /* Return here if interrupt is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
- return;
- }
-
- status = bnx2x_update_dsb_idx(bp);
- if (status == 0)
- BNX2X_ERR("spurious slowpath interrupt!\n");
-
- DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
-
- /* HW attentions */
- if (status & 0x1)
- bnx2x_attn_int(bp);
-
- /* CStorm events: query_stats, port delete ramrod */
- if (status & 0x2)
- bp->stat_pending = 0;
-
- bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx,
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
- IGU_INT_ENABLE, 1);
-
-}
-
-static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
-{
- struct net_device *dev = dev_instance;
- struct bnx2x *bp = netdev_priv(dev);
-
- /* Return here if interrupt is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
- return IRQ_HANDLED;
- }
-
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return IRQ_HANDLED;
-#endif
-
- schedule_work(&bp->sp_task);
-
- return IRQ_HANDLED;
-}
-
-/* end of slow path */
-
-/* Statistics */
-
-/****************************************************************************
-* Macros
-****************************************************************************/
-
-#define UPDATE_STAT(s, t) \
- do { \
- estats->t += new->s - old->s; \
- old->s = new->s; \
- } while (0)
-
-/* sum[hi:lo] += add[hi:lo] */
-#define ADD_64(s_hi, a_hi, s_lo, a_lo) \
- do { \
- s_lo += a_lo; \
- s_hi += a_hi + (s_lo < a_lo) ? 1 : 0; \
- } while (0)
-
-/* difference = minuend - subtrahend */
-#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
- do { \
- if (m_lo < s_lo) { /* underflow */ \
- d_hi = m_hi - s_hi; \
- if (d_hi > 0) { /* we can 'loan' 1 */ \
- d_hi--; \
- d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
- } else { /* m_hi <= s_hi */ \
- d_hi = 0; \
- d_lo = 0; \
- } \
- } else { /* m_lo >= s_lo */ \
- if (m_hi < s_hi) { \
- d_hi = 0; \
- d_lo = 0; \
- } else { /* m_hi >= s_hi */ \
- d_hi = m_hi - s_hi; \
- d_lo = m_lo - s_lo; \
- } \
- } \
- } while (0)
-
-/* minuend -= subtrahend */
-#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
- do { \
- DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \
- } while (0)
-
-#define UPDATE_STAT64(s_hi, t_hi, s_lo, t_lo) \
- do { \
- DIFF_64(diff.hi, new->s_hi, old->s_hi, \
- diff.lo, new->s_lo, old->s_lo); \
- old->s_hi = new->s_hi; \
- old->s_lo = new->s_lo; \
- ADD_64(estats->t_hi, diff.hi, \
- estats->t_lo, diff.lo); \
- } while (0)
-
-/* sum[hi:lo] += add */
-#define ADD_EXTEND_64(s_hi, s_lo, a) \
- do { \
- s_lo += a; \
- s_hi += (s_lo < a) ? 1 : 0; \
- } while (0)
-
-#define UPDATE_EXTEND_STAT(s, t_hi, t_lo) \
- do { \
- ADD_EXTEND_64(estats->t_hi, estats->t_lo, new->s); \
- } while (0)
-
-#define UPDATE_EXTEND_TSTAT(s, t_hi, t_lo) \
- do { \
- diff = le32_to_cpu(tclient->s) - old_tclient->s; \
- old_tclient->s = le32_to_cpu(tclient->s); \
- ADD_EXTEND_64(estats->t_hi, estats->t_lo, diff); \
- } while (0)
-
-/*
- * General service functions
- */
-
-static inline long bnx2x_hilo(u32 *hiref)
-{
- u32 lo = *(hiref + 1);
-#if (BITS_PER_LONG == 64)
- u32 hi = *hiref;
-
- return HILO_U64(hi, lo);
-#else
- return lo;
-#endif
-}
-
-/*
- * Init service functions
- */
-
-static void bnx2x_init_mac_stats(struct bnx2x *bp)
-{
- struct dmae_command *dmae;
- int port = bp->port;
- int loader_idx = port * 8;
- u32 opcode;
- u32 mac_addr;
-
- bp->executer_idx = 0;
- if (bp->fw_mb) {
- /* MCP */
- opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
-
- if (bp->link_up)
- opcode |= (DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE);
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, eth_stats) +
- sizeof(u32));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, eth_stats) +
- sizeof(u32));
- dmae->dst_addr_lo = bp->fw_mb >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = (offsetof(struct bnx2x_eth_stats, mac_stx_end) -
- sizeof(u32)) >> 2;
- if (bp->link_up) {
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
- } else {
- dmae->comp_addr_lo = 0;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 0;
- }
- }
-
- if (!bp->link_up) {
- /* no need to collect statistics in link down */
- return;
- }
-
- opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
-
- if (bp->phy_flags & PHY_BMAC_FLAG) {
-
- mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM :
- NIG_REG_INGRESS_BMAC0_MEM);
-
- /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
- BIGMAC_REGISTER_TX_STAT_GTBYT */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
- dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
- BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- /* BIGMAC_REGISTER_RX_STAT_GR64 ..
- BIGMAC_REGISTER_RX_STAT_GRIPJ */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct bmac_stats, rx_gr64));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct bmac_stats, rx_gr64));
- dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
- BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- } else if (bp->phy_flags & PHY_EMAC_FLAG) {
-
- mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
-
- /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- EMAC_REG_EMAC_RX_STAT_AC) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
- dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- /* EMAC_REG_EMAC_RX_STAT_AC_28 */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats,
- rx_falsecarriererrors));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats,
- rx_falsecarriererrors));
- dmae->len = 1;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- EMAC_REG_EMAC_TX_STAT_AC) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats,
- tx_ifhcoutoctets));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats,
- tx_ifhcoutoctets));
- dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
- }
-
- /* NIG */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
- dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
- NIG_REG_STAT0_BRB_DISCARD) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig));
- dmae->len = (sizeof(struct nig_stats) - 2*sizeof(u32)) >> 2;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig) +
- offsetof(struct nig_stats, done));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig) +
- offsetof(struct nig_stats, done));
- dmae->comp_val = 0xffffffff;
-}
-
-static void bnx2x_init_stats(struct bnx2x *bp)
-{
- int port = bp->port;
-
- bp->stats_state = STATS_STATE_DISABLE;
- bp->executer_idx = 0;
-
- bp->old_brb_discard = REG_RD(bp,
- NIG_REG_STAT0_BRB_DISCARD + port*0x38);
-
- memset(&bp->old_bmac, 0, sizeof(struct bmac_stats));
- memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
- memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), 1);
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), 1);
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
-
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), 0);
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
-
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-}
-
-static void bnx2x_stop_stats(struct bnx2x *bp)
-{
- might_sleep();
- if (bp->stats_state != STATS_STATE_DISABLE) {
- int timeout = 10;
-
- bp->stats_state = STATS_STATE_STOP;
- DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
-
- while (bp->stats_state != STATS_STATE_DISABLE) {
- if (!timeout) {
- BNX2X_ERR("timeout waiting for stats stop\n");
- break;
- }
- timeout--;
- msleep(100);
- }
- }
- DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
-}
-
-/*
- * Statistics service functions
- */
-
-static void bnx2x_update_bmac_stats(struct bnx2x *bp)
-{
- struct regp diff;
- struct regp sum;
- struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac);
- struct bmac_stats *old = &bp->old_bmac;
- struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
-
- sum.hi = 0;
- sum.lo = 0;
-
- UPDATE_STAT64(tx_gtbyt.hi, total_bytes_transmitted_hi,
- tx_gtbyt.lo, total_bytes_transmitted_lo);
-
- UPDATE_STAT64(tx_gtmca.hi, total_multicast_packets_transmitted_hi,
- tx_gtmca.lo, total_multicast_packets_transmitted_lo);
- ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
-
- UPDATE_STAT64(tx_gtgca.hi, total_broadcast_packets_transmitted_hi,
- tx_gtgca.lo, total_broadcast_packets_transmitted_lo);
- ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
-
- UPDATE_STAT64(tx_gtpkt.hi, total_unicast_packets_transmitted_hi,
- tx_gtpkt.lo, total_unicast_packets_transmitted_lo);
- SUB_64(estats->total_unicast_packets_transmitted_hi, sum.hi,
- estats->total_unicast_packets_transmitted_lo, sum.lo);
-
- UPDATE_STAT(tx_gtxpf.lo, pause_xoff_frames_transmitted);
- UPDATE_STAT(tx_gt64.lo, frames_transmitted_64_bytes);
- UPDATE_STAT(tx_gt127.lo, frames_transmitted_65_127_bytes);
- UPDATE_STAT(tx_gt255.lo, frames_transmitted_128_255_bytes);
- UPDATE_STAT(tx_gt511.lo, frames_transmitted_256_511_bytes);
- UPDATE_STAT(tx_gt1023.lo, frames_transmitted_512_1023_bytes);
- UPDATE_STAT(tx_gt1518.lo, frames_transmitted_1024_1522_bytes);
- UPDATE_STAT(tx_gt2047.lo, frames_transmitted_1523_9022_bytes);
- UPDATE_STAT(tx_gt4095.lo, frames_transmitted_1523_9022_bytes);
- UPDATE_STAT(tx_gt9216.lo, frames_transmitted_1523_9022_bytes);
- UPDATE_STAT(tx_gt16383.lo, frames_transmitted_1523_9022_bytes);
-
- UPDATE_STAT(rx_grfcs.lo, crc_receive_errors);
- UPDATE_STAT(rx_grund.lo, runt_packets_received);
- UPDATE_STAT(rx_grovr.lo, stat_Dot3statsFramesTooLong);
- UPDATE_STAT(rx_grxpf.lo, pause_xoff_frames_received);
- UPDATE_STAT(rx_grxcf.lo, control_frames_received);
- /* UPDATE_STAT(rx_grxpf.lo, control_frames_received); */
- UPDATE_STAT(rx_grfrg.lo, error_runt_packets_received);
- UPDATE_STAT(rx_grjbr.lo, error_jabber_packets_received);
-
- UPDATE_STAT64(rx_grerb.hi, stat_IfHCInBadOctets_hi,
- rx_grerb.lo, stat_IfHCInBadOctets_lo);
- UPDATE_STAT64(tx_gtufl.hi, stat_IfHCOutBadOctets_hi,
- tx_gtufl.lo, stat_IfHCOutBadOctets_lo);
- UPDATE_STAT(tx_gterr.lo, stat_Dot3statsInternalMacTransmitErrors);
- /* UPDATE_STAT(rx_grxpf.lo, stat_XoffStateEntered); */
- estats->stat_XoffStateEntered = estats->pause_xoff_frames_received;
-}
-
-static void bnx2x_update_emac_stats(struct bnx2x *bp)
-{
- struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac);
- struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
-
- UPDATE_EXTEND_STAT(tx_ifhcoutoctets, total_bytes_transmitted_hi,
- total_bytes_transmitted_lo);
- UPDATE_EXTEND_STAT(tx_ifhcoutucastpkts,
- total_unicast_packets_transmitted_hi,
- total_unicast_packets_transmitted_lo);
- UPDATE_EXTEND_STAT(tx_ifhcoutmulticastpkts,
- total_multicast_packets_transmitted_hi,
- total_multicast_packets_transmitted_lo);
- UPDATE_EXTEND_STAT(tx_ifhcoutbroadcastpkts,
- total_broadcast_packets_transmitted_hi,
- total_broadcast_packets_transmitted_lo);
-
- estats->pause_xon_frames_transmitted += new->tx_outxonsent;
- estats->pause_xoff_frames_transmitted += new->tx_outxoffsent;
- estats->single_collision_transmit_frames +=
- new->tx_dot3statssinglecollisionframes;
- estats->multiple_collision_transmit_frames +=
- new->tx_dot3statsmultiplecollisionframes;
- estats->late_collision_frames += new->tx_dot3statslatecollisions;
- estats->excessive_collision_frames +=
- new->tx_dot3statsexcessivecollisions;
- estats->frames_transmitted_64_bytes += new->tx_etherstatspkts64octets;
- estats->frames_transmitted_65_127_bytes +=
- new->tx_etherstatspkts65octetsto127octets;
- estats->frames_transmitted_128_255_bytes +=
- new->tx_etherstatspkts128octetsto255octets;
- estats->frames_transmitted_256_511_bytes +=
- new->tx_etherstatspkts256octetsto511octets;
- estats->frames_transmitted_512_1023_bytes +=
- new->tx_etherstatspkts512octetsto1023octets;
- estats->frames_transmitted_1024_1522_bytes +=
- new->tx_etherstatspkts1024octetsto1522octet;
- estats->frames_transmitted_1523_9022_bytes +=
- new->tx_etherstatspktsover1522octets;
-
- estats->crc_receive_errors += new->rx_dot3statsfcserrors;
- estats->alignment_errors += new->rx_dot3statsalignmenterrors;
- estats->false_carrier_detections += new->rx_falsecarriererrors;
- estats->runt_packets_received += new->rx_etherstatsundersizepkts;
- estats->stat_Dot3statsFramesTooLong += new->rx_dot3statsframestoolong;
- estats->pause_xon_frames_received += new->rx_xonpauseframesreceived;
- estats->pause_xoff_frames_received += new->rx_xoffpauseframesreceived;
- estats->control_frames_received += new->rx_maccontrolframesreceived;
- estats->error_runt_packets_received += new->rx_etherstatsfragments;
- estats->error_jabber_packets_received += new->rx_etherstatsjabbers;
-
- UPDATE_EXTEND_STAT(rx_ifhcinbadoctets, stat_IfHCInBadOctets_hi,
- stat_IfHCInBadOctets_lo);
- UPDATE_EXTEND_STAT(tx_ifhcoutbadoctets, stat_IfHCOutBadOctets_hi,
- stat_IfHCOutBadOctets_lo);
- estats->stat_Dot3statsInternalMacTransmitErrors +=
- new->tx_dot3statsinternalmactransmiterrors;
- estats->stat_Dot3StatsCarrierSenseErrors +=
- new->rx_dot3statscarriersenseerrors;
- estats->stat_Dot3StatsDeferredTransmissions +=
- new->tx_dot3statsdeferredtransmissions;
- estats->stat_FlowControlDone += new->tx_flowcontroldone;
- estats->stat_XoffStateEntered += new->rx_xoffstateentered;
-}
-
-static int bnx2x_update_storm_stats(struct bnx2x *bp)
-{
- struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
- struct tstorm_common_stats *tstats = &stats->tstorm_common;
- struct tstorm_per_client_stats *tclient =
- &tstats->client_statistics[0];
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
- struct xstorm_common_stats *xstats = &stats->xstorm_common;
- struct nig_stats *nstats = bnx2x_sp(bp, nig);
- struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
- u32 diff;
-
- /* are DMAE stats valid? */
- if (nstats->done != 0xffffffff) {
- DP(BNX2X_MSG_STATS, "stats not updated by dmae\n");
- return -1;
- }
-
- /* are storm stats valid? */
- if (tstats->done.hi != 0xffffffff) {
- DP(BNX2X_MSG_STATS, "stats not updated by tstorm\n");
- return -2;
- }
- if (xstats->done.hi != 0xffffffff) {
- DP(BNX2X_MSG_STATS, "stats not updated by xstorm\n");
- return -3;
- }
-
- estats->total_bytes_received_hi =
- estats->valid_bytes_received_hi =
- le32_to_cpu(tclient->total_rcv_bytes.hi);
- estats->total_bytes_received_lo =
- estats->valid_bytes_received_lo =
- le32_to_cpu(tclient->total_rcv_bytes.lo);
- ADD_64(estats->total_bytes_received_hi,
- le32_to_cpu(tclient->rcv_error_bytes.hi),
- estats->total_bytes_received_lo,
- le32_to_cpu(tclient->rcv_error_bytes.lo));
-
- UPDATE_EXTEND_TSTAT(rcv_unicast_pkts,
- total_unicast_packets_received_hi,
- total_unicast_packets_received_lo);
- UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
- total_multicast_packets_received_hi,
- total_multicast_packets_received_lo);
- UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
- total_broadcast_packets_received_hi,
- total_broadcast_packets_received_lo);
-
- estats->frames_received_64_bytes = MAC_STX_NA;
- estats->frames_received_65_127_bytes = MAC_STX_NA;
- estats->frames_received_128_255_bytes = MAC_STX_NA;
- estats->frames_received_256_511_bytes = MAC_STX_NA;
- estats->frames_received_512_1023_bytes = MAC_STX_NA;
- estats->frames_received_1024_1522_bytes = MAC_STX_NA;
- estats->frames_received_1523_9022_bytes = MAC_STX_NA;
-
- estats->x_total_sent_bytes_hi =
- le32_to_cpu(xstats->total_sent_bytes.hi);
- estats->x_total_sent_bytes_lo =
- le32_to_cpu(xstats->total_sent_bytes.lo);
- estats->x_total_sent_pkts = le32_to_cpu(xstats->total_sent_pkts);
-
- estats->t_rcv_unicast_bytes_hi =
- le32_to_cpu(tclient->rcv_unicast_bytes.hi);
- estats->t_rcv_unicast_bytes_lo =
- le32_to_cpu(tclient->rcv_unicast_bytes.lo);
- estats->t_rcv_broadcast_bytes_hi =
- le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
- estats->t_rcv_broadcast_bytes_lo =
- le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
- estats->t_rcv_multicast_bytes_hi =
- le32_to_cpu(tclient->rcv_multicast_bytes.hi);
- estats->t_rcv_multicast_bytes_lo =
- le32_to_cpu(tclient->rcv_multicast_bytes.lo);
- estats->t_total_rcv_pkt = le32_to_cpu(tclient->total_rcv_pkts);
-
- estats->checksum_discard = le32_to_cpu(tclient->checksum_discard);
- estats->packets_too_big_discard =
- le32_to_cpu(tclient->packets_too_big_discard);
- estats->jabber_packets_received = estats->packets_too_big_discard +
- estats->stat_Dot3statsFramesTooLong;
- estats->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
- estats->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
- estats->mac_discard = le32_to_cpu(tclient->mac_discard);
- estats->mac_filter_discard = le32_to_cpu(tstats->mac_filter_discard);
- estats->xxoverflow_discard = le32_to_cpu(tstats->xxoverflow_discard);
- estats->brb_truncate_discard =
- le32_to_cpu(tstats->brb_truncate_discard);
-
- estats->brb_discard += nstats->brb_discard - bp->old_brb_discard;
- bp->old_brb_discard = nstats->brb_discard;
-
- estats->brb_packet = nstats->brb_packet;
- estats->brb_truncate = nstats->brb_truncate;
- estats->flow_ctrl_discard = nstats->flow_ctrl_discard;
- estats->flow_ctrl_octets = nstats->flow_ctrl_octets;
- estats->flow_ctrl_packet = nstats->flow_ctrl_packet;
- estats->mng_discard = nstats->mng_discard;
- estats->mng_octet_inp = nstats->mng_octet_inp;
- estats->mng_octet_out = nstats->mng_octet_out;
- estats->mng_packet_inp = nstats->mng_packet_inp;
- estats->mng_packet_out = nstats->mng_packet_out;
- estats->pbf_octets = nstats->pbf_octets;
- estats->pbf_packet = nstats->pbf_packet;
- estats->safc_inp = nstats->safc_inp;
-
- xstats->done.hi = 0;
- tstats->done.hi = 0;
- nstats->done = 0;
-
- return 0;
-}
-
-static void bnx2x_update_net_stats(struct bnx2x *bp)
-{
- struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
- struct net_device_stats *nstats = &bp->dev->stats;
-
- nstats->rx_packets =
- bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
- bnx2x_hilo(&estats->total_multicast_packets_received_hi) +
- bnx2x_hilo(&estats->total_broadcast_packets_received_hi);
-
- nstats->tx_packets =
- bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) +
- bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
- bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
-
- nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
-
- nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
-
- nstats->rx_dropped = estats->checksum_discard + estats->mac_discard;
- nstats->tx_dropped = 0;
-
- nstats->multicast =
- bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
-
- nstats->collisions = estats->single_collision_transmit_frames +
- estats->multiple_collision_transmit_frames +
- estats->late_collision_frames +
- estats->excessive_collision_frames;
-
- nstats->rx_length_errors = estats->runt_packets_received +
- estats->jabber_packets_received;
- nstats->rx_over_errors = estats->brb_discard +
- estats->brb_truncate_discard;
- nstats->rx_crc_errors = estats->crc_receive_errors;
- nstats->rx_frame_errors = estats->alignment_errors;
- nstats->rx_fifo_errors = estats->no_buff_discard;
- nstats->rx_missed_errors = estats->xxoverflow_discard;
-
- nstats->rx_errors = nstats->rx_length_errors +
- nstats->rx_over_errors +
- nstats->rx_crc_errors +
- nstats->rx_frame_errors +
- nstats->rx_fifo_errors +
- nstats->rx_missed_errors;
-
- nstats->tx_aborted_errors = estats->late_collision_frames +
- estats->excessive_collision_frames;
- nstats->tx_carrier_errors = estats->false_carrier_detections;
- nstats->tx_fifo_errors = 0;
- nstats->tx_heartbeat_errors = 0;
- nstats->tx_window_errors = 0;
-
- nstats->tx_errors = nstats->tx_aborted_errors +
- nstats->tx_carrier_errors;
-
- estats->mac_stx_start = ++estats->mac_stx_end;
-}
-
-static void bnx2x_update_stats(struct bnx2x *bp)
-{
- int i;
-
- if (!bnx2x_update_storm_stats(bp)) {
-
- if (bp->phy_flags & PHY_BMAC_FLAG) {
- bnx2x_update_bmac_stats(bp);
-
- } else if (bp->phy_flags & PHY_EMAC_FLAG) {
- bnx2x_update_emac_stats(bp);
-
- } else { /* unreached */
- BNX2X_ERR("no MAC active\n");
- return;
- }
-
- bnx2x_update_net_stats(bp);
- }
-
- if (bp->msglevel & NETIF_MSG_TIMER) {
- struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
- struct net_device_stats *nstats = &bp->dev->stats;
-
- printk(KERN_DEBUG "%s:\n", bp->dev->name);
- printk(KERN_DEBUG " tx avail (%4x) tx hc idx (%x)"
- " tx pkt (%lx)\n",
- bnx2x_tx_avail(bp->fp),
- *bp->fp->tx_cons_sb, nstats->tx_packets);
- printk(KERN_DEBUG " rx usage (%4x) rx hc idx (%x)"
- " rx pkt (%lx)\n",
- (u16)(*bp->fp->rx_cons_sb - bp->fp->rx_comp_cons),
- *bp->fp->rx_cons_sb, nstats->rx_packets);
- printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
- netif_queue_stopped(bp->dev)? "Xoff" : "Xon",
- estats->driver_xoff, estats->brb_discard);
- printk(KERN_DEBUG "tstats: checksum_discard %u "
- "packets_too_big_discard %u no_buff_discard %u "
- "mac_discard %u mac_filter_discard %u "
- "xxovrflow_discard %u brb_truncate_discard %u "
- "ttl0_discard %u\n",
- estats->checksum_discard,
- estats->packets_too_big_discard,
- estats->no_buff_discard, estats->mac_discard,
- estats->mac_filter_discard, estats->xxoverflow_discard,
- estats->brb_truncate_discard, estats->ttl0_discard);
-
- for_each_queue(bp, i) {
- printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
- bnx2x_fp(bp, i, tx_pkt),
- bnx2x_fp(bp, i, rx_pkt),
- bnx2x_fp(bp, i, rx_calls));
- }
- }
-
- if (bp->state != BNX2X_STATE_OPEN) {
- DP(BNX2X_MSG_STATS, "state is %x, returning\n", bp->state);
- return;
- }
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return;
-#endif
-
- /* loader */
- if (bp->executer_idx) {
- struct dmae_command *dmae = &bp->dmae;
- int port = bp->port;
- int loader_idx = port * 8;
-
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
- dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
- sizeof(struct dmae_command) *
- (loader_idx + 1)) >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct dmae_command) >> 2;
- dmae->len--; /* !!! for A0/1 only */
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- bnx2x_post_dmae(bp, dmae, loader_idx);
- }
-
- if (bp->stats_state != STATS_STATE_ENABLE) {
- bp->stats_state = STATS_STATE_DISABLE;
- return;
- }
-
- if (bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, 0, 0, 0) == 0) {
- /* stats ramrod has it's own slot on the spe */
- bp->spq_left++;
- bp->stat_pending = 1;
- }
-}
-
-static void bnx2x_timer(unsigned long data)
-{
- struct bnx2x *bp = (struct bnx2x *) data;
-
- if (!netif_running(bp->dev))
- return;
-
- if (atomic_read(&bp->intr_sem) != 0)
- goto timer_restart;
-
- if (poll) {
- struct bnx2x_fastpath *fp = &bp->fp[0];
- int rc;
-
- bnx2x_tx_int(fp, 1000);
- rc = bnx2x_rx_int(fp, 1000);
- }
-
- if (!nomcp) {
- int port = bp->port;
- u32 drv_pulse;
- u32 mcp_pulse;
-
- ++bp->fw_drv_pulse_wr_seq;
- bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
- /* TBD - add SYSTEM_TIME */
- drv_pulse = bp->fw_drv_pulse_wr_seq;
- SHMEM_WR(bp, func_mb[port].drv_pulse_mb, drv_pulse);
-
- mcp_pulse = (SHMEM_RD(bp, func_mb[port].mcp_pulse_mb) &
- MCP_PULSE_SEQ_MASK);
- /* The delta between driver pulse and mcp response
- * should be 1 (before mcp response) or 0 (after mcp response)
- */
- if ((drv_pulse != mcp_pulse) &&
- (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) {
- /* someone lost a heartbeat... */
- BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n",
- drv_pulse, mcp_pulse);
- }
- }
-
- if (bp->stats_state == STATS_STATE_DISABLE)
- goto timer_restart;
-
- bnx2x_update_stats(bp);
-
-timer_restart:
- mod_timer(&bp->timer, jiffies + bp->current_interval);
-}
-
-/* end of Statistics */
-
-/* nic init */
-
-/*
- * nic init service functions
- */
-
-static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
- dma_addr_t mapping, int id)
-{
- int port = bp->port;
- u64 section;
- int index;
-
- /* USTORM */
- section = ((u64)mapping) + offsetof(struct host_status_block,
- u_status_block);
- sb->u_status_block.status_block_id = id;
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HOST_SB_ADDR_OFFSET(port, id), U64_LO(section));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, id)) + 4),
- U64_HI(section));
-
- for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, id, index), 0x1);
-
- /* CSTORM */
- section = ((u64)mapping) + offsetof(struct host_status_block,
- c_status_block);
- sb->c_status_block.status_block_id = id;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_SB_ADDR_OFFSET(port, id), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_SB_HOST_SB_ADDR_OFFSET(port, id)) + 4),
- U64_HI(section));
-
- for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_OFFSET(port, id, index), 0x1);
-
- bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-}
-
-static void bnx2x_init_def_sb(struct bnx2x *bp,
- struct host_def_status_block *def_sb,
- dma_addr_t mapping, int id)
-{
- int port = bp->port;
- int index, val, reg_offset;
- u64 section;
-
- /* ATTN */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- atten_status_block);
- def_sb->atten_status_block.status_block_id = id;
-
- bp->def_att_idx = 0;
- bp->attn_state = 0;
-
- reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
- MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
-
- for (index = 0; index < 3; index++) {
- bp->attn_group[index].sig[0] = REG_RD(bp,
- reg_offset + 0x10*index);
- bp->attn_group[index].sig[1] = REG_RD(bp,
- reg_offset + 0x4 + 0x10*index);
- bp->attn_group[index].sig[2] = REG_RD(bp,
- reg_offset + 0x8 + 0x10*index);
- bp->attn_group[index].sig[3] = REG_RD(bp,
- reg_offset + 0xc + 0x10*index);
- }
-
- bp->aeu_mask = REG_RD(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
- MISC_REG_AEU_MASK_ATTN_FUNC_0));
-
- reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
- HC_REG_ATTN_MSG0_ADDR_L);
-
- REG_WR(bp, reg_offset, U64_LO(section));
- REG_WR(bp, reg_offset + 4, U64_HI(section));
-
- reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0);
-
- val = REG_RD(bp, reg_offset);
- val |= id;
- REG_WR(bp, reg_offset, val);
-
- /* USTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- u_def_status_block);
- def_sb->u_def_status_block.status_block_id = id;
-
- bp->def_u_idx = 0;
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
- U64_HI(section));
- REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(port),
- BNX2X_BTR);
-
- for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
-
- /* CSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- c_def_status_block);
- def_sb->c_def_status_block.status_block_id = id;
-
- bp->def_c_idx = 0;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
- U64_HI(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(port),
- BNX2X_BTR);
-
- for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
-
- /* TSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- t_def_status_block);
- def_sb->t_def_status_block.status_block_id = id;
-
- bp->def_t_idx = 0;
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
- U64_HI(section));
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port),
- BNX2X_BTR);
-
- for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
-
- /* XSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- x_def_status_block);
- def_sb->x_def_status_block.status_block_id = id;
-
- bp->def_x_idx = 0;
-
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
- U64_HI(section));
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port),
- BNX2X_BTR);
-
- for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
-
- bp->stat_pending = 0;
-
- bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-}
-
-static void bnx2x_update_coalesce(struct bnx2x *bp)
-{
- int port = bp->port;
- int i;
-
- for_each_queue(bp, i) {
-
- /* HC_INDEX_U_ETH_RX_CQ_CONS */
- REG_WR8(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_TIMEOUT_OFFSET(port, i,
- HC_INDEX_U_ETH_RX_CQ_CONS),
- bp->rx_ticks_int/12);
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, i,
- HC_INDEX_U_ETH_RX_CQ_CONS),
- bp->rx_ticks_int ? 0 : 1);
-
- /* HC_INDEX_C_ETH_TX_CQ_CONS */
- REG_WR8(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_TIMEOUT_OFFSET(port, i,
- HC_INDEX_C_ETH_TX_CQ_CONS),
- bp->tx_ticks_int/12);
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_OFFSET(port, i,
- HC_INDEX_C_ETH_TX_CQ_CONS),
- bp->tx_ticks_int ? 0 : 1);
- }
-}
-
-static void bnx2x_init_rx_rings(struct bnx2x *bp)
-{
- u16 ring_prod;
- int i, j;
- int port = bp->port;
-
- bp->rx_buf_use_size = bp->dev->mtu;
-
- bp->rx_buf_use_size += bp->rx_offset + ETH_OVREHEAD;
- bp->rx_buf_size = bp->rx_buf_use_size + 64;
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- fp->rx_bd_cons = 0;
- fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
-
- for (i = 1; i <= NUM_RX_RINGS; i++) {
- struct eth_rx_bd *rx_bd;
-
- rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
- rx_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
- rx_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
-
- }
-
- for (i = 1; i <= NUM_RCQ_RINGS; i++) {
- struct eth_rx_cqe_next_page *nextpg;
-
- nextpg = (struct eth_rx_cqe_next_page *)
- &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
- nextpg->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_comp_mapping +
- BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
- nextpg->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_comp_mapping +
- BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
- }
-
- /* rx completion queue */
- fp->rx_comp_cons = ring_prod = 0;
-
- for (i = 0; i < bp->rx_ring_size; i++) {
- if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx skbs\n", i);
- break;
- }
- ring_prod = NEXT_RX_IDX(ring_prod);
- BUG_TRAP(ring_prod > i);
- }
-
- fp->rx_bd_prod = fp->rx_comp_prod = ring_prod;
- fp->rx_pkt = fp->rx_calls = 0;
-
- /* Warning! this will generate an interrupt (to the TSTORM) */
- /* must only be done when chip is initialized */
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod);
- if (j != 0)
- continue;
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port),
- U64_LO(fp->rx_comp_mapping));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port) + 4,
- U64_HI(fp->rx_comp_mapping));
- }
-}
-
-static void bnx2x_init_tx_ring(struct bnx2x *bp)
-{
- int i, j;
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- for (i = 1; i <= NUM_TX_RINGS; i++) {
- struct eth_tx_bd *tx_bd =
- &fp->tx_desc_ring[TX_DESC_CNT * i - 1];
-
- tx_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- tx_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- }
-
- fp->tx_pkt_prod = 0;
- fp->tx_pkt_cons = 0;
- fp->tx_bd_prod = 0;
- fp->tx_bd_cons = 0;
- fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
- fp->tx_pkt = 0;
- }
-}
-
-static void bnx2x_init_sp_ring(struct bnx2x *bp)
-{
- int port = bp->port;
-
- spin_lock_init(&bp->spq_lock);
-
- bp->spq_left = MAX_SPQ_PENDING;
- bp->spq_prod_idx = 0;
- bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
- bp->spq_prod_bd = bp->spq;
- bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PAGE_BASE_OFFSET(port),
- U64_LO(bp->spq_mapping));
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PAGE_BASE_OFFSET(port) + 4,
- U64_HI(bp->spq_mapping));
-
- REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(port),
- bp->spq_prod_idx);
-}
-
-static void bnx2x_init_context(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i) {
- struct eth_context *context = bnx2x_sp(bp, context[i].eth);
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- context->xstorm_st_context.tx_bd_page_base_hi =
- U64_HI(fp->tx_desc_mapping);
- context->xstorm_st_context.tx_bd_page_base_lo =
- U64_LO(fp->tx_desc_mapping);
- context->xstorm_st_context.db_data_addr_hi =
- U64_HI(fp->tx_prods_mapping);
- context->xstorm_st_context.db_data_addr_lo =
- U64_LO(fp->tx_prods_mapping);
-
- context->ustorm_st_context.rx_bd_page_base_hi =
- U64_HI(fp->rx_desc_mapping);
- context->ustorm_st_context.rx_bd_page_base_lo =
- U64_LO(fp->rx_desc_mapping);
- context->ustorm_st_context.status_block_id = i;
- context->ustorm_st_context.sb_index_number =
- HC_INDEX_U_ETH_RX_CQ_CONS;
- context->ustorm_st_context.rcq_base_address_hi =
- U64_HI(fp->rx_comp_mapping);
- context->ustorm_st_context.rcq_base_address_lo =
- U64_LO(fp->rx_comp_mapping);
- context->ustorm_st_context.flags =
- USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT;
- context->ustorm_st_context.mc_alignment_size = 64;
- context->ustorm_st_context.num_rss = bp->num_queues;
-
- context->cstorm_st_context.sb_index_number =
- HC_INDEX_C_ETH_TX_CQ_CONS;
- context->cstorm_st_context.status_block_id = i;
-
- context->xstorm_ag_context.cdu_reserved =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_XCM_AG,
- ETH_CONNECTION_TYPE);
- context->ustorm_ag_context.cdu_usage =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_UCM_AG,
- ETH_CONNECTION_TYPE);
- }
-}
-
-static void bnx2x_init_ind_table(struct bnx2x *bp)
-{
- int port = bp->port;
- int i;
-
- if (!is_multi(bp))
- return;
-
- for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
- REG_WR8(bp, TSTORM_INDIRECTION_TABLE_OFFSET(port) + i,
- i % bp->num_queues);
-
- REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
-}
-
-static void bnx2x_set_client_config(struct bnx2x *bp)
-{
-#ifdef BCM_VLAN
- int mode = bp->rx_mode;
-#endif
- int i, port = bp->port;
- struct tstorm_eth_client_config tstorm_client = {0};
-
- tstorm_client.mtu = bp->dev->mtu;
- tstorm_client.statistics_counter_id = 0;
- tstorm_client.config_flags =
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
-#ifdef BCM_VLAN
- if (mode && bp->vlgrp) {
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
- DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
- }
-#endif
- if (mode != BNX2X_RX_MODE_PROMISC)
- tstorm_client.drop_flags =
- TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR;
-
- for_each_queue(bp, i) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, i),
- ((u32 *)&tstorm_client)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, i) + 4,
- ((u32 *)&tstorm_client)[1]);
- }
-
-/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
- ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
-}
-
-static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
-{
- int mode = bp->rx_mode;
- int port = bp->port;
- struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0};
- int i;
-
- DP(NETIF_MSG_RX_STATUS, "rx mode is %d\n", mode);
-
- switch (mode) {
- case BNX2X_RX_MODE_NONE: /* no Rx */
- tstorm_mac_filter.ucast_drop_all = 1;
- tstorm_mac_filter.mcast_drop_all = 1;
- tstorm_mac_filter.bcast_drop_all = 1;
- break;
- case BNX2X_RX_MODE_NORMAL:
- tstorm_mac_filter.bcast_accept_all = 1;
- break;
- case BNX2X_RX_MODE_ALLMULTI:
- tstorm_mac_filter.mcast_accept_all = 1;
- tstorm_mac_filter.bcast_accept_all = 1;
- break;
- case BNX2X_RX_MODE_PROMISC:
- tstorm_mac_filter.ucast_accept_all = 1;
- tstorm_mac_filter.mcast_accept_all = 1;
- tstorm_mac_filter.bcast_accept_all = 1;
- break;
- default:
- BNX2X_ERR("bad rx mode (%d)\n", mode);
- }
-
- for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_MAC_FILTER_CONFIG_OFFSET(port) + i * 4,
- ((u32 *)&tstorm_mac_filter)[i]);
-
-/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
- ((u32 *)&tstorm_mac_filter)[i]); */
- }
-
- if (mode != BNX2X_RX_MODE_NONE)
- bnx2x_set_client_config(bp);
-}
-
-static void bnx2x_init_internal(struct bnx2x *bp)
-{
- int port = bp->port;
- struct tstorm_eth_function_common_config tstorm_config = {0};
- struct stats_indication_flags stats_flags = {0};
-
- if (is_multi(bp)) {
- tstorm_config.config_flags = MULTI_FLAGS;
- tstorm_config.rss_result_mask = MULTI_MASK;
- }
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(port),
- (*(u32 *)&tstorm_config));
-
-/* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
- (*(u32 *)&tstorm_config)); */
-
- bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
- bnx2x_set_storm_rx_mode(bp);
-
- stats_flags.collect_eth = cpu_to_le32(1);
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port) + 4,
- ((u32 *)&stats_flags)[1]);
-
-/* DP(NETIF_MSG_IFUP, "stats_flags: 0x%08x 0x%08x\n",
- ((u32 *)&stats_flags)[0], ((u32 *)&stats_flags)[1]); */
-}
-
-static void bnx2x_nic_init(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- fp->state = BNX2X_FP_STATE_CLOSED;
- DP(NETIF_MSG_IFUP, "bnx2x_init_sb(%p,%p,%d);\n",
- bp, fp->status_blk, i);
- fp->index = i;
- bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, i);
- }
-
- bnx2x_init_def_sb(bp, bp->def_status_blk,
- bp->def_status_blk_mapping, 0x10);
- bnx2x_update_coalesce(bp);
- bnx2x_init_rx_rings(bp);
- bnx2x_init_tx_ring(bp);
- bnx2x_init_sp_ring(bp);
- bnx2x_init_context(bp);
- bnx2x_init_internal(bp);
- bnx2x_init_stats(bp);
- bnx2x_init_ind_table(bp);
- bnx2x_int_enable(bp);
-
-}
-
-/* end of nic init */
-
-/*
- * gzip service functions
- */
-
-static int bnx2x_gunzip_init(struct bnx2x *bp)
-{
- bp->gunzip_buf = pci_alloc_consistent(bp->pdev, FW_BUF_SIZE,
- &bp->gunzip_mapping);
- if (bp->gunzip_buf == NULL)
- goto gunzip_nomem1;
-
- bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL);
- if (bp->strm == NULL)
- goto gunzip_nomem2;
-
- bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
- GFP_KERNEL);
- if (bp->strm->workspace == NULL)
- goto gunzip_nomem3;
-
- return 0;
-
-gunzip_nomem3:
- kfree(bp->strm);
- bp->strm = NULL;
-
-gunzip_nomem2:
- pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
- bp->gunzip_mapping);
- bp->gunzip_buf = NULL;
-
-gunzip_nomem1:
- printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for"
- " uncompression\n", bp->dev->name);
- return -ENOMEM;
-}
-
-static void bnx2x_gunzip_end(struct bnx2x *bp)
-{
- kfree(bp->strm->workspace);
-
- kfree(bp->strm);
- bp->strm = NULL;
-
- if (bp->gunzip_buf) {
- pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
- bp->gunzip_mapping);
- bp->gunzip_buf = NULL;
- }
-}
-
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
-{
- int n, rc;
-
- /* check gzip header */
- if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
- return -EINVAL;
-
- n = 10;
-
-#define FNAME 0x8
-
- if (zbuf[3] & FNAME)
- while ((zbuf[n++] != 0) && (n < len));
-
- bp->strm->next_in = zbuf + n;
- bp->strm->avail_in = len - n;
- bp->strm->next_out = bp->gunzip_buf;
- bp->strm->avail_out = FW_BUF_SIZE;
-
- rc = zlib_inflateInit2(bp->strm, -MAX_WBITS);
- if (rc != Z_OK)
- return rc;
-
- rc = zlib_inflate(bp->strm, Z_FINISH);
- if ((rc != Z_OK) && (rc != Z_STREAM_END))
- printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n",
- bp->dev->name, bp->strm->msg);
-
- bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out);
- if (bp->gunzip_outlen & 0x3)
- printk(KERN_ERR PFX "%s: Firmware decompression error:"
- " gunzip_outlen (%d) not aligned\n",
- bp->dev->name, bp->gunzip_outlen);
- bp->gunzip_outlen >>= 2;
-
- zlib_inflateEnd(bp->strm);
-
- if (rc == Z_STREAM_END)
- return 0;
-
- return rc;
-}
-
-/* nic load/unload */
-
-/*
- * general service functions
- */
-
-/* send a NIG loopback debug packet */
-static void bnx2x_lb_pckt(struct bnx2x *bp)
-{
-#ifdef USE_DMAE
- u32 wb_write[3];
-#endif
-
- /* Ethernet source and destination addresses */
-#ifdef USE_DMAE
- wb_write[0] = 0x55555555;
- wb_write[1] = 0x55555555;
- wb_write[2] = 0x20; /* SOP */
- REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
-#else
- REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB, 0x55555555);
- REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 4, 0x55555555);
- /* SOP */
- REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 8, 0x20);
-#endif
-
- /* NON-IP protocol */
-#ifdef USE_DMAE
- wb_write[0] = 0x09000000;
- wb_write[1] = 0x55555555;
- wb_write[2] = 0x10; /* EOP, eop_bvalid = 0 */
- REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
-#else
- REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB, 0x09000000);
- REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 4, 0x55555555);
- /* EOP, eop_bvalid = 0 */
- REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 8, 0x10);
-#endif
-}
-
-/* some of the internal memories
- * are not directly readable from the driver
- * to test them we send debug packets
- */
-static int bnx2x_int_mem_test(struct bnx2x *bp)
-{
- int factor;
- int count, i;
- u32 val = 0;
-
- switch (CHIP_REV(bp)) {
- case CHIP_REV_EMUL:
- factor = 200;
- break;
- case CHIP_REV_FPGA:
- factor = 120;
- break;
- default:
- factor = 1;
- break;
- }
-
- DP(NETIF_MSG_HW, "start part1\n");
-
- /* Disable inputs of parser neighbor blocks */
- REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
- REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
- REG_WR(bp, CFC_REG_DEBUG0, 0x1);
- NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0);
-
- /* Write 0 to parser credits for CFC search request */
- REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
-
- /* send Ethernet packet */
- bnx2x_lb_pckt(bp);
-
- /* TODO do i reset NIG statistic? */
- /* Wait until NIG register shows 1 packet of size 0x10 */
- count = 1000 * factor;
- while (count) {
-#ifdef BNX2X_DMAE_RD
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
-#else
- val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET);
- REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4);
-#endif
- if (val == 0x10)
- break;
-
- msleep(10);
- count--;
- }
- if (val != 0x10) {
- BNX2X_ERR("NIG timeout val = 0x%x\n", val);
- return -1;
- }
-
- /* Wait until PRS register shows 1 packet */
- count = 1000 * factor;
- while (count) {
- val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
-
- if (val == 1)
- break;
-
- msleep(10);
- count--;
- }
- if (val != 0x1) {
- BNX2X_ERR("PRS timeout val = 0x%x\n", val);
- return -2;
- }
-
- /* Reset and init BRB, PRS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x3);
- msleep(50);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x3);
- msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
-
- DP(NETIF_MSG_HW, "part2\n");
-
- /* Disable inputs of parser neighbor blocks */
- REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
- REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
- REG_WR(bp, CFC_REG_DEBUG0, 0x1);
- NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0);
-
- /* Write 0 to parser credits for CFC search request */
- REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
-
- /* send 10 Ethernet packets */
- for (i = 0; i < 10; i++)
- bnx2x_lb_pckt(bp);
-
- /* Wait until NIG register shows 10 + 1
- packets of size 11*0x10 = 0xb0 */
- count = 1000 * factor;
- while (count) {
-#ifdef BNX2X_DMAE_RD
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
-#else
- val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET);
- REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4);
-#endif
- if (val == 0xb0)
- break;
-
- msleep(10);
- count--;
- }
- if (val != 0xb0) {
- BNX2X_ERR("NIG timeout val = 0x%x\n", val);
- return -3;
- }
-
- /* Wait until PRS register shows 2 packets */
- val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
- if (val != 2)
- BNX2X_ERR("PRS timeout val = 0x%x\n", val);
-
- /* Write 1 to parser credits for CFC search request */
- REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1);
-
- /* Wait until PRS register shows 3 packets */
- msleep(10 * factor);
- /* Wait until NIG register shows 1 packet of size 0x10 */
- val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
- if (val != 3)
- BNX2X_ERR("PRS timeout val = 0x%x\n", val);
-
- /* clear NIG EOP FIFO */
- for (i = 0; i < 11; i++)
- REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO);
- val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY);
- if (val != 1) {
- BNX2X_ERR("clear of NIG failed\n");
- return -4;
- }
-
- /* Reset and init BRB, PRS, NIG */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03);
- msleep(50);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
- msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
-#ifndef BCM_ISCSI
- /* set NIC mode */
- REG_WR(bp, PRS_REG_NIC_MODE, 1);
-#endif
-
- /* Enable inputs of parser neighbor blocks */
- REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff);
- REG_WR(bp, TCM_REG_PRS_IFEN, 0x1);
- REG_WR(bp, CFC_REG_DEBUG0, 0x0);
- NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x1);
-
- DP(NETIF_MSG_HW, "done\n");
-
- return 0; /* OK */
-}
-
-static void enable_blocks_attention(struct bnx2x *bp)
-{
- REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
- REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0);
- REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
- REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
- REG_WR(bp, QM_REG_QM_INT_MASK, 0);
- REG_WR(bp, TM_REG_TM_INT_MASK, 0);
- REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0);
- REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0);
- REG_WR(bp, XCM_REG_XCM_INT_MASK, 0);
-/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */
-/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */
- REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0);
- REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0);
- REG_WR(bp, UCM_REG_UCM_INT_MASK, 0);
-/* REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */
-/* REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */
- REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0);
- REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0);
- REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0);
- REG_WR(bp, CCM_REG_CCM_INT_MASK, 0);
-/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */
-/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */
- REG_WR(bp, PXP2_REG_PXP2_INT_MASK, 0x480000);
- REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0);
- REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0);
- REG_WR(bp, TCM_REG_TCM_INT_MASK, 0);
-/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */
-/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */
- REG_WR(bp, CDU_REG_CDU_INT_MASK, 0);
- REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0);
-/* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */
- REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */
-}
-
-static int bnx2x_function_init(struct bnx2x *bp, int mode)
-{
- int func = bp->port;
- int port = func ? PORT1 : PORT0;
- u32 val, i;
-#ifdef USE_DMAE
- u32 wb_write[2];
-#endif
-
- DP(BNX2X_MSG_MCP, "function is %d mode is %x\n", func, mode);
- if ((func != 0) && (func != 1)) {
- BNX2X_ERR("BAD function number (%d)\n", func);
- return -ENODEV;
- }
-
- bnx2x_gunzip_init(bp);
-
- if (mode & 0x1) { /* init common */
- DP(BNX2X_MSG_MCP, "starting common init func %d mode %x\n",
- func, mode);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
- 0xffffffff);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- 0xfffc);
- bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
-
- REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
- msleep(30);
- REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
-
- bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
- bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
-
- bnx2x_init_pxp(bp);
-
- if (CHIP_REV(bp) == CHIP_REV_Ax) {
- /* enable HW interrupt from PXP on USDM
- overflow bit 16 on INT_MASK_0 */
- REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
- }
-
-#ifdef __BIG_ENDIAN
- REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1);
-
-/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
- REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
- REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1);
- REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1);
- REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
-#endif
-
-#ifndef BCM_ISCSI
- /* set NIC mode */
- REG_WR(bp, PRS_REG_NIC_MODE, 1);
-#endif
-
- REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 5);
-#ifdef BCM_ISCSI
- REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
- REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5);
- REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5);
-#endif
-
- bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
-
- /* let the HW do it's magic ... */
- msleep(100);
- /* finish PXP init
- (can be moved up if we want to use the DMAE) */
- val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE);
- if (val != 1) {
- BNX2X_ERR("PXP2 CFG failed\n");
- return -EBUSY;
- }
-
- val = REG_RD(bp, PXP2_REG_RD_INIT_DONE);
- if (val != 1) {
- BNX2X_ERR("PXP2 RD_INIT failed\n");
- return -EBUSY;
- }
-
- REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
- REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
-
- bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
-
- bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
- bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
- bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
- bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
-
-#ifdef BNX2X_DMAE_RD
- bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
-#else
- REG_RD(bp, XSEM_REG_PASSIVE_BUFFER);
- REG_RD(bp, XSEM_REG_PASSIVE_BUFFER + 4);
- REG_RD(bp, XSEM_REG_PASSIVE_BUFFER + 8);
- REG_RD(bp, CSEM_REG_PASSIVE_BUFFER);
- REG_RD(bp, CSEM_REG_PASSIVE_BUFFER + 4);
- REG_RD(bp, CSEM_REG_PASSIVE_BUFFER + 8);
- REG_RD(bp, TSEM_REG_PASSIVE_BUFFER);
- REG_RD(bp, TSEM_REG_PASSIVE_BUFFER + 4);
- REG_RD(bp, TSEM_REG_PASSIVE_BUFFER + 8);
- REG_RD(bp, USEM_REG_PASSIVE_BUFFER);
- REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 4);
- REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8);
-#endif
- bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
- /* soft reset pulse */
- REG_WR(bp, QM_REG_SOFT_RESET, 1);
- REG_WR(bp, QM_REG_SOFT_RESET, 0);
-
-#ifdef BCM_ISCSI
- bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
-#endif
- bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
- REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_BITS);
- if (CHIP_REV(bp) == CHIP_REV_Ax) {
- /* enable hw interrupt from doorbell Q */
- REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
- }
-
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
-
- if (CHIP_REV_IS_SLOW(bp)) {
- /* fix for emulation and FPGA for no pause */
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
- }
-
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
-
- bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
- bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
- bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
- bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
-
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
-
- bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
- bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
- bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
- bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
-
- /* sync semi rtc */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0x80000000);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
- 0x80000000);
-
- bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
- bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
- bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
-
- REG_WR(bp, SRC_REG_SOFT_RST, 1);
- for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
- REG_WR(bp, i, 0xc0cac01a);
- /* TODO: replace with something meaningful */
- }
- /* SRCH COMMON comes here */
- REG_WR(bp, SRC_REG_SOFT_RST, 0);
-
- if (sizeof(union cdu_context) != 1024) {
- /* we currently assume that a context is 1024 bytes */
- printk(KERN_ALERT PFX "please adjust the size of"
- " cdu_context(%ld)\n",
- (long)sizeof(union cdu_context));
- }
- val = (4 << 24) + (0 << 12) + 1024;
- REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
- bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
-
- bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
- REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
-
- bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
- bnx2x_init_block(bp, MISC_AEU_COMMON_START,
- MISC_AEU_COMMON_END);
- /* RXPCS COMMON comes here */
- /* EMAC0 COMMON comes here */
- /* EMAC1 COMMON comes here */
- /* DBU COMMON comes here */
- /* DBG COMMON comes here */
- bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
-
- if (CHIP_REV_IS_SLOW(bp))
- msleep(200);
-
- /* finish CFC init */
- val = REG_RD(bp, CFC_REG_LL_INIT_DONE);
- if (val != 1) {
- BNX2X_ERR("CFC LL_INIT failed\n");
- return -EBUSY;
- }
-
- val = REG_RD(bp, CFC_REG_AC_INIT_DONE);
- if (val != 1) {
- BNX2X_ERR("CFC AC_INIT failed\n");
- return -EBUSY;
- }
-
- val = REG_RD(bp, CFC_REG_CAM_INIT_DONE);
- if (val != 1) {
- BNX2X_ERR("CFC CAM_INIT failed\n");
- return -EBUSY;
- }
-
- REG_WR(bp, CFC_REG_DEBUG0, 0);
-
- /* read NIG statistic
- to see if this is our first up since powerup */
-#ifdef BNX2X_DMAE_RD
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
-#else
- val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET);
- REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4);
-#endif
- /* do internal memory self test */
- if ((val == 0) && bnx2x_int_mem_test(bp)) {
- BNX2X_ERR("internal mem selftest failed\n");
- return -EBUSY;
- }
-
- /* clear PXP2 attentions */
- REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR);
-
- enable_blocks_attention(bp);
- /* enable_blocks_parity(bp); */
-
- switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
- /* Fan failure is indicated by SPIO 5 */
- bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
- MISC_REGISTERS_SPIO_INPUT_HI_Z);
-
- /* set to active low mode */
- val = REG_RD(bp, MISC_REG_SPIO_INT);
- val |= ((1 << MISC_REGISTERS_SPIO_5) <<
- MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
- REG_WR(bp, MISC_REG_SPIO_INT, val);
-
- /* enable interrupt to signal the IGU */
- val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
- val |= (1 << MISC_REGISTERS_SPIO_5);
- REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
- break;
-
- default:
- break;
- }
-
- } /* end of common init */
-
- /* per port init */
-
- /* the phys address is shifted right 12 bits and has an added
- 1=valid bit added to the 53rd bit
- then since this is a wide register(TM)
- we split it into two 32 bit writes
- */
-#define RQ_ONCHIP_AT_PORT_SIZE 384
-#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
-#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
-#define PXP_ONE_ILT(x) ((x << 10) | x)
-
- DP(BNX2X_MSG_MCP, "starting per-function init port is %x\n", func);
-
- REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + func*4, 0);
-
- /* Port PXP comes here */
- /* Port PXP2 comes here */
-
- /* Offset is
- * Port0 0
- * Port1 384 */
- i = func * RQ_ONCHIP_AT_PORT_SIZE;
-#ifdef USE_DMAE
- wb_write[0] = ONCHIP_ADDR1(bnx2x_sp_mapping(bp, context));
- wb_write[1] = ONCHIP_ADDR2(bnx2x_sp_mapping(bp, context));
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
-#else
- REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + i*8,
- ONCHIP_ADDR1(bnx2x_sp_mapping(bp, context)));
- REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + i*8 + 4,
- ONCHIP_ADDR2(bnx2x_sp_mapping(bp, context)));
-#endif
- REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, PXP_ONE_ILT(i));
-
-#ifdef BCM_ISCSI
- /* Port0 1
- * Port1 385 */
- i++;
- wb_write[0] = ONCHIP_ADDR1(bp->timers_mapping);
- wb_write[1] = ONCHIP_ADDR2(bp->timers_mapping);
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
- REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
-
- /* Port0 2
- * Port1 386 */
- i++;
- wb_write[0] = ONCHIP_ADDR1(bp->qm_mapping);
- wb_write[1] = ONCHIP_ADDR2(bp->qm_mapping);
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
- REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
-
- /* Port0 3
- * Port1 387 */
- i++;
- wb_write[0] = ONCHIP_ADDR1(bp->t1_mapping);
- wb_write[1] = ONCHIP_ADDR2(bp->t1_mapping);
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
- REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
-#endif
-
- /* Port TCM comes here */
- /* Port UCM comes here */
- /* Port CCM comes here */
- bnx2x_init_block(bp, func ? XCM_PORT1_START : XCM_PORT0_START,
- func ? XCM_PORT1_END : XCM_PORT0_END);
-
-#ifdef USE_DMAE
- wb_write[0] = 0;
- wb_write[1] = 0;
-#endif
- for (i = 0; i < 32; i++) {
- REG_WR(bp, QM_REG_BASEADDR + (func*32 + i)*4, 1024 * 4 * i);
-#ifdef USE_DMAE
- REG_WR_DMAE(bp, QM_REG_PTRTBL + (func*32 + i)*8, wb_write, 2);
-#else
- REG_WR_IND(bp, QM_REG_PTRTBL + (func*32 + i)*8, 0);
- REG_WR_IND(bp, QM_REG_PTRTBL + (func*32 + i)*8 + 4, 0);
-#endif
- }
- REG_WR(bp, QM_REG_CONNNUM_0 + func*4, 1024/16 - 1);
-
- /* Port QM comes here */
-
-#ifdef BCM_ISCSI
- REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
- REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
-
- bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
- func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
-#endif
- /* Port DQ comes here */
- /* Port BRB1 comes here */
- bnx2x_init_block(bp, func ? PRS_PORT1_START : PRS_PORT0_START,
- func ? PRS_PORT1_END : PRS_PORT0_END);
- /* Port TSDM comes here */
- /* Port CSDM comes here */
- /* Port USDM comes here */
- /* Port XSDM comes here */
- bnx2x_init_block(bp, func ? TSEM_PORT1_START : TSEM_PORT0_START,
- func ? TSEM_PORT1_END : TSEM_PORT0_END);
- bnx2x_init_block(bp, func ? USEM_PORT1_START : USEM_PORT0_START,
- func ? USEM_PORT1_END : USEM_PORT0_END);
- bnx2x_init_block(bp, func ? CSEM_PORT1_START : CSEM_PORT0_START,
- func ? CSEM_PORT1_END : CSEM_PORT0_END);
- bnx2x_init_block(bp, func ? XSEM_PORT1_START : XSEM_PORT0_START,
- func ? XSEM_PORT1_END : XSEM_PORT0_END);
- /* Port UPB comes here */
- /* Port XSDM comes here */
- bnx2x_init_block(bp, func ? PBF_PORT1_START : PBF_PORT0_START,
- func ? PBF_PORT1_END : PBF_PORT0_END);
-
- /* configure PBF to work without PAUSE mtu 9000 */
- REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + func*4, 0);
-
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + func*4, (9040/16));
- /* update init credit */
- REG_WR(bp, PBF_REG_P0_INIT_CRD + func*4, (9040/16) + 553 - 22);
-
- /* probe changes */
- REG_WR(bp, PBF_REG_INIT_P0 + func*4, 1);
- msleep(5);
- REG_WR(bp, PBF_REG_INIT_P0 + func*4, 0);
-
-#ifdef BCM_ISCSI
- /* tell the searcher where the T2 table is */
- REG_WR(bp, SRC_REG_COUNTFREE0 + func*4, 16*1024/64);
-
- wb_write[0] = U64_LO(bp->t2_mapping);
- wb_write[1] = U64_HI(bp->t2_mapping);
- REG_WR_DMAE(bp, SRC_REG_FIRSTFREE0 + func*4, wb_write, 2);
- wb_write[0] = U64_LO((u64)bp->t2_mapping + 16*1024 - 64);
- wb_write[1] = U64_HI((u64)bp->t2_mapping + 16*1024 - 64);
- REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2);
-
- REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10);
- /* Port SRCH comes here */
-#endif
- /* Port CDU comes here */
- /* Port CFC comes here */
- bnx2x_init_block(bp, func ? HC_PORT1_START : HC_PORT0_START,
- func ? HC_PORT1_END : HC_PORT0_END);
- bnx2x_init_block(bp, func ? MISC_AEU_PORT1_START :
- MISC_AEU_PORT0_START,
- func ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
- /* Port PXPCS comes here */
- /* Port EMAC0 comes here */
- /* Port EMAC1 comes here */
- /* Port DBU comes here */
- /* Port DBG comes here */
- bnx2x_init_block(bp, func ? NIG_PORT1_START : NIG_PORT0_START,
- func ? NIG_PORT1_END : NIG_PORT0_END);
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + func*4, 1);
- /* Port MCP comes here */
- /* Port DMAE comes here */
-
- switch (bp->board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
- /* add SPIO 5 to group 0 */
- val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
- val |= AEU_INPUTS_ATTN_BITS_SPIO5;
- REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
- break;
-
- default:
- break;
- }
-
- bnx2x_link_reset(bp);
-
- /* Reset PCIE errors for debug */
- REG_WR(bp, 0x2114, 0xffffffff);
- REG_WR(bp, 0x2120, 0xffffffff);
- REG_WR(bp, 0x2814, 0xffffffff);
-
- /* !!! move to init_values.h */
- REG_WR(bp, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
- REG_WR(bp, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
- REG_WR(bp, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
- REG_WR(bp, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
-
- REG_WR(bp, DBG_REG_PCI_REQ_CREDIT, 0x1);
- REG_WR(bp, TM_REG_PCIARB_CRDCNT_VAL, 0x1);
- REG_WR(bp, CDU_REG_CDU_DEBUG, 0x264);
- REG_WR(bp, CDU_REG_CDU_DEBUG, 0x0);
-
- bnx2x_gunzip_end(bp);
-
- if (!nomcp) {
- port = bp->port;
-
- bp->fw_drv_pulse_wr_seq =
- (SHMEM_RD(bp, func_mb[port].drv_pulse_mb) &
- DRV_PULSE_SEQ_MASK);
- bp->fw_mb = SHMEM_RD(bp, func_mb[port].fw_mb_param);
- DP(BNX2X_MSG_MCP, "drv_pulse 0x%x fw_mb 0x%x\n",
- bp->fw_drv_pulse_wr_seq, bp->fw_mb);
- } else {
- bp->fw_mb = 0;
- }
-
- return 0;
-}
-
-/* send the MCP a request, block until there is a reply */
-static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
-{
- int port = bp->port;
- u32 seq = ++bp->fw_seq;
- u32 rc = 0;
-
- SHMEM_WR(bp, func_mb[port].drv_mb_header, (command | seq));
- DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
-
- /* let the FW do it's magic ... */
- msleep(100); /* TBD */
-
- if (CHIP_REV_IS_SLOW(bp))
- msleep(900);
-
- rc = SHMEM_RD(bp, func_mb[port].fw_mb_header);
- DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
-
- /* is this a reply to our command? */
- if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
- rc &= FW_MSG_CODE_MASK;
-
- } else {
- /* FW BUG! */
- BNX2X_ERR("FW failed to respond!\n");
- bnx2x_fw_dump(bp);
- rc = 0;
- }
-
- return rc;
-}
-
-static void bnx2x_free_mem(struct bnx2x *bp)
-{
-
-#define BNX2X_PCI_FREE(x, y, size) \
- do { \
- if (x) { \
- pci_free_consistent(bp->pdev, size, x, y); \
- x = NULL; \
- y = 0; \
- } \
- } while (0)
-
-#define BNX2X_FREE(x) \
- do { \
- if (x) { \
- vfree(x); \
- x = NULL; \
- } \
- } while (0)
-
- int i;
-
- /* fastpath */
- for_each_queue(bp, i) {
-
- /* Status blocks */
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_status_block) +
- sizeof(struct eth_tx_db_data));
-
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
- bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
- BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
- bnx2x_fp(bp, i, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring),
- bnx2x_fp(bp, i, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
- }
-
- BNX2X_FREE(bp->fp);
-
- /* end of fastpath */
-
- BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
- (sizeof(struct host_def_status_block)));
-
- BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
- (sizeof(struct bnx2x_slowpath)));
-
-#ifdef BCM_ISCSI
- BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024);
- BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024);
- BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024);
- BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024);
-#endif
- BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, PAGE_SIZE);
-
-#undef BNX2X_PCI_FREE
-#undef BNX2X_KFREE
-}
-
-static int bnx2x_alloc_mem(struct bnx2x *bp)
-{
-
-#define BNX2X_PCI_ALLOC(x, y, size) \
- do { \
- x = pci_alloc_consistent(bp->pdev, size, y); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset(x, 0, size); \
- } while (0)
-
-#define BNX2X_ALLOC(x, size) \
- do { \
- x = vmalloc(size); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset(x, 0, size); \
- } while (0)
-
- int i;
-
- /* fastpath */
- BNX2X_ALLOC(bp->fp, sizeof(struct bnx2x_fastpath) * bp->num_queues);
-
- for_each_queue(bp, i) {
- bnx2x_fp(bp, i, bp) = bp;
-
- /* Status blocks */
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_status_block) +
- sizeof(struct eth_tx_db_data));
-
- bnx2x_fp(bp, i, hw_tx_prods) =
- (void *)(bnx2x_fp(bp, i, status_blk) + 1);
-
- bnx2x_fp(bp, i, tx_prods_mapping) =
- bnx2x_fp(bp, i, status_blk_mapping) +
- sizeof(struct host_status_block);
-
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
- sizeof(struct sw_tx_bd) * NUM_TX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
- &bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
- BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
- sizeof(struct sw_rx_bd) * NUM_RX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
- &bnx2x_fp(bp, i, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring),
- &bnx2x_fp(bp, i, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
-
- }
- /* end of fastpath */
-
- BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
- sizeof(struct host_def_status_block));
-
- BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
- sizeof(struct bnx2x_slowpath));
-
-#ifdef BCM_ISCSI
- BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024);
-
- /* Initialize T1 */
- for (i = 0; i < 64*1024; i += 64) {
- *(u64 *)((char *)bp->t1 + i + 56) = 0x0UL;
- *(u64 *)((char *)bp->t1 + i + 3) = 0x0UL;
- }
-
- /* allocate searcher T2 table
- we allocate 1/4 of alloc num for T2
- (which is not entered into the ILT) */
- BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024);
-
- /* Initialize T2 */
- for (i = 0; i < 16*1024; i += 64)
- * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
-
- /* now fixup the last line in the block to point to the next block */
- *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
-
- /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
- BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024);
-
- /* QM queues (128*MAX_CONN) */
- BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024);
-#endif
-
- /* Slow path ring */
- BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE);
-
- return 0;
-
-alloc_mem_err:
- bnx2x_free_mem(bp);
- return -ENOMEM;
-
-#undef BNX2X_PCI_ALLOC
-#undef BNX2X_ALLOC
-}
-
-static void bnx2x_free_tx_skbs(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- u16 bd_cons = fp->tx_bd_cons;
- u16 sw_prod = fp->tx_pkt_prod;
- u16 sw_cons = fp->tx_pkt_cons;
-
- BUG_TRAP(fp->tx_buf_ring != NULL);
-
- while (sw_cons != sw_prod) {
- bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons));
- sw_cons++;
- }
- }
-}
-
-static void bnx2x_free_rx_skbs(struct bnx2x *bp)
-{
- int i, j;
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- BUG_TRAP(fp->rx_buf_ring != NULL);
-
- for (i = 0; i < NUM_RX_BD; i++) {
- struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
- struct sk_buff *skb = rx_buf->skb;
-
- if (skb == NULL)
- continue;
-
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_use_size,
- PCI_DMA_FROMDEVICE);
-
- rx_buf->skb = NULL;
- dev_kfree_skb(skb);
- }
- }
-}
-
-static void bnx2x_free_skbs(struct bnx2x *bp)
-{
- bnx2x_free_tx_skbs(bp);
- bnx2x_free_rx_skbs(bp);
-}
-
-static void bnx2x_free_msix_irqs(struct bnx2x *bp)
-{
- int i;
-
- free_irq(bp->msix_table[0].vector, bp->dev);
- DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
- bp->msix_table[0].vector);
-
- for_each_queue(bp, i) {
- DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq "
- "state(%x)\n", i, bp->msix_table[i + 1].vector,
- bnx2x_fp(bp, i, state));
-
- if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
- BNX2X_ERR("IRQ of fp #%d being freed while "
- "state != closed\n", i);
-
- free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
- }
-
-}
-
-static void bnx2x_free_irq(struct bnx2x *bp)
-{
-
- if (bp->flags & USING_MSIX_FLAG) {
-
- bnx2x_free_msix_irqs(bp);
- pci_disable_msix(bp->pdev);
-
- bp->flags &= ~USING_MSIX_FLAG;
-
- } else
- free_irq(bp->pdev->irq, bp->dev);
-}
-
-static int bnx2x_enable_msix(struct bnx2x *bp)
-{
-
- int i;
-
- bp->msix_table[0].entry = 0;
- for_each_queue(bp, i)
- bp->msix_table[i + 1].entry = i + 1;
-
- if (pci_enable_msix(bp->pdev, &bp->msix_table[0],
- bp->num_queues + 1)){
- BNX2X_LOG("failed to enable MSI-X\n");
- return -1;
-
- }
-
- bp->flags |= USING_MSIX_FLAG;
-
- return 0;
-
-}
-
-
-static int bnx2x_req_msix_irqs(struct bnx2x *bp)
-{
-
- int i, rc;
-
- rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
- bp->dev->name, bp->dev);
-
- if (rc) {
- BNX2X_ERR("request sp irq failed\n");
- return -EBUSY;
- }
-
- for_each_queue(bp, i) {
- rc = request_irq(bp->msix_table[i + 1].vector,
- bnx2x_msix_fp_int, 0,
- bp->dev->name, &bp->fp[i]);
-
- if (rc) {
- BNX2X_ERR("request fp #%d irq failed "
- "rc %d\n", i, rc);
- bnx2x_free_msix_irqs(bp);
- return -EBUSY;
- }
-
- bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
-
- }
-
- return 0;
-
-}
-
-static int bnx2x_req_irq(struct bnx2x *bp)
-{
-
- int rc = request_irq(bp->pdev->irq, bnx2x_interrupt,
- IRQF_SHARED, bp->dev->name, bp->dev);
- if (!rc)
- bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
-
- return rc;
-
-}
-
-/*
- * Init service functions
- */
-
-static void bnx2x_set_mac_addr(struct bnx2x *bp)
-{
- struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
-
- /* CAM allocation
- * unicasts 0-31:port0 32-63:port1
- * multicast 64-127:port0 128-191:port1
- */
- config->hdr.length_6b = 2;
- config->hdr.offset = bp->port ? 31 : 0;
- config->hdr.reserved0 = 0;
- config->hdr.reserved1 = 0;
-
- /* primary MAC */
- config->config_table[0].cam_entry.msb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[0]);
- config->config_table[0].cam_entry.middle_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[2]);
- config->config_table[0].cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[4]);
- config->config_table[0].cam_entry.flags = cpu_to_le16(bp->port);
- config->config_table[0].target_table_entry.flags = 0;
- config->config_table[0].target_table_entry.client_id = 0;
- config->config_table[0].target_table_entry.vlan_id = 0;
-
- DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x)\n",
- config->config_table[0].cam_entry.msb_mac_addr,
- config->config_table[0].cam_entry.middle_mac_addr,
- config->config_table[0].cam_entry.lsb_mac_addr);
-
- /* broadcast */
- config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
- config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
- config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
- config->config_table[1].cam_entry.flags = cpu_to_le16(bp->port);
- config->config_table[1].target_table_entry.flags =
- TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
- config->config_table[1].target_table_entry.client_id = 0;
- config->config_table[1].target_table_entry.vlan_id = 0;
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
-}
-
-static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
- int *state_p, int poll)
-{
- /* can take a while if any port is running */
- int timeout = 500;
-
- DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
- poll ? "polling" : "waiting", state, idx);
-
- might_sleep();
-
- while (timeout) {
-
- if (poll) {
- bnx2x_rx_int(bp->fp, 10);
- /* If index is different from 0
- * The reply for some commands will
- * be on the none default queue
- */
- if (idx)
- bnx2x_rx_int(&bp->fp[idx], 10);
- }
-
- mb(); /* state is changed by bnx2x_sp_event()*/
-
- if (*state_p == state)
- return 0;
-
- timeout--;
- msleep(1);
-
- }
-
- /* timeout! */
- BNX2X_ERR("timeout %s for state %x on IDX [%d]\n",
- poll ? "polling" : "waiting", state, idx);
-
- return -EBUSY;
-}
-
-static int bnx2x_setup_leading(struct bnx2x *bp)
-{
-
- /* reset IGU state */
- bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-
- /* SETUP ramrod */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0);
-
- return bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0);
-
-}
-
-static int bnx2x_setup_multi(struct bnx2x *bp, int index)
-{
-
- /* reset IGU state */
- bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-
- /* SETUP ramrod */
- bp->fp[index].state = BNX2X_FP_STATE_OPENING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
-
- /* Wait for completion */
- return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(bp->fp[index].state), 0);
-
-}
-
-
-static int bnx2x_poll(struct napi_struct *napi, int budget);
-static void bnx2x_set_rx_mode(struct net_device *dev);
-
-static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
-{
- u32 load_code;
- int i;
-
- bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
-
- /* Send LOAD_REQUEST command to MCP.
- Returns the type of LOAD command: if it is the
- first port to be initialized common blocks should be
- initialized, otherwise - not.
- */
- if (!nomcp) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
- if (!load_code) {
- BNX2X_ERR("MCP response failure, unloading\n");
- return -EBUSY;
- }
- if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) {
- BNX2X_ERR("MCP refused load request, unloading\n");
- return -EBUSY; /* other port in diagnostic mode */
- }
- } else {
- load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
- }
-
- /* if we can't use msix we only need one fp,
- * so try to enable msix with the requested number of fp's
- * and fallback to inta with one fp
- */
- if (req_irq) {
- if (use_inta) {
- bp->num_queues = 1;
- } else {
- if ((use_multi > 1) && (use_multi <= 16))
- /* user requested number */
- bp->num_queues = use_multi;
- else if (use_multi == 1)
- bp->num_queues = num_online_cpus();
- else
- bp->num_queues = 1;
-
- if (bnx2x_enable_msix(bp)) {
- /* failed to enable msix */
- bp->num_queues = 1;
- if (use_multi)
- BNX2X_ERR("Multi requested but failed"
- " to enable MSI-X\n");
- }
- }
- }
-
- DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
-
- if (bnx2x_alloc_mem(bp))
- return -ENOMEM;
-
- if (req_irq) {
- if (bp->flags & USING_MSIX_FLAG) {
- if (bnx2x_req_msix_irqs(bp)) {
- pci_disable_msix(bp->pdev);
- goto load_error;
- }
-
- } else {
- if (bnx2x_req_irq(bp)) {
- BNX2X_ERR("IRQ request failed, aborting\n");
- goto load_error;
- }
- }
- }
-
- for_each_queue(bp, i)
- netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
- bnx2x_poll, 128);
-
-
- /* Initialize HW */
- if (bnx2x_function_init(bp,
- (load_code == FW_MSG_CODE_DRV_LOAD_COMMON))) {
- BNX2X_ERR("HW init failed, aborting\n");
- goto load_error;
- }
-
-
- atomic_set(&bp->intr_sem, 0);
-
-
- /* Setup NIC internals and enable interrupts */
- bnx2x_nic_init(bp);
-
- /* Send LOAD_DONE command to MCP */
- if (!nomcp) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
- if (!load_code) {
- BNX2X_ERR("MCP response failure, unloading\n");
- goto load_int_disable;
- }
- }
-
- bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
-
- /* Enable Rx interrupt handling before sending the ramrod
- as it's completed on Rx FP queue */
- for_each_queue(bp, i)
- napi_enable(&bnx2x_fp(bp, i, napi));
-
- if (bnx2x_setup_leading(bp))
- goto load_stop_netif;
-
- for_each_nondefault_queue(bp, i)
- if (bnx2x_setup_multi(bp, i))
- goto load_stop_netif;
-
- bnx2x_set_mac_addr(bp);
-
- bnx2x_phy_init(bp);
-
- /* Start fast path */
- if (req_irq) { /* IRQ is only requested from bnx2x_open */
- netif_start_queue(bp->dev);
- if (bp->flags & USING_MSIX_FLAG)
- printk(KERN_INFO PFX "%s: using MSI-X\n",
- bp->dev->name);
-
- /* Otherwise Tx queue should be only reenabled */
- } else if (netif_running(bp->dev)) {
- netif_wake_queue(bp->dev);
- bnx2x_set_rx_mode(bp->dev);
- }
-
- /* start the timer */
- mod_timer(&bp->timer, jiffies + bp->current_interval);
-
- return 0;
-
-load_stop_netif:
- for_each_queue(bp, i)
- napi_disable(&bnx2x_fp(bp, i, napi));
-
-load_int_disable:
- bnx2x_int_disable_sync(bp);
-
- bnx2x_free_skbs(bp);
- bnx2x_free_irq(bp);
-
-load_error:
- bnx2x_free_mem(bp);
-
- /* TBD we really need to reset the chip
- if we want to recover from this */
- return -EBUSY;
-}
-
-
-static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
-{
- int port = bp->port;
-#ifdef USE_DMAE
- u32 wb_write[2];
-#endif
- int base, i;
-
- DP(NETIF_MSG_IFDOWN, "reset called with code %x\n", reset_code);
-
- /* Do not rcv packets to BRB */
- REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0);
- /* Do not direct rcv packets that are not for MCP to the BRB */
- REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP :
- NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
-
- /* Configure IGU and AEU */
- REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
- REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0);
-
- /* TODO: Close Doorbell port? */
-
- /* Clear ILT */
-#ifdef USE_DMAE
- wb_write[0] = 0;
- wb_write[1] = 0;
-#endif
- base = port * RQ_ONCHIP_AT_PORT_SIZE;
- for (i = base; i < base + RQ_ONCHIP_AT_PORT_SIZE; i++) {
-#ifdef USE_DMAE
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
-#else
- REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT, 0);
- REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + 4, 0);
-#endif
- }
-
- if (reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) {
- /* reset_common */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0xd3ffff7f);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- 0x1403);
- }
-}
-
-static int bnx2x_stop_multi(struct bnx2x *bp, int index)
-{
-
- int rc;
-
- /* halt the connection */
- bp->fp[index].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0);
-
-
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
- &(bp->fp[index].state), 1);
- if (rc) /* timeout */
- return rc;
-
- /* delete cfc entry */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
-
- return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
- &(bp->fp[index].state), 1);
-
-}
-
-
-static void bnx2x_stop_leading(struct bnx2x *bp)
-{
- u16 dsb_sp_prod_idx;
- /* if the other port is handling traffic,
- this can take a lot of time */
- int timeout = 500;
-
- might_sleep();
-
- /* Send HALT ramrod */
- bp->fp[0].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, 0, 0);
-
- if (bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
- &(bp->fp[0].state), 1))
- return;
-
- dsb_sp_prod_idx = *bp->dsb_sp_prod;
-
- /* Send PORT_DELETE ramrod */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
-
- /* Wait for completion to arrive on default status block
- we are going to reset the chip anyway
- so there is not much to do if this times out
- */
- while ((dsb_sp_prod_idx == *bp->dsb_sp_prod) && timeout) {
- timeout--;
- msleep(1);
- }
- if (!timeout) {
- DP(NETIF_MSG_IFDOWN, "timeout polling for completion "
- "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
- *bp->dsb_sp_prod, dsb_sp_prod_idx);
- }
- bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
- bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
-}
-
-
-static int bnx2x_nic_unload(struct bnx2x *bp, int free_irq)
-{
- u32 reset_code = 0;
- int i, timeout;
-
- bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
-
- del_timer_sync(&bp->timer);
-
- bp->rx_mode = BNX2X_RX_MODE_NONE;
- bnx2x_set_storm_rx_mode(bp);
-
- if (netif_running(bp->dev)) {
- netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
- }
-
- /* Wait until all fast path tasks complete */
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- timeout = 1000;
- while (bnx2x_has_work(fp) && (timeout--))
- msleep(1);
- if (!timeout)
- BNX2X_ERR("timeout waiting for queue[%d]\n", i);
- }
-
- /* Wait until stat ramrod returns and all SP tasks complete */
- timeout = 1000;
- while ((bp->stat_pending || (bp->spq_left != MAX_SPQ_PENDING)) &&
- (timeout--))
- msleep(1);
-
- for_each_queue(bp, i)
- napi_disable(&bnx2x_fp(bp, i, napi));
- /* Disable interrupts after Tx and Rx are disabled on stack level */
- bnx2x_int_disable_sync(bp);
-
- if (bp->flags & NO_WOL_FLAG)
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
-
- else if (bp->wol) {
- u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
- u8 *mac_addr = bp->dev->dev_addr;
- u32 val = (EMAC_MODE_MPKT | EMAC_MODE_MPKT_RCVD |
- EMAC_MODE_ACPI_RCVD);
-
- EMAC_WR(EMAC_REG_EMAC_MODE, val);
-
- val = (mac_addr[0] << 8) | mac_addr[1];
- EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
-
- val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
- (mac_addr[4] << 8) | mac_addr[5];
- EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
-
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
-
- } else
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
-
- /* Close multi and leading connections */
- for_each_nondefault_queue(bp, i)
- if (bnx2x_stop_multi(bp, i))
- goto unload_error;
-
- bnx2x_stop_leading(bp);
- if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) ||
- (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) {
- DP(NETIF_MSG_IFDOWN, "failed to close leading properly!"
- "state 0x%x fp[0].state 0x%x",
- bp->state, bp->fp[0].state);
- }
-
-unload_error:
- bnx2x_link_reset(bp);
-
- if (!nomcp)
- reset_code = bnx2x_fw_command(bp, reset_code);
- else
- reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
-
- /* Release IRQs */
- if (free_irq)
- bnx2x_free_irq(bp);
-
- /* Reset the chip */
- bnx2x_reset_chip(bp, reset_code);
-
- /* Report UNLOAD_DONE to MCP */
- if (!nomcp)
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
-
- /* Free SKBs and driver internals */
- bnx2x_free_skbs(bp);
- bnx2x_free_mem(bp);
-
- bp->state = BNX2X_STATE_CLOSED;
-
- netif_carrier_off(bp->dev);
-
- return 0;
-}
-
-/* end of nic load/unload */
-
-/* ethtool_ops */
-
-/*
- * Init service functions
- */
-
-static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
-{
- int port = bp->port;
- u32 ext_phy_type;
-
- bp->phy_flags = 0;
-
- switch (switch_cfg) {
- case SWITCH_CFG_1G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg);
-
- ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_TP | SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n",
- ext_phy_type);
-
- bp->phy_flags |= PHY_SGMII_FLAG;
-
- bp->supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_TP | SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD SerDes ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- return;
- }
-
- bp->phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR +
- port*0x10);
- BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->phy_addr);
- break;
-
- case SWITCH_CFG_10G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg);
-
- bp->phy_flags |= PHY_XGXS_FLAG;
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_TP | SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
- ext_phy_type);
-
- bp->supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
- ext_phy_type);
-
- bp->supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
- ext_phy_type);
-
- bp->supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
- ext_phy_type);
-
- bp->supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- return;
- }
-
- bp->phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR +
- port*0x18);
- BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->phy_addr);
-
- bp->ser_lane = ((bp->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
- bp->rx_lane_swap = ((bp->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
- bp->tx_lane_swap = ((bp->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
- BNX2X_DEV_INFO("rx_lane_swap 0x%x tx_lane_swap 0x%x\n",
- bp->rx_lane_swap, bp->tx_lane_swap);
- break;
-
- default:
- BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
- bp->link_config);
- return;
- }
-
- /* mask what we support according to speed_cap_mask */
- if (!(bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
- bp->supported &= ~SUPPORTED_10baseT_Half;
-
- if (!(bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
- bp->supported &= ~SUPPORTED_10baseT_Full;
-
- if (!(bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
- bp->supported &= ~SUPPORTED_100baseT_Half;
-
- if (!(bp->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
- bp->supported &= ~SUPPORTED_100baseT_Full;
-
- if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
- bp->supported &= ~(SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full);
-
- if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- bp->supported &= ~SUPPORTED_2500baseX_Full;
-
- if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
- bp->supported &= ~SUPPORTED_10000baseT_Full;
-
- BNX2X_DEV_INFO("supported 0x%x\n", bp->supported);
-}
-
-static void bnx2x_link_settings_requested(struct bnx2x *bp)
-{
- bp->req_autoneg = 0;
- bp->req_duplex = DUPLEX_FULL;
-
- switch (bp->link_config & PORT_FEATURE_LINK_SPEED_MASK) {
- case PORT_FEATURE_LINK_SPEED_AUTO:
- if (bp->supported & SUPPORTED_Autoneg) {
- bp->req_autoneg |= AUTONEG_SPEED;
- bp->req_line_speed = 0;
- bp->advertising = bp->supported;
- } else {
- if (XGXS_EXT_PHY_TYPE(bp) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) {
- /* force 10G, no AN */
- bp->req_line_speed = SPEED_10000;
- bp->advertising =
- (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- break;
- }
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " Autoneg not supported\n",
- bp->link_config);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_10M_FULL:
- if (bp->supported & SUPPORTED_10baseT_Full) {
- bp->req_line_speed = SPEED_10;
- bp->advertising = (ADVERTISED_10baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_10M_HALF:
- if (bp->supported & SUPPORTED_10baseT_Half) {
- bp->req_line_speed = SPEED_10;
- bp->req_duplex = DUPLEX_HALF;
- bp->advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_100M_FULL:
- if (bp->supported & SUPPORTED_100baseT_Full) {
- bp->req_line_speed = SPEED_100;
- bp->advertising = (ADVERTISED_100baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_100M_HALF:
- if (bp->supported & SUPPORTED_100baseT_Half) {
- bp->req_line_speed = SPEED_100;
- bp->req_duplex = DUPLEX_HALF;
- bp->advertising = (ADVERTISED_100baseT_Half |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_1G:
- if (bp->supported & SUPPORTED_1000baseT_Full) {
- bp->req_line_speed = SPEED_1000;
- bp->advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_2_5G:
- if (bp->supported & SUPPORTED_2500baseX_Full) {
- bp->req_line_speed = SPEED_2500;
- bp->advertising = (ADVERTISED_2500baseX_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_10G_CX4:
- case PORT_FEATURE_LINK_SPEED_10G_KX4:
- case PORT_FEATURE_LINK_SPEED_10G_KR:
- if (bp->supported & SUPPORTED_10000baseT_Full) {
- bp->req_line_speed = SPEED_10000;
- bp->advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->link_config, bp->speed_cap_mask);
- return;
- }
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD link speed link_config 0x%x\n",
- bp->link_config);
- bp->req_autoneg |= AUTONEG_SPEED;
- bp->req_line_speed = 0;
- bp->advertising = bp->supported;
- break;
- }
- BNX2X_DEV_INFO("req_line_speed %d req_duplex %d\n",
- bp->req_line_speed, bp->req_duplex);
-
- bp->req_flow_ctrl = (bp->link_config &
- PORT_FEATURE_FLOW_CONTROL_MASK);
- if ((bp->req_flow_ctrl == FLOW_CTRL_AUTO) &&
- (bp->supported & SUPPORTED_Autoneg))
- bp->req_autoneg |= AUTONEG_FLOW_CTRL;
-
- BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x"
- " advertising 0x%x\n",
- bp->req_autoneg, bp->req_flow_ctrl, bp->advertising);
-}
-
-static void bnx2x_get_hwinfo(struct bnx2x *bp)
-{
- u32 val, val2, val3, val4, id;
- int port = bp->port;
- u32 switch_cfg;
-
- bp->shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
- BNX2X_DEV_INFO("shmem offset is %x\n", bp->shmem_base);
-
- /* Get the chip revision id and number. */
- /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
- val = REG_RD(bp, MISC_REG_CHIP_NUM);
- id = ((val & 0xffff) << 16);
- val = REG_RD(bp, MISC_REG_CHIP_REV);
- id |= ((val & 0xf) << 12);
- val = REG_RD(bp, MISC_REG_CHIP_METAL);
- id |= ((val & 0xff) << 4);
- REG_RD(bp, MISC_REG_BOND_ID);
- id |= (val & 0xf);
- bp->chip_id = id;
- BNX2X_DEV_INFO("chip ID is %x\n", id);
-
- if (!bp->shmem_base || (bp->shmem_base != 0xAF900)) {
- BNX2X_DEV_INFO("MCP not active\n");
- nomcp = 1;
- goto set_mac;
- }
-
- val = SHMEM_RD(bp, validity_map[port]);
- if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- BNX2X_ERR("BAD MCP validity signature\n");
-
- bp->fw_seq = (SHMEM_RD(bp, func_mb[port].drv_mb_header) &
- DRV_MSG_SEQ_NUMBER_MASK);
-
- bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
- bp->board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
- bp->serdes_config =
- SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
- bp->lane_config =
- SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
- bp->ext_phy_config =
- SHMEM_RD(bp,
- dev_info.port_hw_config[port].external_phy_config);
- bp->speed_cap_mask =
- SHMEM_RD(bp,
- dev_info.port_hw_config[port].speed_capability_mask);
-
- bp->link_config =
- SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
-
- BNX2X_DEV_INFO("hw_config (%08x) board (%08x) serdes_config (%08x)\n"
- KERN_INFO " lane_config (%08x) ext_phy_config (%08x)\n"
- KERN_INFO " speed_cap_mask (%08x) link_config (%08x)"
- " fw_seq (%08x)\n",
- bp->hw_config, bp->board, bp->serdes_config,
- bp->lane_config, bp->ext_phy_config,
- bp->speed_cap_mask, bp->link_config, bp->fw_seq);
-
- switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK);
- bnx2x_link_settings_supported(bp, switch_cfg);
-
- bp->autoneg = (bp->hw_config & SHARED_HW_CFG_AN_ENABLE_MASK);
- /* for now disable cl73 */
- bp->autoneg &= ~SHARED_HW_CFG_AN_ENABLE_CL73;
- BNX2X_DEV_INFO("autoneg 0x%x\n", bp->autoneg);
-
- bnx2x_link_settings_requested(bp);
-
- val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
- val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
- bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
- bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
- bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
- bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
- bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
- bp->dev->dev_addr[5] = (u8)(val & 0xff);
-
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
-
-
- val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
- val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
- val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]);
- val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]);
-
- printk(KERN_INFO PFX "part number %X-%X-%X-%X\n",
- val, val2, val3, val4);
-
- /* bc ver */
- if (!nomcp) {
- bp->bc_ver = val = ((SHMEM_RD(bp, dev_info.bc_rev)) >> 8);
- BNX2X_DEV_INFO("bc_ver %X\n", val);
- if (val < BNX2X_BC_VER) {
- /* for now only warn
- * later we might need to enforce this */
- BNX2X_ERR("This driver needs bc_ver %X but found %X,"
- " please upgrade BC\n", BNX2X_BC_VER, val);
- }
- } else {
- bp->bc_ver = 0;
- }
-
- val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
- bp->flash_size = (NVRAM_1MB_SIZE << (val & MCPR_NVM_CFG4_FLASH_SIZE));
- BNX2X_DEV_INFO("flash_size 0x%x (%d)\n",
- bp->flash_size, bp->flash_size);
-
- return;
-
-set_mac: /* only supposed to happen on emulation/FPGA */
- BNX2X_ERR("warning rendom MAC workaround active\n");
- random_ether_addr(bp->dev->dev_addr);
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
-
-}
-
-/*
- * ethtool service functions
- */
-
-/* All ethtool functions called with rtnl_lock */
-
-static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- cmd->supported = bp->supported;
- cmd->advertising = bp->advertising;
-
- if (netif_carrier_ok(dev)) {
- cmd->speed = bp->line_speed;
- cmd->duplex = bp->duplex;
- } else {
- cmd->speed = bp->req_line_speed;
- cmd->duplex = bp->req_duplex;
- }
-
- if (bp->phy_flags & PHY_XGXS_FLAG) {
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- cmd->port = PORT_FIBRE;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- cmd->port = PORT_TP;
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->ext_phy_config);
- }
- } else
- cmd->port = PORT_TP;
-
- cmd->phy_address = bp->phy_addr;
- cmd->transceiver = XCVR_INTERNAL;
-
- if (bp->req_autoneg & AUTONEG_SPEED)
- cmd->autoneg = AUTONEG_ENABLE;
- else
- cmd->autoneg = AUTONEG_DISABLE;
-
- cmd->maxtxpkt = 0;
- cmd->maxrxpkt = 0;
-
- DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
- DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
- DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
- cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
- cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
-
- return 0;
-}
-
-static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u32 advertising;
-
- DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
- DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
- DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
- cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
- cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
-
- if (cmd->autoneg == AUTONEG_ENABLE) {
- if (!(bp->supported & SUPPORTED_Autoneg)) {
- DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
- return -EINVAL;
- }
-
- /* advertise the requested speed and duplex if supported */
- cmd->advertising &= bp->supported;
-
- bp->req_autoneg |= AUTONEG_SPEED;
- bp->req_line_speed = 0;
- bp->req_duplex = DUPLEX_FULL;
- bp->advertising |= (ADVERTISED_Autoneg | cmd->advertising);
-
- } else { /* forced speed */
- /* advertise the requested speed and duplex if supported */
- switch (cmd->speed) {
- case SPEED_10:
- if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->supported &
- SUPPORTED_10baseT_Full)) {
- DP(NETIF_MSG_LINK,
- "10M full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_10baseT_Full |
- ADVERTISED_TP);
- } else {
- if (!(bp->supported &
- SUPPORTED_10baseT_Half)) {
- DP(NETIF_MSG_LINK,
- "10M half not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_TP);
- }
- break;
-
- case SPEED_100:
- if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->supported &
- SUPPORTED_100baseT_Full)) {
- DP(NETIF_MSG_LINK,
- "100M full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_100baseT_Full |
- ADVERTISED_TP);
- } else {
- if (!(bp->supported &
- SUPPORTED_100baseT_Half)) {
- DP(NETIF_MSG_LINK,
- "100M half not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_100baseT_Half |
- ADVERTISED_TP);
- }
- break;
-
- case SPEED_1000:
- if (cmd->duplex != DUPLEX_FULL) {
- DP(NETIF_MSG_LINK, "1G half not supported\n");
- return -EINVAL;
- }
-
- if (!(bp->supported & SUPPORTED_1000baseT_Full)) {
- DP(NETIF_MSG_LINK, "1G full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_TP);
- break;
-
- case SPEED_2500:
- if (cmd->duplex != DUPLEX_FULL) {
- DP(NETIF_MSG_LINK,
- "2.5G half not supported\n");
- return -EINVAL;
- }
-
- if (!(bp->supported & SUPPORTED_2500baseX_Full)) {
- DP(NETIF_MSG_LINK,
- "2.5G full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_2500baseX_Full |
- ADVERTISED_TP);
- break;
-
- case SPEED_10000:
- if (cmd->duplex != DUPLEX_FULL) {
- DP(NETIF_MSG_LINK, "10G half not supported\n");
- return -EINVAL;
- }
-
- if (!(bp->supported & SUPPORTED_10000baseT_Full)) {
- DP(NETIF_MSG_LINK, "10G full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- break;
-
- default:
- DP(NETIF_MSG_LINK, "Unsupported speed\n");
- return -EINVAL;
- }
-
- bp->req_autoneg &= ~AUTONEG_SPEED;
- bp->req_line_speed = cmd->speed;
- bp->req_duplex = cmd->duplex;
- bp->advertising = advertising;
- }
-
- DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_line_speed %d\n"
- DP_LEVEL " req_duplex %d advertising 0x%x\n",
- bp->req_autoneg, bp->req_line_speed, bp->req_duplex,
- bp->advertising);
-
- bnx2x_stop_stats(bp);
- bnx2x_link_initialize(bp);
-
- return 0;
-}
-
-static void bnx2x_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- strcpy(info->driver, DRV_MODULE_NAME);
- strcpy(info->version, DRV_MODULE_VERSION);
- snprintf(info->fw_version, 32, "%d.%d.%d:%d (BC VER %x)",
- BCM_5710_FW_MAJOR_VERSION, BCM_5710_FW_MINOR_VERSION,
- BCM_5710_FW_REVISION_VERSION, BCM_5710_FW_COMPILE_FLAGS,
- bp->bc_ver);
- strcpy(info->bus_info, pci_name(bp->pdev));
- info->n_stats = BNX2X_NUM_STATS;
- info->testinfo_len = BNX2X_NUM_TESTS;
- info->eedump_len = bp->flash_size;
- info->regdump_len = 0;
-}
-
-static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (bp->flags & NO_WOL_FLAG) {
- wol->supported = 0;
- wol->wolopts = 0;
- } else {
- wol->supported = WAKE_MAGIC;
- if (bp->wol)
- wol->wolopts = WAKE_MAGIC;
- else
- wol->wolopts = 0;
- }
- memset(&wol->sopass, 0, sizeof(wol->sopass));
-}
-
-static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (wol->wolopts & ~WAKE_MAGIC)
- return -EINVAL;
-
- if (wol->wolopts & WAKE_MAGIC) {
- if (bp->flags & NO_WOL_FLAG)
- return -EINVAL;
-
- bp->wol = 1;
- } else {
- bp->wol = 0;
- }
- return 0;
-}
-
-static u32 bnx2x_get_msglevel(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->msglevel;
-}
-
-static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (capable(CAP_NET_ADMIN))
- bp->msglevel = level;
-}
-
-static int bnx2x_nway_reset(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (bp->state != BNX2X_STATE_OPEN) {
- DP(NETIF_MSG_PROBE, "state is %x, returning\n", bp->state);
- return -EAGAIN;
- }
-
- bnx2x_stop_stats(bp);
- bnx2x_link_initialize(bp);
-
- return 0;
-}
-
-static int bnx2x_get_eeprom_len(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->flash_size;
-}
-
-static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
-{
- int port = bp->port;
- int count, i;
- u32 val = 0;
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* request access to nvram interface */
- REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
- (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port));
-
- for (i = 0; i < count*10; i++) {
- val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
- if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))
- break;
-
- udelay(5);
- }
-
- if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
- DP(NETIF_MSG_NVM, "cannot get access to nvram interface\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int bnx2x_release_nvram_lock(struct bnx2x *bp)
-{
- int port = bp->port;
- int count, i;
- u32 val = 0;
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* relinquish nvram interface */
- REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
- (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port));
-
- for (i = 0; i < count*10; i++) {
- val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
- if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)))
- break;
-
- udelay(5);
- }
-
- if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) {
- DP(NETIF_MSG_NVM, "cannot free access to nvram interface\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static void bnx2x_enable_nvram_access(struct bnx2x *bp)
-{
- u32 val;
-
- val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
-
- /* enable both bits, even on read */
- REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
- (val | MCPR_NVM_ACCESS_ENABLE_EN |
- MCPR_NVM_ACCESS_ENABLE_WR_EN));
-}
-
-static void bnx2x_disable_nvram_access(struct bnx2x *bp)
-{
- u32 val;
-
- val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
-
- /* disable both bits, even after read */
- REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
- (val & ~(MCPR_NVM_ACCESS_ENABLE_EN |
- MCPR_NVM_ACCESS_ENABLE_WR_EN)));
-}
-
-static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
- u32 cmd_flags)
-{
- int count, i, rc;
- u32 val;
-
- /* build the command word */
- cmd_flags |= MCPR_NVM_COMMAND_DOIT;
-
- /* need to clear DONE bit separately */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
-
- /* address of the NVRAM to read from */
- REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
- (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
-
- /* issue a read command */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* wait for completion */
- *ret_val = 0;
- rc = -EBUSY;
- for (i = 0; i < count; i++) {
- udelay(5);
- val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
-
- if (val & MCPR_NVM_COMMAND_DONE) {
- val = REG_RD(bp, MCP_REG_MCPR_NVM_READ);
- DP(NETIF_MSG_NVM, "val 0x%08x\n", val);
- /* we read nvram data in cpu order
- * but ethtool sees it as an array of bytes
- * converting to big-endian will do the work */
- val = cpu_to_be32(val);
- *ret_val = val;
- rc = 0;
- break;
- }
- }
-
- return rc;
-}
-
-static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
- int buf_size)
-{
- int rc;
- u32 cmd_flags;
- u32 val;
-
- if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
- DP(NETIF_MSG_NVM,
- "Invalid parameter: offset 0x%x buf_size 0x%x\n",
- offset, buf_size);
- return -EINVAL;
- }
-
- if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
- " buf_size (0x%x) > flash_size (0x%x)\n",
- offset, buf_size, bp->flash_size);
- return -EINVAL;
- }
-
- /* request access to nvram interface */
- rc = bnx2x_acquire_nvram_lock(bp);
- if (rc)
- return rc;
-
- /* enable access to nvram interface */
- bnx2x_enable_nvram_access(bp);
-
- /* read the first word(s) */
- cmd_flags = MCPR_NVM_COMMAND_FIRST;
- while ((buf_size > sizeof(u32)) && (rc == 0)) {
- rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
- memcpy(ret_buf, &val, 4);
-
- /* advance to the next dword */
- offset += sizeof(u32);
- ret_buf += sizeof(u32);
- buf_size -= sizeof(u32);
- cmd_flags = 0;
- }
-
- if (rc == 0) {
- cmd_flags |= MCPR_NVM_COMMAND_LAST;
- rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
- memcpy(ret_buf, &val, 4);
- }
-
- /* disable access to nvram interface */
- bnx2x_disable_nvram_access(bp);
- bnx2x_release_nvram_lock(bp);
-
- return rc;
-}
-
-static int bnx2x_get_eeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom, u8 *eebuf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc;
-
- DP(NETIF_MSG_NVM, "ethtool_eeprom: cmd %d\n"
- DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
- eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
- eeprom->len, eeprom->len);
-
- /* parameters already validated in ethtool_get_eeprom */
-
- rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
-
- return rc;
-}
-
-static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
- u32 cmd_flags)
-{
- int count, i, rc;
-
- /* build the command word */
- cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
-
- /* need to clear DONE bit separately */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
-
- /* write the data */
- REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val);
-
- /* address of the NVRAM to write to */
- REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
- (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
-
- /* issue the write command */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* wait for completion */
- rc = -EBUSY;
- for (i = 0; i < count; i++) {
- udelay(5);
- val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
- if (val & MCPR_NVM_COMMAND_DONE) {
- rc = 0;
- break;
- }
- }
-
- return rc;
-}
-
-#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
-
-static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
- int buf_size)
-{
- int rc;
- u32 cmd_flags;
- u32 align_offset;
- u32 val;
-
- if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
- " buf_size (0x%x) > flash_size (0x%x)\n",
- offset, buf_size, bp->flash_size);
- return -EINVAL;
- }
-
- /* request access to nvram interface */
- rc = bnx2x_acquire_nvram_lock(bp);
- if (rc)
- return rc;
-
- /* enable access to nvram interface */
- bnx2x_enable_nvram_access(bp);
-
- cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST);
- align_offset = (offset & ~0x03);
- rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags);
-
- if (rc == 0) {
- val &= ~(0xff << BYTE_OFFSET(offset));
- val |= (*data_buf << BYTE_OFFSET(offset));
-
- /* nvram data is returned as an array of bytes
- * convert it back to cpu order */
- val = be32_to_cpu(val);
-
- DP(NETIF_MSG_NVM, "val 0x%08x\n", val);
-
- rc = bnx2x_nvram_write_dword(bp, align_offset, val,
- cmd_flags);
- }
-
- /* disable access to nvram interface */
- bnx2x_disable_nvram_access(bp);
- bnx2x_release_nvram_lock(bp);
-
- return rc;
-}
-
-static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
- int buf_size)
-{
- int rc;
- u32 cmd_flags;
- u32 val;
- u32 written_so_far;
-
- if (buf_size == 1) { /* ethtool */
- return bnx2x_nvram_write1(bp, offset, data_buf, buf_size);
- }
-
- if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
- DP(NETIF_MSG_NVM,
- "Invalid parameter: offset 0x%x buf_size 0x%x\n",
- offset, buf_size);
- return -EINVAL;
- }
-
- if (offset + buf_size > bp->flash_size) {
- DP(NETIF_MSG_NVM, "Invalid parameter: offset (0x%x) +"
- " buf_size (0x%x) > flash_size (0x%x)\n",
- offset, buf_size, bp->flash_size);
- return -EINVAL;
- }
-
- /* request access to nvram interface */
- rc = bnx2x_acquire_nvram_lock(bp);
- if (rc)
- return rc;
-
- /* enable access to nvram interface */
- bnx2x_enable_nvram_access(bp);
-
- written_so_far = 0;
- cmd_flags = MCPR_NVM_COMMAND_FIRST;
- while ((written_so_far < buf_size) && (rc == 0)) {
- if (written_so_far == (buf_size - sizeof(u32)))
- cmd_flags |= MCPR_NVM_COMMAND_LAST;
- else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0)
- cmd_flags |= MCPR_NVM_COMMAND_LAST;
- else if ((offset % NVRAM_PAGE_SIZE) == 0)
- cmd_flags |= MCPR_NVM_COMMAND_FIRST;
-
- memcpy(&val, data_buf, 4);
- DP(NETIF_MSG_NVM, "val 0x%08x\n", val);
-
- rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags);
-
- /* advance to the next dword */
- offset += sizeof(u32);
- data_buf += sizeof(u32);
- written_so_far += sizeof(u32);
- cmd_flags = 0;
- }
-
- /* disable access to nvram interface */
- bnx2x_disable_nvram_access(bp);
- bnx2x_release_nvram_lock(bp);
-
- return rc;
-}
-
-static int bnx2x_set_eeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom, u8 *eebuf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc;
-
- DP(NETIF_MSG_NVM, "ethtool_eeprom: cmd %d\n"
- DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
- eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
- eeprom->len, eeprom->len);
-
- /* parameters already validated in ethtool_set_eeprom */
-
- rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
-
- return rc;
-}
-
-static int bnx2x_get_coalesce(struct net_device *dev,
- struct ethtool_coalesce *coal)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- memset(coal, 0, sizeof(struct ethtool_coalesce));
-
- coal->rx_coalesce_usecs = bp->rx_ticks;
- coal->tx_coalesce_usecs = bp->tx_ticks;
- coal->stats_block_coalesce_usecs = bp->stats_ticks;
-
- return 0;
-}
-
-static int bnx2x_set_coalesce(struct net_device *dev,
- struct ethtool_coalesce *coal)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
- if (bp->rx_ticks > 3000)
- bp->rx_ticks = 3000;
-
- bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
- if (bp->tx_ticks > 0x3000)
- bp->tx_ticks = 0x3000;
-
- bp->stats_ticks = coal->stats_block_coalesce_usecs;
- if (bp->stats_ticks > 0xffff00)
- bp->stats_ticks = 0xffff00;
- bp->stats_ticks &= 0xffff00;
-
- if (netif_running(bp->dev))
- bnx2x_update_coalesce(bp);
-
- return 0;
-}
-
-static void bnx2x_get_ringparam(struct net_device *dev,
- struct ethtool_ringparam *ering)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- ering->rx_max_pending = MAX_RX_AVAIL;
- ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = 0;
-
- ering->rx_pending = bp->rx_ring_size;
- ering->rx_mini_pending = 0;
- ering->rx_jumbo_pending = 0;
-
- ering->tx_max_pending = MAX_TX_AVAIL;
- ering->tx_pending = bp->tx_ring_size;
-}
-
-static int bnx2x_set_ringparam(struct net_device *dev,
- struct ethtool_ringparam *ering)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if ((ering->rx_pending > MAX_RX_AVAIL) ||
- (ering->tx_pending > MAX_TX_AVAIL) ||
- (ering->tx_pending <= MAX_SKB_FRAGS + 4))
- return -EINVAL;
-
- bp->rx_ring_size = ering->rx_pending;
- bp->tx_ring_size = ering->tx_pending;
-
- if (netif_running(bp->dev)) {
- bnx2x_nic_unload(bp, 0);
- bnx2x_nic_load(bp, 0);
- }
-
- return 0;
-}
-
-static void bnx2x_get_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *epause)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- epause->autoneg =
- ((bp->req_autoneg & AUTONEG_FLOW_CTRL) == AUTONEG_FLOW_CTRL);
- epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) == FLOW_CTRL_RX);
- epause->tx_pause = ((bp->flow_ctrl & FLOW_CTRL_TX) == FLOW_CTRL_TX);
-
- DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
- DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
- epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
-}
-
-static int bnx2x_set_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *epause)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
- DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
- epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
-
- if (epause->autoneg) {
- if (!(bp->supported & SUPPORTED_Autoneg)) {
- DP(NETIF_MSG_LINK, "Aotoneg not supported\n");
- return -EINVAL;
- }
-
- bp->req_autoneg |= AUTONEG_FLOW_CTRL;
- } else
- bp->req_autoneg &= ~AUTONEG_FLOW_CTRL;
-
- bp->req_flow_ctrl = FLOW_CTRL_AUTO;
-
- if (epause->rx_pause)
- bp->req_flow_ctrl |= FLOW_CTRL_RX;
- if (epause->tx_pause)
- bp->req_flow_ctrl |= FLOW_CTRL_TX;
-
- if (!(bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
- (bp->req_flow_ctrl == FLOW_CTRL_AUTO))
- bp->req_flow_ctrl = FLOW_CTRL_NONE;
-
- DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n",
- bp->req_autoneg, bp->req_flow_ctrl);
-
- bnx2x_stop_stats(bp);
- bnx2x_link_initialize(bp);
-
- return 0;
-}
-
-static u32 bnx2x_get_rx_csum(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->rx_csum;
-}
-
-static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bp->rx_csum = data;
- return 0;
-}
-
-static int bnx2x_set_tso(struct net_device *dev, u32 data)
-{
- if (data)
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
- return 0;
-}
-
-static struct {
- char string[ETH_GSTRING_LEN];
-} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
- { "MC Errors (online)" }
-};
-
-static int bnx2x_self_test_count(struct net_device *dev)
-{
- return BNX2X_NUM_TESTS;
-}
-
-static void bnx2x_self_test(struct net_device *dev,
- struct ethtool_test *etest, u64 *buf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int stats_state;
-
- memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS);
-
- if (bp->state != BNX2X_STATE_OPEN) {
- DP(NETIF_MSG_PROBE, "state is %x, returning\n", bp->state);
- return;
- }
-
- stats_state = bp->stats_state;
- bnx2x_stop_stats(bp);
-
- if (bnx2x_mc_assert(bp) != 0) {
- buf[0] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
-
-#ifdef BNX2X_EXTRA_DEBUG
- bnx2x_panic_dump(bp);
-#endif
- bp->stats_state = stats_state;
-}
-
-static struct {
- char string[ETH_GSTRING_LEN];
-} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = {
- { "rx_bytes"},
- { "rx_error_bytes"},
- { "tx_bytes"},
- { "tx_error_bytes"},
- { "rx_ucast_packets"},
- { "rx_mcast_packets"},
- { "rx_bcast_packets"},
- { "tx_ucast_packets"},
- { "tx_mcast_packets"},
- { "tx_bcast_packets"},
- { "tx_mac_errors"}, /* 10 */
- { "tx_carrier_errors"},
- { "rx_crc_errors"},
- { "rx_align_errors"},
- { "tx_single_collisions"},
- { "tx_multi_collisions"},
- { "tx_deferred"},
- { "tx_excess_collisions"},
- { "tx_late_collisions"},
- { "tx_total_collisions"},
- { "rx_fragments"}, /* 20 */
- { "rx_jabbers"},
- { "rx_undersize_packets"},
- { "rx_oversize_packets"},
- { "rx_xon_frames"},
- { "rx_xoff_frames"},
- { "tx_xon_frames"},
- { "tx_xoff_frames"},
- { "rx_mac_ctrl_frames"},
- { "rx_filtered_packets"},
- { "rx_discards"}, /* 30 */
- { "brb_discard"},
- { "brb_truncate"},
- { "xxoverflow"}
-};
-
-#define STATS_OFFSET32(offset_name) \
- (offsetof(struct bnx2x_eth_stats, offset_name) / 4)
-
-static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = {
- STATS_OFFSET32(total_bytes_received_hi),
- STATS_OFFSET32(stat_IfHCInBadOctets_hi),
- STATS_OFFSET32(total_bytes_transmitted_hi),
- STATS_OFFSET32(stat_IfHCOutBadOctets_hi),
- STATS_OFFSET32(total_unicast_packets_received_hi),
- STATS_OFFSET32(total_multicast_packets_received_hi),
- STATS_OFFSET32(total_broadcast_packets_received_hi),
- STATS_OFFSET32(total_unicast_packets_transmitted_hi),
- STATS_OFFSET32(total_multicast_packets_transmitted_hi),
- STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
- STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */
- STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors),
- STATS_OFFSET32(crc_receive_errors),
- STATS_OFFSET32(alignment_errors),
- STATS_OFFSET32(single_collision_transmit_frames),
- STATS_OFFSET32(multiple_collision_transmit_frames),
- STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions),
- STATS_OFFSET32(excessive_collision_frames),
- STATS_OFFSET32(late_collision_frames),
- STATS_OFFSET32(number_of_bugs_found_in_stats_spec),
- STATS_OFFSET32(runt_packets_received), /* 20 */
- STATS_OFFSET32(jabber_packets_received),
- STATS_OFFSET32(error_runt_packets_received),
- STATS_OFFSET32(error_jabber_packets_received),
- STATS_OFFSET32(pause_xon_frames_received),
- STATS_OFFSET32(pause_xoff_frames_received),
- STATS_OFFSET32(pause_xon_frames_transmitted),
- STATS_OFFSET32(pause_xoff_frames_transmitted),
- STATS_OFFSET32(control_frames_received),
- STATS_OFFSET32(mac_filter_discard),
- STATS_OFFSET32(no_buff_discard), /* 30 */
- STATS_OFFSET32(brb_discard),
- STATS_OFFSET32(brb_truncate_discard),
- STATS_OFFSET32(xxoverflow_discard)
-};
-
-static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = {
- 8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
- 4, 0, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4
-};
-
-static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
-{
- switch (stringset) {
- case ETH_SS_STATS:
- memcpy(buf, bnx2x_stats_str_arr, sizeof(bnx2x_stats_str_arr));
- break;
-
- case ETH_SS_TEST:
- memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr));
- break;
- }
-}
-
-static int bnx2x_get_stats_count(struct net_device *dev)
-{
- return BNX2X_NUM_STATS;
-}
-
-static void bnx2x_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *buf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u32 *hw_stats = (u32 *)bnx2x_sp_check(bp, eth_stats);
- int i;
-
- for (i = 0; i < BNX2X_NUM_STATS; i++) {
- if (bnx2x_stats_len_arr[i] == 0) {
- /* skip this counter */
- buf[i] = 0;
- continue;
- }
- if (!hw_stats) {
- buf[i] = 0;
- continue;
- }
- if (bnx2x_stats_len_arr[i] == 4) {
- /* 4-byte counter */
- buf[i] = (u64) *(hw_stats + bnx2x_stats_offset_arr[i]);
- continue;
- }
- /* 8-byte counter */
- buf[i] = HILO_U64(*(hw_stats + bnx2x_stats_offset_arr[i]),
- *(hw_stats + bnx2x_stats_offset_arr[i] + 1));
- }
-}
-
-static int bnx2x_phys_id(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int i;
-
- if (data == 0)
- data = 2;
-
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0) {
- bnx2x_leds_set(bp, SPEED_1000);
- } else {
- bnx2x_leds_unset(bp);
- }
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
- }
-
- if (bp->link_up)
- bnx2x_leds_set(bp, bp->line_speed);
-
- return 0;
-}
-
-static struct ethtool_ops bnx2x_ethtool_ops = {
- .get_settings = bnx2x_get_settings,
- .set_settings = bnx2x_set_settings,
- .get_drvinfo = bnx2x_get_drvinfo,
- .get_wol = bnx2x_get_wol,
- .set_wol = bnx2x_set_wol,
- .get_msglevel = bnx2x_get_msglevel,
- .set_msglevel = bnx2x_set_msglevel,
- .nway_reset = bnx2x_nway_reset,
- .get_link = ethtool_op_get_link,
- .get_eeprom_len = bnx2x_get_eeprom_len,
- .get_eeprom = bnx2x_get_eeprom,
- .set_eeprom = bnx2x_set_eeprom,
- .get_coalesce = bnx2x_get_coalesce,
- .set_coalesce = bnx2x_set_coalesce,
- .get_ringparam = bnx2x_get_ringparam,
- .set_ringparam = bnx2x_set_ringparam,
- .get_pauseparam = bnx2x_get_pauseparam,
- .set_pauseparam = bnx2x_set_pauseparam,
- .get_rx_csum = bnx2x_get_rx_csum,
- .set_rx_csum = bnx2x_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = bnx2x_set_tso,
- .self_test_count = bnx2x_self_test_count,
- .self_test = bnx2x_self_test,
- .get_strings = bnx2x_get_strings,
- .phys_id = bnx2x_phys_id,
- .get_stats_count = bnx2x_get_stats_count,
- .get_ethtool_stats = bnx2x_get_ethtool_stats
-};
-
-/* end of ethtool_ops */
-
-/****************************************************************************
-* General service functions
-****************************************************************************/
-
-static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
-{
- u16 pmcsr;
-
- pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
-
- switch (state) {
- case PCI_D0:
- 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 */
- msleep(20);
- break;
-
- case PCI_D3hot:
- pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
- pmcsr |= 3;
-
- if (bp->wol)
- pmcsr |= PCI_PM_CTRL_PME_ENABLE;
-
- pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
- pmcsr);
-
- /* No more memory access after this point until
- * device is brought back to D0.
- */
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * net_device service functions
- */
-
-/* called with netif_tx_lock from set_multicast */
-static void bnx2x_set_rx_mode(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u32 rx_mode = BNX2X_RX_MODE_NORMAL;
-
- DP(NETIF_MSG_IFUP, "called dev->flags = %x\n", dev->flags);
-
- if (dev->flags & IFF_PROMISC)
- rx_mode = BNX2X_RX_MODE_PROMISC;
-
- else if ((dev->flags & IFF_ALLMULTI) ||
- (dev->mc_count > BNX2X_MAX_MULTICAST))
- rx_mode = BNX2X_RX_MODE_ALLMULTI;
-
- else { /* some multicasts */
- int i, old, offset;
- struct dev_mc_list *mclist;
- struct mac_configuration_cmd *config =
- bnx2x_sp(bp, mcast_config);
-
- for (i = 0, mclist = dev->mc_list;
- mclist && (i < dev->mc_count);
- i++, mclist = mclist->next) {
-
- config->config_table[i].cam_entry.msb_mac_addr =
- swab16(*(u16 *)&mclist->dmi_addr[0]);
- config->config_table[i].cam_entry.middle_mac_addr =
- swab16(*(u16 *)&mclist->dmi_addr[2]);
- config->config_table[i].cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&mclist->dmi_addr[4]);
- config->config_table[i].cam_entry.flags =
- cpu_to_le16(bp->port);
- config->config_table[i].target_table_entry.flags = 0;
- config->config_table[i].target_table_entry.
- client_id = 0;
- config->config_table[i].target_table_entry.
- vlan_id = 0;
-
- DP(NETIF_MSG_IFUP,
- "setting MCAST[%d] (%04x:%04x:%04x)\n",
- i, config->config_table[i].cam_entry.msb_mac_addr,
- config->config_table[i].cam_entry.middle_mac_addr,
- config->config_table[i].cam_entry.lsb_mac_addr);
- }
- old = config->hdr.length_6b;
- if (old > i) {
- for (; i < old; i++) {
- if (CAM_IS_INVALID(config->config_table[i])) {
- i--; /* already invalidated */
- break;
- }
- /* invalidate */
- CAM_INVALIDATE(config->config_table[i]);
- }
- }
-
- if (CHIP_REV_IS_SLOW(bp))
- offset = BNX2X_MAX_EMUL_MULTI*(1 + bp->port);
- else
- offset = BNX2X_MAX_MULTICAST*(1 + bp->port);
-
- config->hdr.length_6b = i;
- config->hdr.offset = offset;
- config->hdr.reserved0 = 0;
- config->hdr.reserved1 = 0;
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
- U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
- }
-
- bp->rx_mode = rx_mode;
- bnx2x_set_storm_rx_mode(bp);
-}
-
-static int bnx2x_poll(struct napi_struct *napi, int budget)
-{
- struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
- napi);
- struct bnx2x *bp = fp->bp;
- int work_done = 0;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- goto out_panic;
-#endif
-
- prefetch(fp->tx_buf_ring[TX_BD(fp->tx_pkt_cons)].skb);
- prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb);
- prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256);
-
- bnx2x_update_fpsb_idx(fp);
-
- if (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons)
- bnx2x_tx_int(fp, budget);
-
-
- if (le16_to_cpu(*fp->rx_cons_sb) != fp->rx_comp_cons)
- work_done = bnx2x_rx_int(fp, budget);
-
-
- rmb(); /* bnx2x_has_work() reads the status block */
-
- /* must not complete if we consumed full budget */
- if ((work_done < budget) && !bnx2x_has_work(fp)) {
-
-#ifdef BNX2X_STOP_ON_ERROR
-out_panic:
-#endif
- netif_rx_complete(bp->dev, napi);
-
- bnx2x_ack_sb(bp, fp->index, USTORM_ID,
- le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, fp->index, CSTORM_ID,
- le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
- }
-
- return work_done;
-}
-
-/* Called with netif_tx_lock.
- * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
- * netif_wake_queue().
- */
-static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
- struct bnx2x_fastpath *fp;
- struct sw_tx_bd *tx_buf;
- struct eth_tx_bd *tx_bd;
- struct eth_tx_parse_bd *pbd = NULL;
- u16 pkt_prod, bd_prod;
- int nbd, fp_index = 0;
- dma_addr_t mapping;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return NETDEV_TX_BUSY;
-#endif
-
- fp_index = smp_processor_id() % (bp->num_queues);
-
- fp = &bp->fp[fp_index];
- if (unlikely(bnx2x_tx_avail(bp->fp) <
- (skb_shinfo(skb)->nr_frags + 3))) {
- bp->slowpath->eth_stats.driver_xoff++,
- netif_stop_queue(dev);
- BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
- return NETDEV_TX_BUSY;
- }
-
- /*
- This is a bit ugly. First we use one BD which we mark as start,
- then for TSO or xsum we have a parsing info BD,
- and only then we have the rest of the TSO bds.
- (don't forget to mark the last one as last,
- and to unmap only AFTER you write to the BD ...)
- I would like to thank DovH for this mess.
- */
-
- pkt_prod = fp->tx_pkt_prod++;
- bd_prod = fp->tx_bd_prod;
- bd_prod = TX_BD(bd_prod);
-
- /* get a tx_buff and first bd */
- tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
- tx_bd = &fp->tx_desc_ring[bd_prod];
-
- tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
- tx_bd->general_data = (UNICAST_ADDRESS <<
- ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
- tx_bd->general_data |= 1; /* header nbd */
-
- /* remember the first bd of the packet */
- tx_buf->first_bd = bd_prod;
-
- DP(NETIF_MSG_TX_QUEUED,
- "sending pkt %u @%p next_idx %u bd %u @%p\n",
- pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd);
-
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- struct iphdr *iph = ip_hdr(skb);
- u8 len;
-
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM;
-
- /* turn on parsing and get a bd */
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- pbd = (void *)&fp->tx_desc_ring[bd_prod];
- len = ((u8 *)iph - (u8 *)skb->data) / 2;
-
- /* for now NS flag is not used in Linux */
- pbd->global_data = (len |
- ((skb->protocol == ntohs(ETH_P_8021Q)) <<
- ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
- pbd->ip_hlen = ip_hdrlen(skb) / 2;
- pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen);
- if (iph->protocol == IPPROTO_TCP) {
- struct tcphdr *th = tcp_hdr(skb);
-
- tx_bd->bd_flags.as_bitfield |=
- ETH_TX_BD_FLAGS_TCP_CSUM;
- pbd->tcp_flags = pbd_tcp_flags(skb);
- pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2);
- pbd->tcp_pseudo_csum = swab16(th->check);
-
- } else if (iph->protocol == IPPROTO_UDP) {
- struct udphdr *uh = udp_hdr(skb);
-
- tx_bd->bd_flags.as_bitfield |=
- ETH_TX_BD_FLAGS_TCP_CSUM;
- pbd->total_hlen += cpu_to_le16(4);
- pbd->global_data |= ETH_TX_PARSE_BD_CS_ANY_FLG;
- pbd->cs_offset = 5; /* 10 >> 1 */
- pbd->tcp_pseudo_csum = 0;
- /* HW bug: we need to subtract 10 bytes before the
- * UDP header from the csum
- */
- uh->check = (u16) ~csum_fold(csum_sub(uh->check,
- csum_partial(((u8 *)(uh)-10), 10, 0)));
- }
- }
-
- if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) {
- tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
- } else {
- tx_bd->vlan = cpu_to_le16(pkt_prod);
- }
-
- mapping = pci_map_single(bp->pdev, skb->data,
- skb->len, PCI_DMA_TODEVICE);
-
- tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
- nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL)? 1 : 2);
- tx_bd->nbd = cpu_to_le16(nbd);
- tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
-
- DP(NETIF_MSG_TX_QUEUED, "first bd @%p addr (%x:%x) nbd %d"
- " nbytes %d flags %x vlan %u\n",
- tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, tx_bd->nbd,
- tx_bd->nbytes, tx_bd->bd_flags.as_bitfield, tx_bd->vlan);
-
- if (skb_shinfo(skb)->gso_size &&
- (skb->len > (bp->dev->mtu + ETH_HLEN))) {
- int hlen = 2 * le16_to_cpu(pbd->total_hlen);
-
- DP(NETIF_MSG_TX_QUEUED,
- "TSO packet len %d hlen %d total len %d tso size %d\n",
- skb->len, hlen, skb_headlen(skb),
- skb_shinfo(skb)->gso_size);
-
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
-
- if (tx_bd->nbytes > cpu_to_le16(hlen)) {
- /* we split the first bd into headers and data bds
- * to ease the pain of our fellow micocode engineers
- * we use one mapping for both bds
- * So far this has only been observed to happen
- * in Other Operating Systems(TM)
- */
-
- /* first fix first bd */
- nbd++;
- tx_bd->nbd = cpu_to_le16(nbd);
- tx_bd->nbytes = cpu_to_le16(hlen);
-
- /* we only print this as an error
- * because we don't think this will ever happen.
- */
- BNX2X_ERR("TSO split header size is %d (%x:%x)"
- " nbd %d\n", tx_bd->nbytes, tx_bd->addr_hi,
- tx_bd->addr_lo, tx_bd->nbd);
-
- /* now get a new data bd
- * (after the pbd) and fill it */
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- tx_bd = &fp->tx_desc_ring[bd_prod];
-
- tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping) + hlen);
- tx_bd->nbytes = cpu_to_le16(skb_headlen(skb) - hlen);
- tx_bd->vlan = cpu_to_le16(pkt_prod);
- /* this marks the bd
- * as one that has no individual mapping
- * the FW ignores this flag in a bd not marked start
- */
- tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
- DP(NETIF_MSG_TX_QUEUED,
- "TSO split data size is %d (%x:%x)\n",
- tx_bd->nbytes, tx_bd->addr_hi, tx_bd->addr_lo);
- }
-
- if (!pbd) {
- /* supposed to be unreached
- * (and therefore not handled properly...)
- */
- BNX2X_ERR("LSO with no PBD\n");
- BUG();
- }
-
- pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
- pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
- pbd->ip_id = swab16(ip_hdr(skb)->id);
- pbd->tcp_pseudo_csum =
- swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
- ip_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0));
- pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN;
- }
-
- {
- int i;
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- tx_bd = &fp->tx_desc_ring[bd_prod];
-
- mapping = pci_map_page(bp->pdev, frag->page,
- frag->page_offset,
- frag->size, PCI_DMA_TODEVICE);
-
- tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
- tx_bd->nbytes = cpu_to_le16(frag->size);
- tx_bd->vlan = cpu_to_le16(pkt_prod);
- tx_bd->bd_flags.as_bitfield = 0;
- DP(NETIF_MSG_TX_QUEUED, "frag %d bd @%p"
- " addr (%x:%x) nbytes %d flags %x\n",
- i, tx_bd, tx_bd->addr_hi, tx_bd->addr_lo,
- tx_bd->nbytes, tx_bd->bd_flags.as_bitfield);
- } /* for */
- }
-
- /* now at last mark the bd as the last bd */
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_END_BD;
-
- DP(NETIF_MSG_TX_QUEUED, "last bd @%p flags %x\n",
- tx_bd, tx_bd->bd_flags.as_bitfield);
-
- tx_buf->skb = skb;
-
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
-
- /* now send a tx doorbell, counting the next bd
- * if the packet contains or ends with it
- */
- if (TX_BD_POFF(bd_prod) < nbd)
- nbd++;
-
- if (pbd)
- DP(NETIF_MSG_TX_QUEUED,
- "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u"
- " tcp_flags %x xsum %x seq %u hlen %u\n",
- pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id,
- pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum,
- pbd->tcp_send_seq, pbd->total_hlen);
-
- DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u bd %d\n", nbd, bd_prod);
-
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
- mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, fp_index, 0);
-
- mmiowb();
-
- fp->tx_bd_prod = bd_prod;
- dev->trans_start = jiffies;
-
- if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
- netif_stop_queue(dev);
- bp->slowpath->eth_stats.driver_xoff++;
- if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
- netif_wake_queue(dev);
- }
- fp->tx_pkt++;
-
- return NETDEV_TX_OK;
-}
-
-/* Called with rtnl_lock */
-static int bnx2x_open(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bnx2x_set_power_state(bp, PCI_D0);
-
- return bnx2x_nic_load(bp, 1);
-}
-
-/* Called with rtnl_lock */
-static int bnx2x_close(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- /* Unload the driver, release IRQs */
- bnx2x_nic_unload(bp, 1);
-
- if (!CHIP_REV_IS_SLOW(bp))
- bnx2x_set_power_state(bp, PCI_D3hot);
-
- return 0;
-}
-
-/* Called with rtnl_lock */
-static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
-{
- struct sockaddr *addr = p;
- struct bnx2x *bp = netdev_priv(dev);
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EINVAL;
-
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- if (netif_running(dev))
- bnx2x_set_mac_addr(bp);
-
- return 0;
-}
-
-/* Called with rtnl_lock */
-static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- struct mii_ioctl_data *data = if_mii(ifr);
- struct bnx2x *bp = netdev_priv(dev);
- int err;
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = bp->phy_addr;
-
- /* fallthrough */
- case SIOCGMIIREG: {
- u32 mii_regval;
-
- spin_lock_bh(&bp->phy_lock);
- if (bp->state == BNX2X_STATE_OPEN) {
- err = bnx2x_mdio22_read(bp, data->reg_num & 0x1f,
- &mii_regval);
-
- data->val_out = mii_regval;
- } else {
- err = -EAGAIN;
- }
- spin_unlock_bh(&bp->phy_lock);
- return err;
- }
-
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- spin_lock_bh(&bp->phy_lock);
- if (bp->state == BNX2X_STATE_OPEN) {
- err = bnx2x_mdio22_write(bp, data->reg_num & 0x1f,
- data->val_in);
- } else {
- err = -EAGAIN;
- }
- spin_unlock_bh(&bp->phy_lock);
- return err;
-
- default:
- /* do nothing */
- break;
- }
-
- return -EOPNOTSUPP;
-}
-
-/* Called with rtnl_lock */
-static int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) ||
- ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE))
- return -EINVAL;
-
- /* This does not race with packet allocation
- * because the actual alloc size is
- * only updated as part of load
- */
- dev->mtu = new_mtu;
-
- if (netif_running(dev)) {
- bnx2x_nic_unload(bp, 0);
- bnx2x_nic_load(bp, 0);
- }
- return 0;
-}
-
-static void bnx2x_tx_timeout(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (!bp->panic)
- bnx2x_panic();
-#endif
- /* This allows the netif to be shutdown gracefully before resetting */
- schedule_work(&bp->reset_task);
-}
-
-#ifdef BCM_VLAN
-/* Called with rtnl_lock */
-static void bnx2x_vlan_rx_register(struct net_device *dev,
- struct vlan_group *vlgrp)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bp->vlgrp = vlgrp;
- if (netif_running(dev))
- bnx2x_set_client_config(bp);
-}
-#endif
-
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
-static void poll_bnx2x(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- disable_irq(bp->pdev->irq);
- bnx2x_interrupt(bp->pdev->irq, dev);
- enable_irq(bp->pdev->irq);
-}
-#endif
-
-static void bnx2x_reset_task(struct work_struct *work)
-{
- struct bnx2x *bp = container_of(work, struct bnx2x, reset_task);
-
-#ifdef BNX2X_STOP_ON_ERROR
- BNX2X_ERR("reset task called but STOP_ON_ERROR defined"
- " so reset not done to allow debug dump,\n"
- KERN_ERR " you will need to reboot when done\n");
- return;
-#endif
-
- if (!netif_running(bp->dev))
- return;
-
- rtnl_lock();
-
- if (bp->state != BNX2X_STATE_OPEN) {
- DP(NETIF_MSG_TX_ERR, "state is %x, returning\n", bp->state);
- goto reset_task_exit;
- }
-
- bnx2x_nic_unload(bp, 0);
- bnx2x_nic_load(bp, 0);
-
-reset_task_exit:
- rtnl_unlock();
-}
-
-static int __devinit bnx2x_init_board(struct pci_dev *pdev,
- struct net_device *dev)
-{
- struct bnx2x *bp;
- int rc;
-
- SET_NETDEV_DEV(dev, &pdev->dev);
- bp = netdev_priv(dev);
-
- bp->flags = 0;
- bp->port = PCI_FUNC(pdev->devfn);
-
- rc = pci_enable_device(pdev);
- if (rc) {
- printk(KERN_ERR PFX "Cannot enable PCI device, aborting\n");
- goto err_out;
- }
-
- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX "Cannot find PCI device base address,"
- " aborting\n");
- rc = -ENODEV;
- goto err_out_disable;
- }
-
- if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX "Cannot find second PCI device"
- " base address, aborting\n");
- rc = -ENODEV;
- goto err_out_disable;
- }
-
- rc = pci_request_regions(pdev, DRV_MODULE_NAME);
- if (rc) {
- printk(KERN_ERR PFX "Cannot obtain PCI resources,"
- " aborting\n");
- goto err_out_disable;
- }
-
- pci_set_master(pdev);
-
- bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
- if (bp->pm_cap == 0) {
- printk(KERN_ERR PFX "Cannot find power management"
- " capability, aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (bp->pcie_cap == 0) {
- printk(KERN_ERR PFX "Cannot find PCI Express capability,"
- " aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
- bp->flags |= USING_DAC_FLAG;
- if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
- printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
- " failed, aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
- printk(KERN_ERR PFX "System does not support DMA,"
- " aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- bp->dev = dev;
- bp->pdev = pdev;
-
- spin_lock_init(&bp->phy_lock);
-
- INIT_WORK(&bp->reset_task, bnx2x_reset_task);
- INIT_WORK(&bp->sp_task, bnx2x_sp_task);
-
- dev->base_addr = pci_resource_start(pdev, 0);
-
- dev->irq = pdev->irq;
-
- bp->regview = ioremap_nocache(dev->base_addr,
- pci_resource_len(pdev, 0));
- if (!bp->regview) {
- printk(KERN_ERR PFX "Cannot map register space, aborting\n");
- rc = -ENOMEM;
- goto err_out_release;
- }
-
- bp->doorbells = ioremap_nocache(pci_resource_start(pdev , 2),
- pci_resource_len(pdev, 2));
- if (!bp->doorbells) {
- printk(KERN_ERR PFX "Cannot map doorbell space, aborting\n");
- rc = -ENOMEM;
- goto err_out_unmap;
- }
-
- bnx2x_set_power_state(bp, PCI_D0);
-
- bnx2x_get_hwinfo(bp);
-
- if (CHIP_REV(bp) == CHIP_REV_FPGA) {
- printk(KERN_ERR PFX "FPGA detected. MCP disabled,"
- " will only init first device\n");
- onefunc = 1;
- nomcp = 1;
- }
-
- if (nomcp) {
- printk(KERN_ERR PFX "MCP disabled, will only"
- " init first device\n");
- onefunc = 1;
- }
-
- if (onefunc && bp->port) {
- printk(KERN_ERR PFX "Second device disabled, exiting\n");
- rc = -ENODEV;
- goto err_out_unmap;
- }
-
- bp->tx_ring_size = MAX_TX_AVAIL;
- bp->rx_ring_size = MAX_RX_AVAIL;
-
- bp->rx_csum = 1;
-
- bp->rx_offset = 0;
-
- bp->tx_quick_cons_trip_int = 0xff;
- bp->tx_quick_cons_trip = 0xff;
- bp->tx_ticks_int = 50;
- bp->tx_ticks = 50;
-
- bp->rx_quick_cons_trip_int = 0xff;
- bp->rx_quick_cons_trip = 0xff;
- bp->rx_ticks_int = 25;
- bp->rx_ticks = 25;
-
- bp->stats_ticks = 1000000 & 0xffff00;
-
- bp->timer_interval = HZ;
- bp->current_interval = (poll ? poll : HZ);
-
- init_timer(&bp->timer);
- bp->timer.expires = jiffies + bp->current_interval;
- bp->timer.data = (unsigned long) bp;
- bp->timer.function = bnx2x_timer;
-
- return 0;
-
-err_out_unmap:
- if (bp->regview) {
- iounmap(bp->regview);
- bp->regview = NULL;
- }
-
- if (bp->doorbells) {
- iounmap(bp->doorbells);
- bp->doorbells = NULL;
- }
-
-err_out_release:
- pci_release_regions(pdev);
-
-err_out_disable:
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
-
-err_out:
- return rc;
-}
-
-static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
-{
- u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
-
- val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
- return val;
-}
-
-/* return value of 1=2.5GHz 2=5GHz */
-static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
-{
- u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
-
- val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
- return val;
-}
-
-static int __devinit bnx2x_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- static int version_printed;
- struct net_device *dev = NULL;
- struct bnx2x *bp;
- int rc;
- int port = PCI_FUNC(pdev->devfn);
- DECLARE_MAC_BUF(mac);
-
- if (version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-
- /* dev zeroed in init_etherdev */
- dev = alloc_etherdev(sizeof(*bp));
- if (!dev)
- return -ENOMEM;
-
- netif_carrier_off(dev);
-
- bp = netdev_priv(dev);
- bp->msglevel = debug;
-
- if (port && onefunc) {
- printk(KERN_ERR PFX "second function disabled. exiting\n");
- free_netdev(dev);
- return 0;
- }
-
- rc = bnx2x_init_board(pdev, dev);
- if (rc < 0) {
- free_netdev(dev);
- return rc;
- }
-
- dev->hard_start_xmit = bnx2x_start_xmit;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- dev->ethtool_ops = &bnx2x_ethtool_ops;
- dev->open = bnx2x_open;
- dev->stop = bnx2x_close;
- dev->set_multicast_list = bnx2x_set_rx_mode;
- dev->set_mac_address = bnx2x_change_mac_addr;
- dev->do_ioctl = bnx2x_ioctl;
- dev->change_mtu = bnx2x_change_mtu;
- dev->tx_timeout = bnx2x_tx_timeout;
-#ifdef BCM_VLAN
- dev->vlan_rx_register = bnx2x_vlan_rx_register;
-#endif
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
- dev->poll_controller = poll_bnx2x;
-#endif
- dev->features |= NETIF_F_SG;
- if (bp->flags & USING_DAC_FLAG)
- dev->features |= NETIF_F_HIGHDMA;
- dev->features |= NETIF_F_IP_CSUM;
-#ifdef BCM_VLAN
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
- dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
-
- rc = register_netdev(dev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register net device\n");
- if (bp->regview)
- iounmap(bp->regview);
- if (bp->doorbells)
- iounmap(bp->doorbells);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- free_netdev(dev);
- return rc;
- }
-
- pci_set_drvdata(pdev, dev);
-
- bp->name = board_info[ent->driver_data].name;
- printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
- " IRQ %d, ", dev->name, bp->name,
- ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
- ((CHIP_ID(bp) & 0x0ff0) >> 4),
- bnx2x_get_pcie_width(bp),
- (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
- dev->base_addr, bp->pdev->irq);
- printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr));
- return 0;
-}
-
-static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp;
-
- if (!dev) {
- /* we get here if init_one() fails */
- printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
- return;
- }
-
- bp = netdev_priv(dev);
-
- unregister_netdev(dev);
-
- if (bp->regview)
- iounmap(bp->regview);
-
- if (bp->doorbells)
- iounmap(bp->doorbells);
-
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
-}
-
-static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp;
-
- if (!dev)
- return 0;
-
- if (!netif_running(dev))
- return 0;
-
- bp = netdev_priv(dev);
-
- bnx2x_nic_unload(bp, 0);
-
- netif_device_detach(dev);
-
- pci_save_state(pdev);
- bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static int bnx2x_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp;
- int rc;
-
- if (!dev) {
- printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
- return -ENODEV;
- }
-
- if (!netif_running(dev))
- return 0;
-
- bp = netdev_priv(dev);
-
- pci_restore_state(pdev);
- bnx2x_set_power_state(bp, PCI_D0);
- netif_device_attach(dev);
-
- rc = bnx2x_nic_load(bp, 0);
- if (rc)
- return rc;
-
- return 0;
-}
-
-static struct pci_driver bnx2x_pci_driver = {
- .name = DRV_MODULE_NAME,
- .id_table = bnx2x_pci_tbl,
- .probe = bnx2x_init_one,
- .remove = __devexit_p(bnx2x_remove_one),
- .suspend = bnx2x_suspend,
- .resume = bnx2x_resume,
-};
-
-static int __init bnx2x_init(void)
-{
- return pci_register_driver(&bnx2x_pci_driver);
-}
-
-static void __exit bnx2x_cleanup(void)
-{
- pci_unregister_driver(&bnx2x_pci_driver);
-}
-
-module_init(bnx2x_init);
-module_exit(bnx2x_cleanup);
-
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 8e68d06510a..4bf4f7b205f 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -14,39 +14,46 @@
#ifndef BNX2X_H
#define BNX2X_H
+/* compilation time flags */
+
+/* define this to make the driver freeze on error to allow getting debug info
+ * (you will need to reboot afterwards) */
+/* #define BNX2X_STOP_ON_ERROR */
+
/* error/debug prints */
-#define DRV_MODULE_NAME "bnx2x"
-#define PFX DRV_MODULE_NAME ": "
+#define DRV_MODULE_NAME "bnx2x"
+#define PFX DRV_MODULE_NAME ": "
/* for messages that are currently off */
-#define BNX2X_MSG_OFF 0
-#define BNX2X_MSG_MCP 0x10000 /* was: NETIF_MSG_HW */
-#define BNX2X_MSG_STATS 0x20000 /* was: NETIF_MSG_TIMER */
-#define NETIF_MSG_NVM 0x40000 /* was: NETIF_MSG_HW */
-#define NETIF_MSG_DMAE 0x80000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_OFF 0
+#define BNX2X_MSG_MCP 0x010000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_STATS 0x020000 /* was: NETIF_MSG_TIMER */
+#define BNX2X_MSG_NVM 0x040000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_DMAE 0x080000 /* was: NETIF_MSG_HW */
#define BNX2X_MSG_SP 0x100000 /* was: NETIF_MSG_INTR */
#define BNX2X_MSG_FP 0x200000 /* was: NETIF_MSG_INTR */
-#define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */
+#define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */
/* regular debug print */
#define DP(__mask, __fmt, __args...) do { \
if (bp->msglevel & (__mask)) \
- printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __FUNCTION__, \
- __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+ printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
+ bp->dev?(bp->dev->name):"?", ##__args); \
} while (0)
-/* for errors (never masked) */
-#define BNX2X_ERR(__fmt, __args...) do { \
- printk(KERN_ERR "[%s:%d(%s)]" __fmt, __FUNCTION__, \
- __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+/* errors debug print */
+#define BNX2X_DBG_ERR(__fmt, __args...) do { \
+ if (bp->msglevel & NETIF_MSG_PROBE) \
+ printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
+ bp->dev?(bp->dev->name):"?", ##__args); \
} while (0)
-/* for logging (never masked) */
-#define BNX2X_LOG(__fmt, __args...) do { \
- printk(KERN_NOTICE "[%s:%d(%s)]" __fmt, __FUNCTION__, \
- __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+/* for errors (never masked) */
+#define BNX2X_ERR(__fmt, __args...) do { \
+ printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
+ bp->dev?(bp->dev->name):"?", ##__args); \
} while (0)
/* before we have a dev->name use dev_info() */
@@ -60,7 +67,7 @@
#define bnx2x_panic() do { \
bp->panic = 1; \
BNX2X_ERR("driver assert\n"); \
- bnx2x_disable_int(bp); \
+ bnx2x_int_disable(bp); \
bnx2x_panic_dump(bp); \
} while (0)
#else
@@ -71,164 +78,412 @@
#endif
-#define U64_LO(x) (((u64)x) & 0xffffffff)
-#define U64_HI(x) (((u64)x) >> 32)
-#define HILO_U64(hi, lo) (((u64)hi << 32) + lo)
+#ifdef NETIF_F_HW_VLAN_TX
+#define BCM_VLAN 1
+#endif
+
+#define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff)
+#define U64_HI(x) (u32)(((u64)(x)) >> 32)
+#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
-#define REG_ADDR(bp, offset) (bp->regview + offset)
-#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
-#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
-#define REG_RD64(bp, offset) readq(REG_ADDR(bp, offset))
+#define REG_ADDR(bp, offset) (bp->regview + offset)
-#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
+#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
+#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
+#define REG_RD64(bp, offset) readq(REG_ADDR(bp, offset))
+
+#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
-#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
-#define REG_WR32(bp, offset, val) REG_WR(bp, offset, val)
+#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
+#define REG_WR32(bp, offset, val) REG_WR(bp, offset, val)
+
+#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
+#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
-#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
-#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
+#define REG_RD_DMAE(bp, offset, valp, len32) \
+ do { \
+ bnx2x_read_dmae(bp, offset, len32);\
+ memcpy(valp, bnx2x_sp(bp, wb_data[0]), len32 * 4); \
+ } while (0)
-#define REG_WR_DMAE(bp, offset, val, len32) \
+#define REG_WR_DMAE(bp, offset, valp, len32) \
do { \
- memcpy(bnx2x_sp(bp, wb_data[0]), val, len32 * 4); \
+ memcpy(bnx2x_sp(bp, wb_data[0]), valp, len32 * 4); \
bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \
offset, len32); \
} while (0)
-#define SHMEM_RD(bp, type) \
- REG_RD(bp, bp->shmem_base + offsetof(struct shmem_region, type))
-#define SHMEM_WR(bp, type, val) \
- REG_WR(bp, bp->shmem_base + offsetof(struct shmem_region, type), val)
+#define SHMEM_ADDR(bp, field) (bp->common.shmem_base + \
+ offsetof(struct shmem_region, field))
+#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field))
+#define SHMEM_WR(bp, field, val) REG_WR(bp, SHMEM_ADDR(bp, field), val)
#define NIG_WR(reg, val) REG_WR(bp, reg, val)
-#define EMAC_WR(reg, val) REG_WR(bp, emac_base + reg, val)
-#define BMAC_WR(reg, val) REG_WR(bp, GRCBASE_NIG + bmac_addr + reg, val)
+#define EMAC_WR(reg, val) REG_WR(bp, emac_base + reg, val)
+#define BMAC_WR(reg, val) REG_WR(bp, GRCBASE_NIG + bmac_addr + reg, val)
-#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
+#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
#define for_each_nondefault_queue(bp, var) \
for (var = 1; var < bp->num_queues; var++)
-#define is_multi(bp) (bp->num_queues > 1)
+#define is_multi(bp) (bp->num_queues > 1)
-struct regp {
- u32 lo;
- u32 hi;
+/* fast path */
+
+struct sw_rx_bd {
+ struct sk_buff *skb;
+ DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+struct sw_tx_bd {
+ struct sk_buff *skb;
+ u16 first_bd;
};
-struct bmac_stats {
- struct regp tx_gtpkt;
- struct regp tx_gtxpf;
- struct regp tx_gtfcs;
- struct regp tx_gtmca;
- struct regp tx_gtgca;
- struct regp tx_gtfrg;
- struct regp tx_gtovr;
- struct regp tx_gt64;
- struct regp tx_gt127;
- struct regp tx_gt255; /* 10 */
- struct regp tx_gt511;
- struct regp tx_gt1023;
- struct regp tx_gt1518;
- struct regp tx_gt2047;
- struct regp tx_gt4095;
- struct regp tx_gt9216;
- struct regp tx_gt16383;
- struct regp tx_gtmax;
- struct regp tx_gtufl;
- struct regp tx_gterr; /* 20 */
- struct regp tx_gtbyt;
-
- struct regp rx_gr64;
- struct regp rx_gr127;
- struct regp rx_gr255;
- struct regp rx_gr511;
- struct regp rx_gr1023;
- struct regp rx_gr1518;
- struct regp rx_gr2047;
- struct regp rx_gr4095;
- struct regp rx_gr9216; /* 30 */
- struct regp rx_gr16383;
- struct regp rx_grmax;
- struct regp rx_grpkt;
- struct regp rx_grfcs;
- struct regp rx_grmca;
- struct regp rx_grbca;
- struct regp rx_grxcf;
- struct regp rx_grxpf;
- struct regp rx_grxuo;
- struct regp rx_grjbr; /* 40 */
- struct regp rx_grovr;
- struct regp rx_grflr;
- struct regp rx_grmeg;
- struct regp rx_grmeb;
- struct regp rx_grbyt;
- struct regp rx_grund;
- struct regp rx_grfrg;
- struct regp rx_grerb;
- struct regp rx_grfre;
- struct regp rx_gripj; /* 50 */
+struct sw_rx_page {
+ struct page *page;
+ DECLARE_PCI_UNMAP_ADDR(mapping)
};
-struct emac_stats {
- u32 rx_ifhcinoctets ;
- u32 rx_ifhcinbadoctets ;
- u32 rx_etherstatsfragments ;
- u32 rx_ifhcinucastpkts ;
- u32 rx_ifhcinmulticastpkts ;
- u32 rx_ifhcinbroadcastpkts ;
- u32 rx_dot3statsfcserrors ;
- u32 rx_dot3statsalignmenterrors ;
- u32 rx_dot3statscarriersenseerrors ;
- u32 rx_xonpauseframesreceived ; /* 10 */
- u32 rx_xoffpauseframesreceived ;
- u32 rx_maccontrolframesreceived ;
- u32 rx_xoffstateentered ;
- u32 rx_dot3statsframestoolong ;
- u32 rx_etherstatsjabbers ;
- u32 rx_etherstatsundersizepkts ;
- u32 rx_etherstatspkts64octets ;
- u32 rx_etherstatspkts65octetsto127octets ;
- u32 rx_etherstatspkts128octetsto255octets ;
- u32 rx_etherstatspkts256octetsto511octets ; /* 20 */
- u32 rx_etherstatspkts512octetsto1023octets ;
- u32 rx_etherstatspkts1024octetsto1522octets;
- u32 rx_etherstatspktsover1522octets ;
-
- u32 rx_falsecarriererrors ;
-
- u32 tx_ifhcoutoctets ;
- u32 tx_ifhcoutbadoctets ;
- u32 tx_etherstatscollisions ;
- u32 tx_outxonsent ;
- u32 tx_outxoffsent ;
- u32 tx_flowcontroldone ; /* 30 */
- u32 tx_dot3statssinglecollisionframes ;
- u32 tx_dot3statsmultiplecollisionframes ;
- u32 tx_dot3statsdeferredtransmissions ;
- u32 tx_dot3statsexcessivecollisions ;
- u32 tx_dot3statslatecollisions ;
- u32 tx_ifhcoutucastpkts ;
- u32 tx_ifhcoutmulticastpkts ;
- u32 tx_ifhcoutbroadcastpkts ;
- u32 tx_etherstatspkts64octets ;
- u32 tx_etherstatspkts65octetsto127octets ; /* 40 */
- u32 tx_etherstatspkts128octetsto255octets ;
- u32 tx_etherstatspkts256octetsto511octets ;
- u32 tx_etherstatspkts512octetsto1023octets ;
- u32 tx_etherstatspkts1024octetsto1522octet ;
- u32 tx_etherstatspktsover1522octets ;
- u32 tx_dot3statsinternalmactransmiterrors ; /* 46 */
+
+/* MC hsi */
+#define BCM_PAGE_SHIFT 12
+#define BCM_PAGE_SIZE (1 << BCM_PAGE_SHIFT)
+#define BCM_PAGE_MASK (~(BCM_PAGE_SIZE - 1))
+#define BCM_PAGE_ALIGN(addr) (((addr) + BCM_PAGE_SIZE - 1) & BCM_PAGE_MASK)
+
+#define PAGES_PER_SGE_SHIFT 0
+#define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT)
+
+/* SGE ring related macros */
+#define NUM_RX_SGE_PAGES 2
+#define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
+#define MAX_RX_SGE_CNT (RX_SGE_CNT - 2)
+/* RX_SGE_CNT is promissed to be a power of 2 */
+#define RX_SGE_MASK (RX_SGE_CNT - 1)
+#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES)
+#define MAX_RX_SGE (NUM_RX_SGE - 1)
+#define NEXT_SGE_IDX(x) ((((x) & RX_SGE_MASK) == \
+ (MAX_RX_SGE_CNT - 1)) ? (x) + 3 : (x) + 1)
+#define RX_SGE(x) ((x) & MAX_RX_SGE)
+
+/* SGE producer mask related macros */
+/* Number of bits in one sge_mask array element */
+#define RX_SGE_MASK_ELEM_SZ 64
+#define RX_SGE_MASK_ELEM_SHIFT 6
+#define RX_SGE_MASK_ELEM_MASK ((u64)RX_SGE_MASK_ELEM_SZ - 1)
+
+/* Creates a bitmask of all ones in less significant bits.
+ idx - index of the most significant bit in the created mask */
+#define RX_SGE_ONES_MASK(idx) \
+ (((u64)0x1 << (((idx) & RX_SGE_MASK_ELEM_MASK) + 1)) - 1)
+#define RX_SGE_MASK_ELEM_ONE_MASK ((u64)(~0))
+
+/* Number of u64 elements in SGE mask array */
+#define RX_SGE_MASK_LEN ((NUM_RX_SGE_PAGES * RX_SGE_CNT) / \
+ RX_SGE_MASK_ELEM_SZ)
+#define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1)
+#define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK)
+
+
+struct bnx2x_fastpath {
+
+ struct napi_struct napi;
+
+ struct host_status_block *status_blk;
+ dma_addr_t status_blk_mapping;
+
+ struct eth_tx_db_data *hw_tx_prods;
+ dma_addr_t tx_prods_mapping;
+
+ struct sw_tx_bd *tx_buf_ring;
+
+ struct eth_tx_bd *tx_desc_ring;
+ dma_addr_t tx_desc_mapping;
+
+ struct sw_rx_bd *rx_buf_ring; /* BDs mappings ring */
+ struct sw_rx_page *rx_page_ring; /* SGE pages mappings ring */
+
+ struct eth_rx_bd *rx_desc_ring;
+ dma_addr_t rx_desc_mapping;
+
+ union eth_rx_cqe *rx_comp_ring;
+ dma_addr_t rx_comp_mapping;
+
+ /* SGE ring */
+ struct eth_rx_sge *rx_sge_ring;
+ dma_addr_t rx_sge_mapping;
+
+ u64 sge_mask[RX_SGE_MASK_LEN];
+
+ int state;
+#define BNX2X_FP_STATE_CLOSED 0
+#define BNX2X_FP_STATE_IRQ 0x80000
+#define BNX2X_FP_STATE_OPENING 0x90000
+#define BNX2X_FP_STATE_OPEN 0xa0000
+#define BNX2X_FP_STATE_HALTING 0xb0000
+#define BNX2X_FP_STATE_HALTED 0xc0000
+
+ u8 index; /* number in fp array */
+ u8 cl_id; /* eth client id */
+ u8 sb_id; /* status block number in HW */
+#define FP_IDX(fp) (fp->index)
+#define FP_CL_ID(fp) (fp->cl_id)
+#define BP_CL_ID(bp) (bp->fp[0].cl_id)
+#define FP_SB_ID(fp) (fp->sb_id)
+#define CNIC_SB_ID 0
+
+ u16 tx_pkt_prod;
+ u16 tx_pkt_cons;
+ u16 tx_bd_prod;
+ u16 tx_bd_cons;
+ u16 *tx_cons_sb;
+
+ u16 fp_c_idx;
+ u16 fp_u_idx;
+
+ u16 rx_bd_prod;
+ u16 rx_bd_cons;
+ u16 rx_comp_prod;
+ u16 rx_comp_cons;
+ u16 rx_sge_prod;
+ /* The last maximal completed SGE */
+ u16 last_max_sge;
+ u16 *rx_cons_sb;
+ u16 *rx_bd_cons_sb;
+
+ unsigned long tx_pkt,
+ rx_pkt,
+ rx_calls,
+ rx_alloc_failed;
+ /* TPA related */
+ struct sw_rx_bd tpa_pool[ETH_MAX_AGGREGATION_QUEUES_E1H];
+ u8 tpa_state[ETH_MAX_AGGREGATION_QUEUES_E1H];
+#define BNX2X_TPA_START 1
+#define BNX2X_TPA_STOP 2
+ u8 disable_tpa;
+#ifdef BNX2X_STOP_ON_ERROR
+ u64 tpa_queue_used;
+#endif
+
+ struct bnx2x *bp; /* parent */
};
-union mac_stats {
- struct emac_stats emac;
- struct bmac_stats bmac;
+#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
+
+
+/* MC hsi */
+#define MAX_FETCH_BD 13 /* HW max BDs per packet */
+#define RX_COPY_THRESH 92
+
+#define NUM_TX_RINGS 16
+#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_tx_bd))
+#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
+#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS)
+#define MAX_TX_BD (NUM_TX_BD - 1)
+#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
+#define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \
+ (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
+#define TX_BD(x) ((x) & MAX_TX_BD)
+#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT)
+
+/* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */
+#define NUM_RX_RINGS 8
+#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
+#define MAX_RX_DESC_CNT (RX_DESC_CNT - 2)
+#define RX_DESC_MASK (RX_DESC_CNT - 1)
+#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS)
+#define MAX_RX_BD (NUM_RX_BD - 1)
+#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
+#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
+ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
+#define RX_BD(x) ((x) & MAX_RX_BD)
+
+/* As long as CQE is 4 times bigger than BD entry we have to allocate
+ 4 times more pages for CQ ring in order to keep it balanced with
+ BD ring */
+#define NUM_RCQ_RINGS (NUM_RX_RINGS * 4)
+#define RCQ_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
+#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - 1)
+#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS)
+#define MAX_RCQ_BD (NUM_RCQ_BD - 1)
+#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2)
+#define NEXT_RCQ_IDX(x) ((((x) & MAX_RCQ_DESC_CNT) == \
+ (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
+#define RCQ_BD(x) ((x) & MAX_RCQ_BD)
+
+
+/* This is needed for determening of last_max */
+#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b))
+
+#define __SGE_MASK_SET_BIT(el, bit) \
+ do { \
+ el = ((el) | ((u64)0x1 << (bit))); \
+ } while (0)
+
+#define __SGE_MASK_CLEAR_BIT(el, bit) \
+ do { \
+ el = ((el) & (~((u64)0x1 << (bit)))); \
+ } while (0)
+
+#define SGE_MASK_SET_BIT(fp, idx) \
+ __SGE_MASK_SET_BIT(fp->sge_mask[(idx) >> RX_SGE_MASK_ELEM_SHIFT], \
+ ((idx) & RX_SGE_MASK_ELEM_MASK))
+
+#define SGE_MASK_CLEAR_BIT(fp, idx) \
+ __SGE_MASK_CLEAR_BIT(fp->sge_mask[(idx) >> RX_SGE_MASK_ELEM_SHIFT], \
+ ((idx) & RX_SGE_MASK_ELEM_MASK))
+
+
+/* used on a CID received from the HW */
+#define SW_CID(x) (le32_to_cpu(x) & \
+ (COMMON_RAMROD_ETH_RX_CQE_CID >> 7))
+#define CQE_CMD(x) (le32_to_cpu(x) >> \
+ COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT)
+
+#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \
+ le32_to_cpu((bd)->addr_lo))
+#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
+
+
+#define DPM_TRIGER_TYPE 0x40
+#define DOORBELL(bp, cid, val) \
+ do { \
+ writel((u32)val, (bp)->doorbells + (BCM_PAGE_SIZE * cid) + \
+ DPM_TRIGER_TYPE); \
+ } while (0)
+
+
+/* TX CSUM helpers */
+#define SKB_CS_OFF(skb) (offsetof(struct tcphdr, check) - \
+ skb->csum_offset)
+#define SKB_CS(skb) (*(u16 *)(skb_transport_header(skb) + \
+ skb->csum_offset))
+
+#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff)
+
+#define XMIT_PLAIN 0
+#define XMIT_CSUM_V4 0x1
+#define XMIT_CSUM_V6 0x2
+#define XMIT_CSUM_TCP 0x4
+#define XMIT_GSO_V4 0x8
+#define XMIT_GSO_V6 0x10
+
+#define XMIT_CSUM (XMIT_CSUM_V4 | XMIT_CSUM_V6)
+#define XMIT_GSO (XMIT_GSO_V4 | XMIT_GSO_V6)
+
+
+/* stuff added to make the code fit 80Col */
+
+#define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE)
+
+#define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG
+#define TPA_TYPE_END ETH_FAST_PATH_RX_CQE_END_FLG
+#define TPA_TYPE(cqe_fp_flags) ((cqe_fp_flags) & \
+ (TPA_TYPE_START | TPA_TYPE_END))
+
+#define BNX2X_RX_SUM_OK(cqe) \
+ (!(cqe->fast_path_cqe.status_flags & \
+ (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | \
+ ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)))
+
+#define BNX2X_RX_SUM_FIX(cqe) \
+ ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
+ (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
+
+#define ETH_RX_ERROR_FALGS (ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG | \
+ ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | \
+ ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)
+
+
+#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
+#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES)
+
+#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS
+#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS
+#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS
+
+#define BNX2X_RX_SB_INDEX \
+ (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX])
+
+#define BNX2X_RX_SB_BD_INDEX \
+ (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX])
+
+#define BNX2X_RX_SB_INDEX_NUM \
+ (((U_SB_ETH_RX_CQ_INDEX << \
+ USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \
+ USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \
+ ((U_SB_ETH_RX_BD_INDEX << \
+ USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \
+ USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER))
+
+#define BNX2X_TX_SB_INDEX \
+ (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX])
+
+
+/* end of fast path */
+
+/* common */
+
+struct bnx2x_common {
+
+ u32 chip_id;
+/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+#define CHIP_ID(bp) (bp->common.chip_id & 0xfffffff0)
+
+#define CHIP_NUM(bp) (bp->common.chip_id >> 16)
+#define CHIP_NUM_57710 0x164e
+#define CHIP_NUM_57711 0x164f
+#define CHIP_NUM_57711E 0x1650
+#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
+#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711)
+#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E)
+#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
+ CHIP_IS_57711E(bp))
+#define IS_E1H_OFFSET CHIP_IS_E1H(bp)
+
+#define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000)
+#define CHIP_REV_Ax 0x00000000
+/* assume maximum 5 revisions */
+#define CHIP_REV_IS_SLOW(bp) (CHIP_REV(bp) > 0x00005000)
+/* Emul versions are A=>0xe, B=>0xc, C=>0xa, D=>8, E=>6 */
+#define CHIP_REV_IS_EMUL(bp) ((CHIP_REV_IS_SLOW(bp)) && \
+ !(CHIP_REV(bp) & 0x00001000))
+/* FPGA versions are A=>0xf, B=>0xd, C=>0xb, D=>9, E=>7 */
+#define CHIP_REV_IS_FPGA(bp) ((CHIP_REV_IS_SLOW(bp)) && \
+ (CHIP_REV(bp) & 0x00001000))
+
+#define CHIP_TIME(bp) ((CHIP_REV_IS_EMUL(bp)) ? 2000 : \
+ ((CHIP_REV_IS_FPGA(bp)) ? 200 : 1))
+
+#define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0)
+#define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f)
+
+ int flash_size;
+#define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */
+#define NVRAM_TIMEOUT_COUNT 30000
+#define NVRAM_PAGE_SIZE 256
+
+ u32 shmem_base;
+
+ u32 hw_config;
+ u32 board;
+
+ u32 bc_ver;
+
+ char *name;
};
+
+/* end of common */
+
+/* port */
+
struct nig_stats {
u32 brb_discard;
u32 brb_packet;
@@ -244,13 +499,53 @@ struct nig_stats {
u32 pbf_octets;
u32 pbf_packet;
u32 safc_inp;
- u32 done;
- u32 pad;
+ u32 egress_mac_pkt0_lo;
+ u32 egress_mac_pkt0_hi;
+ u32 egress_mac_pkt1_lo;
+ u32 egress_mac_pkt1_hi;
+};
+
+struct bnx2x_port {
+ u32 pmf;
+
+ u32 link_config;
+
+ u32 supported;
+/* link settings - missing defines */
+#define SUPPORTED_2500baseX_Full (1 << 15)
+
+ u32 advertising;
+/* link settings - missing defines */
+#define ADVERTISED_2500baseX_Full (1 << 15)
+
+ u32 phy_addr;
+
+ /* used to synchronize phy accesses */
+ struct mutex phy_mutex;
+
+ u32 port_stx;
+
+ struct nig_stats old_nig_stats;
+};
+
+/* end of port */
+
+
+enum bnx2x_stats_event {
+ STATS_EVENT_PMF = 0,
+ STATS_EVENT_LINK_UP,
+ STATS_EVENT_UPDATE,
+ STATS_EVENT_STOP,
+ STATS_EVENT_MAX
+};
+
+enum bnx2x_stats_state {
+ STATS_STATE_DISABLED = 0,
+ STATS_STATE_ENABLED,
+ STATS_STATE_MAX
};
struct bnx2x_eth_stats {
- u32 pad; /* to make long counters u64 aligned */
- u32 mac_stx_start;
u32 total_bytes_received_hi;
u32 total_bytes_received_lo;
u32 total_bytes_transmitted_hi;
@@ -267,97 +562,117 @@ struct bnx2x_eth_stats {
u32 total_multicast_packets_transmitted_lo;
u32 total_broadcast_packets_transmitted_hi;
u32 total_broadcast_packets_transmitted_lo;
- u32 crc_receive_errors;
- u32 alignment_errors;
- u32 false_carrier_detections;
- u32 runt_packets_received;
- u32 jabber_packets_received;
- u32 pause_xon_frames_received;
- u32 pause_xoff_frames_received;
- u32 pause_xon_frames_transmitted;
- u32 pause_xoff_frames_transmitted;
- u32 single_collision_transmit_frames;
- u32 multiple_collision_transmit_frames;
- u32 late_collision_frames;
- u32 excessive_collision_frames;
- u32 control_frames_received;
- u32 frames_received_64_bytes;
- u32 frames_received_65_127_bytes;
- u32 frames_received_128_255_bytes;
- u32 frames_received_256_511_bytes;
- u32 frames_received_512_1023_bytes;
- u32 frames_received_1024_1522_bytes;
- u32 frames_received_1523_9022_bytes;
- u32 frames_transmitted_64_bytes;
- u32 frames_transmitted_65_127_bytes;
- u32 frames_transmitted_128_255_bytes;
- u32 frames_transmitted_256_511_bytes;
- u32 frames_transmitted_512_1023_bytes;
- u32 frames_transmitted_1024_1522_bytes;
- u32 frames_transmitted_1523_9022_bytes;
u32 valid_bytes_received_hi;
u32 valid_bytes_received_lo;
- u32 error_runt_packets_received;
- u32 error_jabber_packets_received;
- u32 mac_stx_end;
-
- u32 pad2;
- u32 stat_IfHCInBadOctets_hi;
- u32 stat_IfHCInBadOctets_lo;
- u32 stat_IfHCOutBadOctets_hi;
- u32 stat_IfHCOutBadOctets_lo;
- u32 stat_Dot3statsFramesTooLong;
- u32 stat_Dot3statsInternalMacTransmitErrors;
- u32 stat_Dot3StatsCarrierSenseErrors;
- u32 stat_Dot3StatsDeferredTransmissions;
- u32 stat_FlowControlDone;
- u32 stat_XoffStateEntered;
-
- u32 x_total_sent_bytes_hi;
- u32 x_total_sent_bytes_lo;
- u32 x_total_sent_pkts;
-
- u32 t_rcv_unicast_bytes_hi;
- u32 t_rcv_unicast_bytes_lo;
- u32 t_rcv_broadcast_bytes_hi;
- u32 t_rcv_broadcast_bytes_lo;
- u32 t_rcv_multicast_bytes_hi;
- u32 t_rcv_multicast_bytes_lo;
- u32 t_total_rcv_pkt;
-
- u32 checksum_discard;
- u32 packets_too_big_discard;
+
+ u32 error_bytes_received_hi;
+ u32 error_bytes_received_lo;
+
+ u32 rx_stat_ifhcinbadoctets_hi;
+ u32 rx_stat_ifhcinbadoctets_lo;
+ u32 tx_stat_ifhcoutbadoctets_hi;
+ u32 tx_stat_ifhcoutbadoctets_lo;
+ u32 rx_stat_dot3statsfcserrors_hi;
+ u32 rx_stat_dot3statsfcserrors_lo;
+ u32 rx_stat_dot3statsalignmenterrors_hi;
+ u32 rx_stat_dot3statsalignmenterrors_lo;
+ u32 rx_stat_dot3statscarriersenseerrors_hi;
+ u32 rx_stat_dot3statscarriersenseerrors_lo;
+ u32 rx_stat_falsecarriererrors_hi;
+ u32 rx_stat_falsecarriererrors_lo;
+ u32 rx_stat_etherstatsundersizepkts_hi;
+ u32 rx_stat_etherstatsundersizepkts_lo;
+ u32 rx_stat_dot3statsframestoolong_hi;
+ u32 rx_stat_dot3statsframestoolong_lo;
+ u32 rx_stat_etherstatsfragments_hi;
+ u32 rx_stat_etherstatsfragments_lo;
+ u32 rx_stat_etherstatsjabbers_hi;
+ u32 rx_stat_etherstatsjabbers_lo;
+ u32 rx_stat_maccontrolframesreceived_hi;
+ u32 rx_stat_maccontrolframesreceived_lo;
+ u32 rx_stat_bmac_xpf_hi;
+ u32 rx_stat_bmac_xpf_lo;
+ u32 rx_stat_bmac_xcf_hi;
+ u32 rx_stat_bmac_xcf_lo;
+ u32 rx_stat_xoffstateentered_hi;
+ u32 rx_stat_xoffstateentered_lo;
+ u32 rx_stat_xonpauseframesreceived_hi;
+ u32 rx_stat_xonpauseframesreceived_lo;
+ u32 rx_stat_xoffpauseframesreceived_hi;
+ u32 rx_stat_xoffpauseframesreceived_lo;
+ u32 tx_stat_outxonsent_hi;
+ u32 tx_stat_outxonsent_lo;
+ u32 tx_stat_outxoffsent_hi;
+ u32 tx_stat_outxoffsent_lo;
+ u32 tx_stat_flowcontroldone_hi;
+ u32 tx_stat_flowcontroldone_lo;
+ u32 tx_stat_etherstatscollisions_hi;
+ u32 tx_stat_etherstatscollisions_lo;
+ u32 tx_stat_dot3statssinglecollisionframes_hi;
+ u32 tx_stat_dot3statssinglecollisionframes_lo;
+ u32 tx_stat_dot3statsmultiplecollisionframes_hi;
+ u32 tx_stat_dot3statsmultiplecollisionframes_lo;
+ u32 tx_stat_dot3statsdeferredtransmissions_hi;
+ u32 tx_stat_dot3statsdeferredtransmissions_lo;
+ u32 tx_stat_dot3statsexcessivecollisions_hi;
+ u32 tx_stat_dot3statsexcessivecollisions_lo;
+ u32 tx_stat_dot3statslatecollisions_hi;
+ u32 tx_stat_dot3statslatecollisions_lo;
+ u32 tx_stat_etherstatspkts64octets_hi;
+ u32 tx_stat_etherstatspkts64octets_lo;
+ u32 tx_stat_etherstatspkts65octetsto127octets_hi;
+ u32 tx_stat_etherstatspkts65octetsto127octets_lo;
+ u32 tx_stat_etherstatspkts128octetsto255octets_hi;
+ u32 tx_stat_etherstatspkts128octetsto255octets_lo;
+ u32 tx_stat_etherstatspkts256octetsto511octets_hi;
+ u32 tx_stat_etherstatspkts256octetsto511octets_lo;
+ u32 tx_stat_etherstatspkts512octetsto1023octets_hi;
+ u32 tx_stat_etherstatspkts512octetsto1023octets_lo;
+ u32 tx_stat_etherstatspkts1024octetsto1522octets_hi;
+ u32 tx_stat_etherstatspkts1024octetsto1522octets_lo;
+ u32 tx_stat_etherstatspktsover1522octets_hi;
+ u32 tx_stat_etherstatspktsover1522octets_lo;
+ u32 tx_stat_bmac_2047_hi;
+ u32 tx_stat_bmac_2047_lo;
+ u32 tx_stat_bmac_4095_hi;
+ u32 tx_stat_bmac_4095_lo;
+ u32 tx_stat_bmac_9216_hi;
+ u32 tx_stat_bmac_9216_lo;
+ u32 tx_stat_bmac_16383_hi;
+ u32 tx_stat_bmac_16383_lo;
+ u32 tx_stat_dot3statsinternalmactransmiterrors_hi;
+ u32 tx_stat_dot3statsinternalmactransmiterrors_lo;
+ u32 tx_stat_bmac_ufl_hi;
+ u32 tx_stat_bmac_ufl_lo;
+
+ u32 brb_drop_hi;
+ u32 brb_drop_lo;
+
+ u32 jabber_packets_received;
+
+ u32 etherstatspkts1024octetsto1522octets_hi;
+ u32 etherstatspkts1024octetsto1522octets_lo;
+ u32 etherstatspktsover1522octets_hi;
+ u32 etherstatspktsover1522octets_lo;
+
u32 no_buff_discard;
- u32 ttl0_discard;
- u32 mac_discard;
+
u32 mac_filter_discard;
u32 xxoverflow_discard;
u32 brb_truncate_discard;
+ u32 mac_discard;
- u32 brb_discard;
- u32 brb_packet;
- u32 brb_truncate;
- u32 flow_ctrl_discard;
- u32 flow_ctrl_octets;
- u32 flow_ctrl_packet;
- u32 mng_discard;
- u32 mng_octet_inp;
- u32 mng_octet_out;
- u32 mng_packet_inp;
- u32 mng_packet_out;
- u32 pbf_octets;
- u32 pbf_packet;
- u32 safc_inp;
u32 driver_xoff;
- u32 number_of_bugs_found_in_stats_spec; /* just kidding */
};
-#define MAC_STX_NA 0xffffffff
+#define STATS_OFFSET32(stat_name) \
+ (offsetof(struct bnx2x_eth_stats, stat_name) / 4)
+
#ifdef BNX2X_MULTI
-#define MAX_CONTEXT 16
+#define MAX_CONTEXT 16
#else
-#define MAX_CONTEXT 1
+#define MAX_CONTEXT 1
#endif
union cdu_context {
@@ -365,345 +680,191 @@ union cdu_context {
char pad[1024];
};
-#define MAX_DMAE_C 5
+#define MAX_DMAE_C 8
/* DMA memory not used in fastpath */
struct bnx2x_slowpath {
- union cdu_context context[MAX_CONTEXT];
- struct eth_stats_query fw_stats;
- struct mac_configuration_cmd mac_config;
- struct mac_configuration_cmd mcast_config;
+ union cdu_context context[MAX_CONTEXT];
+ struct eth_stats_query fw_stats;
+ struct mac_configuration_cmd mac_config;
+ struct mac_configuration_cmd mcast_config;
/* used by dmae command executer */
- struct dmae_command dmae[MAX_DMAE_C];
+ struct dmae_command dmae[MAX_DMAE_C];
- union mac_stats mac_stats;
- struct nig_stats nig;
- struct bnx2x_eth_stats eth_stats;
+ u32 stats_comp;
+ union mac_stats mac_stats;
+ struct nig_stats nig_stats;
+ struct host_port_stats port_stats;
+ struct host_func_stats func_stats;
- u32 wb_comp;
-#define BNX2X_WB_COMP_VAL 0xe0d0d0ae
- u32 wb_data[4];
+ u32 wb_comp;
+ u32 wb_data[4];
};
-#define bnx2x_sp(bp, var) (&bp->slowpath->var)
-#define bnx2x_sp_check(bp, var) ((bp->slowpath) ? (&bp->slowpath->var) : NULL)
+#define bnx2x_sp(bp, var) (&bp->slowpath->var)
#define bnx2x_sp_mapping(bp, var) \
(bp->slowpath_mapping + offsetof(struct bnx2x_slowpath, var))
-struct sw_rx_bd {
- struct sk_buff *skb;
- DECLARE_PCI_UNMAP_ADDR(mapping)
-};
-
-struct sw_tx_bd {
- struct sk_buff *skb;
- u16 first_bd;
-};
-
-struct bnx2x_fastpath {
-
- struct napi_struct napi;
-
- struct host_status_block *status_blk;
- dma_addr_t status_blk_mapping;
-
- struct eth_tx_db_data *hw_tx_prods;
- dma_addr_t tx_prods_mapping;
-
- struct sw_tx_bd *tx_buf_ring;
-
- struct eth_tx_bd *tx_desc_ring;
- dma_addr_t tx_desc_mapping;
-
- struct sw_rx_bd *rx_buf_ring;
-
- struct eth_rx_bd *rx_desc_ring;
- dma_addr_t rx_desc_mapping;
-
- union eth_rx_cqe *rx_comp_ring;
- dma_addr_t rx_comp_mapping;
-
- int state;
-#define BNX2X_FP_STATE_CLOSED 0
-#define BNX2X_FP_STATE_IRQ 0x80000
-#define BNX2X_FP_STATE_OPENING 0x90000
-#define BNX2X_FP_STATE_OPEN 0xa0000
-#define BNX2X_FP_STATE_HALTING 0xb0000
-#define BNX2X_FP_STATE_HALTED 0xc0000
-
- int index;
-
- u16 tx_pkt_prod;
- u16 tx_pkt_cons;
- u16 tx_bd_prod;
- u16 tx_bd_cons;
- u16 *tx_cons_sb;
-
- u16 fp_c_idx;
- u16 fp_u_idx;
-
- u16 rx_bd_prod;
- u16 rx_bd_cons;
- u16 rx_comp_prod;
- u16 rx_comp_cons;
- u16 *rx_cons_sb;
-
- unsigned long tx_pkt,
- rx_pkt,
- rx_calls;
-
- struct bnx2x *bp; /* parent */
-};
-
-#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
-
-
/* attn group wiring */
-#define MAX_DYNAMIC_ATTN_GRPS 8
+#define MAX_DYNAMIC_ATTN_GRPS 8
struct attn_route {
- u32 sig[4];
+ u32 sig[4];
};
struct bnx2x {
/* Fields used in the tx and intr/napi performance paths
* are grouped together in the beginning of the structure
*/
- struct bnx2x_fastpath *fp;
- void __iomem *regview;
- void __iomem *doorbells;
+ struct bnx2x_fastpath fp[MAX_CONTEXT];
+ void __iomem *regview;
+ void __iomem *doorbells;
+#define BNX2X_DB_SIZE (16*2048)
- struct net_device *dev;
- struct pci_dev *pdev;
+ struct net_device *dev;
+ struct pci_dev *pdev;
atomic_t intr_sem;
- struct msix_entry msix_table[MAX_CONTEXT+1];
+ struct msix_entry msix_table[MAX_CONTEXT+1];
- int tx_ring_size;
+ int tx_ring_size;
#ifdef BCM_VLAN
- struct vlan_group *vlgrp;
+ struct vlan_group *vlgrp;
#endif
- u32 rx_csum;
- u32 rx_offset;
- u32 rx_buf_use_size; /* useable size */
- u32 rx_buf_size; /* with alignment */
-#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */
-#define ETH_MIN_PACKET_SIZE 60
-#define ETH_MAX_PACKET_SIZE 1500
-#define ETH_MAX_JUMBO_PACKET_SIZE 9600
+ u32 rx_csum;
+ u32 rx_offset;
+ u32 rx_buf_use_size; /* useable size */
+ u32 rx_buf_size; /* with alignment */
+#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */
+#define ETH_MIN_PACKET_SIZE 60
+#define ETH_MAX_PACKET_SIZE 1500
+#define ETH_MAX_JUMBO_PACKET_SIZE 9600
struct host_def_status_block *def_status_blk;
-#define DEF_SB_ID 16
- u16 def_c_idx;
- u16 def_u_idx;
- u16 def_t_idx;
- u16 def_x_idx;
- u16 def_att_idx;
- u32 attn_state;
- struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
- u32 aeu_mask;
- u32 nig_mask;
+#define DEF_SB_ID 16
+ u16 def_c_idx;
+ u16 def_u_idx;
+ u16 def_x_idx;
+ u16 def_t_idx;
+ u16 def_att_idx;
+ u32 attn_state;
+ struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
+ u32 aeu_mask;
+ u32 nig_mask;
/* slow path ring */
- struct eth_spe *spq;
- dma_addr_t spq_mapping;
- u16 spq_prod_idx;
- struct eth_spe *spq_prod_bd;
- struct eth_spe *spq_last_bd;
- u16 *dsb_sp_prod;
- u16 spq_left; /* serialize spq */
- spinlock_t spq_lock;
-
- /* Flag for marking that there is either
- * STAT_QUERY or CFC DELETE ramrod pending
- */
- u8 stat_pending;
-
- /* End of fields used in the performance code paths */
-
- int panic;
- int msglevel;
-
- 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_MSIX_FLAG 0x20
-#define ASF_ENABLE_FLAG 0x40
-
- int port;
-
- int pm_cap;
- int pcie_cap;
-
- /* Used to synchronize phy accesses */
- spinlock_t phy_lock;
-
- struct work_struct reset_task;
- struct work_struct sp_task;
-
- struct timer_list timer;
- int timer_interval;
- int current_interval;
-
- u32 shmem_base;
-
- u32 chip_id;
-/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
-#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
-
-#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
-
-#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_REV_EMUL 0x0000e000
-#define CHIP_REV_FPGA 0x0000f000
-#define CHIP_REV_IS_SLOW(bp) ((CHIP_REV(bp) == CHIP_REV_EMUL) || \
- (CHIP_REV(bp) == CHIP_REV_FPGA))
-
-#define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0)
-#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0x0000000f)
-
- u16 fw_seq;
- u16 fw_drv_pulse_wr_seq;
- u32 fw_mb;
-
- u32 hw_config;
- u32 board;
- u32 serdes_config;
- u32 lane_config;
- u32 ext_phy_config;
-#define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
-#define SERDES_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
-
- u32 speed_cap_mask;
- u32 link_config;
-#define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
-#define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
-#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
-#define SWITCH_CFG_ONE_TIME_DETECT \
- PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT
-
- u8 ser_lane;
- u8 rx_lane_swap;
- u8 tx_lane_swap;
-
- u8 link_up;
- u8 phy_link_up;
-
- u32 supported;
-/* link settings - missing defines */
-#define SUPPORTED_2500baseT_Full (1 << 15)
-
- u32 phy_flags;
-/*#define PHY_SERDES_FLAG 0x1*/
-#define PHY_BMAC_FLAG 0x2
-#define PHY_EMAC_FLAG 0x4
-#define PHY_XGXS_FLAG 0x8
-#define PHY_SGMII_FLAG 0x10
-#define PHY_INT_MODE_MASK_FLAG 0x300
-#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
-#define PHY_INT_MODE_LINK_READY_FLAG 0x200
-
- u32 phy_addr;
- u32 phy_id;
-
- u32 autoneg;
-#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
-#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
-#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
-#define AUTONEG_PARALLEL \
- SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
-#define AUTONEG_SGMII_FIBER_AUTODET \
- SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
-#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
-
- u32 req_autoneg;
-#define AUTONEG_SPEED 0x1
-#define AUTONEG_FLOW_CTRL 0x2
-
- u32 req_line_speed;
-/* link settings - missing defines */
-#define SPEED_12000 12000
-#define SPEED_12500 12500
-#define SPEED_13000 13000
-#define SPEED_15000 15000
-#define SPEED_16000 16000
-
- u32 req_duplex;
- u32 req_flow_ctrl;
-#define FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO
-#define FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX
-#define FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX
-#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
-#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
-
- u32 advertising;
-/* link settings - missing defines */
-#define ADVERTISED_2500baseT_Full (1 << 15)
-
- u32 link_status;
- u32 line_speed;
- u32 duplex;
- u32 flow_ctrl;
-
- u32 bc_ver;
-
- int flash_size;
-#define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */
-#define NVRAM_TIMEOUT_COUNT 30000
-#define NVRAM_PAGE_SIZE 256
+ struct eth_spe *spq;
+ dma_addr_t spq_mapping;
+ u16 spq_prod_idx;
+ struct eth_spe *spq_prod_bd;
+ struct eth_spe *spq_last_bd;
+ u16 *dsb_sp_prod;
+ u16 spq_left; /* serialize spq */
+ /* used to synchronize spq accesses */
+ spinlock_t spq_lock;
+
+ /* Flags for marking that there is a STAT_QUERY or
+ SET_MAC ramrod pending */
+ u8 stats_pending;
+ u8 set_mac_pending;
+
+ /* End of fileds used in the performance code paths */
+
+ int panic;
+ int msglevel;
+
+ 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_MSIX_FLAG 0x20
+#define ASF_ENABLE_FLAG 0x40
+#define TPA_ENABLE_FLAG 0x80
+#define NO_MCP_FLAG 0x100
+#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
+
+ int func;
+#define BP_PORT(bp) (bp->func % PORT_MAX)
+#define BP_FUNC(bp) (bp->func)
+#define BP_E1HVN(bp) (bp->func >> 1)
+#define BP_L_ID(bp) (BP_E1HVN(bp) << 2)
+/* assorted E1HVN */
+#define IS_E1HMF(bp) (bp->e1hmf != 0)
+#define BP_MAX_QUEUES(bp) (IS_E1HMF(bp) ? 4 : 16)
+
+ int pm_cap;
+ int pcie_cap;
+
+ struct work_struct sp_task;
+ struct work_struct reset_task;
+
+ struct timer_list timer;
+ int timer_interval;
+ int current_interval;
+
+ u16 fw_seq;
+ u16 fw_drv_pulse_wr_seq;
+ u32 func_stx;
+
+ struct link_params link_params;
+ struct link_vars link_vars;
+
+ struct bnx2x_common common;
+ struct bnx2x_port port;
+
+ u32 mf_config;
+ u16 e1hov;
+ u8 e1hmf;
u8 wol;
- int rx_ring_size;
+ int rx_ring_size;
- u16 tx_quick_cons_trip_int;
- u16 tx_quick_cons_trip;
- u16 tx_ticks_int;
- u16 tx_ticks;
+ u16 tx_quick_cons_trip_int;
+ u16 tx_quick_cons_trip;
+ u16 tx_ticks_int;
+ u16 tx_ticks;
- u16 rx_quick_cons_trip_int;
- u16 rx_quick_cons_trip;
- u16 rx_ticks_int;
- u16 rx_ticks;
+ u16 rx_quick_cons_trip_int;
+ u16 rx_quick_cons_trip;
+ u16 rx_ticks_int;
+ u16 rx_ticks;
- u32 stats_ticks;
+ u32 stats_ticks;
+ u32 lin_cnt;
- int state;
-#define BNX2X_STATE_CLOSED 0x0
-#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000
-#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000
+ int state;
+#define BNX2X_STATE_CLOSED 0x0
+#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000
+#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000
#define BNX2X_STATE_OPEN 0x3000
-#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
+#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
-#define BNX2X_STATE_ERROR 0xF000
+#define BNX2X_STATE_DISABLED 0xd000
+#define BNX2X_STATE_DIAG 0xe000
+#define BNX2X_STATE_ERROR 0xf000
- int num_queues;
+ int num_queues;
- u32 rx_mode;
-#define BNX2X_RX_MODE_NONE 0
-#define BNX2X_RX_MODE_NORMAL 1
-#define BNX2X_RX_MODE_ALLMULTI 2
-#define BNX2X_RX_MODE_PROMISC 3
-#define BNX2X_MAX_MULTICAST 64
-#define BNX2X_MAX_EMUL_MULTI 16
+ u32 rx_mode;
+#define BNX2X_RX_MODE_NONE 0
+#define BNX2X_RX_MODE_NORMAL 1
+#define BNX2X_RX_MODE_ALLMULTI 2
+#define BNX2X_RX_MODE_PROMISC 3
+#define BNX2X_MAX_MULTICAST 64
+#define BNX2X_MAX_EMUL_MULTI 16
- dma_addr_t def_status_blk_mapping;
+ dma_addr_t def_status_blk_mapping;
- struct bnx2x_slowpath *slowpath;
- dma_addr_t slowpath_mapping;
+ struct bnx2x_slowpath *slowpath;
+ dma_addr_t slowpath_mapping;
#ifdef BCM_ISCSI
void *t1;
@@ -716,264 +877,164 @@ struct bnx2x {
dma_addr_t qm_mapping;
#endif
- char *name;
+ int dmae_ready;
+ /* used to synchronize dmae accesses */
+ struct mutex dmae_mutex;
+ struct dmae_command init_dmae;
/* used to synchronize stats collecting */
- int stats_state;
-#define STATS_STATE_DISABLE 0
-#define STATS_STATE_ENABLE 1
-#define STATS_STATE_STOP 2 /* stop stats on next iteration */
-
+ int stats_state;
/* used by dmae command loader */
- struct dmae_command dmae;
- int executer_idx;
+ struct dmae_command stats_dmae;
+ int executer_idx;
- u32 old_brb_discard;
- struct bmac_stats old_bmac;
+ u16 stats_counter;
struct tstorm_per_client_stats old_tclient;
- struct z_stream_s *strm;
- void *gunzip_buf;
- dma_addr_t gunzip_mapping;
- int gunzip_outlen;
-#define FW_BUF_SIZE 0x8000
-
-};
+ struct xstorm_per_client_stats old_xclient;
+ struct bnx2x_eth_stats eth_stats;
+ struct z_stream_s *strm;
+ void *gunzip_buf;
+ dma_addr_t gunzip_mapping;
+ int gunzip_outlen;
+#define FW_BUF_SIZE 0x8000
-/* DMAE command defines */
-#define DMAE_CMD_SRC_PCI 0
-#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
+};
-#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
-#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
-#define DMAE_CMD_C_DST_PCI 0
-#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
+void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
+void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
+ u32 len32);
+int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode);
-#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
+static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
+ int wait)
+{
+ u32 val;
-#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
-#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
-#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
-#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
+ do {
+ val = REG_RD(bp, reg);
+ if (val == expected)
+ break;
+ ms -= wait;
+ msleep(wait);
-#define DMAE_CMD_PORT_0 0
-#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT
+ } while (ms > 0);
-#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET
-#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
+ return val;
+}
-#define DMAE_LEN32_MAX 0x400
+/* load/unload mode */
+#define LOAD_NORMAL 0
+#define LOAD_OPEN 1
+#define LOAD_DIAG 2
+#define UNLOAD_NORMAL 0
+#define UNLOAD_CLOSE 1
-/* MC hsi */
-#define RX_COPY_THRESH 92
-#define BCM_PAGE_BITS 12
-#define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS)
-
-#define NUM_TX_RINGS 16
-#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_tx_bd))
-#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
-#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS)
-#define MAX_TX_BD (NUM_TX_BD - 1)
-#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
-#define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \
- (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
-#define TX_BD(x) ((x) & MAX_TX_BD)
-#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT)
-/* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */
-#define NUM_RX_RINGS 8
-#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
-#define MAX_RX_DESC_CNT (RX_DESC_CNT - 2)
-#define RX_DESC_MASK (RX_DESC_CNT - 1)
-#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS)
-#define MAX_RX_BD (NUM_RX_BD - 1)
-#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
-#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
- (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
-#define RX_BD(x) ((x) & MAX_RX_BD)
+/* DMAE command defines */
+#define DMAE_CMD_SRC_PCI 0
+#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
-#define NUM_RCQ_RINGS (NUM_RX_RINGS * 2)
-#define RCQ_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
-#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - 1)
-#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS)
-#define MAX_RCQ_BD (NUM_RCQ_BD - 1)
-#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2)
-#define NEXT_RCQ_IDX(x) ((((x) & MAX_RCQ_DESC_CNT) == \
- (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
-#define RCQ_BD(x) ((x) & MAX_RCQ_BD)
+#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
+#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
+#define DMAE_CMD_C_DST_PCI 0
+#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
-/* used on a CID received from the HW */
-#define SW_CID(x) (le32_to_cpu(x) & \
- (COMMON_RAMROD_ETH_RX_CQE_CID >> 1))
-#define CQE_CMD(x) (le32_to_cpu(x) >> \
- COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT)
+#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
-#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \
- le32_to_cpu((bd)->addr_lo))
-#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
+#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_PORT_0 0
+#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT
-#define STROM_ASSERT_ARRAY_SIZE 50
+#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET
+#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
+#define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT
+#define DMAE_LEN32_RD_MAX 0x80
+#define DMAE_LEN32_WR_MAX 0x400
-#define MDIO_INDIRECT_REG_ADDR 0x1f
-#define MDIO_SET_REG_BANK(bp, reg_bank) \
- bnx2x_mdio22_write(bp, MDIO_INDIRECT_REG_ADDR, reg_bank)
+#define DMAE_COMP_VAL 0xe0d0d0ae
-#define MDIO_ACCESS_TIMEOUT 1000
+#define MAX_DMAE_C_PER_PORT 8
+#define INIT_DMAE_C(bp) (BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
+ BP_E1HVN(bp))
+#define PMF_DMAE_C(bp) (BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
+ E1HVN_MAX)
-/* must be used on a CID before placing it on a HW ring */
-#define HW_CID(bp, x) (x | (bp->port << 23))
+/* PCIE link and speed */
+#define PCICFG_LINK_WIDTH 0x1f00000
+#define PCICFG_LINK_WIDTH_SHIFT 20
+#define PCICFG_LINK_SPEED 0xf0000
+#define PCICFG_LINK_SPEED_SHIFT 16
-#define SP_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_spe))
-#define MAX_SP_DESC_CNT (SP_DESC_CNT - 1)
-#define ATTN_NIG_FOR_FUNC (1L << 8)
-#define ATTN_SW_TIMER_4_FUNC (1L << 9)
-#define GPIO_2_FUNC (1L << 10)
-#define GPIO_3_FUNC (1L << 11)
-#define GPIO_4_FUNC (1L << 12)
-#define ATTN_GENERAL_ATTN_1 (1L << 13)
-#define ATTN_GENERAL_ATTN_2 (1L << 14)
-#define ATTN_GENERAL_ATTN_3 (1L << 15)
-#define ATTN_GENERAL_ATTN_4 (1L << 13)
-#define ATTN_GENERAL_ATTN_5 (1L << 14)
-#define ATTN_GENERAL_ATTN_6 (1L << 15)
+#define BNX2X_NUM_STATS 39
+#define BNX2X_NUM_TESTS 8
-#define ATTN_HARD_WIRED_MASK 0xff00
-#define ATTENTION_ID 4
+#define BNX2X_MAC_LOOPBACK 0
+#define BNX2X_PHY_LOOPBACK 1
+#define BNX2X_MAC_LOOPBACK_FAILED 1
+#define BNX2X_PHY_LOOPBACK_FAILED 2
+#define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \
+ BNX2X_PHY_LOOPBACK_FAILED)
-#define BNX2X_BTR 3
-#define MAX_SPQ_PENDING 8
+#define STROM_ASSERT_ARRAY_SIZE 50
-#define BNX2X_NUM_STATS 34
-#define BNX2X_NUM_TESTS 1
+/* must be used on a CID before placing it on a HW ring */
+#define HW_CID(bp, x) ((BP_PORT(bp) << 23) | (BP_E1HVN(bp) << 17) | x)
+#define SP_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_spe))
+#define MAX_SP_DESC_CNT (SP_DESC_CNT - 1)
-#define DPM_TRIGER_TYPE 0x40
-#define DOORBELL(bp, cid, val) \
- do { \
- writel((u32)val, (bp)->doorbells + (BCM_PAGE_SIZE * cid) + \
- DPM_TRIGER_TYPE); \
- } while (0)
-/* PCIE link and speed */
-#define PCICFG_LINK_WIDTH 0x1f00000
-#define PCICFG_LINK_WIDTH_SHIFT 20
-#define PCICFG_LINK_SPEED 0xf0000
-#define PCICFG_LINK_SPEED_SHIFT 16
+#define BNX2X_BTR 3
+#define MAX_SPQ_PENDING 8
-#define BMAC_CONTROL_RX_ENABLE 2
-#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff)
+/* CMNG constants
+ derived from lab experiments, and not from system spec calculations !!! */
+#define DEF_MIN_RATE 100
+/* resolution of the rate shaping timer - 100 usec */
+#define RS_PERIODIC_TIMEOUT_USEC 100
+/* resolution of fairness algorithm in usecs -
+ coefficient for clauclating the actuall t fair */
+#define T_FAIR_COEF 10000000
+/* number of bytes in single QM arbitration cycle -
+ coeffiecnt for calculating the fairness timer */
+#define QM_ARB_BYTES 40000
+#define FAIR_MEM 2
-/* stuff added to make the code fit 80Col */
-#define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG
-#define TPA_TYPE_END ETH_FAST_PATH_RX_CQE_END_FLG
-#define TPA_TYPE(cqe) (cqe->fast_path_cqe.error_type_flags & \
- (TPA_TYPE_START | TPA_TYPE_END))
-#define BNX2X_RX_SUM_OK(cqe) \
- (!(cqe->fast_path_cqe.status_flags & \
- (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | \
- ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)))
+#define ATTN_NIG_FOR_FUNC (1L << 8)
+#define ATTN_SW_TIMER_4_FUNC (1L << 9)
+#define GPIO_2_FUNC (1L << 10)
+#define GPIO_3_FUNC (1L << 11)
+#define GPIO_4_FUNC (1L << 12)
+#define ATTN_GENERAL_ATTN_1 (1L << 13)
+#define ATTN_GENERAL_ATTN_2 (1L << 14)
+#define ATTN_GENERAL_ATTN_3 (1L << 15)
+#define ATTN_GENERAL_ATTN_4 (1L << 13)
+#define ATTN_GENERAL_ATTN_5 (1L << 14)
+#define ATTN_GENERAL_ATTN_6 (1L << 15)
-#define BNX2X_RX_SUM_FIX(cqe) \
- ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
- PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
- (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
+#define ATTN_HARD_WIRED_MASK 0xff00
+#define ATTENTION_ID 4
-#define MDIO_AN_CL73_OR_37_COMPLETE \
- (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
- MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
-
-#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
- MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
-#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
- MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
-#define GP_STATUS_SPEED_MASK \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
-#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
-#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
-#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
-#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
-#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
-#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
-#define GP_STATUS_10G_HIG \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
-#define GP_STATUS_10G_CX4 \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
-#define GP_STATUS_12G_HIG \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
-#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
-#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
-#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
-#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
-#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
-#define GP_STATUS_10G_KX4 \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
-
-#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
-#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
-#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
-#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
-#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
-#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
-#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
-#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
-#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
-#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
-#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
-#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
-#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
-#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
-#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
-#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
-#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
-#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
-#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
-#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
-#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
-#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
-#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
-
-#define NIG_STATUS_XGXS0_LINK10G \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
-#define NIG_STATUS_XGXS0_LINK_STATUS \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
-#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
-#define NIG_STATUS_SERDES0_LINK_STATUS \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
-#define NIG_MASK_MI_INT \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
-#define NIG_MASK_XGXS0_LINK10G \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
-#define NIG_MASK_XGXS0_LINK_STATUS \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
-#define NIG_MASK_SERDES0_LINK_STATUS \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
-
-#define XGXS_RESET_BITS \
- (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
-
-#define SERDES_RESET_BITS \
- (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
+/* stuff added to make the code fit 80Col */
+#define BNX2X_PMF_LINK_ASSERT \
+ GENERAL_ATTEN_OFFSET(LINK_SYNC_ATTENTION_BIT_FUNC_0 + BP_FUNC(bp))
#define BNX2X_MC_ASSERT_BITS \
(GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
@@ -987,12 +1048,20 @@ struct bnx2x {
#define BNX2X_DOORQ_ASSERT \
AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT
+#define BNX2X_GRC_TIMEOUT GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC)
+#define BNX2X_GRC_RSV (GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCN) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCU) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCP) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RSVD_GRC))
+
#define HW_INTERRUT_ASSERT_SET_0 \
(AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT)
-#define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \
+#define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\
@@ -1009,7 +1078,7 @@ struct bnx2x {
AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT)
-#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\
+#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \
@@ -1026,7 +1095,7 @@ struct bnx2x {
AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT | \
AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT |\
AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT)
-#define HW_PRTY_ASSERT_SET_2 (AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR | \
+#define HW_PRTY_ASSERT_SET_2 (AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR | \
AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\
AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \
@@ -1035,42 +1104,44 @@ struct bnx2x {
AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
-#define ETH_RX_ERROR_FALGS (ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG | \
- ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | \
- ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)
-
-
#define MULTI_FLAGS \
- (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
-
-#define MULTI_MASK 0x7f
+ (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
+#define MULTI_MASK 0x7f
-#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS
-#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS
-#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH
-#define BNX2X_RX_SB_INDEX \
- &fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX]
+#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES)
+#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES)
+#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES)
+#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES)
-#define BNX2X_TX_SB_INDEX \
- &fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX]
+#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH
#define BNX2X_SP_DSB_INDEX \
-&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX]
+(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX])
#define CAM_IS_INVALID(x) \
(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
#define CAM_INVALIDATE(x) \
-x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE
+ (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
+/* Number of u32 elements in MC hash array */
+#define MC_HASH_SIZE 8
+#define MC_HASH_OFFSET(bp, i) (BAR_TSTRORM_INTMEM + \
+ TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(BP_FUNC(bp)) + i*4)
+
+
+#ifndef PXP2_REG_PXP2_INT_STS
+#define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0
+#endif
+
/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
#endif /* bnx2x.h */
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index 3b968904ca6..e3da7f69d27 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -8,191 +8,390 @@
*/
-#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
- (0x1922 + (port * 0x40) + (index * 0x4))
-#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
- (0x1900 + (port * 0x40))
-#define CSTORM_HC_BTR_OFFSET(port)\
- (0x1984 + (port * 0xc0))
-#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\
- (0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
-#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\
- (0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
-#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\
- (0x1400 + (port * 0x280) + (cpu_id * 0x28))
-#define CSTORM_STATS_FLAGS_OFFSET(port) (0x5108 + (port * 0x8))
-#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id)\
- (0x1510 + (port * 0x240) + (client_id * 0x20))
-#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
- (0x138a + (port * 0x28) + (index * 0x4))
-#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
- (0x1370 + (port * 0x28))
-#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\
- (0x4b70 + (port * 0x8))
-#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function)\
- (0x1418 + (function * 0x30))
-#define TSTORM_HC_BTR_OFFSET(port)\
- (0x13c4 + (port * 0x18))
-#define TSTORM_INDIRECTION_TABLE_OFFSET(port)\
- (0x22c8 + (port * 0x80))
-#define TSTORM_INDIRECTION_TABLE_SIZE 0x80
-#define TSTORM_MAC_FILTER_CONFIG_OFFSET(port)\
- (0x1420 + (port * 0x30))
-#define TSTORM_RCQ_PROD_OFFSET(port, client_id)\
- (0x1508 + (port * 0x240) + (client_id * 0x20))
-#define TSTORM_STATS_FLAGS_OFFSET(port) (0x4b90 + (port * 0x8))
-#define USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
- (0x191a + (port * 0x28) + (index * 0x4))
-#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
- (0x1900 + (port * 0x28))
-#define USTORM_HC_BTR_OFFSET(port)\
- (0x1954 + (port * 0xb8))
-#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port)\
- (0x5408 + (port * 0x8))
-#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\
- (0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
-#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\
- (0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
-#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\
- (0x1400 + (port * 0x280) + (cpu_id * 0x28))
-#define XSTORM_ASSERT_LIST_INDEX_OFFSET 0x1000
-#define XSTORM_ASSERT_LIST_OFFSET(idx) (0x1020 + (idx * 0x10))
-#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
- (0x141a + (port * 0x28) + (index * 0x4))
-#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
- (0x1400 + (port * 0x28))
-#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\
- (0x5408 + (port * 0x8))
-#define XSTORM_HC_BTR_OFFSET(port)\
- (0x1454 + (port * 0x18))
-#define XSTORM_SPQ_PAGE_BASE_OFFSET(port)\
- (0x5328 + (port * 0x18))
-#define XSTORM_SPQ_PROD_OFFSET(port)\
- (0x5330 + (port * 0x18))
-#define XSTORM_STATS_FLAGS_OFFSET(port) (0x53f8 + (port * 0x8))
+#define CSTORM_ASSERT_LIST_INDEX_OFFSET \
+ (IS_E1H_OFFSET? 0x7000 : 0x1000)
+#define CSTORM_ASSERT_LIST_OFFSET(idx) \
+ (IS_E1H_OFFSET? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
+ (IS_E1H_OFFSET? (0x8522 + ((function>>1) * 0x40) + ((function&1) \
+ * 0x100) + (index * 0x4)) : (0x1922 + (function * 0x40) + (index \
+ * 0x4)))
+#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x8500 + ((function>>1) * 0x40) + ((function&1) \
+ * 0x100)) : (0x1900 + (function * 0x40)))
+#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x8508 + ((function>>1) * 0x40) + ((function&1) \
+ * 0x100)) : (0x1908 + (function * 0x40)))
+#define CSTORM_FUNCTION_MODE_OFFSET \
+ (IS_E1H_OFFSET? 0x11e8 : 0xffffffff)
+#define CSTORM_HC_BTR_OFFSET(port) \
+ (IS_E1H_OFFSET? (0x8704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
+#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
+ (IS_E1H_OFFSET? (0x801a + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)))
+#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
+ (IS_E1H_OFFSET? (0x8018 + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)))
+#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
+ (IS_E1H_OFFSET? (0x8000 + (port * 0x280) + (cpu_id * 0x28)) : \
+ (0x1400 + (port * 0x280) + (cpu_id * 0x28)))
+#define CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
+ (IS_E1H_OFFSET? (0x8008 + (port * 0x280) + (cpu_id * 0x28)) : \
+ (0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+#define CSTORM_STATS_FLAGS_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x1108 + (function * 0x8)) : (0x5108 + \
+ (function * 0x8)))
+#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x31c0 + (function * 0x20)) : 0xffffffff)
+#define TSTORM_ASSERT_LIST_INDEX_OFFSET \
+ (IS_E1H_OFFSET? 0xa000 : 0x1000)
+#define TSTORM_ASSERT_LIST_OFFSET(idx) \
+ (IS_E1H_OFFSET? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
+ (IS_E1H_OFFSET? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) : \
+ (0x9c8 + (port * 0x2f8) + (client_id * 0x28)))
+#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
+ (IS_E1H_OFFSET? (0xb01a + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0) + (index * 0x4)) : (0x141a + (function * 0x28) + (index * \
+ 0x4)))
+#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET? (0xb000 + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0)) : (0x1400 + (function * 0x28)))
+#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
+ (IS_E1H_OFFSET? (0xb008 + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0)) : (0x1408 + (function * 0x28)))
+#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2b80 + (function * 0x8)) : (0x4b68 + \
+ (function * 0x8)))
+#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x3000 + (function * 0x38)) : (0x1500 + \
+ (function * 0x38)))
+#define TSTORM_FUNCTION_MODE_OFFSET \
+ (IS_E1H_OFFSET? 0x1ad0 : 0xffffffff)
+#define TSTORM_HC_BTR_OFFSET(port) \
+ (IS_E1H_OFFSET? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
+#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x12c8 + (function * 0x80)) : (0x22c8 + \
+ (function * 0x80)))
+#define TSTORM_INDIRECTION_TABLE_SIZE 0x80
+#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x3008 + (function * 0x38)) : (0x1508 + \
+ (function * 0x38)))
+#define TSTORM_RX_PRODS_OFFSET(port, client_id) \
+ (IS_E1H_OFFSET? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) : \
+ (0x9c0 + (port * 0x2f8) + (client_id * 0x28)))
+#define TSTORM_STATS_FLAGS_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2c00 + (function * 0x8)) : (0x4b88 + \
+ (function * 0x8)))
+#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET? 0x3b30 : 0x1c20)
+#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET? 0xa040 : 0x2c10)
+#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET? 0x2440 : 0x1200)
+#define USTORM_ASSERT_LIST_INDEX_OFFSET \
+ (IS_E1H_OFFSET? 0x8000 : 0x1000)
+#define USTORM_ASSERT_LIST_OFFSET(idx) \
+ (IS_E1H_OFFSET? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
+ (IS_E1H_OFFSET? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \
+ (0x5450 + (port * 0x1c8) + (clientId * 0x18)))
+#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
+ (IS_E1H_OFFSET? (0x951a + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0) + (index * 0x4)) : (0x191a + (function * 0x28) + (index * \
+ 0x4)))
+#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x9500 + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0)) : (0x1900 + (function * 0x28)))
+#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x9508 + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0)) : (0x1908 + (function * 0x28)))
+#define USTORM_FUNCTION_MODE_OFFSET \
+ (IS_E1H_OFFSET? 0x2448 : 0xffffffff)
+#define USTORM_HC_BTR_OFFSET(port) \
+ (IS_E1H_OFFSET? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8)))
+#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
+ (IS_E1H_OFFSET? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \
+ (0x5448 + (port * 0x1c8) + (clientId * 0x18)))
+#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2408 + (function * 0x8)) : (0x5408 + \
+ (function * 0x8)))
+#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
+ (IS_E1H_OFFSET? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)))
+#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
+ (IS_E1H_OFFSET? (0x9018 + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
+ (index * 0x4)))
+#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
+ (IS_E1H_OFFSET? (0x9000 + (port * 0x280) + (cpu_id * 0x28)) : \
+ (0x1400 + (port * 0x280) + (cpu_id * 0x28)))
+#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
+ (IS_E1H_OFFSET? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
+ (0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+#define XSTORM_ASSERT_LIST_INDEX_OFFSET \
+ (IS_E1H_OFFSET? 0x9000 : 0x1000)
+#define XSTORM_ASSERT_LIST_OFFSET(idx) \
+ (IS_E1H_OFFSET? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
+ (IS_E1H_OFFSET? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40)))
+#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
+ (IS_E1H_OFFSET? (0xa01a + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0) + (index * 0x4)) : (0x141a + (function * 0x28) + (index * \
+ 0x4)))
+#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET? (0xa000 + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0)) : (0x1400 + (function * 0x28)))
+#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
+ (IS_E1H_OFFSET? (0xa008 + ((function>>1) * 0x28) + ((function&1) \
+ * 0xa0)) : (0x1408 + (function * 0x28)))
+#define XSTORM_E1HOV_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2ab8 + (function * 0x2)) : 0xffffffff)
+#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2418 + (function * 0x8)) : (0x3b70 + \
+ (function * 0x8)))
+#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2568 + (function * 0x70)) : (0x3c60 + \
+ (function * 0x70)))
+#define XSTORM_FUNCTION_MODE_OFFSET \
+ (IS_E1H_OFFSET? 0x2ac8 : 0xffffffff)
+#define XSTORM_HC_BTR_OFFSET(port) \
+ (IS_E1H_OFFSET? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
+#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2528 + (function * 0x70)) : (0x3c20 + \
+ (function * 0x70)))
+#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2000 + (function * 0x10)) : (0x3328 + \
+ (function * 0x10)))
+#define XSTORM_SPQ_PROD_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x2008 + (function * 0x10)) : (0x3330 + \
+ (function * 0x10)))
+#define XSTORM_STATS_FLAGS_OFFSET(function) \
+ (IS_E1H_OFFSET? (0x23d8 + (function * 0x8)) : (0x3b60 + \
+ (function * 0x8)))
#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
/**
* This file defines HSI constatnts for the ETH flow
*/
-
-/* hash types */
-#define DEFAULT_HASH_TYPE 0
-#define IPV4_HASH_TYPE 1
-#define TCP_IPV4_HASH_TYPE 2
-#define IPV6_HASH_TYPE 3
-#define TCP_IPV6_HASH_TYPE 4
+#ifdef _EVEREST_MICROCODE
+#include "microcode_constants.h"
+#include "eth_rx_bd.h"
+#include "eth_tx_bd.h"
+#include "eth_rx_cqe.h"
+#include "eth_rx_sge.h"
+#include "eth_rx_cqe_next_page.h"
+#endif
+
+/* RSS hash types */
+#define DEFAULT_HASH_TYPE 0
+#define IPV4_HASH_TYPE 1
+#define TCP_IPV4_HASH_TYPE 2
+#define IPV6_HASH_TYPE 3
+#define TCP_IPV6_HASH_TYPE 4
+
+/* Ethernet Ring parmaters */
+#define X_ETH_LOCAL_RING_SIZE 13
+#define FIRST_BD_IN_PKT 0
+#define PARSE_BD_INDEX 1
+#define NUM_OF_ETH_BDS_IN_PAGE \
+ ((PAGE_SIZE) / (STRUCT_SIZE(eth_tx_bd)/8))
+
+
+/* Rx ring params */
+#define U_ETH_LOCAL_BD_RING_SIZE (16)
+#define U_ETH_LOCAL_SGE_RING_SIZE (12)
+#define U_ETH_SGL_SIZE (8)
+
+
+#define U_ETH_BDS_PER_PAGE_MASK \
+ ((PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))-1)
+#define U_ETH_CQE_PER_PAGE_MASK \
+ ((PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe)/8))-1)
+#define U_ETH_SGES_PER_PAGE_MASK \
+ ((PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))-1)
+
+#define U_ETH_SGES_PER_PAGE_INVERSE_MASK \
+ (0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1))
+
+
+#define TU_ETH_CQES_PER_PAGE \
+ (PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe_next_page)/8))
+#define U_ETH_BDS_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))
+#define U_ETH_SGES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))
+
+#define U_ETH_UNDEFINED_Q 0xFF
/* values of command IDs in the ramrod message */
-#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
-#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
-#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
-#define RAMROD_CMD_ID_ETH_UPDATE (100)
-#define RAMROD_CMD_ID_ETH_HALT (105)
-#define RAMROD_CMD_ID_ETH_SET_MAC (110)
-#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
-#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
-#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
+#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
+#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
+#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
+#define RAMROD_CMD_ID_ETH_UPDATE (100)
+#define RAMROD_CMD_ID_ETH_HALT (105)
+#define RAMROD_CMD_ID_ETH_SET_MAC (110)
+#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
+#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
+#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
/* command values for set mac command */
-#define T_ETH_MAC_COMMAND_SET 0
-#define T_ETH_MAC_COMMAND_INVALIDATE 1
+#define T_ETH_MAC_COMMAND_SET 0
+#define T_ETH_MAC_COMMAND_INVALIDATE 1
+
+#define T_ETH_INDIRECTION_TABLE_SIZE 128
-#define T_ETH_INDIRECTION_TABLE_SIZE 128
+/*The CRC32 seed, that is used for the hash(reduction) multicast address */
+#define T_ETH_CRC32_HASH_SEED 0x00000000
/* Maximal L2 clients supported */
-#define ETH_MAX_RX_CLIENTS (18)
+#define ETH_MAX_RX_CLIENTS_E1 19
+#define ETH_MAX_RX_CLIENTS_E1H 25
+
+/* Maximal aggregation queues supported */
+#define ETH_MAX_AGGREGATION_QUEUES_E1 (32)
+#define ETH_MAX_AGGREGATION_QUEUES_E1H (64)
+
/**
* This file defines HSI constatnts common to all microcode flows
*/
/* Connection types */
-#define ETH_CONNECTION_TYPE 0
+#define ETH_CONNECTION_TYPE 0
+#define TOE_CONNECTION_TYPE 1
+#define RDMA_CONNECTION_TYPE 2
+#define ISCSI_CONNECTION_TYPE 3
+#define FCOE_CONNECTION_TYPE 4
+#define RESERVED_CONNECTION_TYPE_0 5
+#define RESERVED_CONNECTION_TYPE_1 6
+#define RESERVED_CONNECTION_TYPE_2 7
+
-#define PROTOCOL_STATE_BIT_OFFSET 6
+#define PROTOCOL_STATE_BIT_OFFSET 6
-#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define ISCSI_STATE \
+ (ISCSI_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define FCOE_STATE (FCOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
/* microcode fixed page page size 4K (chains and ring segments) */
-#define MC_PAGE_SIZE (4096)
+#define MC_PAGE_SIZE (4096)
-/* Host coalescing constants */
-/* IGU constants */
-#define IGU_PORT_BASE 0x0400
-
-#define IGU_ADDR_MSIX 0x0000
-#define IGU_ADDR_INT_ACK 0x0200
-#define IGU_ADDR_PROD_UPD 0x0201
-#define IGU_ADDR_ATTN_BITS_UPD 0x0202
-#define IGU_ADDR_ATTN_BITS_SET 0x0203
-#define IGU_ADDR_ATTN_BITS_CLR 0x0204
-#define IGU_ADDR_COALESCE_NOW 0x0205
-#define IGU_ADDR_SIMD_MASK 0x0206
-#define IGU_ADDR_SIMD_NOMASK 0x0207
-#define IGU_ADDR_MSI_CTL 0x0210
-#define IGU_ADDR_MSI_ADDR_LO 0x0211
-#define IGU_ADDR_MSI_ADDR_HI 0x0212
-#define IGU_ADDR_MSI_DATA 0x0213
-
-#define IGU_INT_ENABLE 0
-#define IGU_INT_DISABLE 1
-#define IGU_INT_NOP 2
-#define IGU_INT_NOP2 3
+/* Host coalescing constants */
/* index numbers */
-#define HC_USTORM_DEF_SB_NUM_INDICES 4
-#define HC_CSTORM_DEF_SB_NUM_INDICES 8
-#define HC_XSTORM_DEF_SB_NUM_INDICES 4
-#define HC_TSTORM_DEF_SB_NUM_INDICES 4
-#define HC_USTORM_SB_NUM_INDICES 4
-#define HC_CSTORM_SB_NUM_INDICES 4
+#define HC_USTORM_DEF_SB_NUM_INDICES 4
+#define HC_CSTORM_DEF_SB_NUM_INDICES 8
+#define HC_XSTORM_DEF_SB_NUM_INDICES 4
+#define HC_TSTORM_DEF_SB_NUM_INDICES 4
+#define HC_USTORM_SB_NUM_INDICES 4
+#define HC_CSTORM_SB_NUM_INDICES 4
/* index values - which counterto update */
-#define HC_INDEX_U_ETH_RX_CQ_CONS 1
+#define HC_INDEX_U_TOE_RX_CQ_CONS 0
+#define HC_INDEX_U_ETH_RX_CQ_CONS 1
+#define HC_INDEX_U_ETH_RX_BD_CONS 2
+#define HC_INDEX_U_FCOE_EQ_CONS 3
+
+#define HC_INDEX_C_TOE_TX_CQ_CONS 0
+#define HC_INDEX_C_ETH_TX_CQ_CONS 1
+#define HC_INDEX_C_ISCSI_EQ_CONS 2
+
+#define HC_INDEX_DEF_X_SPQ_CONS 0
-#define HC_INDEX_C_ETH_TX_CQ_CONS 1
+#define HC_INDEX_DEF_C_RDMA_EQ_CONS 0
+#define HC_INDEX_DEF_C_RDMA_NAL_PROD 1
+#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2
+#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3
+#define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4
+#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5
-#define HC_INDEX_DEF_X_SPQ_CONS 0
+#define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0
+#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1
+#define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2
+#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3
-#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2
-#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3
/* used by the driver to get the SB offset */
-#define USTORM_ID 0
-#define CSTORM_ID 1
-#define XSTORM_ID 2
-#define TSTORM_ID 3
-#define ATTENTION_ID 4
+#define USTORM_ID 0
+#define CSTORM_ID 1
+#define XSTORM_ID 2
+#define TSTORM_ID 3
+#define ATTENTION_ID 4
/* max number of slow path commands per port */
-#define MAX_RAMRODS_PER_PORT (8)
+#define MAX_RAMRODS_PER_PORT (8)
/* values for RX ETH CQE type field */
-#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
-#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
-
-/* MAC address list size */
-#define T_MAC_ADDRESS_LIST_SIZE (96)
-
+#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
+#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
+
+
+/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
+#define EMULATION_FREQUENCY_FACTOR (1600)
+#define FPGA_FREQUENCY_FACTOR (100)
+
+#define TIMERS_TICK_SIZE_CHIP (1e-3)
+#define TIMERS_TICK_SIZE_EMUL \
+ ((TIMERS_TICK_SIZE_CHIP)/((EMULATION_FREQUENCY_FACTOR)))
+#define TIMERS_TICK_SIZE_FPGA \
+ ((TIMERS_TICK_SIZE_CHIP)/((FPGA_FREQUENCY_FACTOR)))
+
+#define TSEMI_CLK1_RESUL_CHIP (1e-3)
+#define TSEMI_CLK1_RESUL_EMUL \
+ ((TSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
+#define TSEMI_CLK1_RESUL_FPGA \
+ ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
+
+#define USEMI_CLK1_RESUL_CHIP \
+ (TIMERS_TICK_SIZE_CHIP)
+#define USEMI_CLK1_RESUL_EMUL \
+ (TIMERS_TICK_SIZE_EMUL)
+#define USEMI_CLK1_RESUL_FPGA \
+ (TIMERS_TICK_SIZE_FPGA)
+
+#define XSEMI_CLK1_RESUL_CHIP (1e-3)
+#define XSEMI_CLK1_RESUL_EMUL \
+ ((XSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
+#define XSEMI_CLK1_RESUL_FPGA \
+ ((XSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
+
+#define XSEMI_CLK2_RESUL_CHIP (1e-6)
+#define XSEMI_CLK2_RESUL_EMUL \
+ ((XSEMI_CLK2_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
+#define XSEMI_CLK2_RESUL_FPGA \
+ ((XSEMI_CLK2_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
+
+#define SDM_TIMER_TICK_RESUL_CHIP (4*(1e-6))
+#define SDM_TIMER_TICK_RESUL_EMUL \
+ ((SDM_TIMER_TICK_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
+#define SDM_TIMER_TICK_RESUL_FPGA \
+ ((SDM_TIMER_TICK_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
+
+
+/**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
#define XSTORM_IP_ID_ROLL_HALF 0x8000
#define XSTORM_IP_ID_ROLL_ALL 0
-#define FW_LOG_LIST_SIZE (50)
+#define FW_LOG_LIST_SIZE (50)
+
+#define NUM_OF_PROTOCOLS 4
+#define MAX_COS_NUMBER 16
+#define MAX_T_STAT_COUNTER_ID 18
+#define MAX_X_STAT_COUNTER_ID 18
-#define NUM_OF_PROTOCOLS 4
-#define MAX_COS_NUMBER 16
-#define MAX_T_STAT_COUNTER_ID 18
+#define UNKNOWN_ADDRESS 0
+#define UNICAST_ADDRESS 1
+#define MULTICAST_ADDRESS 2
+#define BROADCAST_ADDRESS 3
-#define T_FAIR 1
-#define FAIR_MEM 2
-#define RS_PERIODIC_TIMEOUT_IN_SDM_TICS 25
+#define SINGLE_FUNCTION 0
+#define MULTI_FUNCTION 1
-#define UNKNOWN_ADDRESS 0
-#define UNICAST_ADDRESS 1
-#define MULTICAST_ADDRESS 2
-#define BROADCAST_ADDRESS 3
+#define IP_V4 0
+#define IP_V6 1
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index b21075ccb52..d3e8198d7db 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -132,6 +132,12 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009
#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1023G 0x0000000b
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1033G 0x0000000c
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957711T1101 0x0000000d
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957711ET1201 0x0000000e
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957711A1133G 0x0000000f
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957711EA1233G 0x00000010
#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000
#define SHARED_HW_CFG_BOARD_VER_SHIFT 16
@@ -313,6 +319,7 @@ struct shared_feat_cfg { /* NVRAM Offset */
u32 config; /* 0x450 */
#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
+#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
};
@@ -502,28 +509,41 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
};
-/*****************************************************************************
- * Device Information *
- *****************************************************************************/
-struct dev_info { /* size */
+/****************************************************************************
+ * Device Information *
+ ****************************************************************************/
+struct dev_info { /* size */
- u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
+ u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
- struct shared_hw_cfg shared_hw_config; /* 40 */
+ struct shared_hw_cfg shared_hw_config; /* 40 */
- struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */
+ struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */
- struct shared_feat_cfg shared_feature_config; /* 4 */
+ struct shared_feat_cfg shared_feature_config; /* 4 */
- struct port_feat_cfg port_feature_config[PORT_MAX]; /* 116*2=232 */
+ struct port_feat_cfg port_feature_config[PORT_MAX];/* 116*2=232 */
};
#define FUNC_0 0
#define FUNC_1 1
+#define FUNC_2 2
+#define FUNC_3 3
+#define FUNC_4 4
+#define FUNC_5 5
+#define FUNC_6 6
+#define FUNC_7 7
#define E1_FUNC_MAX 2
-#define FUNC_MAX E1_FUNC_MAX
+#define E1H_FUNC_MAX 8
+
+#define VN_0 0
+#define VN_1 1
+#define VN_2 2
+#define VN_3 3
+#define E1VN_MAX 1
+#define E1HVN_MAX 4
/* This value (in milliseconds) determines the frequency of the driver
@@ -619,7 +639,9 @@ struct drv_port_mb {
#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000
#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000
- u32 reserved[3];
+ u32 port_stx;
+
+ u32 reserved[2];
};
@@ -642,6 +664,11 @@ struct drv_func_mb {
#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
+#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
+#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
+#define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000
+#define BIOS_MSG_CODE_VIRT_MAC_ISCSI 0xff040000
+
#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
u32 drv_mb_param;
@@ -671,6 +698,11 @@ struct drv_func_mb {
#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000
#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000
+#define FW_MSG_CODE_LIC_CHALLENGE 0xff010000
+#define FW_MSG_CODE_LIC_RESPONSE 0xff020000
+#define FW_MSG_CODE_VIRT_MAC_PRIM 0xff030000
+#define FW_MSG_CODE_VIRT_MAC_ISCSI 0xff040000
+
#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
u32 fw_mb_param;
@@ -696,7 +728,13 @@ struct drv_func_mb {
u32 iscsi_boot_signature;
u32 iscsi_boot_block_offset;
- u32 reserved[3];
+ u32 drv_status;
+#define DRV_STATUS_PMF 0x00000001
+
+ u32 virt_mac_upper;
+#define VIRT_MAC_SIGN_MASK 0xffff0000
+#define VIRT_MAC_SIGNATURE 0x564d0000
+ u32 virt_mac_lower;
};
@@ -713,6 +751,92 @@ struct mgmtfw_state {
/****************************************************************************
+ * Multi-Function configuration *
+ ****************************************************************************/
+struct shared_mf_cfg {
+
+ u32 clp_mb;
+#define SHARED_MF_CLP_SET_DEFAULT 0x00000000
+ /* set by CLP */
+#define SHARED_MF_CLP_EXIT 0x00000001
+ /* set by MCP */
+#define SHARED_MF_CLP_EXIT_DONE 0x00010000
+
+};
+
+struct port_mf_cfg {
+
+ u32 dynamic_cfg; /* device control channel */
+#define PORT_MF_CFG_OUTER_VLAN_TAG_MASK 0x0000ffff
+#define PORT_MF_CFG_OUTER_VLAN_TAG_SHIFT 0
+#define PORT_MF_CFG_DYNAMIC_CFG_ENABLED 0x00010000
+#define PORT_MF_CFG_DYNAMIC_CFG_DEFAULT 0x00000000
+
+ u32 reserved[3];
+
+};
+
+struct func_mf_cfg {
+
+ u32 config;
+ /* E/R/I/D */
+ /* function 0 of each port cannot be hidden */
+#define FUNC_MF_CFG_FUNC_HIDE 0x00000001
+
+#define FUNC_MF_CFG_PROTOCOL_MASK 0x00000007
+#define FUNC_MF_CFG_PROTOCOL_ETHERNET 0x00000002
+#define FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA 0x00000004
+#define FUNC_MF_CFG_PROTOCOL_ISCSI 0x00000006
+#define FUNC_MF_CFG_PROTOCOL_DEFAULT\
+ FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA
+
+#define FUNC_MF_CFG_FUNC_DISABLED 0x00000008
+
+ /* PRI */
+ /* 0 - low priority, 3 - high priority */
+#define FUNC_MF_CFG_TRANSMIT_PRIORITY_MASK 0x00000300
+#define FUNC_MF_CFG_TRANSMIT_PRIORITY_SHIFT 8
+#define FUNC_MF_CFG_TRANSMIT_PRIORITY_DEFAULT 0x00000000
+
+ /* MINBW, MAXBW */
+ /* value range - 0..100, increments in 100Mbps */
+#define FUNC_MF_CFG_MIN_BW_MASK 0x00ff0000
+#define FUNC_MF_CFG_MIN_BW_SHIFT 16
+#define FUNC_MF_CFG_MIN_BW_DEFAULT 0x00000000
+#define FUNC_MF_CFG_MAX_BW_MASK 0xff000000
+#define FUNC_MF_CFG_MAX_BW_SHIFT 24
+#define FUNC_MF_CFG_MAX_BW_DEFAULT 0x64000000
+
+ u32 mac_upper; /* MAC */
+#define FUNC_MF_CFG_UPPERMAC_MASK 0x0000ffff
+#define FUNC_MF_CFG_UPPERMAC_SHIFT 0
+#define FUNC_MF_CFG_UPPERMAC_DEFAULT FUNC_MF_CFG_UPPERMAC_MASK
+ u32 mac_lower;
+#define FUNC_MF_CFG_LOWERMAC_DEFAULT 0xffffffff
+
+ u32 e1hov_tag; /* VNI */
+#define FUNC_MF_CFG_E1HOV_TAG_MASK 0x0000ffff
+#define FUNC_MF_CFG_E1HOV_TAG_SHIFT 0
+#define FUNC_MF_CFG_E1HOV_TAG_DEFAULT FUNC_MF_CFG_E1HOV_TAG_MASK
+
+ u32 reserved[2];
+
+};
+
+struct mf_cfg {
+
+ struct shared_mf_cfg shared_mf_config;
+ struct port_mf_cfg port_mf_config[PORT_MAX];
+#if defined(b710)
+ struct func_mf_cfg func_mf_config[E1_FUNC_MAX];
+#else
+ struct func_mf_cfg func_mf_config[E1H_FUNC_MAX];
+#endif
+
+};
+
+
+/****************************************************************************
* Shared Memory Region *
****************************************************************************/
struct shmem_region { /* SharedMem Offset (size) */
@@ -747,14 +871,349 @@ struct shmem_region { /* SharedMem Offset (size) */
struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */
struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */
- struct drv_func_mb func_mb[FUNC_MAX]; /* 0x684 (44*2=0x58) */
+ struct drv_func_mb func_mb[E1H_FUNC_MAX];
+
+ struct mf_cfg mf_cfg;
}; /* 0x6dc */
+struct emac_stats {
+ u32 rx_stat_ifhcinoctets;
+ u32 rx_stat_ifhcinbadoctets;
+ u32 rx_stat_etherstatsfragments;
+ u32 rx_stat_ifhcinucastpkts;
+ u32 rx_stat_ifhcinmulticastpkts;
+ u32 rx_stat_ifhcinbroadcastpkts;
+ u32 rx_stat_dot3statsfcserrors;
+ u32 rx_stat_dot3statsalignmenterrors;
+ u32 rx_stat_dot3statscarriersenseerrors;
+ u32 rx_stat_xonpauseframesreceived;
+ u32 rx_stat_xoffpauseframesreceived;
+ u32 rx_stat_maccontrolframesreceived;
+ u32 rx_stat_xoffstateentered;
+ u32 rx_stat_dot3statsframestoolong;
+ u32 rx_stat_etherstatsjabbers;
+ u32 rx_stat_etherstatsundersizepkts;
+ u32 rx_stat_etherstatspkts64octets;
+ u32 rx_stat_etherstatspkts65octetsto127octets;
+ u32 rx_stat_etherstatspkts128octetsto255octets;
+ u32 rx_stat_etherstatspkts256octetsto511octets;
+ u32 rx_stat_etherstatspkts512octetsto1023octets;
+ u32 rx_stat_etherstatspkts1024octetsto1522octets;
+ u32 rx_stat_etherstatspktsover1522octets;
+
+ u32 rx_stat_falsecarriererrors;
+
+ u32 tx_stat_ifhcoutoctets;
+ u32 tx_stat_ifhcoutbadoctets;
+ u32 tx_stat_etherstatscollisions;
+ u32 tx_stat_outxonsent;
+ u32 tx_stat_outxoffsent;
+ u32 tx_stat_flowcontroldone;
+ u32 tx_stat_dot3statssinglecollisionframes;
+ u32 tx_stat_dot3statsmultiplecollisionframes;
+ u32 tx_stat_dot3statsdeferredtransmissions;
+ u32 tx_stat_dot3statsexcessivecollisions;
+ u32 tx_stat_dot3statslatecollisions;
+ u32 tx_stat_ifhcoutucastpkts;
+ u32 tx_stat_ifhcoutmulticastpkts;
+ u32 tx_stat_ifhcoutbroadcastpkts;
+ u32 tx_stat_etherstatspkts64octets;
+ u32 tx_stat_etherstatspkts65octetsto127octets;
+ u32 tx_stat_etherstatspkts128octetsto255octets;
+ u32 tx_stat_etherstatspkts256octetsto511octets;
+ u32 tx_stat_etherstatspkts512octetsto1023octets;
+ u32 tx_stat_etherstatspkts1024octetsto1522octets;
+ u32 tx_stat_etherstatspktsover1522octets;
+ u32 tx_stat_dot3statsinternalmactransmiterrors;
+};
+
+
+struct bmac_stats {
+ u32 tx_stat_gtpkt_lo;
+ u32 tx_stat_gtpkt_hi;
+ u32 tx_stat_gtxpf_lo;
+ u32 tx_stat_gtxpf_hi;
+ u32 tx_stat_gtfcs_lo;
+ u32 tx_stat_gtfcs_hi;
+ u32 tx_stat_gtmca_lo;
+ u32 tx_stat_gtmca_hi;
+ u32 tx_stat_gtbca_lo;
+ u32 tx_stat_gtbca_hi;
+ u32 tx_stat_gtfrg_lo;
+ u32 tx_stat_gtfrg_hi;
+ u32 tx_stat_gtovr_lo;
+ u32 tx_stat_gtovr_hi;
+ u32 tx_stat_gt64_lo;
+ u32 tx_stat_gt64_hi;
+ u32 tx_stat_gt127_lo;
+ u32 tx_stat_gt127_hi;
+ u32 tx_stat_gt255_lo;
+ u32 tx_stat_gt255_hi;
+ u32 tx_stat_gt511_lo;
+ u32 tx_stat_gt511_hi;
+ u32 tx_stat_gt1023_lo;
+ u32 tx_stat_gt1023_hi;
+ u32 tx_stat_gt1518_lo;
+ u32 tx_stat_gt1518_hi;
+ u32 tx_stat_gt2047_lo;
+ u32 tx_stat_gt2047_hi;
+ u32 tx_stat_gt4095_lo;
+ u32 tx_stat_gt4095_hi;
+ u32 tx_stat_gt9216_lo;
+ u32 tx_stat_gt9216_hi;
+ u32 tx_stat_gt16383_lo;
+ u32 tx_stat_gt16383_hi;
+ u32 tx_stat_gtmax_lo;
+ u32 tx_stat_gtmax_hi;
+ u32 tx_stat_gtufl_lo;
+ u32 tx_stat_gtufl_hi;
+ u32 tx_stat_gterr_lo;
+ u32 tx_stat_gterr_hi;
+ u32 tx_stat_gtbyt_lo;
+ u32 tx_stat_gtbyt_hi;
+
+ u32 rx_stat_gr64_lo;
+ u32 rx_stat_gr64_hi;
+ u32 rx_stat_gr127_lo;
+ u32 rx_stat_gr127_hi;
+ u32 rx_stat_gr255_lo;
+ u32 rx_stat_gr255_hi;
+ u32 rx_stat_gr511_lo;
+ u32 rx_stat_gr511_hi;
+ u32 rx_stat_gr1023_lo;
+ u32 rx_stat_gr1023_hi;
+ u32 rx_stat_gr1518_lo;
+ u32 rx_stat_gr1518_hi;
+ u32 rx_stat_gr2047_lo;
+ u32 rx_stat_gr2047_hi;
+ u32 rx_stat_gr4095_lo;
+ u32 rx_stat_gr4095_hi;
+ u32 rx_stat_gr9216_lo;
+ u32 rx_stat_gr9216_hi;
+ u32 rx_stat_gr16383_lo;
+ u32 rx_stat_gr16383_hi;
+ u32 rx_stat_grmax_lo;
+ u32 rx_stat_grmax_hi;
+ u32 rx_stat_grpkt_lo;
+ u32 rx_stat_grpkt_hi;
+ u32 rx_stat_grfcs_lo;
+ u32 rx_stat_grfcs_hi;
+ u32 rx_stat_grmca_lo;
+ u32 rx_stat_grmca_hi;
+ u32 rx_stat_grbca_lo;
+ u32 rx_stat_grbca_hi;
+ u32 rx_stat_grxcf_lo;
+ u32 rx_stat_grxcf_hi;
+ u32 rx_stat_grxpf_lo;
+ u32 rx_stat_grxpf_hi;
+ u32 rx_stat_grxuo_lo;
+ u32 rx_stat_grxuo_hi;
+ u32 rx_stat_grjbr_lo;
+ u32 rx_stat_grjbr_hi;
+ u32 rx_stat_grovr_lo;
+ u32 rx_stat_grovr_hi;
+ u32 rx_stat_grflr_lo;
+ u32 rx_stat_grflr_hi;
+ u32 rx_stat_grmeg_lo;
+ u32 rx_stat_grmeg_hi;
+ u32 rx_stat_grmeb_lo;
+ u32 rx_stat_grmeb_hi;
+ u32 rx_stat_grbyt_lo;
+ u32 rx_stat_grbyt_hi;
+ u32 rx_stat_grund_lo;
+ u32 rx_stat_grund_hi;
+ u32 rx_stat_grfrg_lo;
+ u32 rx_stat_grfrg_hi;
+ u32 rx_stat_grerb_lo;
+ u32 rx_stat_grerb_hi;
+ u32 rx_stat_grfre_lo;
+ u32 rx_stat_grfre_hi;
+ u32 rx_stat_gripj_lo;
+ u32 rx_stat_gripj_hi;
+};
+
+
+union mac_stats {
+ struct emac_stats emac_stats;
+ struct bmac_stats bmac_stats;
+};
+
+
+struct mac_stx {
+ /* in_bad_octets */
+ u32 rx_stat_ifhcinbadoctets_hi;
+ u32 rx_stat_ifhcinbadoctets_lo;
+
+ /* out_bad_octets */
+ u32 tx_stat_ifhcoutbadoctets_hi;
+ u32 tx_stat_ifhcoutbadoctets_lo;
+
+ /* crc_receive_errors */
+ u32 rx_stat_dot3statsfcserrors_hi;
+ u32 rx_stat_dot3statsfcserrors_lo;
+ /* alignment_errors */
+ u32 rx_stat_dot3statsalignmenterrors_hi;
+ u32 rx_stat_dot3statsalignmenterrors_lo;
+ /* carrier_sense_errors */
+ u32 rx_stat_dot3statscarriersenseerrors_hi;
+ u32 rx_stat_dot3statscarriersenseerrors_lo;
+ /* false_carrier_detections */
+ u32 rx_stat_falsecarriererrors_hi;
+ u32 rx_stat_falsecarriererrors_lo;
+
+ /* runt_packets_received */
+ u32 rx_stat_etherstatsundersizepkts_hi;
+ u32 rx_stat_etherstatsundersizepkts_lo;
+ /* jabber_packets_received */
+ u32 rx_stat_dot3statsframestoolong_hi;
+ u32 rx_stat_dot3statsframestoolong_lo;
+
+ /* error_runt_packets_received */
+ u32 rx_stat_etherstatsfragments_hi;
+ u32 rx_stat_etherstatsfragments_lo;
+ /* error_jabber_packets_received */
+ u32 rx_stat_etherstatsjabbers_hi;
+ u32 rx_stat_etherstatsjabbers_lo;
+
+ /* control_frames_received */
+ u32 rx_stat_maccontrolframesreceived_hi;
+ u32 rx_stat_maccontrolframesreceived_lo;
+ u32 rx_stat_bmac_xpf_hi;
+ u32 rx_stat_bmac_xpf_lo;
+ u32 rx_stat_bmac_xcf_hi;
+ u32 rx_stat_bmac_xcf_lo;
+
+ /* xoff_state_entered */
+ u32 rx_stat_xoffstateentered_hi;
+ u32 rx_stat_xoffstateentered_lo;
+ /* pause_xon_frames_received */
+ u32 rx_stat_xonpauseframesreceived_hi;
+ u32 rx_stat_xonpauseframesreceived_lo;
+ /* pause_xoff_frames_received */
+ u32 rx_stat_xoffpauseframesreceived_hi;
+ u32 rx_stat_xoffpauseframesreceived_lo;
+ /* pause_xon_frames_transmitted */
+ u32 tx_stat_outxonsent_hi;
+ u32 tx_stat_outxonsent_lo;
+ /* pause_xoff_frames_transmitted */
+ u32 tx_stat_outxoffsent_hi;
+ u32 tx_stat_outxoffsent_lo;
+ /* flow_control_done */
+ u32 tx_stat_flowcontroldone_hi;
+ u32 tx_stat_flowcontroldone_lo;
+
+ /* ether_stats_collisions */
+ u32 tx_stat_etherstatscollisions_hi;
+ u32 tx_stat_etherstatscollisions_lo;
+ /* single_collision_transmit_frames */
+ u32 tx_stat_dot3statssinglecollisionframes_hi;
+ u32 tx_stat_dot3statssinglecollisionframes_lo;
+ /* multiple_collision_transmit_frames */
+ u32 tx_stat_dot3statsmultiplecollisionframes_hi;
+ u32 tx_stat_dot3statsmultiplecollisionframes_lo;
+ /* deferred_transmissions */
+ u32 tx_stat_dot3statsdeferredtransmissions_hi;
+ u32 tx_stat_dot3statsdeferredtransmissions_lo;
+ /* excessive_collision_frames */
+ u32 tx_stat_dot3statsexcessivecollisions_hi;
+ u32 tx_stat_dot3statsexcessivecollisions_lo;
+ /* late_collision_frames */
+ u32 tx_stat_dot3statslatecollisions_hi;
+ u32 tx_stat_dot3statslatecollisions_lo;
+
+ /* frames_transmitted_64_bytes */
+ u32 tx_stat_etherstatspkts64octets_hi;
+ u32 tx_stat_etherstatspkts64octets_lo;
+ /* frames_transmitted_65_127_bytes */
+ u32 tx_stat_etherstatspkts65octetsto127octets_hi;
+ u32 tx_stat_etherstatspkts65octetsto127octets_lo;
+ /* frames_transmitted_128_255_bytes */
+ u32 tx_stat_etherstatspkts128octetsto255octets_hi;
+ u32 tx_stat_etherstatspkts128octetsto255octets_lo;
+ /* frames_transmitted_256_511_bytes */
+ u32 tx_stat_etherstatspkts256octetsto511octets_hi;
+ u32 tx_stat_etherstatspkts256octetsto511octets_lo;
+ /* frames_transmitted_512_1023_bytes */
+ u32 tx_stat_etherstatspkts512octetsto1023octets_hi;
+ u32 tx_stat_etherstatspkts512octetsto1023octets_lo;
+ /* frames_transmitted_1024_1522_bytes */
+ u32 tx_stat_etherstatspkts1024octetsto1522octets_hi;
+ u32 tx_stat_etherstatspkts1024octetsto1522octets_lo;
+ /* frames_transmitted_1523_9022_bytes */
+ u32 tx_stat_etherstatspktsover1522octets_hi;
+ u32 tx_stat_etherstatspktsover1522octets_lo;
+ u32 tx_stat_bmac_2047_hi;
+ u32 tx_stat_bmac_2047_lo;
+ u32 tx_stat_bmac_4095_hi;
+ u32 tx_stat_bmac_4095_lo;
+ u32 tx_stat_bmac_9216_hi;
+ u32 tx_stat_bmac_9216_lo;
+ u32 tx_stat_bmac_16383_hi;
+ u32 tx_stat_bmac_16383_lo;
+
+ /* internal_mac_transmit_errors */
+ u32 tx_stat_dot3statsinternalmactransmiterrors_hi;
+ u32 tx_stat_dot3statsinternalmactransmiterrors_lo;
+
+ /* if_out_discards */
+ u32 tx_stat_bmac_ufl_hi;
+ u32 tx_stat_bmac_ufl_lo;
+};
+
+
+#define MAC_STX_IDX_MAX 2
+
+struct host_port_stats {
+ u32 host_port_stats_start;
+
+ struct mac_stx mac_stx[MAC_STX_IDX_MAX];
+
+ u32 brb_drop_hi;
+ u32 brb_drop_lo;
+
+ u32 host_port_stats_end;
+};
+
+
+struct host_func_stats {
+ u32 host_func_stats_start;
+
+ u32 total_bytes_received_hi;
+ u32 total_bytes_received_lo;
+
+ u32 total_bytes_transmitted_hi;
+ u32 total_bytes_transmitted_lo;
+
+ u32 total_unicast_packets_received_hi;
+ u32 total_unicast_packets_received_lo;
+
+ u32 total_multicast_packets_received_hi;
+ u32 total_multicast_packets_received_lo;
+
+ u32 total_broadcast_packets_received_hi;
+ u32 total_broadcast_packets_received_lo;
+
+ u32 total_unicast_packets_transmitted_hi;
+ u32 total_unicast_packets_transmitted_lo;
+
+ u32 total_multicast_packets_transmitted_hi;
+ u32 total_multicast_packets_transmitted_lo;
+
+ u32 total_broadcast_packets_transmitted_hi;
+ u32 total_broadcast_packets_transmitted_lo;
+
+ u32 valid_bytes_received_hi;
+ u32 valid_bytes_received_lo;
+
+ u32 host_func_stats_end;
+};
+
+
#define BCM_5710_FW_MAJOR_VERSION 4
-#define BCM_5710_FW_MINOR_VERSION 0
-#define BCM_5710_FW_REVISION_VERSION 14
+#define BCM_5710_FW_MINOR_VERSION 5
+#define BCM_5710_FW_REVISION_VERSION 1
#define BCM_5710_FW_COMPILE_FLAGS 1
@@ -793,7 +1252,7 @@ struct doorbell_hdr {
};
/*
- * doorbell message send to the chip
+ * doorbell message sent to the chip
*/
struct doorbell {
#if defined(__BIG_ENDIAN)
@@ -849,8 +1308,10 @@ struct parsing_flags {
u16 flags;
#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0)
#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0
-#define PARSING_FLAGS_NUMBER_OF_NESTED_VLANS (0x3<<1)
-#define PARSING_FLAGS_NUMBER_OF_NESTED_VLANS_SHIFT 1
+#define PARSING_FLAGS_VLAN (0x1<<1)
+#define PARSING_FLAGS_VLAN_SHIFT 1
+#define PARSING_FLAGS_EXTRA_VLAN (0x1<<2)
+#define PARSING_FLAGS_EXTRA_VLAN_SHIFT 2
#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL (0x3<<3)
#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT 3
#define PARSING_FLAGS_IP_OPTIONS (0x1<<5)
@@ -874,6 +1335,12 @@ struct parsing_flags {
};
+struct regpair {
+ u32 lo;
+ u32 hi;
+};
+
+
/*
* dmae command structure
*/
@@ -901,8 +1368,10 @@ struct dmae_command {
#define DMAE_COMMAND_SRC_RESET_SHIFT 13
#define DMAE_COMMAND_DST_RESET (0x1<<14)
#define DMAE_COMMAND_DST_RESET_SHIFT 14
-#define DMAE_COMMAND_RESERVED0 (0x1FFFF<<15)
-#define DMAE_COMMAND_RESERVED0_SHIFT 15
+#define DMAE_COMMAND_E1HVN (0x3<<15)
+#define DMAE_COMMAND_E1HVN_SHIFT 15
+#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17)
+#define DMAE_COMMAND_RESERVED0_SHIFT 17
u32 src_addr_lo;
u32 src_addr_hi;
u32 dst_addr_lo;
@@ -952,72 +1421,107 @@ struct double_regpair {
/*
- * The eth Rx Buffer Descriptor
- */
-struct eth_rx_bd {
- u32 addr_lo;
- u32 addr_hi;
-};
-
-/*
- * The eth storm context of Ustorm
+ * The eth storm context of Ustorm (configuration part)
*/
-struct ustorm_eth_st_context {
+struct ustorm_eth_st_context_config {
#if defined(__BIG_ENDIAN)
- u8 sb_index_number;
+ u8 flags;
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
u8 status_block_id;
- u8 __local_rx_bd_cons;
- u8 __local_rx_bd_prod;
+ u8 clientId;
+ u8 sb_index_numbers;
+#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0
+#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4
#elif defined(__LITTLE_ENDIAN)
- u8 __local_rx_bd_prod;
- u8 __local_rx_bd_cons;
+ u8 sb_index_numbers;
+#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0
+#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4
+ u8 clientId;
u8 status_block_id;
- u8 sb_index_number;
+ u8 flags;
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
#endif
#if defined(__BIG_ENDIAN)
- u16 rcq_cons;
- u16 rx_bd_cons;
+ u16 bd_buff_size;
+ u16 mc_alignment_size;
#elif defined(__LITTLE_ENDIAN)
- u16 rx_bd_cons;
- u16 rcq_cons;
+ u16 mc_alignment_size;
+ u16 bd_buff_size;
#endif
- u32 rx_bd_page_base_lo;
- u32 rx_bd_page_base_hi;
- u32 rcq_base_address_lo;
- u32 rcq_base_address_hi;
#if defined(__BIG_ENDIAN)
- u16 __num_of_returned_cqes;
- u8 num_rss;
- u8 flags;
-#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT (0x1<<0)
-#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC (0x1<<1)
-#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC_SHIFT 1
-#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA (0x1<<2)
-#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA_SHIFT 2
-#define __USTORM_ETH_ST_CONTEXT_RESERVED0 (0x1F<<3)
-#define __USTORM_ETH_ST_CONTEXT_RESERVED0_SHIFT 3
+ u8 __local_sge_prod;
+ u8 __local_bd_prod;
+ u16 sge_buff_size;
#elif defined(__LITTLE_ENDIAN)
- u8 flags;
-#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT (0x1<<0)
-#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC (0x1<<1)
-#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC_SHIFT 1
-#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA (0x1<<2)
-#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA_SHIFT 2
-#define __USTORM_ETH_ST_CONTEXT_RESERVED0 (0x1F<<3)
-#define __USTORM_ETH_ST_CONTEXT_RESERVED0_SHIFT 3
- u8 num_rss;
- u16 __num_of_returned_cqes;
+ u16 sge_buff_size;
+ u8 __local_bd_prod;
+ u8 __local_sge_prod;
#endif
#if defined(__BIG_ENDIAN)
- u16 mc_alignment_size;
- u16 agg_threshold;
+ u16 __bd_cons;
+ u16 __sge_cons;
#elif defined(__LITTLE_ENDIAN)
- u16 agg_threshold;
- u16 mc_alignment_size;
+ u16 __sge_cons;
+ u16 __bd_cons;
#endif
+ u32 bd_page_base_lo;
+ u32 bd_page_base_hi;
+ u32 sge_page_base_lo;
+ u32 sge_page_base_hi;
+};
+
+/*
+ * The eth Rx Buffer Descriptor
+ */
+struct eth_rx_bd {
+ u32 addr_lo;
+ u32 addr_hi;
+};
+
+/*
+ * The eth Rx SGE Descriptor
+ */
+struct eth_rx_sge {
+ u32 addr_lo;
+ u32 addr_hi;
+};
+
+/*
+ * Local BDs and SGEs rings (in ETH)
+ */
+struct eth_local_rx_rings {
struct eth_rx_bd __local_bd_ring[16];
+ struct eth_rx_sge __local_sge_ring[12];
+};
+
+/*
+ * The eth storm context of Ustorm
+ */
+struct ustorm_eth_st_context {
+ struct ustorm_eth_st_context_config common;
+ struct eth_local_rx_rings __rings;
};
/*
@@ -1088,9 +1592,9 @@ struct xstorm_eth_extra_ag_context_section {
#if defined(__BIG_ENDIAN)
u16 __reserved3;
u8 __reserved2;
- u8 __agg_misc7;
+ u8 __da_only_cnt;
#elif defined(__LITTLE_ENDIAN)
- u8 __agg_misc7;
+ u8 __da_only_cnt;
u8 __reserved2;
u16 __reserved3;
#endif
@@ -1368,7 +1872,13 @@ struct timers_block_context {
u32 __reserved_0;
u32 __reserved_1;
u32 __reserved_2;
- u32 __reserved_flags;
+ u32 flags;
+#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0)
+#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0
+#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2)
+#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2
+#define __TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3)
+#define __TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3
};
/*
@@ -1478,11 +1988,19 @@ struct xstorm_eth_st_context {
u32 tx_bd_page_base_hi;
#if defined(__BIG_ENDIAN)
u16 tx_bd_cons;
- u8 __reserved0;
+ u8 statistics_data;
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0)
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7)
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
u8 __local_tx_bd_prod;
#elif defined(__LITTLE_ENDIAN)
u8 __local_tx_bd_prod;
- u8 __reserved0;
+ u8 statistics_data;
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0)
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7)
+#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
u16 tx_bd_cons;
#endif
u32 db_data_addr_lo;
@@ -1559,7 +2077,7 @@ struct eth_tx_doorbell {
struct ustorm_def_status_block {
u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
u16 status_block_index;
- u8 reserved0;
+ u8 func;
u8 status_block_id;
u32 __flags;
};
@@ -1570,7 +2088,7 @@ struct ustorm_def_status_block {
struct cstorm_def_status_block {
u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
u16 status_block_index;
- u8 reserved0;
+ u8 func;
u8 status_block_id;
u32 __flags;
};
@@ -1581,7 +2099,7 @@ struct cstorm_def_status_block {
struct xstorm_def_status_block {
u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
u16 status_block_index;
- u8 reserved0;
+ u8 func;
u8 status_block_id;
u32 __flags;
};
@@ -1592,7 +2110,7 @@ struct xstorm_def_status_block {
struct tstorm_def_status_block {
u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
u16 status_block_index;
- u8 reserved0;
+ u8 func;
u8 status_block_id;
u32 __flags;
};
@@ -1615,7 +2133,7 @@ struct host_def_status_block {
struct ustorm_status_block {
u16 index_values[HC_USTORM_SB_NUM_INDICES];
u16 status_block_index;
- u8 reserved0;
+ u8 func;
u8 status_block_id;
u32 __flags;
};
@@ -1626,7 +2144,7 @@ struct ustorm_status_block {
struct cstorm_status_block {
u16 index_values[HC_CSTORM_SB_NUM_INDICES];
u16 status_block_index;
- u8 reserved0;
+ u8 func;
u8 status_block_id;
u32 __flags;
};
@@ -1664,20 +2182,21 @@ struct eth_dynamic_hc_config {
* regular eth FP CQE parameters struct
*/
struct eth_fast_path_rx_cqe {
- u8 type;
- u8 error_type_flags;
-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<0)
-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 0
-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<1)
-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 1
-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<2)
-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 2
-#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<3)
-#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 3
-#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<4)
-#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 4
-#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x7<<5)
-#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 5
+ u8 type_error_flags;
+#define ETH_FAST_PATH_RX_CQE_TYPE (0x1<<0)
+#define ETH_FAST_PATH_RX_CQE_TYPE_SHIFT 0
+#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<1)
+#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 1
+#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<2)
+#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 2
+#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<3)
+#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 3
+#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<4)
+#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4
+#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5)
+#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5
+#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6)
+#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6
u8 status_flags;
#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0)
#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0
@@ -1692,11 +2211,13 @@ struct eth_fast_path_rx_cqe {
#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7)
#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7
u8 placement_offset;
+ u8 queue_index;
u32 rss_hash_result;
u16 vlan_tag;
u16 pkt_len;
- u16 queue_index;
+ u16 len_on_bd;
struct parsing_flags pars_flags;
+ u16 sgl[8];
};
@@ -1710,6 +2231,23 @@ struct eth_halt_ramrod_data {
/*
+ * The data for statistics query ramrod
+ */
+struct eth_query_ramrod_data {
+#if defined(__BIG_ENDIAN)
+ u8 reserved0;
+ u8 collect_port_1b;
+ u16 drv_counter;
+#elif defined(__LITTLE_ENDIAN)
+ u16 drv_counter;
+ u8 collect_port_1b;
+ u8 reserved0;
+#endif
+ u32 ctr_id_vector;
+};
+
+
+/*
* Place holder for ramrods protocol specific data
*/
struct ramrod_data {
@@ -1739,15 +2277,20 @@ struct eth_rx_bd_next_page {
* Eth Rx Cqe structure- general structure for ramrods
*/
struct common_ramrod_eth_rx_cqe {
- u8 type;
+ u8 ramrod_type;
+#define COMMON_RAMROD_ETH_RX_CQE_TYPE (0x1<<0)
+#define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0
+#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x7F<<1)
+#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 1
u8 conn_type_3b;
- u16 reserved;
+ u16 reserved1;
u32 conn_and_cmd_data;
#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0)
#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0
#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24)
#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24
struct ramrod_data protocol_data;
+ u32 reserved2[4];
};
/*
@@ -1756,8 +2299,7 @@ struct common_ramrod_eth_rx_cqe {
struct eth_rx_cqe_next_page {
u32 addr_lo;
u32 addr_hi;
- u32 reserved0;
- u32 reserved1;
+ u32 reserved[6];
};
/*
@@ -1787,11 +2329,6 @@ struct spe_hdr {
u16 reserved;
};
-struct regpair {
- u32 lo;
- u32 hi;
-};
-
/*
* ethernet slow path element
*/
@@ -1802,6 +2339,7 @@ union eth_specific_data {
struct eth_halt_ramrod_data halt_ramrod_data;
struct regpair leading_cqe_addr;
struct regpair update_data_addr;
+ struct eth_query_ramrod_data query_ramrod_data;
};
/*
@@ -1824,10 +2362,13 @@ struct eth_tx_db_data {
/*
- * Common configuration parameters per port in Tstorm
+ * Common configuration parameters per function in Tstorm
*/
struct tstorm_eth_function_common_config {
- u32 config_flags;
+#if defined(__BIG_ENDIAN)
+ u8 leading_client_id;
+ u8 rss_result_mask;
+ u16 config_flags;
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1)
@@ -1840,17 +2381,32 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3FFFFFF<<6)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 6
-#if defined(__BIG_ENDIAN)
- u16 __secondary_vlan_id;
- u8 leading_client_id;
- u8 rss_result_mask;
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
#elif defined(__LITTLE_ENDIAN)
+ u16 config_flags;
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
u8 rss_result_mask;
u8 leading_client_id;
- u16 __secondary_vlan_id;
#endif
+ u16 vlan_id[2];
};
/*
@@ -1868,7 +2424,7 @@ struct eth_update_ramrod_data {
struct mac_configuration_hdr {
u8 length_6b;
u8 offset;
- u16 reserved0;
+ u16 client_id;
u32 reserved1;
};
@@ -1925,15 +2481,55 @@ struct mac_configuration_cmd {
/*
+ * MAC address in list for ramrod
+ */
+struct mac_configuration_entry_e1h {
+ u16 lsb_mac_addr;
+ u16 middle_mac_addr;
+ u16 msb_mac_addr;
+ u16 vlan_id;
+ u16 e1hov_id;
+ u8 client_id;
+ u8 flags;
+#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
+#define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0
+#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE (0x1<<1)
+#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1
+#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2)
+#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2
+#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED0 (0x1F<<3)
+#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED0_SHIFT 3
+};
+
+/*
+ * MAC filtering configuration command
+ */
+struct mac_configuration_cmd_e1h {
+ struct mac_configuration_hdr hdr;
+ struct mac_configuration_entry_e1h config_table[32];
+};
+
+
+/*
+ * approximate-match multicast filtering for E1H per function in Tstorm
+ */
+struct tstorm_eth_approximate_match_multicast_filtering {
+ u32 mcast_add_hash_bit_array[8];
+};
+
+
+/*
* Configuration parameters per client in Tstorm
*/
struct tstorm_eth_client_config {
#if defined(__BIG_ENDIAN)
- u16 statistics_counter_id;
+ u8 max_sges_for_packet;
+ u8 statistics_counter_id;
u16 mtu;
#elif defined(__LITTLE_ENDIAN)
u16 mtu;
- u16 statistics_counter_id;
+ u8 statistics_counter_id;
+ u8 max_sges_for_packet;
#endif
#if defined(__BIG_ENDIAN)
u16 drop_flags;
@@ -1941,42 +2537,42 @@ struct tstorm_eth_client_config {
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 3
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<4)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 4
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x7FF<<5)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 5
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
u16 config_flags;
#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x3FFF<<2)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
#elif defined(__LITTLE_ENDIAN)
u16 config_flags;
#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x3FFF<<2)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
u16 drop_flags;
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 3
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<4)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 4
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x7FF<<5)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 5
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
#endif
};
@@ -1992,103 +2588,119 @@ struct tstorm_eth_mac_filter_config {
u32 bcast_drop_all;
u32 bcast_accept_all;
u32 strict_vlan;
- u32 __secondary_vlan_clients;
+ u32 vlan_filter[2];
+ u32 reserved;
};
-struct rate_shaping_per_protocol {
+/*
+ * Three RX producers for ETH
+ */
+struct tstorm_eth_rx_producers {
#if defined(__BIG_ENDIAN)
- u16 reserved0;
- u16 protocol_rate;
+ u16 bd_prod;
+ u16 cqe_prod;
#elif defined(__LITTLE_ENDIAN)
- u16 protocol_rate;
- u16 reserved0;
+ u16 cqe_prod;
+ u16 bd_prod;
#endif
- u32 protocol_quota;
- s32 current_credit;
- u32 reserved;
-};
-
-struct rate_shaping_vars {
- struct rate_shaping_per_protocol protocol_vars[NUM_OF_PROTOCOLS];
- u32 pause_mask;
- u32 periodic_stop;
- u32 rs_periodic_timeout;
- u32 rs_threshold;
- u32 last_periodic_time;
- u32 reserved;
-};
-
-struct fairness_per_protocol {
- u32 credit_delta;
- s32 fair_credit;
#if defined(__BIG_ENDIAN)
- u16 reserved0;
- u8 state;
- u8 weight;
+ u16 reserved;
+ u16 sge_prod;
#elif defined(__LITTLE_ENDIAN)
- u8 weight;
- u8 state;
- u16 reserved0;
+ u16 sge_prod;
+ u16 reserved;
#endif
- u32 reserved1;
};
-struct fairness_vars {
- struct fairness_per_protocol protocol_vars[NUM_OF_PROTOCOLS];
- u32 upper_bound;
- u32 port_rate;
- u32 pause_mask;
- u32 fair_threshold;
-};
-struct safc_struct {
- u32 cur_pause_mask;
- u32 expire_time;
+/*
+ * common flag to indicate existance of TPA.
+ */
+struct tstorm_eth_tpa_exist {
#if defined(__BIG_ENDIAN)
- u16 reserved0;
- u8 cur_cos_types;
- u8 safc_timeout_usec;
+ u16 reserved1;
+ u8 reserved0;
+ u8 tpa_exist;
#elif defined(__LITTLE_ENDIAN)
- u8 safc_timeout_usec;
- u8 cur_cos_types;
- u16 reserved0;
+ u8 tpa_exist;
+ u8 reserved0;
+ u16 reserved1;
#endif
- u32 reserved1;
+ u32 reserved2;
};
-struct demo_struct {
+
+/*
+ * per-port SAFC demo variables
+ */
+struct cmng_flags_per_port {
u8 con_number[NUM_OF_PROTOCOLS];
#if defined(__BIG_ENDIAN)
- u8 reserved1;
u8 fairness_enable;
u8 rate_shaping_enable;
- u8 cmng_enable;
+ u8 cmng_protocol_enable;
+ u8 cmng_vn_enable;
#elif defined(__LITTLE_ENDIAN)
- u8 cmng_enable;
+ u8 cmng_vn_enable;
+ u8 cmng_protocol_enable;
u8 rate_shaping_enable;
u8 fairness_enable;
- u8 reserved1;
#endif
};
-struct cmng_struct {
- struct rate_shaping_vars rs_vars;
- struct fairness_vars fair_vars;
- struct safc_struct safc_vars;
- struct demo_struct demo_vars;
+
+/*
+ * per-port rate shaping variables
+ */
+struct rate_shaping_vars_per_port {
+ u32 rs_periodic_timeout;
+ u32 rs_threshold;
};
-struct cos_to_protocol {
- u8 mask[MAX_COS_NUMBER];
+/*
+ * per-port fairness variables
+ */
+struct fairness_vars_per_port {
+ u32 upper_bound;
+ u32 fair_threshold;
+ u32 fairness_timeout;
};
/*
- * Common statistics collected by the Xstorm (per port)
+ * per-port SAFC variables
*/
-struct xstorm_common_stats {
+struct safc_struct_per_port {
+#if defined(__BIG_ENDIAN)
+ u16 __reserved0;
+ u8 cur_cos_types;
+ u8 safc_timeout_usec;
+#elif defined(__LITTLE_ENDIAN)
+ u8 safc_timeout_usec;
+ u8 cur_cos_types;
+ u16 __reserved0;
+#endif
+ u8 cos_to_protocol[MAX_COS_NUMBER];
+};
+
+
+/*
+ * Per-port congestion management variables
+ */
+struct cmng_struct_per_port {
+ struct rate_shaping_vars_per_port rs_vars;
+ struct fairness_vars_per_port fair_vars;
+ struct safc_struct_per_port safc_vars;
+ struct cmng_flags_per_port flags;
+};
+
+
+/*
+ * Protocol-common statistics collected by the Xstorm (per client)
+ */
+struct xstorm_per_client_stats {
struct regpair total_sent_bytes;
u32 total_sent_pkts;
u32 unicast_pkts_sent;
@@ -2097,9 +2709,31 @@ struct xstorm_common_stats {
u32 multicast_pkts_sent;
u32 broadcast_pkts_sent;
struct regpair broadcast_bytes_sent;
- struct regpair done;
+ u16 stats_counter;
+ u16 reserved0;
+ u32 reserved1;
};
+
+/*
+ * Common statistics collected by the Xstorm (per port)
+ */
+struct xstorm_common_stats {
+ struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID];
+};
+
+
+/*
+ * Protocol-common statistics collected by the Tstorm (per port)
+ */
+struct tstorm_per_port_stats {
+ u32 mac_filter_discard;
+ u32 xxoverflow_discard;
+ u32 brb_truncate_discard;
+ u32 mac_discard;
+};
+
+
/*
* Protocol-common statistics collected by the Tstorm (per client)
*/
@@ -2117,20 +2751,17 @@ struct tstorm_per_client_stats {
u32 rcv_multicast_pkts;
u32 no_buff_discard;
u32 ttl0_discard;
- u32 mac_discard;
- u32 reserved;
+ u16 stats_counter;
+ u16 reserved0;
+ u32 reserved1;
};
/*
- * Protocol-common statistics collected by the Tstorm (per port)
+ * Protocol-common statistics collected by the Tstorm
*/
struct tstorm_common_stats {
- struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID];
- u32 mac_filter_discard;
- u32 xxoverflow_discard;
- u32 brb_truncate_discard;
- u32 reserved;
- struct regpair done;
+ struct tstorm_per_port_stats port_statistics;
+ struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID];
};
/*
@@ -2143,6 +2774,16 @@ struct eth_stats_query {
/*
+ * per-vnic fairness variables
+ */
+struct fairness_vars_per_vn {
+ u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
+ u32 vn_credit_delta;
+ u32 __reserved0;
+};
+
+
+/*
* FW version stored in the Xstorm RAM
*/
struct fw_version {
@@ -2160,8 +2801,10 @@ struct fw_version {
#define FW_VERSION_OPTIMIZED_SHIFT 0
#define FW_VERSION_BIG_ENDIEN (0x1<<1)
#define FW_VERSION_BIG_ENDIEN_SHIFT 1
-#define __FW_VERSION_RESERVED (0x3FFFFFFF<<2)
-#define __FW_VERSION_RESERVED_SHIFT 2
+#define FW_VERSION_CHIP_VERSION (0x3<<2)
+#define FW_VERSION_CHIP_VERSION_SHIFT 2
+#define __FW_VERSION_RESERVED (0xFFFFFFF<<4)
+#define __FW_VERSION_RESERVED_SHIFT 4
};
@@ -2169,15 +2812,9 @@ struct fw_version {
* FW version stored in first line of pram
*/
struct pram_fw_version {
-#if defined(__BIG_ENDIAN)
- u16 patch;
- u8 primary;
- u8 client;
-#elif defined(__LITTLE_ENDIAN)
u8 client;
u8 primary;
u16 patch;
-#endif
u8 flags;
#define PRAM_FW_VERSION_OPTIMIZED (0x1<<0)
#define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0
@@ -2185,8 +2822,34 @@ struct pram_fw_version {
#define PRAM_FW_VERSION_STORM_ID_SHIFT 1
#define PRAM_FW_VERSION_BIG_ENDIEN (0x1<<3)
#define PRAM_FW_VERSION_BIG_ENDIEN_SHIFT 3
-#define __PRAM_FW_VERSION_RESERVED0 (0xF<<4)
-#define __PRAM_FW_VERSION_RESERVED0_SHIFT 4
+#define PRAM_FW_VERSION_CHIP_VERSION (0x3<<4)
+#define PRAM_FW_VERSION_CHIP_VERSION_SHIFT 4
+#define __PRAM_FW_VERSION_RESERVED0 (0x3<<6)
+#define __PRAM_FW_VERSION_RESERVED0_SHIFT 6
+};
+
+
+/*
+ * a single rate shaping counter. can be used as protocol or vnic counter
+ */
+struct rate_shaping_counter {
+ u32 quota;
+#if defined(__BIG_ENDIAN)
+ u16 __reserved0;
+ u16 rate;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rate;
+ u16 __reserved0;
+#endif
+};
+
+
+/*
+ * per-vnic rate shaping variables
+ */
+struct rate_shaping_vars_per_vn {
+ struct rate_shaping_counter protocol_counters[NUM_OF_PROTOCOLS];
+ struct rate_shaping_counter vn_counter;
};
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 370686eef97..4c7750789b6 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -22,7 +22,8 @@
#define INIT_ASIC 0x4
#define INIT_HARDWARE 0x7
-#define STORM_INTMEM_SIZE (0x5800 / 4)
+#define STORM_INTMEM_SIZE_E1 (0x5800 / 4)
+#define STORM_INTMEM_SIZE_E1H (0x10000 / 4)
#define TSTORM_INTMEM_ADDR 0x1a0000
#define CSTORM_INTMEM_ADDR 0x220000
#define XSTORM_INTMEM_ADDR 0x2a0000
@@ -30,7 +31,7 @@
/* Init operation types and structures */
-
+/* Common for both E1 and E1H */
#define OP_RD 0x1 /* read single register */
#define OP_WR 0x2 /* write single register */
#define OP_IW 0x3 /* write single register using mailbox */
@@ -38,7 +39,37 @@
#define OP_SI 0x5 /* copy a string using mailbox */
#define OP_ZR 0x6 /* clear memory */
#define OP_ZP 0x7 /* unzip then copy with DMAE */
-#define OP_WB 0x8 /* copy a string using DMAE */
+#define OP_WR_64 0x8 /* write 64 bit pattern */
+#define OP_WB 0x9 /* copy a string using DMAE */
+
+/* Operation specific for E1 */
+#define OP_RD_E1 0xa /* read single register */
+#define OP_WR_E1 0xb /* write single register */
+#define OP_IW_E1 0xc /* write single register using mailbox */
+#define OP_SW_E1 0xd /* copy a string to the device */
+#define OP_SI_E1 0xe /* copy a string using mailbox */
+#define OP_ZR_E1 0xf /* clear memory */
+#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */
+#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */
+#define OP_WB_E1 0x12 /* copy a string using DMAE */
+
+/* Operation specific for E1H */
+#define OP_RD_E1H 0x13 /* read single register */
+#define OP_WR_E1H 0x14 /* write single register */
+#define OP_IW_E1H 0x15 /* write single register using mailbox */
+#define OP_SW_E1H 0x16 /* copy a string to the device */
+#define OP_SI_E1H 0x17 /* copy a string using mailbox */
+#define OP_ZR_E1H 0x18 /* clear memory */
+#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */
+#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */
+#define OP_WB_E1H 0x1b /* copy a string using DMAE */
+
+/* FPGA and EMUL specific operations */
+#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */
+#define OP_WR_EMUL 0x1d /* write single register on Emulation */
+#define OP_WR_FPGA 0x1e /* write single register on FPGA */
+#define OP_WR_ASIC 0x1f /* write single register on ASIC */
+
struct raw_op {
u32 op :8;
@@ -87,10 +118,6 @@ union init_op {
#include "bnx2x_init_values.h"
static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-
-static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
- u32 dst_addr, u32 len32);
-
static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
@@ -107,9 +134,6 @@ static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
}
}
-#define INIT_MEM_WR(reg, data, reg_off, len) \
- bnx2x_init_str_wr(bp, reg + reg_off*4, data, len)
-
static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
u16 len)
{
@@ -124,11 +148,117 @@ static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
}
}
+static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
+{
+#ifdef USE_DMAE
+ int offset = 0;
+
+ if (bp->dmae_ready) {
+ while (len > DMAE_LEN32_WR_MAX) {
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, DMAE_LEN32_WR_MAX);
+ offset += DMAE_LEN32_WR_MAX * 4;
+ len -= DMAE_LEN32_WR_MAX;
+ }
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, len);
+ } else
+ bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
+#else
+ bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
+#endif
+}
+
+static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
+{
+ if ((len * 4) > FW_BUF_SIZE) {
+ BNX2X_ERR("LARGE DMAE OPERATION ! addr 0x%x len 0x%x\n",
+ addr, len*4);
+ return;
+ }
+ memset(bp->gunzip_buf, fill, len * 4);
+
+ bnx2x_write_big_buf(bp, addr, len);
+}
+
+static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
+ u32 len64)
+{
+ u32 buf_len32 = FW_BUF_SIZE/4;
+ u32 len = len64*2;
+ u64 data64 = 0;
+ int i;
+
+ /* 64 bit value is in a blob: first low DWORD, then high DWORD */
+ data64 = HILO_U64((*(data + 1)), (*data));
+ len64 = min((u32)(FW_BUF_SIZE/8), len64);
+ for (i = 0; i < len64; i++) {
+ u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
+
+ *pdata = data64;
+ }
+
+ for (i = 0; i < len; i += buf_len32) {
+ u32 cur_len = min(buf_len32, len - i);
+
+ bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+ }
+}
+
+/*********************************************************
+ There are different blobs for each PRAM section.
+ In addition, each blob write operation is divided into a few operations
+ in order to decrease the amount of phys. contigious buffer needed.
+ Thus, when we select a blob the address may be with some offset
+ from the beginning of PRAM section.
+ The same holds for the INT_TABLE sections.
+**********************************************************/
+#define IF_IS_INT_TABLE_ADDR(base, addr) \
+ if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
+
+#define IF_IS_PRAM_ADDR(base, addr) \
+ if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
+
+static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
+{
+ IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
+ data = is_e1 ? tsem_int_table_data_e1 :
+ tsem_int_table_data_e1h;
+ else
+ IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
+ data = is_e1 ? csem_int_table_data_e1 :
+ csem_int_table_data_e1h;
+ else
+ IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
+ data = is_e1 ? usem_int_table_data_e1 :
+ usem_int_table_data_e1h;
+ else
+ IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
+ data = is_e1 ? xsem_int_table_data_e1 :
+ xsem_int_table_data_e1h;
+ else
+ IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
+ data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
+ else
+ IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
+ data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
+ else
+ IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
+ data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
+ else
+ IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
+ data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
+
+ return data;
+}
+
static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len, int gunzip)
+ u32 len, int gunzip, int is_e1, u32 blob_off)
{
int offset = 0;
+ data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
+
if (gunzip) {
int rc;
#ifdef __BIG_ENDIAN
@@ -143,64 +273,59 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
#endif
rc = bnx2x_gunzip(bp, (u8 *)data, len);
if (rc) {
- DP(NETIF_MSG_HW, "gunzip failed ! rc %d\n", rc);
+ BNX2X_ERR("gunzip failed ! rc %d\n", rc);
return;
}
len = bp->gunzip_outlen;
#ifdef __BIG_ENDIAN
kfree(temp);
for (i = 0; i < len; i++)
- ((u32 *)bp->gunzip_buf)[i] =
+ ((u32 *)bp->gunzip_buf)[i] =
swab32(((u32 *)bp->gunzip_buf)[i]);
#endif
} else {
if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len*4);
+ BNX2X_ERR("LARGE DMAE OPERATION ! "
+ "addr 0x%x len 0x%x\n", addr, len*4);
return;
}
memcpy(bp->gunzip_buf, data, len * 4);
}
- while (len > DMAE_LEN32_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_MAX);
- offset += DMAE_LEN32_MAX * 4;
- len -= DMAE_LEN32_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len);
-}
-
-#define INIT_MEM_WB(reg, data, reg_off, len) \
- bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 0)
-
-#define INIT_GUNZIP_DMAE(reg, data, reg_off, len) \
- bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 1)
-
-static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
-{
- int offset = 0;
-
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len * 4);
- return;
- }
- memset(bp->gunzip_buf, fill, len * 4);
-
- while (len > DMAE_LEN32_MAX) {
+ if (bp->dmae_ready) {
+ while (len > DMAE_LEN32_WR_MAX) {
+ bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+ addr + offset, DMAE_LEN32_WR_MAX);
+ offset += DMAE_LEN32_WR_MAX * 4;
+ len -= DMAE_LEN32_WR_MAX;
+ }
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_MAX);
- offset += DMAE_LEN32_MAX * 4;
- len -= DMAE_LEN32_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len);
+ addr + offset, len);
+ } else
+ bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
}
static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
{
- int i;
+ int is_e1 = CHIP_IS_E1(bp);
+ int is_e1h = CHIP_IS_E1H(bp);
+ int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
+ int hw_wr, i;
union init_op *op;
u32 op_type, addr, len;
- const u32 *data;
+ const u32 *data, *data_base;
+
+ if (CHIP_REV_IS_FPGA(bp))
+ hw_wr = OP_WR_FPGA;
+ else if (CHIP_REV_IS_EMUL(bp))
+ hw_wr = OP_WR_EMUL;
+ else
+ hw_wr = OP_WR_ASIC;
+
+ if (is_e1)
+ data_base = init_data_e1;
+ else /* CHIP_IS_E1H(bp) */
+ data_base = init_data_e1h;
for (i = op_start; i < op_end; i++) {
@@ -209,7 +334,30 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
op_type = op->str_wr.op;
addr = op->str_wr.offset;
len = op->str_wr.data_len;
- data = init_data + op->str_wr.data_off;
+ data = data_base + op->str_wr.data_off;
+
+ /* carefull! it must be in order */
+ if (unlikely(op_type > OP_WB)) {
+
+ /* If E1 only */
+ if (op_type <= OP_WB_E1) {
+ if (is_e1)
+ op_type -= (OP_RD_E1 - OP_RD);
+
+ /* If E1H only */
+ } else if (op_type <= OP_WB_E1H) {
+ if (is_e1h)
+ op_type -= (OP_RD_E1H - OP_RD);
+ }
+
+ /* HW/EMUL specific */
+ if (op_type == hw_wr)
+ op_type = OP_WR;
+
+ /* EMUL on E1H is special */
+ if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
+ op_type = OP_WR;
+ }
switch (op_type) {
case OP_RD:
@@ -222,7 +370,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
bnx2x_init_str_wr(bp, addr, data, len);
break;
case OP_WB:
- bnx2x_init_wr_wb(bp, addr, data, len, 0);
+ bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
break;
case OP_SI:
bnx2x_init_ind_wr(bp, addr, data, len);
@@ -231,10 +379,21 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
bnx2x_init_fill(bp, addr, 0, op->zero.len);
break;
case OP_ZP:
- bnx2x_init_wr_wb(bp, addr, data, len, 1);
+ bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
+ op->str_wr.data_off);
+ break;
+ case OP_WR_64:
+ bnx2x_init_wr_64(bp, addr, data, len);
break;
default:
- BNX2X_ERR("BAD init operation!\n");
+ /* happens whenever an op is of a diff HW */
+#if 0
+ DP(NETIF_MSG_HW, "skipping init operation "
+ "index %d[%d:%d]: type %d addr 0x%x "
+ "len %d(0x%x)\n",
+ i, op_start, op_end, op_type, addr, len, len);
+#endif
+ break;
}
}
}
@@ -245,7 +404,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
****************************************************************************/
/*
* This code configures the PCI read/write arbiter
- * which implements a wighted round robin
+ * which implements a weighted round robin
* between the virtual queues in the chip.
*
* The values were derived for each PCI max payload and max request size.
@@ -315,7 +474,7 @@ static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
{{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
};
-/* register adresses for read queues */
+/* register addresses for read queues */
static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
PXP2_REG_RQ_BW_RD_UBOUND0},
@@ -375,7 +534,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
PXP2_REG_PSWRQ_BW_UB28}
};
-/* register adresses for wrtie queues */
+/* register addresses for write queues */
static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
@@ -424,6 +583,10 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
w_order, MAX_WR_ORD);
w_order = MAX_WR_ORD;
}
+ if (CHIP_REV_IS_FPGA(bp)) {
+ DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
+ w_order = 0;
+ }
DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
for (i = 0; i < NUM_RD_Q-1; i++) {
@@ -481,7 +644,20 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
- REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16);
+
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR(bp, PXP2_REG_WR_HC_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_USDM_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_CSDM_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_TSDM_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_XSDM_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_QM_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_TM_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_SRC_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_DBG_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
+ REG_WR(bp, PXP2_REG_WR_CDU_MPS, w_order+1);
+ }
}
@@ -564,6 +740,72 @@ static u8 calc_crc8(u32 data, u8 crc)
return crc_res;
}
+/* regiesers addresses are not in order
+ so these arrays help simplify the code */
+static const int cm_start[E1H_FUNC_MAX][9] = {
+ {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
+ XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START,
+ XSEM_FUNC0_START},
+ {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
+ XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
+ XSEM_FUNC1_START},
+ {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
+ XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
+ XSEM_FUNC2_START},
+ {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
+ XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
+ XSEM_FUNC3_START},
+ {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
+ XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
+ XSEM_FUNC4_START},
+ {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
+ XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
+ XSEM_FUNC5_START},
+ {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
+ XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
+ XSEM_FUNC6_START},
+ {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
+ XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
+ XSEM_FUNC7_START}
+};
+
+static const int cm_end[E1H_FUNC_MAX][9] = {
+ {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
+ XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
+ XSEM_FUNC0_END},
+ {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
+ XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
+ XSEM_FUNC1_END},
+ {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
+ XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
+ XSEM_FUNC2_END},
+ {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
+ XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
+ XSEM_FUNC3_END},
+ {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
+ XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
+ XSEM_FUNC4_END},
+ {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
+ XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
+ XSEM_FUNC5_END},
+ {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
+ XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
+ XSEM_FUNC6_END},
+ {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
+ XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
+ XSEM_FUNC7_END},
+};
+
+static const int hc_limits[E1H_FUNC_MAX][2] = {
+ {HC_FUNC0_START, HC_FUNC0_END},
+ {HC_FUNC1_START, HC_FUNC1_END},
+ {HC_FUNC2_START, HC_FUNC2_END},
+ {HC_FUNC3_START, HC_FUNC3_END},
+ {HC_FUNC4_START, HC_FUNC4_END},
+ {HC_FUNC5_START, HC_FUNC5_END},
+ {HC_FUNC6_START, HC_FUNC6_END},
+ {HC_FUNC7_START, HC_FUNC7_END}
+};
#endif /* BNX2X_INIT_H */
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
index bef0a9b19d6..63019055e4b 100644
--- a/drivers/net/bnx2x_init_values.h
+++ b/drivers/net/bnx2x_init_values.h
@@ -57,6 +57,7 @@ static const struct raw_op init_ops[] = {
{OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
{OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
{OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0},
+ {OP_WR_E1H, PRS_REG_FCOE_TYPE, 0x8906},
{OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff},
{OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff},
{OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff},
@@ -74,23 +75,27 @@ static const struct raw_op init_ops[] = {
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END 46
-#define PRS_PORT0_START 46
- {OP_WR, PRS_REG_CID_PORT_0, 0x0},
-#define PRS_PORT0_END 47
-#define PRS_PORT1_START 47
- {OP_WR, PRS_REG_CID_PORT_1, 0x800000},
-#define PRS_PORT1_END 48
+#define PRS_COMMON_END 47
+#define SRCH_COMMON_START 47
+ {OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
+#define SRCH_COMMON_END 48
#define TSDM_COMMON_START 48
- {OP_WR, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
+ {OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
+ {OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
+ {OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
+ {OP_WR_E1H, TSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
+ {OP_WR_E1, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
+ {OP_WR_E1H, TSDM_REG_Q_COUNTER_START_ADDR, 0x204},
+ {OP_WR_E1, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
+ {OP_WR_E1H, TSDM_REG_PCK_END_MSG_START_ADDR, 0x219},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x80},
+ {OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x2},
+ {OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
+ {OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
+ {OP_ZR, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
{OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
{OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
{OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
@@ -109,9 +114,12 @@ static const struct raw_op init_ops[] = {
{OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
{OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
{OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR, TSDM_REG_TIMER_TICK, 0x3e8},
-#define TSDM_COMMON_END 76
-#define TCM_COMMON_START 76
+ {OP_WR_E1, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
+ {OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
+ {OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
+ {OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
+#define TSDM_COMMON_END 86
+#define TCM_COMMON_START 86
{OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
{OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
@@ -143,9 +151,14 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
{OP_ZR, TCM_REG_N_SM_CTX_LD_4, 0x4},
{OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
- {OP_WR, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_ZR, TCM_REG_PHYS_QNUM1_0, 0x6},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM1_0, 0x7},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM1_1, 0x27},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM2_0, 0x7},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM2_1, 0x27},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM3_0, 0x7},
+ {OP_WR_E1, TCM_REG_PHYS_QNUM3_1, 0x27},
{OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1},
{OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1},
{OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1},
@@ -162,23 +175,75 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END 126
-#define BRB1_COMMON_START 126
+#define TCM_COMMON_END 141
+#define TCM_FUNC0_START 141
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
+#define TCM_FUNC0_END 145
+#define TCM_FUNC1_START 145
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
+#define TCM_FUNC1_END 149
+#define TCM_FUNC2_START 149
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
+#define TCM_FUNC2_END 153
+#define TCM_FUNC3_START 153
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
+#define TCM_FUNC3_END 157
+#define TCM_FUNC4_START 157
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
+#define TCM_FUNC4_END 161
+#define TCM_FUNC5_START 161
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
+#define TCM_FUNC5_END 165
+#define TCM_FUNC6_START 165
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
+#define TCM_FUNC6_END 169
+#define TCM_FUNC7_START 169
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
+ {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
+#define TCM_FUNC7_END 173
+#define BRB1_COMMON_START 173
{OP_SW, BRB1_REG_LL_RAM, 0x2000020},
{OP_WR, BRB1_REG_SOFT_RESET, 0x1},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_2, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_3, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_2, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_3, 0x0},
{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
{OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
{OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END 139
-#define TSEM_COMMON_START 139
+#define BRB1_COMMON_END 178
+#define BRB1_PORT0_START 178
+ {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
+ {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
+ {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
+ {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
+#define BRB1_PORT0_END 182
+#define BRB1_PORT1_START 182
+ {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
+ {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
+ {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
+ {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
+#define BRB1_PORT1_END 186
+#define TSEM_COMMON_START 186
{OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -222,106 +287,247 @@ static const struct raw_op init_ops[] = {
{OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18},
{OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc},
{OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+ {OP_WR_ASIC, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+ {OP_WR_EMUL, TSEM_REG_FAST_MEMORY + 0x18300, 0x138},
+ {OP_WR_FPGA, TSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
{OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2000, 0x1b3},
- {OP_SW, TSEM_REG_FAST_MEMORY + 0x2000 + 0x6cc, 0x10223},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1fa0, 0x4},
- {OP_SW, TSEM_REG_FAST_MEMORY + 0x4cf0, 0x80224},
- {OP_ZP, TSEM_REG_INT_TABLE, 0x8c022c},
- {OP_ZP, TSEM_REG_PRAM, 0x3395024f},
- {OP_ZP, TSEM_REG_PRAM + 0x8000, 0x2c760f35},
- {OP_ZP, TSEM_REG_PRAM + 0x10000, 0x5e1a53},
- {OP_ZP, TSEM_REG_PRAM + 0x18000, 0x5e1a6b},
- {OP_ZP, TSEM_REG_PRAM + 0x20000, 0x5e1a83},
- {OP_ZP, TSEM_REG_PRAM + 0x28000, 0x5e1a9b},
- {OP_ZP, TSEM_REG_PRAM + 0x30000, 0x5e1ab3},
- {OP_ZP, TSEM_REG_PRAM + 0x38000, 0x5e1acb},
-#define TSEM_COMMON_END 202
-#define TSEM_PORT0_START 202
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
- {OP_SW, TSEM_REG_FAST_MEMORY + 0x4000 + 0x5b0, 0x21ae3},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1370, 0xa},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x13c0, 0x6},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1418, 0xc},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1478, 0x12},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1508, 0x90},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x820, 0x10},
- {OP_SW, TSEM_REG_FAST_MEMORY + 0x820 + 0x40, 0x21ae5},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2908, 0xa},
-#define TSEM_PORT0_END 213
-#define TSEM_PORT1_START 213
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x45b8, 0x16c},
- {OP_SW, TSEM_REG_FAST_MEMORY + 0x45b8 + 0x5b0, 0x21ae7},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1398, 0xa},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x13d8, 0x6},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1448, 0xc},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x14c0, 0x12},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1748, 0x90},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x868, 0x10},
- {OP_SW, TSEM_REG_FAST_MEMORY + 0x868 + 0x40, 0x21ae9},
- {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2930, 0xa},
-#define TSEM_PORT1_END 224
-#define MISC_COMMON_START 224
- {OP_WR, MISC_REG_GRC_TIMEOUT_EN, 0x1},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2000, 0xb2},
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x1},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x23c8, 0xc1},
+ {OP_WR_EMUL_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x0},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x23c8 + 0x304, 0x10223},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1000, 0x2b3},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x1000 + 0xacc, 0x10223},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3b28, 0x6},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
+ {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x940000},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
+ {OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
+ {OP_ZP_E1, TSEM_REG_PRAM, 0x30b10000},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
+ {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33c50c2d},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
+ {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xbc6191f},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
+ {OP_WR_64_E1, TSEM_REG_PRAM + 0x117f0, 0x5d020232},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x6140, 0x200224},
+ {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x960000},
+ {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x360, 0x140244},
+ {OP_ZP_E1H, TSEM_REG_PRAM, 0x30cc0000},
+ {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x33df0c33},
+ {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0xdce192b},
+ {OP_WR_64_E1H, TSEM_REG_PRAM + 0x11c70, 0x5c720246},
+#define TSEM_COMMON_END 276
+#define TSEM_PORT0_START 276
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0xfc},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
+ {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0xfa},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0xbe},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20234},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
+#define TSEM_PORT0_END 294
+#define TSEM_PORT1_START 294
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x43f0, 0xfc},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
+ {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3738, 0xfa},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xcb8, 0xbe},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20236},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
+#define TSEM_PORT1_END 312
+#define TSEM_FUNC0_START 312
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
+#define TSEM_FUNC0_END 318
+#define TSEM_FUNC1_START 318
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
+#define TSEM_FUNC1_END 324
+#define TSEM_FUNC2_START 324
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20248},
+#define TSEM_FUNC2_END 330
+#define TSEM_FUNC3_START 330
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2024a},
+#define TSEM_FUNC3_END 336
+#define TSEM_FUNC4_START 336
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x2024c},
+#define TSEM_FUNC4_END 342
+#define TSEM_FUNC5_START 342
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2024e},
+#define TSEM_FUNC5_END 348
+#define TSEM_FUNC6_START 348
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20250},
+#define TSEM_FUNC6_END 354
+#define TSEM_FUNC7_START 354
+ {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x20252},
+#define TSEM_FUNC7_END 360
+#define MISC_COMMON_START 360
+ {OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
{OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
{OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
{OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424},
{OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
{OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
-#define MISC_COMMON_END 230
-#define NIG_COMMON_START 230
+ {OP_WR_E1, MISC_REG_SPIO, 0xff000000},
+#define MISC_COMMON_END 367
+#define MISC_FUNC0_START 367
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
+#define MISC_FUNC0_END 368
+#define MISC_FUNC1_START 368
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
+#define MISC_FUNC1_END 369
+#define MISC_FUNC2_START 369
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
+#define MISC_FUNC2_END 370
+#define MISC_FUNC3_START 370
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
+#define MISC_FUNC3_END 371
+#define MISC_FUNC4_START 371
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
+#define MISC_FUNC4_END 372
+#define MISC_FUNC5_START 372
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
+#define MISC_FUNC5_END 373
+#define MISC_FUNC6_START 373
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
+#define MISC_FUNC6_END 374
+#define MISC_FUNC7_START 374
+ {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
+#define MISC_FUNC7_END 375
+#define NIG_COMMON_START 375
{OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
{OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
{OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
{OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
{OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END 235
-#define NIG_PORT0_START 235
+#define NIG_COMMON_END 380
+#define NIG_PORT0_START 380
{OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x26},
+ {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
{OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
{OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4},
{OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1},
{OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0},
+ {OP_WR_E1H, NIG_REG_LLH0_CLS_TYPE, 0x1},
{OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30},
{OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1},
{OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
{OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
{OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END 246
-#define NIG_PORT1_START 246
+#define NIG_PORT0_END 392
+#define NIG_PORT1_START 392
{OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x26},
+ {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
{OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
{OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4},
{OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1},
{OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0},
+ {OP_WR_E1H, NIG_REG_LLH1_CLS_TYPE, 0x1},
{OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30},
{OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1},
{OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
{OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
{OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END 257
-#define UPB_COMMON_START 257
+#define NIG_PORT1_END 404
+#define UPB_COMMON_START 404
{OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END 258
-#define CSDM_COMMON_START 258
- {OP_WR, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+#define UPB_COMMON_END 405
+#define CSDM_COMMON_START 405
+ {OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
+ {OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
+ {OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
+ {OP_WR_E1H, CSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
+ {OP_WR_E1, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+ {OP_WR_E1H, CSDM_REG_Q_COUNTER_START_ADDR, 0x204},
{OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff},
{OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff},
{OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff},
{OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR, CSDM_REG_AGG_INT_EVENT_0, 0x80},
+ {OP_WR, CSDM_REG_AGG_INT_EVENT_0, 0xc6},
+ {OP_WR, CSDM_REG_AGG_INT_EVENT_1, 0x0},
+ {OP_WR, CSDM_REG_AGG_INT_EVENT_2, 0x34},
+ {OP_WR, CSDM_REG_AGG_INT_EVENT_3, 0x35},
+ {OP_ZR, CSDM_REG_AGG_INT_EVENT_4, 0x1c},
+ {OP_WR, CSDM_REG_AGG_INT_T_0, 0x1},
+ {OP_ZR, CSDM_REG_AGG_INT_T_1, 0x5f},
{OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff},
{OP_WR, CSDM_REG_ENABLE_IN2, 0x3f},
{OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff},
@@ -340,19 +546,29 @@ static const struct raw_op init_ops[] = {
{OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
{OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
{OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR, CSDM_REG_TIMER_TICK, 0x3e8},
-#define CSDM_COMMON_END 285
-#define USDM_COMMON_START 285
- {OP_WR, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
+ {OP_WR_E1, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
+ {OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
+ {OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
+ {OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
+#define CSDM_COMMON_END 444
+#define USDM_COMMON_START 444
+ {OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
+ {OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
+ {OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
+ {OP_WR_E1H, USDM_REG_CMP_COUNTER_START_ADDR, 0x400},
+ {OP_WR_E1, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+ {OP_WR_E1H, USDM_REG_Q_COUNTER_START_ADDR, 0x404},
+ {OP_WR_E1, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
+ {OP_WR_E1H, USDM_REG_PCK_END_MSG_START_ADDR, 0x421},
{OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff},
{OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff},
{OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff},
{OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff},
{OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46},
- {OP_ZR, USDM_REG_AGG_INT_EVENT_1, 0x5f},
+ {OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
+ {OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
+ {OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
+ {OP_ZR, USDM_REG_AGG_INT_EVENT_4, 0x5c},
{OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
{OP_ZR, USDM_REG_AGG_INT_MODE_1, 0x1f},
{OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
@@ -374,9 +590,12 @@ static const struct raw_op init_ops[] = {
{OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0},
{OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
{OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR, USDM_REG_TIMER_TICK, 0x3e8},
-#define USDM_COMMON_END 317
-#define CCM_COMMON_START 317
+ {OP_WR_E1, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
+ {OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
+ {OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
+ {OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
+#define USDM_COMMON_END 486
+#define CCM_COMMON_START 486
{OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
{OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
@@ -401,23 +620,28 @@ static const struct raw_op init_ops[] = {
{OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
{OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
{OP_ZR, CCM_REG_XX_TABLE, 0x12},
- {OP_SW, CCM_REG_XX_DESCR_TABLE, 0x241aeb},
+ {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240238},
+ {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x240254},
{OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
{OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
{OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
{OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8},
{OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4},
{OP_WR, CCM_REG_CCM_REG0_SZ, 0x4},
- {OP_WR, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_ZR, CCM_REG_QOS_PHYS_QNUM2_0, 0x4},
- {OP_WR, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR, CCM_REG_PHYS_QNUM2_0, 0xb},
- {OP_WR, CCM_REG_PHYS_QNUM2_1, 0x2b},
- {OP_ZR, CCM_REG_PHYS_QNUM3_0, 0x2},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
+ {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
+ {OP_WR_E1, CCM_REG_PHYS_QNUM1_0, 0xc},
+ {OP_WR_E1, CCM_REG_PHYS_QNUM1_1, 0x2c},
+ {OP_WR_E1, CCM_REG_PHYS_QNUM2_0, 0xc},
+ {OP_WR_E1, CCM_REG_PHYS_QNUM2_1, 0x2c},
+ {OP_WR_E1, CCM_REG_PHYS_QNUM3_0, 0xc},
+ {OP_WR_E1, CCM_REG_PHYS_QNUM3_1, 0x2c},
{OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1},
{OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1},
{OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1},
@@ -433,8 +657,80 @@ static const struct raw_op init_ops[] = {
{OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END 373
-#define UCM_COMMON_START 373
+#define CCM_COMMON_END 547
+#define CCM_FUNC0_START 547
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
+#define CCM_FUNC0_END 554
+#define CCM_FUNC1_START 554
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
+#define CCM_FUNC1_END 561
+#define CCM_FUNC2_START 561
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x17},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
+#define CCM_FUNC2_END 568
+#define CCM_FUNC3_START 568
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x37},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
+#define CCM_FUNC3_END 575
+#define CCM_FUNC4_START 575
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x47},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
+#define CCM_FUNC4_END 582
+#define CCM_FUNC5_START 582
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x67},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
+#define CCM_FUNC5_END 589
+#define CCM_FUNC6_START 589
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x57},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
+#define CCM_FUNC6_END 596
+#define CCM_FUNC7_START 596
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
+ {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x77},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
+ {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
+#define CCM_FUNC7_END 603
+#define UCM_COMMON_START 603
{OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
{OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
@@ -457,20 +753,23 @@ static const struct raw_op init_ops[] = {
{OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40},
{OP_WR, UCM_REG_TM_INIT_CRD, 0x4},
{OP_WR, UCM_REG_UQM_INIT_CRD, 0x20},
- {OP_WR, UCM_REG_XX_INIT_CRD, 0xc},
- {OP_WR, UCM_REG_XX_MSG_NUM, 0x20},
+ {OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
+ {OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
{OP_ZR, UCM_REG_XX_TABLE, 0x12},
- {OP_SW, UCM_REG_XX_DESCR_TABLE, 0x201b0f},
- {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0xa},
+ {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b025c},
+ {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b0278},
+ {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
{OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
{OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
{OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
- {OP_ZR, UCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xd},
+ {OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
{OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
- {OP_WR, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR, UCM_REG_PHYS_QNUM1_1, 0x2e},
+ {OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
+ {OP_WR_E1, UCM_REG_PHYS_QNUM0_1, 0x2f},
+ {OP_WR_E1, UCM_REG_PHYS_QNUM1_0, 0xe},
+ {OP_WR_E1, UCM_REG_PHYS_QNUM1_1, 0x2e},
{OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1},
{OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1},
{OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1},
@@ -488,8 +787,56 @@ static const struct raw_op init_ops[] = {
{OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END 426
-#define USEM_COMMON_START 426
+#define UCM_COMMON_END 659
+#define UCM_FUNC0_START 659
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
+#define UCM_FUNC0_END 663
+#define UCM_FUNC1_START 663
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
+#define UCM_FUNC1_END 667
+#define UCM_FUNC2_START 667
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
+#define UCM_FUNC2_END 671
+#define UCM_FUNC3_START 671
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
+#define UCM_FUNC3_END 675
+#define UCM_FUNC4_START 675
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
+#define UCM_FUNC4_END 679
+#define UCM_FUNC5_START 679
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
+#define UCM_FUNC5_END 683
+#define UCM_FUNC6_START 683
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
+#define UCM_FUNC6_END 687
+#define UCM_FUNC7_START 687
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
+ {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
+#define UCM_FUNC7_END 691
+#define USEM_COMMON_START 691
{OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
@@ -533,87 +880,196 @@ static const struct raw_op init_ops[] = {
{OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e},
{OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10},
{OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+ {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+ {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18300, 0x138},
+ {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18300, 0x1388},
{OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x5000, 0x102},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1e20, 0x40},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3000, 0x400},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x2400, 0x2},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x2408, 0x2},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x2410, 0x6},
- {OP_SW, USEM_REG_FAST_MEMORY + 0x2410 + 0x18, 0x21b2f},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
- {OP_SW, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x21b31},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
- {OP_SW, USEM_REG_FAST_MEMORY + 0x2c30, 0x21b33},
+ {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
+ {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
+ {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0x102},
+ {OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57e8, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8020, 0xc8},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d0, 0x5},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x2},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d0 + 0x14, 0x10277},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3000, 0x400},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x2c00, 0x2},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2c00 + 0x8, 0x20278},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x2027a},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027c},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x20296},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x20298},
{OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW, USEM_REG_FAST_MEMORY + 0x10c00, 0x101b35},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x10027e},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a},
{OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW, USEM_REG_FAST_MEMORY + 0x10c40, 0x101b45},
- {OP_ZP, USEM_REG_INT_TABLE, 0xb41b55},
- {OP_ZP, USEM_REG_PRAM, 0x32d01b82},
- {OP_ZP, USEM_REG_PRAM + 0x8000, 0x32172836},
- {OP_ZP, USEM_REG_PRAM + 0x10000, 0x1a7a34bc},
- {OP_ZP, USEM_REG_PRAM + 0x18000, 0x5f3b5b},
- {OP_ZP, USEM_REG_PRAM + 0x20000, 0x5f3b73},
- {OP_ZP, USEM_REG_PRAM + 0x28000, 0x5f3b8b},
- {OP_ZP, USEM_REG_PRAM + 0x30000, 0x5f3ba3},
- {OP_ZP, USEM_REG_PRAM + 0x38000, 0x5f3bbb},
-#define USEM_COMMON_END 498
-#define USEM_PORT0_START 498
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1d00, 0x24},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3000, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3200, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3300, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3400, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3500, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3600, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3700, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3800, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3900, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3a00, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3b00, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3c00, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3d00, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3e00, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3f00, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x2400, 0x2},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
-#define USEM_PORT0_END 521
-#define USEM_PORT1_START 521
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x1d90, 0x24},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3280, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3380, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3480, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3580, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3680, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3780, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3880, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3980, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3a80, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3b80, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3c80, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3d80, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3e80, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x3f80, 0x20},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x2408, 0x2},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
- {OP_ZR, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
-#define USEM_PORT1_END 544
-#define CSEM_COMMON_START 544
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x10028e},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa},
+ {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000},
+ {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000},
+ {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029e},
+ {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba},
+ {OP_ZP_E1, USEM_REG_PRAM, 0x311c0000},
+ {OP_ZP_E1H, USEM_REG_PRAM, 0x31070000},
+ {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x33450c47},
+ {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42},
+ {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919},
+ {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906},
+ {OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x500402a0},
+ {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d},
+ {OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc},
+#define USEM_COMMON_END 790
+#define USEM_PORT0_START 790
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x28},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9640, 0x34},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d00, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d20, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3000, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3200, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3300, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3400, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3500, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3600, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3700, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3800, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3900, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3a00, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3b00, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3c00, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3d00, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3e00, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3f00, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x2c10, 0x2},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
+#define USEM_PORT0_END 838
+#define USEM_PORT1_START 838
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x95a0, 0x28},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9710, 0x34},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d10, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1da0, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3280, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3380, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3480, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3580, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3680, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3780, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3880, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3980, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3a80, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3b80, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3c80, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3d80, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3e80, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x3f80, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x2c20, 0x2},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
+#define USEM_PORT1_END 886
+#define USEM_FUNC0_START 886
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4010, 0x2},
+#define USEM_FUNC0_END 888
+#define USEM_FUNC1_START 888
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4020, 0x2},
+#define USEM_FUNC1_END 890
+#define USEM_FUNC2_START 890
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4030, 0x2},
+#define USEM_FUNC2_END 892
+#define USEM_FUNC3_START 892
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4040, 0x2},
+#define USEM_FUNC3_END 894
+#define USEM_FUNC4_START 894
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4050, 0x2},
+#define USEM_FUNC4_END 896
+#define USEM_FUNC5_START 896
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4060, 0x2},
+#define USEM_FUNC5_END 898
+#define USEM_FUNC6_START 898
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4070, 0x2},
+#define USEM_FUNC6_END 900
+#define USEM_FUNC7_START 900
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4080, 0x2},
+#define USEM_FUNC7_END 902
+#define CSEM_COMMON_START 902
{OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -658,50 +1114,106 @@ static const struct raw_op init_ops[] = {
{OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30},
{OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe},
{OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
- {OP_SW, CSEM_REG_FAST_MEMORY + 0x25c0 + 0x900, 0x83bd3},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x1},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+ {OP_WR_EMUL_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x0},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x1000, 0x42},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7020, 0xc8},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7000, 0x2},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
+ {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a2},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x240},
+ {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be},
{OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
- {OP_SW, CSEM_REG_FAST_MEMORY + 0x10c00, 0x103bdb},
+ {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002aa},
+ {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de},
{OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW, CSEM_REG_FAST_MEMORY + 0x10c40, 0x103beb},
- {OP_ZP, CSEM_REG_INT_TABLE, 0x5f3bfb},
- {OP_ZP, CSEM_REG_PRAM, 0x32423c13},
- {OP_ZP, CSEM_REG_PRAM + 0x8000, 0xf2148a4},
- {OP_ZP, CSEM_REG_PRAM + 0x10000, 0x5f4c6d},
- {OP_ZP, CSEM_REG_PRAM + 0x18000, 0x5f4c85},
- {OP_ZP, CSEM_REG_PRAM + 0x20000, 0x5f4c9d},
- {OP_ZP, CSEM_REG_PRAM + 0x28000, 0x5f4cb5},
- {OP_ZP, CSEM_REG_PRAM + 0x30000, 0x5f4ccd},
- {OP_ZP, CSEM_REG_PRAM + 0x38000, 0x5f4ce5},
-#define CSEM_COMMON_END 609
-#define CSEM_PORT0_START 609
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2300, 0x2},
- {OP_SW, CSEM_REG_FAST_MEMORY + 0x2300 + 0x8, 0x24cfd},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END 616
-#define CSEM_PORT1_START 616
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2310, 0x2},
- {OP_SW, CSEM_REG_FAST_MEMORY + 0x2310 + 0x8, 0x24cff},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
- {OP_ZR, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END 623
-#define XPB_COMMON_START 623
+ {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ba},
+ {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee},
+ {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000},
+ {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000},
+ {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002ca},
+ {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe},
+ {OP_ZP_E1, CSEM_REG_PRAM, 0x32580000},
+ {OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000},
+ {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96},
+ {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f},
+ {OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402cc},
+ {OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300},
+#define CSEM_COMMON_END 981
+#define CSEM_PORT0_START 981
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8500, 0x40},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8700, 0x3c},
+ {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
+#define CSEM_PORT0_END 993
+#define CSEM_PORT1_START 993
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8600, 0x40},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x87f0, 0x3c},
+ {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
+ {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
+#define CSEM_PORT1_END 1005
+#define CSEM_FUNC0_START 1005
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
+#define CSEM_FUNC0_END 1007
+#define CSEM_FUNC1_START 1007
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
+#define CSEM_FUNC1_END 1009
+#define CSEM_FUNC2_START 1009
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
+#define CSEM_FUNC2_END 1011
+#define CSEM_FUNC3_START 1011
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
+#define CSEM_FUNC3_END 1013
+#define CSEM_FUNC4_START 1013
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
+#define CSEM_FUNC4_END 1015
+#define CSEM_FUNC5_START 1015
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
+#define CSEM_FUNC5_END 1017
+#define CSEM_FUNC6_START 1017
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
+#define CSEM_FUNC6_END 1019
+#define CSEM_FUNC7_START 1019
+ {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
+#define CSEM_FUNC7_END 1021
+#define XPB_COMMON_START 1021
{OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END 624
-#define DQ_COMMON_START 624
+#define XPB_COMMON_END 1022
+#define DQ_COMMON_START 1022
{OP_WR, DORQ_REG_MODE_ACT, 0x2},
{OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
{OP_WR, DORQ_REG_OUTST_REQ, 0x4},
@@ -720,8 +1232,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
{OP_WR, DORQ_REG_REGN, 0x7c1004},
{OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END 642
-#define TIMERS_COMMON_START 642
+#define DQ_COMMON_END 1040
+#define TIMERS_COMMON_START 1040
{OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
{OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
{OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
@@ -730,8 +1242,11 @@ static const struct raw_op init_ops[] = {
{OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1},
{OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1},
{OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
- {OP_WR, TM_REG_TIMER_TICK_SIZE, 0x3d090},
+ {OP_WR_E1, TM_REG_PCIARB_CRDCNT_VAL, 0x1},
+ {OP_WR_E1H, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
+ {OP_WR_ASIC, TM_REG_TIMER_TICK_SIZE, 0x3d090},
+ {OP_WR_EMUL, TM_REG_TIMER_TICK_SIZE, 0x9c},
+ {OP_WR_FPGA, TM_REG_TIMER_TICK_SIZE, 0x9c4},
{OP_WR, TM_REG_CL0_CONT_REGION, 0x8},
{OP_WR, TM_REG_CL1_CONT_REGION, 0xc},
{OP_WR, TM_REG_CL2_CONT_REGION, 0x10},
@@ -741,24 +1256,37 @@ static const struct raw_op init_ops[] = {
{OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
{OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
{OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END 661
-#define TIMERS_PORT0_START 661
+#define TIMERS_COMMON_END 1062
+#define TIMERS_PORT0_START 1062
{OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END 662
-#define TIMERS_PORT1_START 662
+#define TIMERS_PORT0_END 1063
+#define TIMERS_PORT1_START 1063
{OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END 663
-#define XSDM_COMMON_START 663
- {OP_WR, XSDM_REG_CFC_RSP_START_ADDR, 0xa14},
- {OP_WR, XSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR, XSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+#define TIMERS_PORT1_END 1064
+#define XSDM_COMMON_START 1064
+ {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
+ {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
+ {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
+ {OP_WR_E1H, XSDM_REG_CMP_COUNTER_START_ADDR, 0x410},
+ {OP_WR_E1, XSDM_REG_Q_COUNTER_START_ADDR, 0x604},
+ {OP_WR_E1H, XSDM_REG_Q_COUNTER_START_ADDR, 0x414},
{OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff},
{OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff},
{OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff},
{OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff},
{OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20},
{OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20},
- {OP_ZR, XSDM_REG_AGG_INT_EVENT_2, 0x5e},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_2, 0x34},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_3, 0x35},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_4, 0x23},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_5, 0x24},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_6, 0x25},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_7, 0x26},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_8, 0x27},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
+ {OP_ZR, XSDM_REG_AGG_INT_EVENT_12, 0x54},
{OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
{OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
{OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
@@ -779,9 +1307,12 @@ static const struct raw_op init_ops[] = {
{OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
{OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
{OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR, XSDM_REG_TIMER_TICK, 0x3e8},
-#define XSDM_COMMON_END 694
-#define QM_COMMON_START 694
+ {OP_WR_E1, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
+ {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
+ {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
+ {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
+#define XSDM_COMMON_END 1111
+#define QM_COMMON_START 1111
{OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
{OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
{OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
@@ -820,13 +1351,27 @@ static const struct raw_op init_ops[] = {
{OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120},
{OP_ZR, QM_REG_QVOQIDX_17, 0x4},
{OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101},
- {OP_ZR, QM_REG_QVOQIDX_21, 0x4},
- {OP_WR, QM_REG_WRRWEIGHTS_5, 0x1010101},
- {OP_ZR, QM_REG_QVOQIDX_25, 0x4},
- {OP_WR, QM_REG_WRRWEIGHTS_6, 0x1010101},
- {OP_ZR, QM_REG_QVOQIDX_29, 0x3},
+ {OP_ZR_E1, QM_REG_QVOQIDX_21, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_21, 0x0},
+ {OP_WR_E1, QM_REG_WRRWEIGHTS_5, 0x1010101},
+ {OP_WR_E1H, QM_REG_QVOQIDX_22, 0x4},
+ {OP_ZR_E1, QM_REG_QVOQIDX_25, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_23, 0x4},
+ {OP_WR_E1, QM_REG_WRRWEIGHTS_6, 0x1010101},
+ {OP_WR_E1H, QM_REG_QVOQIDX_24, 0x2},
+ {OP_ZR_E1, QM_REG_QVOQIDX_29, 0x3},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_5, 0x8012004},
+ {OP_WR_E1H, QM_REG_QVOQIDX_25, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_26, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_27, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_28, 0x5},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_6, 0x20081001},
+ {OP_WR_E1H, QM_REG_QVOQIDX_29, 0x8},
+ {OP_WR_E1H, QM_REG_QVOQIDX_30, 0x6},
+ {OP_WR_E1H, QM_REG_QVOQIDX_31, 0x7},
{OP_WR, QM_REG_QVOQIDX_32, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_7, 0x1010101},
+ {OP_WR_E1, QM_REG_WRRWEIGHTS_7, 0x1010101},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_7, 0x1010120},
{OP_WR, QM_REG_QVOQIDX_33, 0x1},
{OP_WR, QM_REG_QVOQIDX_34, 0x1},
{OP_WR, QM_REG_QVOQIDX_35, 0x1},
@@ -853,36 +1398,169 @@ static const struct raw_op init_ops[] = {
{OP_WR, QM_REG_QVOQIDX_52, 0x1},
{OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101},
{OP_WR, QM_REG_QVOQIDX_53, 0x1},
- {OP_WR, QM_REG_QVOQIDX_54, 0x1},
- {OP_WR, QM_REG_QVOQIDX_55, 0x1},
- {OP_WR, QM_REG_QVOQIDX_56, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_13, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_57, 0x1},
- {OP_WR, QM_REG_QVOQIDX_58, 0x1},
- {OP_WR, QM_REG_QVOQIDX_59, 0x1},
- {OP_WR, QM_REG_QVOQIDX_60, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_14, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_61, 0x1},
- {OP_WR, QM_REG_QVOQIDX_62, 0x1},
- {OP_WR, QM_REG_QVOQIDX_63, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_15, 0x1010101},
- {OP_WR, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
- {OP_ZR, QM_REG_VOQQMASK_0_MSB, 0x2},
- {OP_WR, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
- {OP_WR, QM_REG_VOQQMASK_2_LSB, 0x100},
- {OP_WR, QM_REG_VOQQMASK_2_MSB, 0x100},
+ {OP_WR_E1, QM_REG_QVOQIDX_54, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_54, 0x4},
+ {OP_WR_E1, QM_REG_QVOQIDX_55, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_55, 0x4},
+ {OP_WR_E1, QM_REG_QVOQIDX_56, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_56, 0x2},
+ {OP_WR_E1, QM_REG_WRRWEIGHTS_13, 0x1010101},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_13, 0x8012004},
+ {OP_WR_E1, QM_REG_QVOQIDX_57, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_57, 0x5},
+ {OP_WR_E1, QM_REG_QVOQIDX_58, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_58, 0x5},
+ {OP_WR_E1, QM_REG_QVOQIDX_59, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_59, 0x5},
+ {OP_WR_E1, QM_REG_QVOQIDX_60, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_60, 0x5},
+ {OP_WR_E1, QM_REG_WRRWEIGHTS_14, 0x1010101},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_14, 0x20081001},
+ {OP_WR_E1, QM_REG_QVOQIDX_61, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_61, 0x8},
+ {OP_WR_E1, QM_REG_QVOQIDX_62, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_62, 0x6},
+ {OP_WR_E1, QM_REG_QVOQIDX_63, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_63, 0x7},
+ {OP_WR_E1, QM_REG_WRRWEIGHTS_15, 0x1010101},
+ {OP_WR_E1H, QM_REG_QVOQIDX_64, 0x0},
+ {OP_WR_E1, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_15, 0x1010120},
+ {OP_ZR_E1, QM_REG_VOQQMASK_0_MSB, 0x2},
+ {OP_ZR_E1H, QM_REG_QVOQIDX_65, 0x4},
+ {OP_WR_E1, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_16, 0x1010101},
+ {OP_WR_E1, QM_REG_VOQQMASK_2_LSB, 0x100},
+ {OP_WR_E1H, QM_REG_QVOQIDX_69, 0x0},
+ {OP_WR_E1, QM_REG_VOQQMASK_2_MSB, 0x100},
+ {OP_WR_E1H, QM_REG_QVOQIDX_70, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_71, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_72, 0x2},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_17, 0x8012004},
+ {OP_WR_E1H, QM_REG_QVOQIDX_73, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_74, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_75, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_76, 0x5},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_18, 0x20081001},
+ {OP_WR_E1H, QM_REG_QVOQIDX_77, 0x8},
+ {OP_WR_E1H, QM_REG_QVOQIDX_78, 0x6},
+ {OP_WR_E1H, QM_REG_QVOQIDX_79, 0x7},
+ {OP_WR_E1H, QM_REG_QVOQIDX_80, 0x0},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_19, 0x1010120},
+ {OP_ZR_E1H, QM_REG_QVOQIDX_81, 0x4},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_20, 0x1010101},
+ {OP_WR_E1H, QM_REG_QVOQIDX_85, 0x0},
+ {OP_WR_E1H, QM_REG_QVOQIDX_86, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_87, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_88, 0x2},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_21, 0x8012004},
+ {OP_WR_E1H, QM_REG_QVOQIDX_89, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_90, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_91, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_92, 0x5},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_22, 0x20081001},
+ {OP_WR_E1H, QM_REG_QVOQIDX_93, 0x8},
+ {OP_WR_E1H, QM_REG_QVOQIDX_94, 0x6},
+ {OP_WR_E1H, QM_REG_QVOQIDX_95, 0x7},
+ {OP_WR_E1H, QM_REG_QVOQIDX_96, 0x1},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_23, 0x1010120},
+ {OP_WR_E1H, QM_REG_QVOQIDX_97, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_98, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_99, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_100, 0x1},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_24, 0x1010101},
+ {OP_WR_E1H, QM_REG_QVOQIDX_101, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_102, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_103, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_104, 0x2},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_25, 0x8012004},
+ {OP_WR_E1H, QM_REG_QVOQIDX_105, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_106, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_107, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_108, 0x5},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_26, 0x20081001},
+ {OP_WR_E1H, QM_REG_QVOQIDX_109, 0x8},
+ {OP_WR_E1H, QM_REG_QVOQIDX_110, 0x6},
+ {OP_WR_E1H, QM_REG_QVOQIDX_111, 0x7},
+ {OP_WR_E1H, QM_REG_QVOQIDX_112, 0x1},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_27, 0x1010120},
+ {OP_WR_E1H, QM_REG_QVOQIDX_113, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_114, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_115, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_116, 0x1},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_28, 0x1010101},
+ {OP_WR_E1H, QM_REG_QVOQIDX_117, 0x1},
+ {OP_WR_E1H, QM_REG_QVOQIDX_118, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_119, 0x4},
+ {OP_WR_E1H, QM_REG_QVOQIDX_120, 0x2},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_29, 0x8012004},
+ {OP_WR_E1H, QM_REG_QVOQIDX_121, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_122, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_123, 0x5},
+ {OP_WR_E1H, QM_REG_QVOQIDX_124, 0x5},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_30, 0x20081001},
+ {OP_WR_E1H, QM_REG_QVOQIDX_125, 0x8},
+ {OP_WR_E1H, QM_REG_QVOQIDX_126, 0x6},
+ {OP_WR_E1H, QM_REG_QVOQIDX_127, 0x7},
+ {OP_WR_E1H, QM_REG_WRRWEIGHTS_31, 0x1010120},
+ {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB, 0x3f003f},
+ {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB_EXT_A, 0x3f003f},
+ {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB, 0x3f003f},
+ {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB_EXT_A, 0x3f003f},
+ {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB, 0x1000100},
+ {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB, 0x1000100},
+ {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB_EXT_A, 0x1000100},
+ {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB_EXT_A, 0x1000100},
{OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2},
- {OP_WR, QM_REG_VOQQMASK_4_LSB, 0xc0},
- {OP_WR, QM_REG_VOQQMASK_4_MSB, 0xc0},
- {OP_WR, QM_REG_VOQQMASK_5_LSB, 0x1e00},
- {OP_WR, QM_REG_VOQQMASK_5_MSB, 0x1e00},
- {OP_WR, QM_REG_VOQQMASK_6_LSB, 0x4000},
- {OP_WR, QM_REG_VOQQMASK_6_MSB, 0x4000},
- {OP_WR, QM_REG_VOQQMASK_7_LSB, 0x8000},
- {OP_WR, QM_REG_VOQQMASK_7_MSB, 0x8000},
- {OP_WR, QM_REG_VOQQMASK_8_LSB, 0x2000},
- {OP_WR, QM_REG_VOQQMASK_8_MSB, 0x2000},
- {OP_ZR, QM_REG_VOQQMASK_9_LSB, 0x7},
+ {OP_WR_E1, QM_REG_VOQQMASK_4_LSB, 0xc0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_3_LSB_EXT_A, 0x0},
+ {OP_WR_E1, QM_REG_VOQQMASK_4_MSB, 0xc0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_3_MSB_EXT_A, 0x0},
+ {OP_WR_E1, QM_REG_VOQQMASK_5_LSB, 0x1e00},
+ {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB, 0xc000c0},
+ {OP_WR_E1, QM_REG_VOQQMASK_5_MSB, 0x1e00},
+ {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB, 0xc000c0},
+ {OP_WR_E1, QM_REG_VOQQMASK_6_LSB, 0x4000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB_EXT_A, 0xc000c0},
+ {OP_WR_E1, QM_REG_VOQQMASK_6_MSB, 0x4000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB_EXT_A, 0xc000c0},
+ {OP_WR_E1, QM_REG_VOQQMASK_7_LSB, 0x8000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB, 0x1e001e00},
+ {OP_WR_E1, QM_REG_VOQQMASK_7_MSB, 0x8000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB, 0x1e001e00},
+ {OP_WR_E1, QM_REG_VOQQMASK_8_LSB, 0x2000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB_EXT_A, 0x1e001e00},
+ {OP_WR_E1, QM_REG_VOQQMASK_8_MSB, 0x2000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB_EXT_A, 0x1e001e00},
+ {OP_ZR_E1, QM_REG_VOQQMASK_9_LSB, 0x7},
+ {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB, 0x40004000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB, 0x40004000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB_EXT_A, 0x40004000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB_EXT_A, 0x40004000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB, 0x80008000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB, 0x80008000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB_EXT_A, 0x80008000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB_EXT_A, 0x80008000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB, 0x20002000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB, 0x20002000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB_EXT_A, 0x20002000},
+ {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB_EXT_A, 0x20002000},
+ {OP_ZR_E1H, QM_REG_VOQQMASK_9_LSB, 0x2},
+ {OP_WR_E1H, QM_REG_VOQQMASK_9_LSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_9_MSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB_EXT_A, 0x0},
+ {OP_WR_E1H, QM_REG_VOQPORT_0, 0x0},
{OP_WR, QM_REG_VOQPORT_1, 0x1},
{OP_ZR, QM_REG_VOQPORT_2, 0xa},
{OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08},
@@ -893,8 +1571,12 @@ static const struct raw_op init_ops[] = {
{OP_WR, QM_REG_CMINTVOQMASK_5, 0x80},
{OP_WR, QM_REG_CMINTVOQMASK_6, 0x200},
{OP_WR, QM_REG_CMINTVOQMASK_7, 0x0},
- {OP_WR, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
- {OP_WR, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
+ {OP_WR_E1, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
+ {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB, 0x1ff01ff},
+ {OP_WR_E1, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
+ {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB, 0x1ff01ff},
+ {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB_EXT_A, 0x1ff01ff},
+ {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB_EXT_A, 0x1ff01ff},
{OP_WR, QM_REG_ENBYPVOQMASK, 0x13},
{OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f},
{OP_WR, QM_REG_VOQINITCREDIT_0, 0x140},
@@ -910,15 +1592,29 @@ static const struct raw_op init_ops[] = {
{OP_WR, QM_REG_BYTECRDINITVAL, 0x8000},
{OP_WR, QM_REG_BYTECRDCOST, 0x25e4},
{OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff},
- {OP_WR, QM_REG_ENBYTECRD_LSB, 0x7},
- {OP_WR, QM_REG_ENBYTECRD_MSB, 0x7},
+ {OP_WR_E1, QM_REG_ENBYTECRD_LSB, 0x7},
+ {OP_WR_E1H, QM_REG_ENBYTECRD_LSB, 0x70007},
+ {OP_WR_E1, QM_REG_ENBYTECRD_MSB, 0x7},
+ {OP_WR_E1H, QM_REG_ENBYTECRD_MSB, 0x70007},
+ {OP_WR_E1H, QM_REG_ENBYTECRD_LSB_EXT_A, 0x70007},
+ {OP_WR_E1H, QM_REG_ENBYTECRD_MSB_EXT_A, 0x70007},
{OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0},
{OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff},
- {OP_WR, QM_REG_FUNCNUMSEL_LSB, 0x0},
- {OP_WR, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
+ {OP_WR_E1, QM_REG_FUNCNUMSEL_LSB, 0x0},
+ {OP_WR_E1H, QM_REG_BYTECRDPORT_LSB_EXT_A, 0x0},
+ {OP_WR_E1, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
+ {OP_WR_E1H, QM_REG_BYTECRDPORT_MSB_EXT_A, 0xffffffff},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_0, 0x0},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_1, 0x2},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_2, 0x1},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_3, 0x3},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_4, 0x4},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_5, 0x6},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
+ {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
{OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END 829
-#define PBF_COMMON_START 829
+#define QM_COMMON_END 1411
+#define PBF_COMMON_START 1411
{OP_WR, PBF_REG_INIT, 0x1},
{OP_WR, PBF_REG_INIT_P4, 0x1},
{OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
@@ -926,20 +1622,20 @@ static const struct raw_op init_ops[] = {
{OP_WR, PBF_REG_INIT_P4, 0x0},
{OP_WR, PBF_REG_INIT, 0x0},
{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END 836
-#define PBF_PORT0_START 836
+#define PBF_COMMON_END 1418
+#define PBF_PORT0_START 1418
{OP_WR, PBF_REG_INIT_P0, 0x1},
{OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
{OP_WR, PBF_REG_INIT_P0, 0x0},
{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END 840
-#define PBF_PORT1_START 840
+#define PBF_PORT0_END 1422
+#define PBF_PORT1_START 1422
{OP_WR, PBF_REG_INIT_P1, 0x1},
{OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
{OP_WR, PBF_REG_INIT_P1, 0x0},
{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END 844
-#define XCM_COMMON_START 844
+#define PBF_PORT1_END 1426
+#define XCM_COMMON_START 1426
{OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
{OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
@@ -971,14 +1667,18 @@ static const struct raw_op init_ops[] = {
{OP_WR, XCM_REG_TM_INIT_CRD, 0x4},
{OP_WR, XCM_REG_XQM_INIT_CRD, 0x20},
{OP_WR, XCM_REG_XX_INIT_CRD, 0x2},
- {OP_WR, XCM_REG_XX_MSG_NUM, 0x1f},
+ {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
+ {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
{OP_ZR, XCM_REG_XX_TABLE, 0x12},
- {OP_SW, XCM_REG_XX_DESCR_TABLE, 0x1f4d01},
+ {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02ce},
+ {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302},
{OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
{OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
{OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
{OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
- {OP_ZR, XCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xc},
+ {OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
{OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
{OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
{OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1},
@@ -1000,28 +1700,116 @@ static const struct raw_op init_ops[] = {
{OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END 904
-#define XCM_PORT0_START 904
- {OP_WR, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END 912
-#define XCM_PORT1_START 912
- {OP_WR, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END 920
-#define XSEM_COMMON_START 920
+#define XCM_COMMON_END 1490
+#define XCM_PORT0_START 1490
+ {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
+ {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
+ {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
+ {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD00, 0x2},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
+#define XCM_PORT0_END 1498
+#define XCM_PORT1_START 1498
+ {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
+ {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
+ {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
+ {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD01, 0x2},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
+ {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
+#define XCM_PORT1_END 1506
+#define XCM_FUNC0_START 1506
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
+#define XCM_FUNC0_END 1515
+#define XCM_FUNC1_START 1515
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
+#define XCM_FUNC1_END 1524
+#define XCM_FUNC2_START 1524
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
+#define XCM_FUNC2_END 1533
+#define XCM_FUNC3_START 1533
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
+#define XCM_FUNC3_END 1542
+#define XCM_FUNC4_START 1542
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
+#define XCM_FUNC4_END 1551
+#define XCM_FUNC5_START 1551
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
+#define XCM_FUNC5_END 1560
+#define XCM_FUNC6_START 1560
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
+#define XCM_FUNC6_END 1569
+#define XCM_FUNC7_START 1569
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
+ {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
+ {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
+ {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
+#define XCM_FUNC7_END 1578
+#define XSEM_COMMON_START 1578
{OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1065,157 +1853,402 @@ static const struct raw_op init_ops[] = {
{OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+ {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+ {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18300, 0x138},
+ {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x55d8, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x48},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5128, 0x92},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x5378, 0x0},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x5380, 0x24d20},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x5428, 0x44d22},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x1820, 0x24d26},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ad8, 0x24d28},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4b08, 0x4},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x1f50, 0x24d2a},
+ {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
+ {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18340, 0x0},
+ {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18340, 0x5},
+ {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
+ {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
+ {OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
+ {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d00, 0x4},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x4},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9020, 0xc8},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3128, 0x8e},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202ed},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402ef},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x20321},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ac8, 0x0},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f3},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 0x0},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f50, 0x202f5},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x83b0, 0x20337},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c00, 0x104d2c},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x1002f7},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c40, 0x84d3c},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80307},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c60, 0x84d44},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x3000000},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c80, 0x84d4c},
- {OP_ZP, XSEM_REG_INT_TABLE, 0x814d54},
- {OP_ZP, XSEM_REG_PRAM, 0x35774d75},
- {OP_ZP, XSEM_REG_PRAM + 0x8000, 0x36525ad3},
- {OP_ZP, XSEM_REG_PRAM + 0x10000, 0x27266868},
- {OP_ZP, XSEM_REG_PRAM + 0x18000, 0x5e7232},
- {OP_ZP, XSEM_REG_PRAM + 0x20000, 0x5e724a},
- {OP_ZP, XSEM_REG_PRAM + 0x28000, 0x5e7262},
- {OP_ZP, XSEM_REG_PRAM + 0x30000, 0x5e727a},
- {OP_ZP, XSEM_REG_PRAM + 0x38000, 0x5e7292},
-#define XSEM_COMMON_END 1000
-#define XSEM_PORT0_START 1000
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5388, 0xc},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x5388 + 0x30, 0x272aa},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x55e0, 0x772ac},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5600, 0x7},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3020, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3030, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3000, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3010, 0x2},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x3040, 0x0},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3048, 0xc},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x3048 + 0x30, 0x272b3},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x30b8, 0x1},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x272b5},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4b18, 0x42},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4d28, 0x4},
-#define XSEM_PORT0_END 1019
-#define XSEM_PORT1_START 1019
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x53c0, 0xc},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x53c0 + 0x30, 0x272b7},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x5620, 0x772b9},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5640, 0x7},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3028, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3038, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3008, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3018, 0x2},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x3044, 0x0},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3080, 0xc},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x3080 + 0x30, 0x272c0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x30bc, 0x1},
- {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x272c2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4c20, 0x42},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4d38, 0x4},
-#define XSEM_PORT1_END 1038
-#define CDU_COMMON_START 1038
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8030f},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351},
+ {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000},
+ {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000},
+ {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130317},
+ {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359},
+ {OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000},
+ {OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000},
+ {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38840d14},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x38240d19},
+ {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3e711b35},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22},
+ {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8},
+ {OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60319},
+ {OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b},
+#define XSEM_COMMON_END 1688
+#define XSEM_PORT0_START 1688
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c20, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x10},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2528, 0x1c},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2608, 0x1c},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26e8, 0x1c},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x27c8, 0x1c},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x10031b},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5030, 0x2},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x2},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5010, 0x2},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2035d},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x2032b},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
+#define XSEM_PORT0_END 1720
+#define XSEM_PORT1_START 1720
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c90, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24e8, 0x10},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2598, 0x1c},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2678, 0x1c},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2758, 0x1c},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2838, 0x1c},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032d},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5038, 0x2},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5008, 0x2},
+ {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5018, 0x2},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2035f},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2033d},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
+#define XSEM_PORT1_END 1752
+#define XSEM_FUNC0_START 1752
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28b8, 0x100361},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
+#define XSEM_FUNC0_END 1755
+#define XSEM_FUNC1_START 1755
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28f8, 0x100371},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
+#define XSEM_FUNC1_END 1758
+#define XSEM_FUNC2_START 1758
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x100381},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
+#define XSEM_FUNC2_END 1761
+#define XSEM_FUNC3_START 1761
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2978, 0x100391},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
+#define XSEM_FUNC3_END 1764
+#define XSEM_FUNC4_START 1764
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29b8, 0x1003a1},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
+#define XSEM_FUNC4_END 1767
+#define XSEM_FUNC5_START 1767
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f8, 0x1003b1},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
+#define XSEM_FUNC5_END 1770
+#define XSEM_FUNC6_START 1770
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a38, 0x1003c1},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
+#define XSEM_FUNC6_END 1773
+#define XSEM_FUNC7_START 1773
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a78, 0x1003d1},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
+#define XSEM_FUNC7_END 1776
+#define CDU_COMMON_START 1776
{OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
+ {OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
{OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
{OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
- {OP_WB, CDU_REG_L1TT, 0x20072c4},
- {OP_WB, CDU_REG_MATT, 0x2074c4},
- {OP_ZR, CDU_REG_MATT + 0x80, 0x20},
-#define CDU_COMMON_END 1044
-#define DMAE_COMMON_START 1044
+ {OP_WB_E1, CDU_REG_L1TT, 0x200033f},
+ {OP_WB_E1H, CDU_REG_L1TT, 0x20003e1},
+ {OP_WB_E1, CDU_REG_MATT, 0x20053f},
+ {OP_WB_E1H, CDU_REG_MATT, 0x2805e1},
+ {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
+ {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6055f},
+ {OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
+#define CDU_COMMON_END 1787
+#define DMAE_COMMON_START 1787
+ {OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
{OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
{OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
- {OP_WR, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
+ {OP_WR_E1, DMAE_REG_PXP_REQ_INIT_CRD, 0x1},
+ {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
{OP_WR, DMAE_REG_PCI_IFEN, 0x1},
{OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END 1049
-#define PXP_COMMON_START 1049
- {OP_SI, PXP_REG_HST_INBOUND_INT + 0x400, 0x574e4},
- {OP_SI, PXP_REG_HST_INBOUND_INT + 0x420, 0x574e9},
- {OP_SI, PXP_REG_HST_INBOUND_INT, 0x574ee},
-#define PXP_COMMON_END 1052
-#define CFC_COMMON_START 1052
+#define DMAE_COMMON_END 1794
+#define PXP_COMMON_START 1794
+ {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50565},
+ {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609},
+ {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x5056a},
+ {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e},
+ {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056f},
+#define PXP_COMMON_END 1799
+#define CFC_COMMON_START 1799
+ {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
{OP_WR, CFC_REG_CONTROL0, 0x10},
{OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
{OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
-#define CFC_COMMON_END 1055
-#define HC_COMMON_START 1055
- {OP_ZR, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END 1056
-#define HC_PORT0_START 1056
- {OP_WR, HC_REG_CONFIG_0, 0x1080},
- {OP_ZR, HC_REG_UC_RAM_ADDR_0, 0x2},
- {OP_WR, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR, HC_REG_LEADING_EDGE_0, 0xffff},
- {OP_WR, HC_REG_TRAILING_EDGE_0, 0xffff},
- {OP_WR, HC_REG_AGG_INT_0, 0x0},
- {OP_WR, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR, HC_REG_ATTN_BIT, 0x2},
- {OP_WR, HC_REG_VQID_0, 0x2b5},
- {OP_WR, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_ZR, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR, HC_REG_INT_MASK, 0x1ffff},
- {OP_WR, HC_REG_CONFIG_0, 0x1a82},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END 1074
-#define HC_PORT1_START 1074
- {OP_WR, HC_REG_CONFIG_1, 0x1080},
- {OP_ZR, HC_REG_UC_RAM_ADDR_1, 0x2},
- {OP_WR, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR, HC_REG_LEADING_EDGE_1, 0xffff},
- {OP_WR, HC_REG_TRAILING_EDGE_1, 0xffff},
- {OP_WR, HC_REG_AGG_INT_1, 0x0},
- {OP_WR, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR, HC_REG_VQID_1, 0x2b5},
- {OP_WR, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_ZR, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_WR, HC_REG_CONFIG_1, 0x1a82},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END 1092
-#define PXP2_COMMON_START 1092
- {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38324},
+#define CFC_COMMON_END 1803
+#define HC_COMMON_START 1803
+ {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
+#define HC_COMMON_END 1804
+#define HC_PORT0_START 1804
+ {OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
+ {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
+ {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
+ {OP_WR_E1, HC_REG_LEADING_EDGE_0, 0xffff},
+ {OP_WR_E1, HC_REG_TRAILING_EDGE_0, 0xffff},
+ {OP_WR_E1, HC_REG_AGG_INT_0, 0x0},
+ {OP_WR_E1, HC_REG_ATTN_IDX, 0x0},
+ {OP_ZR_E1, HC_REG_ATTN_BIT, 0x2},
+ {OP_WR_E1, HC_REG_VQID_0, 0x2b5},
+ {OP_WR_E1, HC_REG_PCI_CONFIG_0, 0x0},
+ {OP_ZR_E1, HC_REG_P0_PROD_CONS, 0x4a},
+ {OP_WR_E1, HC_REG_INT_MASK, 0x1ffff},
+ {OP_ZR_E1, HC_REG_PBA_COMMAND, 0x2},
+ {OP_WR_E1, HC_REG_CONFIG_0, 0x1a80},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS, 0x24},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
+#define HC_PORT0_END 1822
+#define HC_PORT1_START 1822
+ {OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
+ {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
+ {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
+ {OP_WR_E1, HC_REG_LEADING_EDGE_1, 0xffff},
+ {OP_WR_E1, HC_REG_TRAILING_EDGE_1, 0xffff},
+ {OP_WR_E1, HC_REG_AGG_INT_1, 0x0},
+ {OP_WR_E1, HC_REG_ATTN_IDX + 0x4, 0x0},
+ {OP_ZR_E1, HC_REG_ATTN_BIT + 0x8, 0x2},
+ {OP_WR_E1, HC_REG_VQID_1, 0x2b5},
+ {OP_WR_E1, HC_REG_PCI_CONFIG_1, 0x0},
+ {OP_ZR_E1, HC_REG_P1_PROD_CONS, 0x4a},
+ {OP_WR_E1, HC_REG_INT_MASK + 0x4, 0x1ffff},
+ {OP_ZR_E1, HC_REG_PBA_COMMAND + 0x8, 0x2},
+ {OP_WR_E1, HC_REG_CONFIG_1, 0x1a80},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
+ {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
+#define HC_PORT1_END 1840
+#define HC_FUNC0_START 1840
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
+ {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
+#define HC_FUNC0_END 1855
+#define HC_FUNC1_START 1855
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
+ {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
+#define HC_FUNC1_END 1870
+#define HC_FUNC2_START 1870
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
+ {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
+#define HC_FUNC2_END 1885
+#define HC_FUNC3_START 1885
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
+ {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
+#define HC_FUNC3_END 1900
+#define HC_FUNC4_START 1900
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
+ {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
+#define HC_FUNC4_END 1915
+#define HC_FUNC5_START 1915
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
+ {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
+#define HC_FUNC5_END 1930
+#define HC_FUNC6_START 1930
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
+ {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
+#define HC_FUNC6_END 1945
+#define HC_FUNC7_START 1945
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
+ {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
+ {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
+ {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
+ {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
+ {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
+ {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
+ {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
+ {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
+ {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
+ {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
+#define HC_FUNC7_END 1960
+#define PXP2_COMMON_START 1960
+ {OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340},
+ {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
{OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
+ {OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
+ {OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
{OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff},
@@ -1231,6 +2264,7 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff},
+ {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_1, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff},
@@ -1245,9 +2279,11 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_0, 0xffff5330},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_1, 0xffff5348},
- {OP_WR, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
+ {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_0, 0xffff3330},
+ {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_0, 0xff802000},
+ {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
+ {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
+ {OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
@@ -1257,6 +2293,7 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0},
{OP_WR, PXP2_REG_RD_START_INIT, 0x1},
+ {OP_WR, PXP2_REG_WR_DMAE_TH, 0x3f},
{OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40},
{OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808},
{OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803},
@@ -1321,58 +2358,103 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004},
{OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440},
{OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
+ {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
{OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
-#define PXP2_COMMON_END 1200
-#define MISC_AEU_COMMON_START 1200
+ {OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340},
+#define PXP2_COMMON_END 2077
+#define MISC_AEU_COMMON_START 2077
{OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
-#define MISC_AEU_COMMON_END 1201
-#define MISC_AEU_PORT0_START 1201
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_0, 0xf0000000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_0, 0xf0000000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_1, 0xf0000000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_1, 0x0},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_1, 0x10000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_1, 0x5014},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
+ {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
+ {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
+#define MISC_AEU_COMMON_END 2096
+#define MISC_AEU_PORT0_START 2096
+ {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff55fff},
{OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0xf00003e0},
{OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0},
{OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000},
{OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5},
{OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000},
- {OP_ZR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
- {OP_WR, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_WR, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_WR, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
- {OP_WR, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
- {OP_ZR, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
- {OP_WR, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END 1221
-#define MISC_AEU_PORT1_START 1221
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
+ {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x7},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4, 0x400},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5, 0x1000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6, 0x4000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7, 0x10000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
+ {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x4},
+ {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
+ {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
+#define MISC_AEU_PORT0_END 2128
+#define MISC_AEU_PORT1_START 2128
+ {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff55fff},
{OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0xf00003e0},
{OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0},
{OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000},
{OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5},
{OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000},
- {OP_ZR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
- {OP_WR, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_WR, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
- {OP_WR, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
- {OP_WR, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
- {OP_WR, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_WR, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
- {OP_ZR, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
- {OP_WR, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7}
-#define MISC_AEU_PORT1_END 1241
+ {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x7},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4, 0x800},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5, 0x2000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6, 0x8000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
+ {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
+ {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7, 0x20000},
+ {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
+ {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x4},
+ {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
+ {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
+ {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
+#define MISC_AEU_PORT1_END 2160
+
};
-static const u32 init_data[] = {
+static const u32 init_data_e1[] = {
0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
@@ -1464,4905 +2546,12215 @@ static const u32 init_data[] = {
0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00088b1f, 0x00000000,
- 0x51fbff00, 0x03f0c0cf, 0x3130ef8a, 0x22b1c430, 0x3b0143f8, 0x02ecdd01,
- 0xdc406ec4, 0x19b7c404, 0x23dfd348, 0xf1476080, 0x03343031, 0x032f3731,
- 0x423f2483, 0x4d5011fc, 0x02ef9025, 0xa40cdb15, 0x77280475, 0xf2c060fb,
- 0x77629812, 0x056c1144, 0x58c8f22c, 0x4dde4d11, 0x44af950c, 0xe340ff40,
- 0xfca8b235, 0x6d081948, 0x8b5f150b, 0x95051f26, 0xd0849577, 0xe76964eb,
- 0x00607a36, 0x2726b9d6, 0x00000400, 0x00088b1f, 0x00000000, 0x7dedff00,
- 0xd554780b, 0x333ef0b5, 0x64ccce67, 0x093c991e, 0x20f264af, 0xf09c0682,
- 0x93a8a808, 0x07be3040, 0x0e22a5e4, 0x27902018, 0xf5e8bd48, 0x620c19bf,
- 0x2f06d6b4, 0x93a45a2a, 0xb6968a80, 0x6c1a06c1, 0x822203b4, 0x6b06f5bf,
- 0x368b6d7b, 0x2062a28a, 0xa5ebd8b9, 0xaffadaf7, 0x99def6b5, 0x91332673,
- 0xfebffdaa, 0x5fa7f7df, 0xf7b3ecdd, 0xf5ed7bd9, 0xb3ef6b5e, 0xa66e6547,
- 0x97d8ce5d, 0x9be507f8, 0x232c630a, 0xa1bbd65a, 0xed58cc9c, 0x9ef8731e,
- 0xec66c65c, 0x4f2e44b1, 0x12ab7a87, 0xf4dd42b6, 0x4fda9d92, 0x7af5e56f,
- 0x9743f773, 0xb9fb3b40, 0x05053d99, 0x589bb1eb, 0x6c276309, 0xf2f5ff8c,
- 0xaf3b72fa, 0x5feeb6d6, 0x557fa0cc, 0xe1d995a7, 0x661d13fd, 0x3cd7d63f,
- 0xc01984a5, 0x3eefbb50, 0xbf8c046d, 0xdbb4ac22, 0x0a7f50bd, 0xcafb421e,
- 0xfb18730e, 0x33bbb9f7, 0x4ec64e03, 0x5798da36, 0x937ef843, 0xd8c453d9,
- 0x59eef0aa, 0xaadfa023, 0x04cf8a5d, 0xaadaacf3, 0x8c9f2e44, 0x19b095cf,
- 0xe9dea886, 0x1cb1de60, 0xcd192f86, 0xf358eb4b, 0xe30bcc24, 0x0b45b532,
- 0x4dbe70b8, 0xc515d79a, 0x0f46c9cf, 0xb5eb23cd, 0xf03cc2cf, 0x144fdd5e,
- 0xceb12e1f, 0x30ed82c4, 0xf67de9ff, 0xb89ddb85, 0xa15af5be, 0x258ebf4b,
- 0xab1d717b, 0x2cdaadc2, 0xaad5c227, 0x8e8a2f2d, 0xcd33bd57, 0xfc96d708,
- 0x7b5d4161, 0x91b2796c, 0xb4616f31, 0x7f318abe, 0x0fe113bb, 0x47c7b36b,
- 0x29641f9f, 0x9deacf44, 0x45b5e666, 0x442c67c7, 0x17cccdcf, 0x2eb2bc41,
- 0xb74f4f97, 0xdd231e33, 0x7788a4d6, 0x7df3c013, 0x024d8741, 0xf843df4f,
- 0x7bf64ca0, 0xfeb0abd6, 0xa3cc99e4, 0x26fef10c, 0x1ed85b0b, 0x900bbd67,
- 0x1630a619, 0xb7822664, 0xc26f058e, 0x50d4cfb2, 0x5fc3c005, 0xeb002b24,
- 0xefe14fbd, 0xd4bccf5f, 0x9ad1beff, 0xe9bae91f, 0xe6ed92ca, 0x7496b15c,
- 0xfa7f2fac, 0xb5321801, 0xbf10cfc2, 0x88ade22a, 0x43321e16, 0xca576bbb,
- 0x7abc07c4, 0xc72d95fc, 0x4d93dcf9, 0xa678fa06, 0xa9ea1927, 0xf0635333,
- 0xb89cf4eb, 0x4e01d440, 0x827fa9ab, 0x6958cf9a, 0xedf88db6, 0xe48d6c8e,
- 0x38cb8ee6, 0x3b64775c, 0x7fa821c3, 0x08b85f17, 0x42f05aea, 0xc07c1c4f,
- 0x859626cc, 0xa6c4d065, 0x466f6e0d, 0x941f023c, 0xf8517ce5, 0xa6f5941e,
- 0x2814c2fe, 0x21a52b57, 0xc446cbc4, 0x330e9423, 0x3b75c06b, 0xd4f08cac,
- 0x7b64a63c, 0xfba78748, 0xb94f0173, 0xb7ef71d1, 0x1f316434, 0xca840f63,
- 0xc070ea43, 0xf7102e6f, 0x3cb78462, 0xf7802a12, 0x42c8ef73, 0x9034da7c,
- 0x1afcfd03, 0xf3445fcc, 0x1f1e20b7, 0x9d8c7415, 0xcd3856df, 0xaf3dbf30,
- 0x5dbf30ca, 0x2781f983, 0x2b5d089f, 0x8e3c07e6, 0xec07ec60, 0x96df9a5a,
- 0x6fe68eb7, 0x619558d6, 0xf981a4fe, 0xd3ef38c3, 0x2e6fe609, 0xfeb8d8bc,
- 0xf5c655bc, 0xcffd7c6b, 0xf989e685, 0x3ffd6893, 0xfaf8f362, 0xebe2eef3,
- 0xfab8c2b7, 0xf803ddf9, 0xefbc476f, 0xdb7f804d, 0xeb8dd379, 0xae31afcf,
- 0x7fe7cadf, 0x988b7421, 0xfff349df, 0xd7c2dd82, 0xcd377f9f, 0xf836b56f,
- 0xcd64d03c, 0x23086a49, 0x7fe17b5f, 0x802ca0c3, 0x5942a679, 0xbc18ca94,
- 0x47961dff, 0x2923b878, 0xfff61e78, 0xcdf8093c, 0x2c0bd519, 0xb94151bc,
- 0x5d3c13af, 0xf6896bb9, 0xb2a5783d, 0x064beb93, 0xc00c74fa, 0xb3f3ba77,
- 0xf000ffcf, 0xf628ee56, 0x8f24bd99, 0x265bdf0c, 0xe66f5296, 0x902c60f8,
- 0xfa85db3d, 0x673d9029, 0x59f9353c, 0x4645e826, 0xe3e20e30, 0x13962d65,
- 0x5af93a3d, 0x5f58c5b1, 0x25d63619, 0x24c8a5dc, 0xd8ca8650, 0xf79806d8,
- 0x0623e804, 0xd07df27a, 0x647e5847, 0xdda2b761, 0x15f400f8, 0xb572f4d3,
- 0x4272e89e, 0xb13ff8e5, 0xf8f241c5, 0x1ad5a6f9, 0x1c7847cb, 0x7cdd6480,
- 0x1156f621, 0x58be73ac, 0x04b9e127, 0xcf5f15f5, 0x6bdaaefc, 0xdc02c4c0,
- 0x4ef78669, 0xd416225b, 0xf0b0b75b, 0xfe3059bd, 0xb6ee0f6d, 0xf8ff4904,
- 0xae489a47, 0xc81348d9, 0x968582f5, 0xef747bf7, 0x64d8ec2d, 0x8de50919,
- 0x9bf3e341, 0xd3f58cab, 0x84c5b096, 0xc2a57976, 0x5bfc615a, 0x72ed8c1a,
- 0x54b13f9e, 0xdf31674e, 0xf0c5a07c, 0x06575c54, 0xe1e82fd1, 0x3ebb00eb,
- 0x87da246b, 0x53df14db, 0xfb05bf50, 0x1e3a444d, 0xe2f9f0d6, 0x07be2965,
- 0x997860d8, 0xdf40930a, 0x78dd8577, 0x743cb557, 0xfe183291, 0x7e1c979e,
- 0xebc184d3, 0x56fb8588, 0xdc3a21e6, 0x7cf8ceba, 0x7d762849, 0x3bea0f9c,
- 0xd03ed34b, 0xbf6daf3d, 0x1d03ed32, 0x9cef54bf, 0x0cafa86d, 0xbfe868df,
- 0x4312cb62, 0x9596b2fb, 0x9adbf686, 0x4bea1b57, 0xfa1a7742, 0xbd6ebadf,
- 0x8696fda1, 0x37ed0dfb, 0xd4326d57, 0x6e3e0c6f, 0x6160bfe8, 0x795da1ab,
- 0xfa0e6569, 0x305af537, 0xfde03867, 0xacacefd4, 0xb1f2894d, 0x1b8ff3e4,
- 0xd93ca8b3, 0x3d72a5e8, 0xbfc82bca, 0xeb2f1f69, 0xa0e496db, 0xffbe4b9c,
- 0x8d90d2c8, 0xdfcb1272, 0xcb18f2b1, 0x6837c8c7, 0xf3d91287, 0x5005851a,
- 0x6e14fbee, 0x77f3e48f, 0xec65fe84, 0x1ab7921e, 0xcd63cb8d, 0x50cbc3f3,
- 0x48b46a5e, 0xf1338361, 0xa15dacb8, 0x46d63075, 0x830cace3, 0x9ae81854,
- 0x77b3806f, 0xafe699bf, 0x22e3e743, 0x2581f7b4, 0x791fce0a, 0xf186fb39,
- 0x297f8f08, 0x48333bd5, 0x5636f62f, 0x22a07da4, 0x7e5402fe, 0xca90b8dc,
- 0x2a418d13, 0xa2ac683f, 0x06c6fdf2, 0xd71a7b2a, 0x636ef951, 0x8d63ca88,
- 0xbefe54cd, 0xb7ca85b1, 0xf950b71b, 0x9530c6db, 0x54fd1ba7, 0xb5a9f00e,
- 0x43fd10bf, 0x432b07f6, 0x0ebd9717, 0xcdc816fe, 0x7737e919, 0xe11afaf2,
- 0x4bc22737, 0xe213dd2c, 0x434c858f, 0x89292dd1, 0xc4c923d3, 0xf9c8182a,
- 0xfaf6e303, 0x8abaf296, 0xe008032a, 0x0397fbd3, 0x860d22e3, 0xde3d357d,
- 0xf683bb41, 0xd93365ef, 0x99f9163f, 0x1e9706ef, 0xd423401f, 0x8474bf37,
- 0x35fd029f, 0x7e72f14a, 0x9cbc0af9, 0x8dddbc39, 0x964d747a, 0xa4c1f3c9,
- 0x6dabebc4, 0x7538f5cf, 0x1a77d4f0, 0x945a67eb, 0x7a0fee0a, 0x478ee793,
- 0x3e78f07e, 0x65ba4028, 0x59c72951, 0x3e79a593, 0x617ec348, 0x95db0f5a,
- 0xf105fc42, 0xb6fbf508, 0x4e3448e1, 0x760e8e14, 0x1f27de1c, 0xff713f3b,
- 0xfea17c84, 0x9a3f4349, 0x473e5975, 0xff856abb, 0x1401897f, 0xc72ea953,
- 0x87376fad, 0xf3e217ac, 0xe0f9865d, 0xf58caf3d, 0x8a1bccbe, 0x427654ff,
- 0xa4a807f2, 0xacde22a3, 0x18f769de, 0xa18a75f5, 0xdc39df5e, 0xf8dfd063,
- 0x3657900f, 0x5ed15153, 0xe8b608d5, 0x0acd9d53, 0xf90bb7c0, 0xaf52e806,
- 0xb6b57ef0, 0x8f082d1e, 0xcd3474ce, 0x3d8bc4bf, 0xb1bd685b, 0x3c6c9df0,
- 0xc4d555ec, 0xcf9b57f0, 0xe38811dc, 0xf0ae7f97, 0xc4c6a538, 0x0b665ffd,
- 0x584e51b9, 0x873dc856, 0x07399bf8, 0x0b7143f0, 0xcbaba3cc, 0xe9afc071,
- 0x7acf678f, 0x8dafdc4d, 0x526ad79d, 0x757f09ce, 0xc2ce8ebb, 0xb1e2c775,
- 0xb43ff3ae, 0xcc8dc520, 0xdf894780, 0x6ac04a5d, 0xed57f182, 0xf9434f7c,
- 0x2a12d8fa, 0xc4dce7fc, 0xbf0c19f8, 0x2384eb33, 0x7b35ceba, 0xad5fe45c,
- 0xede224d9, 0x79c6eb10, 0x13134e97, 0x74bd017f, 0x62e58070, 0x26dfa826,
- 0x5dee326a, 0xfe4d51da, 0xa42c87d5, 0x89f53fa1, 0xfd04a5b9, 0xaded5583,
- 0x3ce01f9a, 0x88154cc5, 0x4dec53af, 0xbd1d24f7, 0xd11a4c8a, 0xa366b6e9,
- 0xa6fe00df, 0xa6fe0ea1, 0xcd9cbea1, 0x7638c4c9, 0xb80b66f9, 0x434eb4be,
- 0x879328fb, 0x3582b0e8, 0x7afb446c, 0xfcd263bc, 0x3f0e904b, 0xf104b27f,
- 0x479a14bb, 0x8f1e22a6, 0xd6ff1e12, 0xfbe257f9, 0x1bcf0713, 0x7c98dbe5,
- 0xed43c080, 0x8e1fc54e, 0x991737c3, 0xfe4abf38, 0x4ff080da, 0x2dcdfa89,
- 0x4d6bf531, 0x6b724a8a, 0xe3a46666, 0x642d8f29, 0x5f76a64a, 0x7a12f004,
- 0x026beade, 0x12a3fafe, 0xbb226d98, 0x74c0991e, 0x04a8fefd, 0xf2af79e9,
- 0x013472fa, 0xc04c8d4c, 0x06d80b3c, 0xd04d3be2, 0x60f08ad7, 0x1aa59cbc,
- 0x728f59d6, 0x9dd8e30d, 0xb7df0c1d, 0xf1da637b, 0xc637681f, 0x8e1bb232,
- 0x2776c6b1, 0x87f219b0, 0xbe7c67cb, 0x180fc842, 0x4c3be222, 0xebdfa17b,
- 0x662339b6, 0x34d94bf0, 0xce2077b5, 0xc878c3c8, 0xfe91813d, 0x645e52f3,
- 0xaff787ad, 0xb5847913, 0x4b0d94ef, 0xa97fc21d, 0x84b61b3f, 0xb57574d3,
- 0xa97e435f, 0x12c3bb3f, 0xf40df49e, 0x989617a0, 0x279b9519, 0xca236094,
- 0xd49bc4ad, 0x3c3d517f, 0xcb97a3ca, 0xfef431ad, 0x03a470da, 0xec70753d,
- 0x482d8252, 0xbe3858f7, 0x8359f8f6, 0xadfadfc6, 0x68305f8e, 0xf0f19dfc,
- 0x631c7a78, 0x0337a4dd, 0xfee80cc9, 0xa8f3dd9f, 0x8ff7444c, 0x85233e41,
- 0x58f84fe8, 0x4b79e344, 0xb8f8cbac, 0x59e5ebaa, 0x81575718, 0xfe05eb7f,
- 0x485ac95d, 0x294c448f, 0xb335cfc2, 0x55de0e88, 0xfea6bf5d, 0xff783aab,
- 0xfd4ed66a, 0x3119bf31, 0xe1927bac, 0x7def293d, 0x9cd49ec2, 0x1d11612d,
- 0x790b763f, 0xe087bf00, 0x106bcf93, 0xb26bcc3e, 0xb6a79a6e, 0xcf30cd3d,
- 0xf6735f80, 0xf9d11662, 0x376ab53d, 0xd9ed77f1, 0x019e68cb, 0x6afe067b,
- 0xfc6a1b44, 0xa3b80691, 0xc0334fe3, 0x3a7f1d1b, 0xcfc72bcd, 0xca72039a,
- 0x2be513f5, 0xc293cb42, 0xb7a7804d, 0x91f7c1ac, 0x9b5cb25f, 0x76415f73,
- 0x04f1fa5a, 0x744fc7d4, 0x1d34df6c, 0xea09fae8, 0x9b975c39, 0x739eb9b9,
- 0x92174c86, 0x7c853afe, 0x18bfa030, 0x43f1afe8, 0xb7e8c7b4, 0x8c0af851,
- 0x28f59a3f, 0x3746dfa8, 0x8e50f518, 0xef84dd33, 0x3e33ace5, 0x019ea2f7,
- 0x521b95bd, 0x9f5ce263, 0x6fcfc709, 0x9f4f3e36, 0xc73aba51, 0xd3516e07,
- 0x2798a533, 0xba505f4a, 0xb187a47b, 0x7957d40b, 0xe2d299fd, 0x79ff50e1,
- 0x1532bad3, 0x7ff4d5fc, 0x86ce2d2b, 0x91b2d3ba, 0xca15abd7, 0xb7cc592b,
- 0x89be8594, 0xcac0081e, 0x6294728d, 0x0a9cfc06, 0xccbf9b1c, 0x5fb47a8b,
- 0x9e8478e3, 0xd3d19f80, 0x39467e38, 0xfc46ed8f, 0xd67a98e4, 0xc3f973a3,
- 0x052bff17, 0xe62f4643, 0x1e0f013d, 0xf483c1b6, 0xbed34781, 0x8ebfc21c,
- 0x5f2533f5, 0xf305b14c, 0x4b938e10, 0x167f7ec7, 0xeaa27d3c, 0x5b0dc500,
- 0x71f9fe44, 0xf46eb710, 0x326f55bb, 0x3364e3f2, 0x0965d7cf, 0x378ceebf,
- 0xfd487937, 0xa195959e, 0x53eae0ea, 0x9fc8ddfb, 0x5f1c5f7d, 0xd6237e8c,
- 0x13d08653, 0x32a359f5, 0xa3139254, 0x749e667e, 0xc14aa3e2, 0x5b378847,
- 0xb6cf3466, 0x7e510942, 0xc0b5fa44, 0xbf5c1e01, 0x7f31aa12, 0x8edfc179,
- 0xe0d6e3a7, 0x775866d5, 0x83c85985, 0xbdb0b98b, 0xf08f2ab7, 0xf6836e96,
- 0x6b3d688c, 0xe809cee9, 0x0398a4e7, 0xc37be2d7, 0xc6cd9f97, 0x43d98e7a,
- 0xb4a2dbf8, 0x00f8470c, 0xc3cfb48f, 0x569d82f6, 0xdcc93168, 0xcf26f64f,
- 0x69ce2219, 0x1f4acc6b, 0x55cf2fca, 0xde718b83, 0xf7bebdfc, 0xf1fc619b,
- 0xf70f9a95, 0x9bafc65b, 0xccf88e99, 0xc03d7132, 0x72f390ee, 0xf82f5f3d,
- 0xf8aacfae, 0x77ded0fd, 0x8435a7bb, 0xda0b33ed, 0xb519afd1, 0xfdc3ebce,
- 0x42873e80, 0x7a35f7ef, 0xe7282f29, 0x1c95dd1d, 0x9e49bbb1, 0xf3c8373f,
- 0xd07d633a, 0x3b7a5f7c, 0x7fbc707b, 0x9c42f8f6, 0x1d0f949e, 0x67d9e82d,
- 0x725dfbe6, 0xb42cd1be, 0x7391fd1f, 0xcc5fef9d, 0x7fda74ae, 0xba037410,
- 0x925e9084, 0xfbdf402e, 0x121b5f10, 0x78bef7d3, 0x6b6e5df4, 0x5db946c8,
- 0x659f6815, 0xe625e781, 0xafd883e0, 0x21f76166, 0x50decd0b, 0xe927fc88,
- 0x70d0d4ce, 0x740353d4, 0xfc21497f, 0x7c717667, 0xb7361fd6, 0xcb1e7ee2,
- 0x40b7ae0a, 0x42ca99fb, 0xa22627ca, 0xfe75f8f3, 0x017cbd74, 0xfce2b7dd,
- 0x9a8ebbe3, 0xef493e10, 0x49de44c7, 0xffecadca, 0xbdfa598c, 0x0f76be62,
- 0xfc55f7cd, 0x166eb457, 0x7c780b8d, 0x80dfcf56, 0xff9c76c7, 0x1fe166c7,
- 0x3b63c60f, 0x3c073ff6, 0x3c1739ee, 0x939de87e, 0xcfe30799, 0x7f093b32,
- 0x87329f2b, 0xbea4b0ad, 0xf52fd2d9, 0x333c335f, 0x5e5627aa, 0xd71fb0d4,
- 0x8549f2b9, 0x6bb2acf8, 0xc26c35c5, 0xf96378e0, 0xe3e910c2, 0xd903b8d8,
- 0x5ab2f912, 0x7f13178e, 0xff07b354, 0x734e4cc3, 0xf54ef498, 0xbffb634e,
- 0x9b30f945, 0x24ce04f2, 0xf1b1b79e, 0xf1d0b2f1, 0xe248be47, 0x8b26717c,
- 0x619e1c91, 0xd0f7c429, 0xbb608bee, 0x33fca2e6, 0xdc6291db, 0x314cac9f,
- 0x6e8e4fec, 0x4ff21930, 0xc9b1f3b1, 0x5fec4cca, 0x6730e42a, 0x6fb0c99d,
- 0xee321b97, 0xa737e5eb, 0x5a63ea1a, 0x9ffa1846, 0xd0cf25b7, 0xbe7c2e3e,
- 0x9d82fda1, 0xf1f50d13, 0xfa1b17ed, 0x6659d85f, 0xae4717a8, 0x749ff432,
- 0x3ea18e78, 0x4326fba5, 0x2f6fa9ff, 0xd45fb435, 0x7ed0cab3, 0x0c6bc7c9,
- 0xeffb4bf5, 0x2c8ff432, 0x00ac38a9, 0xff025efd, 0xe086f314, 0x67c8a857,
- 0x99acfe07, 0xfc0e4f90, 0xa8c4d0b9, 0x2bc867dd, 0xa673f81e, 0xf81f9f1f,
- 0xfb1f8973, 0xe7cb3295, 0x5952e2f1, 0xdb19b0ce, 0x0be05553, 0xc0d96fb4,
- 0x569a9817, 0x7203f28d, 0x39454235, 0x0fc3a7fb, 0x469d0215, 0x46482cac,
- 0x34f20d3b, 0xbd373d42, 0x27ef8394, 0x962da792, 0x290f1b96, 0xac7ded83,
- 0x38e590be, 0x5bade655, 0xbad37de8, 0x65a7616c, 0xb230f17d, 0x5f9f9233,
- 0x7a1c5333, 0xe3d70366, 0x86a43667, 0xdf9efef9, 0x0fe75c39, 0x24e8399e,
- 0x9efdcefe, 0xaf01db93, 0x892cebd3, 0x7f2901da, 0x323f22f9, 0x7945582a,
- 0xe3fe418f, 0xb8f59ea2, 0x1ff573ce, 0x99c6fd63, 0xff021e92, 0x05d1d709,
- 0xf1f68972, 0x27da1483, 0x7161e35a, 0x36b6eff7, 0x16770f36, 0x4b2e7e0c,
- 0xdce1cd65, 0xb40f30fb, 0xe159f14f, 0x1fd86dfd, 0xbc587bec, 0xb5ea26d7,
- 0xbd454d21, 0xebe22b56, 0x521e71d8, 0x7e466f4b, 0xdd96a1d8, 0xc5d14eac,
- 0xdc5a0dd3, 0xd077c7bc, 0x0473c089, 0x0d80efaa, 0xcf5fefe6, 0xff306d7c,
- 0x0ca78b1a, 0xf4ee6beb, 0x9af21d12, 0x7ae1667b, 0x5dc13a73, 0x73fbd9d7,
- 0xc056a780, 0xd4f08b53, 0xa714fda9, 0xb0a8bff5, 0x879c5cb6, 0x5f66bb8f,
- 0x487e432e, 0xd51ce704, 0x72057c42, 0x738e3770, 0x4ed09aa7, 0xf28e7ddf,
- 0x638d5eb0, 0xf2ec065f, 0xf15bed52, 0x137072c7, 0x9eb44a78, 0xe196d0ff,
- 0x9d39b728, 0xc0a89fa5, 0x60e039b7, 0x9f22a726, 0xd1bef632, 0xebef623f,
- 0xf344d0fc, 0x7689557e, 0xf1157def, 0x0631f7ce, 0xc7231dc1, 0xe46f75de,
- 0xebe9a417, 0x4c17e7af, 0x10950012, 0x306c14bc, 0xe5e2db88, 0x95f6738b,
- 0x2427561e, 0xbdefe786, 0x377881ce, 0x4bfd5e46, 0x7c8f5ec7, 0xb311fb77,
- 0xb2845562, 0xc84178c1, 0xe677b2eb, 0xf0e8a664, 0xe5b1b5b3, 0xaf27556a,
- 0xf7f012a3, 0x9ff72a9b, 0x5c3635b6, 0xe380595d, 0x3d7a4c7a, 0xca13dd90,
- 0xd27988dd, 0x8c2f870e, 0x9327acfa, 0x702b58f0, 0xbe0a6c90, 0xf4bcfc89,
- 0xd7ca6ec2, 0xe97c88e6, 0x297e7168, 0x2ae3be76, 0x97f847cf, 0x8c2958da,
- 0x16cda7fb, 0x34b277f2, 0x08e28798, 0x5a5b9d07, 0x0a6c0636, 0x93db2fb4,
- 0x0c53f5c6, 0xd0c6e15c, 0xa20a1bd5, 0xc71c02f3, 0x3dbc1e51, 0x7f3859c1,
- 0x4451c22e, 0xe11276f2, 0xe84d48fb, 0x473c9dcf, 0xd21beb79, 0x43c6c4fe,
- 0xf0e2fd09, 0xa7e485fd, 0x7e4dffe6, 0xa1c3fa31, 0x0c3fa8a2, 0xd058b2eb,
- 0xeb8c594e, 0x8b55d9d2, 0x95d6dce5, 0xaeda1964, 0x92416e3e, 0x32407389,
- 0x9ae1230f, 0x57f2e169, 0xe618d1ef, 0x4e51ead3, 0x54d9f0e3, 0xbb88628b,
- 0x3138adbf, 0xede6553f, 0x7887bda4, 0xe5c2e311, 0x33a3e24e, 0x0bfbd6de,
- 0x877c7327, 0xc8f7c086, 0x04322375, 0x0f887d5e, 0x16f1c789, 0xbc069ea3,
- 0xb5e2e2fa, 0x326af006, 0x57ca75e0, 0x95fc95e0, 0xa98f9daf, 0x9cefee34,
- 0xa5dff816, 0xde703304, 0x5bbc3753, 0xbab0f982, 0x086b9f79, 0x679ed7d7,
- 0xe7e9b32e, 0x981ef991, 0x9cf383c7, 0x9aafe1be, 0xe825a7d0, 0x39ed3667,
- 0x35cf192f, 0x93f38ad4, 0xfd5af6a7, 0x3e5f8e8a, 0x1e70f2fd, 0x1b4fa5ea,
- 0xf2c7ccaf, 0x5bcf2a54, 0xf53bda9e, 0xa9d5f210, 0xb12d1c9f, 0x9ea738c0,
- 0xd2a25a3f, 0x60d85b3e, 0xef2f6a7f, 0x203b412e, 0x7c03daf3, 0xdfaf8b67,
- 0xfcfe0b56, 0x4aafebda, 0xc8d5e788, 0xef1ca707, 0xebfae096, 0x0f09675c,
- 0x7cb9db0f, 0x6da1923c, 0xd32332c4, 0x17fa10f4, 0x4fc1a45a, 0x5b8788db,
- 0x75265822, 0x7971fbb7, 0x23bbb7ce, 0xfa7bba58, 0xbd7618fd, 0xe201fe05,
- 0x67b1f3d5, 0xbe1fd63f, 0x33e504f2, 0x1ab017d9, 0x80916380, 0x3b59f7e3,
- 0x3a04a91e, 0xf37d2efc, 0x7e86e423, 0xf685eb01, 0xa0dff19b, 0x1e818e87,
- 0xdc6c80f2, 0x7cfb72a4, 0xb512a553, 0x191ff853, 0xe9187947, 0x8a3545d3,
- 0xeea5aec1, 0xd3f94199, 0x6429af3e, 0x61a47581, 0xbff81a56, 0x66ceeb4f,
- 0xc5cec0df, 0x3883bf96, 0x9d9d7de5, 0x0952acfa, 0x67df30a9, 0x7fac8f42,
- 0xd3f1127d, 0x178a65e6, 0xfefb18f1, 0xcb5eeb63, 0x727a099f, 0xf3879dd8,
- 0x6efc8267, 0x90027916, 0xa7cf0537, 0x80f22c3d, 0x877b866b, 0x9ae3ede9,
- 0x8252f323, 0x46defaba, 0x89d6dfbe, 0x7ca15ee7, 0xed7b9c41, 0xfaa2cc6a,
- 0x2a5e8d4b, 0xe9638d23, 0x434b66f9, 0x7bdf9e0a, 0x3342c2cd, 0x77bf97c1,
- 0xe51bff78, 0x1ddb42e0, 0x699b2fbf, 0x33d6f187, 0xd6f8cf3a, 0x13ddefbd,
- 0x1df00e9a, 0x1929a4f8, 0xd2a740ed, 0xa61c478e, 0x23fdbe2a, 0xcb5d4f51,
- 0x75a54f48, 0x306e742a, 0x3611cbad, 0xb7d3fce9, 0x765edc2c, 0x72de785b,
- 0xb442da2a, 0x7fa5b32f, 0xef413fd7, 0x0fea0cc7, 0x7b9e1f81, 0xa98f9d8e,
- 0x4ecf94fd, 0x7c30def4, 0xbfb9fc6f, 0xad4c77d7, 0x2a89f3a0, 0x66a77fb7,
- 0x903eb667, 0xcfebfbcb, 0x79e1f497, 0xfa7238ce, 0xbdef3117, 0xc7f74e16,
- 0x64768d72, 0x8fdb9597, 0x1df316ff, 0xa392dc68, 0x9651bf3f, 0xffe8dfc0,
- 0x335ff2a6, 0xe488ff68, 0x68f596be, 0x3f72bcfc, 0x11fc49e5, 0x3619af8e,
- 0x577d470e, 0xca04b2b1, 0x97ae4e19, 0xe50eb0d2, 0xeb9c550c, 0x689cfc66,
- 0x2b56455a, 0xe28e5f9e, 0x5a73af81, 0x1c16bf4f, 0x7dc3dfcf, 0x7c0fb4df,
- 0x29ebf20a, 0x7fee39a4, 0xfd11b6cc, 0xaa825b67, 0xbc52f486, 0x9d22578f,
- 0x3a238cf6, 0xec958fd9, 0x5c3a464f, 0xde4cf2cb, 0x2dec1f28, 0x9c627a05,
- 0xb6f14fb4, 0xa73ee8b1, 0xe340bf9c, 0x23e595f8, 0xc877e04a, 0xea5a05e7,
- 0x784fdc0c, 0x82581ec4, 0x7e113247, 0x678c165b, 0x478cde0f, 0x5debedd2,
- 0xf4e0154d, 0x3b40b5ed, 0xba360bd4, 0xfe00369b, 0x4704a6f6, 0x6b9796e2,
- 0x30e9a3bd, 0xb970a7b6, 0x68e8d828, 0xd1c8b942, 0xe61f3c3c, 0x5f22e7f4,
- 0x503dd40d, 0xdbabaf1f, 0xaf2aea62, 0xbed575cb, 0xc843e7fc, 0x5c5d75a7,
- 0xd6f006be, 0xfea0ac59, 0x7e135f3c, 0xf4398392, 0x547fddfb, 0xbe341382,
- 0xedc85d8f, 0x4a07dc98, 0x81f62ed0, 0x828b58b2, 0x1e04767a, 0xff47cb60,
- 0x6cca9bba, 0xdca54fd6, 0x59dbc8df, 0xea04607c, 0x76605353, 0x35e7d239,
- 0x18f7970b, 0x72b1efbc, 0x2d6bdd3e, 0xf985659d, 0x63d01e1e, 0x46ba5f7c,
- 0x81b669e8, 0xc15eedeb, 0x9b369fbb, 0xc9c01a42, 0x79e83876, 0x553f388d,
- 0x4c81cef3, 0xd4f8d7dc, 0xc9e22acf, 0x7b085cc5, 0x5b5f8f11, 0xb946822e,
- 0xef907fa8, 0xcc7c819b, 0x21d57c45, 0xd937505c, 0x847ce9ba, 0x87f69ee5,
- 0xff3718cc, 0x73c1e2d8, 0xbeb9d58e, 0xa2fe78fd, 0x0fae5f7a, 0xc3bde555,
- 0x9d577c79, 0xd1399ed2, 0xbacbe519, 0x21d94dce, 0xfb27f7c0, 0x95f2477f,
- 0x61ec878f, 0xa38edafc, 0xd79e105a, 0xa1a7bc75, 0x4524fd61, 0xda3e81fa,
- 0xb877bdb7, 0x9c12f92f, 0x3c6657ef, 0xa7803859, 0x14ee96d1, 0xc3c979fd,
- 0xa0fde7a0, 0x3d035fcf, 0xd021e58f, 0xf3d07eff, 0xd7f8be47, 0xaf3fd44c,
- 0xccd7c25a, 0xcd9e71c1, 0xe15e60f7, 0xc1f84f53, 0xb4ff5089, 0x3d6f8c60,
- 0x6b3e57d4, 0x7fbc600e, 0x96716d44, 0x6083ff40, 0x9dfde847, 0xc2f4eaff,
- 0xdb0583f3, 0xf471bd33, 0xd36795dd, 0x60981f99, 0x7cef997b, 0x36078f94,
- 0x976c9bfa, 0xbeb9f802, 0xea18ac55, 0x0d93795a, 0xa99365e4, 0x1f62d1fd,
- 0xc73867d5, 0xce597f81, 0xf2b187e5, 0x278e52a6, 0x71b4dfaa, 0xdfdc0cd3,
- 0x8a7bbb5b, 0xc89a7c82, 0x7d9d56de, 0xc825ce8e, 0x6b263e7a, 0xd4aaef80,
- 0xaa59e510, 0xce84fece, 0x271acc33, 0x61fe68f3, 0x1f2dc68c, 0x8edd7886,
- 0x13177c7b, 0xbdf843c9, 0x68b2f6c2, 0xabc1f51d, 0xd0be02a9, 0x41334d8d,
- 0x0cb11fbe, 0xdcf1fbb4, 0xe12b9aa0, 0x523c2167, 0xfb26aafc, 0x099a6e2f,
- 0xcd76ea41, 0x36867e38, 0x02afdfd0, 0x249abe1f, 0xfc682beb, 0x6293fd41,
- 0xf1c997fa, 0xf3c2e3eb, 0xb75a3d88, 0x2ff57f41, 0x59fbe8d6, 0x3b68ff88,
- 0xc727978d, 0x56f0475f, 0xf6f3370f, 0xbf65e850, 0x4dcfa51a, 0xeb4dfdda,
- 0xdaaf6f01, 0x97a8a57d, 0xa465affa, 0x7cff916f, 0x49b87e3a, 0xb3aad9e8,
- 0x39fd3157, 0x58b49b92, 0x90c75cba, 0xde3ee76e, 0xa2f186f9, 0x7a604ce3,
- 0x7e047ffa, 0x6fb7584d, 0xedd762bf, 0x03ce90b3, 0xc510b3f3, 0xf35b55f3,
- 0x07a75859, 0x5f1c3ffe, 0x027f0e17, 0x5ffe6638, 0x61ac6386, 0x451c28be,
- 0xfefef806, 0x80259470, 0x02b7d663, 0x959dac47, 0x67617ee5, 0x0d5452fb,
- 0xbdb63bf7, 0x8ffda564, 0x96c85374, 0xceba7687, 0x5b7a7644, 0xbf1f8b6a,
- 0xc6b6d8bf, 0x1ee1e74b, 0x722a04b1, 0xdd0a7fc1, 0xabfda269, 0x6ebe796d,
- 0xf6dadfdc, 0x26be792f, 0x8b3d349c, 0x071662ec, 0x3c5b6d81, 0x087e2aff,
- 0xa3efef8d, 0x3e3b44e9, 0xf646c532, 0xe59cdb72, 0x9f4fff94, 0xda1c7673,
- 0x0a7e9d49, 0x66531d91, 0xf3353f93, 0x3c26d6be, 0x149191ef, 0x2ffd1c78,
- 0x74dad425, 0x76bc7878, 0x58667fae, 0xbe6066db, 0xcf595b68, 0x73938c38,
- 0x803e702e, 0xfcf5abaa, 0xff311311, 0xbc1adc73, 0xbb780ad6, 0x1bf22aca,
- 0xf2852c29, 0xc9051562, 0x6dd2c2a8, 0x5a253ed0, 0xa7caf87f, 0x3191cf29,
- 0xefc860af, 0xaf814b18, 0xa67a3abc, 0xf641ffa9, 0x461afeb9, 0x8bf47179,
- 0x172feff5, 0x027d7d7e, 0xb4e81dff, 0xad1ce11c, 0xd4c21cf4, 0xd1e75d61,
- 0xd45f18d9, 0x139955ae, 0xe46d496c, 0x8bffdc77, 0xfd6207f1, 0x22de595a,
- 0x7c44acfc, 0xf3958cf1, 0x25ff80e5, 0xe40fadfc, 0xb3f0a37e, 0x1ea2ed2a,
- 0x9e506e73, 0xfe13ec17, 0xfc62df4f, 0x37d61268, 0xd769978c, 0xee7ce904,
- 0xe5deb172, 0xd1334a5b, 0x7fdca9bf, 0xd963ad23, 0xf7e4d9e6, 0x84bcdf2f,
- 0x784a7bce, 0x9bfc632a, 0x51265acf, 0x1d112bbe, 0xfd221fa4, 0x273f5899,
- 0xde157bd1, 0x41cfa256, 0x58edafcf, 0xe67cc36e, 0xf67fa8c4, 0x7367c42a,
- 0xf1a6dca0, 0xb31e09ef, 0x1b6d38f3, 0xb6005f7e, 0x399650ff, 0xb957d715,
- 0xdf092329, 0x716b623f, 0xf91e5ca2, 0x61d7d7e2, 0xf093f43f, 0x9529ccbc,
- 0x9eb2a5fb, 0xb72b9e08, 0x55e93f70, 0xe1accf31, 0xeff3661f, 0x1879c4ab,
- 0xe97ca696, 0xec7efc48, 0xa69d9879, 0xaf903bb2, 0x9d7810ef, 0x873e0b62,
- 0x155793f5, 0x5ea79f12, 0xc7cdd079, 0x79d79e37, 0xd3a5c44c, 0xee4dc3fb,
- 0xbfdf3a74, 0x71e5e1db, 0x23ac1946, 0x653e4fed, 0x7f1e8ea9, 0xaf8978b1,
- 0xc528fe31, 0x47d7a438, 0x702ce0f1, 0x0579f82f, 0x7e48df23, 0xa6f3eafb,
- 0x2dff066d, 0x69f4de7a, 0x8b4edbf2, 0xacf5e5b8, 0x724be6c8, 0x51ef6c31,
- 0xdebd4e31, 0xbf416e99, 0x16bcc030, 0xf5ae4b8c, 0x16eb9cc5, 0x11aedae7,
- 0x7dc209fa, 0xfa0daefa, 0xaf15f619, 0xcfac669f, 0x37eb1bf6, 0x7effc454,
- 0xee374d8b, 0xdf169fdb, 0xf0299e75, 0xb10ca726, 0x002d82de, 0x3bbd6eb4,
- 0xae127f54, 0x9bcb4777, 0x26fe7d6e, 0xb0584f36, 0x4f212345, 0x900eee34,
- 0xbca43c0f, 0x9d688580, 0x99dda94f, 0xc0a0b8fa, 0xb579ce22, 0x12f33aff,
- 0x36c391a0, 0x9fea266c, 0xe7eb955e, 0x4afefbbe, 0x4b18ebf1, 0xcefc0de4,
- 0x168bcc78, 0x2853ee2f, 0xff285a2f, 0x4edb3f51, 0xa5bf03df, 0xf7a1935c,
- 0x3900c7c7, 0x5d33ae10, 0x5f3c8663, 0x9bacf73a, 0xb79ec5fa, 0xe7cdfbff,
- 0xcec73c24, 0xe23e5ec7, 0x16007bc6, 0xf9d1366c, 0x5c8b85ab, 0xa4889df4,
- 0x6338ec6f, 0xe171a8b6, 0x84ff844e, 0xb8f4b774, 0x74e6ff71, 0x4af299bb,
- 0x6de3edb1, 0x5f8b37ca, 0xbaf31a17, 0x43fd9ea7, 0x57d60461, 0x375cf4ab,
- 0xd8e2972e, 0x638c36f1, 0x5f719d37, 0x3fbe7a49, 0xaefba033, 0x86fdb7a9,
- 0xe3cf20a4, 0x4903be18, 0x2f128fc4, 0xea70f089, 0x7e16edf0, 0xd164327e,
- 0x28c6d7e7, 0xef9439fe, 0xa7b2a4db, 0xd1a77ce2, 0x7be71364, 0xc44c9ed5,
- 0xfda5dd57, 0x2f2ab714, 0x41eee87e, 0x7ef160bd, 0x23e0e29f, 0xe97b0710,
- 0x3c775efb, 0xfc1bfdfb, 0xc4ec10ee, 0x8fb71b02, 0x12f3edb1, 0x17f8a39c,
- 0xecdf8741, 0x9bd1e4ff, 0xd013e087, 0x6f30733c, 0xd551ef35, 0x3aaef983,
- 0xdbc90f4b, 0x3718affc, 0x76fc7f11, 0xa0f29dbf, 0xe9da160b, 0xf9d888fe,
- 0x8f3dab4e, 0x9df30cde, 0xff707806, 0x00a8f4ff, 0x66f4f1e1, 0xf6fb83d5,
- 0x983ae7f3, 0x54ffd74d, 0x08f9f1c7, 0x0cce99df, 0xba701f3a, 0x49df3e2b,
- 0xfb655d3c, 0x45c57986, 0xf209fcc6, 0x8eadca1f, 0x3c57feff, 0xc70abbfe,
- 0xd7e1c29e, 0xd53a8b9f, 0x8f1c9f91, 0x7c1f72ae, 0x1cf18b4c, 0x2ee80955,
- 0x775eb71e, 0xb180acb0, 0x0c8eb261, 0xa075f30e, 0x7071e39e, 0xfb24f104,
- 0xdd7cd43f, 0x8577dc4c, 0x03f11fba, 0x9d5bf9ef, 0x7762bfd4, 0xe8cfc211,
- 0x059ab9bb, 0x3b01e64e, 0x74a399f4, 0x54f00db3, 0x43407dd2, 0x6475857f,
- 0xc46bfad0, 0x6ef0b1fb, 0x68fd8bb3, 0xe4ca87bb, 0xc23ffdb7, 0xba3a4a7b,
- 0x49f8bc93, 0xfc6a4756, 0x5d9a0073, 0x60039c31, 0xf1e50f6a, 0x3cf06632,
- 0x473eff6b, 0x87894db8, 0x3bfcf59f, 0x2abb18af, 0x8d46b7e5, 0x11ad7d90,
- 0xe6abf5f6, 0x5bdf10ef, 0x9ac492be, 0x355df46d, 0xbfe013e0, 0xb41717fe,
- 0x7af9403d, 0x1cac9dfe, 0xf31164a7, 0x47fae9b7, 0xe33cf26c, 0x833d7cc3,
- 0xbd70e7de, 0xfb033a02, 0x4cf6a667, 0x01bff250, 0x7e316e1f, 0xeb6b5267,
- 0xf43d4429, 0x15fc1284, 0xedfeadd2, 0x77ac4c9e, 0xfc9279bc, 0x67c573ae,
- 0x7f3205ee, 0xeed0d114, 0x3a5dddac, 0xb57f286c, 0x9d40e306, 0x7de28c7e,
- 0xf187c516, 0x5abcc3c6, 0x2c11d9cd, 0xdd143694, 0x126859b2, 0x9fdf33c7,
- 0xdf8099e8, 0x6e3ac1ef, 0x2ff5039d, 0x3fccf462, 0x69e9fc2a, 0x574cffdc,
- 0x730d41d9, 0xdd376a6c, 0x214bf0bf, 0xf214bf2f, 0x33dff1d2, 0x74fa46ae,
- 0xdcf269bc, 0x97e3ab93, 0xc1b21624, 0x7b5bd77b, 0x8efe827e, 0xebf6cbac,
- 0x869d2fc1, 0x72e36afc, 0x66b5e523, 0x7d397c51, 0xfe26e6d2, 0xc476f61c,
- 0xc7ce798d, 0xff23e951, 0x7f271fb7, 0xccd3a3a1, 0x61cd93f0, 0xa0e6828b,
- 0xc1ff8a33, 0x2a3d70e3, 0x96a21de5, 0xde425c0b, 0xe57bdf91, 0x951e59f7,
- 0xc2b5c7fc, 0x3c65ec7f, 0xfb11a87e, 0xf02a7fac, 0x1afe39d3, 0x5c600b3b,
- 0x3f8f27f7, 0x78fc8539, 0xdf2d9fa3, 0xbdf67e93, 0xa55e39eb, 0x38a362de,
- 0xf266647f, 0xaf296bfd, 0xf687ab2c, 0x207f24b1, 0x03d3c4ff, 0xd47a0a97,
- 0xe819359c, 0x46a7a51a, 0xdfcf94f4, 0xd2127b07, 0xfa5cc39d, 0x377d0171,
- 0x51f31b73, 0x66b6e33e, 0xe4e90b07, 0x3e51e3b6, 0xc63dc76f, 0x798967f9,
- 0x3e38925b, 0xf877c43b, 0x91dfaa1d, 0x37d5145a, 0xae075f80, 0xabcbfd4f,
- 0x79498f14, 0x95dce390, 0x7ee1f7c4, 0xadf357f1, 0x2bb67db2, 0x76a5deba,
- 0x2f24b7d3, 0x27de437e, 0x24999f8a, 0xc5e58947, 0x92f215f3, 0x4d05f84e,
- 0xf97b46ea, 0x9f1ff09c, 0x68aa6c3b, 0xdb7fc38b, 0xe73d7c6d, 0xec01a867,
- 0xdb844177, 0x32fd44b3, 0x15f9c553, 0x3c589781, 0x3fc7e7a4, 0xd056b2ff,
- 0x7f8ca6a5, 0x22f78ccf, 0xca0c3e60, 0xd78c1f6c, 0xd10ce65b, 0xef22cbf3,
- 0xcd493ee2, 0xca2f56f3, 0xf6f3ef6f, 0xf49bcc2a, 0x6aad6f3e, 0xc7a60e73,
- 0x1e8d6fe6, 0xebfd6f7f, 0xf42bf49f, 0xbecd3b63, 0xf3c1de31, 0x845dd927,
- 0x93bd019f, 0x68d83fc0, 0x3b3c7273, 0x792d9e38, 0x5ba78f5c, 0xb1ff788d,
- 0x33748790, 0xd7a0b644, 0xfe7905a6, 0x90bb39e9, 0x5b87900f, 0x4eec2f90,
- 0x2c7efe03, 0xafa969fc, 0xc6575f1e, 0x7ee1a78e, 0x6ff6886c, 0xc91f7e3b,
- 0x4b7a79c6, 0xb56fdfe3, 0x6309f05b, 0xea6eff46, 0xfb42af4c, 0x678aede8,
- 0x9ff68b0c, 0xe7bfceda, 0x061ddb35, 0xf02cdbbf, 0x7638e521, 0x3cc40f9e,
- 0x90cfa81d, 0xc31ece2e, 0x03e4bb3e, 0x7ae4d7a9, 0xfd911da4, 0x67f82f7e,
- 0x8ccfe0ba, 0xfc1f3e26, 0xca9ac2b3, 0xdeff01ed, 0x7841eb9d, 0x9da2b21e,
- 0x78f34160, 0xaddd67a0, 0x16f7d18c, 0x33fc1f62, 0xbb2df047, 0x07e81d6e,
- 0x7e16fe92, 0xd738875f, 0xd407fd28, 0x7a9d134f, 0x0e1c43b8, 0x55f5c2b3,
- 0x70927e8c, 0x7cfc3ac0, 0x138d171c, 0x8edc6fb5, 0xb58f42a9, 0x6322ef8a,
- 0xfe7fe6e5, 0x569b911f, 0xe9025e71, 0xbcdf4f10, 0xc96eec25, 0x0562fedb,
- 0xc04c6bf8, 0x624fc3e9, 0x1ce7ba4a, 0xb0bd40b0, 0x37cb414b, 0x82855720,
- 0x45bc70df, 0x18f8a3e3, 0xf032e49d, 0x3e2a3fdf, 0x0366df0a, 0xa3a2dff0,
- 0x2e2494e7, 0xf32a19c7, 0xc3fedf13, 0x80381fc2, 0x00d4efdf, 0xdf34505d,
- 0x969bf01a, 0xbf4763dc, 0x43e66de7, 0xfb74e9bf, 0x8c78d312, 0xbf70b75f,
- 0x6e2f4065, 0xbd07ebe6, 0x6d7a8ed6, 0x477edbcc, 0x2167d411, 0x5bce30fd,
- 0xd379f8c4, 0xe3185776, 0x198f2925, 0xe0667b73, 0xa39d473e, 0xf75dbd61,
- 0x277fa07c, 0xca8dcff4, 0x35ca0d75, 0x82b53bcc, 0x2b4eb3b7, 0x8b160fdd,
- 0x47bec62f, 0xeff226f3, 0x7ae24c6e, 0xd234f50d, 0x6ec21ca9, 0x4afdc03b,
- 0x798cc86e, 0xe4c657d4, 0x957dc44e, 0xa2c14943, 0xa67ef035, 0x29983738,
- 0x26669bce, 0x126b72f1, 0x0e99cbd7, 0x5c1d065e, 0x79ba67bf, 0xef79d8ff,
- 0x54defd12, 0xed7f064c, 0x7c3c8204, 0x38af9f30, 0x327e88cb, 0xed42bf4f,
- 0x8002cdff, 0x9997456f, 0x4d3b07f2, 0xea24fac1, 0xfb1d12a7, 0x0f8b3d4c,
- 0x1ef10123, 0xf3128ba5, 0xb167d493, 0xa3ea34fe, 0xfcf20d9b, 0x3be3825d,
- 0x9190afb8, 0xfafcbfd8, 0x027e7d7c, 0xb7c26b7f, 0xfa496fe2, 0x8c80bccb,
- 0x307f25bf, 0x6bad20f6, 0xbfce4cea, 0x6177afa0, 0xbafa0afc, 0xebc91a68,
- 0x6bbc780f, 0x719178e3, 0x4f66667c, 0xc0b7c61d, 0xbc9ef487, 0xe4f729f7,
- 0xe41e749b, 0xf537248d, 0xb7f0e5db, 0x5bc9c526, 0x6869a88d, 0x8487fba2,
- 0x42f795dd, 0xafdf6a8d, 0x19be3aa8, 0xfee1c555, 0x60c59269, 0x7d443a17,
- 0xd3971277, 0xa5115551, 0xd88dfa00, 0x015143ba, 0xfced119e, 0x0688f77c,
- 0x0c9ff746, 0xf0e61bcc, 0x95870d8e, 0x70a28adb, 0x17669b37, 0xe69e0079,
- 0x09af874c, 0xe0ce699e, 0xcd77080b, 0x039d08b1, 0x5bac7a9d, 0xd32978c5,
- 0xf205ffe9, 0x6bd7849b, 0xbcc08cf6, 0x8718e3bd, 0x9fc065b3, 0x79e6c9ef,
- 0x3c0aefc9, 0xc9fb09b7, 0x4efdd30e, 0x336f6e4e, 0xa6db19ef, 0xfd26673f,
- 0xccd7e858, 0x72e3ee28, 0x614f799e, 0xb8ba03db, 0xb03f3cb1, 0x0f979f03,
- 0xbf11371b, 0x307fcfb7, 0xc73ee2a2, 0x154d5b0b, 0xf6fc38e1, 0xa75394b6,
- 0x2eb8d7ff, 0xc957ff09, 0x4967ec87, 0x1def9a1a, 0xb7060f82, 0xa5ed443f,
- 0x84dfa64f, 0xd06cd6f0, 0x48f16e18, 0x033a67bc, 0x239f1027, 0xc4155bda,
- 0x9f8e63c9, 0xae0e7828, 0xce798aba, 0xaef6d203, 0x7bc1cb6b, 0x7cee6a97,
- 0x79ef072e, 0x38c0f092, 0x98d6ef84, 0x0fd28b73, 0x67e11ff9, 0x67033b94,
- 0xcebafc70, 0xb7bfb44d, 0x5fbf0772, 0xcfbae127, 0x9eb02f11, 0xd5bfc8f5,
- 0x5478bfc0, 0x8dfb0147, 0x6859acf4, 0x6a26efa3, 0x63fe7176, 0x18f0b41b,
- 0x8eefb7ac, 0xe47da098, 0xa61f7edd, 0xed77abef, 0xf0e99656, 0x4c26b235,
- 0xb9e77bfb, 0x97227ee4, 0x4bed11f7, 0xb38f886a, 0x63e43e1c, 0x71d92fcc,
- 0xfdcecf3f, 0x1e52deaa, 0x425af49f, 0xafd0bd63, 0x87c93737, 0xbabd3bdf,
- 0xdefa0afb, 0x35bcf5d0, 0x7ca3b8a2, 0x6f7ac0f3, 0x40f9c229, 0xdf20f339,
- 0x835fde80, 0x2726f2f5, 0x1a9fbe43, 0x77a9c743, 0x3bf6be73, 0xc31ef2dc,
- 0x63d7c889, 0x81aedc1d, 0xeebf205d, 0xf3c38590, 0xdd74e33c, 0x75c8149a,
- 0x87f7e064, 0x54f18611, 0x86bb454a, 0x387608f9, 0xbd5bf095, 0x37d683b5,
- 0x7bf71772, 0x92b577aa, 0x82fd4a3c, 0x7b7bc0f8, 0x457be2a7, 0x47040fc4,
- 0x943b93e9, 0x927fd0e3, 0xbcf3ccc3, 0xc7ec775b, 0xf019887b, 0xd02fc60b,
- 0xce4affbe, 0xe96e2a3f, 0xce3dc80d, 0x59e7c453, 0x097b93a6, 0xbff91c77,
- 0x1e77e118, 0xe5c83eeb, 0x6fefc23f, 0xe921fc12, 0xf5c1c330, 0x21c7a48f,
- 0xe300e80d, 0xa24bca1c, 0xa23ca471, 0xfa11ccfc, 0xc68ce4c9, 0x090e1249,
- 0xd9472ee7, 0xb8298e15, 0x775a6eee, 0xe09556ed, 0x0502d72e, 0x3b7c75ab,
- 0xfbf9c1cf, 0xb57782c0, 0xf9be781e, 0x9f0947e7, 0x3f0a2db5, 0x5472dac7,
- 0x3e7a879b, 0xe319acf4, 0xff19ab9d, 0x51cf747b, 0x7757cfd2, 0x76d7bc70,
- 0x736f56ec, 0xf728f946, 0x74c581e4, 0x95bb751f, 0xe9923fa1, 0x788cde0c,
- 0x024fc418, 0x25cf520f, 0xf4871392, 0xf91a4253, 0xe421e029, 0xf520dc62,
- 0xdf1156e4, 0xfe7f2730, 0x515d624f, 0x41ac10fd, 0xf927947c, 0xdf50d80e,
- 0x3ce8544d, 0xe933b487, 0xf51e3833, 0x37bdc4f0, 0xd287e64f, 0xb25f8c98,
- 0x63bee8e7, 0xe2b7d018, 0x5d04bbfd, 0x3f8479e1, 0x37687967, 0x74b1dc25,
- 0x6bf081fb, 0x1351f0e2, 0x476b1fc2, 0xfac05f24, 0xf73db19a, 0x41ec89a4,
- 0x86d6c86d, 0x98af26fb, 0x75df90e6, 0xf09b8160, 0xdf90b357, 0x67f9bc63,
- 0x84d4af5c, 0x777f749c, 0x256e704d, 0xdba543ed, 0xc50fb87d, 0x79b50782,
- 0xf774c1ae, 0xce9fbf3e, 0xcedd5c31, 0x8f4060e5, 0x4bfa73b6, 0x1fd72efd,
- 0xcfc7375d, 0xec858d2c, 0x6dbc51a9, 0x7d08f24d, 0xdfe5cc10, 0x3ccd7fa3,
- 0x7b1666f7, 0x88b3d29f, 0xcf5b5a8f, 0x2faadc21, 0xd35fbb79, 0xf2c727ef,
- 0xd7baf557, 0xac2ed10a, 0xa54c3aca, 0xb7a0ff3e, 0x7d057b57, 0x8be5149e,
- 0xa7985f48, 0xc93b727a, 0x0d07f54d, 0x0ace6f24, 0xc79c67ae, 0xd6307a8c,
- 0xb4772a5f, 0xdefdc2cf, 0x9e2a1ff2, 0x5ed89626, 0xde7850ac, 0x2fada3f3,
- 0xc19cf1bb, 0xe26bbdc0, 0x0e1bf03c, 0x3bbdffce, 0x97c4e101, 0xfe50da0d,
- 0xc78d57e2, 0x74296f22, 0x7dc0808f, 0x1719aeef, 0xd2e7887d, 0x7e532677,
- 0x375dd3e7, 0xc021f9dc, 0x72e3bbdd, 0x4de943b2, 0xfe9fe201, 0xf70fbb0c,
- 0xa97e20df, 0xebee8050, 0xe3765fdb, 0x3f27e4fe, 0xda2270ba, 0x9c050fb7,
- 0x5e667f27, 0xe7b97887, 0x865e9f99, 0x2561d5ed, 0xef6cf50d, 0x15fe1fce,
- 0x8ed570f5, 0x9a9f8a7a, 0x0d4bf47e, 0xe14d39f7, 0x677cfe56, 0x7dfb07b2,
- 0x65d37db2, 0xf6a6ef88, 0xb93f6a26, 0x07ea95bd, 0x4be9f99e, 0x33f68dff,
- 0xbf61f6e0, 0x4fdb3f93, 0xaa09a974, 0x04f0defc, 0xeee8fd7c, 0xa19f5cfd,
- 0xb07287bf, 0xc919eb90, 0x3f7f92d7, 0x8bd6e679, 0xc6bbfaf4, 0x60a5181c,
- 0x1f5661ff, 0x7d07d79e, 0x15fbfa4e, 0xc4ed533b, 0xce9cadf7, 0xaf74d5e6,
- 0xd73e7943, 0xdc61883b, 0x72febaf7, 0x91477d07, 0x4afb10e1, 0x293f1176,
- 0xbcc3ed0a, 0x6d05e972, 0x217dba4d, 0x9457bf49, 0x1756a3d9, 0x8b379f45,
- 0xb8939b79, 0xf514f93d, 0xd539c430, 0xac1efc65, 0x5f6c7f4f, 0xd6b5fe48,
- 0xd76bf743, 0x34be7114, 0x9a3d393b, 0xb7e57e45, 0x39630ee0, 0xcf02e41e,
- 0x8eeb40d5, 0xfadf292f, 0x1a6fd913, 0xbed357c2, 0x784752da, 0x0e7f11f9,
- 0x8ee7c658, 0x354b06a2, 0x1b592f3c, 0xe91c5e3f, 0x3dfd3274, 0x663a2376,
- 0xde92f28f, 0xe8c6fab1, 0x5511d2fc, 0x27dc26c1, 0x906d6ab8, 0xe17ea9ee,
- 0x5ee937e3, 0x2ac667e3, 0x30df8893, 0x2f76847f, 0x6a79a4e4, 0x70078f31,
- 0x7114ef9e, 0x17a987a3, 0x32aff1eb, 0x75fb49d5, 0x6a97a4fd, 0xdc5d859b,
- 0x5b19e221, 0x6bde367f, 0x2f39ef0a, 0xc09bedd6, 0xd5274e7b, 0x8fe7b3fb,
- 0x5a143b47, 0xabc87648, 0xa527bc11, 0x09a161fe, 0xa1e2e8b7, 0xf51738d8,
- 0xca77e61b, 0xe77ea59d, 0xe3296894, 0xdd3c58df, 0x3877da25, 0xea277efd,
- 0x16e79dc7, 0x7a09d687, 0x2cf4aa3f, 0xed0e3e47, 0x2f907bb3, 0x29eb2eeb,
- 0x3bb1ebd4, 0x0b4e9e04, 0x41dfc13e, 0x64cdb8a0, 0xb5df110a, 0xa4dad05d,
- 0xe77bb60c, 0x44757f09, 0xba41e2a7, 0xc73ad88c, 0x9bf03f40, 0x7f686bd6,
- 0xe4252ac6, 0x7eae76cf, 0x11e61c6d, 0xaf586e81, 0x495d98eb, 0x833b03f8,
- 0xe75d6cfe, 0x73840eec, 0x3eb5fa64, 0x3f0797dc, 0xe77d1664, 0xa0a6c351,
- 0xda3a3efc, 0xad246fbf, 0x1e786143, 0x384b51f3, 0xa3f7ed0b, 0x787d0ae3,
- 0x582ea63e, 0x0af24359, 0x2f7d2d7e, 0xfe40dc15, 0x26f79d6b, 0xc6a7ed1f,
- 0x853ef9ca, 0x1be054fc, 0xab8b1dfa, 0x7c2cbbf1, 0x7920ec3f, 0x2dccebaf,
- 0x9eaef845, 0x9e60f3e9, 0x8fc494ed, 0xf4dd2d2c, 0xf7a7183b, 0x27485958,
- 0x03eeaf97, 0xf80266bf, 0xafc17b35, 0x3fdf8099, 0x1571d9fa, 0x0d7a71c6,
- 0x5deab779, 0xcdef74b9, 0x7f8ed129, 0x2d7ddd5e, 0xe21195b5, 0xcfe11acb,
- 0xc5fd5ba6, 0x26e8ebb7, 0xfa5894fd, 0xf6e4ee3f, 0xe727bce8, 0x00463d12,
- 0x239f103d, 0xa26e9ab6, 0x863485f5, 0x8aaabbeb, 0xbe01ea45, 0x229ab6ab,
- 0xfa884f97, 0x3de3b131, 0x4f7114e9, 0xf518a05a, 0xa702f95b, 0xca87af4f,
- 0xbb26fc93, 0x2c628fce, 0x92e31930, 0x845d338f, 0xaf4e1df7, 0x7e0c87f4,
- 0xd3b8e0cf, 0xe1f8c3ee, 0x04d0969a, 0xaf0e87dc, 0xf2885a4f, 0x49d47a08,
- 0x781eebfb, 0xb6d6e31f, 0xb8f3b64b, 0xf9d689b5, 0xc247a77d, 0xe301b937,
- 0x5ac0fcdc, 0xbe5c7f6e, 0xe5d6fb78, 0x2ee7e94e, 0xbef3c62e, 0x3e9d7375,
- 0xff36af8c, 0xe38a5942, 0x746c85d7, 0x705d6e39, 0xf2579bed, 0x5fdf8038,
- 0xbaa2fc23, 0x347d1bf4, 0x7a7e20ff, 0x4e8ddb8f, 0x4ebaaf4e, 0x1c642f6e,
- 0x5e217a8b, 0x29ca5ede, 0x6b8c63ea, 0x39497f24, 0x3c79573d, 0xfc90096d,
- 0x2375869c, 0xe1f00e3f, 0x630f9c0b, 0xff8934e3, 0x8bc2f8d8, 0xef7506c2,
- 0x8f7d0776, 0xe69af52f, 0x3d451c0c, 0x6476d754, 0xd0abb123, 0xdc2f7543,
- 0x3f94385f, 0x78f95365, 0x3d2b9036, 0x1359e0df, 0x432a44d7, 0xc0df3a4e,
- 0xc6df5fb8, 0x1d8e8fef, 0x4f42b7ef, 0xbf4a7c49, 0xcf82f319, 0xc29ff943,
- 0xfa227d7e, 0xcf29d5fd, 0xfc0d8457, 0xdf0535e7, 0x44f17dc3, 0xf7be56fa,
- 0x7226f34d, 0x63efa97c, 0x99f325e9, 0x45d98eb8, 0xecb5fb89, 0x0c48f117,
- 0x3e0b14ff, 0x80e7037e, 0x07724f75, 0xbea0b917, 0xd3f99928, 0x7e8bdf00,
- 0x29f7e569, 0xc42fed8c, 0x655aaa78, 0x5797cc21, 0xf584b4ef, 0xa1f736e7,
- 0xf5ef040f, 0x33216cb9, 0x3bb95df0, 0x0671c1e8, 0xcbbd87ee, 0xc1e1e74e,
- 0x7282994d, 0x481ed23b, 0xf7e06575, 0x4f743d89, 0x1e0e63ec, 0x311ff44f,
- 0xc5cbcf87, 0xe87bbe7b, 0xacce84f7, 0xea7ca7cd, 0x61fc2f3b, 0xede01fcf,
- 0x1a3e7b53, 0xd493cfad, 0x55364cd9, 0xad3c6f97, 0x2b67dfc4, 0x167d7176,
- 0xf3f65bcd, 0x438be5bc, 0x63eb41e7, 0xf3d1fbf2, 0xfdf9b1b3, 0x6fa878e8,
- 0xfbf263eb, 0x6f5c5d07, 0xf9e7df47, 0xf14c77fd, 0xc7bd6fbf, 0x8bafdc65,
- 0xc5cfbf6d, 0x8f23abf9, 0xe3ff45cb, 0xe4fd184a, 0x115d6be5, 0x396b8fbc,
- 0x63bf463c, 0x311427b9, 0xf9ae51b9, 0xcdfc323e, 0xbe5f81b5, 0xe807d844,
- 0xbe474ea7, 0xff68790c, 0xd0f42831, 0xff57ce92, 0x72f4f18c, 0xc3a6d995,
- 0xbe6d4b38, 0x13fbf843, 0xba673a1f, 0x7e56ed51, 0x744c86e7, 0x6a2d86e6,
- 0xf455bca0, 0xf374f57c, 0xfabe72df, 0x57302bb0, 0x7fd21bf2, 0x5f5cedd1,
- 0x9756fec8, 0xe467373c, 0xd01377b7, 0x665dc739, 0x3ababe46, 0xc698b029,
- 0x4194fdbd, 0x7a569caf, 0xf201fe9e, 0x7bfe6ae3, 0xd7efb147, 0x8afaf98a,
- 0xc53ee9bb, 0xc97fd5be, 0xebaebf26, 0xff51b7d5, 0x817bcad5, 0x7b862c3b,
- 0xfc932b81, 0xf7efc4d5, 0xfba14f4d, 0x73c186ce, 0x1ab82782, 0xf6fe41e1,
- 0xdbf9eba7, 0x2ce78c9b, 0xba01b5ea, 0x921ef7d0, 0xcb946c2e, 0x23ae8f48,
- 0x36a58f44, 0x701bdd3f, 0xf0403f9b, 0x4c8e4a2d, 0x5ff018f1, 0xf7dd37f4,
- 0xf6e42958, 0xfdfe2d1d, 0x3e09f7e2, 0x8dfb283c, 0x4efafce0, 0x1e7aab36,
- 0xff234ccb, 0x2ce42c3e, 0x71cbde2c, 0xbc421ffb, 0x18795e80, 0x8e7400f1,
- 0xcaf5e8a4, 0xe7ba7ee4, 0x374a6fa2, 0xae7d1f7d, 0x80ac66f8, 0x8e784bd6,
- 0xd1385e73, 0xf0b56f7a, 0xb5df0075, 0x47af48b9, 0x87bfebc6, 0x5b80b9ff,
- 0x493be5ca, 0x142cbc46, 0xe091fbeb, 0x87974a93, 0xfd7c1be7, 0x3bce38d9,
- 0xb8f1f1a9, 0x768f8a28, 0x7fb583c2, 0x6fd01a71, 0x6d35d83e, 0x12a7e122,
- 0x938a0f9f, 0x49ff228a, 0x5c6b6dfb, 0x0bc5ed0c, 0xfdc9be72, 0x963f8f3c,
- 0x885a0bcf, 0x57d96eff, 0xc2bd6de0, 0x3145e77f, 0x2b6844c3, 0xdf2f32c7,
- 0x7fce980f, 0x203ecaaf, 0x195c8797, 0xcec4fc51, 0xc09b0c7b, 0xc4bb779e,
- 0xe63e40f7, 0x1f16f7c3, 0x8b75ccfd, 0xf43df0d7, 0xef4e385b, 0x1fc8479d,
- 0x0a45a63b, 0xda719c5b, 0xc7b6c8b5, 0x6b3b6894, 0xadc17ee0, 0xbbe99acf,
- 0x9ea66398, 0x2d7f7047, 0xfc99a6f4, 0x3dde3fa8, 0xfa2bbe83, 0xffa30ef4,
- 0x45d0527a, 0x20309f7e, 0x830b783f, 0xc5eff079, 0xcb9ce6dc, 0x3ee629e5,
- 0x14164af6, 0xfb13fbbf, 0xe103427d, 0x893df079, 0xe73c87eb, 0x7ce6e995,
- 0xf38269f3, 0xebfb8a19, 0x3ee327da, 0xc4bed45d, 0xf1f1d3ee, 0x474e6edc,
- 0xf6fea769, 0x304aaef9, 0xe77175df, 0xba7cf393, 0xb3bafe3c, 0xd58edcdc,
- 0x461becc7, 0xb3e795c7, 0xa49fa85a, 0x2cd9fd77, 0xd2eb2e7a, 0x37be8a8f,
- 0xfd8bc68a, 0x13e6472e, 0xa7beff25, 0x9efd1b30, 0xf224db11, 0x78099e86,
- 0x687bd0bf, 0x06df412f, 0xf52f60af, 0xfe4b8800, 0x9aa17879, 0xd8efe517,
- 0x9d5f0075, 0xd51effd4, 0x4fb8b704, 0x217642ef, 0xf821177d, 0xe59df179,
- 0xf25aee74, 0x854f546f, 0x71adbc78, 0xa7319e3f, 0x18b3ff41, 0x13a4b0fb,
- 0xb204c1ec, 0xfc0e74cb, 0x12378bf8, 0x5f32571f, 0x17d1e926, 0xe93f74ad,
- 0x120bb5d7, 0x4b421b9e, 0x8adefc2c, 0x6bc7ba74, 0x86ff988e, 0x981fee2e,
- 0xfbfe7e6c, 0xf5e67e55, 0x03dff264, 0xca05fb21, 0xa5fa855d, 0x00cc8eb2,
- 0x3162e9f5, 0xf00fbe0a, 0xb64a2a5f, 0xf2859834, 0xb7ffef26, 0x961670b3,
- 0xbcf9174d, 0x04ae5e58, 0xa7070e54, 0x30d62cf3, 0x6c9bfb0a, 0xff9c663d,
- 0x58da7991, 0x4fa01fbc, 0xdf89f249, 0x74fba3fb, 0xf3f303ad, 0x9dd64bba,
- 0x0eefc32e, 0x7dc5bbd4, 0xa366360f, 0x4673ebdf, 0x057da13e, 0x616cda51,
- 0x0701ddfa, 0xcdba448b, 0x8c00fbf8, 0x614f9bbe, 0x3dfc112d, 0xff17be8c,
- 0x1e1c518b, 0x76fc0fbd, 0xef2194f7, 0xc7b6370b, 0x2a9e17dc, 0x7e634ae0,
- 0xad221fba, 0x635f78c2, 0x42ad7386, 0x3016e13f, 0xc444cf3e, 0x0b61ff43,
- 0x6f0bef63, 0xe1fc7051, 0x1b73e341, 0x5f7a463b, 0xbeb20489, 0x93de8b4c,
- 0xdf8920b4, 0x22eff44b, 0x115b9c8e, 0x6f015728, 0xafd88bf3, 0xe8de50fc,
- 0xe1177e09, 0x4370f1bf, 0x17d40d6d, 0xe3c6cebe, 0xc9c530f7, 0x185dea9e,
- 0xefcadd7f, 0x3efe2d6b, 0xec361d67, 0xf0c78a3c, 0xc9b51707, 0x2b2ace78,
- 0xb17d718c, 0xd48fb443, 0x7f18bda8, 0x3fdf1100, 0x95f74bcf, 0x74f38bd4,
- 0x9a7987f8, 0xc333f3d6, 0x67d30768, 0x7ac46ff4, 0xee8cfdff, 0x19f79059,
- 0x408ec76d, 0xbf4afa9f, 0x87da0325, 0xe23e64cf, 0x03bed149, 0xebcf9dff,
- 0xdf889797, 0x5d47c08d, 0x2733ca9b, 0xc6fa9b13, 0x5cfcc1b0, 0x18bb35df,
- 0x73f954f3, 0x297f13a7, 0xba0a2f82, 0x7c51ff14, 0x3f68c22f, 0x972bbeb5,
- 0x1c17dfce, 0x719e51f6, 0xd4e1a981, 0x1bdf5c1e, 0x13effe3c, 0xc84cc6fb,
- 0x7918d4f3, 0xafca24b9, 0xe72c5ed4, 0x7accfb97, 0x3ce046be, 0xfc44a0f0,
- 0xc7bd12c4, 0x1662ece5, 0x6671c3fd, 0xbd25c744, 0xbdb45332, 0x3fdf0b72,
- 0xf646aa9b, 0x225e1ca3, 0x4e5162ca, 0xe2330166, 0x7f73c4ab, 0x5177ce13,
- 0xf21a68e0, 0xaf9b74fd, 0x9f46af19, 0xb86150bb, 0x4e9cc4af, 0xffb17ebe,
- 0x3d8af52d, 0xfb67e799, 0xddbab3dc, 0xdf997dba, 0x30df85ba, 0xb98d8d96,
- 0x24f7ff67, 0x3bffa517, 0xdb18dc91, 0x4066e463, 0x7d3f313f, 0x7dfb18b7,
- 0xff3f3ce1, 0xc05e6a6e, 0x7e3e7cf8, 0xe71f97d7, 0x15d0ec77, 0x0b8e8ccb,
- 0x78416472, 0x6ec77f62, 0x2ab7f48e, 0xa2d6fe8c, 0x8522fa7f, 0xa7b0c0ec,
- 0xc1ccbf6b, 0xe25ce67c, 0xb12ebacb, 0x43fc0f3f, 0xfd89e3df, 0xe34efaf9,
- 0xd77d7cfe, 0x74337b92, 0x9d75f3fb, 0xcf3fb55f, 0x5bbfeeed, 0xd30f74c2,
- 0xd604afbf, 0x165e7982, 0x7107c2fb, 0x9462783f, 0x3cc5aeee, 0xe35073af,
- 0x3107f4fb, 0x4bcba37f, 0xfcf070cc, 0x340b8ce8, 0xe5573e7a, 0x2129f2fb,
- 0x0b92f927, 0x665defc4, 0x7e41d998, 0x1fe7847e, 0xeb3e22c2, 0xb40d7e16,
- 0x47fca06f, 0xa465dc8c, 0x6547ca31, 0xf2963cdc, 0x8abb0b3a, 0x0d3e6327,
- 0x7fe533f4, 0x7a5eddbb, 0x98b0617f, 0x395723f2, 0x8af3a46f, 0x6aad5df5,
- 0x7adf4ea5, 0xf5f78d93, 0x9a5df9c4, 0xfa29e482, 0xe019a5df, 0x489e7a27,
- 0xa7dfcb0f, 0x9bbe62ac, 0x7de2e597, 0x9d774001, 0x3194b79d, 0x53fb4f7e,
- 0x5d2b9d0a, 0x76483ce5, 0x630ed578, 0xd45b943f, 0x6bafd57b, 0xcd537f74,
- 0x467c41ae, 0x5de52d72, 0xa1b517de, 0x3ee0afd4, 0xe611df4f, 0x77fa436b,
- 0xc05b8cc4, 0xe04f98ed, 0xa5e858b3, 0x3666f349, 0x24e53ee1, 0x565f9713,
- 0x7fc91be9, 0xe7917377, 0xc7551d84, 0xfe50cad3, 0x63eb9f40, 0x067dfcb3,
- 0xc4531fd4, 0x717ab1f8, 0x2e03f08a, 0x137d6153, 0x0a7d76a3, 0xa683f5e3,
- 0xbddd332e, 0x3c9ce02f, 0x9fdc4720, 0xd24a7a90, 0xc6e5ef03, 0x92cb5df3,
- 0x63c87e85, 0x184f4879, 0xc157f89f, 0x8d2a73cc, 0xbca1521f, 0xf407cc44,
- 0x84df210e, 0x9dfa364c, 0x034a8d8f, 0xfa1b79e9, 0xa03e508d, 0xfd7f4904,
- 0x46642abc, 0x1ac45ebc, 0x1726b86e, 0x03b758f5, 0xb07c05e9, 0x4d1fcf52,
- 0x5bbd922c, 0xb509f031, 0xe8c4a6f7, 0x3d12a61d, 0xc238304c, 0xa5ad7669,
- 0xc42bf47d, 0x6e53a273, 0xc9d51fb4, 0x3fb4618f, 0x87c01fea, 0xf52fddb1,
- 0x93ea3309, 0x8f05f65c, 0xf43feed3, 0xfb0f8c1d, 0x8c5fc22c, 0xa1dd4ba1,
- 0x641f8b93, 0xbe49fa51, 0x983598ba, 0xca1f00b3, 0xf75e792f, 0x2a5ba462,
- 0xfc8c51fa, 0x892c69a7, 0xe64d8be4, 0x57c907f9, 0xa2255e92, 0x4fa484f6,
- 0x7841cb0e, 0x53b4ed2f, 0xa462e9de, 0x58bdd013, 0x4aed2f8c, 0x6af4e4c4,
- 0xb0174879, 0x7ec1e61b, 0x97aa665e, 0xe4c933e8, 0x614cfa27, 0xdba434be,
- 0xd7ddf6cf, 0xe8eb7084, 0xe3192db0, 0x80e80545, 0x3ed8357c, 0xe463db18,
- 0x94bbe259, 0x2c9fc979, 0x9c394665, 0x670d04e1, 0x8dcafba2, 0xa0b363f7,
- 0x7b94f08a, 0x6f8fdd06, 0x41b1d232, 0xc8ae7845, 0x444bf632, 0xa7a41ccf,
- 0x89690fb4, 0x6ae529e9, 0xa9d39db7, 0xfa84e81e, 0xd2afd266, 0x34813867,
- 0x25ccade7, 0xc53bb0fb, 0xfaf584db, 0xc5f4851a, 0xcbdf6ee4, 0x106fcf58,
- 0x337eb9ed, 0xafd683ee, 0xde53ede5, 0x7ac0cc0a, 0x5ede3ac1, 0xc9b04f7c,
- 0xaddfe385, 0x2fd8bdd0, 0xcbc7727c, 0x47be1ed8, 0xcfca5fbc, 0xe06fd6e1,
- 0xf9847fef, 0x3cf10bde, 0x7c0ccb44, 0x9739ae3e, 0xf0b00eff, 0xfc172e67,
- 0xe3695bb2, 0xc83c20f7, 0xc8715dc7, 0xce28c496, 0x65cafee1, 0x6f979d62,
- 0x3f4cebe5, 0x1785557e, 0x37b2a9f8, 0x2d95d740, 0x1109c164, 0x3372ef58,
- 0xf1f9f204, 0x10bc1be4, 0x0d288f28, 0x500aa744, 0x72fbf49d, 0xc0b67cd3,
- 0xc7ef9e78, 0x92fa79ef, 0xf329bc79, 0x35ffb8e5, 0xfb4f675b, 0x469e7992,
- 0x654ccbf6, 0x09ef3f7c, 0x91a3f917, 0x7c8298c7, 0xfec0b88f, 0x57faf289,
- 0xbd9037e4, 0xe64722ba, 0xa5d47bf3, 0x97f15f30, 0x178acd9f, 0xcc9e7f07,
- 0x62c7e4ed, 0xaf3e4f1f, 0xbdfdf30a, 0xf4cbc8dd, 0x30e9ad7d, 0xe19853d5,
- 0xb9ddab1e, 0xfe7aaebc, 0x28f35f7a, 0x06b35dfc, 0x36ca8435, 0xcc7da15b,
- 0x679fe0eb, 0xffe14627, 0x2830d93f, 0x00800092, 0x00000000, 0x00088b1f,
- 0x00000000, 0x7dedff00, 0x45947c09, 0xf37f78b2, 0x093215cd, 0x87213b93,
- 0x98884013, 0x861c2184, 0x4109264b, 0xe8098414, 0x720d7282, 0xeb22dc85,
- 0x97f75763, 0xd9110441, 0x73d6f8dd, 0x0160763d, 0x18896151, 0xc3824830,
- 0x12a20882, 0x75040411, 0x0844ae22, 0xf1e20c49, 0xabaf2e1e, 0xbe667bba,
- 0xfc38666f, 0xddbf7ffb, 0xdb2e23f7, 0xaaefafa9, 0xeaeaeaea, 0x084c8eaa,
- 0x908238b9, 0xadc4b45b, 0x9680a1cf, 0xc8401bfe, 0xd5fa25dc, 0x3f02242b,
- 0x213c6376, 0x33fe1277, 0x192d7aec, 0xf01dc844, 0x289085bb, 0x2afda4b3,
- 0x9fdefe83, 0xd328bff4, 0xf3bfcf72, 0xc84d94a3, 0x3a558caf, 0xd50a1dd2,
- 0x8459ece8, 0x9c9b359c, 0x7c84be9a, 0xcce2392e, 0x7d690903, 0x965cff76,
- 0x64beceef, 0x47e696be, 0xb048d4d0, 0xefde62df, 0x13d2e27c, 0x977cdfda,
- 0x918f0bee, 0xfd22ed0d, 0xa43a6a57, 0xae9a1a27, 0x232f7e57, 0x41e93d1e,
- 0xf2ad7948, 0xe271257b, 0xe57acaf7, 0x91d99277, 0x845efd06, 0xf69f8a1f,
- 0x5907cb67, 0xcfff6932, 0xe6147fbc, 0xb9346c57, 0x97129a65, 0xc193d5ae,
- 0x1e7ce1eb, 0x4e157f34, 0xc8fba793, 0x64246f17, 0x6cc89752, 0xbb9095d2,
- 0xe67e8ecc, 0xf99c4238, 0x146529e6, 0xe1e9cebf, 0x5c5025d6, 0x4c396536,
- 0x6308fdb4, 0x8bce9b96, 0x4cc588d8, 0x79f12df1, 0x9f0c0d4a, 0x3c52471f,
- 0x4832f8c3, 0xe699e006, 0x14d1f53b, 0x8448e3ee, 0x93881bf1, 0x88c23e00,
- 0x4252112b, 0xbf1846ac, 0x42475e1f, 0x2179adff, 0x57ccaef1, 0x1f027de1,
- 0xd36244cf, 0x47137f41, 0xa775f12b, 0xfbd22169, 0xfbf2bb4e, 0xcb1388af,
- 0xc2ac9a4f, 0x24c9b12f, 0xe0aed7de, 0xca1cbb93, 0x9e041372, 0x3cf1ab47,
- 0xc515fccc, 0x01309d2f, 0x54d24c7c, 0x58c9e3fd, 0xb30d6f0a, 0x1cf6c5ae,
- 0xb852178f, 0xbac12eb3, 0x4b44c002, 0xfdb409d7, 0x926c404a, 0x3d22ae8f,
- 0xab189d58, 0xe707e9ed, 0x93761991, 0xee389e0f, 0x1499a0d8, 0xcfe5d22e,
- 0x06913c03, 0x29837ffa, 0xd210c53f, 0xb2f80994, 0x18262574, 0x52d47107,
- 0xde92d3b8, 0xd814da35, 0x132b488f, 0xfdb4e313, 0xdb4bf8fd, 0x3e066911,
- 0xb0cf20b8, 0x2a383267, 0x53f552f3, 0xc131b4e2, 0x5acf37fa, 0x91787809,
- 0xa38e81e1, 0xadf943de, 0x2b5f7d73, 0x2a7210e5, 0x942468ce, 0xa67467de,
- 0x1f5f52e5, 0xea2ee63e, 0x4a95ed86, 0xd0b6efae, 0xc764836f, 0x52cf3023,
- 0xf8cf5b8d, 0xa13a6aa9, 0x6f3f96ed, 0xf748adb0, 0xf8d43fcd, 0x2d23f008,
- 0xc93bffa2, 0x1d7ad2d0, 0xeaeb1752, 0x0bdefc74, 0xddca2ce8, 0x2b17451f,
- 0x9185ef5d, 0xdd60278e, 0xe8b8c3b7, 0xa309697a, 0xaf8e86eb, 0x01932245,
- 0x74e2549f, 0x7e02ca2d, 0x04eba3bc, 0x951297ca, 0x81d1c953, 0x351856fd,
- 0x5e1fb764, 0x757d78db, 0x096655b9, 0x9989f7c7, 0x4dc7ff60, 0xdf30d5b6,
- 0xae293d16, 0xe96c78a5, 0x9a48d3c2, 0xa01bfad2, 0xcf2840fc, 0x70e0edea,
- 0xabe5868b, 0xbee517db, 0xdd9236ac, 0x545fac74, 0xf29bb213, 0x4369e597,
- 0x4bb68b95, 0x147fd2a6, 0xa2dbed2f, 0x453e0156, 0xbce67dbd, 0xdd1c604f,
- 0x802df64d, 0xcd35d98f, 0xfb5f877a, 0xe01f30ed, 0x579b1d13, 0x454b187b,
- 0x45ccfb7f, 0xef1e209f, 0xbcdd20f2, 0xdb0160f0, 0xe1f6fdb1, 0x1fd21e4c,
- 0x72c3ac0d, 0xc5cb0ebe, 0xae53ab7a, 0x04a64937, 0x63f9468d, 0x5aa0b941,
- 0xc67a957f, 0x17ef844f, 0x4ebac4d3, 0xfb42d089, 0x64535953, 0x1fbec35a,
- 0xa64248a5, 0x64b2c91b, 0x21a33f9a, 0x7175e501, 0x1997b3a4, 0x0cd23ce9,
- 0x0ce489fb, 0x5f862f97, 0xe4b4bf8a, 0xd93e312b, 0xa9ed6fc7, 0xf6cf384d,
- 0x81a63f55, 0x786f2ebc, 0xa875e507, 0x191f3979, 0x48f38516, 0xd6e0fb60,
- 0xd9391b6a, 0x059787d3, 0x428f3666, 0x0f40acb9, 0x313664f2, 0x7ea7e81b,
- 0xc3d3fba4, 0x57b95c28, 0x6f285c47, 0x93901a6c, 0x9c63c397, 0x7e2c435d,
- 0x72612df2, 0xf0c96217, 0x688e49c1, 0xdc5c9c05, 0xb53e514d, 0xff22bbaa,
- 0x147d45ba, 0x1ccee9f9, 0xf963dc05, 0xebf94510, 0x7015f26b, 0x536e67ef,
- 0x35c1bf94, 0xc2770141, 0x9e3f202f, 0xca4e5d97, 0xbfae37a7, 0xde7f515b,
- 0xbf4859be, 0x895ebe3a, 0x4994d6d3, 0xd05b30f1, 0x80686e9f, 0x670e52c7,
- 0x68a3ded5, 0xb725b89f, 0xe1cfcb44, 0x69bb31fc, 0xf94258ee, 0x897d6fa3,
- 0x67221fa2, 0xd28e30ca, 0xa18912ed, 0x46a73eac, 0x7bcc4fb9, 0x37170946,
- 0x992cbe3c, 0xf407ea04, 0xdb4b4327, 0xac5d2129, 0xf5a8dfa0, 0x11519e84,
- 0xdd0fc8b1, 0x57c63748, 0x79303e6a, 0x074861f1, 0xf4f5e83e, 0x3e3e01b0,
- 0x19ebe2f0, 0xb9d5f109, 0x7b8e07b7, 0xee3a36de, 0x18fc40f4, 0x10fc9512,
- 0x43f25166, 0x1f928678, 0x7e4aac22, 0xe4ab9ae8, 0xa3be3507, 0x20fe4a6c,
- 0x105ffa1e, 0x568cc77c, 0xbca94df2, 0xefe00f72, 0x5f9e7872, 0x1fe90abf,
- 0xf0a987a0, 0x1af01e3a, 0xff6bc3ee, 0x2625b6dd, 0x61df660b, 0xe478041c,
- 0x197620f8, 0x046c52e5, 0x3e561dea, 0xcca7a14e, 0x107ae288, 0xd69fa76f,
- 0xf7d613bd, 0xa049c932, 0x967fd09e, 0xdcd3bae4, 0xc639df14, 0xd520a02a,
- 0xa2b3ec6f, 0xd32c1ca8, 0xdf21b3bb, 0xefc1ef4f, 0x417bd2ad, 0xa7411ef5,
- 0x7281c439, 0xa61f0025, 0x2f50f427, 0x3f40ff80, 0xff8411ed, 0xed077ea8,
- 0x5179f256, 0x7234b93a, 0x06a4be20, 0x0d911dc9, 0x72106cd3, 0x3fb171d6,
- 0x157ca366, 0x4a0da2f8, 0xe84772fe, 0x817da28f, 0x448f211f, 0x255206bb,
- 0xab7f0227, 0x50c913e4, 0xa9371de2, 0x223ff841, 0x35e80bd8, 0x416f9bc4,
- 0x0899037e, 0xbc4de94a, 0xd30f723f, 0x06a48d4b, 0xb242b2e9, 0x7f69972e,
- 0x4be975f2, 0x7f4ba508, 0x64ffd533, 0xa69b42d8, 0xd18d77c0, 0x773ec329,
- 0xfe60b91d, 0x3f5a06ea, 0xc5f95d61, 0xbff2d098, 0x5b8d8dfc, 0x281f549d,
- 0x2464f4d9, 0x5afaf4a1, 0xa56f135b, 0x2ed6cbf5, 0xb4d1b48d, 0x7d44eb45,
- 0x3c976bea, 0x7f6415da, 0xed8a3f7e, 0x264274df, 0x7c153f90, 0x795fa72a,
- 0xd7ac1c6c, 0xccead6ef, 0xb9522d32, 0xd036e0de, 0x375151f5, 0x46c92c7f,
- 0x8fc199b8, 0x54f8037c, 0x5e4a1b9f, 0x82de327a, 0x5933a3fb, 0x3ba90893,
- 0x62b4d099, 0x81463fcd, 0x3a49567e, 0xd4b8c196, 0x1fffa0f5, 0x595afee8,
- 0x77d4cf2b, 0xe11e720d, 0xb5d05aeb, 0x6fb1eeb2, 0xcdf848e4, 0x557e07a3,
- 0xbd062f97, 0x3b67ea8e, 0x89bb3c84, 0x45eb04dc, 0xe2b883e0, 0xdf93ef50,
- 0x99bb2178, 0xf66badc2, 0x787e4a47, 0xc421e422, 0xaced674f, 0x0969bcbf,
- 0xaa36874d, 0xfe5e90d7, 0xcf585cf5, 0x9ee12f52, 0x5a581a4a, 0x0e4773a6,
- 0xb654aca5, 0x687a874a, 0xaebfc6d9, 0x33c533fb, 0x5eb06639, 0xdd2fdb4f,
- 0x43c7f6f8, 0xa6bfbe40, 0xa6cb1d8b, 0x7de29261, 0xffa4a974, 0xe8f8e516,
- 0xdbfaf250, 0xfb164b7a, 0x8fb460fe, 0xedafa51e, 0x40ac93d4, 0xeed4147c,
- 0x414c7bd4, 0x3cdb52e8, 0x1e02648a, 0xdd03d27e, 0x9121debf, 0xf820f484,
- 0xa476f55c, 0xe909e383, 0xa5e4e9c8, 0x5cfabd5b, 0x412bf4c9, 0x2bbe7527,
- 0x0afa8cca, 0xca7a87b4, 0xf6ff1b1b, 0xf14fc526, 0xcc2b0627, 0xf76ff8bf,
- 0x4e3cc245, 0x5f18ab69, 0xde34b0bf, 0xd62dfb46, 0x98cde339, 0x2fc5efb2,
- 0x6df91afe, 0x8ebf87de, 0xd93fa827, 0x38b93492, 0xdf9824cf, 0xc4efe79c,
- 0x0e25cdf9, 0x17e2bbe4, 0x9fe83b64, 0xf464b5e7, 0x45d6416b, 0x175b3441,
- 0x15d356a7, 0x4a77e74d, 0xf38044cf, 0x8b5aeca0, 0x517bd287, 0x28dafc18,
- 0x8402ffd6, 0x9d191bcf, 0xf86b45ba, 0xdf4ba2ba, 0x3cd75f9f, 0x39f404d2,
- 0x004b6a9d, 0x6892af3d, 0xd21f1c9d, 0xfcaeda45, 0xa3026161, 0x8568b10f,
- 0xa8f2a47c, 0xf943be00, 0x2c2d9d26, 0x5c8f515b, 0xbff5f74c, 0xc74ff790,
- 0xd0f405dd, 0xf5c1f153, 0xa668caf2, 0x269fd327, 0x7e5fc7e2, 0xf7ad9beb,
- 0xf5b28f35, 0xabbbd62d, 0x7fe43468, 0x1fad887b, 0x839c97a8, 0x602772e3,
- 0x243bcefe, 0xe2060794, 0xd7aeb60e, 0x56baf8e8, 0xa13e0be6, 0xb9c2d6e3,
- 0x842fcbc7, 0xf14e6f9d, 0x27dcc8f3, 0x7dbf3d68, 0x8bfa12be, 0xac4f6c0c,
- 0xfd7c79db, 0xf7cd1cdf, 0xc9febe5d, 0xcf4171f3, 0x5b73eabf, 0xeeb5ce99,
- 0xe95eb0cf, 0x605a74fa, 0x30eceabd, 0x761b33ef, 0x5d377c7d, 0xc56a6727,
- 0x4fca553a, 0xde2d3af5, 0xa7f236fc, 0xa99e9d7a, 0xe83e3b7d, 0xeded7d3a,
- 0xb0664f78, 0x2bbffa75, 0xe6fe053f, 0xa7e52b46, 0xf0a18790, 0x728796a8,
- 0xa9f105b4, 0xe7f48796, 0xc8141910, 0x04ef827f, 0x5abc95bf, 0x1dc81d7e,
- 0xbe0a5f2f, 0xe0a5f2f3, 0x957cf53b, 0x5be753f8, 0xf9472ce1, 0xf0edbec4,
- 0xcf4a64a8, 0x6ac906b2, 0x3dbd60b0, 0xd93c5300, 0x35231b70, 0xfd63927b,
- 0xae0a9761, 0xa9b79555, 0xbcaabb60, 0xa9570543, 0x5c70bbca, 0xf4bbf565,
- 0x5b81e504, 0x10f75e51, 0x3d804671, 0xad7651a1, 0xa76ca8a6, 0xeb465e63,
- 0x47486fb7, 0x12697b7d, 0xc474dbb3, 0xfc8197e9, 0x4477376a, 0x75fc5346,
- 0xb373f184, 0xca3223bd, 0xdcd32ecf, 0xf5fca320, 0xdae8c8b8, 0xaa1af620,
- 0x3cfd2249, 0x62fe5424, 0x4d90bf66, 0xef408b69, 0xa0ad91af, 0x3c5ecd0b,
- 0xcef41229, 0xe31e86f6, 0x73efd327, 0x43baa1f6, 0x903db9da, 0x49b4039e,
- 0x38b3fe94, 0xe710b63f, 0x7ce8c353, 0xa2943566, 0xa57b3e3e, 0x4d735e92,
- 0x9ccf510b, 0x1efd04fb, 0xe12fdf44, 0xaf3f14ed, 0x2b212fcc, 0x1d289f91,
- 0x297760f5, 0x77cca359, 0x2ecffb70, 0x48fde7c1, 0x87b9c53f, 0x3942d5cb,
- 0xb064fc73, 0x0995ec57, 0x836749f0, 0xdcef788c, 0x9e08b920, 0xa83d986b,
- 0x3ca07482, 0x8569f813, 0x2d0fa0f5, 0x7cb75a6f, 0x5a01e83a, 0xf1eb6ca4,
- 0xda68e7ec, 0xaf58f5ba, 0x71bf00ed, 0x0938ed24, 0x08ed3fb2, 0x64dda1b3,
- 0x00cb8447, 0x3f7c6ff4, 0xa3b401ed, 0xce30ac18, 0x67df1df6, 0x3fb4df03,
- 0x79062864, 0xecca9ed5, 0xbf1a4b23, 0xe57266cf, 0x5b57a461, 0x37e99eb4,
- 0x99fdff0d, 0x06fae704, 0xf7d82b3a, 0xf9e38477, 0x30cdf2ad, 0xbff6c117,
- 0xfd30e41f, 0xd0a9f372, 0x61f20713, 0x19bc9904, 0x704517c6, 0x07db953e,
- 0xed3175ff, 0xa76ebcbf, 0x2fcd167e, 0x6ca7eb78, 0x37db0fd8, 0x4da67d33,
- 0x5dd2b847, 0xad1e68f2, 0x61c616d7, 0x056eefe7, 0x160db77d, 0x9e423747,
- 0xab70d98e, 0x4f0c14d3, 0x5e21a53f, 0xd13f10ae, 0xfbe47a31, 0x48fc7d7f,
- 0x2bf28236, 0x609465c2, 0x767e3fde, 0x0ec1e41c, 0x98a9f203, 0xc5da99ef,
- 0x6e5c7fa8, 0xfe62fdde, 0x4ae2f85d, 0xafb92de7, 0x7ff6de64, 0xe21f7a71,
- 0x5d7aa8fb, 0xe379f204, 0x8c6f08fd, 0xaf78e2b0, 0xfeabdf90, 0x337dd1af,
- 0xe5e47ba5, 0x7fc7fde7, 0xa68779f1, 0x9ce9befb, 0xc3b066ee, 0x13f5be55,
- 0xe56aef8e, 0x537fa6dc, 0xba7a17be, 0x3890befa, 0xf0a5a225, 0x744f0e70,
- 0xd2e79e4a, 0xc388f77d, 0xd2113a79, 0xdd475048, 0xcad38f27, 0x2a4b24c3,
- 0xde132828, 0x7a071dec, 0x8aa932cb, 0x4737eca8, 0x6476d3b7, 0x940c474d,
- 0x2d0e242b, 0x217217bb, 0x3c91df1e, 0x15f9d768, 0xb4852db1, 0x9a8ed482,
- 0x3bdd6902, 0x97b42547, 0x923f2184, 0x9e3df57a, 0x0d11f516, 0x1de8019d,
- 0xce2b00a5, 0xbe9f5a77, 0x8bc20722, 0xa293d8e9, 0x313f7f2f, 0xcfccd63a,
- 0x58bd1d7d, 0xc46fd33e, 0xfbe8727d, 0x66f8e55c, 0x4ba76699, 0xf36f41dd,
- 0x8c15c71b, 0x291e0093, 0x3ca6de9e, 0x7bfaa463, 0xd1d1dc12, 0x618fecf1,
- 0x72ef2df4, 0x141b63e2, 0xe694d01b, 0xa9563f7f, 0xec193627, 0xae0d5b24,
- 0xad4fd0b5, 0x1b4ddef2, 0xa1dbcecb, 0xef13d0f1, 0x421e0453, 0x3efaabf1,
- 0x1be80665, 0x667c6103, 0x74c6f8c5, 0x29631bb1, 0xf3d47a9c, 0xd5f1a495,
- 0xd75b942f, 0x60fa073d, 0x2b7fd33d, 0xf57bb386, 0xda326d8a, 0x0c1ada0f,
- 0xb18e892e, 0xde177eb8, 0x1b56b4c7, 0x9eb7dc09, 0xab48eba6, 0x55fe04bd,
- 0x371c0df3, 0xcd67075b, 0xea86a746, 0xee5896d5, 0xb24d908f, 0x3fd31e61,
- 0xcd31173c, 0x9ede7682, 0x5e76feb1, 0xab37fdef, 0xedcf9017, 0xedef54c0,
- 0xcce2f20a, 0x65ef04fd, 0x6d23b689, 0x1cbf9642, 0x23a3ce50, 0xa9e3d186,
- 0xb4167b68, 0xf294dcd7, 0x2857b414, 0x06e9ec37, 0xcec859f8, 0xc40c2359,
- 0x64e94619, 0x56b5ef90, 0xde95c9f9, 0x9cf196bf, 0xfbc2e9fd, 0xfa6567a2,
- 0x692dedda, 0x741eecec, 0xa5bf67f3, 0x988ef4ed, 0xd3daf78a, 0x93bcec0c,
- 0xbbb87f7e, 0x6f5f5d07, 0xf81189e9, 0xeabdd74b, 0x4e70ade0, 0xabad928a,
- 0x32b17f69, 0x217c0919, 0xce1b1bc6, 0xe7be23e6, 0x0246b0bd, 0x8fbe22f9,
- 0x7fd1d258, 0xb1f54d01, 0xf8c53f8c, 0xf4741446, 0xf0f932af, 0xe7e466de,
- 0xd716b319, 0xb4c3b093, 0xec0979c1, 0xeb0e7024, 0x3db7c84b, 0x5e1f786d,
- 0x20ec4611, 0xdb35bef7, 0x7ce146ba, 0xb66f782c, 0xb7acacd0, 0x04fcd3f0,
- 0xa0571f28, 0xe91787bc, 0xc76658ac, 0x4341fb29, 0xe2767e9c, 0x0f5bad32,
- 0x1fb281f6, 0x77e9c4f4, 0x9d05fc0f, 0x5cefd3b7, 0x4f4b4f7e, 0x22cc27b4,
- 0xcc27b456, 0x9c4e1e5a, 0x3aa2e77e, 0xbd350e3e, 0x56fa71cf, 0x96896944,
- 0x2242abce, 0xdb954bf6, 0x9f764ffe, 0x23ff1eaf, 0x70e36eb0, 0x779fb87e,
- 0xab5c1a34, 0x9dcb03d3, 0xb8f6618b, 0x3dc51bf4, 0xc5cf07bf, 0x25e5b70b,
- 0x8aed2090, 0x1b07e2b4, 0xa5e1f971, 0x7983d682, 0x9230fc56, 0x6f07fab8,
- 0x66f982cf, 0x81cede05, 0x5fe81a7c, 0x4df1163f, 0xb091c44f, 0x97a95e7e,
- 0xf13d8347, 0xd19abd95, 0x678c83ab, 0x9f679f03, 0xf5f22d38, 0x5b626e8d,
- 0xa29e8415, 0xdb347c5c, 0x459f0117, 0xa8788159, 0x074cf7cb, 0x2469b87e,
- 0xefeb05b1, 0xc42f9c2f, 0x19a2ebb8, 0x18762b7e, 0xdb405ed0, 0x011455ed,
- 0x71733ddf, 0x74959b3d, 0x8d863cfb, 0x4f36eea3, 0x76d3f41a, 0x083ff72b,
- 0xe173df41, 0xe018f68e, 0x30b449c3, 0xda4187e5, 0xb7ecc92a, 0xbe94ae3e,
- 0xd6ac3f15, 0x102bd3f9, 0xae74ebef, 0xc576befe, 0x22f3643d, 0xe6def519,
- 0x95fefc83, 0x62eee3db, 0x499a4cac, 0x97b02ed5, 0x68495734, 0x41dbbbc7,
- 0xdeba22c8, 0x14b87aef, 0x97d34ded, 0x8234bebe, 0xca907f7f, 0x0912bb8d,
- 0x77a699b9, 0x09da56cf, 0xb70596a6, 0x3f7839a7, 0xfa0748d3, 0xa85f4cf9,
- 0xfb702fb2, 0xe541e383, 0x17e02ff7, 0xc60fd72a, 0x0e43bb72, 0xbd7901c9,
- 0x3d39e960, 0xf8a109a8, 0xc3ca85ba, 0x8b905a9e, 0xab5b4c46, 0x157e98cd,
- 0xf604fb6b, 0x8eb1f3a5, 0xb6ee414f, 0x52e4c87f, 0x4c73cae7, 0x418f2f9e,
- 0x2ef2c73b, 0xd78dff6c, 0xd3ea3b58, 0x3e3efe41, 0x8fc51c71, 0xeb5a2fe1,
- 0x9b878a12, 0xc0d3353c, 0x35e84525, 0x905aac8f, 0x127e8b11, 0xefc041d6,
- 0x32deafb1, 0x7133ec1a, 0x00db86af, 0x5cf22b7f, 0x62b18f78, 0xe7f41771,
- 0x0fcdd232, 0x0d8f7ae4, 0x3fb81a79, 0xb16ea1bd, 0xd76d1ba6, 0x0dd3b0dc,
- 0x35cb0efe, 0x6b3da0df, 0xf984cdf9, 0x287ef17f, 0x6919fb3e, 0x4c13f13b,
- 0x171d2f78, 0x50d44aee, 0xbd46ee38, 0x17ea0975, 0xe0a95f4c, 0x2c976834,
- 0x7e0a1c7f, 0x8264fb64, 0x16b13e7e, 0x087daf94, 0x0b92bfb3, 0x0f945f14,
- 0x8fc40c60, 0x2dab5aef, 0x92fc9f68, 0xd0fb29db, 0xce8ea1f3, 0x4f8a2be7,
- 0x6a1ecb80, 0xebe3051a, 0xabac48d8, 0xb7d89169, 0x912df292, 0xea337780,
- 0x13aba7bb, 0x16e31531, 0x6bd947fb, 0x3f41a36b, 0x9999229e, 0x43d7095f,
- 0x10121f05, 0x4c9e1456, 0x8bbf9c98, 0xa8539feb, 0xe3a30dd8, 0xd35887bd,
- 0x46dddea0, 0xf8a1a912, 0x3b50529f, 0x5299f710, 0xe7ec145d, 0xe30542a0,
- 0x8bfa5087, 0x72ea2758, 0x81af41a7, 0xc98db8f5, 0x11758a83, 0x6bbbb44e,
- 0xecffb03a, 0x7b1ebe38, 0xd22e3f31, 0xfd60d893, 0xbde8ec54, 0xa062e80a,
- 0xa5e303fc, 0x9b98ca72, 0xd19cfa83, 0x7f3fe748, 0x8a5b987b, 0xd9a7a3f4,
- 0xfa034fd6, 0x1c9484fc, 0x4a3a97f4, 0xd80447e5, 0xb8693c71, 0xeb47419e,
- 0x7d5cc306, 0x54ebdc1b, 0xfb30dc50, 0xee0ccbce, 0x2d6761c6, 0x7978d383,
- 0x777066e2, 0xdbddff51, 0xc743fec0, 0x621fcbcb, 0x1f011f70, 0x45b3e566,
- 0xce0c63f9, 0x1927f911, 0x7fb4483c, 0x1843c18a, 0xd3c9fc7c, 0x0f4139b7,
- 0x8ffae289, 0xaee783d5, 0x6b7b378a, 0xde96fdfc, 0xf3726389, 0x772b1874,
- 0x98cc9d3a, 0x08cbf400, 0x5e55fe5e, 0x02c5e85e, 0x493ea27f, 0x266f5e0c,
- 0x80bf37af, 0x64e129eb, 0x5bf31879, 0xba524675, 0xbde86eee, 0xc617ca1a,
- 0xd03a7345, 0xdaf80676, 0xed11f411, 0x244b7e89, 0xe9b497a6, 0xbbd89d98,
- 0xfdb1c66f, 0x30f3f684, 0xd293d3f6, 0x909bda15, 0x81f80fd2, 0xf39681f2,
- 0x80f81681, 0x7c6c5590, 0xc028ddb4, 0x3fa3b9b9, 0xbeedbff8, 0xfba7cb40,
- 0xcbe6adc6, 0xcddf3807, 0x81cec25f, 0x703d511d, 0xce1118bf, 0x403244f4,
- 0x380f8f39, 0x8b89de1e, 0xd2f4f362, 0x7ec24125, 0xa63c7096, 0xc84d7a78,
- 0xff79faba, 0x97e78f9e, 0xbd1fb79e, 0xd7e4326c, 0xcd9ab0df, 0xd60bd187,
- 0x85ea3447, 0x3bda2b8f, 0x3f5558bd, 0x98702e97, 0xac0f746f, 0x311848ff,
- 0xdab277e2, 0x9b3d2f5b, 0xc7a0abe9, 0x27ca2f96, 0x74ff6127, 0x85f78cde,
- 0x952a5c65, 0xe3d26f2f, 0x64ad6bfd, 0xef3cbf43, 0xe00ec73c, 0x79f334f3,
- 0x5d3cd99a, 0x87257e0a, 0x88eed23a, 0x2f63e408, 0x65edbdfe, 0x14f6f0e6,
- 0x7b582372, 0xd1422720, 0xd34bfdc5, 0x85538c45, 0x559e2f4f, 0x84f813e3,
- 0x32f58df5, 0xc6297c95, 0xf5a87af9, 0xfb33fe9d, 0xcaf563cb, 0x08e9437f,
- 0xc945a7fa, 0xe975e5d7, 0x7d327b9a, 0xae8036f5, 0xf3f3e717, 0xfdc71939,
- 0x0a485286, 0x7cce0fec, 0xfec37562, 0xfb80d9b9, 0xfd92e7fe, 0x505c5c54,
- 0xaefc20ff, 0x47b6173e, 0x1bec09e9, 0x7b40fb6a, 0x06c9b59c, 0x0967e5f7,
- 0x550edffa, 0x6fc033d9, 0x57c9b373, 0x295fb7cf, 0x4cf111e1, 0xc3b40cbf,
- 0xe68a7dd0, 0xb868300f, 0x018dd73c, 0x5c203d79, 0xf0d57705, 0xe0c8c4fd,
- 0x293b0e04, 0x2034f14c, 0x3187e459, 0x3f513af8, 0x51bf958c, 0x5f70e794,
- 0xa208fe55, 0xfdb28784, 0xb0a9e624, 0x20ff7031, 0x78d8a0f4, 0x2e43ce0b,
- 0x4be010d0, 0x80d53803, 0xc196f5be, 0xa08d7a05, 0xce94a853, 0x3dd82ab3,
- 0xf0bc6a7e, 0x977e6033, 0xbb40f2e8, 0x047615ca, 0x4761568f, 0x3a348f68,
- 0xc768aee5, 0xadf605eb, 0xf747788c, 0x32bf5a78, 0x3a7a75bc, 0xff0a1f85,
- 0x256cfd0c, 0x258fd31b, 0xa54c998b, 0x575a95e3, 0x23df41d8, 0x16a35625,
- 0x4aedc4e9, 0xe94bf770, 0xcbc77db1, 0x6eb3240f, 0xc18e30ec, 0xee54ae5c,
- 0xe3bbf1f8, 0x369fffb0, 0x7dfae159, 0xf7b3c370, 0xb838be81, 0x4c8fff61,
- 0x5fa1304f, 0x60f718ac, 0xdfa29bf0, 0x380deb73, 0x370dc1fe, 0x43f281cc,
- 0x01e86a3f, 0x84fc377c, 0x9988097b, 0x9237c6f6, 0xb91f281d, 0x25392c9f,
- 0xd5c19c41, 0x7c5e45ea, 0x7e8f43fc, 0x231f141e, 0xcc2e3e19, 0xc5b4fc05,
- 0x41e65c1d, 0x8b0a62a3, 0xe9f5e067, 0xb9fd03b9, 0x2b17493b, 0x23db5dd8,
- 0x3b6a3b58, 0x3a22d1e4, 0x787dfa3f, 0x9f811d07, 0x07e23fde, 0x3e4c1523,
- 0x29448f38, 0x926302e0, 0x39a17ca2, 0x4b7f915d, 0xfc8a0de2, 0x14fd2d5b,
- 0xc18c98f0, 0x5bb7f28a, 0xf8f014f3, 0xe5155bdc, 0x0a456c8b, 0x56bb9fb8,
- 0xdeffbe51, 0x21fe657a, 0x721d0322, 0x41775a8e, 0x1b4bf03a, 0xb507359a,
- 0x7482ed54, 0x1d0cb7f0, 0x90ec3b6a, 0xc1776a1f, 0x15876177, 0xce30f0fa,
- 0x3b2ec22f, 0xf4b93649, 0x89afedc1, 0x959e9a5a, 0x649f283c, 0xafed1d8d,
- 0x078e61c9, 0x473d29e2, 0x2814aa91, 0xb0ec0237, 0x33850894, 0xfc01fece,
- 0x32a73aad, 0x2051dc7b, 0xbbbbc80c, 0x788ed022, 0xf1b55754, 0xce43ea38,
- 0xc3a39054, 0xe62b263b, 0x8707e23d, 0x6479de62, 0xf74e8abe, 0xf342e02a,
- 0x6fe5146f, 0xc8ac5c49, 0xa8f2d5bf, 0x2b8f4e8a, 0xcfaddbe0, 0x4ab4e8aa,
- 0x1597a745, 0x1bbf82f9, 0x076c7db8, 0x3a68b5d8, 0x0054d3cc, 0xa5b9b874,
- 0xdb91e903, 0x74005354, 0x16b4721a, 0x6dc035e9, 0x3bf1002f, 0x2ed56f68,
- 0x5cf4dd48, 0x4efef503, 0xee9035cf, 0xb023e7a6, 0xcea9ed8f, 0xb56f74c0,
- 0x5bbfbf15, 0x7be98b9d, 0x3f4c36d5, 0x698d1ea8, 0xd31db553, 0x2c5aeada,
- 0x9ebab9bf, 0xf862d7d9, 0x0bf1473e, 0x38368c76, 0x9cbca253, 0x0db2f28a,
- 0x5f2850ce, 0x177066ef, 0x0c29930e, 0xebe5648e, 0xf2829a9f, 0x8cf83f74,
- 0x30bf81c4, 0xd824cf4b, 0xdd3409ec, 0x8186e70b, 0x5a89b8be, 0xe4a7688d,
- 0xb1eb9031, 0x525fbc31, 0x4296c632, 0x5ec5d2c8, 0xc18431f8, 0x2307eb28,
- 0x1bc1f8b3, 0xe21b6b61, 0xc61edfab, 0x97c6f7f2, 0x4173818c, 0xf330fae9,
- 0x29747e97, 0xc0528daf, 0xe649f595, 0x88e8fd2f, 0x7654c97e, 0xe5091492,
- 0x36c3d09f, 0x20438e48, 0x1e8dca7f, 0x1aa627f4, 0x6c2bfa30, 0x8044b16c,
- 0x85e0ea5d, 0xcf8011de, 0x672edc83, 0x3374fd23, 0xeda79a69, 0xff7d83a7,
- 0x124f4aa8, 0xef2941e9, 0x56b76853, 0xf413bd63, 0x3a6de724, 0x413ffc02,
- 0x51007662, 0xa604ddee, 0x6edfb4af, 0x21e0f3c0, 0xc60e6d8d, 0x9f024811,
- 0x149f718b, 0x11c2f7f3, 0x7489df22, 0xf9128f6b, 0xe5538e1c, 0x1d60a927,
- 0x5f19df2b, 0x05fe748d, 0x904ff9f1, 0xca7c6a0b, 0x97a66609, 0xa0a96db9,
- 0x50f808c7, 0xe41cad91, 0xdb3ca1c7, 0x83ef30f5, 0x17930376, 0xf5d708f6,
- 0x0db33768, 0xfecfd3bc, 0xc3a09d55, 0x1f00777a, 0xddc4fdc3, 0x3515ca32,
- 0x604a5ffe, 0x15f22afa, 0x0aefbb9c, 0x21cd73c7, 0x1cde290d, 0x387b5e84,
- 0x0974ce1d, 0x277df76e, 0xf9fbed81, 0x6e37cb13, 0x85cf7b81, 0xbb74d861,
- 0x93ea37bd, 0xf31255ed, 0x3aa96903, 0x560df2cb, 0x33f4128e, 0xd1bf029f,
- 0xf70d8dfc, 0xcb4c3f9d, 0xdc30b67f, 0xb9967b8a, 0x6eefe20f, 0x8c5a785e,
- 0x69bff511, 0x61f35213, 0xfdc29e1f, 0x6847a79a, 0x59bdd1e3, 0xd337a51b,
- 0xfa9b6676, 0x2418a32d, 0xf48b6373, 0x4e2e1451, 0xa41977b9, 0xd71f3d25,
- 0x595dd5c3, 0x40cb6be6, 0x22a72f0d, 0x5bca2063, 0x74d5fbcf, 0xc916335c,
- 0xe51e7616, 0xf4adb8fb, 0x045de2aa, 0xf1e21fbf, 0x78091447, 0xf1cbdede,
- 0xe5edea2d, 0xe0482af8, 0x245922f7, 0xb8aca2eb, 0x0125b8f7, 0xbda63dee,
- 0xbdc42bdf, 0xeb9f3288, 0x59eb1fbf, 0x75eba5bf, 0xb9104f2e, 0x9d812fbc,
- 0x89e90f9b, 0x9d55ee0d, 0x277db377, 0x87b9f27b, 0x67f9d206, 0xe8359837,
- 0x7ca33457, 0xb3a1d00b, 0x4751d39e, 0x4dfd61ea, 0xecfcce74, 0x96261230,
- 0x5e1fc7f8, 0x36b67f6e, 0xf7fc0b99, 0x7b1e01e7, 0x9cfeff81, 0x005351db,
- 0x8fd8b0fb, 0xbba83dc5, 0x03ef98ba, 0x77bf2855, 0x78422f57, 0xd313b54f,
- 0xf9cbd5bd, 0xf983503e, 0xc33f55ef, 0xdf1701f7, 0xf7e3d607, 0x98c9ea86,
- 0x6076a8ee, 0xbd8ba63a, 0x1df4e402, 0x47c60746, 0x81acfdbe, 0x675e7dc0,
- 0x47e30183, 0xf1788ae8, 0x538858b9, 0x58579832, 0xd495e302, 0x1f978afb,
- 0xb3fb7e54, 0x0b7ed8bb, 0x99e378fd, 0x2ebd3f40, 0x241d3f34, 0xdf390e5c,
- 0xd0743945, 0x07d6e42c, 0x7808b60c, 0xa2ad833f, 0xf72807fc, 0xbe78da0e,
- 0xed833f73, 0x601c9f3c, 0xefc043b0, 0x944ab831, 0x73dac03f, 0x063df80a,
- 0x4df288d7, 0x7831760c, 0xa21fd3ed, 0xd223cc5c, 0x056f586e, 0x2091f4c6,
- 0x79cd0b62, 0xdd9d61bb, 0x24733892, 0x826333ac, 0x56fcf905, 0x00dde2cb,
- 0xa558c98f, 0xcdba1305, 0xa861efd4, 0xa45b1f97, 0x53237a85, 0xea187dee,
- 0xb8f9ea8d, 0xe8debfd6, 0x061ed7cc, 0x9575ac78, 0x236bf416, 0xbe81c5c8,
- 0xf22c0476, 0xe2213ec5, 0xd836faf0, 0xaeca3f71, 0x247ee3b7, 0x477f9cf0,
- 0x9c3352d1, 0xb325ea03, 0x43b8e304, 0x404f06f2, 0x05c5630c, 0x1e291aba,
- 0xe13c12ea, 0x2b3ce98b, 0xf0821e01, 0xd97f8b63, 0x109dd5fd, 0xc2383f64,
- 0x2be807e5, 0x23ffb445, 0x3f835d74, 0x4bc70442, 0x88ccc365, 0x755e7899,
- 0x189e8044, 0x0490f5c3, 0x2dfe6948, 0xbfcb1d3c, 0xef6c941f, 0x30f8bc82,
- 0x03b79f81, 0x1861cde5, 0x73279507, 0xe40238d9, 0xcb9f328d, 0xdf62239b,
- 0xb2e2c01a, 0x8b0d49cb, 0x7c4cbee7, 0xb8dc405f, 0x84a71e2a, 0xa5b1eed4,
- 0x6f178b07, 0x2e2f1a0a, 0xfd031bfc, 0xb0b9f96d, 0x93cf930b, 0xc3d17641,
- 0xb9686760, 0xab971dfb, 0xcca0f0a1, 0xe0e285ff, 0xf90e2389, 0xbc3c5423,
- 0xf9c08be0, 0xb6f3b0d5, 0xea9fe196, 0x81c4c69f, 0x8823bf20, 0x6794ab1c,
- 0xcf212f87, 0x97f1f2d4, 0x6693bb92, 0xfdc1a794, 0x98b91043, 0xcb54e30a,
- 0xc93e6745, 0x7505fb80, 0x0a68f42a, 0xd3de213b, 0xed0c23b9, 0x8e31f514,
- 0x0fd0448c, 0x83be3bf3, 0xeb122d78, 0x371c3c41, 0xf6846e39, 0xbff33d25,
- 0x2dcdf110, 0x753f7d5e, 0x7923c62c, 0xfb0a7bf5, 0x9efdf7e9, 0xf20b1d49,
- 0xdec9bbad, 0x1921da1f, 0xc85d1fcc, 0xbef1508f, 0x3ed91343, 0xff92981f,
- 0x8e5838b7, 0xae7a369f, 0xf4e74dda, 0x62bf86ce, 0x57d9ccdc, 0x56c1c79a,
- 0x265dba5c, 0xb68f8a46, 0x0dc4110d, 0xe52d1be7, 0xd4969a3f, 0x2b8c36c9,
- 0x4d07bad2, 0x5bd7f08c, 0xe974ff98, 0xcadc08a6, 0x5c1b364b, 0x92fd6963,
- 0xd1b327ad, 0x0ea1f5af, 0xbe730fbc, 0x22d75922, 0x13d93cfa, 0x1b594fc1,
- 0x353e4edc, 0xad87e991, 0x8327c2db, 0xbf5a56bd, 0x25deed13, 0x707493b5,
- 0x4dca2a0f, 0x3e21d44c, 0xa7b43968, 0xb8965f3b, 0xe41eeb1e, 0xfc2caf7f,
- 0x665f5bb7, 0x7a92a976, 0xc60c2b9d, 0x36b5feb7, 0x3929c788, 0x4dfb406a,
- 0xf46ffae5, 0x4d82c740, 0x1f01231b, 0xd932f595, 0x550fbcad, 0x97ac41c6,
- 0xe3f006dd, 0x7f472baf, 0x23370a6e, 0x1e3c1b5c, 0xfafe72e8, 0xb71a9ba5,
- 0x4b0a293a, 0x12297f5f, 0x374e29e2, 0xbc048dad, 0x192f76d3, 0xf7101487,
- 0x25e8fb50, 0x134e1ee3, 0x134b03c6, 0xeb237155, 0xcb71b863, 0x3fdfc83d,
- 0x274787c9, 0xf3c6f3a3, 0x5e5c422f, 0x2f33e6eb, 0xfecb78c2, 0xf045ee79,
- 0xc23b26cf, 0xad0f60cc, 0xc630e57c, 0x7f7a8935, 0x627a6449, 0xe12fcbdb,
- 0x31db6a3d, 0x35b7afa6, 0x6dbe429e, 0x78c7ed7b, 0xd85af388, 0x0efe8858,
- 0x2414b70b, 0x02e72090, 0xbadf0291, 0x4d1e20ae, 0x755daf4d, 0xfc8fd0bb,
- 0xe837a52c, 0x9638dea1, 0x171672da, 0x2bf1e164, 0xfdc7821b, 0xd4abc405,
- 0x1c3f1c4d, 0x3a75e2ec, 0x415c85ab, 0x4a21cadc, 0x4057bec7, 0x728f0dbf,
- 0xf4e0fe7f, 0x50bf0b3b, 0x2a26353a, 0xd7ce56e3, 0x9fcbf9cd, 0x262eaf21,
- 0xfb8adc64, 0xe226f00a, 0xda24570a, 0x6c3c82f6, 0xc62afcdd, 0xc6dd0109,
- 0x6db689d2, 0xf1069f3c, 0x8eba2d98, 0xc1efdce9, 0x25acf70c, 0xfd70478d,
- 0x10f96db4, 0x8f08f6e3, 0xde236bef, 0x258f161f, 0x89ae79f1, 0x1c2ef160,
- 0x030f10ff, 0x3bf4d0f7, 0x7c617b8f, 0x4261e22c, 0x4c5cc1c5, 0x2df6ceec,
- 0xbe58ef1e, 0x2b8f38e6, 0xca4bd1f1, 0x5f353a05, 0xe048be32, 0xb8780cc1,
- 0x2bae3fc9, 0x3791bc78, 0x0bd38ffe, 0x5cf107e8, 0x0a2db8de, 0x3a58430f,
- 0x83c88242, 0x1e2c55b6, 0xe3ff7d4c, 0x3843cfa3, 0xd152ffaf, 0xf433cc59,
- 0xd3ad9239, 0x6aff8dcb, 0xd12673f1, 0x127388a2, 0x10bd6a78, 0x26a78e5c,
- 0x67eafdb1, 0x00b6b7eb, 0x092536fd, 0x66badbf4, 0xe62b7e85, 0x05754adb,
- 0xafadef90, 0x960c77b0, 0x3942eed5, 0x141796ae, 0xf760b62f, 0x98937d0d,
- 0x67a8aa9c, 0xe6eb44fb, 0xb6899708, 0x6df7fad3, 0x1b15cfc8, 0x8fb0f59a,
- 0xbaff59ef, 0xb317f99e, 0x84fb03f5, 0xadfc6fcb, 0x8d99db7f, 0x09fa1b72,
- 0xbce1d742, 0xe086ca9f, 0xf86e54fd, 0xa94fd146, 0xfccf56b3, 0xdfdd2e8d,
- 0x126dad69, 0x49ba77b4, 0x7269a607, 0x6df996ba, 0x24b7fba9, 0x4abdf8e9,
- 0xa8f7d70d, 0xc83f47bc, 0x9c271e61, 0x51c3735b, 0xc5e6b63e, 0x35a45da3,
- 0x6965af55, 0x7fff842f, 0x935bfbdb, 0xbfac8d72, 0x371f1851, 0xd6e8c62e,
- 0x8073f5d0, 0xaf513fbf, 0x00fff677, 0x8707cfee, 0x78e3dfa1, 0x4dbefcc9,
- 0x6827bc0a, 0xdf3537dd, 0x5f781d92, 0x91912ad0, 0x65279512, 0xf0a59acd,
- 0x0fef6aed, 0x477d16ca, 0xa19d1de0, 0x78102e8b, 0xefeae7df, 0xb3a29a13,
- 0x70b7602d, 0xfa6d812c, 0x829ad6a6, 0x597216ae, 0x0edcef3f, 0x67b012d7,
- 0xdec0b88c, 0xba4a18b7, 0x4daae158, 0xfccfddca, 0xbeaa79be, 0x31ae9877,
- 0x83ddf4b9, 0xe7909fbc, 0xdc82481e, 0x867b8837, 0x8ac730e4, 0xf71081a4,
- 0xc01beecf, 0xe4f915f3, 0x3fa6c7b7, 0x3081e780, 0xe71573f4, 0x27f58d99,
- 0x9fac60e3, 0xb93dc537, 0x34af7e9d, 0x79f8877f, 0x8f9f8932, 0xf28ac4ac,
- 0xf50f7e4b, 0xfb25cff8, 0xfb8a49b3, 0x08b9ef58, 0x63efabbf, 0x8cee7f85,
- 0xec276597, 0x0dbf85a3, 0xc608781b, 0x03961751, 0xc31fd8e3, 0x980641fd,
- 0xf1401f6f, 0xf5cb7673, 0x5b3fe039, 0x9eefb5e4, 0x88bcbd47, 0x338963db,
- 0xafd876f3, 0xd7bd848a, 0xdcf961e9, 0xd9febbde, 0x3ac3b7de, 0xa1c1fe14,
- 0xa2c56de4, 0x421f9137, 0xda12cbe6, 0xa6e4c939, 0xbd3f22b4, 0x072e4df9,
- 0x397efdc4, 0xa78b0bf7, 0xf68dc8d3, 0xbc5791f9, 0xba46e611, 0xcec4d97e,
- 0xe976dbc5, 0x09af1d99, 0xa78f21cf, 0x7c02de3a, 0x81da2c55, 0x762626f8,
- 0x6c96396e, 0x1d31fee6, 0x0eae5099, 0x6eb027ce, 0x7da184b6, 0xd1eb4136,
- 0x2ab8e95b, 0x8bf4128e, 0x33c7c638, 0xd40be9a8, 0x70e6bff7, 0x37e67ad7,
- 0xd7c3c6a1, 0xf1aa1149, 0xc60c37bf, 0x2231f02f, 0xfdc2d49c, 0x958f9d30,
- 0x98aac7cf, 0x814fd78f, 0x6ff74bd6, 0xebf0a2d7, 0x5b2af312, 0xdffc49d4,
- 0x1c5d6ad3, 0xe311df7c, 0x97dbdf56, 0x840f7698, 0x2ae4a37d, 0x02a7fafd,
- 0x3e01c46f, 0x871eaa59, 0x7ee32d3a, 0x17efea1d, 0xf67dc492, 0x7fae3b2f,
- 0x69bd7bb7, 0xf9153b55, 0xbbed1633, 0x713f7ba2, 0x75bff71f, 0xdeea17ff,
- 0xf66ec1ef, 0x8e946ecc, 0x29fcdfe3, 0x9df108f3, 0x1105eddb, 0xbe51c718,
- 0xc8156135, 0x7e470fe5, 0xc2f60f14, 0xf71231fd, 0x1cb4bde7, 0xf7bb52b9,
- 0x717bd567, 0x393f625c, 0x5846ed51, 0x3a9f076d, 0xa7bc31e2, 0xdb2dfc1e,
- 0xb05e8637, 0xf2c9b91d, 0xc231edf3, 0x32ec230e, 0xd4cf3b6a, 0xefe4666e,
- 0xec29bfe9, 0x9417fcca, 0xac472e7c, 0xffdc83d1, 0x17ee7cb9, 0xd65d3347,
- 0xe2877b40, 0xce89bda1, 0xb0475ee6, 0xc23de51d, 0x7b8e2e98, 0x73134e80,
- 0x88863f99, 0x5b942a5b, 0x7a049c9f, 0xfb8c934e, 0x7ddfc2d7, 0x2ce7b7f4,
- 0x34a8f481, 0x131ca277, 0x5eeb1774, 0x86a543f0, 0x14e7b1f9, 0x097fd058,
- 0x57d811e4, 0x0d34746b, 0x299ee742, 0x3c600bf9, 0x0e3afded, 0x8abf024f,
- 0x669dff2d, 0x09aebd41, 0xb39779cf, 0xbffd80df, 0xd73b105b, 0xe8393cb2,
- 0x298977fb, 0x6aceff4c, 0xbbfbb0d6, 0x7aeb92f9, 0x347973b0, 0x39acaa88,
- 0xe0192ee9, 0x559f963a, 0x2892e51e, 0x8c38359c, 0x851bdfe5, 0x88d3df71,
- 0xf3fb0747, 0xa60af00c, 0xc1624ce9, 0xf1b11674, 0xba3ae5f7, 0x9cfeb44b,
- 0x83f32306, 0x309e9e25, 0xfa10ec9f, 0xcc6eceef, 0x3bb7d3be, 0xf37ddf93,
- 0x19fc7295, 0x726eff9e, 0xef9849fe, 0x67b66ee9, 0xdd1bed21, 0x704fe2b4,
- 0x21a2dcde, 0x1a9df7a0, 0x9bb41bfc, 0x24df7a8a, 0x8dd8bfe7, 0x3124dbd6,
- 0x23674aff, 0x1d22a78f, 0xb6f6fef1, 0xd60b93d7, 0x02af7b40, 0xae3c815f,
- 0x29be462d, 0x935c3332, 0x457cec91, 0xca5da5eb, 0xf857d20e, 0x5c87c2f7,
- 0x86e117ec, 0xfdba4f3f, 0xbeef3a61, 0x073dfa1a, 0x02d8e5c6, 0xf74beae3,
- 0xff8c1373, 0x40a71e05, 0xdee0d2aa, 0x068bde6c, 0xc79bec0d, 0xbf03bca8,
- 0xa7e0e3eb, 0xb94fd34d, 0xdce7f63f, 0xfc19bb1f, 0x927a69ba, 0xe7482dca,
- 0x842560fc, 0x64c8e7f2, 0x95f2235b, 0x883bf82e, 0x21e726ef, 0xb4ebb31e,
- 0xd7678fb8, 0xfae7227b, 0x377f65d1, 0xb59a1f16, 0x5848cbe5, 0xef666d4f,
- 0xed126cbc, 0x73b71c6a, 0x0736efee, 0xb26ef5e7, 0xe7cc24ed, 0x01c764f5,
- 0xa3feb76c, 0x753f04ff, 0x7fde3eda, 0x4f1d4bb4, 0xf102950d, 0xa37f9dea,
- 0xe39fcd9e, 0xd3545379, 0x69bfa80a, 0x2cc0774b, 0x2c7ee2c9, 0x0527e804,
- 0xe7b33fc3, 0x0c74378d, 0xf8d17380, 0xff50728b, 0x3fef3131, 0xf38b3a0a,
- 0x286ba70e, 0xcf9287ba, 0x80cc78de, 0x442e1377, 0xe22f5c82, 0xbafa9376,
- 0x6fd0079e, 0xe04caf7f, 0x27ca23dd, 0x498efe0a, 0x48807a66, 0xf8f51ab3,
- 0xc6a6cf5e, 0x36ce7aaf, 0xce7a1d21, 0xe4e5e5a1, 0x507a15eb, 0xff1fe0d6,
- 0x2c58a7fc, 0x92412f0f, 0x42aac8bb, 0x629af7b8, 0x4c36f9dc, 0xb9b99a61,
- 0x66bdee10, 0x207b4a24, 0x1f49699d, 0xe25df705, 0x232b38dc, 0xecb00f6f,
- 0xca116b58, 0xc4583ce1, 0x814bfb7e, 0x1eee1c31, 0x39a170bc, 0x92df0146,
- 0x7f28ac98, 0x2287a5ab, 0x8dc64c7f, 0x9faf7c8a, 0xefbfb5bc, 0x47c0777b,
- 0xc3b07747, 0x9ca079d3, 0xb4656b21, 0x396d66db, 0x148ddb74, 0x4eeeb71e,
- 0x9b036c2b, 0xcdb8fe78, 0x4fd82e05, 0xb00a5de1, 0x3ee4b463, 0xa09fd4fa,
- 0x5f7b2d31, 0x74611e63, 0xebfc6b28, 0x799b6028, 0x3da1e6c3, 0x8c9de036,
- 0xd5dfc135, 0x52c1f610, 0x65e9ecc2, 0xbbf6d41b, 0x550ecc95, 0xe54faca7,
- 0x3c827fd1, 0x0ef5bbea, 0x6e97f833, 0x3763fc1a, 0x64d6e790, 0x284bbc65,
- 0xbff2f17e, 0x1fe03964, 0x17e6a1e7, 0xe9120761, 0x6e2c83b8, 0xc5e56ae1,
- 0xf85e403f, 0xe57917c5, 0x31fb9e98, 0xc41278f1, 0x3f1f0f47, 0x628e4b4f,
- 0x5aaf67e5, 0xd0b8ef0a, 0x13c4277c, 0x4b9db291, 0x85efaec1, 0xf32b3617,
- 0x2996941f, 0x95d387e0, 0x65bccaf0, 0xad43f5fe, 0x66fa8abb, 0xefca83bd,
- 0x39d8278a, 0x639f7024, 0x992ee8eb, 0x6fdb0554, 0x4a31fe44, 0x7853f40b,
- 0xc70bed83, 0xfef47aba, 0xc96527fe, 0xbb3b4f4c, 0x7ddff1ed, 0x6de27607,
- 0xce46fd04, 0x5cfb3146, 0x8d29dd76, 0x177ae406, 0xb36caf86, 0xec7e0347,
- 0x4ee1c5ed, 0x9cac83f0, 0x24fe811f, 0x866ce17d, 0xbfedc9e7, 0x7843d1b7,
- 0xbf09efe5, 0x03ff0f57, 0xd13f379c, 0x46fb1468, 0xff9589bb, 0x6cede48f,
- 0xeb67c8df, 0x83d03a63, 0x974261cb, 0xe252e566, 0xeeb0cb95, 0xbf003e60,
- 0xf78edcf6, 0xd37b009f, 0x5a3eb63e, 0x29e3fb89, 0x4cd8bfb8, 0x95a3ebfe,
- 0x7e77b2d4, 0x427dec2d, 0x7218bf71, 0xd1aeecbd, 0xbf8dfbc3, 0x2279baf4,
- 0x843bdf99, 0xc7071f5e, 0xdca93e50, 0x3b1afcc6, 0x4aefae1b, 0x804bd6fc,
- 0x068cf69e, 0x6dc05af9, 0x3bfdfc0d, 0xd8a17c55, 0x17b58837, 0xf78b13fa,
- 0x3ae80f3e, 0x541fa026, 0xc6fd16a3, 0x092ce816, 0x6fea9751, 0xfc5886b9,
- 0x68dbebfa, 0xe62df940, 0x73666ed1, 0x3e78dbed, 0x8171de1a, 0xc3ea3174,
- 0x87fd8a35, 0x58ba73ee, 0xec455810, 0x6370ec5e, 0xe1d03e42, 0x199c44b0,
- 0x309a9839, 0x35fb9bce, 0x27fc244d, 0xffeb4331, 0x6fd0b6ae, 0xf3bc6cef,
- 0x3e87d07a, 0xcee7bbae, 0x24fbf401, 0xe29b9778, 0xfb7740f7, 0x81df9834,
- 0x73f4255f, 0xfa91fc2a, 0x77f7acfc, 0xf307e50b, 0x65dd80c6, 0xfe83312a,
- 0xfa665e3c, 0xad8b7916, 0x2a37212b, 0xe868a6a5, 0x09e4f5ff, 0xbce99287,
- 0x01fd1613, 0x3df569f5, 0x5bea95f3, 0x26b0f285, 0xebede81b, 0x6e7f1625,
- 0x31577c65, 0x9393ccec, 0x7d508e40, 0xf28ff41e, 0x1ef89dfa, 0xe6dcfa81,
- 0xe7d5abd5, 0xf38dabef, 0xedcbd00f, 0x7071c96d, 0x7877388e, 0xcfd40912,
- 0xcd56f27d, 0x021f5477, 0xdc36b479, 0xa6aef8c5, 0x6fce94ad, 0xb364dac1,
- 0xf6e78a13, 0xa2d6f162, 0xdba7f0fc, 0xcbf3437e, 0x83370a5e, 0x9d30bdda,
- 0x818de138, 0xa37aab85, 0xdeafbbbd, 0xd006eaf2, 0xa1d65eaf, 0xe06bf45d,
- 0xbd7f0a1d, 0xd81706f9, 0x2c69e783, 0x8cf7847f, 0xf9193ac9, 0x060bd4ed,
- 0x1fe75fdc, 0x2bfb81e9, 0xa50b23ac, 0x4254a9cf, 0xfcdeb4cc, 0x5db193d7,
- 0xaf7625f9, 0x02537f3b, 0xfa0aa1c6, 0x8610bcb6, 0xd9c591f1, 0xf4dcbdb5,
- 0x47449edb, 0xbc1c4a54, 0x975ae7ff, 0xf054f144, 0xc01f4fd2, 0x537f36be,
- 0x47cbd21c, 0x61fbe0e7, 0xb60f4367, 0x84be39ce, 0xef05fedc, 0x0653120f,
- 0x87895f82, 0xeece77bf, 0x7db8720f, 0xd977cd4e, 0x7e32ffbc, 0xd840c3ce,
- 0x67cff058, 0xdca24cf1, 0x628d14a8, 0x4f942d3f, 0x3e076c54, 0xf9e037ad,
- 0xb82c35b2, 0x0a486a9d, 0x8c2b57db, 0x49ec2adf, 0x507e8b15, 0x322b13d8,
- 0xe7bbde09, 0xbff4b12c, 0x71f7a697, 0xd9c4a7fc, 0x4a7cc387, 0xfadf1f6a,
- 0xf9f1e21e, 0x7e813ffb, 0x3bd89af7, 0x7c31ef6f, 0x6f02ff0b, 0xbe0ec67b,
- 0xf429570e, 0x476db6cb, 0x7f781db2, 0x382bfc77, 0x3c6d9f0f, 0x25a654f2,
- 0xc7cc7ec8, 0x658cec2b, 0x60fede30, 0x4b8db487, 0xb473b3f1, 0x5efc1d7f,
- 0xeeaff44b, 0x53646cf7, 0xb6dbbc36, 0x07698200, 0x46cff2fa, 0x3ec36537,
- 0x4437fc2b, 0x14cccedc, 0x4a947fee, 0xfbc44352, 0x0b8949cc, 0xdf83ef1a,
- 0xe7de3aaf, 0x19f78b3c, 0x7de333fe, 0x0c9f393a, 0xef1e0988, 0x5fcf04f2,
- 0x43d96a42, 0x43ee5c72, 0x077f0dd8, 0x67bc5658, 0x8899e5c9, 0xc0da18f3,
- 0xb943ffec, 0x6364ab1f, 0x88432e71, 0x7aa7b59b, 0xe5640597, 0x89119054,
- 0x113ae237, 0xc606fdef, 0x7be13425, 0x0e9337cd, 0xacc46d4c, 0x1ba29485,
- 0x8ec491d3, 0x855228e9, 0x835268e9, 0x16a46de9, 0x09a4b1d3, 0x8dc7d253,
- 0xff78c7ef, 0xf3adc67e, 0x0cffb034, 0x6f5c1498, 0xbfaf837b, 0x5243e04b,
- 0x9578afbc, 0xd84518f8, 0xf121c5fb, 0x7e819292, 0xea2f0258, 0x9c31bfbf,
- 0x119db078, 0x80f651b0, 0xef0594f3, 0x0d880a4f, 0xc42bc2e1, 0xa1c7ae47,
- 0x2532f665, 0xe0e9025e, 0x1bd4854c, 0x19ee4607, 0x2b038ca7, 0x5e718719,
- 0x5cec39fd, 0xe26ff2c0, 0xb1f79de5, 0x2824507c, 0x82ca45fc, 0x5c71fe71,
- 0xef190f72, 0xb187261d, 0x6ef17ab8, 0x4230e4c9, 0xb5bf809a, 0xcf9438ce,
- 0xde297a8b, 0x392530f3, 0x355ca00e, 0x142d23ba, 0x16670b7f, 0xb1c6ffa2,
- 0xdb8dcb38, 0x7e3c5f25, 0xd75b0a4b, 0xc4aaa547, 0x8f1e743e, 0x77dfa7e4,
- 0xbfafba7f, 0x04e7e82b, 0x3f755bac, 0x3c3ac46f, 0xf6313fd0, 0x2cfcf3c2,
- 0xde6cafbe, 0xaadb343c, 0xaccd7e81, 0xdd67dfdf, 0x32cd3f77, 0x424edaa7,
- 0x821496f9, 0x5da44deb, 0xf02dece2, 0x893bc45d, 0xbf33edef, 0xbe26eadf,
- 0x531faa38, 0x5ca1671c, 0xd693c6a5, 0x571d0e5f, 0x5c46c4b6, 0x655be47a,
- 0x2e3a993c, 0x3df7b68b, 0xee52abcc, 0xd3fc0b98, 0xfe91f516, 0xcaefea2c,
- 0x1dc6acb8, 0x687114fb, 0xe3781d62, 0x1c593ad0, 0x438850da, 0xbff1f48b,
- 0x7c134388, 0x10c3d62c, 0x72c34388, 0xf281cc37, 0x813a3fc3, 0x4e236871,
- 0xda1c7878, 0x9a1c6511, 0x159ffbed, 0xb1de2687, 0xbd85b058, 0xdb80bfa7,
- 0xfd060077, 0x5f7894e2, 0xc4579f86, 0xdf7ca4b9, 0xdf9eecdb, 0x041bff49,
- 0xa7ec907e, 0xe859f9f8, 0x0fe0122f, 0x0cb5c279, 0x0fe01dc6, 0x09aff2a9,
- 0x568277fd, 0xe9fbf506, 0x2bcfca93, 0x5c219f7c, 0xcbc7997f, 0xaec0fcc0,
- 0x8f51a0b5, 0x1782d1fa, 0xfe82b3ee, 0x64d520b4, 0xf2b77945, 0x514be43e,
- 0xfccf3c9e, 0x9b7ac473, 0xdea09cbf, 0xac4f3de5, 0xeff0d833, 0x404bac23,
- 0x3e7bcafd, 0x0814f6e7, 0xebfb84d3, 0xdd1d514d, 0x536ddee1, 0xf4158663,
- 0x5b220fbb, 0x71b14256, 0x5e9f0ce1, 0x0e98797d, 0x9603aff5, 0x74888298,
- 0xf3b13adf, 0xf99e4275, 0x3af98335, 0x7bb136b3, 0xf6a39c85, 0xdc0b4882,
- 0x84fbb02b, 0xefc12d41, 0x4ae7c7a9, 0xc08a7b8a, 0xcb16c9f7, 0x7fb8255d,
- 0x6a10f760, 0xbfb8bd3b, 0x2985b22e, 0xdd423fee, 0x0ef38b67, 0x1e89efdd,
- 0x118d7bf6, 0xc48337fd, 0xf7233dd3, 0xf663bdf0, 0xf3c0e48e, 0xa6c61dd0,
- 0x4fabe034, 0x53731c63, 0xcb6e20e3, 0xce39416a, 0xf17ceae3, 0xbca06f40,
- 0x073ef114, 0x20e32da5, 0x54deea1e, 0xa3d40547, 0x067b30d3, 0x9947def9,
- 0xc5f27b99, 0xa7682dd7, 0xb7f54caf, 0x3bbff3d3, 0x1e2f5ea2, 0x59e3058d,
- 0x5095bf9c, 0x8d0338af, 0x15f3c60c, 0x8a674ff2, 0xdbf98729, 0x4adefeaa,
- 0xdfe5576c, 0xf167a95b, 0xad89a50d, 0x59b3af4c, 0xfa6e2cad, 0x959dfde7,
- 0x9553ddcb, 0xf428b626, 0xe621b255, 0xbea6ec8a, 0xfdae5df9, 0x5a7f6c36,
- 0x7e0a87d5, 0x98e8b198, 0x3a66cf82, 0xb5f9959b, 0xaf7838d2, 0x1567d28c,
- 0x35b3c7d0, 0x0b14d469, 0xf01801f8, 0xf7cbbf5d, 0x77f11a7b, 0xcf09baa2,
- 0x9f5e628b, 0xd8451f55, 0xc651ed53, 0xa979f067, 0x704f8bfd, 0xdc1399bf,
- 0xf704e66f, 0xfdc1399b, 0xbf704e5a, 0x7c87e116, 0x4c8aa242, 0xe47f5074,
- 0x828f8137, 0xc23723f8, 0xc8fe90f7, 0x0a71c7e4, 0xb7e7647f, 0xe47f0b08,
- 0x91e7a95d, 0xec9bbb8f, 0xc43b436f, 0x9ffbd1e6, 0x23f943bb, 0xeeca9fbf,
- 0xa5503e93, 0x22f3d29f, 0xb4f1a9fa, 0x0bd95e50, 0x37ac59df, 0xcb879010,
- 0xf1a6d924, 0xb0f18fbf, 0x16ce5377, 0x1dfc28a5, 0x8b7f962a, 0x0f7e17f8,
- 0xd0196f39, 0xdf7ca04f, 0xd7405ec1, 0xe71d53c7, 0x1dfd9952, 0xab2e87df,
- 0x5fbfb033, 0xbf21cfc7, 0xebf139e0, 0x718181d4, 0x77e6a114, 0x53d34e76,
- 0xe55e7499, 0xef153b91, 0x8af18b22, 0xfa718979, 0x5f8cb9da, 0xc50ef2c9,
- 0xf6db6b3a, 0x63e02f48, 0x9c167ef1, 0xa904275b, 0xe8c69f1f, 0x5287cf42,
- 0xa4bfed1a, 0x7d0f9d8a, 0xffb9adf4, 0x3ec7a013, 0x509dca13, 0x2cf3d5f5,
- 0xf10fb1df, 0xd2173ea1, 0x0b4d7679, 0x3b9fcf32, 0x6bf5abbf, 0x4e217437,
- 0x715097e0, 0x9b250751, 0x2d77c605, 0x4b5e96bd, 0xd2d7a5af, 0xf4b5e96b,
- 0xbd2d7a5a, 0xaf4b5e96, 0x6bd2d7a5, 0xf4e5ffe9, 0xfffd007f, 0x8000c102,
- 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
- 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
- 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
- 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
- 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
- 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
- 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
- 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
- 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
- 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
- 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
- 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
- 0x00008000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0x00002000, 0x000040c0, 0x00006180,
- 0x00008240, 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600,
- 0x000146c0, 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80,
- 0x00020b40, 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00,
- 0x0002cfc0, 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380,
- 0x00039440, 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800,
- 0x000458c0, 0x00047980, 0x00049a40, 0x00008000, 0x00010300, 0x00018600,
- 0x00020900, 0x00028c00, 0x00030f00, 0x00039200, 0x00041500, 0x00049800,
- 0x00051b00, 0x00059e00, 0x00062100, 0x0006a400, 0x00072700, 0x0007aa00,
- 0x00082d00, 0x0008b000, 0x00093300, 0x0009b600, 0x000a3900, 0x000abc00,
- 0x000b3f00, 0x000bc200, 0x000c4500, 0x000cc800, 0x000d4b00, 0x000dce00,
- 0x000e5100, 0x000ed400, 0x000f5700, 0x000fda00, 0x00105d00, 0x00000028,
- 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0xffffffff, 0x40000000,
+ 0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
+ 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0,
+ 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540,
+ 0x00012600, 0x000146c0, 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0,
+ 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40,
+ 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140, 0x00033200, 0x000352c0,
+ 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740,
+ 0x00043800, 0x000458c0, 0x00047980, 0x00049a40, 0x00008000, 0x00010380,
+ 0x00018700, 0x00020a80, 0x00028e00, 0x00031180, 0x00039500, 0x00041880,
+ 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80,
+ 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280,
+ 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780,
+ 0x000ddb00, 0x00001900, 0x00000028, 0x00000000, 0x00100000, 0x00000000,
+ 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
+ 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x65e21f09,
- 0x63e62860, 0x88237860, 0xcc2b4e2a, 0xfe9942ce, 0x0c0cccf3, 0x32f88117,
- 0xe2055f10, 0xe9a48cd3, 0xb045e2b7, 0x30327377, 0x7df90358, 0x9b8b5a40,
- 0xc8014181, 0xb3e201b6, 0x204bfe40, 0xadc40afe, 0xdc0c0c3c, 0x6a0c0c5c,
- 0xc4042c40, 0xcdf8bcb6, 0xff2023b7, 0xaf951b9f, 0x17ca83cd, 0x3fafc6e6,
- 0x7cbf0789, 0x6c790106, 0xf928b3f8, 0x4620e1f1, 0x2d43749f, 0xca86aeac,
- 0x6065522f, 0xe7c40df8, 0x681ae2a1, 0x10aac5f2, 0x03329cfa, 0x7e1ab243,
- 0xc80853b3, 0x000c060f, 0x4022bae9, 0x00000400, 0x00088b1f, 0x00000000,
- 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x27bcce66, 0x20212793, 0xf0841e4c,
- 0x04242074, 0x11093a8c, 0x5076c403, 0xc2ab16fe, 0x25786784, 0x5ae5a911,
- 0xc0133bff, 0x51b91688, 0x7e2da5a8, 0x68bc104e, 0x01226f69, 0x903a4483,
- 0xbd08a5c0, 0x168b6ad1, 0xe088786d, 0x7e929205, 0xcfe956de, 0xe7dad6bf,
- 0x9939cccc, 0x77e8f881, 0xbf41ffbf, 0xdecfb3ba, 0xd7b5ef67, 0xcfb5ef5e,
- 0x30733d1e, 0xd7632776, 0x73941ff1, 0x4158c645, 0xf81d0ca4, 0x614b3ce2,
- 0xc18b72ec, 0x6c64cc65, 0xe8431eca, 0x68afa84e, 0xd7588214, 0x3633301d,
- 0x5b2bb181, 0xec46bd79, 0xb41b78dc, 0xb645d7b3, 0xd3b60a03, 0x8c8563a6,
- 0xfe31379d, 0xb1d76f4f, 0x9916c634, 0xe3457579, 0x7e3839c1, 0x9991ab55,
- 0x2df3fde1, 0x2beb07a2, 0x26410877, 0x27befb40, 0x7f180ca5, 0x32685071,
- 0xe3bea0bb, 0x6765c959, 0x2f81cd6c, 0x0abce0ae, 0x4dfa9f5c, 0x7c2125cc,
- 0x8d75a5ef, 0xb0696c66, 0x8c066a79, 0xe09774b3, 0x4b3cc1d6, 0x3ba10ab7,
- 0x2173e027, 0xcbb8c228, 0x2b995a76, 0x9d70c38f, 0x8eb4bcd1, 0xbcc02f95,
- 0x83670899, 0xe647b5e4, 0xa9f3f053, 0x72b981bf, 0xaf15f523, 0x5ef03cc0,
- 0x3704aff5, 0xc75ab12e, 0xff304d7c, 0xd9e67d95, 0x7d70d92f, 0x3dae5275,
- 0x7b951d7a, 0x834b1d71, 0x1b54d28d, 0x2d28d5c2, 0x6f191d1a, 0xcc4dced9,
- 0x6b828a65, 0x5f00f64b, 0xfcb6bb54, 0xf054cfd4, 0xd3cc652c, 0x83f84364,
- 0x9131ccd2, 0x22422de7, 0xbe38a963, 0xb19f1aa8, 0x99173d00, 0x6778843b,
- 0xf477766d, 0xaa755dbe, 0xa2656df7, 0x781c6efc, 0x87de45fe, 0x2a4efd67,
- 0xa9d3f937, 0x45dfb1fc, 0x9fc4fe70, 0xfd4fe547, 0x73fe7a6e, 0x2f95117f,
- 0xbe543df8, 0xb2a72fe8, 0x7ea5efd1, 0x5367f92f, 0xa3efc3b9, 0xafeaffe7,
- 0x7f15f2a2, 0x85ff3d2d, 0xbf95357f, 0xf9e807f4, 0x53d7f9bf, 0x04fb8cd9,
- 0x16ff6ee5, 0x83f8f72a, 0xff75efd4, 0xf9f72a4e, 0x33f9e89b, 0x13283f88,
- 0x3d3ace3c, 0x19424fec, 0xb0790273, 0xceb7af64, 0x59e4f500, 0xd7c03ebc,
- 0x7e012750, 0x3a802c06, 0xdaa0dfec, 0xb4233ace, 0xdbc55a0f, 0x6b9c0687,
- 0x743ed04c, 0x6ecf6f1d, 0x4331aef0, 0xde66f67b, 0xb0d83c3e, 0xc3ed02c6,
- 0x51f6f3b7, 0xac6b9d4d, 0x85aa3ed0, 0x721adfb7, 0xfd41b5ae, 0xcf5e0ed6,
- 0xb5aef4ef, 0x5dff3d43, 0xd5d89f5e, 0xef01d6b0, 0xdfc73c4f, 0xd9bde2d7,
- 0x60cf9ce0, 0xee0736af, 0x4207e8f2, 0xc23e725d, 0x1cbd8cdc, 0x77d516f8,
- 0xded4dc1b, 0x47aef81a, 0x92ea093f, 0x058fda9b, 0xc7bed47c, 0x53f6a5e0,
- 0xbed42581, 0xfb52f247, 0x6a4ac095, 0x4b50dd7f, 0x87eeaced, 0x54bafed4,
- 0x7549ed4b, 0xcfbea8eb, 0x8c196d00, 0xe33dd4e5, 0xcdfd0009, 0x511b7c11,
- 0x6aeb747e, 0x12ca18ab, 0xf91d287d, 0xcd8149e9, 0x5d80fe46, 0xf27bba23,
- 0x7c83c916, 0xc29bfcd7, 0x994cc497, 0xbeb052d6, 0x05a7e5e8, 0xd827e71a,
- 0x71825baf, 0xce3e6fb2, 0xaa4563b8, 0xab1dc671, 0x1209c652, 0x8dfe963c,
- 0xb26c7cd3, 0x4b639e1a, 0xa15e7195, 0x5bfd1c71, 0x8ab7b8d7, 0xb5bcf0d5,
- 0x35e7195c, 0x7fa9271a, 0x1b7eecf0, 0xc64423f0, 0xe036fdd9, 0xd9c69327,
- 0xf5a4e34f, 0x77fc9e0f, 0xe4e3548a, 0x8ca553bf, 0xce7841d3, 0xbb38dfe8,
- 0x86ac99df, 0xcaa59de7, 0x9c682738, 0x575bfd21, 0xd58aeffe, 0xb96efcf0,
- 0x69efce32, 0x8dfeac9c, 0x357de7b3, 0x3f79ecfd, 0xa27f3f4c, 0xb7fb7271,
- 0xd40f82ae, 0x41f053f4, 0x102e7e98, 0x6ff6479e, 0xa81f3d9c, 0x07cf67e9,
- 0x33f9fa61, 0x7fb633c1, 0xa3f82aeb, 0xfe0a7e9a, 0xcf9fa618, 0xfdf19e09,
- 0xd3f5e783, 0x7ebcfc6a, 0x511f8c3a, 0xfb0a7840, 0x33c4cf07, 0x3c4cfc6a,
- 0x8d8fc613, 0xbfdc99c6, 0xa33f5e71, 0x67ebcfc6, 0x1549f8c2, 0xf4775d70,
- 0xcf135d6f, 0xf133f1aa, 0x433f186c, 0x19529e08, 0x8ce3061e, 0xbece3f89,
- 0xecfc6a8b, 0x33f1c8bb, 0x3a27d3be, 0xce90dda0, 0xe4ce08dc, 0x0080de0b,
- 0xa814faed, 0x30f4b0bb, 0x3d3bc81f, 0xf8d1ddea, 0x84405772, 0xc4aefb76,
- 0xa2bb4ff1, 0x58e96ff5, 0x8263975c, 0x3877654e, 0x7aaa2d8b, 0x4a925952,
- 0x6454a73f, 0xb369eaa8, 0xf4f554b2, 0xdeaa4707, 0x5e3058cf, 0x7cbc1f55,
- 0x643eaab2, 0x7deaa955, 0x55d3e3d7, 0xeeeb59ed, 0x3673d555, 0xcf554f7c,
- 0x554f3cdd, 0x54badbcf, 0xedc8de35, 0xd1f5552b, 0xd5531ebb, 0x51acb6c7,
- 0x4f6dddd5, 0x3be3eaab, 0x3f8d539e, 0x54cff8e1, 0xb777c2f5, 0xa745eaa9,
- 0x3fbd555e, 0x1a6bdcf9, 0x3ce6c6fb, 0x8bae4a3f, 0xc95acf68, 0x910e33ce,
- 0x192d5ec8, 0xa3faa262, 0x7f546c43, 0x70df0ef4, 0x8fe3ec27, 0x6bd005f0,
- 0x5bbe4a8f, 0x2fec319d, 0x4b1d39d8, 0x63a7d2c7, 0xd7db7d45, 0x80ce801b,
- 0x5e874a2e, 0x650d3dcb, 0x3727ae8d, 0xe8dfca11, 0x2e916a4a, 0x4474151f,
- 0xd591567f, 0x8d58dd22, 0xfd70e88c, 0x0297c2b0, 0x54f87451, 0xcaf39726,
- 0x6a194fb8, 0x3eef51d3, 0x0066f756, 0x9993f2f5, 0x664cbc60, 0x9bc287ec,
- 0xbc0e40a1, 0x3a68f99f, 0x09268bda, 0xf9e8d0ec, 0x347f9825, 0xf9c01fcd,
- 0x6fcce3eb, 0xcd522dca, 0x52aace6f, 0x60966fcd, 0x4f63277e, 0xe7961dd7,
- 0xffde9137, 0xe6987091, 0xa6ad6537, 0xac4bd7f9, 0x25bf354a, 0xf2037f3c,
- 0x7f38f3c1, 0xe7f58c41, 0x3faf564e, 0xfd7aa96b, 0xcfff5f12, 0xf3c84eea,
- 0x3ffd685b, 0xf5f04e17, 0xd7c63d67, 0xa371846f, 0xf18477e7, 0x5ff9c41f,
- 0x69bf338e, 0xfd7ab178, 0xebd5cbd9, 0x5ff9f237, 0x9e4f7bad, 0xfff346df,
- 0xaf8f7842, 0x9a71fb3f, 0x75ac68df, 0x38c9a13b, 0x441b52d4, 0x2fe600b9,
- 0x050c801b, 0xc6444cf3, 0xde0c6248, 0xd164285f, 0x016a3c3e, 0x9ffe83ba,
- 0xd0de8059, 0x72ed977e, 0xd017ac16, 0x6996af0e, 0x4aaec17a, 0x657819e9,
- 0x57f72b41, 0xc333f818, 0xad2bbe00, 0x11fd9fbd, 0x7db05de0, 0xa025c91c,
- 0x2def8674, 0x23529794, 0xe6307c72, 0xe413321d, 0x877bd329, 0x9a863bdc,
- 0x2fd7683c, 0x1f630466, 0x60d85e3a, 0xc515df38, 0xa8b78b6f, 0xea824beb,
- 0x097702ba, 0x81940912, 0x0b579652, 0x7f079ef3, 0x7ddd8180, 0x2c6dec06,
- 0xb9b0313f, 0x0e7e785e, 0x452605fc, 0xed1d55f3, 0xabbd79cb, 0x73d61d3e,
- 0xc3704abe, 0x0d81ec88, 0x3a196395, 0x7bcf0172, 0x77ef0039, 0x852ff298,
- 0x7273e9d6, 0x003617f8, 0x7ff1477f, 0xb0bbc88d, 0x0ee08517, 0x7fbfe790,
- 0xba054573, 0x83d7d0bc, 0x5e577def, 0xc92de2f7, 0xde98f7aa, 0xa9cdef44,
- 0x1ea20c4c, 0xc36ceef8, 0x3b552eb9, 0xf1c03f30, 0xdd0fec91, 0xf1eebacf,
- 0xdfb99e82, 0x75d7eea7, 0x8dd1eac0, 0xbb4b7285, 0x3dbec181, 0x8719a550,
- 0x1f7f6879, 0xa878e192, 0x973edd56, 0x5fd42539, 0x9fab5773, 0xe3b40657,
- 0xcf00f800, 0xf81c793c, 0xe6f844e7, 0xd7f36dcb, 0x7daa021b, 0x0a947a02,
- 0xa22cf6e5, 0xbd0f5a02, 0x3fb7dd9f, 0x434041d0, 0xfb588107, 0xf9f7fffe,
- 0xae7d8dff, 0x3e492d69, 0x8ad70517, 0xe7c969a6, 0xdb2dfaa2, 0x5f555339,
- 0xd55fbc12, 0x4a96f17f, 0x86c2fb55, 0xf9f6aa25, 0xd5561feb, 0xa4ff032b,
- 0x75773fea, 0xa1fdaa9d, 0xed54a7da, 0xab3d540f, 0xfbefdfaa, 0x77ffaaa9,
- 0xdaaa3767, 0x864b0385, 0x46a8dc62, 0x881d0df2, 0x8df7aef1, 0xa1109b6c,
- 0x2fae855b, 0xfca9d3f8, 0xb2a2efd4, 0xc830e50e, 0x5e3edd75, 0x1cab6cd6,
- 0xa15bf28a, 0xb50c4ff3, 0x69fe5043, 0x672b55e9, 0x6325d0fb, 0x88bed083,
- 0x2e596717, 0xf3ca2f30, 0x19db816e, 0xb213f3ca, 0x0d6c675e, 0x8972d7f1,
- 0xd7f2dff3, 0x3f229606, 0xb942972c, 0xe3f8b6b5, 0xd68126b2, 0x1a36d8c1,
- 0x10704967, 0xfbd17918, 0xf382ad9a, 0xe69141d2, 0x6e1f46af, 0xdec1da12,
- 0x3f9c3a0d, 0xbee43ed4, 0xe78f0831, 0xc1c01d19, 0xdf49535a, 0x2797f25d,
- 0xfe23d39f, 0xf05e54bc, 0xbcf2a6cf, 0x39e547df, 0x6795157f, 0x7654b5fc,
- 0xf95357f9, 0xe5403f91, 0x2a7aff29, 0x5037f03f, 0x85bfd279, 0x83fbdfca,
- 0x7bf15e54, 0xf4e854a8, 0xb57d96ff, 0xf2bdb8e8, 0xffafb8df, 0x16afbd1e,
- 0x23c3939d, 0x0d06ebef, 0x55794abc, 0x61797027, 0xf31676e4, 0x788e2958,
- 0xc3078955, 0x94571448, 0xf0ddc1e3, 0xd3f62777, 0x1831e537, 0xcfe8eaef,
- 0x7b8e3173, 0xb191a4f5, 0xd3ebf8cc, 0x3c5c5fee, 0x46ee80b0, 0x3858b7f8,
- 0x72aa015e, 0xdcec1e36, 0xf3dd7b11, 0x92cf5d78, 0x7726fdf0, 0x3c355c74,
- 0xc072e22e, 0xd16af1cd, 0xdacf7b71, 0x847c722e, 0xb3efbb76, 0xc6b5e847,
- 0x718b93d8, 0x2347f662, 0x36c63d43, 0x055871cb, 0x575e015f, 0x3a7ff5f0,
- 0xfda04e3e, 0x1f1f105b, 0x47e0a5dd, 0x32bff0c4, 0x574aafc5, 0xae90439d,
- 0x7bf4cab6, 0x027865b5, 0xe7191d1b, 0xd38b9d6e, 0x7ef04df5, 0x0e4be8f5,
- 0xa657f3b4, 0xf2e79ceb, 0x456fe3e3, 0x16d3a653, 0xaab4a76d, 0x841b57eb,
- 0x70371e72, 0x831acc25, 0x3ce9d1f2, 0x2c728397, 0x9c654a9d, 0xf392e995,
- 0x0bf6325c, 0x2576f872, 0xea7e5f12, 0x6fbf5137, 0xe3788e1a, 0x6168e044,
- 0x247de167, 0xf1d9ebd1, 0x3ba5c7fb, 0x8c245ffd, 0xc336b0c7, 0x985f6867,
- 0xd1d7ffe0, 0xaa7a63ee, 0x34d6e32b, 0xade30189, 0x6a977cf8, 0xa5cf783e,
- 0x67ae94e4, 0xf5be88dd, 0x7f42bcec, 0xa0e7ca20, 0x1079489d, 0xbf6d53b3,
- 0x35eaaa24, 0x2a9d03ad, 0x00ff067b, 0x04cac739, 0x72c1d23d, 0xf5ba2c99,
- 0xc002f5b6, 0x2e9d0937, 0xf78147a4, 0x92ea615b, 0xafa42e7c, 0xcdb9dfb5,
- 0x681b3d85, 0x60f85abd, 0xf5ea66ff, 0x265fe1f1, 0x1bd47d5e, 0x22d7fe83,
- 0xd01ea3fd, 0x999f3f71, 0x43e40e02, 0xdc701e96, 0x6cc3fc4b, 0x9ae0fc61,
- 0x5513cc19, 0xff01c657, 0x5f6d47ad, 0xa4bbbe72, 0x76bbfee3, 0xbcf2cdde,
- 0xf55fc337, 0xe2a7b7ae, 0xac78b5ba, 0xe4b3fd6e, 0x5314fca3, 0xefc151e1,
- 0x59bbd124, 0xee97f984, 0x7f212d3c, 0x7204305d, 0xb903787f, 0x5b7e17df,
- 0x646b79fa, 0xd8f72b9d, 0xf95fbec9, 0x0bd79cac, 0x779c4eb0, 0xf13c915e,
- 0x0515e835, 0xa67c6807, 0xd3d88c2b, 0x5e6d7e4a, 0x27f232cb, 0x0901663e,
- 0xc51792e3, 0x9fb44286, 0x4a353697, 0x32f3801e, 0xbe2395d3, 0x1c77b32e,
- 0xb5fb51f9, 0x9f08944f, 0x899f6760, 0x6cec1386, 0x6cec1d55, 0xbb117d55,
- 0x51f30d37, 0xc01b368b, 0xaa75a7c5, 0x9d115fda, 0x5662ee34, 0xc9768f5b,
- 0xeffc96d9, 0xf0fb86dc, 0x88850bfa, 0x3cd079df, 0xf8f10928, 0xcbf1e136,
- 0xdf04bfce, 0xde77df1f, 0xf26add08, 0x561e328e, 0xc13c14ec, 0x44737418,
- 0x7d0ad796, 0x5f8641fd, 0xc59c0f89, 0xdea4417a, 0xa17fa9ad, 0xfe657fa9,
- 0x4bba014d, 0x24f7ec8b, 0xe91677d1, 0x38f906ad, 0x5fb7c221, 0x3ef4fc79,
- 0xa37f77e3, 0xf3560fe3, 0xc5ff8c0d, 0x4e7e3a37, 0xfa8df81f, 0x77e3be82,
- 0x59631d9b, 0xc4a9d902, 0x3a71815f, 0x1fe9bbf2, 0xd2136bda, 0xc0a69fc9,
- 0x39ddd638, 0xd9a38c41, 0x14e99dcd, 0x54bf07d7, 0x6024f30f, 0x0edf907f,
- 0xf9f016e6, 0x2cd37ed3, 0xf8ca8794, 0xe55eb776, 0xe914267f, 0x7b28fe35,
- 0x61f00737, 0x38a6a793, 0xfcedd41b, 0x5b6b666f, 0xe30b7c4c, 0x04e8fca8,
- 0x2ffe45d6, 0x9e7aa78c, 0xa1d59a38, 0xa8f44a1a, 0x6d154f9f, 0x9c4b6f14,
- 0x9c4e28c6, 0xfad7ae5c, 0xd2c315f7, 0x4740e0a2, 0x32c9ea1b, 0xcfa6e01c,
- 0x67fde014, 0xf08cf4cb, 0xc5ff8012, 0xbc593380, 0x01f9c216, 0x39df155e,
- 0x65f540f2, 0xe7aabc11, 0x4d19e700, 0xe50f207c, 0xb8b31246, 0x53801e71,
- 0xdbd1eed5, 0x0e1e2853, 0xa3e517f2, 0xc989d4cd, 0xaaef9c7f, 0xf4ebaf0a,
- 0x190b23e9, 0xfc385085, 0x942fa601, 0x83ef8bf7, 0xd313bfaa, 0x8f04d9d4,
- 0xd8361c7a, 0x6f8f2d19, 0x8309fd95, 0xe9133bc1, 0xad6870aa, 0xa717f388,
- 0xaec872bb, 0x3a214b68, 0xca5d5acc, 0x685d42ce, 0x9cf78460, 0x39ef1c0d,
- 0xf71e3a3d, 0x0e09675c, 0x268cb183, 0x9c833016, 0x301cad02, 0x8259c78c,
- 0x5ae49fb2, 0xcd3cc3a3, 0x7829a07a, 0x54a7adaf, 0xa73610b7, 0xfc609b09,
- 0x3e3de96f, 0x67c1c63d, 0xe375d2fa, 0x9ae161f0, 0xa5a0c18e, 0xb8211b19,
- 0x05080b41, 0xc2de8e87, 0xdf184a43, 0x790f4185, 0xd72ed46c, 0xdaed0859,
- 0x2faf0b06, 0xae9417d7, 0x988ff787, 0x5d71cbbc, 0x891ce4cc, 0x4a162b79,
- 0xb7c6f5a2, 0x0724024f, 0xb6f2b815, 0x4cb54d77, 0x2814fe40, 0x1ecc3fcf,
- 0x24255bb6, 0xa5361dae, 0x6ed0921e, 0x2dbcb6f5, 0xa2bb7fa1, 0xd76a6de9,
- 0xa1ca1d61, 0x07535dc9, 0xd4f88981, 0xf4d2b2ba, 0x4b5e3011, 0xd60eba65,
- 0xb2badcf5, 0x4f75ea43, 0x1c51d35b, 0x775eb759, 0x77dd66b7, 0xcfdd70df,
- 0x5d2eefe9, 0x75ffdc5f, 0x8b3fbec2, 0xa25199f8, 0xeefe510b, 0xf0282da4,
- 0xec99bb78, 0xc69c7941, 0x1287f638, 0x7e718437, 0xe850eb8a, 0xa14f7947,
- 0x9174789b, 0x79239ccd, 0x1f4d503e, 0x6d9ef4c7, 0x7a4bd708, 0x4054894f,
- 0x787b25eb, 0x2ee7cf86, 0x2dd08fcb, 0xd1f2f9b3, 0xe61832be, 0x57e702fd,
- 0xb2519ae0, 0x7802cc52, 0x21ec6177, 0xd49eb235, 0x2e7301d5, 0x03d533ac,
- 0x7be177d8, 0xcf7c66be, 0x8427bb31, 0x32262647, 0x4620be5f, 0xaf995ee8,
- 0xdf1e4dfe, 0x05d4afaf, 0xed5c90d7, 0x08bc7012, 0xe869743d, 0x43d387a1,
- 0x87a269eb, 0x9cd3b6ea, 0x4aeb5a1e, 0xdbaa9e91, 0x85d1a704, 0x8719eaeb,
- 0xebeffcfb, 0x61ea97e6, 0x7b5a879f, 0x1d0107ea, 0x69655818, 0x7af09985,
- 0xb3ebe118, 0xca7c323f, 0x6fede2ba, 0x1facd1c3, 0x707d468d, 0xe61ee75c,
- 0xe94de08a, 0xd12f4977, 0x7c906c3e, 0x295e90ef, 0xcb823aea, 0x3be8ed7f,
- 0x1c5bb40e, 0x883defc7, 0xc1663bef, 0xf322b90e, 0x535f1c36, 0x1a67e78a,
- 0x64381d60, 0xa009eb02, 0x1f1f13dd, 0xf8c25f9c, 0xf84d3968, 0x9e1d61d1,
- 0xa7e72abf, 0x5ec8cf80, 0x7ee56a19, 0x1e7ac7ee, 0x5e9bfb3f, 0xef6e4b94,
- 0x2abf1ea6, 0x5c4fd0b9, 0xa9fea3a7, 0x5e8e8e58, 0xf7ea3aff, 0x055e5437,
- 0xfb287c11, 0x4813d0a9, 0x5fe62b4a, 0x577c5996, 0x6493f4d5, 0x4f1a8acd,
- 0x9fa36f79, 0x7f8017b9, 0xde63b137, 0x81ff2823, 0xf543fe7e, 0x198318de,
- 0x47f4a6f1, 0x3fb58cfa, 0x14331ef0, 0xd05c79f0, 0xa563b9bf, 0x7f617688,
- 0xf650b5f7, 0xacad0b8f, 0xbf7835f6, 0xac4a0130, 0x01f5cb27, 0x2f107d72,
- 0x75b94fb3, 0x946f3c02, 0x6e9effb8, 0x7a92e390, 0x3bcc48e7, 0x3db81ba5,
- 0x923e9c58, 0xb7c2bee4, 0x2484be88, 0x58021b32, 0xe964f566, 0x3e14df70,
- 0x42e8f7d6, 0x594a5076, 0x0dce977a, 0x61f98fcf, 0x9ff037dd, 0xbd108fa6,
- 0xd1d1ecb1, 0xfcbf5d06, 0x5276b898, 0x6c3b1f57, 0xec9521b4, 0x42f78da3,
- 0xaf447abd, 0xc6b5fb84, 0x8ddb7d5a, 0xe169efce, 0x13ed763f, 0x577bfa07,
- 0x8f2c6afe, 0x5078f715, 0xff51dbc6, 0xb14f7a6c, 0x30ab68a3, 0x3ec0cfbe,
- 0xd70bf0e2, 0x7d92548d, 0x3c890774, 0x3e80c7dc, 0x55a7f509, 0x777e73a0,
- 0xebb3fa46, 0x8477e7c0, 0xb1b05696, 0xb72bf950, 0x3ff04c6f, 0xe98faff4,
- 0xed1e747d, 0x9a79e318, 0x3b6d6b42, 0xd33199d6, 0xf985c3bd, 0xa29e753e,
- 0x2ca1a130, 0x42489509, 0xc533cd26, 0x0e4f69a4, 0xb2fe51e8, 0xe71e4cec,
- 0x945f3062, 0x44f40e9f, 0x7c3658f9, 0x3395d924, 0x65dd2af2, 0x48bdfbf2,
- 0x731b7eac, 0xfae44426, 0xeefdd734, 0xd1dd9532, 0xfd3946e0, 0xe245dfd6,
- 0x7f1e2d6b, 0x7d7ce065, 0x9775efd4, 0x63c5f4e5, 0x67584ba9, 0xa7c5f577,
- 0xfc5a5f16, 0xc95fc3c6, 0x52597729, 0xf1693c0c, 0x46ff0c72, 0x06368f3c,
- 0x9de20203, 0x4b98e9e3, 0x78188160, 0x29d2ec52, 0xa4683176, 0x9dd90f76,
- 0x68f0c977, 0x4f17d6f1, 0xd2bb8a9e, 0x411ff022, 0x4e91e87c, 0x884aefdc,
- 0xdb0304ff, 0xdd0ceb81, 0x6ab7f949, 0x434c1fb9, 0xf93bb579, 0x8375e150,
- 0xf087707c, 0x386301bd, 0x6d55fd7d, 0xb83dde7f, 0x14a0dd72, 0xfb9803c4,
- 0xd4671f1c, 0xf1b8c374, 0x7da4cd61, 0xdba8fc07, 0x587e3993, 0xcbbf6f32,
- 0xd0d769a9, 0x0abd768d, 0x3e1bfcdd, 0x3f17d498, 0x30ecdd0a, 0x067276c8,
- 0x1e788c1b, 0x02426fbb, 0x78da2dc5, 0x4f4b5ede, 0xc37a4f13, 0x47f4c8e3,
- 0x5f3025f4, 0xfb33b9f8, 0x569bc86b, 0xf25166d0, 0x7be8b866, 0x51bc9623,
- 0x7976fff6, 0x81676e9f, 0x4b03a283, 0x74c25ffd, 0xff591993, 0xda275c21,
- 0x20d883e7, 0x8318e75c, 0x7969cb8b, 0xcb75e19d, 0xe58a09e7, 0xb64d8bf9,
- 0x7acb8e10, 0xf8c297f4, 0x5cf8a2cf, 0xc08a4a40, 0xb3fb9061, 0xdb8cb521,
- 0x79d20f5d, 0xbb0bc01c, 0xf1c08d6e, 0xa7a08307, 0xc70c9578, 0x80a69de5,
- 0x57ac2b78, 0xf511fdf4, 0xf8e125d6, 0x3e9f5a58, 0x4a7a8b94, 0xdadbdedb,
- 0xd0ed8d51, 0x93f5116f, 0x71865fe1, 0x9ea7a007, 0x6dc18d37, 0x8a48e231,
- 0x4a6c093d, 0x83e15cf2, 0x6505513b, 0x92dfa5f7, 0x1c7af1d6, 0xa5b74b5f,
- 0x1da159e0, 0xbbd7a5aa, 0x7c1ccf58, 0x4553a5ae, 0x7a597eaf, 0x30a9ec50,
- 0x74d4845d, 0xd003d0a1, 0xfa42ffc7, 0xf1f09ee8, 0x9efe68f3, 0x169bd098,
- 0xbd810f4b, 0xeca293a7, 0xb3f678e8, 0x48273762, 0xc7da333e, 0x595d797a,
- 0x9e1d2e79, 0xf25dba8f, 0x62b9f058, 0x0fccdc4f, 0x80e01d60, 0x91cc7d02,
- 0x83a4ddf1, 0xc0dbe006, 0xf288214a, 0x63d621e6, 0xaa1ef9c0, 0xc9fca835,
- 0x8f9ee639, 0xe6fd087e, 0x3d270dd4, 0xbf28c3e4, 0x38f3ef48, 0xffcf3d44,
- 0x5c9ebcb3, 0xaee6bff4, 0xd1fc6836, 0x39e3a224, 0x23ecfe4e, 0x09303be8,
- 0x4d4aedc7, 0x76f94d1a, 0xfced7f55, 0xe3b43aca, 0x91abdf6a, 0xee78b2e3,
- 0xf7851dca, 0x83b71251, 0x131ef0c2, 0x6f80bc39, 0x6aebac1d, 0xd3e088db,
- 0x2954e831, 0x8e5d267d, 0xef52393e, 0x3b38d37a, 0x955f6318, 0x3f7c1479,
- 0x7c153ac8, 0x0e8b1e7e, 0xffdc7d8b, 0x910e6dd6, 0x2f1dacbd, 0xec8ca7a7,
- 0x81269cb0, 0x4de5deec, 0x2af9ba25, 0xa3fb9bfb, 0xa6efec7d, 0xf2de3483,
- 0xfedc8396, 0x3b23aa6e, 0xf70b797e, 0xa43ec047, 0xc80463f3, 0x15cbb268,
- 0x7983d33f, 0xb79815a2, 0xbd21ede4, 0xf3d5cf0b, 0x78d235fe, 0xf21ca9f1,
- 0xc0ff7913, 0xa7e8b5c4, 0xa85afd86, 0xbab5fb47, 0x9576c2ba, 0x6c281b5f,
- 0x5b5f91bf, 0x05385f53, 0x8fe05afd, 0xcdc15245, 0xe4b663f9, 0x797fa1ba,
- 0x41ade4c4, 0x02e2533e, 0x6abffdda, 0xfd202572, 0xbdfb253d, 0x23cf57d3,
- 0xfc3cde7b, 0xa37990da, 0x7df2de51, 0x76e24c7f, 0x7be88a4b, 0x3eebc70c,
- 0xcf172d74, 0x7fb4d4cb, 0xbcf911ba, 0x1ec3ce4d, 0x5d9157f7, 0x13dfeca3,
- 0xa777b712, 0xa077688f, 0xc14f7ffd, 0xcfe81cef, 0xbcf3d65c, 0x4922a5cf,
- 0x18f66f65, 0xd7027aee, 0x1e8094ad, 0xf16ee511, 0x82938e84, 0x8ffcbe23,
- 0x808f77c8, 0x7b5d9df2, 0x5bd70d3b, 0x81d872d3, 0x7e84bef8, 0x5bc9c610,
- 0x8f30d3da, 0x77f9a2b8, 0x9e7bf40e, 0x7b5db897, 0x40e9df59, 0x1ef96ebf,
- 0x5fc9dbb0, 0x003da50a, 0x32d4ba78, 0x3e69f0bf, 0xbf5a298d, 0x85f57fe1,
- 0x76edbb11, 0xeb282053, 0x284e253b, 0xefa1875c, 0x663d116c, 0xedfb5f47,
- 0x4dacd1f2, 0xcc0fb815, 0x0f861ee0, 0xec83acf5, 0x09962539, 0x21cf0a92,
- 0xbf2b901d, 0xefbde96e, 0xe7162236, 0xda0251ba, 0x0c14be3d, 0x8db69592,
- 0x9188375b, 0x73d950be, 0x12ef7b5a, 0x1b77dd73, 0x7aa3b9ca, 0xd6b37686,
- 0xfdd163fe, 0x9f7fe387, 0xd6bcbc25, 0xfdc56d92, 0x59d320da, 0x54ef4b4d,
- 0x166a97e4, 0x6f7e0efa, 0x3a22dd55, 0x7246ec43, 0xf85bdd77, 0x9b7753fd,
- 0xd8f485c1, 0x34d876dd, 0x22adeb16, 0x4e6a99c5, 0x3a428f14, 0x2866d2ba,
- 0xbcd7bc47, 0xf903b1f9, 0x57cfd15b, 0xde7a44da, 0x9e9676dd, 0x695ee32b,
- 0x7a851e4d, 0xfdc759a5, 0x9f238ebc, 0x7fdf915b, 0x326aed7d, 0x7eb297f9,
- 0xaaa7618d, 0xddad4eec, 0x6e19e53a, 0xb5494e47, 0xec579c93, 0xf8fa3ecb,
- 0x67675b14, 0x6b1f425f, 0x4919f0f4, 0x616ef3b6, 0xd8af31e3, 0x19792d7a,
- 0x9b7765f2, 0xe286b9d5, 0xe88edc1e, 0xb9f4f8ee, 0xb8fcf819, 0xee9c7148,
- 0xf1d1226b, 0x86cb03a1, 0xf1a2d976, 0xf5fb4f5c, 0x5f3fc0d9, 0x3ffd0fd9,
- 0x07716c3b, 0xf77a7d70, 0xd63daf28, 0x78e504be, 0x97432841, 0x4320658e,
- 0xec35f457, 0xe27d93c4, 0x7f91d7f7, 0xa67a9857, 0xddcd18a2, 0xfe425a7a,
- 0x057920df, 0x2687e923, 0x8075f22b, 0x73c20e95, 0x561655cc, 0x53d4f48a,
- 0xa0db9cc7, 0x9d51cf75, 0x30fb04ce, 0x1ba64761, 0xf955edb7, 0xa692f35c,
- 0x4a332906, 0xbf912c5e, 0x0860bb3b, 0x7a8a490c, 0xcb91a4fe, 0x97870bab,
- 0xeef248be, 0x161b237d, 0x362dbf43, 0x5bb57d72, 0x85d8cc0a, 0xe8e8cefd,
- 0x238ec1fb, 0xf3c11c6f, 0xba4e4b10, 0x28bea1c6, 0x6ffa7231, 0x3d6afe3d,
- 0x3d690b9e, 0x76f478c5, 0x83a8a57b, 0x1733f779, 0xabbd3f8f, 0x1c23ff23,
- 0x649e63b7, 0x461de75c, 0x1ff6672e, 0xc74795d5, 0xe7cbf605, 0x1a356e1c,
- 0x4661fc68, 0x8ed7ca91, 0x23cf2696, 0x19e5f3be, 0x75ceef91, 0x915c3bd5,
- 0xef629578, 0xb5f77a4c, 0xcfe06319, 0x4e749749, 0xbbd76edc, 0xaf5c44db,
- 0x896302eb, 0x07fb5f42, 0xf88f1bc6, 0x7fdbc657, 0x70078f89, 0x54be421c,
- 0xf41a0ff0, 0xbea1a347, 0x849f53bf, 0xf82813df, 0xcca1d657, 0x9e626aef,
- 0x8eb11b46, 0xc41bb5e7, 0x8f52314d, 0x54ef91f4, 0x7449cef8, 0x29e486f9,
- 0x1810f4e5, 0x870bf582, 0xec57642d, 0x4b11f596, 0xf88a1caf, 0xbe69f653,
- 0x0513eb91, 0xcff3789e, 0xca54e191, 0xafd74b2f, 0xa2015c1a, 0xc5023d9b,
- 0x90815c19, 0xfb053b29, 0xe739d365, 0x37d8de48, 0xbd87f707, 0xd6ffa6ab,
- 0x8ace9d2e, 0x214df1f2, 0xfde0d291, 0x74c34fb4, 0xfa226fa6, 0x88c93d6b,
- 0x7cee978f, 0x58cdc798, 0x728e9068, 0xc84181c8, 0x9c3fc8b7, 0x0503437f,
- 0x35b52728, 0xf8441dae, 0xaf90390d, 0xbe027822, 0x41b6b2c1, 0xb25d7a42,
- 0xe58b978a, 0x6c9647ef, 0x2e7f11f1, 0x15395ada, 0x98d5a7ed, 0x28bd40f4,
- 0x59d32bd3, 0x4ebcf032, 0x85df6caf, 0xdd3897e1, 0xd4d96c5e, 0x7d02f38e,
- 0x63e233fd, 0xcfb3eb72, 0xbd0ab823, 0xa06edc5e, 0xde90aa71, 0xad74f8a3,
- 0xde7bafbc, 0x693ef4e5, 0x7bf4a1bb, 0x0149eeb0, 0xec38c4e6, 0x443bedfe,
- 0x91fbdf94, 0x9f39339e, 0x70be9ea3, 0x63eb69f8, 0xeb4ecfa8, 0x777bc618,
- 0x39aaac4b, 0x1a3a2f8a, 0xeff1575f, 0x33759dd2, 0x95dcae28, 0xa66ba024,
- 0xf782adf0, 0x1a7b92dd, 0x34b7fff1, 0xdfc65ffc, 0x81ff87df, 0xfe649b7e,
- 0xfc0e54df, 0xb7128f0f, 0xce380a27, 0x79f6296e, 0xfd8d57a1, 0x5710b73b,
- 0x23ef1eae, 0x72355f57, 0x0d91dbff, 0x73df57f3, 0x30effc95, 0x6cdd327c,
- 0x26e8532a, 0x7b71f053, 0xf8839753, 0x3d22bc02, 0xf289bd93, 0xb82b24b6,
- 0x8f45884d, 0x967c946b, 0x72236f8a, 0x5f5fe14d, 0x5853c21b, 0xed16bb56,
- 0x008ae4e4, 0xc145e9d1, 0xf4093437, 0xe7e445da, 0x67e17218, 0x333e5e32,
- 0x1be754f8, 0x32c1c2fb, 0xc0abae90, 0x69f3a2e3, 0xee27055b, 0xdaeed28f,
- 0xf782fdca, 0x9e573e65, 0xf915ffbf, 0x53f78c3e, 0xeface27d, 0x933eb91b,
- 0xdcceb04c, 0x4c67d720, 0x60be2528, 0xc819e9ba, 0x8f404b6f, 0x8f4a2f7d,
- 0x1034345d, 0x38782abd, 0x67fbd32b, 0xcfdd7c89, 0xc41e70c9, 0x5be12998,
- 0x7a0947ce, 0x5af9c0bd, 0x8bbf3814, 0xc3c5fe38, 0xdd11a793, 0xee9b13df,
- 0x246aed97, 0x772c4cfa, 0xb3b9438e, 0x2736ef49, 0x8f258e8e, 0xec765483,
- 0x49f909f8, 0xf7c8c748, 0x0aa0f8f1, 0xa0c580f9, 0x7fd020ff, 0x7429fed4,
- 0x1d717400, 0xd73ca5f1, 0x379285d2, 0x5bb2f053, 0x669b7793, 0x601a78e2,
- 0x25def2e2, 0xfa78a9cb, 0xf3ef2be5, 0x2bf87dbb, 0xe6a054cd, 0x456fdc2f,
- 0x13717c4e, 0xe2679b3e, 0xfa644fed, 0x780ede4e, 0xe4a0627a, 0xeb720b5a,
- 0xe766d809, 0xa63e48f8, 0x595f9e49, 0xa09348c7, 0xf368dbca, 0x6f830629,
- 0x9f0a2984, 0x8d73f798, 0x334bd08e, 0xd81cfce3, 0x43cf946e, 0x5f765538,
- 0xc6912981, 0x40c1ea77, 0x967fd405, 0x0361d959, 0x0ceeeeb8, 0xe1718c54,
- 0x5981db77, 0xbae264f7, 0x853e829c, 0x53ace5d6, 0xdf20ce8e, 0x7c50b71d,
- 0x3ddb3f24, 0x974cfc8a, 0xf7c71f3b, 0xeca4fbc8, 0x6b75bc67, 0xfdbc5cf5,
- 0x21e3279c, 0xcad76e55, 0x2e26418f, 0xf9657a37, 0xf83fe5a1, 0x526f9317,
- 0x3b242fb7, 0x6d8c9d90, 0x326fde07, 0xff5179f0, 0x00d4bf40, 0x23ddfeff,
- 0xdcec27ef, 0xc343c41c, 0xa39d2376, 0x31d7f850, 0xf18e9bcb, 0xe48a4713,
- 0xaeb8c176, 0x7e1a6c59, 0xe8f2efbf, 0xd651bfc8, 0x26e1ff5f, 0x7ea26fba,
- 0x7da19187, 0x57ef209f, 0x0c162cc2, 0xbaf9f109, 0xb1e80763, 0xd3fe2894,
- 0xee89eb07, 0x5103bf80, 0xd93437fc, 0x2d806e97, 0xdbfac1fe, 0xc0b74cca,
- 0x8ccc993c, 0xa82aea16, 0x347c006f, 0x96047924, 0xb675f548, 0x0fe3f181,
- 0x2e4d303f, 0xbf04f3c3, 0x6fbe7a32, 0xc438a54a, 0x1c2cb00f, 0x28b22b50,
- 0x1d99bdbe, 0xb1f955f3, 0xb0738e46, 0x69469036, 0x9ce2f8aa, 0x2f8a2e9d,
- 0x507c8d3e, 0x79fe719d, 0x8da6ae1c, 0x078beb9f, 0x678c8a47, 0x17c4e790,
- 0x115ade29, 0xcf857ffd, 0xc925379e, 0x3011ebfb, 0x1dd0aefe, 0x93da29f2,
- 0xe31d7e4a, 0x2f8a762e, 0xb0ee8907, 0xc23e309e, 0x742a1b7f, 0x61e2b1e5,
- 0xafb64cbb, 0xf23487a7, 0xb17db589, 0x4bd031f7, 0x48b7f835, 0x29976af2,
- 0x54d81eca, 0xc78d2671, 0x439d19cd, 0xe39e447e, 0xffee35c5, 0xe1f28e18,
- 0x947efcb7, 0x80294671, 0xfdc0aae7, 0xe4d33975, 0xda9d90f1, 0xfc1d9084,
- 0xd1cf9add, 0xf37f0173, 0x2f951d73, 0x3cb7b3fe, 0x56d9ed13, 0x032c1b9d,
- 0x5c93ebcc, 0x41650f70, 0x9373d013, 0x2a9b9f85, 0x9079b769, 0x1305bbfe,
- 0x13e99b9d, 0x19ea2f8f, 0xd7da0bb2, 0x411f01b6, 0xb184bbb5, 0xef57844e,
- 0x0ad0f3a6, 0xd89ec77e, 0x63df4794, 0x37dc1be9, 0xcbc55b8a, 0xb6af16df,
- 0x894adc50, 0xf4f71593, 0xb5649d10, 0x61f8ea65, 0x5e8f3e29, 0xd792af5e,
- 0xbef1926d, 0x226be8fb, 0xb2c2b1ea, 0xef68b586, 0xef7d1867, 0x2e4ddd23,
- 0x1339db56, 0x3b76da84, 0x4634d7d2, 0x1fc2827e, 0x20ec5dc9, 0x4f12a986,
- 0xcfd07976, 0x73c17c9a, 0x04a9fd10, 0x77f8132f, 0x24f3e192, 0x58ff70e7,
- 0x07b8478a, 0x13fc29c6, 0xe328bc23, 0x2a5a3eec, 0xd2919da0, 0x46b82659,
- 0x2defa5f7, 0xe04e77e8, 0x5f701ee7, 0xe8687f15, 0x6196462f, 0x2fe9487c,
- 0xbd5cb99a, 0x429be7cd, 0xafa34fa1, 0x349de717, 0xa98ed83b, 0x81558997,
- 0x84f10c76, 0xd184b3d7, 0x02ba8378, 0x27818eb4, 0x9658257d, 0xf7048948,
- 0x3a210be4, 0x96a0312f, 0x5b9231d1, 0xfb25df3a, 0x4eda96e1, 0xf771f701,
- 0xef0443d1, 0x5e0ecee0, 0x9af57cca, 0xb814ffac, 0xa27f644a, 0xd5c38e44,
- 0x8e9f9e5f, 0xecd181fe, 0xa338c12b, 0x12fa8eb2, 0xbf9e3a5f, 0x3ce782dc,
- 0xe73fc426, 0x14966691, 0x8cc1373f, 0xaeecee7e, 0x5a7b4823, 0xf8ed39bf,
- 0xb48fda19, 0xdd1ddcd5, 0x80a57c72, 0xc1e5b5f4, 0x22b37ed8, 0x71c8b62f,
- 0x14f3a8c4, 0x7ad1cd83, 0x9ac932b9, 0xc28f2515, 0x9e722672, 0x9e7cb762,
- 0x6f7aa6c2, 0xa46613cc, 0x27834ea7, 0xdf2b9f07, 0xdf2abce1, 0x71f8a01b,
- 0x961ebe0a, 0x9e68d3f7, 0x1086e749, 0xe3a04e4f, 0xbfb1cd57, 0xd6685987,
- 0xd3977ac9, 0xf4e4eb0b, 0xb688eb82, 0xb999a633, 0xe3cdbd5e, 0x74e7a29b,
- 0x9c788452, 0x476c1454, 0x1e589dba, 0xbffa4768, 0x5274c985, 0x4b44e9ce,
- 0x939bf7ef, 0xa1e93a64, 0xe0260a7b, 0xe43145f7, 0xdb998563, 0xa59d2977,
- 0x0fc03f44, 0x857ce177, 0x03456a83, 0x339cd0a5, 0xf0f8ef50, 0x9e7822f2,
- 0x4769e45f, 0xbc7a737a, 0xa8db8e22, 0xc9ba7277, 0xb8c49ef4, 0xe4aa7d77,
- 0x38d02b5e, 0xe0c736df, 0xa7e416ab, 0x4a7e11d1, 0x5a47e391, 0xc3229cba,
- 0x1cf193e5, 0x43df1e7f, 0xa74a4f38, 0x33f783ce, 0x4c25b9e0, 0x055c4e46,
- 0x96f912fa, 0xd2f9d275, 0x09672aa4, 0xe5a0ddf2, 0xf9f7016e, 0x016fbd25,
- 0x3c76b3ee, 0x350c9f45, 0xbffe8879, 0x6268deb2, 0xf2ff8d26, 0xb5db99b0,
- 0x7e512b1b, 0x8499f2bf, 0xf0a5d5f2, 0xd6f1d1e5, 0xf3745179, 0xf83a5f74,
- 0xa07458a7, 0x3a5a7f95, 0xb50bc888, 0xadbc03fc, 0xedc3fbe5, 0x55ce94dc,
- 0x6a1b9722, 0x7f6f1779, 0x0d0dc8fa, 0x3de98f1e, 0x097ae0cf, 0xf39105e9,
- 0x74f4f1db, 0xae1ff9a3, 0x31cd1ba7, 0xd4ceb4f4, 0x9f3c1bf3, 0x744da2bb,
- 0x5f225c61, 0xf6ba8f3e, 0x4f3a24f1, 0xe09362f0, 0xd1439746, 0x502244d3,
- 0x6127b2bf, 0x4a15bb2c, 0x6ae78078, 0xb2250302, 0x08c759cf, 0x24d633ca,
- 0x1bac70ca, 0xdbb7fa41, 0x51e600a9, 0x256063eb, 0x91d3fa01, 0x684b181d,
- 0xf310783a, 0x988b6b2c, 0xb77000cf, 0x80f3f1b7, 0x485bd62f, 0x7e3eef9f,
- 0x400f37f5, 0x1d71e73d, 0x0e047f1d, 0x4ab673a6, 0x03b145de, 0xe8590e3a,
- 0xb32f703c, 0x7754d1b8, 0xf8790d8b, 0x21fbec02, 0xe8d983c4, 0xe2281fcb,
- 0x77aec439, 0xf1eca38a, 0xccbfd6de, 0xe48ae439, 0x7d0e9a97, 0xdf6d185e,
- 0x14a9f929, 0x3996f7d1, 0x963fdfca, 0x77cb9677, 0x055fb9cd, 0x9c5e309e,
- 0x5da27f1c, 0x2375f04f, 0x48bf687c, 0x10fb861e, 0xe3d648f8, 0xfb94de32,
- 0x0adbba0f, 0xbe80fa4e, 0x98393c5e, 0x7b5be1c7, 0xef7768cd, 0x214ef932,
- 0xf4b7899d, 0xf6a9f9d0, 0xe811deb6, 0xf9fc834f, 0x1ef79f08, 0x9d149b3f,
- 0xeb12feff, 0x3f5a24fb, 0x729f5bc4, 0x1f4b5e3e, 0xda167dda, 0x184dfe0e,
- 0x50c07c4b, 0xb086054e, 0xf567fa20, 0x17adc663, 0x31672371, 0x341dc517,
- 0x999fb479, 0x8e65ffbc, 0x4c679fe2, 0xde21bfde, 0x4efc1e71, 0x05f9d603,
- 0x989ec7d6, 0xdb478f9f, 0xf53ac2be, 0x18fb9896, 0x215afda2, 0xe60567af,
- 0x537cf0fd, 0x3852e18b, 0xef231ddf, 0x8091fb07, 0xdd4a05e3, 0x9fb87d27,
- 0x6bdcd81f, 0x4efa1f11, 0x0091da27, 0xb3b6227f, 0x97ba4aa2, 0x50f060c7,
- 0x3ad5f47e, 0x5bbd7e7e, 0x1e31b8b0, 0x6491dcd6, 0x33f87941, 0xfb1d2f93,
- 0x9d5dd48f, 0x09fa7183, 0x3cdd5e9d, 0x41be53d2, 0xe753b216, 0x8e09eaf7,
- 0xdfda315a, 0xcfeb12fe, 0xe7dcc4b1, 0xc790fb3e, 0xa1f7c5d7, 0xf462e7df,
- 0x3e9c7bfc, 0x45d651f9, 0xfb83f6f1, 0x3cc5c93e, 0x4f81f552, 0x7ead3fc8,
- 0x5b9b48c3, 0x0488c6f6, 0x252be3a4, 0x4b89edb1, 0x1eb75afe, 0x967199ec,
- 0xcb9b922c, 0x23dd2759, 0x61e9a2b0, 0x5e4a3eb7, 0x71d3f62a, 0x8e056743,
- 0x6440bc7f, 0xbd774075, 0x580389ee, 0x94ac390c, 0x097b45bf, 0xfd1f7f60,
- 0x9f9bd4d2, 0x9de6d283, 0x338fb4fb, 0x42a11c53, 0xb3cc8763, 0x88f73d70,
- 0x8fbc325c, 0xbcbce005, 0xe0e74ed7, 0xcf7f8f2e, 0x5c4b1f81, 0x7e5df96e,
- 0xb0ffcf00, 0xbf3047ce, 0x8d8bf816, 0x718aa8fc, 0xd9d7e5ef, 0x3b76fc23,
- 0xdbb0418f, 0x70e13f5f, 0xe68aff41, 0x144094f6, 0xa1e7b4fe, 0xc7d7911e,
- 0x6e745df4, 0x98bfed84, 0x563ef786, 0x829c3bec, 0xec37fdeb, 0xaedfc318,
- 0xf44d5d58, 0x9f22d533, 0x1960caa3, 0x8bfa0f28, 0x0573ed07, 0x5dc7c70f,
- 0xf77a821c, 0xd23b1c4a, 0x75ebf72f, 0xf6801a4f, 0xca14854d, 0x55bf1589,
- 0xbc2d2bfc, 0x3b373b37, 0x58f7e243, 0xb6af9f6a, 0xebdf3d70, 0xf000b336,
- 0x068d23e9, 0xc4eeaefa, 0xcacc3fb5, 0x64f8fd87, 0x06b9c1ab, 0x85eaadf8,
- 0x309bc1f6, 0x48ce395e, 0x5c4f97f1, 0xcba41ca1, 0xf3f02fc5, 0x7d6c9fb8,
- 0xc8f30d24, 0xb5f409ff, 0xdc58e01c, 0x55e7a068, 0xe7a7df8d, 0x5bba6517,
- 0xe52a42fc, 0x3c744f97, 0xaceb869d, 0xdf93fbfa, 0x966ffe41, 0x41c6a39c,
- 0xa0977cb9, 0x74b7773a, 0x575559bb, 0xbacad2f2, 0x8f391099, 0x7e7802e7,
- 0xe79af969, 0x89f57780, 0xc2d2fe5b, 0xdd6f8bed, 0x2eaeeb07, 0xaefb25e8,
- 0x8c8588fd, 0x44db5fa8, 0x71a1dfd2, 0xadd6f5ff, 0x77f29f50, 0xd31f9bbd,
- 0xb239274d, 0xece5c4c8, 0x70fa7d94, 0xff719cbe, 0x615776dd, 0x08797cfc,
- 0xdbd200e4, 0xe18a9f94, 0x79f479bc, 0x5cde6d54, 0xf36b8fc9, 0x029c78e6,
- 0xf2cdf1e5, 0x1c3f0ae6, 0x49cf84b3, 0x1fb7dd12, 0x45f279e1, 0x2f6e45c7,
- 0xfc4e44dd, 0xe3d6e116, 0x107b1efe, 0x6427dde3, 0xf6b89c6c, 0xafbc3ac9,
- 0x012293e1, 0x93ec2033, 0x58f2c66b, 0x2287707c, 0x659cf02f, 0xef5f645e,
- 0xd7092f71, 0x5dbe0d91, 0x1ceab0f4, 0xd5e5ff68, 0x49f0f98d, 0x419eff0b,
- 0xfcb4cf2b, 0x67928ff2, 0x0f0ee315, 0x7ca9d809, 0xcd4bcb19, 0xe568ae5c,
- 0x14a7581b, 0xe4e55a87, 0xa5c0a2f4, 0x5fc57785, 0x3f3058b3, 0xf5177e1a,
- 0x94efa15b, 0xf8acbe50, 0x260b2e6b, 0x50fea37f, 0x3f8635b2, 0xf095fa04,
- 0x07d42815, 0xfd408fd1, 0xdb46fd8f, 0x0025c95c, 0x96673ad2, 0x2772e515,
- 0x416b7fe8, 0x6a313e24, 0xe50e8357, 0x376fd845, 0xc577fda8, 0x72b2c95f,
- 0x795a31ba, 0xddfc98fd, 0x5df3bc4f, 0x3c4af8ca, 0xf184bea4, 0xb91273ef,
- 0x839ca6fd, 0x3967eb5c, 0x933e3df8, 0xd26bc3bf, 0xc8f0eff1, 0xfcf5c4a7,
- 0x83fdc8d8, 0x5c5574bc, 0x29bf09f0, 0x792def07, 0xf7a4efd2, 0x53a7f29f,
- 0x8bbf23f9, 0x79fc67ca, 0x135efc39, 0xc7c8fe46, 0xd18d2c87, 0xe49b04e7,
- 0xb093cdbc, 0xd062d7de, 0xe55623e1, 0xf497a03c, 0xd8d2c2db, 0x567bfdf2,
- 0xe4a5e13d, 0xa087fbf9, 0xc1f1f1dd, 0x097dd1ef, 0x83e26b1f, 0x6e6f250b,
- 0x13f37d2c, 0xc9379f99, 0x32c7e5fa, 0xfd900d7f, 0x9e729047, 0x4f78d1e6,
- 0xff773f30, 0xc31dfcac, 0xa9abfd4f, 0xf3cad3bc, 0x8ff76923, 0xf0073b7f,
- 0x3f036e75, 0xa4ce749f, 0x6cf3bf23, 0x85bcadad, 0xfd8ef0e0, 0xde76511f,
- 0xf1dc329d, 0xfd6355d6, 0x057e726a, 0xdea072eb, 0x876fd30a, 0x5c3e1e3a,
- 0xfa432df4, 0x695d66eb, 0xe846afd8, 0x2315ddcc, 0x79209b8f, 0xff84ac6b,
- 0x5f28219e, 0xed02fd95, 0xfefa2a31, 0xe72b228c, 0x7ce38fcb, 0xa65ab6ff,
- 0xcf25dbdb, 0xfa9e3e6a, 0x195fc37e, 0xf2b43f3d, 0xb4ffe678, 0x8c02f9ca,
- 0xce4894df, 0xdb9d7c70, 0xd635dedb, 0x78997118, 0x8e16bf7e, 0x9e9c6c5b,
- 0xa500f1b4, 0xcf01e254, 0x65044da0, 0x7049d5a6, 0x1803e36b, 0x07158d27,
- 0x8f2b4ff8, 0x3c7ba61f, 0x9f15d5a2, 0xcef8272f, 0x6c9b7dd0, 0x7bf3a336,
- 0x0e9b8a03, 0x60643c62, 0xd90eb059, 0xcb513ea5, 0xc63301a7, 0xba7cb249,
- 0xa4dbcc34, 0xa33f0275, 0x6a9781bd, 0xd69d22a5, 0x4f5d21d6, 0xf168e9f0,
- 0x412c3a13, 0x54e67141, 0x660266e7, 0x0bfeef39, 0xda82f3c2, 0x1db718b5,
- 0x797fbcb4, 0x9f7936f7, 0x84d9bc95, 0xc3c206ed, 0xa63fed84, 0xed84d6fc,
- 0x2885eb77, 0x35693efe, 0x878bff50, 0xff250e97, 0xaa39ce38, 0x26dc794e,
- 0xfc417bc4, 0xadc710f3, 0x8879f8df, 0xb8a8d6e3, 0xab8af54a, 0x5a77c724,
- 0x39f8feb9, 0x9f0169e6, 0xe4a05f3f, 0xfe291b69, 0x9a6a5bb6, 0x40887986,
- 0x43ce8eb5, 0x0bdcf386, 0xf08f79f8, 0x86ef98fb, 0xe2af3fe7, 0xc181eef9,
- 0xf6df2967, 0x03e79999, 0x6461db3f, 0xf25d2798, 0xefe51376, 0xb1d72cb6,
- 0xc364f758, 0x9cf9064c, 0xefcf018e, 0x7ca3fee0, 0x081df653, 0x08fdc24b,
- 0xf9b5c3e7, 0x8bae193f, 0xe9723e72, 0x4869e6ce, 0x93cb1927, 0x563fbc04,
- 0xeaebeb81, 0xbf506f91, 0xe5f7975e, 0x6f55fa66, 0xb55fa18b, 0xe0d3b57a,
- 0x6f52da31, 0x641b5fae, 0x2ab5eafa, 0x78e406e7, 0x6247e637, 0xd633cbec,
- 0x34ce713e, 0x738857db, 0x3149adfa, 0xf7ca9ce3, 0x6c490d9e, 0xfc18ccee,
- 0x37cc98f0, 0x743dcdba, 0x4da5230e, 0x4a972988, 0x17c94924, 0xc545b08d,
- 0x35f2b5c7, 0xd8dd7e06, 0xd0aec47f, 0x3e35ec21, 0x668ac731, 0x9c73e000,
- 0xf2719f0a, 0x9533bf0c, 0xe4a27d90, 0xd49a2e15, 0x6c77dbf6, 0x6dcf3f4a,
- 0xc4b78fb8, 0x6c53db91, 0x297f0282, 0xc5594bf6, 0x2572f154, 0x1b529e4e,
- 0xaffbf010, 0x3f230f14, 0xafb26862, 0x7afd00ce, 0x36f73126, 0xe83c27a8,
- 0x9779412c, 0x883ee554, 0xcbfadda1, 0x0fcaf7f2, 0x395efa33, 0x65f5ef9c,
- 0x7883bd91, 0x4f0efe8f, 0xfaca0fd1, 0x6bdd6f40, 0xb2cd70e3, 0x7d6f40dd,
- 0xcf317c83, 0x58be3fd6, 0xf769708c, 0x81ef1b2d, 0x7fd98d4a, 0xb0feac45,
- 0xd9fdd5cf, 0xbc720de7, 0xa4f9bfbf, 0xf5f0bd46, 0xf17de5e2, 0xbc2c44f2,
- 0xe5d0a86c, 0x009479e1, 0xe963b8b3, 0x7fb62d9d, 0x8b7edc78, 0x9edc462d,
- 0xfebf24dd, 0x49773fe2, 0xe2560f18, 0x507b61cf, 0x9e575793, 0xf909b757,
- 0xb49597e8, 0xb7fb235f, 0x64e7e0fb, 0x8fcdf6ff, 0x025779f3, 0xdc7f2279,
- 0xbf6f9f25, 0xf7fb95ba, 0xa4fd7322, 0x39a8e018, 0x6841606a, 0x606f8abf,
- 0x882116fb, 0x3d5f0bf7, 0x8bea853a, 0x192c09f7, 0xe9e02409, 0x160cefc4,
- 0x425e3e30, 0x8f754e91, 0x7d47a275, 0x7972784f, 0xea9eaa92, 0x3e13df55,
- 0xaa967660, 0xa46fa07d, 0xd5507daa, 0x96fd5578, 0xe13df55a, 0x457f4143,
- 0xd30333d7, 0xd7b3fd55, 0x0faaabdf, 0x13df506b, 0xcbadf8ae, 0xdf0cf5e4,
- 0x2f7d4f32, 0x61084877, 0xbca163be, 0x38e40bdd, 0x52e088c5, 0xc4cb38d5,
- 0xbbf0470d, 0x57de9b8a, 0x7448dad4, 0x68afbdaa, 0x7d754ed9, 0x46fb89ec,
- 0x5e0cf3f1, 0xc675373a, 0xdc5f8ea6, 0xc3035f74, 0x1abed6bf, 0x6afbd5d3,
- 0x886e5976, 0x7a9e6b37, 0x6f7c999f, 0x766f168c, 0xbfff7ab7, 0xed19bc69,
- 0x0c193c6a, 0xe31d8b3e, 0x44abad80, 0x5cb2defa, 0x4bee4e7d, 0xed93ddc4,
- 0xcaeee231, 0xcf376abd, 0x0dffb4a7, 0xd04664f3, 0x173c0634, 0x8536e455,
- 0x48e627f3, 0xaf2b5d9c, 0x75e41294, 0x2af29d8e, 0x5ad3bc91, 0xff21df86,
- 0x2b708bde, 0xf7588979, 0x05ce6880, 0xbe71c68e, 0x4d0afdea, 0xd240e7f8,
- 0xae76f983, 0x51ec0b07, 0x8739507a, 0x78c1e8a2, 0x897928e3, 0x4870a578,
- 0x0f44b8a4, 0xc86257e6, 0xbfdb6ff1, 0x7be93ea6, 0xf6dbf38e, 0xe0bf2882,
- 0x5047bdfb, 0xefde039e, 0xedd9f5c5, 0x888527a0, 0xd589fc9e, 0xf3d3fc41,
- 0x3c38311b, 0x48be7233, 0xe1689fc9, 0x0f7cd62d, 0x87b9a6d9, 0xb73c7eb4,
- 0xb9dae63b, 0xdf2c3d5e, 0xd7235143, 0x7a76346b, 0x8fee7acd, 0x6d15bde2,
- 0x8d5ff651, 0xe7fd4edd, 0x106a4be8, 0xf70b46ee, 0x8105eaab, 0xa67d78f4,
- 0x6e3ef340, 0x71f6a52a, 0x5c6a92f6, 0xacb930f7, 0x2a5e58c1, 0xed443bdd,
- 0x5efb1892, 0x6e765582, 0x7896cf2f, 0xddfd2fff, 0x0ee60ad4, 0x9bbe44a5,
- 0xd3be7162, 0x3d83c6d7, 0x140ece79, 0x3bf55f8b, 0x9a1fc42a, 0x3f1d0ade,
- 0x43e70f63, 0xfaf9fbe8, 0x66e7aecc, 0x109ebee0, 0xdb1e78dd, 0x1d602a75,
- 0x57c7829b, 0xa02256f1, 0x8d6cad93, 0x038bea19, 0x18f78a2e, 0x8fb25fc0,
- 0xcbddf08f, 0xc7c24cf6, 0xd3219398, 0x789f6858, 0xe3107bca, 0x58b3b9c3,
- 0x06ed8a12, 0x7f0530d6, 0x55b0291f, 0x5ab31bce, 0x19abfdfa, 0xe8a52b25,
- 0x5ba94073, 0xe2f3a61f, 0xf87579ca, 0x28fc4167, 0x9e47dff7, 0x4338f3f3,
- 0xe32f654d, 0x98e5297e, 0xc578ec60, 0xccbbf96c, 0x5ddef587, 0x5a63dfb8,
- 0xbddee8ba, 0x5b1c8ac5, 0x9defa3a0, 0xe1f793ef, 0x0f3cadbe, 0xbf5daecc,
- 0xce46162e, 0x0cf8c1fd, 0x2cf173f9, 0xb3bbdd3b, 0xbe932db8, 0x815e668b,
- 0x6d351be2, 0xbf497b6f, 0x44e0984c, 0x01f3d37f, 0x4b7ef013, 0x039701c4,
- 0x952efbea, 0x95efd37b, 0xa77ca7d7, 0x8372f20a, 0x78bbf015, 0x81a1dd6b,
- 0x2f7bde30, 0xa18fba31, 0xf240acf0, 0x37168981, 0xcb85edda, 0x05cfba04,
- 0xbdd1f40f, 0x6d862314, 0x7e3b8e8b, 0xb78bcb2a, 0xe5a078fe, 0x9c297404,
- 0x2a48f952, 0xfda768ec, 0x5dfc54c2, 0x95fdc2a8, 0xa338648f, 0x7b2a9bea,
- 0xde11bb07, 0x80cb530b, 0xe760fe4e, 0x85d74cf0, 0xd9bbfcf4, 0x543fca4e,
- 0xd20f24d8, 0x9d2d8569, 0x80ae37ee, 0xf400bdad, 0xdfa3fd35, 0x9f2e51eb,
- 0x05f7cbb2, 0x5c5cb2e4, 0x77c3b267, 0x2accf89e, 0xaf10339f, 0x0fb68d8d,
- 0xe539f4a3, 0xacdbba47, 0xf9586994, 0x3fe53666, 0xfbb4f795, 0xdf9f9cfa,
- 0xf0ec9873, 0x57fdc79c, 0xfade81fa, 0x93ddeb1c, 0x1db97f3f, 0xfc52bdc6,
- 0x17082197, 0x677e8fe0, 0x4ebfb941, 0x296dc719, 0x3f2762b9, 0x3f717986,
- 0xf9e3936e, 0xbb6d9d93, 0xebb7dd71, 0x0e516b42, 0xa9fef9be, 0x28671c64,
- 0x3eb8e078, 0xf5d573f8, 0x4570bee4, 0xbf7abee4, 0xf9f0a70b, 0xef2bbf0b,
- 0x8bc79b9b, 0x500df7bb, 0x0eed8bc5, 0xbfb86fbe, 0xc0937fd4, 0xcfd9f1ef,
- 0x937c564b, 0x9055fef7, 0x05824f7f, 0xe577e844, 0xc00fde4d, 0x66a87f21,
- 0x13a270ff, 0xb3cb839f, 0x51e7acc9, 0xb6e4e75c, 0x87efa77f, 0xf2792b27,
- 0xb93cea0b, 0xe2a59f0f, 0xf43d23b5, 0xb5f7701d, 0x63796fde, 0x43a95bf0,
- 0xfbf0fbc9, 0x837ec3f0, 0xf87e1f7c, 0xec5342bc, 0x7197f0fb, 0x89f120ca,
- 0xc52f0fdf, 0xe12fe03a, 0xe907f9ef, 0xc166c1fc, 0xb04c798d, 0xcfef5483,
- 0x87ded3c8, 0xf17fefcf, 0xe3df93c9, 0xc91f33ee, 0x1e194adf, 0x5dff1b5f,
- 0xcf3c0e82, 0xdeea7803, 0x51377fc0, 0x777fcf7b, 0x05b7e739, 0x4ba085eb,
- 0x553bfba0, 0xd6650bed, 0x6776085e, 0x3cec9328, 0x3dc477cd, 0x5c5f6c5e,
- 0x041befcc, 0xded34fbb, 0x754fe0a0, 0xf961ec4f, 0xfe1671f7, 0xf237d658,
- 0x64f32fbd, 0x590f31f8, 0xaf591692, 0xf9147fa2, 0xe16050b9, 0x1abee9f7,
- 0xed463ef9, 0xbb95e7fa, 0x36f3cf09, 0x761c6e08, 0xd067aff1, 0x078053f7,
- 0x2f995e95, 0x837e73af, 0x6ff3e740, 0xb2a98f76, 0xeeb845ee, 0xaef6becc,
- 0x50587ef6, 0x5f842e6f, 0xc6b1f990, 0x49afe1c8, 0x885f7466, 0xba25ec90,
- 0x125dc780, 0xf83b0f94, 0x0de10b39, 0xe627c923, 0xf2937b05, 0xe44e6574,
- 0x85058143, 0xcffaa3eb, 0x30fbe1af, 0xf842e7c2, 0x12c98efb, 0xc74cdbf9,
- 0xca3b6dfd, 0xd223d01d, 0x4e10dac9, 0xf2b126b7, 0x67bc0731, 0x20f06aea,
- 0x342e58cb, 0x2cdcb085, 0x3e7bbbc7, 0xaffc1134, 0x846cbe0b, 0x2a18a27f,
- 0xe79af927, 0xee93341b, 0xcaf9e3af, 0x167f328d, 0xaefa06b1, 0xa26b3260,
- 0x527598b2, 0xa1eb0779, 0xac5f83d2, 0xe03da364, 0x798cb2a6, 0x6aca9ca9,
- 0x0d672ca9, 0x712b7e54, 0xc002625e, 0x51359d35, 0x39e402bd, 0x32890bdd,
- 0xf74de319, 0xeecec89a, 0xac1cd37e, 0x0e6af800, 0x38bcb918, 0x577d2560,
- 0x08466073, 0x1fddf9e3, 0x7bf85cd9, 0xa7b176a0, 0xbf48e29a, 0xf7f93ab6,
- 0xbdd52e34, 0x2bb935dc, 0x78e3f77b, 0x7c7f421f, 0xbaad9e90, 0xafe27ba7,
- 0x7a8f907f, 0xe1ade260, 0xe81cf27b, 0xcb6d5fcf, 0xcafe3f26, 0x9446dd40,
- 0x5219d5d3, 0x7ab7e23d, 0x95ee8598, 0x05d3cee9, 0x415b2824, 0xe9fde3fe,
- 0x05efe06f, 0xff26d940, 0xf901c05e, 0xde10f57e, 0xdab60eaf, 0x951e7f21,
- 0x95377e1d, 0x5445fc47, 0xa87bf51e, 0x397f31df, 0x5efdc795, 0x9d1eaf2a,
- 0x77c7df4f, 0x839e9fa7, 0xc87427bf, 0x19a4f951, 0xb28fe1f4, 0x44fc2e7c,
- 0xfdf4eb08, 0x45aec0c8, 0xd508fdf8, 0xd7d67f41, 0xd19dd2f9, 0x555352ed,
- 0x92ea1db8, 0x7008fdfc, 0x629e93d2, 0xea4527a8, 0x118dfdf8, 0xbc199ce3,
- 0x57f3065e, 0xfb5220bf, 0x303f7811, 0xc72bd618, 0x2e094ca3, 0x03461f2e,
- 0x74e18cbd, 0x7c65df83, 0xea99d5d8, 0x69762310, 0x4e5c13e5, 0xedc0be54,
- 0xec67cace, 0x9eeef7f2, 0xef0d2132, 0x89cb511d, 0xf94c45f9, 0xbded13fd,
- 0xea2c45a5, 0x83b9983e, 0xe60f2475, 0xd3f756ae, 0x4ce807ca, 0x95aad3bf,
- 0x643a1f0b, 0x8d9733fb, 0x97faefc1, 0x1d93b1cf, 0xa76ec976, 0x763f7a73,
- 0x0164a475, 0x44fbd5bc, 0x0ab413ca, 0xb5b07640, 0xeab8de7f, 0xced0136e,
- 0xd7a7159d, 0xbeb1b8a6, 0xaefc49fa, 0x4ff352e2, 0x233aa4a7, 0xf4ec59f5,
- 0xdda007c6, 0xddf56eb9, 0x2ffac0f7, 0xb8c0bd23, 0xfc0d5b97, 0x12939b1e,
- 0xded32efd, 0x0b21af4c, 0x763f7bea, 0xa6ff3c33, 0x99bbf5e0, 0xbddbfbfc,
- 0x2b41be99, 0xa7deab47, 0x1afd61df, 0x6bf133ef, 0x00dc2fbe, 0x8a7bed7e,
- 0x7efbdb5c, 0xa77f0dee, 0x6dead976, 0xcea27243, 0x37d32c15, 0x658279d1,
- 0x921e5fab, 0xa5cdf603, 0xe88d96e2, 0x7835ef77, 0xf942ef12, 0x71e06cd5,
- 0xec904366, 0x89af4f80, 0x02466f34, 0x0609fbd7, 0x7c249f6e, 0x3d446a68,
- 0x1382f603, 0x6bdcafbf, 0xa439f0e6, 0xc112572e, 0xc2c3ebc9, 0x86f1f1ef,
- 0xf7b97025, 0xb25eb5e9, 0xd76e7ba7, 0x8082efd3, 0xc4faa07c, 0x6884523b,
- 0x226f67bb, 0x8af3de7f, 0xcc52fd48, 0xf1e8c49e, 0x2f1debb5, 0xdcd7b7cf,
- 0xc53f1aa3, 0xd653dfc0, 0xe36f9da3, 0x9de51324, 0x496e289e, 0xb2ebfcc3,
- 0x207bfe12, 0x8abc3245, 0xa3f1357d, 0xe1a3dba9, 0xeeff289b, 0x26e4ceb0,
- 0x557079fa, 0x7dfa38e2, 0xe297a742, 0xe71e73fb, 0x38f269f5, 0xe08e4520,
- 0xdcb9e772, 0xf20cd153, 0x28657c39, 0x79e417b7, 0x8afd608f, 0xf510a7a1,
- 0x24aab886, 0x33de0030, 0x9f495e3c, 0xd5d719f7, 0x6f34b005, 0xe1036468,
- 0xcdcdc2f9, 0xa13df70c, 0x8a176cf9, 0xefe69499, 0xaf6d7c53, 0xd813a641,
- 0xfe51998f, 0xa96736d7, 0xd7e60137, 0x391db939, 0x4245ac7d, 0x467a607b,
- 0xf5f9d906, 0xcc1cc1a5, 0x308cf70f, 0x3a627c53, 0x9f80258c, 0xc5886c72,
- 0xd412fe83, 0xcf58893d, 0xa7fd4c98, 0x86591d8f, 0xc658f87a, 0xb78c74f7,
- 0x9e2bc7af, 0x5fc0658e, 0xc21fda0e, 0x8969cf57, 0x963eafbe, 0xf92a74b1,
- 0xbd382315, 0x6c78cb1f, 0xd22bf62a, 0xc2cbee05, 0xf289a176, 0x70278fae,
- 0x0c5d3f3d, 0x09efc71d, 0xcef819ef, 0x566ff471, 0xc77ec826, 0x622b9018,
- 0x5c981fc4, 0x9f8edcd4, 0xde7b15cb, 0xeaea829e, 0xb73ff28e, 0x26f1e963,
- 0x2f7aa196, 0x03ae3d9d, 0xccdf32cb, 0xe8731032, 0xf88e3caf, 0x70f55a9e,
- 0x01ffd607, 0x88e3cafe, 0x55c992e7, 0x9f37fbf4, 0xa3e5dfdd, 0x7024e93c,
- 0x7dc463d4, 0x4b09f622, 0x781af7e2, 0x485f5092, 0xdf7db86b, 0x7b244fb3,
- 0x39751582, 0xea6e5c74, 0x33aafe90, 0x9e90d2bb, 0x38f207eb, 0x976715cb,
- 0xfdf2ea83, 0xf322ff02, 0x57624541, 0xc561d21a, 0x9e0261be, 0xe1e2bd3b,
- 0x56a04a76, 0x3061e7e4, 0xff2694cb, 0xd51678ee, 0x93fceec9, 0xfcf5ebc0,
- 0xf3d676ee, 0x23ed237d, 0x2f10cf8c, 0xe30f0f3d, 0xeabe0170, 0xb92f5ef1,
- 0xb983c33f, 0x52abf748, 0x87f21ee9, 0xfc24a72c, 0xe3302469, 0xae3e50d2,
- 0xe276ca68, 0xef06cdf3, 0x15f71a4c, 0x96e389c1, 0x3c966cef, 0x2a4fd236,
- 0x90f41e3b, 0x7ba7eed6, 0x3e32e687, 0xd126dcdf, 0x9aba0663, 0x03fcd2db,
- 0xeecd2e81, 0x8ff7c832, 0x4d6bdea9, 0xfa9f74e0, 0x4fba66cb, 0x87ce1976,
- 0xee81ab65, 0xab365d95, 0xf1443245, 0x3dd6b2cb, 0x577cafd4, 0xcbc5e533,
- 0x2f64ecf3, 0xeb0d634f, 0xdf2d5f28, 0x53e3e457, 0xc9add3b0, 0x65003fcf,
- 0xbe399fc5, 0x3efc53d8, 0x0f83f9b5, 0xbb2f91d9, 0xfc53960a, 0x942143e7,
- 0xf8bd001a, 0x0ee76650, 0xc92e1ff4, 0x0fd68ef6, 0x0b1dfad1, 0xa2a7335c,
- 0xdfd7d149, 0x38e8b660, 0xb03f168a, 0xdef11b1d, 0xa24d45a3, 0xd131ef13,
- 0xfe0a23fa, 0x953f78b4, 0xc7db2290, 0x3f706320, 0x20eca69b, 0xfa71933f,
- 0xd6017b20, 0x987dc971, 0xd39ab3ee, 0x6279efc4, 0x8a14a13d, 0xb3f06b03,
- 0x8cda1f41, 0xd60549f7, 0x02fee819, 0x5c02fe1f, 0x8dfdac52, 0xec4a27ba,
- 0xeb2d3f5b, 0x5bcf3ecb, 0x7a775fb9, 0x1b9f28bd, 0xdbcfb751, 0xb3247f97,
- 0x26fbe31f, 0xeed27df0, 0xcfd002c7, 0xdf8217e4, 0xafa97287, 0xdfa5e85f,
- 0xfed9b883, 0xdffff828, 0xc7a90a29, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7dedff00, 0xc554780b, 0x3d9cf0d9, 0xcd8dcd7b, 0x09c246fd, 0xb8094404,
- 0x9fb1dc24, 0x4a34021b, 0x414045d0, 0x2dc8d812, 0x088d9242, 0x59b6b696,
- 0x5a4062e4, 0x7da5aac1, 0x2c142ea8, 0x11a0d05a, 0x86ec5d43, 0xba8b4508,
- 0x8ad45cb1, 0x14178026, 0xb16d0042, 0xfbdfad1f, 0xbb2733be, 0x6a2364e7,
- 0xffefefd5, 0x27a3cbff, 0x9cccce73, 0x997ef799, 0x6318c399, 0xb17fc39f,
- 0x50dff876, 0x261d8ac6, 0xd8c21b27, 0x4fab569c, 0x8a6c61c9, 0xef74676b,
- 0xa79cc624, 0x18564c0d, 0xedfd2e6b, 0xd543262f, 0x8ad79b24, 0xcb7693f7,
- 0xcd942f0e, 0x3b58eef1, 0xdaf4b7b4, 0xd5f6c468, 0x512c490f, 0x6724ac62,
- 0x618b126f, 0x9b0e576c, 0x7783cae5, 0xd0daefe1, 0x950ed135, 0x6cdb1992,
- 0xfb622577, 0x1b32dee7, 0x1ec60f58, 0x87f5e78c, 0xe3db99bd, 0xfd5098b6,
- 0x687f5841, 0xd5b23ca8, 0x467f58c0, 0xe8c79c3f, 0xb318a30f, 0xebdfca86,
- 0xaf94d048, 0xa9a198bd, 0x68fac85f, 0x0759179e, 0xb38f9e68, 0xdfca6817,
- 0xa9ad1b4f, 0xa4529d7f, 0x3fe84f29, 0xa27f5341, 0xbca6b263, 0xeb8ac8d6,
- 0x63675e61, 0x8f4b5e8c, 0xd8463cd0, 0xb787040d, 0x478702d3, 0x683b584b,
- 0x8576c572, 0xa98d5957, 0x7dec35a3, 0x9c38da0f, 0x819c5d58, 0x4eec630d,
- 0xffa899f5, 0x58df0143, 0x7be0d599, 0xdd46a303, 0xb5bc046f, 0x160d941f,
- 0x42f32fc0, 0xcec614bb, 0x1a17768b, 0xbe207a0b, 0x7f7e01d8, 0xdfdf8d91,
- 0xded1f025, 0xc335e0df, 0x816b5bb8, 0xde85fa26, 0x660c56e3, 0xdd7e1843,
- 0x8259b28d, 0x730370f2, 0x17dd7be3, 0x1059cccd, 0x5163071a, 0xde76bdfc,
- 0xe64e3abf, 0x8defe68c, 0xaedff7e7, 0xec62e245, 0x5d2b5a9d, 0x82cf0e7f,
- 0xc0633e38, 0x691fa0cc, 0x34f8cc74, 0x06f6b7a0, 0xfa016ec9, 0x366c6cac,
- 0xed17f8e3, 0x316549cc, 0x5ea7e15d, 0x31a6d78f, 0x5aabfa05, 0xd52ab2dc,
- 0x1f6ef401, 0x682bf752, 0xe303555f, 0xb1a91200, 0x965bab0f, 0xbb62d8cb,
- 0x6716f442, 0x7f43f981, 0xbff4feef, 0xf0073ccf, 0xd4b3fe3b, 0xfd07e47c,
- 0xffb559f3, 0x17e8f4fc, 0x27f77f3c, 0x83f63f7f, 0xd3ff6a2f, 0x65fbdecf,
- 0xc6eef3d8, 0x932ebb3f, 0x30746129, 0xace1cccc, 0xe90cb7af, 0x3b3ffa0a,
- 0x358f1fea, 0xb2497f43, 0xe01d997b, 0x27cd7edc, 0xc51e0cd9, 0xcc34bf0e,
- 0x37e2131d, 0x095ffb7d, 0xb1bc037e, 0xfb338018, 0x15b7cd81, 0x0ddf06e9,
- 0x924b63e5, 0x5e906b7d, 0x669ac15d, 0x95b1f718, 0xe06b1c7d, 0x0ec7e53d,
- 0x86f7338e, 0x2f3cb1f2, 0x24cbfbc3, 0x2cfb8307, 0x3a446acd, 0x5703899d,
- 0x2b2ef868, 0xd31674e0, 0xf9d02dd2, 0x7c61adfb, 0xb6a96b33, 0x96d5ee5c,
- 0x61fce387, 0xd899cf1e, 0xbc30fab4, 0xeffcc4fb, 0x047c2f89, 0xce3b8be5,
- 0x5376e54e, 0xfac85dc7, 0xbfb4f58c, 0x81fa2d1f, 0x32008e39, 0xb7b2f1c5,
- 0x9fcf34ac, 0xf89183e1, 0xf2266f3f, 0x4f82dbe3, 0xd6c4c4cf, 0x6707c049,
- 0x6f070e14, 0xd2e1cc8d, 0xed056013, 0x6e2777ab, 0xdfc0b822, 0xb3ee5451,
- 0xa4c7cb19, 0xde17b240, 0xfb07265b, 0x28cffbe2, 0x1d630fad, 0x4668e2ef,
- 0x53b491ed, 0x10fa7c04, 0x30f3148c, 0xe7801f01, 0x69d946cc, 0xf1f0441b,
- 0x29a3e0ea, 0xa8d0fe8f, 0x43af7f29, 0xa2f6be5b, 0xb4c85cb6, 0xdaac8bed,
- 0x8e02cbf2, 0xfbdaece3, 0x96d34fdf, 0x1e3a55df, 0x1d8bf2e2, 0xf3c30dca,
- 0x259521cc, 0xcfe00e2c, 0x179c66ec, 0xb864f78c, 0xc11e2b1c, 0x3adb78e1,
- 0x21cbe7c9, 0x5f9e6afc, 0xecab1cc7, 0xdaf74879, 0x418bf0fb, 0xe82b9a7a,
- 0xed3aee67, 0x19dfebf3, 0xbc019e35, 0xe325d84e, 0x207f78fb, 0x4e78881b,
- 0x419f738c, 0xc744f03e, 0xc37d420d, 0x46b9ede4, 0xabd9ff78, 0xe3990e6c,
- 0x3b21cb81, 0x3938ff1f, 0xe7c011c6, 0x058768fe, 0xd3da2d6e, 0x8fe51527,
- 0x37cf5eda, 0x52dc800f, 0x9c7be1fa, 0x99af4867, 0x25d20559, 0x28fa021b,
- 0xe4c2c81d, 0xf6878f8c, 0xceb71dcf, 0x3be04772, 0xef955ce0, 0x77c8259c,
- 0x35f4e63f, 0x1ec8cda6, 0x352c71c7, 0x9c20b26d, 0x8fc427eb, 0xb999fa03,
- 0x5b9df38c, 0x3064ac0a, 0x647b99bf, 0x25cce782, 0x44498f92, 0xf435e72f,
- 0xbea0f022, 0x5e71f00f, 0x329a5fc7, 0xfdd12850, 0xecc62683, 0x678ebef0,
- 0x1466df25, 0x648d53d9, 0xbb6d542f, 0x337047c2, 0xef1117b2, 0x2a8f816e,
- 0xa81e2323, 0x0658fe04, 0x4bd4e7f5, 0x178fae34, 0xa8067c5b, 0x261db55f,
- 0xae3fcf08, 0x2824f931, 0x3328dc7f, 0xbeb10fce, 0x7db550be, 0x7c2f2f3b,
- 0xf82d96fc, 0xff3c5dbc, 0x2db8fb78, 0xa2b5bef8, 0x9062ef7f, 0x6ddf504b,
- 0x3e6b5664, 0x0259b75c, 0x63b7a076, 0x4757f651, 0xe8ed3d21, 0x3e0cf0f3,
- 0xc618c524, 0xab59c74f, 0x85d0e109, 0x9f03b69f, 0x2be575c5, 0xa0f1d237,
- 0x50b9f4ae, 0x839039aa, 0x9267e372, 0x95d2ab63, 0xa974f54e, 0xc17cedd2,
- 0xd9b3d01f, 0x1bca1035, 0x1d38f5f4, 0x1fd635ac, 0xb9e715b9, 0x3bfea642,
- 0xb71009e7, 0xdc2d4902, 0x28c8f7d1, 0xdabe5e78, 0x32efe884, 0x33f3aecf,
- 0x6ce6fcd1, 0x673274e7, 0xa453e4a9, 0xcfd5f3ae, 0x98bccbb3, 0xa63d956b,
- 0xcebafceb, 0x218fd383, 0xf1104876, 0xa2d1be75, 0x9dd1fda0, 0xab5d3b7e,
- 0xff411b64, 0x675adbb6, 0x238c0732, 0x2575bb7e, 0x907688c8, 0x179fa8c1,
- 0xec5ddfac, 0x2d39be05, 0x4a6f7971, 0xf95874e6, 0x5926ea74, 0x6953f50a,
- 0x4073f40e, 0x15e3bbbd, 0x81a56382, 0xc1fa09eb, 0x4e0f4e38, 0xc606bcd8,
- 0x856de601, 0x32679fa6, 0xe361c937, 0x8604b4ab, 0x3b41fa69, 0x7c9fbc26,
- 0x1c19cfde, 0x9fa85e4f, 0xf1da5daa, 0x9a839954, 0xfb0954f1, 0x0ce7ed48,
- 0x9fea078e, 0xf784f1c1, 0x3c769cf3, 0x66a09655, 0x769d553c, 0x9f27e895,
- 0xae55d3f7, 0x73f634f8, 0xb64e7d55, 0x2b4f0c31, 0xfb1631af, 0x0f4dd822,
- 0xbff973c4, 0x7ecd9b70, 0x557eac32, 0xeca6bc7d, 0x9fb74c69, 0x859fa30c,
- 0x3bc807f8, 0x032418b6, 0x314ad3c8, 0xfbb291c4, 0xa3d47881, 0x011faf49,
- 0x5b559a0b, 0xa748cc3b, 0xfcfa5d8c, 0x865861f3, 0xcf1c653f, 0x38450394,
- 0x1d93469f, 0xf00cfd59, 0x71e017bf, 0xf5f061c6, 0x7fddf986, 0x119b83e9,
- 0x4dbb313e, 0x7940f709, 0xab45e3ad, 0xdb5fe302, 0xe5f62a68, 0x67dddea1,
- 0x5f261d9d, 0xfdb93ad7, 0xeb019ccd, 0xfba181e4, 0x8f5f8331, 0x0cf17b43,
- 0x5e2316b3, 0xd6031ad7, 0x587061c1, 0x3eaa2a0b, 0xc5765c02, 0x5fd744cb,
- 0xb54b2e1b, 0x01e15170, 0xf085d9f0, 0x535b58f1, 0xffbb4ed0, 0x6871e39a,
- 0x360d15a7, 0x9ca7a44a, 0x9721e912, 0xabaff39f, 0x0d7f2644, 0x08525626,
- 0xf441bbf0, 0xfa0ad677, 0xdbf06ae9, 0xd885091c, 0xbc71c6ee, 0xd2f978dd,
- 0x9e50c9a1, 0xca993dfc, 0x4d99eeaf, 0xe2600d72, 0x27bc0008, 0xbf258d4f,
- 0x3863fa0e, 0x9fa8a9be, 0xe126d481, 0xa937682d, 0xe005f258, 0x308e377d,
- 0xf3e70f1d, 0x796d4e49, 0x0cb6b172, 0x335f91fd, 0xafbda5d5, 0xe28759da,
- 0x07de9363, 0xb1458c17, 0xfed1cf8c, 0x6632fa11, 0x1f6b5ef0, 0x11d9d718,
- 0xebcd0766, 0xeca9dfd2, 0xb6c0c6bd, 0xa7337b62, 0xb28d9ffb, 0x84e796fa,
- 0x443dfbd3, 0x030e4db7, 0x37fb6133, 0x9bd43e2c, 0xbb33db7f, 0x77a08b17,
- 0xd198ed43, 0x35e34690, 0xdcfeb832, 0xfd8c51d4, 0x067bfcff, 0x8ffa0cb6,
- 0xfb76651b, 0x27bfb422, 0x4231f85e, 0xef072dde, 0x2f2dfd0f, 0x256c728b,
- 0x3f2148bb, 0x58b7f54d, 0xab2a1f5a, 0x340c967e, 0x34fa4419, 0x9e3d1076,
- 0x81e9f7f7, 0xe68d8ce3, 0xa07f3c78, 0x2f6e1ed9, 0x047fa234, 0xd01fc676,
- 0xa36b823f, 0xb5fd7fb0, 0x00bf2a76, 0x035e0e7e, 0x4ff90ab5, 0xd3fb6b7b,
- 0x075ac5f5, 0x8ed7f75d, 0x5a81eba0, 0xb97bd527, 0x07ae98b6, 0x75745d6b,
- 0xf9f025c7, 0xec5db918, 0x920afe79, 0xdbafe073, 0x88e28612, 0x3e20066b,
- 0x793e3bcf, 0x0af0b7f2, 0xafd3a8cf, 0xacf5c116, 0x735771d4, 0x3ff9fc98,
- 0x3f074fcd, 0x7fc71728, 0xef5d7f39, 0xb73d542f, 0x70179763, 0x87a9e0b4,
- 0xfbcc18e2, 0x0a5d7194, 0xadcae1ca, 0x709ce32b, 0x0e3bb305, 0x9f29e1f5,
- 0x3e891c5c, 0xfa54134a, 0x2848c670, 0xabe718e7, 0xefb89e8f, 0xbfabe406,
- 0x51d9356d, 0x7ec0785f, 0xae7e80b1, 0xf89db86e, 0xbc6dca12, 0x1939ef7c,
- 0xfe5a8dcb, 0x87bbf059, 0xa2589452, 0xb74e4cbb, 0xdba44c81, 0x8def2dea,
- 0xb0f23a47, 0xfad3d20e, 0x8bfef876, 0xbd4f7a00, 0xbd7e8e5c, 0xffcab9fe,
- 0x9eae411e, 0xc9cefb86, 0xab57f871, 0xafaef119, 0x0e34815f, 0x41313c7c,
- 0x3670f1f0, 0x156ded1c, 0x4c97cc1e, 0xf73f2cfc, 0xa86d419b, 0x39fcb7bf,
- 0xcaebca4e, 0x67ebe7af, 0xa507fa3f, 0x176cfe7b, 0x6bd7af74, 0x200c234a,
- 0x7e7e8a15, 0xe20534ad, 0xb9fda346, 0xacf244c9, 0x1f6fc772, 0xd3da35fb,
- 0x7d1c5a6f, 0xf69bb415, 0xe505191d, 0x494d3b85, 0x311a7c25, 0x2f084a52,
- 0x696ff81e, 0x0b0f087e, 0x5667d99e, 0x77fbf206, 0xb1f08427, 0x99936770,
- 0x8f0aec0d, 0x7326faa2, 0xbc044c6b, 0x478db7d4, 0xfb9f96be, 0x7ef119a7,
- 0xa58905ea, 0xe78044e6, 0x6e717da6, 0xa3c22701, 0xde2753c0, 0x803df574,
- 0x1553a417, 0x57e7fa4f, 0xc67a7027, 0xa23c94fe, 0x00ff27e7, 0xcb78a9f0,
- 0x57f9c0e2, 0x1c67793c, 0x6303e3ce, 0xdfeba70d, 0xc2714cac, 0xde4c2b7b,
- 0xf95d3b14, 0x96478afd, 0x6fcdbd10, 0xc8c29259, 0x1ba670ee, 0xd33cd046,
- 0x37737e71, 0xcdf9a54e, 0xbba26e63, 0x2ec8df8a, 0x353e2bb4, 0x119de2b2,
- 0xc175e2f8, 0x066c1f17, 0xfbf3046d, 0xef73c840, 0xcb8fb2eb, 0xca183bcd,
- 0xdcaa25c9, 0xfca88b64, 0xe9e395a9, 0xe08304f1, 0x70f2e02b, 0x6f72dd7a,
- 0x51f3f110, 0xfd153396, 0xbf030f47, 0x7d21f797, 0x2dcafd0e, 0x7e3952e3,
- 0xed4cbdb8, 0xc2290ec0, 0x683f58fb, 0xac3b7f22, 0x273cfb1d, 0xe2c5fef4,
- 0x28ee30fd, 0x07f3e409, 0xd36edc29, 0x095fefcf, 0xbf028e3c, 0xafa30b20,
- 0xfce6fe30, 0xe73565be, 0x7ddf956f, 0xf9f18a93, 0xff388727, 0x7cccbb60,
- 0x9520571a, 0x914d379e, 0x58581e48, 0x6f5f1220, 0xd6be0931, 0x04e9573e,
- 0x38c46dc6, 0x60bd2746, 0x7f0409ff, 0x3de787b2, 0xe4c2ed08, 0x17df07a1,
- 0x953fb5d7, 0xfe0be76f, 0x3ff9057f, 0x6cffc43a, 0xeefbe723, 0xf097adf5,
- 0x3df26957, 0x57e46bf6, 0x82af4fe0, 0xe1726afc, 0xdede3fbc, 0xf456e47c,
- 0x3e55eb1b, 0x3d4fcad5, 0xbd3c569f, 0xcf53e88f, 0xefd71fa7, 0xa7c8894b,
- 0xb4a5f73b, 0xd3e245e6, 0xaa7e56ef, 0x2754fbf0, 0xd879553f, 0xf2f51c1d,
- 0x250481f0, 0xdf843ca2, 0x2bac3621, 0xa774a9fd, 0xdf82dbd2, 0xb942f557,
- 0x2a9749d3, 0xa5d275dd, 0xf9fa774a, 0x7fa7e16a, 0x158047fe, 0xb90df9e2,
- 0xf7da1863, 0x45b8c153, 0x03054dbc, 0x6b1f34a3, 0x4d5f11a5, 0xfef3e311,
- 0xb7184983, 0x79c21241, 0xf4bff54d, 0x0df7be19, 0xdfa2f313, 0x2dcf767b,
- 0xab57da0a, 0x990ead92, 0xe68f84e4, 0x5eec8efd, 0xb00f7189, 0x8e51aaa3,
- 0xdb47f74c, 0xddb96ed1, 0x32709eea, 0x7f448411, 0x8dcbe489, 0x07b2656b,
- 0x2e3c79ad, 0xf2611ae1, 0x9efa5fa1, 0x2be345c1, 0xfd5e1829, 0xf73d1a23,
- 0xb93dd1cf, 0x2157c606, 0x8c3f87c6, 0xc2ceddd7, 0x0f5faa7e, 0x46bbce5d,
- 0xa1c5440a, 0xe3b12c3f, 0xddb87061, 0xefe32da7, 0xfd4252bf, 0x777eae5e,
- 0x5f4df47c, 0x3aba05df, 0x1b787e0e, 0xba7c8d5e, 0xcb3cf4e1, 0xa9e8e1cf,
- 0x031fc894, 0x615c9bbc, 0x44bad57e, 0xbddef72e, 0xcce280bb, 0xec0ff785,
- 0x2e6de5c1, 0x423cd7c5, 0x2af79e7e, 0xa8af503d, 0x03f9eef6, 0xe8efe445,
- 0xe822d3c7, 0xdec22ffc, 0x5a563b3d, 0x9ddf0327, 0x3f641d65, 0xd8dac779,
- 0x6f7e08d6, 0x7ea7624d, 0xd430f260, 0x86afea4b, 0x4f13b0f8, 0x329e276b,
- 0x7f0aea0e, 0xe5571dfc, 0xc3effca0, 0xe109f915, 0x1d6b62d9, 0xcf308aef,
- 0x4adc047b, 0x46667ef6, 0x3f937639, 0xb8f084c7, 0xb1acac69, 0x28947f63,
- 0x2b0144e4, 0xec9571c0, 0x246e2ebd, 0xec80e3e2, 0x3d5c01b0, 0xf76673fe,
- 0x11c3cbc0, 0xf5fb47fb, 0x0f31c984, 0x67e278e1, 0x3e05e636, 0x45c44578,
- 0xf51391e0, 0x44e5741a, 0x225f7dfd, 0x9bbc078f, 0x4eb82768, 0x2534292e,
- 0x1af37bc3, 0x6f3183ec, 0xbfea2191, 0xf3d0a89b, 0xad4ed14c, 0xebc95197,
- 0xd5ed99b5, 0x23dfe691, 0x6a5f53b9, 0xdefb35f0, 0x0fe8cd3b, 0xabe16fff,
- 0xc0d8fef0, 0x8d5f8c18, 0x746e4895, 0xfc4663a5, 0x63fc1e70, 0xfbcf13f4,
- 0x7cf2bc79, 0x02c38f09, 0x735db93c, 0x8d764493, 0xf87ae74a, 0xabe0273e,
- 0x28a8ffbe, 0x9db913fb, 0x8557c2a4, 0x6abc7eab, 0xd757907d, 0x1bfbcb86,
- 0x293f071b, 0x2fc23e61, 0x55d00dd9, 0x8cd5b1b5, 0x5c69e77c, 0x667f426f,
- 0x65fbc2ba, 0x29a0d746, 0x6ef37461, 0xdbde91a2, 0x267a3f9c, 0xb585c7d2,
- 0x77f38616, 0x871739ce, 0x8315f37a, 0xc8d1b5e3, 0xe4caaf7f, 0xc707778f,
- 0xafdad6bf, 0xef0c6b1f, 0x39c68737, 0x84d0b2b9, 0x654669ea, 0x8c352993,
- 0x4c4dde8e, 0xfdeae7a0, 0xf2854a8c, 0x1a3ef062, 0x16e7f787, 0xd5e49bca,
- 0xc344c707, 0xf13519f3, 0xc02afe9c, 0x8e72a6f0, 0xbea68f26, 0x5347cf47,
- 0xe535a24a, 0x3dad45d9, 0x96252e11, 0x044762c0, 0xa926f4fa, 0xf535f9f4,
- 0x37e81382, 0x5ffedd02, 0xab1617a7, 0x9355a17a, 0xa92ebecf, 0x8d485e8b,
- 0x2d1617a4, 0x0f115253, 0xd165be6a, 0x2252e34b, 0xb5c385e9, 0x1472df3c,
- 0xcf5e19e4, 0x70bd014e, 0x985e9875, 0xd13a2362, 0xba482bb7, 0xf1505e8c,
- 0x99cb1df4, 0x2217a8c3, 0x24f8f5f0, 0xd9b85ead, 0xe17a4e5f, 0x533229e6,
- 0x497df3c2, 0x56eefec2, 0x4ca6142f, 0x11c9b2a7, 0x106e811d, 0x3a17189e,
- 0xf8eef22a, 0x3f0fd41e, 0xbc13b24e, 0x3ba27af4, 0x39799e39, 0x04bffe39,
- 0x2f8e555f, 0xbd912a9a, 0x18ee95d7, 0xe9a2efd1, 0x16ade512, 0x7c72e1ed,
- 0xf1c81951, 0xae45d61c, 0x0eae50ba, 0xbcab9709, 0xeb9bb57d, 0xce634f01,
- 0xf9e14b2f, 0x0e4cebad, 0x35bfd42b, 0x85876724, 0x271fd9cb, 0x2b672375,
- 0xe0bd9cb8, 0x45f1e82f, 0x4263cb71, 0xcafc82be, 0x8ba04475, 0x9ad1a569,
- 0x06270375, 0x19ef29ff, 0x64578fe4, 0x27bc878a, 0xc1c1fdf4, 0xf6821a7f,
- 0x0f1c61ff, 0x49b7efe0, 0x9f80ef5c, 0xe058fd71, 0xdc39a2fb, 0x2edaae5e,
- 0x1baafc13, 0x6f57bf38, 0x3d0e2893, 0x3333ff3e, 0xf0f6ede5, 0x971a86b8,
- 0xf0bff156, 0x9955d695, 0xc4937cf8, 0xfc0acce3, 0xcd87cb0b, 0xbf242c73,
- 0xad06fe64, 0xe96250ff, 0x4aed8fd8, 0x3639277e, 0xec8bfc91, 0x7e89556f,
- 0x3ed36e16, 0x16ac72af, 0xe48057fe, 0xf6bd5576, 0x5fc15ef9, 0xde40e573,
- 0x7bcf9833, 0xd244764d, 0x4ebd6a67, 0x9bfc5478, 0x780168f0, 0xf0eaf90c,
- 0x44dfddb8, 0x0baf9379, 0x5ffcfd07, 0x3e46e554, 0xf6fc821b, 0x7249c19e,
- 0xcf32fbc3, 0xdf59ce3b, 0xfe3c3537, 0x8ba0bafc, 0x55ee0c57, 0x9aaf58e9,
- 0x6fe73fe7, 0xca1a8704, 0x306cf5a5, 0x37f36efa, 0xa76bf568, 0x48506f3e,
- 0xecd6975f, 0x43cb6e94, 0x5abcf3b8, 0xf8fd6f85, 0xb65e780c, 0xd437f414,
- 0x716f9d9f, 0xc5a8fc63, 0x517241d6, 0x05cfcfa5, 0xe053fcbf, 0xc74644e3,
- 0x8d3bd258, 0x2ef89d92, 0x087ae360, 0x728362f0, 0x8fbfc8f3, 0x5bb07817,
- 0xde392f88, 0xe427803c, 0x517ef1db, 0xddf6e7ae, 0xee39ff0c, 0x4c9bfbff,
- 0x91a2aed8, 0xa0236baf, 0x8c3be986, 0x84a61447, 0x1b4f73e1, 0x92adefa7,
- 0xe0f86e83, 0xe7c197df, 0xdaa8f065, 0x9f165f23, 0x4f3e5c2a, 0xc0827e12,
- 0x582d8b6b, 0xfc798052, 0x3363923d, 0x53c7f656, 0xbae4e15c, 0xd8df843e,
- 0x3d578e64, 0x80dfa3dd, 0xf2d4a6eb, 0xfa201c24, 0x7636c5f4, 0x6f6f7d42,
- 0xcb855f6e, 0xa3be351d, 0xbe6abf5e, 0x1482c3cc, 0x66f352af, 0x83f76523,
- 0x7257a889, 0xa44f5a25, 0x4660cfe6, 0x40dfd7c4, 0xbe9313ff, 0x66967fa0,
- 0xecedebe7, 0xe13b7dea, 0x6e5136e9, 0xb4761ace, 0xa17be014, 0xbae0764e,
- 0xca0c5bb4, 0x9e506b91, 0xe43131ac, 0x4d070b8f, 0xa3df2e4e, 0xbf949f49,
- 0xfa84c272, 0x82731cb0, 0x09ffc798, 0xc4271bd7, 0x3d02de78, 0x2898c4ec,
- 0x093a1fab, 0xd1c53fde, 0x9cf30e34, 0xacb48753, 0xe4ee38c4, 0x2391fb22,
- 0x32d5cf88, 0xaf1e7c43, 0xeb3f222b, 0xe2243bce, 0x6f0037af, 0x94ea7ed8,
- 0xe047239c, 0xc97565bd, 0x75295314, 0x0d3cdf26, 0x6507a5ca, 0x66f50287,
- 0x831b18df, 0xfd09d7f1, 0x830ee665, 0xae0b194f, 0x6957f8c4, 0x71531dcd,
- 0xe7a015dc, 0xe15d1f30, 0x8a97196f, 0xb5128de5, 0xe6dd78f7, 0xe09d2054,
- 0x21e67386, 0x5079fef0, 0xd9eec10f, 0xb679ebc8, 0x754c0e48, 0x27aff3cd,
- 0x8b6f3879, 0x598970c4, 0x2b58ec10, 0x8567d7ef, 0xa11b837e, 0x63e7943d,
- 0x4b77ec7b, 0x90d3cdfc, 0xd49c618f, 0xfdb2c47e, 0x41e72f28, 0x82cc783b,
- 0xfea0ee5b, 0xb128df6e, 0x62afe834, 0x47cfce44, 0x4d077f60, 0xb47e7c0e,
- 0x671457e9, 0x4bef099f, 0xcb67fe87, 0x9d68e3ad, 0x3b258fd7, 0xb92abbad,
- 0x5677f099, 0x9b4b19f0, 0x47baf64a, 0x6f3daa62, 0x3edb8f0c, 0xe89bdc96,
- 0x65d2de78, 0xad5e70ab, 0x031ce4de, 0x5a39d5d1, 0xe0127897, 0xf43b06ed,
- 0x83c79984, 0xcc27bd9b, 0xb37261ad, 0xf10fb939, 0x42c69ce5, 0x3aea2f92,
- 0x6e32f70a, 0xb4adb467, 0x36987ad1, 0xef1b3d93, 0xd0b4af37, 0x5c1df6fd,
- 0xb567b4bf, 0xdc7e83be, 0xcc4d1b07, 0xbe5c630b, 0x88c3cfb1, 0x9bb60fc7,
- 0xdfe4de88, 0xcd8e4898, 0x5be3c1df, 0xbf791bcd, 0x72e36c1f, 0x5337e8ad,
- 0x9ebca3c7, 0x42c9f20f, 0xafcad3f3, 0x1e02ca79, 0x89b75d47, 0x9557cbf4,
- 0x53e45d53, 0x5f1455cf, 0x7aef4eec, 0x77aa8c58, 0x5ebe31f2, 0x7335955e,
- 0x196fd203, 0x03068c4f, 0x087d3fbb, 0x2c6569f5, 0x46d53bc3, 0xa712c3fb,
- 0x96c7ca07, 0x8a7e77fa, 0x6a515ff4, 0xde1e2073, 0xbf23f847, 0x78a44dac,
- 0x395f3cea, 0xab3e79c1, 0xdfcf3821, 0x356fa5a0, 0x2ddd386e, 0x9eb86733,
- 0xce6688aa, 0x7f477ab0, 0xef0a7402, 0xf928d599, 0xdb96126c, 0x42192ff6,
- 0x6b8d3b65, 0x6bfbd0a9, 0x8f8e8963, 0x4adcf0fe, 0x7799d3a4, 0x6eed0c4b,
- 0x42af75e6, 0x41bd57bd, 0xd6bd7052, 0xfb79bbfc, 0xc71ed0f9, 0x9c57f47d,
- 0x15ae809e, 0x8deafba4, 0xfd53f7eb, 0xfd82922d, 0x4e54dd1f, 0x57854276,
- 0x4b7cf466, 0xa001f91b, 0xd30f2897, 0x905395ec, 0x5857abee, 0x57d798ec,
- 0xc7a547e9, 0x661f9136, 0xc9a0c756, 0xb2516ed0, 0xe50e9112, 0xdea75269,
- 0x78f17a44, 0xedb57d39, 0x25903930, 0x7c8f4f2e, 0x6f4a825d, 0x90dbd232,
- 0x6f35bd10, 0xfd23322c, 0xebe3e07d, 0x5e908a11, 0x571f1e91, 0x262c2ae3,
- 0xe9523edc, 0x07e80ab1, 0xe8e5f4e5, 0xd3fa3bb1, 0x02f81dd3, 0xcee47eb4,
- 0x771a3695, 0x37ddaad1, 0xc47ce52f, 0xab459c70, 0x8179487e, 0xff1e4679,
- 0xeb88e156, 0xd24f30da, 0x2e0f1c65, 0x997fa733, 0xf1c6e8f1, 0x10d8e48b,
- 0x96e803fd, 0x01bac59b, 0xe5039443, 0x5698c4d3, 0x31e304a3, 0x51187525,
- 0xe14f0f3f, 0xc23979fa, 0x3325eb0a, 0x67281f5a, 0xacee081a, 0xa3d7c297,
- 0x876476e6, 0xa67b63c7, 0xb06efea8, 0x189fde27, 0x5851e50d, 0xff404db6,
- 0x5745a26e, 0x60a061ee, 0xbc516313, 0x5eca2a9c, 0x4c9d0328, 0x479f54cc,
- 0xd12f72f3, 0xebcd1bde, 0xc79f500f, 0xead5f2f0, 0x7f5e18f3, 0x99e7a334,
- 0x7013b129, 0x14cf573d, 0x237c66bb, 0xfd0d4951, 0x62d957fa, 0x6eb489a8,
- 0x9a8a6fa7, 0xaf146787, 0xf4fff976, 0x5cb5e606, 0xf90098d6, 0xe9d34e07,
- 0x867b30d6, 0x13ca7589, 0xa4b23d04, 0xae0bb238, 0x2f01bfc7, 0x26818c13,
- 0x06b06f6c, 0xb0573f08, 0xfbf7f615, 0xf65222e3, 0xdd05e7e0, 0x56a86bfb,
- 0x6ff30fde, 0x4b632725, 0xc524ae81, 0xe590f94e, 0x46db994b, 0xed4b94eb,
- 0xcc49bf68, 0xaf9cf869, 0xfbe17657, 0xefa8f1d5, 0x802e32ef, 0x7c2131b4,
- 0x1fa91b5c, 0x07675c75, 0xb798bc5b, 0xfd618ef4, 0x74e0c26b, 0xf08ae916,
- 0xe22264b4, 0x098daced, 0xac728bbc, 0x8447fcfa, 0xeaf1b3d7, 0xd64e5173,
- 0x95d74f3d, 0xa4febc4d, 0x78272b94, 0x64b3bde1, 0x6814a4e7, 0xd0c73163,
- 0x28baeaba, 0xbee5debe, 0xed17b764, 0x5a73a023, 0x32cde497, 0x76317f93,
- 0x5f0ce488, 0xd043315f, 0xb114b1f5, 0xaeb2d94e, 0x0ded05a6, 0x4196c3f0,
- 0x0ba5cf7d, 0x4c4f8c66, 0x9199b7f4, 0x401baaee, 0xcb15e26e, 0x68dd5798,
- 0xf75a4676, 0x56452a76, 0xf59a17e3, 0xfab2fbc0, 0xb9424cad, 0xafcb873c,
- 0xc7e3bb45, 0x39517961, 0xbd6ff7b7, 0x0438e766, 0x69ab9941, 0xb1675e25,
- 0x8a687dd6, 0x74517ea3, 0x4edc25fa, 0xd449ab2e, 0x03ad6794, 0x75c20e6c,
- 0xfef5da99, 0xa7b9e44c, 0xe30fd0b3, 0xde04d38d, 0xa5ada7a7, 0xb774f7bc,
- 0x44e73d76, 0x026332ff, 0x2246bb8e, 0xb8e6093d, 0xf066ed82, 0x6c35c219,
- 0x7dc0385d, 0x67d0a35c, 0x97ce5c95, 0xb4a97f0a, 0xdd17af82, 0xc2666597,
- 0x7f71f2df, 0x84d8fd6a, 0xa3f71421, 0x7f1efef5, 0xcfeb098b, 0x137e0258,
- 0x4ec97bf7, 0xda0ea598, 0x86e60ceb, 0xe3c61b8d, 0xe755fa45, 0x3ee50d35,
- 0xf5edc3ae, 0x10ed09be, 0x5d668f98, 0x6d0a8ce9, 0x5b46acb9, 0xf733afd6,
- 0x3b3908a5, 0x7e400d80, 0x19229adb, 0xf944ff89, 0x5791d674, 0xefae0a03,
- 0x194b6d74, 0x0747eb4a, 0x295ca1a1, 0xf9dca9bb, 0xe6a81cdc, 0xc78c07fb,
- 0x25cf895b, 0x26e5dfe2, 0xe310bda7, 0x0fdc5529, 0x35cf819e, 0x7d7806eb,
- 0xcb5dcb2a, 0xfee14d7f, 0x6b9b72da, 0xc12dc531, 0xc13cc54f, 0x98d3a358,
- 0x307c4790, 0x7b3c922d, 0xabffd05b, 0x8c15b40c, 0x25121fab, 0xe4dfa5e0,
- 0xcf8c3e1e, 0xb963fbf5, 0xfd53e317, 0x0aef000a, 0x779e05ca, 0xaef2209d,
- 0xb33e8037, 0x5c9fb5c1, 0xc7f48d3f, 0x176e66d5, 0x2aac7c8b, 0x6b8f9c4f,
- 0x7a13b1f3, 0xe50cf81e, 0xd61b0dce, 0xdb99ff92, 0x1ebf99c7, 0x8d9f77c6,
- 0xddbeffbf, 0xcea98fdc, 0x35f24fdb, 0xf4f229d5, 0x36ce4269, 0xe7559c82,
- 0x454df80f, 0x64fe87b9, 0x37bd1e49, 0x87bd73bd, 0x14a4e493, 0x1cf86318,
- 0x78aa57e4, 0x0a599def, 0x41652bc1, 0xcef384bd, 0x6865de62, 0x6819ff37,
- 0xd7abef0a, 0x533ebdaf, 0x56ebf491, 0x541d2067, 0xf58ab5a5, 0xdfcf5faa,
- 0xe7fe82fc, 0xf7d41ca2, 0xebe7d30f, 0xec4ced04, 0xf144b847, 0xde2e3540,
- 0xad917e9d, 0x30dc8d06, 0xf234a3d9, 0xad7f4265, 0xd0e899bc, 0x471b99ca,
- 0x9f3cd1f4, 0x79a01ce4, 0x40b8b93e, 0x1aea9e53, 0xcb7fa9ad, 0xd94d22b4,
- 0xa6bd7692, 0x49b94dbe, 0x7fee8e53, 0xac7ea6ab, 0x73cd36e3, 0x4ecf4bcb,
- 0x662e0093, 0x0dd5b7ab, 0xde03a870, 0xd2109118, 0xace2031b, 0xaa287eb4,
- 0x6c7e46c0, 0x004b60dd, 0x832ea4e9, 0xbcb0d3ef, 0x002d24b4, 0x6c7b58fd,
- 0xf5c216b7, 0x0c6f92f7, 0x62ac73c6, 0x7755f61d, 0xf95e8d33, 0x2be70665,
- 0xaa657af5, 0x5c1a687b, 0x9929b6f3, 0xf068048c, 0x358fc42a, 0x6bbb718a,
- 0x7437df17, 0x91cfea35, 0x64967ea1, 0xc54a0e15, 0xaf3b7776, 0x91b3bf23,
- 0xbd42fbd9, 0x91bf62cd, 0xda999777, 0x1ab635e5, 0xfdfc619c, 0x0f2e5487,
- 0xb98d721e, 0x32f8898e, 0x0deac3ea, 0xf7e8cdc7, 0x689bfb57, 0xd720e1dd,
- 0x16f7da71, 0x9af42fba, 0xd70a23b1, 0x1f553d3d, 0xc2e23d79, 0x6bcd3354,
- 0x65e390bf, 0x7f61644b, 0x2aa4f8f3, 0x7676cb97, 0x1b8c6404, 0x93e36954,
- 0xf20d397a, 0xded76359, 0x7140223a, 0x11d3900d, 0x0f5545fd, 0x3cd6dc80,
- 0x3af6859f, 0x7943275f, 0x9ae39023, 0x4553d3e7, 0xcb006b3c, 0x6fc275c3,
- 0xe7110cb8, 0x1e0cdbf7, 0x5dc37ebf, 0x087f7044, 0xc21216e3, 0x0e2f0f53,
- 0x69c1cbc7, 0x15bf9a87, 0x7bd7d2f8, 0x6be3832a, 0x3a723747, 0xceedca90,
- 0x1f3052cd, 0x15c7a885, 0x033af445, 0x2014a5d7, 0x0ab6fe1e, 0x67b2a8fd,
- 0xf4fa8625, 0xd12f4daf, 0xae33263a, 0xa438c24f, 0x6954bf58, 0x7fa19652,
- 0x40e0f400, 0x31baa6fb, 0xaaafe340, 0xfbc2682f, 0xce3c8d55, 0xf1e069e2,
- 0x4ad66acb, 0x6ee6dd7e, 0x2a6f75c6, 0x5207efa7, 0xc7bf1a15, 0xbd44ef0d,
- 0xf9f160de, 0x2b7fc424, 0x76ca57c5, 0x941d6c4b, 0x4eb6af37, 0x3d2f648b,
- 0xe2fde02f, 0xf5c3336a, 0x1ed095e6, 0x6b3fb1e7, 0x3be319bf, 0xca253b65,
- 0x5bea7867, 0xd6be62a6, 0xd0c4d8b3, 0x77c7508e, 0x7e482b26, 0x84739be4,
- 0xc787391f, 0xcc5cde2d, 0xee790fed, 0x9d57147b, 0xc8fc255e, 0x0e281739,
- 0xf08566f4, 0xb8f2e723, 0xd43bf4c7, 0x8e968ebc, 0xd3d53a55, 0xf56e9e9f,
- 0xe955faf4, 0xa76a4773, 0xf508319d, 0x1c7be03a, 0x1fdef1fa, 0x4c27ca32,
- 0x426cd4bb, 0x2af7bf3f, 0x281ee3bb, 0x2b7d940f, 0x9ace5e31, 0x95c1f3f9,
- 0x5f2e249b, 0x3e715b94, 0x86667599, 0x020239fb, 0x53c4014f, 0x43a94e32,
- 0x357e468a, 0x1ca37b06, 0x0175c1ca, 0xc1a7c700, 0xf949dfcf, 0x065f2e25,
- 0x69b6973e, 0xd6bd184d, 0xcaa2b908, 0xe66601bd, 0x017189de, 0xc6067d63,
- 0xf8987717, 0xd16c963e, 0x1d3edf5f, 0xb5c127e3, 0x65ffbc4d, 0x7fcb5571,
- 0x94fe10c9, 0x75c11673, 0x5da3c8a2, 0x8a5034bf, 0x744ec8f3, 0x6f315307,
- 0x12a47d99, 0xef5d5af5, 0x1fd0f397, 0xabc3d751, 0x91e6f471, 0x13bc6c1f,
- 0x32bb6be6, 0xdb69f08a, 0xf48edeb3, 0x243beb6b, 0x57de5235, 0x2a2e7abd,
- 0x53fc0dcc, 0x5d37b17d, 0xbda4f2d5, 0x6dfd68a7, 0x78dcffb5, 0x698b8fe2,
- 0xf76d5f74, 0x81ee3127, 0xf32cff62, 0x065e9127, 0x911c6cb9, 0xc2a7aa1f,
- 0x68e75d41, 0xf085bbeb, 0x3c1de775, 0x7ad8c1bf, 0x654667ea, 0xfd0e548b,
- 0x9a7262dc, 0x47de0062, 0x709b4c7a, 0xd5d71732, 0xc1c1b8f3, 0xa5c52b5a,
- 0x53b5ad5e, 0x469b5839, 0x156bd7e5, 0xec915eba, 0x34e104fa, 0xbe9ac5f5,
- 0xace6b708, 0xa7985d87, 0x44d07b3c, 0xaecc60f0, 0xc17de7d9, 0xea3c532f,
- 0x5f5f0342, 0xe67f8ea2, 0x4ee60cc5, 0x8a6371e4, 0x0bfd2c57, 0xc54739c9,
- 0xf7e8f1b9, 0x5b6cae0c, 0xd2cf6585, 0xee9d694f, 0x282fa03b, 0xe3c8d1ef,
- 0x2d8d55a7, 0xf4b9ceb4, 0xb3f50262, 0x1e31d0c3, 0x82fbccf9, 0xde3beb44,
- 0x4e673c69, 0xd288fae5, 0x7c451b3a, 0x3c5a4879, 0x1fe3c1c1, 0xe5f8e06c,
- 0x8245d579, 0xfaae9a1e, 0xc3e21c47, 0xf5a154ba, 0x6407d522, 0x19acb38a,
- 0x8f6711d3, 0x6e317720, 0xde93eb8d, 0xf494eb12, 0xbd99a7cf, 0xc07d717d,
- 0xfde44334, 0x50b48ecf, 0x75d71f7e, 0xc7f53297, 0x3f83d7f7, 0xca88eb43,
- 0x8ca745fc, 0x6ef9ad78, 0x196acff2, 0xfdf0c1fd, 0x320fe806, 0x34bdfbcd,
- 0xae564b7e, 0x85d6ef26, 0x98335bfe, 0xaeaa7802, 0x20173003, 0xd7455f9d,
- 0x2af7ddf6, 0xa8d637c8, 0x2f51878e, 0xf2067eb0, 0x5abcaa27, 0xe84b273b,
- 0xee0cacad, 0x89a7173f, 0x2fc2b2fd, 0x4267ff02, 0xe27ff71a, 0x5f8d32f6,
- 0x7e4fbfa4, 0xc7ec5591, 0x7978001e, 0xafb8c23a, 0xc2e318cc, 0x1d6cd976,
- 0xfa0337d1, 0xcfd2ba46, 0x1f1a4673, 0xd3cfca97, 0x28f39f91, 0xacfc4ece,
- 0x464877ef, 0xcfb40ce1, 0x5fb37756, 0xefc12aeb, 0xc1181b55, 0x8121b3cb,
- 0x6d8674e0, 0x7a018d70, 0xd8e3033c, 0xd678f40c, 0x878e8ae5, 0xaedd67f6,
- 0x109884e8, 0x886f57ff, 0x73ab76a2, 0x872c4a6f, 0xf7a08d72, 0x2b22c6f6,
- 0x06e679c2, 0xfbea77ce, 0x4f4c09de, 0x6a1a3e44, 0xde6330ea, 0x2dbfa7ae,
- 0xa1bbed0e, 0x222727bb, 0x4e3775ff, 0x779f3a77, 0xb445d2d5, 0xb87f155e,
- 0xd0a1627e, 0x3a7b9e63, 0xd57ca11e, 0xdbf44652, 0xd5afebb4, 0xfeedbfc8,
- 0x9e6bca68, 0x7a4d13d9, 0x3cd3ecf0, 0xd4c679af, 0xaa60eb4a, 0xf476cb77,
- 0x7c2f3d07, 0x9ff230fc, 0xa1459767, 0xdeffbd78, 0xb6aeb873, 0xad1d7fd2,
- 0xfedca8c3, 0xd541f2dd, 0xfec8bbd2, 0xd71fcb51, 0x37285d5a, 0x2e5c8ddb,
- 0x867c6c2c, 0x9785d9ec, 0xfcc20c2e, 0xff3d99ef, 0x98e50c3d, 0x86178fe7,
- 0xe7ec3ed1, 0xe7c30c2f, 0x6ba2e79e, 0xef25d922, 0x8e38f066, 0x0e731faa,
- 0x9ef13519, 0x73fe8209, 0xc62bac56, 0xb6864d73, 0xaf84714c, 0xd7da1b1b,
- 0x8617fb40, 0x389b1e1e, 0x8addac37, 0x392fdf20, 0xf46c65a4, 0x747a309c,
- 0xb8d49866, 0xd38ad7d1, 0xa11fb130, 0x34132e33, 0xd5843ed0, 0x6f3f2341,
- 0xa1f242a0, 0x8a7600ff, 0x4bd91dbe, 0xe44f6f67, 0x5d1832e7, 0x1d220613,
- 0xf697dedc, 0x75af3387, 0x3d986e5f, 0xa0683d34, 0xfcd3ddf5, 0xefd90096,
- 0xefad2341, 0x99a4ed56, 0xcd883ee7, 0x5dc42291, 0x0e3ebffa, 0xfe3eb6e5,
- 0x6ec6b3d2, 0x2fef0898, 0x08ecc15d, 0x063c7d3f, 0xfb9db17e, 0xf8d75992,
- 0xd07c128c, 0x5c95ed8a, 0xa7c71d83, 0xb78899da, 0x3efc0886, 0xb3f39d2d,
- 0x822b47ca, 0x8ac7c206, 0x2e6b18e0, 0xe789275c, 0x7136a00d, 0xff0ae8df,
- 0x1f18ade4, 0x96e97158, 0x9ef081e8, 0x626e8715, 0xdbbf20f7, 0x62fb58c7,
- 0xb7df4bbb, 0xd10bcd4e, 0x4a7dfe89, 0x2127d73a, 0x7eb2207b, 0xfbfc178b,
- 0xd8b9e95d, 0x3d6cfff4, 0x52757e07, 0xabf250fa, 0x07b8f067, 0xfaf5abf7,
- 0x6abb9541, 0x7e04e3bf, 0x53ddcabb, 0xff80bf64, 0x5c77724b, 0x7af542ba,
- 0x922527fa, 0x4a687c5f, 0xb5d312a2, 0x87463eff, 0x6baf2121, 0xe69daaff,
- 0x59f73af1, 0xf2717fd1, 0x8a6796fc, 0x90a493e4, 0x4971e75d, 0xa9649f7c,
- 0xd4f587c9, 0xf0a70571, 0xa754e9b8, 0xaa86f289, 0x87daa7fd, 0x3c1dcf9d,
- 0x8bdaa8af, 0x74185daa, 0x94ec38f1, 0x15f9fc21, 0x106beec9, 0xf588ef5e,
- 0xf247432d, 0xf6b98cfb, 0xcb747fa1, 0x7e2312cd, 0x4aa2f617, 0x527b7a9f,
- 0x1ddf6f5d, 0xba0a371e, 0x5b2bf954, 0x9eaa17c7, 0xba7a11aa, 0x2274f51a,
- 0x34cfe9ea, 0x5fbeb776, 0xf4aed3d0, 0x08c76c64, 0x1b0e43be, 0xeefc915d,
- 0x375fa213, 0x3dae0fe2, 0xe2162f83, 0x7058b378, 0xdd8bfa19, 0xb0974fe9,
- 0x5e7bba63, 0x5f9fc693, 0x08d78f8e, 0x7c577ffc, 0x9c3feabc, 0xbeed3b8f,
- 0xba23ce6e, 0x7ef0a332, 0xb928dba4, 0x7c885826, 0xc51367f7, 0x4af5f5c9,
- 0xff063e85, 0xfbbf4355, 0xf406ccb2, 0xdc153c77, 0x578bafff, 0xe4bf235e,
- 0xd5d69925, 0x0eff042c, 0x1705b3ed, 0x44ad74ed, 0x33ae183b, 0xfe50b5b6,
- 0x76854660, 0x831875fc, 0xe477f6c5, 0x32fc7ad0, 0x44e29636, 0x3b78fe65,
- 0x4baf23ee, 0x86f5a7ae, 0xb2b2adde, 0xedfebc35, 0x8f2b7d6a, 0xf74d2d9b,
- 0x6b79e72d, 0xab2fbe8d, 0x5af3dbd1, 0xc45a3ffd, 0x03b3ba7d, 0x71b26f9e,
- 0x26407279, 0x78c6aefe, 0x998cd5d1, 0x4bd5f5d5, 0xdaa39c79, 0x23f68cbf,
- 0x1fe78957, 0x4714831a, 0x5417fca2, 0x9f5fe53d, 0x9cc87c82, 0xd54f7cda,
- 0x2724c396, 0x849f79f5, 0x3c8f2e06, 0xf3c8b295, 0x7d68930c, 0xa7d8a363,
- 0x223728aa, 0xcc5c61dc, 0x863ee0a7, 0xce3fe413, 0xf325fdd8, 0x17f84e3c,
- 0x7fb3cf31, 0xf972a65f, 0x63754f3c, 0x84fd098b, 0xde7be5cb, 0xc38cef49,
- 0x97b09c50, 0x7b5fc791, 0xc63b25f9, 0xf5897a97, 0x4757c37e, 0xc77ff5f1,
- 0xdf2224e6, 0x9f6978ab, 0xfed9e1c4, 0xd88527e6, 0xa331d86e, 0x3e11d71d,
- 0xbfe2e6ff, 0xad32f264, 0x6c7f18d3, 0x25fa3471, 0x4516c7ed, 0x879f3c23,
- 0xb9e3e22b, 0xe3118c37, 0x78a1e589, 0x7bd205f2, 0xb2788b77, 0x6c5ef411,
- 0x6fa32e28, 0xd72153f7, 0x8adf30ea, 0xe79bb974, 0xddd2ebfd, 0x57f953d7,
- 0x13ff69bd, 0xbcc279c3, 0xc63a019e, 0x9800cfb8, 0x9f95e62c, 0x302b628c,
- 0xec9753cf, 0xe6f8997e, 0xf9050657, 0x7e53da06, 0x2153bbc8, 0x55a1883d,
- 0x020cc3cc, 0x7da563dd, 0x8f944979, 0x2fe04ab9, 0xf452fc1d, 0x5334610f,
- 0x403c8f30, 0x450663e4, 0x7ff62331, 0xe6bdc99f, 0x34ffcc4a, 0x88cb1d19,
- 0x93891de8, 0x85e6bb62, 0x77cf2724, 0x3521f9ab, 0x7e5dddef, 0x0cf7c248,
- 0xf945f4e2, 0x3094e620, 0x81e6ae1f, 0x4a2ecdd8, 0x511f2d4e, 0x7967e743,
- 0x9d37d8b2, 0x8b4a29ff, 0xa5719f90, 0x6bef6131, 0xfa6b81f3, 0xfa744d3f,
- 0x6b80f355, 0x71e9bfd2, 0xd5efdc2b, 0xfc487b8d, 0xa3f214f9, 0x3a77f9fe,
- 0xffb560b7, 0xb3bde902, 0x0e71161d, 0x938f2b45, 0x2f144dfb, 0x58fe0b38,
- 0xdd3e9872, 0xddfbc69e, 0xfa222feb, 0x8d8e086f, 0xc487fac6, 0xa687d5fd,
- 0xde7b464c, 0xfa3a341b, 0x7fb848d2, 0x0e3410d5, 0x1be4fb45, 0x7a694bc4,
- 0xa359f984, 0xf3d23eb8, 0xbfe09c51, 0xe70e0cb8, 0x5fb937a2, 0xf3cc59e5,
- 0x1d75761f, 0x73cf0d70, 0x914acfef, 0x6a77f8d4, 0x6ec8fca4, 0xecbd2ebe,
- 0x2df68976, 0xc8fcd97f, 0x7fb6c68c, 0x8fa23f2b, 0x219ddf3b, 0x790322f2,
- 0xdd23b9dc, 0xa84bf34e, 0xfb885c19, 0x7ef9d49e, 0x901f7083, 0x43e6edf9,
- 0xedf9efaf, 0x352fdff6, 0x837cdd02, 0xcb7d97fd, 0x96fc2ffd, 0xf52fbffb,
- 0xdb7f85db, 0xcbffdcb7, 0x8fff72df, 0xff07d244, 0xf5ebe6af, 0xfe7d78f9,
- 0xb7979f5e, 0x8bd734bc, 0xd695eecf, 0x6ae00476, 0x4d35db8d, 0x8c687902,
- 0xbd4562df, 0xe7923259, 0xb58f56af, 0xa14936fa, 0xaf0abe3c, 0x3fdc5991,
- 0xf39de7b3, 0x6ce356e2, 0x226c7067, 0x3246bbc6, 0xdacf6ff2, 0x198b1e78,
- 0xd798e9ed, 0x37e99a82, 0x67521d81, 0x7d079c8b, 0xf7f0a7af, 0x4b1bd1ba,
- 0xc8af0ab2, 0xfed5a64c, 0x59f648ce, 0xdb2f88ad, 0x17c5191b, 0xbf495199,
- 0xa4abde89, 0xe3d3fda3, 0x2e3f7e45, 0x689b9cc0, 0x4dce4a5c, 0x928f6e74,
- 0x407be383, 0xae1367e4, 0xf18397ef, 0x03b004e4, 0x1eb78f31, 0xa7e479f3,
- 0xfa9ea9da, 0xdc99ddbe, 0xc4c07a4f, 0xef305ce8, 0x11dd7c95, 0xbd9156b3,
- 0x0ee1e6a6, 0xcb27029a, 0x8dc3ca25, 0x62bff1c1, 0xce6de408, 0x449c4411,
- 0x3f296dfb, 0xdfc8eaf8, 0x7bd377f5, 0x86fecd14, 0x6187f466, 0x29ee771c,
- 0xb19dfa20, 0x6fed2477, 0x091ae4f0, 0x46fc5dce, 0x43780711, 0x38d431c4,
- 0x7a8f9a80, 0xde3fc45b, 0x3f4ab8c1, 0xa1584f3c, 0xc34caceb, 0x5a9e77bf,
- 0x159cfe57, 0x203d3f49, 0xf78fb8f1, 0x29f71e15, 0x84fa3b30, 0xccac7faf,
- 0x0f2c78e4, 0x1a83bcf0, 0xcc4279c7, 0x7287e0a7, 0x687602c0, 0x6681aac1,
- 0xab05ebd4, 0x3af0a2b2, 0xa433e9c8, 0xcfa7bc00, 0xf15069d9, 0xee8e8917,
- 0x89f114ca, 0x8f941d03, 0x9797467b, 0xd7c99ddf, 0x7165e41b, 0x64ceeefc,
- 0xafb3be54, 0x8b9a3971, 0xcbb1ae3d, 0x6541f291, 0x38e2f7e0, 0xb8f8ebcb,
- 0x05977855, 0x4f7c2294, 0x558ebedb, 0xc8afcd78, 0x79b8a229, 0xb455b9e5,
- 0x85d2e9bf, 0x1c52d7fd, 0xffa0accc, 0x1b55b330, 0xc5909b4f, 0xa0cfe7e3,
- 0xbb708dc1, 0x6ffe48ce, 0xa24675c1, 0x1b32849f, 0x2609a7f9, 0x7960c726,
- 0xf283b712, 0xb08a938b, 0x93c4a6cc, 0x407f97fd, 0x179b9f89, 0x5c256f8a,
- 0xe11938b7, 0xa8bcb974, 0x22bb271a, 0xa44bf9d9, 0x179aafdf, 0x88783aad,
- 0xf3aa7bd6, 0xe6a2e152, 0x8bcbbb37, 0x3c12ebaa, 0xd6689fc5, 0x1d8c7851,
- 0x58ae31e3, 0xaccda7b0, 0xcb4b37ee, 0x0b4de509, 0x7ca39f76, 0xf51f9aa9,
- 0x3b239cd4, 0xb199da1a, 0x3fa0017d, 0x4364e41d, 0xee9bcf2d, 0x1a7bfb12,
- 0xae78fe61, 0xfe601ff6, 0xfcc3f578, 0xb50bfef1, 0xa81ae9fd, 0x6f75d075,
- 0x7aba08ed, 0xcf28e7fc, 0x36a642fa, 0x8f99d75f, 0x084d5d93, 0x1d7cb0af,
- 0x3af9f595, 0x63c78a39, 0xee303f70, 0xb41cf21f, 0xf42efc92, 0x7f42f797,
- 0xee2d6fe0, 0x6aee385e, 0xd18597cc, 0x61d3bb45, 0xdb6c73c3, 0xe61b0e5d,
- 0x4e9a0ac9, 0x6a847ed1, 0x15ce9063, 0xa6073ce8, 0x775f1ce1, 0x21b42feb,
- 0xd79b2f7c, 0x79fffc6a, 0xd7932fad, 0x32f905ba, 0xf23f2439, 0x26e7065d,
- 0xda701ebc, 0x87c986e6, 0x179e2ed5, 0x9bdb9d59, 0x5741eff8, 0x6139f8ef,
- 0xe628adfd, 0xeb848a71, 0xf7e16d72, 0x79e2c89f, 0xb98904ac, 0xe4b1c922,
- 0xbcb8df9e, 0xef648e4e, 0xf402bfb7, 0xc3d03578, 0x5abdf9ee, 0x71b4ae89,
- 0x73c5d5b6, 0xdbb9e17a, 0xac2c37de, 0x69c38f2f, 0x974c6ce2, 0xde2eeb4f,
- 0x40d8a336, 0x7bc2e2e7, 0xeb5f51b3, 0xd8cc62e3, 0xb9f5cd91, 0xe4739c53,
- 0x582364cd, 0x5bdabc97, 0x173877cc, 0x362f4fea, 0xf3509e90, 0x46c5f96b,
- 0x99f40b56, 0xa3e4d4bf, 0xb1b15abc, 0xff0b9e8d, 0x3f3d8570, 0x3bc9e513,
- 0x8c76cd07, 0x60e3e9a3, 0x752de28e, 0xa3bda1bd, 0x6d7da252, 0x373fd65d,
- 0xf8c38d36, 0xaeb660d9, 0x1bd42c6e, 0xe3b06b9c, 0xe5cbe57a, 0x3d85f2e1,
- 0x219f8fa3, 0xa1fda15d, 0x2f5fa38f, 0xb0bd7ef0, 0xbf43ee97, 0x8fd43932,
- 0x2f4f4eda, 0xbe94f68f, 0xbf7f2e30, 0x71456fe8, 0xc45ceafe, 0xa1818967,
- 0x3c5158de, 0xd61b9ac6, 0x234f595f, 0x7986af5f, 0xbcf0a4bd, 0xe9dfcf1e,
- 0x3caa79f3, 0x8cfa682b, 0x083efff6, 0x95f51972, 0xffc78d27, 0x3c285e0b,
- 0x34227280, 0x1f9fae4e, 0x37bf534c, 0x7c6788e0, 0xd14fb45e, 0xb8a247bb,
- 0x27c97e5b, 0xcca1a37b, 0x7fb4f15c, 0x773073de, 0xef939e39, 0xc50e3129,
- 0x971e3afd, 0xc22799d4, 0xd7e4d07c, 0xf5c7ae2a, 0x075305fc, 0xa67e20b7,
- 0x9d689a96, 0xa6d7e4de, 0xaae539d1, 0xba982b9e, 0x7c289ee9, 0xf3a25fde,
- 0x56bf261a, 0x4f9f063c, 0x88c01ed8, 0xb3889b38, 0x3c193907, 0x7c88d278,
- 0xfbb24572, 0x0537c827, 0xa89e4493, 0xa9e3eb94, 0xc62649fe, 0x7e8d46ed,
- 0x1bface6c, 0xf3d479c5, 0x7d711204, 0x2f485e42, 0x7d01ec15, 0x57d21b15,
- 0x7a9eaeff, 0xe09da7b4, 0x2be83579, 0x24c24f1c, 0x62ef4f9e, 0x77fc08bf,
- 0x93ba7fa7, 0xc467a8bb, 0x529983f9, 0xad7d575a, 0x38673c60, 0x9d12e5da,
- 0xfd1dd683, 0xcfec26bd, 0xb6ec6ef8, 0x76fd04d7, 0xf1a9aebb, 0xfd13c9bb,
- 0x787fe7b9, 0x57f8489e, 0xf548be6a, 0x7b09fac7, 0x215ebd57, 0x7b7fbbfc,
- 0xd12a013f, 0x1209fb88, 0x9827ef22, 0xbda12f59, 0xd827eea4, 0x3b856667,
- 0xab3d7093, 0x73e44fd8, 0xefb41d91, 0x7aad6fd7, 0x7bce893c, 0xa0cc6dc0,
- 0x9f485af7, 0x43fd8157, 0x63ff92f6, 0xe7ad3f1e, 0x1aabb1eb, 0xd496fbb5,
- 0x5f616ceb, 0x50f9858f, 0x77ac459e, 0x91ce2f1d, 0xef21c508, 0x21c78632,
- 0x59304a3d, 0xe3eb475d, 0x5c4d1779, 0x6438bbb2, 0x75a0eb35, 0x9215d5b3,
- 0xb7c3f503, 0x91ec971d, 0xddaf5da5, 0x83cb9327, 0x42496e69, 0x706ad5fb,
- 0xf8bad255, 0x6c7ef817, 0x66fa7c3d, 0x413c7971, 0x331e31e4, 0x6c787a73,
- 0x5bfb4494, 0xe21c1f70, 0xf817b1f9, 0xf2c7973e, 0x35173ef9, 0x5feea16f,
- 0xb79432b9, 0xea6ffda0, 0x1f7517be, 0x780fba8b, 0x00a886d2, 0x99f707da,
- 0x1db8d3ea, 0x3c3a25eb, 0xf3d193dc, 0x6f3f0b28, 0xf8ce3f5d, 0x28c3c2ac,
- 0xf37f0f87, 0xac88d176, 0x25a67108, 0xaffc2fc2, 0x98fb2eac, 0x30bffb54,
- 0xfec6a86b, 0xfedeb2a7, 0x16f2a6ff, 0x6f9f0141, 0x32abde70, 0xe6f8ddbf,
- 0xfc72df67, 0x7b247cfa, 0x4b88b976, 0xd9e7e9e9, 0x68bf552c, 0xbac34bbf,
- 0xfae43fec, 0x8e524ebb, 0x2f6bb9d2, 0x542573f1, 0xcb175a39, 0xe4215ffb,
- 0x547d7aa7, 0x914ceb5c, 0x884f5fe3, 0xe764b3e7, 0x0193a472, 0xc8f1b4db,
- 0x78daf581, 0x098dd5e4, 0x40e0f29a, 0xc17ea686, 0xe79ade81, 0x69578343,
- 0x237f0f9e, 0xd91e535f, 0x7f534a3a, 0xb46387f4, 0x68755ae7, 0x5ed791e3,
- 0x2fb749bc, 0x2bf047d2, 0x6f0dca04, 0xad9d6457, 0xa15997a9, 0x8d56579d,
- 0x96bd5e76, 0x2fcee826, 0x78e6fde1, 0x53ebf3b5, 0x025f9da7, 0xbef2d3e6,
- 0xd4cd3e7e, 0xecf7a153, 0x61b1f7f5, 0x738a07bb, 0xa99f686d, 0xc1db99fb,
- 0x6411786e, 0xffb69fdf, 0x9cd7d696, 0x06eda279, 0x79e6cf3a, 0x0379e199,
- 0x5963dbed, 0xa3e3de80, 0x34162873, 0x661ef4c8, 0x1c9b0c0c, 0x9d1afe76,
- 0xe9f28f4c, 0x911258a9, 0xf8b69e0b, 0x82fda04a, 0xe106275d, 0x7bf692fe,
- 0xfbcb3e78, 0x31f14484, 0x841d6de6, 0x60584bdf, 0xa89dfc8c, 0xbcb8b2d7,
- 0x9a3bbd3b, 0xdb49ebd6, 0xbf52669a, 0x3098b7f5, 0xdbd6a69f, 0xa849fc2f,
- 0x3d3df7c7, 0x5e77d12e, 0x71e17c70, 0x27bbf54d, 0xfae71fa7, 0x89a3416f,
- 0xb059efce, 0x9e3b676d, 0x0de0bd57, 0xe65b9d0b, 0xf48e76d9, 0x3b53d16a,
- 0x469ece08, 0xd5a8bd99, 0x8273da57, 0x5db8f1b7, 0xe9154375, 0xff932841,
- 0xf91f5d55, 0x9dcbecbc, 0xa9f0bb67, 0x00bcbb3d, 0xfccf85c2, 0x1ee30e2e,
- 0xc6b7051f, 0xedbedf91, 0xeee9cf8b, 0xfd702e72, 0x173c2fea, 0x03fc23f8,
- 0x2cc5cbe4, 0xdbcab9dd, 0xa9f7c512, 0xf7c2c302, 0xe8e087f9, 0xf1de78e5,
- 0x6e7823e9, 0x3fa7e9fd, 0x5bc7047e, 0x8f0baff9, 0xadf498fc, 0xc3728ecd,
- 0x3a61c4f3, 0x976d5bf7, 0x40e5cd90, 0xa3bfe3fb, 0xdfdbd2f3, 0xb7b038b4,
- 0x641f3df6, 0xefb77d23, 0xe3052cfc, 0x8cf78b5c, 0xe2f078a3, 0xf0be8b67,
- 0xb7486b7b, 0xe3e17ebe, 0x3e7375f2, 0xcd5f16b1, 0x38d9cd0d, 0x6f8033ce,
- 0x9e75f38c, 0xc55f5cf3, 0xc456cdcf, 0x23dbcef9, 0xe5df8b9f, 0xc986e73c,
- 0xed0f7e37, 0x2e7e069e, 0x75cf65cc, 0xbc78043e, 0x6fe04bfa, 0xbe716afb,
- 0x9dfc6449, 0x4f003fc1, 0xb9ed6c8e, 0xcc369fce, 0xf8d7f47d, 0xdbb121ac,
- 0x5f039d73, 0xb9ea6e02, 0x72ccfffb, 0x3e46ce8e, 0x74f7fa7c, 0xade2368e,
- 0x3a73c144, 0x7f46cd3e, 0x075343ee, 0xb1d72b9d, 0xefc762c7, 0x73d82d37,
- 0xfda7f894, 0x64b71e59, 0x76fbfce2, 0xe7e3f9d6, 0x8a988b95, 0x3f2c4b67,
- 0x1fc05a0f, 0xe2568bcf, 0x1738bee8, 0x7ab1d39a, 0xe777745e, 0xeeca2f44,
- 0xf89cf5cd, 0x96d5401e, 0x9fb99abf, 0x3497c21a, 0x7fe9f682, 0x2adbf9e1,
- 0xbfc2ec1c, 0x96dbc4eb, 0x7771e7c8, 0xf02f8f9e, 0x73c3f885, 0x35cf3a3c,
- 0x5435f287, 0x08b28e96, 0x137da0f2, 0xbdbd2f3f, 0xeea9fd1b, 0xd6caaa0f,
- 0x6798a9f1, 0xf2a1fc77, 0xffc6e5e9, 0x3333e155, 0x8bd0d15b, 0x97d3a70a,
- 0x75f1cb22, 0xb6bfef82, 0x62ece3fd, 0xf48fdcff, 0x66d0d558, 0x44d9fbe6,
- 0xf7cc547e, 0xf4dfd834, 0x6427a4fd, 0xd557e3b2, 0xd71c9337, 0x6eea8bcb,
- 0xb39b6df2, 0x7153bac5, 0xa7e9c14e, 0xefb87d63, 0xdddef4ea, 0xf6effd7c,
- 0xfa17b336, 0x19edbfdb, 0x721b8f33, 0xe13d41fe, 0xe9ff1b0b, 0x91069b27,
- 0xdd66eedc, 0x8f78bd77, 0x3df91fc7, 0x34e7ed9e, 0xade859ef, 0x72efff27,
- 0xe8c8fbef, 0xfbfb05bc, 0x3bf7c828, 0x4ffb847e, 0x17ffbc23, 0x176126d9,
- 0x22eb13ae, 0x3f03de41, 0x9ee02bbf, 0x3cf5cbd6, 0x9d1999c2, 0xe3be1083,
- 0x2725917e, 0xaf979f01, 0x7fa8ec95, 0x4c18af67, 0x9ccf9274, 0x89652744,
- 0xfa937bfc, 0xe6cf1cf7, 0x1ab6fc7a, 0xc3fa4313, 0x280cded3, 0xb624eb7f,
- 0x3197fb86, 0xe7425313, 0x6ead56d1, 0x0abc2389, 0xef3d533f, 0x3e66a2b6,
- 0x39fd07c9, 0xdeac9538, 0x2d6fe78c, 0x2dcfcb58, 0xa38b9fd4, 0xcf5dab97,
- 0x85fb5a89, 0x956df672, 0x81cc1cef, 0x07e7377c, 0xd7e456b1, 0x4a68f0ae,
- 0xb3ca05be, 0x07a4c80f, 0x2eb0b854, 0xebcbfddf, 0x7f3cf881, 0x973f2fa0,
- 0xb152515c, 0x3c1e9cde, 0xdd19282e, 0x597ef1c3, 0x19b87ba2, 0xb19beae5,
- 0xb596c7b8, 0x7c50345d, 0x36595980, 0x59d9938e, 0x537db876, 0x60a7b26e,
- 0x16cbc4de, 0x58fc51a5, 0xeb0addff, 0x1eff20da, 0x157bf683, 0x5f9c8965,
- 0xeff3763a, 0x1e46b1ef, 0xeb32b6bf, 0x9c778c32, 0xe0a5d652, 0x95ae5411,
- 0xc53dfe26, 0x4714f1ed, 0x91456db8, 0xba5fcf19, 0xf69e21ad, 0x93af30b5,
- 0xe2a8cfbe, 0xc1456db1, 0xf7e834fe, 0x871cfab6, 0x269fc5ac, 0xaea0bc1e,
- 0xc9dbc54d, 0x64ede0cb, 0xbe01bc24, 0x7a13f734, 0xeec5f169, 0xe94cf6e6,
- 0x62fafb1d, 0x0d7ceefe, 0x77631eff, 0x340e92f2, 0x35c5094a, 0xe33a338b,
- 0xef4829b5, 0x250ed617, 0x55f1e9bc, 0xc3d9affc, 0x7b337f71, 0x05ce962b,
- 0x66c3eb2e, 0x6ff184dd, 0xd953f389, 0xa316262f, 0x8bd01ade, 0xb56bfdf3,
- 0x82d9fe3c, 0x787ecff1, 0xca9dba6e, 0xf3fc4587, 0xe13fc628, 0x3fc626fa,
- 0x7c527ae1, 0x33e5433f, 0xd7a20020, 0x7f38bdc1, 0x8925ee0d, 0x34e2ddf8,
- 0xff8a4bb4, 0x73f38b25, 0x61637d7e, 0xce878d0c, 0xa3fef9cb, 0x7bd1bebf,
- 0x3a37630d, 0x69b4f1b5, 0xb4f1b453, 0x663915f2, 0x736fd7f4, 0xa3d4d68d,
- 0x0f5abc88, 0x925e98ba, 0x337e79a8, 0xbfcc34be, 0xf0a5ee2f, 0x1f7147f8,
- 0x4b5bbd4d, 0x2a5bdfb5, 0xb3c668bf, 0x62dbd985, 0x26b3309f, 0x87bfc219,
- 0xf1ca4402, 0x3e6de762, 0x416e3a31, 0x60e4fc7a, 0x5e7284b2, 0xaf150f8f,
- 0x080037b3, 0x1b39dfa0, 0xbd97940c, 0x55e3b66b, 0xaeeccf3c, 0x7bf7f8a7,
- 0x467bae4e, 0x39805df3, 0xbf84994f, 0xa1fb2763, 0xf232c568, 0x607dca3b,
- 0xcb88022f, 0xa23ef45f, 0x467e3196, 0x0f91594b, 0x80bec90e, 0xe2727844,
- 0x4fbd83f7, 0x7e47eff0, 0x0ed86208, 0x2b7677fa, 0x1287c71f, 0x53e5815b,
- 0xfdfbb7b6, 0x6675e600, 0x0679bae2, 0x307c8dc4, 0xd3e2e499, 0x2cfa4332,
- 0xe744c3bd, 0x587ede39, 0x31f4efa6, 0xc5533f29, 0xd9cbe62b, 0x1dfe1613,
- 0x04a00e9b, 0x71f8b7a8, 0x8f9f7d0b, 0xcfcb0328, 0x11adf40e, 0xf2f48874,
- 0xc6733c61, 0xfe7960d3, 0x6496a3e0, 0x82119f5a, 0xce106f9b, 0xfae09bd7,
- 0xa3a02f51, 0x06f9e68f, 0x3bbafc91, 0x0f47f899, 0x2e6693df, 0xef48bc9f,
- 0xea2e4852, 0x26d996ed, 0xc7df7d07, 0xa3a486cb, 0x96b93a5c, 0xf40f477f,
- 0x3f5f1c4a, 0xabd134f3, 0x46939efa, 0xef8e3c65, 0xe90e5d64, 0x0ad6dbaf,
- 0x06f4137f, 0xfae3efaf, 0x46ecbd6a, 0x275bc3bb, 0xaf9db9b9, 0x4db78fa5,
- 0x688b9ede, 0xd68db1fd, 0x6809dcaf, 0x9dca3cc5, 0x2ec9533b, 0x5bec2998,
- 0x2ddbc696, 0x3b3a73b6, 0x0f4fa07f, 0xea7ad7dc, 0xea01e010, 0x75f3a7b4,
- 0xacc6a705, 0x3747861b, 0x1dec369d, 0xffb803f6, 0xfbef44f1, 0xc8dbc046,
- 0x5ee6f76c, 0xac329f18, 0x4473c6cd, 0xfc4fface, 0xf50fbf1c, 0x83930ed1,
- 0x97e974d8, 0x0c4ed3b3, 0xeb835d8d, 0xf2eb67c2, 0x3f042704, 0x5bf8293c,
- 0x8b6fcfd5, 0xa7036cf2, 0x2482f63f, 0x34c46bbe, 0x9e217872, 0xe4872a43,
- 0x2b872aa5, 0xc7fadd85, 0x3e6edc5e, 0x60a5d6c5, 0x4fa005bd, 0x3b3cfef1,
- 0xb72a4bb7, 0x7ee7eff1, 0x4c9c7c84, 0xf5c31a7d, 0xe4167cf2, 0xea014e7a,
- 0x77dd0949, 0xc0388b45, 0x409fbe3a, 0xb9e7f72f, 0xe06ffb7d, 0xa3003bfd,
- 0x7cffe45d, 0x8f1b1ae6, 0x3c6deb71, 0xff97ac9e, 0xb9b7e84c, 0x3d7a7de2,
- 0xbbe85730, 0x377d3ab9, 0xce8e71cf, 0x0edca91d, 0xb2b945ef, 0xc2efab4e,
- 0x9a44a9e6, 0x872f3ce7, 0x873f3cf7, 0x769d7bcb, 0x08fda30d, 0x3d59dc2a,
- 0x77b4d3fc, 0x791c61c5, 0xc33283fe, 0x78aa1cef, 0x823e66a8, 0xb02cc7f7,
- 0x8f18ed0a, 0x062e31bc, 0xa1f0ba70, 0x2dc7ecbf, 0xa06b944a, 0x7efef3f3,
- 0x9427b3bf, 0xa4b2f37b, 0x6f7efdfc, 0xd570aecf, 0x829bf1c3, 0x6ef9131b,
- 0x9863076a, 0x377f85bb, 0xc91eac3a, 0x0901fffb, 0x00d0a8f5, 0x0000d0a8,
- 0x00088b1f, 0x00000000, 0x3bedff00, 0xe5557469, 0x73dcfbb5, 0xe1dc8487,
- 0xc2040464, 0xc06e49b9, 0x612f4865, 0x1213d41e, 0xde0d4b22, 0x00c10580,
- 0x86120137, 0x7c07504c, 0x0040e3e2, 0xaa1a4583, 0xf50af8a5, 0x22d28342,
- 0xb04a0834, 0xc141170c, 0xd6de8ba7, 0xa44f7d6a, 0x40932861, 0xd2bb6a52,
- 0xf7b79457, 0x3b939df7, 0xed83a404, 0x58b593af, 0x9ef37efb, 0x77f7bdbf,
- 0x52015000, 0xaaa8e601, 0xd08eceb5, 0x092bd00c, 0x72c06e60, 0xd80e35b6,
- 0x37fc0ddf, 0xbb746b7f, 0x01e5e696, 0xf7473754, 0xa41c5fe3, 0xbfe6cc01,
- 0xff5616a1, 0xd845cc41, 0x766f3d12, 0xe890eadc, 0x556679a4, 0x086e17eb,
- 0xa1e6ca0c, 0x840cfada, 0x9f12a24d, 0x6e0f351b, 0xca7a01b8, 0x7773948e,
- 0xde0bc361, 0xc5c2221b, 0x002300c9, 0x5c78174a, 0x439c1cfe, 0x2186f77f,
- 0xb09e7468, 0x39cd23c0, 0x098a6584, 0x68c79cf0, 0xb1c6994f, 0x477f788d,
- 0x617c67e2, 0xc1864ef6, 0x15483f08, 0x3a6f3c54, 0xeba236e1, 0x71eb15be,
- 0xdf8841e7, 0x11f8137a, 0xcbbf5b9e, 0xfe3e47e9, 0x695dc5fe, 0x88772b04,
- 0x66084410, 0xdcf015bf, 0x2f65f582, 0x56fb833f, 0xdaf78d6c, 0x88e2bbb0,
- 0x3c7008bf, 0x252b7c0f, 0xe3d7971c, 0xe070c341, 0x71dd8445, 0x8428f23d,
- 0xdfd982fd, 0x513de68f, 0xd927efe1, 0xd187faa3, 0xf4cc4fbe, 0xee3f7cff,
- 0x04b6c4fb, 0x9248caaf, 0x44e1a682, 0x84041489, 0x7b7f0bd5, 0x04fc8cd2,
- 0x9e8f83f1, 0xf2b8014a, 0xb6c408ba, 0x817f24ec, 0xcfdc4a9c, 0x703d05eb,
- 0x5d29b89e, 0x22f6c4ca, 0xeff9ecec, 0x8d4ce7e7, 0x4fc4e59f, 0xd599e914,
- 0xf3a50e1f, 0xbe70374f, 0x4d99face, 0xf397a7e3, 0xe7e73573, 0x339f8d4c,
- 0x7e35788f, 0x4f892bca, 0x9f8d6af2, 0xeace1c0d, 0x3a7537c2, 0x4fc4f5e1,
- 0xa7155e6c, 0xa60f885c, 0x173f909a, 0x4f508a76, 0x12a80b6d, 0x4485c3da,
- 0xdf511250, 0x3f8d04ff, 0x7e610a0e, 0xe50ecdce, 0xd29e9106, 0xc49d47b5,
- 0x453bb9d7, 0x3f2c704e, 0x73eee941, 0xc81f9e44, 0x24d53c25, 0x087942df,
- 0x408aa5c0, 0xb7fbe12e, 0x825a7df2, 0x79e3e522, 0xde2dfbed, 0x36efc8cd,
- 0x85c01587, 0x8384f676, 0x227265c1, 0x3a81679b, 0x505f3c00, 0xf8845814,
- 0xdd3e50db, 0xb2159e90, 0x5905c6cc, 0x87ec5282, 0x7e13200d, 0x24288282,
- 0x1d2fed75, 0x3e462283, 0x814c3bb5, 0x67ff48cd, 0x3c80d0d6, 0xffaf187b,
- 0xe913b192, 0x03c835f8, 0xd252bce8, 0xccafc235, 0xfc8cd815, 0x6c4c0879,
- 0x0cc087df, 0x982708a5, 0xd8713541, 0xba224f60, 0x3fa85990, 0xf1bf35e3,
- 0x7410e1ed, 0xef82af21, 0x3fae7081, 0x73a55d30, 0xc14d0726, 0x1e0fe87e,
- 0x090f0732, 0xb2714d08, 0x7c73c245, 0x913c84e3, 0x660cb0e4, 0xf15decf8,
- 0x21f846db, 0x1326a5bd, 0x8129ebc7, 0x0a28f1d1, 0xdd32f89d, 0x8444470c,
- 0x4439e28f, 0x5904b4f7, 0x0816f365, 0xa30ccdde, 0x54df8614, 0x2881bf0d,
- 0x4bc87387, 0x0df76ddc, 0x3547d3d4, 0x069f707c, 0xf1cf5b27, 0x1edf9588,
- 0xad004f8d, 0xcd6be256, 0x227fef63, 0x71359d20, 0x49f920f6, 0x6e5cb168,
- 0x39f9afed, 0x48afe1e4, 0xc05f384e, 0xf4f90083, 0x04db06a8, 0xb87b3bb4,
- 0x1e0d21ff, 0xa5ace8d7, 0xde0bca36, 0xdc5b0212, 0x03e73fb7, 0xd3ad8939,
- 0x3b0347f7, 0x1026e34d, 0xed6bfc80, 0xb2562dfe, 0xbf5a79bf, 0xb22187ee,
- 0x5dacde2d, 0x169f912a, 0x41ba6fc0, 0x8b3edad0, 0x13dc2958, 0x7afb25ef,
- 0xa1ecdad4, 0x5e76277b, 0x5874df2c, 0xef53805c, 0x3e75f9a0, 0x03c03465,
- 0x0bdbd3df, 0xcbda0a7c, 0xe39de1a4, 0x8e164a8d, 0x8e7f177f, 0x7828e864,
- 0x452fc133, 0xd7253ede, 0xfce39685, 0x8a728f0a, 0xdcd39ffc, 0xa0fecc0a,
- 0x58bbf191, 0x28061324, 0x28a37d1c, 0xb858f911, 0x6c9e605b, 0xe636e8ea,
- 0x50f13a77, 0xd478619f, 0x76f413ec, 0x71bbc148, 0x36ceeeea, 0xb070a3c3,
- 0xf27c6a2b, 0x9f1a8868, 0x1be91d78, 0x6a71b5a9, 0xd194f488, 0x4a8d9ff1,
- 0x235b6c6f, 0x42dae3e6, 0x4ba74f3a, 0x65ffef0e, 0x835f19e0, 0x9d75d199,
- 0xcc5075f9, 0xba6101be, 0x91df665c, 0x5dff223f, 0xe2a48229, 0xfc5f1aba,
- 0x6117f26a, 0x3d181a7a, 0x8f9d78a1, 0xf1a37cd1, 0x06bfa442, 0x8d55f1f4,
- 0x67cdf20a, 0xd2af9cea, 0x3f3ab1fc, 0x337f7d70, 0x7d6c4973, 0x4686a6d2,
- 0x9fa61ed5, 0xbe18b3b5, 0x7c21ee49, 0x295fd339, 0xc42f48ff, 0x4ef906b3,
- 0x5ca74557, 0x5f8c75d5, 0x6d1131a1, 0xa62337c2, 0xff022ddd, 0x52fc11de,
- 0x59f949d7, 0x7cd2f811, 0x8b4a67c4, 0x127fbd10, 0xb4ddcf1f, 0x1d1d51ae,
- 0x90fc036e, 0x5e8227f1, 0x9d299fc6, 0x9be75ef2, 0x6ac7eb85, 0xfee019fc,
- 0x45e88fa1, 0x7d3972fa, 0xd2fd2881, 0x65bcaef5, 0x14b48aed, 0x2004b38a,
- 0x68f2c37a, 0xe7fc91f2, 0x9bff3a4b, 0x586f8442, 0xa13dbc1e, 0xa9bf3f59,
- 0x64abf491, 0x6f2f4eb7, 0xf70bf587, 0xbff216fb, 0xea7c7a21, 0x53f5e8f2,
- 0x667f73a0, 0xf53a5357, 0xfa43cf17, 0xbcfc69e6, 0x4853537f, 0xbf76fae5,
- 0x67ac353b, 0xad12b365, 0xed85bf74, 0x6be31b71, 0x93b8de27, 0xbc0fe380,
- 0x07c7cd1f, 0xb27b79ea, 0xc1af9b7b, 0x4d7ed91e, 0x7764e3e7, 0x7d72bd94,
- 0xc4fd1df9, 0x4024f37b, 0x161fbd94, 0x4487dba3, 0x437baf9d, 0xa750e58f,
- 0x1f5efe7e, 0xfc0fb7dd, 0x719f1a30, 0xc7bdbd36, 0x6fe91857, 0x5f1937d4,
- 0xf9f4fc74, 0xd7a25f45, 0xddaaf3c3, 0x729afa6f, 0x320cdee8, 0xc49a56ff,
- 0x71c75c21, 0xb56a47bc, 0xbf68a938, 0xbcd00be8, 0xc2cf416e, 0x873d309c,
- 0xff99169e, 0x8085eb56, 0x196cfd07, 0x04ba56c8, 0xa5628267, 0xcb90f5fb,
- 0x9c15e8b5, 0x7169f87f, 0x3df70051, 0xc59928b9, 0xadb81f9b, 0x5d87ff8c,
- 0x6366d37d, 0x0cc250fb, 0x0ef38cab, 0xc1963b3d, 0x7fe93bb7, 0x337a47d7,
- 0xc9a5ce2b, 0x97e65df9, 0xf6f0250e, 0xbedbf72a, 0xd5af28a5, 0xe7ed996e,
- 0x5ad2924f, 0x39e13f50, 0x09916c0b, 0x098fef4f, 0x6de7b2bf, 0xfc239f03,
- 0x4695de96, 0x41ff2ef2, 0x9c4f5149, 0xe2c2be57, 0xab5e7015, 0x7c274a49,
- 0x658dcffd, 0xb96b30fa, 0x18fbd506, 0x4fd5f83c, 0xcf749dea, 0x1c58146e,
- 0xcd17f773, 0xbb62e7ef, 0x4bd321b2, 0x30e81ea8, 0x9ce78481, 0x202fdf5e,
- 0x899dcaa2, 0x3c777baf, 0xbf340f9f, 0x7c7cbaf2, 0x2f9a60fc, 0xfe70cb4a,
- 0x7017ec39, 0x712adcfc, 0x397840b3, 0x2404dd1d, 0xc097dce9, 0x2b73f0ae,
- 0xb865816c, 0x7fbb69cf, 0x673a7afa, 0xd29605bd, 0x93d7413a, 0x4e5f198f,
- 0x3f5cba4b, 0xa1cfcc6e, 0x2dbd3679, 0xca9f2195, 0x157a9d4c, 0x2aefbc04,
- 0xb5fb7912, 0xb6f91f4d, 0x2f73fae0, 0xaaf163f5, 0x276ca19c, 0xa19d3d7d,
- 0x3ffb20ec, 0x462ed5f8, 0x3c4bfb5f, 0x51d03b6e, 0x111e569e, 0x315c5427,
- 0x68387d33, 0x7c231f95, 0x23eb760f, 0x6a2f2ca8, 0xf8a12e4e, 0xe28cf511,
- 0x45ebd46d, 0x1f126ebb, 0x2645ba36, 0x4ddf43af, 0xea472d1d, 0xf9867ab7,
- 0xde64e289, 0x6d6eea3e, 0x9cafd154, 0x33822db5, 0xfaf5e159, 0xe8aef9fe,
- 0x39983938, 0x81d128e1, 0xca30c679, 0xeb7cf453, 0x0733f533, 0xf533f1c9,
- 0xe3630653, 0x43a74ad4, 0xde7fe725, 0x1c9330e1, 0x9c979a4e, 0x62b938a3,
- 0xb9f985a3, 0x8ba98d8a, 0x414e29db, 0x5740f17d, 0x2c32927a, 0xda5b9e8c,
- 0x2beedaa5, 0x07191dec, 0x5dad7fb4, 0xf36a6eb6, 0x6d6fd935, 0x5b129597,
- 0x2d1b4503, 0xcaabb23e, 0xa0330e21, 0xf1b31cbf, 0xefa42d9d, 0xf3e20b95,
- 0xe578886c, 0x53931b46, 0x4aa1c3ab, 0x3a77ee38, 0xaf0889cc, 0x6e8c4dba,
- 0x60cc8657, 0xb8e60881, 0x5397063c, 0xf10d711e, 0xc5f6c649, 0xa3ac2f45,
- 0x0412e4b4, 0x3d430d26, 0xfd70a6bd, 0x0c5bb6bc, 0x66047e50, 0xf98c5cc5,
- 0x7ee01cd3, 0x5dbdfaa2, 0x39fc7cd6, 0x41f2aea7, 0xf9f965c8, 0xfcfc98e9,
- 0x8e1e7474, 0xfe51a61b, 0x30aaffcd, 0xc43b24de, 0x5e6a3d7c, 0xd51e7e44,
- 0xf2d0c96f, 0xa3c83ceb, 0x9d5aee38, 0xdd829b25, 0x13da3b4a, 0x41b059d2,
- 0x2e56f860, 0xc4360312, 0xe79920b7, 0xa0976747, 0x5e8caddc, 0x2576c255,
- 0x37c4b1e5, 0xf8710210, 0x0b0dbef3, 0x1767e4cc, 0x4ca57e6b, 0xdbe91f00,
- 0xfa6f7899, 0x36c78a02, 0x56be33c6, 0xc7ee78fe, 0xd6bae12f, 0xa229c5a5,
- 0x5e87d61c, 0xfee03e9a, 0xde149710, 0x67d2fce7, 0x0bdf49d2, 0x4857ee5e,
- 0x22657871, 0x26e298ec, 0x974cf539, 0x9579e1ed, 0xe6ce9ecb, 0x8083e2f3,
- 0x2ad970f1, 0x6f01d191, 0x521e02d8, 0x4520fec8, 0xf2d66df2, 0x1cd6acf7,
- 0xd34a5bfe, 0xfc991ee2, 0x9c5faf37, 0xced171c6, 0xc676a7f8, 0x066ff8bd,
- 0xf993d5ed, 0x57d13f09, 0x4c66126a, 0x5bb4fb60, 0x328b8ec9, 0xb7701e78,
- 0xbdd2cb06, 0xea8f09d3, 0x32ef3635, 0x1c47df37, 0xb181e1aa, 0x5429b54d,
- 0xf3c223f1, 0x0b779b4d, 0xbc796dc9, 0xb924ef12, 0x0e7af282, 0xad98c7ab,
- 0xa72fb449, 0x76e64ab3, 0x989ffd8c, 0xc1dabfb1, 0x227560fd, 0x15cedbf2,
- 0xb7fb84c4, 0xbe4cafd1, 0xf0dccf5f, 0x85f3cefa, 0xb99df8f0, 0x49e4afc4,
- 0xdb1e108f, 0xc8af6645, 0x29c3358c, 0x0e2ed96e, 0xf1a64e7a, 0x57e445c3,
- 0xc81cefe7, 0x1db2b6e2, 0x617bb21f, 0x56e726be, 0xc7296f2d, 0x33844ef6,
- 0xf8bdb832, 0x666ba845, 0xe8bf9e6d, 0xabc7d6f2, 0x9c985957, 0x937fd1aa,
- 0xfa5ea8e3, 0xb56fb65b, 0x79469423, 0x961bf556, 0xcb6fe4a1, 0x97cbfc35,
- 0x09fd19f6, 0xc5b94fea, 0x543dd125, 0xa95b16a5, 0xb028d55d, 0x6a5d7876,
- 0xe7e3e93a, 0x4938f7cb, 0x07c4ce4f, 0xb4df743d, 0x52f7882f, 0xc0da887e,
- 0x97cf93ee, 0x873f367b, 0xc85259ed, 0xacf8e021, 0xc89332c7, 0x82949f2f,
- 0xd93f1a56, 0x5b5136ec, 0xd4d1a491, 0x62dfcc56, 0x55d1cfed, 0x43fa6b35,
- 0xe046a5fe, 0xed7aacf2, 0xcf0335b0, 0xffc9a95b, 0xb30ff6ca, 0xa756cfc9,
- 0x397db287, 0x14d9de4c, 0x04cfc2ff, 0xbcd6df76, 0xba60ebc6, 0xde486bbc,
- 0x34f35f68, 0xdeecd739, 0x7de924f3, 0xaf3bc90d, 0xdea0beab, 0xaffd611e,
- 0xbe022a6f, 0xc5e908fe, 0x53cc7899, 0x05b97b79, 0xbcacc7db, 0xbfe6acfd,
- 0xf790bfb0, 0x4f3c39ab, 0xac6b79e3, 0xbe4adfbe, 0x263f244d, 0xa7f31b0f,
- 0xadbd1a4d, 0x9270deab, 0x3f6caefc, 0xc1c8eefc, 0x57e61784, 0x5ef44df2,
- 0xd12d47e3, 0xb3f864ef, 0xe896a1b8, 0xefe98675, 0xdecd73d4, 0xa7d3816a,
- 0xd66b5bd3, 0xb5c7d7e8, 0x3a345bf5, 0xd7e340ab, 0xbedc7eee, 0x7b227b34,
- 0xa749fca5, 0xd7c49fcf, 0xbef9faeb, 0x4d6edf46, 0x766a414f, 0xbe487f12,
- 0x7f5067e4, 0xcd50eb14, 0x2b94e06f, 0xfcb1373b, 0x8e979751, 0xfbe1a7ff,
- 0x0a4c4942, 0x04d5b1cb, 0x5ded9a73, 0x1a23c5ef, 0xe8ad4f1f, 0xfc82de9e,
- 0x06f31cfb, 0xbea36e96, 0xd3ce239a, 0xaf3f46f5, 0xfdc95b60, 0x86600eac,
- 0x9fafed20, 0x304d527b, 0x81273ed3, 0xbf8e87db, 0xf505976e, 0xe81feed3,
- 0x1c5779a4, 0x37443999, 0x0cd3ff3f, 0x5457ad89, 0x4af3f307, 0x7010108b,
- 0xebc094e8, 0xec56a782, 0x84e79671, 0x327ffdf5, 0x62ff4e84, 0xa78aeb4e,
- 0xfa117fae, 0x782cf0cc, 0xd4fdf276, 0x7a16f4fe, 0xd74df3a9, 0xca9c584f,
- 0x3d5893e2, 0xca7dedad, 0xf6c5e74a, 0x19caf1eb, 0xfec97bca, 0x10faf2f7,
- 0x5923872c, 0xeeb0f711, 0x0ecff1d7, 0x84f7c343, 0x65e72f7e, 0x2efa3066,
- 0x1f35b341, 0x85d578fd, 0xa6539150, 0xf5644fb8, 0x08bfbba0, 0xb3d42e8a,
- 0xbceeddaa, 0xeaad7bc8, 0xa7a611f2, 0x756210d5, 0x1f55b2cb, 0x7d230f16,
- 0x45c629fc, 0x8c5757e4, 0x3d5c52b5, 0xa1cccb77, 0x0dd3e724, 0xb8badefc,
- 0x142bc87c, 0x786e9f17, 0x0e666d21, 0x1a282bad, 0x6b65fd89, 0x9e393207,
- 0x53150f89, 0x1171fdbb, 0x6a358ea8, 0x53c590cb, 0xd1ca3db1, 0x39e89137,
- 0x8e1624d9, 0x2cfb908c, 0xa54f1690, 0x92eccc78, 0x6a4e0ec8, 0xc2deabfe,
- 0x933bd2e5, 0x277279eb, 0xa0bafee4, 0x44db3ebe, 0x7e84db7c, 0xc5aee913,
- 0xd507a018, 0xff1e054d, 0x5c42b1cc, 0x1fd63ccf, 0x4dfb13d7, 0x09aa2709,
- 0x13c7b6ff, 0x4ddbaa24, 0x883781b3, 0xfb0769ed, 0xa6e851e4, 0xc6287168,
- 0x9d5cecab, 0xbdf9fa4f, 0xc51eb932, 0xf5e20bee, 0xc76fa4a1, 0x19d63ab4,
- 0xcb8bef0d, 0xee893a7f, 0x3d5b8ba5, 0xf9f74449, 0x140df1fd, 0x70b79cc7,
- 0x7fefa57f, 0xd88f77bb, 0x77d88ef7, 0x0c65800d, 0x189901af, 0x6740253f,
- 0xe3eba4fc, 0x70baeaed, 0xcdd78d22, 0xfaf53db5, 0x5ecd1ffa, 0xd64de257,
- 0x12f2f0e9, 0xce365864, 0x9e083aa3, 0xe5f0985f, 0xd9c510ae, 0x86c9368d,
- 0xbd259ef4, 0x86fab6c6, 0x1481eac8, 0x9f9e9313, 0x8050637d, 0x138ab7f2,
- 0x2cd15dbc, 0x7884a804, 0x22b3ed64, 0x718d9fcd, 0x2221775e, 0xed717d6e,
- 0x6bff5224, 0x9ecaff5e, 0x56daff38, 0xe037bd81, 0x5e263db0, 0xfca7b77d,
- 0xf5578bef, 0xe754bffc, 0xa42ef6bb, 0x57cf5bf3, 0x0c5ea20e, 0xedf30bcf,
- 0x2c3992ea, 0xc4bcbd5e, 0x709b60cf, 0x5628cd6a, 0xbab176e7, 0x5e5a2fef,
- 0xdc917b10, 0x4ebc0f77, 0xbb48e779, 0xbdbb224b, 0x401164ba, 0x63abad36,
- 0x5ebb9750, 0xf77bb9df, 0x6aeeb621, 0xa37da0cb, 0xbb01dd70, 0xcee7f98b,
- 0xf79892f7, 0xbc58ef91, 0x7dd913dd, 0x7451dfc1, 0xd772ebf9, 0xded4abe9,
- 0x2ffc7445, 0xdee5c53d, 0xd33aded9, 0xfa1ef449, 0x11bef251, 0x9704ef24,
- 0xb9da7144, 0x5c5fdcf5, 0xf2bd7388, 0xc2fbca20, 0x80698986, 0xa1f6727e,
- 0x7f512787, 0xa2417ec5, 0xbfbbdcf8, 0xd3f949c4, 0x4eadcdef, 0xbf7ef3ca,
- 0x0abf7f5e, 0x469fe488, 0x3489838e, 0x0cd0647f, 0xe233ee32, 0x2337ae41,
- 0x0a039b2e, 0xcfd83bc5, 0xbbd716ea, 0xfe05bab1, 0xfde09725, 0xaf2f7b39,
- 0xd072e873, 0x1a51adf3, 0x9333079d, 0xfeb4ff38, 0xffbce182, 0xe35d86fc,
- 0x4d8bbf69, 0xbef08916, 0xfb6164da, 0xc93cc3cf, 0x5b33ef44, 0xed421e79,
- 0x37d93778, 0x35e637cf, 0x7aa37cf3, 0xbab14581, 0x4167eaba, 0xe7ca3cc4,
- 0x73a64fb0, 0xa7fa6ae7, 0x853cedeb, 0xef0f37d3, 0x5637a235, 0x99a1138f,
- 0x4edddbbd, 0x3d56ff9f, 0x37e31dde, 0xa982584e, 0xef9f8993, 0x77565e89,
- 0xe87e85b9, 0x403f257c, 0xc3ebac7a, 0x0517d43c, 0x079a9287, 0xea3e93e6,
- 0x9bfba1fa, 0xa5e35bf9, 0x2dfe51b3, 0xdb5daa31, 0x1b3a53d2, 0x7a69e719,
- 0x99823908, 0xe9d2abe8, 0x535d6b8b, 0xf8a6b082, 0xc421150f, 0xafe88473,
- 0x9152a4f0, 0xc05e8bef, 0xc69ed964, 0x642091de, 0x061ef601, 0x6a17ff4c,
- 0xa2b1b075, 0xe519bfbd, 0xf3742a58, 0x96d93e52, 0x2e4d50ef, 0xf9327796,
- 0x04253e96, 0xc44ffb00, 0x9ea9733b, 0x0e420330, 0xbb3fb637, 0x464d7643,
- 0xf5ebd5f9, 0x2d63b56a, 0xe65767d5, 0xfffb5a8b, 0x3aa8944a, 0x8afdffc8,
- 0x530f20ea, 0xffb5943d, 0xf6f5425a, 0x71b477b6, 0xe3425eb8, 0xab402b6d,
- 0xdbc57d8b, 0x85c7d03f, 0xdb5fb409, 0xe45c7d2a, 0xfdf5e7ed, 0x98daf6b5,
- 0xe331a5f1, 0x1ff6f12f, 0x504e227e, 0x88f5c273, 0x9ef7b527, 0x7d5a65d2,
- 0x8336f4c2, 0x93df2cf6, 0x1d17cf54, 0xe7941d67, 0x27947914, 0x7bf0dde9,
- 0xcd7ffd7d, 0x44af3844, 0x9f78ad50, 0xd9026fc1, 0xda75e7c4, 0xe1ffdd7c,
- 0xc9bac83c, 0x6f3439bc, 0xcb3cd448, 0xda7de6cd, 0x376ebf75, 0x89e2979b,
- 0xe77f4fde, 0x9c56e29d, 0x278f5f34, 0x94afef62, 0x8c471e2c, 0x699254ca,
- 0xb40b239e, 0xe9bc42b8, 0x16615a3b, 0xbb4a038f, 0x99b677f1, 0x32711d43,
- 0x37e431e2, 0xf9077afe, 0xbe3c0db3, 0x98efb57a, 0xf41fb43e, 0xc757be8e,
- 0xcc43ef21, 0x3cb3b5af, 0x86fb8ff2, 0xd1bfc8b8, 0xebaf24db, 0xea9f7da5,
- 0x759dc5ee, 0x67dfbea6, 0xacb74def, 0x409df543, 0x5f71a875, 0x66f3bd71,
- 0xc93efcf5, 0x01b0da75, 0xb48fc8dd, 0x25effba4, 0xbb0da63c, 0xf9da88bb,
- 0xaef662b6, 0xefafa3dd, 0x6b3fea1e, 0xa1089e52, 0x6346fb3e, 0x7f611b20,
- 0xa2130a13, 0x983f0fda, 0x3d844a0c, 0x57b87a4e, 0xd291fb54, 0x53f9a8cc,
- 0x3515dd67, 0x0d0b6c5e, 0xf69c7966, 0x78ab7cce, 0xc61df3a2, 0x9f3debc1,
- 0xc7d3fbed, 0x6a1fa28f, 0x5d59126b, 0x2dfeee77, 0x70828f1f, 0xec46805c,
- 0x74bdfb22, 0x93ca044c, 0x5757eb63, 0xb46eb420, 0x80f135f0, 0xe5c58474,
- 0x8d1fa8ff, 0xc6a34bc8, 0xfb4567a7, 0x1f756bd3, 0x23180ba5, 0xac7568d5,
- 0x594f7b2b, 0xbbff5e65, 0xeafd0371, 0xde90b47d, 0xfe903b3b, 0x2d7fa841,
- 0x38adaca7, 0xe64b23de, 0x05ef4779, 0xe5007966, 0x4acc0b11, 0xa1171e84,
- 0xbea8b81d, 0xde3f71d2, 0x83474878, 0x74d7d6c2, 0xb8bb5898, 0x5465b4d7,
- 0xc336aa6f, 0xc754dd80, 0x6e2c1d90, 0x7df9fe2a, 0x67e580e3, 0x63f74282,
- 0xe7c2a355, 0x4c1ebf8b, 0x1db1b0f5, 0xc53ed8e3, 0x50131c22, 0xe0281f37,
- 0x31d5d17e, 0x76d7f581, 0x6e0f9b00, 0x54ace2ff, 0x7144aefe, 0x29aefe6f,
- 0x72888985, 0x86795bb2, 0x2297ebf4, 0xfbbb222c, 0x86f7bde5, 0x5f7a1494,
- 0x32283418, 0xc59358ff, 0x6a400ddf, 0x5df74ebf, 0x990481ed, 0xc5eac8e4,
- 0xb7ed0f14, 0xec7c77b1, 0xda90f567, 0x94cdb603, 0xdb3ad5e7, 0x0afec9b3,
- 0x8907c60e, 0xe307438e, 0xcdbf2ccd, 0x73a1aff4, 0x2bf60e0b, 0xd9537ca4,
- 0xf3033367, 0x98f7ca63, 0xca589e3d, 0xd25d3ae4, 0xea37fb04, 0xbfbf6c63,
- 0x4cabf381, 0x872ebbe3, 0x7eef8d72, 0x1a659f8d, 0xdf1067df, 0xc5f2ee91,
- 0x587b6fc8, 0x29a2c52e, 0xb260fd7b, 0xca5e3e8f, 0x15bf743f, 0x8eaaf7cb,
- 0xeaf7c638, 0x7c9a1e8e, 0xa1c945bb, 0xb58323bc, 0xdb7dba07, 0x7ae2ce89,
- 0x5fee2f94, 0x287a0f6e, 0x17519a3f, 0x87f7a5ef, 0x45dd8b6b, 0xab85d7c4,
- 0xfee6e1b0, 0x8ab5ee8b, 0x74add4df, 0x4a65c844, 0xb8c82e47, 0x2c8ec4df,
- 0xebed5f06, 0x2e724bdf, 0xcecf18eb, 0x66c8ef29, 0xa95c62e7, 0x23fef8b0,
- 0xfbffbe3d, 0x20b9c7be, 0x21811b30, 0x75dfca8a, 0x26ef3602, 0xcbfdfc21,
- 0x54238c4c, 0x1696673c, 0x5b650e7f, 0x6c9b7f22, 0xf8424381, 0x72ff18fb,
- 0x9da86a91, 0x3be5d7f6, 0x678c7c99, 0x26e5dd70, 0xd543930b, 0x950f5fa1,
- 0x9092fc70, 0x4eec9ddf, 0xc47ff24d, 0x810995ee, 0xcf6c161d, 0x73977e7f,
- 0x8fd61c84, 0x43d07366, 0xf919a67e, 0xe6b5f548, 0x00b8e2d5, 0x942667af,
- 0x9eb5b80c, 0x83b8ebcc, 0xb79febf1, 0x286b4dd3, 0x66cb869f, 0xed879796,
- 0xb78ef375, 0xb8127f48, 0x6ecadcfe, 0x58912cf7, 0xbf6b167c, 0x959eddba,
- 0xf9227ffd, 0xcfadbbde, 0xfee11fe0, 0x584a5363, 0x99ef1cbd, 0x87583ca8,
- 0x7f31eec9, 0xb3b7f9a1, 0xcac7bb6f, 0xcf6b12f8, 0x6db37d7a, 0xb2019dff,
- 0xf68093f7, 0x2fb47a4f, 0xd9a2de41, 0xdd07f33b, 0xb3af815c, 0x339951f7,
- 0xddef14ed, 0x9e1ddec4, 0xdece6fd4, 0xf23939bf, 0xf85201bc, 0x1c846afb,
- 0xa43d50d7, 0xc9852db8, 0x2e9b9751, 0xba7e5d47, 0xfd963ebc, 0x637d1177,
- 0xd775fdb6, 0xd55762ff, 0x53073deb, 0x793b767c, 0xfee1e3dc, 0x8f285ff6,
- 0xf7373c7b, 0xfe7af7bf, 0x7e8bff09, 0xe26ec072, 0x5bc3a64f, 0xa3f9872f,
- 0xb741e3cb, 0x2433d8bf, 0x68241fcc, 0x6f4fd530, 0x9ee98fc7, 0x99fefc6f,
- 0x67fa0b7e, 0xfff433fc, 0x1292f9c3, 0x78b12f9d, 0x49e50466, 0x5527963e,
- 0xfc83bd53, 0x4fe818df, 0x15bd59f1, 0x9aa43e58, 0xee4979ba, 0x42d97625,
- 0xc5259771, 0x3afd216b, 0xbea211ea, 0x48f56bef, 0x2496087d, 0xbd0ddfe8,
- 0x128cf2cd, 0x43cb4997, 0x30f6f30e, 0x09bdfc7d, 0x0c94d794, 0x18e1c6d2,
- 0x6c089f1f, 0x472df9fc, 0xcdb25e59, 0xfc20aca3, 0x4c48f05e, 0x74b7173e,
- 0xfde7e3ef, 0x5747c40d, 0x04bbffb2, 0x5676ad6b, 0xda136b4f, 0xc3b91773,
- 0xdfb57ff3, 0x8817f271, 0xaca3c877, 0x502f79a1, 0x12352231, 0x16ad79f2,
- 0x84e6f748, 0x5601cbfb, 0xae58bdd0, 0x6044fd1e, 0x1c3c1df1, 0x1fbe9437,
- 0x959f7604, 0x35b1dfeb, 0x06c77f44, 0xb3e3175e, 0xfea11dfe, 0xb09de09d,
- 0xd7bed25c, 0xf92370db, 0x866ce4eb, 0xafdf1173, 0x2e9059b5, 0x22efd757,
- 0xff477d85, 0xabd6fb42, 0xf2cf1ad0, 0xd7efe8d9, 0x4f3013aa, 0x7b287e45,
- 0xca3b411c, 0x04f6e171, 0xab986756, 0xa47b8fd7, 0x31f44bb0, 0x3d03d389,
- 0xfd7dd8d2, 0xe74ba6b8, 0x2cff4097, 0x6fcdc533, 0x1e23355f, 0xeff1f66f,
- 0x99543925, 0x285f483e, 0xdea45d53, 0x95d0f749, 0x4a97a21d, 0x9d5a5530,
- 0xb5529a1e, 0xbc188afa, 0xb98fc717, 0xf54cdcef, 0xfe1ec3bd, 0x0dd9714e,
- 0x5d519dec, 0x10b6936a, 0xa70fd72e, 0x71ed8d3f, 0xe979f719, 0xcef2eefd,
- 0xa366b367, 0xc05ad01c, 0x00fae2c9, 0x36c1675b, 0xd2b91f7d, 0x96ba42fd,
- 0x4220fbbf, 0xbb9f3a1e, 0xa28f1ff0, 0x0e29bdfa, 0x09dede98, 0xc78a241b,
- 0xa58c3975, 0x838a53c7, 0xc8efe0de, 0x6ce8050b, 0x3e725c53, 0x5dfbe78e,
- 0xb0ef8beb, 0x52cd017c, 0x6cdbaa8d, 0xfcf37998, 0xa5602522, 0xbae9bfad,
- 0xf68f25e3, 0x06103e4e, 0x791deff2, 0x9b52a35d, 0x952c5633, 0x6a4f44cd,
- 0xbfe4979c, 0x77666370, 0x7c3043f2, 0x83ce441d, 0x2f4cc90d, 0x1845ba56,
- 0xb7367a8e, 0xfba4c905, 0x160ee5a8, 0x92d83df7, 0xe313a0c4, 0xf8bfea4e,
- 0x7983fbca, 0xa7cb871d, 0x63eed5f8, 0x6afb1c58, 0xf563063f, 0x4fb9fcd6,
- 0xd84b77a1, 0x123ab023, 0x75ca12f9, 0xc7563d75, 0x6eac8378, 0xeec096f7,
- 0xbf9b293d, 0x75495463, 0xd20e1dec, 0xc22f2c7d, 0x2ec94b25, 0x6cddf45d,
- 0x8faeff12, 0xf7dacce5, 0x3e4d4eb1, 0x7df9d009, 0x881bef6c, 0xccb67277,
- 0x3d208bbf, 0x264949c1, 0x5cfc9bb7, 0x393fb66a, 0xe6bde29b, 0x9f54459d,
- 0x4aea0b9a, 0x13d94770, 0x6ae848dc, 0x77b497a7, 0x2b0f5d31, 0x852173b5,
- 0xc6855feb, 0x3e8d4ad6, 0x2b5418cb, 0x4772cfa4, 0x377ae6f6, 0x80fe8691,
- 0x1f0adf7d, 0x40fe3dfc, 0x3f7407bf, 0x2cf535fd, 0xc7d2cfc6, 0x7ce3ddb9,
- 0x0ffd175e, 0x511f5021, 0x6faceac7, 0x77b0233d, 0x326ebd6d, 0xbd0a0ccd,
- 0x095422ef, 0xd2f7d296, 0x8598e104, 0x62e38b9d, 0x8cc3ab12, 0x63ebfc62,
- 0xd39d5952, 0x9830ebce, 0xfd43dc27, 0xbf66ead7, 0x7920f8cb, 0xc51bf7d9,
- 0x6c4f5e36, 0xdf644f7f, 0xee8add1f, 0x555e5af1, 0x6f62e07b, 0x5f71dbb2,
- 0xf7e27e89, 0x11e38b71, 0x67c753ca, 0xf197f7f3, 0x9828a6d9, 0xe98bfb2e,
- 0xea3b3fdc, 0x5f909ba6, 0xc167be7f, 0x8771df2b, 0xae887ae9, 0x40a7ba2c,
- 0x4d3e90b6, 0x371de504, 0xf06df56e, 0x5064f6b3, 0xf7496c19, 0xa54eca4f,
- 0xac0310ef, 0x7dc47c7d, 0x8b125eac, 0x655e2c7f, 0x2c5efcd9, 0xc14536cb,
- 0xcfdfb271, 0x5e1852f1, 0xd1365fb8, 0x24f5e3a5, 0xdfea4ee9, 0x88555f25,
- 0x7ccaef90, 0x02d7df91, 0xf2c3afbf, 0x25496b1d, 0xbd108ef9, 0x0c17ab4c,
- 0xe0f48479, 0xa5eadd9a, 0xbe5d3b77, 0x9bde8108, 0x638e72c3, 0x88ba52fa,
- 0x6c91cbeb, 0x6a0baf37, 0x580e4772, 0xf942ae28, 0x9a7c4d3f, 0x75e44237,
- 0x3fe50938, 0x4addc980, 0x82995e36, 0x2ae8cf72, 0xde2d5adf, 0x66e2d1ad,
- 0x66f51fbd, 0xeae9f105, 0x89fd61de, 0x4607b53f, 0x7a9fc4c8, 0xd4dbcf13,
- 0xd0ead6ff, 0xa38bc99a, 0x47ef62ee, 0x297af660, 0x45be2aff, 0x9355b29e,
- 0x961ef1cb, 0x5fb60171, 0x4076bbf4, 0xa6809fd3, 0x9c70ff57, 0xe2a21fd5,
- 0xffa211ac, 0x754fe265, 0xf32b55dc, 0xfe7bda63, 0x19b37a56, 0xd11fd612,
- 0xb26ff0ea, 0xf5cbe247, 0x55f9f506, 0x44e7ff5a, 0xa64ce7d4, 0xef28e7cf,
- 0x75e56e3c, 0x156456e7, 0xff107ffd, 0xccbbfccb, 0x3e9a77f0, 0xbc512b06,
- 0x8042e704, 0xbad0f9c1, 0x9fce1072, 0x469658d8, 0xfc9854f8, 0xa2ad3eec,
- 0x3be9bc2f, 0xec2f681b, 0x76fcfc81, 0x7a77d2c3, 0x5e538a20, 0x5c285b74,
- 0xb041b49b, 0x97be40f4, 0x41582d34, 0xb78fb46d, 0xb70f4e48, 0x0ee77a6c,
- 0xe39d17ec, 0x8f1c7d98, 0x1cac5391, 0x45fc6b0e, 0xd39b787b, 0x70ba30a5,
- 0xa1ed4dfd, 0xe12bdd06, 0x01ffffa5, 0xd5b93efd, 0xefd023ff, 0xe3781b15,
- 0x7a6ec8e2, 0x3fbfcc83, 0xf3e7f68f, 0xfa27df80, 0x923afa7e, 0xf397dd20,
- 0xf4979ba1, 0xfb8592ea, 0x807d4bcd, 0x0125c1d9, 0xf0bcec2f, 0xfee906fd,
- 0xe199791e, 0xf4d6a37b, 0x39f92e5a, 0xc77e57bc, 0xe699e2fc, 0xe4dd0395,
- 0x64e903ff, 0xd99f96af, 0x735ff5bc, 0x9510ccbf, 0x80ceb4d3, 0x01a03406,
- 0x0340680d, 0x0680d01a, 0x0d01a034, 0x1a034068, 0x340680d0, 0x680d01a0,
- 0xd01a0340, 0xa0340680, 0x40680d01, 0x80d01a03, 0x01a03406, 0x0340680d,
- 0x0680d01a, 0x0d01a034, 0x1a034068, 0x340680d0, 0x680d01a0, 0xd01a0340,
- 0xa0340680, 0x40680d01, 0x80d01a03, 0x01a03406, 0x0340680d, 0x055ff01a,
- 0x328d1fff, 0x800060f6, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00,
- 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
- 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
- 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
- 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
- 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
- 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
- 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
- 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
- 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
- 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
- 0xee017e3f, 0x0014ab55, 0x000014ab, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x00001000, 0x00002080,
+ 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380,
+ 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680,
+ 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980,
+ 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80,
+ 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000,
+ 0x00010001, 0x00000604, 0xccccccc1, 0xffffffff, 0xffffffff, 0xcccc0201,
+ 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x00088b1f, 0x00000000, 0x62f3ff00, 0x51f86063, 0x408cc10f,
- 0x7f120cb6, 0x66476028, 0x48107d08, 0xf3e2061f, 0x2fe9a48c, 0xb9b04160,
- 0x40afec80, 0xa8597833, 0x88a1bee7, 0xcfd2738f, 0x81ae792e, 0x66322ff7,
- 0xe86067e6, 0x6ff047e4, 0xb3caa3f2, 0x3dd7d3f0, 0xb000c6b4, 0x00eeff4a,
- 0x0000eeff, 0x00088b1f, 0x00000000, 0x7dd5ff00, 0xc554780b, 0x3d9cf0d9,
- 0x3764dd97, 0x2485cd9b, 0x200d8410, 0x125c40a2, 0x126e20ee, 0xc3116088,
- 0x65e28145, 0xb201ae41, 0xdb3f6911, 0x5cbb7ffa, 0xc6d6a444, 0xa0b45b4b,
- 0x06a2828b, 0x82482459, 0xa5c8ba1b, 0x5835b5b4, 0x0da978aa, 0x24c4dc88,
- 0x97f4b004, 0x3bef3fca, 0xce7bbb33, 0xf4bc4c6e, 0x7d6f9ffb, 0x7339867c,
- 0xef3bccce, 0x6779de7d, 0x313b10a2, 0x0ae42775, 0x64246efc, 0x19084c99,
- 0xbbc32d14, 0x32413cbf, 0x46bcf909, 0x08f39a75, 0x86a1d929, 0xc5f5a46f,
- 0xd400a41b, 0x0893bb4d, 0xd3484819, 0xcaf7563a, 0xa08e8f0d, 0x4ca764ed,
- 0x8482d136, 0x4592266d, 0x610b09c8, 0xd60a673f, 0xeab126e7, 0xee7b0de2,
- 0xd7e7fe82, 0xfd12499a, 0xec8d44fe, 0x4d92fa86, 0xb4488052, 0xad21eebd,
- 0x5e7fed0b, 0x39260a40, 0x63d37d69, 0x9085339a, 0x6cbfbbe5, 0x5c057182,
- 0xe2167c67, 0xbfbe00d4, 0x23f63565, 0xadb03ca4, 0xa7ed0bb4, 0x99725abc,
- 0xebe538e8, 0x038df0a4, 0x9014b9e1, 0x370bbf69, 0x0fb3895b, 0xc10ae183,
- 0x4b1e7171, 0x6971d3d6, 0xd2a9447f, 0xe3a252ca, 0xf19cfc09, 0x4471c5ad,
- 0x744bf17d, 0xc55dfa1c, 0xa60b92ab, 0x9e226158, 0xa9bf1d20, 0xf3da692e,
- 0x32df9836, 0xec4a77ad, 0x0ebe663c, 0x6c0f28f3, 0x006d4ad0, 0x6e6d06d7,
- 0x0b7f68bf, 0x0f56ff37, 0xd99edad7, 0x6376989e, 0x5147c679, 0x2f5a3bda,
- 0xb41dc427, 0x6d01fc01, 0xf3e8ff62, 0x908d295a, 0x4cbfd04e, 0xff68969c,
- 0xb9f1f884, 0xc0615c4c, 0xb8a5093b, 0xead6e962, 0x496dd3d0, 0x0db6ff1a,
- 0xe9c97e78, 0x81cf98f0, 0x1cbe13e5, 0x73e57f2c, 0xf1bf9c22, 0x29f2c1f5,
- 0xff9f0b9f, 0xcb1437d6, 0x96373ef5, 0x62c6facf, 0x8657c1b9, 0x9bef3def,
- 0x9f26e586, 0xe8bf9f07, 0x4be58f9b, 0xfe7c4abe, 0x2c7eef8a, 0xf8fcf8b7,
- 0x356fab7c, 0x557cdb96, 0xf4e76e58, 0xe00be1da, 0x9b7d3b7b, 0x05f3acb1,
- 0xbe1bf9f1, 0x017f2c5a, 0xaa65a478, 0xa14cb1db, 0x4d1d4a74, 0x484d941c,
- 0x32d95946, 0xa633d695, 0xa7b67ab0, 0xf146996a, 0xd69b3d94, 0x2b731d29,
- 0x6999961b, 0xd652ee7b, 0x58efddde, 0xddeda16e, 0x9ef6b257, 0x93cb6555,
- 0x27cf7b68, 0x8135fb59, 0xb4c9e5aa, 0xac8d9afd, 0x61b06fbd, 0xf7b695b9,
- 0xd7ed61ad, 0x6c2b1d87, 0x3efd7eb4, 0x286c2f56, 0xeb42915b, 0x7d598785,
- 0x0ad56348, 0xc87efd3b, 0x88fdf671, 0x4ceca096, 0x55db1fc0, 0xd2843dd7,
- 0x52fed7ee, 0xd68c32b7, 0xc47dd735, 0xff66c845, 0x33a56ead, 0x865a87c5,
- 0xd3fcbbed, 0xc32b5d58, 0x33fcb7f6, 0x6a9dfdf1, 0xec7fb625, 0x9df6c72f,
- 0xb7b6255a, 0xf6c3eff8, 0xdb0ab53a, 0x601ecb4d, 0xdb0aad75, 0x883d9733,
- 0x52a1bfef, 0xd2138760, 0x6ea3d97b, 0x966f853f, 0x7d02a9e4, 0x9caa6cd2,
- 0x28b7404f, 0xaf901ce1, 0x0d322487, 0xc4a7e5e4, 0xa1e6fa89, 0xc83734ab,
- 0x8343f6e1, 0xc539079f, 0xe7d4265f, 0x0f26b0be, 0xfb0a79fb, 0x3d3f68d1,
- 0xf0a7efdb, 0x7ebaa19d, 0x2f99df0a, 0xf80e79fa, 0x63b939be, 0x677f6cfd,
- 0x779e1eb8, 0xaf3f45ca, 0x8ef63f60, 0xaff0abcd, 0xfcf0f523, 0xa7e89175,
- 0xde95e706, 0xbc767831, 0x1793f14f, 0xfbc767ed, 0xf6123f14, 0x64fd8f53,
- 0x419e0c75, 0xf5d50c1f, 0xf983e833, 0xd8039fa2, 0xf58e974f, 0xe183e3b3,
- 0x283e787a, 0x8dbcfd17, 0xd8eb74fd, 0x387d06bc, 0x87cf0f52, 0x473f448b,
- 0x1d1e9fb0, 0x51e767eb, 0x1e767e3d, 0x28e7e08d, 0x63bbd3f6, 0x4c721af3,
- 0xc7219f8f, 0x8339f822, 0x63aebf74, 0xa63cecfd, 0x63cecfc7, 0x479cfc11,
- 0x363bf278, 0xe89f21af, 0x93e433f1, 0x632e7e08, 0x831d053f, 0x1eb4eea7,
- 0x23a7753f, 0x982551f8, 0xc18ee0d7, 0x1e8cec33, 0x44cec33f, 0x009763f0,
- 0xeb1de19e, 0x1e8ceea7, 0x2267753f, 0x7846c9f8, 0x5e6c7546, 0xe3d33ec3,
- 0x1167d867, 0x9e1138fc, 0x08cdcae2, 0xf4fda10f, 0x379fbb6f, 0xcff5e9ce,
- 0xfe98e71b, 0x8fc47819, 0x21cd57fa, 0x6467002e, 0xa25f994b, 0xd6932575,
- 0x89ba509d, 0x055fda87, 0xf83f70ec, 0xd32fd1b8, 0xb4ea94f6, 0x58ce3582,
- 0x02ec5c7b, 0x4d03ec78, 0x18ef7b3a, 0xa7abac99, 0xd9d74e8f, 0x5df1cceb,
- 0x29acf574, 0x9cf5743d, 0x7dd3ae3b, 0x817665df, 0xd175deae, 0xdbbd5d70,
- 0xf7dd62d2, 0xd66e07ce, 0x3958f7b5, 0xf5ef5749, 0xf5750fc8, 0xd2ce4fde,
- 0x2bacfbd5, 0xdd77f5d7, 0x7aba25c6, 0xea9feabf, 0xcb35f9ea, 0x68577575,
- 0xb05eae8d, 0xff5d71ef, 0x5a7adf03, 0xf87c1f57, 0xe87d5d39, 0xbeeb2f47,
- 0x35fc7e1f, 0xd9e47d5d, 0xc7ff065d, 0x97d138e6, 0x77f065d7, 0x9a07e8ad,
- 0xcfe869bb, 0x60b37516, 0x6cddc7fd, 0x28f1ff58, 0x4a0e35cf, 0x07c39fd7,
- 0x58fdeed4, 0x48ef5cf3, 0x25297f60, 0x4a07244d, 0x8d0c898f, 0x52ad5f6f,
- 0x527ca3be, 0xef72fddc, 0x9af4b4a3, 0xd1a77a5a, 0xa2a6eff2, 0x3f17c0a5,
- 0x97e84c95, 0x09526559, 0x1335647c, 0x57d5cbe4, 0x1fde7e0f, 0xe70fdfc3,
- 0xfd14be31, 0xe656ac3e, 0xeffe1d80, 0x83f3bf65, 0x4f287e1d, 0x93ec3b43,
- 0xf7f6177e, 0xfde7dfa2, 0x49fc0738, 0xd4fd468b, 0x3a35f1d8, 0x7f1c3f7e,
- 0xa6bf8c25, 0xbd2df18d, 0x4fc6ea87, 0x375f31ea, 0xc746927e, 0xe8f21077,
- 0xf1f3dfb2, 0x50bafe29, 0x3dfa50bf, 0x71e96f8e, 0x5abf8e3f, 0xe375f323,
- 0x7fc64727, 0x69fde412, 0x82507f18, 0xae1ef7f9, 0x728f7f9f, 0x3635fcfd,
- 0xbd9667ff, 0xc64fc7cd, 0xbd2b3ff9, 0xe3dfe6cd, 0x66fe6ca7, 0xf8ec6fda,
- 0x37fe08f6, 0xb72ff8c2, 0x9ae5be31, 0xf7f9fa91, 0xbf9fa45c, 0xeaff8d99,
- 0xf8f8f7b2, 0xab7f1c36, 0x7f9b1ef4, 0x7c7007cf, 0xe5d2b9b3, 0xeee64da0,
- 0xd00195c9, 0x263dd413, 0x746020d9, 0x2820219c, 0xefd084e9, 0x903d4817,
- 0xa64e3f0e, 0xffdf477c, 0x1bf29922, 0x6fdcf7f8, 0x12558127, 0x1dd74c19,
- 0x5767a79c, 0x417ed4cf, 0xcb5d993f, 0xae8433d6, 0xf0a6ae77, 0xff9ed535,
- 0xef0a43e2, 0x50038dec, 0x274e514f, 0x3e1cddf0, 0xf0ccaf15, 0xb7594841,
- 0x12bf5489, 0xa4dbaca5, 0x06e4d8fe, 0x411e7fbf, 0x78f8e318, 0xa27a954e,
- 0xe6fe4631, 0x17d7d5ad, 0x0175f404, 0x09301177, 0xa4c5fd2d, 0xf71d254f,
- 0x10275d18, 0x447f97ea, 0x594270fd, 0xdc9513f6, 0xf2f1465d, 0x404f5d31,
- 0x27ae91bd, 0x4cae9da0, 0x14c72e91, 0xb63bf382, 0x7a001ada, 0x0193f17c,
- 0xbb87d81a, 0x1bf2a7ef, 0x727edf2b, 0x5fc28738, 0xd339e7c6, 0x076fa19f,
- 0x4c3c53bc, 0x0b2bf3e4, 0x974f1e2d, 0xd59ee4c4, 0x459954b9, 0xf24a6bdf,
- 0x54ffd0a8, 0xe9b356e2, 0x9d2e7778, 0x5f107aa8, 0xca135cee, 0x5135c939,
- 0x56e89f39, 0xf4c6358f, 0x8066a93f, 0x93227b4a, 0xdf9feac7, 0x37afa656,
- 0x44d56ea9, 0x5134d3e9, 0xdda81b22, 0xdf4d3a99, 0x2339c62e, 0xc5fce3a5,
- 0x6e746578, 0x9e61d39d, 0xeffa63f4, 0x3cd83a1f, 0x34bc3ae8, 0x3f73d617,
- 0x689b5c90, 0x57bc2a7d, 0xa83d7400, 0xb769f3c1, 0x90d6b9a4, 0x92897878,
- 0xe11cfd83, 0xca23bceb, 0xcd0c5fa6, 0x83ff878b, 0x29b756dd, 0x461e7e3f,
- 0xa093a7b8, 0xba76f60a, 0xc67cff47, 0x18fce37c, 0x74e09c5f, 0x407c063e,
- 0x07c093cb, 0x39c7cf14, 0x2bf5441f, 0xc01383e3, 0x4eb09907, 0xa7307c66,
- 0x6ffd312a, 0x479ff4e7, 0x29676afc, 0x9ca9f74a, 0xba73b7ee, 0xe7ab5bcf,
- 0x3cf9b88f, 0x1cc1e1b9, 0x3cf98267, 0xa62547b2, 0x657979f8, 0x2ff91f06,
- 0x8e89b029, 0xbea5677b, 0xfd0376fd, 0x777e9c3c, 0x7165e846, 0xbf3e5197,
- 0x011927eb, 0x7c7133d0, 0x31f5e9c1, 0xb5b4d7a7, 0x4cefed8f, 0xe46be1e2,
- 0xf6b13af4, 0xfb44d579, 0x112f9c6b, 0xf08c6ff0, 0x9bbbe11a, 0xdfa03438,
- 0x9febf7dd, 0xa627f4cf, 0x28b6b79f, 0xf3cc78e3, 0x1971c1c5, 0x68e463c7,
- 0xba89e6e1, 0x74c082fa, 0xd6f3fbdd, 0xcfb5d4ce, 0x6ba05aa9, 0xbdf567bf,
- 0xff4cfaba, 0xdfef744f, 0x5d32ff7d, 0x0f959dfb, 0xcc67daeb, 0x9f574c7f,
- 0xf74a79ee, 0x1b69d4fe, 0x95b7ed74, 0x9f6ba4bd, 0xae9b763c, 0xa75dd13e,
- 0xbdda5f7b, 0x9fc43ba0, 0xd9e79abc, 0xbd9b886c, 0x49cf266f, 0xe84c7af1,
- 0x273ee3bb, 0xebe13f3e, 0x9f29e583, 0xf19f9f0b, 0x1972c50d, 0x176a71e8,
- 0xf4ac754c, 0x3bb33e3e, 0x07217fe8, 0x6eaea89f, 0x7a8d3fa0, 0xc4e7a8cf,
- 0x46bd46fb, 0xa7e0b97f, 0x59cf15b4, 0xb0329124, 0xf312cd0b, 0x43f3c457,
- 0xb2123edc, 0x1a45cb1c, 0xaf45d393, 0x39062e75, 0x7b85a45a, 0xeedada57,
- 0x9c250497, 0x9eaa9ccf, 0xade7383a, 0xef806bed, 0x05abe439, 0xf3dd4281,
- 0xe8479b85, 0x47bb3bbe, 0x402af846, 0xff8187b6, 0x04deb65d, 0xb7bc31f6,
- 0x00fee4db, 0x1319fbaf, 0x09db5bc0, 0xdf59eaed, 0x0ae38cd8, 0xcb0cb9e0,
- 0x5869be53, 0xb079f09e, 0x8f9bee3c, 0x255f31e5, 0xfbbe8d96, 0xe7d8fcb1,
- 0xdf23f2c7, 0xf03f2c6a, 0xc4796155, 0x77cb16b7, 0x0f2c017d, 0xf96336fb,
- 0x65882f8e, 0xcb16af83, 0x4b1b9f26, 0xfc312f21, 0x0c73bdd2, 0x277d08bf,
- 0xce29e1f4, 0x5f80672f, 0x73c5f112, 0xa938be7a, 0x185f2256, 0x0e91a1f5,
- 0x6df77d46, 0xf4dd21f9, 0x9443f0fd, 0x7a06b9de, 0xde8f6cf7, 0x397d221f,
- 0x0e4dd3bd, 0xf7a70f06, 0x45780623, 0x041281a9, 0x7e6665bd, 0x595b711e,
- 0xabc453dc, 0x7b8b3249, 0x337578f2, 0xbc0377fd, 0x10fb04a7, 0xbf6b5fda,
- 0xe21bdbff, 0xcc47adcc, 0x3db5e484, 0xdafd233f, 0x9bf103c4, 0xc9ff0ebe,
- 0x14af0cc9, 0xda84b1aa, 0xbed73587, 0xeac59aee, 0x423b010a, 0xb8d8ae82,
- 0xc05fa46f, 0x78fb7665, 0x7f31374d, 0x6657bad3, 0x776f08f8, 0xf2894e4d,
- 0xd2dcd7ab, 0x95f833bb, 0xd8099a1f, 0xe9b01233, 0xf5a7e5f1, 0xb57c51c1,
- 0xf4f68f35, 0xfc2fffde, 0xda8fa7b4, 0xa48743d3, 0x735fc7af, 0x24f75d31,
- 0x008e2f58, 0x6df41c3e, 0x1ba1b0f8, 0xf81061f0, 0x5adff69d, 0xe92a4d73,
- 0x66e7ed17, 0x13af9393, 0xde4e9ebe, 0xd37e0854, 0x1334537e, 0xcbae9eb9,
- 0xf24dcf65, 0x5dcff020, 0x6f4a7e8d, 0x6bab6eff, 0x49d61385, 0x7612fe67,
- 0x75fa17c2, 0xe7c1eb73, 0x59aeb0ed, 0x1c726392, 0x3e9b6c2f, 0x0e79838b,
- 0x547fac5b, 0x56b7afab, 0xdc596349, 0xa53a99c4, 0x8769e83f, 0xd02f78e3,
- 0x8a58399b, 0x68e4967e, 0xf019e38e, 0x79c9805e, 0x81ea1a75, 0xbe0b3e33,
- 0xd1c37df7, 0x38513f56, 0xf427c86a, 0x2b89107b, 0xbf7edb3d, 0x2e56be4d,
- 0x228f1068, 0x580bf521, 0xffd1252f, 0x7e80f4af, 0x7e8bac15, 0x6fd941bd,
- 0x579e1ebe, 0xdfa3c6eb, 0x1b1ec539, 0xfcb6d77c, 0xe084e428, 0x3f374a5f,
- 0x2fb8a7f8, 0xfbd0e494, 0xbaba696d, 0x43b3b6b7, 0x3fc1c7e7, 0x2d1cd1c0,
- 0x8b47c029, 0x2b355b38, 0x8512d5b6, 0x322c066f, 0xf6259f81, 0xa34b62de,
- 0x968fa1e6, 0x7f4148ec, 0x7c63c978, 0x1a4fcd9f, 0x4359fbe0, 0x29970779,
- 0x51fd3154, 0xb44c470b, 0x89af0f7e, 0x3559aefd, 0xff5fd10b, 0xdd71f894,
- 0x1aae5a77, 0x796a7e0c, 0xa6e68370, 0x989cfb74, 0xffbe82c6, 0x2f63bc9c,
- 0x57b7918c, 0x7be70d64, 0xffbd6acf, 0xbab1d74a, 0xeac75d3a, 0xa4c973ea,
- 0x9a17d82c, 0x974aa4fb, 0xd5aeb8d4, 0x7656ffb5, 0x91e77ce0, 0x876055ca,
- 0xbc29a93f, 0x71e0047d, 0xb0c1fae7, 0x9b459c4e, 0x29fea973, 0x03487cdf,
- 0xe3a6f939, 0x0bef802f, 0xf315c7e2, 0xe407db8a, 0x59bc5878, 0xd8120772,
- 0xf76e5abd, 0x3bfa5e84, 0x1eb31fc0, 0x23e7cd3f, 0x3f9adfea, 0x65c32932,
- 0x4339e945, 0xc1921cf6, 0xa49f008e, 0x5be2f946, 0xd7139ff7, 0xd7bfdfff,
- 0x1d12bbfe, 0x4ffed37f, 0xdefc5e83, 0x0715effa, 0xf044c5ff, 0xb22c3a0b,
- 0x17c01c34, 0xbe096e1d, 0x14dcb853, 0x7c60714d, 0x725ab9aa, 0xc4fbe999,
- 0x2c8e9c4d, 0x3d601fa6, 0x6a5afcd9, 0xe1bd413e, 0x1f3a6e20, 0x552e7f2b,
- 0xd123d9ef, 0x3b4ae175, 0xfe51a771, 0x9953e954, 0x692ad1ca, 0xe5a24580,
- 0x7f739ae2, 0x9bf68379, 0x88099214, 0xa1853374, 0xdd97f701, 0xac776069,
- 0x03b411e4, 0x257ec7b0, 0xd1a70a23, 0x0578103e, 0x8d8397ec, 0x61b6463b,
- 0x9d75a6fc, 0x9955718c, 0x919bf75c, 0x0f782f54, 0xeda2f952, 0xb405f0ad,
- 0x5d7095af, 0x04b07adf, 0x24eaf3eb, 0x6beb4192, 0x60f9ec93, 0x26dcd2af,
- 0x63373c5d, 0x4e7e3eac, 0x5806eefc, 0xf3e6cfff, 0x1c00c405, 0x53bd790b,
- 0x7de1ba59, 0x5c4c5ffa, 0xee67b66c, 0x93f14278, 0x771f4d3d, 0x723f285f,
- 0xed3ae200, 0x06ed6dca, 0x9463900d, 0xf59b85db, 0x21b78175, 0x09e64a4a,
- 0x6236c9b0, 0xadb5bc03, 0x67c1dbc7, 0x8cdfef63, 0x7c71d81c, 0xce64f11a,
- 0xc935e3d1, 0xb5abc7a9, 0x066f018f, 0xf4b8a6bc, 0x3a66a2f8, 0xa9af0890,
- 0xfae87b43, 0x7af1bef9, 0x6fb3e017, 0x57f49f14, 0xa262c966, 0x56767007,
- 0x46ffc8c2, 0x85b5c979, 0x55f7f825, 0xf8658199, 0xf5052b95, 0x5f870e40,
- 0xb3becd9a, 0x60c8bc82, 0x2f285d55, 0x3b046910, 0x391f256e, 0xf2268e80,
- 0xb7d2b909, 0x37de3a6d, 0x59d1df71, 0xc075abf4, 0x1f23d7cf, 0xe9fc5d20,
- 0x0f22b024, 0x00e5d1e4, 0x59f416bb, 0xbae9b39c, 0x711f55f1, 0xcdfea6ce,
- 0x96073e6b, 0xf7b0168f, 0x0091fb9b, 0xe1831bac, 0x884e590b, 0xeba1cf67,
- 0x1fffaa34, 0x80265ad5, 0x9517fc3f, 0x55eecfad, 0xab772c35, 0x47ffae26,
- 0x79f201ff, 0x00ffa99a, 0xd0e6a5f1, 0x50d5cb26, 0xbf3195af, 0x75569bc0,
- 0x14df8c2d, 0xb35c1952, 0xf64f182d, 0xc768abd6, 0xc48f669b, 0x9f311a7c,
- 0x163c90a6, 0xa1cdd9e2, 0xc4f7ec4f, 0xdaa69dd8, 0xbb05ae27, 0xb12994f7,
- 0x628cfbff, 0xc87e6efa, 0xfa3d38ba, 0xf509d28c, 0xe83da3e7, 0xb6262a3c,
- 0x9becbf22, 0x77ce337b, 0x9a724847, 0xf2a5dc29, 0x0fe83f1d, 0x537f86fb,
- 0xee24de98, 0x58b333f1, 0x5f563ce8, 0xabd4888c, 0x7ec32afe, 0xc3c45d25,
- 0xcac0e2be, 0x8c87e8b9, 0x0292490e, 0xc108ebfa, 0x0fc8467e, 0x7f32c094,
- 0xe3a28350, 0x0921c1c7, 0x91b836f1, 0x90d37e60, 0x61f6fa23, 0xae218a8d,
- 0x9f819016, 0x3fd29c46, 0x6d7c13af, 0xd7c05927, 0x25965e4f, 0x5b9a4ff0,
- 0x1d396b88, 0x977679bf, 0xf9a78022, 0xd046ec02, 0x363cb2f2, 0x8ff7fad1,
- 0x9e87f30a, 0xc6fed8d2, 0x816d7353, 0x6fbe9465, 0xb8c72dce, 0xf13f17c4,
- 0xbfb44f74, 0x5287a315, 0xdc83684d, 0x75cfb0a9, 0x1295c4df, 0xd552031a,
- 0xfe252cb9, 0x82bfc17d, 0x771f059f, 0x09ec9b9e, 0xb2671824, 0xe294fcca,
- 0x8d247db9, 0x5bb4d7c2, 0x4da57422, 0x747b969a, 0xe9630ef1, 0x0173cb27,
- 0x79ed6f1e, 0x2594ec0d, 0xfa0fd894, 0x3ca3b14c, 0x2ff72d34, 0x1fb5bc83,
- 0x3bf46153, 0x27dfaebf, 0x48723e31, 0x2cefb271, 0x9e813355, 0xe42c732d,
- 0xd6379639, 0xf00a5279, 0x55b8c97b, 0xcba7de14, 0x9f37684c, 0xbf085d52,
- 0x7961317f, 0xa2ff7c71, 0x61b204eb, 0x5cfc8c4d, 0x95248a54, 0x0ea92bf6,
- 0xe3c33fec, 0xd77e0092, 0x8769ffbf, 0x4be690fd, 0x1763a466, 0xdf10f71e,
- 0xfad95575, 0xfeea8371, 0xd0f58152, 0x0b944cfc, 0x9ceec797, 0xf5f2ed4d,
- 0x09ef14b5, 0xffe146fc, 0x98e87ba5, 0x9b749e14, 0xb892f909, 0xd5074edd,
- 0x7e225e77, 0x8883947e, 0xa225845c, 0x51ea8e0c, 0x53852429, 0x681c3ea8,
- 0x5a6585b1, 0xf3a7cfa6, 0x6231fd86, 0x2835fd61, 0x40fb2367, 0x7ca1aeb8,
- 0x4d821839, 0xaef587f4, 0xafd0bfd8, 0x84af2f42, 0x67ed36b8, 0x604a63e5,
- 0x9d67ed05, 0x357498d2, 0xcedcf32d, 0xba412062, 0x5003f4e2, 0x2e27cd57,
- 0xf6b1210a, 0xf1169f5c, 0x0ed0a847, 0x78c64af8, 0xd38e9180, 0xf4f2f822,
- 0xf3fce952, 0x09bcb60f, 0x892b8b6e, 0x6fdae78d, 0xca593b41, 0x4fb0eaed,
- 0x17d0014d, 0xee237c24, 0x112d799b, 0x17d3a0fd, 0xc4686ec3, 0xef61ae7c,
- 0x54a87833, 0x41fde1b9, 0x7d723c11, 0xa136fdc2, 0x8284863f, 0x2eaeb085,
- 0xb5ee1508, 0x3e0bf1d1, 0xa71b7262, 0x15d20e3f, 0xaf6f8f5b, 0x307c8c37,
- 0x90e54c20, 0x1d1fa5d3, 0x23a0f0bf, 0x52f68752, 0x7019ea95, 0xc99eb916,
- 0x1b30389c, 0x7f38bdf7, 0xe42af119, 0x05e728d9, 0x9af6bbf7, 0x0c885c19,
- 0x8a4438e3, 0x09ece1c2, 0x392de87a, 0x1157f415, 0xeb8503c5, 0x696f2e73,
- 0x60e30217, 0x6e864ffe, 0x65df224a, 0x7e99b25d, 0xc62f631d, 0x20d99ec9,
- 0xd85ed477, 0x7b150f01, 0x8f4c682e, 0x11de9185, 0x0172a7be, 0x10b909df,
- 0x6fe46efc, 0xe82b0f21, 0x189ea657, 0x4760249f, 0xce082965, 0xeb61d52e,
- 0xe157801c, 0x1a7f1337, 0x3a9663c6, 0x78eb38d8, 0x24d2ca5e, 0xd7fa7677,
- 0x25ef5fe8, 0xc4c40913, 0x8b4abc39, 0x7bd17a06, 0x8c812349, 0x8d9f80ef,
- 0xad59f871, 0xcfc78a76, 0xebf3c86c, 0xfe02bff4, 0x87fe1180, 0x5ff8519c,
- 0x421456b7, 0xe70efe9d, 0xef9bd2c4, 0x15f90a13, 0xb6b43af2, 0x9cb52f72,
- 0x2719f271, 0x0c80a197, 0x4f978a78, 0xccf41932, 0x23f33088, 0x817a728c,
- 0xf6f9a3cf, 0xefc0de96, 0x0ea7b2f9, 0xf7def7e0, 0x2fe83745, 0xc63249df,
- 0x6bf32053, 0x2bd81765, 0xb3a190d2, 0xda76f107, 0xf5c4e8cf, 0x9f9f057a,
- 0xd4f94b54, 0x9e05fb0e, 0x0affd07d, 0x41ff5b07, 0xc7f41e40, 0x7bf3c545,
- 0x852b0b90, 0xa7e2192d, 0x1879c27d, 0x45c832a7, 0x3560725b, 0xce9079f0,
- 0x9f8cec17, 0xa5ab99da, 0x5879e1b6, 0x52f0634d, 0xa23f07e9, 0x06c260eb,
- 0x8fb820ab, 0xe59f35da, 0x602d74af, 0x729fd6f9, 0x50c27e7d, 0x3eca545e,
- 0x0aa97986, 0xbe0b9bf1, 0x2a00dc3d, 0xaa4e5fc4, 0x1f008fee, 0x9c6eb196,
- 0xb883ae47, 0x72276a24, 0xa2e4a095, 0x722fa470, 0x9fc6bda2, 0xbfb49fb0,
- 0x22cef1dc, 0xd52e77a0, 0xcaf71089, 0x91247f05, 0xc22aa85c, 0x3ef9adfd,
- 0x5f07e710, 0x407f7ce1, 0x18cdf3a3, 0xbcb1a2df, 0xd4ce2a85, 0xdbf0092e,
- 0x4e3b7294, 0xc4a2e9b6, 0x8634fcfc, 0x08bae367, 0x52f30608, 0x8d41fd78,
- 0xb8e94928, 0xbec3f16e, 0xc164dfb2, 0xb8958b75, 0xbae7a082, 0xbe1e2c68,
- 0x86ad724a, 0x16952ffa, 0x78f9e40b, 0xfefd6cad, 0x2e49c8e8, 0xbf62be85,
- 0xd61f35a1, 0x3bcf949e, 0xa6fdf469, 0x57bdad91, 0xba5a0ce2, 0xcb737e31,
- 0x27c12f30, 0xb56e8215, 0x496e8eaa, 0xa1888f10, 0xad148adb, 0x4dc5f80f,
- 0xd60bb252, 0x240b4d29, 0xe164a706, 0xff9053f3, 0x1e127122, 0xf2d42857,
- 0x6f423f10, 0x86acf9d3, 0xfb0dc052, 0xf92fd0fa, 0x89b0359d, 0x8f1bfabe,
- 0x81c433a5, 0xed8e67b3, 0xaf67710c, 0x491ba5bd, 0xf3a60710, 0xcbf3001b,
- 0x40d32b56, 0x79df65cf, 0x30f40edc, 0xd7f62dc2, 0x4bfb07f0, 0x586c656f,
- 0x7125fe83, 0xe7cf7ab3, 0x05094eb0, 0x60e39978, 0x2a49cff0, 0xb7d58acb,
- 0x132cfa4f, 0xef5a2515, 0xec4bc914, 0xffe7cba3, 0x89daefb5, 0xbd7be9a3,
- 0x59372635, 0x9fe3f5a4, 0xd6e671d1, 0x3f105d58, 0x8cf65478, 0x773fb803,
- 0x70975f3b, 0x01295d1d, 0x959f8b1c, 0xf079d3c8, 0x43fb611d, 0x1f943f1c,
- 0xd98ecf3a, 0x2ef3a037, 0xd3c506d3, 0xb52559b5, 0x7212e710, 0x2ca7c999,
- 0x4ba082f4, 0xea9bd026, 0xe5465205, 0x8dce2634, 0xdc6166af, 0xe8527f0a,
- 0xbf02fff7, 0x31437ed1, 0x1ba09dca, 0x48f4c3e9, 0x4c75c812, 0xfeb9aabc,
- 0x14fcabbd, 0x9fffbf8e, 0xb68429f3, 0x496943ff, 0xf53e3901, 0xdc535fc0,
- 0x00f60f90, 0x977acf5b, 0xeebce2a4, 0x8ff77ee2, 0xb46a9e38, 0xd79872b2,
- 0x637fbedd, 0x6fa2379c, 0x8efb67ef, 0x8ffaa80b, 0x4b6a2fdd, 0x1479c32f,
- 0xfd7793a2, 0x8562ecbe, 0x7e30eb9d, 0xeb6349bf, 0x1bd505e6, 0xc0275cb4,
- 0x806ff9e3, 0x5f5f14e7, 0xf161aa9c, 0xacdf011e, 0xf81a01ea, 0x9908ffdc,
- 0x1fed9849, 0xb95f4ca9, 0xb7c5126d, 0x08d1e387, 0x179e01f7, 0x3257e739,
- 0xe933c1fa, 0xb953f758, 0x601684f7, 0xff08c71c, 0x52bcba9c, 0xf3987fc8,
- 0x29eb84b0, 0xaa01ff78, 0x3ff73d3f, 0x68e80e74, 0x9f319f9c, 0x171f18c4,
- 0x43c8b37e, 0x983c4d9b, 0x27171297, 0xfb1cfd0a, 0x9e8bc637, 0x797af8d5,
- 0xfb021930, 0xbef96725, 0x621b9c3a, 0xcb04ebfb, 0x14925072, 0x1e968b9f,
- 0xb926052a, 0xc61b72a3, 0x33f8c5eb, 0xf833f8f8, 0xaae15438, 0xe633c7c0,
- 0xf36217ab, 0xdc68b6dc, 0xc7421e6f, 0x89e3a393, 0x39731671, 0x7a0be314,
- 0xe72abe0a, 0x7f515d74, 0xd3235bb2, 0x0c498703, 0x9ff88c7d, 0xca2b3bf7,
- 0xa1cf0447, 0xfd039c5f, 0x51736738, 0xec271769, 0xc28e545f, 0xcfe269fc,
- 0xe16af961, 0x1bb7581c, 0x36a4def1, 0xd8257376, 0xfee2689f, 0xb9717b5c,
- 0x03c89a1d, 0x94f2c2a8, 0x67e07552, 0x191b87c0, 0xb9de2c1f, 0xb79075e5,
- 0xb2bfadf2, 0x569dbc83, 0xbc60b2aa, 0xb41e9b45, 0x29c57ec3, 0xbd076fc5,
- 0xe4c03a78, 0x8aefc8ce, 0x305bec59, 0xe0f6157e, 0x9f3fcbcc, 0xc5f9fc00,
- 0x7a01d526, 0x1cd9bbde, 0x547c5336, 0xd0fc30d4, 0x7f5651fa, 0xade2f108,
- 0xfe5dc3d5, 0x9cb2afe2, 0xe7969f6c, 0x9d7185f3, 0xd3f1b15f, 0x2f0f9052,
- 0x1d7dc169, 0xfe3077e3, 0x97dc74a5, 0xc6a5a99b, 0x11be0bb7, 0x8d6f05eb,
- 0x3c469be0, 0x7f7c665f, 0x172fd73e, 0xfe72bf05, 0x0120f811, 0x9de457a6,
- 0xd28ff3eb, 0x7f8dd9fa, 0x62fd4bb2, 0xbfcb09f5, 0xf3de0d68, 0xdb672eec,
- 0xe71360fe, 0x0177e8c3, 0xcb59cefc, 0xac4230f3, 0xed86a45c, 0xb4591710,
- 0xecf5c541, 0xbfcf2da2, 0xbdd834f0, 0xabaecdf7, 0xb70bff69, 0x38777fec,
- 0xa6dc2fad, 0xd3678e66, 0x763149b0, 0x5a7c0bda, 0xf943a510, 0xb39afdf6,
- 0x40fe7b3f, 0x0b1e947a, 0x48d1edb7, 0x947c78ff, 0x8c68f704, 0x09740dff,
- 0x7d852d1e, 0xbfe7796e, 0xe9fba035, 0xbc8112dd, 0x6e7c38cc, 0xd2fb8fd8,
- 0x23a42780, 0x6e8453a7, 0x94bdf786, 0x39e7682e, 0xefed8c9d, 0x3fe40e69,
- 0x5dce0fe8, 0x757e7e51, 0xfccfc517, 0x982ecc0f, 0xef57fcff, 0x4e3cc3b3,
- 0xaf8c952a, 0x05983fd7, 0xeabe6476, 0xc96072cf, 0xe67fcf9e, 0xf36fc847,
- 0x8b28fd0e, 0x99d2fd30, 0x9dfcd1c5, 0xd6737e61, 0x9bf386dd, 0x77c83c4b,
- 0x65cbd7f3, 0xa8babf10, 0x12dbb190, 0xb94fc5c8, 0xce7c9c5c, 0x27f8fb8c,
- 0xb8531ec1, 0xccc8effc, 0xa2f721cf, 0x9f11fd7d, 0x58fcb50b, 0x18e3c8bf,
- 0x1e22cd13, 0x2c72b54c, 0xa87c6ebf, 0xe673e801, 0xc436772a, 0xf144bd01,
- 0x57487c73, 0xa1f2bf68, 0x3f5cd931, 0x7f189539, 0xc39e04b7, 0x3baa0dfb,
- 0x1df75f29, 0x1d1792b9, 0x9f1f297f, 0xfb0c9dc2, 0x12b327c6, 0x305f87c7,
- 0xd611624b, 0xa303f3a0, 0x7de4cdf2, 0xbe4cc3e3, 0x2607bc85, 0x0bf6858e,
- 0xc0fc9987, 0x53c7e077, 0xd8d9c2b8, 0x848a67be, 0xc3da80fa, 0x51bd7244,
- 0x6fad72e5, 0xe1427c17, 0x897fc056, 0xfb610bf0, 0x7e7927bc, 0xe927dcfb,
- 0xc1763177, 0xe3d9e30b, 0x3b7213fb, 0x6617f84f, 0x7593fcbd, 0x5bc6129d,
- 0x22c47e8c, 0xd3c2f035, 0x3e54af20, 0xda2edf41, 0xbcc196a2, 0xfbdeab3f,
- 0x9ca90fee, 0x7214167c, 0x469fd7aa, 0xdaff9d39, 0xa34fe47e, 0xdc167e9c,
- 0x4e50959f, 0x73c7edb7, 0xfa72f1b7, 0x053fab3f, 0xf01bd6fe, 0x5b61f427,
- 0xc3ea3478, 0x4fc410e1, 0xb7090fa0, 0x13fe46c3, 0xadf8277c, 0xddc595fc,
- 0xf844ef41, 0x845df052, 0xc5df052f, 0xf0ead1e5, 0x083f3717, 0x589f01a2,
- 0x75828ed6, 0xf6c5c586, 0xcb39ae13, 0x819693e2, 0x67d6fd6c, 0x43f582ad,
- 0xb020c726, 0xec4613fb, 0xa427ecfc, 0xbef9fe6d, 0x963e9dcb, 0x65075fa3,
- 0x895f042f, 0x1090e3a5, 0x16fbd383, 0x7d40f409, 0xf76396e0, 0x930b640b,
- 0xbd1f9df7, 0x2c780856, 0xca97ee6a, 0xae1babf8, 0xb5fc445b, 0x054cefd5,
- 0xea1ada7d, 0xad4f7989, 0x4494e507, 0xe25fa5e7, 0xfb857df4, 0x491bcd5b,
- 0xadf94c95, 0xdfa0b499, 0xc168dfe0, 0xbe38b67c, 0xe67f3330, 0xe803e2bb,
- 0x2978f80f, 0x5134b1a9, 0xf9f09a3c, 0x5ff3784e, 0x0baf1f68, 0xbf81306d,
- 0x9346dd7e, 0x24be4fce, 0x1480baf8, 0x784f5f00, 0x20652933, 0x2ecaf3ee,
- 0x0dee5738, 0x093cd39d, 0xf38c95f2, 0xdfc1fe87, 0xe0716fea, 0xc1a86fb8,
- 0xdbdcf07b, 0xeb0216e7, 0x6aad3a85, 0x3b382261, 0xeb383125, 0x7cba338e,
- 0x6a29785f, 0x618b85b6, 0x61237a7f, 0x3a38f671, 0xde0eb613, 0xaa7f704c,
- 0x7ab32435, 0xa347db35, 0x2462fca0, 0xf699777c, 0xd79f231a, 0x057b6ed4,
- 0x8455e7ce, 0xb6898724, 0x1a8d2857, 0x36b78bf0, 0x363d064d, 0xcbce29c0,
- 0x894ffa3b, 0x16febfe1, 0x77b9e705, 0x00331bf8, 0x6acfe72f, 0xddd5f604,
- 0x60ec5afb, 0x0a87ceef, 0x9adadf91, 0x191f76d7, 0xfee9eb05, 0x78a77f00,
- 0x4eabf63a, 0x9447d5d6, 0x5c00ba78, 0x4b8dcc13, 0xfef0095d, 0xf7d9858a,
- 0xdb3e4bef, 0xbf2c3b2b, 0x7afc8587, 0x7c41bf70, 0x378700ff, 0x13b37e46,
- 0x6592efc9, 0xf7986cce, 0xd99efa92, 0x7f25cf80, 0xe2253b50, 0x963e2dab,
- 0xee15b4df, 0xadf90017, 0x7d7bf2a1, 0x50d6fc8c, 0xff8bcdf9, 0xfbe5ae6e,
- 0x202ddf95, 0xfbe009bf, 0x90af9f09, 0x51d0fcdf, 0x1afcdf94, 0x4acef9fd,
- 0x2bf27b4b, 0xf2c29a75, 0x04d65c60, 0x00f01afa, 0x795bb2f9, 0x038c387e,
- 0x37c2fc72, 0x24bce394, 0x4a7fef06, 0x20ec978e, 0x4f128798, 0x4bc7266f,
- 0x4b1ca8ea, 0xc7267740, 0xcb09ea4b, 0x6fc83407, 0x65f9389f, 0xd98457df,
- 0xbcdadef7, 0xc741dcdf, 0x2eab702b, 0x20bf7d0b, 0x6283cf2a, 0xb685f9e5,
- 0xc760f9e4, 0x970779e4, 0x3da72a67, 0xeae8095c, 0x63f3e90a, 0xb27618de,
- 0xe5f03b7a, 0x275c659f, 0x0f79e21d, 0x7276197f, 0x3fc5f020, 0xff8a1e00,
- 0x9a6f9c3d, 0xbfec7e7c, 0xe853f874, 0xabec9547, 0x03ec35fa, 0x12a8de2e,
- 0x351587d0, 0x328fd147, 0x5f85bfae, 0x0b875c65, 0x7e5ed23d, 0x776e61cc,
- 0x088dca26, 0xc65b792f, 0xf38c3ffb, 0xc1c5ef17, 0x5deab079, 0xc042afb8,
- 0x407c5ed9, 0xb83da3cc, 0x15debcc4, 0x148032f2, 0xe286dc42, 0xffc5e511,
- 0xb5cf1947, 0xad5d1595, 0x23e51fbb, 0xaac2cf8e, 0x870812a2, 0x37e7e44f,
- 0xf7bdaee7, 0x18af9c00, 0x0059c474, 0xe188f4ee, 0xa7ac0f66, 0x416a4a5e,
- 0x49741679, 0xb974624d, 0xa379fbc4, 0xf031654b, 0x7256b79b, 0x86f1dd80,
- 0xc1f785ff, 0x8bea7dec, 0x05a3e052, 0x8cc392f5, 0x834e787c, 0xb5295e75,
- 0x854fc0bf, 0x7eb873a1, 0x245f505b, 0xea0bf7c3, 0xa3c0bc24, 0x9474fc3d,
- 0x0edc296e, 0x6df8016f, 0xb30b6700, 0xd13e1c6b, 0x3afc55ee, 0xbe9e4bf8,
- 0xc1972ab4, 0x571704ed, 0x02283bc0, 0xe7194cef, 0x057841d5, 0x3783dbde,
- 0xc74f4935, 0x679e47b7, 0xb4a110fb, 0xbe6bad0e, 0x97887ee9, 0x4cfae034,
- 0x90cc8bec, 0xac0b663d, 0xf3e97b6f, 0xc1690995, 0xa1efebbc, 0xf5d7ff7f,
- 0x0037d91f, 0xece41dff, 0xcbae2a4f, 0xb338a497, 0x1df1dce1, 0xb75d2af0,
- 0xfb336d34, 0xff313de1, 0xabb73e13, 0xc3710297, 0xf19e58b1, 0xf57ab995,
- 0x4f6fb18a, 0xbe43b79d, 0x821f7357, 0x294d2179, 0xda274e2c, 0x0b3249dd,
- 0x587e73fa, 0xf57c34a4, 0x1b49f821, 0x5c03061b, 0xbcf32e27, 0xb1e6cb92,
- 0xd3ddd689, 0xe7109db9, 0x3802ef28, 0x2fb2249d, 0xe59f377a, 0x927e705d,
- 0xad6667ae, 0xf8852b4b, 0xa0bcf1b2, 0x83403827, 0xde31a438, 0x11b88738,
- 0xd0f9718f, 0xbf1611e4, 0xeedff034, 0x273b0724, 0x706a54aa, 0x3ac4f65e,
- 0x8829f889, 0x8f88db0b, 0xf1e24c6f, 0x1fc20ec8, 0x46b1ce77, 0x11b978c2,
- 0x971b79ee, 0x6042eaad, 0xf15e6cbe, 0xb579b3f0, 0x78d20f35, 0x8bb58923,
- 0xbcec420b, 0x3223c576, 0xaf3c83b3, 0xe02bc044, 0x2a5dc233, 0xa7ff422f,
- 0xfa8cad79, 0x607f2ef7, 0xba479c15, 0xfb84a56b, 0x54f9c62e, 0x009cced4,
- 0xdf43c0fa, 0xf3693887, 0x69ed0447, 0x00296af3, 0xd73f8c78, 0x4bfb66e9,
- 0x427bbc7c, 0x7e7351f2, 0x1ea2f4db, 0x3665d20e, 0x849acba5, 0xd5c8a3fa,
- 0x168e462b, 0x7ab9c604, 0xe20bc6e9, 0xe6e17eba, 0xbfe7ba89, 0x74f1e249,
- 0x4f6fbf1e, 0x6265489e, 0x47e422bd, 0xaf9093c8, 0x817ce0dd, 0x0702519e,
- 0x4f00f372, 0x1a7ea18f, 0x4c5e7b27, 0x8f217962, 0x54afa74e, 0xe79e753c,
- 0x0cbc7085, 0x2399f465, 0x6de7c78f, 0x078a31e9, 0xb6c0fedd, 0xe27c7d24,
- 0xcc47cebb, 0x9881c843, 0x8c0e519f, 0x21e91bdf, 0xba46c0e2, 0x6721e918,
- 0x7e40fa9b, 0x5d939121, 0xb9cb77e0, 0xe8d7caa6, 0x5a7772b8, 0xcbf703f6,
- 0x65a4cf25, 0x7928c955, 0xa8572d16, 0x30ad2f4c, 0x1898b8b1, 0x970e5dff,
- 0xcb923328, 0x3ec1270e, 0x830ddbe3, 0x0c2f2cad, 0x5c7145f7, 0x9215a78a,
- 0xe83f809b, 0xfed04fdf, 0xbd926417, 0x712b7f80, 0xd6fdc50f, 0x9e3e7124,
- 0x5fd2e1e5, 0x582e942e, 0x35a70fc7, 0x83473fff, 0x8ab2ecbf, 0x4f5625fa,
- 0x153de135, 0xab25ffc4, 0xb93af367, 0xa2b9eacc, 0xfc29d69d, 0x7bfceeae,
- 0xef566ff2, 0xcdffda2b, 0xb45ebfde, 0x21dac57f, 0x7fb69481, 0xa357f0f5,
- 0xae7f30fd, 0xbbb548c7, 0x62bbf02f, 0xe529eb62, 0xdcf30d4d, 0x15fe3e44,
- 0x96ab97ce, 0x8562bf15, 0xb762a23c, 0x67c4f213, 0xdf3b73f0, 0x90f414b6,
- 0xf7bc26ad, 0x9ba04a01, 0xc0e2cc96, 0xc6a49e82, 0xcbce17dd, 0x2fbba091,
- 0x246635e4, 0xc192927b, 0x61ab7abf, 0xcd47c814, 0x060c1f3b, 0x0ee80bff,
- 0x05be14fd, 0xfa50da77, 0x436abced, 0x46705e6c, 0x193d9172, 0x6cdd1af2,
- 0x3a724adf, 0x14051dc8, 0xadf6b80e, 0xf4d68427, 0x8035b2fb, 0xfb0f6a3a,
- 0xc1659527, 0x986ba478, 0x9cb8fbc5, 0x2e9ecbe4, 0xb8b9bcf0, 0xe061d1f1,
- 0x7ed89997, 0xef48693b, 0xe5a13f90, 0x74798fdf, 0x47b5b9e9, 0x3e3ee166,
- 0xdc90cfdb, 0x6e838c6e, 0x24179c8d, 0x25603f98, 0x6fdc2ec9, 0x7f1c9177,
- 0x307fcf16, 0x1cccbe31, 0xccffb31c, 0x1fbf45e7, 0x870fe70d, 0x375e5958,
- 0x710ca79d, 0x89c401b8, 0x33e42165, 0xf55604f4, 0x09177d60, 0xed19f91e,
- 0x7624f1ff, 0x336585ef, 0x4c87e5d1, 0xd876664f, 0x21f9656f, 0x12706ac9,
- 0x73e4ede8, 0xbb7a01c4, 0xe0a6bd79, 0xf1c50ef9, 0x3c5fcc03, 0xef002260,
- 0x01c06a8b, 0xd72d7479, 0x48e7ce2a, 0x4e66bfb4, 0xe3efd17f, 0xc85af39a,
- 0xcad078cb, 0xb1162fea, 0xd396833c, 0x5af2005a, 0x952d73d3, 0x93b3f9b1,
- 0xf13f9992, 0x78f14a62, 0x3eb043a0, 0x43f8c099, 0xa2065376, 0xbaa579f4,
- 0x63f80920, 0xe288e02b, 0xb8ecdd21, 0x3f4bfa17, 0xc3cde14f, 0xafc46ee7,
- 0x4a901ce2, 0x66fc3bf1, 0x47ee139b, 0x7829317a, 0xcb41c833, 0x839e1316,
- 0x26b9aade, 0xab6b7d42, 0x257901d3, 0x9305e62f, 0x4c5b3e71, 0xc9ad9f38,
- 0xa12dd72d, 0xa3e9af70, 0x14f8058c, 0xe92c512b, 0xcec54f20, 0x99f3e97b,
- 0xacaf4cc9, 0x7a793134, 0xf589d93c, 0x7e3a25c7, 0x8457bc01, 0x4fce24f2,
- 0x75b0b734, 0x0d29a76b, 0xf275f032, 0x25de7144, 0x3c7f832c, 0xbda08cb2,
- 0x0353691c, 0xb9538c4e, 0xfd29336d, 0x07661147, 0x08b47d46, 0x0528c3f3,
- 0xfda08f0e, 0x04a9b5ed, 0x1e7845e6, 0x4f9c8de8, 0xb28d206e, 0x70dfb685,
- 0x74c2b889, 0xe92f1bbc, 0x2ddcbff3, 0x8d14d18e, 0xb62488a4, 0x78f863c7,
- 0x00adc4c5, 0xf45894ff, 0x7b018def, 0xe318e14c, 0x49339c30, 0x1bb476e6,
- 0x2e7b16e9, 0x8dede447, 0x853dfb91, 0xcd58c0fe, 0x66d87805, 0xfb07bf73,
- 0x9506fe7f, 0x46175a24, 0x6a3ed7d6, 0x61537a39, 0x798c94b9, 0x6d1f947b,
- 0xadd707c0, 0xfdc3f2ad, 0x62f5d787, 0x81df03fd, 0x7d66b95e, 0x87d80666,
- 0x511f4e02, 0x7e033e0a, 0x7e32a472, 0x951f5c72, 0x79c9f5c7, 0xbe429fc8,
- 0x9fa0cf80, 0x46606a5d, 0xe50738a2, 0x9fc0f5cf, 0xfd046cdb, 0xb6779fdb,
- 0x12b9034c, 0xfce31ce3, 0x2d572c6f, 0x8547b25b, 0x76645f79, 0x4b977466,
- 0x3c8c635a, 0xc1852bfe, 0x4d5675eb, 0x1bf1009e, 0x2dfb8a9b, 0x162e3c59,
- 0x639d1fcb, 0x59f043f8, 0x51e58d93, 0xa9297e08, 0xbbae2bfb, 0xe2122e4a,
- 0x3f1123c8, 0x28cbf04f, 0x61f3187f, 0xd7e61147, 0xe8a5f919, 0x7d015382,
- 0xb4bf1ed4, 0x089027c5, 0xc8d27605, 0xb992072f, 0xbf26d29f, 0x5e03b65c,
- 0x6497d696, 0xa4fc5d7f, 0x5b47f396, 0x4cacc3ed, 0x5f9f19ef, 0xa8f66148,
- 0x41faab4e, 0x5b85e83e, 0x7b902e4c, 0x70b90dca, 0x325d513f, 0x95288efb,
- 0x4dbea13d, 0x5b667a61, 0x667a8cc8, 0xc1e3cd9b, 0x161cd07d, 0xa78a241f,
- 0x5c9af211, 0x35ce2c5d, 0x0cfcfc31, 0x1aa0bfe7, 0xe212761e, 0x74607f0b,
- 0x014b7a1f, 0x9d25189c, 0x1fb93367, 0x00db4a78, 0x6c3dcbf7, 0x7c0d3a2d,
- 0x04b20c95, 0x35c74f79, 0x38ad77dc, 0xdbfea1ae, 0x2950fbb9, 0x9e0afdd8,
- 0xd76431e7, 0xd062d2a1, 0x37a65627, 0x29fd71cf, 0x4e60c3ea, 0xf70d0fa0,
- 0x4c230d15, 0x53ddc54f, 0x1f937c04, 0x77bb8f6d, 0x0635d1a8, 0xef771ac8,
- 0x98f711d0, 0x7bdc2714, 0x797bc1e3, 0xe1efeee2, 0x67bc60fc, 0xc7927fa6,
- 0xf83f0562, 0x36dd8695, 0xb3276be0, 0xb2ad41c7, 0xa92bcb2f, 0x23fc09ec,
- 0x147f0ce4, 0xf7bfc15f, 0x7cf62e79, 0xbe7c2dc3, 0xb614b88f, 0x61a8dd3f,
- 0x082fe81e, 0xedc82efb, 0x1e6b6f52, 0x5f4b0bd3, 0x5d7c019d, 0xf98ddf38,
- 0xc8a58fb6, 0x2497fcf8, 0x7409e96c, 0xaf182972, 0x92ceaa0a, 0x3df45293,
- 0x81f594a2, 0x4eaed4b8, 0xfe3085c9, 0xb5cf56c3, 0x5a513f00, 0x4377c20e,
- 0x82141786, 0x580db65e, 0x4a760199, 0x1ae14dc0, 0x8516c9bb, 0x6595c043,
- 0xb0f87c65, 0xd6b5e675, 0xd03bec4e, 0x4f47b53b, 0x417be058, 0x39fd60ff,
- 0x3e18f746, 0xf947ba00, 0xea1bba40, 0xdc050f02, 0xbff2dede, 0x25c60f87,
- 0x87e103e2, 0x76ecbf51, 0x1ff78fc0, 0x73b37b97, 0x6fcf2c1d, 0x24778c88,
- 0x9b25f246, 0xb05d8a72, 0xf9d1597f, 0x3e525887, 0xa067ff3a, 0xff766ee7,
- 0x04e7f0b0, 0x45cbe4df, 0x234bafd8, 0x2e83de78, 0xe21fb0d8, 0x823cc349,
- 0x63060eed, 0x744fdff3, 0x59282ea3, 0x72674d60, 0x1bb5efc9, 0xefd09610,
- 0xc715401c, 0x75d7e81d, 0xe2e8bd45, 0x242725f8, 0x03c5ce09, 0x05c95f2b,
- 0x019c33ff, 0x8f300fe3, 0xed3ec30f, 0xb951d66b, 0xeb029f30, 0x8fc09ec8,
- 0xfa59f7af, 0xaf693027, 0x7dbf9977, 0x4fea33a3, 0x97b8fd09, 0xbfc62b77,
- 0xcbf4cadf, 0xcfb66e8d, 0x163d7a0e, 0x801f610e, 0x1487008c, 0x62ba6a9e,
- 0x6a1dbd45, 0x11be78a4, 0xd8f4a0e0, 0xf01a9123, 0xee4c8a17, 0xfbf012cc,
- 0x8015853a, 0x5ffeb9b3, 0x340e20dd, 0x23fbf43e, 0x9178ef00, 0xe7d2eb1f,
- 0x6cfd1ac7, 0xf588ffe1, 0x148ff086, 0x47e1088a, 0x7874fb41, 0xe0e9f14e,
- 0x0c8de0f7, 0xfefe305b, 0x5af3ab78, 0x85779737, 0x98bc63ce, 0x572be5c7,
- 0x4cba5246, 0x5a3f3120, 0x0a4a05bf, 0x2483f8ff, 0x82f18c9c, 0xe7f80516,
- 0x8e449716, 0xadd9f0c5, 0xf875f543, 0xf68aca8d, 0x46fbded7, 0x2242323b,
- 0xff1f9b5f, 0x3e83cb4d, 0x47f62fb6, 0x18f7db1f, 0x2bf643de, 0xed0db0e0,
- 0x1c3bf6cc, 0xb5070f0c, 0x73ed76c4, 0x4dc3ef2e, 0xef10f98d, 0x4bebb3dd,
- 0xee6fa3b4, 0xf05df2fa, 0x569d871b, 0x8767c408, 0x8a981e9f, 0x39a1d271,
- 0xf442be78, 0xc6b4fdeb, 0xe473d84a, 0xdfff711f, 0x5b8f0a01, 0x582cf803,
- 0xf1f671be, 0x0bbfa027, 0xdbc615c7, 0xcd52fc7c, 0xebe20bd3, 0xc81efca5,
- 0xa7f31203, 0x7e01fb44, 0xd6bbdaef, 0x31105e48, 0x3497d2c7, 0xe820bfa0,
- 0xb1a9cb78, 0x78fc95a7, 0x98efc0ba, 0x39afbfe0, 0x295edccf, 0x714e97f6,
- 0xefbd91bc, 0x4ddb3ee3, 0xe02af735, 0x2394dfa7, 0xb8cc7713, 0xe2569ce3,
- 0xfc6b898e, 0x63f06ac3, 0xc4f4bef6, 0xbf8b8804, 0x2f91e325, 0x9fdb686f,
- 0x20dea1f2, 0x3377dc27, 0xd0a6f5e2, 0xfdf00abd, 0x97931b38, 0x7e1fc6f6,
- 0xeb8fe51d, 0xf984de81, 0x9425837f, 0xdf5d231f, 0x8cdbf5dc, 0xf8f17ec6,
- 0x02de8b6e, 0x6f0e82ef, 0x054e2d9c, 0x0747b47c, 0xa6ee9f23, 0x79d3f3f3,
- 0xfcfce985, 0xd37b4fd4, 0x3efac0e7, 0x05d60e5f, 0x9feb7a7f, 0x4f3f00cf,
- 0x0c98e5f0, 0xeac327c6, 0xb620c89e, 0xf88c9d28, 0x74636eea, 0xc0e9fc9b,
- 0x7e3e5414, 0x6ce700d2, 0x536c38ca, 0x57ef1389, 0xbdfcfc24, 0x954dbed1,
- 0xea0318ef, 0x8cdf68d2, 0x738a6d76, 0xd7c3de26, 0x6384bdde, 0x2052aadf,
- 0x5954b3dd, 0x80fbb0aa, 0xe02e9f99, 0x6ff3d231, 0x09b6eca4, 0x19f0db52,
- 0x67071de9, 0x3d353caf, 0x3fc2bc01, 0x4e10f717, 0x78f686f9, 0xd7cf4db8,
- 0x7e8d4fe7, 0x5b6ad41b, 0x8ba46472, 0x83e85db1, 0x00a01852, 0x23f83f4b,
- 0x48596ce3, 0x1a4bd2bf, 0xb579c371, 0x93e449ae, 0xc642bb18, 0xba7e4777,
- 0xb59ec1cf, 0x97154fc5, 0x1193c44c, 0xf6b52be5, 0x55f02b31, 0x8565529d,
- 0x6c1babfd, 0x52a45713, 0xb4fe8c3c, 0x5bee0a78, 0x84089a35, 0xce84c6c6,
- 0x813885ed, 0x1c5d5f38, 0x7c0253da, 0xc0694fb8, 0x05f35375, 0xf8c61bea,
- 0x15a1b599, 0x6ac3f056, 0x0b8c6533, 0xba23481c, 0x6dc7a073, 0x3daaefcc,
- 0x9dc13ade, 0x0a73bda0, 0xdc4c9f6b, 0x6768f999, 0x51be3053, 0xf384daba,
- 0xf6b92d1f, 0x321f8267, 0xd9afdd9d, 0x7f643f5c, 0xe9b78526, 0x1fd434ce,
- 0xba1f6a63, 0x110941d7, 0x3e2177fc, 0xb929996f, 0x95efa39e, 0x2f585d3a,
- 0xeb879d9d, 0x655f21b8, 0xed0f1e4c, 0xd75c54e3, 0x2917918c, 0x3cfa6f10,
- 0xf5802a47, 0x71a92ee1, 0xe4fc1999, 0xe21c6c89, 0x7ac067f0, 0x19f19df3,
- 0xcf20d603, 0x05d5fa88, 0x75ea186b, 0x3ba5b3eb, 0xbf81efce, 0x36f4b04f,
- 0x8e51cf09, 0x7f12e471, 0xae94ff0c, 0xfea4f4a6, 0x7650a4d7, 0xe4f1f031,
- 0xc40932b1, 0x656df1f0, 0x5d881256, 0xb1f3f20f, 0xde2af52d, 0xf8e42037,
- 0x53bfce66, 0xdee865a7, 0x0ede6fa7, 0x886267f6, 0xfcb841c7, 0xd9cb80fc,
- 0x3bfd7ccd, 0x1bab93dd, 0xbf308cb7, 0x65a4cfe6, 0x671d2a74, 0x960f4a76,
- 0x70d2d51f, 0xe5f07318, 0xcf4083ae, 0x618fa0fd, 0x5a2f2b3d, 0x2390fc89,
- 0xb77f00b9, 0xb7edf4b8, 0xe3d7d50e, 0xe8353fee, 0x74e0db81, 0x0faf1c94,
- 0x56dfdc84, 0xc710ab2f, 0xe288adb9, 0xbd61fd17, 0x5eaede7f, 0x107cecb8,
- 0x5bef86dc, 0xb2a4ec2f, 0xefca9436, 0xae1fa16e, 0x7e815722, 0x3f572318,
- 0x4cd2fc01, 0x01399eed, 0x21fb08bf, 0x54a5f3d6, 0xc83f815e, 0xab8c4cd9,
- 0xe544b98e, 0x9eba2336, 0xea0be88f, 0xf812b84f, 0x7ad81f39, 0x221df6ea,
- 0xd4fe83fa, 0x9fdddfc1, 0xb550a318, 0x75700052, 0xd442fe25, 0x2c571857,
- 0x10450385, 0x8739cbdf, 0x42af1b71, 0x5768a7d7, 0x8c7a679f, 0xd2ae0bfe,
- 0xf46ffc15, 0x789c4433, 0x7ff08a52, 0x89117cf4, 0x31514e17, 0xa1f8238e,
- 0xf208f014, 0x38c6453d, 0x21fc7b7e, 0xe29fffc6, 0xe3c2920b, 0xaf48bd7f,
- 0xe083f08e, 0x4617c103, 0x4347f1fb, 0xfb2da75c, 0xf5f29691, 0x1f7f63f6,
- 0x7b74f515, 0x6764887e, 0x7363d97a, 0xb5f37960, 0x0fc0d9b7, 0x83f5c499,
- 0xf89143b0, 0x17c65ad4, 0x29671bfb, 0x05e46fb0, 0xc51790bd, 0x0adf88bb,
- 0x4d58ac3e, 0x9e397e30, 0x7aa6a5eb, 0x8ef3cf16, 0x12900396, 0xec7a1252,
- 0xf9675609, 0xb79e822e, 0x5228be70, 0xf7f028f6, 0x49756e5f, 0xb913882e,
- 0x82703c79, 0x6078c25b, 0x7f823e9c, 0xc75bf6d0, 0xd758014a, 0xa093f519,
- 0x7fde64f7, 0x7df09f1c, 0xdc9f2357, 0xbee5c290, 0x9ffee93b, 0x03c60bf4,
- 0x4db53b5d, 0x7b7df157, 0xbe0d9d74, 0x5ed9c82d, 0xfe02bf96, 0xa6f5d035,
- 0x3bf60a4b, 0xe7ef4535, 0xf05b385c, 0xf20b5c4b, 0xaf798df7, 0x37b4f9c6,
- 0xc7e124fe, 0x8c5ebf73, 0xf2c2b37b, 0xa6768df9, 0xbfc2bb5d, 0x32abd233,
- 0x26bfb125, 0xde1c6bf4, 0x8b6dfeb9, 0x5fe9ed6e, 0x53feefa1, 0x2bf457fa,
- 0xcf1882ec, 0x5adb97a8, 0xbb3d09cf, 0xe309836a, 0xf5f03727, 0xae3c0df2,
- 0xc3f70cfb, 0xdede3c02, 0xf782d17c, 0xb6550653, 0x63dfe53f, 0xd6d038c3,
- 0xe97fccdd, 0xfbe2756d, 0xc6324a0f, 0x641c1e29, 0xd74c3d42, 0x3f308526,
- 0x3e9098a5, 0x85dacfb0, 0x2b56b3ed, 0xe3d432e1, 0x7e40852e, 0xf1959e54,
- 0xfa6f83c1, 0x0fff4067, 0x5a6deb1e, 0x70e37181, 0x4331f803, 0xa7dc140a,
- 0x313b334a, 0x6f54dcce, 0xe6aabcc6, 0x03daffba, 0xf9aa277f, 0xf2c17122,
- 0x39bd5f66, 0x7a044fb2, 0x96fc8c62, 0xcd11790c, 0x0ef3042d, 0x970b4e47,
- 0x06e97ac0, 0xd602b0d2, 0x7635c3e1, 0xa788dd8e, 0xc6de7ca3, 0xbec8847d,
- 0x1bcb3d41, 0x79e14929, 0x06fb7123, 0x6fb8250d, 0x15ae48a0, 0xd33ed124,
- 0x60df667f, 0xf29ce038, 0x7a0c5ff3, 0x7fb1b488, 0xfb6355b0, 0x54872d4c,
- 0x39327e02, 0x5e309995, 0x423eded3, 0xb764eedd, 0x82fb0ed3, 0xdbaf9fcc,
- 0xccedc5dd, 0xfcfdfb6f, 0x986296c6, 0xd36ad6c6, 0x47632b4a, 0xe246bb8c,
- 0x727c4671, 0xbfedc7bc, 0x61a35c84, 0x63c462dd, 0xe2194b71, 0x4fe29bf7,
- 0x13d6c5c8, 0xebe06ec9, 0xb8ba27ad, 0x3c63dc61, 0x3b32e70e, 0xbf7604fe,
- 0x326b78ee, 0x6e6ab3ee, 0x5a1bac27, 0x762e2cd2, 0xf3e3110f, 0x78dee760,
- 0x3c07fc6f, 0xb935b7ae, 0x337d8fe5, 0xd851f763, 0xc51349be, 0x0faa3eeb,
- 0x3cfd5f7f, 0xfe7e03e6, 0x13cc51f2, 0x4c86f85a, 0xadaf102c, 0x85e7e14e,
- 0x03f81a03, 0xee3235e5, 0x18b9534f, 0x5625393c, 0x7960acdf, 0x3dd95b34,
- 0x99afe59f, 0xf7e9e303, 0x927fafe5, 0x4df6f90f, 0xc00e5bcb, 0xbff01fdf,
- 0x33bfb12c, 0x87cc6fe7, 0x95cb9afb, 0x2eb271c4, 0x9d7fe676, 0x034eb3ad,
- 0xccda40ff, 0x79605efe, 0x8e6aaa70, 0xd9a5ef59, 0xd31ef155, 0xec492f0b,
- 0x5f0a097e, 0xe2bf7dec, 0x7d9c06ef, 0xd5f06249, 0xbbf801aa, 0xb79be583,
- 0xbe39c135, 0x5c6623f2, 0x9f3779bf, 0x4b33fbc3, 0xfcc16eb6, 0x4cad6f60,
- 0x09d619f6, 0x9b53f3ba, 0x45e430e5, 0xbfb0d455, 0x98eb4023, 0x4c115527,
- 0xbdb08e7c, 0xb70b3e73, 0x87eebfd6, 0x2feda83c, 0x9dbec1da, 0x0764d869,
- 0xbf7ed3bc, 0xdc62fcf6, 0xc3e0a979, 0xea5e7b5f, 0x5a72610c, 0x379c3762,
- 0x37c19cdb, 0x6383c223, 0x78a3faf3, 0x70b9fc64, 0xe067c5cb, 0xd7d9ef3c,
- 0xe0067b3e, 0xf9d5f45d, 0x0d7f6067, 0xbd60f512, 0x6ff97dea, 0x7c521e78,
- 0xdff72777, 0x117a5e9a, 0xbd3691cf, 0x6f41766f, 0xbb27f54d, 0xa6ca79c1,
- 0x82caff6d, 0xfad2deb8, 0x2e77e831, 0xcffd41dd, 0xa2bafb04, 0x83e8326c,
- 0x1ab1ceb6, 0x66b7b5e9, 0xf380376f, 0xf06f4a73, 0xdfe7237b, 0x2ecf2c82,
- 0x3aadee72, 0xb8e179f1, 0x93356e73, 0x2061bd6f, 0xd40baa94, 0xdde7bb46,
- 0x5e3a530e, 0x55fa01df, 0xeaf3cc3f, 0x73efd312, 0xd3a507f8, 0xf3faeccf,
- 0xe66b17e6, 0xb434fb3c, 0x79b464d5, 0x01dc2dde, 0xc8f389bc, 0x55eeed63,
- 0xd79b9076, 0x85f3c15e, 0x74f1b740, 0x2e5b4da2, 0xdc738376, 0xbb96d4a7,
- 0xda836f30, 0x940b8843, 0xf287bfd7, 0x10e3b4d3, 0x3f0969c6, 0x2244dc17,
- 0x538e763f, 0x98dcf3e2, 0x71c9cec2, 0x3a39c3fc, 0x39f4e3d0, 0xf8c72f3f,
- 0x6ba39c58, 0xbd5cfceb, 0xefbf07bd, 0x77bb13ba, 0x1a87e378, 0x4a20dfbb,
- 0x3468692f, 0x3a2dbd0f, 0x00383c09, 0xcf62430f, 0xa73e2683, 0xcc373918,
- 0x03f405e9, 0xde722fff, 0x6247d693, 0x248f7a5d, 0x1b4d07d0, 0x26d239d8,
- 0xf53df135, 0xad687ce2, 0x9e62ce81, 0x9087c96d, 0xffe0f6d3, 0xc979f8a6,
- 0x8bf1d4ee, 0xcbd9d3c0, 0x87f8f589, 0xddbbe976, 0x8c96e36b, 0x607cdaf7,
- 0xd3f704ef, 0x98f9e51e, 0xcc5acf2c, 0x96f82cf7, 0xbecf4f94, 0x17fde32c,
- 0x517b82ab, 0x85f51b8f, 0xc23597d8, 0xb78739fb, 0x89d996a2, 0x04a5afb3,
- 0xb39fb46c, 0x3f21d66f, 0xd51f5457, 0xc0ef8f20, 0x8b1aede6, 0x01f933d7,
- 0xc71b113b, 0x9eeafb3a, 0x24dbd47c, 0x97f27e71, 0x437a1f5c, 0x56f1c789,
- 0xb38dd39f, 0xfbc41fd0, 0xef1bdab1, 0x0a9ee28c, 0x50699dfd, 0x4cfa3f31,
- 0x8d41c590, 0xedcc7fe3, 0x203ee466, 0xcf412f6a, 0x5768fb88, 0x3cf30468,
- 0xe79626fd, 0x6a7efc69, 0x00d3c32a, 0xee04b387, 0x82d9750b, 0x52b8b9b8,
- 0xd4cdc32e, 0x6c7b9115, 0xf6f7f85c, 0xe4977922, 0x2f309b91, 0x925de452,
- 0x50bd5927, 0x613703d4, 0xfe10e51e, 0xdac03fbe, 0xeb4c2161, 0xecf97eb3,
- 0x2c7efe4d, 0x3320b26f, 0x9cffcfea, 0x829630fa, 0xd5a67ee8, 0xa049fc4c,
- 0x3ebdf82f, 0x22b27f22, 0x3575e449, 0x9ef7f3b2, 0xfa5f9d6c, 0x77a7bb47,
- 0x5b73ec2a, 0x552776c2, 0xc6eb4b29, 0x4e2a1da0, 0xfabe2075, 0x03911f6e,
- 0xc1ffc1fb, 0x76a707f1, 0xa57f1f8a, 0x6ab7faca, 0xe074dfb4, 0x4025be97,
- 0x09ddbee7, 0x831773e6, 0xa3bf4a13, 0x9e7c14cb, 0xfec1c944, 0x073b995e,
- 0xd22b1fe2, 0x2c63cc34, 0xdd00b0a6, 0x5e5c658c, 0x72a9aa68, 0xa5c72d1b,
- 0xcdc875b2, 0x1ebe4ea9, 0x277f6169, 0xffc2d1cc, 0xe7db184e, 0x9682e597,
- 0xe981d830, 0xecbfcc29, 0xdc31f2da, 0xb4eef1ff, 0x37582ebe, 0x7a4c0d4d,
- 0x21b7e610, 0xf00933d5, 0xeeb4befb, 0x9b5f946a, 0x34fc0527, 0xfcb1ddc9,
- 0x8871f8d0, 0xdbf4fc05, 0x61057187, 0xbc18f763, 0xe955943b, 0xa7c01e78,
- 0xae323f18, 0x03d8bf21, 0x13883d71, 0xf11efbf1, 0xce3a7afe, 0xcc26e3f6,
- 0xb64a6f8f, 0x59b47bf3, 0x00b608dc, 0x3fc7def0, 0xbef9972f, 0x5f775f96,
- 0xa7bb2d5c, 0xb89eee3e, 0x08129e83, 0x8bef1839, 0x3b37de33, 0x4f300494,
- 0xdc7f78d4, 0x307ebe08, 0x40f71bde, 0x5d0fb72a, 0xbddd1748, 0x5fd616db,
- 0xf03d5beb, 0x09dc1b9c, 0x6b3c5325, 0x4d0c994e, 0x0d73ca8f, 0x3e708fd5,
- 0x4e7e75f8, 0xc761ffb8, 0x2d7f003d, 0x79435fdc, 0x1dfc177b, 0x072a2d13,
- 0xbb930ffd, 0xb9a75ec1, 0xacd4ff99, 0xd3cb7bb2, 0xbf4058e8, 0xc98fb834,
- 0x89c4fa0e, 0x9bfe1b79, 0x3c7bee09, 0xa0499729, 0x92e9721f, 0x5c47ee1b,
- 0x3dc7cfc9, 0xf6e9326a, 0xca9d7e61, 0xf96fe3f4, 0xefb1633d, 0xb7a04a4d,
- 0xeb654d9f, 0x552cdb85, 0x9f198557, 0x9f740b3d, 0x70a8f26e, 0x599a9b4f,
- 0x331c42a9, 0xce4fca35, 0x13e2092b, 0xeecedfef, 0xab5f7f4b, 0x81ebf39a,
- 0xef66f3d1, 0xc7814600, 0x6fb8e92c, 0xbee38d3b, 0x4d4ce9d5, 0xd5a7818b,
- 0x99dbe426, 0xeadb720a, 0x91e589e9, 0x1f719a1f, 0xcfa688e9, 0x02f71783,
- 0xc480fb89, 0x7da2417d, 0x291586fe, 0xe91f1fe0, 0x74e77443, 0xd2ff5c42,
- 0xf9039ef5, 0xf3a3047f, 0xa67f73fb, 0xff15dfc2, 0x82f48fab, 0xc5f187bf,
- 0x4cdd73f4, 0x73cddf14, 0xd7f8b9ff, 0x79a3ddb4, 0xdcbc04de, 0x1578db9d,
- 0x531dd7c8, 0x4dfa41ce, 0xf9bf7cdc, 0x9e3f653c, 0x61250ecb, 0xef3bc23c,
- 0x4f180acb, 0xe6f687e8, 0x1d972f9b, 0x2a70bd06, 0x8bde09f0, 0xf626c646,
- 0x8dfe8d5f, 0xe71773e0, 0x0db231f3, 0x493356ed, 0x5cac7966, 0x73ee636e,
- 0xb37ee273, 0xe209fc9b, 0x98f62b3a, 0xd99fec08, 0xe1778941, 0x87754882,
- 0x8af6165d, 0xf5942db8, 0xda1fcd21, 0xb95ea54f, 0x17c42569, 0xc8682fe0,
- 0xfa80faf1, 0x56296e2b, 0x4f2bec0f, 0x79d607ac, 0x5a96c056, 0x58607a7b,
- 0xdb7e84d8, 0x5f07d537, 0xe281f419, 0x82be2270, 0x605033e0, 0xc43e1fff,
- 0x8000938b, 0x00008000, 0x00088b1f, 0x00000000, 0x59edff00, 0xe554707b,
- 0xef773f15, 0xc3cdddde, 0x210366e4, 0x804d8404, 0x85701020, 0x5c7c0188,
- 0x94422101, 0xd6da0300, 0x02101ba9, 0x16a52d79, 0x9b8cea9d, 0x8e233480,
- 0xd29dad13, 0x542cce96, 0x2ec4952a, 0x4dd0689a, 0xd15c04ba, 0x63e02711,
- 0xb46d63a0, 0xec083a2d, 0x98f8a71a, 0xe739ec76, 0x647dd7bb, 0xeffa7471,
- 0xe5f98617, 0x7cebdfbb, 0xe3cefce7, 0x648a12fb, 0x40a50307, 0x676a733f,
- 0xf1d31c02, 0xee016bb7, 0x0d1c442a, 0x00f250e0, 0x007f73e6, 0xd63c03c6,
- 0xe9b6dc06, 0xdb007b5a, 0x2ed8c9ae, 0x95d6c801, 0xfc76edf6, 0x06dbb8fd,
- 0xbab60173, 0xc00f77f0, 0xf9e9b1f0, 0xffbf8150, 0xbe956be7, 0x16bcea57,
- 0x373f4d7c, 0xb772b025, 0xecf7000d, 0xb5ddc372, 0x9d701e34, 0x913ac4a2,
- 0x46383668, 0x9dbac401, 0xef289d7b, 0xb1b0b870, 0xddc3db13, 0x5a64d759,
- 0x1e17c2cf, 0x40074ec2, 0xf3e36e8d, 0x91bdb05c, 0x35eb8157, 0x87973cf5,
- 0x33c685c7, 0xd752e6a7, 0x64df0e9b, 0x4e7dcf1d, 0x9aee5bd9, 0xc1ed1d84,
- 0x508fa459, 0x87df2ca4, 0x43b4ccf2, 0xe47b3ec0, 0xf8ddfefa, 0xcb400e71,
- 0xcce3376e, 0x987a9cf0, 0xe223df85, 0x8687b43c, 0x817ad35d, 0xb77b17db,
- 0xff3d69bb, 0x7c4afa5f, 0x470700b9, 0xc4219dc3, 0x2e98be67, 0x4ec1dbe6,
- 0x05e9e7e3, 0xd0402f2c, 0x39170ab6, 0x9c38e1a8, 0x1b0bf177, 0x9ff6b38f,
- 0xaab37bd9, 0x222a89a3, 0xfa80031d, 0x3d3b0ac8, 0xa7accf64, 0x676e1400,
- 0xfdc14105, 0x528297fa, 0x002bfa89, 0x5dfd82af, 0x01f7f1d9, 0xa73ef1db,
- 0x67f61f67, 0xc6e01de9, 0x421cbbf5, 0x8c00d3ff, 0xdf1372e7, 0xc2b2fdad,
- 0x65c806bf, 0xea411bbb, 0x0dc077b7, 0x9b7e89b9, 0xfdcb057e, 0xa7f05d43,
- 0xcb623b2b, 0x53e23945, 0x5cb1f600, 0xf7813909, 0x169ce4b5, 0x7fb4280c,
- 0xa303ecfc, 0x9f7d2e58, 0x7210e487, 0x67aa7842, 0x0dd7cd3f, 0xee96473e,
- 0x74f8d2f1, 0x20b3fcb9, 0x9e09f908, 0x55018fe2, 0xd13b3df8, 0xfb855d76,
- 0x42de0994, 0xe2fb7660, 0xc4da93eb, 0x7cc4aaf3, 0xfb6d7ebf, 0x1db9e40e,
- 0xa9a2afed, 0x70af1073, 0x7c3d39d3, 0x31bca43e, 0x83d0b67a, 0xe394f517,
- 0x8cdffd12, 0x52e6fe47, 0xf38c573b, 0x659cf53a, 0x400feca5, 0x8202d0fe,
- 0x912af7df, 0x00a937b3, 0xcdaf1fe7, 0x9d73c0af, 0xeb6c0db7, 0xd49f71c4,
- 0xd823ca85, 0xfdf3ceae, 0x5efdc75c, 0xaedd6f7c, 0x739fa899, 0x06b79a5d,
- 0xe050c1e7, 0x8fa87189, 0xcf346786, 0x007e4923, 0xc445e3e3, 0xfc7df4df,
- 0x189eda67, 0x58747e47, 0x1db0b8f1, 0x4813e2d3, 0x47f096ee, 0x7978830e,
- 0x078703f8, 0xf81715e7, 0x543f9276, 0x222eb6f5, 0x8e83cebd, 0x0ce23aed,
- 0xaf88f81b, 0x0f5c62a1, 0xbb7e1df7, 0x926b5f7c, 0x85753a1d, 0x7dc407e3,
- 0x0a916b13, 0xfaffd361, 0xf631721f, 0x24c1f91c, 0x1347bf5a, 0xb5e6b33c,
- 0xd238c0c2, 0x631c1b7b, 0x82c7beb4, 0xd9e26af6, 0x775d778c, 0x9fe3491b,
- 0x69f9fd36, 0x41710fda, 0xc90f6f81, 0x43e478db, 0xf39d1e47, 0x8009a19f,
- 0x4f764243, 0xf97b9ebe, 0xf34fe0f8, 0xee3dbf27, 0x8ffef1a0, 0x7415df91,
- 0x079f0f1e, 0x1f23beed, 0xddf078ed, 0xd875e9de, 0xfc2a53df, 0x1dab47b1,
- 0xdf5be347, 0x086b34b9, 0x123231f1, 0xd7d4bf8e, 0x86f49138, 0x4d985ffc,
- 0xf908767e, 0x69f849ef, 0x8a29f905, 0xaffc415e, 0x8e34f6a4, 0xc18e5dc3,
- 0x3d97ec65, 0x44bf2036, 0x203fb3fe, 0x40fdf5ff, 0x781fd1e3, 0xf3f654fe,
- 0x419b41ae, 0xf1c600ed, 0xb85edc29, 0x835dda9a, 0x73f6758b, 0x3679f21b,
- 0x80646bf9, 0x4c0109d7, 0x5029d321, 0xf648aa1b, 0xa3d63cdb, 0xdba7d4cd,
- 0x55d0dff4, 0x9e2f7c9e, 0x53554723, 0xb54f23fc, 0xb502f225, 0x3fdc2bb7,
- 0xed0df1e6, 0xc13fa24f, 0x740799a0, 0x2d383bc1, 0x5d4ff9e2, 0x7d6ffe22,
- 0x4e8afe65, 0x13d6e73c, 0x13f7f72a, 0xce31ca4f, 0x78193c9b, 0xe536e748,
- 0xe7da0f05, 0xfcc543d8, 0x1b6c5afd, 0x1ae74718, 0xba51165b, 0x38eeaaa9,
- 0x36bf384a, 0xbc4348b4, 0xa3c1cefe, 0x19f3709a, 0x81eebfc4, 0x29d8675b,
- 0x42719dee, 0xfdd88a16, 0x67fdfc55, 0xfadb0f50, 0xf219ff51, 0xf9871e06,
- 0x0e3b5007, 0xc7f6478a, 0xdc8e2b14, 0xbc7c4d5f, 0xda26add8, 0x120b4828,
- 0xf417da9b, 0x6c01ed6d, 0xc46057df, 0x71bf9789, 0x8d44e2fb, 0x8aafc9d8,
- 0xde7b2dc8, 0xe28f30fe, 0x98c3b77f, 0x2ee9fc41, 0x0ca14d83, 0xd74f7d3c,
- 0x4e954f98, 0xdfa992d8, 0xa0fc205d, 0x88bb003c, 0xaadd2d47, 0x5fbb441e,
- 0xc70d56e8, 0x431f00d5, 0x8a02ed60, 0xb0630137, 0x01bff518, 0xc8031fac,
- 0xa6894d1e, 0x68daf641, 0x6b1c3736, 0xd63ca1a8, 0x20e83ea4, 0xa4f8da3f,
- 0x55d0e1f6, 0xffc6ee66, 0x27686153, 0x53ff11c5, 0xed82378a, 0xfb527b4d,
- 0x7887c21b, 0xa953c35e, 0xb13a9bdf, 0xddb44aed, 0x3a8c5705, 0x997f033b,
- 0x42b09304, 0x5c711e20, 0xdc70ecd0, 0xd97dbc89, 0x6f4953ed, 0x3f426d07,
- 0x0fd94f18, 0x2cbf2b55, 0x7e287114, 0x2fec8201, 0xf3474207, 0x9df9ae50,
- 0x63da5ea5, 0xcff45dbe, 0xfce52def, 0xbaa0f602, 0x65500d12, 0xde9096f8,
- 0x176f2f51, 0x9937b9e3, 0xfc7411f1, 0xa6cded87, 0x1e91361e, 0x073635d0,
- 0x079ee553, 0x4fb4edc1, 0x3f3c01fd, 0x903c6bce, 0xd7e96fda, 0xb4d3ae6f,
- 0x2c7464fb, 0x75287362, 0xfd1e1f9c, 0xa17aa554, 0x73fbf537, 0x5cc09bc0,
- 0x60133f4b, 0xeb07e902, 0x97b1802b, 0x8ee4678f, 0x344f97a4, 0x329c5751,
- 0xd7fab1d7, 0x41697c9a, 0x344e28f1, 0xf120d505, 0xc8129365, 0xcfb79503,
- 0xd7b943ad, 0xe0f0bc5b, 0x3dc7d43f, 0x9bd67ea6, 0xe173e0bc, 0x4a3de6fc,
- 0xeff38230, 0xfe553479, 0x25baa10d, 0x79233ce3, 0xab53a9b3, 0x6e7e6073,
- 0xb40e2d80, 0x98de48f9, 0x70e800fa, 0xe74afe50, 0xb94f8b4f, 0x6e46dc8c,
- 0x5fffdcdd, 0xe22d46ee, 0xf8da7ca0, 0x201bc52b, 0xe27fbbf9, 0xe791b280,
- 0x60dbecb0, 0xd73cc4f1, 0x56cf3df7, 0x61d3becb, 0xbab7db3a, 0x37d93bf0,
- 0x6f463ebd, 0xc618ff63, 0x9150577c, 0xfcfa4fe0, 0xbd9d6625, 0x5e303774,
- 0xcf2cfde8, 0x8362f383, 0x68c079c3, 0x47bca6ab, 0xf149c9ed, 0xcec0ada6,
- 0xfe2ceefb, 0x500b63c7, 0x690f4b3f, 0xa0e0ac5e, 0x96ad4ae9, 0x95d373f2,
- 0x4e4d14af, 0xe6ed27ca, 0x3687a5f8, 0x9c5165b4, 0x25e293f8, 0x7f858bf7,
- 0x40ed4036, 0x829de2a7, 0xc383a3f3, 0x7b202e6f, 0xa5cce714, 0xb77dfcf5,
- 0x76c2e8cc, 0xaf1cdf74, 0x17ac49ea, 0x2df38b75, 0x7ce352bd, 0xe724be79,
- 0xbf68350f, 0xfb2f6306, 0x9e97f9f1, 0xc79f9077, 0xc62814ba, 0x47c5a28d,
- 0xbea00d9f, 0xd270bfcf, 0xa2f84541, 0xa18e93ee, 0x2e03a96f, 0x50885504,
- 0x3877b03c, 0xdb52bee8, 0x10c72ff3, 0x7d4f45d5, 0x34bd20e0, 0x471c2af4,
- 0x41a8f61a, 0xb47afe0f, 0xf10745ef, 0x8153a5a8, 0xfdc9a531, 0xe663f71a,
- 0xc23e7964, 0x092adffe, 0xf933ae7e, 0xe2d3f168, 0xce333aeb, 0xe54f6fac,
- 0x763046e3, 0x0dfce096, 0x4f1c759d, 0x8e647437, 0xaabc5633, 0x28ead88f,
- 0x4eefd7ee, 0x1bf9b71d, 0x941c061e, 0xd9e3d317, 0xd3878b51, 0x70f11a60,
- 0xa26eb238, 0xe97f791d, 0xa844c364, 0x37afa918, 0xe56d7ccc, 0xf5e9cbcb,
- 0x0e67ef62, 0xf1fe73ca, 0xfc17df1a, 0x48edffe3, 0xe209c9e6, 0x25b7e609,
- 0x3ed94fe1, 0x8b23e135, 0xc0dbbf69, 0xbdfa44d7, 0x53a39c2d, 0x24335bfd,
- 0xd85976fc, 0x242a0c19, 0xdbf38d9f, 0x41da106d, 0x3bf58ff6, 0x92f03fb9,
- 0x981075c2, 0xd4deac71, 0xdfa9bd77, 0x8d5fbc7a, 0x30f54d9b, 0xfae283ea,
- 0x6ea37b55, 0xbf316fec, 0x3476bd37, 0x0cbcf48f, 0x16599c44, 0xb2c67112,
- 0xd2279597, 0xd0331cfd, 0x8ddec98f, 0x823c2761, 0x719b97e3, 0xc6277966,
- 0xdfa46519, 0x30e6c6c7, 0x423d025f, 0xd8bcf4de, 0xfe3a9dd2, 0x2ba8814c,
- 0xf67acd87, 0xd57b34cb, 0x02a721c4, 0x51e65bd7, 0x359e41bd, 0x8ffda768,
- 0xe1fe42cf, 0x933dc7fa, 0x397b1ef8, 0xd669bd3b, 0x057b56e9, 0xc3ea8b12,
- 0x5b91de90, 0xf737e490, 0x3921d860, 0x01a9e61a, 0xbdd27fd2, 0xd2ecc565,
- 0xdd16f78c, 0x1d5fe38d, 0x6bd1febf, 0xc62def92, 0xe1e272de, 0x597f8a2f,
- 0x43e29b33, 0x172788a7, 0x7cdd70ab, 0xeb81c3aa, 0x33a77f5a, 0x3f0bf748,
- 0xadea88f2, 0xf213c4a5, 0x0b72b0cf, 0xfeeb04f1, 0x4afeb4f1, 0xe146192c,
- 0x8af657f9, 0xe2e5647a, 0xaf77994f, 0x46e7164d, 0x74c98dbd, 0xffeab00f,
- 0x9d442f96, 0xb16f7d69, 0xa03df10f, 0x6f30ac25, 0x9cbe07bb, 0xc6f28a50,
- 0x509f3efa, 0x16eb5887, 0x54f5b479, 0x797d5036, 0xa0ceaff1, 0x74bce513,
- 0x1f0fe5f8, 0x2ea5f6c0, 0xf2e63117, 0xc1d95c71, 0x0da2d37e, 0x721d7115,
- 0xebbceb18, 0x7c73bd68, 0xc81ee88f, 0xbc40dbba, 0x5137ceb8, 0xb5bb16ff,
- 0xa9d71b42, 0x9183b06d, 0x3ae499ea, 0xcac75eae, 0x8d864b14, 0x566bfe66,
- 0x7bc42373, 0x57346e2b, 0x883dc625, 0x6b88dffc, 0x533b38dc, 0x5cec08fc,
- 0x1b8c8ca0, 0x777b158d, 0xfd5321ba, 0x977ce113, 0xe3dcef5e, 0x24e6de46,
- 0x1e2a1b78, 0xde84b67a, 0xa13b4e71, 0xffce94b5, 0xafb204d5, 0x9ceb7e75,
- 0x9e7e4ce7, 0xc601fba7, 0x952ad69d, 0x279b65f5, 0x708baad0, 0x7626f31e,
- 0xf5483732, 0x17fe8cfe, 0x8d0788cb, 0xb25c7007, 0x7d1da1ff, 0x90438854,
- 0x421cdcf9, 0x3ce492a1, 0x74e2ffd8, 0x97d91be2, 0xa6fc9dde, 0xb2e5d37d,
- 0xfdc45150, 0xfb88a6d5, 0x287d8f6b, 0xfe4dee8f, 0x306d6ac3, 0xfcd67ec9,
- 0x80fe4d7b, 0xefd3dc5d, 0x7c4420a7, 0xd81e0b0a, 0xef2204fa, 0x1a778ad6,
- 0x334aca0d, 0x7e442ff4, 0x035e4b7c, 0xea6d0b92, 0x33cce2d7, 0xcb1b49ff,
- 0x5c393fe3, 0x03df9c94, 0x8a18eeb4, 0xc04dad7b, 0x28072471, 0x0b1c62ce,
- 0xf97b63e4, 0x97ae2ce9, 0x6abb65a2, 0xa9956e38, 0x5b6b7140, 0xc9a9e6ff,
- 0x05bfe1f9, 0xe91738aa, 0x95aa98a1, 0xa6fec527, 0x9560da1e, 0xbc17cf79,
- 0x7888140d, 0x27a3f782, 0x47ee19dd, 0x6ddeb5df, 0x3d8273ed, 0xfa974ec9,
- 0x0dfef9ea, 0x52a6f85f, 0xef9f019c, 0xfd6dc26a, 0xfbe953f5, 0x57cdfea5,
- 0xd2a4bbf3, 0x02bf9296, 0xd5315f24, 0x7914ef45, 0xefb9bfb0, 0xd460229d,
- 0x276a7e58, 0x6efdafe7, 0x8ec4e751, 0x84fbf164, 0x07826502, 0xdd653930,
- 0xb857eea6, 0x55ea688e, 0x583e648d, 0x22dc7af3, 0x1e261e0f, 0x1486b620,
- 0x487ced83, 0xf3ef5360, 0x16a34f2c, 0x76b63b62, 0x4bbfa26a, 0x3c97d620,
- 0x00ee002f, 0x39feafc9, 0x52754c3c, 0x87964f73, 0x3eb14bde, 0xc4b1f914,
- 0xfa8fdc19, 0x99c2f459, 0xcd5b8a22, 0xf50a682f, 0xbbea50c3, 0x679b736d,
- 0xbde88fc5, 0xe81575e0, 0xda55e1dd, 0xc4b0ed02, 0x4d54d181, 0x1d66efca,
- 0x5f9bb560, 0xc8d4abaa, 0xcb06dbef, 0xe6ce512b, 0x3b4abafe, 0x78b4f419,
- 0xb634ba0f, 0x3009eb91, 0x95b65d84, 0x27f0a634, 0xf7290300, 0xb14e506e,
- 0x8d61631e, 0x03a281df, 0xfde9ca67, 0x6fe4b9a8, 0x7347e4e5, 0x537bc50a,
- 0x554bbd33, 0x7de27c90, 0x4d7f9aca, 0xafb3f0a1, 0x0b7b7f4d, 0x7bcda3bc,
- 0x9e1b2ece, 0x4d1aadff, 0x05eb847f, 0x6edd9f51, 0xb7d5cdc6, 0xbc5f5c69,
- 0xc78d1e05, 0xcca18a1b, 0xfac8bce5, 0xa78cddb9, 0xe352aa2b, 0xf03dcadb,
- 0x91a11670, 0x635b4eb9, 0x0c0abfae, 0x7575775e, 0x6635b8ea, 0x36a6b69d,
- 0x56e7fbf5, 0x930c9cdc, 0xc2ea6e39, 0x66c75b9e, 0xb90c7e71, 0x0cdef93c,
- 0xb475e279, 0xf541c78f, 0x683c0b9a, 0x1c66e3a7, 0x01c92b6d, 0x177e28f7,
- 0xa3fd9209, 0x53bfbed9, 0x719f8ade, 0x34553bf2, 0x1565ce2d, 0x29cd3f0a,
- 0x514a7114, 0x9b276ca2, 0xa3ed9c72, 0xed9baf28, 0xe7ec5237, 0x533bc4d7,
- 0xfc937914, 0xacc27c8e, 0x788aa223, 0x7b974b47, 0x8778a17c, 0x34dfa11a,
- 0x5fd08ebd, 0x36a2de9a, 0x6ec5c751, 0x5ffef856, 0xc519f58e, 0x958bb5af,
- 0x14f141a0, 0x2bfdc0f5, 0x54c3d615, 0x62704f88, 0x8f981dff, 0x4d8beea8,
- 0xb6fd7513, 0xefe2f9b5, 0x9b780124, 0x64f168ec, 0x57e45d85, 0x286b0f8b,
- 0xdf12cebf, 0x6ede9f29, 0x7755d3e6, 0x850af35e, 0xadaf4b45, 0x2f9ca7e4,
- 0xb1463146, 0x475e20be, 0x53c7eafb, 0x917d23dc, 0xf32f479f, 0xadc2742e,
- 0xa72e7eb1, 0x2fd36abf, 0xa839476e, 0x7adefdae, 0xeba5e734, 0x9530bab3,
- 0x2b581887, 0xf2138fc8, 0xc7e6333b, 0x943ca6d5, 0x47e80363, 0xedfd4d6b,
- 0x2eadf7cd, 0x0477efc4, 0x7e4c3d57, 0xb3d94675, 0xce2410ff, 0x9d187a4d,
- 0x85addeb4, 0x090c3de2, 0x9b7ef192, 0x16f0179e, 0xd7b8e016, 0x54af718f,
- 0x241777bc, 0x933eebe9, 0xb161d7d7, 0x079c764a, 0x25de9501, 0xdc3b03ae,
- 0x443b6d45, 0x200b88ec, 0xfe81dfc2, 0x4fc45608, 0x9d73fcea, 0x9944723d,
- 0xeff8e3c5, 0x9061f343, 0x7108ddc7, 0x3b740346, 0x32f042e1, 0xcb22b956,
- 0x08af6ca9, 0x4baa5485, 0x82f64523, 0x5213a8b3, 0x2473a665, 0xb38763ce,
- 0xd2a2fd56, 0x0b6011df, 0x3cfd3dd9, 0x0c79d61d, 0x0d4a4bc1, 0x555ca177,
- 0x93695210, 0x1548601b, 0x39f32ff1, 0x4ddd6016, 0x01b8b77f, 0xfacd9fed,
- 0xebf8f208, 0xa66a3ce9, 0xaf2d0cf3, 0xeb1615e0, 0x29129f24, 0xf39d7db2,
- 0x2b11cfdd, 0x6f375e02, 0x03e2fc7d, 0xfbbf8995, 0x9eafc378, 0x2a3d3fa6,
- 0xd3f70186, 0x665c4ddf, 0x9fb11add, 0x788f86ff, 0xe17dfd3f, 0x5215dfba,
- 0x7ce8f23c, 0x8781f04e, 0xf60638f8, 0xb23f74e8, 0x7142b8d1, 0x128b8fdc,
- 0x5c103bbc, 0x2f21b1e5, 0xf2e518ee, 0x43cca5aa, 0xab8d675e, 0xcf7a4ae3,
- 0xe14e4d43, 0x91e4c1ba, 0x6aab7f25, 0x2af891fc, 0x8944a251, 0x944a2512,
- 0x44a25128, 0x4a251289, 0xa2512894, 0x25128944, 0x5128944a, 0x128944a2,
- 0x28944a25, 0x8944a251, 0x944a2512, 0x44a25128, 0x4a251289, 0xa2512894,
- 0x25128944, 0x5128944a, 0x128944a2, 0x28944a25, 0x8944a251, 0x944a2512,
- 0x44a25128, 0x4a251289, 0xa2512894, 0x25128944, 0x5128944a, 0x128944a2,
- 0x28944a25, 0xffe12251, 0x72255300, 0x008000ab, 0x00000000, 0x00088b1f,
- 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
- 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
- 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
- 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
- 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
- 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
- 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
- 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
- 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
- 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
- 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
- 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0x00001000, 0x00002080, 0x00003100,
- 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400,
- 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700,
- 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00,
- 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00,
- 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001,
- 0x000e0004, 0xcccccccd, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc,
- 0x00100000, 0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
+ 0x00007ff8, 0x00000000, 0x00003500, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x00100000, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x00100000, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
+ 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
+ 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
+ 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
+ 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
+ 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
+ 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
+ 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
+ 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
+ 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
+ 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
+ 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
+ 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
+ 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
+ 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
+ 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
+ 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
+ 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
+ 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
+ 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
+ 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000,
+ 0x00070100, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280,
+ 0x00010370, 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0,
+ 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170,
+ 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000,
+ 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298,
+ 0x00080380, 0x00028000, 0x000b8028, 0x000200e0, 0x00010100, 0x00008110,
+ 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
+ 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc,
+ 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
+};
+
+static const u32 init_data_e1h[] = {
+ 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
+ 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
+ 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
+ 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
+ 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
+ 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
+ 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
+ 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
+ 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
+ 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
+ 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
+ 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
+ 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
+ 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
+ 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
+ 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
+ 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
+ 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
+ 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
+ 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
+ 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
+ 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
+ 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
+ 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
+ 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
+ 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
+ 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
+ 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
+ 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
+ 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
+ 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
+ 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
+ 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
+ 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
+ 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
+ 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
+ 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
+ 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
+ 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
+ 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
+ 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
+ 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
+ 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
+ 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
+ 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
+ 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
+ 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
+ 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
+ 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
+ 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
+ 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
+ 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
+ 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
+ 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
+ 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
+ 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
+ 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
+ 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
+ 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
+ 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
+ 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
+ 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
+ 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
+ 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
+ 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
+ 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
+ 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
+ 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
+ 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
+ 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
+ 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
+ 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
+ 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
+ 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
+ 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
+ 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
+ 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
+ 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
+ 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
+ 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
+ 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
+ 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
+ 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
+ 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
+ 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
+ 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
+ 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
+ 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
+ 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
+ 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
+ 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
+ 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
+ 0x00000000, 0x00003500, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
+ 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
+ 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
+ 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
+ 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
+ 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
+ 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
+ 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
+ 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
+ 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
+ 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
+ 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
+ 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
+ 0x00000028, 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x00088b1f, 0x00000000, 0x1113ff00, 0x51f86066,
- 0x423ec08f, 0xac9d0c0c, 0xc4b462a8, 0x1818990b, 0x12b102fe, 0x3c430333,
- 0x203aded0, 0x2388107d, 0x16181858, 0x2fd610b0, 0x022bd404, 0x2c4062c4,
- 0x19b7c401, 0x9cdfb348, 0x1f0f680b, 0xc8037f82, 0x3f4024be, 0x1c360fff,
- 0xfb5f40ad, 0x1819d502, 0x8aa06bfe, 0xf2a26831, 0x9bf13519, 0xcf2684c1,
- 0x2167c68c, 0x63247fa0, 0x0d75b600, 0x000400f1, 0x00000000, 0x00088b1f,
- 0x00000000, 0x7dd5ff00, 0xd554780b, 0x673ef0b5, 0xf3399cce, 0x00fde4cc,
- 0x108f0992, 0x2104e034, 0x0432b445, 0x3b69488c, 0xc514543c, 0xf791e109,
- 0xb14a3e44, 0x44033bd2, 0x350af808, 0x0380a050, 0xed168d02, 0x06823ca0,
- 0xfda2901c, 0x5a1bdedb, 0xcb6ab7bd, 0x880b851f, 0x52d11921, 0xf77ac5ea,
- 0xcc9f7b5a, 0xd0049339, 0x9fdffed6, 0xcfb3767e, 0xd6bdaf7e, 0xf7b5ebda,
- 0xa441c448, 0x84be421c, 0xfc8471bf, 0xa484205e, 0x83bf52c6, 0xa908a3a6,
- 0x2d0867d9, 0xc26425cf, 0x5c64633e, 0x136fcd0a, 0x179a2642, 0xbcb19b0f,
- 0xfbcb3373, 0xdd4f6d0d, 0x01c9cb4a, 0x1349d903, 0x49116f92, 0x1467211a,
- 0xd146fec2, 0xf321117c, 0xb35b2ccd, 0x426cc8ed, 0x98b797eb, 0x3fb69988,
- 0x81e0d7b3, 0x429dc2fc, 0xd439d088, 0x67255c1c, 0x8417fed1, 0x45d9b084,
- 0x47e93bf3, 0xd7b15e5a, 0x5dfa8210, 0xaf34b68e, 0x01f3908d, 0x9864b885,
- 0xed693bdf, 0x86548405, 0xd16494f6, 0x05bb957a, 0xa9c748b7, 0xc6442cdc,
- 0x42ef828d, 0xa8bb40c8, 0x5712b66a, 0x97c39b3e, 0x75c5c704, 0xc742dc2c,
- 0xa912fda5, 0x61daf651, 0xcbb2b5bc, 0xf9cf831e, 0x51c71380, 0xd3cf35f3,
- 0xdabb6871, 0x2c370497, 0xbe2456b1, 0xf3bf1d30, 0x73e679a0, 0x32df5836,
- 0x5daecf39, 0x587ee947, 0x9b686547, 0x7983625c, 0x17e7936d, 0x6aabfac4,
- 0x6bcfd64e, 0x9f74a0c3, 0x3d3e3ca6, 0x95c4201f, 0x1257cb17, 0x60db09e2,
- 0xea7921fe, 0x63f7d8f0, 0xb3f71124, 0x5c40d9aa, 0x427fac4a, 0x40ddf882,
- 0x2b8011dc, 0xb5bbb569, 0xa9d176fb, 0x8985b7df, 0xf31f6dbc, 0xc3ef9a79,
- 0x27a70e5a, 0x4d347e61, 0x499738f0, 0x1309fd74, 0x4ab85389, 0x3246b5fb,
- 0x7acbdc33, 0x186405ef, 0x888f884d, 0xe25adf38, 0x2ed21fbb, 0x4e9caeb1,
- 0x3245fe9e, 0xabbd74bc, 0xfbfed604, 0x57f585c4, 0xb03d900d, 0x2aef6baf,
- 0xcb90ce7a, 0xf90292d7, 0xd0d6bbf9, 0x7926932e, 0x0257c008, 0x614015b8,
- 0xcb40d07b, 0x4713bbed, 0xe16971ae, 0xc61f3c57, 0x75128c73, 0xcdbce3fb,
- 0x4d27cba2, 0xaf838a4c, 0x46e679cd, 0x34f3a79e, 0xd211d189, 0x67c64220,
- 0x8b6f882b, 0x9ba465b3, 0x79b3b7c5, 0x85b6ce2d, 0x38ff3482, 0xe685b834,
- 0xce4ddf65, 0x4741e05e, 0xa4064916, 0xe98c913e, 0x7000de59, 0x9c5078a4,
- 0x03ef2573, 0x68c5fa9a, 0x1f4d225e, 0x0107c616, 0x8e012b2e, 0x481ab534,
- 0x6adbac1d, 0x86a70822, 0x05cf4521, 0x9d5a7035, 0x1b94e14b, 0xb1b577eb,
- 0x09b8832e, 0x23bc1359, 0xf8526528, 0x1dcdd2e6, 0x23bdf30b, 0xdb4c1c12,
- 0x00ce2ee7, 0xa5322a78, 0x32f8ed03, 0xc700bf1d, 0xae38046f, 0x3f18fbe7,
- 0x463792be, 0x6079be37, 0xb37c6eb9, 0x38a7c74c, 0x5df829b9, 0x63853e3e,
- 0x233f2116, 0x95f1c5df, 0xfc704b81, 0xeb949906, 0x8f74b7c6, 0x7771821f,
- 0x437e31f5, 0xfafd58de, 0xd7ea5607, 0xbff5b32f, 0x8f9bbc10, 0xfff5c16f,
- 0xd6cddc82, 0x6c47f03f, 0xafda26fd, 0x37477c76, 0xf700c3fc, 0x5fc07dfd,
- 0x7e9b7a19, 0xf5aa83fd, 0xf1b137eb, 0xc83e0d5f, 0xf8e1b7c7, 0xd90791af,
- 0xc52d07fa, 0x3aa64df1, 0x991693b7, 0x21752c72, 0xfd176bc0, 0x074d3a5f,
- 0x45be71d3, 0x422482d3, 0x901ffb68, 0xc5870881, 0xa850df16, 0xf142c97f,
- 0x0be316cd, 0x0052b424, 0x38e5afba, 0xa977773d, 0x326d24fc, 0x4bf185b7,
- 0x10e9f942, 0x96cebf3a, 0x4fbd2f4f, 0x47773be7, 0x42e0dba1, 0x6ed0247a,
- 0xdf8a5f1e, 0x8841e0c0, 0x1daa7b37, 0x7b3793f8, 0xf22c70da, 0x40599f00,
- 0xf03d8e70, 0xf1a35e78, 0xbe86bb4c, 0xe7d06c16, 0xbcfa422b, 0x80f1ef3a,
- 0x160d3424, 0x3a3afc93, 0x8fca19ee, 0x1f93e508, 0xe9047e52, 0x08792359,
- 0x94d38dce, 0x4b59115f, 0x5f70cb57, 0xfe0c48ce, 0x91583667, 0x7dad2f1e,
- 0x60832658, 0x640a563e, 0xf24178cd, 0xff9d3e76, 0x089d7c3d, 0x57e022e7,
- 0xb4f73d6c, 0x47a14cd6, 0xb2779d2c, 0x31a75dae, 0xf5be0462, 0x963d0920,
- 0x7b2ffb41, 0x87d18f62, 0x4fd3c7fc, 0xfd26ba44, 0xf7d74a44, 0xd87e34ce,
- 0x733769ae, 0x3f635aef, 0xd3e7de9a, 0xae559f7f, 0x431a77cf, 0xe5ce1146,
- 0xa36c810a, 0xa7583ffd, 0xf9c7572f, 0x7db1248c, 0x43dde3e6, 0x049992d7,
- 0xfe91fa59, 0xeb64e7db, 0x497ae7a0, 0xca1f383f, 0x9a4ef704, 0x8dea107f,
- 0x4b7c7d84, 0xe7b3ef86, 0x90d7ba25, 0x5225f39e, 0x9273f606, 0x25271b9f,
- 0x08b753e3, 0x7edfe73d, 0x4711ead8, 0xfc475cf4, 0x4e221fbc, 0x968787dc,
- 0x0697bfe8, 0xf0c7d7e3, 0x3e32dfc0, 0x7be6b4f9, 0xe4aef84d, 0xa97c1ad3,
- 0xcbaa9e6a, 0xd3ee8457, 0xa1b05fd5, 0xaf3e5754, 0x5e5742b1, 0x2eb0f0d6,
- 0x447c1a5f, 0x25a1ff57, 0x0fe574cb, 0x95d6add6, 0xab5f2acf, 0xdbe7dfcb,
- 0xef7faba8, 0x72ba6dcc, 0x0e4570e1, 0xd97e37c8, 0xe1499397, 0x135de17e,
- 0xf0c42ed9, 0x73f3c558, 0xcf4c0c81, 0x2e985c07, 0xf4a57a03, 0xa9641e2f,
- 0x0e697b7f, 0xf78ab9d0, 0xd9758d67, 0xf8f12740, 0xf18f4f1d, 0x03780c78,
- 0xe75f50e7, 0xbc40b579, 0x025df740, 0xefd48f3b, 0x97fce67f, 0x6f48e590,
- 0xc7a332d5, 0x8b3397ea, 0xe5aa5e81, 0xad9d5e48, 0x58497eef, 0xb21075c0,
- 0x08a9fb1d, 0xedd0aa51, 0x3cdd20eb, 0x70188e3b, 0x3e105afc, 0xdef3816e,
- 0xf8c02a5b, 0xa7b23791, 0x78f9870f, 0x25be60e6, 0x4762f915, 0x69f25260,
- 0xc5e7e009, 0x26605cf4, 0x3e0267a6, 0xca074f4c, 0x5030fd31, 0x607b6987,
- 0x0327a609, 0x14ff4c41, 0xbdf4c068, 0x7fa62340, 0xf4c06c0c, 0x4c21033f,
- 0x4c1e033b, 0x14d4f1bb, 0x90f903cd, 0x20226fbc, 0x2e1492e2, 0x3372a97f,
- 0x5c85f961, 0x2e0bee6e, 0x27defbf1, 0xbc5048fc, 0x2c59beda, 0xa8e83f6c,
- 0xf3a50893, 0xbbf6c335, 0x44bcb0e7, 0xdd843f90, 0xbbb2f95a, 0xf483d85f,
- 0x9fc7ef6b, 0xf381dce1, 0x9e030def, 0x8af2247f, 0x0b5dba7b, 0xc047ba0f,
- 0x86b75e6f, 0xd5fe5276, 0x7c31705f, 0x2e5c06b9, 0x039cf5be, 0x0cc2e8f8,
- 0xe6fa79d1, 0x1357d7be, 0x34da75ce, 0xe8b7f1f3, 0x851b17f3, 0x741e4c49,
- 0x0e18cc25, 0x9e74e0f8, 0x96fb0c1e, 0xcfdaa981, 0x79d90cc2, 0x85ea193a,
- 0x77643d70, 0xd517e222, 0x3fdeb047, 0xf57d1e7b, 0x5ec79b13, 0x47b68a72,
- 0xdf507b19, 0x0bc4fbf5, 0xe41933e9, 0xbc6ad268, 0x85aae704, 0x40e5f7fe,
- 0xbcc257e8, 0x6c3fafda, 0x826e9a08, 0xe375bbef, 0x552e76d1, 0x7d7683d7,
- 0xce449fe3, 0x5941f8a8, 0x6fae09d2, 0x9d9b3556, 0xa89d7e7a, 0x325bfbcb,
- 0x0dfe3a9d, 0x4af4a0ff, 0x9c120a26, 0x2b1cd5bb, 0x835b24ba, 0x1bb7e740,
- 0x8bee86f0, 0x6af5605f, 0x47d97694, 0x67dc2d3f, 0xe17df3c7, 0x05efae5a,
- 0x9fb41b49, 0x70778633, 0xd34ace85, 0x449ce51f, 0x9e32f9a4, 0x39aef553,
- 0x7cf0ab7b, 0x94126fff, 0xc8ff3ce1, 0xe70458d0, 0x9b786553, 0x76fba1ec,
- 0x80938881, 0xbf205cef, 0x91acdc77, 0x3208afe3, 0x41acb7ae, 0x79516e7f,
- 0xf2a79747, 0x9f3f2e8e, 0x3d034b4c, 0x91937e6a, 0xff285e8a, 0x043bcae8,
- 0x80bbf627, 0xfe04add4, 0xcdef6a7e, 0x700adcf7, 0xc8a5b03c, 0x6873f347,
- 0xbf4a3f71, 0x6427cd95, 0x3aaf93a0, 0x1fb4057e, 0x755c73d9, 0x51f43d5d,
- 0x669a870e, 0x85ea13c1, 0xa6459b9f, 0x9f74a9d7, 0x72753a25, 0x7e5c5e5b,
- 0xf6fe5c64, 0xc6d7fcb8, 0x908a149f, 0xdefdb169, 0x44f2f82d, 0x478043e0,
- 0xf9bc3109, 0xf467fdda, 0x3fe47fe8, 0x44feffb5, 0xffb4ff87, 0xfda9ffdb,
- 0xff31ee0f, 0x5ff5bdc9, 0x149e8a6b, 0xdd7b1ce0, 0xe198e78c, 0x7a0839b0,
- 0x19ab7f82, 0xf637dcf5, 0xd01775fd, 0x26b3e75d, 0x8e7a6262, 0x93bff280,
- 0xdf767bf5, 0x0ffeb75f, 0x8d0b3f2d, 0xb60b7f69, 0xef80fad2, 0x64c8adbb,
- 0x184e5eba, 0x2f5d2841, 0xefd1fd78, 0x2e2f2a11, 0x91dee2b0, 0x0f4cbf05,
- 0x51fb00ad, 0x799fcb2a, 0x08284071, 0xed979e76, 0x1808c311, 0xa3ed40f7,
- 0xad2fee30, 0xa42d1e84, 0xd61375f3, 0xa305fceb, 0x2ee78a7f, 0x24415e9d,
- 0xe77e3757, 0xb5241c02, 0xe052f85c, 0xf0e22840, 0xd55ef4a1, 0x8f31e092,
- 0xfbeaf800, 0x2e8c60b9, 0x0eff2376, 0x5bc88966, 0x77205922, 0xcb53d7c7,
- 0x5540e2fd, 0xb6ec581e, 0xfd53eac5, 0x37cb3e79, 0xa0fd3166, 0x052feb0d,
- 0x958d49fa, 0xd597ecf7, 0xcec891ff, 0xac3f58db, 0x53d72d7d, 0x1572e9e3,
- 0xe6aacba7, 0xa6f6862f, 0x7f32f55f, 0xa65fbefc, 0xafdd0582, 0x10e6cbe0,
- 0x23b5616c, 0x6bef7a82, 0x6d511edc, 0x9e1ea089, 0x3905c7c5, 0x6944f20f,
- 0x8ced097f, 0xf404cc07, 0xedd79add, 0x9adfd81e, 0xf33d7ffd, 0x63bdfa33,
- 0xf80dd59f, 0x0ffaf350, 0x4c6bdf71, 0xdd02d991, 0x2a1ee8bf, 0x1dfad2ff,
- 0x4d9d7e7b, 0xc61d3f68, 0x55d27648, 0x613565ec, 0xcafc9c53, 0xe03e7de6,
- 0x98f2019e, 0x3b5447ca, 0x53fb7c5a, 0x45cff162, 0x4417970a, 0x7c88b34f,
- 0xa9df6f4b, 0x5d39525c, 0xfdabde7b, 0xbecc4a54, 0xc43f7ea4, 0x1ba87be1,
- 0x2e935fce, 0xf2e83d6d, 0x02ebcc10, 0xf3834b69, 0x13f9b6a8, 0x4aed4419,
- 0x2e813590, 0xbee032df, 0xa12b9b10, 0x4d4df937, 0x4cc605cf, 0x75de5097,
- 0xfedfea63, 0xc28b2381, 0x4f86fe7f, 0xe91ce1b2, 0x199e643a, 0x7f39fd42,
- 0xbf1834ba, 0xa0f5dca3, 0x51eb8ac1, 0xe3a4abc7, 0xf5b10bd5, 0x755c6b5f,
- 0xaefc753c, 0xcfac9f8d, 0x69f8e174, 0xb8fc7e30, 0x5c753b6a, 0xde7c572a,
- 0xd886978d, 0x414b96fe, 0x72c3ce19, 0x947ee122, 0x14797a93, 0xcd8841d2,
- 0x74ed4977, 0x97ca9f90, 0x4a5d3edc, 0xf900f366, 0x6901e60d, 0x5ef1c6d7,
- 0xfb7fa380, 0x3a520554, 0x305f5c0f, 0x221a16d3, 0x3ca0f9b0, 0x7d414c1f,
- 0x777be257, 0xe9fdf026, 0x17b87f4c, 0xb81d39fb, 0xf1c6f313, 0x1437c875,
- 0x85a988d2, 0x1ffd3184, 0x8f9c46f1, 0x90238a8d, 0x98f81aa7, 0x0e11c359,
- 0xb6245979, 0xe913f87e, 0xcdbf2b38, 0x572ddad7, 0x30e1c53d, 0x580679c5,
- 0xbe47d066, 0x08ae5da4, 0xa3f364cc, 0xbe5128f8, 0x517f84e5, 0xc79d3a78,
- 0x103826ff, 0x4a7ad9ef, 0x5d056848, 0x7c73248f, 0xbe184c99, 0x5e265c34,
- 0xdd3c1d8d, 0x090ef8c0, 0xe83e411e, 0x5fc1fde0, 0x9451e694, 0x245655a7,
- 0x7802df64, 0x089270e1, 0x91b7638c, 0xd8047588, 0x5af3a551, 0x1b79c1f9,
- 0xa8ecebcd, 0x3a78f2fa, 0xb14bed53, 0x7e70db71, 0xe2cfdfb4, 0xae2cfdfa,
- 0xd6aecfdf, 0xbf270aaf, 0x740bddb2, 0x87c058fc, 0xa78ea6fb, 0x7c28f1f0,
- 0x113f51f2, 0x429dee2d, 0xd616ae0c, 0x22633d15, 0xc0337fb8, 0xf4e14ce8,
- 0xe8e1c278, 0xb29050a3, 0xd7fe0081, 0xfd353b73, 0xed34daf3, 0x7a415388,
- 0x99c7cd5e, 0xa1fc6061, 0x9ecff39e, 0xee78cdf5, 0xee6fa8f7, 0xf7a5beab,
- 0xe6bef6fa, 0x3e75ed63, 0xd55f955f, 0xff5ffebe, 0xf869711e, 0x52829396,
- 0x30ccaf2f, 0x126b7ed0, 0x1dbdfccf, 0x0f5144bf, 0xf7ebfa51, 0x4af802cb,
- 0x5832c7f1, 0xa056ddff, 0xf05ee7df, 0xd74996c5, 0x63af9331, 0x14e97366,
- 0x86264738, 0x526496a6, 0x5abfbf3c, 0x17709b70, 0xbce8ffe9, 0xbaf3e3ee,
- 0x3a4051bf, 0x21917fb8, 0x6ec5eae4, 0x41fe0b35, 0x09d567cb, 0xd3d088a1,
- 0x1b4b057e, 0x3e760696, 0x3b4f6e36, 0xeaf1045c, 0x6cde3e21, 0x0c1a4a42,
- 0x845bed3d, 0xef2957e3, 0x35dede27, 0x2ed1b887, 0xffcf2f16, 0xe463e419,
- 0x91b921c7, 0x46c1afee, 0x31e416f1, 0xfe8dc583, 0x3037fe90, 0xdc2159fd,
- 0x2e5047ce, 0xa4040722, 0x573e8bfb, 0xec55d242, 0x33025b30, 0x62f0ced1,
- 0xd9a60360, 0xce043c8b, 0x412f6961, 0xa05b7f79, 0xdf0fbf1c, 0xd1942edb,
- 0x176ce4bc, 0x6774d3e6, 0x1f7e0960, 0x3fafaf58, 0x644baf7c, 0xd4225cf5,
- 0xc3e0367b, 0xea05cf7a, 0x7cf5bed0, 0x3ff301a0, 0xcd31040f, 0x95f3626b,
- 0x2fe82a96, 0x11a045fc, 0x18fed1eb, 0x41427aff, 0x2f7c3cfe, 0x79b797ab,
- 0x2dd6084c, 0x777e7939, 0x197fe639, 0x377f6108, 0xb5fde0ec, 0xb30b9412,
- 0xb3afdd17, 0xce96b863, 0x030fc9d1, 0xe5752beb, 0x3f063aea, 0x6f5750b1,
- 0x5890def8, 0xfdf30056, 0xe4bbee91, 0xffe0890c, 0x5cbcdfcb, 0x3b0dcfd7,
- 0x15eae8d6, 0xae89feec, 0x4ddec47c, 0x75bbbcba, 0xeeaf2ebb, 0xca65f54f,
- 0x5679e9d8, 0x4205f975, 0x2fdb3f28, 0xf4375e79, 0x075cb722, 0x76bca05e,
- 0x69f87c2d, 0x5c7083c0, 0x4840f545, 0xb3fcb833, 0x3493ec1a, 0x27d838ff,
- 0xecc82fd1, 0x3b734f54, 0x3e40dad5, 0xe0267f7e, 0xc0bafcc6, 0x0c6fcc18,
- 0xcffcc24c, 0xdfcc5e02, 0x09bf3123, 0xf00da9e0, 0xda3359f4, 0xe9671087,
- 0x525b5d7f, 0x923f2043, 0x32f1c68c, 0xa2e637e4, 0x3f709a5d, 0xb3a70543,
- 0x955687b3, 0x7122a6ac, 0x288beb55, 0x9939511f, 0x4e9adc80, 0xefd6bd79,
- 0x037f2d77, 0xfef58395, 0x0721b987, 0x258aadf0, 0x0a29c993, 0xcfcda3ef,
- 0xfae9da39, 0x432c762b, 0x3abcbb7d, 0x6d20bb28, 0xd3fd067e, 0x0dc4d5e5,
- 0xb6e547c7, 0x4b9eff6d, 0x99f55dc7, 0x0f80da40, 0x0107214b, 0x91b376bf,
- 0xde58ae72, 0x009cfcdc, 0xd93b34f3, 0xee9d98be, 0x0a79e208, 0xc5710f71,
- 0x519cdaf0, 0x7f6e7e87, 0xe825f47a, 0x3c87dcdf, 0x2ee92bfb, 0xe50d1a41,
- 0x8a30c46d, 0xf7d80cd1, 0x78582f1f, 0xe791ec04, 0x80b7201f, 0x6bf1e73f,
- 0xe74ecbcc, 0x4eeded05, 0x93bb0b06, 0xf36393fb, 0x1d96ff42, 0x9b1b95e6,
- 0xe5e89d97, 0x52bccd62, 0x772854a4, 0x4ece780a, 0xf04f1824, 0x79fa6df4,
- 0xb2f30d3d, 0x44af3df5, 0xebc02f3a, 0xc4af0e44, 0xfd42f09e, 0x5e0e3134,
- 0x6bc37d89, 0x912bcc28, 0xf4230578, 0xebc18333, 0x79fa2999, 0x780d733d,
- 0x4179d2a5, 0xaf0e54fb, 0xc2f09ed4, 0xbc1c6a7c, 0xd786fb52, 0xd2979858,
- 0x0df1d45f, 0x8e8b60cb, 0xefc0d82f, 0xfb5729a7, 0xd2ca8c73, 0xfddf4f7d,
- 0x005150b0, 0xdd40d3f2, 0x3789a4f7, 0x5329f2e8, 0x4ffaea46, 0x9756319b,
- 0x58a078cf, 0x3b9acf97, 0x7fbed759, 0x795d34f5, 0x191103fa, 0xcb9a8bf4,
- 0xd6f9e3db, 0x7c2f523d, 0x0728cbab, 0x35d7cec1, 0x4163c99c, 0xbd63ca81,
- 0x3e8baff0, 0x5b17db86, 0xff436f87, 0x39789fea, 0x1fb40bc7, 0xe0f03d83,
- 0x55f7f450, 0x13ddfa73, 0xf3be4668, 0x7c8c204a, 0x6fb71f68, 0x8738801d,
- 0x0381823c, 0xd378df68, 0x82788215, 0x19e6dfea, 0xfceb3ce0, 0xfc13329d,
- 0x8be69dae, 0xefc8230e, 0x3771d452, 0xa94107cd, 0x8905b881, 0x1f6dea4c,
- 0xb7f38dff, 0x9ecf07e5, 0x1d2f7e84, 0xb44cbb34, 0x56af09df, 0xf9a7643c,
- 0xdd98f7da, 0xfbfe2fa4, 0x63f7c92b, 0x97e62706, 0x93f97da9, 0x5f8e8411,
- 0x00d13bb8, 0x180aa7fc, 0x07f82a44, 0x1f41b3db, 0x05ec791a, 0xfd47fc1d,
- 0xfedd65f6, 0x230b1e14, 0x43f752df, 0x7ee84f3d, 0x8538c034, 0x56e3e07d,
- 0xe225db89, 0x067f74f9, 0xa7c0b3af, 0xbfe59569, 0x9697eca3, 0xda6cdfcf,
- 0xbf9ceb0e, 0xe071d961, 0x1cb767cb, 0x0bbefe38, 0xdbe3a1a7, 0xb9435f54,
- 0xe7f36bf0, 0x53dcf07f, 0xbd7e22f1, 0x119b9755, 0x70f9dd2e, 0xbdcef6ef,
- 0x7b53d312, 0x57b7d3c2, 0x18587f42, 0x2eaa8ee3, 0x7bdf84bf, 0xd42eb1ca,
- 0xd539172f, 0xfdc9b5f9, 0x601d0f80, 0x8545d97e, 0x2fc812e1, 0xbdd1317a,
- 0xf95faa02, 0x46834bf2, 0xda345ece, 0x2af0be93, 0xddea91f6, 0xc5ea1226,
- 0x4625d23e, 0x48d2996b, 0x578a50e5, 0x2768965d, 0xf5477fe4, 0x986349fa,
- 0x12e20abd, 0x62daa59a, 0xbf36ac69, 0xfaca58b0, 0x4d42faea, 0xdfc7c7eb,
- 0x817d3127, 0x427f07ea, 0xf5e814f8, 0xe84f5506, 0xae703d6b, 0x0cec3ea3,
- 0xbbaf5af7, 0x728d75dc, 0xd2e51ae5, 0x45ffca35, 0xcf29f7e3, 0x55ea66bf,
- 0xe058bf9e, 0xd03e074a, 0x76098f45, 0xe064468e, 0x2d0d555f, 0x1adf3f0c,
- 0x8ff9009d, 0x7d5abeb9, 0x72f8c439, 0x5cd79588, 0x788108a6, 0xd426e2ca,
- 0x49163f7e, 0xe17c6f79, 0x1fd32356, 0x20ff5a6b, 0x73cf80bb, 0x7ce1a93a,
- 0x4532e6a4, 0x695f4a28, 0x1bd61346, 0xfe233466, 0xef491915, 0xad8d9f72,
- 0x8027e54f, 0xce4fc093, 0x3cc5cc6e, 0xf5f227e5, 0x8e1a93f0, 0x9f955f67,
- 0x02f30adc, 0xf3da54bc, 0xf7905e30, 0xdaeebf13, 0xa9c20746, 0xfe80ce9b,
- 0xed7e066f, 0x02a63429, 0xf71809dd, 0x4262dd58, 0xa356e439, 0x5eebed8b,
- 0xbeac4fe6, 0x03f18bbc, 0x17d38d89, 0x538fc7be, 0xe3a2d8d5, 0x16f83d4b,
- 0xff8c578f, 0xf1919f7e, 0xe2848bef, 0xfc4f4147, 0xafa2f150, 0x5b2e6b7e,
- 0xdee8f374, 0x767deeef, 0xc6c73ee0, 0x953c7053, 0xa470aa1f, 0x38dbb9f0,
- 0x627c27ba, 0x38412970, 0x48fb7276, 0xc98d5f3c, 0xc55edc0f, 0x81e3d9f9,
- 0xb5adde3f, 0x38fb5af7, 0x387156c7, 0xd1040eac, 0xf51d242e, 0x5aaec138,
- 0x6f07766f, 0x49f0c437, 0xa164d8e6, 0x9d035e62, 0x849525a7, 0x16a6d196,
- 0xe7f02b98, 0x2af8825c, 0xfe1d24d9, 0xaf3429c8, 0x288db7e3, 0x13069b27,
- 0xe957f001, 0x615f2faf, 0x6b3af164, 0x4b3bb7f2, 0x927fbce9, 0xb820fbff,
- 0x6d601dd2, 0xebfda033, 0x63bfaea2, 0xca64dcd2, 0xfcf8132f, 0x72d1b79c,
- 0xc1e6f8cd, 0xade4014e, 0x76fa89a4, 0x0cb070f1, 0x8abfeba6, 0x1c524cdd,
- 0x20a197e8, 0xc2317662, 0x612230e5, 0x272ae8dc, 0xadcb47e3, 0x95d7a40e,
- 0x63ee2239, 0xadb7b713, 0xc81b3b07, 0xfc848a52, 0xeac894cb, 0xb44109cb,
- 0x4ec199a3, 0x8a7d806b, 0xda4ede60, 0xeb009f31, 0xb8f2041e, 0x4c9fd70b,
- 0x6f412b22, 0xbedf1aef, 0x164fbe18, 0xfe02cf7d, 0x3b6cca5c, 0xd53d8029,
- 0xf40a1beb, 0x2c10c1be, 0xcffad174, 0x5085a21a, 0xfd169b2f, 0x39a58931,
- 0xd3e4d710, 0xff987ff8, 0xf437963b, 0x912ce7cc, 0x5721fce2, 0x5fcb6a86,
- 0x012f3d10, 0x129ca79d, 0xba909e50, 0x09bd4de3, 0x2bf70f10, 0xb1878f23,
- 0x2fe93d31, 0x8f4cb9ad, 0xeac721ed, 0xf70537f9, 0x79ba63f4, 0x63f2e3b9,
- 0xd8d31fa6, 0x2797fdc3, 0x0ec1f8ea, 0x1d8d03a0, 0x11e4b07d, 0xa4355fc1,
- 0xcabf7e91, 0x6dd6bf7e, 0x601a0cbf, 0xf8f1f77e, 0xb3d5220b, 0x22f78f3c,
- 0xff744bb0, 0x6cd455df, 0x593bcb3d, 0xf9873fce, 0xc0f9baf3, 0xec045361,
- 0xce1eef7b, 0xdcfb062c, 0x51e8c66b, 0x3ff5c82b, 0xfdcdf260, 0x5a331cef,
- 0xedefba69, 0x4b9076ed, 0x9cfa724f, 0xd846a24d, 0x0f8f1f47, 0xaafaed53,
- 0x55ca8c5d, 0x0f9be046, 0x7f774244, 0x3c1ee697, 0x1c2efa16, 0x8adfb397,
- 0x9ad80afe, 0xb12cec2f, 0x16bb4d12, 0x679671f7, 0x45eb34ed, 0x57ad8e7c,
- 0xd668f5c1, 0x5b15fb8b, 0x50f082af, 0xfc19fbd7, 0x787ce69f, 0x14fbe8db,
- 0xdd7e33f0, 0x5b344ad5, 0xfbf8881a, 0x5a9bc057, 0x8d272f83, 0x00c2e3ae,
- 0x5854d0df, 0xf2325b4f, 0x6ff8bebf, 0xf466fc77, 0xcdb71606, 0xf386a7f1,
- 0x86fb15fb, 0xe11d8026, 0x220daffc, 0x21e7ddc8, 0xbf7e921e, 0x81343cd8,
- 0x73bec55c, 0x2e75db8e, 0xe8095d3a, 0x911d094f, 0xbec00b4b, 0x539e4471,
- 0x9a9eb3d0, 0x91ed0f2f, 0xb20ed14b, 0xa2388647, 0x1af71e1a, 0x993f7fdf,
- 0x6379c1d1, 0x20e804b8, 0x04e0a2fa, 0xeed55eff, 0x5ed1c73d, 0x247123b2,
- 0x710d2f8b, 0x08db473f, 0x908a9fd8, 0x146f1f41, 0x91057266, 0xb0cc46da,
- 0x8f52e16b, 0x63fd34ed, 0xed57dcfc, 0x31496cbf, 0xbb720539, 0xfa0f1cec,
- 0xc32b7043, 0x1e89b2cf, 0x33f69d83, 0x7f4041b6, 0xdba72de5, 0xaca98e31,
- 0xbf409129, 0x472c8f65, 0x9b6d533f, 0xf81da5ab, 0x0f704864, 0x794fe021,
- 0x14c7f0b8, 0xb28eeb1e, 0xc3fc807d, 0xb8f32fe8, 0x6fbb1a6c, 0xd0aeb187,
- 0xa0f0f409, 0x5cf203cd, 0xbbcf0ce9, 0x205957e0, 0xfe008e45, 0x7d2ceba8,
- 0x0e0635c0, 0xd9b0d285, 0x2442a983, 0xa56be50b, 0x4d205112, 0x86648997,
- 0xffcfeb7c, 0x6c289cc2, 0xa216e9bd, 0xfebfefb0, 0x8de1e01b, 0x8edeb2cd,
- 0x6fe7d619, 0x0be7d16a, 0xcdfcfa23, 0x4ff3e96f, 0xf74941c0, 0x0c2fb5f7,
- 0x37f088c4, 0x47fe0085, 0x8588990f, 0x97eaabae, 0x2703d466, 0x9cf0d954,
- 0x7305f8f8, 0xde47f208, 0xec08b57b, 0xb4bf954b, 0x6f01b8b3, 0xaf2825f8,
- 0x811fa97a, 0x0dff7273, 0x8cb7b544, 0xff64b900, 0x3ed80ddf, 0x9fed3cfa,
- 0xe0f8ffd6, 0x947a5fcf, 0xf9f8ffb6, 0x1210497e, 0xdf87d594, 0xef59aabb,
- 0x41ba1e1f, 0x2161ff3f, 0x664abe7d, 0x2f0bfafa, 0x187e2ac8, 0xdba5df18,
- 0x17f5c695, 0x907f9697, 0x6e20fd45, 0x8182e400, 0x4455efb1, 0xbf46afd3,
- 0xe1e9c89f, 0x019dc05c, 0xc88a63e7, 0x85cfeae2, 0x7a0348de, 0x1bc768fa,
- 0xe74f4069, 0x4fd04b03, 0x6767bd55, 0xd5e79c12, 0xf0e1bfcf, 0xaedf7a40,
- 0xdc82c6a7, 0x0c21bcf4, 0xd3dfa0f3, 0xf8477be0, 0xf4598e57, 0xc91db9fb,
- 0xd17def88, 0x30a8457b, 0x7c0e7b43, 0x8ee87c55, 0x383272a3, 0x9de3181c,
- 0x0fba5dfe, 0x780d9b55, 0x7c2aa65f, 0x038677f7, 0xa2366c1d, 0x8f7aabdd,
- 0xbe3ea091, 0x7bb456ed, 0x813eed55, 0x8dfec771, 0x5e5718a5, 0x61af1124,
- 0x664cba24, 0x75ae7a40, 0xb7ec039f, 0x926e7f55, 0xefc81725, 0x78a3fdfa,
- 0x548c7180, 0x069a28f2, 0xb2cf494e, 0xa9bff022, 0x57ae7bdf, 0x5f7e3edf,
- 0x78d5915e, 0xddaf9225, 0xc97af8df, 0x37688253, 0x5cb25ea9, 0x7d500f17,
- 0xfe0651ba, 0x4a0e3f1a, 0xfa739a90, 0x017f0835, 0xeb917f3a, 0x51ce5439,
- 0xc3cfa2e8, 0x3cb106bf, 0x80952b9c, 0x1bfeb047, 0x851744c8, 0x3234d547,
- 0x032cd209, 0xe42c7bc1, 0xefefe615, 0x7a0473a0, 0x237dd8e8, 0x84bab7da,
- 0xc33f5df6, 0xb7c8edfe, 0x07119c3a, 0xb6544dc4, 0xe2ee319a, 0xf2320be3,
- 0x37e1658d, 0xdc6f101c, 0x145992f1, 0xf1f5b0a9, 0x8362e49e, 0x37e7f003,
- 0x4e19aecc, 0x571d962e, 0x7b9a2fd1, 0x00f8b78f, 0xafcf49fe, 0x273d94ff,
- 0x7d678064, 0xe98b9e32, 0xbd8575c9, 0xedaafdc5, 0x42bae452, 0xb3d3c817,
- 0x5aefdc6d, 0x72f80b9f, 0x06e197d1, 0x6054a979, 0xf4480efd, 0xed7e849e,
- 0x924bd6cc, 0x076c32de, 0x70653a7c, 0xf852762f, 0x945e25cd, 0xf28ee60b,
- 0xa48740c9, 0x96fdc59e, 0x51222449, 0xf80cb039, 0xa3cc08ea, 0x59b65efc,
- 0xb9a2f8c0, 0xe775184f, 0x69e1c400, 0x1a4e57d7, 0x124adfb1, 0xb37cb4c6,
- 0xf802bcbe, 0xa5578534, 0x95e0fcc2, 0xf0718c3b, 0x5a3ea089, 0x930bfbbd,
- 0xfd751c76, 0xfaea217f, 0xd1e5973c, 0xfd45fd4c, 0xf70129be, 0xd8c8ffd9,
- 0xe65f380c, 0xf8e0f699, 0x985cfc55, 0x7e58ea4f, 0xa00c8922, 0xeba3cfe3,
- 0x9e607382, 0x918e8242, 0x92309f2c, 0xdf93c7ad, 0x0eb03d73, 0x36f277ed,
- 0x56aaafdb, 0xd61c3221, 0xf20de743, 0x5b47ac37, 0xb3af9aaf, 0xaefd377a,
- 0x7690ffb5, 0xf7bb5fac, 0x5fae930b, 0xe7a0cf6e, 0x7dd33110, 0x37cdd758,
- 0x71b4c343, 0xe1bdaa23, 0xbac78724, 0x0267e7bb, 0x720d3dbd, 0xd8071658,
- 0x8127aa18, 0x032c676f, 0xb7c742ac, 0xc79ddcdc, 0x2ce5a2f2, 0x76b4c83f,
- 0x54fe86c2, 0x32fa310f, 0x3329ae41, 0x68438f78, 0x37c54ece, 0x29c744d4,
- 0x12d93d93, 0x1e4f75f2, 0xb09659da, 0x6474fff5, 0x5ebab0dd, 0xbf7518e4,
- 0x08e10bd6, 0x641d43c6, 0xbd7c41f2, 0x4fc62671, 0x1fb68e12, 0xdd173e07,
- 0x5a11e547, 0xc1f0a36f, 0x6de3b071, 0x5645cbbc, 0xdd067cd0, 0x1b77e01f,
- 0x502f5205, 0x4bda8cb8, 0xa3d01be5, 0xd4378ef7, 0x4cdd70d8, 0x6dd6b06e,
- 0xfa47fb03, 0x0123f943, 0xb930ef5f, 0xdd741e70, 0xe5a34d0f, 0xb983cb19,
- 0x384bff60, 0x0ede6a1a, 0x8b70efe7, 0xa74bc61b, 0x6127b1b0, 0x7fe700da,
- 0x023c2906, 0xc5319574, 0x88ec1235, 0xffac1ceb, 0xd0f0d154, 0x46539054,
- 0x28d27cb2, 0xfb8ed9e2, 0x49c716b3, 0x30499137, 0xf20ef83f, 0xb3d6ed17,
- 0xc4349107, 0x5d4275f6, 0x3e9f8c21, 0x7064a588, 0x8bcbca06, 0x9eaa7cb8,
- 0xf7f59f6f, 0xea3f0024, 0x3f01f7e2, 0x201279b3, 0x1b1c8c8e, 0x9fed6a26,
- 0x0345fd6a, 0xdf50e93c, 0xc124597f, 0x287fe464, 0x5e67fa5f, 0xff857b42,
- 0x1a824cb2, 0x9cbfec3e, 0xd777cfa4, 0xb1f6c34b, 0x4a12167a, 0x839eadee,
- 0x11fd7484, 0x7f2d7f7d, 0xec24f5e5, 0x77698c8f, 0xe9d91c80, 0xdb3e476a,
- 0x46831215, 0x1174f7aa, 0x9dc1f182, 0x6d5df64e, 0x265339df, 0xa2679411,
- 0x40474fd8, 0xb2630881, 0xf413f5a9, 0x1eb7561f, 0x35ef8129, 0x7ce30da4,
- 0x1256c26b, 0xdbffc5ec, 0x970b0011, 0x3f29fce6, 0xfdd4ed8a, 0x9037b588,
- 0xb38fd690, 0x52222da2, 0xeab75a5a, 0xc00a2bd7, 0xd3947704, 0x2b37f04d,
- 0x72d1b73c, 0x23a3a883, 0xba6ea8eb, 0x275f3242, 0x061d181a, 0xe262bb7f,
- 0xaf3c9a6d, 0xf83edddf, 0x291309bb, 0x602a8ddd, 0xf55d9fed, 0x972c6fef,
- 0xae807c62, 0xd76bdb3f, 0xbcb895e4, 0x6b87e68d, 0xf2b8cef2, 0x8cf2b894,
- 0x567f7cb8, 0xc91ec3bf, 0x1ca9b836, 0x13f7eab7, 0x3a4fca24, 0xa9b32332,
- 0x309e4f04, 0x226133bc, 0x6a8f8dc4, 0x5a79c0f3, 0x59b82adb, 0x5f830fb8,
- 0xb9e19bad, 0x832eddcd, 0xaa3adf7f, 0x7688b8ed, 0x7209c12a, 0x27bc2da6,
- 0xe7687982, 0x330bb4d2, 0xfc3aa4fd, 0xb3ebb601, 0xe9117cff, 0x87fe4d7c,
- 0x765aef58, 0x8faf9274, 0x6e2bef83, 0x3be0b770, 0x92bd026a, 0x77bf9144,
- 0x992ff9ec, 0x7c633fdd, 0xf3d333ab, 0x43adf206, 0xb7cb5382, 0xa41f30fc,
- 0x0e5c65e7, 0x935c7062, 0xb886517f, 0xb787f78d, 0xa9c703be, 0xcb27d175,
- 0x73fb1e40, 0x20d1d9cd, 0x1f2d809f, 0x217af4f8, 0xd6f18664, 0x7861a18b,
- 0xc866adff, 0x7a05d111, 0xf016fb7c, 0x75574417, 0xda4ffc22, 0x284007db,
- 0x9755c5fb, 0x7db53e59, 0x5dc7ec0b, 0x009b7f0d, 0x0e4f1ef7, 0xd2201f68,
- 0x8355a5fc, 0x487e6227, 0xf7c816fb, 0x3f2c1c53, 0x81807dbc, 0x0921cfb6,
- 0x76ff6113, 0x8abf193a, 0x3967bfe7, 0xf7e755ff, 0x29cf7f4e, 0x66a90b80,
- 0x1c0b7dfc, 0xed9f94cf, 0x73b538ec, 0x9d9fdd17, 0x9fc8cc4b, 0x10bc6429,
- 0xe1ce938f, 0xf20ee78c, 0x8df50953, 0x926b384c, 0xcf68fb62, 0x7f21736e,
- 0x0f6ea1be, 0xb3e9d79c, 0xff3f900b, 0xac99ec87, 0xfdd2c6a4, 0xfad29a36,
- 0xe3271593, 0xed1106a7, 0xda8fe99e, 0xda78fe51, 0x0561d6cc, 0x1b534afe,
- 0x7c2b8fdf, 0x4c4c571d, 0xdf24b91f, 0xdacdfd81, 0x950cf946, 0x240966db,
- 0x309c80a8, 0x81394655, 0x3341a3aa, 0xdc5537cd, 0xddd27180, 0x335ad2fa,
- 0xd0a9bfce, 0x26760993, 0x9a693f55, 0xd44cc9ea, 0xdb4d65c8, 0x67cab958,
- 0x5e69729b, 0x12102e73, 0xad9779c6, 0xbb424dcf, 0xf3eec4bc, 0x743b5fac,
- 0x573c1afb, 0x9b3ae1a7, 0x68664312, 0x2fffc2a7, 0xf0c93dfd, 0xbef57efd,
- 0x7507df28, 0xd30ac9dc, 0xec0cca87, 0xf1527e3c, 0x44cb3ae1, 0x39a208cf,
- 0x4d03279f, 0xa448e068, 0xfdf0d1f6, 0x8c7843ff, 0xa3fdf586, 0xf1daf8f0,
- 0x84fc71c5, 0xa0bb8df2, 0x67259aff, 0xf30cdc79, 0x5df0a9bf, 0xe98c442f,
- 0x77b06f8c, 0xd077e804, 0x3e4c0abb, 0xe753b42f, 0x1ad1fb3d, 0xf5d4d794,
- 0x60787f58, 0x9d99dc12, 0xc5fe795d, 0xecfdb49d, 0xf775591f, 0xa4be5581,
- 0xae46bde2, 0x11eec618, 0x4fbb29ab, 0xe80a7208, 0x3aeaed77, 0xc4264f24,
- 0x18afaf8b, 0x609e8228, 0x828ff805, 0xb7432efb, 0x9c18132f, 0x9caa9e60,
- 0x08bb8843, 0x2953b3d6, 0xf97d86ae, 0xa05e2952, 0xf071b2a4, 0xa75e097c,
- 0x03d78dfd, 0x7aeae779, 0xfc72610d, 0xefa604a6, 0xd0f10249, 0x8dffcdf9,
- 0x811adb71, 0x13e21f03, 0xb0bb30b6, 0xc357972a, 0x79f74ee9, 0xe7e3973e,
- 0xc17e3973, 0x1deea306, 0x3e908a82, 0xbcd89a4f, 0x523eb9aa, 0x9fb0da45,
- 0xbd7d66aa, 0xd82faa6a, 0x83bf701d, 0x8690f1ca, 0xf9eae5f5, 0xc2f96fe1,
- 0xa0f77fa4, 0xa361f711, 0x09f1c999, 0x8fb93d23, 0xb5fc7f01, 0xffcde511,
- 0xc2a2fbe6, 0xf1624061, 0x8b5f00c3, 0x9ff84441, 0xec394916, 0x95c0676f,
- 0x93307831, 0x02f5a76f, 0x9aaf35bf, 0x361f01cb, 0xffcea22b, 0x64628f78,
- 0xcce5c37e, 0x4fbd1e9e, 0xc8133b46, 0xffbd5ac1, 0xe7d54539, 0x10ff72d7,
- 0x129a33d3, 0xa9bedc99, 0xe9077049, 0x2b4d277c, 0x5ff800af, 0xc021699c,
- 0x3d72e76a, 0x746a42f3, 0xfaadc031, 0x76bb4bbe, 0x7c37d011, 0x74be022f,
- 0xc7ecd18a, 0x967fd172, 0x0fb3fe00, 0x7cef8c43, 0xfdc0eb48, 0x9dab6098,
- 0x4f1355c5, 0xefda3ce6, 0x6ee9d5a9, 0xe3533b88, 0x641d4e49, 0x46f5cbfe,
- 0xf3dc096f, 0xfa63ee0d, 0x574687c3, 0xeb23dc36, 0xd011caf2, 0xd744cbbb,
- 0x7b2025d6, 0xaaf6b61d, 0x5a9ff85f, 0xfeae7180, 0x23dfa5ca, 0xfdd3d157,
- 0xbd3d7a2d, 0x61b34493, 0x07ca9b5d, 0xfc742386, 0x6e61d6ce, 0x40cad666,
- 0x93ad4be3, 0xd54d3dd5, 0x7187bc3a, 0xbdf088c8, 0xff91fede, 0xf0fc7ed1,
- 0x684bf06f, 0xef681fed, 0x7a43dbd0, 0xfabed9e6, 0x7e674d5f, 0xeff2b892,
- 0xb093becb, 0xf93fb50f, 0x0825c9eb, 0x37d228d7, 0x3e7a6469, 0xa144779d,
- 0xb46f4fed, 0xdda77f23, 0xf9fdbde1, 0xbe053654, 0xd194b393, 0xf486f55b,
- 0x4837606d, 0x57eac89c, 0x768a186f, 0xfedcb184, 0xea40df3b, 0x133ba015,
- 0xa1390069, 0x696ae4cc, 0x9c63c4d7, 0x5bd267b9, 0xbcb45f40, 0x0dabca1e,
- 0x82fcdeec, 0x8da2b6b6, 0xecc22f30, 0x02cde5c3, 0x78c53881, 0xdad115fb,
- 0x3560a889, 0x80cdbc36, 0x55d83f4a, 0x55df63f2, 0xbf79ee3a, 0x3d26efe5,
- 0xbf2a82dc, 0x7abd31f1, 0x9ff83a70, 0x901c7a54, 0x48cc95e8, 0xe074ae07,
- 0x3e0c67a7, 0xe02c97b4, 0xb82b1bf7, 0x478eaf9e, 0x3be30df9, 0x281fb70a,
- 0x2d70aecc, 0x47daa3fe, 0x0f403b54, 0xf294b3be, 0xf37d119d, 0x0aea421d,
- 0x80f84ed1, 0xd2740dcd, 0xfe70ff83, 0xba53eea6, 0xd8d0f8cc, 0xd10321a5,
- 0x6497b9c8, 0xcd3697cf, 0xa3ffe2b9, 0x826eb8a2, 0xb40c97bc, 0xbe365c81,
- 0xf70a91d2, 0xcebf98dc, 0xdb3c46da, 0x662df7e8, 0xfed02f2a, 0x90b871ee,
- 0x0cc8647f, 0x97928c0f, 0xa2f2d214, 0xfb9436e2, 0x09c4a9a3, 0xc6decefc,
- 0xa762dffa, 0x3b4246ed, 0xdbba77c6, 0xa2dea42b, 0x2afc5f69, 0xe9725fbb,
- 0xdfed1da0, 0x734b1297, 0xbe748f80, 0xa77e476a, 0xba53bbfa, 0x8958d5df,
- 0x1e1db9eb, 0xd5854a45, 0x3d03f715, 0xfb93088b, 0xd86277b1, 0xf46358b9,
- 0xe9ff00e5, 0x9644d778, 0xe08b7ed3, 0xbc54a231, 0xef0257b7, 0x2ebed536,
- 0xca486400, 0x8216772b, 0x5864d91d, 0xf7428f74, 0x34b0c4a7, 0x576d08fa,
- 0x04e6c033, 0x9cc4c293, 0x7de7fd3f, 0x5ed1ff34, 0xaba7de23, 0x266139d8,
- 0xa2fad1d8, 0xa2fbf8ff, 0x7975bf74, 0xbcbabfba, 0xbf9f45bf, 0x814f6cd7,
- 0x36942cfb, 0xd8cf70dd, 0xb73baa64, 0xf4d7ce8d, 0x354dc99a, 0xd9b37211,
- 0xe81980f7, 0x071e8c5d, 0x3a729978, 0xe17c8046, 0xc044fd6f, 0x559250f7,
- 0x072f80ff, 0x9992e7e8, 0xf3efb3c1, 0x9eec289b, 0x6967551d, 0xc36d94da,
- 0x597a68fd, 0x6f8c0908, 0x045d194f, 0xf7e130e7, 0x97183c4f, 0x265367e5,
- 0x4cfefc4d, 0x68437ed3, 0xded79c19, 0x5c27bc72, 0x856bcf4b, 0xb87177e6,
- 0x8b47d557, 0x53445ee0, 0x3061a4d2, 0xc90be92f, 0x0abbfb0b, 0x17c8d13a,
- 0x3fe2cdcb, 0x115a3f76, 0x2d89efe2, 0x7b873a07, 0xf8e9e39b, 0x0cf8bee3,
- 0xe8532ee3, 0xc9cfc030, 0xee376656, 0xfda21652, 0x43ae6fda, 0x44b8d5bf,
- 0x60b5d709, 0xa0242d80, 0x9f20991d, 0x3932260c, 0xcb41611a, 0xffb986cf,
- 0x0b4e0e3a, 0x9ab930b6, 0xbbe033ec, 0xc1400b31, 0xd5fbb902, 0x700f18a9,
- 0xc9a7f376, 0x5b6e01e3, 0xbb0270ef, 0xccbdf5a2, 0x8369e78f, 0xada4bbf7,
- 0xbd0172df, 0x6262db1f, 0x765448f3, 0xfb8f7ec1, 0x837280c2, 0xc81f1224,
- 0x67b24d0d, 0x6b91d018, 0x8012cef3, 0x59a9d9eb, 0x517fd622, 0x37184e20,
- 0x7c1a4971, 0x5e48205f, 0xfdfa3f46, 0xa26bf753, 0x05c99939, 0x7f782b86,
- 0x4db4d8fa, 0x3e3dcf18, 0xc6f7f367, 0x8d3b7f42, 0xd2846f78, 0x3e703dc7,
- 0xc0f5d0d4, 0xbcb66a7c, 0xb38cc693, 0x628a4484, 0xa3fcdbef, 0xaab26074,
- 0x07975c78, 0xf2c16c7c, 0x3bed3cba, 0x78f03d1e, 0x1b9ba533, 0x166078a9,
- 0xaf2097c8, 0x35ea4ff7, 0x1e5e293e, 0xc54af555, 0x6d3b3c4d, 0x08f3d768,
- 0x329d3f94, 0x4e47c84b, 0x27ac6599, 0xf3616dfd, 0x3f105cef, 0xd02dfbeb,
- 0x60f10e5f, 0xea2b853c, 0x0ee2a62c, 0x69cf0080, 0x9fc599b2, 0xf51f73d1,
- 0x44a9f5a0, 0xffd1aef7, 0x3a51fde5, 0xb2f0077e, 0xc72bddf3, 0xd9b5ae01,
- 0x8f40231d, 0x0cfe5ff0, 0x56b65eed, 0xb9b4f766, 0x0d9e64bd, 0x992a7be8,
- 0x83e3105b, 0xcfe3377e, 0xd1baebf1, 0x63f16462, 0xc7ec5129, 0xd7f4656a,
- 0x4df6f5c4, 0xf7a82c4b, 0x99094a6d, 0x955fd261, 0x573f54ce, 0x2a63b705,
- 0x7b415e3b, 0x4e09090e, 0x2e296bf0, 0xe55d2746, 0x3fcf11b3, 0x882831da,
- 0xd1e3bdf9, 0xf1db65af, 0x8040c35c, 0x83f30b53, 0x0eeddcd9, 0x3b47df58,
- 0x7d60394e, 0xb80c3be5, 0x27d0f2ee, 0x620af369, 0xf049bd74, 0xfaf3c15d,
- 0x46b59d0a, 0xc768fb4f, 0x6d7369a7, 0x730a4f4c, 0x706f417b, 0x2f1952f9,
- 0xc65c2858, 0x751d9839, 0xf7c453dc, 0x386de232, 0x4f6f6b5b, 0x6af3b0b5,
- 0x0dc9859c, 0x7ad0d6e3, 0x7c618788, 0x1ebe29cf, 0x57a32079, 0xf8fc6d3b,
- 0xb4441be7, 0x26ac56a3, 0xff3d6768, 0xf46c81fc, 0x903cee6b, 0x5f53473d,
- 0x6f8c3f8d, 0xf1616d9f, 0xa7f1a41f, 0xe20d251e, 0x7378d83d, 0x2007cabc,
- 0x3b86909f, 0x1e38fa3c, 0xbd4d130a, 0xa7c40dae, 0xefd58a0c, 0x01dcff2a,
- 0x5a736a71, 0xb413110d, 0xa70678f7, 0xebcbbc80, 0x2f77f7c7, 0x45a123c7,
- 0x5ac93d40, 0xfa3e4510, 0x1134f9b5, 0x4d3e5a6c, 0xe324f7f7, 0xf0e3d1d3,
- 0x19d813ee, 0x6b933ce1, 0xf5c8126d, 0x5e182b69, 0xa2207f45, 0xc435ddfc,
- 0xf9522f52, 0xb0cace45, 0xb14aff01, 0x01acb8b0, 0xbf58f959, 0x1a679efb,
- 0x4999e7bb, 0x8a7e30ea, 0x1f51db38, 0x38863fee, 0x580d0e41, 0x41911c98,
- 0x830c1bdc, 0x7a3c9820, 0xf10151ea, 0x8e7c03c4, 0xa9ea0a88, 0x3f185f14,
- 0xfa33e477, 0xf952f0e6, 0xa02ad0a8, 0x92db371c, 0x862bf5c8, 0xa3c2d757,
- 0x3c62ffd9, 0x778ea05a, 0x12e478bd, 0x5be1f5c8, 0x1fc2761f, 0x845fb828,
- 0xf0a771fb, 0x3628a67e, 0xb880af7c, 0xf1dd1d8d, 0xcd9fb464, 0xfd04de54,
- 0xf62bb541, 0x62ea515b, 0x76b6e07e, 0xdface790, 0x7c5cf052, 0x05cb6c5c,
- 0xcede3a79, 0x11367748, 0x533801ce, 0x1f94bd61, 0x5797fb30, 0x9d71fbc6,
- 0xe21b8f01, 0x44880607, 0xcfdf3e02, 0x35ef8b90, 0xdd380bf6, 0x59dc182b,
- 0xbb1e631c, 0xb12b5c0f, 0x075942fb, 0x1772c912, 0x5f4cc7c8, 0xcb8eface,
- 0x78b52e0d, 0x225346ff, 0x7ea987b3, 0x69ecbef7, 0x9f4f41a4, 0xcbad5daa,
- 0x537e174e, 0x0659ce0c, 0x85049f3e, 0x41ee4fdf, 0x35c00ae7, 0xff510c6d,
- 0x4b3e4036, 0x14fe37cd, 0xae957bcf, 0xbd9d7b55, 0x736b9bc0, 0x7abb9213,
- 0x8be031dd, 0xb8e7efd7, 0xfdd5e57f, 0x025dff1c, 0x9e7a0e7e, 0xb4c39776,
- 0xe6ab39e9, 0xae12203d, 0x21cac7b2, 0x11695ece, 0x2575fb78, 0xde5c4877,
- 0x3ee7f1c2, 0x3caaef06, 0xf1ba266d, 0xe293f3b4, 0x629087fa, 0xdfad4b9b,
- 0x5bfa1138, 0x83e79237, 0x5f83d41f, 0xbea369e7, 0x6f29043f, 0x029a990f,
- 0xc9f07fd6, 0x1a9fc741, 0xe1ef3b1c, 0xa97807fc, 0xf7aafee7, 0x44de34a6,
- 0x3f3ab2c7, 0xf50778c5, 0xf4a7f6fc, 0x24e22f7e, 0xff5fe3e7, 0x761e841d,
- 0x261693ca, 0xc90096df, 0xf9003d51, 0x17a97fb2, 0x9ca825e3, 0xb7cc21f1,
- 0x338eddf3, 0xe7796847, 0xf78fcfb4, 0x7d6e3c03, 0x31e83678, 0xfa03b7e0,
- 0x501b37f1, 0x055a55ce, 0x462d6f86, 0x7f1517a4, 0x7f1c9d2a, 0x7f788312,
- 0x3090e9b0, 0x5445ec1a, 0x9bbecd3f, 0xd5b165ee, 0x31c70173, 0x533fdfea,
- 0xeccad953, 0xe2fcfe56, 0xffd0798d, 0xf9c0810e, 0xc3ff26bf, 0xbfa8b9b4,
- 0x4f36907c, 0x65a2aed3, 0x691f8b1d, 0x470af636, 0xfa606ad9, 0x1e7dc1dc,
- 0x43e70be0, 0xca4b1618, 0x906ad0a5, 0x45cbcb57, 0x8546efd4, 0xbe43ef4a,
- 0x2026533d, 0x5c587787, 0xd3cd1e6c, 0xe42f1083, 0xbf81ffa7, 0x7e77936a,
- 0x3347ca29, 0xd5c41b15, 0xce2fcf9e, 0x5795fb44, 0x061c0276, 0x926537bc,
- 0x149ef80b, 0xadb4b8c6, 0x2091b6b5, 0x83efadd7, 0x63693ecf, 0x782f5cfb,
- 0x7e67df83, 0x5bb5a271, 0xf930b4e5, 0xe4cac32e, 0x867bf541, 0xb79dc995,
- 0x0026db05, 0xda961c3a, 0xfaf720ad, 0xd013e789, 0xe6d7894b, 0x0f7089da,
- 0x129ddea3, 0x4d3da170, 0xfc7f6949, 0x4dbf2826, 0x223b38c2, 0xe3033fb5,
- 0x894eae76, 0xfc850bdd, 0x6f680523, 0x1beacc7b, 0x14e3a562, 0xf3b27971,
- 0x10859de0, 0xe1ce38d7, 0xe824c9fa, 0xed0973e7, 0x8a9ee33a, 0xf8004db6,
- 0xd9903e7d, 0x08e895b9, 0x9376b9ed, 0x9e93ad95, 0x92ef286f, 0xfbf237c3,
- 0x1d9eb40a, 0x5a16f1ba, 0xb8de4153, 0xfd18f458, 0x24694c6c, 0x7d549f80,
- 0x9282bb40, 0x872025e2, 0x4a96084c, 0x271cb718, 0x71e04c87, 0xf4a4881d,
- 0xfbc7317b, 0xe1777421, 0x558a2dfd, 0xc7265ff5, 0xaeb792e4, 0xa3e090cc,
- 0x8a88af2a, 0x1399ed0f, 0xc6085a67, 0x1e8cafd3, 0x9e2ec117, 0x0a7af942,
- 0xf160cbde, 0xb32ff9a2, 0x466120fb, 0x3ffeddb7, 0xa8fd1da9, 0x7e56ad93,
- 0xfc33d7ae, 0xb7186d21, 0xb0900940, 0xd6cf68fd, 0xfd5057de, 0xf27f6a86,
- 0xad8f6672, 0x7c17f6e1, 0xdf9696f9, 0xb2ed556d, 0x467e75cb, 0xf0bedc75,
- 0xc6aac2ab, 0x804b4453, 0xd507a31e, 0x4a4f8a78, 0x8cfa2f00, 0x5778e0a7,
- 0x78f572db, 0xd195bf0a, 0x4f1d37c9, 0x913588f1, 0x11f44bc5, 0x471f114f,
- 0x911999d1, 0xda4b5ed0, 0x7d04eeb7, 0x7e84c5bc, 0x6f2d29db, 0xcbce11fe,
- 0x43090a29, 0x5cbc56dc, 0x5f4d35e1, 0x75def80e, 0xc056cce1, 0xef7775c3,
- 0xb03f3377, 0xd7885e5e, 0x7cabb60f, 0x1b73cb97, 0x1fa7d7ad, 0x29bef5a8,
- 0xcbe54eb9, 0x5187ae7e, 0xb9c072fa, 0x23d383b3, 0xd1c41250, 0xdd6dcbc5,
- 0x1c9c7ef2, 0xd19eff11, 0x9d6f69a4, 0x61a47bc1, 0xa87100b3, 0xde0919af,
- 0x63ee0dd3, 0x85b56dfa, 0xc3ea93f1, 0x2ca9fdec, 0xe3ed1793, 0xf22315e4,
- 0xf9e57f0d, 0xfd114497, 0xdc00af04, 0x27e5a653, 0x5faefd40, 0xd50e901b,
- 0x85b690f7, 0x2a74fc98, 0x94c88c5f, 0x79c1b7ce, 0xa13ce30c, 0x3d741bf7,
- 0x31f18fd9, 0x5ae837ee, 0x9706fccd, 0x6033e3cc, 0x330ecaf3, 0xb7197ffb,
- 0xf14aafff, 0xae8332fd, 0xc64ff16b, 0x1e75dda3, 0xd65a61f1, 0xc71bb7a0,
- 0xbfccbdec, 0x78af0554, 0xcc05fbb3, 0x8fb1a7df, 0xae523bc1, 0xce18a906,
- 0x5ce25ca5, 0x15d97c0e, 0x16fdd0a4, 0xbbf9eb4d, 0x802882c3, 0x4ead213c,
- 0xac7ec0b1, 0x012717aa, 0x45eb05bd, 0x5bb88f7c, 0xd7e7e00e, 0x29ffce25,
- 0x8e3042c8, 0x77f3d69a, 0x96fed57b, 0xa9023111, 0x9574b028, 0xdbd49a53,
- 0x57f6a8b9, 0xc653ac6f, 0x4034be83, 0x25ecbb44, 0xe01333d9, 0x8f29297a,
- 0xbd645c40, 0x1261aebd, 0xbf1c472b, 0xb17a8e64, 0x1312dbfc, 0x092b88d8,
- 0xfcdbd9f8, 0xdb878edc, 0x3838c6bc, 0xe3f3d9c6, 0x88cb3ee3, 0xa0e6686f,
- 0x6f92719e, 0x69733e73, 0xbfbf2e4d, 0xaeaee0c0, 0x067f597f, 0x4b007137,
- 0x9e280e07, 0x303ffb09, 0xa04d8651, 0xd223b329, 0x07fce095, 0xef053b7e,
- 0xb7cfc513, 0xc023841e, 0xbdecd5ab, 0xff3aaf8f, 0xddff79f8, 0xcce9c69a,
- 0x5f780193, 0x3df194e6, 0x17d96baf, 0x705cb972, 0xd6a1fe2d, 0x07f806fb,
- 0x1b578bd3, 0x13adbc78, 0x97bc08f9, 0x04a77f08, 0x9e08aef7, 0x79d5a1df,
- 0x06d5aeb0, 0xc27e1f7c, 0xef9e1b74, 0xfbd987b5, 0xdb4b3576, 0xad9ce1b3,
- 0xf7c76e2d, 0x0de1e36b, 0xfe5495b3, 0x49cdeb43, 0x1c6ef821, 0x79fbd069,
- 0x3cb3fa7a, 0xd3e03645, 0x37aec8c6, 0x654338e9, 0xd7c858df, 0x02ee8d2e,
- 0x91e3b579, 0x5e404af7, 0xd26f539b, 0x2792a7c5, 0xd2227ef4, 0x65768490,
- 0x5effa4d2, 0x5dae39be, 0x2351bf0f, 0xd97ae3e2, 0x7be80c37, 0xd3f9839c,
- 0xef88a549, 0x01db75fc, 0xe1ce1a9e, 0xeed3cee7, 0xee7d03ef, 0xef67ad2f,
- 0xf77aef59, 0x2fec02f7, 0xbe6ad7dd, 0x7df617bf, 0xb7f60f2b, 0xf2b7cf63,
- 0x1bd77f60, 0x3f403d1b, 0x0f9f153b, 0xefa73cfc, 0xa39ca2f0, 0x0b5c45c6,
- 0x275d172f, 0xe6fa2e5e, 0xe7aaf2f0, 0xcaa6c05a, 0x5ced5f49, 0x9ead3f83,
- 0x218af87d, 0x34bf4668, 0x3d98ffc3, 0xf077fcec, 0x0a2cb95c, 0xabe8f7e0,
- 0xae5c51bf, 0x104850cc, 0xc54513ec, 0xe8aed8ed, 0xdc809173, 0xf179caa4,
- 0x9f09f870, 0x4f36f3ff, 0x5f879c02, 0xce5aeed7, 0x4fa128eb, 0x43b9fc99,
- 0x6bbb3370, 0x1dd5c598, 0x9d82752a, 0xd9885cf5, 0xb1f76b5d, 0x422bea77,
- 0x5df0446f, 0x09c156f3, 0x8ec541fa, 0xeef01c0f, 0xae4e2690, 0x448ce819,
- 0x9deceff5, 0x40729d0b, 0xb79d1bbc, 0x6b78e415, 0x7a06544a, 0xf1172da8,
- 0x295ab3dd, 0xb5bcf18a, 0x241dc429, 0xf5ea5f20, 0x6c2e352d, 0xba465793,
- 0xdecad4d9, 0x7d934ca1, 0x0f11fdb9, 0x6dfbe3fb, 0xb7edfd2a, 0xf800fe79,
- 0x7ad3f31b, 0x8b576c5a, 0xc32ff91b, 0x617fe636, 0xccd97fe5, 0x6e3502e4,
- 0xce8ff544, 0xf3eef1e7, 0xf83bbc79, 0xf81a236d, 0x9b56df82, 0xd5b6fd57,
- 0x88322f10, 0xe5b56df9, 0x8d687edd, 0xae5b56df, 0xe889178d, 0x93234df8,
- 0x310b0d77, 0x25d2864e, 0x579163c6, 0x88ced505, 0x74a7e9f4, 0x0c6464b0,
- 0xf0fdd57f, 0x12b87f97, 0x3cfcf3e2, 0xf01ab2ee, 0x61c60477, 0x5fc04c46,
- 0x355f14c3, 0x4b6a2efc, 0x7d7374e4, 0x37e8c8f6, 0xedf1df4c, 0xe3c7573f,
- 0xb3aead74, 0x02ad5d7b, 0x75b8c3a3, 0xf189ebc5, 0xcf5569f6, 0x4bdf16bb,
- 0xdf1f5fb6, 0xabfdeb53, 0xfdb65ef9, 0xbef7c39f, 0x47fffb29, 0x3034c6ae,
- 0xe87b3e05, 0xd083df87, 0xad8312a4, 0x4c9477fb, 0xae3fe1d7, 0x437062d9,
- 0x21cd4ddc, 0xaaf21bbb, 0x7fde323f, 0x94f64958, 0xfde3c800, 0x5710d588,
- 0xfedae831, 0xb77b62c4, 0xfb573d5f, 0xb151785e, 0x61bf5f9e, 0xa7d934fb,
- 0x02e2d3c1, 0x82f7e02a, 0x24148ab7, 0xa9f638da, 0x7eb7e676, 0x9fefbf83,
- 0x88069321, 0x6eda7893, 0x14467bc5, 0xa62e306b, 0x6e9dead8, 0x9afc0d1f,
- 0x83d9efc1, 0x0b8812f7, 0xc618d67e, 0x1ac13efb, 0x5727de1b, 0xff6a23ed,
- 0xa97ea96f, 0xcd73e06b, 0xcd73e275, 0xf1cf8c37, 0xe3ab17ed, 0x61dfaf5d,
- 0x06918503, 0xb3f1e3df, 0xf17d76af, 0xef765581, 0x91d23b72, 0x5eb9ef07,
- 0x11e8ff2f, 0xf1b92987, 0x4dc41d5e, 0xfc559c42, 0x74f7a87e, 0x6b70b954,
- 0x97a1fb9f, 0xc57eb707, 0x3c96b8fd, 0x0de2a4f8, 0x8f4f7ac1, 0x3e81e4f7,
- 0xeccecabb, 0x0ccd9b2e, 0x0c0b372f, 0x13e07b1f, 0xe2a3efbf, 0xf5fb01d5,
- 0x7ad43bd9, 0x78fe6aff, 0x2d7c2ed4, 0x69fc077b, 0x886c90f1, 0x7d767be2,
- 0xfe9ec7f2, 0x5977162e, 0x517a86dc, 0xef8090f4, 0xf6f3ab33, 0xd63b31b7,
- 0xd45c39ef, 0x1cb8fbef, 0xfcf0e398, 0xf10a9ec1, 0x8f028a49, 0x59028c3b,
- 0x2f28e40e, 0x0da9378b, 0xda8fb8b3, 0x70e304a5, 0xb511fbd4, 0xc809532d,
- 0xbecd0b6d, 0x55fb433f, 0x8682d9ef, 0x4fa3b004, 0x75a72023, 0x37f2cbbe,
- 0x401f7d9b, 0x3b697fb9, 0xa69bfdda, 0xa138c79d, 0x5d3f2fa2, 0x3a5df609,
- 0xa40bb45f, 0xd3f7f498, 0xc7c60e1d, 0x50ead4d4, 0x7b41ebe1, 0xfb950778,
- 0xa7f2de40, 0x5f609c78, 0x56cded50, 0xe1da1b57, 0x6732f76b, 0xad81915f,
- 0x9fda3c87, 0x8ef6d1f9, 0xe415fc2f, 0x9042e6c3, 0xb7de8b57, 0xe3a8fda1,
- 0x138c2c91, 0xbbeacc78, 0x1f6af80c, 0xe40bba15, 0x0e3a1ccb, 0x7b1dadc8,
- 0x79842aee, 0xe0a17d77, 0xccecbaba, 0x24f5d0bf, 0xcaf88999, 0x665dd1ed,
- 0x9f022786, 0x666ad76f, 0xba1e0a9f, 0xdd03bf91, 0x38368f6d, 0xd1ecc746,
- 0xa5407cf1, 0x08fbeeff, 0x1ff414b3, 0xbd61fcab, 0xeaa39d91, 0xeece77f9,
- 0x3c16f1e2, 0x2a75aeae, 0x79e0d78b, 0xf8554f1b, 0xe3bb6f3e, 0x9cf3ac1c,
- 0xdec7fa5d, 0xe24cbec3, 0x2fd8e7fd, 0xe36939c4, 0xdfe0add5, 0x53897b01,
- 0x37b2bc46, 0xa1dfe610, 0xf9f20578, 0x09b6d16d, 0x839d7409, 0x01b7229b,
- 0x165f0fbc, 0x53a0bbd9, 0x92f78b7f, 0xde360413, 0x57da27a0, 0x8afb050f,
- 0xc36fedf3, 0x9d1abad6, 0x5b92e0c5, 0x870ef668, 0xd52241b8, 0xc578c3e5,
- 0x3c5918ef, 0xda2b21df, 0xabb29a09, 0xbb691273, 0x684cf7ce, 0x03e789af,
- 0xcb241a6a, 0x606f8e31, 0x0ed01fcb, 0xe82bdf6f, 0x93a6a6e0, 0xf7e6361c,
- 0x6095b609, 0x296dc9ac, 0x0e6e77ec, 0x7f041fbd, 0x5f1ab4bd, 0x46f52486,
- 0x7572088f, 0x7b411970, 0xa72690e4, 0xc395fb08, 0x0eba44e3, 0x1f08cfff,
- 0xddaa9f9e, 0x64a9843d, 0x7a095f6c, 0xfdacb495, 0xc7ec20f6, 0xb6b144de,
- 0xd68bfa00, 0x12b27c32, 0x5a739f38, 0x95bf2d06, 0x9c1a73e6, 0x7aea3fe8,
- 0x0de30ab5, 0x439d7483, 0xa167597a, 0xdce5c583, 0xa520e3c8, 0xfc115643,
- 0xb85ad2d2, 0x5341440d, 0xd29671ef, 0x129c43f6, 0xc38e7de2, 0xd4f00b37,
- 0x5902f9ca, 0x9c7f4162, 0x6d78625d, 0x8bdef25f, 0x55bfcf10, 0x1d4fef66,
- 0x34e37c3d, 0x96addfb4, 0xc6ab5ed0, 0x74e02e51, 0x47de13dc, 0xe0725e31,
- 0xbf303fa1, 0xfa0b1d0d, 0x3f0c8c97, 0xf829d5a4, 0xc87fe07e, 0xfd0b8c3e,
- 0x80c47d76, 0xe9e728fe, 0xaeb92667, 0xebc4b7ad, 0x891ccb29, 0x622e295f,
- 0x3d9be399, 0x3fdbe24f, 0x55f78eae, 0xd7a210f5, 0x63e87acf, 0x5c7572f1,
- 0x0ee4befb, 0xf542ee35, 0x504f1177, 0xcc526f17, 0xbe8a21c7, 0xef0b6abf,
- 0x50a3c78f, 0xf205c439, 0xd70ada4e, 0x8ebf8832, 0xdfa098fe, 0x09978d46,
- 0x9738b316, 0xbde0a8a0, 0x88d20cab, 0x48fd3271, 0x1ed01044, 0xd3b6e2c6,
- 0xb6865e21, 0x8818ef5b, 0xee216ffd, 0x41f20306, 0xa4abbe17, 0xfdd055c6,
- 0xd3243a41, 0xc13f1e64, 0x566b37f0, 0x70e2085a, 0x9f7edcfd, 0x7f1f2b35,
- 0x3f135567, 0x33feecc1, 0x7d4f882d, 0x10aa53de, 0xd6253df9, 0x1710d36f,
- 0x4d7ff3de, 0x693e6bb5, 0xe2e3ed67, 0xaa38542c, 0xfc2a1671, 0xf14c7bd4,
- 0x79314c70, 0x57bc02df, 0x7dd425e3, 0x0d8fdeee, 0x55d82ecc, 0x1cbbe221,
- 0x155d7f6a, 0xdc83679f, 0x626adc50, 0xefd712f8, 0xaefbeea6, 0x67c63321,
- 0x96bd7df3, 0xdfbeaa1c, 0x23bf9475, 0xd7bf8c75, 0xc21665de, 0x399f8006,
- 0xc9381b3a, 0xee4784f6, 0x5d817b84, 0xdc3668f6, 0x78dcdc2b, 0xa7cc24ff,
- 0xfe424f46, 0xc3ff84b5, 0x5ba243f2, 0x89e19ee1, 0x1e58b3a7, 0x908b2e70,
- 0x49848e33, 0xe07f82c1, 0xe3d73a5c, 0x022e1a77, 0xfb486b1c, 0xd3b436ca,
- 0x146973f0, 0xa26463e3, 0x44ecc429, 0x13ffdc2e, 0x631dec99, 0xbdc0fe5b,
- 0xdfde506d, 0x5a2df684, 0x627bf88e, 0xee5678c8, 0xfa4dfb62, 0x029c59db,
- 0x13d33dff, 0x1fd1e3b9, 0x4df8035e, 0x462b85e5, 0xc740989f, 0xe1b420bf,
- 0xee27593b, 0xe00161f8, 0x8ffd85eb, 0xe2b9060e, 0x77f7b94e, 0x72731ee1,
- 0x7ec8c239, 0xa34de5f7, 0xf9409acf, 0xb3ad1fc3, 0xff69124b, 0xcbc79333,
- 0xe0ef3089, 0x51eef8f3, 0xc4bfdf2a, 0x4bee4c19, 0x2015e89c, 0x3363f17e,
- 0x1f54b3a3, 0xe2063dfb, 0x3ddc219b, 0x12d7235c, 0xc4113bf6, 0x7b804ae7,
- 0x68eff108, 0x6b5e12dc, 0xf7f73900, 0x780ce881, 0xfefd5552, 0x38f7a107,
- 0xc604828b, 0x5c19a6c7, 0x141f01c3, 0x29cdf1b1, 0x2bc6c4b7, 0xfbf17048,
- 0x70a375c5, 0x51ba86dc, 0x28f4c7a0, 0xd072d1b7, 0xe5a09e93, 0x97297bc3,
- 0xd67afb78, 0x938ef35e, 0xa974e01b, 0x2fbc03f4, 0x04eb38b4, 0xc27647be,
- 0x0ef03c48, 0xfb93304e, 0x0739e8f5, 0x273c7dfb, 0x3b4fc591, 0x40704c37,
- 0xffdb107e, 0xfd0848bb, 0xb06653bc, 0x21df597b, 0xb4edf56d, 0xfa199dde,
- 0xcbb963df, 0x277fcfa5, 0xc29f9f5f, 0xebbe07e3, 0x1eff7fd6, 0x0f804a89,
- 0xffa31fdf, 0x441797dd, 0x0be0094f, 0x2f8c27e5, 0x2aee3c0a, 0xf9c20845,
- 0x2c81e37e, 0xc61a9ef5, 0xf5c0bdb3, 0x7fbf3f11, 0x91aa6701, 0x8586e3ae,
- 0x1bdc9dec, 0x93928833, 0xf92bfc04, 0xf07bbe08, 0xa729f711, 0xf4789bc0,
- 0xd713a97b, 0xf419e2af, 0x1f7c3b75, 0xe2e0cf9d, 0xd2538321, 0x418eefd8,
- 0x6b2309d9, 0x84b1fc1b, 0x7d684e7c, 0x3e2c6ff3, 0xf184bc62, 0xd7ab0277,
- 0x4ff86665, 0xfefc524f, 0xe21ede53, 0x27c89caa, 0x4abfdc2d, 0x8be85df0,
- 0x78d8d2a3, 0xfa8b0f1c, 0x5bc01629, 0x7cbb5df5, 0x1bf6e127, 0x7069a64a,
- 0xe794103e, 0xfd54bc54, 0x3c380348, 0x7f327e28, 0x1f872671, 0x06f7f091,
- 0xcfda8932, 0xadc61374, 0x04bafcf1, 0xde2a6f46, 0xb5ec7fae, 0x5f00a737,
- 0xc03f5c12, 0x3bb2ee7e, 0x74f9bd61, 0x804999ac, 0x78d829bf, 0xf449e707,
- 0x247927bb, 0x8c5d8798, 0xb09a1b18, 0xbf7f307c, 0x4fa4fa6c, 0xfe1a4866,
- 0x61adfb45, 0xfdf55afd, 0x459ba3c2, 0x68337e9a, 0x7e9a49bf, 0xf2c2689f,
- 0xbfe5fbbe, 0xe7e92147, 0xaf8fb6a7, 0xf3f5ea4f, 0x7c7dabec, 0x14f7f53d,
- 0x4df87326, 0xf329e356, 0x640f71f5, 0x7e615b8c, 0xc39c7d6c, 0x8edf1c9b,
- 0x306dff5b, 0x09250be8, 0x2844a70f, 0x1a524c3d, 0xf408dbeb, 0xd0fa461b,
- 0x802ff5d0, 0x7e652e2e, 0xb6fbbf80, 0xd989e078, 0x97a519d0, 0x7ba309dd,
- 0xe7c547ce, 0x3c5179ee, 0xf1543c06, 0xdd9e7e38, 0x30bdfc78, 0xa16d7206,
- 0xaaa407f2, 0x9d48423c, 0x0d70eb80, 0x2283ad88, 0x87528961, 0x22b37ff3,
- 0x33bdf388, 0xff8c19f1, 0x3be49319, 0x799af302, 0x3dec27d3, 0xa1d28c93,
- 0xf9d10720, 0xfd484d1e, 0x355f377f, 0xe1dc796e, 0xbd82373b, 0xe3ee9bb4,
- 0x5fed5ce8, 0xf234d395, 0x2af73b15, 0xf2be5545, 0x19642900, 0xe57cb832,
- 0xacd678c2, 0xf10dcb80, 0x8af91aaa, 0x44d547c9, 0xeece07bd, 0xa060fced,
- 0x987abe5e, 0xb76ebc60, 0x271a557c, 0xede3cd5f, 0xc42092a7, 0x93d936c5,
- 0x805e2c42, 0x162d39ce, 0x8db4dbff, 0xb74d8dc9, 0x82419cb8, 0x33d31672,
- 0xe87bf166, 0x6bde4cb9, 0x77c98fba, 0xbaea1ce3, 0x6b78fa2c, 0x133567ee,
- 0xb8b12f2a, 0x99abb40c, 0xa5d97d9d, 0xb53576f4, 0xf202ffde, 0x007f0832,
- 0x00007f08, 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0x73b9f8b9,
- 0x64cacb67, 0x109848df, 0x424e3b08, 0x875b3612, 0xe22948b0, 0x3cb888b0,
- 0x4240b21c, 0x3eb44196, 0xc33fedad, 0x0d220222, 0xc168d46d, 0x2a14180e,
- 0x0431a0d8, 0xa4587049, 0x141a87d0, 0x2f1f682d, 0x48145840, 0xad88a0c6,
- 0xbefbffcb, 0xef726e73, 0xf6b42264, 0xfa7fb6ff, 0xef7397b3, 0x6df3be59,
- 0x39ce5be7, 0xd78deec3, 0x1ec658b1, 0xacc630b4, 0x98eb458c, 0xb19436b3,
- 0x96eff0ef, 0x95e5e7ae, 0x6289e63a, 0xa31574ac, 0x47d7e5e7, 0x7a83cfa6,
- 0x4c8c7697, 0x66e783cf, 0x92d433b3, 0x50e158cd, 0x2fa18a7b, 0x7b46f963,
- 0x9b19933a, 0xbeb45e64, 0xcc9eba19, 0xd393f516, 0x5b09fb18, 0xcf074c74,
- 0x48ce9151, 0xc8673fac, 0x287a2967, 0x0379f8b3, 0xfd8c611c, 0xc28f675e,
- 0x19b98cf7, 0x718535c2, 0x4398a6b8, 0xf870f2bd, 0xa5c340f7, 0xfe8c8196,
- 0x1c7183be, 0x4b6f6726, 0x1155630c, 0x67971fb5, 0xa35cf631, 0xe2b6e6c9,
- 0xec1496d7, 0x11deb18f, 0x043086e7, 0x543ce185, 0x39e814f0, 0x4cb2d13c,
- 0x040bf4f0, 0xc65e630f, 0x68e0ba72, 0x94ae8437, 0xb1e0a97a, 0x00d17eb3,
- 0xc7be24a7, 0x06895ab1, 0x6a5383f3, 0x1257e3fc, 0x33d38fd4, 0x63265877,
- 0xea97981b, 0x1ce75efd, 0xb3c6e381, 0xb8e1894a, 0x112b6c2b, 0x96e0dd4f,
- 0xbf30c901, 0x1ec977d9, 0x0ae60c13, 0x7ace1f09, 0xd4fb3d61, 0xba7f1804,
- 0x2af67f18, 0xac0884c7, 0x78e25d37, 0x00ffc2f0, 0xfbe219fe, 0xa9b2c6f4,
- 0x3198e00c, 0x13ba70c1, 0xa66ff83e, 0x0181ba65, 0xc2a6b39c, 0x7bd7737b,
- 0x61d2209c, 0x2cffd28e, 0x6c39bb6d, 0x387267cd, 0x10191696, 0xd5ee735f,
- 0x09669f7e, 0x42173e8b, 0x077c076d, 0x60603af3, 0x79f68f34, 0xe609b3cc,
- 0x82cc56f1, 0x3347f7f5, 0x43b7e036, 0x7fe86533, 0xcd716c62, 0xf4bf283a,
- 0xbf2a60dc, 0x83cf7b15, 0xf3fbf147, 0xa09e54e9, 0x6e504683, 0xb3ce99ff,
- 0x9cd01529, 0x5494d773, 0x9040ff18, 0x467ef7e8, 0x9d83e3ef, 0x5ea1d355,
- 0x99bef0fc, 0x04d3e0cb, 0x0aede323, 0xde9ff7f9, 0x9ce54614, 0x191eacfb,
- 0x6c109cba, 0x30f7d375, 0xaa09b6c9, 0xd130c91e, 0x53e361f7, 0xccbef7f9,
- 0xe7df851e, 0x23fb5185, 0x0b5e2199, 0x47f2f78c, 0x01fbe883, 0x0eb9b3e9,
- 0x595b5120, 0x52e91ea8, 0xe336689e, 0xc940c873, 0x3df0083b, 0x5f8c5221,
- 0x353de7c6, 0xca226b73, 0xdf5c84cd, 0x6850c75c, 0x670e6897, 0xfe1f1137,
- 0x8879f90c, 0x34aadc6d, 0x5f16afe4, 0x150f9a8a, 0xf8574f3a, 0xcf96826f,
- 0xc51e7e40, 0xfa9f0af6, 0x87c2a7f3, 0xea0b3e1a, 0xb97f33e2, 0xd7009e57,
- 0xb18f924a, 0x97721f20, 0xe38e747c, 0xe3fe2727, 0xf8bf24f6, 0xdca2c527,
- 0xc2777f88, 0xd0f24b57, 0xb9e9b99b, 0xcb83e501, 0x8708b3cb, 0xc56cd751,
- 0xdb247df7, 0x33c20b60, 0x0c7666ca, 0x0a372eeb, 0x783ac97c, 0x2e1dd991,
- 0x3943d3fc, 0x45fe7589, 0xb8e0e747, 0xb3b43bfc, 0xb82ec8b3, 0xa4adfc60,
- 0x7870569f, 0xb88b4836, 0xd09763bc, 0x5768b94f, 0x41b7ccae, 0x0678df3b,
- 0x2ffa8778, 0xc4967ec4, 0xfe18dddb, 0x82b87995, 0x4f81ee41, 0x611d9966,
- 0x1dd39846, 0xb724f911, 0xebf73277, 0xb38f8011, 0xc2136706, 0xae643c77,
- 0xed7e1191, 0xf757a146, 0x74285f20, 0xc7f4e052, 0x7a0f794f, 0xfe1e7fcd,
- 0x57a2e978, 0x133e0273, 0x2b2a22d8, 0x79e1bdf3, 0xae5e0ff6, 0x69bdf983,
- 0x147c9df0, 0x6fcdebe4, 0xeb3736cc, 0x20cdf382, 0xbc3d12eb, 0xd992ff77,
- 0xb3e00736, 0x051f8168, 0xb32e772e, 0xcebeb19b, 0x8a9659ec, 0xe06af674,
- 0xcfe88fca, 0x7f174c58, 0x5eeb31c5, 0x2afb3154, 0x3d56b6ec, 0x57a487ad,
- 0xcf50c2d8, 0xab9f6866, 0x99c4e5e7, 0x50a59eb1, 0xdce8f76e, 0x3c6f1806,
- 0x347375e8, 0xefe74fbe, 0x38230b59, 0xc20b3147, 0x90011559, 0xbbaaf7c2,
- 0xd1c03dd2, 0xd95bfeac, 0x7ddf041d, 0x0fa4c1c5, 0xc16032aa, 0x83efc2cb,
- 0x896efbe9, 0xd62ee38f, 0xd355b8d1, 0xeaa8feb9, 0x53b8f16f, 0x54ceb271,
- 0x8daaf7e4, 0xd04884f6, 0x5b328923, 0xa47a0b54, 0xf0ca152a, 0xeec65d8c,
- 0xf4c47d43, 0xc3d3e1f6, 0x78fbf0ba, 0x11deb8d8, 0x84b71fc0, 0x96fe75f3,
- 0x2af9ccb5, 0x29b563d6, 0xd57587d3, 0x00008a8b, 0xd4305eb0, 0x596efe83,
- 0x6286f50d, 0xac2f507f, 0x83763d7b, 0x68a7c476, 0xac608c47, 0x9f11d858,
- 0x8299dd6e, 0x9b27c476, 0xa9e4a677, 0xd8945fea, 0xbfd71c1c, 0xbc656f7d,
- 0x66ec67ca, 0xa0926f18, 0xf98724fb, 0x50eb8494, 0xe77b44fc, 0x1a7c85fa,
- 0x0235bf61, 0xef9061f5, 0xb47ba445, 0xf90e77d1, 0x6261bd8a, 0xa3ae199b,
- 0x1a5d72be, 0xf7876faf, 0x1bc8efe5, 0xdb7e0357, 0xdbfe3862, 0xbe041976,
- 0x2dff9e5b, 0x0c34af94, 0x3c61ab60, 0x0231bc17, 0xd71cbbff, 0x853d702a,
- 0xbfce333f, 0x57112854, 0x55d98983, 0xfc1b60eb, 0xc5d99457, 0xd04ced2f,
- 0xe88421b7, 0x1b372e5b, 0x75caff91, 0x70875d92, 0x59ec1c2c, 0xa7e97526,
- 0xe8af4512, 0x132972d8, 0x262cede9, 0x9827bcbe, 0xfdf0966d, 0x80c5f4e9,
- 0x9af352af, 0xa18f5c66, 0xd70901de, 0xb407a41c, 0x53ed885f, 0xbcb3e3bb,
- 0xad54e00e, 0xb4dba5f7, 0xc6642f70, 0x0784efae, 0xd7cbc937, 0xc414e706,
- 0xb730596b, 0xcd4b2e43, 0xf03f0839, 0xf017b79d, 0x2649afa9, 0xc0c426be,
- 0xbe8a79f8, 0xdc7ce6a9, 0xb3c7d55e, 0x09e7be04, 0xca35e5ba, 0x0b3c135e,
- 0x5a7bbce3, 0x2d4addb0, 0xfbc74b1d, 0x3952ea0e, 0x1ea38e1e, 0x4dc152af,
- 0xa7054e7a, 0xa25cbddc, 0x7d45eef7, 0xc63f3fe0, 0xeba935be, 0x4ab689dd,
- 0xe709f236, 0xf495667b, 0x0797d066, 0x4ca15d05, 0xe62499f3, 0xf5f23466,
- 0x14ef9fdb, 0xd08eaefc, 0x8eba3971, 0xbe412dbc, 0xbcbeb98e, 0xb3fef529,
- 0xdff56de4, 0x06ec6f29, 0x8267c1d7, 0xf8083b98, 0xd8ca5ab3, 0xfab27a8b,
- 0x465b6636, 0x37ebb55f, 0x088673ac, 0xc035fd7c, 0x85987403, 0x9d7906ff,
- 0xad3f7d1d, 0xfc97607b, 0x9cd9f516, 0x776ec201, 0x2424bb70, 0x9b19f38b,
- 0x61fd3cc0, 0x1ca2610a, 0x23d9b932, 0x1eb91f03, 0x006765ce, 0xf8fb311f,
- 0x32f5f2fb, 0xe51375d9, 0xa865d8bf, 0x659431db, 0x5cc80582, 0xd53f4417,
- 0xa633f512, 0x24fee371, 0x6e4c4728, 0x7016464e, 0x6674bc3d, 0x9c0208eb,
- 0xd058b1e8, 0xdfe1f163, 0x67c5bd50, 0x7d827979, 0x57942f60, 0x799921d7,
- 0xa1c761a0, 0x2f2c7a99, 0x28b125d8, 0x104cf718, 0xd501a397, 0xc955663a,
- 0x304f20e3, 0x75f8aab3, 0x4d4896c8, 0xa26d5879, 0x0d4dfea6, 0x33df357d,
- 0xdf3583bc, 0xd4ca1c47, 0xc79bb394, 0x3c8fea68, 0x8f29ab9e, 0xa9a2996e,
- 0x0cc2f63f, 0xbe47f94d, 0x99f535bb, 0x103cdedb, 0xe82050f0, 0x8a0ff8af,
- 0x5ae5bafe, 0x2c3da69e, 0xe8095ec7, 0xb15fc85a, 0xc80b3582, 0x2d07193f,
- 0xc896fdd4, 0x8da20e6b, 0xf5a95856, 0x6b54164f, 0x1b0dc5cb, 0x5609408d,
- 0x2fbed1ec, 0x0f2da2d9, 0x43a79e88, 0x011b3abe, 0xf820c9fe, 0x428b1447,
- 0x2ec9eff9, 0x44efa7f1, 0x00758fe1, 0x7e8098df, 0x33dface9, 0x7d234737,
- 0xdf03cc0d, 0x7e05b03b, 0xf5c1be07, 0x03d0e3a3, 0x8523e43a, 0x3278fede,
- 0x1ee96bc5, 0x3dd2d564, 0xee96a064, 0xdd2d3661, 0xd2d28d7b, 0xa5aec23d,
- 0x2d64d47b, 0x5a1c63dd, 0xd1cdc7ba, 0xa9c13dd2, 0x91527ba5, 0x8bc9ee96,
- 0xf3ef74b4, 0xa9ae96b0, 0xbe5a85ee, 0xc503e3f0, 0xb95b4b4e, 0x8e9eafd8,
- 0xe0fcd4e9, 0x40ca9a28, 0xfcaff4cf, 0x7fffa6b9, 0x45a43f36, 0x92353f0a,
- 0x7e477e45, 0x645fbd86, 0x46ff7776, 0x7f6a6bd1, 0x65d39f42, 0xefa4f67f,
- 0xd3cbd9ba, 0x47a09c78, 0xdc9ad97b, 0xf5272f65, 0x982797cc, 0x4bd689bb,
- 0xf08746b6, 0x70e165dd, 0xa357c15c, 0xd59bbb19, 0x13dfb01a, 0xc0146750,
- 0x03e7027b, 0x9acbdfe3, 0xe65cfde9, 0x5993a7a3, 0x63ccf88c, 0x30167a36,
- 0xe8a73d07, 0x1e22b79c, 0x392dcd4a, 0xceaf6fa8, 0x42527a3b, 0x21448ea0,
- 0x2f23dfd0, 0x4ea75a6e, 0xd999cc57, 0xd6b18fda, 0xb44ce70a, 0x16e33ba7,
- 0x568d6676, 0xbc6f2de1, 0x7a8f5034, 0xa1b60e56, 0xa777943d, 0xde6cf644,
- 0x3739fc97, 0xfe43af92, 0x2b0f65cf, 0xfe14ab78, 0x1e43f707, 0xbb0ab48e,
- 0xc943399e, 0x7059b3be, 0xb8fe805d, 0x9182ff3d, 0x82582eec, 0x2e80d7f5,
- 0x4f4e24db, 0x4dda2ba4, 0x7cccf4c3, 0x9843ca0d, 0x27ccfc93, 0x7892a0f4,
- 0x1fb1833f, 0xa0dbda17, 0x75234a02, 0x8e394e34, 0x3cd4f007, 0xaa20cccb,
- 0xe98126ac, 0x9afb4207, 0xf12ca225, 0xbce1fe32, 0x454cdfc9, 0x4d2b6d78,
- 0x4858af64, 0x4ccd923e, 0xe3dc91c4, 0x493ef0dc, 0xed090d06, 0xbfc01bd6,
- 0x6b942488, 0x2198c3e6, 0xfaf99ce2, 0x934c157e, 0x51f8539d, 0x0a2f7c26,
- 0x1dbfdeb4, 0x9595edc9, 0x40efc715, 0xcdef297a, 0x84b3377a, 0xf7825ea2,
- 0xeb31b92a, 0xb0f11d99, 0x533dc2a2, 0xc8d9ff5d, 0xf1e7ea48, 0x4e2d8bde,
- 0xdf723ef8, 0x720428a2, 0xd9739067, 0x10a1658f, 0xe9458962, 0x069ad46f,
- 0x1ec3fb99, 0x919afd19, 0xd4e7f5c7, 0x2dd1a471, 0x0bd8f2da, 0x0f42b2da,
- 0xc177f376, 0x82650728, 0x00f14caf, 0x195eaa97, 0x67c0f63a, 0x0fdcf165,
- 0x84c1be63, 0x1b90a377, 0x0de49d53, 0xc130f902, 0x0a61925c, 0x9ccc0c2b,
- 0xedeb7480, 0x6e5da0b4, 0xd0ebd44c, 0x2ff2603f, 0xf800ce6c, 0x78a69e53,
- 0x7eb555fd, 0x17ea03f9, 0x48d86bb0, 0xdff11236, 0x41e02f09, 0x1a3a7802,
- 0x46ae36e2, 0xcdcc9c78, 0x613603cb, 0xb3fea7b9, 0x7a59becd, 0x0b6cc110,
- 0xbc3fc67f, 0x447e9674, 0xa3af7af7, 0x64e3075d, 0xd93db8eb, 0x8e5cde9d,
- 0x6bb3e93a, 0x01646c81, 0xb0d553e8, 0x7fd4e3ff, 0x25793e9c, 0x51e22ba9,
- 0x6fc092ee, 0xcd698787, 0xf8009612, 0xc75aac2e, 0x092e3f90, 0x8f325c38,
- 0x24d7b1c3, 0xb5e8a7aa, 0x10022c97, 0x875a1af3, 0x62f04407, 0x0eb72f7a,
- 0x6bd2f2e5, 0x2fae88bd, 0xf1474efe, 0xa3cc41b8, 0x610cf9c3, 0x8c3efa5e,
- 0x26f950b5, 0x67281514, 0xdbf12b30, 0xbb23e608, 0x2b5cf411, 0xd972b9ea,
- 0x2820bbf9, 0xbe764e5f, 0xe84e7a44, 0x4fc174fd, 0xaf7e8ae9, 0xddc7fbd6,
- 0xf8a48d3e, 0xad0b6f4a, 0x54ce4223, 0x3af82674, 0x7f91448e, 0xe768e209,
- 0x544db4e5, 0xc688303e, 0x587c1429, 0x8d88ec98, 0xc5ebd154, 0xf5336b8a,
- 0x7802f92a, 0x5bbf28ec, 0x4d66822a, 0xa397bd50, 0x32071e38, 0xa18fd5df,
- 0x2175f9ff, 0xe047b436, 0xf97ec68d, 0x4729c90f, 0x5b97bc01, 0x9a3af5ac,
- 0xf50ea567, 0x24efd962, 0x33c01cf6, 0x66b97180, 0x7035e2fd, 0x9848a96d,
- 0xf9f40135, 0x0fdc917b, 0x1c7cc971, 0xe28433b6, 0x8cc98531, 0x853f4385,
- 0x7c91a7af, 0x0bd0c40d, 0xcc32b1c2, 0x8c2f7683, 0xdd95151b, 0xf1ff1e1d,
- 0x35df43df, 0xb733f49b, 0x1ef543bf, 0xdd9973f4, 0x7bc7556e, 0x19bb0b56,
- 0xe39213fc, 0x3b9fd160, 0x7aff7197, 0x84fb8f30, 0x296ae6b2, 0x62f5e7ad,
- 0x9a651a20, 0x014c02f5, 0x36ce5718, 0x16ae5c93, 0x47acc472, 0xe18fe8ad,
- 0x3a184673, 0x8f0e9cfd, 0x1cfbb187, 0x24fd7a2a, 0x3f0baf8a, 0x6a78e289,
- 0x077b7337, 0x2a19f5e3, 0x31af387f, 0x251bec9f, 0xec2edfbe, 0x9503f6c9,
- 0x27e8c1b9, 0xbe388a57, 0x058a9fb0, 0xfa682d2b, 0x4ad78e4d, 0x3e91587d,
- 0xfe7de2f9, 0x535dad4a, 0xf649c5b8, 0x24ecf5cf, 0x09c514c0, 0x49a4edfd,
- 0xd96f4251, 0xefc60658, 0x3b49accf, 0x307a8c18, 0x1e305995, 0x9abf249f,
- 0xf11428b1, 0x871cace0, 0x4f543df2, 0x67afeb72, 0x1a87041e, 0xe245b9e9,
- 0xe7f774f4, 0xd92db4f1, 0xb2dcefdc, 0x7f5a63b7, 0x58cbe7e8, 0xdda52f8e,
- 0x6a06b197, 0x38e828f7, 0xd8cb5f7c, 0x6e7e40e4, 0xc977c091, 0x7a8b2096,
- 0x8dab2a7d, 0x0d5d94d0, 0x7af51609, 0x2c28f640, 0x4c146caa, 0x7e2ba721,
- 0x72d0d653, 0x768ac430, 0xca017381, 0xbfc1fb49, 0x3a250f86, 0xff5072f8,
- 0xf9c7183d, 0x02b6e113, 0x9f743b3c, 0xffd355cd, 0x80bd28d1, 0xffa7af9b,
- 0x2d765c30, 0x1e87975c, 0xe1c29d8b, 0xd5c239fa, 0x8b1d3de6, 0x8cb805f4,
- 0xe476b86a, 0x3f9ff8f2, 0xa1fc9e9e, 0x88f564f0, 0x87df35a7, 0xc0c61da7,
- 0x74126cf0, 0x6e80f97b, 0xfac027b2, 0xcfc849b4, 0x1aef0c3f, 0x6b6dfc3f,
- 0x15618d9e, 0xe1137780, 0x9635be2f, 0x7f021672, 0xe04e22b5, 0xc6fa12ce,
- 0xfd03ba06, 0x7a468fba, 0xead40f50, 0x2c54d459, 0x96d814e7, 0x46af3cc0,
- 0x5da0fb38, 0xfe21eae4, 0x7f8091f2, 0x7014a247, 0xef881ffe, 0xf5e48f7b,
- 0x89ff75c1, 0xf28626e3, 0x09ebe0af, 0x1339ad4b, 0xe6fa37fb, 0xf59cb0db,
- 0x1a1ad9b9, 0xef1d7fa0, 0xf27e57ff, 0x3caff4a1, 0xc81a8ddf, 0x01d247e3,
- 0xfb209419, 0x9ac7cdd5, 0x7f9cc3c7, 0x9d27a595, 0x79e30ffa, 0x79fe36b9,
- 0x762c7bd9, 0x778be71a, 0x4b97df51, 0x876fc367, 0xbdf24bb2, 0x97f31433,
- 0xd7cd2746, 0x6d8991f5, 0xbce7600c, 0x9942f821, 0x057f329f, 0x151fb0ee,
- 0xee0091f4, 0x5a2613b0, 0xf5103e0c, 0x97a07595, 0x5e71a3b0, 0xacdc0eb4,
- 0x6ca071e7, 0x57f7d13d, 0x1c50c6a3, 0x27c88768, 0x291b46fa, 0x870fe95e,
- 0xff8f9a21, 0x9bf7b5c4, 0x8d3f62fb, 0x33e78a06, 0x4cfc4b7d, 0xdbd717e0,
- 0x9427877a, 0x8ef266f8, 0x4763a450, 0x753c0b78, 0xa76a06d1, 0x7287bd43,
- 0x8c9e4d71, 0xc8fdae7a, 0xc55916e7, 0xccb472e7, 0xb9ac6be3, 0xbff42c79,
- 0x30599336, 0xd62a1cbe, 0xad23d0df, 0xe87f0845, 0x249b9fa8, 0x4af6fc55,
- 0xadda8994, 0x6d62fa35, 0x09ab9fd0, 0xf78a051c, 0xb1b118b7, 0x85970782,
- 0xeb3ca1e3, 0xe866e800, 0x4760d1a7, 0x2b68e578, 0x7700a7d7, 0x1e0fbc3d,
- 0x1f25b9f4, 0x78c167bf, 0x87dabb7d, 0x833d3859, 0x439e61b3, 0xb3de5f91,
- 0x97b3c014, 0xdf081cc4, 0x3f5cd183, 0xc455702b, 0xfc02fd71, 0xf114321e,
- 0x7ca3ac9a, 0x66fae3ea, 0x96e3dfc2, 0x8c25967e, 0x79c76ef0, 0x299b46f9,
- 0xed1d56ee, 0xf9c6898c, 0x1e1cd818, 0x8c766cf7, 0x32587c27, 0x07002356,
- 0xf0bd9106, 0xc38bc133, 0xb21cf358, 0x168cb20b, 0xf594475c, 0x8ede8bf9,
- 0xcd37685e, 0xd076e68d, 0xd742b7f9, 0xc0abbae0, 0x2c02b677, 0xb957633a,
- 0x8498e6d0, 0x9ccf9978, 0xe78e502b, 0x551e0157, 0xc0de7efc, 0x16bc2dfb,
- 0xaa51bccc, 0x36eea376, 0x6bc2bb62, 0x760bcce1, 0x5e20f9f7, 0x5f187cef,
- 0xf18ac6cf, 0x33fc156f, 0xea07fa33, 0x7c9f9b31, 0x8bf3f86d, 0x8d8f5c79,
- 0x4995bc45, 0x7bb4462d, 0xabf98ed7, 0xb3e9ed11, 0x4de61615, 0x4679beff,
- 0x9c6aaf31, 0xccd77ace, 0x3ca51f34, 0x5b24f917, 0xc250df3d, 0xf88ad9c3,
- 0x4931e0eb, 0xfeaec783, 0xd8f06afb, 0x1a74ffbd, 0xc0c56cff, 0xa43ff4eb,
- 0x1aadfe87, 0xedfabbf8, 0xedb6e347, 0x04297bcb, 0x779f7bf8, 0x31bb73e9,
- 0x64c7bb1e, 0x373ca131, 0x3f22e6d4, 0xbc0edd5e, 0xd0f4fc04, 0xff28af9e,
- 0xa326d0f8, 0x3768c70d, 0x02dae6f8, 0xcc7eefe8, 0xea8dd6e2, 0xa746167a,
- 0xdffd9d11, 0x0b1ef59b, 0x03cd95c6, 0x375c16f5, 0xb3d9accc, 0x4cd7f894,
- 0x3f8944fa, 0x8b4efd28, 0xccfa3592, 0x5fd9f425, 0x9047cef5, 0x5f3aedde,
- 0x89da1e7d, 0xb70f3f03, 0x41117f92, 0x3f12ba76, 0x892383d0, 0x3989ad76,
- 0xde4de618, 0xa3ba758e, 0x82dfbfa1, 0x411c62b8, 0xc4e3561e, 0x2293fb78,
- 0x5064ffee, 0xa54dbc73, 0xeb45d697, 0xb09d987f, 0xb35f8fd2, 0xcbd17c3f,
- 0xc47583d7, 0x2bf372af, 0xb58bbf08, 0xc55c7918, 0x5e67f64a, 0x94e3c1d6,
- 0xacfc520f, 0x05fbfe95, 0xbfd02392, 0xe11de252, 0x9ae2ace8, 0xd68c36bd,
- 0x5e10fceb, 0x28b7ffce, 0x8a819fca, 0x6ac43d26, 0x162f9e65, 0x310e9671,
- 0xdaf37687, 0xda1ff414, 0xa3ab1e45, 0x46e83f71, 0x4fecae78, 0xf37fcf74,
- 0x9f6869d1, 0x79e33e83, 0x5a30a6ab, 0x624df227, 0x9106279c, 0x9123b17f,
- 0x7ab57fdb, 0xcaa6786f, 0x77bc7c1e, 0x685f736e, 0x7f656977, 0x5dcbda1d,
- 0x0efbcdfa, 0x39dae7f6, 0x574df888, 0x39e9e83f, 0xd7489718, 0xdcebb0d9,
- 0x31eaaffa, 0x16b650de, 0xef1801ec, 0xa469e812, 0xc4feae93, 0x705f5c70,
- 0xcb3f5c6c, 0x9fc893ea, 0xd1f10fcc, 0x60b293fe, 0xea05ba5b, 0x4d8fd7e5,
- 0xf33fbe47, 0x5c14a0e4, 0x58c74e0f, 0xdc4f3053, 0x192024fe, 0x69ba79e6,
- 0x6abf7f00, 0x17d470e4, 0x9c436b61, 0xadfc009e, 0x95fcf7e8, 0x14767226,
- 0xcc48ef3a, 0x7c406b68, 0x7e93320c, 0xf6450507, 0xdf21fe53, 0x17786b0c,
- 0x473f159e, 0xa15ac7c1, 0x3ffe954f, 0x79517a16, 0xd299fac2, 0x31ef7082,
- 0x1ccffd11, 0xc38d7bd1, 0xf1b21ed1, 0xd08556f1, 0x0730f978, 0x29cbc80b,
- 0x8e9d8eb1, 0xbc470eb4, 0x2832ebe7, 0xe443ba0f, 0x7c5956e5, 0xe41eb8e1,
- 0x194ad9eb, 0xbe62afea, 0xf8d508f0, 0xd7b28df9, 0xfbddf448, 0x4d5ff90e,
- 0xabe90c61, 0xfc8c337b, 0xa69bd773, 0x018f684d, 0x6821ddfe, 0x91371e17,
- 0xc9afb2df, 0xfb617644, 0xd7f21089, 0x42c3f1fc, 0x3f48297d, 0x44499bd7,
- 0xdf64f6df, 0x0c8edcf3, 0x680f9862, 0x891cea3f, 0xd1694274, 0x9ec3e3c5,
- 0xd5cd7680, 0xda2f20a6, 0x60f4f035, 0x6acdd07c, 0x9efde9e2, 0x347e8610,
- 0xa8643d3c, 0xe0f17549, 0x1082a0b3, 0xfda99bed, 0x01ce2943, 0x4a1f1fa8,
- 0xb143fe83, 0xbbd52b7d, 0x9379d7da, 0x1221c785, 0xd48978c5, 0x5fb7326f,
- 0x8d39f499, 0xef89fd03, 0x65ddf4cd, 0x79a48e72, 0x36c61c7c, 0x61679806,
- 0xa0bcb6a5, 0xf62e5b5a, 0x5b25cb68, 0x745f65b4, 0x814fd114, 0x7f73e15b,
- 0x70c4a4bc, 0x87c142bb, 0xd2769f3f, 0x61f03af3, 0xcbf1013c, 0x571d391a,
- 0x929aba0f, 0x0f2de387, 0x9753e4d6, 0x3e279d34, 0x9fd8376c, 0x77c075c1,
- 0x9136c0d4, 0xd50360fe, 0xf8ffb6fe, 0xe7adf3dd, 0xbcf5be45, 0x26dadf26,
- 0x160c2ef4, 0x5084f18e, 0xe11c359b, 0xad4ba1d8, 0x3d5f22f5, 0xbe7c4419,
- 0x21cbf716, 0x401baddf, 0x054452f0, 0xf0b3cfc6, 0xfd08cff1, 0x54c5e677,
- 0x642d33ca, 0x4b4fa4b5, 0x44bef399, 0x5887e78c, 0x57ff9073, 0xcdfb02d9,
- 0x27baf8fe, 0x34e3d386, 0x7d8ac6b3, 0x6fcc564d, 0x80bfe114, 0x74fd4504,
- 0xdfbe20f6, 0xd175f48f, 0xd481137a, 0xd8ccf7c9, 0xf3ff9655, 0x0d0077cb,
- 0x3655fe11, 0x67ae3877, 0xde7c2c17, 0x91593f60, 0x9f3245be, 0x8875fa07,
- 0x2f120bc7, 0xd942fa2b, 0xdf00b12f, 0x989e7ccb, 0x518f2fa7, 0xc7ae38fc,
- 0xf75e925c, 0xd693e830, 0xf2386b08, 0xb4aaeb53, 0xb79825c8, 0x66c6b088,
- 0x3aecf0aa, 0xd026bcc0, 0x0946d65f, 0xf0ddbf63, 0xf39223b5, 0x085d6fa3,
- 0x8eaf2bad, 0xf6ab996b, 0x8635ff13, 0xc58f91db, 0x16a6ff70, 0x40ec826d,
- 0x5a74e078, 0xcab4e820, 0xf931fce6, 0x16f57e4b, 0xf412f754, 0xb95f7bf3,
- 0x2f295ffb, 0x0fc55eb5, 0x8a4edeb0, 0x385de3e5, 0x374b7464, 0xfb4a5f91,
- 0x82eb7c9a, 0x70bf6ec8, 0xae3a4a68, 0x82eb4543, 0x155f5122, 0x8b135e1d,
- 0x8db8c8f6, 0x3ae2c58f, 0x6269b055, 0x9fe2533a, 0x482a3e2a, 0x3da3a7b1,
- 0xb6567be4, 0xd5453f60, 0x4ab5c132, 0x167e695f, 0x36ab9fde, 0x24549d90,
- 0xdbd73ae0, 0x2f788e19, 0x11bd33d2, 0xef4e7ef0, 0xf03b270c, 0x2ffc9959,
- 0xbd40f9ff, 0x00ccfa63, 0xfa0b3278, 0x00b48be2, 0x47547bfc, 0x66082a74,
- 0x36e75724, 0xb9edfcf2, 0x587de764, 0x157f056e, 0xaaad77f7, 0x0eb70e2c,
- 0x73f78eed, 0xddf12766, 0x051f3102, 0x28e3feaf, 0xbc476d78, 0xe871fda2,
- 0x2768c9b9, 0x91929eb8, 0xc6ded933, 0x8e47e42b, 0x72789a6b, 0x075fbe2c,
- 0xd7158076, 0xdcefbec7, 0x4ad4eb83, 0x909da199, 0xcb1694d7, 0x57d76a86,
- 0xdef22fb4, 0xa3ae159e, 0x90d31df7, 0x6d5b4e9f, 0xfb2a99b1, 0xcfc11dee,
- 0x5fc974fe, 0xec70b7f7, 0x818d68af, 0xdff057e0, 0xfd93630e, 0x41e21953,
- 0xedef6f3e, 0x7a157ea3, 0x2116fd28, 0x81fe15be, 0x2c63577a, 0x7c795f82,
- 0x99d535b1, 0x0fc00b63, 0xe3037ff3, 0x61d57f62, 0xdcbfcc76, 0xbccab8e8,
- 0xc8aae93b, 0xafd399ad, 0x8a54f9f5, 0xea8eeadf, 0xe9e99369, 0x50535bca,
- 0xfd61f2de, 0x5f3a7f46, 0xfe449df2, 0xe315b285, 0x4aebf9d5, 0xf2f1c3ee,
- 0xf874984f, 0xadcf75bd, 0x3f2e09c3, 0x529e01fa, 0x7b75f102, 0xa6c52faa,
- 0xfbac1fc2, 0x7ccacf24, 0x1c137054, 0xe4307fe0, 0xa054f6ff, 0xbfee4a9b,
- 0xf50f7210, 0x63e2462d, 0x5fc470fb, 0x7e2d7ce7, 0xcdf8b5f3, 0x3e2318f7,
- 0xcd273666, 0x9323e0a7, 0xfc17df0e, 0x28e9a7fa, 0xc7abad9f, 0x235abcd3,
- 0x8e51c3ed, 0xffa0535a, 0x59e7dda1, 0xe7986bf0, 0x6799efd0, 0xabd11065,
- 0xfa4679c7, 0x33df679e, 0xed58c8cf, 0xadeacf3c, 0x5c5fa8e1, 0xfb8664bb,
- 0x8ec95cc3, 0xd97963b5, 0x768614b2, 0x05d0f589, 0xd5e912fa, 0xb8a068d6,
- 0x30ef22a1, 0x83f20dde, 0x35a1f88e, 0x28f4fad7, 0x0b656f5a, 0x575bd9c6,
- 0x51e7788f, 0x95aeb728, 0xb407682d, 0x81fc72e6, 0x0f50ebdc, 0xa638a6b4,
- 0xc18f7951, 0x39fa14b2, 0x0fb7f953, 0x0c0bf225, 0x73f34656, 0xbe3b45ac,
- 0xfd45e01d, 0xcd997805, 0xcd034aed, 0xa7cad57f, 0x7777e256, 0xfe964df5,
- 0xa7eb40d6, 0x6b45cf16, 0x321c8d64, 0x73c695bd, 0x8ac93afd, 0x0cf050f3,
- 0xc67d349a, 0x607c2eb0, 0x2eb0d679, 0xfd94b8bc, 0xeb3d626c, 0x9f885bd4,
- 0xc05d7cbe, 0xafa8ea7d, 0xa77d3f70, 0x57affb3c, 0xdfc67a7e, 0xd04db89e,
- 0x16ef5fd3, 0x7ca9cbab, 0x5cbaa15f, 0x4a37a7e2, 0xbac3befd, 0xfc502d3b,
- 0x78e77774, 0x02796f1c, 0xaf5c4a6f, 0xd68949fd, 0xd5bd3cd5, 0xabc17e88,
- 0x155c78e3, 0x8ff301fc, 0x683b0e49, 0xb67a793e, 0xef8994dc, 0x994f546d,
- 0xdcb7f427, 0x8ef46b04, 0xa077ae60, 0xaaa364de, 0x0557e8ac, 0xfe44479e,
- 0xc3fe7942, 0xad64f3fe, 0xb38aacff, 0x201b123f, 0xf7299ece, 0xc608ed7d,
- 0x64c976db, 0xf30eba37, 0x7d7d8575, 0xf06de9e5, 0x1a4f7cbe, 0xe6555bed,
- 0xf6c78fef, 0x7de12b86, 0x21db7de1, 0xcbc63063, 0x72a31af2, 0xf48a2fc9,
- 0xaffbc405, 0xfe94fcc4, 0xe12df4da, 0x2df6d5d3, 0xa19f096b, 0x86bc8fe2,
- 0x164fb42b, 0x5596e7f0, 0x534cfb7a, 0x79fa2e4c, 0xcc4a7ff9, 0x55f3c1d5,
- 0x06b5cf41, 0x506b0beb, 0xc899764e, 0x3c3b6f6f, 0xdbed8747, 0xe789170e,
- 0x9e7a7643, 0xe382933d, 0x7f38eb87, 0x14bde32b, 0x7ca5edcb, 0x7fe7a9dd,
- 0x8dfefa84, 0xaa65d4b8, 0x2ebe69f8, 0x6dc4fc93, 0x845cdf06, 0x95f1ec1b,
- 0xe943efb8, 0x2b58d5e7, 0xebb6d1c1, 0x0fa8f3fc, 0xce4dacce, 0xb6d23544,
- 0xcc70c06b, 0x189db7fb, 0x3fe78e91, 0xb04c9eda, 0x66d81ea1, 0xfc443eb0,
- 0x86cc2ab6, 0x87f4ae72, 0xac7e60e3, 0x1cc8d76d, 0x4edbb3f4, 0x4ca17870,
- 0x73d4377e, 0xa50efee3, 0xf59d70df, 0x8c8fb857, 0x7940c9fd, 0xa4dfc5b4,
- 0x1abfa1c5, 0x5f9c0c6e, 0xbb5dfb40, 0xc1296a7f, 0xf1e3ecad, 0x7d95efb7,
- 0xd17efe3d, 0xf80bd07c, 0x2b7fdfde, 0x702b9562, 0x1fbf917f, 0xdc7e40c7,
- 0xfa62beca, 0xbdf5a5ab, 0x2677cb64, 0x0fb13d4d, 0xbe031a88, 0x571e40f2,
- 0xc3c65c53, 0xe52b5fe3, 0x5f42f980, 0x3ec7cf2c, 0xdcedf213, 0x4f5d1516,
- 0x1e3e98eb, 0xc8da7af0, 0x7f99f1cc, 0xaf973fbf, 0xbacc57de, 0x73a777fb,
- 0x00b9953d, 0x32d5e9d7, 0xa1fd47ed, 0x7b7f9dfe, 0xf3e88480, 0x4effb099,
- 0x3e705cc3, 0x5ab3fb3d, 0x067c1578, 0xfe057d89, 0xfe22cdf5, 0x991bf03e,
- 0x9bee51d9, 0xcfe41e0c, 0x3f9f8d90, 0x67f20f7d, 0x6a92c1a3, 0xed017ca5,
- 0x64bb6573, 0xb75c7f4f, 0x2f84cf1a, 0xd76575c4, 0xd34e3a08, 0x92ecbfe9,
- 0xd6dfee29, 0xf3162570, 0xe50fd003, 0x4f4d5d3b, 0x7b7f90d9, 0x4e312382,
- 0xeffa61fe, 0xa1f8bf66, 0x6db67bc8, 0xfa8e973c, 0x6260f41d, 0xfa67ca1c,
- 0xff9e46d7, 0x7da1c96c, 0x273f1bbf, 0x73ddbcbb, 0x7349ec95, 0x940f6ca3,
- 0x671a1c57, 0x4df061fc, 0xf007c2d0, 0x1478450c, 0x3eadcb38, 0xbd737f3a,
- 0x5d84ffbc, 0x1cf14b85, 0xd1f9e608, 0x94682fbe, 0x582add69, 0x40ac7b2f,
- 0x7e030997, 0xed082fb1, 0x8a24a7d1, 0x6f924e0b, 0xd40e70fe, 0x4ca4f05f,
- 0x1f1bbde5, 0x7480d0fa, 0xbca06f5d, 0x99a682e1, 0xfc57da46, 0x122cc494,
- 0x37d9ab8d, 0x12972c50, 0x09f6dd5c, 0x680fedf8, 0x7d0b76cb, 0xe37ef7e0,
- 0xa2fb198a, 0x9267a9f1, 0x017efbb5, 0xcb103bfc, 0xdfe047cf, 0x126bfe96,
- 0x416d0e91, 0x5ca3358c, 0x5fc85bea, 0x3e7e5e61, 0xd9d76db3, 0xeb97a414,
- 0x5e292f8d, 0xb01c93d9, 0xf33fbe46, 0xfc8938ce, 0x5cdf81d2, 0x5008e699,
- 0x6fc8b67f, 0x13b8316f, 0xb7dd3ed1, 0xe38f2af1, 0xae71e2ec, 0xee67fb1e,
- 0xf26f1e20, 0x2c1c5106, 0x0532d6ab, 0x3cec01e5, 0x36b93fcc, 0x09b198ad,
- 0x0dbb41ca, 0xabab4456, 0x05c9287f, 0xaaa141ca, 0xb61e455f, 0xb2947c88,
- 0xd8b661bf, 0x6feca397, 0xf83bf650, 0x77eca1c3, 0x3bf62d98, 0x78eb1dbc,
- 0xc19e0e28, 0xd9385f3a, 0x5ffb7eb1, 0xe2cfda7a, 0x3fd1efbf, 0x4f9fee6e,
- 0xcbecad5b, 0x47146088, 0x8dfac237, 0xcd86c395, 0xabf51778, 0xfe4c98e1,
- 0xef23ded0, 0xf1f5aac5, 0x38737d0a, 0xd72f31c6, 0xd1fe4419, 0xc316f947,
- 0xa98dcf91, 0x862597a4, 0xca0bae76, 0xb375def8, 0x338eaede, 0xe7c71d3f,
- 0x9d2e22bb, 0xfb7ab7af, 0xb7afcc21, 0x688cf259, 0x148e1b8f, 0x367e464c,
- 0xf919e7c4, 0x54e6b9f8, 0x9e844ba4, 0xa3457ff8, 0x05b36e32, 0x7bf257fb,
- 0x2cc71161, 0x598577c8, 0xbf3fbeb3, 0x4a83f227, 0xdf33af7e, 0x7be33f17,
- 0xe33b7bf3, 0x8bf71d38, 0xff71bbe7, 0x3b7bf2cf, 0x5265fe91, 0x30f1a4cb,
- 0x8ef88ac4, 0x6ebdf9c0, 0xfcb1bcf3, 0x567147de, 0x9ceb7f9e, 0xbdf90f6f,
- 0x58dffd6e, 0xff7baf7e, 0xbaf7e43d, 0xf9837ff5, 0x797ecebd, 0x50f96f7e,
- 0x5b3fed1d, 0xe3c4dc7e, 0xffbe66e4, 0x65e424c3, 0x668277b9, 0x74f284ff,
- 0x184909b3, 0x275e5f27, 0xbcfe464f, 0xa0b3c96c, 0x78221a7c, 0xb064c83c,
- 0xd43f464f, 0x85191114, 0x711ff97c, 0xabaf3469, 0x3f888b11, 0xc87982af,
- 0x722d89cf, 0xef797960, 0xca649902, 0xd6177f2f, 0xd57cf324, 0x7758b368,
- 0x87e4b7df, 0xf3fbfe52, 0x3d1e5538, 0xed00fb2c, 0xce0d648b, 0x8fbf283e,
- 0x127f405b, 0x7c50b79f, 0x7f3928c6, 0x76217187, 0xbb639f82, 0x601ce41a,
- 0x3ea5c951, 0x2eec28de, 0x33ea126f, 0xa7a2ab37, 0xe10ae1ab, 0x2a478959,
- 0x47cc5ddf, 0xa5794778, 0x7a09b8c3, 0x706f7d2b, 0xb573a00e, 0xbb4e8e02,
- 0x6ea18fe0, 0x6a69a73c, 0x8ff286fa, 0x34df7aed, 0x36d4eb8c, 0xfc6a21ca,
- 0xb973c526, 0x9cfe4dc8, 0xd8e556f2, 0x57e617ae, 0x7ca0064b, 0xc37c9b96,
- 0x7b7dee11, 0xf51c36fe, 0x92a6d5ca, 0x0b7ef83e, 0xdc75a7d4, 0xe7572be8,
- 0xaaf3fd5d, 0xf381f1d1, 0x969a5bad, 0xdb1c2225, 0xf6005e30, 0x3fc3f955,
- 0x663a73a7, 0xea0dff66, 0x837a060f, 0x99868afc, 0x93b438f2, 0x01db003e,
- 0xf8bb59ca, 0xcc959bfa, 0x2d37983c, 0x0e60fa6f, 0xdb3cabd2, 0x32974168,
- 0x6de78338, 0x16cdb383, 0x45a6ff5c, 0xe2303e71, 0xed869b3a, 0xdd214627,
- 0x3031c41e, 0x7b73b9cf, 0xb7f01bbd, 0x854f0ff0, 0x27dfc033, 0xafda4afa,
- 0xb1f9ba51, 0x2f3c3b70, 0xc714dde8, 0x0723c4fc, 0x1794ffdc, 0xf6b7f8af,
- 0xfe754950, 0x3fdfd3e0, 0x6ef88d31, 0x7982c1b3, 0x1316d77f, 0xaf2b9f9d,
- 0x33f3a62b, 0xcbc53e50, 0xfe867f8f, 0xbb41ab95, 0xe97c2f4e, 0xad2b58a9,
- 0xb124ee0b, 0x941f11ee, 0x849d9cd7, 0xc1f857f8, 0x8f8e1dbf, 0xb55de5fb,
- 0xaf633cf2, 0x7b15dfee, 0x5dff5943, 0xfb884f75, 0x3fc85a01, 0x845faff0,
- 0xb19a3232, 0xfddaf199, 0x983e0ad1, 0xa3f48627, 0xf0c373bc, 0x54be5053,
- 0x92e16ff3, 0xbf8a4f0a, 0xff9b51d3, 0x3dac37bb, 0xb06defaf, 0x7574b02e,
- 0xb3b50f3b, 0x177e0836, 0xf06a5f7c, 0x955ca386, 0xdcd8346e, 0xfb74baf0,
- 0x973e2f0b, 0xc3667245, 0xfb64ac75, 0x818e1f5b, 0x430ec972, 0x8d3e54f4,
- 0xde754950, 0x61ff05cd, 0xc3a1405e, 0x32ded7c2, 0xf7f1875a, 0xa2ec88bf,
- 0xbd8ec947, 0xfc5e7446, 0x76be31f1, 0xbbf291af, 0x3da974fe, 0xef2b7245,
- 0xbbec86fc, 0x2c48f64f, 0x3e00352e, 0xee15be37, 0x3a227814, 0xd2753a0a,
- 0x92beafcd, 0xe4e8577f, 0xde3b3dff, 0xfd85f242, 0x3f023ca1, 0xc606f2bf,
- 0xd9323ffb, 0xaf45fe70, 0xf38e103c, 0xc45faf38, 0x63c37af9, 0xb71876b1,
- 0xb58ee0c8, 0x2fbf93d0, 0xc467fe7a, 0xfe8e0b6f, 0xcc7fdb8c, 0xfca3a09e,
- 0x7bf29ba5, 0xd0efeb85, 0x0da2ffe8, 0x85ffae3c, 0x11de4d9e, 0x0b8e2e40,
- 0x937e72bd, 0xe7d9f289, 0xf6860f31, 0xdf327bcb, 0xa7eec7b7, 0xdf629078,
- 0xe54d2780, 0xfe1e842f, 0x894ebc43, 0xfc359b7f, 0x3378f35a, 0x64d3e7d2,
- 0x25ea1c7b, 0x05bbd317, 0xa0efa43e, 0xc4e8f95f, 0x1e1f4e38, 0x6076a33f,
- 0xf7c78e8f, 0x40d9bf58, 0x3b5550f1, 0x8f966e71, 0x1f18a0ff, 0x7cc60ee0,
- 0x5658f9ca, 0xd44fc814, 0xe7c67427, 0x29e7359b, 0xcb9be4bb, 0x2e2acd7b,
- 0x7bbc8adf, 0xefc64fa6, 0xf2e31f9f, 0x3292ed83, 0x1c6f2e09, 0x4b3bdf7d,
- 0x27cfce1a, 0x75c9037b, 0xb5c8418d, 0x27c2bbf6, 0xee9eb700, 0x05f85021,
- 0xfc248ffb, 0xbad2d517, 0x1dd8d26d, 0xbc2f1c2e, 0xdc8a7f7b, 0xfff2102e,
- 0x7f38bc7e, 0xad9fe425, 0xf3a1b98f, 0xcf06a545, 0xbca1cf8b, 0xbef7e09e,
- 0x90376e94, 0xdb717e5d, 0x06ef0ffe, 0xab58b939, 0x7f56a9c8, 0xd169cbfa,
- 0x7f116fab, 0xc5e9cbfa, 0x0362b7da, 0xb78ee9ca, 0x2eee0ec8, 0xfab9ffa7,
- 0xdfdfc153, 0xe8a7f0fc, 0xe8f09ec3, 0xe3ab0faf, 0x21f501ad, 0x9f531dfc,
- 0xa5f0537b, 0x6fc29df0, 0xeb2e5f0b, 0x93a77a83, 0xebbe152f, 0xef854be4,
- 0xd73bedba, 0xfbffcfe0, 0xe00df85b, 0x60faec72, 0xb3d01252, 0xc9fb91b4,
- 0x9620eed0, 0x5a764f01, 0x41e558c6, 0x55db6f3c, 0x6b95f8f6, 0xfddbeafd,
- 0xfabf0eca, 0x22f2bf4e, 0x821efabf, 0x3f61b4ab, 0xbcc96fdf, 0xa586fa9a,
- 0xdd161dcc, 0xf31e0e75, 0xcfd02b58, 0xf4f3c6df, 0xb8f0258f, 0xb8c62fa9,
- 0x891ff682, 0xe13e2a7d, 0xb43bb467, 0x354e54fb, 0x5b7fa4ca, 0xf8f3813c,
- 0x3c9209e0, 0x3fb0f4b4, 0x4d3b895e, 0x1e534394, 0x2a3a3806, 0x60a0fc79,
- 0x94e19dc9, 0xbb4c69cf, 0x850ae31d, 0x2c31f987, 0x73143f65, 0xaa09f5db,
- 0x98170efd, 0x319be9fb, 0x4258d64f, 0x35828bf1, 0x0fcd7a5a, 0x0be2907d,
- 0xf7b4abf3, 0xad7c2900, 0xd68b0bc4, 0xc42fbf6b, 0x1ee8847b, 0x47da4a85,
- 0xfb46b0b4, 0x0e7c89dd, 0x41273c7c, 0x2c1909d8, 0xf9bde443, 0x57a11239,
- 0x6f43ca27, 0x21cbfca7, 0x1da5f299, 0xbde1328d, 0xfb449b63, 0x863b9869,
- 0xf99ca5e4, 0xf8299f48, 0x60f284b9, 0x5cdf59ec, 0x73dffd7a, 0xa52a851e,
- 0xff0f1ff5, 0xd52f3c2d, 0x8ddf489f, 0x4e7f9de5, 0xaf7598f9, 0x104f7e3f,
- 0xdf6a1fed, 0x35f74613, 0x9dbd37b5, 0x85e528f2, 0x07ba364c, 0x9497cf61,
- 0x6a5f6b7f, 0xd57d422a, 0xcafdcc9e, 0x0e5f4d65, 0x39657ae7, 0xc098df3f,
- 0x34744dcf, 0x94f28dfe, 0xca268d1d, 0x84f6b933, 0x7ae11f90, 0x9cfc8823,
- 0x292fa6f6, 0x9acffcbe, 0x3788b94f, 0x3cf187b7, 0xbfb8bb4f, 0xf47bb5c4,
- 0x2d87980b, 0x446bdbab, 0x9bfc65bf, 0xdf5d90df, 0x67b72afe, 0x1eded0da,
- 0x5bae7883, 0x7dc44e33, 0x4d0ecca8, 0x0db77b45, 0xb1912385, 0x9d5dcfa1,
- 0x081a1eea, 0x5e50df4f, 0xf3f146f5, 0xfc18ffd2, 0xb9dfb448, 0x63cc31b4,
- 0x5fde7096, 0xf518fc9d, 0xd79e1ec1, 0xb17be657, 0x1fd90976, 0xc1f79bd7,
- 0xfddfee04, 0xe4b799ef, 0x9f7991bd, 0xef4e6ffd, 0x98d43c62, 0xba2e5ddd,
- 0xcf1379f3, 0xb30f6d17, 0xc837bc11, 0xffc486ef, 0x157f7465, 0xfd7e1ee8,
- 0x6ffbf779, 0xe99eef3e, 0xa0ae787e, 0xf3e305bb, 0x21bf37ae, 0x3d5efef8,
- 0xe87fe137, 0xfd3b15fc, 0x6fd7c67d, 0x91c3a257, 0xee9efb88, 0x5f02bc38,
- 0x274e74b9, 0xcd12c3c5, 0x4d9fee74, 0x8e87e28d, 0x33618ef5, 0x57877586,
- 0x25fe1bf1, 0x31273ed1, 0x07feaba6, 0xa619efb3, 0x7d57779e, 0x58d1be3e,
- 0x379d3f7b, 0xfca50b29, 0xc18f6e2c, 0x36cc2f76, 0xf713fe71, 0x990f1c3c,
- 0xa606307b, 0x738347f2, 0xe739c23e, 0xc0ac9fce, 0xca2fb4b2, 0x35e718ba,
- 0xdc4725af, 0xc710b08b, 0xfb3b352f, 0x72f9aa60, 0x2f4073b2, 0x511c47b4,
- 0x1ccb9e3c, 0xe1011cc3, 0x37ce6b77, 0x994bf62a, 0xea3aa1b0, 0xbe517ad2,
- 0x645ed5e4, 0xb8e9b57f, 0xe026d87f, 0xb767e0bd, 0x1a8e7917, 0x5c58ff31,
- 0xcea8d473, 0x7389963f, 0x3fe3fea9, 0x23f3c891, 0x87f6be9f, 0x8bf748ab,
- 0xa3a7d45f, 0x5d2256bd, 0xdd5d79a2, 0x98ae747a, 0xff9c0adf, 0x14be1d43,
- 0xb4abcc23, 0xc791af76, 0xf4fcc523, 0x9beff4be, 0x79ae9b5f, 0xaabb9d12,
- 0x8e7ce897, 0xeeacaed2, 0x93b424e8, 0xe8226a8b, 0xa7dc473e, 0xca9dcfc2,
- 0x7860fb7e, 0x8eb2493f, 0x4bf7dbf8, 0xd21bf689, 0xe9dfb41f, 0xbee0f08e,
- 0xcaee936a, 0x676899b1, 0x8ce7e30f, 0x438307d6, 0xbbc77e0f, 0xc41b5f02,
- 0xbf780779, 0x07c7df12, 0x4ff1f6f3, 0xfedf68eb, 0x9409b90b, 0x7bdd543f,
- 0x72075291, 0x36b26494, 0x49b8c0b4, 0x0f28bd15, 0xb9d13dbc, 0x5f71f105,
- 0x18e52e94, 0x421ce1c1, 0x8e6f80e7, 0x753f21ba, 0xf818b306, 0x9e7e527e,
- 0x4f85867d, 0xb5d850a5, 0xee9d9933, 0x3983b8e1, 0x6d7bdea9, 0xd7da3b46,
- 0x336e61ef, 0xa3f7ee93, 0x0f3177f7, 0x5e61ef3d, 0xac2fffaa, 0x5f0aca85,
- 0x17de3f02, 0x3cf1f9cd, 0x8e8160a6, 0x47dc226f, 0x3f278643, 0xfe9ef80c,
- 0x94fe80cc, 0x76e2ad2f, 0x9ee0f5f0, 0x574bfc2e, 0xf210f3a2, 0x2fe4c77b,
- 0x7e82af9e, 0xf12f6674, 0x91ee7283, 0x7c11884d, 0xdb72fdf1, 0x0f99d1dc,
- 0xe2bf450d, 0x5bd24156, 0x509fdced, 0x2edc0dce, 0xd9ef01e4, 0x343a0489,
- 0xa7bdf95b, 0x3dbd2acc, 0xc793ca02, 0xe59fb4c9, 0x20d6e08f, 0x4331fc7f,
- 0xd9a5f716, 0xd134fda9, 0x3371d4ef, 0x7a82f797, 0xc96ebe93, 0x9327f3c2,
- 0x8afd6b7b, 0x5c6f449f, 0x29cf011e, 0x7fefb4fd, 0x88f59aca, 0xb543a9d7,
- 0x2cb4cdfe, 0x38bdbd6d, 0x2a962466, 0x4b845ee9, 0x193fc289, 0xfdab06cc,
- 0x1d3e6513, 0xd118af53, 0xe493ec17, 0x597482bc, 0xb9d9db7c, 0xcf4ede74,
- 0x4d111ede, 0xbcd1cff7, 0xe6f02b5a, 0x55cec646, 0xa179e998, 0x20ecc2c2,
- 0xc4569ff7, 0x8552f3d3, 0x55b7de95, 0xf8e7a40c, 0x90dfc724, 0x9f95053e,
- 0x670fd1e9, 0xee34e955, 0x9acf8203, 0x9d1d5e75, 0xd124d85f, 0x82079a7e,
- 0x8ef1739a, 0xa73607ac, 0x61739c52, 0x0c41ed43, 0x1d78141f, 0xf39c9093,
- 0x883a2d0f, 0xc06bb2cf, 0x158023e9, 0x24a61c12, 0xa763eb94, 0x7ac6df67,
- 0xe37b1be6, 0xd05183a9, 0x1b0af9ff, 0xc549f5c1, 0xac5e7a28, 0xb3dc13b0,
- 0xa4961c92, 0x67d2a46c, 0x6db73fc4, 0x824fa53b, 0x12ad13fa, 0xb63f2bad,
- 0xe4078f33, 0xd7c0daab, 0xb304ea85, 0xdc74e50d, 0x1e1b19b0, 0x9df7a864,
- 0x1dc70889, 0xe2278a53, 0xcd46d338, 0xeeb47ba3, 0x7bf19afc, 0x58dc2695,
- 0xe9f988dc, 0x247bcbdd, 0x3acbcbe2, 0xff18edeb, 0xa649ff75, 0xde0740fc,
- 0xe3fe80d3, 0xe32f7e71, 0xe2d3d7e2, 0x362f3f50, 0x5fd0e358, 0x79f62ddf,
- 0xe97a045c, 0xc5eceb55, 0x9cce7fed, 0x25bfd2a7, 0xfabaecaf, 0xf2fbf411,
- 0xea1b48c9, 0xe2918bbd, 0x28b6467e, 0x9b48f504, 0x19623bc8, 0xd65015ef,
- 0x5833d45d, 0xebcc18be, 0x9492bce7, 0xe382728b, 0x7a5d8d59, 0x6795fd28,
- 0xed6a3efa, 0x6d4b6f1a, 0x41cf47e1, 0xe747b2f9, 0x723ac036, 0x61b6d599,
- 0x135dd6dc, 0x066dfb4a, 0x87e0fa4a, 0x7c3d6f89, 0xd56488bf, 0xeb6c3c63,
- 0xd1121b2b, 0x392dd80e, 0xfa823ee6, 0xffaf037b, 0xe48fd3d2, 0x53e7c2ed,
- 0x823eaf65, 0xa08a4f78, 0x2b9ff376, 0x36fc8c1e, 0x5d5efd6c, 0xa9bfbc22,
- 0x7c52d4e6, 0xc2a240ce, 0x926d8cf7, 0x8cdd778c, 0x865d4ba8, 0x1fb898af,
- 0xfbc0b06e, 0xed9ff5d0, 0xf4107703, 0x08e2ed6b, 0x525757ca, 0x671bd7bb,
- 0xc10f7fbe, 0x7bc04ee1, 0x8cf3dd35, 0xb8f03edc, 0x5c9f2237, 0x51b40e76,
- 0x7ee1cd7e, 0xd973e916, 0xf5c36b19, 0x0ee75ea0, 0x4ff5831f, 0x76087bf2,
- 0xc70d1cd6, 0xeabd11fd, 0xed082c0c, 0xad1f0c95, 0x56c9654b, 0x259659bc,
- 0x64eb7f3f, 0xd7927946, 0xa53f5237, 0x99e61b66, 0x42bf5e8b, 0x13f61cf1,
- 0xfc8feb66, 0x4fcbc751, 0xfd13b04c, 0xc17e368a, 0x2a0ecdcb, 0x2a77643b,
- 0x0f945fdd, 0xfbf40c76, 0x5877588c, 0x47d270cb, 0x2ed672c4, 0x9f013f7c,
- 0x3abdf02d, 0xfb809dd5, 0x0af594c3, 0x219f99d6, 0x839ba37f, 0xef739bed,
- 0xf775a149, 0xa519d706, 0xfc8c679f, 0x46f5bd7e, 0xb66e1ebe, 0xf42778f0,
- 0x4fe514bf, 0x64931759, 0xae1d5869, 0x6c98cf73, 0x3e37accb, 0xfee2ddce,
- 0x2af813ae, 0x430d6c41, 0xf8ffba42, 0xe9ffc636, 0xfbf23dfe, 0x15675799,
- 0xf941ecf7, 0x4fc3a4e9, 0xe619bf2e, 0xe003f82d, 0x83013820, 0xf2a7f50c,
- 0xe38b2c3e, 0xb669d233, 0x2e2b7e61, 0x33dd116a, 0xd307f0a1, 0xdda0477b,
- 0x995bfab0, 0xffb94bce, 0x7f714a1a, 0x4ddf787f, 0x7af471e2, 0x639e07c0,
- 0x7bf07772, 0x5ac31a9f, 0xf403fe5e, 0x9bdc58df, 0x0dbbc6e2, 0xf756fefc,
- 0xdc5df174, 0x5778dd27, 0xa27dc92c, 0x7601eb89, 0xd38d304f, 0x7e6cf068,
- 0x8f4fbf1a, 0x85c7f6a7, 0xde671d9c, 0x955f707b, 0x7ba467db, 0x1822ab39,
- 0xb55367dd, 0xfdc50064, 0xe07dbfea, 0xbda186df, 0x639f84b2, 0xacf0caab,
- 0x55ff7dc4, 0x70e34cbf, 0x1724de48, 0x260e2fb6, 0xdd355d3d, 0x4071809e,
- 0xba10b4e7, 0xfba7ba57, 0x28323f5e, 0x09ec89e7, 0x0ae78f88, 0xfdf533fa,
- 0xca4e7f41, 0x57748c3d, 0x3a73d1f2, 0x8ecc22f3, 0x21de5bf7, 0x6e15770a,
- 0xbb7e420e, 0x14e828a3, 0x178f6bc6, 0xb8c30d2d, 0x7e4e1de3, 0x359b273f,
- 0x8f3eaed1, 0xfb24e7f9, 0x5657e461, 0xdeedd8a0, 0x1ed3c47c, 0xbdce999f,
- 0xa847f901, 0x7f8544ed, 0xbe77aafe, 0x8ddaed87, 0x92e35ee2, 0xb6cda6af,
- 0x6bf1faaa, 0xf27edfe7, 0x37bf330c, 0x7644cea9, 0x8ec27dc1, 0xb3bc9972,
- 0xad5a0ed1, 0xf607fe73, 0xe9f85aef, 0xa277b470, 0x17fbf067, 0x09be31db,
- 0x7a0a4f75, 0xff7c649d, 0x98517ba0, 0xb2f11bc8, 0x0f28d1f3, 0x9ec7a7bf,
- 0x07e58850, 0x1f70d886, 0x99e45390, 0x7c44b958, 0xf9c2d272, 0x146364e4,
- 0xe33e8fdf, 0x30e9d3da, 0xab8e938f, 0x7a848f6f, 0x79f81b27, 0xcc3cbf8e,
- 0x2f9619cf, 0x60d2913b, 0x7baf3eed, 0xd97bf297, 0x0bf85def, 0x93da6f3a,
- 0xaa5bddfc, 0xd21987dd, 0xce15fedb, 0xb5c67a33, 0x1287a849, 0x2d9f4a4b,
- 0xdbdabd44, 0x2fbe2df9, 0x2394b637, 0xff77ca3e, 0x7fda0a7b, 0xda5ebbed,
- 0xaf9e1071, 0xdeba9d19, 0xade97df8, 0x67618fa9, 0xd72f9ec2, 0xae403d03,
- 0x34edea9f, 0x717e06f6, 0x63a6f04d, 0xe6864bbb, 0xf6378849, 0x1bb31b8b,
- 0x5cdc6d3f, 0x115fa12f, 0x4f4e58dc, 0xe11c33d9, 0xc37928b8, 0xa71e1ef1,
- 0xc97e8fd8, 0x188f0de2, 0x72c7f78a, 0x1f3ff5fe, 0x8ac5a048, 0xaed0327d,
- 0xe71656a4, 0x27143c97, 0x025faff6, 0x0ddea9ef, 0xcbce57be, 0xac344495,
- 0x66f44b1d, 0xee166f5e, 0xf74feceb, 0xfd7e5d32, 0x5fb574a5, 0x0eecffe5,
- 0x9d3f9f2f, 0xa9bcc6e7, 0x7bf7df87, 0xe4068a09, 0x71266db3, 0x51f38f8e,
- 0xc104d6db, 0xda8f9c67, 0xa8f00eb6, 0x9cf3b6e5, 0x8736ada0, 0x6bdbedf6,
- 0x501ed073, 0x6b999fe4, 0x36677ee9, 0xda3876b0, 0xc23d8add, 0xf4e9b51c,
- 0x8e9b53de, 0x3c75ebf5, 0xbb8ca73f, 0x7e24e5f0, 0xeb9998df, 0x0f2f85c5,
- 0x94c6fba1, 0xcf37af7e, 0x4d46d501, 0x5b479079, 0xef9bd69e, 0xeffdf85b,
- 0xcbf1f73b, 0x93c61ec2, 0x40f79d85, 0xbd73de76, 0xf2f05255, 0xfa0e5260,
- 0xaaf28ca3, 0x0be07bbb, 0xbd21ae05, 0xf30b3fb9, 0xbbceb863, 0xbbfae23f,
- 0xf331c33e, 0x6fd72836, 0xb6fb2348, 0xe9f8e74d, 0x79e71c30, 0x3ebaafbe,
- 0x9cf947c2, 0xfdb967fa, 0x5de62e5b, 0x424ce11f, 0xc2a17a7d, 0xffee2f16,
- 0xe96c3b26, 0x98e11589, 0x61dfaff7, 0xd5f8c0c8, 0x63fb3527, 0xad3e2f91,
- 0x37ee9878, 0x75e3bc1c, 0x6e94a3ca, 0x1c7de07d, 0x8336d2f7, 0xd2acdd0d,
- 0x8b5c5ebb, 0x56e948f6, 0x5be716b9, 0xe53f75ba, 0xbed52fc7, 0x71fb8e15,
- 0x9144d42f, 0x53f08c1f, 0x1cf7fafe, 0x2ff8fe0f, 0xabc464f6, 0xc91591f7,
- 0x7f78b5ee, 0x5a2d90c9, 0x3c7d17bc, 0xedea10e9, 0x18cff50b, 0x1fbc56f5,
- 0xa6fdfb56, 0xeff96d06, 0xe4abaf3d, 0xd4e39091, 0xdcc85c74, 0xdda9f507,
- 0xb5645feb, 0x3f18edb3, 0x9727bce8, 0xdae8edcb, 0xbb379475, 0x6e6e78fe,
- 0xe9da853c, 0xa379ab9e, 0xe231b7f8, 0xe6b65efe, 0xdbc424e8, 0x5a2427bc,
- 0x36bde6ef, 0xcfea00e0, 0x9aee3b53, 0x93d9cf42, 0xe8f91f09, 0xd67ee085,
- 0x061bc946, 0x8e28cb65, 0x9e6ac2ef, 0xee5bca17, 0x8d69ee77, 0x2af8fedf,
- 0x0d05f7ed, 0xbcc2bf7b, 0x79f99176, 0x3f741f8a, 0xfba1e3c7, 0x605e177f,
- 0xac2dcfe4, 0x2814cef9, 0xcca851be, 0xda63fdc3, 0x264dc01f, 0xfff0fff0,
- 0x4daee346, 0xe1ea3d47, 0x651b5531, 0x731957c4, 0x2349643e, 0x021bc5bf,
- 0x8137cfe3, 0xeb4992dd, 0x4ae7cd21, 0x8f3a2f75, 0x5059ef0e, 0xda03de26,
- 0xe4eb839c, 0x1b30ba95, 0x9cd69fdf, 0x02d57683, 0x21f9d328, 0x0bce2956,
- 0xf1fee87b, 0xcd06d505, 0x1ec5e07d, 0x7255996d, 0xef14b0fb, 0xfa470ed3,
- 0x92bb50b7, 0xa57ada2d, 0x91e39f30, 0xfb51ffb8, 0x5b7cc5de, 0x2b7da45f,
- 0xefd498df, 0xb1547b15, 0x0e38958f, 0xe460b228, 0x7237bb97, 0x04b77a3d,
- 0x0c3b45f3, 0xafb234ed, 0x420e3b3c, 0x2878aab9, 0xdff54fd9, 0xca5bfdf2,
- 0x0caad4f9, 0x279e3a7b, 0x88375aab, 0xb25bbfe6, 0x7a863ea7, 0xd859ba60,
- 0xe1ee8c57, 0xa44e2aaf, 0x1c23fbf5, 0x2ced0132, 0xf729ef6e, 0xeea227f5,
- 0x18e371c2, 0xb53f8fbf, 0xb37a8bd6, 0x3fae29ea, 0x81563b14, 0x4f675f3b,
- 0xb36e75c1, 0xcdebe9d9, 0x23a56ff7, 0x09bff9dc, 0x4557bc22, 0xfce8c2f8,
- 0x0dd4517f, 0xc59ba7ad, 0xabcca0fa, 0x7dd07255, 0x293d4ae8, 0x9cdbeb99,
- 0xa28bfb5c, 0x0b39c51e, 0x6fab1d72, 0x3c147c01, 0x1fa2b3ad, 0xbb6789dd,
- 0x13ef1d3d, 0x94175d68, 0xcc9cf089, 0x47367ae0, 0xf6061bdc, 0x3c137dbb,
- 0x9a759383, 0x32706578, 0xc163a7b7, 0x5af1c27f, 0x5438f227, 0xfc839658,
- 0xe6a9c079, 0x19e53c1e, 0x302be02b, 0xa3f4fe3a, 0xd274f000, 0x7bc7027b,
- 0xad12fdeb, 0xa21f3047, 0x83afce5f, 0x2ad00e28, 0x4e8503d6, 0xb4d92fc0,
- 0x54bd09ce, 0x21f80ab5, 0x2da1ed15, 0x6afa835b, 0x0be286f8, 0x3ebe2eec,
- 0x7c704554, 0x4c393d56, 0x6f82e5d8, 0xbf120c9e, 0x6cedc0c7, 0xec51fd65,
- 0x3d3e6570, 0xef40e1d9, 0x7c2ac961, 0xe999d3f9, 0x7dead93d, 0x5e74fe94,
- 0xd2986e60, 0x0bc1550a, 0x5c067825, 0x6b7d91d2, 0xde0892ce, 0x2a7ad581,
- 0xb259d51f, 0x8da6ee51, 0x11f179dd, 0x7e7857d4, 0xebf47907, 0x39bbbeef,
- 0xa951f707, 0x7dc472fe, 0xeb0fc8ca, 0xef183799, 0xd894afd9, 0xa03acd69,
- 0x8fdfe32d, 0xb9fabb63, 0xf89efd5e, 0xdcfd9ff7, 0x69d8c159, 0xf85d8590,
- 0xebc347ec, 0x4665fbd5, 0xb93c7236, 0x5f4f308e, 0x597677d2, 0x0467ef8d,
- 0xcbfcee1f, 0x6e3023ab, 0x687dae31, 0xe9679e2f, 0xd3ef53a7, 0x5ed660ed,
- 0xa3b4efb8, 0xee17ad31, 0x2438eb4b, 0xf0033987, 0x038056f5, 0x572ff1e3,
- 0x5ed9e998, 0xf0652ac3, 0x8f99da2b, 0x6bba67f6, 0x5f902ccc, 0x73b934ba,
- 0x739319ff, 0x3ba5f7d4, 0xa4ec7d68, 0x9fa9a5d3, 0xc77787e8, 0x569dfe3f,
- 0x87f913d6, 0xebf715e3, 0x06b75e20, 0x740a4cb5, 0xe04aafde, 0xafbeda6d,
- 0xe0e33f68, 0x943a8dc6, 0x3a35c1f7, 0x26b93acd, 0xca43ec59, 0xd7089964,
- 0x61417db4, 0x438f4859, 0xe6082db2, 0xccfc6ae7, 0xd7e00ce8, 0xfb11e3f9,
- 0x8702fdc7, 0xa7842d93, 0xf25a86dd, 0x365f772b, 0xbb29fdd3, 0x8125958c,
- 0x23eccce0, 0xd8ebc405, 0x5f6833f3, 0x5e157fca, 0x7a87b5c7, 0x588e3173,
- 0xbb1c78c3, 0x7d71bf1b, 0xd185b1d4, 0x710ef739, 0x1b63a80e, 0xa01ebca3,
- 0x77dc49e2, 0x8b7df203, 0x80d63f7a, 0xe32f1d86, 0x28de5efa, 0x72e4fed1,
- 0xf7118b7d, 0x221aba5b, 0x65bfcc64, 0xae3dc558, 0x59b0cb7a, 0x9c38392a,
- 0x17e7e7ac, 0x07beecc6, 0xc972bdc7, 0xec87e748, 0xef747c07, 0x11c695c0,
- 0x3cefbebd, 0x6c156bce, 0x7b3bde0a, 0x5f119938, 0xd0c1f3f8, 0xf29ac16d,
- 0x8899d958, 0xd4cd34f2, 0x002da0f2, 0xc4528add, 0x7aa370fa, 0x89fff3cc,
- 0xe8a63b1e, 0x8eaca731, 0x74a46487, 0x817163d3, 0xc962d8f4, 0x5ef8871a,
- 0x871694dc, 0xd87c5cf4, 0x8f481310, 0xac38076d, 0x007f7720, 0x7b67c3f9,
- 0x9bb1e81d, 0x0eac7a54, 0xbf0058f4, 0x3ae52924, 0x5ff3cc7a, 0x51db6f23,
- 0xe798058f, 0x1fae14f0, 0xbc363d14, 0xb1e914f1, 0xcd3a75e1, 0x29feda39,
- 0x5263d3d7, 0x2c68accc, 0x01216c1b, 0x89f106f8, 0x27c47779, 0xd41c713e,
- 0x9629f967, 0xfd9f4bbf, 0xecfa7af8, 0x8abf08bf, 0x3afc5b3e, 0x3ba37f23,
- 0xdfe231df, 0xfd18bbc5, 0x26e2cfce, 0x3716cfae, 0xcf0fbe31, 0xec0d8f4f,
- 0xff18c7a6, 0x6f2f165d, 0x7d486aef, 0x2fe85ee6, 0x99b06ed3, 0x97667ea1,
- 0xeb56cb5e, 0x1e94fcb5, 0x1ba1daf4, 0x0baf6bd3, 0xaafa06bd, 0x7f51ea2f,
- 0x6a35b0be, 0xf763977f, 0x5edbf3e8, 0x5b78f943, 0x4701f3a6, 0x9dfebe45,
- 0x90b3e7d1, 0x1e11eaaf, 0x4235d390, 0xdc2adb5e, 0x03f8ffd4, 0xdb657e7c,
- 0xca0f5a24, 0x57bdb8eb, 0xf07b235e, 0x31a4e180, 0xff3ed15f, 0xe18926e2,
- 0xa6e9b2d1, 0xfef1a7ca, 0x8192f630, 0xd4e53889, 0x143f150c, 0xf8a12a8c,
- 0x999e8161, 0xc96ddf71, 0xb73fbe28, 0x7b959444, 0xf53b0ba2, 0xcdbedfa0,
- 0xf7e9fb86, 0x7bcffc34, 0xdcf7134e, 0xf2417b4d, 0xdd5ffde0, 0x712a7bcf,
- 0x97fbed38, 0xcba77cc5, 0xf61f842d, 0xde73e06e, 0xe5e3fb2f, 0x8d4bc090,
- 0x478bc5ac, 0xe517880a, 0x8782ad5c, 0x565bb7e2, 0xf8a75c60, 0x32fc8959,
- 0x782b79ff, 0x761f76ea, 0x909dff23, 0xdb62f7ee, 0xd25bbf35, 0x144477ed,
- 0x7fcdfb3c, 0x323fa2bb, 0x37bc08d8, 0xf482f81b, 0xfc4ffb87, 0xb8c7421e,
- 0x3d6a71fe, 0xc3c09afc, 0xe371ca88, 0x2e99add1, 0xd5f98afc, 0x804c1ff7,
- 0xb71f67f9, 0x6303fdd2, 0x9ee898c7, 0x3e41adbe, 0x9f0a6fd2, 0x3e70fa19,
- 0xecfd116b, 0x4b945c4e, 0x241a74fb, 0x2e13da0b, 0x37bf106f, 0x082df805,
- 0xf67fecaa, 0x478124ea, 0x689efd0b, 0x006f5883, 0x4e57e8ef, 0xc01fd652,
- 0x88cfca3b, 0xd7074e46, 0x2c874e16, 0xe567e3c6, 0xf30d92d5, 0xf70de5ea,
- 0x8a3e711b, 0x50bf85de, 0xfc545d35, 0x27f357a9, 0x7bad547d, 0x34fbe225,
- 0x1887e553, 0xfc06993f, 0x0cd891be, 0xfc3df7fe, 0x5f77eddb, 0x2f7bf3ae,
- 0xa78e1f72, 0xf44788ed, 0xdc7d12f3, 0xbac2f26e, 0xddf5d610, 0xf06b77a5,
- 0x6bb9fe38, 0x249abf9c, 0x3b01c62b, 0xefc354f1, 0xf056cf6d, 0x788afc84,
- 0x63279c6f, 0xf8837e79, 0xf9bf1fdd, 0xb5083ee2, 0x9d37171c, 0x906ffde2,
- 0xbcc02c6c, 0x7fdfe47b, 0x927b6f90, 0x2d1f435f, 0xe413beff, 0x2efb823b,
- 0x77e24ddc, 0x34231a19, 0x7dfec279, 0x35b01db8, 0xfd1cf808, 0x1b06c3e8,
- 0x2fe0a7de, 0x3d62b1ef, 0xaadf7b43, 0x420f97ca, 0xb12e3180, 0x28ceccc5,
- 0x76e5f470, 0x6edf5aa5, 0xb331620f, 0xbfee7ab2, 0x4f5ba09f, 0x1e528df6,
- 0x5ea1e386, 0x54f1806c, 0x7d7f2cf9, 0xd7e5f8af, 0x0fc6579b, 0xce32979c,
- 0xd87e7bdf, 0xfe799ac5, 0xd0245f02, 0x26dfe179, 0x9fa9bc63, 0x7bdf57a4,
- 0xfe6fdcae, 0x3b3fe84f, 0xfee7a625, 0xf685bc59, 0x4efb2937, 0x0e3cfd94,
- 0xf3fb130b, 0xae33fe6f, 0xfcec57e3, 0x8e9641fc, 0xae33707d, 0x3a06b90f,
- 0x88e57ac7, 0x573fe281, 0x2e7bf026, 0xbf7b7f6f, 0xedf2f51e, 0xff0114a8,
- 0xe44b67b7, 0xaec51d1f, 0x6d1da347, 0x80257da6, 0x1f9811bf, 0x1ca9a8c9,
- 0x333ee78f, 0xe19678b7, 0x17de36d3, 0x6dd20efd, 0x7bf74c9c, 0xc6a3db34,
- 0xc0fa3ae3, 0x71819659, 0xa9ef5877, 0x1621e67d, 0xd8c6f583, 0x18fdc863,
- 0xb1f9f75d, 0xe8c70099, 0x0acdb223, 0x0fefa6f5, 0xf77cc50d, 0xe63af5c0,
- 0x0c6be154, 0x73c32cf3, 0xed5ba33e, 0x22ee1133, 0x2e305fb0, 0x71b8d45f,
- 0x2e439e19, 0x7b512f5a, 0x2939db97, 0xbdb3e61c, 0x4349b3fa, 0x3d401f50,
- 0x9eb5c6ec, 0x48d573d7, 0xcf394c36, 0x24675c6f, 0xefc3517d, 0x91eed86f,
- 0xebf79998, 0xdbbf4331, 0x2cfb43d7, 0xd05b638a, 0x7cd5720e, 0x5cdffb46,
- 0xdfb52700, 0xccc5cfc6, 0x94567687, 0xa9fb9a97, 0x12f5e2bf, 0x457323c3,
- 0x543af8db, 0xc360c474, 0x9f7b75ef, 0x2a74f5a5, 0x8a90978c, 0x02778eeb,
- 0x884739c5, 0xffc77b7d, 0xed5df90f, 0xd58fd38c, 0x2feb92fc, 0x9fbf2989,
- 0x4f9f57ab, 0x97d3e8eb, 0x2db10bef, 0x3f414631, 0x498a8cef, 0x7d5f11d5,
- 0x71b4e746, 0xf013935f, 0x179c547d, 0x8cea3fdb, 0x409f7d51, 0x4f3f2b2f,
- 0x8e30d05b, 0x321551ce, 0x9aa39d07, 0x8fdb9a36, 0xc828feef, 0xde33fb83,
- 0xe37af835, 0xe23ffdfb, 0xb6dcd3bf, 0xb6dfeb9d, 0x1fda16e4, 0x307f1e7b,
- 0xb65c6009, 0x717d265e, 0xce819b7e, 0x7018c90d, 0xe76dfc44, 0xf5fec5f6,
- 0x5bf3dfbc, 0x7e361db8, 0x70931dc3, 0x59b05dbd, 0xf5c46739, 0xce3fe2b3,
- 0x62f388b7, 0xfc8d1b95, 0x5fefacde, 0xac3d1477, 0xbf911efc, 0xfceb2d9e,
- 0xc92f6cfd, 0xffad594f, 0x2ed0ccf9, 0xefe9043f, 0xb9f88afd, 0xa18188fc,
- 0xb99d221f, 0x4f8ff944, 0xef871d70, 0x3b251ba3, 0x3a2a3b9e, 0x1d90f26e,
- 0xdf7799ed, 0x393d71cf, 0x3afba261, 0x1cf055ce, 0xef9328f6, 0xf781bf2f,
- 0xe3351c9f, 0x97e03cce, 0x05ef8479, 0x3be1116c, 0x473f336b, 0x2ab47597,
- 0xe7ae3e76, 0x7fdc7813, 0x9cccb541, 0x89f0fd2a, 0x37799f64, 0x1ee8175f,
- 0x598e856b, 0xb8f9cac6, 0xe562de9e, 0xd9bad8fa, 0x2fcde740, 0x760cfd08,
- 0x5103dd3e, 0xac5d6bbc, 0xe2ff4551, 0xf8b175a6, 0xc42b2853, 0xe265b439,
- 0x91b17a9c, 0x47bc538f, 0x8d546cb2, 0xf4a3f4a3, 0xdbc5dc6b, 0x67f135a5,
- 0x2317fd4f, 0x2fcf347c, 0xfc27a88c, 0x7e36e9fb, 0x7a8cfd0f, 0xee155aff,
- 0xaef51817, 0x8c72974c, 0x2d35333a, 0x0f643ef0, 0xd31fcf8f, 0x747f7e69,
- 0x35825fd4, 0x6cba91f9, 0xdfa07790, 0x4edc0d6d, 0x653ecbab, 0xb2a2cb2c,
- 0x5cbbe505, 0x27cb85c4, 0x75f57df0, 0xa3974719, 0x92cd4fbc, 0xdb981f88,
- 0x29dfc469, 0x8accbb07, 0x5905a779, 0x6802fdbc, 0xf758728f, 0xd04b972c,
- 0x1fd4560f, 0x830017ff, 0x8000007b, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7cedff00, 0x55537c7b, 0x393ef0b6, 0x526d3479, 0xa0fa5b42, 0xb4db4e50,
- 0x9494b14d, 0x27457897, 0x880b5a3c, 0x46107006, 0xf4228206, 0xbd185499,
- 0x35fde338, 0x9c414415, 0x0e7c570b, 0x42d2d37a, 0x1429a2c1, 0x20d5b16c,
- 0xb47441d2, 0x3bd15ef6, 0x0f8afea3, 0x52d25a04, 0x8ef4f987, 0x6b5adfa3,
- 0xa126d39f, 0xdf7ef515, 0x37f5375f, 0xef6758b3, 0xbdeb1fb3, 0xce275ef6,
- 0x620a3b5d, 0xd67318e3, 0x319e920a, 0x6abd54d6, 0xc614f273, 0x2c8ba68a,
- 0x67e7c242, 0xf01192b4, 0x2c7133e6, 0xd3e3b187, 0x1939db3f, 0x74339dda,
- 0x7ff41d26, 0xc637d357, 0xf3ec6064, 0x991cc64a, 0x5ea5b388, 0x698459c0,
- 0x8c09e2c2, 0x060e313d, 0xead8ca99, 0x0c0599e6, 0xeccddf9e, 0xf8bfb19b,
- 0x7981f436, 0x47a20d5d, 0x2e9c0027, 0xc60dba8e, 0xc680f77d, 0x7e3b280a,
- 0xfdda8e83, 0x153da007, 0x4faed8e0, 0xdcbfc004, 0xe86e61a5, 0xc89771b0,
- 0xb2fff418, 0xc5f7a05e, 0x90597ee7, 0x3adaf804, 0x2983aac1, 0xad9aef8f,
- 0x1efec24d, 0xd9bc61c0, 0xbc6869cf, 0x7f78fbb5, 0xc5e433f8, 0xf186b633,
- 0xe2a635bf, 0x632e599b, 0x65a7cce5, 0x69efd0e9, 0x115da7cd, 0xf87bedbc,
- 0x1827b15f, 0xc60fad2f, 0x4bb6d9cb, 0x6f403462, 0x750ef3f0, 0xef386dd7,
- 0xb4f41bfa, 0xb637d9ee, 0xeb8f5e9c, 0x5c30d06e, 0xef1bece7, 0xba02ef8f,
- 0x963351ae, 0x8e90693c, 0x0cc788e5, 0x559d8eb1, 0xb31fa4da, 0x1c75909e,
- 0x3b8c6719, 0x63fc0d7b, 0x3df49b12, 0xb8dcee90, 0x628d8c91, 0x740b5dcc,
- 0xb67e0049, 0xf00f360a, 0x4765b8a5, 0xf3d616bc, 0x02fdfe3d, 0xf11db6f0,
- 0xb6d73c22, 0xbd2fd408, 0xad62c38d, 0x60aff16d, 0x0aafc51f, 0xb0696aa6,
- 0xb9ce32bf, 0x7df10271, 0xbfef3373, 0xb5e015b1, 0xac5f8fc3, 0x0ac6bedd,
- 0x65dd4a70, 0x72b864ad, 0xb17e651c, 0x739c782d, 0x8e857cb2, 0x2c1a2f97,
- 0x10bba46a, 0xaf7e4569, 0xadbcb817, 0xdc799bbf, 0xacc94f20, 0x87406042,
- 0x9013e644, 0xbd29c0df, 0x86fce41d, 0xcb55903e, 0xf17edd20, 0x1d5b0475,
- 0x6c99c740, 0x3b3e1064, 0x7fa82922, 0xa83529be, 0xecc4a6fd, 0x52b9f6a0,
- 0xdf3e105e, 0xff505d72, 0x4199d605, 0xe7d3adf8, 0x685ff506, 0xdb84185b,
- 0xeb8d4998, 0xba5cad6f, 0x999073f8, 0x041d2b57, 0x70287a15, 0xd8c54e86,
- 0xee0bc13f, 0xa036ec9b, 0x19288ccf, 0x3e397367, 0xd8d1f002, 0x06ddb37e,
- 0x20919d74, 0xc7016ce3, 0x05f69593, 0xe538ffbc, 0xfb785bfd, 0x2dfb4a35,
- 0xd2a27dbc, 0xafc72b7e, 0xf1eed467, 0x03776adc, 0x8ed1ebfe, 0xb6f8096a,
- 0x138aebe4, 0xfde9a023, 0xa77745aa, 0x45583f02, 0x18d36306, 0x0034875b,
- 0xed182ed6, 0x351a4a78, 0x7ff4aed8, 0xe357b255, 0xd14bdef3, 0x63226cb9,
- 0x51dfc80d, 0xe6321f3f, 0x716779a3, 0x1159b2d2, 0x33ea1f06, 0x0cf4d08b,
- 0x631a51e8, 0x0db18d82, 0x906f4831, 0x0477a213, 0x89a55f41, 0x8995ebe0,
- 0x94a8df04, 0x63336ad8, 0x821695ed, 0xf4ad2b27, 0x74e554fc, 0xda576f82,
- 0x5953be08, 0xd2a3b048, 0xe290504e, 0x9f1872d8, 0xa23eb1ed, 0xd5b87a41,
- 0xfcc2cf23, 0x7e40cff8, 0xd4c64286, 0x1722acec, 0xcabf79d0, 0x65f48ad6,
- 0x6ce98c6c, 0x5ef3e0d4, 0x815243a1, 0x46a7bade, 0x0f40eb58, 0xf37a0f8c,
- 0x4617a04c, 0x11bac1a7, 0xe59c6168, 0xbb43524b, 0xbad69d71, 0x029fda11,
- 0xf587ab73, 0xda991ad4, 0x1cc9f602, 0x34f1100f, 0xf7aa8d0e, 0x7fec0552,
- 0x1ff5045f, 0x0236c603, 0x196825fa, 0x7de0f7c3, 0x1ffd8116, 0xdfd81163,
- 0x684024fc, 0x10e1adaf, 0x37f48224, 0x43cde741, 0xe2e09efb, 0xd555d8eb,
- 0xee304921, 0x5c7ca9ae, 0x29f13158, 0x8119cc5f, 0x499fb2f6, 0xb8394c23,
- 0x005abd1f, 0x83d5e881, 0x2bb009df, 0x45034f59, 0xdb24f402, 0x01d4c113,
- 0xbd4d757a, 0xe09f0829, 0x3fea0c4d, 0x6a0a59b1, 0x8259f3cf, 0xb49f27da,
- 0x3b53e106, 0xbff507a6, 0x105b43f6, 0x61575d7e, 0xcfebff50, 0xfef083d9,
- 0x618fd81c, 0x94defe78, 0x9ff50428, 0x703ade0b, 0x89aac67c, 0x232df33e,
- 0x1bf79e83, 0x1b869d38, 0x78358177, 0xb71f855c, 0x7f1e0f4e, 0xdc782da1,
- 0x3d87cb1f, 0x906a27a0, 0x13d07aff, 0x4f41fb84, 0x0de720d4, 0xbf8827a0,
- 0xd0827a08, 0xcf827a0b, 0x209e820f, 0x827a04de, 0x13d011f8, 0x4f419bc4,
- 0x3d051e10, 0xa357e7c1, 0xef3cbb57, 0x53de7949, 0xed8cbcf2, 0x8d5d3a20,
- 0xefcb6f2e, 0xdfbf23bf, 0x079bef81, 0x30bcb0e5, 0xc835f543, 0xf398ccf3,
- 0x87582eda, 0x01575d6d, 0x6f7d4dc6, 0x8246ac8a, 0xc9cf0e6e, 0x5aab8c4a,
- 0x9456d962, 0x5bdf7b5f, 0xa70fc42a, 0xfb42b69b, 0x78ffe696, 0x4dfddb07,
- 0xcdf184a2, 0x459fcdeb, 0x5f3d38e3, 0x2c753247, 0x3459f7be, 0xdf654bc6,
- 0x42b7c230, 0xb9c5fa3b, 0xe5f3228d, 0xb57bbaa0, 0x5663ded8, 0xe3168f70,
- 0xa3437b33, 0x5a52f916, 0x6fed48df, 0xedc1357a, 0xed41d5f5, 0xb00fec26,
- 0x4689ed54, 0x56685e7a, 0xff51f3c6, 0xc3f73332, 0x6f8fea17, 0x5bd61ebe,
- 0x562ab8de, 0x3697f584, 0xd77f17bc, 0xe2ffd00f, 0x1c721791, 0x0b797ef0,
- 0x1c18678c, 0x2345bcaf, 0x65fd7ce3, 0x1882c6e6, 0x621a1ba0, 0x87acfcb0,
- 0xc01b676d, 0xd736942e, 0x577c6195, 0xc343b96a, 0x5ebd3e80, 0x01d710b1,
- 0x71062a7f, 0x9189995b, 0x7ef1e87f, 0x8c177d15, 0xc4f79afb, 0x7a87e82d,
- 0xe3478f5b, 0xd04dbdbc, 0xabbf803f, 0xb11c7953, 0xfc4b553a, 0x1e3a69eb,
- 0x16fb412d, 0x774e71ef, 0xfff68fb5, 0x02f78cba, 0x8b377a24, 0x5afa2e3c,
- 0xc6507c45, 0x9a33a173, 0x4619ed8a, 0x97a757dc, 0xaa7f77cf, 0x579b9fc4,
- 0x9ff5c6ad, 0x55365c4a, 0xae05fb24, 0xf1def01a, 0xc2b6ebf3, 0x30bd4a52,
- 0xf7f210ee, 0xbb6e3ca8, 0x69bf471c, 0x1a3ed43e, 0x30aa7ee8, 0x807c8f36,
- 0xaa636fdc, 0x6815fa8a, 0xe80ae61d, 0x8c9069d7, 0x160fcf28, 0xbf911ba6,
- 0xe7c423af, 0x0eb5bb85, 0x7c4d2580, 0x47534ebe, 0x675dca34, 0xe31164d3,
- 0x7fbc6551, 0x901de791, 0xb9be01ef, 0x9e454f89, 0x338e036a, 0xfcfe3fc8,
- 0xbd1354fe, 0xdef3ca77, 0x7f603b92, 0x2b28969d, 0xcb5da5f2, 0xa5fd708a,
- 0xbe7160e8, 0xa46ae4d6, 0xfddf3283, 0x2d7a3f32, 0xbfabe22a, 0xbbf72359,
- 0xf5058ea3, 0xd57e70d3, 0xe4c7af06, 0x3bfbf339, 0x73d97fa0, 0xbef8c322,
- 0x8f11534c, 0x20fcc7fb, 0x9d32dd68, 0xf8be34cb, 0x2d7900f8, 0x1bd0196b,
- 0x8b79c903, 0xf11227a2, 0xa763e153, 0x4aebe445, 0x2c1879d4, 0x8eb1acb9,
- 0xced41ae4, 0x4d3907ad, 0xff20ea8e, 0xdccffc97, 0xfc0ad54f, 0xfb2559b9,
- 0xb5c7154d, 0x3e2fd100, 0x7853fb27, 0x1f00999f, 0x00146c0b, 0x4fa614d7,
- 0x917c4155, 0x21e6362c, 0xb6a9753f, 0xff9854a6, 0xc87ec97d, 0x6489f142,
- 0x553e43b4, 0x66e0d97e, 0x7efed023, 0xdbce24f4, 0x047904df, 0xd11e5bcc,
- 0x9073ef3c, 0x282b7ecf, 0x7fb7ac08, 0x5ce28697, 0x00833b10, 0xe99acd71,
- 0x94be5f5c, 0x8844d31c, 0x54abcb17, 0xc832afb4, 0x5f98f4bf, 0x62eef6c9,
- 0x28adea63, 0x452765a7, 0x2be60453, 0x9d7fd4de, 0x86837881, 0x57a72af2,
- 0xff30fab0, 0x255a326b, 0x9deacfc0, 0x9d379869, 0xe2d3eaad, 0x3e21677b,
- 0xcbcf9c7f, 0xa7cb4f50, 0xd4519f73, 0x193da3bc, 0x57e60960, 0xafc8cfe2,
- 0x3a99f242, 0x8c75c7fc, 0xf21539fd, 0xb26f8c1a, 0x37c63659, 0x048ce2f9,
- 0x7f995fd2, 0x1710276c, 0x13f5a612, 0xdfa809ac, 0x3cd2d45b, 0xab6f77dc,
- 0x71f484c6, 0xc62a1db5, 0x22ca7b75, 0xafd82aad, 0xa251c373, 0x815fef63,
- 0xf65710ce, 0x33ca3226, 0x67a7197b, 0x6797336f, 0x44f04697, 0x9e20fbe0,
- 0xe0845e34, 0x5ea682a9, 0xd9347f77, 0x510ac621, 0xcb2dd7fe, 0x68bc6150,
- 0x80337203, 0x57b91447, 0xf5c0a5fc, 0x977546fc, 0x7bde1238, 0xe7fdc343,
- 0x48d353df, 0x9968e7ee, 0x46f5f103, 0xc62bf92b, 0x887de8aa, 0x52fe28a7,
- 0x67c435fc, 0xc7254f14, 0x147e497a, 0x6d50bc3f, 0xab8e04d2, 0x821bdfbc,
- 0x0580f32b, 0xe0ede3e1, 0xf8c0def1, 0xa6fc7923, 0x1e740f8c, 0x6afe7481,
- 0x70fc958a, 0x91f042ca, 0xa41577a4, 0xf59e8a77, 0x01cd5c80, 0x3810cab9,
- 0x1d76cabf, 0x728073a3, 0x00e741d6, 0xde7cd105, 0xf11f9c02, 0xd2130e48,
- 0xedffda04, 0xdb5e9c69, 0xa7d8a864, 0xc4b66913, 0x698d8034, 0xa469318e,
- 0xb792261f, 0x408cb2f5, 0x35d0927c, 0xf75d7d84, 0xf06e7e27, 0xda3dc815,
- 0x08575f99, 0xfe203992, 0x6ed3fd29, 0x69c34b2d, 0x18161d6c, 0xbd7188af,
- 0xc5d9e451, 0x1b95b2bb, 0x303992f4, 0x7fc3b2fe, 0x72c567a0, 0x279e117b,
- 0xd8e0fe40, 0x27992f10, 0x8f627bc3, 0x4fd73c16, 0x73577396, 0x73d3ee30,
- 0x0519f379, 0xffc9c60f, 0xf5e72694, 0xc8a7fcb2, 0x10ed58f2, 0xabdf683c,
- 0xee1355bf, 0x90782e5e, 0x8784bf07, 0x45e4621b, 0x99a2bf62, 0xbf47f41e,
- 0x8ef29404, 0x2fa4719d, 0xb9fb08d4, 0x2fffde4d, 0x0263bed5, 0xc684e7ec,
- 0xc2f98a9b, 0x2b08f289, 0x418cbf8e, 0x64f60180, 0x7820eb39, 0xd879ca3a,
- 0xc7bb8347, 0x81ff3c62, 0xf8c56743, 0x8d537aa7, 0x2e66ed11, 0x3cc264db,
- 0xff514805, 0x9f1fe4fd, 0x0b8830cf, 0x5f0aff90, 0xcbecd31b, 0x073f00d2,
- 0x749c493c, 0xefa5fbe5, 0x3e468e1f, 0xd0e6ff76, 0xda19db92, 0x3bb23e9d,
- 0x1a551525, 0xa8c41c9c, 0x906d32c3, 0xe0bf0abf, 0x1f1052df, 0x90630f61,
- 0x42cf622e, 0x177ffbd2, 0xabb1fa19, 0xf3a151f1, 0xac7e642f, 0x21f6e16d,
- 0xdd0abf94, 0xa21e676f, 0x5daff81f, 0x23a617c4, 0xffca147b, 0x0407f1ab,
- 0xcd363971, 0xe431d38e, 0xdb8ab26b, 0x2035e4ab, 0x3beeb02f, 0x0bada398,
- 0x8fa892e0, 0x32e72434, 0x7ccb969f, 0x167980fa, 0xdfff5258, 0x9a44e9f1,
- 0xe91a7b63, 0xfd4869ad, 0x32c7d50c, 0xe2aefac9, 0x67a43c6f, 0x3579fac1,
- 0xf85664bd, 0x8e7f802f, 0x7fa4d10d, 0x625d7f0a, 0xd5f7e903, 0xad18f3cf,
- 0xf059bcab, 0x847f52f8, 0x10b00a5e, 0x884363e0, 0x1afc2a3e, 0xf6291ece,
- 0xfb96b4ec, 0xa27df763, 0x8ff2f307, 0x1309df05, 0xceeca7da, 0xd282640c,
- 0x8eaae3ff, 0x38c0f7b1, 0xf0e4cf1f, 0x0159c634, 0xad922db8, 0xa49e23b4,
- 0x3f7ee373, 0xa167b216, 0xf858fe7f, 0x9e385be7, 0x5f1095a0, 0x04cb3096,
- 0xef0d69f8, 0xc57dd8af, 0xecbc7fde, 0x4fd439da, 0xbee06f60, 0x47a25c60,
- 0xa782fddf, 0x256a4406, 0x5f5c6a98, 0x0aa7acea, 0x27f9e0d3, 0x43cf4dbf,
- 0x05d6d87e, 0x2e7e878f, 0x3ce22275, 0xebf1baef, 0x9caacd3e, 0xfc0679c1,
- 0xf44b9cd4, 0xfd53f15c, 0xb25a1965, 0x2833ab53, 0x69922fde, 0x1ec98b6d,
- 0x87f829f1, 0x08fa4f7e, 0x5fa0ce55, 0xc8793fe9, 0xefa008e0, 0x4c3bf079,
- 0x3f67801b, 0x97e81296, 0x3479ed8e, 0xa451f913, 0xb9e2e775, 0x3feab9e3,
- 0x2edfa0a4, 0x2670f3da, 0xb67b8dc5, 0x5ffc6264, 0xa668f354, 0x0728f08d,
- 0x4e6a1fe5, 0xd703ee87, 0x101adeed, 0xf26526a7, 0xc47979f8, 0x1f8c7cb1,
- 0xf1735de7, 0xcbf41321, 0x4260adf8, 0xeb35f831, 0xddfd0878, 0x77970b0a,
- 0xec8233b6, 0x43678c31, 0x2f65d7be, 0x3d7d45a8, 0xb34cf965, 0x74bfe31a,
- 0x056bd135, 0x804b6cf3, 0x6088f676, 0xfd8163aa, 0xff6356c7, 0x6d049b55,
- 0xb1fa1c62, 0x97987991, 0xd247d2e9, 0x247cee3a, 0xaf9f1daf, 0x9f3f8078,
- 0x7534f3a7, 0x694f38e2, 0x37a475ad, 0x278c34f6, 0xd2ebf595, 0xcadef4b5,
- 0xcbc5026d, 0x4f193cca, 0xee0757c6, 0xfdce9753, 0x8db29b32, 0x32adcfec,
- 0xe07e6e5f, 0x611237bd, 0x1d6349dc, 0x7f6874c6, 0x66b389e7, 0x139f3c1f,
- 0xf3073e73, 0xe3ad0c86, 0x77dc62d9, 0xfb8ace8d, 0x2c9b9298, 0xdfff6026,
- 0xe11c7ccc, 0x3d5607ca, 0xf2768c5b, 0x73ca08e9, 0x13adf594, 0x83e61524,
- 0xbf6fabc7, 0xee76e913, 0x778a0889, 0x256755d7, 0xdfc81fb0, 0xa5ff02f7,
- 0x41f6c64c, 0x05f08efe, 0xd825dfc8, 0x44ca81e2, 0x94aa5fc2, 0x5ca5b208,
- 0xb899d6be, 0xbc6e193d, 0x4b9790c9, 0x3ca64760, 0x7c41e302, 0xcd9c6f38,
- 0xcaf40e92, 0xb35e5f18, 0x0657de45, 0x4ee79fbc, 0x98748d9d, 0x769ee5b2,
- 0xd2e31d0c, 0x56f2fe79, 0xa82923e7, 0x381f6bc7, 0xb4317cf3, 0xe7b74aaf,
- 0xbb11fbe1, 0x7e3e512e, 0x15e1e5bc, 0x1aa2ef48, 0xbc9fdf1d, 0x644f73ef,
- 0xe78b3c26, 0x286a6f75, 0x3aed763f, 0x8016fcf3, 0x47bb6d77, 0x3fef281b,
- 0x7113bf76, 0xba7f533d, 0x97470d9e, 0x8f67ae9f, 0xd53e90a6, 0xfce59e80,
- 0x3d733d7c, 0xdcf44550, 0x15ff6e9c, 0x8d39dbca, 0xebf5053b, 0x240df65c,
- 0x8136eef7, 0x5fd8a1f8, 0xf2a5fde5, 0xde554bfe, 0xce02336d, 0xc6432f15,
- 0xd63ef486, 0xc62665f2, 0x979b97b5, 0x47dc088d, 0xfb023c28, 0x35864c86,
- 0xda7dbd03, 0x69a7db2b, 0xd856e91d, 0x8f1534df, 0xabdb4367, 0xbdb255d2,
- 0xcf0ffc85, 0xc5ff1433, 0x0f78b43a, 0xf82ad651, 0xaa3ef122, 0x6af3a6f9,
- 0xd81257ba, 0x7de741a7, 0xe01a7d8c, 0xe75b8777, 0xc713a0d5, 0xe3da0f51,
- 0x31543f6b, 0xbdbf805f, 0xf9922bae, 0xc81de602, 0x114f6023, 0x4b7f1fc0,
- 0xd87d9052, 0xe7042e9e, 0x36aef013, 0x15f21fa0, 0x2dfc65ef, 0x9f8835d9,
- 0xfb3e72d7, 0xc47c408f, 0x389849cf, 0xe71e906d, 0xd173ba5b, 0x70f42b2e,
- 0xb926ed1e, 0xf87e6b29, 0x99f44092, 0x7b9d5e7b, 0xdb1cfa75, 0x7c8b9dd3,
- 0x9ae9af3d, 0x5f947986, 0xfc8b95db, 0xedc2be71, 0x93a54ffe, 0x11f8bcf2,
- 0x05d800d8, 0x3ca260a7, 0xa1ec5f2f, 0x927fdcbc, 0x96cee5e7, 0xfb7764dd,
- 0x88b9f95b, 0x9051d54b, 0x1508e780, 0xeed1da67, 0xfcf227f5, 0x21b7c609,
- 0xcba466bd, 0x97dd53fe, 0xdfec10b2, 0xe1390189, 0xd439da79, 0xe38e2d73,
- 0xc17b432d, 0x1d58a372, 0xf501778c, 0xd8af9e1e, 0xe519ba90, 0xd4679cff,
- 0x6fa3b424, 0x49ddfee5, 0x45af68e7, 0x638a4499, 0x7f0069e0, 0x11e1f607,
- 0x1e282d99, 0x80b6628a, 0x74ad2e7e, 0xa7bfc52b, 0x74c7ba44, 0xc67ae78d,
- 0x2b3d728e, 0x9b4c74df, 0xa35e3018, 0x7894f76c, 0x7f6bde70, 0x345d7d27,
- 0xf023b991, 0x14f597bd, 0x2031b0e7, 0x7a2f80ff, 0xf283c139, 0xdca8f7e0,
- 0x178bc81a, 0x87fee64d, 0x7ef1d21d, 0xa454d289, 0x6af31f87, 0x4c794fa0,
- 0xc00c6647, 0x2b89df23, 0x4e4f98ed, 0x2be01c02, 0xf2cf9702, 0x23991d45,
- 0xd0495cf1, 0xa4bcf0ab, 0x77b786bc, 0x54bc78aa, 0xf7dfc69e, 0x7b57dc0f,
- 0xde821653, 0x9cbdb6f5, 0x5be02772, 0x9c35be0d, 0x7c4cbe0f, 0xb99eda0e,
- 0x46efe608, 0x5cf74d9f, 0x5ed08be5, 0xdc151b75, 0xf78c71c9, 0xb5cd9ee9,
- 0x5baae508, 0xbc15e0af, 0x5c64105d, 0xe5c15f79, 0x8c8547f7, 0xb4859237,
- 0x0a4ff487, 0x3dca35c1, 0x58ff3c9c, 0xb517fefe, 0x7bc22cf7, 0xcf3af9b7,
- 0x57f44ac9, 0xd218692f, 0xf0e07f55, 0x697fa459, 0xb33bf70b, 0x39ee1c0e,
- 0xd872f288, 0xb1e6f748, 0xe3e254e6, 0xdbbd96c6, 0x375ca126, 0xada073f2,
- 0xff3fef0d, 0xc3a7ea3b, 0x57183163, 0xe69eb759, 0xebca2f9d, 0x1e39eb66,
- 0xdfb3b725, 0xb2847c72, 0x3c71dfaf, 0x6b7fb796, 0xa75a17fe, 0xfb81f0ff,
- 0x9fa05e50, 0x17a5e29b, 0xa2605e40, 0x73d94392, 0x1bf59e30, 0xfce0563b,
- 0xab3afdce, 0x09e7c25b, 0x95be30b3, 0xa4dcfccc, 0x14f6fc78, 0x4754a7cc,
- 0x1df9edf7, 0xd7efbb9e, 0x2ba139d3, 0x12a5db86, 0x3dda7ab1, 0xf7bb3f24,
- 0xb5f701fc, 0xf6e74f4f, 0x1edcd1c5, 0xa0c9ef15, 0xfe579ef3, 0x940ad9f1,
- 0xd7717c83, 0xd7fe7c1e, 0xe90abd5a, 0x8db5a9d4, 0x4cfd01b8, 0xa9e286a7,
- 0x3e2f1962, 0x13d7cb1d, 0xf24055d5, 0x653db713, 0x4948c811, 0xe0b7fdec,
- 0xdb8be7ba, 0xce7f479f, 0x0ce8eaf6, 0xa03efceb, 0xbe77bc2b, 0x2da7434e,
- 0x35467dfe, 0xb0b76bca, 0x38b3c57d, 0xd7ef1d7e, 0xf44edfad, 0x3165d776,
- 0x31fa0f9c, 0x16ea9f3c, 0x3f3d0476, 0x1737b75f, 0xfb0bade3, 0xa5dc53e7,
- 0x97a293e8, 0x20bab525, 0x293fc7fd, 0xf963f31e, 0x8666e4cf, 0xc2e9fc80,
- 0xcffc6791, 0x85f5e806, 0x0b4f8d06, 0xb1d62a34, 0xa7af784d, 0xf24963e8,
- 0xbfb8854d, 0xe6755512, 0x278bc03a, 0xbd40ad77, 0x1167af3c, 0x2defd089,
- 0x2e0f3f15, 0x885aaa69, 0xf5b87b76, 0x7c799b14, 0x9f913979, 0xd66e5f97,
- 0xa9cf027b, 0x9547e143, 0x3d5b7a4c, 0x42baff88, 0x19473e47, 0xb7ad2def,
- 0x670ee30c, 0x9fc3f70c, 0x3306ff40, 0xee6661c4, 0x086e56a7, 0x1cdcbfee,
- 0xda9dcf43, 0xcbb44cae, 0xcccbf8ca, 0xd4cf6e26, 0x9fe8995d, 0x7923df43,
- 0x82f57b47, 0xa4aaf640, 0xf7433849, 0xf8d248c7, 0x44967a41, 0xee623db8,
- 0x9c487cd0, 0xc601f326, 0x77ac87fa, 0x9b7a0d25, 0x8d29c61e, 0x7f468aec,
- 0x8aec6655, 0xff6f73c6, 0xc8d59151, 0xc6538bec, 0x4f9c1b4f, 0xbd8b8fc9,
- 0xa87e9b1a, 0x183b60f9, 0x7fc5adef, 0x32622903, 0x3514deb8, 0xcc7cd147,
- 0xe50d35d4, 0xf05768b6, 0x534fb87b, 0x9bfa3e80, 0xc607c777, 0x75c7bfa1,
- 0x8677de53, 0x1ff7a6f4, 0x1ca0a69f, 0x26d8a894, 0x20bee73c, 0xc0617bf0,
- 0x82f85ee9, 0xf25e5e7c, 0xca244337, 0x65cb85cf, 0x01fec7a4, 0xd928fb3b,
- 0x6762bf07, 0x15c70d59, 0x7076cb3b, 0xeecec07c, 0x3762b8e2, 0x42a3fe95,
- 0x1d0a4fde, 0x9077a94f, 0xe6ed93c7, 0x6e7abaa2, 0x7f7e4537, 0x4c6b76c7,
- 0xfce27f3c, 0x19d32b5a, 0x95d3b412, 0x123577e4, 0x19c5b1fa, 0x76a579ca,
- 0xa0e27e90, 0x7499fa3e, 0xbbf509a0, 0x10f940c8, 0x070d15c4, 0x59791cf1,
- 0x07ef15bc, 0x9caee943, 0x7cc5c777, 0x7cf906b3, 0x8af1d6ab, 0x7269ef19,
- 0x82afc8ba, 0x74bf90b6, 0xb8a3aabe, 0xb7d357aa, 0x965fed07, 0xf61af1d6,
- 0x6c76d32b, 0xea4b029e, 0xe3b574d1, 0x943cd091, 0x5c43b257, 0xbb39fd5e,
- 0x39527ce9, 0xe6577f2f, 0x5ea70323, 0x7025f28d, 0x7cde3939, 0x57b46de8,
- 0xf2748efe, 0x03e45703, 0xa3478fcd, 0xe210f9dd, 0x5c407714, 0xbdaae1fc,
- 0x14b50f74, 0xde011fef, 0x7f7829b9, 0xa62edffd, 0x0b6d8838, 0xbcf28e78,
- 0xa50f1833, 0x2fb5ca0b, 0x24dc8f48, 0x9ba5dfc7, 0xeace9608, 0x061d2270,
- 0x8b8045f0, 0x21ebf801, 0x667f4878, 0x1e6266f7, 0x08d61dfa, 0xc6ca3d01,
- 0xbc534efa, 0xd0c3407a, 0xbf046c3f, 0x28e1f849, 0x1d532baa, 0xc718bf00,
- 0x9bfa22fd, 0xca0ee8d2, 0x7587fceb, 0x60f0df74, 0xb82997cb, 0x8ba6bf7f,
- 0x96d295f2, 0x9e31e397, 0x344b358d, 0x78dff83e, 0xdc3d8fba, 0xb6318f12,
- 0xe54cbcf2, 0x94eb94cd, 0x28fed172, 0x5f45cbcf, 0x54bfae26, 0xf6c5c8e8,
- 0xd453b458, 0x7111701f, 0x1328fb46, 0x2d60ddb8, 0x5089f922, 0x706745be,
- 0x25f60bbb, 0x8f11ee97, 0xb15978f2, 0x605f6427, 0x79f1d7bc, 0x261fb70e,
- 0x5e14fce5, 0x31bb462d, 0xa4d99d84, 0x41564dd8, 0x06644d79, 0x3ef2b75f,
- 0x30f3cb8d, 0xd2be776a, 0x83969b9d, 0x7bf249ef, 0x7d2cf601, 0x1da13ed0,
- 0xf23b2449, 0xf61e26a0, 0x60bcf255, 0x14af08dd, 0x802aaf2f, 0xfaad6cee,
- 0x2fca029e, 0x19ee9b99, 0x8575d742, 0x7f39997e, 0xd2f3e44b, 0xbcfc3d92,
- 0x9f8682f4, 0xf2bd832f, 0x3b5afda1, 0xf500aaa7, 0x72b8eeef, 0xdcb9e06d,
- 0xb35fc6d5, 0x5b5f1833, 0x30905551, 0x6c979e84, 0x8a3ed1d8, 0x1d17e10d,
- 0xd2f105d5, 0x7595cf95, 0xeb2bd05f, 0x1519a59c, 0x55a58f48, 0xae00a305,
- 0xf4b9f88d, 0xd0befbe0, 0xdfa1f3a2, 0xf9d2fa06, 0x575f8de9, 0x5c3f9d04,
- 0xe662bc6d, 0xe1c2f3a1, 0xcb0a1fd6, 0xcc69df04, 0x57e818a3, 0xe819e91d,
- 0x2f7cc04d, 0xb4fbfeca, 0x9e78a04a, 0x871aad15, 0xac7301f9, 0x6b7e871a,
- 0x0c0178b8, 0xdd1568e5, 0x8209ba49, 0x0eb0ae1e, 0xffa50f41, 0xbcfc191d,
- 0xaf5945e1, 0x7d2fcf46, 0x9fb420e6, 0x19456c96, 0x5c28a8c0, 0x8945e623,
- 0xda183c23, 0x7203be53, 0x036394ed, 0x5f7cab43, 0xbb522858, 0x586459ab,
- 0x8d12caa7, 0x57d80c9e, 0xf54edb21, 0x7798f37b, 0xa9791506, 0x3d7f7ebb,
- 0x4d7fcfb4, 0xd195bc9c, 0x37e50f7d, 0x330e9105, 0x5fb055c6, 0x4ef43f39,
- 0x7e701859, 0x37f647b7, 0xfc814433, 0x14525f40, 0x5dced39d, 0x503cbe5a,
- 0x10853b4e, 0x72fa79ba, 0xf5f1bf29, 0x6dd206e5, 0x15516bc9, 0xbcc80e74,
- 0xcc049653, 0xaf0672f3, 0x696af89f, 0xb8979d06, 0xd27bf32e, 0x27dbf17c,
- 0xd7588f31, 0x80af7906, 0x407ea7e3, 0x2f906675, 0x0dd09c62, 0xcc1ce9f9,
- 0x66cc1df5, 0x61387b43, 0xae7be514, 0x7ac30203, 0xae8b6733, 0x9d9bef06,
- 0x8c78ae9a, 0xbf34b673, 0xec3f45af, 0x569efc3a, 0x92abbcc2, 0x2637f5c9,
- 0x05d7d215, 0x5bbf40ec, 0x01f59cde, 0x93f2b5da, 0x5cb0d4fc, 0x3fdd1efd,
- 0xce14b9e2, 0x48d4da57, 0xcc658df7, 0xd65f7247, 0xf6ff9c10, 0x075d0e27,
- 0xa76cb2f4, 0xd3ee7c14, 0x225fcf3c, 0xb72f0ab2, 0xce9f148b, 0x73a04c4d,
- 0x38f7c1d8, 0xf7626d7d, 0xdb6e7843, 0x0558269b, 0xd237aa18, 0x26e309bd,
- 0xc73f2677, 0x85f57ded, 0x7ce86b29, 0xeb0533c4, 0x73e57ba4, 0xec8fb9fc,
- 0xeb018b50, 0xebcadb99, 0x59237a17, 0xbbe211d1, 0x23f20c63, 0x92ded52b,
- 0xb6967181, 0xf1eb9def, 0xaf8e59de, 0x57b1f743, 0x253e6fbe, 0xbacae9c7,
- 0xf32727e7, 0x21e618f3, 0xf3976a39, 0xda0a9b62, 0x4cd3ee03, 0x77528299,
- 0x046befc7, 0x9c3e8f7e, 0x17bd617e, 0xbd623bd6, 0x72fdc217, 0x7bd6245d,
- 0x5ca2fe21, 0x5ef58917, 0xbdeb1cf8, 0xeb926f10, 0x0bdeb122, 0x42f7ac71,
- 0x8bae5478, 0xa54b853c, 0xbfd2eef8, 0x3edb9e61, 0xfc721f10, 0x3e084c74,
- 0xe9ffb83a, 0x1f182118, 0x33ff502d, 0xcdfe9775, 0x1675839d, 0xf0dfd926,
- 0x9ce50b3a, 0xb670b3ab, 0xb1f20779, 0x3c24c275, 0x69266747, 0xb74bea04,
- 0x56ffe7cc, 0x1da02fdb, 0xe47d1160, 0x64c4e797, 0x78bb408f, 0xba62e4f2,
- 0xd38feb87, 0x93bc3e91, 0x7ec3e8ee, 0x9e6f98ae, 0xeb06cc3f, 0x265a66e6,
- 0xfc029a6f, 0xe4106998, 0x44fb7238, 0x059f72bb, 0xbadd99fc, 0xdb9a8a6a,
- 0x994e130b, 0xc6ad962f, 0xe925d771, 0xaa1e6327, 0x1dfc734b, 0x5fe855c7,
- 0x19ad7a30, 0x48d76fe7, 0xeabc601f, 0xf3cf13fe, 0xa501fa95, 0x33a927df,
- 0xdef099f5, 0x26fa4b5c, 0x2819ebcc, 0x4dbc8a1f, 0x3e501acb, 0x6128aa6c,
- 0x4933d923, 0x67d5fb8d, 0x92cefdf2, 0x4f80fdf8, 0x6063a92b, 0xcce45f7c,
- 0xdb77cc38, 0x949fbe65, 0xe64a7ef9, 0xcdd1d63b, 0x3a3af351, 0x87475884,
- 0x20ea10f0, 0xdd2fbfcc, 0x7149931e, 0xd20a5f72, 0x984ba95d, 0xedc67a87,
- 0xf5d20a4f, 0x27c72c90, 0x99d3fb64, 0xefe24f66, 0x54acf8f1, 0x96e81fae,
- 0x7d9473cf, 0xbe0def2a, 0xfb05e7cf, 0x6ffee12d, 0x5f645510, 0x5b38e543,
- 0x788efb96, 0xbd4abde3, 0x3739c608, 0x261fdc88, 0x41dffaab, 0x6f1c93bb,
- 0x90c23694, 0x78a3b3f9, 0x09bd36bf, 0xdb6f6c4d, 0xddce7437, 0x296190fb,
- 0x30314fbf, 0x3da11efc, 0xe04d4271, 0xe51fe979, 0x908fc079, 0x9a2cba5e,
- 0x3923f61f, 0x423f01c6, 0x144e66f9, 0x9bf923dd, 0xa4fca2bf, 0x09aa75b7,
- 0xe1dfd4e5, 0x715fa031, 0xc4ffe3fd, 0xb7f0bfa3, 0x6cf5417e, 0xa4bf6ffe,
- 0x722db73a, 0xcdebe1bd, 0x87589d72, 0xbde7c464, 0x60159f85, 0x1c32adbf,
- 0x3cfc23b4, 0x686f814f, 0x681de66c, 0x51509ecf, 0x8dd8a2fe, 0x98597d50,
- 0xf78e5239, 0x676831ec, 0xc4ec5f40, 0x597d01b7, 0xc1798316, 0x12917da0,
- 0x132ea87e, 0xcd598bed, 0xb4420bed, 0xb733662f, 0x7da3882f, 0x05f68841,
- 0x417da39f, 0xe20bed1c, 0x47105f68, 0xed1082fb, 0xebff3e0b, 0xd3a75e52,
- 0x3f29810b, 0x5c5035c7, 0x7f8ebebf, 0x8dbeb27f, 0xafaddbdf, 0xac0ea816,
- 0x94dfe607, 0x509d4439, 0xe4275c93, 0xa2f741dd, 0x15a2c3ae, 0xd6017859,
- 0x6dcf09bd, 0xd0277d35, 0x051ab82f, 0xcf84956b, 0xb63ad297, 0x60fd4eb4,
- 0xd3af3e39, 0x2fe85558, 0xa3c72f5a, 0xad692bdf, 0x2735ff23, 0xbfcb4da1,
- 0x9e181197, 0x71d12f1f, 0xe11728fd, 0x3fba24e9, 0xae5ffb26, 0xad73a0eb,
- 0x0a417ad2, 0x35c08efc, 0x7fc512fd, 0xf2b9fdca, 0x57b94bdd, 0xca0ead2f,
- 0x6ebc6c9f, 0x4aff718b, 0x9e406579, 0xc3277cab, 0x74d56fc4, 0xc08afe3f,
- 0xd7ab8562, 0x36b49573, 0xaffac66e, 0xb4767bd0, 0x16d75424, 0x44febf72,
- 0x95d75ca6, 0x6f30f2c7, 0xf5627c2e, 0x5f30c381, 0xe51d76ff, 0x774f609d,
- 0x409efea1, 0x9cba0439, 0xb9d3d368, 0xb23be7db, 0xde1f1046, 0xf6489914,
- 0xb7d90c72, 0xf2811a75, 0x3597b031, 0xc2ecdef8, 0xceaec8bb, 0xfc8abb06,
- 0x93eee454, 0xca2d7b54, 0x1209bae7, 0x1d7cb9f9, 0x93c697bb, 0x9200c5eb,
- 0x146fe5de, 0x57c02a3c, 0x2f7d2b31, 0x86c812b4, 0xc6af50f1, 0x75d608f0,
- 0xaebc64ad, 0x75a39143, 0x8eef943b, 0x577d10c6, 0xd95cf4c8, 0xb06fc7fa,
- 0x1d2ee36e, 0x56490f3f, 0xe4803af1, 0xe7bebcad, 0xf5e0e66e, 0x8b4d9872,
- 0xdabd2f94, 0x511dcf05, 0x79f85263, 0xe380948f, 0xa1a53aaf, 0x84fce33a,
- 0x8a0e9905, 0xfd50e64f, 0x43bbe086, 0x1f9afefc, 0xeb83878a, 0xec684e37,
- 0x3b573df4, 0x73d925ca, 0x9553c107, 0xbb150445, 0xf63fd4ad, 0x88dcbdb6,
- 0x0cbbe7f3, 0x62b7a456, 0x83a8ae07, 0xa950e48c, 0x100b1c83, 0xc0cc0aeb,
- 0xda0c5363, 0x44ec8967, 0xb273aab2, 0x1bfffb84, 0x3f200eff, 0xe30f2da1,
- 0xfc7974a6, 0x43fd92d3, 0x9a2d9fe4, 0xbc3df1b9, 0xf40eda4f, 0x080dc02c,
- 0x6d7b2f18, 0x6dbfc622, 0x1a46a982, 0x78ee8eca, 0x5c97eb08, 0x7184c166,
- 0xf6e44159, 0xbf1878fc, 0x8ad52d20, 0xccd5dc76, 0x403f2de3, 0x3debf7ce,
- 0x55dfc0a2, 0xce9c63c7, 0xea9596f9, 0x351ccee8, 0xacbe7cf8, 0x5fadbd4f,
- 0xabe3faf1, 0x38b563c7, 0xade99bbe, 0xc8f8f275, 0x8cd7f9f7, 0x914cb8a5,
- 0x8486fe9b, 0xef9b941a, 0x7cbbff65, 0xcc1a7bf9, 0x1cd33b03, 0xaff38dff,
- 0xa1e97d58, 0xd0e7da78, 0xd3a9507e, 0x4a83f50f, 0xabfff37c, 0xcaedff3e,
- 0x54ef820a, 0x51d8206e, 0x51f6a6e9, 0x735cfc59, 0xfc0ab8b8, 0x10d65c43,
- 0xbf4294f1, 0xe4aae221, 0xae3ca9ac, 0x89473cc2, 0xa388aeab, 0x0155df40,
- 0x75bb3efa, 0x608f9de4, 0x6b53b3dc, 0xeb0090c5, 0xc81bd7a8, 0x4d64643e,
- 0x529e2a1d, 0xf8a069e8, 0x27e99fab, 0x2cb3fce1, 0x1fbc6ae9, 0x0425989f,
- 0x3fa80be5, 0x1fd46fb8, 0xea3fa884, 0x39e7b880, 0x14f6a82d, 0x29b82f1e,
- 0xbf13d05e, 0x5d815737, 0x662efc01, 0x3d2bb20a, 0x31857621, 0x1d70affb,
- 0x9d795a6b, 0x3a5f5297, 0x93d7c00b, 0x5e33b086, 0x46c6676e, 0x3ce1f77a,
- 0x54919d63, 0xc3427caf, 0x16c4eee5, 0x9ab82f5e, 0x8ff7f9d9, 0x689bda57,
- 0xb15defa4, 0x01fc9f7d, 0xa8f5dffa, 0xcd9ee281, 0xfda66b49, 0xf8cdec4f,
- 0x7f0f4e2c, 0xe7de6fa5, 0x22731f20, 0x905cf7f9, 0xee2859bb, 0x7e924555,
- 0x8ed97e40, 0x6bac57df, 0x8ed0f211, 0x77d9d1cf, 0x6a9d3ae1, 0x27167ebe,
- 0x3baa27df, 0xbf42f78a, 0x2b64f8ce, 0x1263cfe6, 0xffac308f, 0xe61577ca,
- 0x64ecbda0, 0xbf7be9db, 0x5dc73a8d, 0x39c5e7c8, 0x7b9d0215, 0x5897faca,
- 0x95b35518, 0x153591f8, 0x2708bef9, 0xe6e473a3, 0x2e8f98c5, 0xf1c10a8a,
- 0x8dce8b1e, 0x6c78e55f, 0xd2827b48, 0x1cc9e32e, 0x2f356777, 0xd2e573c6,
- 0xf3e9bd7a, 0x91cffaa0, 0x39abb841, 0x6079f4c9, 0x03fe2a7d, 0x822daecf,
- 0x93dc059a, 0x078e0837, 0x85e53f70, 0x2e39f917, 0x5abf23eb, 0x7d112595,
- 0x7ccebd47, 0x737dff28, 0x902e748d, 0x87915b10, 0x472c09e7, 0x52fd8a9a,
- 0x17147d34, 0x96ab7ef6, 0x8be8b3bf, 0xef202dbe, 0x7f95be7f, 0xcfca117f,
- 0x7b970b3c, 0x0db0d997, 0x8c4ce6f9, 0x7ad82088, 0xa616e289, 0xdef19bb6,
- 0x3a0af214, 0x3f7d08b7, 0xb7efc2dd, 0x656b3753, 0x90ff813a, 0x8e337ae4,
- 0xc674d9bb, 0x948befaa, 0x266ccae9, 0x866d3ff8, 0xfcffc64a, 0x0113e638,
- 0x7fd86dfd, 0x6b5f9db0, 0xf77bef2b, 0x26f8fbbe, 0xca1f3cb3, 0xf1461ad7,
- 0xa0f7e873, 0x06625a9f, 0x2e5033ea, 0x53d38b9e, 0xf7583f9e, 0x6ba0ebcf,
- 0x7f3d72f5, 0xf83fbd68, 0x8ae7f43b, 0x725f7b9f, 0x52bf1d50, 0xf9d4aff7,
- 0xcd2f3127, 0xe027b4a7, 0xda88baed, 0x3847a1db, 0x2193f303, 0x659376e8,
- 0x91647fe6, 0x17d9b8de, 0xfee7c1ea, 0x810de8a8, 0xe486727c, 0x66593737,
- 0xfbca7bd1, 0xb1661be5, 0x26e3262f, 0xaccc38e5, 0x14e7ff22, 0xd9021bd9,
- 0xa28f5e11, 0xec1a77bc, 0x9ff7ce3c, 0x7e11f760, 0x0bfef608, 0xc19fe7a0,
- 0x08fc21de, 0xff3e1dec, 0xc21dec04, 0xf803f02e, 0x03f053fc, 0x61dc9708,
- 0xe57a829c, 0x5f62ae6a, 0x3b3dd704, 0xd3bfe302, 0x97968733, 0x9e2a598b,
- 0xdd0ea5bf, 0xe9e596ae, 0x6f9c8df4, 0x4f3377bd, 0xdfc92a4d, 0x86178c26,
- 0xd7b7eefb, 0x5afbedc8, 0x37bc1cf9, 0xb2e7e389, 0x473cfc34, 0xf7c69ec5,
- 0x3af066d7, 0x2b8ec539, 0x1fc82af9, 0x63acaf8d, 0x29d79c9c, 0x55663cfd,
- 0x0a48f7d0, 0xfde1639c, 0x5f313e48, 0x0d4c7947, 0x44a74f90, 0x172a19f2,
- 0x1d385a9f, 0x772e3acc, 0xa09768c9, 0x9e82727f, 0xe361c6e2, 0x51ef90b0,
- 0x394f90ae, 0x32c64b1e, 0xf3e1988f, 0xf7aca363, 0x7e3f3a3f, 0x943150d8,
- 0x3ff998fd, 0x3e80ffdd, 0x8affef06, 0x8e876b7d, 0xf7db873f, 0xca2bbd40,
- 0xc1f610cf, 0xb81f603a, 0xb164dcfc, 0x1d4cb78d, 0x05483bfe, 0xebe0cdae,
- 0x6a83e456, 0xc5ee3094, 0xee0fa57d, 0x91fd6067, 0xcb5bfb21, 0x94225ee8,
- 0x13df018f, 0x05fafb29, 0x1ba147ae, 0xa38a3e58, 0xa81994c7, 0xc590fbce,
- 0x4769efc4, 0x0762b97d, 0xf645feb4, 0xf1507f13, 0x6ec51a7a, 0xc4173c0f,
- 0x82730b95, 0x513339ec, 0xfd23ad9c, 0x7bbc41f2, 0x4f7830d0, 0xb7f7eca9,
- 0xcbf63eb2, 0x6fffb5f9, 0x8ff65f3c, 0x73dfa3ee, 0xefcd3ff0, 0x9bc460d1,
- 0x6eee0eb1, 0xcc253bf9, 0x9e5ad5af, 0xcf21ab37, 0x7d2f7bf6, 0xae01f782,
- 0xaa3c4467, 0x9733e262, 0xd3fc5097, 0x7e6131a6, 0xc7e9f1be, 0x9dbca24f,
- 0x7424126d, 0xd826fed9, 0x3ba7e636, 0xf43d1e8d, 0xe7e2682f, 0x45eb6b27,
- 0xfcff048f, 0x696efe42, 0xfa1a33f6, 0x234d699e, 0xfe3977af, 0x6bca7af4,
- 0xcf207acf, 0xc40b7186, 0xbcf1da07, 0xfe39e4be, 0xfb2512bb, 0x1efc5adc,
- 0xa05aa4af, 0x97c9537c, 0xaf75e4cb, 0x6c7909d9, 0x30483dd0, 0x14bccc5e,
- 0x06d4955f, 0x086b2f3f, 0xb5ef7fce, 0x94d77c0c, 0xf9c8ebc7, 0x3f62acbd,
- 0xdcab8caf, 0xfac1a7c4, 0xe3c6bfeb, 0x76d8be79, 0x0353e539, 0xf8ca17c7,
- 0xca2fc019, 0xfacaf6e7, 0x62e8fc95, 0x85e29b12, 0x2e313afd, 0x50efe495,
- 0xc8aedf81, 0x1f485bae, 0x8c268a8f, 0x8b34b6b3, 0x7967a46e, 0x7d377eab,
- 0xf4e78537, 0x3df3a446, 0xc26ff7e4, 0x273c267b, 0x83b67c84, 0xce83a6e4,
- 0x6fad99e5, 0xb697dd0d, 0x4fe84de8, 0x683f479d, 0xfd06efc7, 0x57860587,
- 0x7cefcaf8, 0xd78679ac, 0xcddfc199, 0x229afdf8, 0x5f006217, 0x436bef91,
- 0xc33e2af8, 0x8d35f3f3, 0xdedf2823, 0xf568b4f8, 0x39785ca1, 0x17be157f,
- 0x3ce8db88, 0x7c48f805, 0xdd4cfd9e, 0x07289193, 0x05fdf8fb, 0xfdf101c8,
- 0x77ce2eec, 0xc443db6d, 0x2cb57f77, 0xf7fc2d07, 0xf8ea4a49, 0x17e81079,
- 0xf1abc9f9, 0x5f7c6aff, 0x7c83db20, 0x3889c671, 0xe5ef778c, 0xe988adf3,
- 0x9a07bf2e, 0x20bb993e, 0x7975f515, 0x26c6eee1, 0x07891980, 0xce621999,
- 0x51db3a53, 0x5cb9e04b, 0x79d79e9b, 0xca045103, 0x4bfae433, 0x53dd4ce9,
- 0x5e47af68, 0xfe31f143, 0xf79c0445, 0x60cf3f00, 0xb23bd09e, 0xd8cbc0fb,
- 0x7e8e946f, 0x55bca58f, 0xa2e5d3e7, 0x9bf2e45f, 0x715bedaf, 0xafddc60f,
- 0x433ee8ea, 0x45dff1b0, 0xe3fd6d28, 0xc84f7887, 0x416df29a, 0xff209bbf,
- 0xfe2941ae, 0x37b602ae, 0xe8067a68, 0x3fa6ed80, 0x165d7bd1, 0x9e92875e,
- 0x71848370, 0xcc65c6ec, 0x943e9911, 0xe764679d, 0x8729ef95, 0x3986c38d,
- 0x2fe2506f, 0x12331ee6, 0x7df94cf5, 0xad0ec505, 0x3c5bbf95, 0x7529df71,
- 0x96afd22c, 0x714c8eff, 0x389fd82b, 0x7922df3a, 0x38aee73b, 0xbf9782a2,
- 0x468ab944, 0x0e68fab9, 0xc7db2ff6, 0x3c0683fb, 0xdf871919, 0x4f286b29,
- 0x7937d01b, 0xa3df867c, 0x05f3bb40, 0x0ea6c581, 0xab6a2f61, 0x421e8f37,
- 0x2e214a6e, 0xca8745c3, 0xb829b38f, 0x768377df, 0xf8f7c264, 0x9726567d,
- 0x662cf72f, 0x0d5ffdc1, 0x40d8f92a, 0x947e067e, 0x19e660ea, 0xc972df29,
- 0xd5ced2e7, 0x51273a26, 0xed538dfc, 0xf299b33d, 0x43972332, 0x63dfa335,
- 0xb68d54e9, 0xef380d6e, 0x4e979ce8, 0x6fc59fdf, 0xdc70faf4, 0xb58205be,
- 0x44e69a06, 0x5f2efcf1, 0x0bdb2f65, 0xb8a86fed, 0xf30e7ddf, 0x17fd1137,
- 0xff419397, 0x93cfcfc6, 0x7f3c8d0b, 0x9adca8f3, 0xa61df489, 0xdd94eb1b,
- 0x2bd52d76, 0x1d291ced, 0x677c0268, 0xefd90e71, 0x73f1df23, 0x5a65bef4,
- 0xf33bf3f2, 0xae51cbec, 0x4f1b2e77, 0xd208afed, 0xe33f7863, 0x7da48e2e,
- 0xcfc85cec, 0x4c2e771b, 0x5967f6a4, 0xdf1a955f, 0xd9fbe6ab, 0x3a04d8f9,
- 0x39d38dff, 0xbef1b372, 0xd8c7be58, 0xc24b6a99, 0x0527d37a, 0x71bbb2fb,
- 0x1a0609bc, 0xe24590ef, 0xc6cb12f7, 0xe907b63f, 0x8a9a4634, 0x7e0fdb76,
- 0x7ff00def, 0x4dd86c7f, 0xf71732f5, 0xc705b99f, 0xe4057d2f, 0x37f7c60f,
- 0xebbe8318, 0x66efbe57, 0xc5b4df6a, 0xb0bf40c6, 0xbcb5d791, 0xeaf6e464,
- 0x3373cea0, 0xe4725fbc, 0xebb45cb3, 0xdafb07fe, 0xdaee3193, 0x243af02f,
- 0xde2e5777, 0x87a89647, 0xce6faf8e, 0x4f4bf1e6, 0x8c52d44b, 0x63fa84e7,
- 0xe252df54, 0xe7435dbd, 0xd9bf7254, 0x866e3cd9, 0xed1f747e, 0xdfc827de,
- 0x05a6f8bb, 0x752b5bde, 0xb8fb3dcd, 0x6b34951c, 0x92e47be8, 0x51ff46fa,
- 0x59d43fc4, 0xf55d7c51, 0x783ee897, 0xe8074bf6, 0x3fef02de, 0x473a08de,
- 0x3b39dfe6, 0xaae63b65, 0x395ec917, 0x77f9ca9b, 0x19e2f55f, 0xd28fbdc2,
- 0xf15d34ef, 0x27731d5d, 0x5f4912ab, 0x29e6b193, 0xa5f4bdb4, 0x206e23b6,
- 0xbda1e961, 0x2ee7e8d1, 0x2345d474, 0x55dc61dd, 0x5e7c11da, 0x2b883dfc,
- 0x7d05b5c7, 0x6ef2e69f, 0x02ebc4b9, 0x845fc8bb, 0xff80bff6, 0x6f7f3f00,
- 0xd91dfcb6, 0xf25aecb5, 0x14b1f5ff, 0xa6fac157, 0x13b77e05, 0x0f4bffea,
- 0x0dde7e5c, 0xbb073ded, 0x96f5c79f, 0xd515f77d, 0xf557b123, 0xdae6b754,
- 0x73f93eff, 0xcd7fbde5, 0x7fa871e6, 0x583ddedf, 0x2fffea97, 0xf347159d,
- 0x22997db7, 0xe36839e1, 0xf10f7437, 0xfa7cb69b, 0x8737e6de, 0xd0fc2767,
- 0xb7281177, 0x75c0cc9e, 0x92bf8879, 0xac503bfc, 0xfc218655, 0x3c74de3a,
- 0x1179d705, 0xba754df8, 0x72f73f12, 0xbee9cb7a, 0x8007f101, 0x8786cebe,
- 0xb8ffa12f, 0x4d9cff1a, 0x61bd6f8b, 0x2b43d90a, 0xf58b95aa, 0xe87ffdd1,
- 0xfb7c037b, 0xc4e3e04f, 0x86bfc11f, 0x70ff342d, 0xff88bbfc, 0x081d3e00,
- 0xa6e5dfe1, 0xeb1dffbb, 0x6c535968, 0x8128f7d0, 0x08fdf374, 0x7c0915ba,
- 0xdb66dffc, 0xf4bed19a, 0x0f617c1c, 0xdf2309d6, 0x2eb0966e, 0x330a72ed,
- 0x7d30f7e2, 0x697f282b, 0xaed099d3, 0x407db495, 0xeb97e3fa, 0x80cfe029,
- 0x06cfce7e, 0x2fc83afe, 0x55d9b6c9, 0xa2e9f46b, 0xf4efe907, 0xa2942c2c,
- 0x7a19f9e9, 0x8c72e1ee, 0x2ddfc3f4, 0xdd8e7a73, 0x97c10c26, 0x9e34ecde,
- 0xd1467927, 0xff6bcbbe, 0x00c0e3c2, 0x91d3097e, 0x6e28674f, 0x0a4f8e1c,
- 0xeff24c1d, 0xadf00d88, 0x685feb96, 0x87f0177f, 0x7e653fee, 0xf7f0ff21,
- 0xceb85cd4, 0x20cf8e68, 0x0d80f85c, 0xd5fc0f61, 0xfce3ca3a, 0x83c9f721,
- 0xd79079fc, 0xa9ea855d, 0xf4e1cfbc, 0xabd3d143, 0xd2a7ffad, 0x52d92fe7,
- 0x7428bc90, 0x6876f9ea, 0xcf1c6e3b, 0x9f67fef5, 0x3504da3f, 0x7f3a0f8b,
- 0xf3c78c34, 0x4133a6c7, 0x7eca8fe7, 0xda73e47b, 0xf922fd9e, 0xeff2cdc7,
- 0x0bda84ac, 0xd0983be5, 0xd7938ef5, 0x7f7f94eb, 0xd1a0e7a1, 0x7a718063,
- 0x79216f5e, 0xd19c3676, 0x7b6a79e2, 0x9efa21fd, 0xf41fd14e, 0xf5809e13,
- 0x2c78bcf7, 0xce36ec97, 0x275f0433, 0x33cf978c, 0xc79e875b, 0x682970d5,
- 0x57b7529e, 0x57ab754b, 0xda82ef99, 0x778e3b76, 0x7eff83a1, 0xd0ef05e1,
- 0xf1a6a9e7, 0x615cf91a, 0x2fe0873b, 0xbcfe01ed, 0x1b4db053, 0xc30c2a3f,
- 0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0x0c30c30c, 0xc30c30c3,
- 0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0x0c30c30c, 0xc30c30c3,
- 0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0xc1b7ff0c, 0x8dca0bff,
- 0x8000e737, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
- 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
- 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
- 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
- 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
- 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
- 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
- 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
- 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
- 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
- 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
- 0x8000dcb1, 0x00008000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0x00100000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00100000, 0x00000000, 0xfffffff3, 0x314fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff,
- 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
- 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff,
- 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
- 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
- 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
- 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
- 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
- 0x000a0000, 0x000700a0, 0x00028110, 0x000b8138, 0x000201f0, 0x00010210,
- 0x000f0220, 0x00010310, 0x00080000, 0x00080080, 0x00028100, 0x000b8128,
- 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0,
- 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338,
- 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280,
- 0x000e8298, 0x00080380, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
- 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
+ 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
+ 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
+ 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
+ 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
+ 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
+ 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
+ 0xccccccc5, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0xcccc0201,
+ 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201,
+ 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201,
+ 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
+ 0x00007ff8, 0x00000000, 0x00003500, 0x00100000, 0x00000000, 0x00100000,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
+ 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
+ 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
+ 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
+ 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
+ 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
+ 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
+ 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
+ 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
+ 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
+ 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
+ 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
+ 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
+ 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
+ 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
+ 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
+ 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xfffffff3, 0x31afffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
+ 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
+ 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
+ 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xffffff97, 0x058fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
+ 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000,
+ 0x00070100, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280,
+ 0x00010370, 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0,
+ 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170,
+ 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000,
+ 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298,
+ 0x00080380, 0x000d0000, 0x000000d0, 0x000280d0, 0x000b80f8, 0x000201b0,
+ 0x000101d0, 0x000c81e0, 0x000002a8, 0xcccccccc, 0xcccccccc, 0xcccccccc,
+ 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
+ 0x00002000
+};
+
+static const u32 tsem_int_table_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9b38a, 0x22717618,
+ 0xa70143f8, 0xa4303332, 0x10267103, 0x97e204af, 0xaf0c0c8c, 0x2fd78918,
+ 0xcf608621, 0x38606610, 0x4206c402, 0x22450c0c, 0xa07af108, 0xfe407b9a,
+ 0xb698a842, 0x76c30328, 0x3bf781d1, 0x34957035, 0x24a458a6, 0x458d5d82,
+ 0xa0d7191e, 0x4494efc9, 0xd012d7e5, 0x4538d03f, 0x513f9509, 0x547f4201,
+ 0x342fa684, 0xf95049f9, 0xa57f5039, 0x77376129, 0x001e542e, 0x61aa8a92,
+ 0x00000360
+};
+
+static const u32 tsem_pram_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce,
+ 0x204e4cce, 0x30840909, 0x43511879, 0x7c061e1c, 0x201276f4, 0x06bf2ae5,
+ 0x0ea2a17c, 0x2de42108, 0xebf8fea5, 0x092132fd, 0xf636c544, 0xda2f45a2,
+ 0x05a855e1, 0xa180d03b, 0x4a00ee05, 0x7836daa1, 0xf5ab15bd, 0x62a2968e,
+ 0x96ad2248, 0xbfcb17fe, 0x24fbdad6, 0x00664e73, 0xbbf7bdcb, 0x9fa7efd7,
+ 0xece7d9dd, 0xebdaf7b3, 0x7b5ad7b5, 0x5d8a3ded, 0x19d7ea62, 0xa0ff873b,
+ 0xc631b3ec, 0x9f2c19ae, 0x23a57cc8, 0x6ad8cbd7, 0x3127d43b, 0x0f623c16,
+ 0x5b18926d, 0xb59fda32, 0x71ca0d30, 0xbc20be69, 0xebe16767, 0xc654c612,
+ 0x9b4aadff, 0xe8f2c994, 0xf073b9f9, 0xf30f81dc, 0x58564b19, 0x63026530,
+ 0xafcc6c2b, 0x8fba830f, 0xfc9c0fb1, 0x7ff8739b, 0xf61b24c1, 0xbf874233,
+ 0xaf3edfa1, 0x814f682d, 0xedcdb37e, 0x1215494e, 0xd5db1993, 0x140bd2c4,
+ 0x9c9abac6, 0x49b4fe54, 0x60282f4f, 0x26534f6c, 0x7935f7d5, 0x8d348ca9,
+ 0x9a07e7a5, 0xb34f547c, 0xf7e3d7f5, 0x2b7c8e23, 0xce0d1595, 0x68ae5adf,
+ 0x060b7182, 0x64cc7feb, 0xf9e00541, 0xafeec2a3, 0x5f9aef80, 0x8512989f,
+ 0x802c99f2, 0xf7e86536, 0x45fb2ecf, 0x8ce1b4fe, 0x387c3d65, 0x6844da7f,
+ 0xe139b127, 0x87459c22, 0xe25c6b34, 0x77b19f71, 0xcdc032a4, 0x6991802d,
+ 0xb9b58c99, 0x4f2e6ffa, 0x44f5cc65, 0x0b9a7fb6, 0x5d0cdde6, 0x2eec648c,
+ 0xde0c1056, 0xf81ffd00, 0xe80525b8, 0x614976a1, 0x4b26cd78, 0xd012cd15,
+ 0x7ccedd8b, 0xa538709b, 0xd41479a2, 0xde60eefb, 0xe383bdc7, 0x9880c5dc,
+ 0x46ccd8e9, 0x32a864e5, 0xa5dd87e8, 0xe2e53686, 0x15c5fd87, 0x2fb712e3,
+ 0xd517f839, 0xf6f1a6eb, 0x078d328f, 0x7f13b9df, 0xcbe07597, 0xaef7d77d,
+ 0x78842332, 0xe11f9853, 0xc657753b, 0xde25c7ba, 0x7d8f163e, 0xc70aab2a,
+ 0x8e1567a1, 0x66dcfc0b, 0x367b74e7, 0xb18d4a17, 0x16663835, 0x9c62b563,
+ 0x03d95a29, 0x3000b258, 0xb58cb5e7, 0xdda0bd20, 0x3abf6894, 0xdf4ae00f,
+ 0x852a4b33, 0x0af1fa7a, 0xf2115e69, 0x10cf41a1, 0xb1259ff5, 0x9ef81d8a,
+ 0x70ca92cd, 0xe71f3b1c, 0x8b50fe86, 0xe86ee007, 0xec9eddca, 0x6194fde5,
+ 0x48553fbb, 0x3858b5f3, 0x7a4fd4bd, 0xdf038c17, 0x38c0f7a7, 0xa56b3ef0,
+ 0xfe69bac4, 0xe1a614de, 0x32c67e78, 0x70a6a440, 0xa8d99099, 0x7867e424,
+ 0xfc8165ae, 0x3f2e3364, 0x8be635a7, 0x9f737e00, 0xd0d47cd4, 0x783579ab,
+ 0x69c85a3f, 0x266aa076, 0x01b630f3, 0x530593d0, 0x7ca8dd1e, 0xb3918d10,
+ 0xcda37331, 0x9663fa28, 0x997b9f99, 0x9cf286d7, 0xcf3f341b, 0xbfd7376f,
+ 0x2769dccd, 0xdc3f82ae, 0x8e4e7dcc, 0xc0e38f33, 0x12cf00d4, 0x6fc0ef21,
+ 0xadbf2c6a, 0x5a19626d, 0x91396241, 0x5dce1c96, 0xb7687a89, 0xf7c073e4,
+ 0x907b602f, 0x6ef890ef, 0x05d7a8bd, 0x0d5d8555, 0x1e282025, 0x958afc7f,
+ 0x1fba406e, 0x101b6567, 0xbf4a0dff, 0x0d7c03aa, 0xa43faa8d, 0x17bf6d0d,
+ 0xd7db1118, 0x4e03be2b, 0x99bfbf18, 0xf8c3d6f9, 0x197aec4b, 0xec3c97d6,
+ 0xd798bd25, 0x7e472d1e, 0xea05d31d, 0xfbf0772a, 0x2767808b, 0xecf001c2,
+ 0x97f4e3e4, 0xdfedfea3, 0xb9f5b12b, 0x77ef0e38, 0x165ceec9, 0xe70c4dcc,
+ 0xfc4ecc73, 0xbc0b40b4, 0x267ee582, 0x02c62729, 0x83cc3d9a, 0xcaa968f4,
+ 0x54394efb, 0xe9f7c69f, 0xf9ccf583, 0x00033233, 0x6618d657, 0xb3a557a2,
+ 0x7af50731, 0x1cb84575, 0x25c3e2f9, 0x12c0acaf, 0x00ae9cf0, 0x2a388fbe,
+ 0xea7ec75e, 0xa21636e6, 0xe870edc8, 0x7b1afe34, 0x7237d647, 0x1fa50f11,
+ 0xd06fc02b, 0x1865306d, 0xff4595f2, 0xc60fbfc3, 0x989cba8a, 0x172a17ee,
+ 0xe20a3f60, 0xf59fcb8d, 0x0f4207fd, 0xf8261e81, 0x957ecbbc, 0xb63c305f,
+ 0xc17e7afe, 0x09500144, 0x13f0cbc1, 0x4552a2c6, 0x663dbd1c, 0xa561e977,
+ 0xff3c3138, 0x7404f3d9, 0x001a7cd2, 0x7527c8b7, 0x1cb4356e, 0xa7753df0,
+ 0xe075f23d, 0x5275ba93, 0xdb7501c8, 0xefbd173e, 0x11ebcb5d, 0xe9f5cab7,
+ 0x0a83a846, 0x7f74706c, 0xb3e47afb, 0x8f5b329d, 0xf5858edd, 0x09ccf418,
+ 0xc49b3b01, 0x174ae7d7, 0xdbadd6af, 0x5f7e1f7f, 0x2e60e5d5, 0xf76eafe8,
+ 0x87af9ba2, 0x76c3a2fa, 0x36ea4d86, 0xa123ab35, 0xd7c438be, 0x0e32bea5,
+ 0x4c97705f, 0xa79f4beb, 0xa076e33b, 0x2726c9cf, 0xd0f182f3, 0xb8ceeee2,
+ 0x3aadf80d, 0xbf1cbdb4, 0xf92adeab, 0x7753ed10, 0x85943a6e, 0x9721faf3,
+ 0xc92d9af3, 0x0fe06bcc, 0x29d13bfe, 0xef0ebe47, 0x193cc097, 0x7588bbf4,
+ 0xac3ea394, 0xad14f4db, 0x4ebe0633, 0xce34e936, 0x10fe1c80, 0xeaef81c6,
+ 0x387c925f, 0x0b1b7ac5, 0xeef63ca0, 0xa0d9cd76, 0xd59afce1, 0x6bce3742,
+ 0x16ed8aa5, 0x72ede685, 0x75be1179, 0xafbc396a, 0xad4ebb5e, 0x9adf918c,
+ 0x70cdc32d, 0x111fc9ad, 0x717d8f38, 0x6f0bec12, 0x1abd60e1, 0x45ea01f5,
+ 0xaec6a425, 0xa9496f6b, 0x2d9adf44, 0xf89af332, 0xf83dd388, 0xedd68caf,
+ 0x5f375ee0, 0x06dd05b7, 0xdba0aaf4, 0x51d05d69, 0x67892fe9, 0xe91b7c7f,
+ 0x2074f000, 0x255ca09e, 0xc0dcf3e0, 0xdfe8154a, 0x2e3a67e3, 0xcbe217bb,
+ 0xc79b3b0e, 0xcd39ac60, 0xac0afd9b, 0x7b2a1da3, 0xef99ed10, 0xd3fd86b6,
+ 0x966dbd60, 0x8025b302, 0xaa05b65b, 0xce15baf8, 0x857f75c4, 0x946f6f58,
+ 0x15af34bc, 0x809fc059, 0x25e98ef7, 0xc049641b, 0xcaf5869e, 0x4b9e3c1f,
+ 0xfd43dcfd, 0xfe4fd0a8, 0xcbd1fb85, 0xd1fa98a7, 0x7e8cabcb, 0x493f5016,
+ 0x474fd717, 0x786675f9, 0x7e8dabca, 0xcf1fa8ea, 0xff4bcdc5, 0x78660dc6,
+ 0xfd4b51be, 0xb1f34ea4, 0xbaeb8680, 0xedd607e0, 0xb6bde197, 0xe3c27535,
+ 0xca2f962c, 0xdcf1c61e, 0x7cb12520, 0xc9253291, 0xfea987c4, 0xf43aa661,
+ 0x2cbad3a4, 0xe3df8ff4, 0x4754b924, 0x4a17a4aa, 0x9e093a47, 0xa46a4687,
+ 0x2eba1e17, 0x87ae3970, 0x4bda3638, 0xab81a90f, 0x0d7c38f5, 0x132c4a70,
+ 0x320fb04b, 0x695fbe87, 0x1b2878e7, 0x7df0b675, 0xd6c1bef8, 0xf50a985f,
+ 0x3fe95b36, 0x959e3ce2, 0x24969db8, 0x976c46b3, 0xdef6e0e4, 0x0d92dcca,
+ 0xb53c18c1, 0x4bfa068f, 0xdbb6fd83, 0x5fc89903, 0x0ebf4bcf, 0x18adbf22,
+ 0xfc7d92ad, 0x22aff342, 0x2b8fd041, 0x22665747, 0xc82a1d3e, 0x2af8ec77,
+ 0xe3445f8c, 0x7ff1c06f, 0x477c6098, 0xf8d314de, 0xd32a9cce, 0xc6154ef8,
+ 0x26df7e07, 0x07c625bd, 0xd8c75dfc, 0xa1bfcd4b, 0x55391df1, 0xb44afe34,
+ 0x4fc7634f, 0x27ff181a, 0x5bbb8c12, 0x90d2ebe2, 0x675de7f9, 0xb54e7f9e,
+ 0x9f2afe79, 0xdfe95eff, 0x3449f8c4, 0xefcd7dff, 0x54e7f9f1, 0x783bf9f3,
+ 0x7be303bf, 0x107ff006, 0xd1247fe7, 0x306ff3fc, 0xad4c7fcf, 0x3e0efe79,
+ 0x0fa52ffe, 0x8d1af8c5, 0x13e6abff, 0x6a63fe7c, 0x11d57c69, 0xa91f21f0,
+ 0xc91a92a3, 0xed06cf9e, 0x94748234, 0xdcb1ca9f, 0xf2976eee, 0x250f0f08,
+ 0x3cfbbe71, 0x1b4df809, 0x042c77d4, 0xacfa0512, 0xcd7cf05e, 0x503552d6,
+ 0xde83de24, 0x5d40285b, 0x5f1325d0, 0xd08ed5b3, 0x6f6f0065, 0xfac41c97,
+ 0x0b5fd582, 0x71deb4c9, 0xb9cc007f, 0xc3ff3e08, 0xc7d6e3d3, 0x2e5acbce,
+ 0x889fb0ec, 0xc388e49a, 0x63632c13, 0x6bbe011b, 0x67f09d25, 0x1e804fd4,
+ 0x3f3fa065, 0xe58a3d00, 0x381fc287, 0xa9967a0e, 0x4cd372b1, 0x6f7741df,
+ 0xeebcc116, 0x509ff010, 0x2c4fbe38, 0xff884295, 0x507a9fcf, 0xb0b4fd45,
+ 0x3e901923, 0xa0834708, 0x476eff53, 0xf844bd68, 0xee7e22f4, 0xec645124,
+ 0x5fbec277, 0xe9b866b4, 0xd42cb9bb, 0x1fed0996, 0xb46f3558, 0x67bff30e,
+ 0x4c82638e, 0x947f9f7e, 0x8d98e48d, 0x318f81b2, 0xfb29f3a7, 0x39dca828,
+ 0xefb26ec7, 0xeb980aef, 0xeb9954f7, 0xdd90f6bd, 0x62c6f686, 0x7e83ad89,
+ 0xbf346def, 0xdbb1c637, 0x8c7b0986, 0x0647778f, 0x2c5ef787, 0x9d63e027,
+ 0xce9f7ae8, 0x69e035bf, 0x22cec478, 0xd3465eb4, 0xc1678fd1, 0x02d7b274,
+ 0x15b79f3a, 0x4eecfbde, 0x73c0057f, 0xe132c3df, 0x747f0ad3, 0x06dfb25f,
+ 0xcd745c76, 0xe768ed1f, 0x8563e75a, 0xd665feff, 0xea2ae8f9, 0xeb4179fb,
+ 0x5627ce73, 0x2ae86a7e, 0xa63c7e1d, 0xeff85d5d, 0xe18f1f87, 0xb32d9aaf,
+ 0xa1c5f54c, 0x17ed4cbb, 0x7a6799ad, 0xb163b0bf, 0xed03fde9, 0xf3ea9a0f,
+ 0xda9b0f82, 0xd9acbfdf, 0xc6defef4, 0xefef4cc7, 0x54ca7aa9, 0xacf02bbf,
+ 0x739dfda9, 0x4bde99d6, 0x898f16fb, 0x8c0d5e92, 0xf2bb42c9, 0x7e43076d,
+ 0x90ddf834, 0x329a8f87, 0xe4d93ca9, 0xe519b2a5, 0xb6dfe414, 0xeb0d979b,
+ 0x63d18de7, 0xed0ff6ec, 0x4f28398d, 0xe2b7be56, 0xf0dfcad3, 0x75bc546f,
+ 0xc16b28c8, 0xd73d475f, 0xe367d627, 0xf8648f79, 0x2e49cb07, 0xb72e556b,
+ 0xcab23bb5, 0x55ae5fd0, 0x718d8523, 0x79018afc, 0x0f344b0e, 0x3a745686,
+ 0xd5b80dd2, 0x137cd744, 0x65fb3d9c, 0x651ebf1a, 0xffdff417, 0xb2df1565,
+ 0x1c883ea1, 0x1c75b9cc, 0xc87fe3c2, 0xa574f086, 0xd3dbfad3, 0x71f86334,
+ 0x4157f105, 0x734d47e5, 0x14d13ca8, 0x5378f2a0, 0x341f9515, 0x6d195235,
+ 0x7be5465a, 0xdf2a414d, 0xf2a76a6d, 0x541d4db7, 0x435a6b1e, 0x429a6fe5,
+ 0xf936f654, 0x2bf01ca9, 0x26993d0c, 0xff614aec, 0xf5410ac3, 0x322e62d3,
+ 0xf24dddfc, 0x7944cbe8, 0x5e7dad3c, 0xe9f37688, 0x72c60e63, 0xcacbe313,
+ 0xcaf1090f, 0x545764fc, 0x4c394086, 0x95defa1c, 0xb2e4e9c4, 0xf40c19b1,
+ 0xfd9763c6, 0x88bf37c0, 0x861b0aea, 0xb37c87df, 0x05fa71dc, 0x75e915df,
+ 0x7f313a21, 0xa06cf17f, 0xfee789c7, 0xedfb04bd, 0xd70a75c1, 0xad3283cb,
+ 0xc1b22c97, 0xc18af487, 0xfd3fad1b, 0xbe5e853b, 0xa54efe00, 0xceebf81b,
+ 0xd8bb7f41, 0xa7ff53a6, 0x414c1d3b, 0x0e49ee3c, 0xf4eaa861, 0x5c1e0de1,
+ 0xda6496ef, 0xf071e3f4, 0xe1759460, 0x5d8b5d5c, 0xf5ccba27, 0x0cd21dd3,
+ 0xa6f2bf1e, 0xd67c86dc, 0x0bc7eba4, 0x5499fe90, 0xc92cfd1a, 0xe4e3f554,
+ 0x3af8871f, 0xf89535b5, 0x6a36fc14, 0x470d1ff7, 0xe1067ea2, 0x87bf64e8,
+ 0xc917c9ef, 0x337ef2ff, 0x7144fe53, 0xfec7b626, 0x0ee7ae39, 0xf91ceff8,
+ 0x8dd50af7, 0x72c21b7e, 0x3e3571d0, 0x0f1a6adf, 0x3e1af3be, 0xf3bcb9f1,
+ 0x4ec2abf1, 0xbdf9f8c4, 0x71f90638, 0xf7acdd2e, 0x86f54d53, 0xb4dd2cae,
+ 0x201fe00e, 0x524aacf7, 0x056a5f90, 0x5a29f4f7, 0x1df004bb, 0x2e8979b1,
+ 0x576f120d, 0x01aa8ce7, 0xcb4df22f, 0xb17bd71d, 0x2f1a8765, 0xe9b2716e,
+ 0x125157b0, 0x9f235fc3, 0x8e22a87e, 0x8d1c3f9d, 0x368bd427, 0x67334f6e,
+ 0x24fe83d0, 0x667a0ccb, 0x6d3409bb, 0x07e43f00, 0x753138c1, 0x21c59fa3,
+ 0x75bc7f7b, 0xedc6c7b2, 0x05b8eb64, 0xf85174b2, 0xb47adfab, 0xc56de71c,
+ 0xa7d77d63, 0x0be4806a, 0x883257fe, 0x47bf0347, 0x3205156c, 0xe5bd5ff4,
+ 0x3f27b27d, 0x1f0b07b2, 0x1ade8f39, 0x7996bf0a, 0xde663922, 0xe38dd641,
+ 0x5a7117cc, 0xdf3befe0, 0xe3f17581, 0xe30cecd7, 0xb42cecf0, 0x8303818a,
+ 0x3fa8364c, 0x3bf36a20, 0xfb3e286b, 0x41db8db1, 0x0785580b, 0xd62ac29d,
+ 0xe0768251, 0x819b6629, 0xdec53a78, 0xa18c4cf0, 0x25590cd3, 0x6ed03cfa,
+ 0x7ec043b6, 0xad17d535, 0xd92bd731, 0x33d40cec, 0x2cedab95, 0x4cfcd124,
+ 0x3ac8a7ef, 0x3588bbf5, 0xb9f5c0ae, 0xdfe3cec5, 0x8ca675f3, 0x5eeaf802,
+ 0xe304be7e, 0xdcc8b7e2, 0x1be2308f, 0xf871878b, 0x54ebc3ab, 0x7dffbc3f,
+ 0xae3bc4e7, 0x687df867, 0xc10fae05, 0x936f929d, 0xbf7e2877, 0x7856fc2c,
+ 0x487bf58d, 0x51c0459c, 0x1b8a45b7, 0xf057bd37, 0x3f8fc1b7, 0xec36f312,
+ 0x1eb197fa, 0xca37f763, 0x332aae22, 0x4a7ee919, 0x296d0677, 0xefe29ef4,
+ 0x5f0e1dc1, 0xacefcc0b, 0xf22962ad, 0xc50fd817, 0x59dda62c, 0xf79e805b,
+ 0xd257af48, 0xa11299be, 0x7b58107d, 0x357dd894, 0x8c53c939, 0x83376371,
+ 0xf71f35f5, 0x241482d5, 0x9aaee158, 0x6e318ac9, 0xfa00fa0d, 0x7e53d27b,
+ 0x4bba8258, 0x9fd864eb, 0x971cd323, 0xf5cd7977, 0xf703fc06, 0x8a32c67d,
+ 0x558f251f, 0x308c782c, 0x9f6e1fd4, 0xe42fbe25, 0x1f13de11, 0xa1c5887b,
+ 0xb9116a74, 0xe9461918, 0xf297f019, 0xf0e35fd0, 0xda007c53, 0xfb79d52f,
+ 0x5f07117a, 0x88d976fa, 0x9789e761, 0x15819c35, 0xdd4c7868, 0x519fd388,
+ 0x25e26858, 0xac2f55e8, 0xf57a31b6, 0x07e05b65, 0xa3d40f48, 0xe3049f08,
+ 0x04f86204, 0x563d571c, 0xf85a0fce, 0x23866fe1, 0xfbf4998d, 0xe5e05b11,
+ 0xcdfc7078, 0xe90e67fd, 0x687fe0ff, 0xfa4305ff, 0xfebc75ff, 0xb6de5eeb,
+ 0x54fc082b, 0x3da7e3fd, 0x63ecccc0, 0x07c323a5, 0xd4ddaf74, 0xfcb941e6,
+ 0x907a0948, 0x64871fae, 0xf2b3f7da, 0xe4315d81, 0x2549afd3, 0x47c43fc4,
+ 0xe27c5f27, 0x3eb7b466, 0xc9d764df, 0x88e2dfbf, 0xeb298038, 0xf973173b,
+ 0x9f78e2d8, 0x8a7e57d7, 0x65d0d9fc, 0x9bd517d6, 0xd2f0ce9f, 0xfe1415fa,
+ 0x87fc846f, 0x287f8dfa, 0x81ac7b47, 0xb3de93f5, 0x9fe3877e, 0xc2f64619,
+ 0xe865353c, 0xaebf637b, 0xa1a5e041, 0x654f89f3, 0xf9289612, 0x55f6d68b,
+ 0x5cf80fc2, 0x9367fb16, 0x33e464d9, 0xc42c1f03, 0xe5f900fd, 0x8e318be7,
+ 0x35f1b3d3, 0xcb14548f, 0x9def5c9f, 0xfdf03f0e, 0xcb137a9f, 0xc5e82f53,
+ 0xb0db7b58, 0xc25dbcef, 0xcbc3d97f, 0x83c47b5a, 0x75dafd71, 0x1e105f76,
+ 0xf0db6ed7, 0xae30e783, 0x77c3b6f2, 0xb35ff419, 0x5cdfd5ed, 0xed9af507,
+ 0x7c99b4f6, 0x31949a1a, 0xf8069748, 0x4184d96f, 0xe4ff543a, 0x8e3bd555,
+ 0xd8747f3f, 0xb66a3d20, 0xb8d957ef, 0x1a98f8a1, 0xb546afde, 0xbf097438,
+ 0x867e8e5f, 0x2a17f2fc, 0x7de3fdd2, 0x1b911b12, 0x5eeb9f07, 0xf1197b25,
+ 0x74147444, 0xa59ba01a, 0x05d0037d, 0x2741abf5, 0x4263fbeb, 0x6f3fb1de,
+ 0x4bf3f111, 0x907dc53f, 0x387c3adf, 0xbe97aaff, 0x7c79c1e9, 0xbe7234a8,
+ 0xc32dbe7e, 0xd956e30f, 0x953a1983, 0x0bd579fc, 0x5b7e22df, 0x195bf474,
+ 0xfe60bf14, 0x0ad91b2c, 0xdf9c2cc1, 0xd3b7b5c2, 0x80592afc, 0x79eaaef8,
+ 0xabd702b9, 0x633614cf, 0x78b91c7b, 0x87c5c844, 0x80f1c1eb, 0x0b887df9,
+ 0xbc0bee07, 0x06de5321, 0x7c520f63, 0x7ec65be4, 0xf5425b0e, 0x4e9c9ccf,
+ 0xefc315b3, 0x96279585, 0xecae375f, 0x1c9cfa46, 0x71811fed, 0x04a606df,
+ 0x73a43e05, 0x747cafd0, 0x1f4e08fa, 0xc44a55e6, 0xa7efa077, 0xdf6c73e2,
+ 0x8abbf76d, 0x73b1df4d, 0x2fe383b9, 0xdc03e315, 0x7ecf6849, 0x1f7f1198,
+ 0xac62b37f, 0xc5576037, 0x7c8c57f0, 0xf8df7973, 0x436f9718, 0x66b343de,
+ 0xbd3ffbe0, 0xbf07e5c9, 0xe0057b43, 0xf7a08c8a, 0x48936ffb, 0x2458381f,
+ 0xb46f5c9e, 0xbf36b90b, 0xe004f837, 0x1ddd7056, 0x7fec17e0, 0xec9fe118,
+ 0xf0d5cad8, 0x6cbe8c5d, 0x433cf1c0, 0x76e433fb, 0x87ff9091, 0xb3fcb314,
+ 0x13ee5cb5, 0xc2411bfb, 0xf43dad4f, 0x5e50e783, 0x1f713e41, 0xbd9b76ba,
+ 0xc9fde702, 0xb9bf83d6, 0x93e4e41b, 0x66a721b0, 0xd39569fd, 0xb0d71daa,
+ 0x09fa7278, 0x93c413a6, 0x571e7853, 0xf128b54e, 0xfe957ff1, 0x82f7f034,
+ 0x3e867f05, 0xab47844c, 0xf15ebc3e, 0xfaad3e12, 0xc9bdfe10, 0x9ff2864a,
+ 0xbf0677c1, 0x6ea8ff55, 0x019dea0c, 0x6ef834be, 0xbe0d2f80, 0x342f121b,
+ 0x3e886fe1, 0xf00cd8c3, 0x7feec549, 0x99fcc72d, 0x5f7c3dda, 0x843bbe14,
+ 0x9f93c075, 0x871d61bb, 0xd6c5a546, 0xd87a9643, 0xa96fded2, 0x07da5857,
+ 0x4b46f52c, 0x0bf710fb, 0x3caa0ebb, 0x6a62254f, 0x82ce5f6f, 0xef538c6e,
+ 0xd21e2995, 0xc0af3007, 0xb9ada4bc, 0x6863cc21, 0x5338f173, 0x02baba7f,
+ 0xde9f57f5, 0xb07b41ef, 0x73e3c5df, 0x9efd157d, 0xec3b18d4, 0xe9323dfd,
+ 0xcd8868df, 0x822fe788, 0x8bf44187, 0x79ef44b2, 0xacba7ddc, 0xf8c32ce5,
+ 0xc3ec874a, 0xe682cd90, 0xdfb83d3b, 0xff27b7df, 0x7cf03996, 0xb69911e1,
+ 0xfed0faf3, 0xfb34414e, 0x3f18ac95, 0x7c1623ed, 0xa38c06e6, 0xdafee1ef,
+ 0xbb165582, 0xbe22ad82, 0xaa96d4a8, 0xbfc117a8, 0x8fbcc0fa, 0x5abbf9c0,
+ 0xd6b557f4, 0xdef8defc, 0x37abe3f0, 0x8407df9a, 0xf9167fdf, 0xf1d2ed1d,
+ 0xbbf73c6c, 0x09378f19, 0x2e5d3afd, 0xe00e65ba, 0xccb0efbf, 0xef4e5f90,
+ 0xa7ff0991, 0x737df2b7, 0x8b5f9f8a, 0x7a4fda7c, 0x0f53c0cd, 0x589a85ca,
+ 0xfcecf4ef, 0xd023c95d, 0x3bd776a4, 0x6504ffc5, 0x0bb7aecf, 0x97f5867f,
+ 0x8779cadf, 0x753f6d0d, 0x2bf68b9f, 0x69b9f6fa, 0xef6fb17f, 0xc11e732f,
+ 0x8f876efa, 0xfdf6fef2, 0xa7f918b9, 0x0aa3b96f, 0x68df56f5, 0xecb667ee,
+ 0x947173fd, 0xa256c9d6, 0xee76e5db, 0xf3de9ee7, 0x6949efef, 0x70acc258,
+ 0x4c97dffd, 0x9f86b771, 0xd65e28ba, 0x25cff7b7, 0xa5fbf6b1, 0xec5ea7ce,
+ 0xd9b9f623, 0x5f081d9c, 0x697fdf2a, 0x1bb5d9f8, 0xa20f319a, 0x00fabf73,
+ 0xcffa9fbc, 0x3ea3145f, 0xedc1dbec, 0xf47b5e9a, 0x9b27dc05, 0xb962b6d0,
+ 0x8bd5e81d, 0x64fb8142, 0x0b2f3f6d, 0xf2f0f16a, 0x2f01c505, 0x8f7f1f16,
+ 0x9fff48f8, 0xf6890f80, 0xb8f76bbf, 0xe7094e43, 0xdef797fd, 0xcfb03d41,
+ 0xcc697c41, 0x337093f7, 0x9a171dd9, 0x6e57d577, 0x62e452de, 0xbff2bde6,
+ 0xedbbff39, 0x2acf825e, 0x7cf94307, 0xdf5443ef, 0xbc11f6e6, 0x9befc917,
+ 0xdf746abf, 0x5cf77401, 0xfe87de78, 0xc8fdd2c7, 0x3aee827d, 0xfc3499e6,
+ 0xdf0417f3, 0x2773d597, 0x3dd39bfe, 0xfb0dfcd1, 0xaf9b71fc, 0x6ce30f23,
+ 0x3ac3fd68, 0xb767b9ad, 0xf1efd863, 0xb475b3b1, 0x2fb16517, 0x846f8569,
+ 0x191ffdca, 0x5e3127f7, 0x3c899a37, 0xd10fee6d, 0xad0c1d96, 0x8f649568,
+ 0x6e0ada2a, 0x6ebe2b27, 0xf1e5e03f, 0x28fbe72b, 0x384d8787, 0xf67ac016,
+ 0x438a3e0d, 0x56c2fc5b, 0xb025f989, 0x6f2b9553, 0x8a7e8c3c, 0xe22dac7d,
+ 0x7df2a628, 0xf88a572c, 0x4d575da2, 0x64568bfe, 0xe6bcbbae, 0xe7f443ba,
+ 0x677e1c64, 0x9c610b26, 0x80e2be59, 0xf265f98e, 0x50498578, 0x208eb177,
+ 0x4c8e09fa, 0xc47ff7f3, 0xb898d364, 0x11ebda2c, 0xbe7fd7b0, 0x07c50375,
+ 0xfef8bd4e, 0xcd6fd8cd, 0x04e664cf, 0x756ef4bc, 0x8df208b3, 0xffd15212,
+ 0xfd94eea8, 0x523c8f3c, 0x3ecc6b72, 0xd62761a0, 0x704dd8fc, 0x8470ef55,
+ 0xd5f7c266, 0x4c5f7ebb, 0x7ef2f6eb, 0x2f8363b2, 0x3d4f3c4a, 0x7dc62d18,
+ 0x0e716abe, 0xf1a74ac0, 0xf77f8f2a, 0x839e4eec, 0x85b4bafe, 0x875649e7,
+ 0x623bb4ef, 0xaac64bf2, 0xf11da376, 0x1287f051, 0x7c20a9e5, 0x8679f9b1,
+ 0x43f3da9d, 0x65d7c389, 0x65be610f, 0xbded96f5, 0x3ea87718, 0xd9a1f0e6,
+ 0x53e5b0d7, 0xfd4f6b8a, 0x944f36f1, 0xe4d92cfc, 0xf7f10e77, 0xd744c8b6,
+ 0xb23acefa, 0xf44ea15b, 0x8fc70fad, 0x2fc85c7b, 0xdef1f9a9, 0x6140415d,
+ 0x7b364fcd, 0xb271ae30, 0xfc87937b, 0x8fe72dbe, 0xeff10cb7, 0xd79d8fc2,
+ 0x7f893bbf, 0xb774fd80, 0xb78ff16a, 0x15fb270c, 0xb7892be0, 0x4df065df,
+ 0x5ecfb6cd, 0xcf63f8c0, 0x405e4f8e, 0xfaff6b78, 0xfed017c7, 0x3a5cfb64,
+ 0xbc3443ee, 0xbf14aff8, 0x2a5bbe31, 0x87f7aee4, 0xd5ee299b, 0xf6357e0b,
+ 0xc3f7bbd6, 0x7a3ff41c, 0x0325ffb7, 0x7ba5e4fd, 0xf9c08fa7, 0x7539dd2e,
+ 0xbf238b04, 0x1b7c8946, 0x9bb888ba, 0x3b075e95, 0x7c9d920f, 0x7e8de80a,
+ 0x1ebf80ca, 0x0ff1e3ae, 0xb7d3f0af, 0x0e6f8fc6, 0x6f3bcbf1, 0x936be5bd,
+ 0x50fbb4b0, 0x3fd05c0d, 0x78e8137f, 0x6fd045f5, 0x5fc263eb, 0x53bf4f89,
+ 0xe9d007f8, 0x57f0aabb, 0xeb3efd04, 0xe7fdf85c, 0xf0e75df0, 0xe479fe84,
+ 0xc466f022, 0xfd57ef4f, 0x3728abcf, 0xf1447e3b, 0x4cdba410, 0xb6ef6898,
+ 0xee3072cf, 0xffbd91fc, 0xef579e3e, 0xad1fd1d0, 0xc916fbde, 0xa3ceef4f,
+ 0x22649f14, 0x06cbd98e, 0x93b8f1fe, 0xd86b85c8, 0xbd7ee6e8, 0xfdfa3fc0,
+ 0x173d0f5e, 0x63e73dfe, 0xe44fefc3, 0xf2a9bfef, 0xae23023c, 0x1df1b75b,
+ 0xd20f3fe1, 0x74829a4b, 0x71bcff7a, 0x3a0f0368, 0x6c7261e2, 0x5c7e2afc,
+ 0x29ce2065, 0xadc465e8, 0x5053e206, 0x4578c6cf, 0xc58b7a48, 0xebbd07d1,
+ 0xd7abdc78, 0x199fce6e, 0x678f0fa4, 0xa72adafd, 0x638b8ba1, 0x2ffe085d,
+ 0xea889f8b, 0x0c73c535, 0x8d9cf53c, 0xab4fc7af, 0x37fa9e3c, 0x902c87ef,
+ 0x9f21fbac, 0x75d63f22, 0xf3f2afbe, 0xcbbcfc04, 0xc8b7bec0, 0x5179ebf7,
+ 0x8ac878a6, 0xe3d241f0, 0xec617d56, 0x55e15997, 0xd54f5c1c, 0xa275f177,
+ 0xa43b8767, 0x073d3f41, 0xd73f1376, 0x455f7d6f, 0x96d0f33f, 0x9edca89f,
+ 0xeb83f2e2, 0xfe062844, 0x17f6979e, 0xcf1d78f3, 0x338eb63f, 0xd2f1c1cc,
+ 0x38fe27b0, 0x353f5b0d, 0x0c13538d, 0xf37f3cab, 0x549de3fc, 0x7f6277fc,
+ 0x0cedbb27, 0x864ef3f3, 0xf6f119e5, 0xeb133f67, 0x035e71a6, 0xb3ca4bd7,
+ 0x33cfca3e, 0x89237a4c, 0x1e9798f2, 0x9e0ef19d, 0xe20a5b8b, 0x6760f68c,
+ 0xced3e733, 0x428ff07f, 0xbd1e777a, 0x6a75c65b, 0xc637e217, 0xb3792c2e,
+ 0xf41baa71, 0x15bbc942, 0xad5d9093, 0x31f266fa, 0x187e099b, 0x03ae0467,
+ 0x9e0fd0ad, 0x27fcc02f, 0x94f64784, 0x647840cf, 0xe2bba6dd, 0xb5da95e4,
+ 0x36f3ca0a, 0xe6ebb5fa, 0x76766e3c, 0xe9fb17a2, 0x0bc8c2bd, 0x3c4148aa,
+ 0x3b7dd67d, 0x29159d2f, 0x99d679fa, 0xecbe848f, 0xef01f269, 0x581673f3,
+ 0xbdf9106f, 0xd20e7b55, 0xb0aaa2b9, 0xaf80bcc4, 0xe483acc5, 0xaa4766e6,
+ 0xdb335bc8, 0xfe7bd50f, 0x7757da85, 0x2c35f6f2, 0x3cf1ed4c, 0x1f24c446,
+ 0x07762d13, 0x913eefe7, 0xa67b51d7, 0xf6624584, 0x7c13ef71, 0x9ba4d3db,
+ 0xc22d7bf4, 0xa939e1a7, 0x2ea71a6e, 0x8e34dc3c, 0xcceeaed1, 0x93122c75,
+ 0x74a7547f, 0x9dd5bf13, 0x671a3bf9, 0x329abe40, 0xfb890f09, 0x7b82651f,
+ 0x2629ffb0, 0xbffb0778, 0xe6b5c681, 0xe6ce6677, 0x5bacc271, 0xce341979,
+ 0x852654bd, 0xb76f005a, 0x0e25816b, 0x5ee99f68, 0xc32afb9d, 0x285356f3,
+ 0x8761fa3f, 0x8cde50a4, 0x4a759f38, 0x583682d7, 0xd6d39f6f, 0xa303753f,
+ 0x707f813c, 0x2793135c, 0x3e7422c0, 0xe43768d3, 0x208f25bd, 0x15013f1b,
+ 0xf2f80b28, 0x68c11e45, 0xb4f3a516, 0x3cfcdd6b, 0xcd2d18e0, 0x106fdf86,
+ 0xde71be76, 0x40f9c86f, 0x0bc0b9cb, 0x9b4c079d, 0x18e0fa5a, 0x396f631f,
+ 0x798a9d3e, 0x967769e2, 0x83a51f6e, 0xa652c1df, 0xe9737d51, 0x97a82cf8,
+ 0xf5e16fb5, 0xcf8e975f, 0xab957a81, 0x246bd793, 0xb35fabca, 0x60b4c172,
+ 0xe5e825d1, 0x252300db, 0x11bcbd26, 0xe2aa71e9, 0x7a163bdd, 0x5fa14f31,
+ 0x1565f8e5, 0x14f46ed8, 0xed6cb78e, 0xa788eddd, 0x3368b631, 0xefef93ea,
+ 0xea2a73fd, 0x09d32f71, 0xd56b3a3f, 0x68f07e91, 0xe4f3b9ca, 0xc2f359c3,
+ 0xa5d9fe0c, 0x1c227605, 0xd2c7f36d, 0xaae7bc39, 0x1fd13826, 0x6cf2235c,
+ 0x0fc81d9e, 0x7ef1e7e4, 0x75fbe0ee, 0xeb0f2299, 0x29b9a3f4, 0x0fa3cec3,
+ 0x5dbb321a, 0x7d5c0c4a, 0xb3ed3f4a, 0xff7d9df7, 0xc49bcc3e, 0x759c6a7a,
+ 0x37fbf065, 0x93c90a5d, 0xe981ff39, 0x0b5fc469, 0xde217f04, 0xf879319c,
+ 0xcaa0e48b, 0x8874c3cf, 0x8e9a6ef5, 0xb58297f3, 0xbeabb9f2, 0x68169e3c,
+ 0xcf90f781, 0xbc8871df, 0x34be711b, 0x7be33ce6, 0x79eb4788, 0x8a8e8dc6,
+ 0x55977e28, 0xe5072679, 0xa27ce06d, 0xf48591d4, 0x64779eb3, 0x9e2dbf4a,
+ 0x9c5eb11f, 0xf7044c77, 0x3e819d8f, 0x9fef3f1c, 0x830e3bbd, 0x40bd5fdc,
+ 0xe7ca61f5, 0xa526cbd5, 0x215cfc2b, 0x820d05d9, 0x5c6d32af, 0x1887b03f,
+ 0x39f6d3ed, 0xebfa3f24, 0xc9d4df7d, 0x305ec80e, 0xbee6fc93, 0xe630dce4,
+ 0xc23df513, 0xfd8297cf, 0x8f7ca120, 0x711293de, 0x3f3e4879, 0xe7e7c8b7,
+ 0x3cc97b66, 0x6f39df6e, 0xd3fa9457, 0xc8607f45, 0x0f9e0c67, 0xfaf993ee,
+ 0x25e4d7de, 0xe0b34638, 0x2f13b47e, 0xd38f3c76, 0xf017fe7c, 0xf0633baf,
+ 0x811c740f, 0x426734f5, 0xc6708e3a, 0x1cf5a3a1, 0x204711ea, 0x587ddb1b,
+ 0x86056879, 0x4fe7ac5e, 0x42cc1299, 0xdbe9593c, 0x6b3c74a0, 0xec662987,
+ 0x16ec94f9, 0x2f577e83, 0xc32ba5f3, 0x8b1cf44d, 0xe7bd5e70, 0x6dc21b53,
+ 0x527bf1d0, 0x8277bb7c, 0xd667af93, 0x44e632f1, 0xed38816d, 0x5095978b,
+ 0x499f807f, 0x8f5cfc16, 0x14e29af3, 0xfc50c2eb, 0x2fed8f5c, 0x8bfe3f02,
+ 0xc7e18fc1, 0xae3908d5, 0xa0277dc1, 0xb3bc1ff3, 0xdc60f233, 0x3e235972,
+ 0xa649bc5d, 0x9fb42db8, 0x28319599, 0x6daf8bf7, 0x7e076fdc, 0x44bcfc59,
+ 0x9c40b4fc, 0x9c44ff2f, 0xefe6b13f, 0x9209ce55, 0x1e70bd9e, 0x46f4885f,
+ 0xf3f316cd, 0x7fc29dbb, 0xca1cb374, 0x47f715cb, 0xad7f82c8, 0x09ad3ff8,
+ 0x6a905eb9, 0xc7a5676a, 0x299b46e8, 0xea6b3c0f, 0xd7e43f40, 0x6fbcda67,
+ 0x17edfc51, 0x20f18676, 0x293692bf, 0x2498f882, 0x4b7ec34d, 0xfd197c85,
+ 0xb666598d, 0xe68372eb, 0xedf979f3, 0x9779f3e6, 0xb5348c75, 0x9e4d7cbf,
+ 0xa115fde9, 0xafef4d2b, 0x54c132da, 0xcebe171f, 0xaeeafed4, 0x7c7d5332,
+ 0xfb5346e4, 0x9b678789, 0xdf74d7ea, 0xf93f6a6d, 0xfbd37cd8, 0xa6d5a36b,
+ 0xb47fd7f7, 0x5aff54c4, 0xb531ffff, 0xfae42c8f, 0x665340eb, 0x7c98f1f6,
+ 0xaa0f03e3, 0x3f9f1d36, 0x8bd36858, 0xf8679f63, 0x9658c5bd, 0x4e9fd1f8,
+ 0x3aa767a4, 0xd763b2b3, 0x376652f7, 0x4ea99fe9, 0xf0643d73, 0x0bf00e4b,
+ 0x45937f10, 0x6dbc80ef, 0xd5193941, 0x983b4378, 0xe2e46ca1, 0xa7941482,
+ 0xc5f9f1a7, 0x9236d9c9, 0x9d08fab3, 0x0e738f8b, 0x17356dfe, 0xf7482ef9,
+ 0x2e1980a1, 0xa33100ca, 0x9606e60c, 0x29060b0a, 0x28f99cd9, 0xeebad2ef,
+ 0x15bdeb1b, 0xdc9c071f, 0x6178701e, 0xdfd9379d, 0x645fee21, 0x3129731e,
+ 0xa8f590f8, 0x1ef0eea9, 0xd77fe2d6, 0xeb2e7a6d, 0x69754cc7, 0xffca4cd1,
+ 0x3d970449, 0x1b4dfe73, 0xb3d9bf41, 0xcf1a5402, 0xe2d8e6db, 0x9d45f7e6,
+ 0x9de79717, 0xf10bbed0, 0xfb18a5fc, 0x39748a2e, 0x33c6f695, 0x3f56af98,
+ 0xeffc9fb7, 0x3f59872c, 0x237dd60c, 0x97963e78, 0xf9d4279f, 0xda9b6b9f,
+ 0xdf75c26f, 0xb7c2e798, 0x7e606767, 0x7f027642, 0xe7c5c73c, 0xd55342f1,
+ 0x8cf00b4d, 0x2589da09, 0x73b2e783, 0x68e50d22, 0xf9118d7f, 0xe2d8cfd4,
+ 0x759d3de7, 0x047b7f72, 0x13b4682a, 0xcb3f7e34, 0x3d77caa9, 0x2455b298,
+ 0x7f22ce07, 0xbbbabfce, 0xf65f9f84, 0x7c3cf265, 0xf437e09d, 0xf1568e5c,
+ 0x1cadea0c, 0xb9bcd730, 0x3119e143, 0x2e4662b7, 0x661d6fbc, 0xef5469f3,
+ 0xf05ce897, 0x870d8ca3, 0x957fadf6, 0x03d6be09, 0x905e52d7, 0xda1805aa,
+ 0x993cc6e1, 0xf63037c8, 0xbb4b3e11, 0xd6d4fc8d, 0x05ce072b, 0xb55bf231,
+ 0xf7ec6e8a, 0x0858bc33, 0x932d69c6, 0xb473ef4c, 0x010f078e, 0xc99d951c,
+ 0xd6549714, 0x967e4cdc, 0x69e1c99a, 0xd962417d, 0xe3c3c112, 0x0f8e1ee6,
+ 0x42ea83c0, 0x3f73fb3a, 0x869319b7, 0x2a2975f7, 0x9d1ceb9d, 0x8d719e20,
+ 0x5b7ebf01, 0x9709d906, 0x5795e19b, 0x21e0fd3f, 0x89d903cc, 0xfde11637,
+ 0x3d04cb22, 0x4b6df3cd, 0x5dcb7d9b, 0x4de5aed0, 0xb800c999, 0x30d8ca37,
+ 0x0a1c879a, 0x41b7c1c5, 0x1afb802f, 0x535e5b84, 0x15ccf34e, 0x74045e74,
+ 0xd32575c6, 0xe8833156, 0x3863619e, 0x37fc2b4f, 0x7fdcb8b8, 0x790ba5cd,
+ 0xe369bcad, 0x90172c70, 0x9b5e81bc, 0xba97fd86, 0xd311da12, 0xdbf4715c,
+ 0xa8ffee85, 0x087dd39d, 0x136fd94b, 0x61636d76, 0xfa0cbdac, 0xd7ec16f0,
+ 0x8f29cba8, 0x17bf6316, 0x141bbbb2, 0xee617b5f, 0xb432ed85, 0x0cff90c7,
+ 0x39e60c7b, 0xcfbbc70f, 0x31ebd665, 0xeb9e7c7a, 0x4ac9ece2, 0xdde1f76c,
+ 0x12f6b891, 0x1bb271e8, 0xfaf8d5d3, 0x1e82fbee, 0x28caba0d, 0x3ec1302f,
+ 0x5c5d77d1, 0x4ff3adae, 0xc85ddeb4, 0x611bc8ef, 0x14ec07ee, 0xa5583ff2,
+ 0xa756fb4a, 0x58f75d1f, 0x68fbe621, 0x9bc79479, 0xcb519fa8, 0x0f3f20de,
+ 0xe204f9f0, 0xbb5fc0c1, 0xc69e7f85, 0xc5d6f1f7, 0xcda7c05a, 0xd70ecf84,
+ 0x7f9fd845, 0xf328b9fb, 0x815e9e79, 0x0ffbd077, 0xf5b83e92, 0xb38c12bd,
+ 0x39fedfd4, 0x79bffde9, 0xb8e6399c, 0x802f1181, 0x9c716a71, 0x2aff5bde,
+ 0x8a51bae2, 0xbcecb647, 0xab07ee9c, 0x49f4332b, 0x45ce93a3, 0x7d11e766,
+ 0xf872ed4e, 0xc353ce11, 0xd4ec5c78, 0x3087c9ae, 0xd349f32e, 0x73d8bce1,
+ 0x3a5ea759, 0xfe87625a, 0x5a38ed4e, 0x0f5e90a2, 0xf78cde11, 0xa5fee775,
+ 0xe377fd04, 0xdf00c1fc, 0x4bafe339, 0xf9fc16bf, 0xf180f165, 0x525fda78,
+ 0xcf68b3d8, 0xd6a5e00d, 0x2a7ff79c, 0xc412bdf9, 0x13ffe603, 0x463c045e,
+ 0x8bb57bbc, 0xa45a9fc7, 0xc6e31060, 0x54f7522d, 0xff06d38c, 0x4073a317,
+ 0x9256b799, 0xcc3dfe99, 0xd61abc03, 0xb7db0ca1, 0x3e667db1, 0x750b9b1b,
+ 0x111d2bc7, 0x1dd49f7c, 0xed42bca6, 0x4b047758, 0x8fdfb44f, 0x47fa86db,
+ 0x6f2c7efa, 0x86ff02d7, 0x0feb0fe3, 0xfdf2815e, 0x3313058f, 0x4ca12631,
+ 0x62f61df5, 0x852ce21e, 0x7d3a6dee, 0x2275a658, 0x3d739663, 0xa8ceff3f,
+ 0x5eedccfe, 0x9392375a, 0x81e9f38c, 0x15575c5c, 0xf611fa56, 0xf815d5bb,
+ 0xc33ff904, 0x08785dd6, 0xfb1d73be, 0x79e60e6d, 0xeda2f71b, 0x8fd8ad2a,
+ 0xbbfdc6fb, 0x367aef25, 0x9c9f6e34, 0x28dfe5c4, 0xbe3527bf, 0xc961f98d,
+ 0x63a7db8f, 0xae7bebbc, 0x0547ba46, 0x999df9fe, 0x702b9fd0, 0x71854b0f,
+ 0xc66da924, 0x876ea0d7, 0x7bf1e3f7, 0xd02b5b5b, 0x606a5761, 0xbbde0d94,
+ 0x87ad73a5, 0x8dfc3df1, 0x49c965f9, 0x9ef15ae7, 0xe7493538, 0xb902d0f3,
+ 0xba818748, 0x4c77750e, 0x2ba969dd, 0xabcc6ebc, 0x285fe0ee, 0x0f7eb3ef,
+ 0xef07d7bf, 0x337dc333, 0xe50cb7bc, 0xe849353f, 0xb1698d09, 0xdacea1e7,
+ 0x3c49e902, 0xe5c8593e, 0x265f88c4, 0x97e22f78, 0xe291ac85, 0x60f1236b,
+ 0x5bda3e75, 0xb0e654dd, 0xf88d2a7e, 0x51f31e5b, 0xa82ac059, 0xa83acb1c,
+ 0xa98592bc, 0x54dd622c, 0x2a7eb316, 0xb1974c7d, 0x547cc09c, 0x8f1ad9a6,
+ 0xf97d474e, 0xcbe93b0b, 0x1e0f2dc2, 0x0508c918, 0x6aa5ba26, 0x69867e5c,
+ 0x2864a1a5, 0x80388b57, 0x16a9ae71, 0x3545e669, 0xd07d90a0, 0x93ea6423,
+ 0xee20b635, 0x2ab9b29f, 0xe715af3d, 0x3edf6b80, 0x27e47640, 0xaa79f8fe,
+ 0x4b949353, 0xeb3287dc, 0x1ab586c7, 0x73e41be1, 0x1ebbe22a, 0xcdba82e1,
+ 0x1ee74dd9, 0xdfc3cbed, 0x745f7196, 0x45f69d9b, 0xa026506b, 0x0c2ee35e,
+ 0xa7984b35, 0x9f6a515b, 0xf24d7c44, 0xce1a9353, 0x9e0da098, 0x78fac407,
+ 0xebdf906d, 0xc1ca9ebb, 0xf78ff67d, 0xf9eb4dbf, 0x34b9c9f5, 0xa3ceba9f,
+ 0xfb4dc06a, 0xcdca2a76, 0xf603e9c7, 0x6d8dd937, 0x9e0a5f2e, 0x25ffe93b,
+ 0xc0ca8fbf, 0x7e95f7df, 0xc7beec57, 0x745026e1, 0x37af632a, 0xabf95265,
+ 0xbf952f26, 0x1f99d268, 0xf623b91c, 0xe11136a8, 0x11d02f4d, 0xf0f44fde,
+ 0x612663eb, 0x179e7b1e, 0x7692d3e7, 0xd444d57c, 0x77d93e3f, 0x77638c19,
+ 0xf7849f2f, 0xce64b627, 0x95947ca6, 0x1fe704da, 0xc5169e00, 0x71874ce7,
+ 0x6876d35f, 0xd3794197, 0xb89d9317, 0xd696bfae, 0xdf7179a9, 0x3aedfc64,
+ 0x7f4103ee, 0xfea56fab, 0x09bfa2ec, 0x18ff6c4e, 0xf60da3f6, 0x6fd45fb3,
+ 0xc348ef72, 0x189a87f7, 0x7a537dc1, 0xf7f61a67, 0xaf85a2f3, 0xdf84984f,
+ 0xbbdee2db, 0x3499d374, 0x67bb07e6, 0xe61c99e6, 0x737af587, 0x2895e359,
+ 0x9a4ddfff, 0xf904e6d6, 0xab1b7257, 0x4dac5f51, 0x09cdb9ba, 0x3653efc6,
+ 0xf54e93a0, 0x0015dae9, 0x1fae34c7, 0xbc36f200, 0x659ed06f, 0xfc3af8a3,
+ 0x8e5eeba3, 0x8eb8fea0, 0x2d969fbf, 0xfda010f2, 0x9f9fc7cc, 0xad57768e,
+ 0xe962f9c4, 0xd3ee8ced, 0x544f6448, 0xf3a2499d, 0x7afd4679, 0xf31104ba,
+ 0x8fb483d8, 0x43c67552, 0xbe2efae7, 0x1ce9a73f, 0x34fed0e0, 0x95f0ef1a,
+ 0x29f93f06, 0xbb74b36e, 0xf970cfc8, 0xefbb6047, 0x83f98dd9, 0x7c44edbd,
+ 0x0a83d40d, 0xaa23dbe8, 0x6df9ff31, 0x6e7f40d3, 0xb3df0756, 0x658f9829,
+ 0xf47e67bc, 0x89248f87, 0x7e3ab07a, 0xfb4b24fb, 0x4dfea33c, 0xe7856f6a,
+ 0xbac1ae7b, 0x5f2bda13, 0x08ea0638, 0x4b3653df, 0xf18cc37f, 0x6afea11f,
+ 0xbed16572, 0x12bf55f5, 0xaae0ef43, 0x667bd2f3, 0xad6dd3d2, 0x9011fdf0,
+ 0x6ebf5a73, 0xa17eb467, 0xf462f9dc, 0x6eb14ce0, 0xd2b99d55, 0x3a418f44,
+ 0xfee89b14, 0xec65c821, 0xada2eb3e, 0x2173a4df, 0xbcbc9333, 0xe7e4161f,
+ 0x9be6d69c, 0x3fff57f6, 0x1c2b7f1c, 0x4c7004fe, 0x63862ffb, 0x41bc69ac,
+ 0xf04c8a38, 0x51c3e7fd, 0xf28e0096, 0x561c14af, 0xc728c57b, 0xf642bda0,
+ 0xb0f38f2a, 0xb7b236e5, 0x151552fb, 0x369897f3, 0x5204ec85, 0x8eea5e19,
+ 0xf146f1f6, 0x8f7799ae, 0xf3b61e63, 0x995dac2a, 0xe82afa80, 0xed7dc3cc,
+ 0xe07ef16f, 0x740561f9, 0x2754e8d0, 0x177b47ed, 0xfc60d454, 0xb2a73bdf,
+ 0xf1bd4a8e, 0x33ffbc16, 0x3c7fa0a7, 0xb4eb77da, 0x98db17b4, 0x6905ef49,
+ 0x241e97dd, 0x13ee76bb, 0x2c94dadb, 0xcf8d9bd4, 0x052c1da2, 0xce1db5b7,
+ 0xeb9ef78a, 0x5f927bad, 0x542975a2, 0x3f44aec6, 0x850ae428, 0xda3d200f,
+ 0x23d21f34, 0x7b5089f7, 0xc795d41e, 0x8066be6c, 0x6d0d4957, 0x2bf00f59,
+ 0x9afa164f, 0xf5087de1, 0x527fb61f, 0xab3de109, 0xd9bc9a2b, 0x8b49bf78,
+ 0xb7d68fb0, 0xdf31d4ce, 0xb30a9ed8, 0xb0ae5204, 0xf685de37, 0xd7e49afa,
+ 0xe2d79cdb, 0x1f6be07a, 0x267af3ae, 0x8f39b5c0, 0xc55339e5, 0x437f587b,
+ 0x1ea46ccd, 0x7f4af753, 0x5fbcf995, 0x80dff36f, 0x6a92fceb, 0x157fbfc6,
+ 0x879b95e3, 0xefe17819, 0x5c7531bd, 0xc1e6944f, 0xf79834fa, 0xbeb9e786,
+ 0x47fa147f, 0x13e61f7b, 0x1c6e3b24, 0x8c324f9f, 0x2710f78d, 0xf5a3cf8f,
+ 0x8beb0435, 0x578fdf07, 0xb1963ce8, 0x671ce3bf, 0x6c1dfda3, 0xdce4f58f,
+ 0x73ffda3c, 0x08be62ce, 0x6966ede6, 0xf150bf7c, 0x38fcc34f, 0xf8bf00f7,
+ 0x8aa8de29, 0x926d0ffd, 0xa93fff79, 0x39b4bbf5, 0x7e64549e, 0xd7302cee,
+ 0x1f37cc1d, 0xb66a9683, 0x592879f9, 0xb387efc4, 0xe457e891, 0x6c3682db,
+ 0x510b0577, 0x908b1579, 0x458e3f5d, 0x86357ea9, 0x38f1f33e, 0x700e9794,
+ 0x997e644d, 0x642b47c7, 0x68163bf4, 0xbf68cd81, 0xfe164c6f, 0x6fde48ca,
+ 0x77c1454b, 0xbe297ba6, 0xc5e519b1, 0x559eafa8, 0x448df14e, 0x3c69a5f2,
+ 0xdee2388e, 0xfbdef382, 0x8f8cf539, 0x3ce46379, 0xbb79e35d, 0xba31b70d,
+ 0x0f61a28f, 0xf78ca3f7, 0x7ef324af, 0x2fc4121b, 0xc15fae41, 0x459f7c79,
+ 0x74b9edcb, 0xd3dfc9cf, 0xda8fb03d, 0x17548218, 0x6dfb9b79, 0x513b7b16,
+ 0x92cfd91e, 0x80f2fe79, 0x18fc235f, 0xce9035f2, 0xe0597fc2, 0xbe6ee832,
+ 0xc7b8c1cf, 0x4dc84fa1, 0xc44aa55f, 0x09834068, 0x05b7e9ea, 0x4a801ee8,
+ 0x35ca9f31, 0x1fe819a5, 0x177fd82c, 0xf570b9c1, 0x0e30352c, 0x23cdc9cf,
+ 0x5d7818bc, 0xfe0ff160, 0xbcf131d8, 0x9ec332f1, 0xc303fc36, 0x09fab01f,
+ 0x71bfbe89, 0x43a27eec, 0xed296679, 0x7b237edb, 0xc0eb0d96, 0x4fbc7e6d,
+ 0x78af38ca, 0x9feecec4, 0x6439445d, 0xb3f9f033, 0x550f7e2e, 0x7543dc48,
+ 0x0c3f9bd8, 0xff919bbf, 0xbe5815c5, 0xa86b0ce6, 0x7b3b5fb7, 0x1ff266f4,
+ 0x7986b094, 0xee14a717, 0xc67519ff, 0xbf14c8ce, 0xc9bf7817, 0x8fdd06fd,
+ 0xefee5370, 0x9d78bce8, 0x573a0dfb, 0x4ed3aa7e, 0xb9377279, 0xf7b169c2,
+ 0xbb94dc67, 0xf87ced37, 0x2387fc31, 0x79c3de02, 0x6804e49f, 0xe19f915c,
+ 0x4b9d20df, 0x35bdfc4e, 0x471ae33f, 0x61f23759, 0x5dd7e0b7, 0x8345205a,
+ 0x21766db2, 0xacda4fc9, 0xbfde4e49, 0x94247f39, 0xc57c44cc, 0xff0647cc,
+ 0x5905ef59, 0xe873f12a, 0x386ae089, 0xafad3363, 0xa884f783, 0x8af6beb4,
+ 0x26774378, 0x907afa7b, 0xd1ac5997, 0xe26ffb4e, 0xc916957e, 0x313d476b,
+ 0xdfb96fcb, 0x5551e447, 0x2df0f588, 0x6a051f91, 0xe63f55f1, 0x7d3f3175,
+ 0x63ee2dd7, 0x8f602c61, 0xfd023f97, 0xaddaf49a, 0xdbf5cc33, 0xeb75cc2b,
+ 0x1e46863d, 0x7a4d2bcc, 0x5d3dec76, 0x87e812d3, 0xa5db351b, 0xcd1a0fc5,
+ 0xae2303f1, 0xc3f98757, 0xe3c2cfb4, 0x7c9dd37a, 0x8b88b2fc, 0x341a2ff6,
+ 0xb8861d75, 0x3de19f51, 0xae35d3f6, 0x845e306f, 0x574d04f7, 0x436dfb8c,
+ 0xef939f22, 0x6457a47b, 0x7dfdfb8a, 0x54af7499, 0x1ce99257, 0x386711ab,
+ 0x494de05d, 0x3b7f0f3d, 0xad70d8d6, 0x54afa818, 0x07c89d1a, 0x5e79b32b,
+ 0x871f20d5, 0xc754f14c, 0xfdee351a, 0x80fd0372, 0xe273c15e, 0xdb6fb12e,
+ 0xd8f5f8ae, 0x5ec38478, 0xda7f23a1, 0x5edd65dd, 0xab55e5e0, 0xabc72cee,
+ 0xbf305a0b, 0x4694ec17, 0x822bebed, 0xed3b4fe0, 0xaf78c3be, 0xf36dd3af,
+ 0xacdc7ae2, 0xab3f68d9, 0xeb49d325, 0x56a90aef, 0xe8d2f5c7, 0x685519d7,
+ 0x3cb5a73e, 0xe0897fd2, 0x669fc153, 0xbe631fb4, 0x6f3fea8f, 0x0dda8d3c,
+ 0xe0eaffb9, 0x756714b5, 0xff946d79, 0x746816a4, 0x5fc19a8f, 0x6b9c7ed6,
+ 0x24fdb894, 0xba427fc2, 0xd794a3db, 0xdfc5abd6, 0xbb497e5f, 0xb9eebcc4,
+ 0xea777896, 0xf8230a6f, 0xe0f514bd, 0x8f902eb9, 0xab8c3497, 0xabfd3e8d,
+ 0x47c92f52, 0xe1afcf06, 0x2da2db72, 0x5fbcf277, 0x89693df3, 0x4bc0d1f8,
+ 0x47283c22, 0x4fdc51fe, 0xfab1601f, 0x563529c6, 0x68e1bed0, 0x138a6d85,
+ 0x5cdc514f, 0x3e28b74f, 0x6bf95fe2, 0x075c4e15, 0x9ccad39a, 0xa6df9fb8,
+ 0xd1725378, 0x33223c3e, 0xeab59b8c, 0xca31b966, 0x4f7ef1c7, 0x8898e380,
+ 0x27df5a8b, 0x380bc825, 0xc7f5d627, 0xeddb5ff7, 0x009f0f3f, 0x491e68de,
+ 0x7a8e8a79, 0x7873b641, 0xed7dc593, 0xc44dfa89, 0xe7ec4f1f, 0x8abbe0f7,
+ 0xca8e749c, 0x38ab5e3a, 0xf00ad72f, 0x9adb9da0, 0xbee3e30d, 0xc9d157b8,
+ 0xc49b1e8e, 0xa17c319c, 0xf7a24ea4, 0x3c34b5a7, 0x135ac7bb, 0xa7819df0,
+ 0x1f552ed7, 0x97fc2c07, 0x978a5bfe, 0x5fdff0c7, 0x6bdff1e3, 0x1ce973c8,
+ 0x2d7bd8fe, 0xbfbe5495, 0xc8d78567, 0xdb6677af, 0xc04bed4c, 0xa371e0b7,
+ 0x032a1cef, 0x50311cd6, 0xf1870607, 0x71cf513a, 0x74e22e7f, 0x714fb60e,
+ 0x55bca77f, 0xc39d3aa1, 0xebfcef83, 0xf74f6a34, 0xcea1d4d9, 0xf6aa3f07,
+ 0xb0e98d4e, 0x4bd59f3e, 0x6f00ddd3, 0x7e01f749, 0x9d33a61e, 0xf88b5eff,
+ 0x8def0ade, 0x1bf74e1e, 0x29953a3d, 0xc23ffcc7, 0xece83fdf, 0x1c62f24e,
+ 0xfc5873b7, 0xcc7883df, 0x742fe46d, 0x28c8fd88, 0x4fa44bed, 0xff51ebe5,
+ 0x8ff264ee, 0x99a7e286, 0xb16177df, 0xc1ee0637, 0x77642250, 0xc3bb0ad4,
+ 0x2e64bf18, 0xf287aff3, 0xeed624d5, 0xca70fb04, 0x15dff8c0, 0x47802dfb,
+ 0x9f96fb80, 0x4ffb455d, 0xc2af7f46, 0x33ed84b2, 0x92c5a232, 0x13fc097c,
+ 0xcefba666, 0x42d19cea, 0xd97b1fdc, 0xf88e9816, 0xcd16386e, 0x1be77ac0,
+ 0xbc1ec927, 0x72ee1e10, 0x7b9a7d73, 0x479f6195, 0xeb38d8d4, 0xe7a5edd2,
+ 0x8b570f3d, 0xfd1890f1, 0x72b78836, 0x7e90ebc2, 0xe8af3fa1, 0xe92be31f,
+ 0x3ae9f12d, 0x2c919f48, 0xf47cfc38, 0x89c161c9, 0x22a12e9c, 0xe7dc7f4e,
+ 0x5d937983, 0xf59b741f, 0x8afeffc9, 0x130d37cc, 0xd29f80d1, 0xbef3c4a1,
+ 0xde2cef78, 0xe3c4bb8f, 0x693fad35, 0x1d457b0a, 0x4987c316, 0xfa84e82c,
+ 0x4be88e2d, 0x7518ff68, 0x0e2dfde3, 0xcfec69e0, 0x90c8e5c9, 0xf1b9dadf,
+ 0xedc736e5, 0xc74df9e1, 0xf7dc1e22, 0x03e38e98, 0xbfc33bbe, 0x3ac77ba7,
+ 0x3f8664bb, 0x6e62309d, 0x83680e40, 0x0fda1a74, 0xfc86abd7, 0x95793983,
+ 0xed3fc85b, 0xfee32ee3, 0x8c67a1b5, 0x6b725eef, 0x8b8fa697, 0x7af39c86,
+ 0xe408e509, 0xcb2e10ea, 0xbdf8cb39, 0x5ee2b577, 0x0f711e9b, 0xdfc207e2,
+ 0xaff73a60, 0x3eb07b8d, 0xf7c81c28, 0xd6af3f23, 0xde0effe5, 0xca8ec343,
+ 0x27fa6f94, 0xfdc29fdd, 0xd4bfb343, 0x31b9ee23, 0x66b6a5fc, 0x36736f71,
+ 0x4936e7e7, 0xf6167fba, 0xf74a363b, 0xf0646718, 0xa738d3f5, 0xf4a332c7,
+ 0x1f065a7b, 0x7fb3e225, 0x7a80f211, 0x8f97182f, 0xe32fe255, 0xeeb007f9,
+ 0xb5ec6305, 0xd0151ff9, 0x98079bb9, 0x0f97e28f, 0x60b327b4, 0x5f3b5e0c,
+ 0x732f9f88, 0x29db8c42, 0x456679ee, 0x7c835e7c, 0xb9d1e7ce, 0x0fdc3e3c,
+ 0xe8fe70a7, 0x7779f714, 0xc464fe2a, 0xe175a253, 0xf65e80c4, 0x2b1f2327,
+ 0x99bc1c5f, 0xc79af5c6, 0xfbf457bd, 0xe2cabfb3, 0x8f0004f7, 0x7b607f42,
+ 0x1762c7a7, 0xf0feb25d, 0x419bd69b, 0xbd234fbc, 0x43fae972, 0x48fe80bf,
+ 0xf2c2fa23, 0xe2bb41ee, 0x57bf30c5, 0xb6c3c5ed, 0xd0e3eb19, 0xe5c840ad,
+ 0xdd0ae995, 0x84557643, 0xda89fbaf, 0xf7130c65, 0x5a3c0b0a, 0x8fcb4be1,
+ 0x08b71fcf, 0xf196d43a, 0x9ef1917b, 0x942f9c76, 0xafe83e39, 0xd20b4ca7,
+ 0xbc8bbff3, 0xdad17187, 0xfe2f0e1d, 0x0ecf524e, 0x85ea1557, 0xaa8e1d9e,
+ 0xfa50daf5, 0x9bf42df9, 0xff8cec2c, 0x64bffae9, 0x2fe27fae, 0x4ba01f71,
+ 0xad1c7ba6, 0x76e93dfd, 0xfa0377d3, 0xe5dd813b, 0x2d33fa10, 0x9ec5d399,
+ 0xab4dd7c7, 0xf023dd5c, 0x67c08f76, 0x1e57b89a, 0xae2721d6, 0x39bb4643,
+ 0x0094fde2, 0xef3f7b8b, 0xfa570863, 0xecf03ae0, 0xfbf632b2, 0x7d3bf8e1,
+ 0x742b8a41, 0x839236fe, 0xf294f6fd, 0xfbf58138, 0x8c67c162, 0xc9e8ed99,
+ 0xfd12bcd3, 0xd258611e, 0x807edf71, 0x4f7e61de, 0xb2770af0, 0xc5a2cfb0,
+ 0xf73f92f7, 0x48a3f524, 0x0f1c50af, 0x0dbf366c, 0x0a7e88f3, 0x9e4c5b76,
+ 0xbd16bde6, 0xbe678563, 0x13b7cf9b, 0xa3f637f5, 0xdde38b45, 0x5bac60ff,
+ 0x86d3bcc6, 0x49e0e59b, 0x26c71f0f, 0x25974bc6, 0x6eba0f1a, 0xebe30c77,
+ 0xe60bcf31, 0x479e127a, 0xc80b39e8, 0xfaee00e3, 0xfc6fc5fb, 0x59ce7888,
+ 0x13d2b03d, 0x5da00763, 0xb095eb4e, 0xc6553bc3, 0x5d844bf7, 0x8274fa88,
+ 0x90770b16, 0x6d974906, 0xf12b5f5c, 0x43cc35f5, 0x9b897efc, 0x2fb419fa,
+ 0x4fb11db8, 0x389d6bcc, 0x8daafa3f, 0x21bd92b5, 0xe9c864f0, 0x6e9c8b4e,
+ 0xec357cf5, 0x77e275b4, 0xf17e912d, 0x614ae1f4, 0xf31c95af, 0x95bcc78f,
+ 0x1f342acb, 0xdd25a1fa, 0x9e600fb3, 0xfc1ee14e, 0x39419a61, 0x8cfc142e,
+ 0xc18dcdfd, 0x6e3cefdf, 0xe6f7dd93, 0x857f0457, 0x7cc0d8c7, 0xebd18def,
+ 0x7ae1eeff, 0x2dfc1d2b, 0x5fd38394, 0x785ebd11, 0x9e00e2ac, 0xba05aac3,
+ 0xf830caa3, 0x6f3c33a3, 0xe1ed0bb9, 0xf687cc63, 0x9e786f74, 0x47f01c6d,
+ 0x3f6e1aef, 0xd5f9e80e, 0x97a05f1c, 0x2f97a8c3, 0x2e4fe63b, 0xc296ba82,
+ 0x7365eef5, 0x2967bf19, 0x5fa10eec, 0xf489e86d, 0xe2a7fadb, 0x727d6f3e,
+ 0xe62bb363, 0x2efb40f9, 0xa83b9f68, 0xdf516a6f, 0xf3db1378, 0x79925323,
+ 0xc71e7b3e, 0xe664f4cb, 0xaf3c0174, 0xdc6506e6, 0xb2f57cc7, 0xaf7809dc,
+ 0x40a4a1fa, 0x7ef812d1, 0x0e3e0cf2, 0x2e8472eb, 0x47878dcb, 0x4433afae,
+ 0xe44328dc, 0xf124676f, 0xe70a4572, 0x979d24f7, 0x1f9ce9f7, 0xe3f13c32,
+ 0xbb44cb4c, 0x3bd71b3e, 0xb7c6978f, 0x914bae4b, 0x8b3ced2e, 0xdfc6b24f,
+ 0x17494baf, 0x06db6af7, 0x3fc1b5f5, 0xc677c427, 0xfc6265f8, 0x89986745,
+ 0x8d29167f, 0xce8b37c4, 0x8637c428, 0x3fe2245c, 0x1aeeff63, 0x14c6e047,
+ 0x9fa3f79c, 0x209c6315, 0xdf0f6577, 0xdfdfc237, 0x7cb136b9, 0x4181eb18,
+ 0x9df3d06f, 0x3d00cf18, 0xad0a693f, 0xfc8bcf43, 0x31a72e53, 0xf08ffa76,
+ 0xbb3b1df7, 0x8e6bccaf, 0x7ac0eba1, 0x8cfee3e9, 0x85195d75, 0x89e9c049,
+ 0x7298d5e7, 0xcaedfaa9, 0xf1787604, 0x5e1da97f, 0xe4813dd2, 0x578101f6,
+ 0xc466be23, 0x7897f0b1, 0x8ab3bdb9, 0x1a7931f0, 0xffc06f97, 0x22ff8156,
+ 0x1a7fff8e, 0x643dffc0, 0x79707427, 0x4bd688c9, 0xf45f24f9, 0x453bf19d,
+ 0xa0df27b9, 0x293dce7c, 0xa9df7fdc, 0xbe409ffb, 0xbbf2255c, 0xa888cf27,
+ 0x407b58de, 0x2ad17efc, 0x1af9c0fb, 0x591bc7ca, 0x0ecdfbcb, 0x189497ef,
+ 0x8596d1f9, 0xf9802cc7, 0xf9f15767, 0x9bb14dac, 0x5875a7d6, 0x485f2e87,
+ 0xbb2dfae1, 0x6015222a, 0x4a376b7f, 0x1237f40a, 0xf809877f, 0x0b236466,
+ 0xd0fefec5, 0x4f1f1f48, 0x07a485f3, 0xd3e7068a, 0xa4559b6e, 0xcf695e83,
+ 0xa0b5f648, 0x3606a4c8, 0xbed79f23, 0xf2fca11b, 0x2b76efc9, 0x9e5fc7e8,
+ 0xcf82dfea, 0x6578f98d, 0xbefd247d, 0xce1cbbf9, 0x32f7610e, 0x71e1cd16,
+ 0xfe0427ff, 0x887b0bd7, 0x23dfa61d, 0x94fdb8d2, 0xe9ac7cb1, 0xff0ce777,
+ 0xfa73fd07, 0xb599693d, 0x70a78a33, 0xbcb196fd, 0x834bec90, 0x57e7a61f,
+ 0xd3e7c46c, 0x01315c47, 0x5fc897ef, 0x77f05115, 0xd6ba7fa5, 0x94fef716,
+ 0xc01f4243, 0xcec7f63c, 0x6b7242e3, 0x9d27b3b4, 0x67936f9f, 0x0ddbb7c4,
+ 0x3e7d2c3e, 0x0fba6eed, 0xb86555b1, 0xffe064ef, 0x378ad4f2, 0xe1919e11,
+ 0x46e11275, 0x49c4678c, 0xcfca39f0, 0x9cf9aa07, 0x5cf9425e, 0x82cc63b6,
+ 0x556cf958, 0x2ceb3e89, 0xe86e13bf, 0xae14de8b, 0xad48efc7, 0x71f203f8,
+ 0x1453d77d, 0x91bc59b7, 0x424c1eff, 0xfe245cfc, 0x78cdde60, 0xf80d5dcf,
+ 0xa3ef7817, 0xeec89614, 0xf7c39dad, 0x72b76adf, 0x2aad657e, 0x1b5703dd,
+ 0x7f411ede, 0x7ea3d462, 0xd5a76e1f, 0x2d2edd6c, 0xa8ebc18c, 0x27e510da,
+ 0xe436ee5c, 0x2b19eb89, 0xd8dc63df, 0xc876fc05, 0x9eeaedc5, 0xff07ee52,
+ 0x7ac9083f, 0x0080006b, 0x00000000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
+ 0xd5947c79, 0x6779f0b9, 0xcc93324f, 0x2133df64, 0x61262201, 0x01161212,
+ 0xa0084933, 0x24584e08, 0x81ec36c8, 0x8bf628ac, 0x0c197e95, 0x6f62e452,
+ 0xb90556ac, 0xda544076, 0x1a080962, 0x88b0e834, 0x148d6ad0, 0x43b05b05,
+ 0x921088a5, 0x6f16b629, 0x79e7bd69, 0x799939ce, 0xf8b0ccdf, 0xabbf7ed1,
+ 0x9cce1c7f, 0xf3cf6cf7, 0x273f679c, 0x2d675a5d, 0x2ba42229, 0xcae6c229,
+ 0x9dbde424, 0x91488ee3, 0xe9769884, 0x55ae503d, 0xd034496d, 0x7483b5f6,
+ 0x4eda16b6, 0x62909b88, 0x8e35a242, 0x12cfd0dd, 0x92adb26b, 0x49eab108,
+ 0xc848d9a1, 0xeec4f1b0, 0xf0b7e5a6, 0xafad095f, 0x425cf5a4, 0xc1d334ee,
+ 0x293fa0e2, 0xc9089874, 0x9c709b36, 0xc3211578, 0xac39090b, 0x34432e25,
+ 0x8be0bb21, 0x89ac8411, 0xe399c472, 0xb10f1e60, 0xf196fed1, 0x4258f7f4,
+ 0x5b891a6a, 0x6cd5f3a2, 0xf423adda, 0x76847277, 0x6524224a, 0xd6f384bb,
+ 0x2d2cdf6c, 0x5e67bfa0, 0x075fb5d8, 0xa19357df, 0x7ab3f461, 0xd03b8d89,
+ 0x7180cf62, 0xf61c7b49, 0x9654eb13, 0xbd70b884, 0xe9b7c6c3, 0x0e38b9ac,
+ 0xbff4a3ee, 0x079f4ab6, 0x5666cfec, 0x9b3577e3, 0xa64feeb6, 0x626a91f3,
+ 0xefc56fee, 0xe6c5dff6, 0xff89e8d7, 0x675864fb, 0xa2e75b2e, 0xc4baff5c,
+ 0x2aaad7fe, 0xdfb4cd73, 0x5b08f8da, 0xb38b6d0b, 0x7ac18738, 0x0f3aa78d,
+ 0x61918851, 0xa73a3ca7, 0x77febfd1, 0xd1848475, 0x58c3877e, 0x15b352ff,
+ 0x47563ae1, 0xcebbf85c, 0xe3a56395, 0x8e17ee1d, 0x49b9bde3, 0xa4e01e35,
+ 0x2773270d, 0x3793f9d3, 0xb454956d, 0xe6411b1e, 0x23d6023a, 0x5cc7bbd6,
+ 0x062e6156, 0x1c227438, 0x706936ea, 0x473a15fd, 0xff5cf2f6, 0x2acc5377,
+ 0xf4c0f79c, 0xfa5e74cf, 0x7c6fd3fb, 0x6ba9f884, 0xb06dec95, 0x748fd6de,
+ 0xac00f2d3, 0x7893533f, 0xf6102642, 0x3e7b33df, 0xefe959d2, 0xfc337613,
+ 0xa9deedd5, 0xaecb4059, 0x1a4ba352, 0x303c780c, 0xaeace807, 0x24c24f4d,
+ 0x06739fc0, 0xa74943c0, 0x78841e02, 0x42be81d3, 0xe80233e1, 0x3aaa08a8,
+ 0x67a47f77, 0xfa64e667, 0xdd346b7d, 0x8ee811bf, 0xd91883ed, 0xbec10fef,
+ 0xc7e902e2, 0xafe60cb9, 0x801db708, 0x28515173, 0xac085ad9, 0x23ee18f3,
+ 0x31c19cb6, 0x79953d70, 0x0ab3d6c1, 0x618b89e7, 0x378d12f3, 0xe713e61d,
+ 0xd64d4e2b, 0xff7f4292, 0xfa578e26, 0x4efd87bb, 0xfcf239fa, 0x6de256eb,
+ 0x75c259ab, 0x55a7a107, 0x53dacf80, 0xa7a30f1e, 0x93d00d4e, 0x8fa0bf58,
+ 0xc6693657, 0x56e39e07, 0x6bc70eb3, 0x1d706b35, 0xa27e00cf, 0xe765a968,
+ 0x065599f2, 0x198ff237, 0xf9488f63, 0xebf72f14, 0xabbe503c, 0xed0b5f9a,
+ 0xf9b326ef, 0x0f54aad7, 0xa3ed7d40, 0xf882d246, 0xf0093fb4, 0x123d303c,
+ 0xa55b52f1, 0x38e9eb73, 0xb126bf4f, 0x26e8cbba, 0xceb59ff4, 0x1fa10ba9,
+ 0xbdb30d89, 0x1e737804, 0xf5334dd2, 0x3d2b27a5, 0xfbfa56f6, 0xce763684,
+ 0xdb6a1e04, 0xdd015d18, 0x5c39bc23, 0xcb74f0fd, 0xc7c08dce, 0xa333289a,
+ 0x00274a07, 0x616d9aef, 0x3606b3e6, 0xe804b7d7, 0x37ab22d2, 0xcf9927b4,
+ 0x35ebf8e6, 0x83a00ff0, 0x8648c4ed, 0x75f075d2, 0xee72a1be, 0x19d43c02,
+ 0x14b587bc, 0xfa4f43b5, 0xa2875cf0, 0x5fa69adb, 0x843b380d, 0x47896590,
+ 0x55e714b0, 0x47ed8fdb, 0xc70eff7c, 0xd250cbfb, 0xba730ff1, 0xc36a29a9,
+ 0xb67358f3, 0x71b1cf11, 0xc667e33c, 0x4d7e7253, 0xbf7c13c8, 0x8a9c71eb,
+ 0x6ab1b688, 0x9f8af70a, 0x1216e64a, 0x912e5f9a, 0x8e8da388, 0x83a6c5f7,
+ 0xbe00f391, 0xe355bf57, 0x7ed8c37e, 0xd0fe704f, 0x1c028db5, 0x4751bde9,
+ 0x46f7ec82, 0xe39e23c7, 0x86bde012, 0x7b6bbec3, 0x513f88f9, 0x8b6d717a,
+ 0xbdff01b2, 0xc3ca7db8, 0xeeeba27f, 0x53625ada, 0x38b4d903, 0x717c7e90,
+ 0x942db661, 0x64d5627e, 0xbef144bc, 0xe460edaa, 0xcbefda48, 0xd42e0c5f,
+ 0x7cdd7ed3, 0x535e179d, 0x1e5c0137, 0x9dc7657d, 0x96e35ed0, 0x778f8062,
+ 0x3fe9fb6d, 0x6f57cf81, 0x9308006d, 0xa3bc5f96, 0x54efd2f3, 0xf7eccdee,
+ 0xf866516d, 0x9f17cbee, 0xdde013bc, 0xed82d6d2, 0x8cdc5e17, 0xecaf03f5,
+ 0xe9bffb78, 0x488eb577, 0xe1777c1b, 0x9788fdb5, 0x0ec6a75a, 0xd7450dfb,
+ 0xcfdceccf, 0x849b64f8, 0x31548de7, 0x5ae825fe, 0xaf97efd0, 0x28111dcc,
+ 0x8ed56a1f, 0x4fbe0954, 0x925edbd0, 0x9ca05e50, 0x688c3778, 0xdffee8c2,
+ 0x9681a5a3, 0xfbe5ea15, 0x2ce780b5, 0xd908cfc6, 0xa7b5e42c, 0x6f7efe84,
+ 0x75e6c449, 0x3eaeee70, 0x26e78d98, 0x1d1dd182, 0x31c7c0c7, 0x434438c0,
+ 0x0fbeb0ec, 0xb2db6fd3, 0xa547ce8e, 0x924efb34, 0x47779c70, 0xce05bedf,
+ 0x8c2f58bd, 0xda0f3937, 0x9e41532b, 0xf2d7df88, 0x670dae75, 0xe722edf2,
+ 0xc6653537, 0x7c5e50b5, 0xf00aac35, 0x0ef3af53, 0x72fc00b0, 0x5b471d19,
+ 0x6daebf18, 0x37adae5b, 0xe71c7f62, 0xa0a7ca13, 0xe9e7a3cc, 0xf49f3d1c,
+ 0x0edfadab, 0xc97ef981, 0x193864f8, 0x3e98fb0e, 0xf0048ceb, 0xd46dc88b,
+ 0x7f5c20d6, 0x9629dac1, 0xae87db02, 0x4947e760, 0x2316b9b7, 0xb73b1b87,
+ 0x532bbbc9, 0xf4b7c8ad, 0xfa01feb6, 0xb3b57253, 0xbf7f44c5, 0xa6d3857b,
+ 0xe6f774a6, 0x536363f9, 0x1c95fd68, 0xabd20869, 0xd8f2625a, 0xea79c465,
+ 0xe7c8ca9a, 0x2d23bd74, 0x9bc75cec, 0x428ee689, 0x342a9e3f, 0xf8446344,
+ 0xd5af90fb, 0x7af2e5ad, 0x31275b2b, 0x98a7d2f8, 0x8ef19fb0, 0x683aff68,
+ 0xeb11a33f, 0xf2fbf4be, 0xaaba3e40, 0x755a3e50, 0x820bdeb8, 0xfe57117f,
+ 0x7f3f3cec, 0x139b7aa0, 0x475e35e8, 0x8fe3234b, 0xfbfc7495, 0x9695a52c,
+ 0x1f197f38, 0x7095dace, 0x74ed0f5a, 0x762dd79c, 0x8b6c8efc, 0x50afc991,
+ 0xe39eb07c, 0xbbc919ff, 0xb5cce818, 0x740ccc37, 0x77a77f5d, 0x5c1f2040,
+ 0xb07c616b, 0xf74dd39b, 0xef2f465e, 0xd82e54aa, 0x6e5bbbdf, 0xa8740cdf,
+ 0xff03c794, 0x8695762b, 0x2edc9b8e, 0xc92f0199, 0xf0cb269b, 0x55baf547,
+ 0xe5d657a0, 0x5f814348, 0x7fcbed48, 0xd7ad1b75, 0xbd41bc53, 0x9f3f377e,
+ 0xef854f54, 0x172bdbeb, 0xb1297cc2, 0x12d4d977, 0x536347ea, 0x96bebd68,
+ 0x7ff9c314, 0x37becd26, 0x9121f705, 0x4f20ac97, 0xf20d5ea9, 0xf50f2e34,
+ 0x56e77af1, 0x8e49bfd4, 0x85bdcb8e, 0x27d7afa8, 0xf9c1b4ce, 0xf627c3ea,
+ 0xaf7d42ae, 0x0b6e1ade, 0x684fdfa3, 0xfa601e97, 0xf5b0918e, 0x4fa87648,
+ 0xc3748f70, 0xf8092e7a, 0x39db5288, 0xdeefe607, 0xda2e27a3, 0x71dedefe,
+ 0xbd05cf28, 0xa3d75e98, 0x98d68f5c, 0x2fcbd025, 0xe7c9db36, 0x65982554,
+ 0x05bc22b1, 0x67b66b3c, 0x5c9ce0aa, 0x9ff0ede2, 0x43cb9e35, 0x42dd69fa,
+ 0x2d67d20f, 0xf563dbd7, 0x030782f6, 0x28f427f0, 0x82fc1d25, 0xa6f27fd3,
+ 0x621c1243, 0xaeee7e25, 0xba069e26, 0xa937bbbe, 0xa8f9253c, 0x7c8fdd5f,
+ 0x6c8e957f, 0xb78efa91, 0x8a8bf383, 0xf0014718, 0x46e98ac9, 0xaa7f205b,
+ 0xc2abb708, 0x423cf402, 0xfa2a451c, 0x1378f9dd, 0xd875ffc2, 0xacbd1077,
+ 0x63967fb7, 0x22bbc02b, 0xa7ed0c21, 0xf95d5a7b, 0x5d6d1fa4, 0xe7055e15,
+ 0x2363f292, 0xed334df2, 0xdf8bbf4f, 0xe445f232, 0xd705a4b3, 0x6662d9b5,
+ 0x8a38c4e3, 0x64b5811a, 0x39305639, 0xdb05b266, 0x3f7c7dcf, 0x29cfa607,
+ 0x4c9d0150, 0xf4f4da35, 0x92dfa7bb, 0xb8dd23e6, 0xf384c0a8, 0xec715ce2,
+ 0xd8af662e, 0x5388ee80, 0x7d56fa83, 0x9c1dc3a3, 0xd71d18ae, 0xf40bfd53,
+ 0x88574a70, 0x2676fab7, 0xddb8227f, 0x50227c07, 0x4ae715df, 0xd7e05b9c,
+ 0xde823740, 0xd1bdb9c4, 0xcfcdd9f3, 0x7fdd3747, 0xde9a7d20, 0x6eb97464,
+ 0xda14b595, 0x731055d7, 0xb4aabda0, 0xf870ac83, 0x62fadd68, 0x11c61b84,
+ 0xe2ce2e7c, 0xa8fc0b38, 0x35d1cb7e, 0x2f9cb648, 0xf8f9bfd5, 0x67e96b80,
+ 0xcf1b0d06, 0x07708ee0, 0x82818fd2, 0xa58854db, 0x4473f80b, 0x12df5c93,
+ 0xdcb93fe5, 0x65facef8, 0x7c01a4ae, 0xa8f2fd09, 0x0b4ff9ca, 0x45292fd7,
+ 0xa626f490, 0xaf03c65f, 0x25b07e07, 0x24fc0dc2, 0x77389e3e, 0x97cf5905,
+ 0xbc099cfc, 0x3e233b0a, 0x1c9f7d92, 0x5324f4cd, 0x8b2efb34, 0x0bf60197,
+ 0xcaab079e, 0x43a88679, 0x8fd101cb, 0xc5db0bae, 0x1fed7a7a, 0xfc6f5b03,
+ 0xacb603a3, 0xffa7c00b, 0x0856dd5c, 0xef5ace78, 0xfa37ccd1, 0x48f211e7,
+ 0x7eb03f49, 0x9fb05b90, 0xdfd0dcca, 0x76e7eeb5, 0xcb9e829c, 0x633af9f8,
+ 0xf2ddf821, 0x68eae718, 0x45159f5a, 0xff1431ec, 0x23d1deb3, 0xdf1c913d,
+ 0x6b43b000, 0x8fa5c434, 0xdd6abc06, 0xfe3c00de, 0xfb40f00d, 0x2e0c98f5,
+ 0x2d073d35, 0x68e2ce31, 0x8cab9e3a, 0xc7a03cd8, 0x0bf29f7e, 0x53c49738,
+ 0x81a4fc0c, 0x8e012378, 0x239c982f, 0x757abbe0, 0xa9d43a67, 0xf30f931d,
+ 0xecc11b3c, 0xb551df27, 0xc785207b, 0x47f78365, 0x2e7ae923, 0xb9b2c8af,
+ 0xdfa738e8, 0xdf9efdfc, 0xed2fafd3, 0x19cd22f9, 0x0deb57c0, 0xc626832a,
+ 0x4896ef5f, 0xbe105b55, 0xc99a233b, 0x09dbccd3, 0x68b804e9, 0xaeb7a87c,
+ 0x8027b308, 0xbec567df, 0xe96b84d2, 0xca570df3, 0x9e603b88, 0xfa1fda06,
+ 0x4b195c35, 0x8c8243dc, 0xf903c74b, 0x992570d0, 0x3cd862b8, 0x315437c0,
+ 0xfbf8ce4c, 0xed1713a7, 0xaa455a7f, 0xe7fbad83, 0xbb5f0cd1, 0xac1f1909,
+ 0xd7df077d, 0xfcec7eee, 0x6e4836fa, 0xaf160fb0, 0x14d47930, 0xcfe98ba4,
+ 0x362d2fa0, 0x48aa3cbb, 0x8f943fe0, 0x4e34460d, 0x647b5035, 0xf467971e,
+ 0xa028cd3b, 0xcf199757, 0xc39f93a1, 0x7defed79, 0xc589fe03, 0x4518621a,
+ 0xb06f99c7, 0xbfa14e1d, 0x2638c9ff, 0xc2c4c412, 0x83c4a687, 0xd5984b1c,
+ 0xbd2273a8, 0x7e83318d, 0xea51912a, 0xa5ae236f, 0x8f50690f, 0x74a27a45,
+ 0xac718ba0, 0x3a00ba04, 0xf5983a04, 0xe26be320, 0x5e7e5cfb, 0x59f87495,
+ 0x8ecf7c08, 0xf181cb29, 0x358e512c, 0x5e0fdf48, 0x6ebff192, 0xf3f2fbc9,
+ 0x4dcba740, 0xdf4897b6, 0x70e13ffe, 0xd4e829ef, 0x2e5a2c91, 0xea3a47ff,
+ 0x9def1da3, 0x675d3e04, 0xa0d47a30, 0x76d6ec57, 0x283ec579, 0xd945060e,
+ 0xf073c29f, 0x739651c3, 0x02482694, 0xe3d71dfd, 0x03bf00dc, 0x0363db9d,
+ 0x151adce9, 0xeba2740d, 0x10c38bc5, 0x490bc7ef, 0xd1f1c935, 0x31f11471,
+ 0x01d760df, 0x1dd817dc, 0x5159beb8, 0x0cb3629e, 0x6feab9fe, 0xf871bf6f,
+ 0xf9e7e7af, 0x61d28eb4, 0x83b07390, 0xc31543c3, 0x64e9c6f8, 0xd3a7af46,
+ 0x282ef549, 0xf692d107, 0xd78fdd3b, 0x007d790b, 0xd59e2eff, 0x797e700f,
+ 0xa77d9f3a, 0x3e33e79c, 0x7b18eccf, 0xf68bc007, 0x4f00e8f3, 0x41b9876f,
+ 0xeafca64f, 0x8f13a700, 0x155f9025, 0x1f0006f9, 0xf8a629ec, 0x5759fba2,
+ 0x013f4bea, 0xde9f64fc, 0x7d7ac5bc, 0xd7c27dbc, 0x97e59df5, 0xa1afca8d,
+ 0x49f5f932, 0x885f9334, 0x1d12ba27, 0x11b2abd3, 0xea17483f, 0x5bcfc71b,
+ 0xf4ee0c61, 0x51a3789c, 0x1cf2794e, 0xaffd7c01, 0x8f826e1c, 0xe3970e9c,
+ 0xf7f7c5d1, 0xeb473f25, 0xde4ccda3, 0x30e97cd9, 0xe0e8e9ce, 0xc7ed5f78,
+ 0x239e3747, 0x0c4e6fbd, 0xa8fbb7a5, 0x442ba0be, 0xf587ac7c, 0x734bb1f4,
+ 0x73857f3d, 0x8980f0dc, 0x22bbdc80, 0xa1f22be6, 0x97ca937f, 0x4e8f0674,
+ 0x87afd41d, 0x27d1f01f, 0xd4951a51, 0xd5a02274, 0x71c5621c, 0x9e3328c8,
+ 0x3e5eb0b3, 0xf38989a2, 0xef3947c3, 0xc8af8e29, 0x0e734918, 0x36236af0,
+ 0xa3e737e8, 0x29b34caf, 0x1b325c9d, 0xcf2a2a5c, 0xd19caaae, 0x79efe031,
+ 0xbbea28f8, 0x019e74a7, 0xed20c6ad, 0xcf0bcf3a, 0xb9f6fe4a, 0x74bb533f,
+ 0xeeef1cf4, 0x74c9faec, 0xa7677fba, 0xd8e706da, 0x1faff2b9, 0xa5bd030c,
+ 0x4feb6b53, 0xd7aeae50, 0x991a3ec0, 0x254a767e, 0xefc5ff87, 0xc187edc9,
+ 0x540f0c31, 0x133a409f, 0x5854e0fc, 0xeba13e64, 0xfd3c4259, 0x51e7ee81,
+ 0xef4a17c3, 0x10f725f2, 0x181627ca, 0x7dfd22a7, 0xe85dc0f1, 0x9c485e6f,
+ 0xb9e62fc8, 0xe40c7fb4, 0xcad60ba3, 0xe55a8beb, 0xc9cf25f5, 0xdffebdeb,
+ 0x4effb972, 0x98635394, 0x0ba8ba5c, 0x863e3ede, 0x9777e3d1, 0xee5083c7,
+ 0xf9c795f6, 0xe395a728, 0xaee5c3de, 0x1e42cb90, 0x84315c37, 0xe388c718,
+ 0x7c1c5c5c, 0xf5f1f7fd, 0xa3315c37, 0x3fdbef7c, 0xd53ae516, 0x813bf0c4,
+ 0x892b86cf, 0x0ba8bbf8, 0x2fdfd07d, 0x8ca3c715, 0xc22e7cdf, 0xdf85fe7f,
+ 0x19efd057, 0xd0921889, 0xfb927b5e, 0xe0f9cc6b, 0xf2033a87, 0x39d9e29d,
+ 0xa5edbc8e, 0x48f79c4b, 0x3f4d00d2, 0xf72b7d3f, 0x82e0e941, 0xd59f8037,
+ 0x716298c6, 0x3064c1de, 0x73e82bcc, 0x5115c3ce, 0xb0ffdf20, 0x50213cb2,
+ 0x6bf5eaff, 0x447d98e8, 0xaf265188, 0xcd9e4288, 0x2bf2a76b, 0x0188f51f,
+ 0xef9f9740, 0xb9f4819b, 0x81e2d890, 0xe9f67b6e, 0xf7ffd1d3, 0x5898e51d,
+ 0x3cd714cf, 0xa92fd32d, 0x65e7a090, 0x4a7f9f32, 0x5467d307, 0xf516bb06,
+ 0x9ab13b15, 0x64a4d1e3, 0x130a96f2, 0x168fad0d, 0x5a1e2075, 0x2337c51f,
+ 0xfeba7f41, 0xf324bcd1, 0x9e70899d, 0x1aaf30f4, 0x113b90d8, 0x361196ca,
+ 0x9225942b, 0xc1d6c343, 0x34963cf0, 0x2af7c2a6, 0xf4cd5783, 0x7882ba25,
+ 0x63e62fe8, 0xafaf1375, 0xce797a9e, 0x68ddf822, 0xe3af73c2, 0xf05578eb,
+ 0xc031032f, 0xcf46f5be, 0xe24f1897, 0x8accaba5, 0x1faba876, 0x9c3fbb41,
+ 0xd79811b4, 0x82e4bc68, 0x59899acd, 0xf9987a82, 0x0211e7b2, 0x52e8cd7c,
+ 0xb6be460d, 0xf49af913, 0x7be062fe, 0x03e68f94, 0xaed90d1f, 0x2efea0f1,
+ 0x5f3452f8, 0x4be70b5f, 0x21c18449, 0xbe71d886, 0x23169b1f, 0xae338a5f,
+ 0x86ffa090, 0x97c8f1c8, 0xb4f001e2, 0x46bc663d, 0x1ce267c6, 0x95427af2,
+ 0x94e49ebc, 0x14e40dd7, 0xe3c903ca, 0x0636fc48, 0xf01c91ed, 0xd8cb683b,
+ 0xce1e99f9, 0xeb0dd5d6, 0x1139fba3, 0x937ffaa3, 0xbb7245fb, 0x475a3eb5,
+ 0x4f150fd0, 0xa8c1e62d, 0x61889c07, 0x2e67c07a, 0x90fb5768, 0xfee09eff,
+ 0x1de3a983, 0xdf8a1a15, 0x07c972fb, 0x8f9e5a76, 0xef869e73, 0xac691c67,
+ 0xaaf5a5ab, 0x879e49f7, 0xe6250596, 0x9f14ed9a, 0x6c9b666b, 0x1afad28f,
+ 0x576d2313, 0x22f51e9c, 0xb698f202, 0xa225566f, 0xfc01a3ff, 0x6bff74ad,
+ 0x3a006f40, 0x5ed04fe8, 0x1ac87aa6, 0x79b7ed03, 0xcebcd99d, 0xdf2a7e0a,
+ 0xfa07f058, 0x16f31116, 0x5c3ce412, 0xe28ce7a5, 0x53a845f5, 0xbe9c4a3c,
+ 0xe15befc4, 0x2f562cf7, 0x1e760a19, 0x83ab2ffb, 0xcff02832, 0xfddce8e4,
+ 0xa51d3d61, 0xcf5a38da, 0x7f43631a, 0x617ce131, 0x9f879898, 0x73fe91bb,
+ 0xbc05ed80, 0x64f1dd9e, 0x978c3c45, 0xca7e504b, 0xd62c0dce, 0xca187f4c,
+ 0x73c0edcc, 0xfff1077b, 0xfb95e307, 0x8dbc47c7, 0xceef6de1, 0x61d8f166,
+ 0x387ecf1a, 0x597923d7, 0x8774cbc0, 0xa511fe54, 0xed8342d7, 0x802b1ee0,
+ 0x7d86a1d4, 0xde3f350f, 0x708ff302, 0x7c03147c, 0xf281946c, 0x0cb65a03,
+ 0x59ccd9b7, 0xf8156fb8, 0x42b5ba97, 0x40a3d91e, 0x92ad4dae, 0x7d00ff5c,
+ 0xe11a8c60, 0xe53197f3, 0x7794d751, 0x3ab22a4d, 0xd6acce50, 0xf3f7fcc9,
+ 0x65ff9963, 0xecd8ec5c, 0x2c079458, 0x962837de, 0xdba009f2, 0x7c03921c,
+ 0xe71ce022, 0xa55d77c3, 0xce750ebf, 0x9cfcede5, 0xd10fb34f, 0xcfcb3ea2,
+ 0x8eabe0bb, 0x669e7670, 0x74069210, 0x22349532, 0xba563dff, 0x7dfbcf14,
+ 0x7805a5c4, 0xe0c65a7d, 0x653dd62c, 0x98af5cbc, 0xa7d790e6, 0x0ef52957,
+ 0x7fbc7b3a, 0x794e19de, 0x3fa164fb, 0x8feb978e, 0x55cffeb3, 0x84b5ca0b,
+ 0xcdbeeb97, 0x54f83f00, 0x03f81c6d, 0xfa33243b, 0x8c243bc1, 0x195434fb,
+ 0x6c6fe0dc, 0x5bf16768, 0xefd05ab2, 0x7e80c7bc, 0x31da5653, 0xbedf571e,
+ 0x80145a53, 0xb75a94af, 0x207cfc04, 0xc8275185, 0x9c77ae2f, 0x83f7bad0,
+ 0x52c4fcbf, 0x9e74e24a, 0xe1df3c83, 0x143be410, 0x34cee9fa, 0x28fff987,
+ 0x3c7fa315, 0x03611cd5, 0xaaad79bd, 0x6b85fd10, 0xbf324d23, 0xf655baee,
+ 0xf84ef80a, 0xcafe4509, 0x6c693d74, 0x43a7fe63, 0xcc8d8cc8, 0x76e6e43f,
+ 0xd32c7672, 0x6afb68cb, 0xce294ff4, 0x410c5c6d, 0x333711b9, 0x5580fd07,
+ 0xe045051d, 0x07f2a587, 0xb1d9d3fd, 0xe55fec56, 0xd5ff402c, 0x1819c6dd,
+ 0xd8e86817, 0xf46859ac, 0x82c3cfd3, 0x044822ee, 0x5faf5dd0, 0xfd1e9768,
+ 0x8e555742, 0xd57d001f, 0x44f93cea, 0x7bf8974e, 0x84b2f928, 0xe65b5de3,
+ 0xc288b198, 0x9d03e7a5, 0xaa3bec0d, 0x5ebe2040, 0xfe416bdb, 0x904c99a7,
+ 0x252eafcf, 0x367b27c8, 0x17c8bf33, 0x687bea96, 0xb52d590b, 0x8eee1f22,
+ 0x5ff08b1e, 0x7a843c66, 0x4a26f548, 0x7e7c014f, 0xbd7956d9, 0xb2fb3086,
+ 0xba1f7b76, 0xf8247e44, 0x796efd55, 0xe4cd923f, 0xb9c38db7, 0x42d1f380,
+ 0x054a6d87, 0x96cabd2c, 0x6244ecc5, 0xfc5e3e07, 0x0bfb8ebe, 0x85cf9967,
+ 0x597b8b01, 0xd41e96ba, 0x66af3a63, 0xcdf198e7, 0x928f3e62, 0xfd73179f,
+ 0x9d0d4ee7, 0xcfafd0a7, 0x3f561314, 0x2750eaa4, 0x2debfcaa, 0x1e84fde2,
+ 0xc0a9f825, 0x4270e957, 0x3b3a5386, 0x8fddf020, 0xd37c03f4, 0x25ce91f1,
+ 0xc68954c8, 0xef605df1, 0x51f3e48c, 0x5d01707a, 0x370654b9, 0xa91aefd0,
+ 0x0188e511, 0xae5a65f4, 0x57c89c93, 0xa976a8df, 0x4823de01, 0x327b94e3,
+ 0x4676bf81, 0x9d289c00, 0x9fa40e1c, 0xdf49e216, 0x08e8c929, 0xbf2cbbdb,
+ 0x82474a0e, 0x653e7bef, 0xba04c0fa, 0x02a71863, 0x3cb40902, 0x3a412d24,
+ 0x5a7c6719, 0xad7ffd03, 0x78d3f662, 0xfac0d6e2, 0xfc72cc2a, 0xd7944b8f,
+ 0xa1f6b2ef, 0xdbff8c0f, 0xe4273c39, 0x82eddbc8, 0xdf39116f, 0x995724ca,
+ 0xe1f8fb7d, 0x8eaec087, 0x10392268, 0x9d1aa3df, 0xf8907fad, 0x2dec4f49,
+ 0xc4f7c3f7, 0xf7c3f106, 0xafbeb968, 0xc3faafa0, 0x27ace617, 0xe7143a7e,
+ 0xa8d20ee1, 0x9370a44e, 0x8ef161de, 0x28fe803b, 0x90370c3d, 0x486fd05c,
+ 0x8973f311, 0x6de821f3, 0xc545af28, 0x20cafa71, 0xa35f4019, 0xbfd0c3db,
+ 0x19d00779, 0x3e02dba5, 0x42df90ae, 0xde196f2f, 0xa532ae87, 0x78e3942c,
+ 0x1f1c84de, 0x7f9ed922, 0x72f41324, 0x01e5ea17, 0x87131474, 0x11d288fc,
+ 0x723ecf9e, 0xa0aede52, 0xe3ef8133, 0x252cdf5c, 0x535f488d, 0x3d2c5655,
+ 0x2f4ecc95, 0x40d54e37, 0x3326f7ff, 0x74031b3a, 0xcbdf0598, 0x20dca4e9,
+ 0x90e92baf, 0x9c0aa8ce, 0xa1974957, 0xe8032ce8, 0x98c7c84c, 0xa8d9d3eb,
+ 0x674e5bb8, 0x826ee2a3, 0xdadf04ce, 0x372e6619, 0x96aedc82, 0xf90c0e50,
+ 0xea05bb20, 0x5132eb03, 0xb169dccf, 0x46f6c41d, 0x69d45ed6, 0x42de4357,
+ 0x9ede0ad6, 0x7a8728e9, 0xa76d1343, 0x671f1743, 0x2bd90d79, 0xa3c17b59,
+ 0xe04d078d, 0xfeb172c7, 0x46b97e6f, 0xdddb491d, 0xd2ff786b, 0x37a872d6,
+ 0xbffd65ac, 0x60c87880, 0xb77287c8, 0xadb7efc0, 0xb331b4cf, 0x25b7e994,
+ 0xa53bbf7c, 0x5fb1075d, 0xe4b7eb2b, 0xa09c21b0, 0xd6f4ccfd, 0x4b3ef93b,
+ 0xc67db136, 0x78f77e7e, 0x458ba52b, 0x5fea173e, 0x43b554e7, 0xb085af91,
+ 0xd6a54b3f, 0x51c72854, 0xdda50bb6, 0xeeab5b60, 0x5b61e2c7, 0x714d14e8,
+ 0xe2217fcc, 0xaeaf1048, 0x9a67d00c, 0x245d98e2, 0x268f8bbe, 0x8d911fa8,
+ 0x4437b426, 0x2cf3cb9c, 0x850ec091, 0x50bf423d, 0x5971af71, 0x8c2fa88d,
+ 0x2ef110cb, 0x9d3e66af, 0xafdbe0b7, 0xaff306c6, 0x3d31c734, 0xbf8f3ce5,
+ 0xddabdf8b, 0x13bf2e2c, 0xe0192488, 0x7057f87a, 0x3c42775e, 0x1727098b,
+ 0x65780e19, 0x727e27f5, 0x6a5add60, 0x35512fbc, 0xcc205c6a, 0x23cc25d2,
+ 0x3c49d49a, 0xd77d9151, 0x3c434e3f, 0x8407963a, 0xa2dc5feb, 0xc2203cc3,
+ 0xc134d9f9, 0xc7f5469e, 0xe3953df3, 0x4fe0a369, 0xe010c843, 0xde38d34f,
+ 0x3d5033ee, 0xab72e518, 0x5e37c156, 0x21b1be40, 0x6f2dfea4, 0x6a95f057,
+ 0xae62ef3e, 0x3e252f77, 0x49ce4bd4, 0x6fcf2c6e, 0x8d777a60, 0x35ea38f1,
+ 0x9e991b3d, 0xa8bc4b59, 0xcb752cf7, 0x36cd42f9, 0x4daebd79, 0x97686f5e,
+ 0x5cf27bd7, 0x86cf4f38, 0x4fe0a1ba, 0x03ee7eab, 0x0b56dff4, 0xf396e2fe,
+ 0x32564217, 0x20ecf2fe, 0xed28e7f4, 0xeef76a70, 0xa1f8c38b, 0xe82d6679,
+ 0x58227305, 0x98da82be, 0x64c07c87, 0x14383b40, 0x39da501f, 0x8320ef42,
+ 0x2a0f9f82, 0xcf000c69, 0xc6777800, 0x921edb5d, 0x21f02bb7, 0x39fb91ec,
+ 0x7c50a63e, 0x93bf3cc3, 0x1cf768ec, 0x31f0ca5b, 0xe902b8cd, 0x0c65d3e1,
+ 0xba2ec21f, 0xaec83b79, 0x90762efe, 0xce2e5fd2, 0xb09a7755, 0x8768ad4f,
+ 0x29800036, 0xf37bae9f, 0x9fa00bc4, 0x358eef8a, 0xc04d3893, 0x2a563c79,
+ 0x9e4e8ff7, 0xe4287a70, 0x2b0f6e3b, 0x93e00bfb, 0xffa1c474, 0xd8412eb0,
+ 0xe9fc6c45, 0xf2eaff3c, 0xe8a8ccca, 0x89bdd96b, 0x009a619d, 0xc68f6cff,
+ 0x4e760917, 0xe70955cf, 0x4825ba85, 0xffdfc91c, 0x87c41878, 0xf9dfcefb,
+ 0x3f03dfbd, 0xe302217b, 0x3257977f, 0xa6f2ef7b, 0x7c079881, 0x0549c791,
+ 0xde1c961c, 0xce17b6f6, 0x1c31d35b, 0x7f7246af, 0x1db687bd, 0xe2633bd5,
+ 0x3caa0e41, 0x2c57463a, 0x1df6219e, 0x42e96fda, 0xc03ba6fe, 0x0a4face4,
+ 0xfa4ebcc7, 0xb8c080fb, 0xe302524e, 0x7e0e42c3, 0x2d6afdcc, 0x17d8a5bd,
+ 0xc4b42bf3, 0x3d60b3d8, 0xc1bac31f, 0x1691f43f, 0xbbf835f9, 0xa548ce21,
+ 0xee89492e, 0xa3881ebb, 0x3881bd6f, 0xc99e2dba, 0xf694a583, 0x62cd3f30,
+ 0xcef9802f, 0x79e1b8f3, 0x1f3a771e, 0x2350e2c9, 0x5f1f19e3, 0xe44dfbca,
+ 0xf110f9e5, 0xd9ddf16e, 0x35618366, 0x9b1feb5d, 0x36756189, 0xf567f125,
+ 0x339f988d, 0x67abed8b, 0x39f305af, 0xf8aabf45, 0x8eb0a5d2, 0x18c71621,
+ 0x9eb61728, 0xa9fa05d1, 0xa83f607b, 0xf57db04f, 0xcc52b184, 0xb95f1557,
+ 0x3ce01e34, 0xec788bc3, 0x75108fad, 0x33df8e07, 0xc24ff19a, 0xfc7510fd,
+ 0x5b8a85fc, 0xa55e2f5d, 0xe6cefb8c, 0xefb889e3, 0x9914362c, 0x73bee3cd,
+ 0x0a4d640c, 0x91db9f6d, 0x48d5ecc0, 0xdc5900d7, 0x537115d7, 0x87417771,
+ 0xb8fe693d, 0x889bc6e9, 0xfe20fe9b, 0x7f4dc796, 0x6e241f10, 0xbfa78caa,
+ 0xb6417a0e, 0x980f0f1f, 0xd42adc19, 0xcfe0e5b5, 0x6090bcbc, 0xe901731e,
+ 0xd028ecf7, 0x89688eb3, 0x137c8adb, 0xe1ebe3f5, 0x22a1ce2d, 0x39df9956,
+ 0xd603589c, 0x968ce49f, 0x0ee351d5, 0xa94c0fc8, 0x4ff5964e, 0xfb27ec6b,
+ 0x9069a33e, 0x55d33dac, 0xad67ab28, 0x7df643bd, 0x5932d6ff, 0x7773e07d,
+ 0xcdbfbecb, 0xbf56593d, 0x7e40ff0c, 0x767e46a6, 0x65fbb6fb, 0x1d1c97fd,
+ 0xddca7e82, 0x9712fe5c, 0x287733bd, 0xfac0a373, 0xcbe6daf3, 0xc91e23c6,
+ 0x45f6d123, 0x23174f1c, 0x85893dd9, 0x3f9fcc9d, 0x6c997db8, 0x2d751afc,
+ 0x47194fe2, 0xc3be242c, 0x96ea3f98, 0x37d21e6c, 0x7db4b8ae, 0x9ebbf633,
+ 0xfafc227e, 0xb14de207, 0x24c91748, 0x92b3d199, 0x70bd8c1e, 0x05197b80,
+ 0xa3b3c064, 0x20f4648a, 0x1b851bc3, 0x6f2ea9fa, 0xd1de6137, 0x700ba392,
+ 0x3944fa3d, 0xe559843d, 0x239110f4, 0x4d9307a7, 0xe1a8ff8e, 0xe12bfc72,
+ 0xe9cbb16d, 0xffe97881, 0xcc7780d7, 0xfcbd3978, 0x1ddce0ab, 0x1c81e3cf,
+ 0xd90e43be, 0x37088c5b, 0xec243f96, 0xa3b73d7b, 0xcfdcac49, 0x7fa7f425,
+ 0x1578f3c6, 0xd5f8471f, 0xb42e48d7, 0x66e37bcb, 0x9ee93dc3, 0x1bcfb04c,
+ 0x38f3f309, 0x41c50954, 0x7bf884fd, 0x80a13f28, 0x67ae54eb, 0xfa3b10d6,
+ 0xfc4117a5, 0x2b67969b, 0x677fa297, 0x1d69f189, 0x9938bff4, 0xc4d563e9,
+ 0x7afdfc8d, 0xdc256ff1, 0x01252f40, 0x1c25547e, 0x63c90ea5, 0xe5c33e02,
+ 0x10e93240, 0xf2c9c072, 0x12fee5f8, 0x00b2f102, 0x5ef4253e, 0x9f80be31,
+ 0x7c625fe0, 0xe059f83d, 0x19f8281c, 0x45e391c9, 0x63815fe9, 0x181a1860,
+ 0xc092b12f, 0xafd28af8, 0x50a7f7e2, 0xa7ce92bb, 0x216cc8ce, 0xcc436f14,
+ 0x15d7f476, 0xf099ce93, 0xa0a7f0bb, 0xd236e17f, 0x29085feb, 0x8f13ae9f,
+ 0xbc92e29d, 0x8df667cf, 0x2eb88ac3, 0xbfe7c305, 0x49479da7, 0xe4f7c456,
+ 0x01c60737, 0x2ff5f51d, 0x45be4eda, 0x7cab51c7, 0x3f7e8131, 0x4f7f5fe1,
+ 0xee7ee2f2, 0x48c7f623, 0x4f519e80, 0xcccec6da, 0x952eff04, 0x3250918b,
+ 0x5769143f, 0xf41ad9ea, 0x4ee8aaff, 0x486bde80, 0xd3329c40, 0x75758edf,
+ 0xe68dfadf, 0xc13afcbb, 0x2cbd9dcc, 0xfe70935f, 0xd0c3ec27, 0x7d7c98f6,
+ 0x330b8c0b, 0x82fbfa25, 0xc0dc75c0, 0x037e453a, 0x7884e3dc, 0x9f2a26c6,
+ 0xb04bcf51, 0x17515ea2, 0x3b13ea7e, 0x99d4567c, 0x36d7a81e, 0x0301a8e8,
+ 0x7aebf8f6, 0x936c9716, 0x4c3fcbeb, 0xa12ef960, 0xa8f3c0e1, 0xf5cc7614,
+ 0x47911df4, 0x16e01135, 0x944b3eb0, 0x9f803fe3, 0x9ef49da4, 0xfefe5493,
+ 0xcc2eea15, 0xaedcbc13, 0xf54efbc6, 0x1fc85da3, 0xf1aaf7ea, 0xe8777508,
+ 0x756f3ef1, 0x93d441fb, 0x03299aba, 0x85c97aa2, 0xe6b33a66, 0xec57f01a,
+ 0x207d9437, 0x4c5e8df2, 0x9f33fce0, 0x2be607e4, 0x8af83e51, 0xdaf60f8c,
+ 0x4a79bdad, 0x93e304af, 0x28dcea15, 0x9bdae7b8, 0xa5f1a287, 0x8fc00e4f,
+ 0x720f1f72, 0x1a37e43b, 0x5d025b47, 0xd4ce99d7, 0x0abc6067, 0x64e1c775,
+ 0xc90acf80, 0x12b47106, 0xa87fbb3d, 0x35b72f57, 0x0375d806, 0x203b521f,
+ 0xc57a795e, 0xbf70d183, 0x503b8c59, 0x393de152, 0xf67d7642, 0x9f8822fd,
+ 0xa3adb2cd, 0x667ad9b5, 0x2f7e6657, 0xcf4593c2, 0x763a3bd7, 0xafdb4b3f,
+ 0x7dfef311, 0xe3fa3516, 0x0c64d562, 0xaf5885d0, 0x7e2857b8, 0x70cefb87,
+ 0x5efc4d7f, 0xf21be2d2, 0x071f2d00, 0xaff62cfa, 0x37dca4af, 0x87e8d1a4,
+ 0x6e9c7d7b, 0xdd45e80d, 0x443f2606, 0x6b31159e, 0x30ad7cf0, 0xaa75f3b0,
+ 0x3d9bb0bf, 0xeabfb026, 0x9851ecc3, 0x9a91f5e7, 0x17f95d80, 0x82ca3db3,
+ 0xdea2b3fb, 0xfaccc2b9, 0xde7cf375, 0xa1969f15, 0x12d7165d, 0x7ce8cf3c,
+ 0x6a9fb302, 0x7964a8af, 0x0f1ab546, 0x5ed50be6, 0x913e61d1, 0x148ffdf8,
+ 0xfe01ae0e, 0xd9f3fcfa, 0x0b5d6163, 0x7c0d6d88, 0x046d60bf, 0x21e80571,
+ 0x8958af22, 0x7c71efff, 0x44345bd7, 0xe7ef1833, 0xddf5ae3a, 0x0754ff5b,
+ 0x9d12efbd, 0x5c71cec8, 0xa5ebcb39, 0xe1c60576, 0x2585df94, 0x6cfc8a4a,
+ 0xecafde2f, 0x5bdb07cd, 0x61ae409a, 0xb15fd7e7, 0xebb3f2cb, 0x57e87f69,
+ 0x228c657f, 0x4b8f9b3f, 0xfd1ab3c7, 0xe0a16079, 0x6604bdff, 0x9e43d4df,
+ 0xdfc090d7, 0xe7f8fd19, 0x5b79e589, 0x7f3848de, 0xe3576f3f, 0x1f9fe3fd,
+ 0x12df8d51, 0x12c3dd64, 0xc506dc19, 0xdc5cf069, 0xcdf621ee, 0xdf17e641,
+ 0xe205fb89, 0x7d729c7e, 0x73bccbbb, 0xc6c3fd60, 0x72aeff30, 0xec89419c,
+ 0xddeeb13b, 0xf51f0cd1, 0x607c536f, 0x9fcb08fe, 0x5ded1ddd, 0x2cc0fc8c,
+ 0x8e7cf3c7, 0x7b77dde7, 0xcbbef1d3, 0x0e7ecc5d, 0xcd570f45, 0x4f8007ce,
+ 0x42374ed4, 0xaa19192e, 0x01cc9469, 0xf47aebe7, 0x4abb87e0, 0x70bed786,
+ 0xc57e21d7, 0xffdf42b8, 0xc63539f2, 0xc63cbff1, 0x1bb12dcf, 0xf77c80a5,
+ 0xebf3092f, 0xa12ad97f, 0x49df3f9e, 0x2fe51348, 0xa0d6b6f3, 0xa5f8b85e,
+ 0x03629821, 0x7ca4afbf, 0x21225e64, 0xfe72d277, 0x775c796a, 0x7e3efae1,
+ 0x7f281239, 0x94469117, 0x969f8b17, 0xeb26abf7, 0x837a0cff, 0x3e8cde32,
+ 0xcf176a4f, 0xf77ae44e, 0xf8143250, 0x7d2f03fd, 0x86b48ba5, 0x94f3ffa6,
+ 0x806b669f, 0xecb01aaf, 0xb963366a, 0x28bed13c, 0x39a5c291, 0x089d59d1,
+ 0x188f8cfe, 0x5ed72e3c, 0x2e00f266, 0x7e008e4f, 0xd33ca12d, 0xd8f164cf,
+ 0x723dc21f, 0x9ebd0f0a, 0xd47575c9, 0x7093c9ca, 0xff846e95, 0x8e79af30,
+ 0x2d8de505, 0xf63de811, 0x63c6e317, 0x222fd75e, 0x75bf00ec, 0xc197eea5,
+ 0x556eb08f, 0x0d71fa38, 0xce0f167a, 0x82aa5eda, 0xedb703fb, 0x1f83f696,
+ 0x5563a1a3, 0x37efdc0e, 0x8f31c35a, 0x5e63aa20, 0x6c639326, 0xc716d89e,
+ 0x2c67c04e, 0xeba36bdc, 0x4ee9975a, 0xe99a7c64, 0xf61cf539, 0x3ff5923d,
+ 0xebb39ee1, 0x21ef1aa8, 0xbcb0d65e, 0xe18441fa, 0xc12be455, 0x5cfa81dc,
+ 0x241b8517, 0x939ef5d5, 0x8da3c936, 0x301c77c4, 0xa8fb50ce, 0xc8267e27,
+ 0x30699f9b, 0xaebbd34e, 0x20ca9277, 0xcce4231e, 0xfcccc94c, 0x9d5f5c42,
+ 0x2c7fc441, 0xe9c5539e, 0x53d70661, 0xf8304667, 0x74b627ce, 0x81bf77e8,
+ 0xd1e8aa44, 0x56de5999, 0xd1abfb8c, 0x116f405a, 0x7ad08971, 0x4e7f7042,
+ 0x7626cbfd, 0x0df2521f, 0x682e4180, 0x79d6b909, 0x43f9c3db, 0x97e600fd,
+ 0x0ec4d925, 0xb7fab071, 0xf8866e07, 0xc59c3e87, 0x321f2959, 0xef277bc0,
+ 0xfba63c82, 0x1856fa5e, 0xdc42bf7b, 0x0bdb3687, 0xc3617ee0, 0xcc42d4e4,
+ 0xc3e9385f, 0xb5ba0877, 0xaf3c74de, 0x5448bf94, 0x38987e06, 0xa50d1eef,
+ 0xaa64faf3, 0x3ffad16f, 0xbd581b12, 0x8ab1779f, 0x3d2407d6, 0xbc83eace,
+ 0x4b6ea0e7, 0x0d1efa7a, 0xf42b63dc, 0xfad3562e, 0xac2da484, 0x324b060e,
+ 0xcfd26f85, 0xf1d171ee, 0x3eb8582f, 0x3de2f363, 0x0737fad0, 0x84fd02aa,
+ 0x7f189263, 0xbec610ba, 0xe64990bb, 0xe778064e, 0x873eff04, 0x5cf42f7f,
+ 0x9fd15fb1, 0xf7ef0624, 0x4b7b9719, 0x92d03df9, 0x8c36b208, 0x915c95c5,
+ 0x3a870f14, 0xec5c6206, 0xcb346240, 0xf17b35df, 0x8e31109d, 0x4f18a780,
+ 0xe40cbbcc, 0xc9f311b0, 0xe2f964aa, 0x79d27e5c, 0xd93ce356, 0x727f7676,
+ 0xe0016a72, 0xc34de28f, 0xbc01a6f1, 0x30d77b89, 0xf91f25ae, 0x43f010fd,
+ 0xbf4aba1f, 0x5baff4cf, 0x38572749, 0x616d2c9d, 0x259f40f1, 0x24a9e90b,
+ 0x513bbf82, 0x04c7df24, 0x4931bf0e, 0x5ecfb616, 0x384824bc, 0x63870b4f,
+ 0xe4c077aa, 0x77df9bbc, 0xcf5b1278, 0x0077dead, 0x7ef0ecbe, 0xdbf6a1c4,
+ 0x30fdb0b6, 0x473d017c, 0xa4f75ea3, 0xab0bbc6c, 0xd387fd14, 0x8dfb0903,
+ 0x3ffec2ce, 0x100defe4, 0x5fb7a5b2, 0x3fd33e66, 0xf7152f41, 0x4eeb89e4,
+ 0xed17e812, 0xc6df0fbd, 0xf7faadee, 0xdf114f79, 0xd3ef99a7, 0x96e9f6cc,
+ 0xee392bd1, 0xea6a9f4b, 0xf0bdc74b, 0xb72f1def, 0x3b278f90, 0x83c6c1e7,
+ 0x2f0a1d73, 0x316e93a3, 0x2a758a3d, 0x670bd9e0, 0x3c04fac5, 0xbf637ce1,
+ 0x8a5d395c, 0x9d42da75, 0x38efccef, 0x57eb295f, 0xbfcb30f7, 0x5d395625,
+ 0x54ceedd7, 0xf45bdc41, 0xee3e0a3b, 0xcb5fbf38, 0x98e3c499, 0x443524a9,
+ 0xa4c2dcde, 0x30fea0b8, 0xe7695dfc, 0x3e5858f5, 0xefded2b2, 0xc275b389,
+ 0x25d7343d, 0xa47a7f76, 0x71013fc2, 0x7f465d92, 0x917cbf3f, 0xf87177d7,
+ 0xf8aff5f5, 0x91677ef0, 0xab35ecbe, 0x9bff908d, 0xebf20ef4, 0x07b2a8a2,
+ 0xf57d6933, 0xdfc8fd86, 0xbeca528b, 0x7cfca4ca, 0xac0386cd, 0xafb2f6fd,
+ 0xe93d41fa, 0xd897ab20, 0x4f7e035f, 0xc67bc1c8, 0x88f5f924, 0x7159261f,
+ 0x0ab9755e, 0xd5eadfdf, 0xa3d1de5f, 0x1ae022fe, 0xabd22caa, 0x9fc5831a,
+ 0x81e97b5a, 0xc38609c5, 0xa790ad3f, 0xaf78edc4, 0xf7c76646, 0xaffbb244,
+ 0x86fefb3d, 0x4f9e19f7, 0xf004fe72, 0x35d110d0, 0x1fd69327, 0xe30cf88d,
+ 0xea9d9250, 0xb0c7e021, 0xba2cc99a, 0x9d6ba95e, 0xb225f403, 0x20d066cc,
+ 0x075fb95c, 0xf0a2f4de, 0x9fedeb7b, 0xa6c2923d, 0x463ac071, 0xf0d03e70,
+ 0x435f37f6, 0x82e1b2dc, 0xe1ea06d1, 0x0f0d8e88, 0xa235be82, 0x30dfd7e3,
+ 0x5feecc39, 0x008f7588, 0x7dfd1dbf, 0xd71ebb78, 0xb6e3a23f, 0xc8fdf045,
+ 0x016476df, 0xe53e8c9d, 0xd0b60169, 0x148defb3, 0x2fcdfdf9, 0x186f99ae,
+ 0xe0248e32, 0x54aa27f1, 0xde3c2145, 0x8ab8f060, 0x71dd51f9, 0xd178d6c7,
+ 0xdfbf27b9, 0x8c76f542, 0xe1265e83, 0x8bd3f036, 0x7f4ac57b, 0xba4ac9e0,
+ 0x68fbfa3f, 0x80415d1f, 0x85725cde, 0x7a01ffda, 0xc8b12978, 0x2486e5ea,
+ 0xe615f7d9, 0xb8fb594c, 0xed64dbc4, 0x640b5977, 0x233909f5, 0xb44fdf64,
+ 0xf7eaca95, 0xf64bbf0e, 0x52bda57d, 0xb4f02f56, 0x721fbec9, 0x7ede5da4,
+ 0x0f01a89c, 0x076d2785, 0x6b3e2ca1, 0xd0e2b747, 0xa1078df3, 0x0617f11c,
+ 0xf43fa50e, 0x076d2b8e, 0x0fe177e1, 0x1157de55, 0x6ae9d1fe, 0xdc175ba3,
+ 0xa1a89a0f, 0x8bc925e5, 0x62ad44fc, 0x305e55f7, 0x6f01bb39, 0x094abee2,
+ 0x122943f8, 0x625ee62a, 0x3167b2f7, 0x4049d87f, 0x19a7f00c, 0x9de3f426,
+ 0xfabe36d4, 0x4ec7167b, 0xda37be03, 0x77db2557, 0x6ca715c9, 0xa964a5df,
+ 0x65cb4f02, 0xc3f30af5, 0x25c7efb2, 0xdfb592ae, 0x815c7d65, 0xf56527a7,
+ 0x0a0db689, 0xe0566d3c, 0x76b267e9, 0xdc1ddf41, 0xf836f53f, 0xca396895,
+ 0x780e59db, 0x0fbcf3b8, 0xb3bc31f1, 0x74f01cb5, 0xc436c9c7, 0x51c79157,
+ 0xe872ec0e, 0x5083c691, 0x05fda87a, 0x27340efd, 0xd9a87962, 0xc3a9fe8a,
+ 0x1e5839cd, 0xefe1b669, 0x8e1e6abf, 0x76cdfbe5, 0x3cd37f2c, 0x66cecb1e,
+ 0xcd6d9607, 0xaefdf86d, 0xdfe676e6, 0xd7bde98a, 0x807e069f, 0x1eb7956e,
+ 0x27643eee, 0x7e044ec7, 0xedee1dd9, 0xaea3fa86, 0x2fc089e8, 0xa1130007,
+ 0xcbcf9c78, 0x3df629b1, 0x0dbf94c9, 0x91756649, 0xb2a6d057, 0x5e1e8017,
+ 0x09e331b2, 0x8f211a4d, 0x9a2472ad, 0xa06eac2d, 0xe6364475, 0x613c655b,
+ 0x55e4254f, 0x60772510, 0x7bd4227d, 0x90fb58c2, 0x4113198d, 0xf1ceff0f,
+ 0xbc9f7b60, 0x20e492c0, 0xcf57e0f1, 0xbfe04d5b, 0xa0757639, 0x8c71e009,
+ 0xa4ecb1fb, 0x968f3b40, 0x2d029aa5, 0x0a93d9c8, 0x3d9444bd, 0xc9f1d2aa,
+ 0xdb6fb071, 0xbe43cc34, 0x7e804b5b, 0xdecc4b27, 0x4ff5df15, 0x1317f9e1,
+ 0x1d4f68f5, 0x6117d957, 0x7be493de, 0x64bce001, 0x7b8410e3, 0x0e97c98f,
+ 0xb1b45bf0, 0x7ce3d590, 0x80b6482f, 0x67c196ba, 0x8982c6fa, 0x0a5bdcae,
+ 0xe0c1059f, 0x666c9d53, 0x9ec7b6fa, 0xa8807a06, 0xd7b4af1f, 0x5e3e79c1,
+ 0xa2fbc76a, 0x767a1cc7, 0xbc261d7e, 0xf63440e7, 0xfe0169e2, 0x5ac9b39c,
+ 0x2e1537ec, 0xf35f819e, 0x739e357e, 0x29553c25, 0x3a470f4c, 0x46733b01,
+ 0xc705da04, 0xb7deec55, 0x14ccfbf2, 0x0c5d1f66, 0xeb77ee0f, 0xa6cbdbc7,
+ 0x87babdd4, 0x22b3d78e, 0x71ee870c, 0xac7d440c, 0x7bc251a7, 0x1be73db5,
+ 0xbd76b12f, 0xe304838d, 0x5fe13392, 0x8ed5fdb4, 0x31faff07, 0x15b3fefd,
+ 0x21943611, 0xbf0841e6, 0xb3c7f9fb, 0x3fa80c63, 0x569c9ecd, 0x26717206,
+ 0x31cd738f, 0xdc31e269, 0xe0e8b1a5, 0xc685ba09, 0x82143582, 0xa56c7164,
+ 0xa9cc9e0e, 0x06be5d4e, 0x4fd965ca, 0xf0ada2ea, 0x35ced77e, 0xd1d6c6a0,
+ 0xfc8c5c23, 0x3341fbcf, 0x26dcd75d, 0x73d995b5, 0x6bdaae5c, 0x433f2a6e,
+ 0x9e71efd0, 0x8081432f, 0x87166af6, 0xc597e8b7, 0x325b74e9, 0x91e4138f,
+ 0xa7df763c, 0x1db00e37, 0xf66ba4e8, 0xc4420307, 0x5cede409, 0xc744fc7f,
+ 0xbbbe55e6, 0x4ecde620, 0x71fe7a61, 0xd04ca51d, 0x7267ef27, 0xabeabf20,
+ 0xfee98b47, 0x2acc3bf3, 0xadcfc38c, 0xb87803db, 0xa8f1cedc, 0x9e70ed25,
+ 0x7de6b8a6, 0x8a4ab986, 0x93d79a7b, 0x734eb697, 0x2cbca079, 0x03ca3af2,
+ 0x5f70e5e5, 0x45c8396b, 0x7c451f21, 0xcd5cd3d0, 0xf22372f9, 0x4dcd43d3,
+ 0xecdc3f58, 0xf348f2c2, 0x5b97ce5a, 0xe6fdfdb1, 0x765f38e7, 0x0dbcbe73,
+ 0xae68ef7f, 0x66edf2c2, 0x28969627, 0x7e016fc7, 0xcc4e0d53, 0x83777bef,
+ 0xeb7c409e, 0xf31e8772, 0x7889e80e, 0xc858f9e1, 0xbde3d1a7, 0x8d5e653b,
+ 0xd2f7cf92, 0x25f7df43, 0xf4f300fe, 0xbe80c3e6, 0x9e9a1198, 0x09ab118e,
+ 0x92dfd2f8, 0xbe82269b, 0x356acc7d, 0x657d3e81, 0xa5f21363, 0x49ab7663,
+ 0x24dfeb4b, 0x9ddacc3f, 0xd69e9356, 0xc3e37bff, 0x3565ddac, 0xdffad185,
+ 0xeacfbf93, 0xc482c26e, 0xe7c8cd29, 0x0874894b, 0x21b947ce, 0x17150c73,
+ 0x1e975e54, 0x2e317382, 0x3818de71, 0x56c97517, 0xacbb8fa4, 0x7d410eab,
+ 0x0d66ce42, 0x1bb6c55c, 0xbf43560b, 0x0d4ad8b2, 0xba931bf4, 0x1bf4357c,
+ 0x26a4fd9b, 0xdcf8dfb0, 0x7ea1ab9d, 0x06b36d8f, 0xce3ad3f4, 0xa238c4c7,
+ 0x9f05da2e, 0x835e7916, 0x0f281c3b, 0x281ddbf2, 0xca5c040f, 0x063e56a6,
+ 0x7686c77e, 0x3ac12cc9, 0xc1bd4aa6, 0xab91c86f, 0x291af787, 0xfe7a8ebf,
+ 0xba2ad309, 0xdfa806cf, 0x5627f581, 0x9dfe5add, 0x97d71292, 0xe7e09f7f,
+ 0xe43de41d, 0xb1d09f65, 0x001e32f7, 0x7de314b8, 0x2bbe1334, 0xd0269c49,
+ 0x3cb89ab3, 0x6d25095f, 0x3bebcedf, 0xd9579c85, 0xdfd0a7fb, 0x7db85373,
+ 0xd83f97d9, 0xfcf41d60, 0x8439ee2b, 0xa1fce768, 0x7b2cc530, 0xb08ea15f,
+ 0xcbd7557b, 0x31e6531b, 0x9629f32b, 0xf6c3b691, 0x1479becc, 0xc7bd84b5,
+ 0xae4fcca2, 0xad5eec27, 0xd7b94f32, 0xfc670aae, 0x0d780ab4, 0x2989e3a5,
+ 0x6564f921, 0xe135f14a, 0x910f6f20, 0xb094bd97, 0xf93eec3c, 0x5b1f3c35,
+ 0x8ce22fb9, 0xf25def63, 0xfee56cfc, 0xddf45d04, 0xbf832b5f, 0xea9fc186,
+ 0x7d600b77, 0x044d7315, 0xfc8156fc, 0xf06be3e7, 0xbb3f251f, 0xfa727c55,
+ 0x9f763adc, 0x6b1f2fbf, 0xc7c2094a, 0xb2975e44, 0xdc2a7a14, 0x3efc831b,
+ 0xec060f78, 0x9c123bfc, 0x3d97402d, 0x55afbe65, 0xb2c68760, 0x2dbb93f7,
+ 0xbbf035ce, 0x03f963a4, 0xbcf6af22, 0xd04bf5ca, 0xf94a9edb, 0x6ebbf215,
+ 0x8cf41610, 0xe075a3ac, 0x8e2c4367, 0xe48fd0f5, 0xef817578, 0x1fca8730,
+ 0xe1cb9a7d, 0xe59125be, 0xfe6cf655, 0x0fde86e6, 0x0a8f050a, 0xdc2f28f5,
+ 0x3c3cb85f, 0x9767e502, 0xfef03c44, 0x3c69576b, 0x695d2dea, 0xb7940d3a,
+ 0x4aee2eda, 0x2be3801b, 0xa4aee3ed, 0xef3606e1, 0xfe50f1d8, 0x115ce926,
+ 0x790fbdc8, 0xcebb613e, 0xe037e435, 0x86111e1f, 0x257bfa71, 0x41c0116f,
+ 0x1d775769, 0xcd66559d, 0xd35f6bef, 0xfd818dfd, 0x3d519ed5, 0xacddbf06,
+ 0xf4db5dbd, 0xed3c8135, 0x09574d91, 0xbcdf8fe4, 0x9d19ddfd, 0xc2bd056f,
+ 0x322402d9, 0x13ea8bac, 0xfcbd7eb4, 0xb5124ba4, 0xec0333d3, 0x66bfe1f2,
+ 0x54bc4a79, 0xde7de7da, 0x92e65b4b, 0x7a95c3e7, 0x44df318a, 0xfbc48ded,
+ 0x9ef62aaa, 0x7a57c882, 0xd4f3db8f, 0x829b3f5e, 0x74ceb87e, 0xfdfebd99,
+ 0x823ce74f, 0xf30c207c, 0xff6d5e33, 0xfad60e3c, 0x9fb8ce87, 0xd3f565bc,
+ 0x6bf98377, 0x5f679812, 0x565974db, 0xed7ee2ef, 0x2fbb2d56, 0x354ffb54,
+ 0xc72a25ca, 0xc89e22d6, 0x0103dd01, 0xfdb495f2, 0x83de17b9, 0x04abbf29,
+ 0x1d7ca180, 0xfb4ec939, 0x887b7255, 0x9d587790, 0x95c48fdb, 0xe271eac2,
+ 0x7ab31ffb, 0xa9fef89a, 0x4f3a7649, 0xe7689265, 0x75e36ffd, 0x33d58797,
+ 0x647ff7c5, 0xbb589bdf, 0x498ed37e, 0x3f05ce70, 0xdfcaa537, 0xddfca201,
+ 0xcd7c5a92, 0x3b791a7c, 0xdde2ffe7, 0xdfef8a9f, 0x9c01f115, 0x730936d3,
+ 0x6a576ae7, 0x317f5fd1, 0xf03f2dba, 0x7791507d, 0x613728e3, 0xebdd541e,
+ 0x0b80b703, 0x1e3a6d53, 0x44ca7a0f, 0xa154ff9e, 0xe59c6236, 0xc7c67af2,
+ 0x8b79e943, 0xe194de9b, 0x7f3b4fab, 0x9103178f, 0x4f4bbe74, 0x90f7b024,
+ 0xee313bb3, 0xe995383f, 0x22bef0f1, 0xf915e7dc, 0xc459b15c, 0xec71f60e,
+ 0x5dec611b, 0xc89db3c8, 0xc1bf175f, 0x1b75d7fc, 0x9b3ca20e, 0xffa2b6af,
+ 0x673f5c68, 0x47c42a71, 0x30039d4c, 0x36f4ddee, 0x673fc39e, 0xcb9c7998,
+ 0xcf081b97, 0x5fe17dd1, 0x97f81d7a, 0xbfe13bfe, 0x180dea9b, 0x8613dae7,
+ 0xc6826cf6, 0x1c41b3ab, 0x577b24f3, 0xdb872172, 0xe23fced0, 0x7887ff7d,
+ 0xc59daa3d, 0x959e4469, 0x54a1f798, 0x8f038313, 0x7e4dd487, 0x43c4147f,
+ 0x224afe04, 0xb7f81b48, 0x1c6c1e29, 0x83c0360f, 0x2e3fb780, 0x0665fb42,
+ 0xbd956b8e, 0x1ee02b5f, 0xe92b1cea, 0x195bac43, 0x3c665827, 0x5df80c54,
+ 0x81799376, 0xbe38d297, 0xfbcc5e35, 0x410673fb, 0xb8f028b9, 0x5dde2fb2,
+ 0xc4d771a9, 0x5ffdbcbb, 0xdc25778c, 0x8f2d6594, 0x7f7f297b, 0x2ff55521,
+ 0x36ffe385, 0xc6ecea7f, 0xb9f6b2fd, 0xc86f474d, 0xa0fc2adf, 0xabbf2eff,
+ 0x7a4eb7f0, 0xe20a896d, 0x7c7b4a32, 0x6be3ba5a, 0xdf7bbfa0, 0x09ee47fc,
+ 0x00f57c58, 0x90793fcc, 0x51abe5ef, 0x11ecfb7f, 0x355f4f4a, 0xa9d43f32,
+ 0xad6a5ffd, 0x63e97d79, 0xb11515f6, 0xecd5d007, 0x20b48fa6, 0xcd5366af,
+ 0xea3c5822, 0x309e9cef, 0x81f2847f, 0xc6d1032a, 0x555ff3d2, 0xae73dec5,
+ 0x344bc082, 0x6d271e96, 0x1e21a49f, 0xd2b5af78, 0x31e8f1a8, 0xb7bf241e,
+ 0xb9efe7aa, 0x7652c352, 0x576d557f, 0xb4d37e63, 0x748e2ce1, 0xef0db1bf,
+ 0xf238ce25, 0x6847a5e8, 0x2aed593b, 0xe2b77966, 0x54efd19e, 0xfa1f1337,
+ 0x7e612a7b, 0x1dc78954, 0xee316b97, 0x61f7eca8, 0x4d63f32a, 0xbf2c4b52,
+ 0x4fcb2f60, 0xee91e713, 0x90be88ef, 0xbbc3c1e5, 0x5a8d95a6, 0xd07cc0cf,
+ 0xfea3f63f, 0x557c30d1, 0x61afe03e, 0x9f46748c, 0x1b03d7ef, 0xfd82fe9a,
+ 0x5958fc95, 0xe9dfa8de, 0x4823e6b3, 0x3c5f422f, 0xbac1ecd5, 0xab350fd2,
+ 0x6e303fe4, 0xee2fe233, 0x5e472816, 0x66189fb5, 0x95f6eefd, 0x9d84abb0,
+ 0x04dbb4a5, 0xb5ef10bf, 0xc3fc140d, 0x777b11f0, 0xbccac351, 0x15ff3934,
+ 0xd9f2957c, 0x7f8c3482, 0x006ff9ca, 0x7ff6c61f, 0xd3f61f17, 0xfc0da37d,
+ 0xeca95535, 0xdd25737d, 0xf93226d7, 0x7577a4a9, 0x19f51ab9, 0x3a0bbd25,
+ 0x19becfbf, 0x20b375fd, 0x31d74f56, 0xfbc241ab, 0xff5f2752, 0xba0643e1,
+ 0xa7b6ae84, 0xe8f7b2b4, 0xfbee926e, 0xe9b381ca, 0x9677df30, 0x9c33a403,
+ 0xf8665bdd, 0x47d69458, 0xbb4d2e8e, 0xb7951cb6, 0x17f18bff, 0xbe73ff64,
+ 0xca241c9b, 0xd473057b, 0xd39f362a, 0x213ef2c8, 0xcdc7acef, 0x675579ee,
+ 0xd37be2b6, 0x122fb864, 0x7dd2c8f8, 0xc58eb26a, 0x01493437, 0x117508ef,
+ 0xe92327cf, 0xb1464bef, 0xf9943877, 0x4f3cf598, 0x37719973, 0xbe5213de,
+ 0x3df22407, 0xca78f9eb, 0x7f448177, 0xf9582f71, 0x34c6d02e, 0x90ad7f7e,
+ 0xf838b214, 0x3753f9b5, 0xff00c9c8, 0x66d5f770, 0xa4b673b4, 0xae47f1fd,
+ 0x6f3c7e51, 0x3e7ee34b, 0xbf6c5d3f, 0xff6c5d0e, 0x6a1749ff, 0xef7c56d3,
+ 0xe2e966e3, 0x3f7dab11, 0x8f9c5bac, 0x96fc73de, 0x78b1cf1e, 0xf967b80f,
+ 0x471ef8ab, 0xe30437cf, 0xc3f3d740, 0x6bb17494, 0xbacfa33d, 0xaf144c5b,
+ 0xd0b94f23, 0xb8e2303f, 0x0dbfef13, 0x990edf7b, 0x90e0a4c6, 0x16eb0d43,
+ 0x1bd0827a, 0xdf80fcfc, 0x1d79e153, 0x6e37ca37, 0xaff1be36, 0xfb886b8a,
+ 0x4f5add32, 0xdb9009f1, 0xbe82c37b, 0x8d257d97, 0xef50edc9, 0x9ca25a6e,
+ 0x534f0057, 0xef15df38, 0xd9a8566f, 0x3b97b93b, 0x589fe8d5, 0xfedf83f1,
+ 0xdf6b79f2, 0x58fa95f1, 0x5072f983, 0x0d9446fb, 0x5f2f962a, 0xbcc56e58,
+ 0xc07bb02c, 0x17fc215f, 0x5847efca, 0xd1d3c2cb, 0x69d51ede, 0xc73cf587,
+ 0x5f0a13d6, 0x123e4d0d, 0xa87ceef8, 0x15f61bf9, 0x9c07e79b, 0xbde9098f,
+ 0x9cf99676, 0x1bef8fc1, 0x6dff8ba5, 0x3524fffa, 0xfe544971, 0xa66e49e6,
+ 0x57a6124f, 0x589d22ce, 0x2c3e21ce, 0x4fe5849d, 0x2c3627cf, 0xaef61217,
+ 0x670ca1f9, 0x8de83a49, 0x0fbe1f5a, 0xbff5e97b, 0x4cfbe2e7, 0x856c8e77,
+ 0xe55ba89c, 0x55ea56b7, 0x8fbe053d, 0xd8ff03a7, 0x2b74f7f3, 0x7b1bffca,
+ 0x94507aa7, 0x107a4a7d, 0x4a6ff6bf, 0xc4beecd5, 0x5e5107c9, 0x1f599a54,
+ 0xfdf98632, 0xe2642627, 0xcdf3f1f9, 0x6f82cd84, 0xef2afc42, 0xdfc58a8c,
+ 0x77f84a97, 0x2abdda79, 0x8b79623c, 0xa86add32, 0x79ed66ef, 0x44b71675,
+ 0xc22379eb, 0x8b72fb58, 0x67ddf21b, 0xcb9e2f13, 0xaeed90b9, 0xbd13bff6,
+ 0x7bf9d880, 0x127ebe06, 0xc3a8bfed, 0x89b6f2c0, 0x9bf61b37, 0x1049760f,
+ 0xe997f73b, 0xee0fbcec, 0xe0fdf8c7, 0xe15fb932, 0x267ede21, 0xe013aca3,
+ 0xfb74bbf1, 0x0d7ce0f7, 0xf75cee8e, 0x53f81154, 0xc2fc0454, 0x18788c5f,
+ 0x5fa228e3, 0x11ecb598, 0xc4876ef8, 0xfb5d8bf2, 0xd2dde2f4, 0xfc7f40f8,
+ 0x55f28ca1, 0x74daddf0, 0xc1429fc6, 0x942efe15, 0x261d8823, 0x8306d5f2,
+ 0x427e886e, 0xed06ef82, 0x437d5890, 0x577bd8fa, 0xe977d11b, 0xcc33fd02,
+ 0xec31fcea, 0x108eb063, 0xbfffac23, 0xd219bdf8, 0xef710e98, 0x55e82f25,
+ 0x4a7c5fa0, 0x27dc31c5, 0x63b53df8, 0xed4d3ca1, 0x40ff2851, 0xcf2851ed,
+ 0xca147b50, 0x0a3da9cf, 0x362ba2e5, 0x14971c78, 0xce7fd867, 0xbbf83ce8,
+ 0x33a62f1b, 0xc32679b9, 0xc75b29d9, 0x63ae1d3e, 0xc7f3a587, 0xec75d14f,
+ 0x82ad93d8, 0xe0a12cfb, 0x6fefb3d1, 0xf820cee9, 0x93dfcdec, 0x6ccbe782,
+ 0xefe7f3e4, 0xcfdca0d6, 0x2e46f76f, 0x3daef80e, 0xc878875d, 0x123673db,
+ 0xf736efc6, 0xd12ed5c2, 0xb1524ead, 0x330bfb7a, 0x0b9d5def, 0x0277b0fb,
+ 0xeef9e8fe, 0xfdbf3280, 0xfb863fb7, 0x8c7c741b, 0xbe48f6c7, 0x532f4067,
+ 0x6fb943ee, 0xffba2fb1, 0xc77fd075, 0x13b07e9e, 0x3b086fca, 0xfbd8fb2f,
+ 0xbbf77db8, 0xaf7bd70a, 0xf70457de, 0x56fdee12, 0xf41f341d, 0xc229464c,
+ 0x99d056bb, 0xba71b788, 0xaefaf812, 0x1e395ae7, 0x0017ef11, 0x3c82b50f,
+ 0xfa091aba, 0x5b8f2560, 0xfeceefb6, 0x1cb9ef10, 0x3bf81351, 0xe5a38381,
+ 0xc19d4ee7, 0xf3289dce, 0x801ce9f6, 0xcefb1daf, 0x9cfbc365, 0xf0d93f14,
+ 0x4abf5b77, 0x17f32fef, 0x66f88de6, 0xfd0fd023, 0xe02eff1e, 0x02b9b20c,
+ 0x0d33f3e2, 0x2d85dffb, 0xa99f36cd, 0xdcfcf880, 0x9430e944, 0x6399acf3,
+ 0xf22f2e21, 0x94e4179a, 0x74a3861e, 0xf512ad8f, 0x2e6052b8, 0xdca17201,
+ 0xe71fc110, 0x46287215, 0x98971f56, 0x2efefb22, 0x7dac966b, 0xb2edce42,
+ 0x26fbdef6, 0xdffe21b6, 0x7c3c01fb, 0x465e20fd, 0x8efec1f7, 0x7dec4bd9,
+ 0xc73dbcdd, 0xd69dbeef, 0x0d3cbd27, 0xc1db63df, 0x2aed27db, 0xd623bfc7,
+ 0xa3a9e143, 0xe1f9d48a, 0x14f33f8f, 0x13b0a60c, 0x78bdf76a, 0xbe67de18,
+ 0x1d709dae, 0xfbd420fb, 0xd2bfa2a1, 0xf2fca03e, 0x072fc0c7, 0x0cd53ebf,
+ 0x231da1f1, 0x790649be, 0xefc19994, 0x21bb7187, 0x9ef4dd14, 0x61fac90f,
+ 0x2528fde0, 0x28f210dd, 0x4e5643a7, 0x01eec63a, 0xfb3f2cdd, 0xb433f013,
+ 0xf0245dc3, 0xfd2a08ef, 0xb6758365, 0xff041f0f, 0xb86a07ce, 0x3f7bd109,
+ 0x5bfc316b, 0xb277a7ed, 0x4963f370, 0x0bbbf8b1, 0xee7ae0f4, 0xc1959b3f,
+ 0x76a4ace2, 0x454963ff, 0xe2b276fe, 0xb27bec8c, 0xab235a52, 0xd794ceaf,
+ 0x09ae97d7, 0x0f4a1fec, 0x3cdcfc5b, 0xee0f339d, 0xff4149f1, 0x7aef626e,
+ 0xd85f3962, 0xecf904b7, 0xf14bfdb9, 0xbf2ab9ef, 0x81e3a7af, 0x08716fdf,
+ 0xd3f82af9, 0xcf7b350c, 0x4cbed957, 0xb5bb67cc, 0x614a7df3, 0x6f5c798f,
+ 0x69fbb930, 0x93275394, 0x7f4c19eb, 0xc9e1b4bd, 0x710d7c1f, 0x9eccbda4,
+ 0x726164ba, 0x17f77f23, 0xcc7bf82a, 0x7d19c383, 0x2abd9be5, 0x53d327b8,
+ 0xbc82e11d, 0x26a586ed, 0xdc1bb7cc, 0xa189f7cf, 0xfc1f9080, 0x1a7fd0f4,
+ 0x0efe7d28, 0xc805bf2e, 0xb9d01ee1, 0x8cf1fd68, 0x49872843, 0xb86fcb2e,
+ 0x9c7cfb55, 0xbfa864ea, 0x317e3194, 0xcb8fe807, 0x55cf422b, 0x57a463c3,
+ 0x021f017e, 0xc0fd40b8, 0xf0fbdf4f, 0x1e33f069, 0xfc02fc65, 0x0f513307,
+ 0x7ee51bb0, 0x1ef63685, 0x0bbd9598, 0x4242f222, 0x87658ff1, 0x5760755a,
+ 0xf1fe6ade, 0xc4f9f5f2, 0x8f1409b1, 0x3e597b0d, 0xfe8ee5f7, 0x6f802451,
+ 0xf0d7e128, 0xb7cf0a9c, 0xa87777a8, 0x5079c3c7, 0x70164bde, 0xb201e626,
+ 0x181e78f7, 0x20c9b7fd, 0xa7d81f97, 0x50f44161, 0x1155acf3, 0x833cc06b,
+ 0x8e51e9f7, 0x98f7f589, 0xf7d91f39, 0x5cd2e8d7, 0x220aae56, 0xa01ea94f,
+ 0xa03d058d, 0xf5bb4252, 0x65097de3, 0x258fff00, 0xe216b1e2, 0x3a2f9810,
+ 0xbf070d85, 0x899df11b, 0xe04d1cc4, 0x6ec27afb, 0x5a6fb69d, 0x3f57d07f,
+ 0x63ff3dd9, 0x69f2198a, 0x879e1646, 0x1f8ef0e9, 0x16c7ef85, 0x43f81a47,
+ 0xeb78f126, 0x175f16c7, 0x8f1fd5e8, 0x6fc0908e, 0x0d5fc749, 0x7d7d8be3,
+ 0x35a475ac, 0xed17fa06, 0xfbd3be83, 0x42bda25d, 0x0274b2bd, 0x11678bc4,
+ 0x5efcd77c, 0xc9a3d335, 0x0b3cec3b, 0x7520dabe, 0xc73be346, 0x32bb9319,
+ 0xa684ff68, 0xab3da11f, 0x51ba27cc, 0x6ed7ba3d, 0x77b126de, 0x4e8c6c32,
+ 0xfc5d47eb, 0x7f3a74c9, 0x41efb53d, 0xdf6babaf, 0x28a6ef8f, 0x7b5ef9ed,
+ 0xbc2fe94a, 0x7fe83f8e, 0xca6fb100, 0x0080005b, 0x00000000, 0x00088b1f,
+ 0x00000000, 0x58adff00, 0xe554700b, 0xdef73e15, 0x66cd927d, 0x421b22f3,
+ 0x260ddde2, 0x9b709601, 0xf51e4357, 0x8ca4109a, 0x6388376d, 0xfadea56a,
+ 0x59092040, 0xd6a27509, 0x0071a6e1, 0x3b634ea9, 0xb33088a3, 0x2331e1d2,
+ 0x3054d353, 0x32d740a3, 0x5da96255, 0x66d42d8b, 0x88d46b98, 0xf1a6c935,
+ 0xa1986655, 0x5ef7fce7, 0xd6086f76, 0xe6ccdd3a, 0xe73effec, 0x9cff8f3b,
+ 0xaa36c01f, 0x5cfb0195, 0x8bdff016, 0xed2bf1f6, 0x8ca2c020, 0x06ac43b0,
+ 0x27c8f2d8, 0xfb0dbd7f, 0x990dedd4, 0x47f18b63, 0x475f8e3e, 0x5c8054b3,
+ 0x000ea580, 0xd4c0154f, 0xbee8b4fe, 0xf097f500, 0xd9b00350, 0x80453f87,
+ 0x9c944e8f, 0x8ff1c6ed, 0x8703b0de, 0x9f1b275d, 0xdb107c9e, 0xf9a7f65b,
+ 0x059e349c, 0xef8d3e6a, 0x38aa8d2b, 0x6a7e3ee1, 0x27073ba4, 0xfb4ba60e,
+ 0xbdc3fc71, 0xc61fcfa5, 0xafe786f6, 0xaecd8897, 0xd9883c5d, 0x0d885fd8,
+ 0x3e6dffea, 0xfd7e075b, 0xfd2e75dc, 0x92e0e15c, 0xf8d0379f, 0xce896cc1,
+ 0xcb39a569, 0x75ec2e00, 0xf00e50cb, 0x7dcac419, 0x731f00c5, 0x1b8f18ea,
+ 0xcf87f3b7, 0xb3c03c73, 0xe494a50e, 0x37fbb8de, 0x7947ab7f, 0xe77e0f9a,
+ 0xdfc865e9, 0x40b93386, 0x5cf2c0fb, 0x787e0186, 0x1a728b98, 0x9708b5e7,
+ 0x60085abc, 0x067158fa, 0xb4f89284, 0xdefb721f, 0xe2b81977, 0xd32073b7,
+ 0xca1aeed2, 0x965fbdf7, 0x8e83b76c, 0xd9c3dc31, 0x7d0eff68, 0x65798608,
+ 0x09d5f109, 0x0808039a, 0x97847298, 0x9c085400, 0x13ff840c, 0x65ff864e,
+ 0xa490dcfa, 0xf8cf222d, 0x1941e0e8, 0x6cfce0f0, 0x702bf970, 0x97e3a2b9,
+ 0xdf74a278, 0xad66c44e, 0xcd500598, 0xbd592df6, 0x8b7fc924, 0x15e9b230,
+ 0x977a7fdc, 0xef627253, 0x0cee1bb8, 0xa73eae87, 0xeb64cc55, 0x053eb9d7,
+ 0x7fb2765b, 0xadbfcf53, 0x51c810ed, 0x27d15f5c, 0xb48fde56, 0xafcbd0db,
+ 0x0c35e1fc, 0x8f2781f7, 0xee78669e, 0x3a1de079, 0xe98794f7, 0xb8eb4e0f,
+ 0x23683827, 0xd6fdcc39, 0x56c0a6b9, 0xc73efc49, 0xc7fb35f8, 0xae5b399e,
+ 0x4763fee0, 0xda039716, 0x7c425df3, 0x67c459ec, 0xfe7e3d32, 0xa783a461,
+ 0xf15732fe, 0x476fcd5c, 0xcfdb34cf, 0x1c738f6c, 0xe483b793, 0x829bfec0,
+ 0x9e228de1, 0x09903603, 0x4b9dd1bf, 0x422d7e18, 0x9ff48328, 0xdfcac8f8,
+ 0xfdcd3e4c, 0xfdccfe4d, 0xa43d79cd, 0xc261c42f, 0xc2cf2f11, 0xa24539fe,
+ 0x6f09ae45, 0x43d33cbc, 0x3fd63efd, 0x14ed8591, 0x9fa36b7b, 0x1736dfa8,
+ 0xbf9073d8, 0xea4e36b6, 0x42afd603, 0x0531a316, 0x2ffc3bc7, 0xd841b81b,
+ 0xab767685, 0x93906761, 0x5a3f236d, 0xdf5dba03, 0x8bc7fb5a, 0x76e0179c,
+ 0xfa03b018, 0xf7be39cb, 0xe3a42ec7, 0x13b4bf03, 0xbe10e87e, 0x4e5fb431,
+ 0xbcbf877d, 0x4db96af8, 0xa58d804a, 0x5f831bc6, 0x22ca09b5, 0xcf84cfb8,
+ 0x014bf2a3, 0x1b39119e, 0x8508579b, 0xa5c70f34, 0x3a81da18, 0x90fa94e8,
+ 0x787c4b9f, 0xe1dfe12f, 0x1f939588, 0xf12eeb98, 0xe71feb0a, 0x7d23af4e,
+ 0x1e562d83, 0x647d474e, 0x40cb803a, 0x65c52b9a, 0x0cfd43c4, 0x23015c58,
+ 0x9518f1fe, 0x1d849ce8, 0x8f9106da, 0xfd37ea46, 0xaaa4ed13, 0x7a0c8f99,
+ 0xfc93f392, 0x0195db5b, 0xb2aacfdd, 0x2cc0c8f9, 0xc327f1fe, 0x4060fb0f,
+ 0xd617fdd0, 0x7ae710b8, 0x59006703, 0x64df7f20, 0x3cb937b4, 0x54e30131,
+ 0x0552ebc2, 0x18febfe4, 0xf5db01ea, 0x44abd8b6, 0x07a1ebd1, 0x310759f5,
+ 0x6b21bf7d, 0x8f70e6fc, 0xfc1c703b, 0xa91c598b, 0x8dbbd433, 0xd1e9008b,
+ 0xee8cfd05, 0xd102e2e4, 0xa314c16f, 0x446cf832, 0x97467611, 0x15d19843,
+ 0x25746110, 0x0aba33f4, 0x19bd1806, 0xa2c28ce2, 0xf8b01f58, 0x58df13ff,
+ 0xdf6f921a, 0x5a465fc7, 0x66441b75, 0xc32987f3, 0x078dafce, 0xaf9af546,
+ 0x500ac78f, 0x6baf8cfc, 0x8cbf32e1, 0x8b89b9d9, 0xd711ec93, 0x27ea21b9,
+ 0xdb1a08da, 0x5c3206e7, 0x1046e7dc, 0x066ed46d, 0xbe5bb599, 0x9ab51e22,
+ 0xb3425362, 0xbb3cd2e0, 0x70345c9d, 0xab2c25e9, 0x185afa93, 0xd4db5910,
+ 0x149f201b, 0x27d6afff, 0x559f1114, 0x889f4d69, 0x03b22218, 0xc61b61bd,
+ 0xa6caaad7, 0x2f6c62ee, 0xb7a93c08, 0xed2a9beb, 0xfbd39e12, 0x8c72f08b,
+ 0xee0c2eab, 0x2845c46e, 0xa916a016, 0x0396f6e2, 0xb85395fa, 0x54ff225f,
+ 0x10f100dc, 0x40b9e373, 0xc256d0fe, 0x3e2dbfee, 0x3aef3f5d, 0xda00f494,
+ 0xe62ba777, 0x2de71115, 0x74792dbd, 0xe8776e0f, 0x2b9bbefb, 0x65057e2e,
+ 0xae39e272, 0x383ca48a, 0xadb1baae, 0x4f776271, 0x57ee7920, 0x5020af38,
+ 0x9af3ed7d, 0xfc488afc, 0x4804ab80, 0x3dc605cf, 0x2f58383d, 0xef9d3c49,
+ 0xe96be763, 0x383ddd25, 0xbc3fa4f4, 0xa44bf690, 0x90b5f6eb, 0xd24dcff0,
+ 0x94b90135, 0x27f667c6, 0x1a38bf7a, 0x1f137dc3, 0xaeb8c1e0, 0xd394a031,
+ 0x56bc5db9, 0xf87a8954, 0x0779da69, 0x4fb4dfe9, 0x0772950e, 0x4327dbca,
+ 0xbeecc1d4, 0xaf2577c1, 0x77da4e2a, 0x0fdc5ee2, 0x870aa871, 0x5c38ed9b,
+ 0x493916d3, 0x6fe956b4, 0xa73a11c6, 0x12e9f89e, 0xbe91d6a6, 0x38cf3327,
+ 0x37fe603e, 0x2333b75f, 0x313f1d2e, 0xde8170fc, 0x7f8a430c, 0xf8b89d75,
+ 0x1e303ff9, 0x247b4d76, 0xec7f5e9a, 0x26f06e99, 0x3ab30afd, 0xfd30dc4b,
+ 0x19c86eac, 0x85bcd813, 0xc6fcd2f7, 0x14c52333, 0xd1186f6f, 0x42dc30fa,
+ 0x02d9f8e2, 0x7b8ddedd, 0xfb82fe41, 0x8b42f73a, 0xb8c74a80, 0x1088f9bf,
+ 0x9b5ca275, 0xda304f29, 0x743fb62a, 0xd0649da1, 0x8f93d97c, 0xe437ad72,
+ 0x83fe1cea, 0x6d3a8303, 0x1bbc92a3, 0xefd7fe0c, 0xca66fbb9, 0xed4436fb,
+ 0xdf8ef8c9, 0x36e891f6, 0x90fdbbe2, 0x21229fb5, 0xac65dfc9, 0xabbca0ef,
+ 0xeb37f298, 0xfc782ebc, 0xba97145f, 0x9bfdac86, 0x4c39e902, 0x063dc60f,
+ 0x9f78be46, 0xa3e48731, 0x71f379bc, 0xb289d447, 0x2ddbde6d, 0xe85da8f9,
+ 0xdd1c5891, 0x5bb328f3, 0xc9ec3e73, 0xfa623666, 0xc01d86e7, 0xc71360f2,
+ 0x329c07a5, 0x81e963e9, 0x62df963c, 0x0af2ce5e, 0xcecc138c, 0x1c262297,
+ 0x990bddda, 0xcf1e4153, 0x9978e179, 0xcbf37944, 0x6f78655b, 0x333f9241,
+ 0x0e116f6f, 0x3ed03b37, 0x1f01efa6, 0x50357de5, 0xae0374f6, 0x87653eab,
+ 0x834f8e28, 0x0be98fae, 0xebbfcb3c, 0x64fd2b86, 0x231cc207, 0x4f31f86e,
+ 0x2dc3c14f, 0x253101ce, 0x75f135cf, 0x2b4b7a1a, 0xa78cb2cb, 0xeb2cf34b,
+ 0xd6836a33, 0x0f1caaf5, 0xd69c50d5, 0x8bca67d7, 0xc341f32c, 0x306f1c3f,
+ 0x5deedbe0, 0xb7ec8a71, 0x66feb3d1, 0x657b29c2, 0x53be6585, 0xff102638,
+ 0x2cda9f0d, 0x8426fc7a, 0xce51d39b, 0x0f31b7da, 0xc6ea73c1, 0x4d6ee3ad,
+ 0x7ee75a05, 0xa01f253b, 0x7b6b44fd, 0xf987b4c0, 0x1ed53f30, 0xae7b7892,
+ 0x50f649e0, 0x782c0b03, 0x0aebc4cf, 0xf3071efe, 0x6ee1ba87, 0xd86e5fc6,
+ 0x9b5e7b8a, 0xc57cf715, 0x7ac1738a, 0x1185ce2b, 0xf5d7ce2b, 0xa80d7158,
+ 0x778adc56, 0x5fe659d4, 0x6964dfdf, 0x655aee97, 0xba30bf99, 0x7c5ed2da,
+ 0xfccb76e8, 0x59770325, 0x6d0e97c6, 0xf69b8cb4, 0xdfff5335, 0x619e6d88,
+ 0x5ff03c5f, 0x53caffa2, 0x99ce590f, 0x888077a9, 0x6bd6f840, 0x5703bb00,
+ 0xedfabdeb, 0x578af07e, 0x0f029deb, 0xf5339de5, 0xa7fa453f, 0xffe86f38,
+ 0xc629d233, 0x17bd37b9, 0xfd37271e, 0xcf1e9a6e, 0xb886845a, 0xb06d7a4c,
+ 0xcfeb7ab3, 0x3a737662, 0x1ee303c5, 0x18f71b0b, 0xecc1dfac, 0xdbd3ec21,
+ 0x493a5c52, 0x5ce2ac71, 0xaaf899b8, 0x512722d2, 0xd0b9a84c, 0xf3419cdf,
+ 0x387d1065, 0xfaf0339f, 0x36072d5e, 0x7b613f8b, 0x5bcf126e, 0x03215ed4,
+ 0x8a5fd727, 0x4b30b1f6, 0xbf9e0ec5, 0x6ae718da, 0x55a27bf5, 0x052d8376,
+ 0xf35ac697, 0xfe3108fe, 0x316ffc4c, 0xe7cc08ea, 0x3cf941c1, 0x05f68aef,
+ 0xa45fcb66, 0xafcb025d, 0xbd6f9614, 0xa27629ce, 0x22f15c6b, 0x9e4aeb8a,
+ 0xb8882f32, 0xc892f24d, 0xeb4e33f2, 0x2412a123, 0x6a565d18, 0x754cab66,
+ 0x30a39618, 0xd19f290f, 0xfb187aaa, 0x2f46ad3e, 0x1253e97b, 0x18838a54,
+ 0xdf394717, 0xfb5c4ab6, 0x45c7dd66, 0xca2d6f74, 0xff501790, 0x3c8ef795,
+ 0xabe30b94, 0x412a8bc6, 0xb1c43ea0, 0xda63e1fa, 0xdf8a5964, 0x7bb3b0ee,
+ 0x6a7a8c0a, 0x599381ad, 0x9c61dd4f, 0xac5b8a3b, 0x76bdf8c7, 0x478675e8,
+ 0xd59c7fbb, 0x926f689f, 0x7bbff70f, 0xea82a7be, 0x252b9049, 0xeb370ebd,
+ 0x7fe102ab, 0x7acd47b9, 0xdbf35af4, 0x752c17fd, 0xefd61c2e, 0xafef6b97,
+ 0xca4d7b32, 0xfa3fefad, 0x77bb1a58, 0x6c2b1f46, 0x7fdc9a22, 0x36bfed92,
+ 0x3ec596f2, 0xbbf9ecee, 0xa47eeec5, 0xd7196bbe, 0x05eca672, 0x3476bf28,
+ 0x100fc57f, 0xce2389bf, 0x5133aa1a, 0xa60fdf5f, 0x13dac1d4, 0xbce9cba5,
+ 0x3fe72eff, 0x5b23be19, 0x905b60e3, 0xd6fcf394, 0x6dadac73, 0x299d18d5,
+ 0x9a9759a7, 0x287bf1d4, 0xa67ea1b3, 0x6cd239b8, 0x41232cef, 0xb91f6f3d,
+ 0xdd136e71, 0x0e8523bf, 0xf44b4e9b, 0x4bad7e76, 0x4958af6f, 0xecf76134,
+ 0x8474baa0, 0x7b439903, 0xf9f79d18, 0x516e0701, 0x403ca797, 0xa69a2672,
+ 0x2977a73e, 0x288ad1c8, 0x2a664c9e, 0x873f520f, 0x167e5fc9, 0xf284b3e3,
+ 0xfabc0bff, 0x7018c06b, 0xad6ddf60, 0x7a4fd794, 0x647fbb75, 0x2aad2ddf,
+ 0x199952e2, 0x40eb4ade, 0x917bd8d6, 0x8ef9afc9, 0xd52f7542, 0x4eb70921,
+ 0x263907b7, 0x74198eff, 0x28d4d537, 0x1d064bdf, 0x384afbe5, 0x4edd87f2,
+ 0x7e601fd8, 0x315e5320, 0xfba9cc7d, 0x8bc00d81, 0x711defe3, 0x3cf6473e,
+ 0xbca67917, 0x9633b305, 0xcefc57ff, 0x6138a319, 0x14e4bfbe, 0xe10b3f8b,
+ 0xec979cfa, 0x4c9fceac, 0xbfc86b17, 0xb2afbd3b, 0xa0a6ebbc, 0x40e4c032,
+ 0x8c7e2849, 0xdbee751e, 0x2a4dfcc9, 0x7ffe9d5a, 0x103b677d, 0xa68c7564,
+ 0x3bc691e7, 0x8b77299b, 0x7b9338f0, 0x4813977a, 0xe37b89ce, 0xbbd8854f,
+ 0x7c445492, 0xdf3af28e, 0x7ca6bf26, 0x7dc91ca6, 0xcd6edcbe, 0x7be4a2f7,
+ 0xf212f6d6, 0x7f51c403, 0x3bb813c7, 0xfeb2cf57, 0x9aabe90c, 0xa09da7bd,
+ 0xa231b638, 0xf525a7bf, 0x3bc0ffde, 0x0f61b7a4, 0x5ad7638b, 0xcece533f,
+ 0x0f0cc313, 0x2487f394, 0xa79c8a5f, 0x7eef2983, 0x3ecfc713, 0xbebf1215,
+ 0x38c2897c, 0x3c4cdf7b, 0xc448b177, 0x5ec79df5, 0xd276473f, 0x33ffd469,
+ 0x739da9df, 0x9acc7eb0, 0x6f1a7ded, 0xc97c9485, 0x6f9fae69, 0x04c7aeb3,
+ 0x886cfc99, 0x0af291fc, 0x5e2927bc, 0x8be4f79b, 0x69c19d46, 0x4d78b1af,
+ 0x6efd91e7, 0x5f7654e3, 0x7d05ef99, 0x5447de1c, 0x2cdd2b97, 0x79d70b8e,
+ 0x17cfb224, 0x74e306d1, 0x34e4d8ff, 0xa33c2ef6, 0x54e79d8e, 0xd93b253e,
+ 0x1e5356f2, 0x6f83b9d5, 0x27ea32ac, 0x36a91efd, 0xce9ab2ec, 0x1943fe27,
+ 0x32a93eec, 0x4571abf8, 0x0cbade58, 0x177f4154, 0x1e19de30, 0x7752cd7b,
+ 0xa2bf07fd, 0x17f0846b, 0x000017f0
+};
+
+static const u32 usem_int_table_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33ab678a, 0x32ea7830,
+ 0x31e9c830, 0x43d24c30, 0xb712d388, 0x9fa65173, 0x8181859d, 0x81b98813,
+ 0x5f881798, 0xbc303231, 0xff5e2466, 0x3b046147, 0xe181804b, 0x0b6f9013,
+ 0x32089fa4, 0xb2075c30, 0x0371033f, 0x88073f90, 0x35b10057, 0x480fbf90,
+ 0xa3e204df, 0x1845fc40, 0x095ff9bf, 0x42156fc8, 0xe3443fe5, 0xafc4159f,
+ 0xf980825f, 0xb1e40472, 0xe42269e1, 0x0a6dc7c7, 0xde040ef4, 0x67ca86a6,
+ 0xe0606553, 0xaac58a07, 0x91dbf843, 0x6281f3e4, 0xf610aaec, 0x8606396b,
+ 0x1db9405f, 0x7dcdd86a, 0x0dff9403, 0x9a86ab94, 0xf1b90003, 0x03685054,
+ 0x00000368
+};
+
+static const u32 usem_pram_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x7dedff00, 0x45547809, 0xbedd70b6, 0xe9d3bb7d,
+ 0x84849d25, 0x1674b090, 0x26c43510, 0x630a0840, 0x944c2127, 0x615151a8,
+ 0x8408ec44, 0xf9707d90, 0x37d7d470, 0xdf95012c, 0x3e30eb89, 0x0e0c1a74,
+ 0x1036a0c3, 0xc6c06a30, 0x680e8300, 0x8cc08378, 0x364584cb, 0x5c710921,
+ 0x7f9e6466, 0xbb75539d, 0x48e9bdef, 0x9bdffc74, 0x3f6fef37, 0x556ea2bf,
+ 0x5b3aaa9d, 0xaa753a9d, 0x42049462, 0x1be426ae, 0x71f4d1f8, 0x10921091,
+ 0x69f2bb4e, 0xb910963a, 0x96bfca27, 0xff6e0d56, 0x401904fa, 0x5be6b9c8,
+ 0x4254e65c, 0xc1513d3c, 0x39f969ab, 0x4cdf9e7f, 0xbcb60bcb, 0x7cd230ef,
+ 0x08d116f5, 0x16ed86e5, 0x4ab9df6c, 0xd6be43f0, 0x55d8fedc, 0x45bddf34,
+ 0x68286b24, 0x2066ceb2, 0x889c8439, 0xb467ec22, 0x2122481b, 0xad961665,
+ 0x1663bd5e, 0x62de57f4, 0xfeda1626, 0x81e8b344, 0x82b582fc, 0xaafed09f,
+ 0x4a665b5f, 0xf9e6f0a6, 0x45c58085, 0x371f6bf3, 0x2c84ecb9, 0xa381feda,
+ 0x19c846c3, 0x9971145f, 0x81e51e70, 0xfc2a424c, 0xd324a71b, 0x041b15f6,
+ 0xafc281b7, 0x13be7558, 0x2cd157c6, 0xbc29170d, 0xe25675ca, 0xfefac91a,
+ 0x6d7f4086, 0x2dbfb0c7, 0x57f40652, 0x136ee17e, 0x929e6111, 0xd355da07,
+ 0x95bcc071, 0x1af8cf7e, 0x18446b89, 0xa1bfd59f, 0x357ad1fd, 0x986e0b2f,
+ 0x78818d62, 0xaf9d1c61, 0x60bfa659, 0x9bd5f983, 0xf3d5d846, 0xf30add28,
+ 0x36aff0a8, 0xf8c1b14d, 0x32ca9b56, 0xd72af0c3, 0x515c493d, 0x4cadf1aa,
+ 0x9555e81f, 0x3e33d3eb, 0x054f19a2, 0x06c05925, 0x6e9bf678, 0x7efe151c,
+ 0x7a458858, 0x3513ae57, 0xf1e529f0, 0xfd3efcbb, 0xbc83c527, 0x9b5feecd,
+ 0x02dba61a, 0x2bb7fd27, 0xa71eb74c, 0x1ceec742, 0x7d257c35, 0xc741e80c,
+ 0x6273e8d3, 0x092f84fa, 0x2e7ca7d3, 0xbe33d3a4, 0xf4ae9891, 0xb3fbf1b9,
+ 0x574c5cbe, 0x3e983cf9, 0xd4c22bef, 0x7ac12bef, 0x31d37c6b, 0xf179f26d,
+ 0x72be8bfb, 0xeaf9d74c, 0xdf7afbf0, 0xf8374c42, 0xb2fefc64, 0x01a6396f,
+ 0xbe4da74e, 0xfb369895, 0xab6f58fc, 0x2da61d6f, 0x5f7e00be, 0x98e7f1c1,
+ 0x748cf248, 0x710f0efe, 0xb8937252, 0x449e4f62, 0x2c2571f3, 0xce53389f,
+ 0xa27cd133, 0x3e29e697, 0x7982ab92, 0xae4f9a66, 0x1f43e563, 0x3451f924,
+ 0xe566543f, 0xf93c2b69, 0x6b4f9a16, 0x5623e564, 0x34d1f9c9, 0xcacfc23f,
+ 0xcc10db2f, 0x65fcd2b7, 0xd59e5601, 0x346c0a4a, 0xf964159f, 0x029ebdec,
+ 0xb767cd3b, 0x87ce7cb3, 0xe6838172, 0x7b583a73, 0x1203de3d, 0x6d284d99,
+ 0x3c8b959e, 0x6f3441c6, 0x37137722, 0xa37c8bc5, 0xe28138c7, 0xf9617241,
+ 0x5827f976, 0xc2e4c9be, 0x367976f2, 0x1e4b3796, 0x572a3f2c, 0xc9b37961,
+ 0x917fe583, 0x56fcc5ef, 0xa6e58bc9, 0xfac37ffa, 0x2c5e4d5b, 0x865faa4f,
+ 0xc64916f9, 0x1beacbf2, 0x498b7eb1, 0x9627f2c6, 0x9933d2fc, 0xef04fb96,
+ 0x8b67c053, 0x49396f05, 0x2409fe07, 0x69fe5095, 0xe074c810, 0xc98107d7,
+ 0x20fcd1c6, 0x605dca13, 0x200bce57, 0x001bf8af, 0x1f17b2f9, 0xcf384549,
+ 0xc2891c21, 0xc70e2f11, 0x03573bbd, 0x5cbbbdc7, 0xd422f381, 0x1fe96c5b,
+ 0x2beec09c, 0x5dd9e3b5, 0x0579c0a1, 0x37fbd8e1, 0x26eff72f, 0xbbf3c76a,
+ 0x0b4e052a, 0xdfed89c2, 0xd3ed3678, 0xbed367e2, 0x20767e10, 0x37fa127e,
+ 0xb577ec9e, 0x377ec9f8, 0x70779f84, 0x07fa833c, 0x5abbd367, 0x377a6cfc,
+ 0xe03f9f84, 0x6ff48678, 0x69efd95e, 0x5efd93f1, 0x221f3f08, 0xc1fed49c,
+ 0x8b5f7e69, 0x43f7e69f, 0xe104f9f8, 0xbcdfef0c, 0xe2d41ec6, 0x10c1ec67,
+ 0x3f113a7e, 0x4e0ff697, 0x7e2d41f3, 0xf0860f9a, 0x678e25f3, 0x35e6ff54,
+ 0x3f1690f6, 0xf0850f63, 0x33800443, 0xd9e37fba, 0x3f1691fa, 0xe10a3f5b,
+ 0xc67082c7, 0x393c6ff5, 0x93f16b1f, 0x3f0871f3, 0x42670871, 0xfd6ce0ff,
+ 0xad9f8b58, 0x93f0871f, 0xf5267082, 0x7f395e6f, 0xe727e2d6, 0x64fc21cf,
+ 0x3e3c9c20, 0xd8e1421e, 0xf2d386fb, 0x2d3f1689, 0x33f0849f, 0xf214e10a,
+ 0x4e045cf1, 0x7e2d09ee, 0xf0844f72, 0xae708393, 0x969c1fe9, 0xb4fc5a13,
+ 0xe7e1089c, 0x5d73846a, 0x7b95e6ff, 0xdc9f8b52, 0xa33f0c93, 0xc1b496f7,
+ 0x40d7437a, 0x4c9b48b7, 0x08f1ee38, 0x64e8beb4, 0x26e9d179, 0x8a888760,
+ 0x3dda417d, 0xdb6fad22, 0x08fd9b10, 0xf919db51, 0xec78c037, 0xdb52fad4,
+ 0xd1b93119, 0xd62bbb1a, 0xc7c9a713, 0xea6b2517, 0x69a49427, 0xbf4e07ca,
+ 0xc83e534c, 0xa7c9ad9b, 0xa9a95f94, 0x5f2ea43f, 0xf0b61f93, 0x54fd4d5a,
+ 0x3e4d26f9, 0x344ff97d, 0xde3787f5, 0x64bf29a5, 0xfca68565, 0x4d02ff52,
+ 0x3f75f2fe, 0x151fd4d3, 0xbf29a458, 0x4d11e5a2, 0x13e0e8f9, 0x3d98fc9a,
+ 0x8fea6acf, 0x29a35f6b, 0xbd787f1f, 0xc7427ca6, 0x529e4d26, 0x72e279c2,
+ 0xcf81179e, 0x07ebb309, 0x0b9ed099, 0x37984dda, 0x4ed0db25, 0x5ccbda0f,
+ 0x4d1d29c7, 0x006baf06, 0x8486814d, 0xc979dbae, 0x507497e5, 0xa577df3a,
+ 0xfd2712f7, 0x7bc99f7e, 0xfd823385, 0x902fe949, 0x065d4824, 0xcbe5f548,
+ 0xf97fc624, 0x1c461729, 0x0d6beda1, 0x696223dd, 0xf790cbbe, 0xf1f94094,
+ 0x7c80c159, 0x3a922d19, 0x266d17a8, 0x4b2ff768, 0x564179cd, 0x21f2e7f1,
+ 0x3084ee54, 0x3792e5dc, 0xe78aec09, 0xc193dfeb, 0x421868ce, 0xc84c95e7,
+ 0x82f784af, 0x3f6d0672, 0x4bc92ca4, 0xd44d99e1, 0x6ff7570e, 0x6267fda2,
+ 0xffd04dff, 0x37fa3efa, 0xfa6ae5a7, 0xae5a1a8f, 0x44ca3fe9, 0x3b5277fb,
+ 0xef10feb3, 0x4ae9129f, 0x0e115e42, 0xa1e6ff61, 0x32ffd8e5, 0xa88fdd13,
+ 0xf50e8ffb, 0xf1f20cdf, 0x109ff43a, 0x5769fe61, 0xb43fe76a, 0x137f3b42,
+ 0xfaf6ff9b, 0xa3fef33f, 0x0a6ffe71, 0x1ff3667f, 0x6fe6c15a, 0xfd437066,
+ 0xdff8423b, 0xa77ff309, 0x4fa7f9af, 0x587fced4, 0x66fe7695, 0xf5bbffd6,
+ 0x36ff7927, 0xe13dffec, 0xb0ff9b24, 0x64dfec2a, 0x7f81baf6, 0x75d1294c,
+ 0x193fda7e, 0x40d1154c, 0x0fda1760, 0x28e323a4, 0xb0f21313, 0xb8e38690,
+ 0xdbf19a2f, 0xdf94d117, 0x88c8bf50, 0x9aa7e21f, 0x6a43ee8c, 0x6e542cb8,
+ 0x1e8133c8, 0x1fba72c2, 0x3a87cb99, 0xfe4445a7, 0xfd994f26, 0x3b78e9c3,
+ 0xf219445b, 0xe49a9e73, 0x6b577d07, 0x40967726, 0xc209233b, 0x1e9e4ff7,
+ 0x2f3d46b5, 0x51b73a7d, 0x91a1d13a, 0x391e362f, 0xa3ac8c9f, 0x26042be3,
+ 0x9fce1718, 0x421dfba0, 0xe94711f7, 0x93d2027e, 0x7e8fed12, 0x43f74e3f,
+ 0x9b96a4c4, 0x64476c7a, 0x7419fbcf, 0xe512b7fc, 0xde79c1e7, 0xe1452281,
+ 0x4ffe1919, 0xd0357dd0, 0x95a36e63, 0x1e3c3f22, 0x6f9c1f3a, 0x5fe0a977,
+ 0xd2bc7023, 0xf6f1b7f6, 0xe147c604, 0x36b272cf, 0x0f72511f, 0xb79f28a2,
+ 0x67035e32, 0x4d2ff106, 0x5f6feda2, 0xb42243b1, 0x74a141ce, 0x97e002c8,
+ 0xc4122407, 0x0247647d, 0x40cce4c9, 0x0c9d7be1, 0xa5d36dfe, 0x382a1de3,
+ 0x4f28a4b3, 0xaccf1d09, 0xef1c45fb, 0xbcb6af0c, 0x63d5bb63, 0xcae9a2c8,
+ 0x494224cf, 0xb6b97b7e, 0x6d3a8efc, 0xda85cefe, 0x098f9d3c, 0x5952b5d6,
+ 0x874e9dff, 0xd0aef3ce, 0x69c4e9bc, 0x9b2f367e, 0x35925cbd, 0x686d8474,
+ 0x034f2f0e, 0x13c413b4, 0x5def4fb6, 0x2681f29f, 0x0ea56f3f, 0xff8be71e,
+ 0xddffff4f, 0xc96daff4, 0x1aae3f8b, 0x9ae07557, 0x7aaae3f8, 0xd46eeb95,
+ 0x67fbe7e4, 0x5bcfea68, 0x9f29aa59, 0x535f38db, 0x4ff97b3e, 0xf952f935,
+ 0x3bfd4d7e, 0xca6bd617, 0x587ba8ef, 0xf97b7e53, 0x0cfc9ae3, 0xf5352fef,
+ 0x5abe9b6f, 0x9f6c2e53, 0xd703ac3f, 0x41b0ef4d, 0xa3fc0fe0, 0x299f0099,
+ 0xfbf0acfc, 0xa6125f29, 0x4c2e7c67, 0x530f41eb, 0x8d786efd, 0x4a6bb5a5,
+ 0x573e8187, 0x54a4fff8, 0xa5f41437, 0xfaf59f9e, 0xf4a7cf57, 0xcec91297,
+ 0x812ad250, 0xd63ac094, 0xe55eedc5, 0xcebe39fb, 0xd308b211, 0xcb93132a,
+ 0xf2834daa, 0xc1f20389, 0xbeb67511, 0x808092e1, 0xcde020f3, 0xa5ba004c,
+ 0x4d4bb5d0, 0x38cd74d7, 0xb110eecf, 0xc9901aff, 0x94dcb009, 0xff40326c,
+ 0x37a1b6c1, 0x78f1828f, 0x25be6336, 0xb3aded01, 0xe3f8a2be, 0x095fc046,
+ 0xd37ca7a6, 0xf3e13d31, 0x57dc7a62, 0x5f51e98e, 0xbe1da61d, 0xec7e9885,
+ 0xd0fd3193, 0x3fd31cb7, 0x3d311af9, 0xe9895bec, 0xd31f9f41, 0x53079f4e,
+ 0x55ff4f85, 0xf0ca3ae8, 0x73d74edf, 0x328eba6a, 0x3878d938, 0xf1851f5d,
+ 0x939bb046, 0xa71918c1, 0x563c47b2, 0xe02eabf4, 0x896a70fe, 0xef2b3f31,
+ 0xd705317b, 0x7f8b768e, 0x9ee1e824, 0x011b7f91, 0xc39ee47e, 0xed480174,
+ 0xfa7a7e7b, 0xe20789f5, 0xccbdfb41, 0x3187174f, 0xd12dcbbd, 0x0316af0c,
+ 0xd4d92229, 0xa2fe1b5e, 0xcc4caefb, 0xb41c491b, 0xb46fbbf7, 0x6d4b8047,
+ 0xc5efc041, 0xfed8baf0, 0x3bc01645, 0x39d7ecf1, 0xa4328e90, 0x4db8bb31,
+ 0x0494bb44, 0x7e03705f, 0xecd67a43, 0x6d3f024e, 0x139370f7, 0xb8a7bdd7,
+ 0x9fc15a9f, 0xfe0af2cc, 0xafe10e1e, 0x97f10931, 0x14bfc5f1, 0x3ba788fe,
+ 0x6151a6eb, 0xbe139dfc, 0x39ca7f1d, 0x1bbfbe89, 0xe277e344, 0x0544aecb,
+ 0x0943edaf, 0xe02de7ed, 0xa7bf0a7f, 0xc01892f9, 0xd93ec873, 0x87f7f662,
+ 0x4e80e74e, 0x6abc30b6, 0x3d9ebc1d, 0xeec0382f, 0x7064905f, 0x67808f1e,
+ 0xa40ead25, 0x3b6a6d3a, 0xef9b45a9, 0x028a1469, 0x62b8cf68, 0xfd028da6,
+ 0xcf1e74eb, 0x84993d00, 0x416702a9, 0x3c79c992, 0xe4c3e91e, 0xca2c437a,
+ 0x145f19fd, 0xc7a1fbd6, 0xf09c17d1, 0x31c99a38, 0xf9501eda, 0xf5df7a4d,
+ 0xe353e4fb, 0x37e04c5f, 0x17d2ad23, 0xd144bf60, 0x0381bfff, 0xbcc46232,
+ 0x2036b702, 0xe02be6ca, 0x7f4d06fb, 0x394b9db4, 0xed26fbc3, 0x48c1e4db,
+ 0x4afc284e, 0xf0468a97, 0xbe038d49, 0xf6b538b5, 0x5f26ac51, 0xa9c832db,
+ 0x1fe097b1, 0x72928f54, 0x577c08c1, 0xcba6d9c5, 0xd02e5b68, 0x538255f1,
+ 0x6055f80a, 0x3aa3aaf5, 0xf0175e4c, 0xaf5be2cb, 0x46cd4172, 0x7c7eaf9c,
+ 0x1a377e94, 0xbf8f7d8d, 0xafb9ec52, 0x6c7c8224, 0xcabb7ae1, 0x240afcc0,
+ 0xf9c0764a, 0x1d924917, 0x6871d937, 0xd07e10b6, 0x51fb470f, 0xf33815e5,
+ 0xd6b752fd, 0xcf91957e, 0xbf981acf, 0x6eefdf40, 0xe2e137e8, 0xb0d9abf8,
+ 0x5bcc0a7f, 0x969ac78f, 0xca2f26f3, 0x272ffd15, 0xbf05478c, 0x6ec96295,
+ 0x58afc291, 0xd5f70477, 0xc47924a7, 0x17a2df03, 0x96df8f7b, 0x9aaac274,
+ 0xa1da4cb7, 0x7972bb9f, 0xdb75c447, 0x9f5f5407, 0x1e44bdfe, 0xa05cba01,
+ 0xa0e354b5, 0xe4310516, 0xbbf5ed84, 0x618b2b9a, 0xfb0d3efd, 0xe72faa15,
+ 0x38071290, 0x6349cb1d, 0xe7e7d80e, 0xf008a188, 0x87fc8e74, 0x4e8a8c63,
+ 0xe2134467, 0x47efda89, 0xf6a3e3d5, 0xed4f26bb, 0x8cbe4d77, 0xe70894dc,
+ 0x494f65d9, 0xfce02fc4, 0x127fe534, 0x79f7489d, 0xec01aea4, 0x5b12c59d,
+ 0x1272efd7, 0x5f1d0a63, 0xe5cfabf5, 0x79fcd294, 0xca23d991, 0x38fcec79,
+ 0xc08afe36, 0x9687936a, 0x731e6b1f, 0xda0455eb, 0xfd601bfb, 0xee08b791,
+ 0xf8deaeb5, 0xd7e3aefd, 0x87b1578f, 0xf30b9d7a, 0x13af5471, 0x7648fe3c,
+ 0x8533e711, 0x4e8c631f, 0x45237f8d, 0x9744bf97, 0x7fcba31f, 0x401f796f,
+ 0x295ef234, 0xe38c537a, 0xfec37c98, 0x2376304e, 0xf86f7f3f, 0x5fe0bd49,
+ 0x1fc283f2, 0xd13393ac, 0x8507e63b, 0xfc6bd19f, 0x5f824757, 0x5b4beafd,
+ 0x2a9faa65, 0x41da795e, 0x6d3a7ea8, 0x53744c6c, 0x5dad57fa, 0x383e00ea,
+ 0xc01d9465, 0x62fda7cf, 0xbe823f91, 0xf0a8d7bb, 0x8026c783, 0x49fe0dff,
+ 0xff599fe1, 0xaeb0f5e8, 0x7256b17f, 0x9d6d5fa2, 0xf2a66839, 0xbf3cd35a,
+ 0xfe616498, 0x3b2fcb08, 0x45be422f, 0xbf159fcb, 0x85d13a7e, 0x314e52fa,
+ 0x8838ffa0, 0xd34d7ff6, 0xdd605327, 0x28dd25af, 0xd076fa67, 0xb87157ff,
+ 0x629a953e, 0x46e3977a, 0xb3da113e, 0xa3f36d5f, 0xfc0745e7, 0x06fd03ab,
+ 0xdce5fafa, 0xda332f8e, 0x1afea007, 0xfe83c64f, 0xfc41f052, 0x5f178ecc,
+ 0xfc0b2e7d, 0x7e9b67a7, 0x785410ef, 0x27ace452, 0xaf57fb30, 0x97d6fabb,
+ 0xd50e549d, 0x4f62a3f6, 0xfef85ab8, 0x55a595a3, 0x1571d052, 0xab5593d5,
+ 0x3f4cb725, 0xc2f4bd57, 0x3f82cf8b, 0xf7668ff3, 0xf2bf0a70, 0xaf075da5,
+ 0x8dcaf9a4, 0x366280d2, 0x18909b0d, 0xfd2d4ba6, 0x9876617f, 0x779b150e,
+ 0xd8a35c99, 0xc2e307f7, 0xb8dca8f4, 0xf54644c3, 0x604147c6, 0x16c3a987,
+ 0x23812e81, 0x12fec053, 0x09bbfd5f, 0xbb7a7ee8, 0x46a60640, 0x5deae7c0,
+ 0x9e019f68, 0x4e9c8e90, 0xeae9ba21, 0x80ba52d7, 0xa4e8573e, 0xfae22f2f,
+ 0x32b9e004, 0x7e5f9f91, 0xfe84e21d, 0xfcc37664, 0xdbbe5fcb, 0x6938f301,
+ 0xfd7c63ac, 0x0f44d2dc, 0x925cb7ed, 0xb2989d13, 0xdfcfe5ef, 0x6f36fc8b,
+ 0xcc89bdff, 0x6419e58f, 0x1e49b5c0, 0xbb9bf304, 0x5f9c16ea, 0xdf22f119,
+ 0x96273f95, 0xdcfc7e80, 0x46368a48, 0x8d4f8b90, 0xb9380ecc, 0x74b81a86,
+ 0xb2e9277e, 0xff337183, 0x14fc6221, 0x3f453f21, 0x2e7cbdd9, 0xfcc382d4,
+ 0x4e8c51e7, 0x5c0d196f, 0xaf15a8ae, 0x65a6d7e6, 0x339f40ed, 0xe1033c43,
+ 0x1896a5bc, 0xe10f8e65, 0xdc570a1b, 0xd190385f, 0x398cb887, 0xc3b51dbc,
+ 0xd43be00a, 0x963c976f, 0xf23b4d2c, 0xffb86a4d, 0x74ff787b, 0x3f60d1dc,
+ 0xbc8c4c9d, 0x2928180f, 0x71d74f72, 0xe4a97f15, 0xd37bc99b, 0x15be4cc3,
+ 0x58dff779, 0x397fe504, 0xda07e4c0, 0xc748fac1, 0xe5881c15, 0xa809a63b,
+ 0x1824cc0f, 0x249bae49, 0x72dad72e, 0xb8e84f85, 0x8a8c428d, 0x1c7e005f,
+ 0xa6ed1fe2, 0x3b68a7b2, 0x85acbe95, 0xe1bd1cfe, 0x8f3b7229, 0x9009ffcb,
+ 0xf2c3cbff, 0xb931564f, 0x95bedbef, 0x92553f11, 0x4167c5ff, 0xca7ca95e,
+ 0xa957902e, 0xe9fde604, 0x3f83b686, 0x69f272a1, 0xad539140, 0x69cbd4fe,
+ 0x097ba6f9, 0x4e5ea7f0, 0x475c1d3f, 0xfd29ca22, 0x074e511e, 0xea97fc77,
+ 0x0e7f054f, 0x153fab49, 0x1e17d87d, 0xb7f0faf5, 0x53e21746, 0xefe90faf,
+ 0xcde9c900, 0x29df0a7f, 0xdbf156fc, 0x77a061ea, 0xf0a97c42, 0x152f885d,
+ 0x57cfd3be, 0xf97d3f8b, 0xd199f061, 0xf6bc9571, 0x4a1494fe, 0xc156aacf,
+ 0xbb61766d, 0x78a790dd, 0xbfb330f2, 0x00ca7771, 0xcbafde75, 0x3df57407,
+ 0xae897cba, 0xaf9757be, 0xb3f7d5d3, 0x9b4b487d, 0x041f2089, 0x45a5f535,
+ 0xfc738644, 0xee226dee, 0x98e8bbbb, 0xaefb681b, 0x997ea90d, 0x16a583ea,
+ 0x4eefbfb6, 0xfe803530, 0x3b7672ea, 0x616f20e2, 0x92aeb5fe, 0xcaac476e,
+ 0x2ad23c3e, 0xf0edfea2, 0xfb48a293, 0x22d16a13, 0x5f483a9e, 0xa3bcece5,
+ 0x5d0db450, 0x46977e08, 0x81ae0dd1, 0x39b7f539, 0xaba1bce0, 0xe986fd35,
+ 0xb7dcfbf4, 0xe85f0c45, 0xc164768a, 0x31ec88b8, 0x0bed520e, 0x99f9114e,
+ 0xb33e7489, 0x60fed95b, 0x5d9d0ace, 0x5f205641, 0x31eed994, 0xf6a45e81,
+ 0x9fad51fc, 0x0577f19e, 0x4abe5787, 0x57b4ae5b, 0x4d158df6, 0xdf2f72da,
+ 0x5c495667, 0xa3268c5f, 0x308f3ed9, 0xafd7093f, 0x0de66285, 0xbbfe29d3,
+ 0xf80488f6, 0x4455a7a5, 0x106cf7fc, 0x226fe0fc, 0x4dca0272, 0xbd46e90d,
+ 0x2ce9e0a6, 0x6fa985c8, 0xcb7673bd, 0xd00f3947, 0x3f5b552a, 0x9a77fac8,
+ 0xc7fadd9e, 0xfe406f11, 0x3f4343d5, 0x17ebbd20, 0x79e0b76c, 0x3b76d76e,
+ 0x6d76afc6, 0x01f437db, 0x7666bfc8, 0xb6bb38c3, 0xfc05997f, 0x5cc8b5d3,
+ 0x6bab7a0e, 0x2cd7db08, 0x5665f6de, 0x4b93ae07, 0x90bf6e90, 0xa7aabed8,
+ 0x858febf5, 0x59d29001, 0xddbffac1, 0xda9dfe8a, 0xa7182dd7, 0xcbedb5db,
+ 0x87edaf1c, 0x3f0d4f9b, 0x93b2efbf, 0x7c609be9, 0xba7cecb1, 0x2f098df6,
+ 0xabfed3d4, 0x6698779b, 0x3782f2d3, 0xfa059eff, 0xb3136bb0, 0x8ea53a6b,
+ 0x7a7ce1e7, 0x8bedd2cd, 0x4ee78a24, 0x42648a10, 0x4df0d47e, 0x09199cbe,
+ 0x7f477f2f, 0xf1f17f53, 0x7c18ffda, 0x53ef1808, 0x47f76ad5, 0xbfef3009,
+ 0xe801fc7e, 0xe466ed81, 0x9fbe654b, 0xeed1ea06, 0x0fbcd8b8, 0xfdc7bcc3,
+ 0x085bcd2b, 0x5fde67f6, 0xfbd393fe, 0xe385c921, 0x6f41cbd3, 0x1f76df3e,
+ 0xbbb25fe6, 0xe4fdbc71, 0x7fa681f7, 0xa26fba31, 0x7c5c7774, 0xe4ff39de,
+ 0xee9beef3, 0x74e2cf6f, 0x8c7de277, 0xe38eff37, 0xee7aaefb, 0xf3a1ffd6,
+ 0xb373ec57, 0x8f3da4a1, 0x693a6f8e, 0x316183b4, 0x2f67a123, 0x8799c484,
+ 0x8c0065fc, 0x8ae7e257, 0x332df1fa, 0x048ffdb1, 0x5fb4c6e7, 0xf7c08b72,
+ 0x743f6c75, 0xae1fb73d, 0xf6865c1f, 0x661ef5e8, 0x496313af, 0x8858de49,
+ 0x46e39aff, 0x3ec9273f, 0x2dfc85ec, 0xbb5e7893, 0x20577c2f, 0xe3da811e,
+ 0xda2d0fd7, 0x0de9f603, 0x33418d83, 0xfa408f4b, 0xcf7f83be, 0x665feed5,
+ 0xdbf9b578, 0xb7f36ba6, 0x82b77870, 0xbffb4571, 0x83f044b5, 0xf21a535f,
+ 0x39f80254, 0x1112b9a5, 0xa9138804, 0x84fb0a5b, 0xedb44a5b, 0x767ec367,
+ 0xf38f185c, 0xe153bca3, 0xa46a21fc, 0x61b8f880, 0x24fa8885, 0xf840532a,
+ 0xc612b925, 0x28627e13, 0x173c01c9, 0xf35f198f, 0x0dce0633, 0xf1cf9df3,
+ 0xd0ea4655, 0xbe1721de, 0x0e6266f9, 0xda0973f8, 0x843df34b, 0xf5ed475c,
+ 0x304289b2, 0x3ce5ca9a, 0xb2639123, 0x9029cfc1, 0xa73f1aa3, 0x1fbf0f36,
+ 0x5ce18625, 0xfc5f7eac, 0x7fa743f8, 0x347ffca6, 0x90cdda83, 0xf33bb9e2,
+ 0xaafb29d7, 0x1e195b3b, 0x7f04ab6b, 0x5055f21a, 0x7c539f52, 0x85fe626d,
+ 0x06383f3f, 0xe7ef2ae5, 0x7ed862a3, 0xcced032f, 0xf6676e5a, 0xf018aec8,
+ 0xa6b4f46f, 0x02b1f3f3, 0x3f023787, 0xadfbe7ef, 0x3ef9c03f, 0x0b26bb4d,
+ 0xfdd8228d, 0x78fd1ba4, 0x590b64f2, 0xee0e211b, 0xa7e29303, 0x1ffdc3a8,
+ 0xa01cc4fc, 0xa3cdfb23, 0x54e2634d, 0xdd715b74, 0x6f566369, 0xa8efc03a,
+ 0x1fe83cea, 0xefec2fc5, 0x2dfbaf00, 0x224a531d, 0x971cf7cc, 0xfeb7e2df,
+ 0x6eb5f78a, 0x00954d6a, 0x164d372f, 0x9fa6e735, 0x75bef898, 0xe303190c,
+ 0x1aeb7e2a, 0xcba004c7, 0xf70dd11e, 0xcf5b6ab3, 0xce11bc9b, 0x04f8f48f,
+ 0x97dfe8f8, 0xcf8065dc, 0x42c7ff63, 0x8fb59f60, 0x4264e79f, 0x6e2674bc,
+ 0x4fe03de5, 0x75e382fa, 0x7489d9aa, 0x4f38b9be, 0x66fda04a, 0xc3473b36,
+ 0xaf325691, 0xad16153f, 0xc11c1071, 0x92f529da, 0x23bd58ab, 0xa44d6726,
+ 0x128a2ff9, 0xfb8579f8, 0x9fe15cbe, 0x3f796e8f, 0x61f307b7, 0xeecc993d,
+ 0x6be6f5d5, 0x53d1f282, 0xdf41f824, 0xf309fec3, 0xe03eecc5, 0x972b033e,
+ 0x597a626f, 0x9e3d7be1, 0xcf0ccdd3, 0x3c05ff4a, 0xf0ccd23f, 0xc159e0a3,
+ 0x4abc7eaf, 0xaeafaa7d, 0x6e21fb56, 0x32fd1968, 0xad3587ac, 0x4140d382,
+ 0x4c3b18d5, 0x2db58720, 0x67e04b8f, 0x7062e19f, 0xa5907ae9, 0x6a9dd73e,
+ 0x6debe766, 0x02cd57d9, 0x056cf93e, 0x7b684bb5, 0x0ef39ccf, 0x19f77758,
+ 0xbdc1efdc, 0x915df949, 0x7d16fdac, 0x79cf81f5, 0x1aa364ed, 0xf38e2a6e,
+ 0x093caae6, 0x57b726dc, 0xaa0690ed, 0x39aa69f8, 0xef95cb0e, 0x6cae55c9,
+ 0xc3fb4ef8, 0x998fc871, 0x6787c409, 0x3ef1da06, 0xb175edda, 0x03cb0f8c,
+ 0x4f984c3b, 0x7f4afac5, 0x797a3f4a, 0x8dac569a, 0xd05d99fb, 0x52f01831,
+ 0xe3de0e6c, 0x9da7c08e, 0xbbe40e9c, 0xca1e13ae, 0x8bff59b7, 0x947b89d6,
+ 0x2a43a275, 0x6c89c551, 0xa73d3335, 0x4606275a, 0xd416275a, 0x1d0206bb,
+ 0x1f4b6c16, 0xe0b24208, 0x48c4c2ed, 0x3efbc4eb, 0x88785e76, 0x9aecdfdf,
+ 0x2b89d746, 0x34c4eb54, 0xbe89f20b, 0xc4acdf9d, 0x9d645d61, 0x5ff6e850,
+ 0x87de6fac, 0x7c822275, 0xd76b366f, 0x4b5b5b89, 0x75b89d71, 0x57b9a89a,
+ 0xb17cdeb1, 0x712f2275, 0xb725e606, 0xbcff0235, 0x43e1edcf, 0xfa0ebe3c,
+ 0x34e2f581, 0xde84ffe8, 0x7a5f46eb, 0xeafeb1fd, 0x3c26fff5, 0xc17d7a2b,
+ 0x781eec2d, 0xc8243e6f, 0x50660bcf, 0x3f002ebd, 0xe0bebd32, 0xd317ee0e,
+ 0xd012d9e9, 0x7ad563b3, 0xf1afb596, 0xb6a175b2, 0x3317f525, 0x1a4ff969,
+ 0xad147725, 0xdeb093ff, 0xddeb51cd, 0x1377a0d3, 0x72dde822, 0x6b3f77a6,
+ 0x53f6831d, 0x88fbf35f, 0xcfaa5beb, 0xf811dc32, 0xab4cfa63, 0xb1ce9ee6,
+ 0xdccbbfd1, 0x4fb2f20c, 0x4fbb73c4, 0x77b01db8, 0x82c6eff4, 0x144a7a9f,
+ 0xa71c4f1b, 0x5c8fa767, 0x81ea993b, 0x9ecc3982, 0x2220deae, 0x999a6afe,
+ 0x4464d7fc, 0x3f345dfb, 0x26affb25, 0x636e57c8, 0x06746fe7, 0xfa2a79c5,
+ 0x68ebee57, 0xe5703f00, 0x0fcf016a, 0xf019ce21, 0xb3e38f39, 0xfb895dcc,
+ 0x80fc7d15, 0xe6ad17e2, 0xaeb7e6f5, 0x3ea9ff46, 0xe33aa0ae, 0xafb0d3da,
+ 0x3a333628, 0xfc166f14, 0x1ce153ab, 0xfdcf575b, 0x541b9e30, 0xc7dfb407,
+ 0x15cef9f0, 0x619b9983, 0xe89ef55f, 0x8dceb48e, 0xfca5e3d1, 0x7ecbc41f,
+ 0xffb1978a, 0x17d2f1ef, 0x8f7da81e, 0x3e3d64fe, 0xbd7145c6, 0x82c64d92,
+ 0xf0627e1c, 0xdf915ea0, 0x642e3111, 0x35c3e3ce, 0xa20bfef7, 0x67dabe98,
+ 0xdc4036f0, 0xe2c35cae, 0xdaade647, 0xe6912bb8, 0x68c80667, 0x5bcf4770,
+ 0x43875da9, 0x0bb37eeb, 0x7599f5d7, 0x1388051b, 0xfdefcb9c, 0xc71ffb94,
+ 0x58ee12f7, 0x5a79d748, 0xd9b6767f, 0xfb9fe70b, 0x37a8dd2d, 0x105dbe15,
+ 0x3a97ecc5, 0xc9638e3e, 0x7d7193dd, 0x289c116a, 0x5b0b418f, 0xe09d28af,
+ 0x09b6871d, 0x74e14e5f, 0x16887e61, 0x4a5ac746, 0x29e79037, 0x8ebf3cad,
+ 0x2bb781d9, 0x77e080f9, 0x7757a009, 0x085dec48, 0x9c0bc481, 0x11f5aa08,
+ 0x12f2d5ce, 0x76de7455, 0x5afff184, 0xfc1f8dc1, 0x43efbff4, 0x9ef93ee7,
+ 0xe5fd31d9, 0x0b4f0577, 0x6fde7474, 0x831e2f69, 0x1b8233e7, 0x8d68c7df,
+ 0xe38573c5, 0x079dec8d, 0xcbd3b799, 0x5c3bec05, 0x8dcabf2a, 0x1f887030,
+ 0x9c60b22d, 0xc69bf61e, 0xbded32ec, 0xd7135940, 0x4ee35df3, 0xda3b496a,
+ 0x3178e163, 0x802637ef, 0xb5182457, 0xc8dd5c71, 0xfc003fe7, 0x02dfcdd7,
+ 0x3139249f, 0xa76ef46e, 0xeec9ddf2, 0xdb7cf06f, 0x33439c90, 0x5b3f7e29,
+ 0xdd79e22e, 0xc1d7066d, 0x1e6fa089, 0xcbc80891, 0x0f257b67, 0xb8ac075b,
+ 0x3bee94ee, 0x4a5ef786, 0x2911ec59, 0x2fad887d, 0xfe78f8c7, 0x0f6dd744,
+ 0x604844f8, 0x4dfbc41c, 0x7428ef73, 0xec64df81, 0x2e70a5fe, 0xf3817376,
+ 0xe7a041e0, 0x93bdecc3, 0x700bcba3, 0x4ff7769f, 0xc3b79405, 0xfed06e94,
+ 0x07a96996, 0xef7ed20f, 0xe7809e58, 0x093d335c, 0xd7b9c2b7, 0xdba2bdcc,
+ 0xbecdeb45, 0x73836ec1, 0x4523a9af, 0xe7e155e2, 0x7e8ed20e, 0x3f75999a,
+ 0x5dc605bd, 0x3143d74e, 0x85fdd215, 0x4abf2103, 0xb2b5f6c0, 0xb29034d7,
+ 0xf3cafb4e, 0xffb4b1a6, 0xd00f5a32, 0xd58abb5e, 0xdc126dab, 0xd65b7a10,
+ 0xcbea38fa, 0x1f0126b2, 0xf6a76896, 0xeb83146f, 0xdb70a28f, 0x34f6d157,
+ 0x03da0f3f, 0x5bd8a6dc, 0x96ab3ce1, 0xe7db138e, 0x6479e3d6, 0x8b476d19,
+ 0x4fd37b49, 0x55fcde11, 0x447b8102, 0x8fa9b9e5, 0xbdbc02e5, 0x0fca1b92,
+ 0xc625f8ed, 0xfda2cc8d, 0x67f0a20d, 0xe8851d8b, 0x70407b57, 0x83233be2,
+ 0x5d7e9033, 0x70686130, 0x64fd0d3c, 0x42e9d718, 0x71d51834, 0x1616c908,
+ 0xb0b65cdf, 0xd5e601be, 0x1aa42721, 0x9bceaf90, 0x4e3f1d60, 0xf6a5edf1,
+ 0x8b1331eb, 0x8f93686f, 0x7a543a99, 0x1d25bc74, 0x969cd8f5, 0x9f2f3c3c,
+ 0xbcf04a4b, 0xeccf5bdc, 0x2d4b2391, 0x30ec017e, 0xbe1439c9, 0xe3352db7,
+ 0xd897cef7, 0xa439d3fa, 0x27a1fd03, 0xee044957, 0x955e2d39, 0xf1d00cfe,
+ 0xf90906e4, 0x424e7c4d, 0x25ef363d, 0x5b6b27e6, 0xbc9ee0c5, 0xcfdec4c7,
+ 0x9f9a7281, 0xff651bf7, 0x6563d5ab, 0x53d40aae, 0x2bd4bd7a, 0x7aa9efee,
+ 0x2f6cb013, 0x14cf757d, 0x741557d4, 0xeb4601dd, 0x3706afa5, 0xaf52bfa0,
+ 0x4d896aaf, 0x10d953d1, 0x3d5a5237, 0xe04ad664, 0xc0583be3, 0xb5f07b76,
+ 0x75869fcf, 0xe04ecab7, 0xf9d18d4b, 0x82f8c08c, 0x6cccbc80, 0xc839f8dd,
+ 0x0b4cf941, 0x0273bbbe, 0xb37200e8, 0x59c59e22, 0xdf114bf9, 0xbce51c4a,
+ 0x573e5a95, 0x7867b5ce, 0xaf51e245, 0xe256e55f, 0xf43bd551, 0xda57e510,
+ 0x822d9dcf, 0xfe4022df, 0xc77beec8, 0xe389de62, 0x83edc85a, 0xe7e47615,
+ 0x5f9ff743, 0xeb3afc0a, 0xbd808141, 0x036f644e, 0x2b3587ac, 0x65f81705,
+ 0xdac83de7, 0x61eda3cf, 0xc97e87dc, 0xb7f28af8, 0x66bff80b, 0xb1bbe3d5,
+ 0x02e0937e, 0x975687f8, 0x2e513da2, 0x9bcb048b, 0x81fee08e, 0x5f1853ae,
+ 0x898b26d4, 0x4b35ffc0, 0x95304ecc, 0xf8523e14, 0x17bf08f2, 0x59dca24d,
+ 0x9f76d337, 0xde849000, 0x174e28fc, 0xf029eb42, 0xf8ccad49, 0x924bc8ec,
+ 0xe2e6d81b, 0xc3eec97c, 0xabebe49e, 0x532ddcf8, 0xd73cc106, 0xb68638b2,
+ 0xb0260555, 0x05fa4e23, 0xcdef8f3c, 0xb6a6c497, 0x7cbe14a3, 0xfafa604e,
+ 0xbda87162, 0xa5f38ef8, 0xa9947fc2, 0xb5595f71, 0x0f702257, 0x5e8fcf57,
+ 0xc42b7029, 0x4cbe940b, 0x5bc743e7, 0xda3f70d0, 0x691e0aeb, 0x65f2113e,
+ 0xa1ef1646, 0x91b543c8, 0xe77d05c5, 0x37fae9f1, 0x7961ec5b, 0x4adc5910,
+ 0xbbfbf690, 0x9c602f0d, 0x47f5b9dc, 0xe6fb47ae, 0x8007ca0d, 0x12760dff,
+ 0x1f87fdc4, 0xb34550f5, 0x4238c1e8, 0x66e73063, 0x895dbed5, 0xc57ca897,
+ 0xd8aef88e, 0xd317f664, 0x8f5b15f6, 0xf5f9e165, 0xe78c6ea2, 0x680bd790,
+ 0x23b9131f, 0x546fee0b, 0x86dc5918, 0x64582ede, 0xb3aa7e61, 0x83a759af,
+ 0x63ac26dd, 0x045569ef, 0x2acc936e, 0x16fdeebf, 0xe787a949, 0x33a53229,
+ 0xf18693dc, 0x5271dfa9, 0xfece35e2, 0x455ff186, 0x5cf6848b, 0x9d8dbac5,
+ 0x71577f10, 0xdcfb8cd8, 0x31e775da, 0x95e0b89e, 0xae1df097, 0x135116da,
+ 0xee2bd57f, 0xe7889d69, 0xd5cd351b, 0xf341bf18, 0x1351ce78, 0x77ff1c88,
+ 0xca9cf8b1, 0x956db657, 0x372b0a29, 0xef81daff, 0x75afb572, 0x7593bde0,
+ 0xd8771edf, 0xf029ce2b, 0x39c6b7f0, 0x507f819d, 0x45adfac6, 0xd644e71b,
+ 0xc746bd31, 0x9ee91397, 0x7adec841, 0x21e7f3e9, 0xa6ecf70e, 0xf1879f4f,
+ 0x67e7fd56, 0x061c43cf, 0x82716ed9, 0xfebb523d, 0x54638c7d, 0x30b2edda,
+ 0x37f3affb, 0xcff8c6bf, 0xdd9a3fce, 0xdb73ad00, 0x6f60a1c9, 0x6bfc6e74,
+ 0xde75c422, 0xfd10adb3, 0x296cf739, 0xf8224818, 0xf814940b, 0xf88fdfd6,
+ 0xdabd3d53, 0x5e30db9a, 0x37a51ce4, 0xdc5087e8, 0xc59aa05a, 0xbc78ba01,
+ 0x71c886da, 0xd3e2bdbe, 0x61be6f9a, 0x66c5e812, 0x345c1766, 0xa500ed4e,
+ 0xa0fd15e3, 0xb98786df, 0xbf4c893e, 0x4a0ff073, 0xfa3a63a7, 0xf73cde7d,
+ 0x5942cf57, 0x719f7c73, 0xe07ec16a, 0x0e23894d, 0x169d3c58, 0xbf4d9b90,
+ 0xa040b8c5, 0xf40bb15b, 0xc143e7f3, 0xea4a7c2f, 0xf743ff46, 0x5bde3336,
+ 0x0876d8ab, 0xcb73a7e5, 0x25d38c7e, 0x93b79e3c, 0xfe2c7e84, 0x6a7afb92,
+ 0xbe2cec9b, 0xe21fe38d, 0xfc0e5cdf, 0x18dce3ce, 0x6ff12b1f, 0x0dbdc57d,
+ 0xefe34e8f, 0xbcf8b02a, 0x780fa6ea, 0x5e98591c, 0xe9d02e42, 0x13c6b7c8,
+ 0x0270782a, 0xe3abc61e, 0x17c72338, 0x397de286, 0xa07e80bd, 0x9a7143a7,
+ 0xe2183f34, 0x21c2fcf6, 0x741f4112, 0x9ff166ae, 0x1ef6929d, 0x2c3e9868,
+ 0xad15d3ae, 0xff7f5393, 0x362f39e2, 0x9f8aeffe, 0x269768d8, 0xd3c151ae,
+ 0xf5910bd9, 0xf0b44178, 0x9a93dd8f, 0x05efe823, 0xc02747e4, 0x1311f979,
+ 0x7c5e7bc1, 0x37dca4ff, 0xb3b4fee2, 0x0b8c45eb, 0xa1b4086c, 0x8bebd71e,
+ 0xa24e7e1a, 0xd12def1f, 0xb4d54f4c, 0xece275b0, 0x46dfbb26, 0xeb7d9ce1,
+ 0x9ae7e435, 0x324c470d, 0xdd7bb785, 0x2b8b1366, 0xeb03f260, 0xfe355f84,
+ 0xc8ef2fb3, 0xdfcdbd42, 0x33f7d215, 0xdb53f79b, 0xda9fb91a, 0xfd35e70d,
+ 0x9301ca54, 0xfef176d3, 0xb73d18ce, 0xed33bc01, 0x133a5ecc, 0xdd228b10,
+ 0x2d12998b, 0x2373fdf1, 0xf5d373f3, 0xb257df12, 0x4494f7b3, 0x5fda3447,
+ 0x0f73d8f7, 0xd4800cc7, 0x8b127184, 0xc55c79eb, 0xa024ee43, 0xb5fb62f7,
+ 0x14bbc604, 0xc7daabf0, 0x012f4e4b, 0x2a4a4dbb, 0x673eab19, 0x1a6fc651,
+ 0x157e2060, 0x17b1effd, 0x27fd840d, 0x6183ca31, 0x7da7d71c, 0xaff58469,
+ 0xf7fcc7dd, 0x0cb1c2e4, 0x746edef8, 0x70a78aee, 0x6e0b27db, 0xe6f6bd70,
+ 0xe43f067b, 0xdf68f04f, 0x7a588485, 0xdb8f5f98, 0xdda0f680, 0x2ad27410,
+ 0x4f696ec4, 0x8bac0dc2, 0x18898cb8, 0xe8718f02, 0xa6a2f88f, 0x073abdc1,
+ 0xd429e6a1, 0xef351b73, 0x1ae4c424, 0x9026ef75, 0xbd741903, 0x557e71b1,
+ 0xf67672fc, 0x03b70a6f, 0xcd8863df, 0xbec0f524, 0xb45eec2b, 0xefe49e1b,
+ 0x48dfd058, 0x23886788, 0x3bf56ed1, 0xcd5fb42e, 0x5fb410fb, 0xa3d63e4d,
+ 0x1917c7cd, 0x5f5a478f, 0xa638f9e2, 0x43c43688, 0xd941a16c, 0x4f0f15af,
+ 0x363b8f0c, 0x5083b881, 0xe30d9d7e, 0xc978a9c0, 0x6cd879ea, 0xf1d371da,
+ 0x4c44f469, 0x606c8766, 0x777cd4e3, 0xf3809712, 0xd3bf68f7, 0xdbf26af1,
+ 0xaa3c79a3, 0xdf411891, 0x09daa2d9, 0x068f7fc7, 0x7b8c4bdf, 0x7d022487,
+ 0xcb57df08, 0xc411ee04, 0xfed079f0, 0xe09df535, 0x6bfd601d, 0x4ec190e1,
+ 0x2bbf7df5, 0xccb7faf8, 0xe81ef25a, 0x75619c9b, 0x313bc818, 0xbde26489,
+ 0xa801d6d5, 0xe616d29f, 0x2f346393, 0xcabe3234, 0x6e504158, 0x9c59ba32,
+ 0x8d12590a, 0x8a39a8f6, 0xb86c96c8, 0x296444c7, 0xf3f17a1b, 0x22d725f3,
+ 0x5c650503, 0xb68d794e, 0x37ceed6b, 0x0844a5cc, 0xbf851140, 0x31f3da37,
+ 0xa370dff4, 0x1a30c937, 0x74b7de3e, 0xda9460e7, 0x6823c14b, 0xb5ddee10,
+ 0xe90b0867, 0x089af781, 0xf01777b9, 0x4f286378, 0xbacf7082, 0xf7943a31,
+ 0xdf7d5144, 0x67f2c698, 0xba5defa3, 0x3fbbc29c, 0x346ce4a6, 0x79ca278c,
+ 0x05779e19, 0x17fe70e3, 0x71945f5b, 0x98ea6c8e, 0xf9963d12, 0xcf1de14d,
+ 0x3dd0f6e1, 0xd7875c6a, 0x107c94da, 0xcd2511f7, 0x55af51fb, 0xb963f607,
+ 0x1d34f201, 0x2531df16, 0xeb109625, 0x930b4ba3, 0xfd78852e, 0x9d0324d2,
+ 0x974780e7, 0x60fb82ee, 0xa23c3c61, 0xb0d183c1, 0x499ed77c, 0xdf2c3c6a,
+ 0x7f487605, 0xbac030f1, 0x89f2e97c, 0xe5379ffd, 0xc42b788b, 0xf019e43b,
+ 0x87f1a5dd, 0xa15fe86d, 0x47ae0b3f, 0x3eeace1c, 0xfb2abfee, 0xc5270a11,
+ 0x5fcc2e3a, 0xaf853b4a, 0x749be2fa, 0xbd8cbce2, 0x9fe5a7af, 0x0327ab62,
+ 0x7ab70de0, 0xe1c6d9f6, 0xf63ef1fc, 0x3dd7af54, 0xaf984c79, 0x063bcd89,
+ 0xb32ef7ee, 0xaaca35de, 0xcd4ecbf2, 0xd1a6205b, 0x2c8166f1, 0x93e78424,
+ 0x8cb650b0, 0xf04cf3a0, 0x7ace3018, 0x063bd599, 0xef4c71fa, 0x8495d20e,
+ 0x31de009a, 0x0b961882, 0x6d86bfa5, 0x50debf6c, 0x622ff06a, 0xc002bde7,
+ 0x8747f30b, 0x19ba3f8e, 0x411cb47f, 0x3d69a8fe, 0xa5a3f8c2, 0x0bf81f3e,
+ 0x9f60cdce, 0x47ba48df, 0x79afdd03, 0x48d0a9b4, 0xb5987ff9, 0xf28521bb,
+ 0x14d64485, 0x788a5f16, 0xaf8c31fd, 0xf8f87d17, 0x45f57994, 0x693dc6df,
+ 0x7ec2668f, 0xcf01af72, 0x85bc14bb, 0x8b2b07ec, 0xf7641c23, 0x6a7e834e,
+ 0xc3763b73, 0xf9ed37f4, 0x70db8c0f, 0x0769bdec, 0xa34c77b4, 0xfb857214,
+ 0x08bbdc6d, 0xa46dcbdf, 0x319000f3, 0x75865ba4, 0x307c6fbd, 0x03e109f9,
+ 0xc04c9eec, 0x979411c7, 0x109efcf5, 0xffbc3b95, 0xdecacc3a, 0x65679865,
+ 0xac07e7fb, 0x1d994f22, 0xc7b7b096, 0xdaadfb04, 0x9fac0625, 0x7aa66900,
+ 0xdeb04bfe, 0x26a35603, 0xa7a14e5e, 0x93544fc2, 0x877de15a, 0x3def588c,
+ 0xb389fe5a, 0x29e0a9a6, 0x11f31eed, 0x4a0c9cf7, 0xdd779d87, 0xe52aeb0d,
+ 0xed351b9f, 0xc0164946, 0xf81f529b, 0x687d1233, 0xae8c45bb, 0x17b05671,
+ 0x205cee36, 0x7f42f9c2, 0xef039ae9, 0x39fad1c7, 0x89b75256, 0xa189cfb6,
+ 0x79e3e429, 0xa7cf207e, 0x43fd34b0, 0xdfa041b7, 0xebbf7357, 0x171e56b3,
+ 0x065e7460, 0xcb3c53ef, 0x29313af1, 0x4505d71a, 0x8066c16e, 0x3f236b73,
+ 0x4eeb4ebf, 0x14dd0033, 0x1b763639, 0x68ba7682, 0x065d19a5, 0xc7786388,
+ 0xec6de747, 0x7b5cef5b, 0xa7bfbb29, 0xa732feff, 0xafb6f7f3, 0xaf75eabf,
+ 0x4ba065f7, 0x63c75475, 0xcd7cd137, 0xf9e19fa5, 0xcd6b22e0, 0x3b73ea55,
+ 0xff1faa7d, 0x3a4e173b, 0xfcec3ec0, 0xc9145cca, 0x32b0eece, 0x6f8f77fb,
+ 0xec53b63a, 0xe815242e, 0x413df564, 0x5768a633, 0x1e5508fd, 0xc63651d0,
+ 0x656afac1, 0x75aba4fe, 0x147f03f7, 0x42bd7e64, 0xf41238d2, 0x5fd58e64,
+ 0xe5c38b8c, 0x481718e9, 0x51f662be, 0xce0ffd14, 0x79f90a97, 0x73b0e798,
+ 0x397f2c27, 0xe3938d31, 0x2a4c7ea0, 0xda23cfc2, 0xe272b9f7, 0x5de82365,
+ 0xf08a9e92, 0xe574a20a, 0xd1da0903, 0x30cb92e4, 0xa890ab9e, 0xbe3a31ec,
+ 0x6fc6749c, 0xba964753, 0x9feff327, 0x6cfaf301, 0xd61319c4, 0x66b8d7f3,
+ 0xec6b27b8, 0xe8374694, 0x5dffdfed, 0x3c5233bc, 0xe31b78c5, 0x12be3dc7,
+ 0xeb339c37, 0x12ef9af1, 0xbd5dd896, 0x9fc7abf1, 0x3e0adf1e, 0xfbcb78f5,
+ 0xce393dd0, 0x7a3f1bd5, 0x5074287c, 0xc7c7acf0, 0x8a6ff03b, 0xcd3277af,
+ 0x3bdacef8, 0x77df8646, 0xdec8b9a8, 0xfda0f46d, 0x43c7c85a, 0x4fb457ed,
+ 0x6eec120b, 0xe29e1ec6, 0x78f0c4c2, 0xe3d578f5, 0xe3bf8731, 0x7c446242,
+ 0xe0377447, 0x0161f28b, 0x7ed04c1c, 0x7099b60b, 0x578248ff, 0x06fc7513,
+ 0x47be061d, 0x17973577, 0xd6392f05, 0x00b19dba, 0xe78a9ccf, 0xa57f57d7,
+ 0x5b0b67b5, 0x7f069ca7, 0x778c4e40, 0x8941f809, 0x5f384a98, 0x15f2d51d,
+ 0xd535971f, 0xa8eaf9cf, 0x9198af8e, 0x0bcacf13, 0x74f2ba9d, 0x85507e82,
+ 0x56f3f4ef, 0xf815ebf8, 0x9e37a130, 0xb2cafe14, 0x993bfb71, 0x387b060c,
+ 0x31b1b5eb, 0x6b499fa0, 0xc3bf445c, 0x2125c3f8, 0x914f9c38, 0x0de2050f,
+ 0xffa6777d, 0x9daa7a03, 0x3f2a82ae, 0x5bd10cc0, 0xa7a08b60, 0xc4993e14,
+ 0xc88935e9, 0x347fc03b, 0x12ff1889, 0x5553f7b2, 0x99e657f3, 0x9e605242,
+ 0x4c5d58af, 0x8679f3bf, 0x47cd4de6, 0xde44fba0, 0x1b28c4ff, 0xdd20b7de,
+ 0xfc21b3c6, 0x32bbe1a7, 0x3c2e29b2, 0x27d7890e, 0xb308eb43, 0x7be266d7,
+ 0xe42f14b6, 0x1c786b1b, 0xc4609b5e, 0x38f85677, 0x928badce, 0x79ed4e21,
+ 0xec073bd1, 0xdec2b3b8, 0x319f9c2c, 0x37d60238, 0x2d67f97d, 0x9ca06b3b,
+ 0x7ac32bd6, 0x2295fc7c, 0x6f742ff3, 0xa4d7fb33, 0x52876df6, 0x4075c671,
+ 0x70899f91, 0x900af15f, 0x8c0a60b7, 0xca586afb, 0x7cfdba68, 0xf2fbee39,
+ 0xd08db25a, 0x299eaecf, 0x4f9f9718, 0x5fb0463c, 0xe7af7cf5, 0xeb3f3d6f,
+ 0x8fec37f9, 0xfb0a1ee8, 0x2fcaef90, 0xe2169d8a, 0x6f94c39b, 0xc29beb54,
+ 0x1e7f942f, 0x8d75bc05, 0x3019e4fd, 0xfd8df7ab, 0x37d6112c, 0xdb0f0ec5,
+ 0xa0c79e1b, 0xb8f65f5e, 0xbbff8762, 0xf034fbcd, 0xcf7491a3, 0x2369f682,
+ 0xefb8065d, 0xf3cdb6fe, 0xec577c0c, 0x2bed8b93, 0xe1ba4ec8, 0x8b337ca5,
+ 0x206021d3, 0xbcabdef8, 0x753d4040, 0xa096e907, 0x24ea3bbf, 0x9675fecd,
+ 0x07e3fba5, 0xfeb03ce0, 0xf2078c12, 0x889a9442, 0x715c59ed, 0x31efbf03,
+ 0xe0047bb2, 0xda85cef5, 0x64d8f8f6, 0xcd5df84e, 0xafb6058f, 0x48e9659f,
+ 0xa5b47b80, 0xbebeb6b2, 0x7a1e657f, 0xb576fab8, 0x78219dfc, 0xb2add8b7,
+ 0x31b55e0b, 0xde34263b, 0x03bbf877, 0xf006df14, 0xea5eb4d7, 0xff02247f,
+ 0x2a37a92a, 0xaf18d32e, 0x99b62fb2, 0xff7a47a7, 0xc147e943, 0xaed24cf7,
+ 0x916ff3e0, 0xe89a2fde, 0xc37dfb65, 0x79cd4153, 0x746692bb, 0x2ebb464f,
+ 0x1da02023, 0x33c8155d, 0xf3d8d6cc, 0xcbdbbf6c, 0x2977879e, 0x0ef37ea0,
+ 0xea07cf66, 0xd5505f71, 0xab37f6cc, 0x99398ce1, 0xed13240f, 0x15bed0fc,
+ 0xe1aaa0e2, 0x1e563f9d, 0xe9e6ab84, 0xd7feac8d, 0x87a685b6, 0xe9df6033,
+ 0x34dc924d, 0x86a1e2bf, 0x6a3fba28, 0x42162548, 0x5d7f47f7, 0x1594d0f1,
+ 0xe2ca54b9, 0xc589023c, 0x426d837c, 0x5fc9f7ff, 0x01b078af, 0x7f74c9f6,
+ 0xed5363d5, 0x8f92fb5b, 0xe21736e3, 0xeafdafb1, 0x5f2531fd, 0x077e54db,
+ 0xa27bfd3d, 0x7fc0315c, 0xf47df30f, 0xc2ef0bb5, 0x92e581fd, 0xde21430b,
+ 0xbba7226b, 0xa9fdced9, 0x3acf7656, 0xed9af45f, 0x5d6fdf20, 0xe27e0118,
+ 0xc31e4677, 0x7f2b597d, 0xafaf716f, 0x8523ed1c, 0x6676718e, 0x697b5fd7,
+ 0x15f6039b, 0x03fb8dd7, 0x673f0fde, 0x9d99ef64, 0xec6935cd, 0x856c87d8,
+ 0x495f0071, 0xd044da29, 0xeec713cb, 0x7ceb0c3c, 0x5843eb5f, 0xd0047bff,
+ 0xfec2e4ff, 0x69df3c44, 0xbf00e5de, 0xdf7e59cd, 0x5b735cfc, 0xad345de2,
+ 0x0707f8de, 0xf9d2a7ec, 0xdb19cefc, 0xaa9b7df1, 0xcbbe222d, 0xbc4dfb40,
+ 0xcdc7fc1d, 0x611e73b3, 0xd7a944dd, 0xd5dfc23f, 0x49bfec50, 0xaf9fb251,
+ 0x12df8a87, 0xbab8e1df, 0x1c58f459, 0x73c0edbd, 0x2c9ed27b, 0xc9107a06,
+ 0x1a3e1c3d, 0x0bb44ec9, 0xfd0df9f9, 0x7ef784ed, 0x9bccf3b7, 0x7cdd9fcd,
+ 0x73913215, 0xd802e5c9, 0xcc01de47, 0xb0f4c739, 0xfd5dbf62, 0xa93fd695,
+ 0x5bf31fb7, 0x21492f47, 0xdef60f88, 0x1fc9b77b, 0xec2ecec9, 0x9ed1129e,
+ 0xc471e424, 0xf496f657, 0x4cfef0a9, 0x2706dbf6, 0xcec83bf4, 0xf9b6b1f8,
+ 0xa51f7c33, 0x856f0486, 0xd1669af2, 0xa6df2419, 0x1efc979f, 0x57545efe,
+ 0xbe02e4ab, 0x15dd6aed, 0x16f90595, 0xb55dfd11, 0x0e5e26fb, 0x2ad9d67c,
+ 0xb5213be1, 0x80713edb, 0xf7d6501e, 0x7ef656ce, 0x31eb5748, 0xedc0aefc,
+ 0x1cbf896c, 0x068d9dd6, 0xb9dcbfb6, 0xd0566ffb, 0xe85e6f0b, 0xad7dc789,
+ 0xb6f73eb2, 0x052f117f, 0xbfe43176, 0x44bfdb55, 0xe200789c, 0x24630a9f,
+ 0x3b610a22, 0xfcfad7b5, 0x27625921, 0x7ce9d7bd, 0x08c5f758, 0x37c735eb,
+ 0xfc08cfed, 0xefbf5fae, 0x6a7b73b5, 0xf786c908, 0xc42e5af5, 0xcdbde257,
+ 0x1173ab56, 0x5d985ffa, 0xccf3b5d2, 0xfbe15313, 0xdbdd915e, 0xdf2220bf,
+ 0x72bdb5bf, 0x8d4d8758, 0xd7a406f7, 0x77ce8317, 0x7feb41be, 0xf99a2bb1,
+ 0xcbee8da3, 0xc206f7d5, 0x5f1cfdf5, 0xae7664c1, 0xbbc32725, 0xeedbdf38,
+ 0x2ef5eeec, 0xb47613d5, 0x80a7bb3b, 0xeab11dfa, 0xc5f40988, 0x53c97b20,
+ 0xac040f4c, 0xe4991780, 0x6fda10a7, 0x07c93479, 0x27aeeafe, 0xdba3884e,
+ 0x0060c7b2, 0x9b5d8cba, 0xeb2ef18a, 0xfcdfb9f9, 0x5529a340, 0xf3e65fa5,
+ 0x9253a373, 0xf54e343c, 0xf4c1d93d, 0x155da9c0, 0xf93d42bf, 0x1e193347,
+ 0x1bfc5d61, 0x4d9b67d7, 0x500dd4f2, 0xf701a8ef, 0xbf773b1b, 0x69de1bbe,
+ 0x35d87f9b, 0x0399d61a, 0x5eb40f20, 0x0df5decb, 0xf2db2f10, 0x6aef4121,
+ 0x68a9534e, 0x41befda0, 0x760fcc5c, 0xe0fb80c0, 0x7890ff90, 0xfb9e61e2,
+ 0xf9bf6ced, 0xe6831ec6, 0xfe0de99c, 0x765be83e, 0x33b7c189, 0x3da6d43f,
+ 0xb7a0f1f9, 0x6fbdd907, 0x8f6b1e00, 0x5c383477, 0x6299bf61, 0xb0384d27,
+ 0xfa28ea69, 0x0d6709cf, 0xebb7204e, 0xe6111ac0, 0x48453aeb, 0xd97a40ac,
+ 0x2ede144d, 0xce37bc35, 0x1c747832, 0x2a9c816f, 0xef2ba7f8, 0xff3499a3,
+ 0x0e31bb46, 0xfc14a4e2, 0xfa50f32b, 0x67880577, 0xc9450db5, 0xfc5be9b3,
+ 0xe69c4ab7, 0xde512718, 0x9cbe4727, 0xcfbcf76a, 0x3b4641f8, 0x68aed4f6,
+ 0xf33647b4, 0x95248c75, 0x29fc030e, 0xa782fa74, 0xeafa78ca, 0x075f3cff,
+ 0xf2bbf494, 0x25c97af5, 0x77f0df23, 0x30725cfa, 0xb1e21d2a, 0xeff1d25a,
+ 0x55e2a8a1, 0xa93e03cf, 0x87f8d602, 0x060c3a5a, 0xb3554fb8, 0x67c5884d,
+ 0xd769fa42, 0x18ccf886, 0x396bfe40, 0x2b8e504c, 0xf994fdd6, 0xe1bea8ef,
+ 0x79e157ef, 0x3f0fc834, 0xd0241e97, 0xeaeb4274, 0xdf8829c5, 0x2ae403a0,
+ 0x372a278c, 0x9a35d690, 0xdfe75f80, 0xfc79d2c3, 0x4afe777c, 0xd967ca2f,
+ 0x67a7162a, 0x38e2a475, 0x257e71ce, 0x8864e886, 0x1bb068e3, 0x4fc9f134,
+ 0xdd3dbe70, 0xf41b64fc, 0xd62bf94b, 0x6cafcb41, 0x1819fc79, 0xa7afc2ae,
+ 0x5384249b, 0xff3dad1e, 0x7830744e, 0x7e300e5b, 0xe524d09f, 0x1349fbc3,
+ 0x7f04e264, 0x6b4d1bf0, 0x6fdfd045, 0x32a73f00, 0xfd758739, 0xac47aed4,
+ 0xeef5833f, 0xdf808188, 0x9489b379, 0xc5c9546f, 0x6aafd5ce, 0x5d62b7e4,
+ 0x6ff454fd, 0xa009c477, 0x55b915e7, 0xe4d9bef0, 0xffe506be, 0x4ffc9d7a,
+ 0x418bed66, 0x27bd6858, 0x593ffcb9, 0x7e9fe544, 0x158a6d8a, 0x5366ce00,
+ 0x26b4f7e4, 0xff1fbe39, 0xf1eaf485, 0x92757a5e, 0x1de7ed83, 0x9affb4e9,
+ 0x3f707aeb, 0xe71f1a1f, 0x2b27279b, 0x002a937c, 0x05291bfe, 0x145f0033,
+ 0x68cfc0af, 0xcdbe82b7, 0x8277c34b, 0x22e3f37a, 0x234ddce5, 0xa6bd61b7,
+ 0x06f7afc8, 0xe4ce4f18, 0x5f60c5ba, 0xc8cb17c7, 0xef05a7a7, 0xaeba38b0,
+ 0x8e79069d, 0x394617a0, 0x42f91e98, 0x11de6af2, 0x920e3def, 0x4e5d7c0c,
+ 0x2f306a77, 0x02704ab2, 0xd772947d, 0xe09fbe2a, 0x4aef94f0, 0xfde37bfe,
+ 0xbdfcbd2f, 0xb8718e55, 0x6420999e, 0xad9f8473, 0x47c84467, 0x6b8620b9,
+ 0xe6de4193, 0x27ec75d3, 0xb4ec75aa, 0xaafc88d4, 0xce3ee1e0, 0xb2c45fef,
+ 0xfce70f79, 0x3f6c0d31, 0x173f37c4, 0x81468c13, 0x3028b5c9, 0xfe011779,
+ 0x5e575de9, 0x5d7f7c83, 0xdcafbe64, 0x33f91ab0, 0xf789c8b6, 0xba349e41,
+ 0x9199b12d, 0xd31fb1f4, 0x817f6b9d, 0x63e02bfb, 0xe4befb90, 0x80e41ca0,
+ 0x3f7fe044, 0xfd157fe5, 0x7ca03e14, 0xa54384f1, 0xa17cf427, 0x7829df9c,
+ 0xff3bacd9, 0xf5c1c8fb, 0x7d5d4f3c, 0xf328a1c4, 0x3e74def9, 0xbfce8bdb,
+ 0xcb0e7461, 0xd15bd017, 0x9c818f13, 0xce5beb8d, 0xac4e316c, 0x6cd1f0d7,
+ 0xe468fb8c, 0xde0140e7, 0xe7dd685f, 0x39d7d9fc, 0xf7ab32ce, 0xe0fe3575,
+ 0x1995d1bc, 0x6e428fe6, 0x6b582ed7, 0x8df473c6, 0xbcb3c984, 0xbeafda33,
+ 0x5234e9a7, 0xfaa29403, 0x09e7d01d, 0x21070ab8, 0x22685aef, 0xf83f7419,
+ 0x4ee96a45, 0x71f9a788, 0x8a3c5cbb, 0x49a363ce, 0xee1d769e, 0x00d7dc0b,
+ 0x0d8a6bfc, 0x88af884e, 0xf00538f5, 0x004ba043, 0xeb2f70e4, 0xfbba4c67,
+ 0xbaafdc72, 0x1f4063dc, 0x52f4e01c, 0xa1e0abe8, 0x2faef5af, 0x9862daba,
+ 0x72f0245c, 0x99791ebd, 0x4f034dcb, 0x6447ae2f, 0x41c9e411, 0x18448bbc,
+ 0x07a644ff, 0x22647a43, 0xcfbe73c1, 0xf3e47a75, 0x7c8f5e1f, 0xb923d1ae,
+ 0x08f5111d, 0xff9445fd, 0x68b9a684, 0x91c392cf, 0x862959ed, 0xb009c7ad,
+ 0x097ad28e, 0xa1fbfb32, 0x52df3807, 0xc438c48e, 0xc63326c6, 0xc87a2b5d,
+ 0xc3e48d31, 0xc0753bdf, 0xa6b50bba, 0x824f0f79, 0x9324d7f3, 0x4f83ce0b,
+ 0xf748dd4b, 0xdcc374d3, 0x2251fc88, 0xe823bd00, 0x0b7e0223, 0x99834ff9,
+ 0x456c5ddf, 0x48505939, 0xb9dd1d70, 0x55f23c76, 0x009a7179, 0x2eb15b7c,
+ 0xb8f28056, 0xe8034ec9, 0xe31e652b, 0xc6481a17, 0x94839418, 0x8c1c9518,
+ 0xc044eb97, 0x6f78b0d7, 0xc84b1492, 0xff4f3165, 0xb9b7ed58, 0x7ed5e684,
+ 0xf65f9a1b, 0x9736fc5d, 0x65c9fcfd, 0x73c9b7e0, 0x8cc64678, 0x65cdff43,
+ 0xac0ce690, 0x6f4a8913, 0xfb8ecc5d, 0xcb52fcbe, 0x40e443fd, 0xacec7f2f,
+ 0xc7f42e75, 0xd47c024e, 0x06789f24, 0x153be1c0, 0x366eed11, 0x2f5c018e,
+ 0xd2090f90, 0x9d494063, 0x4512fe08, 0x87035cef, 0x1ed428ae, 0x1433ce01,
+ 0x85bd0379, 0xce3c6ee7, 0x7655fc01, 0x91fbd7f4, 0x931f208f, 0x2b47d61d,
+ 0xdf110d8a, 0xc633be11, 0x67ea83f6, 0xd6f5fad2, 0xf8f0e59f, 0xe9e5115f,
+ 0x3d9518ce, 0xd1f164f4, 0xc10e7644, 0x9bbbe5de, 0x45abf1f7, 0x192ef7ee,
+ 0x615f7e10, 0x4324d9b4, 0x10f1293c, 0x4f155397, 0x410ab42c, 0xfea7c43b,
+ 0x746e760d, 0x0337fdbf, 0xb7fabfa6, 0xb054a292, 0x6e0c5be7, 0x7c41196a,
+ 0x7b83ca05, 0x267bc118, 0x616efe01, 0x23cd9b5e, 0x8843bf81, 0x3da0f7e2,
+ 0xdc8df3da, 0x681ba1ee, 0x3356e2f9, 0xaebdcdfe, 0x1eefe53c, 0xb21ef1b8,
+ 0x7dacdf82, 0xb8c48e4f, 0x1ba3634d, 0x858d6ce4, 0x51635fc1, 0x6062bbea,
+ 0x1cebeebd, 0x64c2e27d, 0xfe29f7f4, 0x41dd89c5, 0xd692f011, 0xe0b032ed,
+ 0xb18fd635, 0x957ce09b, 0xc700f5f3, 0x9b3de6fb, 0x73c75844, 0x862e3726,
+ 0x764bcefd, 0xf3c00aef, 0x76b51395, 0x0ea158de, 0xb9246eff, 0x493ee086,
+ 0x0ef88f91, 0x9a4c03b2, 0x1e1dc3d8, 0x9e573d50, 0xfd80ecf2, 0x11094c64,
+ 0xae2a9e00, 0x5f2017e7, 0xb8478064, 0xbdfc006e, 0x08b7fe4e, 0x7bcd9c39,
+ 0xf79005f2, 0x0593ed01, 0xfe6f6657, 0xeefb095e, 0x04fe2cb1, 0x07ecaae8,
+ 0xb2f6fd87, 0x534fe0c9, 0x618d6fea, 0xaf2afc7a, 0xc45c00b7, 0x422f3e74,
+ 0xfba613bf, 0xa929e0db, 0x9b72e5f1, 0xcf9aa5c9, 0x52f0827c, 0xc79c643a,
+ 0x3cdec3a0, 0x62d9f748, 0x4f2bdfb1, 0x656e3105, 0x70c11d60, 0x07ed219e,
+ 0x521a7ed0, 0x1d002ed7, 0x0b79ef37, 0x7db83bc7, 0x5cb94b27, 0x80f6e26d,
+ 0x367dae32, 0xe3ee5eb6, 0xe70dd1e7, 0x7af97ad8, 0x92e3178c, 0xe4347994,
+ 0x28ea9379, 0x6f1095fc, 0x78efb633, 0x4263b79b, 0x016f36f1, 0x77a76abd,
+ 0xd3de06ec, 0xf7120dfb, 0x247a451e, 0xf1db642e, 0x08177b95, 0xce5627a0,
+ 0x5037ec8c, 0xee4ac5f4, 0xb5c55577, 0x5aa317bc, 0xc696a72f, 0xfa54d359,
+ 0x4cf76948, 0x3365ae38, 0x53796b8f, 0x52d46ed3, 0x0cd3f00b, 0x8c10e79b,
+ 0x3f7bf95b, 0xd1dff9eb, 0x0ab1f651, 0x0c9d52be, 0xdcc7af5f, 0x8dce0fb8,
+ 0xca4e4f00, 0x912debc7, 0x9c13c3e3, 0x306f6e06, 0x8ced217e, 0x6a1e605f,
+ 0xb702ebbb, 0x78f2ae3b, 0x4f8c8c0b, 0xc93e453e, 0xdf01b7f5, 0xdb922f8e,
+ 0x1087ff80, 0x8c4527ce, 0x1efcf44f, 0x7ce38ced, 0xef004dd2, 0xb1bde163,
+ 0x3ff1fa08, 0x067cd863, 0xff23e7b4, 0x0af87950, 0x3a949bd7, 0x4923c251,
+ 0xc38c54e7, 0x7e995584, 0x69eb931f, 0x7a737e03, 0xd39e504a, 0x07664ead,
+ 0xa0fe32a5, 0x426705ed, 0x2ffe9e58, 0x4f842ce7, 0x00008000, 0x00088b1f,
+ 0x00000000, 0x7dedff00, 0xd554780b, 0xb3dae8b9, 0x64932667, 0x6f264c92,
+ 0x80849af2, 0x3c870108, 0x4e3d2878, 0x0f78601e, 0x02483508, 0x48042bc3,
+ 0xd2d04132, 0x20196f1e, 0x83548086, 0xa96a1ea5, 0x5af11e0e, 0xd528368a,
+ 0xf09d8360, 0x41d0582a, 0x396b42d1, 0x0a8a2341, 0xf41ea009, 0xfffde3d0,
+ 0xcccdad7f, 0x228899de, 0xb9eefbf6, 0x62ecfd37, 0xdaf6bded, 0x8fdffaff,
+ 0xfb0cd7b5, 0x33d6c60f, 0x2a1d76c6, 0x8cb96c96, 0x794bfbc5, 0xc5a398cb,
+ 0x8cf3d8cc, 0xff40b595, 0x9dbbfc2b, 0x7463cfb1, 0x1630258c, 0x2b18916b,
+ 0xa46fac64, 0x598dfa85, 0x187ae4ae, 0x15d236bf, 0x79c0496d, 0x26090e74,
+ 0xecc27e19, 0xf8743065, 0x99997af2, 0xc4bf5e71, 0xd5acc664, 0xbc232296,
+ 0x2ec6b537, 0x7efe60b9, 0x0b78ce91, 0x0b1703cd, 0x79d22da0, 0x2d73c0d7,
+ 0x66a38ed1, 0x6792cf78, 0x269d2dc2, 0xc15f7f46, 0xb12db57f, 0x35bbbeaa,
+ 0x2039d2c5, 0xff825fd0, 0x0eff8148, 0xc61b1331, 0xc5bf0d58, 0x2caec896,
+ 0x6b57cc0b, 0x0e6878ea, 0xf37eebf4, 0x92c191b9, 0x805eb86c, 0x7943f9e3,
+ 0x81cd7391, 0xd62adef5, 0x55c39b79, 0xcff187a2, 0xc66eb946, 0xf08e47e7,
+ 0xa1e193ee, 0x7d9e65e1, 0xa40b687a, 0xb0517dfa, 0xd996365e, 0xae3f41b7,
+ 0x4347b583, 0x8744f637, 0x47fa1a23, 0xa784b1cd, 0xb4743f5b, 0x62fac2e7,
+ 0xe7c24c9c, 0x38f95f01, 0xe5778b1f, 0xde23073b, 0xe00ccb96, 0x61e90178,
+ 0x8e3d36be, 0xdf04759a, 0x53873351, 0x4884c3a1, 0x5d0b28c7, 0x4f5ef467,
+ 0xd7801b31, 0x95d04c37, 0x579e8379, 0x4cc5a75a, 0xcf1baee3, 0x307d309f,
+ 0x7fdb599e, 0xe813f8bd, 0x32dff1bb, 0xf029dde1, 0xd617dd1e, 0xef09f3fd,
+ 0x95e0ba26, 0x61f7533a, 0xdb51f009, 0x5864db26, 0x9664a0c2, 0xd8c719db,
+ 0x0eadfb9a, 0x5a2783e4, 0x8c187b24, 0xb3660e67, 0x25643224, 0xdff9d622,
+ 0xb7610cc7, 0xac170b40, 0x6293ce30, 0xde436ef4, 0x43337fd9, 0x02b1dc38,
+ 0xc3e8068e, 0x05165d73, 0x0df50730, 0x459feaec, 0xf861f182, 0x6a4b982f,
+ 0x80976f69, 0x30466b70, 0xdee00197, 0x3f1326d7, 0xe118d13e, 0x7ff9830d,
+ 0xe1e2e3bb, 0xb9cfd099, 0x82cb875f, 0x339609bf, 0x43a8f891, 0x395a0afa,
+ 0x0f4034da, 0x8472edf7, 0x2df1865d, 0x5843d111, 0xfb45630c, 0x9ad9f988,
+ 0xbc0f307e, 0x047b4d67, 0x3f4d6fad, 0xe22c8f90, 0xff917b83, 0x591947f7,
+ 0x04bf5c0a, 0x86e38372, 0x46378eb3, 0x74e80565, 0x59d3f5a9, 0xeefd617b,
+ 0xd76f3e48, 0x91fd2bde, 0xe3fb957f, 0x97b5cc56, 0x2c5633e6, 0xf38a7ebb,
+ 0x1d5fd729, 0xe2345ef0, 0x8234b19b, 0x0727e897, 0x378abbe0, 0x1cafc70b,
+ 0x7475a7a5, 0xae3b08b1, 0x60e8c5bb, 0x29cf2748, 0x5e0adfce, 0x746f04eb,
+ 0x709e15b5, 0x389efac1, 0xe7c76691, 0x852f5abb, 0xb37de0eb, 0x230f5c63,
+ 0xeef4e5dd, 0xe22e6768, 0x1dcdd2f3, 0xe75eb8b9, 0xd2ef8446, 0xaeacf791,
+ 0xdf5aebdc, 0x7d64df63, 0x49b9bd6e, 0x3fc9e98a, 0xda903e5a, 0x8690bfda,
+ 0xd4309c90, 0xe60c9e5b, 0x6eeb035d, 0x49b43c1c, 0x634f4246, 0xc64f9436,
+ 0x06672c2a, 0x313de805, 0x12ddb9c6, 0x188e5f24, 0x2f5c0ee7, 0x8f3527be,
+ 0xde1cf9d6, 0x5e74721f, 0x5d7741be, 0xf4297ceb, 0xaf447d3a, 0x5a9eb15a,
+ 0x0327d993, 0xe1976cfc, 0x3e450e93, 0x0bc27bb3, 0xf08bd8f4, 0x27ed8a79,
+ 0xbfcf485c, 0x106bed9a, 0xc5bf7a1f, 0xeff04519, 0x11b1f7c7, 0xbd719273,
+ 0xff1d236b, 0xf6fe8665, 0x83f38c55, 0x127f6114, 0xbf73b716, 0xe4f50235,
+ 0x9fd718c4, 0xba81be71, 0xd09cb38b, 0x753bf02f, 0x781db973, 0x92fbac4d,
+ 0x97a8e09e, 0x58ebfe71, 0xaf425fff, 0xfe1d07bf, 0x05074c16, 0x7d04a33f,
+ 0x507e2147, 0x3feb7721, 0xf00530e9, 0x4f528123, 0x8f9cf6b5, 0x840c8eb1,
+ 0x07f77db7, 0xbe603bfd, 0x983e57ba, 0xf75bf285, 0xb7111872, 0x639be5f4,
+ 0x17cf8f90, 0x7316f2b1, 0xc9fa7d4f, 0x3ebb7aca, 0x4b4eb187, 0x1ad5e936,
+ 0xbeb237e6, 0xda974fa8, 0x14fa41f5, 0x47fba620, 0x3809fe0c, 0x994291ff,
+ 0xbbbe02ad, 0xc49e1f64, 0xa569e842, 0xb3256d7d, 0x7fd807cf, 0xf00e7a8e,
+ 0x4177643f, 0xcda5e10c, 0x3b58fa4a, 0x6acac8fe, 0xef4e697b, 0x1a191df3,
+ 0xbb45ee5e, 0xb0673121, 0xe588497d, 0xb4572576, 0x081d28a0, 0xa317b9e7,
+ 0x74b81ebc, 0x68adef2e, 0xb73a7806, 0x0f7ccdeb, 0xe639cbf0, 0x9407f65f,
+ 0x6ccd4f9f, 0xa1c76a1b, 0x8aafe56f, 0x0fdbc80a, 0xffb5f046, 0xd1a3a5e0,
+ 0x613f1836, 0x4f78bee7, 0xc07efe10, 0xe55e9ff4, 0x2f7c2cdf, 0x7d30fc23,
+ 0x07a47f47, 0x44d9c3fb, 0x7613b41b, 0x7ce7881f, 0x3a43a890, 0xeb7a172f,
+ 0x64697877, 0x2b09be60, 0x948f88ea, 0x1365ed7e, 0xf505c6f3, 0x9a237ef5,
+ 0x66cbdabe, 0x5f7185e6, 0x49e2a258, 0x7d61f47f, 0x537c7f50, 0x2baf69bc,
+ 0xf4323b78, 0xefda066c, 0xf9a1e1f3, 0x77188464, 0x09323ec9, 0x4609a3fd,
+ 0xc4258e5f, 0x34bcc638, 0x57aebb4e, 0xa5ecba57, 0x1be1defa, 0x96ae646f,
+ 0xf4347c10, 0x99c37bea, 0xd97ae407, 0xa1d90356, 0x32fe57a3, 0xf7e81f2d,
+ 0x658316c1, 0xfab3e035, 0x7ed2fbd7, 0x87abf70e, 0xe8245986, 0xe5f3607f,
+ 0xfc2f1f20, 0x75c4ecb5, 0x5965b07f, 0x3f683ce2, 0x01ac7e06, 0x356e1638,
+ 0xadeaf5d0, 0xb3f5d2f7, 0xfe174f82, 0xea10613a, 0xd7fba3f9, 0xab3ae227,
+ 0x87f6b1ff, 0x1a762fa8, 0x4286832d, 0xb243b35b, 0xc5c90697, 0x55c2a7e2,
+ 0x563a9dfd, 0xd650eb8d, 0xd5d724cd, 0xa78036fb, 0xddf7562a, 0x6afd97fc,
+ 0x95fc05ff, 0xf204d8aa, 0x09dd2657, 0xbc2baeeb, 0xbee27e44, 0xc7641183,
+ 0xc99668ff, 0xfd0df01f, 0x02df3fcf, 0xe87f92fd, 0x0843e4ed, 0xf42d1f3e,
+ 0xa4c96332, 0xbc4caa87, 0x4f5bb25f, 0x944944fe, 0xf186f84c, 0xff70d1e6,
+ 0x1f78c45f, 0x37e40de8, 0x34da8f26, 0x8e8dc612, 0x13f43031, 0x78b7c5ff,
+ 0x7efd0302, 0xbbfd65fb, 0x29eb411d, 0xd003cd66, 0x06622911, 0x1e8775cd,
+ 0xd49897af, 0x8ce747d7, 0x6e768b3b, 0x5d7d45b4, 0x58869b91, 0x0141ffe0,
+ 0xf077dffe, 0xc3c647a3, 0xc88eaafa, 0x86bb0fdc, 0xe10d797e, 0x5f9d23d7,
+ 0xcf01d8ad, 0x3958151d, 0x8683e57a, 0x11abe414, 0xfd0d5b12, 0x9584ae0f,
+ 0x0b879285, 0xbca36fe8, 0x80efa033, 0xda277d00, 0xa3ed5d17, 0xb11e4c38,
+ 0xe11f6af4, 0xee7ae6ff, 0x11d1e5eb, 0x6bf7a46b, 0x6e56a0f5, 0x383d2fbe,
+ 0x0c81e861, 0x4fb5144f, 0x4ec9fb63, 0x7ab45fae, 0x14f7ab51, 0xd6f0b4b8,
+ 0xf4a9d65e, 0x1b58d0dd, 0x3de80b8d, 0x1bbde923, 0x8d1d5f18, 0x815f110d,
+ 0x797c265d, 0xae29e986, 0x0de1bf03, 0xb66b971c, 0x480115c5, 0x48ec960d,
+ 0xcc33e7d4, 0xee50b7ae, 0xb03b7f32, 0x1ebd8194, 0x8759a3b4, 0xe24ba37a,
+ 0x106edaf4, 0x0373f62d, 0x623bcff1, 0xbcb1edfd, 0xc50ff10f, 0x8a2bd98d,
+ 0xfeb07bd9, 0x84f31330, 0xf7bd91e7, 0xf302f218, 0xa2e31cbf, 0x8c458d71,
+ 0xdcb19dc7, 0x601ecbef, 0x7e6059d3, 0x87592036, 0x70265af4, 0x25a576b1,
+ 0x7bf813b7, 0x6a64cadd, 0xe7c45fd1, 0x68237b3c, 0xce4bef5d, 0x6b772821,
+ 0x7a5a7c05, 0xfe155b64, 0xf60ff676, 0x87141687, 0x56d1d3d6, 0xe8a7ad3d,
+ 0xe81919d1, 0x7edfbc6f, 0xcfea0677, 0x3f5e01f7, 0x3dbd3fda, 0x84fcebe6,
+ 0x3e3c8587, 0x8c44ec28, 0x267f2388, 0xc7d804e4, 0xb5fd13b1, 0xbfba4e95,
+ 0xb539656e, 0xa0ae571b, 0x59b1ddfb, 0x91e8fef4, 0x81b3fbcf, 0x641b9d7e,
+ 0x8c0b03b2, 0xf0b1fece, 0x8e934ede, 0xeaf7d1e2, 0xccbb65cd, 0x5c519d78,
+ 0xf1d1e0b3, 0x142e50db, 0xf563ba38, 0xd6deeeb4, 0x3ebd6d99, 0x3acb5dfd,
+ 0x5d1ed1a2, 0x0077c7e5, 0x7e01893b, 0x32bb219c, 0xc71809ad, 0x38e22474,
+ 0xbfefe4b7, 0xee808283, 0x956ff40c, 0xeccafff7, 0x6216b6c8, 0xa106c39c,
+ 0x7044b45c, 0x7385a37b, 0xd9f395a0, 0xc13695da, 0xfda80307, 0xef61f858,
+ 0xa10a9da3, 0xcf116e57, 0x6e3b361d, 0x6630f7c1, 0xd6937f26, 0xda3bfa81,
+ 0x42708791, 0xf78050bc, 0xcbd52587, 0xdbf90906, 0xf80df5c2, 0x771fdca5,
+ 0x2c71c48e, 0x044d21de, 0xf9130c7a, 0x05f2de9b, 0xb4de385a, 0xe6d0f972,
+ 0xc9569411, 0xf95a9423, 0x6b16fe7a, 0x6c77e551, 0x2a11cc2d, 0xcad5b07f,
+ 0xc3b266f5, 0x7ada4721, 0xd702bb97, 0xf3191ebb, 0xdecce524, 0x51a49a0f,
+ 0x3f98ed2d, 0xaef52949, 0x634afcc2, 0x3d0e56ac, 0xc95798e1, 0x3d12e976,
+ 0xefd12e30, 0x1c02322a, 0xe912625b, 0x7eac497d, 0xc0abd215, 0x1745a3a5,
+ 0x4af08fec, 0x4307904a, 0x047e85f2, 0x79470d09, 0x9ae51f1b, 0x5f9df843,
+ 0xc368c6bf, 0x464793fc, 0x025672fd, 0x38fe013e, 0xa422207b, 0x228f773f,
+ 0x1f7152b7, 0x4f05e934, 0x050f0819, 0x1662fd4f, 0xd4f05bc2, 0x28297a1d,
+ 0x6ac87f4e, 0x3d9dfc20, 0xe29338b0, 0xac6193e6, 0x79cf565f, 0x545f051b,
+ 0x60bf7c09, 0xab77cd0c, 0x5baffbc5, 0x7f82774f, 0xd3d2a893, 0x8109adab,
+ 0xed5d4c7c, 0xb3d3d245, 0xfc3edcac, 0xb072df4a, 0x57f3e00f, 0xf11d99f3,
+ 0xad99f8be, 0xc17ba794, 0x077632d8, 0xc74ea7ae, 0xffb00f30, 0xfb07cbe0,
+ 0xdf387fa0, 0x83fd1436, 0xd91fcfab, 0x7fd788de, 0x2286cd55, 0x1bbc53fe,
+ 0x7c07cc25, 0xf84cde1e, 0x185b7cfa, 0x5a4b055b, 0xec65ac74, 0xb9bfa04f,
+ 0xaf50c746, 0x6f0dd768, 0xb192e832, 0x237419f5, 0xff51fd38, 0xc6077429,
+ 0x143d2232, 0x50fe21ba, 0xf6dfed9f, 0xc0afc112, 0x46c625b5, 0xccfc5bf8,
+ 0x27c8b1ce, 0x12ac6a7d, 0xb81467e6, 0xb89dabbe, 0xf7f3f681, 0x3f666fd6,
+ 0x69fa465f, 0x6ed6a7ed, 0xf63b30ce, 0x86bbfe90, 0xf8231cfd, 0x0f4237f0,
+ 0x41ed98db, 0x23b253cc, 0x68f7ca3a, 0xf82a52e9, 0x7a2f2831, 0x791d7ac4,
+ 0x2b5661d1, 0x179b57bd, 0x7ae46edd, 0x66cad9b4, 0x87e5094f, 0x9b757809,
+ 0x17688dba, 0x90a4dbe3, 0x99a8e97a, 0x9bd025eb, 0x9f7241ff, 0x86af5a1a,
+ 0xc419efc0, 0x7c3bcddb, 0x5e54717b, 0xba244e6c, 0x0fcf805d, 0x7814f854,
+ 0xe0aaf054, 0x88a631b3, 0xf0bb65f8, 0x70c4b733, 0x9970297c, 0x8e7194e3,
+ 0x7a5f380b, 0x0bfafa2f, 0xff806781, 0xbf1fc232, 0xeaf2a99c, 0xbe3d3e4a,
+ 0x0b1923de, 0xca302cd0, 0xb9c665bf, 0x5c601956, 0x7f6648f7, 0x1531fa12,
+ 0x77d42296, 0x3b7b6ad6, 0xcf1bdde6, 0xe366bcf1, 0x4d5de652, 0x7ffe30f3,
+ 0xa3ca6cae, 0xe69dde22, 0x5941769e, 0x532bd81f, 0x15c1215c, 0xf635f711,
+ 0x45ca06ea, 0x9337dc72, 0x10b8f48b, 0x731b7b74, 0xc7210980, 0x4379c5f7,
+ 0xaf0739d0, 0xb7ce8b5f, 0xe5e57889, 0xcd472998, 0x0cb56fc2, 0x4b5dd009,
+ 0xdf91becf, 0xc4f78f51, 0x09716dcb, 0x61b2f13d, 0x1e806e82, 0xec22c9d7,
+ 0xa4ceeca1, 0xdf3defb8, 0x442e293f, 0x54fe1fbe, 0xab13f4fe, 0x84dfafed,
+ 0x5326be70, 0x4fc4f49c, 0x27988c3b, 0x0ad2f256, 0x812feebc, 0x773f40a3,
+ 0x56a3a97d, 0x26d75eb9, 0x55dc63e5, 0xf90aefb4, 0x5fed5dc7, 0xa5dc7f92,
+ 0xf7958ff1, 0x89ec03de, 0x365a31f2, 0xdc5fff13, 0x9978e3c2, 0x146dfed9,
+ 0x643ee1c0, 0xf11b5e60, 0xb40ff92f, 0xc45fe85e, 0x633fc716, 0xe16f78a4,
+ 0xf98617e1, 0x08cc52e0, 0xe105b31d, 0xc111d62b, 0x8af8416c, 0xfaaab32b,
+ 0xaa3ece09, 0xd9e549f1, 0xae29fbaa, 0xa9fbaa81, 0x7eaa79d5, 0xaaadfd7a,
+ 0xb76099f1, 0x9e59fb82, 0x7df1aa71, 0xfaaaa69b, 0x56ef9afd, 0x871e678d,
+ 0x39d6073f, 0xa6f3ac5f, 0xe35573cd, 0x61f24f99, 0x2081647d, 0xc7dbc7f3,
+ 0xc8fac21c, 0xb88f917c, 0x3558bbd9, 0x756682df, 0x08f0815e, 0x956aab78,
+ 0xb78863d8, 0xd5fbeacd, 0x531b1b6d, 0x55e45da1, 0x758c5f5f, 0x53f9090f,
+ 0x3af7fd7d, 0xe3f432e7, 0xcea7197f, 0xbe935dd3, 0x45ae9b9e, 0xc70fbb5f,
+ 0x7f2288ef, 0x79e1e167, 0xc9614724, 0xdb86fa6a, 0x7f16be22, 0x9aac0391,
+ 0xafbff0fb, 0x5d945fc1, 0xfc5a0fcd, 0xc1f759e9, 0xceab8054, 0xac7dd92b,
+ 0xb516fe27, 0xb538256e, 0xede2d3f8, 0xbcea718f, 0xd748dace, 0x971bd45e,
+ 0x0ccb975a, 0xbc65f3f3, 0xf5a978fe, 0x6c4721d3, 0x7ef97941, 0x5fe5e6bd,
+ 0x97910b8d, 0xcb7ac2ef, 0xd41bec2d, 0x817df65b, 0x8b030878, 0xb27a0063,
+ 0xd5d37611, 0x20784afa, 0x5bd5af0f, 0xfb7a0b4a, 0xcfa4716f, 0x35a97503,
+ 0x98b0f4f0, 0xaf089db7, 0xef18b752, 0xb7bc1172, 0xe1232020, 0xa75f333f,
+ 0xe1e00f32, 0x7c679c3d, 0xe3123591, 0xeffb9da7, 0xb58078a1, 0x073d73c5,
+ 0x1f1e0f24, 0xfe9297e4, 0xa67fc16c, 0x48fc3d90, 0x704fc3d8, 0x321ec53e,
+ 0x57bf959f, 0xe6dec3d8, 0xbd16ea51, 0x995ed2b5, 0x58dd2fea, 0xcfa1097f,
+ 0xd1dff18d, 0x23d27cae, 0x0f8c69ff, 0xbdee0f8e, 0x3af51074, 0x1e3c3de0,
+ 0x051519d6, 0xd80a52f6, 0x8c8b7fcb, 0x3eeb7926, 0x826f7b2c, 0xb64d170b,
+ 0xa06e6b18, 0x7785a2be, 0xab9ac994, 0x6de3d20f, 0x365eda92, 0x23ff71e6,
+ 0x1dfb9e31, 0x2fdccc93, 0xe9d62c1d, 0xeeebf8d6, 0x82971e26, 0x05b75434,
+ 0xe38381f9, 0x3bfc68a3, 0x71834511, 0x5c455b3d, 0xd12598df, 0x89251afb,
+ 0x312dfaec, 0x9dff74c5, 0x6c5ca2b8, 0x0ef789fb, 0xda089f46, 0x8f0e6ce6,
+ 0x5013ec4d, 0xc710ffe6, 0x4c5b6217, 0x8b78e0ed, 0x0658efc8, 0x448fbd22,
+ 0xa35e6838, 0x29fcab2c, 0xe78bcda5, 0x99a7447e, 0x2a937e29, 0xe8463c7f,
+ 0x8717cc31, 0x26393091, 0xe40c4e8c, 0xea3c998b, 0xe45e31b8, 0xdc7a2589,
+ 0x5dbc7481, 0xbcb7b1d0, 0x658063b1, 0x4439bc3f, 0x1c97d8de, 0x1f6c6f32,
+ 0x78637943, 0xd2eb8f52, 0x0e918fe6, 0x3c80d691, 0xaabf8c4c, 0xdf50d26f,
+ 0x3c756634, 0xe3f91e32, 0x127f6ca8, 0x13c77f41, 0xb6e00439, 0x7c7675d9,
+ 0xb616e464, 0x0bfa1c3a, 0x2fca363d, 0x8afe2019, 0xefc80bca, 0x4e2cf892,
+ 0xd33e13ff, 0xfc3fb810, 0xe63b671d, 0x634ffb93, 0xcdff5456, 0x1a24b9ac,
+ 0x2c2d88fd, 0x2552bc64, 0xd17c66f8, 0x3ce5195e, 0x25f81ba1, 0xe2aa3d04,
+ 0xbdbf8a75, 0xbc36e900, 0xf50975db, 0x4807a289, 0xb45c6195, 0xb27e475f,
+ 0xe896f9f6, 0x07c42592, 0x9279d0de, 0xe387334e, 0x29738442, 0x57783fce,
+ 0xcdf51187, 0xce6f4542, 0xd03d31d7, 0xbf414ef7, 0xbaf0b73b, 0xd5f2bb34,
+ 0x5fe2b257, 0xa19f9a31, 0x2d38583e, 0x87798bca, 0x1e596d85, 0x5129cb82,
+ 0x76ddc55e, 0x85fd89cc, 0x8c160505, 0x657f1d73, 0xe40199d2, 0x77ae319a,
+ 0xa28cecf4, 0xc67ec807, 0xaa629d53, 0xb34eabe0, 0xfd04e08d, 0xe81221bc,
+ 0xaacb70b0, 0xe12fb8bd, 0x54677fad, 0x7721388f, 0xa6c9c30f, 0xe4567203,
+ 0x1567ab61, 0xaf30f879, 0xf3134c77, 0xf784be78, 0x9def029a, 0xd69876de,
+ 0x3cc0c273, 0xae97e026, 0xd0d9773d, 0x304c6d4f, 0x457f89d9, 0xec94eb9d,
+ 0x878c807a, 0x410ebbbe, 0x6916d19b, 0x58eb0f59, 0xafdc6463, 0x11d845d5,
+ 0x1dcd13ff, 0xf897e27a, 0xf1e23d6e, 0xf467410d, 0x4fcfc9ed, 0x39274460,
+ 0x96e9c755, 0x44fbe369, 0xbff9d472, 0xc1dd0497, 0xebc34c6b, 0x58df2313,
+ 0x7cce036e, 0xc70fd376, 0xdea247e9, 0x1679637b, 0xdd365bf4, 0xfc8f4e35,
+ 0xa7c6fa9d, 0xcfea2059, 0xf7e72a6f, 0x69f1bd07, 0x6d77f436, 0xdfefc19a,
+ 0x5ecfbc46, 0x38f774dc, 0x74bfebcc, 0xf9f02f55, 0x12422097, 0xc395bfae,
+ 0xe2a1f574, 0x92bc5f0b, 0x7c06665f, 0x4fedb38f, 0x3aced027, 0xc3b7fa95,
+ 0x237faaa0, 0xdf8098c7, 0x62be0bc6, 0x0764d1f1, 0x8dfa09c6, 0x3f68fbd7,
+ 0x23e4ce8c, 0x1ac4defc, 0x8037c82c, 0xe55f4dad, 0xc07f7cf7, 0x4bf9a9ae,
+ 0x02b63072, 0x2cd92de8, 0x566b27c4, 0xda385730, 0x5ddd40fd, 0xcceeebc7,
+ 0xe057ef89, 0x03dfde51, 0xdead202e, 0x16d70c1a, 0xab81479a, 0x0798686b,
+ 0x9fb149e5, 0x525d5c0a, 0xf498e3f7, 0x0f2fd9fe, 0x75ba404e, 0x48677545,
+ 0x7090dfd0, 0x95d8e890, 0x64b8fdd0, 0x381bea0f, 0x5a6ccf1d, 0xef03ce36,
+ 0xce3b28d9, 0x1986dca0, 0x2692bef9, 0x3de0538c, 0x3cb8260f, 0xbe03cf58,
+ 0xef90fbb3, 0x87a48dd2, 0x79d40b4a, 0x67c16e89, 0xdeb813cb, 0x5cd61d1f,
+ 0xd2f80c7f, 0xab624bbd, 0xcafbbc60, 0x89da2325, 0x8da76d89, 0x76eb680e,
+ 0xbea2369d, 0xcc3ec3aa, 0x18c5b753, 0x12796f52, 0xd43f6164, 0xf481f07e,
+ 0xe3c40ffe, 0x12f985be, 0xd9eee255, 0xfb1a3b1d, 0x55c1ccf7, 0xa8f77632,
+ 0x5d91a39d, 0x0fed9d2a, 0x759b3b60, 0x9a16401c, 0x7e5592e1, 0x48eacce9,
+ 0x595b5f95, 0xcfeaa71f, 0x80ea066e, 0x915ecf5c, 0x181f8eaa, 0xcf00abc4,
+ 0x43f8160c, 0xe82e56fd, 0x83792338, 0xccadf71f, 0x1d3c1970, 0x6c4df341,
+ 0x22b7a55b, 0x9d92f5dc, 0xd987afd4, 0x7c99b9f0, 0x3dead085, 0xd1b0f5c1,
+ 0x51893cad, 0x7f226e57, 0x80fb02bf, 0xd91a8ad7, 0x0f10936b, 0x6eefba46,
+ 0x5bbee895, 0x4b5777dc, 0xec961d4a, 0xe3016cee, 0x46c73dcc, 0xe110b6d3,
+ 0xcef02bdf, 0x4b3b2f2e, 0x7afc28fc, 0x36e55d65, 0x7d70b3b0, 0x06dbfa6d,
+ 0x8ff6779c, 0x45971624, 0x50eceaeb, 0xafdd51e1, 0x19f757ac, 0x9e6030eb,
+ 0xf50af67a, 0xc209e1f5, 0x83620e9e, 0x25469e50, 0x2f927a48, 0xfd24ffd1,
+ 0x007cd7ed, 0xf3b2e3df, 0x83e004f6, 0xea8fa31a, 0x2ecb8f50, 0xe1f72bea,
+ 0xb9231d7a, 0xe4807f03, 0x5cf92258, 0x8a587063, 0x95ae8fd0, 0xb2676f88,
+ 0x2b217f20, 0x72fa9e30, 0x093dfecf, 0x135a5fdc, 0xf54e5cee, 0x65923db0,
+ 0xd52a5c1b, 0x07e8f43b, 0xe74291ae, 0x70259643, 0x418d7879, 0xf5700ef4,
+ 0xbb452647, 0xd78c677e, 0xffedef03, 0xf41e39c7, 0x03e7fbef, 0xee50d81f,
+ 0x2f19bdb9, 0xf024cdec, 0xebffd12f, 0x9394b72f, 0x68c5bf7e, 0xec2efd21,
+ 0x1c2fa290, 0xa1db51bf, 0x288769f1, 0x79b498fe, 0x8bd405c3, 0x791d7d39,
+ 0x07be011b, 0x1ffbf9c3, 0x71792ddc, 0xee5d4e1f, 0x499fd241, 0xdef81ec0,
+ 0x47a164ba, 0xacfbd55b, 0x21af5092, 0xa5c84cc3, 0x1498a6f7, 0x1e90776e,
+ 0xbac57c94, 0x497e80af, 0x69a9bde2, 0xe257c236, 0xd70916e2, 0xab3cce9d,
+ 0x45cf8ed0, 0xb40c2c21, 0x97cfedd7, 0xbe7f5a4a, 0xe4f9fc9b, 0x7bc5230e,
+ 0x9df8dbac, 0xe73d73f2, 0xfcd432ff, 0x53aa7cb0, 0x2bf2e207, 0xb9a798d1,
+ 0xafdf4f67, 0x9b24dfdd, 0xc1b771d4, 0xc7bb8ea2, 0x9feb500f, 0xdeb57689,
+ 0xafa23c99, 0xc714feea, 0x3bfdd520, 0xfd55f2cb, 0x54dbcee9, 0x2f2aefe3,
+ 0x92c3f551, 0x00f269c7, 0xe44abcea, 0x255e7500, 0xa3ceaeca, 0x7dfe1d84,
+ 0x317804b9, 0x2e1d3c9a, 0xc81343c0, 0xc06b08c6, 0x368a0c8e, 0x22367151,
+ 0x6d8cdc3f, 0x1f30d0d3, 0x1f5349f2, 0x1d87871e, 0x07d937be, 0x766298f3,
+ 0xf104b098, 0x1c5bc95b, 0x9a007307, 0xf03a9ea8, 0x39bfb57e, 0x17db8532,
+ 0xb825f5a5, 0x36844f5e, 0x2a5b19f7, 0x14fd67f7, 0x1822989f, 0x345e8bf7,
+ 0xc4a45f91, 0xe93ccac9, 0x50074569, 0xefdee47f, 0x6b09baa0, 0x27cc1665,
+ 0x7914693e, 0xbef917d4, 0x0ed6dcdb, 0xbe48239d, 0xfae44cef, 0xe2ce17e0,
+ 0x5d7f38b1, 0x9459581b, 0x1aefcda7, 0xd7593eb1, 0xf68d1ed6, 0x5df3886c,
+ 0x02ebe623, 0xd39d85d7, 0x5d604777, 0x722d77e5, 0x72cafdc8, 0x1febcf22,
+ 0xf2bd7a14, 0x547c40de, 0xafa02c34, 0xf5f2772b, 0x92374e55, 0x46c2c13e,
+ 0x7a0dbd28, 0x2ade67ba, 0xf28c1ed8, 0x03ba803e, 0xdc6ab7f4, 0x2e3c69ec,
+ 0x8dbd00aa, 0x5cfa0c72, 0x91ad3f7d, 0x73e80bf4, 0x010bf5d5, 0x15fb9e7d,
+ 0x19c2773c, 0xe8f65f7a, 0x3f375e14, 0xfc212ae1, 0x88f002ff, 0x7a2ff27e,
+ 0xf3e38de0, 0x167af85a, 0x37441f69, 0x2929b8ed, 0xb67c7fdc, 0x433d7d17,
+ 0xc949f5d0, 0xd4ca879f, 0xbe208ced, 0x8d72699d, 0x7a47ccef, 0xf588de7c,
+ 0x4bdfca89, 0xdfeced0c, 0x7ed30fda, 0x03cee33d, 0xd28fb889, 0x912072dd,
+ 0x18d5df01, 0x8fd0ab6c, 0xa3b0be07, 0xead753df, 0x5b6bf823, 0x7af1dbf2,
+ 0x4764ab6d, 0x75deec55, 0x93ad0c61, 0xbd623475, 0xe05ec9ef, 0x76e44cca,
+ 0x8da26064, 0x985c07e7, 0xc3e7c113, 0xf9095ebc, 0xc212f400, 0xcd625bb5,
+ 0x9d727fd0, 0xb79d6429, 0xff7be052, 0x57c5233a, 0xae3cf035, 0x41fa60e3,
+ 0x68f909a3, 0xc24bac27, 0x1e9b1c75, 0x372ff389, 0x142ff430, 0xfba5cef8,
+ 0x4ffae14f, 0x070087ce, 0x2f99afae, 0x2e4fbe13, 0x05c87917, 0x58cfea06,
+ 0xdd7e2464, 0x46bdff37, 0xac9defcc, 0x4bdcfbe1, 0xf9467c16, 0x248b19be,
+ 0x8a993f65, 0xd57e159f, 0x7f96a7f2, 0xf569f07b, 0x98e9f1f5, 0x3a7cabc4,
+ 0xd03ced04, 0xf212747d, 0xce218fcf, 0xb2b9f946, 0xf00490cf, 0xec5a3766,
+ 0xb06bafb8, 0x11207dec, 0x7e3ec4f5, 0x56cd687f, 0xdb1beb89, 0xa98728dd,
+ 0x1eb6464d, 0xae44cbfd, 0xbd206697, 0xdd69710a, 0x7bc52452, 0x4bd46cfe,
+ 0x0ef7ca59, 0x13be5606, 0xae7a71f3, 0x94bf066f, 0x107d75bc, 0x39129adf,
+ 0x707a2abf, 0x76b99190, 0xa5bfde52, 0xe79814cf, 0xdbaf0359, 0xfaf98864,
+ 0x331eedf5, 0x089fda05, 0xe027997e, 0x0af7fa50, 0xcd4f67fe, 0x344efc20,
+ 0x5b8fbc71, 0x75c0abe1, 0x8b5d1934, 0x84fee112, 0xd06bb78c, 0xbf6535ce,
+ 0x42f94b9a, 0xa73b2366, 0x46fbe7c4, 0x1965b07e, 0xe6fc37ac, 0xf863a208,
+ 0xe4168d9e, 0x057ef0e3, 0x7c10ae49, 0xcbeeb4a7, 0x3902e636, 0x4d9cbbaa,
+ 0xb29fd2ad, 0xf691acf7, 0x185db721, 0x39727243, 0xcf2bae99, 0xf9114a2d,
+ 0x53dfb12a, 0x9e825fc9, 0x0bc88fd6, 0xc0f0538c, 0x215e1770, 0xd114f3c2,
+ 0x3652d96b, 0x37d1a794, 0xd667fad2, 0xc0e6931c, 0x1c19773c, 0xd6167306,
+ 0x77c7cacf, 0x537ee0e6, 0x71fd5cc6, 0xb9899d9f, 0xcfdfb88c, 0xcaff7d42,
+ 0xb1bfea64, 0x63ed46d2, 0xd0cfe726, 0x5fdf4cde, 0x4df68fdf, 0x2cea3fa6,
+ 0x1d74f786, 0xb6be0831, 0x3a94be10, 0x9936a5d0, 0xa5fee099, 0x35d5125d,
+ 0x5d67f815, 0x715cc3ee, 0xdf15fd8c, 0x5da9ef07, 0x3be926f1, 0x3185f57b,
+ 0xad0d1718, 0x7d88dd39, 0xc6cf8af7, 0x0a713fa0, 0xf5f907ec, 0x4b27dfe0,
+ 0x198e47a8, 0xc55d7f71, 0xf3cd2b65, 0x0c7baeac, 0x15e797ca, 0xa74dea89,
+ 0x93182f5a, 0x08627db8, 0x9f5816ca, 0x1895d703, 0xb771f84b, 0xfa71d50d,
+ 0x4ab8f0e6, 0xc0fb43f0, 0x1e91a32f, 0xd7b615a6, 0x0fe7c36f, 0x77e50cc9,
+ 0xb477717d, 0x3dfe8425, 0xfeb2f301, 0x6ad81d7c, 0x3d1b97ef, 0x5cf0ecfd,
+ 0xfef42eb9, 0x9f0557a8, 0x3e29a602, 0x11293fc0, 0x55ff99e5, 0xac6292c2,
+ 0x22f8f714, 0xdb2b8e40, 0xb1eace4a, 0xbbd897ad, 0xbd8c78ea, 0xf7b7e41b,
+ 0xb4df87c6, 0xf4f9c3ad, 0xe201f641, 0x07e41646, 0x54c8dc61, 0xbcf0f7ef,
+ 0x924e7a52, 0xaf3ac42b, 0x1f4741ca, 0xd57a0366, 0xf3ba0135, 0x5207df91,
+ 0x5af77e7b, 0x298fca1b, 0xb451fba2, 0x8ebfac13, 0x8f5a8ce2, 0x93d9ffda,
+ 0x4f78e5cc, 0x77eb9732, 0x12f1d513, 0xa3ef45c4, 0x145c431c, 0xa0df858d,
+ 0x9d7b4978, 0xca1325e2, 0x1077bc15, 0x10f9e7d0, 0x2e4e1f70, 0x3df908fe,
+ 0x9f133583, 0xe473e033, 0x3f3aed2f, 0x9153f613, 0xd72819eb, 0x5cadbfc8,
+ 0x1ef3b5ae, 0x0cfa2e4f, 0xfb8759e1, 0x8de842b5, 0x6b3ac557, 0x97c23337,
+ 0xf095b37b, 0x766d8e74, 0x9e5f0316, 0xfeb03803, 0x4674e5df, 0xc67d62c6,
+ 0x9ab48ce5, 0x6ea07a03, 0xb73d0473, 0xdc6a672e, 0x2447e81c, 0xdf3fbe71,
+ 0x3c42625a, 0xe5ccdacf, 0x29df794f, 0x94388cdf, 0xb74342a7, 0xd3f70ed1,
+ 0xa3474eda, 0xfbb857df, 0xc39438ce, 0x47fce0de, 0xed775f12, 0xe3c67b8a,
+ 0x87f85df7, 0xfea54cf9, 0x33ed5ee6, 0x0578dd52, 0x7f6dfe23, 0x28756ff1,
+ 0x22dbe7c7, 0xcf37682d, 0xa0f489ed, 0x257aeffe, 0x2893abcc, 0x80c4f0ee,
+ 0xe8673b5e, 0xe5fe4498, 0xfe82d96e, 0x8f95fb9d, 0x7479451f, 0x9e8618bf,
+ 0xb6d25b1e, 0xbdda02f6, 0x67b1b69a, 0x9f6843f5, 0x1e553ff9, 0x47dc576a,
+ 0xffd2917e, 0x89c9a578, 0x9ebcf47a, 0xad2589eb, 0xbbbf902f, 0x21a5cae4,
+ 0xb73ef758, 0xa186bfe7, 0xf1ff735e, 0x67d430d2, 0x1a5c3fee, 0x2fddf786,
+ 0xf287d645, 0xc8a55657, 0x5ec57f44, 0xabd71d66, 0x0b1f43f2, 0x686ac8fe,
+ 0x9bfdc32e, 0xd9a6c785, 0xdcab7f31, 0xa3a7ec2f, 0x6f85fafd, 0x082dc695,
+ 0xafc1ae7a, 0x05ebc32f, 0xe7234ac7, 0x4765f107, 0x2fc941b2, 0x075e575e,
+ 0x0587eaef, 0x3afc71e5, 0x5b8c3847, 0x7df3d7e7, 0x1792d5b4, 0x5ff00be3,
+ 0xdf91cfb4, 0xce28b5d4, 0x04fc9ebb, 0x05c1f8e7, 0x5f67efd8, 0x62b5436f,
+ 0xe413903a, 0xebf0cd27, 0x47c0617c, 0x3e616de5, 0xfafdeff2, 0xfe17d4d3,
+ 0x1f0bacd3, 0x21496544, 0xde0333f2, 0x5c7a8d18, 0xbf81a79b, 0xf15b8428,
+ 0x5dea2ab7, 0x36bf08e9, 0xfcbb337f, 0x690fca0e, 0x7e5937f3, 0x01626ebd,
+ 0x4d79e7d6, 0x937f9d74, 0xf145e509, 0xbb7e9143, 0x67ffc842, 0x8a7e9c49,
+ 0x75f8355c, 0x7f069744, 0xda0729b1, 0x2efee2f3, 0x1df8a730, 0x9ddb4347,
+ 0xd08f30db, 0x48aee570, 0x1c355dac, 0x3bf0ca9f, 0xb14b2e8e, 0x773e1fa9,
+ 0xf4d30ee5, 0x68bf00dc, 0x8927b7df, 0x9f80cbeb, 0x3deeda10, 0x9ff9e427,
+ 0x27b6ff65, 0xffcfcd5d, 0x20ff6d5f, 0x9499df0e, 0x4cf87140, 0x71e1279e,
+ 0x286ed6b8, 0xf79958fa, 0x9ee7415d, 0xf92cf8fa, 0x932f1037, 0xc9377e3e,
+ 0xdad2e346, 0x1c51c4a6, 0x9c5a7c7d, 0xfe73dccd, 0xcebb7abe, 0x7e73db9a,
+ 0x7b738fc5, 0x184c071c, 0x3ef838e7, 0x8934f731, 0x7e2ad5f6, 0x9129db9f,
+ 0x30aeee3f, 0x029c7178, 0xcf1a7f97, 0x18774eab, 0xc052e1bc, 0xc7fc543f,
+ 0x12edf7ab, 0x49fc57dd, 0x3bf46fc5, 0x5a771e79, 0x98ffbf01, 0x093275c9,
+ 0x70be41eb, 0x92385eba, 0x79cc675f, 0x77fa1520, 0x246250fd, 0x549fc2ff,
+ 0x6feb54f8, 0xfbeb6c5e, 0xb7e4fbb5, 0xe454fe08, 0x1f23432c, 0x108afd8a,
+ 0xfb43aa78, 0xfbf6871d, 0xae5f950b, 0xf7ec179d, 0x8e7a24b9, 0x6f05f3d1,
+ 0xe2a19de9, 0xfe6295f3, 0xa0fd207f, 0x2feff34d, 0x99d37842, 0xf6b9f69f,
+ 0x85bb5766, 0xfddbd37f, 0xcf286f88, 0xf89d8403, 0x4e73c967, 0x790cfff2,
+ 0xf617eabe, 0xe1dd9df2, 0xc9c1a2e4, 0xdeb97f48, 0xf7f2845f, 0xfac84367,
+ 0x7f8115f4, 0x7c557388, 0xa8dd207c, 0x5dc8b8c3, 0x4d03f3cd, 0x29d7b6b1,
+ 0xd32c397e, 0x1025ebfe, 0xb6ffa207, 0xda85b2f8, 0xa193f41a, 0x31ccf99d,
+ 0x9997ea03, 0x9bf86ad5, 0xcf8b7730, 0xa2f2cd2f, 0x4ac95cdf, 0xd954af29,
+ 0xfdc16b16, 0x2d094dcc, 0x3cae5107, 0xb6db64db, 0x06ebf1e0, 0x9e26f18a,
+ 0xa58eab6f, 0xe34c93fd, 0x6bd65407, 0x5fb57dfd, 0x13c89b70, 0xfc1fe6f5,
+ 0xeb9c3da1, 0xc9324395, 0x97e61d79, 0xd8cc616e, 0x7b82f5c6, 0x4de53845,
+ 0xb8435e30, 0x79215c3e, 0xad77004d, 0xdea1f718, 0xaa27f94f, 0xb390c1a7,
+ 0x51131b6d, 0x5d43992e, 0xea7daa3f, 0xda9bd22d, 0x9775923a, 0xad5d0ba8,
+ 0xb0930d1b, 0x64f10b5f, 0x3697fa12, 0x3fc464db, 0x47daa7c0, 0x1705f8a6,
+ 0xf147bd0f, 0xbcddcce7, 0x7ea3d3fe, 0xd78e34d4, 0x0d3ec48f, 0x76721e6d,
+ 0xa903c1e6, 0x8dd76bb6, 0x198f5aea, 0xe1e8ae30, 0x8efc687f, 0xf3ab269f,
+ 0x9e7a998c, 0x936ccdc7, 0xca9f982c, 0xbe1c7814, 0xeafc822e, 0x1f9f7f31,
+ 0xa140fa87, 0x1c29f9d3, 0x7e4fe7af, 0x045b445a, 0x84b7aefe, 0x70febac3,
+ 0xa99bf972, 0xd9336fbc, 0x91e5b9f0, 0xdff43df4, 0xbc4489ef, 0xdc5a01fe,
+ 0x09d2f997, 0xa47cc87d, 0x1fe5c294, 0x93cfe1ec, 0x2fde1ed1, 0xb07ad2f2,
+ 0x7c815187, 0x9b39f68e, 0xc209ae78, 0xee63ca14, 0xa6fdf5e6, 0xea38d714,
+ 0x6d9b32ff, 0x41d0ff23, 0x8017e779, 0x345f31af, 0xf58b1608, 0x5822e7e7,
+ 0x9a8bd603, 0x92af5c12, 0x6752fd1c, 0xe7823943, 0xd9e4cea9, 0x88fb2369,
+ 0xce7ac328, 0x2649b010, 0xf7c0d7da, 0x74140c47, 0x1638814c, 0xcd0049eb,
+ 0x0f37ac34, 0x219d7512, 0xf38f4c11, 0xad70683f, 0x48eb19bf, 0x2afb7aed,
+ 0xdc7b0212, 0xf59ea894, 0xebc1c925, 0x499d4ae2, 0x56f78fa9, 0x3df09267,
+ 0xaf0e1f7c, 0x727d892b, 0xfd893d4a, 0xae4549d0, 0x19ea2335, 0x6949adc6,
+ 0x0bedbbec, 0xf9e759eb, 0xdab9c63b, 0xc047cf3a, 0xa13f3ce3, 0x1fae2bae,
+ 0xe9f13cf0, 0x0e27adb7, 0xb8376648, 0xa3f1c5fe, 0xf620bb85, 0x5bc52262,
+ 0x68cff8ff, 0x976db3b2, 0x75761ec8, 0xe53f3187, 0x9e783b1d, 0xef7f8dbd,
+ 0x5b7105d3, 0xbd9d9042, 0x7b5bf843, 0xff884adb, 0x234bf977, 0xb0bd7c71,
+ 0x4f8eebe3, 0xd3bf13bb, 0xb4f5f8f2, 0x1e31872f, 0xebf2ed87, 0xb96fd10b,
+ 0x22f97481, 0xcdfd4429, 0x93edc114, 0x4b9e8e56, 0xe7a4f9e6, 0x947f3992,
+ 0x97f1e49c, 0xa3af397b, 0x705e8458, 0x0f491997, 0x944f4c1e, 0x5279fc94,
+ 0xeecb3aa8, 0x951bb26e, 0x3fda248b, 0x9675dd7b, 0xb76176d6, 0xb2e9f934,
+ 0x7b37a431, 0xd5075bcb, 0x33f755cd, 0xe13ec452, 0xdd7f3cc1, 0xf5a16c9c,
+ 0x1687eb5a, 0xaca64ba1, 0xe1d206ff, 0x5bf7ca68, 0xf3eaed67, 0x27bfcefd,
+ 0xdc9c8421, 0xfb3ff9c0, 0x4397e79e, 0x381ba7e9, 0xefc4df7f, 0xf93fff17,
+ 0xf79fe79e, 0x6467e33d, 0xfff43d28, 0x6d003eea, 0x2fbb5f9d, 0x0fef5b40,
+ 0x83c0bc3b, 0x1b4ad6f7, 0x9ad07dba, 0x972c5fa2, 0x63eb5540, 0x1da1329f,
+ 0xd792309d, 0x9a95d6c1, 0xc0a55bbc, 0x5f0500fe, 0x1c7953a7, 0xe0bdc961,
+ 0x673c0389, 0x71a5fc38, 0xc91b2798, 0x0aee0e28, 0xa630f5e7, 0xa14ca4b7,
+ 0x9496f6fd, 0x9b37a0a9, 0xe95ef97a, 0x6f5f3141, 0xad3d2476, 0x214a70e8,
+ 0x943c8eff, 0xea2596bf, 0xbe569652, 0x6de996df, 0xbde95329, 0x87f414b6,
+ 0xebf3f662, 0xd8e63ed1, 0xb2d9704a, 0x683c52a6, 0x1ef842cb, 0xeb5ef511,
+ 0x9859feb8, 0x5f82b68f, 0x8dc0f588, 0x78a41758, 0x94e342d6, 0xc3eccdf7,
+ 0xc0c47de1, 0x7adfac24, 0x99fbe66e, 0x5542f358, 0xc188ef3d, 0xa24739d7,
+ 0xea275e7a, 0x5f3aa3eb, 0x825993ee, 0xb9bf0189, 0x67542cbb, 0xffe46d7c,
+ 0x5bbfc01e, 0x65bdf5e2, 0x1f643e16, 0xc700cdc6, 0xc4f93db2, 0x8ef733bf,
+ 0xc6054bfc, 0x1cfc391d, 0xa5711e90, 0x109c17c8, 0x5f250ef9, 0xdeb5d4a0,
+ 0x53927911, 0xb6817f98, 0xd021f303, 0x37747d4a, 0xa1493eda, 0x1223c7ec,
+ 0x8e790fcf, 0xbe50fcf2, 0x7837ded1, 0xc0b464df, 0xaf1f1ceb, 0x9ef9285b,
+ 0xf93d62ed, 0x617d963f, 0x37e697e0, 0x9da2360e, 0x8f4c6fcf, 0xc38876c0,
+ 0xef12c3ab, 0x753bf98c, 0xf142fd0a, 0xee1f7251, 0xd43bac8f, 0x17bd754d,
+ 0x99fe7534, 0xff748c7d, 0x99c7e0b8, 0x97f5187d, 0x41afd3f5, 0x946631f7,
+ 0x4f550e45, 0x18b884aa, 0xc4d39ce1, 0x5df056e1, 0xe095b3e9, 0xe81f4e7b,
+ 0xaf36c46e, 0xf284ab3a, 0x1a1735ed, 0x5f737fd1, 0x76f074b9, 0x6d1997ca,
+ 0xeacc4f18, 0x2edde750, 0x96fdf2a5, 0x7bfc482f, 0x3d58cf4c, 0x63f9c7c5,
+ 0xd63fc4f5, 0x5f8a70ca, 0x9b2606ad, 0xfb853fb1, 0xf1657945, 0xd367d825,
+ 0xcc1fc962, 0x5d8b643b, 0x83c81b90, 0x4f2ec759, 0xab5d3c40, 0xd3e4aabe,
+ 0x4639331e, 0x6dbf3d22, 0xc8f6b57d, 0xaa57da71, 0x8bc14bac, 0xaded2752,
+ 0x73ecaabe, 0xaa7d9770, 0xd6e197da, 0xfcc18f77, 0xd39efe63, 0xd2cfb146,
+ 0xa8159c92, 0xbeefe6bf, 0xa5577540, 0xbfaeeace, 0x3c357e40, 0xe490e747,
+ 0x4053f903, 0xc95aee4f, 0x022fafeb, 0xc2b6d83c, 0xd7001dfa, 0x6c7eb0cb,
+ 0x78fd60db, 0x039595fd, 0xb4adf5a8, 0xe577bb53, 0x6ddd6a08, 0xeb5ea817,
+ 0x7f63d3ea, 0x1ef3d524, 0xfaf39d97, 0x5247f7a8, 0x93ef5b5f, 0xc6be7823,
+ 0xdf40c87d, 0x988fb82b, 0xb5177f48, 0xf8c4c9cd, 0xae63f3e0, 0x0ebb844c,
+ 0x7c416deb, 0x0f61de71, 0xce3173c7, 0x58e1ed3b, 0x3f6fcb67, 0x2ffdc46b,
+ 0x11bf7a75, 0x710061f3, 0x744d6e2a, 0xf7c0baef, 0x8515b6f7, 0x59af7e23,
+ 0xfffd6b17, 0x536fb175, 0x202afb17, 0xf247a49f, 0x56c73a9c, 0xc2390f6c,
+ 0x89e90417, 0x4f5e4e75, 0x4d939759, 0x99c9b872, 0x683f3b1d, 0x9e3286be,
+ 0xcd8eb0bf, 0x3ebe0f09, 0xf340cd35, 0xa09cf15b, 0x156fef10, 0xea06ecfa,
+ 0x213ed6ed, 0x47f3b6fc, 0x48ddf44d, 0x9985eefb, 0xea5fc41d, 0xb2badc7c,
+ 0xfdf899f9, 0x1844e7bd, 0x75f3c7eb, 0xd31c7caa, 0xcb7ae3d4, 0xd32ccdcb,
+ 0xce29c239, 0xbb40ceea, 0x319bcdad, 0xb706777d, 0x7e548eeb, 0x9527835e,
+ 0xea3d608d, 0xde657f72, 0xfc6072b7, 0xd91d328c, 0x973ea50b, 0x2b67a657,
+ 0x56f33f81, 0x9754bc18, 0xa69fd32b, 0x6c6e22fb, 0x22a5e4b0, 0x623a9f9f,
+ 0x57da84b4, 0xaa7b2f6d, 0xb79e1b29, 0x5c7648d7, 0x77eab5d6, 0xa3edad95,
+ 0x16fd6953, 0xf124e519, 0x53efa320, 0xf8f3d67b, 0xd63cef7e, 0xe30a54dc,
+ 0x82ce8e58, 0x679b51f6, 0xbf433e43, 0xef879b44, 0x4bbbf612, 0x48c1cfd8,
+ 0x8f9c04db, 0x73ca4bfb, 0x4d29fe5a, 0xaf36be95, 0xfdca905f, 0xbcb286aa,
+ 0xdf483975, 0xf6863a09, 0xd8aca1a4, 0x9f341394, 0xe34f552e, 0x60fac11e,
+ 0x907d707c, 0x75b501d7, 0xe5cf4541, 0x06317fb7, 0xf409bdf1, 0x7731da35,
+ 0xe41faf32, 0x087452bf, 0x4e0046f5, 0xc94dbebe, 0x8eb7bf57, 0x0c5d7c65,
+ 0xf679cbf7, 0xcb9f9448, 0xdee9f09b, 0x139fc448, 0xb5ea1eec, 0xcc6b3923,
+ 0xe8268fa8, 0x1dfbf10b, 0x5aba53b7, 0xd27ac267, 0x8f57af9d, 0xf209efc3,
+ 0x863d0fa7, 0x615e9f78, 0x7780fda0, 0x063e5ebe, 0x2ff62baf, 0xd5d6fa7f,
+ 0x807f7811, 0xe1b70f64, 0xbc62b2fd, 0x0f877e3f, 0x226ce933, 0xdcfa0742,
+ 0x8f53a47f, 0xc998f372, 0xf00a9d95, 0x75114fe6, 0xa76e0aa6, 0x314db7a7,
+ 0xaa4fee30, 0xf4bee6ec, 0x741f29cf, 0xea9f2da9, 0xefb87147, 0xaf603721,
+ 0x1d80f7f2, 0xb1d80a8b, 0x4abf6aef, 0xcf842d53, 0x218ec05b, 0xbc29d63c,
+ 0xbfa5af3e, 0x37bfd04e, 0x1e9bd4bb, 0xe783fb46, 0x4a7ca0a8, 0xb8ed3dc9,
+ 0xc33ef30d, 0xf0975fd1, 0xf95e9590, 0x6fd0a96f, 0x73f8bdb1, 0x7af80af7,
+ 0xfad537dd, 0x2d33a9cf, 0x521ffd4d, 0x97f11267, 0xe2526f52, 0x9e04d7b5,
+ 0xa175f695, 0x77f3be37, 0x435c680c, 0x0d60c77e, 0xacc31dfd, 0x44873a16,
+ 0x80e18ef9, 0x8ced1591, 0xe2b3fdc7, 0x93af26bb, 0x8f03a4fc, 0x37f1b5fd,
+ 0x935df8f1, 0x80672784, 0x76463c3d, 0xae8f395e, 0x9e63edae, 0xfbe16d6f,
+ 0x435b6bc0, 0x9912eb9f, 0x297bedc6, 0x33ea87ac, 0x98ed7f62, 0xe44ea25d,
+ 0x596d7a30, 0x4fbcb798, 0x74b79c1f, 0xca09fcdb, 0xc52f5dbe, 0x663cea7b,
+ 0x3acb796f, 0x6afc3be5, 0xd1df8ec9, 0xd31e775c, 0x7ee1f7c1, 0x4be63cdb,
+ 0xce3aeaa9, 0xad0b1481, 0xd125dcbf, 0x9d264cb9, 0xe7f686b3, 0x425922bf,
+ 0x9a3eebed, 0xbc75e5ca, 0x6d3c83a8, 0xf4f1fce4, 0x8bed12ad, 0x90edefc7,
+ 0xc2bf4fee, 0x3a79b7bf, 0xa36f7f8f, 0xef943dd4, 0xd40e6e68, 0x3b3be83d,
+ 0xe51bfbe5, 0xfbe51a7b, 0x239b29cd, 0x07e23ce8, 0xdcc92d0d, 0x5f10f5ef,
+ 0xf61e2bfe, 0x30d0f580, 0x5e4a1f56, 0xfd16a777, 0xbb8d2a6b, 0x476f71e1,
+ 0x29ff086a, 0x7848e309, 0x5ed499cf, 0xa9b385e3, 0xfa8178ea, 0x46e178da,
+ 0x4bee3dd5, 0xdd7a3765, 0x8df94203, 0x2dfe7037, 0x9bfcf3df, 0x4d6dd143,
+ 0x15f3e878, 0x1d44d32b, 0x380e735d, 0x245df1eb, 0x924debb7, 0x51b72fed,
+ 0xf540dd3d, 0x36af4574, 0x73f9f145, 0x7b4a7cc5, 0xb3d71a47, 0xf9d0864d,
+ 0xdc62a9b2, 0x2831d946, 0xcf41da0d, 0x8397f3a8, 0xcbf9d45b, 0xe7d55a5b,
+ 0xa9f50c85, 0x3fc903cf, 0xa61f3ea4, 0x1f3eafd0, 0xf509f866, 0x3b2330f9,
+ 0xdcc3e7d4, 0x7cfaa1f6, 0xab741f98, 0x5fb797f3, 0x5ef9aa9e, 0x77cfcbd3,
+ 0x7e0dce02, 0x4f34c4ae, 0x4e8d2e73, 0x844d2e73, 0xcd1a5ce6, 0xde622839,
+ 0xcd1f4f2c, 0xf5ea34f9, 0x971eb159, 0xb8f5fd7b, 0x44d8fa67, 0x386fae3d,
+ 0x5948f73e, 0x6dfa384e, 0xffd377ca, 0x97ccf821, 0xf48b9ae6, 0x5b1ead71,
+ 0xb1d57c87, 0xf3032c2a, 0x29d5ae2e, 0x83f03c72, 0xbe8921eb, 0x9d5e2f9b,
+ 0xe67bfb42, 0x3f250c35, 0xc8398f29, 0x638caa4f, 0x5873cf21, 0xd6f5c69f,
+ 0x33037adc, 0x6ccbe0c6, 0xd0a81d46, 0x5b124d73, 0x798dedcf, 0x3561f022,
+ 0xbb587ce3, 0xd53458ee, 0x59dd85bd, 0xaac151c4, 0xb9d217eb, 0x5d73da0d,
+ 0x318b586a, 0xbc59e605, 0x41e49da1, 0x628bce7b, 0x9e62dc87, 0x7df516da,
+ 0x8170db37, 0x1d6789ce, 0xee33b446, 0x86fdf556, 0xb32f5134, 0x8dca3b33,
+ 0x1328beeb, 0x02c597fa, 0x4836732f, 0xce0fac16, 0xb84f686b, 0x0ef3fa0b,
+ 0x296f14c9, 0xce3d6178, 0x73a5c9e1, 0xea1e2fd2, 0x45f3fe47, 0xc7092d9b,
+ 0xbc79a2b9, 0xc35de920, 0x9c657af1, 0x5f9e386b, 0x0a327dd6, 0xa761f1bf,
+ 0x5fc8eb2f, 0x08681f00, 0x36166df9, 0x3bcf3824, 0xc44960c7, 0xdd878b3c,
+ 0xa6714c93, 0x75957b88, 0xc7104dbb, 0xe21f6346, 0xe93ebe54, 0x46e8892b,
+ 0xfc1bad26, 0xf80f7c22, 0x9ac7143f, 0xfa156998, 0xcd6d673f, 0x3afae889,
+ 0x5f90301f, 0x2c477731, 0x1b7315f9, 0xfe788c4a, 0xb15ddcc1, 0x79967fb4,
+ 0xae31c71c, 0xba78e855, 0x3260ff21, 0x25b73bcc, 0xe9ab2ecb, 0x17138aa7,
+ 0xe8569d37, 0xba0d79d6, 0x1ba28675, 0xfd754bd0, 0x17e134e5, 0xfbb17a08,
+ 0xbdfbe8e3, 0xfa07a58a, 0x62efbe61, 0x0efd387d, 0xc038cf45, 0x5a64f5c3,
+ 0x29de2abc, 0x8e3573eb, 0x2fba73a3, 0xba24286d, 0xf655e969, 0xe386f3df,
+ 0xafec55f7, 0x8dfd0c51, 0xf66cbeca, 0x5b3eb854, 0xb955f2e2, 0xfa196c66,
+ 0x7d0a6f39, 0x8b88baf8, 0x045c618e, 0x189bfc7e, 0x2dff4117, 0x05fd1711,
+ 0x4f6822e3, 0x6d045c62, 0x4fff38a7, 0x00603391, 0x4293d7e2, 0xd55e4ebe,
+ 0x3193cbf3, 0xdff6569f, 0x80ea166f, 0xb53c12e7, 0x33a74693, 0xf6a1d936,
+ 0xa9a7cba7, 0x830ee9fd, 0xed324c65, 0x81f5e26b, 0x54dbceb9, 0x66de99e3,
+ 0x1b073cc4, 0x4eb81f90, 0xc466c7f6, 0x098cc73c, 0x3ff1aa71, 0xf5554a6c,
+ 0x0c5fa02f, 0xeb294df0, 0x777ebaab, 0x7f5520c5, 0x424065ce, 0x95af723e,
+ 0xe22ce79f, 0x2794ca24, 0x9f0dea06, 0xfa4f0fd6, 0xe9fbc011, 0xd7dd0311,
+ 0xeba143d2, 0xca3acdfc, 0x0cdbcedf, 0x3b79836b, 0x5c91e79b, 0x8a227c7d,
+ 0xdc6987ce, 0x08daff91, 0x61de9fe8, 0xa764fda0, 0xc21ee21b, 0xef4faaf3,
+ 0xefc68848, 0x328d5cf2, 0xb59e91f3, 0xe6559e90, 0x4558692d, 0xc7307fbf,
+ 0xf947661b, 0xf3dfb39f, 0xfdc7d2b8, 0x0645b401, 0xecb8e3e5, 0x3f4449f5,
+ 0x7b77e107, 0x3fc5e538, 0x058f3034, 0x1d79cbfc, 0x250fae1c, 0xb3fd80d6,
+ 0xfff4efe1, 0x6e71c011, 0x0e957362, 0x48f928fd, 0xe7cbe902, 0x5b7c8665,
+ 0xe740d4b1, 0x4b7a2f09, 0x267d8ade, 0x7a72a5e5, 0x1d3bf4cb, 0xcd187b6c,
+ 0x4381bacf, 0xdff2dc60, 0x5eb93d84, 0xffa8b9e4, 0xf5dec1fb, 0x8f913f82,
+ 0x8e658c3e, 0xe7960258, 0x963a3e1b, 0x009e7540, 0x7043bd3e, 0x3bd4bfdd,
+ 0xbd83a5fb, 0x3bcaa8fa, 0xfddaf484, 0x5a572409, 0xb91a77bc, 0x1ca0f2de,
+ 0x197d0148, 0x9dfe3390, 0x3d833cd5, 0xaafa4ed1, 0x55f50520, 0xe50306e7,
+ 0x11de9915, 0xcf70ebcd, 0xef2b1f13, 0xc6dbd4e9, 0x4d9d7c20, 0xe11df459,
+ 0xd9320ddc, 0x3e3fe43b, 0xebe3cbde, 0xe30bb28d, 0xe4934f75, 0xcb5d78c2,
+ 0x0e96cb37, 0x9815dfa7, 0xd9193885, 0x4f9c0f53, 0xa50775e1, 0x3f0f78bf,
+ 0x74159fd7, 0x0e0da7e8, 0x7f03475e, 0x5f9f325f, 0x26bc7739, 0xf0a74ffb,
+ 0x878ba668, 0xf7e0c6fa, 0xcb8f6738, 0xb36767c4, 0x0325879b, 0xedd13f3d,
+ 0xe823f61d, 0x73d13c7f, 0x70fd8f46, 0xebc454d7, 0x0c86dd12, 0xabba1efc,
+ 0x6e87bded, 0x7a3ee783, 0x312760d6, 0xfa40915f, 0x45f6f163, 0x7df75f99,
+ 0x3ef05810, 0x48e8cf3c, 0x4b9f0091, 0x30632d6c, 0x3980b07f, 0xf8e21d85,
+ 0x79e0edb1, 0x9e26cb0c, 0x30af78d7, 0x67ee3d6a, 0x5bc9a79b, 0x13be27bc,
+ 0xa92e905c, 0xa2ed84fc, 0xf9c74f3f, 0xf3c73d9b, 0xd2a7f059, 0xfbf16eff,
+ 0x57de8a1e, 0x6b0d75f4, 0x7fa9f3a6, 0xf04d9e94, 0x34bc922c, 0x9a4f0eae,
+ 0x65551506, 0xcd6af1e1, 0x8a5e6133, 0xe9606d47, 0xdd80fc82, 0x6e7a36e9,
+ 0x47d9f1b1, 0x32176d91, 0x669f5f3f, 0x6f0647dc, 0xa7ab3f95, 0x6cb2a9bd,
+ 0xfcd2b06d, 0x57ee3b06, 0xb4e4285c, 0xfaf259b6, 0x6ec83af8, 0x2cf3102e,
+ 0x6b537610, 0x23d87a9f, 0xa05a1d8d, 0x59acb3b1, 0x5e01576d, 0x815b973a,
+ 0x33a70b57, 0xb0f08a32, 0xcf9f99b8, 0x1ef2e551, 0x4b70449c, 0x0f64a076,
+ 0x67321678, 0xe3ae2c69, 0x6b8f1e19, 0xabaed3e1, 0x9d62bc07, 0xecabb85a,
+ 0x01727c17, 0xda0a3dff, 0x8759a9df, 0xbfad0f42, 0xcaa5d0a6, 0xd55bf1c3,
+ 0xdf3d1126, 0x3207eabf, 0xf0aa07da, 0xff816b0b, 0x4e779ea9, 0x70b67d42,
+ 0xacdfe813, 0xfc28ff00, 0x44b598b4, 0x31d4bf23, 0xd496235f, 0x7e5afacf,
+ 0xcf0b3238, 0xe7463a65, 0x7d585547, 0x80b174fd, 0x1fdfcf42, 0x8041fb2a,
+ 0xbe78b5af, 0x17af5d16, 0x11d44c6f, 0xd3c039e8, 0xfa64a782, 0x9c6827ae,
+ 0x243d7f88, 0x8f1ed54f, 0xd5cbeb11, 0xdc3e7e7a, 0xeb74e0b5, 0x5d29eff9,
+ 0xfc5ede13, 0xf70aefa4, 0xf9bde907, 0x4262fd59, 0x9d6529e9, 0x72bd08ef,
+ 0xb7aefb4d, 0xbec8c5df, 0x8f984827, 0x575f4de9, 0x00bebb09, 0x67b43ced,
+ 0xe740bf36, 0xe9bfbe2e, 0xd55f3a05, 0xda02ecf8, 0xf3667097, 0xf7f087bc,
+ 0x98ecce23, 0xe17d7647, 0x775d8a63, 0x85fd8319, 0x9e73cd92, 0xafc85ff8,
+ 0xdd5384cf, 0x4bbf6ab8, 0x47a039c4, 0x336d9c61, 0x136c9bd7, 0xd10ba3d7,
+ 0xfd92e5fe, 0xddc709bb, 0x09bae557, 0x3ae83ef9, 0xe6fbc5d9, 0x07b77eb9,
+ 0xb7efbde6, 0x2d0f7691, 0x79e3e2d9, 0xed0f8b67, 0x7f3ded5f, 0x0bbf4539,
+ 0xeb791f25, 0x87bd8ac7, 0x577aedee, 0x97ca0642, 0xf2b5f3b0, 0xfa0b0cd6,
+ 0xfc2ec205, 0x173df1b3, 0x14fe4df1, 0x4dbbf7c7, 0x6defcf1c, 0xdc6f78e0,
+ 0xd3e297d1, 0x92fa9b77, 0x8eeef51f, 0xf9ef847e, 0xe4df01eb, 0x7ed4db47,
+ 0x1be01354, 0x37c404e3, 0xbf7735c0, 0xcedbe04d, 0xf1c4ddf1, 0x76f036cc,
+ 0x7abc0f7e, 0xfbf4fce8, 0x8ecc3dfe, 0xe187c17e, 0x3e97f23e, 0x99d329dc,
+ 0xa59f8a67, 0xb19f39f8, 0x1fd1c7e6, 0xa8bdf053, 0xea087fbf, 0x7f8d8a97,
+ 0x2fbc468a, 0x2393c9da, 0x1ccdf03d, 0x076fe849, 0x2fd57fde, 0x0848cb2a,
+ 0x21be8bf2, 0x9398ea5d, 0xe1d723f6, 0x82436479, 0xbf2b3df6, 0xe7dda65b,
+ 0xc8f9e36c, 0x99376630, 0xed349e10, 0x18b9afef, 0xbcfe7bee, 0xf75985df,
+ 0xab771c90, 0x12634f7e, 0x9cf019f3, 0xd122d602, 0xe5da967e, 0x188ba34b,
+ 0x4f5a3f9e, 0xe0cdac70, 0xbc2bbd76, 0xb2fc833b, 0xef1c613d, 0xf3aaf19d,
+ 0x6fdd2789, 0xb457f98f, 0xf9f847fb, 0x763c93c4, 0x1a4e67ca, 0x2ab93431,
+ 0x2e0bae88, 0xab8973f3, 0xf2e6032e, 0xc6fdf7f1, 0x0587bed2, 0xcea853cd,
+ 0x496d055f, 0xbe5ef8f0, 0xc19b5bbf, 0xb8539be3, 0x973c3ca6, 0x9d7efc49,
+ 0xea8d1738, 0x539b80b4, 0x373a4ee1, 0xc98254ef, 0x8bbacfce, 0xeffdf3a1,
+ 0xa6707a16, 0x13ed20f9, 0xcc3c7987, 0xbfd6e78a, 0xab014069, 0x8b3c7530,
+ 0xe4ecf021, 0xe935eef7, 0x837f6b70, 0x7773e445, 0x13d7157d, 0xd51d009e,
+ 0x23b9b9e7, 0x9a3fe742, 0x87255e05, 0x610cea83, 0xbc047730, 0x3619e7ff,
+ 0x6fec5d7e, 0x9e805b67, 0x85cf3d51, 0x0f33ae53, 0xa6b60f3f, 0x2b7dfe18,
+ 0x7a848ce3, 0xfaa9d643, 0x7f7e4635, 0xc9c4c67b, 0xf631469b, 0xf7ac0306,
+ 0xf194bf45, 0x8c4e7f38, 0x4d75f717, 0xaca373c6, 0xaf89ead8, 0x4799eaa6,
+ 0x3326dbc7, 0x79c43bd6, 0xfe049351, 0xbe608fa6, 0xdf7de018, 0x89b9f561,
+ 0xbe74f977, 0x93af009b, 0x21ba5cf1, 0xcd9cfe78, 0x38f78160, 0x8c3ca4cb,
+ 0x7f566a4f, 0x64f77833, 0x94de4f94, 0x8e9d7d06, 0x9e63f9c3, 0xf989988f,
+ 0x2cc3c079, 0xe72fdb3d, 0x5e237a71, 0xed1b56dc, 0x2a5ee8f3, 0x25147ed1,
+ 0x7bd0af2f, 0x4f2f2068, 0xe0299c74, 0xa29a7983, 0x686379f1, 0x50ce1d7a,
+ 0x8a16e8e2, 0xf90897af, 0xe5c8a25c, 0x9e5cb50e, 0x7e823a45, 0xc8893dc6,
+ 0x0b453357, 0x6bf9a4eb, 0x73947bc4, 0xf064cfd3, 0x0c99e97c, 0xfe387f5e,
+ 0xccc7df2d, 0x45469cfc, 0xf8c36b3e, 0x27fbcafc, 0xc333b68b, 0xf02bf34a,
+ 0x1ff1f368, 0x7e43596c, 0xccb7f552, 0x1be907c7, 0xc6497baa, 0x7a88f9ee,
+ 0x49c25fe9, 0x5b1a66ee, 0x7b9bd5fa, 0x1dce538e, 0x037e60ac, 0x55300faf,
+ 0x6cb4741d, 0x2b2c73a6, 0x9afbfe24, 0x1e51455d, 0x6be60c5d, 0x8ada440c,
+ 0xe973f31f, 0xfbe709de, 0xee632b3b, 0x607e849b, 0x4f51b445, 0x7f31ece7,
+ 0x40565654, 0xc91636ef, 0x04214e74, 0x6eb19382, 0x7feb06b6, 0x23b0ffbc,
+ 0xa24bb28d, 0x51d7b3ff, 0x02bb4d1f, 0x43fea7f4, 0x0f101d93, 0xf7101d75,
+ 0x7cf4c3d9, 0x8f8203d7, 0xfde73f3d, 0x37f7285f, 0xe53afef3, 0xffde16fe,
+ 0xe8bf3299, 0x5fdcd46f, 0x4bffb9a5, 0x627c4fde, 0xfa0f64cb, 0xa59cc5af,
+ 0xe8956e2b, 0x05ca3577, 0xf6ac559f, 0x742b7e11, 0xcc5b797b, 0x6b82ba7c,
+ 0x74ce2b8f, 0x211fa396, 0xa1467547, 0xe5909e9d, 0x75bb4728, 0x2b2bba6b,
+ 0x53c5da13, 0xd6118f24, 0xc97b8ecd, 0x45ea4c6e, 0xbe0b971f, 0xf9f1b22d,
+ 0x3cc37c14, 0xbf0b3303, 0x847e3cfd, 0x4f35412b, 0xf3c0f5fe, 0x798f5b6b,
+ 0x3ccf5d46, 0xbaf52cba, 0x89e83f14, 0x385dc76c, 0x2e1ed69f, 0x063da9f9,
+ 0x35ec50f3, 0xeae1fdf1, 0x987c8c96, 0xbb73c97f, 0xefd0aa33, 0x1d40fe12,
+ 0x3c7cc3da, 0xc3db82e7, 0xf24fdb8f, 0xdabb707d, 0xbf30638d, 0x3db06d0f,
+ 0xce05e9ac, 0xd89d4c8a, 0xd791b047, 0xab3b9ec5, 0xd12e7a47, 0x0c799cb5,
+ 0x52adfbed, 0x1127dfe8, 0xe5ea9dcf, 0x66e68e77, 0x90d43d72, 0xeb8398e3,
+ 0x3464c92c, 0xe84d64be, 0x9b7f9a73, 0x8572edc9, 0x86f37bb0, 0x806c9945,
+ 0xaee3c2e7, 0xaabfb835, 0x1e564b6a, 0xa56785e6, 0xfcc92f17, 0x376abcda,
+ 0xf1b6abcf, 0xd5856abc, 0x37941cbf, 0xedb33a7b, 0x633a5361, 0x914dffe3,
+ 0x78591033, 0xe94c2cb6, 0x74b939bf, 0x617bcf14, 0x4713dd7f, 0x39b9461e,
+ 0xfe60f084, 0x08e0f87c, 0x591d0bd4, 0xe80b3a91, 0x7369598b, 0xacfe469e,
+ 0xda03fe1c, 0x1614532f, 0xcf0e7fd5, 0xcc5f13cf, 0x42ae734a, 0xe63c7138,
+ 0x5f465c43, 0x0eb05dc2, 0xed32abd7, 0x890d7553, 0x4efc8574, 0xe9e1e059,
+ 0xebe10b4c, 0xfd199010, 0xe50e0514, 0x2fe7e0fd, 0x9d7cc3f7, 0xe28653ab,
+ 0xb4be4e77, 0x85996da2, 0xd2fbf781, 0xbf048f5c, 0xfac753bf, 0x4df1a863,
+ 0xc05878e1, 0x06e90db1, 0xcc9473ad, 0xdef1411c, 0x5548d2d4, 0x3884da7f,
+ 0xd7ce08e6, 0xf5554b4e, 0xaafa2bcb, 0x7f3ddfc6, 0xc4feea90, 0x7d417f30,
+ 0xbbdbbf90, 0xe7e1e49f, 0x4545458f, 0xbfbcbee0, 0x36f67db7, 0xd7745efe,
+ 0x7d1db253, 0xb67b45da, 0x03478dbd, 0xb39fc45f, 0x8da43ca0, 0x1d1f66f2,
+ 0xd73f1992, 0xae0fa1c2, 0xfe639d0f, 0x1077f147, 0x2907ab7a, 0xcb12eef1,
+ 0x801dfa7e, 0x3a0f5d1b, 0x41ea2998, 0xed0f2c79, 0xb7fac5e1, 0x67576f28,
+ 0xb73bebe6, 0x8b4f9f9b, 0x057f53e7, 0x3e077efc, 0x65e1fe88, 0x4bb5e50f,
+ 0xfd534f5a, 0xeb932aac, 0xa5b4bae9, 0xdd8bf47a, 0x181da2d0, 0x062afa03,
+ 0xcedfc5f8, 0x7dc2ef06, 0xdc51596c, 0x953cbf5f, 0x2be438b1, 0x9439e79e,
+ 0x53bf4b18, 0x8ca9a4bc, 0x8e5dd7ae, 0x975ff9a0, 0xcd4fb4fd, 0x754492f3,
+ 0x95a98988, 0xc6bf71ab, 0xee4f08a1, 0xc4ef7832, 0x8651dddf, 0xc5dbab78,
+ 0x944c91f7, 0x0a5828df, 0x19734d6d, 0x66513f3d, 0x17f02487, 0xfb7097c6,
+ 0xbe6d113b, 0x46e0f715, 0x2bbb47ad, 0x7ffd7d1b, 0x18c67a85, 0xe6267a45,
+ 0x7ef4ddf2, 0x3d1365f7, 0x88f425df, 0x35c383a1, 0xae93b2fa, 0x59f0fc2b,
+ 0x77eab666, 0x4f090c7f, 0x91f7f1e9, 0xc68c1d0d, 0x903cbb8f, 0xafbd655a,
+ 0xfa77f80e, 0xc2435b5d, 0xfa5fb4a7, 0x42c978d5, 0x0f46886e, 0x1e1faa5f,
+ 0xa9e842c3, 0xf111efab, 0x5fea1848, 0x72ccbf68, 0x3012da44, 0x63d0e99e,
+ 0x4d99885d, 0xffe44fb4, 0x0538cd00, 0x00800076, 0x00000000, 0x00088b1f,
+ 0x00000000, 0x7dc5ff00, 0xd554780b, 0x399ef0b5, 0x66491e67, 0x99212726,
+ 0x4ce21024, 0xe010245e, 0x0f080424, 0x860240cb, 0x084013a7, 0xbc80e834,
+ 0x2b101025, 0x0337e95e, 0x60d22049, 0x45405283, 0x68b0503b, 0xaaf8ff6d,
+ 0x0131f5a9, 0xe94a0fe4, 0x7ab7bd60, 0x52036b6f, 0xe08d4504, 0xb16dcfed,
+ 0xbdad6bfe, 0x3267324f, 0xfdeded41, 0xbe3ef9ff, 0x3ef6759d, 0x7af6b1fb,
+ 0xb30fb5ef, 0xcb5d8aca, 0x0afb188b, 0x9318137f, 0xbb302e8e, 0xda663286,
+ 0xb1ecc67d, 0xb2816631, 0x96bea23c, 0x046b4f31, 0x2e4995ac, 0x19236323,
+ 0x3950b6fc, 0xfbc1db0b, 0x631f77cc, 0x576ec64e, 0x4a6dff18, 0xb1832c65,
+ 0xed04dfbf, 0x0fde7b53, 0x852ea01b, 0x968bc0b1, 0xbbf861e0, 0xc72fb65f,
+ 0x89e1f505, 0xec39faac, 0x55670e47, 0xcddfa1d9, 0xda15b29d, 0x39559b31,
+ 0x9ff806ec, 0x6f82ff34, 0x8ba77f39, 0x12b7ffcf, 0xfdfd84db, 0xb084c276,
+ 0x7ed5e607, 0x921188ff, 0x31dfa7ab, 0x63b5332e, 0x5675d74a, 0xd7bad8ca,
+ 0x603b5c12, 0xc1fb337d, 0x5ebb8033, 0xba0f04b5, 0xa43339e9, 0x68396960,
+ 0x8e75fa80, 0x8c2f7cae, 0x5c7afe5f, 0x7e830d88, 0x19938f5f, 0xae52f38c,
+ 0xa5e20c6f, 0x1541f5fc, 0xf24c0706, 0xa0cc8b15, 0x3c9ba4dd, 0x5f79f163,
+ 0xaf5e8df3, 0xf9c60256, 0x18a7cefc, 0xadbbbdf1, 0x5529b5fc, 0x22624086,
+ 0xc954d774, 0x16c608d8, 0x9b0d9b5f, 0x6b92d8c2, 0x5afb04f1, 0x75abf3f8,
+ 0xdf705369, 0x49866eae, 0x6c963ac3, 0x017d0c36, 0x765cc5d6, 0x30f00f35,
+ 0xada2c073, 0x5339e60c, 0x677ad232, 0xd60a490e, 0x71dbd343, 0x73e0c7bf,
+ 0x664861d6, 0x3db97a6c, 0xd6f18460, 0xdfa8535c, 0x1a2e6bda, 0x64b5ed6f,
+ 0xb35dd782, 0xdae4b952, 0xb96e7a60, 0x801e6466, 0x1c035e97, 0xdb273c00,
+ 0x3fd70ab7, 0x4a96feb3, 0x35b7cf1c, 0x8b67d4a3, 0x82b317a4, 0x92f40574,
+ 0xb3d6dcbe, 0x05f6fafe, 0x2fe85530, 0xb2f44bc5, 0x88f2ca14, 0x0e8265fa,
+ 0x56b6f1a2, 0xa537ffec, 0x5f411a97, 0x3ca16c4b, 0x54c1e023, 0x856ea717,
+ 0x71495cf9, 0x6cbc414d, 0x6fe38078, 0x6e5bc983, 0x786ef987, 0xcec2a0c4,
+ 0xd9473bb0, 0x32f00cad, 0xb33addea, 0x176e822f, 0x5cc61b5c, 0xd739feb0,
+ 0x7dbca972, 0xae336fa0, 0x79b5f17f, 0xa8c34f02, 0x2364d664, 0x46d8c51b,
+ 0x4e1757dc, 0xb3ef9928, 0x7517df98, 0x85eed3a3, 0x6538bff1, 0xb88bfaa2,
+ 0x5530252f, 0x9c09e04f, 0x51682997, 0x2ebcc00f, 0x8140589a, 0x9f73b8ad,
+ 0xdf000591, 0x41f4a14b, 0xb07b5d09, 0x291de59d, 0x92ed8ed8, 0x04a92798,
+ 0x2deb09f1, 0x057c63e0, 0xc2192eff, 0xfd42f7f9, 0x965b3327, 0x81e0731b,
+ 0x86552a74, 0x9cf27e75, 0xbe7824c4, 0x4e1bfd6a, 0x95ab1e58, 0x5029640e,
+ 0xcc10d1bf, 0x3d8c4937, 0xe2f6fb22, 0xd85a3eba, 0xd0656ffa, 0xf3cb7cee,
+ 0x0d57dc0e, 0x2872adaf, 0x0569fb0f, 0xee60067c, 0x6552cdad, 0x26c346d0,
+ 0xa1ed0d54, 0xa39e8d6f, 0xb5f57ce9, 0xaba7a26c, 0x2fa19675, 0xdd031d20,
+ 0x415af3e2, 0xfd2177ef, 0xacea6943, 0xe9c8f414, 0x5aeba35f, 0x5aadcb99,
+ 0x0030625b, 0xbff99bf3, 0xf500fe80, 0xf2a85f6b, 0x2bba444e, 0x5079a830,
+ 0x32fc11ac, 0xe0f83a53, 0xcf83e458, 0x787ad452, 0x579af93e, 0xc1f3d73c,
+ 0xc674fe4b, 0xbc4b19f2, 0xd5c690b6, 0xe822dfe8, 0xdff484dd, 0x2d83de8f,
+ 0xd9fffe05, 0x77ff9edf, 0xdb90f3f8, 0x6be216f7, 0x7fca1c9a, 0x3b4b052c,
+ 0x94e4d1d1, 0xe7e9192a, 0xb3cfcb9b, 0xd59e7e42, 0x7db5cfc9, 0xb7f0cfc8,
+ 0x04d787e4, 0xd85a543f, 0x2e22de1d, 0x7bdb67df, 0x3d97ebfa, 0xea0b9ce9,
+ 0x7819743f, 0xf343ff7f, 0xca5bf0fe, 0x86fd7ffd, 0x42afff72, 0x79cb47ee,
+ 0x9ca1fd06, 0xc2d5ecff, 0xf781ea20, 0xd405e819, 0xb824af7b, 0x403d0b0e,
+ 0x313e227a, 0xd03d2378, 0x5fe77b90, 0x7f03d0fb, 0xa3fdbc43, 0x3fa3407a,
+ 0xfe345f8d, 0x9a21f8d0, 0x987e347f, 0xf13503fe, 0x401fdc5e, 0x1fe461cc,
+ 0xae0cf039, 0x5095d6a3, 0xf1a97c8c, 0x0c17dad1, 0xf4bd67c4, 0x1e9be083,
+ 0x0bebd13e, 0x3e341f8d, 0x56a6f8d1, 0x28b2c3f0, 0xb526387e, 0xde163c3e,
+ 0x15f6eedb, 0xf87b53b9, 0xd173cd63, 0x7a4fa17a, 0xcb4f4862, 0xd218ea52,
+ 0x91942d53, 0x83e964f4, 0xdfdd8a9e, 0x126e9e8e, 0x9e8ebfed, 0x6a66dc2a,
+ 0x4f483ff7, 0x3191ee15, 0xfbb269e9, 0x5c57689f, 0xa97dfbad, 0xb573e60b,
+ 0xbbace414, 0xbfa6de87, 0x90ddb8c5, 0x7e915763, 0x3af9e23a, 0x8303cc3b,
+ 0x2beed8f5, 0xd4788756, 0x67db52e8, 0x86580ecd, 0xb6e50074, 0x9c2aef6c,
+ 0xa07c476f, 0x9337fd68, 0x96cfb477, 0x53d9b094, 0xd61dfb84, 0xecbeffe9,
+ 0x72dfb5c5, 0xdfdc6b9f, 0xddf86e4c, 0xd17b74ff, 0x272d8eef, 0x7d9dff02,
+ 0x7f0e599d, 0x94f047f6, 0xf61e33d7, 0x660287e7, 0xcbf22f61, 0xfead32bc,
+ 0x191e2d37, 0x3dfc03e5, 0x30f04696, 0xc381e12b, 0x0ae1d381, 0x87f4e798,
+ 0x5803ebbb, 0xa27c793f, 0x0c798fe8, 0x8ffda7ac, 0x6e15bc0f, 0xc2defd26,
+ 0x94ebeff1, 0xe02343bd, 0x11ed8052, 0xbc145970, 0xc877b79f, 0x7ea14c9d,
+ 0xa0af9c82, 0xc209437f, 0x7e827f5a, 0x55f8e799, 0xc52cf3c0, 0x3ec076c0,
+ 0xf0394bad, 0x6b9455c6, 0x7066066d, 0xfd81e045, 0x04c9ebde, 0x20c578ba,
+ 0x7b08ffe0, 0xf85b1972, 0xb84f8702, 0xc812d4ff, 0xbe02fd15, 0x9b7408d7,
+ 0x091e0d5a, 0x66535bfa, 0x7bbb6608, 0x5b84fbe3, 0x7cdaabd3, 0xdfea5540,
+ 0x6f94e667, 0x6d1a3ef7, 0xbd367ef4, 0x8b7cb21f, 0x678fe7f1, 0x7b0c609e,
+ 0x1f820ff8, 0x63134a2a, 0x4b779fd6, 0x01d7ff1c, 0x4787c6d6, 0xc1fd6073,
+ 0x5975fc18, 0x1a3617f4, 0xd6ff3e05, 0x36167482, 0x6bfef86b, 0x327be20b,
+ 0x8274dd63, 0x13e30374, 0x7fdc7ffc, 0x7cc936f5, 0x7c289eb9, 0x6fbd68dd,
+ 0x2057c0c6, 0x372cbf6a, 0x6ee9f7c0, 0xbef3d0b9, 0xe87eff4b, 0x4ef5fb46,
+ 0xdd05f1af, 0xd8e8d4ae, 0x44f7a3a3, 0x99f44bd9, 0x02506298, 0xbd6b8f40,
+ 0x2fe8cd71, 0xa9a7f0f4, 0x8e14f10a, 0x87a9e3d3, 0x1555ccff, 0x448fb236,
+ 0xe42eeb7b, 0xbbb1af5f, 0x6ec7e73d, 0x029e66ba, 0xd29a2bc0, 0x41d27ef8,
+ 0x8d80aecb, 0x09ea82e8, 0x77988dce, 0x46b63f34, 0xf8a3e3c1, 0xc91ff057,
+ 0x8007d40f, 0x6f943ca7, 0xaecd6729, 0xb3513a08, 0x313e9e39, 0xa7946ab0,
+ 0x8edc49e1, 0xd2f3670c, 0xfaa06d9b, 0x1fbe6cb2, 0xe386511e, 0xa7a0f023,
+ 0x2bfa109f, 0x3c26eb11, 0xd6d1482d, 0x0335505d, 0xe64e15d6, 0x73b2d3f5,
+ 0x7b320577, 0x66fee8e0, 0x05541764, 0xcffb228a, 0x5d78833f, 0xcde6f020,
+ 0xeb06741e, 0x4b507935, 0x11f44284, 0x8b507940, 0x4de861f4, 0xbdd9e91f,
+ 0xf51033e8, 0x8374c7be, 0xbf7ab3f7, 0x9f7a89ef, 0xcdbe5299, 0x66df62fb,
+ 0x656bed44, 0x4456bed4, 0x1c1a35c1, 0x4d5fc9d4, 0xdb692f2e, 0x7984e8d5,
+ 0xe40475dc, 0xe7a48b2c, 0x77cf4451, 0x8efd1a29, 0xbb7a833e, 0x08cb9e87,
+ 0xf62add9e, 0x1766302d, 0x942a9fea, 0xe07b63c3, 0x08872839, 0x19e55b1e,
+ 0xc6afa91e, 0x3db942ed, 0x3f6b49bf, 0x6c2fda9e, 0x99bbfad0, 0x647db5ea,
+ 0xd154ef81, 0xc3b90abe, 0x60ce1302, 0xf857eafd, 0x3d07f5fb, 0x0fc86e67,
+ 0xd978512d, 0xa207051f, 0x1afeefda, 0xf510d6fd, 0xfaa8e6fe, 0x5f7828e6,
+ 0x7fa4dc14, 0x0352f17f, 0xa062e1f1, 0x6888dc07, 0x8fa68cbe, 0xedbbb387,
+ 0x6e7d6e9c, 0xa77d91b0, 0xf5e9abe3, 0xe0fc7e1c, 0xa2a6aacc, 0xd6fb3808,
+ 0xdff700aa, 0x2697480d, 0x73207fc6, 0x83d01203, 0xf9b90fa9, 0xb2e8be83,
+ 0xf3df5a20, 0x9fe13ffa, 0x332f6819, 0x4c725d9d, 0x92edc3d2, 0x6745ef36,
+ 0x43e11636, 0x42a9ae0d, 0x5efa7a7f, 0x9fc0bafd, 0xaac2f015, 0xbb08cc8a,
+ 0xcaa0b028, 0xad4eb113, 0xbf2f94fd, 0xe7bc7092, 0x1d5417b3, 0x499afa82,
+ 0x983abca1, 0x2f324d67, 0xa84a5f41, 0xf889d7af, 0x255794cd, 0x9acbea2f,
+ 0x86de50f8, 0xb27588a2, 0x675c7cd6, 0xed12fdfb, 0xf61ea04f, 0x98b4f007,
+ 0x8f0a2381, 0x331e64ee, 0xc4fa81cb, 0xc24f4dc4, 0x97eec77b, 0x7e9ea136,
+ 0x273f537f, 0x39c943fa, 0x963ceedc, 0x19739378, 0x7709edc0, 0xdf6dbc90,
+ 0xa3ca993e, 0x975b6792, 0xd9dbd8c2, 0x856caaab, 0x78489f58, 0x69707d3a,
+ 0xefa016d5, 0x7a2ed933, 0x38ac97df, 0xdeded0db, 0x5d876261, 0xe2952f38,
+ 0x5a778b48, 0x7ce0778a, 0xa2710cb6, 0x47e4b9fd, 0xa0325355, 0x934692dd,
+ 0xa754768a, 0xf9c2c951, 0x364c76f9, 0x06d2fd63, 0xa16e0651, 0xffbff5f2,
+ 0xed01dea4, 0xa8371ebb, 0xcdfda107, 0x35beb45f, 0x4d15e00c, 0xd16e2a39,
+ 0x2807e06b, 0x7db9ce30, 0xd0128283, 0x757107e5, 0xf6f16627, 0xb8afdb0c,
+ 0xab3d3aee, 0xca4bdb14, 0x017f6856, 0x7cfda39e, 0xa0e901e1, 0xb0e5e701,
+ 0x49601bc7, 0x1464be17, 0x68d0b9cf, 0xee7c6209, 0xfb77cd9c, 0x9f671c3e,
+ 0x767d2d09, 0x1872e0c1, 0x1d9f0f00, 0x3d2ab7bc, 0xc45b9f03, 0xb49bdefe,
+ 0xd8b0f018, 0xa43f4dd8, 0x7127964f, 0x7becb3f8, 0x3ac30eab, 0x88323c2e,
+ 0x722b57e2, 0x80d95d3c, 0xcf5cc2af, 0x107e58e7, 0xebd6f5c7, 0x40ee977f,
+ 0x97d7fe3b, 0xbe913897, 0xd6f426fe, 0x3896d76b, 0x55d84497, 0x89913fcb,
+ 0xbb375e0e, 0x5f7ce236, 0x40681f8f, 0xa0e81b3f, 0x97c9c61f, 0xe805bf0a,
+ 0x31f3d379, 0xcd7fabec, 0xdabf6896, 0xde3a907f, 0x6deba3a5, 0xdfc8a7a4,
+ 0x93f6d800, 0xa002bbad, 0x365bcfdb, 0x8e500fb1, 0x7147ee6d, 0xc84ca5db,
+ 0x82e26781, 0xf4b157e8, 0xf8c8fcd6, 0x8a1f374d, 0xd80c7ff6, 0x847faf09,
+ 0xfdf7e8f6, 0x761ff031, 0x7eddeb66, 0x401ec385, 0xbb43e2e3, 0x78fdc65d,
+ 0xb85ff65f, 0xfe5bde0f, 0xc0f489b8, 0x3753c7f2, 0x40b8e177, 0x8b571837,
+ 0x1c82d75e, 0xf4638f13, 0x878197c5, 0xfe742aab, 0xbf24c3ca, 0xfccbe2fb,
+ 0x75543c9f, 0x5f37d6c8, 0x7cb850ae, 0xc9b8f29a, 0x62b4fc8b, 0xa0665da4,
+ 0xfe3d264f, 0xcfc461c6, 0x2571f58a, 0x8af89816, 0x5fb42dc7, 0x407b769d,
+ 0xc39f7a81, 0x5941272e, 0xd6e5c39a, 0xed171cbc, 0x64c4b973, 0x0d95096b,
+ 0x82bd6f18, 0x2f800de1, 0xcf787a6d, 0x23e71868, 0x1a379c16, 0xc3c577f0,
+ 0x0bcaf4e9, 0x991dc512, 0x826791ec, 0xb8c95cbc, 0xf93da89c, 0xfc2279bc,
+ 0xc56eb2b9, 0x5707f40c, 0x3ae74d05, 0xf18e0f85, 0xf9ac75d8, 0xea186973,
+ 0xa273fd57, 0xf3d62704, 0x49d61adf, 0x35b6a372, 0xdaebfbf6, 0xe467cff4,
+ 0x0c2e53d8, 0x2e431861, 0x2bb10c01, 0x067ca675, 0x03615c4b, 0x96f582fe,
+ 0xbcd037ef, 0x82926c57, 0x79779816, 0x3e2f1e3f, 0x37fd87ef, 0x0a03bad3,
+ 0x73762bc0, 0x1982b3bd, 0xf3f85682, 0x29ebfd96, 0xc84c797e, 0xe606c599,
+ 0x20fefa45, 0x3f42cd4e, 0x71e3f97f, 0x4f15df84, 0x47b7faac, 0x2dcebde0,
+ 0xfd225333, 0x174825ea, 0x9accbf1c, 0x87cfd3dc, 0x859fbe5b, 0x63fe5ff4,
+ 0x3d618ff0, 0x2fd8922b, 0xbf71b816, 0xb65cb232, 0xb62b769e, 0xdbcf9fde,
+ 0x7e0d7f81, 0x2407e2f4, 0xd17b075a, 0x78107a42, 0xdbc4895d, 0x669386d2,
+ 0x5bff1173, 0xdafb0a71, 0x39bc7285, 0xe7fbc12c, 0x11b25ea0, 0x119d02fe,
+ 0xb03bf271, 0x23920caf, 0x8d5f5c3e, 0x6cc770d1, 0x8ccba7ea, 0x8733bd7c,
+ 0x441b43c7, 0xbd4b38b9, 0x0fcfe29d, 0x6eadd45a, 0x4a348fde, 0xbbfc03cc,
+ 0x3978635a, 0x2fd981c6, 0x5957142d, 0x89e710d7, 0xe23f9073, 0x5dfa0e79,
+ 0x9cd93327, 0xfa72fd8c, 0x72e2e35b, 0x2bbf9e03, 0x3b5af3c3, 0x49b58b97,
+ 0x97ae6f80, 0xffe8463d, 0x872bfc33, 0xac3197f7, 0xf1eefde7, 0x85f53d0d,
+ 0xfd5f10c3, 0x3ce355e6, 0xdf112e7e, 0x2c1e3202, 0xe7eefb43, 0xabf408d2,
+ 0x6c703f17, 0xbbd9ca0a, 0xf0562d9e, 0xf8bfc5d5, 0xbb89e91d, 0xa2773ec4,
+ 0x037a8f9d, 0x7ca167e0, 0x45cb8732, 0x42e3c49f, 0x687c0a4f, 0xd7d5adfb,
+ 0xf1e2603e, 0x28e79079, 0xfcb76a40, 0xb5adfa9e, 0x67289d87, 0x8d345f6b,
+ 0x94fc7942, 0x2d92ff98, 0x0bbfc703, 0x94c4b3f4, 0x5a5ea0a8, 0x46699813,
+ 0x818b4d78, 0x52f79ee0, 0x3f1e90b3, 0x81c9786e, 0x5c41f274, 0x4ff50f28,
+ 0xf538fad7, 0xe1402e20, 0x1b8fb971, 0xfc620ef2, 0xb612a966, 0xe97ea01b,
+ 0x94649cc6, 0x212befd3, 0xdfbfd633, 0xec2236ea, 0x08f19451, 0x04e1e47b,
+ 0xab220c7f, 0xca0fd055, 0xbe06b599, 0x399e6b9f, 0xf186ce66, 0xfdc3937e,
+ 0xfe7e4f9b, 0xf38c7cbb, 0xf38566d4, 0x7ec07f51, 0x3c400fe7, 0xfd206d3f,
+ 0xc919f6bb, 0x67ac3713, 0x7ee2d7bf, 0x16ad7f03, 0x85f6bcfb, 0xba45ee97,
+ 0x5dfb8b5f, 0x805e9bd2, 0xf3d38f6e, 0x614c0ee7, 0x48e3fdfc, 0x02be9a17,
+ 0x8c94c1b8, 0x9f0e3a71, 0x02fce1ce, 0xf3f82bcf, 0x4bc91140, 0x67682390,
+ 0x5f7bd346, 0xd8b1fbfb, 0x2c5b25bf, 0x163f5724, 0xc0f9dbfb, 0xbfdc0e8b,
+ 0xec7e7e4f, 0xd4a39e04, 0xd8da073e, 0x05ee8315, 0xfae1d63e, 0xb27f341d,
+ 0x7ae1d623, 0xefeb3d1d, 0x6fc173a6, 0x9f5f18eb, 0xb275deb6, 0x2f56bf58,
+ 0xd62cbfde, 0x7c0986b9, 0xf38830bd, 0xe427e097, 0xb4c7b457, 0xf992f9f5,
+ 0x267d1afb, 0xffb972e7, 0x99ff2137, 0xfc40ead2, 0x9ca2fee0, 0x98f1fa01,
+ 0x01b90947, 0x16793e4d, 0x5fb11fe6, 0x73b3fcda, 0xae403cf9, 0x7b929279,
+ 0xc8d3b1f6, 0xb73ac656, 0x78e5c84c, 0x9698db3c, 0xfbf806d5, 0x892bfc18,
+ 0x23957a71, 0x46e8d3c6, 0x67fcaf1b, 0xdd70d355, 0xfb087fd0, 0x3f7dc6d7,
+ 0x3f632090, 0x1fce33ef, 0xbe35fcda, 0x345faf2c, 0xed81d8ad, 0x14e7b13e,
+ 0xdd39bae1, 0x542ae766, 0x802ed07a, 0x066d3df7, 0x159f4f8a, 0xc6d9fcfe,
+ 0x8a4b1c97, 0x25dde87a, 0xd93f8de6, 0x1a9e7bd9, 0x33d045fd, 0xfb7cb3cd,
+ 0x6b0869fc, 0x4ba68df3, 0x7d1a6f0d, 0x64a9cdb2, 0xe9d344af, 0x66b3ccba,
+ 0xb9fa2f1c, 0x807cb766, 0xffe415f1, 0xf2e3c654, 0x6e78ec0d, 0x9f863e84,
+ 0xd1ea8d8d, 0xd79c9a0f, 0x14baf3f4, 0x2fc225cf, 0x43703a0b, 0x5366e736,
+ 0xc72977bf, 0xfde039b7, 0x74c3e731, 0x87d9abfe, 0x92117f37, 0xf48e3112,
+ 0x5224bb82, 0x7cb9adcf, 0x96b6e89c, 0xbfa1b785, 0xdf81f8b3, 0xf48d1ccd,
+ 0xce8994f9, 0x4e37165b, 0xbddda336, 0xa39df0ea, 0x35cfdf70, 0xa9763d71,
+ 0x6893e461, 0x7a6b9f37, 0x116779d8, 0x653e57be, 0xbc5f3c2c, 0xf5f698ab,
+ 0x4cf0b883, 0x91eebb84, 0x6f7841d8, 0x9b91e1dc, 0xce3c0217, 0xae12537e,
+ 0x5243fdef, 0x3a08d8c5, 0xcd94ca58, 0x934ed10b, 0x8be41513, 0xab3c85f7,
+ 0x5a7df137, 0x517fe82e, 0x45f3e72e, 0xebcb7f62, 0x7cf1f3eb, 0xc800ebbc,
+ 0x8d63c051, 0xc21ad5d9, 0x234d5f71, 0xd81d7fbb, 0x74c9e908, 0xd2764d4e,
+ 0x66b3334a, 0x6b73d094, 0x693f3c06, 0xeb83df0a, 0xbd8f7939, 0x58e20b78,
+ 0x096a3eba, 0x5f896fb7, 0xf1a5aec0, 0x3168edbb, 0x2e82658f, 0xded3fba3,
+ 0x1ebb40ef, 0xff989ee5, 0xe6a786a5, 0x74babea1, 0xd7192f24, 0x71abe1ff,
+ 0x7cdf684d, 0x4c72e268, 0xaeec1feb, 0x11f691f3, 0x183a5bd8, 0x0c1d2aec,
+ 0x6f5e75f4, 0xbc256d8f, 0xb7ab9bdc, 0xad3a34ab, 0x18979f59, 0xcbd01799,
+ 0x0a43fefe, 0x9cf7ff9d, 0x644e8cbf, 0x7742e431, 0x880fd5dc, 0x3c6c67ca,
+ 0xcf18fada, 0xf9f2f84d, 0x2ddfda30, 0xeb02c516, 0x8e748f3c, 0x4a2f4be7,
+ 0x72b7eedc, 0xe2ff3fba, 0x77fa2088, 0xe1c0ffcb, 0x2086ade5, 0xdf1edd1e,
+ 0xf6c25db5, 0x4beec0cb, 0xb3d84433, 0x03cd77bb, 0x545767f2, 0x680cb6df,
+ 0xcf08e57f, 0x5b6a8077, 0x227b1d94, 0x1db7d5c3, 0x5fb6cffb, 0x61c0b8b5,
+ 0x532adf0d, 0x9e1adf11, 0x75e67f35, 0x92b287a0, 0xea7dbc1e, 0xebf6495f,
+ 0xca8fbf65, 0x1f670ccf, 0x6c74871c, 0x5f91544f, 0xb0f6dd7e, 0xfbf70034,
+ 0xe8ebe285, 0x25b58e97, 0x9fb7c82a, 0xb9d137fa, 0x1d7f65e6, 0x6b7eda95,
+ 0x5f9bb171, 0x3ef7a768, 0xcaf11b6d, 0x35ef7838, 0xd790a25b, 0x35f731c9,
+ 0xeee3bf3a, 0xf0d3a3f5, 0x8faeb6b9, 0xabfbe3ee, 0x23a3fbcd, 0x5d703a77,
+ 0x7bf58fed, 0x6bee0c65, 0xf682a242, 0xdf910ad9, 0x971f6171, 0x89ad170f,
+ 0xfd80ce4f, 0x8e7fb8bd, 0x5c9c8193, 0x1e773ed6, 0xaafe5f3e, 0x5cfb4141,
+ 0x81cab57d, 0xcb3f8df1, 0x4b050e9d, 0xf3842f78, 0xca128391, 0x6c95b1a3,
+ 0x1b1fb60e, 0xfa0b9992, 0xd3833319, 0x72cb98c9, 0x3e780f10, 0xb714e786,
+ 0x714f1eb8, 0xc3f5f80b, 0xbf658dfc, 0x0d0ef1e2, 0x35df9aef, 0x04dbac4e,
+ 0x2e7447ec, 0xf197979e, 0x7fee1fe7, 0x77f6167e, 0xc14990e9, 0xc87a7f79,
+ 0x06affd44, 0xe308c97f, 0xfdc23c5d, 0xdce38410, 0xdfdcc7c8, 0xfdcadd58,
+ 0x26f5da8d, 0x37b1398f, 0xb447963d, 0x9e0ebf43, 0x55dc70b9, 0x3a34de82,
+ 0xebe1ed5d, 0x0d7a0d5b, 0xb74d1bd7, 0x1b75ac49, 0xe8ebe9e2, 0xedd29bf7,
+ 0x135e90df, 0xe87cb758, 0xe8bed7a6, 0xf913e044, 0xa355e91d, 0xf8fbd587,
+ 0x6b727a39, 0x3ba444f1, 0x79343e8d, 0x0ac49812, 0x9bd66f50, 0xdde60159,
+ 0x2af18c04, 0x9b2a81ca, 0x7f7284cb, 0x05674a4e, 0x1e4965a2, 0xb952a797,
+ 0xfd4463d1, 0x79216f53, 0x526f2d11, 0xdffcb8f2, 0xed074483, 0x2a14f28b,
+ 0xfc8eac4d, 0x8584ad07, 0x5cfd440c, 0x9ffc9095, 0x5372682e, 0x65b383de,
+ 0xb8d57f98, 0x54727be4, 0xede506c6, 0xe488f0e6, 0x97a82691, 0x5d9a1feb,
+ 0x9e457001, 0x445e6067, 0xa70e97bf, 0xc0f5c40d, 0x8c1e5773, 0x97c53dbb,
+ 0xb33ae583, 0x67f7e48d, 0x9b61ae86, 0xcfed3ddc, 0xff7f6abc, 0xb81eaed7,
+ 0xd4b2c4d3, 0xcd198422, 0xcaef2b5b, 0xe3e60cf3, 0x612f9fe8, 0xe2f291ac,
+ 0x5dfbff02, 0xe7e043b4, 0xdefec2b5, 0x8969e82a, 0xfdc216d5, 0xcba64d64,
+ 0xa80576dd, 0xca26a67e, 0x04b30748, 0x872adc1d, 0x42fdf1da, 0xb05ca0d6,
+ 0xffb3e992, 0x3a377eab, 0x05d995a7, 0x87a03fad, 0x3eb04ccf, 0x900367a0,
+ 0x196026d7, 0x06b12003, 0x95e197e4, 0xd85ffdff, 0x75807d6f, 0x6b9e11c6,
+ 0x067b9414, 0x057e33e6, 0x63826d65, 0x3c33c618, 0x3643d92f, 0x3f0dc7d8,
+ 0x5fba204f, 0x5217ec25, 0xa65f98c6, 0x74b0f5f0, 0x8f7fde7e, 0xfd0fb7a0,
+ 0x5817372c, 0xf47613fb, 0xb1e61953, 0x1b37ce2a, 0x78c6bdf1, 0x0b836b2a,
+ 0x81deb4f9, 0xbf27c576, 0x09145490, 0xc8dd846b, 0x7e0aa50e, 0xa0134297,
+ 0x785dc3be, 0x8d4bf510, 0x6ecb97a0, 0x606f7e46, 0xfaf2858b, 0x5963f5d8,
+ 0x995c03f7, 0xfe8a8b7d, 0xb767e5e4, 0x7d832ee7, 0x0ed8c0b2, 0xe854e758,
+ 0x6aa60cb3, 0x73a25802, 0x03f520de, 0x3c0701f5, 0x387ee6df, 0xf319d38b,
+ 0xfdb47ae2, 0x6bdef0d1, 0xb468603f, 0x66568d2f, 0x90b1ff42, 0xff9057ed,
+ 0x8c997db4, 0xfff03dce, 0x9c791786, 0x75818363, 0xf9af18c3, 0x8d780ad0,
+ 0x4f6a5f21, 0x267641be, 0x27405bb0, 0x19dff657, 0x1d95ff5b, 0xffd76330,
+ 0x98d83d6c, 0x315ff427, 0x037b262b, 0xadfd0697, 0x4b266d10, 0xd7192e35,
+ 0x91556a93, 0x9e3c361e, 0x1d867a43, 0xa0f44dd9, 0xfbfb63b5, 0x736c9d11,
+ 0x55ff844b, 0xcc4cb06d, 0x4feb69d3, 0xda338b79, 0x5c74a992, 0x97e7a74b,
+ 0x94ab7c9e, 0x3fbe1bcb, 0x369a7f33, 0x7e83f289, 0x6d4a883a, 0xbd041b1e,
+ 0xe2be7869, 0xc93e7815, 0xbb06d5f5, 0x397dfc99, 0x79489850, 0x0b121d8c,
+ 0xe4f73c02, 0x57e2131c, 0x6d74e78a, 0x57323749, 0xc459bc0c, 0xe2b9c47e,
+ 0xded22b99, 0x68c2780f, 0xf517cfd7, 0x51c90509, 0xe6df7cf5, 0xb7cfe589,
+ 0xf3819cad, 0x75fdabb6, 0x4c776ce3, 0x92ba20e9, 0x5f38cb2e, 0xeb0304cb,
+ 0x352be787, 0x3b987dfa, 0xc69b0f57, 0xd5f24e7f, 0xbf7a3e34, 0x4dfd0999,
+ 0xfcff478b, 0x17a13cb5, 0xe461590a, 0x9fc2f63e, 0x0d7c4acd, 0x78ef79da,
+ 0x9875e780, 0xedc5d058, 0xafc7b435, 0xb7442c78, 0xde04e3db, 0x21e9a50c,
+ 0xa6589f68, 0x47925fc7, 0x957eaf8f, 0x7aa4fc7a, 0xab4878f5, 0x67d5d6ce,
+ 0xeaeb06f8, 0xd12cac07, 0xc6eb03c1, 0xb4dfdaea, 0x760e9269, 0xdae9a607,
+ 0xd6cd34e7, 0x0b2d79c1, 0xed07ed75, 0x2faba25b, 0xd5d6ae0c, 0x41b2390f,
+ 0xfd6d0f07, 0xe1fb5d17, 0xf5755b6d, 0xba1da1c5, 0x0f1d11fa, 0xe191e0e9,
+ 0x47ed7547, 0x57507bbf, 0x69f3a63f, 0x8bb8fd5d, 0x9be0e9cf, 0xb5d65ebb,
+ 0xa8ed709f, 0xdec89e0e, 0xb72fb5d2, 0x4f074efe, 0xd743fe56, 0x0ff496fe,
+ 0x5d53f574, 0xa7eaeb1f, 0xc1d55c17, 0x097d9877, 0xea97c8f9, 0xcdef74df,
+ 0x8e1fae62, 0x9f9e3a07, 0x00435462, 0xfc85f3db, 0x8c977410, 0xdaed13fa,
+ 0x7485965c, 0x1f1a593a, 0x336bba22, 0x4457e8a8, 0x63f927eb, 0x65e307af,
+ 0x8a8325ec, 0xb044ac71, 0xf188e4eb, 0x70563c92, 0x7ee07b00, 0x4e0e8a95,
+ 0xdaeba6f5, 0x74bb55a7, 0x02be19f5, 0x9580fd5d, 0x581e0eaa, 0x7f6ba657,
+ 0x0e8f26d3, 0x752a0776, 0xbc9a73ed, 0xa5af383a, 0xd07ed75a, 0xbeae9f3e,
+ 0x5752b830, 0x9d48e43f, 0xbada1e0e, 0x787ed749, 0x5f57405b, 0xd5d26a1c,
+ 0xd168e88f, 0xfbc323c1, 0xbf47ed74, 0x8fd5d41b, 0xaba23ce9, 0x55b1771f,
+ 0xd5dcdf07, 0xe13f6ba6, 0x4f07485a, 0xed752764, 0x7467adcb, 0x3de564f0,
+ 0xd25bfb5d, 0xa7eaeacf, 0xeae92eba, 0x7a647b35, 0xe7fae7c1, 0xa9993ec2,
+ 0xfdee97fe, 0x430f24c0, 0x673c08fa, 0xa05deb50, 0xb9b3f2ff, 0x2d13073e,
+ 0xc67b424e, 0xc945f94b, 0x7207a098, 0x2060312b, 0x5b9542ba, 0x149ef143,
+ 0x52a453d2, 0x0347985c, 0xde81de7a, 0xf68ddb93, 0x9d8f426d, 0x88d5f995,
+ 0x7d676e6f, 0x30387d1f, 0x944db65d, 0x0de563aa, 0xc79f3f7e, 0xfbe50e39,
+ 0xa2a7e436, 0x14ecf11f, 0xb157b3b4, 0xe79c36c0, 0xb128a964, 0x71a8e313,
+ 0x568538fa, 0x645eb54e, 0x77dd8472, 0xb325ae32, 0xfcfe06e4, 0x2665eb54,
+ 0x57e8888f, 0xb00c2fc4, 0xfd110dfe, 0x807e083f, 0x8b7f3e0c, 0x6c0af81f,
+ 0x0afc87a4, 0xe9fdbbc1, 0xbbf1ef04, 0x2fe7dca8, 0xbf51f2a0, 0xfdfbf54a,
+ 0xe13f0465, 0xf41c10f7, 0xd0795257, 0x87e7a5ef, 0x3f04d5fc, 0x96317e09,
+ 0xc64fc047, 0x77f069f2, 0xf019feb1, 0x85fe117f, 0xab65403f, 0x3f9e89bf,
+ 0xf8216fe7, 0x823eff05, 0x520fe97f, 0x423fe6d9, 0x56fecbe5, 0xdfc57faa,
+ 0xfe6bf046, 0x7f21c110, 0xfd47c107, 0xfb8f8261, 0x84f825df, 0x0eca93bf,
+ 0xdf2a45ff, 0xfd5177f4, 0x8235ff29, 0x6f53f67b, 0xf3e346ff, 0x65571123,
+ 0x215c4ec2, 0x70a587e8, 0x273970fb, 0xd042b605, 0xa81269ad, 0xfa3fb457,
+ 0x3cc41fe7, 0x574891d6, 0xa7574405, 0x1efd8dbe, 0x25697fed, 0x9bf719d0,
+ 0x3c781bd7, 0x22efd346, 0xefd3405f, 0x7f70f735, 0xbbd81175, 0x43ffff18,
+ 0xaf3fb71c, 0xd00a99d4, 0xc431ab8e, 0x5d2f68ab, 0xd933fba9, 0xafcf0c47,
+ 0x78ee4581, 0x476072c5, 0x0356df84, 0xfde11bef, 0x18b45999, 0x4c3ac356,
+ 0x332a2e74, 0x357c048f, 0x37efa076, 0x0f561fa8, 0x7fc80634, 0xd1f305b6,
+ 0xa07dbb6f, 0x7ef48c2f, 0x09d96ea5, 0xd2a28fc2, 0x4b4ce0b9, 0xc63e7528,
+ 0x144a4e49, 0x1f0bebdf, 0x785e44eb, 0x5daff59f, 0xbc3b44ca, 0x0f92eff2,
+ 0xc9b4e7f7, 0x83718d5e, 0x1fb9f20f, 0x51be41fa, 0xe81e5e57, 0xfcf3873b,
+ 0x76eebd8b, 0x2ff0a023, 0xe4ff59df, 0xbf1eeedd, 0x3d7456f9, 0x62ae5ec1,
+ 0x29e5132e, 0x6e1bcf32, 0xe636eae8, 0x0b3e7823, 0xa67b7950, 0xd75c63ef,
+ 0xd8241602, 0x1592d637, 0xf3d15d6b, 0x03908bfa, 0xea37c97f, 0xbe59feca,
+ 0xf2f3e4ff, 0x8f4ebcd0, 0xd71f25b9, 0x616bcda5, 0x3fe68b96, 0x813d758b,
+ 0xabcbfbf3, 0xe4305f9f, 0xff8fa6f4, 0x61b0ba01, 0x31da0598, 0xc7a8df3c,
+ 0xafa81cc4, 0xf940cfbf, 0xd45d1ad9, 0xdf104060, 0xbca06cdb, 0x013a1efd,
+ 0x2bbf40fa, 0xf1ee8ba5, 0x0f249d01, 0x23193a42, 0x4f60cc05, 0xf306369e,
+ 0xbc5e740d, 0x84718ccc, 0x1f402915, 0xc1d37dd9, 0x409f715a, 0x95f40e7b,
+ 0xfa7dfd89, 0x8805d1ab, 0x8daf75af, 0xeabe2171, 0xe80fb08d, 0xa929be27,
+ 0x8b851f3c, 0x50dc697e, 0x5932578a, 0x34ce3155, 0xde5b12d3, 0xe9c41f8e,
+ 0xa9ba74e7, 0xe9fd4832, 0x074a55cf, 0x1d2b7df1, 0xc373f7c4, 0x48d70ffa,
+ 0x47d3ef30, 0x947dd12f, 0xf4dff35e, 0xc46e6166, 0x9db5d7bc, 0x2189e29d,
+ 0xfe8be7bf, 0xcc91ba34, 0x5b01df76, 0xe9babce4, 0xfbae1c78, 0xc740492f,
+ 0x17c74439, 0x9670fcf0, 0x1f3895c5, 0x09404eca, 0x1fbee9da, 0x2dffe42b,
+ 0x4b952a61, 0x15ca9799, 0xb748edb0, 0x332ec0de, 0x6b357be2, 0xcb6be7a5,
+ 0x1d2274ee, 0xc8fa372f, 0x99835e2f, 0xcb9e78b7, 0x01d22aba, 0x6d35b76f,
+ 0xd01d2379, 0xd765a737, 0xcecf8c64, 0x037e2e0e, 0x8643aacb, 0x0a87980b,
+ 0xe70b317c, 0x6ba869d5, 0x2fe30fec, 0xe362667c, 0x4b3e7800, 0xdec1fbe2,
+ 0xc9a1fbe2, 0x0375e88d, 0x941bcc1f, 0xd0f2eb8a, 0xa54724ba, 0xb66a0f8e,
+ 0xa5218f32, 0x9bbe1f27, 0xfaeeca2f, 0x5f9400d3, 0x07c51772, 0x4966bdd6,
+ 0xcd5e7dc6, 0xf0603db8, 0xcd0ff168, 0xe744600e, 0x1578b177, 0xe8247ddb,
+ 0x8c81a3fa, 0x0323fae8, 0x3d258438, 0xf2cb29f6, 0xf4e497a5, 0xc675ebe8,
+ 0x9e218667, 0xe2d79f40, 0xd07f577c, 0x8dd8adba, 0x85983f72, 0x69e989f6,
+ 0xd6ef5a8b, 0x55f615e9, 0xeb5c4f42, 0x3b8f1341, 0x50cbcf45, 0xd0bfe276,
+ 0x5998b11e, 0x8039cf00, 0xe428d9af, 0xe266fee7, 0x2d447aab, 0x7926c7c6,
+ 0x557cfc5d, 0x3169ffdf, 0xb92f8edf, 0xf5801c3f, 0xf7a49c60, 0x594f5c38,
+ 0x21c67be2, 0x3464e1b9, 0x9c41cece, 0x98f1b57f, 0xed1333ad, 0x7de3fbf7,
+ 0xd5fdc03f, 0x3f9a3de2, 0x30fee1d9, 0x8d99ee97, 0xf74354bd, 0xe858c637,
+ 0x22addf7e, 0x196b760e, 0xaadd838f, 0x47c6bdc5, 0xe2a2bdc5, 0xec7c6c2f,
+ 0x97269838, 0xefc95319, 0xd07f642d, 0x17f14fd6, 0xd2f60e4d, 0x3090b0ab,
+ 0x145da5c5, 0xcb8ee8af, 0x1e799b14, 0xad306b8d, 0xe4e42cc7, 0x4f972f4e,
+ 0xd569fbda, 0xfce8c2e0, 0xd5cb2b08, 0x0e8a11f9, 0xae97581e, 0x26d37f6b,
+ 0x1ddeae97, 0xe7d5d028, 0x383aa934, 0xd74ca5af, 0x8f3ed07e, 0x560c2e0e,
+ 0x390fdaea, 0x43c1d5e2, 0xed75ab5b, 0x74f9b787, 0x95a1c5f5, 0x1d11faba,
+ 0x64783a75, 0xfdae9378, 0xba0377e8, 0x4d9d31fa, 0x1771faba, 0xcdf0745b,
+ 0xed74fb5d, 0xea0b5c27, 0xa7b227ea, 0xd6e5f574, 0x64f07567, 0xf6ba57e5,
+ 0x74fd0b8f, 0xeebb7a4b, 0x49d754f9, 0x0bd37bdd, 0xc7e0e8ce, 0x0f919f71,
+ 0x0f899816, 0xe9efaa66, 0x10f267de, 0xe39b938a, 0x1dfdb3f8, 0x3ca3146f,
+ 0x170c6fdc, 0x6e3e9f23, 0xf96374ec, 0xb5b5c184, 0xce49d01f, 0xd61489f8,
+ 0xbc58abce, 0x3341cb15, 0x5d5318b6, 0x0f731fb0, 0x393d456c, 0xe8dda6a4,
+ 0xd2e87804, 0x889d5bb3, 0x290635f7, 0xd1bdf10d, 0x88e58f5d, 0x74a513cd,
+ 0xb0d91fa8, 0xe8e51eb8, 0x8b33e6e8, 0x007496d1, 0xfe3187cf, 0x3e887b25,
+ 0x69186637, 0xc6471bde, 0xcedcde53, 0x9d1936b1, 0x9c3b9d96, 0xdc0f180d,
+ 0x09a4a3b9, 0xbf606dcb, 0x358ccd07, 0xe58efd81, 0x83dfb00e, 0x3c6c8be0,
+ 0xe424e7f3, 0x53a6e547, 0xbf2e78e9, 0xaa47d27d, 0x4a15c551, 0xbf438f73,
+ 0x22f1a9cd, 0x3b9a515f, 0x4efb7411, 0xdf8049e4, 0x1730923f, 0xe1a370f3,
+ 0xad788717, 0x72f7c805, 0xbaed1b8b, 0xac06fd5e, 0xfe017efa, 0x927afd66,
+ 0x1e785fb1, 0xad216f33, 0xf7e1eb80, 0xde5a8c0b, 0x715be53a, 0xb04a1c53,
+ 0x9e41123f, 0xf0e98f35, 0xcabc00ad, 0xee819d4a, 0x26fb8b09, 0xf8a6aa18,
+ 0x26aff5ee, 0x2e9c03c4, 0xe451dbde, 0xfe802bcb, 0x9ca0606c, 0xf497a08b,
+ 0xd04700a5, 0xefc05ec7, 0xf99edcb9, 0x0630ee98, 0xa60b9064, 0x1555789f,
+ 0x516c79c6, 0x7b97393c, 0x223b7acd, 0xdc8de44f, 0xf7146057, 0x68a8e65f,
+ 0xc057dcff, 0xfe23dcf5, 0xe7cff38b, 0xf35dff62, 0x329e03cf, 0x0f988696,
+ 0xf54d99e4, 0x611a98aa, 0xb17567aa, 0xf19bc8fc, 0x6fbc0612, 0xee92763a,
+ 0x702aafaf, 0xd4325e11, 0xff775a16, 0x646fd0a5, 0x33ae4d9c, 0xda403e60,
+ 0xce033ae6, 0xaaf14d2f, 0xacc78e78, 0xbcfddd4e, 0x997f4db4, 0xa7e41e7f,
+ 0xb155efc9, 0x46ba699d, 0x222b218f, 0x925aaafb, 0x47cc62c8, 0xfc9d6d2b,
+ 0x7aafa8fc, 0x759bc947, 0x625a3794, 0xd111e173, 0xeab6c5e3, 0x7bf63103,
+ 0x66efd895, 0x9b7c7e87, 0xe4203e76, 0x718555f4, 0xf7f8213d, 0x6b0e24ee,
+ 0x5c5ddcfd, 0xf9c37692, 0xce7463ee, 0x30cdc1a9, 0xf9a9e20e, 0xd715bb7a,
+ 0x0b798cdf, 0xe9182fa4, 0x547e2789, 0xa1876070, 0xa2f63ef7, 0xc4fca047,
+ 0xce8fa412, 0x83f03d60, 0xa2acd8bd, 0xdefb645d, 0xdeea0372, 0x89475674,
+ 0x1591b637, 0x1bb0f21d, 0x4f5aafcc, 0x3d3e6987, 0x97d9329d, 0x62faf941,
+ 0x1c3d351f, 0xafa66fbd, 0xc872d272, 0xd979e2ee, 0x67fe4e1b, 0xef022f9c,
+ 0x557c123f, 0xe4245ac6, 0x95acb193, 0x4c2cf1ca, 0x175877e5, 0xc8a61e95,
+ 0x2a624e58, 0x4bcc1595, 0x475614e5, 0xa16b2565, 0xa56b1a72, 0x530b0672,
+ 0x950afe09, 0x5f90a65e, 0x36f41b35, 0x97997396, 0x8eac79ca, 0x1d229fca,
+ 0x59ab3e03, 0x590bc10b, 0xc06d952b, 0xfaa5787f, 0x586f9065, 0x0df202be,
+ 0xe9fcd7cb, 0x2efc8654, 0xbf47cae6, 0xe3ca80bf, 0x13ca957e, 0x3b2a32fe,
+ 0xf76a1efc, 0xca92bfa6, 0x952f7e53, 0x54d5fda7, 0x6a3efd86, 0x257fb6f7,
+ 0xebf8ef95, 0xff37fca8, 0xf5df2a26, 0x77fca807, 0x7995137f, 0x39764666,
+ 0xcf15082b, 0x7e67fc06, 0x60b8f660, 0x3c0aaf1f, 0x5318f31e, 0xff70530b,
+ 0x4df18664, 0x2231c55b, 0x48cb9b0a, 0x5c9addf7, 0x289dd947, 0x3b734f07,
+ 0x27669ecd, 0x72d6d03b, 0x613e619c, 0x4a53a19b, 0x793cbd80, 0xd6b98ee4,
+ 0xaf93d042, 0x150486b0, 0xadbba5e1, 0x309e07a0, 0x027eeb85, 0x960bc7f5,
+ 0xce82b5cc, 0xfb7f6b1a, 0x4c39a7e3, 0xb38e63f5, 0xdfe0057a, 0x1bb1591e,
+ 0x3ce130af, 0x57bede50, 0xe62e7ab0, 0xf2155feb, 0x00c37c02, 0xb7ad2de5,
+ 0xb16f3105, 0x3168e5b8, 0x7531b62a, 0x37d412b6, 0x1e28ed11, 0xe8bb57d0,
+ 0xc7bded7a, 0xe2129d6a, 0x64cff9a1, 0x9cccb37e, 0x9dc63150, 0x7e35fb22,
+ 0x7499f1b3, 0xdb23f183, 0xdfd06e19, 0x9fcf228e, 0xfffccf50, 0xfa68f3a6,
+ 0xec757d36, 0x062efa59, 0x7e438aeb, 0xe5c4983e, 0xa5d8174d, 0x0b34dfe8,
+ 0x364b79b8, 0xb507a9d9, 0xcbefb37c, 0x5e307f54, 0xf081d2bd, 0x378a5c96,
+ 0xe2792734, 0x637db10b, 0xcc9dc936, 0x63794604, 0x8a13d53b, 0xe3ef822b,
+ 0xb2fcb90b, 0x7285fcdd, 0xefe5ca27, 0xae8f0ccb, 0x3bfefa6f, 0xde00b71d,
+ 0x05468d5c, 0xe6f12df7, 0x7e512a77, 0xa3cb3704, 0x18e32124, 0x12792fd5,
+ 0xaa9da6fd, 0xf61f3e39, 0x0ea200f5, 0x1b26aced, 0xfd9959d9, 0xc377c542,
+ 0xcf328d78, 0x6f968aff, 0x9cb90bb3, 0xc34bda37, 0xc0b76e74, 0x4478c2ea,
+ 0xd9b0f25f, 0xf3c2caef, 0x6fbc6764, 0x287e0331, 0x4a676a7c, 0xa7732823,
+ 0xa313db83, 0xf6483a9f, 0x27c8b344, 0xd2314c6d, 0x256c49f7, 0x445203ce,
+ 0xc87336bf, 0x36f8e785, 0xb163e0a3, 0x3207e69e, 0xf7b75f29, 0xefba5d3c,
+ 0x9855d915, 0x6e1c8447, 0xee817116, 0x3ff446f1, 0xcdc44520, 0x4a90966c,
+ 0x4bfa69e3, 0x3fc76f1b, 0x914ede36, 0x678da927, 0x9f5fa51f, 0xf5a61cdd,
+ 0xa1fd85d9, 0xd713b78d, 0xe30f2317, 0xf5c3c76b, 0x5a378e45, 0x25bb3ebf,
+ 0x4bb3eb4c, 0x1ee95edc, 0xf1ec476f, 0x4f671afa, 0x569cfe54, 0x72e42fce,
+ 0x7632cc15, 0xd33ff60e, 0x09f9e9c2, 0xd9c5d313, 0x7e7a0937, 0xa69788b2,
+ 0x992e5c09, 0xcfba669c, 0x7179d133, 0x6db5d217, 0x9dce91b7, 0xc827296c,
+ 0x4ed3927e, 0x40fc8931, 0x9fcf8ad6, 0x02f7f030, 0x7998e6a9, 0xe1fc7b2b,
+ 0x7111b9f9, 0xceb534e3, 0x134ff980, 0xe30c1d9d, 0x3314b6ec, 0x6296dfad,
+ 0xfca1c60d, 0xcd809955, 0xdb8004c1, 0x0b1b7c8b, 0x954e3d61, 0xc5338bf3,
+ 0x92f3007c, 0xdfa1aad2, 0x84ff7d08, 0x772663a0, 0xee22abba, 0xc45b3cd7,
+ 0xaf8d49ed, 0x7237e7a3, 0x41ff5f30, 0x4f31e7f0, 0x8f0c6ba7, 0xdc3e9c93,
+ 0x5987fc9f, 0xd07bc60f, 0xc0fd3e8f, 0x77820ae0, 0xf5f3a58c, 0x4ec787d3,
+ 0xd6627f41, 0x8246698e, 0xe303ac0d, 0x2c76b31f, 0xccf3e234, 0xdffb461c,
+ 0xf24cd675, 0xd58ed675, 0x4cbffda2, 0xc665f6c1, 0x6e30cfc0, 0x91ef7650,
+ 0x8c8b8c04, 0x00373fb5, 0xcec6d3cb, 0xa07df88d, 0x1bf6155b, 0x5bbcd734,
+ 0xb228ed92, 0x36c81eab, 0x44f59fa1, 0x99bf3f21, 0x9e263cc3, 0xbf25e187,
+ 0xf091fc7e, 0xfbb2bc31, 0x72aed69d, 0xb4f6c63c, 0x9cb1c729, 0xdaf15214,
+ 0xf0e8ab32, 0x4a72c71e, 0xcd02aeb8, 0x5b77cad9, 0x3159638e, 0xe204f7dc,
+ 0x46f7f0f7, 0xc614fc95, 0x6e6fbac9, 0xd93bda3c, 0x0f27435b, 0x44d65c50,
+ 0x94f6c2f7, 0x18249b79, 0x6bcb8f6f, 0x27b43d45, 0xf248db25, 0x256ea935,
+ 0x3c6073ad, 0x51ee75c3, 0x45c9717c, 0xbec97724, 0x11ec137f, 0xe7eeffdc,
+ 0x33f9fcf1, 0x151afe82, 0xf88935af, 0x027ca140, 0x9acbb09b, 0x151d2799,
+ 0x04f76ca1, 0xc7b72e31, 0xc078e5c3, 0x6c52fdc6, 0x58ec0dbe, 0xec6992ba,
+ 0x95594fd9, 0x60c779f5, 0xb2bf60de, 0x10b28768, 0xa6bc5fed, 0x0fe8308a,
+ 0xc61d5dfe, 0xe6dda1f5, 0x36be38a4, 0xfa14b97f, 0x9c33a08b, 0xcf5b6cff,
+ 0x67b8da7b, 0x237e7ac4, 0x1f1ef4e4, 0xef9b4fef, 0x463728db, 0x465dbcd2,
+ 0xe6248f9c, 0x4630eb03, 0x1da227cc, 0xde7bafad, 0xf7e74d4c, 0xdf8c3d4d,
+ 0x392e6543, 0x8b0efd62, 0x1e912ad7, 0xbf482a34, 0xf948d576, 0x2fdb76fc,
+ 0x7a3f0f29, 0x790a171d, 0x7287eabc, 0x365fa188, 0xe430f54d, 0x1e2a1fcb,
+ 0x0164abb2, 0x0edc29cb, 0x624fc793, 0xcaf588a6, 0xdda89329, 0xf18f6834,
+ 0x096569c5, 0x74ebd22a, 0x70a0dad6, 0x2e78e03f, 0x318f2fcc, 0x2cb75e5d,
+ 0x9faac7e0, 0xf0bb72ab, 0x7b4b592a, 0xf745da01, 0x9dbca72c, 0x3ad30d86,
+ 0x05e9be70, 0xa193dbeb, 0xdf39fbde, 0xe3cc5677, 0xcb760372, 0x8cdfbcba,
+ 0x9e470095, 0x30f4fb5f, 0xbdae83d0, 0x43365746, 0x847682a5, 0xaefae131,
+ 0xecbf983c, 0x2c1bfae0, 0x4637365c, 0x5d17ba3c, 0xfb6bfc09, 0x4b9c1f63,
+ 0x1c6d94f8, 0xb54bacef, 0x89f7c6de, 0x84fe8de8, 0x6d81eaf1, 0xbebd1f31,
+ 0x7de20a42, 0x7b777b4a, 0x1afb8a96, 0x96d94fbd, 0xb8795dae, 0xca4675fe,
+ 0x2bc68f0f, 0xb9b711d8, 0xa4d6ce91, 0xa73c3d50, 0xe8cc6f7c, 0x8a47eee9,
+ 0xe3f7eb05, 0xca3fdaeb, 0xbe78bb82, 0x7a79fea9, 0x059bc94a, 0x500714a5,
+ 0xebeb36f9, 0xf7ea36f3, 0x283a6315, 0x1654d3c7, 0xfdbfb90c, 0x394b4e7e,
+ 0xbd6cc158, 0xbba355f7, 0xe5b17ecc, 0xce421bfc, 0xd3282667, 0xa7ce500a,
+ 0xf3fec91a, 0x23531aa6, 0x8329defd, 0xf09cfeb9, 0x37e48d92, 0xf74ac0fb,
+ 0x3850d4d6, 0x49c4ed01, 0x3ec9185f, 0xd1d4e37f, 0x3941a787, 0x9b4b37f9,
+ 0x0ce4ddb0, 0x86ed0e78, 0xc47d74be, 0x84b7649d, 0x5f5f910b, 0xed93a166,
+ 0x4c3b1fa8, 0x2da7bdf4, 0x26536c9f, 0x4cabfee1, 0x6d29dcc5, 0xdc6215dc,
+ 0x5e029b5f, 0x996ea792, 0x51e7e41d, 0xf6d2bfd7, 0x2865c789, 0xf036577f,
+ 0xbad57bb5, 0x9997d23a, 0xf142cc45, 0xd22af0ee, 0x19e31bc7, 0xa56ccbf2,
+ 0xcf08bbf5, 0x4664ecbe, 0xeab66fe8, 0xf3c62d32, 0xce676119, 0x44d35451,
+ 0x3f95552c, 0x73e7f2b7, 0x9f3d0f15, 0x73f87aab, 0x6feff71b, 0x3f610253,
+ 0x2d9b77f4, 0xddfd85d9, 0xfd797aa6, 0x9fd50b35, 0x172fff02, 0x171ac158,
+ 0xb7ae5050, 0xf3f2345c, 0xd13c5f2f, 0xa4ada37b, 0x2bf385c3, 0x36fdd235,
+ 0x3ee893b0, 0x4bc54ef2, 0x32f791f7, 0xf822065f, 0x64d9d2e5, 0x629cbf47,
+ 0x2f4b7ba4, 0xbf0c8c7b, 0x91a81403, 0x41423df9, 0x67572f47, 0x3654f9d2,
+ 0xebf71322, 0x43b256bb, 0x0fa0f11a, 0xe7f757db, 0xf6e642fa, 0x2951bec3,
+ 0x6161ded4, 0x074895c9, 0x3bca6587, 0x1e78e1ff, 0x650f943f, 0x735ed107,
+ 0x5df9e8d6, 0xe9c49d2e, 0xf20a6541, 0x25550cc1, 0xcddfafba, 0xf88ba354,
+ 0x7d87de9e, 0x2cee75a5, 0x1fa2bb7d, 0x55546bc2, 0x93a18ce2, 0x6fa5f517,
+ 0x8cf83c73, 0xb3be4794, 0x9befbc54, 0xd7c70874, 0xe0b07cf8, 0xf4ae4d4f,
+ 0xf52a4396, 0xa49a4f63, 0x306800ee, 0xbffc800c, 0x51cf0ccf, 0x74cb242e,
+ 0xa9706adf, 0xf586521c, 0xe8867df0, 0x4fe0b077, 0xcf9e88f9, 0xe1e90ef2,
+ 0xeeff0447, 0x1fb92163, 0xe8c2dbf6, 0x8b406a5c, 0x3e781dbe, 0xd1639406,
+ 0x22abfc7c, 0xd48f1683, 0x9e17a1e1, 0xd9d7b17d, 0x5c40aeb3, 0xc8cbad3e,
+ 0x5de425d7, 0x3d2b6dae, 0xd56455cf, 0x2d62f385, 0x07fae36f, 0x40c1921c,
+ 0x352afd85, 0x7801cece, 0x71264046, 0x49859337, 0xbadd7c5e, 0x2b5c451b,
+ 0xebd19d7a, 0x44b065bb, 0xf1cccbeb, 0xca6ec979, 0x326ec990, 0x18c2006d,
+ 0xbdb0d78e, 0xa3716e3b, 0xd4fb3b3d, 0xe6439060, 0x182b567b, 0xe4233e0f,
+ 0x892be992, 0x56fdd7d3, 0xda5357a2, 0xfbc8828c, 0x4f86972a, 0xf318333a,
+ 0x7ababfbd, 0x4f8f1072, 0xe5a3fe11, 0x7f455fdc, 0xf9f53a63, 0xc62ee386,
+ 0xe9c7e547, 0x5c270df3, 0x1f951feb, 0x1f951397, 0x3f574437, 0x95111959,
+ 0x2a2e371f, 0x075cae3f, 0xae982f4f, 0x9d533f6b, 0x2d6f83a3, 0x7daeaefb,
+ 0x5d4ee795, 0xbbca9cfd, 0x79b7f574, 0xf3c1d6ef, 0xb5d7efab, 0xd7abe05f,
+ 0xe5777fd5, 0x20f5740f, 0x8bc6622f, 0xf74a3c31, 0x613dd386, 0x3016a0fa,
+ 0x3d8637bc, 0x57722920, 0xf471fea4, 0x1e4c5fe1, 0x71e3f7c2, 0x3b093fcd,
+ 0xc4591c78, 0x838b595f, 0x7c5ab1e2, 0x9a763436, 0xb722fd15, 0xbd434d45,
+ 0xf5cb7ece, 0x74380b06, 0xdf89cb71, 0x1b76a4ab, 0xfce9b292, 0xb3b051e3,
+ 0xef30f97d, 0xe927cf20, 0x1c6b001f, 0x500ddbe3, 0xd7febb42, 0x2237cccc,
+ 0x9e2c1e62, 0x3cb585c7, 0xe64f3107, 0x8bf3e049, 0x61f7cfe3, 0xfd1f313c,
+ 0x0f952b38, 0x4173b53a, 0xf6bf6195, 0xf2807332, 0xed834b11, 0x036f9866,
+ 0xc51447c8, 0xc74e5e12, 0xbd4db838, 0x7aaa3de1, 0xb3dd3a7f, 0x050d2db1,
+ 0x3aa5d04c, 0x3d1fd1e4, 0x7cdbef02, 0xe314e28c, 0x11ffec87, 0x433ce1c6,
+ 0xbb3f345c, 0xf7bcf1cc, 0x74b97ff6, 0x9265e518, 0x45f5ee93, 0xb1dda7d7,
+ 0x6e37f3f9, 0xd177bf50, 0x765bdef7, 0xdf6ff7a3, 0xa231b674, 0xcbf9afbe,
+ 0x13ccfeb6, 0x66590741, 0xad55fdfd, 0xfae10ef4, 0x3358dd7d, 0x49272fc5,
+ 0x604399be, 0xfec6cfbc, 0xe1db7bf5, 0xbe2b4fbd, 0x3bfd1db8, 0xe7c5ee78,
+ 0xfaf08ed0, 0x2c95e669, 0x04399e7c, 0xb3d47fec, 0xbe662c71, 0xadd05f9c,
+ 0x45d3569c, 0x99aa79fe, 0x6b4e43e2, 0xb0f3fce7, 0xf1516def, 0xcbf46682,
+ 0x447baf01, 0x8f8b447c, 0x59fa2ddf, 0xe9494a21, 0x660e73a4, 0x527dd00d,
+ 0xc5ec5ecd, 0x86328e0f, 0x936ca37e, 0xc5ca442f, 0xc53354f6, 0x4cc52407,
+ 0x3292e779, 0x2823be8a, 0xe78fa381, 0x985b7637, 0xd4f68cfc, 0x900f1451,
+ 0xce286342, 0xa885b360, 0x2fb6bf3f, 0x77dfdeaa, 0xbcd3cf5a, 0x759feefa,
+ 0xc7704f3f, 0x1e6a2718, 0x47d61e38, 0xccc0738f, 0xdcb9dfb8, 0xf1be331a,
+ 0x0d8990e2, 0x5f915243, 0x82dd773b, 0xd8bbfafc, 0x312b5972, 0x81183e8f,
+ 0x6486879f, 0xfe605d13, 0x5c62307c, 0x848f97cc, 0xdee80281, 0x6aa0c104,
+ 0x71425a06, 0xa13c7083, 0x6acd9a07, 0xa087d93a, 0xf71f70fe, 0x0a7e7e09,
+ 0x51fc8d68, 0x03ef87e1, 0x51f2c63e, 0xda7642bf, 0x843fe07e, 0xa8bbf09f,
+ 0xa80bfa0c, 0xa957e83c, 0x8cbf90fe, 0x1efd27e0, 0x2bf88f82, 0xefda7ca9,
+ 0xf8cfe7a5, 0x85fe09ab, 0xab6547df, 0x7f3d257f, 0xf0475fce, 0x044dfe0b,
+ 0x42ed12ff, 0x9a27cf19, 0xdfd97ca8, 0xf8aff542, 0x9afc11f7, 0xc865483f,
+ 0x1f9e847f, 0x7c12b7f5, 0xf046dfdc, 0xe0887f09, 0x95077f0e, 0xf4c3fa6f,
+ 0x5dff94fc, 0x2758afde, 0xfc672278, 0x45b49780, 0x79da1746, 0xcc968b69,
+ 0x6f7800ae, 0x6df74cb5, 0x4be40b9d, 0x1e2e8007, 0xf7f26555, 0x5234aef6,
+ 0x2bb347dc, 0x486cd6f7, 0xb9faa72a, 0x1592df54, 0xbed9764f, 0x77ba66a5,
+ 0xedc55b6d, 0x46ccb659, 0x32c56ded, 0x72ba3fd5, 0xcd8dd92e, 0xae300538,
+ 0x07818c32, 0x25bb6326, 0xfbdf9246, 0xefbae2a2, 0x6f79fd89, 0x45efcc88,
+ 0x2253891d, 0x5b6b21cf, 0xbaf07493, 0x7ce50cb6, 0x25dcdd04, 0x989b61c6,
+ 0xc49df91c, 0x33bdf64f, 0x79d602af, 0x0f7be497, 0xfba7c8e5, 0x3403cdcf,
+ 0xcbb5a331, 0xc8e4fc8c, 0xbea7ad89, 0x4b3fe4d4, 0xdbf8893f, 0xbf84caab,
+ 0x69c6eabd, 0x2c5fe8b9, 0x137be992, 0xcfe48b69, 0xbfe99fd1, 0x997ba640,
+ 0xc53255b6, 0xa322d903, 0x5a46c7c0, 0x7305ff77, 0xe9b95ea9, 0x9dd1c514,
+ 0x27878eab, 0xf802dda3, 0x387da3ca, 0x4fdf8494, 0xd77110ca, 0x94f1297d,
+ 0x9f3d1637, 0xf8bbff2f, 0x19f80cd9, 0x5f3f1315, 0xa3cfc2c6, 0x7f75fee2,
+ 0x68857df1, 0x31df693c, 0xcf7c547d, 0xc791b03b, 0xa5dba3ef, 0xe62ab888,
+ 0x4ff7d174, 0x1f92656a, 0x81f059fb, 0xc59d807c, 0x7de3dd32, 0xb3ead264,
+ 0x733e6007, 0x114a7c8a, 0xc855039e, 0x26c65147, 0x6ffef257, 0x893f235a,
+ 0xbaf40574, 0xb76849ea, 0x99fa617d, 0x05fb287c, 0x7f18ed5c, 0x9fde8fb5,
+ 0x8df313e1, 0xc5b217a5, 0x447bf63c, 0x81e614fc, 0xaadb3b71, 0xf9c785dd,
+ 0x504559b8, 0x657accef, 0x77fd5e2a, 0x9832edcd, 0x2c5feca0, 0x2cf1c7af,
+ 0x893f4ddf, 0x3c06a5e3, 0x38c578da, 0x53c537de, 0x69157dd6, 0xf75deeb1,
+ 0x4ebf0f25, 0x12288e0e, 0xb00674f7, 0x1f072801, 0x9c527531, 0xcb86703a,
+ 0xd326a641, 0x71e8b87d, 0x98fbcafa, 0x6193f028, 0xd10de7e1, 0xf6eb4def,
+ 0xee54025b, 0xa2aff4f7, 0xb2c9a83c, 0x233d0ef8, 0xc4c37b7f, 0x0dcb6578,
+ 0x421e63ce, 0x36840bf9, 0x7e8988be, 0x7ef2a732, 0x9b9fbc8c, 0x27827ad9,
+ 0x0dc094da, 0x8b7601ce, 0x5157507e, 0x95c2c45e, 0x3de11abb, 0xca265bfb,
+ 0xbe4bb355, 0x7e77245d, 0xe47f912b, 0x3aacb634, 0x62dfd116, 0x1ced1eb1,
+ 0x8a35f302, 0x88f39ee4, 0x91f01af4, 0xbdadf022, 0xd1c450b7, 0x6f7ebb1f,
+ 0x1445e512, 0xfb438c6f, 0x12b32f6f, 0x214cd81d, 0x7f0238a5, 0x0eff0336,
+ 0xebfcf44e, 0x1e5acc8b, 0x28e26d80, 0xfc64473c, 0x51ca30be, 0x3eabf798,
+ 0xd1deff07, 0x0fa677a2, 0x17fc7807, 0x383f9d32, 0x7bf3c597, 0x52367fd0,
+ 0x226bcf7e, 0xb59df85e, 0x2c3f7415, 0x4ff44b1d, 0x78054fd1, 0x86a666fc,
+ 0x8d9f7df0, 0xaf9bc1fc, 0xed22e7c9, 0xec152412, 0x4645dc6f, 0x5d71e5f1,
+ 0xd83eeeb2, 0xf6fa8b98, 0xfa12ffb0, 0xfa9de9b5, 0xfe426976, 0xe8da473b,
+ 0x1f769d1e, 0xdee5f9cf, 0x13d272c2, 0x1fff24f1, 0xe7e26553, 0x076d4ac7,
+ 0x2b76ddb0, 0xa27e84bb, 0x4155817d, 0x8ceed039, 0x1b6ab927, 0xf3f64f11,
+ 0xd6a3ccf6, 0x659fc04e, 0xda0a3be4, 0xbe2d032b, 0x7ebb1803, 0xbcc668b4,
+ 0xc72431f4, 0x5c03be7b, 0x2f077a06, 0x733c1037, 0xbda6920f, 0xe9df48d8,
+ 0x63345fda, 0xb68c804f, 0x5b979a16, 0x7cf30652, 0x35786ec0, 0x9c760dda,
+ 0x63b418fb, 0xd0e01ea0, 0x9401df70, 0x7529e947, 0xcd5748ed, 0x292ba3b6,
+ 0x429a5d0e, 0xabe4d572, 0x689ca10b, 0x91ac4b56, 0xc9f1adfc, 0x1afbe5b7,
+ 0x3afef711, 0x7ebafffe, 0x4df3e2fb, 0xfaef9c85, 0x7e68038a, 0x9a7f747e,
+ 0x60c6ff5f, 0x90a37efe, 0xe6b381e7, 0x70bf7298, 0x65279728, 0x5661ef22,
+ 0xaf7d254a, 0x53a0567d, 0xa1d3fca6, 0x9bd80fdc, 0x867ca76a, 0xc2166ebd,
+ 0x016079f8, 0x2ba40fd7, 0x29b29e88, 0x086cd54e, 0x3c1c812b, 0x70b90d0f,
+ 0x97e09c5f, 0xd17bffe1, 0xa418d0bc, 0x7d05d8ef, 0x393df871, 0x17e747e8,
+ 0xc57b4ad8, 0xd77ec9ab, 0x1f78d0e2, 0x439bbf1f, 0xa09820ae, 0x7d236af6,
+ 0xbdfa261f, 0xf0f4bb9b, 0x787a6b84, 0xe77fd322, 0x87aadca5, 0xf87a2b27,
+ 0x6e472153, 0x9f3fd749, 0xfdc3d2ea, 0x338c1c17, 0x1415fbf2, 0x828ed2af,
+ 0xc60ef7e1, 0x200806c5, 0xfca16a47, 0x6b9d01a0, 0x3f341e48, 0xbff88338,
+ 0x7c7d1aff, 0x6dd59d38, 0x9c603649, 0x59dcff5a, 0xefd68674, 0x073fd1ac,
+ 0xfc60e83c, 0x7dd209ec, 0x3c9f70c5, 0x387fe614, 0xe657e79f, 0x7869de48,
+ 0x5a0263e4, 0xfdf915bb, 0xdb8fbe76, 0xfe0b5f64, 0x4adb16bf, 0xa0af2853,
+ 0xb5f7c2cc, 0xf77c58ab, 0xdf8525a6, 0xbcb35edb, 0xa67f0dc9, 0xfba6cc8d,
+ 0xfedd6dd8, 0x2be48fb5, 0xe291be3b, 0x646b7bff, 0x8676aefa, 0x85eb4035,
+ 0xc5d15c75, 0x5cba34a9, 0x6049cfc0, 0x587aba3d, 0x3d3d15cf, 0xa874443c,
+ 0x31f90bad, 0xe45eb110, 0xfb4440c3, 0x72fb86f7, 0x8fc8dd71, 0x72e3cf91,
+ 0x0f744d3b, 0x2fa7ac59, 0x42e4d4be, 0xd68f3899, 0x10bed2f2, 0x69796a63,
+ 0x695e451b, 0x878f439b, 0x5127aa2f, 0xf08be11c, 0x0c5f789c, 0x0fbe453e,
+ 0xc7be73e4, 0x87bc3b72, 0xfae7bd7c, 0x1e38a9e2, 0xc44081ca, 0x084e1bf7,
+ 0xed87fc3a, 0xbb2896ca, 0x3fbfecfb, 0xaec8cf59, 0xeb0a1cac, 0x8e781dac,
+ 0xdf174fdf, 0xf4213ab7, 0xe9c094be, 0xebbcafa6, 0x56bc9efa, 0x8a5bae2b,
+ 0x12bbe3ca, 0x020daf85, 0x57fbda5f, 0xd3c26c94, 0x6b728e95, 0x4262785f,
+ 0x1f21323e, 0xb32a7bf1, 0x4c6ecfca, 0x3a5b1955, 0xf879b9f4, 0x7759887d,
+ 0x02cd2d9d, 0xd7d0f378, 0xb3d3fc38, 0xa6800c2f, 0x2dfcfd1f, 0xf67c3f0e,
+ 0xf9154c8b, 0xe1e73ff2, 0xe21c23f7, 0xaf9b45dc, 0xa1fade36, 0xb758dedc,
+ 0x238f1ce9, 0xbf3a5ec8, 0xc97a77ac, 0xa52cffcf, 0x07e781cb, 0x9cbb52eb,
+ 0xd7206e4b, 0x40ba6dd7, 0xe9860c71, 0x5f30a351, 0x9f129188, 0x57c7e5ad,
+ 0x1de3f3ea, 0xd7c4d58e, 0x50501616, 0x3d59c5de, 0x7d7e7e74, 0x73e68ba8,
+ 0xf9ab531b, 0x0f2bb9f9, 0x5dd667f7, 0x5ff69886, 0x8f9150e3, 0x68df42ca,
+ 0xf2f2265c, 0x768994e7, 0x7117f8ca, 0x9e8cdb9c, 0xfffbd446, 0x2a51663a,
+ 0xbf2d098a, 0x3dcf4869, 0xe6df43b7, 0x0face4fe, 0x24575c0c, 0x53f178f2,
+ 0xcf345dc3, 0xea0038c8, 0xe5f6be85, 0x3d53d088, 0x38a1e2fb, 0x87b27d67,
+ 0xe5d28bef, 0x92fb82d8, 0x5adce5d4, 0x7bfaf7d4, 0x3e144fed, 0xcd32875a,
+ 0x7e90967e, 0xda7f0ebf, 0x607968fe, 0x1e5706f5, 0x87172bd9, 0x609fe2e8,
+ 0xf6bcbbe8, 0x718df4d8, 0xa7360d4a, 0x648e297b, 0x300b514a, 0xeffeb84f,
+ 0xe9bccc52, 0xb74e8273, 0xbee9e238, 0x4cc3bd75, 0x1ddabdf7, 0x61da183b,
+ 0xc236db56, 0x89a3854b, 0x835c9e61, 0xb7d2b59b, 0x82f2a20f, 0x790bec1b,
+ 0x659f2a7d, 0x8e4d54c3, 0xc6d67e71, 0xdc94aabb, 0x772a2e30, 0xa3affff2,
+ 0xf2477aaf, 0xec1f9e34, 0xb07e5330, 0x8bae6894, 0x26dc1f95, 0x5c768dec,
+ 0x83ae0a57, 0xf5b4c9c7, 0xaf3c5d58, 0x9c639f11, 0xd1f2eccc, 0xada2e3ff,
+ 0x87ec4dbb, 0xaae2ded6, 0x25ef2863, 0xf942eab3, 0xff73c52a, 0x4147f51d,
+ 0xc6d49c84, 0x89a87e7f, 0xae1b0bdf, 0x2b35fcf0, 0x7eb317d7, 0x7f19886b,
+ 0xf3543abf, 0xbf19beb7, 0xdb32f469, 0x3461f3c8, 0x336b9ebe, 0x981ed07b,
+ 0x7ca74b6b, 0x8040b99d, 0xda239317, 0xbf3e677f, 0xe9ab29bf, 0x1bbf4748,
+ 0xdfc5e137, 0x4c36f801, 0xf6f4f117, 0x6bdd1354, 0x3cc0db7a, 0xe74652e8,
+ 0x49bd7a23, 0xb79a7193, 0x80db38ce, 0x31d8786c, 0xcbe504be, 0x13728ee1,
+ 0x3b0067de, 0xca186e21, 0x46eea599, 0xbf30efbc, 0x7fbe98a6, 0xd77fc5a2,
+ 0x49303d09, 0xddb039f2, 0x9a3f6367, 0xde6c4155, 0x7fdf4595, 0x88dff114,
+ 0xbb44fd76, 0xaca26ed3, 0xc03efa2e, 0x45e8e515, 0x83f68b9f, 0xf1a21af2,
+ 0xf912fb89, 0x72698bff, 0x8b3bf502, 0xe123b3b2, 0x949d89ed, 0xa9e9af6f,
+ 0xcdf23ea6, 0xf2130db6, 0x714fe351, 0x7cc7109e, 0x6493c456, 0xf37b72f0,
+ 0x3f4fd3c8, 0x37b1eced, 0xa43d0877, 0xd05093f5, 0x2209954a, 0x78a0c4ef,
+ 0x2564fe88, 0x75801e90, 0xfb197d36, 0x61dcf89e, 0x716d8e5c, 0xf6c74b6f,
+ 0x3a6ab915, 0x79d14bfa, 0x51eef5de, 0xf57fc8e9, 0xaafd3553, 0xaff9235a,
+ 0x7bff9ddd, 0x75b42f3c, 0xb9e45898, 0xc669747c, 0xe41bb573, 0xfdc59bed,
+ 0xc7476dc8, 0xbcbe3158, 0xc61256cd, 0xb66dd9f3, 0xbb721294, 0x478f3c6c,
+ 0xf1b36f6b, 0xca9b3abc, 0x1b36d5e3, 0xf2d37bcf, 0x27ddda6f, 0xbb5a0f08,
+ 0xfef8c3e1, 0xff7e54d9, 0x520d5e21, 0x1bd938bb, 0xb8acbcc0, 0x66f64614,
+ 0xc77f959c, 0xc8c0a12f, 0xf9fc31ac, 0xea266182, 0x49665b67, 0x9b54ec98,
+ 0xd87642ec, 0x4e925e96, 0x0df11272, 0xbbdbd6e3, 0x19f745f1, 0x6b7c0856,
+ 0xf3b7d4fd, 0xa9bede75, 0x08c56e72, 0x8bbd13b4, 0xd9b74e90, 0xbf315896,
+ 0xde97b254, 0xc3f5bfb0, 0xca7cba0c, 0x7994fe9e, 0xd815bfa2, 0x512f649f,
+ 0x8b133fb0, 0xfa0cfffd, 0xbbfebcc5, 0x819815e7, 0x60e3df46, 0x9e4fbb4c,
+ 0x68cf4b1e, 0x439c55a5, 0x0ff7bf44, 0xfacd95db, 0x93d82578, 0x75830d0f,
+ 0x3b9e66d5, 0x709e9131, 0x5e31b27b, 0xd849177c, 0xdbc2b285, 0x3df91a37,
+ 0x637bed4d, 0x27289d9a, 0x73d0f1e9, 0xc3ef8a7f, 0x31c78555, 0xc518daae,
+ 0xf9f9a257, 0xba63a9ea, 0x67a8107b, 0xc6dec23d, 0x8f48ed12, 0x3895cf19,
+ 0x8efc6b5f, 0x3f28ba77, 0xf77f9aaa, 0x2918a6c4, 0xf400c25f, 0xddad744b,
+ 0x8a4af9df, 0x115d7f69, 0xab486afb, 0x6dbf8951, 0xa32c42a1, 0xf3bf7bf9,
+ 0xf3f22154, 0xfadd69fe, 0x6d75c156, 0xf7e5ca48, 0x564e4f17, 0x5fc3d962,
+ 0x71c25f77, 0xa4ddc76e, 0xcf5c9d67, 0x3fbebffe, 0xaf34e8d1, 0x66debd44,
+ 0x97f7fbd0, 0x50fddc85, 0x9afd8ff0, 0xdbbcf74c, 0x22ef7c8b, 0xde8c98bd,
+ 0xfb07d46a, 0xbf9366eb, 0x501e0324, 0x30dfeeef, 0xc0af2a2d, 0x08b0fef7,
+ 0x326b2e7e, 0x1aa677d3, 0xbf208fc0, 0xa31f6a2e, 0xb7eda7f1, 0xf9abdb06,
+ 0xbfb69a39, 0x216cd313, 0x764bb791, 0xb9653387, 0xb398e501, 0xd9f067da,
+ 0xec987db1, 0xfddabe8d, 0xad3bc84c, 0xb7fb0dbd, 0x3c4afce1, 0x8c4c7bfc,
+ 0x6b24aef2, 0xec7fffec, 0x810f0a30, 0xcbac2b1f, 0x82aa7471, 0xeec24afd,
+ 0xe8f9146d, 0xd5a94af5, 0x94bef113, 0x149d6a54, 0x7df52f41, 0x874a87c4,
+ 0x942bdb77, 0xfce5a7e7, 0x60af684b, 0xbe4d9f5e, 0x20471ddc, 0x675e20ff,
+ 0x47e36a2f, 0x9cf7bb9f, 0xbe3a73b3, 0xbd9294aa, 0xbb018f28, 0x4307ec00,
+ 0x489bd2d2, 0x3f7c9a3f, 0x743c034e, 0xfca167bd, 0x3f05f7db, 0xec7e0a76,
+ 0xd8056e4b, 0xb7dcba51, 0x4bc71d95, 0x2527401e, 0xf5274889, 0x39dd4699,
+ 0x8b16568c, 0x5fb0c675, 0xfc8f87f2, 0x90cbf646, 0x17ec31e1, 0xcf224fb4,
+ 0xf12ed1cf, 0xb445c844, 0xec313c4b, 0xf0a36697, 0xe779c4df, 0xadab9369,
+ 0xfa70f013, 0xcefa44e6, 0xdbb469cd, 0xfb3ec04a, 0xdc5cd9e9, 0xee865994,
+ 0x3b0853ef, 0x760c1191, 0x5e7077da, 0x1abbcc55, 0x1cd6ffff, 0x883f1bc9,
+ 0xffd197e7, 0xfb75f2ab, 0x40b80719, 0xfbc76cbc, 0x1f744570, 0xf9d632ae,
+ 0xe9baf7da, 0x88974504, 0x601e11c3, 0x5be22217, 0x5176e2bd, 0xa30c3a71,
+ 0xe6fde774, 0xfdbf6ef4, 0xdae281ba, 0x882c7d3b, 0xb5bfb9df, 0x7b571f4c,
+ 0xed99e443, 0xcf88ca5c, 0x86b41676, 0x53495fd0, 0xabc9c519, 0x73f6fa3c,
+ 0xe3bfa32a, 0xddbf8fac, 0xcf4535e6, 0xd6ebbe97, 0xc06fac5f, 0x9714d5ee,
+ 0x8b8f15eb, 0xfad1c38a, 0xf2943f50, 0x46adbc78, 0x6f655f9f, 0x7ddf419e,
+ 0x12aeac66, 0x34cce7d7, 0xda8f8c32, 0xcff3a3ab, 0x1ecf0202, 0x9e1a5a12,
+ 0xd878efb5, 0x7bfc8d8a, 0x540981a4, 0xe1c1e5af, 0x3a2705f7, 0x5b65d67b,
+ 0x2c53e62f, 0xd881ace2, 0xf189daeb, 0x2e57cc46, 0x83c4830a, 0x302e70fe,
+ 0xa30d464e, 0xbac299ef, 0x8705e775, 0xd0356f77, 0x03e147ff, 0x3c26ed71,
+ 0x9813cfe8, 0x5afb40cf, 0x807f3fa3, 0x68e0ea75, 0xecebfebb, 0xb3bbc3f9,
+ 0x58ff7e63, 0x5038b52b, 0x7610f8af, 0x383a4800, 0x6ca77c5c, 0xf68a1b28,
+ 0x2378ad8d, 0x4c95c3ed, 0x0acaf79e, 0xa1bb9f62, 0x0ddf8f9d, 0x327c8a9a,
+ 0xa679fd12, 0xf302cefb, 0x6f9f94c8, 0x3573e328, 0xa672f3f4, 0xd7c4622b,
+ 0xb1307896, 0xbcfff04a, 0x1fa0f78a, 0x8c00b167, 0xdf1063df, 0xbdc4969f,
+ 0x26062da4, 0xd514cc23, 0xb5e4f3ca, 0xe9043cef, 0x8d7d0f3b, 0x8b077da3,
+ 0xda7bf805, 0x37dfd138, 0x74fbd1ba, 0x7e894d1f, 0x3ae282bf, 0xe17df8da,
+ 0x17efafbd, 0x9dfcb1fd, 0x953e3c91, 0xc35a7449, 0xeba71fb4, 0x2b74ddc5,
+ 0x53b83c93, 0x0f0f4eab, 0x773e7e45, 0xf74a824f, 0x0475b56f, 0x8eb44ba6,
+ 0xf75fd96f, 0x595dd23c, 0x5881defc, 0xdbefe897, 0x117e8bae, 0x9301acf2,
+ 0x1a8e816f, 0xcf91ef81, 0x2e93296c, 0xa10e74c9, 0xbf8bcfbf, 0x35fd1173,
+ 0xf9493d1c, 0xbdc47b3b, 0xa75c6d70, 0x8a0433ea, 0x3c107ef0, 0xd08f118f,
+ 0xdf8ca5ca, 0xf5e6d28f, 0x3504017f, 0x7fe05f6a, 0x00007fe0
+};
+
+static const u32 csem_int_table_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0xe733ff00, 0x51f86062, 0x39fbc10f, 0x716e1819,
+ 0x0143f822, 0xd9433117, 0x1017fa40, 0x606463bf, 0xbc48cf78, 0x040e357e,
+ 0x033b2f7b, 0x3e200ac3, 0xfef03ec0, 0xc95c481a, 0x4ebb3f4d, 0x622ed1d0,
+ 0x067e2ef0, 0x0c023d86, 0x1082590c, 0x54417ffe, 0x08fcddf9, 0x651898b6,
+ 0xf5012976, 0x93320003, 0x038009d3, 0x00000380
+};
+
+static const u32 csem_pram_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x7dd5ff00, 0xc5547c0b, 0xbddcf8d5, 0xeecddd8f,
+ 0x21079b26, 0x086e3c21, 0x4bc60a22, 0x9bade102, 0x88b46204, 0x7d608a89,
+ 0x8420182d, 0x96d22247, 0xedf7ed7e, 0x5ab11062, 0x68db151b, 0x34105db1,
+ 0x060b28da, 0x2df0980c, 0xaa5694a0, 0xd1f58df1, 0x90cbc8a0, 0xf87e8784,
+ 0xce7feb69, 0x7bbbb999, 0x7c486eef, 0xfefdfbf4, 0x730ecfe9, 0x3399dee7,
+ 0x9ce735e7, 0xc92b3339, 0x210cb102, 0xbbf81be4, 0x22ad909c, 0xa46c6421,
+ 0xe5a22aec, 0x79fc4218, 0x8126c08e, 0xafaed090, 0x4234908e, 0x54cd364e,
+ 0xec84d9ad, 0x2e8473ce, 0x0327eda7, 0x6d2b0185, 0x76f6de2f, 0x4beb44a2,
+ 0xb41289b6, 0xf1d9765b, 0x4275cefb, 0xd6d5ea00, 0xd12607b6, 0x9136f77a,
+ 0x935da06c, 0xd242d390, 0x23623909, 0x61754fec, 0x559dbe7d, 0x7ddfac97,
+ 0xd9578c2b, 0xfa76256c, 0xd12691fd, 0x9b65f503, 0xe3a10084, 0x8f71d92d,
+ 0xb7f68032, 0xed042020, 0x7a6fad2a, 0x845d5150, 0xfdebb5dc, 0x212776c4,
+ 0xa2367c27, 0xca8f382a, 0xaa4228e0, 0x064a5b02, 0x1aabefd0, 0xfb42cd05,
+ 0xaa775aaf, 0x6aabe013, 0x69102f92, 0x1c1a8b7f, 0xc6c11d44, 0x78c086fe,
+ 0xbc703b7b, 0x1830f26d, 0x3bebf2af, 0x3cc22215, 0xb77c0f65, 0xf301c284,
+ 0xe13dc7d6, 0x74f1c7ab, 0x9a792e7c, 0x5bdf478e, 0xc1a09cfa, 0x885a9714,
+ 0xdce8e017, 0x84fd9f61, 0x52b7e613, 0x9e8aee19, 0x30ed9cc7, 0x7ac0aa8f,
+ 0xf009c4a5, 0x8fe657ad, 0xa8b7f48a, 0xf846f7e1, 0x7bfa73ea, 0xe5cddaa3,
+ 0xe9451f09, 0x8abd48f0, 0xf6904f10, 0x5280a44b, 0xf9e4497e, 0xd2324207,
+ 0x4883517b, 0x7fa45b54, 0xfa42794a, 0x9b7fffd1, 0xc1e293fe, 0x6c0aeadf,
+ 0x6dd08eca, 0x16681b99, 0x3769dba1, 0x5dd4a3a7, 0x5ebfdd10, 0xa0f4003e,
+ 0xdcf9d4f0, 0xcbe43e58, 0x4fad72c0, 0xd6fdbc45, 0x7acb0237, 0x1fcf869f,
+ 0x72c78df3, 0xe583cf9d, 0x58a57c1f, 0xf8657c06, 0x6cdf06de, 0xbcfa372c,
+ 0x5f49fcf8, 0xbe0d9625, 0x8cfe7c1a, 0x8d96056f, 0x7f3e3f3e, 0xcb06b7ce,
+ 0xcb0eafa0, 0x5a2f40ad, 0xf802f936, 0x035f76de, 0x20becd96, 0x6be9df3e,
+ 0x8e7ef2c6, 0xa4c9c4c7, 0x4878a250, 0x253710f4, 0xee99493b, 0x3d699429,
+ 0xd3d58ca5, 0x2a17f66f, 0xa5ee9eb4, 0x01978a75, 0x5685438b, 0xc3501f5a,
+ 0x92ff07da, 0x7d68d914, 0x0fb59fb0, 0x6453dfbd, 0x75a1f5a7, 0x3af87dac,
+ 0xad02517f, 0xf6b00f0f, 0x45431b8b, 0x38bf5a0e, 0x5b73dac8, 0xd693b148,
+ 0x9eac4373, 0xec53c077, 0x36bcf5a2, 0xc0f82f56, 0xeb489c5f, 0xfbeced05,
+ 0x51011d89, 0x61d2c675, 0x4edeacab, 0xf9d6ad28, 0x1348f4af, 0xef515d68,
+ 0x8fc51a24, 0x948f5aff, 0x7b21f149, 0xbfe43db0, 0x149bdb09, 0xe1bfb60f,
+ 0x76fac0af, 0x87ed8bd9, 0x5d584bfd, 0x17fb62f1, 0xbd629ffe, 0xbb63f659,
+ 0xd58fa56d, 0x0fb63f15, 0xfb06b958, 0xb00729df, 0x07cad47d, 0x12a77db1,
+ 0x5687f6c0, 0x4a99e63d, 0xf782b5eb, 0xb48fc0b7, 0xc03924ac, 0x328cc14f,
+ 0x05ab4fca, 0xf7f81b32, 0x28e980bf, 0x54ceae5f, 0xfeb70e50, 0x9009e0ad,
+ 0x834bfc5f, 0x7f27fcfa, 0xffdf8d95, 0x6991fb11, 0xfdef623f, 0xde3abde4,
+ 0xabde4fd0, 0x0d3f7a95, 0xbdad5ef0, 0x7d6cfd6f, 0x9e11a275, 0x7ef4ab57,
+ 0xae3c20b6, 0xef2bcdbe, 0x7846c9b5, 0xf7ac5b5e, 0x49e113b3, 0x4d3c1bee,
+ 0xd3f11b6f, 0x3f1876f4, 0x7e9e117b, 0xcc67837d, 0x8cfc463b, 0x9f8c2779,
+ 0x664fd803, 0x7a69fadf, 0xa69f88c7, 0x79f8c277, 0xa835e71b, 0xf31af36f,
+ 0x633f11ae, 0xe7e30dde, 0xbb278423, 0xff6cfd6f, 0xed9f88d0, 0x73f1861f,
+ 0xa0b9fb14, 0xf82af36f, 0x829f88c8, 0xe9f8c28f, 0xea2e7ec6, 0x3fdb3f5b,
+ 0xfb67e232, 0x7cfc6147, 0xd25cfd89, 0xfc1579b7, 0x829f88c3, 0x63f1847f,
+ 0xd19fa011, 0xf9a7837d, 0x9a7e2353, 0xc7e30d3f, 0xed8cfd81, 0x8fe33c1b,
+ 0xfe33f118, 0x693f1848, 0x427dd002, 0x3e69fadf, 0xf34fc462, 0x067e3091,
+ 0xfa533f61, 0x47f1af36, 0x7f19f88d, 0xe19f8c34, 0x2a42af38, 0xa10f00f7,
+ 0xee7ab8fd, 0x2349e767, 0x0c9e767e, 0xec52e7e3, 0x27ed1a67, 0x267ef7a7,
+ 0x33f11a76, 0x9f8c33b1, 0x95cfd8f1, 0x6767eb7d, 0x3b3f11a7, 0x29f8c33b,
+ 0xdd5cfc44, 0xec4d79b7, 0x6267e232, 0xfe4fc317, 0x89c5355b, 0x85ae9db4,
+ 0x993f489a, 0x08f1e1d4, 0x59ba2eb4, 0x046b745d, 0xb75112ec, 0x479b4837,
+ 0x1b3bdfa4, 0x457ef393, 0xa28eeda2, 0x8b979872, 0x76d1635a, 0x04f8d247,
+ 0xec939d83, 0x53d43149, 0xde18074b, 0xd43657ef, 0xf67fded0, 0x4cf686c5,
+ 0x9ea19e6f, 0xf0d13955, 0x229aa0fe, 0x8ac87d43, 0x67ef0cab, 0xd435affb,
+ 0xd8fcd673, 0x7505fef0, 0x17ed0d73, 0xda1957d6, 0x332c0a2f, 0xfc3647d4,
+ 0x4bfde187, 0xda197782, 0x95fe6d2f, 0xe8747da1, 0x7f3d4321, 0xf78663ff,
+ 0x306db6c7, 0xf83b8fb4, 0x427da18c, 0x7d4356fb, 0x269db1d2, 0x3ee9cf3b,
+ 0x45d79232, 0xecc27be0, 0xed054cfe, 0xc14b90bd, 0x89c032ba, 0xd76efc76,
+ 0xa530f57c, 0x76e7b2af, 0x17d28d35, 0xbae84a68, 0xf2a0385e, 0xfcfa76c2,
+ 0x17bd13a7, 0x9ff3e9ba, 0xdd4bde2a, 0xca53ec71, 0x80c9020f, 0x6940b552,
+ 0x6647bf6e, 0xf59458fc, 0xf443f0f5, 0xf74b6afb, 0xb75a64f0, 0xc0f58588,
+ 0x2c107fbf, 0x2209a7c8, 0x12f781a9, 0x82fd04ac, 0x9e0bb27b, 0xebf147f0,
+ 0x0e54419a, 0x6bbf4885, 0xd8066f64, 0xbe561b19, 0x643b07ee, 0xaf3a20f5,
+ 0x213c8401, 0x0ff21ebc, 0x9a0fdfa3, 0xfda5e19f, 0xa76a1559, 0xd0af8f47,
+ 0xf8e147f1, 0x73fe300d, 0x1d6f8c3d, 0xbe30de3a, 0x61a5706d, 0xc7429b7c,
+ 0x607b5377, 0x7c7c7be5, 0x8489844a, 0x87bc2f3c, 0x57075be3, 0x28f7f8e2,
+ 0x1e895fd4, 0x7e3c213f, 0x2ecbc833, 0x9c6c7f18, 0x689d0ff9, 0x2ae0ff9c,
+ 0x3615fce3, 0x0f2b3dff, 0x7013f1f1, 0x43857bfe, 0xab83fe6c, 0xacadfcd8,
+ 0x89f8f0df, 0x87effc61, 0xd3dabff9, 0x1b2673fc, 0xb1643fe7, 0x3656fe71,
+ 0x8f2b1bfe, 0x389df1f3, 0x71c29bfe, 0x8b21ff36, 0xeac57c71, 0x947f80d5,
+ 0x009a84ac, 0xa40c9f1d, 0xb03fa98a, 0xca071d0b, 0xa9942911, 0x30b5f909,
+ 0x69f8e114, 0x2fb7e302, 0xa1bf2812, 0x73e3f1be, 0xad9aa012, 0x9c5dfa80,
+ 0x163517d7, 0xb097a02a, 0xf32bfa9d, 0xcd15a838, 0x5937f222, 0x405c0d6b,
+ 0x166cede1, 0x58af50fd, 0xfa00253b, 0x6e4adaaf, 0x24ef832b, 0x9fe78212,
+ 0x86c9723e, 0xcb9979e8, 0x91f27579, 0x0b7928f6, 0x644551fb, 0x6f850d44,
+ 0xd8c1301a, 0xea63fd48, 0x5fea1107, 0x0cfd407c, 0x13f25942, 0x11f78d99,
+ 0xdea097f5, 0x6825fd4e, 0x7e256427, 0x2b7bbb47, 0xc65fc283, 0x6258ffe1,
+ 0xcdf1faf2, 0xe54fc042, 0x8f9f8bf3, 0xb6f53f46, 0xf48a0e15, 0xfc731c08,
+ 0x9d3a86a9, 0xd4e81f97, 0xd81ac3bd, 0x557e2020, 0x8a3957c0, 0xafb72126,
+ 0x8eb8a2c9, 0x252effbc, 0xfd45267b, 0xf723c40d, 0xb2dfefa7, 0xa6e4185c,
+ 0x58f4cee3, 0xe13ad8f3, 0x5ca0b2c9, 0x78cb2c93, 0x1a6dae42, 0x481ed32d,
+ 0xb8fe47b9, 0xebdc6a3d, 0x99f58d4a, 0xa77ac665, 0x142d91ec, 0x8172ceae,
+ 0xcefda7ac, 0xd76c6d9a, 0x525a71c7, 0x78f99d18, 0xbe0ce965, 0xc1e65059,
+ 0x79d23763, 0xab7d9bb6, 0xbb7d53c3, 0xa0585d4c, 0x011fbfa7, 0xf0d3faba,
+ 0xd9bb1fbd, 0xcef0cdbc, 0x329e6d96, 0x73d9cf3a, 0xb7f000c4, 0xefbffe19,
+ 0xb92c7872, 0xb0f35cb4, 0xf3b12c4c, 0xa37fc331, 0xa09f3cd7, 0x4df0eb0c,
+ 0x8ce7e695, 0xfa708e6f, 0x41fc0c7f, 0x1fc0a3cb, 0x9cc3fe14, 0x957a223f,
+ 0xd5b547f1, 0xa1f8033b, 0x209151fb, 0xdcbf395d, 0x5e65f9c0, 0x082f919d,
+ 0xc740caf1, 0xbc85b305, 0xc1f1455f, 0x0b07ce2c, 0x737c8dea, 0x99cbf10b,
+ 0xe372e871, 0x6777f5da, 0xfbf3b1a8, 0x4dcdf390, 0xfc46eff7, 0xd193cec4,
+ 0xa74e56e9, 0xed8c6a5b, 0xdeba7037, 0xbb3ae9c2, 0xa997c1fe, 0x563f20fa,
+ 0x7bc83203, 0x7a742ff5, 0xe9e81bb6, 0xc334f4e5, 0xe7a72b79, 0xf4673fad,
+ 0xcedbc334, 0x7f5ed9e9, 0x63432646, 0x77c335e1, 0xf9988adb, 0x39cf4028,
+ 0xacf4f8fe, 0x3d4c2e6e, 0x497cf51c, 0xc3d4caf0, 0xa8b67251, 0x5f50dca1,
+ 0xf0d1b818, 0x39fa82fe, 0x7579f686, 0xb7ed0d0b, 0x50c3b9af, 0xb9ffe39f,
+ 0x56dbfde1, 0xdfb434ac, 0xa1af7352, 0x07caa6fd, 0xbd1bf50d, 0x9fde1a8f,
+ 0xa1bd7b35, 0xd3d9667d, 0x4aebf686, 0xe5ea18b7, 0xf7861d9e, 0x870b5d85,
+ 0xeabae3b4, 0x887f63fd, 0x4567be27, 0x3beb353e, 0xf61e2f5d, 0x88fcf8a9,
+ 0xc796046f, 0x3f3e1a7c, 0xe58f1be1, 0x74dfd04a, 0x60ecb05d, 0x7343f565,
+ 0xe2a3b886, 0xdac89f1e, 0xbdb3d060, 0x7dfd43e9, 0x7fa3deb3, 0x14ecf159,
+ 0x902c5cbd, 0xbb075832, 0x3fad1db8, 0x49d7c53f, 0xb942ee42, 0xb930ac5c,
+ 0xb335bc5d, 0x3d422488, 0x4e26bc34, 0xcf2c267c, 0x33e70141, 0x00c72eaf,
+ 0x91fa82e7, 0xe036f826, 0xf9030b38, 0x1a8be786, 0xebbe1926, 0x7c222dd8,
+ 0x27c6414b, 0xb65672c0, 0x85f002c7, 0xeebe0ef6, 0xb3d78012, 0x4beb02d7,
+ 0xe7b43f73, 0xa9a57c3a, 0x73c02587, 0x7cc79619, 0xe23cb1b3, 0xd87962f3,
+ 0xc7e58957, 0xdb2c1abe, 0xfcb02b7d, 0xf2c7e7c8, 0x2c1adf03, 0xc3abeeff,
+ 0x1eafa0f2, 0x017c77cb, 0x35f2df2c, 0x2f86f960, 0xaf9b6588, 0x9f4ecb19,
+ 0x5e5d4b07, 0x4865f8a2, 0xe8bf1466, 0x8fd74ffa, 0x9cbf38c7, 0xc7897e00,
+ 0x7c8c1b17, 0x41ae5471, 0x43eb30be, 0xfacc1d33, 0xc3f2bbef, 0xdbb30b58,
+ 0x443f2fbe, 0xa2659de8, 0xf46f4e77, 0xbd146226, 0x0cdc5ac7, 0xfbef4e1e,
+ 0xf638de00, 0xb8b025fa, 0x83b28bf7, 0xff160e3c, 0x6a7a71e5, 0x2ff8b201,
+ 0xbe96bb1f, 0x52f686db, 0xe3e80460, 0x77fe23d3, 0x4fb7c438, 0x6752b41f,
+ 0x99f9e7aa, 0x1e23d7e9, 0x86fd0788, 0x28ba01f9, 0xdbb6c7e4, 0xed5e1813,
+ 0xe84a5216, 0x05ef717a, 0x47736a4f, 0x29225d61, 0x2b407df0, 0x97e9c577,
+ 0xdf80a0da, 0xeb5af0de, 0xfa1722fa, 0x57d8f23b, 0xb58e5005, 0x61343b30,
+ 0x30f688af, 0x01a13d09, 0xdefac37e, 0xdc4065aa, 0xc502fbb8, 0xc071eb8d,
+ 0x9f9fc469, 0xf8220bd6, 0xa8e297bb, 0xbab3d70d, 0xb0dfc40c, 0xf667862f,
+ 0xe9bd7f01, 0x39f0dec9, 0xdfe03037, 0xf4decf82, 0x8b7a6f57, 0x9ae7d478,
+ 0x76bbfce9, 0x2bf7925d, 0x50d4f415, 0x80f4ffe6, 0xc7bf7d6f, 0xf0254f0c,
+ 0xf3bed8f1, 0xceba5771, 0x09836dc7, 0x906de71d, 0xe9ffda17, 0x80930ba6,
+ 0xb41fb42e, 0x71b7bbbb, 0xba17b9fb, 0xf636cc9e, 0x2fe5cd57, 0x42925fdc,
+ 0xb8e94b84, 0x4921452e, 0xbd161d74, 0x1bf4442b, 0xf83f76b4, 0x5a1cbbe3,
+ 0xd8fe0aad, 0x2a435789, 0xdbf468f4, 0x227fef4f, 0x659bfc11, 0xe1f71619,
+ 0xcbd47438, 0xb76cc125, 0x680fda33, 0xd74fd636, 0xf441a509, 0xeba4d493,
+ 0xc075812f, 0x0c3c3eed, 0x960672f4, 0x32cb3f7a, 0x54e1f714, 0x23d33fa4,
+ 0x67a8c98d, 0xf86cf84e, 0x470d0fde, 0xe044fd4f, 0xd09f2268, 0xdf1481ef,
+ 0x7efcf4e4, 0x9d20728f, 0x485e2055, 0xc02fe45a, 0xffd3b37f, 0xfd0a19be,
+ 0xfbd7584a, 0x7e8a0ead, 0xbcf0a5eb, 0xfd1e30d1, 0x32f7d54e, 0xe59ebbe1,
+ 0x7447224d, 0xdb74a77e, 0x175bf7c2, 0x46ddd835, 0x50d930bb, 0x74ce6eaf,
+ 0xf844ec1b, 0x95c21807, 0xb77c0482, 0x975db398, 0x7c035ce4, 0xe3043f74,
+ 0xf605df80, 0xbb5b12de, 0x4c5155e2, 0xe72f80da, 0x5ef9d78e, 0xd53ef59d,
+ 0x915fc74f, 0xf917c809, 0x1055429a, 0xa0ae8fe9, 0xb7eb42c4, 0xa6dcdaf3,
+ 0xbd61d345, 0xf6616e3a, 0x4b290578, 0x92b37f04, 0x7c4015d4, 0x94b124f2,
+ 0x249e5c82, 0x47e6246f, 0xa2fbe1c9, 0xbedcf082, 0x531768c6, 0x5f50d97f,
+ 0xcfac6f50, 0xc3a6d727, 0xb5fcf2be, 0xa0080932, 0xafed8c2f, 0x168e4c88,
+ 0xb0d59a90, 0xd995afbe, 0x4dd7363a, 0xdf0a2ca4, 0x2f1e1792, 0x1feb4398,
+ 0xd31ecc8b, 0xa61745f7, 0x82abf830, 0x6d0f15eb, 0xff29a4ff, 0xe879aa06,
+ 0xb0d581f7, 0x09b7f95e, 0x963526da, 0x7e16df7e, 0xfafabc33, 0xcb3fb31f,
+ 0x20d258e1, 0xec710278, 0x0ebe6e80, 0x4d2e7aeb, 0x08e21b72, 0xe2a3d42a,
+ 0x9f99df0c, 0x9f8188d2, 0x36bd17ee, 0x1fe31fa9, 0xa904a7f0, 0x9f7ef15b,
+ 0xfa6233fe, 0xfec6934f, 0xa40ffd80, 0xfa1817fd, 0xf8507f57, 0x3fc0c587,
+ 0x4bff5e2a, 0xbb76785e, 0xaa93ea9f, 0x12248fcd, 0x971e3eba, 0x4a35d2ea,
+ 0xee9bc5df, 0x1f3a044e, 0xc089fc93, 0x6203c7af, 0x7ace2069, 0xe9d25735,
+ 0x100a71ed, 0xd27f82c7, 0x733c4ffe, 0x5ff7fa1f, 0x18dd926c, 0x86b06a9f,
+ 0x971e54ac, 0x4e9c2d36, 0x887eb172, 0x2539efd5, 0xc8d9bd42, 0x3d4f557f,
+ 0x0af90e92, 0xbc785394, 0xecf68426, 0x969f8dd2, 0xba44bae0, 0xdfcc8e51,
+ 0x52e7f8c1, 0x51cdff50, 0x29db6292, 0x5777e89c, 0x3754bc73, 0x4c4a77dd,
+ 0xa3b57f84, 0xbf7e6c3f, 0xd7a5db92, 0x23b4ae49, 0xe32704d4, 0x87d038c8,
+ 0x80483e3a, 0x0be2a5d9, 0x1c42e78f, 0x2be363b2, 0x9e144289, 0x1d3a3974,
+ 0x3b8ffdbc, 0x6df59ed5, 0x68b39527, 0xaf5f47fb, 0x4f6e66d4, 0xb172b0b7,
+ 0x449c4a1c, 0xf5e2e0f5, 0x8fa7e6b2, 0xc4fb3f17, 0x5c418f93, 0x76ab3df0,
+ 0xd17fed01, 0x33bf2fb3, 0x6d17d691, 0xb3a6d391, 0xf4853869, 0xe9aa5d08,
+ 0x22f22b7f, 0xfe7aa874, 0x84bd4565, 0x4a65ff3d, 0xb68b1e84, 0x25c856ec,
+ 0x0e28f8b1, 0x9dda56ee, 0x3c12e871, 0x81f60254, 0x153fc2f8, 0x5df1fba0,
+ 0x1d9fe902, 0x5feb9f07, 0xf01ff5c6, 0x74e47484, 0xf4cdd30a, 0x0ba5357e,
+ 0x4e9d6be8, 0x5cb1f6e6, 0xea7f40bf, 0xe7e7e428, 0x54fc5276, 0xc1aaddfe,
+ 0xbb9f2bfc, 0x71e61133, 0x7c61aa54, 0xe9ddf8fd, 0xa56e3a1e, 0x63774fec,
+ 0xfe579ec9, 0x6fc827e1, 0x49ff5e0b, 0x8867c63a, 0x6b82d327, 0xe6133f8f,
+ 0x4cdd6f37, 0xe27cdf9c, 0x7cabbe45, 0xfd032c5c, 0x4a44b9f7, 0x8b91c4b7,
+ 0xe3b31283, 0x06a06e8e, 0x51df9d18, 0x7e60acba, 0xe6221bca, 0x07721129,
+ 0x09fff901, 0x10b50b9f, 0x8db9feb0, 0xa4b369d1, 0xcad461fb, 0x8dd7e68c,
+ 0x7d01b4f7, 0xf4f20c4e, 0x6a8b7d87, 0x3e39f922, 0xbf686f84, 0xfad3ebe2,
+ 0x5550fa33, 0xa3bfc05b, 0x3c317ceb, 0x64dbf787, 0xf0d73d8f, 0x3b26f91d,
+ 0x3e72fe32, 0x013b853e, 0xe9a3e7d6, 0x4954edf1, 0xdaf87416, 0x457f1448,
+ 0xf79337c9, 0xf932f78d, 0x503de5d6, 0x67ed0a5e, 0x03f262df, 0x47fac1df,
+ 0xc7f50ae1, 0x0bd7ddf6, 0x24ac0fa8, 0x37ae4f14, 0x8dae5cca, 0x509f3aed,
+ 0x292125b8, 0xffa05f8a, 0xee3fc414, 0x4b5fcc57, 0x97d28bbf, 0x625e30d5,
+ 0xdcba7f6c, 0xfff2e02e, 0xc8ffc826, 0x7593fc88, 0xb67bee4c, 0x17a8fc9f,
+ 0x2781cb17, 0xa579031f, 0x4157e9f2, 0x9832e55e, 0x7b8d67f7, 0x9531f9df,
+ 0xba82cf93, 0xa7f51a9c, 0xb72b4e59, 0xe4f1258e, 0x46a733f4, 0x7d29cae2,
+ 0x9d4e571e, 0xffc7c8ed, 0xc753fa57, 0xfc2657df, 0x27b0fae9, 0x61f59a3c,
+ 0x3e22a4bd, 0xfe90facd, 0x620a45bd, 0x3be74ff9, 0xfeaadf9d, 0xe80864b4,
+ 0xea5f309d, 0x4be6177c, 0xe262ef9d, 0x99fc06a1, 0x18865fdb, 0x816b8510,
+ 0xf032fead, 0x809a6c23, 0x87617e72, 0x6ceef305, 0xbff40463, 0x584bd446,
+ 0x1ee2dd7f, 0x8ce8760b, 0xf67c2f49, 0xededf273, 0xbe5aefff, 0x307b63e0,
+ 0x861ca03b, 0x74d14be0, 0xe0c2d71c, 0x02403eac, 0x781f5143, 0x7f28b2c4,
+ 0xf7970e79, 0x9ad83e17, 0xec2c780f, 0x8ed4951a, 0xfa30727a, 0x6f5cd593,
+ 0x49abf69c, 0xb74f4fa0, 0x78bfa0e4, 0x8ae8bf7a, 0x34f7ff97, 0x209fefa7,
+ 0xaecb463e, 0xa44ea48d, 0xba45d6fc, 0x6ff06ed1, 0x714d91b4, 0xcba6aff6,
+ 0x5f7e2f4c, 0x01fd007c, 0xdbdb4f1f, 0xd8e2ca4b, 0xf9f2b7b1, 0x25f3d8ce,
+ 0xb7178fae, 0xbd80b7ac, 0x8b46f174, 0x41bfefc1, 0x479d7ce6, 0x67af80f2,
+ 0xc6bbb1ec, 0x8bf71e00, 0x5649e41a, 0xbc529cb7, 0xf342fc71, 0xb07fa1fc,
+ 0xdd93eeb7, 0xca2f4fc8, 0x0f01dbc1, 0x11b49e2f, 0xa1db2fd8, 0x078a2dd4,
+ 0x830a9de7, 0x4661c773, 0x2f0a1f97, 0x50ce5d85, 0x3673c411, 0x58dbe412,
+ 0xf3e4133a, 0xb0240dd3, 0x2de81b32, 0xc1237ab2, 0xca0a57bc, 0x77c327af,
+ 0xa35ed35f, 0xe6c2f3e4, 0xe8127f2d, 0x045b4b7b, 0x2fb685b7, 0xe015da95,
+ 0x64e6ea97, 0x68d8f411, 0x74ffcf55, 0x147d725f, 0x4b27ddff, 0x13bd9788,
+ 0xf009bc5f, 0x2143a672, 0x79efcfb0, 0x68f31ba9, 0x23e4b4cf, 0xaf34f5bf,
+ 0xb2e47de7, 0x43f412a9, 0x3a665f10, 0x304c6a8e, 0x7b1527d4, 0x335c0007,
+ 0xb5cbedac, 0x2bb77838, 0xa1fdeecc, 0xb2b7b3e4, 0x96fbf2cf, 0xb15ebf2e,
+ 0xfeef8a2c, 0xfdbf2b1e, 0xb2efc9e3, 0x987f6a95, 0x9cd6b2f7, 0x65cf80fe,
+ 0xc5fb917f, 0x7d67abe3, 0xccdc2fcc, 0x9abb65f3, 0x1a5efca8, 0x544dbf25,
+ 0x01c4e37e, 0xe581fa5f, 0xdf9059f7, 0x2bbdf038, 0xf2e8fa33, 0x0872db9b,
+ 0xc9b737e5, 0x7933c862, 0x7d76e655, 0xf42bf28f, 0xea0d3ebb, 0xa388e6b2,
+ 0x100f01af, 0xe3ccdcc7, 0xc80e30fc, 0x71b8a4b1, 0x63957d9e, 0x8e59bfdf,
+ 0x98236d97, 0x6f4b1317, 0x76cbc726, 0x80163950, 0x978e4cee, 0xce3952b5,
+ 0x11df958e, 0xbecbf231, 0xdf621a5f, 0xff673757, 0x5e3a66ee, 0x6cd6479e,
+ 0x88bcfdf4, 0x968d8f3c, 0x70914967, 0xbcf231be, 0xbcf26fbf, 0x9533cb8d,
+ 0x1c5aa1d3, 0xc62d6aba, 0x2717acfc, 0x1e7c6d1c, 0x226ff2f8, 0x5baf49fa,
+ 0xeafb5d98, 0x8063a384, 0x7870a62f, 0x743a7086, 0x7fd8fcfa, 0xd347c4c9,
+ 0x5f8a4e41, 0xe42dfbaa, 0x28d92f35, 0x4b87d013, 0x1fa10e9b, 0xe8ab8e6a,
+ 0xbe399576, 0x7311eba2, 0x8351659c, 0xc7c79eb1, 0x11db172f, 0xa89af25e,
+ 0x77c38a6d, 0xb9c13d79, 0xe71deebf, 0xbd9c0898, 0x79f47dc5, 0x3e9706f4,
+ 0x970a31af, 0x1f24d197, 0x8f1489e2, 0xbffe2f28, 0x2a87188a, 0x90c0bc2b,
+ 0xeb913fef, 0xc2bafcc9, 0x944b0862, 0xf80e3e43, 0xec77f551, 0xb1b27d83,
+ 0x303cd507, 0xb44d27a7, 0x7a9fc17a, 0xf28ddeda, 0x0965d3ac, 0xbc0dcba7,
+ 0xd407179f, 0x55bf0114, 0x586e0b37, 0x5f43aa77, 0xbd86b9e2, 0x02517e8f,
+ 0x55b0b47c, 0x0f915b70, 0xe7e0294f, 0x17f5d095, 0xe5bf29f8, 0x0bbdda14,
+ 0xf8450b5b, 0x010ee17e, 0xc37bd213, 0xb6e95f4f, 0x59e3d388, 0x7009df80,
+ 0x8d75b376, 0x57b7a7c3, 0xfc037e4b, 0x5b9d8fc5, 0x56e0c59d, 0xde046aad,
+ 0xe77861b1, 0x3eaf3888, 0xbde3abc2, 0x98977837, 0xe4daf8e8, 0x220f1833,
+ 0xf27dc92d, 0x5c6dbe6b, 0xa1b49aaa, 0xa7c7a67f, 0xf3bd17ee, 0x951b8864,
+ 0x8e31920a, 0xedf18ddb, 0x8fffa01f, 0xf83fd7ce, 0x6eba2117, 0x09f1b9fd,
+ 0x67c9f7c4, 0xba00cd0e, 0x24517a2c, 0xce974a36, 0xe1091746, 0x0140483e,
+ 0x8935543a, 0x48f78c1e, 0x5ceb82a1, 0x65a8f8d1, 0x42ecd8f8, 0xd5b5583d,
+ 0xbf4e981a, 0x49fedaaf, 0x9d33d82e, 0xcbef7577, 0x19ffbf02, 0xf898e501,
+ 0x1f6173db, 0xfb624aa8, 0x6efc663b, 0xd8fad854, 0x1b31c3b1, 0x606841e4,
+ 0x82aa8be7, 0x946b64b3, 0x457bfc3d, 0x7be971c6, 0x7fe6d798, 0x30bcc05a,
+ 0x5cfa2f80, 0xd36f9e8b, 0x4bf334f1, 0x00e59aaa, 0x6aaa539c, 0x7109d2d8,
+ 0x5683aa92, 0x1baad75c, 0xb75c614e, 0xa8b3f378, 0x459bab7f, 0xe31c9f83,
+ 0x2188369f, 0x4d57f82b, 0x4ece304b, 0x1eb087eb, 0xe9a71f8c, 0xb45a8fcd,
+ 0x1fbb75b9, 0xa7f9e4e4, 0x529cf112, 0xf444a6db, 0x1fce1b53, 0x47f18a1f,
+ 0xd79ef783, 0xf9c13d1f, 0x318a6fe3, 0x521a479e, 0xf0a54fd1, 0xb1c59415,
+ 0xff7cc3d7, 0x807fe7ec, 0xd6c76978, 0xf000fecf, 0x99d7fe2e, 0xe282fc3f,
+ 0xbbb2ec91, 0x3f55ff41, 0x9bc636f3, 0x728eeff4, 0xf4f9d5bd, 0xeba71853,
+ 0x41aacf7c, 0x47ad9d6f, 0xaabc4307, 0xe997cb73, 0x6f2c9f60, 0xd6f6869d,
+ 0xfdc56df2, 0x40fb1c49, 0x036f812f, 0x9a13887d, 0x69b7b5e9, 0xf38060ef,
+ 0x6c37a524, 0x0be38609, 0x5e2c25c1, 0x42b8f2a3, 0x6c78fc63, 0xe9a11c4c,
+ 0x8ca66bba, 0x54d65281, 0xc27887d2, 0x978e945b, 0x8d7e81f6, 0x89ef6fcc,
+ 0x1fe1277e, 0xd5b24e94, 0x9bcfbf48, 0x31f1fde6, 0xed4a6b68, 0xea109e31,
+ 0x78f4de03, 0xc78a1bef, 0xdaf9056d, 0xdf8c27fa, 0xd3a6dd00, 0xfb3e7689,
+ 0x938860f9, 0x6fbb931f, 0x56d57dc5, 0x5797ee2b, 0xf28bbeb5, 0x75edb9d3,
+ 0x8f0937b4, 0xf09276bb, 0xf1938b1f, 0x8dead3dc, 0xe087162e, 0x853887f8,
+ 0x79cf889a, 0xb1f1823c, 0x29e8a71e, 0x7585713e, 0x6523cf28, 0x1b259471,
+ 0x298857df, 0x8f8c23ee, 0xd13df3ac, 0x1b83c749, 0x3a2e30f0, 0x0e3f16de,
+ 0x72cb8e14, 0x20fd017a, 0xa78e16ce, 0x8840fad1, 0x778404af, 0xd07d1c49,
+ 0xe9c59eb9, 0xfe63653a, 0x2c3e8449, 0xa26456fe, 0xdecf3eb3, 0xe0dea7d6,
+ 0xc9f8b6ff, 0x6c79c587, 0xbe3a9e2c, 0xe7c7af8e, 0xb7ef8559, 0x98215a5f,
+ 0x802a6ff7, 0x1d34971f, 0x513f2052, 0xf9f4c75f, 0xbc3b7076, 0xf31119e3,
+ 0xf707576b, 0xeb371ea2, 0xde70a58b, 0x3fbc0e21, 0x6d2ef0e3, 0xc744eb66,
+ 0x49c05756, 0xb3d8e9fb, 0x6979f903, 0x4fc521e3, 0xf0d7dbfb, 0x46fcc2bc,
+ 0x4eb03f26, 0xefe0a204, 0x2e776e78, 0xbb322f8b, 0xddce3cdf, 0xd3a79e56,
+ 0xea9c7f12, 0x718653c6, 0x0a83f916, 0xff3e97cb, 0xcf242778, 0x44efe82c,
+ 0x5f204c9b, 0x2c5044f2, 0x593fb78d, 0xdc799569, 0x74958eba, 0x25f3c4bd,
+ 0x449e762e, 0xde30514c, 0xfe35dcb1, 0x941a5260, 0x507e0a8a, 0x5fb64aed,
+ 0x5a9ffb5b, 0x36bbd006, 0xc78c06f9, 0xebf099d6, 0xc217734e, 0xd4f71339,
+ 0xaec031b2, 0xec937d66, 0x5fe018b1, 0xafed2aee, 0xd1573852, 0x275ce07e,
+ 0xef3c3491, 0x94962622, 0xb7447cc2, 0x138f6dc5, 0x659d9307, 0x17851bc4,
+ 0x9f3c6dd9, 0x57cebe42, 0x9f7d1fa1, 0x6dadb175, 0x3dba361f, 0xc495f002,
+ 0xaf0bd5f7, 0xbbbce377, 0x580d051a, 0xd563aa9c, 0x05f2ce9d, 0xdae8dd60,
+ 0x2e4b949a, 0x87890fc5, 0xfe0e27ae, 0xbddc685c, 0xaad1f41b, 0xa649e244,
+ 0xaab14672, 0x4e70398a, 0xc84db467, 0xf53d3e01, 0x5fb48bea, 0x60488b7b,
+ 0xa9cbbf8b, 0x92790be7, 0xe41cce41, 0x010bcc7e, 0x3526fe56, 0x5f39a702,
+ 0xe92bc084, 0xd3bc7391, 0x39c62744, 0xd113af4e, 0xc5c9159f, 0xfccc9bbf,
+ 0xf8001273, 0x88b27af9, 0x4a1a79c3, 0xc142bf78, 0x7f05da3c, 0x4420be79,
+ 0xf1a21d18, 0xf46a5a95, 0x89edeb17, 0x436fb0b9, 0xc8369efc, 0xfde0ae4b,
+ 0x9e332bf5, 0xe7e2a1f3, 0xcf52fb07, 0x7e6cffd3, 0x7fd07ec9, 0xa8f9de15,
+ 0x36cffbd7, 0xdb32039e, 0xe42f08ef, 0x7bb9500d, 0xe7b5884c, 0x5c1e5b2b,
+ 0xb1e0f90d, 0x0464f3fb, 0x91541be4, 0xa1f20d04, 0x077df6cd, 0xf1c84de8,
+ 0xe0271271, 0xd97d67b1, 0x87db7e0b, 0x98f26eff, 0x0b57e2f3, 0x2e8dfbc1,
+ 0xf058dfdc, 0x3f51db97, 0xf88c3359, 0xfc46abb5, 0xf198463a, 0x4bb3c468,
+ 0xb28de233, 0x787ce079, 0x3c6f1a4e, 0xb3c6655f, 0x0e1da844, 0xd0404af6,
+ 0xf931fe80, 0x11ebcd0f, 0xa6fcdeee, 0x8f5f1b34, 0x5fe95e38, 0xa99d2d99,
+ 0x533b806c, 0x985ca10a, 0x19cb28e5, 0x83dfe012, 0xf12b02d2, 0x7e85cd2b,
+ 0x8f9f0649, 0x73bec150, 0x00891c80, 0x047286af, 0xcf402827, 0x6e07c83b,
+ 0x7c85a7a0, 0xd919be42, 0x2cef3d33, 0x5cd0e97f, 0xe03ad5fa, 0xae514bdf,
+ 0x14a939d8, 0x06cda812, 0xb0dcd539, 0x367d076e, 0xf38242b5, 0x18ad44e6,
+ 0xddcce706, 0xc7903e58, 0x451aefde, 0x182c5f30, 0xfa0e9b3a, 0x291e7aa9,
+ 0x80f7fd03, 0xfc033dd2, 0xccedfbdb, 0xaec8b94f, 0xa5ff3ea0, 0x9cafdf5d,
+ 0xa9cb97fa, 0xc8b5763c, 0xebc39c2a, 0xbb64d96a, 0x22cdea00, 0x4eaef79e,
+ 0xc608bbae, 0x19916cef, 0xc0b6155c, 0xb7c7e005, 0x741eb8ca, 0xf3c64c56,
+ 0xadbb612c, 0x7613ed85, 0x78927cb5, 0xef3e947b, 0x22f87e6c, 0x6a3c3388,
+ 0x793fbf89, 0x9df2cdbd, 0xfaf0d4fc, 0x3f9314db, 0xe58dbd71, 0x94303c4f,
+ 0xf96963ce, 0x330ebe69, 0xe9c49879, 0xabfcd2fc, 0x5adbfe70, 0xe74f3fa8,
+ 0xfcde2251, 0x3ce84ba3, 0x312dbc27, 0xd33c4afd, 0xa3b3a4e7, 0x0efef03c,
+ 0x3e0065a2, 0x02214c26, 0xf784f3c8, 0x8febee08, 0x7e8f99a9, 0x94898bd5,
+ 0x4c5f29cf, 0x0b7ca16d, 0x89c3ae7a, 0x36d8fbf6, 0xc997c0c9, 0xc17bbd53,
+ 0x90771ccf, 0x771dbea0, 0x9e3ed8d0, 0xa71c4404, 0xd27cf8dd, 0xc6bd6331,
+ 0x1233f7c6, 0xf7f03a49, 0x8445afda, 0x689babab, 0xbb7ed177, 0xfde0062a,
+ 0xe1675d02, 0xbf2d1494, 0xade34b16, 0x8c6d2bf3, 0x08551e2f, 0xce8f2fae,
+ 0xc13ee277, 0x9855f99e, 0xcfc5fd27, 0x9de243bd, 0x4bd28bbb, 0xddff6c49,
+ 0xa7814493, 0x604abd7c, 0x8ccbaef8, 0x4bd297de, 0xbe758f9d, 0x7339f9d6,
+ 0x5e37827e, 0xcec38ade, 0xf9a29dec, 0xfc050423, 0x01025db2, 0xe5de76bc,
+ 0x9b5fe435, 0x2bb93f4b, 0x6ea9e00b, 0xb676833e, 0x1e7e25ad, 0x225b06d4,
+ 0xf2eefbf3, 0x8d7c84af, 0x04a1529f, 0xbf73d8fd, 0x5aafd16b, 0x88534103,
+ 0xe6ead9eb, 0x79a7b9e0, 0xe201b236, 0xe65d52b0, 0xfbe02eb5, 0x53572be2,
+ 0xb32b1f78, 0x951f9d20, 0xbfdf8435, 0x2f8c1084, 0x077e4c48, 0xa3eb20ce,
+ 0xda357fcf, 0xb46d9b0a, 0x1b9b66df, 0x6af54ffb, 0xfdafc002, 0xc1127ff3,
+ 0x673ae99e, 0xe00e3a45, 0xddfe8ffe, 0xaf66369b, 0x6cf762dd, 0x9527fe05,
+ 0x9a1f2869, 0x48ad5137, 0x14a07385, 0x4fe271ef, 0xe29a5dba, 0xc28dbaa5,
+ 0xe0b4e293, 0x78f110be, 0x979eb754, 0x517bf840, 0x024240f2, 0x5d05bc81,
+ 0x422d0a9f, 0x7ff945c8, 0x0219cd8c, 0x92a5233f, 0x60829bce, 0x5fd63627,
+ 0x3e11d49b, 0x907986c7, 0x200b2f94, 0xde609df9, 0x415a2403, 0xd59ebaff,
+ 0x64aaf3f5, 0xd566fa82, 0x96a05283, 0x6a4eb3f6, 0x24fc43b7, 0xc116a3db,
+ 0xa48a7356, 0x41baf9e2, 0x1d1e4c95, 0x87278f39, 0xec2a15ed, 0xde25ffa3,
+ 0xef8e2f16, 0x8b757ce6, 0xe03efbdd, 0xf77f773b, 0x346b301e, 0x7b4f1b3b,
+ 0x79f686d9, 0x3b706f58, 0xbbaf84ac, 0xfb653e13, 0x397424c6, 0x71e863e6,
+ 0xa0deb37a, 0x08a6f072, 0x44a9f572, 0x87943cf0, 0x4f40affe, 0x1fd288c9,
+ 0x682c9d7c, 0xb68bd9ae, 0x2f6a389b, 0x57a4e3f0, 0x8c73ecf0, 0xc077191e,
+ 0x7ef00b5b, 0xe661fd57, 0x2a21d187, 0xa33e9c8f, 0xec173854, 0xfda1d70e,
+ 0x937d265f, 0x3fa63e56, 0xcf9cb5da, 0xe5d5f8cc, 0x79ef2cda, 0x56bdb42b,
+ 0x488035ec, 0x84438f30, 0x0e6a1c08, 0x2203a3e8, 0x855df7d8, 0x5c285f94,
+ 0x28ee411b, 0x0d9f26bf, 0xb37c095c, 0x3b0ae5b6, 0x5e77c7c8, 0xebf4423f,
+ 0x7fe3b8a8, 0x7681de88, 0x08983f96, 0xfbba5878, 0x423f5f2c, 0x5d30e748,
+ 0xc7447ca9, 0x37be7443, 0x172eb9f3, 0x394070b5, 0x009b9d87, 0x104288fa,
+ 0xeb256b09, 0xe8a760dc, 0xd86d75f6, 0x7cc64d9e, 0x366ee5ef, 0xdbacad5e,
+ 0xe60d9ae5, 0xd455dcbb, 0x2efb7cff, 0xffa8e7d5, 0x5d2f9512, 0x7fa3752d,
+ 0x214e7d56, 0x81efd481, 0x7a3a16af, 0x455f01ba, 0xf8b17ef6, 0xd472081a,
+ 0xf9cbffef, 0xcf9e6cdc, 0x3e646a3d, 0xc5f78893, 0x0a17aa76, 0x64cfacee,
+ 0xcade417c, 0x7e0be688, 0xf927b1de, 0x1be54f1e, 0x7918c7dc, 0x84f1c936,
+ 0x96c72a16, 0xe4d63958, 0x4827bc32, 0xbea0756b, 0x59f5cb33, 0x076aaf3e,
+ 0xa24dfbc3, 0x9f3067f7, 0x60f74b6a, 0x955cbbe0, 0xc0a74ea4, 0xe88b36e6,
+ 0x54b69007, 0xbb123ac3, 0xdc59fbbe, 0x7a07af8a, 0xa668529c, 0xb3e74d7c,
+ 0x0bbdeec9, 0xcdd6a5e4, 0x58384afc, 0xa3707604, 0x3c377bcd, 0x12d85077,
+ 0x88c75ce0, 0x838b3650, 0xd4720c84, 0x4c38dc93, 0x490c1172, 0xe9f93eb8,
+ 0xd08174fa, 0xf6c53c33, 0xd52f0664, 0x0c7f6016, 0xb06c202c, 0xf9f304a5,
+ 0xf3b2e606, 0xd8f303f8, 0xd84f59fd, 0x91b9bad9, 0xd97a07af, 0x075b2b68,
+ 0xe2259378, 0x777de6b7, 0x885401b8, 0x7bb26e0b, 0x6cfe831e, 0x479c1ea5,
+ 0x02689b96, 0x292ca3e5, 0x53fec028, 0x605562ca, 0xd6c240f1, 0x7f692813,
+ 0x42d5d359, 0x20b28f58, 0x07de0097, 0x9c8e263b, 0xefe5dab4, 0x8e6ac717,
+ 0xb95ba3b1, 0xe853ec1c, 0xb3a7537c, 0x3c70e43c, 0xf80f8286, 0x80dd74ed,
+ 0x9cfced93, 0x93f835e5, 0x7ecd9e19, 0xe60c1015, 0xddfaf125, 0x29ec910a,
+ 0x2df8f7e8, 0x86c59df0, 0x68838f7e, 0x078bd041, 0xce5ceced, 0x035b416a,
+ 0xdd48dff5, 0x40b7b836, 0x2607ebe7, 0xf449ab5f, 0xa729c495, 0xa517c173,
+ 0xf026fe7c, 0xd3e4e75b, 0x0ce157c3, 0x7e3307ba, 0xbc8688f3, 0xcd6e9d47,
+ 0x766e81b2, 0xeb447388, 0x7e829761, 0xa090a77b, 0xb9d39f81, 0x0a706050,
+ 0x2a179e36, 0x5c2fe319, 0xfdfae9cf, 0xe9bcd82b, 0x8ff1f307, 0x6c567bc6,
+ 0xd1e00d9a, 0x1b9f0fe1, 0x31eb9d32, 0xc8c9fb9f, 0x3263c709, 0x4cab4f31,
+ 0xc852bb81, 0xda0716e9, 0x4c89d555, 0xd0fccdae, 0x79c2941f, 0x7c50cbce,
+ 0xedf4097d, 0x8324d72f, 0xcb7fed1e, 0xafa044e1, 0x825d0f19, 0xd83ef47f,
+ 0x1c9bfab7, 0x2f5b7f77, 0x94063233, 0x91999d83, 0xfea58199, 0xc529debc,
+ 0x26a5ef8d, 0x6bb8cf7c, 0x46dbe580, 0x026a6bf1, 0xf7a4efed, 0x283c778d,
+ 0xf718ddee, 0xf8604fae, 0x3c7457ae, 0x672049aa, 0xc496ba91, 0xb32779ce,
+ 0x8cdc1c7b, 0xb67d6b9e, 0x7e8a4972, 0x467683cf, 0xf2b9e23f, 0x6b025046,
+ 0xf909b265, 0xf465c59a, 0xe8aa5c7c, 0x1992fd18, 0x8df5bf5c, 0xff7d872e,
+ 0x9c6484dc, 0xd3b5d9ef, 0x7274bc70, 0xc5387d97, 0x8b32fceb, 0x939af106,
+ 0x089eff73, 0x66e6ff47, 0x3c1015b5, 0x1ab35a62, 0x16ffaefc, 0x9409b9bd,
+ 0x54f5694e, 0x3e32a511, 0x74a3b900, 0x13f712b9, 0xe6e258e7, 0x604d8ddf,
+ 0x76a7f57e, 0x919b8e37, 0x22bcb831, 0x103eba3f, 0x23f3a4e9, 0x8accc395,
+ 0x61739131, 0x24a63f94, 0x2ea791c4, 0x7ec33499, 0xd30fae80, 0x7d75fe38,
+ 0x1a43cbac, 0xefec19c8, 0xa8fd5195, 0x7f2873d3, 0x90e31d35, 0xfcb427f8,
+ 0xf3b04bf9, 0xa114a713, 0xbff2a3be, 0x0465e506, 0xd076dfd3, 0xc7f151a7,
+ 0x0777d6ae, 0x87debec1, 0x05c679ff, 0x90ff3bfb, 0x3fa05dba, 0x4df2fd8f,
+ 0x7c11e417, 0x87164bf8, 0x1fe4d5b8, 0x9e981379, 0xcd94260f, 0xe6dd7982,
+ 0x378167fb, 0x0ac92f8a, 0x90b15fb6, 0xf3c6bb2e, 0xbcf3c683, 0xf3e6824b,
+ 0x77ec7ebb, 0x8e3f1489, 0xc3a708fe, 0x4af5c6c2, 0x7be30a96, 0x8f3d0217,
+ 0x58efff71, 0x4367bb13, 0xe36e6787, 0xa27c0568, 0xf958b47f, 0xcc9b76be,
+ 0x74cf05d6, 0x72f2a7d8, 0xdce199bc, 0xfd81cbb7, 0x44447bcd, 0x1d0e64bf,
+ 0xafd5056b, 0x679616de, 0xbcc79e6b, 0x3812d50f, 0x5eef3f2f, 0x785dfd01,
+ 0x9d7497ff, 0x07b8aef2, 0xf3ccb3f7, 0x603fdf34, 0xfba4b73e, 0xfd380b49,
+ 0xe517882b, 0xa20f262f, 0x9b3bed85, 0xf7a77ae3, 0xfe6038e7, 0x3f7025f7,
+ 0x838c80a3, 0xfbad877c, 0x2f9d2687, 0x9f83aacf, 0xf3c13ed7, 0x08f98f33,
+ 0x5412b396, 0xe5ba2e76, 0xabe012f5, 0xf05bcda5, 0xab6f96be, 0x1cb4966f,
+ 0x8931fc4f, 0x1f6a1de8, 0x21fe07ae, 0x3760c15e, 0x467f5d2e, 0xc32c7e61,
+ 0xf9fccdc3, 0xdc5f30cd, 0x72f76527, 0x3e58bcdc, 0xcb9f7d1b, 0x7cc609d3,
+ 0xf9f08eeb, 0x258f3673, 0x9f481f7c, 0x679f999f, 0x5e78b025, 0xd5f2c6c5,
+ 0x6b94e803, 0xe60e8f5b, 0xdf300ae7, 0x3317e75a, 0x65202c3f, 0x14429925,
+ 0x8d7e5bdd, 0xa9f4ea70, 0xe7c39ba8, 0xfbe0cfe3, 0xe710196f, 0xcc0f8de9,
+ 0xdb94eef4, 0x9a7c8307, 0xc3d9dde9, 0x09adf0f9, 0x50afdd6c, 0xffa0253d,
+ 0xd5b291e6, 0xe3bb28ee, 0xefb75498, 0x1b372017, 0xad46df19, 0x7b38cca7,
+ 0x79f5c645, 0x0fed4b99, 0x1d210cf7, 0xbdfec026, 0xe9ef0fd5, 0x79f11ce3,
+ 0xe01261b4, 0x13cb14b9, 0xd86d32be, 0xfcfb48b0, 0x4224cf47, 0x046bb53c,
+ 0xa74b78c1, 0xc7ef08cb, 0xf3c22209, 0x62c3a731, 0xef5feda9, 0xd8d9ce83,
+ 0x47097986, 0x9af1e6be, 0xf1a5adaf, 0xbe4ff9e6, 0x9f7e11fe, 0x6e5cadca,
+ 0x36e1ff74, 0x5b5bb74e, 0xdcf3bed8, 0x0f48e575, 0x0720fdf3, 0x16497704,
+ 0x1c1bcaed, 0xcdfd00ad, 0x5da799f4, 0x6bf41c71, 0xfdc89d0c, 0x98bd2f9c,
+ 0x2f51534f, 0x4cc27c62, 0x9b870abf, 0x35abcde5, 0xea2d6fe8, 0xe55dcf41,
+ 0xafae7a60, 0x63cf31f3, 0x7a80934e, 0x82ff0ccf, 0x0f572b8d, 0x367f3020,
+ 0x8479d8bf, 0xe19ea206, 0x55e7d4f3, 0x473c3441, 0xd38fb31a, 0xce89397e,
+ 0x72d85cab, 0x2ec1e63b, 0x2c27f3a5, 0x1bf183de, 0x5e1d7e1d, 0xc44a3cf3,
+ 0xf106d90e, 0x068215d6, 0xdef636fa, 0x5ee18f16, 0xbb0d39a8, 0x8efd0207,
+ 0x21abed48, 0x2fc47bfe, 0xf5d6ffa0, 0xb445c101, 0xfb808d6b, 0xafd23d5e,
+ 0xf4ede585, 0x051ac74c, 0x58aa39ee, 0xe3a5c427, 0x6d42fa82, 0x59de9458,
+ 0x1b52b818, 0x88378066, 0x1a8b1c79, 0xa7cf0dca, 0xb8fa8c38, 0x35237937,
+ 0x74d2f3f1, 0x4de5d2f9, 0x870abf97, 0x52ffe2ca, 0x36565f60, 0xd107e9e8,
+ 0xf67aa0cf, 0xc38b076a, 0x7d23703c, 0x67a3e965, 0x79fc710c, 0xe67d19e3,
+ 0x79f1d389, 0xc503eb4f, 0xcedf4183, 0xedf51872, 0x3e8f9df7, 0xf42e5d0f,
+ 0xc2e599f9, 0xfe3d7f8c, 0x1983a665, 0xd81700ff, 0x1d5a07fb, 0x9004bb81,
+ 0xbfa70677, 0x76708ed5, 0x70691466, 0x7c00e59e, 0xd2dcf540, 0xfd631fcc,
+ 0xb96cb126, 0xee34fd03, 0xf3f16907, 0x0ff6c26d, 0xfec463b7, 0x1e301196,
+ 0xc8341311, 0x2cb3170b, 0xbce95b35, 0x1cb421c4, 0x9ac1e905, 0xeb9fe708,
+ 0xe1132f8a, 0x7e5a86de, 0xc2d6ba3e, 0xfde96dce, 0x75b071ad, 0x39772f49,
+ 0x683b56ca, 0x6b5f27ff, 0x78b0702b, 0x3819fa2f, 0x93ee114f, 0xd8317ea4,
+ 0xcc132fb3, 0x234bcd4f, 0x0ebe817b, 0xf20f19e2, 0x85238cfd, 0xfb655f9f,
+ 0x0b2ff46c, 0x796acd4a, 0xf908d55e, 0xa6077dfd, 0x5a703dc1, 0x6ccee592,
+ 0xf1c27f5a, 0x5967ab3a, 0xa9bb64ce, 0x8378edff, 0xce5a47d5, 0xa7f5a50c,
+ 0x3ab26f1c, 0x0551086c, 0xade3b4f3, 0x3051fe69, 0x3fdf9b8e, 0xf20919e0,
+ 0x5f985920, 0x3051ed2b, 0xa3efacfe, 0x2c06a2af, 0x00cfaff8, 0xba9f82ff,
+ 0x0e4fe8b2, 0x7915ef88, 0xbf1fd854, 0xfdb6821f, 0xe3a97bbe, 0xf0587455,
+ 0x01280a5e, 0x3e385bff, 0x2690ba75, 0x23c848cf, 0x48cf4124, 0xe5d877d8,
+ 0xdd0136f0, 0x5db40ff3, 0xf4d47206, 0xf00bdfc6, 0xac21ccfe, 0x28ca7c9f,
+ 0xc9e6df70, 0x8fad0617, 0xe5dbbfde, 0xf401dc28, 0x3b4064a1, 0xe4dd5041,
+ 0xd4176a66, 0xc95e3f52, 0x68c47f01, 0x7e713787, 0x6ca12d7b, 0xc0d9f237,
+ 0x8e1fd310, 0x8fd0bdb2, 0x2da4572e, 0xa77c4fa5, 0x4110aee4, 0x3564a63f,
+ 0x720b9c1f, 0x9cecdff8, 0x60f1e0ac, 0xf0e6dbfe, 0x3f6c20fd, 0xe9fb01dd,
+ 0x9235afa0, 0x71e74fe1, 0x238f1605, 0xfe510569, 0xfd079f05, 0x37dc2a7e,
+ 0xf6c1ce32, 0x44bce95b, 0x13461f58, 0x887ccb15, 0x6a00e413, 0x49df58bd,
+ 0x417f0782, 0xcec87ffb, 0x035b74fc, 0x2c5dc431, 0x5f7eb64e, 0x7dd992e8,
+ 0x5af0722d, 0xa709e3d0, 0x78f41b88, 0x848ae3d7, 0xfb9218f9, 0xb09fb847,
+ 0xde0042cf, 0x1b80e4a7, 0x17ddd9e2, 0x1206ea49, 0xd38bafe9, 0x21f7ef5b,
+ 0xe208bd45, 0xcc5ca31d, 0x90aa78be, 0xf768fe60, 0xfb002571, 0xb659294c,
+ 0xfabf689a, 0xef7b072b, 0xcfa2a4d6, 0xd6c11e81, 0x8fe30204, 0x440d45db,
+ 0x353f874a, 0x1f81d9e6, 0x288e0336, 0xeeac521e, 0x94bfa03b, 0x6cde1433,
+ 0xfc41ee7c, 0x24e8ea4a, 0x5789df8a, 0xbfb85539, 0xf07b29e1, 0x7b9fcc2a,
+ 0x24f782d6, 0x72b4566d, 0xad3e6fa8, 0xf35e21ba, 0x01307654, 0x05acf3e7,
+ 0xa139b3e7, 0x1465e2fb, 0x608d5fee, 0x20e4bf7e, 0xe4052d92, 0x83bd48a8,
+ 0x32704f3e, 0xc2cab87d, 0x938a68e4, 0x0243cfc9, 0xde0f3f1d, 0xd1f9442b,
+ 0xbaba1bf3, 0x7e8879d9, 0xc089b7d7, 0xbae509c7, 0xc1121e3f, 0x465c9e8f,
+ 0xec9cfd70, 0x3a2a0394, 0x1ce71e9f, 0x08cbff4a, 0xfb2e1f5b, 0x5fc63160,
+ 0x82de0529, 0xebd80bdf, 0xf052f7e4, 0x39cb987d, 0xed214c9f, 0x53e7ac22,
+ 0x442d11ce, 0x9cfcbbc7, 0x9f3d7714, 0x527dfbc6, 0x7d125220, 0x2aacf0af,
+ 0x1215df01, 0xad3b7ae3, 0xc438e4be, 0xa66d8b7b, 0x235eb0e7, 0xf4091e3c,
+ 0xb1b734d7, 0xaf93a47d, 0xe0c9834f, 0x3d1abce8, 0x1c4d3e6e, 0x0bda28f5,
+ 0x78068aa5, 0xbcf4e2d9, 0x7e44fb0b, 0x2f9e26ea, 0x8fa4f33e, 0x388d3fe5,
+ 0x72f18097, 0xe04e9fca, 0xebeb8b8b, 0xef3a76fc, 0xfeb1878b, 0xaf410f81,
+ 0x5a78f85c, 0xf7f9e82a, 0x4bd1beb9, 0xbf80ef9d, 0xbf8c49dc, 0xe44697dc,
+ 0xc49214b3, 0x0de446c6, 0xd9fa0ef8, 0x8a6e0729, 0xa92f7e7b, 0x0fd9d4a8,
+ 0x4ed041e6, 0x36d32fbe, 0x1f4ce41b, 0xe32701e7, 0x7ab9736b, 0x10ddb2e5,
+ 0xce7ff707, 0x03a98bd6, 0x5a1e61ce, 0x62488fd8, 0xd6ad567c, 0xf203375d,
+ 0xc6329c62, 0xf9f9d3bb, 0xc97e68ab, 0x9d17e28c, 0xcc9d3aef, 0xa7f9d68f,
+ 0x989bc778, 0x39fc5fdf, 0x126cee21, 0xfe7507b6, 0xf8cfccb9, 0x6cfdb2f0,
+ 0x7f8de89d, 0xa9eedd3c, 0xf8631ea0, 0x9be33f66, 0xf81fca22, 0xf03d10fb,
+ 0x966f998f, 0x5f37caf5, 0x967e0227, 0x779f16b7, 0x67d9a59f, 0x973393cc,
+ 0xf3f11c13, 0x624d9f28, 0xa943b1fc, 0xe82e51fb, 0x1a2dab8b, 0x15ca03e8,
+ 0x3e52d759, 0xdfa091df, 0x03935a7b, 0xd3122df5, 0xac5a5b3f, 0x38b67fa8,
+ 0x678c5ebd, 0x68f3b065, 0x43b6f244, 0xc036b41e, 0xf3df46a6, 0x8d93a57c,
+ 0x13439413, 0xf41d828e, 0xf1ff4617, 0x8dc1e757, 0x82b32430, 0x31cc61d1,
+ 0x0d98bd65, 0x8f853be9, 0x00bd7f00, 0x577e833a, 0x73c1587d, 0x2b0f4bfe,
+ 0xd85f17a8, 0xc4097af5, 0xcb7cf48d, 0x2f5f3b71, 0xef051a29, 0x9c7b3e33,
+ 0x8ebd63eb, 0x27a0e7a9, 0x4ea6f74d, 0x997f4c20, 0x032d3def, 0xb48dc9fe,
+ 0x9d03ef9b, 0xd61e4545, 0xb5db6b9d, 0xcc16a069, 0x0ace81f7, 0xfff6855d,
+ 0x699e83cc, 0x7dce352e, 0x6e1f9ca0, 0xc1db6d20, 0x4fdf3525, 0x6de7d749,
+ 0xaf93ff30, 0x2f881484, 0x919a9506, 0x9aeebeec, 0xba3fd01c, 0xc51fe1dc,
+ 0x11c3f05b, 0xbf68fb86, 0x5fbef3e4, 0x08bdd893, 0xbfee0aed, 0xefb09afc,
+ 0x7add7c82, 0xdde2c9d3, 0xbb9fcb79, 0x7e61f409, 0xb9f707a5, 0x9f98934a,
+ 0xb2121bfc, 0x34bd00e5, 0x41c8e309, 0x2a3e2d59, 0x5223de44, 0x0f3808d9,
+ 0x425fb3b5, 0xb9af8c3e, 0xc138efbc, 0xf7ba90ae, 0x26e377c3, 0xde83e5e6,
+ 0x955e8e76, 0x0e98eb0a, 0x74ab8537, 0x87023393, 0xbe5ed70e, 0x39ae68ce,
+ 0xe1fcc0ef, 0xcd43d03b, 0xe0d88e87, 0x820f9d7b, 0xfd18a7ad, 0xe801f8a3,
+ 0xe107e11f, 0x78eba836, 0x87e707f8, 0xfc6dff2f, 0xf159fd40, 0xfe00fc3c,
+ 0xe2f7e260, 0xe689ff87, 0xfdaf6a07, 0xaf6519d3, 0xa7961505, 0x3e75d7a5,
+ 0xc428e458, 0x608534f7, 0x65d905be, 0xe2dfbf67, 0xf038c64d, 0x46366ef3,
+ 0x064787d7, 0x76e22f83, 0xe37930a5, 0x0e8f5df7, 0x8e576809, 0x66e10aa6,
+ 0xa206e3b4, 0xbe38d43e, 0x804111c8, 0x1730ac7b, 0xcbec0b37, 0xc5c82a50,
+ 0x10f4eb68, 0xc756fff0, 0x1f605965, 0xe72639e6, 0x1f6d7f00, 0x5815fcb1,
+ 0xa80fb6b2, 0x1aa37e7c, 0xbd749fb1, 0xab7797b7, 0xc5c43f8f, 0x0f72e1f8,
+ 0x7a014f3b, 0x5d0e1a3b, 0x005903ff, 0xcb34210e, 0xf5038df2, 0xe83b4b75,
+ 0xe2838073, 0x9a40b775, 0xb4283ec0, 0xc18ad278, 0x9217ebce, 0xd6aece00,
+ 0xbc43072f, 0x9fcb7a68, 0xd3bc020f, 0xcd267df5, 0xb664cfb8, 0x477b75a3,
+ 0x7b742bf7, 0xd088a248, 0xb76826ed, 0xb86ee7f0, 0xafd61b1f, 0x71cf0d90,
+ 0xbd5a743e, 0x57e5c3c8, 0xce98f3a2, 0x690d71e7, 0xd7c8b843, 0x99337cdf,
+ 0xc70667d2, 0x24fdf4c7, 0xed0b9094, 0xf14d5c84, 0xfc44b570, 0xab9c7449,
+ 0x1c7c8135, 0x8cd727c5, 0xefe1d637, 0x3f48f4b2, 0x5e6fbdbd, 0xe299261f,
+ 0xdcb7dff1, 0xabe763ef, 0xe763eaff, 0x150e2767, 0xa82c12fd, 0xb9d933e3,
+ 0xc3c33759, 0x7afe257e, 0xc98b88f5, 0x7b4b44f1, 0xdc1b9c2e, 0x5c2bf3bd,
+ 0xfcecf71f, 0x13b01dea, 0x08971c27, 0x3c4e01e4, 0xf709263e, 0xe067c73d,
+ 0x6fde9d3e, 0x0e4da7f5, 0xff239ec2, 0xef82f7e8, 0x1478f0a3, 0xe586cf80,
+ 0x3d0f1d8b, 0x3d9dfd0c, 0x3ce8912c, 0x3bc512f3, 0x2569e20c, 0x7df87efc,
+ 0xf497b302, 0x5efc7df6, 0x5972ffe6, 0x9b6b7ef8, 0x625efdc4, 0xd5f3a28d,
+ 0xe524f354, 0xf57ae845, 0x52e3d2b1, 0xe07d2c6e, 0x0f9d63ef, 0xdc6793cf,
+ 0x579fa95b, 0x23f8e3ae, 0xf3c3df7b, 0xdd345700, 0x7e7d8121, 0x3c488645,
+ 0xa95ee351, 0x2a3e0f52, 0x8b8f71ee, 0x76eae5e7, 0x1fa7deca, 0xf706919e,
+ 0x7a988859, 0xe5b2dd55, 0xb7a85c95, 0x71cf7189, 0x457bf19b, 0xf0121dcb,
+ 0x262e17ff, 0x3f8dbd1f, 0x27ca62f1, 0x09dd0297, 0x040af3b3, 0x7d332394,
+ 0x7dfcecf7, 0x9ea8fb6a, 0xfd13ddf1, 0xb17874cd, 0x2ff708a3, 0x9987a37a,
+ 0x79d1776f, 0x42fce9fa, 0x6a7e9e74, 0xb9f1ed8f, 0x2f92feb1, 0xbf3aeb03,
+ 0x913eb756, 0xce9cf60a, 0x1952d3a7, 0xf1d84cdf, 0x46712a70, 0xdbc665e8,
+ 0x66fd395f, 0x0ce66d11, 0x826dcffa, 0xe17d42e6, 0xcf906d27, 0x9c61c652,
+ 0xda0956f5, 0xcfe7841f, 0x59b1d79b, 0xd7bc28e2, 0xd97bd7ba, 0xa0ca1587,
+ 0x15ebcd6e, 0x7c0e17dc, 0x4aa75e6d, 0x7049d40f, 0xb48958ad, 0x6e31e99c,
+ 0x9970eba7, 0x2936fce9, 0x04f479c3, 0xcc0f99a7, 0xb9f6eaf0, 0xc5394f7e,
+ 0xda14b4c7, 0x216ab5df, 0x1d662fce, 0x69e978e6, 0x5e69edfd, 0x7ffc4d47,
+ 0xd7d4d8e6, 0xc93dbd00, 0xe66e999b, 0x947f5d76, 0x587900c0, 0xf91ec1fa,
+ 0xf48e95c2, 0x10a7392d, 0x0f1bec0f, 0xa24f93b4, 0x7d3221d6, 0x9ddbf208,
+ 0x27acf66e, 0xce7a5b7e, 0x11a9bc42, 0x1f9b93be, 0xeddf0074, 0xb01cea90,
+ 0x59c533af, 0xf1449b5e, 0xa2d3f535, 0x74bcf1eb, 0xc84085bb, 0xa9cb5a6c,
+ 0xa84710bd, 0x9f30483e, 0x7765a8ba, 0x4be9f031, 0x51fa1b52, 0x7909675d,
+ 0x6cceca30, 0x8075a96e, 0xc69cd61d, 0x4bed03ce, 0xcdbc8626, 0xbf191247,
+ 0x3d3e1f36, 0xfda713c3, 0x8ebf6f00, 0x7172d278, 0xfc61765d, 0x058d64a3,
+ 0xd0553fe7, 0xbb034e5e, 0x0f7646e5, 0xb8eb5763, 0xbc28d397, 0xa324b79d,
+ 0x7cd6999e, 0x4a6e1dcf, 0xf33fe088, 0x1cf779f1, 0xdf40db41, 0xac35512b,
+ 0xe3645497, 0x7fb8f8be, 0x1d375ea5, 0xd194afda, 0x2e2699bf, 0x751e2096,
+ 0x03c84332, 0xd0a7717f, 0xa77e12be, 0xc6ce5fcd, 0x2a7f6e21, 0x4c6f9ff8,
+ 0xbf8d1d4f, 0xf5eaa26d, 0x6bf7f00b, 0x5b4fc988, 0x6eccedbe, 0x3e5f6d2b,
+ 0xc77cc053, 0xe22cee69, 0x929fe28f, 0xf99e9435, 0xfa5b2f94, 0x5f5f0117,
+ 0x673c6a57, 0x41ccb335, 0x63f1d102, 0xc2c32dc1, 0xb5e78fb3, 0x7efc0b76,
+ 0x57e72e59, 0x359f7e71, 0x5df0d53b, 0x66766139, 0xdd9136f5, 0x7ec85257,
+ 0xaf975127, 0xbc39711f, 0x37c7fb8a, 0x700cb37a, 0x0d28874c, 0x693334fd,
+ 0xd75dda28, 0xe5c76d9c, 0xe0fc5cb9, 0x78e89bad, 0xf2611a3f, 0xabc5c56b,
+ 0xd8322f90, 0xc84cca7e, 0x6f41122e, 0x66bbdf1a, 0x471eb1bc, 0x27abcf8e,
+ 0xb3307d74, 0x9bfdc455, 0xcf148599, 0xd3b18902, 0x18beadbf, 0x865ed167,
+ 0xe7b5d078, 0x04bbf83c, 0x83e2fa31, 0x2fa4efd2, 0x3832a05e, 0xd2f5ca9e,
+ 0x0fdfee44, 0x6f408322, 0x1f1b134c, 0xa2ea3e06, 0x0e35a6eb, 0x8eebe91f,
+ 0x5097efee, 0x21be0639, 0x8f18691d, 0x032e769d, 0x7f7449f3, 0xa847ac3f,
+ 0xb1c5a25d, 0xcc4bee97, 0x1307dc31, 0x76512bd6, 0xfdf05c89, 0xd46992ed,
+ 0x00f2551e, 0x9fc481be, 0xe30cfa8f, 0x70902592, 0x8cc1f102, 0xa9e71853,
+ 0x8affa896, 0x4c13f3eb, 0x097fd1cf, 0x30f91129, 0x9c7a2bdb, 0xdba49ad9,
+ 0x093e4653, 0x97af1bc7, 0xf3a3ee31, 0x13e00949, 0x117affe4, 0xf1bd3ae3,
+ 0x6f7e3e8d, 0xfaa212fc, 0x0f384928, 0xfbf970bf, 0xbcf2fcb6, 0xc8c327ce,
+ 0x89f0beb0, 0xbf3a1fce, 0xa609d8c4, 0xeb4f5078, 0xe9894bcd, 0xd69edf88,
+ 0xc847979b, 0xb37bd7a8, 0x3126766b, 0x744aee3d, 0x5d577f63, 0x7609d334,
+ 0x11eb958d, 0xc70add7d, 0x9f19eab5, 0x573edcbc, 0x6aa3fd82, 0x11d91fd0,
+ 0x60f1e83a, 0xae972f9d, 0x9cff1821, 0x6756f5ce, 0x56078b2b, 0x7003154f,
+ 0xe5b8a284, 0x9d5987c1, 0xd3a2cbdd, 0x27ce6af7, 0x096ed285, 0x1af3777e,
+ 0xbe20d04d, 0xc4f1e1e4, 0x8094e719, 0xafab1d9a, 0xc75fba74, 0x0bbf07bf,
+ 0x23c6bfde, 0x1c4ba804, 0x3baecfa3, 0x188aecc7, 0xcfbc2a7b, 0x891e62ab,
+ 0xeb4e5f99, 0x86421f74, 0x0aed3bfc, 0x76fce921, 0x6f7dfe85, 0x1e064e74,
+ 0x65ee7a06, 0x1d80aef7, 0xe2be740f, 0x3afd849c, 0xccf18c93, 0xbf791db3,
+ 0xbf93df41, 0xcdafbe6f, 0xc6de9f3c, 0x17f746ff, 0x8fa0ffb8, 0xcec4957b,
+ 0x27d79bc7, 0xd75e9c7d, 0x99bdfe23, 0xe293c37e, 0x3eba7ddb, 0xd73fc18e,
+ 0xafd13dd7, 0xebad7d37, 0xbeb77fc5, 0xd7d7fbd6, 0xb35c7d13, 0x8fc9ef1e,
+ 0xeaf2f5d4, 0xdf8c16f5, 0xfafee14c, 0x9e2f1e14, 0x6ce2c499, 0xeedeb8b3,
+ 0x0166dcfa, 0xb3282ebb, 0x6eff30fd, 0x36a1c627, 0xd0f662ef, 0x724e3c9b,
+ 0x9c6220b7, 0x16b1eee4, 0x17d4dbd4, 0x4b7987ca, 0x808c8445, 0x2c01dcfd,
+ 0x8528df4e, 0x6bef50ca, 0x6f738112, 0xefdfeaaf, 0xfd04dff1, 0x70f1fddf,
+ 0xa3c62d4b, 0xc7e06d43, 0x7093cb8f, 0xaad92c5f, 0xb3bafc62, 0x03f78ad5,
+ 0xd9f8ed75, 0xf9fa196e, 0x5ae0689c, 0x0d6ad4be, 0x1e814bef, 0x101e2699,
+ 0xaba33f21, 0x59fde09b, 0x8a876793, 0x429b3fc1, 0x0e216ada, 0xf9615130,
+ 0x3d3c66e8, 0xcc31f7ca, 0x7de114fb, 0x9f665689, 0x7644bb15, 0xfb4f580f,
+ 0xe60acd12, 0x2fb6f757, 0xa0967851, 0x2fb3169d, 0xd2f4ccd1, 0x9897ddb7,
+ 0xdf87b808, 0x9ff9d367, 0xc3d227eb, 0x8566c4fe, 0xbf7567ed, 0xbfb0132e,
+ 0xb8b4b1c9, 0xf6dea371, 0x4aec7629, 0x1d3dc0f0, 0x4deff99b, 0xc035d8ec,
+ 0xfcf6e6a3, 0x777b6e7e, 0xcda4a811, 0x984ad78d, 0xb9e3c6f7, 0x19a0b8e1,
+ 0x66ff1caf, 0xc8156e7c, 0x07c4072a, 0xe0a9b45b, 0xbfb8f517, 0x71c1edd3,
+ 0x5d478afa, 0x491f364e, 0x6f9f00f0, 0x03c0323e, 0xfc003fe3, 0xab59710a,
+ 0x93f015fb, 0x9d3e1c77, 0x8abcfb80, 0xa4bf0547, 0xb1a6d93b, 0xef8c8973,
+ 0x03c39983, 0x9abd0fb0, 0x84e6f9f3, 0x4c8ebfee, 0x61afde8b, 0x39fa33fb,
+ 0x60855aff, 0xc2df883e, 0x78cc41f2, 0xeb66e41b, 0xebc4e6b5, 0xa69c89c3,
+ 0x35f2f18a, 0x7f9662b5, 0x807e7e60, 0xf03977f3, 0x7147ed01, 0x8956b833,
+ 0xaeff8465, 0xcef58128, 0xbfe5af5c, 0xc67b4387, 0x1cd565df, 0xed2a3396,
+ 0x67d278e3, 0x40efc057, 0x3b96f96b, 0x2f70dc73, 0xf2ca5083, 0xb2f92c3c,
+ 0xc493c846, 0xd6953a52, 0x0ecb922b, 0xb883f526, 0xe40d73b1, 0x479e4333,
+ 0x2f445a5e, 0x0ad747dc, 0x2e245e5b, 0xbf12b0eb, 0x3d70ec1d, 0x79e79fcf,
+ 0xfbebb52c, 0x3eecedd1, 0x86fe8aea, 0x850e4e73, 0xbfbf477e, 0x9a3deade,
+ 0xa14cf984, 0x7dd29544, 0x78698ef9, 0x76e2907f, 0x3e477ce3, 0xf803293f,
+ 0xd9f5c281, 0xff5c31ff, 0xc82e0f1b, 0x3a71816f, 0x062c8eb6, 0x087231fd,
+ 0xd08b599c, 0x7c41aa87, 0xbc120f6e, 0x01fff12f, 0x512809c2, 0x00008000,
+ 0x00088b1f, 0x00000000, 0x5bb5ff00, 0xd554740d, 0x79bfff9d, 0xbe4cdef3,
+ 0x21264cdf, 0x012f0842, 0x1c424242, 0x61f08062, 0xc4443e1d, 0x602a0320,
+ 0x43e196eb, 0x9a1af909, 0x7ab76eba, 0x2904930e, 0xb693db02, 0xb654e56e,
+ 0x28bb560e, 0x82609d89, 0x04ec2681, 0x6eb50314, 0x5b604040, 0x6a445477,
+ 0xbb8d3243, 0xb29eec54, 0xf7bdffff, 0x60c33325, 0x392dd9e9, 0xddf73739,
+ 0x7ffdeefb, 0xf75ffefc, 0x595c003e, 0xc9a00392, 0xe7b73aa6, 0x001aa802,
+ 0x6dbcdc64, 0xa0556052, 0x324e4018, 0x63240a6d, 0xd4da669b, 0x668a6d86,
+ 0x9aa9e362, 0x70805ace, 0x6c14b2ce, 0xf2ce70b4, 0xc6efbc29, 0xc34b9656,
+ 0xfdec32c1, 0x45f38a5d, 0xe1d90a9c, 0xfec49e0f, 0x39148ffb, 0x42ff63b7,
+ 0xa4096a62, 0xe7f2ac01, 0x3fb08535, 0x1b1fe2d5, 0x69ceba44, 0x1a6d2c9e,
+ 0xfe2dd7c0, 0x7be32089, 0x68529bc9, 0xf005c97d, 0xbab63b1d, 0x22948f06,
+ 0xd5d02e7d, 0x60a300f1, 0x08a976b7, 0xeb82a900, 0x05f6f1e9, 0x58074c2b,
+ 0x8eff1339, 0xf19217d8, 0x53d22679, 0x741b9fce, 0xb405fee0, 0x30cf41bf,
+ 0x5dad901d, 0xeff6024a, 0x96eff63a, 0x8fb81851, 0xdf9313f7, 0xbf8b6122,
+ 0xa2fd7fd4, 0xbfc3efc9, 0xdb9f6807, 0x792bb669, 0xc43674cd, 0xebf999f6,
+ 0xeb119946, 0x3e7c1fc3, 0x65092f8d, 0x9015d59d, 0xf33efd8a, 0xd8ab2147,
+ 0xf4677f07, 0xe327e67a, 0x45ce337b, 0x8175c73f, 0xd62d9fe8, 0x0cbf072d,
+ 0xa1998f28, 0x61b379e8, 0x5c641fe7, 0xe8e5f677, 0x14b40be7, 0x3467e307,
+ 0xf8cebe8c, 0xbd70aa43, 0x6f5f2b7a, 0x34bc9de8, 0xcd9bfd40, 0xbb945328,
+ 0x8e50cbaa, 0x77fa75ed, 0x66fb4017, 0x700f979c, 0xb595b360, 0xeb6b4e53,
+ 0xcdcefe88, 0xe0152008, 0xd62ce6d0, 0x98c69aaa, 0x561a729c, 0x3ec44943,
+ 0x90c7df1a, 0x2e39d0e3, 0x82a1a9c7, 0x5f60e6e7, 0xafc055e9, 0x4b39f08f,
+ 0xb80869c8, 0x9534879c, 0xf1fa79c9, 0xc411dd9f, 0x132c9647, 0x25fc11e8,
+ 0x17a089e8, 0x0a93f48c, 0xd97d51ec, 0xd5cf8fd0, 0xdfeb8597, 0x714fd621,
+ 0x075a8e8e, 0xa113f8fc, 0x85f643bf, 0x71f212bd, 0x05657247, 0x9e5693f1,
+ 0xd96eb517, 0x427ab13b, 0xd3cbe1c1, 0x209fc890, 0xc69fa69e, 0x33f988f1,
+ 0x00923e1c, 0xfa26ff94, 0x4cb34039, 0x62eb3476, 0x6f27f3f4, 0xc99bb7a6,
+ 0x9b9e4a13, 0xe5ebf8e3, 0xcb457369, 0xb4517d33, 0xd1dc333c, 0x2ab51cf2,
+ 0x79b76e5a, 0xa632e5a2, 0xf8d47272, 0x51a54dd8, 0x99df71fd, 0xd73f3515,
+ 0x3faa2f37, 0xa8e2db7e, 0x979b13f9, 0xed27f547, 0xfcd47afa, 0xa8daff42,
+ 0x55bda2f1, 0x29ffa4b7, 0x79a8fa81, 0x57d35e24, 0xcef6ffe8, 0xf3ed46ef,
+ 0x2fffd6b7, 0x9c7ff463, 0xd234d97c, 0xf447fa17, 0xf24a838b, 0xd99f0936,
+ 0x93f25690, 0xafb7aeb6, 0xbe976849, 0xe88fba79, 0x67062df0, 0x2b3d8e13,
+ 0x6bf225bb, 0x26d45063, 0x4c5b1bf4, 0xfefe4950, 0x6ad326fb, 0x9d88f277,
+ 0xb624d71f, 0x982af3fe, 0xf3d1ec13, 0xcc8f1796, 0x14d3da33, 0xf88da61f,
+ 0xf45bafd9, 0x3df210a6, 0x147ee655, 0xf269ebfd, 0xa7a417af, 0x8a997214,
+ 0x8a78a7c3, 0xed59bc59, 0x0e06d6c6, 0xb4db1ea9, 0x5faebf11, 0x505ce547,
+ 0x98ff2ffd, 0x3b213fe8, 0xdffa465f, 0x86dc8125, 0x89bb56bf, 0xc361f3ec,
+ 0x9a7ae96f, 0x21ae822d, 0x048fa5e4, 0xd0d3d66c, 0xfad0c3e7, 0x9dafccf1,
+ 0x4805a6ff, 0xce55e7ff, 0xb2ff318f, 0x099f6bf0, 0xfe4fd6bf, 0xbc647f2c,
+ 0x528fcf72, 0x7ce75c74, 0x440a2c01, 0xe42c29c8, 0x58d06604, 0x75cd99bc,
+ 0x876aa176, 0xbfae18f2, 0x44d87df2, 0x13fcacfb, 0xef7c8a6c, 0xdec29acf,
+ 0xb326b3fb, 0x59360576, 0x1815e728, 0xaca56ccb, 0x5db0941f, 0xe40a0bda,
+ 0xe4f32c01, 0xf794242a, 0x03a679c0, 0xa292b4b7, 0xc107bdf1, 0x3fff90ad,
+ 0x14dacdfb, 0xcebc379a, 0x4fdd4fdb, 0x8a815d38, 0x7dff61b6, 0x44c94f9b,
+ 0x53be107f, 0xf711f162, 0xf773d2b1, 0xa69e6323, 0x3c167338, 0xbea0ce57,
+ 0xad938396, 0x600bac67, 0x1733f28f, 0xe3a60854, 0x160bbe3a, 0x4748cbff,
+ 0x4561b23d, 0x8f77d4fd, 0xb0647e62, 0x3fad8fea, 0xc7ab79c6, 0x9c52c684,
+ 0xa7f550be, 0xc3f3d27c, 0x20afd0bb, 0x3d124b6f, 0x118cb619, 0xff5f9c39,
+ 0x638d0a79, 0x867a65bc, 0xcbe7167d, 0xd8fb7e4c, 0x71bcc67b, 0x6da3b9b6,
+ 0x5c72e724, 0xf88de664, 0xb00a5a33, 0xa9549f94, 0x177e9ffe, 0x0a1384e9,
+ 0xcbc0cf5b, 0xfa978146, 0x24547d5c, 0x8653ea5e, 0xf08a32f1, 0xccb2ff52,
+ 0x3bbea6ec, 0x97280fc1, 0xde770233, 0xfb5ed77d, 0x9e1d4eae, 0xb88c7cef,
+ 0x9f2711d1, 0x8c746e20, 0x6e229f7b, 0xd90dffa8, 0xfde8953d, 0xa9c7e778,
+ 0xc1f75a1e, 0x507ba35b, 0x06fd9f0a, 0xc738f7c9, 0x9d0c10fb, 0xbdba7e65,
+ 0x1d21f750, 0x3b5c0ff3, 0x5d5cf94b, 0x60b745bb, 0x742d8aff, 0x7f9a79ec,
+ 0x5f9a0250, 0x4e604c17, 0xf25daeab, 0x5578e027, 0x31d6db67, 0x596aafd8,
+ 0xc3614656, 0xbbc10a9b, 0xe4bf7c68, 0x4bf1c46f, 0x1725839b, 0x87bae027,
+ 0x75a25dae, 0x75f10e07, 0xe60e6f2f, 0xb0300e53, 0xb407cd7f, 0x05bb4d5e,
+ 0xb1bf2812, 0xb431d505, 0xa0149b5f, 0x3f032afd, 0xcafd6950, 0xa04d9697,
+ 0x6f7aa6f4, 0x1109c4cf, 0xc0e06b7e, 0x39475549, 0x60ffb655, 0xc65798a1,
+ 0xe19f97c3, 0xa37fe0d7, 0x1cdf27bf, 0x6ff13fe9, 0xf093d91f, 0xf216bfbf,
+ 0xbe35d55f, 0x7e89c489, 0x8979e3a5, 0x84d595f9, 0x5b870ba7, 0xda4bfb7f,
+ 0x4ebfe0ef, 0xd940dc24, 0xdc1bc9ad, 0xeb17163e, 0xf9703ec4, 0x429dd53d,
+ 0x452e53f2, 0xff3e73fb, 0x435dcd90, 0x2a9861fb, 0xc48444d8, 0xd0db87e4,
+ 0x93e4801e, 0x43ecc89b, 0x6bab0e4e, 0xd1ef9e90, 0xacc7a404, 0xd8b5d585,
+ 0xf31766df, 0x97feacf2, 0xafa46f73, 0xf26666c3, 0x2781e6b1, 0xed186fd2,
+ 0x3a471a7e, 0xa67de68e, 0x4ebc7086, 0x6e12acbf, 0x53bf82eb, 0xdbdfa475,
+ 0x5742e1f9, 0x3602f79c, 0x9314afee, 0xd94f72bb, 0x4bd47d88, 0xf089218d,
+ 0xce92707e, 0x2f9b58f2, 0x48ebe8c4, 0xf98f89d0, 0x3d377e07, 0xefdeb114,
+ 0x26131f11, 0x7eebf48c, 0x428961f1, 0xc3fd7b72, 0xc8ca7312, 0xe4cc81f3,
+ 0x3a5c7f4a, 0x3a78bc78, 0xf6997dd5, 0xd1603dad, 0x13be191b, 0x77c2419c,
+ 0x3d139257, 0x6d5be135, 0xf7c48b2c, 0xbaee8cc3, 0x4889d92e, 0x65ceba87,
+ 0x3f36069e, 0x906a49c5, 0x08fae73b, 0x66e6b267, 0xc1ff8478, 0xa54710fd,
+ 0xa3fa37f4, 0xcfcf3695, 0xe4e67f49, 0xbc48c4e0, 0x394299d5, 0xcfe9128d,
+ 0xc2373cd3, 0x9f64e4fe, 0x7920e8de, 0x7d653ba6, 0x898a7f44, 0x0f4065eb,
+ 0x8e29daa5, 0x50f5c66d, 0xdfc1031e, 0xb7fc92a5, 0x92b3ae76, 0xa6c77fdd,
+ 0x55593d31, 0xff61ae9f, 0xbe47d4db, 0x4aeea9b7, 0x996dabb2, 0x0d764089,
+ 0xef8676d9, 0x01d784bf, 0xbd5457b2, 0xb8a01e02, 0x36f0203a, 0xff981630,
+ 0x708fdca5, 0x37be5326, 0xa3c8cc9e, 0x676f3cd1, 0x08c5c94f, 0xae0e077e,
+ 0x4a7d1274, 0x321f7f22, 0xf7635e39, 0xc3814ffd, 0x9b6b4da7, 0xe1c446e7,
+ 0x15bf79d8, 0x00e43478, 0xab165f66, 0x8cf13107, 0xdb3adf87, 0x1fe433bc,
+ 0x0bbbb69f, 0x899b0fc8, 0xaea3c230, 0xe703a5c6, 0xcde907ff, 0xc85c7f98,
+ 0x1a3c5555, 0x214df5c9, 0x33754557, 0xeb61a339, 0xfcc3c764, 0xed71a9e5,
+ 0xdfc10bec, 0xbd68dcb6, 0x2abbcec7, 0xbe4c53f8, 0xe744b5ac, 0xcdd99961,
+ 0xfa661ea0, 0x060de637, 0x77fd71af, 0x8bbf7e7d, 0x05773cec, 0xaf67e7c3,
+ 0x11ca9614, 0xcdb38eeb, 0xffe22ffb, 0x8a0f0313, 0x0ee88b2f, 0xdeb1f0c5,
+ 0xf892fee6, 0xc83bf236, 0x4e12dc76, 0x4e07d440, 0x3eb0ef11, 0xabe33028,
+ 0x24e89083, 0xf226deff, 0x19b83360, 0xa9c0924e, 0x05d77ab3, 0xfc8d9abf,
+ 0x6098f535, 0x9b53763b, 0x8139ca24, 0x9ccd608d, 0x228c9b2a, 0x52c565c2,
+ 0x0c8c88af, 0xf6ed53c7, 0xbd20b77b, 0xf327c107, 0xfeba39ba, 0x92e49705,
+ 0x37deeb22, 0xbdd7e2ab, 0x644d3dbb, 0xeea97fd7, 0xad34199d, 0xfafed351,
+ 0x1d8277fa, 0x1822e8f3, 0xdb27a3ce, 0xa0544675, 0x102fe380, 0x7b33f44c,
+ 0xf09f54c4, 0x1a7e4fdb, 0x922bf9e5, 0xa553ce29, 0x0dab0281, 0x78eec4a0,
+ 0xda365b66, 0x3fce04d7, 0xefe89bf5, 0x0c679e5e, 0x4e6fd3d7, 0xfa277966,
+ 0x93d59921, 0x4625a09a, 0x1f98656f, 0xd88d3a41, 0xe0f1eaa3, 0xc9532fb1,
+ 0xf5dab6ef, 0x84bd277f, 0xf940cb8f, 0xa439825b, 0xd5d8e2da, 0x3163ca01,
+ 0xcedc790f, 0x9dac6bcf, 0xfb8fcb92, 0x5017755b, 0xb4d04f7c, 0x7d8472a9,
+ 0x3625d815, 0x85d8f6af, 0xc7f3151c, 0x5277a62b, 0x9afd718b, 0x74a9fd8e,
+ 0xfe7d53ac, 0xed4a74d4, 0x0a9ecd8b, 0x4cfbce3b, 0xa56f93da, 0xbf9b70bc,
+ 0x0813e484, 0xbc51a5e6, 0x9f06629d, 0x7a46f4b9, 0x594abbbc, 0xcbb75591,
+ 0x5d29dace, 0xbca06c77, 0xfce41bd4, 0x0e0a1ed2, 0xeb027615, 0xd936740f,
+ 0xbfef3d69, 0xff268f75, 0x56032fb4, 0xf578ff91, 0x7dfcc98b, 0xfe699833,
+ 0xe04dbb1a, 0xf3a26fdc, 0xdce27da7, 0x130be06a, 0x3fec679b, 0xacae73a5,
+ 0x838a0e21, 0x0fc847cd, 0x58597424, 0x12f0951e, 0x61747970, 0x38e7477e,
+ 0x8a01ef87, 0x70368343, 0x9ade384a, 0x4f796618, 0xbfa2dbb8, 0x9adc9128,
+ 0x55bcec81, 0x214af5e5, 0xf27f7202, 0xbf6373c8, 0xe8e7ae84, 0xe170898c,
+ 0x6097b8a2, 0x933b866e, 0xc29de523, 0x73b46ee8, 0x0626b53c, 0x9794c94d,
+ 0x9178044f, 0x274235d1, 0x3a0d7db0, 0x6f7f990b, 0x9e97c355, 0x34ba3074,
+ 0x702141c2, 0x926ba13a, 0x412dfe4e, 0x123e3173, 0x93e9dd34, 0x5bcba46e,
+ 0xda178982, 0x611bf7cd, 0xaec98ed8, 0x7d2389bd, 0x6b42da2b, 0xf835c71e,
+ 0x20b33e16, 0x0e4fa23b, 0xfde47ca6, 0x3ef7ece7, 0x9d9b25b3, 0x5464f917,
+ 0x29b61275, 0x6753e276, 0x74d7a27c, 0x39729465, 0x494e5138, 0x3c3e3e56,
+ 0x4c9e711f, 0xcf3e64fd, 0x1692d169, 0x017b32e7, 0x2f2317b2, 0x5e0a5c7b,
+ 0xb5ed0bba, 0xb4ee07ff, 0xdfabe462, 0x1689e474, 0x35fbf79c, 0xf620fc81,
+ 0x179ea94f, 0xfc6f9f09, 0x298eed66, 0x155b6fe4, 0x9df90567, 0x2c87ef90,
+ 0xd1557dff, 0x1dd847b7, 0x09338764, 0x78fbb1bf, 0x90fe37cf, 0x83c1dbf2,
+ 0xc9d56e92, 0x887386ef, 0x4faebaee, 0xdee7f255, 0x7cb21f83, 0xe7ba6e76,
+ 0xafea3b35, 0x3e61b3bc, 0x342675c9, 0x2ebf9137, 0x20417912, 0xa193fb8b,
+ 0x362ff9d3, 0xb4e1e844, 0x7b0837b0, 0xea7c51c6, 0x987af612, 0x3b6c4eea,
+ 0x4f1e1e7a, 0xba8877eb, 0x01af78d8, 0xb9218c8e, 0xac9bc237, 0x7e378e1d,
+ 0x59c222f3, 0x6aeb59d1, 0x77fcc457, 0x7abf3ced, 0xbdf3ced7, 0x379ee9f5,
+ 0x3dd53e49, 0xc4a9a91f, 0x0e40c5e7, 0xac0193d5, 0x7e38b58f, 0x637ed864,
+ 0x0e6bc9ec, 0x7bdf34ab, 0x415f9819, 0x43496f7d, 0xdb3bedfd, 0x3e0d7939,
+ 0xa49d40ef, 0x9e709e51, 0x8a1d87d7, 0x6fcd0c7b, 0x84b57338, 0x2201d8fc,
+ 0xdab9e902, 0xe48e3d5d, 0x979ff886, 0x06d67648, 0x7619afcc, 0x8a764c5a,
+ 0xfe1317ef, 0xc85fa8cb, 0xdaab72fc, 0x65d998b7, 0x2ec80987, 0x1eccff11,
+ 0xc51aff10, 0xed0d62e3, 0x893fbd81, 0x9f6b79d9, 0x58f2c5c9, 0x5913ebf4,
+ 0xd403de7f, 0xa05bed6f, 0x21373b31, 0x5ec94b9e, 0x3ad84783, 0xa4898001,
+ 0x91dc093a, 0xf60503e7, 0xc337a654, 0xf6174e5f, 0xd3d0281b, 0x9247c89c,
+ 0x47d9472c, 0x7de49c44, 0x3f5d4711, 0x9e67c7fa, 0xfb4f839d, 0x44d09c44,
+ 0xfdc73c7c, 0xac45b7fe, 0xd66b7faa, 0xc7ca16d2, 0xf1b32d7f, 0x227ce2c3,
+ 0x44727028, 0xdc504f9c, 0x6f3f51d0, 0x69d7738a, 0x1fa177d8, 0x34daee9d,
+ 0xf2aa729f, 0xa947cd45, 0xcc0ee59d, 0xce7154a7, 0x0aa3beaa, 0xc222f337,
+ 0x7b91fb5f, 0xf7e4cc8b, 0xaefaf3ce, 0x07f0cbfd, 0x9e1ca2af, 0x8ff28c38,
+ 0x1d90a713, 0xafcc3f86, 0x8dd640c6, 0xe19283e3, 0x4bde7647, 0x97681c78,
+ 0x4848fa47, 0xfa9b021d, 0x9fdbe919, 0x9fdf61f1, 0x474acaee, 0x78711e79,
+ 0x9e51d2b2, 0xccbf2783, 0x38ecb324, 0x9bab11fd, 0x115755db, 0x0f3da7e1,
+ 0x3838cd4b, 0x73f3a735, 0xf44b3294, 0xced18af9, 0x3071e74e, 0x243b07df,
+ 0x9acb1756, 0x76e6ea9f, 0xfe62a5d9, 0x2b7c1973, 0x11bf9366, 0x828f81e7,
+ 0x1fc2e7f8, 0xa263cfd4, 0x2be528fb, 0x7b1eb718, 0xaf398956, 0x3c2264db,
+ 0xe092e86d, 0xe57bc827, 0x1771d8ee, 0xc46a5bcb, 0xf73b1b3a, 0xfa831b1c,
+ 0x7a297aac, 0x2be50d5e, 0xc03c9cec, 0x169acfea, 0x499f3a25, 0x78cb7917,
+ 0x0b794f18, 0x07f989e2, 0x16bd0cc5, 0x8745efc4, 0x6b4c90a7, 0x09cb899f,
+ 0xcbb32afd, 0xb4bf9142, 0x28fee3ce, 0xccfc057c, 0x8e06f66e, 0xb3dd22a6,
+ 0xb49d725a, 0x1f332cc7, 0xcb99d59f, 0xfd980ce2, 0x445432f2, 0x90b3cbb9,
+ 0xd73ed3e5, 0x47942ce9, 0xa093f0a5, 0x8daef3f1, 0x914aaf82, 0x47f46dcf,
+ 0xfc133dd3, 0x86cfb44d, 0xa83392bd, 0x1280f9d3, 0x8af3af37, 0x9d766a75,
+ 0x7bc7463c, 0x79e881b5, 0x6f1f215e, 0xfdf3f467, 0xd58136c0, 0x347ce2e9,
+ 0xf9d87207, 0xd5adef78, 0x7857bf53, 0xac4a717e, 0x166f8c63, 0xf243a9b8,
+ 0x7e35bf48, 0xa9b84fd9, 0x3ca97c94, 0x35e485bf, 0x033af748, 0xa0fe3a2f,
+ 0xf90bd63c, 0x617813ac, 0xb5fbe17c, 0xdd3f25bb, 0x19dfad2b, 0x81a3ff4d,
+ 0x0f090b35, 0x6caab8b1, 0x5b7e5851, 0xca549b05, 0x5571636f, 0x66978c35,
+ 0x2c58e295, 0xd23cea9e, 0x79e6e84d, 0xee95fff9, 0xcec8256a, 0x59ffaa7d,
+ 0xfe88fa72, 0x74a96ff6, 0x7da378fe, 0x1956fd70, 0xfd7c1138, 0x6f3cfcb5,
+ 0x4c327fe0, 0x945dfa66, 0x50758b7e, 0xa6dd3e74, 0x3218fb72, 0x0362f3f3,
+ 0x2fefb13f, 0x3df8f914, 0x57b580bb, 0xa54f3f3a, 0xbec1dff3, 0xad6054a1,
+ 0x3fc51169, 0xf0884fea, 0x79d2fb3b, 0xeb35b89d, 0xbe53efe3, 0xe29b4f7e,
+ 0x6a0e4cc4, 0x8a6e2ac6, 0xdf6335d3, 0x11109cca, 0x79d2da57, 0xdb4f79fd,
+ 0x74098da3, 0xe48af0ce, 0xec1bf324, 0xd423fbfa, 0xce48b5f7, 0xb1fef889,
+ 0x6777a1be, 0x92b23e93, 0xde7ad3a6, 0x5a8bbbee, 0xc5ec7fb1, 0x75919c3b,
+ 0xe73b31e5, 0x0ab19eef, 0xa3fd9b8b, 0x41567e93, 0x3dae80e7, 0x0ffb8ecc,
+ 0x9d92aebd, 0x904ab60f, 0xcb1d1b85, 0x8f9afa3a, 0x27039cea, 0xe7c64a55,
+ 0x43549fb7, 0x5c0f915f, 0xc82b72c1, 0x559b49ce, 0x1ddc6baa, 0xca21a89f,
+ 0x90fa5e8f, 0x75553f9d, 0x548fcc4a, 0x3afd96ed, 0xfbb479fe, 0x5470950d,
+ 0xa8c122d7, 0x8571c8dc, 0xa3bf938d, 0xdc2da7fe, 0x5cf81a7f, 0xe068f02b,
+ 0x5aebc0d3, 0x6dd667e1, 0x63e3c68b, 0x1a3adae0, 0x65b47fdf, 0xcd794a8d,
+ 0xfdf1cda3, 0x36afe18c, 0xfe88fd50, 0xe8aec37f, 0x71871b79, 0x387e63e8,
+ 0x1bf59fd6, 0x42842c38, 0x7050e1c2, 0xe23338ed, 0xaac9eafe, 0x5ee71071,
+ 0xb7111de4, 0x3379b88d, 0x7e740eb9, 0xf3bc52ae, 0x6eac2b66, 0xb7ff66f0,
+ 0xab93891a, 0xbb0b2702, 0x53f4c0fe, 0x80b3d5d1, 0x9e025bf6, 0x92ef921a,
+ 0xf28d24ae, 0xb7108ae0, 0x165dc5db, 0xfa225fbf, 0x2dce2c4c, 0xd216c081,
+ 0x0b61e0ff, 0x243c773f, 0x84087cb1, 0xe420db1f, 0x77c841bd, 0x6359d603,
+ 0xe62f294a, 0x82c6f475, 0xa528c73d, 0x6bcf13af, 0x254d1f8e, 0xee062f39,
+ 0xb8071667, 0x65f4319f, 0xe31b89c4, 0xa49bf861, 0x0b2eeaef, 0xf708f7d0,
+ 0x5f733f09, 0xe919fa0b, 0xbc1fbb46, 0xc5e1892d, 0x8de9c1d7, 0xed758b8d,
+ 0x0e4df3d1, 0x890e5f9e, 0x11cf36bc, 0x308aafad, 0x7ae31524, 0xe9d9758b,
+ 0x99f56f67, 0x12deff69, 0xf5d3dd89, 0x3cd3e3ea, 0x9c38f471, 0xdd7c8b57,
+ 0xf3a52fe8, 0xd01f9c2d, 0xeb23939a, 0x9e0e9df1, 0x94cd577f, 0x88ff247d,
+ 0x696965fa, 0x65fadc6e, 0xbfe703a6, 0xe76ebd9d, 0xc5fac8d4, 0x709f27b5,
+ 0x1facbdf8, 0x7f929455, 0x64fee168, 0x4dd71ca0, 0x581c7ca3, 0xb16deb7e,
+ 0xf0cea9f8, 0xef288e22, 0x427087ba, 0xdd25d9f6, 0xfcc1384d, 0xcd126eff,
+ 0x437aba32, 0x627597fe, 0x97e5c63c, 0xc303f82d, 0x9c09f1dd, 0xa8db946f,
+ 0x5180f578, 0xc17dd407, 0x79e34df3, 0xeac4399d, 0x892eba81, 0xc8fdb6e1,
+ 0xa45c9cb5, 0x8ffbb077, 0xfdb06b39, 0xa38f0707, 0x1f02f3ed, 0x572077d1,
+ 0xf371ad5b, 0x2dbf61ca, 0x5276616d, 0x593284a7, 0xf31071de, 0x3f5819bb,
+ 0xd58cfa9c, 0x1247ed0f, 0xf6b9d356, 0x38cf5ac0, 0xd4f42bed, 0x3f2c8d00,
+ 0xac2d846d, 0x3225fca5, 0xf1a0db9f, 0x131e4aef, 0x4ffa8ef1, 0xc31fae21,
+ 0x8d2b5fb9, 0x5b7c17e7, 0xfa374b67, 0xd4afc303, 0x1757bc0a, 0x294ad9ef,
+ 0x539e6c57, 0x3308ec2b, 0x62df1678, 0x0e9d9bf3, 0x9c08bf91, 0x644a9c36,
+ 0x71e0eaf9, 0x5d33a359, 0x474feb94, 0x7986fe53, 0x739c5e7a, 0x2e04cfcc,
+ 0x65fdc5fb, 0xe4ccb943, 0x5bc99a66, 0xf9421f23, 0x9e0cbc31, 0xbe53f64c,
+ 0x8df8745f, 0xf57fd23c, 0x69179c5e, 0x0f3fa877, 0xcfc7aefb, 0x481b5c70,
+ 0xc6327762, 0x6fc3bef8, 0x359c264c, 0x9f32fa9c, 0xbe5ae5eb, 0x7d39b8ea,
+ 0xbc492b46, 0xbc49358e, 0x8730ed8e, 0xf27ea952, 0xfedd941e, 0x7a1a7d08,
+ 0x476117fe, 0xfaf5e660, 0xface871e, 0x171c5d0d, 0xe2de6ea6, 0x79f82bfe,
+ 0xbff6c28d, 0xe21e7c61, 0x1ae22be5, 0x7ba85d10, 0xb86612af, 0x31349ef3,
+ 0x8727bc7a, 0xbbe32332, 0x451dd68f, 0x06a1af7e, 0x02491f98, 0xc7e8b3f2,
+ 0xdef7547c, 0xe5812e77, 0x76f2c74b, 0x95bf3054, 0xadf90327, 0x4d554e27,
+ 0xf90f8c8a, 0x27e7990e, 0xca2c8724, 0xfbe59e56, 0xc234390b, 0x73ef5172,
+ 0xce92bf1c, 0x527580e5, 0x6c71d937, 0xf9ab749d, 0x05b7436e, 0x7bd81ce8,
+ 0x13bec2c1, 0x81bddab9, 0x85f0e1d5, 0x19f91267, 0xa76e78f0, 0x1bc389f6,
+ 0xabf3d126, 0xcede3787, 0xc6a52fce, 0x23e5f8a8, 0x2f28b2fa, 0xe3a9933a,
+ 0x99f76d78, 0xc2ad604c, 0x647ea7e8, 0xc1d77afc, 0x4f60d7e3, 0x90a73b02,
+ 0x00e38f20, 0x5bad4426, 0xcb16fed3, 0x653a6a23, 0x8c1e2457, 0xf0703ef7,
+ 0xc223eafc, 0x9013f101, 0x6dcf4c5c, 0x7ce9adbc, 0xad53d19d, 0x1b1e9804,
+ 0xde3e145a, 0x2fcc5bca, 0xb03e1d19, 0x36fe88fb, 0xf7e6bf3a, 0x02bcec1a,
+ 0x18fb3267, 0x6ff4282a, 0xe8affec7, 0xc875ca11, 0xdcfe026f, 0x9b83eec2,
+ 0x11a7c77a, 0x5f7a87ee, 0x178bc477, 0x083dd0ef, 0x97227a92, 0xe3b117d7,
+ 0x39f8327b, 0xdcf389c2, 0xeb989d8f, 0x9fcf1499, 0xaf1e60f9, 0xef2125b7,
+ 0xbc516576, 0x3217b4fb, 0xdecf39f8, 0xe209df6c, 0x812dbfa7, 0xdbf5a7dd,
+ 0xfce8b9f8, 0xe9cdc7fd, 0xa5db7714, 0xaa3f1469, 0x405fde0b, 0x2fd8f8f7,
+ 0x782b7e63, 0xd61bdd90, 0x742db4b6, 0x2ea3a1c5, 0xc5f1fb83, 0xc8fbfc6a,
+ 0x7bf8c5db, 0xf510cce0, 0xee130ed1, 0xa2855ef7, 0x8679676d, 0xf436f92b,
+ 0xff0bf7bf, 0x8512c0fb, 0x81ef25e5, 0x077bf0ae, 0x54b03f7e, 0x85fbd1f8,
+ 0x1e5a5e5f, 0xed9727ed, 0x7ee9a786, 0xbe2b9960, 0xac487e1f, 0x6c5c1cbf,
+ 0x451607dd, 0xe4487bcf, 0xa3b90f77, 0x10ca4f9f, 0xf21f37fe, 0x3006ffc9,
+ 0xebbe901e, 0x5c58130b, 0xc4ca6fbd, 0xb1c179b8, 0xfdeec0cd, 0xbffdc57b,
+ 0xc286f7a1, 0x3abc59f7, 0x35fe73d1, 0x09dbf31b, 0x5ee71790, 0x195e246b,
+ 0xd720fef6, 0xa82fb8b7, 0x868d38d5, 0xe560afde, 0x652e7913, 0x90b17de8,
+ 0x04def57f, 0xaf9ef22d, 0xea8b6036, 0xd36f3b7b, 0xf9f8462e, 0xf46f816a,
+ 0x73c8e6fd, 0x67b29d8a, 0x0bdd0671, 0x3e59fb58, 0xb8b01c8d, 0x08e57c85,
+ 0x112c72be, 0x6dcae8f1, 0x77e2e26b, 0x8fbb3f84, 0x6b077dfb, 0xcc2d0a7b,
+ 0x92036aee, 0x6aa3ee9f, 0xac9ebc83, 0xc9ebc05d, 0x579e76fc, 0xf25078ae,
+ 0xbee624bb, 0x067d134e, 0x795a967e, 0x327036fc, 0x1f812f2c, 0x7e78a71a,
+ 0xb1e788bf, 0x7d049a38, 0x779ce90b, 0xd2724ba5, 0x78b171f7, 0xea6abe5a,
+ 0x6f9ee45b, 0x9bc41f86, 0x16327e42, 0xf0cf3f47, 0x1a632b7c, 0x4c570bab,
+ 0x144f75c1, 0xb8439a7e, 0xdd89bba9, 0xdb7a14ec, 0x413bec9b, 0xbf66bef1,
+ 0x5fdf07b8, 0x792219d8, 0xf7cb02f4, 0x5b7d6dfa, 0xcc1e79eb, 0x836bc1ee,
+ 0xdefa4e09, 0xc92bb6b5, 0xf6fd4099, 0x54c9c486, 0xcec9761f, 0xb457ec24,
+ 0xf2405c9f, 0xdfe328ac, 0x61a9d465, 0xb4ae6f96, 0x5e92b679, 0xa27b3897,
+ 0x3a0dbfee, 0x58f3866f, 0x0902f6bf, 0xe76fe327, 0xe0c85e6f, 0xf8feaef1,
+ 0x719399e7, 0xcf36e9ab, 0xf07ba26e, 0xba5557ad, 0x7e4ef326, 0x4eba6163,
+ 0x6f3674f3, 0x16cf4b49, 0xe8357e3a, 0xee343b0f, 0x367f155f, 0x6f8b23cb,
+ 0x86907bed, 0x50976f83, 0x73d03cde, 0xc08d44bc, 0xfa3d7f77, 0x6bfa38e7,
+ 0x5bb09300, 0x69256b33, 0xb86fc8b9, 0x8fbb7b1d, 0x41b9d266, 0x316fd93f,
+ 0x295267b5, 0xbdb6d62e, 0xf2913a97, 0x1ade0e8c, 0x92e95deb, 0x87303cd9,
+ 0x894a1ff2, 0x4669efa4, 0x5f0095df, 0xff942007, 0xf1c894c0, 0xfb6fffa6,
+ 0xae38413f, 0xeca286b5, 0x561390df, 0x47563eed, 0x7bb0b61e, 0x8927ba75,
+ 0x92ea9efc, 0x2c0cf5c0, 0x674ec86e, 0x78f0bdd2, 0xf0ccc54a, 0x10cdf508,
+ 0x9ee9db34, 0xeff32836, 0xff99b2cc, 0x9ff62e9e, 0xd0f60e61, 0xc53396f7,
+ 0xe82ce2bd, 0x06bef363, 0x40bad661, 0x0f3b5333, 0xb72dac9c, 0x32a3ef06,
+ 0x901038af, 0x4cc1ff49, 0x9592edb3, 0xf1007f7d, 0x37223df4, 0xe4325c33,
+ 0x13fdd321, 0x962f5eff, 0x8f02eb9f, 0xefdc5c33, 0xdf412a50, 0x80439659,
+ 0x09df77dd, 0x1def7121, 0x58d98f9f, 0xd77dd1a7, 0x893b689d, 0x367e1e4c,
+ 0x23f10e7f, 0x7427e3c7, 0x2c33531f, 0x293e88d0, 0x9eba6998, 0x0c7ceb74,
+ 0x375b0266, 0xe0785d75, 0xfb91b2c9, 0xdbd76742, 0x50bbe8e7, 0xdf62e5c9,
+ 0xc9ad3a8d, 0x04975641, 0x7ec3fdcd, 0x39200f2c, 0x66626d73, 0xf777c8c6,
+ 0x3df601e0, 0xf777ec45, 0xcce5eec4, 0x8cb4ef91, 0xfaf73fef, 0xc426eb97,
+ 0xd5872ac7, 0x4a3e2329, 0xd07739ad, 0xcd39e0f9, 0x8d399893, 0x996d03be,
+ 0xfb3116c8, 0x53bcb1a7, 0x5c092ae0, 0xe4bfc4e5, 0x07fbbe32, 0x389f1786,
+ 0x8265f6bf, 0x9252ae9f, 0x91587c30, 0x43881dae, 0x5fa19dab, 0xe159efa7,
+ 0xe53af9a9, 0x566d5bb7, 0x166fe527, 0x846937a2, 0xff2b26de, 0x7ef8c1ee,
+ 0x4d8e562b, 0x663e8328, 0xcb2b4e7f, 0x628fd78b, 0x6b8f34f7, 0xb27fbf9c,
+ 0xfd10a678, 0x1bcca78f, 0xd16ef945, 0xb164e62f, 0x30e51bfc, 0xe98390c7,
+ 0x80e7ffc6, 0x3c91977c, 0x817fff63, 0x802a2fc1, 0x72134681, 0x48d7f834,
+ 0x5c6f143f, 0xbf431fa8, 0xd9722379, 0x57f9c891, 0xf18f4be8, 0xec9d5dec,
+ 0x836f9634, 0xcf05ffbf, 0x10785073, 0x00107850
+};
+
+static const u32 xsem_int_table_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x94f3ff00, 0x51f86066, 0x257bc08f, 0x799c1819,
+ 0x8968c550, 0x1819390b, 0x0bf1030e, 0xda005620, 0xc0c5caeb, 0xfdc406e0,
+ 0x88013c40, 0x3eb100bf, 0x01830337, 0xd902a710, 0x736e6852, 0x17ba0264,
+ 0xd8815d88, 0x32bf881d, 0x637c3030, 0x767ede20, 0x623da021, 0x2039fe08,
+ 0xfd04b2fb, 0xf0d83ffc, 0xdafa655d, 0xc0c2a817, 0x2a83a310, 0x8fc68b16,
+ 0x466fc1d3, 0x027c9a3c, 0x8f113f1a, 0x5473717e, 0x2a019d7e, 0x8188c93f,
+ 0x9a920f61, 0x6efc037a, 0x81afc741, 0x3100df7a, 0x74769a00, 0x0003685d,
+ 0x00000000
+};
+
+static const u32 xsem_pram_data_e1[] = {
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0x45547809, 0xbedd70b6, 0x4e9def4b,
+ 0x62585908, 0x81511007, 0x05e42ce9, 0x62d9b1c4, 0x970621f4, 0x66854611,
+ 0x44749ecb, 0xf9d1c1c6, 0x153610d3, 0xc713309d, 0x60ec44e0, 0x81a0d050,
+ 0x60241009, 0x3cc0ea03, 0x64ffe31d, 0xb83066dc, 0xc5a4c6b0, 0xfcb8df0d,
+ 0x4dd54e75, 0x11d37bdf, 0x7fef999c, 0xca3fbff3, 0xfb5ba957, 0x539cead9,
+ 0x2c922aa7, 0x4222e910, 0xab9f83be, 0x409bf908, 0x4d171908, 0x69e5a909,
+ 0x24e05295, 0xbfa2e024, 0xe1521366, 0xd3cb4254, 0x43b29909, 0x48955f0e,
+ 0xc8428df3, 0x7da6f34c, 0x6eef2c56, 0x53b0f960, 0xfe5a11f1, 0xd3cd1371,
+ 0x8ee6033e, 0xe5a0ae87, 0xd9221d91, 0xb28edd08, 0x21124899, 0xfd842dc7,
+ 0x0e7cd364, 0x96568521, 0x3fdc68ad, 0xb717da07, 0xf6958999, 0x68bbb157,
+ 0x5f3415c6, 0x50264874, 0x32d362a5, 0x97cd1065, 0xc8168484, 0xf3664cf7,
+ 0x4314ee0b, 0x1efd689b, 0xcdd24757, 0x574e420e, 0x2147885b, 0x91d9c6a4,
+ 0x4268d374, 0xf2db434a, 0xb3695da0, 0x581135e0, 0x5397a6c7, 0x045b5d61,
+ 0x4843d9af, 0xf13b66d9, 0xf873628c, 0xde3bfe8e, 0xa2af862a, 0x3ae98be5,
+ 0x88b7ed09, 0x1111e6d4, 0x78a75fc6, 0x9df8519c, 0x38e376ae, 0x0b62be6a,
+ 0xabb6871d, 0xc2f0567c, 0xc44d2b12, 0xefc742df, 0xf59d6dde, 0xb7d60384,
+ 0x84e9194c, 0xa056ad75, 0xde68515e, 0xe607ab4e, 0xd1e4a8d7, 0x4686d2f2,
+ 0xb47470a5, 0x03cdb2bf, 0x1faaf3f4, 0x94d7ec9e, 0xd5d3d31b, 0x46467884,
+ 0xf884a5f3, 0x44bf685a, 0xc733290a, 0x407fbf44, 0x081909e2, 0x63c48bfd,
+ 0x214ff689, 0x4783df89, 0x5e14afe8, 0x844ebdc1, 0xc5b78aab, 0x27bbfa6e,
+ 0x6eb3b78a, 0x9229478e, 0x4d5feda3, 0xd03c021f, 0x9c02d4f9, 0xcf96ba68,
+ 0x4c9135cf, 0x2eff6892, 0xe903711f, 0x351eb7f5, 0x3cc995ad, 0x185ac742,
+ 0xc693e31c, 0xee42bcd3, 0x7e425e20, 0x37c722bd, 0x241fe695, 0x6f3039fe,
+ 0x062fe4d1, 0x92d2113c, 0x4abbf402, 0xfd60b320, 0xd349813f, 0x94a955f2,
+ 0x6bdc293e, 0x213ce5a7, 0x89ee7c0a, 0xf27c2f90, 0xa7ec74fe, 0x6851fb08,
+ 0xdfcfc33f, 0x572f3b8f, 0xaf3b8fd7, 0x0aa7ed58, 0x585db1fb, 0x1379b53f,
+ 0x2bc9f3f4, 0x1bb9fb55, 0xd85d71fb, 0x4f57dcba, 0xeae7cfd4, 0x7e27ec72,
+ 0x69f897aa, 0x07a5517d, 0x6913e1d2, 0x3e39a3b9, 0xa5a27ef3, 0x812bc98b,
+ 0x4b949dff, 0x971174b4, 0x61d1d36b, 0x97412fbc, 0x8fb93da7, 0x30f3ce5f,
+ 0x7c82cb88, 0x50520ca9, 0x641a4c2e, 0x35dcf9c1, 0xe17281c8, 0x4bfe09ae,
+ 0x301e74dc, 0x79a54936, 0x7723ffc5, 0xf3a6ba0c, 0xa40a4814, 0xc6a4131e,
+ 0x8332d5f2, 0x5fc1e4c3, 0xdb463c8f, 0x91914c07, 0x4ebf34f1, 0xac38f498,
+ 0x21311363, 0xa9226c7c, 0x33367a82, 0x3ab4f941, 0xa089e73d, 0x866b4e06,
+ 0xd10bfc52, 0xfec8d77e, 0x2dafa014, 0xd020e6e4, 0x94a1aadb, 0xf21107c9,
+ 0x70a6f074, 0x87eda250, 0x3c00a616, 0x6fe50acd, 0x1d0af8ed, 0xff8e347f,
+ 0x03bf8c1c, 0x77d71fc6, 0x5cb0f37c, 0xb496f8dd, 0x16f8dd62, 0xe94f8e85,
+ 0x9db9377d, 0x37e14f8f, 0x83e79081, 0xe6f8e1b7, 0x7f1c62b4, 0x758a42b5,
+ 0xc77adbe3, 0xfdd6017f, 0x1feb7f52, 0xfebf4136, 0xfafd52b4, 0xc3feb615,
+ 0xdf1f1164, 0x63ffeb86, 0x7f5b2170, 0xbf5b295a, 0x3bdbf599, 0xfe17abbe,
+ 0x8fbac1af, 0xe1feb7f4, 0xbfebf513, 0x7ebf5ca8, 0x6dff1b33, 0x77c7c152,
+ 0x04eff8e0, 0x2ffad9cb, 0x15f1c72a, 0x740bdfb3, 0x55b60ca4, 0x64f8e885,
+ 0x64886508, 0x4c3e5194, 0x42102547, 0x6191d7db, 0x6cbb8708, 0xb0beee8c,
+ 0x44737a51, 0x51091de5, 0xacf2a28e, 0x597cd392, 0xe40524f3, 0xb953962c,
+ 0x754f88b7, 0x74889b61, 0xa1ccea4d, 0xbb7ce98b, 0xe420c4db, 0x195dd617,
+ 0x23bf7112, 0x9da00b73, 0xfdf0c244, 0x6cc787a3, 0x98cbaed4, 0x8f95aa2e,
+ 0x88f8ea77, 0x993827cd, 0xf3a2aa8c, 0x3044069b, 0x4e3f9a2e, 0xf2a128e5,
+ 0x472a7df3, 0xd3213d21, 0x0ff7e8f1, 0x8a259ca9, 0xb1966f96, 0xde483c7d,
+ 0x72049518, 0x971cfd82, 0x2f8fbc18, 0xff004211, 0xa1ddd62f, 0x545a7c80,
+ 0x8f40a76b, 0xf1c023ce, 0x0e6dd914, 0x9e10146d, 0x2dcf801e, 0xfc848ac8,
+ 0x9535a295, 0x7ea8b682, 0x6dddae80, 0x8532b424, 0x76b05fd6, 0x5d3750de,
+ 0xccb3adff, 0x1fec2299, 0x84d837c4, 0x9b064c7c, 0xd5990972, 0x4c1e4eba,
+ 0x92ccb733, 0xb4d4efdf, 0xe7d7ed9f, 0xe7d62d6f, 0x6c90e5bb, 0x44a37d02,
+ 0xdfb48d20, 0xe5f4abdb, 0x42f138ea, 0x1f2bc302, 0x6c4927ef, 0x9a43b7be,
+ 0x88dd9f09, 0xd66e39d7, 0xe04f9d56, 0x7184991e, 0x481cecbf, 0xb103ff10,
+ 0xd6cddf9e, 0x1cef9c6d, 0xa02be2d9, 0xb77399f3, 0xce34f088, 0xdd9f73bf,
+ 0xd34b1a67, 0x20654ffa, 0x8c7ae341, 0xd4bb9ff3, 0xea371eb8, 0xc682f361,
+ 0x8c4e8cef, 0x9b6814f4, 0x4d43e034, 0x6b968abd, 0xa1a87c06, 0x33cdb2af,
+ 0xd092f975, 0xa2fd5d6c, 0xf2ba79fa, 0xba25b545, 0xee6b05f2, 0x05e7e5d0,
+ 0x9fd5d6ef, 0xae9974bb, 0xfbaaf6fc, 0x16b7e574, 0x67e5d3af, 0xeaebd7fb,
+ 0x51ab32df, 0x2bec2e57, 0xe513a8b9, 0x54a2ffaa, 0x36df2bd0, 0x9547a013,
+ 0x387e55de, 0xe9829d59, 0xa60f6ae9, 0x294f80cb, 0xb3769bff, 0xde71b034,
+ 0x2aefc045, 0x55c84e9c, 0x464fc069, 0xd3c237ba, 0x67f4df48, 0x487dac70,
+ 0x5205cb4d, 0x87ae7200, 0xf7eacfef, 0x120e5c73, 0x72d31cb2, 0xf96df185,
+ 0xc4c9d4f6, 0xc8f0f905, 0xfdff472a, 0xd7011692, 0x1e8b4041, 0xd4a37808,
+ 0x70ebc3aa, 0xf6bb3cdd, 0x257e388b, 0x0078eef0, 0x0132c155, 0x307c21f8,
+ 0x3031c6ed, 0xcc72df1f, 0xfdc40db7, 0x7f3aabb7, 0xc01287c0, 0x93d300af,
+ 0x3d30b3d5, 0xf4c7ed5e, 0x4c62eac3, 0xc2aeafdf, 0x297ab3b4, 0x83ab47a6,
+ 0x7aa5fe98, 0x54efa60d, 0x56fa62d7, 0x7fa63d75, 0xda610eae, 0x54c3ed5d,
+ 0x395edba5, 0x4af5c899, 0x1dd3ffae, 0xf967f302, 0x7bfa445a, 0x37a3f207,
+ 0xacf1f805, 0xa0918be3, 0xcb7d9f37, 0xef2f404c, 0x7a465e0f, 0xc4ae17e8,
+ 0x61457a87, 0xac870a88, 0x1b56e5be, 0x44d593c3, 0x1b9509f2, 0xa4fc5df7,
+ 0xcc68fe77, 0xda01244b, 0x9d33bc87, 0x411dfa31, 0xc3e75f10, 0xc645f113,
+ 0x71f140de, 0xe5bfd1fc, 0xf8e7bf40, 0x283b653e, 0xc2497ee2, 0x5f01784f,
+ 0xfee1b81a, 0xe5c1d913, 0xf7e079f2, 0x7e1540f1, 0xa684691d, 0xd2370413,
+ 0x3356d9df, 0xed8e0091, 0xfda110f6, 0x84f43d9c, 0xc5bbf60b, 0x87f72629,
+ 0xa6a0e031, 0x6ee92d15, 0x689f7687, 0xd6cfe7d3, 0x282df90a, 0x37713d37,
+ 0x72ba018d, 0x011c3fbb, 0x54c14ff8, 0x8a7167ed, 0x0070fee2, 0x45f18fc2,
+ 0x29d23c73, 0xdeb0dbb5, 0xfd1e7b3f, 0x479d13f5, 0xb680f92b, 0xf8645b47,
+ 0x3e91edf9, 0x533e96f8, 0xed4f000a, 0x9fb017f2, 0xefbfe8db, 0x12bf4186,
+ 0x037ed5e6, 0xfcd0622d, 0xacdef823, 0xf3b68f1b, 0xb43136a8, 0x255e9feb,
+ 0x27a55c72, 0x0bfeda2a, 0xce3b403a, 0xfdcbd6ea, 0xd03e5d78, 0xedd6ea96,
+ 0xe50bf003, 0x482c527b, 0x9ce52f40, 0xc7247a7a, 0xefce811a, 0xf461e088,
+ 0x157ab026, 0xefc54e96, 0x00ec3241, 0xae7e603d, 0x5b9e6f4a, 0xf972a5de,
+ 0xe4c87fd4, 0x9aff287e, 0xda272ace, 0xc4c0951f, 0x780bf344, 0xd96b7e6e,
+ 0xa7779074, 0x5e1f6c4c, 0x605c0a48, 0xda931494, 0x3e43d01c, 0xa07ca626,
+ 0xffc98ffb, 0xec696576, 0x05261181, 0x8d60b3e7, 0xfaa41f7e, 0x545f2e93,
+ 0x9217cfaf, 0xce80921b, 0x1264eb0b, 0xf51f8012, 0xc62689e5, 0x6aa4450f,
+ 0x2b0fec15, 0xdf313db8, 0x74c1a44d, 0x1ebb157e, 0xe74799cb, 0xc989b971,
+ 0x2ebed56f, 0x2ff36049, 0x7c54696d, 0xd683fcb4, 0x415c9fac, 0x15687da0,
+ 0x3b8219f8, 0x4f26ef04, 0xd0fdfc5f, 0xabe71bf9, 0xec7d1fee, 0x8a8f3e7c,
+ 0x142f82cd, 0x6f191f63, 0x13fef812, 0x035e3844, 0x99e8d6eb, 0xa8387337,
+ 0xf28679f9, 0xeffe430a, 0xa244b7a6, 0x8223b7a3, 0x40d366ff, 0x5fa05f46,
+ 0xf1445209, 0xa7fd23ff, 0x9e7fe9f4, 0xb13fdc69, 0xffb421ff, 0x15ff5d1c,
+ 0x47fed4ff, 0xddff99f4, 0xd8affab1, 0x906775b5, 0xe7d29bca, 0xba11761e,
+ 0x6a929cff, 0xff14bc93, 0xba569be5, 0x4a4e0e80, 0xf3d01741, 0x1f9890a9,
+ 0x3f57618a, 0x3e0f4bd7, 0x0f760087, 0x3ffb4afc, 0x3303f4fd, 0x62f97f60,
+ 0x7b46ec93, 0x6c39b366, 0xd95afca6, 0x8c9d325a, 0x9631fcc5, 0x0889fd5f,
+ 0x7d3d36f9, 0x70f53e96, 0x28c7f812, 0x3f7d70a5, 0x6552fa8c, 0xb07947d3,
+ 0x044804ff, 0x0ed8ccf9, 0x80973fc6, 0x129e71f2, 0xce9cb7d7, 0x00f0f513,
+ 0xf5a04b87, 0xf0444f81, 0xe64e924d, 0x2fd434a7, 0xc84f7ae6, 0x4e3c4ce4,
+ 0x6ff23c55, 0x5e40dfe4, 0x2120f0aa, 0xbb88f7a6, 0x760b1b1e, 0x7fd3576b,
+ 0x9c0d04b8, 0xdb3b3e54, 0xe7f1e0b2, 0xe3cbfd3d, 0x45876e6e, 0x9db085db,
+ 0x6beb8da7, 0x972d2ced, 0x63f02ec3, 0xdeca3796, 0xbe5cfd20, 0x1f2789f5,
+ 0x6df23b05, 0xda62f7b3, 0x97d6d97f, 0xe6813cfe, 0x89c9b6cb, 0x1c32d9d3,
+ 0x2f145242, 0x696ffa01, 0xa50f1466, 0xf1497fbf, 0xefdf618c, 0xa3e2884d,
+ 0x857edb6c, 0x8f0be98c, 0x95fb2d29, 0xbc0c474e, 0x03cb1cb4, 0xf5dc4abd,
+ 0x3f78028d, 0xc9204fb5, 0xd9e031e9, 0x07ea12f8, 0x23c42700, 0xde2f53c7,
+ 0x1403f50c, 0x55cf202f, 0x97cb193c, 0xfd037973, 0x3d234679, 0xf83cfb3f,
+ 0x7b31df7d, 0xcfc5fd61, 0x7582e9de, 0x18aa909c, 0x32b63f5d, 0x2dc747c9,
+ 0x6e498396, 0xe2f7d94c, 0x7a433f0d, 0x67fd7a2b, 0xf35ecc49, 0x6f709aa5,
+ 0xfac2a60a, 0x8cdc3516, 0x7e242beb, 0xc7e2bba4, 0x8f9002c4, 0x7f244b9f,
+ 0xb8be0c5b, 0x717c6458, 0xb4552362, 0xd04efae8, 0xa0fd076d, 0x6d0c5bff,
+ 0x1dc57f42, 0x67fff804, 0x2c9affaa, 0x16e7fcc6, 0x4dafa786, 0xb54f9eaa,
+ 0x36bd2d3c, 0xfc00eead, 0x4bea1e9c, 0x80573f06, 0x0f0e4148, 0xafda3be1,
+ 0x64b4faf8, 0x91e21f86, 0xaa3b7872, 0xef814c07, 0xf643bf50, 0xdaeac759,
+ 0xa3d2ef91, 0xe3e12fe3, 0x60db79d3, 0x44913eff, 0xac625b8a, 0xf2a8a66f,
+ 0x35c7dd3d, 0x6fe1a5f4, 0xf74defc6, 0xf956fe31, 0x1f33343d, 0x837b3fca,
+ 0x83b40ff1, 0x2bce91fd, 0xfbe58c9c, 0x1e50126f, 0x16384998, 0x9cc9375f,
+ 0x2ae5f5af, 0x4b79d09d, 0x5e869c42, 0x8404ffa0, 0x0ab7fa3f, 0x8d3b68eb,
+ 0x78c00cbc, 0xa9fdbeae, 0xf9c45b7c, 0xf9ea23df, 0xbe30349f, 0x0abf5fef,
+ 0x2e573ee2, 0x147c9e87, 0x67f295f8, 0x2afc03d0, 0xcfbac017, 0xf3fc1f34,
+ 0x9c9f294f, 0x54f95169, 0x7c8d3f2f, 0x5c7dbc5a, 0xb33d3e4c, 0x9f362336,
+ 0xf931efd2, 0xd3e32d74, 0x53f25bff, 0xc03e5f85, 0xfc28f2ef, 0x1fd87954,
+ 0xf0f28d1c, 0xe1079323, 0xf4879469, 0xd3920de7, 0xba54fe97, 0xf4ade953,
+ 0x408b8a99, 0xa5d2f4ee, 0x74bd774a, 0x1f5dd2a9, 0x7e0e88ff, 0xa004f2c6,
+ 0x05274a05, 0x0de48fbb, 0x6f2cf8a6, 0xb440e767, 0xa790cbdd, 0x36e1f270,
+ 0x1e5f6a46, 0x87cda89c, 0x4316f90c, 0x5f219f7d, 0x37efa860, 0xf50cabe4,
+ 0xd03fcc43, 0x48215076, 0x7d5d6107, 0x3a093979, 0x57b72fc1, 0x87affb44,
+ 0x6d1579ce, 0x1e9cd3df, 0xb079520a, 0xeaeccad2, 0x156540c8, 0x771eafc8,
+ 0x790095c4, 0x7b6bd32b, 0x78ae220a, 0xac787e8d, 0xdbf9445d, 0x5af92219,
+ 0x1f94457f, 0x9d7f106a, 0xe672bfa4, 0x3a269c67, 0x3d8296d2, 0xc17a2b59,
+ 0xecb85d44, 0x3cb81716, 0x5f87da7a, 0x5f7e8b3f, 0xe3c45874, 0x6b9b1e8b,
+ 0x048bcc2c, 0xc6aa527d, 0x8249382e, 0x7e089dbf, 0x1f6676c3, 0xd06b5c2c,
+ 0xa45ac82b, 0x12c7428b, 0xd522e405, 0xfbd7dfe7, 0x977d194d, 0x1b8afef2,
+ 0x7b6ae5f4, 0x3b023938, 0x5f49b4ad, 0xce76e7ee, 0x67bd2a93, 0x17940c90,
+ 0x7d80c060, 0x34ebe5cd, 0xb3f5f471, 0x0e7bfc28, 0xe5e80489, 0xf088bb6c,
+ 0xceccdb3f, 0x20704909, 0x89254df2, 0xe1535ca0, 0xa17c05d4, 0xba772ff4,
+ 0xe735fc76, 0x7ca55a1e, 0x7f63bbe7, 0x9daed347, 0x03dc8f6f, 0xa66f5df9,
+ 0xd6fa4bbd, 0x8acfb29f, 0x7d9ed9fe, 0xe94f3c4e, 0xda6afbd9, 0x6ddf903d,
+ 0x7b3cc2f6, 0x16397df6, 0xb967a7e8, 0x56e418b9, 0x7f8a50cf, 0xfdecd69a,
+ 0xee276c72, 0x6f102b93, 0xd30a8baf, 0x76ffda73, 0x94844854, 0xfff60aae,
+ 0x33f4767d, 0xa2b79e04, 0xef67a07f, 0xc77e3997, 0x953d6f3f, 0xc7a4dcfc,
+ 0x876d6649, 0x7f33c5f9, 0xf8cf6073, 0xb9c19627, 0x657eeb6f, 0xf29f2d01,
+ 0x416337c2, 0x676cf61e, 0xdcb74d7a, 0x05ce01b9, 0xeef352fe, 0xb9c29932,
+ 0x1062981b, 0x862bb995, 0x623a0e4c, 0xf41be5c1, 0x3c285c7b, 0x067ffd3e,
+ 0xf79e021e, 0x433bb795, 0xfdd60116, 0x4177d1d5, 0x2333ec0e, 0x3debaa5d,
+ 0xf50cb2d3, 0x3badf38e, 0xf5f66241, 0x0b759cff, 0x77590be1, 0x8daff486,
+ 0x07a25def, 0x83e462f1, 0xf7be74be, 0x756fcc2e, 0x17be717a, 0xff33ef48,
+ 0x83ffd7c5, 0xe29dbef1, 0x75fe75dd, 0xaf8bfd57, 0x1fbc7fbb, 0xeef1c39e,
+ 0xc0f57386, 0xfce0df0b, 0xab9ca87e, 0xf7e717fd, 0xeaafd6fe, 0x79307fe7,
+ 0xf5a0c8de, 0x03ad49f3, 0x2a6b8b14, 0xa0ce1c0e, 0x72187fa5, 0x3be61e30,
+ 0x18c39f99, 0x125fb7e7, 0xc164fdb0, 0x891d7684, 0xc75db817, 0x5cc1a1ec,
+ 0xa4bc187f, 0xc190f510, 0x7a641e43, 0x83a9e483, 0xa43fbe73, 0xcc62f02d,
+ 0xcb7cc902, 0x95f7790f, 0x0bb7af3c, 0x1f10277f, 0x4e0e411c, 0xa043f7fb,
+ 0x22190e9f, 0x534afea2, 0x745f5bd4, 0xe5efb3e5, 0xb97ece8a, 0x67b7a3c6,
+ 0x76f512f2, 0xdfde54cf, 0x3fe6c234, 0x428421cd, 0x87930e14, 0xfc1126fe,
+ 0x962f939c, 0x79f34089, 0xec02bfc4, 0x7d0ea984, 0x19c18f7f, 0x580fc68c,
+ 0x16bb6964, 0xaf16dffc, 0xd25dfd80, 0x62794265, 0x0e9016c9, 0x984bd546,
+ 0x1ee4dd7f, 0x719e7007, 0x7733aec5, 0xfa97f013, 0x528f1614, 0x5fdefcc0,
+ 0x44ddf77f, 0xf0e2e388, 0xaeffa22b, 0x036eff03, 0x7ae8db09, 0x18244917,
+ 0x4efe0097, 0xf3afbc81, 0xf0f3ea77, 0x68a4e3f3, 0xdfabe73f, 0xb3fe1d1f,
+ 0xee945dd3, 0xdbb0a7df, 0x1c08e90d, 0x53dad25e, 0xe0ced6ff, 0x84857815,
+ 0x6ef3b186, 0x2e7340b1, 0xeccca974, 0xd97f5dee, 0xccf6059e, 0x71d19ea4,
+ 0xa0471f8c, 0xfae0197e, 0x89e259e5, 0x1f803af3, 0x79e1c787, 0x19d121d7,
+ 0x0b6bde2b, 0x819eb3b7, 0xf69a5073, 0x115a9134, 0x41127df4, 0xc9b05dff,
+ 0x88c53642, 0x4d94483b, 0xe39c5cfc, 0x3988fe8d, 0xe36787e0, 0xe34da22f,
+ 0x9aeb78b4, 0xdb1a4a7e, 0xf3f00f17, 0xe21ce6be, 0xd82f851f, 0x2ddf0075,
+ 0x82bcced6, 0x923b7c18, 0x81c66fc3, 0xbe9ed0af, 0x04d1bdac, 0x93597e7c,
+ 0x969e7749, 0x3dfd7326, 0xbcc26493, 0x3ab01c66, 0x872f01b3, 0xd9c42f44,
+ 0x513fda05, 0x83ce31fc, 0xfe84f08c, 0x9b7a8fc1, 0xed7846ec, 0x00165b91,
+ 0x6c7cf75c, 0xed676021, 0x62cb6a56, 0x0a4ff3cd, 0xd222e79b, 0xf4d8e772,
+ 0x4ef83d7f, 0x278471ea, 0x44d2bd83, 0xd2fbaf90, 0x3e3a411f, 0x408499bb,
+ 0x037d831e, 0x336ce172, 0x8280fdc1, 0xd3b041e4, 0xa55fbf28, 0x692fdfb5,
+ 0xec0cf6db, 0x82ed9523, 0x95cb5c1b, 0xfe02a752, 0xbc5b40b9, 0xc33b7208,
+ 0xba21c6a3, 0xe1a4dcc7, 0x0964db8b, 0xc2707be1, 0xdc615b9e, 0x0214bb4f,
+ 0xc5ef9afb, 0xfee40b88, 0xc859eda7, 0xebadfd07, 0xdae4d5f7, 0xc3f412a9,
+ 0x1e919ae4, 0x74db3746, 0xff442bf9, 0x19afe020, 0xde25cee6, 0x96fbf818,
+ 0xcb05d9d3, 0x67ffd0b7, 0x550dedf2, 0x02c5f9be, 0x2cbd1f0d, 0x23557db3,
+ 0xc96392df, 0x2782c5b7, 0x78bee019, 0xc064f0ef, 0xf2c3e2eb, 0x6df258c0,
+ 0xdf3b356b, 0x8fc78e7a, 0xf952b4f6, 0x7c8d23f6, 0x2df2a56b, 0x8b7ff9c6,
+ 0xcf5ffaac, 0xff42df23, 0x15b7fc3d, 0xf58c5be4, 0x53f0e41e, 0xf6d8dbe5,
+ 0xc6df2863, 0x71749ab6, 0xdccbcf96, 0x7cafd99f, 0x04de0613, 0xd921d4fa,
+ 0x3f418f6b, 0xf6feb95b, 0x819f8f1c, 0x7dce4071, 0xdce503f5, 0xe72a173b,
+ 0xace09bfe, 0x3bc5b9ca, 0xf69fc608, 0xe72643a5, 0x72a6ef16, 0x647a004e,
+ 0x5ef16e72, 0x0638fcc2, 0x8faa36f9, 0xbf58237c, 0x07dacc32, 0xb91fd2da,
+ 0xe997f68d, 0x5a16bd93, 0xef2a333f, 0xdde569c6, 0xbbc9fd57, 0xef261743,
+ 0x47797076, 0x9030d8e5, 0xf0fa46af, 0x74e3ebb6, 0xd13f8cf7, 0x97e07bfc,
+ 0x673c4557, 0xcec4dd7a, 0xfe34fe05, 0x57d03644, 0x33e6c281, 0xd7f46142,
+ 0xfec41d5d, 0xd6c8bca7, 0xf160e157, 0x4cad95bb, 0x166cac3f, 0x6bfa1e42,
+ 0xf0af84de, 0xaf64a8bc, 0x7e699240, 0x27d599a6, 0x24e7a94f, 0x86867a64,
+ 0x96e6161e, 0xa1777fa1, 0xbfe02c44, 0x9de4732d, 0x2cb63d02, 0xcb7bf997,
+ 0xc392f7f8, 0xdfc0ab9d, 0xc05eb259, 0xee353273, 0xecbf8d50, 0xbede5e73,
+ 0xc681fd0c, 0x3c19f373, 0x33c6664e, 0xc631a842, 0x66d97fb9, 0xa71a7e7d,
+ 0x276299e7, 0x26bc8bc2, 0xe0c5377a, 0x2f5eb51f, 0x38710e9c, 0x9fb88935,
+ 0xc289c2f6, 0x17de93cd, 0xd3d3144e, 0x70a29233, 0xae957929, 0xf5ffbb37,
+ 0xae3370aa, 0x9677f55b, 0x83fa7ef1, 0x3ee70a83, 0x2770e7eb, 0xd2728424,
+ 0x95ab8f08, 0x16683f5e, 0xba50a7c4, 0xfc133941, 0x0d7188a3, 0xd62e9305,
+ 0x8eb843dd, 0xed564fd3, 0x8c7029a4, 0x7de2133d, 0xfeaddce1, 0x6e21978e,
+ 0x9e5bdc6f, 0xaf4ed84c, 0xc3f66098, 0x6b16dbf9, 0x4aa0e504, 0x87408d87,
+ 0xf0f7ae14, 0xaa0cf67e, 0x61768c9a, 0x3d06e09b, 0x22b61024, 0xae14035c,
+ 0x20242f70, 0x2806fc31, 0x1dff023d, 0x8305ff5c, 0x03c15ee3, 0x753c80fe,
+ 0xd0bc02bf, 0x0ced59fa, 0x8090812f, 0x1126c978, 0xd657bbf4, 0xc030de0b,
+ 0xe111adaf, 0xfa67caa7, 0x49e2d0e3, 0x2c52bf43, 0x9a4ac5fa, 0xd78cb2fd,
+ 0xfdae619b, 0x8cf3d033, 0x88d264a7, 0x7dffa6e0, 0x279f3d1f, 0xa788c3fe,
+ 0xb6bc39c7, 0x001d3c02, 0xbbd308b7, 0x3de15fc2, 0x203cb515, 0x9cf07505,
+ 0xefb9e8f2, 0x1538d785, 0x20c7405e, 0x89e7dadf, 0x136c2f90, 0xbef480c8,
+ 0x307385eb, 0xec97bf2d, 0x7ffac63d, 0x1892f04c, 0xba60beeb, 0x8b9e87ee,
+ 0x7f82dd29, 0x36ba3fbd, 0xe151a9c2, 0xe7a726fb, 0xaf23593f, 0xef3d0164,
+ 0x49cf9015, 0x3ceebc7b, 0xf4c2bf6b, 0x4a562d88, 0x91dd74f7, 0xa377b2c3,
+ 0xd83cafa7, 0xf60be1ce, 0xd01ef683, 0x8810b0a5, 0xc16cdc0f, 0xc79c2f38,
+ 0x6a9fa630, 0x2b56f3e5, 0x76537819, 0x7987fdff, 0x47e9fdff, 0x8c0c7e6a,
+ 0x6dcd7107, 0xd151bc74, 0x83fb8cf1, 0x6f9ff76a, 0x3972af5d, 0x4baef7f7,
+ 0xc687e71d, 0x074804c1, 0x878d55e2, 0xc7f82239, 0xe5cfa0c8, 0xae3e920b,
+ 0xd6e5c22c, 0x1fffdc3f, 0x927fafbf, 0x4e7bc6e2, 0xefd5ba77, 0x02cfa46e,
+ 0x41e7e137, 0x7d84df13, 0x3b1f53ff, 0x9136caf7, 0xff611323, 0xa0132c98,
+ 0x915f4fab, 0xe9f96fd1, 0x79671654, 0x2507abfd, 0xcf5cdd70, 0xf5c8a162,
+ 0xb3b404e3, 0xc7ae875e, 0x216e1e83, 0xbf0891be, 0x954fb82c, 0xc53b54d1,
+ 0x733af943, 0x5206a873, 0xe24894ef, 0x936f009f, 0xeb780244, 0xe2980df0,
+ 0x3f3bf9a0, 0x32e01922, 0xb601faa3, 0x06443ccf, 0xbe09bd42, 0x8cc66881,
+ 0x8decfd6f, 0xc63ce91b, 0x3d7a22bf, 0x83ccdeb4, 0xfaa1070e, 0x1306a8f4,
+ 0x35e06bf1, 0xc06a8481, 0x43fe346f, 0xef308ddf, 0x40efaa62, 0x7b717efc,
+ 0xf20b8d63, 0x0fb6020d, 0x2e79fd04, 0xf5ad9eba, 0x0e5de49f, 0x83d68172,
+ 0xac0d026e, 0xf049a05e, 0x616a4842, 0xe5053afb, 0x17809346, 0x0486b6bd,
+ 0x86fd6162, 0xaddfb42c, 0x367db40d, 0x3db45fec, 0xc9f4dbf4, 0xdc82371b,
+ 0xf6c4f3a1, 0xb63ceccd, 0x00f3b690, 0x81dd34bf, 0x083495fd, 0x1419ee04,
+ 0xa97db337, 0x0bd915f8, 0xd7fbade5, 0x9d3b7ee3, 0x0e9a978e, 0x2a7850fb,
+ 0x12c8d7de, 0x6d8f78dc, 0x5fc450fa, 0x23f8610f, 0x1c984389, 0xdb9e7813,
+ 0xf7deaa3d, 0xe430f32b, 0x32ef4283, 0xe7ed0065, 0xd303b94f, 0x9f57484d,
+ 0x7da7a028, 0xa7ede148, 0xc79d7ef0, 0xfdcc1c29, 0xecd4e940, 0xe1e6cd8b,
+ 0xdb617ed8, 0x5a7f8c24, 0xfcf00a44, 0xa678c67e, 0xa576be6f, 0xbafe0435,
+ 0x10c8e4d7, 0x4af07ef8, 0xdeef7e33, 0xf770e4ca, 0xcff44ed0, 0x0990689e,
+ 0x69a82fdc, 0x9c5e5110, 0xbcf19668, 0x464c7c5a, 0x95b45db9, 0x1b071fe9,
+ 0x4027bf58, 0x393f036f, 0xd17cd394, 0xfbdb8116, 0xf6ab4e4c, 0x9d9ba167,
+ 0xb772abbb, 0xcfbbaf82, 0x4cb7543e, 0xca359201, 0x8f2e0adb, 0x02a4a94b,
+ 0xddca3342, 0x7577380a, 0xe31a5f01, 0x3b511c83, 0xfc20e806, 0xe575d215,
+ 0x3b01322b, 0x2ba0f846, 0x6a7de60f, 0xee7e80af, 0x0f82edf1, 0xdf8bbdce,
+ 0xff508732, 0xfb9bcd0e, 0xde5fd80b, 0x55081336, 0xa0780e3d, 0x1cd72a72,
+ 0xe86fcbf9, 0x5baf53f7, 0xd2841220, 0xbb843ccd, 0xbd99df1a, 0x6471c589,
+ 0x04975ebf, 0xd4c92cf7, 0x8a072801, 0xd7e245ea, 0x825389c8, 0xb29fc6ef,
+ 0x8dadc1fd, 0x6a56cce3, 0x3d7f610b, 0xd1f2666a, 0xd88649b3, 0xccd2b208,
+ 0x0fb534e4, 0x64b2fe30, 0x4524baf7, 0x7b250743, 0xf48925d7, 0x071e2afb,
+ 0x2bfb0351, 0xb0a2576d, 0x09f64a71, 0x38cd46ee, 0xbf6a3f6a, 0x6ed66eca,
+ 0xf6965ef8, 0xcc097fd7, 0xb9f9d70f, 0xd8c2f202, 0xfbf19f4f, 0x3ff727e9,
+ 0x7409d5cf, 0x89afb95e, 0xfb9ca418, 0xdae1f4c1, 0x55350073, 0xde7215e3,
+ 0x069f1130, 0xb17fb97e, 0xdf069f11, 0xdf28e3ad, 0xd75dfc53, 0x02ac8426,
+ 0x15298fe4, 0x037798d9, 0xff72579f, 0x7654e573, 0xf19ad3be, 0xfbe00afa,
+ 0xd202d9e9, 0x95fa0903, 0xafa88901, 0xb8ce2079, 0x2fb59b28, 0x1f81eda2,
+ 0xfe33d75b, 0x03c272a4, 0x61b2a472, 0x6fd61e5d, 0x7fd03c12, 0xd43ce36b,
+ 0x45738a47, 0xc74de582, 0x6e2a3f50, 0x7c08963b, 0x0eb6f94c, 0x89ca81f4,
+ 0x71c83766, 0xfe551f95, 0x05c78d7e, 0x0c7b8b13, 0x0067e3c4, 0xcbec0df3,
+ 0x4c2be2d7, 0x199a07ae, 0x1972063f, 0x55b6bebf, 0x085e1586, 0x9f3f237f,
+ 0x55f8ccd8, 0x3ce6ec7c, 0xb45ca7b8, 0x1ca7c589, 0x80a2986c, 0x24227d3e,
+ 0x97d37ee0, 0x6ade99bf, 0x811aefe4, 0x543f7bed, 0x5bf954bf, 0x73fa63e5,
+ 0x4e578c1d, 0xb5ee14f9, 0x867af919, 0x3be7f2dc, 0x7faf7ce9, 0xce87ae96,
+ 0xef8fca77, 0xe46a7576, 0x4127cd24, 0x716250be, 0xa95caa3c, 0xd7bc5890,
+ 0x619f9e0f, 0x7acd1bfc, 0x734ac8ff, 0x6e6b8b3c, 0xcfee9192, 0xf87d9fc7,
+ 0xf3f902ec, 0x7ceaf942, 0x2f8ea9fc, 0xb3f7d5ee, 0xb19bd392, 0xd70a6ebf,
+ 0x1feb8530, 0xb8c09f9a, 0x3e9f8fb1, 0x53f00336, 0x39d287b6, 0x93b357d0,
+ 0x49ce4184, 0x4aafdc21, 0xc61f455b, 0x9ce14abf, 0x3e5a9d1b, 0x653e7166,
+ 0x9e9139cf, 0x439bb74a, 0xd2fb69d3, 0xc58c1f9d, 0x11e58bb8, 0x3e0a438c,
+ 0x60e5f5cd, 0x83e058e7, 0x1bc58952, 0x00c2e519, 0xe8673b0b, 0x059f6dda,
+ 0xb33613eb, 0x2da5fd7b, 0xcd66c8b7, 0x22cd84b9, 0x1cf0f5ab, 0x18e94830,
+ 0xfcc255ee, 0xd5c9f7b4, 0x2daea338, 0xb6944e4c, 0x960768c9, 0x0dd6de6e,
+ 0x6fa5a371, 0x15dfd199, 0xc609fcd8, 0x6e794fc1, 0x0253fa2b, 0xfceea26d,
+ 0xdebc4fac, 0x866c3166, 0x0ad6b378, 0xf9a3ef3c, 0x896f9863, 0xbe7ab71d,
+ 0xe7b2b2b8, 0x520ceef6, 0xfefd9610, 0x97c81729, 0x5c9b1dd3, 0xf9b7b718,
+ 0xfb65e3fb, 0xdcb5e7c4, 0x79f1bdf7, 0xca17e1a7, 0x862d1338, 0x03cdc6f8,
+ 0xf3a48f50, 0x718829cb, 0x97abd1ce, 0x037cfd6f, 0x6d778fc4, 0xe601b33f,
+ 0xa7edfe5b, 0x887e201b, 0x7ee2b3ec, 0x08fa7817, 0xedaadfc6, 0x7ee1627e,
+ 0x614f2d8f, 0xdbf772dc, 0xd6f42f66, 0x1a44f7bd, 0x6f758fc4, 0xfc092afb,
+ 0x4ef64b96, 0x92eebf43, 0x4992531d, 0x4d42fd8c, 0x17436e81, 0xc46d3710,
+ 0x83d6c1d7, 0x31f4e718, 0xbfc837c5, 0x96cb78de, 0xeabf160a, 0xcd9671e1,
+ 0xfbd3e3b1, 0xdeb655c4, 0x2095fd78, 0xfe995bf7, 0xcaf8de78, 0x7f1e2837,
+ 0x6bf80174, 0xb102fd56, 0xfc31f7f1, 0x76e21e32, 0xbcfbf8f5, 0x8fe3d175,
+ 0x80eb5942, 0xc32be37e, 0x35370017, 0xc5927dfe, 0xbe016d57, 0xc60cfed9,
+ 0xa6de02b3, 0xf9ff607b, 0x0dee0d3c, 0x7323949c, 0x5ed93ef0, 0x09e21bb3,
+ 0x89bef74b, 0xe3bdd3fc, 0x1343f475, 0x4dde871e, 0xdc587f7a, 0xd9d7c0b0,
+ 0x997164e4, 0xb710fe1c, 0x77e171e9, 0xe8c99f1e, 0xecdb8d58, 0xa7735e2f,
+ 0x6ad9e985, 0xd3457e5c, 0x31fe3cbb, 0x17212f8a, 0x7bec74f0, 0x70a811ef,
+ 0x1c397370, 0x1d8e3f8d, 0xa71bdb17, 0xf805f1ce, 0x37a87d83, 0x87e698be,
+ 0xe8dfa264, 0x1e43124d, 0xb8b23774, 0x7f596ee5, 0x1f8a33df, 0xcdbc8f16,
+ 0x0ba1a7c8, 0xdf3e438b, 0x7c287ffc, 0x33f28236, 0xba9c2fb0, 0xc72d8ebe,
+ 0xff7ce0df, 0x5967df77, 0xb3ef1828, 0x63d027fc, 0x0531eb45, 0x3b5ee0ec,
+ 0x8bb7af9b, 0x9ebbd5fb, 0x759e3116, 0x9441cb55, 0x517946e3, 0xc458ef09,
+ 0x0b71ef98, 0xd8dbc3d7, 0xddb5d13e, 0x7ed07219, 0x46ec0eba, 0x3e6cae7a,
+ 0xe09c40a6, 0xaf7f9bcb, 0xc629f3b0, 0x844fb03f, 0x7aeff334, 0x1658ff76,
+ 0xf8fccd6f, 0xe33e71c6, 0x63da04e3, 0xfe68138f, 0x594e3744, 0x3b7145b0,
+ 0x69de3fce, 0xf40b77c9, 0xe983ba77, 0xc45ba783, 0xb9f758fc, 0x66fbe4de,
+ 0x743d7bef, 0x4177c4bf, 0x101dec9c, 0xfd4365d1, 0xf7338972, 0x4844b8ad,
+ 0xa9ef8c15, 0x81e3c659, 0x014de97e, 0xaf38d77c, 0x95df3025, 0x9f8d5f00,
+ 0x09fb7647, 0x4a72a5e8, 0x15f83641, 0x4946f28c, 0x06909134, 0xf99c4bff,
+ 0xef3c1ec9, 0x7c010f08, 0x2138cd1e, 0x19efbf43, 0x49ef54fc, 0x9d325564,
+ 0xc1417bdf, 0x4bf68cbb, 0x6860febe, 0xff6fb381, 0xaf7fde6a, 0x552bf3a8,
+ 0xc147239a, 0x582f212e, 0xdc41be31, 0x17f7c567, 0xb8ac1b02, 0xbe3b83de,
+ 0xebf5127c, 0x9d84cdc7, 0x85eb50fb, 0x9b915fd2, 0xc76271f5, 0x06fe1b97,
+ 0xa63433fa, 0xa06d17e3, 0x686ec1f5, 0xd39da3b6, 0x2c6e3db3, 0x5e8a45f8,
+ 0xc80667b8, 0xa33b22b3, 0x92e7a2c7, 0xbfb43543, 0xfe5903e3, 0x78a1d6f8,
+ 0xbb6cbfdf, 0x0f0ce313, 0x0955d8ee, 0x73f752fb, 0x52fb0276, 0xcf5c0bf7,
+ 0x1fbf867f, 0xb47b2f54, 0x4425c6f1, 0x71ef68f2, 0x959e4194, 0xfc107de3,
+ 0x047ce1c9, 0x38b6aafe, 0xf541ffbc, 0x1f3f5d5f, 0xbcbb91cb, 0x41c1c748,
+ 0x784bdeec, 0x6303c810, 0x4afcb53d, 0x8f7e30eb, 0x4473b698, 0x489407eb,
+ 0x0ed7cb21, 0x03a4f262, 0x656b5feb, 0xf796affc, 0xcfd597ed, 0xd5d30eb7,
+ 0xf257db53, 0xf48c41f7, 0xe055b37b, 0x2e6fc1fe, 0x45fef589, 0xf7e3f98c,
+ 0x6824099f, 0x9b653d02, 0x8225df15, 0xdf10f37b, 0xe76153be, 0x30aee55a,
+ 0x87b23fbe, 0x5b72e3cb, 0x1943df18, 0xf501e7c4, 0x9d2c4f21, 0x56bbe2cf,
+ 0xde04acbb, 0xc178a9c7, 0x577c03e9, 0xf8f2fcec, 0x8e21b2ef, 0xd4718ecd,
+ 0x1cfc2f15, 0x1cc2a0e9, 0x10fc039e, 0x1b2666d9, 0x1db7cf81, 0xed7e034e,
+ 0x0969c392, 0x575e73df, 0xbc3662d1, 0x71d6c01f, 0x0afebaba, 0xdeace7b8,
+ 0x47ed2ca7, 0x656b3cce, 0x585fe87e, 0x78ad4b7d, 0x677fadae, 0xacf574e7,
+ 0xaf57b82c, 0xc4b52fd6, 0xad6b8b96, 0x4f763ff2, 0x5ee7d1d8, 0x40eb5ae2,
+ 0x923a63d0, 0x4953efc0, 0xe7906ef5, 0x87d39ba5, 0x80e09f80, 0xee77bd55,
+ 0xe8fd8389, 0x7b41ec80, 0x3eed521a, 0x9bdab273, 0xff008d25, 0x892ca8cd,
+ 0xf1a7a3ae, 0x0441c293, 0xb3ad0ee2, 0x0dbdc962, 0xa3c23b56, 0xc5f662d4,
+ 0x0cf8d7ba, 0xc107d7a7, 0xc6c71fe8, 0xc750fe03, 0x5087203d, 0x79b70f0e,
+ 0x2ed43f58, 0x9b65ef82, 0xdee96767, 0xb16a90c5, 0x8453e51e, 0x53a90967,
+ 0x5bf235b2, 0x6964af1d, 0x05949676, 0xeaffa5df, 0x8a3157a5, 0x444c1267,
+ 0x30e250bd, 0xbaa97526, 0x5c9204fb, 0x29f80160, 0x892dc0a4, 0xc8b52a40,
+ 0x82d236ef, 0x5baa83a9, 0x2aa8fdec, 0x64f27202, 0x0417bbef, 0xeebc28d3,
+ 0x1c1fb946, 0xe9c5c84a, 0x13dfff70, 0xafc0d6e7, 0xf9c2eacd, 0xc22aa598,
+ 0x3774c5e4, 0xd04223e8, 0xf4a3be4f, 0x9f9d5354, 0x7f48f405, 0x0cff707c,
+ 0x3f3a0f4d, 0xafe5fb97, 0x74a20f40, 0xfb59deca, 0x50d50931, 0x28f84310,
+ 0x132755fa, 0x9ad83ef6, 0xded688b7, 0x6fe72bf8, 0x728fdc12, 0x3fa241cc,
+ 0xb1079a11, 0x26b6f20a, 0x385cdbee, 0x49b87447, 0xbb42f418, 0x34ed8483,
+ 0x4e968c75, 0x95dff96b, 0x3a1af34d, 0x97d44f75, 0xca82f91b, 0x2db8c335,
+ 0xefda3f08, 0x3f7e8667, 0xd9fbf433, 0xc2abf5f7, 0xe8d96029, 0x5609f785,
+ 0xb8701756, 0x1c2cf1b1, 0xa33e146e, 0x62337de0, 0x79f979b2, 0xc6d5c238,
+ 0xfa866367, 0x6c83af14, 0x07a708e9, 0x2045f6e2, 0xd624966e, 0x577bb013,
+ 0xa69f6c08, 0x4d0e053f, 0x20b6e23b, 0xc7c7de1f, 0xf4636419, 0xef5bdeae,
+ 0xe78adf5b, 0x5bea7d1a, 0x8b6fabfb, 0xdfd9df5d, 0xe731ec7c, 0x4ce543f3,
+ 0xfe6f0be5, 0x7b61ce09, 0x829b8de5, 0x6f274732, 0x9c28d906, 0x7f8fe22a,
+ 0x985f89db, 0xa21968de, 0xe80d9fc7, 0x6d8fd295, 0x11bbfe84, 0xcbd1fdef,
+ 0x9a0ebe3c, 0x75d2a477, 0x3f8f94fd, 0x639d89b5, 0xf984b6df, 0xe7b9a8dd,
+ 0xf2b7fa83, 0x14b53ffa, 0x18e0ffa1, 0xb6e9177f, 0xde17a67a, 0xe788af76,
+ 0xfdde7dcd, 0xff285f81, 0x0854bedc, 0xbd63d385, 0xe09a4463, 0x3e5cd47e,
+ 0x205df1be, 0xade4f13f, 0x0bbd6311, 0xbd4ce8c4, 0x6f7c6557, 0xe0292160,
+ 0xbfe93def, 0x91bab26f, 0xd61e410e, 0x4bee8e8e, 0x8e9475c1, 0x74a49f41,
+ 0x70ece70c, 0x3ce3063d, 0xf38b0a5c, 0xe78a18e8, 0x3b3caa63, 0xe1c4f1eb,
+ 0xd34deafe, 0x78b817bd, 0x5e3927bc, 0x73a5af23, 0x2b7bdd36, 0x0537b235,
+ 0xee7c95e4, 0xa6a1e232, 0x1e8d42af, 0xea9ca68f, 0x10ccc8a1, 0x277284a6,
+ 0x9c810a45, 0xa405dc93, 0x9958f408, 0x5f5aa7d1, 0x57acbc49, 0xfe8d7c6f,
+ 0x878801bb, 0x3be2e5d2, 0xd728c93c, 0xe00b05ed, 0xf5cae893, 0xe97d1dfa,
+ 0xad95b821, 0x9dd606bb, 0x353d77de, 0xfa8bd78a, 0xf7de84f3, 0x3f302c69,
+ 0xd379ecd1, 0x0ffbf303, 0xa51f8099, 0x27bc7c2f, 0x677e1443, 0xde318343,
+ 0x3e9b8c43, 0xdf57c612, 0x9d535c45, 0x2bade782, 0x2b897bf8, 0xfe6147aa,
+ 0xe59efe7e, 0xa60f6aaa, 0xde2cfc2a, 0xcfc77c5a, 0x6ff58232, 0x24fc7371,
+ 0xfc7c389a, 0x52592fa8, 0xd01cf0aa, 0xc30aaeea, 0x086459fb, 0xda6027dd,
+ 0x9f845aee, 0x87e826e2, 0x6f31f5a4, 0xe54d3c86, 0x0f88d1fa, 0x8a455dc9,
+ 0xddbe7968, 0xcdc020ff, 0x7ba419ea, 0x329cd01f, 0x03df7bec, 0xf5a7a5ec,
+ 0x72262e4c, 0x27c2327a, 0x65ef6151, 0x9fd474aa, 0xe3c3555e, 0xf6ae1f74,
+ 0xdfc35a62, 0x7781aa81, 0x3d48147f, 0xedc81f98, 0x470a1ac4, 0xdf08fef8,
+ 0x73aa6b37, 0x972cfcb1, 0xaaa68957, 0x25c032fd, 0x66ff3081, 0xc90c9062,
+ 0x14042c21, 0xc482527e, 0x9cf57903, 0xe6c69dd0, 0x7441e9cd, 0xdc77864b,
+ 0x5e008f3c, 0x26cb0eea, 0x4b8b93f0, 0x681f25af, 0xe59c59e8, 0x99bf078b,
+ 0xb00bf0e8, 0x78003dff, 0x4759f3a5, 0x96ef85e7, 0xc9587a72, 0xd39abef1,
+ 0x1f407dc3, 0xd3907d34, 0xfae8afc5, 0x65e35f21, 0xe6d601f7, 0xc4b778b3,
+ 0xc77f130c, 0xf1b44c2c, 0x16def164, 0x2275d0a2, 0xc5307a8f, 0x5bc8ea77,
+ 0xfb17a466, 0xa113e268, 0x43bbadfc, 0x82c91dec, 0xe337d854, 0x272377d5,
+ 0xe367e27a, 0xc4b0d545, 0x991373df, 0xf311d1dd, 0xef1ac67d, 0xefd80b01,
+ 0xeec7cdfd, 0xa4afa5f5, 0xd9ebd9e3, 0xfe01c5bd, 0x688bd982, 0xf54f51de,
+ 0x8ce5026f, 0xde741d2e, 0xc67d1a45, 0xbffd8fde, 0x51cd7ed4, 0x7be7c51b,
+ 0xe45141b0, 0xb87ebaff, 0x614be015, 0xc73f01ed, 0x2a4172c3, 0xf1c3fff0,
+ 0x8735fdb1, 0x83d2326d, 0x1d32fb2b, 0x3ec9d73d, 0x989ee76c, 0x3afba3a9,
+ 0xa612772e, 0x577dd04e, 0x6defcce5, 0xb12eef4c, 0xbcc2cffb, 0xc5d1ce92,
+ 0xbc4a7e51, 0xa9dcb621, 0xdc209591, 0xc319afdf, 0xa6705ce4, 0x3eabf4c2,
+ 0xa7c98472, 0x6f32e4b3, 0x645f4350, 0xf03d4114, 0xee8a998b, 0xc035c1dd,
+ 0x7e5e941f, 0x057ee9cd, 0xc54d01f0, 0x4dd20a11, 0xda1374c2, 0x5f38aba9,
+ 0x68f9cfdd, 0x87a3e72d, 0xc2467f80, 0xdf8cae3b, 0x051de224, 0x8b8d48fb,
+ 0xc0258fbd, 0x8d49b4ff, 0xe85cfe6d, 0xb32de6af, 0x350fe700, 0x11752f92,
+ 0x977e29e4, 0xef8f307b, 0xedeb06ea, 0xbbf1589e, 0x9293ed4b, 0xc95e14ec,
+ 0xdfbf8676, 0xfe2167d4, 0x316f6e2c, 0xd8724bac, 0x19afaed0, 0x658e2969,
+ 0xbdecd81f, 0x53b74ef0, 0x9fc80f78, 0x817f6bd0, 0x666ea17b, 0x37fdc20e,
+ 0x06399f70, 0x33b18cfd, 0x04864079, 0xff0d08c9, 0xdcf7f1d7, 0x46482788,
+ 0xf2c0e469, 0xf808f38b, 0x7ff2fa77, 0x136ff23f, 0x02357f93, 0x780c57df,
+ 0x5531f755, 0xd78049fe, 0xb9e77d01, 0xdd5ca2f2, 0xcb997b3d, 0x3cbd636f,
+ 0x4f9d9dbb, 0x2fc46f11, 0x70a72df4, 0xce6bb3ca, 0x09c49495, 0x5d95efbd,
+ 0x461d6315, 0xf61277b9, 0x9225903f, 0x5905df1f, 0x191e78a8, 0x8fe4f20f,
+ 0x3fa5fe2c, 0xaf1d40fd, 0xee315ce8, 0x72e785f3, 0xae299f71, 0x20fe45cf,
+ 0xd8d78de0, 0x7e1a2749, 0x9dbc02e6, 0xa3e7e7a8, 0xe208720d, 0xbc6ff652,
+ 0x14d9a1e7, 0x88370b9e, 0xd7fefeec, 0x6a277ddf, 0xb6481be2, 0xf53af507,
+ 0xa113b43d, 0x73da5d3b, 0x58dfc2ec, 0xf62fa07d, 0x3614cfb7, 0x6bdfb6c4,
+ 0x53d057e0, 0x1e801f29, 0x4881f54a, 0x5f85f418, 0x08bdf15b, 0x68dc1f35,
+ 0x540ef98f, 0x195a7dbe, 0xddbe67d0, 0xc4a42777, 0xfafe8091, 0x8ea1e6fe,
+ 0xa67c1c7b, 0x28f64e70, 0x70a5b38f, 0x9ff3a99f, 0xe3b273b1, 0x2c421fdc,
+ 0x78db94fd, 0x729fa7b9, 0x21678b17, 0xeae5d8ee, 0x3b714e7c, 0x7b46e170,
+ 0xfd8c7968, 0xefbf217c, 0x479f90b7, 0xd53ff8a8, 0xba3137ab, 0x3f2ffb51,
+ 0xdfe18a37, 0x53c26740, 0x3eae9063, 0x7fa3243d, 0x4aea784d, 0xf2a52f7c,
+ 0x97eb059c, 0x415fde8b, 0x4d79161c, 0xf3bbba44, 0x873c38f0, 0xc3bc32ea,
+ 0xb7f387b8, 0x2b9e169a, 0x8599e9d5, 0xec0a05a1, 0x2ae785cb, 0xde211e91,
+ 0x1397ee11, 0x934bf6f2, 0x13574e24, 0x6991fda0, 0xa2bd69cb, 0x64bf464e,
+ 0xfd12b062, 0xef768d84, 0xdae431fd, 0xe747bb1e, 0x2cea2837, 0x2389fec7,
+ 0xe7351248, 0x7bf90bf5, 0xd8e745e1, 0x1dc4847b, 0xcf402924, 0xe944de5c,
+ 0x6c6eff52, 0xcbe18997, 0xf857deb8, 0x5de95f3a, 0xd67e84ef, 0x5eb663fb,
+ 0x7517cfbe, 0xf5d61ae6, 0xd6b1f1bb, 0x44cf5d15, 0xdfce5f6c, 0x31372df9,
+ 0x9fe5abbc, 0xf4d5f1f3, 0xb82cf578, 0xf84a4361, 0xa185903b, 0xff78153b,
+ 0x3e21b0a8, 0xb3acd041, 0x5d56fea8, 0xfd61495c, 0xaaff7c3c, 0x329e61a8,
+ 0x7a47235f, 0xecfc14f1, 0xa22349a5, 0x81fcfa78, 0x1dcb699e, 0x1c14afb0,
+ 0xfe3b3e03, 0xe79cc564, 0xf0cbf409, 0x8e095276, 0x72b942ad, 0x3dd62ba7,
+ 0x788dcf94, 0x1b78e7ab, 0x35a32411, 0x97c54672, 0x4df1fdb1, 0xf9c17765,
+ 0xecf5f1f4, 0xe5fe8f75, 0x1a7c6c4c, 0x3076e8e1, 0x71e9a9f8, 0x2ffb2fba,
+ 0xeb978e08, 0x85fa9be2, 0x0abfc723, 0xd53bf527, 0x1c0eacab, 0xa37bb097,
+ 0x0417b9f5, 0x8cf8e8bf, 0xbe2a4e3e, 0x7e41eb91, 0x7c093951, 0x07c9ea7a,
+ 0xe5db6ac6, 0x840d27db, 0x85ed4871, 0x6fdd8f9d, 0xfd41a7f7, 0x21ef64e0,
+ 0xd15bca0f, 0x5dd7435b, 0x7768f712, 0xdfab5718, 0x935656bf, 0x4a5fc12b,
+ 0xc12b87ed, 0x05b5436f, 0xe6a8a3d4, 0x847d05e0, 0x7ac5f156, 0x83926a17,
+ 0x5656b3f9, 0x95bfa157, 0x0dc48258, 0xf8c23d7e, 0x42cc9c92, 0xd0e497ff,
+ 0xec8a01eb, 0x4dbf8377, 0x6591f7e1, 0x3d26bfc9, 0xc4d9ec1b, 0xbe06a08c,
+ 0xbc583957, 0xc594dac4, 0xb7438841, 0x38719f80, 0xeace37fa, 0xa517fbec,
+ 0xdd280385, 0xda7dcfa9, 0xe5cbe846, 0xfe8216c4, 0xbbf4d1b4, 0x74891e76,
+ 0x4c7dbade, 0xe2c9170f, 0x890f73c2, 0x8715bf70, 0x7282fd07, 0xc3973578,
+ 0xdc2eedcb, 0x645d567f, 0x8ea0fb42, 0x0b7ec3fb, 0x8b84307e, 0x84327684,
+ 0x257d40dd, 0xb0eb882e, 0xd0447ac2, 0x7798c3db, 0x22328bc2, 0x4025b13e,
+ 0x04789e3e, 0xe1200fc8, 0xf687a055, 0x0bbcea4c, 0xfd58a7be, 0x5fbf01b3,
+ 0x151c76a4, 0xe05a0fc0, 0x5ce004bf, 0x3c33062f, 0x62e3feb4, 0xa5ea0324,
+ 0x12b7a2d1, 0xc4117a58, 0xe735fb41, 0xce1dec2b, 0x9bec5e68, 0x64a968bf,
+ 0xfaf86f38, 0x2ff96d12, 0x0762beac, 0xf656fbec, 0x07e24d7e, 0x9ab9ca02,
+ 0x01773f5e, 0x71a9dbde, 0xd23d7f30, 0x21d5d005, 0x959f4fb6, 0xe809713c,
+ 0xf5951b3f, 0x5e1e6ea2, 0x76e25e5d, 0x53a5134d, 0xf4ab8bf0, 0x99f24231,
+ 0xae2e8e80, 0x78b5dfa5, 0xc15fa18c, 0x39fa2338, 0x47e7504f, 0x157a45c7,
+ 0xfdb0e5cf, 0x7b0f40d6, 0xa0ff3604, 0x0fecced5, 0xaf011412, 0x93c255b3,
+ 0x3c7cb056, 0xddf07f51, 0x3f55b7cf, 0xf2c15937, 0xcc0b966e, 0xc66ae767,
+ 0x5f6eccf9, 0xe5fe01dd, 0x0ba9edd9, 0xb6659ce0, 0x208ff2e5, 0x0e4723dd,
+ 0xfc4e41d8, 0xf9a3bd8c, 0xca2f23d3, 0xbc778a20, 0x43ef11b1, 0x71f9ce3f,
+ 0x80c8890e, 0x2b713f7f, 0xc21e4fcc, 0x5e27cdf5, 0xc1916f9e, 0x1c2dbd7e,
+ 0x9a3af9ba, 0xd0c5fdbb, 0xcd5a6075, 0x09791439, 0x716fe6d0, 0x5a2fa1e7,
+ 0x7de6d76d, 0xbb59e599, 0xdff81c28, 0xb82c90c1, 0x2dbae8ae, 0x9d750708,
+ 0xa3e226b4, 0xfdfc4e17, 0xbd2e1520, 0x7adfb6eb, 0xfb0bf82d, 0x2db36f93,
+ 0x71623e63, 0x465e6cb9, 0x45067d38, 0xc3915ef0, 0xf2e807b7, 0x1daf8761,
+ 0x12dca4f8, 0x21869349, 0x5f2184df, 0x4a2ffa29, 0x78f870a2, 0x8192ffa8,
+ 0x018e8f00, 0xbe67a417, 0xd5fce9ca, 0x83f7def4, 0xbe99d113, 0x66c1f986,
+ 0xb55b7a70, 0x9b8c4de3, 0x7b30f8fc, 0xf442a90f, 0xfa0f7f5c, 0x4b1244bf,
+ 0x57d355ef, 0x2de61fb9, 0x9d1f7a87, 0xc48673ad, 0xd5a33de0, 0x667af78e,
+ 0xfd3a8b64, 0xc0b6467b, 0xc63ad7e3, 0x4bd3a4de, 0xeeba7057, 0x11c40fdb,
+ 0xb059fb18, 0x55da3274, 0x24f7153b, 0x0dc1ff90, 0x4c16ce8c, 0x671089f5,
+ 0x808d613c, 0x1ff188fe, 0x87901276, 0x09e2ea0b, 0xb82f839c, 0xbc16717b,
+ 0xe1d95097, 0x3904eb69, 0xe0bc1219, 0xef164b47, 0x9d25f8c8, 0xd807c3d7,
+ 0x3bf90c3e, 0x9f0e9e60, 0x2bf1a1c7, 0x1955c977, 0xdbeba06e, 0x0b903e1d,
+ 0xbdf26ef3, 0x922d780d, 0x76b5fbc2, 0x3cdbbcc8, 0xf31f40b9, 0x4c3eac5a,
+ 0x51b2442d, 0x224f36b9, 0x15934816, 0xdf215922, 0xece7d4fe, 0x3bad86b0,
+ 0xec2c46d9, 0x80afe1fb, 0xacdf2e4e, 0xa63dd6e8, 0x51ff9f45, 0x119f3e9b,
+ 0x0eb3e7d6, 0x80b7f3e9, 0x87d1a31a, 0xe765ec0e, 0xd86765dc, 0x05e7c13d,
+ 0x7fc083d8, 0x37b9466a, 0x073daca5, 0x3ccf4dce, 0xf94134eb, 0xfd986f9e,
+ 0xc562d916, 0xbff6cbf7, 0x44b62363, 0xbad4c778, 0xd8cfca11, 0xffc0725a,
+ 0xfc63eb44, 0x4735dd03, 0xf3b1fd82, 0x0cced532, 0xcec49c61, 0x7b9c596f,
+ 0x04398b64, 0x7667b1e7, 0xd02cf53f, 0x832d99dd, 0x5e79ef51, 0xdfa09a08,
+ 0xaf0c7de0, 0x9d2e6c13, 0xacdb29fc, 0x3846ebb7, 0x73d53e99, 0xf10b994a,
+ 0xebd4974f, 0x48697dd7, 0x64ed1f9f, 0xd13e67f2, 0x73874f7c, 0x14aacf66,
+ 0x48278ba0, 0x5983fbcc, 0x9f7f264e, 0xed515a7e, 0x33bf916c, 0xd1493c46,
+ 0xa27b4f7b, 0x064b3fe7, 0xc0001c43, 0x7bf45862, 0xb55c6199, 0x7cb96fff,
+ 0xfa7ee44f, 0xc222abc8, 0xb17574e7, 0x57b89cee, 0xa6f6ad3f, 0x33ecd54c,
+ 0x93fbf585, 0xb85ea1e6, 0xd6be693f, 0x3072db2e, 0x738856e9, 0xdfe12cd9,
+ 0xfd9f2a4f, 0x121343e4, 0x02d8bbe1, 0x1f7285f3, 0x2f2d1fd8, 0xd51ea0b9,
+ 0x71b5333f, 0xe3f54523, 0xf66aa652, 0x974a1fd7, 0xbb4aefbd, 0xe5767c19,
+ 0x1d78dc16, 0x835977c5, 0x656a85e8, 0xfbff372d, 0x837b8018, 0xcb5cf78c,
+ 0xbef8c9b7, 0x0af1a079, 0x359413f4, 0xef879ebf, 0xe79fade8, 0x48e57985,
+ 0x44cc40a4, 0x904dc0d7, 0x81df6c9e, 0xfd95d5ef, 0x3c914eb5, 0x7d3d5f30,
+ 0x3f437a50, 0x7280d517, 0xf01e006e, 0x54f8c32d, 0xae11bbf5, 0x7b7d2125,
+ 0x17febe23, 0x33fa37a7, 0x63778b4a, 0x83d301bd, 0xca4877f8, 0xa3b95297,
+ 0x3fca2fb1, 0x38f8c5ac, 0x542838e3, 0xb0d0e735, 0x1f90797f, 0x271f7cad,
+ 0xc7872582, 0x79670e8f, 0xe80f377c, 0x197fd60b, 0xfb81ea99, 0x7c90378d,
+ 0xc2179f48, 0xe322890f, 0x6c3bf46b, 0x775f23b5, 0xfc9f3bb9, 0xf343d01d,
+ 0x18c73c18, 0x767befc4, 0xdef8c279, 0x0ff7faa0, 0x5f2cdcba, 0xf8c56eda,
+ 0x2b1f338a, 0x4196cf28, 0x7fd4175c, 0xd1326ad6, 0xb6cce67d, 0x4e219301,
+ 0xbd85abb0, 0x65ba7b2f, 0x7be564c0, 0xff2347f6, 0x31d6fbaa, 0x6fee95f8,
+ 0x1b7d384f, 0x15df009c, 0x79328e2c, 0x55465540, 0xeda93c0c, 0x0caa9512,
+ 0xb7221fb0, 0x991bbc3b, 0x720e93be, 0x053facff, 0xdc79f9ed, 0xae37b17f,
+ 0xd7e819e0, 0xe8faeb49, 0xe24384bf, 0x0fafa046, 0xee5def44, 0xb5f3d1e1,
+ 0xbc7ed985, 0x30564a4f, 0x4481663b, 0x4fd512c2, 0x1fbc8017, 0x8394798b,
+ 0x8c041a0b, 0x56b85a2b, 0xef781ebf, 0x0377fb54, 0x5e2fe18a, 0x9138870d,
+ 0x1b8b4c16, 0xb025e5f4, 0xfe30b87f, 0x4bcfcf03, 0x70e5f49b, 0xbdf41093,
+ 0xccefe6f2, 0x39f6e0b1, 0x7be7d751, 0x1f93a9c9, 0x8f8fca32, 0x5f5c02c4,
+ 0x909b5819, 0x702afdf2, 0x42ca6e77, 0xa59ee20a, 0x66165213, 0x04183be1,
+ 0x1645a7f6, 0xb2657412, 0x8003bc3c, 0xc9fc83ac, 0xf5825bde, 0x9487ef69,
+ 0xa1e1254d, 0x613ae8ae, 0xf272da7d, 0x5963c306, 0xe31e10bb, 0x8237de8a,
+ 0x95eb6a75, 0x3797f5f3, 0x837e759b, 0x84f3880a, 0xefd69538, 0x797ebacc,
+ 0x37dd1cfc, 0xe7e29589, 0x1bb95ee1, 0xfc5634ba, 0xa70e51f9, 0x4c2e6f87,
+ 0x15fcbe05, 0x388381e8, 0x3da97320, 0x0271c20a, 0x8e85b803, 0xcdeacb63,
+ 0x72ce7963, 0xf9d4ff96, 0x10fd5e55, 0x7ec9376a, 0x2058573c, 0xf70cbc16,
+ 0xfdba669a, 0x17fc025f, 0x12697c98, 0x246fa7f2, 0x652e47c6, 0xb3247feb,
+ 0x18aad2ea, 0xc78aa9f6, 0x782d0adf, 0xcddc17be, 0x76673df6, 0x3bfad644,
+ 0xee4c5de3, 0xc4e81dc4, 0x0ec8fe78, 0xae11ef01, 0x3de18e17, 0x78d7f5bb,
+ 0x29cfd808, 0x17206f14, 0x05640bd7, 0xdd9563bc, 0x978ef33a, 0x36d97f00,
+ 0x5a2a77d4, 0x0e158927, 0x77d33f5c, 0x708d55ec, 0x773c98ce, 0x33d02654,
+ 0x1bdcf75d, 0x83cbbbe0, 0x183aa5e3, 0x0f2ca41d, 0x0d1e2fa6, 0xf1dc17e3,
+ 0x18dbf012, 0x4d3fde1b, 0x2672b0a6, 0xf406ba60, 0xb1921497, 0xca77e41f,
+ 0xf8264f74, 0xb1761f5a, 0xc49a0671, 0xcf4133b9, 0x84f964ca, 0x46df057b,
+ 0xb875ae24, 0xc93364fe, 0x77c2f987, 0x602d13d0, 0x887963cf, 0x554a79e1,
+ 0x3c9f8c06, 0x4a89a59c, 0x5e82e318, 0xcedef151, 0xb89673e2, 0x25e3ca09,
+ 0x4e4a4d5f, 0xe95feda0, 0x952d86a2, 0x510caf53, 0x03b0e1f5, 0x623210f4,
+ 0xf5cfab14, 0x2c1925e1, 0x4d313dee, 0xbd5857d5, 0x9717d91e, 0x75f3f205,
+ 0xe67f17a6, 0x9c41c5f0, 0xec4a15da, 0x1c49dbb8, 0x3673814f, 0xfff8d212,
+ 0xc0beb303, 0x73811c7b, 0xecd2122e, 0x9b2ef007, 0xbcb37e36, 0x17be00f8,
+ 0x303a415c, 0x45a2b80e, 0x857a6f1f, 0x2ab8f62d, 0x99ce079d, 0x42ed1048,
+ 0xc0271f0a, 0xce0ab227, 0x057b8271, 0xce06aff4, 0x19a82429, 0x412e703f,
+ 0x679def9f, 0xad13f612, 0xdaf5f447, 0x247ac4be, 0xe305d3b7, 0x713bbb74,
+ 0x939c08bf, 0xafba9db0, 0x414c84f4, 0xdd6fea99, 0xc3de561e, 0xeb55a3df,
+ 0xcf75fdab, 0x977df852, 0x55dbf608, 0x8511054d, 0x9feda3cb, 0xbcb39fa0,
+ 0x45c23f7d, 0x7c2887a5, 0x81a824ec, 0x474d524f, 0xfb7944d8, 0x584d0fe7,
+ 0x4a52fa3d, 0x1f38075a, 0xf6ae2707, 0xa2e5a44d, 0xf6d7c749, 0x473e5eec,
+ 0x49b0f2f1, 0x2bc8fee4, 0xa89d4f57, 0xbdfaf3c9, 0xbe3f83ed, 0x47b3ca1a,
+ 0x1ecbf6b3, 0xcb0feaba, 0xa25ca8a5, 0x702b48eb, 0x4316f26a, 0x63f341de,
+ 0xa1b77934, 0x9e50d13c, 0x610fc862, 0xe19cbbf5, 0xc84bd134, 0x5ca687da,
+ 0x03dfc12d, 0x81cf0d4a, 0xc56bfb9b, 0xefe1abbc, 0xb364562b, 0xd95817bf,
+ 0x3859782e, 0x655f8313, 0xa76cf9ef, 0xc03460b2, 0x9065e3a1, 0x826de503,
+ 0x4770f41b, 0xe630b6cb, 0xd3479da1, 0x7bdd85ae, 0x86396f2a, 0x7fedfaed,
+ 0xf8f90994, 0x63ef51fe, 0x15c5f3bd, 0x78fae991, 0x19e2fef3, 0x26fe088f,
+ 0x3be8b8d7, 0xdedb5dbd, 0x37bdfe8c, 0x53ba472a, 0x8e51077d, 0x067fee1a,
+ 0x288e3e60, 0xbc70a89f, 0x7c59d47f, 0x31ddf0b7, 0xdb6047ed, 0x64f92fb7,
+ 0x7f91e819, 0x0e3138ad, 0xfb782af4, 0xdf8df610, 0x614ba10a, 0xf8947a1f,
+ 0x6f71852f, 0x3f78b8af, 0x547d913c, 0xde0c7cee, 0x87cffdb5, 0x7f0d5ee6,
+ 0xb3a8eeef, 0xa9fc2873, 0x52ae239e, 0x81d1c7c4, 0x4292f89d, 0xcb195c66,
+ 0x6a1ced0f, 0x5db7f9a2, 0xe2fe59eb, 0x2f20c7ce, 0xed632dc4, 0x150e74c7,
+ 0x2c3260dd, 0x726dfc47, 0x3ff7e6c7, 0xcea33972, 0xbee1eeef, 0xa42e0097,
+ 0x7037ed9c, 0xe542d0bd, 0xd3d29ce9, 0x7851375b, 0x1d85f9cc, 0xaea6dce5,
+ 0xfa65af1b, 0xe200b070, 0xbc39928d, 0xb9443f71, 0x90dea12e, 0x42607b0a,
+ 0xb4ce9f14, 0x17ee0f0e, 0x036d5597, 0xce79207d, 0x1a2fdc68, 0xb8acbe9c,
+ 0x4374d171, 0xe2b34b22, 0x8bae4cdc, 0x961fbc26, 0xf5138f7c, 0x77f15fa5,
+ 0x21df29ae, 0x5e38387d, 0xbb3173de, 0xf3173dec, 0x4e741c2b, 0x11de7ec3,
+ 0x222deb7c, 0x056824a4, 0x50d896bc, 0x91b5b90f, 0xd72a15ca, 0xebbcf8eb,
+ 0xfe8a5dd6, 0x5fc15b82, 0xfbbe1a3b, 0x47461352, 0x0cbafcf5, 0xed44779a,
+ 0xbe99bab0, 0xda7bed54, 0x5cac8d75, 0xe9755b95, 0x5fbabdac, 0x71b0d725,
+ 0xe9757f92, 0x5d875846, 0x8bf5e762, 0xb8dc8d66, 0x1bfff70c, 0x1fc0e2b2,
+ 0x82a5f3e2, 0xc961fcdd, 0x9fe81330, 0x861a7e2a, 0xd172befb, 0x73f29ff2,
+ 0xbd4f1516, 0x5b1c65f6, 0xea9102f7, 0x3fbd740f, 0xfd71fb72, 0xcb189f54,
+ 0x3e99b30e, 0x4cd74591, 0x5225f034, 0xfef838e7, 0x694e083f, 0x147feeb0,
+ 0xbc777f4e, 0xf73ef4f4, 0xbe61325e, 0xe84f4b15, 0xb870bdef, 0xcb0856ff,
+ 0xf79ad9c9, 0xb077e848, 0xfa76bf33, 0xce69c7c7, 0x53dce7e7, 0xbaa77a81,
+ 0x77cffb1e, 0x64dfc3e5, 0x51a7f234, 0x8efa3c2f, 0x3ff82d65, 0x282d2a8e,
+ 0x4b5e8f8f, 0x51c5fef0, 0xaa941efe, 0xa2fce6d7, 0xd3b015ec, 0x4889c536,
+ 0xbe09f71f, 0x7dc78054, 0xfee01e94, 0xa28f1ab6, 0xf175c7ee, 0x4085f5a1,
+ 0xc68f370f, 0x881eef73, 0x4b7a848c, 0x2eb8df99, 0xf0ed13be, 0x371ef1ba,
+ 0x07d0099d, 0x5b3231e2, 0x5d4fff41, 0xbab3a306, 0x3ef0cb92, 0x2097a505,
+ 0xe8cd9fb6, 0x41266eae, 0x766ea1bb, 0x959bd20a, 0x9f30ac84, 0xa927e8fe,
+ 0x10a3c586, 0x7b5637c9, 0x638c1d6e, 0x767b117e, 0x41378ee7, 0x456b5d8f,
+ 0x8950163d, 0xc9b51de7, 0x074a5f38, 0xaa5748c5, 0xd49bf67d, 0x0f68fdd0,
+ 0x5feed17a, 0xc3cdf4ed, 0xeed2fff9, 0x5837f981, 0x264b1ac9, 0x05643598,
+ 0x1f3e49ca, 0xc608fb52, 0x7ae5cc2f, 0x67c57be1, 0xfc7fa09d, 0xff504e3c,
+ 0xec0fa52e, 0x9584f9f0, 0x7ed7bfcf, 0xf9a9ec0c, 0x6277b2f7, 0x3e699ac9,
+ 0x9d05f9fd, 0xb9f8126b, 0xc47d4ff9, 0x87e37409, 0xffe82e76, 0xff709cbf,
+ 0xbb2f7fc6, 0xb4824acf, 0xfb68a8fd, 0xc1df81fb, 0xf9b22e5f, 0x27bb6a93,
+ 0xf7a0fbd6, 0x44bf71c7, 0xed3e23ed, 0xc638ea78, 0xf8bda97e, 0xc28bc000,
+ 0x8cf70c3d, 0x7f64bf22, 0xdf38c097, 0xa0f22544, 0xa9cf9695, 0xefe1e316,
+ 0x3a97fb88, 0x7ceabd71, 0xae4726e7, 0xa1847f44, 0xcaf6e3ff, 0xab67f01c,
+ 0x57b90ff6, 0x5c21ef63, 0x845e6894, 0xb411f87b, 0xe77cfaa3, 0xeed1b1f6,
+ 0xb35be424, 0xdc6f5eb6, 0xcc3047be, 0x4795d39f, 0x7e6f0090, 0x28af1e7e,
+ 0x5ef83991, 0x2ade6194, 0xba73773c, 0x08c2e953, 0xc0fdddef, 0x1ce9513b,
+ 0x97fafd0a, 0xc64e119a, 0xf4fdd5fe, 0x1fe52b11, 0x82f5774a, 0x7f5af480,
+ 0xc7f71db7, 0x49e46b1e, 0xefb8d7bc, 0x7777c46a, 0x4103cd89, 0xb5528f5a,
+ 0xf633cf1d, 0x9e8cf3b1, 0x81239d91, 0x9ae9ba9f, 0xdd3f147d, 0x418d8aaf,
+ 0xd5049d41, 0x37155e8f, 0xef77fd02, 0xb3f586be, 0x89dececc, 0xbdc30806,
+ 0xaadfe0c4, 0x81f39fc1, 0x002fbd89, 0x6b458f7f, 0xd1bdc377, 0xbca8cce2,
+ 0x180281e8, 0x573d4dbf, 0x38e097f2, 0x3df0dab7, 0xe0934a81, 0xb2abbd03,
+ 0x67bc32f4, 0xd1dff840, 0xa568e551, 0x99a3da89, 0x34afbe51, 0x31723fbd,
+ 0x491293f3, 0xf5a347e3, 0xb03b045e, 0x03b6b2dc, 0x49bb51ef, 0x6843eff4,
+ 0x6b95a5fc, 0xf3037ccf, 0xf8356caf, 0x83fe0c11, 0xa53d2d52, 0xf504e947,
+ 0x531f907e, 0x775bde09, 0xbf3dbcf2, 0x018efd03, 0xf030ce7e, 0xd6d77b00,
+ 0xc042dd99, 0xc9381aaf, 0xed0996f4, 0x0ec1078d, 0x18efcf8f, 0x700dcb0a,
+ 0x9ef19f3f, 0x75f6f8c9, 0xaa95d822, 0x6bb1a3be, 0x8c61bd2f, 0x4df76536,
+ 0xf1864ec1, 0xf013e13a, 0xc9f6c48d, 0xf74803ff, 0x800023ad, 0x00008000,
+ 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b, 0x733ef0b5, 0x9992bcce,
+ 0x9264cce4, 0x0927de4c, 0x27010084, 0xd4500421, 0xe6a2bc21, 0xa2d101da,
+ 0x3c2438b5, 0xa0992112, 0xf7ad8b95, 0x24844032, 0x111a0804, 0xa284e028,
+ 0x17edaf62, 0x04c0622c, 0x16c45407, 0x6b5ec5fb, 0x46f7f6d5, 0x485ca008,
+ 0x6c5cb046, 0xad7bfcb5, 0x67324fbd, 0xde952892, 0x1e9f7cde, 0xecfbd9f6,
+ 0xaf6b5ac7, 0xa5b3def7, 0x90d74b32, 0x44b44849, 0xc8485488, 0xbb11a6c2,
+ 0xfe840957, 0x5b6673b9, 0x862a7909, 0x83c9e03c, 0x33c8abb2, 0x72599086,
+ 0x9e3c8c71, 0xb1722390, 0xf7878e59, 0xda1e9181, 0x08e3f88e, 0x55c84499,
+ 0xe075bbf8, 0x24203693, 0x625dbfbe, 0x8d7e4d76, 0x0e76e865, 0x83a7fd03,
+ 0xd8b6d090, 0x8f986ec0, 0xd1796024, 0x0d2df46f, 0x613a3f38, 0x7687df3a,
+ 0xfe600666, 0x40c9a415, 0x4a5909b2, 0xd2220602, 0x8fe22676, 0xda4fa029,
+ 0x173e962c, 0x2512356f, 0x55dfe097, 0x40655ffa, 0x6ccd265b, 0xe0a54b5e,
+ 0x90862111, 0xfb13a425, 0xdb57b259, 0x1234e96e, 0x2afad2b4, 0xc3460913,
+ 0x5f5b55b3, 0x0f38424d, 0xa355db5f, 0x44d27fa6, 0x36db8508, 0x3b662133,
+ 0xf99dc9cc, 0xe87f9d38, 0xb76bbd6d, 0x6869c842, 0x870fd492, 0x38e2d88e,
+ 0xa8947380, 0x568675c3, 0xd3760745, 0x48eb7675, 0xb70a3ec5, 0xc0f2364d,
+ 0x59ecfa6c, 0x0d8738a9, 0x9d8c7043, 0x3c20663d, 0x2b990e1b, 0x6e7f1402,
+ 0x55708759, 0xd5895fdf, 0x40cbb963, 0x7d695a2a, 0x5fda6ad1, 0xf57d7f5e,
+ 0x7c2f163d, 0x70165337, 0xbbe780de, 0x0d64cf00, 0x3ded077e, 0x71a8fc74,
+ 0x777ea9ec, 0xcdfb5f67, 0xfe14df0c, 0x952dff30, 0x27802d51, 0x0493b922,
+ 0x04759407, 0x63cf2ee9, 0x0fefd2f0, 0xfd7e7405, 0x5849f40d, 0x31ad7f7b,
+ 0x97b62cf0, 0xe5a0ade7, 0xb9e69f43, 0x489c281a, 0xd03e7bae, 0x5173d2c1,
+ 0xf1c1d00a, 0xff5f3f73, 0xf17f5a5b, 0xa4628353, 0x36800bf5, 0x090f1e28,
+ 0xe7684ade, 0x3c8a37bf, 0x352ddf4b, 0xbb8c3710, 0x8088c0f4, 0x807bf69f,
+ 0xb0feb196, 0x1a59c715, 0x90b6dde3, 0xa5f4b3f6, 0x40a51778, 0xf03eaaf2,
+ 0xdf5073c2, 0x4b3d7661, 0xc51a5dfb, 0xa1e971e8, 0xbe7efc14, 0xf014bbd9,
+ 0xfc0c6c93, 0x7be92fc7, 0xf5d19af2, 0x245c7d2c, 0xff3045c1, 0x0166ad8b,
+ 0x75849dda, 0xad27d2c5, 0xed5d6013, 0xbfb63c74, 0xefd21692, 0xb227d54e,
+ 0x9d387175, 0xe91a30da, 0x8d9e8b79, 0x60283fe7, 0xcf7a93fb, 0x3e5a248c,
+ 0x6bbe72f9, 0xf5eaad15, 0x4a068218, 0x4b4dbe7f, 0x84b1904e, 0x5d94eb94,
+ 0x38722700, 0xe2abe71a, 0x7171b7c3, 0x1efbd429, 0x124eec7c, 0xf4fef433,
+ 0x310919b5, 0x0f6bd3f5, 0xfd03a509, 0x6ac8af6f, 0x7b71d20d, 0x44ba47da,
+ 0xe45275ac, 0x5990fa53, 0x833d6edb, 0x8f43a86b, 0xfb5af4fb, 0xb44af587,
+ 0x5bfc1f1f, 0xf0dd2784, 0xbc017eea, 0xc1c59787, 0x747f14ca, 0x8943bebd,
+ 0x7ac8af08, 0x0bbbd5b3, 0x13f553f8, 0x0af1f3ff, 0xf9086f84, 0xc78a6919,
+ 0x1de7467d, 0xbbefd134, 0x5f7159b7, 0xb4a63c65, 0xf77e0175, 0xb69d70db,
+ 0x0ad16e69, 0x58991de5, 0x314571be, 0x86c71539, 0xaf940925, 0xa4ffa44c,
+ 0x49122efd, 0xdf00a9ad, 0xeda36ce7, 0x869cbccf, 0x24645cf8, 0xcfba2675,
+ 0xebc32349, 0xa7ca1699, 0x8dca7c28, 0xc967c85d, 0xe804087f, 0x85abb685,
+ 0x20e94b76, 0xe1030549, 0x034b7c06, 0x395840b7, 0xb5abce8b, 0xff742445,
+ 0xfaa7ca10, 0xcfd59fd6, 0x693f80c7, 0x337f27be, 0x57e8e16a, 0x63ee2df9,
+ 0x59c4a8ba, 0x51f9fa63, 0x18e7ac47, 0x12c3f3e3, 0x44677e01, 0xf29972ef,
+ 0x8fc4c5b7, 0x0492b1fc, 0x478ea9f1, 0xbbe32df9, 0xe177c626, 0xfc0d7519,
+ 0x8ad241f7, 0x380ab37c, 0xf77c60d2, 0xc777ca31, 0x0977cd0e, 0xb807c9a9,
+ 0xb8b7eefa, 0xf803ce00, 0x2aefe72f, 0x8c0d131e, 0x58f8df0f, 0xfd792440,
+ 0xeadd7870, 0xcfa0e73e, 0x06e242e8, 0xc0fbe7fe, 0x806e5264, 0x516487b2,
+ 0x4eb0ecf8, 0xad027ef9, 0x0dc449f7, 0x93ba337c, 0xfbe85bb8, 0x87e2669d,
+ 0x2826a6fe, 0xc0d38fd8, 0x792f42e8, 0x2fad3e48, 0xea0cee2a, 0x13c49f60,
+ 0xb5bdf819, 0xd3bff593, 0x802bbf4a, 0xaefc04ef, 0xa9137bef, 0xbefb0a8d,
+ 0xe91990f8, 0x6b41f2e8, 0xd0f288c0, 0xfda3619b, 0x48d1fc25, 0x873dbd60,
+ 0x7be7c8ac, 0x2b6e64f4, 0x4910ef6d, 0x73e22b4d, 0xd827f62d, 0x27e9f132,
+ 0x680429c5, 0x053db857, 0xab2132b6, 0x65575f91, 0xf283de76, 0x81519f76,
+ 0xd6d97c7d, 0x74ca1cb5, 0xe5a7e23c, 0xdb05652f, 0xcd4ff6f9, 0xef7d09ff,
+ 0x0c5c58f3, 0xa07cdeba, 0xa3f8a317, 0x6f144c7b, 0x42c7c433, 0x5679d28f,
+ 0xe06459a5, 0xfe32d3c7, 0xb4bdfef4, 0x3d7ed9fc, 0x9fde0231, 0x64973a9d,
+ 0x2a27cd0d, 0x5d93fa03, 0x64baf461, 0xd55cb6af, 0xdafb2daa, 0x9b54e5b4,
+ 0x1a2671d5, 0x2aeba6f7, 0xb1a327a5, 0x3a16d3e6, 0x46abe35f, 0x967f9be4,
+ 0xe03699bd, 0x31d0ba0b, 0xe331a380, 0xe02f58fc, 0x0173fdb9, 0x1b4a469e,
+ 0xbe0c799d, 0x9b2eafb0, 0x79c867e7, 0xfe97cf43, 0x47087499, 0x93c189b7,
+ 0x9b1f07f1, 0xee57dd12, 0xf5d08ecf, 0x251d9a2f, 0xee37c6af, 0xa045f1d2,
+ 0x891ce0af, 0x9f6deb6f, 0x5db16309, 0x5989f225, 0x579d1db4, 0xb7c656c5,
+ 0x18ce9297, 0x54d50fd8, 0x145131af, 0x78636c3e, 0x2a1b5258, 0x367fd20a,
+ 0xc2464bdb, 0x25afa53c, 0x1d7fe00f, 0x87a61bf4, 0xb1d366dd, 0x72cd7bf6,
+ 0x368e06b7, 0x96d7d94d, 0xed877724, 0xff7c2597, 0x60904513, 0x7af94b3d,
+ 0x6f782f7e, 0x9955f803, 0xe8530cba, 0xfd7eb7f8, 0xc5efca05, 0x75c6ca2b,
+ 0xdbd70b8f, 0x1757c88c, 0xf7c5ea3f, 0x399b6faf, 0xcdb7d71f, 0xcfdc00ac,
+ 0x9e9014ec, 0x025aa717, 0x5bcffa26, 0x5b9f4c6d, 0x8413bf4c, 0x848c7081,
+ 0x331dd9db, 0x6747409d, 0xdfcf1b09, 0x59e4e4ca, 0x9b2bc299, 0xcefe81b5,
+ 0xebbe31b6, 0x33f33adb, 0x778b4fe0, 0x67902e8a, 0x1aeac3a4, 0x7d3ca04e,
+ 0xf40b42e4, 0x0a6e2977, 0x6bbcdf6d, 0x7be22cba, 0xfd8013d1, 0x6f3bb923,
+ 0x5da5efa5, 0x78df5013, 0xcd91a763, 0x0e7a66d3, 0xd7eb71d6, 0x92c7ea22,
+ 0x2f41788e, 0x47b8366b, 0x76557ec2, 0xf0033b3c, 0xb2567672, 0x42ffdb0e,
+ 0xc3c03220, 0xde0122b6, 0x0f24162f, 0xad8acfec, 0x72e1a595, 0x11136cd9,
+ 0x1e32535f, 0xe0b2e84b, 0xe407ba7e, 0xba4ed554, 0xd9fc607f, 0xaf7fbd1f,
+ 0x3d3f7c23, 0x6174445c, 0xbfc77672, 0x5fc13d20, 0x34f808b0, 0xeef5c583,
+ 0xbab4632b, 0x80726a2f, 0x5d5e2e5f, 0xa20f2393, 0x8bedf7bf, 0x8e1f741d,
+ 0x4d836426, 0xb0755720, 0xfd1aed31, 0xdfbd2876, 0x0373ab92, 0xe22e4ddc,
+ 0x133e967e, 0xa0bf548d, 0xa025f07c, 0x1a78788f, 0x97d23e10, 0x877ded0f,
+ 0xcd926bae, 0xc7a053fb, 0x07cee20c, 0xb9212bbc, 0x005baa98, 0xc80fd462,
+ 0xb7d3230e, 0x6defa624, 0x81cf2789, 0xfb8ea0be, 0x1e2fe84b, 0x1b1ec2f9,
+ 0xc3e7b7ed, 0x5c018eaf, 0x8fcfd3ab, 0xbbecf905, 0xa14185f2, 0x0bb4b5eb,
+ 0x2e2dafc8, 0xf17a010f, 0x0b22cfb5, 0xacf9faf2, 0x40e4c5cf, 0x6afebae4,
+ 0xcfb67a63, 0x4e7ec211, 0x6dfed9db, 0xdcfa31b6, 0x002a22be, 0x23bb75fc,
+ 0xff498660, 0x7c94fbbd, 0xc538a545, 0xe189a573, 0x57e7b4d9, 0x3be8116e,
+ 0xa1c3c820, 0xd1fdb0ac, 0x202f315b, 0xdb3e71d2, 0xf2c7ed93, 0x912e29fe,
+ 0xfcf659d6, 0xe00b2eac, 0x4177a6d4, 0x2bab8b7b, 0xd9f7d606, 0xb031539e,
+ 0x223d8abe, 0xf022bbae, 0xbcc2c279, 0xbaf0be7e, 0xc00dfde0, 0x4b04388b,
+ 0x6cf87f38, 0x0584a5cf, 0x98395416, 0x1c1c2c7c, 0x29e4472e, 0x5bb7809d,
+ 0x3978616f, 0x00630bf7, 0x3339def8, 0xfc615f95, 0xc9959cf6, 0x263693b3,
+ 0x4d69091f, 0x57d37907, 0x07573fbe, 0x6648ffe3, 0x5a1877eb, 0xfe3f61d3,
+ 0xe7eda0b7, 0x091d3ac1, 0x595ede50, 0xf9434147, 0x5e17b9d1, 0xff7e0749,
+ 0xa4afb3d9, 0x2fcd8597, 0x79f53bf2, 0x9aedc6de, 0x26dda7a6, 0x51195e3a,
+ 0xc2a60bc7, 0xe32e6578, 0x485fc027, 0xdf7774dd, 0xcf62c9be, 0xab64f6f0,
+ 0xaf60f91b, 0x1d00a8cb, 0x56f5dfaa, 0x804db944, 0xfe426217, 0x062ed657,
+ 0xdb9fd08d, 0xfa01cc3d, 0x447dfab6, 0x4638aeff, 0x809b424f, 0x5e746976,
+ 0x77f1f908, 0x2d4ef7e6, 0x7f9e293e, 0x32ae7801, 0x10a58e85, 0xc0030fa4,
+ 0x916d50cd, 0xac253e40, 0x7a15f461, 0xbffa8744, 0x0169d921, 0x4e6b767e,
+ 0x6e8ead54, 0xcc544744, 0xa7f54258, 0x6c5ce4b4, 0x74662fef, 0x81204fef,
+ 0x590c0235, 0x96bf2023, 0x3a9c5e99, 0xb40dc891, 0xd33b3df8, 0xb5c49c57,
+ 0xbc46cc55, 0x507fe00b, 0x05caa1e1, 0x8fe01fa0, 0xd21304e7, 0xa02ed08f,
+ 0x5aea289e, 0x43bf41e7, 0x5d9e53d1, 0x3d1953b5, 0x49ff95f5, 0xe76454f4,
+ 0x9e803bf4, 0x93d20abc, 0x3d3834d3, 0xbbf90229, 0x07bf13da, 0x0e44acec,
+ 0xef9c4daf, 0x31311e84, 0x19050abf, 0xf794b7ac, 0x04b26a57, 0x2e1f9045,
+ 0x30aef9fd, 0xd507627b, 0x494ec16f, 0x3e9e7d02, 0x57ccd653, 0xb3a46f10,
+ 0xe8daec0b, 0x8f942609, 0x999d75eb, 0x8e24afa0, 0x7407d9aa, 0xaf2f3891,
+ 0x67da0d60, 0x079036a9, 0xbfd15b20, 0xd3d8a2b0, 0x2fa6171d, 0x2fa80874,
+ 0xc6ea3f54, 0x99db53f7, 0x661be07e, 0xd7d77d40, 0xcf01f826, 0x00431ed5,
+ 0x817aa0f4, 0x1bfc01f9, 0xefd80acc, 0x156536cd, 0xbff34fd0, 0x5d3f2e29,
+ 0xf9806f47, 0xd7497a13, 0xbd009fae, 0x3ed05855, 0xb605b66f, 0x7776822d,
+ 0x03bb61e7, 0xf8d9137f, 0xdf8e09c3, 0x7a8adf9c, 0x0a6df37a, 0xfc7003f3,
+ 0x2772cf35, 0xa81f40d9, 0xe6e7eed3, 0x9d927716, 0x52b5efbe, 0xcaf1d0c0,
+ 0x8788cd1a, 0x99c19164, 0xfc989ac4, 0x4c17c819, 0x8984f700, 0x4f4d311c,
+ 0xb7d3bea3, 0x80a729cf, 0x6faf3272, 0xd0e3a4ce, 0x3cf35879, 0x9f79a099,
+ 0x3c7e5a6a, 0x024fd28a, 0xc46e87f8, 0xebd07e26, 0x564c61a3, 0x4f70c376,
+ 0x9244e8e9, 0x86cef6a1, 0xcac39369, 0xf7ff7dbc, 0x69f6efff, 0xfb7728a9,
+ 0x54da61ea, 0xb765ab1e, 0x9d6bce99, 0xa25ebfb5, 0x4da9aefa, 0xd7fbdf60,
+ 0x8a9d3edf, 0x1d415ee8, 0x377aceff, 0x44cca9f8, 0xfcf85e33, 0xf5fe88a4,
+ 0xa28b7fb4, 0x02565fb6, 0xa0553dfd, 0x73aedf96, 0xd26df9d3, 0x9043fb6b,
+ 0xa0a1eff2, 0x4f8be78e, 0xdc9c686a, 0x3d5017af, 0xdf1f6021, 0xfbac1faf,
+ 0x06e9b4a8, 0x7cb4563a, 0x577200c9, 0x873ef395, 0xe447fa80, 0xef897d7e,
+ 0x57ccefd7, 0xba3d5187, 0xbf47a348, 0xdabe4764, 0x24b60335, 0x6f903fb5,
+ 0x10f31efb, 0x3ea8e7d0, 0xfa8ec072, 0x4733f9c8, 0xeccf7d68, 0x514b1cbf,
+ 0x79b2dda0, 0xaefaf7a0, 0xbeb74848, 0xa04062bd, 0xfbe26b74, 0xc0f1ca85,
+ 0x9e9fa170, 0x9d39941e, 0x0744fcda, 0x8c21df74, 0xd57d23f7, 0x714ddfa4,
+ 0x3ee71299, 0xb7ef8f62, 0xfdd7231b, 0x0fd99d91, 0x6de2dcbe, 0x1effd039,
+ 0xd09e8081, 0x61327b90, 0x9f4dda01, 0xfb0c2c24, 0x29edb2ae, 0x5ee56784,
+ 0xfc70a0fd, 0x1c222ec8, 0xecbe0fab, 0x2e71be06, 0xa84f2020, 0x37f50290,
+ 0x854572d2, 0x5241340e, 0x2f7f9818, 0x35cc8fac, 0x7d74e190, 0x409bd041,
+ 0x977bda8f, 0x375846ff, 0xafa04ffd, 0xa1167bb6, 0xd73edd3c, 0x30992164,
+ 0x0865b2cf, 0x0dca3907, 0x2dc86870, 0xaa71824e, 0x4590cd67, 0x1c7aa7a8,
+ 0x7a3f57d4, 0xd30c405f, 0xf4da1b03, 0x14e7a025, 0x57ee7d51, 0xf669de74,
+ 0x745c4bdb, 0xfb88a71f, 0xe5a61ff2, 0xf1f0432d, 0x6e4c1c47, 0xff1e0ad4,
+ 0x5fd10af7, 0x6ffdc247, 0x6f4c6d19, 0x683768bc, 0xed17affc, 0xd9377e12,
+ 0xc81539df, 0x15d4b0e7, 0x8fb4fa0d, 0xfb073fb8, 0xca2c7899, 0xc62788b3,
+ 0x152b1c8f, 0x1c992bf4, 0x806feb5d, 0xda12c9fa, 0x7aea442f, 0xa9edc612,
+ 0x081ab877, 0x7e5007df, 0x9eed0f34, 0xabde71f9, 0x5c454740, 0x3839ed4f,
+ 0xaf2cbf33, 0x7faaef5f, 0x0d581ad6, 0x3caad4fc, 0xf4fc0251, 0x24f9094b,
+ 0xa73a8531, 0xff2a7ed2, 0x1b7ec76a, 0x7151bda2, 0xe6f5fe74, 0x81d03d40,
+ 0x76c445bf, 0x20a6d98e, 0x73d9f3f4, 0x2fd016d6, 0x02268ef5, 0x15cd4c74,
+ 0x1c9887f4, 0xf2d0a21e, 0x497cff54, 0xa1117900, 0xbf054ccf, 0x0e2bda11,
+ 0xf3162bf4, 0x529c31fd, 0x6e1319c1, 0x71abda85, 0xf1cdfafd, 0xf048e6af,
+ 0x747bd552, 0x9de7e626, 0xc08a3736, 0xe86d64f8, 0xcafc0e98, 0x7a024e8e,
+ 0x80ab5570, 0xbee554e3, 0x65bb0064, 0xdfdb2b49, 0x50676e3e, 0x5e83a5f8,
+ 0xcd171d91, 0x465acbf5, 0x58f3a4ef, 0x45f9c00a, 0x68424f86, 0xbdb86b3b,
+ 0xd5d98ab2, 0xf7033fbc, 0xbf715787, 0x58849511, 0xd54e363f, 0x67f35633,
+ 0x71f27b13, 0x6e9d08b7, 0x2f99e011, 0xeab6fc68, 0xe31c7a73, 0x4347b13b,
+ 0x86ff6033, 0xff817d28, 0x6b309b68, 0x7d749bd9, 0x728fc6db, 0xa4e60a81,
+ 0xc01624e4, 0x148a4a7b, 0x9f6d85ee, 0x21ba00cf, 0x6bf70425, 0xb114db75,
+ 0x400dc78a, 0xae8c485f, 0xc4fa8169, 0x3e517207, 0xfc1f1f83, 0xb87077ff,
+ 0xff985926, 0x9fdab9ce, 0x8c1e50f9, 0x26f659ef, 0x0a263f8c, 0x148915e3,
+ 0x3e3b5637, 0xe57fc0eb, 0x4047f924, 0x954b3afe, 0x1a8f9802, 0x89d78a37,
+ 0x43cacc0f, 0xbb658e3e, 0xa6ef704b, 0x6ce3bbcf, 0xdf6a2eb8, 0xe17cc095,
+ 0x0ddb807d, 0x4e274760, 0x7187c9ad, 0xcf044e21, 0x84a0a49e, 0xcf2a68fe,
+ 0x6d3a059f, 0xaf00ca33, 0x3eb7b6d2, 0x6a5b7900, 0xe822ad22, 0x4b7a113f,
+ 0xf35dcc56, 0x2f7b6e80, 0x38f5d99c, 0x03eeebcc, 0x47e22f2e, 0x7adc8fab,
+ 0xcfcbd30b, 0x80ad1b3d, 0xf39bb91e, 0xb23faa6d, 0x982fc138, 0x47a9191d,
+ 0xb5a7123e, 0xffcafa4b, 0xcd923d70, 0xf7e74fcf, 0xf77f186c, 0xb7afbb71,
+ 0xc80c62e2, 0xf47d55af, 0x517fe546, 0xb6529ebf, 0xd813fa27, 0x45767d67,
+ 0xb5223e84, 0x840538b0, 0xdaef90d9, 0xe2fe3c0c, 0xff07ce76, 0xf9072d87,
+ 0xa2e7f1cf, 0x173740fd, 0x97a8cd5b, 0x10433649, 0xb2fb55e6, 0x8013a031,
+ 0x7578720f, 0x818ab8f0, 0x39ec6bc7, 0x0714280a, 0xfbe41e0c, 0x2cf497fe,
+ 0x781312ae, 0x5e5a39e1, 0xc789387a, 0xeff6085d, 0xf08d183f, 0xc4a51a5e,
+ 0x7f4bff42, 0x9e20471d, 0x03c74bd2, 0x7b37cf3c, 0x4d780a7f, 0xc9feb236,
+ 0xc585466b, 0x36398279, 0x0096870a, 0xe54effd3, 0xba0682ea, 0x17d016ee,
+ 0x3546dfa0, 0xd9d6c2fe, 0xc58521bb, 0x0119400f, 0xfb9eacbb, 0xcab8d5e9,
+ 0x2b87e661, 0x5393f1e7, 0x033d17b3, 0xa15ab4a1, 0xb4ec04a6, 0xd0530dcb,
+ 0x89fcbd6f, 0xaf2cf859, 0x17dbfad3, 0xaf7c1a91, 0x3f5527c6, 0x19711977,
+ 0xefdcfe98, 0x7d51d43f, 0x8a93a946, 0x12667e41, 0x03c83579, 0x37b14fc5,
+ 0xe96b3e81, 0x81789413, 0x93b69942, 0x80511dea, 0x3ab575ef, 0x5afe5b94,
+ 0xa9da1b9d, 0x1c56f2f4, 0x57fd23f3, 0x5097f31c, 0x1c600750, 0xe7ab59f5,
+ 0xdfde7efe, 0xc20ba22a, 0xe7b02753, 0x192a593a, 0xfdab7e4c, 0x4c6bead5,
+ 0x4e6f4053, 0xfb3fa1d3, 0x173dc1b2, 0x1cf6c5fd, 0xb5ad53c4, 0xd584aea6,
+ 0x6cba5ee3, 0xfeb0790e, 0x96298966, 0x3f03b144, 0xfa6388ed, 0x16dc2445,
+ 0x91cb6936, 0x80ca9071, 0xbc4e5cb6, 0x59b29223, 0x7dfc20dc, 0x9767e707,
+ 0xbc39321b, 0xbbe0065d, 0xa557faea, 0xd2e9b832, 0xad2b33d8, 0x41d02e78,
+ 0x3285f816, 0xaafcc9e1, 0xff382574, 0x021d9bac, 0x7cc447d2, 0x9e8c6d6b,
+ 0x0fccf5fc, 0x3fcef7f9, 0xe367de72, 0x763ef812, 0x56be213b, 0x5e301b2e,
+ 0x12fead7a, 0xdf6b4393, 0xf1ff95f6, 0xe7b32df6, 0x2fc645eb, 0xa97c8c88,
+ 0x396b664c, 0x0b9eb825, 0xd50b7bc2, 0xf51d601b, 0x91f00162, 0x705977a9,
+ 0x2987d51d, 0x55f5a11f, 0x83a5758f, 0xee2eaf5c, 0x80bc81ca, 0x6cc2f848,
+ 0xd19f9525, 0x6a0e6576, 0x50de808f, 0x0d878da7, 0xd3ba038c, 0xeec1e31c,
+ 0x2defb539, 0xccfb5f90, 0xbfe8bf28, 0xff61188e, 0xbe44cc1f, 0x3bc589f6,
+ 0xbe3ee21c, 0xe7aee0a8, 0x618f4133, 0xbb55547a, 0xc4f405b1, 0xf8b0dab2,
+ 0x51affc1a, 0x75236f1b, 0x93bbf476, 0x8afbed66, 0x0ddf111d, 0x2135bf88,
+ 0xbc18b65e, 0x53bf6123, 0xf1f18439, 0x023a950b, 0x5d172df8, 0x5d48408b,
+ 0xf3f56b30, 0xaf86560b, 0xfe550e69, 0xcf0072b8, 0x7801e57d, 0x9e00e576,
+ 0x1bc475cb, 0xe0154fde, 0x2977e299, 0x9785f3c7, 0x9e00e427, 0x909befcf,
+ 0xa2de7803, 0xbec3726f, 0x4b7b2599, 0xd3dd8e00, 0x415fa83d, 0xd1f613bc,
+ 0x7de3d2b5, 0xf464f37d, 0xf390df78, 0x5bf8c7fc, 0x8b8f9286, 0x95a1e6fa,
+ 0x92830e8f, 0xcca0fc0a, 0x3946fc64, 0xfa837f09, 0xf4464cf3, 0xeafe1c7f,
+ 0x1bcc46d2, 0x3f511768, 0x2c3bfb51, 0x3f41b379, 0xd381fc3a, 0xee8617e5,
+ 0x8afc0adf, 0xe0fcffc5, 0x02ed5167, 0xe48cbf55, 0xfbe63fc7, 0xfdc3b37a,
+ 0xd83bfd99, 0xb8ffaaa7, 0x0531b782, 0x77bd312e, 0xfe62e08f, 0x27f456e3,
+ 0x97cc7757, 0x69fc5fc1, 0xab8ff980, 0xff47ce5f, 0xf5e06571, 0xdfc80a60,
+ 0x7b064176, 0x27cf72a4, 0xfd2c8b31, 0x73b52f76, 0x886e809b, 0xfa471b49,
+ 0xa62a7034, 0x3ef382dc, 0x768ef30d, 0xf7400c84, 0x23fed4d5, 0x52d54974,
+ 0x5bf418e8, 0x17a820ed, 0xed69b614, 0xb8054a41, 0x031eedee, 0xededddf2,
+ 0x75f80042, 0x999bc182, 0xa48d720a, 0xe40718ca, 0xc3976cfb, 0xe8f301dd,
+ 0x03bb6b8f, 0xa33cb08e, 0x48b16dae, 0xe27a5dbf, 0x6d9f8196, 0x267e72b3,
+ 0xf3fb7f21, 0x21a05b0e, 0x73f86f4c, 0x9509e980, 0x4491be6a, 0xd7c51282,
+ 0x0fee39a2, 0xefc0df01, 0x3efc1183, 0xa3c6acbc, 0x3cfc4097, 0xde1dee22,
+ 0x1f8e2fae, 0xf4d6f716, 0x95f26a43, 0x5bdc6d42, 0x7667ef5b, 0x2b0fdd33,
+ 0x57e9fa0a, 0xbf4a83c5, 0xed1fdcd5, 0x16b938ab, 0x26d7d7e8, 0x2f5f60c8,
+ 0x5dfa3175, 0xe32fed4a, 0x9dfb81d8, 0x0dfa52b4, 0xed4377e3, 0xe4228fff,
+ 0x7bff47d1, 0x3b5068f2, 0xf8df74fd, 0xebabdf6c, 0x7df7fd57, 0xd8176ceb,
+ 0x57588cbe, 0xe91adda4, 0xceed5777, 0x5f87e56b, 0xafc3f045, 0xa1f88ffe,
+ 0x7e287e29, 0xfc6b8da8, 0x7ff0fcdd, 0x4cf1be39, 0x3a31d3c7, 0x332a2aca,
+ 0xd7a64efd, 0xe2f135b9, 0xcdc5a219, 0xcb22a6e2, 0xbb8c8897, 0xdc78332b,
+ 0xd7e7ed9d, 0x5f11165f, 0x5c3e3c55, 0x417561d5, 0x62cb0ad3, 0xc646cf8c,
+ 0xfb241f4f, 0x228a0066, 0x614ba8e3, 0x7b7f671f, 0x9e3f353c, 0x5ce947c5,
+ 0xa14f2132, 0xdfcb58a8, 0x8a5cb75f, 0xbbe186f3, 0x021a8f38, 0x49b5d083,
+ 0xd87b13f2, 0x99e35bfb, 0xcf3afd3e, 0x481a71e7, 0x6ca1e41d, 0xc1bb46b2,
+ 0x58ea718e, 0x9c4a51be, 0x78fc4a67, 0x9e1cefe0, 0x744fbf07, 0xe8cf2e14,
+ 0xf89f915b, 0xe02e2cab, 0x471faa7f, 0xf7077fed, 0x9d2b5e83, 0xddaf1bdf,
+ 0x7fe57df7, 0x572fbed2, 0xe37bfbc7, 0x6c295b76, 0x2081fb34, 0x38809efd,
+ 0xba40e653, 0xa19faa1d, 0xbc7977e8, 0xee3c5967, 0xcc58f73b, 0xfe46bd9f,
+ 0x3a185d12, 0xb222fe05, 0x7f80a8df, 0x2825fc13, 0xb8931b17, 0x022aeebd,
+ 0x2ebe4338, 0x0c7d6be4, 0xb4349cff, 0xb7d8d8fe, 0xd8fe99ff, 0xe907fe57,
+ 0x9ec8378f, 0xeeceb08d, 0x901cee29, 0x74aceb6f, 0xbe1760fe, 0x768cf2c0,
+ 0xee7d1998, 0x925d1810, 0xe4d77115, 0xaf13d977, 0x867b9fe5, 0x2efff79c,
+ 0xa7fd6cff, 0xc4bfcff1, 0xe8751f80, 0x2f2cfc7e, 0xcdd3b8b7, 0x776469e3,
+ 0x07db7f98, 0xfbf466f9, 0xeabe7c23, 0x2e5c9dfb, 0x47dc125a, 0xff9c1f81,
+ 0xb12264d0, 0x6429e554, 0x63dab17c, 0x7542f8c1, 0xa97bcb2b, 0xff208c7e,
+ 0x69ff06ae, 0x6715f81e, 0x26f7d011, 0x0027bcd9, 0xb23eebcf, 0xf058c5f8,
+ 0xa026cfbb, 0xc87cf5df, 0xbd967fca, 0x7bef509d, 0x19e30bac, 0x61cfb3cd,
+ 0xd5d155de, 0x0a4b6b4b, 0x47e8be71, 0x4d491870, 0x1afe9e38, 0xd596f2cf,
+ 0x783e95e7, 0x7fafd1bb, 0x11e582be, 0x196e1cfb, 0x5faa11fc, 0x44e95a3c,
+ 0x7ef5533f, 0x8915b4a6, 0x27e43d6c, 0xd54f48a9, 0x83e4a7fb, 0x9ab494ff,
+ 0x2dcf41f3, 0xed05a3fa, 0x268ff3bd, 0xfcc49e63, 0x9859ef38, 0x7030b5af,
+ 0x19a5e81b, 0x77d01c74, 0x2dbbefcf, 0xf2ade61f, 0x3fe02dbf, 0x58b7eda7,
+ 0x62717eb5, 0x95ddf962, 0xfea8a7cf, 0xb7f410f3, 0x6243ef85, 0x359a2a69,
+ 0xf757bec8, 0xc3a8a27b, 0x607f13fe, 0xcab938c2, 0x89e8b60f, 0xcfdd94d7,
+ 0xcf10fe47, 0x3c1cfbde, 0x167db15f, 0x65e14fcb, 0xf0aa7f0b, 0xfe98ecdc,
+ 0x1fc79807, 0xcbeba5e2, 0x4b05930b, 0x75eb3c78, 0x7887fbc1, 0x8032cf16,
+ 0x8a314e7d, 0x2be8967e, 0x92ce7f4c, 0x5647480d, 0x3e30dfba, 0xf408e943,
+ 0xcea1c9f8, 0x9d74b1a9, 0x93839ac3, 0xaf87be01, 0xd24f10e8, 0x9f1813ac,
+ 0x78d81589, 0xf55d8dd9, 0x22ffc023, 0xa03377bf, 0x8b926952, 0xc937d421,
+ 0x404e49e6, 0x2e4d7a7f, 0x7bfc578c, 0xec93cb3d, 0x42bf4688, 0xcc52fa73,
+ 0xc8f9ec93, 0x489cfe88, 0xfd3ea0f9, 0x45e63564, 0x27fdb566, 0xfbac09c6,
+ 0xd4dc0d05, 0x0b04f8e7, 0x3bf95f8b, 0xcd6e6067, 0x57f20764, 0x188fe3a9,
+ 0x25ea969f, 0x56a43ce0, 0x8199d6ef, 0xe822ad7f, 0x2cde1ce7, 0x195f00eb,
+ 0xf7a62f3c, 0x7ac75ff0, 0xe3514ed1, 0xd7960102, 0x0b5aefa4, 0xaab497f6,
+ 0xe03f16eb, 0x574dbf63, 0x85fd079d, 0xd2cfd1aa, 0xcf804d11, 0xaf65b467,
+ 0x339689be, 0x838c64ea, 0x925a1ef5, 0xba557e81, 0xac83e1ce, 0xe5813d33,
+ 0x18133921, 0xd11d48bd, 0xd267903a, 0xd182e266, 0x32dd6b33, 0xcb8779f8,
+ 0x25b9d212, 0x70025bc1, 0x807ce68d, 0xb8c288ac, 0x7e6255a2, 0x8f8aeb11,
+ 0x44e7017e, 0x03f3f176, 0x9e8f0f47, 0x7abdfe8d, 0x5fb80049, 0xc9bcb1b6,
+ 0x73da0939, 0x3ef0fd07, 0x59a7f98a, 0xe4c9ff1d, 0xfa0b1d17, 0x3e8cf497,
+ 0x0b477aa4, 0x587711f8, 0x7b6f98bd, 0xc4506d73, 0xfddc9938, 0x66128964,
+ 0xf2656ccf, 0xb32f7aa4, 0x97ed23bf, 0x5523936f, 0xd2395a09, 0xe927fe57,
+ 0xae122b27, 0x5a212ed3, 0x4f522e7b, 0x06dfb489, 0xfd11dbe8, 0xa8afa50d,
+ 0xfdc52779, 0xd9bd30e3, 0x7e43eaaa, 0xb14e5e4d, 0x4c4b8d85, 0xdb27feda,
+ 0xcc8f9665, 0xd61274f3, 0x9024ab28, 0xd046ff57, 0x0be6a72f, 0x5e598bf9,
+ 0xf9475f8f, 0x97c4265f, 0x284f309a, 0x01050485, 0x045d66fd, 0x7c844bbe,
+ 0xe3ddfa21, 0xef385909, 0x2755c49d, 0x04547f22, 0xf219b798, 0x352f304c,
+ 0x8c116db0, 0xc705b773, 0xc99e4331, 0x70154838, 0x3a7e036f, 0x11c582b5,
+ 0x05dca992, 0xc61e4dfa, 0x973cd0e8, 0xf9a89be5, 0x87fe6a24, 0x0e62870a,
+ 0x8b11e4df, 0xd5ef8132, 0x4017de0b, 0x1817a9cf, 0x981bfc7c, 0x46d9a11f,
+ 0x6e5a68f5, 0xf9851cae, 0xf584bd7e, 0x21d0afef, 0x80f9aa5d, 0x7615c3cd,
+ 0x226fe53e, 0xf9cdefea, 0x4064bf2c, 0x5c044a1e, 0x6e943cd5, 0xf603b7ab,
+ 0xe4c8b26d, 0xa2379aa8, 0xfe1849d2, 0xde3a66fc, 0xbfa60ef6, 0x70185717,
+ 0xb795bd1d, 0xb7b1ffa3, 0xce404752, 0x191bb717, 0xb78c45dd, 0x0481ae7d,
+ 0x60295fa1, 0x8e79fcc6, 0x5fd36fff, 0xc1735e29, 0x65747bbf, 0x0a6eb8c9,
+ 0x7a5637e3, 0x166bd9f0, 0xd7c8455a, 0x01e68731, 0xf89cda47, 0x49a43ba3,
+ 0x4a135790, 0xecc92817, 0x54a0fe70, 0x37a072a2, 0x9431f43e, 0x9c7c4c5f,
+ 0x76878795, 0xd1fdb409, 0xd8a51da7, 0x9931681e, 0x98253f90, 0xeb96fd4b,
+ 0x40646f90, 0xc0a7c6be, 0xd748aa87, 0x0bf44eda, 0xc856f971, 0x669921f8,
+ 0x94bf300c, 0x77b1fe82, 0xee513293, 0xf6b3725b, 0xaa7d4277, 0xb469fd11,
+ 0xddfde91e, 0xbd5853e1, 0x524ef0c2, 0x836f2cad, 0x9f81f974, 0x05399bbd,
+ 0xb055d2fd, 0xf4fea81f, 0x057bc5a6, 0xe8417af0, 0xe0fb0e5c, 0x9affe9dd,
+ 0xe17df407, 0x01864fc0, 0xa06999bf, 0xfc20f97a, 0xe32771e5, 0x4b7abd2f,
+ 0x79fb409d, 0x1215e2dc, 0xe883f969, 0x95203379, 0x14dc6e7c, 0x200d1c03,
+ 0xe04417fe, 0x7f1cf177, 0x5f4c39b6, 0x08f34db4, 0xc6b9f790, 0xef11e6cc,
+ 0xbfa8dc95, 0x7708e778, 0x11aff5d3, 0x94433eb8, 0x143bb458, 0x8eec1625,
+ 0xc21e2ba5, 0xef916fbc, 0x9bad49e7, 0x7f97d045, 0x4df8f2b7, 0xe5a1b0d2,
+ 0xf6115df0, 0x1254fa85, 0x8b663ad9, 0x8fa018ca, 0x6fe342b5, 0x3de0934a,
+ 0x31e9b3a3, 0x5f210a2b, 0x4d74667a, 0x22cdc621, 0xf7d2c7df, 0x23656179,
+ 0x14d4b76b, 0x3d28974a, 0x61decd3b, 0xf3cb9700, 0xfb0e593f, 0xbbf27977,
+ 0xc2be431f, 0xd6e27abb, 0xe24d3ec3, 0x1f2a4371, 0x32c7bf01, 0x286e2c6c,
+ 0x031a9d6f, 0xef866ce5, 0xe30048db, 0xd873a5d4, 0x483bc139, 0x6d176d67,
+ 0x57a9d337, 0xece8c2ba, 0xbe5b4536, 0x2e5b5723, 0xff1179e5, 0xbfbed2e2,
+ 0xc0248493, 0x7e26f7ff, 0xfdfc223d, 0x1beecd8f, 0x0aaffe61, 0x3fd28f2c,
+ 0x87a8c889, 0xe83f043a, 0x495fa305, 0x5926e7e6, 0xb9cfdfbe, 0x44caf31d,
+ 0x7b09f582, 0x0f21bb4d, 0x8b07f55f, 0x93b47ebc, 0xc8ec3298, 0x84ae508f,
+ 0xe8379e04, 0x390918c0, 0x7e664cb0, 0x40d6da51, 0x5f3039fb, 0x5824b841,
+ 0xa016e474, 0xd21342eb, 0x298a5175, 0x28e0e80a, 0x3f1f23a7, 0x55d2a387,
+ 0x903c4491, 0x9e8740bf, 0xf577cf03, 0xfff011f2, 0x78233ffa, 0x29908a4e,
+ 0xf231e612, 0x855908b1, 0xbd39a7e5, 0xedf9551e, 0x6fc849bf, 0x701ab4df,
+ 0x16bf895f, 0x439f805b, 0x5fd6991b, 0xf3851c6c, 0xdd03f753, 0x091cc3bd,
+ 0xfde672e8, 0x44983a4a, 0x2acaccae, 0x38f862bd, 0x410fe401, 0x738d523d,
+ 0xbefa99a5, 0x4977c373, 0x74bb9fbc, 0x8a4cde2c, 0xdc9d1c78, 0x3f7cc465,
+ 0xbfb42f5e, 0xf7e025f5, 0xdc4cc4f1, 0xb7887b74, 0x3446e80b, 0x4ba014b8,
+ 0xdae5ce95, 0x9d29bf43, 0x79c9eb04, 0xbb73d704, 0xe4f58655, 0x6b9c3252,
+ 0xae3ba7c7, 0xf461fa00, 0xefb1462e, 0xfb792aef, 0x3e8c2926, 0xec55f7e8,
+ 0xf7ed68fb, 0x3dbdfa4e, 0xfa18fbec, 0xefc0de7d, 0x72220909, 0xbff3e76e,
+ 0xee89e79d, 0xba829ab1, 0x917fd0b1, 0x13bf45d2, 0xc3f7d813, 0xe07be862,
+ 0x7cdab9fb, 0x65d1320c, 0x88de3cc2, 0xc2998bfc, 0xd7404963, 0xdaaa99b7,
+ 0x6fff68bb, 0xd4ccfc71, 0xf380bf79, 0xcbcd6f66, 0x57fc0379, 0xbfba2625,
+ 0x055f60b2, 0x7ad202d7, 0xb19f78a7, 0xddfee365, 0x2d5ff401, 0x69d8477a,
+ 0x69be82f9, 0xdc4cb2d8, 0xe3133b17, 0xc55fce07, 0xa00ebabf, 0x3ea7a003,
+ 0xb798883a, 0x67722f8a, 0xedac262b, 0x3c087aa4, 0x9084bd55, 0xac9f961a,
+ 0x8baff5a4, 0x530ccb12, 0x0bd030cd, 0xe3f4aade, 0x7b699dbe, 0x9e97f312,
+ 0x04bef24f, 0xc37b9df3, 0x3412e9e7, 0x011fce76, 0xdf3a207e, 0xce5ffd5f,
+ 0x06bfd557, 0x667ee7e4, 0x0ee7e4d0, 0x71d47fb5, 0x8957a07d, 0x82dbc790,
+ 0x39beb6f9, 0xab9c1716, 0x68be41f0, 0x5079c621, 0x30243aaf, 0x982fd57d,
+ 0xad741eb8, 0xe984bc79, 0xfa7d554b, 0xbd0f2692, 0xbbcd9f39, 0xfa829979,
+ 0x6b02abd6, 0x984f9fef, 0xd78b363e, 0x5eb1942f, 0x6e6f57cd, 0xe6b5fe61,
+ 0xd0284797, 0x50a3d52f, 0xae58931e, 0xfe3265a7, 0x91493cda, 0x44dc0cfd,
+ 0xafcfe848, 0xfa67a2de, 0xab9d76df, 0x0c41f308, 0xf1623f54, 0x869fc65b,
+ 0xfd23f1b3, 0xaa275f70, 0xc3f30076, 0x41ff95f5, 0xb259b87e, 0x7f693897,
+ 0xe9dcf30b, 0x17982cfa, 0xfa51c7f3, 0x2049d1dc, 0x1866ac4d, 0x91b7cde8,
+ 0xd974f79a, 0x68069f48, 0xa534773f, 0x7d0d6ccf, 0x8cf19d1a, 0x22bcc21f,
+ 0x1d2441f9, 0x6578c566, 0xd6d9a7e8, 0xd06ac7fa, 0x2e8ddb37, 0xf2ca7f96,
+ 0x40f922e9, 0x48167cd8, 0x510e3e6c, 0x0738f9c4, 0xecb5cf9b, 0x4cfa7093,
+ 0x0c3f6c24, 0x25125fb5, 0xf416b7e2, 0x9b1f97ef, 0xbd6023bd, 0x2d66fb7d,
+ 0xcc062fb3, 0x7d20b45b, 0x8b2f73dd, 0x99a2f837, 0x43b8835c, 0x167f1d12,
+ 0x7a9eff1f, 0xfcf78746, 0x4b7480d0, 0xf9841fa7, 0xb3f5e6cf, 0xdf30abda,
+ 0xfd34f668, 0xff0d2ec9, 0xe7bc2375, 0x1c7376f2, 0x02d87af9, 0x71b54a73,
+ 0xb3f7b985, 0xa4ddc6b8, 0xbdf30f46, 0x9fb68e67, 0x73f1a4b9, 0x7b9a9fc8,
+ 0x54fdf6bf, 0xc9b9df67, 0x788f1011, 0xbde1db83, 0x7ec0bf74, 0xf17e337a,
+ 0x7e94658e, 0xaf34fc47, 0xd303fc00, 0x6cf72a13, 0xb7e7e5a6, 0x9bf2c28f,
+ 0xd1f83f09, 0x2bbf50bb, 0x20d3cb07, 0x08ec0c19, 0x6f208fd8, 0x3dbdee8a,
+ 0x86fb8e93, 0x8cbbf799, 0xa33bdbe5, 0x68b3cdbc, 0x2cd8e73b, 0xc69c1bcc,
+ 0x42ef4df9, 0x0dc77f56, 0xfa1a9656, 0xb97e8280, 0x79a15169, 0xf227ff40,
+ 0x790050ff, 0x78b2d3ac, 0x51d5e0b9, 0xf8437e50, 0x4dd81e7c, 0x0916553d,
+ 0xcc9d5fe0, 0x73a399fc, 0x0a48e085, 0xde766997, 0x575b157f, 0xc90bc169,
+ 0x15a63fb0, 0xbb467eb3, 0x4367d4a6, 0x2c45dd3b, 0x629b24f7, 0xfbaa1f80,
+ 0xfb93996c, 0xe49eb807, 0x15fefbe1, 0x71b527f7, 0x498f5fb4, 0x3d12c170,
+ 0xfb413f13, 0x39d85894, 0x533b8f2c, 0x54e87f02, 0xdc73cb37, 0x02ac8aba,
+ 0xcdeb647d, 0xad0d696e, 0x7a226a9f, 0xce946b90, 0x9b7a011f, 0xf4f3e13b,
+ 0x8b2e2018, 0x3a55ce96, 0xf7d2a59a, 0xd31d2d34, 0xe713f9fd, 0xcfe76ff8,
+ 0xf7363a1a, 0x7a50f1d3, 0x1d579d39, 0xb49bbfee, 0x9c6faaf2, 0x39187d88,
+ 0x01fc50ee, 0x67f9c2fe, 0x715afcff, 0xb642a5bf, 0xc7ec3658, 0x6e3f7526,
+ 0x7418f803, 0x24fe789d, 0xc28d7043, 0xe8439b03, 0xd2fcea15, 0x305927c0,
+ 0x27f05e70, 0xfb1d7aa9, 0x9b1d8073, 0x77e9ebca, 0x9fef626e, 0x05ff1d17,
+ 0xd96b7fe4, 0x350a767c, 0xbd709f8c, 0xab7fb55a, 0x69b6f5d5, 0xc5145bd7,
+ 0xc13b7bce, 0xe93e814f, 0xf37d51fc, 0xa83c06be, 0x3971f1eb, 0xb1e4c73d,
+ 0xeedae81a, 0xfd2395b6, 0x5ff89f7c, 0xa0e87d06, 0xe6187bc5, 0xefe75479,
+ 0x2163fb00, 0x925c6371, 0xce6bc7d2, 0x9d42fd30, 0xaa9c246f, 0x919fe087,
+ 0x4f8489eb, 0x513ade3f, 0x77cf539f, 0x1af7adf5, 0x21eaa9d7, 0x3fd6830e,
+ 0x1cfee764, 0x00dff73b, 0x2e3c8145, 0xd02e5125, 0x04baa7eb, 0x894a27d4,
+ 0x6970f909, 0x76df9309, 0x5437d30b, 0xfed43f39, 0x8216f5b8, 0x2974a9fc,
+ 0xd8c9e7e1, 0x30e922ba, 0x823d7491, 0xd9499e76, 0x39f600b6, 0xff4a25e8,
+ 0xcc2d4bfc, 0xa9c57bcf, 0xf1aef5ca, 0xcafbd720, 0xd77ae403, 0xf337e078,
+ 0xa3fc6d44, 0x2ff30af4, 0x7c10afda, 0x193eba96, 0x5edd720f, 0xf81e35d2,
+ 0xeeb1add6, 0x1f9f012f, 0x361f98eb, 0x24fa8e12, 0xbc5fea9d, 0xdc8cfa26,
+ 0xe95c6a3f, 0x94d78b4d, 0x1fdfbe34, 0x2ce84171, 0x38ae4682, 0xcdeff799,
+ 0xf4a63a04, 0xf2897288, 0xc157abc7, 0x837f8398, 0x532c721c, 0x092d9bf9,
+ 0x2e08dbf8, 0x8f8c3dc7, 0xdb758b9c, 0x0d1c5893, 0x8710f2e1, 0x572e74cb,
+ 0xd110ee2f, 0x9dcd3f9f, 0xdcb834fb, 0x24f5c77d, 0x8dd7fb80, 0x5f097172,
+ 0xa53a45d7, 0xd17fb420, 0xe2c67a8a, 0x1e31cbb7, 0x8eab6231, 0x72726128,
+ 0x734a2064, 0xbde8c47f, 0x4c794d76, 0xfda6b26b, 0x9a596d0d, 0x28e0fcfa,
+ 0xe3b8fd4d, 0xf8f29a05, 0xed351bce, 0xac507c27, 0xbaea4f29, 0xa6fed35d,
+ 0xca6b674f, 0xac123014, 0x0283b9fb, 0x7dd74ed9, 0xcd3ee873, 0x7dbdfff7,
+ 0x0b8871c6, 0x33f6e29e, 0x733bbbf1, 0xa8161c29, 0x4ca57c74, 0x08505fdb,
+ 0x07c0450a, 0x4682dfd8, 0x853cd796, 0xdfbc2e42, 0x7d5a4d85, 0x6d56f162,
+ 0xf37da2b9, 0x0395e05a, 0x8a6a21f3, 0x646c88e1, 0x7934c43e, 0x75e80ebe,
+ 0x2fd51276, 0x91c63040, 0x1ac7c838, 0x1b7fdf6a, 0xb0c873fe, 0x6b3fc36f,
+ 0x7a80d5bf, 0x7fb7e2fd, 0xafa41455, 0xfe2d4e8c, 0xff168acd, 0xfc5ab9d1,
+ 0xfc5a5d5b, 0xe2d44ec7, 0xe2d6e6df, 0x8b44ae3f, 0x168f78ff, 0xb57389ff,
+ 0x6af24ff8, 0xa1529ff1, 0x8d5a7fc5, 0x2b19df16, 0xf4ccf8b4, 0xffbda83f,
+ 0x2aff0224, 0x7baeccff, 0x149ee228, 0xd185d11d, 0x0b474a81, 0xe798153c,
+ 0xc7e9bc32, 0xe922719a, 0x3a8dda81, 0xda8b87bc, 0x6b85db71, 0xbdca0fa7,
+ 0x491a5fd0, 0xf1244f1f, 0xb13b183c, 0xeef9455f, 0x40f8127e, 0xf2a15ea4,
+ 0x1e3970ad, 0xc50eff6e, 0x27c806cf, 0x290f0f6e, 0x361ec09f, 0x43c3dbf7,
+ 0x9087e9d1, 0x53fa838d, 0xee8bfa23, 0x2e3cd995, 0xe049abc1, 0xf225fd5f,
+ 0x04e90fbb, 0x7ef9d227, 0xe3a1eb08, 0x1a35187f, 0x203f18fd, 0x7fcfd441,
+ 0x74871908, 0x712007b0, 0x13e73e99, 0x5ce59f05, 0x7ee42f5e, 0xdbd9a70e,
+ 0x16a97006, 0x300919bd, 0x9e276a6e, 0xe227221f, 0x855ee9ae, 0x976fe093,
+ 0x7f06e908, 0x98f67d3b, 0x519c7d19, 0x289b87f9, 0x9678308e, 0x5172154d,
+ 0x30a3157f, 0xfbeca80f, 0xb2a5ca02, 0xcecf61ff, 0x4707a624, 0x50acd73e,
+ 0xf5c4d9e1, 0xfc0fa600, 0xe3c29277, 0x416bc433, 0xe064b9b8, 0xe63fb4fb,
+ 0xf319feff, 0x4925d193, 0xec78ec57, 0xf80cf10a, 0xa241f386, 0x8c73cd89,
+ 0xe8574c44, 0x8bc4d1fb, 0x49c7dffa, 0x7aee3859, 0xd632b289, 0xb7e828ef,
+ 0xefa3c60b, 0x045c5ba7, 0xd3a2bdfc, 0xabffd045, 0xc32b0996, 0xf55bac1f,
+ 0x7a72a5eb, 0xcc2563d8, 0xe7e1157f, 0x2729114b, 0x3d157c85, 0x94ed0f3b,
+ 0xf0bb32b6, 0x18ceab98, 0x792a2eb6, 0xed7e706d, 0xc81cf4db, 0x96133d2f,
+ 0x5ee14e0f, 0x3f1c9833, 0xa8e2cc9e, 0x6e9a566b, 0x0f497886, 0xbe3d078f,
+ 0xf80cdc92, 0xe6172514, 0x417dc181, 0x0defb0b6, 0xb61f5a0e, 0x498b24df,
+ 0x3c5bd653, 0xdac65978, 0x17483595, 0xd1af7e7a, 0x6487d4ba, 0x217f986f,
+ 0x4c4f8f9a, 0x1027227e, 0xbfd2f2ae, 0x5812a74f, 0x674b28af, 0x9feaf634,
+ 0xdc0146ae, 0xa93d38aa, 0xe93a35f3, 0xdeed6138, 0x2557f4e1, 0xfe601a77,
+ 0x741c50ef, 0xea413c42, 0x56bde074, 0xffb8e975, 0x37f0e4ef, 0x908217ee,
+ 0xe0946ff7, 0xd2f4268c, 0xd28e3cd9, 0xf477dae9, 0x6b25e204, 0x7e44cfc7,
+ 0xb8d7b066, 0x1e4f05a8, 0xeca1677e, 0xea9e041d, 0x2e94e8d3, 0x61a3f387,
+ 0x9e0edcc9, 0x3e002640, 0xca0f9906, 0xf66587a7, 0x59e3c3cd, 0x3fc3c1be,
+ 0x4c7f9824, 0xa2bfd056, 0x13c4f87e, 0x1b1bf217, 0xc6cbe109, 0x50037495,
+ 0xa561b71b, 0xa8737889, 0xa835221c, 0x3710251f, 0xfe6351d2, 0xfd395709,
+ 0xebf052ce, 0x3787b05c, 0x0d53ff8c, 0x1f45ad94, 0x61b94055, 0x90ad8be4,
+ 0xb981642b, 0x23bf3038, 0xa2b66700, 0xef7cfd46, 0xef07686a, 0x425f3e21,
+ 0xacf9d3df, 0x821ed31f, 0x0f63d1f6, 0x51f50a7d, 0x9b29a096, 0x3f75177e,
+ 0x45b04971, 0xb253855c, 0x4856d3e9, 0x8e28a17b, 0x4f47dfe6, 0xc646fd64,
+ 0xbb2d1203, 0x93217dd9, 0xb1678f09, 0x1faaec73, 0xbbb2de3e, 0xc6f818a9,
+ 0x53fd6d30, 0x96711e1c, 0x41678e97, 0xe7612a7d, 0x93fd7957, 0x7966debc,
+ 0xe598b3a9, 0xdfbe681c, 0xb58ffbcc, 0x50bf18e8, 0xb1b78f08, 0xdebc4dfa,
+ 0x093bd6ac, 0xfab1a78f, 0xb46f5e7a, 0xba12fcb0, 0xafdf35ad, 0xdc27e3e3,
+ 0x30de23af, 0x89cc74fa, 0xfa30de22, 0x35da97b0, 0x9d85bd65, 0x25a79523,
+ 0xfb53be6b, 0x1b8f9c7d, 0xf34b3933, 0x28d8699d, 0x34cefb6d, 0x710f2394,
+ 0x0b521b38, 0xf9eaf534, 0xb3a7226c, 0x276b3276, 0xf4d46e39, 0x6251517b,
+ 0x999fff61, 0xcbadd2a4, 0x90fb7404, 0xe2112b35, 0xb99581b4, 0x1f0144a0,
+ 0x3f994fe1, 0x6674789d, 0xcb054acd, 0xb8bfdc99, 0x2c44e566, 0x0b74a6ef,
+ 0x74accff5, 0x2d277961, 0x53f9f42b, 0x58950fda, 0x07ed1b64, 0x7ed34fca,
+ 0xed14f9e0, 0xd24f9e07, 0x337ea0f1, 0x9bca0efd, 0xde507f68, 0xe58dd2b0,
+ 0xb04b2bf5, 0x83d2bf5c, 0xe72b75e5, 0x95f1f3e2, 0x59ae7c5e, 0xbbf58159,
+ 0x3beb8593, 0x22485f7f, 0x93bbb9e3, 0xdde7f7c7, 0x16dcf1ab, 0xd476e0c3,
+ 0x32ffce01, 0x8988e788, 0xa5c63fd1, 0x8f5b1ad2, 0xe719bd80, 0x6a48f861,
+ 0x5b7ac1ac, 0xfd471b09, 0x24fc388e, 0x331d88b5, 0x5950fc64, 0x230df98d,
+ 0x7317cb09, 0xc45289fa, 0x9fc25fcf, 0xbcff4214, 0xabe5ab94, 0x71f91199,
+ 0x9923b3ea, 0xb0e279d9, 0xc72c371a, 0x8413d134, 0xcb8b5e7c, 0x33b1e78b,
+ 0xa9ced0ae, 0xe57b1cbd, 0x5f80a216, 0xbfab54bf, 0x6815a7da, 0x4af144f4,
+ 0xa533b635, 0x6769a7de, 0xda699470, 0x5cc92d95, 0xa47804eb, 0x1b1875b0,
+ 0xbd101157, 0xe3379b0b, 0x999367b8, 0xebd74bbd, 0x3efbff47, 0xeb97ad81,
+ 0x7ccbcf4d, 0xe446a6bd, 0xac6c23ab, 0xd7eb1398, 0xff3c3f01, 0xafdc58ab,
+ 0x43a33dcf, 0x1248dfff, 0x46be01d0, 0xf50cf153, 0x96174863, 0x4aee006f,
+ 0x1144f9cb, 0x848e3ca1, 0x7aa4bed0, 0xb3257fd3, 0x6633d0b8, 0x79a50b88,
+ 0x23f9679f, 0x392b9441, 0xaa391f1c, 0x8a55b8fe, 0x4e9da7f4, 0x7b56fb46,
+ 0x5b8d449e, 0x2516b2ae, 0x33d13e82, 0xb44f7e44, 0x169bbef3, 0x27463850,
+ 0xfaa7c5cd, 0x1ba2bd7e, 0x55e57cf4, 0x4cefaf0e, 0x77c601e7, 0x6afce8c2,
+ 0x0bbfa532, 0x0c83bf79, 0x2c3d5219, 0x1af0f684, 0x941fcabd, 0xfd0fe058,
+ 0xe62c5765, 0x2127b473, 0xc199447c, 0xde95b9e7, 0x7fa9249b, 0xf997e29d,
+ 0xe49be432, 0xbdb67cf0, 0x34dd972b, 0xc75fea4d, 0x5fb614e8, 0xf22b4973,
+ 0xce875cfb, 0xa735ecc5, 0x0f33bec6, 0x79c3726b, 0x7114715f, 0x48c42e41,
+ 0x5ee784d2, 0xc889bfc5, 0xb7a3c47f, 0x17ea8511, 0x40807251, 0x2fda873e,
+ 0x8fe276e1, 0xc2fcbf38, 0x2de70d32, 0x94f7aba6, 0xf9af51b9, 0x90c97642,
+ 0xb345f2cf, 0x4f123f1e, 0x6573eb6a, 0x4a5e07d7, 0x47f68b97, 0x517a60bb,
+ 0x5f784db9, 0x204bb89b, 0x83ce02a9, 0x99d9a7e5, 0x5adfaa7e, 0xe0e3fc44,
+ 0x2e37aed0, 0xa5dae005, 0xc2a9d01c, 0x8aabb69e, 0x3f06ec33, 0x0b8008d4,
+ 0x2e5873c0, 0x5f2171c2, 0xab95deef, 0x14ee4e10, 0x6935e786, 0x7cf9dc2a,
+ 0xf70ddb88, 0x566a2dbb, 0x3aed5bed, 0x7f15e7d7, 0x3b6bea0f, 0x8bd3cc45,
+ 0x9885e784, 0x286263f7, 0x3346cba2, 0xa79d0cff, 0xc129e61b, 0xbe00e3bc,
+ 0x58b3d704, 0x5ce00436, 0x5ad08f66, 0x31a97182, 0x971e123a, 0x53339f52,
+ 0x277aff18, 0xb467c659, 0x0b4dde73, 0xef9785c6, 0xc31eba47, 0x122c4fd7,
+ 0xbb7093cb, 0x5abf7095, 0xf0676a83, 0x3e28ea3c, 0xa0fbbedf, 0x2f3cb146,
+ 0x0adce90b, 0xd9431779, 0x614c3f11, 0x3b7ef2f1, 0xe806a282, 0xf309bc67,
+ 0x7cd41a1b, 0x055de514, 0x13e96bf3, 0x9c4c51f2, 0xd959d74e, 0xfaea043d,
+ 0xbe30a656, 0xa3e392b9, 0x22ecc4d7, 0x27e4db88, 0x6f9f9d84, 0x58fb472f,
+ 0xb6f4f38d, 0xd552fcb3, 0x49c950ff, 0x060df7a0, 0x221dde87, 0xdb2a77c6,
+ 0x0ef760ef, 0xf7893c76, 0x14bed235, 0xde7287a0, 0x6b4ebcbe, 0xe3d82f0f,
+ 0x0ca51b59, 0xc117bbb4, 0x03d9ab7d, 0x3b48eded, 0xae14b1fb, 0x3e48babf,
+ 0x354e71c4, 0xa28b1f66, 0x126435f3, 0x2297bf3c, 0x6ef784be, 0x09b3ed53,
+ 0x79243bee, 0x488fbeec, 0x6a92bfbc, 0x15ef3840, 0x5a5b8f08, 0x8ef7fe90,
+ 0xef7ffb67, 0x0e778b91, 0x93dcfda7, 0x7ea6e0c1, 0xcb064f77, 0x0607dd33,
+ 0x4adf7d15, 0xf960c948, 0xdc38bb3c, 0x9b9f33bf, 0x5573e5ac, 0xa2c75d6d,
+ 0x3b77e415, 0x8f7bde81, 0x0f2625fd, 0xef0847f7, 0x833f7f2d, 0x0de607cd,
+ 0x74fbf479, 0xa70bcf9f, 0x12297d83, 0xfaeeb79f, 0xda698cf4, 0x7bc85d79,
+ 0x3676e12f, 0x579856af, 0x4264f04f, 0x3ab47e78, 0x83c57daf, 0xfd7cef9f,
+ 0x9133e77a, 0x5068a7ce, 0x26fd1d38, 0x0c33ed38, 0xf80f9f3e, 0x0de3fe7c,
+ 0xc0c0ef76, 0xd3d4ebfa, 0xefc04476, 0x807bcec5, 0x7ef9d35d, 0x847a0290,
+ 0x63013bb3, 0xad7e1c4c, 0x0b3e9c85, 0xa171df39, 0x1f7c444d, 0xa4bcc04d,
+ 0xfbd58956, 0xab028bec, 0x8ebafd28, 0x7900c82c, 0x88d0fd60, 0x86f8c5f7,
+ 0x4b8b37c8, 0x97d8eb65, 0x870a0c2c, 0xe47f5e18, 0xb7f61944, 0x012303fe,
+ 0xf5cb507e, 0xab72f5f4, 0x5501ee09, 0x02e508e1, 0x4219f4fa, 0x2e505c8b,
+ 0x58a4c2fc, 0xc74f1906, 0xb114dbc6, 0xd4f1d46f, 0x973529a7, 0x3785ddf9,
+ 0xdea3c844, 0xbc3df934, 0xa15367af, 0x3bf73c84, 0x4b59bfc3, 0xef82172f,
+ 0xe8c9dc25, 0x7a0a94c5, 0xe63a7094, 0x13ecb47b, 0x03cdbf42, 0xb8bc19f8,
+ 0x4647df7e, 0x840c22d2, 0x2f4e25d3, 0xf5d4faea, 0xdeb6f3ab, 0xd6f300bc,
+ 0xf1301f01, 0x7a9d5498, 0xd5f21e2f, 0x60f72e58, 0x2627285d, 0x7d0f2c4b,
+ 0xdd7884bc, 0x3c46f134, 0xc78fb027, 0x0c93439b, 0x7e43de83, 0xfd7f1f0b,
+ 0x04ecff95, 0xaedfd5fb, 0x44d9f3c7, 0x45de72ea, 0x8ef7c8e9, 0x52bdf784,
+ 0xfb812a7a, 0xb89c8e67, 0xdd7a0318, 0x847aa94d, 0x0fc04df3, 0x115c3e41,
+ 0xff7f304b, 0x18b217c4, 0x5393ff46, 0x7497ae45, 0xfe5e4276, 0x979602c6,
+ 0x807ae16c, 0x057744e5, 0xf132dfcc, 0x4c2146c7, 0x1aa5e6ce, 0x868dbbf1,
+ 0xf68b8250, 0x4910ebe7, 0x2e81f510, 0xefab47bc, 0xe0cc91dc, 0x05485d50,
+ 0x47dc1e4c, 0x9ad7eeca, 0x3e30aa9c, 0x807de74b, 0xf91a8fbe, 0xf50e5c85,
+ 0xacbc7485, 0x32adeffe, 0x78d467c3, 0xa6c59f76, 0xe193bfc9, 0x8158aefe,
+ 0xafb43de0, 0x7935eaa4, 0xe8649ffa, 0x9d9dbf78, 0x65f9bfa0, 0x5b09f309,
+ 0x40990f83, 0xc5f757af, 0x86dd54d3, 0xfdf8eb76, 0xe626ebaa, 0x805ce006,
+ 0x4a7fc74a, 0x61527af5, 0xbc5f747d, 0xa7577a84, 0x47c22a67, 0xc97c87ce,
+ 0xef13a431, 0x0685210d, 0xae4be419, 0x6fd9a74e, 0xea6f1c2d, 0xa8a5ea93,
+ 0x69c23cef, 0x62f79559, 0x39e0898b, 0x62b32ba3, 0xd3152f41, 0x25cf3d54,
+ 0x6cff1c03, 0xe1fa8399, 0x8d2d37d9, 0xf57cf1e1, 0xb3da9a79, 0x797f4341,
+ 0x0333cba1, 0xde222fda, 0x2e8fa0b5, 0xe735166a, 0x7df2cfae, 0x144af0be,
+ 0xf5e98609, 0x87de270b, 0x5e1647e7, 0xaa412189, 0xe7e59d27, 0x3cf2ce7d,
+ 0x654f7f9f, 0xaf81b2f2, 0x75ea4b67, 0x08aefbea, 0x0ff3b97e, 0x7e3195cf,
+ 0xf700eff9, 0x00cba12a, 0x8de36e7c, 0xfe3cc17f, 0x0f4ed4d3, 0x3ad37ce6,
+ 0x6c3048e3, 0x5776be9c, 0x7e9eb84c, 0xff3828bc, 0x105af5fe, 0xfda9a70e,
+ 0x4c70cdff, 0xbfb1c0d1, 0x1c0d2cff, 0x839ff607, 0x995e9fe3, 0x8ffd2dfb,
+ 0x457fa21e, 0x7efeff33, 0x3db8e187, 0x8f9ecb47, 0x68e5fba6, 0x57f6f570,
+ 0xb0ed5f21, 0x272fef11, 0x78c5ad6d, 0x0417e89e, 0x3f2d99cf, 0x90c7e5fc,
+ 0xb77cb687, 0xf46305c1, 0x5cf343ea, 0x6187c883, 0x7dc3f644, 0x6f73ea3e,
+ 0x27ae366a, 0x0a49bdf2, 0x666f90c8, 0x55e495ca, 0x9d65e80a, 0x1fb8d581,
+ 0x549fc84c, 0x6fdab83f, 0x9ea88a6d, 0xad7dc567, 0x10d0dbde, 0x7c00eded,
+ 0xe6a5167f, 0x8237f91d, 0x67f2ad1f, 0x85eecca2, 0xa21da1b3, 0xe225b1fa,
+ 0x91a3bf45, 0xe5e40878, 0xdf7865e7, 0x53fefe00, 0xafc006ca, 0xe3d98e2d,
+ 0xb723ff45, 0x3b9836f7, 0x7e30ae9d, 0xe954fbf7, 0xd6fce4fa, 0xfe333908,
+ 0x4c82e7fd, 0xe61efcce, 0xfe762551, 0xf2132cb2, 0xbdf8bb08, 0xe3018a3d,
+ 0xf0c78505, 0xd532afbe, 0x8c8baf5e, 0x40d9a75f, 0xeefd55ff, 0x044f9031,
+ 0x9646c23a, 0xcd1e5dbf, 0x89bfe5ca, 0x907573c3, 0xf0079fc2, 0xec5d156e,
+ 0xe119379e, 0xa1af917a, 0x1d31b4d7, 0xe1cbd9e0, 0x75fdb17a, 0x62ee57bc,
+ 0x7fc470dd, 0xc13f6bf9, 0x25f6a17b, 0x0ea77cf3, 0x729fca2b, 0xee08aba3,
+ 0xcc97db2d, 0x2956ccf4, 0xa6105318, 0x2d4bae77, 0xbe7abe46, 0xf40eb86e,
+ 0x7fae1572, 0xa360fce6, 0x4293efea, 0x2ebbf045, 0xbf830be7, 0xdfb7f945,
+ 0xa267bf8c, 0x1165f03b, 0xd1b76fde, 0x1782f788, 0x65b9181f, 0xcaafad2e,
+ 0xa59e61d1, 0xe71980ee, 0xdd81a173, 0x82df03af, 0x903aae9c, 0x52c3bf82,
+ 0x3cc21d1e, 0x5728aaa9, 0xca41c40e, 0xf784dc0f, 0x30da9f7a, 0xe5f81d32,
+ 0x1d2578c9, 0x40dd35ef, 0x7dd74e81, 0x7b0463b2, 0xcf013f5f, 0x463759ad,
+ 0x5ff3077b, 0xf22472a8, 0xc97d9efe, 0x006d3df9, 0xd726919f, 0x2d3e5a6e,
+ 0xeb9c58b8, 0x82b66878, 0x9e171671, 0x9cb72bdf, 0xdbef1afb, 0x7ee4fe6a,
+ 0x481def82, 0x161daab7, 0x97395e39, 0xa10cfb33, 0x387bf079, 0xdc386be5,
+ 0xab9f2c0d, 0x839f975c, 0x8df70e65, 0xe65cf711, 0xab7831a5, 0x242753cf,
+ 0xca8c2fbc, 0x67c874ff, 0x88d8753e, 0xe36a7674, 0xaaaf3c68, 0x614e578e,
+ 0x797dd322, 0x058caed2, 0x634b8ebc, 0x0d7caafc, 0xf7d52fb3, 0x25cdbae5,
+ 0x8750e780, 0xbd2bf988, 0xe2062872, 0xb53b6a1c, 0x769eb7dc, 0x65d77f11,
+ 0xc411f25f, 0x0227a537, 0xcd7ba4f4, 0xf7d5f28a, 0xe037719a, 0xf1217cf3,
+ 0xfe5c8347, 0xce4efd80, 0xea230ed1, 0x321fbdbd, 0xfdc074bb, 0x3a509649,
+ 0x7be81fdc, 0x58f9052d, 0x17685a6f, 0xeccd93d3, 0xbd77b55e, 0x2c3c7813,
+ 0x9647df89, 0xe5d9fa04, 0xf410730e, 0xf8c4fa33, 0x71ec9f86, 0xd1c3fbe2,
+ 0xf436fc04, 0x53854019, 0xdfc4efd8, 0xfc4d2095, 0x7efc4efb, 0x0477ba79,
+ 0xd9e5e5f0, 0x7c0b7fb4, 0x2eed8ddf, 0x806f7967, 0xe64bfd32, 0xbf6325e3,
+ 0x7c0cde69, 0x64e17c2f, 0xc4d0a7bf, 0xdeb13beb, 0xc04ef467, 0x4ad1fc75,
+ 0xe759065a, 0x55bbdef5, 0x7887169c, 0xe14de754, 0x245efa8c, 0x98d26a5c,
+ 0x23c2a47e, 0xf0fb2e92, 0x03f32df9, 0x97c009bf, 0x363c33b4, 0x3e30348c,
+ 0xf51a3f52, 0xa51b525a, 0xd55a13c9, 0xf761cec1, 0x9e22b06c, 0xa7eef57b,
+ 0xde851e41, 0xaf7613d5, 0xc008d515, 0xf07130bf, 0xe78e72fd, 0xb3d65709,
+ 0x2f73a27c, 0x6f9f4d9c, 0x678af381, 0x5515e735, 0x24ed1f3f, 0x1628fc06,
+ 0x96531297, 0x116cf4c7, 0x377ec7e7, 0xc15ea367, 0x6ff207df, 0x847e8918,
+ 0x00e50653, 0xc3518efe, 0x55d01d18, 0x1ef18bbd, 0x9f5b137f, 0x7a8e5f7a,
+ 0x7c244def, 0xd9b2d35a, 0xef1091ef, 0xf2877003, 0xf024a249, 0xffde1a60,
+ 0xa2ff0155, 0xa618afa0, 0x3f919b73, 0x185ca0d4, 0xe196cf78, 0xe83f7e5b,
+ 0x3fbcb6ff, 0xeb3ae09d, 0x9018fe5d, 0xccca9fab, 0x53d8a3de, 0x6c8bae50,
+ 0x69a7789d, 0x4f6bc812, 0xd63c5a5b, 0x54fc3f23, 0x9f2af560, 0xa07eb01b,
+ 0xda07e817, 0xa78ebed1, 0x3219bf31, 0x8ca7b809, 0x8f900df8, 0x9f27caa6,
+ 0x3ce0e920, 0x894db76d, 0xaeec7a01, 0xbd83b6cf, 0x1253665c, 0xc2e8c20a,
+ 0x73c106f7, 0x37dc0aa4, 0x5f7e013c, 0xfc163dc2, 0x5aecfb75, 0x7ce4417f,
+ 0x35d29a5e, 0x77febc2f, 0xedff4c69, 0x8a28fbe2, 0xdf9063c3, 0x2fbc4279,
+ 0x77af78e6, 0xfb416f79, 0xe2dda231, 0x1e9cb1ad, 0xbd37de22, 0xf798affa,
+ 0x4f7b43b1, 0x78f8cfdc, 0xf8371e9f, 0x19e01b85, 0x15baf985, 0xab9f199b,
+ 0xe734bb78, 0xf3c65651, 0x1e5a53d5, 0x58e3dfc7, 0x0e7a7bb0, 0xf10b7c61,
+ 0x82e3d2a0, 0xe80e7774, 0xa26da171, 0x62a2fb0c, 0xa9f388ab, 0xdb4c9a97,
+ 0x5b33fbe8, 0x55dfa8f5, 0x499cf9f0, 0xde20c6f5, 0x28192224, 0xde48cfdc,
+ 0xb75fd418, 0x891ddff1, 0xf76d0758, 0x0830549e, 0xcf0c4c7c, 0x41ec9f08,
+ 0x1d5de0e8, 0xfc0169e2, 0xa3cc197e, 0xe4bf4045, 0x03ef3499, 0x76a6ee50,
+ 0xdbffde3b, 0x59f78954, 0x8cfbc244, 0xb9f48bc9, 0x8547af98, 0x2a38e467,
+ 0x9e017b3c, 0xdf1d2fa0, 0xf7cf728e, 0x4b140894, 0x425fb48e, 0xc74a7a7b,
+ 0x826f8ff4, 0xdea99bf7, 0xcd9c80a2, 0x400fedfa, 0xf889d5ce, 0x1d65267b,
+ 0x422409d9, 0x58dd835e, 0x189ccef6, 0xac9c985d, 0x7e31166f, 0x766c3f52,
+ 0x7f6c42cc, 0xafa04ef1, 0xa12b8a93, 0xe8ddac20, 0x8178bef4, 0x9be55f06,
+ 0xe3031aff, 0x71ea3454, 0x7a5e2a5d, 0xff909ce9, 0xbfa34536, 0x843537a8,
+ 0xea78aafd, 0x83c06fa3, 0xddb44f4a, 0x1f32e95d, 0xa8fc8fc7, 0xe45bd33b,
+ 0x164e841a, 0x85c7493d, 0xf15ab6fe, 0x1d6bc2fe, 0x1f478557, 0xc6bef9be,
+ 0x5771e032, 0x75bffa26, 0x4c984aef, 0x6669b27d, 0x72e3ec3a, 0xdfc02f2a,
+ 0x3e842e50, 0x3b247bc6, 0x6b0f788c, 0x0f25e6f9, 0x1fe578c0, 0xdf50751a,
+ 0x58e6787d, 0x5e04579c, 0x07d29c29, 0xccdef7a3, 0x0c2bba50, 0xc09f547e,
+ 0x27aeadfd, 0x0f38de6c, 0x7de14f6a, 0x1499bd24, 0x607c619f, 0xbbd33a76,
+ 0x80d97b68, 0xc3eecdf4, 0x1caf5be9, 0x62395eb1, 0xa411efbd, 0xe2f2e26f,
+ 0x647c167a, 0x05fbc1d4, 0x0391dc4f, 0x86eeb5fe, 0x6eaeb8a9, 0xec2c7bbb,
+ 0xda74eeaf, 0x72fc20ff, 0x9d7413c1, 0xceb0df79, 0x6be23326, 0x43da75c8,
+ 0xac37c8bb, 0x50e9c7d3, 0x4969e75d, 0x2bdfc189, 0xf012283b, 0x3cd2f897,
+ 0x65626f1b, 0x9f289dfc, 0x6f83d19e, 0x31e63473, 0xfbb3b4f6, 0x403e55c9,
+ 0x7a46bbc7, 0x743d21d0, 0x265b2b17, 0x106d7d02, 0xed8bc865, 0x5bf7186e,
+ 0xeeaf1df8, 0x7a0ca28d, 0x83317742, 0x2807e51f, 0x3dd3bbb7, 0xb0f96277,
+ 0xea8f7f1e, 0xdf5fd354, 0x1de173c7, 0xfae0857a, 0x42e71b3c, 0xf817ce99,
+ 0x3dcb851a, 0xe3d55f4c, 0x9eebebfa, 0xff7a83aa, 0xfcf01bd6, 0xacf940c3,
+ 0xa3457385, 0x4487d9a8, 0xdf3c7052, 0xaf782913, 0xca670a83, 0x1ec07361,
+ 0xe501e152, 0xe1fa6339, 0xa0e7e3e2, 0xf7602f41, 0x067e7120, 0x7262c9f0,
+ 0x0081ce02, 0x28f3831f, 0x48abc943, 0x47a913fe, 0xaf8fbcfd, 0x6571f968,
+ 0x3e18efc4, 0x125e5118, 0x469637c1, 0xd44557d4, 0xe77cf953, 0xe4e7fe60,
+ 0x2b5f2d0c, 0xfd5470e3, 0x041bbda0, 0x24cb43b4, 0xcff600c5, 0x7c98534b,
+ 0xe988972e, 0xec97dc16, 0x44994b7c, 0xf0058d6a, 0xb70865de, 0xb57f6893,
+ 0x472d3b46, 0xdb443e31, 0xcac21895, 0xe755bf2a, 0x878701f3, 0x7ecefcfa,
+ 0xe321d281, 0x8fa41f15, 0x28af181f, 0x757eb310, 0x83abec02, 0xbe95da22,
+ 0x21fc99b7, 0xf2da5d5f, 0x97ee03a2, 0x30bcc6cd, 0x7091fd75, 0x14bb6dec,
+ 0xd7ebbf03, 0xe780dc73, 0xe3dacb93, 0xb2fed18a, 0x7b850687, 0xda9f5f0f,
+ 0x15d48f5f, 0x6f5c2b33, 0xe1315d26, 0xd65aa3bf, 0xd8256976, 0x7e7e14b3,
+ 0x9f8f8c31, 0x062f88ea, 0xd7fcb2bb, 0x7e70c5c9, 0xdaa196d6, 0x1acfcafd,
+ 0x341cdf61, 0xe7a23fa2, 0xf83ab9ed, 0x0aede7be, 0xf78e5cfe, 0x3e9cf5b8,
+ 0xc7e30e95, 0xfee7b4e8, 0x5b6fdc0d, 0xd764fbae, 0x0fffc0cd, 0x09ae6625,
+ 0xeb9737f3, 0x7e1ed00a, 0x079a1f51, 0x7e7aa6f3, 0xaa57e41d, 0x1432d8fd,
+ 0xf071af96, 0x0fe02eec, 0x15a636a7, 0x39e95b00, 0xdfed0238, 0xe5c70f9e,
+ 0x247f68c8, 0xbc2f80b9, 0x339657a8, 0xdaeac57b, 0x1fdfd99d, 0xc671038c,
+ 0x8a13839e, 0xf3d05fc0, 0x2d2f9b21, 0xb680ffa3, 0xa51e43f3, 0x4e8c6fda,
+ 0xdd7904d9, 0xb47ad7e4, 0x3afa1e23, 0xb9ee113b, 0x1e0c3188, 0x41bb019f,
+ 0x1abcd79b, 0xabdeade7, 0x2c57691d, 0x4f961e20, 0xa97f611b, 0xda4773f7,
+ 0x69a41589, 0xd030976d, 0xb88aa45e, 0xfb009fc9, 0x456bfd5a, 0xef64bf79,
+ 0xbef6a355, 0x9fdf3f62, 0x65c7e426, 0xa0363f74, 0xfcc029bf, 0xa0e2757b,
+ 0x65efd771, 0x9e3ae264, 0xbcdbfe8e, 0x9ebc30ae, 0x49c911d4, 0x40d27ae1,
+ 0xc182ce4c, 0xe9cbc6ec, 0xb40d9f60, 0x1fa2cf17, 0xbefc3ca3, 0x6ed03230,
+ 0xc01c593c, 0x0d93bdbc, 0xc09efe22, 0x918ddaf5, 0x97bfabdf, 0x2c20c9e0,
+ 0x6772191f, 0x3764dfed, 0xc2abe76b, 0xc77fccd3, 0xe2fdb222, 0xca37160c,
+ 0x6e245afd, 0x7a1df7d8, 0xdd13bf3c, 0x1f96c5f2, 0xebb67d00, 0xe3054ce5,
+ 0x0b7bf82b, 0xf988a0e4, 0xa7edbd7f, 0x39041e62, 0x1e1c7073, 0xd793eb23,
+ 0x938c4507, 0x4a5db4f4, 0xed0a7880, 0xbec6e307, 0x405ca78e, 0xe3cd43bf,
+ 0xfaf10cd1, 0x08eef9fc, 0x1f8f28bf, 0xc99cb4f7, 0xf94efe01, 0xb019a3e0,
+ 0xe2be733f, 0x15756cf7, 0xf9d1fd01, 0x1bdefea1, 0xa5fa8cb8, 0xf41c5da9,
+ 0x19f5aafe, 0xcfe3eb86, 0x8bf20325, 0xf7c467d6, 0x095ab3cf, 0x7ece4019,
+ 0xb4c51e5b, 0xc3570b83, 0x4dbd33fd, 0xb77f0b82, 0xb9445db9, 0x3a3da0b5,
+ 0x4cbc50a0, 0x72c1611b, 0xee764ef9, 0xf9388663, 0x2e6ff07d, 0x7fa220de,
+ 0xf2cb48f3, 0x6798f5f7, 0xe58327a1, 0x5de7f461, 0xc6147c3c, 0xdc14fc59,
+ 0xc4ff4312, 0x6fd00dfb, 0x8102d3e5, 0xcc884a9f, 0x779818bf, 0x144f35d1,
+ 0xc05de607, 0x6907e5f9, 0x466d15bf, 0x3c0faff4, 0x1bc840ef, 0x21f7fd09,
+ 0xbc6f0ee5, 0x9f6d28ef, 0xf96062db, 0x3e35667f, 0x0ef685d5, 0xd0f3b209,
+ 0xa74f073d, 0x877d1e03, 0xb1fd07fe, 0xd20fed43, 0x0e3cf2ce, 0x57dfb066,
+ 0xd2fafdcc, 0xda419e9d, 0x8b3cf237, 0x327f7abd, 0x5b47b1e8, 0xe83f232e,
+ 0x6cfcc83d, 0xfc4ff643, 0x0aefe666, 0x570fd19a, 0x0edf2ad8, 0x83ea84fb,
+ 0xeedf5eb0, 0xd377b3b5, 0xbd55f9b2, 0x6f95aa02, 0x0bf705b8, 0xdff08fec,
+ 0xc9f75203, 0x53a71e5e, 0x791a47f3, 0x3f9a8dbe, 0x4493e6a2, 0x27cd43ce,
+ 0x7c614c69, 0xf3c32f23, 0x945bd001, 0xe77ecfce, 0x68cf2233, 0xc8a1bca8,
+ 0x71910773, 0x8ae24182, 0x46c0af2c, 0xc6a06e30, 0xbe540d17, 0x31d647c3,
+ 0xd06537b3, 0x227bfd7a, 0xc5434fda, 0x1c75d51b, 0x79865139, 0x8b2f5556,
+ 0xb0bfafe8, 0xbce3cf5f, 0xe9438c21, 0xc8617c4f, 0x7ece7e44, 0xcb47c95f,
+ 0x5937def0, 0xd28efcd2, 0xe71e1c57, 0xd9f07233, 0x978fb923, 0xe47b7ed2,
+ 0xf5e80332, 0x4a0b13fa, 0x9de8de40, 0xd7980665, 0xa6c51391, 0x4d9bc04c,
+ 0xb6b37dc2, 0x53b71d5d, 0x3ffffe86, 0x1f012a80, 0x00008000, 0x00088b1f,
+ 0x00000000, 0x7db5ff00, 0x55945c0b, 0xe779f8da, 0x380c2b9d, 0xa5117280,
+ 0x380a0ee1, 0xdb95902a, 0x9784268e, 0x4d32d45a, 0xe5450757, 0xdb698032,
+ 0xcbbaeee7, 0x5acd4d78, 0xb5aca8dd, 0xbcc0c1be, 0x1a163b60, 0x25a3b614,
+ 0xb68b9599, 0x3f9b5b99, 0x0286f328, 0xffb9f562, 0xcffebf6d, 0x3af39cf3,
+ 0x7e988ef3, 0xbf67dfbb, 0xde73877e, 0x73ce7d73, 0x9339cf3f, 0x196e39a6,
+ 0x9eb19fd3, 0xcadb2d1c, 0xc87b3b18, 0x630d81bc, 0xf7fc07ec, 0xacf2c653,
+ 0x18036312, 0x319abafb, 0x3e57deaf, 0x7c81fb3f, 0x02d8c196, 0x316358e6,
+ 0x33235a43, 0xbfd191af, 0x1d1fb01f, 0xf281ee9b, 0x988357f9, 0x5dafc237,
+ 0xb63d14f4, 0x94357f9b, 0x3d424779, 0x3677af13, 0x4f285204, 0x1872f1c0,
+ 0x9de912cb, 0x6edf2d22, 0xebf69cb2, 0xa613c2bf, 0xc53557ca, 0xf9a74e58,
+ 0x47f8e5f2, 0x636ffc0c, 0x98c91646, 0x97627f93, 0xdb74fc5e, 0x913f485c,
+ 0x5856091c, 0x9ed48557, 0xb10c0f7f, 0xef57ba26, 0x2d3ae330, 0x63f29bcc,
+ 0x5e608ceb, 0xd5ae71bf, 0xf5a46abb, 0x2566e0f8, 0x6bd6f9b8, 0x5d7c3826,
+ 0x38137d1d, 0xe8e0aac6, 0x05413feb, 0x4ffbebc7, 0xaebff1a1, 0xff49bb4e,
+ 0xbfd06f43, 0x5f7f3555, 0xee3449bf, 0x0b0d0caa, 0xa4f486cd, 0x5e00cdc1,
+ 0xcb235500, 0x1d80cc65, 0x795654c1, 0x66ad19c7, 0x75257b5f, 0x6cb171b1,
+ 0x946f7c14, 0xfdf0dc0b, 0x25ae6592, 0x985d5219, 0xa1dbb186, 0x705ecebd,
+ 0x086bf417, 0x41708f0b, 0x89ac133f, 0xc2efaeb4, 0x28301516, 0x08f06eff,
+ 0x838f15d9, 0xfcc42a2c, 0xf2c541aa, 0xe37f1c7a, 0xb5f70c73, 0x0fc7c8ca,
+ 0xfc332fd9, 0xba30eece, 0x777ea193, 0x7996c7cb, 0x06dfce30, 0x3ee0e639,
+ 0xc909f32b, 0x3ee19779, 0x6dc726b3, 0x3d8c2185, 0x0dac616e, 0x50f6daf3,
+ 0x725eaf5c, 0x405de7fc, 0x06afec0f, 0x77c90f56, 0x25aa4726, 0xcabed7c3,
+ 0x01f9a7aa, 0x68b2c435, 0xa50d5f5c, 0x08574d55, 0x8916d6ce, 0xaf7ca5d6,
+ 0x77043d62, 0x8851e586, 0x7d2b5a93, 0x16a4726f, 0x71e6fa66, 0xccf7ffad,
+ 0x9fd00d2e, 0x433fff61, 0xdadd9e11, 0x906dfb9e, 0x60e45a7a, 0x11aef87f,
+ 0xf0763974, 0x50ed5937, 0xfaed895e, 0xdbd8f631, 0xf30ca9e5, 0x9c2c9e86,
+ 0xffb7c1f7, 0xe90ed591, 0x6fcbfb77, 0x50edf2c3, 0x6ef90adf, 0xcda54f7d,
+ 0x6624bfaf, 0xf9466971, 0x0fb16ad2, 0xf7dbe581, 0xf3881caf, 0xdcc1d068,
+ 0xa59c61c3, 0x474f2365, 0x9fd83a20, 0xb5b8478e, 0xec3d58e8, 0x54d35747,
+ 0xe54af919, 0x43058c27, 0xf619bb3e, 0x83d9f207, 0xfb035b99, 0x93ffb953,
+ 0x955fb8e9, 0x068b7a39, 0xbc341296, 0xbe02bdcd, 0x2d18e507, 0x2c53e212,
+ 0xeccf5f1f, 0xfb62258c, 0xb7dc08bc, 0x2a310637, 0x41f997ff, 0x6bdbc71d,
+ 0xbc7bc0fc, 0xabc601b2, 0x47efdb90, 0xa17c003e, 0xf2a5f11e, 0x668e6fa3,
+ 0x4f46b158, 0x78cfee24, 0xd0f8171c, 0x369fa2c7, 0xac0ee16b, 0xfbe0fdd7,
+ 0x2de8b06b, 0xf5c0e1c9, 0xb68c62b8, 0x68cfc47a, 0xbf14c277, 0xaacd7d7d,
+ 0x4ff0f6a1, 0x221dbc42, 0xa07bbae6, 0x22587167, 0x470ee5fe, 0x30d2a87c,
+ 0x3643f207, 0x077a8009, 0xe66165e2, 0xe9ebcc94, 0xd415b18a, 0x7b56dbdf,
+ 0x57c735b3, 0x336993ff, 0xd07d1d33, 0xc12a6221, 0x0479ef53, 0x6153d9e7,
+ 0x7d856db6, 0x827e0bf8, 0x334f2f76, 0x5850e578, 0x56bcce8f, 0x193a3c02,
+ 0x0075bb3c, 0xd9b57fac, 0x73ae1ef1, 0xd7e343fa, 0x183a5e60, 0x788c5d61,
+ 0x8b9ed459, 0x726d12fb, 0x3be3807c, 0x22db8e8d, 0x06978961, 0xc1fb523b,
+ 0x08c2b356, 0x98566f0e, 0xfce7d859, 0x797c7cf9, 0x54b841a6, 0x36f4b808,
+ 0x7c43f626, 0x5fad7aed, 0x74f98316, 0xca095869, 0xdf312e87, 0x988f2073,
+ 0x712e9f1f, 0x4117d31f, 0x63bad2fd, 0xeb7eb9fa, 0xeecc60af, 0xfc7eb8c9,
+ 0x301fb88b, 0xffd785fe, 0xa1afddf8, 0xf76fceab, 0xc004b0a5, 0xad22e913,
+ 0xc71dbbeb, 0x9df58b66, 0xd63ff5c5, 0x87a713db, 0x073d3975, 0x887f9cf4,
+ 0x527b69f5, 0x5d7d6c7e, 0xc27cb69a, 0xa5927d8b, 0xaed7de3e, 0x7e58f1a2,
+ 0x497be02c, 0x9908d85d, 0xe20a59e3, 0x061ba959, 0xa55bc3f1, 0x8b3e051f,
+ 0x5debbf05, 0x1413e02a, 0x5af2859a, 0xfe328f81, 0xccf800a9, 0xe1e4f6d6,
+ 0x0b2f663c, 0xea7e70d3, 0xbe51fc26, 0x1eaa59cf, 0x30e22577, 0x1bf5cfcc,
+ 0x66f34dc9, 0x2b86ff3c, 0xf21ebdcc, 0xbf95cd06, 0x21bd454c, 0xbd436353,
+ 0xf0104b61, 0xfd8c1180, 0x8bcfec59, 0xe18c1fc0, 0xcb16be54, 0xfb7883a3,
+ 0xee3567e8, 0x70bed095, 0xe1e1336c, 0x9b6695cb, 0x3115630c, 0x8530ac60,
+ 0x47aecc79, 0xe63d7fb8, 0x61dbfb1f, 0x1de2839d, 0xfeb0f151, 0xb89a1139,
+ 0x1c3cd0bf, 0x9c032743, 0xc70e68d8, 0xc207b840, 0xe8b30a7f, 0x36c65fb0,
+ 0xa7ee9068, 0xe652f858, 0xa78e9c4b, 0xc70ebb32, 0xa839907b, 0xbd2ef1de,
+ 0x1c1d019d, 0x3060f407, 0x8b9887ef, 0x373067ca, 0x979933a5, 0xb59cffea,
+ 0x03a15e53, 0xfd39ffc0, 0x8d9ffe39, 0xb26f0992, 0xc7be01e2, 0x2f06b382,
+ 0x7e4c7585, 0x6199352e, 0x0803359f, 0xf79b373e, 0xb1c38964, 0x1db8eacd,
+ 0xf05bdfd7, 0xd0354bed, 0x25e8c68f, 0x27c6bbfc, 0x78100dc6, 0xa27ce3f8,
+ 0x09e397ad, 0x06398390, 0xd8af70e0, 0xe5ed7bd2, 0x8cbd7093, 0xfe9e4859,
+ 0x9e5fd04c, 0xb3fd666c, 0x6dd97c71, 0xa5d8b9c0, 0xbe42468f, 0xd6cc8c60,
+ 0x5bde3cc3, 0xbede48ce, 0x13765c37, 0x869f20ae, 0x7e8bf7f6, 0xba998d27,
+ 0xcbd41faa, 0xdb3dbeff, 0x20c1690b, 0x7eed97dd, 0x7fbe35f8, 0x4830aaed,
+ 0xcba92427, 0x2d36b227, 0x065275c2, 0xf3f1fb94, 0xf5d5b3fb, 0xe198e00e,
+ 0x2328db98, 0x0f8ccdfd, 0x18267fe9, 0x90d843b2, 0xbd1f641f, 0x9de9eb28,
+ 0x0ddf4574, 0xef10d8f3, 0xb2fb8b98, 0x67afbef8, 0x2d33bd23, 0xca2468fb,
+ 0x5d7ca3a9, 0x00dd025f, 0xd5d3b206, 0x7e80d120, 0x883e80ce, 0xb7a073f9,
+ 0xdaa17a61, 0xd045e94a, 0x577bf0b3, 0x9ef28db5, 0xec72c2f8, 0xcbdaee77,
+ 0x4e06475a, 0x6df0852b, 0x36b7c089, 0x8c13578d, 0xb255b4f4, 0x625c7ca1,
+ 0x0c1b1b6a, 0x1f525bf0, 0x671d836f, 0x569e4d65, 0xb7b17e9c, 0x75b71f30,
+ 0xad45e1c1, 0x055c5698, 0x6cbd078c, 0x1ff85cae, 0x7f5d0788, 0x7dda72f9,
+ 0x7ab67e50, 0xbe7f8d14, 0x77e34eda, 0xfa501756, 0x37e3bc7e, 0x4b7b0f38,
+ 0x15846b47, 0xe132e577, 0x1d0d7dcb, 0xe7c858da, 0xd23b25d9, 0xe676dde1,
+ 0x6d3d0376, 0xb5b971d6, 0xd216e419, 0x29cc98e5, 0x50ca3e2f, 0xc71e38ae,
+ 0x509c1ef1, 0xdcfd879a, 0x8b48aa3f, 0x9efa1ef5, 0x1f7888b1, 0x8f0cddde,
+ 0xbf5f0059, 0x7844b6f4, 0xfd634978, 0xae59ea19, 0x0be93223, 0x2a985abd,
+ 0x727bdff4, 0x7b05db88, 0x626f78bb, 0xc5b7f214, 0xb8546b3a, 0x0ceb5f1f,
+ 0xbb9d6be0, 0x97f68f6f, 0x9ee19d77, 0xbe433eef, 0x4be705f4, 0x5e6733b0,
+ 0x8e65be40, 0x76fee1b6, 0xf404bb09, 0xcf9460c9, 0x47417a95, 0xdf3057c0,
+ 0x14e6c419, 0xd5f73e42, 0x1748b1d8, 0x7caa1e38, 0x7949df0a, 0x5f84b9f5,
+ 0x6de37d5b, 0xecffccf7, 0x725fc805, 0x903a5c6b, 0xa7989753, 0x575c4deb,
+ 0xfa86d99d, 0x0da49a63, 0xea784a5a, 0x934c3a26, 0xc0a5daac, 0xfabc7657,
+ 0x303fc0e2, 0x1b181bd4, 0xdadfdf05, 0xe77c4c14, 0xd4ed9d2d, 0x22ff6c52,
+ 0x53caff6f, 0x09b2fcbf, 0x462b27d3, 0x3ef112fc, 0x5ae09c3e, 0x21d2fbfc,
+ 0x63436788, 0xbfa01b61, 0x5e486f5d, 0x99631653, 0xc4560735, 0x6d867cc0,
+ 0x840cd0e9, 0xb49d7874, 0x21a1d312, 0xf8658705, 0x95bc5efe, 0x21b231e6,
+ 0x72458e5e, 0xecfee819, 0xa87fa4a7, 0x9a8c92f5, 0x320763cb, 0x44327e9f,
+ 0x7dc05cf2, 0x62721959, 0xb63fc904, 0xdbd9fa91, 0x99e3f532, 0x7cd00eb4,
+ 0x7a45de70, 0xb70bc91b, 0xecf116ab, 0x46cd2392, 0xeba17afa, 0x4bdfdc79,
+ 0xca1b488e, 0x571a7d8f, 0xff589de8, 0xf9d69694, 0x50b1dd46, 0x35fbe41d,
+ 0xbe0998ea, 0x21ef0c57, 0xd83159b9, 0xc1dc70ca, 0x805bdd2f, 0xdc6ca9f0,
+ 0x38fd4b5b, 0xea09368d, 0xd2bdec95, 0x8d94728a, 0xc464b667, 0x7f9e46af,
+ 0x86dd9c62, 0xf6a4b572, 0x2b6f9e5b, 0x58217ca4, 0x3fac5a13, 0xcf69eb8f,
+ 0xdac53909, 0x117f88b3, 0xfb7d5aca, 0xc67c04f5, 0x5de39bef, 0x3ecc8b31,
+ 0xe97206f9, 0x8c59d202, 0x1b6fb79e, 0xe08e333b, 0x49728b72, 0x3d39e7e9,
+ 0x4e509973, 0xacfcb9ea, 0xf8817e07, 0x17fffd01, 0xd1c8aff6, 0x6cca5958,
+ 0x3ec77584, 0xb4adb067, 0xd338fade, 0x3921adfb, 0x5575e8aa, 0x89585f42,
+ 0x36fda055, 0x804e43b3, 0xb90be671, 0x0cd6b4cb, 0x319e43d4, 0xa409b5db,
+ 0xa3de81d7, 0x4c667921, 0x0658bd40, 0x4fd12f3d, 0xdf8733cf, 0x366b3c92,
+ 0xfdb143db, 0x2fefd6ad, 0x3157f9e6, 0x444b424f, 0x31c85748, 0xf23de03b,
+ 0xa127764e, 0xeb0357aa, 0xe790701b, 0x6dfa1213, 0x7aba055a, 0xfa958252,
+ 0x7c11f801, 0xca19e761, 0x243ca509, 0xb841e39b, 0x47fa48c3, 0xe1a2c454,
+ 0x9af0fc8b, 0x1123bd69, 0x5bffeb0e, 0xbfa84af6, 0x1bb33ffd, 0xbe7025f1,
+ 0x3fdc0945, 0xb9890bf1, 0x97578834, 0x45af54f5, 0x8febbed7, 0x34a5aed0,
+ 0xed7686c3, 0xd821e43e, 0xf49ea84f, 0xe61096a9, 0x99697a42, 0x7d46e91c,
+ 0xa7b42dec, 0x88661e90, 0x7c4626f6, 0x40c665ba, 0x0d0387e2, 0xf35c1800,
+ 0xaf6f034a, 0x2641f45b, 0x963cbff6, 0xc94ac7e4, 0xf48136bd, 0xcbe49935,
+ 0x6a8fc149, 0x6533bcc2, 0x9cb9af28, 0x939c70c2, 0x61569760, 0xa22092bd,
+ 0x7b309abb, 0x7dd7f20c, 0xdf132dff, 0x790e19ab, 0xf225f133, 0xb64cd4c7,
+ 0xfe4184c7, 0x351fb161, 0x67faeeb5, 0x69c9bfb1, 0x3281aeb4, 0xe2f5445b,
+ 0xe99f3f79, 0xfdc73b78, 0xdbd45ac1, 0x20c50241, 0x4e285efc, 0x2a07c866,
+ 0x44cec613, 0xf7ec52bc, 0x28df82e9, 0x630363fd, 0xfc63ea2e, 0xf5f98cdf,
+ 0x07aba426, 0x201d4c4b, 0x92c9d839, 0xbf682115, 0xbd90e83e, 0x1e5bd406,
+ 0xd35fb3c8, 0x7fb0120b, 0xb3c24cfb, 0xf27ec562, 0xbdb843ce, 0xeb6463dd,
+ 0x7d847f49, 0xdf1ebccd, 0x22633c2a, 0x52c7edfc, 0xf397a703, 0xd7482f38,
+ 0x714a3b07, 0xe34d55de, 0xcaedfc23, 0x8757f319, 0xf18bdd12, 0x23db562e,
+ 0x5ea1274e, 0x32a94050, 0xc14e329e, 0xea5da314, 0x818df68f, 0x4239aaf4,
+ 0x7832ad0f, 0x4dfd21a7, 0xa31e3937, 0x642eca71, 0x7fd8bea1, 0x9c3f5a4a,
+ 0x32fbf77f, 0x253d3c43, 0x3214f5f6, 0x45a7c46c, 0x4c2f8421, 0x8ebf1de4,
+ 0xf41cfd20, 0xc737c21a, 0xde5286ef, 0xccc7b7a1, 0x1c5cfc47, 0xca71f84c,
+ 0x729fbfc2, 0xcd7e1186, 0x87f95dfa, 0xaa7be00c, 0x78784f50, 0x3f2645aa,
+ 0xca96dfcf, 0xb9c03d5e, 0x67d5ca6b, 0xd75da053, 0x3772afb2, 0xe2beda43,
+ 0x3f9438f3, 0x4c5456b3, 0xcab376c2, 0xfc8fdd96, 0x3d7446f9, 0x441069cb,
+ 0x35b6e1cc, 0xd711bec1, 0xd5ca7fd9, 0x03cbe47c, 0xcfcf9dcb, 0x0983f287,
+ 0xcf88678e, 0x112bdbe8, 0x7d6f951e, 0x73fa8711, 0x7b2bf377, 0x6dfd215a,
+ 0xfa79e388, 0xf8dee2be, 0xb099d8d5, 0xb0b52abf, 0xb73f805f, 0xc45e3a27,
+ 0xbce355ef, 0xa2eed829, 0xe11f2dae, 0x9add96c6, 0xa5a17dde, 0x76849f7e,
+ 0x254b5060, 0x0b3bb2a5, 0x7929d1e7, 0x8444a543, 0xb00be823, 0x6f168bee,
+ 0xb9e21868, 0xb7cbc3d0, 0x5347d7ab, 0x077e148b, 0x91ee5768, 0xb3d226ed,
+ 0x6f9c7add, 0x2872fd60, 0x58b77aa7, 0xbc3cc65e, 0xa9e9ac3c, 0x7b7ef8bb,
+ 0x179fb0bd, 0xc56f2476, 0xf7b4befd, 0x3b7f1495, 0x7ebd3038, 0x17fd7cbe,
+ 0x8e00bf11, 0x8744a117, 0x5060d5f8, 0x3b5d7fd9, 0xd5f85462, 0xbdd523b5,
+ 0x762f8fde, 0x6cc1be09, 0x88c9dc9e, 0x2e4f76f7, 0x9f0a55ea, 0x164f4660,
+ 0x9e696fd9, 0x1457b42c, 0x3d0ac33e, 0xf6ee5429, 0x7dfd60a4, 0x7d9acf68,
+ 0x8aed96e3, 0xfdcf5dad, 0x364d2e8e, 0xc56e87e6, 0xcdefd2bc, 0x59ba97d6,
+ 0xbba7caaf, 0x09d3f9d5, 0x73b69fdc, 0x83b15ea7, 0x30476165, 0x568fb2ab,
+ 0x5c11afae, 0xe057aafe, 0x2e6c68f2, 0xafe00dfa, 0xe7379a04, 0xddb93be3,
+ 0x23b86fbc, 0x62a9f916, 0x830bef9f, 0x51ca067c, 0xaf256f3e, 0xde7021c0,
+ 0x20bafe2b, 0x967bfd16, 0x4e508d44, 0x3f88516c, 0x2f9c4d2b, 0xbe81d4ad,
+ 0x4976819a, 0x5ad3c8c9, 0xd16c57b4, 0x1c1f5ac5, 0x6e1e6c16, 0xb85d3a44,
+ 0x1fd1b865, 0x1f6e561f, 0xf30ad879, 0x6b5db8bc, 0xd4af29c3, 0x7d429fba,
+ 0xd976e56c, 0xddf462e3, 0x17fa8768, 0x628f07cd, 0xb85b05bd, 0xbf69429f,
+ 0x744e7370, 0x873cdfb1, 0x33c3576e, 0x0fcea3d3, 0x07e7526b, 0xf391aea2,
+ 0xdc376f3f, 0x3c8fceab, 0xfd9fceac, 0x10d3a3cb, 0xd7644aed, 0x87ea3253,
+ 0x461fe79f, 0xdf6e71b9, 0xdfe4a11b, 0x15b8a2f9, 0x9b85def5, 0x7d8670d5,
+ 0x701f5093, 0x2e48936d, 0xe903ba96, 0x65ba6fa3, 0xd7e2b96c, 0x93c7f34b,
+ 0xd56ae632, 0xbf5f5fc6, 0xd9a67993, 0x74b48fd1, 0x23d3c8f1, 0xe1defd7d,
+ 0x7b47a4d9, 0x1bdc7027, 0xdb3329d1, 0x165f68ad, 0xeedfe28d, 0x7d963a5c,
+ 0x6d882205, 0xf88f9638, 0x4484f457, 0xf5e8b6f2, 0x2f9177d4, 0x3199ec77,
+ 0x0569d281, 0xcfc50f04, 0xf245b0b2, 0x32de4086, 0xfcede38a, 0xc19b92cd,
+ 0x32aee7bc, 0xc541fca8, 0x58f3d41b, 0xbefea350, 0xdfc0e9b0, 0xc4bfe825,
+ 0xe51e92f8, 0x4316c956, 0xfdcb1f80, 0x65e1ea0e, 0xd9d918e7, 0x183f7565,
+ 0xcd73f2fa, 0xbae1d657, 0xb8fae19b, 0x07d3e78a, 0xf806634f, 0x857efef8,
+ 0xfea11233, 0x32b5359d, 0x3982adc2, 0x9224b31e, 0x860de99d, 0x7d002c79,
+ 0x9069f509, 0x2baeb4b7, 0x0db9fb9b, 0x4cce54f1, 0xb5857e50, 0xbe1ca2e5,
+ 0xe36218d2, 0x5cb6b0fe, 0x4217e40b, 0xc256e11e, 0x9c7c1236, 0x8e657fc8,
+ 0xf9bf762f, 0xe7f93ee2, 0x8fae46d9, 0x03deb53b, 0xd6728708, 0xff70ed4e,
+ 0x6139ebfc, 0x51c3275d, 0xcf6808df, 0xaf0fe46c, 0xdf69eb32, 0x307e9aaa,
+ 0xec577ff8, 0x512ec500, 0x59ff6dfc, 0xe21070f6, 0xfec96af5, 0xd4c651bc,
+ 0xf115a7bd, 0x724cd4b8, 0xce5ae1fe, 0xd9d06bcf, 0x6cd7fd02, 0xf37d274a,
+ 0x829ec961, 0x4c9b65eb, 0x1e810764, 0xdb3abf18, 0x3e81d7a7, 0x9fa132e8,
+ 0xbdc834b8, 0xe70fbf15, 0x8ccd79f6, 0xde17d214, 0xe45e3c92, 0x3867aec3,
+ 0xe64cd4bd, 0x64f353f8, 0x0cff7d0c, 0xfa831aa7, 0x6a4bd722, 0x3d72a536,
+ 0x60f3e656, 0xfe210bbf, 0xe62f1358, 0xf34ac035, 0xc9f5f452, 0x8973c716,
+ 0x5e2ceb7e, 0xf4247a01, 0x995bfc5f, 0x95829fa1, 0x3c92dc44, 0xaa7217af,
+ 0x8dc99367, 0x52d3eefe, 0x3f9e2b61, 0x13dfb35c, 0x1dcfdf39, 0xea26df6b,
+ 0x58bc5f91, 0x4ffd7933, 0x3567bc71, 0x7ef195d6, 0x53dbb7f0, 0xbd3fcf50,
+ 0xf70234c9, 0xce70d4e9, 0x72c773b7, 0x25d801bf, 0xee90adf6, 0xfca8d449,
+ 0xb9127bab, 0xd13fb09d, 0x3ce9e94a, 0xc90c47ee, 0x0cff242e, 0xf1f115ec,
+ 0x17ec75c0, 0x85f58aed, 0xc7d27e47, 0xb0f8147c, 0x4e7f7c71, 0x5c91223f,
+ 0x58a4f584, 0x7bfb9f20, 0x4e75f913, 0xeca2f90b, 0x0e51e00b, 0xbfc15bc9,
+ 0x49fc459e, 0x27f014c4, 0x51fc2fbb, 0x60c3c7e3, 0x7f1098ef, 0x1f683f00,
+ 0x327afc15, 0xf011f693, 0xe7a1f087, 0xf00dd349, 0x285f6d47, 0xe5a9adeb,
+ 0x5da047f6, 0x3270f801, 0xa0bcefd1, 0x0427ac26, 0x3c14b7cf, 0x8e775a60,
+ 0x205a39ff, 0xe6c9e41e, 0x4befe434, 0xea1b20a4, 0x7f844bdd, 0x467cc97b,
+ 0x8b658df3, 0x68d7a424, 0x0ec895e6, 0xec266d66, 0x003d27ef, 0xfc3a3f73,
+ 0xf32355e9, 0x58637b97, 0x8f7f2a98, 0x3f554631, 0xfaaf12cf, 0xba746f7e,
+ 0xeb78fbea, 0x627e5570, 0xfaaa1dda, 0xa8c6d9f7, 0x351b3ff2, 0xb27f555e,
+ 0x6f2ab27d, 0xce2d1667, 0x60baa5bf, 0x6f1fda24, 0x5e921757, 0xd1970810,
+ 0x5baf8386, 0xea46206d, 0x00b453b4, 0x0efdd1bf, 0x7c87892e, 0x14d33aff,
+ 0xe8c7e02d, 0xe25783d8, 0xd5a2602d, 0x43eff105, 0x80495e0f, 0x305d747c,
+ 0xc8c5dfcf, 0x67581f1e, 0x9332e29e, 0x093630bf, 0xeaed3ce0, 0xf66843a2,
+ 0xca7cb27d, 0x75a478fc, 0x3ff33267, 0x7566d8b7, 0xe53d6184, 0x547f52bb,
+ 0xefb52152, 0xfcf9ccbe, 0x393fb827, 0x760a7aff, 0xb18fc917, 0xac6c341c,
+ 0x5be74cd1, 0x78bba8cc, 0x7c0cafcd, 0x8633b253, 0x6a96b9fe, 0xc22d67d8,
+ 0xb7a948cb, 0xc1e942da, 0xdf4a68ea, 0x62b2b6ad, 0x756b6780, 0xab87a51a,
+ 0xa47e546d, 0x1fa5147a, 0x3d29db56, 0x69405d5a, 0xa521755b, 0xb34f2812,
+ 0xb36c6f90, 0x3c21d5ad, 0x33b0da5c, 0xd9fe3e30, 0xe1f2df17, 0x519d96ad,
+ 0xff2a15f6, 0x4dcf64ca, 0xb20d75a2, 0x945b9f90, 0xa9ffda1f, 0xe8d1f915,
+ 0xf5e1236c, 0xd59b7368, 0x48f3cd98, 0x99977567, 0xebca1357, 0xf5ebfd69,
+ 0xfe470cf7, 0xa669da30, 0x50bd497a, 0xbdeb0b2f, 0xf2c5a317, 0xca1b7a45,
+ 0x3f04e7cb, 0x901cd10e, 0x5e909c71, 0xc834367e, 0x144ef9c0, 0x5df85fa8,
+ 0xf5d5a3f1, 0x8706f1f2, 0x9df3a22f, 0xc4cdb3c1, 0x15b9147f, 0xc18de11b,
+ 0xd12ec5f9, 0xe6887953, 0x2efd15b8, 0x09ded55d, 0x84e3af88, 0x67a71f9c,
+ 0xa60f3869, 0x94f92209, 0x1adf7f27, 0xcdc5f90b, 0x398c70d2, 0xdc286718,
+ 0x96a1f642, 0x6feb31d3, 0xb6b8fae2, 0xa815f4ad, 0xd6323c77, 0x15a11eb6,
+ 0x81258fbd, 0x5557959e, 0xf2728190, 0xf448db38, 0x31d43f3d, 0x6a6df10f,
+ 0x46bdd006, 0x13f40920, 0xfc4c105d, 0x6a7f7bb3, 0x53cdea0e, 0x0cbdd60c,
+ 0x292ca2e8, 0x4a7ef087, 0x648e6b3f, 0x445dfcc1, 0xaca25327, 0x9e1b257b,
+ 0x194ce49e, 0x71bfc777, 0xd2493d2e, 0x7ca9c7fa, 0xc31e3922, 0x5c1455f9,
+ 0xf5f9f3d2, 0xebf89e90, 0xb3f12b24, 0xc9190701, 0x21f19edf, 0x7fd15fc4,
+ 0x61f918b5, 0xeb073586, 0x427ae9c5, 0xfba0ee31, 0x5dc52d7b, 0x07d0cd40,
+ 0x2f1efcfc, 0x8c78f0b5, 0x9a1bbc40, 0x554de5cc, 0xaa038f12, 0x291a368c,
+ 0xcf9cb96d, 0x30a24e28, 0xd036ed09, 0x5794fb1e, 0xdcb99383, 0xe7a35f8b,
+ 0x49643afe, 0x107b6530, 0x8c2ef253, 0x2c7da907, 0xecee5148, 0xc7a64e00,
+ 0xe87f9476, 0x5492e3f7, 0xdf58edf5, 0x11d99df7, 0x9dfb4a9c, 0xbf7e9375,
+ 0x43c62b4a, 0xdcc0597c, 0x7e4084b8, 0xb87245fe, 0xfb411e72, 0x137f62fc,
+ 0x324993d9, 0x71e037e0, 0xfc87b06c, 0x8e26757f, 0x9e1a49ef, 0x77f869d6,
+ 0x93e8107d, 0x790c1f90, 0x3efa773c, 0x1e49e1d9, 0x0599ed40, 0xa87bcbdb,
+ 0xd0f30c7d, 0x28f7ca78, 0x9d435ef4, 0x304f2041, 0xfa6b2d1d, 0xe498db84,
+ 0x7d211f31, 0xf91f0177, 0x775f8fda, 0xf52e8705, 0x6c4aa7df, 0x376ff66f,
+ 0xed29da96, 0xd86a962b, 0xffc411d7, 0x922a5f08, 0xb7377634, 0x5095df37,
+ 0x7a6d604f, 0xbb4a6b94, 0xbeefc013, 0x05ff7806, 0x27a61ff8, 0xf8e1ef81,
+ 0xc3df019f, 0xf7c06ff4, 0xf014fcb0, 0x81db4c3d, 0x97f961ef, 0x9d30f7c0,
+ 0x1b243336, 0x69aaa4e9, 0x855afb0c, 0xff873af7, 0x3189ddf9, 0xd9cbe37d,
+ 0x9ed76e24, 0xfbfbef88, 0x7c71277f, 0xdf37713a, 0xd7906eb7, 0xfe019fa8,
+ 0xdf84b2ad, 0x87776e58, 0xef9e73f0, 0xd77eb8d2, 0x5ff3c31d, 0x3fa8e926,
+ 0xc66d86bb, 0xe9a5dff6, 0xe649ef29, 0xf85ba372, 0xa8ff012f, 0xc31e657f,
+ 0x7aaa4a86, 0x814d24ee, 0xdef98fbb, 0x23c7cc9d, 0x1c3d44fc, 0x0fde31f1,
+ 0x84ad2b3f, 0xf178819f, 0x249ba085, 0x58bbc703, 0x27c8f1e4, 0xbe744ca3,
+ 0xe3b5f30a, 0xc49d7479, 0xfc3af1f1, 0xe77b70d4, 0x7e84fc3a, 0xe7804e08,
+ 0x093fa412, 0x35251fc0, 0x45b77988, 0xe082fc86, 0xa0b3a2dc, 0x3227efff,
+ 0x6bdb1600, 0x84ce8f7a, 0x10c8d8f2, 0xe41d9e2b, 0xd45e6e3d, 0xebb8ff17,
+ 0x35ff5ddf, 0xffaf547a, 0x738b75ba, 0x375d5b93, 0x97e413f1, 0xf07d3f88,
+ 0x1fc82187, 0x33f87c72, 0x849ed926, 0x264b74fd, 0xbb81fa2d, 0x022f1c4d,
+ 0x1a5dfbd7, 0x3f055fc7, 0x18fc40be, 0xbac3fd80, 0xb9eb7d12, 0x80a0ff36,
+ 0x14642df5, 0x8fb8110f, 0x5bf15f0a, 0x39c91dd7, 0x2601b83e, 0x041efc92,
+ 0x71fd1bf2, 0xc70b649e, 0x676701f3, 0x81f9426f, 0xffea0272, 0xfafdc341,
+ 0x56bedf0a, 0x2673c92e, 0x39f8a867, 0x67b07b43, 0xcbe881bf, 0xaf2561ab,
+ 0x43825da1, 0x8f59d9f9, 0xf6f5f325, 0xa0d64f4e, 0x9df5d4de, 0x27f145d9,
+ 0xa14e7b03, 0x59b5d67d, 0x6d3db8c7, 0x3c81249f, 0x057e8f9b, 0x8dc5fa2b,
+ 0xa17b6e74, 0xd43d991a, 0x853e5cf3, 0xf3d56176, 0xe8023332, 0x9dbfe7e4,
+ 0x60b2f886, 0x7a82cebf, 0x4fcdcac7, 0x3b7c461f, 0x515928d3, 0xc23577de,
+ 0x457ea1b2, 0x04db884d, 0x8f21f3f5, 0xf59a17f5, 0x8f1f2b6e, 0x18a74cf4,
+ 0x65536bef, 0xefa5fa02, 0x70475e79, 0xc783b05e, 0x79b3bc31, 0x9f639d09,
+ 0x0a2c4b71, 0xcbcbe5da, 0x9fd0635a, 0x3364a2f8, 0x39a73b40, 0xefda3cff,
+ 0xcd983b65, 0x3d8afe8b, 0xb2be7421, 0x7f1d46a0, 0xa4dee250, 0x64a27d47,
+ 0xacbcba8b, 0x9d879d4e, 0x6ceb7e21, 0x3c33c750, 0x15e22c92, 0xf270d9d2,
+ 0x9384d633, 0xd3f0a01e, 0xf631d91b, 0x324f9cc5, 0xfa244df6, 0xdffde549,
+ 0xe6697dc6, 0xdf22c9f9, 0xdf4bf901, 0xe0517df2, 0xbf9ca952, 0x4f6cb0c7,
+ 0x99dfc636, 0x55c7682c, 0xca157f36, 0xa82cee30, 0xcfa27efd, 0x538a6537,
+ 0xbb24d75a, 0x2d15be10, 0x3e3197a6, 0x31ef72af, 0xe10435bd, 0x01e908fe,
+ 0x1ad732f7, 0x1abcbfb4, 0x3c236b0d, 0x15ff236a, 0x202cf7b3, 0xc9b370bf,
+ 0x6f3de742, 0x133ada7e, 0x66257bf3, 0xdc1c7dc2, 0xe0b2784e, 0x75ce9979,
+ 0xb93e6a19, 0x71913c3e, 0x3d9f715f, 0x16bf68fd, 0x3ee3bee2, 0x3ee3bec3,
+ 0xd89fb8cb, 0xe6ef443e, 0xccedc278, 0xfef9db33, 0x2f9efb2a, 0xdf93d06f,
+ 0xf3ef96b8, 0x3fd7cf3d, 0xa078441b, 0x680f0263, 0xe16ccfdf, 0xbfdfaefb,
+ 0xf1103f5a, 0x0f0036b7, 0xf0d70d9a, 0x1d77e700, 0x7fec041e, 0x07cbf0a9,
+ 0xfee041e2, 0x44f82bdf, 0x10fa3c9e, 0xfe2cd9c6, 0xf1571f05, 0xef0ecd73,
+ 0xaa0478ac, 0x11ff1a9c, 0x392cdd9a, 0x049635fa, 0xb421bd72, 0xc0f909b0,
+ 0x86bb09f1, 0xfc099c53, 0x9c524633, 0xddefc11b, 0x053dfd5f, 0x7e3bbfe9,
+ 0xe23796f2, 0x703aff69, 0xc161dd1d, 0x96ee7e5c, 0x1b9512dc, 0x538006bc,
+ 0xa451f01e, 0x81b6f643, 0x07ba91ce, 0x31e8f43c, 0x693f77c8, 0x48f6e1b6,
+ 0x951f6e76, 0x1277bcb7, 0x31ac86fd, 0x9fb2aecf, 0x8e537d84, 0x6f7e15f6,
+ 0xefcafb00, 0x7cb24e3c, 0x4f3eed44, 0xcaf5a04e, 0xb266db1a, 0x9598ea83,
+ 0xe3af63ce, 0xbdf88cf7, 0xa1ba07e2, 0xf7c0163e, 0xeb9efc7d, 0x2835cc61,
+ 0xb14be90c, 0xb47e14b3, 0x0f4bf850, 0x1b44763d, 0x03aceb81, 0xb5bee3b8,
+ 0x8fea1f00, 0xdb9d3d7e, 0x8dd1f92a, 0xf1167fa8, 0xce78e00a, 0x469f68b5,
+ 0xd332fc46, 0x0f029d7c, 0x605f112b, 0x07d9659d, 0x775f5142, 0x6ce1fe0a,
+ 0x497f210e, 0x8f98db19, 0xe30655f8, 0x9bc0fb79, 0x487bedb2, 0xde19bfcf,
+ 0x655bfa28, 0x3fdebaa3, 0x250c9f90, 0x03f9927e, 0xfc69dfe0, 0x37c7c73b,
+ 0x7e8ce4f2, 0xcbdc0718, 0x6e90fdac, 0x52d7246f, 0xfb290337, 0x36ee9bf5,
+ 0xcfcaad32, 0x33e5516f, 0xfaaad13d, 0xaaac9ac3, 0x69bdc3ef, 0x0f23efaa,
+ 0x9cf954db, 0xfaaa51b6, 0xabb49fb7, 0x17b477f2, 0x75dfeaa8, 0xef9550ae,
+ 0xfcf580cd, 0xbdd739c8, 0xfeaa92d1, 0xd549ab78, 0x042a683f, 0x6169899f,
+ 0x335ef2aa, 0xfa8dd387, 0xeea6cfbd, 0x7f6fb157, 0xffdd4a36, 0xdfbabb64,
+ 0x6d87dd5b, 0xa0b52720, 0xb9076f6f, 0xd04ee989, 0x6fa0b5cb, 0x8e5e8037,
+ 0x2f4157f9, 0x7a03d4c7, 0x06bf9639, 0x1be6397a, 0xfcc72f41, 0x3023b03e,
+ 0x405d54df, 0x85d59be9, 0x78337e54, 0x0f718ab5, 0x888f718b, 0xc4db1971,
+ 0xe04dfee5, 0x7f68a1f2, 0xc36fb454, 0x3c3e49f6, 0xd64828ac, 0x1d3a055c,
+ 0x8f5e7e13, 0xc5f65ae7, 0xd768f9ed, 0xb32fbcf7, 0xcc2740ad, 0xdd5c3ee1,
+ 0x0452e51f, 0xec2faf3f, 0x0efd00f9, 0x2d137b95, 0xaeb06e78, 0xf8a3e3e9,
+ 0xb651abbd, 0x6c1ddd22, 0xfb142afa, 0x141578b9, 0x9e4291bc, 0x77f9de41,
+ 0xf0f5f946, 0xc7d5e31d, 0x964501ef, 0xe48794e4, 0x2524c5d4, 0x0e7ba6ef,
+ 0xf47b0d85, 0xb6fe74ed, 0xefbfbe87, 0x6fbfa9d1, 0xb77d55af, 0xf73c7d60,
+ 0xcec9bad5, 0xf4a4d0be, 0xcefaa5e7, 0xfa8ec924, 0xefed85f1, 0xb738c1ac,
+ 0x11453d8a, 0xde567e78, 0xde722c70, 0xd2ffc08f, 0xc8195dbe, 0xa19a2bd7,
+ 0xbfafb33f, 0xc89d668a, 0x933bf9f3, 0x2387e4f6, 0x18906edf, 0x6c8b928a,
+ 0x950dc523, 0x913bd537, 0xcda7952f, 0x4e39e1d4, 0xf61647b7, 0x73c38f3f,
+ 0xc7d7185a, 0xe742573c, 0xf27fbf41, 0xe31fba1c, 0xde5bba69, 0xbb71c509,
+ 0xdf869ef1, 0xc2913efe, 0x5227daf5, 0x8b87bdf8, 0x6284ef8d, 0xcf3ac5fc,
+ 0x5aee1c3b, 0xa0ffad2f, 0x4a4377c8, 0x69926ef0, 0x3557a5fd, 0x7f4a0fb4,
+ 0xd4c8a6cf, 0xe4a6f8cf, 0x71d75c10, 0x8dcf1f0f, 0xce3005c1, 0x62a2a4f8,
+ 0xe891ff9c, 0xe9323919, 0xdc6fdc75, 0x3d62643d, 0x8e7813ea, 0xf5dd97de,
+ 0x55b7e89a, 0x9fbdf7c4, 0xf22b7af4, 0x110523db, 0x880649c3, 0xb8533b7a,
+ 0x77af919d, 0x389ca124, 0x1f92b66e, 0x62414579, 0x41efee08, 0xe0bcb14c,
+ 0x97cbf265, 0x8ef1f235, 0x1142da5b, 0x8e378eef, 0x516f5194, 0x71c3abfa,
+ 0x6facf8fd, 0x4fb45cdf, 0x335aee25, 0x3fdbe3f6, 0xb14eee5e, 0xee23bb50,
+ 0x3f50d363, 0x4c169e3a, 0x9eab45fa, 0x37977b9f, 0x78f6fd70, 0xecad6c4b,
+ 0x16e15e77, 0xa69dd1fb, 0x6aed7da1, 0x337a89d2, 0x9eaa99eb, 0x9d57ef8e,
+ 0x77163e7a, 0x57a853c7, 0xe9945f3b, 0xb7538eee, 0x7fd71228, 0x7e7a8b76,
+ 0x4ece0225, 0xd232379d, 0xcd9d5f0f, 0x4cc6e8d7, 0xd0acde78, 0x53f69589,
+ 0x69e3c7d9, 0x1e3b2f5c, 0x390befcd, 0x5e13d4f7, 0x5b7de4fb, 0xb11dea3c,
+ 0x4ee3c1ff, 0x2ad7666f, 0x5d9f80fa, 0xd3aed0c4, 0x68e62415, 0x3f727c12,
+ 0x79fec52b, 0x97b400ca, 0x040ec90a, 0x3f210f64, 0xfdc3ea08, 0xedfeff90,
+ 0xb7b71c59, 0xd440f411, 0x134d8c83, 0xaf4afef0, 0xe604080d, 0xe745bbdb,
+ 0x198bf616, 0x4205d2f5, 0x756b3d2f, 0xbe78cae4, 0xeb435cb8, 0x81dd8272,
+ 0x825d8a71, 0x13da5ddf, 0x07d233ff, 0xb416cb0e, 0x70f1ee67, 0xc0d9d63d,
+ 0x4f4ad2f5, 0xa346effc, 0xb3a0ddde, 0x535a0559, 0x2fd0ac5c, 0xf5bd08ce,
+ 0x3d1ef2cc, 0x25fb27d9, 0x5ff434f6, 0xce89b4d2, 0x7e842bab, 0x90372151,
+ 0xb370b09e, 0xbd002f5a, 0xdf2f9545, 0x0837a81e, 0x5d47907f, 0x7277d8ae,
+ 0x21fd35ea, 0xd011ed1d, 0x0e90a34b, 0xdcad53a2, 0x93ec266f, 0x28b69925,
+ 0x5a75f7a4, 0x4fc504eb, 0xdaaaf080, 0xce297aff, 0xb20ceddb, 0xf4b0bd91,
+ 0xf76b824d, 0xe90edc37, 0x8f04668e, 0xdbe1c66e, 0xbbf1c4dd, 0x8db9274a,
+ 0x95d01ed8, 0xee4a33fa, 0xba87a8e5, 0x2f89437a, 0xf4805631, 0xb70678b0,
+ 0x0be8ed37, 0x850bf485, 0x29f9140e, 0x5bbfba71, 0xf9872edb, 0x54e487f1,
+ 0x138e77ae, 0x424b3b71, 0x06bf246c, 0x9d9eb91a, 0x8e19e257, 0xec1030f8,
+ 0x9f9f8368, 0x2dd9a07a, 0x52babd61, 0xe45717ee, 0x45ad64f3, 0x7e2bfd87,
+ 0x4cfce522, 0xb7895fe9, 0x16ff69bf, 0xebecdfe8, 0x0fdde01f, 0xdb257de1,
+ 0x6e39f246, 0x6d2f72b2, 0xb2a3d111, 0x6f808b9e, 0x1f451fe8, 0x739bee0a,
+ 0x7e7c81cb, 0xf746ddfe, 0xf943f2cc, 0x5c45f23c, 0x4f107e73, 0xbf72a4c7,
+ 0x0e54cacc, 0x2a9166b7, 0x549beb7c, 0xc854d8fb, 0xf23aa7b7, 0x42dca953,
+ 0xdae4b9f8, 0xa88c807d, 0xeef83ef6, 0xbdf88fe2, 0x0f402bbb, 0xbe7e7fc8,
+ 0xa926b248, 0xe78e22f4, 0xe308bc55, 0x468c4e1f, 0x6decb838, 0xce789169,
+ 0xce6be9ce, 0xc9359352, 0xec2e4fdf, 0xc4db0c2f, 0xd1529c73, 0x4a52c4be,
+ 0x4b1c15f7, 0xd7e8ad23, 0x487a42af, 0x07fe39b8, 0xdbfc3de2, 0xc956f882,
+ 0xde7e360c, 0xa6ddf81e, 0x417b3d45, 0x09c45d00, 0x4875ad3c, 0xfb598e74,
+ 0xb9fb96bd, 0xd7e44966, 0x790a107a, 0x57a8b7bc, 0xa3e28632, 0x9d2c841e,
+ 0x17f4d503, 0xe9fdafe7, 0xb101ea7c, 0xdc4507fe, 0x279d21c0, 0x8730fd1e,
+ 0xcdf9f82a, 0x73a1e60c, 0x8dac59e2, 0x95c113d2, 0xb9d4bd7b, 0xd1da306b,
+ 0xe40c3a9f, 0xb55da9ff, 0x6bf90435, 0xc1655b16, 0x93202373, 0xbc8c3fed,
+ 0x78119eb1, 0xbdc4a4be, 0x9edcfb2a, 0xf11ab85a, 0x51ec1ce0, 0xdbeb88f4,
+ 0x97b27f97, 0x1f3a69e2, 0x43da7d7d, 0x1e9bed0c, 0x5b28778a, 0xee9a3c34,
+ 0x5b58b855, 0x7f6fae5a, 0xf654fd95, 0xaaacca0f, 0x0cb5857d, 0x674cf802,
+ 0xe95eb93d, 0xc0a9fbe6, 0x33d74e39, 0xf2094115, 0xe050f88b, 0xaf702b3e,
+ 0x3dc48b64, 0x674745a0, 0x5787fd40, 0x4fa8ac69, 0x37efb75e, 0x89af1fd9,
+ 0x4886f27f, 0x68dea764, 0xfa7d94bf, 0x742fb8b9, 0x3bb78c32, 0xfc9973f9,
+ 0xfbdbff7d, 0x63aa4df5, 0x3bc92a7f, 0x1b749f4b, 0xa237a748, 0x034b39cb,
+ 0x4e8037e8, 0x0da5d1af, 0x3fdbf3fe, 0xa250d2c7, 0x9d7f6547, 0x517fb056,
+ 0xd884b5fe, 0xfdfaecdc, 0xe7163b44, 0xb128d653, 0xa15ba417, 0x7bb276d7,
+ 0x700bf703, 0xe0f28ec5, 0x553a00f3, 0x7c46f1f6, 0x277be14b, 0xbb9e5cf4,
+ 0xfce9931e, 0x7bc90bf0, 0x2c7c82c8, 0xd7dd38fd, 0xb17fea52, 0x23f06dbc,
+ 0x6317cfd0, 0xcf427a78, 0xbc94f9e3, 0xe5fb883d, 0xb83188be, 0x485ffd70,
+ 0x9e5163e9, 0xc7fd217f, 0xa51f3cfd, 0x467e62b7, 0xe40b58d4, 0x3f14e84f,
+ 0x87c10ade, 0x3c7fdcdd, 0x5471f6e3, 0x32ef624f, 0x2ff5bf7f, 0xcf5bf225,
+ 0xf38e9601, 0x5cfb1f8b, 0x9f940241, 0x70e255fa, 0xac5b5f3a, 0x62e50fee,
+ 0xb8fff93c, 0xd5f776dd, 0x86515d1e, 0xf26b9c6f, 0x5e65dc6c, 0xf64c9c5e,
+ 0xad808941, 0xdb9d3c3d, 0xcf7e6ea9, 0xbd379150, 0xfb375f87, 0x0bcf27fb,
+ 0x7cb5ee7f, 0xfe7193fa, 0xb6c0eaf2, 0x9fb05227, 0x0b2bbd12, 0xab9f1bef,
+ 0xca1c43fd, 0x8f6d92f5, 0xb99e90a7, 0xda0a5d6d, 0x9f5b250b, 0x3e53b148,
+ 0x8af641d8, 0x73bbaf96, 0xaf2f1df7, 0xeb6bd3f7, 0x3f9eb9d3, 0x0f2078cb,
+ 0x4309cdf5, 0x3f46ad2f, 0x24aff278, 0xd6f44c8b, 0xe0e51ab6, 0xef8e34ec,
+ 0x7c48c6ac, 0xa2fde199, 0xbefed8fe, 0x47c7e43a, 0x15d2bed2, 0x34ecbd43,
+ 0x3663c12d, 0x82886f73, 0x64ad6cef, 0xf5fe67a9, 0x6139d307, 0x1f492ad1,
+ 0x5be51fdd, 0xe3b470d8, 0x68c2d3b2, 0x0ed7731e, 0xd9f2c56f, 0x04f978cb,
+ 0x38f1bb83, 0x9e9cf3f6, 0x804067e2, 0x9bc7f825, 0x3b71a767, 0x8906ce6a,
+ 0x9c656bf4, 0x6b2367e4, 0x9d99d7fd, 0x39f3e426, 0xe521f137, 0x65a4db1e,
+ 0x868ddec7, 0x1d6a0f7e, 0xf7c1a677, 0x499ccfa3, 0x2e333e42, 0xda067cfc,
+ 0xc77ac919, 0xeeb8a50b, 0xcb8a06ad, 0x958aceca, 0x88fea0a3, 0x8d3cc747,
+ 0x45659ce9, 0x3fa2942f, 0x3871b375, 0xf3e56f0f, 0x35592c5b, 0x53be3f68,
+ 0x845cd0fb, 0x8c67b9db, 0xae2f1fa4, 0x3f628d4d, 0x02bfef62, 0x614d6ffb,
+ 0xfbd8076c, 0x7b02ee98, 0xed4bef1f, 0xfca68eae, 0x94adab1f, 0xbf1ce9b2,
+ 0x1f385b16, 0x237f51b9, 0x02b78ec1, 0x0b5ec91f, 0x78fe81fd, 0x107f6f46,
+ 0xa43c99d7, 0xb13aeb62, 0x3f6864ae, 0x0f7f15dc, 0xdd7b21c2, 0x5aa8ad23,
+ 0xe7e3498e, 0x5f1c1f7a, 0xf1fa471b, 0x4a978eb2, 0xb486fbe1, 0xded8d9c2,
+ 0xd932e5b8, 0x3f34efef, 0x5de11b3e, 0xd7c0d5b2, 0xee7dd627, 0x17a89499,
+ 0xfbd77fa0, 0xaba7b23a, 0xb4bc74b6, 0x1b79d20e, 0xe3fbd11e, 0x77aeadfb,
+ 0xcdcf9896, 0x7046eae8, 0xd5d39ff8, 0x3f447113, 0x32ae815b, 0xaaba75fe,
+ 0xe09cb65a, 0xe15a5af7, 0x9fc834ea, 0x90e2b9d3, 0xffa5ce9e, 0xb5dcf084,
+ 0x2bf8225f, 0xbf6955fc, 0x9bdb8d32, 0x06cf1ae5, 0x7f04efd2, 0x3a2c16fd,
+ 0xe681ef84, 0xdfa829b3, 0xe334db7e, 0xafbdd747, 0xd233bf9a, 0x7ff5f004,
+ 0x734942c7, 0x1b448ef5, 0xc4572fac, 0xdf7e07dd, 0xce51a69d, 0xe05e48f1,
+ 0xae2fc93f, 0xd62602a2, 0x92e51c2f, 0x7b420de4, 0xf3dee9aa, 0x379450da,
+ 0xad52fb12, 0xfd2fb21f, 0xe68dede4, 0x12b4b37b, 0xf8fad1fb, 0x3527edee,
+ 0xee43f7aa, 0xbd520f68, 0x8ecd71c7, 0x9d3d3280, 0x2ad4c4a3, 0xbf18f6f1,
+ 0x4e9cd5d3, 0xc5e7fdf1, 0x7daea27d, 0x3f712f60, 0xdefd9309, 0xdcdf3835,
+ 0x367c8599, 0x6f95bd70, 0x387e1276, 0x4cbf1e9b, 0xf8d364f6, 0x9bacdaf3,
+ 0xb6c0ffaf, 0xe2677a4e, 0x173daebc, 0x7d2ea2ed, 0x43ee167b, 0x9f9c5be5,
+ 0xa0e14fff, 0xd5ae9794, 0x649dbf73, 0x4f2efb21, 0x79f648be, 0x9f6e61d7,
+ 0x4cbf3657, 0x85b7b4fc, 0x34aa47fb, 0xe851f96d, 0xd1d4584f, 0x37acfc8a,
+ 0x954bdb9a, 0xe8ff9ee2, 0xb5072144, 0xff78713d, 0x9f3892e0, 0x7c34ec55,
+ 0xb5e90037, 0x5271e34a, 0x305650dc, 0x0b8f73c3, 0x3e50cf48, 0x1afc697b,
+ 0xee73f3c4, 0x3f902301, 0x8ff5907e, 0xfda7f24a, 0x9322d829, 0xe2ab297e,
+ 0xc3adaf9a, 0x14c0f32d, 0xc1abe8a6, 0x2adef8aa, 0x6467f5bd, 0xe7e11eef,
+ 0x3843555e, 0x3937b13d, 0x3aac553d, 0xebf68fa0, 0x9e82afef, 0xc26f3d14,
+ 0x7441fe9f, 0xfb64cff9, 0xa33f217f, 0x5fd86ffb, 0x24b73f74, 0xbeb97a89,
+ 0x8b733e73, 0x640bafb0, 0x24d55efa, 0x62ef3c33, 0x1e7421d1, 0x5236c05f,
+ 0xe604e09c, 0xb17a4d19, 0x7c29fdb6, 0x9fe26587, 0x371891e4, 0x9d2e7a05,
+ 0x3907e71b, 0xe8ae3092, 0x70124684, 0xf64f64f5, 0xe9396793, 0x968d4e5c,
+ 0x3d639225, 0xa7a4c131, 0x315e9f8c, 0xfa7f5fcb, 0x4fedc487, 0x26f487e8,
+ 0xf7e1eee6, 0x593dbc40, 0x4c64effe, 0x22f053fb, 0x93cc8b92, 0x9c6fcd3d,
+ 0xa71e74fc, 0x9dcf0571, 0x89549f81, 0xf93ccdf3, 0x0ed167fb, 0x9f9fbc5a,
+ 0xc4d09deb, 0xc9714a7f, 0xc258af78, 0x1efcbbfb, 0xbb307337, 0x7327e91d,
+ 0xa95fdd00, 0x8c312dda, 0x366cab2f, 0x4d7f456c, 0x123daea5, 0xd35d79f1,
+ 0xe7c47a27, 0xccef3c2a, 0xb97ff7e4, 0xf742daff, 0x8c2cabb9, 0x534557e4,
+ 0x47e8a7ea, 0xa5cc38ab, 0x18f68568, 0xb7c8e9d9, 0xc6f2bc71, 0x3b97643d,
+ 0x72ec9799, 0x6f1a8367, 0xf6fba37a, 0x5ba7e7a3, 0x8c62ef55, 0x63e9ccdf,
+ 0x9ac3c61a, 0x43f939a9, 0xd54747c7, 0xc9bbdffa, 0xb5f0e74f, 0x51ab9dcb,
+ 0x904ee98f, 0x4a8ef86c, 0x156b9077, 0x14ae47ea, 0xbf74d7ae, 0x017b2bbd,
+ 0xf67717f1, 0x077c4cd4, 0xe3b1eb86, 0xcad26ed7, 0xdf19f37e, 0xdd7ffdc2,
+ 0x1f64ac41, 0x1063bbed, 0x29fdc7ee, 0x39e90585, 0xd1cc7ef4, 0x234fd0bb,
+ 0xae04e9ee, 0x9f0a68e3, 0xdff411cf, 0x3de6f864, 0xf3963631, 0x3c26e633,
+ 0x62f7156a, 0xa516f894, 0x578116fd, 0x8917ecd7, 0xc46e9dfb, 0x04bcf05f,
+ 0xbcf132e3, 0x229dd304, 0x4bcf137e, 0x88aaff30, 0x12f3c4df, 0x12f3c72c,
+ 0xf88a37cc, 0xc12f3c4d, 0x60979e3c, 0xdf88a6fa, 0xa553823c, 0x1ae6b3b8,
+ 0xa4568bc4, 0xfcbe81b5, 0xfc80f089, 0x13fd7540, 0x3f3a92e1, 0x8bfaa250,
+ 0x5c6b9bd2, 0xb4a7e819, 0xfdc57908, 0x1d83eb94, 0x2af840bf, 0x15cf0ef7,
+ 0xe90fbd3c, 0x8cf85c68, 0xbd5f4859, 0xf90c0dfd, 0xc774aed0, 0xf877ac32,
+ 0x9b493df0, 0xe89a3f88, 0xc3c4f8fc, 0x05f75543, 0x5c8da4c7, 0x31f90d95,
+ 0x6bdc4966, 0x50ac38de, 0x5cf0fbb1, 0x5b28a5bc, 0x0582f9cb, 0xd93ce4f5,
+ 0x2ce38c59, 0x448d318e, 0xd53c3bfe, 0x1fba78f1, 0xb81fcebf, 0xa1f50930,
+ 0x53f59d56, 0x3eba97f4, 0x9bb431d2, 0x529abf14, 0xe63a90cf, 0x3e376c19,
+ 0x08d5712d, 0x0c881fec, 0xcf5d9cf9, 0x767e701a, 0xdfc4b04d, 0x916ab08d,
+ 0xf6233c0f, 0xeb95ac7b, 0x55bd5ec5, 0x76768e1b, 0x78fe98d0, 0xf62ada7e,
+ 0xdfd8b0f7, 0xf17f6223, 0x969c69bc, 0x8a61379f, 0x2a984de7, 0xd2c75a71,
+ 0x274a5f0a, 0x21c4f6f8, 0xddbf157c, 0x1a3ee504, 0x9ea1c4f3, 0xd7c099f0,
+ 0x919f0407, 0x79eb0ad2, 0x2fdd0f3b, 0xb4fe172c, 0xa0be714e, 0xe76953ac,
+ 0x9dc7cf6b, 0x67f38c32, 0x13dc4fd6, 0x185cc41b, 0x8de53af7, 0x7507f218,
+ 0xce3df9b9, 0xc8db4029, 0xfc1bd8bf, 0x73459dfc, 0x7af2993a, 0x295bd514,
+ 0xe1159afc, 0x0718296d, 0x49e825df, 0x76f72bc9, 0xde40462b, 0xafab8bec,
+ 0x8296d298, 0x925df571, 0x54788349, 0x3f7f95b1, 0x22ade82e, 0xbca7f441,
+ 0xc4f46087, 0xef743ee1, 0xef0e237f, 0x7b37ad89, 0xef7e7017, 0x98f2f7e5,
+ 0x84e30537, 0x29cf253a, 0xdfad878c, 0x8c41f939, 0x79d4ed87, 0x8efcc25e,
+ 0xc41f539d, 0x694ed878, 0xff8b29cf, 0x389e01f7, 0xdfad978c, 0xf7e44539,
+ 0xf36614bc, 0x3b5eebcb, 0x2bf5df85, 0xf1883ea6, 0xee0d13b3, 0x2f88d5c3,
+ 0x6578e47f, 0x0cf7bdda, 0x99bca7c2, 0x7763ebeb, 0x1af8bdef, 0x21bde3ca,
+ 0x55ff6e74, 0x7bc13c7a, 0x1b2bf365, 0xf6bacf10, 0xd60e88e8, 0xd2f27c37,
+ 0x819ea9af, 0x689b2b9e, 0x6ba364f0, 0x979dd5e4, 0x2771c01f, 0xc1be7b06,
+ 0xcc869ffc, 0x8c4c79a6, 0xeefc74e0, 0x3107a290, 0xef6bbd9e, 0xee90c7ee,
+ 0xfc63f626, 0x132ef5de, 0xebd94fed, 0xaed0e3e9, 0x9b690aef, 0xee57fd8d,
+ 0xfdf3f034, 0xbde8a3d7, 0xee749e88, 0xb21d2e6f, 0xabe50e31, 0xdb1dcde6,
+ 0xc67e8d7e, 0x6f3a269d, 0xfae70aa9, 0x9b5c995d, 0xdfed08fb, 0x80fedbcb,
+ 0xa261def3, 0xf452cff3, 0x74be40ad, 0x17bf325b, 0x66afcffe, 0xc9e43ee3,
+ 0xca7ee85b, 0x0d267537, 0xdeb8e1c2, 0x83ef0fde, 0xc8eb8eb8, 0xf9152cce,
+ 0x7c1113d2, 0xf9edc13e, 0x37fd7fb4, 0x2d7ca1c6, 0xfde5f88b, 0xf289ef38,
+ 0xced097c6, 0xf7f0af61, 0x00efcecd, 0xf3bb41b8, 0x0e8a3af5, 0x4211daed,
+ 0xa53bb6f7, 0xddf1b38d, 0xaf3d570c, 0x48da69d7, 0xa7d574f0, 0x76bdf7f2,
+ 0xb0c3a740, 0xf95526de, 0xb257faf9, 0xb0bd0ed0, 0xa3d92273, 0xf42b9e0a,
+ 0x78175652, 0xafdf8c2f, 0x337f132c, 0xfd998b8b, 0xf6174afc, 0x02f5df3d,
+ 0xd0bfb5f3, 0xc8fba3a0, 0x0ab606a5, 0x7a1571e3, 0xb7bd8b28, 0xa657d700,
+ 0x7d414da9, 0xfb6474a5, 0xf38ba46c, 0x868c6626, 0x39081f7a, 0x7cb8d655,
+ 0x37bdea32, 0x431dcf9a, 0x56fa1f38, 0x4db7e1d0, 0x79ffb726, 0xb7fa605f,
+ 0x50fd666a, 0x7cffcbeb, 0xdc9efa91, 0x138f7a07, 0x70cab3ed, 0x414e3fce,
+ 0x5fe006fd, 0xfce10fb7, 0x7552ce62, 0x3c218cfd, 0xdf52b10e, 0x4ef2829e,
+ 0x887d3fe9, 0xda83eb85, 0x2a277a76, 0x5944ddb0, 0xfc5d9bf0, 0xa35969de,
+ 0x1df741d4, 0x3e91a410, 0x5d199678, 0xe9d38c6e, 0x73a21f6b, 0xbde03ec5,
+ 0x34f12182, 0x8983595e, 0x07972dee, 0x7ea287b5, 0x0f690ce4, 0xeba7bd45,
+ 0x8bde994d, 0xafebedc4, 0x1be09ff4, 0x9617f14f, 0x5376747a, 0x72c1e35f,
+ 0x885e2ed0, 0x3e28037f, 0xeb40921b, 0xe60a692e, 0xed2da4f7, 0xf0386f74,
+ 0xd3ae211e, 0x5d8f47e2, 0xfa472f4d, 0x87b3e7db, 0x57ff0bc4, 0xf74dd107,
+ 0x438cbf3f, 0xb0d3283c, 0x785e7855, 0x15f7e241, 0x15f74f20, 0xc773882e,
+ 0x41ccefb2, 0xbe173f88, 0x771d1275, 0xe7c4ed49, 0x88aabbcc, 0xdae9743f,
+ 0x4349cf89, 0xae7c417f, 0x367dac2b, 0xd0f32df2, 0x4c7bfc35, 0x4fbc6cfb,
+ 0xc8886173, 0xf724660f, 0x40daee07, 0xcca264fc, 0xcbd818e3, 0x0bf70b3a,
+ 0x142f7871, 0xed6c6270, 0x3bb26a89, 0x8fd45674, 0x424a8762, 0xd6fbd7ff,
+ 0xa9e8fb2f, 0x3777598b, 0xf0967d22, 0x9f406277, 0xf50d786a, 0xf49119be,
+ 0xdc204dce, 0xfebe7394, 0x805f7fe1, 0x710a64fb, 0xe7821cac, 0x64ed19d5,
+ 0x93b60057, 0xb6f95efe, 0x6ecbec81, 0xe436cf5d, 0xc7661d5f, 0xa9cf58e3,
+ 0x2d935b6f, 0xf6fa7de1, 0x9bdf3c56, 0x7be3dca0, 0x575be385, 0x9efccbc6,
+ 0x7c273882, 0xbe03ec4e, 0xf88b5881, 0x7e7df121, 0x0ff5e9a7, 0xb574df91,
+ 0x0e9f1225, 0x4df3a7a4, 0x0a7bd34f, 0xbbae4127, 0x93ffecfc, 0x79d0af45,
+ 0xc38c74fc, 0x3f7f5f30, 0xa9fbf7b5, 0x0db20764, 0x8f88e57e, 0x207cea35,
+ 0xbd2f105c, 0x11703a2a, 0x5ba78fdc, 0x63a3bbf8, 0x821de8db, 0x9029f96b,
+ 0x07f2fd97, 0xf501f203, 0xea3b5ef1, 0x2f51c70f, 0xf60e3840, 0x7dbb209e,
+ 0x5d938f37, 0xf28d7209, 0x9ce9837b, 0xe41bb358, 0xb72e7f56, 0x87945e50,
+ 0xaabf91b6, 0xce81af6b, 0x9f345637, 0x03f5c38d, 0xa65f923e, 0x488df9bc,
+ 0x12bfe7b4, 0xc7c80376, 0xd94b8a48, 0xf6891cdb, 0xd4ee5287, 0x7c445278,
+ 0x0ff2167c, 0xf642bca5, 0x553dd0a6, 0x39de8da9, 0x4de70af8, 0x632f21f5,
+ 0x9c3ad19e, 0xd67ba712, 0x0a6bdfcc, 0x8213b7dc, 0xa07f019f, 0xbc572777,
+ 0x0a05fdc9, 0x7c15283f, 0x679620e5, 0x28b7fa70, 0xde7843e7, 0x07df7483,
+ 0xe140789f, 0xf9116c7b, 0xb10f8e73, 0xf68ab872, 0x37f72fd4, 0xb7b8b8f1,
+ 0x3212b33a, 0xdaf59db0, 0xfc6b8f7d, 0x5fc7d128, 0x13440f90, 0x8ba1581f,
+ 0xbd957584, 0x3abbd124, 0xe796b3a5, 0x50b67543, 0xe7bd08fb, 0xae718259,
+ 0x15e7ebe6, 0x43154788, 0x34ca9c38, 0xdb2eeedc, 0xcf39d126, 0x3f3f1d05,
+ 0x71437e03, 0x2dc70bf4, 0x9bfa47cf, 0xef42bfdf, 0xacdf1f6f, 0x5beeebff,
+ 0x1f9e5a2f, 0x979d07d5, 0x3ad4dd2d, 0x5fdf5d80, 0x3f36a3a9, 0xb97d7ad2,
+ 0x260bef32, 0x75639e65, 0x31e1fc03, 0xbe3e797d, 0xf8d0b8fb, 0xaf83c2af,
+ 0xc1b342fb, 0xe017728b, 0x77b5e74b, 0xf2a45d5f, 0xbfacdeab, 0x73a6e652,
+ 0x3fcd1b8f, 0xde4a7530, 0x0ad71413, 0x744f55f4, 0x37e37406, 0x024363de,
+ 0x452511fc, 0x157bd1b7, 0xfcdba28e, 0x298111fd, 0x1a81ca30, 0x5170d98a,
+ 0xdb38740a, 0x943c07d6, 0xb94389fa, 0x8131f55f, 0x962703c7, 0x231aff3f,
+ 0xe86d8e3f, 0xc7df1b80, 0xfff043b8, 0x718fbe5b, 0xb7af304f, 0x574164df,
+ 0xbffef74b, 0x7bb83f93, 0x3f3a79b5, 0x18b33067, 0x9d1adef8, 0xefdfd5b9,
+ 0xb7b889fb, 0xe996f780, 0xee9a79fe, 0x1949fdc7, 0x49fcd721, 0x04646fa4,
+ 0x574af9d3, 0x6f9215d3, 0x16392ddd, 0x6ae9073c, 0xde919b73, 0x5ff9feaa,
+ 0xbb872891, 0xb8a6be5a, 0xcfefaeb0, 0x3ad8bc52, 0xb077b711, 0xb55bc449,
+ 0xbcb04359, 0x7cabe0bb, 0xa45eb7ac, 0xf7027f3e, 0xe2a92ba7, 0x9f7bf02f,
+ 0x1cd0d667, 0xdd6b3f7c, 0x3e30d953, 0x45cc6e33, 0x7376007e, 0x9f0dca38,
+ 0xf51ac11f, 0xe88bf163, 0x72d24847, 0xe8a6023f, 0xe24a4847, 0xa3cc047e,
+ 0xf453011f, 0xfa396023, 0x7e8f3011, 0x1fa3cc04, 0x47e8f301, 0x08fd14c0,
+ 0xb88dfe58, 0x8c0dd12f, 0xcd39fb8b, 0x6097f7c4, 0x6fc030fc, 0x78bf7889,
+ 0x777f3d49, 0xa04bef07, 0x7e2ebbfc, 0xcfc451a6, 0xf9d13678, 0xd95ed55f,
+ 0xf7845b86, 0x18295c2a, 0x0873d347, 0x7b553ffd, 0x2b72db24, 0x79a74f96,
+ 0xf9c96bac, 0xd7961674, 0x5ef86ceb, 0xdf13e016, 0xe2895acf, 0xea5aca98,
+ 0x2e355fc9, 0xcdc53f6a, 0x0c483557, 0x0cd3acfd, 0x90ae4edc, 0x9d0474a1,
+ 0x5d1e9297, 0xfb236861, 0x64bb7ca5, 0x5c9fbff5, 0xf132ea35, 0x78dce509,
+ 0x2ac4ff01, 0xb16b263c, 0x79dace4a, 0x69fe13fc, 0x9137c5f5, 0x17a7e21e,
+ 0x64f3c02d, 0xa7bf972c, 0x60151b7b, 0x374846e0, 0x6b2a7f8f, 0xe306b3d9,
+ 0x0e356ea6, 0xe2a1e5ea, 0xbf3878fc, 0x4cf0518f, 0x30bdeef1, 0x0346ef5e,
+ 0xd2bb29e9, 0xbf113b1d, 0xe4ece90e, 0xdfb4396f, 0xe9d67644, 0x7f2aa94d,
+ 0x883c9e4b, 0x758b1dfc, 0xe1efc912, 0xb60f0ea9, 0x1e60a7bb, 0x89ee59f9,
+ 0x563a210e, 0x5a90d0f0, 0x81f21af8, 0xf25699c5, 0xd819e56f, 0x113fa82f,
+ 0x53eca557, 0xde894ade, 0x36622e4d, 0xc7305fba, 0x5389dfce, 0xc39b75de,
+ 0x82839c78, 0x49378b57, 0x364eddfc, 0x5b3ce088, 0xcb4e73c0, 0xc74ef47b,
+ 0x5778833c, 0xbfcfc34e, 0x78f3d763, 0xc2f8f986, 0x8177be11, 0x7c9327d8,
+ 0xca1dbb7d, 0xe283c11d, 0x8d6f7eb8, 0x8e8bfec2, 0x373e28e8, 0x14beea2f,
+ 0x71f9c907, 0x7920c714, 0x0c3fca67, 0xa9fe31fd, 0xa438638e, 0xeb841c2b,
+ 0x253c456e, 0xd2838eff, 0x9425d523, 0x251c7e2a, 0xff7bb06e, 0xfc707b1b,
+ 0x6efe2abc, 0xc5ef0dec, 0x3f7df505, 0xf027b94c, 0x0e29c619, 0x1f1ff5c0,
+ 0xc4dbef89, 0xe1b6677e, 0xf6a2f3fa, 0x44aabdd3, 0x933fffd1, 0xfee0cf0b,
+ 0x0b9943d8, 0xcc39e1db, 0x3e678046, 0x3f42402e, 0xf78ec7b9, 0x4bf67a53,
+ 0xbe5f8a16, 0x5a6e6f8e, 0x5521f18d, 0x6bbd1249, 0x31b41f9d, 0xcffa122f,
+ 0x21b7884f, 0xe26aaedf, 0x482ed67e, 0xe5dfbef9, 0x18aaf7a6, 0x826a3f7f,
+ 0x53fbb7d8, 0x3a1f7f1c, 0x513e57c0, 0xcb7755d0, 0x7bb71e15, 0x1d6c3f73,
+ 0xf8c73fbd, 0x0ff41f7b, 0xe87135e6, 0x2ac7f260, 0x10dbd378, 0x26f115b5,
+ 0x9bb78324, 0x0e98eb35, 0xcd2906f5, 0xfc80cc61, 0xabcbe2ec, 0x7d9d6923,
+ 0xf894c5fb, 0x98bf40f6, 0xbffd7f3f, 0xb0ff6b88, 0x47a5117a, 0xda5297ab,
+ 0xefa2ed56, 0xcb6e1720, 0x6a7f35b8, 0xfe1f464a, 0xf6b46654, 0xf40ab923,
+ 0x01d6fdcd, 0x6ba053fe, 0xdf5d1f8d, 0x773612d3, 0x351dea2d, 0x128f7a7a,
+ 0x98978ce3, 0x32d80f89, 0x2aa3f4fa, 0xdf933370, 0x469997b5, 0xa6c7fc20,
+ 0xf0356a25, 0x490ccefd, 0x74865e75, 0x3a43eb82, 0x44e914c1, 0x7cefe7eb,
+ 0x9c240f51, 0x1700f5cd, 0xda2601e9, 0x81cb35d7, 0xeef8487f, 0x3fc5458f,
+ 0x0ff0062e, 0xa61e5830, 0x062d55fb, 0x8946877a, 0xc90b1cb7, 0xf07d11d5,
+ 0x27e70f13, 0x3b3c8383, 0x657fbee8, 0x1ef3c510, 0x3afc71d2, 0xc9c78eb4,
+ 0xfe42b315, 0x7cf5d0de, 0xcccbee85, 0xf539e88b, 0xef3fa807, 0x33e93309,
+ 0xe416626b, 0x257c3bfe, 0xe0106507, 0x4b2c6b9d, 0x9be0b8c3, 0x03bbcaa5,
+ 0xd021ded7, 0x271cf78b, 0xaa6a77f0, 0x5953fe84, 0x54fa216c, 0x6a5661ee,
+ 0xb06b1d3d, 0x1e10ff5e, 0xf465a1ef, 0xcd71c8ce, 0xa9eefe40, 0x13e3b3a0,
+ 0x1b9fc912, 0xc5e3d2b9, 0x93ee7b7e, 0x71da7de8, 0x831dfcc1, 0xf3a14d3c,
+ 0xaefef815, 0x7d47df86, 0x9029df11, 0x5fb95f71, 0x93ef77c4, 0x05b169eb,
+ 0x7fb95b21, 0xb3fbbf98, 0x00fe1252, 0xb74b6ef1, 0x1fdde03b, 0x374aeef1,
+ 0x08f59c2b, 0xcae981f2, 0x27d68ffb, 0xa6a07cf1, 0xf7788874, 0xcf7fe387,
+ 0xf90da364, 0x3e70cd59, 0x04d29aff, 0xac948fee, 0xb98e51cb, 0x1c68c37e,
+ 0x833fbbdf, 0x1fb2bbe9, 0xa72e3bca, 0x43bf1c43, 0x9ef811be, 0xe152b3cb,
+ 0x4fd8f98c, 0x27af9f26, 0x43e3f399, 0xb93c8633, 0xc838e10d, 0xf87a839a,
+ 0xb96151dc, 0xac47e012, 0x800cb996, 0xa69be87f, 0x69d66e77, 0xbc602bdd,
+ 0x2f715a41, 0x3df82b5f, 0x82341974, 0x90f5dbea, 0x217a7a2f, 0x8abca3b3,
+ 0x6c5ef465, 0x879f9192, 0x29863b43, 0x946469ba, 0x85fb8c83, 0xfef1fa8a,
+ 0x7b98a28b, 0xd9fd4485, 0x673c4a35, 0x020efe2e, 0xb6173f23, 0xed411d0f,
+ 0xdede1a5d, 0xb6f485ae, 0x51defe44, 0x9d036acf, 0x3e3d1683, 0xa4e3e498,
+ 0xedfbeab1, 0x38f067df, 0x985d2505, 0xf9d15569, 0x74e955dc, 0xd577389e,
+ 0x43d40a8c, 0x74c10d1c, 0x81f3af1f, 0x9df0bb97, 0xbdd972f1, 0x6bb413e0,
+ 0x216f1d32, 0x5920b95f, 0x0a85ef67, 0x477c1f73, 0x0e31718f, 0x6f4be4cf,
+ 0xed70dca2, 0xbaef8a39, 0x4c80ffdd, 0xfc67efed, 0x8ab6647d, 0x9f7903bf,
+ 0x1a36b2eb, 0xb46fbffa, 0x0ef27e44, 0xf50e2593, 0x5fb122ba, 0x14ff82ad,
+ 0x829c19ad, 0x787df576, 0x9c87dece, 0x3d793291, 0xf76dfbe5, 0x635d9530,
+ 0x990ddf10, 0x25b7bd7c, 0x6bc5eff2, 0xa1891d0d, 0xa9bcea98, 0x8d86da90,
+ 0x65f118fd, 0xdfcb0252, 0x25fc708c, 0x987633f7, 0x97ce9798, 0xae0933eb,
+ 0xf1d3d60e, 0x6ea3ae38, 0x63a3ad28, 0xde8e258c, 0x8aef10bf, 0xfe70b7ce,
+ 0x8f8631d4, 0x1ed2ca73, 0xe9c19e12, 0x9d17df07, 0xebf4b627, 0xba9f2ba5,
+ 0x5bcdea1d, 0x927ba466, 0x4a999ff3, 0x1abcca76, 0xb247ee99, 0x45f7ea0d,
+ 0xe2749e41, 0x0bdf02fc, 0x14177c0d, 0xa0f11cf7, 0x78448378, 0x9b4adb74,
+ 0x7bdfcf1e, 0x009e8136, 0xdecd8bdf, 0x8a0bd424, 0x0adb266d, 0x43778fa9,
+ 0xe5b807bf, 0x8ccbbbe2, 0x592126fc, 0x6e38ab8e, 0x7a22c6d1, 0xc33833a7,
+ 0xdbb0fe41, 0xfd441ec0, 0x4e4c8ee7, 0xbc00933f, 0xb683cef4, 0x9fed063d,
+ 0xaf1c193d, 0x525b8526, 0x269784cc, 0x3bbbf786, 0x9c149674, 0x936ac75f,
+ 0x499ef506, 0x027e382b, 0x23b518dd, 0x059fbe30, 0x111efd21, 0xd72d67ed,
+ 0x7e42d616, 0x90ed8810, 0xe19bc470, 0x0e8f9f84, 0xf119fc73, 0xd86fdcef,
+ 0xf39fe428, 0xf3e26c36, 0xb4cffb12, 0x9ef0e36d, 0xf8fab9e5, 0xa0571811,
+ 0xc3a3c3e0, 0xfd325ac6, 0x8901e0f1, 0x73d61ff6, 0x6d8de518, 0xccc8dcd8,
+ 0x007e5401, 0x58d263f1, 0xe421c52f, 0xe7864ec9, 0x8cd1bdf8, 0x197be9e2,
+ 0xb5ded7a7, 0x0a6fe25a, 0x01f8509f, 0xef1d83e0, 0xadfb2ac7, 0x2bff85f0,
+ 0x43e0043d, 0x1be1457c, 0xf0517f0a, 0x8133e14b, 0xc01b3578, 0x6a08f77c,
+ 0xe14cfc4f, 0xcd0eb863, 0x517f1f08, 0x76b759f6, 0xadfc868c, 0xe4f39f62,
+ 0x40dfbb8b, 0x49989438, 0x1706b96f, 0x12e091b3, 0xf84d67a7, 0x47caea3e,
+ 0x402cf70a, 0x416dfc7c, 0x331fea3c, 0x18f7d44b, 0x7d48be7f, 0x52ce717f,
+ 0x59c5fdf5, 0x843e3f4b, 0x5086a77e, 0xbfdc04c7, 0xf33dbf53, 0xfe50a7e2,
+ 0x90bdbf9f, 0x8becedcc, 0xb8e1cff5, 0x3cc482cb, 0x96bcf9da, 0xdcbe49e9,
+ 0xfc30f426, 0x9732fb87, 0x8a2d3a71, 0xf28a3b0f, 0x29c22e6f, 0x611fdf0b,
+ 0x89bfcf04, 0xf62539fd, 0xf73568a7, 0x24b8743b, 0x5dcc43f2, 0xad74e825,
+ 0x97f25efa, 0x383dac31, 0xf97f77d1, 0xc4a4dfcb, 0xf72b5d21, 0xf96b1d95,
+ 0xe969667d, 0x1c5fd261, 0xae50fbca, 0x96a1f780, 0xcf7bf2b6, 0xc4fbeaed,
+ 0x3d76d9c1, 0xb71829f9, 0x1da6e6a3, 0x1b35f1e4, 0xb28a0b25, 0xbc5e5162,
+ 0x57dd5256, 0xdf93247b, 0xd0cc6b17, 0xfa0bbf72, 0x1f38949c, 0x7c04be3f,
+ 0x15cfee83, 0x5fae1c6f, 0xe747c7e0, 0x6979f28a, 0xf2954a1a, 0x571e0cc6,
+ 0x03448c1a, 0x4b4faefd, 0x7e27cfd0, 0xa8bf2567, 0xda6e7f52, 0x37e83588,
+ 0x7f01bb98, 0xfed7c79d, 0x6a5a9937, 0x26f428df, 0xfcf80de7, 0xfc2a38b5,
+ 0x379a0ef3, 0xaf65d3d9, 0xdf157aee, 0xdcfb2fbd, 0x6ca67240, 0xcf5f3898,
+ 0xa54ee770, 0x9f7e63f3, 0xf7ec52aa, 0x845f5db8, 0xd5509da2, 0x8671dfc8,
+ 0xcad303b4, 0xef642565, 0x1e80da57, 0xf78fafc2, 0xcfd5f77e, 0xd95fb943,
+ 0x9f41ab15, 0xa59df888, 0xc8afc6ca, 0xdefca0ef, 0x2abb6052, 0x6e50fbe9,
+ 0xff985abf, 0xede411ef, 0x549d11d7, 0xb97b7335, 0xf215ef6a, 0x5fed579b,
+ 0x63e8e91d, 0x13dfd7fd, 0xe8e2abb1, 0xcb86d8ab, 0x06fe0f74, 0x4c9eeaf1,
+ 0xedc3eef1, 0x538a76ec, 0x2b8a32d7, 0x2ebbf6ba, 0x8d1fe4ee, 0xacdaac8f,
+ 0x5ea078a1, 0x9e1fb5ad, 0xfb8b75c7, 0xbef58151, 0xd776e4cd, 0x7c23a025,
+ 0x41bba377, 0xee9df3a6, 0xabbfee06, 0x15ba786c, 0x8256a5ef, 0x5ec30ce1,
+ 0xd9543fbb, 0x7fa33328, 0x1fc61adc, 0x9e78dc45, 0xe842bbe5, 0x8f52981d,
+ 0xf987af64, 0x34bd82f4, 0xc73e6fc0, 0x1b955e05, 0x2fb4b93c, 0x0387fe62,
+ 0x96d29df4, 0x2b9ee9a7, 0xfd22ebd4, 0x8cc18fe4, 0x1cf5939f, 0x6e7679c5,
+ 0x5ae74919, 0x953d9ea5, 0x086c77e4, 0x0b9578a6, 0xe9bdf53a, 0x53bc6253,
+ 0xafee3c99, 0xb124e313, 0xe932abfd, 0xa44f38a7, 0x3a920bc7, 0x68b4e38e,
+ 0x6dc05a77, 0xa54ba09d, 0x23a7a97e, 0x9fea0934, 0xd298fa6d, 0xd4bf512e,
+ 0x728596dc, 0x30636cf3, 0xdb3d63dd, 0xb7fc87f8, 0x9e4bbc60, 0x3f25fd31,
+ 0x74b292fa, 0x88b63f7c, 0x08eeb8fb, 0x43c4cf71, 0x886ce9eb, 0xacbed095,
+ 0x9d5ef110, 0x6a87af8d, 0xff5d7e88, 0x4d5defde, 0xb15deebf, 0xfea046ef,
+ 0xbd576c62, 0xd5bff62b, 0xff28a57f, 0xe3142a44, 0xb9c5e8f4, 0x101dff30,
+ 0xe13ba08b, 0xcc3d9d8f, 0x7fde10fa, 0xdff01f65, 0xffbd030d, 0x668fb439,
+ 0xec8239ff, 0x0ffdfc4f, 0x21f37fcc, 0x3d9b2f3f, 0xe895f052, 0xd7f41cf6,
+ 0xfd73c477, 0x2816b9c1, 0x0e5a4011, 0xf802e5f8, 0xe61add39, 0x2cd0fc80,
+ 0x02753f6e, 0xe187ebfe, 0xe58e3cc8, 0xf877d814, 0x35eb8c9e, 0x4cec8e7e,
+ 0xbde0a6f0, 0x4f114ebe, 0xa6f70ce0, 0x17bf4044, 0xa7389e05, 0xdffc5378,
+ 0xf56e74a9, 0x45cd3c52, 0xdf873f11, 0x1ce79fd1, 0xc475ebc1, 0xdee8ba5b,
+ 0x8610dec6, 0x8de6aafa, 0x8ac3c210, 0x0d5b4c57, 0xa8d2767e, 0x5f0fae2c,
+ 0xad77f3d4, 0x7cf8db5d, 0x5237434a, 0x7e05173f, 0xa46d0697, 0xf7129df9,
+ 0x3cf54b83, 0xf463a1df, 0x0ecf7c9e, 0x85cf6efe, 0x387db698, 0xe91d85ce,
+ 0x11da6714, 0x44d05eef, 0x497c79df, 0x17834ed9, 0x477e75e7, 0x2a03dd08,
+ 0x3a66edf8, 0x33adec5f, 0xceffc848, 0xcf74600f, 0x00fd7ce1, 0x25e7d792,
+ 0xcf37f92b, 0xfd411fbf, 0xa52f5595, 0xc0652cfb, 0x84ef5026, 0xb5f500b4,
+ 0xc7cff5f3, 0x7e42fd21, 0x6c1de62d, 0x215fece3, 0x260f6e9d, 0xcec2f33b,
+ 0x9ffba47f, 0xe06928f7, 0x9fb289b9, 0x59e9f7ca, 0x2e986edc, 0xcb2b34e0,
+ 0x832dcfc2, 0xd026cf3d, 0x037d38fa, 0x002ec99c, 0x7177a27a, 0x239a794e,
+ 0xeca7e825, 0xca3b108d, 0x379d0ef7, 0x87040fe5, 0x30bbf160, 0xf3c2ec8c,
+ 0x2ec822db, 0xfa9a2d07, 0x932dbf39, 0x389543e2, 0xaba84993, 0x12663ed1,
+ 0x2de4f37c, 0x706ef459, 0xe1c5305d, 0xbb7e3d94, 0x644ee286, 0xbd9777ae,
+ 0xc8926f3a, 0xa69cf1db, 0x56bf57ec, 0x49fe45e0, 0x29d48e25, 0xe3c568f8,
+ 0xb8c3f577, 0x9967f65b, 0x68aee3e2, 0x20639c79, 0x0964765c, 0x45efba3e,
+ 0xe0275ba2, 0x502efe39, 0x2f0388b9, 0x2cfdc9df, 0x7aee6be5, 0x51e3f88e,
+ 0xdf38c31d, 0x43a79e8b, 0xb4fee1fd, 0xded7c7e8, 0xa1cbf546, 0x41ff6f3e,
+ 0x9b67cd28, 0x0392e28e, 0xdb96ebf7, 0xa5ff94ef, 0xd01e65f6, 0x0738fa03,
+ 0x1edac2be, 0x40f91cfb, 0xa2e6c983, 0xd7b71e52, 0xe02cf3a9, 0xc44c19f7,
+ 0xc4c33a1f, 0xf35689ef, 0x35f281f8, 0x71477f13, 0xd2a7c70a, 0xee85a61d,
+ 0x36e9cfbe, 0x115cfe0b, 0x7487eb61, 0x41fb0158, 0xbf1f09f7, 0xb375ee8b,
+ 0x7da8eb3f, 0x131e7ae0, 0xe1d1aeed, 0xdcff1e6e, 0x4bef9039, 0x24a9abe7,
+ 0x38c23a77, 0xc97cc35e, 0xe30ced4e, 0x60480529, 0xe3858ddc, 0x0f18e743,
+ 0xd29ddfd9, 0x743b4a1e, 0x52d95dbc, 0x5e177bf1, 0x44e2371e, 0x77c44d9c,
+ 0xa1b43677, 0x38fc81be, 0x5ea50477, 0xeff5f843, 0x931e0386, 0xc593d77d,
+ 0x7f129be5, 0x93d6ef43, 0x47a3d35f, 0x7a10ea7e, 0xfae1b39f, 0x7ba033df,
+ 0xc5120def, 0xe959ff1d, 0x94ffc447, 0xcacf0e73, 0xe39d125d, 0xa47aaf97,
+ 0x7cbef114, 0x4899a6d1, 0xca3aca0f, 0xed00acb5, 0xa6490eaf, 0x3f5d80f9,
+ 0xf5c64a67, 0xfdf029e3, 0x513fd04c, 0x8067228e, 0x59654ed6, 0x6d953d15,
+ 0xab9cfe84, 0x4e340da4, 0xf27762bc, 0xc27029f5, 0x638c1f73, 0x3701fc54,
+ 0xcf32bf5a, 0x57a7cd1b, 0x788ea1f0, 0xe346efeb, 0x13247f7e, 0xfdf2b93f,
+ 0x3fe17ec8, 0x2fd1b7a2, 0xe1fd2a59, 0x11d4127d, 0xc8839fa1, 0x046e30cf,
+ 0x3cc0bb6f, 0x8087e853, 0xd5a6e37c, 0x1a43f3a9, 0x468cf9d4, 0x45ab3e75,
+ 0xabbdb79d, 0xe3159fce, 0x3b42702a, 0x6c3def18, 0xd01ff717, 0x4bfbc60e,
+ 0x1e630768, 0xd14c60ed, 0xb472c60e, 0x768f3183, 0x0ed1e630, 0x1db9eab6,
+ 0xc1da298c, 0x8c359e58, 0xcb59c9c3, 0x0fb090fd, 0x9f8f3a76, 0x026efca1,
+ 0x8fa885d8, 0xbd220e96, 0xa8be7d0e, 0xedfff437, 0x478805d5, 0xd44710a6,
+ 0xc38c1cb0, 0x83135b6a, 0x93e203f5, 0x664c239c, 0xafb437f4, 0xd506bb3e,
+ 0x63b30e90, 0xe257d610, 0xbe962a96, 0xd6efbf43, 0xe7fadcbe, 0x227df29f,
+ 0xfbf287bf, 0xbef86543, 0x2e7e4cbb, 0x391dff23, 0xf7afb19b, 0x8ce303a3,
+ 0x22f895fe, 0x368e8abb, 0x53fe5c12, 0x7c8313d7, 0x461dabfe, 0x2bf5677a,
+ 0x4d931f71, 0xe77ea8b7, 0xde79daf1, 0xcb9d1293, 0x9c2c3ddc, 0x061ef7da,
+ 0x790fbbfd, 0xd0f3a4aa, 0x9f77ef59, 0x4906de78, 0xa6dce383, 0x276470e7,
+ 0x1c6f1164, 0x4ea77fca, 0xf51531cc, 0xa7f9bf73, 0xf85483bb, 0x787b7433,
+ 0x0c35efc0, 0xd61fd554, 0x7bf01094, 0xbfd4430d, 0xf2c0f023, 0x4f676803,
+ 0x555230dd, 0x6bd20aef, 0x28d5ca36, 0x85c597e2, 0x27c40577, 0x4f7eaa86,
+ 0xa7ae896f, 0xbfa871e3, 0xc90c6f64, 0xb7986283, 0xf388a47d, 0x49c7a581,
+ 0xb7c435ae, 0x3dfa256b, 0xde4279b2, 0xf96aa5b0, 0xe7e5a25b, 0x3646f87a,
+ 0xbdce83ea, 0x84fef451, 0x16258f82, 0x811b0f66, 0x596dbcf1, 0xde1fb45e,
+ 0xf117397f, 0x8dae42aa, 0x781bdfc3, 0xc36f7254, 0xc217a78b, 0x01de44f7,
+ 0x38d63fdf, 0x2f0f112a, 0x3a39ce1e, 0xb17ce00a, 0x4b7ba641, 0xe46f3a71,
+ 0xff0fb308, 0x209674e2, 0x8ddaffdc, 0xf41bfdfc, 0x3ee1c95b, 0x18dda8fc,
+ 0xf6649411, 0x87c15bad, 0x41def4db, 0xaf5d704b, 0x02af4899, 0xd3e49a3d,
+ 0xe932c395, 0x2463256f, 0x62b9e917, 0x4b7dca9d, 0x85a73d65, 0x78d2c83d,
+ 0xef8a8fbf, 0x640fd317, 0xce1d6159, 0x1938a6ea, 0x61a6b8f9, 0x63a40c5b,
+ 0xc3758e8c, 0xa8efe006, 0xef8a7f25, 0x227d9497, 0xf8ef8c33, 0xd09ee6ba,
+ 0xdccf503b, 0x824db3ad, 0x5f1be3fc, 0x6595fba6, 0xed1eb75a, 0xb51d92d2,
+ 0x5ee68f74, 0x82d26ef1, 0x9f6445ed, 0xc88b642f, 0xc4a73cce, 0x94780b9d,
+ 0x58b6958c, 0x823dde60, 0x7788946f, 0xf1f7942b, 0xefe76cae, 0xb8503f3e,
+ 0xf5e77e87, 0x902f5165, 0x9c3f7a5e, 0xfd00379a, 0xf6c91e4d, 0x1f4cf763,
+ 0xc03fa0c4, 0xad57a987, 0x75703e94, 0x9fb9d908, 0xa184afe0, 0xb008c8bc,
+ 0xf1e43f77, 0xbbf8bd19, 0xef78f148, 0x2a7fdbd2, 0x3adbc3ee, 0xc00a87da,
+ 0x7823519f, 0x909dc33c, 0xdf568e16, 0x171aa9f7, 0xe9f7c2ac, 0xa08e8fcc,
+ 0x7c1869bf, 0x607f97ee, 0xfeaaa252, 0x0d0c0f43, 0xbe1187a0, 0x742e74ef,
+ 0xb44e2aa7, 0x4acb9962, 0xe4f1f4f7, 0xd21cbfce, 0x13678465, 0xd82bed54,
+ 0x78bd5f14, 0x45ba3bfe, 0x7a6d7f84, 0x344a97b4, 0xba7d6e3c, 0xb79443a3,
+ 0x442c3953, 0x25b79745, 0x72e53eda, 0x83e3c751, 0x3a7b1f85, 0x97d89dfe,
+ 0x168d845c, 0xc9efe2e3, 0xa1c1ffa1, 0x54da3bd6, 0x3fc22271, 0xfdc69154,
+ 0x36ae1543, 0x01df9e3d, 0x00b1b5fc, 0xfc8dca92, 0x6fa8085d, 0xf9e70d8c,
+ 0x7fae2365, 0xc3fb0f2f, 0x0f2ac877, 0x2f4845cb, 0xf12bdf81, 0x0f9c027d,
+ 0xe94273fa, 0xbfde719d, 0xcfc157e8, 0xc09438c0, 0xb5f1b27e, 0xdf7a1c9f,
+ 0x9aa3de8f, 0x89efc85a, 0xf9933d3b, 0x3c00fbbd, 0x15fdf853, 0xfd12cf7c,
+ 0x43be1fdb, 0x5dbbd678, 0x00b76367, 0xf73b4a8f, 0xdfe20677, 0xbe0f5802,
+ 0x51a0b86f, 0x5e25b9b2, 0xfff2e10f, 0xf482dc01, 0x00800036, 0x00000000,
+ 0x00088b1f, 0x00000000, 0x5bcdff00, 0x6595580d, 0xf3be7e9a, 0x700e01c7,
+ 0x0427e540, 0x094a880f, 0x44101df6, 0x18293b53, 0x54da1595, 0x021f44a2,
+ 0x9a2824fe, 0x2edb52ed, 0x4c7350c7, 0x4a976867, 0x57a3ab1b, 0xb5accd39,
+ 0x8cce9a98, 0x7e927bbb, 0xa772b268, 0xa9aeae69, 0x66b663b5, 0x3b448dae,
+ 0xb5b4d45d, 0xdfbefdcf, 0x23bef9c7, 0xb5cced4c, 0xd7175c3f, 0xfff79e73,
+ 0xe7defe7d, 0xbbf79e7d, 0xc89132a3, 0x1befe24d, 0xffe56ffe, 0xd5a212ec,
+ 0x441f9d07, 0xabe5a30a, 0xae0decfb, 0x60fd65cb, 0xcbf5c5da, 0xc32a63f1,
+ 0x9c284a23, 0xd70770c7, 0x4d5dc69b, 0x27b53edb, 0x97f1ca03, 0x3463fc69,
+ 0x284a83c3, 0x1e3c5ca4, 0xca8d9055, 0x0c61d689, 0xf1c0d11f, 0x3f685d3b,
+ 0xaf214bb0, 0xa09d9a22, 0xd41eb974, 0x62bbdeb7, 0xc8614d3e, 0xf5e6cc63,
+ 0x11741c2d, 0x1b8d1295, 0xe6e5c27f, 0x1487fd7e, 0xbbf70f75, 0xca21d065,
+ 0x10e41d5b, 0x6a21acfb, 0xf9bdf867, 0x9dc1d117, 0xefeb269d, 0x60f37865,
+ 0xbb17e8ba, 0xe87a21ce, 0x6e88b9f4, 0x7645c274, 0x798dfed3, 0xa22ff1f5,
+ 0x71ff4c53, 0x1af6e9e3, 0x0a27510f, 0x7f0cb8b2, 0x8fb90257, 0x86688ca8,
+ 0xccfa349a, 0xb2efc264, 0xf21e786f, 0xa3d3a0f0, 0x512162ed, 0x8f0c6890,
+ 0xc7ad22eb, 0xd2593c03, 0xb8e92bd9, 0x48cbe9ce, 0x99dfe22d, 0x3bfa56c9,
+ 0x3728297c, 0x61d869c6, 0xa3d31f23, 0x3d363eca, 0x8c68e3c2, 0xc8b43e83,
+ 0x345f036b, 0x1bcdbc7d, 0x4c46e7c7, 0xce4db4fd, 0xb9f6e274, 0xd809461b,
+ 0x574def10, 0x8361beb9, 0xf0c426bd, 0xa467ef83, 0x7d1cb057, 0x7a39c9b0,
+ 0xc1f10f3e, 0xa97353dd, 0x80957818, 0x5b8c1fa7, 0xbc5cf214, 0x26d506af,
+ 0x37fad1e8, 0xf9dae4ef, 0xe3b627e7, 0xfe788bc9, 0x92874d96, 0x559c782b,
+ 0xf72ade9b, 0x6ddd13e6, 0xde54dad3, 0xf76539ff, 0xe5e82f5e, 0x86a53ddd,
+ 0x52015dc7, 0xd8ee5f30, 0xdc419554, 0xdeebe5ae, 0x79e3bdc7, 0xe99c1bbd,
+ 0x8f9f9636, 0x3b276d7f, 0x2759cfcb, 0xe24cbd05, 0x7e52f1b3, 0x18953ecf,
+ 0x3f7964ea, 0x9e2050ab, 0x5fda57cb, 0x5b718298, 0x75888e3a, 0xbd1db2ac,
+ 0xb5fff305, 0xc32de79b, 0x99bda1bc, 0x4e0d5798, 0x86dabcc4, 0xd15a2909,
+ 0xb35afcc8, 0x75d044a3, 0x99f7076f, 0xa8817448, 0xba7b7c1a, 0x9ff02dc3,
+ 0x59a13076, 0x6475f7d4, 0x0ed9fc0a, 0x1d3d809f, 0xbbbca285, 0xddf92bc8,
+ 0xc75fefd9, 0x50e704f3, 0x7c079b61, 0x783a14f3, 0x092a77fd, 0xa8029c6a,
+ 0xf7c17866, 0xff04b327, 0x5d88790c, 0xa27eaccf, 0x5e7c9326, 0x26a6e839,
+ 0x455efc93, 0xae7c16a9, 0xbed2cb3b, 0xa9679bca, 0x52f33abf, 0x3e35fd4b,
+ 0xaebf05bf, 0xfda5ba70, 0x1655eaf5, 0x6b8ac6fc, 0x0417ed2c, 0x9bf05816,
+ 0xed2d6baa, 0xb069ae6f, 0x68badfd4, 0x56bea5a5, 0x97c16b5b, 0xd2dbb8ac,
+ 0x0db6b6fe, 0x7900fa96, 0x7272c41d, 0x63e3f994, 0xf313ffba, 0xd7cef005,
+ 0x7ccc7827, 0xd6d7399d, 0xdc8c33d6, 0x32dc861e, 0x07f5de7f, 0xe47c839e,
+ 0x321ca4d8, 0x53cb100c, 0xf513eaaf, 0x305614d9, 0x2cbd9b0f, 0xbb6c4dc8,
+ 0x8999fad8, 0x31f33ec7, 0x7ffd730f, 0xf6c1c8b1, 0x63b4e660, 0xbf19e3a5,
+ 0x916fbfc9, 0xccc8ed83, 0x067d8e2b, 0x19ff0dfc, 0x5dc4df89, 0xf6fef067,
+ 0xf20a2c37, 0x995e673a, 0x3d654dbf, 0xea9d37a4, 0x7cb23453, 0x0e4ddf62,
+ 0x30c06fb9, 0x31e023cb, 0x17c04796, 0x0a9b1e59, 0x79665e88, 0x50ebec04,
+ 0x3b2ff945, 0xde3c042a, 0x8df01011, 0x4f016a8e, 0xf808d474, 0x02458eab,
+ 0x1343bafe, 0xb1d37efd, 0x3a77c042, 0x6ff944da, 0x7c05da3b, 0xca2823af,
+ 0xa11557df, 0x8202bcff, 0x0339c2dd, 0xf6ed5df9, 0x2e7ced84, 0xf9e711d0,
+ 0xfacabb21, 0xeed804ad, 0xdf14dd33, 0xd863aa68, 0x449146d9, 0x91c465e8,
+ 0x8bf9867a, 0x37edc39f, 0x741d476a, 0x1b8f18c6, 0x381f13df, 0x3442bb07,
+ 0x31267bd6, 0x1fc07e5a, 0x03e504f8, 0x2539f505, 0x3ebd9fcc, 0xf9f053ed,
+ 0x4dc692e6, 0xae376c29, 0x09cdaafc, 0x46db7939, 0x8f93862b, 0xb23e5d5e,
+ 0x638c141d, 0x29b8177e, 0xf0269298, 0x0e618b80, 0x88eec397, 0x0177de3f,
+ 0x81e43e60, 0xb963e508, 0xb670cdde, 0xf10a793b, 0xe5c394f9, 0x142f2176,
+ 0xc27ac870, 0xb41e5c78, 0xa9e745a5, 0xdf61241a, 0x84716d66, 0x1c921f60,
+ 0xc895b614, 0x7225c9f6, 0xdcb3e05e, 0xe5857e3d, 0x478b5664, 0x327ef20d,
+ 0x2255deb8, 0x0cec07da, 0xf73dfc9f, 0x514c229b, 0xd444a130, 0xbd72f58b,
+ 0xa0d54758, 0xcff40146, 0xef4e3524, 0x41f596ef, 0x6bc59ff4, 0x30c15f80,
+ 0x9c79f184, 0x7689d600, 0x185db289, 0xce7c14e3, 0xf49b24f3, 0x9642fec5,
+ 0xdf65fb83, 0x9f6152e9, 0xe44ed273, 0x3f31eec1, 0xfeb9f9c6, 0xdbd9d4a6,
+ 0x9a9fcc23, 0x26bfef38, 0xf34a5f32, 0xff9402b4, 0xc13f194a, 0x4c17e60f,
+ 0xc4935319, 0xe7c6c4f6, 0x39f630e4, 0x3f062f96, 0xf41bba0c, 0x48dbe58d,
+ 0x4f891afc, 0x1aa9fcb1, 0xf41bd28c, 0x512f991a, 0xff9505fe, 0x754cbe7b,
+ 0x7ac6ecf4, 0x2adc5ae2, 0x7c6df3d6, 0xe69fbdba, 0x869370a5, 0x80cbdf41,
+ 0x5eb4f267, 0x5d2351e8, 0x9a0bcf35, 0xe0c5ed79, 0x0bbb6c4f, 0x03e3b423,
+ 0x779c56f7, 0x6d273e7d, 0x8b5ff9e5, 0xa0a73a67, 0x33f1e03c, 0xf6eae61f,
+ 0x84da8fa2, 0x2937673d, 0xea54fe08, 0xb45b9aac, 0x9597f85c, 0x36bfab1e,
+ 0x8d9aabef, 0xe8de7798, 0xcd95ff18, 0x6bd1ce32, 0xa6af71f5, 0xf56e312e,
+ 0x6bbb6b58, 0xdaf0bf75, 0x5df96b02, 0xcbafdd7e, 0x91d83ca3, 0xbae5524a,
+ 0xcbf09b68, 0xdc72bd2a, 0xe3af9d6c, 0x099a767d, 0x80e691be, 0x77f17af1,
+ 0x7bd600ae, 0x7e050535, 0xbc04850d, 0x9c62c28e, 0x01d0d9eb, 0x09c891bf,
+ 0x9fddc5bc, 0x5e9162eb, 0x87ded76d, 0x8e49f3df, 0xeb852936, 0xfbb5e333,
+ 0x89bd17a1, 0xe1add437, 0xce96e6f9, 0x63bf402d, 0x2fe13e95, 0x178f731c,
+ 0xdfe40bfe, 0x8fd51699, 0x17fed957, 0xf97adaf0, 0x897c007c, 0x160287cf,
+ 0x7cf857f6, 0xe16d7e00, 0x79bf4206, 0xa61c853e, 0xaffd1b7d, 0x4721cef3,
+ 0xf7f6c8e9, 0x1b3f29ba, 0xbc9cb1ab, 0x92a93a96, 0x55a70192, 0xa5afbf62,
+ 0x8c24d866, 0x7c580973, 0xff3860b8, 0xe8bf90ca, 0x31c8f37c, 0x1b3a646a,
+ 0xa7a58d74, 0x813fe741, 0x470dcfae, 0xc4955ed7, 0x3ee03639, 0x313d9ab0,
+ 0xf6944d6a, 0x89387020, 0xd77e5932, 0xa087b21d, 0x89631f8f, 0xd25f1859,
+ 0xbfa50a89, 0xef5f5ebe, 0x16341d47, 0x53a7a6f4, 0xba5df944, 0xcfb736cc,
+ 0xd65cfb10, 0x7dfa215e, 0x88bda719, 0x092f9c75, 0x820f644f, 0x99d5da3e,
+ 0xf9e7833c, 0x0abb59e4, 0xeec5bbff, 0xd742a6db, 0x4fabb35f, 0x55f4b8f1,
+ 0xe842ee6f, 0x86a393d3, 0xb8b467bd, 0x7b8d1d25, 0x357957c6, 0xc8ef38bd,
+ 0xf5299a5b, 0x85e81490, 0x8d8f3e71, 0xf2c2bb63, 0xe125cbbb, 0x7975e748,
+ 0x12a7db02, 0x49d85ed1, 0x4fdc7f83, 0x4e3cd9e0, 0x0fc8ec39, 0x7e3f8413,
+ 0x9ef0252e, 0x9256f31f, 0xbf659fc5, 0x81add857, 0xb38e92d1, 0x3323e269,
+ 0x73ecaf19, 0x07eb8852, 0x1b5da52a, 0xdd85b8f0, 0xd1b57aac, 0xa9dcfb01,
+ 0x4cb88bdb, 0xf498f7be, 0x4097de3f, 0x26fc933e, 0xf059a616, 0x4b12f524,
+ 0x7c8a94fb, 0xe06a7d4b, 0xa8fd4b32, 0x3e0b12ea, 0xa58666a6, 0x39a2c67d,
+ 0xbb4b3c16, 0x7b3ed2d6, 0x6e0b42c5, 0x596ca1d8, 0x8b6d3944, 0xb5c7fd2d,
+ 0xcfb4b52f, 0xa961de0b, 0x44e060a7, 0xd6aff721, 0xb2df8ffb, 0xe4cf5ace,
+ 0x2f4395b5, 0x928fdfe4, 0xe614fbab, 0xd967b55f, 0x84e5e87c, 0xebac7bae,
+ 0xc7657fb1, 0xa29d9039, 0xffa628d0, 0xddab3ed5, 0xe2b4caab, 0x8bff5e95,
+ 0xaf5cdd60, 0x9fb2eed5, 0xb29e40a7, 0xf2961cdb, 0xddba25b1, 0xc453429c,
+ 0xf8dbf87d, 0xe1665daf, 0x2ebd2c7f, 0xfe038796, 0xb49bb730, 0x97072ac3,
+ 0x3072ac86, 0x1cab69f9, 0xe558f714, 0x5623f2e0, 0xad87f039, 0x67da5072,
+ 0x13b28395, 0xf6983956, 0x0c0e558e, 0xd7e58cf9, 0x3e5588f4, 0xe5345348,
+ 0x8aebf08f, 0x89f956b3, 0xbf510fe5, 0x8f3cdfe0, 0xfde68f42, 0x185afcf9,
+ 0xfe21afc3, 0x77e1bd30, 0x4e4f0ece, 0x67d55e01, 0xf7cf10a7, 0xabcfbe98,
+ 0xf279b727, 0x74ee9ed9, 0xd0257568, 0x3aae5d73, 0x0d5ca4b3, 0x87881df4,
+ 0x198fafdd, 0x5a59c7ff, 0x1a2fda03, 0x0bae59f5, 0x4dafd1f2, 0x39e97dc2,
+ 0x1ddd8495, 0xe7c72097, 0x4758b27b, 0xa87b1ef0, 0xd271d793, 0x3ec0a5d6,
+ 0x2b6b2737, 0xa2f6ffd1, 0x07708536, 0xfe82a0a3, 0x971cfff5, 0x1c7ebc0b,
+ 0x151e7b89, 0x2416ca45, 0x7d62ed45, 0x7af39736, 0xf7e896d6, 0xb9eb9514,
+ 0x1912fadf, 0xbd5248b7, 0x290f112e, 0x20e200a2, 0xadc8bd7c, 0x8e3d062f,
+ 0x3d024fc7, 0x9b2a6dba, 0x7d388a38, 0xf067d829, 0xa53d3b55, 0xfe113f48,
+ 0x7fee8e5e, 0x4eff5365, 0x0ed273ac, 0x97ab9cb2, 0x30e4dc86, 0xd3f27dd1,
+ 0xdc5e0b5e, 0x7f696993, 0xa59f11f9, 0xb42e1fde, 0xa9f697d4, 0x44ecbc16,
+ 0xb4fda585, 0x7c160277, 0xd2daa47a, 0x35b38afe, 0x229c7c16, 0x5f7fafef,
+ 0xe3e92f92, 0x7de44563, 0xba9fdfd6, 0xf788ab7b, 0xe1ad7bc9, 0x23d7534f,
+ 0x4ce23701, 0xdec71cba, 0x404c5c87, 0xfec5cff0, 0xb183ce2f, 0x6b47e96e,
+ 0x294fbaf7, 0xdd3f51c9, 0xff0db3f0, 0x01558295, 0xfdc3b9f3, 0xfba2f9e4,
+ 0x6d7f86f3, 0x8bd3cdf8, 0x721ce27d, 0x26cabc6e, 0xc911c1e4, 0xc7d79c82,
+ 0xfdf7b0d1, 0xbde44be7, 0xc6fd7621, 0x9fe762ba, 0xed95ec5e, 0x729f71f5,
+ 0xc335edd3, 0x5cba33f9, 0x735f1c2d, 0xb8f9f214, 0x79677d53, 0x9e7f7fde,
+ 0xb3cfa4ce, 0x2e5cde84, 0xb3675fd7, 0x31a3f889, 0x52a991cf, 0x7f380d5e,
+ 0x7e3bfb0e, 0xe37deea2, 0x1fd87876, 0x21ddbc79, 0x9fc708e2, 0x2c1b515b,
+ 0x01443f80, 0xef8e338c, 0x7c0fe003, 0xae1fdc0a, 0xfd176a99, 0xbd4897cf,
+ 0x1265da8b, 0x24807976, 0x5dda07ff, 0x0c317ee2, 0x181c85bf, 0xcc7c41fb,
+ 0x62e32051, 0x398b8880, 0x062e321c, 0x4031711c, 0xfe50c5c4, 0xf02a875c,
+ 0x02151d83, 0x2023be7f, 0xd51d23f0, 0xa3bcfe02, 0x721b9446, 0xe32f4b13,
+ 0x1ff0663e, 0xa373886a, 0xe71e4620, 0xe5f927df, 0xd9aceb5b, 0x6f9c5bc3,
+ 0x24a56aa3, 0xa6dbcf4a, 0x2dc8794a, 0x3b407495, 0xed48ffe8, 0x2945ecaa,
+ 0x900ea788, 0x47fbc52f, 0x53ff86e2, 0x6ee830f4, 0xfaa357dc, 0x2461f526,
+ 0xbfee34bd, 0xd0acfba6, 0x8c7d58bb, 0xba58dbd5, 0xbdeb3f8b, 0x8d7bde59,
+ 0xa7ae85f8, 0xbd0c5f06, 0x16a45276, 0x605425f6, 0xef7d06ab, 0xd1eab24f,
+ 0xbe92a5f5, 0x8623d003, 0x74de7ca7, 0x7687ce1b, 0x5607f0af, 0x90ccb6e8,
+ 0xec87e6d3, 0xf3e27ce2, 0xed37e3d6, 0x7db779b7, 0x6eef9ea8, 0xe215bfbc,
+ 0x201d9d5c, 0xda5f1f71, 0x737684a5, 0xf5a086bf, 0x2521147c, 0xfae46fae,
+ 0xe35fb817, 0x33f3d896, 0xf221d620, 0xe6b5bc2c, 0x72fd6b2e, 0x33c91efd,
+ 0x632760ba, 0x96570af3, 0x4aa0e7ea, 0x5f7237ea, 0xdd105ee2, 0xa1572e97,
+ 0x873829f1, 0xcbb4af70, 0xce3846b8, 0x21f3af74, 0x8a2a3fce, 0x0a133d33,
+ 0x746e4e71, 0x177c13a8, 0xcf41a1cb, 0x9e833ca1, 0xeae7184f, 0xe23f753f,
+ 0x8bc7cf8b, 0x7fcf057b, 0xbe76e823, 0xff40aecf, 0x7a08f287, 0x3b41f3fb,
+ 0xe73e99d9, 0xba09c60f, 0x7e3b627e, 0x94cfbe4b, 0x5f28b877, 0xb015c941,
+ 0xa8c6fb1f, 0x65d661c1, 0xfb222d40, 0xe1bf588f, 0x99ee3250, 0xfcc8cf2d,
+ 0xbd33cb44, 0x7b2605e9, 0x10ea5cd8, 0xa6dbbbfb, 0xff2294b5, 0x8b9ddf60,
+ 0x5f1dde7b, 0xce00a686, 0xb12de3d7, 0x77b219fb, 0x47211533, 0x613fbc03,
+ 0xb115aaef, 0x0497b63f, 0x989b7b3d, 0x02ce3c9b, 0x34068f0a, 0x96da00f2,
+ 0x2307c10a, 0xae10d00f, 0xb9b8fb10, 0x8133b973, 0xde76449b, 0x8be0955b,
+ 0x392207e6, 0xc7fe08b4, 0x9b827948, 0xde315506, 0x886706f7, 0xcd281e71,
+ 0xc6d0fe93, 0x1fe16bed, 0x3934f65e, 0x53888741, 0xa74b138e, 0xf3ca943f,
+ 0x1d3c1320, 0xbadfdd13, 0xe7b08a0d, 0xc02ba0eb, 0x9ec22bb7, 0x5d67f81b,
+ 0xf1255e3a, 0x3c49373b, 0x516cf4e2, 0x117ee452, 0x013ec02f, 0x6bdc1fb1,
+ 0x05f1e9f7, 0xfb1003ec, 0x18ec3940, 0xe031d870, 0x61c063b0, 0xc76100c7,
+ 0x6a94be50, 0x43e71172, 0xacd2a33e, 0xaa6e8327, 0xc825f934, 0xe4719867,
+ 0x91edcc33, 0x23d730cf, 0x47ae619f, 0x238cc33e, 0x8f6e619f, 0x4719867c,
+ 0x1edcc33e, 0x8e330cf9, 0x3db9867c, 0x7ae619f2, 0xf5cc33e4, 0x719867c8,
+ 0xedcc33e4, 0xd730cf91, 0x58aededf, 0xb3b71df2, 0x35dc86f9, 0xf21348ee,
+ 0xa6af3631, 0x7efe720f, 0x3977d7e2, 0xa3e7c1f3, 0xebb7212b, 0xc954135a,
+ 0xc96aaee7, 0x3e491b77, 0x3e0ad7f7, 0x7892ebdf, 0x1de19a95, 0x1e422fc6,
+ 0xe640b2a1, 0x47910011, 0x011e4400, 0x4a847910, 0x0023cc87, 0x72808f22,
+ 0x910011e4, 0x1e440047, 0x04791001, 0x0011e440, 0x3f404791, 0x910011e4,
+ 0xf2394047, 0x23c88008, 0xaf24fca0, 0x6304f903, 0x0ba3f05d, 0x963cf72c,
+ 0xcf3dcb43, 0x47e1c16b, 0x8fc3db9b, 0x8fc3d736, 0x8fc3d736, 0xa3f0e336,
+ 0x47e1edcd, 0xa957719b, 0xfc17e84f, 0xf83f7369, 0xb8bc66d3, 0x6212f82b,
+ 0xfaefd744, 0x91808bdd, 0xc571e524, 0x41ec67cb, 0x4f7c8c5a, 0x4dc95e24,
+ 0x545cf955, 0x192b8b5c, 0x844b06d7, 0x7ea14fde, 0xf22df81b, 0x2d37ccb7,
+ 0xcde4214c, 0x14c8bf8b, 0x513e46f5, 0xfddf31fc, 0xe7f84907, 0x5d7245dd,
+ 0xbc957f46, 0x7da34076, 0x5dbe1f14, 0x3b46fcec, 0xeb4d2f61, 0x1f9b0be0,
+ 0xbdff7cf9, 0x2cad929e, 0x8a6d7b4f, 0xb2f74ff0, 0x1870b59f, 0xf74b34bb,
+ 0xf6daf69b, 0x7ee04b1f, 0xba8a0dfd, 0xe89e8787, 0x09673ea0, 0x0256d4e8,
+ 0xd4c2623f, 0xd47f3d54, 0x71616336, 0x3c46dd74, 0x0044ed8f, 0xfd99e779,
+ 0x79e26ae4, 0xb907fd66, 0xb9cfe19a, 0x7e811fa4, 0x0e4dcfb8, 0x263d812a,
+ 0xaa7cbef9, 0xe0b4ff3c, 0x5c4d19da, 0xdb5f793e, 0x77f8668c, 0x8fdfb209,
+ 0x7416489f, 0xb2a361bc, 0x99fbcec7, 0xbb028fb9, 0xbe855db9, 0xbcfbc9ee,
+ 0xaf3126ae, 0xce6cd5d7, 0x75caefbf, 0xa45f70f9, 0x88a66548, 0x3c842bc5,
+ 0xde37419d, 0x1fd88bdf, 0xc43ef89b, 0x1d3d5765, 0x24d0fdef, 0xa93dad1f,
+ 0x91cd7c16, 0x2687ef2c, 0x1f855b39, 0xeec4172c, 0x16adce21, 0xf5abe59d,
+ 0x9a95b7f2, 0x9e784bcf, 0x0bbf7756, 0x35359bf4, 0x6c346ab5, 0x275251ff,
+ 0x36a6ee40, 0xebc31a6c, 0xd50142d2, 0xdabd03ee, 0x93f8125e, 0xe2170235,
+ 0x27d62e53, 0x4149c3ce, 0xa4c89c25, 0xdbb821b8, 0xebf19a36, 0xe99c1b83,
+ 0x548fbf68, 0xf89303b8, 0x7449767f, 0xc274455f, 0x5e40af16, 0x499477a8,
+ 0x7c72d8fe, 0x57e2f20f, 0x58f9049d, 0x613af0e0, 0x8dfd626f, 0xec0f77d8,
+ 0xec2adc7f, 0x21d39f54, 0x3fdd3afc, 0xb5caf06a, 0x29d1b67e, 0x43868ffc,
+ 0x3ea07fec, 0xde30dfc6, 0xa1dfb043, 0x1f8e7186, 0x720d4ebc, 0xb7dacb55,
+ 0x7383bbc5, 0xa9bda179, 0xf2e7d72c, 0x0152dff7, 0x0aed90bf, 0x0dfb29ec,
+ 0xb9654e77, 0x52f4d86b, 0x915dee32, 0x6fe101e0, 0xa1f1b67c, 0x905f1964,
+ 0x9d2689f9, 0xa6fc464e, 0x9347e759, 0x03e5eefe, 0xa96c5bb6, 0xf186ee71,
+ 0x2bd7815e, 0x3f588afc, 0x9bfbc891, 0x82bf5c99, 0xb195b3f7, 0x361adbe5,
+ 0xfec5d267, 0xae6fe1a2, 0xb95de7d2, 0xb7de29d1, 0x3890a0ac, 0xac86560f,
+ 0xfee957ed, 0xada7aae7, 0xca983fe5, 0xa1f2277e, 0xdfa9df86, 0xdbd4ee93,
+ 0x7bdebc34, 0xda7bf0b3, 0x5075c89c, 0x07e906dd, 0x4d0a7ed1, 0xb5cf8050,
+ 0x775e33c5, 0xc32aa028, 0xba9bcdc8, 0x931f343f, 0x0c173d32, 0xb23b0826,
+ 0x8112f070, 0x299832df, 0x8583ade0, 0x19b11cb2, 0x4aa473e6, 0xe3c7dd09,
+ 0x41fba5bf, 0x265e0f37, 0x198207ea, 0x58078e42, 0x14c5318e, 0x165d3edd,
+ 0xd6117a50, 0x36d4ef9e, 0xf9fae18d, 0x95f849bb, 0xe25fc3d7, 0x9ff0458a,
+ 0x7907a14a, 0x6f9f1855, 0x0f21346f, 0x9756b07a, 0x1203d67b, 0xec202376,
+ 0x1082e559, 0xd22c93de, 0x6fc0dbf6, 0xe0b5fe43, 0xebf00729, 0x57cb8a83,
+ 0xe215ee24, 0x77c86cfe, 0x27d41eac, 0x8f26f1ea, 0xc50d278c, 0x5e58b09b,
+ 0xc5b5051a, 0x47afae01, 0x9d12f06c, 0xa4aa4cb1, 0x77df5922, 0x91bc5b50,
+ 0x353fbdcf, 0xb367511e, 0xb3f57e09, 0x8a07b79f, 0x32aa274a, 0x94db27a0,
+ 0xe8bead92, 0x9f289e7a, 0xba665033, 0xf5d52f27, 0x032ef58a, 0xdf758ef7,
+ 0xc341909f, 0x6c0605f8, 0xbf433a64, 0x772253ea, 0xfeea4c29, 0x64a814a9,
+ 0xbe92d6d6, 0x79fe244f, 0x3c758b9d, 0xdff6d0f7, 0xfa08f16e, 0xd4fcfc08,
+ 0x45838b35, 0xac1d867f, 0x77d01c53, 0xadbe0ec3, 0xb7a0e768, 0x3cc8eead,
+ 0xa8b135f0, 0xc5be05df, 0x6db6e7d2, 0x3127db3d, 0x24cb721d, 0x5d5ceaff,
+ 0x80b8f14e, 0xd3dc4e42, 0xb9e48b1a, 0xee5f0e42, 0xf11f9112, 0xb19fb889,
+ 0x6fe00fef, 0xf497430f, 0xc36fe932, 0xa4b9f63f, 0xff080c7f, 0xe04fef18,
+ 0x7f87031f, 0x18ff080c, 0x818ff0e5, 0x0e063fc3, 0xfc3818ff, 0xc7f84063,
+ 0x16d87f28, 0xf33f7538, 0x685b51f3, 0xd39661ff, 0xee6b47c7, 0x51ef9e32,
+ 0x238f92ea, 0x63fb1348, 0x627611b9, 0x7cb13ec8, 0x72a3cbb9, 0xf4fdb4b4,
+ 0x547e5b21, 0x7cb69a9e, 0xdc29f3ba, 0x841fd983, 0x945b6b3e, 0x9194dc70,
+ 0x3b89ece5, 0x3cbe8412, 0xd84b8f71, 0x89d73add, 0x5179dc97, 0xfedbbe7a,
+ 0x27694eb7, 0x3c7c13c3, 0x78b6e2ee, 0x89ff7615, 0xac1c9af2, 0x1548b137,
+ 0xd9c0197c, 0xb256f88e, 0xa5f28796, 0x4ce5e274, 0x57ff576e, 0x7ea2e7af,
+ 0x173cd1cd, 0x11c36fec, 0x1f4ce6ff, 0x21136bfa, 0xaf1e0daf, 0xeac5fe0b,
+ 0xbce2a98d, 0x7190cfad, 0x9140965c, 0x31f83307, 0xdfc64cbb, 0x80ef79fa,
+ 0x127bf417, 0xc0b9c813, 0x2df24ed2, 0xb88cdf56, 0x2b5c6c62, 0x72795f1a,
+ 0x22e23e4b, 0xf4ed49a3, 0xc42f4c5d, 0xd1255c3d, 0xfc6c4ab8, 0x5d5f4863,
+ 0x19e78964, 0x7e994d70, 0xa9efd74f, 0xd4f743cd, 0xf01979a2, 0xbc541fe7,
+ 0x79373f88, 0x674eb77c, 0x89cfa9bc, 0x3f348817, 0x62cae7cd, 0x8afbffbc,
+ 0xbdf80f77, 0x56ec2fde, 0xebc2781d, 0x2151da69, 0xc429b6f4, 0xfac8d470,
+ 0xdec1e4bd, 0x5f619f9c, 0xeb0b80e1, 0x5c06f26c, 0xa77f2669, 0x98094bb1,
+ 0xf819fddf, 0x8e3265ed, 0x07d7c758, 0xf5b6efd0, 0x88a5ae79, 0x83dbb25b,
+ 0x746b6ef7, 0x71fa3139, 0x625ef13b, 0x0cbd3e7e, 0x7de7eab9, 0xbe616ec1,
+ 0x4bf8d312, 0x7e69be31, 0xb5fc2f6e, 0x62496595, 0xef2f06bc, 0x2bd00f3b,
+ 0x1074c9d6, 0xcedfea74, 0x3cc4f9e3, 0xe18dee82, 0x7ac55390, 0xf1834ef0,
+ 0x1390dec5, 0xe8dd2cf3, 0x6d7ef117, 0xdb479c9b, 0x862aea92, 0xbaf0e73f,
+ 0x1e7ecc72, 0xb2e41dcb, 0xd1fa970e, 0x0fc2bd62, 0xa53a626e, 0x634cffc1,
+ 0x3173d7bf, 0xf5f41abd, 0x5aa57537, 0x07aec6fd, 0xad4fe09d, 0xf2c4ae7e,
+ 0x8e5d31e1, 0xcabc6e97, 0x08efe845, 0x533ef0b8, 0x6ffde9d3, 0x22b7e36b,
+ 0xfddb523f, 0xf18f3388, 0x4fd265ed, 0x46740c7d, 0x3c3f383c, 0xfa53ef01,
+ 0xf78bc6d7, 0x2edeb5b6, 0x7a21dfb1, 0x81f4c43f, 0x11ade25f, 0x093966f4,
+ 0x535afde2, 0xd1bf95b7, 0x718924f5, 0x841bba9b, 0x68732dfe, 0x1d79af2e,
+ 0xa0985e3b, 0x596a5d30, 0x3f9c15ef, 0xf2172d5e, 0x5ba1e673, 0x793ec573,
+ 0x9273a09d, 0xd8879bea, 0x908dcb04, 0xea7e436b, 0x1b3ea54b, 0x932c1df3,
+ 0x65839cf1, 0xbfe9c7c3, 0xb69b4f4d, 0x71005035, 0x15524cbc, 0xd4f5dbe5,
+ 0x5f434fd0, 0x6538f56b, 0xa405b6e3, 0x9f0dec99, 0x0dcf6ddf, 0xdd019f43,
+ 0xf9d62c9e, 0x917cf4c9, 0xf7baf14c, 0xe5d67e74, 0xe31ef55b, 0x7557dc61,
+ 0x139bafbd, 0x28b6b09e, 0xb798deda, 0x83f64d2e, 0x5ece43fc, 0xf682e9d5,
+ 0xdd7b44eb, 0xa376e99e, 0xec6ec871, 0xbb0e94db, 0x79115fb1, 0xa5db75ab,
+ 0x99eeb75f, 0xfadf1124, 0xdf8775f7, 0x9ddb85b8, 0x3d77787b, 0xabac6bf6,
+ 0x44ed2c29, 0xb053fb33, 0x73f4cb1b, 0x7b58b3bf, 0xc7a4cca7, 0xccf77f4d,
+ 0xe2c5e844, 0xdf99ff1e, 0x1877d892, 0x67bde6f6, 0x0cf6f17e, 0x357cf45f,
+ 0xcb74b1f6, 0x3c1b38bf, 0x7dc9ba66, 0x2a5c2d6e, 0x5f8139de, 0x6e357fb8,
+ 0x81de4454, 0xffc25dda, 0x2b1df834, 0xbfac0d07, 0x1ca89e8d, 0xc91ffc18,
+ 0xe50d726f, 0x0dff24e7, 0x60721b7e, 0x13e0dbf0, 0xf9359ce1, 0xffbac6fd,
+ 0xb17bafa0, 0xeb5fbf2e, 0x4578b77a, 0xd0996b9e, 0x23573cf7, 0xafaf5ee4,
+ 0x0f96b26d, 0x643bc9f1, 0x2f4337df, 0x9f247a06, 0x6539b606, 0x45df721c,
+ 0xb9c5ca7c, 0xb963ac6f, 0xd66c6f1e, 0x74cb86e3, 0x94f9983f, 0x6a665e54,
+ 0x53e484f7, 0xffafb3e3, 0x627dcfeb, 0x6d8ed27f, 0xe2fe138f, 0x82fd9ed2,
+ 0x1e5bb55f, 0xbb71e674, 0x7719729c, 0x6df3b21c, 0xe7e22f7e, 0x76ecb78b,
+ 0xca73ff42, 0xe562dd25, 0x077f4ebd, 0xe715d06b, 0xf73a628f, 0x7bb0f68c,
+ 0xf59e79fb, 0xf193e36b, 0x6798c6ae, 0xe394b95e, 0x34d4b6c6, 0xd6d8d7cc,
+ 0xabdc03f0, 0xab1fbb0c, 0xa5e3a777, 0xf1e52c3e, 0xafa797a0, 0x15d77352,
+ 0x332f9c5d, 0xc972ace0, 0x79311fb7, 0x3b258ef1, 0xe227e7b1, 0x049ac41d,
+ 0x82e5f915, 0xf3084882, 0x6eb18e42, 0xbc45db17, 0x89682987, 0x14758a7c,
+ 0x02ff7c90, 0xf3269498, 0xef8ce91f, 0x305765e1, 0xd84bb7cc, 0x2107d3a8,
+ 0xe8d3d434, 0x1ff61948, 0xf246b76b, 0x34f90c2b, 0x53b589c6, 0xc96fed23,
+ 0xe9dfdc77, 0x525e3d3c, 0x79bae6a8, 0x4e1ffade, 0xfa3f1152, 0x12ba7db6,
+ 0x6869be64, 0x15ac2cbf, 0xb7ecc369, 0x4683de40, 0x55776fde, 0xbdfb30fa,
+ 0xebac0f28, 0x7bd6f189, 0x25d23f28, 0x15a723f3, 0xdfb8b73e, 0xe2f1b5e9,
+ 0x2fb199bd, 0x5dff3e23, 0x9477e7df, 0x8b71e9a7, 0xc9fc1248, 0xff5d04ba,
+ 0xf94712c3, 0x71b95302, 0x46f49fde, 0xf64cd292, 0xfd36c3f9, 0x76c8a43c,
+ 0x1f6f8311, 0x9c73884f, 0x649d3aec, 0xca7c822b, 0xd6fd19f5, 0xed93d53b,
+ 0xe29b73b0, 0xf66efbc4, 0x8e23369b, 0x154c1cd4, 0xdadb99f1, 0xe0eccf4b,
+ 0x98db6e71, 0x5ebf0aad, 0xe997f3f7, 0x7d712ff6, 0x6869e6c3, 0x0bcf23bf,
+ 0x53d9be3f, 0x2dfc42e3, 0x2b817bb1, 0xf2bdf85f, 0xabe4601e, 0x03542bd6,
+ 0xfb0e5bfd, 0xbdb2bd08, 0x66f38050, 0xffe90ef9, 0x16d1b7cf, 0x75c73be4,
+ 0x82cbccd6, 0xa8a9d87d, 0x176927f0, 0x7ee351db, 0x6923b6c6, 0x72cecd4a,
+ 0x962bebd0, 0x32ff1e3b, 0xec76b19c, 0x7b8027a7, 0x817fb127, 0xa03d60fd,
+ 0xb4b9564b, 0x4fbb278f, 0xa28af925, 0xbf53fcf4, 0xc2e4317f, 0x23359bc8,
+ 0xf20a33ee, 0xf90e9751, 0x63f3d268, 0x0ae7bb9b, 0x4df779bc, 0x4e973be2,
+ 0x647be634, 0x0f5583d3, 0x733e5907, 0xb5347a75, 0x7e01bdce, 0x713d8ad1,
+ 0xe35ee2a9, 0xfd9ae60c, 0xf7dda6d0, 0xce5eef8b, 0xdf178eee, 0x177a54bd,
+ 0x3ef2a654, 0xf54aed97, 0xc2e74ddb, 0xddfeba2b, 0xf2d73ad1, 0x8f334afd,
+ 0x7ff1e5e9, 0xde2893df, 0xa5df192f, 0x8ed6e55c, 0xfbe34ec1, 0xf93ee994,
+ 0x68964a5d, 0x3e361bef, 0x1d33c06f, 0xd3073bf2, 0xd4373677, 0xd696ff72,
+ 0x6718c903, 0x956f43d5, 0xd7108533, 0x1a7c037a, 0x8766cefa, 0xf9a6cefc,
+ 0x77bfe1a1, 0x3e435c81, 0x4b211c57, 0x50b6f17e, 0xb543f08a, 0xef90b930,
+ 0xfc24bcd6, 0x6a76b3dc, 0xf86eb9c7, 0x44794625, 0x94d9c3a7, 0x7ff05cae,
+ 0x7247dee5, 0x9c7c6e71, 0xbdbaf124, 0x7612feb7, 0x4e327b48, 0x120edffa,
+ 0x50636dfe, 0xf7c6cbfa, 0x1baa4453, 0xe573f0f7, 0x95bc6289, 0xc63877fa,
+ 0x10bfd8ba, 0xa83b1fe5, 0xf7c0eb1a, 0x77e79035, 0xf066e11d, 0x47f65df3,
+ 0x4578ef91, 0xbb77bf97, 0x7bc4f3ec, 0xf8045622, 0x1d76ef15, 0xd11e4248,
+ 0xecaac3f0, 0xf0ec05ef, 0x7e290e97, 0x4589c39c, 0x863dc427, 0x6ac978f4,
+ 0x75b794af, 0xcbce733f, 0x2afc2d1e, 0x08e2d251, 0xd7e386bb, 0x34dfba1d,
+ 0x2fdc1f84, 0xfb2d65ee, 0xd2d05fa4, 0x05f84a73, 0x7c619f86, 0xdf6ab747,
+ 0x1827e129, 0x941f56fd, 0x283d6974, 0x6d0a1bcb, 0xa025bc46, 0xacbee014,
+ 0xd9727c08, 0x38364bfd, 0x25e6f8cc, 0xbd000a1b, 0x5fa43c7a, 0x0b5be5f8,
+ 0x33ee257f, 0x71f51bad, 0xe69a7719, 0x4636994b, 0xe5c5c77e, 0xefe83de3,
+ 0x5adfdcb3, 0x50fbca0f, 0x8b6135b8, 0xdabb1778, 0x6cec00e3, 0x7cf388f5,
+ 0x10ad9b57, 0x4a03c9ef, 0x8ee7f082, 0xc6b9efea, 0x3c4dfaac, 0xd45904e2,
+ 0x13cb6bdf, 0xa7f2b8ef, 0x14193cf1, 0x8cbaef14, 0xfc2e67ef, 0x18a547e3,
+ 0xe45c767f, 0x97802200, 0x096c7b4e, 0x53b325f2, 0xf8a0a522, 0x951f87a5,
+ 0x00e44678, 0x60de50e2, 0xe9ca92f7, 0x695c467f, 0xaf8962be, 0x6568adbf,
+ 0xe0eb4120, 0x6b8c9779, 0xfe7c8bf4, 0x8e52698c, 0x7be31cc6, 0x5f51ee24,
+ 0x303dc478, 0xf89b5463, 0x228a8bae, 0x147768a5, 0x823e587d, 0xf084265f,
+ 0xc93c8c3e, 0x983ccf32, 0xa8ef121f, 0x30df32dc, 0xf02e9fd0, 0xb431ce30,
+ 0xda2dd4ff, 0x5dd1cac7, 0xa0fde4d3, 0x63e64e26, 0x399c546f, 0x9b9300ff,
+ 0xfa0b5da7, 0x8bdbe4d5, 0xdef1e3fd, 0xbf03be4e, 0x0d6de7a0, 0xbe8e797f,
+ 0x9efd1caf, 0xd324bae7, 0x0253fd03, 0xe5ddf101, 0x1ac7457d, 0xfd03ff31,
+ 0xd0fe426e, 0xa738c778, 0xabde413f, 0xe716a92e, 0x5073e2ab, 0x563fb71d,
+ 0x1de30b64, 0x16e403ff, 0xc7726579, 0x78b6d9f8, 0x395b1ef1, 0x3817cafa,
+ 0x9fedb267, 0xfef0a6f6, 0x5152ffb3, 0x07eb8361, 0x26f63cce, 0x3dc1bac3,
+ 0x7d8fb1fb, 0xf6235ac9, 0xfaa07271, 0x7e24c694, 0x56e3dbc0, 0xe645f9e5,
+ 0xfbbd1ff5, 0x5b34e48b, 0xfa175d74, 0x78733ccf, 0xc45ba02a, 0xb51ce7a5,
+ 0xcc5638cb, 0xfa642e7a, 0x6e70bbc4, 0xc17ee827, 0x5ee10b63, 0xef68e738,
+ 0x1cdf583b, 0x7dc677bc, 0x6f3cedc1, 0x97c8e73e, 0x1af78a93, 0x64df9d30,
+ 0x1ac0ed47, 0xef4a3cfd, 0x0579bdf4, 0xed57c9ce, 0x73037884, 0x963ff052,
+ 0x1fc16f7f, 0x699ce3c1, 0x2a36def2, 0x4d3826bf, 0x072863e8, 0x3ed338fa,
+ 0xd0b53bfc, 0x638f4534, 0xfc1a7e49, 0xf063f832, 0xdd33a0c3, 0x14a5e270,
+ 0xf8b7d045, 0x3fae9287, 0xe2fd7410, 0x4b5626f8, 0xd70fe4ba, 0x7ffefa0a,
+ 0xfbc8eba3, 0x0d85df93, 0xde1eefed, 0x7f659e5f, 0xda5ffd3f, 0xeff7d09f,
+ 0xd613bfbc, 0x8677a5fd, 0x4e4127e3, 0x7f09b21e, 0x28bdf62a, 0x97b09215,
+ 0x1104f6f5, 0xe412d537, 0x276c06f7, 0x349d825f, 0xeab8e3ec, 0x8afc3148,
+ 0x638f4493, 0x8f5b115d, 0x5a78ff28, 0xb19390be, 0x7c4b2274, 0x9488e137,
+ 0x54ed6fc1, 0x76dd3b02, 0x8733c8c0, 0x7a565f61, 0x42edde44, 0xf27416c8,
+ 0xa1a9ddf8, 0xde78cb9d, 0x448b9bee, 0xd102e51e, 0x1f382394, 0x7f082457,
+ 0x84953bb4, 0x9daeeadd, 0xe796fc28, 0xc2e7b6bf, 0x4dafed5f, 0x6edbf910,
+ 0xfc3b647f, 0x3e09eecf, 0x7f4dc835, 0xf844d0a1, 0x6e05c1ab, 0x02f74f31,
+ 0xb7bb0769, 0x83f7c8e7, 0xf209fa14, 0x48ae8f48, 0xeec17910, 0xc42c81dd,
+ 0xd24c3ecf, 0x2e1f434e, 0xb873cbb1, 0x19cb8f3b, 0xd4d4ac3e, 0x62bc6336,
+ 0x6d48eeb9, 0x797bb3c2, 0x3602f894, 0xb27e5c99, 0x6be4493d, 0xe2317d0d,
+ 0xa782e3d5, 0xc64e8276, 0xebefb677, 0x5dd065f2, 0x0eefc809, 0x721bfa0d,
+ 0xbba75a36, 0xb794af72, 0xabc7f7a1, 0x1e3fbc49, 0x77c04bcb, 0xaa71f56a,
+ 0x32be740f, 0xeb12fb45, 0x7ccb5cee, 0x92fd63b1, 0x1df127fe, 0x95fe30e1,
+ 0xd38f42b3, 0xd45fdfe8, 0xf523b493, 0xed16f7c6, 0x282defd6, 0x79153632,
+ 0xdc47213b, 0x9abef7ff, 0x8dd80ab8, 0xc125df82, 0x4fff1c6e, 0x80efb0fb,
+ 0xbcf215bc, 0x296bc4f0, 0xfdfebda2, 0x1f5fe189, 0x83947ff7, 0xdde4e273,
+ 0xfc058caf, 0xad26a92a, 0x70f5d782, 0x70f3e7ed, 0x159fbd74, 0xbccddf11,
+ 0x8e65fb5f, 0xfbdfb788, 0xeff7908a, 0x02ffceba, 0xb38b7a5f, 0x000040d0
+};
+
+static const u32 tsem_int_table_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33b3af8a, 0x21716830,
+ 0x9f0143f8, 0x38606664, 0x8167c40d, 0x81859798, 0x818997c1, 0x78898fc1,
+ 0x10c533fd, 0x0611416c, 0x5e203b06, 0xf0c0c42e, 0xce21044e, 0x10c0ce28,
+ 0x20c0ca2d, 0xafe10a2b, 0x6266d204, 0x40ff71d4, 0x4c194663, 0x089207b1,
+ 0x79161336, 0x268ccc64, 0xca8520ef, 0x7fa02167, 0x2517f1a0, 0x22acbe54,
+ 0x8a846e84, 0x9793457f, 0x432bca83, 0x094df5fd, 0x502ab9bb, 0x1aa00079,
+ 0x03605f82, 0x00000360
+};
+
+static const u32 tsem_pram_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780d, 0x733ee8b5, 0x49999cce,
+ 0x21264cce, 0x61021309, 0x40a02092, 0x200c7e18, 0xf7f09d78, 0x803aa568,
+ 0x07515a56, 0x43f21081, 0xbd1f5202, 0x24266bed, 0x1bd568c1, 0xab45a8fa,
+ 0x68a90076, 0x62348ed1, 0xa80740a8, 0x0db6a85c, 0xc7f42ad6, 0xc405ad1b,
+ 0x96aa4490, 0x6bb94abe, 0xe64fbdad, 0x4019939c, 0x6f5fb7bd, 0x6fd697bf,
+ 0x67d9cfb3, 0xdfd7b5ef, 0xb5ed6b5e, 0x897628f7, 0xec650ee5, 0xc75dfe02,
+ 0x319902d8, 0xf4a27576, 0x0d0ebbc1, 0x07f8adfe, 0xccdd2832, 0x2862b12f,
+ 0x2f6e2cfd, 0xfc707281, 0xd65e9618, 0xf37e18c9, 0x959905f1, 0x3271e632,
+ 0xb09417f1, 0xdaf2f5ee, 0x6d87b2b7, 0xd5b28428, 0x6cc653f7, 0x67aaed8c,
+ 0x44f66181, 0xff57873b, 0x91c17e2e, 0xfa4870cb, 0x877560cb, 0xbb87c187,
+ 0xb6e2e7a4, 0x8ef58c89, 0x7e2d8161, 0x5dde0718, 0xcffd059b, 0x316dec61,
+ 0x704605e6, 0x8a50b85c, 0x4b8231df, 0xe73af8fb, 0x0ee76842, 0x00c55fad,
+ 0x7334cf5e, 0xb9a26d7b, 0xf50d18ee, 0xa5fa8991, 0x6ca603da, 0x881de00c,
+ 0xed5c03f0, 0xd79a4ef5, 0x81bdeb8f, 0xb6305761, 0xf547dea7, 0x2a7ef57d,
+ 0xe923f5e3, 0x00fa81f9, 0xb05873d5, 0xeac7f090, 0x66ca2c36, 0x8536f1ac,
+ 0x7412c7dd, 0x8c3d66f9, 0xfea24577, 0x222cd1a7, 0xa4fee4c3, 0x00423bb0,
+ 0x132bc36b, 0xbca13a32, 0x7f41db1f, 0x28018d0f, 0x3fda26c6, 0xdce5f6bc,
+ 0xcb181399, 0xdc91eafb, 0xbde00399, 0x46c616c4, 0xd2ad78e3, 0x9df031bc,
+ 0xdbd1fbca, 0xeb6325eb, 0xed9a0f88, 0x65afdfc9, 0xf2cf0212, 0x7e60ac0e,
+ 0x0f6bf437, 0x07013be7, 0x04c644b7, 0xb8c3065b, 0x186bec48, 0x111b32fb,
+ 0x370e0089, 0x8c799761, 0xf342d0ed, 0x5f1cbbf0, 0x91230a48, 0x299c40c3,
+ 0x2cab658c, 0x470a4b1c, 0x2b71c103, 0x4b0733fe, 0x0f4bd53f, 0x7ef571f2,
+ 0xe711b2f4, 0xcee4e507, 0xde2c5b30, 0x77fbe197, 0xe862d242, 0xe7c5d9bf,
+ 0x736302f3, 0x1249bc70, 0x12b9610b, 0x2dfa1299, 0x312732c7, 0xe5c60aee,
+ 0x6173bae1, 0x547e8416, 0xc785985f, 0xfc837ef0, 0x6c8ca6fb, 0x1b7f9b9a,
+ 0xda9443f1, 0x474ddb1b, 0x88b6fcb8, 0xedc7033d, 0x23ed883d, 0xf6c3163e,
+ 0x39b6682f, 0x3b44b45b, 0x6e499e1d, 0x968b685b, 0x16c82fe8, 0xe5d3fa9b,
+ 0xbe72764d, 0x81def9d3, 0xda9c809f, 0xc228fbe1, 0x3705983b, 0xbdebc127,
+ 0x07a5be62, 0x3c06415d, 0xa3542ead, 0xafa9242e, 0x39eb0cb5, 0x0640594b,
+ 0xe5eb4e1a, 0x0703b8f3, 0x3bcc49c9, 0x37c003e7, 0xfec01d94, 0x08e3e60c,
+ 0xda03a8b0, 0x826b79ab, 0x1f4f5065, 0x1b02d5cc, 0x3672631c, 0xcdc473c9,
+ 0x97a1c3fa, 0xfc13c7da, 0x00df1748, 0x0604ef5d, 0x41dba832, 0x78020ca1,
+ 0xa83b8f1a, 0xe5dc8fff, 0xfd33b143, 0xf1f553bb, 0x3e414b71, 0xa61fd74e,
+ 0x83beabb2, 0x63faeeca, 0x0f1aa654, 0x26c6d124, 0x60df8c03, 0x5dca2741,
+ 0x075d12a1, 0xffee37fd, 0x218ff32a, 0x878823f8, 0x2d16cd74, 0x4e665e42,
+ 0xf815cd59, 0xe12b7c45, 0x8e6ef9bc, 0xbdb3c45f, 0x866d0950, 0x2ad9cf32,
+ 0x786d1aad, 0xfc40740e, 0xb87c1e97, 0x2ea4f101, 0x855ce365, 0x4f9c2f28,
+ 0x97c89f11, 0x5f381abb, 0x284efd62, 0x029539af, 0xef1c5def, 0x53a9dada,
+ 0xc06099df, 0x5c82c29f, 0x28bf39ae, 0x78c77ff0, 0x7b343a80, 0xbde82645,
+ 0xbc077fbc, 0x9e7d268e, 0x906b95c1, 0x9e2adea1, 0x30ddebac, 0xabd27e23,
+ 0x5079edc0, 0x97cfac1f, 0xf8897ff9, 0xfa04dcd8, 0xd57eeb09, 0x21fbc2af,
+ 0x70e0f5a2, 0xca545cc5, 0x1ee7cb5b, 0x62bc6092, 0xa8fde3f9, 0x29d487de,
+ 0xf41a776f, 0x6042c165, 0x86c622bc, 0x2f3f35ae, 0x30eb988c, 0xf3042d80,
+ 0x3f316e2f, 0xd9dcce3f, 0x2e19d227, 0x80906e48, 0xbd5af37e, 0x849a45ec,
+ 0xf58dde95, 0x0dd9ae2c, 0xf427a175, 0xdc99e4ba, 0xadf98119, 0x900592be,
+ 0x449269c6, 0xefc56c78, 0x141e8f80, 0x7e96fde5, 0xac9952f4, 0x02ef50d9,
+ 0xf4c983de, 0xd654be58, 0x56bc748b, 0xfd8bde9a, 0xe6312ba6, 0x54bf90d5,
+ 0xfb6b13e2, 0xf1a14934, 0xa08e94d3, 0x14deeb8c, 0xb6adeebe, 0x9e51c6f7,
+ 0x03f99756, 0x028f5c11, 0x4cdf9251, 0x5e50b358, 0x363c013f, 0x9363c389,
+ 0xf5189c68, 0xdb2beb03, 0xbc38e122, 0xfa57d5df, 0x0d4a4459, 0x2d191fe7,
+ 0x1698ec62, 0x3cfec4ce, 0x709ca492, 0x58d3e826, 0xb36ff451, 0xc372eaa1,
+ 0x7513abfb, 0x7c739ddf, 0x4379c7c8, 0x772bf4cd, 0x7f2015d6, 0xb3628654,
+ 0x7a4e7f91, 0x0edeba7e, 0xf602def3, 0x9ff80282, 0x61e50ce4, 0xea8b353f,
+ 0xf30aa386, 0xe303a2e3, 0x1eb7b26e, 0x39824b07, 0x5ff48859, 0x0175cccb,
+ 0x67dbde05, 0xf03b712a, 0x01f27da5, 0xac5c57b2, 0xc9c7eb8e, 0x07b43291,
+ 0xef83239c, 0x455ef0ca, 0xdee78079, 0x75c32b60, 0xbccc39c4, 0x9b3c83ce,
+ 0xb9b64aea, 0x5ccf4a9e, 0xf8ca5caa, 0x84069efa, 0xb267fc22, 0x995fe228,
+ 0xf841281c, 0xf3e6bc1e, 0xaa67847e, 0x84a5d7c4, 0xde72e2fe, 0xbfb5ef47,
+ 0x00361dc8, 0xf972b79f, 0xee4afb5f, 0x8f8809b0, 0x73979a56, 0x0b926ac6,
+ 0x7323f115, 0x13b90ff9, 0xf878ebdf, 0x961bcf7b, 0xf4979a05, 0x5027f393,
+ 0x6f3e363f, 0x9f9ea3f7, 0x7e3dbcf1, 0x366bd41d, 0x6df7a44b, 0x9f845cfb,
+ 0x3d7947ee, 0xd88356ee, 0x5013ccfe, 0x3ad57c07, 0x8a9c1e3a, 0x665e7bf8,
+ 0x0b3d085b, 0x4ecfa86d, 0x3b68f6e8, 0x78bb97af, 0xfef366b5, 0x8afbf1db,
+ 0x7d430776, 0xf97bb35c, 0xbea1530d, 0x619db0fc, 0x0d6d9a93, 0xafa820ea,
+ 0xac314a88, 0xf4e74cf7, 0xa392ec89, 0x8f7da0db, 0x66f723a7, 0x271dd70d,
+ 0xb8008ff3, 0x37b91ddd, 0x46571f01, 0xdf8d9b9f, 0x0290ee55, 0xc7983140,
+ 0xf07943b6, 0x5253cd5d, 0x5c7c01c0, 0xf99d3db5, 0x89e5f60d, 0x1d7e3936,
+ 0x93cc19ca, 0x59cbbf41, 0x4fa46ceb, 0xaa0db6cd, 0xd39f40df, 0xdf9923f5,
+ 0x3cd7a891, 0x77c0e305, 0x02959f2b, 0x3695c538, 0xef753f6e, 0xaadc2d76,
+ 0xd41afce1, 0xd79c6ee1, 0x5bb62a3d, 0xcbbc5d1e, 0x36f847e5, 0x7de1b3ab,
+ 0xd59ba3e5, 0xa85e8372, 0x640a3eda, 0xa6d700c9, 0x24e181e2, 0x0f01237a,
+ 0x8953c133, 0xedd6867a, 0xa5768aa8, 0x2daa7cfe, 0x6ab1f893, 0x5fea6cbb,
+ 0xd7e47ba7, 0xc887ec8c, 0x55e1375e, 0x2f6adba7, 0xa08eebe3, 0xa0af59db,
+ 0x6a5bd2a3, 0x1f2f5fec, 0x50383a44, 0xfca97b5f, 0xca8fbd56, 0xa27ef58d,
+ 0xbf8843cf, 0xc64edc11, 0x97d760e7, 0x827b2f21, 0xc3ec0bcc, 0xcb06e6b2,
+ 0x0acf50ec, 0xa2ee7af1, 0xc8bfe4b0, 0xec12f5fc, 0x04e0c5de, 0x7afdfac1,
+ 0xf63b0150, 0x8abc3521, 0xa6fc6005, 0x04ce08ff, 0x528ff77b, 0x4afa8638,
+ 0xb82b85b6, 0x287cc5dc, 0xfac5eb77, 0x13f25db3, 0xa9e7d61e, 0xba1f6fa4,
+ 0x2cab74ad, 0x6366b989, 0xf7fbfcbd, 0xbb3f5215, 0xfa151fa9, 0x3f74be29,
+ 0x364fb7b9, 0x7b7b93f5, 0x01cfde85, 0xf2ed27ea, 0xf6e879fa, 0xdcf0cc6b,
+ 0xf3f7a95e, 0xb9e3f532, 0xdee579bc, 0xcf0ccd31, 0xcfd4d51d, 0xd20145c0,
+ 0x3fceb2b7, 0xb43bd60c, 0x8e647717, 0x5341fa37, 0xc0dfd36d, 0x520dc5f5,
+ 0x8ca3e465, 0x792669c9, 0x99660cca, 0x0ce603ea, 0x09cfb532, 0x0fde9915,
+ 0x8595785c, 0x89ef352f, 0x408ea251, 0xf68b43a1, 0xf49520f1, 0x2720d94e,
+ 0x20f77fc1, 0xddcef48d, 0xe04784d7, 0xa2b08e3a, 0x1ab7737f, 0xea4deb1e,
+ 0xcc4874c7, 0x86dfa587, 0x3dfdf5a5, 0x9e9c1ec2, 0xb7f0f1ff, 0x5b5afbe0,
+ 0xa84cf0ef, 0xfb2b6bbf, 0xbcf9e233, 0x3269ffd0, 0x6976c3ab, 0xeffa460e,
+ 0xadd2c29e, 0x5b5e0311, 0x48bf0086, 0xec5b7e89, 0xa3f21f61, 0x901a9364,
+ 0x510fd73f, 0xfa041b19, 0x1fdb1d74, 0x9ee73581, 0xc43ee521, 0x2ffd03bf,
+ 0x8c2af8e3, 0x77c69a3f, 0xb77c60d8, 0x8ef8f92d, 0xf1a6c9a2, 0xa615059d,
+ 0x8c2a9df1, 0x6991f20f, 0x9df18973, 0xad6617e4, 0x8ef8d273, 0xff1a0a82,
+ 0x9855951e, 0x1beb4fc6, 0xc60da07f, 0xfee3621d, 0x17f9bf4a, 0x7f9e635d,
+ 0xfe79a541, 0xa17f9f2a, 0x9f8c532d, 0x5a2ff346, 0x2ff3e5e7, 0x77f3e4a8,
+ 0xc6fb7ef0, 0x7fe1f4f7, 0x263f8e04, 0xe28ef8c5, 0x0ff9e669, 0xdfcf36ad,
+ 0x671fc7c1, 0x6be313cb, 0x75f8fe34, 0xa1ff3e3e, 0xeabe34d5, 0x8f900708,
+ 0xbab4fcd4, 0x8343da28, 0x240dfb41, 0x72a4181d, 0xbb93f724, 0xe38222a4,
+ 0x77ce34ee, 0xbf01a51f, 0xca7d0969, 0x9e29eba2, 0x74f052b2, 0x35328ed5,
+ 0x07bc5a3c, 0x00997f7b, 0x4cbb6975, 0x3a36cd7c, 0xbc0057a2, 0xf932eddd,
+ 0x5e374b3b, 0x3d69951b, 0x1808fee5, 0xfe7c7190, 0xd98f6fc7, 0xb5979c62,
+ 0x3f6ad65c, 0xab9069d1, 0x9d3efd3e, 0xf803ac8d, 0x535e4836, 0x69e804fd,
+ 0x06dea674, 0x49e58c7d, 0xf3c0338c, 0xb38f4077, 0x7ffdfd11, 0xd1b5eee8,
+ 0x0a2faf30, 0x1c284ff8, 0x48d627df, 0x47ffc451, 0xa8a9561b, 0xa6b596cf,
+ 0x07d3d1a3, 0x53a0ad47, 0xd9076eef, 0x3f4f8055, 0x1216e7e2, 0xbf7ec645,
+ 0x24870bef, 0x6f967bb0, 0x6efa601a, 0xfb368b11, 0xfb92fda0, 0xc2f10f17,
+ 0xe85d6ffc, 0x1f932f18, 0x91b7cc18, 0x1b7cb31c, 0xdb0b4ef8, 0xa1f3d836,
+ 0xbb42cb72, 0x52f94fc9, 0xb5bf5cd8, 0xb6ef5cc2, 0xcf18ed47, 0xb1215eea,
+ 0x6defd0cd, 0xff8b7675, 0x6159c7c3, 0x08f112cb, 0x8117de3e, 0xe8f07986,
+ 0xe3c72c36, 0xf5d12f63, 0x56ff2f76, 0x6bf6a787, 0x90547076, 0xe8399d7e,
+ 0x0e48b347, 0x2f6177f9, 0xde15b79f, 0x60ceeddb, 0xfdb9e008, 0xd3e132ab,
+ 0xbee77f0a, 0xec0da0f4, 0x7f4dced1, 0x6e7da3b2, 0xfe158f9d, 0xe75ad63b,
+ 0x7d7155e3, 0x3eb11c58, 0x5aec988f, 0x2f6dacbd, 0x818efadb, 0x9f626a9f,
+ 0xe18efadb, 0xf3edaabb, 0xd115f54c, 0x2fda992f, 0xf4d8b4df, 0x0aeb597e,
+ 0x2d25fbd3, 0xc5f54cab, 0xda9aaf91, 0xc1b6b1df, 0xbab6fef4, 0x6fef4d7b,
+ 0xaa60d8ad, 0xb0fc297f, 0x0b2dfda9, 0x4bde9b37, 0xed0c56fb, 0x1e1abd24,
+ 0xeb76879a, 0x59f90771, 0xf2ebbf3a, 0x16ec0a70, 0xdd834f2c, 0xca036582,
+ 0x6dbfc829, 0xb76b2f37, 0x35ea1e2c, 0xed2761f8, 0x4f280575, 0xe2b7be56,
+ 0xf0dfcad3, 0x1d6c9f97, 0x8c6acbd2, 0x3dbf4143, 0x24393f16, 0x1f1ea0f4,
+ 0xdcb956ac, 0x9bccef56, 0xb57ffe8e, 0x975e1f1a, 0x93ec4fc4, 0xf34498e7,
+ 0xe7a56860, 0x5b80dd20, 0xdaab780d, 0xb3826c5e, 0xe34cbf6b, 0x05d944af,
+ 0x0a5f37fd, 0x88f5c71d, 0x2c160fc5, 0x04f08318, 0xf6f5437f, 0xbb7f5a1c,
+ 0x7d6ce7ea, 0x0bf88ec7, 0x7eaa7951, 0xea279521, 0x53be54c3, 0xdbe5415f,
+ 0x765475f5, 0xf2a5afd6, 0x9508facd, 0xa16fabbf, 0xadf537f2, 0xdfab1e54,
+ 0xf5ebe544, 0xebbb2a51, 0x7cea5483, 0x4327a7db, 0xfe156ec2, 0xb7224805,
+ 0xe45cc55b, 0x96b8bedc, 0xacf1e50f, 0xb470d1f6, 0x031ecfcb, 0xc6a61722,
+ 0x521f9597, 0xc90595e2, 0x028f28ae, 0x7ff4079d, 0x74e34aef, 0x1cd8d972,
+ 0xdee37a06, 0xc01fbe2b, 0x15d41338, 0x47df8596, 0x49dcf303, 0x107f05fa,
+ 0x3a2975e9, 0xc96f60b1, 0x89c7a07c, 0x8a5afe47, 0x456c86fd, 0x28385edc,
+ 0xe2c97ad3, 0xaf48035b, 0xe9378a4f, 0x402fbf27, 0xa39339b9, 0x00a3afe3,
+ 0xb2df04e3, 0xb39fa979, 0x20a60e6d, 0x47a4f71e, 0xf67d2431, 0xae0f56f0,
+ 0x727dab77, 0xb31f18d4, 0xc2b13596, 0x4f9866a8, 0x7eb9bb6d, 0xc39a55b6,
+ 0x8cfe69e3, 0x5f20c69b, 0x50efa379, 0xa547d15c, 0x9f6acfde, 0xfee8e34a,
+ 0x4991db38, 0x217e0a7c, 0x86affbb5, 0x093f5523, 0x1fd8da38, 0x2e287700,
+ 0xb93f8a17, 0x0f94ce5f, 0xb1bb8c54, 0x708ff63d, 0x7fc0773d, 0x6591d017,
+ 0x7ef5d50a, 0xc472636b, 0xef9f1631, 0xdf078d30, 0xfb9f75f9, 0xf8c5d142,
+ 0xf4276155, 0x9b6a8279, 0x0e443e8f, 0x6a2b95f2, 0xa699fbd6, 0x5e7b6d7a,
+ 0xe00eb4d4, 0x59ee403f, 0x3ae0a485, 0xa8b82d58, 0x245ad147, 0xec8c6f80,
+ 0xf126fce7, 0x4ece3576, 0xbe47ec35, 0x54e2fc69, 0xa56cb63f, 0x3be15af9,
+ 0xabd87f5d, 0x5c7e245c, 0x3bbd9f25, 0xffc8bed9, 0x48bef996, 0xd3db8db5,
+ 0xa0f119cc, 0x117ccabf, 0xe18bc60f, 0x0fc3eb4f, 0x8e304df9, 0xb3f7aea1,
+ 0x4def6a22, 0xd9764eb6, 0x1d6c9db8, 0x7b8c45b7, 0xdcadfc29, 0xce367471,
+ 0x95c78adb, 0xb4abefed, 0xffc0a31f, 0xd478134a, 0x0e463bf1, 0xdfc0c8b5,
+ 0x22dfdb95, 0x3d94f27b, 0x176bfc32, 0xe1fd5bd1, 0xb7147cd7, 0x611de7d5,
+ 0x9dce381d, 0xff67f17d, 0x7585bf2d, 0xed97ddf1, 0xf62cbe3c, 0x70387437,
+ 0xf506d0d3, 0x6776a225, 0x9bc5155b, 0x3d75dddf, 0x594b6fd9, 0x644e83c8,
+ 0x452d6b05, 0xb30cf03b, 0x9d3c41cd, 0x267aaf61, 0x43b4e818, 0x974e4956,
+ 0x10ed98b4, 0xf54d5fb0, 0xf5cc9be5, 0x173f3672, 0x46f94cf5, 0x344a8b3b,
+ 0x47fbd33f, 0x7fe12f65, 0x8f5bab39, 0x9da373eb, 0xe9ddb3ef, 0xe83e4a65,
+ 0x1e179adb, 0xff38c52b, 0x7ebe648f, 0x1593f1ea, 0xab8edc59, 0x31566d8c,
+ 0xb687ffbe, 0xca9c5f09, 0x7ae8fbf0, 0xcf221f5c, 0xfe6d814b, 0xa4fdf8fe,
+ 0xd5e15bf0, 0x717eefd7, 0xcd47011c, 0xbc692976, 0x892cbf77, 0x63f39ff5,
+ 0xbaa5e286, 0x5be7d76e, 0x22c9afea, 0x19332c1e, 0xebc67ee9, 0xe832d88c,
+ 0xf38e207d, 0x3408e9db, 0x72c2fcc2, 0xf64c98e8, 0x1984bc44, 0x30e585da,
+ 0x5e92ef3d, 0x93bb4729, 0xb412f129, 0x21ed6123, 0x3f05553e, 0x129e69c8,
+ 0x31bb778c, 0x67718bbe, 0xd60b6797, 0xe62bbbd7, 0x16b51c62, 0xf7f401f5,
+ 0x61f66780, 0xb2709fdc, 0xf81078d6, 0xef33e1d7, 0xe6fcb82f, 0x75ea3a7a,
+ 0x00f877d4, 0x8c02f9f7, 0x23e954e2, 0x01dcedcd, 0x1f6cfd73, 0x5f7ce29e,
+ 0xf71c589c, 0x0cb8b5c7, 0x4ac9b3e3, 0x54bf9f57, 0x871afe84, 0x5a64ec1f,
+ 0x7978d6ff, 0x7e2295fb, 0xf4f8e6bf, 0x89175981, 0x939ed547, 0xceb0d458,
+ 0x2abd2ad4, 0x39ed61f2, 0x6a7f9e85, 0xd587eabd, 0xf357a0d6, 0x929a70e5,
+ 0xc228f5c3, 0x6138c127, 0xe3809f03, 0xf9ca35ea, 0x7c3f0b08, 0x99b2386a,
+ 0x918fbf49, 0xe0c9f9c3, 0xfbfdd4f8, 0xe23ff5fa, 0x61ffb4bf, 0x909ffafd,
+ 0x179affac, 0x8115d99e, 0x87f2a2f5, 0x3300f6df, 0xd69577b3, 0xbdd000dc,
+ 0x07b35b7a, 0x1294f2e5, 0xdf5d20f1, 0xa273ca8d, 0x52a1f849, 0xa82ef9d1,
+ 0x3fc4a549, 0x9fa747c4, 0xe80de6fe, 0xcdb47fc7, 0x7eff25ee, 0x00ee23bb,
+ 0xb6d95ca6, 0x76c7cb82, 0x7ebc5bc7, 0x9fc8fbcf, 0x7d66edb5, 0xb7e4f951,
+ 0x7eb4fd73, 0x1bff8445, 0xe561ff27, 0x8d9c7f13, 0xeb2d58f6, 0xfd67bd25,
+ 0x973fc70e, 0x62c2f645, 0x7bffa335, 0x56b21f7d, 0xedb6a5e0, 0x3ee3ef9b,
+ 0xe7db6d44, 0xe9a1724e, 0xfad1bf24, 0x07f0855d, 0xd9dc556e, 0xc49baf14,
+ 0xe9bf2126, 0xee516178, 0x3c2fc80f, 0x9cf18256, 0xf65e27ae, 0x7c8da348,
+ 0xd9dff5ca, 0xfdef92d8, 0xae5a9fd8, 0x1a3f41ba, 0xcedd6eed, 0x3f0bb7f3,
+ 0xab2f0f66, 0xee0f71ed, 0xb66f541f, 0xf55cbed3, 0xffbf5b33, 0x8e57c608,
+ 0x4057023b, 0xbccf55ff, 0x5035faf4, 0x9ece7aaf, 0x434f973d, 0xf4137293,
+ 0xd6ff85a9, 0xa3d04f8e, 0xa92f47f2, 0xcf8d0fb8, 0xa0959ebf, 0xfb73d54b,
+ 0x3fa63655, 0xf6c4663e, 0x125a9dab, 0x9adec4fa, 0xfc86fe8d, 0xe91579c2,
+ 0x893eeeff, 0x824c2c0d, 0x912fcdcf, 0x22788cdd, 0xf57a0a7a, 0xbed2cfd1,
+ 0x7a42e816, 0x6b2f42d1, 0xfe4269bb, 0xa78c5fb1, 0xfb3f7f03, 0xf977dc63,
+ 0x7880238d, 0x2ef678a8, 0xa4e7ce0f, 0xfcf9c752, 0xcc5ce6b1, 0x47b0a8b3,
+ 0xf254bd72, 0x7f8f15e7, 0xf96ff885, 0x52e4afd1, 0xf305833c, 0x443b646c,
+ 0xcb9e70f2, 0xe699bd1e, 0xc4c2ce59, 0xc98f1587, 0xa1f0ff94, 0x973ce6c2,
+ 0x16de4e44, 0x8b727272, 0x4e859283, 0xfb8242e2, 0xd1caaf10, 0x5bcf146d,
+ 0xaf92f145, 0x6c47fbe8, 0x743fd535, 0x2bb57a72, 0x4b0c1fba, 0x9f7f9189,
+ 0xe903a7b8, 0x70487a74, 0x6b81c620, 0xf8111299, 0xbf402e90, 0x0359d1f2,
+ 0x5f989d39, 0x81df1529, 0xcf819ffe, 0x3d877db1, 0x7d312ae8, 0x26142ec7,
+ 0xc6235fc6, 0xd0d3b807, 0x0b993dbe, 0xf99260f6, 0x3d25d865, 0x0cc1d46e,
+ 0x7790667c, 0xdc4fff2e, 0x975de5cb, 0x39bce8ff, 0xd783fef8, 0x77e11cb8,
+ 0x5c00bf68, 0x7ef481f1, 0xe9124dff, 0x278b0707, 0xec27f393, 0xefcdce42,
+ 0xf002fcad, 0xf71eb82b, 0x938e0df1, 0xfb207445, 0x7c237cb6, 0x38abd46f,
+ 0xbf7fa7ae, 0x172f1cba, 0x8af7e0fa, 0xfa100fc8, 0xf5ca3d80, 0x243f6a40,
+ 0x7b75edc2, 0xa08ffbf4, 0x46bc82fc, 0xf6bf28fc, 0xbdffce10, 0xff5f071d,
+ 0x7bcdc832, 0xcd6e5d31, 0xb72ad57a, 0x66af3b15, 0x3df6e4c9, 0xca92c02d,
+ 0x2a4f3c2d, 0xf1275ab7, 0xaf5bdff3, 0xed5478ea, 0xebaabd66, 0xb4f854c9,
+ 0x8acdc9ea, 0xd56af09f, 0x1af7f093, 0x8fcfed2b, 0xfcea1f3a, 0x9a83f957,
+ 0xfa8fa8a1, 0xc3e754f8, 0xf9d53e3e, 0xd13c5fb0, 0xfbeb4784, 0x18dc605f,
+ 0xfbb425f8, 0x81f3b3d7, 0xf87bd5ae, 0x777c2cbe, 0xaf80eb08, 0x5ad37720,
+ 0x1b67e50f, 0x3d4b51eb, 0xb41f6966, 0xf69643d4, 0xcebd4b61, 0xe3ca3ed2,
+ 0x5507ed69, 0x37139f9e, 0x63afb7b5, 0xb1c63711, 0xc714caf7, 0xd79801ee,
+ 0x3b3df7c3, 0xc291a30a, 0x6f5b5e44, 0xf51eba8e, 0xd7b78f59, 0xaf62f683,
+ 0x7aefc78b, 0x4c9ebd42, 0xd6f69d83, 0x71f4991e, 0x49cd9467, 0x05824fe6,
+ 0x64ebf44d, 0xb8f3dea9, 0xddda0f7c, 0x592cde30, 0x718b582b, 0xf2995698,
+ 0xdc369667, 0x8cfcc1e2, 0x37c53d9e, 0xcbe7842e, 0x9b7cc88e, 0xf2541230,
+ 0x29dc7e0c, 0x9a687916, 0xf7c7fb84, 0xec97fd13, 0xd2dd7ee1, 0x73f393fb,
+ 0x5caef8a5, 0xdea2a35b, 0x6dec7f04, 0xde83bee3, 0x96a3c54f, 0x17ae7be7,
+ 0xfdfdcf7c, 0xefcc27ca, 0xb03e22c3, 0x71fbe74c, 0xcff71c6c, 0xae77e519,
+ 0x96777a16, 0x85c6fa3c, 0xc39e8740, 0x39be4332, 0x3a2647bb, 0xf7c1dd9c,
+ 0x3ece29ef, 0x97b5f905, 0xaf8e9df4, 0x118f942e, 0xd750f5a9, 0xfd2fbff3,
+ 0xdea9341a, 0xef92dbf5, 0xebb5d942, 0xb117f0f8, 0x051bc2fe, 0xdbfd65bf,
+ 0xa2e7d8cf, 0x7d9e8d7d, 0xec87da6e, 0x82f3fbd9, 0xb77d61af, 0xf6708023,
+ 0x0973fbec, 0x3acf51f2, 0xb1ea0547, 0x1fdc219e, 0xe7fbdc6d, 0x3f5a4e92,
+ 0x937e789b, 0x67c3fb9d, 0x4df5fcf7, 0x984b1b29, 0xfb07da15, 0xa87f69d2,
+ 0x8a2ec7f6, 0xfdecf5ab, 0xced1a973, 0x59f3acff, 0x7b1bf629, 0x4ee16cdc,
+ 0xef932f84, 0x38bed4d3, 0xe6036b65, 0x57edb463, 0x19fbc097, 0x825f393f,
+ 0x2767b1fa, 0xedba7bb7, 0x7ee38f9d, 0x2fed77da, 0xbd03b3ae, 0x063851ba,
+ 0x3f529a81, 0x92d11e9e, 0xc53ce5e1, 0x1f172f0b, 0xe0c7ff3b, 0xf57da243,
+ 0xa8ee3dea, 0xff79c253, 0xa2dfcde5, 0x20e7d83e, 0xfbe7d4be, 0xec81ac5e,
+ 0xfbcd4b91, 0xbcdd3fe8, 0xcce5f8a5, 0x7c1ff7bb, 0xf26377de, 0xe5fdd5db,
+ 0xef9f3fa0, 0xcfea9bbd, 0xef0403b8, 0x57bbf265, 0xfd1c7955, 0x9ffe741f,
+ 0x813bee98, 0xcf4b9eee, 0xf83fec7b, 0xfdd353bc, 0xee82edc8, 0xa947cc5e,
+ 0x8279c9fd, 0xb9ea93ef, 0xce87ff1b, 0xefd7b75f, 0x315a05b3, 0xbd1d3b2f,
+ 0xe1e73c01, 0xe182df9e, 0xce46fbc1, 0x28dda2f7, 0x2b4bfd8b, 0xfb95117c,
+ 0xf3c4b27d, 0x1e10d9d6, 0x4fc263cf, 0xd710f342, 0x272b454f, 0xd6d154bb,
+ 0x94ccdd93, 0xf0104740, 0x7755df72, 0x87d72806, 0xc6163f8d, 0x0169e0fa,
+ 0xfc5b578a, 0x058926c5, 0x9557b025, 0x187f3eab, 0x48fb16fd, 0x4251dc5b,
+ 0xde585be5, 0x7690e223, 0x67f26aaf, 0xbae6d1b4, 0x3bae6fcb, 0xc64e7f44,
+ 0x58fa77e1, 0xf2d1e314, 0x98bc0795, 0x538f26cf, 0xbb2ea618, 0xfd046b58,
+ 0xfccf8706, 0x73f422fd, 0xb45bf10d, 0xb060e3db, 0xad8efbfd, 0xf3383f14,
+ 0x60375bf4, 0xca2f55bf, 0xe97809cc, 0x7166e1de, 0xaa251be4, 0xd9523fa2,
+ 0xbe290726, 0x174bc4a2, 0x750bf618, 0x87eab17b, 0x72ab826e, 0x173a23a7,
+ 0xf5dcafbe, 0xb75a1287, 0x3d92f5d7, 0x0a5a791b, 0x3be1a36c, 0xb03f704b,
+ 0xbe7e4952, 0xe79511e4, 0x4eed751b, 0xbc7e885f, 0x6be79db4, 0xb16ec656,
+ 0x28790c3b, 0xdebb541b, 0xf228f88e, 0x2cf94494, 0x4f319f08, 0xbb57b750,
+ 0x7c38929e, 0xe628f6ed, 0x7f6e567d, 0x11e31bae, 0x011cc795, 0xb76b1b74,
+ 0xeff14fbf, 0xc67c3f19, 0x977e49d3, 0xfb43f26c, 0x65db7ff9, 0xb6caeba2,
+ 0xa15bb21a, 0x195df44e, 0x27d6fe13, 0x7eaa4ff4, 0x1e1777b8, 0xd1faa894,
+ 0x778c1e93, 0xe6d8ee9c, 0xfb703f21, 0xfd31e3c5, 0xbdd8bdfc, 0xc2fbdfc2,
+ 0x54e3e449, 0xfc69defe, 0x3f51d807, 0xf37e2d55, 0xc76401f6, 0xc9a59c02,
+ 0xfe74c7f6, 0xc3e67aa9, 0xd95e31c7, 0xc7bdf3b5, 0xbfeaee11, 0xb471e9fd,
+ 0x973ed943, 0x6a2df717, 0xc535fe9f, 0xdeeff477, 0xa25c7954, 0x2927a9fb,
+ 0xfe0dd63e, 0xbdd6f636, 0xfa0164f7, 0xfdcfdd23, 0xe7fd1725, 0xd1677b35,
+ 0xcf358ff9, 0x92c818cf, 0x225eb1c8, 0x232f46ff, 0xdba5673e, 0x6483b6c1,
+ 0xba019f2f, 0xe7d2bfa3, 0x786ac7c7, 0xfc2fc47c, 0xe3c91df7, 0xf5fcfda1,
+ 0x5e3705b6, 0x6db8f98b, 0x83aa00f6, 0xafedfa4b, 0x5ec73d01, 0x88771d06,
+ 0x0bec4cf8, 0xcfdbf517, 0x5e803fe0, 0xfc742de7, 0xf7d96db0, 0x6d77c11e,
+ 0xedfa5203, 0x9fc0cbf1, 0xa23d6f1e, 0x940e9d06, 0xa03f9db7, 0x6fd20978,
+ 0xfbb84c2e, 0x300b0f99, 0xdeca7d5e, 0xb1e53b7b, 0xd17875ef, 0xfbdcad4f,
+ 0xf753c906, 0x9e2947f3, 0xb3dc44c9, 0xf1fdf59b, 0xa1c894f8, 0xcdc27dab,
+ 0x07417dfd, 0x3df8078c, 0xfdf85cf4, 0x78f5af9c, 0x4038aa40, 0xe4f3c1d0,
+ 0xcd7038f4, 0x7e15bf13, 0xd26e8275, 0x5bd7a464, 0xeb5f8d17, 0x1e22f078,
+ 0x5ce31926, 0x7d2ee3c9, 0xdd0b2e71, 0x5f56f8f4, 0x83ea0b1c, 0x95119e31,
+ 0x371648de, 0xe3ccdeed, 0x7376dd63, 0x4e824dfe, 0xd535ee3c, 0xe8d38e61,
+ 0x2f254df3, 0x6a5edcba, 0x4f149f1e, 0xbb08d0a3, 0xbabe3fba, 0xdfae4e3e,
+ 0xde5c776f, 0xfdca757e, 0x7592a594, 0xc736e53f, 0xbc3f68d5, 0x57ca32a5,
+ 0x0c79e5e8, 0xc8b9befa, 0x5a7aec17, 0xfac978a6, 0xefd241d8, 0xefa1fd56,
+ 0xade159b7, 0x6caef013, 0xd747ebe7, 0x8354774e, 0xec0eba7e, 0xb95ebe26,
+ 0xfd152de3, 0x7fdb43cf, 0x8b3b72a4, 0x1fae11cb, 0xba7cc351, 0xc25fdd9e,
+ 0xdf3c7ae3, 0x37ce3ad9, 0xa93edc1c, 0x9c7c93dd, 0x9bef1dda, 0xc48aa9c6,
+ 0x79ff9e54, 0x2b4ef1f1, 0xbfb05bc1, 0x3a761dd3, 0x263a73cf, 0xbfb649cf,
+ 0x1761d8bb, 0x2f2b41f6, 0xbca51d61, 0xbcfca3ee, 0xd357c4c5, 0xcd7a0f28,
+ 0xc5bf39d1, 0x406b8c73, 0x6c4ed1ac, 0xda7ce06b, 0xf9827ff6, 0xa3b6ef48,
+ 0xfd71965f, 0x35f885da, 0xafa58bd8, 0x8370cdd5, 0x5dfd287e, 0xabb22268,
+ 0x3a4cef55, 0x0fc13366, 0x75c40ce3, 0xc1fa09a1, 0x9fcc7dfc, 0xcf647842,
+ 0x8f0839ec, 0x5d79b5ec, 0xed52f249, 0xcaf2885a, 0x5eed7ef5, 0xc338de73,
+ 0x4fd086f3, 0x5e7a95f7, 0xf1032851, 0xcdc761f4, 0x328674bc, 0x775917bc,
+ 0xd9bd094e, 0xf1601f55, 0x081cfc11, 0x7e456bd6, 0x839ec570, 0x560f51b3,
+ 0x2fe624c4, 0xada473c4, 0x763f3724, 0xa573f264, 0x515db351, 0xd457e7b9,
+ 0xb78db2be, 0x6a3162af, 0x8c45e78f, 0x6c4d5bf6, 0xe11ec582, 0xf223ddfc,
+ 0x95cfaa42, 0xff21b8b2, 0x9f8267eb, 0x26bdeaba, 0xf08d5f3d, 0xd61afb41,
+ 0xc4d4e341, 0xd1c69806, 0x9b9cd5db, 0x46afea6a, 0xab7e20e9, 0xf42ff739,
+ 0xeabe4fbc, 0xd487847d, 0xe09be7fd, 0x853ff44e, 0xeb2427c5, 0xb73d1a7f,
+ 0xe6fa87e6, 0xde6378f3, 0x882cbd02, 0xe88cfea2, 0xd3ca73e7, 0xbf808da2,
+ 0x3ff85a23, 0xdcf81f50, 0x625f0b1b, 0x326cde78, 0x709f59e5, 0x0f047c88,
+ 0x047cf0f3, 0x7583622d, 0xcb6d11f8, 0xf28c6986, 0x8c3b4e0d, 0x5e2c06f9,
+ 0x6f447a82, 0x25bdefd7, 0x7e30611f, 0x1650aa02, 0xde631670, 0x8d07ac3f,
+ 0xb05b3cf3, 0x9f9ba8fe, 0xbd602c93, 0x60ff31fb, 0x0a03f0ab, 0xdc58ce31,
+ 0xa7e4bcff, 0x3d99273d, 0xd0d56ca3, 0x9cb36300, 0xa02a6723, 0x296fb32f,
+ 0x0bdf2e7b, 0x3d9b1966, 0xb3d0f313, 0x971b2c9f, 0x4b58f507, 0xcbff7f27,
+ 0x500571b2, 0xe2eae63f, 0xca24abef, 0xbe5b57d3, 0x7da2333b, 0x137d3d06,
+ 0xa4d4a660, 0x409cb3a7, 0xdfa133cf, 0x1f99717d, 0x557a1ef3, 0xc216678e,
+ 0x73264376, 0x7ed60dfc, 0x75fa1cf7, 0x0d9d6d43, 0xb7be5fa8, 0x7499cff7,
+ 0x23f30fde, 0x6b1e9cf0, 0xe11d22f2, 0x170be4d1, 0xe6b3afc9, 0x74fce999,
+ 0xec5c3b95, 0xdf363a04, 0x23ce9239, 0xde31523e, 0x26e37e89, 0x70f3b791,
+ 0x3f21be5f, 0x93b57897, 0x44f9f7ef, 0x0fd9d75e, 0x2eb2330a, 0x7d6a1fa2,
+ 0x0628278b, 0x5e947ab8, 0xf9efb7da, 0x31dbadf8, 0x99eb130f, 0xc499d649,
+ 0x7be94bf7, 0xf3053e6b, 0x2d9f1366, 0x78867c15, 0xfaf21a73, 0x9511cb97,
+ 0xc55bda07, 0x8bd337fa, 0xd52297f3, 0x9f5185f2, 0xb4c74f1c, 0xd3c45cf0,
+ 0xcf299ce7, 0x7a45ce75, 0x6675cf5a, 0xe0374339, 0xe7e57977, 0xfaee500a,
+ 0xad4a69ce, 0xeb3f4879, 0xf4a64fb9, 0x19f992da, 0xcfb9c45b, 0x710f7054,
+ 0x71c36f85, 0xdfe27e8a, 0x7fe41879, 0x803552ec, 0xd763a4a9, 0xa4280c4e,
+ 0x45de789f, 0x3c2be0ad, 0x1ee74eae, 0xcfb466ee, 0x8290e3db, 0xdcf7d7e8,
+ 0x60bb25e5, 0xe4b9d2f0, 0x17a4f75f, 0xa93f30c6, 0xda7e6be7, 0x427b040f,
+ 0xb21f3942, 0xf2ee2327, 0x647e9c90, 0xcc8fd391, 0xb71e6972, 0xbdbf82e7,
+ 0x8af3fa93, 0xcfd0c0fe, 0xee9f9c4d, 0xdf7af991, 0x3827ef53, 0x7ec8b086,
+ 0x772f1fb4, 0x853bafbc, 0x03e8281d, 0x1186fff8, 0x66c740ff, 0x3a43afac,
+ 0xc74a4c8e, 0xb47464e6, 0xe49dc79e, 0xfd87df0c, 0x443f2c9c, 0xe7ad72e7,
+ 0xc9129970, 0xe9593c43, 0x3eb4ab5b, 0xb9d25b8c, 0x3b27de7b, 0xd8dfa746,
+ 0x4e88e3b5, 0x843e7a06, 0xf3dd8c70, 0xd6e10dbe, 0x291df8e9, 0xc14c1db9,
+ 0x8ffbabc0, 0xd3b0bb97, 0xbed24e16, 0xf5296d64, 0x82d9f807, 0xf3f018e3,
+ 0x9fbfd614, 0xe14f3f1a, 0x3f032fbc, 0x7e0e5ecf, 0x4aaf3f74, 0xee1571c8,
+ 0xff9d015b, 0x5b9f9fe8, 0x96cee304, 0x15d3e235, 0xef8a64db, 0x79b9fb42,
+ 0x5fb909b9, 0x3f6ea531, 0xf15c579e, 0xb4fc4498, 0x7fbf9c54, 0xb7bf9c4f,
+ 0x2f9603e6, 0xbd9e908c, 0x94605e74, 0x76d546f4, 0x09c3f3f3, 0x3ca02afe,
+ 0x89ef715f, 0x15805f7e, 0x213567ff, 0x365d4bd7, 0xfd02bde3, 0x66ceb7e4,
+ 0x9bcf2bca, 0xf90fd7d1, 0xff9b3efd, 0xfdd38a0d, 0x6e30cecc, 0x27b25414,
+ 0x131f11c6, 0x6fd899a5, 0xbd2f9099, 0xcd6ba1bf, 0xc4615e76, 0xb8b03e7c,
+ 0xf03e7cc5, 0xf9f3568a, 0xcc9b11c0, 0x8caf03e7, 0x8e07cf9a, 0x54de3eda,
+ 0xc6bb131f, 0xfb6c7ed4, 0x5c7d5374, 0xf6a6f3fc, 0x37cf0e13, 0xf8eeafd5,
+ 0xa4fda9b2, 0xde9a7763, 0x34ace94f, 0x6a7a9fbd, 0x6d7ea9b5, 0xda9abfef,
+ 0xfd7197c7, 0xe47ea075, 0xfa9e6354, 0xcdaa5581, 0x0d57cf8b, 0x8c4b79b7,
+ 0xfe8373cf, 0x834b2c12, 0xd2a767e8, 0x579c33b3, 0xf7ae354e, 0xd26ecc65,
+ 0xe69c333f, 0xe225c7ba, 0x2fc00510, 0x2e01fc40, 0xbc815cb3, 0x1e40bae5,
+ 0xb5a6ebf2, 0x83c7870c, 0x40cb0c56, 0xcb390279, 0x9c9e5d75, 0x93bb63e5,
+ 0xb1ebe32b, 0x003eec9e, 0x2ef910b5, 0xb29bf942, 0xe32ff738, 0xfe32173d,
+ 0xc2a5443f, 0x5e4a1122, 0x7c860167, 0xf5f75d6f, 0x8f8adef5, 0x27c78b80,
+ 0x04f0fe1d, 0xdc3f2cc5, 0x4c55f0df, 0x92f80c50, 0x76a675bd, 0x499cff0e,
+ 0xef89f7c6, 0xdfcc9342, 0xa5d5342d, 0x7f2973e5, 0x765c1528, 0x4f5192df,
+ 0xe7b37e80, 0x7f52a62d, 0x96d0bcde, 0x06f05f34, 0xc3f467d7, 0xc9ff3ca3,
+ 0x80dddf60, 0xfd933974, 0xf79843ea, 0x2f5172b6, 0x0e79e3f9, 0xd4487eb3,
+ 0x3a2f3df9, 0xb3d68f3c, 0xebdeb8d1, 0x4196dae7, 0x9a6dd621, 0xf3e3b2ef,
+ 0x61af3173, 0xfd3f0a70, 0xc79f3101, 0x96a323eb, 0xa7306322, 0x41793ce9,
+ 0xda3676bc, 0x9e454361, 0xe4b643f6, 0x2e5553f9, 0x440caebe, 0x82f68d45,
+ 0xc13ed2a6, 0x79dff299, 0x55abf530, 0xff21570e, 0xa3b639de, 0x0ea39f94,
+ 0x3f7e78f8, 0x77d75b87, 0x21e85a05, 0x60055fd4, 0xfb0bf9b6, 0x517033c3,
+ 0xbc214e68, 0x05b2ca6f, 0x4af7aa34, 0xebf8de74, 0xbed03320, 0xc1326fe9,
+ 0x0a6074d7, 0x5aa915e5, 0x27464598, 0x7e44c9e6, 0xf0efbe82, 0xe44df661,
+ 0xd55d36bf, 0x9188de77, 0x3a85ab3f, 0x370fdfb0, 0xa6dc69da, 0x7de992e9,
+ 0xeabad681, 0xde51c010, 0x4bf14e96, 0xe40dd365, 0x0e3ea97f, 0x12e3d34f,
+ 0x3c112c1b, 0xe1eece3c, 0x7c3c00f8, 0x2670f105, 0x4d91f858, 0xafbc349f,
+ 0xbce950c9, 0x711490e8, 0xfc3a6d8e, 0x3a2691c1, 0xc3308de7, 0xf6fc6f2d,
+ 0x3f9843aa, 0x807a7cf2, 0x2e3ea4a4, 0x779e6ae8, 0x1bfcf673, 0x1aed04bf,
+ 0x1e19935f, 0xc277f0f9, 0x91f34f1a, 0x7824d1a3, 0xf006e9d7, 0x957e436f,
+ 0xf9a6cd37, 0x2f7a0a16, 0x3ae37a07, 0xe685b3e3, 0x6d73fd10, 0x9d6be70c,
+ 0x07a10ec7, 0x8579719e, 0xf97396fc, 0xf51d2df3, 0x73d204c4, 0x73ffd86d,
+ 0x73f694ae, 0xdd892b9b, 0x517ba975, 0x1c7617aa, 0xca0e52c2, 0xd427ee01,
+ 0xcfda370d, 0xe27f1fa0, 0x72cdf832, 0xb04bd7c6, 0xe1d94bdf, 0x65a04ab5,
+ 0xeda5e178, 0x90cfb434, 0x0cfb750f, 0xe71479e6, 0x9e8b0bf9, 0xa3f5e837,
+ 0x4499e6c9, 0xed8ebfaf, 0x9e397e4e, 0xbd027ed4, 0x8e64764e, 0x65ff5c9a,
+ 0xd47a71a4, 0xf946557a, 0x97f62985, 0xedc9696c, 0xdfeb54c6, 0xa290fca5,
+ 0xc07ee681, 0x847f216e, 0xdfb4ab95, 0xcd83f675, 0x3cc70ef7, 0xf288ad21,
+ 0x93f55383, 0x04c976bf, 0x22bfcf81, 0x9dfc741e, 0xf015e0b3, 0xeba4d7f9,
+ 0xd3e03564, 0x4b27c266, 0xf47b0cbb, 0x32bb9fd3, 0x16ea179f, 0xe0758778,
+ 0x16075a2d, 0xf18a59bc, 0x7f379597, 0xa7c0eb44, 0x39a1671e, 0x0fc7a08e,
+ 0x21df9c60, 0xfc17ba9e, 0x3b7dc44d, 0xf8d95e29, 0x17ba08fc, 0xaeba66af,
+ 0x749cea4f, 0x117072ee, 0x2ecce7d1, 0x3ce11047, 0x66e3c593, 0x3a4d7667,
+ 0xf799f184, 0x19670fea, 0xd9e67ce9, 0xe876a5a3, 0xa3ceccef, 0xf7e90aa5,
+ 0x9ddee9a8, 0x2abf0b9a, 0x3f5e7f45, 0x77c7d0df, 0xd3ebe4ce, 0x3f3f8275,
+ 0x5e301e29, 0x0a51fb4f, 0xbbed187b, 0x9b54bc3e, 0x499c15cf, 0xf114b37f,
+ 0x0eb97800, 0x43d3aee9, 0x332b878f, 0xdc60663a, 0xfc0bf7b6, 0x2e8da93e,
+ 0xe352a71e, 0xcd769875, 0xe35b879c, 0xc475a658, 0x3b50ef28, 0xd2c711d6,
+ 0xc41bd9d3, 0x7676a7ed, 0x5fb1e7e7, 0x7eef29ef, 0x06f567ac, 0xd0c7873e,
+ 0x06afe765, 0xbb7c03bd, 0x71fade71, 0xf7e94fe8, 0xd98af96b, 0xe0b1c2c8,
+ 0xe25e61bf, 0x2dcb8a58, 0xe607efc0, 0x71c41eda, 0xf37325a5, 0x6c5c8196,
+ 0x8794a8f2, 0x1c08cca9, 0xf37c23f6, 0xecef8214, 0x17df9961, 0x85b9cf32,
+ 0xfc67bf9f, 0xfd9b921e, 0xa7d4beb4, 0xc3e3e7e9, 0x2afeb885, 0x1a516cac,
+ 0x85a707d4, 0xd732c0ef, 0x10fc31d6, 0xf63ae77c, 0x609c029b, 0xd0bfc1e9,
+ 0xcabb3abd, 0x3f71fb42, 0xe4b777ba, 0xc7fac2df, 0x7e85ebfd, 0x48efcbd0,
+ 0xef31c775, 0xebbefeac, 0xec7c6166, 0xba3aae3b, 0x82fe05f7, 0xe7f41f4e,
+ 0x32cadf0a, 0x6a691c61, 0xa16b9cf3, 0xe3f7876e, 0xcd69fbf0, 0x577ed04d,
+ 0xaf1f3866, 0x534b71c2, 0xc10f0f9a, 0xb5bca33a, 0xcd29b4fa, 0xfe663011,
+ 0xe3cbcd35, 0x10b85aed, 0xf757d4e9, 0xa86ddd42, 0x85752d3b, 0xd579f5d7,
+ 0xe50bfc1c, 0xc3dcae95, 0xd9ca2def, 0x1bdf8f33, 0xee8f3ed7, 0x134e6b8d,
+ 0x9a63447a, 0x58563cf1, 0xf88bdf0e, 0x195e92ea, 0x8f48e5ce, 0x2f78a67b,
+ 0x59c39ee2, 0x06e3c51d, 0x62eec1e1, 0xbc78cbb4, 0x52f580b3, 0x8aebc7a9,
+ 0x61ca8058, 0x48e5442c, 0x55e54ad6, 0x68e5462c, 0x096541d6, 0xc032a5eb,
+ 0xe39632bc, 0x6cca8059, 0x59d1dd5b, 0x667f4fa8, 0x7c3a7d27, 0x8303aafb,
+ 0x44de9118, 0xc78d66b7, 0x656bd6e9, 0xdcbc1ad9, 0x3f50f828, 0x348d5557,
+ 0xdb62be03, 0xe87ec8f3, 0xdef63212, 0xf7045b26, 0xf9a3d963, 0x9c5abcf4,
+ 0x7e3eae47, 0xf7cdec80, 0x60f3c982, 0xbb8bc05f, 0x963ed33e, 0x3ed67f59,
+ 0x41be11aa, 0x39405f7e, 0x41708959, 0xa0ece6dd, 0x75f69773, 0x3ee907b1,
+ 0xb4ec67b8, 0x18555abf, 0xbd43b32a, 0xa061776a, 0x7a8720c1, 0x6655703e,
+ 0x96bc772c, 0xf5888f38, 0xdf825a71, 0x286fb657, 0x77fb7dc0, 0xf5a71ff7,
+ 0x85e987fe, 0xb69a9f34, 0x4dd86aa3, 0xca2a7efb, 0x7d39bbcd, 0x97d93af6,
+ 0x0640aecd, 0xfde9779e, 0x4b6fbf39, 0x94f7dfc7, 0xdf71975e, 0x283d70e4,
+ 0x5ee9b042, 0xf951f7a9, 0x953f7a8b, 0xb2f7ab3f, 0x4700f820, 0x04da9dec,
+ 0x30ce4f9c, 0x7bfbca2f, 0x432bd8de, 0x7cbe6227, 0xe601bf91, 0xcefd98d7,
+ 0xded013fd, 0x7401c80c, 0x75eeec0b, 0xf3b42513, 0xcf29f37c, 0xbc6d1ee5,
+ 0x4f008ff3, 0xe67012a3, 0x6b2fb8c0, 0xa02bb53b, 0x24fcfebc, 0xe5ffce27,
+ 0x0fcd36ec, 0xddc61bf5, 0x247dc5ec, 0x02e36fe8, 0xfa2ecfea, 0xf6c4ef1b,
+ 0x5a3f62f7, 0xa2fd9fa2, 0x677bbd7e, 0x543fbe36, 0xebee08cf, 0xb1b2da73,
+ 0xbd1f7fbf, 0x13f195ec, 0xba477ee9, 0x17caca2f, 0x66cb9fd7, 0xe6cbb041,
+ 0x41602b9e, 0xd393c7a0, 0xf942aeeb, 0xd1bfd357, 0xa0fd04ec, 0xa255d614,
+ 0xb7a6f0be, 0x1f413b34, 0x9d01b06c, 0xa59f54bc, 0xcc70095d, 0xb181fae4,
+ 0xa432e696, 0xc62bb03b, 0xae8fe1e3, 0xfa82399b, 0x7efe1ae3, 0xd79160e6,
+ 0xf7e3ed00, 0xed0b31bd, 0x918a6ab2, 0x66e6b630, 0xa479f746, 0xce2a37b2,
+ 0xc1a8b3a5, 0xba61fbae, 0x42a7e49f, 0x4c3ed089, 0xbd0f39c5, 0x5cfefcbf,
+ 0xfd8873a6, 0xfde8d3fb, 0x7e74abe1, 0x679c520a, 0xdf2273cd, 0x881c15c3,
+ 0xd763beed, 0xb8f60fe7, 0x57d5f113, 0xcc3e288f, 0xffe7d043, 0x49ffcd28,
+ 0xef1ef135, 0xf7d81cf5, 0x7fd1059e, 0xea26923e, 0xb7922791, 0x2fb4b34f,
+ 0x34cfebd2, 0x1fd69ccf, 0x12b8ef9e, 0x57b42775, 0xeafa3bce, 0x9b06df08,
+ 0x7d2cbfa5, 0xfc69e7fc, 0xb45942aa, 0x5052f7df, 0x723bd031, 0xabef19a8,
+ 0x78ef454d, 0x9b9b2fda, 0xae23fbe0, 0x5fad1950, 0xbf5a3337, 0x0602ee50,
+ 0xe34f183d, 0xb9c555fe, 0x247a2651, 0x7a6250e8, 0xd2e4127e, 0x7cbb4fb8,
+ 0xfe745dc7, 0xe7e69e24, 0x3f08b0fd, 0xb168f557, 0xfff67f69, 0xe169f1c3,
+ 0xc7014b28, 0x1c33bfcc, 0x3fe49a57, 0xd368c701, 0x387efff3, 0x6380a466,
+ 0x1c153ff6, 0x2f457b56, 0x2bda2fff, 0xcabda357, 0x9d6c41e3, 0xf7fdce8d,
+ 0xe52a2a64, 0xc99369ef, 0xe195204e, 0xdf68eea7, 0xcd779f2f, 0x8b1c7bfc,
+ 0x615f9db1, 0xd478ca2d, 0x11671157, 0x857f87ee, 0x0fcf03f7, 0x8683a02b,
+ 0x1f693a64, 0x5434bfdb, 0xfe05fb85, 0x5435e585, 0x546eeb7a, 0x587a5f70,
+ 0xefb438ef, 0x4fd96b36, 0xde933337, 0x2fbad08b, 0xb6bb22ad, 0x9b279be3,
+ 0x6078df71, 0x68c3dd5a, 0x93914b07, 0x24a787cd, 0xd6f5cf7b, 0xd14fd32f,
+ 0xce9d14ba, 0x293f42ae, 0x0ec68aea, 0xb59a3d20, 0xf0a3d200, 0x2296d19b,
+ 0xdaf72ba8, 0xaf000d02, 0xbedd1992, 0x1e57e005, 0x4d764e18, 0xb61ff514,
+ 0x6e89407f, 0xfa9dfcc1, 0x1bb7c500, 0xa5b47d85, 0xf317ae69, 0x3099ed98,
+ 0x7ae5204b, 0xd097dd7b, 0x7534d75e, 0xae0a73bd, 0x01968107, 0x01f75e5e,
+ 0xb1164f5c, 0x78a66722, 0xb46feb0f, 0x1af20d81, 0x6fe97eea, 0xbab79f32,
+ 0xd70d383e, 0x8c95d5f9, 0xf7087f7f, 0xd2cc9e89, 0xfbdfc2f1, 0x4f5c750d,
+ 0x7d448694, 0xeb7bcc26, 0xf7df5c63, 0xd1ebaba6, 0x44f987de, 0xc31b8ec8,
+ 0x630e93e7, 0xf4fe007b, 0xbeb44571, 0xf17d6146, 0x0a71fbe0, 0xf7d2f79d,
+ 0x6c639c83, 0xed841fb4, 0xc2ea7ee9, 0x742fda22, 0x388163ce, 0x69e703e6,
+ 0x09517f7c, 0x3b3cc4ce, 0x04bf1f77, 0x8aa6ce29, 0xa26d12fd, 0xad205f39,
+ 0x99b45be9, 0xfcda369e, 0x5ccc39dc, 0x9dc0b077, 0x60ec8f74, 0x2681be4b,
+ 0xb00687f6, 0x1457e841, 0x6c3622db, 0xca85da07, 0x76df7851, 0xec811e31,
+ 0x0c58faa4, 0x31e31691, 0x0c1d3f2b, 0x3282c09b, 0x6486a38f, 0x698e3bf4,
+ 0x07947ce1, 0x66e2269f, 0x8dbf7883, 0x36ff61a1, 0x8ff14fcb, 0xf5efb47c,
+ 0xb379c6fa, 0x4a91fe29, 0x889a22be, 0xec36dee7, 0xce9af7a2, 0x19100738,
+ 0xc68e6ff4, 0x6f6b81f3, 0xd779f7e2, 0x947ee1ee, 0xe8b27efe, 0x9c4536b7,
+ 0x327ae413, 0xd63df9c2, 0x485edb39, 0x0e7cacf7, 0x75f356e9, 0x6b4fc31b,
+ 0xdfb9c7e2, 0x53b7b166, 0x158da1e5, 0x5f9f4dfe, 0xf218fc23, 0xc2ce902d,
+ 0xd2ea597f, 0x4fbe6ee9, 0xa247bf42, 0x4f4dc847, 0xa8c44ab9, 0xea098345,
+ 0xe9853739, 0x3172821e, 0x654df29f, 0x2c1fe8b9, 0x8225ffdd, 0x79c6d973,
+ 0x5e4bde2a, 0xe13171be, 0x52ebc745, 0xa7f07f8b, 0x8d1709d6, 0xb4f6e9a7,
+ 0xfee81fee, 0x484fd580, 0x47e7fdf5, 0xcc3a27ee, 0x3ed195f6, 0x3c1affef,
+ 0xe07586cf, 0x67de20b6, 0x473ffba5, 0xf98eecec, 0x73655cf8, 0x2ec3f9f0,
+ 0x54560f7e, 0xd87583dc, 0xdf859c5f, 0x7f3e29cd, 0x3b2f9625, 0xedea1a63,
+ 0x7a3e3f97, 0x4a0ff903, 0x8d3cc34c, 0xfff70a33, 0xe7633af4, 0x0bf38a64,
+ 0x7eef5fbc, 0xb867ee95, 0x74f7f0be, 0xfdc6bd3e, 0x3f639d2a, 0x3ca766d3,
+ 0xb15debbb, 0x1dfde36c, 0xcdee17d7, 0x747e18be, 0x8088e1ff, 0x7bd170f7,
+ 0x571a6105, 0xb70473e4, 0x53d2174a, 0xe7cd6f7f, 0x3e98ecd8, 0xa669e513,
+ 0x2ff9e926, 0xcd97c88d, 0xfc9387f3, 0xe89bcf64, 0xf39bfde4, 0xc791b24d,
+ 0x47cfeeae, 0xef59ff3a, 0xf1235925, 0xe0a9ef73, 0x19b405aa, 0x3dc4d1d7,
+ 0xef3d2a25, 0x0e86f116, 0x54f6fb1f, 0xac799790, 0x75fb4ece, 0xfd177ee2,
+ 0x4179975e, 0x2242fdcb, 0xd6242aff, 0x5e4437c3, 0xa7e63cd5, 0x376817ef,
+ 0x75bf51d9, 0x6e60fb88, 0xf1bb6162, 0x425ea67c, 0xb6bd26bf, 0x7eb98e60,
+ 0xb75cc873, 0xe7a8a3de, 0xdeb4fccd, 0x89ef153f, 0x999dfbd3, 0xd3ec3f42,
+ 0xb03c5d3e, 0x67507e2f, 0x71e81f8e, 0x43cc1abf, 0x1e18fda6, 0xe4e59bf7,
+ 0xbb8f4fe3, 0x56a37f68, 0x16e33753, 0xc5b3ea0c, 0xc6967cf0, 0x8bc60df5,
+ 0x59a29ef0, 0x6f1f7e8a, 0x80e7bf54, 0xf909cbbe, 0x0ddc6336, 0x5ee930f3,
+ 0xdf1e70ab, 0xa0721157, 0x0ece19c7, 0x5e6467f3, 0x4db5bf84, 0xba9ee9b2,
+ 0x13b895fb, 0x00fee0f9, 0xf04ac3cf, 0x6f14d471, 0x49a936d5, 0xebebb7ef,
+ 0x9e0af407, 0x3ee0724f, 0x01f7d02f, 0xc635e825, 0x887b3423, 0xf4f776ea,
+ 0xf2f23f0e, 0xe3661b03, 0x988d1055, 0xca760c1f, 0x6957da3b, 0x03db767d,
+ 0x621ef187, 0xc7e6dbb7, 0xb341b8f5, 0xa357bed1, 0xefeb49cf, 0x8bdaa97a,
+ 0xebf7a4fc, 0xae0854ee, 0x06515ab3, 0xabff08bb, 0xda334fe0, 0x87df31af,
+ 0x9e37dff5, 0xddfaed46, 0x0a7075bf, 0x131d59c5, 0x17bc016d, 0xb1ac1d5c,
+ 0xcfc9243f, 0x936f1bec, 0x549fb492, 0x77494ff8, 0xf507a77b, 0x7c96b743,
+ 0x2dc8ba3f, 0x3fc2fb89, 0xb22c3ca5, 0x5f33c3c4, 0xefc71e1f, 0x8a1bcea5,
+ 0x8a3e490b, 0x2b6f20dc, 0xccf59dc7, 0xe47c93f0, 0x2e1c7cf2, 0xabda8db7,
+ 0x6c379e4e, 0x152da7be, 0x4978ea3f, 0xc8e50785, 0x37e78c5d, 0x7f719986,
+ 0x43c52dce, 0x4e32d794, 0xb8afba49, 0x51a1e056, 0xcabf1009, 0xb89c86d7,
+ 0x4f64340e, 0x7ffee277, 0x28cfe2b3, 0x88f0fb44, 0xd66e30cc, 0x8dcb35e4,
+ 0xfb88b65e, 0x6dbae745, 0x7559ef49, 0xeeff92da, 0xbe6e5dce, 0x9fecb44e,
+ 0x52dee742, 0xd46809f1, 0xa5a5d910, 0xf3ef178a, 0x5e1ced96, 0x04fc8a57,
+ 0xfc54dfbd, 0x177eef71, 0x61993dff, 0x659f3a4e, 0x9c49af1d, 0x78026bc3,
+ 0x1a6dced0, 0x6c7841dc, 0xd178a89a, 0xd3f9768e, 0x5ed0d398, 0xef489cc9,
+ 0x78d96acf, 0xa5359026, 0x4f1d3be0, 0x9f6db9d7, 0x16c2ff8d, 0x0df9cbfe,
+ 0xfc0dcbc5, 0xff193ab7, 0x983c875d, 0xde37e1c3, 0xf264a9ab, 0xbc2b3ffd,
+ 0xde3e7e7a, 0x9fcc6e87, 0x845f052a, 0x1c8e8dc7, 0xec0c3e9a, 0x303abedd,
+ 0x86d78c38, 0x73fb8e7a, 0xd133a771, 0x647dd1be, 0x75429376, 0xdf07df3a,
+ 0x6cf7f105, 0x39fdc4da, 0xc1f3a835, 0x45beaa8f, 0x9f585e63, 0xbb2ccaef,
+ 0xda51e717, 0xab9f8071, 0xf9a1cb69, 0xadef8b57, 0x9c3dc6f0, 0x2f1ee39f,
+ 0x82c71995, 0x77dfc03f, 0xf348eb68, 0x2db71c63, 0xd639db8b, 0xf5bbceef,
+ 0xb156873c, 0xfb49d1df, 0xf8333912, 0x3bbbd47a, 0xfea3fc9d, 0xf7e069f8,
+ 0x8dec5869, 0x94367bbe, 0xd51dd938, 0xc7d0eec2, 0x82c45d2f, 0x2f4bbbf8,
+ 0x2716b1a5, 0x843b87d8, 0x2df6321c, 0x780a5fb1, 0x7c6fb804, 0x3fed1471,
+ 0x04bdfde9, 0xcfb612cb, 0x912cedcd, 0x3fc0cfe4, 0x6fba6631, 0x39d9c6ad,
+ 0xbe47f51c, 0x46edde1c, 0x6758e33f, 0x5edbd62e, 0xe0f64d3d, 0x73f0f0a5,
+ 0x51c2bf81, 0x571e7dba, 0x35d6718d, 0xf45d95cf, 0xc6355d7c, 0x50fe0c43,
+ 0xe9b36f02, 0xa17ebf79, 0x1fe8bf3f, 0x8d392be3, 0xa09ae9c9, 0x4c8b3e4f,
+ 0x0a7d18b8, 0x25d23de8, 0x1fd39a3a, 0xde60f9f7, 0x607fd764, 0x09ef27d1,
+ 0x9f4ffd7a, 0xae26366f, 0x40e53f01, 0xf188e789, 0x9fbc5bde, 0x6fc794f7,
+ 0x15b27f5a, 0xcb3553f6, 0x2c6987c0, 0x8dfa84e2, 0xd167ce8e, 0xfaebd3fe,
+ 0xc7c11bfb, 0x39fd8c9a, 0xf2e91cb9, 0xb928bd5b, 0xedcb7edc, 0x3c0efc21,
+ 0xbee0f716, 0xfc628bc7, 0xe81fd8b6, 0x76b6b3be, 0x3d4fe199, 0x96145c0c,
+ 0x4e825ac3, 0xebe1fbfd, 0x60ff2e8f, 0x0b728e4e, 0x4a3947f9, 0x6bfdcb5f,
+ 0xdfe8cf5d, 0xcfb47915, 0xee8f1f66, 0xc8ac4e77, 0x75724393, 0x05f44308,
+ 0x7bbdf96b, 0xa2ff0b6f, 0xd39fdc5a, 0x18c7dfa5, 0xde33691c, 0x5a76f5bb,
+ 0x87fd1441, 0xe5f787b7, 0xed1ae609, 0xf0576aaf, 0x1bbef0df, 0x7ca65476,
+ 0xc1bc0fd5, 0x9a2fee0c, 0x712ea7fd, 0x3fee8eaf, 0xffdf8b35, 0x7f398362,
+ 0x1dd24b37, 0x91ffb0f3, 0x72af749d, 0xa75f2e6e, 0xcc7f73f5, 0xf64259d7,
+ 0x54abe0b7, 0x0f39f77c, 0x83d40f97, 0xad7ca491, 0x0dbf9e9a, 0x70c460eb,
+ 0x53cee84e, 0xcf1ce8c3, 0x78a01612, 0x749692e6, 0xbde03116, 0xf9e4f1ed,
+ 0xbe848b35, 0x4ef7136f, 0x5e7cd1b3, 0xf3e7be09, 0x1c975b68, 0xbe0c9eee,
+ 0xfb89b70e, 0x6094dbc5, 0xd529e23a, 0x078fa13a, 0x3ca74b04, 0x6f07f387,
+ 0xe6fd71a0, 0xfa257f71, 0xb26ff17d, 0xc0037df8, 0xd827d0a3, 0x9b1e1bfe,
+ 0xe2bebe49, 0xb3faacf9, 0x24feb4cc, 0x9e933ef0, 0x927d767f, 0x927d0979,
+ 0xf251ef4d, 0x3a78ced0, 0x7b75efc6, 0xce6db0fa, 0xdb742496, 0xaaf4e424,
+ 0x3fee851c, 0x76e7151b, 0xb976aa40, 0x639ee259, 0x7c2b4781, 0xf9c9c5d9,
+ 0xfe0ca5e3, 0x7e74f57d, 0x1bde334f, 0xb285f38f, 0x75fd0020, 0xf422d74d,
+ 0x6fe25ffc, 0x7ab49c62, 0xbf8fc3a7, 0xd3b5d7cf, 0xa27a8155, 0x62a3a76b,
+ 0x7e9fd68b, 0x3b663cbb, 0x4ccf99f7, 0xf58c7fbf, 0x705174a0, 0x5fd1cfc2,
+ 0x3ee99768, 0x927f6b49, 0xecf34dc7, 0xec29e7d3, 0xb9b9afb0, 0xe74ecd3e,
+ 0xf117b174, 0x572ad475, 0x1d3c8547, 0x2d90f215, 0x75876bee, 0x92eb89c9,
+ 0x0217eede, 0x2cc393df, 0xe7c17de9, 0xb12e02dd, 0x76bc3c2e, 0x04c3fb06,
+ 0x08ce7dfc, 0x7eda19c5, 0x7ec02f13, 0xdc78cabb, 0x16fdfac0, 0x998c67c1,
+ 0x3349eaed, 0xb9e612fd, 0xc5e498b0, 0xfdbd7c7d, 0xb7bf18a4, 0xd3b9fff8,
+ 0xdbc5ecfb, 0x807bbfc8, 0xf49a2eff, 0x81eb8a53, 0x61b4170d, 0xc18fd15e,
+ 0x5ff8338e, 0x1de8b2bf, 0x0baf3c2b, 0xefc4da78, 0xeb8d3287, 0xf55d2b61,
+ 0x779f4c75, 0x1cb300f6, 0xd7ff82c8, 0x9647328a, 0xb9743c68, 0x7d7c591c,
+ 0x5cc4f9e6, 0x49d2e24f, 0x1e5859cf, 0xbcaf7003, 0x90e6fc43, 0x95dcef88,
+ 0x31ef3e19, 0xe9da3df0, 0xbb097eb4, 0x6fdc4dbc, 0xa889dba9, 0x466bc74f,
+ 0x0e0223b8, 0x4ad7d71b, 0xf30d7d72, 0xe2a7bf10, 0xf6127ea6, 0x262bb706,
+ 0x166dfc0a, 0xb25f51e7, 0x3fb226b1, 0x39749e04, 0x9661951d, 0x7f8ca2d3,
+ 0xacdd390e, 0xa4727cf2, 0x787d325f, 0x9427ed1e, 0x71c16387, 0x4572c798,
+ 0x5fa00b48, 0xff31da5a, 0x0cf1e600, 0x943f83df, 0xe1e39093, 0xbfb19f82,
+ 0x2dfc0645, 0xf09b70c8, 0x7f8cf9f7, 0xf877bb0e, 0xdf37d631, 0x7d7a0cdb,
+ 0xe5c68655, 0x942ffc00, 0x9a7f8a83, 0xe00e86f9, 0xa06aae39, 0x9d0caa3b,
+ 0x8b62da3f, 0x3ed0b9d7, 0x6802c63e, 0x16c7775f, 0x7f00c6db, 0xf6e26f74,
+ 0xdf9e9f63, 0x7a05f1c8, 0xf97a8639, 0xf4c1638a, 0x275f50d1, 0x458ae3f8,
+ 0x14e7df8c, 0xcfd14773, 0xce44f5d6, 0x7033bd4d, 0x7a6577df, 0xf0cb835d,
+ 0x3b7dafbc, 0xe84c2fb4, 0x37d46a9b, 0x7df6d4fe, 0x8d3a466b, 0xe209eb87,
+ 0x733a5665, 0x979e00ba, 0xee32230a, 0x4574be6b, 0xe7bc78e1, 0x785a50fd,
+ 0x7ef86af4, 0x0e3e1cd2, 0xaf44776b, 0xd2ff1248, 0x88ae75f5, 0x7c8ae54f,
+ 0x5e34dcef, 0x45f42c7e, 0xc1f39783, 0x9ebcbdaf, 0xcf1e49eb, 0x17ef11ea,
+ 0xdcef5cc8, 0x2edc9657, 0xc67c6589, 0xb24063f8, 0x1963e3c6, 0x6f9ee239,
+ 0xeb5f425b, 0x7c4273fc, 0x2edf8fa7, 0x9cfcb5e6, 0xe59fe264, 0xcdf11d4a,
+ 0x3d0a73f2, 0x1522e5d7, 0x79fbe9ff, 0x78e11d9b, 0xbe7bd406, 0xc60961fe,
+ 0xe9ef0a0d, 0xf848fbe2, 0x5253407b, 0x1ebe87cb, 0x3d06f4e8, 0x0df186df,
+ 0x2713f3d0, 0x18f43ad3, 0x9c85975f, 0x1ff4ec1a, 0xb659efe0, 0xd4555c75,
+ 0xdf6ba060, 0xfee0197a, 0xd95d758c, 0x57c4c980, 0x89d79ea7, 0xa3ef2ccf,
+ 0x25e1d852, 0xbc3b577f, 0xc93c63b4, 0x578112ed, 0xc7a6de3d, 0x507b18b5,
+ 0x13f731f8, 0xe4cd277e, 0xdff80df2, 0x9a3ff021, 0x7dbbffe3, 0xec95bff8,
+ 0x2f2e5684, 0xa52b9db9, 0xfa2f9262, 0xa4ddff4e, 0x52afd3c2, 0x2f78e77e,
+ 0x13ffe7f7, 0xc9555084, 0x00008000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
+ 0xd5d47c79, 0xcefdf8b5, 0x3324b677, 0x5f64ccc9, 0x25849308, 0x2126126a,
+ 0x26504109, 0xc5116109, 0xfb094049, 0x515983b0, 0x2fb5696c, 0x4a444103,
+ 0x505d8bdf, 0xd101da94, 0x101ac55a, 0x83b06034, 0x6795622c, 0x05b054a4,
+ 0x2108ee3b, 0xf16b43c9, 0x3dde5a57, 0x999bdee7, 0x006677ef, 0x7e7ebe7d,
+ 0xdeb8ff0f, 0xdef7cbb9, 0xfb3dce73, 0x3ab3c9bd, 0x21094b25, 0x0b62a21b,
+ 0x99941c48, 0xc84b125e, 0xbd3e0988, 0xe90844dd, 0x95242448, 0xa423aefe,
+ 0x475aea0b, 0x2423c932, 0xbd389ead, 0xbed19eb4, 0xfad2d25f, 0x8637f865,
+ 0xc94ad310, 0xfe9e30b9, 0xd3b694be, 0x3a166ddf, 0x9ed03130, 0x1609ebcc,
+ 0xd025213b, 0x820d27cf, 0x936f36f9, 0xb4be74b4, 0x62908976, 0x2f13365a,
+ 0x4b8c0ac9, 0x99efb073, 0x01695e1c, 0xbb48dfed, 0xac849191, 0x59e754d3,
+ 0x14996812, 0xbfa568e3, 0x07bab06d, 0x4fea7ec0, 0xda667cf9, 0x2ea9c465,
+ 0x7b8e9bad, 0xb4cceac2, 0x63f60624, 0x24692d97, 0x53989087, 0x366d9d6c,
+ 0xfb05d732, 0x174cfe23, 0xc63f240c, 0x15b211f5, 0x93289bd7, 0xab46c423,
+ 0x2f7e87d0, 0xd6ee7569, 0x7d6052f5, 0x6ee23649, 0x49496da7, 0x84d3bdc4,
+ 0x2291d7fd, 0x7048d7da, 0x87ab493f, 0x059f5d6c, 0xde7179f3, 0x36d71caa,
+ 0xf92abdf8, 0xfa56a2ba, 0x9f06ce7b, 0xb71d3e76, 0x0266b377, 0x2bcc53ec,
+ 0x0916d1ca, 0x8c7dd1c7, 0x7d89fd80, 0x9289fba8, 0x5bae0f10, 0xb345d3f4,
+ 0x5bf685fd, 0x4cc6f385, 0x6d0df060, 0x2f6c77ff, 0x0cc265ff, 0x1afd6f58,
+ 0x0148313d, 0x75613ff8, 0x4d7002dd, 0x0122df6b, 0xa68c3e6c, 0xf02c3474,
+ 0x29a30fdd, 0x76b0153d, 0x87f3853b, 0x79474a7a, 0xb48a3a01, 0xb295fafe,
+ 0xa0f0e173, 0xe23d1afa, 0x2c9e8b69, 0x5e0bcf6d, 0xdf5c6adf, 0xcb068b22,
+ 0x2cd756a3, 0xc7634f80, 0xfbc07ac3, 0xe81f6db2, 0xcef857dd, 0xee91c2b5,
+ 0xe296957f, 0xb25daebd, 0x4ae92818, 0xe81392ed, 0xe8d6bea0, 0x6fd47805,
+ 0xd64b7467, 0xa183bde8, 0xa7c3bede, 0xf7e9eda1, 0xfd321d3b, 0x0efb6eb9,
+ 0x7c105169, 0x12bdebd3, 0x59a86bac, 0x1e9f2b9c, 0xfe8a95cf, 0x4578510f,
+ 0x1c3bba51, 0x5a463c45, 0x3c9b9776, 0xb76f8512, 0xfd0f5dce, 0x1c6353ba,
+ 0xf5efda1e, 0x488fe31d, 0x779adcf4, 0xae507c1a, 0x314d6cd3, 0xd775f6d2,
+ 0x41ad1deb, 0xbad36774, 0x6b38c176, 0x8ab1d982, 0x206eca7e, 0x9c131645,
+ 0x47fe2577, 0xc5cecfdc, 0xa32c4b6e, 0xe08a4223, 0x316e3c5c, 0x82893d63,
+ 0xf7d28cbb, 0xd75b1d61, 0xe1e8c24e, 0x836b9c52, 0x23e3bf05, 0x3ade3a0e,
+ 0x3a979d81, 0x7e891fba, 0x2ef36eaf, 0x623927dc, 0x6fa7b843, 0x75bbf097,
+ 0xb9e0b7db, 0x73bb3ace, 0x2ffa1ebf, 0x2451a525, 0x1b9cce98, 0xd5efcf83,
+ 0x426235f0, 0xade81ebb, 0xf2a1f38e, 0x3e936e5f, 0xafdfda0a, 0xa3c2322d,
+ 0xfdb6f36e, 0x647bf469, 0xb60cb129, 0x13fdbf63, 0x06b5f7d9, 0x607fc412,
+ 0x9d6c799d, 0x8ff8828b, 0x3e187fd8, 0xaf585bf4, 0x41d754e9, 0x487c87c6,
+ 0x6afd628f, 0x7e7076bc, 0x3c4f4e38, 0x93debbf8, 0x1df3a76b, 0xf9c68ece,
+ 0x73805f04, 0xa5f9c35c, 0x6213d686, 0x5a0eb9e8, 0x9e6f588f, 0x82d3a2b5,
+ 0x3842e870, 0xe2d66c34, 0xaef4abfa, 0xce83cb41, 0xb9f9efc3, 0xfbda6d79,
+ 0xfdfd3f7a, 0x83bf2fe7, 0x936869f8, 0x48cfc09c, 0x3bfa3bdb, 0xbfac01f2,
+ 0x21124991, 0xb7fb0893, 0x7a3bf771, 0xd27dfd3b, 0x86bf862e, 0x0bb43b5d,
+ 0xccfa014c, 0x1cdafb3a, 0x7686b3a0, 0x00928903, 0x582eee7f, 0x054e9a8f,
+ 0x8ddf043c, 0x0998cf84, 0x0f128f8c, 0xcf485f3d, 0x731aacee, 0x8a5f6f80,
+ 0x353a30d3, 0x2dbbdfb1, 0x1fa01eac, 0x974007f7, 0xd78ed155, 0x15545ce0,
+ 0x02568e49, 0xfb863ceb, 0x7064a848, 0x754f5e0c, 0x997e647e, 0x85e5cf18,
+ 0x63599fd6, 0x7eaf9c0e, 0xf7c7cfbe, 0xfc995e02, 0x49dfb1f0, 0xb03f2bb6,
+ 0xd2de356e, 0x0ff612ad, 0x01174f43, 0x26b96a7e, 0xe3e82fd6, 0x0ab59bd7,
+ 0xeab061f9, 0x55833e71, 0x08dbeb8b, 0x7e72a1f8, 0xcb9d8ea3, 0x5e8cab8d,
+ 0xc7d31fe4, 0x9f28911d, 0xfbd0cf36, 0x99a43ca0, 0x87ed0f5f, 0xd7f7d8d2,
+ 0x43773469, 0x136add7d, 0x3a7c4569, 0xa044d68d, 0x4bc4589b, 0x6bdead7d,
+ 0xfcfcf3a0, 0xeabfc645, 0x012f263d, 0xba9ee83e, 0x8491c610, 0x8053c728,
+ 0xfd41f737, 0x7a50e61d, 0x6f63d3b2, 0x6a4fbfa7, 0xe04ce767, 0xa451f281,
+ 0x04bf212b, 0xf4f0035c, 0xc08dce2a, 0x0b38a5c7, 0x2cee5be7, 0x33dd7780,
+ 0x738fde51, 0x132eb7d9, 0xa2ab4ba0, 0xea91d4de, 0xa818d8fd, 0x00ffc1d7,
+ 0x52a76c1d, 0x83ae94ad, 0x765d33af, 0x6efb075f, 0xeb0ffa30, 0x4f4b6a28,
+ 0x8eb9e1f6, 0x2b75b744, 0x98fb4cdf, 0xa57743ea, 0x38a581bc, 0xa56cbaaf,
+ 0x78e52e3c, 0x9bcbc01f, 0xd41f8cac, 0x79e3b715, 0x19b8fbac, 0x0269b1cf,
+ 0x53a667e3, 0xc84d7e4a, 0xb2beb84f, 0xc557c701, 0x29938fb4, 0x257eabdc,
+ 0x64495a59, 0x2244b97e, 0x9fa7902e, 0x3b103e6d, 0xe97be00f, 0x8dfb8cb2,
+ 0x6c9dfb62, 0xfba8e765, 0xa4700a19, 0x093d66f7, 0x9d6bdfb3, 0x4b8ef88f,
+ 0x0e3af780, 0x95edeeeb, 0xf4a13f23, 0xce2679e2, 0xdcf7fc01, 0xf83f29f6,
+ 0x7bbbae84, 0x9b9418db, 0xa42ead09, 0x28c4be9f, 0x3f4a56c7, 0x20993209,
+ 0x6aafbc51, 0x8a3b103f, 0xb9fcfb8e, 0x8f204561, 0x9e75f117, 0x095e517d,
+ 0xebfd5970, 0xf6866e17, 0x0f14af3a, 0x99fbbc7c, 0xf813fd5f, 0x4d6dd2fc,
+ 0xd69149a0, 0xf7a77ee7, 0xef1a7ed3, 0x33fbf616, 0xf7e81671, 0xdf0f93f9,
+ 0x6d6ef00c, 0xb3f6c56f, 0xfac16e4f, 0xe17ebf6b, 0xf207ffd5, 0x80eb15de,
+ 0xdc5f677e, 0x77a9788f, 0xdfb09d6b, 0x71bd7448, 0x27c67ec7, 0x39c3ae41,
+ 0x4bfc65a8, 0xdfa0b5d0, 0x773d7fcf, 0xa87cb064, 0x12195d97, 0x38364ff4,
+ 0x5e50929e, 0x14389ca0, 0x7451b445, 0xd2d3afff, 0x792acb48, 0xe01d7ef9,
+ 0x33f18739, 0x790921aa, 0x7f431bed, 0xcc4c7dbf, 0x2f3bd416, 0xcf0833dd,
+ 0x3ba30c4d, 0xcf918f3a, 0x88798463, 0xf33ea096, 0xa875e676, 0xcd2952d7,
+ 0xce1249fa, 0x1ba6e873, 0x17b9c2b6, 0x6af985eb, 0x3abda1f2, 0xf889e403,
+ 0xe75f1d7d, 0xdf2668ba, 0x537e71ce, 0x075a6157, 0xa3e7b9e5, 0x8d3f016a,
+ 0x2b10ff7a, 0xd18f2fc0, 0x265643f1, 0x97dbea87, 0x384d1aeb, 0x9779e71e,
+ 0xf32829f2, 0x94fa79e9, 0x6bda579e, 0xf0e1e5db, 0x3e32dfbd, 0x60ca4d19,
+ 0x7d66d31f, 0x62fc0120, 0x75759af2, 0x58e7d708, 0x7052c53b, 0x760ae97b,
+ 0xfb74d47e, 0xcfc4d5a4, 0x69b73b0f, 0xec33aabb, 0x8e0cb7c8, 0x53fa41c1,
+ 0xab7752da, 0xcb7efe99, 0xa643b70a, 0xccf7b774, 0xb4e971b1, 0x695cebfe,
+ 0x2cabd238, 0x31ec7931, 0x561a77e1, 0xe88f9256, 0xcfc9dfb9, 0x68859275,
+ 0xe00a2c6f, 0xb44b4aa9, 0x1f7f8426, 0x7586b5f2, 0x636f5e5c, 0xbec624eb,
+ 0x1c6629cc, 0x16d1ba67, 0x671d0758, 0x2fbd6132, 0x907ccef3, 0x945a9e8f,
+ 0xae3d768f, 0x5fe0acf7, 0x3b3053c4, 0xa81fc03f, 0x7a06e6de, 0x7b33d24d,
+ 0xb563f805, 0xf2e6f419, 0x4092d623, 0xdacd1499, 0x6d9270d5, 0x3bae9db4,
+ 0x7ec4e6df, 0x857899e4, 0x07c48afc, 0x37fe391b, 0x40c5fe4a, 0x513d9e67,
+ 0xc6eba016, 0x1443fd9b, 0x53870976, 0x9e9ba70f, 0x0e5e8c3d, 0xd81e3469,
+ 0x37ada1df, 0x4295696c, 0xae50f1e5, 0x4875a79f, 0xda4bc016, 0xfe051ae6,
+ 0x0ab75ea8, 0x5c86caf4, 0xf7f514a9, 0xbfbfe58e, 0x291bd68e, 0xb8dea0de,
+ 0xaa4f9f8b, 0xc6ff42a7, 0xf085ea8e, 0x8984f4bd, 0xfd42590e, 0xad3a5c68,
+ 0x1293d637, 0x071bff38, 0xe3a4f738, 0x94f2243e, 0xd529e41d, 0x269e41ab,
+ 0xde3ea3e6, 0xfa86dee8, 0x73d5c937, 0xf510b7b9, 0x9994c6f5, 0x215f380e,
+ 0x2acf627c, 0xed1af7d4, 0xda288ed1, 0x7487527f, 0x4c77d337, 0x7247ad84,
+ 0x77927d42, 0x73d61794, 0x9447c05e, 0xf039aeba, 0x06dd9efd, 0xafeda1e2,
+ 0xf28f19ef, 0xf98bd05c, 0x75ca0325, 0x8122d69b, 0xc5ae7e5e, 0x4c1a3e49,
+ 0x9cb81fc8, 0xdbacf011, 0x7381a59e, 0xc3b79e72, 0x97127b3f, 0xc36bb487,
+ 0x67d21f42, 0x13dbd73d, 0x7bc2ce0c, 0xf427f082, 0x641d3528, 0xd35e18db,
+ 0xe0941f36, 0x73f1ab10, 0x6be252cb, 0x65bbeba2, 0xa637c6b3, 0x19abf500,
+ 0xe957f7c8, 0x742956c9, 0xc63621be, 0x5de2aa2f, 0xab27c085, 0xc11c99a6,
+ 0xda2aa9fc, 0xd20a89a9, 0x157108f3, 0x26763d83, 0xcff08cc9, 0xeac3d9b7,
+ 0x79f6a165, 0xb74fda14, 0x480a79b6, 0x155d6d36, 0x92e70b5d, 0xf21363f2,
+ 0x0f1d0b4d, 0x51d6fdf6, 0xbefb324f, 0xb14de715, 0x8ef9d859, 0x83371577,
+ 0xb5c7203f, 0xb331c982, 0x8e7edc23, 0x3e1e855a, 0x740350a7, 0x00e4d532,
+ 0xafe7f2bb, 0x6e91f348, 0xc260543c, 0x38af7179, 0x2bd99136, 0xe23ba00e,
+ 0xd5bea2d6, 0x86f2ecd8, 0xc7462ba7, 0x02ff548d, 0x15d29c3d, 0x83b1ade2,
+ 0xf7611fc9, 0xd6089f03, 0x12b9c577, 0x35f816e7, 0x37a08dd0, 0xf5af6e71,
+ 0xf3f0f67c, 0x1ff743d1, 0xbde69f4c, 0xafd72e8c, 0xfb4397b2, 0x09622afa,
+ 0x76d557b6, 0x1f0e1d90, 0x8c9fdbad, 0x823cc2f1, 0xbab06dcf, 0xbd60da66,
+ 0xab58df5b, 0xd4be0125, 0x21a1f7b8, 0x8ccfd257, 0xd19f365a, 0xa60de31b,
+ 0xb705231f, 0x0f4b08b9, 0x9598e7f0, 0xf723fde1, 0xcf4c4cda, 0x65fab6fb,
+ 0x7c05a49e, 0x5f32fd09, 0xe36bdf76, 0x08a525fa, 0xe992b992, 0xebc04997,
+ 0x8d6c1f81, 0x113f02f1, 0x7af5267e, 0x099cfcdc, 0x233b0abc, 0x7ff59629,
+ 0x359b9f98, 0xbc63dfbc, 0xf05fb20c, 0xee35d83c, 0x591c880f, 0xdf71880e,
+ 0x7c4bdf95, 0x3523c847, 0x41fac0fd, 0xaa7ec16e, 0x6bf722f3, 0x38edcfdb,
+ 0xe1ef3d15, 0xe016abe7, 0xbc627a08, 0xe700effb, 0x19c47159, 0xeb3ff14f,
+ 0x27a40677, 0x0437db92, 0x2d3ad0ec, 0x806c18f1, 0x1fd79d57, 0x78a6b784,
+ 0x6cd7be36, 0x1cf4c8f4, 0x6f778a5c, 0x153c7987, 0x3d03e1c4, 0x5f9487f6,
+ 0xbe24b9c0, 0x4d27e012, 0x700b1fc4, 0xdbbac5b4, 0xaee53e91, 0x3b53a84c,
+ 0xf3be00a6, 0x9fb30c48, 0xbd90defa, 0x2e3c2943, 0x3efffd18, 0xc2e7ae8a,
+ 0x87871c8a, 0xef7a73ce, 0x99ff779f, 0xfbbf3ef6, 0x7ec101b3, 0xeca346ac,
+ 0xea07c6d2, 0x6da9123d, 0xbb77c30f, 0x986fcc6c, 0xbbf08375, 0xbadea1f5,
+ 0x0c99ca22, 0xfb159f7e, 0xa4af93ca, 0xac5d37cf, 0x3f20de24, 0x0f1d135c,
+ 0x8e2e9ae3, 0xe643dfc3, 0x7c81f3a5, 0x4e98ba68, 0x77d9c33c, 0x30fc6f80,
+ 0xc0dbf19e, 0x3f6c4cf8, 0xf3fa51ad, 0x3c45e5fa, 0x422ed7c3, 0x1f6b8426,
+ 0xb5f6cf1a, 0xdf9d9b2b, 0x17924dbe, 0x2bc583ec, 0x82993ecc, 0x19fd3174,
+ 0x16c5a5f4, 0x0b134f8f, 0xb1f287fc, 0xa9c68861, 0xcc8f6a46, 0xf68cf2e3,
+ 0x7a068ed3, 0x1cf058f5, 0x9c39f9ba, 0xd7faf1d7, 0xac589fe0, 0x74d1c625,
+ 0xc746f99e, 0xfbfa74e1, 0xb1b1a627, 0xde162620, 0xe409253b, 0x66acf258,
+ 0x32122ff4, 0xa9fa02d6, 0x97cb4644, 0x0fa4ae63, 0x458f5169, 0xf074a27a,
+ 0x2faef16f, 0x1d021d04, 0xf187bacc, 0x49ffd135, 0x17f3869b, 0x1fbe1d25,
+ 0xc6efdf01, 0xe80afc57, 0xd738c1ec, 0x7bde703f, 0x5ff82bce, 0xfa7fe48f,
+ 0xe5d3a071, 0x2453c766, 0xc389bc74, 0x4bb0b7bd, 0xdef1fe0f, 0x44c8ffe5,
+ 0xf5f3b47d, 0x1ba7c093, 0x0c9f268c, 0x5d2ec57a, 0x03ec5fb7, 0x339c62e4,
+ 0xf38e9e3a, 0xfada383c, 0x9209a529, 0xfdc77f4c, 0xde144ed2, 0xbc191b77,
+ 0x5b778ddf, 0xee9113e3, 0x757d82e7, 0xb38f68c1, 0xfbe8bd01, 0x2632e3f1,
+ 0x3243f005, 0x74bc4acc, 0x997881be, 0x01ea746f, 0x2e9c0bfe, 0x38ace75c,
+ 0x8145895f, 0xf2f93c87, 0x078ed70d, 0xd3eb9f99, 0x730e5fe0, 0xb872861e,
+ 0xd1fa10fc, 0xa31a74f2, 0x6499d3db, 0xaf284ee9, 0x771d25a7, 0x8bd79b3a,
+ 0xef087d78, 0x37eac497, 0x5d3dba72, 0xbfa9fac0, 0xceff2773, 0x62cef1bb,
+ 0xe71d1380, 0x5ebe03d3, 0xbe82f28d, 0x8dd6f94c, 0x7c5e8cf1, 0x55be60d6,
+ 0xf80437dc, 0xc5096f61, 0xfacfdd1b, 0x13ccbef2, 0x19f657c0, 0x57ed5b2c,
+ 0xbe64dfc7, 0xc72d6fae, 0x958e541c, 0xe4d8e42a, 0x10c72678, 0x7a25744f,
+ 0x420d5fa6, 0xc87d20fc, 0x1b9f8ed7, 0xe9dc19a2, 0x478da979, 0x77cbe579,
+ 0x86f7f105, 0x044e7678, 0xad1d393f, 0x38dfe3c4, 0xfbc79c1f, 0x6616f1c9,
+ 0x32fa39ef, 0xb6d39e61, 0xbbff78f0, 0x8b1f1fad, 0x1967be81, 0x53c4e6fa,
+ 0xea93bb7a, 0xc422fa0d, 0x09eb0c87, 0x7cf34fb1, 0xdcf3857f, 0x8099b774,
+ 0xef866bfc, 0x589e2225, 0x7d97297c, 0x3d4f7297, 0x1f86afd4, 0x52a7d5f0,
+ 0xf4c9243e, 0x563c3643, 0x1aa71676, 0x16f3c16d, 0xee4fcfd5, 0xfa8f860f,
+ 0xbe38a7bb, 0xda4bc6d6, 0x0e8f014f, 0x737180e2, 0x3cc2f9de, 0x79c9d29b,
+ 0xa1a3d18b, 0xbb2dcd72, 0xbb7ec3d7, 0xea06f07f, 0xbef4a7bd, 0x30a66d21,
+ 0x13df7aed, 0xf681488f, 0x3d91bfb9, 0x778e7a7a, 0x62ff7575, 0xbbbfdd1a,
+ 0x39c0764b, 0xd7ffdf76, 0x7f4023a3, 0xc039d2e9, 0x75f2a0ac, 0xd1f61683,
+ 0x53b4f4cc, 0xcffc251a, 0x47694f7d, 0x46f1c33c, 0x33a40af5, 0xf14e0fc1,
+ 0x6212e5b8, 0x159fba41, 0xea15bb1d, 0x6e4be5fe, 0x7ce63885, 0xa4ec38e2,
+ 0xeeecfff0, 0x5e77e889, 0x2fc89c44, 0x1f7479e6, 0x05d3f306, 0x45f594eb,
+ 0xfd3aca6d, 0x92efd222, 0x73bfd547, 0xf865707f, 0x78d1daf8, 0xd39d27a6,
+ 0xcfdf6f87, 0x7cbdbfdb, 0x837881be, 0x7c8080f4, 0xd5dfc02d, 0x39021ef3,
+ 0xd390125c, 0x5d373e42, 0x8f308a8c, 0xb73f7f09, 0xdffafc38, 0xe9a37ce6,
+ 0x79e515a2, 0xfc04f8e8, 0xd8666a9d, 0xe9b5e04f, 0xc4f12a62, 0x3f42ea07,
+ 0xc0cb8c0c, 0x2c002a76, 0xf804c69f, 0x0b03f080, 0x2240fe3a, 0xdfb454c6,
+ 0xac7ae61e, 0x52fc00a5, 0xa7bc801f, 0x278f76f8, 0x12e9faaf, 0x3a97dde7,
+ 0xa01d9b44, 0x283ef573, 0x07f59c3d, 0xe24fb9f1, 0xae7809cd, 0xf0619186,
+ 0x73a7415d, 0x0715507e, 0xf72ffef2, 0xeb072657, 0x0e7efd63, 0xa897b33d,
+ 0x2dc85524, 0xf36b92a2, 0x2b1ca83a, 0x0862bd40, 0xf68f8d30, 0xb93e474d,
+ 0x80923890, 0x19f77b8e, 0xf81fd132, 0x5899e52d, 0x3ccf14cf, 0x1337d31d,
+ 0xf0d70e50, 0x64e94fef, 0xe8c68dfa, 0xe2fea1d4, 0x124b7624, 0xee4c989a,
+ 0xa5a2a152, 0x1d449bf5, 0x47d68788, 0x3048cdf3, 0x26ffae9e, 0xeef9925e,
+ 0x06573814, 0xec0caef8, 0x65029bc8, 0x1d8748eb, 0x4b9231ca, 0xf0c1d6cb,
+ 0x67348e3c, 0xd18d7f40, 0x89fd332f, 0xc60920ae, 0xbab1ef8b, 0x4cd7d799,
+ 0x116730bd, 0xe3326efc, 0x75f3d7f9, 0x7ca0490c, 0x246df60c, 0xc1b7d846,
+ 0xe31cfbe4, 0x54f4bc4b, 0xf52ed1d8, 0x03f41364, 0x02769344, 0xce9935df,
+ 0x16b3607b, 0x1ea09162, 0xbbe0b965, 0x337f008f, 0x90c33479, 0x009f5dbf,
+ 0xade96f7e, 0x28ffc0c5, 0xf3802d3f, 0xeb5db11f, 0xf05e7d43, 0x5f5f1b27,
+ 0xa94fe72b, 0xfec24054, 0x7e9fce65, 0xfc8c5e6a, 0xf6b88129, 0x14da7f03,
+ 0x53f9013b, 0x7ae37132, 0x156827e2, 0xa5d1267c, 0x6ad727ac, 0x23c87c55,
+ 0xdd52fac1, 0xe48ddfca, 0xc907ca14, 0x1cb94ae7, 0x2e4a768f, 0x157423f8,
+ 0x44f51cec, 0xb4fd78b1, 0x9aceb668, 0xbff31b04, 0xfdb8b145, 0x2101f4d5,
+ 0x017ad5ff, 0xb5da5629, 0x413d368d, 0xb512553f, 0x7ea187a8, 0xf4c09350,
+ 0xd03df783, 0x5f21f72e, 0x0bfdc13e, 0xaab82753, 0x77df14b4, 0x4ea391e6,
+ 0x724b2e5a, 0xba5026d7, 0xb9a47e99, 0x6bd69ea1, 0x3ef922df, 0xb18e165a,
+ 0xf8a76dd4, 0xecdb3b5d, 0x6beb4d58, 0x3dd48ccd, 0x97d40689, 0xda69c808,
+ 0x829345be, 0xf02691fe, 0xb47e52c7, 0x4011e216, 0xda098317, 0x593f54d3,
+ 0xb6e3a46b, 0xd658b7ac, 0xd58fc1db, 0x85fc0e37, 0x65888b7d, 0x3e73092b,
+ 0x4773d12e, 0xd424fcf1, 0x4e255e29, 0x6df7e26f, 0xab0e7bf0, 0x3b05298f,
+ 0xe9cbfd90, 0xfc0b0ca4, 0x4f2cb937, 0x5cb3a9a0, 0x39eb4897, 0x4fe81d63,
+ 0x8c4f9c26, 0xe7e1df10, 0x5ce05470, 0xaf217b60, 0xb87cea0f, 0xcbe6092a,
+ 0xaeee0e23, 0x58239c0b, 0x50fe85ac, 0xe0f1ccca, 0x09237c73, 0x2af983fc,
+ 0xde23f303, 0x43b6f2c6, 0x76bc59b3, 0x1fb7d684, 0x5e28f9ce, 0xd332f216,
+ 0x43be5525, 0xe8c8bfe9, 0x0edbb038, 0xb0c97520, 0x43cb52ef, 0x91fdf0ad,
+ 0x81e277ae, 0x52368daf, 0xd6cb40fe, 0x92c38732, 0x80d6fb83, 0x2747a9ff,
+ 0x0e3393e4, 0x11606b73, 0x9cd5fbf4, 0x96d6a696, 0xfb0c5edf, 0xec0992eb,
+ 0x5c1ca22f, 0xc1359329, 0x8be787f2, 0x09fbfa88, 0x207fbfcc, 0x21379c61,
+ 0x74f82e28, 0x7283d702, 0x8ff02e49, 0x2cfdf3a0, 0xf9775bd0, 0xbfce919b,
+ 0xff9f9db2, 0x75c39c3b, 0x3e72efa8, 0x8badf820, 0x274cc5e7, 0xa7c01d4e,
+ 0x01f28a2b, 0xbe563f5a, 0x34c0f90c, 0xdfdfc6e2, 0xa6f060ab, 0x7cc1d788,
+ 0xf5282653, 0xca5c3b8d, 0xb55ab4fa, 0x9ebf423e, 0x74eef814, 0x46bdb2b7,
+ 0x941397e8, 0xeface5fa, 0x9ca2b25f, 0xe1ba7e4d, 0x97f040f2, 0x8225d54f,
+ 0xe793b0df, 0x184a74bb, 0xf9e26a1f, 0x921d4d2e, 0xa9a5df22, 0x8903de73,
+ 0x8d2ef941, 0x77cb571d, 0x09c8fa61, 0xf83f779d, 0xa32c4fd5, 0x39dfa63b,
+ 0x0e22f3c0, 0x51445e42, 0x73ccfe80, 0x52909f98, 0x33d1fa33, 0xd00e312c,
+ 0x8a69d7ab, 0x2eb8afd0, 0xfff0acd6, 0xace55fae, 0x9fc27e82, 0xa65cf228,
+ 0x3b734819, 0x641d53f3, 0x8fcc5cf9, 0xb4f6e5e4, 0x7e124137, 0xc7e835e1,
+ 0xc4df9d52, 0x24f28278, 0xfa2e6671, 0x0b3b6b0b, 0x4b5fc18b, 0xb1fa12e5,
+ 0x1c7609bd, 0x442eeb5f, 0xa62dd73f, 0x683f18e9, 0x5da2dcea, 0xcfd00a68,
+ 0xc5dd055f, 0xbba01890, 0x4ed1ff7e, 0xdc8ffa03, 0xa06bebb2, 0xafbd7aaf,
+ 0x12e92880, 0x77248f7f, 0xebbc7096, 0x17d35c2a, 0x1ef4b851, 0xfec03bd5,
+ 0xe2058aa3, 0x563dc5eb, 0x1ada83e4, 0x4d7efc82, 0xd97e4139, 0x4ff985bb,
+ 0xbd2eb33e, 0x9afef815, 0xaa72826a, 0xe10e36c7, 0x0f788cbf, 0xa5b8e93b,
+ 0x053d299b, 0xb6bbfff1, 0xa4f5eb29, 0xfd78f91d, 0x44ba10f6, 0x56f824be,
+ 0x3acbb103, 0x52ec6b88, 0x9883278e, 0x7870777c, 0x3abe7217, 0xadb18efc,
+ 0xae1f6f10, 0x2c85fc61, 0xa0d7a474, 0xf2cb34fd, 0xbab01469, 0xe92ba5a7,
+ 0x33e6bd47, 0x8cc73b32, 0xf9f0967f, 0x84bd7cd5, 0x6b3745eb, 0x1450a1a9,
+ 0x7f6873d0, 0x74d41fac, 0xc09a29ca, 0x38f98b3a, 0xbe095fa1, 0x5e55f02a,
+ 0xa5194846, 0x39139bb3, 0x3649b3be, 0x8fce9be0, 0x46412e74, 0xf7e70d8b,
+ 0x8a343d80, 0x83d28f7f, 0xa3cae807, 0x7e817a31, 0x28cd4ad7, 0x47a08c4f,
+ 0xe4bd72d3, 0xf2fafe46, 0xf40c8f52, 0x4f349231, 0xf80b35b9, 0xf00c576c,
+ 0x15274a1f, 0xfa018989, 0xccbe2569, 0x8e82921d, 0xfadbbdb0, 0x123a5866,
+ 0x1ef7dffc, 0x11260bd3, 0xefd1bfaa, 0xf4c4ff3a, 0x12d28397, 0xc7aa13a4,
+ 0xe5fd041d, 0xafb30d4d, 0x406dd226, 0x128b2abf, 0x9453e3ff, 0x10f689f5,
+ 0x013cc0fa, 0xbd3c3f67, 0xa4cf585a, 0xa73f655c, 0xc9445fe0, 0x25c8b2bf,
+ 0x743f0766, 0xbfb05ef8, 0x5c925663, 0x8d520788, 0x4c3831cf, 0xf13ea5bc,
+ 0xd7dbf73b, 0xdbf18627, 0x3db8eaf7, 0xc6b3a2a0, 0x6ce767c3, 0x147a0120,
+ 0xd246e2e7, 0xf850a72c, 0xf163bf49, 0x0e811b91, 0x19945d29, 0x3be81e49,
+ 0xc3f998a4, 0x7410f9c4, 0x1b6bca57, 0x240d9d04, 0x6ece8103, 0x7f4288ea,
+ 0x6f408de8, 0xf90b7e94, 0x0b9e42bc, 0x2cb5bdbd, 0xa4b2be84, 0x39eb941c,
+ 0xae424f40, 0x8f1c970f, 0x7a0597df, 0xf6f507bb, 0x436a7a20, 0x3d28927a,
+ 0x4427bfa1, 0x55db2a5e, 0x7ef026f4, 0xe5a3eb9c, 0x85ed19a4, 0x4e4cd1a9,
+ 0x3d99aafa, 0xd224d94f, 0x8c35ebdb, 0x1388aade, 0x289cade9, 0xa8d2a4e9,
+ 0x91e9abac, 0xa4a3517e, 0x9bd23737, 0xd1234e9a, 0x37a040db, 0xafe32f21,
+ 0x137b6f4e, 0xff33ff4d, 0xedbd285a, 0x76b92c4d, 0x6c7c137a, 0xd2a59447,
+ 0xa97c7204, 0xf8617284, 0x50ad41d1, 0x8590da1f, 0xab0ee7fa, 0x37b600e3,
+ 0x2ee2f6b3, 0x0ef90ca7, 0x7b782b39, 0xea12ab96, 0x3b692b4d, 0x38e4ba9d,
+ 0x741887cb, 0x5c2f6b3f, 0x0cc07cdd, 0x1b0f2f7e, 0xb5f3f7bf, 0xf76d2c72,
+ 0xcbe3e5ae, 0xdea12adb, 0xff8d8eb4, 0xc328e20c, 0xdbca8f20, 0xb75fbf0a,
+ 0xccc1cb21, 0x8ef7a657, 0x21ddfbe1, 0xe3803ced, 0x25b8d8da, 0x04d18d87,
+ 0xcfa66ced, 0x39f7ccde, 0x67db3366, 0x4cb747c2, 0xa7bf83b0, 0xd8fa83cf,
+ 0x52fa9aa7, 0xec1173e4, 0x2da972d4, 0xc0f1ca03, 0xbbc064bf, 0xcd9c9d63,
+ 0xe95b68e2, 0x644abe27, 0x7f110e7e, 0x75773882, 0x55f37e90, 0x8a13f322,
+ 0x8236497e, 0xcc7912fa, 0x8888768c, 0x211ef98f, 0xd84f9c12, 0x148b8c23,
+ 0xd39f1b2f, 0xf8c3fa8c, 0xe64e2281, 0xdfa7ced7, 0xc5fcbc2d, 0x987e70b8,
+ 0xbd32247f, 0xdb8f0ce5, 0x7a97df8b, 0x077f3c59, 0xc01a4910, 0xd626f755,
+ 0x2b0844ad, 0xbc03290f, 0x46cc7ab2, 0xa8ebc7e9, 0xd344bf91, 0x7080f5ac,
+ 0xff3094cb, 0xf1177268, 0xae86c5c5, 0xf896bc7f, 0x087f2cf4, 0x55b8bfd7,
+ 0x8443f98f, 0x383bb5f3, 0xc1e8c8fe, 0x72a7ce78, 0x7124a53c, 0x19387dbb,
+ 0x0eea7c0e, 0x8d3bb78e, 0xa7263acd, 0xfe2a74db, 0x7a049191, 0xfa88a6cf,
+ 0xc55db2b8, 0xeff2965f, 0xf87ae62e, 0xfe87d232, 0x1eb94fc2, 0xd313667e,
+ 0xed22efc3, 0x7dec2fe8, 0x0d9de98c, 0x2f407b74, 0xbe4abccb, 0xb28cf750,
+ 0xacaed0de, 0x0eb15237, 0xa87537f3, 0xf31e4ef8, 0x6a6ef6c3, 0xdbff0528,
+ 0xa28f47d2, 0xe0a977df, 0x9f255e33, 0xc67ee421, 0x1eb91e67, 0x7b6a3ffd,
+ 0xd4e9d85d, 0x0929be3e, 0x999690e3, 0xcc37a0f5, 0x0f796189, 0xf91f29b2,
+ 0xf688d982, 0xa0be2472, 0x5e8483b6, 0x7f0fae42, 0x3204a85e, 0xe0823ec2,
+ 0x5fef82ef, 0xb6525ec1, 0xec23f0ab, 0x3f1c1995, 0xe1fe2853, 0x76127f3b,
+ 0x9f8632d2, 0x0875c4a9, 0x5ddef3f0, 0x6ec23f0c, 0x9276e6fa, 0x93b60e53,
+ 0xad75bd84, 0xefda92f6, 0xcf5bce2e, 0xdacf6100, 0x026d9ed1, 0xddfe5340,
+ 0x13c4f7b0, 0xefd02455, 0x68710b58, 0x72f54175, 0x66b57fa5, 0xc852e9d2,
+ 0xae88cc9f, 0x46e017b8, 0xffd1133a, 0xec2c90d8, 0x34ff3627, 0xe175cf9e,
+ 0xdb38accb, 0x29c4fc95, 0x836b86f3, 0x6d5ee3ec, 0x43d82c5f, 0xfc2497bd,
+ 0x61add42e, 0xf18151e2, 0xe87c710b, 0xf7bebbf7, 0x4f73e067, 0xf13c60c4,
+ 0x2ecc97c2, 0x2879b0bc, 0xe39f15e6, 0x87015771, 0x799f8725, 0x70e70fd5,
+ 0x10e182e5, 0xbc93aebf, 0x6da6ed5f, 0x9fee8c23, 0xd3adf9c3, 0xbe8cf4f8,
+ 0xec445c58, 0xd3dfb23b, 0xff4f7c83, 0x7dbf931a, 0x89e63452, 0x0487dfd2,
+ 0x273687c7, 0xf081f8b3, 0xf93909c7, 0xe56f5e47, 0xa35a9ef7, 0x3f98fec4,
+ 0xf3bc52e2, 0x1fff8029, 0x57e0fd61, 0xfc87477a, 0x10e6fc1c, 0x9952a4b7,
+ 0xd742dba4, 0x6df9f105, 0xdf9f10d7, 0xc5e4c499, 0xb08b4a39, 0xe73645be,
+ 0x33bdf08b, 0x86790e3c, 0xc4ceb1c7, 0xbed6b8b2, 0x7cacfefe, 0x2267979b,
+ 0xbf45d1c4, 0xae8c5b8f, 0x3ede9435, 0x35ae216c, 0x1fd83e54, 0xde633431,
+ 0xafb62ccf, 0xcc563dde, 0xfee31513, 0x0e7e5494, 0xd5acf1d6, 0x85ca1875,
+ 0x347bca6d, 0xd41fb0bd, 0x7abed837, 0xbe2958a3, 0xeaa4a7f7, 0xdecf8073,
+ 0x67c47ee9, 0xa8a47d7f, 0xdefe70bb, 0x5fc8fc9b, 0x345bf709, 0x2918f3f0,
+ 0xf8b5760e, 0x3c8e3a97, 0x1e6f9c5b, 0xa6c59e47, 0x1c79b322, 0xac918e79,
+ 0x73eda74d, 0xffd1933b, 0x33d634be, 0xf6471144, 0x78a37cc4, 0xdec7a0be,
+ 0xec388101, 0x0e20df63, 0x3be9397b, 0x4e5ec38f, 0x5587130a, 0x025fe9c7,
+ 0xc01741bd, 0x0616ddc3, 0xbeb92ab7, 0x17a0fc12, 0x8fcc1216, 0x8fd9242e,
+ 0xec3d068c, 0x91788e88, 0xfa3d326f, 0x744b786a, 0xe15d8869, 0xf6268ebf,
+ 0xbaa4fda0, 0x6a3a8a6d, 0x877941e6, 0x14d34be9, 0x673407e3, 0x5c0ffa2b,
+ 0x3da2bd79, 0xa8a453cb, 0x51bbace7, 0x5b707fd1, 0xf43ea285, 0xfd145bd1,
+ 0x28d6f3af, 0x7fe017ea, 0xc8c9af90, 0x66786ed7, 0x92fc6286, 0xf52c5e37,
+ 0x7cb9b6c1, 0x8b72e56e, 0x795d9c78, 0x02fdcca5, 0x9f6fc8fb, 0xf89798af,
+ 0x0a549f24, 0xeff64971, 0x87bb2c5c, 0xc58bb0b1, 0xdc758607, 0x684ef8a5,
+ 0xa32ed25c, 0x9121d5de, 0xf8d0a4c7, 0x87ced2e4, 0x8ade42d7, 0xffa17f5a,
+ 0xa0c5b572, 0x3e6344ef, 0xa99f5aa4, 0xa027364a, 0xd24691de, 0xe9ab5d18,
+ 0x0f0fd4c2, 0x4851f7b8, 0xba323c86, 0x0a174158, 0xa1f851fc, 0x76c2eb7f,
+ 0x2d35e633, 0xd2016379, 0x494521a3, 0x25765117, 0x2ae4c45d, 0x50ecc2e9,
+ 0x995c41d2, 0xf0d40e92, 0x74953ab6, 0xbff4fc41, 0x7e3bc02b, 0xd46e9282,
+ 0x7d222ef0, 0xd80f3187, 0xdf00392b, 0xeb2f786a, 0xbafb82d8, 0x3cb8be9a,
+ 0x3917c799, 0x741f877c, 0x6e109ab6, 0xf8493f2c, 0xeedc0c03, 0xbf4a0926,
+ 0x56abd098, 0x8dbd7325, 0xf2fc23cf, 0xda0f256b, 0xb871fdf1, 0x2fa65f32,
+ 0x66f9ec0b, 0xae43fcc2, 0xc3139207, 0xf7f117fa, 0x0145fe48, 0xff5ca9d7,
+ 0xff2c23ac, 0xf31478e6, 0xbd5c7d0b, 0x8b42fd0c, 0xd1ea3349, 0x73c66ae7,
+ 0xfb07a1ff, 0x0219e1a9, 0x529d353f, 0xf904957d, 0x1aa2ef5f, 0x142726b2,
+ 0xe4a7529e, 0x533dc333, 0x81e429d2, 0x5013dd9b, 0x84e857fa, 0x12bf3052,
+ 0x5f98b0fa, 0x31f04fc0, 0xfc01af31, 0x540e7032, 0x2ae48d7c, 0xc7f6a2f1,
+ 0x963031c0, 0xec5bc706, 0xa33e3824, 0xfc04c3f6, 0x84fed42f, 0xacc0e178,
+ 0x3a07b856, 0x3f44e2dc, 0x9ae9095f, 0xff0bbf09, 0xae21fa0b, 0x887efd23,
+ 0x2aea7288, 0x1e29ddf1, 0x5678ffc9, 0xc4575c68, 0x3e182989, 0x3c1d33fa,
+ 0x800fb25a, 0x1decd475, 0x1474089a, 0x9c7497ea, 0x23ce857c, 0xa1e2fa6b,
+ 0x2824155f, 0x5f7dc507, 0x9fb8fc97, 0x81f3893b, 0x8dddfbe0, 0x4cdc7da4,
+ 0xf95307f4, 0xf3250b18, 0xb50e915b, 0x7f45adde, 0x04ee86b1, 0x048ebde8,
+ 0x02b33bc5, 0x439758ed, 0x479ad7eb, 0xc2c53933, 0x3e5809f3, 0x4ffce128,
+ 0xed9191d8, 0x16fae535, 0x49661698, 0xc105f7f4, 0x7586b8eb, 0xb8097c8a,
+ 0x90710a27, 0xd7042981, 0xc76c95d3, 0x4fa21bdf, 0x6e84ebbd, 0xc1995dc5,
+ 0x9e936e7a, 0xb760361a, 0x716064bf, 0xfea576cd, 0xf4c29d1c, 0xe070c8e0,
+ 0xbb2a59f9, 0x8f7a6ae6, 0x4aeacfc8, 0xf7d628b6, 0x362b9c60, 0xc06f7e85,
+ 0x92a7ff49, 0x4abe3026, 0xc43cc6ee, 0xde321d0b, 0x89bc6aa7, 0x3dc687f1,
+ 0x9ea11e32, 0x17de034e, 0x0071da5e, 0x16eea5f5, 0x7ea880ca, 0x7e85b672,
+ 0xe015f079, 0x246fdaaf, 0x31e4417b, 0x7ee1490d, 0x10520288, 0xf105079c,
+ 0xf1b094fd, 0x27fcfeff, 0x93e73b65, 0x1c5e7255, 0xcfeda3dc, 0x65f6d16b,
+ 0x47e104d6, 0xb8af8fbd, 0x73aa525d, 0x70a14f0d, 0x632ba0fb, 0x2557cc23,
+ 0x034e1e77, 0x1c90acf8, 0x631b7f10, 0x0d1bf760, 0x734772f2, 0xf4379d90,
+ 0x7105d95e, 0xee2bd3ce, 0x69fdc1b1, 0x4950ef31, 0xa8f0f783, 0x0ffef185,
+ 0x36ee218b, 0xd69eb1cb, 0x9d981b66, 0x18bdf599, 0x5f3d0e5f, 0xfbb3d3bf,
+ 0x66ecba5f, 0x67d057bc, 0x976fd195, 0x40b19320, 0xe2bd6217, 0x1df8a2de,
+ 0xfe4353ee, 0x4c7df8a6, 0xbbf0df6b, 0xb14a6969, 0x187bde2b, 0xbc37d953,
+ 0xbb8014d9, 0x4c6ad7c8, 0xfd05afd4, 0xeac8c7a8, 0x7a8b99c4, 0x3b230ae4,
+ 0x3db8a75f, 0xb0b06a76, 0xe0e67da7, 0x28c6a83c, 0x93e61c67, 0xb01323bd,
+ 0x38b4bf3b, 0x5fb8ace3, 0xc2c79b0b, 0xf9e1e9e6, 0xabde2bc3, 0xb12d7b40,
+ 0x531e7c35, 0xbbd30a43, 0x8aca2feb, 0xad7aa63c, 0xea91f30f, 0xbf15ea2f,
+ 0xe2e1487f, 0xf3ea0431, 0x071a0ccf, 0x1c405beb, 0x82ffa16b, 0x13c43175,
+ 0x3c8897a4, 0x7c3d3566, 0x68dff1cd, 0x30ed12d5, 0xbaec0fbc, 0xfe57bf52,
+ 0x5fbd8729, 0x468a48f3, 0x1e61a1e4, 0x3037b531, 0xf7eea79e, 0x7cea29ef,
+ 0xe7de3f33, 0xdb37cfec, 0x77c57e53, 0x962f1a19, 0x1bc1f22b, 0xd71878e9,
+ 0x2aac7178, 0x4bcf9c1f, 0x029bb3e7, 0xe0916679, 0x5b3275ff, 0x91e42357,
+ 0xceff07c5, 0x9df029e8, 0xe6179e04, 0xf8f3858f, 0xf78c876c, 0xa23d9f9d,
+ 0xcc35b099, 0x5c393bba, 0xe2d44fae, 0x47c1b939, 0x7cc25b9c, 0xf713f45f,
+ 0x3c7dc419, 0x5576faf5, 0xfac0e7f8, 0x7e658c47, 0x2f3cf561, 0x758af870,
+ 0x7c31b2ef, 0xf14abe34, 0x2c28f981, 0xcd97774f, 0x83f918bf, 0x4fe78945,
+ 0x763ad992, 0xc4cfe2dd, 0xcc899cfc, 0x0f448eae, 0x7fdd58f7, 0x9a6e3d45,
+ 0x48d57209, 0xb259b6a9, 0xabb79d04, 0xee0043d1, 0xa1af02b2, 0xbb63d770,
+ 0x63f3f798, 0x7e7edcec, 0x61539d8c, 0xa8fe7c0f, 0xf401f98c, 0xa0a49b40,
+ 0x09cffb3c, 0xde7c0b8b, 0x3ffea126, 0x4ac84ddf, 0x6de677ca, 0xe2fa63ab,
+ 0x7531c353, 0x9fbf7e07, 0x547997f2, 0xcb4cddde, 0xf1546bf9, 0x08576e61,
+ 0x8370bc39, 0x1b21deca, 0x3cc64bfe, 0x279466cf, 0x1cae7f8b, 0xa4db74bf,
+ 0xea7be0cf, 0x4afa3638, 0x71fcfda9, 0x4bcbd70a, 0x83c82949, 0x42fa9fbb,
+ 0x7c8f6b1f, 0x7e50ce1e, 0xf030683b, 0xdd96235d, 0x2f2c162d, 0x41bb38a6,
+ 0xdd53e83e, 0x7bd7c0bd, 0xbaf061df, 0xc9817f50, 0x39bcb80b, 0x84b9f812,
+ 0x9330cef2, 0x841f79c5, 0x2e14ec7b, 0xfb930306, 0x35fddc72, 0x5e957193,
+ 0x7e118ba4, 0xca2b1ccb, 0xd00a4723, 0xe373c27f, 0x13fc0027, 0xc2718b9f,
+ 0x7b97d6be, 0xc37f069f, 0xe8d155fa, 0x581a35ff, 0x7b67399c, 0xc0ec06b9,
+ 0xfb4976eb, 0xd4d1dfc1, 0xde172ab9, 0xa3d93017, 0xae213f31, 0x93165e73,
+ 0x093bec73, 0x801daead, 0x57b804cf, 0x3eb5d747, 0xf8c29bcb, 0x1a83d338,
+ 0x257bcc39, 0x3dc07ffb, 0x321bcf6b, 0xa0bc83de, 0xd7fcf965, 0x915f8613,
+ 0x0edf050f, 0x29baf7d6, 0x40d0c8dc, 0xc976fafd, 0x77c58ba7, 0x515e3024,
+ 0x3497dabf, 0x6fd1e413, 0xe9ef18b4, 0x52efd75f, 0x23ae202b, 0xc94cd0e4,
+ 0x5c47fcc2, 0xc44e9d9f, 0xaa17163f, 0x9d3274e5, 0x6333b1eb, 0x13e77c18,
+ 0x9b8c2647, 0x1ab12461, 0x5666947a, 0xfee097b6, 0xd05674ea, 0x237c4407,
+ 0xde111eb2, 0xb4f8d3ef, 0x94c7dd99, 0x24c086fa, 0x72a7c167, 0x3a37f385,
+ 0xc69dc995, 0x4b8fcc21, 0xc4271106, 0x1d5f1ad3, 0x72ec05ba, 0xdb8b3443,
+ 0x8464be52, 0x810e56f7, 0x5efba6bc, 0x7b144af6, 0xc7dc433f, 0xe10b38b6,
+ 0x4d53637e, 0xb7de1146, 0xef87d93a, 0xfce8f420, 0x297e7899, 0x4ca891bf,
+ 0xb6d373bc, 0xce94b55b, 0x3ea8d31b, 0x366beb46, 0x0b55bced, 0xfdb2e4f7,
+ 0xfeb4358b, 0x58b7a6fc, 0x4ffef5fb, 0xa6f2fea1, 0xc8bdac13, 0xf5a658bf,
+ 0x613e9b63, 0xa4d060ed, 0x4d97f211, 0xe87ab7dd, 0x5cad67fc, 0xf1f871df,
+ 0xdee36a1e, 0x7f609aa1, 0x8ca99be2, 0x628d9d5f, 0x9166cefd, 0xef0035b9,
+ 0x5ffdf0dc, 0x24f0d548, 0xc52c368d, 0x9278c57e, 0x22dc7e12, 0xbf196e3e,
+ 0x86263a87, 0xf1628bac, 0xc52c4f29, 0xa1cec1c3, 0x989b5f18, 0xf370e36a,
+ 0x62253be3, 0x314f011e, 0x5deef89f, 0xbe599720, 0x9e706d5a, 0x7f1cddfa,
+ 0xf06b3bf4, 0xec9c833b, 0x464d66fe, 0xe28fe021, 0xa6f1cb4d, 0x7b89bc05,
+ 0xb5af30df, 0x70fff900, 0xbc1f5bf0, 0x0567fb44, 0x93a6add6, 0xa7c65496,
+ 0xb8b2b597, 0x07359f62, 0x0c4c69e9, 0x58a2f77f, 0x1c638fb9, 0x5aa66f0e,
+ 0x01073df9, 0xbf0964af, 0x98e1cad3, 0x93521fe1, 0xfdf7cdff, 0x77cf5f30,
+ 0x7c20efbd, 0x8afde139, 0x6dd71d83, 0xb1b1fb65, 0xcf4a54bc, 0x1ef3d436,
+ 0x7677cc56, 0x197c6a95, 0x5fb0903d, 0x7f8e0e5b, 0x2077bf90, 0x7182f3de,
+ 0x3f4c0559, 0xdc55bd05, 0x9b9e27d3, 0xb4ffb049, 0x3b7e3eff, 0xd81b37bb,
+ 0x7cc5ade7, 0x4fbe169f, 0x57a7db0b, 0x78e4af41, 0x7354e65f, 0xc3f71d28,
+ 0xbcbe7fbf, 0xe29f3e22, 0x0f9b879c, 0xbc2475ce, 0xf1aefc1c, 0x82a9d622,
+ 0x559c3f67, 0x84f013eb, 0xf2e38df3, 0xd6297494, 0xf3a472f9, 0xbf2df59d,
+ 0x35c6ce57, 0xf7e580fc, 0xae92bb12, 0x6965761b, 0xc62e7e20, 0x2ecf03e5,
+ 0x3ebdf809, 0x6076e54b, 0x9088c906, 0x352e778f, 0x7f0cbfbc, 0xbd81db57,
+ 0xacef9656, 0x26f407f6, 0x109cba3a, 0xeecf3a47, 0xf9528f6f, 0xb29e202f,
+ 0x171814d3, 0xfaca2f90, 0xbf0634c8, 0x1f4bff50, 0x362d2fde, 0x7768bc54,
+ 0x31eebb50, 0xbfc06dcd, 0xee2ae38b, 0x98f5a2c9, 0xc06ddd34, 0x2bd38bbf,
+ 0xfca2c8be, 0x67a69cdc, 0xbe2a1bf5, 0x63fa86c8, 0x8c7fd67a, 0xf7e045f3,
+ 0x6dbfa3c4, 0x8f406a6c, 0xb3b34d88, 0x1a9553fb, 0x5fabff7c, 0x019df97f,
+ 0xd70117f5, 0x41b16548, 0x4e2e1cd3, 0xe8269c95, 0xca13c581, 0x90ed7fe0,
+ 0x7cedc4f7, 0xe76156bf, 0xfbb2c6f7, 0xfefbbdb7, 0xb227f786, 0x6919dcd3,
+ 0x314d5d74, 0x68b273dd, 0xfbcc757d, 0x9c92af18, 0x3f010f54, 0x6642dd87,
+ 0xdd4af5d1, 0x2fa05deb, 0x461cbb91, 0xfb95c22d, 0x314de07d, 0x5e57bf0a,
+ 0xe97dcdfd, 0x582e33ec, 0x07ce48c7, 0xfafd5e9a, 0x3673882b, 0xc039359d,
+ 0x73b23e2d, 0x6fa03dd3, 0xf37cec8d, 0xd987266b, 0xeeb10f7d, 0xa3d7e091,
+ 0x187597bf, 0x3b23fd70, 0xfd045baf, 0x33a1fd47, 0xa6e4e807, 0x6056be53,
+ 0x5efbbd0b, 0x1fde574e, 0x798aecfd, 0x4de3118c, 0xe89f1e02, 0x1499e809,
+ 0x7833371e, 0xab7cc25c, 0x6b63c49e, 0x2b97a8fd, 0xbd50d3ef, 0x17a6e31d,
+ 0xfc03b448, 0xb35ee2f8, 0xb2785fda, 0xfe8fee9a, 0x5d1f537e, 0x3cde9041,
+ 0x3291a2e6, 0x9cbd4092, 0x4af51558, 0x7fa2aa63, 0xd14b2595, 0x3ae53e3e,
+ 0x7b44fb45, 0x293ea2a1, 0xffa2a477, 0x45728e6d, 0x89b2f6fd, 0xced5fe8a,
+ 0xd0bd456a, 0x3fe8aed7, 0xb28748fc, 0x019138fd, 0x1d27450f, 0xf92ca007,
+ 0xc76e89d8, 0x07cd33d2, 0x25f91ca0, 0x5fda8703, 0xf6c5e37a, 0xf0bbf003,
+ 0xc7efaa97, 0x34e9ff08, 0x87d5e4d9, 0x68a693f7, 0xf25e7969, 0x35913f23,
+ 0x2d8c7eec, 0xe02f7dd6, 0x198fdc4d, 0x8a52fe03, 0xe7b9aa84, 0x59f0bdd9,
+ 0x12765fcc, 0x69fc0310, 0x7cfd19ba, 0xcfcd7527, 0xbdc599ff, 0xbbdf0007,
+ 0xb156afa9, 0xdd1731ef, 0x93977d8a, 0x2d3c2a65, 0x2cabd457, 0x1ff4503f,
+ 0xd14ab29f, 0x90fed13e, 0x2b0f4f0a, 0x3639b7ea, 0x45b4f0a9, 0x28dfa785,
+ 0x70edfbda, 0x157abfee, 0x1cb44efc, 0x04aaefed, 0xa67cdc3c, 0xd651f10f,
+ 0x780956d5, 0x3b64f1ba, 0xe7d8abe2, 0x597604aa, 0x00f9a47a, 0x7f6a3e94,
+ 0x5ad7b8c1, 0xd83cb052, 0xd5ff4762, 0x2c5c96e1, 0xf038b48f, 0x94b7dff7,
+ 0x8b56f961, 0x6cffcb13, 0x57658099, 0xf6cb0b8b, 0xbfec7696, 0xf983a5b3,
+ 0xdffbe2bf, 0x7e001815, 0xbf8d1e81, 0x3c56ee11, 0xe434d8f7, 0xfed13d9f,
+ 0x26afa81e, 0x9636de77, 0x81e78d32, 0xcc9d8089, 0xcee9a3cb, 0xbf94e9d1,
+ 0xac1c85ed, 0x41fe4092, 0x0859c6bb, 0xb4e1f87a, 0x0ed13f05, 0x5581e420,
+ 0x958b14ae, 0x8eb48dd5, 0x643186c8, 0x199c4fc1, 0x25105e74, 0x70584c18,
+ 0xa37bd41b, 0xb4defb58, 0xf279b705, 0x637107fe, 0xe17e4867, 0x7130b4e1,
+ 0xd8cfe7e3, 0x39cfe0cd, 0x19a86976, 0xfb8c71e0, 0x50a49cb5, 0xe5968f37,
+ 0xc81d42da, 0xbd2a93d9, 0xe4539444, 0xde61b7f2, 0x0ee38d76, 0x45be6fcc,
+ 0x6b7e8047, 0x8aef6624, 0x99d3db7e, 0x9b7bd0bd, 0xe3a9ed01, 0xbc22e71a,
+ 0x3df52717, 0x49ee7001, 0xa9ca3efb, 0x265f735e, 0xed3bafc0, 0xd89eac7b,
+ 0x08e484f7, 0x7c18ebaa, 0xf7bb4fde, 0xd9cf86bb, 0xf85092b4, 0x5859a6f4,
+ 0x1ce7c0dc, 0xaf007a80, 0x3676af1f, 0xdcac9c60, 0x71f61839, 0xe76065cc,
+ 0xfbc665d7, 0x2ceb4413, 0xbfc823b9, 0xc3ae9753, 0xa2e15371, 0x6739f81b,
+ 0xd5ce78c8, 0x9d287cf0, 0x27481fd9, 0x8f4e6760, 0xb8e0bb41, 0x5737dd86,
+ 0x9d267ff7, 0x1173d9c9, 0x0dfd83de, 0x94c57b87, 0xd377e786, 0x44577af9,
+ 0xaebdd4e1, 0xf58fa8a1, 0x9f784b36, 0xf34cf7b7, 0x706ed679, 0xdc609070,
+ 0x1ffc2672, 0xf3be7f6d, 0x91febf9e, 0x457f7ff6, 0x8865038c, 0xdf847ae5,
+ 0x7679de0c, 0xa7f511bc, 0x2a0335d9, 0xe4ce2e40, 0x6639b071, 0xc386126d,
+ 0x3c3d56b4, 0x54d0b89d, 0x904296b8, 0xd6a84e2c, 0x4b4553c3, 0x85af9633,
+ 0x0f41aef2, 0x9f09e1eb, 0x6b1dbcfa, 0xa06d8d41, 0xf904b847, 0x0b68ff9f,
+ 0x95dcd75d, 0x73d99db2, 0xeb3aae5c, 0x871e51be, 0x3ce3dfa0, 0x010286af,
+ 0xd367d5ed, 0xfb7f8525, 0x61af0e59, 0xcc7f5ce9, 0x1eecf927, 0x609c7f51,
+ 0xeefb9c38, 0x448747d9, 0xdb282388, 0x2ef8feb9, 0xfd56e77f, 0xeef883ee,
+ 0xc7ef1c73, 0x413294f5, 0xe4c19c9f, 0x17ed4140, 0xfee84bab, 0x1a2d3a0b,
+ 0x6dcfd38c, 0xb8780dd8, 0xa8f1c1d0, 0x9e701d23, 0xbde678a6, 0xaa4d398f,
+ 0x9357a17b, 0x4b2e8e97, 0x2cbcb065, 0x832abbf6, 0x5f5965e5, 0x45c8255b,
+ 0x2d7d1f21, 0x6e3f394b, 0xb07a3e46, 0x0fd62565, 0x3cb078b7, 0xf38eb2d2,
+ 0x7f6c36e3, 0xce51e5ab, 0x1f9cbd8f, 0x77bf833f, 0xf962d4b6, 0xcb1b8b6a,
+ 0x33dce307, 0x3e226e00, 0xc6e8d539, 0x9b43d1bc, 0x5fe2040c, 0x980d3a17,
+ 0xc44f4097, 0x40278f13, 0xef018dde, 0x6ff3a9f5, 0x9fbe7cd4, 0xb7df421e,
+ 0x189e9c58, 0xfa033794, 0xf4c8c0e2, 0xcdd88c74, 0xedfe97c0, 0x0f9057f1,
+ 0xcddbb31d, 0xa4b74fa0, 0x38bca277, 0x759bb4e6, 0xbc79eeb4, 0xedbbb593,
+ 0xafad0366, 0xdac7df4a, 0x1473763d, 0x7c7eafad, 0x12f76b1f, 0xf83f220c,
+ 0xc7c86bf8, 0x107489ca, 0x31a547ce, 0x17152c6b, 0x1f975e54, 0x3e317384,
+ 0x3858de65, 0x3d725f17, 0xd57da27d, 0xca4fa841, 0xab85a2dd, 0xe1534edf,
+ 0x9157181a, 0x7185ad50, 0xaf963363, 0x06e37181, 0x1e0dac3d, 0xc76f2137,
+ 0xeadfa81a, 0xfd05a2d8, 0xc7ce4bf4, 0x2ea23cc4, 0x169f05da, 0x3ac360f9,
+ 0x0a0f285d, 0x0f285c3a, 0xa62a5c04, 0x7e003f56, 0xc90ea6c7, 0xa63ac122,
+ 0x71c1fd4a, 0x846ba5c8, 0xbf2922f7, 0x8efe98de, 0xd71d1579, 0xb11bf504,
+ 0xa65593fe, 0x6f7f94ef, 0xdf230f4d, 0x0ef3f04e, 0xbbf21ef2, 0x3bd9e84f,
+ 0x5c035f1d, 0x9b9ef04a, 0x24b5df19, 0xe3fa336e, 0x3d833641, 0xb69e7204,
+ 0x1965e70f, 0x6453fb97, 0xcef876e7, 0xc3f9918b, 0xabfcfccb, 0x68444dee,
+ 0x4f61fce7, 0x4bd985ba, 0x06875dfc, 0xd07e86d2, 0xa997e5ab, 0xf9d5a1f3,
+ 0x59ff2216, 0x4f515f9d, 0xa1307bd8, 0xdeecce79, 0xb39e486e, 0x19a2abb0,
+ 0x5e05ad3f, 0x78f8e943, 0x0957cf3a, 0xabc9c385, 0x3864e1c0, 0x87ec8438,
+ 0x2eef3178, 0x74c6ff24, 0xdeacf11c, 0xb2277117, 0x3f8936f7, 0x5d04feec,
+ 0x8dafee84, 0xe0cb5fc1, 0xb3bbf54f, 0xb9aae780, 0xab7e0266, 0xc7f3fe60,
+ 0x351ff02b, 0xf8aefb5f, 0x0db9b4e5, 0x5080fdec, 0x1c39763e, 0xc2f7131f,
+ 0x53d0a5d5, 0xe41a3ee1, 0x343bc201, 0x4befe760, 0x80674776, 0xf7d1567e,
+ 0xd0ec0695, 0xf37ef604, 0x9cdb9b22, 0xe922e141, 0xc8817e59, 0xf1a33dc3,
+ 0xb6f416fc, 0xc9e6cdb4, 0xb0832fa8, 0x4ac767a0, 0x7e3fe0eb, 0x878aead6,
+ 0xafd72471, 0x3a077e0f, 0x7a699e52, 0xa17f9306, 0x5fe45125, 0xfaf96ef6,
+ 0x8a2fde9a, 0x792a8f04, 0x41ee1fb4, 0x418b285c, 0x112dd9f9, 0xdb3fbc1f,
+ 0x7a849e5d, 0xbd00f74b, 0xdaefca16, 0x301eee2e, 0xdb57e704, 0x65a9ddc7,
+ 0x71ddf646, 0xd0eca013, 0x079d1fbb, 0x0691e0fe, 0xcdbc938c, 0xc7270ff3,
+ 0xb7c3fcb0, 0xc980fdf9, 0x004a5e1f, 0xf65938f9, 0xa1481525, 0x1bf77676,
+ 0x05ec2ab3, 0xdd36f6a1, 0xefd858ef, 0x976eecd5, 0x6006cbb1, 0xf5dfdb55,
+ 0x9022bf2b, 0xe56a3de7, 0xe3f90225, 0xbc7b73ff, 0xa4f5132b, 0x9533e4ab,
+ 0x415b79f5, 0x897318ff, 0x228e39e5, 0x9525ce2c, 0x9bf2c9bd, 0xdbb6a978,
+ 0xbda868e7, 0xa76a1d9e, 0xa5fd92cf, 0xd421ef50, 0xd809cf5e, 0x374ec2eb,
+ 0x45bf9610, 0x3806f7ed, 0xddb9e717, 0x8f13314e, 0x7c3f2179, 0xc87dce6f,
+ 0x9f30a217, 0x8f8ef9e3, 0x7fad6112, 0xc5fc4ae9, 0xbd00f62b, 0x22be5937,
+ 0xf5fa79c1, 0xc120bf2b, 0x7375bcef, 0x8e9b773f, 0xffaa43dd, 0x8a728ca7,
+ 0x8075b5ca, 0x9af27aa7, 0x7920eefe, 0xabffda4b, 0x28c3de1f, 0x3586abff,
+ 0xb4f5bc81, 0x7ed2764c, 0x223edcd5, 0xac76f91e, 0x32927b73, 0x289ed646,
+ 0xeacbbffa, 0x13ff4403, 0xbbf49d93, 0x9da2a9d5, 0xd78ebf8f, 0x6c76ee89,
+ 0x0df312cf, 0x6b337565, 0x72f8cb6f, 0x8231e832, 0xe0cc6fbf, 0x47bf91f2,
+ 0x63fdf944, 0xcc578919, 0x73b651bf, 0x1fde2079, 0xc4e1faaa, 0x6e70a398,
+ 0xb5cc25db, 0x875fbfab, 0xb673fbfe, 0xf7e082f6, 0x8e9e454a, 0x798cd2ab,
+ 0x0d2f0d53, 0x22740add, 0x81278f9b, 0xe3c5d2de, 0x09b255f1, 0x36172ee3,
+ 0x491ebe30, 0xf2bc5bef, 0x42be0515, 0xc0fbf9da, 0xdfa49818, 0x6493ff3b,
+ 0xa0f33ef6, 0xe80bcc2e, 0xde0c7ce0, 0xc37b847b, 0x212bff22, 0x5ec13887,
+ 0x8a39784e, 0x71f953bd, 0xc5dbf217, 0x767f332f, 0x2803a6c3, 0x76cbe6df,
+ 0xc89d27f4, 0xf00abf76, 0x0d7731e9, 0xcaf838c1, 0x3f5d7157, 0xdc785bb2,
+ 0x182f2fab, 0xe143879e, 0xc0abfbff, 0x4afff7ff, 0xfc82eff8, 0xbb73e032,
+ 0x4dbed0a3, 0x0ef5fad6, 0x649e6b88, 0xe79e5cef, 0xfaed2b70, 0xf815df10,
+ 0xd3b30667, 0xdc583ae2, 0x8965e446, 0xc333feef, 0x1e74eccc, 0x79a8691f,
+ 0x47c4346b, 0xc4c6fe04, 0x77f07690, 0x38383c53, 0x07801c1e, 0x9c40ef01,
+ 0x0acb8e84, 0xb0aed79e, 0x23dc050f, 0x7d35639d, 0xe3ab7588, 0x0e997706,
+ 0xef7e0096, 0x847986fa, 0xb0b4cfdf, 0xcc7eb4f9, 0xf011fc13, 0x1e00c4ca,
+ 0xef940375, 0x46bc5180, 0x22b9280d, 0xffed95de, 0xc35778cb, 0xf3d65d4d,
+ 0xf7fa9838, 0xff3403a1, 0xbffc70ab, 0xdd9d5fe6, 0x3ed15fbc, 0xd71be577,
+ 0x7e157fe4, 0x1f957fd1, 0xf5ff9236, 0x16ee992f, 0x2fc9bba0, 0xfc40d12e,
+ 0xffbdf6e6, 0x8b013bc8, 0x5e303bf7, 0xcbdf0f74, 0xf6ffa317, 0x9e947dfe,
+ 0x7e6668be, 0x3ffb53a9, 0x43f3d9d7, 0x45f663e9, 0xe8833899, 0x77caf66a,
+ 0x669f2074, 0x5c22cd53, 0xa70d6a7c, 0xa127cc27, 0x48d6a07c, 0xfcf40974,
+ 0xf7b2d6d7, 0x10216ba5, 0xe7d2c363, 0xb593eda6, 0xc7ef07c4, 0x3eb49b56,
+ 0x9487c603, 0xfc0d61f7, 0x686a597d, 0xcac5ee2a, 0x9ef3194e, 0x716328ee,
+ 0x76a619a5, 0xfd38dfbc, 0xf7f3eac8, 0xe35dd9c1, 0xba796129, 0x9fd27ee2,
+ 0x5e24df34, 0x37e406b4, 0x1e259ff8, 0xc3ae5c87, 0x5c7aa438, 0xfe7600ed,
+ 0xcb12cb26, 0xf2c3d837, 0xa479c4d7, 0x28623bfb, 0xf0f37962, 0xb3756ace,
+ 0x00b437ce, 0xa8fd8ff4, 0xad95347f, 0x353c002a, 0x303e958d, 0xc0f40414,
+ 0xa25f95a6, 0xc7e6a37e, 0xfd5af2ea, 0x1cb7ef50, 0xfa117a41, 0x1f16a9e2,
+ 0xa97ed5d6, 0x8c7e6359, 0x5f919c71, 0xd470bd32, 0x1189e725, 0x6f6f6ff6,
+ 0xd84b3b09, 0x4e3b6a5d, 0x5ef10bf0, 0x0b00fb5c, 0x77c6bb93, 0x5a8ffbd8,
+ 0x4034be56, 0x5f057729, 0xef767ca5, 0x4a5fe400, 0x87c41bfe, 0xc55ffdb1,
+ 0xdf740387, 0x4dff00ec, 0x6f7b066d, 0xf5f74d5d, 0xaa7e4c29, 0x94ae5de9,
+ 0xd3519f51, 0x3bf3a0bb, 0x7fd05b9d, 0xd2c60b37, 0x926acc75, 0xc9d59ef0,
+ 0xd7bc1e97, 0xddd09748, 0xe29d33fe, 0x486fbc3d, 0xe072a1f7, 0xbe23b463,
+ 0x5d201cb5, 0x33feecd1, 0xa84f47c3, 0xc0a0bd1c, 0xbd1ca84f, 0x5fc4aff0,
+ 0xf9cffd98, 0xf0907276, 0xc8bb7f3c, 0x6b239ff3, 0x26dcf7d8, 0x790a0796,
+ 0x765ebd68, 0x56696c2f, 0x4d7fbe1b, 0xe058b20d, 0xc9f6cb23, 0x778b3d64,
+ 0xde835368, 0xbe26ea2b, 0xe0494777, 0x9bf9624f, 0xf7b3464b, 0x9a79d43e,
+ 0x91b3ff22, 0xb4cbbb8f, 0x54788f4b, 0xe62443bd, 0xd443bf51, 0x67fc7a38,
+ 0xf7e7ff18, 0x0fefd58b, 0xf9e4ca0d, 0x88a4459f, 0xccafc7c5, 0x5e407aa7,
+ 0x7b8df906, 0xbda0b52e, 0xf4399793, 0x01193c3f, 0x8665177c, 0x99a5d7e8,
+ 0x94b3d657, 0xfa62ffed, 0xf0dbcd90, 0x4a6f913d, 0xe72c861f, 0x38b75824,
+ 0xf9e7fd27, 0x679e0315, 0xef713ef1, 0xbdf1e7f2, 0x09afde8f, 0xe6ae87c6,
+ 0xcdd3199f, 0xf4dd03ae, 0x4cd5b7b1, 0x94ea3ef1, 0x2304fd07, 0xdef1bb8f,
+ 0x9cb788dc, 0x0a4c8190, 0x5864ba0f, 0x841bd0b7, 0x0be0111e, 0xcf0b7efc,
+ 0xfe56b8f7, 0xdc4bfff1, 0xe9b3dc43, 0x4e4af9d1, 0x13defc80, 0xef1df615,
+ 0x2b9a99d5, 0x60f9ffbe, 0xe0357b9c, 0xbfe70a69, 0x2ad01de2, 0x7bdbbd99,
+ 0x3f464ba1, 0xfd1f8ac5, 0xdb8fb7e1, 0xeb57e743, 0x2f964d67, 0xd247ae50,
+ 0x2c349bd7, 0xd2a8beaf, 0x605af98e, 0x42df80ff, 0xfdd431f8, 0x7e2bd90f,
+ 0xf776899e, 0xac272ee8, 0x9eb651e7, 0x5a6af848, 0xbf0a5ff9, 0x37efa449,
+ 0xccb12bed, 0x7f1f3a0f, 0xfd0494cc, 0x06353e5b, 0x74ad7df0, 0x0ecd7ff1,
+ 0x8f132c98, 0xbe70e544, 0x257a65e4, 0x2ce5fa61, 0x1ce585d2, 0x9ba587d2,
+ 0xf9eabcb0, 0x42e581c4, 0x65d3cf7e, 0x0991bf77, 0x1f5d55fe, 0xfe7b53be,
+ 0xe1e7bfa5, 0x8f37503b, 0xa95c836a, 0xad9fcaef, 0x0b7aafd6, 0x0d38fefb,
+ 0xbfeec7f8, 0x0f51da67, 0xb377b6b8, 0xd3ce71bd, 0xddfc6199, 0xb32e59ff,
+ 0xee97157b, 0x5a4def65, 0x363218d8, 0x2574fb11, 0x09f9e167, 0x2de4cdf0,
+ 0x5c426f82, 0x0d03ff2b, 0x932fcb8b, 0x7505eff0, 0xc47835f8, 0x796517f2,
+ 0x62efa865, 0x560df9ed, 0x717904af, 0xfb58a323, 0x5dfe2b72, 0x8fc4d9cf,
+ 0x3c2e72e7, 0x3dc32b65, 0x0b963b09, 0x54d4fbf8, 0xe896cee3, 0x469d45f8,
+ 0xfc4dcf96, 0x05bf6083, 0xb1849f60, 0xf206cb77, 0xe3367438, 0x542ac3f7,
+ 0x0fce05fe, 0x3315ec1a, 0xe172d206, 0x48192740, 0xad987ee9, 0x20cffd6b,
+ 0x86b7606f, 0xcfafbdc0, 0xe300fe46, 0x2fdc622b, 0xe83a15ec, 0xf2c482f7,
+ 0x0cfb3d8e, 0xa4d4bde2, 0xcbbd3f60, 0xfd03195e, 0xa8b6146c, 0x2b80451f,
+ 0x572abdfc, 0xe44c7b18, 0x1d030db1, 0x0485fd11, 0x417a25df, 0x819cf562,
+ 0x4d7dbe3f, 0x3d30fa1e, 0xc2fe87a0, 0x7d80ceee, 0x6213d30c, 0x92fff582,
+ 0xcd21afdf, 0x5f0f1099, 0x034184f2, 0x547bc67a, 0x833dc31c, 0x167b533f,
+ 0x2ed4d3ca, 0xd42ff285, 0x03f2852e, 0xf942976a, 0xa14bb511, 0x10b1745c,
+ 0xbe2224de, 0xd862ce81, 0xa83b888f, 0x903f9bd7, 0xbb06cdc9, 0x1d62867b,
+ 0x8eb8f4fb, 0x3f5dac17, 0xc75d19fd, 0x6907bb0b, 0x244bbee0, 0xfbeef478,
+ 0xfe95e65b, 0x7f888d3e, 0xf107dba8, 0xd2ec17ef, 0xe82fdca2, 0x0e2ec7f0,
+ 0x503157ea, 0x77f3e38f, 0xf30b1c7f, 0xe1fa58f7, 0x56e894ea, 0xbd586b27,
+ 0x845e57e2, 0x39dd836b, 0xcf4bf603, 0x4fd838f7, 0x7e1fc741, 0xe83af70a,
+ 0xeda718fc, 0x8236fa95, 0x87dea67e, 0x5f62df7a, 0x61ebff74, 0xb3bb0bfc,
+ 0xdf942761, 0xf65e7610, 0x437977b1, 0xf70abbf7, 0xafa1bb73, 0xdc2bee18,
+ 0x9b0e597e, 0x2f60da27, 0xc57f7847, 0x38fed0f5, 0x812ba71c, 0xae7b6faf,
+ 0xf111f3d5, 0x50f001ee, 0x4ba3c83b, 0x560fa0b1, 0xc76678f3, 0xe36f41ae,
+ 0x322397fd, 0x385fbf81, 0x773ca6cc, 0x1278e13f, 0xbd3efe65, 0xc2f5f00b,
+ 0xc1074fbe, 0x3f14a07b, 0xc9efe083, 0x60e068fe, 0xfe7dfe45, 0x031fafc8,
+ 0xf1fda1fa, 0x274e15ef, 0x6e20aa5b, 0xffb8d33f, 0xb6696c10, 0x882a83e5,
+ 0x914dcfdb, 0xcf39430e, 0xe20e359e, 0x79df22f5, 0x61f96e41, 0x3ab74a38,
+ 0x2b8f51aa, 0x2412e607, 0x318d2a17, 0x216051fc, 0xf515e287, 0x8ae929f1,
+ 0x39ed13fe, 0xb949f68a, 0xfbda2837, 0x8638a1ef, 0x06cf7e07, 0x4365f478,
+ 0x83ee8d1c, 0xa7b57dfd, 0xca77cc64, 0x96fc7ddf, 0xf27d681b, 0x7be077d3,
+ 0xf6f02f6f, 0xf12b3bc9, 0x52f59bef, 0x22a9ea78, 0xa1eca675, 0xc9833f8d,
+ 0xfd42f654, 0xc30f27be, 0xd8dfd0bb, 0x2760885e, 0x97a611d4, 0xd417b246,
+ 0x9be50276, 0x39be053f, 0x16a9a5ec, 0x617f0fc8, 0x2069d7e4, 0xe40fb697,
+ 0xfb7066ef, 0xf4fd1221, 0xfec9139f, 0x29fdf076, 0xbf88fd35, 0xc9ca2d6f,
+ 0xa13dd8c7, 0x3ed7ca6f, 0x7686be01, 0xafdb87b9, 0xcff954bc, 0x6f1de986,
+ 0x9efe03df, 0x94dc32a3, 0xb5bfbfe8, 0x0e5ffe18, 0xb8593dd0, 0x04d481e5,
+ 0xfa03ddfc, 0xa7f72370, 0xeb90367d, 0x1ffbf553, 0xb40e2d48, 0x281f1593,
+ 0xa5fb93fa, 0x9afa8ab5, 0x437d652c, 0xf1e0daf9, 0xc5b1f491, 0xbbd3ce8f,
+ 0x9f9ee1f3, 0x3aeff614, 0x8127aff6, 0x4b7d87f3, 0xba7edf90, 0xbdfe197f,
+ 0x46ff7559, 0x01f81f3a, 0xb3904717, 0x974d4f82, 0xeac23bd9, 0xef8abff6,
+ 0xefdbbe39, 0x8f6147bd, 0x332f5e79, 0x9c5efbf9, 0x13a0af5b, 0xf9eefb3b,
+ 0xe8ff0f4d, 0xed2b882b, 0x79d57661, 0x051f932b, 0xc0d33ebb, 0x161e8bdf,
+ 0xc0abe8cd, 0x3dc0d7e2, 0x7e06ff9a, 0x00334c2b, 0x0000334c, 0x00088b1f,
+ 0x00000000, 0x18adff00, 0xf514707b, 0x7bdbdbf9, 0x79724b92, 0x71211240,
+ 0xc220572f, 0x4849ac91, 0x92ea4903, 0xf03ea410, 0xa2a21900, 0x799e0fae,
+ 0x2a93a84a, 0x028d361d, 0xd6d36d52, 0x4f4e2a2a, 0xd1954a2c, 0x2562bc34,
+ 0x40569478, 0x2f2a7b1d, 0x419cca69, 0xee421923, 0x8cc38a8c, 0xbf7dfa1d,
+ 0x5eddcddd, 0xc9a75502, 0xf6fbbf1f, 0xcfdef8f7, 0x05048af0, 0x571a0192,
+ 0x02a62a26, 0xc8dc8280, 0x00b5fb71, 0xbb4c6176, 0x94e00b3d, 0x157004c9,
+ 0xa5029fd0, 0x30276100, 0xf0efdd38, 0xbdbf423d, 0x225f1c91, 0x9e5eef7e,
+ 0x77dc2323, 0x4055a560, 0x5dfd12f8, 0x361b5d17, 0x709563df, 0xd480197f,
+ 0x0fb91ce1, 0x1d300ad0, 0xe7f015df, 0x32a3a458, 0xe784db92, 0xf716faee,
+ 0x2412fc55, 0x828f9d20, 0x76048f4e, 0x15798f80, 0x0624279e, 0x8df3c49f,
+ 0x22b07847, 0x3810033f, 0x8ec7077e, 0x004ab339, 0x814fd396, 0x815877be,
+ 0xc005bf67, 0xefb42bef, 0xdf97cbcb, 0x6f084904, 0xf286f4b1, 0x4970fbd8,
+ 0x90e30343, 0xaadced7e, 0x9d5bb7bf, 0x78c9feb4, 0xff1e01ae, 0xb5fbc782,
+ 0xd7ef6410, 0x7b7dc0ed, 0xf5f97ecc, 0x0dfbd39f, 0x0af78cbb, 0xbef4c485,
+ 0x0a03f4a9, 0xb3ecf12f, 0xb6adf089, 0xf9aaf8ab, 0xb1bc3f6f, 0x837af918,
+ 0x69f86d17, 0x64c4df68, 0xd98fe2f0, 0x91aca428, 0x8cdc6c72, 0xe145a48f,
+ 0x5cfc7dc1, 0x47379d3f, 0x1b4fe672, 0x44906f29, 0xb561c913, 0xbab7c54b,
+ 0x80059be2, 0x9b7756f8, 0xe02bb801, 0x1083c8d9, 0xdba0a783, 0xa33bf3e6,
+ 0x2a5d87f4, 0x5fdd058f, 0xaaf2cea7, 0x01d12b6b, 0x405e2aed, 0xa67a41bb,
+ 0x47496071, 0x139f307c, 0xac72e1b7, 0xe492a33b, 0x80838c74, 0xb89ec850,
+ 0x2df48ed5, 0xefa39f54, 0x1fc5484e, 0xc2667999, 0xcbd340b3, 0x2f77d2c2,
+ 0x516f7872, 0x4889a2f7, 0x75df1c01, 0x1cd431ef, 0x0c3c152c, 0x2c5062df,
+ 0x296397a4, 0xa466ecbe, 0xddcf1e73, 0x1c12f3ed, 0xff10e019, 0xae048ab1,
+ 0x3fef638d, 0x7cebef42, 0xb2f8b31d, 0xb35f189b, 0x37a87d5d, 0x5fc29a4e,
+ 0x8f29184a, 0xd0cd5ca8, 0x5797eba7, 0x59ec86dd, 0xd7e6afdf, 0x1d31bace,
+ 0x5c04b8f5, 0x16fba436, 0x610c0d1e, 0xdfe6cb78, 0xe03126e6, 0x5f2819ef,
+ 0xf44a982e, 0x2d0584fa, 0x68cfde02, 0xd39835f9, 0x5667e462, 0x8fd74efd,
+ 0xf491cf2e, 0xf9abf8a8, 0x7c84a0f2, 0x98e76d0e, 0xaa88351d, 0x9f94369d,
+ 0xc462c3fb, 0x45e410df, 0xefa9e90e, 0xe492703a, 0x03aeb1d8, 0xce8016cc,
+ 0xad6c5d75, 0x7c033bb7, 0xd98fe33e, 0x838d09af, 0xc1a55bf8, 0x74775f8c,
+ 0x1c7fca3f, 0x3032cbbc, 0xf802e70c, 0x13bf7d93, 0xbf359f90, 0x62d8f2f8,
+ 0x794376a2, 0xb207f30a, 0xf4a3abb9, 0x9c015817, 0x5b647f48, 0xc32b7f82,
+ 0xa27eaa23, 0xfeff6dd9, 0x719a2749, 0x0b1dffbf, 0x1583db33, 0x1cfe0f4f,
+ 0x12db35e1, 0x53fb9c98, 0xfda2c941, 0x0afd93ad, 0x8a6e581e, 0xdc9334f4,
+ 0x6dc5133b, 0xf3f9ffb8, 0x81dd5f93, 0x2757caf0, 0xf926448a, 0xdf845091,
+ 0xefa011b3, 0x3dd8b33b, 0xcbbc5590, 0x5fe4ff34, 0x729bf69e, 0x4d397fda,
+ 0xfeba3c24, 0x90ef3ece, 0x35f5e500, 0x685df204, 0xa538e782, 0xd70f84cf,
+ 0xe69c769a, 0x36ad3ed0, 0x75e92779, 0x397fb3d5, 0x54fc865e, 0xd3f37cbd,
+ 0x95be9033, 0x7a058d1f, 0x11d7aa27, 0xe42920f1, 0x51e038a5, 0x9f2680e3,
+ 0xff0eedda, 0xa57131a7, 0x00c523be, 0xf9657637, 0x47898d3f, 0x18caa0b5,
+ 0x1f98e7ee, 0x35fe69d5, 0x20df978d, 0x4843d47d, 0xb110938d, 0xf2155d92,
+ 0x2171449c, 0xc98d84f2, 0x3ecede3f, 0x2ecc4c10, 0x53204ceb, 0x034c2f7c,
+ 0xaff9267b, 0xfc2fcaac, 0x9bade4c4, 0x42fd3650, 0x93ffeeaa, 0xb58b4c16,
+ 0x37869ecf, 0xdb373ec9, 0x380e7d98, 0x3c67f980, 0x290b7f9e, 0xfb32fcec,
+ 0x861fcc57, 0x45cb4bf3, 0xc0c51730, 0xee28905e, 0x4509b615, 0xacdae00f,
+ 0x964a65e9, 0xadfc442f, 0x9eedf8ea, 0xb73c98f7, 0xf08a783c, 0xfd32761e,
+ 0xdcaa7bc1, 0xc4d41cc3, 0xf665a9e6, 0x7bff342f, 0x7dcfe0c1, 0x97c89ccf,
+ 0xddbefdf1, 0xed01f353, 0xd83e5ef9, 0x67ca1cf7, 0xfa783130, 0x0f3b5c61,
+ 0xf28e387f, 0x75bd3c62, 0xe01a5f2d, 0x478d4e01, 0x7e07c475, 0xbbeb913f,
+ 0xe181f640, 0xde87c584, 0xfc98d34d, 0x326f79aa, 0x6fdc3fe9, 0x4e9e2fa4,
+ 0x3e9d7dfd, 0x9cfd7dfd, 0xebeaadd9, 0x9f9835bc, 0xcc9fdf8a, 0xefac1811,
+ 0xe60a4f9f, 0xbbe938a7, 0x8a973d4b, 0xd5bd8c70, 0x6fd44fd0, 0x37e31d8d,
+ 0xc35357d2, 0xbec06d89, 0x713f142b, 0x5fb8c80d, 0x26a6f997, 0xd1d9f037,
+ 0x766916ce, 0x6669e906, 0x82b73bca, 0xb48bd76a, 0x743b7df8, 0xe5fd0058,
+ 0x67f5a9a4, 0x3a075c76, 0x63916f7e, 0xca72afe3, 0xf7ea6974, 0x254abf8f,
+ 0x3f1c51e4, 0x3ab272ef, 0x339ba267, 0x90d973b3, 0x5f70e74d, 0x281da00c,
+ 0x0db1369d, 0xdf7991e9, 0x57bc6e35, 0x93e40d67, 0x64f7e81f, 0x07df665e,
+ 0x9196f7b8, 0xc81cc1be, 0x8a4ff567, 0x3bac3815, 0xa0c563c2, 0xbe50f284,
+ 0xe2571606, 0x02d865e3, 0x47489d35, 0xfdd77d05, 0xb8a4ed11, 0xe9d4d4ca,
+ 0xc65e251c, 0xbd3407c1, 0x9a99a715, 0x8ff1463a, 0xe91f68db, 0x5e0e836b,
+ 0x7f355ff5, 0xc6726996, 0xd6c7cf84, 0x5c5a0d33, 0x15d9270f, 0xdb2fe91e,
+ 0xb8407a87, 0x40381ccc, 0xb43d7a2b, 0x42673ea0, 0xcbaf7d40, 0x6729bf18,
+ 0x78f9612c, 0x33238b2a, 0xe7aef535, 0x68f4809a, 0xeb857ca7, 0xd3c82e26,
+ 0xb08813fa, 0x99970255, 0x5b3b1456, 0xad8f8367, 0xad89a073, 0xad9da173,
+ 0x5b074037, 0x5b20826f, 0x0da04a61, 0xeb5ffc58, 0x0c3cc3ea, 0xa26e5d3f,
+ 0x18bc5c7c, 0x87f3469a, 0x2ebc9ab5, 0xea8c0f2f, 0x1e5c3f25, 0x64ce4073,
+ 0x2e4e5d74, 0x9d98f213, 0x91b172eb, 0x073de23d, 0xad6933f8, 0x877b1080,
+ 0x99de925c, 0xe0998205, 0x5c18902a, 0x51e51dfd, 0xb2cd921a, 0x54b91477,
+ 0x8f276e8d, 0x9171726a, 0xea8d8f0d, 0x605baf6b, 0xcc37aeb0, 0xff1499d0,
+ 0x7213ea47, 0x84e2ce88, 0x0c052fca, 0x21f77e11, 0x6be3199f, 0xb3655171,
+ 0xf74ee107, 0xe3199f49, 0x65597168, 0x6ac44591, 0xdf63f5b3, 0x4765846c,
+ 0x1fa03e52, 0x3bc831d9, 0x87bc3e50, 0xfa54d287, 0x7ca7e39e, 0x101fe369,
+ 0x07654fc9, 0xadd59040, 0x17e45568, 0xaeef357e, 0xba7aa971, 0x4b3f26d9,
+ 0x0f6f587e, 0xc3c80924, 0x0cead69a, 0xac1b87ca, 0x8c9fbbea, 0x89bea615,
+ 0x1e21b172, 0x2f94617b, 0x081c57dc, 0xb9a13887, 0x47a51dc5, 0xf01dffc7,
+ 0x784af9fe, 0xafca650f, 0x09bf29b9, 0xc61beb22, 0xb3bb796b, 0x97c44cb3,
+ 0xa3170e90, 0xa9389423, 0x26dc85b9, 0xde97b7cb, 0xf6aa270b, 0x7b6c97b6,
+ 0x75ed747a, 0xd3ddbb4b, 0xb70f7e47, 0x8027b37e, 0x433f86ef, 0x5def78c4,
+ 0xce8fbcb7, 0x39429a35, 0x5f97a845, 0x92b69c26, 0xcaf6e83d, 0x209692a1,
+ 0xf8126ddf, 0xca0fccad, 0x9675c35d, 0xe1ef6a27, 0xca1ef8a5, 0xabe7d8a3,
+ 0x4a0fb2c2, 0xd20e9a6a, 0x57b72a5a, 0x39e10ee1, 0xf236f442, 0xffa46591,
+ 0xac8f94c1, 0x9c7f319f, 0x169ddaa0, 0x1ff7baa7, 0x0abc7879, 0xdfc620fa,
+ 0xbc5ff71a, 0x8f8c2ff0, 0x914e438d, 0x7bed978e, 0x7dea99a6, 0xcab0cfdd,
+ 0xdd11c433, 0xd97666ef, 0x773b3c02, 0x5f3a52cd, 0x878f51f1, 0x3d75efe2,
+ 0x832a36a1, 0xc627ddc3, 0xd7aff6ab, 0x3f70dfe9, 0x6e7c4f24, 0xa6487b47,
+ 0xa7ca8b3c, 0xef37683e, 0xab7f21b7, 0x60d07ea9, 0xf6abf185, 0x58ff7a95,
+ 0x561fe47f, 0x19f03bea, 0xa95df885, 0xcb62bfd1, 0x5d91377d, 0xfb1bf4ad,
+ 0x6cafbd41, 0xf6d5ced4, 0x1f13d7f8, 0xe78ddbb5, 0xccafa91a, 0xeb0cfaa7,
+ 0x75d50f31, 0xaa5bfb71, 0xd8d95f58, 0x1ffefc65, 0x2495f637, 0x81bf2d60,
+ 0xd72e4756, 0x4e7f10ce, 0xfd59e7d6, 0xf56de436, 0x8ba2cdf3, 0xc8a76ce0,
+ 0xf5d1ebe2, 0xb61e7b10, 0xd15b31a4, 0x46e575fd, 0xc3c7d58e, 0x364bdffd,
+ 0x7828e889, 0xbdd58329, 0x7ab3af58, 0xd9881d03, 0x86ca016b, 0x3d7bfb43,
+ 0x426b9225, 0xe777af3c, 0xff4f5489, 0x67049d75, 0xf4fa512c, 0xdf9abe7a,
+ 0x3ea56551, 0x93ec7ee9, 0xef210ec8, 0x37bc72e9, 0xfc05b0fd, 0xaa043fb8,
+ 0x9ace863e, 0xf33e5d58, 0xe49e4ec8, 0xfd518fcf, 0x026996d9, 0x0e1e4621,
+ 0xa3080c61, 0x4d36f5f4, 0xa979097f, 0xf144fd86, 0xe4fdc32a, 0x7ec35cd2,
+ 0x2b69239b, 0x0a4501e1, 0x8e284b7a, 0x48a4efab, 0x20f70c53, 0x5fb8ff84,
+ 0x437189ae, 0x64c39cd2, 0x15ce15cf, 0x3690de6c, 0x9e78d0b7, 0x5f13cb5f,
+ 0x87b833b6, 0x657f957c, 0xe675e836, 0x7e9e1180, 0x10921db4, 0x39a8e3af,
+ 0x00a16e6e, 0xc13625d5, 0xd5ca5df8, 0x4c0262ec, 0x861bcc30, 0x961ceee5,
+ 0x0945d92b, 0xf720c8fc, 0x1ea1b978, 0x3434dd58, 0x422a29c1, 0x7d630f54,
+ 0xd467f946, 0x259fe518, 0x7e3de51b, 0xd9de5185, 0x5f79464d, 0xab9462dd,
+ 0xcdca315b, 0xe1a671b3, 0x4af6c4fc, 0xf3793c03, 0xd7f3860d, 0xe01817f8,
+ 0x376fdba9, 0x71d69f9c, 0xa0bf61af, 0x5f61956b, 0xd9cbb3b7, 0xd581b5c1,
+ 0x0266f671, 0xa0ec15d3, 0x0643f0e8, 0xff7af17c, 0x12aaf831, 0x47a5ce51,
+ 0x48c2de51, 0x1484703b, 0x6f1878a0, 0x57faf107, 0xaadff4e2, 0x93f793e5,
+ 0xee4e3ece, 0x8f412f3a, 0xa0bcda7f, 0xb1fac2dc, 0x55690a7f, 0xcb567489,
+ 0xaf2d3e6b, 0x644df6c1, 0xa973e024, 0x0f1418b0, 0x3c2b1c52, 0xbb22abe9,
+ 0x1d350e2c, 0xe4a0f644, 0x32557b6c, 0x7040979d, 0x4b47538d, 0x5296fe74,
+ 0x72b1cc0e, 0x8f366742, 0xa171ca8b, 0xe327cad2, 0xfd6fb2e1, 0x54ecc96d,
+ 0xcfa7c33a, 0x3552b87d, 0x1c97cc6f, 0x47918e60, 0x4f9ea945, 0x5d5e8cbc,
+ 0x089cfaee, 0x52b07deb, 0xfbb26fbd, 0xd5a3dcdb, 0x9e66e237, 0xab325fd5,
+ 0x32710ec7, 0x6add1f9b, 0x7d90e60f, 0x5f90c99f, 0x317cc5c9, 0x56051268,
+ 0x36a171bf, 0x8c4c2a62, 0x6e52f251, 0x9f512f9b, 0xcd2aed86, 0x8bf21727,
+ 0x465e2be7, 0xa2542bbe, 0xb7f4c5b6, 0x99de5727, 0x739e794b, 0xbbc22fad,
+ 0x973ccfef, 0x9fcc7943, 0xf7a2ed2c, 0x1921e787, 0xd9c617c8, 0x48504990,
+ 0x1c43ca04, 0xd1ce2feb, 0xfc623323, 0xe585a376, 0xadfad02b, 0xe939353b,
+ 0x0d12d6fd, 0xb13e2f6f, 0x9df8e302, 0x3c98875d, 0xb407336a, 0x7449ad3e,
+ 0x4df7fbe1, 0xbf521670, 0xa8915209, 0xff7ae9f6, 0x3eff9e35, 0x57ef5579,
+ 0x36be772f, 0x07d0dfb3, 0x51b48ec3, 0xf3f18de7, 0xeadf28ac, 0x258fbdfb,
+ 0xfbd3fcb0, 0x1f9b3658, 0x641fdf46, 0x9b3b8173, 0xc7d8303e, 0x1b1f2ddd,
+ 0xe51eeeec, 0x287ec313, 0x8f19623d, 0x64f687fc, 0xe503b9cd, 0xadb77e77,
+ 0xd450fa84, 0x4c6e7f57, 0x627a1c9f, 0xf7c26cf2, 0xc73cf9bf, 0x1759e8e8,
+ 0x9d34f364, 0x4eebd3cf, 0x2eb43832, 0x3e78d6c4, 0x5f55bef5, 0x3c837fad,
+ 0xc227ea33, 0x9b47118d, 0xd479d4c3, 0xd667beba, 0xc3ca4ab8, 0xb356d93d,
+ 0xe1524eba, 0x0abb52ac, 0x6b4b99cf, 0x48dce2d8, 0x070f6b7d, 0xd0f68712,
+ 0x9785d57b, 0x7744f8ac, 0x50f56c86, 0xb9195a5d, 0x482b7340, 0xe379b10f,
+ 0x41d954d2, 0x062c39df, 0x9d1952b3, 0x383fa893, 0x035e526b, 0x2f25018c,
+ 0xf53e71fe, 0xaa498301, 0xf8be27dd, 0xe9057cdc, 0x97c5257e, 0x0a40f74c,
+ 0x94e76359, 0xfa859cfa, 0xc253ea62, 0xf0cd750e, 0xcc8f8c70, 0x478a75b8,
+ 0xd3d7578d, 0x9af5ef8a, 0xe47126da, 0x80dacf0f, 0x07e8a7e6, 0x4317d512,
+ 0x1faa6cfb, 0x70920198, 0xdb6eccff, 0xe3cf640b, 0x5faa6690, 0x7d635ab0,
+ 0xb65be141, 0x7d09c500, 0x11ee933e, 0xfbc5e57e, 0x6c2d7be9, 0x2898300e,
+ 0xd77f9094, 0xf5601d27, 0x595c89d7, 0x15f9b0f2, 0x7a3f1448, 0x6eb6d8f7,
+ 0x3991e752, 0xafff120b, 0x0f12b873, 0x6a4233eb, 0xe1cda95d, 0xf9abbe74,
+ 0x43df19c7, 0x7c406d9b, 0x7c1a5f9e, 0x4ee6cbca, 0xd9d10e62, 0xd6e9526b,
+ 0xd3f9d5e9, 0x73be88f9, 0xe7d5bb65, 0xd779d149, 0x07e44986, 0xce754728,
+ 0x2f7773c7, 0x7dfee518, 0x7cb2beba, 0x558f88f3, 0x2dbcea4d, 0x07f6f7aa,
+ 0x8ede914f, 0xbb1c5938, 0x3e78fddc, 0x611ff7eb, 0xef3e40f2, 0xf862fe22,
+ 0x9989e25c, 0x3eef9e0b, 0xf85794f1, 0xb385fce1, 0xf878f9d5, 0x02398b85,
+ 0x77dfafde, 0xc9d924e8, 0x6e3c1cf0, 0x831b6d8e, 0x68ea657d, 0x0acc6bf3,
+ 0x4d92f531, 0x6cc13fbf, 0x9f218fbc, 0xfc8bacfc, 0x5d89eb11, 0xf9421f5a,
+ 0x9eb6e292, 0xb1d9772f, 0xe2df454f, 0xb8b36f42, 0x8ec9784d, 0xcb0a73d7,
+ 0xa15cfa5b, 0x44bcc38d, 0x599b963a, 0x76afe73c, 0xbba7648a, 0xd482f6d0,
+ 0x04a59ad7, 0xeb8e3f36, 0xe4dbd76f, 0xd65ec947, 0x4199507c, 0x3be76ffd,
+ 0x957d6837, 0x6ba64f9a, 0xf09d39f6, 0x64de1f13, 0x358a5796, 0x4dec4afa,
+ 0x3321d53c, 0xf9d5e140, 0x788f3681, 0x8fd66dec, 0x775717fd, 0x1c70ea99,
+ 0x00001c70
+};
+
+static const u32 usem_int_table_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33a98f8a, 0x32e8f430,
+ 0x31e8a430, 0x43d4dc30, 0xcf12d388, 0xbf4ca2e1, 0x83030b30, 0x038b1028,
+ 0x7f1024b1, 0xf8606463, 0x7ebc48ce, 0xbb04115e, 0x81818045, 0x070fc80f,
+ 0x1905ffd2, 0x330b3e18, 0xf903f030, 0x6dfc80b3, 0x88087c40, 0x376280c3,
+ 0x2067f480, 0x02c40fbe, 0x17cdf822, 0x417f2024, 0x07ff9508, 0x1042ff8d,
+ 0x61637ebf, 0x0496f2fc, 0x4de1b1e4, 0x0f8cdc04, 0xef40a77f, 0x6a87e040,
+ 0x557d7ca8, 0xa02b0606, 0x843a8758, 0x7e4908ff, 0x40cc5016, 0x93e6c215,
+ 0x05506067, 0x61ab1ff2, 0x281f9737, 0x5f9406af, 0x00073506, 0x15e5ac6f,
+ 0x00000368
+};
+
+static const u32 usem_pram_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x7dedff00, 0x45147809, 0xf4f570da, 0x73264cf4,
+ 0x10909264, 0xa70930ae, 0xe15c380a, 0x1084ca30, 0xa8ea2416, 0x1388a888,
+ 0x2e421081, 0xf57175d1, 0x11c3a7fb, 0x9e375941, 0x1d47facb, 0xa22cdc10,
+ 0x60188806, 0xb200c1c0, 0x1761bb8a, 0xc363d715, 0x01921a0d, 0xe5c58f15,
+ 0xeaadf7ab, 0x44ceee99, 0xeff3eba2, 0xe3fdfb7e, 0x575453e3, 0xef555bf5,
+ 0x5dbd6f5d, 0x71024a31, 0x02e426f6, 0xf211c6fc, 0x4908488c, 0xe36d9689,
+ 0x1749c7c3, 0x92cde442, 0x8840ad6b, 0x343dbaf0, 0xfb21046e, 0x33010956,
+ 0x587687ad, 0xd3f5a109, 0xcc07d735, 0xd43eb419, 0x9afac1ec, 0xbee7ac1c,
+ 0x48c3aefa, 0x8aafa5eb, 0x761ba846, 0xdb34729c, 0x37372908, 0x7d05723d,
+ 0x24557e1e, 0xc450e9ab, 0xb240c535, 0x471e3908, 0xad196fd8, 0x685212a7,
+ 0x55d2d561, 0x3cc2673b, 0xc4cc1a8a, 0x6e94e142, 0x15ed7b99, 0xaf773eb4,
+ 0xe94ba044, 0x77534ada, 0x10179f5a, 0x68bea0ea, 0x4e3887c7, 0x545278db,
+ 0x4f908837, 0x35c471fd, 0x4d1dd680, 0xe7d137a9, 0x130d81c5, 0x7af17fa1,
+ 0xfda06dc1, 0x7e766b8b, 0xeb8bf004, 0x8522bea5, 0x4ad6bf3f, 0xd8d9035c,
+ 0x63ac0817, 0xdf30b5ce, 0xc4483fd2, 0xe745eb4c, 0xc01136ef, 0xe4dab191,
+ 0x8ff8c3b5, 0x18765c9a, 0x51c716a7, 0x7bfa59f0, 0xaf7d0e3a, 0x0dc165ec,
+ 0x10332b4b, 0x75a7cc1f, 0xf3fa658b, 0xa5575836, 0xbfbc3fa9, 0xf41341e5,
+ 0xd8281b9b, 0xfcc1716c, 0xc2269956, 0x99566b3c, 0xe145070a, 0x517dafcd,
+ 0x2be3af33, 0xa9f574fb, 0xa7e5f5da, 0x735a8a7e, 0x884c5eb4, 0xf306cea7,
+ 0x1fae980e, 0x547e7d1c, 0xcf7a4448, 0x2b8915af, 0x529f0a2e, 0xefcb9f1e,
+ 0x1f027fd2, 0xd607b76c, 0xb5e94466, 0x8eff09c0, 0x93acebd2, 0xce18cfd3,
+ 0xca57c352, 0x740e8047, 0x277ed53e, 0xd3f98f96, 0xefc27cb0, 0xe53dbc42,
+ 0x4ae5881f, 0x3f9f1bbf, 0x658d1fed, 0xe583df8d, 0x5849feb3, 0xec5efc06,
+ 0x1d3fdab7, 0x1f7e35cb, 0x5fc17f3e, 0xbfad6584, 0xf3af9f02, 0xbd72c42f,
+ 0x2fe7c65f, 0x596197fb, 0x72c6afe7, 0x96257fa3, 0xf600fef5, 0xd7e9ccdb,
+ 0xe7c3afe0, 0x580dfd5b, 0x2c21fd06, 0x62f7f877, 0xd5e382b9, 0x8c724d91,
+ 0x0f0e2f14, 0x20715271, 0x1c9ef949, 0xbc93d689, 0x433a9eac, 0x7ad131ce,
+ 0x29d68faa, 0x8497ba9e, 0xdeb4cc72, 0xa7b582bd, 0xc7c6403f, 0xccba7ad1,
+ 0x785733da, 0x3d685bc6, 0xf7b59ab3, 0xc7c791af, 0x00ff7ad3, 0x7d74bf6b,
+ 0xd695bc68, 0xed63ad2f, 0xd7248243, 0x4243eb46, 0x9f6c3eac, 0xeb4ed727,
+ 0x3d589ac3, 0xd73923eb, 0xcd59eb41, 0x2db1fdec, 0x5a04dca1, 0xed661b1f,
+ 0x166f9d57, 0x67f8315d, 0x459be4b3, 0xf2032d28, 0x1bb18f14, 0x777c9bad,
+ 0x97c53713, 0x1c63d53c, 0xc923f143, 0xbe4bbed8, 0x4c1bdb1d, 0x27bfb632,
+ 0x56fb6217, 0x27ed8029, 0xdf6c72e5, 0xfb600a6a, 0xac42f2b7, 0xb610a507,
+ 0xb12b2adb, 0xc214d07f, 0x87caf4f6, 0xd4877db0, 0xcaeeed8c, 0x877db1c7,
+ 0x1fdb19a9, 0x99e3525b, 0x0b0feb40, 0x2f81a7be, 0x22be0b17, 0xadf807d2,
+ 0xf94bcd2e, 0xd3204aad, 0x0117bf81, 0xaaf6d253, 0x47d4266e, 0x7ace3f9b,
+ 0x6f38145e, 0xe17a8176, 0x20650f0b, 0x8e11e79c, 0x1788e144, 0xc9f59387,
+ 0xac9c0d68, 0x38148a4f, 0xa58e11eb, 0x7f367073, 0x9f3b5632, 0x38158a4f,
+ 0x149192af, 0xeb73bd8e, 0xb65bfaca, 0x2b7f3e76, 0xc0ece051, 0x6e7624f9,
+ 0xb4c70d3e, 0x163869f8, 0x389bcfc1, 0xcdce949f, 0x2d71f467, 0x8f1f467e,
+ 0xe109a7e0, 0x9c1ceb74, 0xfc5ae386, 0xe08f1c34, 0xd38403e7, 0x1aeb73ab,
+ 0x9f8b427d, 0xf82227d1, 0xc9f88c39, 0xad9c1ce8, 0xd9f8b5a7, 0x9f823a7a,
+ 0xbf4e10cf, 0x6c6badce, 0x633f16ab, 0xf9f8235b, 0x4975d702, 0x6d6ce0e7,
+ 0x6b67e2d5, 0xdf3f046b, 0x9dc19c21, 0x36d8d75b, 0xb6c67e2d, 0x1263f045,
+ 0xced0ce00, 0xa5f827cd, 0x2fc13f16, 0x4049f823, 0x373b2338, 0x5a73ec9f,
+ 0x8b9f64fc, 0xe10d27e0, 0x9c1ce98c, 0x7e2d39e0, 0xf822e782, 0x573840c9,
+ 0xd95d6e76, 0x93f1695f, 0x3f0455fd, 0xf7400a97, 0x421f3e1c, 0x863bd8e1,
+ 0x2d3be3b3, 0x177c767e, 0x9c70cfc1, 0xcf9f1e4f, 0xf55ce045, 0xae7e2d0f,
+ 0x3f0447fa, 0x726708d9, 0xf8ece0e7, 0x3b3f1687, 0x4fc111fe, 0x9aebae1e,
+ 0xaaebadce, 0x5cfc5a0b, 0x67e18175, 0xdcbad1d4, 0x6d4eda04, 0xafa45ba3,
+ 0xf1ef3b8c, 0x3a2eb408, 0xba745d59, 0xa22df809, 0x26908fe2, 0xb7df488f,
+ 0xf61c4fad, 0x25fb5110, 0x75826fe3, 0xa697a9d9, 0x46124bf6, 0xa0fc6bc7,
+ 0xa6924f44, 0xbba93c9e, 0x378a7fa6, 0x75ded353, 0xf69aa5fa, 0x9a61be6e,
+ 0xb1a28f7a, 0x2abdfe9a, 0xbdea6bc6, 0xe9ad5e17, 0xa0df219f, 0x7659f7a9,
+ 0xbf7fa6ab, 0xed353bea, 0x6b165603, 0x2c092fda, 0xab2fd4d0, 0xffa6a5fd,
+ 0x9a45bae0, 0x1e1bcbf6, 0x0d0fb4d2, 0x0fa9a63d, 0xa6b4fbdf, 0xd5a6c8ff,
+ 0x0751f69a, 0xc7da69d7, 0xd4d46f34, 0x55b938af, 0xf0caffd3, 0xb8fa9a1b,
+ 0xf4d2dfaf, 0x1e7394a7, 0x45d78cbf, 0xfb820b90, 0x099bb902, 0xdd90c5fd,
+ 0x77537584, 0xd827db1b, 0x29475d0b, 0x9f064ddd, 0x812d0bab, 0xfdda84e6,
+ 0x0345ee9c, 0xdc5f299a, 0xc037d63b, 0x6bdf9f49, 0x8cee5df2, 0x7e509fe1,
+ 0x941a4811, 0xfa94032e, 0xc62507f6, 0x9c7be3af, 0xbe887fef, 0xf7086e5f,
+ 0xbff5a44f, 0xc002721b, 0xd4082fdf, 0x157ca7eb, 0xe80a922f, 0x1e266f17,
+ 0x3307dfe0, 0x55979eb2, 0x17acbcfc, 0x0a215395, 0x4be49977, 0x5d643f03,
+ 0xf832bbe5, 0xe8bd5529, 0xf213baba, 0x486ef0a2, 0xefdf4bee, 0xa3e69855,
+ 0xea26ccf0, 0x37c7abe7, 0xe107f1d1, 0xcfc075f8, 0x94fc619b, 0x339be3f6,
+ 0x8fc66b47, 0x8cd22f4b, 0xe3a2671f, 0xafbea93b, 0x4f8f98fc, 0x90963289,
+ 0x38c7c26d, 0x08bd39be, 0x44d07fc7, 0xf1ea3df7, 0x87e323e3, 0x3a7bfd60,
+ 0x58e67f5a, 0x8bd3faed, 0xb137ebb5, 0x7955bff5, 0x8f1f8f8c, 0x385b7feb,
+ 0x5e9fd6c6, 0x666fd6cc, 0x3be32370, 0x826ff822, 0xd1d7bff5, 0x6b64fbfa,
+ 0x44bbdfd7, 0x1b337ebb, 0xa795afff, 0x1c36f8f9, 0x34e143ff, 0x12ef7f5b,
+ 0xf664df1c, 0x4c7f81b9, 0x022be23d, 0x93d27c74, 0xc0aeae2a, 0x281c742e,
+ 0xa6512607, 0x2149e427, 0x6f71e713, 0x73b7e33c, 0x50df94f1, 0x9cf8c91f,
+ 0xa3e6a804, 0xce329cfb, 0xe7d7f3fb, 0x616f4098, 0xccefdd3b, 0xdd9d53e1,
+ 0x937f2220, 0x7e81cc27, 0x0dadbe74, 0xd9f50ca2, 0x00195c4f, 0x266e58fd,
+ 0x3de17877, 0xf3c10923, 0x5e0e4f63, 0xbe975ead, 0x1d2d539c, 0x17c8d66f,
+ 0x9e3c8f9b, 0xf3a0ac0c, 0x182603cb, 0xa71fad19, 0x98d829fb, 0x12fba61e,
+ 0x74484f28, 0x28fcfa3c, 0x01916fdd, 0xc4a9b96a, 0x79ec88f7, 0xff9d2fb7,
+ 0x3cfca234, 0x51dbceb8, 0x233c28a4, 0x1af1ffc3, 0x98f40021, 0xf9f74d53,
+ 0x372ff92a, 0x170ef933, 0x02d58108, 0xff7d2bc7, 0x813efe66, 0x33f851f9,
+ 0x8f9dec9d, 0x47b35c77, 0xedfdd070, 0x9c0d64ca, 0x6960485b, 0xb6ff7d1a,
+ 0x62253b15, 0xe828be00, 0xe5f800b5, 0x7084897e, 0x429cda9f, 0xa0667106,
+ 0x064e7df0, 0xd2e9e6ff, 0x9c1566d1, 0xc79c5299, 0xf333e74b, 0x7be7113e,
+ 0xdedb4f8b, 0x31eac3bc, 0xcae5a10c, 0x494225cf, 0xb6915b7e, 0x6d0af6fd,
+ 0xda858efd, 0xee0f5d3a, 0xfd640bf3, 0xba1cba73, 0xeb233bce, 0xf5a70ba6,
+ 0xd66dbc59, 0xd0d64932, 0x4d736e91, 0x133dbc59, 0x4f104ed0, 0xf69f7ef8,
+ 0x681f29fd, 0xea5773ea, 0xf8be71e0, 0xdffff4ff, 0x86f2ff4d, 0x5547c59c,
+ 0x9bad2af3, 0xaaa8f8bc, 0xebdafcdf, 0x8179f535, 0xe7fd345b, 0xb4d02cae,
+ 0xa79ea9cf, 0xecb59f69, 0x40bd4d2e, 0xffd34fbe, 0x9a95858e, 0x962bdbf6,
+ 0x2b6fda6b, 0xbf53547a, 0x4d5bf7c5, 0xafa79bff, 0x3b0bb4d2, 0x466ef5e6,
+ 0xddebe9bb, 0xf4fe928d, 0x7c026607, 0xc2b3f0a6, 0x69fd27ef, 0x77ea7e58,
+ 0x7a095961, 0xc377ea98, 0xaf965616, 0xfa0de82e, 0x13ffe15c, 0xe83a4552,
+ 0xeb3f3d4b, 0x4f9eaff5, 0x2c47afe9, 0x4b29433f, 0x3b05e204, 0x64fdc6d6,
+ 0xdc37f9e5, 0x0ce782ce, 0xc9898965, 0x6ec6c965, 0xea0389e3, 0xb615fea1,
+ 0x3a92e18e, 0x2041d701, 0x74029a4a, 0x976d41eb, 0x347dae9a, 0x29d96cf3,
+ 0x2065f8e2, 0xdcc06393, 0x60187778, 0xfa6350fc, 0x3e61838d, 0xdeb1d79e,
+ 0x56fe8290, 0xe2d27f8b, 0x7f00fda3, 0xfa4f2c5e, 0xdc7963a7, 0xa8f2c3ef,
+ 0xc3cb08bf, 0x9b2c0afe, 0xfcb10bfd, 0xf9632fc4, 0x96197f91, 0x6357f57f,
+ 0x12bfd079, 0x01fcf7cb, 0x1efd5b2c, 0xfd3e152c, 0x18eba14f, 0xae9cbfc3,
+ 0x3ae9a8df, 0xf364e0c6, 0x187d74e1, 0x6fc31be6, 0xc8ce0fee, 0xe23f9548,
+ 0xdb718c99, 0x4ece3c05, 0xc71624c8, 0xa62f63e5, 0x6fd09ae0, 0x3d040c09,
+ 0xb7e0767c, 0x7d4e21fd, 0x4a2520f6, 0xd3ebc746, 0x3c43afd3, 0xeffa0f10,
+ 0x974a0185, 0x96edf6e4, 0x8b578678, 0xc3224c81, 0xefde5908, 0x839df705,
+ 0x49246eb0, 0x7dc07ef0, 0x5c063dbd, 0x7e020bea, 0xc5d7862f, 0x004373f6,
+ 0xffa7f1de, 0x18e5059e, 0xe307f303, 0x4bf4451b, 0x3779e849, 0x67a237e0,
+ 0x8834eecd, 0x99fb86f7, 0x9af7689c, 0x4fe2d6ae, 0xbf835abe, 0x55fc11e5,
+ 0xfafe21a7, 0xc28ffb9e, 0x8784f11f, 0x8a3830dc, 0xef846fbf, 0x1e729fc7,
+ 0x36ef1fa3, 0xf883f8d1, 0xc1552db2, 0xa13a536b, 0xf811fce3, 0x5b3fc29f,
+ 0xf001203f, 0x1173811c, 0x7faf08fa, 0xe8fa0e9c, 0x16c9d034, 0x0e9f7785,
+ 0xcfbdd9de, 0x5fefc03b, 0x47ca2690, 0x2959e063, 0x6432eb4b, 0x6a4fda9b,
+ 0x56cfd6d0, 0xd0ea930b, 0x4c25719f, 0xd7fa0c1d, 0x40951f29, 0xa961a64f,
+ 0x669059c0, 0x7d2871c2, 0x4faf5c98, 0xd4ffb944, 0x7efd871f, 0x047479ea,
+ 0x7a8f3a27, 0x0fbe8472, 0x4fa17f2c, 0xe43bfdc7, 0x2617e353, 0xa091b388,
+ 0x97fc0e74, 0x05fffa38, 0x46237838, 0xcb702bac, 0x7cd944eb, 0xaf5f3c39,
+ 0xe7be8f19, 0x2f06ce52, 0x3c9f7e64, 0x8571c918, 0xa8a9a95f, 0x48d61881,
+ 0xac8b5be0, 0x35128ff5, 0x6e86f2f5, 0x825fc6b2, 0x4a3d507f, 0xf023048a,
+ 0x9f67094b, 0x996da336, 0x0bf7e740, 0x3e816208, 0xd2bf5810, 0xcf9366b8,
+ 0x78b2fc05, 0xe82e15da, 0xd5eb8d59, 0x2fd28fcf, 0x3c7528c3, 0xd9e2f9ff,
+ 0xe431bd7b, 0xdbd72763, 0x57160625, 0x03b27120, 0x9a48d7ce, 0x8ec1b8ec,
+ 0xf045b353, 0x3a3b7183, 0x0a0f0a8e, 0x2901799c, 0x995ff5ac, 0x5818b65c,
+ 0xee3f40bc, 0x94dc619f, 0x6cafe38b, 0xb089fefd, 0xcb1e3d6e, 0x7c98ce1a,
+ 0xbff45728, 0x151e28ac, 0xf442fefc, 0xeba459fe, 0x843dae2a, 0x9293eafb,
+ 0xeffeffdc, 0xe7ed8bd1, 0x6e3b4b6f, 0x265bad55, 0x9dce304d, 0xc440f9a3,
+ 0x5487f375, 0x5b7a9f5f, 0x5d010f22, 0xaa5ed3ce, 0x828f5079, 0xfea2b218,
+ 0xf3f59dfa, 0x9f7ec1f3, 0xf7053cda, 0xd789b32b, 0x22ca4101, 0xfe059d52,
+ 0x986269f9, 0x4d3a7804, 0xae18ecfe, 0xd139d3a2, 0xfea1f484, 0xfcf561fb,
+ 0xa9aeffa8, 0x535dff53, 0xa437242f, 0xe178f9c2, 0x08091213, 0xfb4d3eb8,
+ 0x7089d171, 0x2a8a92e7, 0x4b1677f0, 0xe9dfaecc, 0x541ec624, 0xf6be979f,
+ 0xad01564c, 0x7f32277f, 0x9def3944, 0x377b7547, 0xb75c5eda, 0xeda1e4ca,
+ 0x4f87ea47, 0xfbc082bb, 0x3fb02a81, 0x7b82abf2, 0x7e3dabad, 0xf5fce87f,
+ 0xa1fc55f3, 0x7ccee776, 0x82b5a51e, 0xcf831027, 0x67c646ac, 0x30f63f0a,
+ 0x8df1353a, 0x70faba01, 0xae9c7d5d, 0xbde5a3fe, 0xfbc8d10b, 0x00df442f,
+ 0x6f930a63, 0xc609dfd8, 0x8ff3f230, 0x0ed69f86, 0x149ff0fe, 0x9cad4f7e,
+ 0x7ee3f851, 0xdb7df852, 0x2c4a7fcd, 0xbdafa5f8, 0xfaa659b4, 0x2795f8a9,
+ 0xa7ea841d, 0x54eac653, 0xc97fa537, 0xe00ea5da, 0xd9469383, 0x2a7cfc01,
+ 0xc40a4e20, 0x8c8b77d0, 0x3daff702, 0x6fe20136, 0xff0a4ff0, 0x5f0f75d3,
+ 0x7387710b, 0xc627256b, 0x21cd6ad5, 0xb2d39533, 0x64f979fa, 0xb10fd608,
+ 0x446783fa, 0xf96837a8, 0x4f77f8b3, 0x5f50baa6, 0x180c3dca, 0xffa10e3f,
+ 0xd8e6b65f, 0xe5fbb044, 0xa6728c24, 0xffc60f7f, 0x53ed093a, 0x7da12981,
+ 0x53e46e3b, 0x2bf67de1, 0x8cf87faf, 0xf27280e8, 0x7427d009, 0x03f184e7,
+ 0xdc457bfd, 0x68dbbf9f, 0xf3f182ef, 0xe8146451, 0x242f0531, 0xf179fcc0,
+ 0x408667b5, 0xcd65b51c, 0x85410edb, 0xcede452f, 0x6e7acdd6, 0xbd63abab,
+ 0x51e54ad9, 0x7e2a47ed, 0xef81ab85, 0x2cac8243, 0xc80e4291, 0x255929ab,
+ 0xb8fa65b9, 0x5fe7a5e4, 0x9ae21a78, 0xfddd981f, 0x2ff9fc28, 0x2c6f7eed,
+ 0x20dfcfad, 0xcb67c975, 0x51a909b0, 0xffd394fa, 0xd28b0e17, 0x6ed378a3,
+ 0x7b306b93, 0x945240fe, 0xec37f32e, 0xedc19134, 0xb75b91f1, 0x8b6cd4d3,
+ 0x43ba9f41, 0x130fc113, 0x04cefb5f, 0x43b53ff4, 0x62335d20, 0x6ed573e0,
+ 0x4f00d3f4, 0xaf4e4f48, 0xfd74fd08, 0x405d29cb, 0xa5e9ebaf, 0xf41537ef,
+ 0x0b830a4b, 0xbf9412f9, 0xf90ade5f, 0xbb357f48, 0x2f450f01, 0xf580eddf,
+ 0x3056309c, 0x69667f3e, 0x5f8e87aa, 0x4ea9c924, 0xa2f3d92c, 0xfc8e7f67,
+ 0xcfff7737, 0xcb5c5953, 0xb680cdd3, 0xeb06ee4a, 0x1373539c, 0xf890b3ae,
+ 0x9e8b0f90, 0x2fa0bd11, 0x499234bf, 0xc9c8621b, 0x4e4e5cb7, 0xa5c4a6ac,
+ 0xcd413ceb, 0xfce9e610, 0xc5ac0c59, 0x185dfa38, 0x5f39fb37, 0xb0e8f50b,
+ 0xa31c65fe, 0xc0d19357, 0xeaf52ef5, 0xe6bbfcd5, 0xd3a026c1, 0x5d3cbda7,
+ 0x9ca5fce1, 0x0f8e6518, 0x2b8502e1, 0xcaebcfee, 0xc65c44e8, 0xf51efe2c,
+ 0x39e172cb, 0x3c926ff4, 0xf79a2196, 0xe88c85c8, 0xf1f0f7f8, 0xc1e3bce9,
+ 0x1a913a9f, 0x40305f7b, 0xb502ec52, 0x533e2aeb, 0xff933bc9, 0xbc99cb35,
+ 0xb81ff22b, 0x7fb4127e, 0x11c98071, 0x92f607bc, 0x15d42bce, 0x154e77db,
+ 0x49983f50, 0xaf9c9628, 0x6b9cb891, 0x42fcf5db, 0x12146fe7, 0xe3037c54,
+ 0xd01d2124, 0x827c2a9f, 0xa3d2afbe, 0xa3ae30e5, 0x8e455c3d, 0xf07d72e7,
+ 0x6b03e825, 0x1a901f54, 0xf63a07a6, 0x53c4657b, 0xe1781489, 0x2a5f9069,
+ 0xe40bb2af, 0xfac2f257, 0xf8df5b3f, 0x6e54adde, 0xe453ab3e, 0xf557ab56,
+ 0xf1b45b72, 0x54f804e7, 0xf59fb72f, 0xe53120ac, 0x298f3e96, 0xff9b3db7,
+ 0xc1557a25, 0xd5a4ba63, 0xec9e8aab, 0x3d7a9f08, 0x42e8c5b9, 0x24f5eabc,
+ 0x59201dfd, 0xe151f9ed, 0x8aff8543, 0x0ded2c5f, 0xa7c228fa, 0xf8461f0a,
+ 0xfd43e154, 0xd478b5ba, 0x9e7c63b7, 0xcb778bf2, 0x507b13bb, 0x050496ba,
+ 0xef85d9b7, 0xc53a81ed, 0x0b6d8797, 0xe8f4f7aa, 0x7407aea2, 0x7f5d3af5,
+ 0xd5eeae8f, 0xeae9f7f5, 0x01feba15, 0x68694fb6, 0x87e41134, 0xb4bfa690,
+ 0x9f90c888, 0xe22ede16, 0x9d1b41b9, 0xbf7d1573, 0x40467d6d, 0xa961faa6,
+ 0xc3dbed85, 0xd02aa629, 0xb0ce6d67, 0x16ea0923, 0xf36b7f16, 0x2a891d86,
+ 0x5050f1ff, 0x1cdc7d44, 0xed629320, 0x8bc7a85f, 0x1d266bf4, 0x90f3b3b5,
+ 0x10c778b6, 0xb44f2f18, 0xf8842fa5, 0x86e8b54c, 0x95d98e23, 0x5ce03b37,
+ 0xe7d82da2, 0xf9f4e9ba, 0x2c883f9c, 0x18f6422d, 0x0df6a9bb, 0x54fc8927,
+ 0x95f900b6, 0xb3fe902b, 0x311f6c82, 0x7e6c457b, 0x15efe62e, 0x8131eeda,
+ 0xfffea4de, 0x5f5c7561, 0xa3545381, 0xc29c1e7b, 0x2fed9ef9, 0xdb68d78b,
+ 0xfa3f7c7d, 0x0fdf0a5f, 0x7ed94325, 0x0838b090, 0xe279bbd7, 0x53a6eba0,
+ 0x15edb43a, 0xd9cdf009, 0x387488a0, 0x40085ebb, 0x29c88a5c, 0x24653f28,
+ 0xc14efa8c, 0xc7c80b57, 0x50f58e80, 0x671fabcb, 0x94bb4fdd, 0xc870fe6c,
+ 0xcb65a5ff, 0x6ffa0fe6, 0xef6bfa83, 0xda487fa7, 0x61ddcff7, 0xb6df73c1,
+ 0x27cc761d, 0x4efedb6e, 0xdf50fdfa, 0x3cc37662, 0x357c76db, 0x6da8f804,
+ 0xf408b991, 0xb62f5b58, 0xfdbc59ff, 0x68cd21ab, 0xfd20973f, 0x8b13256a,
+ 0xfeff04d7, 0x4a05d089, 0x0ff02aba, 0xf9727e78, 0x20804b56, 0x7cb2affc,
+ 0x3d6e9fb6, 0xbf9cfc65, 0x6fa64ecd, 0xb225f984, 0x6df2ec73, 0xa4af9e63,
+ 0xefd697e3, 0xeda2cd34, 0x377fafb9, 0x3791f304, 0x55a7bf32, 0xce167e6a,
+ 0x6f4937b1, 0x9e28922e, 0xba38415b, 0x299d7213, 0xc5b6572e, 0x1877cbc2,
+ 0x3e2cea97, 0x7ed892de, 0x1f1fdff4, 0x9511e602, 0x3881ed04, 0xcdfdd601,
+ 0x3e821f27, 0xbe4661d8, 0x59fbd654, 0x23fa255d, 0xa9f75b17, 0xd07c31ff,
+ 0xa10b75d9, 0xce3bacce, 0xeebdeff4, 0xce172447, 0xed072f4f, 0xbdfb7cf9,
+ 0xeec97f58, 0x9276f9c6, 0xfe9a07df, 0x237df8c3, 0xe2e3bba5, 0xbfd9feeb,
+ 0xa63bbaf9, 0x72661ffb, 0x1f213bba, 0xeff5fcac, 0x543f7e70, 0x1ffdcdcf,
+ 0xbf8af7ca, 0x9b78366e, 0xa6fce872, 0x383b6a93, 0x9ca4b716, 0x73a907dd,
+ 0x745f5ee6, 0xfc4af981, 0xbf3f51fc, 0xefb62695, 0x997ce093, 0x126e4b8e,
+ 0xed8f7ef8, 0xfee5ae93, 0x0b3db5c5, 0xd6bd2fd1, 0x6277fcc3, 0x46737af4,
+ 0x6cd89e40, 0xc943c637, 0xa83e83b0, 0xaf2574df, 0x7f8bf76b, 0xa0478814,
+ 0xe9b5f9fe, 0x9f82f693, 0x634f5d7a, 0x43caccc8, 0xe0ebbe50, 0xf76b47cf,
+ 0xb4f8b733, 0x6ba79bf5, 0x787137eb, 0xa2b9c0d3, 0x0af34fe3, 0x4a7f8801,
+ 0x81489ebd, 0x4734a878, 0xf9008222, 0x614b1524, 0x579370df, 0xb03dfefb,
+ 0xc5191dcf, 0x82b8bce3, 0x114e70f9, 0x7c405037, 0x4442b75c, 0x4837127d,
+ 0xd1def840, 0x1e1de612, 0x00b37833, 0x47c3f9cf, 0x8192fd95, 0xe77ac373,
+ 0x92157c71, 0xc877f40a, 0xb2170bf9, 0x4bee20b3, 0xe79a5fd0, 0xea1ae421,
+ 0x0b6617b7, 0x63c878a1, 0x61391231, 0x0543c418, 0x0f135872, 0x77e1d6d5,
+ 0xce146a55, 0xc477fac5, 0xf9753f8f, 0x87ffca37, 0x433fea25, 0x2cf3e789,
+ 0xb3eca7ae, 0x3c3208ee, 0x81089796, 0x90abe44c, 0xb0cf3ea4, 0xfdff1999,
+ 0x28e181ed, 0x1ebf3957, 0x7ff6c09c, 0xa0bbf023, 0x9e67ee72, 0x10095d95,
+ 0xec1b38f7, 0x72d1cfc3, 0xfc18be1d, 0xbbef9fbc, 0x007902fe, 0x209b6cb4,
+ 0xffe08b54, 0xfbc63093, 0xb21609e4, 0x5cbe4636, 0x8739498b, 0x207dc0af,
+ 0xa02cc4fc, 0xa5cdfb23, 0xa92426af, 0x9ae2b6e8, 0xed21c653, 0xc3bf00e9,
+ 0x7e4bce31, 0x3cfb096c, 0x4b7eebc0, 0x8c6f44f3, 0xcb83fef5, 0xdf1bfe6f,
+ 0x376377e0, 0xc0243304, 0x44130dcb, 0x39eaf9cd, 0x87e3f713, 0xaf30e193,
+ 0x3b2637fc, 0xf65d00c6, 0x4ef86e8a, 0xc6783cac, 0xce718be4, 0xc027c7a4,
+ 0xc90073c7, 0x3cf8085d, 0x810b2bf2, 0xfc3bd6fd, 0xe41067dc, 0xadc20f61,
+ 0x4ce207bd, 0x0b8b3366, 0x713b30cd, 0xe7e6379e, 0xdc742948, 0xa1cef541,
+ 0x9dd5f470, 0x46019ff7, 0x5124246b, 0x7e94f7b0, 0xbf584bdd, 0x59672643,
+ 0x113ff5ac, 0x733ae2c7, 0xd1defb89, 0xdd1fbfc2, 0x0f6d7e72, 0x327b078d,
+ 0xd8e77d81, 0xca09af9e, 0x4249d9c7, 0xec3df400, 0x2f9eb09f, 0xc779bda0,
+ 0x1be5dac0, 0xf8565e98, 0x11e78f5e, 0xf8cacf1c, 0x0c7d7953, 0xcf052f97,
+ 0xf3f57e0a, 0x7d53fa55, 0x8f1d4e35, 0xe861aeb8, 0xcb0f60cb, 0x40d38282,
+ 0x9b199541, 0xe587204d, 0x104a8f0d, 0xc5c5bf8f, 0x307b52e0, 0x3bfe7d44,
+ 0xe1ceccc3, 0x315d871b, 0xf3e4f813, 0xa12fd415, 0x9f667bef, 0x7ddd8071,
+ 0x13fee0c7, 0xff29077c, 0xbf6b2451, 0xe87d5f47, 0x904f1677, 0x703370d4,
+ 0xe496379e, 0xb93e1048, 0xd4a764ad, 0x334fc555, 0xaed849cc, 0xe25eef3c,
+ 0xe9cf061a, 0xf90f3878, 0x3c813311, 0x4d7541f2, 0x6ddbfdf8, 0x0f8c8915,
+ 0x9a76ea8b, 0xfd819eb0, 0x7194f195, 0x3534f2f4, 0x341f9b5f, 0x27b9b72b,
+ 0x1cdf25e0, 0x831dc7ba, 0x95982f4f, 0x681f8873, 0x6f943c27, 0xb22ffc87,
+ 0x7628f713, 0xaaf259a2, 0x34de49f2, 0xd9573933, 0xecb1ae89, 0x574a82c4,
+ 0x82c3a057, 0x82ba7ded, 0x43f82c90, 0x3b2c6a5e, 0x9d9faef1, 0xbfcfbe2b,
+ 0x4a9b6d23, 0x2ae5c4ed, 0x82d5313b, 0x6f7fa27c, 0x7693b983, 0xffdba142,
+ 0x2ef37d63, 0xf21889d8, 0x4fe38bbd, 0x82d313b1, 0xa6276805, 0xdf35154d,
+ 0xf3336c5f, 0x76877178, 0x16f52722, 0x6b6e4bac, 0x9779fe0c, 0xf3efc3fb,
+ 0x07183c3c, 0x5cb7c5ec, 0x46edebff, 0x371d7a47, 0xa13b2335, 0x7845ffd7,
+ 0x02faf456, 0x339b2fea, 0x4121f162, 0x0b705e7e, 0xf002ebd5, 0x0bebd323,
+ 0x3171e76e, 0x82f59e9d, 0xd6a11d9e, 0x32fdecb3, 0xe50bb31f, 0x99bf190d,
+ 0xad6fdb41, 0xb471dc96, 0xbd51adff, 0xbbd6a59b, 0x77a476df, 0xfdde988b,
+ 0xfd1c383c, 0xf7d68ea7, 0x54b7d731, 0xc775f59f, 0x33e98fe0, 0x77ef9aac,
+ 0x737d0c8e, 0x979026d0, 0xd73c4477, 0x80fdc63b, 0x1cdf437d, 0xe9eaf101,
+ 0xbbe44671, 0xad9e9cbe, 0x813c527e, 0x36772fe2, 0xd74ba7f3, 0xb2bf888b,
+ 0x65ff267a, 0x45c042b5, 0x7d8713eb, 0xfcfa8263, 0x8e7ceced, 0x473f20ae,
+ 0xeff9ff45, 0x3c415734, 0x012afe78, 0x1f2117cf, 0x9739f01a, 0x3dd0b3e3,
+ 0xfa2bf71f, 0xf1e5833c, 0x72e4d58e, 0xd3f18784, 0xdf3fde52, 0x72f8c61c,
+ 0xf704effe, 0x1f3ed22a, 0xd5efb4a1, 0x319f60a7, 0xdcf756bf, 0x11cf1cbd,
+ 0x718b5fa8, 0x6d3ad2d4, 0x4ff71e7b, 0x41a188e6, 0xf57f609b, 0xcb1dd127,
+ 0x22fd29de, 0x27fa29f8, 0xe29fb3f1, 0x874fc467, 0x9dc1799f, 0xa1fe5f18,
+ 0xe3e3d178, 0xbf5c7167, 0x4023230c, 0x3c198f1e, 0xb7e45fa8, 0x9923cc44,
+ 0xcd3f68fd, 0x7137043d, 0xe0c779be, 0x5f3c82ab, 0x9be58cb9, 0xb0d9adcc,
+ 0x67d6953b, 0x10a191d4, 0x52bb9e96, 0xf6238f6b, 0xfcc5debf, 0x020d8a82,
+ 0xe1ce15e4, 0x051509df, 0x1b7bc51e, 0xed485f6e, 0x6b3fed3d, 0xe707d998,
+ 0x612dfba3, 0xff0a9fd4, 0xf263892e, 0xe3cf88b4, 0x04f0f748, 0x820d53b4,
+ 0x6432e513, 0xd28b7661, 0x6893ee09, 0x44d5f31c, 0x8f16174e, 0x2c746068,
+ 0xb90374a7, 0xf5e4189e, 0xde0fe63a, 0xcec33c16, 0x253b82b5, 0x40852f76,
+ 0xb9df5192, 0xd8acff71, 0xcb673847, 0x77d15549, 0xffc621fb, 0x3e37056b,
+ 0xfeffd008, 0x4076fa19, 0xe99fc557, 0x3c157d2c, 0x79d1d12d, 0x7f29a5bf,
+ 0x08d79e38, 0x23a7bc6e, 0x0be78898, 0xbdd9ab47, 0xfe718f13, 0xec05cbd7,
+ 0x60f7d43f, 0x87130f5c, 0x1649d37c, 0x71c3ebcc, 0xa67f9933, 0xd6508efd,
+ 0xd0fd01e4, 0xd272953c, 0x34597e84, 0x34e7ccbf, 0x249fdd83, 0x5f79b518,
+ 0x9ffb9461, 0xdfdbfe00, 0xc5a49f07, 0xdbb97da1, 0xf6369ec9, 0xf4191132,
+ 0xf90932fb, 0xeb8366e8, 0x2fd06cbd, 0xe404490f, 0x237df3e3, 0x05d19fdf,
+ 0x8fe445da, 0x97867782, 0x80a48841, 0x829126e5, 0x3a5d98fb, 0x2bffc7c2,
+ 0x019ed7b5, 0x83f0487c, 0xf80189fd, 0x7baa6cae, 0xe20b9e67, 0x2ff62326,
+ 0x1bb1f385, 0xbdef9d73, 0xce5c7407, 0xbc395bee, 0x69f7172c, 0xa025df77,
+ 0xf4a41d9c, 0x4d373802, 0x3def78cd, 0x97dbbf3a, 0xd739e0a5, 0x34ca4f0c,
+ 0xb19af738, 0x68bb744f, 0xd9d759bf, 0x364e706d, 0x7c48a065, 0x4edcbc2a,
+ 0x334e309a, 0x9baee2a3, 0xa88a4e40, 0x547b843d, 0xf3fb828a, 0x46bd42ba,
+ 0x65cbf7c0, 0x9d2ba99f, 0x33cad35f, 0xfc7411a6, 0xd00fda42, 0xfac35e5d,
+ 0xdc11af95, 0x185baa90, 0x64f5147c, 0x2f011ae1, 0xfea268aa, 0x1b831c6f,
+ 0x9b70a388, 0xb4fbe86a, 0x07de173e, 0xa7126bb8, 0x395679c1, 0x3fbe279d,
+ 0x25cf12ba, 0xb47be90b, 0xb9ad3499, 0xabcde10b, 0x6f7c0811, 0xe33a3454,
+ 0x6f00d191, 0xf686e49f, 0x16fe77f7, 0xd2664af3, 0xf851baf1, 0x3ce6c4b3,
+ 0x2fddab8c, 0x93bef138, 0xee517dd9, 0x91dcb8da, 0xb9d87d81, 0xef9440b4,
+ 0xfcea8c7e, 0x96164184, 0xb0b85d07, 0xd5d60ab2, 0x1864a72c, 0x98ce9f90,
+ 0xa51f8ec0, 0xff51f6f8, 0xe58988f5, 0x47ca343d, 0xfd2acd4c, 0x07d2d939,
+ 0x437671e5, 0x3999ea0e, 0xe7e78bc4, 0x8fe64abe, 0x096a5a1c, 0x4987e008,
+ 0xde7874ce, 0xcf8cd4b8, 0x76625f5b, 0x3357b5a7, 0xd44f43c6, 0x87be0448,
+ 0xe7d35c5a, 0x89e3a029, 0x139e12f5, 0xa848cf8b, 0xc4bee6cf, 0x358d64e2,
+ 0x5a89ee0c, 0x9f72dfa6, 0xe82269b9, 0x956bb9ed, 0x1ead6573, 0xa315742b,
+ 0xc2c67a9e, 0x5f5e92f4, 0x5154f5e9, 0x76d8aaf5, 0xb1899ee8, 0x2acf50ed,
+ 0xc0ecaf16, 0x9b13973e, 0x4186a7a2, 0x6941495e, 0x812b99af, 0x89676f9f,
+ 0x2da14dde, 0x76093e5f, 0xf78ec4b7, 0x9d199503, 0x3f8c094f, 0x19ffe808,
+ 0x825f0dc1, 0xb0cd143c, 0xc73ffde0, 0x47201e81, 0xdcf1922b, 0x805030b3,
+ 0x2ef25778, 0xf2d4aee7, 0x7dce72bb, 0x1e244f8b, 0xb22afdb5, 0xdfaa8f12,
+ 0xf945fffb, 0x47738e96, 0x08b01083, 0xe7b43f50, 0xeeb023e7, 0xe42d79c4,
+ 0x3b0ac1fe, 0xf7fbf5f2, 0x7c0a599d, 0x8101f33b, 0x644edf80, 0xc3d8155f,
+ 0x0b8295b2, 0x1f73b3e2, 0xa5cfef60, 0xdfbcc3ef, 0x2fe32dff, 0x902ee7ca,
+ 0x479ab283, 0x35ff60f7, 0xbfe00b82, 0xfd00aabf, 0x24592289, 0x10e6bed8,
+ 0xbda823ee, 0x46a3fcc2, 0x39054c59, 0x76625b28, 0xc2b779c2, 0x1e7f0a4f,
+ 0x9351dfe2, 0x1b90f738, 0x00e77be9, 0x14be0c48, 0x7b110ba7, 0x2e53fc0a,
+ 0xf43b7e33, 0x1106e492, 0xb27f38b9, 0xfe1567ef, 0x46ff8113, 0xb1aff944,
+ 0xfc04d726, 0xe0202278, 0xf02e7cb9, 0xefe7f02f, 0xb10cf895, 0x8ba8fda9,
+ 0x0f9ea7f1, 0xe51ff1db, 0x0af3d03b, 0xa8fc2a7f, 0x46c3c3e7, 0x7de60d32,
+ 0xae0b52f7, 0xcb6ab723, 0xce4c85b4, 0xb7273cf0, 0x9054beea, 0xcb2342eb,
+ 0x5af050fb, 0x4279646a, 0x44f5e6ed, 0x675ba9a5, 0x479ba7e6, 0x2a3d8b37,
+ 0x63cb220f, 0xde71d109, 0xe63cff5c, 0x775e9dd3, 0x6ff45ae8, 0x003e51b6,
+ 0x93b7affc, 0x0243ee10, 0xeb8a8fa8, 0x1be60f45, 0x3759431a, 0x4aeff6aa,
+ 0x57fcc4fe, 0xe2ef88ec, 0x3e40e68d, 0xf378bf7d, 0x8e782191, 0xdff988bd,
+ 0xfd013af2, 0x0f372263, 0x8a3def81, 0x438f2c8d, 0x613c17ef, 0x96f0fb61,
+ 0xe0e9d62d, 0xecb509b7, 0xbae2af5e, 0x2ab3259b, 0x45b0fbbe, 0xb9e1fa52,
+ 0x0ce94c8a, 0xfcc355df, 0x294af7d4, 0xbf2d1bf9, 0xdc57fc67, 0x573fa120,
+ 0x15a1bb5c, 0x0f8af3f2, 0x5bbf719a, 0xf3067b5e, 0x795f738f, 0xd63fdd89,
+ 0xb2f26a20, 0xd543e5da, 0x51ce788a, 0x798a5f56, 0xe78eb41c, 0x3c75651d,
+ 0xe607e8ff, 0x657fcceb, 0xa29966fb, 0xdfa6fe70, 0xb09ef039, 0xfc0eb5a6,
+ 0xfbf6a54e, 0xe5db13f3, 0xe72dd53f, 0x9cd74ff9, 0x631fa820, 0x0a7d3fe7,
+ 0x947b80ff, 0x27fcda2c, 0x1bf4cb52, 0xac56679d, 0x7e2213ef, 0x3e5f4bd7,
+ 0x2dbbf90b, 0x167b3f1b, 0x8ff25de6, 0xbc859fcf, 0x09d00a0c, 0xbaf94a7e,
+ 0x51df3177, 0x85a0ef79, 0xff7e83ef, 0x6d17cc3b, 0x06ecc0fd, 0x4fdbad68,
+ 0xd1ff83a4, 0x549be1ba, 0x67bd03c8, 0x77c61e7b, 0xb73579ee, 0x6f15892b,
+ 0x6ff025e3, 0xaaf913a0, 0xd635ba7a, 0xc8fe6237, 0xd0774a69, 0xb6bc9113,
+ 0x2f9652ba, 0x6cf9e2e8, 0x07e763eb, 0xab5fcbb7, 0x2bbaf1bf, 0x33d63f41,
+ 0x79a2e13f, 0x3d28076c, 0x1d04ef2f, 0xc57cf3d7, 0x37be6bba, 0xfc34ed8f,
+ 0x2bebd283, 0xf01f368b, 0xcf39facb, 0xf56d0d3d, 0xb1e61dc9, 0x3f813a85,
+ 0xd1b8ff25, 0x83c431e2, 0x117c6d1c, 0x7e8107f3, 0xd7d02ef9, 0xbc43a65f,
+ 0xc614a4f8, 0xbb7844b8, 0x2b7bbf19, 0xca3efede, 0xfbabeb53, 0xf097bf31,
+ 0x1256e03c, 0x4d7cb1f9, 0x5f2a031e, 0x6ff96763, 0x1f900e9c, 0x73e072e7,
+ 0xf8c7079e, 0xeb8fc95a, 0x6c6e2f28, 0xe38b267c, 0xd2e8bcf1, 0x3cf21f35,
+ 0x84dd28b3, 0x43af40d1, 0xa8779bdf, 0x7809c1e0, 0xfbcea518, 0x18879d8c,
+ 0xd1d4fbc9, 0x7a09e80d, 0x49d7923c, 0xbf213deb, 0x1fbc202f, 0x75b88f2b,
+ 0x6d17cb15, 0x93dfb495, 0xf2c4e946, 0xebc64740, 0xb9d036e4, 0xad8bcffc,
+ 0xa9e287e3, 0xc34bbc5f, 0x5abe0a37, 0xefd6c7ce, 0x7f85e3d3, 0xd9ab7bee,
+ 0x82fbfe82, 0xfbe1e39b, 0x2643fa82, 0xf18bdf82, 0xddf2957d, 0xb5b78f12,
+ 0x7f3113ac, 0x11aeaab0, 0x7f5ebbf5, 0x1473f194, 0xe38b7cfd, 0x6b2ade99,
+ 0x65a3f660, 0xa3603da3, 0xd8de5a70, 0xb65d7c82, 0xf20990fe, 0x6ed4f6b1,
+ 0x03bcb132, 0x3f604726, 0xb7f9aa02, 0x0873bcbc, 0x9f7e73ea, 0x859c7e91,
+ 0x60f29c7c, 0xd7ca71ec, 0x338cd19f, 0x3933ae5f, 0xef1f176d, 0x66e7a353,
+ 0x1369f780, 0xad3ea3f3, 0xfac52713, 0x78b6e6be, 0xababef89, 0x3b50fc99,
+ 0xd93af78a, 0xa24e3dd9, 0xb2fd1e23, 0x0fa3ec7b, 0xf780fdc2, 0x47984dd8,
+ 0xe792b8b1, 0x3b97fc5d, 0xd8bde80d, 0xf981357e, 0xaafc052e, 0xd392f7f6,
+ 0x939fc047, 0xd423bcd2, 0xfcca30e7, 0x240c5d4d, 0xb7bf3ea0, 0xfb0aea4f,
+ 0x7b946253, 0xcdae3cc2, 0x7608cafc, 0xe2cfc9b1, 0x91fce4fb, 0xc9bcf0be,
+ 0x4c9ddce8, 0x104d36e1, 0x6d9a10dc, 0x7e0cf7cf, 0xd1e0ce24, 0x39095fde,
+ 0xb3beb0f8, 0x89fa036e, 0x49c84376, 0xa5bb10bb, 0xb8370d29, 0xa632e22e,
+ 0xe63cea62, 0x8fe43faf, 0xe7df0beb, 0x5b750839, 0xa8db9fa1, 0x61216fb9,
+ 0xff7751b4, 0x97d03902, 0xe71b1fda, 0x675e2557, 0x70a6ff67, 0x875ef19b,
+ 0x12a441c4, 0xdd8577d8, 0xe3c4fe87, 0x5f7e0f0e, 0x21037f46, 0xc48921df,
+ 0xc1f7d5bb, 0xf73571d0, 0x3571d04c, 0xb68f44f5, 0x78c93c9e, 0x49bd9634,
+ 0x2898f3e6, 0x890f10da, 0x2fee0679, 0xa5fbf27b, 0x989de746, 0x6821dc42,
+ 0x7986c6bf, 0x64bc54e3, 0x366c3af5, 0xfce9bced, 0x61227a34, 0x606cb350,
+ 0x773cd4f3, 0xeb809712, 0xd39f68f7, 0x7fea6af9, 0xcdf6e789, 0xefa08c48,
+ 0x844d716c, 0x06acffe3, 0xde8c4bdf, 0x4cc254a4, 0x4e93cc26, 0x483fbe13,
+ 0xe3a0ebe0, 0x213bfa6b, 0xd7c6c07a, 0x9d3d21c2, 0x2f06efea, 0xc6b076e7,
+ 0xfa0a3dea, 0x0577ab26, 0xa766fa26, 0xc3a39e09, 0x0bb05b69, 0x85cca7ea,
+ 0xad08e4b9, 0xaf8cd50b, 0x2820aefa, 0x2cc37d37, 0x892c858f, 0x1cd53f47,
+ 0x30cb6447, 0xc88a1ef8, 0x251830d2, 0x5c9fcfc0, 0x94140c8b, 0x35e51971,
+ 0x3c305efa, 0x128730de, 0x289a0ea1, 0x9ef143fc, 0xaafc61cf, 0x86697deb,
+ 0x793cb0a1, 0x946caee9, 0x62204bda, 0xeff4a868, 0x4b257bde, 0x9f7b81f9,
+ 0x0ddfec88, 0xa95ab876, 0xdf0ec553, 0x47c7576b, 0xaa389eea, 0x5933abef,
+ 0xbfd8785d, 0x424f5974, 0x0af04b1e, 0x7107d056, 0x3cf14bce, 0xeb84942c,
+ 0x517d98bf, 0x4d7039e6, 0x11f8c4f3, 0xf70a9e2c, 0x47b3f68a, 0x7b46c7be,
+ 0xd4a6d6bc, 0xf0bfb843, 0xbd47efd6, 0x1fb75a56, 0xa7500ddb, 0xe6e4ef65,
+ 0x29123d89, 0x79d5ac56, 0x5f809769, 0xa066905b, 0x5ac4bceb, 0xc1a8dbbd,
+ 0x3c1a13c3, 0xa63d1718, 0x3f63c3c3, 0x3c970f08, 0xa1e218fc, 0x7ca6ebb3,
+ 0xe94ad031, 0x80c72537, 0x3a8d37f7, 0x0bf8c368, 0x1ed059fd, 0x3aab3871,
+ 0xd9568ef8, 0x6e3850a7, 0x97f0a380, 0x57c29ef2, 0x1f4df11d, 0xdd94bce2,
+ 0x9fe5a7eb, 0x0c67ab02, 0xf56b1bc0, 0xe0a5b31c, 0xeebbf1fa, 0xef02be29,
+ 0x5f28e484, 0x386f9b13, 0x635c277c, 0x55bc73bd, 0x929daf15, 0xa4cc40b3,
+ 0x5905cdf3, 0x4f5d1918, 0xd2d942ca, 0xc533ae9f, 0xec3cc063, 0x126fab1a,
+ 0x1e98e38c, 0x48f5510e, 0x70df005d, 0xa38e8c41, 0x76d547c8, 0x2aaf8fb6,
+ 0xb1160430, 0xe00160f3, 0x59a3f945, 0xc6611fc7, 0x90870d1f, 0x8782ca3f,
+ 0x54347f18, 0xe7e78f8e, 0xae8fb06a, 0x40a1e126, 0x57d699f7, 0x28bd8cf2,
+ 0x55c358df, 0x485f283d, 0xfcbcfaf2, 0x33af104b, 0xcf87d262, 0x4757594b,
+ 0x9bdeadf4, 0xd820f0f9, 0xe033ee67, 0x37829879, 0x2b62dfa5, 0x661cb3cb,
+ 0xfc03cdf7, 0xde6e8f95, 0xb8dbe403, 0xd798cff7, 0xc377d8e1, 0x31df784e,
+ 0x15c85295, 0xdf7ab71d, 0xb7bfbc22, 0x4003ae9a, 0x0cb09026, 0x7c63bd76,
+ 0xe089f930, 0x419efc03, 0x28438f80, 0x77f8eb2f, 0xf0ee5445, 0x56deda3b,
+ 0x03c3bf76, 0x52079656, 0xc979156d, 0x7d94b0fc, 0xffb04d67, 0xc0625f2a,
+ 0x0e5029fe, 0x097faf52, 0x1ab6abf6, 0x0a74f935, 0xa27e155d, 0xf70ad49a,
+ 0xe8955c44, 0x9fe5ae5b, 0x0aa66b24, 0x23def29e, 0x4d9de27e, 0xaed46519,
+ 0xbb06ef3b, 0xd0a7f94a, 0x53d3b2aa, 0xc0164b06, 0x287f845b, 0x0fa2c67f,
+ 0x3037ef7d, 0xfe038c1e, 0x0b5d86c2, 0xe8773844, 0xe0b35d2c, 0x3fda3a1e,
+ 0x362a4acb, 0x12b3f7d2, 0x64f50968, 0xebcaef5e, 0xe7d9583d, 0xa041b723,
+ 0xb8f157cf, 0x9e562bec, 0x5e746037, 0xbc5cf70a, 0x9d9af1c2, 0xa0bb4566,
+ 0xa291adc8, 0x8db5ce0f, 0x333b7cfc, 0xba00699c, 0x0c6c7229, 0x6a76421b,
+ 0x2e8d32b4, 0xbc39e403, 0xe179f7e5, 0xbd23b0bc, 0xec25f573, 0xf3fd3fbb,
+ 0x1f9f3e46, 0xdd7f5fed, 0x46e0fbee, 0x5c696fc0, 0xd03723f3, 0x9f25d97a,
+ 0x91769c63, 0xf50aecb5, 0xd4be9e79, 0xf3adffcf, 0x1fe01c27, 0x9e6d7eb6,
+ 0xfecfcb14, 0xdffccaca, 0xf8e9febd, 0x2177e29e, 0xab2740a9, 0x63342fbf,
+ 0x55d57e89, 0x8e80f2a8, 0xec0931b2, 0x99c595ab, 0x2bbee9c6, 0xaec7ce54,
+ 0x5fb8b10a, 0xe833e816, 0xdd8335df, 0xf335fe57, 0x7fe8e28f, 0xc794ee70,
+ 0x32dec9cf, 0x69db16fa, 0x3b08b7bf, 0xa84acd6f, 0x93ef8468, 0xcf033988,
+ 0xf688732b, 0xe4acafbe, 0x8f3809ea, 0x479c0c84, 0xbdae9c6e, 0x40346cab,
+ 0xcc0c9f7b, 0x2a23cc57, 0x23ce8cbf, 0x78c10fab, 0x29701916, 0x194d85e6,
+ 0xb79ff948, 0xeccc0e7f, 0x426711b7, 0x764fef54, 0xa09de2dd, 0xddaa5bf1,
+ 0xfedfc7a0, 0x5623bc4e, 0x3675c5fe, 0xfd7b9fc6, 0x03e42f5e, 0xde3cf1e8,
+ 0xbbb12c25, 0x8f5be3da, 0x15fe3d4f, 0x98f1eabc, 0x427b91f3, 0xe93c0c52,
+ 0xbf3d12f1, 0xba00ac0c, 0xd1140de4, 0xd074297e, 0xcbf689e3, 0x5f6f7e87,
+ 0xf9c1fb42, 0x08c2b8ab, 0x43372f76, 0x457fdc20, 0xc22f36ff, 0x257fcc1f,
+ 0x3748ed5d, 0xe3db5e3d, 0x979f93d1, 0x1edf5d1a, 0x37e617c0, 0x3e400fb9,
+ 0xc24da359, 0x1c684971, 0xbc7be751, 0x04e4f102, 0xbbef1e1c, 0xaa40c71b,
+ 0x5762aef8, 0xff2888e2, 0xeb5afb8c, 0x2705e6e7, 0x39ff029e, 0x04b7c12b,
+ 0xcc44a6e2, 0x8a3a3cc0, 0x3e5ac3bf, 0xcd6bfce3, 0xf8a13e40, 0x0c43b6d4,
+ 0x664fde07, 0x5d4e79ed, 0xf4cf8ebb, 0xecf857eb, 0xa6307815, 0x3e14be3d,
+ 0x7ee3689b, 0x13d27779, 0x5b21e4fc, 0xde802446, 0x98a4c126, 0x075188f1,
+ 0x9c3811bd, 0x051f915f, 0x773c8be2, 0xf427f9f6, 0x8eb51357, 0x1cc0f8aa,
+ 0x2d9b77d1, 0xf852fe86, 0xb74e4ae3, 0x13bc892b, 0x12574be2, 0x7d9117e3,
+ 0xfd744640, 0xde3c6cb3, 0x80f483d2, 0xbab2ee75, 0xaf997ed8, 0xea6eb233,
+ 0xb3dd0256, 0x71d9f8f9, 0x834efc36, 0x112d8d84, 0xbde267fc, 0x2929b235,
+ 0xf7890f3a, 0x8415e927, 0xf03371f9, 0x178a5cbe, 0x9d1ac172, 0x609b42c7,
+ 0xf85c7bc4, 0xc6d74e3c, 0xb6df90c9, 0x003df44e, 0xf6116ceb, 0x19f5c10d,
+ 0xeec1fd43, 0x6f3fdbe9, 0xed0655d8, 0xf6215fb4, 0x2f9ff3e3, 0x7843b8b2,
+ 0x3ab039bb, 0x94ff63a3, 0x07da358a, 0xe1b22e45, 0x41cbc8bb, 0xcc22c2ce,
+ 0x53cfc83b, 0xc2299c76, 0x3887a0fd, 0xe1465c97, 0x113b3eed, 0xa973f9f3,
+ 0x7a7e81ba, 0xb7f3d7be, 0x90279f9e, 0x4f784cf0, 0x363fc7cf, 0xdff1400f,
+ 0x90737c22, 0xeeca8df2, 0xf942fc29, 0x5d1b79e7, 0x6388db77, 0xfdbb814f,
+ 0x53cf88ce, 0xfe29eec1, 0xf10fd479, 0x3afd00bc, 0xff15d3f2, 0xf7cd937c,
+ 0xc233f412, 0x99fbe87a, 0xf8065d03, 0xcd90fe7e, 0x573c32f3, 0xed8b96fc,
+ 0x232ec837, 0x3be74819, 0xcea1d393, 0x593ef040, 0xf6808179, 0x961276ec,
+ 0x2bdbbc60, 0x76becd24, 0xc9fc25a6, 0x587e70fd, 0x99ed0039, 0x14fabe0f,
+ 0x8f967df1, 0x13bfc55c, 0x0fee1819, 0x163bbefb, 0x43c7df6a, 0xbde8acc2,
+ 0xbed09f9d, 0x6e0092dd, 0x877c0a73, 0xfb6b205b, 0xd657c7eb, 0x7fab87a1,
+ 0x63df9caf, 0xbb22f704, 0x9fc2fe55, 0x8d8fcc6c, 0x7e2df7cc, 0x37c5018f,
+ 0xc1b3d5d8, 0xc50f024b, 0xf4a55fe0, 0x8c7b25c5, 0xe6f5a3c3, 0xb1e9e6ed,
+ 0xc65117ee, 0x833df051, 0xfcf82934, 0x65ff1636, 0xc01c58fb, 0x734844f0,
+ 0x7d94af4e, 0xdfd013c3, 0xa0275beb, 0x97525d7f, 0xf1a59863, 0xb83ed9f3,
+ 0xf70f9f9d, 0xfaff405d, 0xafcfcc9d, 0x42fdc4ab, 0xf7db3d49, 0x5cef82ac,
+ 0x0c89f3ba, 0xb23fff42, 0xa9bc859f, 0x9047b852, 0x53e087b5, 0xacd53ef5,
+ 0x897db27f, 0xf611b969, 0xc934bea3, 0x5abfeb4d, 0xf747155e, 0xc419554d,
+ 0x29bee842, 0x27cb57f1, 0xb54d18ae, 0x20479273, 0xb2af5889, 0xfefce98d,
+ 0xcb57f939, 0xe36596aa, 0xaede2bbe, 0x2476cfda, 0x2e6de71f, 0xfb4763c4,
+ 0xbc12c7d8, 0x3c5576c9, 0xb3ff4f42, 0xe004ae71, 0x7f7ce5bf, 0x59c2f57d,
+ 0x0cb06fb8, 0xf90e9f38, 0xee9cd961, 0xb38f3b2e, 0xdcf7d95a, 0x00f4d6e5,
+ 0x456ba9e8, 0xd9e60b9f, 0xfef9c6f6, 0x6b7e4710, 0xb7dc11e0, 0x8ebdf905,
+ 0x5e45fcfb, 0x65fabe75, 0x5f67e676, 0x03a3497d, 0x8cd71df6, 0x677e0bfc,
+ 0xeec8da7e, 0x6d196b4d, 0x4fb9f8d2, 0x032ef2da, 0xd1494af8, 0xce7e8227,
+ 0x20ebb11e, 0xec8efbd8, 0x780ed444, 0xe403b004, 0x3c54fefc, 0xeddfaa07,
+ 0x0b65d880, 0x74fd6eff, 0x9dea637d, 0xf0dd2cb4, 0xb7ec0717, 0xcfccedb2,
+ 0xc26c6d3b, 0x5e4a747b, 0x079ef115, 0x6dea6e3a, 0x9fae5f10, 0x1b10f595,
+ 0x076d4e26, 0x43afbf09, 0x8caf07f1, 0x2edc0393, 0xbc4d712a, 0xbd5c63df,
+ 0xda38b1e8, 0xf7a785fb, 0x0f9e3e66, 0x1b922174, 0xd92325dd, 0x3f227e85,
+ 0x5dbfa1e7, 0x0ef0af70, 0xfebd795e, 0x40af1bf3, 0x4276a266, 0xd7c93f00,
+ 0x98ef0585, 0xb7fc563e, 0xe36b5f71, 0x527f7a97, 0x83e33bb1, 0x20f49743,
+ 0x8dd71780, 0x5ec21df8, 0xe94de623, 0xf0bccdfd, 0xcafc0ec4, 0x363f9147,
+ 0x02b1f7d6, 0x19d9873d, 0x7fd7965f, 0x94aef78e, 0xb834d091, 0x5eaca6ff,
+ 0xf7c88674, 0x6f25e9e9, 0x6ac1dfc3, 0xe02e4a0b, 0xeee0b6df, 0x6f5021b8,
+ 0x561e3110, 0x65f64efe, 0x41ad67c0, 0x291fef09, 0x01cc7edf, 0xf3b140fa,
+ 0x2f7641ad, 0x08f05b49, 0xb6e0573e, 0x065f2436, 0x818367f6, 0xed773fed,
+ 0xfa0ad6f9, 0x67f3f5e1, 0xabdf7193, 0xff9d69d8, 0x7377c4ab, 0xbe2462ed,
+ 0x896ff6ab, 0xf2007d98, 0x2412f2a7, 0x7f510a22, 0xfe9d9db5, 0x93b12c88,
+ 0x823af6f6, 0x8231e27f, 0x77edeb9c, 0xfb3adf04, 0xfb9d88fd, 0x30c8bd8f,
+ 0xe1afc7b8, 0xfc7cf27c, 0x756833ee, 0x0cf8c22e, 0x76da4ff3, 0x14d8fa7d,
+ 0x644fbe78, 0x179ffddf, 0xd8dfef91, 0xb377bf31, 0x2af78d4d, 0x6eb9d7a4,
+ 0xd1b75a67, 0xc776e7fe, 0xd1b578b3, 0xbbfa997d, 0x00ff6883, 0x3ba857c7,
+ 0xbb92f73b, 0x3f3b7dc3, 0xb70cffda, 0x45eaffbb, 0xb8d2f790, 0xc35044f0,
+ 0x990e6bfd, 0xb30c5f40, 0x7a625f7b, 0x7a0acea0, 0x7be32640, 0x516e3a10,
+ 0xfc0f193c, 0x4e24ae15, 0x757bc3c8, 0x7400c1af, 0x0336b119, 0xf1d664f3,
+ 0x7579c173, 0x950ca6d5, 0xcfc7997e, 0x724a4e95, 0xf9ea927a, 0x03d30770,
+ 0x3f177727, 0x03f2fa87, 0xc317e933, 0x983b263e, 0x9264dbbd, 0x7e87aca7,
+ 0xefb80d87, 0xeb67b5d8, 0x6e0fb81e, 0x50d741de, 0x41a737b0, 0x86bc281e,
+ 0x20aaeb7d, 0x23e1b6cf, 0xbf5416b0, 0x0d1029af, 0xc46ddc74, 0x0764e2c5,
+ 0x8dffb80c, 0x278917c4, 0x29f9d619, 0xf6dbbfd7, 0x50e7341a, 0xa43df8db,
+ 0x39d9da1f, 0x8b3b7ed4, 0x3bdc6d53, 0x944ef93e, 0xd001df43, 0x9b47e5ff,
+ 0x68ae1cab, 0x97f14d5c, 0x38d81cc6, 0xe7fd3065, 0x13831698, 0xb03aedc8,
+ 0xbaf5845a, 0x25db524e, 0x13fe7690, 0x1a89f785, 0x0616b6de, 0x0de3ce8f,
+ 0xff055390, 0x3c3f02d4, 0x35b7d688, 0xbf209319, 0xb2bfc14a, 0x577c650e,
+ 0xb2acf11d, 0x367928a1, 0x577c4f7e, 0xb87cf7b9, 0xa0f72893, 0xb6ce5f23,
+ 0x3f195a7b, 0x3f50e9c8, 0xfd1e3bb9, 0x9edc4d92, 0xde82b491, 0x4e853f80,
+ 0x7f660e09, 0x3474f994, 0xbfa73c7e, 0xbe50fe52, 0x64b9275e, 0x1f7e1be4,
+ 0xc50e4ba0, 0xae3c81f5, 0x77f83e86, 0xae79545a, 0x47c00ef1, 0xd47e368b,
+ 0xc0306cd0, 0xdb6558f7, 0x66bc4485, 0x6dfe93a4, 0x758ccf84, 0x070d7fc8,
+ 0x7171ca09, 0xbe2c5ded, 0xf83d4247, 0x5e7858bd, 0xcfc3f20d, 0xb409bbad,
+ 0xb55c131c, 0x37e207b8, 0x8ab900e4, 0x0dca89e2, 0x26d51594, 0xf779d7e0,
+ 0x3f2e72b0, 0xd2b79dff, 0x5859f287, 0xfafbf2c3, 0x7cd8323a, 0x4312bf38,
+ 0xfbc8777c, 0x7fdb8e78, 0x022fde65, 0xa9fad2df, 0x611bc7fa, 0x975fca5c,
+ 0xdeee203a, 0x3053e8f0, 0x4f5f855d, 0x4e1091ad, 0x7cf6bc51, 0xd74e72fc,
+ 0x7e300f57, 0x1a46b31f, 0x8d31f70f, 0xe2138991, 0xacd6dbc5, 0x6f7f4115,
+ 0x60ce7e03, 0xfd760e72, 0xac87eee4, 0x773b04bf, 0x2e2040c8, 0x8a44c9bd,
+ 0x62e4a836, 0x34d7aad7, 0x5b5c5bf2, 0xdfe30539, 0xe80249cd, 0x156e4579,
+ 0xb9326fbc, 0x5ffca327, 0x09ff93ab, 0x0e39fdec, 0xb9c79746, 0x893e3ffc,
+ 0x947d3fca, 0x005126b8, 0xb14c9b38, 0xf69ae9ef, 0xa22ff923, 0xd3b68f57,
+ 0x6c1cd3ab, 0x43e8ef5f, 0xe6bb2fc7, 0x23ebee2c, 0xf37ce3f3, 0x6f8504f8,
+ 0x7fc00432, 0x5f60a535, 0x2bc517c0, 0xaffa33f0, 0x32736fa0, 0xf6a1bef1,
+ 0x3948b8fc, 0x6dc8d397, 0xf229af54, 0x7a022beb, 0x58a84d67, 0x72767e0c,
+ 0x7a7c8cbe, 0x4ef5f04a, 0x14ed76a2, 0xbd0c73c8, 0xf4c1d130, 0xa7c939c8,
+ 0xfdbcafb9, 0xe077483c, 0x63ba22eb, 0x1a917583, 0x51f409c1, 0x6c355dda,
+ 0xc394b15f, 0xf52b9e53, 0x2ff78d1f, 0x9783c5da, 0x333d983a, 0x7fb056c1,
+ 0x2233d980, 0x20b9478c, 0x83bbab86, 0x76a3cdbc, 0x1d9556ec, 0x2355253b,
+ 0xf8782abf, 0x73f7e735, 0x57dd6c89, 0x829679f1, 0x673aa7ef, 0xa3041ba2,
+ 0x145ae4c0, 0x008bbc98, 0xb1eed4ff, 0xafef9193, 0xf3f7cd89, 0xfe42afd7,
+ 0xc4e49c4c, 0x371e48ef, 0x83892dba, 0x00e3e962, 0xfed6bb96, 0xc059f706,
+ 0x1df720c7, 0xc81141c9, 0xffc18901, 0x2affca01, 0x407c29fa, 0x8745e2f9,
+ 0xf9e84f4a, 0x53df3942, 0x7749b2f0, 0xeb8e783e, 0xba5e46f9, 0x5153c83a,
+ 0xe9a3f3d6, 0xce8ed2dc, 0x473a306f, 0xade80be5, 0x81df89e8, 0x2c74a59c,
+ 0x9c12fd67, 0x8faa9f38, 0x485e6167, 0xaa273f35, 0xf329e3e3, 0x42f5c03e,
+ 0x353ce747, 0x1c5fdf56, 0xd748f3ba, 0xe47f28a0, 0xc176bf71, 0xb39e335a,
+ 0x9e4c206f, 0x01f15de5, 0x4e9e77f5, 0x294c7523, 0x3e808faa, 0x3856891f,
+ 0x42d77504, 0xc74be913, 0xb051973d, 0x7e6df20b, 0x0fe724d6, 0x60d8eba6,
+ 0x835ea792, 0x64f701fb, 0xdf393f80, 0x6f7884e0, 0x4029c7a2, 0x0343023c,
+ 0xd8fb8720, 0xb8fbc338, 0xab7dc32f, 0xf41c3dcb, 0x2f4e69c1, 0x1e0abe85,
+ 0x1d77b23a, 0x025fb5d1, 0xede3a73f, 0x26f23d7a, 0x38e79b97, 0x47ae2f1e,
+ 0xc9e41164, 0x448b7c41, 0xd3367f98, 0x923d1183, 0xd01cf04d, 0x9e55c7c1,
+ 0x509ff52b, 0x5212388f, 0x74647a54, 0x423d4c73, 0x3fe5317f, 0xf41ccd65,
+ 0xd8c1c967, 0x027a6cfe, 0x6029c7b3, 0x14bf6947, 0xd33dfd99, 0x503edcd3,
+ 0xc57cc48e, 0x8c6635ea, 0xc87a2be3, 0x878c9531, 0x00eacfbf, 0xa6bd0bbb,
+ 0x095e0efa, 0x2669b3e7, 0x9f179c17, 0xf748c292, 0x5cc37453, 0x15e1fc8d,
+ 0xf431de80, 0x85f88111, 0x2c9ed7fc, 0x51062efe, 0x11e4164e, 0xd6bba3b4,
+ 0x2abe428e, 0x8014cfca, 0x136b8b6f, 0x9a4f6805, 0xbe8034e0, 0x6a31d652,
+ 0x49fc88a1, 0x824460e5, 0xe4a31e8a, 0xd5f0110a, 0x2697d93b, 0xd6fdd225,
+ 0x4cfd57af, 0xd0f1bf1d, 0x68b48afa, 0x1fd686fc, 0x7ceb75b4, 0x213726fc,
+ 0x3fe420f0, 0xe4f0eadc, 0x5635b8c0, 0x59942e6f, 0xce302b5d, 0x88bcd9db,
+ 0xe52fcb1f, 0x0e444e3c, 0xcecb8bb4, 0x5c6175ac, 0xa7cc1a76, 0xa7f1fbac,
+ 0x73de1c00, 0x66efd311, 0xf5c2e8f3, 0x2088f902, 0x2b78ba3d, 0x28978844,
+ 0x384ee77a, 0xf6a14594, 0xa1ae7008, 0x2de81bc8, 0x3c95a7f0, 0xd95b8808,
+ 0x401f6e31, 0xc27a823e, 0x5a3ea8b0, 0x79886f91, 0x04c2f15f, 0x9faa4fdb,
+ 0x9beff049, 0x477ca97f, 0x2d3ca228, 0xebe9504c, 0xa70ff3c7, 0x7608f3b2,
+ 0x7cdddfaf, 0xb916e78c, 0x4ba034ff, 0xa1867ef4, 0xf90c9366, 0x5c43c4a6,
+ 0xb1fe554e, 0x76421410, 0x56fd63c8, 0x874a1e20, 0x2c456fb6, 0xde3ffb9f,
+ 0xcfe01949, 0xd4dc1837, 0x0bfc8233, 0x6f770794, 0xd4a7df82, 0x73127bf1,
+ 0x091e6d1a, 0x1c421de2, 0xa3da8eff, 0x1d18e73d, 0xdb4f5f4e, 0xf8cd0717,
+ 0x72dafdb7, 0xe0afbf94, 0x1598efc6, 0xe7790efc, 0xd79881f1, 0x8376ac69,
+ 0x30b6ad9c, 0x2c2dabf8, 0xa2dab76e, 0x004ae7bc, 0x79d1ddbb, 0x1ec2f67b,
+ 0xe253ff18, 0x90e1d98d, 0x0cc9f808, 0xc92c0cbb, 0x0c678d8d, 0x72b75c13,
+ 0xf1c75f0e, 0x46ef69bf, 0xd679ec11, 0xb0c5ea84, 0xf763d9ef, 0x6bfa00bd,
+ 0xdfd6b66c, 0xf3f0211b, 0xf704c9e1, 0x249c8a4b, 0xe09d9337, 0x6c1e24da,
+ 0x1a0a80f6, 0x13b3d27b, 0x5e0995f6, 0x553c0022, 0x8006cffe, 0x8478ba4b,
+ 0xdfc0ba6b, 0xfb7fe5eb, 0xb4d9c390, 0x7200bc77, 0x8269a5df, 0x9ed41ae0,
+ 0xfec257cf, 0x53cb047b, 0xfb2afa01, 0x5e2fdec2, 0xa5f0013a, 0xfae26ff4,
+ 0x2f9f0afc, 0x74c64217, 0x7718213d, 0x2340f4cc, 0xaa35495c, 0xb9346e48,
+ 0x4799eb54, 0x668f5e10, 0xedd1d719, 0xca072fa0, 0x1c44b663, 0x10c9ec77,
+ 0xad74b7e6, 0x43f69020, 0x401d357a, 0x4557aa3f, 0xdcf40093, 0x9c0df7b4,
+ 0x5da6cf6f, 0xb5f2e4ac, 0xca05fb91, 0x98d98ebc, 0xcfc63cdd, 0x334eaba9,
+ 0xc12079bb, 0xca4bf987, 0x7c72aa3a, 0xfe141569, 0x19cbc84a, 0xce5e71d1,
+ 0xb2930491, 0xd608ffdf, 0x79bd3e57, 0x3ea0f00f, 0xefba907e, 0x7523d230,
+ 0xaf96db21, 0x0040b7dc, 0x4672b17d, 0xa281f8ec, 0xf8f25637, 0xe5ff2aab,
+ 0x4f4f5a94, 0x66b24829, 0xf292f4aa, 0xfcd153de, 0xff3c4d97, 0x7bcd03e5,
+ 0x805a9783, 0x79b2ee9f, 0xe573c0ce, 0xe3ad0bef, 0xd947b77f, 0xbaf82acf,
+ 0x80fcc9c2, 0x1fd70903, 0xc0247383, 0xf1f29393, 0x3cec4b3a, 0x069dcbf2,
+ 0x7e3077ee, 0x5f8c4d21, 0xff6a1d60, 0xb001bfeb, 0x00d7432f, 0x0000d743,
+ 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0xc9332666,
+ 0xe4cc9924, 0x40275e49, 0x21c40a30, 0xeb141021, 0xef0c0124, 0x02415041,
+ 0x8042120c, 0x2a941324, 0x8065bd6d, 0x8d520318, 0x8bd4b45e, 0xd7a5783a,
+ 0x2941b622, 0x84ec1a86, 0x3a0bc157, 0x94b62a28, 0xaa54141b, 0xa5ac4090,
+ 0xd7f97b96, 0x661f7b5a, 0x962264ce, 0xbfefbf62, 0x767e9fff, 0x67d9cfb3,
+ 0xfbd7b59f, 0x649ecfb1, 0x1258c4ab, 0xdd3b3763, 0xd8c67a65, 0xc1b758be,
+ 0x88d8c45a, 0x596edf62, 0xb9786c61, 0xda1eb777, 0x3bbf564c, 0x94061136,
+ 0x6826c733, 0x3dac1dec, 0xa384da0e, 0xb838ce1d, 0xa36adfdf, 0xacfa6e79,
+ 0x8c2db98b, 0xab98950d, 0x97631065, 0x60d6eff0, 0x31d56a9b, 0x0627f306,
+ 0xe306254a, 0x6cb8c436, 0xe961bef8, 0x4001b2f5, 0xf1d66449, 0x03631fac,
+ 0x2b8d0aad, 0x96ee762c, 0xa7563de1, 0x8b79c64b, 0x9ef4ac63, 0x6a771cc6,
+ 0x1d3e7f3d, 0x4e89679f, 0x37c02269, 0x5b18bfec, 0xfb6ddd03, 0x1065254b,
+ 0x6f1467be, 0xc0b67319, 0x056057f8, 0x115970a1, 0x9f7c249e, 0x39ebef44,
+ 0x4acf3bbf, 0x129ceaf0, 0xa8fc324c, 0xe860c7c5, 0x32f5a5f0, 0x02c89fc2,
+ 0x6d000312, 0x2312d6d5, 0xc6bd37bc, 0xfe61b921, 0xf95c629b, 0x0e635cf8,
+ 0x6d0a1c5c, 0x0ab7ce89, 0xe7103b9e, 0xf981653c, 0xf668bf17, 0xfa31349e,
+ 0xd5ff04bb, 0xfa6824b6, 0xef34d69e, 0x7f60bcc9, 0x0d23fe31, 0x4ccfdbfe,
+ 0x3563186c, 0x407b16fc, 0xef8cdf76, 0x3c7535a9, 0x75fa173a, 0xc8caf8bf,
+ 0xae0a4960, 0x6578e017, 0x3dcc417f, 0xa77ae096, 0x9977a4f5, 0xbd27a935,
+ 0xde824a87, 0x4ade8163, 0xb29f7a4f, 0x3b7a0824, 0xfac107db, 0xc24c5de2,
+ 0x135f01e7, 0x85dc3d39, 0xb788c1ae, 0x380332a5, 0x587a455e, 0x538f4cae,
+ 0xa71fce16, 0x2a1e9c2c, 0x38c6e61d, 0x75d2b4ef, 0x96f5ef46, 0xbebc3cb2,
+ 0xdcae8276, 0x16cf8117, 0xee342d59, 0x05fcf1aa, 0x99e287d3, 0xfb6dfdb5,
+ 0xc1efa10f, 0xf784cb7f, 0xc0378845, 0x583f5c7b, 0xf84ebff7, 0x53f91928,
+ 0x203aea67, 0xdb6a3e01, 0x25864564, 0x9c954c0c, 0x5b190b27, 0x89cda0f5,
+ 0x8b5cf07c, 0xf18288e4, 0x6b14c9cc, 0x22564332, 0x75fd9d62, 0x11bb3e7c,
+ 0x8360b85a, 0xa334de71, 0xcef2136f, 0x8c33c01e, 0x380824f3, 0x001fe01a,
+ 0x0555a747, 0x0df749cc, 0x559ff2ec, 0xf851fb82, 0x6a4b982f, 0x80976f69,
+ 0x998aab70, 0xef7000db, 0x1f89936e, 0xf68c6b9f, 0x2ffcc145, 0x607f396d,
+ 0x3ffbf426, 0xc165c3a8, 0x27eb04df, 0x53a8f831, 0x1cad04ba, 0xc3d3ca67,
+ 0xed1c877d, 0x4b7c6190, 0x8b3e5c74, 0x3764ac67, 0x955b3f31, 0x7bc0f30b,
+ 0xd347b556, 0x82e556fa, 0x1f10e47c, 0xd9f8863c, 0x69646b13, 0xe41bbd70,
+ 0x670dc706, 0xcc8cef1d, 0xbba9d209, 0xbbd9cbf5, 0x189efd60, 0x2627af3e,
+ 0xde00c7cb, 0x07175dce, 0x5b8f1f20, 0xca35cf36, 0xd924d8ce, 0xafe91ebd,
+ 0xde66f73e, 0x6f8871c7, 0x5e0832c6, 0x841c9fa2, 0xacde32ef, 0xac72bf1c,
+ 0xc9d1d69e, 0xeeb81da2, 0x2193a316, 0x39c7bc9d, 0xad78ab7f, 0xd9d1bc13,
+ 0x0dd47456, 0x68ee7beb, 0xef9f0386, 0xeb36ed6c, 0xe2cb7de0, 0x75c0bfdd,
+ 0x715d99c9, 0xcf8841ae, 0x063bebee, 0x097a1e91, 0xfc1f77af, 0x741ee6d8,
+ 0x86dbeb55, 0x7d695fcf, 0x49a5bd1e, 0x3fc9ef8a, 0xb5207ce1, 0xca55ffb5,
+ 0xa8613927, 0xcc59bcb7, 0xddd60ab7, 0x93487838, 0xc69e848c, 0xc64f9414,
+ 0x0c9fac2a, 0x2abbd20c, 0xf107b5de, 0x8cd7caac, 0x843ed778, 0x5e93df0b,
+ 0x8fdceb40, 0xf343fcfd, 0xabba0d0a, 0xc8e1e75a, 0xfe13f4eb, 0x6a7ac56b,
+ 0x0cbf164d, 0x866db3f0, 0xf9543a2f, 0x5e13dbec, 0x0e31c7a0, 0x1ba8e3af,
+ 0x8b7bf9e9, 0x43e21563, 0x62bab01f, 0xf8e3fe09, 0x373c563e, 0x21bbd715,
+ 0x858f69c6, 0x30579bf1, 0xb4520fce, 0xdc5879e3, 0x68b63dd6, 0xf15593d4,
+ 0xdf3853ee, 0xb3f3ba0d, 0x02c7685d, 0xdc3ddd2e, 0xd7867c0e, 0x7adddd61,
+ 0xc65ea382, 0xfd62aff9, 0x71f322e7, 0xd9fc3a0f, 0x54e7a21a, 0xf4148cfc,
+ 0x41f8891d, 0xffa5dc85, 0xc414c3a2, 0x3d4a048f, 0x3e73d6dd, 0x10b23ac6,
+ 0x9f1df6de, 0xf980e80e, 0x74f8deea, 0xdd6fca36, 0xb888a26f, 0x7d737ea3,
+ 0xd9f1f23c, 0xc5bd3612, 0x7e9f53d2, 0xa5debcb1, 0x1ffae607, 0xcbd25f6b,
+ 0x44602c35, 0xb2db5d3b, 0xd10fa5c4, 0xe93100a7, 0xc08683dd, 0x60ff9c04,
+ 0x0056cc91, 0x863b75df, 0x7a08b0a7, 0x5adf6d5a, 0xb9955cce, 0xf512fd8c,
+ 0x8ed7f21c, 0x9784f1a1, 0xe3e91b36, 0x9707f1f0, 0x1946bb57, 0xe0ef9f7a,
+ 0x1f74f310, 0xcc213f3c, 0x8131b90f, 0xa23195db, 0x44e94505, 0x8f6ccf38,
+ 0xd2e179f5, 0xe2f78299, 0xcce9e018, 0xbd0b77b6, 0x58672fc0, 0x51d7bee0,
+ 0x30b4be7e, 0x0c267bf4, 0x4570af79, 0x6ede506c, 0xbf6be629, 0x7143b5e5,
+ 0xb09f8c0a, 0x37a27775, 0x30b77f04, 0xf99797fd, 0xcbdf0737, 0x1df4c7d7,
+ 0xec1e9003, 0x0ac9d3f5, 0xec7613b4, 0xa07ce44d, 0x4bce90e8, 0x15fade85,
+ 0x9c111a5e, 0x3ab2c26f, 0x60c2a8d7, 0x9982f6bf, 0xfafb42f9, 0x5f4d1180,
+ 0x5d0b05ed, 0x26c427b7, 0xc3e8fe92, 0xf8fea0fa, 0xbf0b78b6, 0xe0ede2ae,
+ 0x6859d390, 0x239acfbf, 0x62edc9f3, 0x4463b75c, 0x1347fa0a, 0xd6fefe8c,
+ 0xf318e308, 0x75f0b8d1, 0xeddcb9bd, 0x3bdb951a, 0xcc8de37c, 0x1cafc91d,
+ 0x9afdc09f, 0x7999876e, 0xdbefae41, 0x743b2068, 0xd307e2e8, 0x9f7e810a,
+ 0x5758306e, 0x9fab3e02, 0xaff19dd9, 0x487abf70, 0xfe825594, 0x3fbf8aa7,
+ 0x6782f1f2, 0xfbae1764, 0x25f70dd3, 0x73f683cf, 0x801ac7e0, 0x0346c163,
+ 0xf8deaf5d, 0x5a7eba7d, 0x6782e9f0, 0x9ea20692, 0x4d67b43f, 0xfab3ae32,
+ 0x13be1fbf, 0xa356c5f5, 0x6810e075, 0xae48b66b, 0xb1722151, 0xa6b305e8,
+ 0xaac755bf, 0xbaea1d71, 0x7cbee499, 0xbc78015f, 0xba0fdc09, 0x8f65ff6a,
+ 0x7f017fd6, 0xfdc09bc5, 0x61534995, 0xdd4575dd, 0xdeee27e4, 0xfc764d17,
+ 0xfc9916b7, 0xbf90ff01, 0xd08de7fc, 0xbd6ffb2f, 0xc1087c83, 0x5e85a3e7,
+ 0xf48f2c66, 0xf7899550, 0xc9e876cb, 0x958b289f, 0xd07edf09, 0x08c8a313,
+ 0x61a32d39, 0xe7d4f7dc, 0x46eb91e4, 0xf1d1b8c0, 0xe27e8606, 0x268bfcf7,
+ 0xb7efd030, 0xd47fd05e, 0x529eb211, 0x23a3d4e6, 0x9a0cc252, 0xe3a3abeb,
+ 0x08ff479e, 0x1ea3d326, 0xef69332f, 0xee3fee8f, 0xd1bbda34, 0x5575ed56,
+ 0x39439e7e, 0x83941818, 0xf4fefbdd, 0x675878c4, 0xfb9941d5, 0x33d05763,
+ 0x72bae16f, 0x566fde91, 0x0ee7816c, 0xba1cec09, 0x1a4369f8, 0xc4b157f2,
+ 0xd3ff4256, 0x91e5518b, 0xd54622e4, 0x9ce80c37, 0x44f3a417, 0x7dcbc2c7,
+ 0xc5c98b14, 0x11f72e4b, 0xefaf6ffe, 0xef2e59be, 0xfbd2304e, 0xb861f5c3,
+ 0xfa577cfc, 0xbd90c270, 0x6a58de59, 0x17ed8e7f, 0x099eb95b, 0xfae18fd7,
+ 0x1c2b854f, 0xb20bdade, 0x4f8def46, 0x505c6850, 0xfee919ff, 0x3eb38c35,
+ 0x6710884b, 0x7c267d81, 0x29e98779, 0xe1ff03be, 0x641b8e0c, 0x0025ec51,
+ 0x6fb58352, 0x25f5ea0c, 0x5e177716, 0x86e97ecf, 0x0c17e851, 0x43acd2dc,
+ 0x7129d1fd, 0x88366d7a, 0x8283fb16, 0x045fd071, 0xfa131cdf, 0x53a0e200,
+ 0x2efb6816, 0xc31f632b, 0xcc4ca2fa, 0xbb202e6b, 0x041435ef, 0x7e023fe7,
+ 0x8d99c60c, 0x9fc78c25, 0xebffdc09, 0xace8a79b, 0xcbc3ff30, 0xc093cead,
+ 0xa797abcf, 0xf2f2cb52, 0xfbbf4874, 0x6fd06e04, 0xbbbce7c4, 0xa75d69a2,
+ 0xca3e5724, 0xbe02c3e5, 0x62dc7a70, 0x35dbf953, 0x9a2fd420, 0x5f591a5f,
+ 0xd3d36f5f, 0x66a792f8, 0x71dfa164, 0x2ceefdaa, 0x00a7a3d4, 0x41da00de,
+ 0x9bfe23bd, 0x84c785fc, 0xec223e3c, 0x2788bc45, 0x04e4227f, 0xd5b9c7d8,
+ 0xd174eb82, 0xa7cbd5fd, 0xf2f8fb53, 0xc63f7465, 0x12fc4396, 0x4095e237,
+ 0xc9dfa05f, 0x83d932b5, 0x80d746f9, 0x49ef7804, 0xd2e28e93, 0xe52deb8f,
+ 0x9d782cdb, 0xff337c51, 0x509bf1a9, 0xb5cb2e2e, 0xeb6f4758, 0x7576c5bc,
+ 0x7596bc7a, 0xba5da1c4, 0x00c78fcc, 0x7e41c93b, 0x6fbb2f9c, 0x3c6115b2,
+ 0xe38c91d3, 0xc060523c, 0xba060a16, 0xaa3f50b2, 0xe2d57fef, 0x8496c5bc,
+ 0x881b0ef1, 0xcd12d172, 0x9c384eed, 0x1efd05a3, 0xbe08ae5e, 0x88d6a3c8,
+ 0xddc624be, 0xe822af68, 0xb9e27195, 0x38e71613, 0x42dfd11b, 0x03ad277e,
+ 0x38eee5f8, 0x0ebc44e7, 0x6c64c371, 0x3cf0a587, 0x558b29cf, 0xe2538bf0,
+ 0x9a6bb97e, 0xa71e422d, 0x3841bcb7, 0x3c6d671c, 0x4f9e138f, 0x9f355b50,
+ 0xe7ac4730, 0x26ab04ab, 0x30b4a3cf, 0x423ca467, 0xe348cd9b, 0x394e9d52,
+ 0xee5de946, 0xf23fba86, 0x992f98ca, 0x4e281cce, 0xda5b2329, 0x36928f31,
+ 0xf302b7ca, 0xe1098d2c, 0x6335e872, 0x5bafa57e, 0x7185ec97, 0x897701c9,
+ 0x1ed8e011, 0xa5f04c9f, 0x4815fab0, 0x1d6ea1af, 0x9ee87a2d, 0x06a49f68,
+ 0x50a4307b, 0x509047e8, 0x655bca33, 0xa441fbac, 0xfacab0f3, 0xf3054655,
+ 0xf5195e50, 0x9dc969cb, 0x38fe036d, 0xa23a37bd, 0x9b13f75f, 0x6952fbd0,
+ 0xef0a961f, 0x7840c179, 0x93c2fa18, 0xa1de11b3, 0x97a6dc2f, 0x5ff5e242,
+ 0xdf040cd8, 0xb28bbde9, 0x30fe7e29, 0xf4e6e58a, 0xe0a3779c, 0xdf02158b,
+ 0xf3231aaf, 0xdc6233dd, 0x93e9eb55, 0x6b24e7e0, 0xb633f4f4, 0x5d4cbc90,
+ 0xd3d279ed, 0xf429b03f, 0xb7d37f9e, 0xf803ebec, 0xe64ab7fc, 0x7a2fbc40,
+ 0xebe52371, 0x8cb6355e, 0xa9eb82dd, 0x07cc31d3, 0x9bf7d9ec, 0x4fd07d7d,
+ 0xa08654ac, 0xf9f9707f, 0xf11b9b83, 0xb355bffa, 0x34ff8821, 0xe612e3df,
+ 0x3732be05, 0xdabebe13, 0xc056c514, 0x6e1e1692, 0xe843fb19, 0x31d1afaf,
+ 0xebe12bd4, 0x74193786, 0x0dfad8a9, 0x7f4e62ba, 0xdd2a7fd4, 0x488cb181,
+ 0x886e950f, 0x7b67d43f, 0xf046bd36, 0x8f6d70ab, 0x7a2d70e7, 0xe458eb71,
+ 0x36353e93, 0x2a34f309, 0x9da8ff5c, 0x33f686b8, 0x2572e820, 0x8e1ef9fb,
+ 0xe19fb70b, 0xc5897376, 0x5dc71479, 0x15ce7ec9, 0xe847b5fc, 0x8f298561,
+ 0x1d92be60, 0x27de51d4, 0x6c732e9c, 0x9fa3f23d, 0x3f22aeda, 0x8b66c53a,
+ 0x6cdd1f98, 0xd9b47ae4, 0x894ce6c6, 0x04130f20, 0x5d75babc, 0x898bb446,
+ 0xbd44526d, 0xf5c2ca74, 0xafcde812, 0x23d3ee49, 0xf808d5eb, 0xff70ec95,
+ 0x5dfe2dfa, 0xa120aa38, 0x5dba0c7f, 0x3d9d4f80, 0x8f029f14, 0x7c555e2a,
+ 0x884be2fa, 0x3f0b365f, 0xa4bc7b73, 0xb3aee389, 0x169ce3ab, 0x2f664f7c,
+ 0xced13afa, 0xedf8039f, 0xa5c4def8, 0x575f934c, 0xf589eaf3, 0x1438c95e,
+ 0x3ca302cd, 0xbdddb65c, 0xbae300c2, 0xf3c73046, 0xb0af8fd0, 0xb3bea096,
+ 0x31da3b55, 0x8678deff, 0x971b37e7, 0x9a4adf30, 0x73fff187, 0x2a7ca5f7,
+ 0xe965dde2, 0xf5d41769, 0x67eabd81, 0x22e570e7, 0xabd9bd5c, 0x8517286b,
+ 0x17276ff6, 0xd6e891c5, 0x6bf5cf15, 0xebdff184, 0xe2b7ce85, 0xf9d12bf5,
+ 0x390f510e, 0xfc853f12, 0x6b3f944d, 0xe1ee907e, 0x918e2cf4, 0x7b7cb1fe,
+ 0x19dcbc4f, 0x276b2f09, 0xb8f4f2e8, 0x88ed164e, 0xda167764, 0xffbcf3bf,
+ 0xcf527b42, 0x69fc3fbc, 0x56e7e7fc, 0x0ebede3a, 0xa64b7ce1, 0x1fb9e938,
+ 0x5f311877, 0x55a7e6ac, 0x4b5f3d78, 0xb9fa09cc, 0x5a996bf3, 0x9b5d7af5,
+ 0x57718854, 0xe48beec9, 0x7fb6771f, 0x6771fe4d, 0xbeac7f98, 0x4f605ef7,
+ 0xb2d18f94, 0xfcfff885, 0xcbcf1e06, 0x48e9f94c, 0xdfb3c380, 0xf10a7cc0,
+ 0xb40ff92f, 0x679fe85e, 0xf1c7e1cc, 0x1ec9625b, 0x8f30382e, 0xac5f1cf0,
+ 0xbe084a63, 0x4cd19c12, 0xbd97c109, 0x27e9a6dc, 0xc668fab9, 0xabef4ca7,
+ 0xbee69fb9, 0xbd3f7341, 0xcfd340ba, 0x3349bfac, 0xa9597b3e, 0x1de39fa6,
+ 0xafdf19a7, 0x3f4d76e9, 0xcd6ef9b7, 0xb8e6cdf8, 0xe00ea9e7, 0xc3fa0675,
+ 0x7ac52b7a, 0x8f7f5baf, 0x97e639e6, 0x992f58fc, 0xf9fdc82f, 0xb1fb31e6,
+ 0xf229525e, 0x16fbd713, 0xdf9de669, 0xe82fcdac, 0x74bed759, 0x4f9d5fc0,
+ 0xbfa1f872, 0xfef6bd60, 0x848dd6c2, 0xed3e85cf, 0x6a2fc5f5, 0xa687f9fb,
+ 0x4c71c40e, 0x7f442aef, 0x6d76d7ee, 0x748ae2be, 0x55775ef6, 0xd54a8e74,
+ 0x68acd9d2, 0xbf8e1ce9, 0xd85b3c98, 0x37dff87d, 0xa1d62fe0, 0x0aef8be5,
+ 0x6bb07f7f, 0x621b9cf3, 0xcf51c7dc, 0x952eb775, 0xcbebe619, 0xbbb23d79,
+ 0x83fccbf5, 0x7d3c844a, 0xfd3c8f6e, 0xbb10f627, 0x3be9e6a6, 0x2372feb1,
+ 0x97f516fb, 0x3c457fdd, 0x31e58144, 0x8acdff80, 0xf5cba61d, 0x2f307316,
+ 0xd4bfae1f, 0x5ff7f416, 0x83d7a4ec, 0xf055aa75, 0xf7f8b0f4, 0x5aa7085d,
+ 0x9eef18c7, 0x88def04b, 0xff808c80, 0xea9d7c2c, 0x4b87803c, 0x12f8cf38,
+ 0x51c60c5b, 0x4bdcf75b, 0x4b6b0171, 0x480efae4, 0xc43e3a1e, 0xda3d253f,
+ 0x234cff82, 0xe44c68bb, 0x1894d176, 0xbf31c712, 0xd857bf8d, 0x51e6dec5,
+ 0xb5bd18eb, 0xea992ed2, 0x8f585d31, 0xfbd7a089, 0xf683fe26, 0xf91e8be5,
+ 0x4589bed0, 0xf7c27121, 0x7ea1f7bb, 0x26e7bc07, 0x63627bc2, 0x414a6ec1,
+ 0x98d3f9bb, 0xaeb79238, 0x3aefb203, 0xa4de70b8, 0x0506dbc4, 0xf0e12deb,
+ 0x9dd9348e, 0xde7d10fa, 0x66ed6926, 0x43f70163, 0x9db9120a, 0xf8f0b2ad,
+ 0x7be8ac75, 0x4f76fcc2, 0x414f8f13, 0x42dbaa1a, 0x89b1c1fc, 0x5cfe34b1,
+ 0x5c58c974, 0xdf1146cf, 0xf448e637, 0x224946be, 0x5f1e5efb, 0x75d7163a,
+ 0x8e525ec1, 0x3e044ae3, 0x046fa2c7, 0x0e5f736d, 0x0df6228f, 0x13ebf3a8,
+ 0xb6127c61, 0x4d8ed4a5, 0xc83f0ab4, 0xfbd2037a, 0xde93b444, 0x8d65946b,
+ 0x93b6a55f, 0x2ebaf912, 0x0a2acda2, 0x2168c9ca, 0x1e846337, 0x1471fcc3,
+ 0xc2739309, 0xde4d64e8, 0x513188f8, 0x7a258de4, 0xbc7489dc, 0xb7b1d055,
+ 0xcf33b23c, 0x69d507ba, 0xad791e78, 0xd591e799, 0x3c8f733c, 0xc44c63b2,
+ 0x21d2323c, 0x879416c6, 0xf5978985, 0x9bea0673, 0x278e9cc6, 0x1c7f23c6,
+ 0x23cf1d92, 0x31bcc7e8, 0xe2b700f9, 0x91f039d0, 0x4ad81b11, 0x7817f433,
+ 0x1933ca15, 0x2d8b0e20, 0xc3efca08, 0x9f843989, 0xa6fd47c1, 0xfc3fb87c,
+ 0xf31dab98, 0x31a603ca, 0x66ffaa1b, 0x87165cd6, 0x1606c4fe, 0x29596e31,
+ 0x64be39e8, 0x9e728c97, 0x12fc05d4, 0x052b1e81, 0x578e403d, 0x77873d20,
+ 0xeec9bbb9, 0xaa403d08, 0x3da3e30c, 0xc397f23a, 0x57103f9f, 0x7bd230f6,
+ 0xbe722fb0, 0xc385a2e4, 0xfd718c61, 0xbc1fe704, 0xfa88c3ad, 0x37aa8166,
+ 0x0f4c752b, 0xe82a9df4, 0xaf037537, 0x978bb353, 0x9faac92e, 0x867e68c5,
+ 0xb4c160fa, 0x1fe61f58, 0x78e5b416, 0x44972e09, 0xdb4f15f9, 0x17f61761,
+ 0xc56a1d0c, 0x7bf9d778, 0x47927d26, 0x7ae31a2e, 0x513ecf47, 0xcfd900f5,
+ 0xdc5baa44, 0xa2eaf82e, 0x41382145, 0x018daf3f, 0xb0d82c3a, 0x53ee1762,
+ 0x19dfef78, 0xca8e27d5, 0xb270c35d, 0xcb39003b, 0xb3d5b00a, 0x387c028a,
+ 0x2699e695, 0x0d7ef1e6, 0xdf0535ef, 0x01db477b, 0x0351cf5a, 0x5f809af3,
+ 0xa5de773a, 0x98dabfa0, 0xff107264, 0x71d7ba8a, 0x1910fdd9, 0x1d577d0f,
+ 0x2da33682, 0xd606bac6, 0xb8c8cab1, 0x768bab7f, 0x5a27fe20, 0x2fc4f43a,
+ 0xc47a5d89, 0x674159e3, 0xdfc9f1f4, 0x2744624f, 0xe9c75d39, 0x7df0ad96,
+ 0x79b5fd23, 0x751377c0, 0x1902fe42, 0xcc627d78, 0xe0154b3b, 0x2aeb03cc,
+ 0x7f41e9c7, 0x677f8c4f, 0x0ff40e69, 0x4e3f9bae, 0x313dfc0f, 0x732f9dfd,
+ 0x5adfd440, 0x0fefc557, 0xbecbe77c, 0x5bac0fd0, 0x4cdfefc0, 0x59decfbc,
+ 0xf30e3d57, 0xd65eeffb, 0x07fe7c0b, 0x57ef2e64, 0xba51cadb, 0xc67148fa,
+ 0xcf3544b1, 0x1ef80ccc, 0x8eefdb57, 0xa9759da2, 0x41a770f5, 0x8e470f53,
+ 0x8dbf0131, 0x12c57c17, 0x8c0ec8e3, 0xaf1bf413, 0x18fed3f7, 0xf84fc99d,
+ 0x58358ebd, 0x5b006f91, 0xf6152eeb, 0xaed07f7c, 0x724bf969, 0xe80cb632,
+ 0xe256292d, 0x98cb5593, 0x3f768cdb, 0xf1d78758, 0xe1733c3a, 0xd47855fb,
+ 0x0b80f7f7, 0x85b7ab48, 0xe681b5c2, 0x1ceae151, 0x7945e512, 0x0aa7ed52,
+ 0xf5d4a757, 0xb7bf262c, 0x013fbda4, 0xdb19d6e9, 0xff412595, 0x4423a4c5,
+ 0xaea4cec7, 0x48472567, 0xa8e9c0df, 0x38c5727b, 0x19e7bc2f, 0x024ba9d9,
+ 0xf91946fc, 0x8c26933e, 0x8f3de057, 0x58bdb924, 0x73be03df, 0x32ef91f8,
+ 0x4687a48d, 0x27e6d50d, 0xcf9c492c, 0x3a3b459a, 0x30feb9aa, 0x9b67a5f0,
+ 0x78c056c4, 0x236ec5cf, 0x6d8989da, 0x684e8c27, 0x309db6eb, 0xc3aabea2,
+ 0xb753cc3e, 0x6f5118c1, 0x7992486d, 0x0fcc329e, 0xe0399bde, 0xc7dc44a1,
+ 0x45512950, 0x091ddeee, 0xef7fb1a3, 0xf8255c5c, 0x8eb7232d, 0xb966c7c6,
+ 0x76c21fda, 0x8bd8eb0e, 0x2dc3342c, 0x99d2fc6b, 0xbf1a31d5, 0x5dbd5676,
+ 0x0cd39fd3, 0x9eb901d4, 0x1b5d2cb3, 0x5b88303f, 0x2c199e01, 0x6dfa87f8,
+ 0x8ce3a0ba, 0xdc01b5d4, 0x6dc332c7, 0xcc8476f0, 0x856db137, 0xd77086de,
+ 0xbf520e4b, 0x73e0a65e, 0xa10af933, 0xeb437bd5, 0x795ba362, 0x86aea332,
+ 0xd815fbfb, 0x5456bc07, 0x42453e4b, 0xbee9183c, 0xfba255a7, 0x47c7d69e,
+ 0xcf323ee1, 0x26f28952, 0x3c447dc9, 0x1cefec24, 0x51e82b01, 0xf333ce03,
+ 0xa3b312fb, 0xbefe10de, 0xe99cff0a, 0x3f89a7e5, 0xaeaf9f85, 0x7602ba73,
+ 0xc9cfae17, 0xfe80c4fe, 0x64efac35, 0xda9f0687, 0x6d7aacfe, 0x6d32ce7f,
+ 0xf0926a7f, 0x81b207df, 0x93d34f28, 0x55ea3d24, 0xe645ffb5, 0x01f96ffb,
+ 0x6bb2cd9e, 0x8d67f226, 0xa8f54fd1, 0xfa9bb2cd, 0x5eb87dea, 0xc0ee48c7,
+ 0x9639201f, 0x19573e48, 0xf412d69c, 0xe2256ba3, 0xc42c99db, 0x8e09c85f,
+ 0xb3dcbea7, 0xd71268ff, 0xaeccab3b, 0xdb1754a5, 0xc1375929, 0xa77a51a5,
+ 0x55c0fd1e, 0xc8bce452, 0xdedc4963, 0x8a20c5be, 0x2006b807, 0x9f5da293,
+ 0xc2f3ef1a, 0x76fc077b, 0xfbfd17ae, 0x07c08501, 0xb73dca0a, 0xbd85e337,
+ 0x25fe0499, 0xe4037ffa, 0xdfa4e996, 0x495a346f, 0xa43b0bbf, 0x2fe70bea,
+ 0x7c6876b4, 0x3f8a7ec6, 0x7b5fad26, 0xff62f50e, 0xc782ce7e, 0xcc47be01,
+ 0xec8ffdfc, 0x2fb87c90, 0x3ed06ea7, 0xc0299fd2, 0xbadef816, 0x5b47a154,
+ 0x52aefbb5, 0x2e61af50, 0x7a20c27f, 0xe5499a6f, 0x41e92776, 0xbbaa5fc9,
+ 0x4529fa04, 0x0ca6f7bc, 0xbc95f085, 0x75c245a8, 0x0aef3267, 0x463fe3b4,
+ 0xb60a4c21, 0x8fcfed57, 0x79fdc292, 0x65e6124b, 0x148c3b52, 0xe32eb1ef,
+ 0xeba7943f, 0xf2327f39, 0xb0fcf859, 0x0757aa7c, 0x718bf2e3, 0x77b9af98,
+ 0xdc6fbf67, 0xb49b24ef, 0xaac1b771, 0xe7c7bb8d, 0x44cff569, 0x4cef5687,
+ 0xb9a7ee2e, 0x5039c53f, 0x796a7f73, 0x877fa6a1, 0xf8cd66eb, 0x6997a6bb,
+ 0xe3a951fa, 0xda00f2c2, 0x9e4c4afc, 0xeb12bf36, 0xa251e6d0, 0xba7afc0e,
+ 0x9a317804, 0xc06e1dbc, 0x46c81343, 0x47682db1, 0xa899c606, 0x685d1b48,
+ 0x34db60b6, 0x7c8fca24, 0xc787d4d2, 0xbe0751e1, 0x7987ea9f, 0x4c5bf14c,
+ 0x49788a58, 0x8a6295f2, 0x7544d018, 0xd41e1bd5, 0xd3d39bfa, 0xeda95cb8,
+ 0x99f724b1, 0xbc1bac64, 0x7f73a4a8, 0x89f14036, 0xbf719a29, 0xfc89bb68,
+ 0xbe4e3522, 0x9465a71c, 0x0eba409c, 0xf549d07a, 0xaccad613, 0xde7c5798,
+ 0xdba9f228, 0x41dc3ef9, 0x673a1dad, 0x492f7c88, 0x49e0fae6, 0x9c58e957,
+ 0xac0daebf, 0xfad3ca2c, 0xa7588c8f, 0x8f6b6bac, 0xef967b43, 0x7988c8fa,
+ 0x6175e0bb, 0xd15df4e7, 0x55f95f58, 0xff711c8b, 0xf7cc92b2, 0x7a13ec6b,
+ 0x83f7d67d, 0xb0c951f1, 0xb59e7ea0, 0xc32fcbb5, 0x5e8167fb, 0x4a6bf2f3,
+ 0xfa0d3d24, 0x3ccf1359, 0xa7eea699, 0xc1ec6a71, 0x037ec5dd, 0xed6a9fd9,
+ 0x78d339f8, 0x5c7a045c, 0x91a33d7b, 0x1d630bf4, 0x815bcc06, 0x8fdcd75e,
+ 0xd271164b, 0x12e83640, 0xaea381e8, 0x2bb5fbc8, 0xc744f4d3, 0xa232eea3,
+ 0x4f8093c3, 0xec9f97f4, 0xd78e3f81, 0x65ede12b, 0xfa1081e4, 0x4fab8f85,
+ 0xcbf47ee3, 0x07ede8bd, 0x979f7d04, 0x54a80502, 0xe268ae3d, 0xb9a699df,
+ 0xf73f718b, 0x1aafccbe, 0xeb315eb1, 0x7b4312d7, 0x03f687fb, 0xb8cf8fb4,
+ 0xee326f75, 0xecb4f4af, 0x7fc0664d, 0x05650635, 0x1fc0f3fa, 0xea7ff40e,
+ 0x7f04fd5a, 0x3b614b6d, 0x956daf5e, 0x3d92a81c, 0xa18dcedb, 0x468eb275,
+ 0xdf3dffac, 0x93235c0b, 0x5b755fb9, 0x04f3c2b2, 0xda27786e, 0x3e516dfd,
+ 0x00fc849f, 0xdae109fa, 0xe866b121, 0x14dabf3f, 0xa0fbeeb1, 0xd59ef7c0,
+ 0x6ab38a46, 0xc75c79e0, 0x467dccbe, 0x56d3f213, 0xeb849758, 0x0c477c38,
+ 0xc0d4bfce, 0xe150cfd0, 0x3819933b, 0xb0ffeb8e, 0xb81d0212, 0x2652aabe,
+ 0x54b87f7c, 0x9fe723e4, 0xb8c74c6a, 0x77ef96a6, 0x4dd95ddf, 0xab0fbe79,
+ 0x36569fb9, 0x397240df, 0x57f70963, 0xe55af9c2, 0x9f05a7db, 0x386ff386,
+ 0xd7e0f6df, 0xd7e3abea, 0xe6bf20ca, 0xfa07dda3, 0x3e414e8f, 0xeeff01fa,
+ 0xddc5fa65, 0xbb801486, 0x81d5a36f, 0xcb06bdfb, 0x519287be, 0xf7e6ec6f,
+ 0x946cd487, 0xee51feb8, 0x37a5f5c6, 0x091ad919, 0xedd389f9, 0x85374101,
+ 0x14314975, 0xa2fa05ff, 0xbf51ca9e, 0xe9b03087, 0xa73f315b, 0xf067fae7,
+ 0xd71ba96b, 0x6e6ff084, 0x555be732, 0x32340e2f, 0x07aa56f7, 0x0299f4b4,
+ 0xe06cbcf3, 0x312c9cf5, 0xaebf6e5f, 0x5da05331, 0xe4f5cc9f, 0xda87010a,
+ 0x80e4275f, 0xf84ddc65, 0xf8e2689c, 0x5fccb71f, 0x99f8eb81, 0xea30fdd1,
+ 0xef5909d5, 0x6bdda0d7, 0x20e6fbea, 0x07321fca, 0xbc6ae1f9, 0xa7c47bbe,
+ 0xf583ee1b, 0x268faf9a, 0x3e779afa, 0x367e456e, 0x714d0ee7, 0xb53fe047,
+ 0x61c85cf5, 0xd5f03b6e, 0xaad47e85, 0x4ebb29fd, 0x729f691b, 0x2431b9db,
+ 0xe8d2172f, 0x535cfaba, 0xc1cf971a, 0x9aa83f62, 0xadbd04cf, 0x8e082e2f,
+ 0x70c0f153, 0xc2115e77, 0xebd102f3, 0x086c25be, 0x4e3fab4f, 0x73599feb,
+ 0xf30b9a58, 0x1a7065dc, 0xf7ef802c, 0xc62fa7e3, 0x2e6f2ffd, 0x851dcc67,
+ 0xcc4ceffb, 0x03ee1d7d, 0xb03f52b4, 0xeffa953c, 0xdda8572c, 0x84bd7262,
+ 0x4f63ba78, 0xabed2e7d, 0x55ca7ccc, 0x3ce9ef0a, 0x053b1068, 0xa827e44d,
+ 0x36eea1f5, 0x7ee09999, 0xea8936f7, 0xb3fc2a9d, 0x3733a42f, 0xe3df97e8,
+ 0xdac1e0fb, 0xde92ef65, 0x1b9f5473, 0x90d27183, 0xd88d139a, 0xf3fb2cf7,
+ 0x8e2ff418, 0x3e413d83, 0xa59fbf03, 0x0e4fa84a, 0x5ddf711b, 0xcd3b05c5,
+ 0x6baeb2f3, 0xf79dca0c, 0x50ea890d, 0x19cf5bc7, 0x62bdb853, 0x5806ca08,
+ 0xffe0139f, 0xeb813922, 0x3a21b693, 0xdca1df4e, 0xd0fc11af, 0x71d7c37e,
+ 0x32d30f48, 0xf19bede5, 0x4332fdf9, 0xda535eb9, 0xa08d6715, 0xbcc28f87,
+ 0x75c15c98, 0x7f7e1b60, 0xeb9bd1ba, 0xeba6e780, 0xfa9bef22, 0xbe72f92c,
+ 0xff14e482, 0x0ab7e024, 0x60b36fc1, 0x8a36f149, 0x20d1fc83, 0xcadab3cf,
+ 0xadb1eb4e, 0xda47d897, 0x147d8cf8, 0xc6f7c7e2, 0xadb6df87, 0x8372f9c3,
+ 0x59238c7d, 0x71845f88, 0xdfbcd324, 0x994cf3cb, 0x11dc53fd, 0x0e5979d6,
+ 0x03bfc03a, 0xe381d57a, 0xdf91d8a4, 0x767b5207, 0xca0ac3c7, 0xebba298f,
+ 0x6c17b429, 0x8ee28e80, 0x1fd6af5a, 0xe5ca963a, 0xc0aa58e1, 0x7e368a5b,
+ 0x4e493882, 0x1c5271e1, 0xe2438416, 0x14ebf0a7, 0xae50993f, 0x8103bde0,
+ 0xa244af3e, 0x29a96a4f, 0xabe50925, 0x019cf899, 0x857f239f, 0x229ed3af,
+ 0xae42d9f2, 0x235ca067, 0xb972b6ff, 0x3bb79f0e, 0xf38ec4b5, 0x5c7dc6ae,
+ 0x69c6f411, 0xf5daceb1, 0xb3cbe112, 0x3a784ede, 0x4abbd6c3, 0x00cf2f81,
+ 0xa02fb81c, 0x498ae5d3, 0xdb8d7ac0, 0x04b36315, 0xfadd40f5, 0x756e7a18,
+ 0x73eddbff, 0xc2979fa1, 0x6b6cfef9, 0x3cf10999, 0x3f973d7b, 0xfdc77df5,
+ 0x4f28ec33, 0xa32e8645, 0xb467ee03, 0x3f43889d, 0x54c768b0, 0x6f61ca3b,
+ 0x70a86670, 0xf16fbb2e, 0x07e73b49, 0xf5aa6fcc, 0xbf4acf38, 0x78bff111,
+ 0x6dfe2319, 0x3a87fedf, 0x6db3e394, 0x87b45631, 0x78c67667, 0xbe77ff51,
+ 0x49d3e511, 0xe3788714, 0x319daf41, 0x7f224c74, 0xc56c8773, 0xc6f3d1f8,
+ 0x3ca14fe7, 0xa147b67a, 0xb716c7e7, 0xed0e7c3d, 0xd8db4d5e, 0xda7cfad3,
+ 0x954ffe87, 0xf765da87, 0xfed57ad3, 0x0a4dcbe7, 0x7ab3d1ea, 0xb71627ae,
+ 0xeffe4abe, 0xf9dd8be2, 0xb33f0f58, 0x50c36ff3, 0xdb7e79af, 0x99f50c3d,
+ 0x61eef5e7, 0x5af3df78, 0xbf247d4c, 0xf3c697c5, 0xccbdaa40, 0xe4d7a239,
+ 0x5d85a28b, 0x2e6869c8, 0x459d7dc7, 0x3039a787, 0x2fdeab9f, 0x7ed1d5ca,
+ 0x46f7a2fe, 0x3c87e7d9, 0x97d010d7, 0x87a1f5e3, 0x8654c547, 0x41aa65f2,
+ 0x555e37cd, 0xeaef079e, 0x75e48587, 0x19a73a02, 0xe80eadc6, 0x6adafef9,
+ 0x06f187c9, 0xcfe12ff8, 0xb9d53f91, 0x435beed0, 0xfc6b827e, 0xcfd8a1e0,
+ 0x5051ac75, 0xf6f698ad, 0x6697f10f, 0x28fe7404, 0x6de9a3e0, 0xf7f27e51,
+ 0xd413fa03, 0xecd47e17, 0xe6c69f73, 0x34f21148, 0x468cef79, 0xaf9e1e3d,
+ 0x8458bf81, 0xdeaff55b, 0xa3f9e34f, 0x0eab7a8c, 0x345667f7, 0xb5e22b30,
+ 0xfa675e47, 0x0a2f946d, 0x8128efcf, 0x4e7c2675, 0x22b3afe9, 0x8a5faabc,
+ 0x4116dc74, 0x72a6240f, 0xaf9544bf, 0xe88e8086, 0x352810d3, 0x563687f5,
+ 0xab36d7c8, 0x68f7be8e, 0x09ba9b68, 0x170d0bf3, 0x0c198aef, 0x723869ef,
+ 0x3defc33b, 0xa6a5ad3a, 0xe2ee7c5c, 0x063ba66d, 0xfc26f905, 0xb852c77d,
+ 0x0bfa0cde, 0x21dfed91, 0x59fecfa1, 0x8a40f076, 0xff3de44e, 0x1083b6ef,
+ 0x7852079f, 0xe7933e7c, 0x1e7c784f, 0xbd543f6e, 0x092bceac, 0xcbd4f73a,
+ 0x81cfc9a7, 0xb2f49a38, 0xb8d0aa94, 0x7629b68c, 0x4c8faf8a, 0x9e962bb3,
+ 0x3bd3f7f3, 0x3d41b674, 0x39fd57e7, 0xd7b9d78f, 0x938f7184, 0x4cf323ef,
+ 0xaddf6893, 0x5c79ffea, 0x9ee5f912, 0xc70f830a, 0xa60570a9, 0x1dec7cf1,
+ 0x2ccf834e, 0xd544fd05, 0xdf7cbc8f, 0xd57dd121, 0xc7fd54af, 0x77e78b80,
+ 0xf7e50da7, 0x17dc98b7, 0xf71f2ed0, 0xd17ae99b, 0x319d7e08, 0xab8c5ed7,
+ 0x6253baee, 0x5f8407a4, 0xb869f2a9, 0xadbe79df, 0xa3ee37df, 0x53f820df,
+ 0x30acb395, 0x58ed50f9, 0xc7970a5e, 0x85e3b43a, 0xaaffc768, 0xe7c3cff1,
+ 0x496e3b05, 0x3d18e7a5, 0xbd3df43f, 0xfebc522b, 0x0ca790ac, 0x3d817e95,
+ 0x266f0825, 0xd83ed00b, 0x7c6becde, 0xded7971a, 0xb909e7ee, 0xdf3c92b9,
+ 0x3fccf426, 0x52cb9e4b, 0xb5f877ff, 0x5ec3fd97, 0x2cfbc7be, 0x2a4264b5,
+ 0xae5a35e0, 0xfca0940f, 0x6221a7fd, 0xd85d3add, 0x3577886b, 0x699bd9f4,
+ 0xe47c61d4, 0x83f9e6a9, 0x6de504a6, 0xc80e638a, 0x317b3fb4, 0xc7e883c4,
+ 0x4090ba2d, 0xcbfa0d6d, 0xf17cced0, 0x6623d530, 0x6fe16b56, 0x3e2e9cc2,
+ 0x87c724bf, 0x362cf3fe, 0xb34cf28a, 0xb8ac12da, 0xa929b9df, 0x95ca1f65,
+ 0x6cac9377, 0x50bf1d0a, 0x79e26f1d, 0xb46965b8, 0xf98592bf, 0xc3eab303,
+ 0x7fad7efd, 0x1bc8b370, 0xbc27e6f5, 0x7ae66ede, 0x724cbf65, 0xa6f9875e,
+ 0xb633191b, 0x59e0bd71, 0x7524f3c6, 0x7be82b6d, 0xff715aac, 0xf2807d33,
+ 0x835f5450, 0x1edba7a1, 0x6479464f, 0xa93d6d4e, 0x48f785f6, 0x95d7865f,
+ 0x5eb8db6c, 0xa2c8d4f2, 0xc24c348e, 0x93c42d7e, 0x2a5fe829, 0x3bc464ca,
+ 0x57d9a5c0, 0xcf05faa6, 0xf9d2ba8b, 0x1c531ffd, 0x2f47733a, 0x71a6a475,
+ 0xf6248ebc, 0x23acf46f, 0xae9bdbed, 0x548eb95c, 0x80d87ad7, 0xea95c5f1,
+ 0x5ea4cf49, 0xde5127ae, 0xf3cf5b31, 0x926dd9bb, 0xd955f315, 0xc3dd7c6d,
+ 0x7f934757, 0x958fe63d, 0x2a07d476, 0xe14ece9d, 0xe1fb3df8, 0x75b42597,
+ 0xab7a8fe0, 0xfaf5d619, 0x4ddf4b87, 0xa4c57de7, 0x634b73e0, 0x3fe9bbe8,
+ 0xf8831bde, 0xa45a1d7d, 0xf5476bcf, 0xc193f391, 0xa92bf57c, 0xf9167794,
+ 0xc3d83d6a, 0x275e60d8, 0x855bb9fc, 0x70826bbe, 0x3b9af285, 0x29bfdd78,
+ 0xfa8e3dcd, 0x36cbeb3f, 0xa4e89f91, 0xc0abf47c, 0x1a3798d7, 0xbac58b08,
+ 0x59a32ff4, 0x9a91d603, 0x926fdc92, 0xa74cfd1c, 0xf3c11ca0, 0x6ef27f54,
+ 0x623ec855, 0x3ceb0bea, 0x858046f9, 0x7df03bf6, 0x3a083713, 0x8b3c41a6,
+ 0x33402571, 0x03d0eb0d, 0x3f27bd45, 0xfe71e99a, 0x35ee0c47, 0xa97d63d7,
+ 0x4158ef5d, 0x4fb0e042, 0x7759ed89, 0x5ebc9c92, 0xd49fd6ae, 0xf56f79ba,
+ 0x93df0927, 0xea8ff9cf, 0x9cff624d, 0x7762675a, 0xb5f8a8ba, 0x619eb8aa,
+ 0x832c3afc, 0xd2faeb5d, 0xd42392df, 0x4c294c7f, 0x7ada67f8, 0x57bc9ae3,
+ 0xdeff4f88, 0xa96de33a, 0x1efb1fec, 0x0adc07a6, 0x0c322eff, 0xe709a1ee,
+ 0xfaee2993, 0x91c4bfef, 0x26eb6d9d, 0x15d9d87b, 0x7f9402c5, 0xf779e0ec,
+ 0x503dfe36, 0x496fc427, 0x7e767621, 0x57779f0a, 0xfff1195b, 0x18a8c0b6,
+ 0x0a58ff1c, 0x23eac7a7, 0xbfa2a6d3, 0x69e80def, 0x3c630ebf, 0xd016db1e,
+ 0x72dfa117, 0x9a92e90d, 0xd12e891a, 0xcb853edc, 0x7f6121d1, 0xba72a50f,
+ 0xe3c87d95, 0x5e52cf30, 0xbd0ab15f, 0x75e7a9e0, 0xc9997df5, 0x4f4f9a92,
+ 0xd97f5489, 0x637645d1, 0xf68942d6, 0xfadb7ed5, 0x916913cb, 0x5b33f1eb,
+ 0xbfae444f, 0xfd218f94, 0x3b3e5bd9, 0x4b7d8f3c, 0x0f63c89a, 0x5fec79e6,
+ 0xbd695aa5, 0x2521fab6, 0xfaeab2c8, 0xbe1d21af, 0x87408b48, 0x5c7f386b,
+ 0xdf5b77fa, 0x7d5230fd, 0x6fce1af7, 0xe16efe4b, 0xa7e92257, 0xf3bf386b,
+ 0xfd7f9e3b, 0x8aff3c77, 0x77ff18ef, 0xff9844a5, 0x01fdd5ff, 0xf0fff5e1,
+ 0xfbe102fd, 0xcc0ea200, 0x87bde2f7, 0x7e5db5a5, 0xdb714d68, 0x07a04ba7,
+ 0x982f09f5, 0x184e8ed0, 0xab61ebc1, 0x1b7c9947, 0x01bee0a5, 0x832c5f15,
+ 0x41d611c7, 0xc076bce7, 0x30339673, 0xb2f98eca, 0xe0e28c11, 0x8baf334e,
+ 0x6d35bd31, 0xb7c3ed0a, 0x7e0edda6, 0xdf2f5349, 0x174e6d33, 0x762f6171,
+ 0xc9466464, 0xacefa867, 0xd5a5fb61, 0x6aea29d6, 0x0fbe56d6, 0xb495e997,
+ 0x4abde9db, 0xf143fa1a, 0x38f5f87b, 0x246e733f, 0xdb9c94b8, 0x72541e29,
+ 0x4427be10, 0x6e36d7fd, 0xa5e60e40, 0x6217e06d, 0xac71f05d, 0x6b3c520f,
+ 0xfbea71a5, 0xbf87d87e, 0x930309ef, 0xbdeb9eb0, 0x6273ef9e, 0x5d4d6a96,
+ 0x7fc1a0ef, 0x7544ae72, 0x8c0fb93d, 0x0ff3a43f, 0x30473e7a, 0xd077e031,
+ 0x1bd52b36, 0x1ff11adf, 0x26bbfc79, 0xcfbbe75e, 0xc6ec87ca, 0xb8e019b8,
+ 0xf121676f, 0x235dccef, 0xf8c0a83e, 0x2f3f3fa3, 0x295c47a4, 0x454705f2,
+ 0x17cd43be, 0x63adf5a8, 0x1c724f22, 0x76d02ff3, 0x5a043e60, 0x5aee8fa5,
+ 0x4fa527db, 0x84f2fd04, 0xde43f3c4, 0x543f3c43, 0x0bf47468, 0xb8394fdd,
+ 0xb9abe70f, 0x50bf5e7e, 0xc59b3df3, 0x207f0a7a, 0x2fc0a3fb, 0x6c1c6c2d,
+ 0xd85f3b44, 0x6d8d1998, 0xc3a7d3be, 0xca8cef52, 0x7e953aad, 0xb868f891,
+ 0xfdeae758, 0x7bdf545d, 0xffeeac35, 0x3f7c3ec3, 0xc7e0b743, 0xd461f61f,
+ 0xbf572fbf, 0xf8c7dd0a, 0x52395691, 0xc416695d, 0xdce708c5, 0x8ab70e26,
+ 0xa57e59ef, 0x6273df0c, 0xb623576f, 0x6539d505, 0x39af7794, 0x9bfe88d7,
+ 0xbef762e7, 0x665f295b, 0x989e3054, 0xbbcda1dd, 0xfe7832d9, 0x7f8955fd,
+ 0xab1de9af, 0x70b8f8a7, 0xc7f89eac, 0xf14ccb36, 0x64c0cdab, 0x70a7f60b,
+ 0x3ca0a8bf, 0x6cfb0cb1, 0x83f9025a, 0x8495fb05, 0x798283f9, 0xa5d8db30,
+ 0x2ba78849, 0x7cd559d5, 0x739316da, 0xeff3d23a, 0x1ed6b3ad, 0x4dfb423c,
+ 0x78a975d5, 0xbda5eb51, 0x7dd559d5, 0x2ff29e0f, 0x3c34fb35, 0x9831aefa,
+ 0x79dc2c7f, 0x5ff628c2, 0x8273535a, 0x1dc2d875, 0xaafea8e7, 0xf53d5bd6,
+ 0x86afc8e7, 0x929ce8e7, 0xfd79cb6d, 0x81c03b75, 0xdbac2b6d, 0x06fcf009,
+ 0x1b6d8dd6, 0xbfaf1bac, 0x5a8f3cb1, 0xb50772ff, 0x531796bb, 0x93ec085b,
+ 0xedbac366, 0x2edbaa39, 0xdf63d3ef, 0x36f5d524, 0x2895aecb, 0x3f7521ef,
+ 0xfdd787ea, 0xaf9e68e4, 0xd037ecf1, 0x839e0c77, 0x25dfd226, 0x31b3736d,
+ 0xb0eaf83e, 0xaee11b3b, 0x085bbac3, 0x3a759c5f, 0xc66e78cc, 0x8cc39759,
+ 0xf6c2b6f5, 0x0fdc46d3, 0x180fa753, 0x90061f31, 0x4596e3a7, 0x7c73b6cf,
+ 0x895b6fdf, 0xc57bf119, 0xffeb58fa, 0x3dfd8faf, 0xa0acb1f5, 0x291e927c,
+ 0x1b9ce970, 0x34efddb1, 0x13d10fcf, 0x9ebc5dab, 0x5f7fbab2, 0xae75c392,
+ 0x219509be, 0xf39435f3, 0x6c6d85fc, 0xf5e8737f, 0x1e061925, 0x4239e047,
+ 0x41ffde11, 0x8e35dd1f, 0xf41fdd5f, 0x9d57e089, 0xefa2643d, 0x2c77da49,
+ 0xc418eec8, 0x1f343f05, 0x32bcbab7, 0xf7cfbf1b, 0xb9628d1e, 0xc9a75f3c,
+ 0xbab0b1c7, 0xb9796f5c, 0xa73ae599, 0x750bf699, 0x0edda165, 0x7d319fcf,
+ 0xebb71657, 0x9e7e74ce, 0x159d3783, 0xb9f51eb3, 0x7bdf33df, 0x8cfc61fd,
+ 0x0bd91d72, 0x50574eb5, 0x81cb67ae, 0x19960b3f, 0x2b9f547c, 0xfba09fd7,
+ 0xb06c6e22, 0x9f23a416, 0xb4683f1f, 0x3c2d5e62, 0x7f28e63f, 0x3c2fa9a1,
+ 0x1c91a8ef, 0xd52bacb8, 0xe07dd4f1, 0x47db5ab3, 0x086dbe63, 0x051a6e6b,
+ 0xafe90fcf, 0xe9fee2b3, 0xbe3cf59e, 0xf840bbff, 0x3679e139, 0x4bf433e4,
+ 0x71f0f3c2, 0xe20f9ce9, 0x9cfdb9d2, 0x0a2db480, 0x173ea3ce, 0xd2f33fce,
+ 0xf0bf75b5, 0xfdc553fb, 0xd582f286, 0x13be91fd, 0x49ed0c74, 0xa9a97943,
+ 0x397cc87f, 0xdb7f7ce9, 0x4c1f5813, 0xf20fad0c, 0x5d78603a, 0x8573d550,
+ 0x831d7fed, 0xfa075ef8, 0x2798ed1a, 0x0a0fd795, 0x8fd928df, 0xa708237a,
+ 0x7a953fd8, 0x04ec7bf9, 0x70c5d7c6, 0xa7779cff, 0x82b9f944, 0x8aee5f09,
+ 0x81733e81, 0x76bd43dd, 0x0b2affb0, 0xfa09a3ea, 0xc7aefc22, 0xd72e92e3,
+ 0x349eb099, 0x71eaedf5, 0xe1419df8, 0x230e431d, 0x30a8ee5d, 0xd540fed0,
+ 0x7b7d4dee, 0x7f7e18fa, 0xbc68cae3, 0xcc39279f, 0x2f2f5e0a, 0xb7e3ebc5,
+ 0xce9331f8, 0xa0742226, 0x4f0703cf, 0xb66e51ea, 0x1825dc98, 0x114e173f,
+ 0x6e0aa675, 0x9b68efa7, 0xe7e46062, 0xeee6ed69, 0x1f28afcc, 0x4856ddd4,
+ 0xee3b23f5, 0xb414187f, 0xc13b8537, 0x3b5ec58e, 0xdd2f363b, 0x11bcf84a,
+ 0x63c218ec, 0xf4ebc29b, 0x11cff4e1, 0x2ecdeff4, 0xd187a6f5, 0x2b39e0fe,
+ 0x6a529f28, 0x60ae3b4f, 0xfa3867de, 0xc21e12eb, 0x35ff2bd2, 0xd096fd0b,
+ 0x4eb73f8b, 0xfbaf7bf0, 0x39ff5aa7, 0xf4e6a675, 0x63751dff, 0xeb52fe35,
+ 0x76bc6a4d, 0xda81f046, 0x3fed159e, 0x1a037dfc, 0x37df88d7, 0xdf7f22d8,
+ 0xce85bb30, 0x6fbf5129, 0x25646bd8, 0x3f71135b, 0xc9def8ad, 0xa4fc8537,
+ 0xbeff4fbd, 0xf88917f1, 0x278493bd, 0x3c3d806b, 0x3d5e764c, 0xedaeaeaf,
+ 0x6d6f9e73, 0x6bc3fbe1, 0xfb9f235b, 0x77da0372, 0x2728ef78, 0x2b51bd23,
+ 0xd98edbf6, 0x9744ea26, 0xebf796f3, 0x1e96f343, 0xeea49025, 0xbc51f5e3,
+ 0xf663cda7, 0x53acb796, 0x96afcfbf, 0xae1f681c, 0x59b70fb4, 0x35edd7ec,
+ 0xe6fce98f, 0x79e1b97d, 0xb5d3f7cc, 0x69939c75, 0x74ff5a56, 0x36e744b7,
+ 0x1aae7499, 0x86ffb7da, 0xcfb48d64, 0x87610bfb, 0xc83a8bc6, 0x3f9c8dcf,
+ 0x44937e7e, 0x77e0dfdf, 0x9ff74878, 0xc3bfc1bf, 0xff0179f9, 0x7bad470e,
+ 0x5cd7dfa8, 0xd07bac1f, 0x77ea77f7, 0x3677ea39, 0x539d77ea, 0xb9d347d6,
+ 0x5a188fc5, 0xebdfb952, 0x3a7cbe25, 0xe8fdd19d, 0x491f5628, 0x97a68f5e,
+ 0x845e9d3c, 0xdc79aee3, 0x423d297b, 0xe30c3bdc, 0x218f7848, 0x3c85e203,
+ 0x305e2916, 0xe2691465, 0xc787ea05, 0xeeaad70b, 0xcfc0a4f1, 0x6df75c35,
+ 0x6bc6fc91, 0xdfebff38, 0x45affcf1, 0x732adba2, 0x1f17f3e4, 0xbe8490cc,
+ 0xce179ed7, 0xc92f7c7a, 0xa4937aed, 0xd533707c, 0x4f540dd3, 0x536af557,
+ 0xbc7f9f2c, 0x6da9a7c8, 0x0c9b6895, 0x4b65f391, 0x6467fdc4, 0x93e438e7,
+ 0xf36a2f81, 0xb45b8397, 0x5b1bcbf9, 0x0c88e7b5, 0x09cf6bf1, 0x3dafdc29,
+ 0xa028a63f, 0xf8663f3d, 0x31f9ed51, 0xe7b43a23, 0x99fcdcc7, 0x5b98fcf6,
+ 0xcbf9b4ba, 0x1edc2f5b, 0x8fa71df6, 0x9c09479f, 0x995cfa1b, 0xb9d85e69,
+ 0x73b0ba35, 0xcec3a26b, 0x1f3b09ad, 0xe39bcc45, 0x7e7613ed, 0x367d768d,
+ 0xba0dc7ac, 0xefdc7afa, 0x1ea228fa, 0xcf8ccfd7, 0xdfde513d, 0xfa9b7e8c,
+ 0x097ff53d, 0xe1913b3e, 0x71f4815e, 0x875b1caf, 0x22b1d57c, 0x2ef30b2a,
+ 0x726995ee, 0xfb83f022, 0xa7be8951, 0x46995d2f, 0x35e67bfb, 0xa93f210c,
+ 0x4fc93980, 0x1167659a, 0x9cd879cf, 0x3decf5c1, 0x8c6606f5, 0x462997c7,
+ 0x33d0a81d, 0xc35b124d, 0x22658ded, 0xe33561f0, 0xfabb587c, 0xbdd51c70,
+ 0xc859dd85, 0xebaac151, 0x0e79d017, 0xa8bde7e1, 0xc623c676, 0x6316b0d5,
+ 0x68bbcc1a, 0x47c93b6d, 0x1e3079f8, 0xea1cf6b6, 0xb096dae1, 0x7db7f5eb,
+ 0x1ff7f8ca, 0x3c8bf446, 0x2ffbdaad, 0x99ba8864, 0x7e503983, 0x9ac7f7dc,
+ 0x152ccfd0, 0x56bb99f8, 0x709d62b2, 0xd27b435e, 0xb79fd05d, 0x4bb8a65f,
+ 0x71eb0fc5, 0x3a20cf4e, 0xfefcfd57, 0xcfa3f25c, 0x8e0a4a2b, 0xb8f1c773,
+ 0x87bbd241, 0x7659f5e3, 0xe73c70f7, 0x58c3ebac, 0x9d87f6fc, 0xdf9320b8,
+ 0x3e50be00, 0x96566ff9, 0x9def9a1f, 0x6326b06b, 0xeecbc5be, 0x5378a54d,
+ 0x7e2abfc4, 0x6788263c, 0xf10fb0e3, 0x749f5f2a, 0x91fa2249, 0xff02eb69,
+ 0x7e03df08, 0x26b3c510, 0x7e815a66, 0x39a569d0, 0xd7605d19, 0x2ff20643,
+ 0x4092d9ee, 0x0d3dc5fe, 0x1f3c4665, 0x096d9ee1, 0x79969fb4, 0xbe30479d,
+ 0xa279e955, 0x2a5f70a1, 0x4b4f7bcc, 0xd2d6438e, 0xd137e4f1, 0x09d35171,
+ 0x7b277e95, 0x48c9dfa1, 0x69ba03f4, 0x4321ffae, 0x6e8209f8, 0x7d3b41ec,
+ 0x64b157e7, 0xffe62e6f, 0xe99bd7ce, 0xc67a2bf7, 0x37ae5e05, 0xc4d26f2b,
+ 0x2e7de53f, 0xbe7475c7, 0x22daf777, 0xdd385fa2, 0xde67ffca, 0x8afefc70,
+ 0xa1963efd, 0x1fab31ff, 0xc63b739b, 0xb79712c9, 0x96c6ab59, 0xa5f3bfa3,
+ 0x8b6fcfd0, 0xc630e938, 0xbfd7e049, 0xf412718b, 0xd27113df, 0x41271807,
+ 0x49c621fb, 0xe7149ed0, 0x0772aa05, 0xfb7c408c, 0xafb790b5, 0x6378d433,
+ 0xd7e62a69, 0xdde7ffca, 0x5f159d22, 0xa349e3f5, 0xec9b1933, 0xd3d7fad4,
+ 0xebfd69a7, 0x4c75830e, 0xd581da2a, 0x8f705ebc, 0x78cd66eb, 0x988c57a6,
+ 0x857960f7, 0x8f64ebc1, 0x3de62314, 0x6bb04c66, 0x94d9dfc6, 0x32dbe9ae,
+ 0x94f75a15, 0xeb9a7ef2, 0xd40c5777, 0x005ee7f4, 0x5df90cc7, 0x59f92629,
+ 0xc626e22a, 0xac5d398a, 0xf597ec7c, 0x001e53c3, 0x683cbf78, 0xf4e1fba0,
+ 0xb95ae950, 0xee7ca65e, 0xf312f5bc, 0x9b278802, 0x7d7c91e7, 0xce96347e,
+ 0x52dc6991, 0xf43156f8, 0xd0316c4f, 0x0d13b2fe, 0x7cf147f6, 0x925b13eb,
+ 0x3dbbf0e2, 0xfccca377, 0xa4ad77a4, 0xcb79d577, 0xefd0561a, 0x45f5cc26,
+ 0xcc0f5039, 0x567de3dd, 0x4ddfa3ed, 0x4e50665b, 0xbf3ec88e, 0x1273f444,
+ 0x299b377e, 0x8199fe4f, 0x92a7f179, 0xb87075e6, 0x0358933e, 0x8f9b4ff6,
+ 0xe000780d, 0xb9b13338, 0x957e874a, 0xf489307c, 0x43322be7, 0x6258adbe,
+ 0x1787f3a0, 0xc46f27be, 0xd20a933e, 0xfa65bd39, 0x39b60f7d, 0x5d67e68a,
+ 0x6e3021c0, 0x9ea22fe9, 0x5ef2235f, 0x60f5ffd4, 0x9fc11adf, 0x259f47c8,
+ 0x01026730, 0x7f0ff3cb, 0x75449c3a, 0x7d3e209f, 0xffeeb8f9, 0x64c6bbd0,
+ 0x54fefd02, 0xfd27cbe5, 0xc91260f6, 0x4fde3855, 0xf2feb91a, 0x41481ca2,
+ 0x339419bd, 0x3cd5fdfe, 0x41d92383, 0x1a686b7a, 0x6b93adea, 0x6467940d,
+ 0xaf1c677a, 0x7c42bdcb, 0xa4e7beac, 0xf083195e, 0xa1ca6c9d, 0x59ef0cef,
+ 0x43fd932b, 0x7de3e3fe, 0x971fff9c, 0x7bbf18dd, 0xc637249b, 0x737ce1ef,
+ 0xf4e192df, 0x11b3047b, 0xea7a2327, 0xbc69b381, 0x17f6a10e, 0x07bfe4ed,
+ 0xe87686c0, 0x5d0e0da7, 0x9f7f0347, 0x4e7358bb, 0xdfdf4d79, 0x9c23c71d,
+ 0x17efefce, 0x9ce9df8f, 0x9f13223e, 0x3cdbee9d, 0xf9e8152c, 0xb0d76e85,
+ 0xf9ffa007, 0x7a27ef44, 0xfbb46fa4, 0x62ebc43e, 0xfc2cdadd, 0xedb3ba6e,
+ 0x866f47e3, 0xb2f4fee7, 0xbe6241c1, 0xc7f4892c, 0xb30bcda2, 0x21bbe9bf,
+ 0x787dfcc6, 0x2699d1de, 0x2b173e01, 0x9f30632d, 0x84b99f30, 0x51f8e23d,
+ 0x86bcf0b6, 0x73cf1d75, 0xbb145c7c, 0x79b4e306, 0x8f8c7961, 0x8d83f7c5,
+ 0x6fc69299, 0xf5c99838, 0xe71d3cd7, 0x38b7886f, 0xb1a631bf, 0x5edeaa03,
+ 0x220fbf8c, 0xaa80ed07, 0x33586bb7, 0xb3fd6b9d, 0xff34becc, 0xbf47c942,
+ 0x27875223, 0x2af8c354, 0x6b638f2b, 0x51f28c5e, 0xe580aa9c, 0x8e0ff10b,
+ 0xe7813ea1, 0x7e5f1916, 0x0177d90a, 0x8675f00b, 0xc193fb8d, 0xe9c81557,
+ 0xacaa7f69, 0x346c1b1b, 0xfb81c1bf, 0x79081719, 0x7c966dad, 0x25075e7e,
+ 0xcc5f3a3b, 0xd1d85f33, 0xc3d4fb70, 0xa3d9852e, 0x977661f9, 0x2ced6b35,
+ 0x79e74bc0, 0xc386f0ab, 0x25898ae9, 0xe66a2c3c, 0xdcab3efb, 0x08937dbe,
+ 0x1401c96e, 0x02cf01ed, 0x80951ae6, 0xc79178eb, 0x85f0e1e9, 0xbc07abaf,
+ 0x70e19d62, 0xd1ce3957, 0x5b35e5f7, 0xf857c224, 0x847a543a, 0x5d2a71fb,
+ 0xbf1cbcaa, 0xd1126d55, 0xff65d4f3, 0x50fed190, 0x0b586f95, 0x79e42ffc,
+ 0x5d608f95, 0x2dbf5093, 0x38fa0758, 0x2d3f27a7, 0xc8712d62, 0xdfcc7537,
+ 0xd3f72588, 0x473b96fe, 0x4e79e0e4, 0xa9dce987, 0x573f9b0a, 0xeca88097,
+ 0x96fcb47c, 0xe3879f20, 0xbdf44afb, 0x5131fc5a, 0x00e7a067, 0x905ff35f,
+ 0x909ffbe9, 0xf63e2271, 0x7b557c92, 0x3fac46bd, 0xb9f9eb57, 0xd3825772,
+ 0xcbbfe7a3, 0x05784574, 0xdc35af3e, 0x7f5a59d1, 0xe577e839, 0x5bd247c6,
+ 0x098f3aea, 0x7b45733d, 0xc5dc77af, 0x4927dec8, 0x4de9af98, 0x3b09577f,
+ 0x3eed1f3f, 0x7fac9fb4, 0x3c6bce95, 0x3a55eeb5, 0xf2f8d59f, 0xf0b7da7c,
+ 0x8f79fac9, 0x7c4fefe2, 0xd91e65b2, 0xab4f05f9, 0x0c6dde76, 0xd6ca1ff5,
+ 0x5fee7dcf, 0x345f6f90, 0x6ab95d53, 0x41c45b8f, 0x9c6157a0, 0x51eb9eb2,
+ 0xd5eb8eb6, 0x070f6805, 0x0ebc3d91, 0xe55fddc7, 0x3ff90ebe, 0xc9d93ae4,
+ 0x7fb9e7fb, 0xbde613b5, 0x8718a5ff, 0xf56c9697, 0xd5b4bcf3, 0xf6b0f68f,
+ 0xd38e0fde, 0x07c94bef, 0x6a81fbdf, 0x139e19ff, 0x42ce2ee5, 0xbf761339,
+ 0x6598de56, 0xec223b45, 0xdf1b3fc4, 0xc9be20f7, 0xfef8e2bf, 0xf9e389a8,
+ 0xef1cb5e3, 0x51fa5b8d, 0x5351fafc, 0x3eabf23f, 0xf84b92da, 0xf8035cae,
+ 0xd15abf26, 0x804d55fa, 0x101f8c6f, 0x3dd700df, 0x6f81147b, 0x1377c707,
+ 0xcb5b33c7, 0x781ecadb, 0xebf9d2f5, 0x947bfff7, 0xcf84fd03, 0x9ff27ecc,
+ 0xd32adb3e, 0xdfaa6959, 0x7f3dfaa5, 0xa2cfcd66, 0x7be2a67f, 0x3e4080e1,
+ 0xc78a97ea, 0x7887177f, 0x2795b85f, 0x9be07a4f, 0xbce85339, 0xbfefcbfd,
+ 0xce2d27ec, 0xbe93f50a, 0x98ea5d25, 0xd72bf68b, 0xf96639e1, 0xd5a2fb21,
+ 0xdf0b3fdf, 0x7cf0ad07, 0x98731465, 0x464f084c, 0xb9b8eff8, 0xfe8bee19,
+ 0xecdcf72a, 0xbb8e497b, 0x31c7bf34, 0x780df989, 0x916b019e, 0xed4bbf68,
+ 0x257125d2, 0xad2dcf0c, 0x67363827, 0x69df3b71, 0x3f22caee, 0xc714676d,
+ 0x359ba8fb, 0x07a4d1f1, 0x423ff11d, 0x3f20e03f, 0xd79278df, 0x49cef941,
+ 0xab5243c5, 0xff3ae842, 0xb8d73f02, 0x9cc482ea, 0xc09dfc76, 0x622fb4b1,
+ 0xda14f37e, 0x6d055007, 0x5ef8e859, 0x9cdbcfbe, 0xc7a2f3c5, 0x78054d71,
+ 0x1df8939e, 0x1a9e713c, 0x370171d5, 0x3a2ecdc7, 0x9278ef6f, 0xc8cfc1c9,
+ 0x07dfa78b, 0xc1e85bb8, 0xb47d9699, 0xf1e61c8f, 0x7b9e1b32, 0x0501aeff,
+ 0xf1d4c2ac, 0x73c68632, 0xbefe3f52, 0xff5b8749, 0xdf22ac1b, 0xbd92edbb,
+ 0x3a413c27, 0xf381cf6a, 0x8fce4744, 0xfdc59abc, 0xa4e9c929, 0xcc14443a,
+ 0xdfef0d1d, 0xebf0a59e, 0xdb3bff62, 0xed8cf400, 0x7a9c9e79, 0x39f9799d,
+ 0xf0a535b2, 0x67189bef, 0xb21bd424, 0x31afd34e, 0x9e87fbf2, 0x5d793d9d,
+ 0x30ef6306, 0xf43f7ac0, 0xff8f1953, 0x70fbc6e7, 0x3c64d7df, 0xad86ca6f,
+ 0x76eaf89e, 0x78eaf33d, 0x7ac164db, 0x6a673888, 0x1ddfc092, 0x0f1fccc5,
+ 0xa03fefbc, 0x2ef16f3d, 0x1d7fcebf, 0x9e3275e0, 0xe78f9767, 0x2b0629d6,
+ 0x2e55c7bc, 0x52bc6015, 0xc1dbf2b3, 0xc2ecf1db, 0x4246ebc9, 0x70e3a75f,
+ 0x29e780fe, 0x1efe6266, 0xcf5b30f0, 0x9c05c8f6, 0x8f1788de, 0x207da14d,
+ 0xda244b5d, 0xede6a2af, 0x090f7a55, 0x8e89ede6, 0x307c0533, 0x3e1c534f,
+ 0xaf4c8c6f, 0xb8d4b22f, 0xede285ba, 0x173e42c5, 0x45b972ab, 0x6c96972b,
+ 0x8ff44741, 0x45336f01, 0xf9a4eb0b, 0xd47bc46b, 0xd9cdd773, 0x36737e7c,
+ 0xf2ffe38f, 0x598fbe77, 0xaa8ef9f8, 0xf146d67c, 0x4ff7d5f9, 0xb6546d16,
+ 0xe155e68d, 0x7fd7cf09, 0xf91561ba, 0x677fd549, 0xdf443ebe, 0x324c5d50,
+ 0xea225576, 0x4999efa5, 0x5b1a66ee, 0x3d2deb72, 0x15e7a9c7, 0x8180b056,
+ 0xbe440fd7, 0xd1a3d84c, 0xbfce85b2, 0xeff890ac, 0xc4967674, 0xe720757a,
+ 0xbf7cccc7, 0x1ff079e7, 0xc0153df1, 0xef31f817, 0x27fbf8ac, 0x11583fa1,
+ 0x7b63d467, 0x73cfcccc, 0xb102c39e, 0xfd413939, 0xd32258db, 0xfbcc8739,
+ 0xafac64f4, 0x213ac2ad, 0xcce63fef, 0xe894aca0, 0xea36f73f, 0x811769a5,
+ 0x9befa80f, 0xa93884ec, 0xcfb8af73, 0x9df3d236, 0xf67e090f, 0x27fde26e,
+ 0x279bfbd5, 0xab9df3e3, 0xe4bffbd5, 0xf3a89ffd, 0x61e3fe8b, 0xdd8457f7,
+ 0xdfef19ff, 0x272fdcf4, 0x2d8fd17b, 0x715dace5, 0xcfbf4493, 0x1bd423f1,
+ 0x562b0fa0, 0x15cf09fa, 0x2dbc5dba, 0xd0dd7e65, 0xcaab8f2b, 0xed08fd76,
+ 0x327b1c95, 0x92f5ed16, 0x67f5271c, 0x6747ba66, 0x8a68bb43, 0xbac235e4,
+ 0xd91f11d9, 0xe8bd498f, 0xbd091fe5, 0xf9f0a55c, 0x3cc37c54, 0xfe8bb293,
+ 0x9cfe79fe, 0xbb9e63dd, 0x5d9e06ae, 0x66914f08, 0xc0d5f71e, 0x768e5d73,
+ 0xda1fd51e, 0x23f9d7d3, 0x2edc2b84, 0x23b1fe2e, 0xec53f31e, 0xe29df12d,
+ 0x42ac96ca, 0x2ff17f98, 0xa1556477, 0x82fc25ff, 0x768bb43a, 0xdb83173c,
+ 0x3fdbcfc5, 0xb6e5fbe4, 0x60c71bb5, 0x50da001d, 0x0bd358bb, 0xb56cde9c,
+ 0xaf38ffce, 0xb4f2fe1b, 0x58b9e91e, 0xd3c9f2d7, 0x926fe768, 0x59777e22,
+ 0xde3b9e2d, 0x3525efcb, 0xe03f7366, 0x87cefea5, 0xb20b6f10, 0xb291e919,
+ 0x79cf9155, 0xb1e85b7e, 0xe6ff610a, 0x29358b0d, 0x23a2e780, 0x0fb855ee,
+ 0x4e436aab, 0x978de601, 0x963e9667, 0xd6f98dfd, 0x6d6f9e2e, 0x0ad6f9e3,
+ 0x2829605b, 0xf666f671, 0x32998f5b, 0xa9fe0fc1, 0xb220672a, 0x94796cf0,
+ 0x79353fda, 0x0f9e48d4, 0xcfcbfec3, 0xe50c7f1d, 0x83c23f66, 0x83e1f5f9,
+ 0x743f51a3, 0xace8c4e4, 0x25fe47a0, 0x089bee63, 0xb7e1acc7, 0x929a7ed0,
+ 0x7301d8a8, 0xf89efe79, 0x5c325fe2, 0x38dd709b, 0x6e24f31e, 0x2ee93fa3,
+ 0x4dfb8758, 0xbab3f699, 0x91dc63f3, 0x2efff3ea, 0xb666f0f0, 0x3afdda95,
+ 0x0820b380, 0xf07efa87, 0x600697f7, 0xd32b93be, 0x50f7e086, 0x0e4a3227,
+ 0xdf051764, 0xbdc3227f, 0xdf53e11d, 0x06c7527f, 0x6df1c860, 0xd05578e1,
+ 0x0dd200f7, 0xe048d75a, 0xefb890b7, 0x9a3151f6, 0x7609b4fe, 0xe3cd0ce6,
+ 0xf4d74b4e, 0xd3f457a7, 0x72bbbf8c, 0xc4fee6a0, 0xfad0c0a8, 0x77b7bf10,
+ 0xf7cbc97f, 0x46c6c4ef, 0x3fbdfee3, 0x7df9fdb6, 0xcee9fdfc, 0xfa076417,
+ 0x6e770bb6, 0x168f1f7a, 0xb5f40f3e, 0xa1527e53, 0xf69fda7c, 0x839f8ccb,
+ 0xd687d4e1, 0xc0b0ce91, 0x60a52353, 0xeb6dfb7c, 0x7bad8b47, 0xae0577e8,
+ 0xf3e8dd55, 0x287f516c, 0x1f680560, 0x47bfd7cf, 0x0b3abd79, 0x1d99e75f,
+ 0x3c5b9cfc, 0xf012fae7, 0x20f86dfd, 0x40178bfa, 0x97fc83f1, 0x7aa09eb5,
+ 0xae6c9adb, 0x9632ebaf, 0xf64fd1e8, 0x65f68b40, 0x78ade80c, 0x3b409be0,
+ 0xf70dbc1b, 0x72c4e5bd, 0x54c2fdff, 0x8fef9bca, 0xfd9ff9e6, 0xfbf409c9,
+ 0xc69b8bc7, 0x0bbaf5d2, 0xdbff3431, 0xb5f68072, 0xa8935f79, 0x7d31314e,
+ 0xcf5c4ad6, 0xdf4401ff, 0x80006da0, 0x00008000, 0x00088b1f, 0x00000000,
+ 0x7dcdff00, 0xd554780b, 0x399ef0b5, 0x67091e67, 0x99212726, 0xe4c21024,
+ 0x4e010249, 0xaaf08042, 0x9e180903, 0x6831004e, 0x0cfde1d0, 0xaf4a8809,
+ 0x04819bf4, 0xa86c1808, 0x3bd15014, 0x6ad480a4, 0xa6a3ea6f, 0xd004c7d6,
+ 0xa0d2941b, 0xdef6b7fe, 0x22c01b5b, 0xda046a28, 0xfad2de9f, 0x3ef6b5af,
+ 0x82499cc9, 0xbf7b7b72, 0xdbe3ef9f, 0xb3ef6759, 0xd7bdeb1f, 0x6b4cfb5e,
+ 0x7eef2074, 0xff99b185, 0x1b297b72, 0x97dad8c6, 0x1e609e4c, 0x857bd2c0,
+ 0xd35ca0eb, 0xbeb19530, 0x5356b308, 0xd731631c, 0x046c61ef, 0x2c018cc1,
+ 0x64ec728d, 0x435a5031, 0xc3c64fd9, 0x3b43ab33, 0xeaac66ec, 0x37bd147a,
+ 0x3011d8bd, 0xdbbc7d43, 0xc648d8c4, 0xe953ed2c, 0xcbd7c9fd, 0xfc6bfea8,
+ 0xfd631b77, 0xaf54e9dc, 0x438496c3, 0xdb0522f2, 0xb4fda89b, 0xaca843eb,
+ 0xca873ebc, 0x147e7277, 0x84fac3ef, 0x17fa536b, 0x526f1c02, 0x64ac4a71,
+ 0x628d999c, 0xa33b7eec, 0x47ab577f, 0xaba530c7, 0x72d2c8df, 0xe81e625d,
+ 0x44dd76cf, 0x8f74c0e5, 0x6c604ee6, 0xd976a6d6, 0xec51eb8e, 0x8034e1ea,
+ 0xcbddf28b, 0x93debaf2, 0xbab7cd8e, 0x7bfbc287, 0xd03d58ce, 0xe2ca0dbf,
+ 0xc64afab0, 0xdd794d3c, 0x36e51bc7, 0xdb193ad3, 0x6c2ce54c, 0xcbb3ef07,
+ 0xef3865df, 0x6f3e557b, 0x912611b6, 0xb60658cc, 0xbf7ae84f, 0x60c1d00d,
+ 0x6d97815e, 0x77f0c3c1, 0xd4afba51, 0x4db4fd0d, 0x602fe564, 0x6a5b723f,
+ 0x371fe399, 0x38b799ff, 0xfe6271ff, 0x46d896bf, 0xb7d7efec, 0x81e6d6dd,
+ 0x3c3cb579, 0xeee48462, 0xb75ef7ea, 0x76abf795, 0xcf4060dc, 0xb8fa37aa,
+ 0x66fac277, 0xdc208f02, 0xd82dbaf1, 0x99cf4698, 0x5b4b1e29, 0xabea09a3,
+ 0x5ed91d9c, 0xcdf8bf18, 0x6ff210a8, 0x32519bcb, 0x9f7e7183, 0xe917bbe9,
+ 0xa0e6fc58, 0x26139312, 0x464d9af9, 0xd036583e, 0xef3e1f73, 0xf1bdbe6d,
+ 0xd69c6009, 0x535fc911, 0x18814cca, 0x1d5f6fe0, 0x82859397, 0xef5d173f,
+ 0xc84fb043, 0xc4ead5cf, 0xabb74829, 0xb0d2609b, 0x4c9b458e, 0x75825f43,
+ 0xcb43b731, 0xeccc3c02, 0x730b60bf, 0x69995ca2, 0xc48733bd, 0xe9a06b06,
+ 0x06b1eb9a, 0x9ebcabf9, 0xbdaffd46, 0xeb9e97de, 0xc848b672, 0x19f90d87,
+ 0x9f8225e0, 0x197e45ef, 0x1b8725d3, 0xe28f7dd3, 0x80d667fa, 0xbe78c3bc,
+ 0x2885c92d, 0x62fc5d47, 0x80af9155, 0x8596925f, 0xcb4d4dc9, 0xf42a987c,
+ 0x7e25ef1f, 0x71650259, 0xc152fd58, 0x7b789107, 0x65f916ec, 0x48bf68b3,
+ 0x01996509, 0x28ea960f, 0xe7cc0b6d, 0x0a7bbc4a, 0x0efd65e2, 0x16f5bf8e,
+ 0xe603b16f, 0x9371febb, 0x8b619406, 0xa8ec3947, 0x587d4687, 0xf185f56d,
+ 0xc3ebfced, 0x30f01b98, 0x95267ae7, 0x83be01fe, 0xd785feb8, 0x0d3a09e7,
+ 0x8bb992a3, 0xd8c5cccc, 0x1baba406, 0xe9c45427, 0xad77e62c, 0x43e2747a,
+ 0x53b5fe30, 0x88bfaa16, 0xa9802d78, 0xe34f027a, 0x9b412cbc, 0x75e61076,
+ 0x2a02c2d1, 0x7ef169d0, 0xdfa00589, 0x46fa5025, 0xd83d52d0, 0x1481f6ce,
+ 0xb176c16c, 0x805b13cc, 0xe6f584f8, 0x86be31f0, 0x6d4c97ff, 0xfd410fd9,
+ 0x961b33e7, 0x81e03399, 0x86412a74, 0x82fe7e75, 0xbe7824c4, 0x2e5bdd72,
+ 0x94ab1e58, 0x50aaa60e, 0xcc14c1bf, 0x7be280b6, 0x86bdf646, 0xbbd3e07a,
+ 0x08adfe9b, 0xf0dc7dda, 0xaae913a2, 0x0e49b5e3, 0x4d3f6165, 0xcc00cf80,
+ 0x2a5ea9bd, 0x6c342a0d, 0x5da1b29f, 0x73f3adfc, 0xbaaf9f24, 0xba78419e,
+ 0xfa1b6d5a, 0xf031f212, 0xf5d73e2d, 0xae3aeaf1, 0xbefd75d7, 0xcebff056,
+ 0xd73295d7, 0x4c4a955b, 0x6e169030, 0x13bcca6f, 0x4c72ef91, 0xb70b165a,
+ 0x8e8f8d37, 0x32f83945, 0x5d61ab5e, 0x839742f6, 0x8049fc57, 0xa47b2ebc,
+ 0xc7ae81cb, 0xf3aebd75, 0x26af6ebd, 0x2f2fe4fd, 0x79fc3bfe, 0x81d7cd32,
+ 0xe64d307c, 0xec9a6b76, 0x1c9a3e20, 0xff23265f, 0x79fd7b7c, 0xb3cfe856,
+ 0xb6b9fd06, 0xc7f9fd17, 0xf387945b, 0xda967f42, 0x3cde7dd8, 0x3b67dfae,
+ 0x4a2bfaba, 0x834b649f, 0x1334947e, 0xcd47fbb5, 0xf3e3495b, 0xfef3b6f8,
+ 0x6fceb12f, 0xd303fbd2, 0xa46fd4ac, 0x1fd0679e, 0x5f2ff9ea, 0x1da20dcf,
+ 0x5d8188f8, 0x5af7bb40, 0x6161f71f, 0x444ec807, 0x666f04c7, 0xb9927e07,
+ 0xa7e22078, 0x4ee03b07, 0x80ec3bfb, 0xbcba57ce, 0xcba1f2e8, 0xe8fca443,
+ 0x11fd30f2, 0xa421e62d, 0x30e6200f, 0x781c8fca, 0xe951d70e, 0x728f93ee,
+ 0xf811cba9, 0xdd672461, 0x9b9083ec, 0xda31392e, 0x742e5d0b, 0xa6e5d139,
+ 0x52c5c852, 0x3cba1721, 0x1e9a971c, 0x3def0b1b, 0x432be697, 0xb1f2e87c,
+ 0xbb4885e6, 0x313f2bd0, 0xf1a5a7e4, 0xa9f90cd5, 0x7e70ca12, 0x4fc2f5b2,
+ 0x9f916ef3, 0x9dbed24a, 0x8d32b11f, 0x40ff11fb, 0xd6995a7e, 0x0ab15fb3,
+ 0xca7fecf9, 0xfd5ab8af, 0xcc37429b, 0xe8216ae7, 0x7e2eb4d9, 0xe32efe9b,
+ 0xf806437e, 0x46b450d9, 0x5ab675f3, 0xb06b0407, 0x1aacd7dd, 0x01fba8f1,
+ 0x7dee914b, 0x27f4f8bb, 0xfe71ff60, 0xc15bfd3a, 0xedf75fff, 0xd9d11df4,
+ 0xf566df16, 0xdbbd21e4, 0x37bff60c, 0x5bb1f17f, 0x6fe6f3a4, 0x4243e749,
+ 0xfa0ffc6f, 0xd17a878b, 0x1eff8713, 0x862cceba, 0xfc21fb3f, 0x3c67af7b,
+ 0x02fbe7d0, 0xa2f39c0e, 0xd22bccbc, 0x3c1bdbeb, 0xe01fa899, 0x8234b1cf,
+ 0x0f09d987, 0x56db3e02, 0xfe9cf302, 0x007d6758, 0x8f8f27eb, 0x8f33ef11,
+ 0x3fb57589, 0x5b51f691, 0xd60bda3d, 0xaf8dedc0, 0x0d0ef65d, 0x76010b83,
+ 0x1145c184, 0xdede01f0, 0x9533b729, 0x972084fc, 0x54dfe82b, 0xfd15f340,
+ 0x9e65fe09, 0xcf015713, 0xdb1354b3, 0x8aaa7409, 0x55d6f83f, 0x26cd6bd4,
+ 0xe1877266, 0xebc97021, 0xf6fd0149, 0x9fc0499a, 0x37c079b7, 0x0e25fbb8,
+ 0xabf0767f, 0xfa2c8086, 0x8d6c7f05, 0xc9a5b740, 0xbfa091e4, 0x60a64535,
+ 0x7c775a7a, 0x67c9d67f, 0x54c07cfa, 0xd667df1a, 0x1f7b5bf8, 0xa7ef4de9,
+ 0xdb21fbd3, 0xd77f8c2d, 0xf609e678, 0xd29b0fe0, 0x292c5db9, 0x3eb1e98c,
+ 0xf8e25d2a, 0x3eb001bf, 0xd39a3c3e, 0x91e5f7c4, 0xf9d363ed, 0xb3666db8,
+ 0x3763a7c0, 0x559b59f2, 0x1bb2b7c7, 0xb1993df1, 0xbe413e4e, 0x4e09f181,
+ 0xeaca5469, 0x4f5cbe64, 0xb66ebe04, 0x74d32fde, 0x5f0ba63f, 0xd97a0881,
+ 0xabef826e, 0x6ddbe03d, 0x33743f7c, 0xdbb9fd7a, 0x576f82fb, 0x31ec7ce8,
+ 0xec8c7bf0, 0x898cfe25, 0xe001a937, 0xa8deb5c7, 0x742fdc7a, 0x195267c9,
+ 0x88ca2de1, 0x4bf92ea7, 0xc8512b2e, 0xfdf5123f, 0x7afca377, 0xb9ed9dcd,
+ 0x0d7cea3c, 0x5e00e7ef, 0xf7c695d1, 0xdbf7a547, 0xbe23c81d, 0xe5827aa0,
+ 0xca4779b0, 0x3c045363, 0x857e423e, 0x40fe91fc, 0xca78007b, 0x7f16fd42,
+ 0xe30eead6, 0x7f053b93, 0xe5626e7c, 0x26db4fa8, 0x2db23f71, 0xa40f979d,
+ 0x02ccb8f3, 0x754b97c1, 0xc30e8a7e, 0x427f9183, 0x5b095fb8, 0x7e69e137,
+ 0x63cf2ebc, 0xbac066cb, 0x7d78e2da, 0xdda8e355, 0x382e9481, 0x8d75bfb2,
+ 0x2f10cb63, 0x8a07fd9d, 0x997da0ce, 0x40f6f02f, 0x813398e3, 0x1767413c,
+ 0x7fda19d9, 0x50047f01, 0x7f22541f, 0xc7f3ba98, 0xfc6ef484, 0xdf788819,
+ 0xfbc9b963, 0xf7dfddc5, 0x2ccfbc44, 0xbef2b7f1, 0x088cdba0, 0xd04696ba,
+ 0xae0224b5, 0x41a0e1d0, 0x797aeaff, 0xadeef351, 0xeac7982e, 0x5967a0a3,
+ 0x2d4f3f38, 0xad5fb943, 0xed3bfcea, 0x176bf20c, 0x3c274f3f, 0xf9d26ecf,
+ 0xd46ec675, 0x87a865c3, 0x73c176c7, 0x3c110f50, 0x1313ccb3, 0xed66af6e,
+ 0x57757b46, 0x0efede9d, 0xad777f6a, 0xea979fde, 0xcf423a75, 0x42d74465,
+ 0x3ecd5edd, 0x5eabf583, 0x4d1fefe3, 0x9026739f, 0x68791379, 0x81cbc088,
+ 0xd1103808, 0xd837cf7e, 0xf788dab7, 0xd7d44537, 0x23fbc047, 0xfbe33ae0,
+ 0x4898970b, 0x3f02170e, 0xe5222120, 0x9a3f9232, 0x9cfd3bd3, 0x526e7b4e,
+ 0xc833bfc8, 0x0e1af4d5, 0x95f74b1f, 0x706129d5, 0x2e32c2e3, 0xf01a3017,
+ 0x7ff185a5, 0x120373a0, 0x17a583f0, 0x1bd4d9bd, 0xda44e65f, 0x7bff5e7b,
+ 0xfd1933fc, 0x4bf06665, 0xb8464b8e, 0x0ef31245, 0x90d99d54, 0x78750f87,
+ 0xa7ee196d, 0xae33efa7, 0xa2b3f60b, 0x49594d7e, 0xd6c45fb8, 0xd6c27994,
+ 0xf29fb7a9, 0x1c25afd7, 0xd5c6c3ef, 0xbea08765, 0xab285262, 0x5e38cb1a,
+ 0xd094bd82, 0xf889575e, 0x25d794cd, 0x8acbda2f, 0xfad650e8, 0x35883f70,
+ 0x5b3ae365, 0x3e88961e, 0x0fa01a81, 0x732169e0, 0x2eced15b, 0x832b1e66,
+ 0x4c4b5cad, 0xf023c6cc, 0xa587f1de, 0x3fa7688d, 0x85d7d8da, 0x19d1a1fb,
+ 0x3c717f7c, 0x296ba066, 0xee7d2dc0, 0xb2db7d23, 0xc795327d, 0x0eb6cf24,
+ 0xdbffb195, 0x929970f8, 0x8431f58b, 0x0fe9aba7, 0xf9066d95, 0x9bba53f8,
+ 0x538beaf0, 0x6fe8cd5d, 0x8c30b4ef, 0x51a63397, 0x2ee1691c, 0x9c4efe5b,
+ 0x2e21e6cf, 0xfd173ff4, 0x324a6cb0, 0xd5b45bb4, 0xd51fa1a2, 0x7153566e,
+ 0x939dbe7e, 0xa4bf58ad, 0xdb819456, 0x6ff37ca9, 0x4271aa3f, 0x4ca78efb,
+ 0x9fb4235a, 0xdde9ad70, 0xaf2f0061, 0x4490d0cb, 0x33375c6f, 0xb739c615,
+ 0x0250507f, 0x551f3cbe, 0xde2cf6fd, 0xe5fb619e, 0x67a7dc37, 0x497b6215,
+ 0x2fed02dd, 0x9ff473c0, 0x1a90ec2f, 0xa72f384d, 0x4b04da23, 0x4657f0ba,
+ 0x5b0b9cf1, 0xcf8c416d, 0xf77c539d, 0xf671c7ee, 0x67d3d05b, 0xa76e4c17,
+ 0x9f10f009, 0x292cb3b1, 0x04db9f19, 0x2ec6773d, 0x685f3904, 0xb21fe4ee,
+ 0x3962cb27, 0x1da3ff1c, 0x1d618765, 0x441f1e17, 0x195dabf1, 0xc00c849e,
+ 0x1e991df7, 0xa3e79617, 0xf37addb8, 0xe87dd26f, 0xf2f2ffc7, 0x97f21722,
+ 0xd3cb833b, 0xb917d71b, 0x55f98516, 0x89973ecb, 0xbab4de0f, 0xdf7ce037,
+ 0xc2601e8c, 0x41f0367d, 0x2f938c5f, 0xe016fb11, 0xf62f8de7, 0x97fd5fe0,
+ 0x1e5ac7f0, 0x36ef1849, 0xd27ef5f0, 0x00dfb49f, 0x87e33f38, 0xc7c003bb,
+ 0xb236db1f, 0x9b8c28f3, 0x75dc52fa, 0xe07a1309, 0xee20a8b9, 0x535258ab,
+ 0xa6fc7876, 0xfb450e53, 0x841c05df, 0x7b41dfd7, 0x2efdf7dc, 0xf08e1ff0,
+ 0xfdbd0bf3, 0x8023a772, 0x0e27c5ce, 0xf8f48c87, 0xf85ff648, 0xecb7bc2e,
+ 0x81d90b29, 0x6c254f65, 0x8171c0ea, 0x16ae306f, 0x867f2eb9, 0xabd5d685,
+ 0x6523b25c, 0xfbe12925, 0xbfa4c395, 0xe9cb937b, 0x0ecb8719, 0x972ef5e5,
+ 0x9fae55cb, 0xf1653ca6, 0x1f2d3ca2, 0x70d990e9, 0xf53d26c6, 0xcfc461d6,
+ 0x055175f2, 0xf2f89836, 0xaf446ca7, 0xa0238776, 0xe9cfbd42, 0x9ca16390,
+ 0xd6f5c19f, 0x3f2e0ca6, 0xed9312c5, 0x62d65405, 0xcc0af5bc, 0x97c02fa7,
+ 0x77b63e36, 0x29f38c34, 0x0d1bce0b, 0xe1e2bbf8, 0x25e57a7c, 0x4c8ee289,
+ 0x4133c8f6, 0x5c60ae5f, 0x7c9e544f, 0xfe113ad1, 0x5ff562ac, 0x5c1fb049,
+ 0x067cbd51, 0x06570bee, 0xc5dae72d, 0xb16bfc5e, 0x55b3d45c, 0x5bd811fc,
+ 0xfefebd63, 0xfa4ed61a, 0xa229b2a3, 0x4ff6fabe, 0xd5537e30, 0x3ebe7c6c,
+ 0xa17f11c3, 0x7258c30f, 0x5d8a6001, 0x3364b6a9, 0x0572ea58, 0x5dd60ce4,
+ 0xf344c07c, 0x0a51be5f, 0xc5fe60da, 0xf8dc797d, 0xc1f03f63, 0x407f5a20,
+ 0x1ef97805, 0x33967f6e, 0x7f0ed053, 0x1d607ede, 0x0a2f31c5, 0xc4d0b37d,
+ 0xe7e7c8bc, 0xdc54b4a3, 0x2a7b2fef, 0xfcbcf08a, 0xf6ff95e9, 0xbed7bc38,
+ 0xf87c6679, 0xf90ebafe, 0xd999e383, 0xf9fabae3, 0x52f7f364, 0xff8a0e51,
+ 0xb0c9f619, 0xecb1e5de, 0x90d3f3a7, 0x6ea9c96e, 0xf2ddaba5, 0xf3670f2d,
+ 0x86cfb076, 0x21dc2f75, 0xcbd83ad1, 0x2087b236, 0x3e386af3, 0xb49ed497,
+ 0x633db95a, 0xd9f84baa, 0xf5e7d46e, 0x7fbc126d, 0x8525ea0e, 0x0f6817f0,
+ 0x87df978b, 0x3e93257d, 0x2afae1f1, 0x66fba6cc, 0x561d3f53, 0x3317ef94,
+ 0xd9f45c78, 0x2ee7ee0c, 0xa5eed54c, 0x36a3f438, 0xef1a4b6d, 0xe6251a47,
+ 0x4abcfb01, 0x3a32db73, 0x8db9fcc7, 0xb5552be2, 0x27289e51, 0x2f3c4bed,
+ 0x3255bf40, 0xd871ad93, 0x1ae75f2f, 0xf01fd737, 0xcf1943fc, 0x3f5c1c67,
+ 0xbe02c656, 0x6638ce15, 0xfc4bffe8, 0x97f7832b, 0xfdebac3c, 0x5d4df1ce,
+ 0x10c3b9f5, 0x95e77d5f, 0x979e3ce3, 0x19017e48, 0x9fa1168f, 0x0234bcf7,
+ 0x770bd7f7, 0xfa829f1c, 0xf2cff576, 0xe1757c55, 0x7b27df4f, 0xb9d05ab1,
+ 0xb47dfd1d, 0x0cff001f, 0x7e4253ca, 0x0f8f127c, 0xd0f8129d, 0x57d7ade9,
+ 0x38f0b0ee, 0x5475e83d, 0x7f9b9524, 0x3a56fd43, 0x6fa85cda, 0x8cb65f2b,
+ 0x6bfcbd42, 0x5fb43f9c, 0xf8c079b4, 0x167f810f, 0xb4546259, 0x33026b4f,
+ 0x69af08ad, 0xf5dc1130, 0xf22a425e, 0xafb567e3, 0xce4f9138, 0xd0b28547,
+ 0x8bac750e, 0x01711ad2, 0x7dcf8f2a, 0x88d59b56, 0x6a259c71, 0xf504c39b,
+ 0xc464364b, 0x48febea1, 0xfeb1590d, 0x3334a6a3, 0x1d551ec2, 0x1e47b08f,
+ 0xa067f04e, 0xff049aba, 0x6b59bea0, 0xf35cf4e2, 0x3a6b71dc, 0xac55778c,
+ 0xdfe7f3f7, 0x4f78c6cf, 0x365b6a65, 0x77a011da, 0xf3c47f76, 0xc3b226b3,
+ 0x3c939f6b, 0xe8bac351, 0x0de916bd, 0xd04ab5f2, 0xaf4bed79, 0xbf7c843c,
+ 0xd05de916, 0x6f805f9d, 0x17f3d04f, 0xfc614e0e, 0x17c813fd, 0xb802ddba,
+ 0x377182d6, 0x09af872b, 0x25e7803e, 0x8f2079fc, 0x11e826f4, 0xf92337f4,
+ 0xc6fa37bd, 0xb7fb7266, 0xf48db368, 0xe7266c6b, 0x2f1df6fb, 0x9f7e913b,
+ 0x6dfc7f3f, 0x7ca94f3c, 0xbbb2ac01, 0xf817be07, 0x3bf5c2a8, 0x4fe4fe69,
+ 0x9d7ae154, 0xe4efeb5d, 0x556f2173, 0x5f4faf8c, 0xd62c956f, 0xf78bd7af,
+ 0xbc8532e3, 0x97af8130, 0x12f97106, 0x8af284f2, 0x3ebe997e, 0x5f7f1c5f,
+ 0x4ca2cfe7, 0x62699fce, 0x726d4c9d, 0xbe907e22, 0x7f8067a8, 0x4251d63c,
+ 0xcf93406f, 0x0ff3067f, 0xff3e97a3, 0xd00f3152, 0xb8d89e6b, 0x9bb63a2e,
+ 0xce9e8ad9, 0x3933f32f, 0x9add9cdf, 0xf80cda98, 0x59f60cfb, 0xfc006794,
+ 0xa78d872a, 0x5e3e8df3, 0xa6ca4ff1, 0xffa1bae1, 0x8faff610, 0x8fa051fb,
+ 0xc47cfd8c, 0xf3e87cb8, 0xb8b2e5d7, 0x7cb4c166, 0xdcfbb627, 0xeb879191,
+ 0x6697e3e6, 0x07bef4aa, 0xdf7803fd, 0x38a26cd3, 0xafb159f5, 0x15f5bb3f,
+ 0x2ebca2e7, 0xde229f7e, 0xabb27fc3, 0xfe753cfb, 0x9a67e30b, 0xbbf6f167,
+ 0xcfac21a6, 0x752f9237, 0xc9fce9bc, 0xdf902536, 0x55a7c912, 0x38ad6729,
+ 0xdd73e45e, 0x718f397f, 0x5fff9416, 0xff248298, 0x6644ecb5, 0x7f865d98,
+ 0x65d51b0a, 0xb3af361f, 0x51cb7b51, 0xbd75076e, 0xaaebdbaf, 0xc425cf78,
+ 0x79328ff7, 0xf56ac91e, 0xf42736c4, 0x36e3e633, 0xfdd60f3a, 0x42d709c5,
+ 0x95c60c52, 0x082b4a5e, 0x2e6b77b7, 0xadfe209f, 0x70db6d64, 0xc770b3ff,
+ 0x234733fb, 0x42d8fe9f, 0xb70b2fe7, 0x1fa2b64e, 0xe2f0f2be, 0x73ff4851,
+ 0x5d9edc75, 0x04791daa, 0x7573e8fd, 0xe716b98f, 0x53c57be1, 0x85f3c2c6,
+ 0xbe89f3bb, 0x66daa3e7, 0x80f1dc22, 0xbde11ac4, 0x6e478771, 0x71e01bba,
+ 0xb8b1818e, 0x490e8fce, 0xf8c36325, 0x37530961, 0x9b7e8ddd, 0x7ca2a31c,
+ 0x5af4247c, 0x6bd3858d, 0xdaffe097, 0x79cb92ce, 0x364d4d71, 0x1c77979e,
+ 0xf80a7d04, 0x9bbab0a9, 0xebee3842, 0xa80fb489, 0x524b6d82, 0x935b9d1c,
+ 0xcac2b4df, 0xf405c9ec, 0xcf0c9edc, 0x1eda5a4f, 0x7c9cf5c0, 0x19bf91c0,
+ 0x18dd2b71, 0xbbfb88b5, 0xe7e03724, 0xbe3af8d2, 0x0bd479f4, 0x4fec8b3e,
+ 0xfd15bf7f, 0x627fd47c, 0x7f6a97fe, 0xd6ed0f3c, 0x7159a3a5, 0x5e4ffeb8,
+ 0x3f43aa8f, 0xd70b13e7, 0xe0ff7a67, 0xee1c7d7f, 0x65bf8127, 0x32bfc180,
+ 0x1f67c0c0, 0x2db5fd1b, 0x33a7af34, 0xce95fe8d, 0xb2eb15af, 0x04f3c262,
+ 0x99e3f9ba, 0x744796b7, 0x02880fd9, 0x318c5d16, 0xf6ef8c0c, 0x6d8bebf9,
+ 0xd8378fe8, 0xf3ac1b54, 0x3c77e463, 0xe2597a6f, 0xe73b00fb, 0x1e5f8fff,
+ 0xdefdc411, 0xf0e4ffb2, 0x105326b2, 0xec4ea553, 0xfb612ede, 0x25ffe0a5,
+ 0xdbfcc29a, 0x01e7bb3d, 0x9a2bb3db, 0xb4325b6f, 0xe79472bf, 0x12b5403f,
+ 0x9dbed7e1, 0xf7dffeec, 0xc178f567, 0x6bbc74af, 0xebbc434c, 0x39f7d6f8,
+ 0x145f026f, 0xefe17415, 0xf20aff0b, 0x7dfb2f67, 0x3a697e54, 0xe438e8fb,
+ 0x868c4767, 0xe6cbf372, 0x48fea4c7, 0x6ff297f7, 0xac757ee0, 0xfca2a312,
+ 0x48dfe17e, 0xfd978c87, 0x74ea54d5, 0x1365e3d7, 0xf7a16a5e, 0xf11e68be,
+ 0xef7838da, 0xeb86250d, 0xf7cf0f6f, 0x646fa488, 0xebfdc7de, 0x73e22746,
+ 0x7e9f5d7d, 0x9f59d397, 0x1747a7f7, 0x2d5d713b, 0x6d7df64f, 0x4fb7d20c,
+ 0xdafe8a8c, 0x71f79172, 0x13d73f61, 0x4731ed17, 0x2f9d0066, 0x62e3981e,
+ 0xb69737a0, 0xcf879dcc, 0x526ebd97, 0x5ed75fd1, 0xfee2732f, 0xbb720fea,
+ 0xde12c553, 0xe47ce10b, 0x697a84a0, 0x839b296c, 0x6486c7ed, 0xc67e86e6,
+ 0x32fce0cc, 0xc41cb2e6, 0xe0cf9f83, 0x6e33c539, 0x033c5344, 0xbcc5f5fe,
+ 0xe0bfa58e, 0xef1d1071, 0x9c6c7efa, 0x1030f758, 0xf177e243, 0x3f88b8bc,
+ 0x8bc0e4ff, 0x4bbfb0b3, 0xce2a2c87, 0x16438bfb, 0xec157fea, 0xde30cca3,
+ 0x5f7ca3c5, 0x1a547082, 0x7fdf33ca, 0xfbe26aac, 0x1675ca8f, 0x3ba6358f,
+ 0xb587165f, 0x3c1efdc3, 0x2bb8e373, 0xfcea1f05, 0xd7c3caba, 0x1cec0ab7,
+ 0xf89bf7ae, 0x6d359637, 0xc6f5bc43, 0x7f96dfc7, 0xfa8cb333, 0x7b6f93a2,
+ 0x578117e3, 0x5be47f94, 0xed562f9d, 0x71ece7e7, 0x9113f94d, 0xd13e74ff,
+ 0x12604bf5, 0x5a7b41cb, 0x98396563, 0x47301397, 0xca17a86b, 0xed05b714,
+ 0xf6f89cc0, 0x23cf4412, 0x4abf5c59, 0x198f66c5, 0x8d8d51ed, 0x78b747f4,
+ 0xc7d71677, 0x283e6421, 0x7952ccef, 0xa6ab25be, 0x825e857d, 0xed0032e3,
+ 0xb89f5976, 0x49a1ba3f, 0xd9c6e1e9, 0xd975f032, 0x3207b8b8, 0x87bcc634,
+ 0x4478728f, 0xd40b48dc, 0xb333d2cb, 0xccae004b, 0x0ac94cf2, 0xe1d2f7eb,
+ 0x1eb801c4, 0x9f153e78, 0x37de28ff, 0xea246b23, 0xf9f4857f, 0x618ea697,
+ 0xdabad31b, 0xf1dd799f, 0x5ddd2fd1, 0xa585bb70, 0xeb08796a, 0x9ee5e5f3,
+ 0xec1ccf2c, 0x22f9f227, 0xde52b6c6, 0x3f5fe05c, 0xfe04ff44, 0x8f40ed79,
+ 0x2d5f043b, 0xa4212bb2, 0x5cb3ab33, 0xc037f4ee, 0x8c5a6015, 0x259b748c,
+ 0x390ee4f8, 0xe7ef82d4, 0x82f55ab2, 0x03a25c9d, 0x5dedf75f, 0xd80603af,
+ 0xe03fbd05, 0xb02d2f87, 0x136be03e, 0x1046dfb0, 0xb120131d, 0xe998f402,
+ 0x33fd7fb5, 0x60135bf6, 0xe78451ed, 0x10c2f50a, 0xccface0c, 0xd959435f,
+ 0xe30c39c7, 0x1c579e1d, 0xb8e80521, 0xc43ef9fe, 0x1f852bff, 0xc4457cc3,
+ 0xbe541bcf, 0x4b1be61e, 0xe080f6fc, 0xacfc4fb7, 0xf044133a, 0x0bec7673,
+ 0x70f1e619, 0xc461ef94, 0xa9f31afb, 0x946ef5d4, 0xfa271ad7, 0x54ff9f19,
+ 0xac3550d2, 0x3b24fe11, 0x5ee42094, 0xf506dd0a, 0x8db969ad, 0x0ab66f68,
+ 0xc69cb97e, 0xd81c3f68, 0x3fbca36c, 0xea78e376, 0xa69700c3, 0x3ee1aedf,
+ 0xb6cff2f3, 0x3a052e67, 0x38bd40d9, 0xa1539d61, 0xb75822cf, 0xce896005,
+ 0x4f448381, 0xe1380fa8, 0xc7b4b6f9, 0x319f3952, 0x4eb5ca2f, 0xddef1d1f,
+ 0xa34301e8, 0x33b669df, 0x732bee0b, 0xe51501d9, 0x27cba74f, 0xe01bc076,
+ 0xfe6e327b, 0x7fac1f41, 0xeb7ffb99, 0xa613ac4d, 0xfb374eb8, 0x9ff916f7,
+ 0x83016e20, 0xf8b0397e, 0xa2c3d9db, 0xe21c5683, 0x81e2ed96, 0xcaf51ee2,
+ 0x257ae8bf, 0x1f93e59f, 0xf1844b82, 0x93368b96, 0x8cb70aa5, 0x6bb049eb,
+ 0x9feb17c8, 0xc3bb20ca, 0x8590fc66, 0xfa0763b7, 0x4b6cbf12, 0x2b0e8893,
+ 0xd7944d9b, 0x3fb9b338, 0x8cd54373, 0x3a54bee6, 0xf3d327af, 0x2dde474b,
+ 0xd3877ae4, 0x8933e669, 0xe88f2893, 0xea544199, 0xf82f58f3, 0x15f3c74e,
+ 0x1cb3c72f, 0x1e37ddc8, 0x2d5a13cf, 0x3f26e82c, 0x35cfd784, 0xb4afde11,
+ 0x7f91979e, 0xb1304ee6, 0xd14b00be, 0x496dcf9c, 0x01eee666, 0x9f4136bf,
+ 0x73347728, 0x6a0bed87, 0xf88d9ca2, 0xda780b1e, 0x97701f70, 0x2727d768,
+ 0xa74ed0ce, 0x8e813ce7, 0x331594bb, 0x9ddb1d70, 0xbf915a53, 0xc33f5a1c,
+ 0xb14936b8, 0xabcc1f20, 0xee63d230, 0x196c235c, 0x5be915ff, 0x73e378cb,
+ 0x5f08c79b, 0xcb98e9d4, 0x18e9c372, 0xfa0f3f86, 0x363c57e1, 0xdee63f8e,
+ 0x79e01e37, 0x7cc3f861, 0x32292b96, 0x147b6fe1, 0xade017c7, 0xa63cf911,
+ 0x58b788c8, 0x7d4f118f, 0x48f88d4b, 0x9bd71af0, 0xa86e9e58, 0x360df64f,
+ 0x515ff7d4, 0x54078060, 0x1fb4358f, 0x019271b8, 0x334c0b4e, 0x9ba8cfb4,
+ 0x1ab3806d, 0x1fb436ee, 0xa1917fb4, 0xcab8373e, 0xe8e43f50, 0xb43c037a,
+ 0xed0c9fe9, 0x316f3787, 0x7687e7d4, 0xb447ea1a, 0x8f00c0fe, 0xd0c27b6c,
+ 0x8d87f47e, 0xed31fa86, 0xc7ea1acf, 0x00c17c5d, 0xd578e84f, 0xebb6fed0,
+ 0x44f00cc7, 0x7da1aef6, 0x037dfdb1, 0x0ffd593c, 0x93dbfb43, 0xa7ea1bce,
+ 0xd4333fba, 0x6ab9cf4f, 0x7f6a6780, 0xb6afb431, 0xa36546fa, 0x265d2aff,
+ 0xc059aab9, 0xeb4aeae5, 0x71ca3b1c, 0xdff03651, 0x7fc9d610, 0xd29ed0e3,
+ 0x62a5857e, 0x34b264fc, 0xd9f2443e, 0xdf70d26c, 0xe4af6911, 0x8c1ebccf,
+ 0x4c57b1ab, 0x06234f74, 0x361c8ecc, 0x0ec7ac7e, 0xb82ec41b, 0x806aa96f,
+ 0x8649bc13, 0x6ee589f6, 0x2fb27d43, 0x7fdf50c7, 0x07806685, 0xda191754,
+ 0x31e8dc0f, 0x528169c0, 0x3a8cfb43, 0x6ace01af, 0x1fb43728, 0xa867dfb4,
+ 0x30ae0dcf, 0x5a390fd4, 0x3687806d, 0x1fb4346d, 0xd4301cde, 0x0cea87e7,
+ 0x1b5a23f5, 0xb6c8f00c, 0xa3f686fd, 0xea1a0c3f, 0x351fb4c7, 0xd8bb8fd4,
+ 0x74278064, 0xdfda1b34, 0x80643d76, 0x8693b227, 0x33f6c5f6, 0xfab27806,
+ 0xdbfb435b, 0xea1ace93, 0x192fbaa7, 0x64ff75ea, 0xc657ce7a, 0x995fc2e7,
+ 0xf0d9fda9, 0x8792607e, 0x5e047f21, 0x6e356930, 0xa766f6c6, 0xde817f13,
+ 0xd0928f6e, 0x3e52f1bf, 0xf4261c52, 0x04c65f01, 0xe857c44c, 0x5c5057ea,
+ 0xafe29e28, 0x98dc5a64, 0x1f760377, 0xb4e67fe3, 0xfb77f434, 0x295df974,
+ 0xf6f88f5f, 0x6cd1d77e, 0xdb6bf646, 0xa7bca944, 0xd9a3c33c, 0xebf20e3c,
+ 0xd953df6c, 0xf8bfb809, 0xbbf414d9, 0x36c0b257, 0x2964e79c, 0xde1da62f,
+ 0x8c651d3b, 0x54e5e863, 0x6c2de03b, 0x1aa3273e, 0xb26e0a52, 0xbf6a9fdf,
+ 0xfb3bed4c, 0x130df115, 0x587d7fac, 0xbec28fff, 0xadbf0640, 0x05720fc1,
+ 0xfc0fecbe, 0xfc7bc12a, 0xf5ef0449, 0xefdca9bb, 0x09f2a1cf, 0x07f546bf,
+ 0x3f0445fc, 0x1c10f7ed, 0xd95297f4, 0xf3d2f7e8, 0x8272fe43, 0x197ec08f,
+ 0x7fb0a3cb, 0xd859f2c6, 0x73fd6307, 0xf8462fb0, 0x9500fea7, 0x7a3afe4d,
+ 0x81bf82fe, 0xfbfc97e0, 0x3fb9fe09, 0xffb36548, 0xfaaf9528, 0x35fea89b,
+ 0x6fc1337f, 0x870443f8, 0x1f04adfc, 0x7c11b7f3, 0xc121ffc2, 0xa9dbfb6f,
+ 0xa45ff56c, 0x077f1df2, 0x5ff29fd5, 0x9e8bb827, 0x12387f46, 0xf88a9f9f,
+ 0xe37e132b, 0x2c3fc172, 0xcb8bfb9e, 0xe5b02b38, 0x932d6f82, 0x78c10dc0,
+ 0x46ecbf60, 0x891d7bcc, 0x7c43957c, 0xfc56ea75, 0x98fdc8f9, 0xf19f025e,
+ 0x133af4fd, 0x76e8d78f, 0xe817e45e, 0x03c5527e, 0x00bb1f7c, 0x273c5ffc,
+ 0xee28cff8, 0xb6a95eaf, 0x573fa0e4, 0xf0d68a61, 0xf54ae51c, 0x610fc81f,
+ 0x220dde78, 0xb66bdf72, 0xf6c33b83, 0xbef01571, 0x4eafde19, 0x54f9a34d,
+ 0x9d0b56b0, 0x23cccaa3, 0x33dd5c81, 0xf89d77c0, 0x4039807a, 0x98256afb,
+ 0xff38fb8d, 0xf05fdf00, 0xa5ea95f9, 0x547e136f, 0x670fce8d, 0x770942da,
+ 0xa4e4fc61, 0xdebff144, 0xf22551f0, 0x7fad7bc8, 0xfa0a52e3, 0x937fa5e5,
+ 0xd39f487c, 0xc6394716, 0xf8839c13, 0xc839d4be, 0x5263286c, 0x30418e7d,
+ 0xaa393f9f, 0x0a0335ef, 0x759df4ff, 0xeb4fee47, 0x81df47da, 0x9bf0515b,
+ 0x42db98cb, 0xf3cc8d79, 0xb85d5e16, 0xbe08f993, 0xfca8058b, 0x35cf8a5e,
+ 0x0fe62468, 0x8df60905, 0xb4f6a5b5, 0xa579c8ae, 0x207ae20d, 0x50d9906d,
+ 0xb9f5484e, 0x393fbfb1, 0xd3af343c, 0xc6cf6e63, 0xfaf3e975, 0xdf9baa5e,
+ 0x4f1d609f, 0xf4fefce3, 0x4c1757fa, 0xe3f9dd19, 0x0a17c01f, 0xc7686f9a,
+ 0x06a41cf0, 0xafdf0764, 0xf289aef9, 0xa8be75b9, 0xbe2180c0, 0x7944c9b7,
+ 0x027c5dfe, 0xb0fb81fc, 0xf7ba0ef8, 0x01327c07, 0x8c6ab9d7, 0x5f82b014,
+ 0xcc1cda79, 0xf2b9d136, 0x15c62b52, 0x7f03c796, 0x07cef7a4, 0x03fdc56b,
+ 0xd7f039fd, 0x2fcf48ed, 0x073a317e, 0xc6f555f1, 0xabe23718, 0xc0740cc6,
+ 0x923be37d, 0xb857f3c6, 0x0dc697ea, 0x932678a5, 0x4fe30d35, 0xeb3d6d33,
+ 0x7f82e5db, 0x4a59274e, 0xf19fd483, 0x413ee5fc, 0x3d04fbb7, 0x64fbafd7,
+ 0x3ef3048d, 0xdd12ec7d, 0xff36e95f, 0x983c8f8d, 0x55c7c619, 0x78a767cd,
+ 0x5bdfd07a, 0xdf3a7f44, 0xef875648, 0xaf3e12a0, 0x465e3e4e, 0x7c0b12fc,
+ 0x7c7c419c, 0x6719cf01, 0x7731dcd9, 0x280ed941, 0xfbe94109, 0x81f69567,
+ 0xe546988b, 0x72a5e612, 0xf91d9039, 0x6dd81bd6, 0x62af7c45, 0x6d7cf44d,
+ 0xf21762d1, 0x8fb332f1, 0x306bc9f6, 0x7dcf1753, 0x12494759, 0x36ea4bc6,
+ 0xe80495bf, 0x7bb0d39b, 0x676fc632, 0x85be1707, 0xd321d965, 0x055bcc05,
+ 0xce2ef8b9, 0xbd54ddab, 0x7f8c1fb5, 0xb71373f7, 0xb3e787f6, 0xf60f4e24,
+ 0xae87a72e, 0x0dd72237, 0xe499b072, 0xeb43d633, 0x06a59c92, 0xc2d8a839,
+ 0xaef8a63c, 0xb94ef9fc, 0xfbfd5a28, 0xe4bfa8fe, 0x54178a0e, 0x438b61bd,
+ 0xdc62af3a, 0xf479301f, 0x07ee8878, 0xd5f3e230, 0x76c35a2c, 0xfebe0a9f,
+ 0xbe230074, 0x1b04d4fe, 0xff2e82c2, 0x92faa594, 0xecba320a, 0xb9f99575,
+ 0xb0278861, 0x9f89fbe7, 0xcb6d37cf, 0x1fbd434f, 0xc4ff454c, 0xab4dacf2,
+ 0x15d83349, 0xae9f75f6, 0x16a3d738, 0x9c8a871e, 0xede8a997, 0x623fa33f,
+ 0x9e00b2b3, 0xb35c8083, 0xfdcf2851, 0x355724ac, 0x978c5a88, 0xf9baf24d,
+ 0xffb1ac39, 0xadbe62d3, 0xdd71e57f, 0xe307ac00, 0xe1c7dd26, 0xdd16ca76,
+ 0x0de90e35, 0x9a71a317, 0xead19107, 0xed298f1c, 0x37bfe829, 0x8e7efb44,
+ 0x3fe3d1f4, 0x35b2befa, 0xba4c93ed, 0x52f63697, 0x18f7dd05, 0x80fba363,
+ 0xd8b88877, 0x2e3c451d, 0x071e8776, 0x07111f1b, 0xb0c7888b, 0xc5c73df1,
+ 0x98ccbd74, 0xe4f9c166, 0xd7d4ffb2, 0x5d18f14f, 0xabb3760f, 0x8a3690b0,
+ 0x6e29bb57, 0xc99f19d1, 0x4cf8f2b7, 0xd5c53249, 0xee4f42ad, 0xa4fd72f2,
+ 0x0e589fbf, 0x3ec3185b, 0x0d32cec2, 0x00d508fb, 0x324ea80f, 0xd1b81fb4,
+ 0x0b4fa86d, 0x33ea18e4, 0x9c0334ea, 0x686450d5, 0xc7bf683f, 0x4b06e700,
+ 0x1c87ed0d, 0xa1e01af5, 0xf686e54d, 0x867d9bc3, 0x0ad0fcfa, 0xd688fd43,
+ 0xb23c036a, 0xfda1a36d, 0x86030fe8, 0x75ed31fa, 0x1771fa86, 0x84f00c1b,
+ 0xf686fd8e, 0x1a0f5db7, 0x1fb227ea, 0xed8bea1b, 0x93c0333f, 0xda185fd5,
+ 0xd3ec253f, 0x862d49ed, 0x5c4407e7, 0xa4fbaa62, 0x39e9fde1, 0x53f00c67,
+ 0x87946f48, 0x879256f9, 0xf783f596, 0x07fd0055, 0x186b37ac, 0xfda999f3,
+ 0xab2fd0d6, 0x6dfc47ee, 0x52cfe28d, 0x947cb6a4, 0xedcca7db, 0x6d3e5869,
+ 0x7dc16f72, 0x89f8c66f, 0x2acef614, 0xcb05b859, 0x9b363341, 0x9f40dc13,
+ 0xa0b707b9, 0x68a90c98, 0x1e00bb31, 0x16ece4ba, 0x8d61d217, 0xfc444a49,
+ 0xc1ab486f, 0x89a6c472, 0x8fd41252, 0x83585dac, 0xfd71757a, 0x61cb8599,
+ 0xd837a35e, 0xa09dcd89, 0x3e30da0b, 0x6f887b26, 0xe29b0037, 0x8c8c363a,
+ 0x5dbbfca6, 0x37191563, 0xba76bb33, 0xb86e316a, 0x1d41676b, 0xafc0db96,
+ 0xac620e0f, 0x2c7afc0e, 0x1f5f8277, 0x386e8584, 0x945887f3, 0xa9e07553,
+ 0xdfd73c24, 0xcd53e93e, 0xfb0ae1ac, 0xe3013dcd, 0x8b4427d6, 0x737ec7bc,
+ 0x7f426627, 0x0f00ab28, 0xdcfa71f8, 0xbe1dd280, 0x2a3bc436, 0x372a1707,
+ 0xd7bfa1a4, 0xc0c0dfad, 0xc3e227b9, 0xa27805fa, 0xf5fa6dfc, 0x785fb078,
+ 0xc3de63de, 0x9f6e1ce4, 0xf59ae407, 0xd7ca023c, 0x943a2ee2, 0x80c497e0,
+ 0xd31fab9e, 0xf80e5bea, 0x136ad595, 0xf71637dd, 0x4da43056, 0x5f1be071,
+ 0x700f16df, 0x64ef7892, 0x8e0e6f9e, 0x72e380ab, 0x927f8c2e, 0xc61c0096,
+ 0xbf00fb1f, 0xf35d2ce7, 0x0e67dcb1, 0x2c2fa0c8, 0x069a65c5, 0x20b93ce3,
+ 0xfb9d369a, 0x22ff46ac, 0xfc9de44b, 0xfbcc473c, 0xfd0d1cc6, 0xf58b9fa2,
+ 0x8df7ee3c, 0xfd82d8fe, 0x7932a0af, 0x40f98849, 0x579a29cf, 0xcb0ad4c3,
+ 0x8cda3fd7, 0x07c04ef7, 0x8a3b426a, 0xf98737cf, 0xb8732b1b, 0x5af9625f,
+ 0xa5baf8a2, 0x85c5abc6, 0x4c916f8d, 0x4fed3dd5, 0x1065e237, 0x5186af7c,
+ 0x49f8e5bd, 0xac9f4fba, 0x52969835, 0xe786213f, 0x3f884a21, 0x4d05a7ef,
+ 0x923e004b, 0xff7c36e3, 0x9812dfa1, 0x4fbc787f, 0xbe6136ae, 0x6aa6e242,
+ 0x5121e213, 0xbe786af5, 0xc35edcc8, 0xc6e275f9, 0x1e3fa3b5, 0x6af6f381,
+ 0x99610798, 0xc87df3ae, 0x9cb5448e, 0x703262d7, 0xea5ee2dd, 0x1316b755,
+ 0xf43ac3df, 0xe7e76952, 0x3bd5bd5b, 0xa6a9de0b, 0xc502d7bc, 0x4f58478d,
+ 0x07e52be5, 0x23b3e07b, 0xa92fdc39, 0xa3e71a77, 0xc217e7e8, 0x19555c6e,
+ 0x6f425bb7, 0x61cb1fdc, 0xf3fb9fbd, 0xcdd9120b, 0x44dfbbe6, 0x5c3ab1e7,
+ 0xde20e30f, 0xd8b46fea, 0x98f56f11, 0x8bf64167, 0xfa7add91, 0x77073987,
+ 0x4ff3ba9a, 0x89003937, 0xbe40298b, 0x01ac1b3c, 0xadf239fc, 0xca69fa1a,
+ 0xe84ccb83, 0x6ab1240b, 0x4652184a, 0xc3cab496, 0x72bf326e, 0xfa27ff23,
+ 0x64c1f28c, 0x37dd325f, 0xfdd57410, 0x7474ee82, 0xde206627, 0xe579e5df,
+ 0x89dcd3eb, 0x5f9d4748, 0x63fc9fd7, 0x0e8c2f94, 0x2e7e081f, 0xca120d62,
+ 0x44d658eb, 0x46d678e5, 0x075877e5, 0xcaa61e95, 0x1a624e58, 0x4bcc2595,
+ 0x4d5614e5, 0xa06b2965, 0xa26b1a72, 0xa36b0672, 0x5453f612, 0xfb4a997a,
+ 0x57e0d9be, 0x79973960, 0xaac79ca9, 0x7c80bca9, 0x672df80e, 0xcddf040d,
+ 0x066ca89a, 0x841ee03d, 0x953b0971, 0xc59e81af, 0x127f0df2, 0x9bbf2195,
+ 0x97186db9, 0x84f2a1c8, 0x6df2a35f, 0xad95117f, 0x7bb50f7e, 0xe54a5fc7,
+ 0xca97bf29, 0x2a72fed3, 0x6a3efcdb, 0x057f9ef7, 0xabf81f95, 0xff37fca9,
+ 0xf43f2a46, 0x77fca807, 0x59951d7f, 0x06fb4656, 0x9fca1396, 0x3948f40d,
+ 0x81b8f56f, 0x1cb905ae, 0xe63dc78f, 0xa478dc84, 0xfe30cca7, 0x271c94aa,
+ 0x66dc5126, 0xe757bfba, 0xa316c63e, 0xfdcd3e3e, 0x83a24748, 0xe1a554fc,
+ 0xc8bcc304, 0xd4bb5366, 0xcf6b6807, 0xe7b5cff5, 0x8d7f1d82, 0x10d1f6d5,
+ 0x0763ddae, 0xa5b4f47b, 0x5047faad, 0xf378fd2f, 0xced83b5c, 0x3ef78eb1,
+ 0x54c3967b, 0xab04e63f, 0xe6760151, 0x5783df6e, 0xa81e70b2, 0xbc7e93f7,
+ 0x4ce6ee63, 0x27d7279c, 0x500d77b0, 0x853ad5fe, 0x1bf2aff2, 0xa1a3e58e,
+ 0x14ad531d, 0x6b0bdda0, 0xde8af147, 0xebd645da, 0xe9593def, 0xf50f1092,
+ 0x01eda07f, 0xe508c94b, 0xbc2c5c63, 0x1bb7f35f, 0x1937499f, 0xe99dbc3f,
+ 0xcc9dfd26, 0xfee6a4f3, 0x91e7c07f, 0xfaf96dfc, 0x3be8cff8, 0x0a23ac1f,
+ 0x9631bbe5, 0xf00e9feb, 0x55ff719b, 0xcdfae02f, 0x3747e4e9, 0xdf7379ea,
+ 0x31bea993, 0x8ad2bb5a, 0x8a4ce6f0, 0x7ac7d487, 0xfdb173a2, 0x43d274d6,
+ 0xe5187d29, 0xded2edbd, 0x7261dd56, 0xeb97353f, 0x35c2655d, 0x8bea3175,
+ 0x8f0cc9ef, 0xef7e07da, 0x01dbd683, 0x66adee6f, 0xcc529efa, 0xd14a0f84,
+ 0xc937042e, 0xf3a124a3, 0x3a2fd518, 0x5dbafb82, 0x1b3a359a, 0x51107ae8,
+ 0x9d5ffe87, 0x4a5ffe42, 0x7e3e50df, 0xccab6a57, 0xf522d7f3, 0xbe316edd,
+ 0x86d851d9, 0x6f9fadef, 0xa4bc6377, 0xef58fd37, 0xf9e3e40f, 0xb7da2bb7,
+ 0xac3c8190, 0x7e3e7dc8, 0x2e15382b, 0x1e6bf727, 0x17363dcc, 0x8bd543ef,
+ 0xf1add8bc, 0x8adefa66, 0x283ae052, 0x58abf585, 0xb3b26e43, 0x62c72166,
+ 0x523bf53d, 0xfbb8ef28, 0xd7f68d3c, 0xc23cc1a1, 0x88bd74f4, 0x378e745b,
+ 0x2941dfa2, 0xd8a7ae2c, 0xa78d1a42, 0xbc7d33db, 0xf1bdff9d, 0x4f7c8976,
+ 0x28c73c7d, 0xd61cfae3, 0x439f5a36, 0x78fa41f8, 0x3d7d70bb, 0xe37c8de4,
+ 0xf0beb878, 0xd71b46f1, 0xd1b5b0e7, 0xf7121cfa, 0xdbc73a6b, 0xbd78f3d9,
+ 0x2237b38d, 0xf72f4fff, 0xdc13ff0a, 0x180e7643, 0xf9c6c534, 0x330b69f9,
+ 0x92bc039c, 0x1ff3edcb, 0x595f38f2, 0xc97ae36e, 0xfdd2b2e2, 0x8bae89a4,
+ 0x95af91bb, 0x173a663d, 0x26dfe253, 0x3c4e4b3f, 0xa7da24c5, 0xfe7c26b2,
+ 0x17bf89b4, 0x98f6b048, 0x5fd7b367, 0x2c333a34, 0x55a89dae, 0x6b6f309b,
+ 0xe195aba2, 0x6f128039, 0xf12bf5a5, 0xea1460f6, 0xd8098d5f, 0xfe83ec1a,
+ 0x8bdf50c4, 0x974f30b9, 0x15c5e5c6, 0xf9883d6f, 0xd0e58954, 0x9e3e186f,
+ 0xe4cc7c16, 0xb0b2b4f6, 0x791d42fb, 0x5cba1f1c, 0xc36fce47, 0xc6878e60,
+ 0xea2af049, 0x8e3c31cd, 0x3f70fa73, 0x7accc7da, 0xfb83da34, 0x063bd3fc,
+ 0x73bc1097, 0x9c01e52c, 0x0a763c3e, 0xed666bee, 0xd826669c, 0x3e315ac4,
+ 0xdde76b33, 0x929e7c66, 0x1dfe88c1, 0x5fa4ad67, 0x255ced67, 0x14d3ffda,
+ 0x0e645f6c, 0x1ae304fc, 0xed1d0f45, 0xb19b7183, 0x63fa178e, 0xbedcda79,
+ 0x7477bf01, 0x857eca87, 0x73779bee, 0x7d4d039c, 0x0b748ed9, 0x977ec5c6,
+ 0xe697cfcb, 0xe7858f30, 0xee29788d, 0xdb68fe30, 0xfc82bc71, 0x628ea69d,
+ 0x34f76e3c, 0x9cb027ab, 0xc84ad214, 0x9ef56c2d, 0x5b4a72c0, 0xbbba0975,
+ 0x9c361fa5, 0xb861b2c0, 0xdf8877ef, 0x2a8e0fc3, 0x49c60678, 0x68dceefd,
+ 0xb7d277f4, 0xa41e4e84, 0xee85b1b8, 0xf22dedb9, 0xde3049d6, 0x8ed7b75e,
+ 0x7c6f6876, 0x6bf499ba, 0x5a0af56c, 0x866880e7, 0xfaabdceb, 0x6fbfd0a2,
+ 0xef46e714, 0x2c4731f8, 0x7f3479ec, 0xbfe099fe, 0x1ed7aaad, 0x52a0724b,
+ 0xfc2283be, 0x49e67ab4, 0x3b284342, 0x1b8c413c, 0x3d70f5ee, 0x7ef8501e,
+ 0x036f9b19, 0x98ae8ebf, 0x29e8bb9a, 0x7f31b26b, 0xec1bdc1a, 0x50ed1657,
+ 0x883fa217, 0x06116ed7, 0x13bfc1fb, 0x743db8c4, 0x673a2e28, 0x172fe7d0,
+ 0x7c617f42, 0xad9ff386, 0x8fa7bd74, 0xf6160eab, 0x5ed3f041, 0x9f4fef1f,
+ 0xb760ec6f, 0x731b5ef8, 0x923e719b, 0xc3ac0f98, 0xb09f361c, 0xcebeb476,
+ 0x892d3379, 0x30f59fdf, 0xb996af7e, 0x3bf5b0e5, 0x44bb5e6d, 0x22acd076,
+ 0x33343aff, 0x28704bdd, 0x04fba73f, 0x1ac8eb91, 0xdf69e3cc, 0x051f6197,
+ 0x79a699eb, 0xf7e5ca18, 0x55f90f55, 0x78e580b2, 0xe3c987ee, 0xd84b3127,
+ 0x49f8e57a, 0xb41a6ed4, 0xb4e7f8c7, 0xf21a3ea2, 0x54d674eb, 0xc17df2ab,
+ 0x5f984c89, 0xfc866316, 0x4fc05974, 0x9650bf96, 0x71abc6e6, 0xe8392d0d,
+ 0x8cb03d17, 0xd76a8cf2, 0xf9c56b4f, 0x6bace526, 0xef7a8389, 0x2cee9c57,
+ 0xfb0dc79f, 0x790d91ef, 0x002bc9cb, 0xf75f3f0e, 0x07e06119, 0xaf9d7b43,
+ 0x8aa95314, 0xcfb9847e, 0x3059dd8d, 0xedc9d97f, 0x6cb87837, 0xf2f10f6e,
+ 0xf0257c6e, 0xc667d3af, 0xa7c24ce0, 0xb3bc70ac, 0x277ecd0e, 0x1bf113a7,
+ 0xd5e309fd, 0x3e62d880, 0x14894d7d, 0x8ea1fbc4, 0x012cf6ce, 0xa7491ae9,
+ 0xeec75b74, 0x957f5c2c, 0x23dbf299, 0xc47e0af1, 0x67c8699d, 0x1ea9e26b,
+ 0x3abe539e, 0xf6752266, 0x1b04f523, 0xed4df1e9, 0xddc1609f, 0xf8d64f3c,
+ 0xe0be293c, 0x8a429c9d, 0xcc9c6847, 0x0dacfac6, 0x8c62ba46, 0xa278f509,
+ 0xb4a182c6, 0xb4e7a75b, 0xa612c6f8, 0xceaba774, 0x7b7d2977, 0x10f2f3d6,
+ 0xea03b093, 0xf3d41cb4, 0xfff26609, 0x84e609bc, 0xd6f07df0, 0x725f7cc1,
+ 0xe90a2bdb, 0x4ede766f, 0x50b4eff7, 0x13f41f5b, 0x93335d27, 0xa9d6fe7f,
+ 0x834d8f63, 0x96aff272, 0xc9bb61d4, 0xbf46edb0, 0x372be862, 0xbf262c46,
+ 0xe5172da5, 0x3a1655f5, 0xb1f682d9, 0x827142d5, 0x536f9fcd, 0x35fd2127,
+ 0x7d3e7146, 0xb98323dc, 0x25a5fa9d, 0x9a7d25e0, 0x7e46b326, 0x6be3765e,
+ 0x3e3c4e9d, 0xb2c77944, 0xabddaf89, 0xbd935755, 0x3663c94c, 0xadb7c78a,
+ 0x21bc7b24, 0xccbca19a, 0x41ee9b56, 0x1765f678, 0xb37f4333, 0x2165b735,
+ 0x3f091f9e, 0x59aa8e73, 0x69a96226, 0x3f9db9fc, 0xe87aab9f, 0xc3cd5cf9,
+ 0xbf7c2b9f, 0x681aa77f, 0x777f43f3, 0xec6e712a, 0xcbcd4eef, 0xa8dbafeb,
+ 0xffec14fe, 0x47b4efd0, 0xebd45405, 0xfccd170d, 0x4d17ce7c, 0x2955befc,
+ 0xfce37568, 0x4f74cd0a, 0xba24fc0f, 0xf54bbd5f, 0x7deafdd2, 0x088c97cc,
+ 0x3670b57e, 0xc6afd1f9, 0xd5fee99b, 0xe5331eab, 0x642a0581, 0xf0521f7e,
+ 0x29e5abd1, 0x8e967e74, 0xdd7a44c8, 0x643f2763, 0x62441e2b, 0xdc7ef2fb,
+ 0x7fdcc85e, 0x9e2a3fd8, 0x2c6d3bda, 0xe0f914ae, 0xf2f94cb0, 0xe3cf1fdf,
+ 0xf4a1f298, 0xae6bfa20, 0xcbbca30a, 0x3f389385, 0x39454c68, 0xc469a198,
+ 0x987b35f7, 0xdc937666, 0x5740fbd3, 0xc2aee75a, 0x22fa4af7, 0x24d346bc,
+ 0x7d06182e, 0x1ef85351, 0x4ccf83c7, 0x0abbeff9, 0x49befbc5, 0x5d7c7087,
+ 0xf90b07ce, 0x774af5d4, 0x3f51a43d, 0xda49d88e, 0xc306804e, 0xfbff2800,
+ 0xf51cf0ad, 0xf74c9c42, 0xca1706c6, 0x97587521, 0x7e8b27dc, 0x94f90b07,
+ 0x2ce51a8f, 0x7e1190eb, 0x7eefc85c, 0x62fb9216, 0xce8c0dbf, 0x1837facd,
+ 0xc7cec1db, 0x522c7a84, 0x3f0baf8e, 0xdd0f1233, 0x79ebecf0, 0x0aeb5d9d,
+ 0xbad36544, 0x425d7ccc, 0x5b2a65df, 0x2aa679e8, 0x179c6e6b, 0xd70f786b,
+ 0x0c90ffdf, 0xabd02a0e, 0xe31b3cd0, 0x3202333c, 0xac99bba9, 0x37c5f48d,
+ 0x88ab7bad, 0x33ae4573, 0x06db7d72, 0x64bf5c4b, 0x37e4bcf8, 0x37e4cb25,
+ 0x6303d659, 0xe56bc70c, 0x23b79dde, 0xeece875d, 0x59da0433, 0x62a5581f,
+ 0x7a155a5c, 0xc4b5f2c9, 0x3b61ebf9, 0x7125abf1, 0x7df84e46, 0x24da919b,
+ 0x51c50875, 0x841c9eaf, 0x2d77c771, 0x3d48ff84, 0xc7086637, 0x637698f3,
+ 0x8bb8e45e, 0x7c7911d1, 0xdbc8bcc6, 0xc88bf7ae, 0xc888cbe3, 0xa8621be3,
+ 0x888eac9f, 0x171be3c8, 0x6c57c791, 0x4ce7a780, 0x9be3c88f, 0x28ef8063,
+ 0xbed0c7ba, 0x50d8b3cc, 0xb574a73f, 0xef4efea1, 0xaef806fd, 0xed0d87f2,
+ 0x0c6afbe7, 0x78acf7f5, 0xfa0f50c4, 0x73b8c7a2, 0x87ae10f1, 0x6d3c936b,
+ 0x103081f4, 0xfe0f6f78, 0x1dcaa480, 0xd9c7f6e1, 0x56a2fecb, 0x7d29e3d0,
+ 0xe248127f, 0x8f116671, 0x10c47705, 0x9d8d0daf, 0x517dc766, 0x444b4d9a,
+ 0xcd7ecebb, 0x585806ed, 0xc4e6f9c3, 0xdda94b07, 0x3a74d8fa, 0xfc027987,
+ 0xc0e81f6c, 0x77cf20da, 0x6f0017e9, 0xabf79e1c, 0xf5da1285, 0x78a56ebb,
+ 0x583ce76e, 0x5577f529, 0xf3ea2f9c, 0x43f18fdc, 0xecdbee1b, 0x54cf3254,
+ 0xe28e3f1e, 0xe9751eed, 0xc31a96e7, 0xd6451d7e, 0x164be500, 0x30ac5b06,
+ 0x8fd05adf, 0x97849af8, 0x55dda1ec, 0x3de9bb45, 0x127f1ab0, 0x96520fdd,
+ 0xe8160284, 0xbf27eab2, 0xf0e3e1f8, 0x1463e2be, 0x27f878a7, 0x7e21fcbf,
+ 0xc43fc407, 0xc871744d, 0xeefbcf1c, 0x874ba7fd, 0xbac65f51, 0x64625ee8,
+ 0x9b7de27d, 0x26eb7abe, 0x3c16fbf5, 0x37a5dbf8, 0x8ddeff7b, 0xd586b767,
+ 0x597f36f7, 0x613cc7e9, 0x356a907c, 0xcbd5c3de, 0xaabe0bef, 0xf8a56b1a,
+ 0x57c92ce5, 0xe5fcf28f, 0x707affd8, 0x45f7bc3b, 0x717bb5c9, 0xbfcf077f,
+ 0x1da1cf8f, 0x948bf5e1, 0x3cf8a92b, 0xfff80865, 0x58a36768, 0x6f7cf98f,
+ 0x8b7ee10c, 0x41d1589c, 0x2b04f3fb, 0xf65c87c5, 0xee3fa3f9, 0x447358cb,
+ 0xf71ea0bc, 0xf7a760e5, 0x1e88f88a, 0xf4417f2f, 0x92944473, 0x41ce9f3a,
+ 0xf7403d98, 0xb17f7562, 0x8b383c9b, 0x651bee18, 0xae10be45, 0xac125b17,
+ 0x54901f14, 0x4b77e52b, 0x2efa28ea, 0x7d1b04a2, 0x2872473c, 0x68cfb46d,
+ 0xf1451849, 0x86342900, 0x128a0ce2, 0x40defea2, 0x7ee024ba, 0x77dfb8c6,
+ 0x5d682bd9, 0x3acff7bd, 0xeb49f79f, 0x79889c61, 0x1f5878e0, 0xfc41ce39,
+ 0x9bda1c2e, 0xe31ef665, 0x4c86d71b, 0x4af48e3c, 0xbeefb5b3, 0xfdf5e51d,
+ 0x5eb2f59e, 0x307f9e62, 0x86673f0c, 0x605f13a4, 0x6c307f7e, 0x0fe3cc5c,
+ 0xe8038187, 0x60c1079e, 0x42d8066a, 0xb9f88351, 0x6f578d05, 0x3fc892d5,
+ 0x7487f304, 0xe7908dfc, 0x61af023f, 0xc3ec57b9, 0x635c83f7, 0x255f84f9,
+ 0xc800ed3f, 0xfb4fc21f, 0xfd0654dd, 0xfa365439, 0xe43faa35, 0x88f8222f,
+ 0x51f043df, 0xcf95297f, 0xfcf4bdfa, 0xc1397f39, 0xa8fbf53f, 0xa0aff26c,
+ 0xabf82fe7, 0xbfc97e09, 0xa39fe091, 0xe785985f, 0xbe547513, 0xfaa06fea,
+ 0x09fbfcd7, 0xa41fc37e, 0x4a3fe432, 0x9bf98fcf, 0x6fe13e08, 0x7f6df826,
+ 0x7f56e088, 0xf8ef952b, 0x29f9e8db, 0xa30487ff, 0x45fee23a, 0xe03f19d2,
+ 0xd9817125, 0xe25e7e8d, 0x4bb34582, 0x2e57de00, 0xd7617dd3, 0x41d2f97c,
+ 0x34278be0, 0xfb7bf699, 0xee299856, 0xfb95fba3, 0x16c7d62a, 0xaa5cfd53,
+ 0x268d486f, 0x12ff6cbf, 0x571fdd2b, 0x967f7256, 0xbda8552d, 0xfd532f92,
+ 0x92e62b13, 0x538f58df, 0xd92ae700, 0x1931d81c, 0x93322ddb, 0x111fdefe,
+ 0xe3ca4dd7, 0x4f293f76, 0x8faff7e6, 0xcfc20546, 0x629b2b29, 0x7355700d,
+ 0x30e3e072, 0xc62d59be, 0x1c991b61, 0xcfc7ddfe, 0xaf307ff7, 0x90f9d604,
+ 0x03ca4be4, 0xe0717c7c, 0x99d83cdc, 0xc3bdb332, 0xcce4f28a, 0x8d4ed9e8,
+ 0xebcfd3cf, 0xfe224e92, 0xe13269f6, 0x61b69f6f, 0x2fee265a, 0xddf4c816,
+ 0xf205c48c, 0xe99fb857, 0xfba65f37, 0x994acaa4, 0x816c81e2, 0x0363e059,
+ 0xfcdfbbad, 0x0eaf54b9, 0x7471453c, 0x6d13cad7, 0x016fd193, 0x1d11657c,
+ 0x39e2c50e, 0xbb88b26e, 0xa68f8fee, 0xf9c8b6bc, 0xf17bff8c, 0x33f009b3,
+ 0x8cfc47aa, 0x4f3f09ef, 0xfde3fb88, 0x222277c4, 0x977fa4f1, 0x7df109f5,
+ 0x1e06c0f2, 0x376c8fbf, 0x731fcc47, 0x2e3be8ce, 0x8fe93295, 0x23b82c03,
+ 0xf998e31b, 0x7e43dd32, 0xb3aad27c, 0x3f3e6107, 0x91ddf3c8, 0x2c9fed07,
+ 0x8ea18f91, 0xfde52b8d, 0x1f235c0f, 0x7e02be41, 0xda04795d, 0xe93bbf6d,
+ 0x7d94364c, 0x8c16ee03, 0x1f463abf, 0xf989f648, 0x161764f6, 0x80fbbf0a,
+ 0x2b4fc447, 0x651a3df9, 0x13dc9ee5, 0x3805dc7c, 0xb5f52bae, 0x0309f8a9,
+ 0x930edcf7, 0xf97eca05, 0xcf1c3af2, 0x49d24f76, 0xe0212f1c, 0xc7cbc7d1,
+ 0x9e2dbef1, 0x925bbf52, 0xf1bdd3d8, 0x37e1f4de, 0x79f5c1e9, 0x7f513ee2,
+ 0xe0f51fd6, 0x8a7696e3, 0x70ce0753, 0x38b4c83d, 0x3917bfba, 0x27f96f4e,
+ 0x649f8101, 0x886f3f1b, 0xe7476f7c, 0xf02025be, 0xf28cafd8, 0xe2cb26b4,
+ 0xf68cfabb, 0x4627ebdb, 0x726f9bab, 0xd403f31e, 0x1eafa0bf, 0x9fa263ce,
+ 0x1fbca994, 0x0267ef33, 0x44f0475b, 0xe4dc0d45, 0xe88f601c, 0x00fd8fc7,
+ 0x7bbf1f7e, 0x18adeec5, 0x42d77cb7, 0xc90e74b9, 0xcef49bb7, 0x1fda25af,
+ 0x2b0dccb9, 0x17f5878f, 0x9fa97c14, 0x48de6043, 0x79d7565e, 0xec055244,
+ 0xadf0c291, 0x88b8f7bf, 0xe3793fa3, 0x9bca58a1, 0x8510dfc8, 0x663edffe,
+ 0x2c503e27, 0x0c3f3521, 0x7f898a7f, 0xfe7227cf, 0x7aacf2c7, 0x7132805e,
+ 0x32239e14, 0xf519cf7e, 0x75fbcc28, 0xb77f939f, 0xd307c169, 0xfe3c0387,
+ 0x0fe74c9a, 0xfcd1a5ae, 0xcc1ff6fe, 0x86f46794, 0x677e1788, 0x63dd096d,
+ 0xf712c24b, 0x054fb8a7, 0xa626fc78, 0x9f7df085, 0x09c1fb42, 0xe173e5d7,
+ 0x0ab2097e, 0x22ee37f6, 0xb8f2f8a3, 0x6f70d90e, 0x6345cc6d, 0x84bfa07b,
+ 0x76a4dafb, 0xa144bb63, 0x15235dff, 0x7e8ffefa, 0xd7f5d06f, 0x64c5b97d,
+ 0xff49a227, 0x24c9a93f, 0x2a164fcf, 0x76ddb107, 0xfb84bb3b, 0xbb7cc744,
+ 0xc5a07a8a, 0x557a4d15, 0xfe4d1119, 0x6394f6f3, 0x9fc076f6, 0x2a07e46d,
+ 0x6c032bfa, 0xbb1883be, 0xab73edfe, 0x218d25e7, 0x5df5de3d, 0x3bb022e3,
+ 0xf282f978, 0x9decd699, 0x1579899c, 0xd8eefa66, 0x7ab73c7f, 0x2277f86f,
+ 0x307524d3, 0x84ec57cf, 0xe0dfa157, 0x418fb9c0, 0x33ea063f, 0xd7c61cf0,
+ 0x29217a8e, 0xf905babe, 0xb6395eaa, 0x85d0e282, 0x2d57a4f1, 0xea10eabe,
+ 0xc0ad7a89, 0xbadf2e1e, 0xdcaadc9c, 0xd5ce293f, 0xbffe49be, 0xe4dedfa9,
+ 0x2e5c95fc, 0x01c5bd77, 0xb77e7df4, 0x5ebec4fe, 0xdfdfc21e, 0xe079f42a,
+ 0xbd47b5ac, 0xd72866bf, 0xef224517, 0x297c5661, 0x567e7f7d, 0x3cc65da0,
+ 0x2e50cf50, 0x1c12fb47, 0x2fb0cf94, 0x7e30858d, 0xedcf981e, 0xe20ad903,
+ 0x538a74a7, 0xd4da9bd5, 0x0a43d200, 0x2e2e91b9, 0xefe187d8, 0x6ddfd478,
+ 0xf977d20e, 0xfc28be82, 0x63f41e3e, 0x852817d8, 0xe4d5e2dd, 0x6871ebbf,
+ 0x7e008efc, 0x82b687ff, 0xca3a82e0, 0x9b9df4cd, 0x7426f7c8, 0xaedbe118,
+ 0xcc89e11b, 0x629abdf8, 0xac9e11bb, 0x43a1e11a, 0xf6e2bef9, 0xa9f3e324,
+ 0x6fdc236e, 0x9994637e, 0x78a0ffdf, 0x0c147e95, 0xb8c03eff, 0x64017f58,
+ 0x60f7e20c, 0x21afb7fb, 0xe8ff507d, 0x7eff920c, 0xcae2226b, 0x8195b00c,
+ 0xf3e36a71, 0x2d859cc4, 0xaaed7e98, 0x87be2390, 0x2ce746d2, 0x73c30f80,
+ 0xf20b7cfc, 0x9e6ce1ff, 0xdc30d9ff, 0xc8e87937, 0xde1c79ae, 0xcfce9b33,
+ 0x035f562c, 0x28c74efd, 0x36d2ec99, 0x9b75d399, 0x35ba72a6, 0x5779d327,
+ 0x60b44aa2, 0x5d5f3645, 0x4723c61a, 0xc91e299a, 0x3df9e21a, 0xd3fae7f4,
+ 0x2c6241f9, 0xe773439f, 0xfa47dbfe, 0x40d89d97, 0x2afb03e7, 0x788efa64,
+ 0xf9403db2, 0x2bceb053, 0xce963886, 0x39f9f3b7, 0x50d7ac0a, 0x62bceb0f,
+ 0x101f97e4, 0xa2f5f49d, 0xf0c206bc, 0x081a7280, 0xbe699b8f, 0x940788e5,
+ 0x51e7f0d7, 0xba16ed99, 0xd3d62d4f, 0x7aeadc9b, 0x579c48a3, 0xd76c79eb,
+ 0x1e7a98c4, 0xff9106db, 0xe234ecda, 0x24f95ae1, 0x6b5c338a, 0xebed139b,
+ 0x2f418e49, 0x2f5c6c04, 0xde1db960, 0x7bdfb943, 0x1c54e163, 0x2044f50f,
+ 0x16147bec, 0x6dffa7c1, 0xc221b3bf, 0xeffb3f2f, 0xf9186a47, 0x9e208f9d,
+ 0xe39c072a, 0x77c5edf7, 0xb6782cbc, 0x3ea5cf07, 0xcb7aaf9c, 0xcae9af1b,
+ 0xbae3b5bf, 0xbfbc88a5, 0x5af8112b, 0xbfa5f02f, 0x274d457f, 0x2d695d3c,
+ 0x2786f7b6, 0x1327f426, 0x332f13fa, 0xbb3e2ace, 0xec634121, 0x9fdfe799,
+ 0x671d0327, 0x985b3ead, 0xcf9bf00a, 0xcfc39eff, 0x3fa97d9c, 0xec361d34,
+ 0x3df879f3, 0x9d8f598c, 0xa1a296bd, 0x85de26dc, 0x8a70c3df, 0xbe7d1973,
+ 0x092f78fa, 0xf1b5597d, 0x90671e1e, 0x357724bd, 0x01c52f2e, 0x70ef8cbe,
+ 0x5542f9e2, 0xd16b8742, 0xd57ef44d, 0xfbf97bc6, 0x0a353e98, 0x5cb889f3,
+ 0xfbf3d6cd, 0xfdf98d4b, 0xd22ae74e, 0x5016367b, 0xd9442f51, 0xeebe743d,
+ 0x3a26e619, 0x72b4c9dc, 0xceeebe7e, 0x5accfa42, 0x3fd1ea6d, 0xe7aa1d6c,
+ 0xd5be86fb, 0x2bdc4cb8, 0xda245398, 0xc65fe3a9, 0x7b34ee71, 0xf05fa2b6,
+ 0x482cc67f, 0xcf41b740, 0x75d21a7f, 0xadd0ef4f, 0x759cffdc, 0x496dc4de,
+ 0xff278f0c, 0x575f3871, 0xed009c78, 0xf9746f46, 0x3c5d1bac, 0x89ad0714,
+ 0xa8ba70f3, 0x48cdce1d, 0xd70ed897, 0xd7debc96, 0x113e8ddf, 0xf82ab8f8,
+ 0xe42bfd1e, 0x9fc26fd7, 0x4f3d1f4e, 0xcee4c6ac, 0x40e67f22, 0x147c437f,
+ 0xaf6e0236, 0x76fe67a3, 0xc88f7d87, 0x38a5e49a, 0xcb5e2593, 0x9ae67cc1,
+ 0xe63d49bf, 0xe30f6777, 0x6766f37e, 0xaf17dd34, 0xbee95a71, 0x27738b5a,
+ 0xaecd3f43, 0x94bc236c, 0xe618eb38, 0xb3a6d5d1, 0x06edfe26, 0xad715e63,
+ 0xef5e6ef3, 0x9dacb3e2, 0x2e31eba6, 0xb4e7b5cf, 0x8103b418, 0xaf2edfd3,
+ 0xbfe76e58, 0xbd5bd25b, 0xcf1a6e33, 0x295a762b, 0xb18a58af, 0x5794f756,
+ 0xc7c117fc, 0x78beb82d, 0xa78f0f5c, 0xbbb2ebe9, 0x3e23fe79, 0xd59a78c7,
+ 0xafdfa3ed, 0x97ffd7d1, 0x7a2e9ca1, 0x9abb9b7b, 0xac97dea1, 0xacf51b9a,
+ 0x884fbe24, 0x4c272476, 0xffe3ea5f, 0xef85a869, 0x4a953597, 0x8ddb9db3,
+ 0x39eebf59, 0x30f47c3f, 0x9dc92dd3, 0xcdb337ce, 0x97466f3c, 0xd58ab9ef,
+ 0x5cc37e83, 0x7af28925, 0x2fea02e6, 0xffb585c6, 0x1efc5dce, 0x2125acaa,
+ 0xee3fbd3f, 0x07df97b6, 0x2e983df0, 0xa9bde9e2, 0xf59fba16, 0x7079899e,
+ 0xb79919eb, 0x4ec6f5e8, 0x1de3edc6, 0xa2d6ce33, 0x620c6638, 0xb0e43f74,
+ 0x78e762b3, 0xccc3fe46, 0xae60d061, 0xde326caf, 0x9e5d98c7, 0xafb616ff,
+ 0x8f407612, 0x49f55717, 0x91fe520d, 0x6c339be4, 0x3f8dc624, 0x6242559d,
+ 0xdf4a91df, 0x4f6aecbd, 0xf6b0e371, 0xd3fb45f3, 0x1d71c469, 0x2b83ddf4,
+ 0x3e8bb1ea, 0xf287d137, 0x8bf12221, 0x9dff0a74, 0xa07f5d35, 0xfe1167dd,
+ 0x48fc3879, 0x13dd394c, 0xbd57edd0, 0xf578e7a5, 0xbd0986af, 0x38adcba9,
+ 0x1f33b087, 0x4c91345d, 0x1ea7ee5e, 0x67d9f67d, 0xea7e5d5d, 0xf49f610e,
+ 0x8333a27e, 0xf98d1954, 0x549a502a, 0xaca3f10f, 0x60052756, 0xdaffdb9d,
+ 0x27f7fdf3, 0xf01e7975, 0x2fb61260, 0xb072fb71, 0xdf17cc8c, 0x072cba96,
+ 0x34db72e5, 0x946aeedd, 0x9cedbe37, 0xbe7437fb, 0x1bcf0efa, 0x9d90196f,
+ 0x4a517988, 0x59be45ab, 0xe415a65e, 0x3d137dd5, 0x3ff7156e, 0x631b1db7,
+ 0x36f4f8c7, 0xcf0da0a5, 0xf129b777, 0x536db405, 0xde901e78, 0x5e78515e,
+ 0x78f1a29e, 0xbcf0a2b7, 0xa77f3d39, 0x84dbc065, 0x03ddbd0f, 0x8d15af82,
+ 0xd288e3df, 0x5d9da81a, 0xb2f7d2f6, 0xe28cf1ec, 0xff957652, 0xa67450ee,
+ 0x907bd999, 0x2cc3b5d7, 0xe5b61f64, 0xa24db415, 0x146ec9f9, 0x05496d93,
+ 0x1147a449, 0x8d7ef0ef, 0x316f13a3, 0x0a9fc788, 0xd4fdebbc, 0xde75f0b4,
+ 0x417771bb, 0x23f45f49, 0x5f9087bd, 0xec8b29b7, 0x7246ef78, 0xbfb4de14,
+ 0x432661e6, 0x7f57663e, 0x7f450a97, 0x24fec53f, 0xfd8a8147, 0xbfcf5859,
+ 0xe8b6f8bb, 0xef3defe7, 0xfa360cc0, 0x226308de, 0xd494268f, 0x2761f9d3,
+ 0x631cf0fd, 0xfef7f744, 0xbd677edb, 0xfe09de31, 0xbf516fe6, 0x7b9de654,
+ 0xe13d127b, 0x68d6e6fe, 0xbf742fae, 0xfb795651, 0x0f7e66ad, 0x9abeff55,
+ 0xb1ca47ee, 0xdd743c46, 0xb874e303, 0xc838f2aa, 0x7c518555, 0xafae5226,
+ 0xb86e3a9e, 0xd8768147, 0x2c71fc23, 0x0cf4cfd1, 0x2e2973c2, 0xa3dcbadf,
+ 0xebfd444e, 0x1f7f7728, 0xa8a4abbf, 0x30b7ca66, 0x5f12ff01, 0x9243de77,
+ 0xc6cff47a, 0x3574e70d, 0x24685625, 0xb7284ae7, 0xe03f3927, 0x728b953a,
+ 0x1ecba07d, 0x03aeb8ab, 0x1389dce7, 0xbf5ce4c3, 0xbff7a21f, 0x3564e4fe,
+ 0x74df5d7c, 0x6e79c2ff, 0x8f64fde7, 0xff1edc5d, 0xd8c7df6f, 0x40aeb2ea,
+ 0x326cdffb, 0xc391e5ea, 0x86d63eb9, 0x75e0f88b, 0xb3b7ee99, 0xe1b4bea1,
+ 0xd98b3f80, 0xf97a8e5b, 0xdfdf3540, 0x1499b1ca, 0x7eb03987, 0x829e445a,
+ 0x30f0d06f, 0xb3aa2c79, 0x85abbe92, 0x03ed077d, 0x491ae823, 0x3afe9d2f,
+ 0xe7e728ec, 0x27bd3a72, 0x91212a26, 0x89fe4c07, 0x09997e2b, 0xdcab9af5,
+ 0xb039f267, 0x81d91b7d, 0x115ddade, 0xaf6f4ffa, 0xce0aff60, 0x73e280af,
+ 0xa0e75057, 0xfcf6a49f, 0x51976cfb, 0xec7e0498, 0xb1e72eb0, 0x2bf62aa9,
+ 0xab793f09, 0x51af6fc8, 0xb09eed0b, 0x42d8a5f7, 0x3e30a4fb, 0xde25e9a9,
+ 0xc7ae1fe4, 0xefb4439b, 0x4810efd7, 0x9e60d7e8, 0xee5f22a0, 0x7ed0478c,
+ 0x9df0d4a2, 0xdefc7d45, 0x5f39edcf, 0x690b555f, 0x018f281f, 0x0bfc017f,
+ 0x8192ec53, 0xbe2d3764, 0xfcc44e7f, 0x28dadf95, 0x2123f79f, 0x3e42ed9f,
+ 0x0163d37b, 0x2d2e8c76, 0xf027616e, 0x49f008d2, 0x49f20c41, 0x70d98a4d,
+ 0x9b97a3ae, 0xe26f3ac4, 0xbf0f54e7, 0xc1e73f35, 0x39f83de1, 0x9f84c7e8,
+ 0xe2ffa3cf, 0xe89bd309, 0xf07a78bf, 0x62cdea73, 0x53ce27ff, 0xcddc5b4f,
+ 0xd39780ed, 0x3be86213, 0xf87d193f, 0xe8d3df3d, 0x7f8015f7, 0x4cd9ccf7,
+ 0x532cd624, 0x843a77e7, 0x0608c99f, 0xca276f3f, 0xaef31945, 0xd5bddfc2,
+ 0xdf8988e5, 0x3a26f9a3, 0xe0dc06cf, 0x3de3b6bc, 0x87ba3cbc, 0x39d3da57,
+ 0xfe4eb1de, 0xc7a61301, 0x401f08fb, 0x5a38b09d, 0x4460f8b7, 0x31c3103c,
+ 0x19c5f99d, 0xbf6fdbdd, 0xf9f8a261, 0xe20b1f2e, 0x51dc02ef, 0xbddf8c64,
+ 0x76d9f225, 0x7f24612d, 0x429a72bb, 0x6a245fe8, 0x65f1e28c, 0x39fb631e,
+ 0xbddf91a5, 0xeef9c636, 0xe7225af4, 0xebb5df4b, 0x7fd7d627, 0xff8a2acf,
+ 0x22fdc645, 0x3eb47de3, 0x3c8523b4, 0x1854afee, 0xf51cb8f3, 0xd8bbe833,
+ 0x714af860, 0x3314ae7d, 0xa3ac38c3, 0x2dcf323c, 0x21ecf020, 0x59e3a665,
+ 0x92899eff, 0x6bdfe66f, 0xf546dc0d, 0x7e1dbe7a, 0xaba27177, 0x3aca5d6b,
+ 0x117c9f31, 0xbcf40dcf, 0xd7185dae, 0xbce8bcc4, 0xd084d036, 0xc605ce1f,
+ 0xf460ae49, 0xb75857bd, 0xf0e25ce1, 0xfa262d9e, 0xa31f0f1d, 0x1e01a1ef,
+ 0xcc16e78c, 0x5850f147, 0x039ce1bf, 0x238069d6, 0xe4df01f7, 0x93de1fff,
+ 0xa277e3de, 0x278f52f5, 0x61338b75, 0x2fa48007, 0xbdf38b86, 0xfa286ca1,
+ 0x06fe4a41, 0x1495c3a2, 0x72cb5f9e, 0xdbdf3e7a, 0xf7e1fd09, 0x72887e93,
+ 0x01718092, 0x04def866, 0x0f74c8f3, 0xe7c454c0, 0xe5ebea6a, 0x48c79742,
+ 0xccd16dbe, 0xa684798e, 0xea0f6882, 0x600d9b13, 0xf8852efc, 0xee24b74e,
+ 0x283ffd3f, 0x00812bd4, 0x0000812b, 0x00088b1f, 0x00000000, 0x9095ff00,
+ 0x50c34b31, 0x97bf8514, 0x4a36ac46, 0x1056dac1, 0xa8508a09, 0x755a5095,
+ 0x97375433, 0x221d0e8c, 0x38ba383a, 0xfc5d251b, 0x09f9ce01, 0xe6e284fe,
+ 0x482ae0e6, 0x22bf8290, 0x26a697de, 0xcbbd0820, 0x77dde779, 0xddf73dce,
+ 0x2e8dcc2b, 0x5eca7550, 0x75619047, 0x444506d2, 0x9aea1152, 0x47e17536,
+ 0x3cd6a5a4, 0x7c22c128, 0x4c12092e, 0xecbbaa75, 0xfbd45ab2, 0x5ffed246,
+ 0x73e4ec6f, 0x7569fd73, 0x27e7cad2, 0x22ff8eba, 0xba77e898, 0x00839d12,
+ 0xe4e3e1d6, 0x65f68fbd, 0xc8773d13, 0x5f94dcac, 0xd53da3e8, 0x3970079b,
+ 0x3adf376b, 0xdbe20d46, 0x0aa8f38a, 0xa567047b, 0xfd398f74, 0xed34737e,
+ 0xb0a56f2d, 0xef37e657, 0xbf89695e, 0xc21b71a5, 0xc1ec8481, 0xc81447a8,
+ 0xbe0daad1, 0xb9417dcd, 0x3e99cb8b, 0xbf05c593, 0x67eb81f0, 0xf3ba7931,
+ 0x8416bf0f, 0xcb62bcbf, 0x5f1dd7ff, 0x7f74f68d, 0x6b7d238c, 0xbb92f72c,
+ 0x50a8dce1, 0xd9f695f8, 0xf4112ed5, 0x738dbcf3, 0xf3e569f1, 0x742b007e,
+ 0x02505747, 0x00000250
+};
+
+static const u32 csem_int_table_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0xe24bff00, 0x51f86062, 0x38cfc10f, 0x90981819,
+ 0x770143f8, 0x01684331, 0x21060616, 0x62636620, 0x22676060, 0x072bbf5e,
+ 0x9d877d82, 0x1038e181, 0x781f67df, 0x5e240d7f, 0xbb3f4dcd, 0x2ed1d37e,
+ 0x7e27f062, 0x02af8606, 0x058b0c0c, 0x210b7c21, 0xfccff954, 0x18a47608,
+ 0x02a57665, 0x150003f5, 0x8051b77b, 0x008051b7
+};
+
+static const u32 csem_pram_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x7dddff00, 0x45547c79, 0xbedd70b6, 0x97a7774b,
+ 0x42c84274, 0x4010dc20, 0x804d8854, 0x024de3b0, 0x10602a31, 0x66b71c11,
+ 0x04484b0f, 0xd3ce7cde, 0x0831baf9, 0x544e38e8, 0x387c0666, 0xa8d041af,
+ 0x1a0c1a51, 0x166bc3b0, 0x26665419, 0xb8c38e3a, 0x6c8a89bc, 0xfd011242,
+ 0x5f283798, 0x3b75539d, 0x4dba6f7d, 0xe3fbe65c, 0x45a7efcb, 0xeab7badd,
+ 0x9cead9d4, 0x25aaa753, 0xd7a92059, 0xfe197212, 0x48a6f968, 0x51d11908,
+ 0x1fb715b6, 0x04846927, 0x6dd5915e, 0x7fc22102, 0x0ed722b9, 0x16c8e427,
+ 0xf5a56821, 0x21075ec8, 0xd3767eb4, 0x9735a0b4, 0x0e057d90, 0xbb3fde0d,
+ 0x25eb08b5, 0x96e2febb, 0x2ee57b68, 0x65ba8251, 0x8b7729ef, 0x6b2a9093,
+ 0xe963a3f3, 0x225df6f3, 0x228742d9, 0x490b1281, 0x8db8e427, 0xac8bbfb0,
+ 0xaacec0be, 0xddf79b95, 0x3456fd05, 0xf69d895a, 0xe17bb953, 0xbeb4b1d4,
+ 0xe04cb0f0, 0xab6dca95, 0xbeb45e94, 0xa0842828, 0x0fdec0fe, 0x62b69c70,
+ 0x4c1a1152, 0x8dbf69c8, 0xbad057a8, 0x067d39bb, 0xb838be7d, 0x5fde14a3,
+ 0x2d782f5c, 0x9bc5fdf4, 0xfe819df6, 0xfdc83717, 0x92ffda45, 0x0751073a,
+ 0x132fb1b1, 0xa9fcc798, 0x1be56f00, 0x7ad2b132, 0x0a15a5c5, 0xb5491c01,
+ 0xc60bb94a, 0x5d514c7f, 0x1c61ce30, 0xe567c747, 0xfa1c7473, 0x0497b2dd,
+ 0x996d4c2f, 0x9e00f885, 0x59f6ddd6, 0x5e613b4f, 0xf08194ab, 0x0ab5eefd,
+ 0x3830b7bc, 0x0abb15fb, 0x4a566df0, 0x9b4dce01, 0x3b830595, 0xf7525bfa,
+ 0xe3ae0196, 0x7c32f21b, 0xf2e6ed31, 0xd5109fb4, 0x4c5f51da, 0x02721688,
+ 0xda6541dc, 0x17e78e90, 0xf7a41484, 0xa8913a92, 0x29fe8eb6, 0x49e90861,
+ 0xfa17ffff, 0x2683e04f, 0x6e5b7057, 0x7b96bd07, 0x0ed5bfe8, 0x70f39d7a,
+ 0x85ed49fa, 0xe5ebfdb1, 0x0a0740a3, 0x83dfad4f, 0x4cfee3e5, 0x55fbd72c,
+ 0xfc6fdbc4, 0xe0dcb083, 0x27f3e2f7, 0xdcb0a3fd, 0xfcb0d7e4, 0xcb0cbf9d,
+ 0xdf1cbfa0, 0x859fe2db, 0x0fbf56e5, 0xafe33f9f, 0x5fceb2c0, 0xf79fcf8d,
+ 0xbd658bdf, 0x5fcf803f, 0x32c3aff2, 0x72c5afe4, 0x96037fa7, 0xbe20fe0d,
+ 0x0ebf8af7, 0x087f46cb, 0x37f1ef9f, 0x47f61962, 0xf40bdcb0, 0xdfc465a5,
+ 0xff7ee58c, 0xfa0f2c51, 0x43bbf05b, 0x3e5893fe, 0x1eeef1c2, 0x8a248a47,
+ 0x3c46b737, 0xea485c54, 0xa648ad64, 0x5672d4f5, 0x5023bf4f, 0xba7ad0a4,
+ 0x1e29d68f, 0x148d2d7b, 0x57bd6959, 0xb9cf6b35, 0x68db149f, 0xdac0273d,
+ 0x15a23dfb, 0x5fbd69db, 0xb81f6b2d, 0x449c5029, 0xac8303eb, 0x48faaafd,
+ 0xafd683b1, 0xfcf6b10a, 0xd2712930, 0xd5847e7a, 0x25688e0b, 0x682f5a2e,
+ 0x0fc2f566, 0x5a6e2503, 0xdf616c2f, 0x2913398f, 0x31f5a649, 0xc27daced,
+ 0x43d13225, 0x808813eb, 0xd16762f5, 0x2f5a14c4, 0x697ab0f6, 0x1a92d9ef,
+ 0xcaf6ff87, 0xe509732d, 0x4dc0ba85, 0xeb45949a, 0xe20acb4a, 0xcc0cf8a5,
+ 0x26447ac2, 0x48fda0f3, 0x8d26b660, 0xac8575a6, 0x0efff684, 0xfdf6c62c,
+ 0xeded8ab2, 0xbed81581, 0xddb1515f, 0xac7eeab2, 0x6c35941f, 0x20f55b4f,
+ 0xd1507fbe, 0xaae07db0, 0x487eb147, 0xa8fb61f6, 0xf7c5bf55, 0x6c3e290f,
+ 0x50757c7f, 0xffeb489b, 0x00b6f821, 0xbe08d75f, 0xfc07920a, 0xa72cca1a,
+ 0x2046bafc, 0x1e3e40b3, 0xf2a6a606, 0xd14b26b0, 0xfdedbf40, 0x5169f0ba,
+ 0x069dbce0, 0x3ccf05f5, 0xbcfd8b9c, 0xb4c8fd80, 0x7eebb11f, 0xca337c26,
+ 0x6f84cfd0, 0x1a7ef42a, 0x7b1abde0, 0xfbd9faf7, 0x3c2318cd, 0xfbd62cdf,
+ 0x5c7ec269, 0x84d79bdd, 0xf08ce3cb, 0xf7aa5e5c, 0x49fb0873, 0x113c1ee9,
+ 0x9fa1a479, 0xef50bc88, 0x4fd84fe7, 0xa3c1eecf, 0xfd0da329, 0xbd22ca68,
+ 0x4fd8a39f, 0x89faf756, 0xf08d6328, 0x7ef44b28, 0xfa7ec63e, 0x9a5e6f74,
+ 0x1e11bc75, 0xcfdea56b, 0x6e7ba469, 0xefd9faf7, 0xbf67e232, 0xf39f8a2b,
+ 0xee80cf08, 0x6dd8abcd, 0x3bb14fc4, 0xd84b9f8a, 0xebdd95cf, 0x88dbbf67,
+ 0x28eefd9f, 0xe601647e, 0xf37ba435, 0xe2364e2a, 0x8a3938a7, 0xf000b71f,
+ 0x3c1eed0c, 0xf11a7b07, 0x1467b073, 0xcf08193f, 0x33c1ee88, 0x9f88dd31,
+ 0xfc51e989, 0xe8cf08a8, 0x3073f5ee, 0x839f88dd, 0x5cfc51e9, 0xef8cfd89,
+ 0x6626bcde, 0x3133f118, 0x029f8a23, 0x57c8a7ec, 0xda10f087, 0x3f712b8f,
+ 0xf118fa87, 0x144fa873, 0x9fb1633f, 0xbc9fb449, 0xcd29fbae, 0x34a7e231,
+ 0x899f8a27, 0xbbebe788, 0x1ca1cfd7, 0xe50e7e23, 0x0533f144, 0xbdd299fb,
+ 0x35f69579, 0x2fb4a7e2, 0xd2b5cfc3, 0xe8675c50, 0xe915e9da, 0x2ef5d727,
+ 0xbefa04d2, 0xd17561e8, 0xf76025e3, 0x433dba88, 0xbe91359a, 0x294facef,
+ 0xdac49878, 0x0277c535, 0xcad45c7e, 0x926bb58b, 0xec192547, 0xd52d14a8,
+ 0xd651ef50, 0xcf7ef0cb, 0xf6867ef2, 0x1957598c, 0x057cb3da, 0xc5767a86,
+ 0x7dfbc318, 0xf50d8baa, 0x60def7be, 0x70373f78, 0xb79ea1b3, 0xf78627ee,
+ 0x31ced407, 0x61b15fb4, 0xcafda1b1, 0xfd4372e0, 0x377fbaea, 0xf4243fbc,
+ 0x9afda180, 0xed0d87c6, 0x1b8f2343, 0x3f0ec3ea, 0x447f7869, 0xfb4316f3,
+ 0x1bcfa3c8, 0xecb747da, 0x9ec7d434, 0x7f7863dc, 0x437efb7c, 0x6f8bdafd,
+ 0x222fde1a, 0xdbda367f, 0xef0c0fb6, 0x6a7cf24f, 0xf32ebf68, 0xea9d9373,
+ 0x9abf1cf4, 0x2b9045d7, 0x20497e82, 0x357b414b, 0xaeb052e2, 0x3f3272f4,
+ 0x3d40b5c5, 0xd947f946, 0x434d573f, 0xd47fa4be, 0x55ea286e, 0x7d0b4571,
+ 0xbe31d3fe, 0xf9f43c2b, 0x35df154f, 0x0df6389e, 0x648137e5, 0xa05aa942,
+ 0x95afb734, 0x6717bf19, 0x31f81a5f, 0xd2cabefd, 0xd685303e, 0x2145897b,
+ 0x04578f90, 0x49d5da0b, 0xf786a922, 0xfd04ac92, 0x85b9b5a6, 0xe462074f,
+ 0x6a1f5d61, 0xfd1d0867, 0x997d93ae, 0xfaad4768, 0xce760028, 0x5e743e9a,
+ 0x4d7908bd, 0xe81228f8, 0xb3efbf4f, 0xfb47d320, 0xcfd42ab3, 0xa15f1d88,
+ 0xf1c60fe3, 0x870f2023, 0x9d11fc60, 0x1bf6b7c7, 0x96df1865, 0xdf186153,
+ 0x3df1d0a6, 0xf55c3fd4, 0x129f1f19, 0x6f210c61, 0xf8e19f09, 0x1c0a9cd6,
+ 0xfd42ad7f, 0x93f1d8ae, 0xc337e3a2, 0x344bdffc, 0x8c637eff, 0x6c59cff3,
+ 0xe6c2bf9c, 0xb3aafeff, 0x9c24fc7c, 0x59c207ff, 0xc59cff36, 0xd656fe6c,
+ 0x777c746f, 0x302dff14, 0xe304f1fe, 0x19c6f35b, 0xa977dfe7, 0x3656fe71,
+ 0x5f55e9fe, 0x389df1f2, 0x97c2e7fe, 0x977dfe6c, 0xd58af8e2, 0x51fe05e7,
+ 0x83aa93b2, 0x9bd27c74, 0x600cbe2a, 0x940e3a17, 0xd0a95283, 0xe84db210,
+ 0x34fc7087, 0x57dbf189, 0x50df9449, 0x39f0059f, 0x59cd5209, 0xce46fd48,
+ 0x8bea4beb, 0xd87bd014, 0xf9adfd4e, 0x8d79d41c, 0x5937f222, 0xa00e0d6f,
+ 0x8a36b6f0, 0x5bcfa801, 0xfa083e3f, 0xee4acab5, 0x24ef872e, 0x9fe78112,
+ 0x96c87afd, 0xcb9979d8, 0xf1f2b5f9, 0x8b791896, 0x64c581fa, 0x6f853550,
+ 0x88c13012, 0xd427fa8e, 0xf8c7038f, 0x10f7ea43, 0x2a7cffea, 0x9bfef1b3,
+ 0x6f507bfa, 0x3a1efea1, 0x7e1564ce, 0x377bbb47, 0xce5fc293, 0x6244ffe1,
+ 0x1dc9faf2, 0xe5403042, 0x0d9fabf3, 0xeefaff45, 0xe9141d7b, 0x0ecc701d,
+ 0xe9d430f4, 0xa74002bc, 0xe0d6ddf6, 0xabf10116, 0xa1a6be02, 0x77321268,
+ 0x75c5365d, 0xdd7ffbc7, 0xe090e53b, 0xa256e426, 0xfdf419c9, 0x7d0a573b,
+ 0x19dc743c, 0xad80b59a, 0x05b65a43, 0x5b649ae5, 0x73721146, 0xf69950c3,
+ 0xf269a640, 0xe3312d27, 0xd6332f4e, 0xeb1b9467, 0x5b26b2ad, 0xd3ad5c28,
+ 0xf699b204, 0xb196733b, 0xbfa71f5d, 0x99d19525, 0x714e578f, 0xcd1f4592,
+ 0x1e00b284, 0xb3ce907b, 0x1d5bec3c, 0x32b9aa9e, 0x1f1fa089, 0xae8049e8,
+ 0xef7c3481, 0x6f361e27, 0x64b3bc33, 0xe74e569b, 0x18b66b39, 0xc336fe04,
+ 0x875efeff, 0xe5a7c966, 0x626427ba, 0x331f3ce9, 0xccf9b7fc, 0xb0c909f3,
+ 0x615edfce, 0xe6f8ce7e, 0x27ffa738, 0x3cb41fc0, 0xe141fc01, 0xa3f9c63f,
+ 0xfe32af43, 0xa6fab2a8, 0x6fb43f02, 0x95d20914, 0x9cadcbf3, 0x1ad7e65f,
+ 0x9f1082f9, 0x385c740c, 0x3878284b, 0x72660f86, 0xc1b8583e, 0x927737c8,
+ 0x87159c80, 0xdfadb72e, 0xdaa660fc, 0x711f7e79, 0x91fdb9be, 0xce9f887d,
+ 0xba7464f3, 0xcee9d38b, 0xadfb636a, 0x7277ae9c, 0xf0daceba, 0x7d54ebd8,
+ 0x41a89f90, 0xeabde419, 0x2d9e9d3e, 0x38fa7a06, 0xde70cd3d, 0xd779e9c5,
+ 0xcd3d18cf, 0x7a70b6f0, 0x2f386cb6, 0xe19d7e93, 0xf777c335, 0x83e69dbd,
+ 0x81d9ad71, 0x6aacf4f8, 0x2c715a2c, 0xe86579e6, 0x62c715fa, 0xdd496ce4,
+ 0x517d4334, 0xfbc336f0, 0x36cc370b, 0x5dafcfb4, 0xbb9f6864, 0x7d431eee,
+ 0x8667e076, 0x77beeff7, 0xcefda195, 0xed0c87ea, 0x663c57b7, 0xdbe6dfa8,
+ 0xe67f7868, 0xf686cdac, 0x19cfe519, 0xed97a7da, 0x69a7d430, 0x0bef0dbb,
+ 0x6df5177b, 0xf7d575c1, 0xef10199f, 0xf9159bfc, 0x74efacd4, 0xafcc78bd,
+ 0xfee3f3e2, 0xf49e5841, 0x69f9f17b, 0x572c28ff, 0xeba6fe81, 0x2b376582,
+ 0xdd9f1eab, 0x9742f817, 0x6f654f8b, 0xaed9e80e, 0xbefea1f4, 0xbfd1ef59,
+ 0x8a7678ec, 0x48152e5e, 0x6d83ac39, 0x9fd74edc, 0x4ecc2ddb, 0x2c01e420,
+ 0x6e4c2a97, 0x2accee97, 0x47a86e26, 0x133b5606, 0x02424bf7, 0x6d7e67ce,
+ 0x85ce019e, 0xc136ae1b, 0x6af905b7, 0xe1987051, 0xb1ba92f9, 0xecceef86,
+ 0x65be1113, 0x61a3e320, 0xdf7f2b39, 0x7233fa02, 0x10fa6720, 0x00fb5780,
+ 0xd13d8deb, 0x2fe33b9e, 0x006c715b, 0xcb1cb9e0, 0x5859fe93, 0xb0fbf71e,
+ 0xc0afe63c, 0x357f13f2, 0x7bfe2d96, 0x7f6ffcb1, 0xfd0fcb00, 0xdf7cb0eb,
+ 0x51e58b5f, 0xdf2c06ff, 0x7cb107f3, 0xe5875fd7, 0x9610fe3b, 0x2c46fecd,
+ 0x961afd5b, 0xf0c4bcba, 0x18acdf4b, 0x9ff5d17e, 0x724f1fae, 0xfc0d397e,
+ 0xb62f8f12, 0x84e2f918, 0x617c8d5c, 0x3a6687d6, 0xf7dff598, 0x3f2987e5,
+ 0xd0743f12, 0xef44db3b, 0x9de8aebc, 0x7bd0c629, 0xe0c3c58a, 0x05fef4e1,
+ 0x5ec71bc0, 0xfb8b049f, 0x483b1888, 0xfac0b22b, 0x2fef9cb0, 0x3f5807d0,
+ 0xa1aec7c7, 0xbda335dd, 0xfa041c14, 0xffa0dcf8, 0xf9f10819, 0x51294773,
+ 0xcfcf1372, 0x7884bf4c, 0xabe8f180, 0x2e94820b, 0xdbb73a3d, 0xed5e1893,
+ 0xe8465216, 0x80d0f17a, 0x0673bc67, 0xa9225d63, 0x3bd07df0, 0x5fa715cd,
+ 0x7e02836a, 0x8d6bc2bb, 0xe87cabeb, 0xff93f8ef, 0x8a72842c, 0x49a1d985,
+ 0x87b44407, 0x2f69e449, 0xefaa37e0, 0x884cdead, 0x500fb763, 0x931eb83c,
+ 0x02fe2312, 0x3dfc06c5, 0x8cd47144, 0x266d59eb, 0x57ffafe2, 0x81bab303,
+ 0x64f4aebf, 0x039cf857, 0xe017fef3, 0xd5fd2bb3, 0x9a22de95, 0x9d2352fa,
+ 0x21dedb7f, 0x30ab0f05, 0x5be3b7ee, 0xc332b7df, 0x7c8ef813, 0xf3ae96dc,
+ 0xa10e7371, 0xf2e59ce3, 0x8ae1ae72, 0xb44ba064, 0x29e82e9f, 0x3947d7fc,
+ 0xe6cebfa0, 0x6b5bfb1a, 0x21592fee, 0x5c7435c2, 0x6490a297, 0xbe885642,
+ 0x06fd115a, 0xfc004b6f, 0x6f0ebdf1, 0xd8fe0a8d, 0x54463fe9, 0xb7e8d9e8,
+ 0xb4fc3b9f, 0xe59bfc1b, 0xb1f56299, 0xcbd47438, 0xb56e50ca, 0x680fd633,
+ 0xd5cfd634, 0x9c21650a, 0xcb7c9a97, 0x3c075810, 0xd064c7d5, 0xea5899cb,
+ 0x54cf2cfd, 0x7f4a1c70, 0x53ea47a6, 0xf69ccf50, 0x1fbdf0db, 0xfd448e1b,
+ 0x40d1c074, 0x83dfa53e, 0x4bce5d88, 0x39427efc, 0x10282e90, 0xf961248f,
+ 0xecdff02b, 0xfdcbbff4, 0xeb095fa0, 0x2155bf7a, 0x06bd6031, 0xc61bd79e,
+ 0xfaa9dfa3, 0x977c2c1e, 0x7224de58, 0x4a77e75c, 0x7ef837b7, 0x7b3a92f1,
+ 0x4c2ed1b5, 0x1aabd431, 0x760daab3, 0x0c03fc22, 0x02410ae1, 0x6729777b,
+ 0xb9c936bf, 0x2b68f80e, 0xdf80fb04, 0xa55ef605, 0xa9f145ad, 0xc0cd2628,
+ 0xe946739f, 0xfcceaf7c, 0x53a7ea80, 0xe404c96f, 0x50a25c8b, 0x47f47615,
+ 0xa1625057, 0x36bcb9f5, 0x64c961a7, 0xbd4eaf58, 0xf5da2372, 0x1bb948f3,
+ 0x520acdfc, 0xcff1085b, 0x0652c4b3, 0xbc967972, 0x23161ee3, 0x0545e787,
+ 0xcebb99e1, 0x7f531768, 0xb85f50d9, 0x405f58c1, 0x7d874e6e, 0x65eb05f0,
+ 0x5f401412, 0x153fdb18, 0x242d1c99, 0x7d606bd5, 0x75b32f5f, 0x48878e6c,
+ 0x555f54d9, 0xe154fabe, 0x1fff5a6c, 0xf42dc591, 0xa945dd7d, 0x1c589fcc,
+ 0xb468acda, 0x6186d3fd, 0x43cd52b7, 0x81ae0fbf, 0x4bb02af5, 0x3b536ef0,
+ 0xc2bbefd3, 0x5f57866f, 0x2fed3bff, 0xeb2a3873, 0xc7182d04, 0x0249b00e,
+ 0x580377f7, 0x863c960e, 0x5328c2b8, 0x53f37bfd, 0xd3f0311a, 0x4aa7d156,
+ 0x80ff193d, 0xed48253f, 0xf487ef8a, 0xffa9d99f, 0xff6a3fc1, 0x85ff69bd,
+ 0xfd47fe86, 0xeff7fda8, 0x6944ff04, 0x2bfee744, 0x95f17d5f, 0x8b27d500,
+ 0x4ddaffb7, 0x4a78fae8, 0x52f74daa, 0xf6dd2efa, 0x7ce81ba0, 0x81b80a52,
+ 0xc5054f5f, 0xf59c60b2, 0xe0493eea, 0x14e6a2f6, 0xff058e20, 0x7e9ffda4,
+ 0xdfe817fe, 0xf64db57f, 0xceaa7c60, 0x3952b11a, 0x68b0d65c, 0xfac7c932,
+ 0xf6beacc7, 0x8dea110b, 0xfc5bfe46, 0x21d3afec, 0x0a7282df, 0xd044d78f,
+ 0xf5b65d9e, 0x975852b3, 0xca3b48aa, 0x183bf991, 0xea2a62ff, 0x724ad9bf,
+ 0x270a76e7, 0x1c55ddfa, 0xbf0d552f, 0x437442f8, 0xd009fd79, 0x4043d417,
+ 0x5dfcd8bf, 0x974fb705, 0xe3b4ae4a, 0x232714d4, 0x8bd048c9, 0x90485e3a,
+ 0xabe2a7d9, 0x3c43e54f, 0xb7d6ccf2, 0xbe0c42dc, 0x173a7974, 0x7b9ffb9a,
+ 0xb77ac4d4, 0xac5bca95, 0x5bafa41d, 0xabb7236a, 0x2a5cacc3, 0x1f90dc47,
+ 0xecb374b3, 0x4bc7d00d, 0x99fa7c5f, 0xf83e2127, 0x0077ab37, 0x8bc97fed,
+ 0x8637bfaf, 0x90ec97d6, 0x69b326d3, 0x0ef48538, 0xffd154fa, 0xa0e82dee,
+ 0x5f97e2c7, 0xec21d457, 0x1da9fdf9, 0x63b25974, 0x7486429f, 0x684947c6,
+ 0x8ce2d29f, 0xc7d09f43, 0x882760a5, 0x00ad7eaf, 0x15ed4ffd, 0x1c6e4648,
+ 0x1d7e6e7c, 0x13c000ed, 0x2bd393d2, 0xfbd33f4a, 0xa02e9455, 0x32f4cdb7,
+ 0xf40537bf, 0x2fd608cb, 0xfe502de4, 0xe40f697e, 0xf56fbd15, 0x5e2a1e02,
+ 0xf986e15a, 0x19aa909c, 0x60f53f9f, 0xafc746ba, 0x1ee90390, 0x8af3d92c,
+ 0xf21bfddf, 0xffb7c2df, 0x35e31d2d, 0xe0b2cb44, 0x82c8145a, 0x34dfce79,
+ 0x80b9e703, 0x2b0f90f8, 0x41cb129e, 0x91297e1f, 0xe4711db2, 0x93973ce4,
+ 0x71285b13, 0xd04f3ce9, 0x6df30665, 0xdb8311de, 0x87beded0, 0x37f83e80,
+ 0x316a173e, 0x1b4bfd60, 0x921bd7a3, 0xab5197ee, 0xb77f9633, 0x3a066dae,
+ 0x65a3ee9d, 0x15463ec0, 0x1f1c0291, 0xafda65c2, 0x0ca4f6f8, 0x4aa22746,
+ 0xba3bfc85, 0x73c097ee, 0xd659bf78, 0xef86f9ec, 0x8edce5c8, 0xf1f257f1,
+ 0xb049dc29, 0x8f489f5e, 0xb2aab76f, 0xbae807ae, 0x3167c31d, 0x7fe4cef2,
+ 0xde4c43eb, 0x4e0ff975, 0x0bf6832b, 0x823932ef, 0xa43d60ef, 0xb0324570,
+ 0x022ddf7d, 0x892b07ea, 0xadf393c4, 0x63739732, 0x285f99bb, 0x1c9092fc,
+ 0x4e3037c3, 0xf701d22a, 0xa7ac1631, 0xd1e8c7df, 0xddd7182a, 0x8e5d5fb9,
+ 0xd07d7217, 0x6407d26a, 0x8903d313, 0xae00aaed, 0xe0e54b7f, 0xfc824f33,
+ 0xa80d7952, 0x3972bf20, 0xfaf3ffcc, 0x84fdef03, 0x21e7cdca, 0x7a8d6e5d,
+ 0x15b72cd5, 0x7890473b, 0xd3b9fb72, 0x2dcae24b, 0x6e571e7d, 0xcfc82d9d,
+ 0xaaf5afff, 0x990cc78e, 0x0eeaf1e2, 0x327aea3c, 0x7acd3e11, 0xc6a4a772,
+ 0xeff493d5, 0x99d8525d, 0xd43e751f, 0x0bf16ff9, 0x1f417d95, 0xe754f945,
+ 0xea9f28c3, 0x5e29d87c, 0xb9a3c06a, 0xefb0effd, 0xdb62fc01, 0x7518f538,
+ 0x015e6d21, 0x338afee5, 0xb4afcc16, 0x5f70170d, 0x0906d064, 0x3c5b6feb,
+ 0x9d4ec023, 0xcfd5f63a, 0xbbbe467f, 0xcb7df07f, 0x3f3e2957, 0x6ec84019,
+ 0x5f046528, 0xc8e7a58a, 0xeab38330, 0x43f60908, 0xe589a0fd, 0xcff4fe31,
+ 0xbdf76665, 0x61cee1fa, 0xb6a2c780, 0xa82dc9c1, 0x9fa20737, 0xc8f5c559,
+ 0x0c9a80b9, 0x385cf5fa, 0x73c9fd0f, 0xbc574587, 0x38e7c6fc, 0xf8805f7d,
+ 0xb6db2d19, 0xf2915a92, 0x47691b5d, 0xd5b022bb, 0xd9c5b646, 0x9990aadf,
+ 0xf8a1fc9e, 0x3e03fa00, 0x94b7b39e, 0x73b1c796, 0xbbeb9dff, 0x81fffba9,
+ 0xe155e6eb, 0xa7b016cd, 0x316adaae, 0xeb9605c4, 0x0a405d7c, 0xeea7af80,
+ 0x0386bbb7, 0x5e8b0f1e, 0x0aad03c8, 0xe2f8a17f, 0xf9e68df8, 0x8f60ff43,
+ 0x707b2b3d, 0xd0e4d7dc, 0x6bc3c05c, 0xf6046d67, 0xb52b76d3, 0xf9c1e24b,
+ 0xb9c1852b, 0xcba318fb, 0xa297858f, 0x18a46736, 0x095b3de2, 0x3a676df2,
+ 0x73f3e413, 0x2ab82475, 0xb22de817, 0x68353d7a, 0x9414fbe8, 0xef838e5f,
+ 0x635ed12e, 0xc68af3e4, 0xf4082f1d, 0xc16165bd, 0xcbeda163, 0xf80516a4,
+ 0x4531aaa5, 0x54367d04, 0x3d5bf3d5, 0xe1896e43, 0x096567bf, 0xcc6079e7,
+ 0x5e03b76b, 0x08519fce, 0x076801e4, 0xf84f31db, 0xf218787c, 0xbd79a25b,
+ 0x275327ec, 0x410fd0ca, 0x71d3363e, 0xa1927d70, 0xd7c4b63e, 0x6a9ae00b,
+ 0x8de9596d, 0x1c01f783, 0x7c963fef, 0x5b765576, 0xe5d5df7e, 0xc79627d7,
+ 0x9d57ddf0, 0x9e2337e5, 0xa55f2efc, 0x97bcc066, 0x0065e537, 0x21bf973e,
+ 0x57c78cf7, 0xdf99fa2f, 0x03e79db8, 0xf95035b7, 0x7e4626bd, 0xc6fca81b,
+ 0xfcb61389, 0x22fbf2c8, 0x7b3c6fc8, 0x9757cf8c, 0xc7f0fcdf, 0x0df9bf28,
+ 0xca1e4316, 0xefaf9969, 0xe857e509, 0xd41a4b79, 0x8e23af65, 0x403c06be,
+ 0xdf3b739c, 0x40718007, 0xbbe5558e, 0xfc7ff1c9, 0xf978e58b, 0x3379822e,
+ 0xe4cde99d, 0x2a6ef978, 0x9dd002c7, 0x26f2f1c9, 0x9db9c72a, 0x275077e5,
+ 0x2fdf65f9, 0xabefb08b, 0x7b7f731a, 0x40af1d07, 0xfa36bd93, 0x3c87417e,
+ 0x6795888f, 0xcf204955, 0xcf27bb87, 0x533cb8bb, 0x8de7ed39, 0xd86f5743,
+ 0xdaf61f98, 0x2ff513e8, 0x41fe5f03, 0x6de9ff44, 0xff73b30b, 0x70c4fa38,
+ 0x00db8be0, 0x632fca1e, 0xfd5a1d39, 0x74bfec01, 0x9074c6cc, 0xb5839293,
+ 0xec3c81bf, 0x0132adca, 0xe1acb87d, 0xcd53f463, 0xbedd1771, 0x745fc732,
+ 0xc38e623d, 0xbd33a92c, 0x9dbe30a7, 0xbc20b626, 0x77a24fe4, 0xd3be1c5b,
+ 0xe704ebdf, 0x9cf7dae1, 0xece03bc3, 0xcfa42e2a, 0xf4b82ba3, 0x7c2b9579,
+ 0x864a1bbd, 0xe291bc41, 0xf025e511, 0xaa7188a6, 0x8601a2f2, 0x72b70cf3,
+ 0x16d58738, 0x62d84095, 0x80ebe41a, 0x9ee1b55f, 0x368fb043, 0x005aa8e2,
+ 0x31d8f566, 0x57f81f56, 0x51dbd9cf, 0x3cba759e, 0x3964f9c4, 0x5eb5e7ef,
+ 0x6fc0c5d5, 0x07828d55, 0xc8aa9dd6, 0xc6dcf03f, 0x955f8d81, 0x6a2d1f02,
+ 0xe4563c12, 0xf0142fc3, 0xfae94afb, 0x2c34fc0b, 0xbfda05fc, 0x448a9a8b,
+ 0x6ed17ef8, 0xbbe41301, 0xe9774fc2, 0xf7c396b6, 0x04efc022, 0xbad9db38,
+ 0xdbd3e1c6, 0x0180a4ab, 0x2f2792fe, 0x7066c9ae, 0x03b556ab, 0x785111de,
+ 0xaf388b67, 0xe3abc26e, 0x1f782bbd, 0xe3deb852, 0xb8d3fc74, 0x222f18f3,
+ 0xf96e94e1, 0x6e35df37, 0xd19a4555, 0x57e3d35f, 0x2adf455b, 0x6588e219,
+ 0xf38c6482, 0xfbfc63b6, 0x7fffe847, 0xf07fadbe, 0xdd74222f, 0xd3fd7dfa,
+ 0xcfb3ef88, 0xe8153c7f, 0x9135e4b2, 0x5a5d28d8, 0x82245deb, 0x054124fb,
+ 0x41b8b0e8, 0x240e30d4, 0xbba70a45, 0xc351f162, 0x85ddb1f0, 0x4ef1707a,
+ 0xfd32706b, 0x9f2bf17e, 0xd33d83e6, 0xa1fb40fa, 0x3c03886c, 0x931ca02f,
+ 0xec3e4b40, 0xd8962d13, 0xbf198dbe, 0x87c58511, 0xcc76eccf, 0xea107902,
+ 0xc5a9b9d8, 0x35b299a1, 0x557e1ec6, 0x641c5991, 0x15af3b37, 0xbcc04e78,
+ 0xf62f8031, 0x8f9e8edc, 0xe639e673, 0x946e2c97, 0x6afe7083, 0x568edd71,
+ 0x3e2c9b88, 0xad75c56a, 0x8c0beeaa, 0x7f6c96fb, 0x6aef9d91, 0x72fe0d14,
+ 0x4eb53f27, 0xbfc1588c, 0x38c4a86a, 0x8c7fad3c, 0x0bf710f5, 0xb51fa3bf,
+ 0x2bd37b64, 0x25c28a01, 0xc6eb3f2f, 0xdbcd5873, 0xd6afe8dc, 0xa8dc7b7d,
+ 0x7a1a5f93, 0x53a5fb88, 0x97df804e, 0xcd3d2fc8, 0x62b4e4f9, 0x7aebeff2,
+ 0xe14abfa0, 0x638f2c2c, 0xfff947b7, 0x077f2fc5, 0x3b33d571, 0xc01dff3f,
+ 0xf39bf4bd, 0xe28fbbbf, 0x7bb5ec93, 0x3d560f40, 0x438c17ff, 0x5649dfe9,
+ 0x7b9fafae, 0xad78e316, 0xa17ab37f, 0x13a6d6b7, 0x6ac71039, 0x748ff1dd,
+ 0x365653b0, 0x6bbb424d, 0x0c92aee5, 0xd04ec712, 0x60dfe04b, 0x6688e237,
+ 0x38681dba, 0x9e700390, 0x748774a5, 0x21bc68be, 0x38e2c954, 0xd4338f2a,
+ 0x76db8fc7, 0x4c342b8a, 0x70fc69bf, 0x4aaf6528, 0x785f11ba, 0x9af3d297,
+ 0x9eb1d06e, 0x534291c7, 0x70be35be, 0xe941fe16, 0xc6356795, 0x986cbe17,
+ 0x424f9fff, 0x848f435b, 0x374885f1, 0x85c7a7f0, 0xdf2d14db, 0xf3b9720a,
+ 0x00eb8c05, 0x09d326fd, 0x65f8beb7, 0x4fd5c40e, 0x6177edca, 0x15935bbe,
+ 0x3717d7f7, 0xa9e515fd, 0x68dbd775, 0x9f1e127f, 0x3fd1256d, 0xb9e34716,
+ 0x5d5b55aa, 0xe9c12e2c, 0xd50b7100, 0x7c79cf8d, 0x1eb5f182, 0xaf1448b7,
+ 0xc7ed6058, 0x5c594ef3, 0x07eb72a5, 0x83c5310a, 0xeb1d5184, 0xe97a227e,
+ 0x1e00f078, 0xe3c6c646, 0xa287c7e2, 0xdd1338f1, 0x87109e80, 0x68dbc68b,
+ 0x5dc437bd, 0xe35fc282, 0x375b77c5, 0xab5e38b3, 0xe95bcc6c, 0xcf8b13a0,
+ 0x5bd136cd, 0xeb576f9f, 0xf8f35756, 0x069a78ae, 0xcecf768b, 0x29733af8,
+ 0x6d5f7ebe, 0x3ed87e15, 0xbcc13ceb, 0x7c0353ef, 0xb1f0d959, 0xfa8d7902,
+ 0xf7cfa6fa, 0xcfcfb70c, 0x5e622f3c, 0x01d09aee, 0xfd66efd4, 0x61ce0cb1,
+ 0x37f781c4, 0x8d65de1c, 0xb338fd6c, 0xd27415d3, 0xdfecce7e, 0xacbd7c8d,
+ 0x402563fe, 0xf7543bfb, 0x49fcc2b2, 0x7eb04726, 0x3fe06304, 0x7cbed2f3,
+ 0xfe647f16, 0xad9c7980, 0x85563f5c, 0x55538fe3, 0x9c6185ff, 0xc2908125,
+ 0x7dbfacf2, 0x3692d3bc, 0xdd3bfa13, 0xb3c8132c, 0xcb121d3c, 0xae6bede2,
+ 0x5f7ccab5, 0xb9c596b3, 0xe78a3ae9, 0x9cec5c5e, 0x60aa988b, 0x6ba5641c,
+ 0x5f3851d4, 0xa8a5d2b9, 0xacd51fe0, 0x35bcfb62, 0x0266f73f, 0x6e526bbd,
+ 0xad6d78c5, 0x349ebf09, 0x7f9c114f, 0x1f2c4cf1, 0xd66aec0e, 0xc59a293b,
+ 0x574aff00, 0xe14a8659, 0x81fb4d5c, 0xf244a8f3, 0xd11c39e2, 0xf3065a5d,
+ 0x8f163d11, 0x4c7c4e3d, 0x5f139676, 0x8f645e0c, 0xb90cdcf1, 0x7e854c34,
+ 0xa5d9fdf4, 0xd843e6b6, 0xe004d1e8, 0xc7ef892b, 0xc1e2dd17, 0x0bd5b779,
+ 0xaa71605e, 0x3a4f559e, 0x758033cb, 0x72676da4, 0x3f06b93e, 0x5f5d1a24,
+ 0x50b9fc1c, 0xe81f6fbf, 0xa26ed5a5, 0xa33950a5, 0x3cc55558, 0xd4343f38,
+ 0x9f01e426, 0xd7c7f17e, 0xb0f6bf68, 0xa0352048, 0x19e7a9cd, 0x67202969,
+ 0xe608f20e, 0x5f2b0093, 0xa701d1ee, 0xc084cf39, 0x97e7312b, 0x8c4e8927,
+ 0x24db9c7f, 0x922b9fa2, 0x8e3b7eab, 0x0824edf9, 0x65f5f3f0, 0x1cf38709,
+ 0xf0231175, 0xe30bbd7e, 0x98df0bf3, 0x7403f28b, 0x8f57c588, 0xb91fa332,
+ 0x87ceeec1, 0x768d9dfd, 0x492816f7, 0xbc866b40, 0xdfbc79e6, 0x73c6e59e,
+ 0x030c5448, 0xe7ce7f60, 0x82f9faf2, 0xaf98c3d2, 0x7a805be0, 0xf196633e,
+ 0xbed9929c, 0x1fb50897, 0x0a0d7d61, 0xb38908de, 0x19b8dfaf, 0xdecaeee1,
+ 0xb0e8f1d7, 0x3909bd51, 0x04e24e42, 0x97d6263c, 0x65b7e05d, 0x0dc76fe0,
+ 0xb5f8eeff, 0x6bf11a66, 0x75f88d57, 0xcfe3320c, 0xd7975f88, 0xe6ca2f88,
+ 0x6fc36fc1, 0xb9e328f2, 0x7e157faf, 0x1db8d987, 0xff4af1c9, 0x4ce96dca,
+ 0x59dc0365, 0xc2e50452, 0xced9472c, 0xeeff0088, 0x855c1693, 0xe85d795f,
+ 0xf9f264af, 0x77d8f308, 0x1123900e, 0x1ca2f5e0, 0xd00bc9c1, 0xa1f20ef3,
+ 0x2169e807, 0x57cb929f, 0x8ae7a627, 0x9e3f0769, 0x04dabf43, 0xf20d7bfc,
+ 0x955f3b03, 0xb935824a, 0x0f5ea720, 0xbf21dfac, 0x864f3bcd, 0x3bc4f673,
+ 0xaf9c006f, 0x68f960f7, 0x6dbf7b01, 0x1a73c130, 0x7485c8a1, 0xf3554fd0,
+ 0xbfe83949, 0xa9f69547, 0x6cbef7e0, 0x1bbdf167, 0xd3ea0aec, 0xae16eda7,
+ 0x71be2757, 0xb6c7952d, 0xf9c2acb0, 0x36f0b6c0, 0x37a800db, 0xbd6e788a,
+ 0x4af6a52a, 0x2c35bf18, 0xd9e6b833, 0xbfc00382, 0x3d71926f, 0x0e379d68,
+ 0xed44c1cf, 0x4fdb30b7, 0xea7f0b6c, 0xcfa31b9e, 0xb89f1b5b, 0x1b0fe212,
+ 0x31f7f12d, 0xdf2cd857, 0xae8d7fcb, 0xf29d0dbf, 0x58d8562e, 0xfda3c75e,
+ 0x4d963ce8, 0x61d7c73b, 0x39630f26, 0xb82e0f9d, 0x2bbfe701, 0x3a7cfd4c,
+ 0x8ef1528f, 0x79d0871b, 0xc48bfe8e, 0x26d12bf4, 0x47674ecf, 0x1afde080,
+ 0x5fa82fd0, 0x0e2cff6b, 0x44a0b887, 0xf0c45ce0, 0x6fe805ea, 0x7ca6e6bd,
+ 0x50a2f94e, 0xbe030d0b, 0xc14e189d, 0x3eaa0a7b, 0x8fd76824, 0xfc0c9668,
+ 0xd5d7c859, 0x9f1616c2, 0xd8d4791f, 0x3245ba3e, 0x8c4141d9, 0x693d8f1f,
+ 0xf3ab5e7c, 0x03a49bb9, 0x24bfaf9f, 0xd517900a, 0x0fbc4ed6, 0xe6dbb850,
+ 0xda3842f5, 0x2b29c02e, 0xcb125e5a, 0x9bf7ade2, 0x6b0f2c6d, 0x9d7042a3,
+ 0x89c0b8d9, 0x17fb08fb, 0xeb3cc62c, 0xebe67eaf, 0x5edcef1b, 0x664a7e8c,
+ 0x325af5fb, 0xbdfc0519, 0xaf78605a, 0xb7dd8acd, 0x9f9d4bd2, 0xf9d6fe75,
+ 0x92416b3a, 0xcbde5e2f, 0x7bb33b60, 0x120c178a, 0xf6d7f014, 0xa9fc780a,
+ 0x219f01f5, 0x065cdb7f, 0x00d903c8, 0x79e3554f, 0xe16dbbb4, 0xfb5479f8,
+ 0x0fe66e6d, 0x0558103e, 0xa53f1e79, 0x327a09c2, 0xd1ebbf71, 0xa083aadf,
+ 0xab677c2a, 0xa6e78d9d, 0x16c8dbe6, 0xb54ad388, 0x80bb3759, 0x5fae4bff,
+ 0xb27de143, 0xebeb82dc, 0xf08bd946, 0xc1092a07, 0xa73f03f8, 0xd92a7bd5,
+ 0xec7e7b1c, 0xa8e8ad88, 0xa8f7ce8d, 0xeef383cd, 0x000af3e1, 0xffebf7bf,
+ 0xa6bb06e3, 0xe915a2ed, 0x43fb8bd8, 0x6de777fa, 0xd80f4f0c, 0x7be077b5,
+ 0x72869152, 0xbdb9f5e2, 0x39c186f3, 0x18f78a55, 0x5fa0ea39, 0xea91e700,
+ 0xc28e3aa3, 0x20b4ea93, 0x534d125f, 0x031e7a3d, 0xc8c5efe1, 0x04088905,
+ 0xbd741cf2, 0x8885842a, 0x70c1ca8b, 0x7e02339b, 0x9d056a47, 0x4ec10537,
+ 0x66bfac6c, 0x1cf44ce9, 0x5251e61c, 0xe4842cbe, 0x12798279, 0xfd05a890,
+ 0xd756faeb, 0x0853abd3, 0xc7eacbca, 0xed0d60a4, 0x62d49367, 0xae4af887,
+ 0x56c316a6, 0xe2a4aa74, 0x153ebcf9, 0x1c73f304, 0x44a54f79, 0xf42a16ed,
+ 0xef11bf43, 0x1fe7178e, 0xe5f1d76a, 0x2be027fb, 0x7efb70ff, 0x76bc6f30,
+ 0x75f79e36, 0x51e9da1b, 0xb1edc1fd, 0x8efebe52, 0x2bed8cfe, 0x24b5c893,
+ 0xd66f8e36, 0x327dba1f, 0x03cb7c7a, 0x6feef80e, 0xadda4e0c, 0xe08ddf06,
+ 0x13ea8df3, 0x0c8e6ebe, 0xbf427d53, 0x3b0f082f, 0x82eef100, 0x771c990f,
+ 0x038727d2, 0xfbefe022, 0x5f3311ea, 0xb9508d0c, 0x5583ede4, 0x89ecbf38,
+ 0xafbda1d6, 0xd277a8dd, 0x40cf0da6, 0x9bf3973b, 0x7cbacf19, 0xe0bee59b,
+ 0x2b01ef5e, 0x60910b83, 0x1d08871e, 0xa079a870, 0x60888e97, 0x5115b7ef,
+ 0x0eb8503c, 0xb94bf972, 0xe61ebc10, 0x9d7c3ebf, 0x7be4e41d, 0xfa1127af,
+ 0xf27c4c75, 0xde37d171, 0xdcf8f2ce, 0xfb658780, 0x24f5f02e, 0xca8ef482,
+ 0xd8939501, 0xffce8978, 0xe5d77e66, 0x3a0e06a3, 0x0bf9e1e7, 0x28aceb02,
+ 0xbdf0f084, 0x00f26c95, 0xbb7b755e, 0x24b7db86, 0xdff68590, 0xebe10f4a,
+ 0xf8104e51, 0xedd646a4, 0x362daf75, 0x55d2b53e, 0xfb6df19c, 0xa9175535,
+ 0x8793167f, 0xa3b5255d, 0x517556ff, 0x1bdfe7c1, 0x450a617f, 0xf37f01ba,
+ 0xe33b3ded, 0x57c83c6f, 0xe62fffcf, 0xbf3ccab7, 0xfcc76ab5, 0x6bdf12c6,
+ 0x147f542d, 0xe35758ae, 0x7793f150, 0xeb3b0b33, 0x657cfd05, 0x96603d22,
+ 0x6b4b91f7, 0xb498600f, 0x72af790b, 0x3212fc70, 0x98d9f41d, 0x725bb508,
+ 0x05ffcb3b, 0x072abf3e, 0xaddb7bc3, 0x9e4103ed, 0xdfbe8856, 0x16a811d9,
+ 0x8aec058b, 0x1eed04dd, 0x6e63beef, 0x1ee6f794, 0xb3a7f586, 0xf660105d,
+ 0xf4475f26, 0x48d0a7b8, 0x738e80e5, 0x0e7beec4, 0x30f1affa, 0x340e14bf,
+ 0x623a7e81, 0x5e03d5f3, 0x24c6141d, 0x28324f38, 0x28e2cb92, 0x25dc8311,
+ 0x49873392, 0xde74428e, 0xe805aeb0, 0x484036ba, 0x7b02cf0c, 0xd502230a,
+ 0xf4b7602e, 0xb06c242e, 0x06f30465, 0x7bb3e77b, 0xb0177a00, 0xb4dec77b,
+ 0x5bc938b3, 0xcbd11d7c, 0x03f2b623, 0x912cbf00, 0xfbe0b580, 0x42a00dc3,
+ 0x5d88f17c, 0xb27807db, 0x8f386995, 0x0af10f6c, 0x52d98e94, 0xad7d8048,
+ 0xc0aaa5d4, 0xad848ae2, 0xfed25043, 0x45ab27b2, 0xfeecf740, 0x6509cf04,
+ 0x4713fd83, 0xe5d98e6e, 0x6b07161f, 0x1f8764ec, 0x487172e3, 0x31edf3a1,
+ 0x473fe599, 0x7c1439e3, 0xebab6fc0, 0xeb6c9c56, 0x225f2c97, 0x6cf0c290,
+ 0x6080cbf6, 0xd7892f30, 0x6488541f, 0x29bf454f, 0xb0197c00, 0x726fd0d8,
+ 0xef086f10, 0xc7ea4949, 0xbc1145ee, 0x2bfea0eb, 0xf706dda9, 0xa0f2e825,
+ 0xe3a3f9f3, 0xf44af66e, 0x73f8f755, 0x52d3e0f9, 0xe027ff7e, 0xb9dc75b9,
+ 0x2671ab81, 0xef8c39ed, 0x6790d134, 0x51afd3a9, 0x0ecfd036, 0xfd5892f1,
+ 0x810652ed, 0x242ade3d, 0x6a5fc179, 0x7830245d, 0x43cf1b05, 0xccf30c95,
+ 0xa33f3074, 0xfec5eb8d, 0x0f38b949, 0xf3a09d7d, 0x5d71875b, 0xe7a23cd3,
+ 0x8ce74c8e, 0x3290e7cc, 0x9df1a2f3, 0x2b07cc2c, 0x184ee057, 0x40ec2e72,
+ 0xddcaacfb, 0x9ce2439e, 0xb168c993, 0xa6073dc7, 0xfd6f1497, 0x5e427a92,
+ 0xe80a7561, 0x993b8cd9, 0xa3e3307e, 0x3d0c084d, 0x7f63fb04, 0xa3eee390,
+ 0xe66665eb, 0xe8f3298d, 0xd75999fb, 0xdf3fa963, 0xc6e294e0, 0x0925c70b,
+ 0x0c8fcc3f, 0x18df3cb2, 0xf3071dfe, 0xe77beb39, 0xbfc50d3d, 0x1be9e31d,
+ 0x37de1892, 0x6fbc3124, 0xaa7c7450, 0x1d7f20c9, 0x5f21af75, 0x96dfbd62,
+ 0x509e4122, 0x73e50b20, 0xbbd187be, 0xed0d7de3, 0xbb449e96, 0x125036fe,
+ 0x0db265eb, 0x7dc59ef9, 0xdfe0bcf4, 0x994b9ff8, 0xdba7ed48, 0x8d505f38,
+ 0xc29be8c0, 0x7eb0bee0, 0x4e9b8e12, 0x1481da2d, 0x2dca0bcf, 0x9d07885e,
+ 0x1bbef39d, 0xc9cdc88e, 0x78242e6e, 0x0d7ab5f4, 0x157f73f8, 0xd125b77d,
+ 0x5036d27e, 0xf183d545, 0xa525c805, 0x8fb8f5d3, 0x3712db39, 0xc497cfef,
+ 0x925776fc, 0xccc8e107, 0xea748a9c, 0x014e4fa8, 0xa7ccc37f, 0xe6b35e54,
+ 0xb738ef0d, 0x1166f946, 0x6f2cd9e0, 0x1469326d, 0x208add70, 0x7674d2be,
+ 0x975b7ae6, 0x43903497, 0xa72a8fd8, 0x73a7547a, 0x3a6afe3f, 0x4ff13bc6,
+ 0x1ffeff08, 0xc7b847e0, 0xd45ea317, 0x620c88e5, 0x7a0ede7a, 0xd9ce2637,
+ 0x3ed7f4d6, 0xd1f89fb0, 0x60bbcfcf, 0x52efe93f, 0xecf40bbb, 0xecfffbc9,
+ 0x8f863c82, 0x8ef167ee, 0xd7fe4cbb, 0xff4c4923, 0x5e54947f, 0xdbbaf303,
+ 0x2fa175ff, 0xbdc95f86, 0x51645f6c, 0x6f9d3450, 0xae379e34, 0x17cf990c,
+ 0x95df1007, 0xfd78fc52, 0xe71624fe, 0x59bf5459, 0x7c6156c9, 0xae81afdf,
+ 0x797fb927, 0x03dd81b2, 0xa733c3a2, 0x3e02a87e, 0x56c3dfd7, 0x2cdeafbe,
+ 0x9b43f5b3, 0x3e62fb0c, 0x9c33378e, 0xa4fdf887, 0xa22d7ff3, 0x8e9b33df,
+ 0xc3d52f75, 0xf3cb30be, 0xfe63cf35, 0x9c296a47, 0x90ff9fe7, 0xbc34fe80,
+ 0xcf5d3f7f, 0xc5aef77c, 0x3cf333fd, 0xa08fdf3b, 0x90b5dfa1, 0xce7cdbd3,
+ 0xed98616a, 0x3e23cf6f, 0xf94ecf94, 0x0f966118, 0x9e238e6d, 0x00e79c3b,
+ 0xf126343c, 0x3242ab7d, 0x762ef212, 0xfc97ee1e, 0x675ef96d, 0xd3f2b9f8,
+ 0xa4f44f3c, 0x9359609f, 0xdbf3b2a4, 0x814bb7e1, 0xee3596bf, 0xbe657bc0,
+ 0x0caa3eab, 0x84ff729f, 0x6a25e874, 0xe811fe5f, 0xc1827c48, 0xf9b65cee,
+ 0x65fcc2bc, 0xf83b9f86, 0x1f003bf3, 0xeececfb8, 0xa963b90f, 0xdef6217c,
+ 0x8c92f799, 0xa267ebfb, 0x3cd9e4e7, 0x93bef92a, 0x5f333f3e, 0x9b3e70d7,
+ 0x9ada75b7, 0x35ca745e, 0xf872274d, 0xfbcc0779, 0x2166f9d6, 0x8acd2f29,
+ 0xbd3a1fc3, 0xfe107ca2, 0xd3abc225, 0x6ced5e69, 0x2640af3e, 0x84cbf7df,
+ 0x2f9992b8, 0xd76f3aba, 0x80e4b72a, 0xdee99abc, 0xfb3ce09a, 0x3ed893df,
+ 0x2b553ced, 0x9f38bd05, 0xc4f1af94, 0xa5272bd8, 0x81f743da, 0x7c656d1c,
+ 0xe06bd51c, 0x7ebe82bc, 0x7cf5c64b, 0x80cd4bb9, 0x1e90917b, 0x87615e70,
+ 0xe9ef0035, 0x6bf71ce3, 0xf0197f5a, 0x69e5865d, 0x7fd6b97f, 0x82fb4740,
+ 0x10dde78d, 0x441b6dc7, 0xead3be30, 0x71ebc232, 0xc78f0888, 0xa5bbd6c1,
+ 0x1f37f352, 0xdada0e80, 0xc711f98c, 0xd0f8f12f, 0xbc596b25, 0x10ed5e79,
+ 0xdd05f70c, 0xf74ae5c5, 0xf4e6ee3f, 0xf6cc2bbb, 0x9a6ce7bd, 0xdf30f486,
+ 0xfb847267, 0x041bb32d, 0xfa6623d4, 0x775ef7cc, 0xdcedf40a, 0xdf7e1160,
+ 0x11e45e89, 0x6e99bba4, 0x761e1deb, 0xad548dbf, 0xc73f7dc0, 0x4fb80937,
+ 0xde8124b8, 0x8f0777fb, 0x3e737767, 0x822479e6, 0x55d6e17f, 0x98117a6b,
+ 0xf80550ff, 0x3ebf0cdc, 0x6344f9ff, 0x37cf877a, 0xcb48bcd1, 0x829f2cb5,
+ 0xc28be3af, 0x65a97eec, 0xaf2c888f, 0x748bc793, 0xcd7875f8, 0x971528f3,
+ 0xdb6f3e62, 0x09f31106, 0xd7040aef, 0x77cbbdc0, 0x3d7016ad, 0x5d27444d,
+ 0x32fbe84f, 0x63671acb, 0xf68f957e, 0xdb697603, 0xd9170487, 0xde0275b6,
+ 0x9e90937f, 0x94579661, 0x30849e88, 0x74a3cdba, 0x7e6e387b, 0x3fd6915c,
+ 0x78273f76, 0x763fd6bd, 0x3084897f, 0xdd4964af, 0x4af3c334, 0x774f5187,
+ 0x3aa47f25, 0x2e9cde7e, 0xe9fcba6f, 0x9c1eb8f2, 0xa51fb073, 0x5ceca1e0,
+ 0xe863cfc0, 0xfbfd50af, 0xff8b0773, 0x7d1b7a3c, 0xf3c6d965, 0xf984fd86,
+ 0xe6bd18a3, 0x79f1938b, 0xe28375a2, 0xd787a0c1, 0xf87a8c3a, 0x9f47ce87,
+ 0xfa272e87, 0x6272ccfc, 0x0f4cdefe, 0xa6670e3d, 0x001e998b, 0x470df827,
+ 0x07c11c9a, 0x04479c28, 0xc9a07706, 0x66b7708e, 0xfe706896, 0xedd65966,
+ 0x0f811e58, 0x57bd8347, 0xed038cfe, 0x7957ee56, 0x4503e7e3, 0xf76e25ed,
+ 0x41961988, 0x93111e30, 0x2ec790bc, 0x77aa5b66, 0x7d8a79d2, 0xd2183969,
+ 0x9c22bd99, 0x992daee7, 0x143dc220, 0x77bcfc35, 0x379d858d, 0xc3dbfbd3,
+ 0xed97a0f1, 0x8046f28e, 0x9a9fece7, 0xfe2c1d0b, 0xce0afe8c, 0x143dee13,
+ 0x760dbfa8, 0xf304ebf0, 0xc8d20b69, 0x83b7a001, 0xee40a368, 0x72a4743f,
+ 0xffed9c3b, 0x286cbfd1, 0xcbcb56bd, 0x3f9097aa, 0x49b3e2fc, 0x37b25f70,
+ 0x9722b2d9, 0x38e2ffd6, 0xb9ee093d, 0xce5b66f3, 0xfda87ae7, 0xd59cf8ed,
+ 0xef9cb6af, 0x737feb47, 0xd875619c, 0xf87b82a8, 0x0527671c, 0x1e38c306,
+ 0xb5eae7a6, 0x243e41ab, 0xa597f30b, 0xc3c60afd, 0xd5fdfdf5, 0x17e0e694,
+ 0x79f9c87f, 0x17e2aacd, 0x2c67101c, 0x6fd854d6, 0x71be0ade, 0xea5fefcf,
+ 0x161d1578, 0x4a0367bc, 0x1ca7ffc0, 0x485d3a9f, 0xe4357683, 0x7690923d,
+ 0xb483ec35, 0x1dc77c3b, 0x91d87db4, 0x572009e6, 0x5fbcef0d, 0xf68df788,
+ 0xa30cfd65, 0xf3a6e20c, 0x9f6afb39, 0x8afbb1cd, 0xcfa28eed, 0x0c943e81,
+ 0xaa084768, 0xed41dc87, 0xa88d1a86, 0x31f81e4a, 0x81bdbb46, 0x49d7d9f3,
+ 0xcf91e7e5, 0x9f50477a, 0x7df0e53c, 0xfd9be305, 0xda9cd211, 0xf253fe2d,
+ 0x7af8c5ef, 0xd1e3766a, 0xff9f2039, 0x0afdcec5, 0x7af9869a, 0x9ef7a3db,
+ 0x1df7f410, 0x710bc924, 0x9925e236, 0xb71e7481, 0x4abe30b0, 0x4bf18c2b,
+ 0xf7e87cf8, 0x951ee113, 0x1fb60e91, 0x8227e74c, 0xa894369f, 0xf8830e58,
+ 0x9ab01e43, 0x487beb0f, 0xb47de8e8, 0xccedc7ff, 0x11d5b7ef, 0x84675c43,
+ 0x7707d993, 0x275c58b9, 0x0cdd0e49, 0x0be93dfa, 0xdefd01e2, 0xe12294f6,
+ 0xb9e4a67e, 0x0e39f711, 0xf82e3059, 0x40f41cac, 0x4afdbd7c, 0x3a42dd49,
+ 0x74e36bfa, 0x5c7dfbd7, 0x7884af51, 0xb3175cca, 0x222d9e27, 0x7edaf798,
+ 0xfec2094a, 0xadb66a57, 0xcf4fd63a, 0x4faddfe7, 0xa4e41e2e, 0x8929a865,
+ 0xf723f8c0, 0xd2928352, 0x02fa85e3, 0x76c5f03b, 0x43c511c0, 0x0f73d5aa,
+ 0x9e7a97f4, 0xcf8b9bc2, 0xa4afc435, 0xf8a64d0e, 0x5383731d, 0x9e297b85,
+ 0xc06e87b5, 0x2d17bf3c, 0x76d3ff78, 0xea0d3bc5, 0x1ea9cfdb, 0x9b3d0788,
+ 0xf9c24a1b, 0xf9c168bc, 0xbf6a4f6c, 0xfb85396a, 0x8e2c41e1, 0x64883920,
+ 0x2a79054b, 0xcfa1ef56, 0x7d993bc7, 0xe4c2dabb, 0x62a9daa9, 0x8e8171fd,
+ 0x15ef005f, 0xf9e91ca1, 0xeced6d17, 0x5bcf471c, 0xe7e0459a, 0x3fba69a4,
+ 0x0fc1111f, 0x704e571f, 0x94e71d5d, 0xad3a2a83, 0x2176739a, 0xd6ceffdc,
+ 0x2e1f098d, 0x29f2cc9d, 0xefc2efbd, 0xf2701c21, 0xbef836fb, 0x4f9cb5d0,
+ 0xd11693c6, 0x5fc7db46, 0x2e48de24, 0x8c6af7dc, 0x5a633edf, 0xfef127e7,
+ 0x44cf76b5, 0x8c445c78, 0x0da4f0eb, 0xae20a7a5, 0x09344c5c, 0x66c4a9f8,
+ 0xdcf5876a, 0x9ac4f70d, 0xf273c9ee, 0xe4872b75, 0xe8fde6c4, 0xe249fb71,
+ 0x47688de0, 0xc05e2994, 0xf6a70ecb, 0x0d4fd857, 0xdbf2f750, 0xf8cf3de2,
+ 0xa0d67e59, 0x57020e8b, 0x74fe50ff, 0xdaae7cc2, 0xd3b01b50, 0x9fd55f79,
+ 0x087c0ff5, 0xa78ae5fa, 0xbe807ad2, 0xe97a7377, 0xc077cea5, 0xc6649e5f,
+ 0x3a6b9e5f, 0x273ef3e4, 0xf2e89b8b, 0xfd077c06, 0xb78391ec, 0xa41fdbc7,
+ 0xf01f7afc, 0x41270eeb, 0x5917fa7b, 0x672059b6, 0x9dfb38fa, 0xe5cdff8c,
+ 0xf7cb559a, 0x0412efc1, 0xc6eb64be, 0x31175ec4, 0x6eba2e4f, 0xab783327,
+ 0x53e9dad4, 0x29c76f21, 0x3a4e5e63, 0xcb16373f, 0xfc31592f, 0xab5df3a2,
+ 0x3adff993, 0xfeec94ff, 0x284b9e33, 0x06fa92f9, 0x376a24b9, 0x2133fcea,
+ 0xb37dc110, 0x89d98409, 0x99d9fe66, 0x2e8a7f80, 0xade812a8, 0x9873fc4e,
+ 0xbe224ff1, 0xb048fda1, 0xe7f99a0e, 0xe3b72719, 0x25cff212, 0x6569e037,
+ 0xeeb7c953, 0x8dfa34ef, 0x72e67cf9, 0xbe7e23b4, 0xef1c67e7, 0x1bda95bb,
+ 0x4c6f41f3, 0x2f4178b1, 0xbec8ee50, 0x3bbbc299, 0xb5d7bf49, 0x3bea0f3a,
+ 0x7687a624, 0x87a8ad84, 0x3e7d3876, 0xb2658b8c, 0xf24474f3, 0xb6fe40b5,
+ 0x8d4d97b7, 0x7efb27bd, 0x39218fce, 0xd804fa32, 0x3e306f45, 0x00a53518,
+ 0x5921bc6e, 0x185e98f3, 0x0cd9527e, 0xd0b28fbf, 0x9386f455, 0x74067fbe,
+ 0xc753ac07, 0x60b7bc14, 0xf50531d9, 0xdf7babe3, 0x93b8852e, 0x723a179e,
+ 0xc5a5dbcf, 0xc67de183, 0xfd736f6f, 0x6531d7aa, 0xe9a5f41e, 0x84d1d85e,
+ 0xbdf331e9, 0x47c0e5ae, 0xe6ed1df9, 0x49434efb, 0x933d2e2c, 0x0e9bb2a8,
+ 0xf958fd31, 0x885d7083, 0x99d3def9, 0x4fd01b91, 0x5f5de5b8, 0x394f7bfc,
+ 0xdfef987f, 0x77c93afc, 0xf95fe61a, 0x985ef342, 0xbad95102, 0xafaa521d,
+ 0x579ef766, 0xe93f01e7, 0x147f8872, 0x068fa17f, 0xf5ddee19, 0x11e8f5f2,
+ 0x7beec4af, 0xbf705168, 0x7d8497e7, 0x98ebe217, 0x40f4c5cd, 0x6e97cac1,
+ 0x55873807, 0x2e800768, 0xf9993bff, 0x1122bfd7, 0xcdd01e5b, 0x3a9c612b,
+ 0x2725ab24, 0x88f78e84, 0xce083e54, 0x99e9ed75, 0x5fc60c34, 0x5c39f2e8,
+ 0xed486f60, 0x91bbe187, 0x81860a63, 0x5d0e771e, 0x35d603dd, 0x570a6e1d,
+ 0x076736d9, 0x175c3a1c, 0x742cbf39, 0x7ab876cd, 0x2f40efb2, 0xdc7c7e35,
+ 0xfcebdf06, 0x82fa6a10, 0x5f0c41f1, 0xf0741f00, 0xd4377085, 0xf1a43c75,
+ 0xd8ffaf52, 0x97fba17c, 0xf805f25d, 0xc5efee8f, 0x715c4317, 0x73da82f8,
+ 0xd9b9e1c3, 0x2c290b9e, 0xfcfccccf, 0xbe114729, 0xe60855ef, 0x76bd9089,
+ 0xbe3bbbf6, 0xbf2f8c14, 0xb66361ec, 0x073c747d, 0x5ceb957c, 0xf90e4ca9,
+ 0x2343df3d, 0x439fda02, 0x03b8a2a9, 0xa8debced, 0x7f1cbd27, 0xc020b8e4,
+ 0x4b985dfd, 0x68760d9c, 0x6bd807a4, 0x2393ad43, 0x1d3b0f20, 0x7ec1b213,
+ 0xcb8c702c, 0x32bff983, 0xb05be568, 0xabd2bda4, 0x6aade5e2, 0xeba57d87,
+ 0x5bbc03c3, 0x5d5bfc7d, 0xd5ae3f8c, 0xd010f9d8, 0xe870b1eb, 0x099003eb,
+ 0x332210e0, 0xa81d972d, 0x142dc3c7, 0x1c02d76f, 0x04fb0f14, 0x43f600d2,
+ 0x2b4b4591, 0x67b03b01, 0xdb380244, 0x0391fe9a, 0xe1c9a771, 0x78051fdf,
+ 0x5bfbeb27, 0x96fee35e, 0xedd6ded9, 0xd0ffdd21, 0x228925ed, 0xa0abb742,
+ 0xa73c047d, 0xbdc0f4f8, 0x45beb0e0, 0xf53e786c, 0x95ea73f1, 0x8967971a,
+ 0x9f3263ce, 0x19a44dc7, 0x2e9722e1, 0xe9471e5f, 0x63e39533, 0x491261f2,
+ 0x427687ca, 0xfdc014a6, 0x4c902433, 0x15e299c7, 0x7c3127c8, 0x6328d373,
+ 0xa426fe1d, 0xd5d3f477, 0x6375e6fb, 0xffce29ac, 0x7ec3cb43, 0x4dfc6e76,
+ 0x3c173b3f, 0x90189fa6, 0x951dfd60, 0x7b03cecb, 0x2b0e1e18, 0x23b1d7f1,
+ 0x58c79e5c, 0x3ce1f25a, 0xff3dbee4, 0xff7375c4, 0x07be7f9e, 0x53e8e476,
+ 0xc63c8112, 0x2786a731, 0x28ebbee3, 0xef4af915, 0x06b3eab7, 0x49cf6107,
+ 0x87e87dec, 0x15da3c28, 0xcb0d9f00, 0xfe3cced7, 0xe177f404, 0xf3624498,
+ 0x5f154be4, 0x968f887f, 0x0ff17bf2, 0xd29ecc09, 0xfbf10fdb, 0x78b977a8,
+ 0x93d28e7c, 0x1ac4c7fb, 0x5429e743, 0x74172513, 0xc9ca75d0, 0x7e5253b2,
+ 0xdfc0fa67, 0x7e1f3a27, 0x57749e4b, 0xfb0e7ea5, 0x5eb62ef7, 0xc37f0392,
+ 0x35d70cf3, 0xfd8123dc, 0x48a65d7e, 0xaf7198b4, 0x1fa7a957, 0xebd8f713,
+ 0x07bfd932, 0x2a627b9e, 0x111e79e4, 0x2aac6531, 0x7cade3bc, 0x718b37a8,
+ 0xf19ba7cf, 0x1ef85d7b, 0x887ff809, 0x574dc99b, 0x8ab98fe3, 0x4035c9f2,
+ 0xc0ecc277, 0xc8e50142, 0x7bfddf4c, 0xcb47a3fe, 0x4ef8c4e0, 0x1d337f44,
+ 0x8c533b5e, 0xd15d21fb, 0x7bb7ccc3, 0x57033ce9, 0xd97aefc0, 0xd77f0048,
+ 0x83f583cb, 0xebac4cfe, 0xf4d55afc, 0xf3b00f74, 0xd49d3e74, 0xe8cdf183,
+ 0x20f44fdd, 0x997a0ece, 0x19b826f1, 0x75d976fd, 0x633bc4bb, 0x67f47d2a,
+ 0xa3210eba, 0xe4334806, 0x587394d9, 0x8a5bbe67, 0xf9e10976, 0x6df5e6ff,
+ 0x24c778a6, 0xdd5da750, 0x3a8b7f4b, 0xb9f75bbb, 0x95a91d97, 0x952c1d60,
+ 0xc63d3256, 0x1e1d78ed, 0x42ff9d33, 0x44fe11ca, 0xc0f999f0, 0x68aee70c,
+ 0xeb86b27e, 0xfb4f7e81, 0x72b9fef4, 0xe8799c6a, 0xd085b8f8, 0xfbaf38f5,
+ 0xdb8e71eb, 0x4fe7ffc8, 0xa013fc4e, 0x99bc9135, 0xd76e66e9, 0x0c2947f5,
+ 0x00658050, 0xee2193ec, 0xd2879474, 0x60d10a8b, 0x9db7ba5f, 0x379b1a7c,
+ 0xe40af93a, 0xf61e15b7, 0x2dbf112c, 0xdf1228bb, 0x93be0eb0, 0x00731f1b,
+ 0x6a96eddf, 0xf7f45e1d, 0x5324d5a7, 0xacfc4d3c, 0x073c16f8, 0x102162de,
+ 0xfe149b5a, 0x19c400e2, 0xcc128eaa, 0xef0e2f07, 0x3d3e012b, 0x9fa33528,
+ 0x908176d5, 0xceec62c7, 0x038d70c6, 0x34c6b2ec, 0x50e99e76, 0x9be4310a,
+ 0x7d33711e, 0xdcec78dd, 0xbb4e2d54, 0x79f8cc98, 0xf2d2d13a, 0xd74b3fe9,
+ 0x3f00fe51, 0xe30ba7b8, 0xef051324, 0xb76069eb, 0x9feec6dc, 0xf91a6b6c,
+ 0xb7851a7a, 0xd414cef5, 0xd71a9333, 0x84a1e3de, 0x0c3d7d08, 0x16cfb79f,
+ 0x7be85bbc, 0xeb17aaa5, 0xd172f3a5, 0x4df91bef, 0xa193e98f, 0xfd197afd,
+ 0x52e2499e, 0x6755e209, 0xf0028533, 0x2d08f727, 0xf2f7e0ab, 0x38d8d302,
+ 0x01e813c4, 0x933be9fe, 0xdfc50c7b, 0xfaf55174, 0x205dfc00, 0x56dff262,
+ 0xcfbf3aee, 0xce57db4a, 0x733f3010, 0x049b2792, 0x74a7f862, 0xbaf3829d,
+ 0x0c519c39, 0xccbd3d7c, 0xc22c4e78, 0xe519c9ed, 0xdd8c120e, 0x283c1527,
+ 0xedec87d7, 0x5cefe2b7, 0xe604c936, 0x0df9cba7, 0xce67df9c, 0x6ef861ea,
+ 0xa776611a, 0x7237572e, 0xfb81bbf9, 0xb2f9b7cd, 0x1397e30d, 0x81fd0f66,
+ 0x92044fb4, 0x3cb32794, 0xcdeda9a2, 0x2f0edeef, 0x8047bd89, 0x9071bc3e,
+ 0x9715efc9, 0xc8be46ae, 0xc780bc14, 0xfb635e29, 0xe74ca34d, 0x6bf24d14,
+ 0x20330fd6, 0xacec4a3b, 0x307d7427, 0x219449a3, 0x88a3341e, 0x62ed19e2,
+ 0x95dedda3, 0x949918be, 0x525c5f40, 0xa433041f, 0xb0f8be93, 0x8be97bec,
+ 0x32dba957, 0x36f5ca8a, 0x21f46f5d, 0x4c6f407d, 0x009feb12, 0xeba36a3e,
+ 0x1f0e35a6, 0x1e8eebe9, 0x72a52807, 0x0ce07a8c, 0x749e2fcb, 0x86048b31,
+ 0xa201c475, 0x25da847a, 0xd2f638de, 0x619e777e, 0x57aa23ff, 0xb912ec62,
+ 0x25db87f0, 0xaa3da893, 0xbd7c0014, 0xc252be11, 0x90a596e2, 0xc3f102c8,
+ 0x0e302fcc, 0x7f512554, 0xa7e7d716, 0xffa39e99, 0xe43b5212, 0xe8af6cc3,
+ 0x3c09e871, 0x97e6617e, 0x16f23c68, 0x3a42e319, 0x3e02949f, 0x116ffe41,
+ 0x2ba09f71, 0x37c7d1be, 0x14c44bf3, 0x5f92ea1f, 0x577ddcb8, 0xe6ed397e,
+ 0xa4fea1f1, 0x44f8777f, 0x5f9d0fe7, 0x9bcdebcc, 0xa25138a6, 0xb09fe6f5,
+ 0xbc4cf4de, 0x483ebcde, 0x95debd46, 0x992e735d, 0x6e89f9e9, 0x75773b0f,
+ 0xd8270ce5, 0x59921335, 0x6ebe817e, 0x1b5de345, 0xdebc9f18, 0x7d824732,
+ 0x1fd02aa6, 0xd0741db9, 0x5f3ac5e3, 0x60275b2e, 0xd732747c, 0x2c4dad5f,
+ 0x5135585e, 0x8fd1c20c, 0x4f63f092, 0x6fbb3ab0, 0x14efa746, 0xd24527ce,
+ 0xff7e093e, 0xe0af26f4, 0xc693b885, 0x35538de3, 0x668de301, 0x44d7b5bd,
+ 0x1fbce9f7, 0xbbe0bff0, 0x2084ca9b, 0xfd6693f8, 0xb322fd36, 0x53d93a2f,
+ 0xccd89f7c, 0x7326572f, 0xf497d0fd, 0x15da57fd, 0xddbf92a3, 0xefbfd0ae,
+ 0xb065ce8a, 0xc0ffa0a6, 0x3b0193ee, 0xdd7ce81e, 0x2dfb0945, 0x49da3649,
+ 0xfc14ce17, 0xfe4f7d0a, 0x3a1ef9be, 0x1aba7cf3, 0x17f750bf, 0x8fa0ffb8,
+ 0xcec4837b, 0xa7d79bf7, 0xfe23d72e, 0x775e999d, 0xb5e31b24, 0x3d745d3a,
+ 0x5cef09dc, 0x5ba2274f, 0xd75a7a57, 0x3d6aff87, 0xafaff7ad, 0x66b8fa23,
+ 0x7fc89dfd, 0x9af1f5d4, 0xdb8c16cd, 0xfa7ee78c, 0xfe3f1e78, 0x7ee7b705,
+ 0xdffccc99, 0x166d2fb6, 0x32436f58, 0xec0b27db, 0x69fc6273, 0x07665efb,
+ 0xbe2a5cd9, 0x6220a0f7, 0x11c1e47c, 0xd4d7d416, 0xf3061a07, 0x19098a96,
+ 0xbdbdfb04, 0xbd6f7ed8, 0x7d472914, 0x9c0895ef, 0x8c5d13d3, 0x1fdc1e1f,
+ 0x7ffa1db8, 0x968193f0, 0x474f8c1a, 0x1a5ec19a, 0x7ee12059, 0xc5558a59,
+ 0x936b7678, 0x6a3bef15, 0xf6bffddb, 0x97cfd0c9, 0xe52e0bc4, 0x746b26c1,
+ 0xc7f40abf, 0x0888f124, 0xed6d1cf9, 0x1b03ef04, 0x02522b37, 0xd278d97e,
+ 0xfffe035c, 0xc1e58518, 0x6cd4f19b, 0xfbcca75a, 0x2c4d255d, 0xc5c4a5ff,
+ 0xed3a5ff3, 0xefe33457, 0x04904f26, 0xbce90d6f, 0xc992f15f, 0xefd8e9df,
+ 0xd15fb04a, 0x77d1f4c8, 0x0318afdd, 0xde7ca034, 0xd701cba4, 0xbec1244f,
+ 0xed8576c5, 0xcdbfb577, 0x6993d3ed, 0x5d46e371, 0xdeec5fed, 0x7dc1a49b,
+ 0xeff9db23, 0xdbdeec6c, 0x13f3534b, 0xd2df9fbf, 0xd8d30c5e, 0x84b37f5e,
+ 0xbe3c73f9, 0x9a0b8d1b, 0x90e9cbf1, 0x6b481f68, 0xf5041cf4, 0xe7df7095,
+ 0xaae18a82, 0x5d4f8aef, 0x4f1fb66e, 0xb7ef80d2, 0x01a5ef1f, 0xdc79fb1c,
+ 0xbcf56bd0, 0xeec2f605, 0x7092e763, 0x54d1583f, 0x53da4ff0, 0xae765e6c,
+ 0x2841c992, 0xf610606b, 0xeff0f7ab, 0xbfb527b6, 0xec5a7579, 0xbfdb0e7e,
+ 0xd7d9cfd1, 0x47f30428, 0x3f961602, 0x0cdfc662, 0x3b938f0f, 0x2274faf1,
+ 0xbc62a9a7, 0x096f503c, 0x3f3057cb, 0xce4c3c97, 0xfdfe2fff, 0x80006684,
+ 0x00008000, 0x00088b1f, 0x00000000, 0x5bbdff00, 0xd554780d, 0xdceefe99,
+ 0xf26677b9, 0xfc999933, 0x4dc2fe10, 0x00908102, 0x7e100843, 0x502021d4,
+ 0x4540647e, 0x043abaec, 0xa1bf9085, 0x56d3ebb1, 0x4126e1f7, 0x27d3e08a,
+ 0x6796dd6d, 0x57067db5, 0x3b1254b6, 0x770704c1, 0x08a00ec2, 0x80a0db54,
+ 0x11dae3c2, 0x2486a229, 0xec56bb0d, 0x3befdd6e, 0x6664dce7, 0xecfa5c18,
+ 0xf8728376, 0x9cf739ee, 0xfbdf7cef, 0xb3739dfd, 0x330001d3, 0x68776e01,
+ 0xdb00d900, 0x8c802f64, 0xde0820cf, 0x16e91bf4, 0xd305d609, 0x7ae77688,
+ 0xa9dfe0a7, 0xce1a6ba6, 0x2cb0ef91, 0x7a448f35, 0x42d1e986, 0xc639e7a4,
+ 0x699e7a72, 0xf806e286, 0xba5bc867, 0xcfc00e68, 0x03875e9c, 0xd257e9d7,
+ 0x00194876, 0x65049366, 0x528ed859, 0xec373803, 0x65ac0152, 0x3c1daeb8,
+ 0xaa40174e, 0xd21b7405, 0x54fb360d, 0x1e95f1a0, 0xd11a4b6d, 0x87c43d00,
+ 0xa5039a39, 0xd336bed8, 0xbe00b304, 0xadc1fb4d, 0x1ef8aaa4, 0xc5a8ffbe,
+ 0xfb81ce37, 0xec46b7ab, 0x1ff6015a, 0xa40473ba, 0x6c1d7ed1, 0xcf2f25bf,
+ 0xc60285cb, 0x33ffe157, 0xf8c9655f, 0x75f0a6da, 0x2c940f7a, 0x64bf5c04,
+ 0x1a5f8a1c, 0x59994fd6, 0x416dcf63, 0xf49f3d00, 0x9095c9e0, 0xeeaa716e,
+ 0xce34f99d, 0xb6f267d0, 0x21fd4145, 0x69aa725f, 0xce51e90b, 0xc0e96d30,
+ 0x89874ef6, 0xac58bfcd, 0xb7903003, 0x8e0df51a, 0x5335bc81, 0x96fa4d38,
+ 0x4881b2e5, 0x9b7f5239, 0x871e7eee, 0x0f8198c2, 0xddfa471e, 0x3bdc4a07,
+ 0xc290be91, 0x502eb1e5, 0x7a4512d0, 0x363025ba, 0x9d397c82, 0xf7c92f3e,
+ 0x04c0969b, 0x2db4a786, 0xe4bf34e9, 0xca0ef801, 0x3d104243, 0xf16efb80,
+ 0x0216a680, 0x1ce7808c, 0x90004b97, 0x332af82b, 0x2560bad9, 0x8737deb9,
+ 0x1758d5cb, 0x1c856865, 0x3f82a7e4, 0xf5c0f837, 0xc1beb47d, 0x301f10cf,
+ 0x153971c6, 0x4857cfd8, 0xd33cd1f7, 0x0a321e50, 0xfff3d705, 0xa0b014de,
+ 0x3ff8fdfc, 0x325f2fd1, 0xc9897405, 0x2cfd6d3d, 0x33ad88f6, 0x9966ade7,
+ 0x9fe3ab31, 0xecd44c59, 0xbb543ca7, 0xf748ec02, 0xad462f98, 0x37f61d62,
+ 0x9cf91c6e, 0x7d9fde27, 0x8d30b7c2, 0xc7e2f7da, 0xffa783cd, 0x15fbe320,
+ 0xe5019010, 0xd09a2732, 0x31fe5a1f, 0x4aef3fcd, 0x77bff3fc, 0x7db167a4,
+ 0x5f51828d, 0x77227db1, 0x95a35eb8, 0x66f837af, 0xd3e10641, 0xa2d9466c,
+ 0x864d55fc, 0xa2bf6c0a, 0x3a003b9f, 0x0b38e2b7, 0x56adc1c0, 0xe3394ed6,
+ 0x84eb40d8, 0x269022b6, 0x35babc02, 0x1d86b597, 0x0f03394d, 0x7598d4c1,
+ 0x390dde04, 0xe5c7be0e, 0xe93a3d38, 0x5691f3a7, 0xd010284e, 0x5730e586,
+ 0x5d106bc8, 0xf079e906, 0x475b9a4a, 0xbbc9d67a, 0x4b4fb265, 0x98b409ae,
+ 0x14b4d9fd, 0xd30d26d0, 0x715c93a9, 0xb8f42cb4, 0x9e7f66cd, 0xf4f742e1,
+ 0x333ae2e4, 0xeee93ac4, 0x41f37151, 0xe8c4ff00, 0xe2d755f3, 0x67ee1213,
+ 0x0af55a46, 0x454657da, 0xe5fcdc41, 0xbbcbc66f, 0x091ebc0c, 0x8fbf765f,
+ 0xb3fbe3fc, 0xcc7f60ce, 0x2b488af8, 0xfbc547c3, 0x5ee7cff1, 0x6f3ba78a,
+ 0xc99bb7a6, 0x74fea613, 0x2e5fd67e, 0x5e27a74f, 0xe34b999e, 0x8ded99e5,
+ 0x7588e797, 0xe91af2f1, 0xe8c7978b, 0xfd71c9ea, 0xc594b763, 0x33bee3d1,
+ 0xbe7c6e37, 0x1747195e, 0x371658ee, 0x9aeb427e, 0xeee27a38, 0x2f8dc66f,
+ 0xf5c5540e, 0xf9abec97, 0x253ff48b, 0x9e3718d8, 0x1afa6cc4, 0x7d0b4ffd,
+ 0xbfbd6e2f, 0x9dfffe96, 0xcf7e8ff4, 0x7a44bfd0, 0x42fa499f, 0x1c36593f,
+ 0x06b89c9f, 0xf8674bf9, 0xda12eb8d, 0xe9a95ea5, 0x0cbebcc4, 0xf7d82ddc,
+ 0xc895ec8c, 0x51468dbf, 0x6c6fd09b, 0xf9354133, 0x4c981ffd, 0x86d3790f,
+ 0x94e4dced, 0xaacffcd8, 0x14b8a660, 0xe94d6e3b, 0x4da338f0, 0x78d89a77,
+ 0xd37edfc3, 0xd144b5a2, 0xb9974e9f, 0x9b3f453f, 0x707f44ee, 0x21427a41,
+ 0xe964a937, 0xc594af8a, 0xd8bc879d, 0x6a4b213a, 0xd86336c4, 0xa15f6bbf,
+ 0x81a82e52, 0xfe213fbd, 0xbdeec94f, 0x486fffc8, 0x17492320, 0xef3f166e,
+ 0xa696fc37, 0xf8633865, 0xe2334c1a, 0xf14196ad, 0x42e1f073, 0x3fced7e6,
+ 0xf50b4e88, 0xfbe55e7f, 0x115fc631, 0xe153ed7e, 0x9fc97ad7, 0xabfb8659,
+ 0x5d38fcf7, 0x4fce79c3, 0x18c1a582, 0x390b1539, 0x2c1c1981, 0x3ae3ccee,
+ 0x4bb350bb, 0xdff388d9, 0xa16c2ef7, 0x13fbee75, 0x6f7d896c, 0xfe6153b6,
+ 0x6653b671, 0x726c5aed, 0x316bce51, 0x18cb39a6, 0x5db0911d, 0xb2140275,
+ 0x7cbed5cb, 0x0ef28485, 0xe176cfb8, 0xd1480b92, 0xe03ddef8, 0x9fffc855,
+ 0x9d3eb07b, 0xf3cd0dc6, 0x117713c6, 0xa2a2d73e, 0xd7792f29, 0xe8392ba9,
+ 0x936e060f, 0x75c49c58, 0xfbdcf4ac, 0x2927e8c0, 0xdf039cbe, 0xafa8b3d5,
+ 0xf366e035, 0x7222f319, 0x05ccfce3, 0x38992215, 0x12c17e8f, 0x347c8bd8,
+ 0xfa825e52, 0xc11eec69, 0xcd7f5fe2, 0x827fdb1f, 0x1d1a1ee3, 0xfaf14b1d,
+ 0x8a9fcd42, 0xeff7cf48, 0x7d434196, 0x77c5377e, 0x90c0e117, 0xaf87f9c3,
+ 0xc63f53a5, 0xd867a65d, 0x65ef716f, 0xdecfdbf2, 0x73adc633, 0xde9bb82e,
+ 0xd0140a83, 0x67f11b9c, 0x496814b4, 0xe06a352e, 0x3e43dfe7, 0xe6c294e1,
+ 0x59b2f033, 0x5f31a5e0, 0x978b111b, 0xbc21f4c6, 0x71ab7cb0, 0xa6ecccaf,
+ 0x0016dbb1, 0x8159cb94, 0xebfeff3b, 0x234f7d2f, 0x1f3de782, 0xc4346e21,
+ 0x3711efc9, 0x8fbdc61a, 0x3f443711, 0x886b7b2a, 0xfe9e8fdf, 0x79a3eec8,
+ 0xbe35b9ef, 0x7381a5fb, 0x3df2437f, 0x083ef1c9, 0x5f98e783, 0x28d62cef,
+ 0xf0785baf, 0xebca39fa, 0x9a2d3a1a, 0xceabe905, 0x6967f1e8, 0x680921fc,
+ 0xc6c4437c, 0xa743559c, 0x7f61b014, 0xfb63a84d, 0xda6ba468, 0xd8539756,
+ 0x7221dbf0, 0x901ff507, 0x7fd8cd02, 0x7b5eab79, 0xf0b87509, 0x6997ebd5,
+ 0xf957bede, 0xeab657bc, 0x9013cc1b, 0x03feb03e, 0xd3aeaf9a, 0x6fd43602,
+ 0x8ea2339f, 0xa43af5a6, 0x1d57ad20, 0xf34aa1fc, 0x7ab0bf57, 0xb539a53c,
+ 0xc6aa9afb, 0xbebff8c7, 0x0d55a783, 0xf9dd54e5, 0x5c62c5c3, 0x015f0f39,
+ 0xfec63766, 0x369a0737, 0x2ee36398, 0x7b275bfe, 0x2df77e12, 0xe175ff21,
+ 0x271216c2, 0x67ae95fa, 0x7657e625, 0xb872bf33, 0x85fedffd, 0x8bf43bd6,
+ 0x281b8409, 0x837935bf, 0xb1716757, 0x5703ac41, 0x9ea951de, 0x2e54e869,
+ 0x7c65e7c7, 0x77a735fc, 0xf92673af, 0x85b49855, 0x79f13bd5, 0x25940ee2,
+ 0x7e7ae1e5, 0x390fb30a, 0x8f5d406d, 0x069f7cfc, 0xc7663f20, 0xf4855a80,
+ 0x5718970e, 0xcdec0d60, 0x3ebf91bf, 0x67ad99a7, 0xac5f002d, 0xcfda30df,
+ 0x82b1ff44, 0xd528d54f, 0x9515da17, 0xf910db70, 0x7f90d544, 0xc5c3e87f,
+ 0x7def249e, 0x6295fc22, 0x29ef56f2, 0x468fb61f, 0x714a39a9, 0x44d0f1aa,
+ 0xd67a674d, 0x2ebf8ca3, 0x58fb469b, 0x5993f078, 0x3ef998d1, 0x578c7c43,
+ 0x5f86e986, 0x2155387d, 0xe1fcbdb9, 0xcc7a7354, 0xaad2723e, 0xe0f94903,
+ 0xbb49e2f1, 0x5bad0af7, 0x35a2d07f, 0xdcdb7c33, 0x3877c211, 0x44668dd5,
+ 0xcb9b56f8, 0x3f7df163, 0x2c21bbe3, 0xd0e911bb, 0x6bed5a10, 0xddd3e362,
+ 0xb43906a4, 0xc99c2740, 0x23c32f0e, 0x37ae27fc, 0xfe30e28b, 0x756a3fa0,
+ 0x78477efa, 0x55e9a731, 0xdaf898e6, 0x35e68a60, 0x5f3fa44b, 0xfb1882eb,
+ 0xad74d393, 0x99e48b39, 0x61b596e9, 0xae2629fd, 0x6a2d3e97, 0xdb1c5177,
+ 0xbd91f38a, 0x93b13e44, 0x3687b7fc, 0x3beec958, 0x47ae0e9c, 0x481cd755,
+ 0x877a09b7, 0xbb26adea, 0xc29391da, 0x2e31b5eb, 0x09ffef86, 0xaf647daf,
+ 0x3e028eb8, 0x09f77f56, 0x058df5bc, 0xf7297fe6, 0x94c99c23, 0x199215ef,
+ 0xce341cf9, 0xbdaa6a1f, 0x87976b14, 0x7f1373ee, 0x1f7f0a4a, 0x135e3872,
+ 0x7175cdd7, 0xaa693d9c, 0x13105d6a, 0xe5c71387, 0xc399b8d0, 0xceb30072,
+ 0x697001ce, 0xfefc324f, 0x776959c2, 0xde5dfe91, 0xcd87e449, 0x51e118c4,
+ 0x81f29353, 0xd95cb3e3, 0x2e4de3c3, 0x554f5b07, 0xeb920e7c, 0xad39397f,
+ 0x67265ea8, 0xec8d6c34, 0x057f6878, 0x9b3b526a, 0x91def82e, 0xc4f7af1f,
+ 0x38c4d371, 0x56e7a4c5, 0x65879f11, 0xdafd3766, 0x31bfd300, 0x9d723fae,
+ 0xed7c3feb, 0x79d90f2e, 0xcf865afe, 0x5c597f4f, 0xbbccc726, 0x853959ce,
+ 0x12e793f6, 0x5cf45078, 0x2ba47be2, 0x733f1f7e, 0x62b8677a, 0x4c601fce,
+ 0x04e12dd6, 0x16e07d44, 0x83eb0ef1, 0xb57c6649, 0xe4dc521f, 0x1e443bdf,
+ 0xc32f066c, 0x35b82a49, 0xe07af756, 0x7f70f3d7, 0xb04c472d, 0x1d3b4913,
+ 0xf3628c72, 0x04d8b079, 0x8a326cbb, 0x4b158f08, 0x323212bd, 0x9ae25fec,
+ 0xc86d8df6, 0x65d021ef, 0xd7c73f5e, 0x3c91e0c1, 0xfbfd6c52, 0xd5adcd5a,
+ 0x5af9cfbf, 0xeb13cec8, 0xd31139df, 0x16e3357a, 0x96d7e0ea, 0x1f83ad25,
+ 0x53d7c574, 0xc634bb0f, 0xc712705c, 0x12923061, 0x3028e7e0, 0x845c7083,
+ 0xedfa84e1, 0xa555bc39, 0x275649be, 0xf4d733c6, 0x418c76a7, 0xe5cf1b3b,
+ 0xfd0b7440, 0x8df3ca3b, 0xb5fabaa1, 0x44ff2cc9, 0x7ab3247f, 0x497821d2,
+ 0xe6395fd0, 0x7118bc49, 0x91e5d5c7, 0xc9da5fe3, 0xb4bbb6ff, 0x067e92df,
+ 0x7940ca4e, 0x551ccd9c, 0xebec499d, 0x98b3e520, 0xe2e4bc8f, 0x921ad67e,
+ 0xdf5c013c, 0xe28079aa, 0x98e1cdbc, 0x59d8c72e, 0x85c78b95, 0xf217e3fa,
+ 0xaf23cc54, 0x97b4de9a, 0x5d75fce2, 0xcc74ec07, 0xedfe7b53, 0xb4147459,
+ 0x4edbecc8, 0xb4a9fb76, 0xf94ac8a7, 0x54c08ee1, 0x52304f92, 0x77714190,
+ 0x7374198a, 0xf8fc8dd9, 0x50a6e377, 0x33bb0d86, 0x3c253b59, 0xa7e51363,
+ 0x2fdf08fe, 0x0ba0a1ad, 0x8c490e2c, 0xb8b50bee, 0xbfff3e68, 0x3f228f76,
+ 0x9f9b3fb5, 0x45f8be2f, 0x0cdf7f09, 0xacff1a66, 0x1ef029cb, 0xd479d130,
+ 0xd58e717e, 0xc6cc85f7, 0x094feb19, 0x881d902d, 0xeb48d283, 0x164e7651,
+ 0xca7cb0b6, 0x797002f6, 0xa3cf3184, 0x4bc39cf3, 0xbf51e280, 0xf612dc13,
+ 0xb00ca7b7, 0xdba067fc, 0x912f3da2, 0xec815adc, 0x75e55dbd, 0xf602314b,
+ 0x73f0da40, 0xf85b3d63, 0x44e674a7, 0xfc50f0b8, 0xe15b99b3, 0x7958b4b6,
+ 0x877933a7, 0xa6c80f29, 0x34a62275, 0x77d1cfca, 0x1af8cf3e, 0xbad813e6,
+ 0xccc59f06, 0x03abb7cf, 0x62cf1f97, 0x0708397c, 0x84f9c0c5, 0xfc8d44f0,
+ 0x61e1cd9c, 0x3439b0fb, 0xc8dd2eb7, 0x262a7f97, 0x3f3f6860, 0x7b218668,
+ 0xa7f6fb26, 0xb456d30c, 0x8e02f685, 0x3c37d06b, 0x0c7e68b5, 0x62a68e4d,
+ 0xaed3fdf8, 0x1b6d4f8d, 0x748dcec3, 0x8a9ff519, 0xf68bba6d, 0xbd0aedc9,
+ 0x8cbb27a7, 0x728dc1cb, 0xfef2b54a, 0xf388f1a1, 0xf8d3a234, 0x91c5b738,
+ 0xd99f2cba, 0x18bd900b, 0xa5b7d9f9, 0x503be5c8, 0xf43fbdb5, 0xbee29466,
+ 0x1f474d7a, 0x9f71c36b, 0x45160fad, 0x7d50fea8, 0x5f3e13ef, 0xd76abf79,
+ 0xedbbf214, 0xf9057b8a, 0x23fea89f, 0xa8bf0796, 0xec633b68, 0xe40cc60e,
+ 0xd7137e10, 0xfe6f9ff1, 0xfdb9e511, 0xaacd2487, 0xc81dff91, 0xc21bbe23,
+ 0xd7e4ab1f, 0x643e87fd, 0x9913ed79, 0x5eb42bbe, 0x2169a845, 0xb40e75c9,
+ 0x2edf90b6, 0x3041f911, 0xc193fb97, 0x37cf4533, 0x9ec1e8c5, 0x0edc7129,
+ 0x9c51c6f8, 0x3d7b0b0a, 0xb627f54c, 0x2fee475d, 0x44bbf9a4, 0xd7bc6c7d,
+ 0x93474704, 0x35e19bdc, 0x9dc50ed6, 0xe1297980, 0xf59ce4ac, 0x78cc4f21,
+ 0xbf3f266b, 0x02f58ab5, 0x133fbe99, 0x2e47b5bf, 0xe7da76aa, 0xd51e60a5,
+ 0x93ac4195, 0xc8fc491d, 0xd826fd90, 0xa03cdf93, 0x15ff78d2, 0xf5057e60,
+ 0xf5032dbd, 0x685cffb7, 0xde7c7af2, 0xa0c93a85, 0xaf3ce17c, 0xef14bb13,
+ 0x74df1a68, 0xe4a9f3f6, 0xa82806c7, 0x779f7fe1, 0xb9238ed7, 0x532bfe21,
+ 0x803acec8, 0x4ec335f9, 0xf14ec94b, 0x7fc252fd, 0xccc5d139, 0x3dabb72f,
+ 0x765d98cb, 0x12ec8099, 0x01eccff1, 0xb8a0eff1, 0x7b40ea5c, 0x644fef60,
+ 0x63dede76, 0x167cb0f2, 0x4604fafd, 0x744dde57, 0x0722cf7b, 0xe21373b3,
+ 0x35ec8cb9, 0x13cd9472, 0xa634a004, 0xec6f025c, 0xcb954139, 0xf86cf0ce,
+ 0x7ec22dcb, 0x0cb49383, 0x5523ee37, 0x23ece396, 0x5a725e26, 0x7fc7d3c4,
+ 0x9ea793fc, 0xa78f4f99, 0x10e138f3, 0xce9b5271, 0x22a3fefc, 0x3ebe3556,
+ 0xe51b5577, 0xacc96fe5, 0xa738b0ff, 0x1c9c0888, 0x1414e715, 0xcfd43437,
+ 0x75fce26b, 0xf41ed226, 0x5b3cb3a3, 0x556e5216, 0x18f5b4b1, 0xc1bd73b5,
+ 0xce329485, 0x4c73d75f, 0x425e66e1, 0xfa3cebf8, 0xf933128d, 0xcebcf3bd,
+ 0xe072fceb, 0x0e511783, 0xf9461d8f, 0xb8538927, 0xcc3f861d, 0xee4346b3,
+ 0x92fdfd8d, 0xf97e47e1, 0xfa43aa0d, 0x1a61e53a, 0x020363e3, 0x9955e89b,
+ 0x474a78bf, 0xf4c83ec6, 0x7944c9ac, 0x35bed9ca, 0x9cef9499, 0xcc8732fe,
+ 0x45ccebb2, 0xaa773f56, 0x4fc2129e, 0x9c960167, 0x7b7a7049, 0x51f4c2a6,
+ 0x673f896e, 0x84c7da31, 0xb0e9141d, 0xb1f5624b, 0xfd5008ec, 0x547b29dc,
+ 0x80ae83cc, 0xf91e76be, 0xf81e711b, 0x0f1f8808, 0x6cfd41fe, 0x9423e414,
+ 0xdadc60b7, 0x77128cf8, 0x2de4673e, 0xb07bc675, 0xdaf844c5, 0x1fe09614,
+ 0xcfd51651, 0xa3af8fc5, 0xd9e705bc, 0x7c73da1c, 0xe6b5ea34, 0xca7e8485,
+ 0x79b9d85b, 0x75a3d590, 0xfe5c4a6d, 0x38a658f2, 0x42842c0f, 0x57105fca,
+ 0x66284fcc, 0x1c416138, 0x6df6c84f, 0x6fdf3b20, 0xff42f2e2, 0x0373ecca,
+ 0xb79f15e1, 0x34bf7257, 0xcc021570, 0x8f05f67e, 0xb9df91d9, 0x5a6ef96d,
+ 0xf799ae63, 0xf3e50dcf, 0x40730d7b, 0xa90a8d5e, 0xb316f8f0, 0x9cf75afc,
+ 0x54b945c9, 0x0e097f0b, 0x59b5fe7e, 0xe45abeec, 0x4a039b77, 0x2fcefcd2,
+ 0x4081cdc6, 0x69bbad0b, 0x47cec49f, 0x8fc5f76b, 0xd5390bf7, 0x9c7d3eed,
+ 0x83eafd8e, 0x4e42fd09, 0xf3fc50fe, 0x78727c03, 0x1e5390d6, 0xf373b1e4,
+ 0x6756b713, 0x7cf0a67d, 0x8f316de3, 0x38161fd1, 0x906dc06a, 0x7202eb7e,
+ 0x2d547080, 0xf79e76e9, 0xdc7ada42, 0x060306df, 0xb941fe1a, 0xb4e42c3c,
+ 0xed87e041, 0x7fafdf1f, 0xbdd00a4e, 0xc74fc3d3, 0x5e035ff3, 0xdf3e3475,
+ 0x952df9d8, 0xf112f5ce, 0xb0a6dd56, 0xc846b7fc, 0x355f1127, 0x5569f843,
+ 0xe225be29, 0xdd27c1ab, 0xb79e7f84, 0x37f96fff, 0xa6235cf4, 0xec2255a9,
+ 0x1ff6a89c, 0xddaeb724, 0xfb435f7c, 0x4bfbfb11, 0xd0de75f7, 0xcc9864f7,
+ 0xf334bdf4, 0xf8a5eb16, 0xe543bb7c, 0xe6683376, 0x9e06cae7, 0x2c5fdf12,
+ 0xbb25f5f2, 0x357ade79, 0xe74ecd74, 0x833dfdc4, 0x69ad6076, 0xa247c529,
+ 0xa5f8c7c7, 0x5d79324f, 0xa3f73dbd, 0xbf3e501f, 0x637143a4, 0x637507a6,
+ 0xf1c52f15, 0xe7afb1ba, 0x2bad8f8c, 0x1d25f8c5, 0xe8db348f, 0x9297e23c,
+ 0x3fb2cc9b, 0x894777fc, 0xf724dbd6, 0x78ff7c04, 0xe66fe0cf, 0x53725e91,
+ 0xfe7cd167, 0xda4b3bee, 0xfcfe3e91, 0xfd6c770c, 0xf7c5dc79, 0xc2ac64b7,
+ 0xa8ef6ae2, 0x415a7fd4, 0x3d9e85e7, 0x5f7bbecc, 0xfb25597d, 0x20976fef,
+ 0x9e3a1717, 0x1d25ec7b, 0xf07bdde5, 0xfac94ab4, 0x6ad3cec2, 0x85f26bf4,
+ 0x458e58ab, 0xab6a79d8, 0xb78f754a, 0x946af7eb, 0x3e17a7f2, 0x3554e764,
+ 0x3e53e794, 0xd01c9cf6, 0xbac79ff0, 0x4f09515f, 0x8c126d0d, 0x57ed8fc8,
+ 0x41f93f58, 0xe36e3fa2, 0x69c0d4fe, 0x81a5c095, 0x55b70353, 0xd86cffc2,
+ 0x86971c91, 0x9e08da9f, 0xbe70a3ed, 0xabd6da47, 0xd23d0794, 0x137e3f1a,
+ 0x68d399d5, 0xa6e5c73c, 0x9bfdf1dd, 0x33a8f087, 0xefe89d3f, 0x1e04b24a,
+ 0xf098a18b, 0x1aa91838, 0x7fdc4667, 0x1c66ba7e, 0x7947b924, 0x2377c453,
+ 0xbe4cdebe, 0x2a6ba17d, 0x18ff45c5, 0xfe17d585, 0xc6a1ff31, 0x166665e2,
+ 0xf0e2cbc7, 0x569e981f, 0xa22c8f84, 0xaf8256f5, 0x32bce48e, 0x7ca0ea9c,
+ 0xdb944579, 0x25b0b2f1, 0x3f889010, 0x2b878b13, 0x708db821, 0xc2d87fd0,
+ 0x955f29cf, 0xc204de58, 0x72126dbf, 0xbce424df, 0xd1b1eb09, 0xa883ddf4,
+ 0xdd441bc7, 0x9ed279bd, 0x340254e3, 0x93bafe88, 0xe724ecc7, 0xcffdc065,
+ 0x3ff720b2, 0x788cfe86, 0x18f76892, 0xfd241ea9, 0x402d86d7, 0x172c33df,
+ 0x1b7967fe, 0x46e91ffa, 0x323fd03f, 0xef47e195, 0xc6277ce2, 0xf8ce86cf,
+ 0x78b20bf1, 0xf2283a3e, 0x712caae0, 0xb6f4203e, 0x4b520062, 0x9a65be71,
+ 0xb7b00eec, 0xfeb4cc7a, 0x4788a989, 0x5684ff9c, 0xa24be198, 0x8dfda34f,
+ 0x7a0defc8, 0xe18b9d15, 0x35a3a0f8, 0x7f7eb62d, 0xebd78b2b, 0x9d647335,
+ 0xef5310f4, 0x4fcb2aac, 0x377cef5a, 0x31bfc70b, 0xd3d3c366, 0xcf1deb63,
+ 0xe3c2229e, 0xbc7f73f7, 0xf157be82, 0xd2ff71b7, 0x66f38157, 0x2c0efe50,
+ 0x59b7f61f, 0xf8975402, 0x37544f11, 0x90bc212c, 0x3ba586bd, 0x2f582f09,
+ 0xaff3493c, 0xdc3b2ba6, 0xc610eaff, 0xf57e9c69, 0xfc303fa2, 0xf7cf1c9d,
+ 0x911b728d, 0xea307eac, 0x782f8686, 0x6f3c6a7e, 0xfd594730, 0x189610d0,
+ 0x5e8f3b7e, 0x7e47cbcf, 0x98ffbbfb, 0x50db1eb7, 0x9db38f16, 0xf48bc195,
+ 0xede7c91d, 0xe879a4d6, 0xb6971f90, 0x50697b31, 0x3f2c39a2, 0xe0f98439,
+ 0xde37ac6c, 0x1bd594fe, 0x0f6d479d, 0xcab43cb1, 0x35f1ce37, 0x66826a7a,
+ 0xc336cf96, 0x9e52d636, 0x6dff9b13, 0x52eff072, 0x48388a36, 0xeb8813f4,
+ 0xf6f6388d, 0x83fd1bb2, 0x05ea6fe1, 0xbe8337ae, 0xa3749e7d, 0x7617a89f,
+ 0x67ba5b53, 0x8968a53b, 0xb0bd5079, 0x59fccc27, 0x83cc4bdc, 0x6bc04ade,
+ 0x2c29dbd3, 0x293fedcf, 0x184ce83b, 0x51f3fbe5, 0x7e61ef94, 0x1ce4905f,
+ 0xcf8153f4, 0xd9ff715e, 0xf9332154, 0xd6f0e699, 0x8e509bc8, 0xa7fd370c,
+ 0x275402d3, 0xa57e1c94, 0xbb507080, 0xdac5c70f, 0xc7d1ea1f, 0xf00a0fbe,
+ 0x2a60a573, 0xfa31d3bb, 0x657e1ff7, 0xe9ade132, 0xb88b2fed, 0xa917ae7e,
+ 0xcfe73759, 0xd7892568, 0xd78926bf, 0xa8e65dbf, 0xff2eea9d, 0x881bd921,
+ 0xefa1abd1, 0xc08e040f, 0x8bfcebcc, 0x9ba31a59, 0xa61f1cc2, 0xfae2de6e,
+ 0x8f39f96b, 0xa1bfd6c2, 0xf37112bf, 0x880ef135, 0x5f80c42f, 0xf3f86019,
+ 0x7e31369f, 0x7307a7fc, 0x4ebee362, 0xff208ef3, 0xcc0754d7, 0xf902a49f,
+ 0x3a67f45d, 0xdfcbcbd5, 0xea7cb1b3, 0x15aec178, 0xc8157fcc, 0xb1ebfe40,
+ 0xc6266bb7, 0x598d8bc6, 0x254c3f32, 0x1652e439, 0x5f5f0cf3, 0xd619a1c8,
+ 0x8e027388, 0xb9338fe7, 0xeafac15f, 0x89cf64cf, 0xe6add5f5, 0x16dd4dc5,
+ 0xff6473a0, 0xcefb0b05, 0x4deef3e4, 0x2f877eac, 0xdfc9137c, 0x8d37cf80,
+ 0x6f0ec7da, 0x3fcf489a, 0x1a79bc3f, 0x9a94f73b, 0x4e99e2e3, 0xbe52e5fc,
+ 0xc3473674, 0xb3eefafe, 0xfab8bbec, 0x4ff1856e, 0xcb3c6c74, 0xefe7e6c8,
+ 0xec6c47fd, 0x0282437c, 0x1f18038e, 0xe75d6f37, 0xa8bf2ceb, 0x589ec90b,
+ 0x8def183c, 0xb171e6cb, 0x20e05b30, 0x9e987928, 0x175b783b, 0x53f1997a,
+ 0x1e9904ab, 0xde14da9b, 0xcc5bcedf, 0x3a1f193b, 0xbfe274b8, 0xf9bfce83,
+ 0xe73b08bd, 0x3ecc91c0, 0x07152706, 0x6bfd2276, 0x1d72847a, 0x3f80980c,
+ 0xe4fbb0b7, 0x19851396, 0x13c1fb84, 0x8b25672f, 0x3dd26f1b, 0x54e5420a,
+ 0x1243af3e, 0xf3652ffb, 0xe75387f3, 0xb53b3fb9, 0x993137c0, 0x92a1d35f,
+ 0x9092e9d7, 0x34b2a777, 0x45dc7dd9, 0x31bedf31, 0x4fda29fa, 0xdd8d876f,
+ 0xf93af5c7, 0x03c2ea79, 0x1499cd27, 0x99a53b7f, 0x276a4714, 0xbe88bbbd,
+ 0x9cba4003, 0xe46d5afc, 0xac77bb10, 0xec58eb6f, 0x4747c249, 0x32dfc736,
+ 0xe67df935, 0x3bff44b7, 0x7516cee0, 0xae132ed4, 0xc50acef7, 0x1de593b1,
+ 0xe891b49e, 0x7e12ef87, 0x0a95eef8, 0x01de53cb, 0x16f7e14d, 0x95617efc,
+ 0x0977b3f0, 0x22aabcff, 0x57be3fb9, 0x39fab3cc, 0x17ee9278, 0xc7e27b56,
+ 0xbdf22bdd, 0xf361e035, 0xa134bddf, 0xf77de45f, 0xc1f2137a, 0x8b87e16c,
+ 0x70fc88a0, 0xe903e310, 0xc6d8b1bd, 0x29f2ece2, 0x09e69213, 0xd2ffd1c7,
+ 0xc42703f7, 0xfe860477, 0x65df8a9b, 0x91d4ebf1, 0x99392ff3, 0x4141b6ff,
+ 0xe1b1fb92, 0xfdd865f8, 0xe2ef5c3d, 0xc1dea1be, 0x7ff43479, 0xd8a32b15,
+ 0xff432d73, 0x7f73674f, 0xb6cfbb59, 0xb0bef625, 0xa38ce83e, 0x5b91a1fd,
+ 0xfbf8c52e, 0x8c73815a, 0x73d8e601, 0xdf641790, 0xf4d9d9d3, 0xcb2f6b3d,
+ 0x2c0771af, 0xf2bee17e, 0x2cf2bec4, 0xeae97131, 0x7149f5c8, 0x973fbc3c,
+ 0x167ffdce, 0x5b148f6b, 0x07d5fd98, 0x6bdd00a5, 0x3db847d5, 0xb123dfd6,
+ 0xcea2c273, 0x857bec23, 0xb7248bb5, 0x33b1bb87, 0xa3819fc4, 0xcf1e5655,
+ 0xc90cbc0d, 0xfa88e04b, 0x25dfbe29, 0x9e227be2, 0x62cf4226, 0x8f3eff9a,
+ 0xecefa6e4, 0x75a38a6e, 0x30a75fd3, 0x211c3374, 0x9bf2152e, 0x24fa7889,
+ 0xf249d7db, 0xed71fac3, 0x54ff9c14, 0x8479c7f1, 0xd89b869f, 0x1d856fd1,
+ 0x4fd34bed, 0x3baffc51, 0x0fd5ee20, 0x24a28714, 0xf2c01397, 0xcf675ec0,
+ 0x1f9e46f6, 0xfaf57bb3, 0x0f7d8d88, 0x754e1f58, 0x6cee88db, 0x754c994a,
+ 0xa7765864, 0xf3a2bd22, 0xdfaa22f4, 0xeff39457, 0x01d41a3c, 0x3ab68796,
+ 0xbf89277d, 0xb8a6ee95, 0xcf8374fb, 0xd13de19b, 0xe1245dcf, 0xfcf5ff64,
+ 0x972145cf, 0x72d793c6, 0x9d7e1326, 0x5365dfbe, 0x45fd793c, 0xfcf6ae95,
+ 0x9c595f93, 0x8d38d1a9, 0x76d95b8d, 0xe31d1b64, 0xcf4ffc1a, 0x4efe3076,
+ 0x2c318129, 0xb5bd2cbf, 0x0e9a4bef, 0xf29531bd, 0x2723bee9, 0x3831aaa7,
+ 0x7f446def, 0x4d7f449d, 0x6bf61260, 0xad24ad66, 0xb70ef911, 0xb1f77f67,
+ 0xe85f3a1c, 0xa52e3b25, 0xe29dacf6, 0x3bc77d64, 0x779409f6, 0x98d6f174,
+ 0x66586aef, 0x2d1cc0e3, 0x963d37ba, 0x7f1927bf, 0x1e7c8357, 0xddd16880,
+ 0x5bfb6253, 0x40fdaffe, 0x03f30e7a, 0x603f38d1, 0x7bab09c8, 0x8799d59d,
+ 0x9e9eec2d, 0xbf625bee, 0xe1ce2acf, 0x1636697e, 0x73af643d, 0x90b99ee8,
+ 0x3c333352, 0x2219b440, 0x07dd1766, 0xddfe6447, 0xe7e618da, 0x67f58967,
+ 0xe847239b, 0xe239cdbb, 0xf42e727e, 0xc3b771b0, 0xe03d6b00, 0x095b5330,
+ 0x5856d66e, 0x6ca9cb23, 0x65060d2f, 0xc7247fd2, 0xe56cbcec, 0x4c90f2bf,
+ 0x3372c3df, 0x1e4365c3, 0xf163dd32, 0xf712ffef, 0xf1c39953, 0xfdc3db38,
+ 0xf416a50f, 0x040566dd, 0x6df9fdd9, 0xe8f71510, 0x0f31f7c9, 0x37ba37eb,
+ 0x99d30dbb, 0x008f2614, 0xf69f3f1b, 0x4fdb2723, 0x33533974, 0x7f10722c,
+ 0xf4c72452, 0xefadea55, 0xd8073fa3, 0x030df6bc, 0x0f978f7d, 0xc3ba3bdf,
+ 0xdf47bc6f, 0x0f1e4a99, 0x6dd50efb, 0x1d508b4d, 0x1de8da83, 0xe80563f2,
+ 0x56aa7337, 0xfe1ccce6, 0xc07c1f9e, 0xfc48cfbe, 0x7bb69f9e, 0xbbf86725,
+ 0xd27be32f, 0x9a35817d, 0x2eb1f109, 0x1196eacb, 0xbcd6651f, 0x657bec19,
+ 0xe1256fa7, 0x36d482ea, 0x0e624d81, 0xa87964cc, 0x782a55c0, 0x92ff682a,
+ 0x027df8c7, 0xc5d17860, 0x039eb7f9, 0x5238f7ec, 0x2bf7fc2d, 0xad0e2176,
+ 0x8d7e862e, 0x27858fbe, 0xef946a16, 0xdd5a776e, 0x8859cf94, 0x7e61d4df,
+ 0x3bfcac5b, 0x5e6b168a, 0xf1b8fc80, 0x3ca2585d, 0x3d16505b, 0x56dd0ecc,
+ 0xfc272f96, 0xc59b47fe, 0xcf922df7, 0x472bd3b7, 0xf25c1e50, 0x2cb9f9ab,
+ 0xcc79472f, 0xba61e437, 0x7028f7f1, 0xfda1dfff, 0x82fefe27, 0x04546fb1,
+ 0xc8438f03, 0x838390d3, 0xc77144f4, 0xf4327a83, 0x9f2c305c, 0x0e5c295d,
+ 0x52417d0a, 0xc8d5dec8, 0x6ff7135e, 0x01bfefec, 0x8f1a3ec3, 0x00003430
+};
+
+static const u32 xsem_int_table_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x277bff00, 0xa3f0c0cd, 0xa5fd811e, 0x79ba1818,
+ 0x8968c550, 0x30327137, 0x303170b0, 0x06710268, 0x2036ded0, 0x17c40edd,
+ 0x1022f880, 0x3033719b, 0x11710214, 0xf2032f10, 0x56dcd093, 0x50c0c4c1,
+ 0x4035c405, 0x3ac4075c, 0xba0c0c8c, 0x1fdbc48c, 0xf0c0c42f, 0xd7c10c42,
+ 0x48606710, 0xff9fa491, 0x54ee1b07, 0xc27dafa1, 0x860c0caa, 0x4662a8ba,
+ 0x5d637c68, 0xa09866fc, 0xf1a29bc9, 0x17e8f0cd, 0x87e540b4, 0xe3f2a219,
+ 0x7618198c, 0x3709a922, 0x7416efc4, 0xf7a802fc, 0x00031025, 0x22037beb,
+ 0x00000368
+};
+
+static const u32 xsem_pram_data_e1h[] = {
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0x73b9f8b9, 0xc999dee7,
+ 0xac84992c, 0x5d86f12c, 0x48409c04, 0x5876c443, 0x0622b4a4, 0x30a20a97,
+ 0x9037d96c, 0xff69f0fa, 0xa5ab0819, 0x68d06a1a, 0x68304ec1, 0x1a0741b0,
+ 0x01c04830, 0x6a2be2d4, 0x6d8ad3ec, 0x2c3480c5, 0x0dc46486, 0x3ff2d3de,
+ 0xcdce77df, 0x11337bdc, 0xbffbfb6c, 0x4f169fe5, 0xb7fb3dce, 0xe77cef9d,
+ 0x92cc5f3b, 0x407e1240, 0xa1f865c8, 0x211318e9, 0x5d245c64, 0x88fdfd6c,
+ 0xe5227d53, 0xacc8957f, 0x465a48e0, 0x46dbe42a, 0xb213be45, 0xb16feb12,
+ 0x589346b9, 0xc402d348, 0x93df3f45, 0x84592268, 0xf826e7dc, 0x9bce25b3,
+ 0x12126426, 0x6f7168de, 0x25dfa74d, 0xd02425c5, 0xb720fd74, 0x4a76805f,
+ 0xebc3e412, 0x9a56f725, 0x165f5f27, 0xcad9bda1, 0x27e813da, 0xf87c9089,
+ 0xd221107d, 0xe8f89145, 0x024ba4fc, 0x32245ba6, 0x4fce972f, 0x2646df72,
+ 0x73f3223a, 0x9392e427, 0x994efbf4, 0x52efd396, 0x37d5ae42, 0x2d7e5232,
+ 0xe4fe7011, 0x5fec4aeb, 0xfbb56f1d, 0xd717ab36, 0xdfb517eb, 0x5c17dcbb,
+ 0xcb757df0, 0x2d0fd8ed, 0xc39675c1, 0x9e5a14fc, 0xa6265270, 0x3811ff48,
+ 0x351c7005, 0x71d0b4af, 0xf08847bf, 0x84ed37ca, 0xb76abbae, 0x5c2858a4,
+ 0x4296ef26, 0xd2f9a03f, 0x7900213a, 0x211b01d3, 0x9b9d6e14, 0x94e43e59,
+ 0x7cff50bd, 0x2ed3cd3d, 0x8fad2dca, 0xdd7000dc, 0x38ad922d, 0xe609ae4c,
+ 0xadc2aedb, 0x6cf3e599, 0x775a5b2c, 0x2fb42e70, 0x1b10b668, 0x6f74afed,
+ 0x681b8cfe, 0x4488ff3e, 0xb6e94aa0, 0x9a5f7215, 0x41080c2f, 0x224d77c8,
+ 0x8f7fbe38, 0xeb46d818, 0x935ab977, 0x3c70a4ee, 0xca256957, 0x676f3a30,
+ 0x141dd26b, 0x9d81450e, 0x515da153, 0x1201e0a3, 0xdb7bbc9a, 0x5db4a9eb,
+ 0x63c176e9, 0x6e2970a1, 0x386513b0, 0xfa65c39b, 0x0c49bdaf, 0x2f9680fd,
+ 0xe924eba5, 0xa9ead780, 0x37f18444, 0x02338aca, 0xc39573a7, 0xe4896289,
+ 0x71d3b74b, 0x17b2bb68, 0xb12c0f04, 0x407c44cc, 0x6d7b9d97, 0xc0719eb3,
+ 0x43c856fa, 0xb5aeb09d, 0x0fcbd432, 0x5363dfcc, 0xf2757e60, 0xb45e5a54,
+ 0xd3ce4eb9, 0xe1b8bfe0, 0x3558a23a, 0x941daaf3, 0x630fa5ac, 0x89928e7a,
+ 0x84453e76, 0x200e8378, 0x533c8083, 0x857d17c3, 0x7177c438, 0x9feba883,
+ 0x44909242, 0xe8f7dffa, 0xfe5e14af, 0xab844efd, 0x9ca5b78a, 0x5dbc548e,
+ 0xcc43fce0, 0xff6d2ce1, 0xe008fa6a, 0xbaa7ce81, 0x2fe98dd2, 0xad30532b,
+ 0x3f1054a9, 0x68fc038f, 0xdbcf81ba, 0x344c8135, 0x5e5d71d3, 0x8b3606e2,
+ 0x289dee9f, 0x2e7c7cd1, 0xe3dd27cb, 0x596f9413, 0x2e3e9abf, 0x4f03e6f9,
+ 0xbd53226e, 0x979a54e6, 0x87884b7d, 0xd5be6f8e, 0x213c653b, 0xa3df12af,
+ 0xe4d17eb0, 0x12bc002b, 0xa5c94c12, 0x50235978, 0xb5e14239, 0xe1491616,
+ 0xd29526b0, 0xe3d3c533, 0x233d66f7, 0x09ad7c0a, 0xf67bcf90, 0xa7ec74e1,
+ 0x6991fb16, 0xdcae833f, 0x6cdcd24f, 0x73493f5d, 0xea7ed40b, 0xab989fb0,
+ 0xb9f1e7eb, 0xccf9fa39, 0x79fb522d, 0xae89ea1e, 0xd2575bab, 0xf9fa09bc,
+ 0x7ec12bcc, 0x10f1ef92, 0xaa2fad1f, 0xbd5a43f4, 0x34772d22, 0x98798dc6,
+ 0xd268e968, 0x49cfe81e, 0x474b4ab9, 0x3a31d9b1, 0xc6f38a7e, 0xa67df2eb,
+ 0x4fd5d5f5, 0x2ba81dcc, 0xc2359e4f, 0x770e9740, 0x0f3c75fb, 0x91597293,
+ 0x32bee5ef, 0x7d899dca, 0xfbff38ad, 0xee503afb, 0x1be39fdc, 0x86f3a6e6,
+ 0xff8a12b9, 0xf5df65fb, 0x437428ee, 0x149025d7, 0xa4131548, 0x12b5f2c6,
+ 0x7ea4db83, 0x413d0f5f, 0xc29b97db, 0xfe68e343, 0x8ff13088, 0x80bfeeb0,
+ 0x8b78a530, 0xd4054911, 0x9410b18b, 0xb3d36b7f, 0xe06bf19e, 0xa5006eba,
+ 0xefd22117, 0x0297c93a, 0xafe6d8f4, 0xae7d03f0, 0x60532019, 0x54827212,
+ 0x6983fc84, 0x297901fb, 0x4c8b7f00, 0x7c7687e5, 0x123f8e99, 0xf1876fc7,
+ 0xdf197a3b, 0x375b3032, 0x40ad35be, 0xa655be37, 0x08fe53e3, 0xf1f397fb,
+ 0x0872fc29, 0xc72c94f9, 0x05692df1, 0x995afe38, 0x8fc6e814, 0x4bff1ee9,
+ 0x186bf718, 0xfaca313f, 0xd7e8e607, 0x5fa4569f, 0x4fd6ccbf, 0xf8f9f856,
+ 0x417eb831, 0xa7f5b3f0, 0x5bf5b115, 0xe3ddbf58, 0x2fe1babb, 0x875c740b,
+ 0x07facbd0, 0xffafd04d, 0xfafd129a, 0xf77c6c2d, 0x7c7c758a, 0x271f8e07,
+ 0xbfeb63ac, 0x97c704a6, 0xd00f3e2d, 0xa62fdc91, 0x69fb0022, 0xc940ca7f,
+ 0x98bd0328, 0x84278f0e, 0x93df93ca, 0xfb870881, 0x7ddd1863, 0xcde94319,
+ 0x24a79111, 0xee903940, 0xa69c65c3, 0xca271b8b, 0xe3f67f6c, 0x4f98bebe,
+ 0x88b35175, 0x2c6a4d74, 0xbe742181, 0x1fa2cd9d, 0x6e6a8bf2, 0x9fb8880c,
+ 0x98823d32, 0xffbe0849, 0xada8d375, 0xd31975da, 0x7b52d5c5, 0xbaaf869b,
+ 0x3224fbe5, 0xafce82bc, 0x5c608802, 0xe54edf24, 0xf872a134, 0x90c79524,
+ 0x5e98969e, 0x71ca8a72, 0x37cb4c32, 0xe25e982b, 0xa70eef27, 0x9f09fff3,
+ 0xc199bb7f, 0x10997dbb, 0xb97ff800, 0xf20c8971, 0x9db5716c, 0x8f323d02,
+ 0xf0a78e72, 0xf5004b5e, 0x001dba29, 0x5642ee7c, 0x03c3e424, 0x502ebcb7,
+ 0xb6bf2d3d, 0x3dddae8f, 0x853ab024, 0x61b85fd6, 0x5d3700fe, 0x96599cff,
+ 0x4fec2231, 0x84cfdbc4, 0x99fa4c7c, 0xd59909b2, 0x47ea51b4, 0x92cd7733,
+ 0xda69b64e, 0xf3e9f6cf, 0xf9f40a73, 0x9920294e, 0x14299f40, 0xf7ed1d48,
+ 0xb97d0ade, 0x2134ce3a, 0x8f95e19e, 0x830a13f7, 0x5ee9fa54, 0x67c0c748,
+ 0xae75e237, 0xe755b59b, 0x44a0fe53, 0xb71fb842, 0x7fc41225, 0xb9f3d622,
+ 0xf38dbad9, 0xbd592b9d, 0x733e74b9, 0x9e11101f, 0x1db7f9c6, 0xa34d7bb0,
+ 0x99fb5a69, 0x5c682404, 0xf3fe718f, 0xe3d71b96, 0x987f6196, 0x677e37ef,
+ 0xa7a46274, 0x8f89e6f2, 0x53d0d29d, 0x8f47f069, 0x2bb4d29d, 0xcba9986e,
+ 0xeb660617, 0xced7e7ea, 0xae2f95d7, 0x2f95d42e, 0x9744b75c, 0x407fef9f,
+ 0xf2de7f57, 0x7bf2ba15, 0xcaebd62b, 0xd46c14e7, 0x9efb67e5, 0x6bbfd5d4,
+ 0x5cae9d56, 0x4d785038, 0xdf55ca1b, 0xb7a0a935, 0x4021607e, 0xabbd2a8f,
+ 0xea8670fc, 0xa39e902d, 0x2ba40b7a, 0xff294f80, 0xb4b2f69b, 0x6bfceb7c,
+ 0xfebd1adc, 0x069154b4, 0x7ba464fc, 0xf48d3c23, 0x45fa7f4d, 0xb4d487db,
+ 0x20b92044, 0x7ef8bae7, 0x5ebf7eae, 0x647a7130, 0x7e129de7, 0x95d9289e,
+ 0x3bce093a, 0x68687225, 0x7ef7a385, 0x75c05049, 0x13d2d010, 0x5a946f01,
+ 0x6e2b7035, 0x679ba418, 0xc71141c7, 0xa5de032f, 0xe4832ff2, 0x0f200b36,
+ 0x6ed38742, 0xf1f3051f, 0x4cf905ee, 0xff71139a, 0xf69ca8ed, 0xe00929d8,
+ 0x99e98b97, 0xb69859ca, 0x3d30fa57, 0xe9805955, 0x4c0acac9, 0x63972adb,
+ 0x8fd2bc7a, 0xd72a5fe9, 0xcaa7fa61, 0x558f4c6a, 0xc7fa62d6, 0x9da600ca,
+ 0x554c5e95, 0x9396edba, 0xe56f5cb9, 0x81fa0be7, 0x2d7cade9, 0x15bdfd22,
+ 0x0293d1f9, 0xf1c178fc, 0xcbd050e5, 0x48a31c2f, 0x5e1def4e, 0x15e87a46,
+ 0x7a8bc4ae, 0xe2805e45, 0x72cf4fb9, 0x93c30c5b, 0x11a644cd, 0x0fd6372a,
+ 0x60b3d679, 0x24cde624, 0x3c07da1e, 0xfa519d33, 0xe0147ba5, 0x22784aeb,
+ 0x3868f0de, 0xf53fb70f, 0xefd0599f, 0xb640c2f5, 0x71161e5f, 0x67a124bf,
+ 0xefaf803c, 0x95e1370a, 0x6f80d30f, 0xf0aa27ce, 0x34234d6b, 0xb1b8225d,
+ 0x164d0bff, 0xb6380662, 0x847003d8, 0x19e470bd, 0x4b77ec17, 0x53eac453,
+ 0x57877b63, 0xdabd3069, 0x794f59a1, 0xa17f3eb3, 0xcec6985a, 0x1dec4af9,
+ 0xdcae80a3, 0x0086a7d5, 0x553053fe, 0x229a59fb, 0xb9ea38e3, 0x21c63496,
+ 0x2173d29d, 0xcf67fbd6, 0x227eb7a3, 0x1f2268f3, 0xbb01d853, 0xe5741e5c,
+ 0x7c0f4bf3, 0x73973f9b, 0xd22d4f01, 0xc79fb097, 0x07977fd0, 0xcc66bf42,
+ 0x0796fdab, 0x7ae5bf45, 0x1ba8def8, 0xd453b68f, 0xebb43733, 0xa4cd5e9d,
+ 0x15275d5d, 0xdedc196d, 0xab60dc52, 0x38fdcbd6, 0x39bcbe5d, 0x0fb75ab5,
+ 0xef942fc0, 0x06608149, 0x54e129ba, 0xac7665d4, 0x1cfce813, 0x2dfb0526,
+ 0x52bd5817, 0x53ec9b6b, 0x415b0c90, 0xad90580f, 0xd7729dd2, 0x3e5ca99f,
+ 0x3c897bfb, 0xeedce50c, 0x2547f6a2, 0xfcd13130, 0xd05b9e42, 0xe41d3c54,
+ 0x373dd9dd, 0x88b0fea3, 0x10e0bae4, 0xb3aa4053, 0x4f390f40, 0xee80d34c,
+ 0xb83f93cf, 0x03ce6ac6, 0xce324c73, 0xfd3ae167, 0x27f5483e, 0x56bf3e5d,
+ 0xb723cf9f, 0xe79d0125, 0x202448d5, 0xcbea3f00, 0x7e31366f, 0x6b1527c8,
+ 0xc5587f60, 0xdc0b13cf, 0xf28fdcc4, 0x5b4be97b, 0x79d3e6b2, 0xf931302c,
+ 0x0bdf9ead, 0x511e99e3, 0xc193ac14, 0xd371f39e, 0x40dc9fd8, 0x0d607da0,
+ 0xbbfc31d8, 0xa536cf05, 0xebbefe27, 0x55f38dfc, 0x761e8ff7, 0xd28f3e04,
+ 0x881bc106, 0x98548fb2, 0xf8ffbe04, 0xeb097e99, 0x1b99e8d6, 0x435af90c,
+ 0xff90debe, 0x812de9bb, 0x61cde8e8, 0x25306df2, 0xfd02fa32, 0x6587304a,
+ 0x7fd23fdf, 0x6bfe8f4a, 0xf7fda9ff, 0xe967fda7, 0xa7ffaffa, 0xc7b83ff6,
+ 0xfad183fc, 0xc7697d2f, 0x37953f1e, 0x726e2f45, 0x9cffba11, 0x79275735,
+ 0xb64bfe28, 0xe2fb46ad, 0x05dfb319, 0x20367cf4, 0x39440b4e, 0x71369f57,
+ 0x3af125bb, 0xc0f73804, 0x73ffb4af, 0x067cffcf, 0xdcbe5b9c, 0x3cf1b926,
+ 0x590960d3, 0x35969f28, 0xa3274e15, 0xe5827f31, 0x422a7ed7, 0x9f4f59be,
+ 0x4a6dcf45, 0xa51bfb02, 0x87efae14, 0xab2a5f50, 0xd854ebff, 0x1849ca7f,
+ 0x0ed8ccf9, 0x8f18bfc6, 0x1cbe71f2, 0xce9cb3db, 0x72f0f513, 0xa6f2970e,
+ 0xba2a7f9f, 0x69d1fd20, 0x369317b4, 0xed8d93d4, 0x73feb80a, 0x684ce4cc,
+ 0xf91eaaa7, 0xc81ef91e, 0x242e154d, 0xf11ff4c0, 0xe1a32da5, 0xff51dafc,
+ 0x81a0977b, 0x176fca97, 0xfd7f0b82, 0x5cbbd2b2, 0xb1e7e4ee, 0xb600bb48,
+ 0xdeb99a53, 0x12d2c2d6, 0x7b02e429, 0xe49d4969, 0x25cfd3f1, 0xf6799e3b,
+ 0x7e4f3829, 0xa10cf160, 0x78ef17fd, 0x34398fed, 0x4a53bc5f, 0x4049ce98,
+ 0xa7e08a48, 0x3e5bfe9c, 0xa28f8226, 0x2b26bedf, 0x87f7d8a3, 0x297823e2,
+ 0x265079de, 0x63c27aa3, 0xdca0f072, 0x9f8288e6, 0xa0a989e0, 0x7d2f895f,
+ 0xcffe0323, 0x7248101e, 0xd678147a, 0x027a86bd, 0xc9f109c0, 0x3f8dd5f1,
+ 0x8a72fd43, 0x46eb9017, 0xedeb197c, 0xfa05f2e5, 0xa521fb05, 0x065e17ef,
+ 0x2c9ff33b, 0xc143801e, 0x60b9f70b, 0x15cda73d, 0xacb7ce8c, 0xf1d2f24e,
+ 0x927f240b, 0xbdf6531b, 0x229fe9e0, 0xf3bfe5fd, 0x7e7624d3, 0x709aa6f3,
+ 0xc2a7f2af, 0xbe6f173a, 0x4799d713, 0x0587487c, 0x905cc45b, 0xc9985f97,
+ 0xf8519db4, 0xe4c89e64, 0x14ade9e6, 0xa79d74b9, 0x768436e9, 0x81883fd7,
+ 0x58bf686d, 0xfc1e4042, 0x9397b554, 0xc2ff98a5, 0x4e35f0ca, 0xaa7ef554,
+ 0xb7e969f5, 0xe02b6d7e, 0x6f00dce9, 0xcabdd832, 0xe1cfd989, 0xfda65c21,
+ 0x94dcef8a, 0x1444f0cc, 0x476f1673, 0xf0c982f5, 0x4ab7ea1d, 0x5d68db5e,
+ 0x3d39723b, 0x3e32fe32, 0x0c779d3e, 0x93a7e7ec, 0xca304148, 0xaa8836fa,
+ 0xbafba01c, 0xfc34ce86, 0x7ebff8ce, 0x9577e33d, 0xa73303ff, 0xefe7f941,
+ 0x76823e32, 0x79d25fb0, 0xfcb19285, 0xca021de0, 0x45090b07, 0x897af3e3,
+ 0xdcbeb9f3, 0xfe742f48, 0x43562166, 0x3c4e3037, 0x5eed01e2, 0xbdb43579,
+ 0xb8c2ae56, 0xaafd9eae, 0xe5cf9c7c, 0x9522ddc1, 0xe445d707, 0xe4ccd901,
+ 0x977aef40, 0x2258f11f, 0x0a7d9e05, 0xabf297f8, 0x95fe015f, 0x9ffd6172,
+ 0xe3fe1e34, 0x3e6f94dd, 0xab7caa09, 0xbe46ab97, 0x2e35d82d, 0xb27edf2a,
+ 0xdf3a2321, 0xf951efd2, 0xdbe30376, 0x5572d7ff, 0xa8956385, 0x9caaab97,
+ 0x469e0dec, 0x2a269939, 0x9ca35708, 0x92ef3fa4, 0xa8f49eac, 0x7f4aa1d2,
+ 0xbd29bf45, 0x3751e406, 0xd874aa9d, 0x1d2aa74d, 0xe89fb0f6, 0xbf2c68e0,
+ 0xd2826819, 0xf7deee4b, 0x78a3f6a6, 0xf761692d, 0xebddb450, 0xf2f0a790,
+ 0xaa4736e2, 0xa097ef5f, 0xf90c07cd, 0xd7bea1a0, 0xd435cf90, 0x15f219f7,
+ 0x6601fa86, 0x2c3e683f, 0x9087a413, 0x92b4beae, 0xb7609df8, 0xdda22fdb,
+ 0x79ce8bae, 0xd5df6d0d, 0x53f01e98, 0xc6dab0f9, 0x44e18fce, 0xb3c80d79,
+ 0x15d8772e, 0xd31b790f, 0xc372bb7b, 0xfe8d38ae, 0x4445a278, 0x2016dc79,
+ 0x8cf6b4d3, 0x21545f08, 0x6f48dafe, 0xd90ecce5, 0x77eec315, 0x691d126f,
+ 0x59dce1cb, 0x19287a2d, 0xee2b4590, 0xba898172, 0xadd065ab, 0xc5f7e8b3,
+ 0x5aec886f, 0xa735efc4, 0x670dce6a, 0x09f1ff88, 0x6d97dc02, 0x6c2ffc40,
+ 0x4588e761, 0x73d3a21b, 0xe7976f11, 0xdc832658, 0x49fffaa4, 0xed559dad,
+ 0xe1b360a7, 0x9ccdcb7b, 0x3cf1abee, 0x2faf5457, 0xd0f3f1f7, 0x647e5549,
+ 0x1f940c90, 0xf381d070, 0x37bb9738, 0x9d6f2389, 0x75d0f145, 0x37402444,
+ 0xc4445a17, 0x764685c3, 0x89fc495f, 0x24653fc8, 0x854ef28c, 0xc7f00757,
+ 0x50e5deb0, 0xb30feec7, 0x4a55a41e, 0xf479fcf6, 0xb1da68af, 0xfba183e7,
+ 0xfbd2ff20, 0x3d267f69, 0x603e4feb, 0xd76e3b43, 0xbbde2701, 0x337fed74,
+ 0xefc841ed, 0xbef078b5, 0xa357c0f9, 0x56ba8e81, 0x8e400a5a, 0xf7600d75,
+ 0xbffb55f4, 0xfb86dd1a, 0x9fc42ae7, 0x5fceccd3, 0xf3fe5a17, 0x5fb3dc38,
+ 0x02aba168, 0x1d80e0fd, 0x2fe5e1ed, 0xd08ed0db, 0x2cabffb5, 0xb79fe39f,
+ 0xbf7e329e, 0xb324e5d2, 0xe2fcc176, 0x7cba5d98, 0x5667f8df, 0xd373fdc0,
+ 0x2d217941, 0x37cafc9f, 0x763e41a3, 0x4f7a62ed, 0x34f6d4a7, 0xaca41fdc,
+ 0xa242b4ba, 0xe604ee70, 0xf94f4be8, 0xf92672ab, 0xcb834647, 0xb91f6837,
+ 0xff5c785a, 0x021e063f, 0xb49623de, 0x01560338, 0xf8e97dd6, 0x1c1e419f,
+ 0xaa5d20b0, 0xb824fdeb, 0x2b91f502, 0xac067bad, 0xd37ff13b, 0xd5d085ba,
+ 0xbff4bbac, 0xe33fbe39, 0x0f91a8fb, 0xfef9d27a, 0xc3bf31fb, 0x5ef9c1e9,
+ 0xe2ffbd25, 0x77de1b7f, 0xaebbbc51, 0xffc6eebc, 0x1deeebe6, 0xe5cc6fef,
+ 0xfdc37778, 0xdf2bf97b, 0xabbefce0, 0x3ffa3b9c, 0xbeaafd74, 0xf2933bfe,
+ 0x3fad066e, 0x403b548d, 0xe951f8b1, 0x683237a1, 0x1ffaefe9, 0x4ef9838e,
+ 0xc635f7e2, 0x66637df9, 0x7049bee7, 0x25c7436f, 0xef3f0271, 0x3f5273b1,
+ 0x5bf45fae, 0x487a8796, 0x40bffebf, 0x9598827d, 0xfc0fb81a, 0x0f42da5d,
+ 0x319036fa, 0x77907cc7, 0xfaf3c8df, 0x04afe2f3, 0xcaab85e2, 0x1f37697e,
+ 0x7fb53d01, 0x58f5117f, 0xfafea29a, 0xfb1a6baa, 0xceeb225e, 0xf4523f33,
+ 0x09a99be7, 0x14d073fa, 0x844ddfde, 0x8726ffcd, 0x38500810, 0x58f01a4c,
+ 0x2743d802, 0x4088910d, 0x6f8953f3, 0xa61b9c15, 0x7dfdf438, 0xe3c4f700,
+ 0xb7cc7022, 0x7f022dee, 0xc047ab3e, 0x987586fe, 0x33589e50, 0xe183a405,
+ 0xbfcc66b5, 0x038f7263, 0xe1b8cf38, 0x201e4fa5, 0xcaf55760, 0x65cba14c,
+ 0x2faff1f6, 0x05909e5f, 0x03f66fe7, 0x50b778fe, 0x66d17d7d, 0xeba18a12,
+ 0xfe266c5d, 0x8bb078d8, 0xcea4e40a, 0xc3cfaa2e, 0x2293f7cf, 0x7ea95cfd,
+ 0xcff8746f, 0x74a25f4e, 0x2108727f, 0xfbc5217b, 0x53cf662e, 0x6bdf57cf,
+ 0x3f2af061, 0xd903024a, 0xab98b8bd, 0x2c5a3fb9, 0xe97bba31, 0xc2c6bb2f,
+ 0xd76266b9, 0x8fc658c8, 0x904fcc99, 0x881797eb, 0x0071eb12, 0xc58a0e3f,
+ 0xa223b17b, 0xd9df9a33, 0xfade7e76, 0xd297dc0d, 0x549eabb4, 0x93f7a08b,
+ 0xfcf9da30, 0x2db256f5, 0xae427f8a, 0x382ddaa4, 0x988fe8de, 0x367af605,
+ 0x34da62fe, 0x8eb78b56, 0xa3cd67e9, 0x7e01e27b, 0x2bee6a4e, 0xc2f851fe,
+ 0xbbe00ef9, 0x3536d6dd, 0x2edf0a37, 0x633d9890, 0x784ba1c6, 0x52d11ebe,
+ 0x1f3e0267, 0xddd26f51, 0x712dddbb, 0x190c7dfd, 0x719af303, 0x04cce6c8,
+ 0x3d111cbc, 0xde57efe0, 0x8beca9f2, 0x84646f72, 0xf60ff427, 0x8dc95ad6,
+ 0x8293eee3, 0xfbae010b, 0x9c095bce, 0xd5caf6b7, 0xe9e6d1c5, 0x2e79b0b0,
+ 0x46fbc126, 0x83f7ffa7, 0x472ec4ef, 0x579c1268, 0x75f209ea, 0x4823fa4f,
+ 0x481a17c7, 0x9c31e400, 0x5c2e406f, 0x1fb82468, 0x02fc9050, 0xdf946bce,
+ 0xc73da07f, 0xf9de6b0f, 0xca47d81b, 0x9837045a, 0x6dcccba0, 0xcaedd832,
+ 0x9044e39b, 0xea8a19db, 0x751ee90f, 0x6a2f8687, 0xebc23325, 0x39bece70,
+ 0x1d67ee30, 0xcd7d8132, 0x05d86afb, 0x96b3ff72, 0xbd07c8b1, 0x95b7ebad,
+ 0x048a68a4, 0x6ba410fd, 0x6c8c3d23, 0x6fe5d18c, 0x817d7d10, 0xda5866bf,
+ 0xe0a27996, 0x7c66472f, 0x2df2d57a, 0x7c99fff0, 0x6f95577b, 0xc357313e,
+ 0xd1992647, 0x25be46bd, 0x4b6f9347, 0xe0192505, 0xa0ff74be, 0xd2ebc064,
+ 0x68c4a437, 0x25476df2, 0x917b07bb, 0x3576b1fb, 0xbd76f951, 0x5135be46,
+ 0x4fc516f9, 0xf13243a0, 0xf20aedfd, 0xc35ff02d, 0xbe403b7f, 0xbe67a345,
+ 0x6df2a83f, 0x9409cb74, 0x4c9ba36f, 0x2fccff3a, 0x84df28af, 0x9f403bc4,
+ 0xec79223a, 0x0767e851, 0xe45edfd7, 0x0e30367e, 0xb271b9c8, 0x5abfc71b,
+ 0xb5729739, 0x08bfee72, 0x5b9caace, 0x9fa09bba, 0x643a4f6a, 0x5ee96e72,
+ 0xa004e72a, 0x96e72647, 0x8ecc27ee, 0xc36f9063, 0x8237c87b, 0xac42cbf5,
+ 0xfa73797d, 0xfed0f713, 0x8f2578c6, 0x131fd695, 0xb4e37791, 0x6c9c6ef2,
+ 0x90f73846, 0x4eae4777, 0xf2e6edde, 0x81b1ca8e, 0xf48d5f20, 0xfbd169e1,
+ 0x7f1beeff, 0xc0b7f1ba, 0x788a6f2f, 0x898ef50f, 0x35bc17dd, 0xd02674fe,
+ 0xc99906d7, 0x7b971f5f, 0xec7e959d, 0x6cabf27f, 0xec8da57d, 0x1359413d,
+ 0xeacb0fd3, 0x7f4280c5, 0x09739a9d, 0xf70a93ef, 0xe699240b, 0x1faa5a67,
+ 0xfd3e8077, 0x3eb8449c, 0x43433d3d, 0x8bb28b0f, 0x655bced1, 0x94256d73,
+ 0x8999178f, 0xc5b9ec15, 0x4167a98e, 0x66ce2d9f, 0xfe62dff6, 0x544bf55d,
+ 0xf78d33fd, 0x4bcd79e9, 0x7a47ef5e, 0xb0cfabde, 0x78cebc30, 0x1f800846,
+ 0xf67bcf61, 0xe285ca00, 0x15f7fd06, 0xc533fd7c, 0x79178436, 0x8b6cf45b,
+ 0x8c2b3fc2, 0xe1c23a70, 0x83a2e144, 0x0a884053, 0xe9e98a27, 0xb8114919,
+ 0xb6d9be14, 0x85c0ec06, 0x6f780a4f, 0x0ab75c68, 0x55fae337, 0xd176aa38,
+ 0x7e5fde62, 0x33be1d4b, 0x8545c231, 0xdd1e11b3, 0xa3c03770, 0xfff6e64a,
+ 0xfc16320c, 0xa0dd2858, 0x9bfff19c, 0xb90ffe88, 0xdee88713, 0xf2e7ac43,
+ 0xc4f56c7f, 0x3ddd70c9, 0xe182fc13, 0xc976ae3e, 0x37dfe0eb, 0x063298ee,
+ 0x721bd3b6, 0x97b83e2c, 0xa30b6edb, 0xf0e9541c, 0xcd874e23, 0xfafbbe1c,
+ 0x73c24c56, 0x06e0b361, 0x643ca43d, 0x5396b843, 0x2ad1b47a, 0x72fc9f87,
+ 0x1bab872a, 0xf334bbdf, 0xc1e289fd, 0x751fe704, 0xf7b00abf, 0x185b6331,
+ 0x181bca5e, 0x1849325e, 0xb565efed, 0xd7442782, 0x04bcd653, 0xf95582fd,
+ 0x5a1c7f4c, 0x5fa1453c, 0x25fa3473, 0x8acc9c60, 0xbcc59bec, 0xf54b0cde,
+ 0x3f9ec11f, 0x1d47f283, 0xdffd2192, 0x95f7d0b7, 0xf88c45fc, 0x6dc390fa,
+ 0x01d5c007, 0xfd330bf0, 0xdf09742b, 0xe5e5a8cd, 0xae0ebf66, 0xc8ba9f93,
+ 0xa0bf6fe8, 0x1ba51d80, 0xb4cf406e, 0x370a9c7c, 0x43c067a0, 0xf2117ccb,
+ 0x7dde1479, 0x17ae7bd2, 0x7cb4c7ee, 0x04ffb85f, 0xe08b7feb, 0xfdd65121,
+ 0x3bfbe99d, 0xfc6f75d2, 0xbe8191fe, 0x8f85b2df, 0xdefa058e, 0x93df202f,
+ 0x3dfd3896, 0x4dcecc97, 0x0f946ddb, 0x0de61ee0, 0xe955b3c9, 0x1cc21f29,
+ 0x509e70ce, 0x6b927634, 0x57e02161, 0xff4560d8, 0x40c79c30, 0xe56aafa6,
+ 0x491b0ef5, 0xf7b323bc, 0xf9c6fffe, 0x497d37ac, 0xf1828fcd, 0xd3368e40,
+ 0xc64786f1, 0xaa17ee33, 0xeb4ae01d, 0xb1fe5bb2, 0x7ce3a975, 0x7299ff57,
+ 0x28f78ad2, 0xc38d1faa, 0xe0942be4, 0x304d3afc, 0xc2d1fdeb, 0x70ffcf1c,
+ 0x2dfcb2ff, 0xab1493fd, 0x4de2fdee, 0x29f883a2, 0x4af33edc, 0xcb542fc8,
+ 0xec026f78, 0x3ee8931f, 0x8ecf9348, 0x1eff7b8e, 0x5ef1172c, 0xfb37d6e6,
+ 0xd5bdc294, 0x8a67ccad, 0xa0219adc, 0x740ef0fe, 0x70f41e36, 0xf85af12b,
+ 0xfb3cb490, 0x7801717b, 0x5f519067, 0x7ca1593d, 0x5021a63d, 0x7267a905,
+ 0xc02de138, 0x009144d7, 0x7dbd5abe, 0x7bfec326, 0x06495fdf, 0x9ea8ce98,
+ 0x398cfd80, 0x5ea11242, 0x8f11378e, 0x3e9be333, 0x3a76f77f, 0x4547f1bf,
+ 0xcdeb428f, 0x0070ec3c, 0x6cdf0d9f, 0x5c0d3e22, 0x0aa04872, 0x4fe347ec,
+ 0x79076f79, 0x1ef54050, 0x682ff7f0, 0x4172aba9, 0xed80b37e, 0xa9befdcb,
+ 0x1dbf3a2e, 0xbd4e9fb5, 0xad02e40e, 0x6f94dd07, 0xebcaf566, 0xb2b80f05,
+ 0x946cb5e6, 0x0bd46e51, 0x476ca0f8, 0xd6562040, 0xfb4ac06f, 0xb699b1dd,
+ 0x8bfd84cf, 0xeb7e87b6, 0x76f77d3f, 0x9e743b90, 0xdd91bed8, 0x76d1e6cf,
+ 0xfd49f00a, 0x70afec12, 0x5de040b3, 0xdb234142, 0x4a8e0a9f, 0x3a6f281e,
+ 0xbbee24f8, 0xa978e9d3, 0x851fb0e9, 0x8efbe0a6, 0xdf1b82b1, 0x43494dd5,
+ 0x0b05d5b9, 0x01d60686, 0xe05cbeec, 0x51fe7e79, 0x2d37bff5, 0xcf377fcc,
+ 0x43ee42b3, 0x3b2b79fb, 0xf484dd31, 0xfa0ca9f4, 0x6f0a29da, 0x3bf7851f,
+ 0x70e17fdc, 0x9b72c7f6, 0x673c7f66, 0xbff48419, 0xfa2279a8, 0xb9262d4b,
+ 0x633faf78, 0xdf3bd33c, 0x0016d1be, 0x52dbddbb, 0x3f7c3fb8, 0xbf05a37c,
+ 0x7260ee77, 0x1b4073b8, 0x6f4f69da, 0x47bc0896, 0xa22cdaa8, 0x28dd389c,
+ 0xb8b5fde1, 0x9db94245, 0x21e983bf, 0x7eb33787, 0xfd30374f, 0x3b96f26d,
+ 0x9c3ec2a7, 0xefbd4dbf, 0x3d5a7266, 0x0bb9e687, 0x519bfb75, 0xb872aace,
+ 0xa0a3c394, 0x5fef0eba, 0x54b7728d, 0xf20d0fdd, 0x65ee14b6, 0x8435fef1,
+ 0x341a547c, 0x983913fa, 0x0d73863c, 0x12e843d0, 0x51d977d2, 0x46b9c089,
+ 0x2a63b8f8, 0xec2ce7ac, 0x7c7cb4f7, 0xfb85e08b, 0x966382f0, 0x81e3ea00,
+ 0x15fef3f9, 0x2c0f99f6, 0xbfc05044, 0xca83e29d, 0xf84b6ca9, 0xefd18f2f,
+ 0x82b1df67, 0x9fa508a7, 0xd57f08f9, 0x1b73342f, 0x7cc8f3f3, 0xde0926a7,
+ 0x7d29927f, 0xd7e40e50, 0x91a7c48a, 0xef05671b, 0xfdb377ed, 0xfff5adc1,
+ 0xf3ab94cc, 0x6fed9f60, 0xd951f265, 0xddfbe126, 0x447cfcc3, 0xb7e80bcf,
+ 0x6377b859, 0x87a1ac92, 0x931bfdc2, 0x6b20e8a8, 0x15447fb8, 0x285bf77f,
+ 0x0f0a71b3, 0xcd3aee08, 0x6a3f6a38, 0xd65ef2bf, 0x967ed06e, 0x217fd6f6,
+ 0xf9d70fcc, 0xc3720c85, 0xf18f4fd8, 0xfb27e97b, 0xc0d62fdf, 0xb7eced3b,
+ 0xce6e7445, 0x20fa78fe, 0x9a80bded, 0x590c7eaa, 0x57889aef, 0xbfecbf03,
+ 0x06af10c4, 0x28e34ddf, 0xddfc53ff, 0xb9f4ccd2, 0xe42771a6, 0xbbcc4cd2,
+ 0xb8cbdf81, 0x0a6cba3d, 0xca69efbb, 0xf0156778, 0x014cf4ff, 0x7df881e9,
+ 0xd4049f72, 0x4ff014df, 0xed64cfce, 0xe07b69f3, 0x1927a6cb, 0xa179529f,
+ 0xdb293c80, 0xd62a71bc, 0xe81417af, 0x3e6ea9bf, 0xd90525ea, 0xfaf2c122,
+ 0x1527a813, 0x00489f34, 0x5bfca67e, 0xd940fa03, 0xc41b8b04, 0x2a97cab1,
+ 0xfdcdbf9f, 0x3dd58989, 0xcbf8fc0a, 0xf0a2a980, 0x709478b7, 0x65f195bd,
+ 0xdbe33679, 0xb04877b7, 0x73e1abc2, 0x8f956be4, 0xcce3e045, 0xde1f1f08,
+ 0xbe06593c, 0xd0101d3e, 0xc83262ef, 0xedf3e001, 0x31efb702, 0xf96af63d,
+ 0x667a4afc, 0xd85fe529, 0x573e552f, 0xcfc8daf9, 0x3bb6e6ad, 0xddf71e60,
+ 0x4c75c368, 0x3fdefefe, 0x15e4c7de, 0xfe4dd7de, 0x204903fe, 0xccccf31f,
+ 0x6b8547af, 0x81f999a9, 0xcd5798f5, 0x6af5390a, 0xc79867e6, 0x5ede8b46,
+ 0xc712d872, 0x25eb9dfc, 0xf12bfba4, 0xbb3e0f67, 0x5abcfe4a, 0x7f12babe,
+ 0xfb8be3aa, 0x061cfdf5, 0xd9eb8e20, 0x6385275f, 0x77f1c288, 0x5fa0cf8d,
+ 0x4fe7f9d9, 0x143c00cc, 0x0e74a3ef, 0x24e8d5f4, 0xe6739021, 0x455bee00,
+ 0xfd17a24d, 0xaca1cd65, 0x3e5a9ddb, 0xc53ffe66, 0x9e913a2f, 0x0259768a,
+ 0xa2fb69d3, 0x468f1f3d, 0x61958c3f, 0x3ff24ff4, 0x7f65f5cf, 0x83e068db,
+ 0x43f33322, 0x9985ca32, 0x773fa656, 0x82cfb5ec, 0x2c0d09f5, 0xf05140de,
+ 0xb9a2c92e, 0x956698a7, 0x2f787ad4, 0x0c74a7e8, 0x7e6131ef, 0xaaee77da,
+ 0x76c751ff, 0x9a8a2726, 0x2dc400a5, 0xd9d86a28, 0x45a5fe09, 0xff682cc7,
+ 0x14f86f2a, 0xbf27e7fd, 0x2bed03b8, 0xeea2cde5, 0x3f87ad3e, 0xb218835f,
+ 0x535a1f80, 0xd1ffde29, 0x07cc09fc, 0x77dcffb9, 0x7e2b37f4, 0x3f1eff71,
+ 0x6ff16105, 0x7c81739f, 0xcdbad739, 0x0d7d7e85, 0xdb5feedf, 0xb82f7fc3,
+ 0xddeffb9e, 0xb9e09a72, 0xdeffba26, 0x3285f839, 0xbd5683ca, 0xe8691eff,
+ 0x9d25fa83, 0x946e5667, 0xfd6e8ffb, 0x4f17c77c, 0xc779ff83, 0x869e4fae,
+ 0xedfc9779, 0xafc1a7b3, 0xe1b01c88, 0xfcfe57be, 0xabafe87b, 0x6564dbb6,
+ 0xfdb9da74, 0xee77f439, 0x81e2c0fc, 0x9ff73ade, 0xb2ff034e, 0x92979dce,
+ 0x6cb99ec0, 0xef684dff, 0x727bb65d, 0x6fb28932, 0x6fd029a8, 0xadfc2ae0,
+ 0xdc3b788d, 0x9ffd1874, 0x83bc53ce, 0xcbf6ec1c, 0x7f32960c, 0x63fb8557,
+ 0x6ff74636, 0xd97fe1ef, 0x37adfb74, 0x626ffc82, 0xfd15e4fa, 0xf8a5df30,
+ 0xf02afebc, 0x6dfdc8d8, 0xab7cb783, 0xf879e61f, 0xc9abe285, 0x9a2fc780,
+ 0x29faff16, 0xd3ea6b28, 0xe8661fab, 0xfaa7e02a, 0xdeadfbcf, 0x6fc0ac57,
+ 0xfe837ebb, 0xe9bf80af, 0x5f47ec0a, 0x83fbc1a4, 0x2e785233, 0xfde13fec,
+ 0x52bf8c16, 0xe47dffb4, 0xefddcea7, 0x709a9da0, 0xd24ef63f, 0x8dfcc3fd,
+ 0x7adebe05, 0xe4dff327, 0x4eff0078, 0xb9df85c5, 0x6ba3271f, 0x37b3bfd5,
+ 0xacafcebf, 0xfd56ff4c, 0xffeb4bfa, 0x2324fdcc, 0x01b21378, 0xf5be275f,
+ 0x070a823d, 0x11cb9737, 0x7ee8e5bf, 0xcb7eddb4, 0x3e01bc06, 0xf6ea9f61,
+ 0xfef9a64b, 0xf24ed063, 0xf83f347e, 0xefe63ace, 0xdfe929dc, 0xc4f0468f,
+ 0x0d5823df, 0xab81cbfe, 0xd2be5ff3, 0x9c2bbe3a, 0x3452824e, 0x3abc27ae,
+ 0xdf2e8ebe, 0x3fc26d13, 0x916d5ef6, 0x931f7c60, 0x7f044b60, 0xcf681390,
+ 0xf37f3eec, 0xfb7076f5, 0x22f3c77b, 0x09aebffa, 0x6ef9461e, 0x10651f94,
+ 0x7cca2347, 0xbe98d987, 0xf6ccd65e, 0xce5d8e8f, 0xd3f68380, 0xd22f6871,
+ 0x09e35975, 0x7bfb4fd9, 0x32b7e1bd, 0x7c62c7bb, 0x4047fb04, 0x178e9eb3,
+ 0x7e668e0e, 0x6fdeccda, 0x1f1c671c, 0xfa25bca7, 0x9f8de538, 0xf629c6ea,
+ 0xe3b76507, 0x339de3ca, 0xfe82ef7b, 0x3d32b5ce, 0x9c505cf1, 0x587ded16,
+ 0xf7e24d8a, 0xa52cd561, 0x25c628fb, 0x2438b271, 0xf5062ba2, 0xecce65ce,
+ 0x9009b163, 0x5407e8ca, 0x0dfb82b5, 0x0293ccfd, 0xfe72aef8, 0x577cc098,
+ 0xf6357c03, 0x23edc91f, 0x294aafa0, 0x776099b9, 0x391dca30, 0x1a0244c1,
+ 0x4e732f7c, 0x5ef0564b, 0xf01fd424, 0xb4e33c79, 0x647efd04, 0x647d5fb0,
+ 0xe9926b26, 0x0bf23efc, 0x5fb4159e, 0x03c7f5f2, 0xfb3d9d72, 0x87bef357,
+ 0xa9bd9d44, 0x0e3e12cc, 0x8af215e7, 0xc423ef0d, 0xe78c3603, 0x0db4fe50,
+ 0xf7787bd7, 0xdea2cf57, 0x610b6bfd, 0x54f443f7, 0xdca47103, 0xbbd38fac,
+ 0x3ffa7abf, 0xc686af41, 0xa7fcfc74, 0x4f387d69, 0xfcf1da34, 0x762bb5d3,
+ 0xafcfea34, 0xe403383c, 0xd19dbe5a, 0xc98bfe63, 0x5fda2a81, 0xb7cb227b,
+ 0xf18018ef, 0x39778a03, 0xf0f11fd1, 0x60ca97ee, 0xd17cea9f, 0xa4066e0e,
+ 0xffae15f3, 0x3bc786ff, 0xad1495aa, 0x3121725f, 0x2077da2b, 0xe56790c5,
+ 0x7f049ef8, 0x811f38b2, 0x1639ab1d, 0xbd508fdf, 0x79cfd758, 0x07bf7c29,
+ 0x97dfd8e9, 0xf5099bbd, 0xac607905, 0x1fff96a7, 0xe5b7931b, 0x11ceda16,
+ 0x872e5fa9, 0xbabe58f3, 0xad27932f, 0x2ae7ff58, 0x9ef2f39d, 0xebfab2fd,
+ 0xf575036d, 0x3c65f6d4, 0x7e9188de, 0x16fde71f, 0x2c337c37, 0x288d3c5a,
+ 0x3fefc7f3, 0x04df8815, 0x1b4ecb7a, 0x778251c6, 0xbf0fe0f8, 0x5ff76647,
+ 0xc610ae25, 0xe5c7d933, 0x084c4971, 0xe5f4abe3, 0x90fa80f3, 0x17b6d627,
+ 0x2fa5ef00, 0xe7c408d9, 0xe9c57d29, 0xee977c05, 0x57fdaaf9, 0x66efe099,
+ 0xe95ebb47, 0x7482ff2b, 0xcd096a50, 0x3b6578c5, 0x99e2042d, 0x237cec75,
+ 0x43b5f80d, 0x7fc5a50a, 0x695ebdcb, 0x478862d0, 0x52efe7e0, 0x7de18303,
+ 0xb33efabd, 0xd33917a8, 0xdef76365, 0xbdde6cfb, 0x7d77e436, 0x95739edc,
+ 0xefb483cd, 0xe8948bb4, 0x9b4df172, 0x69d977f4, 0xa3b8e5bb, 0x37c73bc7,
+ 0x49e73e61, 0x2018126b, 0x0e3ea8cb, 0x21a8bcf2, 0x0fd83fbd, 0x77d4d90e,
+ 0xec2c4aec, 0x05248747, 0x0687d9cf, 0xfbb5fd28, 0xab4a99cc, 0xaed09662,
+ 0xdd576983, 0x097d79a7, 0x66da27f8, 0x1f7b9345, 0x8f08ecd9, 0x1bc5ab22,
+ 0x07649ded, 0x02deafdf, 0x1b224063, 0x1d43f817, 0x401490f7, 0x4628bc39,
+ 0x0ff4fd61, 0xb8bdf0c8, 0x2d20ef61, 0xd5cd0a1c, 0x29f28f58, 0xd490b3c2,
+ 0xf91a99c8, 0xb8578ead, 0xf198a1dc, 0x3ff9ba3d, 0x8c55e9ba, 0xc88d19e0,
+ 0x7472789a, 0xb33b45c7, 0x2cc0eefa, 0x7e015ae5, 0x9b75c932, 0x6a952045,
+ 0x1218f7e4, 0xd541d4c4, 0xaabf162e, 0x3c9c8082, 0x83471dd3, 0xd7811a60,
+ 0xfdf72803, 0x92190803, 0x1286fa0e, 0xefc0d6eb, 0xf385cd92, 0x082b98b1,
+ 0xddd31793, 0x7e0a7fa0, 0xe94cb91f, 0x61b2aaa9, 0x40f78b10, 0x0d7ef0bc,
+ 0x3f3a5855, 0x4bf5fb97, 0xd5f907a0, 0x27df70b8, 0x620a2a81, 0xbb453370,
+ 0xe2c224eb, 0x463bad99, 0xb48fe7b4, 0xffaf8118, 0x0731ca20, 0x6984fc89,
+ 0xc82ac41e, 0xbfd8aadb, 0x9cfdc365, 0xa0424dc3, 0x241dda1f, 0x63a9a764,
+ 0x969cf9a4, 0x34995dff, 0xf74ba1af, 0x91b97d04, 0x335ca82f, 0xf8441b8c,
+ 0x373f7ed1, 0xa1b9fbf4, 0xadbfcfdf, 0xe54e155f, 0x10e941d6, 0x65756087,
+ 0x8d8dc390, 0xa370e567, 0x710e19f0, 0xc62988d7, 0x11cdefc3, 0x367c31ae,
+ 0xf14fa816, 0x1d26273a, 0xd8f3f4e1, 0xaff06103, 0x04b50925, 0x04abc3ce,
+ 0xc922fe35, 0x11da6875, 0x70f915b7, 0x4e671f3d, 0xf577a30c, 0xfacf7c1d,
+ 0xe8efbc36, 0x5bd6df51, 0xf5e898fd, 0xc7cdbd9d, 0xdf3e751e, 0xbd94ce55,
+ 0x705bfef2, 0x6f2ddb5f, 0xfa9414dc, 0x6273db77, 0x71a5bf68, 0xc36b7fed,
+ 0xb46f4c2f, 0x2fe3d7f6, 0xd295e806, 0xfd60cc4f, 0x7bde2377, 0x7cf997a3,
+ 0x48ef341d, 0x9bbaeba5, 0x9ea53f8f, 0xb3df77dd, 0xe8e3d98c, 0xf50bcff1,
+ 0x77faf0e7, 0xaed1f35b, 0x87e62270, 0x9ee12718, 0xde17a65a, 0xf78890f3,
+ 0x08e23dab, 0x7f942fc1, 0x042e5dee, 0xe2d1e942, 0xe3779122, 0xf8f3ff68,
+ 0x4338c6f8, 0x5d4ca23e, 0x338b4627, 0x7d4ce8c4, 0x5f8c6587, 0xf2e488b0,
+ 0xeffa51f8, 0x933736ed, 0x5c80e687, 0x2fb2323d, 0x3a5237f9, 0xd2927d06,
+ 0x8967dc31, 0x712d3dfc, 0xfabfccc9, 0x3c9d788e, 0xb128a0bb, 0xc536bfb8,
+ 0x2e1be2eb, 0xc724af1d, 0xf9b5e469, 0xbf175da2, 0xa4f24aa5, 0x2e92bc80,
+ 0xca14475e, 0x3ec5f257, 0x5394d144, 0x1999143d, 0xee5136dc, 0x200398a4,
+ 0x5ceecce7, 0x6c7a0f92, 0xb54fa31c, 0xa2309cbe, 0x9b7c6f5b, 0x262c7bfe,
+ 0xe96cf911, 0xc6192512, 0xeb73da09, 0xcae893e1, 0x3d1cf8f6, 0x83bfc1e9,
+ 0xd60abbad, 0x3d73de9d, 0x83c7b255, 0x774e73fa, 0xcc2b1bbc, 0xef28b44f,
+ 0xdfbf302b, 0x2aec044b, 0x39e3e13d, 0xbbf0a013, 0x7e87e810, 0xf4ec6221,
+ 0xc3afe8a1, 0x1075e4f5, 0xf5ca91cf, 0xe3be3c55, 0xf1cf1e2a, 0x737f1e61,
+ 0xa8f38f0d, 0xa9eacfc2, 0xd68238c6, 0xab7facc1, 0xc127e39b, 0x43e3e1c4,
+ 0x529ac97d, 0x3684f781, 0xe2084577, 0x74fe9171, 0xbb69809f, 0xb27e11ab,
+ 0x927da09b, 0x05bcc7d6, 0x6a9534f2, 0xcc1e2247, 0x4f920aee, 0xfbb61fcb,
+ 0xd9b802de, 0x41bc7d14, 0xc340ca4b, 0x9e01b0bd, 0xc93d3d2a, 0xa70262e4,
+ 0x127c2327, 0x53df1664, 0xf4dea3a5, 0xcfee2aaa, 0x83d2a9bb, 0x2b8f1569,
+ 0x84710555, 0x8f294e20, 0xcfc89423, 0x8e145589, 0xbe09fdf0, 0x6655566f,
+ 0x9da67963, 0xa60953ed, 0xc012838a, 0xbb309e25, 0xf49f8267, 0x55cc22cf,
+ 0xfc527e14, 0x7abc8144, 0xe7c3588f, 0x7441e9cd, 0xe1710d9b, 0x2f002794,
+ 0x26486f35, 0x9715e7b8, 0xd63e4cdf, 0xcb38b3d0, 0x3476071b, 0x6013e1d1,
+ 0xe039fbff, 0x2367ce95, 0x59c6179d, 0x9ab0f4e5, 0xa72d7de3, 0xde3cf587,
+ 0x5d382fe7, 0x0fd74a3c, 0x7b0f2af9, 0x1a61b037, 0xc84b8bf3, 0x68b8f130,
+ 0x3bf5a221, 0x8904f38b, 0x3c89d74c, 0x718a60aa, 0x0b31c8ef, 0x247d8bd2,
+ 0x7e508af1, 0x8b0081ec, 0x0a9b9963, 0x1a9c66fb, 0x128272b7, 0xb61f1b37,
+ 0x3e3ccc86, 0x1dcec89c, 0x3de351ad, 0x590e7956, 0xdbdefce1, 0xdcce0e7c,
+ 0xf6bc6043, 0xd20e8851, 0x7b3b97c7, 0x6a3bcd31, 0x7f4dfea9, 0xda5f1eec,
+ 0x5ae7a06a, 0x373f010b, 0xbe7f9d07, 0xf7b1af46, 0xd9080762, 0xa9d8a47f,
+ 0x45074b3c, 0x97f7e283, 0x006c83b5, 0x05730a67, 0xa49b1dec, 0x039054dc,
+ 0xdba2e29b, 0x4cec626d, 0x8e65765f, 0x8d75d1d0, 0xee76c5e4, 0xf4746309,
+ 0x4fe5c35f, 0xdd1c94fc, 0x7cde5577, 0x0bfac31e, 0x30997dda, 0x998ba4af,
+ 0xb709bfc8, 0x553f9745, 0x3887ec92, 0x98a35500, 0x94cff3bc, 0x43d59e99,
+ 0x7539309e, 0xf8f08c81, 0x86467435, 0xbf07d413, 0xe2eb299c, 0x3e03ae19,
+ 0x63710619, 0x02affd19, 0x38a9a07e, 0x89fa4658, 0xf3c26e9f, 0x5fce1aea,
+ 0xda7e730f, 0x11e9f9c0, 0xc40b23e0, 0x677c659f, 0xb0e19e26, 0x58b9549f,
+ 0xfe012ddc, 0xc5549b4f, 0x7187982c, 0x04598f8e, 0x32a89fb8, 0x4317537b,
+ 0x59e2d6be, 0xe31e60a9, 0xed6bfb01, 0xdf7f344a, 0x2ce27d90, 0x6cd7853b,
+ 0x6ac7bf8e, 0xacfe22c7, 0xac014f6e, 0xc188eccb, 0x50d57df3, 0x73b4416b,
+ 0xb33b74c2, 0x2f78508f, 0x4cfa7e84, 0x873ee9cb, 0x66a19981, 0xfdc21666,
+ 0x1d077831, 0xedca7e85, 0xfd218f4c, 0x46b064fd, 0x38f0d40e, 0x93f14471,
+ 0xb0791ae1, 0x0254c872, 0x729e9e76, 0xb83917a0, 0x2ac1c98d, 0x062fef81,
+ 0xf8f156bc, 0x341caadb, 0xc4a35e03, 0x4d7d5ad7, 0xbe7deeb6, 0xb1b8e5c4,
+ 0x3b3b3ade, 0x9e21ad37, 0x59e84fb0, 0x0eb4e14e, 0x3fd914e0, 0xa0e3ba73,
+ 0x3aca20fd, 0x0ceff28c, 0x532083ec, 0x338c3ecc, 0x9e5648b2, 0xe5720f18,
+ 0x4cbf98df, 0x3a827a6f, 0x42c5fe5e, 0x2ef267dc, 0xbffdc78e, 0x213c76a0,
+ 0x2b02ae70, 0xf69de6bd, 0x753fcde9, 0xd74ede01, 0xcdd3fbf2, 0x57fc0052,
+ 0x2eaed74e, 0x4db57cc3, 0xfc4c9c01, 0x882e03e5, 0x69e8b2cb, 0xcf53ef11,
+ 0xd0d3f8c4, 0xcbebefff, 0x7f8d4597, 0xb5ba8ac4, 0x169f2069, 0xef8b5d6d,
+ 0x7bc4ceec, 0xf26ae687, 0xbd415324, 0x96d38d50, 0x0bc58cf7, 0xfb6f5dfa,
+ 0xe8e6de52, 0xf82afde7, 0xca5af415, 0x1eb7a02f, 0x4384e574, 0x7e67ff14,
+ 0xb27d4369, 0x4277f64a, 0x1dab6abe, 0xf8aa905a, 0x1e3ff1e8, 0x0bb4dfb6,
+ 0x76c3c7e4, 0x89483eef, 0xed4bc583, 0xf8ea3e6d, 0x856b60ed, 0x78a7b77b,
+ 0xa78a141c, 0x1bbb3a99, 0xe76b77bb, 0xed621476, 0x97863ca5, 0xbb94bd2b,
+ 0x710c9f98, 0xe7572f47, 0x1f9f9673, 0x07b56d17, 0x03d14656, 0x84f7f116,
+ 0x867df88b, 0xbb672f4a, 0x67462df5, 0x1725ff6a, 0x62f465af, 0xb9e14ba0,
+ 0x9f874851, 0x7f70911d, 0x11bb9e11, 0x5d94b4e3, 0x12fd61b4, 0xf828f3d1,
+ 0x45b79377, 0xdefbd3a4, 0x59f78718, 0x9078861d, 0x09e983a2, 0xb1779a6a,
+ 0xe69fa758, 0xb0ca1605, 0x2c5de79f, 0xf60c7463, 0x93983867, 0x689b5e6f,
+ 0x0396f4e6, 0xb4dd2fed, 0x6fcbd692, 0x264ef463, 0xbed0cbf8, 0x3cf76758,
+ 0x8a0e451c, 0x3717450e, 0x84adbf34, 0x49f873b5, 0x7ffee682, 0x9e8b8f11,
+ 0x45c5917f, 0x493f6e24, 0xf2e73a01, 0xfa9f4229, 0x261db5f8, 0x7ae32f86,
+ 0x133af813, 0x437bd7ba, 0x3efdeb2f, 0x0fd72f5b, 0x1bc6dbf2, 0xf1abf5d6,
+ 0x5915d6d1, 0x5fac04cf, 0x970de3c2, 0xd5de1898, 0x4c1d1bf2, 0x7b69ab0e,
+ 0xa5e22ce5, 0x8f2151fb, 0xb81798ab, 0xcf3e064f, 0x2f171cdb, 0x5f99d668,
+ 0xa7e7473b, 0x1f3b5792, 0x6fe570e3, 0xd02f2f9e, 0x9e3755f0, 0x6baf29fc,
+ 0x86e374f1, 0x3a57533e, 0xbdca1f60, 0x3ee301d6, 0x65f73a5b, 0xbc32fd02,
+ 0xa3fd919d, 0xdd0e502b, 0xcef68ae7, 0xdbc046e5, 0x387ced38, 0xc9fb06de,
+ 0xa37bed48, 0x58e3d18b, 0xbe2b6fb6, 0xdbbbee1f, 0x4451649f, 0xd137977a,
+ 0xe38469f1, 0x59bf0e2c, 0x8e1c70dd, 0x8657547e, 0x7f3a75e3, 0xc8e15ea9,
+ 0x49c2aff1, 0xb0f54efd, 0x18448e99, 0x57f7b097, 0x0aafe3b5, 0x27f1917e,
+ 0xa1defaf0, 0xa2fc824f, 0xf4f812f2, 0x1f3fb3ec, 0xb0f76dad, 0x30bde27d,
+ 0xbabea90e, 0xd83fb57b, 0xdf50797d, 0x0473c93f, 0xadfe6bce, 0xae8aa7a2,
+ 0xa9f630bb, 0x56ae10ce, 0xaeaddfbf, 0x760e186c, 0x20caaad6, 0x40bb54a6,
+ 0x8a6a8bbd, 0x685fd01e, 0x78b46f15, 0xbc39eb54, 0x32b65757, 0x4fd5913b,
+ 0x240f60dc, 0x99c92f8c, 0x333768b1, 0x837af43b, 0x60dcf92c, 0x7bf993a7,
+ 0x5becc967, 0xe7099e97, 0xbf0c84e0, 0x1d6bbe06, 0x4362ffcc, 0xf83f52ca,
+ 0x3ec159ed, 0x22ed0839, 0x81767417, 0x9c8bcd57, 0xf0d4ee94, 0xf58331a3,
+ 0x904252e5, 0x246e1da0, 0x479daefd, 0x2eceab42, 0xd98b846a, 0x12fbc2ea,
+ 0x2ef6e133, 0xeff50f0e, 0x72e5ac64, 0xcddb86b8, 0x197b071e, 0xbb4adf85,
+ 0x35a3f70b, 0x39d898d7, 0xf3c66ac3, 0x40f1b835, 0x8fd6397d, 0x7ac1b0eb,
+ 0x43f3d044, 0xe4427798, 0x7b43111a, 0x238f9009, 0x3ef9008a, 0xf406b424,
+ 0x6d89aed6, 0xd9f7c3f7, 0xe01d5f36, 0xd6d4cbf7, 0x4fd802e3, 0x00c37d73,
+ 0x3fa2b5ce, 0x7ff5a143, 0xa033862d, 0x3a2d1a5e, 0x6bd2cf16, 0xa7daafc0,
+ 0xf16197b9, 0xb1792340, 0xe59afe67, 0xc53dc366, 0xe5b4c3d7, 0x2d946cfb,
+ 0x7bfcf5c6, 0x0b1f0929, 0x74b6ef28, 0xf173c9db, 0x8e51d07d, 0xa00fa44f,
+ 0xbf6c23af, 0x625660be, 0x4dfd99e3, 0x67675579, 0x6aaf2ab6, 0xf3f333c6,
+ 0x57a53d50, 0x74aba7b0, 0x35ecd832, 0xa90d3d01, 0x74b5dfa6, 0x832f4511,
+ 0x72f70671, 0x0fcea11f, 0x3c0007de, 0x6c598bc5, 0xc5d031bf, 0x25fb6ebe,
+ 0xb32a7bfb, 0xaf33c255, 0xa238f962, 0xd1fc60fe, 0xe3edba0f, 0xcdde58ab,
+ 0xd80be572, 0x05a1dc7d, 0xa6d7e8b1, 0xcb7663ce, 0xc3d056da, 0x2ea4b766,
+ 0xd999fb84, 0x0afeebd6, 0x7c293ee9, 0xe2720ec8, 0xe79e2ca7, 0x2abdefdd,
+ 0xfbba69d9, 0xdef8addd, 0xcfdf34fa, 0x04b092e6, 0xb711f7f8, 0x01ebeccc,
+ 0xc405d3e4, 0x0941f3c3, 0x84f7bdce, 0x42de7702, 0x1abef773, 0x628e05b8,
+ 0x5f848f73, 0x82f97403, 0xc368a9ee, 0x7b35db56, 0xd679675e, 0x66fd7bae,
+ 0xb227ae2b, 0x5fae2b5e, 0xf6441f5d, 0xb8eef2c4, 0x912e2cc0, 0x0b498f0a,
+ 0xdb67bad9, 0x7c98fce7, 0xdb39de8b, 0xccafea3a, 0xc7cd887f, 0xa1cf9f08,
+ 0x4ec5ca88, 0xa4e4d787, 0xe1d0ffeb, 0x5eb49d15, 0x669c3589, 0x62fc881e,
+ 0xe8997c81, 0xae8926bb, 0xdf00fcff, 0x438044b0, 0xd2ab9f6b, 0xf4e4df2f,
+ 0xefa726fd, 0xe3bbd337, 0x1ea02718, 0xae024f7d, 0xb3a7066b, 0x47dfbb35,
+ 0x6ff3cc3f, 0xa54b78b0, 0x83eb72a2, 0x49133768, 0x6aac38b4, 0xdfb726fa,
+ 0x0e954e28, 0x0dce3c03, 0x4d1997e3, 0x9fbbf476, 0xf4ea2991, 0x029919f0,
+ 0x1d6b87f7, 0x2f4e877d, 0xd2f5c55d, 0xff80fd9e, 0x859fb181, 0x39e327cb,
+ 0x9eec8f6c, 0xffdff208, 0x85b3a334, 0x293c2853, 0x13ace5dd, 0xfc70def0,
+ 0xf20236a9, 0x1c4d6170, 0x85f3fb81, 0x20fbfc0f, 0xd650c788, 0x81b734aa,
+ 0x1e080c9c, 0x8b25bfb0, 0x467e324b, 0x10e9b5e7, 0xbf2187db, 0xf0e9e604,
+ 0x3d8d0e2a, 0xc8aa43ba, 0xdf5d0370, 0x3c82f0eb, 0xf7877f98, 0x6fe78c03,
+ 0x7b041d0e, 0xf99ebab7, 0x00d928f7, 0x9b41f9ff, 0x312b5317, 0x36b950c7,
+ 0x90ac4cdf, 0x6cc4cb26, 0x73cb7c83, 0x1e4bb05f, 0x18e4eeb6, 0xdfdf6562,
+ 0x72f404b8, 0x5bac835d, 0x3ea0a8f7, 0x3eb37d7f, 0xe7d2119f, 0xe7d11ec7,
+ 0x431a83b7, 0xffc395f1, 0xfda1d4ce, 0x877f0216, 0x0b45f8a6, 0x0cbeb3fa,
+ 0x05fa007b, 0x4dde50da, 0x82c96e2e, 0x5e4fd6fb, 0x9ce09a70, 0xdf9befbf,
+ 0x786d7de2, 0xc9e31d87, 0x0c53fc1f, 0xc07f0189, 0xa15b6d17, 0x04e298bc,
+ 0x2fc577ec, 0x0ec0eada, 0x7a8467b2, 0x5fa00d1e, 0x31bf9ec5, 0x76f0f9bf,
+ 0x6fee004b, 0xdcfbd93f, 0x9f6f400b, 0xfa87ef6c, 0xdf82cbce, 0xd7f9fd04,
+ 0xc4e67c33, 0x272d7db0, 0xde33d286, 0x75cfebbb, 0x1c993bf7, 0x1e6caf69,
+ 0x4e59fb01, 0xb47fb33c, 0x011c1e57, 0x8f0e5cfb, 0x49eaae43, 0xbc7e3c39,
+ 0x274fea9b, 0xe51439d9, 0x0fce70c2, 0xb2058179, 0xd5fa01d7, 0x5390188a,
+ 0x79e5675d, 0xac358fe0, 0x15470f56, 0xf406d7cf, 0x7cf92bdf, 0xf7cd1016,
+ 0x56f7b874, 0xbd00a4d6, 0xbea2433d, 0xf9c35c7b, 0x65e7f9e8, 0xf22fbcf5,
+ 0xd14468f8, 0xc88acfbc, 0x1facb273, 0xbe0025f8, 0x17be4606, 0xfb55c61b,
+ 0xfffbca9f, 0x92fccacc, 0xce1c3813, 0x7d411e55, 0xaddf5ba0, 0x68a77af4,
+ 0x07b579f2, 0xfc23e693, 0xd02d260e, 0x1fb6f39e, 0xfe039a4e, 0xfc660d36,
+ 0xb32553bb, 0x27247d9f, 0x418bbe01, 0x03942798, 0xaf823b1c, 0xd51ea0b9,
+ 0xfd68c767, 0x6f6bf257, 0xecd14ef2, 0xce95dfd7, 0xbb65e3bb, 0xca5e5c19,
+ 0x16fdbdce, 0xa2cdbba0, 0x0715aa07, 0x1479bcef, 0x84b37bc0, 0x764b72ef,
+ 0xbdb7184a, 0xb406eebc, 0xbe371453, 0xffe31533, 0x03df393d, 0x9332caf3,
+ 0x9a0c715c, 0xf480ee18, 0x8c6ecb4c, 0x61fc57af, 0x60566c8d, 0xa3ba7abe,
+ 0xa3f08c74, 0x6dd6541a, 0x15de53c0, 0x7eab3fe8, 0x30b7e237, 0xc46f6fa0,
+ 0x1ba72b53, 0x8b5c33fa, 0x3ebd636f, 0x8ef8fdd3, 0x953964b2, 0x543b1a63,
+ 0xf46aa9c9, 0x038e33d7, 0xa344da37, 0x7703eca7, 0x1dafe01b, 0xfe836fcc,
+ 0xee2cd608, 0xe5883ad7, 0xd0200e31, 0x047fac15, 0x3bc0a299, 0x34c8dbcc,
+ 0xd1b95548, 0x0d1c1d91, 0xda165ff5, 0xf615fd9e, 0xed7e44e7, 0x2e308770,
+ 0x3efe5f62, 0x796143b5, 0xa83aeff5, 0x362d45e5, 0xe4f8f3f4, 0x71f28cbc,
+ 0x4197f805, 0x266c17fd, 0x3ebfdd13, 0x1267d9d9, 0x04762df8, 0x73dcbc59,
+ 0xe4933ec1, 0x8d77d96f, 0x0fdd4172, 0x74afc04f, 0xe9c2fcdf, 0x4b7ec30d,
+ 0xcebf3156, 0x19153ee4, 0xa4f05115, 0x2b904bb6, 0x123ce032, 0xd9e1d7be,
+ 0xa7f2708a, 0xc1723ec3, 0x81f68297, 0x121edcf9, 0x06fdceef, 0xbad275fa,
+ 0xfe2ffa5e, 0xe815b888, 0x73d163eb, 0xe4507bbf, 0xa6516f9e, 0x90f3df0f,
+ 0xb45cec55, 0x66424cd0, 0x842eefaa, 0xe63463fd, 0xb85bbf71, 0xa6ff4059,
+ 0xebf41b45, 0xdaad7881, 0x405087bf, 0x22dfb1aa, 0x60b4c412, 0x10bcbeb3,
+ 0xf81723f6, 0xfc7bb067, 0xb97d7aa2, 0xa4a84efa, 0x1a25b2f1, 0xea20bedc,
+ 0x2ec9bcfa, 0xb36e179a, 0xdbeefce2, 0x35eecb14, 0x7d85e264, 0x89c9bc30,
+ 0xf898bc72, 0xbe3f3bd8, 0x303f960f, 0xd288bbdf, 0x85f2d767, 0x307d45de,
+ 0x7d81077e, 0xf895b16f, 0x1e58635d, 0x0b2017e2, 0x38b29f21, 0xed4eb051,
+ 0x29e2963b, 0x15c03424, 0x53ac2f59, 0x65de4e5b, 0x116e2cf8, 0xbd60a342,
+ 0x64427ef0, 0x2bd6d5eb, 0x692870e1, 0x11ece8b4, 0x0a7fe0a5, 0x974d337e,
+ 0xb97eba2d, 0x8fdd1f3f, 0x69e28d89, 0x0ddcb753, 0x4fcd1b5c, 0xd78738fe,
+ 0x52f33ba6, 0x051f3f81, 0x072fb33d, 0x173d3668, 0x61cc9083, 0x71d2b780,
+ 0xe776c662, 0x256b3cb1, 0x647d4fcb, 0x51e90fe0, 0x1bcefe1b, 0x142c6fde,
+ 0xf7875f73, 0x7db9cf57, 0x71d1763f, 0x69bc9a16, 0xef53e466, 0x5cd7f450,
+ 0xc4ffd6ce, 0x2b6b8a98, 0x557b9ca2, 0x042e3e7c, 0xbfd1bef1, 0xceabed97,
+ 0x7da4b0cc, 0xc5c8b45f, 0xa1ec4fe4, 0x10777c36, 0xbbe02dde, 0x138527c7,
+ 0xc9f02ef8, 0xce04291f, 0x6f1429e5, 0x149f1f20, 0xbf882ac8, 0x7334d995,
+ 0xbf806bc9, 0xa3d418cc, 0x8a269b4a, 0x3f5c0ea5, 0x15eca3d3, 0x99ef7075,
+ 0x18f86f3c, 0xeeba6ba0, 0xff01b779, 0x5b8414bb, 0x41d183aa, 0xfa7f4aca,
+ 0x7e3091d2, 0x80d792ee, 0xe0c546ef, 0x0a64d93b, 0xa63c672b, 0x4a2f40eb,
+ 0x41071921, 0x574ca78e, 0x772d80c6, 0x938d8b93, 0xcde71268, 0x0c6dfd04,
+ 0x243fc7cb, 0x7122b778, 0x2575c46d, 0x369fd85b, 0x7fa0ef82, 0x804ec15a,
+ 0xe78601e5, 0x301915c9, 0x9620f27e, 0xf421c826, 0x8dda3a53, 0xcdea1f77,
+ 0xe504dccb, 0x134bb2f2, 0xfb69e393, 0xc0f41da3, 0xd1d5e54c, 0x1d9eaafe,
+ 0x439e8072, 0xf5670f06, 0x2cb15eb9, 0x27e5f983, 0x10faa9a4, 0x7925d7ab,
+ 0xfc82c763, 0xdbe9877c, 0xb1bc3b9f, 0x837737e0, 0xb80fdd1c, 0xfca9e386,
+ 0x34049da2, 0xd67cbff2, 0xa4def897, 0xf74ba2fc, 0x69c9e21d, 0x0a4b49fd,
+ 0xe3dc610e, 0x7e8ad252, 0xbd41a5c9, 0x310debff, 0xe955c7d1, 0x48a2fcbc,
+ 0x95c751fc, 0xf62fdff5, 0xd13efe21, 0xbfe925ea, 0xf9f4145f, 0x3d78afe6,
+ 0xd9277e33, 0xc7382e6d, 0x077d874d, 0xe4c049e4, 0xe08fae97, 0xa6ddd3a5,
+ 0x153a6fdb, 0x71e2ef96, 0xb572d575, 0x3259ceff, 0xc6139f7f, 0xa92a3a71,
+ 0x79f0a240, 0xb453e5aa, 0x1cb496a3, 0x74a8f844, 0x9d938111, 0x4a7035f8,
+ 0x990d6aaa, 0xfeff8f28, 0x476b4591, 0x72514b5e, 0x3fb3f388, 0xf297ad6f,
+ 0x2fc4126f, 0x3db7f0d7, 0x51df9bb3, 0x89326ccc, 0xbf99dedc, 0x4d04ca76,
+ 0x6eefd79e, 0x21f82fef, 0x648e6794, 0xa47bdfed, 0x072b77f0, 0x5d13e447,
+ 0x53ae5a47, 0xf21ab793, 0xa51f9a0e, 0xe50dbbc9, 0x14f28609, 0xab3fbe43,
+ 0xa50ce1df, 0xda421e89, 0x21fd291e, 0x8eb95dfc, 0x885cd0d4, 0xac41b038,
+ 0xddfc21f8, 0xf64cd2c9, 0x5acb1477, 0xb3730f04, 0xf32bf062, 0x87307bb0,
+ 0x385e4da7, 0xfad0e012, 0x9283c83a, 0xfa0dc166, 0x33b823be, 0xa7687984,
+ 0xd905da68, 0xe092ad3b, 0x6bd76c09, 0xc84dc3ff, 0x3f0f0fcf, 0xe4aef589,
+ 0xeba644ef, 0xf37be0fd, 0x7c9874b3, 0x53df6117, 0xec770ce3, 0x77f23f7c,
+ 0xcef7e8ed, 0x9461ef54, 0xaaf786a7, 0x471f30e5, 0x38545f84, 0x02fc3c3e,
+ 0xf3fc5dc6, 0x40f796a8, 0xfb2fb00d, 0x95e80574, 0x1e9e961f, 0xc4167a07,
+ 0xe3fd846e, 0x2d702171, 0x114f47ec, 0xee30b5df, 0x0e43a5bd, 0x39949fc2,
+ 0x816db52e, 0x1ec31050, 0x3ff08f5d, 0x001b6cee, 0xdae8927f, 0x4f961ad8,
+ 0x1008c36c, 0xfd37626b, 0x39fb4cd0, 0x806da03e, 0xc547e689, 0x43e5661e,
+ 0xfe40b6da, 0xb0dfd8ce, 0x036d51f2, 0x1d1c3744, 0xdb7f111a, 0x3ef9d1dc,
+ 0x1bc9962d, 0x06437e75, 0x4163537b, 0xfb612a8f, 0xb4873c0e, 0xb73ab952,
+ 0x6d8edce8, 0xff731e14, 0x6ef28ed5, 0x3fedc75b, 0x3fb1fa66, 0x92a0fc17,
+ 0x5f71bc39, 0x466ef944, 0xf61521bd, 0x3e08f8c2, 0x0aad699d, 0x2a231bee,
+ 0x905e8276, 0xee24773c, 0xef4e9d1b, 0x9171d8da, 0x9a048bf4, 0x8dac79d2,
+ 0x2ef93375, 0x5b3df09a, 0xd44e83f2, 0xf1e51e9f, 0x21df29ba, 0x5e38387d,
+ 0x8cf5f2c6, 0xa1e7658d, 0xd84dd744, 0xaf5cddcf, 0xd81f59ad, 0xfff0a36e,
+ 0xde0e7a93, 0x39e4f4c8, 0xc4ee5475, 0x37817f82, 0x1cc9e415, 0x8c8f07b0,
+ 0xbfbd55e4, 0x1de68326, 0xcd58f391, 0x36aa6f4c, 0x1d4d782e, 0x55e5572b,
+ 0xaf6b3a4d, 0x55c95bee, 0x8fc93e0c, 0xd615bb5e, 0xff333761, 0x86b3c581,
+ 0x7a815d6e, 0x5f386dc0, 0xc2a6f5e2, 0xe154fcb9, 0xa3e81340, 0x0da67e2a,
+ 0xeb82def6, 0x2a38f7e1, 0xd7f1d49e, 0x142f75f2, 0xf6011ea9, 0xe10fb774,
+ 0xd18af549, 0xe99d72ec, 0x5ae96b15, 0x7c2a1f01, 0x1c6db989, 0x045fff7c,
+ 0x0cffa5a7, 0x7eddfd38, 0xbc7bd3dc, 0xfd0359c7, 0xad3f2e97, 0xe1c38f7f,
+ 0x9210b8fe, 0xf1353392, 0x3877e853, 0xf2eade77, 0x735622fd, 0xc1f735bf,
+ 0xd53fd452, 0xe5ffd8f5, 0x917769a5, 0xd469fc9e, 0xc9ff8f0f, 0x02ec01ba,
+ 0xca20e5c7, 0x263fe3e3, 0x38e42ef8, 0xeaa5678f, 0x5aff59b7, 0x6dce147c,
+ 0x222b11ff, 0x7a54d87d, 0xe6777210, 0xa7aef851, 0x3bbc39db, 0xd464fd57,
+ 0xc786bafd, 0xe079ada1, 0xd1af7c3a, 0x3cf0da45, 0x2826cfee, 0x67cbbb3f,
+ 0x4a72c50f, 0xc81b7e27, 0x8c18c289, 0x41935fc7, 0xcd497df0, 0x0e5811ec,
+ 0xc7f458e7, 0x71c56d99, 0x3a32666a, 0x478c29ac, 0x5dc8217b, 0x746f5b80,
+ 0xecc55494, 0x1decc41f, 0x7f1fbdad, 0xf9f9962f, 0x76db33db, 0xed7a0fbf,
+ 0xb5ea1b06, 0x57bc4280, 0xf1c64ea9, 0x8fec3d28, 0xcd97fdc5, 0xa963e163,
+ 0x5c718781, 0xd603da0f, 0x51f3bd3a, 0xaeccfdce, 0xdb37fcc0, 0x18eb3ac8,
+ 0x5590e638, 0x7cf92f28, 0xe813f548, 0xeb8f3157, 0x5c151f89, 0x721e8270,
+ 0x1edbb634, 0xf9f385e0, 0x17cac202, 0x013f643c, 0x0f05abe7, 0x64b778b1,
+ 0xfd5e4ddd, 0x6b9d093d, 0xf9d3d812, 0x09d86d4f, 0x3b41f070, 0x1ffff417,
+ 0xe41f784e, 0xc3bd887b, 0x7eda7e25, 0x47fda478, 0x9760f7c0, 0x49fcd917,
+ 0x16895da5, 0x58a3f4e7, 0xfd5397ee, 0x9e3b5784, 0x5fb18e3a, 0x036c8e7a,
+ 0x0f70a37e, 0xf0a83bc1, 0x59dfd8cf, 0x4137ce30, 0x46c2ff0e, 0x8a56e7cb,
+ 0x3c292b71, 0xb89dcb7d, 0xf3be755e, 0xa237c392, 0x7fd0c29d, 0x0b2cbdbb,
+ 0x79eae7ec, 0x39a43c88, 0xe45c21ff, 0xf8845e48, 0x573c6101, 0xcfcef8f5,
+ 0x2873c6cd, 0x68b37f21, 0x2bbf75eb, 0xfcc30450, 0x82295d39, 0xe3e6f019,
+ 0x1cb2fef7, 0xeb720b9e, 0x50eb02ff, 0x8000589e, 0x00008000, 0x00088b1f,
+ 0x00000000, 0x7dc5ff00, 0xd5547c0b, 0x73b9f899, 0x3332bcef, 0x49324cc9,
+ 0x9b8f2126, 0x80402107, 0x52024c49, 0x1878431f, 0xa4076b35, 0x438b5b16,
+ 0x921123c2, 0xb175b689, 0x5100cb65, 0x8d042208, 0x41380abc, 0xbb6bba50,
+ 0x060222c1, 0xb6a2d11a, 0x6eb42fea, 0xfdfeed57, 0x58f88845, 0x16544649,
+ 0xefffad5b, 0x99b9cefb, 0x514493b9, 0x67f4ddbb, 0x739ee72f, 0x77cef9cf,
+ 0xcef9f7be, 0xe99a1619, 0xf4662deb, 0xfc3e79f7, 0x33577f87, 0x3034e896,
+ 0x7cd8ca96, 0x96773599, 0xeb47df44, 0x6d67aa25, 0x34967d5b, 0x0bbc02c6,
+ 0x66f536e6, 0x607da1fb, 0x694df9b9, 0xeb88bc22, 0x6330b19f, 0xb56d8c15,
+ 0x993590b2, 0xf4126db1, 0xbbcf0e53, 0x7935e16c, 0x23580d8c, 0xc602b08f,
+ 0x59afc782, 0x1bfbef80, 0x4d065412, 0x08589876, 0x8ee3a1cb, 0x576c3ef0,
+ 0x64c45bd4, 0x7c1807a8, 0x24be786e, 0x0d248477, 0x5e9ac608, 0x87acf792,
+ 0xae47fd76, 0xb2acfde5, 0x41ca0ca9, 0xb8c136a8, 0x575fd0c1, 0xa4c644b2,
+ 0xff1a1639, 0x6c2921cc, 0x66c3fac6, 0x85e0d3e6, 0xbfe1faff, 0x2f1832fa,
+ 0x2719086c, 0x102b13c1, 0x8236c38e, 0x40da6603, 0x813f7de3, 0x9bf187ad,
+ 0x00cf920c, 0x8db74df5, 0xf0e1af0b, 0x67e01858, 0xc9ad0099, 0xe8245ac0,
+ 0xb5e0532f, 0xe8ba70c9, 0xa75e128e, 0xf8a5bb40, 0x3dda950f, 0xcb9c012b,
+ 0x647a1b2c, 0xe1399380, 0x0dbfa83f, 0xeba2f3eb, 0xbfe1b4d0, 0x3479c33f,
+ 0x2db8041d, 0x3d97b851, 0x6dc79fa6, 0x27ad14cc, 0x7eb443b8, 0x2f8e72b6,
+ 0x47858336, 0x510ebc03, 0x84f755b6, 0xf2c7c465, 0x65ccece9, 0xef44f4d0,
+ 0xeb1dbf2c, 0x3c2d593b, 0x5f30ef83, 0xda9ee018, 0x28ccf1d5, 0xeeaaef68,
+ 0x06e9c6c9, 0xa0b1ff97, 0x3ae8b2ef, 0xde5e706b, 0x766659b5, 0x03be8f1a,
+ 0xec077c50, 0x9cec6ed4, 0xd5cfb109, 0x41aa5df4, 0xebc715be, 0x881957c5,
+ 0x04865f1c, 0xc8696ce3, 0xdabae037, 0xb0057814, 0xb31b6a2e, 0xd9e11567,
+ 0xc1c73457, 0xec8983d8, 0xd3e13f56, 0xfe87e95b, 0x2d56751e, 0xe97f4274,
+ 0x9d5baaae, 0xbf1c7ca9, 0x029fa703, 0x6ba50d40, 0x47e1a9ed, 0xd05e976b,
+ 0x1f6cda5c, 0xc4db9db9, 0x9ed916f1, 0xf083de14, 0x17951228, 0xb1d8deff,
+ 0x8853e09e, 0x95d8ee6e, 0xebf84617, 0xe9099b59, 0x9b0b197c, 0x5b178e90,
+ 0xe8112858, 0x4b343162, 0x6d92e782, 0xacc6a666, 0x5f58435f, 0xae1ced66,
+ 0xd3f74a65, 0x4dd22252, 0x74b3f50f, 0xb2ddbebf, 0x01dbac19, 0xd6168df5,
+ 0xa767c36d, 0x4589bebe, 0xe1e08e08, 0xfebacdcf, 0xc3ad1b59, 0xc8632b76,
+ 0xbe6549a7, 0xfe01bbbc, 0xef460bc8, 0xb7cfa01e, 0x7868bac4, 0x35567648,
+ 0x64139e20, 0xb233cd03, 0x03de16ca, 0xb033ecf3, 0x4de75c7a, 0x1ceb762e,
+ 0x64aff678, 0xa12342be, 0x77ae2263, 0x1fd73e3c, 0x7d23d6b5, 0x13f9416c,
+ 0x38373f43, 0x5ee7848d, 0xbe47ab13, 0xfd0d5ca9, 0xa6a5c8c5, 0xfc01ec9b,
+ 0x9726976e, 0xc46f9d60, 0xa86b6675, 0x9e91ed8c, 0x4fe32e12, 0x83bdbbed,
+ 0xa7f337ed, 0x4b7bf9c2, 0xae074243, 0x0cee9453, 0xc4aee88c, 0xf7c00a6f,
+ 0x583c8547, 0x38fdf960, 0x40a3f7a4, 0xa1f7c808, 0x0b972b4e, 0x72fe738a,
+ 0xa77d1f28, 0x455ebbc4, 0xe272e0fa, 0xd812f7e8, 0xf9f2186a, 0xdef5fef7,
+ 0xfcfea197, 0x0cd5263b, 0x46910bf5, 0x4a8f3d60, 0x85e387cc, 0xf787309e,
+ 0xc065bbc1, 0xb2cf08b6, 0x28c213e3, 0x02990edf, 0x38e117db, 0xfbbd1b8f,
+ 0x8965bbe0, 0x423c5fe1, 0xa05e19f5, 0x9194f644, 0x88e861d3, 0x109f7f8d,
+ 0xb95fb7fe, 0x1bdd3eb1, 0xac7bf682, 0x07c81381, 0x09356699, 0x97bf65fb,
+ 0xbba71f19, 0x3bf805c8, 0x824af38d, 0x38495427, 0xfa83974e, 0x58cafe01,
+ 0x699cfd04, 0x80f9a74d, 0x38e1f4dc, 0xf79a3667, 0x32dcdca0, 0xed44ae38,
+ 0xb3fd1b4f, 0xfa7ca032, 0x2aef5289, 0x9bf01aa8, 0x7f404dba, 0x5f4b4dc1,
+ 0xea17a064, 0xc46eea0c, 0xa36e3b0f, 0x11eb6879, 0x06a4b8dc, 0xadb783eb,
+ 0xdae501b8, 0x7289fc48, 0xbbc8c59a, 0x41c9167e, 0x9f51dffa, 0xfa8dd9df,
+ 0x57ac6ba0, 0x2c0f5aa6, 0x9387d03e, 0x7233edb7, 0x198e46fc, 0xb52f4f89,
+ 0xa50ba47f, 0x1c0feb92, 0x94f20827, 0xf242fc69, 0x0f2ca634, 0x18ebe657,
+ 0xfc4e9a3c, 0xdb3f5f1f, 0xf908f811, 0xfffee9a7, 0x8ab96379, 0x9e4845e3,
+ 0xe254b6b1, 0xdbbb8033, 0x6df7df02, 0xe55f1077, 0xf70f50ae, 0x741ebae2,
+ 0x335d3cd1, 0xcb03b27c, 0x3ca8f33b, 0x1c6dc855, 0xe2c6f516, 0xcaf48c29,
+ 0x58b59962, 0xd17de8ca, 0xf67f6876, 0xcf5a6c89, 0xceb666c5, 0x36ce7c02,
+ 0xdb3ffa70, 0xf00a7201, 0x25ee6753, 0x4dfecb39, 0xb518fb62, 0xcb76c16b,
+ 0xb28c9060, 0xb94378a1, 0x385bc3a5, 0x7ffa0ca6, 0xe907676a, 0x8a720601,
+ 0x9a05d8c5, 0xa4f9431c, 0xcdfd9efb, 0x4863c7ac, 0xc7c4b793, 0xd9f4a930,
+ 0x28f2a213, 0x72cfe9d9, 0x30a16055, 0x5677f11d, 0x04e9dc0e, 0x8584b6f9,
+ 0xb0363e48, 0xe36a7a6e, 0x72e5bc81, 0x2ee5c2d7, 0x412e133e, 0x3ac6defe,
+ 0xa2366e49, 0xee4e1a44, 0x3bb900ae, 0xcbb96471, 0xe2297358, 0xdd8b7835,
+ 0x221e788b, 0xd77c857f, 0xc4dd31d6, 0x15d4f0e5, 0x44959961, 0xe89a90f1,
+ 0x115a969b, 0x57c1abd5, 0x1275162d, 0x1f2cfd96, 0xda63ade5, 0x7d41a7bf,
+ 0x943e6150, 0xe61eb69b, 0xbbf780eb, 0xf3f5fd84, 0xf1fa9534, 0x185d3898,
+ 0x852b3f15, 0x9eaacafa, 0x49f2036e, 0xbca2732a, 0xfef0f477, 0xbbe03977,
+ 0xcb8efc32, 0x2defc1cd, 0xe62125ac, 0x56a3aafb, 0x470ba3a2, 0xe933611c,
+ 0x0bae40c3, 0xb3fb4bfa, 0xfea4ec99, 0xf3920ea3, 0xaf3646fd, 0xd1bbda13,
+ 0xbcf5a21e, 0xaefbfa87, 0x219e8f2b, 0x218a3556, 0x8dd74aed, 0xecd65642,
+ 0x9ebcc683, 0x1edf489b, 0xc7c8ab30, 0x77bd5c17, 0x63c61962, 0xedbf2728,
+ 0xf05da952, 0x9fd2f4e0, 0xdfa0fbc2, 0x0dd8e5ee, 0x98bd2294, 0x64dd1fe5,
+ 0x259b7581, 0x05dc88af, 0xdb663670, 0x6787289d, 0x9fd7fee4, 0xbbf2866e,
+ 0x8ccc8d07, 0xfa6fbeeb, 0xb23f963c, 0x1b08689c, 0xd0c6f74f, 0xfafdd2eb,
+ 0xbea76372, 0x2fac3c1c, 0xb872e1df, 0xde278ecf, 0xf40e7ef4, 0xbf373664,
+ 0x9af001d3, 0xdc93329f, 0xf815debc, 0x26e7a467, 0xe224e443, 0xfefb9cd1,
+ 0x73ae00c4, 0x3e1207d7, 0x3d2640cd, 0xc8bf1c25, 0x0bac1757, 0xd8c39d72,
+ 0x857b51eb, 0x47840c59, 0x513d06b0, 0x20e410f9, 0xdef95f01, 0xbfe61a7d,
+ 0x73824e78, 0xd5f1bd35, 0xbda25454, 0xe0b23042, 0x45df6bb6, 0x35da1ebb,
+ 0x0d989c90, 0xfaae00ed, 0x2f6e5c6d, 0xc8893d63, 0xd7604d0f, 0x7f096058,
+ 0xb1f4e2e7, 0xd95225b4, 0x4f6cff0d, 0x708b1eae, 0x7e299f2a, 0xd8b5ff5c,
+ 0xf61d8c6f, 0x1dfb8b90, 0xdb5bf74b, 0xa1f862fa, 0x2ba5d3b1, 0xb4670f07,
+ 0x5de2c5f5, 0x25533ff0, 0xb6ded625, 0xb90f021b, 0x7b0f9152, 0xfc60d34d,
+ 0x88fb3fab, 0xe592f7f4, 0x0a9d90cf, 0xedc058f3, 0x728aab36, 0x4f5dc975,
+ 0x2fcd7bd3, 0x276d9b38, 0xed99e0bf, 0x99765e66, 0x17767ca8, 0x74965bf7,
+ 0xa79c614a, 0xca62e734, 0xbba79434, 0x1b334e8c, 0x3c78d78a, 0x3ff3bdbe,
+ 0xf54c1913, 0xfa3a426d, 0x1bb71213, 0x6489cd9c, 0x89cdaa9f, 0xb7051f68,
+ 0xca2ef35d, 0x64bb25a9, 0x7635ea2f, 0xcd1de1cc, 0xec733cb0, 0xf3f63b22,
+ 0x8034ca61, 0x4cf77da3, 0x65ef4ca7, 0x48f9187f, 0x0d5cf5f1, 0x93dd95ef,
+ 0x67b7e455, 0x97f87177, 0x208f2cb8, 0x99fd5d1d, 0x62b2764c, 0xcfb40160,
+ 0xb1be4dda, 0xceeab7c8, 0x7d70b37d, 0x699d9ede, 0x94bff6a0, 0xe2f11398,
+ 0xef869e5a, 0x1f8a4897, 0x5b7eb4f9, 0x7eac4d43, 0x1325d5be, 0x5dcb4dbf,
+ 0x276bd691, 0xf509babe, 0xe02ee355, 0xce7f1c23, 0xd9ba7feb, 0x692be51d,
+ 0xa61bb6ce, 0x1a8fff62, 0x8377c8bd, 0x3fe7777a, 0x5fe17d11, 0x6dca2577,
+ 0xca6faf8e, 0xc69b6667, 0x2845cd27, 0x6eac973f, 0x630e722e, 0xc9f20fcf,
+ 0x6f97ce4e, 0xb7ee24b9, 0xeceb2566, 0x00fc91dd, 0x87c1b17b, 0x9978b7f8,
+ 0xd33c1f6f, 0x7f430dc1, 0xa159212f, 0x136484fa, 0xe4f949e1, 0xa92ffd8e,
+ 0x3e071768, 0x65ccfa44, 0x27d452be, 0x9559c46a, 0xec2b7484, 0xdb93b605,
+ 0x907f6081, 0x9525b5bd, 0xc63eb23d, 0xfe8933ff, 0x8a7c4e40, 0xb5ffa272,
+ 0x7e224f4f, 0x9fde729b, 0x783afa88, 0x0a9323f1, 0x4977b5f3, 0x5eedbf24,
+ 0x09ba433f, 0x0b66cd76, 0x3772a24b, 0x217ae5e8, 0x26375e7e, 0x751cb91b,
+ 0xab9fa847, 0xb73f3852, 0xd3d118bb, 0x6409e58e, 0x8770ee97, 0x57f408ad,
+ 0x29f65be5, 0xe7587568, 0x675f0b06, 0xfb5fdecb, 0xb0f3a464, 0x658d1ce4,
+ 0x40c7f395, 0x0cb0fcfd, 0xb7bbbce3, 0x83e54420, 0xd432bcd3, 0xbc3ef7d9,
+ 0x74f11f2e, 0xf6c5e8d8, 0x226f6f76, 0xbdddefce, 0x7e711267, 0x9a657bf5,
+ 0x83f87d77, 0x512545b4, 0x2917f139, 0x768c9050, 0xc7b25b82, 0xf7778bca,
+ 0xd0b6987e, 0xd253fdce, 0xe3c3e597, 0xad35dd25, 0xfabfbf18, 0xef2ebe2a,
+ 0x461cd2fd, 0x159ef839, 0xfc8c59f4, 0xf5c1cf7d, 0xcd64d4db, 0x41cce8cf,
+ 0x565833fd, 0xfc701ac6, 0xfcf9391f, 0x1ccea6dd, 0x96ffcbe4, 0xb6dcfdf4,
+ 0x9061664e, 0x24eb0d4b, 0xff990616, 0xcc9e2fde, 0xeefff941, 0x6a7327be,
+ 0xff8be063, 0xd0ce7b4e, 0x9af113c6, 0xd78da65a, 0xd5e3859d, 0xa26fcd7a,
+ 0x66eb619c, 0x26f906fa, 0xdb633f9f, 0x8a3e6db3, 0xd7000ca7, 0xdf6a1d22,
+ 0xf827d40d, 0xcc2eb82c, 0x4e90c612, 0x6ddc976d, 0xbe7cfec6, 0xdfda3742,
+ 0xfd71f7da, 0x927a0ab7, 0xa7e44b0e, 0x24224ada, 0xfcb6bf9f, 0x13d7e8f7,
+ 0x4c98d9d6, 0x72723ff2, 0x30fa2314, 0x4d4cde21, 0x55f50576, 0x5f4e1ada,
+ 0xc81b1f91, 0x2427701f, 0x3f60644e, 0x763d3299, 0x17576f94, 0x9218b425,
+ 0x184e7df0, 0x166767db, 0x2aa177d3, 0x34a1ff4e, 0x0c9e7146, 0xff212cd6,
+ 0x97b72732, 0xe730a6b3, 0x4fee287a, 0x878c76e6, 0x05c9b779, 0xc612feb4,
+ 0x68bc3425, 0x08e901fa, 0x927be5e5, 0xea48e885, 0x947ec892, 0xb1f39d0d,
+ 0xeae891df, 0x8ad75c6e, 0x960d5d28, 0xb57441ff, 0x086f1b49, 0xa254055d,
+ 0x78658f2b, 0xf62552ba, 0x90b3da95, 0x74affd1f, 0x424daf81, 0x6c7e44fe,
+ 0x4016f1e1, 0x46b7ce19, 0xb16357f4, 0x47a8cb77, 0x63f7c6bc, 0xc13b8fe3,
+ 0x25ff45ee, 0x787ced03, 0x40b35a8e, 0x3d6375a5, 0xdaefe8bd, 0x5f485b26,
+ 0xc9e86bde, 0x7d263b43, 0xa401f35c, 0x25f9f48f, 0x6fc86b65, 0x5ea172cb,
+ 0x714b5d40, 0xfdd3e587, 0x7e808edc, 0x9b668e91, 0xba6b3fc8, 0xdb9f9a6b,
+ 0x2fc4d511, 0x15560dc1, 0xaef4e0f5, 0xf76455bc, 0x335e60af, 0xf6c771d1,
+ 0x9c2f18c5, 0xaca2f76b, 0x213c62b3, 0xe7afe705, 0x93a956bb, 0xb5d0f1ec,
+ 0x5d728bcc, 0xbbb6478b, 0x14ff777a, 0x09437ff5, 0xf183f7f9, 0x7a4642c9,
+ 0xcbe5dda3, 0x1ebc0648, 0xa78f1bfa, 0x194297b5, 0xf5894f9e, 0xcbed9f6c,
+ 0x76b94170, 0xdef09583, 0x07ebc1de, 0x49a0801c, 0xfea4a714, 0xeb859258,
+ 0x81f2a1a1, 0x53699be2, 0x0db7f698, 0xb95a99cb, 0x41d92b6d, 0xe7b7ff1a,
+ 0x251c7871, 0xc8b43cfe, 0xf1dcdf2f, 0x47f0027c, 0xa68dc61a, 0xb42117d2,
+ 0xc92e29f7, 0x7cb614cb, 0x648000d0, 0xeb27f162, 0x5b115c67, 0xdfa3ede6,
+ 0x7ac7af5b, 0xf583bfd0, 0x65e83608, 0x02b3ecad, 0xd11d6b1c, 0x60ec057a,
+ 0x7c4961cb, 0x3375e4ff, 0x92fe610b, 0x93f43f18, 0xafc61f56, 0x5e374cac,
+ 0x5c4a7c2c, 0xdfe846ff, 0x77ed6aae, 0x0684cf56, 0xe569960f, 0xb2f9d78f,
+ 0xbea33fa0, 0xf8a9423f, 0x78da0b1e, 0x63383dcf, 0xa8ac86fd, 0xc2f6007d,
+ 0x34cf2827, 0xebed613b, 0x60936d35, 0x43f39b2c, 0x4d5fea13, 0x12dd07df,
+ 0xfcf121d9, 0xbe914b6a, 0x085d7d99, 0xcea575f6, 0x70a5b6be, 0xb2167afb,
+ 0x2425f824, 0xfc2b83bf, 0xb05bed0c, 0xbeb0924b, 0xcff7b5ff, 0xfdf50d3e,
+ 0x7272fe73, 0x6eed8a94, 0x557e8f9f, 0xf242a2f0, 0x0e5fb837, 0x9637c04b,
+ 0x83576e2e, 0xb478a73e, 0x39b73f46, 0x42b8fd05, 0xed6ce30c, 0xa40aa4c7,
+ 0x73a3f077, 0xf96b03be, 0x665f14a3, 0x9fd4454a, 0x65f79f8c, 0x189e3c29,
+ 0x5edaae2c, 0x95effd84, 0xeb0bda18, 0x2da74f8b, 0xcdea7f24, 0xdf3145b4,
+ 0x907e1c35, 0xdfb0d9f0, 0x2f1e2c38, 0x8f09914b, 0xf09e474d, 0x2f78dca1,
+ 0xa84c912c, 0x68adc257, 0x1bd7d6d7, 0xe56422d0, 0x533705e1, 0x899e7d7c,
+ 0x65f9868d, 0xdc177d08, 0x2a68637f, 0x93fe1bce, 0xff0ed5e0, 0x3b139262,
+ 0xb4ec59e6, 0x7b5c514f, 0x99c1e13b, 0xac3c43e0, 0xc0caae2f, 0xcf669a71,
+ 0x1e5c5272, 0x6fac39ec, 0x147bebba, 0x5ae0d7a7, 0x8d58d87f, 0xd8254ef6,
+ 0xb806bf75, 0xabaf93b3, 0x8f5f02f6, 0xfe940f92, 0x465bca10, 0xba2fe390,
+ 0x48b45d39, 0xcbb7d0fe, 0x62c78e29, 0x87b972e3, 0x7d78fdb9, 0x69da898a,
+ 0x514fafef, 0x8457af08, 0xb923a67a, 0x6d7a571c, 0x99075768, 0xabf403ef,
+ 0xeeaedf99, 0xf2e275a3, 0xa552bdcb, 0xddc59378, 0xac24ef7b, 0x7f2142bf,
+ 0x0fbd2986, 0xadfdb8e0, 0x267aef6e, 0x77cb00f8, 0xea1c5095, 0x1e604a68,
+ 0xb0a56fae, 0x5c8ffb57, 0x125b5a53, 0xf75abfb5, 0x01abc239, 0xf50ead0f,
+ 0x93946afe, 0x2724289f, 0x33d22599, 0xf869fa1d, 0xfbf5326b, 0x0ea05b07,
+ 0x86b569fb, 0x420e915b, 0x73b5321d, 0x6374b1cf, 0xe23eef3f, 0xd33b40e8,
+ 0x48636ee8, 0x50bee0c7, 0xf6e2c49c, 0xd3ca1533, 0x09140b43, 0x5d9c45f5,
+ 0x49e31d33, 0x29b8b7e4, 0xf82558de, 0xc1503463, 0x42b10b59, 0x5129e7cb,
+ 0x4ff9e73b, 0x52f82ae7, 0x160c7fb3, 0x319e1f1e, 0xf8e1812f, 0x49c89eec,
+ 0xdd9bc603, 0xe1ed0c3d, 0xc6894ec6, 0xdc7e2c69, 0xd2cbfe84, 0x41dfce4e,
+ 0xfe006fe1, 0x58aed072, 0x76136291, 0x77a70b66, 0x147273d6, 0xbe31f9e2,
+ 0x3b418c9e, 0xb2dfac47, 0xfd69da8a, 0xbc9c4499, 0x4093c451, 0xdafd5213,
+ 0x58cecd14, 0xc26d9e2d, 0x6ee3e0ce, 0x327c7a91, 0xd254b3e2, 0xe7b573c5,
+ 0x9277216e, 0x2166444e, 0xbe8046ff, 0x5db4ae30, 0x6ffb7d9a, 0x2bdb7e61,
+ 0x14d179c6, 0xc93900f3, 0x481ef865, 0x7e5ef011, 0x485983f8, 0x119aac37,
+ 0x9e1d36bf, 0xfd8a3726, 0xd217b404, 0x581dcd6d, 0x316b7e9f, 0xef8c67e9,
+ 0x5ec0bee3, 0x3b0cd781, 0x5679eb8f, 0x9f70f287, 0xff84e92d, 0xf8e2dff6,
+ 0x1f681213, 0xc6d61d23, 0x75cf4c91, 0xb0f2d718, 0x3f51a7d2, 0x32d46a7b,
+ 0x4fdb4784, 0xd9a8fdc2, 0xa9c72425, 0x7c95ec9c, 0xabf9e07b, 0x01e11714,
+ 0x846abcfc, 0xed87df17, 0xf4adfdd1, 0x38a5cde9, 0xe11fee2e, 0x5ba33fb3,
+ 0xeb3538a1, 0xfc8fbddd, 0xf113b37e, 0xb9f87355, 0xd6ff5157, 0xed275858,
+ 0x2dd9c5f7, 0xf1bc4e3f, 0x03a39449, 0xbeeecee7, 0xcefae11b, 0xd6806f21,
+ 0x5c8f6f47, 0xcfb7157d, 0x5367dbdf, 0x23dc8ed1, 0x8fd836e4, 0x5fa127c4,
+ 0xde327f72, 0x45397c8e, 0x960c9fef, 0x2476eeff, 0xf0042f87, 0xef918bed,
+ 0x0dffe141, 0x444f9fd4, 0x20faf5fd, 0x2bffa03c, 0xed5076a3, 0x2bed1b5e,
+ 0x7117fa0f, 0x8ff3c8f6, 0x0f4842d8, 0x14ad3be7, 0xfec45477, 0xe44739cc,
+ 0x8b52444e, 0x284de4eb, 0xbdb7836f, 0xf0032bf7, 0xf7c1d29f, 0xec49143b,
+ 0x3320bc87, 0x73e37fbe, 0x294feec6, 0x5f1e59ae, 0x3e47ca09, 0x6e2265ef,
+ 0x48b92cb4, 0x7c32fbe5, 0x62596a5f, 0x53da1177, 0xb43d094f, 0xabef812c,
+ 0xdd4cb80c, 0xac7baeb8, 0xb429f381, 0x67bfc2ff, 0xb1ab31bf, 0x611d2ffb,
+ 0x299dd76e, 0x609b7436, 0x1f681d9e, 0xe06dbae0, 0xfb8330fb, 0x1dcdc7d5,
+ 0x51938266, 0xc455a079, 0x95fdb5eb, 0x571e3ce3, 0xce51f627, 0x10fc59cc,
+ 0x48b5a96e, 0x9fe8d5cd, 0x8d3f585d, 0xde77d7e2, 0x759e9b3f, 0xf771f4eb,
+ 0xde99acc5, 0x5a94fb6b, 0x7996bbbc, 0x8e5edc4d, 0x600d11c6, 0x94eba8bf,
+ 0x7997d42a, 0xe51ab9cc, 0xd5821abf, 0x16cf0c9a, 0x2ed1a278, 0x73b42419,
+ 0x02775694, 0x16daefae, 0x50a9e903, 0xed87c18b, 0xb8e73c34, 0xd2a91c79,
+ 0xb01ae3cd, 0x471c6154, 0x4518b67b, 0xb7f45fdc, 0xf1ba198a, 0x73f89069,
+ 0x1ea953ad, 0xfd6b5f4e, 0x2d9b18b5, 0x648ba718, 0x7dae281b, 0x479be4c1,
+ 0x22e4e371, 0xb67c0216, 0x55d79a38, 0x9de27af3, 0x9f88d60b, 0xb854afea,
+ 0x64d4c921, 0x376e9f94, 0xe3c6538f, 0xbe9b516d, 0xd21fbf1c, 0xeb97d610,
+ 0x464c6058, 0x883fdf01, 0x7376ef7d, 0x7d6175f9, 0xd7b7c09e, 0x9b567284,
+ 0x8e2caaff, 0x7f364337, 0xcd5767e6, 0x77c83a43, 0x203f2899, 0xabe3c5df,
+ 0x3f821330, 0x44b74aff, 0x6f0711f4, 0x486d1a0b, 0xdf7cad5f, 0x1fc2abee,
+ 0xee55f70f, 0x7c1fa134, 0xab67dc1e, 0xdf689a73, 0x24e352f4, 0x72f5bab7,
+ 0xf7fcb068, 0x9fb967f7, 0x3c8b2ad4, 0xa1c9270e, 0xcb9f275a, 0x48fbc919,
+ 0x83b7be37, 0x68f3809d, 0x6ed0cb95, 0x9da37e99, 0xdc74d1e6, 0xc6e0714a,
+ 0xa839bd15, 0x7aaa9bc7, 0x203f308b, 0xad08bf1e, 0x682fc9a2, 0xff06eb57,
+ 0xd884ed03, 0xc547e476, 0x7efa07ef, 0x3f454ee4, 0xe781cce7, 0xb01d5f50,
+ 0x7f82be92, 0x38c66d3d, 0xb23c91cb, 0x023ac6a3, 0x305db02b, 0xa3f77ba1,
+ 0x70b76879, 0xcbb1a9bb, 0x617681dc, 0x3ecc4b6d, 0x06dffe1b, 0x5b1bbefd,
+ 0x77f14c97, 0x5f7faed6, 0xbbee33bf, 0x6d70fb21, 0x4c5bceb4, 0xefc8b181,
+ 0x9f6877a0, 0x81835cfc, 0x64ebb7f6, 0xb79462ef, 0x7b7aace7, 0xaf839cfc,
+ 0x9addcfd7, 0xc22de13d, 0x0f2c1e75, 0x116f6759, 0x819d73ae, 0x69fb6205,
+ 0xf58675c4, 0xf9d6265d, 0x8b9313dc, 0x3fdf9d70, 0xd708b930, 0xcdb18b79,
+ 0xa8f37c87, 0x1b90f033, 0xe99bedfa, 0xf70a7b27, 0x2e8f913d, 0xc40f1e95,
+ 0xff81e3d1, 0xefa47a3d, 0xc787d246, 0xebd0e106, 0xcd49b743, 0x6b507942,
+ 0x5ea17f31, 0xe361bfc4, 0xc5331678, 0xfa7f8e3b, 0x5047c6e1, 0x64c9740e,
+ 0x1dfd688f, 0x68050257, 0xd57f1d0f, 0x23490de3, 0xed18bff7, 0x07da0aad,
+ 0x455c610c, 0x7b3403f3, 0x9f1e5e32, 0xc779f312, 0x7b42abed, 0x8dc6ebfc,
+ 0x4b3bc5eb, 0xe76e43f8, 0x3cbc95ee, 0x7149dc6e, 0x0b63a6e4, 0x7e27189c,
+ 0xc6e3cc27, 0x52944f4d, 0xfc21b8dc, 0x2de6374c, 0x89c92eb1, 0xdec347fe,
+ 0xdb171337, 0xf82e7ea3, 0x5f236fb5, 0x3f7e8b31, 0x99f09de9, 0xc13b3ac4,
+ 0x71ea157d, 0x42623b9b, 0x7f026fba, 0x9ad4f30f, 0xec49c894, 0x28cdc9b7,
+ 0xb0fca31f, 0xf2d3ffde, 0x4df876a2, 0x74777724, 0xd7946149, 0x5e40a669,
+ 0x9635ea16, 0x8b6b3ce5, 0x6ec7d9f2, 0x77f71b9f, 0xbedbfba3, 0xe4c771ff,
+ 0x4f6ef51b, 0x35edfa22, 0xe5139f32, 0x908776d9, 0xb7c90a67, 0xc2ba778f,
+ 0xb788ff3c, 0xedcc38ff, 0xef2d0684, 0x0add6148, 0xb9e2d7ac, 0xbd70d7be,
+ 0xc777de51, 0xb2d8fbc9, 0x14bd2fb6, 0xf6e3d1f7, 0x0ddb63bf, 0xecc7e7ee,
+ 0x61faeb7f, 0xb96aa5cd, 0x5f5bff7e, 0x327ee21f, 0xb2f2c3f0, 0xeb6afd28,
+ 0x936fd1a0, 0xeb074388, 0xf483df4f, 0x392c3c1b, 0xe65bbed1, 0x0cbbf4e5,
+ 0xc4f32dfc, 0x3acefca1, 0x238979f5, 0xaa697ff1, 0xcb07ff9e, 0xeaf8a0ff,
+ 0x9c9aa915, 0xcdaf7ce4, 0x0fdb8b5f, 0xe24bb3ce, 0xaf37197c, 0x3e353f78,
+ 0x99f9aede, 0x6f0f2a97, 0xe387841c, 0x0ffcb063, 0xc6b78796, 0xfda465e1,
+ 0x0f2caf8c, 0x35f797ff, 0x35b63a1e, 0xb40efd11, 0x594fd1e3, 0xf3c8cfb7,
+ 0xb1fd0023, 0x64b3c5fb, 0x9fef8fbb, 0x7ebd5aca, 0x259d5e1f, 0x5f39e1f6,
+ 0x4c84f33f, 0xf628d6eb, 0x398f1b89, 0xdeb4d8bc, 0x69f684be, 0x6f4ff7e3,
+ 0xe1660763, 0xa3efc552, 0x2e7e432e, 0xd4fdf2f8, 0xbcc1d4d6, 0x5bcc3c85,
+ 0xcbd2aca8, 0x1fec67f9, 0xd66204a6, 0x1c04aabd, 0xdbe86182, 0x725884a2,
+ 0xa9adfbcc, 0x467eaedc, 0x4c78f7e4, 0xa5e61d6c, 0x7cd8726c, 0x0c78cfe8,
+ 0x47e8ff3c, 0x28edfe29, 0xc0aa2d17, 0x32ef91eb, 0x21e5e003, 0x95c92763,
+ 0x8bdda350, 0xdf8b5072, 0x2c7ffd68, 0x592ec1f6, 0xfbd1c7ff, 0x7a65ff81,
+ 0x53cfc78f, 0x755f78da, 0xe01b6edf, 0x8c17c746, 0xdc45f8e8, 0x4a1bca5f,
+ 0x33f523bf, 0x9cbf1d12, 0x95217fea, 0x226fa2e4, 0xa25c2be5, 0x4795b19c,
+ 0x889c60ce, 0x18ab341d, 0x0938c4d7, 0x190dc7e9, 0x5bd26f22, 0x80f29b39,
+ 0xbf9895bd, 0xf3fe06f5, 0xc8ed91f2, 0xe1f5c1be, 0x88df6476, 0xecf5f3eb,
+ 0xfe9dbbc8, 0x7d6748b3, 0x6f947cd3, 0xf001d6be, 0x0bf87fa3, 0xd3b4779e,
+ 0xa773e9ca, 0x2d92e9c4, 0x78a4b94f, 0x7471a7cb, 0x91ffe9f5, 0x8da4b51c,
+ 0xbdfe5764, 0x125fe8e5, 0x723a7e31, 0xa79e213f, 0x7843d55b, 0xd8931c8b,
+ 0x76b8989e, 0xe0cff310, 0xaf010cfb, 0xe123fef6, 0xf34c2c37, 0xfbc1a665,
+ 0x58b35ff7, 0x3e981258, 0x362e5ce5, 0xafb4edf9, 0xf3c9d4d0, 0x30569a5f,
+ 0x184de392, 0x78c12d37, 0x98b66ce2, 0x428189e2, 0xfb5b93cc, 0x27243dba,
+ 0x0e7dbc61, 0xffaf3b43, 0xdebe5e35, 0xfec62815, 0x697a2b83, 0xce7da31f,
+ 0x5587947b, 0xf787f9f9, 0xbc139754, 0x9b704f14, 0x6e25e7f5, 0x0efbe34c,
+ 0xa69fd3da, 0xe28fbbad, 0xf3d7eff9, 0xdba0e2bc, 0x84b8c4e7, 0xa9b70f16,
+ 0xd0afb43d, 0x6f1b9074, 0x0f9f3295, 0xd11669fb, 0x69c1d353, 0x653718a5,
+ 0xb452d69d, 0x6cff2b77, 0xfdefbf27, 0x4f2932bb, 0xe04a68e2, 0x51d7846a,
+ 0xed16be1e, 0x07185cd3, 0x0ff7deed, 0x708a5b5c, 0x0b6ff26b, 0xfda1cdc6,
+ 0x1e3e8716, 0xdf3c2cce, 0x51d1e1bb, 0x1abcdc5a, 0xf045b3f1, 0x55b7b321,
+ 0xef861ece, 0x974f7e35, 0xfa7fd40d, 0x3fb42df7, 0x2d83c9ae, 0x14b01646,
+ 0x24c8e544, 0x74183f91, 0xaec5fc8b, 0x453f3cd9, 0xa9e2ed94, 0xf71df3e1,
+ 0xaf3849cc, 0x37ca6949, 0x4a72c7db, 0xac7dd8f6, 0xea0148bf, 0xd0c4f317,
+ 0xa515874f, 0x22ed8b78, 0x9df3a3b7, 0xc723a226, 0xa7f7c63a, 0x9ed08e80,
+ 0x33d222bf, 0x59e6093d, 0x057dded8, 0x45f8f7e2, 0x3293ad03, 0x97da45fb,
+ 0x78f89249, 0x5b7a1b05, 0xc61c60c7, 0xb895caf9, 0xb39b6a94, 0x36f8b70a,
+ 0xa477fcb9, 0x1737df11, 0xff5578e3, 0x9379e461, 0x5f146cc7, 0x4659cf68,
+ 0xaffd9379, 0x3ee7759b, 0xb6219fe2, 0xf324f29a, 0xf691ff0f, 0x25071c07,
+ 0xe7b4de1d, 0xbe76697d, 0x99ea156f, 0x5735b945, 0x2abe49b8, 0x421cfec7,
+ 0x5569437b, 0x16b0f250, 0x4560cfa3, 0x518ab5f9, 0xbb747f3c, 0x95eb80d3,
+ 0x0662f22b, 0x6275ff8e, 0x6d15fc80, 0xf3cc203f, 0xf7bd8c9a, 0xaca61fa0,
+ 0x842abdea, 0x65d071eb, 0xa9b8c268, 0xf144d231, 0x8a366396, 0x2e1ee6af,
+ 0x282dfd58, 0xd273aee7, 0xd1c0d7fe, 0x6f94b9a5, 0x3d1cf30e, 0x4cef3ccc,
+ 0xcd4879e3, 0x63945e82, 0x33ea0336, 0xe2f33365, 0x3e2d79e8, 0x7ef802e7,
+ 0x3a2153b4, 0x0816985f, 0x9e0e7ae3, 0xc09e596f, 0x3c28b7cf, 0xfe58e23e,
+ 0xdcf12ffa, 0xb7116ec8, 0xfc7c713d, 0xb5f38a1c, 0xfde2122a, 0x51e78b82,
+ 0x3fa6963e, 0xf7c51087, 0xcd47ca09, 0xae47f63f, 0xf60da0bf, 0x7d3918af,
+ 0x0eeead28, 0x3bf6278c, 0x7b7f9402, 0x4cb74b65, 0xbece63fb, 0x18d5aa07,
+ 0xd71b66bf, 0xb9fb4d27, 0xc7ef1e1f, 0xf91e997c, 0xe13ca0ed, 0xfcb0647a,
+ 0x7a4fb20f, 0x57c7f4e2, 0xde984ff6, 0x53b78baf, 0x21b8fde2, 0x7f5c7776,
+ 0x5a2bd923, 0x745549be, 0x3b376e1c, 0xa4287b34, 0xb2a9c7cb, 0x166bf38b,
+ 0x260fff7d, 0x22ff793b, 0x8d6d273f, 0x7d414aba, 0xe28c2ff5, 0x90fe5a73,
+ 0xaa142f96, 0x213d79e2, 0xb7ce8583, 0xe51b5879, 0xdd628d09, 0xb4714492,
+ 0xa7df865e, 0x7c10be63, 0xf2d2ffff, 0xcc5dffa9, 0x39264ebb, 0xbf084aa9,
+ 0x524cf315, 0xf6f0ee10, 0x77de38c5, 0x159e34ec, 0xc8524cf3, 0xcdfe209f,
+ 0xd4fcf3f4, 0x7f7cf5e9, 0x30f41321, 0x390b3396, 0x99e75a5d, 0xcb555f28,
+ 0x4cf2d11f, 0x0954bc34, 0x598e677c, 0x5072879c, 0x92d947cb, 0xfb44ade0,
+ 0x7b0255a7, 0x90d3e71a, 0x784bf220, 0xf90dedbf, 0xaff7a461, 0x8f127f9b,
+ 0x650f2d67, 0x3d206272, 0x5e7a22bd, 0xd11fcb4e, 0x3d6626e8, 0xc71dae09,
+ 0x555f3db8, 0x0c79a26f, 0x71475c34, 0x030681c9, 0xd55fbd43, 0x1874e665,
+ 0x798ede37, 0xfd8dd626, 0xe52b612a, 0xf87a0bd7, 0xd6167b32, 0xbee318b7,
+ 0x2fee5627, 0x7fde03e8, 0x3d276576, 0xa752ac07, 0x33ce893c, 0x950947ce,
+ 0x5eb8e9e3, 0x6af31cb9, 0x90123922, 0x0fed84d0, 0x353950d7, 0xa79606f2,
+ 0x51ae5e7a, 0x8c0c4f40, 0xa096ec8e, 0x2ddb7fbd, 0x99b48cbc, 0x7d3dfa09,
+ 0xe4a84d76, 0x363be81b, 0x2aa36f24, 0x37e2953d, 0xbc50f4f7, 0x72bbe848,
+ 0x0cd91f2e, 0xabc79873, 0x9d9b8a54, 0x3b23c8ca, 0x7f9c5ec0, 0xb3eb07b0,
+ 0x836714cc, 0x53ffa27a, 0x7af1a7a3, 0xcb3faf95, 0x0dfcf072, 0xf9421bd6,
+ 0x1a6f2a76, 0x911babc5, 0xb29ec03f, 0x7073023b, 0x3d49cf5d, 0x9c3f2277,
+ 0x25cff99a, 0x0ee7e748, 0xe510b4fd, 0xb02635cf, 0x379187d3, 0xde5c1969,
+ 0xebed180c, 0x65e7e824, 0xd8fbe07b, 0xf9b6abcf, 0x7cd530b3, 0x1334ca5e,
+ 0xa1601d1e, 0xff28c85f, 0xb9fac552, 0xd1fb72e6, 0x612fc335, 0x2b1ae81e,
+ 0xa0352387, 0x099ec8f8, 0x03be95cc, 0x09235ff3, 0x49a986fb, 0x6aa887e4,
+ 0xcb21fa12, 0x5946b9c4, 0xf82cb7f0, 0x7b2b0ffb, 0xd830150a, 0x2cdcef2e,
+ 0xdedfe70f, 0x686fe718, 0x5ce94dcf, 0xd591cf4e, 0x6e1f4809, 0xd7df91e3,
+ 0x26c93ac0, 0xbdf1186f, 0xfb41db26, 0x2a3b4fb7, 0xafd0bd3d, 0xe52ffb94,
+ 0x26bd5798, 0x71ca5ffb, 0xf64e4d9f, 0xe531fc7a, 0xf52ae94d, 0x21db0337,
+ 0xe5cd6cfe, 0xbbfd7f18, 0xfd0497f5, 0xfefd7c95, 0x7331fb06, 0x225996b8,
+ 0xddf00a39, 0x03c0d6cd, 0x16177eb8, 0xb3fb49bc, 0x7a9e6677, 0x4e2bf303,
+ 0x88cf9919, 0x9c432472, 0x8ebd033f, 0x75cc9ee3, 0xce53f3f1, 0xb113d36d,
+ 0xf2e9c05c, 0x7da6165a, 0xfcb99af5, 0xacf5e3bc, 0xda17a5a7, 0xaa31e35d,
+ 0x71fc31bd, 0x5f2faaad, 0xd72fac5f, 0x7f8e3c88, 0xdfdfeaf2, 0xd20a22c0,
+ 0x7ca7b7e9, 0xfdf62636, 0x2fdf5653, 0x929e8f90, 0xe867de78, 0xfb24e672,
+ 0xd0852dd9, 0x64ff199e, 0xc9ff38a6, 0x55ff13f3, 0x4e4f5ff8, 0xb69f5461,
+ 0x82c7b2df, 0x2d9e22f5, 0x1ef1fa8b, 0x264dc966, 0x30fa49b9, 0x473c8922,
+ 0xb0f1ed37, 0x793bb743, 0x9ada175c, 0x0b439fa0, 0x9a4bc254, 0x42aec0dd,
+ 0x10b72bfe, 0xbe7469ff, 0x0af40ac6, 0x651ca978, 0x5dfa4049, 0xc36ef463,
+ 0xb304e4be, 0x5a6ffa8a, 0x96fa85a2, 0xfe90a67f, 0x33356558, 0xdc4f9427,
+ 0x68654097, 0x44e07247, 0x718c2985, 0xee4235ee, 0x481bf7cb, 0xcc2a567f,
+ 0xd01b798f, 0x9fdf1bae, 0x3b50b0c8, 0x7c5cd298, 0xf1a8ca7f, 0xf28534d5,
+ 0x1aec0538, 0xf488c13f, 0x57e0ab7e, 0xb3cdf059, 0xfb8d0700, 0x7141dc82,
+ 0x05bd5530, 0x632de7cb, 0x70511ce8, 0x629b9cf0, 0x9d8ac1c0, 0xf8bbdf82,
+ 0x3f8d3339, 0xd2017935, 0x28b710ad, 0x6d0e3125, 0x3ea1a7af, 0x6b5f6466,
+ 0x07edaafc, 0x76b45b66, 0xcffb0f8a, 0x3cd9df10, 0xdcb84279, 0x47fca668,
+ 0x7aea5ef1, 0x1fa413ee, 0xaf77af8d, 0x3d7c40bd, 0x3fc5df14, 0x0e75f2a6,
+ 0x98f7c727, 0x391fe42c, 0xea164c61, 0xaf2e359f, 0x17298fea, 0x4bcff903,
+ 0x3b407c46, 0x7d58df28, 0x918950aa, 0xe70f36f3, 0x4be76857, 0xb09f7c01,
+ 0x67c859aa, 0xc8db8cc3, 0x7dfdb5c7, 0xb8c0f5c7, 0x0384eed0, 0x7b7685c6,
+ 0x436ee6ad, 0x4fe370e2, 0x2fbc7151, 0x6eb1971b, 0x04eb9e22, 0x420e815e,
+ 0xe13a3718, 0x5e3d1030, 0x4f7bf227, 0x58f1f2a4, 0xa65f3eb1, 0x40d0e810,
+ 0xfcfa58f9, 0x9da46b98, 0xb6efa82d, 0x20f7135a, 0xe8273ddd, 0x67eda4e2,
+ 0x3cef6885, 0x59e8bf37, 0x92b3eb94, 0x9120b556, 0x893ac75c, 0x757935ef,
+ 0x4acde321, 0x1adc832c, 0xbff581e7, 0x7cd4ff33, 0xd759fcec, 0x5fd442d6,
+ 0x7bc60f20, 0xafc28752, 0x37069fd1, 0xfbd221d2, 0xc1c61d20, 0xbb11d1af,
+ 0x0b1293a1, 0x88bd8177, 0x047ecd4f, 0x91e7884f, 0xf9d1d9ab, 0xb2cf1101,
+ 0x3479f334, 0x6bee0884, 0x9e500f5c, 0x0199e5d9, 0x69d6079f, 0x720fa4de,
+ 0x59ec6c14, 0x76e30630, 0xffb4ef00, 0xede3784b, 0xa7cb2fe5, 0xb58f891e,
+ 0xfb39a5f1, 0x383a9f29, 0xd5f94ed7, 0x693e45d3, 0x7140deb0, 0xc8abf074,
+ 0x96626f1e, 0xa9ddca30, 0xf2d5bec2, 0x3c4a8ffc, 0xc27a193e, 0xb18beeac,
+ 0x59e68793, 0x1dc794ab, 0xb1f3c15a, 0x46e0ed07, 0x9060ec95, 0x0573badb,
+ 0x765ca5ed, 0xd2aedfb7, 0x24a79979, 0x80b43ede, 0x7db3dc51, 0xe45fa8b6,
+ 0x58f76b0c, 0x7cd16948, 0x460ef6f7, 0xc8eedff4, 0x594cfaa7, 0x16fdcb9c,
+ 0x79ed37d7, 0xbf6c4fdc, 0xb7ea88b9, 0x52c78424, 0x87d88f5e, 0xf5fb81df,
+ 0x7f1fb05f, 0xe3f3479f, 0xb0751c78, 0xa38a77fc, 0xb40cea3e, 0x2a2dfd21,
+ 0x8118e5f1, 0x3c4cea5e, 0xbaf40a9e, 0x7a6187b3, 0xfa21735f, 0xe6b2d73b,
+ 0x44050c57, 0x2e905baf, 0x7a078de7, 0xebd1d02d, 0x97054f56, 0x469708db,
+ 0x5a7483af, 0x17379f1c, 0x76fb6308, 0x9b9fe757, 0x32e83fd0, 0x30de797b,
+ 0x978c83cf, 0x2cf0310f, 0x6e3c3854, 0xf6782659, 0xc1c4ff13, 0x137c2973,
+ 0x8ce9a74b, 0xfc48c7f3, 0x90b0ae93, 0x3fca2ca3, 0x4f03594f, 0x7c83b8e2,
+ 0x0bf70f74, 0xdb2dc087, 0xba6e9e89, 0x0517ef99, 0xe3ef5c6d, 0x8c0651be,
+ 0x7f8c5b3f, 0x867fab53, 0x96cddb0b, 0xe1ba1e38, 0x1cff007f, 0xabbb3f51,
+ 0xe6c6f291, 0x8e9e30cc, 0x793473b5, 0xcd53eda9, 0x746fed13, 0x1e6236ce,
+ 0xfd1adcf7, 0x5bbcd0fe, 0x4dd4fef8, 0xccfdf573, 0xa03e1b63, 0x6cd646fc,
+ 0xbbcdfc44, 0x8aff5f45, 0x695f7067, 0x3d2bee0c, 0x0329e22b, 0x47c827c0,
+ 0xb25d4dbf, 0xf3a076f3, 0x292f3f31, 0xcccf38c3, 0x9bbd86b4, 0x8ee8fca1,
+ 0x6dfe5471, 0x747ff7da, 0x1777eb0a, 0x41867951, 0x90c7e7e2, 0x8acf810f,
+ 0x2ebe6f2b, 0x89f5112f, 0x4676f7e8, 0x81093def, 0xced0d9f6, 0xf29f3133,
+ 0xf888673e, 0x5e22c0c0, 0x0724fd7f, 0x55bded4f, 0x8ceaf8a5, 0xe47cc884,
+ 0xff4b1783, 0x90f30cb3, 0x728be467, 0xb0e353d9, 0xc1f4acfc, 0xfd67d47c,
+ 0xd705768d, 0xc79329a1, 0x4b17c7a5, 0xe22763dd, 0x7fd12c79, 0x4d579f23,
+ 0x91322fd9, 0xf154664f, 0xa77bc67e, 0x3b6016b5, 0xf72a79c3, 0x11125a67,
+ 0x19bf1aff, 0xd9a41f84, 0x27217e8d, 0xd9bdf49e, 0xfafd0292, 0xa717922d,
+ 0x26f29fe8, 0x9d9817c5, 0xfbf3a79f, 0x6b8c14f2, 0x3cf1f74f, 0xd8ab6dd5,
+ 0xb6f3b42a, 0xd653e95d, 0x0b74fd40, 0x7a04f5a3, 0xbd206537, 0x2720fe4f,
+ 0xaecc8911, 0x9e8d77a7, 0x3e746b66, 0xc0cf4f43, 0xfefc76a7, 0x8eb5e4cb,
+ 0x7a51ad9e, 0x09ce291e, 0xa0646570, 0x5e96f85c, 0x138e0d8f, 0xe3f18fc7,
+ 0xf027248e, 0x46de562f, 0xbe24ebe1, 0xbfecc2cb, 0x36cbe402, 0xe1c72f8d,
+ 0x1e864cfc, 0x2b943f3a, 0x01d1c779, 0x0b5e29dc, 0xfe38b9e9, 0xc6cbe0d4,
+ 0x50d972d8, 0xd14ff0b8, 0xe7fe50ec, 0x9643f8c6, 0x7cef87a8, 0x170a392c,
+ 0xf1153f8c, 0xf0e1eec0, 0xb99a92ec, 0x867e115c, 0xd268b716, 0x3f587be6,
+ 0x7e04cadf, 0x7183df8e, 0x285bda26, 0xf708371d, 0x3683ac25, 0xdfd0a09f,
+ 0x877e2d73, 0x1df6e609, 0xcfd11d57, 0xba834177, 0x811d5d70, 0x279c236f,
+ 0xe863a10c, 0x3e622d8f, 0xfa065fda, 0x445467f0, 0x37834bd7, 0x234d4f1e,
+ 0xf9f8d1c8, 0xba27e3c4, 0xf8193d6e, 0x0de7ced4, 0xe712f7ce, 0xb89f6f19,
+ 0x5f78fa4d, 0x25cb88b2, 0xc570e347, 0x12c35f58, 0xf38714bc, 0xd5bfe44a,
+ 0x7281bd80, 0x519aa6b9, 0x6ed9243c, 0x669c38a0, 0x27c48c77, 0x48c55f57,
+ 0x632cd54e, 0x9f205ce2, 0xa63d3c5f, 0x931fdeb3, 0xb7516bff, 0xaf7e442f,
+ 0xf0f2ebb7, 0x6e3cec6b, 0x1b935ebf, 0xf502b7ac, 0x887960fc, 0x40adef9e,
+ 0xff7f13b9, 0x1e45cd57, 0x28be4e2f, 0xfbc6b3d1, 0xf9ea0566, 0x0adeeae4,
+ 0x240f5f94, 0x75c5eef9, 0xe3c0c37d, 0xdcf8f1ea, 0xe2d0619a, 0xa74497c5,
+ 0x78347cf1, 0xd811dace, 0xf168e381, 0x0f5273a4, 0x38a64f8f, 0x3c81ff45,
+ 0x4ba067a4, 0x20669a23, 0x1cff3f27, 0x37fc519d, 0xf726ede0, 0x7b9c9aed,
+ 0x18dce498, 0x5cfdd7a1, 0xbe9cf89e, 0x4e1c19bd, 0x021dcbc2, 0x9e85332f,
+ 0x2653bf3d, 0xaf86643f, 0xa16e2b78, 0xb2379f04, 0x8fb1f130, 0x8f76a3f4,
+ 0xa83079d7, 0x63fdb1ba, 0x4bb7d20e, 0xfda3a85e, 0x0cdb31a5, 0x97d18d4c,
+ 0xba09c363, 0xefc641fb, 0x2795d64f, 0xdaea6674, 0xaf9c3a4f, 0x1eed2fab,
+ 0xecbfaba7, 0xb95d32f9, 0xaeaa67a2, 0xab57e4fd, 0x7bcbe574, 0x7fb5d3af,
+ 0xe03df504, 0xccef5bf5, 0xefffbdd1, 0xc79eb31d, 0x232bdcfd, 0x7f7dd3df,
+ 0x5819c446, 0x0c53d7c8, 0xd1a85ff3, 0xdd5ac5ef, 0x74d660f7, 0x0728954b,
+ 0x0dc2dff8, 0x1a7d4f3c, 0xbfb62c60, 0x7b7a6d45, 0x508b2662, 0x58535f7e,
+ 0xcc3376f2, 0x37d7d353, 0xbc20ee1c, 0x013dd97e, 0x0c0bdc63, 0x197d0f48,
+ 0x858c6760, 0x14b0a47f, 0x891bb3cc, 0xfd6cbfff, 0xd7e1588b, 0x47b37f5a,
+ 0x5556febf, 0x62b6febf, 0xbc3bfafd, 0x9a4ff5fa, 0x977f5fa2, 0x29febf4f,
+ 0x4ff5fad5, 0x3fd7ebf5, 0xfd7e9e7d, 0xf5fa0233, 0x5faf551f, 0xfd66ecf7,
+ 0xd72ee77a, 0xe85e6baf, 0x36fdfd36, 0xd1a07471, 0x0b4f2693, 0x7711ddd6,
+ 0x19818e1f, 0xa342e862, 0x7afe85b3, 0xdd1a5fca, 0x78dd13f6, 0x8631f4f1,
+ 0x6fcbbc89, 0x99851f48, 0x7f981740, 0x3f92cc99, 0x1bef3d27, 0xd43a999d,
+ 0x56e4d0be, 0xf58f3eac, 0x6792478f, 0xf094f443, 0x53d44797, 0xa35b2fe8,
+ 0x7448f2fe, 0xfd031afa, 0xa06f834a, 0x4ecdd838, 0x0489c70e, 0x887fb76e,
+ 0x3b439755, 0xe0053368, 0x03e70d7d, 0x3096bfe3, 0xdf1de29e, 0x1c469d63,
+ 0x43d616f7, 0x422cf9cf, 0xea7300cf, 0x642c7dce, 0x7f88937e, 0x8159975c,
+ 0x4ade9171, 0x1617a394, 0xf6837a9c, 0xb94c5eb3, 0x4e327ba4, 0x68c97ee3,
+ 0xb90acec6, 0x26fb87d1, 0x8ab7ee50, 0xa98fa078, 0x9e7c18ee, 0xdacbf115,
+ 0x57e912e9, 0x7e502726, 0x2577ed57, 0xffb54fd2, 0x99759fc3, 0xff1eae3c,
+ 0xc35cb35c, 0x0bb09b6b, 0x5f707db8, 0xbbf54aa6, 0xb276aa60, 0x944ebd43,
+ 0xdf1fd0ff, 0x44d878c7, 0xc2c7b9fe, 0xa29504e1, 0xe3a64c5c, 0xb8eeb474,
+ 0xcbee78fe, 0x4df0e163, 0x22e59850, 0x02cf1fbc, 0x95de1764, 0xdffd4f99,
+ 0xe38880ab, 0xfec38ffd, 0x15684a3d, 0xc07fd1c5, 0x5bf471f4, 0xa38a259a,
+ 0x85e000ff, 0xf5e9c7a7, 0xcad61ea0, 0x33bc05ab, 0x4fbc1db0, 0x184b34f7,
+ 0xfdbafaff, 0x78c3f60d, 0x7887f83f, 0x59a1e2d7, 0x58668740, 0x603fbdd7,
+ 0x8f8bcf14, 0x41928e8b, 0x93fe63a2, 0xf7ab9f91, 0x9fb8db28, 0xd4ebd27a,
+ 0xd1987dc5, 0xbf20e785, 0xbcc2decc, 0xe731b3e5, 0x87bd600c, 0xe9747fbd,
+ 0xbf2fbe28, 0x31676566, 0x4fd88dd1, 0x7ee57bbc, 0x978acb2a, 0x3ef10af2,
+ 0xf7cc572a, 0xc7d43726, 0x8762bbf0, 0x90e463ef, 0xcba7eed1, 0xd959ee57,
+ 0x4678fb43, 0xdad66f71, 0x819c3bac, 0x2fc77898, 0x631d8533, 0x1a673109,
+ 0xfc37a613, 0xe19d33bd, 0xe54ecafa, 0xcb5fac6c, 0x886c979e, 0xcf4146b7,
+ 0xd7ba092f, 0x607b36e0, 0x5eb818bc, 0xe8def412, 0x3ce131ec, 0xe8b5825e,
+ 0xd2b4b8c1, 0xd3fba6e3, 0x1c93716e, 0x83ac41ba, 0x8dd4a0f9, 0x0acc4ae7,
+ 0x5ec5f99e, 0x832fda7a, 0x64bcf726, 0x76efb864, 0x2435c54f, 0xcdc94d4f,
+ 0x8fa06ede, 0xc8b4be1f, 0xaf061819, 0x51ecd3da, 0xc5cac42e, 0x5f8532e7,
+ 0xc64d993e, 0x1e061975, 0x743f93d2, 0x587e6ff2, 0x7e58f3c1, 0xf94603f8,
+ 0xfc396ced, 0x94f14655, 0xf724bcca, 0x2f422c5c, 0x0604ac37, 0xe8f6031c,
+ 0x980b0b4a, 0x66b21f41, 0x98d2d3b2, 0x4369e88f, 0x3ade8be9, 0xf65ecef8,
+ 0xcff462bb, 0xaff8abef, 0x2a3b2c66, 0xf2c7af5f, 0x758fb1fa, 0x1d9a0e62,
+ 0xde537161, 0xe0af1850, 0xaff7184c, 0x3b6357fb, 0x1f798f7c, 0xe01ef0d5,
+ 0x574277b9, 0x26dbdb04, 0xeb077d1e, 0x96ddec13, 0xe12ef802, 0x0055e616,
+ 0xf2dea95f, 0x74f00569, 0xb02f4395, 0xbdf136d4, 0x37ef0a6d, 0xdd26bf7e,
+ 0x43df87be, 0xfb130573, 0x045efca2, 0xd5233f6d, 0x0aada7be, 0xbea156e5,
+ 0x8f8141fe, 0xcfe3fb14, 0x303d63e7, 0xad1668dc, 0xbbd4407f, 0x54f78fec,
+ 0xdd165cf1, 0xff459bf7, 0x97037649, 0xfb132a57, 0x937ebcb6, 0xf56ab7a8,
+ 0x65f6261e, 0xa8ab7d79, 0xde79db37, 0xeeb7b012, 0xfc62b5fb, 0x2c0c5bb4,
+ 0xeecf4310, 0x102c09b9, 0x35c91f43, 0xd1b2bac9, 0x3b25cfce, 0xbeea6467,
+ 0x5bbdfad3, 0x45789b8c, 0x4b3beebe, 0xfb7d38e1, 0xcfa4c9b9, 0x367810ee,
+ 0xeae99565, 0xacfef3b5, 0xf273b45d, 0xaa7b8a76, 0xaaf3dfae, 0xe072849a,
+ 0xdd1ae5ec, 0xb7482d7a, 0xd3f23877, 0xbc21bf71, 0xa3353a12, 0xa788b13c,
+ 0x683d3c53, 0xa553c05c, 0x7b889e72, 0x853959ae, 0x6e807bca, 0x95a1feb1,
+ 0x82ef2a5e, 0x9fcf0ab2, 0xbc2a3f43, 0x60fd0edf, 0x83f42b79, 0x1fa107cf,
+ 0xe3003e7c, 0xf866fd61, 0xa09bcb0e, 0xb7df2c3f, 0x7be547d2, 0xb9535657,
+ 0xca9fa575, 0xa3ce576b, 0x032bdde7, 0xb2b35cf4, 0x8e67ea9e, 0x6bedfae2,
+ 0xb39405e7, 0x9980bcf8, 0xe7a22aa3, 0x80bcb43a, 0xfef0d30e, 0xb8a3cddc,
+ 0xfe65cc1c, 0xfe9c2da7, 0xecc89ee9, 0xa34f9d0d, 0xe7e29bdf, 0xa1b191eb,
+ 0xd55dea99, 0x3bed1c7c, 0xacb10ee6, 0x158c7e4a, 0xea4bf5db, 0x1997ca6a,
+ 0xcceae3cb, 0x256a6213, 0xfe974ebf, 0x13e90894, 0x5f2f58a5, 0xdfc3ccf3,
+ 0xe3101d53, 0x3ecd85c8, 0x8a658e9c, 0xc4f31bbf, 0x9d00deed, 0x08bdcfef,
+ 0x9b1f839d, 0xa62af174, 0xaee2e982, 0xc9d1dbd1, 0x7674ca33, 0x89b17caa,
+ 0xbeb259da, 0x72676ba7, 0xd5daead7, 0xc7bbcd2e, 0xc518f883, 0xb0de61e7,
+ 0xb8c0658a, 0xd337da8b, 0xbac5ebb8, 0xbdf97cc1, 0x3e2407d6, 0x3dbf615f,
+ 0xb5f314ea, 0x3ab9206c, 0x458bc5c6, 0xca032149, 0x9d7ff7c3, 0xc8fafc44,
+ 0x478a0643, 0x0361658e, 0x5078d7ae, 0x813f58d3, 0x127952f5, 0x9728574a,
+ 0xf2c65532, 0x7e422c65, 0xab6fd82e, 0xe49b9d71, 0x285643c0, 0x3c0ecb9f,
+ 0xba91f3ca, 0x8914af49, 0xecd228f5, 0x7c4a6dd8, 0x28dd6f7c, 0xe7f58ff2,
+ 0x9bf7e295, 0xd32a3957, 0x1fe8fed1, 0xe6cc7f21, 0x42dcf339, 0xe32dbfc0,
+ 0xef6a7a4d, 0xc30d55ef, 0x787de39e, 0xf2cdf494, 0xfbfac33e, 0x1fde81b8,
+ 0x2b9c79c6, 0x5e6603f9, 0x08c2a6b1, 0x8c6b09f9, 0x93509c9a, 0xecb63d98,
+ 0xf331624d, 0xabe56478, 0xec090a05, 0x764de100, 0xe7cc746a, 0xea527f2b,
+ 0x22a63cc4, 0x7fb93791, 0x8ce14665, 0x7befd1d1, 0xb3141d04, 0xc5ff924e,
+ 0xfc97836e, 0xe7539f48, 0xdb0b5a77, 0x445e787c, 0x98bcc71e, 0xb5963363,
+ 0xf96b39d1, 0x23c9326f, 0x4cb5c4f9, 0xc123bb05, 0x7b216619, 0xfc265fb4,
+ 0xf9091fd7, 0x067d91f9, 0x68e72fc1, 0xc8f9e1f7, 0xe9c8f9de, 0xd49e6275,
+ 0xfa46ed47, 0xafad3e48, 0x5f7a762f, 0x2e9d000d, 0x22f3683e, 0x6dc50978,
+ 0xbca03f74, 0x1259625b, 0x20f3c1c1, 0x6cbdb993, 0x42c956dc, 0x1b579eb0,
+ 0xbf098702, 0x8321eabd, 0x5da1fca6, 0xee898a63, 0x78831f67, 0x6e5e23b1,
+ 0x43819c2e, 0x1e131617, 0xbf798917, 0x26b1e625, 0x80bfc35b, 0x787cf987,
+ 0x76e2e09f, 0xcfd6efcd, 0xaa92def3, 0x4b7d636f, 0xa0f94c8f, 0x973cf8f1,
+ 0x44c4a7f8, 0xf1daf058, 0x70046e3c, 0xa0fc85be, 0x8829dc20, 0xb69fbe5f,
+ 0xe30a69c4, 0xa97ee039, 0x30f29ab3, 0x7f281827, 0xdf2e9e35, 0xf368f617,
+ 0x6d3d2728, 0xcf44b39e, 0x73df72d1, 0x7fc8530b, 0xaed67ae0, 0x9f16bcf0,
+ 0xf78d8d4f, 0x28e2d7ad, 0x413f5f22, 0xdf783bc0, 0x479e38d8, 0xdb3d6768,
+ 0x24664f30, 0x9590c6bf, 0xc0d7e717, 0x54fd20d2, 0x651f2858, 0xa4e796bd,
+ 0x8f29529e, 0xe7989e1b, 0xba741164, 0xb9efc1d6, 0x3a37e6d0, 0xd1d1cb8b,
+ 0x06ff9c59, 0x86de5a2c, 0x2634a6af, 0xabb6bfff, 0x6d75fc8e, 0xc4406a3f,
+ 0xf4120649, 0x820d47fb, 0x6d9e0614, 0x7dc04aab, 0x1fbe3690, 0x3d75d0d5,
+ 0xd8f2efbf, 0x285f7403, 0x3d22a9f4, 0x75f689d4, 0xfafef4eb, 0xe201fda2,
+ 0x4078f8d7, 0x980fffbc, 0x1e5da133, 0x67e7ffef, 0xcbdf7f09, 0xe9bf714a,
+ 0x938286cc, 0x29b70009, 0xd1b9d18f, 0x74e3f251, 0xa5583bef, 0x26cf786d,
+ 0xcaf7e12b, 0x0fffafc4, 0x97844db2, 0xdf5f12fd, 0xf13b68d0, 0x2e0afec1,
+ 0x7d3ff607, 0x28d186fe, 0x7d2572cf, 0x91ae713e, 0x818b77df, 0xc9df787e,
+ 0xf970f558, 0x0cb23362, 0x5fcf4cdf, 0x8d7b97a1, 0xda4f7b87, 0xd37f9254,
+ 0x4f3d70b3, 0x84b125fe, 0xf74228f8, 0x83b9a3e6, 0x78dc21e3, 0xe180e36e,
+ 0xf4b1f983, 0x452cddf0, 0x66f86dc0, 0x1e8678f2, 0xaf2573ae, 0xe1c75da4,
+ 0xf50b29ba, 0xb4e9f763, 0x0d7c7cd8, 0xc35503ae, 0xf86e2b9f, 0x029a78a6,
+ 0x8b0e54f0, 0xc22ffaa7, 0xf0d301d3, 0xc04cfcf0, 0xf2cf6ff3, 0xd6862efb,
+ 0x6dfb437f, 0x1efe1c67, 0xc509b9eb, 0x33fbc036, 0x2fa79fc2, 0x04c2f68d,
+ 0x05cb3afe, 0xf90b967d, 0x895f25e3, 0x4c9f5f05, 0x0a9d64f9, 0x72c1a94b,
+ 0x2aef42e5, 0x4a7f7a35, 0xfca010d0, 0x79baf67c, 0x4477f958, 0x990385c8,
+ 0x3878b0d2, 0xf4f9e628, 0xa8b9b58b, 0xd57dee67, 0xb42e50cc, 0x5efdfb08,
+ 0xef05a767, 0x88f0d59f, 0x067832e5, 0x5ec5914d, 0x647f972c, 0x8cc3ed51,
+ 0x6de3e067, 0x6d1be38a, 0xabf9ed3c, 0x0fae62ac, 0xcc6567a5, 0xc574dfdb,
+ 0xd42f742b, 0x648572a6, 0x7fc6d7ef, 0xce5e9ebb, 0x7692bf75, 0x5f97a703,
+ 0x4934bd21, 0x1b7e256f, 0xf22941ca, 0xcbee0972, 0xff34029b, 0x43b1e020,
+ 0xeda78a1a, 0xf9b45e82, 0xe0d7f369, 0x90b95c76, 0x9af1c1d6, 0x41c69499,
+ 0x17d35ed1, 0xe1ff4249, 0x5c5f48bc, 0x0f73f0a1, 0xfbad0a15, 0xe95329a6,
+ 0xb101ca5c, 0xdcb91e2f, 0xf83dec34, 0xf76f027d, 0x0f63fc5e, 0x2ea1b5fa,
+ 0xc00bdd23, 0x8dcf5e94, 0x4bf12f78, 0x0c33dd0a, 0xf78d54f4, 0xe2fd3d1c,
+ 0xf3b444f9, 0xf2e2ccde, 0x2e2ccdec, 0xca2e070f, 0xe45e74d5, 0x729c8fc5,
+ 0xce9ffd0c, 0x4d3ec592, 0x039e0f4f, 0xf3c658d9, 0x1ec2eddf, 0x57d8bfb0,
+ 0xa7dbf08f, 0xc52cc4fc, 0xb21fdbd0, 0x46d704cc, 0x0bcd2453, 0xc98f05fd,
+ 0x82ec9bac, 0x6dafba5e, 0x939b9cf0, 0xfca9a1e3, 0x8ef68659, 0xe3df8bbd,
+ 0xe54b3a76, 0x3ee01672, 0xc613ef04, 0xc3ace47e, 0x2f1872fa, 0xc3bdfa3f,
+ 0xa133d7c9, 0xb2a3df82, 0x383f8ae9, 0x24b89ef1, 0xc7fdd189, 0xea36c83f,
+ 0x57ada1ce, 0x2cec1cb9, 0x3b41e9ef, 0x2854e42e, 0xfbb3a72f, 0xfbda0b0e,
+ 0xf2f85f1a, 0x8ad7bcf8, 0x4ed77cfb, 0x39e30e29, 0xd78e8d14, 0x202e0764,
+ 0xbe046edf, 0xafec9c78, 0xc274ff1e, 0xf314b38f, 0x1eb0275c, 0x9586afba,
+ 0x87c89c9b, 0x8e8306c5, 0xe6c9aedf, 0x413da374, 0xf3dd93fd, 0x9abb4163,
+ 0x2c3b97de, 0x7db5cf0c, 0x1276717c, 0xb672a7da, 0x9d79ef66, 0xed8fc788,
+ 0x7c4ec973, 0x0df6b7fb, 0xda0779b1, 0x73f02df3, 0xcb44c7bb, 0x59febc8b,
+ 0x0b317ed8, 0xe97683dc, 0x775976e2, 0xc16dffde, 0xda2e8be7, 0x9d8c7758,
+ 0xf7ca68bf, 0xa2d2bce8, 0xfef4898b, 0xf49f916d, 0x2a4bc8b6, 0x8af0f314,
+ 0xdfd915e7, 0xc6f7fed0, 0xff5dcbc9, 0x972d48f9, 0xd0d98597, 0x6bd4a36f,
+ 0xe36a7f42, 0xb9d0bfd4, 0x7fc0b791, 0xd17f36ef, 0x7758533c, 0xed83b8cc,
+ 0x77595a2e, 0xa8baec4a, 0xbe747704, 0x6b7faa76, 0xf04be7a5, 0xc7874a38,
+ 0x3a05ff68, 0xbfed0e3c, 0x5adfea88, 0xfd25fc59, 0xffa11f8f, 0xd1fc1d3c,
+ 0x7de90b7e, 0x47da89ff, 0x272fc06d, 0x78ef57ba, 0x8eebf30a, 0x7cfee99b,
+ 0x8ab3b876, 0x92fdafce, 0x3bc6b9d1, 0x06f27f8f, 0xb9ddcde6, 0x31c5e4c7,
+ 0xf9918c06, 0x43f461de, 0xf0867321, 0x79ed291e, 0xcd017643, 0x45bdfe27,
+ 0x0f313b09, 0x38ac52ce, 0x58593f51, 0xf135784f, 0x93e48583, 0xfad79716,
+ 0x2672871d, 0xf76a3e46, 0xf62bbc85, 0x0b60ff8d, 0xc0aecc2c, 0x8157f732,
+ 0x9c623773, 0xd961e1ad, 0x7421efc9, 0xc5a23f91, 0xf3f415bb, 0xe3d4300a,
+ 0xe3fe7867, 0x4b03723f, 0x0e7e6e91, 0xdfe300e2, 0x01bd84f2, 0xff0a4f8a,
+ 0x8f6b3eef, 0xf7231bc7, 0xdf2b6456, 0x8b6fdf4c, 0x7f1537d3, 0xeb9ba47a,
+ 0x8f38159b, 0x57e7b946, 0x8e7879b5, 0x1bdc57a9, 0x5bdd92a5, 0xee927e5b,
+ 0xfcd5ab97, 0xfbf175f9, 0xb42ed9ec, 0x7cf8b583, 0xa13fe622, 0xf3c8dfbe,
+ 0xbc6cebef, 0x14fbf75c, 0x4789cf3a, 0xef104a45, 0xdf97b29d, 0xfc24e82b,
+ 0x0f30179e, 0x20e63658, 0x9e04077e, 0x433d77cf, 0x5f9e18f7, 0xa0e89a37,
+ 0xa53f37ee, 0x640ec97b, 0x63acfc8a, 0x7543d20e, 0xde256f66, 0x93207793,
+ 0x4a9d9bdb, 0x8c596277, 0xab36b9fd, 0xfbebe48a, 0xd01b46eb, 0xbaf0d73e,
+ 0x8d85c853, 0x89503c5a, 0x6dfde254, 0xbf7797ef, 0xa0f07a4c, 0xc6e77e95,
+ 0x4a93e870, 0xa3714fba, 0xafa5ee99, 0xcb76343a, 0x2c6fa83c, 0xa8be5032,
+ 0xe09590e1, 0xdf9eb739, 0xa2df84ef, 0x343c6ebe, 0xa80f7e8a, 0xbca116ce,
+ 0x6f04c6ae, 0xd497ee11, 0xdd16fa1d, 0xbee67f27, 0x372839b1, 0x39aaa74f,
+ 0x7dee7f74, 0xf7987480, 0xf86363e9, 0x74c9d6fb, 0xd1b1d25e, 0xae2e1816,
+ 0xf893e9a1, 0x640ea3fb, 0x461ff696, 0x78b58cfc, 0x917940f7, 0xb8b03f76,
+ 0xf9eeac0f, 0xf3151cc8, 0x557f85ac, 0x33ef7f67, 0xfdadf7ba, 0x3d385bcd,
+ 0xcd027df3, 0xb71f8b3f, 0x039de84e, 0xfc7cc8a6, 0x35baa67d, 0x9e26ff02,
+ 0x28675687, 0xd327dfa5, 0xee31bff0, 0x0457d57e, 0x99e7b5de, 0xb7ba1517,
+ 0x1c81ec0e, 0x733a57dc, 0x76f44cdc, 0x3a78e366, 0x578dad2f, 0x0271b807,
+ 0x564e9e9f, 0xfefae227, 0xbaafc859, 0xd4efdc35, 0x3619d7de, 0x477ae357,
+ 0x6f94c98e, 0x248ce033, 0xd6887ee2, 0xce0f2b4e, 0xdfa64ba7, 0xf9903a19,
+ 0xd03bad34, 0x32ba4315, 0xfa41c6fc, 0xfe1bf836, 0x97ef457b, 0xf50d90b3,
+ 0xf266abf4, 0x331c4ed3, 0xf03c1d93, 0x3b773f1a, 0x7b2f1ee4, 0xadef0724,
+ 0x1466fe0c, 0xec81b5c9, 0x376e6ec8, 0xb8dee95b, 0xc9815381, 0x432cff62,
+ 0x81978bdc, 0x6385daf6, 0xd7b46ed6, 0x20fb49e0, 0x43d7b621, 0xe8db8fef,
+ 0xd2780ffe, 0x1d260939, 0x9cefd0f4, 0x7df136b0, 0x677f7d0f, 0xca0c604e,
+ 0xa00b3be9, 0xdf7e3b7f, 0xe42eed47, 0x19612607, 0x78c532fe, 0x766fd499,
+ 0x4bde9720, 0xeff8791f, 0xfa89b47b, 0x9a0faa1e, 0x1e699303, 0x8eb0767f,
+ 0x4df9e661, 0x2f7b7fef, 0x9be4853b, 0x99e03706, 0xbc78bfec, 0xe20c7278,
+ 0x3e385df7, 0x7072e9e2, 0x3e04bf3d, 0x5f90a78c, 0x71d7c5d2, 0x971358fd,
+ 0xc9e3ad27, 0x431ba5ce, 0x569af262, 0xe89b7b1d, 0xdbe8c072, 0x72297a8a,
+ 0xbdf8c8ca, 0x6019606a, 0x6f0a619c, 0xfce36757, 0x9ef1c1a4, 0x686e6fc8,
+ 0xef4f79e5, 0x9cede2fd, 0x273c7605, 0x9ceeb6fb, 0x83f716ac, 0xae31124e,
+ 0x89aaf762, 0xdedc25b5, 0xfe2e0996, 0x8d1b4dfb, 0x554efd2a, 0x14b1bee8,
+ 0x5263384f, 0x8ebdd10f, 0x901827eb, 0x5cbd5a9e, 0xf8da84f6, 0x9afbb4bc,
+ 0xe2977bb4, 0x9cddf2f1, 0x38bbfe02, 0xde2b702c, 0xa99a7dd9, 0x8db36269,
+ 0xc7ab9fee, 0xebca017f, 0x2b3e0d0b, 0xbd25bfcf, 0x379ef430, 0x8efc97d3,
+ 0xf96dffd5, 0xe68cb907, 0x250dead9, 0xc77d5ea2, 0x583efdc9, 0xbbf4953d,
+ 0x7749e7cc, 0xbea066e8, 0x939adff6, 0x0724f54a, 0x7d7891df, 0xf2699d3c,
+ 0x903e086e, 0xfc5fb06e, 0x3dbefa0e, 0x48d5c787, 0x79bde058, 0x7ba2642c,
+ 0x0abe8461, 0xcf018a4a, 0xd4b9f775, 0xbecba444, 0x55e482d6, 0x52e0a798,
+ 0xe862cad3, 0xa32cf824, 0x9e2accf3, 0xbf8c984f, 0x889be273, 0xc903bcf1,
+ 0x3c4238fa, 0xeb4f8f3c, 0xff5b1f9d, 0x772e1cd3, 0x1fb8735b, 0x261cebf8,
+ 0x3c78feec, 0x22583a72, 0x1bd5a0e8, 0xcafc8ab8, 0xb64b76b8, 0x88fa0925,
+ 0xd4f6df7b, 0xcabe533f, 0x85bdfd4e, 0xde3d6235, 0x9214de79, 0x8133e126,
+ 0x37eb8df2, 0xff577973, 0x5dd14d42, 0xfce74cbc, 0x4ddc75a7, 0x70b30fbf,
+ 0xc622cccf, 0x8bad17e5, 0x730b9f46, 0xdf68457c, 0x4ecbb645, 0x6dfa93e4,
+ 0xaad3c132, 0xc3b659b4, 0x8cdbb3fb, 0x0bd5f764, 0x0566ce78, 0x14dd6912,
+ 0xef0098a6, 0x22409567, 0xc5dbb5d9, 0xcdc4e0ef, 0xa2bdda03, 0x1f830d94,
+ 0xc2675f0b, 0x7430c14f, 0xeb40ca70, 0x898130b4, 0xe89347df, 0xecd9c79c,
+ 0xee58adc0, 0xee9e7f03, 0xa06b6e9f, 0xf1e2557b, 0x2012d67d, 0xe6225d7a,
+ 0x7e33e1a3, 0x039f0d1c, 0x9fb44f88, 0xfa41df9e, 0x8ca0f82f, 0xee9ecc14,
+ 0xecfc90fa, 0xbe66c769, 0xbf7c2df1, 0x1518ec19, 0xcbfe6df5, 0x077d47df,
+ 0x98ed0a72, 0x690563da, 0xa36f4e2c, 0xd2fb593f, 0x8c4344dc, 0x976d6cbe,
+ 0xb5a59f69, 0x22e24e70, 0x06fe7f6a, 0xaad3afa4, 0xa62cad37, 0x9a392bdd,
+ 0xaf5fa93f, 0x4d7fcdba, 0x37ea71c4, 0xda5e6918, 0x4c000cba, 0x6cdb8724,
+ 0x81ffa461, 0xabf508ac, 0x7d20d3ad, 0xf4683ae3, 0xcd3eed04, 0x78718a71,
+ 0x2f2fb6bc, 0x861de950, 0x003f164e, 0xdb7f62e3, 0xe69f741c, 0xe1ab8ea5,
+ 0x05bd7063, 0xd719535f, 0xc51e7771, 0x14a70dc7, 0xdd3f064a, 0xf20e4d76,
+ 0x07d81d71, 0x93a88718, 0xbdd06f22, 0x74ccc7a6, 0xe6dd6fef, 0x78e2b7a5,
+ 0x0d99af75, 0xfc77df58, 0x5704899a, 0x9e02badc, 0xf7a38672, 0x8e48bc81,
+ 0x607f0637, 0x6b7f1057, 0x9b8189f3, 0x8b3f00e0, 0xc819c5ee, 0x918cf583,
+ 0xe1cd7f03, 0xef681af1, 0xf37d1134, 0xe706997b, 0xaf9b8ceb, 0xafbe6e33,
+ 0xe66fa230, 0x167cd00d, 0xe0366ebe, 0x5ff785fb, 0xb771845f, 0x69d3f5be,
+ 0xbec97d5e, 0x7d5fc889, 0x30ffd039, 0xfde172f2, 0x2f92cf30, 0x959b6798,
+ 0x79c46bd6, 0xb3764726, 0x27a7982f, 0xb7cf3f57, 0x7e913514, 0xcc88e34f,
+ 0xcc128e30, 0x16fc6ff6, 0x97efd32f, 0x1e9c8d05, 0x746d9b82, 0x8bbfaa2e,
+ 0xc9af8fdf, 0x12ef1801, 0xf440c1e9, 0x6ea557d0, 0x75f48299, 0xfdc4ec9f,
+ 0x97f5be8a, 0x2fbf8cbd, 0x7651b7d7, 0x57d0dda2, 0xf207f1c5, 0x5f78f480,
+ 0x2a06ff8e, 0xefd2371f, 0xfb699da4, 0x3ee89feb, 0xfa466382, 0x3c81e23d,
+ 0x5879c6ff, 0xae517806, 0xe26e5e01, 0xe691ab76, 0xc1eebadf, 0xda1f5875,
+ 0x6fce8936, 0x7ad7d50c, 0x906fd73c, 0x14c87c75, 0xde0bc695, 0x17ee8a3f,
+ 0x120cf0d1, 0x23fd08b6, 0x9e581f0d, 0x978a213b, 0x8f7f38a0, 0x8fbf0276,
+ 0xc433c84b, 0x13d73e4f, 0xe5058e78, 0x19a79e18, 0xcbc55f49, 0x7bbd789f,
+ 0x4fb6ae63, 0x0dc797a9, 0x79afbf71, 0x69795c5b, 0x1658dc9c, 0x5718df57,
+ 0x86f9fa0f, 0xcfd2e2e1, 0xa2cf8e0c, 0x1a21927e, 0x4fb81d1f, 0x56b4bf22,
+ 0x07e84d51, 0xeb8d3e3d, 0x59853ae7, 0xe4be22ae, 0x156a73e7, 0xc32e62d6,
+ 0xac535ef7, 0xb5fd04bf, 0x9ca19398, 0xb410e5c0, 0x94c536ab, 0xc1ab7935,
+ 0xa3c04ab3, 0x9c76bf3d, 0x7dc466a0, 0x15b9558c, 0xca31f743, 0xbf5ffce4,
+ 0x11d67e88, 0xe0ccfc99, 0xb0ff5c0b, 0xf2dc3f4f, 0x3bef1b98, 0x323ca02e,
+ 0x78f1fe6d, 0x61fc381c, 0xe4defd22, 0x5f3a26f3, 0x5295db5e, 0x72587e45,
+ 0x6fbc5864, 0x44fae5cd, 0xe95fafeb, 0x6b1d9c4d, 0xc4deb347, 0xadf7dfd8,
+ 0x4ae1fc3d, 0x7f016bf4, 0x8e463921, 0x5a96399f, 0xdd65fe85, 0xf0ab32ef,
+ 0x5cd1efbc, 0x3ea00e2d, 0xe6f901bc, 0x13e29988, 0x33cc2ffd, 0x2ffdf7e0,
+ 0x9de78bd4, 0xff609f74, 0x7072675b, 0xfe8344fc, 0xcf7f89be, 0x9d54f6e5,
+ 0x57ddcde1, 0x9a3ffca2, 0x2626b79e, 0x28675d0e, 0x31f8bf23, 0xc23e6463,
+ 0x3aff760d, 0xfad503cc, 0x12ab9a39, 0xde47fd1c, 0xe1f28dde, 0x32ecc6cc,
+ 0x47fd2b14, 0xdc1f90c6, 0x4565daff, 0xff6b5f78, 0x945e197d, 0xd5198f0b,
+ 0xe2dfb93b, 0x8bc9eef0, 0xe0e387f6, 0x91ff63fe, 0x3f1895c9, 0xc38d7fe8,
+ 0x278a650b, 0xe610bb40, 0x26fd6a5f, 0x984dd41a, 0x677ece8f, 0x8ee2bf24,
+ 0xf1d20acf, 0xd344957e, 0xa050f7f0, 0xc3cfa11f, 0xd6f34d5e, 0xfde37df2,
+ 0x37ff2d0c, 0xeed30fde, 0x17f78f8b, 0x3ddb59eb, 0xef1c9798, 0x6e618237,
+ 0xdf89a509, 0x4ebfa733, 0xf74bf7d2, 0xdfd66e7f, 0xf6121d9f, 0x71e48580,
+ 0x7ae3f02d, 0x79853f8a, 0x3c9d6fdc, 0xc5ec7eec, 0x6fa76e5c, 0x7e6dfdb5,
+ 0x9ebacc6f, 0x03c53036, 0x626d3d78, 0x70d94f16, 0x9c85e3fe, 0xc37b925a,
+ 0xb1758dfb, 0xa1b1d6f7, 0xaae9e47e, 0x9df9e530, 0xefd32f5e, 0xf5c3c459,
+ 0xf8c8fd55, 0xebdfb5ef, 0xc4ed04f8, 0x00938c54, 0xe45fc9a4, 0xd5e1eb3f,
+ 0xbf1569f0, 0x01fff2a3, 0x949113dd, 0x00008000, 0x00088b1f, 0x00000000,
+ 0x7db5ff00, 0xc5547c0b, 0xbddcf8d5, 0xc3764cfb, 0x083c8426, 0x813bcd84,
+ 0x44902c24, 0x8f2ed4ac, 0x0310f0c4, 0x5850822a, 0x89de4020, 0xc5b0fd60,
+ 0x40802166, 0x151a86d1, 0x260dda2b, 0x22ec1208, 0x760d1201, 0x4a888941,
+ 0xadb45503, 0x202a25f2, 0xd4109204, 0xeb6bfe8f, 0x73339cff, 0xd0820fb3,
+ 0xcfe8fbf6, 0x99dee64e, 0x7de733b9, 0xfd999cce, 0xf7f87bfe, 0x17bec613,
+ 0x62a2d9a5, 0xc963106c, 0x2d9990ff, 0x43b2b194, 0x891ae71a, 0xafdac0b1,
+ 0xf50b999f, 0x398d16ee, 0xf958c2c6, 0x6726d921, 0x659ac630, 0x3e0c4267,
+ 0x08a822ff, 0x8f3797de, 0x33cccb31, 0x9cb3795e, 0xac654ce7, 0xd86ae9ab,
+ 0x671a54e2, 0xfd88c5ba, 0xa1dab69f, 0xc2acc834, 0x57b4f465, 0x4c8b58ca,
+ 0x69de28f3, 0x9932fea8, 0xe1efbfd1, 0xb05752bf, 0x29bcbd4f, 0xbd4bfab2,
+ 0x7f8c5ea7, 0x367fc244, 0x8c5967a6, 0xec57f095, 0x6187ea72, 0x5dde6053,
+ 0x1912e7b5, 0xb2a8d12c, 0xa1325ac7, 0x169df89e, 0x67b58ceb, 0x7e6899e5,
+ 0x67981641, 0x20dbf3b7, 0xb7d2f306, 0xbf9c36c8, 0x2c32fcff, 0xff32c65a,
+ 0xc2e5f983, 0xf33cc2fc, 0x5864f983, 0x59e67906, 0xb2d1e966, 0x3e879858,
+ 0xc48d9d28, 0xa369b616, 0xfc22fda0, 0x6a2fde13, 0x058d3c59, 0x79a93631,
+ 0xe0031ac9, 0xb25abba1, 0x7e79e0ea, 0xf00dc00b, 0x764dbf90, 0x932f005a,
+ 0x311d5692, 0xd3f17d40, 0xe6ba1ef0, 0xcf4ee3c8, 0x9ecbf686, 0xb87ea990,
+ 0x1ad391f6, 0x0d36ebc4, 0x031e21d3, 0xef8bb682, 0xa15f9c31, 0xcb615f98,
+ 0x7c120bd4, 0xd921d96f, 0xf5fec6ea, 0x5f3e2b26, 0x79f341bc, 0x96fad7bb,
+ 0xde301fe0, 0xd392ad92, 0xa92de30d, 0x95df7df6, 0x38b2d0e9, 0xefd5bfe8,
+ 0x99faed79, 0x54b14247, 0x51d60933, 0x8f7df4e8, 0xf986deff, 0x77bf8b94,
+ 0x8c1e6c26, 0x3032e9f8, 0x61f806d6, 0x8630f6ea, 0x1a3dbba5, 0x7cd5d8f1,
+ 0x58f11a36, 0x24fffafe, 0xa7f07eb2, 0x14c5ac94, 0xe0102e7a, 0xf7d89169,
+ 0xabfba42a, 0x69faf3d3, 0xe7087a3f, 0xc71a9d8b, 0x3fbc2b60, 0x746dfb52,
+ 0xb349d23b, 0x1fb9987d, 0x9f1bedfa, 0x08aa0c39, 0x8606dd2c, 0x3ccb8665,
+ 0x4de4f905, 0xd213798d, 0x33f5f6c7, 0xf0dd43b7, 0x00660686, 0xf12304f5,
+ 0x12c7f20b, 0x3e1571af, 0xd9b129d9, 0x99426654, 0x6892f38a, 0x930fdf5e,
+ 0x1e771e88, 0xd09e9dee, 0x69867cdf, 0x21e8dda8, 0x347dda8c, 0xd2356f2c,
+ 0x11ca805b, 0x3660f884, 0xe014259b, 0xaafa092b, 0xe121595a, 0x4d5608f3,
+ 0xa2e610e5, 0xecc605f2, 0xaccf6c46, 0x63338466, 0x7e118343, 0x5eb4f3c4,
+ 0xe6e90abb, 0x9b770267, 0x8e0f4e24, 0x87ace660, 0x3d5ae5bf, 0xa6300793,
+ 0xd841ed65, 0xf33694c9, 0xbde0c3d7, 0x255943e6, 0x43c8bd01, 0xcd5a7c15,
+ 0x8c6fdf88, 0xc6f00df7, 0x17f7e1df, 0xa578e2e5, 0x83a665fb, 0x6a372ef1,
+ 0xed88db98, 0x9da05f81, 0xb5affde6, 0x5a972831, 0xeb009624, 0x3e3a8728,
+ 0xb6a71f2f, 0x52e0bd39, 0x78f0e16f, 0xf04892da, 0x8edb52e8, 0x33fa434d,
+ 0x2c3ad22f, 0x2e7e4e38, 0x11347183, 0xaf38b48b, 0xd04fefc3, 0x82de20c7,
+ 0xeb37c4d5, 0xb6ef945b, 0x64fc7199, 0x78f329d5, 0xa993df78, 0xf1e1db66,
+ 0xcdc6a3f9, 0xf7ca47c8, 0x3f1c2cba, 0x12812b67, 0x97cf3c92, 0x8397dc64,
+ 0xfb3297fd, 0xa5a3a47a, 0x7b733235, 0x0d79fdd1, 0x6b92f7c7, 0xc63dcc81,
+ 0x4cc45fab, 0x6b92d75a, 0xbcfcf441, 0x6f3bb781, 0x9ef174e2, 0xc7c5d385,
+ 0x885fbbe2, 0xaf2dbffa, 0xeaf2beac, 0xef1f0bf2, 0xd6e5c458, 0xa547487b,
+ 0x44ce7b52, 0x88fac4f8, 0xf5ca2d5e, 0xe66695b3, 0x3ad0fdd6, 0xd7b73207,
+ 0x5ddafb77, 0x40f73033, 0x6859b86f, 0x1af59efe, 0xcad9fde9, 0x31c09b88,
+ 0x9e8e07ca, 0xe07ce3f1, 0x89f8fd78, 0x656cfef4, 0x1fc64df2, 0x63f18371,
+ 0x19efe67c, 0xaf9e9e37, 0x20b1554d, 0x9fb5aba0, 0x6cc49ce8, 0x74a7ae7a,
+ 0xbad6ef82, 0xfd2de927, 0x4d83aff0, 0xe163628a, 0x8b9ca37d, 0xbcd97c74,
+ 0xae7c8cc8, 0x74b90609, 0xd8d7f41b, 0x7180ef72, 0x0321c175, 0x5aaf7e91,
+ 0xdf5d68e2, 0x1d105706, 0xb4743b7f, 0x8fc188ec, 0x7d61e454, 0x997c90ed,
+ 0x59fab378, 0x7ae5f392, 0x21d37dfe, 0x9fe44a60, 0xaf42f5db, 0x18bcc9ff,
+ 0xd43553be, 0xf4c98fae, 0xf994c7cc, 0xb33c4336, 0x9430fb26, 0x819b8f03,
+ 0x801f896f, 0x5abd61af, 0x3bbbfec9, 0x9fd81f80, 0x8a1eac75, 0x24f60d6f,
+ 0x471f17b3, 0x09fd70c4, 0x728510dc, 0xa86ac1d1, 0x4aba6f2c, 0xff00b670,
+ 0xf794bae2, 0xe087ace5, 0xc2cd7c8e, 0x16d52691, 0x4f64df7a, 0xccf34bca,
+ 0x78eecfa3, 0x0150e8c7, 0xfd0ee9ff, 0xd9e10823, 0x6e99eead, 0x22d5d285,
+ 0x77c37a07, 0x8fe70c64, 0x4ebf4309, 0x65e7876f, 0xd3e40fd8, 0x27166f23,
+ 0xd329fca1, 0xbce3a4f5, 0xf7f9bc8f, 0xdff79474, 0x861e2a1e, 0x7b4277cf,
+ 0x3db413b2, 0xf1af5665, 0xa1d999e2, 0x9329eb1a, 0xef88e263, 0x3cef9ffc,
+ 0xe7183554, 0x886200d1, 0x5677c085, 0xe5f717be, 0xdb072440, 0x18672853,
+ 0x0b7a97c8, 0xcaf74dda, 0x3eca5728, 0xea04db02, 0xbf5ccd19, 0x4e650c67,
+ 0x67da0c55, 0x7c46cd1f, 0xcd6a6595, 0xc04a582a, 0x1ae736a8, 0xa9901f78,
+ 0x1d1ea337, 0x5f7f843e, 0x0e3cfa8b, 0x440f67fb, 0xe414fdbc, 0x0f247fec,
+ 0x2becfcea, 0x06b2a9f7, 0xdca95ef8, 0x00e51d3e, 0x31e985c8, 0x07d97e30,
+ 0xb5489f5f, 0x309e8b60, 0xd0b74fc4, 0xe3127f3f, 0x37931a3c, 0xfbaae913,
+ 0xe3d777fe, 0xbb2437a3, 0x88e3d71d, 0x5f515bd4, 0xec6708b0, 0xcebc2f4c,
+ 0xba09518d, 0xba01ee01, 0xb6e62e1d, 0x796bb067, 0x6725e930, 0xb943d208,
+ 0x1e51d98a, 0xd40069b2, 0xf32e91db, 0xf5a666d2, 0xd0d79fa7, 0x6c62cb78,
+ 0x4abe708b, 0xcd668ffb, 0xc3f7b34d, 0x04a94887, 0x21ebad4f, 0xa94f679c,
+ 0xf01dbad1, 0x82be21f0, 0xd2cd2f7e, 0x93b065b9, 0x0dc635ba, 0x27d1d012,
+ 0x075bf381, 0x184ffac1, 0xceb815ed, 0x5e4c0fd9, 0xc8e9758f, 0xa472cb40,
+ 0x59ed85cb, 0x06399788, 0xbef8c3fb, 0x161f6f44, 0x3cbc4b06, 0x00349ed4,
+ 0x40de6a95, 0x97966f0e, 0xfcefd796, 0x753c7cf9, 0x54b7fa46, 0x31b7a5c0,
+ 0x49d9006e, 0x67480daf, 0x152e9f30, 0xd0fd402b, 0x15fbe625, 0x25e623e8,
+ 0x279c0ba7, 0x7da10bb5, 0xed49dd61, 0x97f5af22, 0xeae08582, 0x3a7a2ec7,
+ 0x1745db86, 0xdbfefdf7, 0x9d50c05f, 0x44481cdf, 0xba58b5bb, 0x76faeb44,
+ 0x62f9c9d7, 0xbeb8d57d, 0xa27b7a47, 0x12aeb0b5, 0x972d61d7, 0xea7d621f,
+ 0x5a1fc49e, 0x2daa975f, 0x80e2e887, 0xf18fae64, 0x3c6d2bf4, 0xf4051399,
+ 0x3c17505e, 0x9674e65a, 0xe8567488, 0xd1788f84, 0x028e32b1, 0xde42e59f,
+ 0xf014aef5, 0xb676e009, 0xfbe51f02, 0x33e0fc67, 0x8d93dd5f, 0x2abf98f3,
+ 0xa9e5c558, 0x7947e893, 0xefa560bf, 0xfb14ab77, 0x49c931e7, 0x7ebc66f3,
+ 0xdcec11d0, 0xea9d7504, 0xa2f787ea, 0xb2a690dd, 0x2db0dda2, 0x68c06400,
+ 0xf028fec6, 0x07c802f3, 0xdf3d087d, 0x0223cf80, 0x6788ff78, 0xe82ace54,
+ 0x99a1379f, 0x32a5f0e8, 0x6f8655a3, 0x98e0642d, 0x331614c0, 0x67d9d91b,
+ 0x50fdffc7, 0x68f3ac3b, 0xf08ddd8c, 0x1550305f, 0xc3cd21fd, 0xda06623e,
+ 0x1c38e36f, 0xfd17b3af, 0x99933fe0, 0xb1e46435, 0xfbe42acd, 0x94be6699,
+ 0xe3e71225, 0x834d997b, 0xd99fbbdf, 0x2ea9dda9, 0x93fd0dad, 0xc15be853,
+ 0x0e601fbc, 0x39873e7a, 0xdccb9ca9, 0xaca7fed4, 0x1f0aea9d, 0x082ffd00,
+ 0x3e7ff4e5, 0xf9ba265c, 0x327de718, 0x4ae87d30, 0x678cc758, 0x5fc81293,
+ 0xf04419ab, 0x67bcd9b9, 0x8f8e1c48, 0x71dbd8c6, 0x6fdcde9c, 0x7181ac5e,
+ 0xd1377a54, 0x989c9f5f, 0xe1d04834, 0xb689cb0f, 0xcc7f3ede, 0xb8700918,
+ 0x2ef4a04b, 0x63f9315b, 0x3991b2d9, 0xe36d3f00, 0x53fa2764, 0x43ab6cc7,
+ 0x93aa6543, 0xcab36d5e, 0x59dff7a4, 0x50194ccd, 0xc694677f, 0x6b74455a,
+ 0x5d3c3d23, 0xcd7d978c, 0x7800f6fe, 0x586e5d3e, 0xdcf50c1b, 0x790fe021,
+ 0xd0e4d5d1, 0xb3e46abd, 0xcfbef129, 0xfafaa5a7, 0x6ab3774d, 0x3d3be119,
+ 0x61ddb7c3, 0x95d00b84, 0x3ffb962a, 0xfe1b386c, 0x8fe1ecbd, 0x31f9147b,
+ 0x1bb6aaed, 0xd62631e6, 0xf585886e, 0xecfbbf2f, 0x532efc7c, 0xa0c60fb3,
+ 0xb3213a5e, 0x73fef04d, 0xd81b13e0, 0x82565f4b, 0x397e0306, 0xd61ff607,
+ 0x0d3b02bf, 0x16958bcb, 0x5d812f2a, 0x2abbef85, 0x207f54ad, 0x16242f36,
+ 0xc368bf40, 0xed1db515, 0xfa2ceafe, 0x5f410afe, 0x2ab72a6d, 0xbb67f910,
+ 0xb87d4564, 0x2136d0c2, 0xa2b6e010, 0x180ac63e, 0xae4d4566, 0xbe7e9c56,
+ 0xd1072f3b, 0x4558f4b8, 0xd7a5962b, 0xd2076624, 0x8bce417e, 0x3ebbf1c6,
+ 0xddd67cfc, 0xe57cfcf0, 0x85fefa58, 0xbf7d1b4a, 0xca9732b3, 0x3c7b588a,
+ 0x74b5b3b6, 0x20b40eb4, 0x7d10ae36, 0xa1d0dddc, 0xb67a828e, 0xdf21b24d,
+ 0x4e6369dd, 0xab75e027, 0xada9eb86, 0x0f90a7a0, 0x7ccda7c7, 0x7a8661e1,
+ 0xe38e9ec4, 0x30a53fdc, 0x3e99c71b, 0xdb1aa176, 0x631df03d, 0x743c6303,
+ 0x65ba3376, 0xf2fc727e, 0xddd1129b, 0x1ee59565, 0xc71cabb4, 0x7a0fb265,
+ 0x185530d5, 0xe193f7bf, 0x74e0074e, 0x70b8fef9, 0x35cb6794, 0x2f10f096,
+ 0x27e9d639, 0xdcf73ac7, 0xdfade116, 0xdf5c433a, 0xd0e505fe, 0x810e5c67,
+ 0xb7ee74a5, 0x118ca728, 0x976fc456, 0x520043f0, 0xcb8fa881, 0x406f82b4,
+ 0x33bd608e, 0x83c82d80, 0x51abd67a, 0xf00f9013, 0x8f24967b, 0xf57c499c,
+ 0x585fd8d9, 0xe9dbdf3c, 0xdf97f25a, 0x53b2fd42, 0x5e80d0e5, 0x5d5cccba,
+ 0xeabae3af, 0x17b4568c, 0xc0752593, 0xefec10ca, 0x964bbe24, 0x2095ea2c,
+ 0xfabd7647, 0x19e7e0c2, 0x8d8c09da, 0x6c6ff785, 0xf3392409, 0x667ac686,
+ 0x817ff625, 0xc9f97ff7, 0xc26f3f47, 0xd1d289f2, 0x1059428f, 0xcd70421b,
+ 0x70e14dff, 0x5111b3a4, 0x6f180680, 0x6dc941f7, 0xad2c6748, 0x489af0e6,
+ 0x6dc8cf98, 0x50c1aa1d, 0xaa93aa8e, 0xca611cb0, 0xfbc3263d, 0xcd0b58b2,
+ 0x8c434c63, 0x32ec851c, 0x9f97f9d8, 0x6be1bd90, 0x5cd6a487, 0x79983099,
+ 0x92e191ec, 0xa5e222eb, 0x347a74ca, 0x4d563be9, 0xb96fece3, 0x69734ff7,
+ 0xe0e9601d, 0xad6a17bc, 0x8e9c1fa4, 0xcbb3a45a, 0xd92b64f6, 0xe78e79e7,
+ 0xed97bf10, 0x17d45661, 0xff5fc007, 0xa33fb611, 0xac1e75a6, 0xf184193b,
+ 0x07e0019b, 0xe97de01b, 0x93d21ea8, 0x0c2d43a5, 0xc5f43bbf, 0x3e1172bb,
+ 0x6bfb8d65, 0xbd129c69, 0x82d9fd15, 0x515b57fd, 0xccc9b26f, 0xd5f4809a,
+ 0x9abfebc8, 0x1ea2b364, 0x86fda82d, 0xa8f2dbd7, 0x83de079e, 0xe62fdb1a,
+ 0x42b3d976, 0x74f6b12f, 0xb2445b92, 0x7ebe0f16, 0xfdf1af05, 0x644718d6,
+ 0xcfa3d185, 0x416d0f40, 0xf2d488fe, 0xe6136dfe, 0x6e5c1346, 0xe3290f51,
+ 0x0e65ab3c, 0x2d45ea03, 0x20f597d7, 0x603e902f, 0x7c7117fc, 0xc9466f45,
+ 0xac235a52, 0x1d59ea3b, 0xf8b7b397, 0xd603d99d, 0xec54de93, 0x1f6172b8,
+ 0xe8136154, 0xbfb465df, 0x8970f282, 0x6d4cb3d0, 0xe3bb4549, 0x776da333,
+ 0x6071d92c, 0x7f48a8e7, 0x65eb1efd, 0x7175d832, 0x319d765e, 0x17f496e4,
+ 0xe3f6d933, 0x7db56e7a, 0x9fe798a8, 0x03433cc5, 0x1d2c9da2, 0x87f80afd,
+ 0x7858e984, 0x587186d2, 0x447ef1f4, 0xc156eb24, 0xe11d073a, 0x8bb1e3f5,
+ 0x1b05acb7, 0x77a47dfd, 0x3382470e, 0xfb430050, 0xca6e794c, 0x6210f4e0,
+ 0x11dd93d7, 0x5462b03e, 0x337d1785, 0xc20c7bb5, 0x653fd363, 0xdb7684b7,
+ 0xfc5233ff, 0x86de7fc7, 0xfd7fee38, 0x150e624c, 0x2d15d7d2, 0xb4d16bb5,
+ 0xf43dfeef, 0xb54c296b, 0x007b3fa2, 0x71c7adf0, 0x8ec96a66, 0x05db416a,
+ 0x09ccb7da, 0x86f7b923, 0xc741cb86, 0xdfde009c, 0xf7c10000, 0x689dc3ab,
+ 0x55d60da7, 0xe38697bc, 0xdf120557, 0x1b9c68b4, 0xc7fc7162, 0xb2f8d206,
+ 0xe8e1bdfe, 0xe4227d7f, 0x9ee49551, 0xc76df18b, 0xefc32d15, 0xa3bb04d5,
+ 0x535ea1ca, 0x7fda9c38, 0xed192a02, 0x5b609ac4, 0x03d9ca24, 0xfe4994ff,
+ 0xba828cd5, 0xc513e491, 0xd8666a61, 0xfea18322, 0x4d4bc0a0, 0x99feb3ad,
+ 0x4c9e7c50, 0xb8c60ce3, 0xe18bb61e, 0xc345fce3, 0x07a7d9fb, 0x075ed1aa,
+ 0xf089144d, 0x027e6dfb, 0xe3c2d2c5, 0x0871c826, 0xcfb7e15f, 0x19477216,
+ 0xb3e83b1f, 0xffe30ed0, 0x37a92ce6, 0x5fdd7f20, 0x0d00e860, 0x58293ec2,
+ 0xf5bf4263, 0xd6ecbb7e, 0xf7605c81, 0xecfadb65, 0xdf1c5882, 0xbd21c726,
+ 0x937e2be5, 0xf5c2317b, 0xdb3d1ecd, 0xe0237644, 0xba7aed35, 0x1fdf80bb,
+ 0xf8e3fe80, 0xc7fdbca7, 0x9fe71d42, 0x6887480b, 0x43da060f, 0x4de5fe70,
+ 0xf6f29f93, 0x592ce72b, 0x40724417, 0xa552f77c, 0x132fa9ed, 0xa5c84ed0,
+ 0xf2aef952, 0x7a99dcbd, 0xfe8a149b, 0x7189ce8d, 0x0ec205c0, 0x67b9d72d,
+ 0x673e3f21, 0xefa30fb0, 0x474c5d14, 0x6674317b, 0x475c00f2, 0x0e60bbf7,
+ 0x0233db41, 0x805067cf, 0x4c2b9e23, 0xd44c3744, 0x4818bfed, 0xdf04b9f6,
+ 0x62fa3a41, 0xda3b698d, 0x2dad7673, 0xd1d20972, 0x47b240f2, 0xc1dc80ce,
+ 0x0494cf71, 0xfbce1d13, 0xc8fbf175, 0xb4f2676f, 0x5a679f44, 0xe9f7bdb8,
+ 0x85add94a, 0xbccd77f5, 0xf4224cf6, 0x45f55aeb, 0xdb2856d6, 0x1a35fcd7,
+ 0x35bcd1f5, 0xdfb0d3a5, 0xd355a2bc, 0xe2374e11, 0x3a2579f3, 0x6e1cccc1,
+ 0xb76ce353, 0x6742be23, 0x3941cb5e, 0xe4b8b83d, 0x17c18c39, 0xc4efd9c7,
+ 0xdb6997f5, 0x651e10cb, 0x8d167c6f, 0xf37773f6, 0xa15b7bcb, 0x27d9336c,
+ 0x35b2bf60, 0xc3acc577, 0x55ff84c1, 0x017c06a6, 0x671e7d1d, 0xe5f7c1cf,
+ 0xd889dc93, 0x2da692ef, 0x56c6e107, 0x7ddd9add, 0x80fea5b1, 0x40607e84,
+ 0xb295194b, 0xd1e71d33, 0xa483b929, 0xd8238438, 0x4beeb00f, 0x70507766,
+ 0xc98d452a, 0xe9de289e, 0x5a9a3ebb, 0x403b8898, 0x6c9762bf, 0x32dd2033,
+ 0xebe716a7, 0x9e18bedf, 0x7c5bbb53, 0xfc5cc45e, 0x93d37079, 0xab7d2077,
+ 0x37f71b99, 0xd84aee2e, 0xbcbff88e, 0x6f44e5ff, 0xbcbfd83f, 0xfd7cbe7e,
+ 0x00be9097, 0x89e0978e, 0x41abe906, 0x75ffe3e7, 0xfa248aed, 0xfd11ef82,
+ 0x724aed74, 0x8f92f26e, 0x307e425d, 0x066b2bab, 0x95cdbdd2, 0x22967685,
+ 0x95de982f, 0xb25bfe4e, 0x15fd1d2b, 0x3cb0de45, 0x773d2257, 0xfdb112ba,
+ 0x8d67f401, 0xed16ef9e, 0xc4ddaa8e, 0x550e8ee3, 0x6c47d606, 0xee32bac7,
+ 0xb497d6cd, 0x4f53eb55, 0x9fd6fa71, 0x95fcf210, 0x1f8ab457, 0x82bf0b2c,
+ 0x5a3c1459, 0x7046fdb8, 0x8156b3f9, 0x5951c3cb, 0xbf803718, 0xdcde6962,
+ 0xfb857e6f, 0xd94607cd, 0x2aae50a3, 0x6081f9fe, 0x5ea2a7a8, 0xea56f3e5,
+ 0xe7fc1c0a, 0x4bcfe6bd, 0xf7be30a3, 0x1f8f1c46, 0xbcb81955, 0xb97032aa,
+ 0x1594dab4, 0x34abef8e, 0xa2a6c760, 0xee2c72bf, 0x0e078d4b, 0x366d2ae7,
+ 0xf57dc110, 0xe9475ba5, 0x6d976f91, 0xa6f7a51b, 0x639daa8f, 0xde60598e,
+ 0xadaa7697, 0xb52a84b8, 0xd7b449f3, 0x2eca76aa, 0x7af7a307, 0x64bfb41b,
+ 0xdb02723c, 0xe3c6dd2d, 0x65ff4a16, 0xf96db35b, 0xb11ef35e, 0x69be17d3,
+ 0xc8fadf2e, 0x51fadf26, 0xfd0645b4, 0xb946fdeb, 0x8e63eb7d, 0x7fcfd6f9,
+ 0x242cf0f8, 0xf1d902c3, 0xe3f68ca4, 0xa18e735f, 0xc0eaf93e, 0xf78a20c1,
+ 0x8adf967c, 0xadb2f176, 0x3c0770be, 0x3827684a, 0x77a44876, 0xfcfe9d0b,
+ 0x031f3fd2, 0x5f389446, 0x14dd37b2, 0x3aab4731, 0x9df6fae6, 0x86cb35cc,
+ 0x7f95a571, 0x8c72fb8a, 0x5ddbdc67, 0x0fe8b45b, 0x46f77ff9, 0x368ccb7c,
+ 0x1637c60b, 0x7eefe58e, 0xfb2272b4, 0x7cdbc702, 0x71e90732, 0xd224afe1,
+ 0x25f70bc3, 0xd3748dbd, 0x14ce77b1, 0x12e5672a, 0xcbb8943c, 0x6dc916b2,
+ 0x2c79ba82, 0x650fdbeb, 0x6b45ef30, 0xa1f13e75, 0xf3becdfc, 0xfbe35a58,
+ 0xe1d3597e, 0x6bbee1bf, 0xda45fe81, 0xa6d82ea7, 0x396b8bf3, 0xbd3b42df,
+ 0x7e462be8, 0xf7dd5178, 0x5ee2feba, 0x143ac44b, 0xee3990fb, 0x6e4eb864,
+ 0x8edf8202, 0x3d7207ff, 0xc4d76cc4, 0x8dd8f20f, 0x95a9aa3f, 0xcca57e11,
+ 0x8e3988fe, 0x207751fc, 0x0ea967cc, 0xa4d1b1ec, 0x577d6987, 0x78a00eb7,
+ 0x06673c07, 0xb5957e78, 0xbe7ea165, 0xf2b268da, 0x965b5938, 0xa0cbea19,
+ 0x602bf08e, 0x12a704d5, 0xa732cb94, 0xddb79b1b, 0xb3adf4e0, 0x97b76e6a,
+ 0x1187dda8, 0x9dacc51e, 0xbd1e21fa, 0xbac095db, 0x3b41093e, 0xb33fafc4,
+ 0xdcbc9c52, 0x95fc25a8, 0xf3af7d37, 0x0bf8af7e, 0xc4a2ff8a, 0xf4577ee1,
+ 0xb7d20060, 0x3587d846, 0x5b7b9d1b, 0x94eb3d61, 0x0316deb8, 0x6b07a7c9,
+ 0x7b07bcb9, 0x59d71130, 0xd68525b3, 0x8b64a0fd, 0xf6b68759, 0x7fd13d0c,
+ 0xd3d8304d, 0x924764a1, 0x237600bd, 0x733dadd9, 0x12edceb4, 0x372e8fda,
+ 0x4f35c1da, 0xca06f8f3, 0x9f6bb249, 0x527d9030, 0x27db8333, 0xa9c25b35,
+ 0xca705fff, 0xf2576891, 0x913cd4f9, 0x995dedc6, 0x8ce163f7, 0x65f607e6,
+ 0x5e6bdea2, 0xb2ff5d8a, 0xf1113ed9, 0x26b7acad, 0xfb84c7b8, 0xe060ac1d,
+ 0x7af9e92d, 0x007abfa1, 0xff07180e, 0xc56bca52, 0xdda5097d, 0x1f5cf17d,
+ 0xedb04d64, 0x5e28ed10, 0xb19aaf9e, 0xa79827e9, 0x52ca8cf0, 0x7f05e315,
+ 0xd7112d9b, 0xc316e5ff, 0x99d3c468, 0x679e5c51, 0x05f1e04d, 0xdb6c5bf0,
+ 0x5e22ff71, 0xfd7713e5, 0x614ef8a9, 0xf5e685bc, 0x2f8f3665, 0x28f2329a,
+ 0xdab6038e, 0xf5f6fe82, 0xbef9e30b, 0xef36be68, 0x99fb8ff8, 0x3617028f,
+ 0x5f17fb89, 0xbe91243e, 0x9a24f584, 0x1bf59ea1, 0xbe7fc503, 0xc1477a14,
+ 0x2651d007, 0xc72161e9, 0xc67e90c2, 0x19e7e878, 0xa40e1741, 0xfd378b0b,
+ 0x83c7d2f8, 0x09ecff02, 0x04d69f6e, 0x13cd7af3, 0x9fa03729, 0x650ffdfe,
+ 0xfcb535bd, 0x01dfbfbd, 0xde36b074, 0x74fe9e0b, 0x4cced4c0, 0x7f35fdef,
+ 0x8d96c83a, 0x57e728c9, 0xb4560148, 0xfe0857c7, 0x1184b158, 0x0ab1463d,
+ 0x8235f909, 0x008f29b9, 0xc70181e4, 0xc00f71fb, 0x7f0f8bdc, 0xbccf4d72,
+ 0x1678dff5, 0xa89f53ec, 0x9f69f48f, 0x79f18e6d, 0x8a44577f, 0x96c9fbcf,
+ 0xa9f53e51, 0xb4fbb7c9, 0xde3adbbf, 0xd8cf7ea7, 0x67ed3ec9, 0xd4f866d8,
+ 0xc6accc6d, 0xee54b7f9, 0xcde0fb24, 0x97dc574a, 0x65c3d709, 0x3ec8ee9c,
+ 0xa6b1958b, 0xaa6707ba, 0x0dc61e81, 0x0622b238, 0xede387ea, 0xe4751ebc,
+ 0xb1998c6a, 0xf217e2b7, 0x572388fa, 0x347ea163, 0xdfaf117e, 0x7f5fc8c1,
+ 0x4cf17e27, 0x15c52a47, 0x667e218f, 0x8a38ab5d, 0xab47e16e, 0x41892e67,
+ 0x24c92f1e, 0x67ecae39, 0x3f6313dc, 0xbcacfc84, 0x8d9fda57, 0xafbbfde7,
+ 0x7ddff970, 0x2377cb85, 0xfe83291a, 0x32fc12fd, 0x0e04fefa, 0x6f413622,
+ 0xa62ffda4, 0x8bea5cd7, 0x94fc8343, 0x3c618c6c, 0xf012a5af, 0xd370809d,
+ 0x34aee953, 0x32a47953, 0x2bb7ca82, 0xe01f2c2d, 0x4c995ada, 0x2b4ab1e5,
+ 0x395e3f3d, 0x2bf7ca96, 0xa89e546d, 0xadb2a5cc, 0x094a8f32, 0x2879a98c,
+ 0x3758763f, 0x0e2e1068, 0xbd39f075, 0xc6e52f27, 0xcecd4c72, 0xc685f829,
+ 0x5f6c186f, 0x31dd93c4, 0x71714cc4, 0xd35bbcf1, 0x73d222f3, 0xc16615d5,
+ 0xa6c3b87c, 0x9fb416d3, 0x44f532ab, 0x9b4f52ef, 0xb8ebe505, 0xbaaf5e0c,
+ 0x675166d2, 0xfdea3af0, 0x28d760ee, 0xa5550bd4, 0x189aeb46, 0x448eef7c,
+ 0xa157197e, 0x387fa2b5, 0x3e67a7a9, 0xa338f1f2, 0xf47a82d6, 0x2df5a9b0,
+ 0x73ca3df1, 0xdcc2bba9, 0x3457dc2a, 0xe2cc59b4, 0x7c0e383b, 0xc1f50637,
+ 0xbbe187b8, 0xed056e34, 0x679b8d07, 0xe4aefbec, 0x0ffd5df7, 0xe4a2777f,
+ 0x5ef8ddf5, 0xff3a6ef8, 0xbbe7c5ae, 0xe5ec996e, 0x0fb26e2b, 0x11ad83ba,
+ 0xfa955f28, 0x4a9f7c24, 0x33d24271, 0x196e2ce3, 0xe887eff7, 0x070d3cb8,
+ 0xa5e0d2f3, 0x6278956f, 0x675f2f5d, 0x08bba557, 0xb0926af9, 0x59692657,
+ 0xa993c232, 0x98fe2802, 0x1ad77f2d, 0xcde5f505, 0x9dcc28d2, 0xdbcba498,
+ 0x9aae7e46, 0xca161dcb, 0xb75332f5, 0xed0cbe15, 0x5945854e, 0x486adf31,
+ 0x0f1601c4, 0x3cbb3872, 0xfaf51537, 0xd4df9129, 0x484f641c, 0x9bdc7980,
+ 0x254a720a, 0xd9f71988, 0xde490372, 0xca4a1f77, 0xa67f7b44, 0x019fb2ce,
+ 0x3c26a71f, 0x720d5333, 0x4b00e671, 0xfac664a6, 0xb70f5e36, 0xbde097ec,
+ 0x73333d99, 0xc1ffedd2, 0x4934fafe, 0x381f97ed, 0xadf80136, 0xc8b2f734,
+ 0xfb21ec57, 0xe498c7f6, 0x77e28834, 0x9ec7a46e, 0x03d226c9, 0x8e5b8f18,
+ 0x92d53bf2, 0x35a2ed89, 0xff08413d, 0x94d4efee, 0x832d023f, 0xe38af3ee,
+ 0xf3c2d8bc, 0xe3f9fc4a, 0xabd70272, 0x9f3cf1e5, 0xaf422ca9, 0x4ae5b2a7,
+ 0x8f7ca30e, 0x3ff478bc, 0x57edeac1, 0x0277febf, 0x598e1fdf, 0x47f1e5af,
+ 0x6530a114, 0xea53005b, 0xa96bcc0e, 0x3140247d, 0x4e006d46, 0x547ec5a6,
+ 0x24cdfa6f, 0x1b7b4fb5, 0x67bcf7b6, 0xd29f0436, 0xcf7ea4bf, 0x8bc6d66f,
+ 0x2cbd21ef, 0x825c4e65, 0x4da9febf, 0x0bfc510c, 0xa10bf3c2, 0xe38bf206,
+ 0xa057a065, 0x1740a8cf, 0x0ceb33c5, 0xdcc17e9c, 0xc54eb2a0, 0xc0036bdf,
+ 0x50fa85fe, 0x9a3ee3a8, 0x22bed13b, 0x67f51071, 0xef2fec66, 0x2291fea5,
+ 0x1f794e6f, 0x1979518e, 0x0cdae9f3, 0x55938e58, 0x4e4dc2fd, 0xc46bff1c,
+ 0x83a55777, 0x2fd2f59d, 0x2b41815d, 0x8654f1bd, 0xfdde8dfd, 0xa53f5026,
+ 0xfdd8297f, 0x9c920767, 0x8d297a26, 0x2b3e5157, 0x4b6fcdf8, 0x36b0d768,
+ 0xa561ea2d, 0xab9069df, 0x410fbdf8, 0x09f962ce, 0xc0b3d7c8, 0x9ca97f9b,
+ 0x95a7e54d, 0xa67e7a76, 0xf6ca80b2, 0xfe7a0aca, 0x2a4ae579, 0x6535cd67,
+ 0x37949f20, 0xbd6766ad, 0xa5d4bae8, 0x4bef7bb1, 0x3fdf1e9e, 0xe04aecbd,
+ 0x98e9dd76, 0x95bbdffe, 0xbc7277f7, 0x817d8375, 0xdfd024f6, 0x8dc8735a,
+ 0x136e8ced, 0x377abfdf, 0x7773d385, 0x25d7af24, 0x536ea868, 0xffd8adb1,
+ 0xd12d14dd, 0xc6448aeb, 0x2c7889db, 0xdf8d1fd0, 0x3e54e707, 0x19ced28e,
+ 0x2fedcaaf, 0xf225984f, 0xe89f4476, 0xc63d202f, 0x9967d178, 0x9fd3e885,
+ 0x39136a2e, 0x38ebc4df, 0x2ea145dd, 0x708c7dc2, 0x0a731383, 0xdc36be60,
+ 0x3893af57, 0x9f475e3d, 0x5d9fee2a, 0x0e309f47, 0x5ce809c1, 0x7ec7f282,
+ 0xef94a3f4, 0x0b6fbe0a, 0xe08cfd33, 0xa331a2dc, 0x0cb1f8be, 0xaafec580,
+ 0x0f9813de, 0xb266151e, 0xf6489ee0, 0xfe8ac6e3, 0x123fc7e4, 0x6ffd7db8,
+ 0x1f8fbfaf, 0xdd7fd77d, 0xd07ec5ba, 0xe49baead, 0xa44bca09, 0xc3e47e9f,
+ 0x3e4504a5, 0x1391fa70, 0x3f50e76d, 0x35064b74, 0x0dbbb3c6, 0x83ae2e9c,
+ 0x4fa70a5b, 0x056a3e85, 0xbae1447d, 0xe9eb3ce2, 0xdf807f9b, 0xca3196fa,
+ 0xa3c7f0eb, 0xd6bc5722, 0x2f04f7f5, 0xd818c279, 0x487fd017, 0x09f69189,
+ 0x099a2457, 0xce83dd7e, 0x6f02dfcf, 0xe27a159f, 0xa7df1579, 0xdf76e450,
+ 0x305e4973, 0x9e47d523, 0x7a33b433, 0xbf88e90e, 0xf0562adc, 0xf851fa1a,
+ 0x70bf2f29, 0xef53c0ac, 0xee154cec, 0x6b7d75bf, 0xcd1e5074, 0x68339ee0,
+ 0x056d7447, 0x7ffc8003, 0xf40934db, 0x878c12d9, 0xafbe3058, 0x8be8fda7,
+ 0x24b20f60, 0x72bae768, 0xf298ed06, 0x07a664e7, 0x7dcfc9d0, 0x65e90b33,
+ 0x998d21e9, 0x4fad9aec, 0x3b7a431d, 0x505928d7, 0xc23577df, 0xb39f71b2,
+ 0x4034e4c6, 0x63a81cfb, 0x653b65fb, 0x03522527, 0x14fe907b, 0x286b3bdf,
+ 0x777b458b, 0xa33f73e2, 0xb5a5f8fd, 0x71870b12, 0xa2badadf, 0xe7ea1235,
+ 0xf9fcf1b6, 0x7fcf032a, 0x6b3791cf, 0xb47c6307, 0x312f3f96, 0x7bfe50e6,
+ 0x75662ed1, 0xaf65bc63, 0xa5f3fc89, 0x1579be35, 0xeb7cdb05, 0x5cbe2285,
+ 0xbcfbe754, 0x4f37c1a4, 0xc8a24c63, 0xa36148c3, 0x135a5e28, 0x22807642,
+ 0x77e46f4f, 0x397396d9, 0x61d7d8c9, 0x0f95ef18, 0xb9fd137d, 0x8867d791,
+ 0x2fd4077a, 0xa2f1c37f, 0xc94ca5c0, 0x1964882b, 0x23cc0cae, 0x3f719834,
+ 0x8bf9acaa, 0x73f98620, 0x89d3ed01, 0x29975f3f, 0x93636adf, 0xa569fb4c,
+ 0x3097862d, 0xff6cb0cf, 0x84c5ad49, 0xec887f70, 0x6398bb80, 0x6e8bfa3d,
+ 0x6fe44a95, 0x8ddc51b7, 0x52967ad9, 0x60d9bb7c, 0xf65afd46, 0x73adc7fa,
+ 0x625fbeb1, 0xd0e3c406, 0xa593a276, 0x5fb4c9cf, 0xc9f2d0cd, 0x8c89d0f2,
+ 0xbb3c4578, 0xcf3ed006, 0xe23bc432, 0xe78ef019, 0x34e7e41b, 0xbba5f784,
+ 0xb55f7a64, 0xed8b4ab5, 0x7e3939cf, 0xc8e7bc15, 0x45cf08ab, 0x4e7c702f,
+ 0x99feae7c, 0x5d83a400, 0xdf73b21a, 0x79837e82, 0xd03a1f3f, 0x77e3e21e,
+ 0xdf144bd5, 0x6683a3ea, 0xe01d1f5d, 0x07466f3c, 0x67a49fc0, 0x0607466f,
+ 0x4fe41794, 0x8a1a3b8f, 0xf8cfedf6, 0x9db8947c, 0x1f9b9712, 0x10fa59d2,
+ 0xd8884d34, 0x1b2cf647, 0x08955f60, 0xe4cce672, 0x74dc280f, 0x51eeca6a,
+ 0xff034f94, 0xbf9461f4, 0xfb7cf047, 0x444b7fe7, 0x331dd079, 0x18c1db63,
+ 0xae0767c2, 0x90383ba7, 0x923dd3eb, 0x3ae7a253, 0x93be0eb7, 0xf915720d,
+ 0xa3a9bd92, 0xa0f743f8, 0x893e1e07, 0x184f68fb, 0xc92e88ad, 0xe2bafdc6,
+ 0xc13e7796, 0xcc6b27f8, 0x7df8f9b6, 0x462b2fc2, 0x37df10bf, 0xb5e85f80,
+ 0x3f9928df, 0x4bbf7ea0, 0xcb75a58c, 0xf256eb2a, 0x0598eadf, 0xe5eb95ed,
+ 0xaff9233f, 0x686eafc4, 0x01e9f99f, 0x76e7fc8f, 0xf10c7319, 0xe5c0b73b,
+ 0xf71132d3, 0x71c8fa3d, 0x675c40f5, 0x53373f1d, 0x297202d8, 0xf8a5ce94,
+ 0xd13297c8, 0x19d23cfe, 0x472bf1c0, 0xec9501c5, 0x9d3e472d, 0xec94e384,
+ 0x2194e3e2, 0x981c20fd, 0xdc0099fb, 0x28697027, 0x84c4591e, 0x5932695c,
+ 0xe47e96dd, 0x7aed5d48, 0xe9fd7f34, 0x37ec18a7, 0x1d3f845c, 0xb6fa3595,
+ 0x97ca03fb, 0xd25f2411, 0x077f47be, 0x23d32369, 0xd4e5b247, 0xf5afe801,
+ 0xe400cb32, 0xb9e91be3, 0xdac0ada4, 0x38a6e35e, 0xb3ed4cf5, 0xa9f6615f,
+ 0x7c22b9a7, 0xb26c8fda, 0xe51fbcf8, 0x3f79f64e, 0xa7d598e6, 0xd636d99e,
+ 0x9f6dfda7, 0xb7ea7cd8, 0xb4fae7b7, 0x3cabe3bf, 0x2a6f7a9f, 0xf607e7ac,
+ 0x908aeeef, 0xb64fda7c, 0x07c67c18, 0x99f04e0d, 0xf3ec1c9a, 0xe1c8d7bc,
+ 0xef71a374, 0xab8efab6, 0x8cf7b9f8, 0x867f1df5, 0x5bdc77cd, 0xd00ec3c5,
+ 0x4d106a9b, 0x628f413b, 0xc0254af9, 0x86f1ec1d, 0xbfaa08ca, 0xd2a1695a,
+ 0xcf4c9955, 0x52b4ab5f, 0x2c72b1bd, 0x7d800fd5, 0xb026f58f, 0x1d7cb1f7,
+ 0x7e7c7cec, 0x8ab57833, 0xdf131eef, 0xcbbe2e3d, 0x076e16d8, 0xef2e04dc,
+ 0x4427fe8b, 0xafec36ff, 0x6961d0f1, 0x1aeaa66e, 0x90f8edf0, 0x2f8c5a0b,
+ 0xe7b796d8, 0xf3df9fa0, 0x03b6ccae, 0xf3bb305f, 0xea286558, 0x1f3c81a9,
+ 0x3de7af21, 0xed97178c, 0xfee3338f, 0x3fa6c6c7, 0x5df7c09d, 0x33c5328d,
+ 0x117d348e, 0xba5ce384, 0x503ecc06, 0x97a837e8, 0xfaa24dfc, 0x798f7826,
+ 0x82f793f8, 0xcb7a4b61, 0x52eb7a45, 0xd27752bc, 0x86bc8df9, 0xda76dabd,
+ 0xef4bdc57, 0xf5be05df, 0xd6b3bf79, 0xdb19bde7, 0xdab67ee3, 0xc5f77e49,
+ 0x373c6526, 0x97892fb5, 0xc5d23ce8, 0xc7ad6f9d, 0xbdd2be7c, 0x3ee2070b,
+ 0xc9c37160, 0x003fc5b0, 0x7607cbff, 0x2f5ca2a7, 0xf9c5966d, 0x695e3e23,
+ 0x891e72b3, 0x7e24bfcf, 0xca084e6f, 0x218906ed, 0x6ab12e7a, 0x6e2a8fca,
+ 0x39412faa, 0x573c9c5a, 0x9721f143, 0x3c01e22c, 0xccc4b0df, 0xbae67db8,
+ 0x35e7841a, 0x3a3ae0ff, 0xba85f31d, 0xc20ade5b, 0xf9e376ef, 0xdefc2f13,
+ 0xdcedc493, 0xdfb8927b, 0x2df1a974, 0xd1b93f3a, 0xbb8716f5, 0x3feb4dda,
+ 0x50ddea22, 0x649bbc12, 0x35e17f5a, 0x8ca0f099, 0x4c9260f7, 0x4a6e4de3,
+ 0x4ebae130, 0xf2f7f8b9, 0x79fc2c93, 0x9c7cc2fc, 0x3988f1ff, 0x95d93299,
+ 0x3ddf2e3c, 0xca3d6a7c, 0xe80fcc51, 0x047b0fcf, 0xb5f985c7, 0x77c63c8a,
+ 0x0eb5f7e3, 0xcf1fb806, 0x748a381d, 0x274fe280, 0x473dfb71, 0x3d478f6b,
+ 0xa168ca71, 0xdc9af838, 0xf7e21338, 0x3cf89608, 0x57da25f7, 0xdfe46a28,
+ 0x0b6e653b, 0xd53bba42, 0x3b464638, 0x40af1946, 0xbe8fb77c, 0x20e6f0fb,
+ 0x6b38153c, 0x078e388d, 0x7e79fc7f, 0x71e69992, 0x167279dc, 0x92a74bda,
+ 0x68cec903, 0xfcfdf2d5, 0xef6e06e2, 0xaa896a9e, 0x5bf6bd95, 0xba3e05f2,
+ 0xd7845593, 0x688d26ae, 0xf99eb737, 0x7c70d3b4, 0xc7cef9d5, 0x1278ecec,
+ 0x1792eced, 0x54933a64, 0xc308a9a2, 0xe6df9ff5, 0x0102bf3b, 0x3b8d12e7,
+ 0x5e8bcc2c, 0xf8fb9a4b, 0xde7448c6, 0x8589f0ac, 0xf1e0a9f0, 0xc73f3254,
+ 0x9f822a72, 0x5bd92a83, 0xd1ed744f, 0x19ae3cf7, 0xbf3c5ff5, 0xae7e66f6,
+ 0xf9780f62, 0x3cfd0c49, 0xa65c6e4d, 0xf7a3d62a, 0xbf6d137b, 0xfe841a4b,
+ 0x85f91e53, 0x8a26ec40, 0x3c7da08b, 0xa7efe500, 0x7b77e0cf, 0xd879f91b,
+ 0x11737d52, 0x5af5fbee, 0xbe604181, 0x4e34dbbd, 0xd118cfe1, 0xec2a5d4e,
+ 0x7b16f3d4, 0xa3fb8c96, 0xaeb455ab, 0x89d90692, 0x425d98f9, 0x1bde5dde,
+ 0x69d20f73, 0x8cd931c9, 0x5744cdfe, 0x65c7afcc, 0xfb26de90, 0xedc5ccae,
+ 0x129db2dc, 0x7d8ab5d9, 0x8bec2a51, 0x3d8ec273, 0xdb87bab7, 0xf62487b7,
+ 0xcec78c54, 0x45761528, 0x3d79bca9, 0x9ffb2be6, 0x396c2daf, 0xfd89e74c,
+ 0xef16d5cf, 0xba97adf4, 0xbf8aeb7c, 0x9f524ef7, 0xfe82927f, 0x94a7d809,
+ 0xc0a9f12f, 0xacafe2a7, 0x2386b348, 0x5b546fbf, 0x037128a6, 0xa1f95784,
+ 0x6f38857d, 0x95804967, 0x6f9587fc, 0xbfbb5c10, 0x77497ee6, 0x77f5a304,
+ 0xeedf0e33, 0xe5df4e26, 0xc7a9c91a, 0x7023a8fe, 0x5ce4bd3c, 0xa3a8768d,
+ 0x12e48837, 0xf7c1e1e6, 0xfee1cf96, 0xa3630da7, 0x855a9530, 0x29fd140f,
+ 0xa9decdce, 0xbd83976e, 0x2495c3e4, 0x124e776e, 0x4c2b48f9, 0x835fd256,
+ 0xc1ebb9c5, 0x0f6f6e7a, 0x53573b56, 0x6631fe3c, 0xf2714359, 0x4e90a303,
+ 0xf14eae30, 0x123d55ff, 0xeb1fc3c5, 0x063f9091, 0x7911ad9b, 0xf849f55e,
+ 0x0763d53e, 0x48f6330c, 0xc7ba9df8, 0xd73af894, 0x66d433ef, 0x894fce0d,
+ 0x87fb293b, 0x7394fcca, 0xf3e7ff08, 0x8cfcc333, 0xbe01f99e, 0xabff6007,
+ 0x0fb25619, 0xe72867a2, 0x1e482afd, 0x04bcf028, 0x70093ef4, 0xa41d3185,
+ 0x876d929b, 0x40fe7873, 0xcbdf9d1b, 0xc8ebe209, 0x39e3f911, 0x941cbc01,
+ 0x2b35f1cc, 0x9e8bc799, 0x3722a510, 0x85b649df, 0x2fb94325, 0x39322f39,
+ 0x62ce73d3, 0x9cfc07f9, 0x87bcbf85, 0x574f44e7, 0xee510f81, 0x3242b4fd,
+ 0x63d8fbc7, 0xf9cabf9c, 0x2a3e3ea3, 0xe225e0fe, 0xb5b0e613, 0x9e618725,
+ 0x05efe702, 0x78e60d2b, 0x1728be2f, 0xc5a6207e, 0x7297fee2, 0x5cc0be4e,
+ 0xec40e748, 0xe8ccc32b, 0x97cb9597, 0xafff5e28, 0x93795df2, 0xe06ddd6f,
+ 0x4936eff4, 0x9edcffe4, 0x13cf67dc, 0xfe0b463f, 0xb44bb5a8, 0x9dfb5c2f,
+ 0xe6dbc79a, 0xbb5f1449, 0x7cf21e1f, 0x60aed17a, 0xdd9be53c, 0x37da550f,
+ 0xfb1509ab, 0x9fb4a1d6, 0xf7589f77, 0xe2df22fd, 0x8315c6a8, 0xa5a3a0f1,
+ 0x3f8e2b7a, 0x7f68b987, 0xa36b1e7d, 0xd96074f2, 0xee0d377e, 0xfcfe8a18,
+ 0xc51d76c7, 0x6ed76aa1, 0x4f5ca137, 0xb8cd6b67, 0xd8a006cf, 0x5b98fdf9,
+ 0xf2538fdf, 0x0e2ec189, 0xfc04fa47, 0x7ffc46cf, 0x1889b805, 0xe2ff7d7d,
+ 0x3e53f68f, 0xfbc3e752, 0xd0c03d66, 0xff21eaaf, 0xb562a8a8, 0x1c4df686,
+ 0xcb392dac, 0xef055783, 0xf0fade0a, 0x1f16616a, 0x869ac2bc, 0x4be49c20,
+ 0xfd2e4833, 0x77a8664e, 0x0557866f, 0xf8113fee, 0xe5ccd659, 0x15be3f97,
+ 0xe7803c3c, 0xdf48e2a3, 0x313c236e, 0x7f4bc91d, 0xbe19b87a, 0xe1e73080,
+ 0x3aa189ab, 0x54a32ff2, 0x2d469e5c, 0x38be2895, 0xb50fd997, 0xf02b3943,
+ 0xbbd10d53, 0x813cdbc0, 0xf3998fb7, 0xff98e4ee, 0x93bdbc3d, 0x3c9d579c,
+ 0xf5be7ae8, 0xf11bd3e7, 0xfac58965, 0x3a5f4547, 0x1fa3f219, 0x6bf1fb3f,
+ 0xf0ad1e1f, 0xda3c2f3f, 0x5f110657, 0x6e5be1f6, 0x88bd35b8, 0xaa1c607f,
+ 0x716bdf89, 0x60957e53, 0x57cf8021, 0xa6f57d93, 0x2e053782, 0x9deb8a37,
+ 0xc23b72d6, 0xfb4c88f1, 0xee499f98, 0x639466a3, 0xfce8a729, 0xb3fed29b,
+ 0x1f436dd5, 0x1b3e7182, 0x5ad3cbcf, 0xd4a91f9e, 0x3e3c016d, 0xcea459f8,
+ 0x4cfdeb81, 0xfa80994a, 0xbfe933e2, 0xb87af3a6, 0x39f582d6, 0x50cc13e1,
+ 0xe251ad3f, 0x7c446b89, 0x67e549c0, 0x449b6e73, 0x36f624ed, 0x3f9f8ef3,
+ 0x7cfc512a, 0x9c728801, 0x6784cc5f, 0xfeaf3173, 0x46e3cfcc, 0x72df3ed1,
+ 0x1f50f1df, 0x921c50c7, 0x5e778bfb, 0xf42cd1eb, 0x7a7d3bd2, 0xfe15d270,
+ 0xce933f3c, 0xd808161b, 0xb85242da, 0xe7e4ec7f, 0xd33d1536, 0xd19f6c7b,
+ 0x417a4e3b, 0xeafb95c4, 0x7b444f29, 0x3bc3a9eb, 0xe388957e, 0xe91d6814,
+ 0xabfb7e78, 0xd1a3e7da, 0xf1d8289e, 0xb7d92278, 0xa226363b, 0xfdb0529f,
+ 0xaa368957, 0x4fc9da07, 0x7775f352, 0xa5fdb9ee, 0xe77a5e4d, 0x6fdce1d1,
+ 0x9c3fa799, 0x94ee768d, 0x61d79711, 0xe7e13e3c, 0xf387dd12, 0x0eb6d653,
+ 0x64fcdff5, 0x46acef4e, 0xe199724f, 0x73c02df9, 0x75ddca7d, 0x93c7a7c8,
+ 0x43e4d0bf, 0x9a8a5d3b, 0x399f33e0, 0x7ee38737, 0x5cc906f6, 0x0fdbbccf,
+ 0x85cafda5, 0x446d256b, 0xe0b7ea28, 0xea3fe851, 0x1e698252, 0x6a8c368b,
+ 0x57f3e7c5, 0x7453e7f1, 0x3853c6ce, 0xca5ab3ce, 0x10f90237, 0xafc79deb,
+ 0xf1e7e14b, 0xc8966c17, 0x93be57ae, 0xad584cf0, 0x29753af7, 0xd4672f42,
+ 0xce51dc91, 0x755b4e09, 0x1808edf2, 0xbb6a9ff7, 0x39c60529, 0x78b9f4f1,
+ 0x149f3c37, 0xfd152172, 0xfdad049b, 0xeeb885b7, 0x83ca3aed, 0x928f48cb,
+ 0xe8fda1c3, 0x853fc787, 0x0b5582e5, 0xf2885b7f, 0x147eab71, 0xf3e6174f,
+ 0x55592e5b, 0xaadf3f28, 0xc211607d, 0xf5a7abed, 0xaf2f9764, 0xfd670a4d,
+ 0xbe528ff0, 0x8dc7f80c, 0x7a955d82, 0x9a57772a, 0x9eda3ce9, 0xffaa08ca,
+ 0x2542d2be, 0x6be9cd9b, 0x8dcb99b9, 0xe6378d1b, 0x80b3205a, 0xc1b19abd,
+ 0x70632cc0, 0x9c96ce5f, 0x18487002, 0xa37dba5e, 0xa56e1758, 0x4cc4728c,
+ 0x6c643844, 0x4d15a87c, 0xee14d0da, 0x6a77bd67, 0xedf23443, 0x2f1d55b2,
+ 0x537ae216, 0x7f6146f2, 0x142bb6fd, 0xf9ab7837, 0xef08f9f1, 0xbe3aed82,
+ 0xafeeb13e, 0xff0c4e9e, 0x78ef8c2d, 0x7c7e4357, 0x178eb6f9, 0x78b94237,
+ 0x6f5a43f3, 0xf5d5bf7a, 0xfbe14c8e, 0xabe3379d, 0x5fe1c11b, 0x455fabe7,
+ 0x7f6cff13, 0xf9e1ee9c, 0x7caaf977, 0xdf826ad5, 0xd9bc94ba, 0x695f5f48,
+ 0x4fc8d11c, 0x98fca55f, 0x4871dce8, 0xf22bf822, 0x4b3fe955, 0xe558bfc0,
+ 0xc62e3cda, 0x61bf5f23, 0xc3df0419, 0xd113e7cd, 0x69a6fdae, 0xfbae0fce,
+ 0xb7bf2540, 0xebe009a5, 0x52882f7d, 0x71ed6966, 0x965f5856, 0xffe0c738,
+ 0x12a291de, 0x6fdf2cf6, 0x57927fc7, 0x17e8077e, 0x4f9800c7, 0x0ee48b49,
+ 0xe9ae3f40, 0x20ea0bae, 0xfb1233d4, 0xc91e27dc, 0x7a5ee7d8, 0xbdf346f6,
+ 0xe3865959, 0xeee47824, 0x7ca89f6d, 0xbdb963ee, 0x7ee7c03d, 0x03ff3e93,
+ 0x3f69699e, 0x3956b227, 0x4c7980bf, 0x7429cd5d, 0x9682e25e, 0x00ebb1e3,
+ 0x3e3c39d8, 0x7baf64c3, 0x77342e22, 0xf59ca3a6, 0xebd96f5f, 0x251f449d,
+ 0x215f8f4d, 0xf269b63f, 0xcdfa7505, 0x47787fd7, 0x71dbdd27, 0x859ed341,
+ 0xb69754fe, 0x50f11d3d, 0xe79706f6, 0x941c2aff, 0x601b85e7, 0x65e7c021,
+ 0x24e89e92, 0x7144be5b, 0x3c63ae81, 0xfcd6502e, 0xded3c912, 0x29971e16,
+ 0x84e5b557, 0xa2a31c63, 0x59e515a3, 0x93f7046f, 0x09bdc4ca, 0x1e84e2e3,
+ 0xe344f754, 0xd8b70e79, 0x3bfc5627, 0xf90187bc, 0x2ae55cb5, 0xf4a5fca1,
+ 0x2dfb8640, 0xe19f9117, 0x3195fcf9, 0xbfce91eb, 0x8d1a0e72, 0xf4bdf1f2,
+ 0x1c5197bf, 0x66810fef, 0xd911ec99, 0x6fbc2f27, 0x27994e1d, 0xaec530c8,
+ 0x8bc9f409, 0xee5ad72e, 0x38f67b21, 0x1f2b7fdf, 0xbd89f9ce, 0x74a9f9ce,
+ 0x846d61ed, 0x820d78d7, 0x6efb149f, 0x4efe1fca, 0xd138797c, 0x92f91c76,
+ 0x78e215ce, 0x929c0311, 0x7965da24, 0x2d8d1bf6, 0x95cfafc2, 0x93797de9,
+ 0x8e5f70cc, 0x2f289845, 0x53559720, 0xe614e57e, 0x339b471a, 0xf127f6ea,
+ 0x7fa99b5e, 0xfe60c790, 0xb441f816, 0x60139d7f, 0xa6fcc78f, 0xc0492ad3,
+ 0xc33195d5, 0x87e99f4b, 0x4e353d73, 0xf58f4896, 0x9d920644, 0xe9767932,
+ 0x69fb6f3c, 0x83b78ab4, 0x626ec871, 0xae7e1ece, 0xee93ddc6, 0xacc8ef7d,
+ 0x9056043f, 0x8cae645e, 0x89df5e59, 0xe6f5ce1c, 0x06ffdc55, 0xfb17293a,
+ 0x77f2d9ac, 0xbd3da0cf, 0x5fdf10fc, 0xf98aad3c, 0xe8b3f318, 0xe784b6dc,
+ 0x7939f9a3, 0xbc366766, 0x6d2baf67, 0x2a079d10, 0xcc3123df, 0xd66b2b73,
+ 0x5138c76d, 0x0c3da699, 0xd36379e9, 0xe7a45a47, 0x4d77dc72, 0x79abe7e3,
+ 0x724f5cdc, 0x48ccdcbc, 0x2536957f, 0xbbf18c7d, 0x8b5c63d2, 0x924faa96,
+ 0x1b728e7f, 0xb8dc57bf, 0x12f1fc97, 0xbc7f26e6, 0x6e97c1a4, 0x8ffa237a,
+ 0xb70e47df, 0x3233dcf8, 0x8fe72b79, 0x325ee259, 0x93b0e226, 0xbd6bc223,
+ 0x0a4531cf, 0xcee4d83c, 0x74c76875, 0xbc564ac7, 0xc03ba697, 0x23ed16b1,
+ 0x6bb72247, 0x9ddcdfba, 0x8be494b1, 0x34dee333, 0xdb8757bc, 0x6c3793b1,
+ 0xf35ecb51, 0xe3ee2c99, 0x05600eeb, 0xf6ef0807, 0x908f8821, 0xe1a8bca4,
+ 0x9e3ee883, 0x7c607713, 0xf27b9c48, 0x446fc75f, 0x38b8e85c, 0x7bcca9bf,
+ 0x9714546a, 0x7449cc67, 0x19ce2ad4, 0x4a367929, 0x1eb10aff, 0x3d077ec5,
+ 0xfb43fe1d, 0x934fb825, 0xf269f62f, 0xbe4d3ec5, 0x17c9a7d8, 0x62f934fb,
+ 0xec5f269f, 0x7d8be4d3, 0x4fb17c9a, 0x69f62f93, 0x0d3ec5f2, 0x54e2c3e5,
+ 0x11cdff31, 0xd1ea34fb, 0xc1b5e456, 0x10e9fa9e, 0xdf60fabf, 0x2443a7f6,
+ 0x8960fadf, 0x257c4fda, 0x118769f6, 0x2166a3e3, 0x547c789f, 0x2a79df39,
+ 0xe1193ed0, 0xfce79cac, 0x03a9f72a, 0x42934fc8, 0xd9bf90e6, 0xca26fe0b,
+ 0xf6e1caa3, 0xec776c3c, 0x2df8c4d8, 0x140d2724, 0xe0fd3ce7, 0x98739f08,
+ 0xacc793e3, 0xc6307bc5, 0x7e71251b, 0x9e647abc, 0x38c1ffe2, 0x66165b13,
+ 0x307cb9a8, 0x2d9cbda3, 0x77e3e497, 0xc61a4796, 0x24d61ca0, 0xf70ee7db,
+ 0x8339db92, 0x5da3c597, 0x7cb1aad4, 0xc75af18c, 0xbf3a1a07, 0x94f5c4ab,
+ 0x8d25ef76, 0x937ec42f, 0x8ed6e393, 0xfcf5f1c6, 0x969b38be, 0x6cfce035,
+ 0xee8940aa, 0x3516616e, 0xe1c283ca, 0x58266e9c, 0xd6ec7db8, 0x1821d45a,
+ 0x1f18098f, 0xad13798a, 0x04c7cf02, 0x3c0b8f9e, 0xa4d77ee3, 0x85dfbe04,
+ 0x6177ee25, 0xd58de4a9, 0x1f2de4a5, 0x27b4f24e, 0xc4ace11a, 0xe728a6fd,
+ 0xee8b98fc, 0xd0517c33, 0xbe70d26d, 0x7261f2cf, 0x09c3a3de, 0xb73a2e3f,
+ 0x69e22c59, 0x437f629d, 0xcfd2a759, 0xfbf19fd3, 0x0732465c, 0x83b367ee,
+ 0x08764f22, 0x9f5023d8, 0xe49c3079, 0x7a1e7290, 0x07ee18e6, 0xfce27db0,
+ 0x13258462, 0xc44aa3f9, 0xfc9cbb53, 0x48696d1c, 0x239e225b, 0xa57c12e8,
+ 0xd17395d4, 0x6ea1a3a5, 0x284b9cf4, 0x8896d99d, 0x24ba12e7, 0x0dce8a83,
+ 0x4fefe76f, 0x8d2bbe09, 0xf729e315, 0xd15de84e, 0x43ee8788, 0xbcf1a307,
+ 0x7ba326dd, 0x6efb9729, 0x2811de7e, 0x3a96f316, 0xcc19d725, 0xf7747dcf,
+ 0x1e63f71b, 0xf5c6a77d, 0xdb1fd622, 0xcc7ee87d, 0xf694edcf, 0xbf7b319e,
+ 0xc68ae41f, 0x7747ddfc, 0x83f7f0b7, 0x6c18bef6, 0x5e6baaf5, 0xb5ef833b,
+ 0x8fdd0e6b, 0x7553bcf9, 0x489563ce, 0x74e7bf2f, 0xffb3d865, 0xb8adc21c,
+ 0x13eddb99, 0xf4bfecf6, 0xfde5ea1a, 0x3fefda26, 0xe0863c38, 0xf2fcd55d,
+ 0xaeb3a466, 0xbfde3cbd, 0x17a3e1a9, 0x74ed417f, 0x54dc0d74, 0xc1832b9d,
+ 0x9eecd677, 0x1a9af34b, 0xeb1afae8, 0x46388d4f, 0x903a98f3, 0x11d6f3f3,
+ 0xe78fddef, 0xeff6ba01, 0x6ef90479, 0x683000ea, 0xf9bb3e71, 0x7da2a0f9,
+ 0xbfd09329, 0xcdb532ef, 0x5ecbf1c7, 0xf339d1d1, 0x74e17da2, 0xc3dbc72f,
+ 0x9939f963, 0xa8d1d5e1, 0xefaf5567, 0x508bf1da, 0xfda0676c, 0x6e10f29e,
+ 0xb5c915e7, 0xfe110f59, 0x3cf1da5e, 0x81977bce, 0x310b5ff6, 0xc2f502a6,
+ 0xa714091d, 0x5f1fe37f, 0x643c47cc, 0x7ce8dbcb, 0x0675d7cf, 0x94e1c215,
+ 0xcf0036d6, 0x694e38d3, 0x142cdfc8, 0xfcd3c2f5, 0x60517dbc, 0x2fe10e7b,
+ 0xf51a3ab4, 0x47c0d16c, 0xa7bce3a7, 0xa22fd5ca, 0xe65ec3bf, 0xd85dc6f7,
+ 0x7e837005, 0x9435ea17, 0xcbb5daad, 0x3be2e744, 0x78f9eaa5, 0x9ea3893f,
+ 0x5434ebb7, 0xf51d3c13, 0xb4defc49, 0x48e8305d, 0xe7c5b76c, 0x97fa85f9,
+ 0xbd1fd1d3, 0xf254caf8, 0x55fa154b, 0xcea8a5f8, 0x3f1d7cff, 0xfe245ab7,
+ 0x33076666, 0x2e93c57a, 0xebae781e, 0xffd3ccb7, 0xce868362, 0xd8ea1779,
+ 0x560fcc5a, 0xea28a1f8, 0x5f5c5cae, 0x1136aa91, 0x31c296ed, 0x2f91f3ed,
+ 0x3e98182e, 0x27bdda02, 0xe35155f4, 0xff6819ea, 0xa63e68de, 0xbf8f9c11,
+ 0xeb7ae089, 0xd383269b, 0xbfd1bf7b, 0x9992b4fc, 0xd4f04fdf, 0x7be15a7f,
+ 0xad3df0de, 0xb4fd04ab, 0x3f2e10b2, 0xbc7b40ce, 0x7c502e93, 0xbf4ac167,
+ 0x78239273, 0xb699645e, 0x9ef5113d, 0x863ffe32, 0xa85db99b, 0xb7fba76e,
+ 0x454dfbfc, 0xc8e50473, 0xb79e7e6e, 0xa0ea51a8, 0x52082273, 0x8b667baf,
+ 0xe6270ef4, 0x8787f509, 0x07812c88, 0x11b9eb18, 0xa28f3431, 0x079d0306,
+ 0x0f680e2f, 0xc4a93b42, 0xf6841ed4, 0x32ebd74f, 0xe889c3dd, 0x8fc6550b,
+ 0x894f7cf5, 0x34ba1613, 0xdf7f4336, 0x1c60e583, 0x0dfe1972, 0x047578a0,
+ 0x682a27df, 0xcfe7e40a, 0x1e74edcd, 0x263cffdb, 0xc5ecd3ae, 0x2f4d5d8f,
+ 0xe9fb7985, 0x797047a3, 0x10752dd0, 0xe3ff74df, 0x83a468f3, 0x8b5b1522,
+ 0x251795fb, 0xea022e7e, 0xa2e21e74, 0xfa2cf7d8, 0xf48018d6, 0x129bf173,
+ 0xa92ee3e2, 0xfb5ce49d, 0x7c933fee, 0x93b4d2e8, 0xc468fb9c, 0xe8fc937f,
+ 0x8f9f6e0a, 0x447dab72, 0xd91f7f0f, 0x23cf1f3e, 0x7c7589bd, 0x81fff78f,
+ 0xfddaeffe, 0xefa8fded, 0x8f3ccaa7, 0x31a4bd82, 0x8710f8f3, 0x270132f7,
+ 0xae9c36c6, 0x6343ff24, 0x2dd0fd41, 0x166f03e8, 0x98fe5e64, 0xcc5d4fc2,
+ 0xf911a7b2, 0xc7df80b3, 0xc3557603, 0xcdff686b, 0x84fba309, 0xeca6e1fc,
+ 0xfc868633, 0x69e2296d, 0xc0fec986, 0x69538008, 0x17f93b6a, 0x87a4ed40,
+ 0x91d4deca, 0xe9add99f, 0x2bf281d9, 0x8b9f64c5, 0x6db44aed, 0xbc2433eb,
+ 0x15bda0a7, 0xca29fa4d, 0x3997c7f9, 0xbea575bd, 0x884dcfc4, 0x8162ca7d,
+ 0xb25bbc07, 0xe243e916, 0x69ab7e78, 0x6f28fbdf, 0x48e2daba, 0xd3f3fb4e,
+ 0xe8a7a685, 0x404f8a9e, 0xe2bc3baf, 0x7c2c9f00, 0x6601f299, 0xf1881e63,
+ 0xbdbe73fa, 0xfe4bdddf, 0xf5ecdb20, 0xc6b1e91c, 0x170feeb7, 0x0fb74ba4,
+ 0xde68381f, 0x00df903b, 0xda13c5fe, 0xbe877ee8, 0xcba84cfa, 0x7e23f55e,
+ 0x78f6bf75, 0x0fda005f, 0x505d843b, 0x9a7dd432, 0x3c3df7fc, 0xf40ab76f,
+ 0x07f7d51a, 0x6aa57e52, 0x50ade80f, 0x5f50b7ae, 0x51b50714, 0xbf6baadc,
+ 0xd779f68e, 0xc68f9f34, 0x523d03f5, 0xf9b8a67c, 0x7ccbdd20, 0x4c87fd10,
+ 0x94618fd2, 0x39bfb317, 0xe510fd0c, 0x95ca8979, 0xd3f5f228, 0xcf287e51,
+ 0x2277654b, 0xda95f39d, 0x8388fee8, 0x2a25de62, 0x1758cba8, 0xdf3896f3,
+ 0x2f7e66b3, 0x5ede3f96, 0x76edc119, 0x9f740f90, 0x79d79ae7, 0x079140dc,
+ 0x1cae4285, 0x9ca9e7c1, 0x3ecacdff, 0x442d7411, 0x4e47efbe, 0x0b308f24,
+ 0xe282b87f, 0x58463b3a, 0xa7f45d78, 0x89dc7971, 0xd1bd97de, 0x8a9b1e99,
+ 0x3dca2cfd, 0x14791e5f, 0x282f91e7, 0x0e482207, 0xc184d1ac, 0x945e8aba,
+ 0xc2a2fee8, 0xa073ab79, 0x7ea65b39, 0x2d49ee88, 0xe35bbcc0, 0xa7f2f3f5,
+ 0x57b8f1a3, 0xec52f288, 0xe0ed1503, 0x351740fb, 0xe40d1f7c, 0x2ff5e50d,
+ 0x073ab49b, 0x68496ff9, 0x4fdbd6a9, 0xd7f8d9be, 0x58af5b9d, 0x0fde139d,
+ 0xdcad179f, 0x5d883ad2, 0xbda15e3f, 0x72cc2736, 0xde6573fd, 0x3cca0d17,
+ 0x79066827, 0xeaf663c3, 0x734fbc1c, 0x85dffe99, 0xc5f75f07, 0xf51b9d66,
+ 0xf697c02e, 0x56bcee83, 0xbd5f13e1, 0xcc8578d9, 0x371ffb49, 0x597fbf9a,
+ 0x534fb922, 0x57f02d5e, 0xf9d9f13d, 0xa0fdef68, 0xf6be4229, 0x160a25c5,
+ 0x407ba30e, 0x79870bec, 0x4bfc25c7, 0x55839410, 0xa0e23394, 0xbe70f812,
+ 0x28781fb5, 0x0467ffed, 0x329a4fcf, 0xe0d5f382, 0xbdcfc5a9, 0xa39e28c6,
+ 0xe3741d4e, 0x54a621f3, 0x7cb74fce, 0x2062643e, 0x60c8776f, 0xf74fb8c6,
+ 0x5c51bfa1, 0x719d7bb8, 0x306fdf36, 0xdf7848b2, 0xddb6911a, 0x8afbfe3b,
+ 0xe7814738, 0x7efce9be, 0xe387e6b2, 0xbea6a94a, 0x1bd912b8, 0xcfb481a9,
+ 0x9574d5d2, 0x4b775bf4, 0x43f719a6, 0x469cdaba, 0x7ff2b7e4, 0xea184ffc,
+ 0xb396aee1, 0xf5d69794, 0x57ca79dd, 0x06f228db, 0x7c89348f, 0x098b36af,
+ 0x7ee7779f, 0x36ed8391, 0x5713d289, 0xa53171e0, 0x2565fc54, 0xff75e07e,
+ 0x6b8428d1, 0x93e379bd, 0xa60f3019, 0x1ddfa6af, 0x0439ff00, 0xae2787f5,
+ 0xa1ff0960, 0x2b8c4a3c, 0xb8f027c4, 0x57189602, 0xb8f0d788, 0xae31d602,
+ 0x15c62580, 0x15c639f0, 0x05718eb0, 0x015c63ac, 0xc05718eb, 0xf80ae312,
+ 0x8e716bfc, 0x378c1ba3, 0x9234f71e, 0xcf515ffc, 0x88576bf7, 0xd457a1fb,
+ 0x85b7944a, 0x0f5038e7, 0xd3c7975e, 0x5c78f228, 0xb03f685b, 0x456cbf7c,
+ 0x0f79e154, 0x79f30e87, 0x3c628e7a, 0x64af7ca8, 0xe7c16d5d, 0x1b1e69b3,
+ 0x9e3f325b, 0x35ebcf87, 0xac97bc56, 0x309be5bb, 0xb515778c, 0x6adc53d4,
+ 0x2d21f852, 0x6241b9e1, 0xa59d6f18, 0xa9727ee3, 0xd3474f0c, 0xd1d929be,
+ 0xf236baa5, 0x4a778a5f, 0xddf3ef66, 0x90af63e5, 0x9bcbe89c, 0xf9cc1972,
+ 0xc6d5fa3e, 0x4ff0aef3, 0x57d88fc4, 0xf49bca5e, 0x3d9159e5, 0x2d1f65e2,
+ 0x7c64fdc5, 0xe7477f2e, 0xd1c14a4b, 0x93f5281d, 0xcfb7e587, 0x77b2d45c,
+ 0xe29bde3d, 0x77dcdfbf, 0x9f6fcf5e, 0xd8aa6579, 0xcfc51e4f, 0x9d3ee489,
+ 0x7c3f67bf, 0x475ab7af, 0x70e54af6, 0x266a657b, 0x28d86be6, 0x90f472ee,
+ 0x2fadfc81, 0xc4f924b7, 0x21e5b25d, 0xae58f714, 0x6b8f4891, 0xb0ebed92,
+ 0xc5dcc4df, 0x18996f14, 0x567e2261, 0xa4bdf0e8, 0xfdf1c7bc, 0xc50b34f2,
+ 0xec75b2bb, 0xc89e3467, 0xf89282ef, 0xa24abb2d, 0x3217a97b, 0x597b9d2b,
+ 0xf2f7e360, 0x2de8f729, 0x41cf3c60, 0x5be5aba1, 0x282bb224, 0xfb861100,
+ 0x0b9e1c9d, 0x7ba1de5a, 0xc4eb164f, 0xbe2a7e3d, 0x89b51e1f, 0xc12cbfe7,
+ 0xdef0a41b, 0x58abd010, 0xb37d9e82, 0x03db9e1d, 0x3b734487, 0xe38e12df,
+ 0xa1ae3c2f, 0xf0ece13c, 0xa4ed13bb, 0x3e5127ef, 0xf6ef5e03, 0x921f88fd,
+ 0x0cf9bea3, 0x43793547, 0x48addd70, 0xb1e714a7, 0xb2bc7953, 0x9e254a80,
+ 0x762fe4a3, 0x17b83a1f, 0xce5d9fbf, 0xe1bde5ef, 0xfe80bd79, 0xe729adcf,
+ 0xf9145e15, 0x53aa5175, 0x75fcf063, 0x2b46b7d4, 0xfc3b3fae, 0x8af79d10,
+ 0x4e1fe313, 0xe5037bcc, 0x39882d8a, 0xcbee1fb0, 0x733c0354, 0xc6120170,
+ 0x3c365dcd, 0x4873d337, 0xf51e5332, 0xcb73f275, 0x29efcc3a, 0xdee8978f,
+ 0xea809cf0, 0x3f1830ec, 0x8ac63627, 0x89bcbbf2, 0xa0bb5dc7, 0xc3bf78e4,
+ 0x3181f749, 0x14d73f7e, 0x2490b781, 0x4cd489fb, 0x82a9f3cf, 0xae5bba6f,
+ 0x9be1fcf2, 0xe8eb65c7, 0xb06613be, 0x21b1f72a, 0x188ea7de, 0x8559f14a,
+ 0xc21b7a6e, 0x7cdd23b7, 0xbcc3f42e, 0x68352779, 0x6c987c3f, 0x30e10cff,
+ 0xbacaff3f, 0xff675a30, 0xcf2531f1, 0xa63e3fde, 0xabffedc8, 0x2bf7fafc,
+ 0x513ca82b, 0xb6ca92b9, 0x07bd074a, 0xea75f0bd, 0xff55c5ad, 0x8ff5f08e,
+ 0x65bd32ab, 0xe057e900, 0xf6c71e6f, 0x5f02a38b, 0x7af8bcab, 0xa2f04b62,
+ 0xd47f680d, 0x4ffee968, 0x615e77cc, 0x49a03924, 0xaa9e37eb, 0xf148cdc0,
+ 0x18665ed7, 0x909ff08d, 0xc156a71c, 0x926901fb, 0xf200fecf, 0xf90fae09,
+ 0x13e44b04, 0xf3dc57b5, 0x70b02d05, 0x1c07b706, 0x08180f64, 0x8357ebaf,
+ 0x1ef090fc, 0xfc8fb325, 0x3f27e4b8, 0x907971c0, 0xf0b57dce, 0xef2526fc,
+ 0xd7140273, 0x4f23f746, 0x0c9e5c5c, 0xc2ed700d, 0x0b2d0cef, 0xa3e2bca0,
+ 0x475f4e1a, 0xb9bcf237, 0xefc7967c, 0xae5eba6f, 0x163e2104, 0xf339ec0f,
+ 0xfc5fb43c, 0x35d9232b, 0x669723eb, 0x257227fd, 0xc3c38d20, 0x63258131,
+ 0xcacdf27e, 0xe045ee7e, 0x314e66f7, 0x2e5b9f91, 0x7cb2a0ec, 0x72a7f133,
+ 0xed4cb43e, 0xed8f58ea, 0xff3c4d42, 0xbee8cd43, 0xc1aa5396, 0xc1599efc,
+ 0xc4a6a767, 0x58605e51, 0xa887bf15, 0xee896ee7, 0xc8149e03, 0x56c857ef,
+ 0x0cbc95e5, 0xb956dfef, 0x54c1efc5, 0x122bf8d3, 0x73d15c79, 0x6bdb951e,
+ 0xba26b951, 0xbaf6413f, 0xc631a93f, 0x39f45eeb, 0x6ecfbefc, 0x4dff72a7,
+ 0xa087bcde, 0x7e1ccd5f, 0xb33766cf, 0x03fb813c, 0x7100828e, 0xb5e8127f,
+ 0x99fdcf0c, 0xedc9fe07, 0x15429ebc, 0x19ad539d, 0xeb8d5965, 0x42cc79aa,
+ 0x27f73def, 0xe8dcf871, 0x82db9c3e, 0x8369f9ec, 0xe717bfae, 0xce6f2919,
+ 0x669fec12, 0xe34ff7e4, 0xeed08de5, 0x4fe19ce8, 0x0e3840ec, 0x3da264b1,
+ 0x706c68be, 0x11f40496, 0x06f306a5, 0xd4630fe8, 0x46d05f74, 0x71f313b5,
+ 0x7dc5a887, 0xef216a01, 0xd180c861, 0x85a6ded4, 0x96a7c2fa, 0xabea1b31,
+ 0xf3f74628, 0xfef9ebc6, 0x5863f438, 0x4646b862, 0x7c78c83d, 0x3e00e168,
+ 0x4670c2fe, 0x45a5cfbf, 0x3bf25016, 0x2677f0b3, 0xb0bbc518, 0xea68d07f,
+ 0xfef150ef, 0xc3943536, 0x523df8e2, 0xb474eb3d, 0xf1f0ba2f, 0xa71fa4a1,
+ 0x773df04d, 0xe78d327f, 0xb8e5282d, 0x9f0f8b74, 0x429b5a2f, 0xd68b8bfb,
+ 0x3b4529ce, 0x4810dec4, 0xef3b02e7, 0xef0ba97b, 0x9d962f71, 0xf5823f4b,
+ 0x57b74ecc, 0x4a2f7c23, 0xa1fbf996, 0xdffba2c1, 0x8c9e62d2, 0xf2e335dd,
+ 0x774e50eb, 0xf7813dec, 0x4fbf4de4, 0x19d3fea6, 0xad9a8fbf, 0xde6cf7e5,
+ 0x8ea2b8ed, 0x1eeff180, 0xbcbc5127, 0x468e60c3, 0xc0a16efb, 0x5c69f3d7,
+ 0x3f5c2f7e, 0xebfd1134, 0xbddf71bb, 0x5a733d1f, 0x0fde53b4, 0xfc7cc89b,
+ 0xfbc54f9b, 0xfef8d34f, 0xfe38b0fc, 0xae837f3e, 0x4b082e23, 0x4a093b8d,
+ 0x4ec2758d, 0x58b4cf5c, 0xe115b396, 0x378f28f8, 0x9b981876, 0x8d3eb1e8,
+ 0x3d676ae0, 0x3ae38f1d, 0x3ad046ea, 0xa39bc63a, 0x710e5ee9, 0x3312eb7f,
+ 0xe31d4f97, 0x98ce77f9, 0xa9214ddb, 0x1ef07f9c, 0xa502c5d7, 0x3d565767,
+ 0x5bb41b79, 0xe74f4abc, 0x7d3c9735, 0x8b2bf92f, 0xa73a646b, 0xdefb36c9,
+ 0xc4fa0ae3, 0xbff3f38d, 0xdeffd58f, 0xd239c455, 0x8966fe41, 0x955868e8,
+ 0xf1fb8b55, 0x4ec05b3d, 0x46f9f780, 0x05da3c77, 0x758356f9, 0xbdcfd48d,
+ 0xdc01dfac, 0x6b9ef0b2, 0xcf93f146, 0xe01fedd3, 0x2f561777, 0x03507ba4,
+ 0x1714ed53, 0x217e061b, 0x48413fda, 0x69d7003f, 0x7fba5e00, 0x891edd42,
+ 0x34facffe, 0x9cc43cf1, 0x34ba2468, 0x0ee7e430, 0xe711398d, 0xa0ceb1d7,
+ 0x6d319942, 0xe04fa70d, 0x347abd1b, 0x0160339e, 0x4bbfbfc8, 0x6f3974e3,
+ 0x16af3ab5, 0x6d4043ea, 0x6e90429b, 0x4e7d1146, 0x50ebdab6, 0x18f57daf,
+ 0x73728b1b, 0x7c2de6f1, 0x4cff025e, 0x34e746dd, 0x198faabf, 0x0a06798d,
+ 0x4eb64c3d, 0x4de69b38, 0x8449f707, 0x31cf587f, 0xeb1a37d4, 0x2f5c4ea2,
+ 0xf48c3f3c, 0x9b826d31, 0xe5b212f2, 0xbcfdfa12, 0xf74608de, 0xce32f4f2,
+ 0xd41bbdaf, 0x391467a4, 0xa003c8a1, 0xd39e1b07, 0x7ffdf055, 0xf2287f65,
+ 0x7243e006, 0x8a1b9145, 0x4be8517c, 0x74fe3391, 0x7cc01f35, 0x4fea68e7,
+ 0x63914cf2, 0x68d50eb8, 0xf0517c8f, 0x5e30d9ac, 0x81577145, 0xd2f96ce7,
+ 0x8708839e, 0x2dd92302, 0xea31707d, 0x5ad12e09, 0xcff784d6, 0xb7943d56,
+ 0xe3d22977, 0xd063732f, 0xe05b98fe, 0xa7f29e7b, 0x28e7be15, 0x3df4ac17,
+ 0xe56f3947, 0xfc628e9f, 0x0fb00d89, 0x9cfc074b, 0x17b9e5f9, 0xefea863e,
+ 0x8131797e, 0xea97d9fb, 0xaeefc59f, 0x68f3100a, 0xa55af3e7, 0x4c31bd25,
+ 0x0ff881d8, 0x7188b2f1, 0x13185d3e, 0xdff5027c, 0x093f105f, 0xf1c1ffb8,
+ 0x67e04673, 0xe80fc211, 0xae3ae17e, 0x121c3a97, 0xad1623c5, 0xc1ba7c15,
+ 0xe7f47cf7, 0x303dac91, 0xfa8e73ce, 0xa312c7f3, 0x7395af91, 0xfc0df6d3,
+ 0xf2b4b55c, 0x762fd918, 0x872d7ee5, 0x2b5afddf, 0xebf9f95b, 0xcd73df76,
+ 0x2d361981, 0xf7182bc5, 0x1f2516a3, 0xd536f9e1, 0xbbf71992, 0xfcf3c5f3,
+ 0xb9cf920d, 0x1e749cb9, 0xa698da17, 0xa3b63c26, 0xcaf1429d, 0x0a2fd26a,
+ 0xa0dc829d, 0xd5f97c73, 0xbd4bb4a3, 0xf122e8e4, 0xcab2717c, 0x36d777e7,
+ 0xebfdf1a6, 0x181a6476, 0xac725377, 0x3bc90976, 0x9547c50b, 0x47928bf6,
+ 0xc1b8c7af, 0xebf8cda2, 0x33fe9e47, 0x367cf9d3, 0xdc94f98a, 0xe5f7ce40,
+ 0xb79fe155, 0x9fc9bcd3, 0xf7757a2e, 0x033bf8ab, 0x91d57f45, 0x291a299e,
+ 0x9d53d9f6, 0x3ed2f759, 0x55d73f32, 0x693df026, 0xe84167f7, 0xf2379427,
+ 0xeca1b2fb, 0x556cb2c0, 0x65fbf901, 0x9087e056, 0xdfbff3eb, 0x41aff57e,
+ 0x88ecbe3c, 0x47ffbf12, 0xd65563bf, 0x1fc505f8, 0x64772ed0, 0x4f9478d0,
+ 0x5cbfdfee, 0xfb882efa, 0x9704edb1, 0x84df43ec, 0x5ff63cd1, 0xf979b8a5,
+ 0xf66175a1, 0xdd7dd67e, 0xcf110139, 0x2af81728, 0xe0af9b67, 0xaaf95afe,
+ 0xc82cf3dc, 0xbf7fbe33, 0xce22e975, 0x8dbb1b70, 0x4cd5d6f2, 0x5ccf7de5,
+ 0x07e133af, 0xb7cb25f3, 0xbd9d73f2, 0xdc00cb6a, 0xe716eb97, 0x1ddbfcb4,
+ 0xc37ee74f, 0x0c27e065, 0xc8377444, 0xddd3cfb4, 0x6578e3c0, 0xe2b54f0d,
+ 0x7032d8f9, 0x959d919c, 0x8d654473, 0xeb7bd332, 0x1a47cc35, 0x1679e378,
+ 0xfdd136ef, 0xc92e8534, 0xe9f30f56, 0x90697f05, 0x165e7cd7, 0x73ac5574,
+ 0xcaf8e165, 0x72105ffc, 0xd857694c, 0xb79d14f2, 0x645d7685, 0x903efc9f,
+ 0x9eb2fdf1, 0xcecf3813, 0x7f68636d, 0xb7b5d0ab, 0x0d8fe28c, 0x72b79481,
+ 0x7e7be351, 0xdef89f7b, 0x676e74be, 0x24de6274, 0xa6557ff6, 0x13ce19b8,
+ 0xe4a2f1f9, 0x2cd1cf9b, 0x73a735fa, 0x3a7e653b, 0x7da503e7, 0x2823aba1,
+ 0x6f9fda1e, 0x6f9513fa, 0x6f7c7b61, 0xbd474b6c, 0x9031be79, 0x6f9ed3ce,
+ 0x0de73e7c, 0xd765def8, 0x8bc950f8, 0xf3a74ebf, 0x6de5e5f8, 0x73b05ce2,
+ 0xe26738a0, 0x3674f5a2, 0x5fe84944, 0xaffc8a96, 0x417dc6ce, 0xc75fe22a,
+ 0x627bf67f, 0xefbbafb3, 0x264c77ac, 0xf76cbf9e, 0x7fecefb9, 0xf132fc6b,
+ 0x13caa8dc, 0xb7bfe1df, 0x5ddf94ca, 0x4a76f331, 0x48fe763c, 0x0e7803cb,
+ 0x7fc7bd97, 0xfeec0d97, 0x9a3fd167, 0xe481c7ff, 0xadefe27f, 0xf7ebfd60,
+ 0xfcd9bef9, 0x44ae4231, 0x4cbe53b4, 0x1fb70c47, 0xcc48364a, 0x062b7006,
+ 0x680072fa, 0xb3329c4b, 0x231dfde3, 0x2772fef9, 0x2476bfd0, 0x67ca0bc9,
+ 0x1dfe0339, 0x6bc10efd, 0x24b93f7c, 0xe7889dd6, 0x5e453b03, 0x3b884941,
+ 0x7b8c2071, 0xc949d049, 0xb7a2774c, 0xddb2537f, 0x9735794d, 0xbe1d3e44,
+ 0xc95e78c7, 0x23aede68, 0xe745dcc6, 0x189bf638, 0x83aaabda, 0xd2c3a226,
+ 0xbddb0d97, 0x4699d5cf, 0x92fffb72, 0xee1bdf96, 0x53e7c1d8, 0xe34d5418,
+ 0x5df4125c, 0xf34d5018, 0x29ce233b, 0xbd796a17, 0xbee8c343, 0xfc5d9efe,
+ 0x918ba13e, 0x3bf0076d, 0x50a57717, 0x8c4769de, 0xbd136973, 0x452679e7,
+ 0x38dce8af, 0x4cbb0baf, 0xf7282e74, 0x9f695b97, 0x274eb7b1, 0xc2e1dc61,
+ 0x1ee74620, 0x220fd42e, 0xb2417d7d, 0xc2f37c50, 0xbc6903bb, 0x7495caa2,
+ 0xc408a5be, 0x509dda04, 0x76bda2e6, 0x68b9fea1, 0x6fa85fe4, 0x559dbac0,
+ 0xf239ffcf, 0xbbfe4ee9, 0xf95f1710, 0xbef78a7b, 0xeffa528f, 0x54f8289f,
+ 0xe48da7de, 0x923698fc, 0x91a8f3f3, 0x3bde7e66, 0x2c4cf5d0, 0x37f38fad,
+ 0x02fc99c0, 0xafba27e0, 0x39ab8ce7, 0x8a71824c, 0xa86c9a0e, 0xee343bdf,
+ 0x0e09e7c4, 0x7877e281, 0x1785f918, 0xbf240c76, 0x1a68ac1c, 0x348ec2e7,
+ 0xf252d3ca, 0xada1a64d, 0x234c7846, 0xdbcb66f8, 0xe5fee9d2, 0xc7ca40ba,
+ 0x36fc7a29, 0xc89fe515, 0x7a2eeedc, 0x5134f175, 0x4d7ee1b7, 0xa17fcfd1,
+ 0x93e28bc0, 0x89695e4a, 0x8fa5a390, 0xf30031df, 0x651fd970, 0xaabb93ca,
+ 0xfe8f79e6, 0x48e5f970, 0xbc0f4721, 0x025b7c40, 0xc3bf8e74, 0xc2f22c54,
+ 0x71e15f8b, 0x77f5e296, 0xf1f24b3c, 0xde618684, 0x53d725ef, 0x2f70de41,
+ 0x96e5c918, 0xda95bfa7, 0xde7b4317, 0x9a20bdff, 0xe50d0ecf, 0xebe3fb29,
+ 0x22bffb96, 0x8bfd5bff, 0xf407605c, 0x957c1fb3, 0x57f23db5, 0x060d0394,
+ 0xf29e83ab, 0x8d4ebdfc, 0xdf3f296b, 0xd0f92060, 0xaf7e2c19, 0x11e792b5,
+ 0xfa9faf14, 0x3857ca6b, 0x699d2f75, 0x7fece65a, 0xa474aebf, 0x0f8bef86,
+ 0x3e400eb4, 0xe07c052c, 0x3a1f8078, 0xa8fece5f, 0xebfefea1, 0xcb923a99,
+ 0xdc3e3ef5, 0x3ba1f3c3, 0x74bc7307, 0x7a449abe, 0xd39823a7, 0xfc97cc35,
+ 0x5e60ced4, 0xe604a252, 0x3d3998df, 0x91778e74, 0xed29ddff, 0xc343b2a5,
+ 0x14ad15fb, 0xe6e22bbf, 0x482523f9, 0xff7871b3, 0xb436e6cf, 0x671e503b,
+ 0xadd2a68d, 0x1efeb90b, 0xf263a076, 0x7e0a8eef, 0xe870f252, 0xae280177,
+ 0x3ca2d2e9, 0xafbb0bb5, 0xdffae1a4, 0xefe7e08b, 0xae43ca25, 0xfb29291b,
+ 0x540794ec, 0x2b3c25cc, 0x9fb44876, 0xa1f6bc5f, 0xe2fba442, 0x91732d8a,
+ 0x1475941f, 0xfa2e59ab, 0x4c921d49, 0x7ebf01f3, 0xebd4ccc1, 0xf7c0a7bf,
+ 0x197ccaf7, 0x3d27cfdf, 0x6fb6bc03, 0x53b145a4, 0x578c3559, 0x4cda56b2,
+ 0xfc5189df, 0x053ebe4e, 0x83efb84e, 0x3c4a8cf9, 0x57eb46e0, 0xf9a379e6,
+ 0x75e423bc, 0xd7e58c47, 0x1fdf10e3, 0xae4f24c8, 0x4066377e, 0x6dd80fc8,
+ 0xcaa14bf4, 0x0fff3078, 0x38c11751, 0x56790acf, 0x79c3f30c, 0xfdf36e26,
+ 0x3ae4807d, 0x06f0fadf, 0xa36a7adf, 0xc5bd3d6f, 0xdb7d6eb7, 0xdf82deb7,
+ 0x09c0f4cd, 0x073c61fd, 0x879c53b1, 0xcf187f40, 0x8c3fa133, 0xb187f475,
+ 0x9f187f44, 0x758c3fa3, 0x8eb187f4, 0x8925b0fe, 0xa258c3fb, 0x65cf8c3f,
+ 0x4953872b, 0x023f8f2d, 0x2fb46c1e, 0x5df9473f, 0xd10bf00a, 0x421c2d1e,
+ 0x7cc61d76, 0x7e9577e9, 0xd2296d79, 0xfd930cd1, 0xcc4cc8d2, 0x1f5b6ac7,
+ 0xf2fded89, 0x1b464a94, 0x686f188c, 0x3d7e775f, 0x2629219a, 0xaf6c15fb,
+ 0xae952fe4, 0x4f7e8b7c, 0xe5b57daf, 0x78e13f8f, 0xf287b8a2, 0x78454f7b,
+ 0x714cbe4f, 0xf8a33d2e, 0xdfdf559e, 0xf9fedc3d, 0x679ab746, 0x5801fff4,
+ 0x00db8bbb, 0x0000db8b, 0x00088b1f, 0x00000000, 0x7ccdff00, 0xd594740b,
+ 0xe6feefbd, 0x49324995, 0x41e42126, 0x21e4cc20, 0x49389311, 0x47114bc8,
+ 0xa8d53048, 0x684d43c3, 0x4092138c, 0xa3c30480, 0x7b96c4eb, 0xa4401833,
+ 0x51b78d70, 0xa13a3951, 0xe85de94a, 0xb6950a09, 0x1006739c, 0x4e6d8ac5,
+ 0xb6abad5b, 0xa9078838, 0x68349687, 0x69edec57, 0xdff7ffef, 0xbef997df,
+ 0xbc7b5249, 0xacdd77ab, 0x7bfe7ba5, 0xfe3f6fef, 0xeffffdef, 0xfc42108d,
+ 0xfb5bfe85, 0xdaf08c7c, 0x85fdff05, 0x442fdfff, 0x59cf10b9, 0x0e9d3247,
+ 0xd77c2e21, 0x4f5c5bbe, 0x1868ac65, 0x06e6a42a, 0x09a449bb, 0xb8df11b1,
+ 0x5335a884, 0xef0479a7, 0x28c7f651, 0xa4f34c42, 0x885d3108, 0x49f933d1,
+ 0x05fffa82, 0x2c4f377f, 0xa8cac75b, 0xadde0eb3, 0x6ccf3098, 0x548af09b,
+ 0x735dfb1a, 0x4f1a05f0, 0xa24d79d4, 0xea4d8842, 0x35ece71a, 0x59105109,
+ 0x38c1b5ef, 0xbfeb7421, 0x018a60ee, 0x619a1a2e, 0xb1fd7fe8, 0x497b431c,
+ 0xbda1ae68, 0x13d6f96d, 0x962144e6, 0xf4332eed, 0xbc116abb, 0xa7cfabcf,
+ 0xea6e0307, 0xf0d1bbe7, 0x3aea109d, 0x936eb29d, 0xc3fce475, 0xd1d37fd4,
+ 0xe3004f4c, 0x2f0b35ee, 0x8d03b7ed, 0x2b6442a5, 0x4f181d81, 0x179e2a0c,
+ 0x6a56bc68, 0xe8bb53f7, 0x9d38f3b1, 0x2c3b7e2a, 0x2da4e022, 0x9bf3447d,
+ 0xd1e77fa9, 0xc256e0f4, 0xc9c61f4b, 0xf0a776a4, 0x6b78d326, 0x87170ee6,
+ 0x6f359c68, 0xd042bb7e, 0x83ccbb16, 0x215cced9, 0x03c12b36, 0x9f10b34e,
+ 0xab4e1ca4, 0xd98776a6, 0xf443c8bf, 0xfca67cb9, 0xe78455c7, 0x1ecc87cb,
+ 0x0d6d93cc, 0x291295a5, 0xab268385, 0x038cec06, 0xcdfb07fd, 0x63a24175,
+ 0x9cc3ad16, 0xc18fe112, 0x797169fe, 0x35bec88e, 0x0b6d987e, 0x7d84dccd,
+ 0x79eb1cbd, 0x0a3f8041, 0x9dbc62ef, 0x8fe02b31, 0x80945b8e, 0x3ec8faed,
+ 0x77e53a37, 0xea3e7eda, 0x7c0632a5, 0xdb3e65e6, 0xbe5fb6ac, 0x8bb144f6,
+ 0x7bd9d1f6, 0x2c4cdb2c, 0xe874ceb0, 0x01952640, 0xfb19bfbb, 0xffcc18e9,
+ 0x679a7cc5, 0x61663bed, 0x3efffea6, 0x9ab128b0, 0x8bc9f7f6, 0xc13d4f56,
+ 0xdb7ff70f, 0xac7da616, 0x1e6d04b5, 0x3bbe3b2a, 0x7952f368, 0xae41c1eb,
+ 0x65b0755f, 0xb575f831, 0x7d81dee8, 0xbf12b25f, 0xb1d1f0eb, 0xa4e7d950,
+ 0x31eebf75, 0xc4777f31, 0x6bda3f09, 0xa74ff3cd, 0x95077f62, 0xb97b2c12,
+ 0x85adb0ef, 0x7ed47bea, 0x7a32f2d1, 0x74ed5976, 0xa43a3fea, 0x92a7de30,
+ 0xd743bb8f, 0x1b2c7cb2, 0x7cb97373, 0x88213aec, 0xbe11df25, 0xa5744122,
+ 0x3ef01ab5, 0xfcccd67a, 0x1cdc7a39, 0x8749f414, 0x0cba942d, 0x2b17f874,
+ 0xf88ba1d3, 0xa4f88aa7, 0x40df7e8b, 0xd9be6fa5, 0xd40fbfc0, 0xbdf81bc4,
+ 0x88e4e841, 0xcc47bbc6, 0xebcbc030, 0xeffd0d73, 0x945d7e5d, 0xda46943c,
+ 0x0dfff8cd, 0xbb827691, 0x4a5c04b6, 0xc685a022, 0x30b72a7a, 0xf866dd9f,
+ 0x8d2c4bbe, 0x3f9f03f4, 0x678c6fff, 0x4b6d8621, 0x26bf688b, 0xafd107a2,
+ 0xad5e7fc1, 0x6d3d730f, 0xb39720c4, 0x98bf3d73, 0xf2317c4f, 0x47ec55b6,
+ 0xdf089fc5, 0x7f46e815, 0x20e913b9, 0x9d5a1104, 0xb1d68937, 0xa9c908fe,
+ 0x618a5f41, 0x06eb17d0, 0x74b6ba1d, 0x2a628bd4, 0xb4059be9, 0xb0c0ae8f,
+ 0xf8c1dbad, 0x4a1164b7, 0xa22bf7d6, 0xdbfb8527, 0xbc2452b3, 0xac47f505,
+ 0xf875861f, 0x686378c3, 0x816e633f, 0xafb744bc, 0xac0b7da7, 0x3dfeec47,
+ 0x2dfad5f4, 0xde631f75, 0xea3cdaf5, 0xae9f1af8, 0xebdf4bde, 0x9e3d1dd6,
+ 0x72c5c4a3, 0xe1e0f6bd, 0x7e1067d7, 0x4b92f996, 0x439d4720, 0x852dac4b,
+ 0xd34df913, 0x9a0f57fb, 0xf06e3183, 0xb7e629df, 0x8f5683d1, 0xb2f01bf8,
+ 0x0f182bde, 0x8ab87cd1, 0xf9a765f6, 0x3c511d57, 0x03f64541, 0xf146d67e,
+ 0x9acdc627, 0xbe1a6f04, 0xd517f1c6, 0x683f1abe, 0x298fab9d, 0x09cbe841,
+ 0xa7c68978, 0x3f2acf3a, 0x0aeb90fd, 0xc6a2baf2, 0xf2d15515, 0xfe86c9b8,
+ 0xe114fba3, 0x1f18be54, 0x2c6cc74b, 0xe573b3df, 0x2a8e47fe, 0xddf4fd9e,
+ 0xae16633d, 0x1f1fe71f, 0xf214ade1, 0x921f0137, 0x7e527c9f, 0xe34b1eee,
+ 0x7c5efeef, 0x34fc45f5, 0xefdc573b, 0x7af44473, 0x621e9e44, 0x49294b3e,
+ 0x5b48bd48, 0xace5dfa0, 0x3b3d541f, 0x4d243e95, 0xfc94facf, 0x71e7e603,
+ 0xf894e3bb, 0xa57568dc, 0xeb4f8327, 0xd468f68c, 0xd64a4ae2, 0x642d21f9,
+ 0xc0d35d67, 0xc2d333bf, 0x609f8e34, 0x4f4d57e8, 0x76f1d5fb, 0x0ecdcb6c,
+ 0x6ff3beeb, 0xea09a6b7, 0x1a75bd9f, 0xceb12d97, 0x9691d834, 0xec1f66ad,
+ 0xa48f87e3, 0x5f1155a7, 0x9addb87d, 0x7c434f5a, 0x6cbce0f8, 0x96b80451,
+ 0xc58f0bcb, 0x131d0434, 0x625d55f7, 0xfd747c62, 0xaed8f7f7, 0x3674d6fd,
+ 0xb77201b1, 0x156268fd, 0xfb6eb38d, 0x649c2acf, 0xfe4c87cf, 0xffda12ba,
+ 0xdb20ca27, 0x2c1ce173, 0xfc4515f6, 0x6bdbb589, 0x3bf761d3, 0x59ea7cff,
+ 0x56ff7dd8, 0xf8899a6b, 0x273f37e8, 0x3db0a87b, 0x52e23f63, 0x4be3e4ac,
+ 0xfb07c42f, 0x292fff88, 0xf54b1bc2, 0x8a27cc6b, 0x7afb069d, 0xffcc1efc,
+ 0xb79a76cf, 0x0f06f31c, 0x4f5e6064, 0xebcc1ae0, 0xe49f9adf, 0xddfe2bff,
+ 0x7fa57b03, 0xe7b54077, 0xa0328857, 0x3b5ec1db, 0x97abffc3, 0x88473d10,
+ 0x0c19bd43, 0xe2ebd4bf, 0x80b7a872, 0x3914d7eb, 0x46fbbd25, 0x3cd2364a,
+ 0xa0a28581, 0xa3aded9b, 0xdfeb42c0, 0xe079c4a4, 0x3c526c4f, 0xfdd04ee9,
+ 0xced2c9e7, 0x5e8bf4aa, 0xe4234dcf, 0xf3f8e983, 0x68bb31e6, 0x2deff1d3,
+ 0x2f00d922, 0xfa1a67b2, 0x86dd3ad7, 0xae335bf6, 0xc57fb435, 0x6f806255,
+ 0xf436a82f, 0x8b73c3bf, 0xeaabbe01, 0x4bfe862b, 0xf00c4bbc, 0x4346bab2,
+ 0x2d7dbbff, 0x1b7bf686, 0x1bda18d6, 0xf00c1bfd, 0x341e3b57, 0x7bafbff4,
+ 0x2bdda1ab, 0xbbd8169c, 0x171f44e3, 0x885ffde1, 0xbd37282e, 0xd3d0ef9d,
+ 0x5322fe75, 0x7c24d0f7, 0xf48968fb, 0xea517e6f, 0x98fe05dd, 0x487c9265,
+ 0xc3ae17a5, 0xd427b033, 0x0a42259e, 0x38622bfb, 0xdd137c13, 0x7e7dba2f,
+ 0x2eabc9fc, 0xf4ada1a2, 0xe90b06c3, 0x2795f98d, 0xbe0972cb, 0x1b6be5f3,
+ 0xe61fa42d, 0x2af278df, 0xb6951fe0, 0x32fb7235, 0xc345aec1, 0x04376fcb,
+ 0x6ff39d68, 0x81edd9ce, 0xe913f3df, 0x9fc54cf7, 0xbe5b77d8, 0x10ca37dc,
+ 0x93ca23f1, 0x5f288fc4, 0xb36c7e23, 0xfc47bf92, 0xaf4cf288, 0xd47feb87,
+ 0xd9e5c55b, 0x3f972f5e, 0x72e3adee, 0xe5c7d7b8, 0xb81b7b4f, 0x9faf79fc,
+ 0xb7b77bbf, 0x7af7cb83, 0x97feb9bb, 0xfe5c3dbd, 0xf5c037aa, 0x2c2896af,
+ 0x0102b4ff, 0x037b05bd, 0x776f5dfe, 0x77a4cc84, 0xe5eb31c5, 0xf24abd71,
+ 0xdda578ad, 0xa2a95c54, 0x6ebeca89, 0x5c878e11, 0x17c92d86, 0x39f8be89,
+ 0x7a237ed9, 0xea2e22d4, 0xc61fadfc, 0xaf424f7a, 0xc9d33108, 0xffad58fa,
+ 0x69ef52a7, 0x15ee5fae, 0x977a7d7a, 0xd023ffdb, 0xb2f71dfb, 0xec3332fc,
+ 0x24e9f753, 0x24c77a6a, 0x93e3263a, 0x593e5467, 0xc62c4f60, 0x3d816ef9,
+ 0xb27b083b, 0x83ee12c0, 0x4cfbea1e, 0x3d221eb8, 0xc6c12274, 0x11efa97a,
+ 0xca13fb0b, 0x9be182a7, 0x7dc30552, 0xa19b0d9f, 0x3d381777, 0x54576c19,
+ 0x022ecf38, 0xdd722949, 0x4a1e6758, 0xa7cd53c2, 0xf3b045e1, 0x2e6c3937,
+ 0x5f9c09e8, 0xcf314a62, 0x02bcdabb, 0xd7bd52e3, 0xff3fdf46, 0x68990899,
+ 0x5fa8b35d, 0x10a5f32c, 0x87d81728, 0x87923ecd, 0x276f5499, 0x9bd51678,
+ 0x02d7bb65, 0x6c3a7c3a, 0x76a11d86, 0x03db2491, 0x7cc894a6, 0x2c133ada,
+ 0xeca97e34, 0xe72a5897, 0x39c0bc01, 0x3ad0a254, 0x1e1cbafb, 0x02dd21e0,
+ 0x5efee7de, 0x543f7f33, 0x3a1e04e2, 0xfb411e1d, 0xe2052c20, 0xaf1fb94a,
+ 0xd722c133, 0x5fa9f353, 0x432fd178, 0x71d46278, 0x803db2ec, 0x0d4a6e71,
+ 0x8f805a65, 0x20279b6e, 0x9d62f1c7, 0xfb2f17e8, 0xb93acc85, 0xad03fbcd,
+ 0xacffec97, 0xf4376194, 0x4c43f12e, 0x2bd4f829, 0x539961f9, 0xa97083f2,
+ 0x1a1fcab0, 0x4a752cbf, 0xedcafc92, 0x78d29677, 0xafe718be, 0x7fce49e3,
+ 0x97e6e4aa, 0x512cdf10, 0x1fbff5fd, 0xfd2578bf, 0x7bbd5267, 0xf468df22,
+ 0xe347f8d1, 0xd23e6883, 0xb7a340f8, 0x7f345df6, 0x3455f345, 0x4bb02d3f,
+ 0x0f8e833a, 0x49f91329, 0x906874f9, 0x6769dfd7, 0x4fcd16bb, 0x35307cd1,
+ 0x4e7dc93f, 0xfd08a3e4, 0xcf2f8f81, 0xde6ec347, 0xa4fb66c7, 0x8ff1a47c,
+ 0x1f1a4fc6, 0x16223fdd, 0xcb535127, 0x9475eb98, 0xcffc727b, 0x8ab48f40,
+ 0xab33165b, 0xbe45cd38, 0x9efd8984, 0x5bdfa298, 0x501fc4b1, 0x2f73c23c,
+ 0x2e3381fc, 0x7ec5d8ab, 0x4251d7b6, 0xeaa45bf4, 0x9ba233d1, 0x8fb91ced,
+ 0x46b5d001, 0xc2a2f125, 0xd77fecd5, 0x2c7e8c38, 0x88fc232c, 0x17efd4db,
+ 0x0db7c9ff, 0x6a9c58eb, 0x536f6ff4, 0x455be3fd, 0x375f8f3f, 0xf0bdaa33,
+ 0x6f9bf656, 0x6fd633cb, 0x5efd5528, 0xcf4370b7, 0x5c8f08d6, 0x7ecdd89f,
+ 0x572a8d6b, 0x72fd2a59, 0x9f31665d, 0xfc2b58f0, 0xd7f72816, 0x62f3677e,
+ 0x80455bdc, 0x2088afe1, 0x108bb797, 0x1907738f, 0x0977c002, 0x69dc0561,
+ 0x91b6c91f, 0xfb37ad48, 0xf85f803f, 0x39fe59db, 0xc636c738, 0xcf20fbfa,
+ 0x6cefe2a7, 0x5be6807a, 0x0f28b654, 0x71ac9ddf, 0xd2753fb1, 0x1dfecb9e,
+ 0x129ac2e4, 0xc937cf91, 0xfd91e63e, 0x13f6453a, 0x9fb269e5, 0xdec76479,
+ 0xf809fb20, 0x02ad82b6, 0x29762ddf, 0xb7dba2c2, 0xceedfdf6, 0x6d32c245,
+ 0x7b74fb6a, 0xfa67f7f1, 0x4adf7f89, 0x1223539e, 0x60d65651, 0xa7256fbf,
+ 0x6319649b, 0xd5e8b2e3, 0x4ffcc9bc, 0xf322ff8d, 0xa6f9e62d, 0xd786b3c2,
+ 0x786a7c68, 0x7d7812fe, 0x3ebc3269, 0xced82253, 0x595fda8f, 0x5755b88f,
+ 0xde6fd4bc, 0x06441357, 0xa3c6eff1, 0x1bfd1cf2, 0xe313312c, 0xf7b53c4b,
+ 0xe42c28dc, 0x2bdc7f4a, 0xaaf3c002, 0x8fae6a9e, 0xf7898f8e, 0x6bf8616e,
+ 0xd9572f2a, 0xdde821fd, 0x6ba1a5cb, 0x1f12c3c8, 0xbc4bebef, 0xedf9e681,
+ 0xce0f664b, 0xd7669d27, 0xace20f6e, 0x2f3d996f, 0x9d3ffbe0, 0x724a5eca,
+ 0x369f9e25, 0xd3ac39e9, 0x9da8f12e, 0xe39dbec3, 0xce14b963, 0x23c80cb2,
+ 0x5f9829fd, 0x92665ff3, 0xfe27692f, 0xe59367dd, 0x454cfe54, 0x529fe91c,
+ 0x50facfee, 0xc77d1fa3, 0x538d1670, 0xeb26fa41, 0xaf3e38d1, 0xf7de9d78,
+ 0x08d50ed8, 0xc5afbf83, 0x25534623, 0x6b88171e, 0xb03c449e, 0x04558ce6,
+ 0x82147da9, 0x250cf68f, 0x7a35bd08, 0xfa19aae6, 0x114136b6, 0x542f60d3,
+ 0x6193127d, 0x3e9d2e12, 0x09c57588, 0xe38f8e97, 0x700c520b, 0xa1866782,
+ 0x8e55527f, 0x3bd93da1, 0xad3ed0d7, 0x4f00d4ae, 0xe860ddf7, 0xd0b0de9f,
+ 0x6ffa6700, 0xeacff433, 0x35806a58, 0xab25957d, 0x15eeacc4, 0xf767ef86,
+ 0x77f434ac, 0xda1ad607, 0xfb8971cd, 0xbc068f59, 0x4e3405c3, 0xee4e3a9d,
+ 0x7e868dce, 0xaa6dd082, 0xbfc89c80, 0xceeb1267, 0x3acf4428, 0xc87aaac7,
+ 0xd7ff7e69, 0xd734eb8d, 0xbca9925b, 0x7fd465d5, 0x784619b5, 0x4284e391,
+ 0x4e458b43, 0xeace1ea3, 0x8ce018b6, 0xd79bd232, 0x51628fd1, 0x2f82f1cc,
+ 0xae7fbfa2, 0x78d1fe81, 0x84f07e22, 0x69ec9fd0, 0xb37aeb00, 0x8f7b02d5,
+ 0x1f7e82fc, 0xf1e82fc8, 0x1e82fc80, 0xdf417e46, 0x7d05f91f, 0xfa0bf23b,
+ 0x4633b2f6, 0x1b0f97fa, 0x9ef95fe9, 0x5f1afe91, 0xeaa7454e, 0x843f91b0,
+ 0x7f2bf15f, 0x5e374e85, 0x344ff232, 0x37266e7d, 0xf4153927, 0xd7213c50,
+ 0x9dd7a797, 0xfa22f451, 0xf7c04c04, 0x9f4904cc, 0xa04975d0, 0xb319ed57,
+ 0x8ffc1208, 0xc77cfb51, 0x23286fe2, 0xab86f03d, 0xebfa0334, 0x147ae166,
+ 0x9dc5db71, 0x86884f26, 0x7e35115d, 0x7dff0cf5, 0x1a17a465, 0xb6cd5da6,
+ 0xfc463f81, 0xdc9e7073, 0xd9ddeaa5, 0xc0fc7271, 0x127cc142, 0xd839baf8,
+ 0x339ee347, 0xcfd02bf5, 0xb7f44fdf, 0x0bfbfbe3, 0xd47f79bb, 0xcdf7c143,
+ 0x0d931aff, 0xe0b679b8, 0x0c28b073, 0x88492f97, 0x2ce6c5e8, 0xd43b27aa,
+ 0xe39ea655, 0xdf4ed43c, 0xb8c99775, 0x69c7824e, 0xa15178e3, 0x444e22f0,
+ 0xe6ecafc7, 0x6ce3e022, 0x63e01cec, 0xde41e4c0, 0x25756c20, 0xde051f41,
+ 0xbde40b34, 0x9fc217e0, 0x57faa59b, 0x29e46259, 0x5ece73ac, 0xd7abb061,
+ 0x62c2ed06, 0x0d397fc8, 0x8650d170, 0xc7f5ffa1, 0x92f6865c, 0xbda18150,
+ 0x00c78cec, 0x19570f97, 0xe7be57fa, 0xe1d5c035, 0x1bff433a, 0xf00cf92f,
+ 0xef9e456c, 0x239653bf, 0x992e21f3, 0x387e6bdf, 0x6bfa5079, 0xf9afdcf2,
+ 0x49ffa2d5, 0x38711daf, 0xbf357f95, 0x6da3f35c, 0xcfd04084, 0xf6c2d3b6,
+ 0xfa5da660, 0xf62dfec9, 0x6827c8f3, 0x57e6bafe, 0x08a9fe6b, 0x76f57ad4,
+ 0xf693be87, 0x35ebf545, 0x8bf359ff, 0x4c5d8b13, 0xb236eb3f, 0x4b07e0ab,
+ 0xae761338, 0x1a4c4639, 0x4cb9790f, 0xd7a25b9e, 0x7a2badaf, 0xa762c4fe,
+ 0xdc7517e4, 0x7ee2ec17, 0xccfe24df, 0xf57caabf, 0x63beb99f, 0xad67cfe0,
+ 0xbb56f79e, 0xf4f3ebff, 0x1321fc25, 0xf5f352fe, 0x264dfd72, 0xc767c713,
+ 0xd72e5fd7, 0x0bf595af, 0xd921dfc9, 0x37e2f359, 0x1fc83af7, 0xc2c7b678,
+ 0xaf339671, 0xe40c6c5c, 0x5e121fc1, 0xfc9b338c, 0x3e07d07c, 0x0b07ce05,
+ 0xdf3ccdcb, 0x772932a5, 0xcf2cbd11, 0xd242a365, 0xc6c7b47f, 0xe849d479,
+ 0xeda07ccd, 0x8b43f107, 0x510dc655, 0xc9686e22, 0xc0437197, 0x44a21b88,
+ 0x2ff510dc, 0x3e187af7, 0xf0c55bd2, 0x0cbd7af7, 0xe3adeb1f, 0x3ebd07f2,
+ 0x26f8d7ae, 0x79da5f1a, 0xc43fa34b, 0x2f237610, 0x1feb1f8a, 0x6d72f492,
+ 0xd3f6fab0, 0xa24deb16, 0xe08d294e, 0x8f151ef3, 0x3c49e633, 0x7fe41fa0,
+ 0xe6b57eaa, 0x9bc424c2, 0xc92b8547, 0xaae257f9, 0x687c2f7f, 0x973f1f78,
+ 0x949bcb8e, 0x52e4a987, 0xceeb3f3b, 0xd1772cab, 0xb72d18f2, 0x3fe778d1,
+ 0xfc7bb9dd, 0x53c5ab5c, 0xe8d53954, 0x55b5c9a2, 0x5fa11b84, 0xce267982,
+ 0x609c3f53, 0xf3c5a394, 0x077f7e24, 0xbcf2a239, 0x326699cb, 0xfdb2f847,
+ 0x1017f271, 0x4869ef1f, 0x8059e0e4, 0x7dba8fce, 0xd2faf02e, 0x2b7ea06e,
+ 0xd062ac07, 0xb0757d85, 0x44096d1d, 0xd8471b9f, 0xaddb6c9f, 0x3e469f38,
+ 0xe7e4e77f, 0xd13fce4a, 0x6fc26d38, 0xfbdbbac3, 0xab56fd8d, 0xfce8cae7,
+ 0xd53cd54a, 0x878479de, 0x7f351ffd, 0x19f6a1de, 0x6e609fe7, 0x60df1a92,
+ 0x1432a479, 0xb9bf3ba3, 0x8b28ef90, 0xb8b784c0, 0x6dc3d802, 0x6bbe4f16,
+ 0x7869bf22, 0x97e7989b, 0xf7c41bf7, 0xa0fcf962, 0x232ff9e5, 0x6afa0fcf,
+ 0xffb514f9, 0x985980e5, 0x48e0df71, 0x7fa7e70c, 0x4f7b3a6b, 0x7f974b8e,
+ 0x11b79099, 0x309fb889, 0x27ba687a, 0xb4bac930, 0x1b361fd2, 0x684c91ee,
+ 0x11347adf, 0x17cec9e7, 0xf3a69e65, 0x796953c5, 0x3cd7bd3a, 0x1bfbc2cf,
+ 0xe7dbf932, 0x9bdc8f4d, 0x60c7fb58, 0x357aca31, 0x9fbd127e, 0x5f36bd71,
+ 0xa519fe61, 0xab5eb1fd, 0xa47f7853, 0x49e40517, 0x112fd7cb, 0x5a9454a1,
+ 0xb3bfc43e, 0xe5a0e99a, 0xd5425a43, 0xfbbb8fbc, 0xa8e35b56, 0x2da9f84b,
+ 0x48ae71b5, 0x4b3c249e, 0x2a99bfde, 0xac6cb25f, 0x3e5bc784, 0xb38f2376,
+ 0xe65b9e6d, 0xd9edb64f, 0xee6fff00, 0x1e056141, 0x4e3956c2, 0x553e9e34,
+ 0xdcb924e5, 0x6e37b7a8, 0x6f6f5855, 0xf796ad84, 0x6b6f587c, 0x157ed5f0,
+ 0xa6f095ae, 0x5b0e12ed, 0x24953b1d, 0x05c45fb9, 0xd8944fb0, 0x87b1ce0f,
+ 0xf60238d4, 0x40fb1281, 0x6015f43d, 0xd0c02be8, 0xafa18057, 0xa15f4250,
+ 0x65f0a57e, 0xbc888e23, 0x4e4e8d4e, 0xd1a9d790, 0xebc81ff9, 0x75e461e8,
+ 0xd791fdf4, 0xaf23b7d1, 0x5e476fa3, 0xaf230f47, 0xbc8fefa3, 0x5e461e8e,
+ 0x791fdf47, 0xbc8c3d1d, 0xf23fbe8e, 0xe476fa3a, 0xc8edf475, 0xe461e8eb,
+ 0x91fdf475, 0xdfb7d1d7, 0xf218a3df, 0x9a93f73e, 0xeeb5df06, 0x71fcc69d,
+ 0x313bedda, 0x41fbe88f, 0x66bf9ffc, 0x8f9d01cd, 0x6edf01af, 0x48f38aec,
+ 0x49d7f73a, 0xa4849bba, 0xd32348f3, 0xc24d8b79, 0xe7749eb5, 0xf20ffe24,
+ 0x99563529, 0x7c89414f, 0x53e44a0a, 0x529f2250, 0x29f32f93, 0x414f9128,
+ 0x2829f23d, 0x89414f91, 0xe44a0a7c, 0x9f225053, 0x14f91282, 0x0a7c877c,
+ 0x5053e44a, 0x4a0a7c8f, 0x7f5053e4, 0xbc81d68e, 0xf82eb68a, 0xf38679cb,
+ 0xe1a1f11c, 0xc034e73c, 0xfdf597f0, 0xdbeb2fe1, 0xdbeb2fe1, 0x61eb2fe1,
+ 0xfefacbf8, 0xb0f597f0, 0xe58b9e69, 0xfeb37e0c, 0x7acdf83b, 0x703fa8b8,
+ 0x3ba0b11a, 0x35eefdf6, 0xe504e194, 0xdf49c559, 0x15b7ff97, 0x638583c8,
+ 0x0f64ec95, 0x0fadbfd9, 0xd821a8ad, 0x2ba7deaf, 0xd0262316, 0x44d8f39b,
+ 0x04487f37, 0xe8a08f71, 0xd76e4cf3, 0x47fcaaf2, 0x22392f74, 0x535f0fd8,
+ 0x7da5d724, 0x334e11ef, 0x047fad4a, 0xf45fbc9e, 0xd63f5afc, 0x9075ba97,
+ 0xfdc12c9d, 0x8e2d9286, 0x4fc45dd2, 0xfb0a4c07, 0x9fc807a1, 0x5e893a5a,
+ 0xa3fd50aa, 0x27c3a603, 0xa22f70e3, 0xa7ecf145, 0x88b1afa1, 0xe052d633,
+ 0xfe14bba9, 0xb2797642, 0xdf75afea, 0xda3f7b80, 0x1db8b5ba, 0xf22f09e9,
+ 0x8447f3ef, 0xb9e68dad, 0x6b6153e9, 0x9366df87, 0xc3be02fe, 0x80baedb9,
+ 0xe3afdde2, 0x697282ef, 0x0d81fcff, 0xfd51b437, 0x6fba8775, 0x171f8768,
+ 0xcefbbf27, 0xc78c8973, 0xfb29b73b, 0xf99fb4cd, 0x90778487, 0xcb9495fa,
+ 0x8775dff3, 0x9e36b69c, 0xd76b69d7, 0x97d843df, 0x5ce1736d, 0x8835c228,
+ 0x8a7989ff, 0xf0444178, 0x0d7bfb46, 0x4486bbfb, 0x75d7f105, 0x3ffb6307,
+ 0xd751f1d2, 0x7e01b250, 0xff6658e0, 0x59fe3a47, 0x72441f87, 0xec206e41,
+ 0xf24aa756, 0xc3bd6af5, 0x79c51be4, 0x623ecba2, 0x9a6efe03, 0x7b8b5c97,
+ 0xf0b8e26c, 0xe6ef83e4, 0x4e9f6cb5, 0xbd07f2eb, 0xba03dc1e, 0xd3eed3e9,
+ 0x63ef3f0c, 0x82a7d998, 0x70f6c7d7, 0xc509404e, 0x0cee2a13, 0x09529a0c,
+ 0xd5b023be, 0x87fe869a, 0x00ee0784, 0xa0b12899, 0x42afb234, 0x558a6c31,
+ 0xd4e22fc0, 0x91ff1d34, 0x7e0e58e6, 0x0558f129, 0xc58963f8, 0x89be8569,
+ 0xefa237f6, 0x71ff907f, 0x6867bcaf, 0x6b1ec0b5, 0x538b51fe, 0x36eaf5ae,
+ 0x2d1ffb2b, 0xd0ffc947, 0xfcd52bdd, 0x085eed0d, 0x109e1df9, 0xdb91f8ec,
+ 0xb9d42e39, 0x7fbe1de1, 0x783b89f1, 0xfaf89920, 0xf7c39c93, 0xb7e1b954,
+ 0xc94fac28, 0x272ce86f, 0x3f6cb63c, 0x55f3889d, 0xfb0af038, 0x3db7571b,
+ 0x08e3289e, 0xa6d11f32, 0xcf8b49e2, 0x68f4abb4, 0x7d01ef53, 0x3bcb7a48,
+ 0x086eed87, 0xbd6836f7, 0xfb4457ec, 0xb91f9a87, 0x384f1b4e, 0xa45c45df,
+ 0x8bb7f683, 0x5bbbd5a0, 0x89886476, 0xd53ae3fe, 0xcdb35caf, 0x3a7ef7ca,
+ 0xc2ed9044, 0x3f54609a, 0xbacfbef5, 0x9dfac683, 0xa7fe51e5, 0xeed22e7a,
+ 0x7dbcb6e5, 0x7ff66eea, 0x6f9cadba, 0xfd2ada6b, 0x04587121, 0x8bc015f3,
+ 0x3704b14c, 0x947af51d, 0x27e7f849, 0x1f545faa, 0x2ebc658e, 0x7d678b19,
+ 0x8b2c74b2, 0x32c67be1, 0x4c77bcb9, 0x8a5c8bde, 0x3bd10c58, 0x9104ab5c,
+ 0xea99fb4f, 0x7b8ddd0f, 0x2063a092, 0x9479f99d, 0x145319f8, 0xae6a7aab,
+ 0x77053957, 0xdfeadeb3, 0xf5987b8e, 0xcbfd8283, 0xd137e03b, 0xa3f00df8,
+ 0xdc1e41a6, 0xb73f7cb5, 0x6ef9114e, 0x9506c3c8, 0x041e49ff, 0xeb2f0feb,
+ 0x41259ab5, 0xf069afdc, 0xee81361f, 0x03f81c9a, 0xef802de7, 0x57362808,
+ 0xf8279f21, 0x79f1acbc, 0xc7343cb4, 0x8725f1ab, 0xfb8d1f8c, 0x9d2c58a7,
+ 0xd7e045bb, 0xded4bc2b, 0x0ce0188c, 0xf7081195, 0xfdb28509, 0xaf5fd1e4,
+ 0xd3c386d8, 0x343f8c97, 0xaf4c4c99, 0xf6f7f211, 0x70c56043, 0x65e43a6d,
+ 0xcbba52b7, 0x53cf5915, 0x572f0b95, 0x2bc5cee8, 0xf922f955, 0x63f9c74b,
+ 0xe9f923e3, 0x40ff1262, 0xcf095b2b, 0xa4e6b390, 0xa214d7f0, 0xc2e527cc,
+ 0xdb0c435b, 0xe27dd428, 0x73ad0422, 0x7c670a85, 0x9dfdee2f, 0x861f8c85,
+ 0x5e5f962f, 0xbffc2811, 0x8a4d87d0, 0xab57ef85, 0xfc9871f8, 0xefc3951f,
+ 0x831787b7, 0x2385f1ae, 0x1a2dd036, 0x1eedf73f, 0xf08733da, 0xe9215190,
+ 0xb7eb64d7, 0x045179f2, 0xb55f88ad, 0x22fb4a16, 0xafecae2c, 0xc5c43e72,
+ 0xdf6d3e71, 0x89f7aa1f, 0xace1f1a3, 0x7e027690, 0xf48e6bb2, 0x4fc25193,
+ 0xf81c7dc6, 0x27e180c9, 0x8c9f84a3, 0x80c9f87a, 0x860327e1, 0x7e180c9f,
+ 0xc9f84a32, 0xe4c27fa8, 0xd130ff3d, 0xf05369f3, 0xa7c4abf0, 0x4dfaa59f,
+ 0xa7feb415, 0xd79b8f71, 0x11fde7ef, 0x195eb0df, 0x5fc453d7, 0x1f088af6,
+ 0x70b9ecad, 0xe11394d4, 0xbf9db6a7, 0xe205ea7f, 0x17e4958f, 0x3bfd9e42,
+ 0xf14c5095, 0xdcf67cd4, 0x979638da, 0x636ebee7, 0x1b64dbfd, 0x47776d3e,
+ 0xcf7ef9f0, 0x7d4ab4ff, 0xd177ca19, 0x63ba2bb8, 0x4fffd03d, 0xb1d2fa55,
+ 0x0f42f8de, 0xad32e5d3, 0x251def89, 0xbf50b3fa, 0x9ebf0c52, 0xbf9afd41,
+ 0xda3676f1, 0xb6ee381f, 0x1cb70f41, 0xe191d92b, 0x177ef7c2, 0xe1c5b5f8,
+ 0x58cfc1b4, 0xed992dbf, 0x8cba736e, 0x73c712db, 0x47a34bde, 0xb78c8555,
+ 0xb829527d, 0x979ea2bc, 0x25d64108, 0x6e927e86, 0xc5a6f2d1, 0x58e3a311,
+ 0xf3ca7891, 0x0710733b, 0x3e9e1549, 0x217c44d7, 0x8d2b61ce, 0xe3a251c4,
+ 0x6af2e31d, 0x9df88613, 0x50a9ae56, 0xdbcef70c, 0x85abcfc7, 0xd7e1d38b,
+ 0x1138a63f, 0xb8736e6f, 0xb826adee, 0x37158ced, 0x8a7d4532, 0xf04996cb,
+ 0x738a23c8, 0xb9bde83f, 0x1356f584, 0xf78a5268, 0xb72cd50b, 0xcb2a416d,
+ 0xafef96a6, 0xd66a763e, 0x90afb1f7, 0xb67586d7, 0x14b6bd39, 0xdad3df9d,
+ 0xf7f578af, 0xb1b83520, 0x9b0dc642, 0xfc0118e8, 0x6dd9b7dd, 0x2538895b,
+ 0xffb83fb9, 0x13e546b7, 0xc7ea3bed, 0x73ea1ff7, 0xabe0ebc4, 0xf417da11,
+ 0xd52be616, 0xe312bf8d, 0xfea7e6eb, 0x56b5b7ec, 0x2d78f024, 0x1bb7da4e,
+ 0x49d793a5, 0x8d3c6078, 0x5cf1a1ec, 0xbde30f3c, 0x7ab41435, 0xbbdc1eb0,
+ 0x33857820, 0x2b3cc568, 0x7c7095b7, 0xce5bbfdf, 0x6c99dfe3, 0x675f822b,
+ 0xe966da71, 0x3be23dfd, 0x0e1365f0, 0x5ebca9f7, 0x08db87f6, 0x43f0294f,
+ 0x75ffc853, 0x8b57c44c, 0xfeb6feba, 0xd8ffa364, 0xf41598ff, 0x4aed5469,
+ 0x549e1d34, 0xb6e578f9, 0xd7786c5b, 0xf2f166d0, 0x8abf07bb, 0x10df7fef,
+ 0x90f90bbb, 0xad2781c6, 0xae1f826e, 0x93f67e90, 0xeadf9215, 0xb8f94273,
+ 0x21b231e7, 0x3721ef96, 0xbf79fb3a, 0x9c7ef8e3, 0xc4ff03f0, 0x137c63e9,
+ 0x9f70049f, 0x48c06daf, 0x127ac8df, 0x81b6dc78, 0x55bf9616, 0xa9cdbf16,
+ 0x13dec75f, 0xa5e10af9, 0x815ee491, 0xb3fa71fd, 0x1f173fc1, 0xf79b37bf,
+ 0x7be4eb49, 0xe2d71e54, 0x37cc798c, 0xff1ad7cc, 0x79499734, 0xa97be6d6,
+ 0xbdf3c2c2, 0xb4e525f4, 0xdf0b776d, 0x10cd6983, 0x62f9451e, 0x53e4d539,
+ 0x3546d793, 0x7bbad92e, 0xf4ebf089, 0xeeefd90d, 0xcfc12797, 0x2b9d7565,
+ 0x3e127a54, 0xb8ba135f, 0x3d2abbdd, 0x728c729b, 0xee30f18f, 0x9bee5529,
+ 0x37f28616, 0x6bfa4614, 0xc8a536f3, 0xe0ffc0ef, 0xbd2a53b3, 0xf7237fd1,
+ 0xeaa4f157, 0xbd71d68d, 0x1a7b6871, 0x8561c6f4, 0xf71b54f3, 0xe36ebf48,
+ 0xe71c098b, 0xaf8d8ffa, 0xea1ef8fe, 0x8313c9f7, 0x13f7facd, 0x27a9216d,
+ 0x829fc9da, 0xdaa558de, 0xff6286fd, 0x72742b4f, 0x17adf6dc, 0xac5c81af,
+ 0xf8b92a18, 0x0efbc14b, 0xeafcdf41, 0x73be1fc5, 0x5f622b83, 0xdcac7db5,
+ 0x16d66ff9, 0x726f1e87, 0x560abb9f, 0x493cef0a, 0x5ac39c2f, 0x1df229b7,
+ 0xfd8d8f59, 0xd1de8d4f, 0xf242d07c, 0xf088eadb, 0xa9ff4681, 0x78db26fc,
+ 0x5fd24e3e, 0x07c6b7a3, 0x3a35bd1a, 0x9d297bf1, 0xfbadafff, 0x2b5e9533,
+ 0x531dfe54, 0x87456ee5, 0xe58ab6db, 0x056b6ddd, 0xb1fa6bdf, 0x4e3f58cd,
+ 0x7eb8e727, 0xc0b901df, 0x69d022bb, 0xc655b774, 0xa04d0f23, 0xbeec3653,
+ 0x6ad58eb6, 0x8d5db1dc, 0xfcd2ae1f, 0x4c7f62e0, 0xab4e8ea5, 0x6a74939f,
+ 0x5fede97d, 0xfbc5c0ff, 0x4f6c7a93, 0x2b8bfb0c, 0xbd330e87, 0x663e771a,
+ 0xf4bf5375, 0x5f41b74a, 0x389776b7, 0xb15f3711, 0xf90ad073, 0x4d74af4f,
+ 0xea4defca, 0xaf0d60bd, 0xce8a3fb0, 0xa1fd69ee, 0x3cd30ef7, 0x26c4379b,
+ 0x368d1ee2, 0xf252b78f, 0x72776b75, 0xed6be60a, 0x381ff96e, 0x3f7a68cf,
+ 0xc42eee5a, 0x4958794a, 0x2f2e429f, 0xdec9e2dc, 0x3f313858, 0x959595a6,
+ 0x10cf6e92, 0x256f717a, 0xbbe87e2b, 0x03d643c0, 0x93e41e71, 0x41c2f2f3,
+ 0xc63e0bcc, 0x17a46dba, 0xaf25ff71, 0xac7bfc33, 0xbe745c83, 0x213282ef,
+ 0xd23be645, 0x926fde08, 0xcc72b3ef, 0x52afbcb2, 0x0f6a3bda, 0x86a45da1,
+ 0x68ffb1cb, 0x5f9535bd, 0x36a7f1a1, 0x9a9eb44e, 0x57777f6a, 0xa2fa794a,
+ 0xab705dfd, 0x4f029371, 0x6de69db6, 0x078e747e, 0xda2fa471, 0xe64e2da7,
+ 0x4bf7c697, 0x32955acc, 0xe4f37ec9, 0xfdea6839, 0x4da6d40e, 0x7909dfb2,
+ 0xb44e555f, 0x79e3efbb, 0x27997e92, 0xdd90a0b9, 0x6c2eefa2, 0x65fbe588,
+ 0x38b4beda, 0x5efadffd, 0x14cac1e1, 0x4e14fe35, 0x14d93f80, 0x487fcaa7,
+ 0xa25fa8c2, 0xfdecd7ab, 0x21386739, 0x3f9fa745, 0xa1ed56ea, 0x3c81ef08,
+ 0x815c9e8b, 0xfeb9c778, 0x42a6090b, 0x9f5ca7f0, 0xab66ddf6, 0xf40f5ce7,
+ 0xbe18f6dc, 0xd37e4eef, 0xda93c40e, 0xa71cc903, 0xeca7afb9, 0xe71a5ee2,
+ 0xfc596dbe, 0xf3f350de, 0x2ffaa957, 0x8ecb737e, 0xebdff44a, 0x6f8fc276,
+ 0x886cf877, 0x2c0fc5c3, 0xdfb0e5b1, 0x5a01cf2b, 0x22b36ade, 0x0c9efc7c,
+ 0x657211fa, 0x7b07913a, 0xf4af7ab3, 0x624debff, 0xb39bf227, 0x338b7cfb,
+ 0x529e1fa1, 0xc527f03c, 0xdaa3d23e, 0xc7748c79, 0x6fbec587, 0xef68bf41,
+ 0xc6c2e6ef, 0x219fb19a, 0x829dce2f, 0x07ec0bfc, 0xa65e01eb, 0x6e71fca9,
+ 0xab827ce0, 0x2fcf8230, 0xe3481efb, 0xd67f2d0b, 0x194ff88e, 0x0d29a3f8,
+ 0xe6a6d1fc, 0x2c0c76c9, 0x707db862, 0xe9fbbf19, 0x473a6743, 0xfb563db6,
+ 0xef08a044, 0xda3e2578, 0x09dd16ba, 0x7f63a8bf, 0x35ce324c, 0xb640d6d9,
+ 0x1b6d0fde, 0x01df987c, 0xe58c1a5d, 0xce354077, 0x67b83525, 0x7c9f6ab3,
+ 0x3bf5a767, 0xb597eaa1, 0xef0c8b5d, 0x4c69da79, 0xd9ff8d27, 0x5fdf3c50,
+ 0x04e9ded3, 0x95e3feec, 0x4ebdf2e5, 0xd3be4bb5, 0xaefee4c9, 0x5af4e349,
+ 0xbe57b179, 0x3bbdd0fb, 0xbe91b3ba, 0x257aecef, 0x7bace311, 0x4e1567fc,
+ 0xceb7c713, 0x77f1fc60, 0xbbe57b47, 0x27c7f6a3, 0xbe03ff7f, 0x1c767f06,
+ 0xc6790c53, 0xec4982fb, 0xc243fa87, 0xdfb6fc86, 0xbdcfd829, 0xb03d1664,
+ 0xa25f9aeb, 0xc552ffd5, 0xfea4a5c3, 0xcd7fd06c, 0x61b32781, 0x20937e37,
+ 0xf703a6e1, 0xc87a08fe, 0xf48c7cff, 0xfd822dbf, 0xf480d6db, 0x64f7b597,
+ 0x38ec7842, 0x19547f87, 0x46b9f2cf, 0xada4977d, 0xae0bfc8b, 0xd4458dff,
+ 0x6f781d61, 0xdf7e7e04, 0x3d076a12, 0x147f27df, 0x2a138f79, 0x6fdfbdff,
+ 0x87f7cc5e, 0x57e01048, 0x4affdfbc, 0x9a89f202, 0xfe6b561f, 0xb4ef1795,
+ 0xef951e37, 0x870be381, 0xd4231cf9, 0xa77ac978, 0xdf8db7e4, 0x4ace2eb7,
+ 0x6b8abf65, 0xdb212d3a, 0xab5af464, 0xf0e34dfa, 0x2e7cc391, 0xfd243ceb,
+ 0xf3a1ce82, 0x7e6817ec, 0x70bef686, 0xecf3a1dd, 0xaddf6827, 0xd2f1223f,
+ 0xb7d64475, 0x78b49814, 0xc3c9578b, 0x38615979, 0xb4d2c2bf, 0x9b9b00d5,
+ 0x3a505ab6, 0x08c878d5, 0x0abbe5fb, 0x99e7ca7e, 0xb8ea6dae, 0xf3755b04,
+ 0x974d56c5, 0x3ea8daef, 0xa5ef81d7, 0xbbdad73d, 0x50f3c88e, 0x276e2ba8,
+ 0xef5d83df, 0xebeca0b0, 0xdf3db072, 0xc02a6dd7, 0x12af757d, 0x71dcfec7,
+ 0xf4d6fef5, 0x22c6ef75, 0x4629904e, 0x7cdc994e, 0x15666b6f, 0x022e9b8d,
+ 0x7b4b8f7c, 0x9fe5744f, 0xf8c32e3f, 0xafc2620b, 0x5b980220, 0x7909a335,
+ 0xe1490593, 0xf73c6032, 0xd384ba58, 0x0e20afc3, 0x37240ce5, 0xa5f28f21,
+ 0x8af54ae3, 0x30eece21, 0x0a07aff9, 0xdb2ec6ba, 0xc4635c64, 0x5799b906,
+ 0xfa68f925, 0xe2473a49, 0x83b9f51c, 0xd3e981cf, 0x9b9df9ba, 0xa1970c28,
+ 0x837c71df, 0x8c7f60fb, 0x420eff93, 0xf6f5979e, 0x027558c6, 0x3de99797,
+ 0xa425aeaa, 0x9f0363e6, 0xf7f8829b, 0xa12b8e04, 0xbcfdeb6f, 0x4f292aee,
+ 0x979918be, 0xceb14bbd, 0xe4fa27fa, 0x835fdb90, 0xcc72fa75, 0xb8b92545,
+ 0x7def2b17, 0xb7f3515f, 0x50bcbf9a, 0x7a96769d, 0xc8cdb3ce, 0xb4fe4070,
+ 0xd78a89fb, 0x1f52efcb, 0x8ad93c2a, 0xc4737f75, 0x1620efce, 0x73c9c48e,
+ 0xb63a8cd5, 0xd9b17daf, 0x2e283fec, 0xfea2688b, 0x214d0b27, 0xa6ffdfdc,
+ 0x599e73b0, 0x6dfca3d8, 0xc3df2c53, 0xf1bf8e56, 0x964dec39, 0x92a7f7f9,
+ 0xff599f68, 0x8ba078a0, 0xfe2f479b, 0x6ca84fe3, 0x187fdb1a, 0xfe4911fb,
+ 0xb9c3f066, 0x7ef3bad1, 0x9d37f542, 0xb48f7643, 0x8fbf4263, 0x9e7e0fe3,
+ 0xac8a6298, 0xc5c8caef, 0x879d5f17, 0xe9f1ced2, 0x32cdc785, 0x9eb5159e,
+ 0xbe2e192b, 0x98fd4e0f, 0xa61c573e, 0x0b87ce20, 0x0f7a9f8f, 0x7b885beb,
+ 0xd83738ce, 0xf6f597ad, 0x2566b84e, 0x150e7e23, 0x88ac97fa, 0xb540783e,
+ 0xae7d694b, 0x7b08dc9f, 0x2059a6f9, 0x651440ee, 0x07d6883e, 0x425f833f,
+ 0xaa37c6fe, 0x07ed79e4, 0x546fbe39, 0x67065cb1, 0x9be72e41, 0xb69fbf27,
+ 0xe3514aaf, 0xd1ae9259, 0x8ba68b74, 0xe7716f86, 0x8524e9f0, 0xa8f45cf1,
+ 0xc62eefc4, 0xb767e7ef, 0x198a9893, 0xc636fbff, 0xf86ffff3, 0xca7de2fd,
+ 0xfbe373f7, 0xd3ed3afc, 0x77e7d86d, 0x93ed1ffe, 0xbcdfc0f5, 0x3ee361cf,
+ 0xb142fad3, 0x8f37c073, 0x8acfd89b, 0x0a2a37be, 0x66d1eb04, 0x53c71c73,
+ 0xddf271fd, 0xd3cfe901, 0xde9a9fd0, 0x2e175d9c, 0x4e71bf82, 0xaeb16788,
+ 0xeb8869b0, 0x30e5562f, 0xc314ccdf, 0xc27efc99, 0x3f872e12, 0x35bfb66b,
+ 0x4bb223f7, 0x0f048f03, 0xf4e34abf, 0x56a7c129, 0xeddd5f41, 0x95dcfce0,
+ 0xa56029a0, 0x45920679, 0x7f9a31f1, 0xce5ccd60, 0xaa115cb3, 0xb1b06a9e,
+ 0xecf6a29e, 0xca37b41e, 0xf9fdeff6, 0xa3f81ec2, 0xf782f923, 0xae225033,
+ 0xc0f04bd9, 0xff6e0292, 0xf6e7a6a1, 0x97efc824, 0x8193e608, 0xef7c2935,
+ 0x83a7e9e4, 0x0e8ec2d7, 0x11337a0c, 0xf44cab57, 0x19c74187, 0x079f6966,
+ 0xe54f54dc, 0xb1af8a13, 0xc914e31d, 0xe31b86f5, 0x43403a5e, 0x2a91e6c5,
+ 0x3d73faa5, 0xd5cf9c09, 0x638b47e4, 0x7f9c0ecf, 0xded2780a, 0xf2a07f23,
+ 0xc5778699, 0xa667df2b, 0xe8d678aa, 0x6a5bf1a0, 0xa6cf7c9c, 0x377c916c,
+ 0xbd791f7e, 0x33c8fbe0, 0x27782969, 0x71e31cd7, 0x4adfdf01, 0xfd618ff2,
+ 0x3e881b7d, 0xd243ec66, 0x5bde1ce1, 0x997fe24e, 0x7e5a4dab, 0x3463df9f,
+ 0x9a5fa90b, 0x3d17f7b5, 0x2217f7c6, 0xef19333c, 0xe89f9891, 0x3edd67fb,
+ 0x5fbe355b, 0xd2fb65ee, 0xd9def2ac, 0x7a4f34ff, 0x5aa9286f, 0x623b95da,
+ 0x9dfc89fd, 0xf3450efa, 0x7c96cfc3, 0xe4f60b3c, 0xcc6f83dc, 0xa2577944,
+ 0xf69ab92f, 0x1fe344f3, 0x7dc4c316, 0xf7e61990, 0xfe341f34, 0xe5c71671,
+ 0xfcc1bcb7, 0x57aeb7ff, 0x01ffc75b, 0x0934e170, 0x000048d0
};
#endif /*__BNX2X_INIT_VALUES_H__*/
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
new file mode 100644
index 00000000000..ff2743db10d
--- /dev/null
+++ b/drivers/net/bnx2x_link.c
@@ -0,0 +1,4527 @@
+/* Copyright 2008 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *
+ * Written by Yaniv Rosner
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/mutex.h>
+#include <linux/version.h>
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "bnx2x_link.h"
+#include "bnx2x.h"
+
+/********************************************************/
+#define SUPPORT_CL73 0 /* Currently no */
+#define ETH_HLEN 14
+#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
+#define ETH_MIN_PACKET_SIZE 60
+#define ETH_MAX_PACKET_SIZE 1500
+#define ETH_MAX_JUMBO_PACKET_SIZE 9600
+#define MDIO_ACCESS_TIMEOUT 1000
+#define BMAC_CONTROL_RX_ENABLE 2
+#define MAX_MTU_SIZE 5000
+
+/***********************************************************/
+/* Shortcut definitions */
+/***********************************************************/
+
+#define NIG_STATUS_XGXS0_LINK10G \
+ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
+#define NIG_STATUS_XGXS0_LINK_STATUS \
+ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
+#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
+ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
+#define NIG_STATUS_SERDES0_LINK_STATUS \
+ NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
+#define NIG_MASK_MI_INT \
+ NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
+#define NIG_MASK_XGXS0_LINK10G \
+ NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
+#define NIG_MASK_XGXS0_LINK_STATUS \
+ NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
+#define NIG_MASK_SERDES0_LINK_STATUS \
+ NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
+
+#define MDIO_AN_CL73_OR_37_COMPLETE \
+ (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
+
+#define XGXS_RESET_BITS \
+ (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
+
+#define SERDES_RESET_BITS \
+ (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
+ MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
+
+#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
+#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
+#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
+#define AUTONEG_PARALLEL \
+ SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
+#define AUTONEG_SGMII_FIBER_AUTODET \
+ SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
+#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
+
+#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
+#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
+#define GP_STATUS_SPEED_MASK \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
+#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
+#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
+#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
+#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
+#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
+#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
+#define GP_STATUS_10G_HIG \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
+#define GP_STATUS_10G_CX4 \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
+#define GP_STATUS_12G_HIG \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
+#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
+#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
+#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
+#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
+#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
+#define GP_STATUS_10G_KX4 \
+ MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
+
+#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
+#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
+#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
+#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
+#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
+#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
+#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
+#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
+#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
+#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
+#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
+#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
+#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
+#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
+#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
+#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
+#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
+#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
+#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
+#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
+#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
+#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
+#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
+
+#define PHY_XGXS_FLAG 0x1
+#define PHY_SGMII_FLAG 0x2
+#define PHY_SERDES_FLAG 0x4
+
+/**********************************************************/
+/* INTERFACE */
+/**********************************************************/
+#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
+ bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
+ DEFAULT_PHY_DEV_ADDR, \
+ (_bank + (_addr & 0xf)), \
+ _val)
+
+#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
+ bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
+ DEFAULT_PHY_DEV_ADDR, \
+ (_bank + (_addr & 0xf)), \
+ _val)
+
+static void bnx2x_set_phy_mdio(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
+ params->port*0x18, 0);
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
+ DEFAULT_PHY_DEV_ADDR);
+}
+
+static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
+{
+ u32 val = REG_RD(bp, reg);
+
+ val |= bits;
+ REG_WR(bp, reg, val);
+ return val;
+}
+
+static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
+{
+ u32 val = REG_RD(bp, reg);
+
+ val &= ~bits;
+ REG_WR(bp, reg, val);
+ return val;
+}
+
+static void bnx2x_emac_init(struct link_params *params,
+ struct link_vars *vars)
+{
+ /* reset and unreset the emac core */
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ u32 val;
+ u16 timeout;
+
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
+ udelay(5);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+ (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
+
+ /* init emac - use read-modify-write */
+ /* self clear reset */
+ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+ EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
+
+ timeout = 200;
+ do
+ {
+ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+ DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
+ if (!timeout) {
+ DP(NETIF_MSG_LINK, "EMAC timeout!\n");
+ return;
+ }
+ timeout--;
+ }while (val & EMAC_MODE_RESET);
+
+ /* Set mac address */
+ val = ((params->mac_addr[0] << 8) |
+ params->mac_addr[1]);
+ EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
+
+ val = ((params->mac_addr[2] << 24) |
+ (params->mac_addr[3] << 16) |
+ (params->mac_addr[4] << 8) |
+ params->mac_addr[5]);
+ EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
+}
+
+static u8 bnx2x_emac_enable(struct link_params *params,
+ struct link_vars *vars, u8 lb)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ u32 val;
+
+ DP(NETIF_MSG_LINK, "enabling EMAC\n");
+
+ /* enable emac and not bmac */
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
+
+ /* for paladium */
+ if (CHIP_REV_IS_EMUL(bp)) {
+ /* Use lane 1 (of lanes 0-3) */
+ REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
+ port*4, 1);
+ }
+ /* for fpga */
+ else
+
+ if (CHIP_REV_IS_FPGA(bp)) {
+ /* Use lane 1 (of lanes 0-3) */
+ DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
+
+ REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
+ 0);
+ } else
+ /* ASIC */
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ u32 ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+
+ DP(NETIF_MSG_LINK, "XGXS\n");
+ /* select the master lanes (out of 0-3) */
+ REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
+ port*4, ser_lane);
+ /* select XGXS */
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
+ port*4, 1);
+
+ } else { /* SerDes */
+ DP(NETIF_MSG_LINK, "SerDes\n");
+ /* select SerDes */
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
+ port*4, 0);
+ }
+
+ /* enable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+
+ if (CHIP_REV_IS_SLOW(bp)) {
+ /* config GMII mode */
+ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+ EMAC_WR(EMAC_REG_EMAC_MODE,
+ (val | EMAC_MODE_PORT_GMII));
+ } else { /* ASIC */
+ /* pause enable/disable */
+ bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_FLOW_EN);
+ if (vars->flow_ctrl & FLOW_CTRL_RX)
+ bnx2x_bits_en(bp, emac_base +
+ EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_FLOW_EN);
+
+ bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+ EMAC_TX_MODE_EXT_PAUSE_EN);
+ if (vars->flow_ctrl & FLOW_CTRL_TX)
+ bnx2x_bits_en(bp, emac_base +
+ EMAC_REG_EMAC_TX_MODE,
+ EMAC_TX_MODE_EXT_PAUSE_EN);
+ }
+
+ /* KEEP_VLAN_TAG, promiscuous */
+ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
+ val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
+ EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
+
+ /* Set Loopback */
+ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+ if (lb)
+ val |= 0x810;
+ else
+ val &= ~0x810;
+ EMAC_WR(EMAC_REG_EMAC_MODE, val);
+
+ /* enable emac for jumbo packets */
+ EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
+ (EMAC_RX_MTU_SIZE_JUMBO_ENA |
+ (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
+
+ /* strip CRC */
+ REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
+
+ /* disable the NIG in/out to the bmac */
+ REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
+
+ /* enable the NIG in/out to the emac */
+ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
+ val = 0;
+ if (vars->flow_ctrl & FLOW_CTRL_TX)
+ val = 1;
+
+ REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
+
+ if (CHIP_REV_IS_EMUL(bp)) {
+ /* take the BigMac out of reset */
+ REG_WR(bp,
+ GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+ /* enable access for bmac registers */
+ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
+ }
+
+ vars->mac_type = MAC_TYPE_EMAC;
+ return 0;
+}
+
+
+
+static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
+ u8 is_lb)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+ u32 wb_data[2];
+ u32 val;
+
+ DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
+ /* reset and unreset the BigMac */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+ msleep(1);
+
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+ /* enable access for bmac registers */
+ REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
+
+ /* XGXS control */
+ wb_data[0] = 0x3c;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr +
+ BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
+ wb_data, 2);
+
+ /* tx MAC SA */
+ wb_data[0] = ((params->mac_addr[2] << 24) |
+ (params->mac_addr[3] << 16) |
+ (params->mac_addr[4] << 8) |
+ params->mac_addr[5]);
+ wb_data[1] = ((params->mac_addr[0] << 8) |
+ params->mac_addr[1]);
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
+ wb_data, 2);
+
+ /* tx control */
+ val = 0xc0;
+ if (vars->flow_ctrl & FLOW_CTRL_TX)
+ val |= 0x800000;
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
+ wb_data, 2);
+
+ /* mac control */
+ val = 0x3;
+ if (is_lb) {
+ val |= 0x4;
+ DP(NETIF_MSG_LINK, "enable bmac loopback\n");
+ }
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+
+
+ /* set rx mtu */
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
+ wb_data, 2);
+
+ /* rx control set to don't strip crc */
+ val = 0x14;
+ if (vars->flow_ctrl & FLOW_CTRL_RX)
+ val |= 0x20;
+ wb_data[0] = val;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
+ wb_data, 2);
+
+ /* set tx mtu */
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
+ wb_data, 2);
+
+ /* set cnt max size */
+ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
+ wb_data, 2);
+
+ /* configure safc */
+ wb_data[0] = 0x1000200;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
+ wb_data, 2);
+ /* fix for emulation */
+ if (CHIP_REV_IS_EMUL(bp)) {
+ wb_data[0] = 0xf000;
+ wb_data[1] = 0;
+ REG_WR_DMAE(bp,
+ bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
+ wb_data, 2);
+ }
+
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
+ REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
+ val = 0;
+ if (vars->flow_ctrl & FLOW_CTRL_TX)
+ val = 1;
+ REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
+ REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
+ REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
+
+ vars->mac_type = MAC_TYPE_BMAC;
+ return 0;
+}
+
+static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
+{
+ struct bnx2x *bp = params->bp;
+ u32 val;
+
+ if (phy_flags & PHY_XGXS_FLAG) {
+ DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
+ val = XGXS_RESET_BITS;
+
+ } else { /* SerDes */
+ DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
+ val = SERDES_RESET_BITS;
+ }
+
+ val = val << (params->port*16);
+
+ /* reset and unreset the SerDes/XGXS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
+ val);
+ udelay(500);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
+ val);
+ bnx2x_set_phy_mdio(params);
+}
+
+void bnx2x_link_status_update(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 link_10g;
+ u8 port = params->port;
+
+ if (params->switch_cfg == SWITCH_CFG_1G)
+ vars->phy_flags = PHY_SERDES_FLAG;
+ else
+ vars->phy_flags = PHY_XGXS_FLAG;
+ vars->link_status = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[port].link_status));
+
+ vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
+
+ if (vars->link_up) {
+ DP(NETIF_MSG_LINK, "phy link up\n");
+
+ vars->phy_link_up = 1;
+ vars->duplex = DUPLEX_FULL;
+ switch (vars->link_status &
+ LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
+ case LINK_10THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_10TFD:
+ vars->line_speed = SPEED_10;
+ break;
+
+ case LINK_100TXHD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_100T4:
+ case LINK_100TXFD:
+ vars->line_speed = SPEED_100;
+ break;
+
+ case LINK_1000THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_1000TFD:
+ vars->line_speed = SPEED_1000;
+ break;
+
+ case LINK_2500THD:
+ vars->duplex = DUPLEX_HALF;
+ /* fall thru */
+ case LINK_2500TFD:
+ vars->line_speed = SPEED_2500;
+ break;
+
+ case LINK_10GTFD:
+ vars->line_speed = SPEED_10000;
+ break;
+
+ case LINK_12GTFD:
+ vars->line_speed = SPEED_12000;
+ break;
+
+ case LINK_12_5GTFD:
+ vars->line_speed = SPEED_12500;
+ break;
+
+ case LINK_13GTFD:
+ vars->line_speed = SPEED_13000;
+ break;
+
+ case LINK_15GTFD:
+ vars->line_speed = SPEED_15000;
+ break;
+
+ case LINK_16GTFD:
+ vars->line_speed = SPEED_16000;
+ break;
+
+ default:
+ break;
+ }
+
+ if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
+ vars->flow_ctrl |= FLOW_CTRL_TX;
+ else
+ vars->flow_ctrl &= ~FLOW_CTRL_TX;
+
+ if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
+ vars->flow_ctrl |= FLOW_CTRL_RX;
+ else
+ vars->flow_ctrl &= ~FLOW_CTRL_RX;
+
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ if (params->req_line_speed &&
+ ((params->req_line_speed == SPEED_10) ||
+ (params->req_line_speed == SPEED_100))) {
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ } else {
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ }
+ }
+
+ /* anything 10 and over uses the bmac */
+ link_10g = ((vars->line_speed == SPEED_10000) ||
+ (vars->line_speed == SPEED_12000) ||
+ (vars->line_speed == SPEED_12500) ||
+ (vars->line_speed == SPEED_13000) ||
+ (vars->line_speed == SPEED_15000) ||
+ (vars->line_speed == SPEED_16000));
+ if (link_10g)
+ vars->mac_type = MAC_TYPE_BMAC;
+ else
+ vars->mac_type = MAC_TYPE_EMAC;
+
+ } else { /* link down */
+ DP(NETIF_MSG_LINK, "phy link down\n");
+
+ vars->phy_link_up = 0;
+
+ vars->line_speed = 0;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+
+ /* indicate no mac active */
+ vars->mac_type = MAC_TYPE_NONE;
+ }
+
+ DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
+ vars->link_status, vars->phy_link_up);
+ DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
+ vars->line_speed, vars->duplex, vars->flow_ctrl);
+}
+
+static void bnx2x_update_mng(struct link_params *params, u32 link_status)
+{
+ struct bnx2x *bp = params->bp;
+ REG_WR(bp, params->shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[params->port].link_status),
+ link_status);
+}
+
+static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
+{
+ u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM;
+ u32 wb_data[2];
+ u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
+
+ /* Only if the bmac is out of reset */
+ if (REG_RD(bp, MISC_REG_RESET_REG_2) &
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
+ nig_bmac_enable) {
+
+ /* Clear Rx Enable bit in BMAC_CONTROL register */
+ REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+ wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
+ REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+ wb_data, 2);
+
+ msleep(1);
+ }
+}
+
+static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
+ u32 line_speed)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u32 init_crd, crd;
+ u32 count = 1000;
+ u32 pause = 0;
+
+ /* disable port */
+ REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
+
+ /* wait for init credit */
+ init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
+ crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
+ DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
+
+ while ((init_crd != crd) && count) {
+ msleep(5);
+
+ crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
+ count--;
+ }
+ crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
+ if (init_crd != crd) {
+ DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
+ init_crd, crd);
+ return -EINVAL;
+ }
+
+ if (flow_ctrl & FLOW_CTRL_RX)
+ pause = 1;
+ REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause);
+ if (pause) {
+ /* update threshold */
+ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
+ /* update init credit */
+ init_crd = 778; /* (800-18-4) */
+
+ } else {
+ u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
+ ETH_OVREHEAD)/16;
+
+ /* update threshold */
+ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
+ /* update init credit */
+ switch (line_speed) {
+ case SPEED_10:
+ case SPEED_100:
+ case SPEED_1000:
+ init_crd = thresh + 55 - 22;
+ break;
+
+ case SPEED_2500:
+ init_crd = thresh + 138 - 22;
+ break;
+
+ case SPEED_10000:
+ init_crd = thresh + 553 - 22;
+ break;
+
+ case SPEED_12000:
+ init_crd = thresh + 664 - 22;
+ break;
+
+ case SPEED_13000:
+ init_crd = thresh + 742 - 22;
+ break;
+
+ case SPEED_16000:
+ init_crd = thresh + 778 - 22;
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
+ line_speed);
+ return -EINVAL;
+ break;
+ }
+ }
+ REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
+ DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
+ line_speed, init_crd);
+
+ /* probe the credit changes */
+ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
+ msleep(5);
+ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
+
+ /* enable port */
+ REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
+ return 0;
+}
+
+static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
+{
+ u32 emac_base;
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ emac_base = GRCBASE_EMAC0;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1;
+ break;
+ default:
+ emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0;
+ break;
+ }
+ return emac_base;
+
+}
+
+u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
+ u8 phy_addr, u8 devad, u16 reg, u16 val)
+{
+ u32 tmp, saved_mode;
+ u8 i, rc = 0;
+ u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+
+ /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+ saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
+ EMAC_MDIO_MODE_CLOCK_CNT);
+ tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
+ (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
+ REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ udelay(40);
+
+ /* address */
+
+ tmp = ((phy_addr << 21) | (devad << 16) | reg |
+ EMAC_MDIO_COMM_COMMAND_ADDRESS |
+ EMAC_MDIO_COMM_START_BUSY);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+
+ for (i = 0; i < 50; i++) {
+ udelay(10);
+
+ tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
+ udelay(5);
+ break;
+ }
+ }
+ if (tmp & EMAC_MDIO_COMM_START_BUSY) {
+ DP(NETIF_MSG_LINK, "write phy register failed\n");
+ rc = -EFAULT;
+ } else {
+ /* data */
+ tmp = ((phy_addr << 21) | (devad << 16) | val |
+ EMAC_MDIO_COMM_COMMAND_WRITE_45 |
+ EMAC_MDIO_COMM_START_BUSY);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
+
+ for (i = 0; i < 50; i++) {
+ udelay(10);
+
+ tmp = REG_RD(bp, mdio_ctrl +
+ EMAC_REG_EMAC_MDIO_COMM);
+ if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
+ udelay(5);
+ break;
+ }
+ }
+ if (tmp & EMAC_MDIO_COMM_START_BUSY) {
+ DP(NETIF_MSG_LINK, "write phy register failed\n");
+ rc = -EFAULT;
+ }
+ }
+
+ /* Restore the saved mode */
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
+
+ return rc;
+}
+
+u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
+ u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
+{
+ u32 val, saved_mode;
+ u16 i;
+ u8 rc = 0;
+
+ u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+ /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ * (a value of 49==0x31) and make sure that the AUTO poll is off
+ */
+ saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
+ EMAC_MDIO_MODE_CLOCK_CNT));
+ val |= (EMAC_MDIO_MODE_CLAUSE_45 |
+ (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
+ REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
+ udelay(40);
+
+ /* address */
+ val = ((phy_addr << 21) | (devad << 16) | reg |
+ EMAC_MDIO_COMM_COMMAND_ADDRESS |
+ EMAC_MDIO_COMM_START_BUSY);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
+
+ for (i = 0; i < 50; i++) {
+ udelay(10);
+
+ val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
+ if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
+ udelay(5);
+ break;
+ }
+ }
+ if (val & EMAC_MDIO_COMM_START_BUSY) {
+ DP(NETIF_MSG_LINK, "read phy register failed\n");
+
+ *ret_val = 0;
+ rc = -EFAULT;
+
+ } else {
+ /* data */
+ val = ((phy_addr << 21) | (devad << 16) |
+ EMAC_MDIO_COMM_COMMAND_READ_45 |
+ EMAC_MDIO_COMM_START_BUSY);
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
+
+ for (i = 0; i < 50; i++) {
+ udelay(10);
+
+ val = REG_RD(bp, mdio_ctrl +
+ EMAC_REG_EMAC_MDIO_COMM);
+ if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
+ *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
+ break;
+ }
+ }
+ if (val & EMAC_MDIO_COMM_START_BUSY) {
+ DP(NETIF_MSG_LINK, "read phy register failed\n");
+
+ *ret_val = 0;
+ rc = -EFAULT;
+ }
+ }
+
+ /* Restore the saved mode */
+ REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
+
+ return rc;
+}
+
+static void bnx2x_set_aer_mmd(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u32 ser_lane;
+ u16 offset;
+
+ ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+
+ offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
+ (params->phy_addr + ser_lane) : 0;
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_AER_BLOCK,
+ MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
+}
+
+static void bnx2x_set_master_ln(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u16 new_master_ln, ser_lane;
+ ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+
+ /* set the master_ln for AN */
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2,
+ MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
+ &new_master_ln);
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2 ,
+ MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
+ (new_master_ln | ser_lane));
+}
+
+static u8 bnx2x_reset_unicore(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u16 mii_control;
+ u16 i;
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
+
+ /* reset the unicore */
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ (mii_control |
+ MDIO_COMBO_IEEO_MII_CONTROL_RESET));
+
+ /* wait for the reset to self clear */
+ for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
+ udelay(5);
+
+ /* the reset erased the previous bank value */
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ &mii_control);
+
+ if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
+ udelay(5);
+ return 0;
+ }
+ }
+
+ DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
+ return -EINVAL;
+
+}
+
+static void bnx2x_set_swap_lanes(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ /* Each two bits represents a lane number:
+ No swap is 0123 => 0x1b no need to enable the swap */
+ u16 ser_lane, rx_lane_swap, tx_lane_swap;
+
+ ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+ rx_lane_swap = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
+ tx_lane_swap = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
+
+ if (rx_lane_swap != 0x1b) {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2,
+ MDIO_XGXS_BLOCK2_RX_LN_SWAP,
+ (rx_lane_swap |
+ MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
+ MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
+ } else {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2,
+ MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
+ }
+
+ if (tx_lane_swap != 0x1b) {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2,
+ MDIO_XGXS_BLOCK2_TX_LN_SWAP,
+ (tx_lane_swap |
+ MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
+ } else {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2,
+ MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
+ }
+}
+
+static void bnx2x_set_parallel_detection(struct link_params *params,
+ u8 phy_flags)
+{
+ struct bnx2x *bp = params->bp;
+ u16 control2;
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
+ &control2);
+
+
+ control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
+
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
+ control2);
+
+ if (phy_flags & PHY_XGXS_FLAG) {
+ DP(NETIF_MSG_LINK, "XGXS\n");
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_10G_PARALLEL_DETECT,
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_10G_PARALLEL_DETECT,
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+ &control2);
+
+
+ control2 |=
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_10G_PARALLEL_DETECT,
+ MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+ control2);
+
+ /* Disable parallel detection of HiG */
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_XGXS_BLOCK2,
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
+ MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
+ }
+}
+
+static void bnx2x_set_autoneg(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 reg_val;
+
+ /* CL37 Autoneg */
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
+
+ /* CL37 Autoneg Enabled */
+ if (params->req_line_speed == SPEED_AUTO_NEG)
+ reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
+ else /* CL37 Autoneg Disabled */
+ reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+ MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
+
+ /* Enable/Disable Autodetection */
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
+ reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
+ if (params->req_line_speed == SPEED_AUTO_NEG)
+ reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
+ else
+ reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
+
+ /* Enable TetonII and BAM autoneg */
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_BAM_NEXT_PAGE,
+ MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
+ &reg_val);
+ if (params->req_line_speed == SPEED_AUTO_NEG) {
+ /* Enable BAM aneg Mode and TetonII aneg Mode */
+ reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
+ MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
+ } else {
+ /* TetonII and BAM Autoneg Disabled */
+ reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
+ MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
+ }
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_BAM_NEXT_PAGE,
+ MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
+ reg_val);
+
+ /* Enable Clause 73 Aneg */
+ if ((params->req_line_speed == SPEED_AUTO_NEG) &&
+ (SUPPORT_CL73)) {
+ /* Enable BAM Station Manager */
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_USERB0,
+ MDIO_CL73_USERB0_CL73_BAM_CTRL1,
+ (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
+ MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
+ MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
+
+ /* Merge CL73 and CL37 aneg resolution */
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_USERB0,
+ MDIO_CL73_USERB0_CL73_BAM_CTRL3,
+ &reg_val);
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_USERB0,
+ MDIO_CL73_USERB0_CL73_BAM_CTRL3,
+ (reg_val |
+ MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
+
+ /* Set the CL73 AN speed */
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_IEEEB1,
+ MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
+ /* In the SerDes we support only the 1G.
+ In the XGXS we support the 10G KX4
+ but we currently do not support the KR */
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ DP(NETIF_MSG_LINK, "XGXS\n");
+ /* 10G KX4 */
+ reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
+ } else {
+ DP(NETIF_MSG_LINK, "SerDes\n");
+ /* 1000M KX */
+ reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
+ }
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_IEEEB1,
+ MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
+
+ /* CL73 Autoneg Enabled */
+ reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
+ } else {
+ /* CL73 Autoneg Disabled */
+ reg_val = 0;
+ }
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_IEEEB0,
+ MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
+}
+
+/* program SerDes, forced speed */
+static void bnx2x_program_serdes(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u16 reg_val;
+
+ /* program duplex, disable autoneg */
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
+ reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
+ MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
+ if (params->req_duplex == DUPLEX_FULL)
+ reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
+
+ /* program speed
+ - needed only if the speed is greater than 1G (2.5G or 10G) */
+ if (!((params->req_line_speed == SPEED_1000) ||
+ (params->req_line_speed == SPEED_100) ||
+ (params->req_line_speed == SPEED_10))) {
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_MISC1, &reg_val);
+ /* clearing the speed value before setting the right speed */
+ reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK;
+ reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
+ MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
+ if (params->req_line_speed == SPEED_10000)
+ reg_val |=
+ MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
+ if (params->req_line_speed == SPEED_13000)
+ reg_val |=
+ MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_MISC1, reg_val);
+ }
+}
+
+static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u16 val = 0;
+
+ /* configure the 48 bits for BAM AN */
+
+ /* set extended capabilities */
+ if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
+ val |= MDIO_OVER_1G_UP1_2_5G;
+ if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+ val |= MDIO_OVER_1G_UP1_10G;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_OVER_1G,
+ MDIO_OVER_1G_UP1, val);
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_OVER_1G,
+ MDIO_OVER_1G_UP3, 0);
+}
+
+static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
+ u32 *ieee_fc)
+{
+ struct bnx2x *bp = params->bp;
+ /* for AN, we are always publishing full duplex */
+ u16 an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
+
+ /* resolve pause mode and advertisement
+ * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
+
+ switch (params->req_flow_ctrl) {
+ case FLOW_CTRL_AUTO:
+ if (params->mtu <= MAX_MTU_SIZE) {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ } else {
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ }
+ break;
+ case FLOW_CTRL_TX:
+ an_adv |=
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+ break;
+
+ case FLOW_CTRL_RX:
+ case FLOW_CTRL_BOTH:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+ break;
+
+ case FLOW_CTRL_NONE:
+ default:
+ an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+ break;
+ }
+
+ *ieee_fc = an_adv;
+
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv);
+}
+
+static void bnx2x_restart_autoneg(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
+ if (SUPPORT_CL73) {
+ /* enable and restart clause 73 aneg */
+ u16 an_ctrl;
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_IEEEB0,
+ MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+ &an_ctrl);
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_CL73_IEEEB0,
+ MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+ (an_ctrl |
+ MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
+ MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
+
+ } else {
+ /* Enable and restart BAM/CL37 aneg */
+ u16 mii_control;
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ &mii_control);
+ DP(NETIF_MSG_LINK,
+ "bnx2x_restart_autoneg mii_control before = 0x%x\n",
+ mii_control);
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ (mii_control |
+ MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+ MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
+ }
+}
+
+static void bnx2x_initialize_sgmii_process(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u16 control1;
+
+ /* in SGMII mode, the unicore is always slave */
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
+ &control1);
+ control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
+ /* set sgmii mode (and not fiber) */
+ control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_SERDES_DIGITAL,
+ MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
+ control1);
+
+ /* if forced speed */
+ if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
+ /* set speed, disable autoneg */
+ u16 mii_control;
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ &mii_control);
+ mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+ MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
+ MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
+
+ switch (params->req_line_speed) {
+ case SPEED_100:
+ mii_control |=
+ MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
+ break;
+ case SPEED_1000:
+ mii_control |=
+ MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
+ break;
+ case SPEED_10:
+ /* there is nothing to set for 10M */
+ break;
+ default:
+ /* invalid speed for SGMII */
+ DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n",
+ params->req_line_speed);
+ break;
+ }
+
+ /* setting the full duplex */
+ if (params->req_duplex == DUPLEX_FULL)
+ mii_control |=
+ MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ mii_control);
+
+ } else { /* AN mode */
+ /* enable and restart AN */
+ bnx2x_restart_autoneg(params);
+ }
+}
+
+
+/*
+ * link management
+ */
+
+static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
+{
+ switch (pause_result) { /* ASYM P ASYM P */
+ case 0xb: /* 1 0 1 1 */
+ vars->flow_ctrl = FLOW_CTRL_TX;
+ break;
+
+ case 0xe: /* 1 1 1 0 */
+ vars->flow_ctrl = FLOW_CTRL_RX;
+ break;
+
+ case 0x5: /* 0 1 0 1 */
+ case 0x7: /* 0 1 1 1 */
+ case 0xd: /* 1 1 0 1 */
+ case 0xf: /* 1 1 1 1 */
+ vars->flow_ctrl = FLOW_CTRL_BOTH;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 ext_phy_addr;
+ u16 ld_pause; /* local */
+ u16 lp_pause; /* link partner */
+ u16 an_complete; /* AN complete */
+ u16 pause_result;
+ u8 ret = 0;
+ u32 ext_phy_type;
+ u8 port = params->port;
+ ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ /* read twice */
+
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_STATUS, &an_complete);
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_STATUS, &an_complete);
+
+ if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
+ ret = 1;
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV_PAUSE, &ld_pause);
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
+ pause_result = (ld_pause &
+ MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
+ pause_result |= (lp_pause &
+ MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
+ DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
+ pause_result);
+ bnx2x_pause_resolve(vars, pause_result);
+ }
+ return ret;
+}
+
+
+static void bnx2x_flow_ctrl_resolve(struct link_params *params,
+ struct link_vars *vars,
+ u32 gp_status)
+{
+ struct bnx2x *bp = params->bp;
+ u16 ld_pause; /* local driver */
+ u16 lp_pause; /* link partner */
+ u16 pause_result;
+
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+
+ /* resolve from gp_status in case of AN complete and not sgmii */
+ if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
+ (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
+ (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
+ (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
+ &ld_pause);
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
+ &lp_pause);
+ pause_result = (ld_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
+ pause_result |= (lp_pause &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
+ DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
+ bnx2x_pause_resolve(vars, pause_result);
+ } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
+ (bnx2x_ext_phy_resove_fc(params, vars))) {
+ return;
+ } else {
+ vars->flow_ctrl = params->req_flow_ctrl;
+ if (vars->flow_ctrl == FLOW_CTRL_AUTO) {
+ if (params->mtu <= MAX_MTU_SIZE)
+ vars->flow_ctrl = FLOW_CTRL_BOTH;
+ else
+ vars->flow_ctrl = FLOW_CTRL_TX;
+ }
+ }
+ DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
+}
+
+
+static u8 bnx2x_link_settings_status(struct link_params *params,
+ struct link_vars *vars,
+ u32 gp_status)
+{
+ struct bnx2x *bp = params->bp;
+ u8 rc = 0;
+ vars->link_status = 0;
+
+ if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
+ DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
+ gp_status);
+
+ vars->phy_link_up = 1;
+ vars->link_status |= LINK_STATUS_LINK_UP;
+
+ if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
+ vars->duplex = DUPLEX_FULL;
+ else
+ vars->duplex = DUPLEX_HALF;
+
+ bnx2x_flow_ctrl_resolve(params, vars, gp_status);
+
+ switch (gp_status & GP_STATUS_SPEED_MASK) {
+ case GP_STATUS_10M:
+ vars->line_speed = SPEED_10;
+ if (vars->duplex == DUPLEX_FULL)
+ vars->link_status |= LINK_10TFD;
+ else
+ vars->link_status |= LINK_10THD;
+ break;
+
+ case GP_STATUS_100M:
+ vars->line_speed = SPEED_100;
+ if (vars->duplex == DUPLEX_FULL)
+ vars->link_status |= LINK_100TXFD;
+ else
+ vars->link_status |= LINK_100TXHD;
+ break;
+
+ case GP_STATUS_1G:
+ case GP_STATUS_1G_KX:
+ vars->line_speed = SPEED_1000;
+ if (vars->duplex == DUPLEX_FULL)
+ vars->link_status |= LINK_1000TFD;
+ else
+ vars->link_status |= LINK_1000THD;
+ break;
+
+ case GP_STATUS_2_5G:
+ vars->line_speed = SPEED_2500;
+ if (vars->duplex == DUPLEX_FULL)
+ vars->link_status |= LINK_2500TFD;
+ else
+ vars->link_status |= LINK_2500THD;
+ break;
+
+ case GP_STATUS_5G:
+ case GP_STATUS_6G:
+ DP(NETIF_MSG_LINK,
+ "link speed unsupported gp_status 0x%x\n",
+ gp_status);
+ return -EINVAL;
+ break;
+ case GP_STATUS_10G_KX4:
+ case GP_STATUS_10G_HIG:
+ case GP_STATUS_10G_CX4:
+ vars->line_speed = SPEED_10000;
+ vars->link_status |= LINK_10GTFD;
+ break;
+
+ case GP_STATUS_12G_HIG:
+ vars->line_speed = SPEED_12000;
+ vars->link_status |= LINK_12GTFD;
+ break;
+
+ case GP_STATUS_12_5G:
+ vars->line_speed = SPEED_12500;
+ vars->link_status |= LINK_12_5GTFD;
+ break;
+
+ case GP_STATUS_13G:
+ vars->line_speed = SPEED_13000;
+ vars->link_status |= LINK_13GTFD;
+ break;
+
+ case GP_STATUS_15G:
+ vars->line_speed = SPEED_15000;
+ vars->link_status |= LINK_15GTFD;
+ break;
+
+ case GP_STATUS_16G:
+ vars->line_speed = SPEED_16000;
+ vars->link_status |= LINK_16GTFD;
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK,
+ "link speed unsupported gp_status 0x%x\n",
+ gp_status);
+ return -EINVAL;
+ break;
+ }
+
+ vars->link_status |= LINK_STATUS_SERDES_LINK;
+
+ if (params->req_line_speed == SPEED_AUTO_NEG) {
+ vars->autoneg = AUTO_NEG_ENABLED;
+
+ if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
+ vars->autoneg |= AUTO_NEG_COMPLETE;
+ vars->link_status |=
+ LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+ }
+
+ vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
+ vars->link_status |=
+ LINK_STATUS_PARALLEL_DETECTION_USED;
+
+ }
+ if (vars->flow_ctrl & FLOW_CTRL_TX)
+ vars->link_status |=
+ LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
+
+ if (vars->flow_ctrl & FLOW_CTRL_RX)
+ vars->link_status |=
+ LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
+
+ } else { /* link_down */
+ DP(NETIF_MSG_LINK, "phy link down\n");
+
+ vars->phy_link_up = 0;
+ vars->line_speed = 0;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+ vars->autoneg = AUTO_NEG_DISABLED;
+ vars->mac_type = MAC_TYPE_NONE;
+ }
+
+ DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
+ gp_status, vars->phy_link_up, vars->line_speed);
+ DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
+ " autoneg 0x%x\n",
+ vars->duplex,
+ vars->flow_ctrl, vars->autoneg);
+ DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
+
+ return rc;
+}
+
+static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u16 lp_up2;
+ u16 tx_driver;
+
+ /* read precomp */
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_OVER_1G,
+ MDIO_OVER_1G_LP_UP2, &lp_up2);
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_TX0,
+ MDIO_TX0_TX_DRIVER, &tx_driver);
+
+ /* bits [10:7] at lp_up2, positioned at [15:12] */
+ lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
+ MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
+ MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
+
+ if ((lp_up2 != 0) &&
+ (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
+ /* replace tx_driver bits [15:12] */
+ tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
+ tx_driver |= lp_up2;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_TX0,
+ MDIO_TX0_TX_DRIVER, tx_driver);
+ }
+}
+
+static u8 bnx2x_emac_program(struct link_params *params,
+ u32 line_speed, u32 duplex)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u16 mode = 0;
+
+ DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
+ bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
+ EMAC_REG_EMAC_MODE,
+ (EMAC_MODE_25G_MODE |
+ EMAC_MODE_PORT_MII_10M |
+ EMAC_MODE_HALF_DUPLEX));
+ switch (line_speed) {
+ case SPEED_10:
+ mode |= EMAC_MODE_PORT_MII_10M;
+ break;
+
+ case SPEED_100:
+ mode |= EMAC_MODE_PORT_MII;
+ break;
+
+ case SPEED_1000:
+ mode |= EMAC_MODE_PORT_GMII;
+ break;
+
+ case SPEED_2500:
+ mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
+ break;
+
+ default:
+ /* 10G not valid for EMAC */
+ DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
+ return -EINVAL;
+ }
+
+ if (duplex == DUPLEX_HALF)
+ mode |= EMAC_MODE_HALF_DUPLEX;
+ bnx2x_bits_en(bp,
+ GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
+ mode);
+
+ bnx2x_set_led(bp, params->port, LED_MODE_OPER,
+ line_speed, params->hw_led_mode, params->chip_id);
+ return 0;
+}
+
+/*****************************************************************************/
+/* External Phy section */
+/*****************************************************************************/
+static void bnx2x_hw_reset(struct bnx2x *bp)
+{
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ msleep(1);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+}
+
+static void bnx2x_ext_phy_reset(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u32 ext_phy_type;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ /* The PHY reset is controled by GPIO 1
+ * Give it 1ms of reset pulse
+ */
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ DP(NETIF_MSG_LINK, "XGXS Direct\n");
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+
+ /* HW reset */
+ bnx2x_hw_reset(bp);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL, 0xa040);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ /* Unset Low Power Mode and SW reset */
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+
+ DP(NETIF_MSG_LINK, "XGXS 8072\n");
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ {
+ u16 emac_base;
+ emac_base = (params->port) ? GRCBASE_EMAC0 :
+ GRCBASE_EMAC1;
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+
+ DP(NETIF_MSG_LINK, "XGXS 8073\n");
+ bnx2x_cl45_write(bp,
+ params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+ }
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+
+ /* HW reset */
+ bnx2x_hw_reset(bp);
+
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+ params->ext_phy_config);
+ break;
+ }
+
+ } else { /* SerDes */
+ ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+ DP(NETIF_MSG_LINK, "SerDes Direct\n");
+ break;
+
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+ DP(NETIF_MSG_LINK, "SerDes 5482\n");
+ bnx2x_hw_reset(bp);
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK,
+ "BAD SerDes ext_phy_config 0x%x\n",
+ params->ext_phy_config);
+ break;
+ }
+ }
+}
+
+static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ u16 fw_ver1, fw_ver2;
+
+ /* Need to wait 200ms after reset */
+ msleep(200);
+ /* Boot port from external ROM
+ * Set ser_boot_ctl bit in the MISC_CTRL1 register
+ */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+
+ /* Reset internal microprocessor */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+ /* set micro reset = 0 */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+ /* Reset internal microprocessor */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+ /* wait for 100ms for code download via SPI port */
+ msleep(100);
+
+ /* Clear ser_boot_ctl bit */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+ /* Wait 100ms */
+ msleep(100);
+
+ /* Print the PHY FW version */
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &fw_ver2);
+ DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+}
+
+static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
+{
+ /* This is only required for 8073A1, version 102 only */
+
+ struct bnx2x *bp = params->bp;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u16 val;
+
+ /* Read 8073 HW revision*/
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ 0xc801, &val);
+
+ if (val != 1) {
+ /* No need to workaround in 8073 A1 */
+ return 0;
+ }
+
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &val);
+
+ /* SNR should be applied only for version 0x102 */
+ if (val != 0x102)
+ return 0;
+
+ return 1;
+}
+
+static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u16 val, cnt, cnt1 ;
+
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ 0xc801, &val);
+
+ if (val > 0) {
+ /* No need to workaround in 8073 A1 */
+ return 0;
+ }
+ /* XAUI workaround in 8073 A0: */
+
+ /* After loading the boot ROM and restarting Autoneg,
+ poll Dev1, Reg $C820: */
+
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ 0xc820, &val);
+ /* If bit [14] = 0 or bit [13] = 0, continue on with
+ system initialization (XAUI work-around not required,
+ as these bits indicate 2.5G or 1G link up). */
+ if (!(val & (1<<14)) || !(val & (1<<13))) {
+ DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
+ return 0;
+ } else if (!(val & (1<<15))) {
+ DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
+ /* If bit 15 is 0, then poll Dev1, Reg $C841 until
+ it's MSB (bit 15) goes to 1 (indicating that the
+ XAUI workaround has completed),
+ then continue on with system initialization.*/
+ for (cnt1 = 0; cnt1 < 1000; cnt1++) {
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ 0xc841, &val);
+ if (val & (1<<15)) {
+ DP(NETIF_MSG_LINK,
+ "XAUI workaround has completed\n");
+ return 0;
+ }
+ msleep(3);
+ }
+ break;
+ }
+ msleep(3);
+ }
+ DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
+ return -EINVAL;
+
+}
+
+static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ u16 fw_ver1, fw_ver2, val;
+ /* Need to wait 100ms after reset */
+ msleep(100);
+ /* Boot port from external ROM */
+ /* EDC grst */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ 0x0001);
+
+ /* ucode reboot and rst */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ 0x008c);
+
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+
+ /* Reset internal microprocessor */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+
+ /* Release srst bit */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* wait for 100ms for code download via SPI port */
+ msleep(100);
+
+ /* Clear ser_boot_ctl bit */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &fw_ver2);
+ DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+
+ /* Only set bit 10 = 1 (Tx power down) */
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_TX_POWER_DOWN, &val);
+
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10));
+
+ msleep(600);
+ /* Release bit 10 (Release Tx power down) */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
+
+}
+
+static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u16 val;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ 0xc801, &val);
+
+ if (val == 0) {
+ /* Mustn't set low power mode in 8073 A0 */
+ return;
+ }
+
+ /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD,
+ MDIO_XS_PLL_SEQUENCER, &val);
+ val &= ~(1<<13);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
+
+ /* PLL controls */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x805E, 0x1077);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x805D, 0x0000);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x805C, 0x030B);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x805B, 0x1240);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x805A, 0x2490);
+
+ /* Tx Controls */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x80A7, 0x0C74);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x80A6, 0x9041);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x80A5, 0x4640);
+
+ /* Rx Controls */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x80FE, 0x01C4);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x80FD, 0x9249);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, 0x80FC, 0x2015);
+
+ /* Enable PLL sequencer (use read-modify-write to set bit 13) */
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD,
+ MDIO_XS_PLL_SEQUENCER, &val);
+ val |= (1<<13);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
+}
+static void bnx2x_bcm807x_force_10G(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ /* Force KR or KX */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 0x2040);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_10G_CTRL2,
+ 0x000b);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_BCM_CTRL,
+ 0x0000);
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL,
+ 0x0000);
+}
+
+static void bnx2x_ext_phy_set_pause(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 val;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ /* read modify write pause advertizing */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV_PAUSE, &val);
+
+ val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
+ /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
+
+ if (vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
+ val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
+ }
+ if (vars->ieee_fc &
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
+ val |=
+ MDIO_AN_REG_ADV_PAUSE_PAUSE;
+ }
+ DP(NETIF_MSG_LINK,
+ "Ext phy AN advertize 0x%x\n", val);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV_PAUSE, val);
+}
+
+static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u32 ext_phy_type;
+ u8 ext_phy_addr;
+ u16 cnt;
+ u16 ctrl = 0;
+ u16 val = 0;
+ u8 rc = 0;
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ /* Make sure that the soft reset is off (expect for the 8072:
+ * due to the lock, it will be done inside the specific
+ * handling)
+ */
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL, &ctrl);
+ if (!(ctrl & (1<<15)))
+ break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
+ ctrl, cnt);
+ }
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ DP(NETIF_MSG_LINK, "XGXS Direct\n");
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ DP(NETIF_MSG_LINK, "XGXS 8705\n");
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL,
+ 0x8288);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ 0x7fbf);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CMU_PLL_BYPASS,
+ 0x0100);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_WIS_DEVAD,
+ MDIO_WIS_REG_LASI_CNTL, 0x1);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ DP(NETIF_MSG_LINK, "XGXS 8706\n");
+
+ msleep(10);
+ /* Force speed */
+ /* First enable LASI */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x0400);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x0004);
+
+ if (params->req_line_speed == SPEED_10000) {
+ DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_DIGITAL_CTRL,
+ 0x400);
+ } else {
+ /* Force 1Gbps using autoneg with 1G
+ advertisment */
+
+ /* Allow CL37 through CL73 */
+ DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_CL73,
+ 0x040c);
+
+ /* Enable Full-Duplex advertisment on CL37 */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FD,
+ 0x0020);
+ /* Enable CL37 AN */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_AN,
+ 0x1000);
+ /* 1G support */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV, (1<<5));
+
+ /* Enable clause 73 AN */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL,
+ 0x1200);
+
+ }
+
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ {
+ u16 tmp1;
+ u16 rx_alarm_ctrl_val;
+ u16 lasi_ctrl_val;
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
+ rx_alarm_ctrl_val = 0x400;
+ lasi_ctrl_val = 0x0004;
+ } else {
+ /* In 8073, port1 is directed through emac0 and
+ * port0 is directed through emac1
+ */
+ rx_alarm_ctrl_val = (1<<2);
+ /*lasi_ctrl_val = 0x0005;*/
+ lasi_ctrl_val = 0x0004;
+ }
+
+ /* Wait for soft reset to get cleared upto 1 sec */
+ for (cnt = 0; cnt < 1000; cnt++) {
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ &ctrl);
+ if (!(ctrl & (1<<15)))
+ break;
+ msleep(1);
+ }
+ DP(NETIF_MSG_LINK,
+ "807x control reg 0x%x (after %d ms)\n",
+ ctrl, cnt);
+
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
+ bnx2x_bcm8072_external_rom_boot(params);
+ } else {
+ bnx2x_bcm8073_external_rom_boot(params);
+ /* In case of 8073 with long xaui lines,
+ don't set the 8073 xaui low power*/
+ bnx2x_bcm8073_set_xaui_low_power_mode(params);
+ }
+
+ /* enable LASI */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL,
+ rx_alarm_ctrl_val);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL,
+ lasi_ctrl_val);
+
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &tmp1);
+
+ DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
+ "0x%x\n", tmp1);
+
+ /* If this is forced speed, set to KR or KX
+ * (all other are not supported)
+ */
+ if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
+ if (params->req_line_speed == SPEED_10000) {
+ bnx2x_bcm807x_force_10G(params);
+ DP(NETIF_MSG_LINK,
+ "Forced speed 10G on 807X\n");
+ break;
+ } else if (params->req_line_speed ==
+ SPEED_2500) {
+ val = (1<<5);
+ /* Note that 2.5G works only
+ when used with 1G advertisment */
+ } else
+ val = (1<<5);
+ } else {
+
+ val = 0;
+ if (params->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+ val |= (1<<7);
+
+ if (params->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
+ val |= (1<<5);
+ DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
+ /*val = ((1<<5)|(1<<7));*/
+ }
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV, val);
+
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
+ /* Disable 2.5Ghz */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ 0x8329, &tmp1);
+/* SUPPORT_SPEED_CAPABILITY
+ (Due to the nature of the link order, its not
+ possible to enable 2.5G within the autoneg
+ capabilities)
+ if (params->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
+*/
+ if (params->req_line_speed == SPEED_2500) {
+ u16 phy_ver;
+ /* Allow 2.5G for A1 and above */
+ bnx2x_cl45_read(bp, params->port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ 0xc801, &phy_ver);
+
+ if (phy_ver > 0)
+ tmp1 |= 1;
+ else
+ tmp1 &= 0xfffe;
+ }
+ else
+ tmp1 &= 0xfffe;
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ 0x8329, tmp1);
+ }
+ /* Add support for CL37 (passive mode) I */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_CL73, 0x040c);
+ /* Add support for CL37 (passive mode) II */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FD, 0x20);
+ /* Add support for CL37 (passive mode) III */
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_AN, 0x1000);
+ /* Restart autoneg */
+ msleep(500);
+
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
+
+ /* The SNR will improve about 2db by changing the
+ BW and FEE main tap. Rest commands are executed
+ after link is up*/
+ /* Change FFE main cursor to 5 in EDC register */
+ if (bnx2x_8073_is_snr_needed(params))
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_EDC_FFE_MAIN,
+ 0xFB0C);
+
+ /* Enable FEC (Forware Error Correction)
+ Request in the AN */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV2, &tmp1);
+
+ tmp1 |= (1<<15);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV2, tmp1);
+ }
+
+ bnx2x_ext_phy_set_pause(params, vars);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, 0x1200);
+ DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
+ "Advertise 1G=%x, 10G=%x\n",
+ ((val & (1<<5)) > 0),
+ ((val & (1<<7)) > 0));
+ break;
+ }
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ DP(NETIF_MSG_LINK,
+ "Setting the SFX7101 LASI indication\n");
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x1);
+ DP(NETIF_MSG_LINK,
+ "Setting the SFX7101 LED to blink on traffic\n");
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
+
+ bnx2x_ext_phy_set_pause(params, vars);
+ /* Restart autoneg */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, &val);
+ val |= 0x200;
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, val);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ DP(NETIF_MSG_LINK,
+ "XGXS PHY Failure detected 0x%x\n",
+ params->ext_phy_config);
+ rc = -EINVAL;
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+ params->ext_phy_config);
+ rc = -EINVAL;
+ break;
+ }
+
+ } else { /* SerDes */
+/* ext_phy_addr = ((bp->ext_phy_config &
+ PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
+*/
+ ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+ DP(NETIF_MSG_LINK, "SerDes Direct\n");
+ break;
+
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+ DP(NETIF_MSG_LINK, "SerDes 5482\n");
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
+ params->ext_phy_config);
+ break;
+ }
+ }
+ return rc;
+}
+
+
+static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u32 ext_phy_type;
+ u8 ext_phy_addr;
+ u16 val1 = 0, val2;
+ u16 rx_sd, pcs_status;
+ u8 ext_phy_link_up = 0;
+ u8 port = params->port;
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ DP(NETIF_MSG_LINK, "XGXS Direct\n");
+ ext_phy_link_up = 1;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ DP(NETIF_MSG_LINK, "XGXS 8705\n");
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_WIS_DEVAD,
+ MDIO_WIS_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_WIS_DEVAD,
+ MDIO_WIS_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_SD, &rx_sd);
+ DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
+ ext_phy_link_up = (rx_sd & 0x1);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ DP(NETIF_MSG_LINK, "XGXS 8706\n");
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_SD, &rx_sd);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_STATUS, &pcs_status);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS, &val2);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS, &val2);
+
+ DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
+ " pcs_status 0x%x 1Gbps link_status 0x%x\n",
+ rx_sd, pcs_status, val2);
+ /* link is up if both bit 0 of pmd_rx_sd and
+ * bit 0 of pcs_status are set, or if the autoneg bit
+ 1 is set
+ */
+ ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
+ (val2 & (1<<1)));
+ /* clear LASI indication*/
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &val2);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ {
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_LASI_STATUS, &val1);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_LASI_STATUS, &val2);
+ DP(NETIF_MSG_LINK,
+ "870x LASI status 0x%x->0x%x\n",
+ val1, val2);
+
+ } else {
+ /* In 8073, port1 is directed through emac0 and
+ * port0 is directed through emac1
+ */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val1);
+
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val2);
+ DP(NETIF_MSG_LINK,
+ "8703 LASI status 0x%x->0x%x\n",
+ val1, val2);
+ }
+
+ /* clear the interrupt LASI status register */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
+ val2, val1);
+ /* Check the LASI */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM, &val2);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM,
+ &val1);
+ DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
+ val2, val1);
+ /* Check the link status */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_STATUS, &val2);
+ DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
+
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_STATUS, &val1);
+ ext_phy_link_up = ((val1 & 4) == 4);
+ DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
+ u16 an1000_status = 0;
+ if (ext_phy_link_up &&
+ (
+ (params->req_line_speed != SPEED_10000)
+ )) {
+ if (bnx2x_bcm8073_xaui_wa(params)
+ != 0) {
+ ext_phy_link_up = 0;
+ break;
+ }
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ 0x8304,
+ &an1000_status);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ 0x8304,
+ &an1000_status);
+ }
+ /* Check the link status on 1.1.2 */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
+ "an_link_status=0x%x\n",
+ val2, val1, an1000_status);
+
+ ext_phy_link_up = (((val1 & 4) == 4) ||
+ (an1000_status & (1<<1)));
+ if (ext_phy_link_up &&
+ bnx2x_8073_is_snr_needed(params)) {
+ /* The SNR will improve about 2dbby
+ changing the BW and FEE main tap.*/
+
+ /* The 1st write to change FFE main
+ tap is set before restart AN */
+ /* Change PLL Bandwidth in EDC
+ register */
+ bnx2x_cl45_write(bp, port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PLL_BANDWIDTH,
+ 0x26BC);
+
+ /* Change CDR Bandwidth in EDC
+ register */
+ bnx2x_cl45_write(bp, port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CDR_BANDWIDTH,
+ 0x0333);
+
+ }
+ }
+ break;
+ }
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val2);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "10G-base-T LASI status 0x%x->0x%x\n",
+ val2, val1);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_STATUS, &val2);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_STATUS, &val1);
+ DP(NETIF_MSG_LINK,
+ "10G-base-T PMA status 0x%x->0x%x\n",
+ val2, val1);
+ ext_phy_link_up = ((val1 & 4) == 4);
+ /* if link is up
+ * print the AN outcome of the SFX7101 PHY
+ */
+ if (ext_phy_link_up) {
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_MASTER_STATUS,
+ &val2);
+ DP(NETIF_MSG_LINK,
+ "SFX7101 AN status 0x%x->Master=%x\n",
+ val2,
+ (val2 & (1<<14)));
+ }
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+ params->ext_phy_config);
+ ext_phy_link_up = 0;
+ break;
+ }
+
+ } else { /* SerDes */
+ ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+ DP(NETIF_MSG_LINK, "SerDes Direct\n");
+ ext_phy_link_up = 1;
+ break;
+
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+ DP(NETIF_MSG_LINK, "SerDes 5482\n");
+ ext_phy_link_up = 1;
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK,
+ "BAD SerDes ext_phy_config 0x%x\n",
+ params->ext_phy_config);
+ ext_phy_link_up = 0;
+ break;
+ }
+ }
+
+ return ext_phy_link_up;
+}
+
+static void bnx2x_link_int_enable(struct link_params *params)
+{
+ u8 port = params->port;
+ u32 ext_phy_type;
+ u32 mask;
+ struct bnx2x *bp = params->bp;
+ /* setting the status to report on link up
+ for either XGXS or SerDes */
+
+ if (params->switch_cfg == SWITCH_CFG_10G) {
+ mask = (NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_XGXS0_LINK_STATUS);
+ DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+ (ext_phy_type !=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
+
+ } else { /* SerDes */
+ mask = NIG_MASK_SERDES0_LINK_STATUS;
+ DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
+ ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
+ if ((ext_phy_type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
+ (ext_phy_type !=
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
+ mask |= NIG_MASK_MI_INT;
+ DP(NETIF_MSG_LINK, "enabled external phy int\n");
+ }
+ }
+ bnx2x_bits_en(bp,
+ NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+ mask);
+ DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
+ (params->switch_cfg == SWITCH_CFG_10G),
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+
+ DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+ REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
+ DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+}
+
+
+/*
+ * link management
+ */
+static void bnx2x_link_int_ack(struct link_params *params,
+ struct link_vars *vars, u16 is_10g)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+
+ /* first reset all status
+ * we assume only one line will be change at a time */
+ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
+ if (vars->phy_link_up) {
+ if (is_10g) {
+ /* Disable the 10G link interrupt
+ * by writing 1 to the status register
+ */
+ DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ NIG_STATUS_XGXS0_LINK10G);
+
+ } else if (params->switch_cfg == SWITCH_CFG_10G) {
+ /* Disable the link interrupt
+ * by writing 1 to the relevant lane
+ * in the status register
+ */
+ u32 ser_lane = ((params->lane_config &
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+ PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+
+ DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ ((1 << ser_lane) <<
+ NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
+
+ } else { /* SerDes */
+ DP(NETIF_MSG_LINK, "SerDes phy link up\n");
+ /* Disable the link interrupt
+ * by writing 1 to the status register
+ */
+ bnx2x_bits_en(bp,
+ NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ NIG_STATUS_SERDES0_LINK_STATUS);
+ }
+
+ } else { /* link_down */
+ }
+}
+
+static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
+{
+ u8 *str_ptr = str;
+ u32 mask = 0xf0000000;
+ u8 shift = 8*4;
+ u8 digit;
+ if (len < 10) {
+ /* Need more then 10chars for this format */
+ *str_ptr = '\0';
+ return -EINVAL;
+ }
+ while (shift > 0) {
+
+ shift -= 4;
+ digit = ((num & mask) >> shift);
+ if (digit < 0xa)
+ *str_ptr = digit + '0';
+ else
+ *str_ptr = digit - 0xa + 'a';
+ str_ptr++;
+ mask = mask >> 4;
+ if (shift == 4*4) {
+ *str_ptr = ':';
+ str_ptr++;
+ }
+ }
+ *str_ptr = '\0';
+ return 0;
+}
+
+
+static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
+{
+ u32 cnt = 0;
+ u16 ctrl = 0;
+ /* Enable EMAC0 in to enable MDIO */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+ (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
+ msleep(5);
+
+ /* take ext phy out of reset */
+ bnx2x_set_gpio(bp,
+ MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_HIGH);
+
+ bnx2x_set_gpio(bp,
+ MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_HIGH);
+
+ /* wait for 5ms */
+ msleep(5);
+
+ for (cnt = 0; cnt < 1000; cnt++) {
+ msleep(1);
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ &ctrl);
+ if (!(ctrl & (1<<15))) {
+ DP(NETIF_MSG_LINK, "Reset completed\n\n");
+ break;
+ }
+ }
+}
+
+static void bnx2x_turn_off_sf(struct bnx2x *bp)
+{
+ /* put sf to reset */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_LOW);
+ bnx2x_set_gpio(bp,
+ MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_LOW);
+}
+
+u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
+ u8 *version, u16 len)
+{
+ struct bnx2x *bp = params->bp;
+ u32 ext_phy_type = 0;
+ u16 val = 0;
+ u8 ext_phy_addr = 0 ;
+ u8 status = 0 ;
+ u32 ver_num;
+
+ if (version == NULL || params == NULL)
+ return -EINVAL;
+
+ /* reset the returned value to zero */
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+
+ if (len < 5)
+ return -EINVAL;
+
+ /* Take ext phy out of reset */
+ if (!driver_loaded)
+ bnx2x_turn_on_sf(bp, params->port, ext_phy_addr);
+
+ /* wait for 1ms */
+ msleep(1);
+
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER1, &val);
+ version[2] = (val & 0xFF);
+ version[3] = ((val & 0xFF00)>>8);
+
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
+ &val);
+ version[0] = (val & 0xFF);
+ version[1] = ((val & 0xFF00)>>8);
+ version[4] = '\0';
+
+ if (!driver_loaded)
+ bnx2x_turn_off_sf(bp);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ {
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &val);
+ ver_num = val<<16;
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &val);
+ ver_num |= val;
+ status = bnx2x_format_ver(ver_num, version, len);
+ break;
+ }
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &val);
+ ver_num = val<<16;
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &val);
+ ver_num |= val;
+ status = bnx2x_format_ver(ver_num, version, len);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
+ " type is FAILURE!\n");
+ status = -EINVAL;
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+static void bnx2x_set_xgxs_loopback(struct link_params *params,
+ struct link_vars *vars,
+ u8 is_10g)
+{
+ u8 port = params->port;
+ struct bnx2x *bp = params->bp;
+
+ if (is_10g) {
+ u32 md_devad;
+
+ DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
+
+ /* change the uni_phy_addr in the nig */
+ md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
+ port*0x18));
+
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
+
+ bnx2x_cl45_write(bp, port, 0,
+ params->phy_addr,
+ 5,
+ (MDIO_REG_BANK_AER_BLOCK +
+ (MDIO_AER_BLOCK_AER_REG & 0xf)),
+ 0x2800);
+
+ bnx2x_cl45_write(bp, port, 0,
+ params->phy_addr,
+ 5,
+ (MDIO_REG_BANK_CL73_IEEEB0 +
+ (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
+ 0x6041);
+
+ /* set aer mmd back */
+ bnx2x_set_aer_mmd(params, vars);
+
+ /* and md_devad */
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
+ md_devad);
+
+ } else {
+ u16 mii_control;
+
+ DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
+
+ CL45_RD_OVER_CL22(bp, port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ &mii_control);
+
+ CL45_WR_OVER_CL22(bp, port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ (mii_control |
+ MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
+ }
+}
+
+
+static void bnx2x_ext_phy_loopback(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 ext_phy_addr;
+ u32 ext_phy_type;
+
+ if (params->switch_cfg == SWITCH_CFG_10G) {
+ ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ /* CL37 Autoneg Enabled */
+ ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
+ DP(NETIF_MSG_LINK,
+ "ext_phy_loopback: We should not get here\n");
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ /* SFX7101_XGXS_TEST1 */
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ MDIO_XS_SFX7101_XGXS_TEST1,
+ 0x100);
+ DP(NETIF_MSG_LINK,
+ "ext_phy_loopback: set ext phy loopback\n");
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+
+ break;
+ } /* switch external PHY type */
+ } else {
+ /* serdes */
+ ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
+ ext_phy_addr = (params->ext_phy_config &
+ PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
+ >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
+ }
+}
+
+
+/*
+ *------------------------------------------------------------------------
+ * bnx2x_override_led_value -
+ *
+ * Override the led value of the requsted led
+ *
+ *------------------------------------------------------------------------
+ */
+u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
+ u32 led_idx, u32 value)
+{
+ u32 reg_val;
+
+ /* If port 0 then use EMAC0, else use EMAC1*/
+ u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+ DP(NETIF_MSG_LINK,
+ "bnx2x_override_led_value() port %x led_idx %d value %d\n",
+ port, led_idx, value);
+
+ switch (led_idx) {
+ case 0: /* 10MB led */
+ /* Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 10M_OVERRIDE bit,
+ otherwise reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_10MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 1: /*100MB led */
+ /*Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 100M_OVERRIDE bit,
+ otherwise reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_100MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 2: /* 1000MB led */
+ /* Read the current value of the LED register in the
+ EMAC block */
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
+ reset it. */
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 3: /* 2500MB led */
+ /* Read the current value of the LED register in the
+ EMAC block*/
+ reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
+ /* Set the OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
+ reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
+ (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ break;
+ case 4: /*10G led */
+ if (port == 0) {
+ REG_WR(bp, NIG_REG_LED_10G_P0,
+ value);
+ } else {
+ REG_WR(bp, NIG_REG_LED_10G_P1,
+ value);
+ }
+ break;
+ case 5: /* TRAFFIC led */
+ /* Find if the traffic control is via BMAC or EMAC */
+ if (port == 0)
+ reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
+ else
+ reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
+
+ /* Override the traffic led in the EMAC:*/
+ if (reg_val == 1) {
+ /* Read the current value of the LED register in
+ the EMAC block */
+ reg_val = REG_RD(bp, emac_base +
+ EMAC_REG_EMAC_LED);
+ /* Set the TRAFFIC_OVERRIDE bit to 1 */
+ reg_val |= EMAC_LED_OVERRIDE;
+ /* If value is 1, set the TRAFFIC bit, otherwise
+ reset it.*/
+ reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
+ (reg_val & ~EMAC_LED_TRAFFIC);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
+ } else { /* Override the traffic led in the BMAC: */
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ + port*4, 1);
+ REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
+ value);
+ }
+ break;
+ default:
+ DP(NETIF_MSG_LINK,
+ "bnx2x_override_led_value() unknown led index %d "
+ "(should be 0-5)\n", led_idx);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
+ u16 hw_led_mode, u32 chip_id)
+{
+ u8 rc = 0;
+ DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
+ DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
+ speed, hw_led_mode);
+ switch (mode) {
+ case LED_MODE_OFF:
+ REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
+ SHARED_HW_CFG_LED_MAC1);
+ break;
+
+ case LED_MODE_OPER:
+ REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
+ port*4, 0);
+ /* Set blinking rate to ~15.9Hz */
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
+ LED_BLINK_RATE_VAL);
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
+ port*4, 1);
+ if (!CHIP_IS_E1H(bp) &&
+ ((speed == SPEED_2500) ||
+ (speed == SPEED_1000) ||
+ (speed == SPEED_100) ||
+ (speed == SPEED_10))) {
+ /* On Everest 1 Ax chip versions for speeds less than
+ 10G LED scheme is different */
+ REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ + port*4, 1);
+ REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
+ port*4, 0);
+ REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
+ port*4, 1);
+ }
+ break;
+
+ default:
+ rc = -EINVAL;
+ DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
+ mode);
+ break;
+ }
+ return rc;
+
+}
+
+u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u16 gp_status = 0;
+
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_GP_STATUS,
+ MDIO_GP_STATUS_TOP_AN_STATUS1,
+ &gp_status);
+ /* link is up only if both local phy and external phy are up */
+ if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
+ bnx2x_ext_phy_is_link_up(params, vars))
+ return 0;
+
+ return -ESRCH;
+}
+
+static u8 bnx2x_link_initialize(struct link_params *params,
+ struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 rc = 0;
+
+ /* Activate the external PHY */
+ bnx2x_ext_phy_reset(params, vars);
+
+ bnx2x_set_aer_mmd(params, vars);
+
+ if (vars->phy_flags & PHY_XGXS_FLAG)
+ bnx2x_set_master_ln(params);
+
+ rc = bnx2x_reset_unicore(params);
+ /* reset the SerDes and wait for reset bit return low */
+ if (rc != 0)
+ return rc;
+
+ bnx2x_set_aer_mmd(params, vars);
+
+ /* setting the masterLn_def again after the reset */
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ bnx2x_set_master_ln(params);
+ bnx2x_set_swap_lanes(params);
+ }
+
+ /* Set Parallel Detect */
+ if (params->req_line_speed == SPEED_AUTO_NEG)
+ bnx2x_set_parallel_detection(params, vars->phy_flags);
+
+ if (vars->phy_flags & PHY_XGXS_FLAG) {
+ if (params->req_line_speed &&
+ ((params->req_line_speed == SPEED_100) ||
+ (params->req_line_speed == SPEED_10))) {
+ vars->phy_flags |= PHY_SGMII_FLAG;
+ } else {
+ vars->phy_flags &= ~PHY_SGMII_FLAG;
+ }
+ }
+
+ if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
+ u16 bank, rx_eq;
+
+ rx_eq = ((params->serdes_config &
+ PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
+ PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
+
+ DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
+ for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
+ bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
+ CL45_WR_OVER_CL22(bp, port,
+ params->phy_addr,
+ bank ,
+ MDIO_RX0_RX_EQ_BOOST,
+ ((rx_eq &
+ MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
+ MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
+ }
+
+ /* forced speed requested? */
+ if (params->req_line_speed != SPEED_AUTO_NEG) {
+ DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
+
+ /* disable autoneg */
+ bnx2x_set_autoneg(params, vars);
+
+ /* program speed and duplex */
+ bnx2x_program_serdes(params);
+ vars->ieee_fc =
+ MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+
+ } else { /* AN_mode */
+ DP(NETIF_MSG_LINK, "not SGMII, AN\n");
+
+ /* AN enabled */
+ bnx2x_set_brcm_cl37_advertisment(params);
+
+ /* program duplex & pause advertisement (for aneg) */
+ bnx2x_set_ieee_aneg_advertisment(params,
+ &vars->ieee_fc);
+
+ /* enable autoneg */
+ bnx2x_set_autoneg(params, vars);
+
+ /* enable and restart AN */
+ bnx2x_restart_autoneg(params);
+ }
+
+ } else { /* SGMII mode */
+ DP(NETIF_MSG_LINK, "SGMII\n");
+
+ bnx2x_initialize_sgmii_process(params);
+ }
+
+ /* init ext phy and enable link state int */
+ rc |= bnx2x_ext_phy_init(params, vars);
+
+ bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+ (NIG_STATUS_XGXS0_LINK10G |
+ NIG_STATUS_XGXS0_LINK_STATUS |
+ NIG_STATUS_SERDES0_LINK_STATUS));
+
+ return rc;
+
+}
+
+
+u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+
+ u32 val;
+ DP(NETIF_MSG_LINK, "Phy Initialization started\n");
+ DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
+ params->req_line_speed, params->req_flow_ctrl);
+ vars->link_status = 0;
+ if (params->switch_cfg == SWITCH_CFG_1G)
+ vars->phy_flags = PHY_SERDES_FLAG;
+ else
+ vars->phy_flags = PHY_XGXS_FLAG;
+
+ /* disable attentions */
+ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
+ (NIG_MASK_XGXS0_LINK_STATUS |
+ NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_SERDES0_LINK_STATUS |
+ NIG_MASK_MI_INT));
+
+ bnx2x_emac_init(params, vars);
+
+ if (CHIP_REV_IS_FPGA(bp)) {
+ vars->link_up = 1;
+ vars->line_speed = SPEED_10000;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+ vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
+ /* enable on E1.5 FPGA */
+ if (CHIP_IS_E1H(bp)) {
+ vars->flow_ctrl |=
+ (FLOW_CTRL_TX | FLOW_CTRL_RX);
+ vars->link_status |=
+ (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
+ LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
+ }
+
+ bnx2x_emac_enable(params, vars, 0);
+ bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
+ /* disable drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+
+ /* update shared memory */
+ bnx2x_update_mng(params, vars->link_status);
+
+ return 0;
+
+ } else
+ if (CHIP_REV_IS_EMUL(bp)) {
+
+ vars->link_up = 1;
+ vars->line_speed = SPEED_10000;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+ vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
+
+ bnx2x_bmac_enable(params, vars, 0);
+
+ bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
+ /* Disable drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ + params->port*4, 0);
+
+ /* update shared memory */
+ bnx2x_update_mng(params, vars->link_status);
+
+ return 0;
+
+ } else
+ if (params->loopback_mode == LOOPBACK_BMAC) {
+ vars->link_up = 1;
+ vars->line_speed = SPEED_10000;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+ vars->mac_type = MAC_TYPE_BMAC;
+
+ vars->phy_flags = PHY_XGXS_FLAG;
+
+ bnx2x_phy_deassert(params, vars->phy_flags);
+ /* set bmac loopback */
+ bnx2x_bmac_enable(params, vars, 1);
+
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
+ params->port*4, 0);
+ } else if (params->loopback_mode == LOOPBACK_EMAC) {
+ vars->link_up = 1;
+ vars->line_speed = SPEED_1000;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+ vars->mac_type = MAC_TYPE_EMAC;
+
+ vars->phy_flags = PHY_XGXS_FLAG;
+
+ bnx2x_phy_deassert(params, vars->phy_flags);
+ /* set bmac loopback */
+ bnx2x_emac_enable(params, vars, 1);
+ bnx2x_emac_program(params, vars->line_speed,
+ vars->duplex);
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
+ params->port*4, 0);
+ } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
+ (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+ vars->link_up = 1;
+ vars->line_speed = SPEED_10000;
+ vars->duplex = DUPLEX_FULL;
+ vars->flow_ctrl = FLOW_CTRL_NONE;
+
+ vars->phy_flags = PHY_XGXS_FLAG;
+
+ val = REG_RD(bp,
+ NIG_REG_XGXS0_CTRL_PHY_ADDR+
+ params->port*0x18);
+ params->phy_addr = (u8)val;
+
+ bnx2x_phy_deassert(params, vars->phy_flags);
+ bnx2x_link_initialize(params, vars);
+
+ vars->mac_type = MAC_TYPE_BMAC;
+
+ bnx2x_bmac_enable(params, vars, 0);
+
+ if (params->loopback_mode == LOOPBACK_XGXS_10) {
+ /* set 10G XGXS loopback */
+ bnx2x_set_xgxs_loopback(params, vars, 1);
+ } else {
+ /* set external phy loopback */
+ bnx2x_ext_phy_loopback(params);
+ }
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
+ params->port*4, 0);
+ } else
+ /* No loopback */
+ {
+
+ bnx2x_phy_deassert(params, vars->phy_flags);
+ switch (params->switch_cfg) {
+ case SWITCH_CFG_1G:
+ vars->phy_flags |= PHY_SERDES_FLAG;
+ if ((params->ext_phy_config &
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
+ vars->phy_flags |=
+ PHY_SGMII_FLAG;
+ }
+
+ val = REG_RD(bp,
+ NIG_REG_SERDES0_CTRL_PHY_ADDR+
+ params->port*0x10);
+
+ params->phy_addr = (u8)val;
+
+ break;
+ case SWITCH_CFG_10G:
+ vars->phy_flags |= PHY_XGXS_FLAG;
+ val = REG_RD(bp,
+ NIG_REG_XGXS0_CTRL_PHY_ADDR+
+ params->port*0x18);
+ params->phy_addr = (u8)val;
+
+ break;
+ default:
+ DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
+ return -EINVAL;
+ break;
+ }
+
+ bnx2x_link_initialize(params, vars);
+ bnx2x_link_int_enable(params);
+ }
+ return 0;
+}
+
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
+{
+
+ struct bnx2x *bp = params->bp;
+ u32 ext_phy_config = params->ext_phy_config;
+ u16 hw_led_mode = params->hw_led_mode;
+ u32 chip_id = params->chip_id;
+ u8 port = params->port;
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
+ /* disable attentions */
+
+ vars->link_status = 0;
+ bnx2x_update_mng(params, vars->link_status);
+ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+ (NIG_MASK_XGXS0_LINK_STATUS |
+ NIG_MASK_XGXS0_LINK10G |
+ NIG_MASK_SERDES0_LINK_STATUS |
+ NIG_MASK_MI_INT));
+
+ /* activate nig drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+ /* disable nig egress interface */
+ REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+
+ /* Stop BigMac rx */
+ bnx2x_bmac_rx_disable(bp, port);
+
+ /* disable emac */
+ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
+
+ msleep(10);
+ /* The PHY reset is controled by GPIO 1
+ * Hold it as vars low
+ */
+ /* clear link led */
+ bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
+ if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
+ if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
+ /* HW reset */
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+
+ DP(NETIF_MSG_LINK, "reset external PHY\n");
+ } else {
+
+ u8 ext_phy_addr = ((ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ /* SW reset */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+
+ /* Set Low Power Mode */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<11);
+
+
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
+ DP(NETIF_MSG_LINK, "Setting 8073 port %d into"
+ "low power mode\n",
+ port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ }
+ }
+ }
+ /* reset the SerDes/XGXS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
+ (0x1ff << (port*16)));
+
+ /* reset BigMac */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+ /* disable nig ingress interface */
+ REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
+ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
+ REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
+ REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+ vars->link_up = 0;
+ return 0;
+}
+
+/* This function should called upon link interrupt */
+/* In case vars->link_up, driver needs to
+ 1. Update the pbf
+ 2. Disable drain
+ 3. Update the shared memory
+ 4. Indicate link up
+ 5. Set LEDs
+ Otherwise,
+ 1. Update shared memory
+ 2. Reset BigMac
+ 3. Report link down
+ 4. Unset LEDs
+*/
+u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u16 i;
+ u16 gp_status;
+ u16 link_10g;
+ u8 rc = 0;
+
+ DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
+ port,
+ (vars->phy_flags & PHY_XGXS_FLAG),
+ REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+
+ DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
+ REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+ REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
+
+ DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+ REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
+
+
+ /* avoid fast toggling */
+ for (i = 0; i < 10; i++) {
+ msleep(10);
+ CL45_RD_OVER_CL22(bp, port, params->phy_addr,
+ MDIO_REG_BANK_GP_STATUS,
+ MDIO_GP_STATUS_TOP_AN_STATUS1,
+ &gp_status);
+ }
+
+ rc = bnx2x_link_settings_status(params, vars, gp_status);
+ if (rc != 0)
+ return rc;
+
+ /* anything 10 and over uses the bmac */
+ link_10g = ((vars->line_speed == SPEED_10000) ||
+ (vars->line_speed == SPEED_12000) ||
+ (vars->line_speed == SPEED_12500) ||
+ (vars->line_speed == SPEED_13000) ||
+ (vars->line_speed == SPEED_15000) ||
+ (vars->line_speed == SPEED_16000));
+
+ bnx2x_link_int_ack(params, vars, link_10g);
+
+ /* link is up only if both local phy and external phy are up */
+ vars->link_up = (vars->phy_link_up &&
+ bnx2x_ext_phy_is_link_up(params, vars));
+
+ if (!vars->phy_link_up &&
+ REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18)) {
+ bnx2x_ext_phy_is_link_up(params, vars); /* Clear interrupt */
+ }
+
+ if (vars->link_up) {
+ vars->link_status |= LINK_STATUS_LINK_UP;
+ if (link_10g) {
+ bnx2x_bmac_enable(params, vars, 0);
+ bnx2x_set_led(bp, port, LED_MODE_OPER,
+ SPEED_10000, params->hw_led_mode,
+ params->chip_id);
+
+ } else {
+ bnx2x_emac_enable(params, vars, 0);
+ rc = bnx2x_emac_program(params, vars->line_speed,
+ vars->duplex);
+
+ /* AN complete? */
+ if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
+ if (!(vars->phy_flags &
+ PHY_SGMII_FLAG))
+ bnx2x_set_sgmii_tx_driver(params);
+ }
+ }
+
+ /* PBF - link up */
+ rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
+ vars->line_speed);
+
+ /* disable drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
+
+ /* update shared memory */
+ bnx2x_update_mng(params, vars->link_status);
+
+ } else { /* link down */
+ DP(NETIF_MSG_LINK, "Port %x: Link is down\n", params->port);
+ bnx2x_set_led(bp, port, LED_MODE_OFF,
+ 0, params->hw_led_mode,
+ params->chip_id);
+
+ /* indicate no mac active */
+ vars->mac_type = MAC_TYPE_NONE;
+
+ /* update shared memory */
+ vars->link_status = 0;
+ bnx2x_update_mng(params, vars->link_status);
+
+ /* activate nig drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+ /* reset BigMac */
+ bnx2x_bmac_rx_disable(bp, params->port);
+ REG_WR(bp, GRCBASE_MISC +
+ MISC_REGISTERS_RESET_REG_2_CLEAR,
+ (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+ }
+
+ return rc;
+}
+
+static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
+{
+ u16 val, cnt;
+
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET, &val);
+
+ for (cnt = 0; cnt < 10; cnt++) {
+ msleep(50);
+ /* Writes a self-clearing reset */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET,
+ (val | (1<<15)));
+ /* Wait for clear */
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_RESET, &val);
+
+ if ((val & (1<<15)) == 0)
+ break;
+ }
+}
+#define RESERVED_SIZE 256
+/* max application is 160K bytes - data at end of RAM */
+#define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
+
+/* Header is 14 bytes */
+#define HEADER_SIZE 14
+#define DATA_OFFSET HEADER_SIZE
+
+#define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
+ bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
+ ext_phy_addr, \
+ MDIO_PCS_DEVAD, \
+ MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
+
+/* Programs an image to DSP's flash via the SPI port*/
+static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
+ u8 ext_phy_addr,
+ char data[], u32 size)
+{
+ const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
+ /* Doesn't include last trans!*/
+ const u16 last_trans_size = size%4; /* Num bytes on last trans */
+ u16 trans_cnt, byte_cnt;
+ u32 data_index;
+ u16 tmp;
+ u16 code_started = 0;
+ u16 image_revision1, image_revision2;
+ u16 cnt;
+
+ DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
+ /* Going to flash*/
+ if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
+ /* This very often will be the case, because the image is built
+ with 160Kbytes size whereas the total image size must actually
+ be 160Kbytes-RESERVED_SIZE */
+ DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
+ "truncated to %d bytes\n", size, MAX_APP_SIZE);
+ size = MAX_APP_SIZE+HEADER_SIZE;
+ }
+ DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
+ DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
+ /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
+ and issuing a reset.*/
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH);
+
+ bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
+
+ /* wait 0.5 sec */
+ for (cnt = 0; cnt < 100; cnt++)
+ msleep(5);
+
+ /* Make sure we can access the DSP
+ And it's in the correct mode (waiting for download) */
+
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
+
+ if (tmp != 0x000A) {
+ DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
+ "Expected 0x000A, read 0x%04X\n", tmp);
+ DP(NETIF_MSG_LINK, "Download failed\n");
+ return -EINVAL;
+ }
+
+ /* Mux the SPI interface away from the internal processor */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_MUX, 1);
+
+ /* Reset the SPI port */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
+ (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
+
+ /* Erase the flash */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
+ 1);
+
+ SPI_START_TRANSFER(bp, port, ext_phy_addr);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
+ 1);
+ SPI_START_TRANSFER(bp, port, ext_phy_addr);
+
+ /* Wait 10 seconds, the maximum time for the erase to complete */
+ DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
+ for (cnt = 0; cnt < 1000; cnt++)
+ msleep(10);
+
+ DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
+ data_index = 0;
+ for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
+ 1);
+ SPI_START_TRANSFER(bp, port, ext_phy_addr);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
+
+ /* Bits 23-16 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ (data_index>>16));
+ /* Bits 15-8 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ (data_index>>8));
+
+ /* Bits 7-0 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ ((u16)data_index));
+
+ byte_cnt = 0;
+ while (byte_cnt < 4 && data_index < size) {
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ data[data_index++]);
+ byte_cnt++;
+ }
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
+ byte_cnt+4);
+
+ SPI_START_TRANSFER(bp, port, ext_phy_addr);
+ msleep(5); /* Wait 5 ms minimum between transs */
+
+ /* Let the user know something's going on.*/
+ /* a pacifier ever 4K */
+ if ((data_index % 1023) == 0)
+ DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
+ }
+
+ DP(NETIF_MSG_LINK, "\n");
+ /* Transfer the last block if there is data remaining */
+ if (last_trans_size) {
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
+ 1);
+
+ SPI_START_TRANSFER(bp, port, ext_phy_addr);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
+
+ /* Bits 23-16 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ (data_index>>16));
+ /* Bits 15-8 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ (data_index>>8));
+
+ /* Bits 7-0 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ ((u16)data_index));
+
+ byte_cnt = 0;
+ while (byte_cnt < last_trans_size && data_index < size) {
+ /* Bits 7-0 of address */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
+ data[data_index++]);
+ byte_cnt++;
+ }
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
+ byte_cnt+4);
+
+ SPI_START_TRANSFER(bp, port, ext_phy_addr);
+ }
+
+ /* DSP Remove Download Mode */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_LOW);
+
+ bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
+
+ /* wait 0.5 sec to allow it to run */
+ for (cnt = 0; cnt < 100; cnt++)
+ msleep(5);
+
+ bnx2x_hw_reset(bp);
+
+ for (cnt = 0; cnt < 100; cnt++)
+ msleep(5);
+
+ /* Check that the code is started. In case the download
+ checksum failed, the code won't be started. */
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD,
+ MDIO_PCS_REG_7101_DSP_ACCESS,
+ &tmp);
+
+ code_started = (tmp & (1<<4));
+ if (!code_started) {
+ DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
+ return -EINVAL;
+ }
+
+ /* Verify that the file revision is now equal to the image
+ revision within the DSP */
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER1,
+ &image_revision1);
+
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER2,
+ &image_revision2);
+
+ if (data[0x14e] != (image_revision2&0xFF) ||
+ data[0x14f] != ((image_revision2&0xFF00)>>8) ||
+ data[0x150] != (image_revision1&0xFF) ||
+ data[0x151] != ((image_revision1&0xFF00)>>8)) {
+ DP(NETIF_MSG_LINK, "Download failed.\n");
+ return -EINVAL;
+ }
+ DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
+ return 0;
+}
+
+u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
+ u8 driver_loaded, char data[], u32 size)
+{
+ u8 rc = 0;
+ u32 ext_phy_type;
+ u8 ext_phy_addr;
+ ext_phy_addr = ((ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+ ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ DP(NETIF_MSG_LINK,
+ "Flash download not supported for this ext phy\n");
+ rc = -EINVAL;
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ /* Take ext phy out of reset */
+ if (!driver_loaded)
+ bnx2x_turn_on_sf(bp, port, ext_phy_addr);
+ rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
+ data, size);
+ if (!driver_loaded)
+ bnx2x_turn_off_sf(bp);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
+ default:
+ DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
new file mode 100644
index 00000000000..714d37ac95d
--- /dev/null
+++ b/drivers/net/bnx2x_link.h
@@ -0,0 +1,168 @@
+/* Copyright 2008 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *
+ * Written by Yaniv Rosner
+ *
+ */
+
+#ifndef BNX2X_LINK_H
+#define BNX2X_LINK_H
+
+
+
+/***********************************************************/
+/* Defines */
+/***********************************************************/
+#define DEFAULT_PHY_DEV_ADDR 3
+
+
+
+#define FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO
+#define FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX
+#define FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX
+#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
+#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
+
+#define SPEED_AUTO_NEG 0
+#define SPEED_12000 12000
+#define SPEED_12500 12500
+#define SPEED_13000 13000
+#define SPEED_15000 15000
+#define SPEED_16000 16000
+
+
+/***********************************************************/
+/* Structs */
+/***********************************************************/
+/* Inputs parameters to the CLC */
+struct link_params {
+
+ u8 port;
+
+ /* Default / User Configuration */
+ u8 loopback_mode;
+#define LOOPBACK_NONE 0
+#define LOOPBACK_EMAC 1
+#define LOOPBACK_BMAC 2
+#define LOOPBACK_XGXS_10 3
+#define LOOPBACK_EXT_PHY 4
+
+ u16 req_duplex;
+ u16 req_flow_ctrl;
+ u16 req_line_speed; /* Also determine AutoNeg */
+
+ /* Device parameters */
+ u8 mac_addr[6];
+ u16 mtu;
+
+
+ /* shmem parameters */
+ u32 shmem_base;
+ u32 speed_cap_mask;
+ u32 switch_cfg;
+#define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
+#define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
+#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
+
+ u16 hw_led_mode; /* part of the hw_config read from the shmem */
+ u32 serdes_config;
+ u32 lane_config;
+ u32 ext_phy_config;
+#define XGXS_EXT_PHY_TYPE(ext_phy_config) (ext_phy_config & \
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
+#define SERDES_EXT_PHY_TYPE(ext_phy_config) (ext_phy_config & \
+ PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
+ /* Phy register parameter */
+ u32 chip_id;
+
+ /* phy_addr populated by the CLC */
+ u8 phy_addr;
+ /* Device pointer passed to all callback functions */
+ struct bnx2x *bp;
+};
+
+/* Output parameters */
+struct link_vars {
+ u8 phy_link_up; /* internal phy link indication */
+ u8 link_up;
+ u16 duplex;
+ u16 flow_ctrl;
+ u32 ieee_fc;
+ u8 mac_type;
+
+#define MAC_TYPE_NONE 0
+#define MAC_TYPE_EMAC 1
+#define MAC_TYPE_BMAC 2
+ u16 line_speed;
+ u32 autoneg;
+#define AUTO_NEG_DISABLED 0x0
+#define AUTO_NEG_ENABLED 0x1
+#define AUTO_NEG_COMPLETE 0x2
+#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3
+
+ u8 phy_flags;
+
+ /* The same definitions as the shmem parameter */
+ u32 link_status;
+};
+
+/***********************************************************/
+/* Functions */
+/***********************************************************/
+
+/* Initialize the phy */
+u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
+
+/* Reset the link. Should be called when driver or interface goes down */
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars);
+
+/* bnx2x_link_update should be called upon link interrupt */
+u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
+
+/* use the following cl45 functions to read/write from external_phy
+ In order to use it to read/write internal phy registers, use
+ DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as
+ Use ext_phy_type of 0 in case of cl22 over cl45
+ the register */
+u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
+ u8 phy_addr, u8 devad, u16 reg, u16 *ret_val);
+
+u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
+ u8 phy_addr, u8 devad, u16 reg, u16 val);
+
+/* Reads the link_status from the shmem,
+ and update the link vars accordinaly */
+void bnx2x_link_status_update(struct link_params *input,
+ struct link_vars *output);
+/* returns string representing the fw_version of the external phy */
+u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
+ u8 *version, u16 len);
+
+/* Set/Unset the led
+ Basically, the CLC takes care of the led for the link, but in case one needs
+ to set/unset the led unnatually, set the "mode" to LED_MODE_OPER to
+ blink the led, and LED_MODE_OFF to set the led off.*/
+u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
+ u16 hw_led_mode, u32 chip_id);
+#define LED_MODE_OFF 0
+#define LED_MODE_OPER 2
+
+u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
+
+u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
+ u8 driver_loaded, char data[], u32 size);
+/* Get the actual link status. In case it returns 0, link is up,
+ otherwise link is down*/
+u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
+
+
+#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
new file mode 100644
index 00000000000..0263bef9cc6
--- /dev/null
+++ b/drivers/net/bnx2x_main.c
@@ -0,0 +1,10294 @@
+/* bnx2x_main.c: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007-2008 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.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Eliezer Tamir
+ * Based on code from Michael Chan's bnx2 driver
+ * UDP CSUM errata workaround by Arik Gendelman
+ * Slowpath rework by Vladislav Zolotarov
+ * Statistics and Link management by Yitchak Gertner
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/device.h> /* for dev_info() */
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/time.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#ifdef NETIF_F_HW_VLAN_TX
+ #include <linux/if_vlan.h>
+#endif
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <net/checksum.h>
+#include <linux/version.h>
+#include <net/ip6_checksum.h>
+#include <linux/workqueue.h>
+#include <linux/crc32.h>
+#include <linux/crc32c.h>
+#include <linux/prefetch.h>
+#include <linux/zlib.h>
+#include <linux/io.h>
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "bnx2x_link.h"
+#include "bnx2x.h"
+#include "bnx2x_init.h"
+
+#define DRV_MODULE_VERSION "1.45.6"
+#define DRV_MODULE_RELDATE "2008/06/23"
+#define BNX2X_BC_VER 0x040200
+
+/* Time in jiffies before concluding the transmitter is hung */
+#define TX_TIMEOUT (5*HZ)
+
+static char version[] __devinitdata =
+ "Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver "
+ DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("Eliezer Tamir");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+
+static int use_inta;
+static int poll;
+static int debug;
+static int disable_tpa;
+static int nomcp;
+static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
+static int use_multi;
+
+module_param(use_inta, int, 0);
+module_param(poll, int, 0);
+module_param(debug, int, 0);
+module_param(disable_tpa, int, 0);
+module_param(nomcp, int, 0);
+MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
+MODULE_PARM_DESC(poll, "use polling (for debug)");
+MODULE_PARM_DESC(debug, "default debug msglevel");
+MODULE_PARM_DESC(nomcp, "ignore management CPU");
+
+#ifdef BNX2X_MULTI
+module_param(use_multi, int, 0);
+MODULE_PARM_DESC(use_multi, "use per-CPU queues");
+#endif
+
+enum bnx2x_board_type {
+ BCM57710 = 0,
+ BCM57711 = 1,
+ BCM57711E = 2,
+};
+
+/* indexed by board_type, above */
+static struct {
+ char *name;
+} board_info[] __devinitdata = {
+ { "Broadcom NetXtreme II BCM57710 XGb" },
+ { "Broadcom NetXtreme II BCM57711 XGb" },
+ { "Broadcom NetXtreme II BCM57711E XGb" }
+};
+
+
+static const struct pci_device_id bnx2x_pci_tbl[] = {
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711 },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711E,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711E },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
+
+/****************************************************************************
+* General service functions
+****************************************************************************/
+
+/* used only at init
+ * locking is done by mcp
+ */
+static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
+{
+ pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
+ pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
+ pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
+ PCICFG_VENDOR_ID_OFFSET);
+}
+
+static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
+{
+ u32 val;
+
+ pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
+ pci_read_config_dword(bp->pdev, PCICFG_GRC_DATA, &val);
+ pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
+ PCICFG_VENDOR_ID_OFFSET);
+
+ return val;
+}
+
+static const u32 dmae_reg_go_c[] = {
+ DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
+ DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
+ DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
+ DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
+};
+
+/* copy command into DMAE command memory and set DMAE command go */
+static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
+ int idx)
+{
+ u32 cmd_offset;
+ int i;
+
+ cmd_offset = (DMAE_REG_CMD_MEM + sizeof(struct dmae_command) * idx);
+ for (i = 0; i < (sizeof(struct dmae_command)/4); i++) {
+ REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i));
+
+ DP(BNX2X_MSG_OFF, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
+ idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i));
+ }
+ REG_WR(bp, dmae_reg_go_c[idx], 1);
+}
+
+void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
+ u32 len32)
+{
+ struct dmae_command *dmae = &bp->init_dmae;
+ u32 *wb_comp = bnx2x_sp(bp, wb_comp);
+ int cnt = 200;
+
+ if (!bp->dmae_ready) {
+ u32 *data = bnx2x_sp(bp, wb_data[0]);
+
+ DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)"
+ " using indirect\n", dst_addr, len32);
+ bnx2x_init_ind_wr(bp, dst_addr, data, len32);
+ return;
+ }
+
+ mutex_lock(&bp->dmae_mutex);
+
+ memset(dmae, 0, sizeof(struct dmae_command));
+
+ dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+ DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->src_addr_lo = U64_LO(dma_addr);
+ dmae->src_addr_hi = U64_HI(dma_addr);
+ dmae->dst_addr_lo = dst_addr >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = len32;
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+ DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
+ "dst_addr [%x:%08x (%08x)]\n"
+ DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+ dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
+ dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+ DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
+ bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
+ bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
+
+ *wb_comp = 0;
+
+ bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+
+ udelay(5);
+
+ while (*wb_comp != DMAE_COMP_VAL) {
+ DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
+
+ /* adjust delay for emulation/FPGA */
+ if (CHIP_REV_IS_SLOW(bp))
+ msleep(100);
+ else
+ udelay(5);
+
+ if (!cnt) {
+ BNX2X_ERR("dmae timeout!\n");
+ break;
+ }
+ cnt--;
+ }
+
+ mutex_unlock(&bp->dmae_mutex);
+}
+
+void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
+{
+ struct dmae_command *dmae = &bp->init_dmae;
+ u32 *wb_comp = bnx2x_sp(bp, wb_comp);
+ int cnt = 200;
+
+ if (!bp->dmae_ready) {
+ u32 *data = bnx2x_sp(bp, wb_data[0]);
+ int i;
+
+ DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)"
+ " using indirect\n", src_addr, len32);
+ for (i = 0; i < len32; i++)
+ data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
+ return;
+ }
+
+ mutex_lock(&bp->dmae_mutex);
+
+ memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
+ memset(dmae, 0, sizeof(struct dmae_command));
+
+ dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+ DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->src_addr_lo = src_addr >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
+ dmae->len = len32;
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+ DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
+ "dst_addr [%x:%08x (%08x)]\n"
+ DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
+ dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+ dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
+ dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+
+ *wb_comp = 0;
+
+ bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+
+ udelay(5);
+
+ while (*wb_comp != DMAE_COMP_VAL) {
+
+ /* adjust delay for emulation/FPGA */
+ if (CHIP_REV_IS_SLOW(bp))
+ msleep(100);
+ else
+ udelay(5);
+
+ if (!cnt) {
+ BNX2X_ERR("dmae timeout!\n");
+ break;
+ }
+ cnt--;
+ }
+ DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
+ bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
+ bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
+
+ mutex_unlock(&bp->dmae_mutex);
+}
+
+/* used only for slowpath so not inlined */
+static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
+{
+ u32 wb_write[2];
+
+ wb_write[0] = val_hi;
+ wb_write[1] = val_lo;
+ REG_WR_DMAE(bp, reg, wb_write, 2);
+}
+
+#ifdef USE_WB_RD
+static u64 bnx2x_wb_rd(struct bnx2x *bp, int reg)
+{
+ u32 wb_data[2];
+
+ REG_RD_DMAE(bp, reg, wb_data, 2);
+
+ return HILO_U64(wb_data[0], wb_data[1]);
+}
+#endif
+
+static int bnx2x_mc_assert(struct bnx2x *bp)
+{
+ char last_idx;
+ int i, rc = 0;
+ u32 row0, row1, row2, row3;
+
+ /* XSTORM */
+ last_idx = REG_RD8(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("XSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("XSTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
+ /* TSTORM */
+ last_idx = REG_RD8(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("TSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("TSTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
+ /* CSTORM */
+ last_idx = REG_RD8(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("CSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("CSTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
+ /* USTORM */
+ last_idx = REG_RD8(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_INDEX_OFFSET);
+ if (last_idx)
+ BNX2X_ERR("USTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
+
+ /* print the asserts */
+ for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
+
+ row0 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i));
+ row1 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i) + 4);
+ row2 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i) + 8);
+ row3 = REG_RD(bp, BAR_USTRORM_INTMEM +
+ USTORM_ASSERT_LIST_OFFSET(i) + 12);
+
+ if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+ BNX2X_ERR("USTORM_ASSERT_INDEX 0x%x = 0x%08x"
+ " 0x%08x 0x%08x 0x%08x\n",
+ i, row3, row2, row1, row0);
+ rc++;
+ } else {
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static void bnx2x_fw_dump(struct bnx2x *bp)
+{
+ u32 mark, offset;
+ u32 data[9];
+ int word;
+
+ mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
+ mark = ((mark + 0x3) & ~0x3);
+ printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
+
+ for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
+ for (word = 0; word < 8; word++)
+ data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
+ offset + 4*word));
+ data[8] = 0x0;
+ printk(KERN_CONT "%s", (char *)data);
+ }
+ for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
+ for (word = 0; word < 8; word++)
+ data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
+ offset + 4*word));
+ data[8] = 0x0;
+ printk(KERN_CONT "%s", (char *)data);
+ }
+ printk("\n" KERN_ERR PFX "end of fw dump\n");
+}
+
+static void bnx2x_panic_dump(struct bnx2x *bp)
+{
+ int i;
+ u16 j, start, end;
+
+ BNX2X_ERR("begin crash dump -----------------\n");
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
+
+ BNX2X_ERR("queue[%d]: tx_pkt_prod(%x) tx_pkt_cons(%x)"
+ " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
+ i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
+ fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
+ BNX2X_ERR(" rx_comp_prod(%x) rx_comp_cons(%x)"
+ " *rx_cons_sb(%x) *rx_bd_cons_sb(%x)"
+ " rx_sge_prod(%x) last_max_sge(%x)\n",
+ fp->rx_comp_prod, fp->rx_comp_cons,
+ le16_to_cpu(*fp->rx_cons_sb),
+ le16_to_cpu(*fp->rx_bd_cons_sb),
+ fp->rx_sge_prod, fp->last_max_sge);
+ BNX2X_ERR(" fp_c_idx(%x) fp_u_idx(%x)"
+ " bd data(%x,%x) rx_alloc_failed(%lx)\n",
+ fp->fp_c_idx, fp->fp_u_idx, hw_prods->packets_prod,
+ hw_prods->bds_prod, fp->rx_alloc_failed);
+
+ start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
+ end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
+ for (j = start; j < end; j++) {
+ struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+
+ BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
+ sw_bd->skb, sw_bd->first_bd);
+ }
+
+ start = TX_BD(fp->tx_bd_cons - 10);
+ end = TX_BD(fp->tx_bd_cons + 254);
+ for (j = start; j < end; j++) {
+ u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+
+ BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
+ j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
+ }
+
+ start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
+ end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
+ for (j = start; j < end; j++) {
+ u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
+ struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
+
+ BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
+ j, rx_bd[1], rx_bd[0], sw_bd->skb);
+ }
+
+ start = 0;
+ end = RX_SGE_CNT*NUM_RX_SGE_PAGES;
+ for (j = start; j < end; j++) {
+ u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
+ struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
+
+ BNX2X_ERR("rx_sge[%x]=[%x:%x] sw_page=[%p]\n",
+ j, rx_sge[1], rx_sge[0], sw_page->page);
+ }
+
+ start = RCQ_BD(fp->rx_comp_cons - 10);
+ end = RCQ_BD(fp->rx_comp_cons + 503);
+ for (j = start; j < end; j++) {
+ u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
+
+ BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
+ j, cqe[0], cqe[1], cqe[2], cqe[3]);
+ }
+ }
+
+ BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
+ " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
+ " spq_prod_idx(%u)\n",
+ bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
+ bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+
+ bnx2x_fw_dump(bp);
+ bnx2x_mc_assert(bp);
+ BNX2X_ERR("end crash dump -----------------\n");
+
+ bp->stats_state = STATS_STATE_DISABLED;
+ DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
+}
+
+static void bnx2x_int_enable(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
+ u32 val = REG_RD(bp, addr);
+ int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+
+ if (msix) {
+ val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
+ val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+ } else {
+ val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+ HC_CONFIG_0_REG_INT_LINE_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
+ val, port, addr, msix);
+
+ REG_WR(bp, addr, val);
+
+ val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
+ }
+
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
+ val, port, addr, msix);
+
+ REG_WR(bp, addr, val);
+
+ if (CHIP_IS_E1H(bp)) {
+ /* init leading/trailing edge */
+ if (IS_E1HMF(bp)) {
+ val = (0xfe0f | (1 << (BP_E1HVN(bp) + 4)));
+ if (bp->port.pmf)
+ /* enable nig attention */
+ val |= 0x0100;
+ } else
+ val = 0xffff;
+
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
+ }
+}
+
+static void bnx2x_int_disable(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
+ u32 val = REG_RD(bp, addr);
+
+ val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+ HC_CONFIG_0_REG_INT_LINE_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
+ val, port, addr);
+
+ REG_WR(bp, addr, val);
+ if (REG_RD(bp, addr) != val)
+ BNX2X_ERR("BUG! proper val not read from IGU!\n");
+}
+
+static void bnx2x_int_disable_sync(struct bnx2x *bp)
+{
+ int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+ int i;
+
+ /* disable interrupt handling */
+ atomic_inc(&bp->intr_sem);
+ /* prevent the HW from sending interrupts */
+ bnx2x_int_disable(bp);
+
+ /* make sure all ISRs are done */
+ if (msix) {
+ for_each_queue(bp, i)
+ synchronize_irq(bp->msix_table[i].vector);
+
+ /* one more for the Slow Path IRQ */
+ synchronize_irq(bp->msix_table[i].vector);
+ } else
+ synchronize_irq(bp->pdev->irq);
+
+ /* make sure sp_task is not running */
+ cancel_work_sync(&bp->sp_task);
+}
+
+/* fast path */
+
+/*
+ * General service functions
+ */
+
+static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
+ u8 storm, u16 index, u8 op, u8 update)
+{
+ u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_FUNC_BASE * BP_FUNC(bp)) * 8;
+ struct igu_ack_register igu_ack;
+
+ igu_ack.status_block_index = index;
+ igu_ack.sb_id_and_flags =
+ ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
+ (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
+ (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
+ (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
+
+ DP(BNX2X_MSG_OFF, "write 0x%08x to IGU addr 0x%x\n",
+ (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr);
+ REG_WR(bp, BAR_IGU_INTMEM + igu_addr, (*(u32 *)&igu_ack));
+}
+
+static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
+{
+ struct host_status_block *fpsb = fp->status_blk;
+ u16 rc = 0;
+
+ barrier(); /* status block is written to by the chip */
+ if (fp->fp_c_idx != fpsb->c_status_block.status_block_index) {
+ fp->fp_c_idx = fpsb->c_status_block.status_block_index;
+ rc |= 1;
+ }
+ if (fp->fp_u_idx != fpsb->u_status_block.status_block_index) {
+ fp->fp_u_idx = fpsb->u_status_block.status_block_index;
+ rc |= 2;
+ }
+ return rc;
+}
+
+static inline int bnx2x_has_work(struct bnx2x_fastpath *fp)
+{
+ u16 rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+
+ if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+ rx_cons_sb++;
+
+ if ((fp->rx_comp_cons != rx_cons_sb) ||
+ (fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) ||
+ (fp->tx_pkt_prod != fp->tx_pkt_cons))
+ return 1;
+
+ return 0;
+}
+
+static u16 bnx2x_ack_int(struct bnx2x *bp)
+{
+ u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_FUNC_BASE * BP_FUNC(bp)) * 8;
+ u32 result = REG_RD(bp, BAR_IGU_INTMEM + igu_addr);
+
+ DP(BNX2X_MSG_OFF, "read 0x%08x from IGU addr 0x%x\n",
+ result, BAR_IGU_INTMEM + igu_addr);
+
+#ifdef IGU_DEBUG
+#warning IGU_DEBUG active
+ if (result == 0) {
+ BNX2X_ERR("read %x from IGU\n", result);
+ REG_WR(bp, TM_REG_TIMER_SOFT_RST, 0);
+ }
+#endif
+ return result;
+}
+
+
+/*
+ * fast path service functions
+ */
+
+/* free skb in the packet ring at pos idx
+ * return idx of last bd freed
+ */
+static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ u16 idx)
+{
+ struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx];
+ struct eth_tx_bd *tx_bd;
+ struct sk_buff *skb = tx_buf->skb;
+ u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
+ int nbd;
+
+ DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n",
+ idx, tx_buf, skb);
+
+ /* unmap first bd */
+ DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx);
+ tx_bd = &fp->tx_desc_ring[bd_idx];
+ pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_bd),
+ BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
+
+ nbd = le16_to_cpu(tx_bd->nbd) - 1;
+ new_cons = nbd + tx_buf->first_bd;
+#ifdef BNX2X_STOP_ON_ERROR
+ if (nbd > (MAX_SKB_FRAGS + 2)) {
+ BNX2X_ERR("BAD nbd!\n");
+ bnx2x_panic();
+ }
+#endif
+
+ /* Skip a parse bd and the TSO split header bd
+ since they have no mapping */
+ if (nbd)
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+
+ if (tx_bd->bd_flags.as_bitfield & (ETH_TX_BD_FLAGS_IP_CSUM |
+ ETH_TX_BD_FLAGS_TCP_CSUM |
+ ETH_TX_BD_FLAGS_SW_LSO)) {
+ if (--nbd)
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ tx_bd = &fp->tx_desc_ring[bd_idx];
+ /* is this a TSO split header bd? */
+ if (tx_bd->bd_flags.as_bitfield & ETH_TX_BD_FLAGS_SW_LSO) {
+ if (--nbd)
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+ }
+
+ /* now free frags */
+ while (nbd > 0) {
+
+ DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx);
+ tx_bd = &fp->tx_desc_ring[bd_idx];
+ pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_bd),
+ BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
+ if (--nbd)
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+
+ /* release skb */
+ BUG_TRAP(skb);
+ dev_kfree_skb(skb);
+ tx_buf->first_bd = 0;
+ tx_buf->skb = NULL;
+
+ return new_cons;
+}
+
+static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
+{
+ s16 used;
+ u16 prod;
+ u16 cons;
+
+ barrier(); /* Tell compiler that prod and cons can change */
+ prod = fp->tx_bd_prod;
+ cons = fp->tx_bd_cons;
+
+ /* NUM_TX_RINGS = number of "next-page" entries
+ It will be used as a threshold */
+ used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ BUG_TRAP(used >= 0);
+ BUG_TRAP(used <= fp->bp->tx_ring_size);
+ BUG_TRAP((fp->bp->tx_ring_size - used) <= MAX_TX_AVAIL);
+#endif
+
+ return (s16)(fp->bp->tx_ring_size) - used;
+}
+
+static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
+ int done = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return;
+#endif
+
+ hw_cons = le16_to_cpu(*fp->tx_cons_sb);
+ sw_cons = fp->tx_pkt_cons;
+
+ while (sw_cons != hw_cons) {
+ u16 pkt_cons;
+
+ pkt_cons = TX_BD(sw_cons);
+
+ /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */
+
+ DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n",
+ hw_cons, sw_cons, pkt_cons);
+
+/* if (NEXT_TX_IDX(sw_cons) != hw_cons) {
+ rmb();
+ prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb);
+ }
+*/
+ bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
+ sw_cons++;
+ done++;
+
+ if (done == work)
+ break;
+ }
+
+ fp->tx_pkt_cons = sw_cons;
+ fp->tx_bd_cons = bd_cons;
+
+ /* Need to make the tx_cons update visible to start_xmit()
+ * before checking for netif_queue_stopped(). Without the
+ * memory barrier, there is a small possibility that start_xmit()
+ * will miss it and cause the queue to be stopped forever.
+ */
+ smp_mb();
+
+ /* TBD need a thresh? */
+ if (unlikely(netif_queue_stopped(bp->dev))) {
+
+ netif_tx_lock(bp->dev);
+
+ if (netif_queue_stopped(bp->dev) &&
+ (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
+ netif_wake_queue(bp->dev);
+
+ netif_tx_unlock(bp->dev);
+ }
+}
+
+static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
+ union eth_rx_cqe *rr_cqe)
+{
+ struct bnx2x *bp = fp->bp;
+ int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data);
+ int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data);
+
+ DP(BNX2X_MSG_SP,
+ "fp %d cid %d got ramrod #%d state is %x type is %d\n",
+ FP_IDX(fp), cid, command, bp->state,
+ rr_cqe->ramrod_cqe.ramrod_type);
+
+ bp->spq_left++;
+
+ if (FP_IDX(fp)) {
+ switch (command | fp->state) {
+ case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
+ BNX2X_FP_STATE_OPENING):
+ DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n",
+ cid);
+ fp->state = BNX2X_FP_STATE_OPEN;
+ break;
+
+ case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING):
+ DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n",
+ cid);
+ fp->state = BNX2X_FP_STATE_HALTED;
+ break;
+
+ default:
+ BNX2X_ERR("unexpected MC reply (%d) "
+ "fp->state is %x\n", command, fp->state);
+ break;
+ }
+ mb(); /* force bnx2x_wait_ramrod() to see the change */
+ return;
+ }
+
+ switch (command | bp->state) {
+ case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
+ DP(NETIF_MSG_IFUP, "got setup ramrod\n");
+ bp->state = BNX2X_STATE_OPEN;
+ break;
+
+ case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFDOWN, "got halt ramrod\n");
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE;
+ fp->state = BNX2X_FP_STATE_HALTED;
+ break;
+
+ case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
+ bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
+ break;
+
+ case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
+ case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
+ DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
+ bp->set_mac_pending = 0;
+ break;
+
+ case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
+ DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
+ break;
+
+ default:
+ BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n",
+ command, bp->state);
+ break;
+ }
+ mb(); /* force bnx2x_wait_ramrod() to see the change */
+}
+
+static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, u16 index)
+{
+ struct sw_rx_page *sw_buf = &fp->rx_page_ring[index];
+ struct page *page = sw_buf->page;
+ struct eth_rx_sge *sge = &fp->rx_sge_ring[index];
+
+ /* Skip "next page" elements */
+ if (!page)
+ return;
+
+ pci_unmap_page(bp->pdev, pci_unmap_addr(sw_buf, mapping),
+ BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE);
+ __free_pages(page, PAGES_PER_SGE_SHIFT);
+
+ sw_buf->page = NULL;
+ sge->addr_hi = 0;
+ sge->addr_lo = 0;
+}
+
+static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, int last)
+{
+ int i;
+
+ for (i = 0; i < last; i++)
+ bnx2x_free_rx_sge(bp, fp, i);
+}
+
+static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, u16 index)
+{
+ struct page *page = alloc_pages(GFP_ATOMIC, PAGES_PER_SGE_SHIFT);
+ struct sw_rx_page *sw_buf = &fp->rx_page_ring[index];
+ struct eth_rx_sge *sge = &fp->rx_sge_ring[index];
+ dma_addr_t mapping;
+
+ if (unlikely(page == NULL))
+ return -ENOMEM;
+
+ mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(dma_mapping_error(mapping))) {
+ __free_pages(page, PAGES_PER_SGE_SHIFT);
+ return -ENOMEM;
+ }
+
+ sw_buf->page = page;
+ pci_unmap_addr_set(sw_buf, mapping, mapping);
+
+ sge->addr_hi = cpu_to_le32(U64_HI(mapping));
+ sge->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+ return 0;
+}
+
+static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, u16 index)
+{
+ struct sk_buff *skb;
+ struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index];
+ struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
+ dma_addr_t mapping;
+
+ skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ if (unlikely(skb == NULL))
+ return -ENOMEM;
+
+ mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(dma_mapping_error(mapping))) {
+ dev_kfree_skb(skb);
+ return -ENOMEM;
+ }
+
+ rx_buf->skb = skb;
+ pci_unmap_addr_set(rx_buf, mapping, mapping);
+
+ rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+ return 0;
+}
+
+/* note that we are not allocating a new skb,
+ * we are just moving one from cons to prod
+ * we are not creating a new mapping,
+ * so there is no need to check for dma_mapping_error().
+ */
+static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
+ struct sk_buff *skb, u16 cons, u16 prod)
+{
+ struct bnx2x *bp = fp->bp;
+ struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
+ struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
+ struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons];
+ struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
+
+ pci_dma_sync_single_for_device(bp->pdev,
+ pci_unmap_addr(cons_rx_buf, mapping),
+ bp->rx_offset + RX_COPY_THRESH,
+ PCI_DMA_FROMDEVICE);
+
+ prod_rx_buf->skb = cons_rx_buf->skb;
+ pci_unmap_addr_set(prod_rx_buf, mapping,
+ pci_unmap_addr(cons_rx_buf, mapping));
+ *prod_bd = *cons_bd;
+}
+
+static inline void bnx2x_update_last_max_sge(struct bnx2x_fastpath *fp,
+ u16 idx)
+{
+ u16 last_max = fp->last_max_sge;
+
+ if (SUB_S16(idx, last_max) > 0)
+ fp->last_max_sge = idx;
+}
+
+static void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp)
+{
+ int i, j;
+
+ for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
+ int idx = RX_SGE_CNT * i - 1;
+
+ for (j = 0; j < 2; j++) {
+ SGE_MASK_CLEAR_BIT(fp, idx);
+ idx--;
+ }
+ }
+}
+
+static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
+ struct eth_fast_path_rx_cqe *fp_cqe)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 sge_len = BCM_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) -
+ le16_to_cpu(fp_cqe->len_on_bd)) >>
+ BCM_PAGE_SHIFT;
+ u16 last_max, last_elem, first_elem;
+ u16 delta = 0;
+ u16 i;
+
+ if (!sge_len)
+ return;
+
+ /* First mark all used pages */
+ for (i = 0; i < sge_len; i++)
+ SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i])));
+
+ DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n",
+ sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1]));
+
+ /* Here we assume that the last SGE index is the biggest */
+ prefetch((void *)(fp->sge_mask));
+ bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1]));
+
+ last_max = RX_SGE(fp->last_max_sge);
+ last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT;
+ first_elem = RX_SGE(fp->rx_sge_prod) >> RX_SGE_MASK_ELEM_SHIFT;
+
+ /* If ring is not full */
+ if (last_elem + 1 != first_elem)
+ last_elem++;
+
+ /* Now update the prod */
+ for (i = first_elem; i != last_elem; i = NEXT_SGE_MASK_ELEM(i)) {
+ if (likely(fp->sge_mask[i]))
+ break;
+
+ fp->sge_mask[i] = RX_SGE_MASK_ELEM_ONE_MASK;
+ delta += RX_SGE_MASK_ELEM_SZ;
+ }
+
+ if (delta > 0) {
+ fp->rx_sge_prod += delta;
+ /* clear page-end entries */
+ bnx2x_clear_sge_mask_next_elems(fp);
+ }
+
+ DP(NETIF_MSG_RX_STATUS,
+ "fp->last_max_sge = %d fp->rx_sge_prod = %d\n",
+ fp->last_max_sge, fp->rx_sge_prod);
+}
+
+static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp)
+{
+ /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */
+ memset(fp->sge_mask, 0xff,
+ (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64));
+
+ /* Clear the two last indeces in the page to 1:
+ these are the indeces that correspond to the "next" element,
+ hence will never be indicated and should be removed from
+ the calculations. */
+ bnx2x_clear_sge_mask_next_elems(fp);
+}
+
+static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
+ struct sk_buff *skb, u16 cons, u16 prod)
+{
+ struct bnx2x *bp = fp->bp;
+ struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
+ struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
+ struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
+ dma_addr_t mapping;
+
+ /* move empty skb from pool to prod and map it */
+ prod_rx_buf->skb = fp->tpa_pool[queue].skb;
+ mapping = pci_map_single(bp->pdev, fp->tpa_pool[queue].skb->data,
+ bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+ pci_unmap_addr_set(prod_rx_buf, mapping, mapping);
+
+ /* move partial skb from cons to pool (don't unmap yet) */
+ fp->tpa_pool[queue] = *cons_rx_buf;
+
+ /* mark bin state as start - print error if current state != stop */
+ if (fp->tpa_state[queue] != BNX2X_TPA_STOP)
+ BNX2X_ERR("start of bin not in stop [%d]\n", queue);
+
+ fp->tpa_state[queue] = BNX2X_TPA_START;
+
+ /* point prod_bd to new skb */
+ prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+#ifdef BNX2X_STOP_ON_ERROR
+ fp->tpa_queue_used |= (1 << queue);
+#ifdef __powerpc64__
+ DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n",
+#else
+ DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n",
+#endif
+ fp->tpa_queue_used);
+#endif
+}
+
+static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ struct sk_buff *skb,
+ struct eth_fast_path_rx_cqe *fp_cqe,
+ u16 cqe_idx)
+{
+ struct sw_rx_page *rx_pg, old_rx_pg;
+ struct page *sge;
+ u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd);
+ u32 i, frag_len, frag_size, pages;
+ int err;
+ int j;
+
+ frag_size = le16_to_cpu(fp_cqe->pkt_len) - len_on_bd;
+ pages = BCM_PAGE_ALIGN(frag_size) >> BCM_PAGE_SHIFT;
+
+ /* This is needed in order to enable forwarding support */
+ if (frag_size)
+ skb_shinfo(skb)->gso_size = min((u32)BCM_PAGE_SIZE,
+ max(frag_size, (u32)len_on_bd));
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (pages > 8*PAGES_PER_SGE) {
+ BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n",
+ pages, cqe_idx);
+ BNX2X_ERR("fp_cqe->pkt_len = %d fp_cqe->len_on_bd = %d\n",
+ fp_cqe->pkt_len, len_on_bd);
+ bnx2x_panic();
+ return -EINVAL;
+ }
+#endif
+
+ /* Run through the SGL and compose the fragmented skb */
+ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) {
+ u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j]));
+
+ /* FW gives the indices of the SGE as if the ring is an array
+ (meaning that "next" element will consume 2 indices) */
+ frag_len = min(frag_size, (u32)(BCM_PAGE_SIZE*PAGES_PER_SGE));
+ rx_pg = &fp->rx_page_ring[sge_idx];
+ sge = rx_pg->page;
+ old_rx_pg = *rx_pg;
+
+ /* If we fail to allocate a substitute page, we simply stop
+ where we are and drop the whole packet */
+ err = bnx2x_alloc_rx_sge(bp, fp, sge_idx);
+ if (unlikely(err)) {
+ fp->rx_alloc_failed++;
+ return err;
+ }
+
+ /* Unmap the page as we r going to pass it to the stack */
+ pci_unmap_page(bp->pdev, pci_unmap_addr(&old_rx_pg, mapping),
+ BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE);
+
+ /* Add one frag and update the appropriate fields in the skb */
+ skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len);
+
+ skb->data_len += frag_len;
+ skb->truesize += frag_len;
+ skb->len += frag_len;
+
+ frag_size -= frag_len;
+ }
+
+ return 0;
+}
+
+static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ u16 queue, int pad, int len, union eth_rx_cqe *cqe,
+ u16 cqe_idx)
+{
+ struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue];
+ struct sk_buff *skb = rx_buf->skb;
+ /* alloc new skb */
+ struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+
+ /* Unmap skb in the pool anyway, as we are going to change
+ pool entry status to BNX2X_TPA_STOP even if new skb allocation
+ fails. */
+ pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
+ bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
+
+ /* if alloc failed drop the packet and keep the buffer in the bin */
+ if (likely(new_skb)) {
+
+ prefetch(skb);
+ prefetch(((char *)(skb)) + 128);
+
+ /* else fix ip xsum and give it to the stack */
+ /* (no need to map the new skb) */
+#ifdef BNX2X_STOP_ON_ERROR
+ if (pad + len > bp->rx_buf_size) {
+ BNX2X_ERR("skb_put is about to fail... "
+ "pad %d len %d rx_buf_size %d\n",
+ pad, len, bp->rx_buf_size);
+ bnx2x_panic();
+ return;
+ }
+#endif
+
+ skb_reserve(skb, pad);
+ skb_put(skb, len);
+
+ skb->protocol = eth_type_trans(skb, bp->dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ {
+ struct iphdr *iph;
+
+ iph = (struct iphdr *)skb->data;
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
+ }
+
+ if (!bnx2x_fill_frag_skb(bp, fp, skb,
+ &cqe->fast_path_cqe, cqe_idx)) {
+#ifdef BCM_VLAN
+ if ((bp->vlgrp != NULL) &&
+ (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
+ PARSING_FLAGS_VLAN))
+ vlan_hwaccel_receive_skb(skb, bp->vlgrp,
+ le16_to_cpu(cqe->fast_path_cqe.
+ vlan_tag));
+ else
+#endif
+ netif_receive_skb(skb);
+ } else {
+ DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages"
+ " - dropping packet!\n");
+ dev_kfree_skb(skb);
+ }
+
+ bp->dev->last_rx = jiffies;
+
+ /* put new skb in bin */
+ fp->tpa_pool[queue].skb = new_skb;
+
+ } else {
+ DP(NETIF_MSG_RX_STATUS,
+ "Failed to allocate new skb - dropping packet!\n");
+ fp->rx_alloc_failed++;
+ }
+
+ fp->tpa_state[queue] = BNX2X_TPA_STOP;
+}
+
+static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp,
+ u16 bd_prod, u16 rx_comp_prod,
+ u16 rx_sge_prod)
+{
+ struct tstorm_eth_rx_producers rx_prods = {0};
+ int i;
+
+ /* Update producers */
+ rx_prods.bd_prod = bd_prod;
+ rx_prods.cqe_prod = rx_comp_prod;
+ rx_prods.sge_prod = rx_sge_prod;
+
+ for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++)
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
+ ((u32 *)&rx_prods)[i]);
+
+ DP(NETIF_MSG_RX_STATUS,
+ "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n",
+ bd_prod, rx_comp_prod, rx_sge_prod);
+}
+
+static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
+ u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
+ int rx_pkt = 0;
+ u16 queue;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return 0;
+#endif
+
+ /* CQ "next element" is of the size of the regular element,
+ that's why it's ok here */
+ hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb);
+ if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+ hw_comp_cons++;
+
+ bd_cons = fp->rx_bd_cons;
+ bd_prod = fp->rx_bd_prod;
+ bd_prod_fw = bd_prod;
+ sw_comp_cons = fp->rx_comp_cons;
+ sw_comp_prod = fp->rx_comp_prod;
+
+ /* Memory barrier necessary as speculative reads of the rx
+ * buffer can be ahead of the index in the status block
+ */
+ rmb();
+
+ DP(NETIF_MSG_RX_STATUS,
+ "queue[%d]: hw_comp_cons %u sw_comp_cons %u\n",
+ FP_IDX(fp), hw_comp_cons, sw_comp_cons);
+
+ while (sw_comp_cons != hw_comp_cons) {
+ struct sw_rx_bd *rx_buf = NULL;
+ struct sk_buff *skb;
+ union eth_rx_cqe *cqe;
+ u8 cqe_fp_flags;
+ u16 len, pad;
+
+ comp_ring_cons = RCQ_BD(sw_comp_cons);
+ bd_prod = RX_BD(bd_prod);
+ bd_cons = RX_BD(bd_cons);
+
+ cqe = &fp->rx_comp_ring[comp_ring_cons];
+ cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
+
+ DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x"
+ " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags),
+ cqe_fp_flags, cqe->fast_path_cqe.status_flags,
+ cqe->fast_path_cqe.rss_hash_result,
+ le16_to_cpu(cqe->fast_path_cqe.vlan_tag),
+ le16_to_cpu(cqe->fast_path_cqe.pkt_len));
+
+ /* is this a slowpath msg? */
+ if (unlikely(CQE_TYPE(cqe_fp_flags))) {
+ bnx2x_sp_event(fp, cqe);
+ goto next_cqe;
+
+ /* this is an rx packet */
+ } else {
+ rx_buf = &fp->rx_buf_ring[bd_cons];
+ skb = rx_buf->skb;
+ len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
+ pad = cqe->fast_path_cqe.placement_offset;
+
+ /* If CQE is marked both TPA_START and TPA_END
+ it is a non-TPA CQE */
+ if ((!fp->disable_tpa) &&
+ (TPA_TYPE(cqe_fp_flags) !=
+ (TPA_TYPE_START | TPA_TYPE_END))) {
+ queue = cqe->fast_path_cqe.queue_index;
+
+ if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) {
+ DP(NETIF_MSG_RX_STATUS,
+ "calling tpa_start on queue %d\n",
+ queue);
+
+ bnx2x_tpa_start(fp, queue, skb,
+ bd_cons, bd_prod);
+ goto next_rx;
+ }
+
+ if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) {
+ DP(NETIF_MSG_RX_STATUS,
+ "calling tpa_stop on queue %d\n",
+ queue);
+
+ if (!BNX2X_RX_SUM_FIX(cqe))
+ BNX2X_ERR("STOP on none TCP "
+ "data\n");
+
+ /* This is a size of the linear data
+ on this skb */
+ len = le16_to_cpu(cqe->fast_path_cqe.
+ len_on_bd);
+ bnx2x_tpa_stop(bp, fp, queue, pad,
+ len, cqe, comp_ring_cons);
+#ifdef BNX2X_STOP_ON_ERROR
+ if (bp->panic)
+ return -EINVAL;
+#endif
+
+ bnx2x_update_sge_prod(fp,
+ &cqe->fast_path_cqe);
+ goto next_cqe;
+ }
+ }
+
+ pci_dma_sync_single_for_device(bp->pdev,
+ pci_unmap_addr(rx_buf, mapping),
+ pad + RX_COPY_THRESH,
+ PCI_DMA_FROMDEVICE);
+ prefetch(skb);
+ prefetch(((char *)(skb)) + 128);
+
+ /* is this an error packet? */
+ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
+ /* do we sometimes forward error packets anyway? */
+ DP(NETIF_MSG_RX_ERR,
+ "ERROR flags %x rx packet %u\n",
+ cqe_fp_flags, sw_comp_cons);
+ /* TBD make sure MC counts this as a drop */
+ goto reuse_rx;
+ }
+
+ /* Since we don't have a jumbo ring
+ * copy small packets if mtu > 1500
+ */
+ if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
+ (len <= RX_COPY_THRESH)) {
+ struct sk_buff *new_skb;
+
+ new_skb = netdev_alloc_skb(bp->dev,
+ len + pad);
+ if (new_skb == NULL) {
+ DP(NETIF_MSG_RX_ERR,
+ "ERROR packet dropped "
+ "because of alloc failure\n");
+ fp->rx_alloc_failed++;
+ goto reuse_rx;
+ }
+
+ /* aligned copy */
+ skb_copy_from_linear_data_offset(skb, pad,
+ new_skb->data + pad, len);
+ skb_reserve(new_skb, pad);
+ skb_put(new_skb, len);
+
+ bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
+
+ skb = new_skb;
+
+ } else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) {
+ pci_unmap_single(bp->pdev,
+ pci_unmap_addr(rx_buf, mapping),
+ bp->rx_buf_use_size,
+ PCI_DMA_FROMDEVICE);
+ skb_reserve(skb, pad);
+ skb_put(skb, len);
+
+ } else {
+ DP(NETIF_MSG_RX_ERR,
+ "ERROR packet dropped because "
+ "of alloc failure\n");
+ fp->rx_alloc_failed++;
+reuse_rx:
+ bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
+ goto next_rx;
+ }
+
+ skb->protocol = eth_type_trans(skb, bp->dev);
+
+ skb->ip_summed = CHECKSUM_NONE;
+ if (bp->rx_csum && BNX2X_RX_SUM_OK(cqe))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ /* TBD do we pass bad csum packets in promisc */
+ }
+
+#ifdef BCM_VLAN
+ if ((bp->vlgrp != NULL) &&
+ (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
+ PARSING_FLAGS_VLAN))
+ vlan_hwaccel_receive_skb(skb, bp->vlgrp,
+ le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
+ else
+#endif
+ netif_receive_skb(skb);
+
+ bp->dev->last_rx = jiffies;
+
+next_rx:
+ rx_buf->skb = NULL;
+
+ bd_cons = NEXT_RX_IDX(bd_cons);
+ bd_prod = NEXT_RX_IDX(bd_prod);
+ bd_prod_fw = NEXT_RX_IDX(bd_prod_fw);
+ rx_pkt++;
+next_cqe:
+ sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
+ sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
+
+ if (rx_pkt == budget)
+ break;
+ } /* while */
+
+ fp->rx_bd_cons = bd_cons;
+ fp->rx_bd_prod = bd_prod_fw;
+ fp->rx_comp_cons = sw_comp_cons;
+ fp->rx_comp_prod = sw_comp_prod;
+
+ /* Update producers */
+ bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod,
+ fp->rx_sge_prod);
+ mmiowb(); /* keep prod updates ordered */
+
+ fp->rx_pkt += rx_pkt;
+ fp->rx_calls++;
+
+ return rx_pkt;
+}
+
+static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
+{
+ struct bnx2x_fastpath *fp = fp_cookie;
+ struct bnx2x *bp = fp->bp;
+ struct net_device *dev = bp->dev;
+ int index = FP_IDX(fp);
+
+ DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
+ index, FP_SB_ID(fp));
+ bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return IRQ_HANDLED;
+#endif
+
+ prefetch(fp->rx_cons_sb);
+ prefetch(fp->tx_cons_sb);
+ prefetch(&fp->status_blk->c_status_block.status_block_index);
+ prefetch(&fp->status_blk->u_status_block.status_block_index);
+
+ netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi));
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
+{
+ struct net_device *dev = dev_instance;
+ struct bnx2x *bp = netdev_priv(dev);
+ u16 status = bnx2x_ack_int(bp);
+ u16 mask;
+
+ /* Return here if interrupt is shared and it's not for us */
+ if (unlikely(status == 0)) {
+ DP(NETIF_MSG_INTR, "not our interrupt!\n");
+ return IRQ_NONE;
+ }
+ DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return IRQ_HANDLED;
+#endif
+
+ /* Return here if interrupt is disabled */
+ if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+ DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+ return IRQ_HANDLED;
+ }
+
+ mask = 0x2 << bp->fp[0].sb_id;
+ if (status & mask) {
+ struct bnx2x_fastpath *fp = &bp->fp[0];
+
+ prefetch(fp->rx_cons_sb);
+ prefetch(fp->tx_cons_sb);
+ prefetch(&fp->status_blk->c_status_block.status_block_index);
+ prefetch(&fp->status_blk->u_status_block.status_block_index);
+
+ netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi));
+
+ status &= ~mask;
+ }
+
+
+ if (unlikely(status & 0x1)) {
+ schedule_work(&bp->sp_task);
+
+ status &= ~0x1;
+ if (!status)
+ return IRQ_HANDLED;
+ }
+
+ if (status)
+ DP(NETIF_MSG_INTR, "got an unknown interrupt! (status %u)\n",
+ status);
+
+ return IRQ_HANDLED;
+}
+
+/* end of fast path */
+
+static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
+
+/* Link */
+
+/*
+ * General service functions
+ */
+
+static int bnx2x_hw_lock(struct bnx2x *bp, u32 resource)
+{
+ u32 lock_status;
+ u32 resource_bit = (1 << resource);
+ u8 port = BP_PORT(bp);
+ int cnt;
+
+ /* Validating that the resource is within range */
+ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+ DP(NETIF_MSG_HW,
+ "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+ resource, HW_LOCK_MAX_RESOURCE_VALUE);
+ return -EINVAL;
+ }
+
+ /* Validating that the resource is not already taken */
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
+ if (lock_status & resource_bit) {
+ DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
+ lock_status, resource_bit);
+ return -EEXIST;
+ }
+
+ /* Try for 1 second every 5ms */
+ for (cnt = 0; cnt < 200; cnt++) {
+ /* Try to acquire the lock */
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + port*8 + 4,
+ resource_bit);
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
+ if (lock_status & resource_bit)
+ return 0;
+
+ msleep(5);
+ }
+ DP(NETIF_MSG_HW, "Timeout\n");
+ return -EAGAIN;
+}
+
+static int bnx2x_hw_unlock(struct bnx2x *bp, u32 resource)
+{
+ u32 lock_status;
+ u32 resource_bit = (1 << resource);
+ u8 port = BP_PORT(bp);
+
+ /* Validating that the resource is within range */
+ if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
+ DP(NETIF_MSG_HW,
+ "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
+ resource, HW_LOCK_MAX_RESOURCE_VALUE);
+ return -EINVAL;
+ }
+
+ /* Validating that the resource is currently taken */
+ lock_status = REG_RD(bp, MISC_REG_DRIVER_CONTROL_1 + port*8);
+ if (!(lock_status & resource_bit)) {
+ DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
+ lock_status, resource_bit);
+ return -EFAULT;
+ }
+
+ REG_WR(bp, MISC_REG_DRIVER_CONTROL_1 + port*8, resource_bit);
+ return 0;
+}
+
+/* HW Lock for shared dual port PHYs */
+static void bnx2x_phy_hw_lock(struct bnx2x *bp)
+{
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+
+ mutex_lock(&bp->port.phy_mutex);
+
+ if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+}
+
+static void bnx2x_phy_hw_unlock(struct bnx2x *bp)
+{
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+
+ if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+
+ mutex_unlock(&bp->port.phy_mutex);
+}
+
+int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ BP_PORT(bp);
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+ /* read GPIO and mask except the float bits */
+ gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
+
+ switch (mode) {
+ case MISC_REGISTERS_GPIO_OUTPUT_LOW:
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
+ gpio_num, gpio_shift);
+ /* clear FLOAT and set CLR */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
+ gpio_num, gpio_shift);
+ /* clear FLOAT and set SET */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_INPUT_HI_Z :
+ DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
+ gpio_num, gpio_shift);
+ /* set FLOAT */
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_GPIO, gpio_reg);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_GPIO);
+
+ return 0;
+}
+
+static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
+{
+ u32 spio_mask = (1 << spio_num);
+ u32 spio_reg;
+
+ if ((spio_num < MISC_REGISTERS_SPIO_4) ||
+ (spio_num > MISC_REGISTERS_SPIO_7)) {
+ BNX2X_ERR("Invalid SPIO %d\n", spio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
+ /* read SPIO and mask except the float bits */
+ spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
+
+ switch (mode) {
+ case MISC_REGISTERS_SPIO_OUTPUT_LOW :
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
+ /* clear FLOAT and set CLR */
+ spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_SPIO_OUTPUT_HIGH :
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
+ /* clear FLOAT and set SET */
+ spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
+ break;
+
+ case MISC_REGISTERS_SPIO_INPUT_HI_Z:
+ DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
+ /* set FLOAT */
+ spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_SPIO, spio_reg);
+ bnx2x_hw_unlock(bp, HW_LOCK_RESOURCE_SPIO);
+
+ return 0;
+}
+
+static void bnx2x_calc_fc_adv(struct bnx2x *bp)
+{
+ switch (bp->link_vars.ieee_fc) {
+ case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
+ bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
+ ADVERTISED_Pause);
+ break;
+ case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
+ bp->port.advertising |= (ADVERTISED_Asym_Pause |
+ ADVERTISED_Pause);
+ break;
+ case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
+ bp->port.advertising |= ADVERTISED_Asym_Pause;
+ break;
+ default:
+ bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
+ ADVERTISED_Pause);
+ break;
+ }
+}
+
+static void bnx2x_link_report(struct bnx2x *bp)
+{
+ if (bp->link_vars.link_up) {
+ if (bp->state == BNX2X_STATE_OPEN)
+ netif_carrier_on(bp->dev);
+ printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
+
+ printk("%d Mbps ", bp->link_vars.line_speed);
+
+ if (bp->link_vars.duplex == DUPLEX_FULL)
+ printk("full duplex");
+ else
+ printk("half duplex");
+
+ if (bp->link_vars.flow_ctrl != FLOW_CTRL_NONE) {
+ if (bp->link_vars.flow_ctrl & FLOW_CTRL_RX) {
+ printk(", receive ");
+ if (bp->link_vars.flow_ctrl & FLOW_CTRL_TX)
+ printk("& transmit ");
+ } else {
+ printk(", transmit ");
+ }
+ printk("flow control ON");
+ }
+ printk("\n");
+
+ } else { /* link_down */
+ netif_carrier_off(bp->dev);
+ printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+ }
+}
+
+static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
+{
+ u8 rc;
+
+ /* Initialize link parameters structure variables */
+ bp->link_params.mtu = bp->dev->mtu;
+
+ bnx2x_phy_hw_lock(bp);
+ rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+
+ if (bp->link_vars.link_up)
+ bnx2x_link_report(bp);
+
+ bnx2x_calc_fc_adv(bp);
+
+ return rc;
+}
+
+static void bnx2x_link_set(struct bnx2x *bp)
+{
+ bnx2x_phy_hw_lock(bp);
+ bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+
+ bnx2x_calc_fc_adv(bp);
+}
+
+static void bnx2x__link_reset(struct bnx2x *bp)
+{
+ bnx2x_phy_hw_lock(bp);
+ bnx2x_link_reset(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+}
+
+static u8 bnx2x_link_test(struct bnx2x *bp)
+{
+ u8 rc;
+
+ bnx2x_phy_hw_lock(bp);
+ rc = bnx2x_test_link(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+
+ return rc;
+}
+
+/* Calculates the sum of vn_min_rates.
+ It's needed for further normalizing of the min_rates.
+
+ Returns:
+ sum of vn_min_rates
+ or
+ 0 - if all the min_rates are 0.
+ In the later case fainess algorithm should be deactivated.
+ If not all min_rates are zero then those that are zeroes will
+ be set to 1.
+ */
+static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
+{
+ int i, port = BP_PORT(bp);
+ u32 wsum = 0;
+ int all_zero = 1;
+
+ for (i = 0; i < E1HVN_MAX; i++) {
+ u32 vn_cfg =
+ SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
+ u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+ FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+ if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
+ /* If min rate is zero - set it to 1 */
+ if (!vn_min_rate)
+ vn_min_rate = DEF_MIN_RATE;
+ else
+ all_zero = 0;
+
+ wsum += vn_min_rate;
+ }
+ }
+
+ /* ... only if all min rates are zeros - disable FAIRNESS */
+ if (all_zero)
+ return 0;
+
+ return wsum;
+}
+
+static void bnx2x_init_port_minmax(struct bnx2x *bp,
+ int en_fness,
+ u16 port_rate,
+ struct cmng_struct_per_port *m_cmng_port)
+{
+ u32 r_param = port_rate / 8;
+ int port = BP_PORT(bp);
+ int i;
+
+ memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
+
+ /* Enable minmax only if we are in e1hmf mode */
+ if (IS_E1HMF(bp)) {
+ u32 fair_periodic_timeout_usec;
+ u32 t_fair;
+
+ /* Enable rate shaping and fairness */
+ m_cmng_port->flags.cmng_vn_enable = 1;
+ m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
+ m_cmng_port->flags.rate_shaping_enable = 1;
+
+ if (!en_fness)
+ DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+ " fairness will be disabled\n");
+
+ /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
+ m_cmng_port->rs_vars.rs_periodic_timeout =
+ RS_PERIODIC_TIMEOUT_USEC / 4;
+
+ /* this is the threshold below which no timer arming will occur
+ 1.25 coefficient is for the threshold to be a little bigger
+ than the real time, to compensate for timer in-accuracy */
+ m_cmng_port->rs_vars.rs_threshold =
+ (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
+
+ /* resolution of fairness timer */
+ fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+ /* for 10G it is 1000usec. for 1G it is 10000usec. */
+ t_fair = T_FAIR_COEF / port_rate;
+
+ /* this is the threshold below which we won't arm
+ the timer anymore */
+ m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
+
+ /* we multiply by 1e3/8 to get bytes/msec.
+ We don't want the credits to pass a credit
+ of the T_FAIR*FAIR_MEM (algorithm resolution) */
+ m_cmng_port->fair_vars.upper_bound =
+ r_param * t_fair * FAIR_MEM;
+ /* since each tick is 4 usec */
+ m_cmng_port->fair_vars.fairness_timeout =
+ fair_periodic_timeout_usec / 4;
+
+ } else {
+ /* Disable rate shaping and fairness */
+ m_cmng_port->flags.cmng_vn_enable = 0;
+ m_cmng_port->flags.fairness_enable = 0;
+ m_cmng_port->flags.rate_shaping_enable = 0;
+
+ DP(NETIF_MSG_IFUP,
+ "Single function mode minmax will be disabled\n");
+ }
+
+ /* Store it to internal memory */
+ for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
+ ((u32 *)(m_cmng_port))[i]);
+}
+
+static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
+ u32 wsum, u16 port_rate,
+ struct cmng_struct_per_port *m_cmng_port)
+{
+ struct rate_shaping_vars_per_vn m_rs_vn;
+ struct fairness_vars_per_vn m_fair_vn;
+ u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+ u16 vn_min_rate, vn_max_rate;
+ int i;
+
+ /* If function is hidden - set min and max to zeroes */
+ if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) {
+ vn_min_rate = 0;
+ vn_max_rate = 0;
+
+ } else {
+ vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+ FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+ /* If FAIRNESS is enabled (not all min rates are zeroes) and
+ if current min rate is zero - set it to 1.
+ This is a requirment of the algorithm. */
+ if ((vn_min_rate == 0) && wsum)
+ vn_min_rate = DEF_MIN_RATE;
+ vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
+ }
+
+ DP(NETIF_MSG_IFUP, "func %d: vn_min_rate=%d vn_max_rate=%d "
+ "wsum=%d\n", func, vn_min_rate, vn_max_rate, wsum);
+
+ memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
+ memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
+
+ /* global vn counter - maximal Mbps for this vn */
+ m_rs_vn.vn_counter.rate = vn_max_rate;
+
+ /* quota - number of bytes transmitted in this period */
+ m_rs_vn.vn_counter.quota =
+ (vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
+
+#ifdef BNX2X_PER_PROT_QOS
+ /* per protocol counter */
+ for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++) {
+ /* maximal Mbps for this protocol */
+ m_rs_vn.protocol_counters[protocol].rate =
+ protocol_max_rate[protocol];
+ /* the quota in each timer period -
+ number of bytes transmitted in this period */
+ m_rs_vn.protocol_counters[protocol].quota =
+ (u32)(rs_periodic_timeout_usec *
+ ((double)m_rs_vn.
+ protocol_counters[protocol].rate/8));
+ }
+#endif
+
+ if (wsum) {
+ /* credit for each period of the fairness algorithm:
+ number of bytes in T_FAIR (the vn share the port rate).
+ wsum should not be larger than 10000, thus
+ T_FAIR_COEF / (8 * wsum) will always be grater than zero */
+ m_fair_vn.vn_credit_delta =
+ max((u64)(vn_min_rate * (T_FAIR_COEF / (8 * wsum))),
+ (u64)(m_cmng_port->fair_vars.fair_threshold * 2));
+ DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
+ m_fair_vn.vn_credit_delta);
+ }
+
+#ifdef BNX2X_PER_PROT_QOS
+ do {
+ u32 protocolWeightSum = 0;
+
+ for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++)
+ protocolWeightSum +=
+ drvInit.protocol_min_rate[protocol];
+ /* per protocol counter -
+ NOT NEEDED IF NO PER-PROTOCOL CONGESTION MANAGEMENT */
+ if (protocolWeightSum > 0) {
+ for (protocol = 0;
+ protocol < NUM_OF_PROTOCOLS; protocol++)
+ /* credit for each period of the
+ fairness algorithm - number of bytes in
+ T_FAIR (the protocol share the vn rate) */
+ m_fair_vn.protocol_credit_delta[protocol] =
+ (u32)((vn_min_rate / 8) * t_fair *
+ protocol_min_rate / protocolWeightSum);
+ }
+ } while (0);
+#endif
+
+ /* Store it to internal memory */
+ for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func) + i * 4,
+ ((u32 *)(&m_rs_vn))[i]);
+
+ for (i = 0; i < sizeof(struct fairness_vars_per_vn)/4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4,
+ ((u32 *)(&m_fair_vn))[i]);
+}
+
+/* This function is called upon link interrupt */
+static void bnx2x_link_attn(struct bnx2x *bp)
+{
+ int vn;
+
+ /* Make sure that we are synced with the current statistics */
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+
+ bnx2x_phy_hw_lock(bp);
+ bnx2x_link_update(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+
+ if (bp->link_vars.link_up) {
+
+ if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
+ struct host_port_stats *pstats;
+
+ pstats = bnx2x_sp(bp, port_stats);
+ /* reset old bmac stats */
+ memset(&(pstats->mac_stx[0]), 0,
+ sizeof(struct mac_stx));
+ }
+ if ((bp->state == BNX2X_STATE_OPEN) ||
+ (bp->state == BNX2X_STATE_DISABLED))
+ bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
+ }
+
+ /* indicate link status */
+ bnx2x_link_report(bp);
+
+ if (IS_E1HMF(bp)) {
+ int func;
+
+ for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+ if (vn == BP_E1HVN(bp))
+ continue;
+
+ func = ((vn << 1) | BP_PORT(bp));
+
+ /* Set the attention towards other drivers
+ on the same port */
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
+ (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
+ }
+ }
+
+ if (CHIP_IS_E1H(bp) && (bp->link_vars.line_speed > 0)) {
+ struct cmng_struct_per_port m_cmng_port;
+ u32 wsum;
+ int port = BP_PORT(bp);
+
+ /* Init RATE SHAPING and FAIRNESS contexts */
+ wsum = bnx2x_calc_vn_wsum(bp);
+ bnx2x_init_port_minmax(bp, (int)wsum,
+ bp->link_vars.line_speed,
+ &m_cmng_port);
+ if (IS_E1HMF(bp))
+ for (vn = VN_0; vn < E1HVN_MAX; vn++)
+ bnx2x_init_vn_minmax(bp, 2*vn + port,
+ wsum, bp->link_vars.line_speed,
+ &m_cmng_port);
+ }
+}
+
+static void bnx2x__link_status_update(struct bnx2x *bp)
+{
+ if (bp->state != BNX2X_STATE_OPEN)
+ return;
+
+ bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
+
+ if (bp->link_vars.link_up)
+ bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
+ else
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+
+ /* indicate link status */
+ bnx2x_link_report(bp);
+}
+
+static void bnx2x_pmf_update(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ u32 val;
+
+ bp->port.pmf = 1;
+ DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
+
+ /* enable nig attention */
+ val = (0xff0f | (1 << (BP_E1HVN(bp) + 4)));
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
+
+ bnx2x_stats_handle(bp, STATS_EVENT_PMF);
+}
+
+/* end of Link */
+
+/* slow path */
+
+/*
+ * General service functions
+ */
+
+/* the slow path queue is odd since completions arrive on the fastpath ring */
+static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
+ u32 data_hi, u32 data_lo, int common)
+{
+ int func = BP_FUNC(bp);
+
+ DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
+ "SPQE (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
+ (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
+ (void *)bp->spq_prod_bd - (void *)bp->spq), command,
+ HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return -EIO;
+#endif
+
+ spin_lock_bh(&bp->spq_lock);
+
+ if (!bp->spq_left) {
+ BNX2X_ERR("BUG! SPQ ring full!\n");
+ spin_unlock_bh(&bp->spq_lock);
+ bnx2x_panic();
+ return -EBUSY;
+ }
+
+ /* CID needs port number to be encoded int it */
+ bp->spq_prod_bd->hdr.conn_and_cmd_data =
+ cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
+ HW_CID(bp, cid)));
+ bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
+ if (common)
+ bp->spq_prod_bd->hdr.type |=
+ cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
+
+ bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi);
+ bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo);
+
+ bp->spq_left--;
+
+ if (bp->spq_prod_bd == bp->spq_last_bd) {
+ bp->spq_prod_bd = bp->spq;
+ bp->spq_prod_idx = 0;
+ DP(NETIF_MSG_TIMER, "end of spq\n");
+
+ } else {
+ bp->spq_prod_bd++;
+ bp->spq_prod_idx++;
+ }
+
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
+ bp->spq_prod_idx);
+
+ spin_unlock_bh(&bp->spq_lock);
+ return 0;
+}
+
+/* acquire split MCP access lock register */
+static int bnx2x_lock_alr(struct bnx2x *bp)
+{
+ u32 i, j, val;
+ int rc = 0;
+
+ might_sleep();
+ i = 100;
+ for (j = 0; j < i*10; j++) {
+ val = (1UL << 31);
+ REG_WR(bp, GRCBASE_MCP + 0x9c, val);
+ val = REG_RD(bp, GRCBASE_MCP + 0x9c);
+ if (val & (1L << 31))
+ break;
+
+ msleep(5);
+ }
+ if (!(val & (1L << 31))) {
+ BNX2X_ERR("Cannot acquire nvram interface\n");
+ rc = -EBUSY;
+ }
+
+ return rc;
+}
+
+/* Release split MCP access lock register */
+static void bnx2x_unlock_alr(struct bnx2x *bp)
+{
+ u32 val = 0;
+
+ REG_WR(bp, GRCBASE_MCP + 0x9c, val);
+}
+
+static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
+{
+ struct host_def_status_block *def_sb = bp->def_status_blk;
+ u16 rc = 0;
+
+ barrier(); /* status block is written to by the chip */
+
+ if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) {
+ bp->def_att_idx = def_sb->atten_status_block.attn_bits_index;
+ rc |= 1;
+ }
+ if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) {
+ bp->def_c_idx = def_sb->c_def_status_block.status_block_index;
+ rc |= 2;
+ }
+ if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) {
+ bp->def_u_idx = def_sb->u_def_status_block.status_block_index;
+ rc |= 4;
+ }
+ if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) {
+ bp->def_x_idx = def_sb->x_def_status_block.status_block_index;
+ rc |= 8;
+ }
+ if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) {
+ bp->def_t_idx = def_sb->t_def_status_block.status_block_index;
+ rc |= 16;
+ }
+ return rc;
+}
+
+/*
+ * slow path service functions
+ */
+
+static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
+{
+ int port = BP_PORT(bp);
+ int func = BP_FUNC(bp);
+ u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_FUNC_BASE * func) * 8;
+ u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
+ MISC_REG_AEU_MASK_ATTN_FUNC_0;
+ u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
+ NIG_REG_MASK_INTERRUPT_PORT0;
+
+ if (~bp->aeu_mask & (asserted & 0xff))
+ BNX2X_ERR("IGU ERROR\n");
+ if (bp->attn_state & asserted)
+ BNX2X_ERR("IGU ERROR\n");
+
+ DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n",
+ bp->aeu_mask, asserted);
+ bp->aeu_mask &= ~(asserted & 0xff);
+ DP(NETIF_MSG_HW, "after masking: aeu_mask %x\n", bp->aeu_mask);
+
+ REG_WR(bp, aeu_addr, bp->aeu_mask);
+
+ bp->attn_state |= asserted;
+
+ if (asserted & ATTN_HARD_WIRED_MASK) {
+ if (asserted & ATTN_NIG_FOR_FUNC) {
+
+ /* save nig interrupt mask */
+ bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+ REG_WR(bp, nig_int_mask_addr, 0);
+
+ bnx2x_link_attn(bp);
+
+ /* handle unicore attn? */
+ }
+ if (asserted & ATTN_SW_TIMER_4_FUNC)
+ DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n");
+
+ if (asserted & GPIO_2_FUNC)
+ DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n");
+
+ if (asserted & GPIO_3_FUNC)
+ DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n");
+
+ if (asserted & GPIO_4_FUNC)
+ DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n");
+
+ if (port == 0) {
+ if (asserted & ATTN_GENERAL_ATTN_1) {
+ DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0);
+ }
+ if (asserted & ATTN_GENERAL_ATTN_2) {
+ DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0);
+ }
+ if (asserted & ATTN_GENERAL_ATTN_3) {
+ DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0);
+ }
+ } else {
+ if (asserted & ATTN_GENERAL_ATTN_4) {
+ DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0);
+ }
+ if (asserted & ATTN_GENERAL_ATTN_5) {
+ DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0);
+ }
+ if (asserted & ATTN_GENERAL_ATTN_6) {
+ DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0);
+ }
+ }
+
+ } /* if hardwired */
+
+ DP(NETIF_MSG_HW, "about to mask 0x%08x at IGU addr 0x%x\n",
+ asserted, BAR_IGU_INTMEM + igu_addr);
+ REG_WR(bp, BAR_IGU_INTMEM + igu_addr, asserted);
+
+ /* now set back the mask */
+ if (asserted & ATTN_NIG_FOR_FUNC)
+ REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
+}
+
+static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
+{
+ int port = BP_PORT(bp);
+ int reg_offset;
+ u32 val;
+
+ reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+ MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+
+ if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) {
+
+ val = REG_RD(bp, reg_offset);
+ val &= ~AEU_INPUTS_ATTN_BITS_SPIO5;
+ REG_WR(bp, reg_offset, val);
+
+ BNX2X_ERR("SPIO5 hw attention\n");
+
+ switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* Fan failure attention */
+
+ /* The PHY reset is controled by GPIO 1 */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ /* Low power mode is controled by GPIO 2 */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW);
+ /* mark the failure */
+ bp->link_params.ext_phy_config &=
+ ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+ bp->link_params.ext_phy_config |=
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+ SHMEM_WR(bp,
+ dev_info.port_hw_config[port].
+ external_phy_config,
+ bp->link_params.ext_phy_config);
+ /* log the failure */
+ printk(KERN_ERR PFX "Fan Failure on Network"
+ " Controller %s has caused the driver to"
+ " shutdown the card to prevent permanent"
+ " damage. Please contact Dell Support for"
+ " assistance\n", bp->dev->name);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (attn & HW_INTERRUT_ASSERT_SET_0) {
+
+ val = REG_RD(bp, reg_offset);
+ val &= ~(attn & HW_INTERRUT_ASSERT_SET_0);
+ REG_WR(bp, reg_offset, val);
+
+ BNX2X_ERR("FATAL HW block attention set0 0x%x\n",
+ (attn & HW_INTERRUT_ASSERT_SET_0));
+ bnx2x_panic();
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & BNX2X_DOORQ_ASSERT) {
+
+ val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
+ BNX2X_ERR("DB hw attention 0x%x\n", val);
+ /* DORQ discard attention */
+ if (val & 0x2)
+ BNX2X_ERR("FATAL error from DORQ\n");
+ }
+
+ if (attn & HW_INTERRUT_ASSERT_SET_1) {
+
+ int port = BP_PORT(bp);
+ int reg_offset;
+
+ reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1 :
+ MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1);
+
+ val = REG_RD(bp, reg_offset);
+ val &= ~(attn & HW_INTERRUT_ASSERT_SET_1);
+ REG_WR(bp, reg_offset, val);
+
+ BNX2X_ERR("FATAL HW block attention set1 0x%x\n",
+ (attn & HW_INTERRUT_ASSERT_SET_1));
+ bnx2x_panic();
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
+
+ val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
+ BNX2X_ERR("CFC hw attention 0x%x\n", val);
+ /* CFC error attention */
+ if (val & 0x2)
+ BNX2X_ERR("FATAL error from CFC\n");
+ }
+
+ if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
+
+ val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
+ BNX2X_ERR("PXP hw attention 0x%x\n", val);
+ /* RQ_USDMDP_FIFO_OVERFLOW */
+ if (val & 0x18000)
+ BNX2X_ERR("FATAL error from PXP\n");
+ }
+
+ if (attn & HW_INTERRUT_ASSERT_SET_2) {
+
+ int port = BP_PORT(bp);
+ int reg_offset;
+
+ reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_2 :
+ MISC_REG_AEU_ENABLE1_FUNC_0_OUT_2);
+
+ val = REG_RD(bp, reg_offset);
+ val &= ~(attn & HW_INTERRUT_ASSERT_SET_2);
+ REG_WR(bp, reg_offset, val);
+
+ BNX2X_ERR("FATAL HW block attention set2 0x%x\n",
+ (attn & HW_INTERRUT_ASSERT_SET_2));
+ bnx2x_panic();
+ }
+}
+
+static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
+{
+ u32 val;
+
+ if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) {
+
+ if (attn & BNX2X_PMF_LINK_ASSERT) {
+ int func = BP_FUNC(bp);
+
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+ bnx2x__link_status_update(bp);
+ if (SHMEM_RD(bp, func_mb[func].drv_status) &
+ DRV_STATUS_PMF)
+ bnx2x_pmf_update(bp);
+
+ } else if (attn & BNX2X_MC_ASSERT_BITS) {
+
+ BNX2X_ERR("MC assert!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0);
+ bnx2x_panic();
+
+ } else if (attn & BNX2X_MCP_ASSERT) {
+
+ BNX2X_ERR("MCP assert!\n");
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0);
+ bnx2x_fw_dump(bp);
+
+ } else
+ BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn);
+ }
+
+ if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
+ BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn);
+ if (attn & BNX2X_GRC_TIMEOUT) {
+ val = CHIP_IS_E1H(bp) ?
+ REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0;
+ BNX2X_ERR("GRC time-out 0x%08x\n", val);
+ }
+ if (attn & BNX2X_GRC_RSV) {
+ val = CHIP_IS_E1H(bp) ?
+ REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0;
+ BNX2X_ERR("GRC reserved 0x%08x\n", val);
+ }
+ REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
+ }
+}
+
+static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+{
+ struct attn_route attn;
+ struct attn_route group_mask;
+ int port = BP_PORT(bp);
+ int index;
+ u32 reg_addr;
+ u32 val;
+
+ /* need to take HW lock because MCP or other port might also
+ try to handle this event */
+ bnx2x_lock_alr(bp);
+
+ attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4);
+ attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4);
+ attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4);
+ attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4);
+ DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n",
+ attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]);
+
+ for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
+ if (deasserted & (1 << index)) {
+ group_mask = bp->attn_group[index];
+
+ DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n",
+ index, group_mask.sig[0], group_mask.sig[1],
+ group_mask.sig[2], group_mask.sig[3]);
+
+ bnx2x_attn_int_deasserted3(bp,
+ attn.sig[3] & group_mask.sig[3]);
+ bnx2x_attn_int_deasserted1(bp,
+ attn.sig[1] & group_mask.sig[1]);
+ bnx2x_attn_int_deasserted2(bp,
+ attn.sig[2] & group_mask.sig[2]);
+ bnx2x_attn_int_deasserted0(bp,
+ attn.sig[0] & group_mask.sig[0]);
+
+ if ((attn.sig[0] & group_mask.sig[0] &
+ HW_PRTY_ASSERT_SET_0) ||
+ (attn.sig[1] & group_mask.sig[1] &
+ HW_PRTY_ASSERT_SET_1) ||
+ (attn.sig[2] & group_mask.sig[2] &
+ HW_PRTY_ASSERT_SET_2))
+ BNX2X_ERR("FATAL HW block parity attention\n");
+ }
+ }
+
+ bnx2x_unlock_alr(bp);
+
+ reg_addr = (IGU_ADDR_ATTN_BITS_CLR + IGU_FUNC_BASE * BP_FUNC(bp)) * 8;
+
+ val = ~deasserted;
+/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
+ val, BAR_IGU_INTMEM + reg_addr); */
+ REG_WR(bp, BAR_IGU_INTMEM + reg_addr, val);
+
+ if (bp->aeu_mask & (deasserted & 0xff))
+ BNX2X_ERR("IGU BUG!\n");
+ if (~bp->attn_state & deasserted)
+ BNX2X_ERR("IGU BUG!\n");
+
+ reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
+ MISC_REG_AEU_MASK_ATTN_FUNC_0;
+
+ DP(NETIF_MSG_HW, "aeu_mask %x\n", bp->aeu_mask);
+ bp->aeu_mask |= (deasserted & 0xff);
+
+ DP(NETIF_MSG_HW, "new mask %x\n", bp->aeu_mask);
+ REG_WR(bp, reg_addr, bp->aeu_mask);
+
+ DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
+ bp->attn_state &= ~deasserted;
+ DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state);
+}
+
+static void bnx2x_attn_int(struct bnx2x *bp)
+{
+ /* read local copy of bits */
+ u32 attn_bits = bp->def_status_blk->atten_status_block.attn_bits;
+ u32 attn_ack = bp->def_status_blk->atten_status_block.attn_bits_ack;
+ u32 attn_state = bp->attn_state;
+
+ /* look for changed bits */
+ u32 asserted = attn_bits & ~attn_ack & ~attn_state;
+ u32 deasserted = ~attn_bits & attn_ack & attn_state;
+
+ DP(NETIF_MSG_HW,
+ "attn_bits %x attn_ack %x asserted %x deasserted %x\n",
+ attn_bits, attn_ack, asserted, deasserted);
+
+ if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state))
+ BNX2X_ERR("BAD attention state\n");
+
+ /* handle bits that were raised */
+ if (asserted)
+ bnx2x_attn_int_asserted(bp, asserted);
+
+ if (deasserted)
+ bnx2x_attn_int_deasserted(bp, deasserted);
+}
+
+static void bnx2x_sp_task(struct work_struct *work)
+{
+ struct bnx2x *bp = container_of(work, struct bnx2x, sp_task);
+ u16 status;
+
+
+ /* Return here if interrupt is disabled */
+ if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+ DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
+ return;
+ }
+
+ status = bnx2x_update_dsb_idx(bp);
+/* if (status == 0) */
+/* BNX2X_ERR("spurious slowpath interrupt!\n"); */
+
+ DP(BNX2X_MSG_SP, "got a slowpath interrupt (updated %x)\n", status);
+
+ /* HW attentions */
+ if (status & 0x1)
+ bnx2x_attn_int(bp);
+
+ /* CStorm events: query_stats, port delete ramrod */
+ if (status & 0x2)
+ bp->stats_pending = 0;
+
+ bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx,
+ IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
+ IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx),
+ IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx),
+ IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
+ IGU_INT_ENABLE, 1);
+
+}
+
+static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
+{
+ struct net_device *dev = dev_instance;
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* Return here if interrupt is disabled */
+ if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+ DP(BNX2X_MSG_SP, "called but intr_sem not 0, returning\n");
+ return IRQ_HANDLED;
+ }
+
+ bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return IRQ_HANDLED;
+#endif
+
+ schedule_work(&bp->sp_task);
+
+ return IRQ_HANDLED;
+}
+
+/* end of slow path */
+
+/* Statistics */
+
+/****************************************************************************
+* Macros
+****************************************************************************/
+
+/* sum[hi:lo] += add[hi:lo] */
+#define ADD_64(s_hi, a_hi, s_lo, a_lo) \
+ do { \
+ s_lo += a_lo; \
+ s_hi += a_hi + (s_lo < a_lo) ? 1 : 0; \
+ } while (0)
+
+/* difference = minuend - subtrahend */
+#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
+ do { \
+ if (m_lo < s_lo) { \
+ /* underflow */ \
+ d_hi = m_hi - s_hi; \
+ if (d_hi > 0) { \
+ /* we can 'loan' 1 */ \
+ d_hi--; \
+ d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
+ } else { \
+ /* m_hi <= s_hi */ \
+ d_hi = 0; \
+ d_lo = 0; \
+ } \
+ } else { \
+ /* m_lo >= s_lo */ \
+ if (m_hi < s_hi) { \
+ d_hi = 0; \
+ d_lo = 0; \
+ } else { \
+ /* m_hi >= s_hi */ \
+ d_hi = m_hi - s_hi; \
+ d_lo = m_lo - s_lo; \
+ } \
+ } \
+ } while (0)
+
+#define UPDATE_STAT64(s, t) \
+ do { \
+ DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \
+ diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \
+ pstats->mac_stx[0].t##_hi = new->s##_hi; \
+ pstats->mac_stx[0].t##_lo = new->s##_lo; \
+ ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \
+ pstats->mac_stx[1].t##_lo, diff.lo); \
+ } while (0)
+
+#define UPDATE_STAT64_NIG(s, t) \
+ do { \
+ DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \
+ diff.lo, new->s##_lo, old->s##_lo); \
+ ADD_64(estats->t##_hi, diff.hi, \
+ estats->t##_lo, diff.lo); \
+ } while (0)
+
+/* sum[hi:lo] += add */
+#define ADD_EXTEND_64(s_hi, s_lo, a) \
+ do { \
+ s_lo += a; \
+ s_hi += (s_lo < a) ? 1 : 0; \
+ } while (0)
+
+#define UPDATE_EXTEND_STAT(s) \
+ do { \
+ ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \
+ pstats->mac_stx[1].s##_lo, \
+ new->s); \
+ } while (0)
+
+#define UPDATE_EXTEND_TSTAT(s, t) \
+ do { \
+ diff = le32_to_cpu(tclient->s) - old_tclient->s; \
+ old_tclient->s = le32_to_cpu(tclient->s); \
+ ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+ } while (0)
+
+#define UPDATE_EXTEND_XSTAT(s, t) \
+ do { \
+ diff = le32_to_cpu(xclient->s) - old_xclient->s; \
+ old_xclient->s = le32_to_cpu(xclient->s); \
+ ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+ } while (0)
+
+/*
+ * General service functions
+ */
+
+static inline long bnx2x_hilo(u32 *hiref)
+{
+ u32 lo = *(hiref + 1);
+#if (BITS_PER_LONG == 64)
+ u32 hi = *hiref;
+
+ return HILO_U64(hi, lo);
+#else
+ return lo;
+#endif
+}
+
+/*
+ * Init service functions
+ */
+
+static void bnx2x_storm_stats_init(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), 1);
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
+
+ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), 1);
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
+
+ REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), 0);
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_STATS_FLAGS_OFFSET(func) + 4, 0);
+
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
+ U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
+ U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
+ U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
+ U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+}
+
+static void bnx2x_storm_stats_post(struct bnx2x *bp)
+{
+ if (!bp->stats_pending) {
+ struct eth_query_ramrod_data ramrod_data = {0};
+ int rc;
+
+ ramrod_data.drv_counter = bp->stats_counter++;
+ ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
+ ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
+
+ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
+ ((u32 *)&ramrod_data)[1],
+ ((u32 *)&ramrod_data)[0], 0);
+ if (rc == 0) {
+ /* stats ramrod has it's own slot on the spq */
+ bp->spq_left++;
+ bp->stats_pending = 1;
+ }
+ }
+}
+
+static void bnx2x_stats_init(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+
+ bp->executer_idx = 0;
+ bp->stats_counter = 0;
+
+ /* port stats */
+ if (!BP_NOMCP(bp))
+ bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
+ else
+ bp->port.port_stx = 0;
+ DP(BNX2X_MSG_STATS, "port_stx 0x%x\n", bp->port.port_stx);
+
+ memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
+ bp->port.old_nig_stats.brb_discard =
+ REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
+ REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
+ &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
+ REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
+ &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
+
+ /* function stats */
+ memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
+ memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
+ memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
+ memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
+
+ bp->stats_state = STATS_STATE_DISABLED;
+ if (IS_E1HMF(bp) && bp->port.pmf && bp->port.port_stx)
+ bnx2x_stats_handle(bp, STATS_EVENT_PMF);
+}
+
+static void bnx2x_hw_stats_post(struct bnx2x *bp)
+{
+ struct dmae_command *dmae = &bp->stats_dmae;
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+ *stats_comp = DMAE_COMP_VAL;
+
+ /* loader */
+ if (bp->executer_idx) {
+ int loader_idx = PMF_DMAE_C(bp);
+
+ memset(dmae, 0, sizeof(struct dmae_command));
+
+ dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+ DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 :
+ DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
+ dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
+ dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
+ sizeof(struct dmae_command) *
+ (loader_idx + 1)) >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = sizeof(struct dmae_command) >> 2;
+ if (CHIP_IS_E1(bp))
+ dmae->len--;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ *stats_comp = 0;
+ bnx2x_post_dmae(bp, dmae, loader_idx);
+
+ } else if (bp->func_stx) {
+ *stats_comp = 0;
+ bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+ }
+}
+
+static int bnx2x_stats_comp(struct bnx2x *bp)
+{
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+ int cnt = 10;
+
+ might_sleep();
+ while (*stats_comp != DMAE_COMP_VAL) {
+ msleep(1);
+ if (!cnt) {
+ BNX2X_ERR("timeout waiting for stats finished\n");
+ break;
+ }
+ cnt--;
+ }
+ return 1;
+}
+
+/*
+ * Statistics service functions
+ */
+
+static void bnx2x_stats_pmf_update(struct bnx2x *bp)
+{
+ struct dmae_command *dmae;
+ u32 opcode;
+ int loader_idx = PMF_DMAE_C(bp);
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+ /* sanity */
+ if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) {
+ BNX2X_ERR("BUG!\n");
+ return;
+ }
+
+ bp->executer_idx = 0;
+
+ opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+ DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
+ dmae->src_addr_lo = bp->port.port_stx >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
+ dmae->len = DMAE_LEN32_RD_MAX;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
+ dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) +
+ DMAE_LEN32_RD_MAX * 4);
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) +
+ DMAE_LEN32_RD_MAX * 4);
+ dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX;
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ *stats_comp = 0;
+ bnx2x_hw_stats_post(bp);
+ bnx2x_stats_comp(bp);
+}
+
+static void bnx2x_port_stats_init(struct bnx2x *bp)
+{
+ struct dmae_command *dmae;
+ int port = BP_PORT(bp);
+ int vn = BP_E1HVN(bp);
+ u32 opcode;
+ int loader_idx = PMF_DMAE_C(bp);
+ u32 mac_addr;
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+ /* sanity */
+ if (!bp->link_vars.link_up || !bp->port.pmf) {
+ BNX2X_ERR("BUG!\n");
+ return;
+ }
+
+ bp->executer_idx = 0;
+
+ /* MCP */
+ opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+ DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (vn << DMAE_CMD_E1HVN_SHIFT));
+
+ if (bp->port.port_stx) {
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
+ dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
+ dmae->dst_addr_lo = bp->port.port_stx >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = sizeof(struct host_port_stats) >> 2;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+ }
+
+ if (bp->func_stx) {
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
+ dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
+ dmae->dst_addr_lo = bp->func_stx >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = sizeof(struct host_func_stats) >> 2;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+ }
+
+ /* MAC */
+ opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+ DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (vn << DMAE_CMD_E1HVN_SHIFT));
+
+ if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
+
+ mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM :
+ NIG_REG_INGRESS_BMAC0_MEM);
+
+ /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
+ BIGMAC_REGISTER_TX_STAT_GTBYT */
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (mac_addr +
+ BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
+ dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
+ BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ /* BIGMAC_REGISTER_RX_STAT_GR64 ..
+ BIGMAC_REGISTER_RX_STAT_GRIPJ */
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (mac_addr +
+ BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct bmac_stats, rx_stat_gr64_lo));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct bmac_stats, rx_stat_gr64_lo));
+ dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
+ BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) {
+
+ mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
+
+ /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (mac_addr +
+ EMAC_REG_EMAC_RX_STAT_AC) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
+ dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ /* EMAC_REG_EMAC_RX_STAT_AC_28 */
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (mac_addr +
+ EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct emac_stats, rx_stat_falsecarriererrors));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct emac_stats, rx_stat_falsecarriererrors));
+ dmae->len = 1;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (mac_addr +
+ EMAC_REG_EMAC_TX_STAT_AC) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+ offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
+ dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+ }
+
+ /* NIG */
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
+ NIG_REG_STAT0_BRB_DISCARD) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats));
+ dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = opcode;
+ dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
+ NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
+ offsetof(struct nig_stats, egress_mac_pkt0_lo));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
+ offsetof(struct nig_stats, egress_mac_pkt0_lo));
+ dmae->len = (2*sizeof(u32)) >> 2;
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+ DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (vn << DMAE_CMD_E1HVN_SHIFT));
+ dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
+ NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
+ dmae->src_addr_hi = 0;
+ dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
+ offsetof(struct nig_stats, egress_mac_pkt1_lo));
+ dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
+ offsetof(struct nig_stats, egress_mac_pkt1_lo));
+ dmae->len = (2*sizeof(u32)) >> 2;
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ *stats_comp = 0;
+}
+
+static void bnx2x_func_stats_init(struct bnx2x *bp)
+{
+ struct dmae_command *dmae = &bp->stats_dmae;
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+ /* sanity */
+ if (!bp->func_stx) {
+ BNX2X_ERR("BUG!\n");
+ return;
+ }
+
+ bp->executer_idx = 0;
+ memset(dmae, 0, sizeof(struct dmae_command));
+
+ dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+ DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+ dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
+ dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
+ dmae->dst_addr_lo = bp->func_stx >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = sizeof(struct host_func_stats) >> 2;
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ *stats_comp = 0;
+}
+
+static void bnx2x_stats_start(struct bnx2x *bp)
+{
+ if (bp->port.pmf)
+ bnx2x_port_stats_init(bp);
+
+ else if (bp->func_stx)
+ bnx2x_func_stats_init(bp);
+
+ bnx2x_hw_stats_post(bp);
+ bnx2x_storm_stats_post(bp);
+}
+
+static void bnx2x_stats_pmf_start(struct bnx2x *bp)
+{
+ bnx2x_stats_comp(bp);
+ bnx2x_stats_pmf_update(bp);
+ bnx2x_stats_start(bp);
+}
+
+static void bnx2x_stats_restart(struct bnx2x *bp)
+{
+ bnx2x_stats_comp(bp);
+ bnx2x_stats_start(bp);
+}
+
+static void bnx2x_bmac_stats_update(struct bnx2x *bp)
+{
+ struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
+ struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
+ struct regpair diff;
+
+ UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
+ UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
+ UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
+ UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
+ UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
+ UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
+ UPDATE_STAT64(rx_stat_grxcf, rx_stat_bmac_xcf);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
+ UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
+ UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
+ UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
+ UPDATE_STAT64(tx_stat_gt127,
+ tx_stat_etherstatspkts65octetsto127octets);
+ UPDATE_STAT64(tx_stat_gt255,
+ tx_stat_etherstatspkts128octetsto255octets);
+ UPDATE_STAT64(tx_stat_gt511,
+ tx_stat_etherstatspkts256octetsto511octets);
+ UPDATE_STAT64(tx_stat_gt1023,
+ tx_stat_etherstatspkts512octetsto1023octets);
+ UPDATE_STAT64(tx_stat_gt1518,
+ tx_stat_etherstatspkts1024octetsto1522octets);
+ UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
+ UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
+ UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
+ UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
+ UPDATE_STAT64(tx_stat_gterr,
+ tx_stat_dot3statsinternalmactransmiterrors);
+ UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+}
+
+static void bnx2x_emac_stats_update(struct bnx2x *bp)
+{
+ struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
+ struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
+
+ UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
+ UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
+ UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
+ UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
+ UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
+ UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
+ UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
+ UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
+ UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
+ UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
+ UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
+ UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
+ UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
+ UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
+ UPDATE_EXTEND_STAT(tx_stat_outxonsent);
+ UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
+ UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
+ UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
+ UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
+ UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
+ UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
+ UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
+ UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
+ UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
+}
+
+static int bnx2x_hw_stats_update(struct bnx2x *bp)
+{
+ struct nig_stats *new = bnx2x_sp(bp, nig_stats);
+ struct nig_stats *old = &(bp->port.old_nig_stats);
+ struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ struct regpair diff;
+
+ if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
+ bnx2x_bmac_stats_update(bp);
+
+ else if (bp->link_vars.mac_type == MAC_TYPE_EMAC)
+ bnx2x_emac_stats_update(bp);
+
+ else { /* unreached */
+ BNX2X_ERR("stats updated by dmae but no MAC active\n");
+ return -1;
+ }
+
+ ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
+ new->brb_discard - old->brb_discard);
+
+ UPDATE_STAT64_NIG(egress_mac_pkt0,
+ etherstatspkts1024octetsto1522octets);
+ UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets);
+
+ memcpy(old, new, sizeof(struct nig_stats));
+
+ memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
+ sizeof(struct mac_stx));
+ estats->brb_drop_hi = pstats->brb_drop_hi;
+ estats->brb_drop_lo = pstats->brb_drop_lo;
+
+ pstats->host_port_stats_start = ++pstats->host_port_stats_end;
+
+ return 0;
+}
+
+static int bnx2x_storm_stats_update(struct bnx2x *bp)
+{
+ struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
+ int cl_id = BP_CL_ID(bp);
+ struct tstorm_per_port_stats *tport =
+ &stats->tstorm_common.port_statistics;
+ struct tstorm_per_client_stats *tclient =
+ &stats->tstorm_common.client_statistics[cl_id];
+ struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+ struct xstorm_per_client_stats *xclient =
+ &stats->xstorm_common.client_statistics[cl_id];
+ struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
+ struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ u32 diff;
+
+ /* are storm stats valid? */
+ if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
+ bp->stats_counter) {
+ DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
+ " tstorm counter (%d) != stats_counter (%d)\n",
+ tclient->stats_counter, bp->stats_counter);
+ return -1;
+ }
+ if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
+ bp->stats_counter) {
+ DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
+ " xstorm counter (%d) != stats_counter (%d)\n",
+ xclient->stats_counter, bp->stats_counter);
+ return -2;
+ }
+
+ fstats->total_bytes_received_hi =
+ fstats->valid_bytes_received_hi =
+ le32_to_cpu(tclient->total_rcv_bytes.hi);
+ fstats->total_bytes_received_lo =
+ fstats->valid_bytes_received_lo =
+ le32_to_cpu(tclient->total_rcv_bytes.lo);
+
+ estats->error_bytes_received_hi =
+ le32_to_cpu(tclient->rcv_error_bytes.hi);
+ estats->error_bytes_received_lo =
+ le32_to_cpu(tclient->rcv_error_bytes.lo);
+ ADD_64(estats->error_bytes_received_hi,
+ estats->rx_stat_ifhcinbadoctets_hi,
+ estats->error_bytes_received_lo,
+ estats->rx_stat_ifhcinbadoctets_lo);
+
+ ADD_64(fstats->total_bytes_received_hi,
+ estats->error_bytes_received_hi,
+ fstats->total_bytes_received_lo,
+ estats->error_bytes_received_lo);
+
+ UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
+ UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
+ total_multicast_packets_received);
+ UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
+ total_broadcast_packets_received);
+
+ fstats->total_bytes_transmitted_hi =
+ le32_to_cpu(xclient->total_sent_bytes.hi);
+ fstats->total_bytes_transmitted_lo =
+ le32_to_cpu(xclient->total_sent_bytes.lo);
+
+ UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
+ total_unicast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
+ total_multicast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
+ total_broadcast_packets_transmitted);
+
+ memcpy(estats, &(fstats->total_bytes_received_hi),
+ sizeof(struct host_func_stats) - 2*sizeof(u32));
+
+ estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
+ estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
+ estats->brb_truncate_discard =
+ le32_to_cpu(tport->brb_truncate_discard);
+ estats->mac_discard = le32_to_cpu(tport->mac_discard);
+
+ old_tclient->rcv_unicast_bytes.hi =
+ le32_to_cpu(tclient->rcv_unicast_bytes.hi);
+ old_tclient->rcv_unicast_bytes.lo =
+ le32_to_cpu(tclient->rcv_unicast_bytes.lo);
+ old_tclient->rcv_broadcast_bytes.hi =
+ le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
+ old_tclient->rcv_broadcast_bytes.lo =
+ le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
+ old_tclient->rcv_multicast_bytes.hi =
+ le32_to_cpu(tclient->rcv_multicast_bytes.hi);
+ old_tclient->rcv_multicast_bytes.lo =
+ le32_to_cpu(tclient->rcv_multicast_bytes.lo);
+ old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
+
+ old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
+ old_tclient->packets_too_big_discard =
+ le32_to_cpu(tclient->packets_too_big_discard);
+ estats->no_buff_discard =
+ old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
+ old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
+
+ old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
+ old_xclient->unicast_bytes_sent.hi =
+ le32_to_cpu(xclient->unicast_bytes_sent.hi);
+ old_xclient->unicast_bytes_sent.lo =
+ le32_to_cpu(xclient->unicast_bytes_sent.lo);
+ old_xclient->multicast_bytes_sent.hi =
+ le32_to_cpu(xclient->multicast_bytes_sent.hi);
+ old_xclient->multicast_bytes_sent.lo =
+ le32_to_cpu(xclient->multicast_bytes_sent.lo);
+ old_xclient->broadcast_bytes_sent.hi =
+ le32_to_cpu(xclient->broadcast_bytes_sent.hi);
+ old_xclient->broadcast_bytes_sent.lo =
+ le32_to_cpu(xclient->broadcast_bytes_sent.lo);
+
+ fstats->host_func_stats_start = ++fstats->host_func_stats_end;
+
+ return 0;
+}
+
+static void bnx2x_net_stats_update(struct bnx2x *bp)
+{
+ struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ struct net_device_stats *nstats = &bp->dev->stats;
+
+ nstats->rx_packets =
+ bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
+ bnx2x_hilo(&estats->total_multicast_packets_received_hi) +
+ bnx2x_hilo(&estats->total_broadcast_packets_received_hi);
+
+ nstats->tx_packets =
+ bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) +
+ bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
+ bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
+
+ nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
+
+ nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
+
+ nstats->rx_dropped = old_tclient->checksum_discard +
+ estats->mac_discard;
+ nstats->tx_dropped = 0;
+
+ nstats->multicast =
+ bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
+
+ nstats->collisions =
+ estats->tx_stat_dot3statssinglecollisionframes_lo +
+ estats->tx_stat_dot3statsmultiplecollisionframes_lo +
+ estats->tx_stat_dot3statslatecollisions_lo +
+ estats->tx_stat_dot3statsexcessivecollisions_lo;
+
+ estats->jabber_packets_received =
+ old_tclient->packets_too_big_discard +
+ estats->rx_stat_dot3statsframestoolong_lo;
+
+ nstats->rx_length_errors =
+ estats->rx_stat_etherstatsundersizepkts_lo +
+ estats->jabber_packets_received;
+ nstats->rx_over_errors = estats->brb_drop_lo +
+ estats->brb_truncate_discard;
+ nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
+ nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
+ nstats->rx_fifo_errors = old_tclient->no_buff_discard;
+ nstats->rx_missed_errors = estats->xxoverflow_discard;
+
+ nstats->rx_errors = nstats->rx_length_errors +
+ nstats->rx_over_errors +
+ nstats->rx_crc_errors +
+ nstats->rx_frame_errors +
+ nstats->rx_fifo_errors +
+ nstats->rx_missed_errors;
+
+ nstats->tx_aborted_errors =
+ estats->tx_stat_dot3statslatecollisions_lo +
+ estats->tx_stat_dot3statsexcessivecollisions_lo;
+ nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
+ nstats->tx_fifo_errors = 0;
+ nstats->tx_heartbeat_errors = 0;
+ nstats->tx_window_errors = 0;
+
+ nstats->tx_errors = nstats->tx_aborted_errors +
+ nstats->tx_carrier_errors;
+}
+
+static void bnx2x_stats_update(struct bnx2x *bp)
+{
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+ int update = 0;
+
+ if (*stats_comp != DMAE_COMP_VAL)
+ return;
+
+ if (bp->port.pmf)
+ update = (bnx2x_hw_stats_update(bp) == 0);
+
+ update |= (bnx2x_storm_stats_update(bp) == 0);
+
+ if (update)
+ bnx2x_net_stats_update(bp);
+
+ else {
+ if (bp->stats_pending) {
+ bp->stats_pending++;
+ if (bp->stats_pending == 3) {
+ BNX2X_ERR("stats not updated for 3 times\n");
+ bnx2x_panic();
+ return;
+ }
+ }
+ }
+
+ if (bp->msglevel & NETIF_MSG_TIMER) {
+ struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ struct net_device_stats *nstats = &bp->dev->stats;
+ int i;
+
+ printk(KERN_DEBUG "%s:\n", bp->dev->name);
+ printk(KERN_DEBUG " tx avail (%4x) tx hc idx (%x)"
+ " tx pkt (%lx)\n",
+ bnx2x_tx_avail(bp->fp),
+ le16_to_cpu(*bp->fp->tx_cons_sb), nstats->tx_packets);
+ printk(KERN_DEBUG " rx usage (%4x) rx hc idx (%x)"
+ " rx pkt (%lx)\n",
+ (u16)(le16_to_cpu(*bp->fp->rx_cons_sb) -
+ bp->fp->rx_comp_cons),
+ le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
+ printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
+ netif_queue_stopped(bp->dev)? "Xoff" : "Xon",
+ estats->driver_xoff, estats->brb_drop_lo);
+ printk(KERN_DEBUG "tstats: checksum_discard %u "
+ "packets_too_big_discard %u no_buff_discard %u "
+ "mac_discard %u mac_filter_discard %u "
+ "xxovrflow_discard %u brb_truncate_discard %u "
+ "ttl0_discard %u\n",
+ old_tclient->checksum_discard,
+ old_tclient->packets_too_big_discard,
+ old_tclient->no_buff_discard, estats->mac_discard,
+ estats->mac_filter_discard, estats->xxoverflow_discard,
+ estats->brb_truncate_discard,
+ old_tclient->ttl0_discard);
+
+ for_each_queue(bp, i) {
+ printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
+ bnx2x_fp(bp, i, tx_pkt),
+ bnx2x_fp(bp, i, rx_pkt),
+ bnx2x_fp(bp, i, rx_calls));
+ }
+ }
+
+ bnx2x_hw_stats_post(bp);
+ bnx2x_storm_stats_post(bp);
+}
+
+static void bnx2x_port_stats_stop(struct bnx2x *bp)
+{
+ struct dmae_command *dmae;
+ u32 opcode;
+ int loader_idx = PMF_DMAE_C(bp);
+ u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+ bp->executer_idx = 0;
+
+ opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+ DMAE_CMD_C_ENABLE |
+ DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+ DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+ DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+ (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+ (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+
+ if (bp->port.port_stx) {
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ if (bp->func_stx)
+ dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
+ else
+ dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
+ dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
+ dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
+ dmae->dst_addr_lo = bp->port.port_stx >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = sizeof(struct host_port_stats) >> 2;
+ if (bp->func_stx) {
+ dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+ dmae->comp_addr_hi = 0;
+ dmae->comp_val = 1;
+ } else {
+ dmae->comp_addr_lo =
+ U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_addr_hi =
+ U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ *stats_comp = 0;
+ }
+ }
+
+ if (bp->func_stx) {
+
+ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+ dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
+ dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
+ dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
+ dmae->dst_addr_lo = bp->func_stx >> 2;
+ dmae->dst_addr_hi = 0;
+ dmae->len = sizeof(struct host_func_stats) >> 2;
+ dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+ dmae->comp_val = DMAE_COMP_VAL;
+
+ *stats_comp = 0;
+ }
+}
+
+static void bnx2x_stats_stop(struct bnx2x *bp)
+{
+ int update = 0;
+
+ bnx2x_stats_comp(bp);
+
+ if (bp->port.pmf)
+ update = (bnx2x_hw_stats_update(bp) == 0);
+
+ update |= (bnx2x_storm_stats_update(bp) == 0);
+
+ if (update) {
+ bnx2x_net_stats_update(bp);
+
+ if (bp->port.pmf)
+ bnx2x_port_stats_stop(bp);
+
+ bnx2x_hw_stats_post(bp);
+ bnx2x_stats_comp(bp);
+ }
+}
+
+static void bnx2x_stats_do_nothing(struct bnx2x *bp)
+{
+}
+
+static const struct {
+ void (*action)(struct bnx2x *bp);
+ enum bnx2x_stats_state next_state;
+} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
+/* state event */
+{
+/* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED},
+/* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED},
+/* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED},
+/* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}
+},
+{
+/* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED},
+/* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED},
+/* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED},
+/* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED}
+}
+};
+
+static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
+{
+ enum bnx2x_stats_state state = bp->stats_state;
+
+ bnx2x_stats_stm[state][event].action(bp);
+ bp->stats_state = bnx2x_stats_stm[state][event].next_state;
+
+ if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
+ DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
+ state, event, bp->stats_state);
+}
+
+static void bnx2x_timer(unsigned long data)
+{
+ struct bnx2x *bp = (struct bnx2x *) data;
+
+ if (!netif_running(bp->dev))
+ return;
+
+ if (atomic_read(&bp->intr_sem) != 0)
+ goto timer_restart;
+
+ if (poll) {
+ struct bnx2x_fastpath *fp = &bp->fp[0];
+ int rc;
+
+ bnx2x_tx_int(fp, 1000);
+ rc = bnx2x_rx_int(fp, 1000);
+ }
+
+ if (!BP_NOMCP(bp)) {
+ int func = BP_FUNC(bp);
+ u32 drv_pulse;
+ u32 mcp_pulse;
+
+ ++bp->fw_drv_pulse_wr_seq;
+ bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
+ /* TBD - add SYSTEM_TIME */
+ drv_pulse = bp->fw_drv_pulse_wr_seq;
+ SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse);
+
+ mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) &
+ MCP_PULSE_SEQ_MASK);
+ /* The delta between driver pulse and mcp response
+ * should be 1 (before mcp response) or 0 (after mcp response)
+ */
+ if ((drv_pulse != mcp_pulse) &&
+ (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) {
+ /* someone lost a heartbeat... */
+ BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n",
+ drv_pulse, mcp_pulse);
+ }
+ }
+
+ if ((bp->state == BNX2X_STATE_OPEN) ||
+ (bp->state == BNX2X_STATE_DISABLED))
+ bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
+
+timer_restart:
+ mod_timer(&bp->timer, jiffies + bp->current_interval);
+}
+
+/* end of Statistics */
+
+/* nic init */
+
+/*
+ * nic init service functions
+ */
+
+static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id)
+{
+ int port = BP_PORT(bp);
+
+ bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
+ USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
+ sizeof(struct ustorm_def_status_block)/4);
+ bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
+ sizeof(struct cstorm_def_status_block)/4);
+}
+
+static void bnx2x_init_sb(struct bnx2x *bp, int sb_id,
+ struct host_status_block *sb, dma_addr_t mapping)
+{
+ int port = BP_PORT(bp);
+ int func = BP_FUNC(bp);
+ int index;
+ u64 section;
+
+ /* USTORM */
+ section = ((u64)mapping) + offsetof(struct host_status_block,
+ u_status_block);
+ sb->u_status_block.status_block_id = sb_id;
+
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id), U64_LO(section));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
+ U64_HI(section));
+ REG_WR8(bp, BAR_USTRORM_INTMEM + FP_USB_FUNC_OFF +
+ USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
+
+ for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
+ REG_WR16(bp, BAR_USTRORM_INTMEM +
+ USTORM_SB_HC_DISABLE_OFFSET(port, sb_id, index), 1);
+
+ /* CSTORM */
+ section = ((u64)mapping) + offsetof(struct host_status_block,
+ c_status_block);
+ sb->c_status_block.status_block_id = sb_id;
+
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id), U64_LO(section));
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ ((CSTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
+ U64_HI(section));
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF +
+ CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
+
+ for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++)
+ REG_WR16(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id, index), 1);
+
+ bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+}
+
+static void bnx2x_zero_def_sb(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+
+ bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
+ USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
+ sizeof(struct ustorm_def_status_block)/4);
+ bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
+ sizeof(struct cstorm_def_status_block)/4);
+ bnx2x_init_fill(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
+ sizeof(struct xstorm_def_status_block)/4);
+ bnx2x_init_fill(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
+ sizeof(struct tstorm_def_status_block)/4);
+}
+
+static void bnx2x_init_def_sb(struct bnx2x *bp,
+ struct host_def_status_block *def_sb,
+ dma_addr_t mapping, int sb_id)
+{
+ int port = BP_PORT(bp);
+ int func = BP_FUNC(bp);
+ int index, val, reg_offset;
+ u64 section;
+
+ /* ATTN */
+ section = ((u64)mapping) + offsetof(struct host_def_status_block,
+ atten_status_block);
+ def_sb->atten_status_block.status_block_id = sb_id;
+
+ bp->def_att_idx = 0;
+ bp->attn_state = 0;
+
+ reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+ MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+
+ for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
+ bp->attn_group[index].sig[0] = REG_RD(bp,
+ reg_offset + 0x10*index);
+ bp->attn_group[index].sig[1] = REG_RD(bp,
+ reg_offset + 0x4 + 0x10*index);
+ bp->attn_group[index].sig[2] = REG_RD(bp,
+ reg_offset + 0x8 + 0x10*index);
+ bp->attn_group[index].sig[3] = REG_RD(bp,
+ reg_offset + 0xc + 0x10*index);
+ }
+
+ bp->aeu_mask = REG_RD(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
+ MISC_REG_AEU_MASK_ATTN_FUNC_0));
+
+ reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
+ HC_REG_ATTN_MSG0_ADDR_L);
+
+ REG_WR(bp, reg_offset, U64_LO(section));
+ REG_WR(bp, reg_offset + 4, U64_HI(section));
+
+ reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0);
+
+ val = REG_RD(bp, reg_offset);
+ val |= sb_id;
+ REG_WR(bp, reg_offset, val);
+
+ /* USTORM */
+ section = ((u64)mapping) + offsetof(struct host_def_status_block,
+ u_def_status_block);
+ def_sb->u_def_status_block.status_block_id = sb_id;
+
+ bp->def_u_idx = 0;
+
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
+ U64_HI(section));
+ REG_WR8(bp, BAR_USTRORM_INTMEM + DEF_USB_FUNC_OFF +
+ USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
+ REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(func),
+ BNX2X_BTR);
+
+ for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
+ REG_WR16(bp, BAR_USTRORM_INTMEM +
+ USTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+
+ /* CSTORM */
+ section = ((u64)mapping) + offsetof(struct host_def_status_block,
+ c_def_status_block);
+ def_sb->c_def_status_block.status_block_id = sb_id;
+
+ bp->def_c_idx = 0;
+
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
+ REG_WR(bp, BAR_CSTRORM_INTMEM +
+ ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
+ U64_HI(section));
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF +
+ CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
+ REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(func),
+ BNX2X_BTR);
+
+ for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
+ REG_WR16(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+
+ /* TSTORM */
+ section = ((u64)mapping) + offsetof(struct host_def_status_block,
+ t_def_status_block);
+ def_sb->t_def_status_block.status_block_id = sb_id;
+
+ bp->def_t_idx = 0;
+
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
+ U64_HI(section));
+ REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF +
+ TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
+ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(func),
+ BNX2X_BTR);
+
+ for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++)
+ REG_WR16(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+
+ /* XSTORM */
+ section = ((u64)mapping) + offsetof(struct host_def_status_block,
+ x_def_status_block);
+ def_sb->x_def_status_block.status_block_id = sb_id;
+
+ bp->def_x_idx = 0;
+
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
+ U64_HI(section));
+ REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF +
+ XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(func),
+ BNX2X_BTR);
+
+ for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++)
+ REG_WR16(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+
+ bp->stats_pending = 0;
+
+ bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+}
+
+static void bnx2x_update_coalesce(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int i;
+
+ for_each_queue(bp, i) {
+ int sb_id = bp->fp[i].sb_id;
+
+ /* HC_INDEX_U_ETH_RX_CQ_CONS */
+ REG_WR8(bp, BAR_USTRORM_INTMEM +
+ USTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
+ HC_INDEX_U_ETH_RX_CQ_CONS),
+ bp->rx_ticks/12);
+ REG_WR16(bp, BAR_USTRORM_INTMEM +
+ USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
+ HC_INDEX_U_ETH_RX_CQ_CONS),
+ bp->rx_ticks ? 0 : 1);
+
+ /* HC_INDEX_C_ETH_TX_CQ_CONS */
+ REG_WR8(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
+ HC_INDEX_C_ETH_TX_CQ_CONS),
+ bp->tx_ticks/12);
+ REG_WR16(bp, BAR_CSTRORM_INTMEM +
+ CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
+ HC_INDEX_C_ETH_TX_CQ_CONS),
+ bp->tx_ticks ? 0 : 1);
+ }
+}
+
+static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, int last)
+{
+ int i;
+
+ for (i = 0; i < last; i++) {
+ struct sw_rx_bd *rx_buf = &(fp->tpa_pool[i]);
+ struct sk_buff *skb = rx_buf->skb;
+
+ if (skb == NULL) {
+ DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i);
+ continue;
+ }
+
+ if (fp->tpa_state[i] == BNX2X_TPA_START)
+ pci_unmap_single(bp->pdev,
+ pci_unmap_addr(rx_buf, mapping),
+ bp->rx_buf_use_size,
+ PCI_DMA_FROMDEVICE);
+
+ dev_kfree_skb(skb);
+ rx_buf->skb = NULL;
+ }
+}
+
+static void bnx2x_init_rx_rings(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+ u16 ring_prod, cqe_ring_prod = 0;
+ int i, j;
+
+ bp->rx_buf_use_size = bp->dev->mtu;
+ bp->rx_buf_use_size += bp->rx_offset + ETH_OVREHEAD;
+ bp->rx_buf_size = bp->rx_buf_use_size + 64;
+
+ if (bp->flags & TPA_ENABLE_FLAG) {
+ DP(NETIF_MSG_IFUP,
+ "rx_buf_use_size %d rx_buf_size %d effective_mtu %d\n",
+ bp->rx_buf_use_size, bp->rx_buf_size,
+ bp->dev->mtu + ETH_OVREHEAD);
+
+ for_each_queue(bp, j) {
+ for (i = 0; i < ETH_MAX_AGGREGATION_QUEUES_E1H; i++) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ fp->tpa_pool[i].skb =
+ netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ if (!fp->tpa_pool[i].skb) {
+ BNX2X_ERR("Failed to allocate TPA "
+ "skb pool for queue[%d] - "
+ "disabling TPA on this "
+ "queue!\n", j);
+ bnx2x_free_tpa_pool(bp, fp, i);
+ fp->disable_tpa = 1;
+ break;
+ }
+ pci_unmap_addr_set((struct sw_rx_bd *)
+ &bp->fp->tpa_pool[i],
+ mapping, 0);
+ fp->tpa_state[i] = BNX2X_TPA_STOP;
+ }
+ }
+ }
+
+ for_each_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ fp->rx_bd_cons = 0;
+ fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
+ fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX;
+
+ /* "next page" elements initialization */
+ /* SGE ring */
+ for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
+ struct eth_rx_sge *sge;
+
+ sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2];
+ sge->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_sge_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
+ sge->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_sge_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
+ }
+
+ bnx2x_init_sge_ring_bit_mask(fp);
+
+ /* RX BD ring */
+ for (i = 1; i <= NUM_RX_RINGS; i++) {
+ struct eth_rx_bd *rx_bd;
+
+ rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
+ rx_bd->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+ rx_bd->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+ }
+
+ /* CQ ring */
+ for (i = 1; i <= NUM_RCQ_RINGS; i++) {
+ struct eth_rx_cqe_next_page *nextpg;
+
+ nextpg = (struct eth_rx_cqe_next_page *)
+ &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
+ nextpg->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_comp_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+ nextpg->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_comp_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+ }
+
+ /* Allocate SGEs and initialize the ring elements */
+ for (i = 0, ring_prod = 0;
+ i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) {
+
+ if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) {
+ BNX2X_ERR("was only able to allocate "
+ "%d rx sges\n", i);
+ BNX2X_ERR("disabling TPA for queue[%d]\n", j);
+ /* Cleanup already allocated elements */
+ bnx2x_free_rx_sge_range(bp, fp, ring_prod);
+ bnx2x_free_tpa_pool(bp, fp,
+ ETH_MAX_AGGREGATION_QUEUES_E1H);
+ fp->disable_tpa = 1;
+ ring_prod = 0;
+ break;
+ }
+ ring_prod = NEXT_SGE_IDX(ring_prod);
+ }
+ fp->rx_sge_prod = ring_prod;
+
+ /* Allocate BDs and initialize BD ring */
+ fp->rx_comp_cons = fp->rx_alloc_failed = 0;
+ cqe_ring_prod = ring_prod = 0;
+ for (i = 0; i < bp->rx_ring_size; i++) {
+ if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
+ BNX2X_ERR("was only able to allocate "
+ "%d rx skbs\n", i);
+ fp->rx_alloc_failed++;
+ break;
+ }
+ ring_prod = NEXT_RX_IDX(ring_prod);
+ cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
+ BUG_TRAP(ring_prod > i);
+ }
+
+ fp->rx_bd_prod = ring_prod;
+ /* must not have more available CQEs than BDs */
+ fp->rx_comp_prod = min((u16)(NUM_RCQ_RINGS*RCQ_DESC_CNT),
+ cqe_ring_prod);
+ fp->rx_pkt = fp->rx_calls = 0;
+
+ /* Warning!
+ * this will generate an interrupt (to the TSTORM)
+ * must only be done after chip is initialized
+ */
+ bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
+ if (j != 0)
+ continue;
+
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func),
+ U64_LO(fp->rx_comp_mapping));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4,
+ U64_HI(fp->rx_comp_mapping));
+ }
+}
+
+static void bnx2x_init_tx_ring(struct bnx2x *bp)
+{
+ int i, j;
+
+ for_each_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ for (i = 1; i <= NUM_TX_RINGS; i++) {
+ struct eth_tx_bd *tx_bd =
+ &fp->tx_desc_ring[TX_DESC_CNT * i - 1];
+
+ tx_bd->addr_hi =
+ cpu_to_le32(U64_HI(fp->tx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+ tx_bd->addr_lo =
+ cpu_to_le32(U64_LO(fp->tx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+ }
+
+ fp->tx_pkt_prod = 0;
+ fp->tx_pkt_cons = 0;
+ fp->tx_bd_prod = 0;
+ fp->tx_bd_cons = 0;
+ fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
+ fp->tx_pkt = 0;
+ }
+}
+
+static void bnx2x_init_sp_ring(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+
+ spin_lock_init(&bp->spq_lock);
+
+ bp->spq_left = MAX_SPQ_PENDING;
+ bp->spq_prod_idx = 0;
+ bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
+ bp->spq_prod_bd = bp->spq;
+ bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
+
+ REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func),
+ U64_LO(bp->spq_mapping));
+ REG_WR(bp,
+ XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4,
+ U64_HI(bp->spq_mapping));
+
+ REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func),
+ bp->spq_prod_idx);
+}
+
+static void bnx2x_init_context(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_queue(bp, i) {
+ struct eth_context *context = bnx2x_sp(bp, context[i].eth);
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ u8 sb_id = FP_SB_ID(fp);
+
+ context->xstorm_st_context.tx_bd_page_base_hi =
+ U64_HI(fp->tx_desc_mapping);
+ context->xstorm_st_context.tx_bd_page_base_lo =
+ U64_LO(fp->tx_desc_mapping);
+ context->xstorm_st_context.db_data_addr_hi =
+ U64_HI(fp->tx_prods_mapping);
+ context->xstorm_st_context.db_data_addr_lo =
+ U64_LO(fp->tx_prods_mapping);
+ context->xstorm_st_context.statistics_data = (BP_CL_ID(bp) |
+ XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+
+ context->ustorm_st_context.common.sb_index_numbers =
+ BNX2X_RX_SB_INDEX_NUM;
+ context->ustorm_st_context.common.clientId = FP_CL_ID(fp);
+ context->ustorm_st_context.common.status_block_id = sb_id;
+ context->ustorm_st_context.common.flags =
+ USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT;
+ context->ustorm_st_context.common.mc_alignment_size = 64;
+ context->ustorm_st_context.common.bd_buff_size =
+ bp->rx_buf_use_size;
+ context->ustorm_st_context.common.bd_page_base_hi =
+ U64_HI(fp->rx_desc_mapping);
+ context->ustorm_st_context.common.bd_page_base_lo =
+ U64_LO(fp->rx_desc_mapping);
+ if (!fp->disable_tpa) {
+ context->ustorm_st_context.common.flags |=
+ (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA |
+ USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING);
+ context->ustorm_st_context.common.sge_buff_size =
+ (u16)(BCM_PAGE_SIZE*PAGES_PER_SGE);
+ context->ustorm_st_context.common.sge_page_base_hi =
+ U64_HI(fp->rx_sge_mapping);
+ context->ustorm_st_context.common.sge_page_base_lo =
+ U64_LO(fp->rx_sge_mapping);
+ }
+
+ context->cstorm_st_context.sb_index_number =
+ HC_INDEX_C_ETH_TX_CQ_CONS;
+ context->cstorm_st_context.status_block_id = sb_id;
+
+ context->xstorm_ag_context.cdu_reserved =
+ CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+ CDU_REGION_NUMBER_XCM_AG,
+ ETH_CONNECTION_TYPE);
+ context->ustorm_ag_context.cdu_usage =
+ CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+ CDU_REGION_NUMBER_UCM_AG,
+ ETH_CONNECTION_TYPE);
+ }
+}
+
+static void bnx2x_init_ind_table(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int i;
+
+ if (!is_multi(bp))
+ return;
+
+ DP(NETIF_MSG_IFUP, "Initializing indirection table\n");
+ for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
+ REG_WR8(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_INDIRECTION_TABLE_OFFSET(port) + i,
+ i % bp->num_queues);
+
+ REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
+}
+
+static void bnx2x_set_client_config(struct bnx2x *bp)
+{
+ struct tstorm_eth_client_config tstorm_client = {0};
+ int port = BP_PORT(bp);
+ int i;
+
+ tstorm_client.mtu = bp->dev->mtu + ETH_OVREHEAD;
+ tstorm_client.statistics_counter_id = 0;
+ tstorm_client.config_flags =
+ TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+#ifdef BCM_VLAN
+ if (bp->rx_mode && bp->vlgrp) {
+ tstorm_client.config_flags |=
+ TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+ DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
+ }
+#endif
+
+ if (bp->flags & TPA_ENABLE_FLAG) {
+ tstorm_client.max_sges_for_packet =
+ BCM_PAGE_ALIGN(tstorm_client.mtu) >> BCM_PAGE_SHIFT;
+ tstorm_client.max_sges_for_packet =
+ ((tstorm_client.max_sges_for_packet +
+ PAGES_PER_SGE - 1) & (~(PAGES_PER_SGE - 1))) >>
+ PAGES_PER_SGE_SHIFT;
+
+ tstorm_client.config_flags |=
+ TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING;
+ }
+
+ for_each_queue(bp, i) {
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id),
+ ((u32 *)&tstorm_client)[0]);
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4,
+ ((u32 *)&tstorm_client)[1]);
+ }
+
+ DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n",
+ ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]);
+}
+
+static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
+{
+ struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0};
+ int mode = bp->rx_mode;
+ int mask = (1 << BP_L_ID(bp));
+ int func = BP_FUNC(bp);
+ int i;
+
+ DP(NETIF_MSG_RX_STATUS, "rx mode is %d\n", mode);
+
+ switch (mode) {
+ case BNX2X_RX_MODE_NONE: /* no Rx */
+ tstorm_mac_filter.ucast_drop_all = mask;
+ tstorm_mac_filter.mcast_drop_all = mask;
+ tstorm_mac_filter.bcast_drop_all = mask;
+ break;
+ case BNX2X_RX_MODE_NORMAL:
+ tstorm_mac_filter.bcast_accept_all = mask;
+ break;
+ case BNX2X_RX_MODE_ALLMULTI:
+ tstorm_mac_filter.mcast_accept_all = mask;
+ tstorm_mac_filter.bcast_accept_all = mask;
+ break;
+ case BNX2X_RX_MODE_PROMISC:
+ tstorm_mac_filter.ucast_accept_all = mask;
+ tstorm_mac_filter.mcast_accept_all = mask;
+ tstorm_mac_filter.bcast_accept_all = mask;
+ break;
+ default:
+ BNX2X_ERR("BAD rx mode (%d)\n", mode);
+ break;
+ }
+
+ for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4,
+ ((u32 *)&tstorm_mac_filter)[i]);
+
+/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
+ ((u32 *)&tstorm_mac_filter)[i]); */
+ }
+
+ if (mode != BNX2X_RX_MODE_NONE)
+ bnx2x_set_client_config(bp);
+}
+
+static void bnx2x_init_internal(struct bnx2x *bp)
+{
+ struct tstorm_eth_function_common_config tstorm_config = {0};
+ struct stats_indication_flags stats_flags = {0};
+ int port = BP_PORT(bp);
+ int func = BP_FUNC(bp);
+ int i;
+
+ if (is_multi(bp)) {
+ tstorm_config.config_flags = MULTI_FLAGS;
+ tstorm_config.rss_result_mask = MULTI_MASK;
+ }
+
+ tstorm_config.leading_client_id = BP_L_ID(bp);
+
+ REG_WR(bp, BAR_TSTRORM_INTMEM +
+ TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func),
+ (*(u32 *)&tstorm_config));
+
+/* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
+ (*(u32 *)&tstorm_config)); */
+
+ bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
+ bnx2x_set_storm_rx_mode(bp);
+
+ stats_flags.collect_eth = 1;
+
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port),
+ ((u32 *)&stats_flags)[0]);
+ REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port) + 4,
+ ((u32 *)&stats_flags)[1]);
+
+ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port),
+ ((u32 *)&stats_flags)[0]);
+ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port) + 4,
+ ((u32 *)&stats_flags)[1]);
+
+ REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port),
+ ((u32 *)&stats_flags)[0]);
+ REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port) + 4,
+ ((u32 *)&stats_flags)[1]);
+
+/* DP(NETIF_MSG_IFUP, "stats_flags: 0x%08x 0x%08x\n",
+ ((u32 *)&stats_flags)[0], ((u32 *)&stats_flags)[1]); */
+
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
+ IS_E1HMF(bp));
+ REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET,
+ IS_E1HMF(bp));
+ REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET,
+ IS_E1HMF(bp));
+ REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET,
+ IS_E1HMF(bp));
+
+ REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func),
+ bp->e1hov);
+ }
+
+ /* Zero this manualy as its initialization is
+ currently missing in the initTool */
+ for (i = 0; i < USTORM_AGG_DATA_SIZE >> 2; i++)
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_AGG_DATA_OFFSET + 4*i, 0);
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ u16 max_agg_size;
+
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
+ U64_LO(fp->rx_comp_mapping));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
+ U64_HI(fp->rx_comp_mapping));
+
+ max_agg_size = min((u32)(bp->rx_buf_use_size +
+ 8*BCM_PAGE_SIZE*PAGES_PER_SGE),
+ (u32)0xffff);
+ REG_WR16(bp, BAR_USTRORM_INTMEM +
+ USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
+ max_agg_size);
+ }
+}
+
+static void bnx2x_nic_init(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ fp->bp = bp;
+ fp->state = BNX2X_FP_STATE_CLOSED;
+ fp->index = i;
+ fp->cl_id = BP_L_ID(bp) + i;
+ fp->sb_id = fp->cl_id;
+ DP(NETIF_MSG_IFUP,
+ "bnx2x_init_sb(%p,%p) index %d cl_id %d sb %d\n",
+ bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
+ bnx2x_init_sb(bp, FP_SB_ID(fp), fp->status_blk,
+ fp->status_blk_mapping);
+ }
+
+ bnx2x_init_def_sb(bp, bp->def_status_blk,
+ bp->def_status_blk_mapping, DEF_SB_ID);
+ bnx2x_update_coalesce(bp);
+ bnx2x_init_rx_rings(bp);
+ bnx2x_init_tx_ring(bp);
+ bnx2x_init_sp_ring(bp);
+ bnx2x_init_context(bp);
+ bnx2x_init_internal(bp);
+ bnx2x_storm_stats_init(bp);
+ bnx2x_init_ind_table(bp);
+ bnx2x_int_enable(bp);
+}
+
+/* end of nic init */
+
+/*
+ * gzip service functions
+ */
+
+static int bnx2x_gunzip_init(struct bnx2x *bp)
+{
+ bp->gunzip_buf = pci_alloc_consistent(bp->pdev, FW_BUF_SIZE,
+ &bp->gunzip_mapping);
+ if (bp->gunzip_buf == NULL)
+ goto gunzip_nomem1;
+
+ bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL);
+ if (bp->strm == NULL)
+ goto gunzip_nomem2;
+
+ bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
+ GFP_KERNEL);
+ if (bp->strm->workspace == NULL)
+ goto gunzip_nomem3;
+
+ return 0;
+
+gunzip_nomem3:
+ kfree(bp->strm);
+ bp->strm = NULL;
+
+gunzip_nomem2:
+ pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
+ bp->gunzip_mapping);
+ bp->gunzip_buf = NULL;
+
+gunzip_nomem1:
+ printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for"
+ " un-compression\n", bp->dev->name);
+ return -ENOMEM;
+}
+
+static void bnx2x_gunzip_end(struct bnx2x *bp)
+{
+ kfree(bp->strm->workspace);
+
+ kfree(bp->strm);
+ bp->strm = NULL;
+
+ if (bp->gunzip_buf) {
+ pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
+ bp->gunzip_mapping);
+ bp->gunzip_buf = NULL;
+ }
+}
+
+static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
+{
+ int n, rc;
+
+ /* check gzip header */
+ if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
+ return -EINVAL;
+
+ n = 10;
+
+#define FNAME 0x8
+
+ if (zbuf[3] & FNAME)
+ while ((zbuf[n++] != 0) && (n < len));
+
+ bp->strm->next_in = zbuf + n;
+ bp->strm->avail_in = len - n;
+ bp->strm->next_out = bp->gunzip_buf;
+ bp->strm->avail_out = FW_BUF_SIZE;
+
+ rc = zlib_inflateInit2(bp->strm, -MAX_WBITS);
+ if (rc != Z_OK)
+ return rc;
+
+ rc = zlib_inflate(bp->strm, Z_FINISH);
+ if ((rc != Z_OK) && (rc != Z_STREAM_END))
+ printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n",
+ bp->dev->name, bp->strm->msg);
+
+ bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out);
+ if (bp->gunzip_outlen & 0x3)
+ printk(KERN_ERR PFX "%s: Firmware decompression error:"
+ " gunzip_outlen (%d) not aligned\n",
+ bp->dev->name, bp->gunzip_outlen);
+ bp->gunzip_outlen >>= 2;
+
+ zlib_inflateEnd(bp->strm);
+
+ if (rc == Z_STREAM_END)
+ return 0;
+
+ return rc;
+}
+
+/* nic load/unload */
+
+/*
+ * General service functions
+ */
+
+/* send a NIG loopback debug packet */
+static void bnx2x_lb_pckt(struct bnx2x *bp)
+{
+ u32 wb_write[3];
+
+ /* Ethernet source and destination addresses */
+ wb_write[0] = 0x55555555;
+ wb_write[1] = 0x55555555;
+ wb_write[2] = 0x20; /* SOP */
+ REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
+
+ /* NON-IP protocol */
+ wb_write[0] = 0x09000000;
+ wb_write[1] = 0x55555555;
+ wb_write[2] = 0x10; /* EOP, eop_bvalid = 0 */
+ REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
+}
+
+/* some of the internal memories
+ * are not directly readable from the driver
+ * to test them we send debug packets
+ */
+static int bnx2x_int_mem_test(struct bnx2x *bp)
+{
+ int factor;
+ int count, i;
+ u32 val = 0;
+
+ if (CHIP_REV_IS_FPGA(bp))
+ factor = 120;
+ else if (CHIP_REV_IS_EMUL(bp))
+ factor = 200;
+ else
+ factor = 1;
+
+ DP(NETIF_MSG_HW, "start part1\n");
+
+ /* Disable inputs of parser neighbor blocks */
+ REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
+ REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
+ REG_WR(bp, CFC_REG_DEBUG0, 0x1);
+ NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0);
+
+ /* Write 0 to parser credits for CFC search request */
+ REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
+
+ /* send Ethernet packet */
+ bnx2x_lb_pckt(bp);
+
+ /* TODO do i reset NIG statistic? */
+ /* Wait until NIG register shows 1 packet of size 0x10 */
+ count = 1000 * factor;
+ while (count) {
+
+ bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+ val = *bnx2x_sp(bp, wb_data[0]);
+ if (val == 0x10)
+ break;
+
+ msleep(10);
+ count--;
+ }
+ if (val != 0x10) {
+ BNX2X_ERR("NIG timeout val = 0x%x\n", val);
+ return -1;
+ }
+
+ /* Wait until PRS register shows 1 packet */
+ count = 1000 * factor;
+ while (count) {
+ val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
+ if (val == 1)
+ break;
+
+ msleep(10);
+ count--;
+ }
+ if (val != 0x1) {
+ BNX2X_ERR("PRS timeout val = 0x%x\n", val);
+ return -2;
+ }
+
+ /* Reset and init BRB, PRS */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03);
+ msleep(50);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
+ msleep(50);
+ bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
+ bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+
+ DP(NETIF_MSG_HW, "part2\n");
+
+ /* Disable inputs of parser neighbor blocks */
+ REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
+ REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
+ REG_WR(bp, CFC_REG_DEBUG0, 0x1);
+ NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0);
+
+ /* Write 0 to parser credits for CFC search request */
+ REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
+
+ /* send 10 Ethernet packets */
+ for (i = 0; i < 10; i++)
+ bnx2x_lb_pckt(bp);
+
+ /* Wait until NIG register shows 10 + 1
+ packets of size 11*0x10 = 0xb0 */
+ count = 1000 * factor;
+ while (count) {
+
+ bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+ val = *bnx2x_sp(bp, wb_data[0]);
+ if (val == 0xb0)
+ break;
+
+ msleep(10);
+ count--;
+ }
+ if (val != 0xb0) {
+ BNX2X_ERR("NIG timeout val = 0x%x\n", val);
+ return -3;
+ }
+
+ /* Wait until PRS register shows 2 packets */
+ val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
+ if (val != 2)
+ BNX2X_ERR("PRS timeout val = 0x%x\n", val);
+
+ /* Write 1 to parser credits for CFC search request */
+ REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1);
+
+ /* Wait until PRS register shows 3 packets */
+ msleep(10 * factor);
+ /* Wait until NIG register shows 1 packet of size 0x10 */
+ val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
+ if (val != 3)
+ BNX2X_ERR("PRS timeout val = 0x%x\n", val);
+
+ /* clear NIG EOP FIFO */
+ for (i = 0; i < 11; i++)
+ REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO);
+ val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY);
+ if (val != 1) {
+ BNX2X_ERR("clear of NIG failed\n");
+ return -4;
+ }
+
+ /* Reset and init BRB, PRS, NIG */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03);
+ msleep(50);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
+ msleep(50);
+ bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
+ bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+#ifndef BCM_ISCSI
+ /* set NIC mode */
+ REG_WR(bp, PRS_REG_NIC_MODE, 1);
+#endif
+
+ /* Enable inputs of parser neighbor blocks */
+ REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff);
+ REG_WR(bp, TCM_REG_PRS_IFEN, 0x1);
+ REG_WR(bp, CFC_REG_DEBUG0, 0x0);
+ NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x1);
+
+ DP(NETIF_MSG_HW, "done\n");
+
+ return 0; /* OK */
+}
+
+static void enable_blocks_attention(struct bnx2x *bp)
+{
+ REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
+ REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0);
+ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
+ REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
+ REG_WR(bp, QM_REG_QM_INT_MASK, 0);
+ REG_WR(bp, TM_REG_TM_INT_MASK, 0);
+ REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0);
+ REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0);
+ REG_WR(bp, XCM_REG_XCM_INT_MASK, 0);
+/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */
+/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */
+ REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0);
+ REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0);
+ REG_WR(bp, UCM_REG_UCM_INT_MASK, 0);
+/* REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */
+/* REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */
+ REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0);
+ REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0);
+ REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0);
+ REG_WR(bp, CCM_REG_CCM_INT_MASK, 0);
+/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */
+/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */
+ if (CHIP_REV_IS_FPGA(bp))
+ REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000);
+ else
+ REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000);
+ REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0);
+ REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0);
+ REG_WR(bp, TCM_REG_TCM_INT_MASK, 0);
+/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */
+/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */
+ REG_WR(bp, CDU_REG_CDU_INT_MASK, 0);
+ REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0);
+/* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */
+ REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */
+}
+
+
+static int bnx2x_init_common(struct bnx2x *bp)
+{
+ u32 val, i;
+
+ DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp));
+
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
+
+ bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
+ if (CHIP_IS_E1H(bp))
+ REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
+
+ REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
+ msleep(30);
+ REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
+
+ bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
+ if (CHIP_IS_E1(bp)) {
+ /* enable HW interrupt from PXP on USDM overflow
+ bit 16 on INT_MASK_0 */
+ REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
+ }
+
+ bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
+ bnx2x_init_pxp(bp);
+
+#ifdef __BIG_ENDIAN
+ REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1);
+ REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1);
+ REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
+ REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
+ REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
+ REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1);
+
+/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
+ REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
+ REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1);
+ REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1);
+ REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
+#endif
+
+#ifndef BCM_ISCSI
+ /* set NIC mode */
+ REG_WR(bp, PRS_REG_NIC_MODE, 1);
+#endif
+
+ REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2);
+#ifdef BCM_ISCSI
+ REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
+ REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5);
+ REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5);
+#endif
+
+ if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp))
+ REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1);
+
+ /* let the HW do it's magic ... */
+ msleep(100);
+ /* finish PXP init */
+ val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE);
+ if (val != 1) {
+ BNX2X_ERR("PXP2 CFG failed\n");
+ return -EBUSY;
+ }
+ val = REG_RD(bp, PXP2_REG_RD_INIT_DONE);
+ if (val != 1) {
+ BNX2X_ERR("PXP2 RD_INIT failed\n");
+ return -EBUSY;
+ }
+
+ REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
+ REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
+
+ bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
+
+ /* clean the DMAE memory */
+ bp->dmae_ready = 1;
+ bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
+
+ bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
+ bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
+ bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
+ bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
+
+ bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
+ bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
+ bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
+ bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
+
+ bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
+ /* soft reset pulse */
+ REG_WR(bp, QM_REG_SOFT_RESET, 1);
+ REG_WR(bp, QM_REG_SOFT_RESET, 0);
+
+#ifdef BCM_ISCSI
+ bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
+#endif
+
+ bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
+ REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
+ if (!CHIP_REV_IS_SLOW(bp)) {
+ /* enable hw interrupt from doorbell Q */
+ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
+ }
+
+ bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
+ if (CHIP_REV_IS_SLOW(bp)) {
+ /* fix for emulation and FPGA for no pause */
+ REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
+ REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
+ REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
+ REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
+ }
+
+ bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+ if (CHIP_IS_E1H(bp))
+ REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
+
+ bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
+ bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
+ bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
+ bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
+
+ if (CHIP_IS_E1H(bp)) {
+ bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp,
+ TSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
+ 0, STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp,
+ CSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
+ 0, STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp,
+ XSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
+ 0, STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1H/2);
+ bnx2x_init_fill(bp,
+ USTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
+ 0, STORM_INTMEM_SIZE_E1H/2);
+ } else { /* E1 */
+ bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1);
+ bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1);
+ bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1);
+ bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
+ STORM_INTMEM_SIZE_E1);
+ }
+
+ bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
+ bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
+ bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
+ bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
+
+ /* sync semi rtc */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+ 0x80000000);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+ 0x80000000);
+
+ bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
+ bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
+ bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
+
+ REG_WR(bp, SRC_REG_SOFT_RST, 1);
+ for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
+ REG_WR(bp, i, 0xc0cac01a);
+ /* TODO: replace with something meaningful */
+ }
+ if (CHIP_IS_E1H(bp))
+ bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+ REG_WR(bp, SRC_REG_SOFT_RST, 0);
+
+ if (sizeof(union cdu_context) != 1024)
+ /* we currently assume that a context is 1024 bytes */
+ printk(KERN_ALERT PFX "please adjust the size of"
+ " cdu_context(%ld)\n", (long)sizeof(union cdu_context));
+
+ bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
+ val = (4 << 24) + (0 << 12) + 1024;
+ REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
+ if (CHIP_IS_E1(bp)) {
+ /* !!! fix pxp client crdit until excel update */
+ REG_WR(bp, CDU_REG_CDU_DEBUG, 0x264);
+ REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
+ }
+
+ bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
+ REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
+
+ bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
+ bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
+
+ /* PXPCS COMMON comes here */
+ /* Reset PCIE errors for debug */
+ REG_WR(bp, 0x2814, 0xffffffff);
+ REG_WR(bp, 0x3820, 0xffffffff);
+
+ /* EMAC0 COMMON comes here */
+ /* EMAC1 COMMON comes here */
+ /* DBU COMMON comes here */
+ /* DBG COMMON comes here */
+
+ bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
+ REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
+ }
+
+ if (CHIP_REV_IS_SLOW(bp))
+ msleep(200);
+
+ /* finish CFC init */
+ val = reg_poll(bp, CFC_REG_LL_INIT_DONE, 1, 100, 10);
+ if (val != 1) {
+ BNX2X_ERR("CFC LL_INIT failed\n");
+ return -EBUSY;
+ }
+ val = reg_poll(bp, CFC_REG_AC_INIT_DONE, 1, 100, 10);
+ if (val != 1) {
+ BNX2X_ERR("CFC AC_INIT failed\n");
+ return -EBUSY;
+ }
+ val = reg_poll(bp, CFC_REG_CAM_INIT_DONE, 1, 100, 10);
+ if (val != 1) {
+ BNX2X_ERR("CFC CAM_INIT failed\n");
+ return -EBUSY;
+ }
+ REG_WR(bp, CFC_REG_DEBUG0, 0);
+
+ /* read NIG statistic
+ to see if this is our first up since powerup */
+ bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+ val = *bnx2x_sp(bp, wb_data[0]);
+
+ /* do internal memory self test */
+ if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) {
+ BNX2X_ERR("internal mem self test failed\n");
+ return -EBUSY;
+ }
+
+ switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* Fan failure is indicated by SPIO 5 */
+ bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
+ MISC_REGISTERS_SPIO_INPUT_HI_Z);
+
+ /* set to active low mode */
+ val = REG_RD(bp, MISC_REG_SPIO_INT);
+ val |= ((1 << MISC_REGISTERS_SPIO_5) <<
+ MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
+ REG_WR(bp, MISC_REG_SPIO_INT, val);
+
+ /* enable interrupt to signal the IGU */
+ val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
+ val |= (1 << MISC_REGISTERS_SPIO_5);
+ REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
+ break;
+
+ default:
+ break;
+ }
+
+ /* clear PXP2 attentions */
+ REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0);
+
+ enable_blocks_attention(bp);
+
+ if (bp->flags & TPA_ENABLE_FLAG) {
+ struct tstorm_eth_tpa_exist tmp = {0};
+
+ tmp.tpa_exist = 1;
+
+ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_TPA_EXIST_OFFSET,
+ ((u32 *)&tmp)[0]);
+ REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_TPA_EXIST_OFFSET + 4,
+ ((u32 *)&tmp)[1]);
+ }
+
+ return 0;
+}
+
+static int bnx2x_init_port(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ u32 val;
+
+ DP(BNX2X_MSG_MCP, "starting port init port %x\n", port);
+
+ REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
+
+ /* Port PXP comes here */
+ /* Port PXP2 comes here */
+#ifdef BCM_ISCSI
+ /* Port0 1
+ * Port1 385 */
+ i++;
+ wb_write[0] = ONCHIP_ADDR1(bp->timers_mapping);
+ wb_write[1] = ONCHIP_ADDR2(bp->timers_mapping);
+ REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+ REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
+
+ /* Port0 2
+ * Port1 386 */
+ i++;
+ wb_write[0] = ONCHIP_ADDR1(bp->qm_mapping);
+ wb_write[1] = ONCHIP_ADDR2(bp->qm_mapping);
+ REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+ REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
+
+ /* Port0 3
+ * Port1 387 */
+ i++;
+ wb_write[0] = ONCHIP_ADDR1(bp->t1_mapping);
+ wb_write[1] = ONCHIP_ADDR2(bp->t1_mapping);
+ REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+ REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
+#endif
+ /* Port CMs come here */
+
+ /* Port QM comes here */
+#ifdef BCM_ISCSI
+ REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
+ REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
+
+ bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
+ func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
+#endif
+ /* Port DQ comes here */
+ /* Port BRB1 comes here */
+ /* Port PRS comes here */
+ /* Port TSDM comes here */
+ /* Port CSDM comes here */
+ /* Port USDM comes here */
+ /* Port XSDM comes here */
+ bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
+ port ? TSEM_PORT1_END : TSEM_PORT0_END);
+ bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
+ port ? USEM_PORT1_END : USEM_PORT0_END);
+ bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
+ port ? CSEM_PORT1_END : CSEM_PORT0_END);
+ bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
+ port ? XSEM_PORT1_END : XSEM_PORT0_END);
+ /* Port UPB comes here */
+ /* Port XPB comes here */
+
+ bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START,
+ port ? PBF_PORT1_END : PBF_PORT0_END);
+
+ /* configure PBF to work without PAUSE mtu 9000 */
+ REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
+
+ /* update threshold */
+ REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16));
+ /* update init credit */
+ REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22);
+
+ /* probe changes */
+ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1);
+ msleep(5);
+ REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0);
+
+#ifdef BCM_ISCSI
+ /* tell the searcher where the T2 table is */
+ REG_WR(bp, SRC_REG_COUNTFREE0 + func*4, 16*1024/64);
+
+ wb_write[0] = U64_LO(bp->t2_mapping);
+ wb_write[1] = U64_HI(bp->t2_mapping);
+ REG_WR_DMAE(bp, SRC_REG_FIRSTFREE0 + func*4, wb_write, 2);
+ wb_write[0] = U64_LO((u64)bp->t2_mapping + 16*1024 - 64);
+ wb_write[1] = U64_HI((u64)bp->t2_mapping + 16*1024 - 64);
+ REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2);
+
+ REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10);
+ /* Port SRCH comes here */
+#endif
+ /* Port CDU comes here */
+ /* Port CFC comes here */
+
+ if (CHIP_IS_E1(bp)) {
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+ }
+ bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START,
+ port ? HC_PORT1_END : HC_PORT0_END);
+
+ bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START :
+ MISC_AEU_PORT0_START,
+ port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
+ /* init aeu_mask_attn_func_0/1:
+ * - SF mode: bits 3-7 are masked. only bits 0-2 are in use
+ * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
+ * bits 4-7 are used for "per vn group attention" */
+ REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4,
+ (IS_E1HMF(bp) ? 0xF7 : 0x7));
+
+ /* Port PXPCS comes here */
+ /* Port EMAC0 comes here */
+ /* Port EMAC1 comes here */
+ /* Port DBU comes here */
+ /* Port DBG comes here */
+ bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
+ port ? NIG_PORT1_END : NIG_PORT0_END);
+
+ REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
+
+ if (CHIP_IS_E1H(bp)) {
+ u32 wsum;
+ struct cmng_struct_per_port m_cmng_port;
+ int vn;
+
+ /* 0x2 disable e1hov, 0x1 enable */
+ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
+ (IS_E1HMF(bp) ? 0x1 : 0x2));
+
+ /* Init RATE SHAPING and FAIRNESS contexts.
+ Initialize as if there is 10G link. */
+ wsum = bnx2x_calc_vn_wsum(bp);
+ bnx2x_init_port_minmax(bp, (int)wsum, 10000, &m_cmng_port);
+ if (IS_E1HMF(bp))
+ for (vn = VN_0; vn < E1HVN_MAX; vn++)
+ bnx2x_init_vn_minmax(bp, 2*vn + port,
+ wsum, 10000, &m_cmng_port);
+ }
+
+ /* Port MCP comes here */
+ /* Port DMAE comes here */
+
+ switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
+ case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ /* add SPIO 5 to group 0 */
+ val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+ val |= AEU_INPUTS_ATTN_BITS_SPIO5;
+ REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
+ break;
+
+ default:
+ break;
+ }
+
+ bnx2x__link_reset(bp);
+
+ return 0;
+}
+
+#define ILT_PER_FUNC (768/2)
+#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC)
+/* the phys address is shifted right 12 bits and has an added
+ 1=valid bit added to the 53rd bit
+ then since this is a wide register(TM)
+ we split it into two 32 bit writes
+ */
+#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
+#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
+#define PXP_ONE_ILT(x) (((x) << 10) | x)
+#define PXP_ILT_RANGE(f, l) (((l) << 10) | f)
+
+#define CNIC_ILT_LINES 0
+
+static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr)
+{
+ int reg;
+
+ if (CHIP_IS_E1H(bp))
+ reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8;
+ else /* E1 */
+ reg = PXP2_REG_RQ_ONCHIP_AT + index*8;
+
+ bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr));
+}
+
+static int bnx2x_init_func(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int func = BP_FUNC(bp);
+ int i;
+
+ DP(BNX2X_MSG_MCP, "starting func init func %x\n", func);
+
+ i = FUNC_ILT_BASE(func);
+
+ bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context));
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i);
+ REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES);
+ } else /* E1 */
+ REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4,
+ PXP_ILT_RANGE(i, i + CNIC_ILT_LINES));
+
+
+ if (CHIP_IS_E1H(bp)) {
+ for (i = 0; i < 9; i++)
+ bnx2x_init_block(bp,
+ cm_start[func][i], cm_end[func][i]);
+
+ REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
+ REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
+ }
+
+ /* HC init per function */
+ if (CHIP_IS_E1H(bp)) {
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+ }
+ bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
+
+ if (CHIP_IS_E1H(bp))
+ REG_WR(bp, HC_REG_FUNC_NUM_P0 + port*4, func);
+
+ /* Reset PCIE errors for debug */
+ REG_WR(bp, 0x2114, 0xffffffff);
+ REG_WR(bp, 0x2120, 0xffffffff);
+
+ return 0;
+}
+
+static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
+{
+ int i, rc = 0;
+
+ DP(BNX2X_MSG_MCP, "function %d load_code %x\n",
+ BP_FUNC(bp), load_code);
+
+ bp->dmae_ready = 0;
+ mutex_init(&bp->dmae_mutex);
+ bnx2x_gunzip_init(bp);
+
+ switch (load_code) {
+ case FW_MSG_CODE_DRV_LOAD_COMMON:
+ rc = bnx2x_init_common(bp);
+ if (rc)
+ goto init_hw_err;
+ /* no break */
+
+ case FW_MSG_CODE_DRV_LOAD_PORT:
+ bp->dmae_ready = 1;
+ rc = bnx2x_init_port(bp);
+ if (rc)
+ goto init_hw_err;
+ /* no break */
+
+ case FW_MSG_CODE_DRV_LOAD_FUNCTION:
+ bp->dmae_ready = 1;
+ rc = bnx2x_init_func(bp);
+ if (rc)
+ goto init_hw_err;
+ break;
+
+ default:
+ BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code);
+ break;
+ }
+
+ if (!BP_NOMCP(bp)) {
+ int func = BP_FUNC(bp);
+
+ bp->fw_drv_pulse_wr_seq =
+ (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) &
+ DRV_PULSE_SEQ_MASK);
+ bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
+ DP(BNX2X_MSG_MCP, "drv_pulse 0x%x func_stx 0x%x\n",
+ bp->fw_drv_pulse_wr_seq, bp->func_stx);
+ } else
+ bp->func_stx = 0;
+
+ /* this needs to be done before gunzip end */
+ bnx2x_zero_def_sb(bp);
+ for_each_queue(bp, i)
+ bnx2x_zero_sb(bp, BP_L_ID(bp) + i);
+
+init_hw_err:
+ bnx2x_gunzip_end(bp);
+
+ return rc;
+}
+
+/* send the MCP a request, block until there is a reply */
+static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
+{
+ int func = BP_FUNC(bp);
+ u32 seq = ++bp->fw_seq;
+ u32 rc = 0;
+
+ SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
+ DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
+
+ /* let the FW do it's magic ... */
+ msleep(100); /* TBD */
+
+ if (CHIP_REV_IS_SLOW(bp))
+ msleep(900);
+
+ rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
+ DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
+
+ /* is this a reply to our command? */
+ if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
+ rc &= FW_MSG_CODE_MASK;
+
+ } else {
+ /* FW BUG! */
+ BNX2X_ERR("FW failed to respond!\n");
+ bnx2x_fw_dump(bp);
+ rc = 0;
+ }
+
+ return rc;
+}
+
+static void bnx2x_free_mem(struct bnx2x *bp)
+{
+
+#define BNX2X_PCI_FREE(x, y, size) \
+ do { \
+ if (x) { \
+ pci_free_consistent(bp->pdev, size, x, y); \
+ x = NULL; \
+ y = 0; \
+ } \
+ } while (0)
+
+#define BNX2X_FREE(x) \
+ do { \
+ if (x) { \
+ vfree(x); \
+ x = NULL; \
+ } \
+ } while (0)
+
+ int i;
+
+ /* fastpath */
+ for_each_queue(bp, i) {
+
+ /* Status blocks */
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
+ bnx2x_fp(bp, i, status_blk_mapping),
+ sizeof(struct host_status_block) +
+ sizeof(struct eth_tx_db_data));
+
+ /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
+ BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
+ bnx2x_fp(bp, i, tx_desc_mapping),
+ sizeof(struct eth_tx_bd) * NUM_TX_BD);
+
+ BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
+ bnx2x_fp(bp, i, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring),
+ bnx2x_fp(bp, i, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring),
+ bnx2x_fp(bp, i, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ }
+ /* end of fastpath */
+
+ BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
+ sizeof(struct host_def_status_block));
+
+ BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
+ sizeof(struct bnx2x_slowpath));
+
+#ifdef BCM_ISCSI
+ BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024);
+ BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024);
+ BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024);
+ BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024);
+#endif
+ BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE);
+
+#undef BNX2X_PCI_FREE
+#undef BNX2X_KFREE
+}
+
+static int bnx2x_alloc_mem(struct bnx2x *bp)
+{
+
+#define BNX2X_PCI_ALLOC(x, y, size) \
+ do { \
+ x = pci_alloc_consistent(bp->pdev, size, y); \
+ if (x == NULL) \
+ goto alloc_mem_err; \
+ memset(x, 0, size); \
+ } while (0)
+
+#define BNX2X_ALLOC(x, size) \
+ do { \
+ x = vmalloc(size); \
+ if (x == NULL) \
+ goto alloc_mem_err; \
+ memset(x, 0, size); \
+ } while (0)
+
+ int i;
+
+ /* fastpath */
+ for_each_queue(bp, i) {
+ bnx2x_fp(bp, i, bp) = bp;
+
+ /* Status blocks */
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
+ &bnx2x_fp(bp, i, status_blk_mapping),
+ sizeof(struct host_status_block) +
+ sizeof(struct eth_tx_db_data));
+
+ bnx2x_fp(bp, i, hw_tx_prods) =
+ (void *)(bnx2x_fp(bp, i, status_blk) + 1);
+
+ bnx2x_fp(bp, i, tx_prods_mapping) =
+ bnx2x_fp(bp, i, status_blk_mapping) +
+ sizeof(struct host_status_block);
+
+ /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
+ BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
+ sizeof(struct sw_tx_bd) * NUM_TX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
+ &bnx2x_fp(bp, i, tx_desc_mapping),
+ sizeof(struct eth_tx_bd) * NUM_TX_BD);
+
+ BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
+ sizeof(struct sw_rx_bd) * NUM_RX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
+ &bnx2x_fp(bp, i, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring),
+ &bnx2x_fp(bp, i, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring),
+ sizeof(struct sw_rx_page) * NUM_RX_SGE);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring),
+ &bnx2x_fp(bp, i, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ }
+ /* end of fastpath */
+
+ BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
+ sizeof(struct host_def_status_block));
+
+ BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
+ sizeof(struct bnx2x_slowpath));
+
+#ifdef BCM_ISCSI
+ BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024);
+
+ /* Initialize T1 */
+ for (i = 0; i < 64*1024; i += 64) {
+ *(u64 *)((char *)bp->t1 + i + 56) = 0x0UL;
+ *(u64 *)((char *)bp->t1 + i + 3) = 0x0UL;
+ }
+
+ /* allocate searcher T2 table
+ we allocate 1/4 of alloc num for T2
+ (which is not entered into the ILT) */
+ BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024);
+
+ /* Initialize T2 */
+ for (i = 0; i < 16*1024; i += 64)
+ * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
+
+ /* now fixup the last line in the block to point to the next block */
+ *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
+
+ /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
+ BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024);
+
+ /* QM queues (128*MAX_CONN) */
+ BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024);
+#endif
+
+ /* Slow path ring */
+ BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE);
+
+ return 0;
+
+alloc_mem_err:
+ bnx2x_free_mem(bp);
+ return -ENOMEM;
+
+#undef BNX2X_PCI_ALLOC
+#undef BNX2X_ALLOC
+}
+
+static void bnx2x_free_tx_skbs(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ u16 bd_cons = fp->tx_bd_cons;
+ u16 sw_prod = fp->tx_pkt_prod;
+ u16 sw_cons = fp->tx_pkt_cons;
+
+ while (sw_cons != sw_prod) {
+ bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons));
+ sw_cons++;
+ }
+ }
+}
+
+static void bnx2x_free_rx_skbs(struct bnx2x *bp)
+{
+ int i, j;
+
+ for_each_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ for (i = 0; i < NUM_RX_BD; i++) {
+ struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
+ struct sk_buff *skb = rx_buf->skb;
+
+ if (skb == NULL)
+ continue;
+
+ pci_unmap_single(bp->pdev,
+ pci_unmap_addr(rx_buf, mapping),
+ bp->rx_buf_use_size,
+ PCI_DMA_FROMDEVICE);
+
+ rx_buf->skb = NULL;
+ dev_kfree_skb(skb);
+ }
+ if (!fp->disable_tpa)
+ bnx2x_free_tpa_pool(bp, fp,
+ ETH_MAX_AGGREGATION_QUEUES_E1H);
+ }
+}
+
+static void bnx2x_free_skbs(struct bnx2x *bp)
+{
+ bnx2x_free_tx_skbs(bp);
+ bnx2x_free_rx_skbs(bp);
+}
+
+static void bnx2x_free_msix_irqs(struct bnx2x *bp)
+{
+ int i, offset = 1;
+
+ free_irq(bp->msix_table[0].vector, bp->dev);
+ DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
+ bp->msix_table[0].vector);
+
+ for_each_queue(bp, i) {
+ DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq "
+ "state %x\n", i, bp->msix_table[i + offset].vector,
+ bnx2x_fp(bp, i, state));
+
+ if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
+ BNX2X_ERR("IRQ of fp #%d being freed while "
+ "state != closed\n", i);
+
+ free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]);
+ }
+}
+
+static void bnx2x_free_irq(struct bnx2x *bp)
+{
+ if (bp->flags & USING_MSIX_FLAG) {
+ bnx2x_free_msix_irqs(bp);
+ pci_disable_msix(bp->pdev);
+ bp->flags &= ~USING_MSIX_FLAG;
+
+ } else
+ free_irq(bp->pdev->irq, bp->dev);
+}
+
+static int bnx2x_enable_msix(struct bnx2x *bp)
+{
+ int i, rc, offset;
+
+ bp->msix_table[0].entry = 0;
+ offset = 1;
+ DP(NETIF_MSG_IFUP, "msix_table[0].entry = 0 (slowpath)\n");
+
+ for_each_queue(bp, i) {
+ int igu_vec = offset + i + BP_L_ID(bp);
+
+ bp->msix_table[i + offset].entry = igu_vec;
+ DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
+ "(fastpath #%u)\n", i + offset, igu_vec, i);
+ }
+
+ rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
+ bp->num_queues + offset);
+ if (rc) {
+ DP(NETIF_MSG_IFUP, "MSI-X is not attainable\n");
+ return -1;
+ }
+ bp->flags |= USING_MSIX_FLAG;
+
+ return 0;
+}
+
+static int bnx2x_req_msix_irqs(struct bnx2x *bp)
+{
+ int i, rc, offset = 1;
+
+ rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
+ bp->dev->name, bp->dev);
+ if (rc) {
+ BNX2X_ERR("request sp irq failed\n");
+ return -EBUSY;
+ }
+
+ for_each_queue(bp, i) {
+ rc = request_irq(bp->msix_table[i + offset].vector,
+ bnx2x_msix_fp_int, 0,
+ bp->dev->name, &bp->fp[i]);
+ if (rc) {
+ BNX2X_ERR("request fp #%d irq failed rc %d\n",
+ i + offset, rc);
+ bnx2x_free_msix_irqs(bp);
+ return -EBUSY;
+ }
+
+ bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
+ }
+
+ return 0;
+}
+
+static int bnx2x_req_irq(struct bnx2x *bp)
+{
+ int rc;
+
+ rc = request_irq(bp->pdev->irq, bnx2x_interrupt, IRQF_SHARED,
+ bp->dev->name, bp->dev);
+ if (!rc)
+ bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
+
+ return rc;
+}
+
+/*
+ * Init service functions
+ */
+
+static void bnx2x_set_mac_addr_e1(struct bnx2x *bp)
+{
+ struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
+ int port = BP_PORT(bp);
+
+ /* CAM allocation
+ * unicasts 0-31:port0 32-63:port1
+ * multicast 64-127:port0 128-191:port1
+ */
+ config->hdr.length_6b = 2;
+ config->hdr.offset = port ? 31 : 0;
+ config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.reserved1 = 0;
+
+ /* primary MAC */
+ config->config_table[0].cam_entry.msb_mac_addr =
+ swab16(*(u16 *)&bp->dev->dev_addr[0]);
+ config->config_table[0].cam_entry.middle_mac_addr =
+ swab16(*(u16 *)&bp->dev->dev_addr[2]);
+ config->config_table[0].cam_entry.lsb_mac_addr =
+ swab16(*(u16 *)&bp->dev->dev_addr[4]);
+ config->config_table[0].cam_entry.flags = cpu_to_le16(port);
+ config->config_table[0].target_table_entry.flags = 0;
+ config->config_table[0].target_table_entry.client_id = 0;
+ config->config_table[0].target_table_entry.vlan_id = 0;
+
+ DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x)\n",
+ config->config_table[0].cam_entry.msb_mac_addr,
+ config->config_table[0].cam_entry.middle_mac_addr,
+ config->config_table[0].cam_entry.lsb_mac_addr);
+
+ /* broadcast */
+ config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
+ config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
+ config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
+ config->config_table[1].cam_entry.flags = cpu_to_le16(port);
+ config->config_table[1].target_table_entry.flags =
+ TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
+ config->config_table[1].target_table_entry.client_id = 0;
+ config->config_table[1].target_table_entry.vlan_id = 0;
+
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+ U64_HI(bnx2x_sp_mapping(bp, mac_config)),
+ U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+}
+
+static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp)
+{
+ struct mac_configuration_cmd_e1h *config =
+ (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
+
+ if (bp->state != BNX2X_STATE_OPEN) {
+ DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
+ return;
+ }
+
+ /* CAM allocation for E1H
+ * unicasts: by func number
+ * multicast: 20+FUNC*20, 20 each
+ */
+ config->hdr.length_6b = 1;
+ config->hdr.offset = BP_FUNC(bp);
+ config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.reserved1 = 0;
+
+ /* primary MAC */
+ config->config_table[0].msb_mac_addr =
+ swab16(*(u16 *)&bp->dev->dev_addr[0]);
+ config->config_table[0].middle_mac_addr =
+ swab16(*(u16 *)&bp->dev->dev_addr[2]);
+ config->config_table[0].lsb_mac_addr =
+ swab16(*(u16 *)&bp->dev->dev_addr[4]);
+ config->config_table[0].client_id = BP_L_ID(bp);
+ config->config_table[0].vlan_id = 0;
+ config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
+ config->config_table[0].flags = BP_PORT(bp);
+
+ DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x) E1HOV %d CLID %d\n",
+ config->config_table[0].msb_mac_addr,
+ config->config_table[0].middle_mac_addr,
+ config->config_table[0].lsb_mac_addr, bp->e1hov, BP_L_ID(bp));
+
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+ U64_HI(bnx2x_sp_mapping(bp, mac_config)),
+ U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+}
+
+static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
+ int *state_p, int poll)
+{
+ /* can take a while if any port is running */
+ int cnt = 500;
+
+ DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
+ poll ? "polling" : "waiting", state, idx);
+
+ might_sleep();
+ while (cnt--) {
+ if (poll) {
+ bnx2x_rx_int(bp->fp, 10);
+ /* if index is different from 0
+ * the reply for some commands will
+ * be on the none default queue
+ */
+ if (idx)
+ bnx2x_rx_int(&bp->fp[idx], 10);
+ }
+ mb(); /* state is changed by bnx2x_sp_event() */
+
+ if (*state_p == state)
+ return 0;
+
+ msleep(1);
+ }
+
+ /* timeout! */
+ BNX2X_ERR("timeout %s for state %x on IDX [%d]\n",
+ poll ? "polling" : "waiting", state, idx);
+#ifdef BNX2X_STOP_ON_ERROR
+ bnx2x_panic();
+#endif
+
+ return -EBUSY;
+}
+
+static int bnx2x_setup_leading(struct bnx2x *bp)
+{
+ int rc;
+
+ /* reset IGU state */
+ bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+
+ /* SETUP ramrod */
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0);
+
+ /* Wait for completion */
+ rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0);
+
+ return rc;
+}
+
+static int bnx2x_setup_multi(struct bnx2x *bp, int index)
+{
+ /* reset IGU state */
+ bnx2x_ack_sb(bp, bp->fp[index].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+
+ /* SETUP ramrod */
+ bp->fp[index].state = BNX2X_FP_STATE_OPENING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
+
+ /* Wait for completion */
+ return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
+ &(bp->fp[index].state), 0);
+}
+
+static int bnx2x_poll(struct napi_struct *napi, int budget);
+static void bnx2x_set_rx_mode(struct net_device *dev);
+
+/* must be called with rtnl_lock */
+static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
+{
+ u32 load_code;
+ int i, rc;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return -EPERM;
+#endif
+
+ bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+
+ /* Send LOAD_REQUEST command to MCP
+ Returns the type of LOAD command:
+ if it is the first port to be initialized
+ common blocks should be initialized, otherwise - not
+ */
+ if (!BP_NOMCP(bp)) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, unloading\n");
+ return -EBUSY;
+ }
+ if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
+ return -EBUSY; /* other port in diagnostic mode */
+
+ } else {
+ DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ load_count[0]++;
+ load_count[1 + BP_PORT(bp)]++;
+ DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ if (load_count[0] == 1)
+ load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
+ else if (load_count[1 + BP_PORT(bp)] == 1)
+ load_code = FW_MSG_CODE_DRV_LOAD_PORT;
+ else
+ load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
+ }
+
+ if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
+ bp->port.pmf = 1;
+ else
+ bp->port.pmf = 0;
+ DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
+
+ /* if we can't use MSI-X we only need one fp,
+ * so try to enable MSI-X with the requested number of fp's
+ * and fallback to inta with one fp
+ */
+ if (use_inta) {
+ bp->num_queues = 1;
+
+ } else {
+ if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
+ /* user requested number */
+ bp->num_queues = use_multi;
+
+ else if (use_multi)
+ bp->num_queues = min_t(u32, num_online_cpus(),
+ BP_MAX_QUEUES(bp));
+ else
+ bp->num_queues = 1;
+
+ if (bnx2x_enable_msix(bp)) {
+ /* failed to enable MSI-X */
+ bp->num_queues = 1;
+ if (use_multi)
+ BNX2X_ERR("Multi requested but failed"
+ " to enable MSI-X\n");
+ }
+ }
+ DP(NETIF_MSG_IFUP,
+ "set number of queues to %d\n", bp->num_queues);
+
+ if (bnx2x_alloc_mem(bp))
+ return -ENOMEM;
+
+ for_each_queue(bp, i)
+ bnx2x_fp(bp, i, disable_tpa) =
+ ((bp->flags & TPA_ENABLE_FLAG) == 0);
+
+ /* Disable interrupt handling until HW is initialized */
+ atomic_set(&bp->intr_sem, 1);
+
+ if (bp->flags & USING_MSIX_FLAG) {
+ rc = bnx2x_req_msix_irqs(bp);
+ if (rc) {
+ pci_disable_msix(bp->pdev);
+ goto load_error;
+ }
+ } else {
+ bnx2x_ack_int(bp);
+ rc = bnx2x_req_irq(bp);
+ if (rc) {
+ BNX2X_ERR("IRQ request failed, aborting\n");
+ goto load_error;
+ }
+ }
+
+ for_each_queue(bp, i)
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, 128);
+
+ /* Initialize HW */
+ rc = bnx2x_init_hw(bp, load_code);
+ if (rc) {
+ BNX2X_ERR("HW init failed, aborting\n");
+ goto load_error;
+ }
+
+ /* Enable interrupt handling */
+ atomic_set(&bp->intr_sem, 0);
+
+ /* Setup NIC internals and enable interrupts */
+ bnx2x_nic_init(bp);
+
+ /* Send LOAD_DONE command to MCP */
+ if (!BP_NOMCP(bp)) {
+ load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, unloading\n");
+ rc = -EBUSY;
+ goto load_int_disable;
+ }
+ }
+
+ bnx2x_stats_init(bp);
+
+ bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
+
+ /* Enable Rx interrupt handling before sending the ramrod
+ as it's completed on Rx FP queue */
+ for_each_queue(bp, i)
+ napi_enable(&bnx2x_fp(bp, i, napi));
+
+ rc = bnx2x_setup_leading(bp);
+ if (rc) {
+#ifdef BNX2X_STOP_ON_ERROR
+ bp->panic = 1;
+#endif
+ goto load_stop_netif;
+ }
+
+ if (CHIP_IS_E1H(bp))
+ if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
+ BNX2X_ERR("!!! mf_cfg function disabled\n");
+ bp->state = BNX2X_STATE_DISABLED;
+ }
+
+ if (bp->state == BNX2X_STATE_OPEN)
+ for_each_nondefault_queue(bp, i) {
+ rc = bnx2x_setup_multi(bp, i);
+ if (rc)
+ goto load_stop_netif;
+ }
+
+ if (CHIP_IS_E1(bp))
+ bnx2x_set_mac_addr_e1(bp);
+ else
+ bnx2x_set_mac_addr_e1h(bp);
+
+ if (bp->port.pmf)
+ bnx2x_initial_phy_init(bp);
+
+ /* Start fast path */
+ switch (load_mode) {
+ case LOAD_NORMAL:
+ /* Tx queue should be only reenabled */
+ netif_wake_queue(bp->dev);
+ bnx2x_set_rx_mode(bp->dev);
+ break;
+
+ case LOAD_OPEN:
+ /* IRQ is only requested from bnx2x_open */
+ netif_start_queue(bp->dev);
+ bnx2x_set_rx_mode(bp->dev);
+ if (bp->flags & USING_MSIX_FLAG)
+ printk(KERN_INFO PFX "%s: using MSI-X\n",
+ bp->dev->name);
+ break;
+
+ case LOAD_DIAG:
+ bnx2x_set_rx_mode(bp->dev);
+ bp->state = BNX2X_STATE_DIAG;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!bp->port.pmf)
+ bnx2x__link_status_update(bp);
+
+ /* start the timer */
+ mod_timer(&bp->timer, jiffies + bp->current_interval);
+
+
+ return 0;
+
+load_stop_netif:
+ for_each_queue(bp, i)
+ napi_disable(&bnx2x_fp(bp, i, napi));
+
+load_int_disable:
+ bnx2x_int_disable_sync(bp);
+
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
+ /* Free SKBs, SGEs, TPA pool and driver internals */
+ bnx2x_free_skbs(bp);
+ for_each_queue(bp, i)
+ bnx2x_free_rx_sge_range(bp, bp->fp + i,
+ RX_SGE_CNT*NUM_RX_SGE_PAGES);
+load_error:
+ bnx2x_free_mem(bp);
+
+ /* TBD we really need to reset the chip
+ if we want to recover from this */
+ return rc;
+}
+
+static int bnx2x_stop_multi(struct bnx2x *bp, int index)
+{
+ int rc;
+
+ /* halt the connection */
+ bp->fp[index].state = BNX2X_FP_STATE_HALTING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0);
+
+ /* Wait for completion */
+ rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
+ &(bp->fp[index].state), 1);
+ if (rc) /* timeout */
+ return rc;
+
+ /* delete cfc entry */
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
+
+ /* Wait for completion */
+ rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
+ &(bp->fp[index].state), 1);
+ return rc;
+}
+
+static void bnx2x_stop_leading(struct bnx2x *bp)
+{
+ u16 dsb_sp_prod_idx;
+ /* if the other port is handling traffic,
+ this can take a lot of time */
+ int cnt = 500;
+ int rc;
+
+ might_sleep();
+
+ /* Send HALT ramrod */
+ bp->fp[0].state = BNX2X_FP_STATE_HALTING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, BP_CL_ID(bp), 0);
+
+ /* Wait for completion */
+ rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
+ &(bp->fp[0].state), 1);
+ if (rc) /* timeout */
+ return;
+
+ dsb_sp_prod_idx = *bp->dsb_sp_prod;
+
+ /* Send PORT_DELETE ramrod */
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
+
+ /* Wait for completion to arrive on default status block
+ we are going to reset the chip anyway
+ so there is not much to do if this times out
+ */
+ while (dsb_sp_prod_idx == *bp->dsb_sp_prod) {
+ msleep(1);
+ if (!cnt) {
+ DP(NETIF_MSG_IFDOWN, "timeout waiting for port del "
+ "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
+ *bp->dsb_sp_prod, dsb_sp_prod_idx);
+#ifdef BNX2X_STOP_ON_ERROR
+ bnx2x_panic();
+#endif
+ break;
+ }
+ cnt--;
+ }
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
+ bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
+}
+
+static void bnx2x_reset_func(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int func = BP_FUNC(bp);
+ int base, i;
+
+ /* Configure IGU */
+ REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
+ REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
+
+ REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
+
+ /* Clear ILT */
+ base = FUNC_ILT_BASE(func);
+ for (i = base; i < base + ILT_PER_FUNC; i++)
+ bnx2x_ilt_wr(bp, i, 0);
+}
+
+static void bnx2x_reset_port(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ u32 val;
+
+ REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
+
+ /* Do not rcv packets to BRB */
+ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0);
+ /* Do not direct rcv packets that are not for MCP to the BRB */
+ REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP :
+ NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
+
+ /* Configure AEU */
+ REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0);
+
+ msleep(100);
+ /* Check for BRB port occupancy */
+ val = REG_RD(bp, BRB1_REG_PORT_NUM_OCC_BLOCKS_0 + port*4);
+ if (val)
+ DP(NETIF_MSG_IFDOWN,
+ "BRB1 is not empty %d blooks are occupied\n", val);
+
+ /* TODO: Close Doorbell port? */
+}
+
+static void bnx2x_reset_common(struct bnx2x *bp)
+{
+ /* reset_common */
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+ 0xd3ffff7f);
+ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
+}
+
+static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
+{
+ DP(BNX2X_MSG_MCP, "function %d reset_code %x\n",
+ BP_FUNC(bp), reset_code);
+
+ switch (reset_code) {
+ case FW_MSG_CODE_DRV_UNLOAD_COMMON:
+ bnx2x_reset_port(bp);
+ bnx2x_reset_func(bp);
+ bnx2x_reset_common(bp);
+ break;
+
+ case FW_MSG_CODE_DRV_UNLOAD_PORT:
+ bnx2x_reset_port(bp);
+ bnx2x_reset_func(bp);
+ break;
+
+ case FW_MSG_CODE_DRV_UNLOAD_FUNCTION:
+ bnx2x_reset_func(bp);
+ break;
+
+ default:
+ BNX2X_ERR("Unknown reset_code (0x%x) from MCP\n", reset_code);
+ break;
+ }
+}
+
+/* msut be called with rtnl_lock */
+static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
+{
+ u32 reset_code = 0;
+ int i, cnt;
+
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
+
+ bp->rx_mode = BNX2X_RX_MODE_NONE;
+ bnx2x_set_storm_rx_mode(bp);
+
+ if (netif_running(bp->dev)) {
+ netif_tx_disable(bp->dev);
+ bp->dev->trans_start = jiffies; /* prevent tx timeout */
+ }
+
+ del_timer_sync(&bp->timer);
+ SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
+ (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+
+ /* Wait until all fast path tasks complete */
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+#ifdef BNX2X_STOP_ON_ERROR
+#ifdef __powerpc64__
+ DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n",
+#else
+ DP(NETIF_MSG_IFDOWN, "fp->tpa_queue_used = 0x%llx\n",
+#endif
+ fp->tpa_queue_used);
+#endif
+ cnt = 1000;
+ smp_rmb();
+ while (bnx2x_has_work(fp)) {
+ msleep(1);
+ if (!cnt) {
+ BNX2X_ERR("timeout waiting for queue[%d]\n",
+ i);
+#ifdef BNX2X_STOP_ON_ERROR
+ bnx2x_panic();
+ return -EBUSY;
+#else
+ break;
+#endif
+ }
+ cnt--;
+ smp_rmb();
+ }
+ }
+
+ /* Wait until all slow path tasks complete */
+ cnt = 1000;
+ while ((bp->spq_left != MAX_SPQ_PENDING) && cnt--)
+ msleep(1);
+
+ for_each_queue(bp, i)
+ napi_disable(&bnx2x_fp(bp, i, napi));
+ /* Disable interrupts after Tx and Rx are disabled on stack level */
+ bnx2x_int_disable_sync(bp);
+
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
+ if (bp->flags & NO_WOL_FLAG)
+ reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
+
+ else if (bp->wol) {
+ u32 emac_base = BP_PORT(bp) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ u8 *mac_addr = bp->dev->dev_addr;
+ u32 val;
+
+ /* The mac address is written to entries 1-4 to
+ preserve entry 0 which is used by the PMF */
+ val = (mac_addr[0] << 8) | mac_addr[1];
+ EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + (BP_E1HVN(bp) + 1)*8, val);
+
+ val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
+ (mac_addr[4] << 8) | mac_addr[5];
+ EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + (BP_E1HVN(bp) + 1)*8 + 4,
+ val);
+
+ reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
+
+ } else
+ reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
+
+ /* Close multi and leading connections
+ Completions for ramrods are collected in a synchronous way */
+ for_each_nondefault_queue(bp, i)
+ if (bnx2x_stop_multi(bp, i))
+ goto unload_error;
+
+ if (CHIP_IS_E1H(bp))
+ REG_WR(bp, NIG_REG_LLH0_FUNC_EN + BP_PORT(bp)*8, 0);
+
+ bnx2x_stop_leading(bp);
+#ifdef BNX2X_STOP_ON_ERROR
+ /* If ramrod completion timed out - break here! */
+ if (bp->panic) {
+ BNX2X_ERR("Stop leading failed!\n");
+ return -EBUSY;
+ }
+#endif
+
+ if ((bp->state != BNX2X_STATE_CLOSING_WAIT4_UNLOAD) ||
+ (bp->fp[0].state != BNX2X_FP_STATE_CLOSED)) {
+ DP(NETIF_MSG_IFDOWN, "failed to close leading properly! "
+ "state 0x%x fp[0].state 0x%x\n",
+ bp->state, bp->fp[0].state);
+ }
+
+unload_error:
+ if (!BP_NOMCP(bp))
+ reset_code = bnx2x_fw_command(bp, reset_code);
+ else {
+ DP(NETIF_MSG_IFDOWN, "NO MCP load counts %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ load_count[0]--;
+ load_count[1 + BP_PORT(bp)]--;
+ DP(NETIF_MSG_IFDOWN, "NO MCP new load counts %d, %d, %d\n",
+ load_count[0], load_count[1], load_count[2]);
+ if (load_count[0] == 0)
+ reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
+ else if (load_count[1 + BP_PORT(bp)] == 0)
+ reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT;
+ else
+ reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION;
+ }
+
+ if ((reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) ||
+ (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT))
+ bnx2x__link_reset(bp);
+
+ /* Reset the chip */
+ bnx2x_reset_chip(bp, reset_code);
+
+ /* Report UNLOAD_DONE to MCP */
+ if (!BP_NOMCP(bp))
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
+ /* Free SKBs, SGEs, TPA pool and driver internals */
+ bnx2x_free_skbs(bp);
+ for_each_queue(bp, i)
+ bnx2x_free_rx_sge_range(bp, bp->fp + i,
+ RX_SGE_CNT*NUM_RX_SGE_PAGES);
+ bnx2x_free_mem(bp);
+
+ bp->state = BNX2X_STATE_CLOSED;
+
+ netif_carrier_off(bp->dev);
+
+ return 0;
+}
+
+static void bnx2x_reset_task(struct work_struct *work)
+{
+ struct bnx2x *bp = container_of(work, struct bnx2x, reset_task);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ BNX2X_ERR("reset task called but STOP_ON_ERROR defined"
+ " so reset not done to allow debug dump,\n"
+ KERN_ERR " you will need to reboot when done\n");
+ return;
+#endif
+
+ rtnl_lock();
+
+ if (!netif_running(bp->dev))
+ goto reset_task_exit;
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ bnx2x_nic_load(bp, LOAD_NORMAL);
+
+reset_task_exit:
+ rtnl_unlock();
+}
+
+/* end of nic load/unload */
+
+/* ethtool_ops */
+
+/*
+ * Init service functions
+ */
+
+static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
+{
+ u32 val;
+
+ /* Check if there is any driver already loaded */
+ val = REG_RD(bp, MISC_REG_UNPREPARED);
+ if (val == 0x1) {
+ /* Check if it is the UNDI driver
+ * UNDI driver initializes CID offset for normal bell to 0x7
+ */
+ val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
+ if (val == 0x7) {
+ u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
+ /* save our func and fw_seq */
+ int func = BP_FUNC(bp);
+ u16 fw_seq = bp->fw_seq;
+
+ BNX2X_DEV_INFO("UNDI is active! reset device\n");
+
+ /* try unload UNDI on port 0 */
+ bp->func = 0;
+ bp->fw_seq = (SHMEM_RD(bp,
+ func_mb[bp->func].drv_mb_header) &
+ DRV_MSG_SEQ_NUMBER_MASK);
+
+ reset_code = bnx2x_fw_command(bp, reset_code);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
+ /* if UNDI is loaded on the other port */
+ if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
+
+ bp->func = 1;
+ bp->fw_seq = (SHMEM_RD(bp,
+ func_mb[bp->func].drv_mb_header) &
+ DRV_MSG_SEQ_NUMBER_MASK);
+
+ bnx2x_fw_command(bp,
+ DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS);
+ bnx2x_fw_command(bp,
+ DRV_MSG_CODE_UNLOAD_DONE);
+
+ /* restore our func and fw_seq */
+ bp->func = func;
+ bp->fw_seq = fw_seq;
+ }
+
+ /* reset device */
+ REG_WR(bp,
+ GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+ 0xd3ffff7f);
+ REG_WR(bp,
+ GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+ 0x1403);
+ }
+ }
+}
+
+static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
+{
+ u32 val, val2, val3, val4, id;
+
+ /* Get the chip revision id and number. */
+ /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+ val = REG_RD(bp, MISC_REG_CHIP_NUM);
+ id = ((val & 0xffff) << 16);
+ val = REG_RD(bp, MISC_REG_CHIP_REV);
+ id |= ((val & 0xf) << 12);
+ val = REG_RD(bp, MISC_REG_CHIP_METAL);
+ id |= ((val & 0xff) << 4);
+ REG_RD(bp, MISC_REG_BOND_ID);
+ id |= (val & 0xf);
+ bp->common.chip_id = id;
+ bp->link_params.chip_id = bp->common.chip_id;
+ BNX2X_DEV_INFO("chip ID is 0x%x\n", id);
+
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
+ bp->common.flash_size = (NVRAM_1MB_SIZE <<
+ (val & MCPR_NVM_CFG4_FLASH_SIZE));
+ BNX2X_DEV_INFO("flash_size 0x%x (%d)\n",
+ bp->common.flash_size, bp->common.flash_size);
+
+ bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+ bp->link_params.shmem_base = bp->common.shmem_base;
+ BNX2X_DEV_INFO("shmem offset is 0x%x\n", bp->common.shmem_base);
+
+ if (!bp->common.shmem_base ||
+ (bp->common.shmem_base < 0xA0000) ||
+ (bp->common.shmem_base >= 0xC0000)) {
+ BNX2X_DEV_INFO("MCP not active\n");
+ bp->flags |= NO_MCP_FLAG;
+ return;
+ }
+
+ val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
+ if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
+ != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
+ BNX2X_ERR("BAD MCP validity signature\n");
+
+ bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
+ bp->common.board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
+
+ BNX2X_DEV_INFO("hw_config 0x%08x board 0x%08x\n",
+ bp->common.hw_config, bp->common.board);
+
+ bp->link_params.hw_led_mode = ((bp->common.hw_config &
+ SHARED_HW_CFG_LED_MODE_MASK) >>
+ SHARED_HW_CFG_LED_MODE_SHIFT);
+
+ val = SHMEM_RD(bp, dev_info.bc_rev) >> 8;
+ bp->common.bc_ver = val;
+ BNX2X_DEV_INFO("bc_ver %X\n", val);
+ if (val < BNX2X_BC_VER) {
+ /* for now only warn
+ * later we might need to enforce this */
+ BNX2X_ERR("This driver needs bc_ver %X but found %X,"
+ " please upgrade BC\n", BNX2X_BC_VER, val);
+ }
+ BNX2X_DEV_INFO("%sWoL Capable\n",
+ (bp->flags & NO_WOL_FLAG)? "Not " : "");
+
+ val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
+ val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
+ val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]);
+ val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]);
+
+ printk(KERN_INFO PFX "part number %X-%X-%X-%X\n",
+ val, val2, val3, val4);
+}
+
+static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
+ u32 switch_cfg)
+{
+ int port = BP_PORT(bp);
+ u32 ext_phy_type;
+
+ switch (switch_cfg) {
+ case SWITCH_CFG_1G:
+ BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg);
+
+ ext_phy_type =
+ SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_TP |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ default:
+ BNX2X_ERR("NVRAM config error. "
+ "BAD SerDes ext_phy_config 0x%x\n",
+ bp->link_params.ext_phy_config);
+ return;
+ }
+
+ bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR +
+ port*0x10);
+ BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
+ break;
+
+ case SWITCH_CFG_10G:
+ BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg);
+
+ ext_phy_type =
+ XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_2500baseX_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
+ bp->link_params.ext_phy_config);
+ break;
+
+ default:
+ BNX2X_ERR("NVRAM config error. "
+ "BAD XGXS ext_phy_config 0x%x\n",
+ bp->link_params.ext_phy_config);
+ return;
+ }
+
+ bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR +
+ port*0x18);
+ BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
+
+ break;
+
+ default:
+ BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
+ bp->port.link_config);
+ return;
+ }
+ bp->link_params.phy_addr = bp->port.phy_addr;
+
+ /* mask what we support according to speed_cap_mask */
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
+ bp->port.supported &= ~SUPPORTED_10baseT_Half;
+
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
+ bp->port.supported &= ~SUPPORTED_10baseT_Full;
+
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
+ bp->port.supported &= ~SUPPORTED_100baseT_Half;
+
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
+ bp->port.supported &= ~SUPPORTED_100baseT_Full;
+
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
+ bp->port.supported &= ~(SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full);
+
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
+ bp->port.supported &= ~SUPPORTED_2500baseX_Full;
+
+ if (!(bp->link_params.speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
+ bp->port.supported &= ~SUPPORTED_10000baseT_Full;
+
+ BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported);
+}
+
+static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
+{
+ bp->link_params.req_duplex = DUPLEX_FULL;
+
+ switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) {
+ case PORT_FEATURE_LINK_SPEED_AUTO:
+ if (bp->port.supported & SUPPORTED_Autoneg) {
+ bp->link_params.req_line_speed = SPEED_AUTO_NEG;
+ bp->port.advertising = bp->port.supported;
+ } else {
+ u32 ext_phy_type =
+ XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+
+ if ((ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+ (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
+ /* force 10G, no AN */
+ bp->link_params.req_line_speed = SPEED_10000;
+ bp->port.advertising =
+ (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ break;
+ }
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " Autoneg not supported\n",
+ bp->port.link_config);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_10M_FULL:
+ if (bp->port.supported & SUPPORTED_10baseT_Full) {
+ bp->link_params.req_line_speed = SPEED_10;
+ bp->port.advertising = (ADVERTISED_10baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_10M_HALF:
+ if (bp->port.supported & SUPPORTED_10baseT_Half) {
+ bp->link_params.req_line_speed = SPEED_10;
+ bp->link_params.req_duplex = DUPLEX_HALF;
+ bp->port.advertising = (ADVERTISED_10baseT_Half |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_100M_FULL:
+ if (bp->port.supported & SUPPORTED_100baseT_Full) {
+ bp->link_params.req_line_speed = SPEED_100;
+ bp->port.advertising = (ADVERTISED_100baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_100M_HALF:
+ if (bp->port.supported & SUPPORTED_100baseT_Half) {
+ bp->link_params.req_line_speed = SPEED_100;
+ bp->link_params.req_duplex = DUPLEX_HALF;
+ bp->port.advertising = (ADVERTISED_100baseT_Half |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_1G:
+ if (bp->port.supported & SUPPORTED_1000baseT_Full) {
+ bp->link_params.req_line_speed = SPEED_1000;
+ bp->port.advertising = (ADVERTISED_1000baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_2_5G:
+ if (bp->port.supported & SUPPORTED_2500baseX_Full) {
+ bp->link_params.req_line_speed = SPEED_2500;
+ bp->port.advertising = (ADVERTISED_2500baseX_Full |
+ ADVERTISED_TP);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ case PORT_FEATURE_LINK_SPEED_10G_CX4:
+ case PORT_FEATURE_LINK_SPEED_10G_KX4:
+ case PORT_FEATURE_LINK_SPEED_10G_KR:
+ if (bp->port.supported & SUPPORTED_10000baseT_Full) {
+ bp->link_params.req_line_speed = SPEED_10000;
+ bp->port.advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ } else {
+ BNX2X_ERR("NVRAM config error. "
+ "Invalid link_config 0x%x"
+ " speed_cap_mask 0x%x\n",
+ bp->port.link_config,
+ bp->link_params.speed_cap_mask);
+ return;
+ }
+ break;
+
+ default:
+ BNX2X_ERR("NVRAM config error. "
+ "BAD link speed link_config 0x%x\n",
+ bp->port.link_config);
+ bp->link_params.req_line_speed = SPEED_AUTO_NEG;
+ bp->port.advertising = bp->port.supported;
+ break;
+ }
+
+ bp->link_params.req_flow_ctrl = (bp->port.link_config &
+ PORT_FEATURE_FLOW_CONTROL_MASK);
+ if ((bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO) &&
+ (!bp->port.supported & SUPPORTED_Autoneg))
+ bp->link_params.req_flow_ctrl = FLOW_CTRL_NONE;
+
+ BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x"
+ " advertising 0x%x\n",
+ bp->link_params.req_line_speed,
+ bp->link_params.req_duplex,
+ bp->link_params.req_flow_ctrl, bp->port.advertising);
+}
+
+static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ u32 val, val2;
+
+ bp->link_params.bp = bp;
+ bp->link_params.port = port;
+
+ bp->link_params.serdes_config =
+ SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
+ bp->link_params.lane_config =
+ SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
+ bp->link_params.ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+ bp->link_params.speed_cap_mask =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].speed_capability_mask);
+
+ bp->port.link_config =
+ SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
+
+ BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n"
+ KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x"
+ " link_config 0x%08x\n",
+ bp->link_params.serdes_config,
+ bp->link_params.lane_config,
+ bp->link_params.ext_phy_config,
+ bp->link_params.speed_cap_mask, bp->port.link_config);
+
+ bp->link_params.switch_cfg = (bp->port.link_config &
+ PORT_FEATURE_CONNECTED_SWITCH_MASK);
+ bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);
+
+ bnx2x_link_settings_requested(bp);
+
+ val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
+ val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
+ bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
+ bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
+ bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
+ bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
+ bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
+ bp->dev->dev_addr[5] = (u8)(val & 0xff);
+ memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
+ memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
+}
+
+static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+ u32 val, val2;
+ int rc = 0;
+
+ bnx2x_get_common_hwinfo(bp);
+
+ bp->e1hov = 0;
+ bp->e1hmf = 0;
+ if (CHIP_IS_E1H(bp)) {
+ bp->mf_config =
+ SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+
+ val =
+ (SHMEM_RD(bp, mf_cfg.func_mf_config[func].e1hov_tag) &
+ FUNC_MF_CFG_E1HOV_TAG_MASK);
+ if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
+
+ bp->e1hov = val;
+ bp->e1hmf = 1;
+ BNX2X_DEV_INFO("MF mode E1HOV for func %d is %d "
+ "(0x%04x)\n",
+ func, bp->e1hov, bp->e1hov);
+ } else {
+ BNX2X_DEV_INFO("Single function mode\n");
+ if (BP_E1HVN(bp)) {
+ BNX2X_ERR("!!! No valid E1HOV for func %d,"
+ " aborting\n", func);
+ rc = -EPERM;
+ }
+ }
+ }
+
+ if (!BP_NOMCP(bp)) {
+ bnx2x_get_port_hwinfo(bp);
+
+ bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) &
+ DRV_MSG_SEQ_NUMBER_MASK);
+ BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
+ }
+
+ if (IS_E1HMF(bp)) {
+ val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper);
+ val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower);
+ if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) &&
+ (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) {
+ bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
+ bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
+ bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
+ bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
+ bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
+ bp->dev->dev_addr[5] = (u8)(val & 0xff);
+ memcpy(bp->link_params.mac_addr, bp->dev->dev_addr,
+ ETH_ALEN);
+ memcpy(bp->dev->perm_addr, bp->dev->dev_addr,
+ ETH_ALEN);
+ }
+
+ return rc;
+ }
+
+ if (BP_NOMCP(bp)) {
+ /* only supposed to happen on emulation/FPGA */
+ BNX2X_ERR("warning rendom MAC workaround active\n");
+ random_ether_addr(bp->dev->dev_addr);
+ memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
+ }
+
+ return rc;
+}
+
+static int __devinit bnx2x_init_bp(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+ int rc;
+
+ if (nomcp)
+ bp->flags |= NO_MCP_FLAG;
+
+ mutex_init(&bp->port.phy_mutex);
+
+ INIT_WORK(&bp->sp_task, bnx2x_sp_task);
+ INIT_WORK(&bp->reset_task, bnx2x_reset_task);
+
+ rc = bnx2x_get_hwinfo(bp);
+
+ /* need to reset chip if undi was active */
+ if (!BP_NOMCP(bp))
+ bnx2x_undi_unload(bp);
+
+ if (CHIP_REV_IS_FPGA(bp))
+ printk(KERN_ERR PFX "FPGA detected\n");
+
+ if (BP_NOMCP(bp) && (func == 0))
+ printk(KERN_ERR PFX
+ "MCP disabled, must load devices in order!\n");
+
+ /* Set TPA flags */
+ if (disable_tpa) {
+ bp->flags &= ~TPA_ENABLE_FLAG;
+ bp->dev->features &= ~NETIF_F_LRO;
+ } else {
+ bp->flags |= TPA_ENABLE_FLAG;
+ bp->dev->features |= NETIF_F_LRO;
+ }
+
+
+ bp->tx_ring_size = MAX_TX_AVAIL;
+ bp->rx_ring_size = MAX_RX_AVAIL;
+
+ bp->rx_csum = 1;
+ bp->rx_offset = 0;
+
+ bp->tx_ticks = 50;
+ bp->rx_ticks = 25;
+
+ bp->stats_ticks = 1000000 & 0xffff00;
+
+ bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
+ bp->current_interval = (poll ? poll : bp->timer_interval);
+
+ init_timer(&bp->timer);
+ bp->timer.expires = jiffies + bp->current_interval;
+ bp->timer.data = (unsigned long) bp;
+ bp->timer.function = bnx2x_timer;
+
+ return rc;
+}
+
+/*
+ * ethtool service functions
+ */
+
+/* All ethtool functions called with rtnl_lock */
+
+static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ cmd->supported = bp->port.supported;
+ cmd->advertising = bp->port.advertising;
+
+ if (netif_carrier_ok(dev)) {
+ cmd->speed = bp->link_vars.line_speed;
+ cmd->duplex = bp->link_vars.duplex;
+ } else {
+ cmd->speed = bp->link_params.req_line_speed;
+ cmd->duplex = bp->link_params.req_duplex;
+ }
+ if (IS_E1HMF(bp)) {
+ u16 vn_max_rate;
+
+ vn_max_rate = ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
+ if (vn_max_rate < cmd->speed)
+ cmd->speed = vn_max_rate;
+ }
+
+ if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
+ u32 ext_phy_type =
+ XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ cmd->port = PORT_FIBRE;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ cmd->port = PORT_TP;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
+ BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
+ bp->link_params.ext_phy_config);
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+ bp->link_params.ext_phy_config);
+ break;
+ }
+ } else
+ cmd->port = PORT_TP;
+
+ cmd->phy_address = bp->port.phy_addr;
+ cmd->transceiver = XCVR_INTERNAL;
+
+ if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
+ cmd->autoneg = AUTONEG_ENABLE;
+ else
+ cmd->autoneg = AUTONEG_DISABLE;
+
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+
+ DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
+ DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
+ DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
+ DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
+ cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+ cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+ cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+ return 0;
+}
+
+static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 advertising;
+
+ if (IS_E1HMF(bp))
+ return 0;
+
+ DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
+ DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
+ DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
+ DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
+ cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+ cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+ cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+ if (cmd->autoneg == AUTONEG_ENABLE) {
+ if (!(bp->port.supported & SUPPORTED_Autoneg)) {
+ DP(NETIF_MSG_LINK, "Autoneg not supported\n");
+ return -EINVAL;
+ }
+
+ /* advertise the requested speed and duplex if supported */
+ cmd->advertising &= bp->port.supported;
+
+ bp->link_params.req_line_speed = SPEED_AUTO_NEG;
+ bp->link_params.req_duplex = DUPLEX_FULL;
+ bp->port.advertising |= (ADVERTISED_Autoneg |
+ cmd->advertising);
+
+ } else { /* forced speed */
+ /* advertise the requested speed and duplex if supported */
+ switch (cmd->speed) {
+ case SPEED_10:
+ if (cmd->duplex == DUPLEX_FULL) {
+ if (!(bp->port.supported &
+ SUPPORTED_10baseT_Full)) {
+ DP(NETIF_MSG_LINK,
+ "10M full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_10baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ if (!(bp->port.supported &
+ SUPPORTED_10baseT_Half)) {
+ DP(NETIF_MSG_LINK,
+ "10M half not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_10baseT_Half |
+ ADVERTISED_TP);
+ }
+ break;
+
+ case SPEED_100:
+ if (cmd->duplex == DUPLEX_FULL) {
+ if (!(bp->port.supported &
+ SUPPORTED_100baseT_Full)) {
+ DP(NETIF_MSG_LINK,
+ "100M full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_100baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ if (!(bp->port.supported &
+ SUPPORTED_100baseT_Half)) {
+ DP(NETIF_MSG_LINK,
+ "100M half not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_100baseT_Half |
+ ADVERTISED_TP);
+ }
+ break;
+
+ case SPEED_1000:
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK, "1G half not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) {
+ DP(NETIF_MSG_LINK, "1G full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_1000baseT_Full |
+ ADVERTISED_TP);
+ break;
+
+ case SPEED_2500:
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK,
+ "2.5G half not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) {
+ DP(NETIF_MSG_LINK,
+ "2.5G full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_2500baseX_Full |
+ ADVERTISED_TP);
+ break;
+
+ case SPEED_10000:
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(NETIF_MSG_LINK, "10G half not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) {
+ DP(NETIF_MSG_LINK, "10G full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "Unsupported speed\n");
+ return -EINVAL;
+ }
+
+ bp->link_params.req_line_speed = cmd->speed;
+ bp->link_params.req_duplex = cmd->duplex;
+ bp->port.advertising = advertising;
+ }
+
+ DP(NETIF_MSG_LINK, "req_line_speed %d\n"
+ DP_LEVEL " req_duplex %d advertising 0x%x\n",
+ bp->link_params.req_line_speed, bp->link_params.req_duplex,
+ bp->port.advertising);
+
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+#define PHY_FW_VER_LEN 10
+
+static void bnx2x_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ char phy_fw_ver[PHY_FW_VER_LEN];
+
+ strcpy(info->driver, DRV_MODULE_NAME);
+ strcpy(info->version, DRV_MODULE_VERSION);
+
+ phy_fw_ver[0] = '\0';
+ if (bp->port.pmf) {
+ bnx2x_phy_hw_lock(bp);
+ bnx2x_get_ext_phy_fw_version(&bp->link_params,
+ (bp->state != BNX2X_STATE_CLOSED),
+ phy_fw_ver, PHY_FW_VER_LEN);
+ bnx2x_phy_hw_unlock(bp);
+ }
+
+ snprintf(info->fw_version, 32, "%d.%d.%d:%d BC:%x%s%s",
+ BCM_5710_FW_MAJOR_VERSION, BCM_5710_FW_MINOR_VERSION,
+ BCM_5710_FW_REVISION_VERSION,
+ BCM_5710_FW_COMPILE_FLAGS, bp->common.bc_ver,
+ ((phy_fw_ver[0] != '\0')? " PHY:":""), phy_fw_ver);
+ strcpy(info->bus_info, pci_name(bp->pdev));
+ info->n_stats = BNX2X_NUM_STATS;
+ info->testinfo_len = BNX2X_NUM_TESTS;
+ info->eedump_len = bp->common.flash_size;
+ info->regdump_len = 0;
+}
+
+static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (bp->flags & NO_WOL_FLAG) {
+ wol->supported = 0;
+ wol->wolopts = 0;
+ } else {
+ wol->supported = WAKE_MAGIC;
+ if (bp->wol)
+ wol->wolopts = WAKE_MAGIC;
+ else
+ wol->wolopts = 0;
+ }
+ memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+ return -EINVAL;
+
+ if (wol->wolopts & WAKE_MAGIC) {
+ if (bp->flags & NO_WOL_FLAG)
+ return -EINVAL;
+
+ bp->wol = 1;
+ } else
+ bp->wol = 0;
+
+ return 0;
+}
+
+static u32 bnx2x_get_msglevel(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ return bp->msglevel;
+}
+
+static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (capable(CAP_NET_ADMIN))
+ bp->msglevel = level;
+}
+
+static int bnx2x_nway_reset(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (!bp->port.pmf)
+ return 0;
+
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+static int bnx2x_get_eeprom_len(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ return bp->common.flash_size;
+}
+
+static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int count, i;
+ u32 val = 0;
+
+ /* adjust timeout for emulation/FPGA */
+ count = NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* request access to nvram interface */
+ REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+ (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port));
+
+ for (i = 0; i < count*10; i++) {
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
+ if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))
+ break;
+
+ udelay(5);
+ }
+
+ if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
+ DP(BNX2X_MSG_NVM, "cannot get access to nvram interface\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int bnx2x_release_nvram_lock(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int count, i;
+ u32 val = 0;
+
+ /* adjust timeout for emulation/FPGA */
+ count = NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* relinquish nvram interface */
+ REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+ (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port));
+
+ for (i = 0; i < count*10; i++) {
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
+ if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)))
+ break;
+
+ udelay(5);
+ }
+
+ if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) {
+ DP(BNX2X_MSG_NVM, "cannot free access to nvram interface\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static void bnx2x_enable_nvram_access(struct bnx2x *bp)
+{
+ u32 val;
+
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
+
+ /* enable both bits, even on read */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
+ (val | MCPR_NVM_ACCESS_ENABLE_EN |
+ MCPR_NVM_ACCESS_ENABLE_WR_EN));
+}
+
+static void bnx2x_disable_nvram_access(struct bnx2x *bp)
+{
+ u32 val;
+
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
+
+ /* disable both bits, even after read */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
+ (val & ~(MCPR_NVM_ACCESS_ENABLE_EN |
+ MCPR_NVM_ACCESS_ENABLE_WR_EN)));
+}
+
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
+ u32 cmd_flags)
+{
+ int count, i, rc;
+ u32 val;
+
+ /* build the command word */
+ cmd_flags |= MCPR_NVM_COMMAND_DOIT;
+
+ /* need to clear DONE bit separately */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
+
+ /* address of the NVRAM to read from */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
+ (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
+
+ /* issue a read command */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
+
+ /* adjust timeout for emulation/FPGA */
+ count = NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* wait for completion */
+ *ret_val = 0;
+ rc = -EBUSY;
+ for (i = 0; i < count; i++) {
+ udelay(5);
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
+
+ if (val & MCPR_NVM_COMMAND_DONE) {
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_READ);
+ /* we read nvram data in cpu order
+ * but ethtool sees it as an array of bytes
+ * converting to big-endian will do the work */
+ val = cpu_to_be32(val);
+ *ret_val = val;
+ rc = 0;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
+ int buf_size)
+{
+ int rc;
+ u32 cmd_flags;
+ u32 val;
+
+ if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
+ DP(BNX2X_MSG_NVM,
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
+ offset, buf_size);
+ return -EINVAL;
+ }
+
+ if (offset + buf_size > bp->common.flash_size) {
+ DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
+ " buf_size (0x%x) > flash_size (0x%x)\n",
+ offset, buf_size, bp->common.flash_size);
+ return -EINVAL;
+ }
+
+ /* request access to nvram interface */
+ rc = bnx2x_acquire_nvram_lock(bp);
+ if (rc)
+ return rc;
+
+ /* enable access to nvram interface */
+ bnx2x_enable_nvram_access(bp);
+
+ /* read the first word(s) */
+ cmd_flags = MCPR_NVM_COMMAND_FIRST;
+ while ((buf_size > sizeof(u32)) && (rc == 0)) {
+ rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
+ memcpy(ret_buf, &val, 4);
+
+ /* advance to the next dword */
+ offset += sizeof(u32);
+ ret_buf += sizeof(u32);
+ buf_size -= sizeof(u32);
+ cmd_flags = 0;
+ }
+
+ if (rc == 0) {
+ cmd_flags |= MCPR_NVM_COMMAND_LAST;
+ rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
+ memcpy(ret_buf, &val, 4);
+ }
+
+ /* disable access to nvram interface */
+ bnx2x_disable_nvram_access(bp);
+ bnx2x_release_nvram_lock(bp);
+
+ return rc;
+}
+
+static int bnx2x_get_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *eebuf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc;
+
+ DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
+ DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
+ eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
+ eeprom->len, eeprom->len);
+
+ /* parameters already validated in ethtool_get_eeprom */
+
+ rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
+
+ return rc;
+}
+
+static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
+ u32 cmd_flags)
+{
+ int count, i, rc;
+
+ /* build the command word */
+ cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
+
+ /* need to clear DONE bit separately */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
+
+ /* write the data */
+ REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val);
+
+ /* address of the NVRAM to write to */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
+ (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
+
+ /* issue the write command */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
+
+ /* adjust timeout for emulation/FPGA */
+ count = NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* wait for completion */
+ rc = -EBUSY;
+ for (i = 0; i < count; i++) {
+ udelay(5);
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
+ if (val & MCPR_NVM_COMMAND_DONE) {
+ rc = 0;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
+
+static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
+ int buf_size)
+{
+ int rc;
+ u32 cmd_flags;
+ u32 align_offset;
+ u32 val;
+
+ if (offset + buf_size > bp->common.flash_size) {
+ DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
+ " buf_size (0x%x) > flash_size (0x%x)\n",
+ offset, buf_size, bp->common.flash_size);
+ return -EINVAL;
+ }
+
+ /* request access to nvram interface */
+ rc = bnx2x_acquire_nvram_lock(bp);
+ if (rc)
+ return rc;
+
+ /* enable access to nvram interface */
+ bnx2x_enable_nvram_access(bp);
+
+ cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST);
+ align_offset = (offset & ~0x03);
+ rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags);
+
+ if (rc == 0) {
+ val &= ~(0xff << BYTE_OFFSET(offset));
+ val |= (*data_buf << BYTE_OFFSET(offset));
+
+ /* nvram data is returned as an array of bytes
+ * convert it back to cpu order */
+ val = be32_to_cpu(val);
+
+ rc = bnx2x_nvram_write_dword(bp, align_offset, val,
+ cmd_flags);
+ }
+
+ /* disable access to nvram interface */
+ bnx2x_disable_nvram_access(bp);
+ bnx2x_release_nvram_lock(bp);
+
+ return rc;
+}
+
+static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
+ int buf_size)
+{
+ int rc;
+ u32 cmd_flags;
+ u32 val;
+ u32 written_so_far;
+
+ if (buf_size == 1) /* ethtool */
+ return bnx2x_nvram_write1(bp, offset, data_buf, buf_size);
+
+ if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
+ DP(BNX2X_MSG_NVM,
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
+ offset, buf_size);
+ return -EINVAL;
+ }
+
+ if (offset + buf_size > bp->common.flash_size) {
+ DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
+ " buf_size (0x%x) > flash_size (0x%x)\n",
+ offset, buf_size, bp->common.flash_size);
+ return -EINVAL;
+ }
+
+ /* request access to nvram interface */
+ rc = bnx2x_acquire_nvram_lock(bp);
+ if (rc)
+ return rc;
+
+ /* enable access to nvram interface */
+ bnx2x_enable_nvram_access(bp);
+
+ written_so_far = 0;
+ cmd_flags = MCPR_NVM_COMMAND_FIRST;
+ while ((written_so_far < buf_size) && (rc == 0)) {
+ if (written_so_far == (buf_size - sizeof(u32)))
+ cmd_flags |= MCPR_NVM_COMMAND_LAST;
+ else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0)
+ cmd_flags |= MCPR_NVM_COMMAND_LAST;
+ else if ((offset % NVRAM_PAGE_SIZE) == 0)
+ cmd_flags |= MCPR_NVM_COMMAND_FIRST;
+
+ memcpy(&val, data_buf, 4);
+
+ rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags);
+
+ /* advance to the next dword */
+ offset += sizeof(u32);
+ data_buf += sizeof(u32);
+ written_so_far += sizeof(u32);
+ cmd_flags = 0;
+ }
+
+ /* disable access to nvram interface */
+ bnx2x_disable_nvram_access(bp);
+ bnx2x_release_nvram_lock(bp);
+
+ return rc;
+}
+
+static int bnx2x_set_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *eebuf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc;
+
+ DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
+ DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
+ eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
+ eeprom->len, eeprom->len);
+
+ /* parameters already validated in ethtool_set_eeprom */
+
+ /* If the magic number is PHY (0x00504859) upgrade the PHY FW */
+ if (eeprom->magic == 0x00504859)
+ if (bp->port.pmf) {
+
+ bnx2x_phy_hw_lock(bp);
+ rc = bnx2x_flash_download(bp, BP_PORT(bp),
+ bp->link_params.ext_phy_config,
+ (bp->state != BNX2X_STATE_CLOSED),
+ eebuf, eeprom->len);
+ if ((bp->state == BNX2X_STATE_OPEN) ||
+ (bp->state == BNX2X_STATE_DISABLED)) {
+ rc |= bnx2x_link_reset(&bp->link_params,
+ &bp->link_vars);
+ rc |= bnx2x_phy_init(&bp->link_params,
+ &bp->link_vars);
+ }
+ bnx2x_phy_hw_unlock(bp);
+
+ } else /* Only the PMF can access the PHY */
+ return -EINVAL;
+ else
+ rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
+
+ return rc;
+}
+
+static int bnx2x_get_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *coal)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ memset(coal, 0, sizeof(struct ethtool_coalesce));
+
+ coal->rx_coalesce_usecs = bp->rx_ticks;
+ coal->tx_coalesce_usecs = bp->tx_ticks;
+ coal->stats_block_coalesce_usecs = bp->stats_ticks;
+
+ return 0;
+}
+
+static int bnx2x_set_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *coal)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
+ if (bp->rx_ticks > 3000)
+ bp->rx_ticks = 3000;
+
+ bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
+ if (bp->tx_ticks > 0x3000)
+ bp->tx_ticks = 0x3000;
+
+ bp->stats_ticks = coal->stats_block_coalesce_usecs;
+ if (bp->stats_ticks > 0xffff00)
+ bp->stats_ticks = 0xffff00;
+ bp->stats_ticks &= 0xffff00;
+
+ if (netif_running(dev))
+ bnx2x_update_coalesce(bp);
+
+ return 0;
+}
+
+static int bnx2x_set_flags(struct net_device *dev, u32 data)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int changed = 0;
+ int rc = 0;
+
+ if (data & ETH_FLAG_LRO) {
+ if (!(dev->features & NETIF_F_LRO)) {
+ dev->features |= NETIF_F_LRO;
+ bp->flags |= TPA_ENABLE_FLAG;
+ changed = 1;
+ }
+
+ } else if (dev->features & NETIF_F_LRO) {
+ dev->features &= ~NETIF_F_LRO;
+ bp->flags &= ~TPA_ENABLE_FLAG;
+ changed = 1;
+ }
+
+ if (changed && netif_running(dev)) {
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ }
+
+ return rc;
+}
+
+static void bnx2x_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ ering->rx_max_pending = MAX_RX_AVAIL;
+ ering->rx_mini_max_pending = 0;
+ ering->rx_jumbo_max_pending = 0;
+
+ ering->rx_pending = bp->rx_ring_size;
+ ering->rx_mini_pending = 0;
+ ering->rx_jumbo_pending = 0;
+
+ ering->tx_max_pending = MAX_TX_AVAIL;
+ ering->tx_pending = bp->tx_ring_size;
+}
+
+static int bnx2x_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc = 0;
+
+ if ((ering->rx_pending > MAX_RX_AVAIL) ||
+ (ering->tx_pending > MAX_TX_AVAIL) ||
+ (ering->tx_pending <= MAX_SKB_FRAGS + 4))
+ return -EINVAL;
+
+ bp->rx_ring_size = ering->rx_pending;
+ bp->tx_ring_size = ering->tx_pending;
+
+ if (netif_running(dev)) {
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ }
+
+ return rc;
+}
+
+static void bnx2x_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ epause->autoneg = (bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO) &&
+ (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
+
+ epause->rx_pause = ((bp->link_vars.flow_ctrl & FLOW_CTRL_RX) ==
+ FLOW_CTRL_RX);
+ epause->tx_pause = ((bp->link_vars.flow_ctrl & FLOW_CTRL_TX) ==
+ FLOW_CTRL_TX);
+
+ DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
+ DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
+ epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
+}
+
+static int bnx2x_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (IS_E1HMF(bp))
+ return 0;
+
+ DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
+ DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
+ epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
+
+ bp->link_params.req_flow_ctrl = FLOW_CTRL_AUTO;
+
+ if (epause->rx_pause)
+ bp->link_params.req_flow_ctrl |= FLOW_CTRL_RX;
+
+ if (epause->tx_pause)
+ bp->link_params.req_flow_ctrl |= FLOW_CTRL_TX;
+
+ if (bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO)
+ bp->link_params.req_flow_ctrl = FLOW_CTRL_NONE;
+
+ if (epause->autoneg) {
+ if (!(bp->port.supported & SUPPORTED_Autoneg)) {
+ DP(NETIF_MSG_LINK, "Autoneg not supported\n");
+ return -EINVAL;
+ }
+
+ if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
+ bp->link_params.req_flow_ctrl = FLOW_CTRL_AUTO;
+ }
+
+ DP(NETIF_MSG_LINK,
+ "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
+
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+static u32 bnx2x_get_rx_csum(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ return bp->rx_csum;
+}
+
+static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ bp->rx_csum = data;
+ return 0;
+}
+
+static int bnx2x_set_tso(struct net_device *dev, u32 data)
+{
+ if (data) {
+ dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
+ dev->features |= NETIF_F_TSO6;
+ } else {
+ dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
+ dev->features &= ~NETIF_F_TSO6;
+ }
+
+ return 0;
+}
+
+static const struct {
+ char string[ETH_GSTRING_LEN];
+} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
+ { "register_test (offline)" },
+ { "memory_test (offline)" },
+ { "loopback_test (offline)" },
+ { "nvram_test (online)" },
+ { "interrupt_test (online)" },
+ { "link_test (online)" },
+ { "idle check (online)" },
+ { "MC errors (online)" }
+};
+
+static int bnx2x_self_test_count(struct net_device *dev)
+{
+ return BNX2X_NUM_TESTS;
+}
+
+static int bnx2x_test_registers(struct bnx2x *bp)
+{
+ int idx, i, rc = -ENODEV;
+ u32 wr_val = 0;
+ static const struct {
+ u32 offset0;
+ u32 offset1;
+ u32 mask;
+ } reg_tbl[] = {
+/* 0 */ { BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff },
+ { DORQ_REG_DB_ADDR0, 4, 0xffffffff },
+ { HC_REG_AGG_INT_0, 4, 0x000003ff },
+ { PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 },
+ { PBF_REG_P0_INIT_CRD, 4, 0x000007ff },
+ { PRS_REG_CID_PORT_0, 4, 0x00ffffff },
+ { PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff },
+ { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff },
+ { PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff },
+ { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff },
+/* 10 */ { PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff },
+ { QM_REG_CONNNUM_0, 4, 0x000fffff },
+ { TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff },
+ { SRC_REG_KEYRSS0_0, 40, 0xffffffff },
+ { SRC_REG_KEYRSS0_7, 40, 0xffffffff },
+ { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
+ { XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 },
+ { XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff },
+ { NIG_REG_EGRESS_MNG0_FIFO, 20, 0xffffffff },
+ { NIG_REG_LLH0_T_BIT, 4, 0x00000001 },
+/* 20 */ { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 },
+ { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 },
+ { NIG_REG_XCM0_OUT_EN, 4, 0x00000001 },
+ { NIG_REG_BRB0_OUT_EN, 4, 0x00000001 },
+ { NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 },
+ { NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff },
+ { NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff },
+ { NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff },
+ { NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff },
+ { NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 },
+/* 30 */ { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff },
+ { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff },
+ { NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff },
+ { NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 },
+ { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 },
+ { NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff },
+ { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 },
+ { NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f },
+
+ { 0xffffffff, 0, 0x00000000 }
+ };
+
+ if (!netif_running(bp->dev))
+ return rc;
+
+ /* Repeat the test twice:
+ First by writing 0x00000000, second by writing 0xffffffff */
+ for (idx = 0; idx < 2; idx++) {
+
+ switch (idx) {
+ case 0:
+ wr_val = 0;
+ break;
+ case 1:
+ wr_val = 0xffffffff;
+ break;
+ }
+
+ for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
+ u32 offset, mask, save_val, val;
+ int port = BP_PORT(bp);
+
+ offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
+ mask = reg_tbl[i].mask;
+
+ save_val = REG_RD(bp, offset);
+
+ REG_WR(bp, offset, wr_val);
+ val = REG_RD(bp, offset);
+
+ /* Restore the original register's value */
+ REG_WR(bp, offset, save_val);
+
+ /* verify that value is as expected value */
+ if ((val & mask) != (wr_val & mask))
+ goto test_reg_exit;
+ }
+ }
+
+ rc = 0;
+
+test_reg_exit:
+ return rc;
+}
+
+static int bnx2x_test_memory(struct bnx2x *bp)
+{
+ int i, j, rc = -ENODEV;
+ u32 val;
+ static const struct {
+ u32 offset;
+ int size;
+ } mem_tbl[] = {
+ { CCM_REG_XX_DESCR_TABLE, CCM_REG_XX_DESCR_TABLE_SIZE },
+ { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE },
+ { CFC_REG_LINK_LIST, CFC_REG_LINK_LIST_SIZE },
+ { DMAE_REG_CMD_MEM, DMAE_REG_CMD_MEM_SIZE },
+ { TCM_REG_XX_DESCR_TABLE, TCM_REG_XX_DESCR_TABLE_SIZE },
+ { UCM_REG_XX_DESCR_TABLE, UCM_REG_XX_DESCR_TABLE_SIZE },
+ { XCM_REG_XX_DESCR_TABLE, XCM_REG_XX_DESCR_TABLE_SIZE },
+
+ { 0xffffffff, 0 }
+ };
+ static const struct {
+ char *name;
+ u32 offset;
+ u32 mask;
+ } prty_tbl[] = {
+ { "CCM_REG_CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0 },
+ { "CFC_REG_CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0 },
+ { "DMAE_REG_DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0 },
+ { "TCM_REG_TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0 },
+ { "UCM_REG_UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0 },
+ { "XCM_REG_XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x1 },
+
+ { NULL, 0xffffffff, 0 }
+ };
+
+ if (!netif_running(bp->dev))
+ return rc;
+
+ /* Go through all the memories */
+ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
+ for (j = 0; j < mem_tbl[i].size; j++)
+ REG_RD(bp, mem_tbl[i].offset + j*4);
+
+ /* Check the parity status */
+ for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
+ val = REG_RD(bp, prty_tbl[i].offset);
+ if (val & ~(prty_tbl[i].mask)) {
+ DP(NETIF_MSG_HW,
+ "%s is 0x%x\n", prty_tbl[i].name, val);
+ goto test_mem_exit;
+ }
+ }
+
+ rc = 0;
+
+test_mem_exit:
+ return rc;
+}
+
+static void bnx2x_netif_start(struct bnx2x *bp)
+{
+ int i;
+
+ if (atomic_dec_and_test(&bp->intr_sem)) {
+ if (netif_running(bp->dev)) {
+ bnx2x_int_enable(bp);
+ for_each_queue(bp, i)
+ napi_enable(&bnx2x_fp(bp, i, napi));
+ if (bp->state == BNX2X_STATE_OPEN)
+ netif_wake_queue(bp->dev);
+ }
+ }
+}
+
+static void bnx2x_netif_stop(struct bnx2x *bp)
+{
+ int i;
+
+ if (netif_running(bp->dev)) {
+ netif_tx_disable(bp->dev);
+ bp->dev->trans_start = jiffies; /* prevent tx timeout */
+ for_each_queue(bp, i)
+ napi_disable(&bnx2x_fp(bp, i, napi));
+ }
+ bnx2x_int_disable_sync(bp);
+}
+
+static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up)
+{
+ int cnt = 1000;
+
+ if (link_up)
+ while (bnx2x_link_test(bp) && cnt--)
+ msleep(10);
+}
+
+static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
+{
+ unsigned int pkt_size, num_pkts, i;
+ struct sk_buff *skb;
+ unsigned char *packet;
+ struct bnx2x_fastpath *fp = &bp->fp[0];
+ u16 tx_start_idx, tx_idx;
+ u16 rx_start_idx, rx_idx;
+ u16 pkt_prod;
+ struct sw_tx_bd *tx_buf;
+ struct eth_tx_bd *tx_bd;
+ dma_addr_t mapping;
+ union eth_rx_cqe *cqe;
+ u8 cqe_fp_flags;
+ struct sw_rx_bd *rx_buf;
+ u16 len;
+ int rc = -ENODEV;
+
+ if (loopback_mode == BNX2X_MAC_LOOPBACK) {
+ bp->link_params.loopback_mode = LOOPBACK_BMAC;
+ bnx2x_phy_hw_lock(bp);
+ bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+
+ } else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
+ bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+ bnx2x_phy_hw_lock(bp);
+ bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+ bnx2x_phy_hw_unlock(bp);
+ /* wait until link state is restored */
+ bnx2x_wait_for_link(bp, link_up);
+
+ } else
+ return -EINVAL;
+
+ pkt_size = 1514;
+ skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ if (!skb) {
+ rc = -ENOMEM;
+ goto test_loopback_exit;
+ }
+ packet = skb_put(skb, pkt_size);
+ memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
+ memset(packet + ETH_ALEN, 0, (ETH_HLEN - ETH_ALEN));
+ for (i = ETH_HLEN; i < pkt_size; i++)
+ packet[i] = (unsigned char) (i & 0xff);
+
+ num_pkts = 0;
+ tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
+ rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
+
+ pkt_prod = fp->tx_pkt_prod++;
+ tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
+ tx_buf->first_bd = fp->tx_bd_prod;
+ tx_buf->skb = skb;
+
+ tx_bd = &fp->tx_desc_ring[TX_BD(fp->tx_bd_prod)];
+ mapping = pci_map_single(bp->pdev, skb->data,
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+ tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ tx_bd->nbd = cpu_to_le16(1);
+ tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+ tx_bd->vlan = cpu_to_le16(pkt_prod);
+ tx_bd->bd_flags.as_bitfield = (ETH_TX_BD_FLAGS_START_BD |
+ ETH_TX_BD_FLAGS_END_BD);
+ tx_bd->general_data = ((UNICAST_ADDRESS <<
+ ETH_TX_BD_ETH_ADDR_TYPE_SHIFT) | 1);
+
+ fp->hw_tx_prods->bds_prod =
+ cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
+ mb(); /* FW restriction: must not reorder writing nbd and packets */
+ fp->hw_tx_prods->packets_prod =
+ cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
+ DOORBELL(bp, FP_IDX(fp), 0);
+
+ mmiowb();
+
+ num_pkts++;
+ fp->tx_bd_prod++;
+ bp->dev->trans_start = jiffies;
+
+ udelay(100);
+
+ tx_idx = le16_to_cpu(*fp->tx_cons_sb);
+ if (tx_idx != tx_start_idx + num_pkts)
+ goto test_loopback_exit;
+
+ rx_idx = le16_to_cpu(*fp->rx_cons_sb);
+ if (rx_idx != rx_start_idx + num_pkts)
+ goto test_loopback_exit;
+
+ cqe = &fp->rx_comp_ring[RCQ_BD(fp->rx_comp_cons)];
+ cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
+ if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
+ goto test_loopback_rx_exit;
+
+ len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
+ if (len != pkt_size)
+ goto test_loopback_rx_exit;
+
+ rx_buf = &fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)];
+ skb = rx_buf->skb;
+ skb_reserve(skb, cqe->fast_path_cqe.placement_offset);
+ for (i = ETH_HLEN; i < pkt_size; i++)
+ if (*(skb->data + i) != (unsigned char) (i & 0xff))
+ goto test_loopback_rx_exit;
+
+ rc = 0;
+
+test_loopback_rx_exit:
+ bp->dev->last_rx = jiffies;
+
+ fp->rx_bd_cons = NEXT_RX_IDX(fp->rx_bd_cons);
+ fp->rx_bd_prod = NEXT_RX_IDX(fp->rx_bd_prod);
+ fp->rx_comp_cons = NEXT_RCQ_IDX(fp->rx_comp_cons);
+ fp->rx_comp_prod = NEXT_RCQ_IDX(fp->rx_comp_prod);
+
+ /* Update producers */
+ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
+ mmiowb(); /* keep prod updates ordered */
+
+test_loopback_exit:
+ bp->link_params.loopback_mode = LOOPBACK_NONE;
+
+ return rc;
+}
+
+static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
+{
+ int rc = 0;
+
+ if (!netif_running(bp->dev))
+ return BNX2X_LOOPBACK_FAILED;
+
+ bnx2x_netif_stop(bp);
+
+ if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
+ DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
+ rc |= BNX2X_MAC_LOOPBACK_FAILED;
+ }
+
+ if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) {
+ DP(NETIF_MSG_PROBE, "PHY loopback failed\n");
+ rc |= BNX2X_PHY_LOOPBACK_FAILED;
+ }
+
+ bnx2x_netif_start(bp);
+
+ return rc;
+}
+
+#define CRC32_RESIDUAL 0xdebb20e3
+
+static int bnx2x_test_nvram(struct bnx2x *bp)
+{
+ static const struct {
+ int offset;
+ int size;
+ } nvram_tbl[] = {
+ { 0, 0x14 }, /* bootstrap */
+ { 0x14, 0xec }, /* dir */
+ { 0x100, 0x350 }, /* manuf_info */
+ { 0x450, 0xf0 }, /* feature_info */
+ { 0x640, 0x64 }, /* upgrade_key_info */
+ { 0x6a4, 0x64 },
+ { 0x708, 0x70 }, /* manuf_key_info */
+ { 0x778, 0x70 },
+ { 0, 0 }
+ };
+ u32 buf[0x350 / 4];
+ u8 *data = (u8 *)buf;
+ int i, rc;
+ u32 magic, csum;
+
+ rc = bnx2x_nvram_read(bp, 0, data, 4);
+ if (rc) {
+ DP(NETIF_MSG_PROBE, "magic value read (rc -%d)\n", -rc);
+ goto test_nvram_exit;
+ }
+
+ magic = be32_to_cpu(buf[0]);
+ if (magic != 0x669955aa) {
+ DP(NETIF_MSG_PROBE, "magic value (0x%08x)\n", magic);
+ rc = -ENODEV;
+ goto test_nvram_exit;
+ }
+
+ for (i = 0; nvram_tbl[i].size; i++) {
+
+ rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, data,
+ nvram_tbl[i].size);
+ if (rc) {
+ DP(NETIF_MSG_PROBE,
+ "nvram_tbl[%d] read data (rc -%d)\n", i, -rc);
+ goto test_nvram_exit;
+ }
+
+ csum = ether_crc_le(nvram_tbl[i].size, data);
+ if (csum != CRC32_RESIDUAL) {
+ DP(NETIF_MSG_PROBE,
+ "nvram_tbl[%d] csum value (0x%08x)\n", i, csum);
+ rc = -ENODEV;
+ goto test_nvram_exit;
+ }
+ }
+
+test_nvram_exit:
+ return rc;
+}
+
+static int bnx2x_test_intr(struct bnx2x *bp)
+{
+ struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
+ int i, rc;
+
+ if (!netif_running(bp->dev))
+ return -ENODEV;
+
+ config->hdr.length_6b = 0;
+ config->hdr.offset = 0;
+ config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.reserved1 = 0;
+
+ rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+ U64_HI(bnx2x_sp_mapping(bp, mac_config)),
+ U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+ if (rc == 0) {
+ bp->set_mac_pending++;
+ for (i = 0; i < 10; i++) {
+ if (!bp->set_mac_pending)
+ break;
+ msleep_interruptible(10);
+ }
+ if (i == 10)
+ rc = -ENODEV;
+ }
+
+ return rc;
+}
+
+static void bnx2x_self_test(struct net_device *dev,
+ struct ethtool_test *etest, u64 *buf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS);
+
+ if (!netif_running(dev))
+ return;
+
+ /* offline tests are not suppoerted in MF mode */
+ if (IS_E1HMF(bp))
+ etest->flags &= ~ETH_TEST_FL_OFFLINE;
+
+ if (etest->flags & ETH_TEST_FL_OFFLINE) {
+ u8 link_up;
+
+ link_up = bp->link_vars.link_up;
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ bnx2x_nic_load(bp, LOAD_DIAG);
+ /* wait until link state is restored */
+ bnx2x_wait_for_link(bp, link_up);
+
+ if (bnx2x_test_registers(bp) != 0) {
+ buf[0] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+ if (bnx2x_test_memory(bp) != 0) {
+ buf[1] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+ buf[2] = bnx2x_test_loopback(bp, link_up);
+ if (buf[2] != 0)
+ etest->flags |= ETH_TEST_FL_FAILED;
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ bnx2x_nic_load(bp, LOAD_NORMAL);
+ /* wait until link state is restored */
+ bnx2x_wait_for_link(bp, link_up);
+ }
+ if (bnx2x_test_nvram(bp) != 0) {
+ buf[3] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+ if (bnx2x_test_intr(bp) != 0) {
+ buf[4] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+ if (bp->port.pmf)
+ if (bnx2x_link_test(bp) != 0) {
+ buf[5] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+ buf[7] = bnx2x_mc_assert(bp);
+ if (buf[7] != 0)
+ etest->flags |= ETH_TEST_FL_FAILED;
+
+#ifdef BNX2X_EXTRA_DEBUG
+ bnx2x_panic_dump(bp);
+#endif
+}
+
+static const struct {
+ long offset;
+ int size;
+ u32 flags;
+ char string[ETH_GSTRING_LEN];
+} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
+/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi), 8, 1, "rx_bytes" },
+ { STATS_OFFSET32(error_bytes_received_hi), 8, 1, "rx_error_bytes" },
+ { STATS_OFFSET32(total_bytes_transmitted_hi), 8, 1, "tx_bytes" },
+ { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), 8, 0, "tx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, 1, "rx_ucast_packets" },
+ { STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, 1, "rx_mcast_packets" },
+ { STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, 1, "rx_bcast_packets" },
+ { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, 1, "tx_packets" },
+ { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
+ 8, 0, "tx_mac_errors" },
+/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
+ 8, 0, "tx_carrier_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
+ 8, 0, "rx_crc_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
+ 8, 0, "rx_align_errors" },
+ { STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
+ 8, 0, "tx_single_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
+ 8, 0, "tx_multi_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
+ 8, 0, "tx_deferred" },
+ { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
+ 8, 0, "tx_excess_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
+ 8, 0, "tx_late_collisions" },
+ { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
+ 8, 0, "tx_total_collisions" },
+ { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
+ 8, 0, "rx_fragments" },
+/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), 8, 0, "rx_jabbers" },
+ { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
+ 8, 0, "rx_undersize_packets" },
+ { STATS_OFFSET32(jabber_packets_received),
+ 4, 1, "rx_oversize_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
+ 8, 0, "tx_64_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
+ 8, 0, "tx_65_to_127_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
+ 8, 0, "tx_128_to_255_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
+ 8, 0, "tx_256_to_511_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
+ 8, 0, "tx_512_to_1023_byte_packets" },
+ { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
+ 8, 0, "tx_1024_to_1522_byte_packets" },
+ { STATS_OFFSET32(etherstatspktsover1522octets_hi),
+ 8, 0, "tx_1523_to_9022_byte_packets" },
+/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
+ 8, 0, "rx_xon_frames" },
+ { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
+ 8, 0, "rx_xoff_frames" },
+ { STATS_OFFSET32(tx_stat_outxonsent_hi), 8, 0, "tx_xon_frames" },
+ { STATS_OFFSET32(tx_stat_outxoffsent_hi), 8, 0, "tx_xoff_frames" },
+ { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
+ 8, 0, "rx_mac_ctrl_frames" },
+ { STATS_OFFSET32(mac_filter_discard), 4, 1, "rx_filtered_packets" },
+ { STATS_OFFSET32(no_buff_discard), 4, 1, "rx_discards" },
+ { STATS_OFFSET32(xxoverflow_discard), 4, 1, "rx_fw_discards" },
+ { STATS_OFFSET32(brb_drop_hi), 8, 1, "brb_discard" },
+/* 39 */{ STATS_OFFSET32(brb_truncate_discard), 8, 1, "brb_truncate" }
+};
+
+static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int i, j;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
+ continue;
+ strcpy(buf + j*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[i].string);
+ j++;
+ }
+ break;
+
+ case ETH_SS_TEST:
+ memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr));
+ break;
+ }
+}
+
+static int bnx2x_get_stats_count(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int i, num_stats = 0;
+
+ for (i = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
+ continue;
+ num_stats++;
+ }
+ return num_stats;
+}
+
+static void bnx2x_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *buf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 *hw_stats = (u32 *)&bp->eth_stats;
+ int i, j;
+
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF(bp) && (!bnx2x_stats_arr[i].flags))
+ continue;
+
+ if (bnx2x_stats_arr[i].size == 0) {
+ /* skip this counter */
+ buf[j] = 0;
+ j++;
+ continue;
+ }
+ if (bnx2x_stats_arr[i].size == 4) {
+ /* 4-byte counter */
+ buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
+ j++;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
+ *(hw_stats + bnx2x_stats_arr[i].offset + 1));
+ j++;
+ }
+}
+
+static int bnx2x_phys_id(struct net_device *dev, u32 data)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int port = BP_PORT(bp);
+ int i;
+
+ if (!netif_running(dev))
+ return 0;
+
+ if (!bp->port.pmf)
+ return 0;
+
+ if (data == 0)
+ data = 2;
+
+ for (i = 0; i < (data * 2); i++) {
+ if ((i % 2) == 0)
+ bnx2x_set_led(bp, port, LED_MODE_OPER, SPEED_1000,
+ bp->link_params.hw_led_mode,
+ bp->link_params.chip_id);
+ else
+ bnx2x_set_led(bp, port, LED_MODE_OFF, 0,
+ bp->link_params.hw_led_mode,
+ bp->link_params.chip_id);
+
+ msleep_interruptible(500);
+ if (signal_pending(current))
+ break;
+ }
+
+ if (bp->link_vars.link_up)
+ bnx2x_set_led(bp, port, LED_MODE_OPER,
+ bp->link_vars.line_speed,
+ bp->link_params.hw_led_mode,
+ bp->link_params.chip_id);
+
+ return 0;
+}
+
+static struct ethtool_ops bnx2x_ethtool_ops = {
+ .get_settings = bnx2x_get_settings,
+ .set_settings = bnx2x_set_settings,
+ .get_drvinfo = bnx2x_get_drvinfo,
+ .get_wol = bnx2x_get_wol,
+ .set_wol = bnx2x_set_wol,
+ .get_msglevel = bnx2x_get_msglevel,
+ .set_msglevel = bnx2x_set_msglevel,
+ .nway_reset = bnx2x_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = bnx2x_get_eeprom_len,
+ .get_eeprom = bnx2x_get_eeprom,
+ .set_eeprom = bnx2x_set_eeprom,
+ .get_coalesce = bnx2x_get_coalesce,
+ .set_coalesce = bnx2x_set_coalesce,
+ .get_ringparam = bnx2x_get_ringparam,
+ .set_ringparam = bnx2x_set_ringparam,
+ .get_pauseparam = bnx2x_get_pauseparam,
+ .set_pauseparam = bnx2x_set_pauseparam,
+ .get_rx_csum = bnx2x_get_rx_csum,
+ .set_rx_csum = bnx2x_set_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .set_flags = bnx2x_set_flags,
+ .get_flags = ethtool_op_get_flags,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = bnx2x_set_tso,
+ .self_test_count = bnx2x_self_test_count,
+ .self_test = bnx2x_self_test,
+ .get_strings = bnx2x_get_strings,
+ .phys_id = bnx2x_phys_id,
+ .get_stats_count = bnx2x_get_stats_count,
+ .get_ethtool_stats = bnx2x_get_ethtool_stats,
+};
+
+/* end of ethtool_ops */
+
+/****************************************************************************
+* General service functions
+****************************************************************************/
+
+static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
+{
+ u16 pmcsr;
+
+ pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
+
+ switch (state) {
+ case PCI_D0:
+ 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 */
+ msleep(20);
+ break;
+
+ case PCI_D3hot:
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= 3;
+
+ if (bp->wol)
+ pmcsr |= PCI_PM_CTRL_PME_ENABLE;
+
+ pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
+ pmcsr);
+
+ /* No more memory access after this point until
+ * device is brought back to D0.
+ */
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * net_device service functions
+ */
+
+static int bnx2x_poll(struct napi_struct *napi, int budget)
+{
+ struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
+ napi);
+ struct bnx2x *bp = fp->bp;
+ int work_done = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ goto poll_panic;
+#endif
+
+ prefetch(fp->tx_buf_ring[TX_BD(fp->tx_pkt_cons)].skb);
+ prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb);
+ prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256);
+
+ bnx2x_update_fpsb_idx(fp);
+
+ if ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) ||
+ (fp->tx_pkt_prod != fp->tx_pkt_cons))
+ bnx2x_tx_int(fp, budget);
+
+ if (le16_to_cpu(*fp->rx_cons_sb) != fp->rx_comp_cons)
+ work_done = bnx2x_rx_int(fp, budget);
+
+ rmb(); /* bnx2x_has_work() reads the status block */
+
+ /* must not complete if we consumed full budget */
+ if ((work_done < budget) && !bnx2x_has_work(fp)) {
+
+#ifdef BNX2X_STOP_ON_ERROR
+poll_panic:
+#endif
+ netif_rx_complete(bp->dev, napi);
+
+ bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
+ le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
+ bnx2x_ack_sb(bp, FP_SB_ID(fp), CSTORM_ID,
+ le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
+ }
+ return work_done;
+}
+
+
+/* we split the first BD into headers and data BDs
+ * to ease the pain of our fellow micocode engineers
+ * we use one mapping for both BDs
+ * So far this has only been observed to happen
+ * in Other Operating Systems(TM)
+ */
+static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp,
+ struct eth_tx_bd **tx_bd, u16 hlen,
+ u16 bd_prod, int nbd)
+{
+ struct eth_tx_bd *h_tx_bd = *tx_bd;
+ struct eth_tx_bd *d_tx_bd;
+ dma_addr_t mapping;
+ int old_len = le16_to_cpu(h_tx_bd->nbytes);
+
+ /* first fix first BD */
+ h_tx_bd->nbd = cpu_to_le16(nbd);
+ h_tx_bd->nbytes = cpu_to_le16(hlen);
+
+ DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d "
+ "(%x:%x) nbd %d\n", h_tx_bd->nbytes, h_tx_bd->addr_hi,
+ h_tx_bd->addr_lo, h_tx_bd->nbd);
+
+ /* now get a new data BD
+ * (after the pbd) and fill it */
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+ d_tx_bd = &fp->tx_desc_ring[bd_prod];
+
+ mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi),
+ le32_to_cpu(h_tx_bd->addr_lo)) + hlen;
+
+ d_tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ d_tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ d_tx_bd->nbytes = cpu_to_le16(old_len - hlen);
+ d_tx_bd->vlan = 0;
+ /* this marks the BD as one that has no individual mapping
+ * the FW ignores this flag in a BD not marked start
+ */
+ d_tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
+ DP(NETIF_MSG_TX_QUEUED,
+ "TSO split data size is %d (%x:%x)\n",
+ d_tx_bd->nbytes, d_tx_bd->addr_hi, d_tx_bd->addr_lo);
+
+ /* update tx_bd for marking the last BD flag */
+ *tx_bd = d_tx_bd;
+
+ return bd_prod;
+}
+
+static inline u16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix)
+{
+ if (fix > 0)
+ csum = (u16) ~csum_fold(csum_sub(csum,
+ csum_partial(t_header - fix, fix, 0)));
+
+ else if (fix < 0)
+ csum = (u16) ~csum_fold(csum_add(csum,
+ csum_partial(t_header, -fix, 0)));
+
+ return swab16(csum);
+}
+
+static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
+{
+ u32 rc;
+
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ rc = XMIT_PLAIN;
+
+ else {
+ if (skb->protocol == ntohs(ETH_P_IPV6)) {
+ rc = XMIT_CSUM_V6;
+ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+ rc |= XMIT_CSUM_TCP;
+
+ } else {
+ rc = XMIT_CSUM_V4;
+ if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+ rc |= XMIT_CSUM_TCP;
+ }
+ }
+
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+ rc |= XMIT_GSO_V4;
+
+ else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ rc |= XMIT_GSO_V6;
+
+ return rc;
+}
+
+/* check if packet requires linearization (packet is too fragmented) */
+static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
+ u32 xmit_type)
+{
+ int to_copy = 0;
+ int hlen = 0;
+ int first_bd_sz = 0;
+
+ /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
+ if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) {
+
+ if (xmit_type & XMIT_GSO) {
+ unsigned short lso_mss = skb_shinfo(skb)->gso_size;
+ /* Check if LSO packet needs to be copied:
+ 3 = 1 (for headers BD) + 2 (for PBD and last BD) */
+ int wnd_size = MAX_FETCH_BD - 3;
+ /* Number of widnows to check */
+ int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
+ int wnd_idx = 0;
+ int frag_idx = 0;
+ u32 wnd_sum = 0;
+
+ /* Headers length */
+ hlen = (int)(skb_transport_header(skb) - skb->data) +
+ tcp_hdrlen(skb);
+
+ /* Amount of data (w/o headers) on linear part of SKB*/
+ first_bd_sz = skb_headlen(skb) - hlen;
+
+ wnd_sum = first_bd_sz;
+
+ /* Calculate the first sum - it's special */
+ for (frag_idx = 0; frag_idx < wnd_size - 1; frag_idx++)
+ wnd_sum +=
+ skb_shinfo(skb)->frags[frag_idx].size;
+
+ /* If there was data on linear skb data - check it */
+ if (first_bd_sz > 0) {
+ if (unlikely(wnd_sum < lso_mss)) {
+ to_copy = 1;
+ goto exit_lbl;
+ }
+
+ wnd_sum -= first_bd_sz;
+ }
+
+ /* Others are easier: run through the frag list and
+ check all windows */
+ for (wnd_idx = 0; wnd_idx <= num_wnds; wnd_idx++) {
+ wnd_sum +=
+ skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1].size;
+
+ if (unlikely(wnd_sum < lso_mss)) {
+ to_copy = 1;
+ break;
+ }
+ wnd_sum -=
+ skb_shinfo(skb)->frags[wnd_idx].size;
+ }
+
+ } else {
+ /* in non-LSO too fragmented packet should always
+ be linearized */
+ to_copy = 1;
+ }
+ }
+
+exit_lbl:
+ if (unlikely(to_copy))
+ DP(NETIF_MSG_TX_QUEUED,
+ "Linearization IS REQUIRED for %s packet. "
+ "num_frags %d hlen %d first_bd_sz %d\n",
+ (xmit_type & XMIT_GSO) ? "LSO" : "non-LSO",
+ skb_shinfo(skb)->nr_frags, hlen, first_bd_sz);
+
+ return to_copy;
+}
+
+/* called with netif_tx_lock
+ * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
+ * netif_wake_queue()
+ */
+static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x_fastpath *fp;
+ struct sw_tx_bd *tx_buf;
+ struct eth_tx_bd *tx_bd;
+ struct eth_tx_parse_bd *pbd = NULL;
+ u16 pkt_prod, bd_prod;
+ int nbd, fp_index;
+ dma_addr_t mapping;
+ u32 xmit_type = bnx2x_xmit_type(bp, skb);
+ int vlan_off = (bp->e1hov ? 4 : 0);
+ int i;
+ u8 hlen = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return NETDEV_TX_BUSY;
+#endif
+
+ fp_index = (smp_processor_id() % bp->num_queues);
+ fp = &bp->fp[fp_index];
+
+ if (unlikely(bnx2x_tx_avail(bp->fp) <
+ (skb_shinfo(skb)->nr_frags + 3))) {
+ bp->eth_stats.driver_xoff++,
+ netif_stop_queue(dev);
+ BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
+ return NETDEV_TX_BUSY;
+ }
+
+ DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)"
+ " gso type %x xmit_type %x\n",
+ skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
+ ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
+
+ /* First, check if we need to linearaize the skb
+ (due to FW restrictions) */
+ if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
+ /* Statistics of linearization */
+ bp->lin_cnt++;
+ if (skb_linearize(skb) != 0) {
+ DP(NETIF_MSG_TX_QUEUED, "SKB linearization failed - "
+ "silently dropping this SKB\n");
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+ }
+
+ /*
+ Please read carefully. First we use one BD which we mark as start,
+ then for TSO or xsum we have a parsing info BD,
+ and only then we have the rest of the TSO BDs.
+ (don't forget to mark the last one as last,
+ and to unmap only AFTER you write to the BD ...)
+ And above all, all pdb sizes are in words - NOT DWORDS!
+ */
+
+ pkt_prod = fp->tx_pkt_prod++;
+ bd_prod = TX_BD(fp->tx_bd_prod);
+
+ /* get a tx_buf and first BD */
+ tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
+ tx_bd = &fp->tx_desc_ring[bd_prod];
+
+ tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+ tx_bd->general_data = (UNICAST_ADDRESS <<
+ ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
+ tx_bd->general_data |= 1; /* header nbd */
+
+ /* remember the first BD of the packet */
+ tx_buf->first_bd = fp->tx_bd_prod;
+ tx_buf->skb = skb;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "sending pkt %u @%p next_idx %u bd %u @%p\n",
+ pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd);
+
+ if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) {
+ tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
+ tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
+ vlan_off += 4;
+ } else
+ tx_bd->vlan = cpu_to_le16(pkt_prod);
+
+ if (xmit_type) {
+
+ /* turn on parsing and get a BD */
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+ pbd = (void *)&fp->tx_desc_ring[bd_prod];
+
+ memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
+ }
+
+ if (xmit_type & XMIT_CSUM) {
+ hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
+
+ /* for now NS flag is not used in Linux */
+ pbd->global_data = (hlen |
+ ((skb->protocol == ntohs(ETH_P_8021Q)) <<
+ ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
+
+ pbd->ip_hlen = (skb_transport_header(skb) -
+ skb_network_header(skb)) / 2;
+
+ hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2;
+
+ pbd->total_hlen = cpu_to_le16(hlen);
+ hlen = hlen*2 - vlan_off;
+
+ tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_TCP_CSUM;
+
+ if (xmit_type & XMIT_CSUM_V4)
+ tx_bd->bd_flags.as_bitfield |=
+ ETH_TX_BD_FLAGS_IP_CSUM;
+ else
+ tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6;
+
+ if (xmit_type & XMIT_CSUM_TCP) {
+ pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check);
+
+ } else {
+ s8 fix = SKB_CS_OFF(skb); /* signed! */
+
+ pbd->global_data |= ETH_TX_PARSE_BD_CS_ANY_FLG;
+ pbd->cs_offset = fix / 2;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "hlen %d offset %d fix %d csum before fix %x\n",
+ le16_to_cpu(pbd->total_hlen), pbd->cs_offset, fix,
+ SKB_CS(skb));
+
+ /* HW bug: fixup the CSUM */
+ pbd->tcp_pseudo_csum =
+ bnx2x_csum_fix(skb_transport_header(skb),
+ SKB_CS(skb), fix);
+
+ DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n",
+ pbd->tcp_pseudo_csum);
+ }
+ }
+
+ mapping = pci_map_single(bp->pdev, skb->data,
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+
+ tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL)? 1 : 2);
+ tx_bd->nbd = cpu_to_le16(nbd);
+ tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+
+ DP(NETIF_MSG_TX_QUEUED, "first bd @%p addr (%x:%x) nbd %d"
+ " nbytes %d flags %x vlan %x\n",
+ tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, le16_to_cpu(tx_bd->nbd),
+ le16_to_cpu(tx_bd->nbytes), tx_bd->bd_flags.as_bitfield,
+ le16_to_cpu(tx_bd->vlan));
+
+ if (xmit_type & XMIT_GSO) {
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "TSO packet len %d hlen %d total len %d tso size %d\n",
+ skb->len, hlen, skb_headlen(skb),
+ skb_shinfo(skb)->gso_size);
+
+ tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
+
+ if (unlikely(skb_headlen(skb) > hlen))
+ bd_prod = bnx2x_tx_split(bp, fp, &tx_bd, hlen,
+ bd_prod, ++nbd);
+
+ pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+ pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
+ pbd->tcp_flags = pbd_tcp_flags(skb);
+
+ if (xmit_type & XMIT_GSO_V4) {
+ pbd->ip_id = swab16(ip_hdr(skb)->id);
+ pbd->tcp_pseudo_csum =
+ swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+
+ } else
+ pbd->tcp_pseudo_csum =
+ swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+
+ pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN;
+ }
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+ tx_bd = &fp->tx_desc_ring[bd_prod];
+
+ mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
+ frag->size, PCI_DMA_TODEVICE);
+
+ tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ tx_bd->nbytes = cpu_to_le16(frag->size);
+ tx_bd->vlan = cpu_to_le16(pkt_prod);
+ tx_bd->bd_flags.as_bitfield = 0;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "frag %d bd @%p addr (%x:%x) nbytes %d flags %x\n",
+ i, tx_bd, tx_bd->addr_hi, tx_bd->addr_lo,
+ le16_to_cpu(tx_bd->nbytes), tx_bd->bd_flags.as_bitfield);
+ }
+
+ /* now at last mark the BD as the last BD */
+ tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_END_BD;
+
+ DP(NETIF_MSG_TX_QUEUED, "last bd @%p flags %x\n",
+ tx_bd, tx_bd->bd_flags.as_bitfield);
+
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+
+ /* now send a tx doorbell, counting the next BD
+ * if the packet contains or ends with it
+ */
+ if (TX_BD_POFF(bd_prod) < nbd)
+ nbd++;
+
+ if (pbd)
+ DP(NETIF_MSG_TX_QUEUED,
+ "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u"
+ " tcp_flags %x xsum %x seq %u hlen %u\n",
+ pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id,
+ pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum,
+ pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen));
+
+ DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod);
+
+ fp->hw_tx_prods->bds_prod =
+ cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
+ mb(); /* FW restriction: must not reorder writing nbd and packets */
+ fp->hw_tx_prods->packets_prod =
+ cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
+ DOORBELL(bp, FP_IDX(fp), 0);
+
+ mmiowb();
+
+ fp->tx_bd_prod += nbd;
+ dev->trans_start = jiffies;
+
+ if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
+ netif_stop_queue(dev);
+ bp->eth_stats.driver_xoff++;
+ if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
+ netif_wake_queue(dev);
+ }
+ fp->tx_pkt++;
+
+ return NETDEV_TX_OK;
+}
+
+/* called with rtnl_lock */
+static int bnx2x_open(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ bnx2x_set_power_state(bp, PCI_D0);
+
+ return bnx2x_nic_load(bp, LOAD_OPEN);
+}
+
+/* called with rtnl_lock */
+static int bnx2x_close(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* Unload the driver, release IRQs */
+ bnx2x_nic_unload(bp, UNLOAD_CLOSE);
+ if (atomic_read(&bp->pdev->enable_cnt) == 1)
+ if (!CHIP_REV_IS_SLOW(bp))
+ bnx2x_set_power_state(bp, PCI_D3hot);
+
+ return 0;
+}
+
+/* called with netif_tx_lock from set_multicast */
+static void bnx2x_set_rx_mode(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 rx_mode = BNX2X_RX_MODE_NORMAL;
+ int port = BP_PORT(bp);
+
+ if (bp->state != BNX2X_STATE_OPEN) {
+ DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
+ return;
+ }
+
+ DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags);
+
+ if (dev->flags & IFF_PROMISC)
+ rx_mode = BNX2X_RX_MODE_PROMISC;
+
+ else if ((dev->flags & IFF_ALLMULTI) ||
+ ((dev->mc_count > BNX2X_MAX_MULTICAST) && CHIP_IS_E1(bp)))
+ rx_mode = BNX2X_RX_MODE_ALLMULTI;
+
+ else { /* some multicasts */
+ if (CHIP_IS_E1(bp)) {
+ int i, old, offset;
+ struct dev_mc_list *mclist;
+ struct mac_configuration_cmd *config =
+ bnx2x_sp(bp, mcast_config);
+
+ for (i = 0, mclist = dev->mc_list;
+ mclist && (i < dev->mc_count);
+ i++, mclist = mclist->next) {
+
+ config->config_table[i].
+ cam_entry.msb_mac_addr =
+ swab16(*(u16 *)&mclist->dmi_addr[0]);
+ config->config_table[i].
+ cam_entry.middle_mac_addr =
+ swab16(*(u16 *)&mclist->dmi_addr[2]);
+ config->config_table[i].
+ cam_entry.lsb_mac_addr =
+ swab16(*(u16 *)&mclist->dmi_addr[4]);
+ config->config_table[i].cam_entry.flags =
+ cpu_to_le16(port);
+ config->config_table[i].
+ target_table_entry.flags = 0;
+ config->config_table[i].
+ target_table_entry.client_id = 0;
+ config->config_table[i].
+ target_table_entry.vlan_id = 0;
+
+ DP(NETIF_MSG_IFUP,
+ "setting MCAST[%d] (%04x:%04x:%04x)\n", i,
+ config->config_table[i].
+ cam_entry.msb_mac_addr,
+ config->config_table[i].
+ cam_entry.middle_mac_addr,
+ config->config_table[i].
+ cam_entry.lsb_mac_addr);
+ }
+ old = config->hdr.length_6b;
+ if (old > i) {
+ for (; i < old; i++) {
+ if (CAM_IS_INVALID(config->
+ config_table[i])) {
+ i--; /* already invalidated */
+ break;
+ }
+ /* invalidate */
+ CAM_INVALIDATE(config->
+ config_table[i]);
+ }
+ }
+
+ if (CHIP_REV_IS_SLOW(bp))
+ offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
+ else
+ offset = BNX2X_MAX_MULTICAST*(1 + port);
+
+ config->hdr.length_6b = i;
+ config->hdr.offset = offset;
+ config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.reserved1 = 0;
+
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+ U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
+ U64_LO(bnx2x_sp_mapping(bp, mcast_config)),
+ 0);
+ } else { /* E1H */
+ /* Accept one or more multicasts */
+ struct dev_mc_list *mclist;
+ u32 mc_filter[MC_HASH_SIZE];
+ u32 crc, bit, regidx;
+ int i;
+
+ memset(mc_filter, 0, 4 * MC_HASH_SIZE);
+
+ for (i = 0, mclist = dev->mc_list;
+ mclist && (i < dev->mc_count);
+ i++, mclist = mclist->next) {
+
+ DP(NETIF_MSG_IFUP, "Adding mcast MAC: "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mclist->dmi_addr[0], mclist->dmi_addr[1],
+ mclist->dmi_addr[2], mclist->dmi_addr[3],
+ mclist->dmi_addr[4], mclist->dmi_addr[5]);
+
+ crc = crc32c_le(0, mclist->dmi_addr, ETH_ALEN);
+ bit = (crc >> 24) & 0xff;
+ regidx = bit >> 5;
+ bit &= 0x1f;
+ mc_filter[regidx] |= (1 << bit);
+ }
+
+ for (i = 0; i < MC_HASH_SIZE; i++)
+ REG_WR(bp, MC_HASH_OFFSET(bp, i),
+ mc_filter[i]);
+ }
+ }
+
+ bp->rx_mode = rx_mode;
+ bnx2x_set_storm_rx_mode(bp);
+}
+
+/* called with rtnl_lock */
+static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (!is_valid_ether_addr((u8 *)(addr->sa_data)))
+ return -EINVAL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ if (netif_running(dev)) {
+ if (CHIP_IS_E1(bp))
+ bnx2x_set_mac_addr_e1(bp);
+ else
+ bnx2x_set_mac_addr_e1h(bp);
+ }
+
+ return 0;
+}
+
+/* called with rtnl_lock */
+static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct mii_ioctl_data *data = if_mii(ifr);
+ struct bnx2x *bp = netdev_priv(dev);
+ int err;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ data->phy_id = bp->port.phy_addr;
+
+ /* fallthrough */
+
+ case SIOCGMIIREG: {
+ u16 mii_regval;
+
+ if (!netif_running(dev))
+ return -EAGAIN;
+
+ mutex_lock(&bp->port.phy_mutex);
+ err = bnx2x_cl45_read(bp, BP_PORT(bp), 0, bp->port.phy_addr,
+ DEFAULT_PHY_DEV_ADDR,
+ (data->reg_num & 0x1f), &mii_regval);
+ data->val_out = mii_regval;
+ mutex_unlock(&bp->port.phy_mutex);
+ return err;
+ }
+
+ case SIOCSMIIREG:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (!netif_running(dev))
+ return -EAGAIN;
+
+ mutex_lock(&bp->port.phy_mutex);
+ err = bnx2x_cl45_write(bp, BP_PORT(bp), 0, bp->port.phy_addr,
+ DEFAULT_PHY_DEV_ADDR,
+ (data->reg_num & 0x1f), data->val_in);
+ mutex_unlock(&bp->port.phy_mutex);
+ return err;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+/* called with rtnl_lock */
+static int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc = 0;
+
+ if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) ||
+ ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE))
+ return -EINVAL;
+
+ /* This does not race with packet allocation
+ * because the actual alloc size is
+ * only updated as part of load
+ */
+ dev->mtu = new_mtu;
+
+ if (netif_running(dev)) {
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+ rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ }
+
+ return rc;
+}
+
+static void bnx2x_tx_timeout(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (!bp->panic)
+ bnx2x_panic();
+#endif
+ /* This allows the netif to be shutdown gracefully before resetting */
+ schedule_work(&bp->reset_task);
+}
+
+#ifdef BCM_VLAN
+/* called with rtnl_lock */
+static void bnx2x_vlan_rx_register(struct net_device *dev,
+ struct vlan_group *vlgrp)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ bp->vlgrp = vlgrp;
+ if (netif_running(dev))
+ bnx2x_set_client_config(bp);
+}
+
+#endif
+
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+static void poll_bnx2x(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ disable_irq(bp->pdev->irq);
+ bnx2x_interrupt(bp->pdev->irq, dev);
+ enable_irq(bp->pdev->irq);
+}
+#endif
+
+static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
+ struct net_device *dev)
+{
+ struct bnx2x *bp;
+ int rc;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ bp = netdev_priv(dev);
+
+ bp->dev = dev;
+ bp->pdev = pdev;
+ bp->flags = 0;
+ bp->func = PCI_FUNC(pdev->devfn);
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ printk(KERN_ERR PFX "Cannot enable PCI device, aborting\n");
+ goto err_out;
+ }
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+ printk(KERN_ERR PFX "Cannot find PCI device base address,"
+ " aborting\n");
+ rc = -ENODEV;
+ goto err_out_disable;
+ }
+
+ if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+ printk(KERN_ERR PFX "Cannot find second PCI device"
+ " base address, aborting\n");
+ rc = -ENODEV;
+ goto err_out_disable;
+ }
+
+ if (atomic_read(&pdev->enable_cnt) == 1) {
+ rc = pci_request_regions(pdev, DRV_MODULE_NAME);
+ if (rc) {
+ printk(KERN_ERR PFX "Cannot obtain PCI resources,"
+ " aborting\n");
+ goto err_out_disable;
+ }
+
+ pci_set_master(pdev);
+ pci_save_state(pdev);
+ }
+
+ bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ if (bp->pm_cap == 0) {
+ printk(KERN_ERR PFX "Cannot find power management"
+ " capability, aborting\n");
+ rc = -EIO;
+ goto err_out_release;
+ }
+
+ bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (bp->pcie_cap == 0) {
+ printk(KERN_ERR PFX "Cannot find PCI Express capability,"
+ " aborting\n");
+ rc = -EIO;
+ goto err_out_release;
+ }
+
+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
+ bp->flags |= USING_DAC_FLAG;
+ if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+ printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
+ " failed, aborting\n");
+ rc = -EIO;
+ goto err_out_release;
+ }
+
+ } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
+ printk(KERN_ERR PFX "System does not support DMA,"
+ " aborting\n");
+ rc = -EIO;
+ goto err_out_release;
+ }
+
+ dev->mem_start = pci_resource_start(pdev, 0);
+ dev->base_addr = dev->mem_start;
+ dev->mem_end = pci_resource_end(pdev, 0);
+
+ dev->irq = pdev->irq;
+
+ bp->regview = ioremap_nocache(dev->base_addr,
+ pci_resource_len(pdev, 0));
+ if (!bp->regview) {
+ printk(KERN_ERR PFX "Cannot map register space, aborting\n");
+ rc = -ENOMEM;
+ goto err_out_release;
+ }
+
+ bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2),
+ min_t(u64, BNX2X_DB_SIZE,
+ pci_resource_len(pdev, 2)));
+ if (!bp->doorbells) {
+ printk(KERN_ERR PFX "Cannot map doorbell space, aborting\n");
+ rc = -ENOMEM;
+ goto err_out_unmap;
+ }
+
+ bnx2x_set_power_state(bp, PCI_D0);
+
+ /* clean indirect addresses */
+ pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
+ PCICFG_VENDOR_ID_OFFSET);
+ REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0 + BP_PORT(bp)*16, 0);
+ REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0 + BP_PORT(bp)*16, 0);
+ REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(bp)*16, 0);
+ REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(bp)*16, 0);
+
+ dev->hard_start_xmit = bnx2x_start_xmit;
+ dev->watchdog_timeo = TX_TIMEOUT;
+
+ dev->ethtool_ops = &bnx2x_ethtool_ops;
+ dev->open = bnx2x_open;
+ dev->stop = bnx2x_close;
+ dev->set_multicast_list = bnx2x_set_rx_mode;
+ dev->set_mac_address = bnx2x_change_mac_addr;
+ dev->do_ioctl = bnx2x_ioctl;
+ dev->change_mtu = bnx2x_change_mtu;
+ dev->tx_timeout = bnx2x_tx_timeout;
+#ifdef BCM_VLAN
+ dev->vlan_rx_register = bnx2x_vlan_rx_register;
+#endif
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+ dev->poll_controller = poll_bnx2x;
+#endif
+ dev->features |= NETIF_F_SG;
+ dev->features |= NETIF_F_HW_CSUM;
+ if (bp->flags & USING_DAC_FLAG)
+ dev->features |= NETIF_F_HIGHDMA;
+#ifdef BCM_VLAN
+ dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
+#endif
+ dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
+ dev->features |= NETIF_F_TSO6;
+
+ return 0;
+
+err_out_unmap:
+ if (bp->regview) {
+ iounmap(bp->regview);
+ bp->regview = NULL;
+ }
+ if (bp->doorbells) {
+ iounmap(bp->doorbells);
+ bp->doorbells = NULL;
+ }
+
+err_out_release:
+ if (atomic_read(&pdev->enable_cnt) == 1)
+ pci_release_regions(pdev);
+
+err_out_disable:
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+
+err_out:
+ return rc;
+}
+
+static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
+
+ val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
+ return val;
+}
+
+/* return value of 1=2.5GHz 2=5GHz */
+static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
+{
+ u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
+
+ val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
+ return val;
+}
+
+static int __devinit bnx2x_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ static int version_printed;
+ struct net_device *dev = NULL;
+ struct bnx2x *bp;
+ int rc;
+ DECLARE_MAC_BUF(mac);
+
+ if (version_printed++ == 0)
+ printk(KERN_INFO "%s", version);
+
+ /* dev zeroed in init_etherdev */
+ dev = alloc_etherdev(sizeof(*bp));
+ if (!dev) {
+ printk(KERN_ERR PFX "Cannot allocate net device\n");
+ return -ENOMEM;
+ }
+
+ netif_carrier_off(dev);
+
+ bp = netdev_priv(dev);
+ bp->msglevel = debug;
+
+ rc = bnx2x_init_dev(pdev, dev);
+ if (rc < 0) {
+ free_netdev(dev);
+ return rc;
+ }
+
+ rc = register_netdev(dev);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot register net device\n");
+ goto init_one_exit;
+ }
+
+ pci_set_drvdata(pdev, dev);
+
+ rc = bnx2x_init_bp(bp);
+ if (rc) {
+ unregister_netdev(dev);
+ goto init_one_exit;
+ }
+
+ bp->common.name = board_info[ent->driver_data].name;
+ printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
+ " IRQ %d, ", dev->name, bp->common.name,
+ (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
+ bnx2x_get_pcie_width(bp),
+ (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
+ dev->base_addr, bp->pdev->irq);
+ printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr));
+ return 0;
+
+init_one_exit:
+ if (bp->regview)
+ iounmap(bp->regview);
+
+ if (bp->doorbells)
+ iounmap(bp->doorbells);
+
+ free_netdev(dev);
+
+ if (atomic_read(&pdev->enable_cnt) == 1)
+ pci_release_regions(pdev);
+
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+
+ return rc;
+}
+
+static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp;
+
+ if (!dev) {
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return;
+ }
+ bp = netdev_priv(dev);
+
+ unregister_netdev(dev);
+
+ if (bp->regview)
+ iounmap(bp->regview);
+
+ if (bp->doorbells)
+ iounmap(bp->doorbells);
+
+ free_netdev(dev);
+
+ if (atomic_read(&pdev->enable_cnt) == 1)
+ pci_release_regions(pdev);
+
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp;
+
+ if (!dev) {
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return -ENODEV;
+ }
+ bp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ pci_save_state(pdev);
+
+ if (!netif_running(dev)) {
+ rtnl_unlock();
+ return 0;
+ }
+
+ netif_device_detach(dev);
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+
+ bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
+
+ rtnl_unlock();
+
+ return 0;
+}
+
+static int bnx2x_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp;
+ int rc;
+
+ if (!dev) {
+ printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
+ return -ENODEV;
+ }
+ bp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ pci_restore_state(pdev);
+
+ if (!netif_running(dev)) {
+ rtnl_unlock();
+ return 0;
+ }
+
+ bnx2x_set_power_state(bp, PCI_D0);
+ netif_device_attach(dev);
+
+ rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+
+ rtnl_unlock();
+
+ return rc;
+}
+
+/**
+ * bnx2x_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ netif_device_detach(dev);
+
+ if (netif_running(dev))
+ bnx2x_nic_unload(bp, UNLOAD_CLOSE);
+
+ pci_disable_device(pdev);
+
+ rtnl_unlock();
+
+ /* Request a slot reset */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * bnx2x_io_slot_reset - called after the PCI bus has been reset
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ */
+static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ if (pci_enable_device(pdev)) {
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset\n");
+ rtnl_unlock();
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
+
+ if (netif_running(dev))
+ bnx2x_set_power_state(bp, PCI_D0);
+
+ rtnl_unlock();
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * bnx2x_io_resume - called when traffic can start flowing again
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation.
+ */
+static void bnx2x_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ if (netif_running(dev))
+ bnx2x_nic_load(bp, LOAD_OPEN);
+
+ netif_device_attach(dev);
+
+ rtnl_unlock();
+}
+
+static struct pci_error_handlers bnx2x_err_handler = {
+ .error_detected = bnx2x_io_error_detected,
+ .slot_reset = bnx2x_io_slot_reset,
+ .resume = bnx2x_io_resume,
+};
+
+static struct pci_driver bnx2x_pci_driver = {
+ .name = DRV_MODULE_NAME,
+ .id_table = bnx2x_pci_tbl,
+ .probe = bnx2x_init_one,
+ .remove = __devexit_p(bnx2x_remove_one),
+ .suspend = bnx2x_suspend,
+ .resume = bnx2x_resume,
+ .err_handler = &bnx2x_err_handler,
+};
+
+static int __init bnx2x_init(void)
+{
+ return pci_register_driver(&bnx2x_pci_driver);
+}
+
+static void __exit bnx2x_cleanup(void)
+{
+ pci_unregister_driver(&bnx2x_pci_driver);
+}
+
+module_init(bnx2x_init);
+module_exit(bnx2x_cleanup);
+
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 5a1aa0b5504..15c9a994672 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -38,21 +38,19 @@
was asserted. */
#define BRB1_REG_NUM_OF_FULL_CYCLES_0 0x600c8
#define BRB1_REG_NUM_OF_FULL_CYCLES_1 0x600cc
-#define BRB1_REG_NUM_OF_FULL_CYCLES_2 0x600d0
-#define BRB1_REG_NUM_OF_FULL_CYCLES_3 0x600d4
#define BRB1_REG_NUM_OF_FULL_CYCLES_4 0x600d8
/* [ST 32] The number of cycles that the pause signal towards MAC #0 was
asserted. */
#define BRB1_REG_NUM_OF_PAUSE_CYCLES_0 0x600b8
#define BRB1_REG_NUM_OF_PAUSE_CYCLES_1 0x600bc
-#define BRB1_REG_NUM_OF_PAUSE_CYCLES_2 0x600c0
-#define BRB1_REG_NUM_OF_PAUSE_CYCLES_3 0x600c4
/* [RW 10] Write client 0: De-assert pause threshold. */
#define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078
#define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c
/* [RW 10] Write client 0: Assert pause threshold. */
#define BRB1_REG_PAUSE_LOW_THRESHOLD_0 0x60068
#define BRB1_REG_PAUSE_LOW_THRESHOLD_1 0x6006c
+/* [R 24] The number of full blocks occpied by port. */
+#define BRB1_REG_PORT_NUM_OCC_BLOCKS_0 0x60094
/* [RW 1] Reset the design by software. */
#define BRB1_REG_SOFT_RESET 0x600dc
/* [R 5] Used to read the value of the XX protection CAM occupancy counter. */
@@ -72,6 +70,8 @@
#define CCM_REG_CCM_INT_MASK 0xd01e4
/* [R 11] Interrupt register #0 read */
#define CCM_REG_CCM_INT_STS 0xd01d8
+/* [R 27] Parity register #0 read */
+#define CCM_REG_CCM_PRTY_STS 0xd01e8
/* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS
REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
Is used to determine the number of the AG context REG-pairs written back;
@@ -190,25 +190,20 @@
weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define CCM_REG_PBF_WEIGHT 0xd00ac
-/* [RW 6] The physical queue number of queue number 1 per port index. */
#define CCM_REG_PHYS_QNUM1_0 0xd0134
#define CCM_REG_PHYS_QNUM1_1 0xd0138
-/* [RW 6] The physical queue number of queue number 2 per port index. */
#define CCM_REG_PHYS_QNUM2_0 0xd013c
#define CCM_REG_PHYS_QNUM2_1 0xd0140
-/* [RW 6] The physical queue number of queue number 3 per port index. */
#define CCM_REG_PHYS_QNUM3_0 0xd0144
-/* [RW 6] The physical queue number of queue number 0 with QOS equal 0 port
- index 0. */
+#define CCM_REG_PHYS_QNUM3_1 0xd0148
#define CCM_REG_QOS_PHYS_QNUM0_0 0xd0114
#define CCM_REG_QOS_PHYS_QNUM0_1 0xd0118
-/* [RW 6] The physical queue number of queue number 0 with QOS equal 1 port
- index 0. */
#define CCM_REG_QOS_PHYS_QNUM1_0 0xd011c
#define CCM_REG_QOS_PHYS_QNUM1_1 0xd0120
-/* [RW 6] The physical queue number of queue number 0 with QOS equal 2 port
- index 0. */
#define CCM_REG_QOS_PHYS_QNUM2_0 0xd0124
+#define CCM_REG_QOS_PHYS_QNUM2_1 0xd0128
+#define CCM_REG_QOS_PHYS_QNUM3_0 0xd012c
+#define CCM_REG_QOS_PHYS_QNUM3_1 0xd0130
/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -253,6 +248,7 @@
mechanism. The fields are: [5:0] - message length; [12:6] - message
pointer; 18:13] - next pointer. */
#define CCM_REG_XX_DESCR_TABLE 0xd0300
+#define CCM_REG_XX_DESCR_TABLE_SIZE 36
/* [R 7] Used to read the value of XX protection Free counter. */
#define CCM_REG_XX_FREE 0xd0184
/* [RW 6] Initial value for the credit counter; responsible for fulfilling
@@ -296,6 +292,8 @@
/* [WB 24] MATT ram access. each entry has the following
format:{RegionLength[11:0]; egionOffset[11:0]} */
#define CDU_REG_MATT 0x101100
+/* [RW 1] when this bit is set the CDU operates in e1hmf mode */
+#define CDU_REG_MF_MODE 0x101050
/* [R 1] indication the initializing the activity counter by the hardware
was done. */
#define CFC_REG_AC_INIT_DONE 0x104078
@@ -330,6 +328,9 @@
field allows changing the priorities of the weighted-round-robin arbiter
which selects which CFC load client should be served next */
#define CFC_REG_LCREQ_WEIGHTS 0x104084
+/* [RW 16] Link List ram access; data = {prev_lcid; ext_lcid} */
+#define CFC_REG_LINK_LIST 0x104c00
+#define CFC_REG_LINK_LIST_SIZE 256
/* [R 1] indication the initializing the link list by the hardware was done. */
#define CFC_REG_LL_INIT_DONE 0x104074
/* [R 9] Number of allocated LCIDs which are at empty state */
@@ -342,6 +343,45 @@
#define CFC_REG_NUM_LCIDS_LEAVING 0x104018
/* [RW 8] The event id for aggregated interrupt 0 */
#define CSDM_REG_AGG_INT_EVENT_0 0xc2038
+#define CSDM_REG_AGG_INT_EVENT_1 0xc203c
+#define CSDM_REG_AGG_INT_EVENT_10 0xc2060
+#define CSDM_REG_AGG_INT_EVENT_11 0xc2064
+#define CSDM_REG_AGG_INT_EVENT_12 0xc2068
+#define CSDM_REG_AGG_INT_EVENT_13 0xc206c
+#define CSDM_REG_AGG_INT_EVENT_14 0xc2070
+#define CSDM_REG_AGG_INT_EVENT_15 0xc2074
+#define CSDM_REG_AGG_INT_EVENT_16 0xc2078
+#define CSDM_REG_AGG_INT_EVENT_17 0xc207c
+#define CSDM_REG_AGG_INT_EVENT_18 0xc2080
+#define CSDM_REG_AGG_INT_EVENT_19 0xc2084
+#define CSDM_REG_AGG_INT_EVENT_2 0xc2040
+#define CSDM_REG_AGG_INT_EVENT_20 0xc2088
+#define CSDM_REG_AGG_INT_EVENT_21 0xc208c
+#define CSDM_REG_AGG_INT_EVENT_22 0xc2090
+#define CSDM_REG_AGG_INT_EVENT_23 0xc2094
+#define CSDM_REG_AGG_INT_EVENT_24 0xc2098
+#define CSDM_REG_AGG_INT_EVENT_25 0xc209c
+#define CSDM_REG_AGG_INT_EVENT_26 0xc20a0
+#define CSDM_REG_AGG_INT_EVENT_27 0xc20a4
+#define CSDM_REG_AGG_INT_EVENT_28 0xc20a8
+#define CSDM_REG_AGG_INT_EVENT_29 0xc20ac
+#define CSDM_REG_AGG_INT_EVENT_3 0xc2044
+#define CSDM_REG_AGG_INT_EVENT_30 0xc20b0
+#define CSDM_REG_AGG_INT_EVENT_31 0xc20b4
+#define CSDM_REG_AGG_INT_EVENT_4 0xc2048
+/* [RW 1] The T bit for aggregated interrupt 0 */
+#define CSDM_REG_AGG_INT_T_0 0xc20b8
+#define CSDM_REG_AGG_INT_T_1 0xc20bc
+#define CSDM_REG_AGG_INT_T_10 0xc20e0
+#define CSDM_REG_AGG_INT_T_11 0xc20e4
+#define CSDM_REG_AGG_INT_T_12 0xc20e8
+#define CSDM_REG_AGG_INT_T_13 0xc20ec
+#define CSDM_REG_AGG_INT_T_14 0xc20f0
+#define CSDM_REG_AGG_INT_T_15 0xc20f4
+#define CSDM_REG_AGG_INT_T_16 0xc20f8
+#define CSDM_REG_AGG_INT_T_17 0xc20fc
+#define CSDM_REG_AGG_INT_T_18 0xc2100
+#define CSDM_REG_AGG_INT_T_19 0xc2104
/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
#define CSDM_REG_CFC_RSP_START_ADDR 0xc2008
/* [RW 16] The maximum value of the competion counter #0 */
@@ -358,6 +398,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define CSDM_REG_CSDM_INT_MASK_0 0xc229c
#define CSDM_REG_CSDM_INT_MASK_1 0xc22ac
+/* [R 32] Interrupt register #0 read */
+#define CSDM_REG_CSDM_INT_STS_0 0xc2290
+#define CSDM_REG_CSDM_INT_STS_1 0xc22a0
/* [RW 11] Parity mask register #0 read/write */
#define CSDM_REG_CSDM_PRTY_MASK 0xc22bc
/* [R 11] Parity register #0 read */
@@ -443,6 +486,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define CSEM_REG_CSEM_INT_MASK_0 0x200110
#define CSEM_REG_CSEM_INT_MASK_1 0x200120
+/* [R 32] Interrupt register #0 read */
+#define CSEM_REG_CSEM_INT_STS_0 0x200104
+#define CSEM_REG_CSEM_INT_STS_1 0x200114
/* [RW 32] Parity mask register #0 read/write */
#define CSEM_REG_CSEM_PRTY_MASK_0 0x200130
#define CSEM_REG_CSEM_PRTY_MASK_1 0x200140
@@ -453,9 +499,8 @@
#define CSEM_REG_ENABLE_OUT 0x2000a8
/* [RW 32] This address space contains all registers and memories that are
placed in SEM_FAST block. The SEM_FAST registers are described in
- appendix B. In order to access the SEM_FAST registers the base address
- CSEM_REGISTERS_FAST_MEMORY (Offset: 0x220000) should be added to each
- SEM_FAST register offset. */
+ appendix B. In order to access the sem_fast registers the base address
+ ~fast_memory.fast_memory should be added to eachsem_fast register offset. */
#define CSEM_REG_FAST_MEMORY 0x220000
/* [RW 1] Disables input messages from FIC0 May be updated during run_time
by the microcode */
@@ -539,13 +584,10 @@
#define DBG_REG_DBG_PRTY_MASK 0xc0a8
/* [R 1] Parity register #0 read */
#define DBG_REG_DBG_PRTY_STS 0xc09c
-/* [RW 2] debug only: These bits indicate the credit for PCI request type 4
- interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are
- configured */
-#define DBG_REG_PCI_REQ_CREDIT 0xc120
/* [RW 32] Commands memory. The address to command X; row Y is to calculated
as 14*X+Y. */
#define DMAE_REG_CMD_MEM 0x102400
+#define DMAE_REG_CMD_MEM_SIZE 224
/* [RW 1] If 0 - the CRC-16c initial value is all zeroes; if 1 - the CRC-16c
initial value is all ones. */
#define DMAE_REG_CRC16C_INIT 0x10201c
@@ -630,6 +672,8 @@
#define DORQ_REG_AGG_CMD3 0x17006c
/* [RW 28] UCM Header. */
#define DORQ_REG_CMHEAD_RX 0x170050
+/* [RW 32] Doorbell address for RBC doorbells (function 0). */
+#define DORQ_REG_DB_ADDR0 0x17008c
/* [RW 5] Interrupt mask register #0 read/write */
#define DORQ_REG_DORQ_INT_MASK 0x170180
/* [R 5] Interrupt register #0 read */
@@ -690,75 +734,33 @@
#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1)
#define HC_REG_AGG_INT_0 0x108050
#define HC_REG_AGG_INT_1 0x108054
-/* [RW 16] attention bit and attention acknowledge bits status for port 0
- and 1 according to the following address map: addr 0 - attn_bit_0; addr 1
- - attn_ack_bit_0; addr 2 - attn_bit_1; addr 3 - attn_ack_bit_1; */
#define HC_REG_ATTN_BIT 0x108120
-/* [RW 16] attn bits status index for attn bit msg; addr 0 - function 0;
- addr 1 - functin 1 */
#define HC_REG_ATTN_IDX 0x108100
-/* [RW 32] port 0 lower 32 bits address field for attn messag. */
#define HC_REG_ATTN_MSG0_ADDR_L 0x108018
-/* [RW 32] port 1 lower 32 bits address field for attn messag. */
#define HC_REG_ATTN_MSG1_ADDR_L 0x108020
-/* [RW 8] status block number for attn bit msg - function 0; */
#define HC_REG_ATTN_NUM_P0 0x108038
-/* [RW 8] status block number for attn bit msg - function 1 */
#define HC_REG_ATTN_NUM_P1 0x10803c
#define HC_REG_CONFIG_0 0x108000
#define HC_REG_CONFIG_1 0x108004
+#define HC_REG_FUNC_NUM_P0 0x1080ac
+#define HC_REG_FUNC_NUM_P1 0x1080b0
/* [RW 3] Parity mask register #0 read/write */
#define HC_REG_HC_PRTY_MASK 0x1080a0
/* [R 3] Parity register #0 read */
#define HC_REG_HC_PRTY_STS 0x108094
-/* [RW 17] status block interrupt mask; one in each bit means unmask; zerow
- in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1...
- bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */
#define HC_REG_INT_MASK 0x108108
-/* [RW 16] port 0 attn bit condition monitoring; each bit that is set will
- lock a change fron 0 to 1 in the corresponding attention signals that
- comes from the AEU */
#define HC_REG_LEADING_EDGE_0 0x108040
#define HC_REG_LEADING_EDGE_1 0x108048
-/* [RW 16] all producer and consumer of port 0 according to the following
- addresses; U_prod: 0-15; C_prod: 16-31; U_cons: 32-47; C_cons:48-63;
- Defoult_prod: U/C/X/T/Attn-64/65/66/67/68; Defoult_cons:
- U/C/X/T/Attn-69/70/71/72/73 */
#define HC_REG_P0_PROD_CONS 0x108200
-/* [RW 16] all producer and consumer of port 1according to the following
- addresses; U_prod: 0-15; C_prod: 16-31; U_cons: 32-47; C_cons:48-63;
- Defoult_prod: U/C/X/T/Attn-64/65/66/67/68; Defoult_cons:
- U/C/X/T/Attn-69/70/71/72/73 */
#define HC_REG_P1_PROD_CONS 0x108400
-/* [W 1] This register is write only and has 4 addresses as follow: 0 =
- clear all PBA bits port 0; 1 = clear all pending interrupts request
- port0; 2 = clear all PBA bits port 1; 3 = clear all pending interrupts
- request port1; here is no meaning for the data in this register */
#define HC_REG_PBA_COMMAND 0x108140
#define HC_REG_PCI_CONFIG_0 0x108010
#define HC_REG_PCI_CONFIG_1 0x108014
-/* [RW 24] all counters acording to the following address: LSB: 0=read; 1=
- read_clear; 0-71 = HW counters (the inside order is the same as the
- interrupt table in the spec); 72-219 = SW counters 1 (stops after first
- consumer upd) the inside order is: 72-103 - U_non_default_p0; 104-135
- C_non_defaul_p0; 36-145 U/C/X/T/Attn_default_p0; 146-177
- U_non_default_p1; 178-209 C_non_defaul_p1; 10-219 U/C/X/T/Attn_default_p1
- ; 220-367 = SW counters 2 (stops when prod=cons) the inside order is:
- 220-251 - U_non_default_p0; 252-283 C_non_defaul_p0; 84-293
- U/C/X/T/Attn_default_p0; 294-325 U_non_default_p1; 326-357
- C_non_defaul_p1; 58-367 U/C/X/T/Attn_default_p1 ; 368-515 = mailbox
- counters; (the inside order of the mailbox counter is 368-431 U and C
- non_default_p0; 432-441 U/C/X/T/Attn_default_p0; 442-505 U and C
- non_default_p1; 506-515 U/C/X/T/Attn_default_p1) */
#define HC_REG_STATISTIC_COUNTERS 0x109000
-/* [RW 16] port 0 attn bit condition monitoring; each bit that is set will
- lock a change fron 1 to 0 in the corresponding attention signals that
- comes from the AEU */
#define HC_REG_TRAILING_EDGE_0 0x108044
#define HC_REG_TRAILING_EDGE_1 0x10804c
#define HC_REG_UC_RAM_ADDR_0 0x108028
#define HC_REG_UC_RAM_ADDR_1 0x108030
-/* [RW 16] ustorm address for coalesc now message */
#define HC_REG_USTORM_ADDR_FOR_COALESCE 0x108068
#define HC_REG_VQID_0 0x108008
#define HC_REG_VQID_1 0x10800c
@@ -883,14 +885,16 @@
rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP Latched
ump_tx_parity; [31] MCP Latched scpad_parity; */
#define MISC_REG_AEU_AFTER_INVERT_4_MCP 0xa458
-/* [W 11] write to this register results with the clear of the latched
+/* [W 14] write to this register results with the clear of the latched
signals; one in d0 clears RBCR latch; one in d1 clears RBCT latch; one in
d2 clears RBCN latch; one in d3 clears RBCU latch; one in d4 clears RBCP
latch; one in d5 clears GRC Latched timeout attention; one in d6 clears
GRC Latched reserved access attention; one in d7 clears Latched
rom_parity; one in d8 clears Latched ump_rx_parity; one in d9 clears
- Latched ump_tx_parity; one in d10 clears Latched scpad_parity; read from
- this register return zero */
+ Latched ump_tx_parity; one in d10 clears Latched scpad_parity (both
+ ports); one in d11 clears pxpv_misc_mps_attn; one in d12 clears
+ pxp_misc_exp_rom_attn0; one in d13 clears pxp_misc_exp_rom_attn1; read
+ from this register return zero */
#define MISC_REG_AEU_CLR_LATCH_SIGNAL 0xa45c
/* [RW 32] first 32b for enabling the output for function 0 output0. mapped
as follows: [0] NIG attention for function0; [1] NIG attention for
@@ -907,7 +911,11 @@
TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0 0xa06c
#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1 0xa07c
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_2 0xa08c
#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3 0xa09c
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5 0xa0bc
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6 0xa0cc
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7 0xa0dc
/* [RW 32] first 32b for enabling the output for function 1 output0. mapped
as follows: [0] NIG attention for function0; [1] NIG attention for
function1; [2] GPIO1 function 1; [3] GPIO2 function 1; [4] GPIO3 function
@@ -923,9 +931,13 @@
TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 0xa10c
#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1 0xa11c
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_2 0xa12c
#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3 0xa13c
-/* [RW 32] first 32b for enabling the output for close the gate nig 0.
- mapped as follows: [0] NIG attention for function0; [1] NIG attention for
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5 0xa15c
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6 0xa16c
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7 0xa17c
+/* [RW 32] first 32b for enabling the output for close the gate nig. mapped
+ as follows: [0] NIG attention for function0; [1] NIG attention for
function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function
0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8]
GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
@@ -939,8 +951,8 @@
TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
#define MISC_REG_AEU_ENABLE1_NIG_0 0xa0ec
#define MISC_REG_AEU_ENABLE1_NIG_1 0xa18c
-/* [RW 32] first 32b for enabling the output for close the gate pxp 0.
- mapped as follows: [0] NIG attention for function0; [1] NIG attention for
+/* [RW 32] first 32b for enabling the output for close the gate pxp. mapped
+ as follows: [0] NIG attention for function0; [1] NIG attention for
function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function
0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8]
GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
@@ -984,34 +996,34 @@
interrupt; */
#define MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0 0xa110
#define MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1 0xa120
-/* [RW 32] second 32b for enabling the output for close the gate nig 0.
- mapped as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt;
- [2] QM Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5]
- Timers Hw interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8]
- XCM Parity error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11]
- XSEMI Hw interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw
- interrupt; [14] NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI
- core Parity error; [17] Vaux PCI core Hw interrupt; [18] Debug Parity
- error; [19] Debug Hw interrupt; [20] USDM Parity error; [21] USDM Hw
- interrupt; [22] UCM Parity error; [23] UCM Hw interrupt; [24] USEMI
- Parity error; [25] USEMI Hw interrupt; [26] UPB Parity error; [27] UPB Hw
- interrupt; [28] CSDM Parity error; [29] CSDM Hw interrupt; [30] CCM
- Parity error; [31] CCM Hw interrupt; */
+/* [RW 32] second 32b for enabling the output for close the gate nig. mapped
+ as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM
+ Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw
+ interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity
+ error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw
+ interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14]
+ NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error;
+ [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw
+ interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM
+ Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI
+ Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM
+ Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw
+ interrupt; */
#define MISC_REG_AEU_ENABLE2_NIG_0 0xa0f0
#define MISC_REG_AEU_ENABLE2_NIG_1 0xa190
-/* [RW 32] second 32b for enabling the output for close the gate pxp 0.
- mapped as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt;
- [2] QM Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5]
- Timers Hw interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8]
- XCM Parity error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11]
- XSEMI Hw interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw
- interrupt; [14] NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI
- core Parity error; [17] Vaux PCI core Hw interrupt; [18] Debug Parity
- error; [19] Debug Hw interrupt; [20] USDM Parity error; [21] USDM Hw
- interrupt; [22] UCM Parity error; [23] UCM Hw interrupt; [24] USEMI
- Parity error; [25] USEMI Hw interrupt; [26] UPB Parity error; [27] UPB Hw
- interrupt; [28] CSDM Parity error; [29] CSDM Hw interrupt; [30] CCM
- Parity error; [31] CCM Hw interrupt; */
+/* [RW 32] second 32b for enabling the output for close the gate pxp. mapped
+ as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM
+ Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw
+ interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity
+ error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw
+ interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14]
+ NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error;
+ [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw
+ interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM
+ Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI
+ Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM
+ Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw
+ interrupt; */
#define MISC_REG_AEU_ENABLE2_PXP_0 0xa100
#define MISC_REG_AEU_ENABLE2_PXP_1 0xa1a0
/* [RW 32] third 32b for enabling the output for function 0 output0. mapped
@@ -1044,34 +1056,34 @@
attn1; */
#define MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0 0xa114
#define MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1 0xa124
-/* [RW 32] third 32b for enabling the output for close the gate nig 0.
- mapped as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2]
- PXP Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity
- error; [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC
- Hw interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE
- Parity error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13]
- IGU (HC) Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt;
- [16] pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0;
- [20] MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0;
- [23] SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST;
- [26] SW timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers
- attn_3 func1; [29] SW timers attn_4 func1; [30] General attn0; [31]
- General attn1; */
+/* [RW 32] third 32b for enabling the output for close the gate nig. mapped
+ as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP
+ Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error;
+ [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw
+ interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity
+ error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC)
+ Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16]
+ pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20]
+ MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23]
+ SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW
+ timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3
+ func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General
+ attn1; */
#define MISC_REG_AEU_ENABLE3_NIG_0 0xa0f4
#define MISC_REG_AEU_ENABLE3_NIG_1 0xa194
-/* [RW 32] third 32b for enabling the output for close the gate pxp 0.
- mapped as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2]
- PXP Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity
- error; [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC
- Hw interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE
- Parity error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13]
- IGU (HC) Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt;
- [16] pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0;
- [20] MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0;
- [23] SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST;
- [26] SW timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers
- attn_3 func1; [29] SW timers attn_4 func1; [30] General attn0; [31]
- General attn1; */
+/* [RW 32] third 32b for enabling the output for close the gate pxp. mapped
+ as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP
+ Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error;
+ [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw
+ interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity
+ error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC)
+ Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16]
+ pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20]
+ MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23]
+ SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW
+ timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3
+ func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General
+ attn1; */
#define MISC_REG_AEU_ENABLE3_PXP_0 0xa104
#define MISC_REG_AEU_ENABLE3_PXP_1 0xa1a4
/* [RW 32] fourth 32b for enabling the output for function 0 output0.mapped
@@ -1088,6 +1100,10 @@
Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0 0xa078
#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2 0xa098
+#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4 0xa0b8
+#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5 0xa0c8
+#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6 0xa0d8
+#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7 0xa0e8
/* [RW 32] fourth 32b for enabling the output for function 1 output0.mapped
as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3]
General attn5; [4] General attn6; [5] General attn7; [6] General attn8;
@@ -1102,34 +1118,36 @@
Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0 0xa118
#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2 0xa138
-/* [RW 32] fourth 32b for enabling the output for close the gate nig
- 0.mapped as follows: [0] General attn2; [1] General attn3; [2] General
- attn4; [3] General attn5; [4] General attn6; [5] General attn7; [6]
- General attn8; [7] General attn9; [8] General attn10; [9] General attn11;
- [10] General attn12; [11] General attn13; [12] General attn14; [13]
- General attn15; [14] General attn16; [15] General attn17; [16] General
- attn18; [17] General attn19; [18] General attn20; [19] General attn21;
- [20] Main power interrupt; [21] RBCR Latched attn; [22] RBCT Latched
- attn; [23] RBCN Latched attn; [24] RBCU Latched attn; [25] RBCP Latched
- attn; [26] GRC Latched timeout attention; [27] GRC Latched reserved
- access attention; [28] MCP Latched rom_parity; [29] MCP Latched
- ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched
- scpad_parity; */
+#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4 0xa158
+#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5 0xa168
+#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6 0xa178
+#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7 0xa188
+/* [RW 32] fourth 32b for enabling the output for close the gate nig.mapped
+ as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3]
+ General attn5; [4] General attn6; [5] General attn7; [6] General attn8;
+ [7] General attn9; [8] General attn10; [9] General attn11; [10] General
+ attn12; [11] General attn13; [12] General attn14; [13] General attn15;
+ [14] General attn16; [15] General attn17; [16] General attn18; [17]
+ General attn19; [18] General attn20; [19] General attn21; [20] Main power
+ interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN
+ Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC
+ Latched timeout attention; [27] GRC Latched reserved access attention;
+ [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP
+ Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
#define MISC_REG_AEU_ENABLE4_NIG_0 0xa0f8
#define MISC_REG_AEU_ENABLE4_NIG_1 0xa198
-/* [RW 32] fourth 32b for enabling the output for close the gate pxp
- 0.mapped as follows: [0] General attn2; [1] General attn3; [2] General
- attn4; [3] General attn5; [4] General attn6; [5] General attn7; [6]
- General attn8; [7] General attn9; [8] General attn10; [9] General attn11;
- [10] General attn12; [11] General attn13; [12] General attn14; [13]
- General attn15; [14] General attn16; [15] General attn17; [16] General
- attn18; [17] General attn19; [18] General attn20; [19] General attn21;
- [20] Main power interrupt; [21] RBCR Latched attn; [22] RBCT Latched
- attn; [23] RBCN Latched attn; [24] RBCU Latched attn; [25] RBCP Latched
- attn; [26] GRC Latched timeout attention; [27] GRC Latched reserved
- access attention; [28] MCP Latched rom_parity; [29] MCP Latched
- ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched
- scpad_parity; */
+/* [RW 32] fourth 32b for enabling the output for close the gate pxp.mapped
+ as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3]
+ General attn5; [4] General attn6; [5] General attn7; [6] General attn8;
+ [7] General attn9; [8] General attn10; [9] General attn11; [10] General
+ attn12; [11] General attn13; [12] General attn14; [13] General attn15;
+ [14] General attn16; [15] General attn17; [16] General attn18; [17]
+ General attn19; [18] General attn20; [19] General attn21; [20] Main power
+ interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN
+ Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC
+ Latched timeout attention; [27] GRC Latched reserved access attention;
+ [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP
+ Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
#define MISC_REG_AEU_ENABLE4_PXP_0 0xa108
#define MISC_REG_AEU_ENABLE4_PXP_1 0xa1a8
/* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu
@@ -1148,6 +1166,7 @@
#define MISC_REG_AEU_GENERAL_ATTN_19 0xa04c
#define MISC_REG_AEU_GENERAL_ATTN_10 0xa028
#define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c
+#define MISC_REG_AEU_GENERAL_ATTN_12 0xa030
#define MISC_REG_AEU_GENERAL_ATTN_2 0xa008
#define MISC_REG_AEU_GENERAL_ATTN_20 0xa050
#define MISC_REG_AEU_GENERAL_ATTN_21 0xa054
@@ -1158,6 +1177,7 @@
#define MISC_REG_AEU_GENERAL_ATTN_7 0xa01c
#define MISC_REG_AEU_GENERAL_ATTN_8 0xa020
#define MISC_REG_AEU_GENERAL_ATTN_9 0xa024
+#define MISC_REG_AEU_GENERAL_MASK 0xa61c
/* [RW 32] first 32b for inverting the input for function 0; for each bit:
0= do not invert; 1= invert; mapped as follows: [0] NIG attention for
function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp;
@@ -1189,10 +1209,29 @@
#define MISC_REG_AEU_INVERTER_2_FUNC_0 0xa230
#define MISC_REG_AEU_INVERTER_2_FUNC_1 0xa240
/* [RW 10] [7:0] = mask 8 attention output signals toward IGU function0;
- [9:8] = mask close the gates signals of function 0 toward PXP [8] and NIG
- [9]. Zero = mask; one = unmask */
+ [9:8] = raserved. Zero = mask; one = unmask */
#define MISC_REG_AEU_MASK_ATTN_FUNC_0 0xa060
#define MISC_REG_AEU_MASK_ATTN_FUNC_1 0xa064
+/* [RW 1] If set a system kill occurred */
+#define MISC_REG_AEU_SYS_KILL_OCCURRED 0xa610
+/* [RW 32] Represent the status of the input vector to the AEU when a system
+ kill occurred. The register is reset in por reset. Mapped as follows: [0]
+ NIG attention for function0; [1] NIG attention for function1; [2] GPIO1
+ mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp; [6] GPIO1 function 1;
+ [7] GPIO2 function 1; [8] GPIO3 function 1; [9] GPIO4 function 1; [10]
+ PCIE glue/PXP VPD event function0; [11] PCIE glue/PXP VPD event
+ function1; [12] PCIE glue/PXP Expansion ROM event0; [13] PCIE glue/PXP
+ Expansion ROM event1; [14] SPIO4; [15] SPIO5; [16] MSI/X indication for
+ mcp; [17] MSI/X indication for function 1; [18] BRB Parity error; [19]
+ BRB Hw interrupt; [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC
+ Parity error; [23] SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw
+ interrupt; [26] TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI
+ Parity error; [29] TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw
+ interrupt; */
+#define MISC_REG_AEU_SYS_KILL_STATUS_0 0xa600
+#define MISC_REG_AEU_SYS_KILL_STATUS_1 0xa604
+#define MISC_REG_AEU_SYS_KILL_STATUS_2 0xa608
+#define MISC_REG_AEU_SYS_KILL_STATUS_3 0xa60c
/* [R 4] This field indicates the type of the device. '0' - 2 Ports; '1' - 1
Port. */
#define MISC_REG_BOND_ID 0xa400
@@ -1206,8 +1245,80 @@
starts at 0x0 for the A0 tape-out and increments by one for each
all-layer tape-out. */
#define MISC_REG_CHIP_REV 0xa40c
-/* [RW 32] The following driver registers(1..6) represent 6 drivers and 32
- clients. Each client can be controlled by one driver only. One in each
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_10 0xa3e0
+#define MISC_REG_DRIVER_CONTROL_10_SIZE 2
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_11 0xa3e8
+#define MISC_REG_DRIVER_CONTROL_11_SIZE 2
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_12 0xa3f0
+#define MISC_REG_DRIVER_CONTROL_12_SIZE 2
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_13 0xa3f8
+#define MISC_REG_DRIVER_CONTROL_13_SIZE 2
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
bit represent that this driver control the appropriate client (Ex: bit 5
is set means this driver control client number 5). addr1 = set; addr0 =
clear; read from both addresses will give the same result = status. write
@@ -1223,6 +1334,47 @@
it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
be asserted). */
#define MISC_REG_DRIVER_CONTROL_1 0xa510
+#define MISC_REG_DRIVER_CONTROL_14 0xa5e0
+#define MISC_REG_DRIVER_CONTROL_14_SIZE 2
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_15 0xa5e8
+#define MISC_REG_DRIVER_CONTROL_15_SIZE 2
+/* [RW 32] The following driver registers(1...16) represent 16 drivers and
+ 32 clients. Each client can be controlled by one driver only. One in each
+ bit represent that this driver control the appropriate client (Ex: bit 5
+ is set means this driver control client number 5). addr1 = set; addr0 =
+ clear; read from both addresses will give the same result = status. write
+ to address 1 will set a request to control all the clients that their
+ appropriate bit (in the write command) is set. if the client is free (the
+ appropriate bit in all the other drivers is clear) one will be written to
+ that driver register; if the client isn't free the bit will remain zero.
+ if the appropriate bit is set (the driver request to gain control on a
+ client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
+ interrupt will be asserted). write to address 0 will set a request to
+ free all the clients that their appropriate bit (in the write command) is
+ set. if the appropriate bit is clear (the driver request to free a client
+ it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
+ be asserted). */
+#define MISC_REG_DRIVER_CONTROL_16 0xa5f0
+#define MISC_REG_DRIVER_CONTROL_16_SIZE 2
+/* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0
+ only. */
+#define MISC_REG_E1HMF_MODE 0xa5f8
/* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
these bits is written as a '1'; the corresponding SPIO bit will turn off
it's drivers and become an input. This is the reset state of all GPIO
@@ -1240,6 +1392,18 @@
This is the result value of the pin; not the drive value. Writing these
bits will have not effect. */
#define MISC_REG_GPIO 0xa490
+/* [R 28] this field hold the last information that caused reserved
+ attention. bits [19:0] - address; [22:20] function; [23] reserved;
+ [27:24] the master thatcaused the attention - according to the following
+ encodeing:1 = pxp; 2 = mcp; 3 = usdm; 4 = tsdm; 5 = xsdm; 6 = csdm; 7 =
+ dbu; 8 = dmae */
+#define MISC_REG_GRC_RSV_ATTN 0xa3c0
+/* [R 28] this field hold the last information that caused timeout
+ attention. bits [19:0] - address; [22:20] function; [23] reserved;
+ [27:24] the master thatcaused the attention - according to the following
+ encodeing:1 = pxp; 2 = mcp; 3 = usdm; 4 = tsdm; 5 = xsdm; 6 = csdm; 7 =
+ dbu; 8 = dmae */
+#define MISC_REG_GRC_TIMEOUT_ATTN 0xa3c4
/* [RW 1] Setting this bit enables a timer in the GRC block to timeout any
access that does not finish within
~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is
@@ -1282,6 +1446,11 @@
#define MISC_REG_MISC_PRTY_MASK 0xa398
/* [R 1] Parity register #0 read */
#define MISC_REG_MISC_PRTY_STS 0xa38c
+#define MISC_REG_NIG_WOL_P0 0xa270
+#define MISC_REG_NIG_WOL_P1 0xa274
+/* [R 1] If set indicate that the pcie_rst_b was asserted without perst
+ assertion */
+#define MISC_REG_PCIE_HOT_RESET 0xa618
/* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911.
inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1
divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1
@@ -1303,7 +1472,7 @@
#define MISC_REG_PLL_STORM_CTRL_2 0xa298
#define MISC_REG_PLL_STORM_CTRL_3 0xa29c
#define MISC_REG_PLL_STORM_CTRL_4 0xa2a0
-/* [RW 32] reset reg#1; rite/read one = the specific block is out of reset;
+/* [RW 32] reset reg#2; rite/read one = the specific block is out of reset;
write/read zero = the specific block is in reset; addr 0-wr- the write
value will be written to the register; addr 1-set - one will be written
to all the bits that have the value of one in the data written (bits that
@@ -1311,14 +1480,12 @@
written to all the bits that have the value of one in the data written
(bits that have the value of zero will not be change); addr 3-ignore;
read ignore from all addr except addr 00; inside order of the bits is:
- [0] rst_brb1; [1] rst_prs; [2] rst_src; [3] rst_tsdm; [4] rst_tsem; [5]
- rst_tcm; [6] rst_rbcr; [7] rst_nig; [8] rst_usdm; [9] rst_ucm; [10]
- rst_usem; [11] rst_upb; [12] rst_ccm; [13] rst_csem; [14] rst_csdm; [15]
- rst_rbcu; [16] rst_pbf; [17] rst_qm; [18] rst_tm; [19] rst_dorq; [20]
- rst_xcm; [21] rst_xsdm; [22] rst_xsem; [23] rst_rbct; [24] rst_cdu; [25]
- rst_cfc; [26] rst_pxp; [27] rst_pxpv; [28] rst_rbcp; [29] rst_hc; [30]
- rst_dmae; [31] rst_semi_rtc; */
-#define MISC_REG_RESET_REG_1 0xa580
+ [0] rst_bmac0; [1] rst_bmac1; [2] rst_emac0; [3] rst_emac1; [4] rst_grc;
+ [5] rst_mcp_n_reset_reg_hard_core; [6] rst_ mcp_n_hard_core_rst_b; [7]
+ rst_ mcp_n_reset_cmn_cpu; [8] rst_ mcp_n_reset_cmn_core; [9] rst_rbcn;
+ [10] rst_dbg; [11] rst_misc_core; [12] rst_dbue (UART); [13]
+ Pci_resetmdio_n; [14] rst_emac0_hard_core; [15] rst_emac1_hard_core; 16]
+ rst_pxp_rq_rd_wr; 31:17] reserved */
#define MISC_REG_RESET_REG_2 0xa590
/* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is
shared with the driver resides */
@@ -1345,7 +1512,7 @@
select VAUX supply. (This is an output pin only; it is not controlled by
the SET and CLR fields; it is controlled by the Main Power SM; the FLOAT
field is not applicable for this pin; only the VALUE fields is relevant -
- it reflects the output value); [3] reserved; [4] spio_4; [5] spio_5; [6]
+ it reflects the output value); [3] port swap [4] spio_4; [5] spio_5; [6]
Bit 0 of UMP device ID select; read by UMP firmware; [7] Bit 1 of UMP
device ID select; read by UMP firmware. */
#define MISC_REG_SPIO 0xa4fc
@@ -1394,8 +1561,9 @@
#define NIG_REG_BRB1_PAUSE_IN_EN 0x100c8
/* [RW 1] output enable for RX BRB1 LP IF */
#define NIG_REG_BRB_LB_OUT_EN 0x10100
-/* [WB_W 72] Debug packet to LP from RBC; Data spelling:[63:0] data; 64]
- error; [67:65]eop_bvalid; [68]eop; [69]sop; [70]port_id; 71]flush */
+/* [WB_W 82] Debug packet to LP from RBC; Data spelling:[63:0] data; 64]
+ error; [67:65]eop_bvalid; [68]eop; [69]sop; [70]port_id; 71]flush;
+ 72:73]-vnic_num; 81:74]-sideband_info */
#define NIG_REG_DEBUG_PACKET_LB 0x10800
/* [RW 1] Input enable for TX Debug packet */
#define NIG_REG_EGRESS_DEBUG_IN_EN 0x100dc
@@ -1409,6 +1577,8 @@
/* [RW 1] MAC configuration for packets of port0. If 1 - all packet outputs
to emac for port0; other way to bmac for port0 */
#define NIG_REG_EGRESS_EMAC0_PORT 0x10058
+/* [RW 32] TX_MNG_FIFO in NIG_TX_PORT0; data[31:0] written in FIFO order. */
+#define NIG_REG_EGRESS_MNG0_FIFO 0x1045c
/* [RW 1] Input enable for TX PBF user packet port0 IF */
#define NIG_REG_EGRESS_PBF0_IN_EN 0x100cc
/* [RW 1] Input enable for TX PBF user packet port1 IF */
@@ -1438,6 +1608,8 @@
#define NIG_REG_INGRESS_EOP_LB_FIFO 0x104e4
/* [RW 1] led 10g for port 0 */
#define NIG_REG_LED_10G_P0 0x10320
+/* [RW 1] led 10g for port 1 */
+#define NIG_REG_LED_10G_P1 0x10324
/* [RW 1] Port0: This bit is set to enable the use of the
~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 field
defined below. If this bit is cleared; then the blink rate will be about
@@ -1448,7 +1620,7 @@
is reset to 0x080; giving a default blink period of approximately 8Hz. */
#define NIG_REG_LED_CONTROL_BLINK_RATE_P0 0x10310
/* [RW 1] Port0: If set along with the
- nig_registers_led_control_override_traffic_p0.led_control_override_traffic_p0
+ ~nig_registers_led_control_override_traffic_p0.led_control_override_traffic_p0
bit and ~nig_registers_led_control_traffic_p0.led_control_traffic_p0 LED
bit; the Traffic LED will blink with the blink rate specified in
~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 and
@@ -1470,19 +1642,47 @@
/* [RW 4] led mode for port0: 0 MAC; 1-3 PHY1; 4 MAC2; 5-7 PHY4; 8-MAC3;
9-11PHY7; 12 MAC4; 13-15 PHY10; */
#define NIG_REG_LED_MODE_P0 0x102f0
+#define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c
+#define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154
#define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244
+#define NIG_REG_LLH0_BRB1_DRV_MASK_MF 0x16048
/* [RW 1] send to BRB1 if no match on any of RMP rules. */
#define NIG_REG_LLH0_BRB1_NOT_MCP 0x1025c
+/* [RW 2] Determine the classification participants. 0: no classification.1:
+ classification upon VLAN id. 2: classification upon MAC address. 3:
+ classification upon both VLAN id & MAC addr. */
+#define NIG_REG_LLH0_CLS_TYPE 0x16080
/* [RW 32] cm header for llh0 */
#define NIG_REG_LLH0_CM_HEADER 0x1007c
+#define NIG_REG_LLH0_DEST_IP_0_1 0x101dc
+#define NIG_REG_LLH0_DEST_MAC_0_0 0x101c0
+/* [RW 16] destination TCP address 1. The LLH will look for this address in
+ all incoming packets. */
+#define NIG_REG_LLH0_DEST_TCP_0 0x10220
+/* [RW 16] destination UDP address 1 The LLH will look for this address in
+ all incoming packets. */
+#define NIG_REG_LLH0_DEST_UDP_0 0x10214
#define NIG_REG_LLH0_ERROR_MASK 0x1008c
/* [RW 8] event id for llh0 */
#define NIG_REG_LLH0_EVENT_ID 0x10084
+#define NIG_REG_LLH0_FUNC_EN 0x160fc
+#define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100
+/* [RW 1] Determine the IP version to look for in
+ ~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */
+#define NIG_REG_LLH0_IPV4_IPV6_0 0x10208
+/* [RW 1] t bit for llh0 */
+#define NIG_REG_LLH0_T_BIT 0x10074
+/* [RW 12] VLAN ID 1. In case of VLAN packet the LLH will look for this ID. */
+#define NIG_REG_LLH0_VLAN_ID_0 0x1022c
/* [RW 8] init credit counter for port0 in LLH */
#define NIG_REG_LLH0_XCM_INIT_CREDIT 0x10554
#define NIG_REG_LLH0_XCM_MASK 0x10130
/* [RW 1] send to BRB1 if no match on any of RMP rules. */
#define NIG_REG_LLH1_BRB1_NOT_MCP 0x102dc
+/* [RW 2] Determine the classification participants. 0: no classification.1:
+ classification upon VLAN id. 2: classification upon MAC address. 3:
+ classification upon both VLAN id & MAC addr. */
+#define NIG_REG_LLH1_CLS_TYPE 0x16084
/* [RW 32] cm header for llh1 */
#define NIG_REG_LLH1_CM_HEADER 0x10080
#define NIG_REG_LLH1_ERROR_MASK 0x10090
@@ -1491,13 +1691,26 @@
/* [RW 8] init credit counter for port1 in LLH */
#define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564
#define NIG_REG_LLH1_XCM_MASK 0x10134
+/* [RW 1] When this bit is set; the LLH will expect all packets to be with
+ e1hov */
+#define NIG_REG_LLH_E1HOV_MODE 0x160d8
+/* [RW 1] When this bit is set; the LLH will classify the packet before
+ sending it to the BRB or calculating WoL on it. */
+#define NIG_REG_LLH_MF_MODE 0x16024
#define NIG_REG_MASK_INTERRUPT_PORT0 0x10330
#define NIG_REG_MASK_INTERRUPT_PORT1 0x10334
/* [RW 1] Output signal from NIG to EMAC0. When set enables the EMAC0 block. */
#define NIG_REG_NIG_EMAC0_EN 0x1003c
+/* [RW 1] Output signal from NIG to EMAC1. When set enables the EMAC1 block. */
+#define NIG_REG_NIG_EMAC1_EN 0x10040
/* [RW 1] Output signal from NIG to TX_EMAC0. When set indicates to the
EMAC0 to strip the CRC from the ingress packets. */
#define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC 0x10044
+/* [R 32] Interrupt register #0 read */
+#define NIG_REG_NIG_INT_STS_0 0x103b0
+#define NIG_REG_NIG_INT_STS_1 0x103c0
+/* [R 32] Parity register #0 read */
+#define NIG_REG_NIG_PRTY_STS 0x103d0
/* [RW 1] Input enable for RX PBF LP IF */
#define NIG_REG_PBF_LB_IN_EN 0x100b4
/* [RW 1] Value of this register will be transmitted to port swap when
@@ -1514,9 +1727,21 @@
/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure
for port0 */
#define NIG_REG_STAT0_BRB_DISCARD 0x105f0
+/* [WB_R 36] Tx statistics : Number of packets from emac0 or bmac0 that
+ between 1024 and 1522 bytes for port0 */
+#define NIG_REG_STAT0_EGRESS_MAC_PKT0 0x10750
+/* [WB_R 36] Tx statistics : Number of packets from emac0 or bmac0 that
+ between 1523 bytes and above for port0 */
+#define NIG_REG_STAT0_EGRESS_MAC_PKT1 0x10760
/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure
for port1 */
#define NIG_REG_STAT1_BRB_DISCARD 0x10628
+/* [WB_R 36] Tx statistics : Number of packets from emac1 or bmac1 that
+ between 1024 and 1522 bytes for port1 */
+#define NIG_REG_STAT1_EGRESS_MAC_PKT0 0x107a0
+/* [WB_R 36] Tx statistics : Number of packets from emac1 or bmac1 that
+ between 1523 bytes and above for port1 */
+#define NIG_REG_STAT1_EGRESS_MAC_PKT1 0x107b0
/* [WB_R 64] Rx statistics : User octets received for LP */
#define NIG_REG_STAT2_BRB_OCTET 0x107e0
#define NIG_REG_STATUS_INTERRUPT_PORT0 0x10328
@@ -1529,8 +1754,12 @@
#define NIG_REG_XCM0_OUT_EN 0x100f0
/* [RW 1] output enable for RX_XCM1 IF */
#define NIG_REG_XCM1_OUT_EN 0x100f4
+/* [RW 1] control to xgxs - remote PHY in-band MDIO */
+#define NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST 0x10348
/* [RW 5] control to xgxs - CL45 DEVAD */
#define NIG_REG_XGXS0_CTRL_MD_DEVAD 0x1033c
+/* [RW 1] control to xgxs; 0 - clause 45; 1 - clause 22 */
+#define NIG_REG_XGXS0_CTRL_MD_ST 0x10338
/* [RW 5] control to xgxs - CL22 PHY_ADD and CL45 PRTAD */
#define NIG_REG_XGXS0_CTRL_PHY_ADDR 0x10340
/* [R 1] status from xgxs0 that inputs to interrupt logic of link10g. */
@@ -1626,7 +1855,6 @@
#define PRS_REG_CFC_SEARCH_INITIAL_CREDIT 0x4011c
/* [RW 24] CID for port 0 if no match */
#define PRS_REG_CID_PORT_0 0x400fc
-#define PRS_REG_CID_PORT_1 0x40100
/* [RW 32] The CM header for flush message where 'load existed' bit in CFC
load response is reset and packet type is 0. Used in packet start message
to TCM. */
@@ -1658,11 +1886,15 @@
#define PRS_REG_CM_HDR_TYPE_4 0x40088
/* [RW 32] The CM header in case there was not a match on the connection */
#define PRS_REG_CM_NO_MATCH_HDR 0x400b8
+/* [RW 1] Indicates if in e1hov mode. 0=non-e1hov mode; 1=e1hov mode. */
+#define PRS_REG_E1HOV_MODE 0x401c8
/* [RW 8] The 8-bit event ID for a match and packet type 1. Used in packet
start message to TCM. */
#define PRS_REG_EVENT_ID_1 0x40054
#define PRS_REG_EVENT_ID_2 0x40058
#define PRS_REG_EVENT_ID_3 0x4005c
+/* [RW 16] The Ethernet type value for FCoE */
+#define PRS_REG_FCOE_TYPE 0x401d0
/* [RW 8] Context region for flush packet with packet type 0. Used in CFC
load request message. */
#define PRS_REG_FLUSH_REGIONS_TYPE_0 0x40004
@@ -1730,8 +1962,17 @@
#define PXP2_REG_HST_DATA_FIFO_STATUS 0x12047c
/* [R 7] Debug only: Number of used entries in the header FIFO */
#define PXP2_REG_HST_HEADER_FIFO_STATUS 0x120478
+#define PXP2_REG_PGL_ADDR_88_F0 0x120534
+#define PXP2_REG_PGL_ADDR_8C_F0 0x120538
+#define PXP2_REG_PGL_ADDR_90_F0 0x12053c
+#define PXP2_REG_PGL_ADDR_94_F0 0x120540
#define PXP2_REG_PGL_CONTROL0 0x120490
#define PXP2_REG_PGL_CONTROL1 0x120514
+/* [RW 32] third dword data of expansion rom request. this register is
+ special. reading from it provides a vector outstanding read requests. if
+ a bit is zero it means that a read request on the corresponding tag did
+ not finish yet (not all completions have arrived for it) */
+#define PXP2_REG_PGL_EXP_ROM2 0x120808
/* [RW 32] Inbound interrupt table for CSDM: bits[31:16]-mask;
its[15:0]-address */
#define PXP2_REG_PGL_INT_CSDM_0 0x1204f4
@@ -1775,8 +2016,7 @@
/* [R 1] this bit indicates that a read request was blocked because of
bus_master_en was deasserted */
#define PXP2_REG_PGL_READ_BLOCKED 0x120568
-/* [R 6] debug only */
-#define PXP2_REG_PGL_TXR_CDTS 0x120528
+#define PXP2_REG_PGL_TAGS_LIMIT 0x1205a8
/* [R 18] debug only */
#define PXP2_REG_PGL_TXW_CDTS 0x12052c
/* [R 1] this bit indicates that a write request was blocked because of
@@ -1828,12 +2068,14 @@
#define PXP2_REG_PSWRQ_QM0_L2P 0x120038
#define PXP2_REG_PSWRQ_SRC0_L2P 0x120054
#define PXP2_REG_PSWRQ_TM0_L2P 0x12001c
-/* [RW 25] Interrupt mask register #0 read/write */
-#define PXP2_REG_PXP2_INT_MASK 0x120578
-/* [R 25] Interrupt register #0 read */
-#define PXP2_REG_PXP2_INT_STS 0x12056c
-/* [RC 25] Interrupt register #0 read clear */
-#define PXP2_REG_PXP2_INT_STS_CLR 0x120570
+#define PXP2_REG_PSWRQ_TSDM0_L2P 0x1200e0
+/* [RW 32] Interrupt mask register #0 read/write */
+#define PXP2_REG_PXP2_INT_MASK_0 0x120578
+/* [R 32] Interrupt register #0 read */
+#define PXP2_REG_PXP2_INT_STS_0 0x12056c
+#define PXP2_REG_PXP2_INT_STS_1 0x120608
+/* [RC 32] Interrupt register #0 read clear */
+#define PXP2_REG_PXP2_INT_STS_CLR_0 0x120570
/* [RW 32] Parity mask register #0 read/write */
#define PXP2_REG_PXP2_PRTY_MASK_0 0x120588
#define PXP2_REG_PXP2_PRTY_MASK_1 0x120598
@@ -2016,8 +2258,12 @@
#define PXP2_REG_RQ_BW_WR_UBOUND29 0x1202a4
/* [RW 7] Bandwidth upper bound for VQ30 */
#define PXP2_REG_RQ_BW_WR_UBOUND30 0x1202a8
+/* [RW 18] external first_mem_addr field in L2P table for CDU module port 0 */
+#define PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR 0x120008
/* [RW 2] Endian mode for cdu */
#define PXP2_REG_RQ_CDU_ENDIAN_M 0x1201a0
+#define PXP2_REG_RQ_CDU_FIRST_ILT 0x12061c
+#define PXP2_REG_RQ_CDU_LAST_ILT 0x120620
/* [RW 3] page size in L2P table for CDU module; -4k; -8k; -16k; -32k; -64k;
-128k */
#define PXP2_REG_RQ_CDU_P_SIZE 0x120018
@@ -2029,14 +2275,26 @@
/* [RW 1] When '1'; requests will enter input buffers but wont get out
towards the glue */
#define PXP2_REG_RQ_DISABLE_INPUTS 0x120330
+/* [RW 1] 1 - SR will be aligned by 64B; 0 - SR will be aligned by 8B */
+#define PXP2_REG_RQ_DRAM_ALIGN 0x1205b0
+/* [RW 1] If 1 ILT failiue will not result in ELT access; An interrupt will
+ be asserted */
+#define PXP2_REG_RQ_ELT_DISABLE 0x12066c
/* [RW 2] Endian mode for hc */
#define PXP2_REG_RQ_HC_ENDIAN_M 0x1201a8
+/* [RW 1] when '0' ILT logic will work as in A0; otherwise B0; for back
+ compatibility needs; Note that different registers are used per mode */
+#define PXP2_REG_RQ_ILT_MODE 0x1205b4
/* [WB 53] Onchip address table */
#define PXP2_REG_RQ_ONCHIP_AT 0x122000
+/* [WB 53] Onchip address table - B0 */
+#define PXP2_REG_RQ_ONCHIP_AT_B0 0x128000
/* [RW 13] Pending read limiter threshold; in Dwords */
#define PXP2_REG_RQ_PDR_LIMIT 0x12033c
/* [RW 2] Endian mode for qm */
#define PXP2_REG_RQ_QM_ENDIAN_M 0x120194
+#define PXP2_REG_RQ_QM_FIRST_ILT 0x120634
+#define PXP2_REG_RQ_QM_LAST_ILT 0x120638
/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k;
-128k */
#define PXP2_REG_RQ_QM_P_SIZE 0x120050
@@ -2050,16 +2308,22 @@
#define PXP2_REG_RQ_RD_MBS1 0x120168
/* [RW 2] Endian mode for src */
#define PXP2_REG_RQ_SRC_ENDIAN_M 0x12019c
+#define PXP2_REG_RQ_SRC_FIRST_ILT 0x12063c
+#define PXP2_REG_RQ_SRC_LAST_ILT 0x120640
/* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k;
-128k */
#define PXP2_REG_RQ_SRC_P_SIZE 0x12006c
/* [RW 2] Endian mode for tm */
#define PXP2_REG_RQ_TM_ENDIAN_M 0x120198
+#define PXP2_REG_RQ_TM_FIRST_ILT 0x120644
+#define PXP2_REG_RQ_TM_LAST_ILT 0x120648
/* [RW 3] page size in L2P table for TM module; -4k; -8k; -16k; -32k; -64k;
-128k */
#define PXP2_REG_RQ_TM_P_SIZE 0x120034
/* [R 5] Number of entries in the ufifo; his fifo has l2p completions */
#define PXP2_REG_RQ_UFIFO_NUM_OF_ENTRY 0x12080c
+/* [RW 18] external first_mem_addr field in L2P table for USDM module port 0 */
+#define PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR 0x120094
/* [R 8] Number of entries occupied by vq 0 in pswrq memory */
#define PXP2_REG_RQ_VQ0_ENTRY_CNT 0x120810
/* [R 8] Number of entries occupied by vq 10 in pswrq memory */
@@ -2130,19 +2394,63 @@
/* [RW 3] Max burst size filed for write requests port 1; 000 - 128B;
001:256B; 010: 512B; */
#define PXP2_REG_RQ_WR_MBS1 0x120164
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_CDU_MPS 0x1205f0
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_CSDM_MPS 0x1205d0
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_DBG_MPS 0x1205e8
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_DMAE_MPS 0x1205ec
/* [RW 10] if Number of entries in dmae fifo will be higer than this
threshold then has_payload indication will be asserted; the default value
should be equal to &gt; write MBS size! */
#define PXP2_REG_WR_DMAE_TH 0x120368
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_HC_MPS 0x1205c8
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_QM_MPS 0x1205dc
+/* [RW 1] 0 - working in A0 mode; - working in B0 mode */
+#define PXP2_REG_WR_REV_MODE 0x120670
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_SRC_MPS 0x1205e4
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_TM_MPS 0x1205e0
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_TSDM_MPS 0x1205d4
/* [RW 10] if Number of entries in usdmdp fifo will be higer than this
threshold then has_payload indication will be asserted; the default value
should be equal to &gt; write MBS size! */
#define PXP2_REG_WR_USDMDP_TH 0x120348
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_USDM_MPS 0x1205cc
+/* [RW 2] 0 - 128B; - 256B; - 512B; - 1024B; when the payload in the
+ buffer reaches this number has_payload will be asserted */
+#define PXP2_REG_WR_XSDM_MPS 0x1205d8
/* [R 1] debug only: Indication if PSWHST arbiter is idle */
#define PXP_REG_HST_ARB_IS_IDLE 0x103004
/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means
this client is waiting for the arbiter. */
#define PXP_REG_HST_CLIENTS_WAITING_TO_ARB 0x103008
+/* [R 1] debug only: '1' means this PSWHST is discarding doorbells. This bit
+ should update accoring to 'hst_discard_doorbells' register when the state
+ machine is idle */
+#define PXP_REG_HST_DISCARD_DOORBELLS_STATUS 0x1030a0
+/* [R 6] debug only: A bit mask for all PSWHST internal write clients. '1'
+ means this PSWHST is discarding inputs from this client. Each bit should
+ update accoring to 'hst_discard_internal_writes' register when the state
+ machine is idle. */
+#define PXP_REG_HST_DISCARD_INTERNAL_WRITES_STATUS 0x10309c
/* [WB 160] Used for initialization of the inbound interrupts memory */
#define PXP_REG_HST_INBOUND_INT 0x103800
/* [RW 32] Interrupt mask register #0 read/write */
@@ -2165,18 +2473,25 @@
#define QM_REG_ACTCTRINITVAL_3 0x16804c
/* [RW 32] The base logical address (in bytes) of each physical queue. The
index I represents the physical queue number. The 12 lsbs are ignore and
- considered zero so practically there are only 20 bits in this register. */
+ considered zero so practically there are only 20 bits in this register;
+ queues 63-0 */
#define QM_REG_BASEADDR 0x168900
/* [RW 16] The byte credit cost for each task. This value is for both ports */
#define QM_REG_BYTECRDCOST 0x168234
/* [RW 16] The initial byte credit value for both ports. */
#define QM_REG_BYTECRDINITVAL 0x168238
/* [RW 32] A bit per physical queue. If the bit is cleared then the physical
- queue uses port 0 else it uses port 1. */
+ queue uses port 0 else it uses port 1; queues 31-0 */
#define QM_REG_BYTECRDPORT_LSB 0x168228
/* [RW 32] A bit per physical queue. If the bit is cleared then the physical
- queue uses port 0 else it uses port 1. */
+ queue uses port 0 else it uses port 1; queues 95-64 */
+#define QM_REG_BYTECRDPORT_LSB_EXT_A 0x16e520
+/* [RW 32] A bit per physical queue. If the bit is cleared then the physical
+ queue uses port 0 else it uses port 1; queues 63-32 */
#define QM_REG_BYTECRDPORT_MSB 0x168224
+/* [RW 32] A bit per physical queue. If the bit is cleared then the physical
+ queue uses port 0 else it uses port 1; queues 127-96 */
+#define QM_REG_BYTECRDPORT_MSB_EXT_A 0x16e51c
/* [RW 16] The byte credit value that if above the QM is considered almost
full */
#define QM_REG_BYTECREDITAFULLTHR 0x168094
@@ -2203,7 +2518,7 @@
#define QM_REG_CMINTVOQMASK_6 0x16820c
#define QM_REG_CMINTVOQMASK_7 0x168210
/* [RW 20] The number of connections divided by 16 which dictates the size
- of each queue per port 0 */
+ of each queue which belongs to even function number. */
#define QM_REG_CONNNUM_0 0x168020
/* [R 6] Keep the fill level of the fifo from write client 4 */
#define QM_REG_CQM_WRC_FIFOLVL 0x168018
@@ -2216,74 +2531,179 @@
bypass enable */
#define QM_REG_ENBYPVOQMASK 0x16823c
/* [RW 32] A bit mask per each physical queue. If a bit is set then the
- physical queue uses the byte credit */
+ physical queue uses the byte credit; queues 31-0 */
#define QM_REG_ENBYTECRD_LSB 0x168220
/* [RW 32] A bit mask per each physical queue. If a bit is set then the
- physical queue uses the byte credit */
+ physical queue uses the byte credit; queues 95-64 */
+#define QM_REG_ENBYTECRD_LSB_EXT_A 0x16e518
+/* [RW 32] A bit mask per each physical queue. If a bit is set then the
+ physical queue uses the byte credit; queues 63-32 */
#define QM_REG_ENBYTECRD_MSB 0x16821c
+/* [RW 32] A bit mask per each physical queue. If a bit is set then the
+ physical queue uses the byte credit; queues 127-96 */
+#define QM_REG_ENBYTECRD_MSB_EXT_A 0x16e514
/* [RW 4] If cleared then the secondary interface will not be served by the
RR arbiter */
#define QM_REG_ENSEC 0x1680f0
-/* [RW 32] A bit vector per each physical queue which selects which function
- number to use on PCI access for that queue. */
+/* [RW 32] NA */
#define QM_REG_FUNCNUMSEL_LSB 0x168230
-/* [RW 32] A bit vector per each physical queue which selects which function
- number to use on PCI access for that queue. */
+/* [RW 32] NA */
#define QM_REG_FUNCNUMSEL_MSB 0x16822c
/* [RW 32] A mask register to mask the Almost empty signals which will not
- be use for the almost empty indication to the HW block */
+ be use for the almost empty indication to the HW block; queues 31:0 */
#define QM_REG_HWAEMPTYMASK_LSB 0x168218
/* [RW 32] A mask register to mask the Almost empty signals which will not
- be use for the almost empty indication to the HW block */
+ be use for the almost empty indication to the HW block; queues 95-64 */
+#define QM_REG_HWAEMPTYMASK_LSB_EXT_A 0x16e510
+/* [RW 32] A mask register to mask the Almost empty signals which will not
+ be use for the almost empty indication to the HW block; queues 63:32 */
#define QM_REG_HWAEMPTYMASK_MSB 0x168214
+/* [RW 32] A mask register to mask the Almost empty signals which will not
+ be use for the almost empty indication to the HW block; queues 127-96 */
+#define QM_REG_HWAEMPTYMASK_MSB_EXT_A 0x16e50c
/* [RW 4] The number of outstanding request to CFC */
#define QM_REG_OUTLDREQ 0x168804
/* [RC 1] A flag to indicate that overflow error occurred in one of the
queues. */
#define QM_REG_OVFERROR 0x16805c
-/* [RC 6] the Q were the qverflow occurs */
+/* [RC 7] the Q were the qverflow occurs */
#define QM_REG_OVFQNUM 0x168058
-/* [R 32] Pause state for physical queues 31-0 */
+/* [R 16] Pause state for physical queues 15-0 */
#define QM_REG_PAUSESTATE0 0x168410
-/* [R 32] Pause state for physical queues 64-32 */
+/* [R 16] Pause state for physical queues 31-16 */
#define QM_REG_PAUSESTATE1 0x168414
+/* [R 16] Pause state for physical queues 47-32 */
+#define QM_REG_PAUSESTATE2 0x16e684
+/* [R 16] Pause state for physical queues 63-48 */
+#define QM_REG_PAUSESTATE3 0x16e688
+/* [R 16] Pause state for physical queues 79-64 */
+#define QM_REG_PAUSESTATE4 0x16e68c
+/* [R 16] Pause state for physical queues 95-80 */
+#define QM_REG_PAUSESTATE5 0x16e690
+/* [R 16] Pause state for physical queues 111-96 */
+#define QM_REG_PAUSESTATE6 0x16e694
+/* [R 16] Pause state for physical queues 127-112 */
+#define QM_REG_PAUSESTATE7 0x16e698
/* [RW 2] The PCI attributes field used in the PCI request. */
#define QM_REG_PCIREQAT 0x168054
/* [R 16] The byte credit of port 0 */
#define QM_REG_PORT0BYTECRD 0x168300
/* [R 16] The byte credit of port 1 */
#define QM_REG_PORT1BYTECRD 0x168304
-/* [WB 54] Pointer Table Memory; The mapping is as follow: ptrtbl[53:30]
- read pointer; ptrtbl[29:6] write pointer; ptrtbl[5:4] read bank0;
- ptrtbl[3:2] read bank 1; ptrtbl[1:0] write bank; */
+/* [RW 3] pci function number of queues 15-0 */
+#define QM_REG_PQ2PCIFUNC_0 0x16e6bc
+#define QM_REG_PQ2PCIFUNC_1 0x16e6c0
+#define QM_REG_PQ2PCIFUNC_2 0x16e6c4
+#define QM_REG_PQ2PCIFUNC_3 0x16e6c8
+#define QM_REG_PQ2PCIFUNC_4 0x16e6cc
+#define QM_REG_PQ2PCIFUNC_5 0x16e6d0
+#define QM_REG_PQ2PCIFUNC_6 0x16e6d4
+#define QM_REG_PQ2PCIFUNC_7 0x16e6d8
+/* [WB 54] Pointer Table Memory for queues 63-0; The mapping is as follow:
+ ptrtbl[53:30] read pointer; ptrtbl[29:6] write pointer; ptrtbl[5:4] read
+ bank0; ptrtbl[3:2] read bank 1; ptrtbl[1:0] write bank; */
#define QM_REG_PTRTBL 0x168a00
+/* [WB 54] Pointer Table Memory for queues 127-64; The mapping is as follow:
+ ptrtbl[53:30] read pointer; ptrtbl[29:6] write pointer; ptrtbl[5:4] read
+ bank0; ptrtbl[3:2] read bank 1; ptrtbl[1:0] write bank; */
+#define QM_REG_PTRTBL_EXT_A 0x16e200
/* [RW 2] Interrupt mask register #0 read/write */
#define QM_REG_QM_INT_MASK 0x168444
/* [R 2] Interrupt register #0 read */
#define QM_REG_QM_INT_STS 0x168438
-/* [RW 9] Parity mask register #0 read/write */
+/* [RW 12] Parity mask register #0 read/write */
#define QM_REG_QM_PRTY_MASK 0x168454
-/* [R 9] Parity register #0 read */
+/* [R 12] Parity register #0 read */
#define QM_REG_QM_PRTY_STS 0x168448
/* [R 32] Current queues in pipeline: Queues from 32 to 63 */
#define QM_REG_QSTATUS_HIGH 0x16802c
+/* [R 32] Current queues in pipeline: Queues from 96 to 127 */
+#define QM_REG_QSTATUS_HIGH_EXT_A 0x16e408
/* [R 32] Current queues in pipeline: Queues from 0 to 31 */
#define QM_REG_QSTATUS_LOW 0x168028
-/* [R 24] The number of tasks queued for each queue */
+/* [R 32] Current queues in pipeline: Queues from 64 to 95 */
+#define QM_REG_QSTATUS_LOW_EXT_A 0x16e404
+/* [R 24] The number of tasks queued for each queue; queues 63-0 */
#define QM_REG_QTASKCTR_0 0x168308
+/* [R 24] The number of tasks queued for each queue; queues 127-64 */
+#define QM_REG_QTASKCTR_EXT_A_0 0x16e584
/* [RW 4] Queue tied to VOQ */
#define QM_REG_QVOQIDX_0 0x1680f4
#define QM_REG_QVOQIDX_10 0x16811c
+#define QM_REG_QVOQIDX_100 0x16e49c
+#define QM_REG_QVOQIDX_101 0x16e4a0
+#define QM_REG_QVOQIDX_102 0x16e4a4
+#define QM_REG_QVOQIDX_103 0x16e4a8
+#define QM_REG_QVOQIDX_104 0x16e4ac
+#define QM_REG_QVOQIDX_105 0x16e4b0
+#define QM_REG_QVOQIDX_106 0x16e4b4
+#define QM_REG_QVOQIDX_107 0x16e4b8
+#define QM_REG_QVOQIDX_108 0x16e4bc
+#define QM_REG_QVOQIDX_109 0x16e4c0
+#define QM_REG_QVOQIDX_100 0x16e49c
+#define QM_REG_QVOQIDX_101 0x16e4a0
+#define QM_REG_QVOQIDX_102 0x16e4a4
+#define QM_REG_QVOQIDX_103 0x16e4a8
+#define QM_REG_QVOQIDX_104 0x16e4ac
+#define QM_REG_QVOQIDX_105 0x16e4b0
+#define QM_REG_QVOQIDX_106 0x16e4b4
+#define QM_REG_QVOQIDX_107 0x16e4b8
+#define QM_REG_QVOQIDX_108 0x16e4bc
+#define QM_REG_QVOQIDX_109 0x16e4c0
#define QM_REG_QVOQIDX_11 0x168120
+#define QM_REG_QVOQIDX_110 0x16e4c4
+#define QM_REG_QVOQIDX_111 0x16e4c8
+#define QM_REG_QVOQIDX_112 0x16e4cc
+#define QM_REG_QVOQIDX_113 0x16e4d0
+#define QM_REG_QVOQIDX_114 0x16e4d4
+#define QM_REG_QVOQIDX_115 0x16e4d8
+#define QM_REG_QVOQIDX_116 0x16e4dc
+#define QM_REG_QVOQIDX_117 0x16e4e0
+#define QM_REG_QVOQIDX_118 0x16e4e4
+#define QM_REG_QVOQIDX_119 0x16e4e8
+#define QM_REG_QVOQIDX_110 0x16e4c4
+#define QM_REG_QVOQIDX_111 0x16e4c8
+#define QM_REG_QVOQIDX_112 0x16e4cc
+#define QM_REG_QVOQIDX_113 0x16e4d0
+#define QM_REG_QVOQIDX_114 0x16e4d4
+#define QM_REG_QVOQIDX_115 0x16e4d8
+#define QM_REG_QVOQIDX_116 0x16e4dc
+#define QM_REG_QVOQIDX_117 0x16e4e0
+#define QM_REG_QVOQIDX_118 0x16e4e4
+#define QM_REG_QVOQIDX_119 0x16e4e8
#define QM_REG_QVOQIDX_12 0x168124
+#define QM_REG_QVOQIDX_120 0x16e4ec
+#define QM_REG_QVOQIDX_121 0x16e4f0
+#define QM_REG_QVOQIDX_122 0x16e4f4
+#define QM_REG_QVOQIDX_123 0x16e4f8
+#define QM_REG_QVOQIDX_124 0x16e4fc
+#define QM_REG_QVOQIDX_125 0x16e500
+#define QM_REG_QVOQIDX_126 0x16e504
+#define QM_REG_QVOQIDX_127 0x16e508
+#define QM_REG_QVOQIDX_120 0x16e4ec
+#define QM_REG_QVOQIDX_121 0x16e4f0
+#define QM_REG_QVOQIDX_122 0x16e4f4
+#define QM_REG_QVOQIDX_123 0x16e4f8
+#define QM_REG_QVOQIDX_124 0x16e4fc
+#define QM_REG_QVOQIDX_125 0x16e500
+#define QM_REG_QVOQIDX_126 0x16e504
+#define QM_REG_QVOQIDX_127 0x16e508
#define QM_REG_QVOQIDX_13 0x168128
#define QM_REG_QVOQIDX_14 0x16812c
#define QM_REG_QVOQIDX_15 0x168130
#define QM_REG_QVOQIDX_16 0x168134
#define QM_REG_QVOQIDX_17 0x168138
#define QM_REG_QVOQIDX_21 0x168148
+#define QM_REG_QVOQIDX_22 0x16814c
+#define QM_REG_QVOQIDX_23 0x168150
+#define QM_REG_QVOQIDX_24 0x168154
#define QM_REG_QVOQIDX_25 0x168158
+#define QM_REG_QVOQIDX_26 0x16815c
+#define QM_REG_QVOQIDX_27 0x168160
+#define QM_REG_QVOQIDX_28 0x168164
#define QM_REG_QVOQIDX_29 0x168168
+#define QM_REG_QVOQIDX_30 0x16816c
+#define QM_REG_QVOQIDX_31 0x168170
#define QM_REG_QVOQIDX_32 0x168174
#define QM_REG_QVOQIDX_33 0x168178
#define QM_REG_QVOQIDX_34 0x16817c
@@ -2328,17 +2748,79 @@
#define QM_REG_QVOQIDX_61 0x1681e8
#define QM_REG_QVOQIDX_62 0x1681ec
#define QM_REG_QVOQIDX_63 0x1681f0
+#define QM_REG_QVOQIDX_64 0x16e40c
+#define QM_REG_QVOQIDX_65 0x16e410
+#define QM_REG_QVOQIDX_66 0x16e414
+#define QM_REG_QVOQIDX_67 0x16e418
+#define QM_REG_QVOQIDX_68 0x16e41c
+#define QM_REG_QVOQIDX_69 0x16e420
#define QM_REG_QVOQIDX_60 0x1681e4
#define QM_REG_QVOQIDX_61 0x1681e8
#define QM_REG_QVOQIDX_62 0x1681ec
#define QM_REG_QVOQIDX_63 0x1681f0
+#define QM_REG_QVOQIDX_64 0x16e40c
+#define QM_REG_QVOQIDX_65 0x16e410
+#define QM_REG_QVOQIDX_69 0x16e420
#define QM_REG_QVOQIDX_7 0x168110
+#define QM_REG_QVOQIDX_70 0x16e424
+#define QM_REG_QVOQIDX_71 0x16e428
+#define QM_REG_QVOQIDX_72 0x16e42c
+#define QM_REG_QVOQIDX_73 0x16e430
+#define QM_REG_QVOQIDX_74 0x16e434
+#define QM_REG_QVOQIDX_75 0x16e438
+#define QM_REG_QVOQIDX_76 0x16e43c
+#define QM_REG_QVOQIDX_77 0x16e440
+#define QM_REG_QVOQIDX_78 0x16e444
+#define QM_REG_QVOQIDX_79 0x16e448
+#define QM_REG_QVOQIDX_70 0x16e424
+#define QM_REG_QVOQIDX_71 0x16e428
+#define QM_REG_QVOQIDX_72 0x16e42c
+#define QM_REG_QVOQIDX_73 0x16e430
+#define QM_REG_QVOQIDX_74 0x16e434
+#define QM_REG_QVOQIDX_75 0x16e438
+#define QM_REG_QVOQIDX_76 0x16e43c
+#define QM_REG_QVOQIDX_77 0x16e440
+#define QM_REG_QVOQIDX_78 0x16e444
+#define QM_REG_QVOQIDX_79 0x16e448
#define QM_REG_QVOQIDX_8 0x168114
+#define QM_REG_QVOQIDX_80 0x16e44c
+#define QM_REG_QVOQIDX_81 0x16e450
+#define QM_REG_QVOQIDX_82 0x16e454
+#define QM_REG_QVOQIDX_83 0x16e458
+#define QM_REG_QVOQIDX_84 0x16e45c
+#define QM_REG_QVOQIDX_85 0x16e460
+#define QM_REG_QVOQIDX_86 0x16e464
+#define QM_REG_QVOQIDX_87 0x16e468
+#define QM_REG_QVOQIDX_88 0x16e46c
+#define QM_REG_QVOQIDX_89 0x16e470
+#define QM_REG_QVOQIDX_80 0x16e44c
+#define QM_REG_QVOQIDX_81 0x16e450
+#define QM_REG_QVOQIDX_85 0x16e460
+#define QM_REG_QVOQIDX_86 0x16e464
+#define QM_REG_QVOQIDX_87 0x16e468
+#define QM_REG_QVOQIDX_88 0x16e46c
+#define QM_REG_QVOQIDX_89 0x16e470
#define QM_REG_QVOQIDX_9 0x168118
-/* [R 24] Remaining pause timeout for port 0 */
-#define QM_REG_REMAINPAUSETM0 0x168418
-/* [R 24] Remaining pause timeout for port 1 */
-#define QM_REG_REMAINPAUSETM1 0x16841c
+#define QM_REG_QVOQIDX_90 0x16e474
+#define QM_REG_QVOQIDX_91 0x16e478
+#define QM_REG_QVOQIDX_92 0x16e47c
+#define QM_REG_QVOQIDX_93 0x16e480
+#define QM_REG_QVOQIDX_94 0x16e484
+#define QM_REG_QVOQIDX_95 0x16e488
+#define QM_REG_QVOQIDX_96 0x16e48c
+#define QM_REG_QVOQIDX_97 0x16e490
+#define QM_REG_QVOQIDX_98 0x16e494
+#define QM_REG_QVOQIDX_99 0x16e498
+#define QM_REG_QVOQIDX_90 0x16e474
+#define QM_REG_QVOQIDX_91 0x16e478
+#define QM_REG_QVOQIDX_92 0x16e47c
+#define QM_REG_QVOQIDX_93 0x16e480
+#define QM_REG_QVOQIDX_94 0x16e484
+#define QM_REG_QVOQIDX_95 0x16e488
+#define QM_REG_QVOQIDX_96 0x16e48c
+#define QM_REG_QVOQIDX_97 0x16e490
+#define QM_REG_QVOQIDX_98 0x16e494
+#define QM_REG_QVOQIDX_99 0x16e498
/* [RW 1] Initialization bit command */
#define QM_REG_SOFT_RESET 0x168428
/* [RW 8] The credit cost per every task in the QM. A value per each VOQ */
@@ -2372,44 +2854,103 @@
#define QM_REG_VOQINITCREDIT_4 0x168070
#define QM_REG_VOQINITCREDIT_5 0x168074
/* [RW 1] The port of which VOQ belongs */
+#define QM_REG_VOQPORT_0 0x1682a0
#define QM_REG_VOQPORT_1 0x1682a4
#define QM_REG_VOQPORT_10 0x1682c8
#define QM_REG_VOQPORT_11 0x1682cc
#define QM_REG_VOQPORT_2 0x1682a8
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_0_LSB 0x168240
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_0_LSB_EXT_A 0x16e524
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_0_MSB 0x168244
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_0_MSB_EXT_A 0x16e528
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
+#define QM_REG_VOQQMASK_10_LSB 0x168290
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_10_LSB_EXT_A 0x16e574
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
+#define QM_REG_VOQQMASK_10_MSB 0x168294
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_10_MSB_EXT_A 0x16e578
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
+#define QM_REG_VOQQMASK_11_LSB 0x168298
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_11_LSB_EXT_A 0x16e57c
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
+#define QM_REG_VOQQMASK_11_MSB 0x16829c
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_11_MSB_EXT_A 0x16e580
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
+#define QM_REG_VOQQMASK_1_LSB 0x168248
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_1_LSB_EXT_A 0x16e52c
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_1_MSB 0x16824c
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_1_MSB_EXT_A 0x16e530
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_2_LSB 0x168250
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_2_LSB_EXT_A 0x16e534
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_2_MSB 0x168254
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_2_MSB_EXT_A 0x16e538
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_3_LSB 0x168258
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_3_LSB_EXT_A 0x16e53c
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_3_MSB_EXT_A 0x16e540
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_4_LSB 0x168260
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_4_LSB_EXT_A 0x16e544
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_4_MSB 0x168264
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_4_MSB_EXT_A 0x16e548
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_5_LSB 0x168268
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_5_LSB_EXT_A 0x16e54c
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_5_MSB 0x16826c
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_5_MSB_EXT_A 0x16e550
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_6_LSB 0x168270
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_6_LSB_EXT_A 0x16e554
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_6_MSB 0x168274
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_6_MSB_EXT_A 0x16e558
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_7_LSB 0x168278
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_7_LSB_EXT_A 0x16e55c
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_7_MSB 0x16827c
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_7_MSB_EXT_A 0x16e560
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_8_LSB 0x168280
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_8_LSB_EXT_A 0x16e564
+/* [RW 32] The physical queue number associated with each VOQ; queues 63-32 */
#define QM_REG_VOQQMASK_8_MSB 0x168284
-/* [RW 32] The physical queue number associated with each VOQ */
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_8_MSB_EXT_A 0x16e568
+/* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
#define QM_REG_VOQQMASK_9_LSB 0x168288
+/* [RW 32] The physical queue number associated with each VOQ; queues 95-64 */
+#define QM_REG_VOQQMASK_9_LSB_EXT_A 0x16e56c
+/* [RW 32] The physical queue number associated with each VOQ; queues 127-96 */
+#define QM_REG_VOQQMASK_9_MSB_EXT_A 0x16e570
/* [RW 32] Wrr weights */
#define QM_REG_WRRWEIGHTS_0 0x16880c
#define QM_REG_WRRWEIGHTS_1 0x168810
@@ -2431,14 +2972,78 @@
#define QM_REG_WRRWEIGHTS_15 0x168828
#define QM_REG_WRRWEIGHTS_15_SIZE 1
/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_16 0x16e000
+#define QM_REG_WRRWEIGHTS_16_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_17 0x16e004
+#define QM_REG_WRRWEIGHTS_17_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_18 0x16e008
+#define QM_REG_WRRWEIGHTS_18_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_19 0x16e00c
+#define QM_REG_WRRWEIGHTS_19_SIZE 1
+/* [RW 32] Wrr weights */
#define QM_REG_WRRWEIGHTS_10 0x168814
#define QM_REG_WRRWEIGHTS_11 0x168818
#define QM_REG_WRRWEIGHTS_12 0x16881c
#define QM_REG_WRRWEIGHTS_13 0x168820
#define QM_REG_WRRWEIGHTS_14 0x168824
#define QM_REG_WRRWEIGHTS_15 0x168828
+#define QM_REG_WRRWEIGHTS_16 0x16e000
+#define QM_REG_WRRWEIGHTS_17 0x16e004
+#define QM_REG_WRRWEIGHTS_18 0x16e008
+#define QM_REG_WRRWEIGHTS_19 0x16e00c
#define QM_REG_WRRWEIGHTS_2 0x16882c
+#define QM_REG_WRRWEIGHTS_20 0x16e010
+#define QM_REG_WRRWEIGHTS_20_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_21 0x16e014
+#define QM_REG_WRRWEIGHTS_21_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_22 0x16e018
+#define QM_REG_WRRWEIGHTS_22_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_23 0x16e01c
+#define QM_REG_WRRWEIGHTS_23_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_24 0x16e020
+#define QM_REG_WRRWEIGHTS_24_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_25 0x16e024
+#define QM_REG_WRRWEIGHTS_25_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_26 0x16e028
+#define QM_REG_WRRWEIGHTS_26_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_27 0x16e02c
+#define QM_REG_WRRWEIGHTS_27_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_28 0x16e030
+#define QM_REG_WRRWEIGHTS_28_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_29 0x16e034
+#define QM_REG_WRRWEIGHTS_29_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_20 0x16e010
+#define QM_REG_WRRWEIGHTS_21 0x16e014
+#define QM_REG_WRRWEIGHTS_22 0x16e018
+#define QM_REG_WRRWEIGHTS_23 0x16e01c
+#define QM_REG_WRRWEIGHTS_24 0x16e020
+#define QM_REG_WRRWEIGHTS_25 0x16e024
+#define QM_REG_WRRWEIGHTS_26 0x16e028
+#define QM_REG_WRRWEIGHTS_27 0x16e02c
+#define QM_REG_WRRWEIGHTS_28 0x16e030
+#define QM_REG_WRRWEIGHTS_29 0x16e034
#define QM_REG_WRRWEIGHTS_3 0x168830
+#define QM_REG_WRRWEIGHTS_30 0x16e038
+#define QM_REG_WRRWEIGHTS_30_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_31 0x16e03c
+#define QM_REG_WRRWEIGHTS_31_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_30 0x16e038
+#define QM_REG_WRRWEIGHTS_31 0x16e03c
#define QM_REG_WRRWEIGHTS_4 0x168834
#define QM_REG_WRRWEIGHTS_5 0x168838
#define QM_REG_WRRWEIGHTS_6 0x16883c
@@ -2447,6 +3052,70 @@
#define QM_REG_WRRWEIGHTS_9 0x168848
/* [R 6] Keep the fill level of the fifo from write client 1 */
#define QM_REG_XQM_WRC_FIFOLVL 0x168000
+#define BRB1_BRB1_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define BRB1_BRB1_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define BRB1_BRB1_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define BRB1_BRB1_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define BRB1_BRB1_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define BRB1_BRB1_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define BRB1_BRB1_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define BRB1_BRB1_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define CCM_CCM_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define CCM_CCM_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define CCM_CCM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define CCM_CCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define CCM_CCM_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define CCM_CCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define CCM_CCM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define CCM_CCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define CDU_CDU_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define CDU_CDU_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define CDU_CDU_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define CDU_CDU_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define CDU_CDU_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define CDU_CDU_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define CDU_CDU_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define CDU_CDU_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define CFC_CFC_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define CFC_CFC_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define CFC_CFC_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define CFC_CFC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define CFC_CFC_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define CFC_CFC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define CFC_CFC_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define CFC_CFC_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define CSDM_CSDM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSDM_CSDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSDM_CSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSDM_CSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSDM_CSDM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSDM_CSDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSDM_CSDM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSDM_CSDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSEM_CSEM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSEM_CSEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSEM_CSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSEM_CSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSEM_CSEM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSEM_CSEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define CSEM_CSEM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define CSEM_CSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define DBG_DBG_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define DBG_DBG_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define DBG_DBG_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define DBG_DBG_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define DBG_DBG_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define DBG_DBG_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define DBG_DBG_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define DBG_DBG_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define DMAE_DMAE_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define DMAE_DMAE_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define DMAE_DMAE_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define DMAE_DMAE_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define DMAE_DMAE_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define DMAE_DMAE_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define DMAE_DMAE_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define DMAE_DMAE_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR_SIZE 0
#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
@@ -2455,6 +3124,22 @@
#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define HC_HC_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define HC_HC_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define HC_HC_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define HC_HC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define HC_HC_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define HC_HC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define HC_HC_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define HC_HC_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define MISC_MISC_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define MISC_MISC_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define MISC_MISC_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define MISC_MISC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define MISC_MISC_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define MISC_MISC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define MISC_MISC_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define MISC_MISC_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
@@ -2463,6 +3148,70 @@
#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define PBF_PBF_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define PBF_PBF_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define PBF_PBF_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define PBF_PBF_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define PBF_PBF_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define PBF_PBF_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define PBF_PBF_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define PBF_PBF_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define PB_PB_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define PB_PB_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define PB_PB_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define PB_PB_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define PB_PB_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define PB_PB_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define PB_PB_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define PB_PB_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define PRS_PRS_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define PRS_PRS_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define PRS_PRS_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define PRS_PRS_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define PRS_PRS_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define PRS_PRS_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define PRS_PRS_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define PRS_PRS_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define PXP2_PXP2_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP2_PXP2_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP2_PXP2_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP2_PXP2_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP2_PXP2_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP2_PXP2_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP2_PXP2_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP2_PXP2_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP_PXP_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP_PXP_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP_PXP_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP_PXP_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP_PXP_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP_PXP_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define PXP_PXP_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define PXP_PXP_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define QM_QM_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define QM_QM_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define QM_QM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define QM_QM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define QM_QM_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define QM_QM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define QM_QM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define QM_QM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define SEM_FAST_SEM_FAST_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define SEM_FAST_SEM_FAST_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define SEM_FAST_SEM_FAST_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define SEM_FAST_SEM_FAST_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define SEM_FAST_SEM_FAST_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define SEM_FAST_SEM_FAST_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define SEM_FAST_SEM_FAST_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define SEM_FAST_SEM_FAST_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define SRC_SRC_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define SRC_SRC_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define SRC_SRC_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define SRC_SRC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define SRC_SRC_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define SRC_SRC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define SRC_SRC_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define SRC_SRC_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR_SIZE 0
#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
@@ -2471,6 +3220,78 @@
#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define TM_TM_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define TM_TM_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define TM_TM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define TM_TM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define TM_TM_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define TM_TM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define TM_TM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define TM_TM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define TSDM_TSDM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSDM_TSDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSDM_TSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSDM_TSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSDM_TSDM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSDM_TSDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSDM_TSDM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSDM_TSDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSEM_TSEM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSEM_TSEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSEM_TSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSEM_TSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSEM_TSEM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSEM_TSEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define TSEM_TSEM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define TSEM_TSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define UCM_UCM_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define UCM_UCM_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define UCM_UCM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define UCM_UCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define UCM_UCM_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define UCM_UCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define UCM_UCM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define UCM_UCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define USDM_USDM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USDM_USDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define USDM_USDM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USDM_USDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define USDM_USDM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USDM_USDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define USDM_USDM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USDM_USDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define USEM_USEM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USEM_USEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define USEM_USEM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USEM_USEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define USEM_USEM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USEM_USEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define USEM_USEM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define USEM_USEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define XCM_XCM_INT_STS_REG_ADDRESS_ERROR (0x1<<0)
+#define XCM_XCM_INT_STS_REG_ADDRESS_ERROR_SIZE 0
+#define XCM_XCM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0)
+#define XCM_XCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0
+#define XCM_XCM_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0)
+#define XCM_XCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0
+#define XCM_XCM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0)
+#define XCM_XCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0
+#define XSDM_XSDM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSDM_XSDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSDM_XSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSDM_XSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSDM_XSDM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSDM_XSDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSDM_XSDM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSDM_XSDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSEM_XSEM_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSEM_XSEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSEM_XSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSEM_XSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSEM_XSEM_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSEM_XSEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0
+#define XSEM_XSEM_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0)
+#define XSEM_XSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0
#define CFC_DEBUG1_REG_WRITE_AC (0x1<<4)
#define CFC_DEBUG1_REG_WRITE_AC_SIZE 4
/* [R 1] debug only: This bit indicates wheter indicates that external
@@ -2483,6 +3304,14 @@
~dbg_registers_debug_target=0 (internal buffer) */
#define DBG_REG_WRAP_ON_INT_BUFFER 0xc128
#define DBG_REG_WRAP_ON_INT_BUFFER_SIZE 1
+#define QM_QM_PRTY_STS_REG_WRBUFF (0x1<<8)
+#define QM_QM_PRTY_STS_REG_WRBUFF_SIZE 8
+#define QM_QM_PRTY_STS_CLR_REG_WRBUFF (0x1<<8)
+#define QM_QM_PRTY_STS_CLR_REG_WRBUFF_SIZE 8
+#define QM_QM_PRTY_STS_WR_REG_WRBUFF (0x1<<8)
+#define QM_QM_PRTY_STS_WR_REG_WRBUFF_SIZE 8
+#define QM_QM_PRTY_MASK_REG_WRBUFF (0x1<<8)
+#define QM_QM_PRTY_MASK_REG_WRBUFF_SIZE 8
/* [RW 32] Wrr weights */
#define QM_REG_WRRWEIGHTS_0 0x16880c
#define QM_REG_WRRWEIGHTS_0_SIZE 1
@@ -2531,20 +3360,67 @@
/* [RW 32] Wrr weights */
#define QM_REG_WRRWEIGHTS_9 0x168848
#define QM_REG_WRRWEIGHTS_9_SIZE 1
-/* [RW 22] Number of free element in the free list of T2 entries - port 0. */
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_16 0x16e000
+#define QM_REG_WRRWEIGHTS_16_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_17 0x16e004
+#define QM_REG_WRRWEIGHTS_17_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_18 0x16e008
+#define QM_REG_WRRWEIGHTS_18_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_19 0x16e00c
+#define QM_REG_WRRWEIGHTS_19_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_20 0x16e010
+#define QM_REG_WRRWEIGHTS_20_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_21 0x16e014
+#define QM_REG_WRRWEIGHTS_21_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_22 0x16e018
+#define QM_REG_WRRWEIGHTS_22_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_23 0x16e01c
+#define QM_REG_WRRWEIGHTS_23_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_24 0x16e020
+#define QM_REG_WRRWEIGHTS_24_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_25 0x16e024
+#define QM_REG_WRRWEIGHTS_25_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_26 0x16e028
+#define QM_REG_WRRWEIGHTS_26_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_27 0x16e02c
+#define QM_REG_WRRWEIGHTS_27_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_28 0x16e030
+#define QM_REG_WRRWEIGHTS_28_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_29 0x16e034
+#define QM_REG_WRRWEIGHTS_29_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_30 0x16e038
+#define QM_REG_WRRWEIGHTS_30_SIZE 1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_31 0x16e03c
+#define QM_REG_WRRWEIGHTS_31_SIZE 1
#define SRC_REG_COUNTFREE0 0x40500
-/* [WB 64] First free element in the free list of T2 entries - port 0. */
+/* [RW 1] If clr the searcher is compatible to E1 A0 - support only two
+ ports. If set the searcher support 8 functions. */
+#define SRC_REG_E1HMF_ENABLE 0x404cc
#define SRC_REG_FIRSTFREE0 0x40510
#define SRC_REG_KEYRSS0_0 0x40408
+#define SRC_REG_KEYRSS0_7 0x40424
#define SRC_REG_KEYRSS1_9 0x40454
-/* [WB 64] Last free element in the free list of T2 entries - port 0. */
#define SRC_REG_LASTFREE0 0x40530
-/* [RW 5] The number of hash bits used for the search (h); Values can be 8
- to 24. */
#define SRC_REG_NUMBER_HASH_BITS0 0x40400
/* [RW 1] Reset internal state machines. */
#define SRC_REG_SOFT_RST 0x4049c
-/* [R 1] Interrupt register #0 read */
+/* [R 3] Interrupt register #0 read */
#define SRC_REG_SRC_INT_STS 0x404ac
/* [RW 3] Parity mask register #0 read/write */
#define SRC_REG_SRC_PRTY_MASK 0x404c8
@@ -2637,11 +3513,14 @@
weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define TCM_REG_PBF_WEIGHT 0x500b4
-/* [RW 6] The physical queue number 0 per port index. */
#define TCM_REG_PHYS_QNUM0_0 0x500e0
#define TCM_REG_PHYS_QNUM0_1 0x500e4
-/* [RW 6] The physical queue number 1 per port index. */
#define TCM_REG_PHYS_QNUM1_0 0x500e8
+#define TCM_REG_PHYS_QNUM1_1 0x500ec
+#define TCM_REG_PHYS_QNUM2_0 0x500f0
+#define TCM_REG_PHYS_QNUM2_1 0x500f4
+#define TCM_REG_PHYS_QNUM3_0 0x500f8
+#define TCM_REG_PHYS_QNUM3_1 0x500fc
/* [RW 1] Input prs Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -2670,6 +3549,8 @@
#define TCM_REG_TCM_INT_MASK 0x501dc
/* [R 11] Interrupt register #0 read */
#define TCM_REG_TCM_INT_STS 0x501d0
+/* [R 27] Parity register #0 read */
+#define TCM_REG_TCM_PRTY_STS 0x501e0
/* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS
REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
Is used to determine the number of the AG context REG-pairs written back;
@@ -2729,6 +3610,7 @@
mechanism. The fields are: [5:0] - length of the message; 15:6] - message
pointer; 20:16] - next pointer. */
#define TCM_REG_XX_DESCR_TABLE 0x50280
+#define TCM_REG_XX_DESCR_TABLE_SIZE 32
/* [R 6] Use to read the value of XX protection Free counter. */
#define TCM_REG_XX_FREE 0x50178
/* [RW 6] Initial value for the credit counter; responsible for fulfilling
@@ -2780,7 +3662,7 @@
/* [RW 4] Load value for expiration credit cnt. CFC max number of
outstanding load requests for timers (expiration) context loading. */
#define TM_REG_EXP_CRDCNT_VAL 0x164238
-/* [RW 18] Linear0 Max active cid. */
+/* [RW 18] Linear0 Max active cid (in banks of 32 entries). */
#define TM_REG_LIN0_MAX_ACTIVE_CID 0x164048
/* [WB 64] Linear0 phy address. */
#define TM_REG_LIN0_PHY_ADDR 0x164270
@@ -2804,6 +3686,21 @@
#define TM_REG_TM_INT_STS 0x1640f0
/* [RW 8] The event id for aggregated interrupt 0 */
#define TSDM_REG_AGG_INT_EVENT_0 0x42038
+#define TSDM_REG_AGG_INT_EVENT_2 0x42040
+#define TSDM_REG_AGG_INT_EVENT_20 0x42088
+#define TSDM_REG_AGG_INT_EVENT_21 0x4208c
+#define TSDM_REG_AGG_INT_EVENT_22 0x42090
+#define TSDM_REG_AGG_INT_EVENT_23 0x42094
+#define TSDM_REG_AGG_INT_EVENT_24 0x42098
+#define TSDM_REG_AGG_INT_EVENT_25 0x4209c
+#define TSDM_REG_AGG_INT_EVENT_26 0x420a0
+#define TSDM_REG_AGG_INT_EVENT_27 0x420a4
+#define TSDM_REG_AGG_INT_EVENT_28 0x420a8
+#define TSDM_REG_AGG_INT_EVENT_29 0x420ac
+#define TSDM_REG_AGG_INT_EVENT_3 0x42044
+#define TSDM_REG_AGG_INT_EVENT_30 0x420b0
+#define TSDM_REG_AGG_INT_EVENT_31 0x420b4
+#define TSDM_REG_AGG_INT_EVENT_4 0x42048
/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
#define TSDM_REG_CFC_RSP_START_ADDR 0x42008
/* [RW 16] The maximum value of the competion counter #0 */
@@ -2868,6 +3765,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define TSDM_REG_TSDM_INT_MASK_0 0x4229c
#define TSDM_REG_TSDM_INT_MASK_1 0x422ac
+/* [R 32] Interrupt register #0 read */
+#define TSDM_REG_TSDM_INT_STS_0 0x42290
+#define TSDM_REG_TSDM_INT_STS_1 0x422a0
/* [RW 11] Parity mask register #0 read/write */
#define TSDM_REG_TSDM_PRTY_MASK 0x422bc
/* [R 11] Parity register #0 read */
@@ -2908,9 +3808,8 @@
#define TSEM_REG_ENABLE_OUT 0x1800a8
/* [RW 32] This address space contains all registers and memories that are
placed in SEM_FAST block. The SEM_FAST registers are described in
- appendix B. In order to access the SEM_FAST registers the base address
- TSEM_REGISTERS_FAST_MEMORY (Offset: 0x1a0000) should be added to each
- SEM_FAST register offset. */
+ appendix B. In order to access the sem_fast registers the base address
+ ~fast_memory.fast_memory should be added to eachsem_fast register offset. */
#define TSEM_REG_FAST_MEMORY 0x1a0000
/* [RW 1] Disables input messages from FIC0 May be updated during run_time
by the microcode */
@@ -2993,6 +3892,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define TSEM_REG_TSEM_INT_MASK_0 0x180100
#define TSEM_REG_TSEM_INT_MASK_1 0x180110
+/* [R 32] Interrupt register #0 read */
+#define TSEM_REG_TSEM_INT_STS_0 0x1800f4
+#define TSEM_REG_TSEM_INT_STS_1 0x180104
/* [RW 32] Parity mask register #0 read/write */
#define TSEM_REG_TSEM_PRTY_MASK_0 0x180120
#define TSEM_REG_TSEM_PRTY_MASK_1 0x180130
@@ -3088,12 +3990,15 @@
#define UCM_REG_N_SM_CTX_LD_2 0xe005c
#define UCM_REG_N_SM_CTX_LD_3 0xe0060
#define UCM_REG_N_SM_CTX_LD_4 0xe0064
-/* [RW 6] The physical queue number 0 per port index (CID[23]) */
+#define UCM_REG_N_SM_CTX_LD_5 0xe0068
#define UCM_REG_PHYS_QNUM0_0 0xe0110
#define UCM_REG_PHYS_QNUM0_1 0xe0114
-/* [RW 6] The physical queue number 1 per port index (CID[23]) */
#define UCM_REG_PHYS_QNUM1_0 0xe0118
#define UCM_REG_PHYS_QNUM1_1 0xe011c
+#define UCM_REG_PHYS_QNUM2_0 0xe0120
+#define UCM_REG_PHYS_QNUM2_1 0xe0124
+#define UCM_REG_PHYS_QNUM3_0 0xe0128
+#define UCM_REG_PHYS_QNUM3_1 0xe012c
/* [RW 8] The Event ID for Timers formatting in case of stop done. */
#define UCM_REG_STOP_EVNT_ID 0xe00ac
/* [RC 1] Set when the message length mismatch (relative to last indication)
@@ -3132,6 +4037,8 @@
#define UCM_REG_UCM_INT_MASK 0xe01d4
/* [R 11] Interrupt register #0 read */
#define UCM_REG_UCM_INT_STS 0xe01c8
+/* [R 27] Parity register #0 read */
+#define UCM_REG_UCM_PRTY_STS 0xe01d8
/* [RW 2] The size of AG context region 0 in REG-pairs. Designates the MS
REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
Is used to determine the number of the AG context REG-pairs written back;
@@ -3189,6 +4096,7 @@
mechanism. The fields are:[5:0] - message length; 14:6] - message
pointer; 19:15] - next pointer. */
#define UCM_REG_XX_DESCR_TABLE 0xe0280
+#define UCM_REG_XX_DESCR_TABLE_SIZE 32
/* [R 6] Use to read the XX protection Free counter. */
#define UCM_REG_XX_FREE 0xe016c
/* [RW 6] Initial value for the credit counter; responsible for fulfilling
@@ -3218,6 +4126,21 @@
#define USDM_REG_AGG_INT_EVENT_17 0xc407c
#define USDM_REG_AGG_INT_EVENT_18 0xc4080
#define USDM_REG_AGG_INT_EVENT_19 0xc4084
+#define USDM_REG_AGG_INT_EVENT_2 0xc4040
+#define USDM_REG_AGG_INT_EVENT_20 0xc4088
+#define USDM_REG_AGG_INT_EVENT_21 0xc408c
+#define USDM_REG_AGG_INT_EVENT_22 0xc4090
+#define USDM_REG_AGG_INT_EVENT_23 0xc4094
+#define USDM_REG_AGG_INT_EVENT_24 0xc4098
+#define USDM_REG_AGG_INT_EVENT_25 0xc409c
+#define USDM_REG_AGG_INT_EVENT_26 0xc40a0
+#define USDM_REG_AGG_INT_EVENT_27 0xc40a4
+#define USDM_REG_AGG_INT_EVENT_28 0xc40a8
+#define USDM_REG_AGG_INT_EVENT_29 0xc40ac
+#define USDM_REG_AGG_INT_EVENT_3 0xc4044
+#define USDM_REG_AGG_INT_EVENT_30 0xc40b0
+#define USDM_REG_AGG_INT_EVENT_31 0xc40b4
+#define USDM_REG_AGG_INT_EVENT_4 0xc4048
/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
or auto-mask-mode (1) */
#define USDM_REG_AGG_INT_MODE_0 0xc41b8
@@ -3298,6 +4221,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define USDM_REG_USDM_INT_MASK_0 0xc42a0
#define USDM_REG_USDM_INT_MASK_1 0xc42b0
+/* [R 32] Interrupt register #0 read */
+#define USDM_REG_USDM_INT_STS_0 0xc4294
+#define USDM_REG_USDM_INT_STS_1 0xc42a4
/* [RW 11] Parity mask register #0 read/write */
#define USDM_REG_USDM_PRTY_MASK 0xc42c0
/* [R 11] Parity register #0 read */
@@ -3338,9 +4264,8 @@
#define USEM_REG_ENABLE_OUT 0x3000a8
/* [RW 32] This address space contains all registers and memories that are
placed in SEM_FAST block. The SEM_FAST registers are described in
- appendix B. In order to access the SEM_FAST registers... the base address
- USEM_REGISTERS_FAST_MEMORY (Offset: 0x320000) should be added to each
- SEM_FAST register offset. */
+ appendix B. In order to access the sem_fast registers the base address
+ ~fast_memory.fast_memory should be added to eachsem_fast register offset. */
#define USEM_REG_FAST_MEMORY 0x320000
/* [RW 1] Disables input messages from FIC0 May be updated during run_time
by the microcode */
@@ -3423,6 +4348,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define USEM_REG_USEM_INT_MASK_0 0x300110
#define USEM_REG_USEM_INT_MASK_1 0x300120
+/* [R 32] Interrupt register #0 read */
+#define USEM_REG_USEM_INT_STS_0 0x300104
+#define USEM_REG_USEM_INT_STS_1 0x300114
/* [RW 32] Parity mask register #0 read/write */
#define USEM_REG_USEM_PRTY_MASK_0 0x300130
#define USEM_REG_USEM_PRTY_MASK_1 0x300140
@@ -3491,11 +4419,8 @@
writes the initial credit value; read returns the current value of the
credit counter. Must be initialized to 64 at start-up. */
#define XCM_REG_FIC1_INIT_CRD 0x20410
-/* [RW 8] The maximum delayed ACK counter value.Must be at least 2. Per port
- value. */
#define XCM_REG_GLB_DEL_ACK_MAX_CNT_0 0x20118
#define XCM_REG_GLB_DEL_ACK_MAX_CNT_1 0x2011c
-/* [RW 28] The delayed ACK timeout in ticks. Per port value. */
#define XCM_REG_GLB_DEL_ACK_TMR_VAL_0 0x20108
#define XCM_REG_GLB_DEL_ACK_TMR_VAL_1 0x2010c
/* [RW 1] Arbitratiojn between Input Arbiter groups: 0 - fair Round-Robin; 1
@@ -3545,6 +4470,7 @@
#define XCM_REG_N_SM_CTX_LD_2 0x20068
#define XCM_REG_N_SM_CTX_LD_3 0x2006c
#define XCM_REG_N_SM_CTX_LD_4 0x20070
+#define XCM_REG_N_SM_CTX_LD_5 0x20074
/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -3556,6 +4482,8 @@
weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define XCM_REG_PBF_WEIGHT 0x200d0
+#define XCM_REG_PHYS_QNUM3_0 0x20100
+#define XCM_REG_PHYS_QNUM3_1 0x20104
/* [RW 8] The Event ID for Timers formatting in case of stop done. */
#define XCM_REG_STOP_EVNT_ID 0x200b8
/* [RC 1] Set at message length mismatch (relative to last indication) at
@@ -3603,53 +4531,17 @@
weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define XCM_REG_USEM_WEIGHT 0x200c8
-/* [RW 2] DA counter command; used in case of window update doorbell.The
- first index stands for the value DaEnable of that connection. The second
- index stands for port number. */
#define XCM_REG_WU_DA_CNT_CMD00 0x201d4
-/* [RW 2] DA counter command; used in case of window update doorbell.The
- first index stands for the value DaEnable of that connection. The second
- index stands for port number. */
#define XCM_REG_WU_DA_CNT_CMD01 0x201d8
-/* [RW 2] DA counter command; used in case of window update doorbell.The
- first index stands for the value DaEnable of that connection. The second
- index stands for port number. */
#define XCM_REG_WU_DA_CNT_CMD10 0x201dc
-/* [RW 2] DA counter command; used in case of window update doorbell.The
- first index stands for the value DaEnable of that connection. The second
- index stands for port number. */
#define XCM_REG_WU_DA_CNT_CMD11 0x201e0
-/* [RW 8] DA counter update value used in case of window update doorbell.The
- first index stands for the value DaEnable of that connection. The second
- index stands for port number. */
#define XCM_REG_WU_DA_CNT_UPD_VAL00 0x201e4
-/* [RW 8] DA counter update value; used in case of window update
- doorbell.The first index stands for the value DaEnable of that
- connection. The second index stands for port number. */
#define XCM_REG_WU_DA_CNT_UPD_VAL01 0x201e8
-/* [RW 8] DA counter update value; used in case of window update
- doorbell.The first index stands for the value DaEnable of that
- connection. The second index stands for port number. */
#define XCM_REG_WU_DA_CNT_UPD_VAL10 0x201ec
-/* [RW 8] DA counter update value; used in case of window update
- doorbell.The first index stands for the value DaEnable of that
- connection. The second index stands for port number. */
#define XCM_REG_WU_DA_CNT_UPD_VAL11 0x201f0
-/* [RW 1] DA timer command; used in case of window update doorbell.The first
- index stands for the value DaEnable of that connection. The second index
- stands for port number. */
#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00 0x201c4
-/* [RW 1] DA timer command; used in case of window update doorbell.The first
- index stands for the value DaEnable of that connection. The second index
- stands for port number. */
#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01 0x201c8
-/* [RW 1] DA timer command; used in case of window update doorbell.The first
- index stands for the value DaEnable of that connection. The second index
- stands for port number. */
#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10 0x201cc
-/* [RW 1] DA timer command; used in case of window update doorbell.The first
- index stands for the value DaEnable of that connection. The second index
- stands for port number. */
#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11 0x201d0
/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
@@ -3659,6 +4551,8 @@
#define XCM_REG_XCM_INT_MASK 0x202b4
/* [R 14] Interrupt register #0 read */
#define XCM_REG_XCM_INT_STS 0x202a8
+/* [R 30] Parity register #0 read */
+#define XCM_REG_XCM_PRTY_STS 0x202b8
/* [RW 4] The size of AG context region 0 in REG-pairs. Designates the MS
REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
Is used to determine the number of the AG context REG-pairs written back;
@@ -3715,6 +4609,7 @@
mechanism. The fields are: [5:0] - message length; 11:6] - message
pointer; 16:12] - next pointer. */
#define XCM_REG_XX_DESCR_TABLE 0x20480
+#define XCM_REG_XX_DESCR_TABLE_SIZE 32
/* [R 6] Used to read the XX protection Free counter. */
#define XCM_REG_XX_FREE 0x20240
/* [RW 6] Initial value for the credit counter; responsible for fulfilling
@@ -3728,7 +4623,7 @@
#define XCM_REG_XX_MSG_NUM 0x20428
/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */
#define XCM_REG_XX_OVFL_EVNT_ID 0x20058
-/* [RW 15] Indirect access to the XX table of the XX protection mechanism.
+/* [RW 16] Indirect access to the XX table of the XX protection mechanism.
The fields are:[4:0] - tail pointer; 9:5] - Link List size; 14:10] -
header pointer. */
#define XCM_REG_XX_TABLE 0x20500
@@ -3745,6 +4640,9 @@
#define XSDM_REG_AGG_INT_EVENT_17 0x16607c
#define XSDM_REG_AGG_INT_EVENT_18 0x166080
#define XSDM_REG_AGG_INT_EVENT_19 0x166084
+#define XSDM_REG_AGG_INT_EVENT_10 0x166060
+#define XSDM_REG_AGG_INT_EVENT_11 0x166064
+#define XSDM_REG_AGG_INT_EVENT_12 0x166068
#define XSDM_REG_AGG_INT_EVENT_2 0x166040
#define XSDM_REG_AGG_INT_EVENT_20 0x166088
#define XSDM_REG_AGG_INT_EVENT_21 0x16608c
@@ -3756,6 +4654,15 @@
#define XSDM_REG_AGG_INT_EVENT_27 0x1660a4
#define XSDM_REG_AGG_INT_EVENT_28 0x1660a8
#define XSDM_REG_AGG_INT_EVENT_29 0x1660ac
+#define XSDM_REG_AGG_INT_EVENT_3 0x166044
+#define XSDM_REG_AGG_INT_EVENT_30 0x1660b0
+#define XSDM_REG_AGG_INT_EVENT_31 0x1660b4
+#define XSDM_REG_AGG_INT_EVENT_4 0x166048
+#define XSDM_REG_AGG_INT_EVENT_5 0x16604c
+#define XSDM_REG_AGG_INT_EVENT_6 0x166050
+#define XSDM_REG_AGG_INT_EVENT_7 0x166054
+#define XSDM_REG_AGG_INT_EVENT_8 0x166058
+#define XSDM_REG_AGG_INT_EVENT_9 0x16605c
/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
or auto-mask-mode (1) */
#define XSDM_REG_AGG_INT_MODE_0 0x1661b8
@@ -3832,6 +4739,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define XSDM_REG_XSDM_INT_MASK_0 0x16629c
#define XSDM_REG_XSDM_INT_MASK_1 0x1662ac
+/* [R 32] Interrupt register #0 read */
+#define XSDM_REG_XSDM_INT_STS_0 0x166290
+#define XSDM_REG_XSDM_INT_STS_1 0x1662a0
/* [RW 11] Parity mask register #0 read/write */
#define XSDM_REG_XSDM_PRTY_MASK 0x1662bc
/* [R 11] Parity register #0 read */
@@ -3872,9 +4782,8 @@
#define XSEM_REG_ENABLE_OUT 0x2800a8
/* [RW 32] This address space contains all registers and memories that are
placed in SEM_FAST block. The SEM_FAST registers are described in
- appendix B. In order to access the SEM_FAST registers the base address
- XSEM_REGISTERS_FAST_MEMORY (Offset: 0x2a0000) should be added to each
- SEM_FAST register offset. */
+ appendix B. In order to access the sem_fast registers the base address
+ ~fast_memory.fast_memory should be added to eachsem_fast register offset. */
#define XSEM_REG_FAST_MEMORY 0x2a0000
/* [RW 1] Disables input messages from FIC0 May be updated during run_time
by the microcode */
@@ -3957,6 +4866,9 @@
/* [RW 32] Interrupt mask register #0 read/write */
#define XSEM_REG_XSEM_INT_MASK_0 0x280110
#define XSEM_REG_XSEM_INT_MASK_1 0x280120
+/* [R 32] Interrupt register #0 read */
+#define XSEM_REG_XSEM_INT_STS_0 0x280104
+#define XSEM_REG_XSEM_INT_STS_1 0x280114
/* [RW 32] Parity mask register #0 read/write */
#define XSEM_REG_XSEM_PRTY_MASK_0 0x280130
#define XSEM_REG_XSEM_PRTY_MASK_1 0x280140
@@ -3993,10 +4905,14 @@
#define BIGMAC_REGISTER_TX_SOURCE_ADDR (0x08<<3)
#define BIGMAC_REGISTER_TX_STAT_GTBYT (0x20<<3)
#define BIGMAC_REGISTER_TX_STAT_GTPKT (0x0C<<3)
+#define EMAC_LED_1000MB_OVERRIDE (1L<<1)
+#define EMAC_LED_100MB_OVERRIDE (1L<<2)
+#define EMAC_LED_10MB_OVERRIDE (1L<<3)
+#define EMAC_LED_2500MB_OVERRIDE (1L<<12)
+#define EMAC_LED_OVERRIDE (1L<<0)
+#define EMAC_LED_TRAFFIC (1L<<6)
#define EMAC_MDIO_COMM_COMMAND_ADDRESS (0L<<26)
-#define EMAC_MDIO_COMM_COMMAND_READ_22 (2L<<26)
#define EMAC_MDIO_COMM_COMMAND_READ_45 (3L<<26)
-#define EMAC_MDIO_COMM_COMMAND_WRITE_22 (1L<<26)
#define EMAC_MDIO_COMM_COMMAND_WRITE_45 (1L<<26)
#define EMAC_MDIO_COMM_DATA (0xffffL<<0)
#define EMAC_MDIO_COMM_START_BUSY (1L<<29)
@@ -4005,14 +4921,12 @@
#define EMAC_MDIO_MODE_CLOCK_CNT (0x3fL<<16)
#define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT 16
#define EMAC_MODE_25G_MODE (1L<<5)
-#define EMAC_MODE_ACPI_RCVD (1L<<20)
#define EMAC_MODE_HALF_DUPLEX (1L<<1)
-#define EMAC_MODE_MPKT (1L<<18)
-#define EMAC_MODE_MPKT_RCVD (1L<<19)
#define EMAC_MODE_PORT_GMII (2L<<2)
#define EMAC_MODE_PORT_MII (1L<<2)
#define EMAC_MODE_PORT_MII_10M (3L<<2)
#define EMAC_MODE_RESET (1L<<0)
+#define EMAC_REG_EMAC_LED 0xc
#define EMAC_REG_EMAC_MAC_MATCH 0x10
#define EMAC_REG_EMAC_MDIO_COMM 0xac
#define EMAC_REG_EMAC_MDIO_MODE 0xb4
@@ -4030,14 +4944,16 @@
#define EMAC_RX_MODE_PROMISCUOUS (1L<<8)
#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31)
#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
-#define EMAC_TX_MODE_RESET (1L<<0)
+#define MISC_REGISTERS_GPIO_0 0
#define MISC_REGISTERS_GPIO_1 1
#define MISC_REGISTERS_GPIO_2 2
#define MISC_REGISTERS_GPIO_3 3
#define MISC_REGISTERS_GPIO_CLR_POS 16
#define MISC_REGISTERS_GPIO_FLOAT (0xffL<<24)
#define MISC_REGISTERS_GPIO_FLOAT_POS 24
+#define MISC_REGISTERS_GPIO_HIGH 1
#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_GPIO_LOW 0
#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1
#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0
#define MISC_REGISTERS_GPIO_PORT_SHIFT 4
@@ -4127,7 +5043,7 @@
#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR (1<<10)
#define RESERVED_GENERAL_ATTENTION_BIT_0 0
-#define EVEREST_GEN_ATTN_IN_USE_MASK 0x3e0
+#define EVEREST_GEN_ATTN_IN_USE_MASK 0x3ffe0
#define EVEREST_LATCHED_ATTN_IN_USE_MASK 0xffe00000
#define RESERVED_GENERAL_ATTENTION_BIT_6 6
@@ -4156,6 +5072,17 @@
/* mcp error attention bit */
#define MCP_FATAL_ASSERT_ATTENTION_BIT RESERVED_GENERAL_ATTENTION_BIT_11
+/*E1H NIG status sync attention mapped to group 4-7*/
+#define LINK_SYNC_ATTENTION_BIT_FUNC_0 RESERVED_GENERAL_ATTENTION_BIT_12
+#define LINK_SYNC_ATTENTION_BIT_FUNC_1 RESERVED_GENERAL_ATTENTION_BIT_13
+#define LINK_SYNC_ATTENTION_BIT_FUNC_2 RESERVED_GENERAL_ATTENTION_BIT_14
+#define LINK_SYNC_ATTENTION_BIT_FUNC_3 RESERVED_GENERAL_ATTENTION_BIT_15
+#define LINK_SYNC_ATTENTION_BIT_FUNC_4 RESERVED_GENERAL_ATTENTION_BIT_16
+#define LINK_SYNC_ATTENTION_BIT_FUNC_5 RESERVED_GENERAL_ATTENTION_BIT_17
+#define LINK_SYNC_ATTENTION_BIT_FUNC_6 RESERVED_GENERAL_ATTENTION_BIT_18
+#define LINK_SYNC_ATTENTION_BIT_FUNC_7 RESERVED_GENERAL_ATTENTION_BIT_19
+
+
#define LATCHED_ATTN_RBCR 23
#define LATCHED_ATTN_RBCT 24
#define LATCHED_ATTN_RBCN 25
@@ -4221,22 +5148,41 @@
#define PCICFG_OFFSET 0x2000
#define PCICFG_VENDOR_ID_OFFSET 0x00
#define PCICFG_DEVICE_ID_OFFSET 0x02
-#define PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET 0x2c
-#define PCICFG_SUBSYSTEM_ID_OFFSET 0x2e
-#define PCICFG_INT_LINE 0x3c
-#define PCICFG_INT_PIN 0x3d
+#define PCICFG_COMMAND_OFFSET 0x04
+#define PCICFG_STATUS_OFFSET 0x06
+#define PCICFG_REVESION_ID 0x08
#define PCICFG_CACHE_LINE_SIZE 0x0c
#define PCICFG_LATENCY_TIMER 0x0d
-#define PCICFG_REVESION_ID 0x08
-#define PCICFG_BAR_1_LOW 0x10
-#define PCICFG_BAR_1_HIGH 0x14
-#define PCICFG_BAR_2_LOW 0x18
-#define PCICFG_BAR_2_HIGH 0x1c
-#define PCICFG_GRC_ADDRESS 0x78
-#define PCICFG_GRC_DATA 0x80
+#define PCICFG_BAR_1_LOW 0x10
+#define PCICFG_BAR_1_HIGH 0x14
+#define PCICFG_BAR_2_LOW 0x18
+#define PCICFG_BAR_2_HIGH 0x1c
+#define PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET 0x2c
+#define PCICFG_SUBSYSTEM_ID_OFFSET 0x2e
+#define PCICFG_INT_LINE 0x3c
+#define PCICFG_INT_PIN 0x3d
+#define PCICFG_PM_CSR_OFFSET 0x4c
+#define PCICFG_GRC_ADDRESS 0x78
+#define PCICFG_GRC_DATA 0x80
#define PCICFG_DEVICE_CONTROL 0xb4
#define PCICFG_LINK_CONTROL 0xbc
+#define PCICFG_COMMAND_IO_SPACE (1<<0)
+#define PCICFG_COMMAND_MEM_SPACE (1<<1)
+#define PCICFG_COMMAND_BUS_MASTER (1<<2)
+#define PCICFG_COMMAND_SPECIAL_CYCLES (1<<3)
+#define PCICFG_COMMAND_MWI_CYCLES (1<<4)
+#define PCICFG_COMMAND_VGA_SNOOP (1<<5)
+#define PCICFG_COMMAND_PERR_ENA (1<<6)
+#define PCICFG_COMMAND_STEPPING (1<<7)
+#define PCICFG_COMMAND_SERR_ENA (1<<8)
+#define PCICFG_COMMAND_FAST_B2B (1<<9)
+#define PCICFG_COMMAND_INT_DISABLE (1<<10)
+#define PCICFG_COMMAND_RESERVED (0x1f<<11)
+
+#define PCICFG_PM_CSR_STATE (0x3<<0)
+#define PCICFG_PM_CSR_PME_STATUS (1<<15)
+
#define BAR_USTRORM_INTMEM 0x400000
#define BAR_CSTRORM_INTMEM 0x410000
#define BAR_XSTRORM_INTMEM 0x420000
@@ -4336,7 +5282,7 @@
#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST 0x8000
#define MDIO_REG_BANK_CL73_IEEEB1 0x10
-#define MDIO_CL73_IEEEB1_AN_ADV2 0x01
+#define MDIO_CL73_IEEEB1_AN_ADV2 0x01
#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M 0x0000
#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX 0x0020
#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 0x0040
@@ -4365,7 +5311,7 @@
#define MDIO_REG_BANK_RX_ALL 0x80f0
#define MDIO_RX_ALL_RX_EQ_BOOST 0x1c
#define MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK 0x7
-#define MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL 0x10
+#define MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL 0x10
#define MDIO_REG_BANK_TX0 0x8060
#define MDIO_TX0_TX_DRIVER 0x17
@@ -4392,213 +5338,266 @@
#define MDIO_XGXS_BLOCK2_RX_LN_SWAP 0x10
#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE 0x8000
#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE 0x4000
-#define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11
+#define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11
#define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE 0x8000
-#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G 0x14
+#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G 0x14
#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS 0x0001
#define MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS 0x0010
-#define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15
+#define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15
#define MDIO_REG_BANK_GP_STATUS 0x8120
-#define MDIO_GP_STATUS_TOP_AN_STATUS1 0x1B
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE 0x0001
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE 0x0002
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS 0x0004
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS 0x0008
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE 0x0010
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE 0x0020
-
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE 0x0040
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE 0x0080
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK 0x3f00
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M 0x0000
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M 0x0100
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G 0x0200
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G 0x0300
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G 0x0400
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G 0x0500
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG 0x0600
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4 0x0700
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG 0x0800
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G 0x0900
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G 0x0A00
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G 0x0B00
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G 0x0C00
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 0x0D00
-#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 0x0E00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1 0x1B
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE 0x0001
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE 0x0002
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS 0x0004
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS 0x0008
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE 0x0010
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE 0x0020
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE 0x0040
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE 0x0080
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK 0x3f00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M 0x0000
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M 0x0100
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G 0x0200
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G 0x0300
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G 0x0400
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G 0x0500
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG 0x0600
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4 0x0700
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG 0x0800
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G 0x0900
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G 0x0A00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G 0x0B00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G 0x0C00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 0x0D00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 0x0E00
#define MDIO_REG_BANK_10G_PARALLEL_DETECT 0x8130
-#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL 0x11
-#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN 0x1
-#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK 0x13
-#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT (0xb71<<1)
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL 0x11
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN 0x1
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK 0x13
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT (0xb71<<1)
#define MDIO_REG_BANK_SERDES_DIGITAL 0x8300
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1 0x10
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE 0x0001
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF 0x0002
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN 0x0004
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT 0x0008
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET 0x0010
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE 0x0020
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2 0x11
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001
-#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G 0x0018
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G 0x0010
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M 0x0008
-#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M 0x0000
-#define MDIO_SERDES_DIGITAL_MISC1 0x18
-#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK 0xE000
-#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M 0x0000
-#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M 0x2000
-#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M 0x4000
-#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M 0x6000
-#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M 0x8000
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL 0x0010
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK 0x000f
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G 0x0000
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G 0x0001
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G 0x0002
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG 0x0003
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4 0x0004
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G 0x0005
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G 0x0006
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G 0x0007
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G 0x0008
-#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G 0x0009
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1 0x10
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE 0x0001
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF 0x0002
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN 0x0004
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT 0x0008
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET 0x0010
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE 0x0020
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2 0x11
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G 0x0018
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G 0x0010
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M 0x0008
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M 0x0000
+#define MDIO_SERDES_DIGITAL_MISC1 0x18
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK 0xE000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M 0x0000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M 0x2000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M 0x4000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M 0x6000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M 0x8000
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL 0x0010
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK 0x000f
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G 0x0000
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G 0x0001
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G 0x0002
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG 0x0003
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4 0x0004
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G 0x0005
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G 0x0006
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G 0x0007
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G 0x0008
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G 0x0009
#define MDIO_REG_BANK_OVER_1G 0x8320
-#define MDIO_OVER_1G_DIGCTL_3_4 0x14
-#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK 0xffe0
-#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT 5
-#define MDIO_OVER_1G_UP1 0x19
-#define MDIO_OVER_1G_UP1_2_5G 0x0001
-#define MDIO_OVER_1G_UP1_5G 0x0002
-#define MDIO_OVER_1G_UP1_6G 0x0004
-#define MDIO_OVER_1G_UP1_10G 0x0010
-#define MDIO_OVER_1G_UP1_10GH 0x0008
-#define MDIO_OVER_1G_UP1_12G 0x0020
-#define MDIO_OVER_1G_UP1_12_5G 0x0040
-#define MDIO_OVER_1G_UP1_13G 0x0080
-#define MDIO_OVER_1G_UP1_15G 0x0100
-#define MDIO_OVER_1G_UP1_16G 0x0200
-#define MDIO_OVER_1G_UP2 0x1A
-#define MDIO_OVER_1G_UP2_IPREDRIVER_MASK 0x0007
-#define MDIO_OVER_1G_UP2_IDRIVER_MASK 0x0038
-#define MDIO_OVER_1G_UP2_PREEMPHASIS_MASK 0x03C0
-#define MDIO_OVER_1G_UP3 0x1B
-#define MDIO_OVER_1G_UP3_HIGIG2 0x0001
-#define MDIO_OVER_1G_LP_UP1 0x1C
-#define MDIO_OVER_1G_LP_UP2 0x1D
-#define MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK 0x03ff
-#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK 0x0780
-#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT 7
-#define MDIO_OVER_1G_LP_UP3 0x1E
+#define MDIO_OVER_1G_DIGCTL_3_4 0x14
+#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK 0xffe0
+#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT 5
+#define MDIO_OVER_1G_UP1 0x19
+#define MDIO_OVER_1G_UP1_2_5G 0x0001
+#define MDIO_OVER_1G_UP1_5G 0x0002
+#define MDIO_OVER_1G_UP1_6G 0x0004
+#define MDIO_OVER_1G_UP1_10G 0x0010
+#define MDIO_OVER_1G_UP1_10GH 0x0008
+#define MDIO_OVER_1G_UP1_12G 0x0020
+#define MDIO_OVER_1G_UP1_12_5G 0x0040
+#define MDIO_OVER_1G_UP1_13G 0x0080
+#define MDIO_OVER_1G_UP1_15G 0x0100
+#define MDIO_OVER_1G_UP1_16G 0x0200
+#define MDIO_OVER_1G_UP2 0x1A
+#define MDIO_OVER_1G_UP2_IPREDRIVER_MASK 0x0007
+#define MDIO_OVER_1G_UP2_IDRIVER_MASK 0x0038
+#define MDIO_OVER_1G_UP2_PREEMPHASIS_MASK 0x03C0
+#define MDIO_OVER_1G_UP3 0x1B
+#define MDIO_OVER_1G_UP3_HIGIG2 0x0001
+#define MDIO_OVER_1G_LP_UP1 0x1C
+#define MDIO_OVER_1G_LP_UP2 0x1D
+#define MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK 0x03ff
+#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK 0x0780
+#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT 7
+#define MDIO_OVER_1G_LP_UP3 0x1E
#define MDIO_REG_BANK_BAM_NEXT_PAGE 0x8350
-#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL 0x10
-#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE 0x0001
-#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN 0x0002
+#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL 0x10
+#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE 0x0001
+#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN 0x0002
+
+#define MDIO_REG_BANK_CL73_USERB0 0x8370
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1 0x12
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN 0x8000
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN 0x4000
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN 0x2000
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL3 0x14
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR 0x0001
+
+#define MDIO_REG_BANK_AER_BLOCK 0xFFD0
+#define MDIO_AER_BLOCK_AER_REG 0x1E
+
+#define MDIO_REG_BANK_COMBO_IEEE0 0xFFE0
+#define MDIO_COMBO_IEEE0_MII_CONTROL 0x10
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK 0x2040
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10 0x0000
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100 0x2000
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000 0x0040
+#define MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX 0x0100
+#define MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN 0x0200
+#define MDIO_COMBO_IEEO_MII_CONTROL_AN_EN 0x1000
+#define MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK 0x4000
+#define MDIO_COMBO_IEEO_MII_CONTROL_RESET 0x8000
+#define MDIO_COMBO_IEEE0_MII_STATUS 0x11
+#define MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS 0x0004
+#define MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE 0x0020
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV 0x14
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX 0x0020
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX 0x0040
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK 0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE 0x0000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC 0x0080
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC 0x0100
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH 0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE 0x8000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1 0x15
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE 0x8000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK 0x4000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK 0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE 0x0000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH 0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP 0x0040
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP 0x0020
+/*WhenthelinkpartnerisinSGMIImode(bit0=1),then
+bit15=link,bit12=duplex,bits11:10=speed,bit14=acknowledge.
+Theotherbitsarereservedandshouldbezero*/
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001
+
+
+#define MDIO_PMA_DEVAD 0x1
+/*ieee*/
+#define MDIO_PMA_REG_CTRL 0x0
+#define MDIO_PMA_REG_STATUS 0x1
+#define MDIO_PMA_REG_10G_CTRL2 0x7
+#define MDIO_PMA_REG_RX_SD 0xa
+/*bcm*/
+#define MDIO_PMA_REG_BCM_CTRL 0x0096
+#define MDIO_PMA_REG_FEC_CTRL 0x00ab
+#define MDIO_PMA_REG_RX_ALARM_CTRL 0x9000
+#define MDIO_PMA_REG_LASI_CTRL 0x9002
+#define MDIO_PMA_REG_RX_ALARM 0x9003
+#define MDIO_PMA_REG_TX_ALARM 0x9004
+#define MDIO_PMA_REG_LASI_STATUS 0x9005
+#define MDIO_PMA_REG_PHY_IDENTIFIER 0xc800
+#define MDIO_PMA_REG_DIGITAL_CTRL 0xc808
+#define MDIO_PMA_REG_DIGITAL_STATUS 0xc809
+#define MDIO_PMA_REG_TX_POWER_DOWN 0xca02
+#define MDIO_PMA_REG_CMU_PLL_BYPASS 0xca09
+#define MDIO_PMA_REG_MISC_CTRL 0xca0a
+#define MDIO_PMA_REG_GEN_CTRL 0xca10
+#define MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP 0x0188
+#define MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET 0x018a
+#define MDIO_PMA_REG_ROM_VER1 0xca19
+#define MDIO_PMA_REG_ROM_VER2 0xca1a
+#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
+#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d
+#define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46
+#define MDIO_PMA_REG_MISC_CTRL1 0xca85
+
+#define MDIO_PMA_REG_7101_RESET 0xc000
+#define MDIO_PMA_REG_7107_LED_CNTL 0xc007
+#define MDIO_PMA_REG_7101_VER1 0xc026
+#define MDIO_PMA_REG_7101_VER2 0xc027
+
+
+#define MDIO_WIS_DEVAD 0x2
+/*bcm*/
+#define MDIO_WIS_REG_LASI_CNTL 0x9002
+#define MDIO_WIS_REG_LASI_STATUS 0x9005
+
+#define MDIO_PCS_DEVAD 0x3
+#define MDIO_PCS_REG_STATUS 0x0020
+#define MDIO_PCS_REG_LASI_STATUS 0x9005
+#define MDIO_PCS_REG_7101_DSP_ACCESS 0xD000
+#define MDIO_PCS_REG_7101_SPI_MUX 0xD008
+#define MDIO_PCS_REG_7101_SPI_CTRL_ADDR 0xE12A
+#define MDIO_PCS_REG_7101_SPI_RESET_BIT (5)
+#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR 0xE02A
+#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD (6)
+#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD (0xC7)
+#define MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD (2)
+#define MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR 0xE028
+
-#define MDIO_REG_BANK_CL73_USERB0 0x8370
-#define MDIO_CL73_USERB0_CL73_BAM_CTRL1 0x12
-#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN 0x8000
-#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN 0x4000
-#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN 0x2000
-#define MDIO_CL73_USERB0_CL73_BAM_CTRL3 0x14
-#define MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR 0x0001
+#define MDIO_XS_DEVAD 0x4
+#define MDIO_XS_PLL_SEQUENCER 0x8000
+#define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a
-#define MDIO_REG_BANK_AER_BLOCK 0xFFD0
-#define MDIO_AER_BLOCK_AER_REG 0x1E
+#define MDIO_AN_DEVAD 0x7
+/*ieee*/
+#define MDIO_AN_REG_CTRL 0x0000
+#define MDIO_AN_REG_STATUS 0x0001
+#define MDIO_AN_REG_STATUS_AN_COMPLETE 0x0020
+#define MDIO_AN_REG_ADV_PAUSE 0x0010
+#define MDIO_AN_REG_ADV_PAUSE_PAUSE 0x0400
+#define MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC 0x0800
+#define MDIO_AN_REG_ADV_PAUSE_BOTH 0x0C00
+#define MDIO_AN_REG_ADV_PAUSE_MASK 0x0C00
+#define MDIO_AN_REG_ADV 0x0011
+#define MDIO_AN_REG_ADV2 0x0012
+#define MDIO_AN_REG_LP_AUTO_NEG 0x0013
+#define MDIO_AN_REG_MASTER_STATUS 0x0021
+/*bcm*/
+#define MDIO_AN_REG_LINK_STATUS 0x8304
+#define MDIO_AN_REG_CL37_CL73 0x8370
+#define MDIO_AN_REG_CL37_AN 0xffe0
+#define MDIO_AN_REG_CL37_FD 0xffe4
-#define MDIO_REG_BANK_COMBO_IEEE0 0xFFE0
-#define MDIO_COMBO_IEEE0_MII_CONTROL 0x10
-#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK 0x2040
-#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10 0x0000
-#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100 0x2000
-#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000 0x0040
-#define MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX 0x0100
-#define MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN 0x0200
-#define MDIO_COMBO_IEEO_MII_CONTROL_AN_EN 0x1000
-#define MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK 0x4000
-#define MDIO_COMBO_IEEO_MII_CONTROL_RESET 0x8000
-#define MDIO_COMBO_IEEE0_MII_STATUS 0x11
-#define MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS 0x0004
-#define MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE 0x0020
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV 0x14
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX 0x0020
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX 0x0040
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK 0x0180
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE 0x0000
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC 0x0080
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC 0x0100
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH 0x0180
-#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE 0x8000
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1 0x15
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE 0x8000
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK 0x4000
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK 0x0180
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE\
- 0x0000
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH\
- 0x0180
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP 0x0040
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP 0x0020
-#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001
+#define IGU_FUNC_BASE 0x0400
-#define EXT_PHY_AUTO_NEG_DEVAD 0x7
-#define EXT_PHY_OPT_PMA_PMD_DEVAD 0x1
-#define EXT_PHY_OPT_WIS_DEVAD 0x2
-#define EXT_PHY_OPT_PCS_DEVAD 0x3
-#define EXT_PHY_OPT_PHY_XS_DEVAD 0x4
-#define EXT_PHY_OPT_CNTL 0x0
-#define EXT_PHY_OPT_CNTL2 0x7
-#define EXT_PHY_OPT_PMD_RX_SD 0xa
-#define EXT_PHY_OPT_PMD_MISC_CNTL 0xca0a
-#define EXT_PHY_OPT_PHY_IDENTIFIER 0xc800
-#define EXT_PHY_OPT_PMD_DIGITAL_CNT 0xc808
-#define EXT_PHY_OPT_PMD_DIGITAL_SATUS 0xc809
-#define EXT_PHY_OPT_CMU_PLL_BYPASS 0xca09
-#define EXT_PHY_OPT_LASI_CNTL 0x9002
-#define EXT_PHY_OPT_RX_ALARM 0x9003
-#define EXT_PHY_OPT_LASI_STATUS 0x9005
-#define EXT_PHY_OPT_PCS_STATUS 0x0020
-#define EXT_PHY_OPT_XGXS_LANE_STATUS 0x0018
-#define EXT_PHY_OPT_AN_LINK_STATUS 0x8304
-#define EXT_PHY_OPT_AN_CL37_CL73 0x8370
-#define EXT_PHY_OPT_AN_CL37_FD 0xffe4
-#define EXT_PHY_OPT_AN_CL37_AN 0xffe0
-#define EXT_PHY_OPT_AN_ADV 0x11
+#define IGU_ADDR_MSIX 0x0000
+#define IGU_ADDR_INT_ACK 0x0200
+#define IGU_ADDR_PROD_UPD 0x0201
+#define IGU_ADDR_ATTN_BITS_UPD 0x0202
+#define IGU_ADDR_ATTN_BITS_SET 0x0203
+#define IGU_ADDR_ATTN_BITS_CLR 0x0204
+#define IGU_ADDR_COALESCE_NOW 0x0205
+#define IGU_ADDR_SIMD_MASK 0x0206
+#define IGU_ADDR_SIMD_NOMASK 0x0207
+#define IGU_ADDR_MSI_CTL 0x0210
+#define IGU_ADDR_MSI_ADDR_LO 0x0211
+#define IGU_ADDR_MSI_ADDR_HI 0x0212
+#define IGU_ADDR_MSI_DATA 0x0213
-#define EXT_PHY_KR_PMA_PMD_DEVAD 0x1
-#define EXT_PHY_KR_PCS_DEVAD 0x3
-#define EXT_PHY_KR_AUTO_NEG_DEVAD 0x7
-#define EXT_PHY_KR_CTRL 0x0000
-#define EXT_PHY_KR_STATUS 0x0001
-#define EXT_PHY_KR_AUTO_NEG_COMPLETE 0x0020
-#define EXT_PHY_KR_AUTO_NEG_ADVERT 0x0010
-#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE 0x0400
-#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_ASYMMETRIC 0x0800
-#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_BOTH 0x0C00
-#define EXT_PHY_KR_AUTO_NEG_ADVERT_PAUSE_MASK 0x0C00
-#define EXT_PHY_KR_LP_AUTO_NEG 0x0013
-#define EXT_PHY_KR_CTRL2 0x0007
-#define EXT_PHY_KR_PCS_STATUS 0x0020
-#define EXT_PHY_KR_PMD_CTRL 0x0096
-#define EXT_PHY_KR_LASI_CNTL 0x9002
-#define EXT_PHY_KR_LASI_STATUS 0x9005
-#define EXT_PHY_KR_MISC_CTRL1 0xca85
-#define EXT_PHY_KR_GEN_CTRL 0xca10
-#define EXT_PHY_KR_ROM_CODE 0xca19
-#define EXT_PHY_KR_ROM_RESET_INTERNAL_MP 0x0188
-#define EXT_PHY_KR_ROM_MICRO_RESET 0x018a
+#define IGU_INT_ENABLE 0
+#define IGU_INT_DISABLE 1
+#define IGU_INT_NOP 2
+#define IGU_INT_NOP2 3
-#define EXT_PHY_SFX7101_XGXS_TEST1 0xc00a
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 5a673725471..b211486a0ca 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -419,8 +419,10 @@ static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
}
if (!bond->alb_info.primary_is_promisc) {
- bond->alb_info.primary_is_promisc = 1;
- dev_set_promiscuity(bond->curr_active_slave->dev, 1);
+ if (!dev_set_promiscuity(bond->curr_active_slave->dev, 1))
+ bond->alb_info.primary_is_promisc = 1;
+ else
+ bond->alb_info.primary_is_promisc = 0;
}
bond->alb_info.rlb_promisc_timeout_counter = 0;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 50a40e43315..9737c06045d 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -88,6 +88,7 @@
#define BOND_LINK_ARP_INTERV 0
static int max_bonds = BOND_DEFAULT_MAX_BONDS;
+static int num_grat_arp = 1;
static int miimon = BOND_LINK_MON_INTERV;
static int updelay = 0;
static int downdelay = 0;
@@ -99,11 +100,13 @@ static char *xmit_hash_policy = NULL;
static int arp_interval = BOND_LINK_ARP_INTERV;
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
static char *arp_validate = NULL;
-static int fail_over_mac = 0;
+static char *fail_over_mac = NULL;
struct bond_params bonding_defaults;
module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
+module_param(num_grat_arp, int, 0644);
+MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
module_param(miimon, int, 0);
MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
module_param(updelay, int, 0);
@@ -133,8 +136,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
module_param(arp_validate, charp, 0);
MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
-module_param(fail_over_mac, int, 0);
-MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. 0 of off (default), 1 for on.");
+module_param(fail_over_mac, charp, 0);
+MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow");
/*----------------------------- Global variables ----------------------------*/
@@ -187,6 +190,13 @@ struct bond_parm_tbl arp_validate_tbl[] = {
{ NULL, -1},
};
+struct bond_parm_tbl fail_over_mac_tbl[] = {
+{ "none", BOND_FOM_NONE},
+{ "active", BOND_FOM_ACTIVE},
+{ "follow", BOND_FOM_FOLLOW},
+{ NULL, -1},
+};
+
/*-------------------------- Forward declarations ---------------------------*/
static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -261,14 +271,14 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
*/
static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
{
- struct vlan_entry *vlan, *next;
+ struct vlan_entry *vlan;
int res = -ENODEV;
dprintk("bond: %s, vlan id %d\n", bond->dev->name, vlan_id);
write_lock_bh(&bond->lock);
- list_for_each_entry_safe(vlan, next, &bond->vlan_list, vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (vlan->vlan_id == vlan_id) {
list_del(&vlan->vlan_list);
@@ -762,39 +772,49 @@ static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct
/*
* Push the promiscuity flag down to appropriate slaves
*/
-static void bond_set_promiscuity(struct bonding *bond, int inc)
+static int bond_set_promiscuity(struct bonding *bond, int inc)
{
+ int err = 0;
if (USES_PRIMARY(bond->params.mode)) {
/* write lock already acquired */
if (bond->curr_active_slave) {
- dev_set_promiscuity(bond->curr_active_slave->dev, inc);
+ err = dev_set_promiscuity(bond->curr_active_slave->dev,
+ inc);
}
} else {
struct slave *slave;
int i;
bond_for_each_slave(bond, slave, i) {
- dev_set_promiscuity(slave->dev, inc);
+ err = dev_set_promiscuity(slave->dev, inc);
+ if (err)
+ return err;
}
}
+ return err;
}
/*
* Push the allmulti flag down to all slaves
*/
-static void bond_set_allmulti(struct bonding *bond, int inc)
+static int bond_set_allmulti(struct bonding *bond, int inc)
{
+ int err = 0;
if (USES_PRIMARY(bond->params.mode)) {
/* write lock already acquired */
if (bond->curr_active_slave) {
- dev_set_allmulti(bond->curr_active_slave->dev, inc);
+ err = dev_set_allmulti(bond->curr_active_slave->dev,
+ inc);
}
} else {
struct slave *slave;
int i;
bond_for_each_slave(bond, slave, i) {
- dev_set_allmulti(slave->dev, inc);
+ err = dev_set_allmulti(slave->dev, inc);
+ if (err)
+ return err;
}
}
+ return err;
}
/*
@@ -955,6 +975,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
}
if (new_active) {
+ /* FIXME: Signal errors upstream. */
if (bond->dev->flags & IFF_PROMISC) {
dev_set_promiscuity(new_active->dev, 1);
}
@@ -970,6 +991,82 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
}
}
+/*
+ * bond_do_fail_over_mac
+ *
+ * Perform special MAC address swapping for fail_over_mac settings
+ *
+ * Called with RTNL, bond->lock for read, curr_slave_lock for write_bh.
+ */
+static void bond_do_fail_over_mac(struct bonding *bond,
+ struct slave *new_active,
+ struct slave *old_active)
+{
+ u8 tmp_mac[ETH_ALEN];
+ struct sockaddr saddr;
+ int rv;
+
+ switch (bond->params.fail_over_mac) {
+ case BOND_FOM_ACTIVE:
+ if (new_active)
+ memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
+ new_active->dev->addr_len);
+ break;
+ case BOND_FOM_FOLLOW:
+ /*
+ * if new_active && old_active, swap them
+ * if just old_active, do nothing (going to no active slave)
+ * if just new_active, set new_active to bond's MAC
+ */
+ if (!new_active)
+ return;
+
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
+
+ if (old_active) {
+ memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN);
+ memcpy(saddr.sa_data, old_active->dev->dev_addr,
+ ETH_ALEN);
+ saddr.sa_family = new_active->dev->type;
+ } else {
+ memcpy(saddr.sa_data, bond->dev->dev_addr, ETH_ALEN);
+ saddr.sa_family = bond->dev->type;
+ }
+
+ rv = dev_set_mac_address(new_active->dev, &saddr);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: Error %d setting MAC of slave %s\n",
+ bond->dev->name, -rv, new_active->dev->name);
+ goto out;
+ }
+
+ if (!old_active)
+ goto out;
+
+ memcpy(saddr.sa_data, tmp_mac, ETH_ALEN);
+ saddr.sa_family = old_active->dev->type;
+
+ rv = dev_set_mac_address(old_active->dev, &saddr);
+ if (rv)
+ printk(KERN_ERR DRV_NAME
+ ": %s: Error %d setting MAC of slave %s\n",
+ bond->dev->name, -rv, new_active->dev->name);
+out:
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
+ break;
+ default:
+ printk(KERN_ERR DRV_NAME
+ ": %s: bond_do_fail_over_mac impossible: bad policy %d\n",
+ bond->dev->name, bond->params.fail_over_mac);
+ break;
+ }
+
+}
+
+
/**
* find_best_interface - select the best available slave to be the active one
* @bond: our bonding struct
@@ -1037,7 +1134,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
* because it is apparently the best available slave we have, even though its
* updelay hasn't timed out yet.
*
- * Warning: Caller must hold curr_slave_lock for writing.
+ * If new_active is not NULL, caller must hold bond->lock for read and
+ * curr_slave_lock for write_bh.
*/
void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
{
@@ -1048,6 +1146,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
}
if (new_active) {
+ new_active->jiffies = jiffies;
+
if (new_active->link == BOND_LINK_BACK) {
if (USES_PRIMARY(bond->params.mode)) {
printk(KERN_INFO DRV_NAME
@@ -1059,7 +1159,6 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
new_active->delay = 0;
new_active->link = BOND_LINK_UP;
- new_active->jiffies = jiffies;
if (bond->params.mode == BOND_MODE_8023AD) {
bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
@@ -1101,22 +1200,22 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (new_active) {
bond_set_slave_active_flags(new_active);
- }
- /* when bonding does not set the slave MAC address, the bond MAC
- * address is the one of the active slave.
- */
- if (new_active && bond->params.fail_over_mac)
- memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
- new_active->dev->addr_len);
- if (bond->curr_active_slave &&
- test_bit(__LINK_STATE_LINKWATCH_PENDING,
- &bond->curr_active_slave->dev->state)) {
- dprintk("delaying gratuitous arp on %s\n",
- bond->curr_active_slave->dev->name);
- bond->send_grat_arp = 1;
- } else
+ if (bond->params.fail_over_mac)
+ bond_do_fail_over_mac(bond, new_active,
+ old_active);
+
+ bond->send_grat_arp = bond->params.num_grat_arp;
bond_send_gratuitous_arp(bond);
+
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
+
+ netdev_bonding_change(bond->dev);
+
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
+ }
}
}
@@ -1129,7 +1228,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
* - The primary_slave has got its link back.
* - A slave has got its link back and there's no old curr_active_slave.
*
- * Warning: Caller must hold curr_slave_lock for writing.
+ * Caller must hold bond->lock for read and curr_slave_lock for write_bh.
*/
void bond_select_active_slave(struct bonding *bond)
{
@@ -1376,14 +1475,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
printk(KERN_WARNING DRV_NAME
": %s: Warning: The first slave device "
"specified does not support setting the MAC "
- "address. Enabling the fail_over_mac option.",
+ "address. Setting fail_over_mac to active.",
bond_dev->name);
- bond->params.fail_over_mac = 1;
- } else if (!bond->params.fail_over_mac) {
+ bond->params.fail_over_mac = BOND_FOM_ACTIVE;
+ } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
printk(KERN_ERR DRV_NAME
": %s: Error: The slave device specified "
"does not support setting the MAC address, "
- "but fail_over_mac is not enabled.\n"
+ "but fail_over_mac is not set to active.\n"
, bond_dev->name);
res = -EOPNOTSUPP;
goto err_undo_flags;
@@ -1456,20 +1555,24 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
if (!USES_PRIMARY(bond->params.mode)) {
/* set promiscuity level to new slave */
if (bond_dev->flags & IFF_PROMISC) {
- dev_set_promiscuity(slave_dev, 1);
+ res = dev_set_promiscuity(slave_dev, 1);
+ if (res)
+ goto err_close;
}
/* set allmulti level to new slave */
if (bond_dev->flags & IFF_ALLMULTI) {
- dev_set_allmulti(slave_dev, 1);
+ res = dev_set_allmulti(slave_dev, 1);
+ if (res)
+ goto err_close;
}
- netif_tx_lock_bh(bond_dev);
+ netif_addr_lock_bh(bond_dev);
/* upload master's mc_list to new slave */
for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
}
- netif_tx_unlock_bh(bond_dev);
+ netif_addr_unlock_bh(bond_dev);
}
if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1490,6 +1593,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
bond_compute_features(bond);
+ write_unlock_bh(&bond->lock);
+
+ read_lock(&bond->lock);
+
new_slave->last_arp_rx = jiffies;
if (bond->params.miimon && !bond->params.use_carrier) {
@@ -1566,6 +1673,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
}
}
+ write_lock_bh(&bond->curr_slave_lock);
+
switch (bond->params.mode) {
case BOND_MODE_ACTIVEBACKUP:
bond_set_slave_inactive_flags(new_slave);
@@ -1613,9 +1722,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
break;
} /* switch(bond_mode) */
+ write_unlock_bh(&bond->curr_slave_lock);
+
bond_set_carrier(bond);
- write_unlock_bh(&bond->lock);
+ read_unlock(&bond->lock);
res = bond_create_slave_symlinks(bond_dev, slave_dev);
if (res)
@@ -1639,6 +1750,10 @@ err_unset_master:
err_restore_mac:
if (!bond->params.fail_over_mac) {
+ /* XXX TODO - fom follow mode needs to change master's
+ * MAC if this slave's MAC is in use by the bond, or at
+ * least print a warning.
+ */
memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
@@ -1693,20 +1808,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
return -EINVAL;
}
- mac_addr_differ = memcmp(bond_dev->dev_addr,
- slave->perm_hwaddr,
- ETH_ALEN);
- if (!mac_addr_differ && (bond->slave_cnt > 1)) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: the permanent HWaddr of %s - "
- "%s - is still in use by %s. "
- "Set the HWaddr of %s to a different address "
- "to avoid conflicts.\n",
- bond_dev->name,
- slave_dev->name,
- print_mac(mac, slave->perm_hwaddr),
- bond_dev->name,
- slave_dev->name);
+ if (!bond->params.fail_over_mac) {
+ mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
+ ETH_ALEN);
+ if (!mac_addr_differ && (bond->slave_cnt > 1))
+ printk(KERN_WARNING DRV_NAME
+ ": %s: Warning: the permanent HWaddr of %s - "
+ "%s - is still in use by %s. "
+ "Set the HWaddr of %s to a different address "
+ "to avoid conflicts.\n",
+ bond_dev->name, slave_dev->name,
+ print_mac(mac, slave->perm_hwaddr),
+ bond_dev->name, slave_dev->name);
}
/* Inform AD package of unbinding of slave. */
@@ -1823,9 +1936,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
}
/* flush master's mc_list from slave */
- netif_tx_lock_bh(bond_dev);
+ netif_addr_lock_bh(bond_dev);
bond_mc_list_flush(bond_dev, slave_dev);
- netif_tx_unlock_bh(bond_dev);
+ netif_addr_unlock_bh(bond_dev);
}
netdev_set_master(slave_dev, NULL);
@@ -1833,7 +1946,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
- if (!bond->params.fail_over_mac) {
+ if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
/* restore original ("permanent") mac address */
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
@@ -1946,9 +2059,9 @@ static int bond_release_all(struct net_device *bond_dev)
}
/* flush master's mc_list from slave */
- netif_tx_lock_bh(bond_dev);
+ netif_addr_lock_bh(bond_dev);
bond_mc_list_flush(bond_dev, slave_dev);
- netif_tx_unlock_bh(bond_dev);
+ netif_addr_unlock_bh(bond_dev);
}
netdev_set_master(slave_dev, NULL);
@@ -2136,17 +2249,6 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks)
* program could monitor the link itself if needed.
*/
- if (bond->send_grat_arp) {
- if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING,
- &bond->curr_active_slave->dev->state))
- dprintk("Needs to send gratuitous arp but not yet\n");
- else {
- dprintk("sending delayed gratuitous arp on on %s\n",
- bond->curr_active_slave->dev->name);
- bond_send_gratuitous_arp(bond);
- bond->send_grat_arp = 0;
- }
- }
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
@@ -2387,6 +2489,13 @@ void bond_mii_monitor(struct work_struct *work)
read_unlock(&bond->lock);
return;
}
+
+ if (bond->send_grat_arp) {
+ read_lock(&bond->curr_slave_lock);
+ bond_send_gratuitous_arp(bond);
+ read_unlock(&bond->curr_slave_lock);
+ }
+
if (__bond_mii_monitor(bond, 0)) {
read_unlock(&bond->lock);
rtnl_lock();
@@ -2397,7 +2506,7 @@ void bond_mii_monitor(struct work_struct *work)
read_lock(&bond->lock);
}
- delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
+ delay = msecs_to_jiffies(bond->params.miimon);
read_unlock(&bond->lock);
queue_delayed_work(bond->wq, &bond->mii_work, delay);
}
@@ -2426,37 +2535,14 @@ out:
return addr;
}
-static int bond_has_ip(struct bonding *bond)
-{
- struct vlan_entry *vlan, *vlan_next;
-
- if (bond->master_ip)
- return 1;
-
- if (list_empty(&bond->vlan_list))
- return 0;
-
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
- if (vlan->vlan_ip)
- return 1;
- }
-
- return 0;
-}
-
static int bond_has_this_ip(struct bonding *bond, __be32 ip)
{
- struct vlan_entry *vlan, *vlan_next;
+ struct vlan_entry *vlan;
if (ip == bond->master_ip)
return 1;
- if (list_empty(&bond->vlan_list))
- return 0;
-
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (ip == vlan->vlan_ip)
return 1;
}
@@ -2498,7 +2584,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
{
int i, vlan_id, rv;
__be32 *targets = bond->params.arp_targets;
- struct vlan_entry *vlan, *vlan_next;
+ struct vlan_entry *vlan;
struct net_device *vlan_dev;
struct flowi fl;
struct rtable *rt;
@@ -2545,8 +2631,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
}
vlan_id = 0;
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
if (vlan_dev == rt->u.dst.dev) {
vlan_id = vlan->vlan_id;
@@ -2576,6 +2661,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
/*
* Kick out a gratuitous ARP for an IP on the bonding master plus one
* for each VLAN above us.
+ *
+ * Caller must hold curr_slave_lock for read or better
*/
static void bond_send_gratuitous_arp(struct bonding *bond)
{
@@ -2585,9 +2672,13 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
slave ? slave->dev->name : "NULL");
- if (!slave)
+
+ if (!slave || !bond->send_grat_arp ||
+ test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
return;
+ bond->send_grat_arp--;
+
if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
bond->master_ip, 0);
@@ -2707,7 +2798,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
read_lock(&bond->lock);
- delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
+ delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
if (bond->kill_timers) {
goto out;
@@ -2764,8 +2855,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* if we don't know our ip yet
*/
if (time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
- (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks) &&
- bond_has_ip(bond))) {
+ (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) {
slave->link = BOND_LINK_DOWN;
slave->state = BOND_STATE_BACKUP;
@@ -2813,246 +2903,305 @@ out:
}
/*
- * When using arp monitoring in active-backup mode, this function is
- * called to determine if any backup slaves have went down or a new
- * current slave needs to be found.
- * The backup slaves never generate traffic, they are considered up by merely
- * receiving traffic. If the current slave goes down, each backup slave will
- * be given the opportunity to tx/rx an arp before being taken down - this
- * prevents all slaves from being taken down due to the current slave not
- * sending any traffic for the backups to receive. The arps are not necessarily
- * necessary, any tx and rx traffic will keep the current slave up. While any
- * rx traffic will keep the backup slaves up, the current slave is responsible
- * for generating traffic to keep them up regardless of any other traffic they
- * may have received.
- * see loadbalance_arp_monitor for arp monitoring in load balancing mode
+ * Called to inspect slaves for active-backup mode ARP monitor link state
+ * changes. Sets new_link in slaves to specify what action should take
+ * place for the slave. Returns 0 if no changes are found, >0 if changes
+ * to link states must be committed.
+ *
+ * Called with bond->lock held for read.
*/
-void bond_activebackup_arp_mon(struct work_struct *work)
+static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
{
- struct bonding *bond = container_of(work, struct bonding,
- arp_work.work);
struct slave *slave;
- int delta_in_ticks;
- int i;
+ int i, commit = 0;
- read_lock(&bond->lock);
+ bond_for_each_slave(bond, slave, i) {
+ slave->new_link = BOND_LINK_NOCHANGE;
- delta_in_ticks = (bond->params.arp_interval * HZ) / 1000;
+ if (slave->link != BOND_LINK_UP) {
+ if (time_before_eq(jiffies, slave_last_rx(bond, slave) +
+ delta_in_ticks)) {
+ slave->new_link = BOND_LINK_UP;
+ commit++;
+ }
- if (bond->kill_timers) {
- goto out;
- }
+ continue;
+ }
- if (bond->slave_cnt == 0) {
- goto re_arm;
+ /*
+ * Give slaves 2*delta after being enslaved or made
+ * active. This avoids bouncing, as the last receive
+ * times need a full ARP monitor cycle to be updated.
+ */
+ if (!time_after_eq(jiffies, slave->jiffies +
+ 2 * delta_in_ticks))
+ continue;
+
+ /*
+ * Backup slave is down if:
+ * - No current_arp_slave AND
+ * - more than 3*delta since last receive AND
+ * - the bond has an IP address
+ *
+ * Note: a non-null current_arp_slave indicates
+ * the curr_active_slave went down and we are
+ * searching for a new one; under this condition
+ * we only take the curr_active_slave down - this
+ * gives each slave a chance to tx/rx traffic
+ * before being taken out
+ */
+ if (slave->state == BOND_STATE_BACKUP &&
+ !bond->current_arp_slave &&
+ time_after(jiffies, slave_last_rx(bond, slave) +
+ 3 * delta_in_ticks)) {
+ slave->new_link = BOND_LINK_DOWN;
+ commit++;
+ }
+
+ /*
+ * Active slave is down if:
+ * - more than 2*delta since transmitting OR
+ * - (more than 2*delta since receive AND
+ * the bond has an IP address)
+ */
+ if ((slave->state == BOND_STATE_ACTIVE) &&
+ (time_after_eq(jiffies, slave->dev->trans_start +
+ 2 * delta_in_ticks) ||
+ (time_after_eq(jiffies, slave_last_rx(bond, slave)
+ + 2 * delta_in_ticks)))) {
+ slave->new_link = BOND_LINK_DOWN;
+ commit++;
+ }
}
- /* determine if any slave has come up or any backup slave has
- * gone down
- * TODO: what about up/down delay in arp mode? it wasn't here before
- * so it can wait
+ read_lock(&bond->curr_slave_lock);
+
+ /*
+ * Trigger a commit if the primary option setting has changed.
*/
- bond_for_each_slave(bond, slave, i) {
- if (slave->link != BOND_LINK_UP) {
- if (time_before_eq(jiffies,
- slave_last_rx(bond, slave) + delta_in_ticks)) {
+ if (bond->primary_slave &&
+ (bond->primary_slave != bond->curr_active_slave) &&
+ (bond->primary_slave->link == BOND_LINK_UP))
+ commit++;
- slave->link = BOND_LINK_UP;
+ read_unlock(&bond->curr_slave_lock);
- write_lock_bh(&bond->curr_slave_lock);
+ return commit;
+}
- if ((!bond->curr_active_slave) &&
- time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks)) {
- bond_change_active_slave(bond, slave);
- bond->current_arp_slave = NULL;
- } else if (bond->curr_active_slave != slave) {
- /* this slave has just come up but we
- * already have a current slave; this
- * can also happen if bond_enslave adds
- * a new slave that is up while we are
- * searching for a new slave
- */
- bond_set_slave_inactive_flags(slave);
- bond->current_arp_slave = NULL;
- }
+/*
+ * Called to commit link state changes noted by inspection step of
+ * active-backup mode ARP monitor.
+ *
+ * Called with RTNL and bond->lock for read.
+ */
+static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
+{
+ struct slave *slave;
+ int i;
- bond_set_carrier(bond);
+ bond_for_each_slave(bond, slave, i) {
+ switch (slave->new_link) {
+ case BOND_LINK_NOCHANGE:
+ continue;
- if (slave == bond->curr_active_slave) {
- printk(KERN_INFO DRV_NAME
- ": %s: %s is up and now the "
- "active interface\n",
- bond->dev->name,
- slave->dev->name);
- netif_carrier_on(bond->dev);
- } else {
- printk(KERN_INFO DRV_NAME
- ": %s: backup interface %s is "
- "now up\n",
- bond->dev->name,
- slave->dev->name);
- }
+ case BOND_LINK_UP:
+ write_lock_bh(&bond->curr_slave_lock);
- write_unlock_bh(&bond->curr_slave_lock);
- }
- } else {
- read_lock(&bond->curr_slave_lock);
+ if (!bond->curr_active_slave &&
+ time_before_eq(jiffies, slave->dev->trans_start +
+ delta_in_ticks)) {
+ slave->link = BOND_LINK_UP;
+ bond_change_active_slave(bond, slave);
+ bond->current_arp_slave = NULL;
- if ((slave != bond->curr_active_slave) &&
- (!bond->current_arp_slave) &&
- (time_after_eq(jiffies, slave_last_rx(bond, slave) + 3*delta_in_ticks) &&
- bond_has_ip(bond))) {
- /* a backup slave has gone down; three times
- * the delta allows the current slave to be
- * taken out before the backup slave.
- * note: a non-null current_arp_slave indicates
- * the curr_active_slave went down and we are
- * searching for a new one; under this
- * condition we only take the curr_active_slave
- * down - this gives each slave a chance to
- * tx/rx traffic before being taken out
+ printk(KERN_INFO DRV_NAME
+ ": %s: %s is up and now the "
+ "active interface\n",
+ bond->dev->name, slave->dev->name);
+
+ } else if (bond->curr_active_slave != slave) {
+ /* this slave has just come up but we
+ * already have a current slave; this can
+ * also happen if bond_enslave adds a new
+ * slave that is up while we are searching
+ * for a new slave
*/
+ slave->link = BOND_LINK_UP;
+ bond_set_slave_inactive_flags(slave);
+ bond->current_arp_slave = NULL;
- read_unlock(&bond->curr_slave_lock);
+ printk(KERN_INFO DRV_NAME
+ ": %s: backup interface %s is now up\n",
+ bond->dev->name, slave->dev->name);
+ }
- slave->link = BOND_LINK_DOWN;
+ write_unlock_bh(&bond->curr_slave_lock);
- if (slave->link_failure_count < UINT_MAX) {
- slave->link_failure_count++;
- }
+ break;
+
+ case BOND_LINK_DOWN:
+ if (slave->link_failure_count < UINT_MAX)
+ slave->link_failure_count++;
+
+ slave->link = BOND_LINK_DOWN;
+
+ if (slave == bond->curr_active_slave) {
+ printk(KERN_INFO DRV_NAME
+ ": %s: link status down for active "
+ "interface %s, disabling it\n",
+ bond->dev->name, slave->dev->name);
bond_set_slave_inactive_flags(slave);
+ write_lock_bh(&bond->curr_slave_lock);
+
+ bond_select_active_slave(bond);
+ if (bond->curr_active_slave)
+ bond->curr_active_slave->jiffies =
+ jiffies;
+
+ write_unlock_bh(&bond->curr_slave_lock);
+
+ bond->current_arp_slave = NULL;
+
+ } else if (slave->state == BOND_STATE_BACKUP) {
printk(KERN_INFO DRV_NAME
": %s: backup interface %s is now down\n",
- bond->dev->name,
- slave->dev->name);
- } else {
- read_unlock(&bond->curr_slave_lock);
+ bond->dev->name, slave->dev->name);
+
+ bond_set_slave_inactive_flags(slave);
}
+ break;
+
+ default:
+ printk(KERN_ERR DRV_NAME
+ ": %s: impossible: new_link %d on slave %s\n",
+ bond->dev->name, slave->new_link,
+ slave->dev->name);
}
}
- read_lock(&bond->curr_slave_lock);
- slave = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
-
- if (slave) {
- /* if we have sent traffic in the past 2*arp_intervals but
- * haven't xmit and rx traffic in that time interval, select
- * a different slave. slave->jiffies is only updated when
- * a slave first becomes the curr_active_slave - not necessarily
- * after every arp; this ensures the slave has a full 2*delta
- * before being taken out. if a primary is being used, check
- * if it is up and needs to take over as the curr_active_slave
- */
- if ((time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
- (time_after_eq(jiffies, slave_last_rx(bond, slave) + 2*delta_in_ticks) &&
- bond_has_ip(bond))) &&
- time_after_eq(jiffies, slave->jiffies + 2*delta_in_ticks)) {
+ /*
+ * No race with changes to primary via sysfs, as we hold rtnl.
+ */
+ if (bond->primary_slave &&
+ (bond->primary_slave != bond->curr_active_slave) &&
+ (bond->primary_slave->link == BOND_LINK_UP)) {
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_change_active_slave(bond, bond->primary_slave);
+ write_unlock_bh(&bond->curr_slave_lock);
+ }
- slave->link = BOND_LINK_DOWN;
+ bond_set_carrier(bond);
+}
- if (slave->link_failure_count < UINT_MAX) {
- slave->link_failure_count++;
- }
+/*
+ * Send ARP probes for active-backup mode ARP monitor.
+ *
+ * Called with bond->lock held for read.
+ */
+static void bond_ab_arp_probe(struct bonding *bond)
+{
+ struct slave *slave;
+ int i;
- printk(KERN_INFO DRV_NAME
- ": %s: link status down for active interface "
- "%s, disabling it\n",
- bond->dev->name,
- slave->dev->name);
+ read_lock(&bond->curr_slave_lock);
- write_lock_bh(&bond->curr_slave_lock);
+ if (bond->current_arp_slave && bond->curr_active_slave)
+ printk("PROBE: c_arp %s && cas %s BAD\n",
+ bond->current_arp_slave->dev->name,
+ bond->curr_active_slave->dev->name);
- bond_select_active_slave(bond);
- slave = bond->curr_active_slave;
+ if (bond->curr_active_slave) {
+ bond_arp_send_all(bond, bond->curr_active_slave);
+ read_unlock(&bond->curr_slave_lock);
+ return;
+ }
- write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->curr_slave_lock);
- bond->current_arp_slave = slave;
+ /* if we don't have a curr_active_slave, search for the next available
+ * backup slave from the current_arp_slave and make it the candidate
+ * for becoming the curr_active_slave
+ */
- if (slave) {
- slave->jiffies = jiffies;
- }
- } else if ((bond->primary_slave) &&
- (bond->primary_slave != slave) &&
- (bond->primary_slave->link == BOND_LINK_UP)) {
- /* at this point, slave is the curr_active_slave */
- printk(KERN_INFO DRV_NAME
- ": %s: changing from interface %s to primary "
- "interface %s\n",
- bond->dev->name,
- slave->dev->name,
- bond->primary_slave->dev->name);
+ if (!bond->current_arp_slave) {
+ bond->current_arp_slave = bond->first_slave;
+ if (!bond->current_arp_slave)
+ return;
+ }
- /* primary is up so switch to it */
- write_lock_bh(&bond->curr_slave_lock);
- bond_change_active_slave(bond, bond->primary_slave);
- write_unlock_bh(&bond->curr_slave_lock);
+ bond_set_slave_inactive_flags(bond->current_arp_slave);
- slave = bond->primary_slave;
+ /* search for next candidate */
+ bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave->next) {
+ if (IS_UP(slave->dev)) {
+ slave->link = BOND_LINK_BACK;
+ bond_set_slave_active_flags(slave);
+ bond_arp_send_all(bond, slave);
slave->jiffies = jiffies;
- } else {
- bond->current_arp_slave = NULL;
+ bond->current_arp_slave = slave;
+ break;
}
- /* the current slave must tx an arp to ensure backup slaves
- * rx traffic
+ /* if the link state is up at this point, we
+ * mark it down - this can happen if we have
+ * simultaneous link failures and
+ * reselect_active_interface doesn't make this
+ * one the current slave so it is still marked
+ * up when it is actually down
*/
- if (slave && bond_has_ip(bond)) {
- bond_arp_send_all(bond, slave);
+ if (slave->link == BOND_LINK_UP) {
+ slave->link = BOND_LINK_DOWN;
+ if (slave->link_failure_count < UINT_MAX)
+ slave->link_failure_count++;
+
+ bond_set_slave_inactive_flags(slave);
+
+ printk(KERN_INFO DRV_NAME
+ ": %s: backup interface %s is now down.\n",
+ bond->dev->name, slave->dev->name);
}
}
+}
- /* if we don't have a curr_active_slave, search for the next available
- * backup slave from the current_arp_slave and make it the candidate
- * for becoming the curr_active_slave
- */
- if (!slave) {
- if (!bond->current_arp_slave) {
- bond->current_arp_slave = bond->first_slave;
- }
+void bond_activebackup_arp_mon(struct work_struct *work)
+{
+ struct bonding *bond = container_of(work, struct bonding,
+ arp_work.work);
+ int delta_in_ticks;
- if (bond->current_arp_slave) {
- bond_set_slave_inactive_flags(bond->current_arp_slave);
+ read_lock(&bond->lock);
- /* search for next candidate */
- bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave->next) {
- if (IS_UP(slave->dev)) {
- slave->link = BOND_LINK_BACK;
- bond_set_slave_active_flags(slave);
- bond_arp_send_all(bond, slave);
- slave->jiffies = jiffies;
- bond->current_arp_slave = slave;
- break;
- }
+ if (bond->kill_timers)
+ goto out;
- /* if the link state is up at this point, we
- * mark it down - this can happen if we have
- * simultaneous link failures and
- * reselect_active_interface doesn't make this
- * one the current slave so it is still marked
- * up when it is actually down
- */
- if (slave->link == BOND_LINK_UP) {
- slave->link = BOND_LINK_DOWN;
- if (slave->link_failure_count < UINT_MAX) {
- slave->link_failure_count++;
- }
+ delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
- bond_set_slave_inactive_flags(slave);
+ if (bond->slave_cnt == 0)
+ goto re_arm;
- printk(KERN_INFO DRV_NAME
- ": %s: backup interface %s is "
- "now down.\n",
- bond->dev->name,
- slave->dev->name);
- }
- }
- }
+ if (bond->send_grat_arp) {
+ read_lock(&bond->curr_slave_lock);
+ bond_send_gratuitous_arp(bond);
+ read_unlock(&bond->curr_slave_lock);
}
+ if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
+ read_unlock(&bond->lock);
+ rtnl_lock();
+ read_lock(&bond->lock);
+
+ bond_ab_arp_commit(bond, delta_in_ticks);
+
+ read_unlock(&bond->lock);
+ rtnl_unlock();
+ read_lock(&bond->lock);
+ }
+
+ bond_ab_arp_probe(bond);
+
re_arm:
if (bond->params.arp_interval) {
queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
@@ -3128,7 +3277,8 @@ static void bond_info_show_master(struct seq_file *seq)
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
bond->params.fail_over_mac)
- seq_printf(seq, " (fail_over_mac)");
+ seq_printf(seq, " (fail_over_mac %s)",
+ fail_over_mac_tbl[bond->params.fail_over_mac].modename);
seq_printf(seq, "\n");
@@ -3500,13 +3650,13 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
{
struct in_ifaddr *ifa = ptr;
struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
- struct bonding *bond, *bond_next;
- struct vlan_entry *vlan, *vlan_next;
+ struct bonding *bond;
+ struct vlan_entry *vlan;
if (dev_net(ifa->ifa_dev->dev) != &init_net)
return NOTIFY_DONE;
- list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) {
+ list_for_each_entry(bond, &bond_dev_list, bond_list) {
if (bond->dev == event_dev) {
switch (event) {
case NETDEV_UP:
@@ -3520,11 +3670,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
}
}
- if (list_empty(&bond->vlan_list))
- continue;
-
- list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
- vlan_list) {
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
if (vlan_dev == event_dev) {
switch (event) {
@@ -3716,6 +3862,7 @@ static int bond_close(struct net_device *bond_dev)
write_lock_bh(&bond->lock);
+ bond->send_grat_arp = 0;
/* signal timers not to re-arm */
bond->kill_timers = 1;
@@ -3933,6 +4080,10 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
* Do promisc before checking multicast_mode
*/
if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
+ /*
+ * FIXME: Need to handle the error when one of the multi-slaves
+ * encounters error.
+ */
bond_set_promiscuity(bond, 1);
}
@@ -3942,6 +4093,10 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
/* set allmulti flag to slaves */
if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
+ /*
+ * FIXME: Need to handle the error when one of the multi-slaves
+ * encounters error.
+ */
bond_set_allmulti(bond, 1);
}
@@ -4060,10 +4215,10 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
/*
- * If fail_over_mac is enabled, do nothing and return success.
- * Returning an error causes ifenslave to fail.
+ * If fail_over_mac is set to active, do nothing and return
+ * success. Returning an error causes ifenslave to fail.
*/
- if (bond->params.fail_over_mac)
+ if (bond->params.fail_over_mac == BOND_FOM_ACTIVE)
return 0;
if (!is_valid_ether_addr(sa->sa_data)) {
@@ -4518,9 +4673,9 @@ static void bond_free_all(void)
struct net_device *bond_dev = bond->dev;
bond_work_cancel_all(bond);
- netif_tx_lock_bh(bond_dev);
+ netif_addr_lock_bh(bond_dev);
bond_mc_list_destroy(bond);
- netif_tx_unlock_bh(bond_dev);
+ netif_addr_unlock_bh(bond_dev);
/* Release the bonded slaves */
bond_release_all(bond_dev);
bond_destroy(bond);
@@ -4568,7 +4723,7 @@ int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
static int bond_check_params(struct bond_params *params)
{
- int arp_validate_value;
+ int arp_validate_value, fail_over_mac_value;
/*
* Convert string parameters.
@@ -4618,11 +4773,11 @@ static int bond_check_params(struct bond_params *params)
}
}
- if (max_bonds < 1 || max_bonds > INT_MAX) {
+ if (max_bonds < 0 || max_bonds > INT_MAX) {
printk(KERN_WARNING DRV_NAME
": Warning: max_bonds (%d) not in range %d-%d, so it "
"was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
- max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
+ max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds = BOND_DEFAULT_MAX_BONDS;
}
@@ -4658,6 +4813,13 @@ static int bond_check_params(struct bond_params *params)
use_carrier = 1;
}
+ if (num_grat_arp < 0 || num_grat_arp > 255) {
+ printk(KERN_WARNING DRV_NAME
+ ": Warning: num_grat_arp (%d) not in range 0-255 so it "
+ "was reset to 1 \n", num_grat_arp);
+ num_grat_arp = 1;
+ }
+
/* reset values for 802.3ad */
if (bond_mode == BOND_MODE_8023AD) {
if (!miimon) {
@@ -4814,7 +4976,7 @@ static int bond_check_params(struct bond_params *params)
printk("\n");
- } else {
+ } else if (max_bonds) {
/* miimon and arp_interval not set, we need one so things
* work as expected, see bonding.txt for details
*/
@@ -4836,15 +4998,29 @@ static int bond_check_params(struct bond_params *params)
primary = NULL;
}
- if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP))
- printk(KERN_WARNING DRV_NAME
- ": Warning: fail_over_mac only affects "
- "active-backup mode.\n");
+ if (fail_over_mac) {
+ fail_over_mac_value = bond_parse_parm(fail_over_mac,
+ fail_over_mac_tbl);
+ if (fail_over_mac_value == -1) {
+ printk(KERN_ERR DRV_NAME
+ ": Error: invalid fail_over_mac \"%s\"\n",
+ arp_validate == NULL ? "NULL" : arp_validate);
+ return -EINVAL;
+ }
+
+ if (bond_mode != BOND_MODE_ACTIVEBACKUP)
+ printk(KERN_WARNING DRV_NAME
+ ": Warning: fail_over_mac only affects "
+ "active-backup mode.\n");
+ } else {
+ fail_over_mac_value = BOND_FOM_NONE;
+ }
/* fill params struct with the proper values */
params->mode = bond_mode;
params->xmit_policy = xmit_hashtype;
params->miimon = miimon;
+ params->num_grat_arp = num_grat_arp;
params->arp_interval = arp_interval;
params->arp_validate = arp_validate_value;
params->updelay = updelay;
@@ -4852,7 +5028,7 @@ static int bond_check_params(struct bond_params *params)
params->use_carrier = use_carrier;
params->lacp_fast = lacp_fast;
params->primary[0] = 0;
- params->fail_over_mac = fail_over_mac;
+ params->fail_over_mac = fail_over_mac_value;
if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);
@@ -4866,15 +5042,28 @@ static int bond_check_params(struct bond_params *params)
static struct lock_class_key bonding_netdev_xmit_lock_key;
+static void bond_set_lockdep_class_one(struct net_device *dev,
+ struct netdev_queue *txq,
+ void *_unused)
+{
+ lockdep_set_class(&txq->_xmit_lock,
+ &bonding_netdev_xmit_lock_key);
+}
+
+static void bond_set_lockdep_class(struct net_device *dev)
+{
+ netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
+}
+
/* Create a new bond based on the specified name and bonding parameters.
* If name is NULL, obtain a suitable "bond%d" name for us.
* Caller must NOT hold rtnl_lock; we need to release it here before we
* set up our sysfs entries.
*/
-int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
+int bond_create(char *name, struct bond_params *params)
{
struct net_device *bond_dev;
- struct bonding *bond, *nxt;
+ struct bonding *bond;
int res;
rtnl_lock();
@@ -4882,7 +5071,7 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
/* Check to see if the bond already exists. */
if (name) {
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+ list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
printk(KERN_ERR DRV_NAME
": cannot add bond %s; it already exists\n",
@@ -4923,10 +5112,7 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
goto out_bond;
}
- lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key);
-
- if (newbond)
- *newbond = bond_dev->priv;
+ bond_set_lockdep_class(bond_dev);
netif_carrier_off(bond_dev);
@@ -4957,7 +5143,7 @@ static int __init bonding_init(void)
{
int i;
int res;
- struct bonding *bond, *nxt;
+ struct bonding *bond;
printk(KERN_INFO "%s", version);
@@ -4973,7 +5159,7 @@ static int __init bonding_init(void)
init_rwsem(&bonding_rwsem);
for (i = 0; i < max_bonds; i++) {
- res = bond_create(NULL, &bonding_defaults, NULL);
+ res = bond_create(NULL, &bonding_defaults);
if (res)
goto err;
}
@@ -4987,7 +5173,7 @@ static int __init bonding_init(void)
goto out;
err:
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+ list_for_each_entry(bond, &bond_dev_list, bond_list) {
bond_work_cancel_all(bond);
destroy_workqueue(bond->wq);
}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 08f3d396bcd..6caac0ffb2f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -50,9 +50,9 @@ extern struct bond_parm_tbl bond_mode_tbl[];
extern struct bond_parm_tbl bond_lacp_tbl[];
extern struct bond_parm_tbl xmit_hashtype_tbl[];
extern struct bond_parm_tbl arp_validate_tbl[];
+extern struct bond_parm_tbl fail_over_mac_tbl[];
static int expected_refcount = -1;
-static struct class *netdev_class;
/*--------------------------- Data Structures -----------------------------*/
/* Bonding sysfs lock. Why can't we just use the subsystem lock?
@@ -111,7 +111,6 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
char *ifname;
int rv, res = count;
struct bonding *bond;
- struct bonding *nxt;
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
@@ -122,7 +121,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
if (command[0] == '+') {
printk(KERN_INFO DRV_NAME
": %s is being created...\n", ifname);
- rv = bond_create(ifname, &bonding_defaults, &bond);
+ rv = bond_create(ifname, &bonding_defaults);
if (rv) {
printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
res = rv;
@@ -134,7 +133,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
rtnl_lock();
down_write(&bonding_rwsem);
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+ list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
/* check the ref count on the bond's kobject.
* If it's > expected, then there's a file open,
@@ -548,42 +547,37 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1;
+ return sprintf(buf, "%s %d\n",
+ fail_over_mac_tbl[bond->params.fail_over_mac].modename,
+ bond->params.fail_over_mac);
}
static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
{
int new_value;
- int ret = count;
struct bonding *bond = to_bond(d);
if (bond->slave_cnt != 0) {
printk(KERN_ERR DRV_NAME
": %s: Can't alter fail_over_mac with slaves in bond.\n",
bond->dev->name);
- ret = -EPERM;
- goto out;
+ return -EPERM;
}
- if (sscanf(buf, "%d", &new_value) != 1) {
+ new_value = bond_parse_parm(buf, fail_over_mac_tbl);
+ if (new_value < 0) {
printk(KERN_ERR DRV_NAME
- ": %s: no fail_over_mac value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
+ ": %s: Ignoring invalid fail_over_mac value %s.\n",
+ bond->dev->name, buf);
+ return -EINVAL;
}
- if ((new_value == 0) || (new_value == 1)) {
- bond->params.fail_over_mac = new_value;
- printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n",
- bond->dev->name, new_value);
- } else {
- printk(KERN_INFO DRV_NAME
- ": %s: Ignoring invalid fail_over_mac value %d.\n",
- bond->dev->name, new_value);
- }
-out:
- return ret;
+ bond->params.fail_over_mac = new_value;
+ printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
+ bond->dev->name, fail_over_mac_tbl[new_value].modename,
+ new_value);
+
+ return count;
}
static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
@@ -952,6 +946,45 @@ out:
static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
/*
+ * Show and set the number of grat ARP to send after a failover event.
+ */
+static ssize_t bonding_show_n_grat_arp(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%d\n", bond->params.num_grat_arp);
+}
+
+static ssize_t bonding_store_n_grat_arp(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int new_value, ret = count;
+ struct bonding *bond = to_bond(d);
+
+ if (sscanf(buf, "%d", &new_value) != 1) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: no num_grat_arp value specified.\n",
+ bond->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+ if (new_value < 0 || new_value > 255) {
+ printk(KERN_ERR DRV_NAME
+ ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
+ bond->dev->name, new_value);
+ ret = -EINVAL;
+ goto out;
+ } else {
+ bond->params.num_grat_arp = new_value;
+ }
+out:
+ return ret;
+}
+static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp);
+/*
* Show and set the MII monitor interval. There are two tricky bits
* here. First, if MII monitoring is activated, then we must disable
* ARP monitoring. Second, if the timer isn't running, we must
@@ -1388,6 +1421,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_updelay.attr,
&dev_attr_lacp_rate.attr,
&dev_attr_xmit_hash_policy.attr,
+ &dev_attr_num_grat_arp.attr,
&dev_attr_miimon.attr,
&dev_attr_primary.attr,
&dev_attr_use_carrier.attr,
@@ -1412,19 +1446,9 @@ static struct attribute_group bonding_group = {
*/
int bond_create_sysfs(void)
{
- int ret = 0;
- struct bonding *firstbond;
-
- /* get the netdev class pointer */
- firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
- if (!firstbond)
- return -ENODEV;
+ int ret;
- netdev_class = firstbond->dev->dev.class;
- if (!netdev_class)
- return -ENODEV;
-
- ret = class_create_file(netdev_class, &class_attr_bonding_masters);
+ ret = netdev_class_create_file(&class_attr_bonding_masters);
/*
* Permit multiple loads of the module by ignoring failures to
* create the bonding_masters sysfs file. Bonding devices
@@ -1443,10 +1467,6 @@ int bond_create_sysfs(void)
printk(KERN_ERR
"network device named %s already exists in sysfs",
class_attr_bonding_masters.attr.name);
- else {
- netdev_class = NULL;
- return 0;
- }
}
return ret;
@@ -1458,8 +1478,7 @@ int bond_create_sysfs(void)
*/
void bond_destroy_sysfs(void)
{
- if (netdev_class)
- class_remove_file(netdev_class, &class_attr_bonding_masters);
+ netdev_class_remove_file(&class_attr_bonding_masters);
}
/*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index a3c74e20aa5..fb730ec0396 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
-#define DRV_VERSION "3.2.5"
-#define DRV_RELDATE "March 21, 2008"
+#define DRV_VERSION "3.3.0"
+#define DRV_RELDATE "June 10, 2008"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@@ -125,6 +125,7 @@ struct bond_params {
int mode;
int xmit_policy;
int miimon;
+ int num_grat_arp;
int arp_interval;
int arp_validate;
int use_carrier;
@@ -157,6 +158,7 @@ struct slave {
unsigned long jiffies;
unsigned long last_arp_rx;
s8 link; /* one of BOND_LINK_XXXX */
+ s8 new_link;
s8 state; /* one of BOND_STATE_XXXX */
u32 original_flags;
u32 original_mtu;
@@ -169,6 +171,11 @@ struct slave {
};
/*
+ * Link pseudo-state only used internally by monitors
+ */
+#define BOND_LINK_NOCHANGE -1
+
+/*
* Here are the locking policies for the two bonding locks:
*
* 1) Get bond->lock when reading/writing slave list.
@@ -241,6 +248,10 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
return (struct bonding *)slave->dev->master->priv;
}
+#define BOND_FOM_NONE 0
+#define BOND_FOM_ACTIVE 1
+#define BOND_FOM_FOLLOW 2
+
#define BOND_ARP_VALIDATE_NONE 0
#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
@@ -301,7 +312,7 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+int bond_create(char *name, struct bond_params *params);
void bond_destroy(struct bonding *bond);
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_create_sysfs(void);
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index a509337eab2..638c9a27a7a 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -1153,9 +1153,7 @@ static int __devinit init_one(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = t1_netpoll;
#endif
-#ifdef CONFIG_CHELSIO_T1_NAPI
netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
-#endif
SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
}
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 8a7efd38e95..d6c7d2aa761 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1396,20 +1396,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
st->vlan_xtract++;
-#ifdef CONFIG_CHELSIO_T1_NAPI
- vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
- ntohs(p->vlan));
-#else
- vlan_hwaccel_rx(skb, adapter->vlan_grp,
- ntohs(p->vlan));
-#endif
- } else {
-#ifdef CONFIG_CHELSIO_T1_NAPI
+ vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
+ ntohs(p->vlan));
+ } else
netif_receive_skb(skb);
-#else
- netif_rx(skb);
-#endif
- }
}
/*
@@ -1568,7 +1558,6 @@ static inline int responses_pending(const struct adapter *adapter)
return (e->GenerationBit == Q->genbit);
}
-#ifdef CONFIG_CHELSIO_T1_NAPI
/*
* A simpler version of process_responses() that handles only pure (i.e.,
* non data-carrying) responses. Such respones are too light-weight to justify
@@ -1636,9 +1625,6 @@ int t1_poll(struct napi_struct *napi, int budget)
return work_done;
}
-/*
- * NAPI version of the main interrupt handler.
- */
irqreturn_t t1_interrupt(int irq, void *data)
{
struct adapter *adapter = data;
@@ -1656,7 +1642,8 @@ irqreturn_t t1_interrupt(int irq, void *data)
else {
/* no data, no NAPI needed */
writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
- napi_enable(&adapter->napi); /* undo schedule_prep */
+ /* undo schedule_prep */
+ napi_enable(&adapter->napi);
}
}
return IRQ_HANDLED;
@@ -1672,53 +1659,6 @@ irqreturn_t t1_interrupt(int irq, void *data)
return IRQ_RETVAL(handled != 0);
}
-#else
-/*
- * Main interrupt handler, optimized assuming that we took a 'DATA'
- * interrupt.
- *
- * 1. Clear the interrupt
- * 2. Loop while we find valid descriptors and process them; accumulate
- * information that can be processed after the loop
- * 3. Tell the SGE at which index we stopped processing descriptors
- * 4. Bookkeeping; free TX buffers, ring doorbell if there are any
- * outstanding TX buffers waiting, replenish RX buffers, potentially
- * reenable upper layers if they were turned off due to lack of TX
- * resources which are available again.
- * 5. If we took an interrupt, but no valid respQ descriptors was found we
- * let the slow_intr_handler run and do error handling.
- */
-irqreturn_t t1_interrupt(int irq, void *cookie)
-{
- int work_done;
- struct adapter *adapter = cookie;
- struct respQ *Q = &adapter->sge->respQ;
-
- spin_lock(&adapter->async_lock);
-
- writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
-
- if (likely(responses_pending(adapter)))
- work_done = process_responses(adapter, -1);
- else
- work_done = t1_slow_intr_handler(adapter);
-
- /*
- * The unconditional clearing of the PL_CAUSE above may have raced
- * with DMA completion and the corresponding generation of a response
- * to cause us to miss the resulting data interrupt. The next write
- * is also unconditional to recover the missed interrupt and render
- * this race harmless.
- */
- writel(Q->cidx, adapter->regs + A_SG_SLEEPING);
-
- if (!work_done)
- adapter->sge->stats.unhandled_irqs++;
- spin_unlock(&adapter->async_lock);
- return IRQ_RETVAL(work_done != 0);
-}
-#endif
-
/*
* Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it.
*
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 7f3f62e1b11..fbd4280c102 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -544,7 +544,7 @@ fatal_error:
spin_unlock(&priv->rx_lock);
netif_rx_complete(priv->dev, napi);
- netif_stop_queue(priv->dev);
+ netif_tx_stop_all_queues(priv->dev);
napi_disable(&priv->napi);
atomic_inc(&priv->reset_pending);
@@ -569,11 +569,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
len = max(skb->len, ETH_ZLEN);
queue = skb_get_queue_mapping(skb);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(dev, queue);
-#else
- netif_stop_queue(dev);
-#endif
desc = &priv->desc_ring[queue];
if (unlikely(desc->dataflags & CPMAC_OWN)) {
@@ -626,24 +622,14 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
dev_kfree_skb_irq(desc->skb);
desc->skb = NULL;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (netif_subqueue_stopped(dev, queue))
netif_wake_subqueue(dev, queue);
-#else
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-#endif
} else {
if (netif_msg_tx_err(priv) && net_ratelimit())
printk(KERN_WARNING
"%s: end_xmit: spurious interrupt\n", dev->name);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (netif_subqueue_stopped(dev, queue))
netif_wake_subqueue(dev, queue);
-#else
- if (netif_queue_stopped(dev))
- netif_wake_queue(dev);
-#endif
}
}
@@ -764,9 +750,7 @@ static void cpmac_hw_error(struct work_struct *work)
barrier();
atomic_dec(&priv->reset_pending);
- for (i = 0; i < CPMAC_QUEUES; i++)
- netif_wake_subqueue(priv->dev, i);
- netif_wake_queue(priv->dev);
+ netif_tx_wake_all_queues(priv->dev);
cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3);
}
@@ -795,7 +779,7 @@ static void cpmac_check_status(struct net_device *dev)
dev->name, tx_code, tx_channel, macstatus);
}
- netif_stop_queue(dev);
+ netif_tx_stop_all_queues(dev);
cpmac_hw_stop(dev);
if (schedule_work(&priv->reset_work))
atomic_inc(&priv->reset_pending);
@@ -856,9 +840,7 @@ static void cpmac_tx_timeout(struct net_device *dev)
barrier();
atomic_dec(&priv->reset_pending);
- netif_wake_queue(priv->dev);
- for (i = 0; i < CPMAC_QUEUES; i++)
- netif_wake_subqueue(dev, i);
+ netif_tx_wake_all_queues(priv->dev);
}
static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -949,7 +931,7 @@ static void cpmac_adjust_link(struct net_device *dev)
spin_lock(&priv->lock);
if (priv->phy->link) {
- netif_start_queue(dev);
+ netif_tx_start_all_queues(dev);
if (priv->phy->duplex != priv->oldduplex) {
new_state = 1;
priv->oldduplex = priv->phy->duplex;
@@ -963,10 +945,10 @@ static void cpmac_adjust_link(struct net_device *dev)
if (!priv->oldlink) {
new_state = 1;
priv->oldlink = 1;
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
}
} else if (priv->oldlink) {
- netif_stop_queue(dev);
+ netif_tx_stop_all_queues(dev);
new_state = 1;
priv->oldlink = 0;
priv->oldspeed = 0;
@@ -1086,7 +1068,7 @@ static int cpmac_stop(struct net_device *dev)
struct cpmac_priv *priv = netdev_priv(dev);
struct resource *mem;
- netif_stop_queue(dev);
+ netif_tx_stop_all_queues(dev);
cancel_work_sync(&priv->reset_work);
napi_disable(&priv->napi);
@@ -1179,7 +1161,6 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
dev->set_multicast_list = cpmac_set_multicast_list;
dev->tx_timeout = cpmac_tx_timeout;
dev->ethtool_ops = &cpmac_ethtool_ops;
- dev->features |= NETIF_F_MULTI_QUEUE;
netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index acebe431d06..271140433b0 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -42,6 +42,7 @@
#include <linux/cache.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
+#include <linux/inet_lro.h>
#include "t3cdev.h"
#include <asm/io.h>
@@ -92,6 +93,7 @@ struct sge_fl { /* SGE per free-buffer list state */
unsigned int gen; /* free list generation */
struct fl_pg_chunk pg_chunk;/* page chunk cache */
unsigned int use_pages; /* whether FL uses pages or sk_buffs */
+ unsigned int order; /* order of page allocations */
struct rx_desc *desc; /* address of HW Rx descriptor ring */
struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */
dma_addr_t phys_addr; /* physical address of HW ring start */
@@ -116,12 +118,15 @@ struct sge_rspq { /* state for an SGE response queue */
unsigned int polling; /* is the queue serviced through NAPI? */
unsigned int holdoff_tmr; /* interrupt holdoff timer in 100ns */
unsigned int next_holdoff; /* holdoff time for next interrupt */
+ unsigned int rx_recycle_buf; /* whether recycling occurred
+ within current sop-eop */
struct rsp_desc *desc; /* address of HW response ring */
dma_addr_t phys_addr; /* physical address of the ring */
unsigned int cntxt_id; /* SGE context id for the response q */
spinlock_t lock; /* guards response processing */
struct sk_buff *rx_head; /* offload packet receive queue head */
struct sk_buff *rx_tail; /* offload packet receive queue tail */
+ struct sk_buff *pg_skb; /* used to build frag list in napi handler */
unsigned long offload_pkts;
unsigned long offload_bundles;
@@ -169,16 +174,29 @@ enum { /* per port SGE statistics */
SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */
SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */
SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */
+ SGE_PSTAT_LRO_AGGR, /* # of page chunks added to LRO sessions */
+ SGE_PSTAT_LRO_FLUSHED, /* # of flushed LRO sessions */
+ SGE_PSTAT_LRO_NO_DESC, /* # of overflown LRO sessions */
SGE_PSTAT_MAX /* must be last */
};
+#define T3_MAX_LRO_SES 8
+#define T3_MAX_LRO_MAX_PKTS 64
+
struct sge_qset { /* an SGE queue set */
struct adapter *adap;
struct napi_struct napi;
struct sge_rspq rspq;
struct sge_fl fl[SGE_RXQ_PER_SET];
struct sge_txq txq[SGE_TXQ_PER_SET];
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
+ struct skb_frag_struct *lro_frag_tbl;
+ int lro_nfrags;
+ int lro_enabled;
+ int lro_frag_len;
+ void *lro_va;
struct net_device *netdev;
unsigned long txq_stopped; /* which Tx queues are stopped */
struct timer_list tx_reclaim_timer; /* reclaims TX buffers */
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 8e8ebd78853..9ecf8a6dc97 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -351,6 +351,7 @@ struct tp_params {
struct qset_params { /* SGE queue set parameters */
unsigned int polling; /* polling/interrupt service for rspq */
+ unsigned int lro; /* large receive offload */
unsigned int coalesce_usecs; /* irq coalescing timer */
unsigned int rspq_size; /* # of entries in response queue */
unsigned int fl_size; /* # of entries in regular free list */
diff --git a/drivers/net/cxgb3/cxgb3_ctl_defs.h b/drivers/net/cxgb3/cxgb3_ctl_defs.h
index ed0ecd9679c..6ad92405d9a 100644
--- a/drivers/net/cxgb3/cxgb3_ctl_defs.h
+++ b/drivers/net/cxgb3/cxgb3_ctl_defs.h
@@ -111,10 +111,7 @@ struct ulp_iscsi_info {
unsigned int llimit;
unsigned int ulimit;
unsigned int tagmask;
- unsigned int pgsz3;
- unsigned int pgsz2;
- unsigned int pgsz1;
- unsigned int pgsz0;
+ u8 pgsz_factor[4];
unsigned int max_rxsz;
unsigned int max_txsz;
struct pci_dev *pdev;
diff --git a/drivers/net/cxgb3/cxgb3_ioctl.h b/drivers/net/cxgb3/cxgb3_ioctl.h
index 0a82fcddf2d..68200a14065 100644
--- a/drivers/net/cxgb3/cxgb3_ioctl.h
+++ b/drivers/net/cxgb3/cxgb3_ioctl.h
@@ -90,6 +90,7 @@ struct ch_qset_params {
int32_t fl_size[2];
int32_t intr_lat;
int32_t polling;
+ int32_t lro;
int32_t cong_thres;
};
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 3a312721679..5447f3e60f0 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1212,6 +1212,9 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"VLANinsertions ",
"TxCsumOffload ",
"RxCsumGood ",
+ "LroAggregated ",
+ "LroFlushed ",
+ "LroNoDesc ",
"RxDrops ",
"CheckTXEnToggled ",
@@ -1340,6 +1343,9 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
+ *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
+ *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
+ *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
*data++ = s->rx_cong_drops;
*data++ = s->num_toggled;
@@ -1558,6 +1564,13 @@ static int set_rx_csum(struct net_device *dev, u32 data)
struct port_info *p = netdev_priv(dev);
p->rx_csum_offload = data;
+ if (!data) {
+ struct adapter *adap = p->adapter;
+ int i;
+
+ for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
+ adap->sge.qs[i].lro_enabled = 0;
+ }
return 0;
}
@@ -1830,6 +1843,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
}
}
}
+ if (t.lro >= 0) {
+ struct sge_qset *qs = &adapter->sge.qs[t.qset_idx];
+ q->lro = t.lro;
+ qs->lro_enabled = t.lro;
+ }
break;
}
case CHELSIO_GET_QSET_PARAMS:{
@@ -1849,6 +1867,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
t.fl_size[0] = q->fl_size;
t.fl_size[1] = q->jumbo_size;
t.polling = q->polling;
+ t.lro = q->lro;
t.intr_lat = q->coalesce_usecs;
t.cong_thres = q->cong_thres;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index cf269687379..c5b3de1bb45 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -207,6 +207,17 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
break;
case ULP_ISCSI_SET_PARAMS:
t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask);
+ /* set MaxRxData and MaxCoalesceSize to 16224 */
+ t3_write_reg(adapter, A_TP_PARA_REG2, 0x3f603f60);
+ /* program the ddp page sizes */
+ {
+ int i;
+ unsigned int val = 0;
+ for (i = 0; i < 4; i++)
+ val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i);
+ if (val)
+ t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val);
+ }
break;
default:
ret = -EOPNOTSUPP;
@@ -1255,6 +1266,25 @@ static inline void unregister_tdev(struct t3cdev *tdev)
mutex_unlock(&cxgb3_db_lock);
}
+static inline int adap2type(struct adapter *adapter)
+{
+ int type = 0;
+
+ switch (adapter->params.rev) {
+ case T3_REV_A:
+ type = T3A;
+ break;
+ case T3_REV_B:
+ case T3_REV_B2:
+ type = T3B;
+ break;
+ case T3_REV_C:
+ type = T3C;
+ break;
+ }
+ return type;
+}
+
void __devinit cxgb3_adapter_ofld(struct adapter *adapter)
{
struct t3cdev *tdev = &adapter->tdev;
@@ -1264,7 +1294,7 @@ void __devinit cxgb3_adapter_ofld(struct adapter *adapter)
cxgb3_set_dummy_ops(tdev);
tdev->send = t3_offload_tx;
tdev->ctl = cxgb_offload_ctl;
- tdev->type = adapter->params.rev == 0 ? T3A : T3B;
+ tdev->type = adap2type(adapter);
register_tdev(tdev);
}
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index f510140885a..825e510bd9e 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -337,7 +337,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
atomic_set(&e->refcnt, 1);
neigh_replace(e, neigh);
if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
- e->vlan = vlan_dev_info(neigh->dev)->vlan_id;
+ e->vlan = vlan_dev_vlan_id(neigh->dev);
else
e->vlan = VLAN_NONE;
spin_unlock(&e->lock);
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index 56717887934..4bda27c551c 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1517,16 +1517,18 @@
#define A_ULPRX_ISCSI_TAGMASK 0x514
-#define S_HPZ0 0
-#define M_HPZ0 0xf
-#define V_HPZ0(x) ((x) << S_HPZ0)
-#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
+#define A_ULPRX_ISCSI_PSZ 0x518
#define A_ULPRX_TDDP_LLIMIT 0x51c
#define A_ULPRX_TDDP_ULIMIT 0x520
#define A_ULPRX_TDDP_PSZ 0x528
+#define S_HPZ0 0
+#define M_HPZ0 0xf
+#define V_HPZ0(x) ((x) << S_HPZ0)
+#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
+
#define A_ULPRX_STAG_LLIMIT 0x52c
#define A_ULPRX_STAG_ULIMIT 0x530
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 796eb305cdc..a96331c875e 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -55,6 +55,9 @@
* directly.
*/
#define FL0_PG_CHUNK_SIZE 2048
+#define FL0_PG_ORDER 0
+#define FL1_PG_CHUNK_SIZE (PAGE_SIZE > 8192 ? 16384 : 8192)
+#define FL1_PG_ORDER (PAGE_SIZE > 8192 ? 0 : 1)
#define SGE_RX_DROP_THRES 16
@@ -359,7 +362,7 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
}
if (q->pg_chunk.page) {
- __free_page(q->pg_chunk.page);
+ __free_pages(q->pg_chunk.page, q->order);
q->pg_chunk.page = NULL;
}
}
@@ -376,13 +379,16 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
* Add a buffer of the given length to the supplied HW and SW Rx
* descriptors.
*/
-static inline void add_one_rx_buf(void *va, unsigned int len,
- struct rx_desc *d, struct rx_sw_desc *sd,
- unsigned int gen, struct pci_dev *pdev)
+static inline int add_one_rx_buf(void *va, unsigned int len,
+ struct rx_desc *d, struct rx_sw_desc *sd,
+ unsigned int gen, struct pci_dev *pdev)
{
dma_addr_t mapping;
mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(mapping)))
+ return -ENOMEM;
+
pci_unmap_addr_set(sd, dma_addr, mapping);
d->addr_lo = cpu_to_be32(mapping);
@@ -390,12 +396,14 @@ static inline void add_one_rx_buf(void *va, unsigned int len,
wmb();
d->len_gen = cpu_to_be32(V_FLD_GEN1(gen));
d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
+ return 0;
}
-static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp)
+static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
+ unsigned int order)
{
if (!q->pg_chunk.page) {
- q->pg_chunk.page = alloc_page(gfp);
+ q->pg_chunk.page = alloc_pages(gfp, order);
if (unlikely(!q->pg_chunk.page))
return -ENOMEM;
q->pg_chunk.va = page_address(q->pg_chunk.page);
@@ -404,7 +412,7 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp)
sd->pg_chunk = q->pg_chunk;
q->pg_chunk.offset += q->buf_size;
- if (q->pg_chunk.offset == PAGE_SIZE)
+ if (q->pg_chunk.offset == (PAGE_SIZE << order))
q->pg_chunk.page = NULL;
else {
q->pg_chunk.va += q->buf_size;
@@ -424,15 +432,18 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp)
* allocated with the supplied gfp flags. The caller must assure that
* @n does not exceed the queue's capacity.
*/
-static void refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
+static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
{
void *buf_start;
struct rx_sw_desc *sd = &q->sdesc[q->pidx];
struct rx_desc *d = &q->desc[q->pidx];
+ unsigned int count = 0;
while (n--) {
+ int err;
+
if (q->use_pages) {
- if (unlikely(alloc_pg_chunk(q, sd, gfp))) {
+ if (unlikely(alloc_pg_chunk(q, sd, gfp, q->order))) {
nomem: q->alloc_failed++;
break;
}
@@ -447,8 +458,16 @@ nomem: q->alloc_failed++;
buf_start = skb->data;
}
- add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
- adap->pdev);
+ err = add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
+ adap->pdev);
+ if (unlikely(err)) {
+ if (!q->use_pages) {
+ kfree_skb(sd->skb);
+ sd->skb = NULL;
+ }
+ break;
+ }
+
d++;
sd++;
if (++q->pidx == q->size) {
@@ -458,14 +477,19 @@ nomem: q->alloc_failed++;
d = q->desc;
}
q->credits++;
+ count++;
}
wmb();
- t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+ if (likely(count))
+ t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+ return count;
}
static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{
- refill_fl(adap, fl, min(16U, fl->size - fl->credits), GFP_ATOMIC);
+ refill_fl(adap, fl, min(16U, fl->size - fl->credits),
+ GFP_ATOMIC | __GFP_COMP);
}
/**
@@ -560,6 +584,8 @@ static void t3_reset_qset(struct sge_qset *q)
memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
q->txq_stopped = 0;
memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer));
+ kfree(q->lro_frag_tbl);
+ q->lro_nfrags = q->lro_frag_len = 0;
}
@@ -740,19 +766,22 @@ use_orig_buf:
* that are page chunks rather than sk_buffs.
*/
static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl,
- unsigned int len, unsigned int drop_thres)
+ struct sge_rspq *q, unsigned int len,
+ unsigned int drop_thres)
{
- struct sk_buff *skb = NULL;
+ struct sk_buff *newskb, *skb;
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
- if (len <= SGE_RX_COPY_THRES) {
- skb = alloc_skb(len, GFP_ATOMIC);
- if (likely(skb != NULL)) {
- __skb_put(skb, len);
+ newskb = skb = q->pg_skb;
+
+ if (!skb && (len <= SGE_RX_COPY_THRES)) {
+ newskb = alloc_skb(len, GFP_ATOMIC);
+ if (likely(newskb != NULL)) {
+ __skb_put(newskb, len);
pci_dma_sync_single_for_cpu(adap->pdev,
pci_unmap_addr(sd, dma_addr), len,
PCI_DMA_FROMDEVICE);
- memcpy(skb->data, sd->pg_chunk.va, len);
+ memcpy(newskb->data, sd->pg_chunk.va, len);
pci_dma_sync_single_for_device(adap->pdev,
pci_unmap_addr(sd, dma_addr), len,
PCI_DMA_FROMDEVICE);
@@ -761,14 +790,16 @@ static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl,
recycle:
fl->credits--;
recycle_rx_buf(adap, fl, fl->cidx);
- return skb;
+ q->rx_recycle_buf++;
+ return newskb;
}
- if (unlikely(fl->credits <= drop_thres))
+ if (unlikely(q->rx_recycle_buf || (!skb && fl->credits <= drop_thres)))
goto recycle;
- skb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
- if (unlikely(!skb)) {
+ if (!skb)
+ newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
+ if (unlikely(!newskb)) {
if (!drop_thres)
return NULL;
goto recycle;
@@ -776,21 +807,29 @@ recycle:
pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
fl->buf_size, PCI_DMA_FROMDEVICE);
- __skb_put(skb, SGE_RX_PULL_LEN);
- memcpy(skb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
- skb_fill_page_desc(skb, 0, sd->pg_chunk.page,
- sd->pg_chunk.offset + SGE_RX_PULL_LEN,
- len - SGE_RX_PULL_LEN);
- skb->len = len;
- skb->data_len = len - SGE_RX_PULL_LEN;
- skb->truesize += skb->data_len;
+ if (!skb) {
+ __skb_put(newskb, SGE_RX_PULL_LEN);
+ memcpy(newskb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
+ skb_fill_page_desc(newskb, 0, sd->pg_chunk.page,
+ sd->pg_chunk.offset + SGE_RX_PULL_LEN,
+ len - SGE_RX_PULL_LEN);
+ newskb->len = len;
+ newskb->data_len = len - SGE_RX_PULL_LEN;
+ } else {
+ skb_fill_page_desc(newskb, skb_shinfo(newskb)->nr_frags,
+ sd->pg_chunk.page,
+ sd->pg_chunk.offset, len);
+ newskb->len += len;
+ newskb->data_len += len;
+ }
+ newskb->truesize += newskb->data_len;
fl->credits--;
/*
* We do not refill FLs here, we let the caller do it to overlap a
* prefetch.
*/
- return skb;
+ return newskb;
}
/**
@@ -1831,9 +1870,10 @@ static void restart_tx(struct sge_qset *qs)
* if it was immediate data in a response.
*/
static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
- struct sk_buff *skb, int pad)
+ struct sk_buff *skb, int pad, int lro)
{
struct cpl_rx_pkt *p = (struct cpl_rx_pkt *)(skb->data + pad);
+ struct sge_qset *qs = rspq_to_qset(rq);
struct port_info *pi;
skb_pull(skb, sizeof(*p) + pad);
@@ -1850,18 +1890,202 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
if (unlikely(p->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;
- rspq_to_qset(rq)->port_stats[SGE_PSTAT_VLANEX]++;
+ qs->port_stats[SGE_PSTAT_VLANEX]++;
if (likely(grp))
- __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
- rq->polling);
+ if (lro)
+ lro_vlan_hwaccel_receive_skb(&qs->lro_mgr, skb,
+ grp,
+ ntohs(p->vlan),
+ p);
+ else
+ __vlan_hwaccel_rx(skb, grp, ntohs(p->vlan),
+ rq->polling);
else
dev_kfree_skb_any(skb);
- } else if (rq->polling)
- netif_receive_skb(skb);
- else
+ } else if (rq->polling) {
+ if (lro)
+ lro_receive_skb(&qs->lro_mgr, skb, p);
+ else
+ netif_receive_skb(skb);
+ } else
netif_rx(skb);
}
+static inline int is_eth_tcp(u32 rss)
+{
+ return G_HASHTYPE(ntohl(rss)) == RSS_HASH_4_TUPLE;
+}
+
+/**
+ * lro_frame_ok - check if an ingress packet is eligible for LRO
+ * @p: the CPL header of the packet
+ *
+ * Returns true if a received packet is eligible for LRO.
+ * The following conditions must be true:
+ * - packet is TCP/IP Ethernet II (checked elsewhere)
+ * - not an IP fragment
+ * - no IP options
+ * - TCP/IP checksums are correct
+ * - the packet is for this host
+ */
+static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
+{
+ const struct ethhdr *eh = (struct ethhdr *)(p + 1);
+ const struct iphdr *ih = (struct iphdr *)(eh + 1);
+
+ return (*((u8 *)p + 1) & 0x90) == 0x10 && p->csum == htons(0xffff) &&
+ eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
+}
+
+#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
+ TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
+ TCP_FLAG_SYN | TCP_FLAG_FIN)
+#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
+
+/**
+ * lro_segment_ok - check if a TCP segment is eligible for LRO
+ * @tcph: the TCP header of the packet
+ *
+ * Returns true if a TCP packet is eligible for LRO. This requires that
+ * the packet have only the ACK flag set and no TCP options besides
+ * time stamps.
+ */
+static inline int lro_segment_ok(const struct tcphdr *tcph)
+{
+ int optlen;
+
+ if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
+ return 0;
+
+ optlen = (tcph->doff << 2) - sizeof(*tcph);
+ if (optlen) {
+ const u32 *opt = (const u32 *)(tcph + 1);
+
+ if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
+ *opt != htonl(TSTAMP_WORD) || !opt[2])
+ return 0;
+ }
+ return 1;
+}
+
+static int t3_get_lro_header(void **eh, void **iph, void **tcph,
+ u64 *hdr_flags, void *priv)
+{
+ const struct cpl_rx_pkt *cpl = priv;
+
+ if (!lro_frame_ok(cpl))
+ return -1;
+
+ *eh = (struct ethhdr *)(cpl + 1);
+ *iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
+ *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
+
+ if (!lro_segment_ok(*tcph))
+ return -1;
+
+ *hdr_flags = LRO_IPV4 | LRO_TCP;
+ return 0;
+}
+
+static int t3_get_skb_header(struct sk_buff *skb,
+ void **iph, void **tcph, u64 *hdr_flags,
+ void *priv)
+{
+ void *eh;
+
+ return t3_get_lro_header(&eh, iph, tcph, hdr_flags, priv);
+}
+
+static int t3_get_frag_header(struct skb_frag_struct *frag, void **eh,
+ void **iph, void **tcph, u64 *hdr_flags,
+ void *priv)
+{
+ return t3_get_lro_header(eh, iph, tcph, hdr_flags, priv);
+}
+
+/**
+ * lro_add_page - add a page chunk to an LRO session
+ * @adap: the adapter
+ * @qs: the associated queue set
+ * @fl: the free list containing the page chunk to add
+ * @len: packet length
+ * @complete: Indicates the last fragment of a frame
+ *
+ * Add a received packet contained in a page chunk to an existing LRO
+ * session.
+ */
+static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
+ struct sge_fl *fl, int len, int complete)
+{
+ struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+ struct cpl_rx_pkt *cpl;
+ struct skb_frag_struct *rx_frag = qs->lro_frag_tbl;
+ int nr_frags = qs->lro_nfrags, frag_len = qs->lro_frag_len;
+ int offset = 0;
+
+ if (!nr_frags) {
+ offset = 2 + sizeof(struct cpl_rx_pkt);
+ qs->lro_va = cpl = sd->pg_chunk.va + 2;
+ }
+
+ fl->credits--;
+
+ len -= offset;
+ pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
+ fl->buf_size, PCI_DMA_FROMDEVICE);
+
+ rx_frag += nr_frags;
+ rx_frag->page = sd->pg_chunk.page;
+ rx_frag->page_offset = sd->pg_chunk.offset + offset;
+ rx_frag->size = len;
+ frag_len += len;
+ qs->lro_nfrags++;
+ qs->lro_frag_len = frag_len;
+
+ if (!complete)
+ return;
+
+ qs->lro_nfrags = qs->lro_frag_len = 0;
+ cpl = qs->lro_va;
+
+ if (unlikely(cpl->vlan_valid)) {
+ struct net_device *dev = qs->netdev;
+ struct port_info *pi = netdev_priv(dev);
+ struct vlan_group *grp = pi->vlan_grp;
+
+ if (likely(grp != NULL)) {
+ lro_vlan_hwaccel_receive_frags(&qs->lro_mgr,
+ qs->lro_frag_tbl,
+ frag_len, frag_len,
+ grp, ntohs(cpl->vlan),
+ cpl, 0);
+ return;
+ }
+ }
+ lro_receive_frags(&qs->lro_mgr, qs->lro_frag_tbl,
+ frag_len, frag_len, cpl, 0);
+}
+
+/**
+ * init_lro_mgr - initialize a LRO manager object
+ * @lro_mgr: the LRO manager object
+ */
+static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
+{
+ lro_mgr->dev = qs->netdev;
+ lro_mgr->features = LRO_F_NAPI;
+ lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
+ lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ lro_mgr->max_desc = T3_MAX_LRO_SES;
+ lro_mgr->lro_arr = qs->lro_desc;
+ lro_mgr->get_frag_header = t3_get_frag_header;
+ lro_mgr->get_skb_header = t3_get_skb_header;
+ lro_mgr->max_aggr = T3_MAX_LRO_MAX_PKTS;
+ if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
+ lro_mgr->max_aggr = MAX_SKB_FRAGS;
+}
+
/**
* handle_rsp_cntrl_info - handles control information in a response
* @qs: the queue set corresponding to the response
@@ -1947,6 +2171,12 @@ static inline int is_new_response(const struct rsp_desc *r,
return (r->intr_gen & F_RSPD_GEN2) == q->gen;
}
+static inline void clear_rspq_bufstate(struct sge_rspq * const q)
+{
+ q->pg_skb = NULL;
+ q->rx_recycle_buf = 0;
+}
+
#define RSPD_GTS_MASK (F_RSPD_TXQ0_GTS | F_RSPD_TXQ1_GTS)
#define RSPD_CTRL_MASK (RSPD_GTS_MASK | \
V_RSPD_TXQ0_CR(M_RSPD_TXQ0_CR) | \
@@ -1984,10 +2214,11 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
q->next_holdoff = q->holdoff_tmr;
while (likely(budget_left && is_new_response(r, q))) {
- int eth, ethpad = 2;
+ int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
struct sk_buff *skb = NULL;
u32 len, flags = ntohl(r->flags);
- __be32 rss_hi = *(const __be32 *)r, rss_lo = r->rss_hdr.rss_hash_val;
+ __be32 rss_hi = *(const __be32 *)r,
+ rss_lo = r->rss_hdr.rss_hash_val;
eth = r->rss_hdr.opcode == CPL_RX_PKT;
@@ -2015,6 +2246,9 @@ no_mem:
} else if ((len = ntohl(r->len_cq)) != 0) {
struct sge_fl *fl;
+ if (eth)
+ lro = qs->lro_enabled && is_eth_tcp(rss_hi);
+
fl = (len & F_RSPD_FLQ) ? &qs->fl[1] : &qs->fl[0];
if (fl->use_pages) {
void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
@@ -2024,9 +2258,18 @@ no_mem:
prefetch(addr + L1_CACHE_BYTES);
#endif
__refill_fl(adap, fl);
+ if (lro > 0) {
+ lro_add_page(adap, qs, fl,
+ G_RSPD_LEN(len),
+ flags & F_RSPD_EOP);
+ goto next_fl;
+ }
- skb = get_packet_pg(adap, fl, G_RSPD_LEN(len),
- eth ? SGE_RX_DROP_THRES : 0);
+ skb = get_packet_pg(adap, fl, q,
+ G_RSPD_LEN(len),
+ eth ?
+ SGE_RX_DROP_THRES : 0);
+ q->pg_skb = skb;
} else
skb = get_packet(adap, fl, G_RSPD_LEN(len),
eth ? SGE_RX_DROP_THRES : 0);
@@ -2036,7 +2279,7 @@ no_mem:
q->rx_drops++;
} else if (unlikely(r->rss_hdr.opcode == CPL_TRACE_PKT))
__skb_pull(skb, 2);
-
+next_fl:
if (++fl->cidx == fl->size)
fl->cidx = 0;
} else
@@ -2060,9 +2303,13 @@ no_mem:
q->credits = 0;
}
- if (likely(skb != NULL)) {
+ packet_complete = flags &
+ (F_RSPD_EOP | F_RSPD_IMM_DATA_VALID |
+ F_RSPD_ASYNC_NOTIF);
+
+ if (skb != NULL && packet_complete) {
if (eth)
- rx_eth(adap, q, skb, ethpad);
+ rx_eth(adap, q, skb, ethpad, lro);
else {
q->offload_pkts++;
/* Preserve the RSS info in csum & priority */
@@ -2072,11 +2319,19 @@ no_mem:
offload_skbs,
ngathered);
}
+
+ if (flags & F_RSPD_EOP)
+ clear_rspq_bufstate(q);
}
--budget_left;
}
deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);
+ lro_flush_all(&qs->lro_mgr);
+ qs->port_stats[SGE_PSTAT_LRO_AGGR] = qs->lro_mgr.stats.aggregated;
+ qs->port_stats[SGE_PSTAT_LRO_FLUSHED] = qs->lro_mgr.stats.flushed;
+ qs->port_stats[SGE_PSTAT_LRO_NO_DESC] = qs->lro_mgr.stats.no_desc;
+
if (sleeping)
check_ring_db(adap, qs, sleeping);
@@ -2618,8 +2873,9 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
int irq_vec_idx, const struct qset_params *p,
int ntxq, struct net_device *dev)
{
- int i, ret = -ENOMEM;
+ int i, avail, ret = -ENOMEM;
struct sge_qset *q = &adapter->sge.qs[id];
+ struct net_lro_mgr *lro_mgr = &q->lro_mgr;
init_qset_cntxt(q, id);
init_timer(&q->tx_reclaim_timer);
@@ -2687,11 +2943,23 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
#else
q->fl[0].buf_size = SGE_RX_SM_BUF_SIZE + sizeof(struct cpl_rx_data);
#endif
- q->fl[0].use_pages = FL0_PG_CHUNK_SIZE > 0;
+#if FL1_PG_CHUNK_SIZE > 0
+ q->fl[1].buf_size = FL1_PG_CHUNK_SIZE;
+#else
q->fl[1].buf_size = is_offload(adapter) ?
(16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt);
+#endif
+ q->fl[0].use_pages = FL0_PG_CHUNK_SIZE > 0;
+ q->fl[1].use_pages = FL1_PG_CHUNK_SIZE > 0;
+ q->fl[0].order = FL0_PG_ORDER;
+ q->fl[1].order = FL1_PG_ORDER;
+
+ q->lro_frag_tbl = kcalloc(MAX_FRAME_SIZE / FL1_PG_CHUNK_SIZE + 1,
+ sizeof(struct skb_frag_struct),
+ GFP_KERNEL);
+ q->lro_nfrags = q->lro_frag_len = 0;
spin_lock_irq(&adapter->sge.reg_lock);
/* FL threshold comparison uses < */
@@ -2742,8 +3010,23 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
q->netdev = dev;
t3_update_qset_coalesce(q, p);
- refill_fl(adapter, &q->fl[0], q->fl[0].size, GFP_KERNEL);
- refill_fl(adapter, &q->fl[1], q->fl[1].size, GFP_KERNEL);
+ init_lro_mgr(q, lro_mgr);
+
+ avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
+ GFP_KERNEL | __GFP_COMP);
+ if (!avail) {
+ CH_ALERT(adapter, "free list queue 0 initialization failed\n");
+ goto err;
+ }
+ if (avail < q->fl[0].size)
+ CH_WARN(adapter, "free list queue 0 enabled with %d credits\n",
+ avail);
+
+ avail = refill_fl(adapter, &q->fl[1], q->fl[1].size,
+ GFP_KERNEL | __GFP_COMP);
+ if (avail < q->fl[1].size)
+ CH_WARN(adapter, "free list queue 1 enabled with %d credits\n",
+ avail);
refill_rspq(adapter, &q->rspq, q->rspq.size - 1);
t3_write_reg(adapter, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) |
@@ -2752,9 +3035,9 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
return 0;
- err_unlock:
+err_unlock:
spin_unlock_irq(&adapter->sge.reg_lock);
- err:
+err:
t3_free_qset(adapter, q);
return ret;
}
@@ -2876,7 +3159,7 @@ void t3_sge_prep(struct adapter *adap, struct sge_params *p)
q->coalesce_usecs = 5;
q->rspq_size = 1024;
q->fl_size = 1024;
- q->jumbo_size = 512;
+ q->jumbo_size = 512;
q->txq_size[TXQ_ETH] = 1024;
q->txq_size[TXQ_OFLD] = 1024;
q->txq_size[TXQ_CTRL] = 256;
diff --git a/drivers/net/cxgb3/t3_cpl.h b/drivers/net/cxgb3/t3_cpl.h
index b7a1a310dfd..917970ed24a 100644
--- a/drivers/net/cxgb3/t3_cpl.h
+++ b/drivers/net/cxgb3/t3_cpl.h
@@ -174,6 +174,13 @@ enum { /* TCP congestion control algorithms */
CONG_ALG_HIGHSPEED
};
+enum { /* RSS hash type */
+ RSS_HASH_NONE = 0,
+ RSS_HASH_2_TUPLE = 1,
+ RSS_HASH_4_TUPLE = 2,
+ RSS_HASH_TCPV6 = 3
+};
+
union opcode_tid {
__be32 opcode_tid;
__u8 opcode;
@@ -184,6 +191,13 @@ union opcode_tid {
#define G_OPCODE(x) (((x) >> S_OPCODE) & 0xFF)
#define G_TID(x) ((x) & 0xFFFFFF)
+#define S_QNUM 0
+#define G_QNUM(x) (((x) >> S_QNUM) & 0xFFFF)
+
+#define S_HASHTYPE 22
+#define M_HASHTYPE 0x3
+#define G_HASHTYPE(x) (((x) >> S_HASHTYPE) & M_HASHTYPE)
+
/* tid is assumed to be 24-bits */
#define MK_OPCODE_TID(opcode, tid) (V_OPCODE(opcode) | (tid))
@@ -768,6 +782,12 @@ struct tx_data_wr {
__be32 param;
};
+/* tx_data_wr.flags fields */
+#define S_TX_ACK_PAGES 21
+#define M_TX_ACK_PAGES 0x7
+#define V_TX_ACK_PAGES(x) ((x) << S_TX_ACK_PAGES)
+#define G_TX_ACK_PAGES(x) (((x) >> S_TX_ACK_PAGES) & M_TX_ACK_PAGES)
+
/* tx_data_wr.param fields */
#define S_TX_PORT 0
#define M_TX_PORT 0x7
@@ -1441,4 +1461,35 @@ struct cpl_rdma_terminate {
#define M_TERM_TID 0xFFFFF
#define V_TERM_TID(x) ((x) << S_TERM_TID)
#define G_TERM_TID(x) (((x) >> S_TERM_TID) & M_TERM_TID)
+
+/* ULP_TX opcodes */
+enum { ULP_MEM_READ = 2, ULP_MEM_WRITE = 3, ULP_TXPKT = 4 };
+
+#define S_ULPTX_CMD 28
+#define M_ULPTX_CMD 0xF
+#define V_ULPTX_CMD(x) ((x) << S_ULPTX_CMD)
+
+#define S_ULPTX_NFLITS 0
+#define M_ULPTX_NFLITS 0xFF
+#define V_ULPTX_NFLITS(x) ((x) << S_ULPTX_NFLITS)
+
+struct ulp_mem_io {
+ WR_HDR;
+ __be32 cmd_lock_addr;
+ __be32 len;
+};
+
+/* ulp_mem_io.cmd_lock_addr fields */
+#define S_ULP_MEMIO_ADDR 0
+#define M_ULP_MEMIO_ADDR 0x7FFFFFF
+#define V_ULP_MEMIO_ADDR(x) ((x) << S_ULP_MEMIO_ADDR)
+#define S_ULP_MEMIO_LOCK 27
+#define V_ULP_MEMIO_LOCK(x) ((x) << S_ULP_MEMIO_LOCK)
+#define F_ULP_MEMIO_LOCK V_ULP_MEMIO_LOCK(1U)
+
+/* ulp_mem_io.len fields */
+#define S_ULP_MEMIO_DATA_LEN 28
+#define M_ULP_MEMIO_DATA_LEN 0xF
+#define V_ULP_MEMIO_DATA_LEN(x) ((x) << S_ULP_MEMIO_DATA_LEN)
+
#endif /* T3_CPL_H */
diff --git a/drivers/net/cxgb3/t3cdev.h b/drivers/net/cxgb3/t3cdev.h
index a18c8a14042..0a21cfbd2b2 100644
--- a/drivers/net/cxgb3/t3cdev.h
+++ b/drivers/net/cxgb3/t3cdev.h
@@ -45,7 +45,8 @@ struct cxgb3_client;
enum t3ctype {
T3A = 0,
- T3B
+ T3B,
+ T3C,
};
struct t3cdev {
@@ -63,6 +64,7 @@ struct t3cdev {
void *l3opt; /* optional layer 3 data */
void *l4opt; /* optional layer 4 data */
void *ulp; /* ulp stuff */
+ void *ulp_iscsi; /* ulp iscsi */
};
#endif /* _T3CDEV_H_ */
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 6b1e77cc069..3e3506411ac 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -773,8 +773,6 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-struct net_device *last_dev = 0;
-
static int lance_open(struct net_device *dev)
{
volatile u16 *ib = (volatile u16 *)dev->mem_start;
@@ -782,8 +780,6 @@ static int lance_open(struct net_device *dev)
volatile struct lance_regs *ll = lp->ll;
int status = 0;
- last_dev = dev;
-
/* Stop the Lance */
writereg(&ll->rap, LE_CSR0);
writereg(&ll->rdp, LE_C0_STOP);
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index e233d04a213..f8037110a52 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -499,7 +499,7 @@ rio_timer (unsigned long data)
entry = np->old_rx % RX_RING_SIZE;
/* Dropped packets don't need to re-allocate */
if (np->rx_skbuff[entry] == NULL) {
- skb = dev_alloc_skb (np->rx_buf_sz);
+ skb = netdev_alloc_skb (dev, np->rx_buf_sz);
if (skb == NULL) {
np->rx_ring[entry].fraginfo = 0;
printk (KERN_INFO
@@ -570,7 +570,7 @@ alloc_list (struct net_device *dev)
/* Allocate the rx buffers */
for (i = 0; i < RX_RING_SIZE; i++) {
/* Allocated fixed size of skbuff */
- struct sk_buff *skb = dev_alloc_skb (np->rx_buf_sz);
+ struct sk_buff *skb = netdev_alloc_skb (dev, np->rx_buf_sz);
np->rx_skbuff[i] = skb;
if (skb == NULL) {
printk (KERN_ERR
@@ -867,7 +867,7 @@ receive_packet (struct net_device *dev)
PCI_DMA_FROMDEVICE);
skb_put (skb = np->rx_skbuff[entry], pkt_len);
np->rx_skbuff[entry] = NULL;
- } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) {
+ } else if ((skb = netdev_alloc_skb(dev, pkt_len + 2))) {
pci_dma_sync_single_for_cpu(np->pdev,
desc_to_dma(desc),
np->rx_buf_sz,
@@ -904,7 +904,7 @@ receive_packet (struct net_device *dev)
struct sk_buff *skb;
/* Dropped packets don't need to re-allocate */
if (np->rx_skbuff[entry] == NULL) {
- skb = dev_alloc_skb (np->rx_buf_sz);
+ skb = netdev_alloc_skb(dev, np->rx_buf_sz);
if (skb == NULL) {
np->rx_ring[entry].fraginfo = 0;
printk (KERN_INFO
@@ -1753,7 +1753,7 @@ rio_close (struct net_device *dev)
/* Stop Tx and Rx logics */
writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
- synchronize_irq (dev->irq);
+
free_irq (dev->irq, dev);
del_timer_sync (&np->timer);
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 864295e081b..952e10d686e 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -44,9 +44,8 @@
#define DM9000_PHY 0x40 /* PHY address 0x01 */
-#define CARDNAME "dm9000"
-#define PFX CARDNAME ": "
-#define DRV_VERSION "1.30"
+#define CARDNAME "dm9000"
+#define DRV_VERSION "1.31"
#ifdef CONFIG_BLACKFIN
#define readsb insb
@@ -55,9 +54,6 @@
#define writesb outsb
#define writesw outsw
#define writesl outsl
-#define DEFAULT_TRIGGER IRQF_TRIGGER_HIGH
-#else
-#define DEFAULT_TRIGGER (0)
#endif
/*
@@ -85,23 +81,36 @@ MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
* these two devices.
*/
+/* The driver supports the original DM9000E, and now the two newer
+ * devices, DM9000A and DM9000B.
+ */
+
+enum dm9000_type {
+ TYPE_DM9000E, /* original DM9000 */
+ TYPE_DM9000A,
+ TYPE_DM9000B
+};
+
/* Structure/enum declaration ------------------------------- */
typedef struct board_info {
- void __iomem *io_addr; /* Register I/O base address */
- void __iomem *io_data; /* Data I/O address */
- u16 irq; /* IRQ */
+ void __iomem *io_addr; /* Register I/O base address */
+ void __iomem *io_data; /* Data I/O address */
+ u16 irq; /* IRQ */
- u16 tx_pkt_cnt;
- u16 queue_pkt_len;
- u16 queue_start_addr;
- u16 dbug_cnt;
- u8 io_mode; /* 0:word, 2:byte */
- u8 phy_addr;
- unsigned int flags;
- unsigned int in_suspend :1;
+ u16 tx_pkt_cnt;
+ u16 queue_pkt_len;
+ u16 queue_start_addr;
+ u16 dbug_cnt;
+ u8 io_mode; /* 0:word, 2:byte */
+ u8 phy_addr;
+ u8 imr_all;
- int debug_level;
+ unsigned int flags;
+ unsigned int in_suspend :1;
+ int debug_level;
+
+ enum dm9000_type type;
void (*inblk)(void __iomem *port, void *data, int length);
void (*outblk)(void __iomem *port, void *data, int length);
@@ -120,10 +129,10 @@ typedef struct board_info {
struct delayed_work phy_poll;
struct net_device *ndev;
- spinlock_t lock;
+ spinlock_t lock;
struct mii_if_info mii;
- u32 msg_enable;
+ u32 msg_enable;
} board_info_t;
/* debug code */
@@ -140,26 +149,6 @@ static inline board_info_t *to_dm9000_board(struct net_device *dev)
return dev->priv;
}
-/* function declaration ------------------------------------- */
-static int dm9000_probe(struct platform_device *);
-static int dm9000_open(struct net_device *);
-static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
-static int dm9000_stop(struct net_device *);
-static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd);
-
-static void dm9000_init_dm9000(struct net_device *);
-
-static irqreturn_t dm9000_interrupt(int, void *);
-
-static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
-static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
- int value);
-
-static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
-static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
-static void dm9000_rx(struct net_device *);
-static void dm9000_hash_table(struct net_device *);
-
/* DM9000 network board routine ---------------------------- */
static void
@@ -302,52 +291,135 @@ static void dm9000_set_io(struct board_info *db, int byte_width)
static void dm9000_schedule_poll(board_info_t *db)
{
- schedule_delayed_work(&db->phy_poll, HZ * 2);
+ if (db->type == TYPE_DM9000E)
+ schedule_delayed_work(&db->phy_poll, HZ * 2);
}
-/* Our watchdog timed out. Called by the networking layer */
-static void dm9000_timeout(struct net_device *dev)
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ board_info_t *dm = to_dm9000_board(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+}
+
+static unsigned int
+dm9000_read_locked(board_info_t *db, int reg)
{
- board_info_t *db = (board_info_t *) dev->priv;
- u8 reg_save;
unsigned long flags;
+ unsigned int ret;
- /* Save previous register address */
- reg_save = readb(db->io_addr);
- spin_lock_irqsave(&db->lock,flags);
+ spin_lock_irqsave(&db->lock, flags);
+ ret = ior(db, reg);
+ spin_unlock_irqrestore(&db->lock, flags);
- netif_stop_queue(dev);
- dm9000_reset(db);
- dm9000_init_dm9000(dev);
- /* We can accept TX packets again */
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
+ return ret;
+}
- /* Restore previous register address */
- writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock,flags);
+static int dm9000_wait_eeprom(board_info_t *db)
+{
+ unsigned int status;
+ int timeout = 8; /* wait max 8msec */
+
+ /* The DM9000 data sheets say we should be able to
+ * poll the ERRE bit in EPCR to wait for the EEPROM
+ * operation. From testing several chips, this bit
+ * does not seem to work.
+ *
+ * We attempt to use the bit, but fall back to the
+ * timeout (which is why we do not return an error
+ * on expiry) to say that the EEPROM operation has
+ * completed.
+ */
+
+ while (1) {
+ status = dm9000_read_locked(db, DM9000_EPCR);
+
+ if ((status & EPCR_ERRE) == 0)
+ break;
+
+ msleep(1);
+
+ if (timeout-- < 0) {
+ dev_dbg(db->dev, "timeout waiting EEPROM\n");
+ break;
+ }
+ }
+
+ return 0;
}
-#ifdef CONFIG_NET_POLL_CONTROLLER
/*
- *Used by netconsole
+ * Read a word data from EEPROM
*/
-static void dm9000_poll_controller(struct net_device *dev)
+static void
+dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
{
- disable_irq(dev->irq);
- dm9000_interrupt(dev->irq,dev);
- enable_irq(dev->irq);
+ unsigned long flags;
+
+ if (db->flags & DM9000_PLATF_NO_EEPROM) {
+ to[0] = 0xff;
+ to[1] = 0xff;
+ return;
+ }
+
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ iow(db, DM9000_EPAR, offset);
+ iow(db, DM9000_EPCR, EPCR_ERPRR);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_wait_eeprom(db);
+
+ /* delay for at-least 150uS */
+ msleep(1);
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ iow(db, DM9000_EPCR, 0x0);
+
+ to[0] = ior(db, DM9000_EPDRL);
+ to[1] = ior(db, DM9000_EPDRH);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ mutex_unlock(&db->addr_lock);
}
-#endif
-static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+/*
+ * Write a word data to SROM
+ */
+static void
+dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
{
- board_info_t *dm = to_dm9000_board(dev);
+ unsigned long flags;
- if (!netif_running(dev))
- return -EINVAL;
+ if (db->flags & DM9000_PLATF_NO_EEPROM)
+ return;
- return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+ mutex_lock(&db->addr_lock);
+
+ spin_lock_irqsave(&db->lock, flags);
+ iow(db, DM9000_EPAR, offset);
+ iow(db, DM9000_EPDRH, data[1]);
+ iow(db, DM9000_EPDRL, data[0]);
+ iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ dm9000_wait_eeprom(db);
+
+ mdelay(1); /* wait at least 150uS to clear */
+
+ spin_lock_irqsave(&db->lock, flags);
+ iow(db, DM9000_EPCR, 0);
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ mutex_unlock(&db->addr_lock);
}
/* ethtool ops */
@@ -400,7 +472,14 @@ static int dm9000_nway_reset(struct net_device *dev)
static u32 dm9000_get_link(struct net_device *dev)
{
board_info_t *dm = to_dm9000_board(dev);
- return mii_link_ok(&dm->mii);
+ u32 ret;
+
+ if (dm->flags & DM9000_PLATF_EXT_PHY)
+ ret = mii_link_ok(&dm->mii);
+ else
+ ret = dm9000_read_locked(dm, DM9000_NSR) & NSR_LINKST ? 1 : 0;
+
+ return ret;
}
#define DM_EEPROM_MAGIC (0x444D394B)
@@ -472,15 +551,48 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
.set_eeprom = dm9000_set_eeprom,
};
+static void dm9000_show_carrier(board_info_t *db,
+ unsigned carrier, unsigned nsr)
+{
+ struct net_device *ndev = db->ndev;
+ unsigned ncr = dm9000_read_locked(db, DM9000_NCR);
+
+ if (carrier)
+ dev_info(db->dev, "%s: link up, %dMbps, %s-duplex, no LPA\n",
+ ndev->name, (nsr & NSR_SPEED) ? 10 : 100,
+ (ncr & NCR_FDX) ? "full" : "half");
+ else
+ dev_info(db->dev, "%s: link down\n", ndev->name);
+}
+
static void
dm9000_poll_work(struct work_struct *w)
{
struct delayed_work *dw = container_of(w, struct delayed_work, work);
board_info_t *db = container_of(dw, board_info_t, phy_poll);
+ struct net_device *ndev = db->ndev;
+
+ if (db->flags & DM9000_PLATF_SIMPLE_PHY &&
+ !(db->flags & DM9000_PLATF_EXT_PHY)) {
+ unsigned nsr = dm9000_read_locked(db, DM9000_NSR);
+ unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0;
+ unsigned new_carrier;
+
+ new_carrier = (nsr & NSR_LINKST) ? 1 : 0;
- mii_check_media(&db->mii, netif_msg_link(db), 0);
+ if (old_carrier != new_carrier) {
+ if (netif_msg_link(db))
+ dm9000_show_carrier(db, new_carrier, nsr);
+
+ if (!new_carrier)
+ netif_carrier_off(ndev);
+ else
+ netif_carrier_on(ndev);
+ }
+ } else
+ mii_check_media(&db->mii, netif_msg_link(db), 0);
- if (netif_running(db->ndev))
+ if (netif_running(ndev))
dm9000_schedule_poll(db);
}
@@ -492,12 +604,6 @@ dm9000_poll_work(struct work_struct *w)
static void
dm9000_release_board(struct platform_device *pdev, struct board_info *db)
{
- if (db->data_res == NULL) {
- if (db->addr_res != NULL)
- release_mem_region((unsigned long)db->io_addr, 4);
- return;
- }
-
/* unmap our resources */
iounmap(db->io_addr);
@@ -505,288 +611,73 @@ dm9000_release_board(struct platform_device *pdev, struct board_info *db)
/* release the resources */
- if (db->data_req != NULL) {
- release_resource(db->data_req);
- kfree(db->data_req);
- }
+ release_resource(db->data_req);
+ kfree(db->data_req);
- if (db->addr_req != NULL) {
- release_resource(db->addr_req);
- kfree(db->addr_req);
- }
+ release_resource(db->addr_req);
+ kfree(db->addr_req);
}
-#define res_size(_r) (((_r)->end - (_r)->start) + 1)
-
-/*
- * Search DM9000 board, allocate space and register it
- */
-static int __devinit
-dm9000_probe(struct platform_device *pdev)
+static unsigned char dm9000_type_to_char(enum dm9000_type type)
{
- struct dm9000_plat_data *pdata = pdev->dev.platform_data;
- struct board_info *db; /* Point a board information structure */
- struct net_device *ndev;
- const unsigned char *mac_src;
- unsigned long base;
- int ret = 0;
- int iosize;
- int i;
- u32 id_val;
-
- /* Init network device */
- ndev = alloc_etherdev(sizeof (struct board_info));
- if (!ndev) {
- dev_err(&pdev->dev, "could not allocate device.\n");
- return -ENOMEM;
- }
-
- SET_NETDEV_DEV(ndev, &pdev->dev);
-
- dev_dbg(&pdev->dev, "dm9000_probe()\n");
-
- /* setup board info structure */
- db = (struct board_info *) ndev->priv;
- memset(db, 0, sizeof (*db));
-
- db->dev = &pdev->dev;
- db->ndev = ndev;
-
- spin_lock_init(&db->lock);
- mutex_init(&db->addr_lock);
-
- INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
-
-
- if (pdev->num_resources < 2) {
- ret = -ENODEV;
- goto out;
- } else if (pdev->num_resources == 2) {
- base = pdev->resource[0].start;
-
- if (!request_mem_region(base, 4, ndev->name)) {
- ret = -EBUSY;
- goto out;
- }
-
- ndev->base_addr = base;
- ndev->irq = pdev->resource[1].start;
- db->io_addr = (void __iomem *)base;
- db->io_data = (void __iomem *)(base + 4);
-
- /* ensure at least we have a default set of IO routines */
- dm9000_set_io(db, 2);
-
- } else {
- db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-
- if (db->addr_res == NULL || db->data_res == NULL ||
- db->irq_res == NULL) {
- dev_err(db->dev, "insufficient resources\n");
- ret = -ENOENT;
- goto out;
- }
-
- i = res_size(db->addr_res);
- db->addr_req = request_mem_region(db->addr_res->start, i,
- pdev->name);
-
- if (db->addr_req == NULL) {
- dev_err(db->dev, "cannot claim address reg area\n");
- ret = -EIO;
- goto out;
- }
-
- db->io_addr = ioremap(db->addr_res->start, i);
-
- if (db->io_addr == NULL) {
- dev_err(db->dev, "failed to ioremap address reg\n");
- ret = -EINVAL;
- goto out;
- }
-
- iosize = res_size(db->data_res);
- db->data_req = request_mem_region(db->data_res->start, iosize,
- pdev->name);
-
- if (db->data_req == NULL) {
- dev_err(db->dev, "cannot claim data reg area\n");
- ret = -EIO;
- goto out;
- }
-
- db->io_data = ioremap(db->data_res->start, iosize);
-
- if (db->io_data == NULL) {
- dev_err(db->dev,"failed to ioremap data reg\n");
- ret = -EINVAL;
- goto out;
- }
-
- /* fill in parameters for net-dev structure */
-
- ndev->base_addr = (unsigned long)db->io_addr;
- ndev->irq = db->irq_res->start;
-
- /* ensure at least we have a default set of IO routines */
- dm9000_set_io(db, iosize);
+ switch (type) {
+ case TYPE_DM9000E: return 'e';
+ case TYPE_DM9000A: return 'a';
+ case TYPE_DM9000B: return 'b';
}
- /* check to see if anything is being over-ridden */
- if (pdata != NULL) {
- /* check to see if the driver wants to over-ride the
- * default IO width */
-
- if (pdata->flags & DM9000_PLATF_8BITONLY)
- dm9000_set_io(db, 1);
-
- if (pdata->flags & DM9000_PLATF_16BITONLY)
- dm9000_set_io(db, 2);
-
- if (pdata->flags & DM9000_PLATF_32BITONLY)
- dm9000_set_io(db, 4);
-
- /* check to see if there are any IO routine
- * over-rides */
-
- if (pdata->inblk != NULL)
- db->inblk = pdata->inblk;
-
- if (pdata->outblk != NULL)
- db->outblk = pdata->outblk;
-
- if (pdata->dumpblk != NULL)
- db->dumpblk = pdata->dumpblk;
-
- db->flags = pdata->flags;
- }
-
- dm9000_reset(db);
-
- /* try two times, DM9000 sometimes gets the first read wrong */
- for (i = 0; i < 8; i++) {
- id_val = ior(db, DM9000_VIDL);
- id_val |= (u32)ior(db, DM9000_VIDH) << 8;
- id_val |= (u32)ior(db, DM9000_PIDL) << 16;
- id_val |= (u32)ior(db, DM9000_PIDH) << 24;
-
- if (id_val == DM9000_ID)
- break;
- dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
- }
-
- if (id_val != DM9000_ID) {
- dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
- ret = -ENODEV;
- goto out;
- }
-
- /* from this point we assume that we have found a DM9000 */
-
- /* driver system function */
- ether_setup(ndev);
-
- ndev->open = &dm9000_open;
- ndev->hard_start_xmit = &dm9000_start_xmit;
- ndev->tx_timeout = &dm9000_timeout;
- ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
- ndev->stop = &dm9000_stop;
- ndev->set_multicast_list = &dm9000_hash_table;
- ndev->ethtool_ops = &dm9000_ethtool_ops;
- ndev->do_ioctl = &dm9000_ioctl;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = &dm9000_poll_controller;
-#endif
-
- db->msg_enable = NETIF_MSG_LINK;
- db->mii.phy_id_mask = 0x1f;
- db->mii.reg_num_mask = 0x1f;
- db->mii.force_media = 0;
- db->mii.full_duplex = 0;
- db->mii.dev = ndev;
- db->mii.mdio_read = dm9000_phy_read;
- db->mii.mdio_write = dm9000_phy_write;
-
- mac_src = "eeprom";
-
- /* try reading the node address from the attached EEPROM */
- for (i = 0; i < 6; i += 2)
- dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
-
- if (!is_valid_ether_addr(ndev->dev_addr)) {
- /* try reading from mac */
-
- mac_src = "chip";
- for (i = 0; i < 6; i++)
- ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
- }
-
- if (!is_valid_ether_addr(ndev->dev_addr))
- dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
- "set using ifconfig\n", ndev->name);
-
- platform_set_drvdata(pdev, ndev);
- ret = register_netdev(ndev);
-
- if (ret == 0) {
- DECLARE_MAC_BUF(mac);
- printk("%s: dm9000 at %p,%p IRQ %d MAC: %s (%s)\n",
- ndev->name, db->io_addr, db->io_data, ndev->irq,
- print_mac(mac, ndev->dev_addr), mac_src);
- }
- return 0;
-
-out:
- dev_err(db->dev, "not found (%d).\n", ret);
-
- dm9000_release_board(pdev, db);
- free_netdev(ndev);
-
- return ret;
+ return '?';
}
/*
- * Open the interface.
- * The interface is opened whenever "ifconfig" actives it.
+ * Set DM9000 multicast address
*/
-static int
-dm9000_open(struct net_device *dev)
+static void
+dm9000_hash_table(struct net_device *dev)
{
board_info_t *db = (board_info_t *) dev->priv;
- unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
+ struct dev_mc_list *mcptr = dev->mc_list;
+ int mc_cnt = dev->mc_count;
+ int i, oft;
+ u32 hash_val;
+ u16 hash_table[4];
+ u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
+ unsigned long flags;
- if (netif_msg_ifup(db))
- dev_dbg(db->dev, "enabling %s\n", dev->name);
+ dm9000_dbg(db, 1, "entering %s\n", __func__);
- /* If there is no IRQ type specified, default to something that
- * may work, and tell the user that this is a problem */
+ spin_lock_irqsave(&db->lock, flags);
- if (irqflags == IRQF_TRIGGER_NONE) {
- dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
- irqflags = DEFAULT_TRIGGER;
- }
-
- irqflags |= IRQF_SHARED;
+ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
+ iow(db, oft, dev->dev_addr[i]);
- if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
- return -EAGAIN;
+ /* Clear Hash Table */
+ for (i = 0; i < 4; i++)
+ hash_table[i] = 0x0;
- /* Initialize DM9000 board */
- dm9000_reset(db);
- dm9000_init_dm9000(dev);
+ /* broadcast address */
+ hash_table[3] = 0x8000;
- /* Init driver variable */
- db->dbug_cnt = 0;
+ if (dev->flags & IFF_PROMISC)
+ rcr |= RCR_PRMSC;
- mii_check_media(&db->mii, netif_msg_link(db), 1);
- netif_start_queue(dev);
-
- dm9000_schedule_poll(db);
+ if (dev->flags & IFF_ALLMULTI)
+ rcr |= RCR_ALL;
- return 0;
+ /* the multicast address in Hash Table : 64 bits */
+ for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
+ hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
+ hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
+ }
+
+ /* Write the hash table to MAC MD table */
+ for (i = 0, oft = DM9000_MAR; i < 4; i++) {
+ iow(db, oft++, hash_table[i]);
+ iow(db, oft++, hash_table[i] >> 8);
+ }
+
+ iow(db, DM9000_RCR, rcr);
+ spin_unlock_irqrestore(&db->lock, flags);
}
/*
@@ -795,7 +686,8 @@ dm9000_open(struct net_device *dev)
static void
dm9000_init_dm9000(struct net_device *dev)
{
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
+ unsigned int imr;
dm9000_dbg(db, 1, "entering %s\n", __func__);
@@ -822,8 +714,14 @@ dm9000_init_dm9000(struct net_device *dev)
/* Set address filter table */
dm9000_hash_table(dev);
+ imr = IMR_PAR | IMR_PTM | IMR_PRM;
+ if (db->type != TYPE_DM9000E)
+ imr |= IMR_LNKCHNG;
+
+ db->imr_all = imr;
+
/* Enable TX/RX interrupt mask */
- iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+ iow(db, DM9000_IMR, imr);
/* Init Driver variable */
db->tx_pkt_cnt = 0;
@@ -831,6 +729,29 @@ dm9000_init_dm9000(struct net_device *dev)
dev->trans_start = 0;
}
+/* Our watchdog timed out. Called by the networking layer */
+static void dm9000_timeout(struct net_device *dev)
+{
+ board_info_t *db = (board_info_t *) dev->priv;
+ u8 reg_save;
+ unsigned long flags;
+
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
+ spin_lock_irqsave(&db->lock, flags);
+
+ netif_stop_queue(dev);
+ dm9000_reset(db);
+ dm9000_init_dm9000(dev);
+ /* We can accept TX packets again */
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+
+ /* Restore previous register address */
+ writeb(reg_save, db->io_addr);
+ spin_unlock_irqrestore(&db->lock, flags);
+}
+
/*
* Hardware start transmission.
* Send a packet to media from the upper layer.
@@ -839,7 +760,7 @@ static int
dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
- board_info_t *db = (board_info_t *) dev->priv;
+ board_info_t *db = dev->priv;
dm9000_dbg(db, 3, "%s:\n", __func__);
@@ -879,50 +800,12 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-static void
-dm9000_shutdown(struct net_device *dev)
-{
- board_info_t *db = (board_info_t *) dev->priv;
-
- /* RESET device */
- dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
- iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */
- iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */
- iow(db, DM9000_RCR, 0x00); /* Disable RX */
-}
-
-/*
- * Stop the interface.
- * The interface is stopped when it is brought.
- */
-static int
-dm9000_stop(struct net_device *ndev)
-{
- board_info_t *db = (board_info_t *) ndev->priv;
-
- if (netif_msg_ifdown(db))
- dev_dbg(db->dev, "shutting down %s\n", ndev->name);
-
- cancel_delayed_work_sync(&db->phy_poll);
-
- netif_stop_queue(ndev);
- netif_carrier_off(ndev);
-
- /* free interrupt */
- free_irq(ndev->irq, ndev);
-
- dm9000_shutdown(ndev);
-
- return 0;
-}
-
/*
* DM9000 interrupt handler
* receive the packet to upper layer, free the transmitted packet
*/
-static void
-dm9000_tx_done(struct net_device *dev, board_info_t * db)
+static void dm9000_tx_done(struct net_device *dev, board_info_t *db)
{
int tx_status = ior(db, DM9000_NSR); /* Got TX status */
@@ -945,52 +828,6 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db)
}
}
-static irqreturn_t
-dm9000_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- board_info_t *db = (board_info_t *) dev->priv;
- int int_status;
- u8 reg_save;
-
- dm9000_dbg(db, 3, "entering %s\n", __func__);
-
- /* A real interrupt coming */
-
- spin_lock(&db->lock);
-
- /* Save previous register address */
- reg_save = readb(db->io_addr);
-
- /* Disable all interrupts */
- iow(db, DM9000_IMR, IMR_PAR);
-
- /* Got DM9000 interrupt status */
- int_status = ior(db, DM9000_ISR); /* Got ISR */
- iow(db, DM9000_ISR, int_status); /* Clear ISR status */
-
- if (netif_msg_intr(db))
- dev_dbg(db->dev, "interrupt status %02x\n", int_status);
-
- /* Received the coming packet */
- if (int_status & ISR_PRS)
- dm9000_rx(dev);
-
- /* Trnasmit Interrupt check */
- if (int_status & ISR_PTS)
- dm9000_tx_done(dev, db);
-
- /* Re-enable interrupt mask */
- iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
-
- /* Restore previous register address */
- writeb(reg_save, db->io_addr);
-
- spin_unlock(&db->lock);
-
- return IRQ_HANDLED;
-}
-
struct dm9000_rxhdr {
u8 RxPktReady;
u8 RxStatus;
@@ -1094,173 +931,109 @@ dm9000_rx(struct net_device *dev)
} while (rxbyte == DM9000_PKT_RDY);
}
-static unsigned int
-dm9000_read_locked(board_info_t *db, int reg)
+static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
{
- unsigned long flags;
- unsigned int ret;
+ struct net_device *dev = dev_id;
+ board_info_t *db = dev->priv;
+ int int_status;
+ u8 reg_save;
- spin_lock_irqsave(&db->lock, flags);
- ret = ior(db, reg);
- spin_unlock_irqrestore(&db->lock, flags);
+ dm9000_dbg(db, 3, "entering %s\n", __func__);
- return ret;
-}
+ /* A real interrupt coming */
-static int dm9000_wait_eeprom(board_info_t *db)
-{
- unsigned int status;
- int timeout = 8; /* wait max 8msec */
+ spin_lock(&db->lock);
- /* The DM9000 data sheets say we should be able to
- * poll the ERRE bit in EPCR to wait for the EEPROM
- * operation. From testing several chips, this bit
- * does not seem to work.
- *
- * We attempt to use the bit, but fall back to the
- * timeout (which is why we do not return an error
- * on expiry) to say that the EEPROM operation has
- * completed.
- */
+ /* Save previous register address */
+ reg_save = readb(db->io_addr);
- while (1) {
- status = dm9000_read_locked(db, DM9000_EPCR);
+ /* Disable all interrupts */
+ iow(db, DM9000_IMR, IMR_PAR);
- if ((status & EPCR_ERRE) == 0)
- break;
+ /* Got DM9000 interrupt status */
+ int_status = ior(db, DM9000_ISR); /* Got ISR */
+ iow(db, DM9000_ISR, int_status); /* Clear ISR status */
- if (timeout-- < 0) {
- dev_dbg(db->dev, "timeout waiting EEPROM\n");
- break;
- }
- }
+ if (netif_msg_intr(db))
+ dev_dbg(db->dev, "interrupt status %02x\n", int_status);
- return 0;
-}
+ /* Received the coming packet */
+ if (int_status & ISR_PRS)
+ dm9000_rx(dev);
-/*
- * Read a word data from EEPROM
- */
-static void
-dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
-{
- unsigned long flags;
+ /* Trnasmit Interrupt check */
+ if (int_status & ISR_PTS)
+ dm9000_tx_done(dev, db);
- if (db->flags & DM9000_PLATF_NO_EEPROM) {
- to[0] = 0xff;
- to[1] = 0xff;
- return;
+ if (db->type != TYPE_DM9000E) {
+ if (int_status & ISR_LNKCHNG) {
+ /* fire a link-change request */
+ schedule_delayed_work(&db->phy_poll, 1);
+ }
}
- mutex_lock(&db->addr_lock);
-
- spin_lock_irqsave(&db->lock, flags);
-
- iow(db, DM9000_EPAR, offset);
- iow(db, DM9000_EPCR, EPCR_ERPRR);
-
- spin_unlock_irqrestore(&db->lock, flags);
-
- dm9000_wait_eeprom(db);
-
- /* delay for at-least 150uS */
- msleep(1);
-
- spin_lock_irqsave(&db->lock, flags);
-
- iow(db, DM9000_EPCR, 0x0);
+ /* Re-enable interrupt mask */
+ iow(db, DM9000_IMR, db->imr_all);
- to[0] = ior(db, DM9000_EPDRL);
- to[1] = ior(db, DM9000_EPDRH);
+ /* Restore previous register address */
+ writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock, flags);
+ spin_unlock(&db->lock);
- mutex_unlock(&db->addr_lock);
+ return IRQ_HANDLED;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
/*
- * Write a word data to SROM
+ *Used by netconsole
*/
-static void
-dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
+static void dm9000_poll_controller(struct net_device *dev)
{
- unsigned long flags;
-
- if (db->flags & DM9000_PLATF_NO_EEPROM)
- return;
-
- mutex_lock(&db->addr_lock);
-
- spin_lock_irqsave(&db->lock, flags);
- iow(db, DM9000_EPAR, offset);
- iow(db, DM9000_EPDRH, data[1]);
- iow(db, DM9000_EPDRL, data[0]);
- iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
- spin_unlock_irqrestore(&db->lock, flags);
-
- dm9000_wait_eeprom(db);
-
- mdelay(1); /* wait at least 150uS to clear */
-
- spin_lock_irqsave(&db->lock, flags);
- iow(db, DM9000_EPCR, 0);
- spin_unlock_irqrestore(&db->lock, flags);
-
- mutex_unlock(&db->addr_lock);
+ disable_irq(dev->irq);
+ dm9000_interrupt(dev->irq, dev);
+ enable_irq(dev->irq);
}
+#endif
/*
- * Set DM9000 multicast address
+ * Open the interface.
+ * The interface is opened whenever "ifconfig" actives it.
*/
-static void
-dm9000_hash_table(struct net_device *dev)
+static int
+dm9000_open(struct net_device *dev)
{
- board_info_t *db = (board_info_t *) dev->priv;
- struct dev_mc_list *mcptr = dev->mc_list;
- int mc_cnt = dev->mc_count;
- int i, oft;
- u32 hash_val;
- u16 hash_table[4];
- u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
- unsigned long flags;
-
- dm9000_dbg(db, 1, "entering %s\n", __func__);
+ board_info_t *db = dev->priv;
+ unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
- spin_lock_irqsave(&db->lock, flags);
+ if (netif_msg_ifup(db))
+ dev_dbg(db->dev, "enabling %s\n", dev->name);
- for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
- iow(db, oft, dev->dev_addr[i]);
+ /* If there is no IRQ type specified, default to something that
+ * may work, and tell the user that this is a problem */
- /* Clear Hash Table */
- for (i = 0; i < 4; i++)
- hash_table[i] = 0x0;
+ if (irqflags == IRQF_TRIGGER_NONE)
+ dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
- /* broadcast address */
- hash_table[3] = 0x8000;
+ irqflags |= IRQF_SHARED;
- if (dev->flags & IFF_PROMISC)
- rcr |= RCR_PRMSC;
+ if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
+ return -EAGAIN;
- if (dev->flags & IFF_ALLMULTI)
- rcr |= RCR_ALL;
+ /* Initialize DM9000 board */
+ dm9000_reset(db);
+ dm9000_init_dm9000(dev);
- /* the multicast address in Hash Table : 64 bits */
- for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
- hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
- hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
- }
+ /* Init driver variable */
+ db->dbug_cnt = 0;
- /* Write the hash table to MAC MD table */
- for (i = 0, oft = DM9000_MAR; i < 4; i++) {
- iow(db, oft++, hash_table[i]);
- iow(db, oft++, hash_table[i] >> 8);
- }
+ mii_check_media(&db->mii, netif_msg_link(db), 1);
+ netif_start_queue(dev);
+
+ dm9000_schedule_poll(db);
- iow(db, DM9000_RCR, rcr);
- spin_unlock_irqrestore(&db->lock, flags);
+ return 0;
}
-
/*
* Sleep, either by using msleep() or if we are suspending, then
* use mdelay() to sleep.
@@ -1323,7 +1096,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
* Write a word to phyxcer
*/
static void
-dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
+dm9000_phy_write(struct net_device *dev,
+ int phyaddr_unused, int reg, int value)
{
board_info_t *db = (board_info_t *) dev->priv;
unsigned long flags;
@@ -1363,6 +1137,273 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
mutex_unlock(&db->addr_lock);
}
+static void
+dm9000_shutdown(struct net_device *dev)
+{
+ board_info_t *db = dev->priv;
+
+ /* RESET device */
+ dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
+ iow(db, DM9000_GPR, 0x01); /* Power-Down PHY */
+ iow(db, DM9000_IMR, IMR_PAR); /* Disable all interrupt */
+ iow(db, DM9000_RCR, 0x00); /* Disable RX */
+}
+
+/*
+ * Stop the interface.
+ * The interface is stopped when it is brought.
+ */
+static int
+dm9000_stop(struct net_device *ndev)
+{
+ board_info_t *db = ndev->priv;
+
+ if (netif_msg_ifdown(db))
+ dev_dbg(db->dev, "shutting down %s\n", ndev->name);
+
+ cancel_delayed_work_sync(&db->phy_poll);
+
+ netif_stop_queue(ndev);
+ netif_carrier_off(ndev);
+
+ /* free interrupt */
+ free_irq(ndev->irq, ndev);
+
+ dm9000_shutdown(ndev);
+
+ return 0;
+}
+
+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+
+/*
+ * Search DM9000 board, allocate space and register it
+ */
+static int __devinit
+dm9000_probe(struct platform_device *pdev)
+{
+ struct dm9000_plat_data *pdata = pdev->dev.platform_data;
+ struct board_info *db; /* Point a board information structure */
+ struct net_device *ndev;
+ const unsigned char *mac_src;
+ int ret = 0;
+ int iosize;
+ int i;
+ u32 id_val;
+
+ /* Init network device */
+ ndev = alloc_etherdev(sizeof(struct board_info));
+ if (!ndev) {
+ dev_err(&pdev->dev, "could not allocate device.\n");
+ return -ENOMEM;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ dev_dbg(&pdev->dev, "dm9000_probe()\n");
+
+ /* setup board info structure */
+ db = ndev->priv;
+ memset(db, 0, sizeof(*db));
+
+ db->dev = &pdev->dev;
+ db->ndev = ndev;
+
+ spin_lock_init(&db->lock);
+ mutex_init(&db->addr_lock);
+
+ INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
+
+ db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (db->addr_res == NULL || db->data_res == NULL ||
+ db->irq_res == NULL) {
+ dev_err(db->dev, "insufficient resources\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ iosize = res_size(db->addr_res);
+ db->addr_req = request_mem_region(db->addr_res->start, iosize,
+ pdev->name);
+
+ if (db->addr_req == NULL) {
+ dev_err(db->dev, "cannot claim address reg area\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ db->io_addr = ioremap(db->addr_res->start, iosize);
+
+ if (db->io_addr == NULL) {
+ dev_err(db->dev, "failed to ioremap address reg\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ iosize = res_size(db->data_res);
+ db->data_req = request_mem_region(db->data_res->start, iosize,
+ pdev->name);
+
+ if (db->data_req == NULL) {
+ dev_err(db->dev, "cannot claim data reg area\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ db->io_data = ioremap(db->data_res->start, iosize);
+
+ if (db->io_data == NULL) {
+ dev_err(db->dev, "failed to ioremap data reg\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* fill in parameters for net-dev structure */
+ ndev->base_addr = (unsigned long)db->io_addr;
+ ndev->irq = db->irq_res->start;
+
+ /* ensure at least we have a default set of IO routines */
+ dm9000_set_io(db, iosize);
+
+ /* check to see if anything is being over-ridden */
+ if (pdata != NULL) {
+ /* check to see if the driver wants to over-ride the
+ * default IO width */
+
+ if (pdata->flags & DM9000_PLATF_8BITONLY)
+ dm9000_set_io(db, 1);
+
+ if (pdata->flags & DM9000_PLATF_16BITONLY)
+ dm9000_set_io(db, 2);
+
+ if (pdata->flags & DM9000_PLATF_32BITONLY)
+ dm9000_set_io(db, 4);
+
+ /* check to see if there are any IO routine
+ * over-rides */
+
+ if (pdata->inblk != NULL)
+ db->inblk = pdata->inblk;
+
+ if (pdata->outblk != NULL)
+ db->outblk = pdata->outblk;
+
+ if (pdata->dumpblk != NULL)
+ db->dumpblk = pdata->dumpblk;
+
+ db->flags = pdata->flags;
+ }
+
+#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL
+ db->flags |= DM9000_PLATF_SIMPLE_PHY;
+#endif
+
+ dm9000_reset(db);
+
+ /* try multiple times, DM9000 sometimes gets the read wrong */
+ for (i = 0; i < 8; i++) {
+ id_val = ior(db, DM9000_VIDL);
+ id_val |= (u32)ior(db, DM9000_VIDH) << 8;
+ id_val |= (u32)ior(db, DM9000_PIDL) << 16;
+ id_val |= (u32)ior(db, DM9000_PIDH) << 24;
+
+ if (id_val == DM9000_ID)
+ break;
+ dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
+ }
+
+ if (id_val != DM9000_ID) {
+ dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Identify what type of DM9000 we are working on */
+
+ id_val = ior(db, DM9000_CHIPR);
+ dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);
+
+ switch (id_val) {
+ case CHIPR_DM9000A:
+ db->type = TYPE_DM9000A;
+ break;
+ case CHIPR_DM9000B:
+ db->type = TYPE_DM9000B;
+ break;
+ default:
+ dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);
+ db->type = TYPE_DM9000E;
+ }
+
+ /* from this point we assume that we have found a DM9000 */
+
+ /* driver system function */
+ ether_setup(ndev);
+
+ ndev->open = &dm9000_open;
+ ndev->hard_start_xmit = &dm9000_start_xmit;
+ ndev->tx_timeout = &dm9000_timeout;
+ ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+ ndev->stop = &dm9000_stop;
+ ndev->set_multicast_list = &dm9000_hash_table;
+ ndev->ethtool_ops = &dm9000_ethtool_ops;
+ ndev->do_ioctl = &dm9000_ioctl;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ ndev->poll_controller = &dm9000_poll_controller;
+#endif
+
+ db->msg_enable = NETIF_MSG_LINK;
+ db->mii.phy_id_mask = 0x1f;
+ db->mii.reg_num_mask = 0x1f;
+ db->mii.force_media = 0;
+ db->mii.full_duplex = 0;
+ db->mii.dev = ndev;
+ db->mii.mdio_read = dm9000_phy_read;
+ db->mii.mdio_write = dm9000_phy_write;
+
+ mac_src = "eeprom";
+
+ /* try reading the node address from the attached EEPROM */
+ for (i = 0; i < 6; i += 2)
+ dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
+
+ if (!is_valid_ether_addr(ndev->dev_addr)) {
+ /* try reading from mac */
+
+ mac_src = "chip";
+ for (i = 0; i < 6; i++)
+ ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
+ }
+
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
+ "set using ifconfig\n", ndev->name);
+
+ platform_set_drvdata(pdev, ndev);
+ ret = register_netdev(ndev);
+
+ if (ret == 0) {
+ DECLARE_MAC_BUF(mac);
+ printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %s (%s)\n",
+ ndev->name, dm9000_type_to_char(db->type),
+ db->io_addr, db->io_data, ndev->irq,
+ print_mac(mac, ndev->dev_addr), mac_src);
+ }
+ return 0;
+
+out:
+ dev_err(db->dev, "not found (%d).\n", ret);
+
+ dm9000_release_board(pdev, db);
+ free_netdev(ndev);
+
+ return ret;
+}
+
static int
dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
{
@@ -1432,7 +1473,7 @@ dm9000_init(void)
{
printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);
- return platform_driver_register(&dm9000_driver); /* search board and register */
+ return platform_driver_register(&dm9000_driver);
}
static void __exit
diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h
index 82cad360baf..ba25cf54142 100644
--- a/drivers/net/dm9000.h
+++ b/drivers/net/dm9000.h
@@ -45,6 +45,9 @@
#define DM9000_CHIPR 0x2C
#define DM9000_SMCR 0x2F
+#define CHIPR_DM9000A 0x19
+#define CHIPR_DM9000B 0x1B
+
#define DM9000_MRCMDX 0xF0
#define DM9000_MRCMD 0xF2
#define DM9000_MRRL 0xF4
@@ -131,5 +134,13 @@
#define DM9000_PKT_RDY 0x01 /* Packet ready to receive */
#define DM9000_PKT_MAX 1536 /* Received packet max size */
+/* DM9000A / DM9000B definitions */
+
+#define IMR_LNKCHNG (1<<5)
+#define IMR_UNDERRUN (1<<4)
+
+#define ISR_LNKCHNG (1<<5)
+#define ISR_UNDERRUN (1<<4)
+
#endif /* _DM9000X_H_ */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 59579b1d884..cf12b05cd01 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -47,12 +47,6 @@ static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation
* Macro expands to...
* {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
*/
-#ifdef CONFIG_E1000E_ENABLED
- #define PCIE(x)
-#else
- #define PCIE(x) x,
-#endif
-
static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1000),
INTEL_E1000_ETHERNET_DEVICE(0x1001),
@@ -79,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1026),
INTEL_E1000_ETHERNET_DEVICE(0x1027),
INTEL_E1000_ETHERNET_DEVICE(0x1028),
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x1049))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x104A))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x104B))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x104C))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x104D))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x105E))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x105F))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x1060))
INTEL_E1000_ETHERNET_DEVICE(0x1075),
INTEL_E1000_ETHERNET_DEVICE(0x1076),
INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -95,28 +81,9 @@ PCIE( INTEL_E1000_ETHERNET_DEVICE(0x1060))
INTEL_E1000_ETHERNET_DEVICE(0x107A),
INTEL_E1000_ETHERNET_DEVICE(0x107B),
INTEL_E1000_ETHERNET_DEVICE(0x107C),
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x107D))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x107E))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x107F))
INTEL_E1000_ETHERNET_DEVICE(0x108A),
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x108B))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x108C))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x1096))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x1098))
INTEL_E1000_ETHERNET_DEVICE(0x1099),
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x109A))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10A4))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10A5))
INTEL_E1000_ETHERNET_DEVICE(0x10B5),
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10B9))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10BA))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10BB))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10BC))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10C4))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10C5))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10D5))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10D9))
-PCIE( INTEL_E1000_ETHERNET_DEVICE(0x10DA))
/* required last entry */
{0,}
};
@@ -1505,6 +1472,8 @@ e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter);
+ netif_start_queue(netdev);
+
/* fire a link status change interrupt to start the watchdog */
E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC);
@@ -2510,10 +2479,15 @@ e1000_set_rx_mode(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- } else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
+ rctl &= ~E1000_RCTL_VFE;
} else {
- rctl &= ~E1000_RCTL_MPE;
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ } else {
+ rctl &= ~E1000_RCTL_MPE;
+ }
+ if (adapter->hw.mac_type != e1000_ich8lan)
+ rctl |= E1000_RCTL_VFE;
}
uc_ptr = NULL;
@@ -4310,8 +4284,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
if (unlikely(adapter->vlgrp &&
(status & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->special) &
- E1000_RXD_SPC_VLAN_MASK);
+ le16_to_cpu(rx_desc->special));
} else {
netif_receive_skb(skb);
}
@@ -4319,8 +4292,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter,
if (unlikely(adapter->vlgrp &&
(status & E1000_RXD_STAT_VP))) {
vlan_hwaccel_rx(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->special) &
- E1000_RXD_SPC_VLAN_MASK);
+ le16_to_cpu(rx_desc->special));
} else {
netif_rx(skb);
}
@@ -4497,16 +4469,14 @@ copydone:
#ifdef CONFIG_E1000_NAPI
if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.middle.vlan) &
- E1000_RXD_SPC_VLAN_MASK);
+ le16_to_cpu(rx_desc->wb.middle.vlan));
} else {
netif_receive_skb(skb);
}
#else /* CONFIG_E1000_NAPI */
if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
vlan_hwaccel_rx(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.middle.vlan) &
- E1000_RXD_SPC_VLAN_MASK);
+ le16_to_cpu(rx_desc->wb.middle.vlan));
} else {
netif_rx(skb);
}
@@ -4999,7 +4969,6 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
if (adapter->hw.mac_type != e1000_ich8lan) {
/* enable VLAN receive filtering */
rctl = E1000_READ_REG(&adapter->hw, RCTL);
- rctl |= E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_CFIEN;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
e1000_update_mng_vlan(adapter);
@@ -5011,10 +4980,6 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
if (adapter->hw.mac_type != e1000_ich8lan) {
- /* disable VLAN filtering */
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
- rctl &= ~E1000_RCTL_VFE;
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
if (adapter->mng_vlan_id !=
(u16)E1000_MNG_VLAN_NONE) {
e1000_vlan_rx_kill_vid(netdev,
@@ -5284,7 +5249,6 @@ e1000_netpoll(struct net_device *netdev)
disable_irq(adapter->pdev->irq);
e1000_intr(adapter->pdev->irq, netdev);
- e1000_clean_tx_irq(adapter, adapter->tx_ring);
#ifndef CONFIG_E1000_NAPI
adapter->clean_rx(adapter, adapter->rx_ring);
#endif
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index d3bc6f8101f..4a4f62e002b 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -283,6 +283,10 @@ struct e1000_adapter {
unsigned long led_status;
unsigned int flags;
+
+ /* for ioport free */
+ int bars;
+ int need_ioport;
};
struct e1000_info {
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 648a87bbf46..869544b8c05 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -98,8 +98,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan) &
- E1000_RXD_SPC_VLAN_MASK);
+ le16_to_cpu(vlan));
else
netif_receive_skb(skb);
@@ -1793,7 +1792,6 @@ static void e1000_vlan_rx_register(struct net_device *netdev,
if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
/* enable VLAN receive filtering */
rctl = er32(RCTL);
- rctl |= E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_CFIEN;
ew32(RCTL, rctl);
e1000_update_mng_vlan(adapter);
@@ -1805,10 +1803,6 @@ static void e1000_vlan_rx_register(struct net_device *netdev,
ew32(CTRL, ctrl);
if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- /* disable VLAN filtering */
- rctl = er32(RCTL);
- rctl &= ~E1000_RCTL_VFE;
- ew32(RCTL, rctl);
if (adapter->mng_vlan_id !=
(u16)E1000_MNG_VLAN_NONE) {
e1000_vlan_rx_kill_vid(netdev,
@@ -2231,11 +2225,16 @@ static void e1000_set_multi(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- } else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- rctl &= ~E1000_RCTL_UPE;
+ rctl &= ~E1000_RCTL_VFE;
} else {
- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ rctl &= ~E1000_RCTL_UPE;
+ } else {
+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ }
+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
+ rctl |= E1000_RCTL_VFE;
}
ew32(RCTL, rctl);
@@ -2514,7 +2513,7 @@ void e1000e_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
tctl = er32(TCTL);
@@ -2664,6 +2663,8 @@ static int e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter);
+ netif_tx_start_all_queues(netdev);
+
/* fire a link status change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
@@ -3119,7 +3120,7 @@ static void e1000_watchdog_task(struct work_struct *work)
ew32(TCTL, tctl);
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
+ netif_tx_wake_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
@@ -3131,7 +3132,7 @@ static void e1000_watchdog_task(struct work_struct *work)
adapter->link_duplex = 0;
ndev_info(netdev, "Link is Down\n");
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -4003,7 +4004,11 @@ static int e1000_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
e1000e_disable_l1aspm(pdev);
- err = pci_enable_device(pdev);
+
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"Cannot enable PCI device from suspend\n");
@@ -4104,9 +4109,14 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ int err;
e1000e_disable_l1aspm(pdev);
- if (pci_enable_device(pdev)) {
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
+ if (err) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
@@ -4185,6 +4195,21 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
}
/**
+ * e1000e_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Returns true if an adapters needs ioport resources
+ **/
+static int e1000e_is_need_ioport(struct pci_dev *pdev)
+{
+ switch (pdev->device) {
+ /* Currently there are no adapters that need ioport resources */
+ default:
+ return false;
+ }
+}
+
+/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in e1000_pci_tbl
@@ -4209,9 +4234,19 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
int i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ int bars, need_ioport;
e1000e_disable_l1aspm(pdev);
- err = pci_enable_device(pdev);
+
+ /* do not allocate ioport bars when not needed */
+ need_ioport = e1000e_is_need_ioport(pdev);
+ if (need_ioport) {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+ err = pci_enable_device(pdev);
+ } else {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ err = pci_enable_device_mem(pdev);
+ }
if (err)
return err;
@@ -4234,7 +4269,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
}
- err = pci_request_regions(pdev, e1000e_driver_name);
+ err = pci_request_selected_regions(pdev, bars, e1000e_driver_name);
if (err)
goto err_pci_reg;
@@ -4259,6 +4294,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
adapter->hw.adapter = adapter;
adapter->hw.mac.type = ei->mac;
adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+ adapter->bars = bars;
+ adapter->need_ioport = need_ioport;
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);
@@ -4344,6 +4381,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_TSO;
+ netdev->vlan_features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_SG;
+
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
@@ -4464,7 +4506,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
/* tell the stack to leave us alone until e1000_open() is called */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
@@ -4493,7 +4535,7 @@ err_sw_init:
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, bars);
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -4541,7 +4583,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, adapter->bars);
free_netdev(netdev);
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 7bb9c728a1d..3c1364de2b6 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -90,6 +90,7 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/io.h>
#include <asm/uaccess.h>
+#include <asm/byteorder.h>
/* These identify the driver base version and may not be removed. */
static char version[] =
@@ -861,40 +862,20 @@ static int netdev_open(struct net_device *dev)
Wait the specified 50 PCI cycles after a reset by initializing
Tx and Rx queues and the address filter list.
FIXME (Ueimor): optimistic for alpha + posted writes ? */
-#if defined(__powerpc__) || defined(__sparc__)
-// 89/9/1 modify,
-// np->bcrvalue=0x04 | 0x0x38; /* big-endian, 256 burst length */
- np->bcrvalue = 0x04 | 0x10; /* big-endian, tx 8 burst length */
- np->crvalue = 0xe00; /* rx 128 burst length */
-#elif defined(__alpha__) || defined(__x86_64__)
-// 89/9/1 modify,
-// np->bcrvalue=0x38; /* little-endian, 256 burst length */
- np->bcrvalue = 0x10; /* little-endian, 8 burst length */
- np->crvalue = 0xe00; /* rx 128 burst length */
-#elif defined(__i386__)
-#if defined(MODULE)
-// 89/9/1 modify,
-// np->bcrvalue=0x38; /* little-endian, 256 burst length */
+
np->bcrvalue = 0x10; /* little-endian, 8 burst length */
- np->crvalue = 0xe00; /* rx 128 burst length */
-#else
- /* When not a module we can work around broken '486 PCI boards. */
-#define x86 boot_cpu_data.x86
-// 89/9/1 modify,
-// np->bcrvalue=(x86 <= 4 ? 0x10 : 0x38);
- np->bcrvalue = 0x10;
- np->crvalue = (x86 <= 4 ? 0xa00 : 0xe00);
- if (x86 <= 4)
- printk(KERN_INFO "%s: This is a 386/486 PCI system, setting burst "
- "length to %x.\n", dev->name, (x86 <= 4 ? 0x10 : 0x38));
+#ifdef __BIG_ENDIAN
+ np->bcrvalue |= 0x04; /* big-endian */
#endif
-#else
-// 89/9/1 modify,
-// np->bcrvalue=0x38;
- np->bcrvalue = 0x10;
- np->crvalue = 0xe00; /* rx 128 burst length */
-#warning Processor architecture undefined!
+
+#if defined(__i386__) && !defined(MODULE)
+ if (boot_cpu_data.x86 <= 4)
+ np->crvalue = 0xa00;
+ else
#endif
+ np->crvalue = 0xe00; /* rx 128 burst length */
+
+
// 89/12/29 add,
// 90/1/16 modify,
// np->imrvalue=FBE|TUNF|CNTOVF|RBU|TI|RI;
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 329edd9c08f..ae9ecb7df22 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -197,7 +197,7 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
if (priv->link == PHY_DOWN) {
new_state = 1;
priv->link = phydev->link;
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
netif_carrier_on(dev);
netif_start_queue(dev);
}
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 20d4fe96a81..4ed89fa9ae4 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -426,6 +426,7 @@ union ring_type {
#define NV_PCI_REGSZ_VER1 0x270
#define NV_PCI_REGSZ_VER2 0x2d4
#define NV_PCI_REGSZ_VER3 0x604
+#define NV_PCI_REGSZ_MAX 0x604
/* various timeout delays: all in usec */
#define NV_TXRX_RESET_DELAY 4
@@ -784,6 +785,9 @@ struct fe_priv {
/* flow control */
u32 pause_flags;
+
+ /* power saved state */
+ u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
};
/*
@@ -2827,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
*/
nv_disable_irq(dev);
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
@@ -2851,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
/* restart rx engine */
nv_start_rxtx(dev);
spin_unlock(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
nv_enable_irq(dev);
}
@@ -2887,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
if (netif_running(dev)) {
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock_irq(&np->lock);
/* stop rx engine */
@@ -2898,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
/* restart rx engine */
nv_start_rx(dev);
spin_unlock_irq(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
} else {
nv_copy_mac_to_hw(dev);
@@ -3967,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data)
printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
if (netif_running(dev)) {
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
@@ -3991,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data)
/* restart rx engine */
nv_start_rxtx(dev);
spin_unlock(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
}
}
@@ -4198,6 +4208,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
nv_disable_irq(dev);
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
/* with plain spinlock lockdep complains */
spin_lock_irqsave(&np->lock, flags);
/* stop engines */
@@ -4211,6 +4222,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
*/
nv_stop_rxtx(dev);
spin_unlock_irqrestore(&np->lock, flags);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
}
@@ -4356,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev)
if (netif_running(dev)) {
nv_disable_irq(dev);
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
spin_unlock(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
printk(KERN_INFO "%s: link down.\n", dev->name);
}
@@ -4467,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
if (netif_running(dev)) {
nv_disable_irq(dev);
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
@@ -4515,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
/* restart engines */
nv_start_rxtx(dev);
spin_unlock(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
nv_enable_irq(dev);
}
@@ -4552,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
if (netif_running(dev)) {
nv_disable_irq(dev);
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
spin_unlock(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
}
@@ -4942,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
napi_disable(&np->napi);
#endif
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
spin_lock_irq(&np->lock);
nv_disable_hw_interrupts(dev, np->irqmask);
if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
@@ -4955,6 +4974,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
/* drain rx queue */
nv_drain_rxtx(dev);
spin_unlock_irq(&np->lock);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
}
@@ -5566,6 +5586,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* set mac address */
nv_copy_mac_to_hw(dev);
+ /* Workaround current PCI init glitch: wakeup bits aren't
+ * being set from PCI PM capability.
+ */
+ device_init_wakeup(&pci_dev->dev, 1);
+
/* disable WOL */
writel(0, base + NvRegWakeUpFlags);
np->wolenabled = 0;
@@ -5816,50 +5841,66 @@ static int nv_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct fe_priv *np = netdev_priv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ int i;
- if (!netif_running(dev))
- goto out;
-
+ if (netif_running(dev)) {
+ // Gross.
+ nv_close(dev);
+ }
netif_device_detach(dev);
- // Gross.
- nv_close(dev);
+ /* save non-pci configuration space */
+ for (i = 0;i <= np->register_size/sizeof(u32); i++)
+ np->saved_config_space[i] = readl(base + i*sizeof(u32));
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
-out:
return 0;
}
static int nv_resume(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- int rc = 0;
- u32 txreg;
-
- if (!netif_running(dev))
- goto out;
-
- netif_device_attach(dev);
+ int i, rc = 0;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
+ /* ack any pending wake events, disable PME */
pci_enable_wake(pdev, PCI_D0, 0);
- /* restore mac address reverse flag */
- txreg = readl(base + NvRegTransmitPoll);
- txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV;
- writel(txreg, base + NvRegTransmitPoll);
+ /* restore non-pci configuration space */
+ for (i = 0;i <= np->register_size/sizeof(u32); i++)
+ writel(np->saved_config_space[i], base+i*sizeof(u32));
- rc = nv_open(dev);
- nv_set_multicast(dev);
-out:
+ netif_device_attach(dev);
+ if (netif_running(dev)) {
+ rc = nv_open(dev);
+ nv_set_multicast(dev);
+ }
return rc;
}
+
+static void nv_shutdown(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct fe_priv *np = netdev_priv(dev);
+
+ if (netif_running(dev))
+ nv_close(dev);
+
+ pci_enable_wake(pdev, PCI_D3hot, np->wolenabled);
+ pci_enable_wake(pdev, PCI_D3cold, np->wolenabled);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+}
#else
#define nv_suspend NULL
+#define nv_shutdown NULL
#define nv_resume NULL
#endif /* CONFIG_PM */
@@ -6030,6 +6071,7 @@ static struct pci_driver driver = {
.remove = __devexit_p(nv_remove),
.suspend = nv_suspend,
.resume = nv_resume,
+ .shutdown = nv_shutdown,
};
static int __init init_nic(void)
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 352574a3f05..445763e5648 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -43,6 +43,7 @@
#include <asm/uaccess.h>
#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#endif
@@ -737,7 +738,7 @@ static void generic_adjust_link(struct net_device *dev)
if (!fep->oldlink) {
new_state = 1;
fep->oldlink = 1;
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
netif_carrier_on(dev);
netif_start_queue(dev);
}
@@ -1172,8 +1173,7 @@ static int __devinit find_phy(struct device_node *np,
struct fs_platform_info *fpi)
{
struct device_node *phynode, *mdionode;
- struct resource res;
- int ret = 0, len;
+ int ret = 0, len, bus_id;
const u32 *data;
data = of_get_property(np, "fixed-link", NULL);
@@ -1190,19 +1190,28 @@ static int __devinit find_phy(struct device_node *np,
if (!phynode)
return -EINVAL;
- mdionode = of_get_parent(phynode);
- if (!mdionode)
+ data = of_get_property(phynode, "reg", &len);
+ if (!data || len != 4) {
+ ret = -EINVAL;
goto out_put_phy;
+ }
- ret = of_address_to_resource(mdionode, 0, &res);
- if (ret)
- goto out_put_mdio;
+ mdionode = of_get_parent(phynode);
+ if (!mdionode) {
+ ret = -EINVAL;
+ goto out_put_phy;
+ }
- data = of_get_property(phynode, "reg", &len);
- if (!data || len != 4)
- goto out_put_mdio;
+ bus_id = of_get_gpio(mdionode, 0);
+ if (bus_id < 0) {
+ struct resource res;
+ ret = of_address_to_resource(mdionode, 0, &res);
+ if (ret)
+ goto out_put_mdio;
+ bus_id = res.start;
+ }
- snprintf(fpi->bus_id, 16, "%x:%02x", res.start, *data);
+ snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
out_put_mdio:
of_node_put(mdionode);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 25bdd0832df..45a63172852 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -44,8 +44,7 @@
* happen immediately, but will wait until either a set number
* of frames or amount of time have passed). In NAPI, the
* interrupt handler will signal there is work to be done, and
- * exit. Without NAPI, the packet(s) will be handled
- * immediately. Both methods will start at the last known empty
+ * exit. This method will start at the last known empty
* descriptor, and process every subsequent descriptor until there
* are none left with data (NAPI will stop after a set number of
* packets to give time to other tasks, but will eventually
@@ -101,12 +100,6 @@
#undef BRIEF_GFAR_ERRORS
#undef VERBOSE_GFAR_ERRORS
-#ifdef CONFIG_GFAR_NAPI
-#define RECEIVE(x) netif_receive_skb(x)
-#else
-#define RECEIVE(x) netif_rx(x)
-#endif
-
const char gfar_driver_name[] = "Gianfar Ethernet";
const char gfar_driver_version[] = "1.3";
@@ -131,9 +124,7 @@ static void free_skb_resources(struct gfar_private *priv);
static void gfar_set_multi(struct net_device *dev);
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
static void gfar_configure_serdes(struct net_device *dev);
-#ifdef CONFIG_GFAR_NAPI
static int gfar_poll(struct napi_struct *napi, int budget);
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
static void gfar_netpoll(struct net_device *dev);
#endif
@@ -260,9 +251,7 @@ static int gfar_probe(struct platform_device *pdev)
dev->hard_start_xmit = gfar_start_xmit;
dev->tx_timeout = gfar_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_GFAR_NAPI
netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = gfar_netpoll;
#endif
@@ -363,11 +352,7 @@ static int gfar_probe(struct platform_device *pdev)
/* Even more device info helps when determining which kernel */
/* provided which set of benchmarks. */
-#ifdef CONFIG_GFAR_NAPI
printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
-#else
- printk(KERN_INFO "%s: Running with NAPI disabled\n", dev->name);
-#endif
printk(KERN_INFO "%s: %d/%d RX/TX BD ring size\n",
dev->name, priv->rx_ring_size, priv->tx_ring_size);
@@ -928,7 +913,7 @@ rx_irq_fail:
tx_irq_fail:
free_irq(priv->interruptError, dev);
err_irq_fail:
-err_rxalloc_fail:
+err_rxalloc_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
@@ -945,14 +930,10 @@ tx_skb_fail:
/* Returns 0 for success. */
static int gfar_enet_open(struct net_device *dev)
{
-#ifdef CONFIG_GFAR_NAPI
struct gfar_private *priv = netdev_priv(dev);
-#endif
int err;
-#ifdef CONFIG_GFAR_NAPI
napi_enable(&priv->napi);
-#endif
/* Initialize a bunch of registers */
init_registers(dev);
@@ -962,17 +943,13 @@ static int gfar_enet_open(struct net_device *dev)
err = init_phy(dev);
if(err) {
-#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
-#endif
return err;
}
err = startup_gfar(dev);
if (err) {
-#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
-#endif
return err;
}
@@ -1128,9 +1105,7 @@ static int gfar_close(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
-#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
-#endif
stop_gfar(dev);
@@ -1259,7 +1234,7 @@ static void gfar_timeout(struct net_device *dev)
startup_gfar(dev);
}
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
}
/* Interrupt Handler for Transmit complete */
@@ -1427,14 +1402,9 @@ irqreturn_t gfar_receive(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
struct gfar_private *priv = netdev_priv(dev);
-#ifdef CONFIG_GFAR_NAPI
u32 tempval;
-#else
- unsigned long flags;
-#endif
/* support NAPI */
-#ifdef CONFIG_GFAR_NAPI
/* Clear IEVENT, so interrupts aren't called again
* because of the packets that have already arrived */
gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
@@ -1451,38 +1421,10 @@ irqreturn_t gfar_receive(int irq, void *dev_id)
dev->name, gfar_read(&priv->regs->ievent),
gfar_read(&priv->regs->imask));
}
-#else
- /* Clear IEVENT, so rx interrupt isn't called again
- * because of this interrupt */
- gfar_write(&priv->regs->ievent, IEVENT_RX_MASK);
-
- spin_lock_irqsave(&priv->rxlock, flags);
- gfar_clean_rx_ring(dev, priv->rx_ring_size);
-
- /* If we are coalescing interrupts, update the timer */
- /* Otherwise, clear it */
- if (likely(priv->rxcoalescing)) {
- gfar_write(&priv->regs->rxic, 0);
- gfar_write(&priv->regs->rxic,
- mk_ic_value(priv->rxcount, priv->rxtime));
- }
-
- spin_unlock_irqrestore(&priv->rxlock, flags);
-#endif
return IRQ_HANDLED;
}
-static inline int gfar_rx_vlan(struct sk_buff *skb,
- struct vlan_group *vlgrp, unsigned short vlctl)
-{
-#ifdef CONFIG_GFAR_NAPI
- return vlan_hwaccel_receive_skb(skb, vlgrp, vlctl);
-#else
- return vlan_hwaccel_rx(skb, vlgrp, vlctl);
-#endif
-}
-
static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
{
/* If valid headers were found, and valid sums
@@ -1539,10 +1481,11 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
skb->protocol = eth_type_trans(skb, dev);
/* Send the packet up the stack */
- if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN)))
- ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
- else
- ret = RECEIVE(skb);
+ if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) {
+ ret = vlan_hwaccel_receive_skb(skb, priv->vlgrp,
+ fcb->vlctl);
+ } else
+ ret = netif_receive_skb(skb);
if (NET_RX_DROP == ret)
priv->extra_stats.kernel_dropped++;
@@ -1629,7 +1572,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
return howmany;
}
-#ifdef CONFIG_GFAR_NAPI
static int gfar_poll(struct napi_struct *napi, int budget)
{
struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
@@ -1664,7 +1606,6 @@ static int gfar_poll(struct napi_struct *napi, int budget)
return howmany;
}
-#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
@@ -1784,7 +1725,7 @@ static void adjust_link(struct net_device *dev)
if (!priv->oldlink) {
new_state = 1;
priv->oldlink = 1;
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
}
} else if (priv->oldlink) {
new_state = 1;
@@ -2003,11 +1944,6 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
gfar_receive(irq, dev_id);
-#ifndef CONFIG_GFAR_NAPI
- /* Clear the halt bit in RSTAT */
- gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
-#endif
-
if (netif_msg_rx_err(priv))
printk(KERN_DEBUG "%s: busy error (rstat: %x)\n",
dev->name, gfar_read(&priv->regs->rstat));
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 27f37c81e52..bead71cb2b1 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -77,13 +77,8 @@ extern const char gfar_driver_name[];
extern const char gfar_driver_version[];
/* These need to be powers of 2 for this driver */
-#ifdef CONFIG_GFAR_NAPI
#define DEFAULT_TX_RING_SIZE 256
#define DEFAULT_RX_RING_SIZE 256
-#else
-#define DEFAULT_TX_RING_SIZE 64
-#define DEFAULT_RX_RING_SIZE 64
-#endif
#define GFAR_RX_MAX_RING_SIZE 256
#define GFAR_TX_MAX_RING_SIZE 256
@@ -128,14 +123,8 @@ extern const char gfar_driver_version[];
#define DEFAULT_RXTIME 21
-/* Non NAPI Case */
-#ifndef CONFIG_GFAR_NAPI
-#define DEFAULT_RX_COALESCE 1
-#define DEFAULT_RXCOUNT 16
-#else
#define DEFAULT_RX_COALESCE 0
#define DEFAULT_RXCOUNT 0
-#endif /* CONFIG_GFAR_NAPI */
#define MIIMCFG_INIT_VALUE 0x00000007
#define MIIMCFG_RESET 0x80000000
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index e5c2380f50c..3199526bcec 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1140,11 +1140,11 @@ static void hamachi_tx_timeout(struct net_device *dev)
}
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+ struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz);
hmp->rx_skbuff[i] = skb;
if (skb == NULL)
break;
- skb->dev = dev; /* Mark as being used by this device. */
+
skb_reserve(skb, 2); /* 16 byte align the IP header. */
hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
@@ -1178,14 +1178,6 @@ static void hamachi_init_ring(struct net_device *dev)
hmp->cur_rx = hmp->cur_tx = 0;
hmp->dirty_rx = hmp->dirty_tx = 0;
-#if 0
- /* This is wrong. I'm not sure what the original plan was, but this
- * is wrong. An MTU of 1 gets you a buffer of 1536, while an MTU
- * of 1501 gets a buffer of 1533? -KDU
- */
- hmp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
-#endif
- /* My attempt at a reasonable correction */
/* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
* card needs room to do 8 byte alignment, +2 so we can reserve
* the first 2 bytes, and +16 gets room for the status word from the
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 9d5721287d6..0f501d2ca93 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -99,9 +99,6 @@ struct sixpack {
unsigned int rx_count;
unsigned int rx_count_cooked;
- /* 6pack interface statistics. */
- struct net_device_stats stats;
-
int mtu; /* Our mtu (to spot changes!) */
int buffsize; /* Max buffers sizes */
@@ -237,7 +234,7 @@ static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
return;
out_drop:
- sp->stats.tx_dropped++;
+ sp->dev->stats.tx_dropped++;
netif_start_queue(sp->dev);
if (net_ratelimit())
printk(KERN_DEBUG "%s: %s - dropped.\n", sp->dev->name, msg);
@@ -252,7 +249,7 @@ static int sp_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_bh(&sp->lock);
/* We were not busy, so we are now... :-) */
netif_stop_queue(dev);
- sp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
sp_encaps(sp, skb->data, skb->len);
spin_unlock_bh(&sp->lock);
@@ -298,18 +295,14 @@ static int sp_header(struct sk_buff *skb, struct net_device *dev,
return 0;
}
-static struct net_device_stats *sp_get_stats(struct net_device *dev)
-{
- struct sixpack *sp = netdev_priv(dev);
- return &sp->stats;
-}
-
static int sp_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr_ax25 *sa = addr;
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
return 0;
@@ -338,7 +331,6 @@ static void sp_setup(struct net_device *dev)
dev->destructor = free_netdev;
dev->stop = sp_close;
- dev->get_stats = sp_get_stats;
dev->set_mac_address = sp_set_mac_address;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->header_ops = &sp_header_ops;
@@ -370,7 +362,7 @@ static void sp_bump(struct sixpack *sp, char cmd)
count = sp->rcount + 1;
- sp->stats.rx_bytes += count;
+ sp->dev->stats.rx_bytes += count;
if ((skb = dev_alloc_skb(count)) == NULL)
goto out_mem;
@@ -382,12 +374,12 @@ static void sp_bump(struct sixpack *sp, char cmd)
skb->protocol = ax25_type_trans(skb, sp->dev);
netif_rx(skb);
sp->dev->last_rx = jiffies;
- sp->stats.rx_packets++;
+ sp->dev->stats.rx_packets++;
return;
out_mem:
- sp->stats.rx_dropped++;
+ sp->dev->stats.rx_dropped++;
}
@@ -436,7 +428,7 @@ static void sixpack_write_wakeup(struct tty_struct *tty)
if (sp->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
- sp->stats.tx_packets++;
+ sp->dev->stats.tx_packets++;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
sp->tx_enable = 0;
netif_wake_queue(sp->dev);
@@ -484,7 +476,7 @@ static void sixpack_receive_buf(struct tty_struct *tty,
count--;
if (fp && *fp++) {
if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
- sp->stats.rx_errors++;
+ sp->dev->stats.rx_errors++;
continue;
}
}
@@ -783,7 +775,7 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
return err;
}
-static struct tty_ldisc sp_ldisc = {
+static struct tty_ldisc_ops sp_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "6pack",
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 5f4b4c6c9f7..b6500b2aacf 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -124,6 +124,18 @@ static LIST_HEAD(bpq_devices);
*/
static struct lock_class_key bpq_netdev_xmit_lock_key;
+static void bpq_set_lockdep_class_one(struct net_device *dev,
+ struct netdev_queue *txq,
+ void *_unused)
+{
+ lockdep_set_class(&txq->_xmit_lock, &bpq_netdev_xmit_lock_key);
+}
+
+static void bpq_set_lockdep_class(struct net_device *dev)
+{
+ netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL);
+}
+
/* ------------------------------------------------------------------------ */
@@ -523,7 +535,7 @@ static int bpq_new_device(struct net_device *edev)
err = register_netdevice(ndev);
if (err)
goto error;
- lockdep_set_class(&ndev->_xmit_lock, &bpq_netdev_xmit_lock_key);
+ bpq_set_lockdep_class(ndev);
/* List protected by RTNL */
list_add_rcu(&bpq->bpq_list, &bpq_devices);
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 65166035aca..3249df5e0f1 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -356,7 +356,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr)
struct sockaddr_ax25 *sa = addr;
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
return 0;
@@ -969,7 +971,7 @@ out:
mkiss_put(ax);
}
-static struct tty_ldisc ax_ldisc = {
+static struct tty_ldisc_ops ax_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "mkiss",
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index c649a8019be..8281209eded 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -103,7 +103,7 @@ static int __init do_hp_probe(struct net_device *dev)
#ifndef MODULE
struct net_device * __init hp_probe(int unit)
{
- struct net_device *dev = alloc_ei_netdev();
+ struct net_device *dev = alloc_eip_netdev();
int err;
if (!dev)
@@ -176,7 +176,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
if (irq == probe_irq_off(cookie) /* It's a good IRQ line! */
- && request_irq (irq, ei_interrupt, 0, DRV_NAME, dev) == 0) {
+ && request_irq (irq, eip_interrupt, 0, DRV_NAME, dev) == 0) {
printk(" selecting IRQ %d.\n", irq);
dev->irq = *irqp;
break;
@@ -191,7 +191,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
} else {
if (dev->irq == 2)
dev->irq = 9;
- if ((retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) {
+ if ((retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev))) {
printk (" unable to get IRQ %d.\n", dev->irq);
goto out;
}
@@ -202,7 +202,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
dev->open = &hp_open;
dev->stop = &hp_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
+ dev->poll_controller = eip_poll;
#endif
ei_status.name = name;
@@ -231,14 +231,14 @@ out:
static int
hp_open(struct net_device *dev)
{
- ei_open(dev);
+ eip_open(dev);
return 0;
}
static int
hp_close(struct net_device *dev)
{
- ei_close(dev);
+ eip_close(dev);
return 0;
}
@@ -421,7 +421,7 @@ init_module(void)
if (this_dev != 0) break; /* only autoprobe 1st one */
printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n");
}
- dev = alloc_ei_netdev();
+ dev = alloc_eip_netdev();
if (!dev)
break;
dev->irq = irq[this_dev];
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index be6e5bc7c88..2e802634d36 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -220,12 +220,12 @@ static int hplance_close(struct net_device *dev)
return 0;
}
-int __init hplance_init_module(void)
+static int __init hplance_init_module(void)
{
return dio_register_driver(&hplance_driver);
}
-void __exit hplance_cleanup_module(void)
+static void __exit hplance_cleanup_module(void)
{
dio_unregister_driver(&hplance_driver);
}
diff --git a/drivers/net/ibm_emac/Kconfig b/drivers/net/ibm_emac/Kconfig
deleted file mode 100644
index f61c48047dc..00000000000
--- a/drivers/net/ibm_emac/Kconfig
+++ /dev/null
@@ -1,70 +0,0 @@
-config IBM_EMAC
- tristate "PowerPC 4xx on-chip Ethernet support"
- depends on 4xx && !PPC_MERGE
- help
- This driver supports the PowerPC 4xx EMAC family of on-chip
- Ethernet controllers.
-
-config IBM_EMAC_RXB
- int "Number of receive buffers"
- depends on IBM_EMAC
- default "128"
-
-config IBM_EMAC_TXB
- int "Number of transmit buffers"
- depends on IBM_EMAC
- default "64"
-
-config IBM_EMAC_POLL_WEIGHT
- int "MAL NAPI polling weight"
- depends on IBM_EMAC
- default "32"
-
-config IBM_EMAC_RX_COPY_THRESHOLD
- int "RX skb copy threshold (bytes)"
- depends on IBM_EMAC
- default "256"
-
-config IBM_EMAC_RX_SKB_HEADROOM
- int "Additional RX skb headroom (bytes)"
- depends on IBM_EMAC
- default "0"
- help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
-config IBM_EMAC_PHY_RX_CLK_FIX
- bool "PHY Rx clock workaround"
- depends on IBM_EMAC && (405EP || 440GX || 440EP || 440GR)
- help
- Enable this if EMAC attached to a PHY which doesn't generate
- RX clock if there is no link, if this is the case, you will
- see "TX disable timeout" or "RX disable timeout" in the system
- log.
-
- If unsure, say N.
-
-config IBM_EMAC_DEBUG
- bool "Debugging"
- depends on IBM_EMAC
- default n
-
-config IBM_EMAC_ZMII
- bool
- depends on IBM_EMAC && (NP405H || NP405L || 44x)
- default y
-
-config IBM_EMAC_RGMII
- bool
- depends on IBM_EMAC && 440GX
- default y
-
-config IBM_EMAC_TAH
- bool
- depends on IBM_EMAC && 440GX
- default y
-
diff --git a/drivers/net/ibm_emac/Makefile b/drivers/net/ibm_emac/Makefile
deleted file mode 100644
index f98ddf0e807..00000000000
--- a/drivers/net/ibm_emac/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the PowerPC 4xx on-chip ethernet driver
-#
-
-obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
-
-ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
-ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += ibm_emac_zmii.o
-ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += ibm_emac_rgmii.o
-ibm_emac-$(CONFIG_IBM_EMAC_TAH) += ibm_emac_tah.o
-ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += ibm_emac_debug.o
diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
deleted file mode 100644
index 97ed22bb432..00000000000
--- a/drivers/net/ibm_emac/ibm_emac.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac.h
- *
- * Register definitions for PowerPC 4xx on-chip ethernet contoller
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Matt Porter <mporter@kernel.crashing.org>
- * Armin Kuster <akuster@mvista.com>
- * Copyright 2002-2004 MontaVista Software 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.
- *
- */
-#ifndef __IBM_EMAC_H_
-#define __IBM_EMAC_H_
-
-#include <linux/types.h>
-
-/* This is a simple check to prevent use of this driver on non-tested SoCs */
-#if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \
- !defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \
- !defined(CONFIG_440EP) && !defined(CONFIG_NP405H) && !defined(CONFIG_440SPE) && \
- !defined(CONFIG_440GR)
-#error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK"
-#endif
-
-/* EMAC registers Write Access rules */
-struct emac_regs {
- u32 mr0; /* special */
- u32 mr1; /* Reset */
- u32 tmr0; /* special */
- u32 tmr1; /* special */
- u32 rmr; /* Reset */
- u32 isr; /* Always */
- u32 iser; /* Reset */
- u32 iahr; /* Reset, R, T */
- u32 ialr; /* Reset, R, T */
- u32 vtpid; /* Reset, R, T */
- u32 vtci; /* Reset, R, T */
- u32 ptr; /* Reset, T */
- u32 iaht1; /* Reset, R */
- u32 iaht2; /* Reset, R */
- u32 iaht3; /* Reset, R */
- u32 iaht4; /* Reset, R */
- u32 gaht1; /* Reset, R */
- u32 gaht2; /* Reset, R */
- u32 gaht3; /* Reset, R */
- u32 gaht4; /* Reset, R */
- u32 lsah;
- u32 lsal;
- u32 ipgvr; /* Reset, T */
- u32 stacr; /* special */
- u32 trtr; /* special */
- u32 rwmr; /* Reset */
- u32 octx;
- u32 ocrx;
- u32 ipcr;
-};
-
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_ETHTOOL_REGS_VER 0
-#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32))
-#else
-#define EMAC_ETHTOOL_REGS_VER 1
-#define EMAC_ETHTOOL_REGS_SIZE sizeof(struct emac_regs)
-#endif
-
-/* EMACx_MR0 */
-#define EMAC_MR0_RXI 0x80000000
-#define EMAC_MR0_TXI 0x40000000
-#define EMAC_MR0_SRST 0x20000000
-#define EMAC_MR0_TXE 0x10000000
-#define EMAC_MR0_RXE 0x08000000
-#define EMAC_MR0_WKE 0x04000000
-
-/* EMACx_MR1 */
-#define EMAC_MR1_FDE 0x80000000
-#define EMAC_MR1_ILE 0x40000000
-#define EMAC_MR1_VLE 0x20000000
-#define EMAC_MR1_EIFC 0x10000000
-#define EMAC_MR1_APP 0x08000000
-#define EMAC_MR1_IST 0x01000000
-
-#define EMAC_MR1_MF_MASK 0x00c00000
-#define EMAC_MR1_MF_10 0x00000000
-#define EMAC_MR1_MF_100 0x00400000
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_MR1_MF_1000 0x00000000
-#define EMAC_MR1_MF_1000GPCS 0x00000000
-#define EMAC_MR1_MF_IPPA(id) 0x00000000
-#else
-#define EMAC_MR1_MF_1000 0x00800000
-#define EMAC_MR1_MF_1000GPCS 0x00c00000
-#define EMAC_MR1_MF_IPPA(id) (((id) & 0x1f) << 6)
-#endif
-
-#define EMAC_TX_FIFO_SIZE 2048
-
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_MR1_RFS_4K 0x00300000
-#define EMAC_MR1_RFS_16K 0x00000000
-#define EMAC_RX_FIFO_SIZE(gige) 4096
-#define EMAC_MR1_TFS_2K 0x00080000
-#define EMAC_MR1_TR0_MULT 0x00008000
-#define EMAC_MR1_JPSM 0x00000000
-#define EMAC_MR1_MWSW_001 0x00000000
-#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
-#else
-#define EMAC_MR1_RFS_4K 0x00180000
-#define EMAC_MR1_RFS_16K 0x00280000
-#define EMAC_RX_FIFO_SIZE(gige) ((gige) ? 16384 : 4096)
-#define EMAC_MR1_TFS_2K 0x00020000
-#define EMAC_MR1_TR 0x00008000
-#define EMAC_MR1_MWSW_001 0x00001000
-#define EMAC_MR1_JPSM 0x00000800
-#define EMAC_MR1_OBCI_MASK 0x00000038
-#define EMAC_MR1_OBCI_50 0x00000000
-#define EMAC_MR1_OBCI_66 0x00000008
-#define EMAC_MR1_OBCI_83 0x00000010
-#define EMAC_MR1_OBCI_100 0x00000018
-#define EMAC_MR1_OBCI_100P 0x00000020
-#define EMAC_MR1_OBCI(freq) ((freq) <= 50 ? EMAC_MR1_OBCI_50 : \
- (freq) <= 66 ? EMAC_MR1_OBCI_66 : \
- (freq) <= 83 ? EMAC_MR1_OBCI_83 : \
- (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
-#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
- EMAC_MR1_OBCI(opb))
-#endif
-
-/* EMACx_TMR0 */
-#define EMAC_TMR0_GNP 0x80000000
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_TMR0_DEFAULT 0x00000000
-#else
-#define EMAC_TMR0_TFAE_2_32 0x00000001
-#define EMAC_TMR0_TFAE_4_64 0x00000002
-#define EMAC_TMR0_TFAE_8_128 0x00000003
-#define EMAC_TMR0_TFAE_16_256 0x00000004
-#define EMAC_TMR0_TFAE_32_512 0x00000005
-#define EMAC_TMR0_TFAE_64_1024 0x00000006
-#define EMAC_TMR0_TFAE_128_2048 0x00000007
-#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
-#endif
-#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP | EMAC_TMR0_DEFAULT)
-
-/* EMACx_TMR1 */
-
-/* IBM manuals are not very clear here.
- * This is my interpretation of how things are. --ebs
- */
-#if defined(CONFIG_40x)
-#define EMAC_FIFO_ENTRY_SIZE 8
-#define EMAC_MAL_BURST_SIZE (16 * 4)
-#else
-#define EMAC_FIFO_ENTRY_SIZE 16
-#define EMAC_MAL_BURST_SIZE (64 * 4)
-#endif
-
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0xff) << 16))
-#else
-#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0x3ff) << 14))
-#endif
-
-/* EMACx_RMR */
-#define EMAC_RMR_SP 0x80000000
-#define EMAC_RMR_SFCS 0x40000000
-#define EMAC_RMR_RRP 0x20000000
-#define EMAC_RMR_RFP 0x10000000
-#define EMAC_RMR_ROP 0x08000000
-#define EMAC_RMR_RPIR 0x04000000
-#define EMAC_RMR_PPP 0x02000000
-#define EMAC_RMR_PME 0x01000000
-#define EMAC_RMR_PMME 0x00800000
-#define EMAC_RMR_IAE 0x00400000
-#define EMAC_RMR_MIAE 0x00200000
-#define EMAC_RMR_BAE 0x00100000
-#define EMAC_RMR_MAE 0x00080000
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_RMR_BASE 0x00000000
-#else
-#define EMAC_RMR_RFAF_2_32 0x00000001
-#define EMAC_RMR_RFAF_4_64 0x00000002
-#define EMAC_RMR_RFAF_8_128 0x00000003
-#define EMAC_RMR_RFAF_16_256 0x00000004
-#define EMAC_RMR_RFAF_32_512 0x00000005
-#define EMAC_RMR_RFAF_64_1024 0x00000006
-#define EMAC_RMR_RFAF_128_2048 0x00000007
-#define EMAC_RMR_BASE EMAC_RMR_RFAF_128_2048
-#endif
-
-/* EMACx_ISR & EMACx_ISER */
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_ISR_TXPE 0x00000000
-#define EMAC_ISR_RXPE 0x00000000
-#define EMAC_ISR_TXUE 0x00000000
-#define EMAC_ISR_RXOE 0x00000000
-#else
-#define EMAC_ISR_TXPE 0x20000000
-#define EMAC_ISR_RXPE 0x10000000
-#define EMAC_ISR_TXUE 0x08000000
-#define EMAC_ISR_RXOE 0x04000000
-#endif
-#define EMAC_ISR_OVR 0x02000000
-#define EMAC_ISR_PP 0x01000000
-#define EMAC_ISR_BP 0x00800000
-#define EMAC_ISR_RP 0x00400000
-#define EMAC_ISR_SE 0x00200000
-#define EMAC_ISR_ALE 0x00100000
-#define EMAC_ISR_BFCS 0x00080000
-#define EMAC_ISR_PTLE 0x00040000
-#define EMAC_ISR_ORE 0x00020000
-#define EMAC_ISR_IRE 0x00010000
-#define EMAC_ISR_SQE 0x00000080
-#define EMAC_ISR_TE 0x00000040
-#define EMAC_ISR_MOS 0x00000002
-#define EMAC_ISR_MOF 0x00000001
-
-/* EMACx_STACR */
-#define EMAC_STACR_PHYD_MASK 0xffff
-#define EMAC_STACR_PHYD_SHIFT 16
-#define EMAC_STACR_OC 0x00008000
-#define EMAC_STACR_PHYE 0x00004000
-#define EMAC_STACR_STAC_MASK 0x00003000
-#define EMAC_STACR_STAC_READ 0x00001000
-#define EMAC_STACR_STAC_WRITE 0x00002000
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_STACR_OPBC_MASK 0x00000C00
-#define EMAC_STACR_OPBC_50 0x00000000
-#define EMAC_STACR_OPBC_66 0x00000400
-#define EMAC_STACR_OPBC_83 0x00000800
-#define EMAC_STACR_OPBC_100 0x00000C00
-#define EMAC_STACR_OPBC(freq) ((freq) <= 50 ? EMAC_STACR_OPBC_50 : \
- (freq) <= 66 ? EMAC_STACR_OPBC_66 : \
- (freq) <= 83 ? EMAC_STACR_OPBC_83 : EMAC_STACR_OPBC_100)
-#define EMAC_STACR_BASE(opb) EMAC_STACR_OPBC(opb)
-#else
-#define EMAC_STACR_BASE(opb) 0x00000000
-#endif
-#define EMAC_STACR_PCDA_MASK 0x1f
-#define EMAC_STACR_PCDA_SHIFT 5
-#define EMAC_STACR_PRA_MASK 0x1f
-
-/*
- * For the 440SPe, AMCC inexplicably changed the polarity of
- * the "operation complete" bit in the MII control register.
- */
-#if defined(CONFIG_440SPE)
-static inline int emac_phy_done(u32 stacr)
-{
- return !(stacr & EMAC_STACR_OC);
-};
-#define EMAC_STACR_START EMAC_STACR_OC
-
-#else /* CONFIG_440SPE */
-static inline int emac_phy_done(u32 stacr)
-{
- return stacr & EMAC_STACR_OC;
-};
-#define EMAC_STACR_START 0
-#endif /* !CONFIG_440SPE */
-
-/* EMACx_TRTR */
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_TRTR_SHIFT 27
-#else
-#define EMAC_TRTR_SHIFT 24
-#endif
-#define EMAC_TRTR(size) ((((size) >> 6) - 1) << EMAC_TRTR_SHIFT)
-
-/* EMACx_RWMR */
-#if !defined(CONFIG_IBM_EMAC4)
-#define EMAC_RWMR(l,h) (((l) << 23) | ( ((h) & 0x1ff) << 7))
-#else
-#define EMAC_RWMR(l,h) (((l) << 22) | ( ((h) & 0x3ff) << 6))
-#endif
-
-/* EMAC specific TX descriptor control fields (write access) */
-#define EMAC_TX_CTRL_GFCS 0x0200
-#define EMAC_TX_CTRL_GP 0x0100
-#define EMAC_TX_CTRL_ISA 0x0080
-#define EMAC_TX_CTRL_RSA 0x0040
-#define EMAC_TX_CTRL_IVT 0x0020
-#define EMAC_TX_CTRL_RVT 0x0010
-#define EMAC_TX_CTRL_TAH_CSUM 0x000e
-
-/* EMAC specific TX descriptor status fields (read access) */
-#define EMAC_TX_ST_BFCS 0x0200
-#define EMAC_TX_ST_LCS 0x0080
-#define EMAC_TX_ST_ED 0x0040
-#define EMAC_TX_ST_EC 0x0020
-#define EMAC_TX_ST_LC 0x0010
-#define EMAC_TX_ST_MC 0x0008
-#define EMAC_TX_ST_SC 0x0004
-#define EMAC_TX_ST_UR 0x0002
-#define EMAC_TX_ST_SQE 0x0001
-#if !defined(CONFIG_IBM_EMAC_TAH)
-#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
- EMAC_TX_ST_EC | EMAC_TX_ST_LC | \
- EMAC_TX_ST_MC | EMAC_TX_ST_UR))
-#else
-#define EMAC_IS_BAD_TX(v) ((v) & (EMAC_TX_ST_LCS | EMAC_TX_ST_ED | \
- EMAC_TX_ST_EC | EMAC_TX_ST_LC))
-#endif
-
-/* EMAC specific RX descriptor status fields (read access) */
-#define EMAC_RX_ST_OE 0x0200
-#define EMAC_RX_ST_PP 0x0100
-#define EMAC_RX_ST_BP 0x0080
-#define EMAC_RX_ST_RP 0x0040
-#define EMAC_RX_ST_SE 0x0020
-#define EMAC_RX_ST_AE 0x0010
-#define EMAC_RX_ST_BFCS 0x0008
-#define EMAC_RX_ST_PTL 0x0004
-#define EMAC_RX_ST_ORE 0x0002
-#define EMAC_RX_ST_IRE 0x0001
-#define EMAC_RX_TAH_BAD_CSUM 0x0003
-#define EMAC_BAD_RX_MASK (EMAC_RX_ST_OE | EMAC_RX_ST_BP | \
- EMAC_RX_ST_RP | EMAC_RX_ST_SE | \
- EMAC_RX_ST_AE | EMAC_RX_ST_BFCS | \
- EMAC_RX_ST_PTL | EMAC_RX_ST_ORE | \
- EMAC_RX_ST_IRE )
-#endif /* __IBM_EMAC_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
deleted file mode 100644
index 73664f226f3..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ /dev/null
@@ -1,2263 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_core.c
- *
- * Driver for PowerPC 4xx on-chip ethernet controller.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Matt Porter <mporter@kernel.crashing.org>
- * (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * Armin Kuster <akuster@mvista.com>
- * Johnnie Peters <jpeters@mvista.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.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/crc32.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/bitops.h>
-
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-#include <asm/ocp.h>
-
-#include "ibm_emac_core.h"
-#include "ibm_emac_debug.h"
-
-/*
- * Lack of dma_unmap_???? calls is intentional.
- *
- * API-correct usage requires additional support state information to be
- * maintained for every RX and TX buffer descriptor (BD). Unfortunately, due to
- * EMAC design (e.g. TX buffer passed from network stack can be split into
- * several BDs, dma_map_single/dma_map_page can be used to map particular BD),
- * maintaining such information will add additional overhead.
- * Current DMA API implementation for 4xx processors only ensures cache coherency
- * and dma_unmap_???? routines are empty and are likely to stay this way.
- * I decided to omit dma_unmap_??? calls because I don't want to add additional
- * complexity just for the sake of following some abstract API, when it doesn't
- * add any real benefit to the driver. I understand that this decision maybe
- * controversial, but I really tried to make code API-correct and efficient
- * at the same time and didn't come up with code I liked :(. --ebs
- */
-
-#define DRV_NAME "emac"
-#define DRV_VERSION "3.54"
-#define DRV_DESC "PPC 4xx OCP EMAC driver"
-
-MODULE_DESCRIPTION(DRV_DESC);
-MODULE_AUTHOR
- ("Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>");
-MODULE_LICENSE("GPL");
-
-/* minimum number of free TX descriptors required to wake up TX process */
-#define EMAC_TX_WAKEUP_THRESH (NUM_TX_BUFF / 4)
-
-/* If packet size is less than this number, we allocate small skb and copy packet
- * contents into it instead of just sending original big skb up
- */
-#define EMAC_RX_COPY_THRESH CONFIG_IBM_EMAC_RX_COPY_THRESHOLD
-
-/* Since multiple EMACs share MDIO lines in various ways, we need
- * to avoid re-using the same PHY ID in cases where the arch didn't
- * setup precise phy_map entries
- */
-static u32 busy_phy_map;
-
-#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && \
- (defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR))
-/* 405EP has "EMAC to PHY Control Register" (CPC0_EPCTL) which can help us
- * with PHY RX clock problem.
- * 440EP/440GR has more sane SDR0_MFR register implementation than 440GX, which
- * also allows controlling each EMAC clock
- */
-static inline void EMAC_RX_CLK_TX(int idx)
-{
- unsigned long flags;
- local_irq_save(flags);
-
-#if defined(CONFIG_405EP)
- mtdcr(0xf3, mfdcr(0xf3) | (1 << idx));
-#else /* CONFIG_440EP || CONFIG_440GR */
- SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) | (0x08000000 >> idx));
-#endif
-
- local_irq_restore(flags);
-}
-
-static inline void EMAC_RX_CLK_DEFAULT(int idx)
-{
- unsigned long flags;
- local_irq_save(flags);
-
-#if defined(CONFIG_405EP)
- mtdcr(0xf3, mfdcr(0xf3) & ~(1 << idx));
-#else /* CONFIG_440EP */
- SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~(0x08000000 >> idx));
-#endif
-
- local_irq_restore(flags);
-}
-#else
-#define EMAC_RX_CLK_TX(idx) ((void)0)
-#define EMAC_RX_CLK_DEFAULT(idx) ((void)0)
-#endif
-
-#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX) && defined(CONFIG_440GX)
-/* We can switch Ethernet clock to the internal source through SDR0_MFR[ECS],
- * unfortunately this is less flexible than 440EP case, because it's a global
- * setting for all EMACs, therefore we do this clock trick only during probe.
- */
-#define EMAC_CLK_INTERNAL SDR_WRITE(DCRN_SDR_MFR, \
- SDR_READ(DCRN_SDR_MFR) | 0x08000000)
-#define EMAC_CLK_EXTERNAL SDR_WRITE(DCRN_SDR_MFR, \
- SDR_READ(DCRN_SDR_MFR) & ~0x08000000)
-#else
-#define EMAC_CLK_INTERNAL ((void)0)
-#define EMAC_CLK_EXTERNAL ((void)0)
-#endif
-
-/* I don't want to litter system log with timeout errors
- * when we have brain-damaged PHY.
- */
-static inline void emac_report_timeout_error(struct ocp_enet_private *dev,
- const char *error)
-{
-#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
- DBG("%d: %s" NL, dev->def->index, error);
-#else
- if (net_ratelimit())
- printk(KERN_ERR "emac%d: %s\n", dev->def->index, error);
-#endif
-}
-
-/* PHY polling intervals */
-#define PHY_POLL_LINK_ON HZ
-#define PHY_POLL_LINK_OFF (HZ / 5)
-
-/* Graceful stop timeouts in us.
- * We should allow up to 1 frame time (full-duplex, ignoring collisions)
- */
-#define STOP_TIMEOUT_10 1230
-#define STOP_TIMEOUT_100 124
-#define STOP_TIMEOUT_1000 13
-#define STOP_TIMEOUT_1000_JUMBO 73
-
-/* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
-static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
- "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
- "tx_packets_csum", "tx_undo", "rx_dropped_stack", "rx_dropped_oom",
- "rx_dropped_error", "rx_dropped_resize", "rx_dropped_mtu",
- "rx_stopped", "rx_bd_errors", "rx_bd_overrun", "rx_bd_bad_packet",
- "rx_bd_runt_packet", "rx_bd_short_event", "rx_bd_alignment_error",
- "rx_bd_bad_fcs", "rx_bd_packet_too_long", "rx_bd_out_of_range",
- "rx_bd_in_range", "rx_parity", "rx_fifo_overrun", "rx_overrun",
- "rx_bad_packet", "rx_runt_packet", "rx_short_event",
- "rx_alignment_error", "rx_bad_fcs", "rx_packet_too_long",
- "rx_out_of_range", "rx_in_range", "tx_dropped", "tx_bd_errors",
- "tx_bd_bad_fcs", "tx_bd_carrier_loss", "tx_bd_excessive_deferral",
- "tx_bd_excessive_collisions", "tx_bd_late_collision",
- "tx_bd_multple_collisions", "tx_bd_single_collision",
- "tx_bd_underrun", "tx_bd_sqe", "tx_parity", "tx_underrun", "tx_sqe",
- "tx_errors"
-};
-
-static irqreturn_t emac_irq(int irq, void *dev_instance);
-static void emac_clean_tx_ring(struct ocp_enet_private *dev);
-
-static inline int emac_phy_supports_gige(int phy_mode)
-{
- return phy_mode == PHY_MODE_GMII ||
- phy_mode == PHY_MODE_RGMII ||
- phy_mode == PHY_MODE_TBI ||
- phy_mode == PHY_MODE_RTBI;
-}
-
-static inline int emac_phy_gpcs(int phy_mode)
-{
- return phy_mode == PHY_MODE_TBI ||
- phy_mode == PHY_MODE_RTBI;
-}
-
-static inline void emac_tx_enable(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- unsigned long flags;
- u32 r;
-
- local_irq_save(flags);
-
- DBG("%d: tx_enable" NL, dev->def->index);
-
- r = in_be32(&p->mr0);
- if (!(r & EMAC_MR0_TXE))
- out_be32(&p->mr0, r | EMAC_MR0_TXE);
- local_irq_restore(flags);
-}
-
-static void emac_tx_disable(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- unsigned long flags;
- u32 r;
-
- local_irq_save(flags);
-
- DBG("%d: tx_disable" NL, dev->def->index);
-
- r = in_be32(&p->mr0);
- if (r & EMAC_MR0_TXE) {
- int n = dev->stop_timeout;
- out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
- while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) {
- udelay(1);
- --n;
- }
- if (unlikely(!n))
- emac_report_timeout_error(dev, "TX disable timeout");
- }
- local_irq_restore(flags);
-}
-
-static void emac_rx_enable(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- unsigned long flags;
- u32 r;
-
- local_irq_save(flags);
- if (unlikely(dev->commac.rx_stopped))
- goto out;
-
- DBG("%d: rx_enable" NL, dev->def->index);
-
- r = in_be32(&p->mr0);
- if (!(r & EMAC_MR0_RXE)) {
- if (unlikely(!(r & EMAC_MR0_RXI))) {
- /* Wait if previous async disable is still in progress */
- int n = dev->stop_timeout;
- while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
- udelay(1);
- --n;
- }
- if (unlikely(!n))
- emac_report_timeout_error(dev,
- "RX disable timeout");
- }
- out_be32(&p->mr0, r | EMAC_MR0_RXE);
- }
- out:
- local_irq_restore(flags);
-}
-
-static void emac_rx_disable(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- unsigned long flags;
- u32 r;
-
- local_irq_save(flags);
-
- DBG("%d: rx_disable" NL, dev->def->index);
-
- r = in_be32(&p->mr0);
- if (r & EMAC_MR0_RXE) {
- int n = dev->stop_timeout;
- out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
- while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
- udelay(1);
- --n;
- }
- if (unlikely(!n))
- emac_report_timeout_error(dev, "RX disable timeout");
- }
- local_irq_restore(flags);
-}
-
-static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- unsigned long flags;
- u32 r;
-
- local_irq_save(flags);
-
- DBG("%d: rx_disable_async" NL, dev->def->index);
-
- r = in_be32(&p->mr0);
- if (r & EMAC_MR0_RXE)
- out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
- local_irq_restore(flags);
-}
-
-static int emac_reset(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- unsigned long flags;
- int n = 20;
-
- DBG("%d: reset" NL, dev->def->index);
-
- local_irq_save(flags);
-
- if (!dev->reset_failed) {
- /* 40x erratum suggests stopping RX channel before reset,
- * we stop TX as well
- */
- emac_rx_disable(dev);
- emac_tx_disable(dev);
- }
-
- out_be32(&p->mr0, EMAC_MR0_SRST);
- while ((in_be32(&p->mr0) & EMAC_MR0_SRST) && n)
- --n;
- local_irq_restore(flags);
-
- if (n) {
- dev->reset_failed = 0;
- return 0;
- } else {
- emac_report_timeout_error(dev, "reset timeout");
- dev->reset_failed = 1;
- return -ETIMEDOUT;
- }
-}
-
-static void emac_hash_mc(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- u16 gaht[4] = { 0 };
- struct dev_mc_list *dmi;
-
- DBG("%d: hash_mc %d" NL, dev->def->index, dev->ndev->mc_count);
-
- for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
- int bit;
- DECLARE_MAC_BUF(mac);
- DBG2("%d: mc %s" NL,
- dev->def->index, print_mac(mac, dmi->dmi_addr));
-
- bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
- gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
- }
- out_be32(&p->gaht1, gaht[0]);
- out_be32(&p->gaht2, gaht[1]);
- out_be32(&p->gaht3, gaht[2]);
- out_be32(&p->gaht4, gaht[3]);
-}
-
-static inline u32 emac_iff2rmr(struct net_device *ndev)
-{
- u32 r = EMAC_RMR_SP | EMAC_RMR_SFCS | EMAC_RMR_IAE | EMAC_RMR_BAE |
- EMAC_RMR_BASE;
-
- if (ndev->flags & IFF_PROMISC)
- r |= EMAC_RMR_PME;
- else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
- r |= EMAC_RMR_PMME;
- else if (ndev->mc_count > 0)
- r |= EMAC_RMR_MAE;
-
- return r;
-}
-
-static inline int emac_opb_mhz(void)
-{
- return (ocp_sys_info.opb_bus_freq + 500000) / 1000000;
-}
-
-/* BHs disabled */
-static int emac_configure(struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
- struct net_device *ndev = dev->ndev;
- int gige;
- u32 r;
-
- DBG("%d: configure" NL, dev->def->index);
-
- if (emac_reset(dev) < 0)
- return -ETIMEDOUT;
-
- tah_reset(dev->tah_dev);
-
- /* Mode register */
- r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
- if (dev->phy.duplex == DUPLEX_FULL)
- r |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
- dev->stop_timeout = STOP_TIMEOUT_10;
- switch (dev->phy.speed) {
- case SPEED_1000:
- if (emac_phy_gpcs(dev->phy.mode)) {
- r |= EMAC_MR1_MF_1000GPCS |
- EMAC_MR1_MF_IPPA(dev->phy.address);
-
- /* Put some arbitrary OUI, Manuf & Rev IDs so we can
- * identify this GPCS PHY later.
- */
- out_be32(&p->ipcr, 0xdeadbeef);
- } else
- r |= EMAC_MR1_MF_1000;
- r |= EMAC_MR1_RFS_16K;
- gige = 1;
-
- if (dev->ndev->mtu > ETH_DATA_LEN) {
- r |= EMAC_MR1_JPSM;
- dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO;
- } else
- dev->stop_timeout = STOP_TIMEOUT_1000;
- break;
- case SPEED_100:
- r |= EMAC_MR1_MF_100;
- dev->stop_timeout = STOP_TIMEOUT_100;
- /* Fall through */
- default:
- r |= EMAC_MR1_RFS_4K;
- gige = 0;
- break;
- }
-
- if (dev->rgmii_dev)
- rgmii_set_speed(dev->rgmii_dev, dev->rgmii_input,
- dev->phy.speed);
- else
- zmii_set_speed(dev->zmii_dev, dev->zmii_input, dev->phy.speed);
-
-#if !defined(CONFIG_40x)
- /* on 40x erratum forces us to NOT use integrated flow control,
- * let's hope it works on 44x ;)
- */
- if (dev->phy.duplex == DUPLEX_FULL) {
- if (dev->phy.pause)
- r |= EMAC_MR1_EIFC | EMAC_MR1_APP;
- else if (dev->phy.asym_pause)
- r |= EMAC_MR1_APP;
- }
-#endif
- out_be32(&p->mr1, r);
-
- /* Set individual MAC address */
- out_be32(&p->iahr, (ndev->dev_addr[0] << 8) | ndev->dev_addr[1]);
- out_be32(&p->ialr, (ndev->dev_addr[2] << 24) |
- (ndev->dev_addr[3] << 16) | (ndev->dev_addr[4] << 8) |
- ndev->dev_addr[5]);
-
- /* VLAN Tag Protocol ID */
- out_be32(&p->vtpid, 0x8100);
-
- /* Receive mode register */
- r = emac_iff2rmr(ndev);
- if (r & EMAC_RMR_MAE)
- emac_hash_mc(dev);
- out_be32(&p->rmr, r);
-
- /* FIFOs thresholds */
- r = EMAC_TMR1((EMAC_MAL_BURST_SIZE / EMAC_FIFO_ENTRY_SIZE) + 1,
- EMAC_TX_FIFO_SIZE / 2 / EMAC_FIFO_ENTRY_SIZE);
- out_be32(&p->tmr1, r);
- out_be32(&p->trtr, EMAC_TRTR(EMAC_TX_FIFO_SIZE / 2));
-
- /* PAUSE frame is sent when RX FIFO reaches its high-water mark,
- there should be still enough space in FIFO to allow the our link
- partner time to process this frame and also time to send PAUSE
- frame itself.
-
- Here is the worst case scenario for the RX FIFO "headroom"
- (from "The Switch Book") (100Mbps, without preamble, inter-frame gap):
-
- 1) One maximum-length frame on TX 1522 bytes
- 2) One PAUSE frame time 64 bytes
- 3) PAUSE frame decode time allowance 64 bytes
- 4) One maximum-length frame on RX 1522 bytes
- 5) Round-trip propagation delay of the link (100Mb) 15 bytes
- ----------
- 3187 bytes
-
- I chose to set high-water mark to RX_FIFO_SIZE / 4 (1024 bytes)
- low-water mark to RX_FIFO_SIZE / 8 (512 bytes)
- */
- r = EMAC_RWMR(EMAC_RX_FIFO_SIZE(gige) / 8 / EMAC_FIFO_ENTRY_SIZE,
- EMAC_RX_FIFO_SIZE(gige) / 4 / EMAC_FIFO_ENTRY_SIZE);
- out_be32(&p->rwmr, r);
-
- /* Set PAUSE timer to the maximum */
- out_be32(&p->ptr, 0xffff);
-
- /* IRQ sources */
- out_be32(&p->iser, EMAC_ISR_TXPE | EMAC_ISR_RXPE | /* EMAC_ISR_TXUE |
- EMAC_ISR_RXOE | */ EMAC_ISR_OVR | EMAC_ISR_BP | EMAC_ISR_SE |
- EMAC_ISR_ALE | EMAC_ISR_BFCS | EMAC_ISR_PTLE | EMAC_ISR_ORE |
- EMAC_ISR_IRE | EMAC_ISR_TE);
-
- /* We need to take GPCS PHY out of isolate mode after EMAC reset */
- if (emac_phy_gpcs(dev->phy.mode))
- mii_reset_phy(&dev->phy);
-
- return 0;
-}
-
-/* BHs disabled */
-static void emac_reinitialize(struct ocp_enet_private *dev)
-{
- DBG("%d: reinitialize" NL, dev->def->index);
-
- if (!emac_configure(dev)) {
- emac_tx_enable(dev);
- emac_rx_enable(dev);
- }
-}
-
-/* BHs disabled */
-static void emac_full_tx_reset(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- struct ocp_func_emac_data *emacdata = dev->def->additions;
-
- DBG("%d: full_tx_reset" NL, dev->def->index);
-
- emac_tx_disable(dev);
- mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
- emac_clean_tx_ring(dev);
- dev->tx_cnt = dev->tx_slot = dev->ack_slot = 0;
-
- emac_configure(dev);
-
- mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
- emac_tx_enable(dev);
- emac_rx_enable(dev);
-
- netif_wake_queue(ndev);
-}
-
-static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
-{
- struct emac_regs __iomem *p = dev->emacp;
- u32 r;
- int n;
-
- DBG2("%d: mdio_read(%02x,%02x)" NL, dev->def->index, id, reg);
-
- /* Enable proper MDIO port */
- zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
-
- /* Wait for management interface to become idle */
- n = 10;
- while (!emac_phy_done(in_be32(&p->stacr))) {
- udelay(1);
- if (!--n)
- goto to;
- }
-
- /* Issue read command */
- out_be32(&p->stacr,
- EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_READ |
- (reg & EMAC_STACR_PRA_MASK)
- | ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT)
- | EMAC_STACR_START);
-
- /* Wait for read to complete */
- n = 100;
- while (!emac_phy_done(r = in_be32(&p->stacr))) {
- udelay(1);
- if (!--n)
- goto to;
- }
-
- if (unlikely(r & EMAC_STACR_PHYE)) {
- DBG("%d: mdio_read(%02x, %02x) failed" NL, dev->def->index,
- id, reg);
- return -EREMOTEIO;
- }
-
- r = ((r >> EMAC_STACR_PHYD_SHIFT) & EMAC_STACR_PHYD_MASK);
- DBG2("%d: mdio_read -> %04x" NL, dev->def->index, r);
- return r;
- to:
- DBG("%d: MII management interface timeout (read)" NL, dev->def->index);
- return -ETIMEDOUT;
-}
-
-static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg,
- u16 val)
-{
- struct emac_regs __iomem *p = dev->emacp;
- int n;
-
- DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg,
- val);
-
- /* Enable proper MDIO port */
- zmii_enable_mdio(dev->zmii_dev, dev->zmii_input);
-
- /* Wait for management interface to be idle */
- n = 10;
- while (!emac_phy_done(in_be32(&p->stacr))) {
- udelay(1);
- if (!--n)
- goto to;
- }
-
- /* Issue write command */
- out_be32(&p->stacr,
- EMAC_STACR_BASE(emac_opb_mhz()) | EMAC_STACR_STAC_WRITE |
- (reg & EMAC_STACR_PRA_MASK) |
- ((id & EMAC_STACR_PCDA_MASK) << EMAC_STACR_PCDA_SHIFT) |
- (val << EMAC_STACR_PHYD_SHIFT) | EMAC_STACR_START);
-
- /* Wait for write to complete */
- n = 100;
- while (!emac_phy_done(in_be32(&p->stacr))) {
- udelay(1);
- if (!--n)
- goto to;
- }
- return;
- to:
- DBG("%d: MII management interface timeout (write)" NL, dev->def->index);
-}
-
-static int emac_mdio_read(struct net_device *ndev, int id, int reg)
-{
- struct ocp_enet_private *dev = ndev->priv;
- int res;
-
- local_bh_disable();
- res = __emac_mdio_read(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
- (u8) reg);
- local_bh_enable();
- return res;
-}
-
-static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
-{
- struct ocp_enet_private *dev = ndev->priv;
-
- local_bh_disable();
- __emac_mdio_write(dev->mdio_dev ? dev->mdio_dev : dev, (u8) id,
- (u8) reg, (u16) val);
- local_bh_enable();
-}
-
-/* BHs disabled */
-static void emac_set_multicast_list(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- struct emac_regs __iomem *p = dev->emacp;
- u32 rmr = emac_iff2rmr(ndev);
-
- DBG("%d: multicast %08x" NL, dev->def->index, rmr);
- BUG_ON(!netif_running(dev->ndev));
-
- /* I decided to relax register access rules here to avoid
- * full EMAC reset.
- *
- * There is a real problem with EMAC4 core if we use MWSW_001 bit
- * in MR1 register and do a full EMAC reset.
- * One TX BD status update is delayed and, after EMAC reset, it
- * never happens, resulting in TX hung (it'll be recovered by TX
- * timeout handler eventually, but this is just gross).
- * So we either have to do full TX reset or try to cheat here :)
- *
- * The only required change is to RX mode register, so I *think* all
- * we need is just to stop RX channel. This seems to work on all
- * tested SoCs. --ebs
- */
- emac_rx_disable(dev);
- if (rmr & EMAC_RMR_MAE)
- emac_hash_mc(dev);
- out_be32(&p->rmr, rmr);
- emac_rx_enable(dev);
-}
-
-/* BHs disabled */
-static int emac_resize_rx_ring(struct ocp_enet_private *dev, int new_mtu)
-{
- struct ocp_func_emac_data *emacdata = dev->def->additions;
- int rx_sync_size = emac_rx_sync_size(new_mtu);
- int rx_skb_size = emac_rx_skb_size(new_mtu);
- int i, ret = 0;
-
- emac_rx_disable(dev);
- mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
-
- if (dev->rx_sg_skb) {
- ++dev->estats.rx_dropped_resize;
- dev_kfree_skb(dev->rx_sg_skb);
- dev->rx_sg_skb = NULL;
- }
-
- /* Make a first pass over RX ring and mark BDs ready, dropping
- * non-processed packets on the way. We need this as a separate pass
- * to simplify error recovery in the case of allocation failure later.
- */
- for (i = 0; i < NUM_RX_BUFF; ++i) {
- if (dev->rx_desc[i].ctrl & MAL_RX_CTRL_FIRST)
- ++dev->estats.rx_dropped_resize;
-
- dev->rx_desc[i].data_len = 0;
- dev->rx_desc[i].ctrl = MAL_RX_CTRL_EMPTY |
- (i == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
- }
-
- /* Reallocate RX ring only if bigger skb buffers are required */
- if (rx_skb_size <= dev->rx_skb_size)
- goto skip;
-
- /* Second pass, allocate new skbs */
- for (i = 0; i < NUM_RX_BUFF; ++i) {
- struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
- if (!skb) {
- ret = -ENOMEM;
- goto oom;
- }
-
- BUG_ON(!dev->rx_skb[i]);
- dev_kfree_skb(dev->rx_skb[i]);
-
- skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
- dev->rx_desc[i].data_ptr =
- dma_map_single(dev->ldev, skb->data - 2, rx_sync_size,
- DMA_FROM_DEVICE) + 2;
- dev->rx_skb[i] = skb;
- }
- skip:
- /* Check if we need to change "Jumbo" bit in MR1 */
- if ((new_mtu > ETH_DATA_LEN) ^ (dev->ndev->mtu > ETH_DATA_LEN)) {
- /* This is to prevent starting RX channel in emac_rx_enable() */
- dev->commac.rx_stopped = 1;
-
- dev->ndev->mtu = new_mtu;
- emac_full_tx_reset(dev->ndev);
- }
-
- mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(new_mtu));
- oom:
- /* Restart RX */
- dev->commac.rx_stopped = dev->rx_slot = 0;
- mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
- emac_rx_enable(dev);
-
- return ret;
-}
-
-/* Process ctx, rtnl_lock semaphore */
-static int emac_change_mtu(struct net_device *ndev, int new_mtu)
-{
- struct ocp_enet_private *dev = ndev->priv;
- int ret = 0;
-
- if (new_mtu < EMAC_MIN_MTU || new_mtu > EMAC_MAX_MTU)
- return -EINVAL;
-
- DBG("%d: change_mtu(%d)" NL, dev->def->index, new_mtu);
-
- local_bh_disable();
- if (netif_running(ndev)) {
- /* Check if we really need to reinitalize RX ring */
- if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu))
- ret = emac_resize_rx_ring(dev, new_mtu);
- }
-
- if (!ret) {
- ndev->mtu = new_mtu;
- dev->rx_skb_size = emac_rx_skb_size(new_mtu);
- dev->rx_sync_size = emac_rx_sync_size(new_mtu);
- }
- local_bh_enable();
-
- return ret;
-}
-
-static void emac_clean_tx_ring(struct ocp_enet_private *dev)
-{
- int i;
- for (i = 0; i < NUM_TX_BUFF; ++i) {
- if (dev->tx_skb[i]) {
- dev_kfree_skb(dev->tx_skb[i]);
- dev->tx_skb[i] = NULL;
- if (dev->tx_desc[i].ctrl & MAL_TX_CTRL_READY)
- ++dev->estats.tx_dropped;
- }
- dev->tx_desc[i].ctrl = 0;
- dev->tx_desc[i].data_ptr = 0;
- }
-}
-
-static void emac_clean_rx_ring(struct ocp_enet_private *dev)
-{
- int i;
- for (i = 0; i < NUM_RX_BUFF; ++i)
- if (dev->rx_skb[i]) {
- dev->rx_desc[i].ctrl = 0;
- dev_kfree_skb(dev->rx_skb[i]);
- dev->rx_skb[i] = NULL;
- dev->rx_desc[i].data_ptr = 0;
- }
-
- if (dev->rx_sg_skb) {
- dev_kfree_skb(dev->rx_sg_skb);
- dev->rx_sg_skb = NULL;
- }
-}
-
-static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot,
- gfp_t flags)
-{
- struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
- if (unlikely(!skb))
- return -ENOMEM;
-
- dev->rx_skb[slot] = skb;
- dev->rx_desc[slot].data_len = 0;
-
- skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
- dev->rx_desc[slot].data_ptr =
- dma_map_single(dev->ldev, skb->data - 2, dev->rx_sync_size,
- DMA_FROM_DEVICE) + 2;
- barrier();
- dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
- (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
-
- return 0;
-}
-
-static void emac_print_link_status(struct ocp_enet_private *dev)
-{
- if (netif_carrier_ok(dev->ndev))
- printk(KERN_INFO "%s: link is up, %d %s%s\n",
- dev->ndev->name, dev->phy.speed,
- dev->phy.duplex == DUPLEX_FULL ? "FDX" : "HDX",
- dev->phy.pause ? ", pause enabled" :
- dev->phy.asym_pause ? ", assymetric pause enabled" : "");
- else
- printk(KERN_INFO "%s: link is down\n", dev->ndev->name);
-}
-
-/* Process ctx, rtnl_lock semaphore */
-static int emac_open(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- struct ocp_func_emac_data *emacdata = dev->def->additions;
- int err, i;
-
- DBG("%d: open" NL, dev->def->index);
-
- /* Setup error IRQ handler */
- err = request_irq(dev->def->irq, emac_irq, 0, "EMAC", dev);
- if (err) {
- printk(KERN_ERR "%s: failed to request IRQ %d\n",
- ndev->name, dev->def->irq);
- return err;
- }
-
- /* Allocate RX ring */
- for (i = 0; i < NUM_RX_BUFF; ++i)
- if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
- printk(KERN_ERR "%s: failed to allocate RX ring\n",
- ndev->name);
- goto oom;
- }
-
- local_bh_disable();
- dev->tx_cnt = dev->tx_slot = dev->ack_slot = dev->rx_slot =
- dev->commac.rx_stopped = 0;
- dev->rx_sg_skb = NULL;
-
- if (dev->phy.address >= 0) {
- int link_poll_interval;
- if (dev->phy.def->ops->poll_link(&dev->phy)) {
- dev->phy.def->ops->read_link(&dev->phy);
- EMAC_RX_CLK_DEFAULT(dev->def->index);
- netif_carrier_on(dev->ndev);
- link_poll_interval = PHY_POLL_LINK_ON;
- } else {
- EMAC_RX_CLK_TX(dev->def->index);
- netif_carrier_off(dev->ndev);
- link_poll_interval = PHY_POLL_LINK_OFF;
- }
- mod_timer(&dev->link_timer, jiffies + link_poll_interval);
- emac_print_link_status(dev);
- } else
- netif_carrier_on(dev->ndev);
-
- emac_configure(dev);
- mal_poll_add(dev->mal, &dev->commac);
- mal_enable_tx_channel(dev->mal, emacdata->mal_tx_chan);
- mal_set_rcbs(dev->mal, emacdata->mal_rx_chan, emac_rx_size(ndev->mtu));
- mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
- emac_tx_enable(dev);
- emac_rx_enable(dev);
- netif_start_queue(ndev);
- local_bh_enable();
-
- return 0;
- oom:
- emac_clean_rx_ring(dev);
- free_irq(dev->def->irq, dev);
- return -ENOMEM;
-}
-
-/* BHs disabled */
-static int emac_link_differs(struct ocp_enet_private *dev)
-{
- u32 r = in_be32(&dev->emacp->mr1);
-
- int duplex = r & EMAC_MR1_FDE ? DUPLEX_FULL : DUPLEX_HALF;
- int speed, pause, asym_pause;
-
- if (r & EMAC_MR1_MF_1000)
- speed = SPEED_1000;
- else if (r & EMAC_MR1_MF_100)
- speed = SPEED_100;
- else
- speed = SPEED_10;
-
- switch (r & (EMAC_MR1_EIFC | EMAC_MR1_APP)) {
- case (EMAC_MR1_EIFC | EMAC_MR1_APP):
- pause = 1;
- asym_pause = 0;
- break;
- case EMAC_MR1_APP:
- pause = 0;
- asym_pause = 1;
- break;
- default:
- pause = asym_pause = 0;
- }
- return speed != dev->phy.speed || duplex != dev->phy.duplex ||
- pause != dev->phy.pause || asym_pause != dev->phy.asym_pause;
-}
-
-/* BHs disabled */
-static void emac_link_timer(unsigned long data)
-{
- struct ocp_enet_private *dev = (struct ocp_enet_private *)data;
- int link_poll_interval;
-
- DBG2("%d: link timer" NL, dev->def->index);
-
- if (dev->phy.def->ops->poll_link(&dev->phy)) {
- if (!netif_carrier_ok(dev->ndev)) {
- EMAC_RX_CLK_DEFAULT(dev->def->index);
-
- /* Get new link parameters */
- dev->phy.def->ops->read_link(&dev->phy);
-
- if (dev->tah_dev || emac_link_differs(dev))
- emac_full_tx_reset(dev->ndev);
-
- netif_carrier_on(dev->ndev);
- emac_print_link_status(dev);
- }
- link_poll_interval = PHY_POLL_LINK_ON;
- } else {
- if (netif_carrier_ok(dev->ndev)) {
- EMAC_RX_CLK_TX(dev->def->index);
-#if defined(CONFIG_IBM_EMAC_PHY_RX_CLK_FIX)
- emac_reinitialize(dev);
-#endif
- netif_carrier_off(dev->ndev);
- emac_print_link_status(dev);
- }
-
- /* Retry reset if the previous attempt failed.
- * This is needed mostly for CONFIG_IBM_EMAC_PHY_RX_CLK_FIX
- * case, but I left it here because it shouldn't trigger for
- * sane PHYs anyway.
- */
- if (unlikely(dev->reset_failed))
- emac_reinitialize(dev);
-
- link_poll_interval = PHY_POLL_LINK_OFF;
- }
- mod_timer(&dev->link_timer, jiffies + link_poll_interval);
-}
-
-/* BHs disabled */
-static void emac_force_link_update(struct ocp_enet_private *dev)
-{
- netif_carrier_off(dev->ndev);
- if (timer_pending(&dev->link_timer))
- mod_timer(&dev->link_timer, jiffies + PHY_POLL_LINK_OFF);
-}
-
-/* Process ctx, rtnl_lock semaphore */
-static int emac_close(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- struct ocp_func_emac_data *emacdata = dev->def->additions;
-
- DBG("%d: close" NL, dev->def->index);
-
- local_bh_disable();
-
- if (dev->phy.address >= 0)
- del_timer_sync(&dev->link_timer);
-
- netif_stop_queue(ndev);
- emac_rx_disable(dev);
- emac_tx_disable(dev);
- mal_disable_rx_channel(dev->mal, emacdata->mal_rx_chan);
- mal_disable_tx_channel(dev->mal, emacdata->mal_tx_chan);
- mal_poll_del(dev->mal, &dev->commac);
- local_bh_enable();
-
- emac_clean_tx_ring(dev);
- emac_clean_rx_ring(dev);
- free_irq(dev->def->irq, dev);
-
- return 0;
-}
-
-static inline u16 emac_tx_csum(struct ocp_enet_private *dev,
- struct sk_buff *skb)
-{
-#if defined(CONFIG_IBM_EMAC_TAH)
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- ++dev->stats.tx_packets_csum;
- return EMAC_TX_CTRL_TAH_CSUM;
- }
-#endif
- return 0;
-}
-
-static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len)
-{
- struct emac_regs __iomem *p = dev->emacp;
- struct net_device *ndev = dev->ndev;
-
- /* Send the packet out */
- out_be32(&p->tmr0, EMAC_TMR0_XMIT);
-
- if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) {
- netif_stop_queue(ndev);
- DBG2("%d: stopped TX queue" NL, dev->def->index);
- }
-
- ndev->trans_start = jiffies;
- ++dev->stats.tx_packets;
- dev->stats.tx_bytes += len;
-
- return 0;
-}
-
-/* BHs disabled */
-static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- unsigned int len = skb->len;
- int slot;
-
- u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
- MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
-
- slot = dev->tx_slot++;
- if (dev->tx_slot == NUM_TX_BUFF) {
- dev->tx_slot = 0;
- ctrl |= MAL_TX_CTRL_WRAP;
- }
-
- DBG2("%d: xmit(%u) %d" NL, dev->def->index, len, slot);
-
- dev->tx_skb[slot] = skb;
- dev->tx_desc[slot].data_ptr = dma_map_single(dev->ldev, skb->data, len,
- DMA_TO_DEVICE);
- dev->tx_desc[slot].data_len = (u16) len;
- barrier();
- dev->tx_desc[slot].ctrl = ctrl;
-
- return emac_xmit_finish(dev, len);
-}
-
-#if defined(CONFIG_IBM_EMAC_TAH)
-static inline int emac_xmit_split(struct ocp_enet_private *dev, int slot,
- u32 pd, int len, int last, u16 base_ctrl)
-{
- while (1) {
- u16 ctrl = base_ctrl;
- int chunk = min(len, MAL_MAX_TX_SIZE);
- len -= chunk;
-
- slot = (slot + 1) % NUM_TX_BUFF;
-
- if (last && !len)
- ctrl |= MAL_TX_CTRL_LAST;
- if (slot == NUM_TX_BUFF - 1)
- ctrl |= MAL_TX_CTRL_WRAP;
-
- dev->tx_skb[slot] = NULL;
- dev->tx_desc[slot].data_ptr = pd;
- dev->tx_desc[slot].data_len = (u16) chunk;
- dev->tx_desc[slot].ctrl = ctrl;
- ++dev->tx_cnt;
-
- if (!len)
- break;
-
- pd += chunk;
- }
- return slot;
-}
-
-/* BHs disabled (SG version for TAH equipped EMACs) */
-static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- int nr_frags = skb_shinfo(skb)->nr_frags;
- int len = skb->len, chunk;
- int slot, i;
- u16 ctrl;
- u32 pd;
-
- /* This is common "fast" path */
- if (likely(!nr_frags && len <= MAL_MAX_TX_SIZE))
- return emac_start_xmit(skb, ndev);
-
- len -= skb->data_len;
-
- /* Note, this is only an *estimation*, we can still run out of empty
- * slots because of the additional fragmentation into
- * MAL_MAX_TX_SIZE-sized chunks
- */
- if (unlikely(dev->tx_cnt + nr_frags + mal_tx_chunks(len) > NUM_TX_BUFF))
- goto stop_queue;
-
- ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
- emac_tx_csum(dev, skb);
- slot = dev->tx_slot;
-
- /* skb data */
- dev->tx_skb[slot] = NULL;
- chunk = min(len, MAL_MAX_TX_SIZE);
- dev->tx_desc[slot].data_ptr = pd =
- dma_map_single(dev->ldev, skb->data, len, DMA_TO_DEVICE);
- dev->tx_desc[slot].data_len = (u16) chunk;
- len -= chunk;
- if (unlikely(len))
- slot = emac_xmit_split(dev, slot, pd + chunk, len, !nr_frags,
- ctrl);
- /* skb fragments */
- for (i = 0; i < nr_frags; ++i) {
- struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
- len = frag->size;
-
- if (unlikely(dev->tx_cnt + mal_tx_chunks(len) >= NUM_TX_BUFF))
- goto undo_frame;
-
- pd = dma_map_page(dev->ldev, frag->page, frag->page_offset, len,
- DMA_TO_DEVICE);
-
- slot = emac_xmit_split(dev, slot, pd, len, i == nr_frags - 1,
- ctrl);
- }
-
- DBG2("%d: xmit_sg(%u) %d - %d" NL, dev->def->index, skb->len,
- dev->tx_slot, slot);
-
- /* Attach skb to the last slot so we don't release it too early */
- dev->tx_skb[slot] = skb;
-
- /* Send the packet out */
- if (dev->tx_slot == NUM_TX_BUFF - 1)
- ctrl |= MAL_TX_CTRL_WRAP;
- barrier();
- dev->tx_desc[dev->tx_slot].ctrl = ctrl;
- dev->tx_slot = (slot + 1) % NUM_TX_BUFF;
-
- return emac_xmit_finish(dev, skb->len);
-
- undo_frame:
- /* Well, too bad. Our previous estimation was overly optimistic.
- * Undo everything.
- */
- while (slot != dev->tx_slot) {
- dev->tx_desc[slot].ctrl = 0;
- --dev->tx_cnt;
- if (--slot < 0)
- slot = NUM_TX_BUFF - 1;
- }
- ++dev->estats.tx_undo;
-
- stop_queue:
- netif_stop_queue(ndev);
- DBG2("%d: stopped TX queue" NL, dev->def->index);
- return 1;
-}
-#else
-# define emac_start_xmit_sg emac_start_xmit
-#endif /* !defined(CONFIG_IBM_EMAC_TAH) */
-
-/* BHs disabled */
-static void emac_parse_tx_error(struct ocp_enet_private *dev, u16 ctrl)
-{
- struct ibm_emac_error_stats *st = &dev->estats;
- DBG("%d: BD TX error %04x" NL, dev->def->index, ctrl);
-
- ++st->tx_bd_errors;
- if (ctrl & EMAC_TX_ST_BFCS)
- ++st->tx_bd_bad_fcs;
- if (ctrl & EMAC_TX_ST_LCS)
- ++st->tx_bd_carrier_loss;
- if (ctrl & EMAC_TX_ST_ED)
- ++st->tx_bd_excessive_deferral;
- if (ctrl & EMAC_TX_ST_EC)
- ++st->tx_bd_excessive_collisions;
- if (ctrl & EMAC_TX_ST_LC)
- ++st->tx_bd_late_collision;
- if (ctrl & EMAC_TX_ST_MC)
- ++st->tx_bd_multple_collisions;
- if (ctrl & EMAC_TX_ST_SC)
- ++st->tx_bd_single_collision;
- if (ctrl & EMAC_TX_ST_UR)
- ++st->tx_bd_underrun;
- if (ctrl & EMAC_TX_ST_SQE)
- ++st->tx_bd_sqe;
-}
-
-static void emac_poll_tx(void *param)
-{
- struct ocp_enet_private *dev = param;
- DBG2("%d: poll_tx, %d %d" NL, dev->def->index, dev->tx_cnt,
- dev->ack_slot);
-
- if (dev->tx_cnt) {
- u16 ctrl;
- int slot = dev->ack_slot, n = 0;
- again:
- ctrl = dev->tx_desc[slot].ctrl;
- if (!(ctrl & MAL_TX_CTRL_READY)) {
- struct sk_buff *skb = dev->tx_skb[slot];
- ++n;
-
- if (skb) {
- dev_kfree_skb(skb);
- dev->tx_skb[slot] = NULL;
- }
- slot = (slot + 1) % NUM_TX_BUFF;
-
- if (unlikely(EMAC_IS_BAD_TX(ctrl)))
- emac_parse_tx_error(dev, ctrl);
-
- if (--dev->tx_cnt)
- goto again;
- }
- if (n) {
- dev->ack_slot = slot;
- if (netif_queue_stopped(dev->ndev) &&
- dev->tx_cnt < EMAC_TX_WAKEUP_THRESH)
- netif_wake_queue(dev->ndev);
-
- DBG2("%d: tx %d pkts" NL, dev->def->index, n);
- }
- }
-}
-
-static inline void emac_recycle_rx_skb(struct ocp_enet_private *dev, int slot,
- int len)
-{
- struct sk_buff *skb = dev->rx_skb[slot];
- DBG2("%d: recycle %d %d" NL, dev->def->index, slot, len);
-
- if (len)
- dma_map_single(dev->ldev, skb->data - 2,
- EMAC_DMA_ALIGN(len + 2), DMA_FROM_DEVICE);
-
- dev->rx_desc[slot].data_len = 0;
- barrier();
- dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
- (slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
-}
-
-static void emac_parse_rx_error(struct ocp_enet_private *dev, u16 ctrl)
-{
- struct ibm_emac_error_stats *st = &dev->estats;
- DBG("%d: BD RX error %04x" NL, dev->def->index, ctrl);
-
- ++st->rx_bd_errors;
- if (ctrl & EMAC_RX_ST_OE)
- ++st->rx_bd_overrun;
- if (ctrl & EMAC_RX_ST_BP)
- ++st->rx_bd_bad_packet;
- if (ctrl & EMAC_RX_ST_RP)
- ++st->rx_bd_runt_packet;
- if (ctrl & EMAC_RX_ST_SE)
- ++st->rx_bd_short_event;
- if (ctrl & EMAC_RX_ST_AE)
- ++st->rx_bd_alignment_error;
- if (ctrl & EMAC_RX_ST_BFCS)
- ++st->rx_bd_bad_fcs;
- if (ctrl & EMAC_RX_ST_PTL)
- ++st->rx_bd_packet_too_long;
- if (ctrl & EMAC_RX_ST_ORE)
- ++st->rx_bd_out_of_range;
- if (ctrl & EMAC_RX_ST_IRE)
- ++st->rx_bd_in_range;
-}
-
-static inline void emac_rx_csum(struct ocp_enet_private *dev,
- struct sk_buff *skb, u16 ctrl)
-{
-#if defined(CONFIG_IBM_EMAC_TAH)
- if (!ctrl && dev->tah_dev) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- ++dev->stats.rx_packets_csum;
- }
-#endif
-}
-
-static inline int emac_rx_sg_append(struct ocp_enet_private *dev, int slot)
-{
- if (likely(dev->rx_sg_skb != NULL)) {
- int len = dev->rx_desc[slot].data_len;
- int tot_len = dev->rx_sg_skb->len + len;
-
- if (unlikely(tot_len + 2 > dev->rx_skb_size)) {
- ++dev->estats.rx_dropped_mtu;
- dev_kfree_skb(dev->rx_sg_skb);
- dev->rx_sg_skb = NULL;
- } else {
- cacheable_memcpy(skb_tail_pointer(dev->rx_sg_skb),
- dev->rx_skb[slot]->data, len);
- skb_put(dev->rx_sg_skb, len);
- emac_recycle_rx_skb(dev, slot, len);
- return 0;
- }
- }
- emac_recycle_rx_skb(dev, slot, 0);
- return -1;
-}
-
-/* BHs disabled */
-static int emac_poll_rx(void *param, int budget)
-{
- struct ocp_enet_private *dev = param;
- int slot = dev->rx_slot, received = 0;
-
- DBG2("%d: poll_rx(%d)" NL, dev->def->index, budget);
-
- again:
- while (budget > 0) {
- int len;
- struct sk_buff *skb;
- u16 ctrl = dev->rx_desc[slot].ctrl;
-
- if (ctrl & MAL_RX_CTRL_EMPTY)
- break;
-
- skb = dev->rx_skb[slot];
- barrier();
- len = dev->rx_desc[slot].data_len;
-
- if (unlikely(!MAL_IS_SINGLE_RX(ctrl)))
- goto sg;
-
- ctrl &= EMAC_BAD_RX_MASK;
- if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
- emac_parse_rx_error(dev, ctrl);
- ++dev->estats.rx_dropped_error;
- emac_recycle_rx_skb(dev, slot, 0);
- len = 0;
- goto next;
- }
-
- if (len && len < EMAC_RX_COPY_THRESH) {
- struct sk_buff *copy_skb =
- alloc_skb(len + EMAC_RX_SKB_HEADROOM + 2, GFP_ATOMIC);
- if (unlikely(!copy_skb))
- goto oom;
-
- skb_reserve(copy_skb, EMAC_RX_SKB_HEADROOM + 2);
- cacheable_memcpy(copy_skb->data - 2, skb->data - 2,
- len + 2);
- emac_recycle_rx_skb(dev, slot, len);
- skb = copy_skb;
- } else if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC)))
- goto oom;
-
- skb_put(skb, len);
- push_packet:
- skb->protocol = eth_type_trans(skb, dev->ndev);
- emac_rx_csum(dev, skb, ctrl);
-
- if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
- ++dev->estats.rx_dropped_stack;
- next:
- ++dev->stats.rx_packets;
- skip:
- dev->stats.rx_bytes += len;
- slot = (slot + 1) % NUM_RX_BUFF;
- --budget;
- ++received;
- continue;
- sg:
- if (ctrl & MAL_RX_CTRL_FIRST) {
- BUG_ON(dev->rx_sg_skb);
- if (unlikely(emac_alloc_rx_skb(dev, slot, GFP_ATOMIC))) {
- DBG("%d: rx OOM %d" NL, dev->def->index, slot);
- ++dev->estats.rx_dropped_oom;
- emac_recycle_rx_skb(dev, slot, 0);
- } else {
- dev->rx_sg_skb = skb;
- skb_put(skb, len);
- }
- } else if (!emac_rx_sg_append(dev, slot) &&
- (ctrl & MAL_RX_CTRL_LAST)) {
-
- skb = dev->rx_sg_skb;
- dev->rx_sg_skb = NULL;
-
- ctrl &= EMAC_BAD_RX_MASK;
- if (unlikely(ctrl && ctrl != EMAC_RX_TAH_BAD_CSUM)) {
- emac_parse_rx_error(dev, ctrl);
- ++dev->estats.rx_dropped_error;
- dev_kfree_skb(skb);
- len = 0;
- } else
- goto push_packet;
- }
- goto skip;
- oom:
- DBG("%d: rx OOM %d" NL, dev->def->index, slot);
- /* Drop the packet and recycle skb */
- ++dev->estats.rx_dropped_oom;
- emac_recycle_rx_skb(dev, slot, 0);
- goto next;
- }
-
- if (received) {
- DBG2("%d: rx %d BDs" NL, dev->def->index, received);
- dev->rx_slot = slot;
- }
-
- if (unlikely(budget && dev->commac.rx_stopped)) {
- struct ocp_func_emac_data *emacdata = dev->def->additions;
-
- barrier();
- if (!(dev->rx_desc[slot].ctrl & MAL_RX_CTRL_EMPTY)) {
- DBG2("%d: rx restart" NL, dev->def->index);
- received = 0;
- goto again;
- }
-
- if (dev->rx_sg_skb) {
- DBG2("%d: dropping partial rx packet" NL,
- dev->def->index);
- ++dev->estats.rx_dropped_error;
- dev_kfree_skb(dev->rx_sg_skb);
- dev->rx_sg_skb = NULL;
- }
-
- dev->commac.rx_stopped = 0;
- mal_enable_rx_channel(dev->mal, emacdata->mal_rx_chan);
- emac_rx_enable(dev);
- dev->rx_slot = 0;
- }
- return received;
-}
-
-/* BHs disabled */
-static int emac_peek_rx(void *param)
-{
- struct ocp_enet_private *dev = param;
- return !(dev->rx_desc[dev->rx_slot].ctrl & MAL_RX_CTRL_EMPTY);
-}
-
-/* BHs disabled */
-static int emac_peek_rx_sg(void *param)
-{
- struct ocp_enet_private *dev = param;
- int slot = dev->rx_slot;
- while (1) {
- u16 ctrl = dev->rx_desc[slot].ctrl;
- if (ctrl & MAL_RX_CTRL_EMPTY)
- return 0;
- else if (ctrl & MAL_RX_CTRL_LAST)
- return 1;
-
- slot = (slot + 1) % NUM_RX_BUFF;
-
- /* I'm just being paranoid here :) */
- if (unlikely(slot == dev->rx_slot))
- return 0;
- }
-}
-
-/* Hard IRQ */
-static void emac_rxde(void *param)
-{
- struct ocp_enet_private *dev = param;
- ++dev->estats.rx_stopped;
- emac_rx_disable_async(dev);
-}
-
-/* Hard IRQ */
-static irqreturn_t emac_irq(int irq, void *dev_instance)
-{
- struct ocp_enet_private *dev = dev_instance;
- struct emac_regs __iomem *p = dev->emacp;
- struct ibm_emac_error_stats *st = &dev->estats;
-
- u32 isr = in_be32(&p->isr);
- out_be32(&p->isr, isr);
-
- DBG("%d: isr = %08x" NL, dev->def->index, isr);
-
- if (isr & EMAC_ISR_TXPE)
- ++st->tx_parity;
- if (isr & EMAC_ISR_RXPE)
- ++st->rx_parity;
- if (isr & EMAC_ISR_TXUE)
- ++st->tx_underrun;
- if (isr & EMAC_ISR_RXOE)
- ++st->rx_fifo_overrun;
- if (isr & EMAC_ISR_OVR)
- ++st->rx_overrun;
- if (isr & EMAC_ISR_BP)
- ++st->rx_bad_packet;
- if (isr & EMAC_ISR_RP)
- ++st->rx_runt_packet;
- if (isr & EMAC_ISR_SE)
- ++st->rx_short_event;
- if (isr & EMAC_ISR_ALE)
- ++st->rx_alignment_error;
- if (isr & EMAC_ISR_BFCS)
- ++st->rx_bad_fcs;
- if (isr & EMAC_ISR_PTLE)
- ++st->rx_packet_too_long;
- if (isr & EMAC_ISR_ORE)
- ++st->rx_out_of_range;
- if (isr & EMAC_ISR_IRE)
- ++st->rx_in_range;
- if (isr & EMAC_ISR_SQE)
- ++st->tx_sqe;
- if (isr & EMAC_ISR_TE)
- ++st->tx_errors;
-
- return IRQ_HANDLED;
-}
-
-static struct net_device_stats *emac_stats(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- struct ibm_emac_stats *st = &dev->stats;
- struct ibm_emac_error_stats *est = &dev->estats;
- struct net_device_stats *nst = &dev->nstats;
-
- DBG2("%d: stats" NL, dev->def->index);
-
- /* Compute "legacy" statistics */
- local_irq_disable();
- nst->rx_packets = (unsigned long)st->rx_packets;
- nst->rx_bytes = (unsigned long)st->rx_bytes;
- nst->tx_packets = (unsigned long)st->tx_packets;
- nst->tx_bytes = (unsigned long)st->tx_bytes;
- nst->rx_dropped = (unsigned long)(est->rx_dropped_oom +
- est->rx_dropped_error +
- est->rx_dropped_resize +
- est->rx_dropped_mtu);
- nst->tx_dropped = (unsigned long)est->tx_dropped;
-
- nst->rx_errors = (unsigned long)est->rx_bd_errors;
- nst->rx_fifo_errors = (unsigned long)(est->rx_bd_overrun +
- est->rx_fifo_overrun +
- est->rx_overrun);
- nst->rx_frame_errors = (unsigned long)(est->rx_bd_alignment_error +
- est->rx_alignment_error);
- nst->rx_crc_errors = (unsigned long)(est->rx_bd_bad_fcs +
- est->rx_bad_fcs);
- nst->rx_length_errors = (unsigned long)(est->rx_bd_runt_packet +
- est->rx_bd_short_event +
- est->rx_bd_packet_too_long +
- est->rx_bd_out_of_range +
- est->rx_bd_in_range +
- est->rx_runt_packet +
- est->rx_short_event +
- est->rx_packet_too_long +
- est->rx_out_of_range +
- est->rx_in_range);
-
- nst->tx_errors = (unsigned long)(est->tx_bd_errors + est->tx_errors);
- nst->tx_fifo_errors = (unsigned long)(est->tx_bd_underrun +
- est->tx_underrun);
- nst->tx_carrier_errors = (unsigned long)est->tx_bd_carrier_loss;
- nst->collisions = (unsigned long)(est->tx_bd_excessive_deferral +
- est->tx_bd_excessive_collisions +
- est->tx_bd_late_collision +
- est->tx_bd_multple_collisions);
- local_irq_enable();
- return nst;
-}
-
-static void emac_remove(struct ocp_device *ocpdev)
-{
- struct ocp_enet_private *dev = ocp_get_drvdata(ocpdev);
-
- DBG("%d: remove" NL, dev->def->index);
-
- ocp_set_drvdata(ocpdev, NULL);
- unregister_netdev(dev->ndev);
-
- tah_fini(dev->tah_dev);
- rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
- zmii_fini(dev->zmii_dev, dev->zmii_input);
-
- emac_dbg_register(dev->def->index, NULL);
-
- mal_unregister_commac(dev->mal, &dev->commac);
- iounmap(dev->emacp);
- kfree(dev->ndev);
-}
-
-static struct mal_commac_ops emac_commac_ops = {
- .poll_tx = &emac_poll_tx,
- .poll_rx = &emac_poll_rx,
- .peek_rx = &emac_peek_rx,
- .rxde = &emac_rxde,
-};
-
-static struct mal_commac_ops emac_commac_sg_ops = {
- .poll_tx = &emac_poll_tx,
- .poll_rx = &emac_poll_rx,
- .peek_rx = &emac_peek_rx_sg,
- .rxde = &emac_rxde,
-};
-
-/* Ethtool support */
-static int emac_ethtool_get_settings(struct net_device *ndev,
- struct ethtool_cmd *cmd)
-{
- struct ocp_enet_private *dev = ndev->priv;
-
- cmd->supported = dev->phy.features;
- cmd->port = PORT_MII;
- cmd->phy_address = dev->phy.address;
- cmd->transceiver =
- dev->phy.address >= 0 ? XCVR_EXTERNAL : XCVR_INTERNAL;
-
- local_bh_disable();
- cmd->advertising = dev->phy.advertising;
- cmd->autoneg = dev->phy.autoneg;
- cmd->speed = dev->phy.speed;
- cmd->duplex = dev->phy.duplex;
- local_bh_enable();
-
- return 0;
-}
-
-static int emac_ethtool_set_settings(struct net_device *ndev,
- struct ethtool_cmd *cmd)
-{
- struct ocp_enet_private *dev = ndev->priv;
- u32 f = dev->phy.features;
-
- DBG("%d: set_settings(%d, %d, %d, 0x%08x)" NL, dev->def->index,
- cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
-
- /* Basic sanity checks */
- if (dev->phy.address < 0)
- return -EOPNOTSUPP;
- if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
- return -EINVAL;
- if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
- return -EINVAL;
- if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
- return -EINVAL;
-
- if (cmd->autoneg == AUTONEG_DISABLE) {
- switch (cmd->speed) {
- case SPEED_10:
- if (cmd->duplex == DUPLEX_HALF
- && !(f & SUPPORTED_10baseT_Half))
- return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL
- && !(f & SUPPORTED_10baseT_Full))
- return -EINVAL;
- break;
- case SPEED_100:
- if (cmd->duplex == DUPLEX_HALF
- && !(f & SUPPORTED_100baseT_Half))
- return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL
- && !(f & SUPPORTED_100baseT_Full))
- return -EINVAL;
- break;
- case SPEED_1000:
- if (cmd->duplex == DUPLEX_HALF
- && !(f & SUPPORTED_1000baseT_Half))
- return -EINVAL;
- if (cmd->duplex == DUPLEX_FULL
- && !(f & SUPPORTED_1000baseT_Full))
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- local_bh_disable();
- dev->phy.def->ops->setup_forced(&dev->phy, cmd->speed,
- cmd->duplex);
-
- } else {
- if (!(f & SUPPORTED_Autoneg))
- return -EINVAL;
-
- local_bh_disable();
- dev->phy.def->ops->setup_aneg(&dev->phy,
- (cmd->advertising & f) |
- (dev->phy.advertising &
- (ADVERTISED_Pause |
- ADVERTISED_Asym_Pause)));
- }
- emac_force_link_update(dev);
- local_bh_enable();
-
- return 0;
-}
-
-static void emac_ethtool_get_ringparam(struct net_device *ndev,
- struct ethtool_ringparam *rp)
-{
- rp->rx_max_pending = rp->rx_pending = NUM_RX_BUFF;
- rp->tx_max_pending = rp->tx_pending = NUM_TX_BUFF;
-}
-
-static void emac_ethtool_get_pauseparam(struct net_device *ndev,
- struct ethtool_pauseparam *pp)
-{
- struct ocp_enet_private *dev = ndev->priv;
-
- local_bh_disable();
- if ((dev->phy.features & SUPPORTED_Autoneg) &&
- (dev->phy.advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause)))
- pp->autoneg = 1;
-
- if (dev->phy.duplex == DUPLEX_FULL) {
- if (dev->phy.pause)
- pp->rx_pause = pp->tx_pause = 1;
- else if (dev->phy.asym_pause)
- pp->tx_pause = 1;
- }
- local_bh_enable();
-}
-
-static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- return dev->tah_dev != 0;
-}
-
-static int emac_get_regs_len(struct ocp_enet_private *dev)
-{
- return sizeof(struct emac_ethtool_regs_subhdr) + EMAC_ETHTOOL_REGS_SIZE;
-}
-
-static int emac_ethtool_get_regs_len(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- return sizeof(struct emac_ethtool_regs_hdr) +
- emac_get_regs_len(dev) + mal_get_regs_len(dev->mal) +
- zmii_get_regs_len(dev->zmii_dev) +
- rgmii_get_regs_len(dev->rgmii_dev) +
- tah_get_regs_len(dev->tah_dev);
-}
-
-static void *emac_dump_regs(struct ocp_enet_private *dev, void *buf)
-{
- struct emac_ethtool_regs_subhdr *hdr = buf;
-
- hdr->version = EMAC_ETHTOOL_REGS_VER;
- hdr->index = dev->def->index;
- memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
- return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
-}
-
-static void emac_ethtool_get_regs(struct net_device *ndev,
- struct ethtool_regs *regs, void *buf)
-{
- struct ocp_enet_private *dev = ndev->priv;
- struct emac_ethtool_regs_hdr *hdr = buf;
-
- hdr->components = 0;
- buf = hdr + 1;
-
- local_irq_disable();
- buf = mal_dump_regs(dev->mal, buf);
- buf = emac_dump_regs(dev, buf);
- if (dev->zmii_dev) {
- hdr->components |= EMAC_ETHTOOL_REGS_ZMII;
- buf = zmii_dump_regs(dev->zmii_dev, buf);
- }
- if (dev->rgmii_dev) {
- hdr->components |= EMAC_ETHTOOL_REGS_RGMII;
- buf = rgmii_dump_regs(dev->rgmii_dev, buf);
- }
- if (dev->tah_dev) {
- hdr->components |= EMAC_ETHTOOL_REGS_TAH;
- buf = tah_dump_regs(dev->tah_dev, buf);
- }
- local_irq_enable();
-}
-
-static int emac_ethtool_nway_reset(struct net_device *ndev)
-{
- struct ocp_enet_private *dev = ndev->priv;
- int res = 0;
-
- DBG("%d: nway_reset" NL, dev->def->index);
-
- if (dev->phy.address < 0)
- return -EOPNOTSUPP;
-
- local_bh_disable();
- if (!dev->phy.autoneg) {
- res = -EINVAL;
- goto out;
- }
-
- dev->phy.def->ops->setup_aneg(&dev->phy, dev->phy.advertising);
- emac_force_link_update(dev);
-
- out:
- local_bh_enable();
- return res;
-}
-
-static int emac_get_sset_count(struct net_device *ndev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return EMAC_ETHTOOL_STATS_COUNT;
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static void emac_ethtool_get_strings(struct net_device *ndev, u32 stringset,
- u8 * buf)
-{
- if (stringset == ETH_SS_STATS)
- memcpy(buf, &emac_stats_keys, sizeof(emac_stats_keys));
-}
-
-static void emac_ethtool_get_ethtool_stats(struct net_device *ndev,
- struct ethtool_stats *estats,
- u64 * tmp_stats)
-{
- struct ocp_enet_private *dev = ndev->priv;
- local_irq_disable();
- memcpy(tmp_stats, &dev->stats, sizeof(dev->stats));
- tmp_stats += sizeof(dev->stats) / sizeof(u64);
- memcpy(tmp_stats, &dev->estats, sizeof(dev->estats));
- local_irq_enable();
-}
-
-static void emac_ethtool_get_drvinfo(struct net_device *ndev,
- struct ethtool_drvinfo *info)
-{
- struct ocp_enet_private *dev = ndev->priv;
-
- strcpy(info->driver, "ibm_emac");
- strcpy(info->version, DRV_VERSION);
- info->fw_version[0] = '\0';
- sprintf(info->bus_info, "PPC 4xx EMAC %d", dev->def->index);
- info->regdump_len = emac_ethtool_get_regs_len(ndev);
-}
-
-static const struct ethtool_ops emac_ethtool_ops = {
- .get_settings = emac_ethtool_get_settings,
- .set_settings = emac_ethtool_set_settings,
- .get_drvinfo = emac_ethtool_get_drvinfo,
-
- .get_regs_len = emac_ethtool_get_regs_len,
- .get_regs = emac_ethtool_get_regs,
-
- .nway_reset = emac_ethtool_nway_reset,
-
- .get_ringparam = emac_ethtool_get_ringparam,
- .get_pauseparam = emac_ethtool_get_pauseparam,
-
- .get_rx_csum = emac_ethtool_get_rx_csum,
-
- .get_strings = emac_ethtool_get_strings,
- .get_sset_count = emac_get_sset_count,
- .get_ethtool_stats = emac_ethtool_get_ethtool_stats,
-
- .get_link = ethtool_op_get_link,
-};
-
-static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
-{
- struct ocp_enet_private *dev = ndev->priv;
- uint16_t *data = (uint16_t *) & rq->ifr_ifru;
-
- DBG("%d: ioctl %08x" NL, dev->def->index, cmd);
-
- if (dev->phy.address < 0)
- return -EOPNOTSUPP;
-
- switch (cmd) {
- case SIOCGMIIPHY:
- case SIOCDEVPRIVATE:
- data[0] = dev->phy.address;
- /* Fall through */
- case SIOCGMIIREG:
- case SIOCDEVPRIVATE + 1:
- data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]);
- return 0;
-
- case SIOCSMIIREG:
- case SIOCDEVPRIVATE + 2:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- emac_mdio_write(ndev, dev->phy.address, data[1], data[2]);
- return 0;
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static int __init emac_probe(struct ocp_device *ocpdev)
-{
- struct ocp_func_emac_data *emacdata = ocpdev->def->additions;
- struct net_device *ndev;
- struct ocp_device *maldev;
- struct ocp_enet_private *dev;
- int err, i;
- DECLARE_MAC_BUF(mac);
-
- DBG("%d: probe" NL, ocpdev->def->index);
-
- if (!emacdata) {
- printk(KERN_ERR "emac%d: Missing additional data!\n",
- ocpdev->def->index);
- return -ENODEV;
- }
-
- /* Allocate our net_device structure */
- ndev = alloc_etherdev(sizeof(struct ocp_enet_private));
- if (!ndev) {
- printk(KERN_ERR "emac%d: could not allocate ethernet device!\n",
- ocpdev->def->index);
- return -ENOMEM;
- }
- dev = ndev->priv;
- dev->ndev = ndev;
- dev->ldev = &ocpdev->dev;
- dev->def = ocpdev->def;
-
- /* Find MAL device we are connected to */
- maldev =
- ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_MAL, emacdata->mal_idx);
- if (!maldev) {
- printk(KERN_ERR "emac%d: unknown mal%d device!\n",
- dev->def->index, emacdata->mal_idx);
- err = -ENODEV;
- goto out;
- }
- dev->mal = ocp_get_drvdata(maldev);
- if (!dev->mal) {
- printk(KERN_ERR "emac%d: mal%d hasn't been initialized yet!\n",
- dev->def->index, emacdata->mal_idx);
- err = -ENODEV;
- goto out;
- }
-
- /* Register with MAL */
- dev->commac.ops = &emac_commac_ops;
- dev->commac.dev = dev;
- dev->commac.tx_chan_mask = MAL_CHAN_MASK(emacdata->mal_tx_chan);
- dev->commac.rx_chan_mask = MAL_CHAN_MASK(emacdata->mal_rx_chan);
- err = mal_register_commac(dev->mal, &dev->commac);
- if (err) {
- printk(KERN_ERR "emac%d: failed to register with mal%d!\n",
- dev->def->index, emacdata->mal_idx);
- goto out;
- }
- dev->rx_skb_size = emac_rx_skb_size(ndev->mtu);
- dev->rx_sync_size = emac_rx_sync_size(ndev->mtu);
-
- /* Get pointers to BD rings */
- dev->tx_desc =
- dev->mal->bd_virt + mal_tx_bd_offset(dev->mal,
- emacdata->mal_tx_chan);
- dev->rx_desc =
- dev->mal->bd_virt + mal_rx_bd_offset(dev->mal,
- emacdata->mal_rx_chan);
-
- DBG("%d: tx_desc %p" NL, ocpdev->def->index, dev->tx_desc);
- DBG("%d: rx_desc %p" NL, ocpdev->def->index, dev->rx_desc);
-
- /* Clean rings */
- memset(dev->tx_desc, 0, NUM_TX_BUFF * sizeof(struct mal_descriptor));
- memset(dev->rx_desc, 0, NUM_RX_BUFF * sizeof(struct mal_descriptor));
-
- /* If we depend on another EMAC for MDIO, check whether it was probed already */
- if (emacdata->mdio_idx >= 0 && emacdata->mdio_idx != ocpdev->def->index) {
- struct ocp_device *mdiodev =
- ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC,
- emacdata->mdio_idx);
- if (!mdiodev) {
- printk(KERN_ERR "emac%d: unknown emac%d device!\n",
- dev->def->index, emacdata->mdio_idx);
- err = -ENODEV;
- goto out2;
- }
- dev->mdio_dev = ocp_get_drvdata(mdiodev);
- if (!dev->mdio_dev) {
- printk(KERN_ERR
- "emac%d: emac%d hasn't been initialized yet!\n",
- dev->def->index, emacdata->mdio_idx);
- err = -ENODEV;
- goto out2;
- }
- }
-
- /* Attach to ZMII, if needed */
- if ((err = zmii_attach(dev)) != 0)
- goto out2;
-
- /* Attach to RGMII, if needed */
- if ((err = rgmii_attach(dev)) != 0)
- goto out3;
-
- /* Attach to TAH, if needed */
- if ((err = tah_attach(dev)) != 0)
- goto out4;
-
- /* Map EMAC regs */
- dev->emacp = ioremap(dev->def->paddr, sizeof(struct emac_regs));
- if (!dev->emacp) {
- printk(KERN_ERR "emac%d: could not ioremap device registers!\n",
- dev->def->index);
- err = -ENOMEM;
- goto out5;
- }
-
- /* Fill in MAC address */
- for (i = 0; i < 6; ++i)
- ndev->dev_addr[i] = emacdata->mac_addr[i];
-
- /* Set some link defaults before we can find out real parameters */
- dev->phy.speed = SPEED_100;
- dev->phy.duplex = DUPLEX_FULL;
- dev->phy.autoneg = AUTONEG_DISABLE;
- dev->phy.pause = dev->phy.asym_pause = 0;
- dev->stop_timeout = STOP_TIMEOUT_100;
- init_timer(&dev->link_timer);
- dev->link_timer.function = emac_link_timer;
- dev->link_timer.data = (unsigned long)dev;
-
- /* Find PHY if any */
- dev->phy.dev = ndev;
- dev->phy.mode = emacdata->phy_mode;
- if (emacdata->phy_map != 0xffffffff) {
- u32 phy_map = emacdata->phy_map | busy_phy_map;
- u32 adv;
-
- DBG("%d: PHY maps %08x %08x" NL, dev->def->index,
- emacdata->phy_map, busy_phy_map);
-
- EMAC_RX_CLK_TX(dev->def->index);
-
- dev->phy.mdio_read = emac_mdio_read;
- dev->phy.mdio_write = emac_mdio_write;
-
- /* Configure EMAC with defaults so we can at least use MDIO
- * This is needed mostly for 440GX
- */
- if (emac_phy_gpcs(dev->phy.mode)) {
- /* XXX
- * Make GPCS PHY address equal to EMAC index.
- * We probably should take into account busy_phy_map
- * and/or phy_map here.
- */
- dev->phy.address = dev->def->index;
- }
-
- emac_configure(dev);
-
- for (i = 0; i < 0x20; phy_map >>= 1, ++i)
- if (!(phy_map & 1)) {
- int r;
- busy_phy_map |= 1 << i;
-
- /* Quick check if there is a PHY at the address */
- r = emac_mdio_read(dev->ndev, i, MII_BMCR);
- if (r == 0xffff || r < 0)
- continue;
- if (!mii_phy_probe(&dev->phy, i))
- break;
- }
- if (i == 0x20) {
- printk(KERN_WARNING "emac%d: can't find PHY!\n",
- dev->def->index);
- goto out6;
- }
-
- /* Init PHY */
- if (dev->phy.def->ops->init)
- dev->phy.def->ops->init(&dev->phy);
-
- /* Disable any PHY features not supported by the platform */
- dev->phy.def->features &= ~emacdata->phy_feat_exc;
-
- /* Setup initial link parameters */
- if (dev->phy.features & SUPPORTED_Autoneg) {
- adv = dev->phy.features;
-#if !defined(CONFIG_40x)
- adv |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
-#endif
- /* Restart autonegotiation */
- dev->phy.def->ops->setup_aneg(&dev->phy, adv);
- } else {
- u32 f = dev->phy.def->features;
- int speed = SPEED_10, fd = DUPLEX_HALF;
-
- /* Select highest supported speed/duplex */
- if (f & SUPPORTED_1000baseT_Full) {
- speed = SPEED_1000;
- fd = DUPLEX_FULL;
- } else if (f & SUPPORTED_1000baseT_Half)
- speed = SPEED_1000;
- else if (f & SUPPORTED_100baseT_Full) {
- speed = SPEED_100;
- fd = DUPLEX_FULL;
- } else if (f & SUPPORTED_100baseT_Half)
- speed = SPEED_100;
- else if (f & SUPPORTED_10baseT_Full)
- fd = DUPLEX_FULL;
-
- /* Force link parameters */
- dev->phy.def->ops->setup_forced(&dev->phy, speed, fd);
- }
- } else {
- emac_reset(dev);
-
- /* PHY-less configuration.
- * XXX I probably should move these settings to emacdata
- */
- dev->phy.address = -1;
- dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII;
- dev->phy.pause = 1;
- }
-
- /* Fill in the driver function table */
- ndev->open = &emac_open;
- if (dev->tah_dev) {
- ndev->hard_start_xmit = &emac_start_xmit_sg;
- ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- } else
- ndev->hard_start_xmit = &emac_start_xmit;
- ndev->tx_timeout = &emac_full_tx_reset;
- ndev->watchdog_timeo = 5 * HZ;
- ndev->stop = &emac_close;
- ndev->get_stats = &emac_stats;
- ndev->set_multicast_list = &emac_set_multicast_list;
- ndev->do_ioctl = &emac_ioctl;
- if (emac_phy_supports_gige(emacdata->phy_mode)) {
- ndev->change_mtu = &emac_change_mtu;
- dev->commac.ops = &emac_commac_sg_ops;
- }
- SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
-
- netif_carrier_off(ndev);
- netif_stop_queue(ndev);
-
- err = register_netdev(ndev);
- if (err) {
- printk(KERN_ERR "emac%d: failed to register net device (%d)!\n",
- dev->def->index, err);
- goto out6;
- }
-
- ocp_set_drvdata(ocpdev, dev);
-
- printk("%s: emac%d, MAC %s\n",
- ndev->name, dev->def->index, print_mac(mac, ndev->dev_addr));
-
- if (dev->phy.address >= 0)
- printk("%s: found %s PHY (0x%02x)\n", ndev->name,
- dev->phy.def->name, dev->phy.address);
-
- emac_dbg_register(dev->def->index, dev);
-
- return 0;
- out6:
- iounmap(dev->emacp);
- out5:
- tah_fini(dev->tah_dev);
- out4:
- rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
- out3:
- zmii_fini(dev->zmii_dev, dev->zmii_input);
- out2:
- mal_unregister_commac(dev->mal, &dev->commac);
- out:
- kfree(ndev);
- return err;
-}
-
-static struct ocp_device_id emac_ids[] = {
- { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_EMAC },
- { .vendor = OCP_VENDOR_INVALID}
-};
-
-static struct ocp_driver emac_driver = {
- .name = "emac",
- .id_table = emac_ids,
- .probe = emac_probe,
- .remove = emac_remove,
-};
-
-static int __init emac_init(void)
-{
- printk(KERN_INFO DRV_DESC ", version " DRV_VERSION "\n");
-
- DBG(": init" NL);
-
- if (mal_init())
- return -ENODEV;
-
- EMAC_CLK_INTERNAL;
- if (ocp_register_driver(&emac_driver)) {
- EMAC_CLK_EXTERNAL;
- ocp_unregister_driver(&emac_driver);
- mal_exit();
- return -ENODEV;
- }
- EMAC_CLK_EXTERNAL;
-
- emac_init_debug();
- return 0;
-}
-
-static void __exit emac_exit(void)
-{
- DBG(": exit" NL);
- ocp_unregister_driver(&emac_driver);
- mal_exit();
- emac_fini_debug();
-}
-
-module_init(emac_init);
-module_exit(emac_exit);
diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
deleted file mode 100644
index dabb94afeb9..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_core.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_core.h
- *
- * Driver for PowerPC 4xx on-chip ethernet controller.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Armin Kuster <akuster@mvista.com>
- * Johnnie Peters <jpeters@mvista.com>
- * Copyright 2000, 2001 MontaVista Softare 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.
- *
- */
-#ifndef __IBM_EMAC_CORE_H_
-#define __IBM_EMAC_CORE_H_
-
-#include <linux/netdevice.h>
-#include <linux/dma-mapping.h>
-#include <asm/ocp.h>
-
-#include "ibm_emac.h"
-#include "ibm_emac_phy.h"
-#include "ibm_emac_zmii.h"
-#include "ibm_emac_rgmii.h"
-#include "ibm_emac_mal.h"
-#include "ibm_emac_tah.h"
-
-#define NUM_TX_BUFF CONFIG_IBM_EMAC_TXB
-#define NUM_RX_BUFF CONFIG_IBM_EMAC_RXB
-
-/* Simple sanity check */
-#if NUM_TX_BUFF > 256 || NUM_RX_BUFF > 256
-#error Invalid number of buffer descriptors (greater than 256)
-#endif
-
-// XXX
-#define EMAC_MIN_MTU 46
-#define EMAC_MAX_MTU 9000
-
-/* Maximum L2 header length (VLAN tagged, no FCS) */
-#define EMAC_MTU_OVERHEAD (6 * 2 + 2 + 4)
-
-/* RX BD size for the given MTU */
-static inline int emac_rx_size(int mtu)
-{
- if (mtu > ETH_DATA_LEN)
- return MAL_MAX_RX_SIZE;
- else
- return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD);
-}
-
-#define EMAC_DMA_ALIGN(x) ALIGN((x), dma_get_cache_alignment())
-
-#define EMAC_RX_SKB_HEADROOM \
- EMAC_DMA_ALIGN(CONFIG_IBM_EMAC_RX_SKB_HEADROOM)
-
-/* Size of RX skb for the given MTU */
-static inline int emac_rx_skb_size(int mtu)
-{
- int size = max(mtu + EMAC_MTU_OVERHEAD, emac_rx_size(mtu));
- return EMAC_DMA_ALIGN(size + 2) + EMAC_RX_SKB_HEADROOM;
-}
-
-/* RX DMA sync size */
-static inline int emac_rx_sync_size(int mtu)
-{
- return EMAC_DMA_ALIGN(emac_rx_size(mtu) + 2);
-}
-
-/* Driver statistcs is split into two parts to make it more cache friendly:
- * - normal statistics (packet count, etc)
- * - error statistics
- *
- * When statistics is requested by ethtool, these parts are concatenated,
- * normal one goes first.
- *
- * Please, keep these structures in sync with emac_stats_keys.
- */
-
-/* Normal TX/RX Statistics */
-struct ibm_emac_stats {
- u64 rx_packets;
- u64 rx_bytes;
- u64 tx_packets;
- u64 tx_bytes;
- u64 rx_packets_csum;
- u64 tx_packets_csum;
-};
-
-/* Error statistics */
-struct ibm_emac_error_stats {
- u64 tx_undo;
-
- /* Software RX Errors */
- u64 rx_dropped_stack;
- u64 rx_dropped_oom;
- u64 rx_dropped_error;
- u64 rx_dropped_resize;
- u64 rx_dropped_mtu;
- u64 rx_stopped;
- /* BD reported RX errors */
- u64 rx_bd_errors;
- u64 rx_bd_overrun;
- u64 rx_bd_bad_packet;
- u64 rx_bd_runt_packet;
- u64 rx_bd_short_event;
- u64 rx_bd_alignment_error;
- u64 rx_bd_bad_fcs;
- u64 rx_bd_packet_too_long;
- u64 rx_bd_out_of_range;
- u64 rx_bd_in_range;
- /* EMAC IRQ reported RX errors */
- u64 rx_parity;
- u64 rx_fifo_overrun;
- u64 rx_overrun;
- u64 rx_bad_packet;
- u64 rx_runt_packet;
- u64 rx_short_event;
- u64 rx_alignment_error;
- u64 rx_bad_fcs;
- u64 rx_packet_too_long;
- u64 rx_out_of_range;
- u64 rx_in_range;
-
- /* Software TX Errors */
- u64 tx_dropped;
- /* BD reported TX errors */
- u64 tx_bd_errors;
- u64 tx_bd_bad_fcs;
- u64 tx_bd_carrier_loss;
- u64 tx_bd_excessive_deferral;
- u64 tx_bd_excessive_collisions;
- u64 tx_bd_late_collision;
- u64 tx_bd_multple_collisions;
- u64 tx_bd_single_collision;
- u64 tx_bd_underrun;
- u64 tx_bd_sqe;
- /* EMAC IRQ reported TX errors */
- u64 tx_parity;
- u64 tx_underrun;
- u64 tx_sqe;
- u64 tx_errors;
-};
-
-#define EMAC_ETHTOOL_STATS_COUNT ((sizeof(struct ibm_emac_stats) + \
- sizeof(struct ibm_emac_error_stats)) \
- / sizeof(u64))
-
-struct ocp_enet_private {
- struct net_device *ndev; /* 0 */
- struct emac_regs __iomem *emacp;
-
- struct mal_descriptor *tx_desc;
- int tx_cnt;
- int tx_slot;
- int ack_slot;
-
- struct mal_descriptor *rx_desc;
- int rx_slot;
- struct sk_buff *rx_sg_skb; /* 1 */
- int rx_skb_size;
- int rx_sync_size;
-
- struct ibm_emac_stats stats;
- struct ocp_device *tah_dev;
-
- struct ibm_ocp_mal *mal;
- struct mal_commac commac;
-
- struct sk_buff *tx_skb[NUM_TX_BUFF];
- struct sk_buff *rx_skb[NUM_RX_BUFF];
-
- struct ocp_device *zmii_dev;
- int zmii_input;
- struct ocp_enet_private *mdio_dev;
- struct ocp_device *rgmii_dev;
- int rgmii_input;
-
- struct ocp_def *def;
-
- struct mii_phy phy;
- struct timer_list link_timer;
- int reset_failed;
-
- int stop_timeout; /* in us */
-
- struct ibm_emac_error_stats estats;
- struct net_device_stats nstats;
-
- struct device* ldev;
-};
-
-/* Ethtool get_regs complex data.
- * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
- * when available.
- *
- * Returned BLOB consists of the ibm_emac_ethtool_regs_hdr,
- * MAL registers, EMAC registers and optional ZMII, RGMII, TAH registers.
- * Each register component is preceded with emac_ethtool_regs_subhdr.
- * Order of the optional headers follows their relative bit posititions
- * in emac_ethtool_regs_hdr.components
- */
-#define EMAC_ETHTOOL_REGS_ZMII 0x00000001
-#define EMAC_ETHTOOL_REGS_RGMII 0x00000002
-#define EMAC_ETHTOOL_REGS_TAH 0x00000004
-
-struct emac_ethtool_regs_hdr {
- u32 components;
-};
-
-struct emac_ethtool_regs_subhdr {
- u32 version;
- u32 index;
-};
-
-#endif /* __IBM_EMAC_CORE_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c
deleted file mode 100644
index 1f70906cfb9..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_debug.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_debug.c
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * 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.
- *
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/sysrq.h>
-#include <asm/io.h>
-
-#include "ibm_emac_core.h"
-
-static void emac_desc_dump(int idx, struct ocp_enet_private *p)
-{
- int i;
- printk("** EMAC%d TX BDs **\n"
- " tx_cnt = %d tx_slot = %d ack_slot = %d\n",
- idx, p->tx_cnt, p->tx_slot, p->ack_slot);
- for (i = 0; i < NUM_TX_BUFF / 2; ++i)
- printk
- ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
- i, p->tx_desc[i].data_ptr, p->tx_skb[i] ? 'V' : ' ',
- p->tx_desc[i].ctrl, p->tx_desc[i].data_len,
- NUM_TX_BUFF / 2 + i,
- p->tx_desc[NUM_TX_BUFF / 2 + i].data_ptr,
- p->tx_skb[NUM_TX_BUFF / 2 + i] ? 'V' : ' ',
- p->tx_desc[NUM_TX_BUFF / 2 + i].ctrl,
- p->tx_desc[NUM_TX_BUFF / 2 + i].data_len);
-
- printk("** EMAC%d RX BDs **\n"
- " rx_slot = %d rx_stopped = %d rx_skb_size = %d rx_sync_size = %d\n"
- " rx_sg_skb = 0x%p\n",
- idx, p->rx_slot, p->commac.rx_stopped, p->rx_skb_size,
- p->rx_sync_size, p->rx_sg_skb);
- for (i = 0; i < NUM_RX_BUFF / 2; ++i)
- printk
- ("bd[%2d] 0x%08x %c 0x%04x %4u - bd[%2d] 0x%08x %c 0x%04x %4u\n",
- i, p->rx_desc[i].data_ptr, p->rx_skb[i] ? 'V' : ' ',
- p->rx_desc[i].ctrl, p->rx_desc[i].data_len,
- NUM_RX_BUFF / 2 + i,
- p->rx_desc[NUM_RX_BUFF / 2 + i].data_ptr,
- p->rx_skb[NUM_RX_BUFF / 2 + i] ? 'V' : ' ',
- p->rx_desc[NUM_RX_BUFF / 2 + i].ctrl,
- p->rx_desc[NUM_RX_BUFF / 2 + i].data_len);
-}
-
-static void emac_mac_dump(int idx, struct ocp_enet_private *dev)
-{
- struct emac_regs __iomem *p = dev->emacp;
-
- printk("** EMAC%d registers **\n"
- "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
- "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
- "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
- "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
- "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
- "LSA = %04x%08x IPGVR = 0x%04x\n"
- "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
- "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
- idx, in_be32(&p->mr0), in_be32(&p->mr1),
- in_be32(&p->tmr0), in_be32(&p->tmr1),
- in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
- in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
- in_be32(&p->vtci),
- in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
- in_be32(&p->iaht4),
- in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
- in_be32(&p->gaht4),
- in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
- in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
- in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
- );
-
- emac_desc_dump(idx, dev);
-}
-
-static void emac_mal_dump(struct ibm_ocp_mal *mal)
-{
- struct ocp_func_mal_data *maldata = mal->def->additions;
- int i;
-
- printk("** MAL%d Registers **\n"
- "CFG = 0x%08x ESR = 0x%08x IER = 0x%08x\n"
- "TX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n"
- "RX|CASR = 0x%08x CARR = 0x%08x EOBISR = 0x%08x DEIR = 0x%08x\n",
- mal->def->index,
- get_mal_dcrn(mal, MAL_CFG), get_mal_dcrn(mal, MAL_ESR),
- get_mal_dcrn(mal, MAL_IER),
- get_mal_dcrn(mal, MAL_TXCASR), get_mal_dcrn(mal, MAL_TXCARR),
- get_mal_dcrn(mal, MAL_TXEOBISR), get_mal_dcrn(mal, MAL_TXDEIR),
- get_mal_dcrn(mal, MAL_RXCASR), get_mal_dcrn(mal, MAL_RXCARR),
- get_mal_dcrn(mal, MAL_RXEOBISR), get_mal_dcrn(mal, MAL_RXDEIR)
- );
-
- printk("TX|");
- for (i = 0; i < maldata->num_tx_chans; ++i) {
- if (i && !(i % 4))
- printk("\n ");
- printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_TXCTPR(i)));
- }
- printk("\nRX|");
- for (i = 0; i < maldata->num_rx_chans; ++i) {
- if (i && !(i % 4))
- printk("\n ");
- printk("CTP%d = 0x%08x ", i, get_mal_dcrn(mal, MAL_RXCTPR(i)));
- }
- printk("\n ");
- for (i = 0; i < maldata->num_rx_chans; ++i) {
- u32 r = get_mal_dcrn(mal, MAL_RCBS(i));
- if (i && !(i % 3))
- printk("\n ");
- printk("RCBS%d = 0x%08x (%d) ", i, r, r * 16);
- }
- printk("\n");
-}
-
-static struct ocp_enet_private *__emacs[4];
-static struct ibm_ocp_mal *__mals[1];
-
-void emac_dbg_register(int idx, struct ocp_enet_private *dev)
-{
- unsigned long flags;
-
- if (idx >= ARRAY_SIZE(__emacs)) {
- printk(KERN_WARNING
- "invalid index %d when registering EMAC for debugging\n",
- idx);
- return;
- }
-
- local_irq_save(flags);
- __emacs[idx] = dev;
- local_irq_restore(flags);
-}
-
-void mal_dbg_register(int idx, struct ibm_ocp_mal *mal)
-{
- unsigned long flags;
-
- if (idx >= ARRAY_SIZE(__mals)) {
- printk(KERN_WARNING
- "invalid index %d when registering MAL for debugging\n",
- idx);
- return;
- }
-
- local_irq_save(flags);
- __mals[idx] = mal;
- local_irq_restore(flags);
-}
-
-void emac_dbg_dump_all(void)
-{
- unsigned int i;
- unsigned long flags;
-
- local_irq_save(flags);
-
- for (i = 0; i < ARRAY_SIZE(__mals); ++i)
- if (__mals[i])
- emac_mal_dump(__mals[i]);
-
- for (i = 0; i < ARRAY_SIZE(__emacs); ++i)
- if (__emacs[i])
- emac_mac_dump(i, __emacs[i]);
-
- local_irq_restore(flags);
-}
-
-#if defined(CONFIG_MAGIC_SYSRQ)
-static void emac_sysrq_handler(int key, struct tty_struct *tty)
-{
- emac_dbg_dump_all();
-}
-
-static struct sysrq_key_op emac_sysrq_op = {
- .handler = emac_sysrq_handler,
- .help_msg = "emaC",
- .action_msg = "Show EMAC(s) status",
-};
-
-int __init emac_init_debug(void)
-{
- return register_sysrq_key('c', &emac_sysrq_op);
-}
-
-void __exit emac_fini_debug(void)
-{
- unregister_sysrq_key('c', &emac_sysrq_op);
-}
-
-#else
-int __init emac_init_debug(void)
-{
- return 0;
-}
-void __exit emac_fini_debug(void)
-{
-}
-#endif /* CONFIG_MAGIC_SYSRQ */
diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h
deleted file mode 100644
index 6c7dccc84bf..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_debug.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_debug.h
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * 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.
- *
- */
-#ifndef __IBM_EMAC_DEBUG_H_
-#define __IBM_EMAC_DEBUG_H_
-
-#include <linux/init.h>
-#include "ibm_emac_core.h"
-#include "ibm_emac_mal.h"
-
-#if defined(CONFIG_IBM_EMAC_DEBUG)
-void emac_dbg_register(int idx, struct ocp_enet_private *dev);
-void mal_dbg_register(int idx, struct ibm_ocp_mal *mal);
-int emac_init_debug(void) __init;
-void emac_fini_debug(void) __exit;
-void emac_dbg_dump_all(void);
-# define DBG_LEVEL 1
-#else
-# define emac_dbg_register(x,y) ((void)0)
-# define mal_dbg_register(x,y) ((void)0)
-# define emac_init_debug() ((void)0)
-# define emac_fini_debug() ((void)0)
-# define emac_dbg_dump_all() ((void)0)
-# define DBG_LEVEL 0
-#endif
-
-#if DBG_LEVEL > 0
-# define DBG(f,x...) printk("emac" f, ##x)
-# define MAL_DBG(f,x...) printk("mal" f, ##x)
-# define ZMII_DBG(f,x...) printk("zmii" f, ##x)
-# define RGMII_DBG(f,x...) printk("rgmii" f, ##x)
-# define NL "\n"
-#else
-# define DBG(f,x...) ((void)0)
-# define MAL_DBG(f,x...) ((void)0)
-# define ZMII_DBG(f,x...) ((void)0)
-# define RGMII_DBG(f,x...) ((void)0)
-#endif
-#if DBG_LEVEL > 1
-# define DBG2(f,x...) DBG(f, ##x)
-# define MAL_DBG2(f,x...) MAL_DBG(f, ##x)
-# define ZMII_DBG2(f,x...) ZMII_DBG(f, ##x)
-# define RGMII_DBG2(f,x...) RGMII_DBG(f, ##x)
-#else
-# define DBG2(f,x...) ((void)0)
-# define MAL_DBG2(f,x...) ((void)0)
-# define ZMII_DBG2(f,x...) ((void)0)
-# define RGMII_DBG2(f,x...) ((void)0)
-#endif
-
-#endif /* __IBM_EMAC_DEBUG_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
deleted file mode 100644
index dcd8826fc74..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_mal.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_mal.c
- *
- * Memory Access Layer (MAL) support
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>,
- * David Gibson <hermes@gibson.dropbear.id.au>,
- *
- * Armin Kuster <akuster@mvista.com>
- * Copyright 2002 MontaVista Softare 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.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/ocp.h>
-
-#include "ibm_emac_core.h"
-#include "ibm_emac_mal.h"
-#include "ibm_emac_debug.h"
-
-int __init mal_register_commac(struct ibm_ocp_mal *mal,
- struct mal_commac *commac)
-{
- unsigned long flags;
- local_irq_save(flags);
-
- MAL_DBG("%d: reg(%08x, %08x)" NL, mal->def->index,
- commac->tx_chan_mask, commac->rx_chan_mask);
-
- /* Don't let multiple commacs claim the same channel(s) */
- if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
- (mal->rx_chan_mask & commac->rx_chan_mask)) {
- local_irq_restore(flags);
- printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
- mal->def->index);
- return -EBUSY;
- }
-
- mal->tx_chan_mask |= commac->tx_chan_mask;
- mal->rx_chan_mask |= commac->rx_chan_mask;
- list_add(&commac->list, &mal->list);
-
- local_irq_restore(flags);
- return 0;
-}
-
-void mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac)
-{
- unsigned long flags;
- local_irq_save(flags);
-
- MAL_DBG("%d: unreg(%08x, %08x)" NL, mal->def->index,
- commac->tx_chan_mask, commac->rx_chan_mask);
-
- mal->tx_chan_mask &= ~commac->tx_chan_mask;
- mal->rx_chan_mask &= ~commac->rx_chan_mask;
- list_del_init(&commac->list);
-
- local_irq_restore(flags);
-}
-
-int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size)
-{
- struct ocp_func_mal_data *maldata = mal->def->additions;
- BUG_ON(channel < 0 || channel >= maldata->num_rx_chans ||
- size > MAL_MAX_RX_SIZE);
-
- MAL_DBG("%d: set_rbcs(%d, %lu)" NL, mal->def->index, channel, size);
-
- if (size & 0xf) {
- printk(KERN_WARNING
- "mal%d: incorrect RX size %lu for the channel %d\n",
- mal->def->index, size, channel);
- return -EINVAL;
- }
-
- set_mal_dcrn(mal, MAL_RCBS(channel), size >> 4);
- return 0;
-}
-
-int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel)
-{
- struct ocp_func_mal_data *maldata = mal->def->additions;
- BUG_ON(channel < 0 || channel >= maldata->num_tx_chans);
- return channel * NUM_TX_BUFF;
-}
-
-int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel)
-{
- struct ocp_func_mal_data *maldata = mal->def->additions;
- BUG_ON(channel < 0 || channel >= maldata->num_rx_chans);
- return maldata->num_tx_chans * NUM_TX_BUFF + channel * NUM_RX_BUFF;
-}
-
-void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel)
-{
- local_bh_disable();
- MAL_DBG("%d: enable_tx(%d)" NL, mal->def->index, channel);
- set_mal_dcrn(mal, MAL_TXCASR,
- get_mal_dcrn(mal, MAL_TXCASR) | MAL_CHAN_MASK(channel));
- local_bh_enable();
-}
-
-void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel)
-{
- set_mal_dcrn(mal, MAL_TXCARR, MAL_CHAN_MASK(channel));
- MAL_DBG("%d: disable_tx(%d)" NL, mal->def->index, channel);
-}
-
-void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel)
-{
- local_bh_disable();
- MAL_DBG("%d: enable_rx(%d)" NL, mal->def->index, channel);
- set_mal_dcrn(mal, MAL_RXCASR,
- get_mal_dcrn(mal, MAL_RXCASR) | MAL_CHAN_MASK(channel));
- local_bh_enable();
-}
-
-void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel)
-{
- set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));
- MAL_DBG("%d: disable_rx(%d)" NL, mal->def->index, channel);
-}
-
-void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac)
-{
- local_bh_disable();
- MAL_DBG("%d: poll_add(%p)" NL, mal->def->index, commac);
- list_add_tail(&commac->poll_list, &mal->poll_list);
- local_bh_enable();
-}
-
-void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac)
-{
- local_bh_disable();
- MAL_DBG("%d: poll_del(%p)" NL, mal->def->index, commac);
- list_del(&commac->poll_list);
- local_bh_enable();
-}
-
-/* synchronized by mal_poll() */
-static inline void mal_enable_eob_irq(struct ibm_ocp_mal *mal)
-{
- MAL_DBG2("%d: enable_irq" NL, mal->def->index);
- set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
-}
-
-/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
-static inline void mal_disable_eob_irq(struct ibm_ocp_mal *mal)
-{
- set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) & ~MAL_CFG_EOPIE);
- MAL_DBG2("%d: disable_irq" NL, mal->def->index);
-}
-
-static irqreturn_t mal_serr(int irq, void *dev_instance)
-{
- struct ibm_ocp_mal *mal = dev_instance;
- u32 esr = get_mal_dcrn(mal, MAL_ESR);
-
- /* Clear the error status register */
- set_mal_dcrn(mal, MAL_ESR, esr);
-
- MAL_DBG("%d: SERR %08x" NL, mal->def->index, esr);
-
- if (esr & MAL_ESR_EVB) {
- if (esr & MAL_ESR_DE) {
- /* We ignore Descriptor error,
- * TXDE or RXDE interrupt will be generated anyway.
- */
- return IRQ_HANDLED;
- }
-
- if (esr & MAL_ESR_PEIN) {
- /* PLB error, it's probably buggy hardware or
- * incorrect physical address in BD (i.e. bug)
- */
- if (net_ratelimit())
- printk(KERN_ERR
- "mal%d: system error, PLB (ESR = 0x%08x)\n",
- mal->def->index, esr);
- return IRQ_HANDLED;
- }
-
- /* OPB error, it's probably buggy hardware or incorrect EBC setup */
- if (net_ratelimit())
- printk(KERN_ERR
- "mal%d: system error, OPB (ESR = 0x%08x)\n",
- mal->def->index, esr);
- }
- return IRQ_HANDLED;
-}
-
-static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
-{
- if (likely(napi_schedule_prep(&mal->napi))) {
- MAL_DBG2("%d: schedule_poll" NL, mal->def->index);
- mal_disable_eob_irq(mal);
- __napi_schedule(&mal->napi);
- } else
- MAL_DBG2("%d: already in poll" NL, mal->def->index);
-}
-
-static irqreturn_t mal_txeob(int irq, void *dev_instance)
-{
- struct ibm_ocp_mal *mal = dev_instance;
- u32 r = get_mal_dcrn(mal, MAL_TXEOBISR);
- MAL_DBG2("%d: txeob %08x" NL, mal->def->index, r);
- mal_schedule_poll(mal);
- set_mal_dcrn(mal, MAL_TXEOBISR, r);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t mal_rxeob(int irq, void *dev_instance)
-{
- struct ibm_ocp_mal *mal = dev_instance;
- u32 r = get_mal_dcrn(mal, MAL_RXEOBISR);
- MAL_DBG2("%d: rxeob %08x" NL, mal->def->index, r);
- mal_schedule_poll(mal);
- set_mal_dcrn(mal, MAL_RXEOBISR, r);
- return IRQ_HANDLED;
-}
-
-static irqreturn_t mal_txde(int irq, void *dev_instance)
-{
- struct ibm_ocp_mal *mal = dev_instance;
- u32 deir = get_mal_dcrn(mal, MAL_TXDEIR);
- set_mal_dcrn(mal, MAL_TXDEIR, deir);
-
- MAL_DBG("%d: txde %08x" NL, mal->def->index, deir);
-
- if (net_ratelimit())
- printk(KERN_ERR
- "mal%d: TX descriptor error (TXDEIR = 0x%08x)\n",
- mal->def->index, deir);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t mal_rxde(int irq, void *dev_instance)
-{
- struct ibm_ocp_mal *mal = dev_instance;
- struct list_head *l;
- u32 deir = get_mal_dcrn(mal, MAL_RXDEIR);
-
- MAL_DBG("%d: rxde %08x" NL, mal->def->index, deir);
-
- list_for_each(l, &mal->list) {
- struct mal_commac *mc = list_entry(l, struct mal_commac, list);
- if (deir & mc->rx_chan_mask) {
- mc->rx_stopped = 1;
- mc->ops->rxde(mc->dev);
- }
- }
-
- mal_schedule_poll(mal);
- set_mal_dcrn(mal, MAL_RXDEIR, deir);
-
- return IRQ_HANDLED;
-}
-
-static int mal_poll(struct napi_struct *napi, int budget)
-{
- struct ibm_ocp_mal *mal = container_of(napi, struct ibm_ocp_mal, napi);
- struct list_head *l;
- int received = 0;
-
- MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget,
- rx_work_limit);
- again:
- /* Process TX skbs */
- list_for_each(l, &mal->poll_list) {
- struct mal_commac *mc =
- list_entry(l, struct mal_commac, poll_list);
- mc->ops->poll_tx(mc->dev);
- }
-
- /* Process RX skbs.
- * We _might_ need something more smart here to enforce polling fairness.
- */
- list_for_each(l, &mal->poll_list) {
- struct mal_commac *mc =
- list_entry(l, struct mal_commac, poll_list);
- int n = mc->ops->poll_rx(mc->dev, budget);
- if (n) {
- received += n;
- budget -= n;
- if (budget <= 0)
- goto more_work; // XXX What if this is the last one ?
- }
- }
-
- /* We need to disable IRQs to protect from RXDE IRQ here */
- local_irq_disable();
- __napi_complete(napi);
- mal_enable_eob_irq(mal);
- local_irq_enable();
-
- /* Check for "rotting" packet(s) */
- list_for_each(l, &mal->poll_list) {
- struct mal_commac *mc =
- list_entry(l, struct mal_commac, poll_list);
- if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) {
- MAL_DBG2("%d: rotting packet" NL, mal->def->index);
- if (napi_reschedule(napi))
- mal_disable_eob_irq(mal);
- else
- MAL_DBG2("%d: already in poll list" NL,
- mal->def->index);
-
- if (budget > 0)
- goto again;
- else
- goto more_work;
- }
- mc->ops->poll_tx(mc->dev);
- }
-
- more_work:
- MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, budget, received);
- return received;
-}
-
-static void mal_reset(struct ibm_ocp_mal *mal)
-{
- int n = 10;
- MAL_DBG("%d: reset" NL, mal->def->index);
-
- set_mal_dcrn(mal, MAL_CFG, MAL_CFG_SR);
-
- /* Wait for reset to complete (1 system clock) */
- while ((get_mal_dcrn(mal, MAL_CFG) & MAL_CFG_SR) && n)
- --n;
-
- if (unlikely(!n))
- printk(KERN_ERR "mal%d: reset timeout\n", mal->def->index);
-}
-
-int mal_get_regs_len(struct ibm_ocp_mal *mal)
-{
- return sizeof(struct emac_ethtool_regs_subhdr) +
- sizeof(struct ibm_mal_regs);
-}
-
-void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf)
-{
- struct emac_ethtool_regs_subhdr *hdr = buf;
- struct ibm_mal_regs *regs = (struct ibm_mal_regs *)(hdr + 1);
- struct ocp_func_mal_data *maldata = mal->def->additions;
- int i;
-
- hdr->version = MAL_VERSION;
- hdr->index = mal->def->index;
-
- regs->tx_count = maldata->num_tx_chans;
- regs->rx_count = maldata->num_rx_chans;
-
- regs->cfg = get_mal_dcrn(mal, MAL_CFG);
- regs->esr = get_mal_dcrn(mal, MAL_ESR);
- regs->ier = get_mal_dcrn(mal, MAL_IER);
- regs->tx_casr = get_mal_dcrn(mal, MAL_TXCASR);
- regs->tx_carr = get_mal_dcrn(mal, MAL_TXCARR);
- regs->tx_eobisr = get_mal_dcrn(mal, MAL_TXEOBISR);
- regs->tx_deir = get_mal_dcrn(mal, MAL_TXDEIR);
- regs->rx_casr = get_mal_dcrn(mal, MAL_RXCASR);
- regs->rx_carr = get_mal_dcrn(mal, MAL_RXCARR);
- regs->rx_eobisr = get_mal_dcrn(mal, MAL_RXEOBISR);
- regs->rx_deir = get_mal_dcrn(mal, MAL_RXDEIR);
-
- for (i = 0; i < regs->tx_count; ++i)
- regs->tx_ctpr[i] = get_mal_dcrn(mal, MAL_TXCTPR(i));
-
- for (i = 0; i < regs->rx_count; ++i) {
- regs->rx_ctpr[i] = get_mal_dcrn(mal, MAL_RXCTPR(i));
- regs->rcbs[i] = get_mal_dcrn(mal, MAL_RCBS(i));
- }
- return regs + 1;
-}
-
-static int __init mal_probe(struct ocp_device *ocpdev)
-{
- struct ibm_ocp_mal *mal;
- struct ocp_func_mal_data *maldata;
- int err = 0, i, bd_size;
-
- MAL_DBG("%d: probe" NL, ocpdev->def->index);
-
- maldata = ocpdev->def->additions;
- if (maldata == NULL) {
- printk(KERN_ERR "mal%d: missing additional data!\n",
- ocpdev->def->index);
- return -ENODEV;
- }
-
- mal = kzalloc(sizeof(struct ibm_ocp_mal), GFP_KERNEL);
- if (!mal) {
- printk(KERN_ERR
- "mal%d: out of memory allocating MAL structure!\n",
- ocpdev->def->index);
- return -ENOMEM;
- }
-
- /* XXX This only works for native dcr for now */
- mal->dcrhost = dcr_map(NULL, maldata->dcr_base, 0);
-
- mal->def = ocpdev->def;
-
- INIT_LIST_HEAD(&mal->poll_list);
- mal->napi.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
- mal->napi.poll = mal_poll;
-
- INIT_LIST_HEAD(&mal->list);
-
- /* Load power-on reset defaults */
- mal_reset(mal);
-
- /* Set the MAL configuration register */
- set_mal_dcrn(mal, MAL_CFG, MAL_CFG_DEFAULT | MAL_CFG_PLBB |
- MAL_CFG_OPBBL | MAL_CFG_LEA);
-
- mal_enable_eob_irq(mal);
-
- /* Allocate space for BD rings */
- BUG_ON(maldata->num_tx_chans <= 0 || maldata->num_tx_chans > 32);
- BUG_ON(maldata->num_rx_chans <= 0 || maldata->num_rx_chans > 32);
- bd_size = sizeof(struct mal_descriptor) *
- (NUM_TX_BUFF * maldata->num_tx_chans +
- NUM_RX_BUFF * maldata->num_rx_chans);
- mal->bd_virt =
- dma_alloc_coherent(&ocpdev->dev, bd_size, &mal->bd_dma, GFP_KERNEL);
-
- if (!mal->bd_virt) {
- printk(KERN_ERR
- "mal%d: out of memory allocating RX/TX descriptors!\n",
- mal->def->index);
- err = -ENOMEM;
- goto fail;
- }
- memset(mal->bd_virt, 0, bd_size);
-
- for (i = 0; i < maldata->num_tx_chans; ++i)
- set_mal_dcrn(mal, MAL_TXCTPR(i), mal->bd_dma +
- sizeof(struct mal_descriptor) *
- mal_tx_bd_offset(mal, i));
-
- for (i = 0; i < maldata->num_rx_chans; ++i)
- set_mal_dcrn(mal, MAL_RXCTPR(i), mal->bd_dma +
- sizeof(struct mal_descriptor) *
- mal_rx_bd_offset(mal, i));
-
- err = request_irq(maldata->serr_irq, mal_serr, 0, "MAL SERR", mal);
- if (err)
- goto fail2;
- err = request_irq(maldata->txde_irq, mal_txde, 0, "MAL TX DE", mal);
- if (err)
- goto fail3;
- err = request_irq(maldata->txeob_irq, mal_txeob, 0, "MAL TX EOB", mal);
- if (err)
- goto fail4;
- err = request_irq(maldata->rxde_irq, mal_rxde, 0, "MAL RX DE", mal);
- if (err)
- goto fail5;
- err = request_irq(maldata->rxeob_irq, mal_rxeob, 0, "MAL RX EOB", mal);
- if (err)
- goto fail6;
-
- /* Enable all MAL SERR interrupt sources */
- set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS);
-
- /* Advertise this instance to the rest of the world */
- ocp_set_drvdata(ocpdev, mal);
-
- mal_dbg_register(mal->def->index, mal);
-
- printk(KERN_INFO "mal%d: initialized, %d TX channels, %d RX channels\n",
- mal->def->index, maldata->num_tx_chans, maldata->num_rx_chans);
- return 0;
-
- fail6:
- free_irq(maldata->rxde_irq, mal);
- fail5:
- free_irq(maldata->txeob_irq, mal);
- fail4:
- free_irq(maldata->txde_irq, mal);
- fail3:
- free_irq(maldata->serr_irq, mal);
- fail2:
- dma_free_coherent(&ocpdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
- fail:
- kfree(mal);
- return err;
-}
-
-static void __exit mal_remove(struct ocp_device *ocpdev)
-{
- struct ibm_ocp_mal *mal = ocp_get_drvdata(ocpdev);
- struct ocp_func_mal_data *maldata = mal->def->additions;
-
- MAL_DBG("%d: remove" NL, mal->def->index);
-
- /* Synchronize with scheduled polling */
- napi_disable(&mal->napi);
-
- if (!list_empty(&mal->list)) {
- /* This is *very* bad */
- printk(KERN_EMERG
- "mal%d: commac list is not empty on remove!\n",
- mal->def->index);
- }
-
- ocp_set_drvdata(ocpdev, NULL);
-
- free_irq(maldata->serr_irq, mal);
- free_irq(maldata->txde_irq, mal);
- free_irq(maldata->txeob_irq, mal);
- free_irq(maldata->rxde_irq, mal);
- free_irq(maldata->rxeob_irq, mal);
-
- mal_reset(mal);
-
- mal_dbg_register(mal->def->index, NULL);
-
- dma_free_coherent(&ocpdev->dev,
- sizeof(struct mal_descriptor) *
- (NUM_TX_BUFF * maldata->num_tx_chans +
- NUM_RX_BUFF * maldata->num_rx_chans), mal->bd_virt,
- mal->bd_dma);
-
- kfree(mal);
-}
-
-/* Structure for a device driver */
-static struct ocp_device_id mal_ids[] = {
- { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_MAL },
- { .vendor = OCP_VENDOR_INVALID}
-};
-
-static struct ocp_driver mal_driver = {
- .name = "mal",
- .id_table = mal_ids,
-
- .probe = mal_probe,
- .remove = mal_remove,
-};
-
-int __init mal_init(void)
-{
- MAL_DBG(": init" NL);
- return ocp_register_driver(&mal_driver);
-}
-
-void __exit mal_exit(void)
-{
- MAL_DBG(": exit" NL);
- ocp_unregister_driver(&mal_driver);
-}
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
deleted file mode 100644
index b8adbe6d4b0..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_mal.h
- *
- * Memory Access Layer (MAL) support
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Armin Kuster <akuster@mvista.com>
- * Copyright 2002 MontaVista Softare 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.
- *
- */
-#ifndef __IBM_EMAC_MAL_H_
-#define __IBM_EMAC_MAL_H_
-
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/netdevice.h>
-
-#include <asm/io.h>
-#include <asm/dcr.h>
-
-/*
- * These MAL "versions" probably aren't the real versions IBM uses for these
- * MAL cores, I assigned them just to make #ifdefs in this file nicer and
- * reflect the fact that 40x and 44x have slightly different MALs. --ebs
- */
-#if defined(CONFIG_405GP) || defined(CONFIG_405GPR) || defined(CONFIG_405EP) || \
- defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_NP405H)
-#define MAL_VERSION 1
-#elif defined(CONFIG_440GP) || defined(CONFIG_440GX) || defined(CONFIG_440SP) || \
- defined(CONFIG_440SPE)
-#define MAL_VERSION 2
-#else
-#error "Unknown SoC, please check chip manual and choose MAL 'version'"
-#endif
-
-/* MALx DCR registers */
-#define MAL_CFG 0x00
-#define MAL_CFG_SR 0x80000000
-#define MAL_CFG_PLBB 0x00004000
-#define MAL_CFG_OPBBL 0x00000080
-#define MAL_CFG_EOPIE 0x00000004
-#define MAL_CFG_LEA 0x00000002
-#define MAL_CFG_SD 0x00000001
-#if MAL_VERSION == 1
-#define MAL_CFG_PLBP_MASK 0x00c00000
-#define MAL_CFG_PLBP_10 0x00800000
-#define MAL_CFG_GA 0x00200000
-#define MAL_CFG_OA 0x00100000
-#define MAL_CFG_PLBLE 0x00080000
-#define MAL_CFG_PLBT_MASK 0x00078000
-#define MAL_CFG_DEFAULT (MAL_CFG_PLBP_10 | MAL_CFG_PLBT_MASK)
-#elif MAL_VERSION == 2
-#define MAL_CFG_RPP_MASK 0x00c00000
-#define MAL_CFG_RPP_10 0x00800000
-#define MAL_CFG_RMBS_MASK 0x00300000
-#define MAL_CFG_WPP_MASK 0x000c0000
-#define MAL_CFG_WPP_10 0x00080000
-#define MAL_CFG_WMBS_MASK 0x00030000
-#define MAL_CFG_PLBLE 0x00008000
-#define MAL_CFG_DEFAULT (MAL_CFG_RMBS_MASK | MAL_CFG_WMBS_MASK | \
- MAL_CFG_RPP_10 | MAL_CFG_WPP_10)
-#else
-#error "Unknown MAL version"
-#endif
-
-#define MAL_ESR 0x01
-#define MAL_ESR_EVB 0x80000000
-#define MAL_ESR_CIDT 0x40000000
-#define MAL_ESR_CID_MASK 0x3e000000
-#define MAL_ESR_CID_SHIFT 25
-#define MAL_ESR_DE 0x00100000
-#define MAL_ESR_OTE 0x00040000
-#define MAL_ESR_OSE 0x00020000
-#define MAL_ESR_PEIN 0x00010000
-#define MAL_ESR_DEI 0x00000010
-#define MAL_ESR_OTEI 0x00000004
-#define MAL_ESR_OSEI 0x00000002
-#define MAL_ESR_PBEI 0x00000001
-#if MAL_VERSION == 1
-#define MAL_ESR_ONE 0x00080000
-#define MAL_ESR_ONEI 0x00000008
-#elif MAL_VERSION == 2
-#define MAL_ESR_PTE 0x00800000
-#define MAL_ESR_PRE 0x00400000
-#define MAL_ESR_PWE 0x00200000
-#define MAL_ESR_PTEI 0x00000080
-#define MAL_ESR_PREI 0x00000040
-#define MAL_ESR_PWEI 0x00000020
-#else
-#error "Unknown MAL version"
-#endif
-
-#define MAL_IER 0x02
-#define MAL_IER_DE 0x00000010
-#define MAL_IER_OTE 0x00000004
-#define MAL_IER_OE 0x00000002
-#define MAL_IER_PE 0x00000001
-#if MAL_VERSION == 1
-#define MAL_IER_NWE 0x00000008
-#define MAL_IER_SOC_EVENTS MAL_IER_NWE
-#elif MAL_VERSION == 2
-#define MAL_IER_PT 0x00000080
-#define MAL_IER_PRE 0x00000040
-#define MAL_IER_PWE 0x00000020
-#define MAL_IER_SOC_EVENTS (MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE)
-#else
-#error "Unknown MAL version"
-#endif
-#define MAL_IER_EVENTS (MAL_IER_SOC_EVENTS | MAL_IER_OTE | \
- MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE)
-
-#define MAL_TXCASR 0x04
-#define MAL_TXCARR 0x05
-#define MAL_TXEOBISR 0x06
-#define MAL_TXDEIR 0x07
-#define MAL_RXCASR 0x10
-#define MAL_RXCARR 0x11
-#define MAL_RXEOBISR 0x12
-#define MAL_RXDEIR 0x13
-#define MAL_TXCTPR(n) ((n) + 0x20)
-#define MAL_RXCTPR(n) ((n) + 0x40)
-#define MAL_RCBS(n) ((n) + 0x60)
-
-/* In reality MAL can handle TX buffers up to 4095 bytes long,
- * but this isn't a good round number :) --ebs
- */
-#define MAL_MAX_TX_SIZE 4080
-#define MAL_MAX_RX_SIZE 4080
-
-static inline int mal_rx_size(int len)
-{
- len = (len + 0xf) & ~0xf;
- return len > MAL_MAX_RX_SIZE ? MAL_MAX_RX_SIZE : len;
-}
-
-static inline int mal_tx_chunks(int len)
-{
- return (len + MAL_MAX_TX_SIZE - 1) / MAL_MAX_TX_SIZE;
-}
-
-#define MAL_CHAN_MASK(n) (0x80000000 >> (n))
-
-/* MAL Buffer Descriptor structure */
-struct mal_descriptor {
- u16 ctrl; /* MAL / Commac status control bits */
- u16 data_len; /* Max length is 4K-1 (12 bits) */
- u32 data_ptr; /* pointer to actual data buffer */
-};
-
-/* the following defines are for the MadMAL status and control registers. */
-/* MADMAL transmit and receive status/control bits */
-#define MAL_RX_CTRL_EMPTY 0x8000
-#define MAL_RX_CTRL_WRAP 0x4000
-#define MAL_RX_CTRL_CM 0x2000
-#define MAL_RX_CTRL_LAST 0x1000
-#define MAL_RX_CTRL_FIRST 0x0800
-#define MAL_RX_CTRL_INTR 0x0400
-#define MAL_RX_CTRL_SINGLE (MAL_RX_CTRL_LAST | MAL_RX_CTRL_FIRST)
-#define MAL_IS_SINGLE_RX(ctrl) (((ctrl) & MAL_RX_CTRL_SINGLE) == MAL_RX_CTRL_SINGLE)
-
-#define MAL_TX_CTRL_READY 0x8000
-#define MAL_TX_CTRL_WRAP 0x4000
-#define MAL_TX_CTRL_CM 0x2000
-#define MAL_TX_CTRL_LAST 0x1000
-#define MAL_TX_CTRL_INTR 0x0400
-
-struct mal_commac_ops {
- void (*poll_tx) (void *dev);
- int (*poll_rx) (void *dev, int budget);
- int (*peek_rx) (void *dev);
- void (*rxde) (void *dev);
-};
-
-struct mal_commac {
- struct mal_commac_ops *ops;
- void *dev;
- struct list_head poll_list;
- int rx_stopped;
-
- u32 tx_chan_mask;
- u32 rx_chan_mask;
- struct list_head list;
-};
-
-struct ibm_ocp_mal {
- dcr_host_t dcrhost;
-
- struct list_head poll_list;
- struct napi_struct napi;
-
- struct list_head list;
- u32 tx_chan_mask;
- u32 rx_chan_mask;
-
- dma_addr_t bd_dma;
- struct mal_descriptor *bd_virt;
-
- struct ocp_def *def;
-};
-
-static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
-{
- return dcr_read(mal->dcrhost, reg);
-}
-
-static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
-{
- dcr_write(mal->dcrhost, reg, val);
-}
-
-/* Register MAL devices */
-int mal_init(void) __init;
-void mal_exit(void) __exit;
-
-int mal_register_commac(struct ibm_ocp_mal *mal,
- struct mal_commac *commac) __init;
-void mal_unregister_commac(struct ibm_ocp_mal *mal, struct mal_commac *commac);
-int mal_set_rcbs(struct ibm_ocp_mal *mal, int channel, unsigned long size);
-
-/* Returns BD ring offset for a particular channel
- (in 'struct mal_descriptor' elements)
-*/
-int mal_tx_bd_offset(struct ibm_ocp_mal *mal, int channel);
-int mal_rx_bd_offset(struct ibm_ocp_mal *mal, int channel);
-
-void mal_enable_tx_channel(struct ibm_ocp_mal *mal, int channel);
-void mal_disable_tx_channel(struct ibm_ocp_mal *mal, int channel);
-void mal_enable_rx_channel(struct ibm_ocp_mal *mal, int channel);
-void mal_disable_rx_channel(struct ibm_ocp_mal *mal, int channel);
-
-/* Add/remove EMAC to/from MAL polling list */
-void mal_poll_add(struct ibm_ocp_mal *mal, struct mal_commac *commac);
-void mal_poll_del(struct ibm_ocp_mal *mal, struct mal_commac *commac);
-
-/* Ethtool MAL registers */
-struct ibm_mal_regs {
- u32 tx_count;
- u32 rx_count;
-
- u32 cfg;
- u32 esr;
- u32 ier;
- u32 tx_casr;
- u32 tx_carr;
- u32 tx_eobisr;
- u32 tx_deir;
- u32 rx_casr;
- u32 rx_carr;
- u32 rx_eobisr;
- u32 rx_deir;
- u32 tx_ctpr[32];
- u32 rx_ctpr[32];
- u32 rcbs[32];
-};
-
-int mal_get_regs_len(struct ibm_ocp_mal *mal);
-void *mal_dump_regs(struct ibm_ocp_mal *mal, void *buf);
-
-#endif /* __IBM_EMAC_MAL_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
deleted file mode 100644
index e57862b34ca..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_phy.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_phy.c
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
- * Borrowed from sungem_phy.c, though I only kept the generic MII
- * driver for now.
- *
- * This file should be shared with other drivers or eventually
- * merged as the "low level" part of miilib
- *
- * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
- * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-
-#include <asm/ocp.h>
-
-#include "ibm_emac_core.h"
-#include "ibm_emac_phy.h"
-
-static inline int phy_read(struct mii_phy *phy, int reg)
-{
- return phy->mdio_read(phy->dev, phy->address, reg);
-}
-
-static inline void phy_write(struct mii_phy *phy, int reg, int val)
-{
- phy->mdio_write(phy->dev, phy->address, reg, val);
-}
-
-/*
- * polls MII_BMCR until BMCR_RESET bit clears or operation times out.
- *
- * returns:
- * >= 0 => success, value in BMCR returned to caller
- * -EBUSY => failure, RESET bit never cleared
- * otherwise => failure, lower level PHY read failed
- */
-static int mii_spin_reset_complete(struct mii_phy *phy)
-{
- int val;
- int limit = 10000;
-
- while (limit--) {
- val = phy_read(phy, MII_BMCR);
- if (val >= 0 && !(val & BMCR_RESET))
- return val; /* success */
- udelay(10);
- }
- if (val & BMCR_RESET)
- val = -EBUSY;
-
- if (net_ratelimit())
- printk(KERN_ERR "emac%d: PHY reset timeout (%d)\n",
- ((struct ocp_enet_private *)phy->dev->priv)->def->index,
- val);
- return val;
-}
-
-int mii_reset_phy(struct mii_phy *phy)
-{
- int val;
-
- val = phy_read(phy, MII_BMCR);
- val &= ~BMCR_ISOLATE;
- val |= BMCR_RESET;
- phy_write(phy, MII_BMCR, val);
-
- udelay(300);
-
- val = mii_spin_reset_complete(phy);
- if (val >= 0 && (val & BMCR_ISOLATE))
- phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
-
- return val < 0;
-}
-
-static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
-{
- int ctl, adv;
-
- phy->autoneg = AUTONEG_ENABLE;
- phy->speed = SPEED_10;
- phy->duplex = DUPLEX_HALF;
- phy->pause = phy->asym_pause = 0;
- phy->advertising = advertise;
-
- /* Setup standard advertise */
- adv = phy_read(phy, MII_ADVERTISE);
- if (adv < 0)
- return adv;
- adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
- ADVERTISE_PAUSE_ASYM);
- if (advertise & ADVERTISED_10baseT_Half)
- adv |= ADVERTISE_10HALF;
- if (advertise & ADVERTISED_10baseT_Full)
- adv |= ADVERTISE_10FULL;
- if (advertise & ADVERTISED_100baseT_Half)
- adv |= ADVERTISE_100HALF;
- if (advertise & ADVERTISED_100baseT_Full)
- adv |= ADVERTISE_100FULL;
- if (advertise & ADVERTISED_Pause)
- adv |= ADVERTISE_PAUSE_CAP;
- if (advertise & ADVERTISED_Asym_Pause)
- adv |= ADVERTISE_PAUSE_ASYM;
- phy_write(phy, MII_ADVERTISE, adv);
-
- if (phy->features &
- (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
- adv = phy_read(phy, MII_CTRL1000);
- if (adv < 0)
- return adv;
- adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
- if (advertise & ADVERTISED_1000baseT_Full)
- adv |= ADVERTISE_1000FULL;
- if (advertise & ADVERTISED_1000baseT_Half)
- adv |= ADVERTISE_1000HALF;
- phy_write(phy, MII_CTRL1000, adv);
- }
-
- /* Start/Restart aneg */
- /* on some PHYs (e.g. National DP83843) a write to MII_ADVERTISE
- * causes BMCR_RESET to be set on the next read of MII_BMCR, which
- * if not checked for causes the PHY to be reset below */
- ctl = mii_spin_reset_complete(phy);
- if (ctl < 0)
- return ctl;
-
- ctl |= BMCR_ANENABLE | BMCR_ANRESTART;
- phy_write(phy, MII_BMCR, ctl);
-
- return 0;
-}
-
-static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
-{
- int ctl;
-
- phy->autoneg = AUTONEG_DISABLE;
- phy->speed = speed;
- phy->duplex = fd;
- phy->pause = phy->asym_pause = 0;
-
- /* First reset the PHY */
- mii_reset_phy(phy);
-
- ctl = phy_read(phy, MII_BMCR);
- if (ctl < 0)
- return ctl;
- ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_SPEED1000);
-
- /* Select speed & duplex */
- switch (speed) {
- case SPEED_10:
- break;
- case SPEED_100:
- ctl |= BMCR_SPEED100;
- break;
- case SPEED_1000:
- ctl |= BMCR_SPEED1000;
- break;
- default:
- return -EINVAL;
- }
- if (fd == DUPLEX_FULL)
- ctl |= BMCR_FULLDPLX;
- phy_write(phy, MII_BMCR, ctl);
-
- return 0;
-}
-
-static int genmii_poll_link(struct mii_phy *phy)
-{
- int status;
-
- /* Clear latched value with dummy read */
- phy_read(phy, MII_BMSR);
- status = phy_read(phy, MII_BMSR);
- if (status < 0 || (status & BMSR_LSTATUS) == 0)
- return 0;
- if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
- return 0;
- return 1;
-}
-
-static int genmii_read_link(struct mii_phy *phy)
-{
- if (phy->autoneg == AUTONEG_ENABLE) {
- int glpa = 0;
- int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
- if (lpa < 0)
- return lpa;
-
- if (phy->features &
- (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
- int adv = phy_read(phy, MII_CTRL1000);
- glpa = phy_read(phy, MII_STAT1000);
-
- if (glpa < 0 || adv < 0)
- return adv;
-
- glpa &= adv << 2;
- }
-
- phy->speed = SPEED_10;
- phy->duplex = DUPLEX_HALF;
- phy->pause = phy->asym_pause = 0;
-
- if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
- phy->speed = SPEED_1000;
- if (glpa & LPA_1000FULL)
- phy->duplex = DUPLEX_FULL;
- } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
- phy->speed = SPEED_100;
- if (lpa & LPA_100FULL)
- phy->duplex = DUPLEX_FULL;
- } else if (lpa & LPA_10FULL)
- phy->duplex = DUPLEX_FULL;
-
- if (phy->duplex == DUPLEX_FULL) {
- phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
- phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
- }
- } else {
- int bmcr = phy_read(phy, MII_BMCR);
- if (bmcr < 0)
- return bmcr;
-
- if (bmcr & BMCR_FULLDPLX)
- phy->duplex = DUPLEX_FULL;
- else
- phy->duplex = DUPLEX_HALF;
- if (bmcr & BMCR_SPEED1000)
- phy->speed = SPEED_1000;
- else if (bmcr & BMCR_SPEED100)
- phy->speed = SPEED_100;
- else
- phy->speed = SPEED_10;
-
- phy->pause = phy->asym_pause = 0;
- }
- return 0;
-}
-
-/* Generic implementation for most 10/100/1000 PHYs */
-static struct mii_phy_ops generic_phy_ops = {
- .setup_aneg = genmii_setup_aneg,
- .setup_forced = genmii_setup_forced,
- .poll_link = genmii_poll_link,
- .read_link = genmii_read_link
-};
-
-static struct mii_phy_def genmii_phy_def = {
- .phy_id = 0x00000000,
- .phy_id_mask = 0x00000000,
- .name = "Generic MII",
- .ops = &generic_phy_ops
-};
-
-/* CIS8201 */
-#define MII_CIS8201_10BTCSR 0x16
-#define TENBTCSR_ECHO_DISABLE 0x2000
-#define MII_CIS8201_EPCR 0x17
-#define EPCR_MODE_MASK 0x3000
-#define EPCR_GMII_MODE 0x0000
-#define EPCR_RGMII_MODE 0x1000
-#define EPCR_TBI_MODE 0x2000
-#define EPCR_RTBI_MODE 0x3000
-#define MII_CIS8201_ACSR 0x1c
-#define ACSR_PIN_PRIO_SELECT 0x0004
-
-static int cis8201_init(struct mii_phy *phy)
-{
- int epcr;
-
- epcr = phy_read(phy, MII_CIS8201_EPCR);
- if (epcr < 0)
- return epcr;
-
- epcr &= ~EPCR_MODE_MASK;
-
- switch (phy->mode) {
- case PHY_MODE_TBI:
- epcr |= EPCR_TBI_MODE;
- break;
- case PHY_MODE_RTBI:
- epcr |= EPCR_RTBI_MODE;
- break;
- case PHY_MODE_GMII:
- epcr |= EPCR_GMII_MODE;
- break;
- case PHY_MODE_RGMII:
- default:
- epcr |= EPCR_RGMII_MODE;
- }
-
- phy_write(phy, MII_CIS8201_EPCR, epcr);
-
- /* MII regs override strap pins */
- phy_write(phy, MII_CIS8201_ACSR,
- phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
-
- /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
- phy_write(phy, MII_CIS8201_10BTCSR,
- phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
-
- return 0;
-}
-
-static struct mii_phy_ops cis8201_phy_ops = {
- .init = cis8201_init,
- .setup_aneg = genmii_setup_aneg,
- .setup_forced = genmii_setup_forced,
- .poll_link = genmii_poll_link,
- .read_link = genmii_read_link
-};
-
-static struct mii_phy_def cis8201_phy_def = {
- .phy_id = 0x000fc410,
- .phy_id_mask = 0x000ffff0,
- .name = "CIS8201 Gigabit Ethernet",
- .ops = &cis8201_phy_ops
-};
-
-static struct mii_phy_def *mii_phy_table[] = {
- &cis8201_phy_def,
- &genmii_phy_def,
- NULL
-};
-
-int mii_phy_probe(struct mii_phy *phy, int address)
-{
- struct mii_phy_def *def;
- int i;
- int id;
-
- phy->autoneg = AUTONEG_DISABLE;
- phy->advertising = 0;
- phy->address = address;
- phy->speed = SPEED_10;
- phy->duplex = DUPLEX_HALF;
- phy->pause = phy->asym_pause = 0;
-
- /* Take PHY out of isolate mode and reset it. */
- if (mii_reset_phy(phy))
- return -ENODEV;
-
- /* Read ID and find matching entry */
- id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
- if (id < 0)
- return -ENODEV;
- for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
- if ((id & def->phy_id_mask) == def->phy_id)
- break;
- /* Should never be NULL (we have a generic entry), but... */
- if (!def)
- return -ENODEV;
-
- phy->def = def;
-
- /* Determine PHY features if needed */
- phy->features = def->features;
- if (!phy->features) {
- u16 bmsr = phy_read(phy, MII_BMSR);
- if (bmsr & BMSR_ANEGCAPABLE)
- phy->features |= SUPPORTED_Autoneg;
- if (bmsr & BMSR_10HALF)
- phy->features |= SUPPORTED_10baseT_Half;
- if (bmsr & BMSR_10FULL)
- phy->features |= SUPPORTED_10baseT_Full;
- if (bmsr & BMSR_100HALF)
- phy->features |= SUPPORTED_100baseT_Half;
- if (bmsr & BMSR_100FULL)
- phy->features |= SUPPORTED_100baseT_Full;
- if (bmsr & BMSR_ESTATEN) {
- u16 esr = phy_read(phy, MII_ESTATUS);
- if (esr & ESTATUS_1000_TFULL)
- phy->features |= SUPPORTED_1000baseT_Full;
- if (esr & ESTATUS_1000_THALF)
- phy->features |= SUPPORTED_1000baseT_Half;
- }
- phy->features |= SUPPORTED_MII;
- }
-
- /* Setup default advertising */
- phy->advertising = phy->features;
-
- return 0;
-}
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ibm_emac/ibm_emac_phy.h b/drivers/net/ibm_emac/ibm_emac_phy.h
deleted file mode 100644
index a70e0fea54c..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_phy.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_phy.h
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, PHY support
- *
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * February 2003
- *
- * Minor additions by Eugene Surovegin <ebs@ebshome.net>, 2004
- *
- * 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 file basically duplicates sungem_phy.{c,h} with different PHYs
- * supported. I'm looking into merging that in a single mii layer more
- * flexible than mii.c
- */
-
-#ifndef _IBM_OCP_PHY_H_
-#define _IBM_OCP_PHY_H_
-
-struct mii_phy;
-
-/* Operations supported by any kind of PHY */
-struct mii_phy_ops {
- int (*init) (struct mii_phy * phy);
- int (*suspend) (struct mii_phy * phy, int wol_options);
- int (*setup_aneg) (struct mii_phy * phy, u32 advertise);
- int (*setup_forced) (struct mii_phy * phy, int speed, int fd);
- int (*poll_link) (struct mii_phy * phy);
- int (*read_link) (struct mii_phy * phy);
-};
-
-/* Structure used to statically define an mii/gii based PHY */
-struct mii_phy_def {
- u32 phy_id; /* Concatenated ID1 << 16 | ID2 */
- u32 phy_id_mask; /* Significant bits */
- u32 features; /* Ethtool SUPPORTED_* defines or
- 0 for autodetect */
- int magic_aneg; /* Autoneg does all speed test for us */
- const char *name;
- const struct mii_phy_ops *ops;
-};
-
-/* An instance of a PHY, partially borrowed from mii_if_info */
-struct mii_phy {
- struct mii_phy_def *def;
- u32 advertising; /* Ethtool ADVERTISED_* defines */
- u32 features; /* Copied from mii_phy_def.features
- or determined automaticaly */
- int address; /* PHY address */
- int mode; /* PHY mode */
-
- /* 1: autoneg enabled, 0: disabled */
- int autoneg;
-
- /* forced speed & duplex (no autoneg)
- * partner speed & duplex & pause (autoneg)
- */
- int speed;
- int duplex;
- int pause;
- int asym_pause;
-
- /* Provided by host chip */
- struct net_device *dev;
- int (*mdio_read) (struct net_device * dev, int addr, int reg);
- void (*mdio_write) (struct net_device * dev, int addr, int reg,
- int val);
-};
-
-/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
- * filled, the remaining fields will be filled on return
- */
-int mii_phy_probe(struct mii_phy *phy, int address);
-int mii_reset_phy(struct mii_phy *phy);
-
-#endif /* _IBM_OCP_PHY_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.c b/drivers/net/ibm_emac/ibm_emac_rgmii.c
deleted file mode 100644
index 9dbb5e5936c..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_rgmii.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_rgmii.c
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Matt Porter <mporter@kernel.crashing.org>
- * Copyright 2004 MontaVista Software, 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.
- *
- */
-#include <linux/kernel.h>
-#include <linux/ethtool.h>
-#include <asm/io.h>
-
-#include "ibm_emac_core.h"
-#include "ibm_emac_debug.h"
-
-/* RGMIIx_FER */
-#define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4))
-#define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4))
-#define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4))
-#define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4))
-#define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4))
-
-/* RGMIIx_SSR */
-#define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8))
-#define RGMII_SSR_100(idx) (0x2 << ((idx) * 8))
-#define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8))
-
-/* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
-static inline int rgmii_valid_mode(int phy_mode)
-{
- return phy_mode == PHY_MODE_GMII ||
- phy_mode == PHY_MODE_RGMII ||
- phy_mode == PHY_MODE_TBI ||
- phy_mode == PHY_MODE_RTBI;
-}
-
-static inline const char *rgmii_mode_name(int mode)
-{
- switch (mode) {
- case PHY_MODE_RGMII:
- return "RGMII";
- case PHY_MODE_TBI:
- return "TBI";
- case PHY_MODE_GMII:
- return "GMII";
- case PHY_MODE_RTBI:
- return "RTBI";
- default:
- BUG();
- }
-}
-
-static inline u32 rgmii_mode_mask(int mode, int input)
-{
- switch (mode) {
- case PHY_MODE_RGMII:
- return RGMII_FER_RGMII(input);
- case PHY_MODE_TBI:
- return RGMII_FER_TBI(input);
- case PHY_MODE_GMII:
- return RGMII_FER_GMII(input);
- case PHY_MODE_RTBI:
- return RGMII_FER_RTBI(input);
- default:
- BUG();
- }
-}
-
-static int __init rgmii_init(struct ocp_device *ocpdev, int input, int mode)
-{
- struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
- struct rgmii_regs *p;
-
- RGMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, mode);
-
- if (!dev) {
- dev = kzalloc(sizeof(struct ibm_ocp_rgmii), GFP_KERNEL);
- if (!dev) {
- printk(KERN_ERR
- "rgmii%d: couldn't allocate device structure!\n",
- ocpdev->def->index);
- return -ENOMEM;
- }
-
- p = (struct rgmii_regs *)ioremap(ocpdev->def->paddr,
- sizeof(struct rgmii_regs));
- if (!p) {
- printk(KERN_ERR
- "rgmii%d: could not ioremap device registers!\n",
- ocpdev->def->index);
- kfree(dev);
- return -ENOMEM;
- }
-
- dev->base = p;
- ocp_set_drvdata(ocpdev, dev);
-
- /* Disable all inputs by default */
- out_be32(&p->fer, 0);
- } else
- p = dev->base;
-
- /* Enable this input */
- out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
-
- printk(KERN_NOTICE "rgmii%d: input %d in %s mode\n",
- ocpdev->def->index, input, rgmii_mode_name(mode));
-
- ++dev->users;
- return 0;
-}
-
-int __init rgmii_attach(void *emac)
-{
- struct ocp_enet_private *dev = emac;
- struct ocp_func_emac_data *emacdata = dev->def->additions;
-
- /* Check if we need to attach to a RGMII */
- if (emacdata->rgmii_idx >= 0 && rgmii_valid_mode(emacdata->phy_mode)) {
- dev->rgmii_input = emacdata->rgmii_mux;
- dev->rgmii_dev =
- ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_RGMII,
- emacdata->rgmii_idx);
- if (!dev->rgmii_dev) {
- printk(KERN_ERR "emac%d: unknown rgmii%d!\n",
- dev->def->index, emacdata->rgmii_idx);
- return -ENODEV;
- }
- if (rgmii_init
- (dev->rgmii_dev, dev->rgmii_input, emacdata->phy_mode)) {
- printk(KERN_ERR
- "emac%d: rgmii%d initialization failed!\n",
- dev->def->index, emacdata->rgmii_idx);
- return -ENODEV;
- }
- }
- return 0;
-}
-
-void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
-{
- struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
- u32 ssr = in_be32(&dev->base->ssr) & ~RGMII_SSR_MASK(input);
-
- RGMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
-
- if (speed == SPEED_1000)
- ssr |= RGMII_SSR_1000(input);
- else if (speed == SPEED_100)
- ssr |= RGMII_SSR_100(input);
-
- out_be32(&dev->base->ssr, ssr);
-}
-
-void __rgmii_fini(struct ocp_device *ocpdev, int input)
-{
- struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
- BUG_ON(!dev || dev->users == 0);
-
- RGMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
-
- /* Disable this input */
- out_be32(&dev->base->fer,
- in_be32(&dev->base->fer) & ~RGMII_FER_MASK(input));
-
- if (!--dev->users) {
- /* Free everything if this is the last user */
- ocp_set_drvdata(ocpdev, NULL);
- iounmap((void *)dev->base);
- kfree(dev);
- }
-}
-
-int __rgmii_get_regs_len(struct ocp_device *ocpdev)
-{
- return sizeof(struct emac_ethtool_regs_subhdr) +
- sizeof(struct rgmii_regs);
-}
-
-void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf)
-{
- struct ibm_ocp_rgmii *dev = ocp_get_drvdata(ocpdev);
- struct emac_ethtool_regs_subhdr *hdr = buf;
- struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1);
-
- hdr->version = 0;
- hdr->index = ocpdev->def->index;
- memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs));
- return regs + 1;
-}
diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h
deleted file mode 100644
index 971e45815c6..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_rgmii.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_rgmii.h
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
- *
- * Based on ocp_zmii.h/ibm_emac_zmii.h
- * Armin Kuster akuster@mvista.com
- *
- * Copyright 2004 MontaVista Software, Inc.
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * 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.
- */
-
-#ifndef _IBM_EMAC_RGMII_H_
-#define _IBM_EMAC_RGMII_H_
-
-
-/* RGMII bridge */
-struct rgmii_regs {
- u32 fer; /* Function enable register */
- u32 ssr; /* Speed select register */
-};
-
-/* RGMII device */
-struct ibm_ocp_rgmii {
- struct rgmii_regs __iomem *base;
- int users; /* number of EMACs using this RGMII bridge */
-};
-
-#ifdef CONFIG_IBM_EMAC_RGMII
-int rgmii_attach(void *emac) __init;
-
-void __rgmii_fini(struct ocp_device *ocpdev, int input);
-static inline void rgmii_fini(struct ocp_device *ocpdev, int input)
-{
- if (ocpdev)
- __rgmii_fini(ocpdev, input);
-}
-
-void rgmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
-
-int __rgmii_get_regs_len(struct ocp_device *ocpdev);
-static inline int rgmii_get_regs_len(struct ocp_device *ocpdev)
-{
- return ocpdev ? __rgmii_get_regs_len(ocpdev) : 0;
-}
-
-void *rgmii_dump_regs(struct ocp_device *ocpdev, void *buf);
-#else
-# define rgmii_attach(x) 0
-# define rgmii_fini(x,y) ((void)0)
-# define rgmii_set_speed(x,y,z) ((void)0)
-# define rgmii_get_regs_len(x) 0
-# define rgmii_dump_regs(x,buf) (buf)
-#endif /* !CONFIG_IBM_EMAC_RGMII */
-
-#endif /* _IBM_EMAC_RGMII_H_ */
diff --git a/drivers/net/ibm_emac/ibm_emac_tah.c b/drivers/net/ibm_emac/ibm_emac_tah.c
deleted file mode 100644
index 3c2d5ba522a..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_tah.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_tah.c
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
- *
- * Copyright 2004 MontaVista Software, Inc.
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.net>
- *
- * 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.
- */
-#include <asm/io.h>
-
-#include "ibm_emac_core.h"
-
-static int __init tah_init(struct ocp_device *ocpdev)
-{
- struct tah_regs *p;
-
- if (ocp_get_drvdata(ocpdev)) {
- printk(KERN_ERR "tah%d: already in use!\n", ocpdev->def->index);
- return -EBUSY;
- }
-
- /* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
- p = (struct tah_regs *)ioremap(ocpdev->def->paddr, sizeof(*p));
- if (!p) {
- printk(KERN_ERR "tah%d: could not ioremap device registers!\n",
- ocpdev->def->index);
- return -ENOMEM;
- }
- ocp_set_drvdata(ocpdev, p);
- __tah_reset(ocpdev);
-
- return 0;
-}
-
-int __init tah_attach(void *emac)
-{
- struct ocp_enet_private *dev = emac;
- struct ocp_func_emac_data *emacdata = dev->def->additions;
-
- /* Check if we need to attach to a TAH */
- if (emacdata->tah_idx >= 0) {
- dev->tah_dev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_TAH,
- emacdata->tah_idx);
- if (!dev->tah_dev) {
- printk(KERN_ERR "emac%d: unknown tah%d!\n",
- dev->def->index, emacdata->tah_idx);
- return -ENODEV;
- }
- if (tah_init(dev->tah_dev)) {
- printk(KERN_ERR
- "emac%d: tah%d initialization failed!\n",
- dev->def->index, emacdata->tah_idx);
- return -ENODEV;
- }
- }
- return 0;
-}
-
-void __tah_fini(struct ocp_device *ocpdev)
-{
- struct tah_regs *p = ocp_get_drvdata(ocpdev);
- BUG_ON(!p);
- ocp_set_drvdata(ocpdev, NULL);
- iounmap((void *)p);
-}
-
-void __tah_reset(struct ocp_device *ocpdev)
-{
- struct tah_regs *p = ocp_get_drvdata(ocpdev);
- int n;
-
- /* Reset TAH */
- out_be32(&p->mr, TAH_MR_SR);
- n = 100;
- while ((in_be32(&p->mr) & TAH_MR_SR) && n)
- --n;
-
- if (unlikely(!n))
- printk(KERN_ERR "tah%d: reset timeout\n", ocpdev->def->index);
-
- /* 10KB TAH TX FIFO accomodates the max MTU of 9000 */
- out_be32(&p->mr,
- TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
- TAH_MR_DIG);
-}
-
-int __tah_get_regs_len(struct ocp_device *ocpdev)
-{
- return sizeof(struct emac_ethtool_regs_subhdr) +
- sizeof(struct tah_regs);
-}
-
-void *tah_dump_regs(struct ocp_device *ocpdev, void *buf)
-{
- struct tah_regs *dev = ocp_get_drvdata(ocpdev);
- struct emac_ethtool_regs_subhdr *hdr = buf;
- struct tah_regs *regs = (struct tah_regs *)(hdr + 1);
-
- hdr->version = 0;
- hdr->index = ocpdev->def->index;
- memcpy_fromio(regs, dev, sizeof(struct tah_regs));
- return regs + 1;
-}
diff --git a/drivers/net/ibm_emac/ibm_emac_tah.h b/drivers/net/ibm_emac/ibm_emac_tah.h
deleted file mode 100644
index ccf64915e1e..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_tah.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_tah.h
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
- *
- * Copyright 2004 MontaVista Software, Inc.
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * Copyright (c) 2005 Eugene Surovegin <ebs@ebshome.net>
- *
- * 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.
- */
-
-#ifndef _IBM_EMAC_TAH_H
-#define _IBM_EMAC_TAH_H
-
-#include <linux/init.h>
-#include <asm/ocp.h>
-
-/* TAH */
-struct tah_regs {
- u32 revid;
- u32 pad[3];
- u32 mr;
- u32 ssr0;
- u32 ssr1;
- u32 ssr2;
- u32 ssr3;
- u32 ssr4;
- u32 ssr5;
- u32 tsr;
-};
-
-/* TAH engine */
-#define TAH_MR_CVR 0x80000000
-#define TAH_MR_SR 0x40000000
-#define TAH_MR_ST_256 0x01000000
-#define TAH_MR_ST_512 0x02000000
-#define TAH_MR_ST_768 0x03000000
-#define TAH_MR_ST_1024 0x04000000
-#define TAH_MR_ST_1280 0x05000000
-#define TAH_MR_ST_1536 0x06000000
-#define TAH_MR_TFS_16KB 0x00000000
-#define TAH_MR_TFS_2KB 0x00200000
-#define TAH_MR_TFS_4KB 0x00400000
-#define TAH_MR_TFS_6KB 0x00600000
-#define TAH_MR_TFS_8KB 0x00800000
-#define TAH_MR_TFS_10KB 0x00a00000
-#define TAH_MR_DTFP 0x00100000
-#define TAH_MR_DIG 0x00080000
-
-#ifdef CONFIG_IBM_EMAC_TAH
-int tah_attach(void *emac) __init;
-
-void __tah_fini(struct ocp_device *ocpdev);
-static inline void tah_fini(struct ocp_device *ocpdev)
-{
- if (ocpdev)
- __tah_fini(ocpdev);
-}
-
-void __tah_reset(struct ocp_device *ocpdev);
-static inline void tah_reset(struct ocp_device *ocpdev)
-{
- if (ocpdev)
- __tah_reset(ocpdev);
-}
-
-int __tah_get_regs_len(struct ocp_device *ocpdev);
-static inline int tah_get_regs_len(struct ocp_device *ocpdev)
-{
- return ocpdev ? __tah_get_regs_len(ocpdev) : 0;
-}
-
-void *tah_dump_regs(struct ocp_device *ocpdev, void *buf);
-#else
-# define tah_attach(x) 0
-# define tah_fini(x) ((void)0)
-# define tah_reset(x) ((void)0)
-# define tah_get_regs_len(x) 0
-# define tah_dump_regs(x,buf) (buf)
-#endif /* !CONFIG_IBM_EMAC_TAH */
-
-#endif /* _IBM_EMAC_TAH_H */
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c
deleted file mode 100644
index 2c0fdb0cabf..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_zmii.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_zmii.c
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Armin Kuster <akuster@mvista.com>
- * Copyright 2001 MontaVista Softare 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.
- *
- */
-#include <linux/kernel.h>
-#include <linux/ethtool.h>
-#include <asm/io.h>
-
-#include "ibm_emac_core.h"
-#include "ibm_emac_debug.h"
-
-/* ZMIIx_FER */
-#define ZMII_FER_MDI(idx) (0x80000000 >> ((idx) * 4))
-#define ZMII_FER_MDI_ALL (ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
- ZMII_FER_MDI(2) | ZMII_FER_MDI(3))
-
-#define ZMII_FER_SMII(idx) (0x40000000 >> ((idx) * 4))
-#define ZMII_FER_RMII(idx) (0x20000000 >> ((idx) * 4))
-#define ZMII_FER_MII(idx) (0x10000000 >> ((idx) * 4))
-
-/* ZMIIx_SSR */
-#define ZMII_SSR_SCI(idx) (0x40000000 >> ((idx) * 4))
-#define ZMII_SSR_FSS(idx) (0x20000000 >> ((idx) * 4))
-#define ZMII_SSR_SP(idx) (0x10000000 >> ((idx) * 4))
-
-/* ZMII only supports MII, RMII and SMII
- * we also support autodetection for backward compatibility
- */
-static inline int zmii_valid_mode(int mode)
-{
- return mode == PHY_MODE_MII ||
- mode == PHY_MODE_RMII ||
- mode == PHY_MODE_SMII ||
- mode == PHY_MODE_NA;
-}
-
-static inline const char *zmii_mode_name(int mode)
-{
- switch (mode) {
- case PHY_MODE_MII:
- return "MII";
- case PHY_MODE_RMII:
- return "RMII";
- case PHY_MODE_SMII:
- return "SMII";
- default:
- BUG();
- }
-}
-
-static inline u32 zmii_mode_mask(int mode, int input)
-{
- switch (mode) {
- case PHY_MODE_MII:
- return ZMII_FER_MII(input);
- case PHY_MODE_RMII:
- return ZMII_FER_RMII(input);
- case PHY_MODE_SMII:
- return ZMII_FER_SMII(input);
- default:
- return 0;
- }
-}
-
-static int __init zmii_init(struct ocp_device *ocpdev, int input, int *mode)
-{
- struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
- struct zmii_regs __iomem *p;
-
- ZMII_DBG("%d: init(%d, %d)" NL, ocpdev->def->index, input, *mode);
-
- if (!dev) {
- dev = kzalloc(sizeof(struct ibm_ocp_zmii), GFP_KERNEL);
- if (!dev) {
- printk(KERN_ERR
- "zmii%d: couldn't allocate device structure!\n",
- ocpdev->def->index);
- return -ENOMEM;
- }
- dev->mode = PHY_MODE_NA;
-
- p = ioremap(ocpdev->def->paddr, sizeof(struct zmii_regs));
- if (!p) {
- printk(KERN_ERR
- "zmii%d: could not ioremap device registers!\n",
- ocpdev->def->index);
- kfree(dev);
- return -ENOMEM;
- }
- dev->base = p;
- ocp_set_drvdata(ocpdev, dev);
-
- /* We may need FER value for autodetection later */
- dev->fer_save = in_be32(&p->fer);
-
- /* Disable all inputs by default */
- out_be32(&p->fer, 0);
- } else
- p = dev->base;
-
- if (!zmii_valid_mode(*mode)) {
- /* Probably an EMAC connected to RGMII,
- * but it still may need ZMII for MDIO
- */
- goto out;
- }
-
- /* Autodetect ZMII mode if not specified.
- * This is only for backward compatibility with the old driver.
- * Please, always specify PHY mode in your board port to avoid
- * any surprises.
- */
- if (dev->mode == PHY_MODE_NA) {
- if (*mode == PHY_MODE_NA) {
- u32 r = dev->fer_save;
-
- ZMII_DBG("%d: autodetecting mode, FER = 0x%08x" NL,
- ocpdev->def->index, r);
-
- if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
- dev->mode = PHY_MODE_MII;
- else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
- dev->mode = PHY_MODE_RMII;
- else
- dev->mode = PHY_MODE_SMII;
- } else
- dev->mode = *mode;
-
- printk(KERN_NOTICE "zmii%d: bridge in %s mode\n",
- ocpdev->def->index, zmii_mode_name(dev->mode));
- } else {
- /* All inputs must use the same mode */
- if (*mode != PHY_MODE_NA && *mode != dev->mode) {
- printk(KERN_ERR
- "zmii%d: invalid mode %d specified for input %d\n",
- ocpdev->def->index, *mode, input);
- return -EINVAL;
- }
- }
-
- /* Report back correct PHY mode,
- * it may be used during PHY initialization.
- */
- *mode = dev->mode;
-
- /* Enable this input */
- out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
- out:
- ++dev->users;
- return 0;
-}
-
-int __init zmii_attach(void *emac)
-{
- struct ocp_enet_private *dev = emac;
- struct ocp_func_emac_data *emacdata = dev->def->additions;
-
- if (emacdata->zmii_idx >= 0) {
- dev->zmii_input = emacdata->zmii_mux;
- dev->zmii_dev =
- ocp_find_device(OCP_VENDOR_IBM, OCP_FUNC_ZMII,
- emacdata->zmii_idx);
- if (!dev->zmii_dev) {
- printk(KERN_ERR "emac%d: unknown zmii%d!\n",
- dev->def->index, emacdata->zmii_idx);
- return -ENODEV;
- }
- if (zmii_init
- (dev->zmii_dev, dev->zmii_input, &emacdata->phy_mode)) {
- printk(KERN_ERR
- "emac%d: zmii%d initialization failed!\n",
- dev->def->index, emacdata->zmii_idx);
- return -ENODEV;
- }
- }
- return 0;
-}
-
-void __zmii_enable_mdio(struct ocp_device *ocpdev, int input)
-{
- struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
- u32 fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;
-
- ZMII_DBG2("%d: mdio(%d)" NL, ocpdev->def->index, input);
-
- out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
-}
-
-void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed)
-{
- struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
- u32 ssr = in_be32(&dev->base->ssr);
-
- ZMII_DBG("%d: speed(%d, %d)" NL, ocpdev->def->index, input, speed);
-
- if (speed == SPEED_100)
- ssr |= ZMII_SSR_SP(input);
- else
- ssr &= ~ZMII_SSR_SP(input);
-
- out_be32(&dev->base->ssr, ssr);
-}
-
-void __zmii_fini(struct ocp_device *ocpdev, int input)
-{
- struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
- BUG_ON(!dev || dev->users == 0);
-
- ZMII_DBG("%d: fini(%d)" NL, ocpdev->def->index, input);
-
- /* Disable this input */
- out_be32(&dev->base->fer,
- in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));
-
- if (!--dev->users) {
- /* Free everything if this is the last user */
- ocp_set_drvdata(ocpdev, NULL);
- iounmap(dev->base);
- kfree(dev);
- }
-}
-
-int __zmii_get_regs_len(struct ocp_device *ocpdev)
-{
- return sizeof(struct emac_ethtool_regs_subhdr) +
- sizeof(struct zmii_regs);
-}
-
-void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf)
-{
- struct ibm_ocp_zmii *dev = ocp_get_drvdata(ocpdev);
- struct emac_ethtool_regs_subhdr *hdr = buf;
- struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
-
- hdr->version = 0;
- hdr->index = ocpdev->def->index;
- memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));
- return regs + 1;
-}
diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h
deleted file mode 100644
index fad6d8bf983..00000000000
--- a/drivers/net/ibm_emac/ibm_emac_zmii.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * drivers/net/ibm_emac/ibm_emac_zmii.h
- *
- * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
- *
- * Copyright (c) 2004, 2005 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by
- * Armin Kuster <akuster@mvista.com>
- * Copyright 2001 MontaVista Softare 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.
- *
- */
-#ifndef _IBM_EMAC_ZMII_H_
-#define _IBM_EMAC_ZMII_H_
-
-#include <linux/init.h>
-#include <asm/ocp.h>
-
-/* ZMII bridge registers */
-struct zmii_regs {
- u32 fer; /* Function enable reg */
- u32 ssr; /* Speed select reg */
- u32 smiirs; /* SMII status reg */
-};
-
-/* ZMII device */
-struct ibm_ocp_zmii {
- struct zmii_regs __iomem *base;
- int mode; /* subset of PHY_MODE_XXXX */
- int users; /* number of EMACs using this ZMII bridge */
- u32 fer_save; /* FER value left by firmware */
-};
-
-#ifdef CONFIG_IBM_EMAC_ZMII
-int zmii_attach(void *emac) __init;
-
-void __zmii_fini(struct ocp_device *ocpdev, int input);
-static inline void zmii_fini(struct ocp_device *ocpdev, int input)
-{
- if (ocpdev)
- __zmii_fini(ocpdev, input);
-}
-
-void __zmii_enable_mdio(struct ocp_device *ocpdev, int input);
-static inline void zmii_enable_mdio(struct ocp_device *ocpdev, int input)
-{
- if (ocpdev)
- __zmii_enable_mdio(ocpdev, input);
-}
-
-void __zmii_set_speed(struct ocp_device *ocpdev, int input, int speed);
-static inline void zmii_set_speed(struct ocp_device *ocpdev, int input,
- int speed)
-{
- if (ocpdev)
- __zmii_set_speed(ocpdev, input, speed);
-}
-
-int __zmii_get_regs_len(struct ocp_device *ocpdev);
-static inline int zmii_get_regs_len(struct ocp_device *ocpdev)
-{
- return ocpdev ? __zmii_get_regs_len(ocpdev) : 0;
-}
-
-void *zmii_dump_regs(struct ocp_device *ocpdev, void *buf);
-
-#else
-# define zmii_attach(x) 0
-# define zmii_fini(x,y) ((void)0)
-# define zmii_enable_mdio(x,y) ((void)0)
-# define zmii_set_speed(x,y,z) ((void)0)
-# define zmii_get_regs_len(x) 0
-# define zmii_dump_regs(x,buf) (buf)
-#endif /* !CONFIG_IBM_EMAC_ZMII */
-
-#endif /* _IBM_EMAC_ZMII_H_ */
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 61af02b4c9d..2e720f26ca8 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -295,7 +295,9 @@ static void emac_rx_disable(struct emac_instance *dev)
static inline void emac_netif_stop(struct emac_instance *dev)
{
netif_tx_lock_bh(dev->ndev);
+ netif_addr_lock(dev->ndev);
dev->no_mcast = 1;
+ netif_addr_unlock(dev->ndev);
netif_tx_unlock_bh(dev->ndev);
dev->ndev->trans_start = jiffies; /* prevent tx timeout */
mal_poll_disable(dev->mal, &dev->commac);
@@ -305,9 +307,11 @@ static inline void emac_netif_stop(struct emac_instance *dev)
static inline void emac_netif_start(struct emac_instance *dev)
{
netif_tx_lock_bh(dev->ndev);
+ netif_addr_lock(dev->ndev);
dev->no_mcast = 0;
if (dev->mcast_pending && netif_running(dev->ndev))
__emac_set_multicast_list(dev);
+ netif_addr_unlock(dev->ndev);
netif_tx_unlock_bh(dev->ndev);
netif_wake_queue(dev->ndev);
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index af233b59153..0960e69b2da 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -35,7 +35,6 @@
#include <linux/moduleparam.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
-#include <linux/lockdep.h>
#define TX_TIMEOUT (2*HZ)
@@ -228,16 +227,6 @@ static struct rtnl_link_ops ifb_link_ops __read_mostly = {
module_param(numifbs, int, 0);
MODULE_PARM_DESC(numifbs, "Number of ifb devices");
-/*
- * dev_ifb->queue_lock is usually taken after dev->ingress_lock,
- * reversely to e.g. qdisc_lock_tree(). It should be safe until
- * ifb doesn't take dev->queue_lock with dev_ifb->ingress_lock.
- * But lockdep should know that ifb has different locks from dev.
- */
-static struct lock_class_key ifb_queue_lock_key;
-static struct lock_class_key ifb_ingress_lock_key;
-
-
static int __init ifb_init_one(int index)
{
struct net_device *dev_ifb;
@@ -258,9 +247,6 @@ static int __init ifb_init_one(int index)
if (err < 0)
goto err;
- lockdep_set_class(&dev_ifb->queue_lock, &ifb_queue_lock_key);
- lockdep_set_class(&dev_ifb->ingress_lock, &ifb_ingress_lock_key);
-
return 0;
err:
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index cda3ec87909..e098f234770 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -31,6 +31,7 @@
#include <linux/types.h>
#include <linux/slab.h>
+#include <linux/if_ether.h>
#include "e1000_mac.h"
#include "e1000_82575.h"
@@ -45,7 +46,6 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *);
static s32 igb_init_hw_82575(struct e1000_hw *);
static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
-static void igb_rar_set_82575(struct e1000_hw *, u8 *, u32);
static s32 igb_reset_hw_82575(struct e1000_hw *);
static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
static s32 igb_setup_copper_link_82575(struct e1000_hw *);
@@ -84,6 +84,12 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
case E1000_DEV_ID_82575GB_QUAD_COPPER:
mac->type = e1000_82575;
break;
+ case E1000_DEV_ID_82576:
+ case E1000_DEV_ID_82576_FIBER:
+ case E1000_DEV_ID_82576_SERDES:
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ mac->type = e1000_82576;
+ break;
default:
return -E1000_ERR_MAC_INIT;
break;
@@ -128,6 +134,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
mac->mta_reg_count = 128;
/* Set rar entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
+ if (mac->type == e1000_82576)
+ mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
/* Set if part includes ASF firmware */
mac->asf_firmware_present = true;
/* Set if manageability features are enabled. */
@@ -171,6 +179,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
* for setting word_size.
*/
size += NVM_WORD_SIZE_BASE_SHIFT;
+
+ /* EEPROM access above 16k is unsupported */
+ if (size > 14)
+ size = 14;
nvm->word_size = 1 << size;
/* setup PHY parameters */
@@ -222,7 +234,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
}
/**
- * e1000_acquire_phy_82575 - Acquire rights to access PHY
+ * igb_acquire_phy_82575 - Acquire rights to access PHY
* @hw: pointer to the HW structure
*
* Acquire access rights to the correct PHY. This is a
@@ -238,7 +250,7 @@ static s32 igb_acquire_phy_82575(struct e1000_hw *hw)
}
/**
- * e1000_release_phy_82575 - Release rights to access PHY
+ * igb_release_phy_82575 - Release rights to access PHY
* @hw: pointer to the HW structure
*
* A wrapper to release access rights to the correct PHY. This is a
@@ -253,7 +265,7 @@ static void igb_release_phy_82575(struct e1000_hw *hw)
}
/**
- * e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
+ * igb_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
@@ -268,7 +280,7 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u32 i, i2ccmd = 0;
if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
- hw_dbg(hw, "PHY Address %u is out of range\n", offset);
+ hw_dbg("PHY Address %u is out of range\n", offset);
return -E1000_ERR_PARAM;
}
@@ -291,11 +303,11 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
break;
}
if (!(i2ccmd & E1000_I2CCMD_READY)) {
- hw_dbg(hw, "I2CCMD Read did not complete\n");
+ hw_dbg("I2CCMD Read did not complete\n");
return -E1000_ERR_PHY;
}
if (i2ccmd & E1000_I2CCMD_ERROR) {
- hw_dbg(hw, "I2CCMD Error bit set\n");
+ hw_dbg("I2CCMD Error bit set\n");
return -E1000_ERR_PHY;
}
@@ -306,7 +318,7 @@ static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
}
/**
- * e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
+ * igb_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
@@ -322,7 +334,7 @@ static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 phy_data_swapped;
if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
- hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+ hw_dbg("PHY Address %d is out of range\n", offset);
return -E1000_ERR_PARAM;
}
@@ -349,11 +361,11 @@ static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
break;
}
if (!(i2ccmd & E1000_I2CCMD_READY)) {
- hw_dbg(hw, "I2CCMD Write did not complete\n");
+ hw_dbg("I2CCMD Write did not complete\n");
return -E1000_ERR_PHY;
}
if (i2ccmd & E1000_I2CCMD_ERROR) {
- hw_dbg(hw, "I2CCMD Error bit set\n");
+ hw_dbg("I2CCMD Error bit set\n");
return -E1000_ERR_PHY;
}
@@ -361,10 +373,10 @@ static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
}
/**
- * e1000_get_phy_id_82575 - Retreive PHY addr and id
+ * igb_get_phy_id_82575 - Retrieve PHY addr and id
* @hw: pointer to the HW structure
*
- * Retreives the PHY address and ID for both PHY's which do and do not use
+ * Retrieves the PHY address and ID for both PHY's which do and do not use
* sgmi interface.
**/
static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
@@ -393,9 +405,8 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
for (phy->addr = 1; phy->addr < 8; phy->addr++) {
ret_val = igb_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
if (ret_val == 0) {
- hw_dbg(hw, "Vendor ID 0x%08X read at address %u\n",
- phy_id,
- phy->addr);
+ hw_dbg("Vendor ID 0x%08X read at address %u\n",
+ phy_id, phy->addr);
/*
* At the time of this writing, The M88 part is
* the only supported SGMII PHY product.
@@ -403,8 +414,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
if (phy_id == M88_VENDOR)
break;
} else {
- hw_dbg(hw, "PHY address %u was unreadable\n",
- phy->addr);
+ hw_dbg("PHY address %u was unreadable\n", phy->addr);
}
}
@@ -422,7 +432,7 @@ out:
}
/**
- * e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
+ * igb_phy_hw_reset_sgmii_82575 - Performs a PHY reset
* @hw: pointer to the HW structure
*
* Resets the PHY using the serial gigabit media independent interface.
@@ -436,7 +446,7 @@ static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
* available to us at this time.
*/
- hw_dbg(hw, "Soft resetting SGMII attached PHY...\n");
+ hw_dbg("Soft resetting SGMII attached PHY...\n");
/*
* SFP documentation requires the following to configure the SPF module
@@ -453,7 +463,7 @@ out:
}
/**
- * e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
+ * igb_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
* @hw: pointer to the HW structure
* @active: true to enable LPLU, false to disable
*
@@ -471,34 +481,29 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
s32 ret_val;
u16 data;
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- &data);
+ ret_val = phy->ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (active) {
data |= IGP02E1000_PM_D0_LPLU;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP02E1000_PHY_POWER_MGMT,
- data);
+ ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+ data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
+ ret_val = phy->ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+ &data);
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
+ ret_val = phy->ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+ data);
if (ret_val)
goto out;
} else {
data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP02E1000_PHY_POWER_MGMT,
- data);
+ ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+ data);
/*
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* during Dx states where the power conservation is most
@@ -506,29 +511,25 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
+ ret_val = phy->ops.read_phy_reg(hw,
+ IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
+ ret_val = phy->ops.write_phy_reg(hw,
+ IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
+ ret_val = phy->ops.read_phy_reg(hw,
+ IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- data);
+ ret_val = phy->ops.write_phy_reg(hw,
+ IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
}
@@ -539,10 +540,10 @@ out:
}
/**
- * e1000_acquire_nvm_82575 - Request for access to EEPROM
+ * igb_acquire_nvm_82575 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
- * Acquire the necessary semaphores for exclussive access to the EEPROM.
+ * Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
@@ -565,7 +566,7 @@ out:
}
/**
- * e1000_release_nvm_82575 - Release exclusive access to EEPROM
+ * igb_release_nvm_82575 - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
@@ -578,7 +579,7 @@ static void igb_release_nvm_82575(struct e1000_hw *hw)
}
/**
- * e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
+ * igb_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
@@ -613,7 +614,7 @@ static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
}
if (i == timeout) {
- hw_dbg(hw, "Can't access resource, SW_FW_SYNC timeout.\n");
+ hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
ret_val = -E1000_ERR_SWFW_SYNC;
goto out;
}
@@ -628,7 +629,7 @@ out:
}
/**
- * e1000_release_swfw_sync_82575 - Release SW/FW semaphore
+ * igb_release_swfw_sync_82575 - Release SW/FW semaphore
* @hw: pointer to the HW structure
* @mask: specifies which semaphore to acquire
*
@@ -650,7 +651,7 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
}
/**
- * e1000_get_cfg_done_82575 - Read config done bit
+ * igb_get_cfg_done_82575 - Read config done bit
* @hw: pointer to the HW structure
*
* Read the management control register for the config done bit for
@@ -675,7 +676,7 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
timeout--;
}
if (!timeout)
- hw_dbg(hw, "MNG configuration cycle has not completed.\n");
+ hw_dbg("MNG configuration cycle has not completed.\n");
/* If EEPROM is not marked present, init the PHY manually */
if (((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) &&
@@ -686,7 +687,7 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
}
/**
- * e1000_check_for_link_82575 - Check for link
+ * igb_check_for_link_82575 - Check for link
* @hw: pointer to the HW structure
*
* If sgmii is enabled, then use the pcs register to determine link, otherwise
@@ -701,20 +702,19 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
if ((hw->phy.media_type != e1000_media_type_copper) ||
(igb_sgmii_active_82575(hw)))
ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
- &duplex);
+ &duplex);
else
ret_val = igb_check_for_copper_link(hw);
return ret_val;
}
-
/**
- * e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
+ * igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
*
- * Using the physical coding sub-layer (PCS), retreive the current speed and
+ * Using the physical coding sub-layer (PCS), retrieve the current speed and
* duplex, then store the values in the pointers provided.
**/
static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
@@ -764,24 +764,135 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
}
/**
- * e1000_rar_set_82575 - Set receive address register
+ * igb_init_rx_addrs_82575 - Initialize receive address's
* @hw: pointer to the HW structure
- * @addr: pointer to the receive address
- * @index: receive address array register
+ * @rar_count: receive address registers
*
- * Sets the receive address array register at index to the address passed
- * in by addr.
+ * Setups the receive address registers by setting the base receive address
+ * register to the devices MAC address and clearing all the other receive
+ * address registers to 0.
**/
-static void igb_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
+static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
{
- if (index < E1000_RAR_ENTRIES_82575)
- igb_rar_set(hw, addr, index);
+ u32 i;
+ u8 addr[6] = {0,0,0,0,0,0};
+ /*
+ * This function is essentially the same as that of
+ * e1000_init_rx_addrs_generic. However it also takes care
+ * of the special case where the register offset of the
+ * second set of RARs begins elsewhere. This is implicitly taken care by
+ * function e1000_rar_set_generic.
+ */
+
+ hw_dbg("e1000_init_rx_addrs_82575");
+
+ /* Setup the receive address */
+ hw_dbg("Programming MAC Address into RAR[0]\n");
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+ /* Zero out the other (rar_entry_count - 1) receive addresses */
+ hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
+ for (i = 1; i < rar_count; i++)
+ hw->mac.ops.rar_set(hw, addr, i);
+}
+
+/**
+ * igb_update_mc_addr_list_82575 - Update Multicast addresses
+ * @hw: pointer to the HW structure
+ * @mc_addr_list: array of multicast addresses to program
+ * @mc_addr_count: number of multicast addresses to program
+ * @rar_used_count: the first RAR register free to program
+ * @rar_count: total number of supported Receive Address Registers
+ *
+ * Updates the Receive Address Registers and Multicast Table Array.
+ * The caller must have a packed mc_addr_list of multicast addresses.
+ * The parameter rar_count will usually be hw->mac.rar_entry_count
+ * unless there are workarounds that change this.
+ **/
+void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 rar_used_count, u32 rar_count)
+{
+ u32 hash_value;
+ u32 i;
+ u8 addr[6] = {0,0,0,0,0,0};
+ /*
+ * This function is essentially the same as that of
+ * igb_update_mc_addr_list_generic. However it also takes care
+ * of the special case where the register offset of the
+ * second set of RARs begins elsewhere. This is implicitly taken care by
+ * function e1000_rar_set_generic.
+ */
+
+ /*
+ * Load the first set of multicast addresses into the exact
+ * filters (RAR). If there are not enough to fill the RAR
+ * array, clear the filters.
+ */
+ for (i = rar_used_count; i < rar_count; i++) {
+ if (mc_addr_count) {
+ igb_rar_set(hw, mc_addr_list, i);
+ mc_addr_count--;
+ mc_addr_list += ETH_ALEN;
+ } else {
+ igb_rar_set(hw, addr, i);
+ }
+ }
+
+ /* Clear the old settings from the MTA */
+ hw_dbg("Clearing MTA\n");
+ for (i = 0; i < hw->mac.mta_reg_count; i++) {
+ array_wr32(E1000_MTA, i, 0);
+ wrfl();
+ }
+
+ /* Load any remaining multicast addresses into the hash table. */
+ for (; mc_addr_count > 0; mc_addr_count--) {
+ hash_value = igb_hash_mc_addr(hw, mc_addr_list);
+ hw_dbg("Hash value = 0x%03X\n", hash_value);
+ hw->mac.ops.mta_set(hw, hash_value);
+ mc_addr_list += ETH_ALEN;
+ }
+}
+
+/**
+ * igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of fiber serdes, shut down optics and PCS on driver unload
+ * when management pass thru is not enabled.
+ **/
+void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
+{
+ u32 reg;
+
+ if (hw->mac.type != e1000_82576 ||
+ (hw->phy.media_type != e1000_media_type_fiber &&
+ hw->phy.media_type != e1000_media_type_internal_serdes))
+ return;
+
+ /* if the management interface is not enabled, then power down */
+ if (!igb_enable_mng_pass_thru(hw)) {
+ /* Disable PCS to turn off link */
+ reg = rd32(E1000_PCS_CFG0);
+ reg &= ~E1000_PCS_CFG_PCS_EN;
+ wr32(E1000_PCS_CFG0, reg);
+
+ /* shutdown the laser */
+ reg = rd32(E1000_CTRL_EXT);
+ reg |= E1000_CTRL_EXT_SDP7_DATA;
+ wr32(E1000_CTRL_EXT, reg);
+
+ /* flush the write to verify completion */
+ wrfl();
+ msleep(1);
+ }
return;
}
/**
- * e1000_reset_hw_82575 - Reset hardware
+ * igb_reset_hw_82575 - Reset hardware
* @hw: pointer to the HW structure
*
* This resets the hardware into a known state. This is a
@@ -798,9 +909,9 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
*/
ret_val = igb_disable_pcie_master(hw);
if (ret_val)
- hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+ hw_dbg("PCI-E Master disable polling has failed.\n");
- hw_dbg(hw, "Masking off all interrupts\n");
+ hw_dbg("Masking off all interrupts\n");
wr32(E1000_IMC, 0xffffffff);
wr32(E1000_RCTL, 0);
@@ -811,7 +922,7 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
ctrl = rd32(E1000_CTRL);
- hw_dbg(hw, "Issuing a global reset to MAC\n");
+ hw_dbg("Issuing a global reset to MAC\n");
wr32(E1000_CTRL, ctrl | E1000_CTRL_RST);
ret_val = igb_get_auto_rd_done(hw);
@@ -821,7 +932,7 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
* return with an error. This can happen in situations
* where there is no eeprom and prevents getting link.
*/
- hw_dbg(hw, "Auto Read Done did not complete\n");
+ hw_dbg("Auto Read Done did not complete\n");
}
/* If EEPROM is not present, run manual init scripts */
@@ -838,7 +949,7 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
}
/**
- * e1000_init_hw_82575 - Initialize hardware
+ * igb_init_hw_82575 - Initialize hardware
* @hw: pointer to the HW structure
*
* This inits the hardware readying it for operation.
@@ -852,18 +963,18 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
/* Initialize identification LED */
ret_val = igb_id_led_init(hw);
if (ret_val) {
- hw_dbg(hw, "Error initializing identification LED\n");
+ hw_dbg("Error initializing identification LED\n");
/* This is not fatal and we should not stop init due to this */
}
/* Disabling VLAN filtering */
- hw_dbg(hw, "Initializing the IEEE VLAN\n");
+ hw_dbg("Initializing the IEEE VLAN\n");
igb_clear_vfta(hw);
/* Setup the receive address */
- igb_init_rx_addrs(hw, rar_count);
+ igb_init_rx_addrs_82575(hw, rar_count);
/* Zero out the Multicast HASH table */
- hw_dbg(hw, "Zeroing the MTA\n");
+ hw_dbg("Zeroing the MTA\n");
for (i = 0; i < mac->mta_reg_count; i++)
array_wr32(E1000_MTA, i, 0);
@@ -882,7 +993,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
}
/**
- * e1000_setup_copper_link_82575 - Configure copper link settings
+ * igb_setup_copper_link_82575 - Configure copper link settings
* @hw: pointer to the HW structure
*
* Configures the link for auto-neg or forced speed and duplex. Then we check
@@ -933,10 +1044,10 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
* PHY will be set to 10H, 10F, 100H or 100F
* depending on user settings.
*/
- hw_dbg(hw, "Forcing Speed and Duplex\n");
+ hw_dbg("Forcing Speed and Duplex\n");
ret_val = igb_phy_force_speed_duplex(hw);
if (ret_val) {
- hw_dbg(hw, "Error Forcing Speed and Duplex\n");
+ hw_dbg("Error Forcing Speed and Duplex\n");
goto out;
}
}
@@ -949,20 +1060,17 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
* Check link status. Wait up to 100 microseconds for link to become
* valid.
*/
- ret_val = igb_phy_has_link(hw,
- COPPER_LINK_UP_LIMIT,
- 10,
- &link);
+ ret_val = igb_phy_has_link(hw, COPPER_LINK_UP_LIMIT, 10, &link);
if (ret_val)
goto out;
if (link) {
- hw_dbg(hw, "Valid link established!!!\n");
+ hw_dbg("Valid link established!!!\n");
/* Config the MAC and PHY after link is up */
igb_config_collision_dist(hw);
ret_val = igb_config_fc_after_link_up(hw);
} else {
- hw_dbg(hw, "Unable to establish link!!!\n");
+ hw_dbg("Unable to establish link!!!\n");
}
out:
@@ -970,7 +1078,7 @@ out:
}
/**
- * e1000_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes
+ * igb_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes
* @hw: pointer to the HW structure
*
* Configures speed and duplex for fiber and serdes links.
@@ -1018,7 +1126,7 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
- hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
+ hw_dbg("Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
} else {
/* Set PCS register for forced speed */
reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */
@@ -1026,7 +1134,7 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
E1000_PCS_LCTL_FSD | /* Force Speed */
E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
- hw_dbg(hw, "Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
+ hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
}
wr32(E1000_PCS_LCTL, reg);
@@ -1034,7 +1142,7 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
}
/**
- * e1000_configure_pcs_link_82575 - Configure PCS link
+ * igb_configure_pcs_link_82575 - Configure PCS link
* @hw: pointer to the HW structure
*
* Configure the physical coding sub-layer (PCS) link. The PCS link is
@@ -1067,7 +1175,7 @@ static s32 igb_configure_pcs_link_82575(struct e1000_hw *hw)
*/
reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
} else {
- /* Set PCS regiseter for forced speed */
+ /* Set PCS register for forced speed */
/* Turn off bits for full duplex, speed, and autoneg */
reg &= ~(E1000_PCS_LCTL_FSV_1000 |
@@ -1088,8 +1196,7 @@ static s32 igb_configure_pcs_link_82575(struct e1000_hw *hw)
E1000_PCS_LCTL_FORCE_LINK |
E1000_PCS_LCTL_FLV_LINK_UP;
- hw_dbg(hw,
- "Wrote 0x%08X to PCS_LCTL to configure forced link\n",
+ hw_dbg("Wrote 0x%08X to PCS_LCTL to configure forced link\n",
reg);
}
wr32(E1000_PCS_LCTL, reg);
@@ -1099,7 +1206,7 @@ out:
}
/**
- * e1000_sgmii_active_82575 - Return sgmii state
+ * igb_sgmii_active_82575 - Return sgmii state
* @hw: pointer to the HW structure
*
* 82575 silicon has a serialized gigabit media independent interface (sgmii)
@@ -1125,7 +1232,71 @@ out:
}
/**
- * e1000_reset_init_script_82575 - Inits HW defaults after reset
+ * igb_translate_register_82576 - Translate the proper register offset
+ * @reg: e1000 register to be read
+ *
+ * Registers in 82576 are located in different offsets than other adapters
+ * even though they function in the same manner. This function takes in
+ * the name of the register to read and returns the correct offset for
+ * 82576 silicon.
+ **/
+u32 igb_translate_register_82576(u32 reg)
+{
+ /*
+ * Some of the Kawela registers are located at different
+ * offsets than they are in older adapters.
+ * Despite the difference in location, the registers
+ * function in the same manner.
+ */
+ switch (reg) {
+ case E1000_TDBAL(0):
+ reg = 0x0E000;
+ break;
+ case E1000_TDBAH(0):
+ reg = 0x0E004;
+ break;
+ case E1000_TDLEN(0):
+ reg = 0x0E008;
+ break;
+ case E1000_TDH(0):
+ reg = 0x0E010;
+ break;
+ case E1000_TDT(0):
+ reg = 0x0E018;
+ break;
+ case E1000_TXDCTL(0):
+ reg = 0x0E028;
+ break;
+ case E1000_RDBAL(0):
+ reg = 0x0C000;
+ break;
+ case E1000_RDBAH(0):
+ reg = 0x0C004;
+ break;
+ case E1000_RDLEN(0):
+ reg = 0x0C008;
+ break;
+ case E1000_RDH(0):
+ reg = 0x0C010;
+ break;
+ case E1000_RDT(0):
+ reg = 0x0C018;
+ break;
+ case E1000_RXDCTL(0):
+ reg = 0x0C028;
+ break;
+ case E1000_SRRCTL(0):
+ reg = 0x0C00C;
+ break;
+ default:
+ break;
+ }
+
+ return reg;
+}
+
+/**
+ * igb_reset_init_script_82575 - Inits HW defaults after reset
* @hw: pointer to the HW structure
*
* Inits recommended HW defaults after a reset when there is no EEPROM
@@ -1134,7 +1305,7 @@ out:
static s32 igb_reset_init_script_82575(struct e1000_hw *hw)
{
if (hw->mac.type == e1000_82575) {
- hw_dbg(hw, "Running reset init script for 82575\n");
+ hw_dbg("Running reset init script for 82575\n");
/* SerDes configuration via SERDESCTRL */
igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x00, 0x0C);
igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x01, 0x78);
@@ -1161,7 +1332,7 @@ static s32 igb_reset_init_script_82575(struct e1000_hw *hw)
}
/**
- * e1000_read_mac_addr_82575 - Read device MAC address
+ * igb_read_mac_addr_82575 - Read device MAC address
* @hw: pointer to the HW structure
**/
static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
@@ -1175,7 +1346,7 @@ static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
}
/**
- * e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
+ * igb_clear_hw_cntrs_82575 - Clear device specific hardware counters
* @hw: pointer to the HW structure
*
* Clears the hardware counters by reading the counter registers.
@@ -1238,11 +1409,84 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
temp = rd32(E1000_SCVPC);
}
+/**
+ * igb_rx_fifo_flush_82575 - Clean rx fifo after RX enable
+ * @hw: pointer to the HW structure
+ *
+ * After rx enable if managability is enabled then there is likely some
+ * bad data at the start of the fifo and possibly in the DMA fifo. This
+ * function clears the fifos and flushes any packets that came in as rx was
+ * being enabled.
+ **/
+void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
+{
+ u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
+ int i, ms_wait;
+
+ if (hw->mac.type != e1000_82575 ||
+ !(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN))
+ return;
+
+ /* Disable all RX queues */
+ for (i = 0; i < 4; i++) {
+ rxdctl[i] = rd32(E1000_RXDCTL(i));
+ wr32(E1000_RXDCTL(i),
+ rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
+ }
+ /* Poll all queues to verify they have shut down */
+ for (ms_wait = 0; ms_wait < 10; ms_wait++) {
+ msleep(1);
+ rx_enabled = 0;
+ for (i = 0; i < 4; i++)
+ rx_enabled |= rd32(E1000_RXDCTL(i));
+ if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
+ break;
+ }
+
+ if (ms_wait == 10)
+ hw_dbg("Queue disable timed out after 10ms\n");
+
+ /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
+ * incoming packets are rejected. Set enable and wait 2ms so that
+ * any packet that was coming in as RCTL.EN was set is flushed
+ */
+ rfctl = rd32(E1000_RFCTL);
+ wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
+
+ rlpml = rd32(E1000_RLPML);
+ wr32(E1000_RLPML, 0);
+
+ rctl = rd32(E1000_RCTL);
+ temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
+ temp_rctl |= E1000_RCTL_LPE;
+
+ wr32(E1000_RCTL, temp_rctl);
+ wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
+ wrfl();
+ msleep(2);
+
+ /* Enable RX queues that were previously enabled and restore our
+ * previous state
+ */
+ for (i = 0; i < 4; i++)
+ wr32(E1000_RXDCTL(i), rxdctl[i]);
+ wr32(E1000_RCTL, rctl);
+ wrfl();
+
+ wr32(E1000_RLPML, rlpml);
+ wr32(E1000_RFCTL, rfctl);
+
+ /* Flush receive errors generated by workaround */
+ rd32(E1000_ROC);
+ rd32(E1000_RNBC);
+ rd32(E1000_MPC);
+}
+
static struct e1000_mac_operations e1000_mac_ops_82575 = {
.reset_hw = igb_reset_hw_82575,
.init_hw = igb_init_hw_82575,
.check_for_link = igb_check_for_link_82575,
- .rar_set = igb_rar_set_82575,
+ .rar_set = igb_rar_set,
.read_mac_addr = igb_read_mac_addr_82575,
.get_speed_and_duplex = igb_get_speed_and_duplex_copper,
};
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index 76ea846663d..2f848e578a2 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -28,7 +28,13 @@
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
+u32 igb_translate_register_82576(u32 reg);
+void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
+extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
+
#define E1000_RAR_ENTRIES_82575 16
+#define E1000_RAR_ENTRIES_82576 24
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
@@ -56,7 +62,7 @@
#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
-/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
+/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
@@ -93,6 +99,8 @@ union e1000_adv_rx_desc {
/* RSS Hash results */
/* RSS Packet Types as indicated in the receive descriptor */
+#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */
+#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
@@ -142,9 +150,25 @@ struct e1000_adv_tx_context_desc {
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
/* Direct Cache Access (DCA) definitions */
-
-
-
-#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */
+#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
+#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
+
+#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
+#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
+
+#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
+#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
+#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
+#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
+
+#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
+#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
+#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+
+/* Additional DCA related definitions, note change in position of CPUID */
+#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
+#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
+#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
+#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
#endif
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 8da9ffedc42..afdba3c9073 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -90,13 +90,18 @@
#define E1000_I2CCMD_ERROR 0x80000000
#define E1000_MAX_SGMII_PHY_REG_ADDR 255
#define E1000_I2CCMD_PHY_TIMEOUT 200
+#define E1000_IVAR_VALID 0x80
+#define E1000_GPIE_NSICR 0x00000001
+#define E1000_GPIE_MSIX_MODE 0x00000010
+#define E1000_GPIE_EIAME 0x40000000
+#define E1000_GPIE_PBA 0x80000000
-/* Receive Decriptor bit definitions */
+/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
@@ -213,6 +218,7 @@
/* Device Control */
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
+#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
@@ -244,6 +250,7 @@
*/
#define E1000_CONNSW_ENRGSRC 0x4
+#define E1000_PCS_CFG_PCS_EN 8
#define E1000_PCS_LCTL_FLV_LINK_UP 1
#define E1000_PCS_LCTL_FSV_100 2
#define E1000_PCS_LCTL_FSV_1000 4
@@ -253,6 +260,7 @@
#define E1000_PCS_LCTL_AN_ENABLE 0x10000
#define E1000_PCS_LCTL_AN_RESTART 0x20000
#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000
+#define E1000_ENABLE_SERDES_LOOPBACK 0x0410
#define E1000_PCS_LSTS_LINK_OK 1
#define E1000_PCS_LSTS_SPEED_100 2
@@ -340,6 +348,7 @@
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Header split receive */
+#define E1000_RFCTL_LEF 0x00040000
/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD 15
@@ -359,6 +368,7 @@
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
#define E1000_PBA_24K 0x0018
#define E1000_PBA_34K 0x0022
+#define E1000_PBA_64K 0x0040 /* 64KB */
#define IFS_MAX 80
#define IFS_MIN 40
@@ -379,7 +389,7 @@
#define E1000_ICR_RXO 0x00000040 /* rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
+#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */
#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
@@ -443,12 +453,6 @@
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-/* queue 0 Rx descriptor FIFO parity error */
-/* queue 0 Tx descriptor FIFO parity error */
-/* host arb read buffer parity error */
-/* packet buffer parity error */
-/* queue 1 Rx descriptor FIFO parity error */
-/* queue 1 Tx descriptor FIFO parity error */
/* Extended Interrupt Mask Set */
#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
@@ -457,12 +461,6 @@
/* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-/* queue 0 Rx descriptor FIFO parity error */
-/* queue 0 Tx descriptor FIFO parity error */
-/* host arb read buffer parity error */
-/* packet buffer parity error */
-/* queue 1 Rx descriptor FIFO parity error */
-/* queue 1 Tx descriptor FIFO parity error */
/* Extended Interrupt Cause Set */
@@ -539,6 +537,7 @@
/* PHY Control Register */
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define MII_CR_POWER_DOWN 0x0800 /* Power down */
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
@@ -567,7 +566,6 @@
/* 1000BASE-T Control Register */
#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
- /* 0=DTE device */
#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
/* 0=Configure PHY as Slave */
#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
@@ -581,7 +579,7 @@
/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
+#define PHY_STATUS 0x01 /* Status Register */
#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
@@ -708,8 +706,8 @@
/* Auto crossover enabled all speeds */
#define M88E1000_PSCR_AUTO_X_MODE 0x0060
/*
- * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold
- * 0=Normal 10BASE-T RX Threshold
+ * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T Rx Threshold
+ * 0=Normal 10BASE-T Rx Threshold
*/
/* 1=5-bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 7b2c70a3b8c..19fa4ee96f2 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -38,6 +38,10 @@
struct e1000_hw;
+#define E1000_DEV_ID_82576 0x10C9
+#define E1000_DEV_ID_82576_FIBER 0x10E6
+#define E1000_DEV_ID_82576_SERDES 0x10E7
+#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
@@ -50,6 +54,7 @@ struct e1000_hw;
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
+ e1000_82576,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
@@ -410,14 +415,17 @@ struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
+ bool (*check_mng_mode)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
void (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
+ void (*mta_set)(struct e1000_hw *, u32);
};
struct e1000_phy_operations {
s32 (*acquire_phy)(struct e1000_hw *);
+ s32 (*check_reset_block)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
@@ -586,14 +594,10 @@ struct e1000_hw {
#ifdef DEBUG
extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
-#define hw_dbg(hw, format, arg...) \
+#define hw_dbg(format, arg...) \
printk(KERN_DEBUG "%s: " format, igb_get_hw_dev_name(hw), ##arg)
#else
-static inline int __attribute__ ((format (printf, 2, 3)))
-hw_dbg(struct e1000_hw *hw, const char *format, ...)
-{
- return 0;
-}
+#define hw_dbg(format, arg...)
#endif
#endif
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 3e84a3f0c1d..20408aa1f91 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -36,10 +36,9 @@
static s32 igb_set_default_fc(struct e1000_hw *hw);
static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
-static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
/**
- * e1000_remove_device - Free device specific structure
+ * igb_remove_device - Free device specific structure
* @hw: pointer to the HW structure
*
* If a device specific structure was allocated, this function will
@@ -73,7 +72,7 @@ static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
}
/**
- * e1000_get_bus_info_pcie - Get PCIe bus information
+ * igb_get_bus_info_pcie - Get PCIe bus information
* @hw: pointer to the HW structure
*
* Determines and stores the system bus information for a particular
@@ -113,7 +112,7 @@ s32 igb_get_bus_info_pcie(struct e1000_hw *hw)
}
/**
- * e1000_clear_vfta - Clear VLAN filter table
+ * igb_clear_vfta - Clear VLAN filter table
* @hw: pointer to the HW structure
*
* Clears the register array which contains the VLAN filter table by
@@ -130,7 +129,7 @@ void igb_clear_vfta(struct e1000_hw *hw)
}
/**
- * e1000_write_vfta - Write value to VLAN filter table
+ * igb_write_vfta - Write value to VLAN filter table
* @hw: pointer to the HW structure
* @offset: register offset in VLAN filter table
* @value: register value written to VLAN filter table
@@ -145,7 +144,7 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
}
/**
- * e1000_init_rx_addrs - Initialize receive address's
+ * igb_init_rx_addrs - Initialize receive address's
* @hw: pointer to the HW structure
* @rar_count: receive address registers
*
@@ -158,12 +157,12 @@ void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
u32 i;
/* Setup the receive address */
- hw_dbg(hw, "Programming MAC Address into RAR[0]\n");
+ hw_dbg("Programming MAC Address into RAR[0]\n");
hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
/* Zero out the other (rar_entry_count - 1) receive addresses */
- hw_dbg(hw, "Clearing RAR[1-%u]\n", rar_count-1);
+ hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
for (i = 1; i < rar_count; i++) {
array_wr32(E1000_RA, (i << 1), 0);
wrfl();
@@ -173,7 +172,7 @@ void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
}
/**
- * e1000_check_alt_mac_addr - Check for alternate MAC addr
+ * igb_check_alt_mac_addr - Check for alternate MAC addr
* @hw: pointer to the HW structure
*
* Checks the nvm for an alternate MAC address. An alternate MAC address
@@ -193,7 +192,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
ret_val = hw->nvm.ops.read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
@@ -209,7 +208,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
offset = nvm_alt_mac_addr_offset + (i >> 1);
ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
@@ -233,7 +232,7 @@ out:
}
/**
- * e1000_rar_set - Set receive address register
+ * igb_rar_set - Set receive address register
* @hw: pointer to the HW structure
* @addr: pointer to the receive address
* @index: receive address array register
@@ -263,7 +262,7 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
}
/**
- * e1000_mta_set - Set multicast filter table address
+ * igb_mta_set - Set multicast filter table address
* @hw: pointer to the HW structure
* @hash_value: determines the MTA register and bit to set
*
@@ -298,7 +297,7 @@ static void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
}
/**
- * e1000_update_mc_addr_list - Update Multicast addresses
+ * igb_update_mc_addr_list - Update Multicast addresses
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
@@ -336,7 +335,7 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
}
/* Clear the old settings from the MTA */
- hw_dbg(hw, "Clearing MTA\n");
+ hw_dbg("Clearing MTA\n");
for (i = 0; i < hw->mac.mta_reg_count; i++) {
array_wr32(E1000_MTA, i, 0);
wrfl();
@@ -345,14 +344,14 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
/* Load any remaining multicast addresses into the hash table. */
for (; mc_addr_count > 0; mc_addr_count--) {
hash_value = igb_hash_mc_addr(hw, mc_addr_list);
- hw_dbg(hw, "Hash value = 0x%03X\n", hash_value);
+ hw_dbg("Hash value = 0x%03X\n", hash_value);
igb_mta_set(hw, hash_value);
mc_addr_list += ETH_ALEN;
}
}
/**
- * e1000_hash_mc_addr - Generate a multicast hash value
+ * igb_hash_mc_addr - Generate a multicast hash value
* @hw: pointer to the HW structure
* @mc_addr: pointer to a multicast address
*
@@ -360,7 +359,7 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
* the multicast filter table array address and new table value. See
* igb_mta_set()
**/
-static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
+u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
{
u32 hash_value, hash_mask;
u8 bit_shift = 0;
@@ -423,7 +422,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
}
/**
- * e1000_clear_hw_cntrs_base - Clear base hardware counters
+ * igb_clear_hw_cntrs_base - Clear base hardware counters
* @hw: pointer to the HW structure
*
* Clears the base hardware counters by reading the counter registers.
@@ -472,7 +471,7 @@ void igb_clear_hw_cntrs_base(struct e1000_hw *hw)
}
/**
- * e1000_check_for_copper_link - Check for link (Copper)
+ * igb_check_for_copper_link - Check for link (Copper)
* @hw: pointer to the HW structure
*
* Checks to see of the link status of the hardware has changed. If a
@@ -540,14 +539,14 @@ s32 igb_check_for_copper_link(struct e1000_hw *hw)
*/
ret_val = igb_config_fc_after_link_up(hw);
if (ret_val)
- hw_dbg(hw, "Error configuring flow control\n");
+ hw_dbg("Error configuring flow control\n");
out:
return ret_val;
}
/**
- * e1000_setup_link - Setup flow control and link settings
+ * igb_setup_link - Setup flow control and link settings
* @hw: pointer to the HW structure
*
* Determines which flow control settings to use, then configures flow
@@ -578,7 +577,7 @@ s32 igb_setup_link(struct e1000_hw *hw)
*/
hw->fc.original_type = hw->fc.type;
- hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
+ hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.type);
/* Call the necessary media_type subroutine to configure the link. */
ret_val = hw->mac.ops.setup_physical_interface(hw);
@@ -591,8 +590,7 @@ s32 igb_setup_link(struct e1000_hw *hw)
* control is disabled, because it does not hurt anything to
* initialize these registers.
*/
- hw_dbg(hw,
- "Initializing the Flow Control address, type and timer regs\n");
+ hw_dbg("Initializing the Flow Control address, type and timer regs\n");
wr32(E1000_FCT, FLOW_CONTROL_TYPE);
wr32(E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
wr32(E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
@@ -606,7 +604,7 @@ out:
}
/**
- * e1000_config_collision_dist - Configure collision distance
+ * igb_config_collision_dist - Configure collision distance
* @hw: pointer to the HW structure
*
* Configures the collision distance to the default value and is used
@@ -627,7 +625,7 @@ void igb_config_collision_dist(struct e1000_hw *hw)
}
/**
- * e1000_set_fc_watermarks - Set flow control high/low watermarks
+ * igb_set_fc_watermarks - Set flow control high/low watermarks
* @hw: pointer to the HW structure
*
* Sets the flow control high/low threshold (watermark) registers. If
@@ -665,7 +663,7 @@ static s32 igb_set_fc_watermarks(struct e1000_hw *hw)
}
/**
- * e1000_set_default_fc - Set flow control default values
+ * igb_set_default_fc - Set flow control default values
* @hw: pointer to the HW structure
*
* Read the EEPROM for the default values for flow control and store the
@@ -689,7 +687,7 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
&nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
@@ -706,7 +704,7 @@ out:
}
/**
- * e1000_force_mac_fc - Force the MAC's flow control settings
+ * igb_force_mac_fc - Force the MAC's flow control settings
* @hw: pointer to the HW structure
*
* Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the
@@ -740,7 +738,7 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
* 3: Both Rx and TX flow control (symmetric) is enabled.
* other: No other values should be possible at this point.
*/
- hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);
+ hw_dbg("hw->fc.type = %u\n", hw->fc.type);
switch (hw->fc.type) {
case e1000_fc_none:
@@ -758,7 +756,7 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
break;
default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
+ hw_dbg("Flow control param set incorrectly\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -770,7 +768,7 @@ out:
}
/**
- * e1000_config_fc_after_link_up - Configures flow control after link
+ * igb_config_fc_after_link_up - Configures flow control after link
* @hw: pointer to the HW structure
*
* Checks the status of auto-negotiation after link up to ensure that the
@@ -801,7 +799,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
}
if (ret_val) {
- hw_dbg(hw, "Error forcing flow control settings\n");
+ hw_dbg("Error forcing flow control settings\n");
goto out;
}
@@ -827,7 +825,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
goto out;
if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
- hw_dbg(hw, "Copper PHY and Auto Neg "
+ hw_dbg("Copper PHY and Auto Neg "
"has not completed.\n");
goto out;
}
@@ -893,11 +891,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
*/
if (hw->fc.original_type == e1000_fc_full) {
hw->fc.type = e1000_fc_full;
- hw_dbg(hw, "Flow Control = FULL.\r\n");
+ hw_dbg("Flow Control = FULL.\r\n");
} else {
hw->fc.type = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = "
- "RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = "
+ "RX PAUSE frames only.\r\n");
}
}
/*
@@ -913,7 +911,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.type = e1000_fc_tx_pause;
- hw_dbg(hw, "Flow Control = TX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
}
/*
* For transmitting PAUSE frames ONLY.
@@ -928,7 +926,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.type = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
}
/*
* Per the IEEE spec, at this point flow control should be
@@ -955,10 +953,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
hw->fc.original_type == e1000_fc_tx_pause) ||
hw->fc.strict_ieee) {
hw->fc.type = e1000_fc_none;
- hw_dbg(hw, "Flow Control = NONE.\r\n");
+ hw_dbg("Flow Control = NONE.\r\n");
} else {
hw->fc.type = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
}
/*
@@ -968,7 +966,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
*/
ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
if (ret_val) {
- hw_dbg(hw, "Error getting link speed and duplex\n");
+ hw_dbg("Error getting link speed and duplex\n");
goto out;
}
@@ -981,7 +979,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
*/
ret_val = igb_force_mac_fc(hw);
if (ret_val) {
- hw_dbg(hw, "Error forcing flow control settings\n");
+ hw_dbg("Error forcing flow control settings\n");
goto out;
}
}
@@ -991,7 +989,7 @@ out:
}
/**
- * e1000_get_speed_and_duplex_copper - Retreive current speed/duplex
+ * igb_get_speed_and_duplex_copper - Retreive current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1007,28 +1005,28 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
status = rd32(E1000_STATUS);
if (status & E1000_STATUS_SPEED_1000) {
*speed = SPEED_1000;
- hw_dbg(hw, "1000 Mbs, ");
+ hw_dbg("1000 Mbs, ");
} else if (status & E1000_STATUS_SPEED_100) {
*speed = SPEED_100;
- hw_dbg(hw, "100 Mbs, ");
+ hw_dbg("100 Mbs, ");
} else {
*speed = SPEED_10;
- hw_dbg(hw, "10 Mbs, ");
+ hw_dbg("10 Mbs, ");
}
if (status & E1000_STATUS_FD) {
*duplex = FULL_DUPLEX;
- hw_dbg(hw, "Full Duplex\n");
+ hw_dbg("Full Duplex\n");
} else {
*duplex = HALF_DUPLEX;
- hw_dbg(hw, "Half Duplex\n");
+ hw_dbg("Half Duplex\n");
}
return 0;
}
/**
- * e1000_get_hw_semaphore - Acquire hardware semaphore
+ * igb_get_hw_semaphore - Acquire hardware semaphore
* @hw: pointer to the HW structure
*
* Acquire the HW semaphore to access the PHY or NVM
@@ -1051,7 +1049,7 @@ s32 igb_get_hw_semaphore(struct e1000_hw *hw)
}
if (i == timeout) {
- hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
+ hw_dbg("Driver can't access device - SMBI bit is set.\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
@@ -1071,7 +1069,7 @@ s32 igb_get_hw_semaphore(struct e1000_hw *hw)
if (i == timeout) {
/* Release semaphores */
igb_put_hw_semaphore(hw);
- hw_dbg(hw, "Driver can't access the NVM\n");
+ hw_dbg("Driver can't access the NVM\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
@@ -1081,7 +1079,7 @@ out:
}
/**
- * e1000_put_hw_semaphore - Release hardware semaphore
+ * igb_put_hw_semaphore - Release hardware semaphore
* @hw: pointer to the HW structure
*
* Release hardware semaphore used to access the PHY or NVM
@@ -1098,7 +1096,7 @@ void igb_put_hw_semaphore(struct e1000_hw *hw)
}
/**
- * e1000_get_auto_rd_done - Check for auto read completion
+ * igb_get_auto_rd_done - Check for auto read completion
* @hw: pointer to the HW structure
*
* Check EEPROM for Auto Read done bit.
@@ -1117,7 +1115,7 @@ s32 igb_get_auto_rd_done(struct e1000_hw *hw)
}
if (i == AUTO_READ_DONE_TIMEOUT) {
- hw_dbg(hw, "Auto read by HW from NVM has not completed.\n");
+ hw_dbg("Auto read by HW from NVM has not completed.\n");
ret_val = -E1000_ERR_RESET;
goto out;
}
@@ -1127,7 +1125,7 @@ out:
}
/**
- * e1000_valid_led_default - Verify a valid default LED config
+ * igb_valid_led_default - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
*
@@ -1140,7 +1138,7 @@ static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
ret_val = hw->nvm.ops.read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
@@ -1152,7 +1150,7 @@ out:
}
/**
- * e1000_id_led_init -
+ * igb_id_led_init -
* @hw: pointer to the HW structure
*
**/
@@ -1217,7 +1215,7 @@ out:
}
/**
- * e1000_cleanup_led - Set LED config to default operation
+ * igb_cleanup_led - Set LED config to default operation
* @hw: pointer to the HW structure
*
* Remove the current LED configuration and set the LED configuration
@@ -1230,7 +1228,7 @@ s32 igb_cleanup_led(struct e1000_hw *hw)
}
/**
- * e1000_blink_led - Blink LED
+ * igb_blink_led - Blink LED
* @hw: pointer to the HW structure
*
* Blink the led's which are set to be on.
@@ -1263,7 +1261,7 @@ s32 igb_blink_led(struct e1000_hw *hw)
}
/**
- * e1000_led_off - Turn LED off
+ * igb_led_off - Turn LED off
* @hw: pointer to the HW structure
*
* Turn LED off.
@@ -1290,7 +1288,7 @@ s32 igb_led_off(struct e1000_hw *hw)
}
/**
- * e1000_disable_pcie_master - Disables PCI-express master access
+ * igb_disable_pcie_master - Disables PCI-express master access
* @hw: pointer to the HW structure
*
* Returns 0 (0) if successful, else returns -10
@@ -1322,7 +1320,7 @@ s32 igb_disable_pcie_master(struct e1000_hw *hw)
}
if (!timeout) {
- hw_dbg(hw, "Master requests are pending.\n");
+ hw_dbg("Master requests are pending.\n");
ret_val = -E1000_ERR_MASTER_REQUESTS_PENDING;
goto out;
}
@@ -1332,7 +1330,7 @@ out:
}
/**
- * e1000_reset_adaptive - Reset Adaptive Interframe Spacing
+ * igb_reset_adaptive - Reset Adaptive Interframe Spacing
* @hw: pointer to the HW structure
*
* Reset the Adaptive Interframe Spacing throttle to default values.
@@ -1342,7 +1340,7 @@ void igb_reset_adaptive(struct e1000_hw *hw)
struct e1000_mac_info *mac = &hw->mac;
if (!mac->adaptive_ifs) {
- hw_dbg(hw, "Not in Adaptive IFS mode!\n");
+ hw_dbg("Not in Adaptive IFS mode!\n");
goto out;
}
@@ -1361,7 +1359,7 @@ out:
}
/**
- * e1000_update_adaptive - Update Adaptive Interframe Spacing
+ * igb_update_adaptive - Update Adaptive Interframe Spacing
* @hw: pointer to the HW structure
*
* Update the Adaptive Interframe Spacing Throttle value based on the
@@ -1372,7 +1370,7 @@ void igb_update_adaptive(struct e1000_hw *hw)
struct e1000_mac_info *mac = &hw->mac;
if (!mac->adaptive_ifs) {
- hw_dbg(hw, "Not in Adaptive IFS mode!\n");
+ hw_dbg("Not in Adaptive IFS mode!\n");
goto out;
}
@@ -1402,7 +1400,7 @@ out:
}
/**
- * e1000_validate_mdi_setting - Verify MDI/MDIx settings
+ * igb_validate_mdi_setting - Verify MDI/MDIx settings
* @hw: pointer to the HW structure
*
* Verify that when not using auto-negotitation that MDI/MDIx is correctly
@@ -1413,7 +1411,7 @@ s32 igb_validate_mdi_setting(struct e1000_hw *hw)
s32 ret_val = 0;
if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) {
- hw_dbg(hw, "Invalid MDI setting detected\n");
+ hw_dbg("Invalid MDI setting detected\n");
hw->phy.mdix = 1;
ret_val = -E1000_ERR_CONFIG;
goto out;
@@ -1424,7 +1422,7 @@ out:
}
/**
- * e1000_write_8bit_ctrl_reg - Write a 8bit CTRL register
+ * igb_write_8bit_ctrl_reg - Write a 8bit CTRL register
* @hw: pointer to the HW structure
* @reg: 32bit register offset such as E1000_SCTL
* @offset: register offset to write to
@@ -1452,7 +1450,7 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
break;
}
if (!(regvalue & E1000_GEN_CTL_READY)) {
- hw_dbg(hw, "Reg %08x did not indicate ready\n", reg);
+ hw_dbg("Reg %08x did not indicate ready\n", reg);
ret_val = -E1000_ERR_PHY;
goto out;
}
@@ -1462,7 +1460,7 @@ out:
}
/**
- * e1000_enable_mng_pass_thru - Enable processing of ARP's
+ * igb_enable_mng_pass_thru - Enable processing of ARP's
* @hw: pointer to the HW structure
*
* Verifies the hardware needs to allow ARPs to be processed by the host.
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index 326b6592307..dc2f8cce15e 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -94,5 +94,6 @@ enum e1000_mng_mode {
#define E1000_HICR_C 0x02
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
+extern u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
#endif
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
index 2897106fee9..a84e4e429fa 100644
--- a/drivers/net/igb/e1000_nvm.c
+++ b/drivers/net/igb/e1000_nvm.c
@@ -32,7 +32,7 @@
#include "e1000_nvm.h"
/**
- * e1000_raise_eec_clk - Raise EEPROM clock
+ * igb_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
@@ -47,7 +47,7 @@ static void igb_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
}
/**
- * e1000_lower_eec_clk - Lower EEPROM clock
+ * igb_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
@@ -62,7 +62,7 @@ static void igb_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
}
/**
- * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
+ * igb_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
@@ -105,7 +105,7 @@ static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
}
/**
- * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
+ * igb_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
@@ -143,7 +143,7 @@ static u16 igb_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
}
/**
- * e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
+ * igb_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
@@ -174,7 +174,7 @@ static s32 igb_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
}
/**
- * e1000_acquire_nvm - Generic request for access to EEPROM
+ * igb_acquire_nvm - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
@@ -202,7 +202,7 @@ s32 igb_acquire_nvm(struct e1000_hw *hw)
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
- hw_dbg(hw, "Could not acquire NVM grant\n");
+ hw_dbg("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
}
@@ -210,7 +210,7 @@ s32 igb_acquire_nvm(struct e1000_hw *hw)
}
/**
- * e1000_standby_nvm - Return EEPROM to standby state
+ * igb_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
@@ -273,7 +273,7 @@ static void e1000_stop_nvm(struct e1000_hw *hw)
}
/**
- * e1000_release_nvm - Release exclusive access to EEPROM
+ * igb_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
@@ -290,7 +290,7 @@ void igb_release_nvm(struct e1000_hw *hw)
}
/**
- * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
+ * igb_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
@@ -337,7 +337,7 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
}
if (!timeout) {
- hw_dbg(hw, "SPI NVM Status error\n");
+ hw_dbg("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
@@ -348,7 +348,7 @@ out:
}
/**
- * e1000_read_nvm_eerd - Reads EEPROM using EERD register
+ * igb_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
@@ -368,7 +368,7 @@ s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+ hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
@@ -391,7 +391,7 @@ out:
}
/**
- * e1000_write_nvm_spi - Write to EEPROM using SPI
+ * igb_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
@@ -414,7 +414,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+ hw_dbg("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
@@ -475,7 +475,7 @@ out:
}
/**
- * e1000_read_part_num - Read device part number
+ * igb_read_part_num - Read device part number
* @hw: pointer to the HW structure
* @part_num: pointer to device part number
*
@@ -489,14 +489,14 @@ s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num)
ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
*part_num = (u32)(nvm_data << 16);
ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
*part_num |= nvm_data;
@@ -506,7 +506,7 @@ out:
}
/**
- * e1000_read_mac_addr - Read device MAC address
+ * igb_read_mac_addr - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
@@ -522,7 +522,7 @@ s32 igb_read_mac_addr(struct e1000_hw *hw)
offset = i >> 1;
ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
@@ -541,7 +541,7 @@ out:
}
/**
- * e1000_validate_nvm_checksum - Validate EEPROM checksum
+ * igb_validate_nvm_checksum - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
@@ -556,14 +556,14 @@ s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
+ hw_dbg("NVM Read Error\n");
goto out;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
- hw_dbg(hw, "NVM Checksum Invalid\n");
+ hw_dbg("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
@@ -573,7 +573,7 @@ out:
}
/**
- * e1000_update_nvm_checksum - Update EEPROM checksum
+ * igb_update_nvm_checksum - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
@@ -589,7 +589,7 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
- hw_dbg(hw, "NVM Read Error while updating checksum.\n");
+ hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
@@ -597,7 +597,7 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
checksum = (u16) NVM_SUM - checksum;
ret_val = hw->nvm.ops.write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
- hw_dbg(hw, "NVM Write Error while updating checksum.\n");
+ hw_dbg("NVM Write Error while updating checksum.\n");
out:
return ret_val;
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 08a86b10722..17fddb91c9f 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -61,7 +61,7 @@ static const u16 e1000_igp_2_cable_length_table[] =
sizeof(e1000_igp_2_cable_length_table[0]))
/**
- * e1000_check_reset_block - Check if PHY reset is blocked
+ * igb_check_reset_block - Check if PHY reset is blocked
* @hw: pointer to the HW structure
*
* Read the PHY management control register and check whether a PHY reset
@@ -79,7 +79,7 @@ s32 igb_check_reset_block(struct e1000_hw *hw)
}
/**
- * e1000_get_phy_id - Retrieve the PHY ID and revision
+ * igb_get_phy_id - Retrieve the PHY ID and revision
* @hw: pointer to the HW structure
*
* Reads the PHY registers and stores the PHY ID and possibly the PHY
@@ -109,7 +109,7 @@ out:
}
/**
- * e1000_phy_reset_dsp - Reset PHY DSP
+ * igb_phy_reset_dsp - Reset PHY DSP
* @hw: pointer to the HW structure
*
* Reset the digital signal processor.
@@ -129,7 +129,7 @@ out:
}
/**
- * e1000_read_phy_reg_mdic - Read MDI control register
+ * igb_read_phy_reg_mdic - Read MDI control register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
@@ -144,7 +144,7 @@ static s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
s32 ret_val = 0;
if (offset > MAX_PHY_REG_ADDRESS) {
- hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+ hw_dbg("PHY Address %d is out of range\n", offset);
ret_val = -E1000_ERR_PARAM;
goto out;
}
@@ -172,12 +172,12 @@ static s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
break;
}
if (!(mdic & E1000_MDIC_READY)) {
- hw_dbg(hw, "MDI Read did not complete\n");
+ hw_dbg("MDI Read did not complete\n");
ret_val = -E1000_ERR_PHY;
goto out;
}
if (mdic & E1000_MDIC_ERROR) {
- hw_dbg(hw, "MDI Error\n");
+ hw_dbg("MDI Error\n");
ret_val = -E1000_ERR_PHY;
goto out;
}
@@ -188,7 +188,7 @@ out:
}
/**
- * e1000_write_phy_reg_mdic - Write MDI control register
+ * igb_write_phy_reg_mdic - Write MDI control register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write to register at offset
@@ -202,7 +202,7 @@ static s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
s32 ret_val = 0;
if (offset > MAX_PHY_REG_ADDRESS) {
- hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+ hw_dbg("PHY Address %d is out of range\n", offset);
ret_val = -E1000_ERR_PARAM;
goto out;
}
@@ -231,12 +231,12 @@ static s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
break;
}
if (!(mdic & E1000_MDIC_READY)) {
- hw_dbg(hw, "MDI Write did not complete\n");
+ hw_dbg("MDI Write did not complete\n");
ret_val = -E1000_ERR_PHY;
goto out;
}
if (mdic & E1000_MDIC_ERROR) {
- hw_dbg(hw, "MDI Error\n");
+ hw_dbg("MDI Error\n");
ret_val = -E1000_ERR_PHY;
goto out;
}
@@ -246,7 +246,7 @@ out:
}
/**
- * e1000_read_phy_reg_igp - Read igp PHY register
+ * igb_read_phy_reg_igp - Read igp PHY register
* @hw: pointer to the HW structure
* @offset: register offset to be read
* @data: pointer to the read data
@@ -284,7 +284,7 @@ out:
}
/**
- * e1000_write_phy_reg_igp - Write igp PHY register
+ * igb_write_phy_reg_igp - Write igp PHY register
* @hw: pointer to the HW structure
* @offset: register offset to write to
* @data: data to write at register offset
@@ -321,7 +321,7 @@ out:
}
/**
- * e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link
+ * igb_copper_link_setup_m88 - Setup m88 PHY's for copper link
* @hw: pointer to the HW structure
*
* Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock
@@ -423,7 +423,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
/* Commit the changes. */
ret_val = igb_phy_sw_reset(hw);
if (ret_val) {
- hw_dbg(hw, "Error committing the PHY changes\n");
+ hw_dbg("Error committing the PHY changes\n");
goto out;
}
@@ -432,7 +432,7 @@ out:
}
/**
- * e1000_copper_link_setup_igp - Setup igp PHY's for copper link
+ * igb_copper_link_setup_igp - Setup igp PHY's for copper link
* @hw: pointer to the HW structure
*
* Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
@@ -451,7 +451,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
ret_val = hw->phy.ops.reset_phy(hw);
if (ret_val) {
- hw_dbg(hw, "Error resetting the PHY.\n");
+ hw_dbg("Error resetting the PHY.\n");
goto out;
}
@@ -467,7 +467,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
if (hw->phy.ops.set_d3_lplu_state)
ret_val = hw->phy.ops.set_d3_lplu_state(hw, false);
if (ret_val) {
- hw_dbg(hw, "Error Disabling LPLU D3\n");
+ hw_dbg("Error Disabling LPLU D3\n");
goto out;
}
}
@@ -475,7 +475,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
/* disable lplu d0 during driver init */
ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
if (ret_val) {
- hw_dbg(hw, "Error Disabling LPLU D0\n");
+ hw_dbg("Error Disabling LPLU D0\n");
goto out;
}
/* Configure mdi-mdix settings */
@@ -570,7 +570,7 @@ out:
}
/**
- * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
+ * igb_copper_link_autoneg - Setup/Enable autoneg for copper link
* @hw: pointer to the HW structure
*
* Performs initial bounds checking on autoneg advertisement parameter, then
@@ -597,13 +597,13 @@ s32 igb_copper_link_autoneg(struct e1000_hw *hw)
if (phy->autoneg_advertised == 0)
phy->autoneg_advertised = phy->autoneg_mask;
- hw_dbg(hw, "Reconfiguring auto-neg advertisement params\n");
+ hw_dbg("Reconfiguring auto-neg advertisement params\n");
ret_val = igb_phy_setup_autoneg(hw);
if (ret_val) {
- hw_dbg(hw, "Error Setting up Auto-Negotiation\n");
+ hw_dbg("Error Setting up Auto-Negotiation\n");
goto out;
}
- hw_dbg(hw, "Restarting Auto-Neg\n");
+ hw_dbg("Restarting Auto-Neg\n");
/*
* Restart auto-negotiation by setting the Auto Neg Enable bit and
@@ -625,8 +625,8 @@ s32 igb_copper_link_autoneg(struct e1000_hw *hw)
if (phy->autoneg_wait_to_complete) {
ret_val = igb_wait_autoneg(hw);
if (ret_val) {
- hw_dbg(hw, "Error while waiting for "
- "autoneg to complete\n");
+ hw_dbg("Error while waiting for "
+ "autoneg to complete\n");
goto out;
}
}
@@ -638,7 +638,7 @@ out:
}
/**
- * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
+ * igb_phy_setup_autoneg - Configure PHY for auto-negotiation
* @hw: pointer to the HW structure
*
* Reads the MII auto-neg advertisement register and/or the 1000T control
@@ -689,39 +689,39 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
NWAY_AR_10T_HD_CAPS);
mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
- hw_dbg(hw, "autoneg_advertised %x\n", phy->autoneg_advertised);
+ hw_dbg("autoneg_advertised %x\n", phy->autoneg_advertised);
/* Do we want to advertise 10 Mb Half Duplex? */
if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
- hw_dbg(hw, "Advertise 10mb Half duplex\n");
+ hw_dbg("Advertise 10mb Half duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
}
/* Do we want to advertise 10 Mb Full Duplex? */
if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
- hw_dbg(hw, "Advertise 10mb Full duplex\n");
+ hw_dbg("Advertise 10mb Full duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
}
/* Do we want to advertise 100 Mb Half Duplex? */
if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
- hw_dbg(hw, "Advertise 100mb Half duplex\n");
+ hw_dbg("Advertise 100mb Half duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
}
/* Do we want to advertise 100 Mb Full Duplex? */
if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
- hw_dbg(hw, "Advertise 100mb Full duplex\n");
+ hw_dbg("Advertise 100mb Full duplex\n");
mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
}
/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
- hw_dbg(hw, "Advertise 1000mb Half duplex request denied!\n");
+ hw_dbg("Advertise 1000mb Half duplex request denied!\n");
/* Do we want to advertise 1000 Mb Full Duplex? */
if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
- hw_dbg(hw, "Advertise 1000mb Full duplex\n");
+ hw_dbg("Advertise 1000mb Full duplex\n");
mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
}
@@ -780,7 +780,7 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break;
default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
+ hw_dbg("Flow control param set incorrectly\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -790,7 +790,7 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
if (ret_val)
goto out;
- hw_dbg(hw, "Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+ hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
ret_val = hw->phy.ops.write_phy_reg(hw,
@@ -805,7 +805,7 @@ out:
}
/**
- * e1000_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
+ * igb_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
* @hw: pointer to the HW structure
*
* Calls the PHY setup function to force speed and duplex. Clears the
@@ -846,13 +846,12 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
if (ret_val)
goto out;
- hw_dbg(hw, "IGP PSCR: %X\n", phy_data);
+ hw_dbg("IGP PSCR: %X\n", phy_data);
udelay(1);
if (phy->autoneg_wait_to_complete) {
- hw_dbg(hw,
- "Waiting for forced speed/duplex link on IGP phy.\n");
+ hw_dbg("Waiting for forced speed/duplex link on IGP phy.\n");
ret_val = igb_phy_has_link(hw,
PHY_FORCE_LIMIT,
@@ -862,7 +861,7 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
goto out;
if (!link)
- hw_dbg(hw, "Link taking longer than expected.\n");
+ hw_dbg("Link taking longer than expected.\n");
/* Try once more */
ret_val = igb_phy_has_link(hw,
@@ -878,7 +877,7 @@ out:
}
/**
- * e1000_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
+ * igb_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
* @hw: pointer to the HW structure
*
* Calls the PHY setup function to force speed and duplex. Clears the
@@ -909,7 +908,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
if (ret_val)
goto out;
- hw_dbg(hw, "M88E1000 PSCR: %X\n", phy_data);
+ hw_dbg("M88E1000 PSCR: %X\n", phy_data);
ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
@@ -927,8 +926,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
udelay(1);
if (phy->autoneg_wait_to_complete) {
- hw_dbg(hw,
- "Waiting for forced speed/duplex link on M88 phy.\n");
+ hw_dbg("Waiting for forced speed/duplex link on M88 phy.\n");
ret_val = igb_phy_has_link(hw,
PHY_FORCE_LIMIT,
@@ -993,7 +991,7 @@ out:
}
/**
- * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
+ * igb_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
* @hw: pointer to the HW structure
* @phy_ctrl: pointer to current value of PHY_CONTROL
*
@@ -1028,11 +1026,11 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
ctrl &= ~E1000_CTRL_FD;
*phy_ctrl &= ~MII_CR_FULL_DUPLEX;
- hw_dbg(hw, "Half Duplex\n");
+ hw_dbg("Half Duplex\n");
} else {
ctrl |= E1000_CTRL_FD;
*phy_ctrl |= MII_CR_FULL_DUPLEX;
- hw_dbg(hw, "Full Duplex\n");
+ hw_dbg("Full Duplex\n");
}
/* Forcing 10mb or 100mb? */
@@ -1040,12 +1038,12 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
ctrl |= E1000_CTRL_SPD_100;
*phy_ctrl |= MII_CR_SPEED_100;
*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
- hw_dbg(hw, "Forcing 100mb\n");
+ hw_dbg("Forcing 100mb\n");
} else {
ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
*phy_ctrl |= MII_CR_SPEED_10;
*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
- hw_dbg(hw, "Forcing 10mb\n");
+ hw_dbg("Forcing 10mb\n");
}
igb_config_collision_dist(hw);
@@ -1054,7 +1052,7 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
}
/**
- * e1000_set_d3_lplu_state - Sets low power link up state for D3
+ * igb_set_d3_lplu_state - Sets low power link up state for D3
* @hw: pointer to the HW structure
* @active: boolean used to enable/disable lplu
*
@@ -1146,7 +1144,7 @@ out:
}
/**
- * e1000_check_downshift - Checks whether a downshift in speed occured
+ * igb_check_downshift - Checks whether a downshift in speed occured
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns 1
@@ -1188,7 +1186,7 @@ out:
}
/**
- * e1000_check_polarity_m88 - Checks the polarity.
+ * igb_check_polarity_m88 - Checks the polarity.
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns -E1000_ERR_PHY (-2)
@@ -1212,7 +1210,7 @@ static s32 igb_check_polarity_m88(struct e1000_hw *hw)
}
/**
- * e1000_check_polarity_igp - Checks the polarity.
+ * igb_check_polarity_igp - Checks the polarity.
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns -E1000_ERR_PHY (-2)
@@ -1260,7 +1258,7 @@ out:
}
/**
- * e1000_wait_autoneg - Wait for auto-neg compeletion
+ * igb_wait_autoneg - Wait for auto-neg compeletion
* @hw: pointer to the HW structure
*
* Waits for auto-negotiation to complete or for the auto-negotiation time
@@ -1292,7 +1290,7 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw)
}
/**
- * e1000_phy_has_link - Polls PHY for link
+ * igb_phy_has_link - Polls PHY for link
* @hw: pointer to the HW structure
* @iterations: number of times to poll for link
* @usec_interval: delay between polling attempts
@@ -1332,7 +1330,7 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
}
/**
- * e1000_get_cable_length_m88 - Determine cable length for m88 PHY
+ * igb_get_cable_length_m88 - Determine cable length for m88 PHY
* @hw: pointer to the HW structure
*
* Reads the PHY specific status register to retrieve the cable length
@@ -1369,7 +1367,7 @@ out:
}
/**
- * e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
+ * igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY
* @hw: pointer to the HW structure
*
* The automatic gain control (agc) normalizes the amplitude of the
@@ -1442,7 +1440,7 @@ out:
}
/**
- * e1000_get_phy_info_m88 - Retrieve PHY information
+ * igb_get_phy_info_m88 - Retrieve PHY information
* @hw: pointer to the HW structure
*
* Valid for only copper links. Read the PHY status register (sticky read)
@@ -1459,7 +1457,7 @@ s32 igb_get_phy_info_m88(struct e1000_hw *hw)
bool link;
if (hw->phy.media_type != e1000_media_type_copper) {
- hw_dbg(hw, "Phy info is only valid for copper media\n");
+ hw_dbg("Phy info is only valid for copper media\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -1469,7 +1467,7 @@ s32 igb_get_phy_info_m88(struct e1000_hw *hw)
goto out;
if (!link) {
- hw_dbg(hw, "Phy info is only valid if link is up\n");
+ hw_dbg("Phy info is only valid if link is up\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -1523,7 +1521,7 @@ out:
}
/**
- * e1000_get_phy_info_igp - Retrieve igp PHY information
+ * igb_get_phy_info_igp - Retrieve igp PHY information
* @hw: pointer to the HW structure
*
* Read PHY status to determine if link is up. If link is up, then
@@ -1543,7 +1541,7 @@ s32 igb_get_phy_info_igp(struct e1000_hw *hw)
goto out;
if (!link) {
- hw_dbg(hw, "Phy info is only valid if link is up\n");
+ hw_dbg("Phy info is only valid if link is up\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -1590,7 +1588,7 @@ out:
}
/**
- * e1000_phy_sw_reset - PHY software reset
+ * igb_phy_sw_reset - PHY software reset
* @hw: pointer to the HW structure
*
* Does a software reset of the PHY by reading the PHY control register and
@@ -1617,7 +1615,7 @@ out:
}
/**
- * e1000_phy_hw_reset - PHY hardware reset
+ * igb_phy_hw_reset - PHY hardware reset
* @hw: pointer to the HW structure
*
* Verify the reset block is not blocking us from resetting. Acquire
@@ -1663,7 +1661,7 @@ out:
/* Internal function pointers */
/**
- * e1000_get_phy_cfg_done - Generic PHY configuration done
+ * igb_get_phy_cfg_done - Generic PHY configuration done
* @hw: pointer to the HW structure
*
* Return success if silicon family did not implement a family specific
@@ -1678,7 +1676,7 @@ static s32 igb_get_phy_cfg_done(struct e1000_hw *hw)
}
/**
- * e1000_release_phy - Generic release PHY
+ * igb_release_phy - Generic release PHY
* @hw: pointer to the HW structure
*
* Return if silicon family does not require a semaphore when accessing the
@@ -1691,7 +1689,7 @@ static void igb_release_phy(struct e1000_hw *hw)
}
/**
- * e1000_acquire_phy - Generic acquire PHY
+ * igb_acquire_phy - Generic acquire PHY
* @hw: pointer to the HW structure
*
* Return success if silicon family does not require a semaphore when
@@ -1706,7 +1704,7 @@ static s32 igb_acquire_phy(struct e1000_hw *hw)
}
/**
- * e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
+ * igb_phy_force_speed_duplex - Generic force PHY speed/duplex
* @hw: pointer to the HW structure
*
* When the silicon family has not implemented a forced speed/duplex
@@ -1721,14 +1719,14 @@ s32 igb_phy_force_speed_duplex(struct e1000_hw *hw)
}
/**
- * e1000_phy_init_script_igp3 - Inits the IGP3 PHY
+ * igb_phy_init_script_igp3 - Inits the IGP3 PHY
* @hw: pointer to the HW structure
*
* Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
**/
s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
{
- hw_dbg(hw, "Running IGP 3 PHY init script\n");
+ hw_dbg("Running IGP 3 PHY init script\n");
/* PHY init IGP 3 */
/* Enable rise/fall, 10-mode work in class-A */
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index ff187b73c69..b95093d24c0 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -56,6 +56,9 @@
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
+#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
+#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
#define E1000_TCTL 0x00400 /* TX Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
@@ -217,6 +220,7 @@
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
+#define E1000_RA2 0x054E0 /* 2nd half of receive address array - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
@@ -235,6 +239,8 @@
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
+#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
+#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* RSS registers */
@@ -256,7 +262,8 @@
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
-#define E1000_REGISTER(a, reg) reg
+#define E1000_REGISTER(a, reg) (((a)->mac.type < e1000_82576) \
+ ? reg : e1000_translate_register_82576(reg))
#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
#define rd32(reg) (readl(hw->hw_addr + reg))
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 6b2e7d351d6..4ff6f0567f3 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -36,12 +36,20 @@
struct igb_adapter;
+#ifdef CONFIG_IGB_LRO
+#include <linux/inet_lro.h>
+#define MAX_LRO_AGGR 32
+#define MAX_LRO_DESCRIPTORS 8
+#endif
+
/* Interrupt defines */
#define IGB_MAX_TX_CLEAN 72
#define IGB_MIN_DYN_ITR 3000
#define IGB_MAX_DYN_ITR 96000
-#define IGB_START_ITR 6000
+
+/* ((1000000000ns / (6000ints/s * 1024ns)) << 2 = 648 */
+#define IGB_START_ITR 648
#define IGB_DYN_ITR_PACKET_THRESHOLD 2
#define IGB_DYN_ITR_LENGTH_LOW 200
@@ -62,6 +70,7 @@ struct igb_adapter;
/* Transmit and receive queues */
#define IGB_MAX_RX_QUEUES 4
+#define IGB_MAX_TX_QUEUES 4
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
@@ -124,6 +133,7 @@ struct igb_buffer {
struct {
struct page *page;
u64 page_dma;
+ unsigned int page_offset;
};
};
};
@@ -150,24 +160,26 @@ struct igb_ring {
u16 itr_register;
u16 cpu;
+ int queue_index;
unsigned int total_bytes;
unsigned int total_packets;
union {
/* TX */
struct {
- spinlock_t tx_clean_lock;
- spinlock_t tx_lock;
+ struct igb_queue_stats tx_stats;
bool detect_tx_hung;
};
/* RX */
struct {
- /* arrays of page information for packet split */
- struct sk_buff *pending_skb;
- int pending_skb_page;
- int no_itr_adjust;
struct igb_queue_stats rx_stats;
struct napi_struct napi;
+ int set_itr;
+ struct igb_ring *buddy;
+#ifdef CONFIG_IGB_LRO
+ struct net_lro_mgr lro_mgr;
+ bool lro_used;
+#endif
};
};
@@ -210,7 +222,6 @@ struct igb_adapter {
u32 itr_setting;
u16 tx_itr;
u16 rx_itr;
- int set_itr;
struct work_struct reset_task;
struct work_struct watchdog_task;
@@ -265,14 +276,34 @@ struct igb_adapter {
int msg_enable;
struct msix_entry *msix_entries;
u32 eims_enable_mask;
+ u32 eims_other;
/* to not mess up cache alignment, always add to the bottom */
unsigned long state;
- unsigned int msi_enabled;
-
+ unsigned int flags;
u32 eeprom_wol;
+
+ /* for ioport free */
+ int bars;
+ int need_ioport;
+
+ struct igb_ring *multi_tx_table[IGB_MAX_TX_QUEUES];
+#ifdef CONFIG_IGB_LRO
+ unsigned int lro_max_aggr;
+ unsigned int lro_aggregated;
+ unsigned int lro_flushed;
+ unsigned int lro_no_desc;
+#endif
};
+#define IGB_FLAG_HAS_MSI (1 << 0)
+#define IGB_FLAG_MSI_ENABLE (1 << 1)
+#define IGB_FLAG_HAS_DCA (1 << 2)
+#define IGB_FLAG_DCA_ENABLED (1 << 3)
+#define IGB_FLAG_IN_NETPOLL (1 << 5)
+#define IGB_FLAG_QUAD_PORT_A (1 << 6)
+#define IGB_FLAG_NEED_CTX_IDX (1 << 7)
+
enum e1000_state_t {
__IGB_TESTING,
__IGB_RESETTING,
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 0447f9bcd27..11aee130995 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -93,13 +93,16 @@ static const struct igb_stats igb_gstrings_stats[] = {
{ "tx_smbus", IGB_STAT(stats.mgptc) },
{ "rx_smbus", IGB_STAT(stats.mgprc) },
{ "dropped_smbus", IGB_STAT(stats.mgpdc) },
+#ifdef CONFIG_IGB_LRO
+ { "lro_aggregated", IGB_STAT(lro_aggregated) },
+ { "lro_flushed", IGB_STAT(lro_flushed) },
+ { "lro_no_desc", IGB_STAT(lro_no_desc) },
+#endif
};
#define IGB_QUEUE_STATS_LEN \
- ((((((struct igb_adapter *)netdev->priv)->num_rx_queues > 1) ? \
- ((struct igb_adapter *)netdev->priv)->num_rx_queues : 0) + \
- (((((struct igb_adapter *)netdev->priv)->num_tx_queues > 1) ? \
- ((struct igb_adapter *)netdev->priv)->num_tx_queues : 0))) * \
+ ((((struct igb_adapter *)netdev->priv)->num_rx_queues + \
+ ((struct igb_adapter *)netdev->priv)->num_tx_queues) * \
(sizeof(struct igb_queue_stats) / sizeof(u64)))
#define IGB_GLOBAL_STATS_LEN \
sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
@@ -829,8 +832,9 @@ err_setup:
/* ethtool register test data */
struct igb_reg_test {
u16 reg;
- u8 array_len;
- u8 test_type;
+ u16 reg_offset;
+ u16 array_len;
+ u16 test_type;
u32 mask;
u32 write;
};
@@ -852,34 +856,72 @@ struct igb_reg_test {
#define TABLE64_TEST_LO 5
#define TABLE64_TEST_HI 6
-/* default register test */
+/* 82576 reg test */
+static struct igb_reg_test reg_test_82576[] = {
+ { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+ { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+ { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ { E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ /* Enable all four RX queues before testing. */
+ { E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ /* RDH is read-only for 82576, only test RDT. */
+ { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
+ { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
+ { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
+ { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ { E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+ { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+ { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RA, 0, 16, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
+ { E1000_RA2, 0, 8, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RA2, 0, 8, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
+ { E1000_MTA, 0, 128,TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { 0, 0, 0, 0 }
+};
+
+/* 82575 register test */
static struct igb_reg_test reg_test_82575[] = {
- { E1000_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
- { E1000_VET, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+ { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+ { E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
/* Enable all four RX queues before testing. */
- { E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
/* RDH is read-only for 82575, only test RDT. */
- { E1000_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
- { E1000_FCRTH, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
- { E1000_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
- { E1000_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
- { E1000_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
- { E1000_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
- { E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
- { E1000_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_TXCW, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
- { E1000_RA, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RA, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF },
- { E1000_MTA, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
+ { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
+ { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
+ { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
+ { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+ { E1000_TXCW, 0x100, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
+ { E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RA, 0, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF },
+ { E1000_MTA, 0, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ 0, 0, 0, 0 }
};
@@ -939,7 +981,15 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
u32 i, toggle;
toggle = 0x7FFFF3FF;
- test = reg_test_82575;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_82576:
+ test = reg_test_82576;
+ break;
+ default:
+ test = reg_test_82575;
+ break;
+ }
/* Because the status register is such a special case,
* we handle it separately from the rest of the register
@@ -966,19 +1016,19 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
for (i = 0; i < test->array_len; i++) {
switch (test->test_type) {
case PATTERN_TEST:
- REG_PATTERN_TEST(test->reg + (i * 0x100),
+ REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
test->mask,
test->write);
break;
case SET_READ_TEST:
- REG_SET_AND_CHECK(test->reg + (i * 0x100),
+ REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
test->mask,
test->write);
break;
case WRITE_NO_TEST:
writel(test->write,
(adapter->hw.hw_addr + test->reg)
- + (i * 0x100));
+ + (i * test->reg_offset));
break;
case TABLE32_TEST:
REG_PATTERN_TEST(test->reg + (i * 4),
@@ -1052,7 +1102,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
if (adapter->msix_entries) {
/* NOTE: we don't test MSI-X interrupts here, yet */
return 0;
- } else if (adapter->msi_enabled) {
+ } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
shared_int = false;
if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
*data = 1;
@@ -1394,13 +1444,39 @@ static int igb_set_phy_loopback(struct igb_adapter *adapter)
static int igb_setup_loopback_test(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- u32 rctl;
+ u32 reg;
if (hw->phy.media_type == e1000_media_type_fiber ||
hw->phy.media_type == e1000_media_type_internal_serdes) {
- rctl = rd32(E1000_RCTL);
- rctl |= E1000_RCTL_LBM_TCVR;
- wr32(E1000_RCTL, rctl);
+ reg = rd32(E1000_RCTL);
+ reg |= E1000_RCTL_LBM_TCVR;
+ wr32(E1000_RCTL, reg);
+
+ wr32(E1000_SCTL, E1000_ENABLE_SERDES_LOOPBACK);
+
+ reg = rd32(E1000_CTRL);
+ reg &= ~(E1000_CTRL_RFCE |
+ E1000_CTRL_TFCE |
+ E1000_CTRL_LRST);
+ reg |= E1000_CTRL_SLU |
+ E1000_CTRL_FD;
+ wr32(E1000_CTRL, reg);
+
+ /* Unset switch control to serdes energy detect */
+ reg = rd32(E1000_CONNSW);
+ reg &= ~E1000_CONNSW_ENRGSRC;
+ wr32(E1000_CONNSW, reg);
+
+ /* Set PCS register for forced speed */
+ reg = rd32(E1000_PCS_LCTL);
+ reg &= ~E1000_PCS_LCTL_AN_ENABLE; /* Disable Autoneg*/
+ reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */
+ E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
+ E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
+ E1000_PCS_LCTL_FSD | /* Force Speed */
+ E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
+ wr32(E1000_PCS_LCTL, reg);
+
return 0;
} else if (hw->phy.media_type == e1000_media_type_copper) {
return igb_set_phy_loopback(adapter);
@@ -1660,6 +1736,8 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
wol->supported = 0;
break;
case E1000_DEV_ID_82575EB_FIBER_SERDES:
+ case E1000_DEV_ID_82576_FIBER:
+ case E1000_DEV_ID_82576_SERDES:
/* Wake events not supported on port B */
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1) {
wol->supported = 0;
@@ -1668,6 +1746,15 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
/* return success for non excluded adapter ports */
retval = 0;
break;
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ /* quad port adapters only support WoL on port A */
+ if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
+ wol->supported = 0;
+ break;
+ }
+ /* return success for non excluded adapter ports */
+ retval = 0;
+ break;
default:
/* dual port cards only support WoL on port A from now on
* unless it was enabled in the eeprom for port B
@@ -1774,6 +1861,8 @@ static int igb_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ int i;
if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
((ec->rx_coalesce_usecs > 3) &&
@@ -1782,13 +1871,16 @@ static int igb_set_coalesce(struct net_device *netdev,
return -EINVAL;
/* convert to rate of irq's per second */
- if (ec->rx_coalesce_usecs <= 3)
+ if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
adapter->itr_setting = ec->rx_coalesce_usecs;
- else
- adapter->itr_setting = (1000000 / ec->rx_coalesce_usecs);
+ adapter->itr = IGB_START_ITR;
+ } else {
+ adapter->itr_setting = ec->rx_coalesce_usecs << 2;
+ adapter->itr = adapter->itr_setting;
+ }
- if (netif_running(netdev))
- igb_reinit_locked(adapter);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ wr32(adapter->rx_ring[i].itr_register, adapter->itr);
return 0;
}
@@ -1801,7 +1893,7 @@ static int igb_get_coalesce(struct net_device *netdev,
if (adapter->itr_setting <= 3)
ec->rx_coalesce_usecs = adapter->itr_setting;
else
- ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
+ ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
return 0;
}
@@ -1835,6 +1927,18 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
int j;
int i;
+#ifdef CONFIG_IGB_LRO
+ int aggregated = 0, flushed = 0, no_desc = 0;
+
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
+ flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
+ no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
+ }
+ adapter->lro_aggregated = aggregated;
+ adapter->lro_flushed = flushed;
+ adapter->lro_no_desc = no_desc;
+#endif
igb_update_stats(adapter);
for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
@@ -1842,6 +1946,13 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
data[i] = (igb_gstrings_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
+ for (j = 0; j < adapter->num_tx_queues; j++) {
+ int k;
+ queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
+ for (k = 0; k < stat_count; k++)
+ data[i + k] = queue_stat[k];
+ i += k;
+ }
for (j = 0; j < adapter->num_rx_queues; j++) {
int k;
queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index e79a26a886c..1b7cb29fe68 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -41,22 +41,27 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
-
+#ifdef CONFIG_DCA
+#include <linux/dca.h>
+#endif
#include "igb.h"
-#define DRV_VERSION "1.0.8-k2"
+#define DRV_VERSION "1.2.45-k2"
char igb_driver_name[] = "igb";
char igb_driver_version[] = DRV_VERSION;
static const char igb_driver_string[] =
"Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] = "Copyright (c) 2007 Intel Corporation.";
-
+static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
};
static struct pci_device_id igb_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
@@ -71,8 +76,8 @@ static int igb_setup_all_tx_resources(struct igb_adapter *);
static int igb_setup_all_rx_resources(struct igb_adapter *);
static void igb_free_all_tx_resources(struct igb_adapter *);
static void igb_free_all_rx_resources(struct igb_adapter *);
-static void igb_free_tx_resources(struct igb_adapter *, struct igb_ring *);
-static void igb_free_rx_resources(struct igb_adapter *, struct igb_ring *);
+static void igb_free_tx_resources(struct igb_ring *);
+static void igb_free_rx_resources(struct igb_ring *);
void igb_update_stats(struct igb_adapter *);
static int igb_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit igb_remove(struct pci_dev *pdev);
@@ -84,8 +89,8 @@ static void igb_configure_rx(struct igb_adapter *);
static void igb_setup_rctl(struct igb_adapter *);
static void igb_clean_all_tx_rings(struct igb_adapter *);
static void igb_clean_all_rx_rings(struct igb_adapter *);
-static void igb_clean_tx_ring(struct igb_adapter *, struct igb_ring *);
-static void igb_clean_rx_ring(struct igb_adapter *, struct igb_ring *);
+static void igb_clean_tx_ring(struct igb_ring *);
+static void igb_clean_rx_ring(struct igb_ring *);
static void igb_set_multi(struct net_device *);
static void igb_update_phy_info(unsigned long);
static void igb_watchdog(unsigned long);
@@ -102,12 +107,18 @@ static irqreturn_t igb_msix_other(int irq, void *);
static irqreturn_t igb_msix_rx(int irq, void *);
static irqreturn_t igb_msix_tx(int irq, void *);
static int igb_clean_rx_ring_msix(struct napi_struct *, int);
-static bool igb_clean_tx_irq(struct igb_adapter *, struct igb_ring *);
-static int igb_clean(struct napi_struct *, int);
-static bool igb_clean_rx_irq_adv(struct igb_adapter *,
- struct igb_ring *, int *, int);
-static void igb_alloc_rx_buffers_adv(struct igb_adapter *,
- struct igb_ring *, int);
+#ifdef CONFIG_DCA
+static void igb_update_rx_dca(struct igb_ring *);
+static void igb_update_tx_dca(struct igb_ring *);
+static void igb_setup_dca(struct igb_adapter *);
+#endif /* CONFIG_DCA */
+static bool igb_clean_tx_irq(struct igb_ring *);
+static int igb_poll(struct napi_struct *, int);
+static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
+static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
+#ifdef CONFIG_IGB_LRO
+static int igb_get_skb_hdr(struct sk_buff *skb, void **, void **, u64 *, void *);
+#endif
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
static void igb_tx_timeout(struct net_device *);
static void igb_reset_task(struct work_struct *);
@@ -121,6 +132,14 @@ static int igb_suspend(struct pci_dev *, pm_message_t);
static int igb_resume(struct pci_dev *);
#endif
static void igb_shutdown(struct pci_dev *);
+#ifdef CONFIG_DCA
+static int igb_notify_dca(struct notifier_block *, unsigned long, void *);
+static struct notifier_block dca_notifier = {
+ .notifier_call = igb_notify_dca,
+ .next = NULL,
+ .priority = 0
+};
+#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
/* for netdump / net console */
@@ -153,6 +172,8 @@ static struct pci_driver igb_driver = {
.err_handler = &igb_err_handler
};
+static int global_quad_port_a; /* global quad port a indication */
+
MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
@@ -184,7 +205,12 @@ static int __init igb_init_module(void)
printk(KERN_INFO "%s\n", igb_copyright);
+ global_quad_port_a = 0;
+
ret = pci_register_driver(&igb_driver);
+#ifdef CONFIG_DCA
+ dca_register_notify(&dca_notifier);
+#endif
return ret;
}
@@ -198,6 +224,9 @@ module_init(igb_init_module);
**/
static void __exit igb_exit_module(void)
{
+#ifdef CONFIG_DCA
+ dca_unregister_notify(&dca_notifier);
+#endif
pci_unregister_driver(&igb_driver);
}
@@ -226,25 +255,46 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
return -ENOMEM;
}
+ adapter->rx_ring->buddy = adapter->tx_ring;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct igb_ring *ring = &(adapter->tx_ring[i]);
+ ring->adapter = adapter;
+ ring->queue_index = i;
+ }
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &(adapter->rx_ring[i]);
ring->adapter = adapter;
+ ring->queue_index = i;
ring->itr_register = E1000_ITR;
- if (!ring->napi.poll)
- netif_napi_add(adapter->netdev, &ring->napi, igb_clean,
- adapter->napi.weight /
- adapter->num_rx_queues);
+ /* set a default napi handler for each rx_ring */
+ netif_napi_add(adapter->netdev, &ring->napi, igb_poll, 64);
}
return 0;
}
+static void igb_free_queues(struct igb_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ netif_napi_del(&adapter->rx_ring[i].napi);
+
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+}
+
#define IGB_N0_QUEUE -1
static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
int tx_queue, int msix_vector)
{
u32 msixbm = 0;
struct e1000_hw *hw = &adapter->hw;
+ u32 ivar, index;
+
+ switch (hw->mac.type) {
+ case e1000_82575:
/* The 82575 assigns vectors using a bitmask, which matches the
bitmask for the EICR/EIMS/EIMC registers. To assign one
or more queues to a vector, we write the appropriate bits
@@ -259,6 +309,47 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
E1000_EICR_TX_QUEUE0 << tx_queue;
}
array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
+ break;
+ case e1000_82576:
+ /* Kawela uses a table-based method for assigning vectors.
+ Each queue has a single entry in the table to which we write
+ a vector number along with a "valid" bit. Sadly, the layout
+ of the table is somewhat counterintuitive. */
+ if (rx_queue > IGB_N0_QUEUE) {
+ index = (rx_queue & 0x7);
+ ivar = array_rd32(E1000_IVAR0, index);
+ if (rx_queue < 8) {
+ /* vector goes into low byte of register */
+ ivar = ivar & 0xFFFFFF00;
+ ivar |= msix_vector | E1000_IVAR_VALID;
+ } else {
+ /* vector goes into third byte of register */
+ ivar = ivar & 0xFF00FFFF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+ }
+ adapter->rx_ring[rx_queue].eims_value= 1 << msix_vector;
+ array_wr32(E1000_IVAR0, index, ivar);
+ }
+ if (tx_queue > IGB_N0_QUEUE) {
+ index = (tx_queue & 0x7);
+ ivar = array_rd32(E1000_IVAR0, index);
+ if (tx_queue < 8) {
+ /* vector goes into second byte of register */
+ ivar = ivar & 0xFFFF00FF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+ } else {
+ /* vector goes into high byte of register */
+ ivar = ivar & 0x00FFFFFF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+ }
+ adapter->tx_ring[tx_queue].eims_value= 1 << msix_vector;
+ array_wr32(E1000_IVAR0, index, ivar);
+ }
+ break;
+ default:
+ BUG();
+ break;
+ }
}
/**
@@ -274,13 +365,19 @@ static void igb_configure_msix(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
adapter->eims_enable_mask = 0;
+ if (hw->mac.type == e1000_82576)
+ /* Turn on MSI-X capability first, or our settings
+ * won't stick. And it will take days to debug. */
+ wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
+ E1000_GPIE_PBA | E1000_GPIE_EIAME |
+ E1000_GPIE_NSICR);
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *tx_ring = &adapter->tx_ring[i];
igb_assign_vector(adapter, IGB_N0_QUEUE, i, vector++);
adapter->eims_enable_mask |= tx_ring->eims_value;
if (tx_ring->itr_val)
- writel(1000000000 / (tx_ring->itr_val * 256),
+ writel(tx_ring->itr_val,
hw->hw_addr + tx_ring->itr_register);
else
writel(1, hw->hw_addr + tx_ring->itr_register);
@@ -288,10 +385,11 @@ static void igb_configure_msix(struct igb_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *rx_ring = &adapter->rx_ring[i];
+ rx_ring->buddy = 0;
igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
adapter->eims_enable_mask |= rx_ring->eims_value;
if (rx_ring->itr_val)
- writel(1000000000 / (rx_ring->itr_val * 256),
+ writel(rx_ring->itr_val,
hw->hw_addr + rx_ring->itr_register);
else
writel(1, hw->hw_addr + rx_ring->itr_register);
@@ -299,12 +397,11 @@ static void igb_configure_msix(struct igb_adapter *adapter)
/* set vector for other causes, i.e. link changes */
+ switch (hw->mac.type) {
+ case e1000_82575:
array_wr32(E1000_MSIXBM(0), vector++,
E1000_EIMS_OTHER);
- /* disable IAM for ICR interrupt bits */
- wr32(E1000_IAM, 0);
-
tmp = rd32(E1000_CTRL_EXT);
/* enable MSI-X PBA support*/
tmp |= E1000_CTRL_EXT_PBA_CLR;
@@ -315,7 +412,21 @@ static void igb_configure_msix(struct igb_adapter *adapter)
wr32(E1000_CTRL_EXT, tmp);
adapter->eims_enable_mask |= E1000_EIMS_OTHER;
+ adapter->eims_other = E1000_EIMS_OTHER;
+
+ break;
+
+ case e1000_82576:
+ tmp = (vector++ | E1000_IVAR_VALID) << 8;
+ wr32(E1000_IVAR_MISC, tmp);
+ adapter->eims_enable_mask = (1 << (vector)) - 1;
+ adapter->eims_other = 1 << (vector - 1);
+ break;
+ default:
+ /* do nothing, since nothing else supports MSI-X */
+ break;
+ } /* switch (hw->mac.type) */
wrfl();
}
@@ -341,7 +452,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
if (err)
goto out;
ring->itr_register = E1000_EITR(0) + (vector << 2);
- ring->itr_val = adapter->itr;
+ ring->itr_val = 976; /* ~4000 ints/sec */
vector++;
}
for (i = 0; i < adapter->num_rx_queues; i++) {
@@ -357,6 +468,9 @@ static int igb_request_msix(struct igb_adapter *adapter)
goto out;
ring->itr_register = E1000_EITR(0) + (vector << 2);
ring->itr_val = adapter->itr;
+ /* overwrite the poll routine for MSIX, we've already done
+ * netif_napi_add */
+ ring->napi.poll = &igb_clean_rx_ring_msix;
vector++;
}
@@ -365,9 +479,6 @@ static int igb_request_msix(struct igb_adapter *adapter)
if (err)
goto out;
- adapter->napi.poll = igb_clean_rx_ring_msix;
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].napi.poll = adapter->napi.poll;
igb_configure_msix(adapter);
return 0;
out:
@@ -380,7 +491,7 @@ static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
- } else if (adapter->msi_enabled)
+ } else if (adapter->flags & IGB_FLAG_HAS_MSI)
pci_disable_msi(adapter->pdev);
return;
}
@@ -417,8 +528,12 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
/* If we can't do MSI-X, try MSI */
msi_only:
adapter->num_rx_queues = 1;
+ adapter->num_tx_queues = 1;
if (!pci_enable_msi(adapter->pdev))
- adapter->msi_enabled = 1;
+ adapter->flags |= IGB_FLAG_HAS_MSI;
+
+ /* Notify the stack of the (possibly) reduced Tx Queue count. */
+ adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
return;
}
@@ -436,29 +551,38 @@ static int igb_request_irq(struct igb_adapter *adapter)
if (adapter->msix_entries) {
err = igb_request_msix(adapter);
- if (!err) {
- /* enable IAM, auto-mask,
- * DO NOT USE EIAM or IAM in legacy mode */
- wr32(E1000_IAM, IMS_ENABLE_MASK);
+ if (!err)
goto request_done;
- }
/* fall back to MSI */
igb_reset_interrupt_capability(adapter);
if (!pci_enable_msi(adapter->pdev))
- adapter->msi_enabled = 1;
+ adapter->flags |= IGB_FLAG_HAS_MSI;
igb_free_all_tx_resources(adapter);
igb_free_all_rx_resources(adapter);
adapter->num_rx_queues = 1;
igb_alloc_queues(adapter);
+ } else {
+ switch (hw->mac.type) {
+ case e1000_82575:
+ wr32(E1000_MSIXBM(0),
+ (E1000_EICR_RX_QUEUE0 | E1000_EIMS_OTHER));
+ break;
+ case e1000_82576:
+ wr32(E1000_IVAR0, E1000_IVAR_VALID);
+ break;
+ default:
+ break;
+ }
}
- if (adapter->msi_enabled) {
+
+ if (adapter->flags & IGB_FLAG_HAS_MSI) {
err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
netdev->name, netdev);
if (!err)
goto request_done;
/* fall back to legacy interrupts */
igb_reset_interrupt_capability(adapter);
- adapter->msi_enabled = 0;
+ adapter->flags &= ~IGB_FLAG_HAS_MSI;
}
err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
@@ -502,9 +626,12 @@ static void igb_irq_disable(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
if (adapter->msix_entries) {
+ wr32(E1000_EIAM, 0);
wr32(E1000_EIMC, ~0);
wr32(E1000_EIAC, 0);
}
+
+ wr32(E1000_IAM, 0);
wr32(E1000_IMC, ~0);
wrfl();
synchronize_irq(adapter->pdev->irq);
@@ -519,13 +646,14 @@ static void igb_irq_enable(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
if (adapter->msix_entries) {
- wr32(E1000_EIMS,
- adapter->eims_enable_mask);
- wr32(E1000_EIAC,
- adapter->eims_enable_mask);
+ wr32(E1000_EIAC, adapter->eims_enable_mask);
+ wr32(E1000_EIAM, adapter->eims_enable_mask);
+ wr32(E1000_EIMS, adapter->eims_enable_mask);
wr32(E1000_IMS, E1000_IMS_LSC);
- } else
- wr32(E1000_IMS, IMS_ENABLE_MASK);
+ } else {
+ wr32(E1000_IMS, IMS_ENABLE_MASK);
+ wr32(E1000_IAM, IMS_ENABLE_MASK);
+ }
}
static void igb_update_mng_vlan(struct igb_adapter *adapter)
@@ -632,12 +760,15 @@ static void igb_configure(struct igb_adapter *adapter)
igb_configure_tx(adapter);
igb_setup_rctl(adapter);
igb_configure_rx(adapter);
+
+ igb_rx_fifo_flush_82575(&adapter->hw);
+
/* call IGB_DESC_UNUSED which always leaves
* at least 1 descriptor unused to make sure
* next_to_use != next_to_clean */
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &adapter->rx_ring[i];
- igb_alloc_rx_buffers_adv(adapter, ring, IGB_DESC_UNUSED(ring));
+ igb_alloc_rx_buffers_adv(ring, IGB_DESC_UNUSED(ring));
}
@@ -660,13 +791,10 @@ int igb_up(struct igb_adapter *adapter)
clear_bit(__IGB_DOWN, &adapter->state);
- napi_enable(&adapter->napi);
-
- if (adapter->msix_entries) {
- for (i = 0; i < adapter->num_rx_queues; i++)
- napi_enable(&adapter->rx_ring[i].napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->rx_ring[i].napi);
+ if (adapter->msix_entries)
igb_configure_msix(adapter);
- }
/* Clear any pending interrupts. */
rd32(E1000_ICR);
@@ -693,7 +821,7 @@ void igb_down(struct igb_adapter *adapter)
wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
tctl = rd32(E1000_TCTL);
@@ -703,11 +831,9 @@ void igb_down(struct igb_adapter *adapter)
wrfl();
msleep(10);
- napi_disable(&adapter->napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_disable(&adapter->rx_ring[i].napi);
- if (adapter->msix_entries)
- for (i = 0; i < adapter->num_rx_queues; i++)
- napi_disable(&adapter->rx_ring[i].napi);
igb_irq_disable(adapter);
del_timer_sync(&adapter->watchdog_timer);
@@ -737,16 +863,23 @@ void igb_reinit_locked(struct igb_adapter *adapter)
void igb_reset(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- struct e1000_fc_info *fc = &adapter->hw.fc;
+ struct e1000_mac_info *mac = &hw->mac;
+ struct e1000_fc_info *fc = &hw->fc;
u32 pba = 0, tx_space, min_tx_space, min_rx_space;
u16 hwm;
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
+ if (mac->type != e1000_82576) {
pba = E1000_PBA_34K;
+ }
+ else {
+ pba = E1000_PBA_64K;
+ }
- if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
+ if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
+ (mac->type < e1000_82576)) {
/* adjust PBA for jumbo frames */
wr32(E1000_PBA, pba);
@@ -785,8 +918,8 @@ void igb_reset(struct igb_adapter *adapter)
if (pba < min_rx_space)
pba = min_rx_space;
}
+ wr32(E1000_PBA, pba);
}
- wr32(E1000_PBA, pba);
/* flow control settings */
/* The high water mark must be low enough to fit one full frame
@@ -795,10 +928,15 @@ void igb_reset(struct igb_adapter *adapter)
* - 90% of the Rx FIFO size, or
* - the full Rx FIFO size minus one full frame */
hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - adapter->max_frame_size));
+ ((pba << 10) - 2 * adapter->max_frame_size));
- fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
- fc->low_water = fc->high_water - 8;
+ if (mac->type < e1000_82576) {
+ fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
+ fc->low_water = fc->high_water - 8;
+ } else {
+ fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */
+ fc->low_water = fc->high_water - 16;
+ }
fc->pause_time = 0xFFFF;
fc->send_xon = 1;
fc->type = fc->original_type;
@@ -821,6 +959,21 @@ void igb_reset(struct igb_adapter *adapter)
}
/**
+ * igb_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Returns true if an adapter needs ioport resources
+ **/
+static int igb_is_need_ioport(struct pci_dev *pdev)
+{
+ switch (pdev->device) {
+ /* Currently there are no adapters that need ioport resources */
+ default:
+ return false;
+ }
+}
+
+/**
* igb_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in igb_pci_tbl
@@ -839,13 +992,21 @@ static int __devinit igb_probe(struct pci_dev *pdev,
struct e1000_hw *hw;
const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len;
- static int cards_found;
int i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num;
+ int bars, need_ioport;
- err = pci_enable_device(pdev);
+ /* do not allocate ioport bars when not needed */
+ need_ioport = igb_is_need_ioport(pdev);
+ if (need_ioport) {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+ err = pci_enable_device(pdev);
+ } else {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ err = pci_enable_device_mem(pdev);
+ }
if (err)
return err;
@@ -867,7 +1028,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
}
}
- err = pci_request_regions(pdev, igb_driver_name);
+ err = pci_request_selected_regions(pdev, bars, igb_driver_name);
if (err)
goto err_pci_reg;
@@ -875,7 +1036,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
pci_save_state(pdev);
err = -ENOMEM;
- netdev = alloc_etherdev(sizeof(struct igb_adapter));
+ netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
if (!netdev)
goto err_alloc_etherdev;
@@ -888,6 +1049,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
hw = &adapter->hw;
hw->back = adapter;
adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+ adapter->bars = bars;
+ adapter->need_ioport = need_ioport;
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);
@@ -907,7 +1070,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
igb_set_ethtool_ops(netdev);
netdev->tx_timeout = &igb_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
- netif_napi_add(netdev, &adapter->napi, igb_clean, 64);
netdev->vlan_rx_register = igb_vlan_rx_register;
netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
@@ -921,8 +1083,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
- adapter->bd_number = cards_found;
-
/* PCI config space info */
hw->vendor_id = pdev->vendor;
hw->device_id = pdev->device;
@@ -947,6 +1107,17 @@ static int __devinit igb_probe(struct pci_dev *pdev,
igb_get_bus_info_pcie(hw);
+ /* set flags */
+ switch (hw->mac.type) {
+ case e1000_82576:
+ case e1000_82575:
+ adapter->flags |= IGB_FLAG_HAS_DCA;
+ adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
+ break;
+ default:
+ break;
+ }
+
hw->phy.autoneg_wait_to_complete = false;
hw->mac.adaptive_ifs = true;
@@ -968,8 +1139,17 @@ static int __devinit igb_probe(struct pci_dev *pdev,
NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_TSO;
-
netdev->features |= NETIF_F_TSO6;
+
+#ifdef CONFIG_IGB_LRO
+ netdev->features |= NETIF_F_LRO;
+#endif
+
+ netdev->vlan_features |= NETIF_F_TSO;
+ netdev->vlan_features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_SG;
+
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
@@ -1053,11 +1233,23 @@ static int __devinit igb_probe(struct pci_dev *pdev,
adapter->eeprom_wol = 0;
break;
case E1000_DEV_ID_82575EB_FIBER_SERDES:
+ case E1000_DEV_ID_82576_FIBER:
+ case E1000_DEV_ID_82576_SERDES:
/* Wake events only supported on port A for dual fiber
* regardless of eeprom setting */
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
adapter->eeprom_wol = 0;
break;
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ /* if quad port adapter, disable WoL on all but port A */
+ if (global_quad_port_a != 0)
+ adapter->eeprom_wol = 0;
+ else
+ adapter->flags |= IGB_FLAG_QUAD_PORT_A;
+ /* Reset for multiple quad port adapters */
+ if (++global_quad_port_a == 4)
+ global_quad_port_a = 0;
+ break;
}
/* initialize the wol settings based on the eeprom settings */
@@ -1072,13 +1264,25 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* tell the stack to leave us alone until igb_open() is called */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+#ifdef CONFIG_DCA
+ if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
+ (dca_add_requester(&pdev->dev) == 0)) {
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
+ dev_info(&pdev->dev, "DCA enabled\n");
+ /* Always use CB2 mode, difference is masked
+ * in the CB driver. */
+ wr32(E1000_DCA_CTRL, 2);
+ igb_setup_dca(adapter);
+ }
+#endif
+
dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
/* print bus type/speed/width info */
dev_info(&pdev->dev,
@@ -1099,10 +1303,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
dev_info(&pdev->dev,
"Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
adapter->msix_entries ? "MSI-X" :
- adapter->msi_enabled ? "MSI" : "legacy",
+ (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
adapter->num_rx_queues, adapter->num_tx_queues);
- cards_found++;
return 0;
err_register:
@@ -1115,15 +1318,14 @@ err_eeprom:
iounmap(hw->flash_address);
igb_remove_device(hw);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
+ igb_free_queues(adapter);
err_sw_init:
err_hw_init:
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, bars);
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -1143,6 +1345,9 @@ static void __devexit igb_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_DCA
+ struct e1000_hw *hw = &adapter->hw;
+#endif
/* flush_scheduled work may reschedule our watchdog task, so
* explicitly disable watchdog tasks from being rescheduled */
@@ -1152,6 +1357,15 @@ static void __devexit igb_remove(struct pci_dev *pdev)
flush_scheduled_work();
+#ifdef CONFIG_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
+ dev_info(&pdev->dev, "DCA disabled\n");
+ dca_remove_requester(&pdev->dev);
+ adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
+ wr32(E1000_DCA_CTRL, 1);
+ }
+#endif
+
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
igb_release_hw_control(adapter);
@@ -1164,13 +1378,12 @@ static void __devexit igb_remove(struct pci_dev *pdev)
igb_remove_device(&adapter->hw);
igb_reset_interrupt_capability(adapter);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
+ igb_free_queues(adapter);
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, adapter->bars);
free_netdev(netdev);
@@ -1200,9 +1413,11 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
/* Number of supported queues. */
/* Having more queues than CPUs doesn't make sense. */
- adapter->num_tx_queues = 1;
- adapter->num_rx_queues = min(IGB_MAX_RX_QUEUES, num_online_cpus());
+ adapter->num_rx_queues = min((u32)IGB_MAX_RX_QUEUES, (u32)num_online_cpus());
+ adapter->num_tx_queues = min(IGB_MAX_TX_QUEUES, num_online_cpus());
+ /* This call may decrease the number of queues depending on
+ * interrupt mode. */
igb_set_interrupt_capability(adapter);
if (igb_alloc_queues(adapter)) {
@@ -1270,15 +1485,16 @@ static int igb_open(struct net_device *netdev)
/* From here on the code is the same as igb_up() */
clear_bit(__IGB_DOWN, &adapter->state);
- napi_enable(&adapter->napi);
- if (adapter->msix_entries)
- for (i = 0; i < adapter->num_rx_queues; i++)
- napi_enable(&adapter->rx_ring[i].napi);
-
- igb_irq_enable(adapter);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->rx_ring[i].napi);
/* Clear any pending interrupts. */
rd32(E1000_ICR);
+
+ igb_irq_enable(adapter);
+
+ netif_tx_start_all_queues(netdev);
+
/* Fire a link status change interrupt to start the watchdog. */
wr32(E1000_ICS, E1000_ICS_LSC);
@@ -1364,8 +1580,6 @@ int igb_setup_tx_resources(struct igb_adapter *adapter,
tx_ring->adapter = adapter;
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- spin_lock_init(&tx_ring->tx_clean_lock);
- spin_lock_init(&tx_ring->tx_lock);
return 0;
err:
@@ -1385,6 +1599,7 @@ err:
static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
{
int i, err = 0;
+ int r_idx;
for (i = 0; i < adapter->num_tx_queues; i++) {
err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
@@ -1392,12 +1607,15 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
dev_err(&adapter->pdev->dev,
"Allocation for Tx Queue %u failed\n", i);
for (i--; i >= 0; i--)
- igb_free_tx_resources(adapter,
- &adapter->tx_ring[i]);
+ igb_free_tx_resources(&adapter->tx_ring[i]);
break;
}
}
+ for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
+ r_idx = i % adapter->num_tx_queues;
+ adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
+ }
return err;
}
@@ -1484,6 +1702,14 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
struct pci_dev *pdev = adapter->pdev;
int size, desc_len;
+#ifdef CONFIG_IGB_LRO
+ size = sizeof(struct net_lro_desc) * MAX_LRO_DESCRIPTORS;
+ rx_ring->lro_mgr.lro_arr = vmalloc(size);
+ if (!rx_ring->lro_mgr.lro_arr)
+ goto err;
+ memset(rx_ring->lro_mgr.lro_arr, 0, size);
+#endif
+
size = sizeof(struct igb_buffer) * rx_ring->count;
rx_ring->buffer_info = vmalloc(size);
if (!rx_ring->buffer_info)
@@ -1504,15 +1730,16 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
- rx_ring->pending_skb = NULL;
rx_ring->adapter = adapter;
- /* FIXME: do we want to setup ring->napi->poll here? */
- rx_ring->napi.poll = adapter->napi.poll;
return 0;
err:
+#ifdef CONFIG_IGB_LRO
+ vfree(rx_ring->lro_mgr.lro_arr);
+ rx_ring->lro_mgr.lro_arr = NULL;
+#endif
vfree(rx_ring->buffer_info);
dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
"the receive descriptor ring\n");
@@ -1536,8 +1763,7 @@ static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
dev_err(&adapter->pdev->dev,
"Allocation for Rx Queue %u failed\n", i);
for (i--; i >= 0; i--)
- igb_free_rx_resources(adapter,
- &adapter->rx_ring[i]);
+ igb_free_rx_resources(&adapter->rx_ring[i]);
break;
}
}
@@ -1564,10 +1790,12 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
- /* disable the stripping of CRC because it breaks
- * BMC firmware connected over SMBUS
- rctl |= E1000_RCTL_SECRC;
+ /*
+ * enable stripping of CRC. It's unlikely this will break BMC
+ * redirection as it did with e1000. Newer features require
+ * that the HW strips the CRC.
*/
+ rctl |= E1000_RCTL_SECRC;
rctl &= ~E1000_RCTL_SBP;
@@ -1597,15 +1825,6 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
rctl |= E1000_RCTL_SZ_2048;
rctl &= ~E1000_RCTL_BSEX;
break;
- case IGB_RXBUFFER_4096:
- rctl |= E1000_RCTL_SZ_4096;
- break;
- case IGB_RXBUFFER_8192:
- rctl |= E1000_RCTL_SZ_8192;
- break;
- case IGB_RXBUFFER_16384:
- rctl |= E1000_RCTL_SZ_16384;
- break;
}
} else {
rctl &= ~E1000_RCTL_BSEX;
@@ -1623,10 +1842,8 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
* so only enable packet split for jumbo frames */
if (rctl & E1000_RCTL_LPE) {
adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
- srrctl = adapter->rx_ps_hdr_size <<
+ srrctl |= adapter->rx_ps_hdr_size <<
E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
- /* buffer size is ALWAYS one page */
- srrctl |= PAGE_SIZE >> E1000_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
} else {
adapter->rx_ps_hdr_size = 0;
@@ -1660,8 +1877,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
mdelay(10);
if (adapter->itr_setting > 3)
- wr32(E1000_ITR,
- 1000000000 / (adapter->itr * 256));
+ wr32(E1000_ITR, adapter->itr);
/* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring */
@@ -1686,6 +1902,16 @@ static void igb_configure_rx(struct igb_adapter *adapter)
rxdctl |= IGB_RX_HTHRESH << 8;
rxdctl |= IGB_RX_WTHRESH << 16;
wr32(E1000_RXDCTL(i), rxdctl);
+#ifdef CONFIG_IGB_LRO
+ /* Intitial LRO Settings */
+ ring->lro_mgr.max_aggr = MAX_LRO_AGGR;
+ ring->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
+ ring->lro_mgr.get_skb_header = igb_get_skb_hdr;
+ ring->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
+ ring->lro_mgr.dev = adapter->netdev;
+ ring->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+ ring->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+#endif
}
if (adapter->num_rx_queues > 1) {
@@ -1699,7 +1925,10 @@ static void igb_configure_rx(struct igb_adapter *adapter)
get_random_bytes(&random[0], 40);
- shift = 6;
+ if (hw->mac.type >= e1000_82576)
+ shift = 0;
+ else
+ shift = 6;
for (j = 0; j < (32 * 4); j++) {
reta.bytes[j & 3] =
(j % adapter->num_rx_queues) << shift;
@@ -1765,12 +1994,11 @@ static void igb_configure_rx(struct igb_adapter *adapter)
*
* Free all transmit software resources
**/
-static void igb_free_tx_resources(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+static void igb_free_tx_resources(struct igb_ring *tx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *pdev = tx_ring->adapter->pdev;
- igb_clean_tx_ring(adapter, tx_ring);
+ igb_clean_tx_ring(tx_ring);
vfree(tx_ring->buffer_info);
tx_ring->buffer_info = NULL;
@@ -1791,7 +2019,7 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_free_tx_resources(adapter, &adapter->tx_ring[i]);
+ igb_free_tx_resources(&adapter->tx_ring[i]);
}
static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
@@ -1817,9 +2045,9 @@ static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
* @adapter: board private structure
* @tx_ring: ring to be cleaned
**/
-static void igb_clean_tx_ring(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+static void igb_clean_tx_ring(struct igb_ring *tx_ring)
{
+ struct igb_adapter *adapter = tx_ring->adapter;
struct igb_buffer *buffer_info;
unsigned long size;
unsigned int i;
@@ -1856,7 +2084,7 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+ igb_clean_tx_ring(&adapter->tx_ring[i]);
}
/**
@@ -1866,16 +2094,20 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
*
* Free all receive software resources
**/
-static void igb_free_rx_resources(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+static void igb_free_rx_resources(struct igb_ring *rx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *pdev = rx_ring->adapter->pdev;
- igb_clean_rx_ring(adapter, rx_ring);
+ igb_clean_rx_ring(rx_ring);
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
+#ifdef CONFIG_IGB_LRO
+ vfree(rx_ring->lro_mgr.lro_arr);
+ rx_ring->lro_mgr.lro_arr = NULL;
+#endif
+
pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
rx_ring->desc = NULL;
@@ -1892,7 +2124,7 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_free_rx_resources(adapter, &adapter->rx_ring[i]);
+ igb_free_rx_resources(&adapter->rx_ring[i]);
}
/**
@@ -1900,9 +2132,9 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
* @adapter: board private structure
* @rx_ring: ring to free buffers from
**/
-static void igb_clean_rx_ring(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+static void igb_clean_rx_ring(struct igb_ring *rx_ring)
{
+ struct igb_adapter *adapter = rx_ring->adapter;
struct igb_buffer *buffer_info;
struct pci_dev *pdev = adapter->pdev;
unsigned long size;
@@ -1930,20 +2162,17 @@ static void igb_clean_rx_ring(struct igb_adapter *adapter,
buffer_info->skb = NULL;
}
if (buffer_info->page) {
- pci_unmap_page(pdev, buffer_info->page_dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ if (buffer_info->page_dma)
+ pci_unmap_page(pdev, buffer_info->page_dma,
+ PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
put_page(buffer_info->page);
buffer_info->page = NULL;
buffer_info->page_dma = 0;
+ buffer_info->page_offset = 0;
}
}
- /* there also may be some cached data from a chained receive */
- if (rx_ring->pending_skb) {
- dev_kfree_skb(rx_ring->pending_skb);
- rx_ring->pending_skb = NULL;
- }
-
size = sizeof(struct igb_buffer) * rx_ring->count;
memset(rx_ring->buffer_info, 0, size);
@@ -1966,7 +2195,7 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+ igb_clean_rx_ring(&adapter->rx_ring[i]);
}
/**
@@ -2015,19 +2244,22 @@ static void igb_set_multi(struct net_device *netdev)
rctl = rd32(E1000_RCTL);
- if (netdev->flags & IFF_PROMISC)
+ if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- rctl &= ~E1000_RCTL_UPE;
- } else
- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
-
+ rctl &= ~E1000_RCTL_VFE;
+ } else {
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ rctl &= ~E1000_RCTL_UPE;
+ } else
+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ rctl |= E1000_RCTL_VFE;
+ }
wr32(E1000_RCTL, rctl);
if (!netdev->mc_count) {
/* nothing to program, so clear mc list */
- igb_update_mc_addr_list(hw, NULL, 0, 1,
+ igb_update_mc_addr_list_82575(hw, NULL, 0, 1,
mac->rar_entry_count);
return;
}
@@ -2045,7 +2277,8 @@ static void igb_set_multi(struct net_device *netdev)
memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
mc_ptr = mc_ptr->next;
}
- igb_update_mc_addr_list(hw, mta_list, i, 1, mac->rar_entry_count);
+ igb_update_mc_addr_list_82575(hw, mta_list, i, 1,
+ mac->rar_entry_count);
kfree(mta_list);
}
@@ -2135,7 +2368,7 @@ static void igb_watchdog_task(struct work_struct *work)
}
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
+ netif_tx_wake_all_queues(netdev);
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
@@ -2147,7 +2380,7 @@ static void igb_watchdog_task(struct work_struct *work)
adapter->link_duplex = 0;
dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -2200,38 +2433,60 @@ enum latency_range {
};
-static void igb_lower_rx_eitr(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+/**
+ * igb_update_ring_itr - update the dynamic ITR value based on packet size
+ *
+ * Stores a new ITR value based on strictly on packet size. This
+ * algorithm is less sophisticated than that used in igb_update_itr,
+ * due to the difficulty of synchronizing statistics across multiple
+ * receive rings. The divisors and thresholds used by this fuction
+ * were determined based on theoretical maximum wire speed and testing
+ * data, in order to minimize response time while increasing bulk
+ * throughput.
+ * This functionality is controlled by the InterruptThrottleRate module
+ * parameter (see igb_param.c)
+ * NOTE: This function is called only when operating in a multiqueue
+ * receive environment.
+ * @rx_ring: pointer to ring
+ **/
+static void igb_update_ring_itr(struct igb_ring *rx_ring)
{
- struct e1000_hw *hw = &adapter->hw;
- int new_val;
+ int new_val = rx_ring->itr_val;
+ int avg_wire_size = 0;
+ struct igb_adapter *adapter = rx_ring->adapter;
- new_val = rx_ring->itr_val / 2;
- if (new_val < IGB_MIN_DYN_ITR)
- new_val = IGB_MIN_DYN_ITR;
+ if (!rx_ring->total_packets)
+ goto clear_counts; /* no packets, so don't do anything */
- if (new_val != rx_ring->itr_val) {
- rx_ring->itr_val = new_val;
- wr32(rx_ring->itr_register,
- 1000000000 / (new_val * 256));
+ /* For non-gigabit speeds, just fix the interrupt rate at 4000
+ * ints/sec - ITR timer value of 120 ticks.
+ */
+ if (adapter->link_speed != SPEED_1000) {
+ new_val = 120;
+ goto set_itr_val;
}
-}
+ avg_wire_size = rx_ring->total_bytes / rx_ring->total_packets;
-static void igb_raise_rx_eitr(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
-{
- struct e1000_hw *hw = &adapter->hw;
- int new_val;
+ /* Add 24 bytes to size to account for CRC, preamble, and gap */
+ avg_wire_size += 24;
- new_val = rx_ring->itr_val * 2;
- if (new_val > IGB_MAX_DYN_ITR)
- new_val = IGB_MAX_DYN_ITR;
+ /* Don't starve jumbo frames */
+ avg_wire_size = min(avg_wire_size, 3000);
+ /* Give a little boost to mid-size frames */
+ if ((avg_wire_size > 300) && (avg_wire_size < 1200))
+ new_val = avg_wire_size / 3;
+ else
+ new_val = avg_wire_size / 2;
+
+set_itr_val:
if (new_val != rx_ring->itr_val) {
rx_ring->itr_val = new_val;
- wr32(rx_ring->itr_register,
- 1000000000 / (new_val * 256));
+ rx_ring->set_itr = 1;
}
+clear_counts:
+ rx_ring->total_bytes = 0;
+ rx_ring->total_packets = 0;
}
/**
@@ -2298,8 +2553,7 @@ update_itr_done:
return retval;
}
-static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
- int rx_only)
+static void igb_set_itr(struct igb_adapter *adapter)
{
u16 current_itr;
u32 new_itr = adapter->itr;
@@ -2315,26 +2569,23 @@ static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
adapter->rx_itr,
adapter->rx_ring->total_packets,
adapter->rx_ring->total_bytes);
- /* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
- adapter->rx_itr = low_latency;
- if (!rx_only) {
+ if (adapter->rx_ring->buddy) {
adapter->tx_itr = igb_update_itr(adapter,
adapter->tx_itr,
adapter->tx_ring->total_packets,
adapter->tx_ring->total_bytes);
- /* conservative mode (itr 3) eliminates the
- * lowest_latency setting */
- if (adapter->itr_setting == 3 &&
- adapter->tx_itr == lowest_latency)
- adapter->tx_itr = low_latency;
current_itr = max(adapter->rx_itr, adapter->tx_itr);
} else {
current_itr = adapter->rx_itr;
}
+ /* conservative mode (itr 3) eliminates the lowest_latency setting */
+ if (adapter->itr_setting == 3 &&
+ current_itr == lowest_latency)
+ current_itr = low_latency;
+
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
case lowest_latency:
@@ -2351,6 +2602,13 @@ static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
}
set_itr_now:
+ adapter->rx_ring->total_bytes = 0;
+ adapter->rx_ring->total_packets = 0;
+ if (adapter->rx_ring->buddy) {
+ adapter->rx_ring->buddy->total_bytes = 0;
+ adapter->rx_ring->buddy->total_packets = 0;
+ }
+
if (new_itr != adapter->itr) {
/* this attempts to bias the interrupt rate towards Bulk
* by adding intermediate steps when interrupt rate is
@@ -2365,7 +2623,8 @@ set_itr_now:
* ends up being correct.
*/
adapter->itr = new_itr;
- adapter->set_itr = 1;
+ adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256);
+ adapter->rx_ring->set_itr = 1;
}
return;
@@ -2441,9 +2700,9 @@ static inline int igb_tso_adv(struct igb_adapter *adapter,
mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
- /* Context index must be unique per ring. Luckily, so is the interrupt
- * mask value. */
- mss_l4len_idx |= tx_ring->eims_value >> 4;
+ /* Context index must be unique per ring. */
+ if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+ mss_l4len_idx |= tx_ring->queue_index << 4;
context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
context_desc->seqnum_seed = 0;
@@ -2507,8 +2766,9 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
context_desc->seqnum_seed = 0;
- context_desc->mss_l4len_idx =
- cpu_to_le32(tx_ring->eims_value >> 4);
+ if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+ context_desc->mss_l4len_idx =
+ cpu_to_le32(tx_ring->queue_index << 4);
buffer_info->time_stamp = jiffies;
buffer_info->dma = 0;
@@ -2609,9 +2869,10 @@ static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
}
- if (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
- IGB_TX_FLAGS_VLAN))
- olinfo_status |= tx_ring->eims_value >> 4;
+ if ((adapter->flags & IGB_FLAG_NEED_CTX_IDX) &&
+ (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
+ IGB_TX_FLAGS_VLAN)))
+ olinfo_status |= tx_ring->queue_index << 4;
olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
@@ -2647,7 +2908,8 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
{
struct igb_adapter *adapter = netdev_priv(netdev);
- netif_stop_queue(netdev);
+ netif_stop_subqueue(netdev, tx_ring->queue_index);
+
/* Herbert's original patch had:
* smp_mb__after_netif_stop_queue();
* but since that doesn't exist yet, just open code it. */
@@ -2659,7 +2921,7 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
return -EBUSY;
/* A reprieve! */
- netif_start_queue(netdev);
+ netif_wake_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
return 0;
}
@@ -2681,7 +2943,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
struct igb_adapter *adapter = netdev_priv(netdev);
unsigned int tx_flags = 0;
unsigned int len;
- unsigned long irq_flags;
u8 hdr_len = 0;
int tso = 0;
@@ -2697,10 +2958,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
return NETDEV_TX_OK;
}
- if (!spin_trylock_irqsave(&tx_ring->tx_lock, irq_flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
/* need: 1 descriptor per page,
* + 2 desc gap to keep tail from touching head,
* + 1 desc for skb->data,
@@ -2708,21 +2965,23 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
* otherwise try next time */
if (igb_maybe_stop_tx(netdev, tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
/* this is a hard error */
- spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
return NETDEV_TX_BUSY;
}
+ skb_orphan(skb);
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
}
+ if (skb->protocol == htons(ETH_P_IP))
+ tx_flags |= IGB_TX_FLAGS_IPV4;
+
tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
&hdr_len) : 0;
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
return NETDEV_TX_OK;
}
@@ -2732,9 +2991,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
if (skb->ip_summed == CHECKSUM_PARTIAL)
tx_flags |= IGB_TX_FLAGS_CSUM;
- if (skb->protocol == htons(ETH_P_IP))
- tx_flags |= IGB_TX_FLAGS_IPV4;
-
igb_tx_queue_adv(adapter, tx_ring, tx_flags,
igb_tx_map_adv(adapter, tx_ring, skb),
skb->len, hdr_len);
@@ -2744,14 +3000,17 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
/* Make sure there is space in the ring for the next send. */
igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
- spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
return NETDEV_TX_OK;
}
static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- struct igb_ring *tx_ring = &adapter->tx_ring[0];
+ struct igb_ring *tx_ring;
+
+ int r_idx = 0;
+ r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
+ tx_ring = adapter->multi_tx_table[r_idx];
/* This goes back to the question of how to logically map a tx queue
* to a flow. Right now, performance is impacted slightly negatively
@@ -2846,7 +3105,11 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
else if (max_frame <= IGB_RXBUFFER_2048)
adapter->rx_buffer_len = IGB_RXBUFFER_2048;
else
- adapter->rx_buffer_len = IGB_RXBUFFER_4096;
+#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
+ adapter->rx_buffer_len = IGB_RXBUFFER_16384;
+#else
+ adapter->rx_buffer_len = PAGE_SIZE / 2;
+#endif
/* adjust allocation if LPE protects us, and we aren't using SBP */
if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
@@ -3010,26 +3273,19 @@ static irqreturn_t igb_msix_other(int irq, void *data)
struct net_device *netdev = data;
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 eicr;
- /* disable interrupts from the "other" bit, avoid re-entry */
- wr32(E1000_EIMC, E1000_EIMS_OTHER);
-
- eicr = rd32(E1000_EICR);
-
- if (eicr & E1000_EIMS_OTHER) {
- u32 icr = rd32(E1000_ICR);
- /* reading ICR causes bit 31 of EICR to be cleared */
- if (!(icr & E1000_ICR_LSC))
- goto no_link_interrupt;
- hw->mac.get_link_status = 1;
- /* guard against interrupt when we're going down */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
+ u32 icr = rd32(E1000_ICR);
+ /* reading ICR causes bit 31 of EICR to be cleared */
+ if (!(icr & E1000_ICR_LSC))
+ goto no_link_interrupt;
+ hw->mac.get_link_status = 1;
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__IGB_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
no_link_interrupt:
wr32(E1000_IMS, E1000_IMS_LSC);
- wr32(E1000_EIMS, E1000_EIMS_OTHER);
+ wr32(E1000_EIMS, adapter->eims_other);
return IRQ_HANDLED;
}
@@ -3040,44 +3296,186 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
struct igb_adapter *adapter = tx_ring->adapter;
struct e1000_hw *hw = &adapter->hw;
- if (!tx_ring->itr_val)
- wr32(E1000_EIMC, tx_ring->eims_value);
-
+#ifdef CONFIG_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_tx_dca(tx_ring);
+#endif
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
- if (!igb_clean_tx_irq(adapter, tx_ring))
+
+ /* auto mask will automatically reenable the interrupt when we write
+ * EICS */
+ if (!igb_clean_tx_irq(tx_ring))
/* Ring was not completely cleaned, so fire another interrupt */
wr32(E1000_EICS, tx_ring->eims_value);
-
- if (!tx_ring->itr_val)
+ else
wr32(E1000_EIMS, tx_ring->eims_value);
+
return IRQ_HANDLED;
}
+static void igb_write_itr(struct igb_ring *ring)
+{
+ struct e1000_hw *hw = &ring->adapter->hw;
+ if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
+ switch (hw->mac.type) {
+ case e1000_82576:
+ wr32(ring->itr_register,
+ ring->itr_val |
+ 0x80000000);
+ break;
+ default:
+ wr32(ring->itr_register,
+ ring->itr_val |
+ (ring->itr_val << 16));
+ break;
+ }
+ ring->set_itr = 0;
+ }
+}
+
static irqreturn_t igb_msix_rx(int irq, void *data)
{
struct igb_ring *rx_ring = data;
struct igb_adapter *adapter = rx_ring->adapter;
- struct e1000_hw *hw = &adapter->hw;
- if (!rx_ring->itr_val)
- wr32(E1000_EIMC, rx_ring->eims_value);
+ /* Write the ITR value calculated at the end of the
+ * previous interrupt.
+ */
+
+ igb_write_itr(rx_ring);
- if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) {
- rx_ring->total_bytes = 0;
- rx_ring->total_packets = 0;
- rx_ring->no_itr_adjust = 0;
+ if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
__netif_rx_schedule(adapter->netdev, &rx_ring->napi);
- } else {
- if (!rx_ring->no_itr_adjust) {
- igb_lower_rx_eitr(adapter, rx_ring);
- rx_ring->no_itr_adjust = 1;
+
+#ifdef CONFIG_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(rx_ring);
+#endif
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_DCA
+static void igb_update_rx_dca(struct igb_ring *rx_ring)
+{
+ u32 dca_rxctrl;
+ struct igb_adapter *adapter = rx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ int cpu = get_cpu();
+ int q = rx_ring - adapter->rx_ring;
+
+ if (rx_ring->cpu != cpu) {
+ dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
+ if (hw->mac.type == e1000_82576) {
+ dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
+ dca_rxctrl |= dca_get_tag(cpu) <<
+ E1000_DCA_RXCTRL_CPUID_SHIFT;
+ } else {
+ dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
+ dca_rxctrl |= dca_get_tag(cpu);
}
+ dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
+ dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
+ dca_rxctrl |= E1000_DCA_RXCTRL_DATA_DCA_EN;
+ wr32(E1000_DCA_RXCTRL(q), dca_rxctrl);
+ rx_ring->cpu = cpu;
}
+ put_cpu();
+}
- return IRQ_HANDLED;
+static void igb_update_tx_dca(struct igb_ring *tx_ring)
+{
+ u32 dca_txctrl;
+ struct igb_adapter *adapter = tx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ int cpu = get_cpu();
+ int q = tx_ring - adapter->tx_ring;
+
+ if (tx_ring->cpu != cpu) {
+ dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
+ if (hw->mac.type == e1000_82576) {
+ dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
+ dca_txctrl |= dca_get_tag(cpu) <<
+ E1000_DCA_TXCTRL_CPUID_SHIFT;
+ } else {
+ dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
+ dca_txctrl |= dca_get_tag(cpu);
+ }
+ dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
+ wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
+ tx_ring->cpu = cpu;
+ }
+ put_cpu();
+}
+
+static void igb_setup_dca(struct igb_adapter *adapter)
+{
+ int i;
+
+ if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
+ return;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ adapter->tx_ring[i].cpu = -1;
+ igb_update_tx_dca(&adapter->tx_ring[i]);
+ }
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ adapter->rx_ring[i].cpu = -1;
+ igb_update_rx_dca(&adapter->rx_ring[i]);
+ }
+}
+
+static int __igb_notify_dca(struct device *dev, void *data)
+{
+ struct net_device *netdev = dev_get_drvdata(dev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned long event = *(unsigned long *)data;
+
+ if (!(adapter->flags & IGB_FLAG_HAS_DCA))
+ goto out;
+
+ switch (event) {
+ case DCA_PROVIDER_ADD:
+ /* if already enabled, don't do it again */
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ break;
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
+ /* Always use CB2 mode, difference is masked
+ * in the CB driver. */
+ wr32(E1000_DCA_CTRL, 2);
+ if (dca_add_requester(dev) == 0) {
+ dev_info(&adapter->pdev->dev, "DCA enabled\n");
+ igb_setup_dca(adapter);
+ break;
+ }
+ /* Fall Through since DCA is disabled. */
+ case DCA_PROVIDER_REMOVE:
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
+ /* without this a class_device is left
+ * hanging around in the sysfs model */
+ dca_remove_requester(dev);
+ dev_info(&adapter->pdev->dev, "DCA disabled\n");
+ adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
+ wr32(E1000_DCA_CTRL, 1);
+ }
+ break;
+ }
+out:
+ return 0;
}
+static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
+ void *p)
+{
+ int ret_val;
+
+ ret_val = driver_for_each_device(&igb_driver.driver, NULL, &event,
+ __igb_notify_dca);
+
+ return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
+}
+#endif /* CONFIG_DCA */
/**
* igb_intr_msi - Interrupt Handler
@@ -3088,34 +3486,19 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
{
struct net_device *netdev = data;
struct igb_adapter *adapter = netdev_priv(netdev);
- struct napi_struct *napi = &adapter->napi;
struct e1000_hw *hw = &adapter->hw;
/* read ICR disables interrupts using IAM */
u32 icr = rd32(E1000_ICR);
- /* Write the ITR value calculated at the end of the
- * previous interrupt.
- */
- if (adapter->set_itr) {
- wr32(E1000_ITR,
- 1000000000 / (adapter->itr * 256));
- adapter->set_itr = 0;
- }
+ igb_write_itr(adapter->rx_ring);
- /* read ICR disables interrupts using IAM */
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(netdev, napi)) {
- adapter->tx_ring->total_bytes = 0;
- adapter->tx_ring->total_packets = 0;
- adapter->rx_ring->total_bytes = 0;
- adapter->rx_ring->total_packets = 0;
- __netif_rx_schedule(netdev, napi);
- }
+ netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
@@ -3129,7 +3512,6 @@ static irqreturn_t igb_intr(int irq, void *data)
{
struct net_device *netdev = data;
struct igb_adapter *adapter = netdev_priv(netdev);
- struct napi_struct *napi = &adapter->napi;
struct e1000_hw *hw = &adapter->hw;
/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
* need for the IMC write */
@@ -3138,14 +3520,7 @@ static irqreturn_t igb_intr(int irq, void *data)
if (!icr)
return IRQ_NONE; /* Not our interrupt */
- /* Write the ITR value calculated at the end of the
- * previous interrupt.
- */
- if (adapter->set_itr) {
- wr32(E1000_ITR,
- 1000000000 / (adapter->itr * 256));
- adapter->set_itr = 0;
- }
+ igb_write_itr(adapter->rx_ring);
/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
* not set, then the adapter didn't send an interrupt */
@@ -3161,57 +3536,41 @@ static irqreturn_t igb_intr(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(netdev, napi)) {
- adapter->tx_ring->total_bytes = 0;
- adapter->rx_ring->total_bytes = 0;
- adapter->tx_ring->total_packets = 0;
- adapter->rx_ring->total_packets = 0;
- __netif_rx_schedule(netdev, napi);
- }
+ netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
/**
- * igb_clean - NAPI Rx polling callback
- * @adapter: board private structure
+ * igb_poll - NAPI Rx polling callback
+ * @napi: napi polling structure
+ * @budget: count of how many packets we should handle
**/
-static int igb_clean(struct napi_struct *napi, int budget)
+static int igb_poll(struct napi_struct *napi, int budget)
{
- struct igb_adapter *adapter = container_of(napi, struct igb_adapter,
- napi);
+ struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
+ struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
- int tx_clean_complete = 1, work_done = 0;
- int i;
-
- /* Must NOT use netdev_priv macro here. */
- adapter = netdev->priv;
+ int tx_clean_complete, work_done = 0;
- /* Keep link state information with original netdev */
- if (!netif_carrier_ok(netdev))
- goto quit_polling;
-
- /* igb_clean is called per-cpu. This lock protects tx_ring[i] from
- * being cleaned by multiple cpus simultaneously. A failure obtaining
- * the lock means tx_ring[i] is currently being cleaned anyway. */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- if (spin_trylock(&adapter->tx_ring[i].tx_clean_lock)) {
- tx_clean_complete &= igb_clean_tx_irq(adapter,
- &adapter->tx_ring[i]);
- spin_unlock(&adapter->tx_ring[i].tx_clean_lock);
- }
- }
+ /* this poll routine only supports one tx and one rx queue */
+#ifdef CONFIG_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_tx_dca(&adapter->tx_ring[0]);
+#endif
+ tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i], &work_done,
- adapter->rx_ring[i].napi.weight);
+#ifdef CONFIG_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(&adapter->rx_ring[0]);
+#endif
+ igb_clean_rx_irq_adv(&adapter->rx_ring[0], &work_done, budget);
/* If no Tx and not enough Rx work done, exit the polling mode */
if ((tx_clean_complete && (work_done < budget)) ||
!netif_running(netdev)) {
-quit_polling:
if (adapter->itr_setting & 3)
- igb_set_itr(adapter, E1000_ITR, false);
+ igb_set_itr(adapter);
netif_rx_complete(netdev, napi);
if (!test_bit(__IGB_DOWN, &adapter->state))
igb_irq_enable(adapter);
@@ -3233,7 +3592,11 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
if (!netif_carrier_ok(netdev))
goto quit_polling;
- igb_clean_rx_irq_adv(adapter, rx_ring, &work_done, budget);
+#ifdef CONFIG_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(rx_ring);
+#endif
+ igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
/* If not enough Rx work done, exit the polling mode */
@@ -3241,16 +3604,16 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
quit_polling:
netif_rx_complete(netdev, napi);
- wr32(E1000_EIMS, rx_ring->eims_value);
- if ((adapter->itr_setting & 3) && !rx_ring->no_itr_adjust &&
- (rx_ring->total_packets > IGB_DYN_ITR_PACKET_THRESHOLD)) {
- int mean_size = rx_ring->total_bytes /
- rx_ring->total_packets;
- if (mean_size < IGB_DYN_ITR_LENGTH_LOW)
- igb_raise_rx_eitr(adapter, rx_ring);
- else if (mean_size > IGB_DYN_ITR_LENGTH_HIGH)
- igb_lower_rx_eitr(adapter, rx_ring);
+ if (adapter->itr_setting & 3) {
+ if (adapter->num_rx_queues == 1)
+ igb_set_itr(adapter);
+ else
+ igb_update_ring_itr(rx_ring);
}
+
+ if (!test_bit(__IGB_DOWN, &adapter->state))
+ wr32(E1000_EIMS, rx_ring->eims_value);
+
return 0;
}
@@ -3268,11 +3631,11 @@ static inline u32 get_head(struct igb_ring *tx_ring)
* @adapter: board private structure
* returns true if ring is completely cleaned
**/
-static bool igb_clean_tx_irq(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
{
- struct net_device *netdev = adapter->netdev;
+ struct igb_adapter *adapter = tx_ring->adapter;
struct e1000_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
struct e1000_tx_desc *tx_desc;
struct igb_buffer *buffer_info;
struct sk_buff *skb;
@@ -3334,9 +3697,9 @@ done_cleaning:
* sees the new next_to_clean.
*/
smp_mb();
- if (netif_queue_stopped(netdev) &&
+ if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!(test_bit(__IGB_DOWN, &adapter->state))) {
- netif_wake_queue(netdev);
+ netif_wake_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
}
}
@@ -3355,7 +3718,7 @@ done_cleaning:
/* detected Tx unit hang */
dev_err(&adapter->pdev->dev,
"Detected Tx Unit Hang\n"
- " Tx Queue <%lu>\n"
+ " Tx Queue <%d>\n"
" TDH <%x>\n"
" TDT <%x>\n"
" next_to_use <%x>\n"
@@ -3365,8 +3728,7 @@ done_cleaning:
" time_stamp <%lx>\n"
" jiffies <%lx>\n"
" desc.status <%x>\n",
- (unsigned long)((tx_ring - adapter->tx_ring) /
- sizeof(struct igb_ring)),
+ tx_ring->queue_index,
readl(adapter->hw.hw_addr + tx_ring->head),
readl(adapter->hw.hw_addr + tx_ring->tail),
tx_ring->next_to_use,
@@ -3375,33 +3737,87 @@ done_cleaning:
tx_ring->buffer_info[i].time_stamp,
jiffies,
tx_desc->upper.fields.status);
- netif_stop_queue(netdev);
+ netif_stop_subqueue(netdev, tx_ring->queue_index);
}
}
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
+ tx_ring->tx_stats.bytes += total_bytes;
+ tx_ring->tx_stats.packets += total_packets;
adapter->net_stats.tx_bytes += total_bytes;
adapter->net_stats.tx_packets += total_packets;
return retval;
}
+#ifdef CONFIG_IGB_LRO
+ /**
+ * igb_get_skb_hdr - helper function for LRO header processing
+ * @skb: pointer to sk_buff to be added to LRO packet
+ * @iphdr: pointer to ip header structure
+ * @tcph: pointer to tcp header structure
+ * @hdr_flags: pointer to header flags
+ * @priv: pointer to the receive descriptor for the current sk_buff
+ **/
+static int igb_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
+ u64 *hdr_flags, void *priv)
+{
+ union e1000_adv_rx_desc *rx_desc = priv;
+ u16 pkt_type = rx_desc->wb.lower.lo_dword.pkt_info &
+ (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP);
+
+ /* Verify that this is a valid IPv4 TCP packet */
+ if (pkt_type != (E1000_RXDADV_PKTTYPE_IPV4 |
+ E1000_RXDADV_PKTTYPE_TCP))
+ return -1;
+
+ /* Set network headers */
+ skb_reset_network_header(skb);
+ skb_set_transport_header(skb, ip_hdrlen(skb));
+ *iphdr = ip_hdr(skb);
+ *tcph = tcp_hdr(skb);
+ *hdr_flags = LRO_IPV4 | LRO_TCP;
+
+ return 0;
+
+}
+#endif /* CONFIG_IGB_LRO */
/**
* igb_receive_skb - helper function to handle rx indications
- * @adapter: board private structure
+ * @ring: pointer to receive ring receving this packet
* @status: descriptor status field as written by hardware
* @vlan: descriptor vlan field as written by hardware (no le/be conversion)
* @skb: pointer to sk_buff to be indicated to stack
**/
-static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan,
- struct sk_buff *skb)
+static void igb_receive_skb(struct igb_ring *ring, u8 status,
+ union e1000_adv_rx_desc * rx_desc,
+ struct sk_buff *skb)
{
- if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan) &
- E1000_RXD_SPC_VLAN_MASK);
- else
- netif_receive_skb(skb);
+ struct igb_adapter * adapter = ring->adapter;
+ bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
+
+#ifdef CONFIG_IGB_LRO
+ if (adapter->netdev->features & NETIF_F_LRO &&
+ skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ if (vlan_extracted)
+ lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
+ adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan),
+ rx_desc);
+ else
+ lro_receive_skb(&ring->lro_mgr,skb, rx_desc);
+ ring->lro_used = 1;
+ } else {
+#endif
+ if (vlan_extracted)
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan));
+ else
+
+ netif_receive_skb(skb);
+#ifdef CONFIG_IGB_LRO
+ }
+#endif
}
@@ -3427,16 +3843,16 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
adapter->hw_csum_good++;
}
-static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
- struct igb_ring *rx_ring,
- int *work_done, int budget)
+static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
+ int *work_done, int budget)
{
+ struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_adv_rx_desc *rx_desc , *next_rxd;
struct igb_buffer *buffer_info , *next_buffer;
struct sk_buff *skb;
- unsigned int i, j;
+ unsigned int i;
u32 length, hlen, staterr;
bool cleaned = false;
int cleaned_count = 0;
@@ -3466,64 +3882,48 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
cleaned = true;
cleaned_count++;
- if (rx_ring->pending_skb != NULL) {
- skb = rx_ring->pending_skb;
- rx_ring->pending_skb = NULL;
- j = rx_ring->pending_skb_page;
- } else {
- skb = buffer_info->skb;
- prefetch(skb->data - NET_IP_ALIGN);
- buffer_info->skb = NULL;
- if (hlen) {
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_ps_hdr_size +
- NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
- skb_put(skb, hlen);
- } else {
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_buffer_len +
- NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
- skb_put(skb, length);
- goto send_up;
- }
- j = 0;
+ skb = buffer_info->skb;
+ prefetch(skb->data - NET_IP_ALIGN);
+ buffer_info->skb = NULL;
+ if (!adapter->rx_ps_hdr_size) {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_buffer_len +
+ NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
+ skb_put(skb, length);
+ goto send_up;
+ }
+
+ if (!skb_shinfo(skb)->nr_frags) {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_ps_hdr_size +
+ NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
+ skb_put(skb, hlen);
}
- while (length) {
+ if (length) {
pci_unmap_page(pdev, buffer_info->page_dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
buffer_info->page_dma = 0;
- skb_fill_page_desc(skb, j, buffer_info->page,
- 0, length);
- buffer_info->page = NULL;
+
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
+ buffer_info->page,
+ buffer_info->page_offset,
+ length);
+
+ if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
+ (page_count(buffer_info->page) != 1))
+ buffer_info->page = NULL;
+ else
+ get_page(buffer_info->page);
skb->len += length;
skb->data_len += length;
- skb->truesize += length;
- rx_desc->wb.upper.status_error = 0;
- if (staterr & E1000_RXD_STAT_EOP)
- break;
- j++;
- cleaned_count++;
- i++;
- if (i == rx_ring->count)
- i = 0;
-
- buffer_info = &rx_ring->buffer_info[i];
- rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
- staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
- length = le16_to_cpu(rx_desc->wb.upper.length);
- if (!(staterr & E1000_RXD_STAT_DD)) {
- rx_ring->pending_skb = skb;
- rx_ring->pending_skb_page = j;
- goto out;
- }
+ skb->truesize += length;
}
send_up:
- pskb_trim(skb, skb->len - 4);
i++;
if (i == rx_ring->count)
i = 0;
@@ -3531,11 +3931,16 @@ send_up:
prefetch(next_rxd);
next_buffer = &rx_ring->buffer_info[i];
+ if (!(staterr & E1000_RXD_STAT_EOP)) {
+ buffer_info->skb = xchg(&next_buffer->skb, skb);
+ buffer_info->dma = xchg(&next_buffer->dma, 0);
+ goto next_desc;
+ }
+
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
dev_kfree_skb_irq(skb);
goto next_desc;
}
- rx_ring->no_itr_adjust |= (staterr & E1000_RXD_STAT_DYNINT);
total_bytes += skb->len;
total_packets++;
@@ -3544,7 +3949,7 @@ send_up:
skb->protocol = eth_type_trans(skb, netdev);
- igb_receive_skb(adapter, staterr, rx_desc->wb.upper.vlan, skb);
+ igb_receive_skb(rx_ring, staterr, rx_desc, skb);
netdev->last_rx = jiffies;
@@ -3553,8 +3958,7 @@ next_desc:
/* return some buffers to hardware, one at a time is too slow */
if (cleaned_count >= IGB_RX_BUFFER_WRITE) {
- igb_alloc_rx_buffers_adv(adapter, rx_ring,
- cleaned_count);
+ igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
cleaned_count = 0;
}
@@ -3564,12 +3968,19 @@ next_desc:
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
-out:
+
rx_ring->next_to_clean = i;
cleaned_count = IGB_DESC_UNUSED(rx_ring);
+#ifdef CONFIG_IGB_LRO
+ if (rx_ring->lro_used) {
+ lro_flush_all(&rx_ring->lro_mgr);
+ rx_ring->lro_used = 0;
+ }
+#endif
+
if (cleaned_count)
- igb_alloc_rx_buffers_adv(adapter, rx_ring, cleaned_count);
+ igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
rx_ring->total_packets += total_packets;
rx_ring->total_bytes += total_bytes;
@@ -3585,10 +3996,10 @@ out:
* igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
-static void igb_alloc_rx_buffers_adv(struct igb_adapter *adapter,
- struct igb_ring *rx_ring,
+static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
int cleaned_count)
{
+ struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_adv_rx_desc *rx_desc;
@@ -3602,16 +4013,22 @@ static void igb_alloc_rx_buffers_adv(struct igb_adapter *adapter,
while (cleaned_count--) {
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
- if (adapter->rx_ps_hdr_size && !buffer_info->page) {
- buffer_info->page = alloc_page(GFP_ATOMIC);
+ if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
if (!buffer_info->page) {
- adapter->alloc_rx_buff_failed++;
- goto no_buffers;
+ buffer_info->page = alloc_page(GFP_ATOMIC);
+ if (!buffer_info->page) {
+ adapter->alloc_rx_buff_failed++;
+ goto no_buffers;
+ }
+ buffer_info->page_offset = 0;
+ } else {
+ buffer_info->page_offset ^= PAGE_SIZE / 2;
}
buffer_info->page_dma =
pci_map_page(pdev,
buffer_info->page,
- 0, PAGE_SIZE,
+ buffer_info->page_offset,
+ PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
}
@@ -3746,7 +4163,6 @@ static void igb_vlan_rx_register(struct net_device *netdev,
/* enable VLAN receive filtering */
rctl = rd32(E1000_RCTL);
- rctl |= E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_CFIEN;
wr32(E1000_RCTL, rctl);
igb_update_mng_vlan(adapter);
@@ -3758,10 +4174,6 @@ static void igb_vlan_rx_register(struct net_device *netdev,
ctrl &= ~E1000_CTRL_VME;
wr32(E1000_CTRL, ctrl);
- /* disable VLAN filtering */
- rctl = rd32(E1000_RCTL);
- rctl &= ~E1000_RCTL_VFE;
- wr32(E1000_RCTL, rctl);
if (adapter->mng_vlan_id != (u16)IGB_MNG_VLAN_NONE) {
igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
@@ -3878,7 +4290,7 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, ctrl_ext, rctl, status;
+ u32 ctrl, rctl, status;
u32 wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
@@ -3886,11 +4298,12 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
netif_device_detach(netdev);
- if (netif_running(netdev)) {
- WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
- igb_down(adapter);
- igb_free_irq(adapter);
- }
+ if (netif_running(netdev))
+ igb_close(netdev);
+
+ igb_reset_interrupt_capability(adapter);
+
+ igb_free_queues(adapter);
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
@@ -3921,33 +4334,24 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
ctrl |= E1000_CTRL_ADVD3WUC;
wr32(E1000_CTRL, ctrl);
- if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
- adapter->hw.phy.media_type ==
- e1000_media_type_internal_serdes) {
- /* keep the laser running in D3 */
- ctrl_ext = rd32(E1000_CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
- wr32(E1000_CTRL_EXT, ctrl_ext);
- }
-
/* Allow time for pending master requests to run */
igb_disable_pcie_master(&adapter->hw);
wr32(E1000_WUC, E1000_WUC_PME_EN);
wr32(E1000_WUFC, wufc);
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
} else {
wr32(E1000_WUC, 0);
wr32(E1000_WUFC, 0);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
}
- /* make sure adapter isn't asleep if manageability is enabled */
- if (adapter->en_mng_pt) {
+ /* make sure adapter isn't asleep if manageability/wol is enabled */
+ if (wufc || adapter->en_mng_pt) {
pci_enable_wake(pdev, PCI_D3hot, 1);
pci_enable_wake(pdev, PCI_D3cold, 1);
+ } else {
+ igb_shutdown_fiber_serdes_link_82575(hw);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
}
/* Release control of h/w to f/w. If f/w is AMT enabled, this
@@ -3971,7 +4375,11 @@ static int igb_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- err = pci_enable_device(pdev);
+
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"igb: Cannot enable PCI device from suspend\n");
@@ -3982,10 +4390,11 @@ static int igb_resume(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
- if (netif_running(netdev)) {
- err = igb_request_irq(adapter);
- if (err)
- return err;
+ igb_set_interrupt_capability(adapter);
+
+ if (igb_alloc_queues(adapter)) {
+ dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
}
/* e1000_power_up_phy(adapter); */
@@ -3993,10 +4402,11 @@ static int igb_resume(struct pci_dev *pdev)
igb_reset(adapter);
wr32(E1000_WUS, ~0);
- igb_init_manageability(adapter);
-
- if (netif_running(netdev))
- igb_up(adapter);
+ if (netif_running(netdev)) {
+ err = igb_open(netdev);
+ if (err)
+ return err;
+ }
netif_device_attach(netdev);
@@ -4026,14 +4436,17 @@ static void igb_netpoll(struct net_device *netdev)
int work_done = 0;
igb_irq_disable(adapter);
+ adapter->flags |= IGB_FLAG_IN_NETPOLL;
+
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+ igb_clean_tx_irq(&adapter->tx_ring[i]);
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i],
+ igb_clean_rx_irq_adv(&adapter->rx_ring[i],
&work_done,
adapter->rx_ring[i].napi.weight);
+ adapter->flags &= ~IGB_FLAG_IN_NETPOLL;
igb_irq_enable(adapter);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -4074,8 +4487,13 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ int err;
- if (pci_enable_device(pdev)) {
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
+ if (err) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 2c03f4e2ccc..7373dafbb3f 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -42,7 +42,6 @@
#define ipg_r16(reg) ioread16(ioaddr + (reg))
#define ipg_r8(reg) ioread8(ioaddr + (reg))
-#define JUMBO_FRAME_4k_ONLY
enum {
netdev_io_size = 128
};
@@ -55,6 +54,14 @@ MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver");
MODULE_LICENSE("GPL");
/*
+ * Defaults
+ */
+#define IPG_MAX_RXFRAME_SIZE 0x0600
+#define IPG_RXFRAG_SIZE 0x0600
+#define IPG_RXSUPPORT_SIZE 0x0600
+#define IPG_IS_JUMBO false
+
+/*
* Variable record -- index by leading revision/length
* Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
*/
@@ -631,6 +638,7 @@ static void ipg_nic_set_multicast_list(struct net_device *dev)
static int ipg_io_config(struct net_device *dev)
{
+ struct ipg_nic_private *sp = netdev_priv(dev);
void __iomem *ioaddr = ipg_ioaddr(dev);
u32 origmacctrl;
u32 restoremacctrl;
@@ -670,7 +678,7 @@ static int ipg_io_config(struct net_device *dev)
/* Set RECEIVEMODE register. */
ipg_nic_set_multicast_list(dev);
- ipg_w16(IPG_MAX_RXFRAME_SIZE, MAX_FRAME_SIZE);
+ ipg_w16(sp->max_rxframe_size, MAX_FRAME_SIZE);
ipg_w8(IPG_RXDMAPOLLPERIOD_VALUE, RX_DMA_POLL_PERIOD);
ipg_w8(IPG_RXDMAURGENTTHRESH_VALUE, RX_DMA_URGENT_THRESH);
@@ -730,7 +738,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
IPG_DEBUG_MSG("_get_rxbuff\n");
- skb = netdev_alloc_skb(dev, IPG_RXSUPPORT_SIZE + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(dev, sp->rxsupport_size + NET_IP_ALIGN);
if (!skb) {
sp->rx_buff[entry] = NULL;
return -ENOMEM;
@@ -751,7 +759,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
sp->rx_buf_sz, PCI_DMA_FROMDEVICE));
/* Set the RFD fragment length. */
- rxfragsize = IPG_RXFRAG_SIZE;
+ rxfragsize = sp->rxfrag_size;
rxfd->frag_info |= cpu_to_le64((rxfragsize << 48) & IPG_RFI_FRAGLEN);
return 0;
@@ -1076,8 +1084,6 @@ static int ipg_nic_rxrestore(struct net_device *dev)
return 0;
}
-#ifdef JUMBO_FRAME
-
/* use jumboindex and jumbosize to control jumbo frame status
* initial status is jumboindex=-1 and jumbosize=0
* 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.
@@ -1097,7 +1103,7 @@ enum {
FRAME_WITH_START_WITH_END = 11
};
-inline void ipg_nic_rx_free_skb(struct net_device *dev)
+static void ipg_nic_rx_free_skb(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH;
@@ -1113,7 +1119,7 @@ inline void ipg_nic_rx_free_skb(struct net_device *dev)
}
}
-inline int ipg_nic_rx_check_frame_type(struct net_device *dev)
+static int ipg_nic_rx_check_frame_type(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH);
@@ -1126,7 +1132,7 @@ inline int ipg_nic_rx_check_frame_type(struct net_device *dev)
return type;
}
-inline int ipg_nic_rx_check_error(struct net_device *dev)
+static int ipg_nic_rx_check_error(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH;
@@ -1209,8 +1215,8 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
/* accept this frame and send to upper layer */
framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
- if (framelen > IPG_RXFRAG_SIZE)
- framelen = IPG_RXFRAG_SIZE;
+ if (framelen > sp->rxfrag_size)
+ framelen = sp->rxfrag_size;
skb_put(skb, framelen);
skb->protocol = eth_type_trans(skb, dev);
@@ -1243,10 +1249,10 @@ static void ipg_nic_rx_with_start(struct net_device *dev,
pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
- skb_put(skb, IPG_RXFRAG_SIZE);
+ skb_put(skb, sp->rxfrag_size);
jumbo->found_start = 1;
- jumbo->current_size = IPG_RXFRAG_SIZE;
+ jumbo->current_size = sp->rxfrag_size;
jumbo->skb = skb;
sp->rx_buff[entry] = NULL;
@@ -1272,11 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
endframelen = framelen - jumbo->current_size;
- /*
- if (framelen > IPG_RXFRAG_SIZE)
- framelen=IPG_RXFRAG_SIZE;
- */
- if (framelen > IPG_RXSUPPORT_SIZE)
+ if (framelen > sp->rxsupport_size)
dev_kfree_skb_irq(jumbo->skb);
else {
memcpy(skb_put(jumbo->skb, endframelen),
@@ -1316,11 +1318,11 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
if (skb) {
if (jumbo->found_start) {
- jumbo->current_size += IPG_RXFRAG_SIZE;
- if (jumbo->current_size <= IPG_RXSUPPORT_SIZE) {
+ jumbo->current_size += sp->rxfrag_size;
+ if (jumbo->current_size <= sp->rxsupport_size) {
memcpy(skb_put(jumbo->skb,
- IPG_RXFRAG_SIZE),
- skb->data, IPG_RXFRAG_SIZE);
+ sp->rxfrag_size),
+ skb->data, sp->rxfrag_size);
}
}
dev->last_rx = jiffies;
@@ -1334,7 +1336,7 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
}
}
-static int ipg_nic_rx(struct net_device *dev)
+static int ipg_nic_rx_jumbo(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
unsigned int curr = sp->rx_current;
@@ -1382,7 +1384,6 @@ static int ipg_nic_rx(struct net_device *dev)
return 0;
}
-#else
static int ipg_nic_rx(struct net_device *dev)
{
/* Transfer received Ethernet frames to higher network layers. */
@@ -1413,11 +1414,11 @@ static int ipg_nic_rx(struct net_device *dev)
/* Check for jumbo frame arrival with too small
* RXFRAG_SIZE.
*/
- if (framelen > IPG_RXFRAG_SIZE) {
+ if (framelen > sp->rxfrag_size) {
IPG_DEBUG_MSG
("RFS FrameLen > allocated fragment size.\n");
- framelen = IPG_RXFRAG_SIZE;
+ framelen = sp->rxfrag_size;
}
if ((IPG_DROP_ON_RX_ETH_ERRORS && (le64_to_cpu(rxfd->rfs) &
@@ -1556,7 +1557,6 @@ static int ipg_nic_rx(struct net_device *dev)
return 0;
}
-#endif
static void ipg_reset_after_host_error(struct work_struct *work)
{
@@ -1592,9 +1592,9 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
IPG_DEBUG_MSG("_interrupt_handler\n");
-#ifdef JUMBO_FRAME
- ipg_nic_rxrestore(dev);
-#endif
+ if (sp->is_jumbo)
+ ipg_nic_rxrestore(dev);
+
spin_lock(&sp->lock);
/* Get interrupt source information, and acknowledge
@@ -1650,7 +1650,10 @@ static irqreturn_t ipg_interrupt_handler(int irq, void *dev_inst)
sp->RFDListCheckedCount++;
#endif
- ipg_nic_rx(dev);
+ if (sp->is_jumbo)
+ ipg_nic_rx_jumbo(dev);
+ else
+ ipg_nic_rx(dev);
}
/* If TxDMAComplete interrupt, free used TFDs. */
@@ -1749,7 +1752,7 @@ static int ipg_nic_open(struct net_device *dev)
IPG_DEBUG_MSG("_nic_open\n");
- sp->rx_buf_sz = IPG_RXSUPPORT_SIZE;
+ sp->rx_buf_sz = sp->rxsupport_size;
/* Check for interrupt line conflicts, and request interrupt
* line for IPG.
@@ -1804,13 +1807,10 @@ static int ipg_nic_open(struct net_device *dev)
if (ipg_config_autoneg(dev) < 0)
printk(KERN_INFO "%s: Auto-negotiation error.\n", dev->name);
-#ifdef JUMBO_FRAME
/* initialize JUMBO Frame control variable */
sp->jumbo.found_start = 0;
sp->jumbo.current_size = 0;
sp->jumbo.skb = NULL;
- dev->mtu = IPG_TXFRAG_SIZE;
-#endif
/* Enable transmit and receive operation of the IPG. */
ipg_w32((ipg_r32(MAC_CTRL) | IPG_MC_RX_ENABLE | IPG_MC_TX_ENABLE) &
@@ -2119,6 +2119,9 @@ static int ipg_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu)
{
+ struct ipg_nic_private *sp = netdev_priv(dev);
+ int err;
+
/* Function to accomodate changes to Maximum Transfer Unit
* (or MTU) of IPG NIC. Cannot use default function since
* the default will not allow for MTU > 1500 bytes.
@@ -2126,16 +2129,33 @@ static int ipg_nic_change_mtu(struct net_device *dev, int new_mtu)
IPG_DEBUG_MSG("_nic_change_mtu\n");
- /* Check that the new MTU value is between 68 (14 byte header, 46
- * byte payload, 4 byte FCS) and IPG_MAX_RXFRAME_SIZE, which
- * corresponds to the MAXFRAMESIZE register in the IPG.
+ /*
+ * Check that the new MTU value is between 68 (14 byte header, 46 byte
+ * payload, 4 byte FCS) and 10 KB, which is the largest supported MTU.
*/
- if ((new_mtu < 68) || (new_mtu > IPG_MAX_RXFRAME_SIZE))
+ if (new_mtu < 68 || new_mtu > 10240)
return -EINVAL;
+ err = ipg_nic_stop(dev);
+ if (err)
+ return err;
+
dev->mtu = new_mtu;
- return 0;
+ sp->max_rxframe_size = new_mtu;
+
+ sp->rxfrag_size = new_mtu;
+ if (sp->rxfrag_size > 4088)
+ sp->rxfrag_size = 4088;
+
+ sp->rxsupport_size = sp->max_rxframe_size;
+
+ if (new_mtu > 0x0600)
+ sp->is_jumbo = true;
+ else
+ sp->is_jumbo = false;
+
+ return ipg_nic_open(dev);
}
static int ipg_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -2240,6 +2260,11 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
spin_lock_init(&sp->lock);
mutex_init(&sp->mii_mutex);
+ sp->is_jumbo = IPG_IS_JUMBO;
+ sp->rxfrag_size = IPG_RXFRAG_SIZE;
+ sp->rxsupport_size = IPG_RXSUPPORT_SIZE;
+ sp->max_rxframe_size = IPG_MAX_RXFRAME_SIZE;
+
/* Declare IPG NIC functions for Ethernet device methods.
*/
dev->open = &ipg_nic_open;
diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h
index cda53887d4d..e0e718ab4c2 100644
--- a/drivers/net/ipg.h
+++ b/drivers/net/ipg.h
@@ -536,83 +536,6 @@ enum ipg_regs {
*/
#define IPG_FRAMESBETWEENTXDMACOMPLETES 0x1
-#ifdef JUMBO_FRAME
-
-# ifdef JUMBO_FRAME_SIZE_2K
-# define JUMBO_FRAME_SIZE 2048
-# define __IPG_RXFRAG_SIZE 2048
-# else
-# ifdef JUMBO_FRAME_SIZE_3K
-# define JUMBO_FRAME_SIZE 3072
-# define __IPG_RXFRAG_SIZE 3072
-# else
-# ifdef JUMBO_FRAME_SIZE_4K
-# define JUMBO_FRAME_SIZE 4096
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# ifdef JUMBO_FRAME_SIZE_5K
-# define JUMBO_FRAME_SIZE 5120
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# ifdef JUMBO_FRAME_SIZE_6K
-# define JUMBO_FRAME_SIZE 6144
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# ifdef JUMBO_FRAME_SIZE_7K
-# define JUMBO_FRAME_SIZE 7168
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# ifdef JUMBO_FRAME_SIZE_8K
-# define JUMBO_FRAME_SIZE 8192
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# ifdef JUMBO_FRAME_SIZE_9K
-# define JUMBO_FRAME_SIZE 9216
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# ifdef JUMBO_FRAME_SIZE_10K
-# define JUMBO_FRAME_SIZE 10240
-# define __IPG_RXFRAG_SIZE 4088
-# else
-# define JUMBO_FRAME_SIZE 4096
-# endif
-# endif
-# endif
-# endif
-# endif
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* Size of allocated received buffers. Nominally 0x0600.
- * Define larger if expecting jumbo frames.
- */
-#ifdef JUMBO_FRAME
-/* IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash */
-#define IPG_TXFRAG_SIZE JUMBO_FRAME_SIZE
-#endif
-
-/* Size of allocated received buffers. Nominally 0x0600.
- * Define larger if expecting jumbo frames.
- */
-#ifdef JUMBO_FRAME
-/* 4088 = 4096 - 8 */
-#define IPG_RXFRAG_SIZE __IPG_RXFRAG_SIZE
-#define IPG_RXSUPPORT_SIZE IPG_MAX_RXFRAME_SIZE
-#else
-#define IPG_RXFRAG_SIZE 0x0600
-#define IPG_RXSUPPORT_SIZE IPG_RXFRAG_SIZE
-#endif
-
-/* IPG_MAX_RXFRAME_SIZE <= IPG_RXFRAG_SIZE */
-#ifdef JUMBO_FRAME
-#define IPG_MAX_RXFRAME_SIZE JUMBO_FRAME_SIZE
-#else
-#define IPG_MAX_RXFRAME_SIZE 0x0600
-#endif
-
#define IPG_RFDLIST_LENGTH 0x100
/* Maximum number of RFDs to process per interrupt.
@@ -786,9 +709,11 @@ struct ipg_nic_private {
unsigned int tx_dirty;
unsigned int rx_current;
unsigned int rx_dirty;
-#ifdef JUMBO_FRAME
+ bool is_jumbo;
struct ipg_jumbo jumbo;
-#endif
+ unsigned long rxfrag_size;
+ unsigned long rxsupport_size;
+ unsigned long max_rxframe_size;
unsigned int rx_buf_sz;
struct pci_dev *pdev;
struct net_device *dev;
diff --git a/drivers/net/irda/ali-ircc.h b/drivers/net/irda/ali-ircc.h
index 07876578887..ed35d99763d 100644
--- a/drivers/net/irda/ali-ircc.h
+++ b/drivers/net/irda/ali-ircc.h
@@ -219,8 +219,6 @@ struct ali_ircc_cb {
int index; /* Instance index */
unsigned char fifo_opti_buf;
-
- struct pm_dev *dev;
};
static inline void switch_bank(int iobase, int bank)
diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h
index 7a31d4659ed..b4763f24dde 100644
--- a/drivers/net/irda/au1000_ircc.h
+++ b/drivers/net/irda/au1000_ircc.h
@@ -122,6 +122,5 @@ struct au1k_private {
struct timer_list timer;
spinlock_t lock; /* For serializing operations */
- struct pm_dev *dev;
};
#endif /* AU1000_IRCC_H */
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 1257e1a7e81..34ad189fff6 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -49,10 +49,6 @@
/* Look at toshoboe.h (currently in include/net/irda) for details of */
/* Where to get documentation on the chip */
-
-static char *rcsid =
- "$Id: donauboe.c V2.18 ven jan 10 03:14:16 2003$";
-
/* See below for a description of the logic in this driver */
/* User servicable parts */
@@ -1677,7 +1673,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
pci_set_drvdata(pci_dev,self);
- printk (KERN_INFO DRIVER_NAME ": Using multiple tasks, version %s\n", rcsid);
+ printk (KERN_INFO DRIVER_NAME ": Using multiple tasks\n");
return 0;
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index e6f40b7f904..9e33196f945 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -533,7 +533,7 @@ static void irtty_close(struct tty_struct *tty)
/* ------------------------------------------------------- */
-static struct tty_ldisc irda_ldisc = {
+static struct tty_ldisc_ops irda_ldisc = {
.magic = TTY_LDISC_MAGIC,
.name = "irda",
.flags = 0,
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index cfe0194fef7..78dc8e7837f 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -1,5 +1,4 @@
/*********************************************************************
- * $Id: smsc-ircc2.c,v 1.19.2.5 2002/10/27 11:34:26 dip Exp $
*
* Description: Driver for the SMC Infrared Communications Controller
* Status: Experimental.
diff --git a/drivers/net/irda/smsc-ircc2.h b/drivers/net/irda/smsc-ircc2.h
index 0c36286d87f..317b7fd69bb 100644
--- a/drivers/net/irda/smsc-ircc2.h
+++ b/drivers/net/irda/smsc-ircc2.h
@@ -1,5 +1,4 @@
/*********************************************************************
- * $Id: smsc-ircc2.h,v 1.12.2.1 2002/10/27 10:52:37 dip Exp $
*
* Description: Definitions for the SMC IrCC chipset
* Status: Experimental.
diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h
index 9d012f0dbd3..403c3f77634 100644
--- a/drivers/net/irda/via-ircc.h
+++ b/drivers/net/irda/via-ircc.h
@@ -118,7 +118,6 @@ struct via_ircc_cb {
int index; /* Instance index */
struct eventflag EventFlag;
- struct pm_dev *dev;
unsigned int chip_id; /* to remember chip id */
unsigned int RetryCount;
unsigned int RxDataReady;
diff --git a/drivers/net/ixgb/Makefile b/drivers/net/ixgb/Makefile
index 838a5084fa0..0b20c5e62ff 100644
--- a/drivers/net/ixgb/Makefile
+++ b/drivers/net/ixgb/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel PRO/10GbE Linux driver
-# Copyright(c) 1999 - 2006 Intel Corporation.
+# Copyright(c) 1999 - 2008 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
index 16f9c756aa4..804698fc6a8 100644
--- a/drivers/net/ixgb/ixgb.h
+++ b/drivers/net/ixgb/ixgb.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -89,18 +89,16 @@ struct ixgb_adapter;
/* TX/RX descriptor defines */
-#define DEFAULT_TXD 256
-#define MAX_TXD 4096
-#define MIN_TXD 64
+#define DEFAULT_TXD 256
+#define MAX_TXD 4096
+#define MIN_TXD 64
/* hardware cannot reliably support more than 512 descriptors owned by
- * hardware descrioptor cache otherwise an unreliable ring under heavy
- * recieve load may result */
-/* #define DEFAULT_RXD 1024 */
-/* #define MAX_RXD 4096 */
-#define DEFAULT_RXD 512
-#define MAX_RXD 512
-#define MIN_RXD 64
+ * hardware descriptor cache otherwise an unreliable ring under heavy
+ * receive load may result */
+#define DEFAULT_RXD 512
+#define MAX_RXD 512
+#define MIN_RXD 64
/* Supported Rx Buffer Sizes */
#define IXGB_RXBUFFER_2048 2048
@@ -157,7 +155,6 @@ struct ixgb_adapter {
u32 part_num;
u16 link_speed;
u16 link_duplex;
- spinlock_t tx_lock;
struct work_struct tx_timeout_task;
struct timer_list blink_timer;
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
index 2f7ed52c750..89ffa7264a1 100644
--- a/drivers/net/ixgb/ixgb_ee.c
+++ b/drivers/net/ixgb/ixgb_ee.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -108,7 +108,7 @@ ixgb_shift_out_bits(struct ixgb_hw *hw,
*/
eecd_reg &= ~IXGB_EECD_DI;
- if(data & mask)
+ if (data & mask)
eecd_reg |= IXGB_EECD_DI;
IXGB_WRITE_REG(hw, EECD, eecd_reg);
@@ -120,7 +120,7 @@ ixgb_shift_out_bits(struct ixgb_hw *hw,
mask = mask >> 1;
- } while(mask);
+ } while (mask);
/* We leave the "DI" bit set to "0" when we leave this routine. */
eecd_reg &= ~IXGB_EECD_DI;
@@ -152,14 +152,14 @@ ixgb_shift_in_bits(struct ixgb_hw *hw)
eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
data = 0;
- for(i = 0; i < 16; i++) {
+ for (i = 0; i < 16; i++) {
data = data << 1;
ixgb_raise_clock(hw, &eecd_reg);
eecd_reg = IXGB_READ_REG(hw, EECD);
eecd_reg &= ~(IXGB_EECD_DI);
- if(eecd_reg & IXGB_EECD_DO)
+ if (eecd_reg & IXGB_EECD_DO)
data |= 1;
ixgb_lower_clock(hw, &eecd_reg);
@@ -205,7 +205,7 @@ ixgb_standby_eeprom(struct ixgb_hw *hw)
eecd_reg = IXGB_READ_REG(hw, EECD);
- /* Deselct EEPROM */
+ /* Deselect EEPROM */
eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);
IXGB_WRITE_REG(hw, EECD, eecd_reg);
udelay(50);
@@ -293,14 +293,14 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw)
*/
ixgb_standby_eeprom(hw);
- /* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
+ /* Now read DO repeatedly until is high (equal to '1'). The EEPROM will
* signal that the command has been completed by raising the DO signal.
* If DO does not go high in 10 milliseconds, then error out.
*/
- for(i = 0; i < 200; i++) {
+ for (i = 0; i < 200; i++) {
eecd_reg = IXGB_READ_REG(hw, EECD);
- if(eecd_reg & IXGB_EECD_DO)
+ if (eecd_reg & IXGB_EECD_DO)
return (true);
udelay(50);
@@ -328,10 +328,10 @@ ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
u16 checksum = 0;
u16 i;
- for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
+ for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
checksum += ixgb_read_eeprom(hw, i);
- if(checksum == (u16) EEPROM_SUM)
+ if (checksum == (u16) EEPROM_SUM)
return (true);
else
return (false);
@@ -351,7 +351,7 @@ ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
u16 checksum = 0;
u16 i;
- for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
+ for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
checksum += ixgb_read_eeprom(hw, i);
checksum = (u16) EEPROM_SUM - checksum;
@@ -365,7 +365,7 @@ ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
*
* hw - Struct containing variables accessed by shared code
* reg - offset within the EEPROM to be written to
- * data - 16 bit word to be writen to the EEPROM
+ * data - 16 bit word to be written to the EEPROM
*
* If ixgb_update_eeprom_checksum is not called after this function, the
* EEPROM will most likely contain an invalid checksum.
@@ -472,7 +472,7 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw)
ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
DEBUGOUT("ixgb_ee: Reading eeprom data\n");
- for(i = 0; i < IXGB_EEPROM_SIZE ; i++) {
+ for (i = 0; i < IXGB_EEPROM_SIZE ; i++) {
u16 ee_data;
ee_data = ixgb_read_eeprom(hw, i);
checksum += ee_data;
diff --git a/drivers/net/ixgb/ixgb_ee.h b/drivers/net/ixgb/ixgb_ee.h
index 4b7bd0d4a8a..7ea12652f47 100644
--- a/drivers/net/ixgb/ixgb_ee.h
+++ b/drivers/net/ixgb/ixgb_ee.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -34,11 +34,11 @@
#define IXGB_ETH_LENGTH_OF_ADDRESS 6
/* EEPROM Commands */
-#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */
-#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */
-#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */
-#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */
-#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
+#define EEPROM_READ_OPCODE 0x6 /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE 0x5 /* EEPROM write opcode */
+#define EEPROM_ERASE_OPCODE 0x7 /* EEPROM erase opcode */
+#define EEPROM_EWEN_OPCODE 0x13 /* EEPROM erase/write enable */
+#define EEPROM_EWDS_OPCODE 0x10 /* EEPROM erase/write disable */
/* EEPROM MAP (Word Offsets) */
#define EEPROM_IA_1_2_REG 0x0000
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 8464d8a013b..288ee1d0f43 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -95,7 +95,7 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
ecmd->port = PORT_FIBRE;
ecmd->transceiver = XCVR_EXTERNAL;
- if(netif_carrier_ok(adapter->netdev)) {
+ if (netif_carrier_ok(adapter->netdev)) {
ecmd->speed = SPEED_10000;
ecmd->duplex = DUPLEX_FULL;
} else {
@@ -122,11 +122,11 @@ ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
- if(ecmd->autoneg == AUTONEG_ENABLE ||
+ if (ecmd->autoneg == AUTONEG_ENABLE ||
ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
return -EINVAL;
-
- if(netif_running(adapter->netdev)) {
+
+ if (netif_running(adapter->netdev)) {
ixgb_down(adapter, true);
ixgb_reset(adapter);
ixgb_up(adapter);
@@ -143,14 +143,14 @@ ixgb_get_pauseparam(struct net_device *netdev,
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
-
+
pause->autoneg = AUTONEG_DISABLE;
-
- if(hw->fc.type == ixgb_fc_rx_pause)
+
+ if (hw->fc.type == ixgb_fc_rx_pause)
pause->rx_pause = 1;
- else if(hw->fc.type == ixgb_fc_tx_pause)
+ else if (hw->fc.type == ixgb_fc_tx_pause)
pause->tx_pause = 1;
- else if(hw->fc.type == ixgb_fc_full) {
+ else if (hw->fc.type == ixgb_fc_full) {
pause->rx_pause = 1;
pause->tx_pause = 1;
}
@@ -162,26 +162,26 @@ ixgb_set_pauseparam(struct net_device *netdev,
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
-
- if(pause->autoneg == AUTONEG_ENABLE)
+
+ if (pause->autoneg == AUTONEG_ENABLE)
return -EINVAL;
- if(pause->rx_pause && pause->tx_pause)
+ if (pause->rx_pause && pause->tx_pause)
hw->fc.type = ixgb_fc_full;
- else if(pause->rx_pause && !pause->tx_pause)
+ else if (pause->rx_pause && !pause->tx_pause)
hw->fc.type = ixgb_fc_rx_pause;
- else if(!pause->rx_pause && pause->tx_pause)
+ else if (!pause->rx_pause && pause->tx_pause)
hw->fc.type = ixgb_fc_tx_pause;
- else if(!pause->rx_pause && !pause->tx_pause)
+ else if (!pause->rx_pause && !pause->tx_pause)
hw->fc.type = ixgb_fc_none;
- if(netif_running(adapter->netdev)) {
+ if (netif_running(adapter->netdev)) {
ixgb_down(adapter, true);
ixgb_up(adapter);
ixgb_set_speed_duplex(netdev);
} else
ixgb_reset(adapter);
-
+
return 0;
}
@@ -200,7 +200,7 @@ ixgb_set_rx_csum(struct net_device *netdev, u32 data)
adapter->rx_csum = data;
- if(netif_running(netdev)) {
+ if (netif_running(netdev)) {
ixgb_down(adapter, true);
ixgb_up(adapter);
ixgb_set_speed_duplex(netdev);
@@ -208,7 +208,7 @@ ixgb_set_rx_csum(struct net_device *netdev, u32 data)
ixgb_reset(adapter);
return 0;
}
-
+
static u32
ixgb_get_tx_csum(struct net_device *netdev)
{
@@ -229,12 +229,12 @@ ixgb_set_tx_csum(struct net_device *netdev, u32 data)
static int
ixgb_set_tso(struct net_device *netdev, u32 data)
{
- if(data)
+ if (data)
netdev->features |= NETIF_F_TSO;
else
netdev->features &= ~NETIF_F_TSO;
return 0;
-}
+}
static u32
ixgb_get_msglevel(struct net_device *netdev)
@@ -251,7 +251,7 @@ ixgb_set_msglevel(struct net_device *netdev, u32 data)
}
#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
-static int
+static int
ixgb_get_regs_len(struct net_device *netdev)
{
#define IXGB_REG_DUMP_LEN 136*sizeof(u32)
@@ -301,7 +301,7 @@ ixgb_get_regs(struct net_device *netdev,
*reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */
/* there are 16 RAR entries in hardware, we only use 3 */
- for(i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
+ for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
}
@@ -415,7 +415,7 @@ ixgb_get_eeprom(struct net_device *netdev,
int i, max_len, first_word, last_word;
int ret_val = 0;
- if(eeprom->len == 0) {
+ if (eeprom->len == 0) {
ret_val = -EINVAL;
goto geeprom_error;
}
@@ -424,12 +424,12 @@ ixgb_get_eeprom(struct net_device *netdev,
max_len = ixgb_get_eeprom_len(netdev);
- if(eeprom->offset > eeprom->offset + eeprom->len) {
+ if (eeprom->offset > eeprom->offset + eeprom->len) {
ret_val = -EINVAL;
goto geeprom_error;
}
- if((eeprom->offset + eeprom->len) > max_len)
+ if ((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
first_word = eeprom->offset >> 1;
@@ -437,16 +437,14 @@ ixgb_get_eeprom(struct net_device *netdev,
eeprom_buff = kmalloc(sizeof(__le16) *
(last_word - first_word + 1), GFP_KERNEL);
- if(!eeprom_buff)
+ if (!eeprom_buff)
return -ENOMEM;
/* note the eeprom was good because the driver loaded */
- for(i = 0; i <= (last_word - first_word); i++) {
+ for (i = 0; i <= (last_word - first_word); i++)
eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
- }
- memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1),
- eeprom->len);
+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
kfree(eeprom_buff);
geeprom_error:
@@ -464,47 +462,47 @@ ixgb_set_eeprom(struct net_device *netdev,
int max_len, first_word, last_word;
u16 i;
- if(eeprom->len == 0)
+ if (eeprom->len == 0)
return -EINVAL;
- if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+ if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
max_len = ixgb_get_eeprom_len(netdev);
- if(eeprom->offset > eeprom->offset + eeprom->len)
+ if (eeprom->offset > eeprom->offset + eeprom->len)
return -EINVAL;
- if((eeprom->offset + eeprom->len) > max_len)
+ if ((eeprom->offset + eeprom->len) > max_len)
eeprom->len = (max_len - eeprom->offset);
first_word = eeprom->offset >> 1;
last_word = (eeprom->offset + eeprom->len - 1) >> 1;
eeprom_buff = kmalloc(max_len, GFP_KERNEL);
- if(!eeprom_buff)
+ if (!eeprom_buff)
return -ENOMEM;
ptr = (void *)eeprom_buff;
- if(eeprom->offset & 1) {
+ if (eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
ptr++;
}
- if((eeprom->offset + eeprom->len) & 1) {
+ if ((eeprom->offset + eeprom->len) & 1) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
- eeprom_buff[last_word - first_word]
+ eeprom_buff[last_word - first_word]
= ixgb_read_eeprom(hw, last_word);
}
memcpy(ptr, bytes, eeprom->len);
- for(i = 0; i <= (last_word - first_word); i++)
+ for (i = 0; i <= (last_word - first_word); i++)
ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
/* Update the checksum over the first part of the EEPROM if needed */
- if(first_word <= EEPROM_CHECKSUM_REG)
+ if (first_word <= EEPROM_CHECKSUM_REG)
ixgb_update_eeprom_checksum(hw);
kfree(eeprom_buff);
@@ -534,7 +532,7 @@ ixgb_get_ringparam(struct net_device *netdev,
struct ixgb_desc_ring *txdr = &adapter->tx_ring;
struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
- ring->rx_max_pending = MAX_RXD;
+ ring->rx_max_pending = MAX_RXD;
ring->tx_max_pending = MAX_TXD;
ring->rx_mini_max_pending = 0;
ring->rx_jumbo_max_pending = 0;
@@ -544,7 +542,7 @@ ixgb_get_ringparam(struct net_device *netdev,
ring->rx_jumbo_pending = 0;
}
-static int
+static int
ixgb_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
@@ -557,10 +555,10 @@ ixgb_set_ringparam(struct net_device *netdev,
tx_old = adapter->tx_ring;
rx_old = adapter->rx_ring;
- if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
- if(netif_running(adapter->netdev))
+ if (netif_running(adapter->netdev))
ixgb_down(adapter, true);
rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
@@ -571,11 +569,11 @@ ixgb_set_ringparam(struct net_device *netdev,
txdr->count = min(txdr->count,(u32)MAX_TXD);
txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
- if(netif_running(adapter->netdev)) {
+ if (netif_running(adapter->netdev)) {
/* Try to get new resources before deleting old */
- if((err = ixgb_setup_rx_resources(adapter)))
+ if ((err = ixgb_setup_rx_resources(adapter)))
goto err_setup_rx;
- if((err = ixgb_setup_tx_resources(adapter)))
+ if ((err = ixgb_setup_tx_resources(adapter)))
goto err_setup_tx;
/* save the new, restore the old in order to free it,
@@ -589,7 +587,7 @@ ixgb_set_ringparam(struct net_device *netdev,
ixgb_free_tx_resources(adapter);
adapter->rx_ring = rx_new;
adapter->tx_ring = tx_new;
- if((err = ixgb_up(adapter)))
+ if ((err = ixgb_up(adapter)))
return err;
ixgb_set_speed_duplex(netdev);
}
@@ -615,7 +613,7 @@ ixgb_led_blink_callback(unsigned long data)
{
struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
- if(test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
+ if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
ixgb_led_off(&adapter->hw);
else
ixgb_led_on(&adapter->hw);
@@ -631,7 +629,7 @@ ixgb_phys_id(struct net_device *netdev, u32 data)
if (!data)
data = INT_MAX;
- if(!adapter->blink_timer.function) {
+ if (!adapter->blink_timer.function) {
init_timer(&adapter->blink_timer);
adapter->blink_timer.function = ixgb_led_blink_callback;
adapter->blink_timer.data = (unsigned long)adapter;
@@ -647,7 +645,7 @@ ixgb_phys_id(struct net_device *netdev, u32 data)
return 0;
}
-static int
+static int
ixgb_get_sset_count(struct net_device *netdev, int sset)
{
switch (sset) {
@@ -658,30 +656,30 @@ ixgb_get_sset_count(struct net_device *netdev, int sset)
}
}
-static void
-ixgb_get_ethtool_stats(struct net_device *netdev,
+static void
+ixgb_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
int i;
ixgb_update_stats(adapter);
- for(i = 0; i < IXGB_STATS_LEN; i++) {
- char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;
- data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
+ for (i = 0; i < IXGB_STATS_LEN; i++) {
+ char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;
+ data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
}
-static void
+static void
ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
int i;
switch(stringset) {
case ETH_SS_STATS:
- for(i=0; i < IXGB_STATS_LEN; i++) {
- memcpy(data + i * ETH_GSTRING_LEN,
+ for (i = 0; i < IXGB_STATS_LEN; i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
ixgb_gstrings_stats[i].stat_string,
ETH_GSTRING_LEN);
}
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 04d2003e24e..11dcda0f453 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -125,7 +125,7 @@ ixgb_adapter_stop(struct ixgb_hw *hw)
/* If we are stopped or resetting exit gracefully and wait to be
* started again before accessing the hardware.
*/
- if(hw->adapter_stopped) {
+ if (hw->adapter_stopped) {
DEBUGOUT("Exiting because the adapter is already stopped!!!\n");
return false;
}
@@ -347,7 +347,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
/* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n");
- for(i = 0; i < IXGB_MC_TBL_SIZE; i++)
+ for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
/* Zero out the VLAN Filter Table Array */
@@ -371,7 +371,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
* hw - Struct containing variables accessed by shared code
*
* Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
+ * of the receive address registers. Clears the multicast table. Assumes
* the receiver is in reset when the routine is called.
*****************************************************************************/
static void
@@ -413,7 +413,7 @@ ixgb_init_rx_addrs(struct ixgb_hw *hw)
/* Zero out the other 15 receive addresses. */
DEBUGOUT("Clearing RAR[1-15]\n");
- for(i = 1; i < IXGB_RAR_ENTRIES; i++) {
+ for (i = 1; i < IXGB_RAR_ENTRIES; i++) {
/* Write high reg first to disable the AV bit first */
IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
@@ -452,19 +452,18 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw,
/* Clear RAR[1-15] */
DEBUGOUT(" Clearing RAR[1-15]\n");
- for(i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
+ for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
}
/* Clear the MTA */
DEBUGOUT(" Clearing MTA\n");
- for(i = 0; i < IXGB_MC_TBL_SIZE; i++) {
+ for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
- }
/* Add the new addresses */
- for(i = 0; i < mc_addr_count; i++) {
+ for (i = 0; i < mc_addr_count; i++) {
DEBUGOUT(" Adding the multicast addresses:\n");
DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)],
@@ -482,7 +481,7 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw,
/* Place this multicast address in the RAR if there is room, *
* else put it in the MTA
*/
- if(rar_used_count < IXGB_RAR_ENTRIES) {
+ if (rar_used_count < IXGB_RAR_ENTRIES) {
ixgb_rar_set(hw,
mc_addr_list +
(i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)),
@@ -649,7 +648,7 @@ ixgb_clear_vfta(struct ixgb_hw *hw)
{
u32 offset;
- for(offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
+ for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
return;
}
@@ -719,9 +718,8 @@ ixgb_setup_fc(struct ixgb_hw *hw)
/* Write the new settings */
IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);
- if (pap_reg != 0) {
+ if (pap_reg != 0)
IXGB_WRITE_REG(hw, PAP, pap_reg);
- }
/* Set the flow control receive threshold registers. Normally,
* these registers will be set to a default threshold that may be
@@ -729,14 +727,14 @@ ixgb_setup_fc(struct ixgb_hw *hw)
* ability to transmit pause frames in not enabled, then these
* registers will be set to 0.
*/
- if(!(hw->fc.type & ixgb_fc_tx_pause)) {
+ if (!(hw->fc.type & ixgb_fc_tx_pause)) {
IXGB_WRITE_REG(hw, FCRTL, 0);
IXGB_WRITE_REG(hw, FCRTH, 0);
} else {
/* We need to set up the Receive Threshold high and low water
* marks as well as (optionally) enabling the transmission of XON
* frames. */
- if(hw->fc.send_xon) {
+ if (hw->fc.send_xon) {
IXGB_WRITE_REG(hw, FCRTL,
(hw->fc.low_water | IXGB_FCRTL_XONE));
} else {
@@ -791,7 +789,7 @@ ixgb_read_phy_reg(struct ixgb_hw *hw,
** from the CPU Write to the Ready bit assertion.
**************************************************************/
- for(i = 0; i < 10; i++)
+ for (i = 0; i < 10; i++)
{
udelay(10);
@@ -818,7 +816,7 @@ ixgb_read_phy_reg(struct ixgb_hw *hw,
** from the CPU Write to the Ready bit assertion.
**************************************************************/
- for(i = 0; i < 10; i++)
+ for (i = 0; i < 10; i++)
{
udelay(10);
@@ -887,7 +885,7 @@ ixgb_write_phy_reg(struct ixgb_hw *hw,
** from the CPU Write to the Ready bit assertion.
**************************************************************/
- for(i = 0; i < 10; i++)
+ for (i = 0; i < 10; i++)
{
udelay(10);
@@ -914,7 +912,7 @@ ixgb_write_phy_reg(struct ixgb_hw *hw,
** from the CPU Write to the Ready bit assertion.
**************************************************************/
- for(i = 0; i < 10; i++)
+ for (i = 0; i < 10; i++)
{
udelay(10);
@@ -965,7 +963,7 @@ ixgb_check_for_link(struct ixgb_hw *hw)
}
/******************************************************************************
- * Check for a bad link condition that may have occured.
+ * Check for a bad link condition that may have occurred.
* The indication is that the RFC / LFC registers may be incrementing
* continually. A full adapter reset is required to recover.
*
@@ -1007,7 +1005,7 @@ ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
DEBUGFUNC("ixgb_clear_hw_cntrs");
/* if we are stopped or resetting exit gracefully */
- if(hw->adapter_stopped) {
+ if (hw->adapter_stopped) {
DEBUGOUT("Exiting because the adapter is stopped!!!\n");
return;
}
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 39cfa47bea6..831fe0c58b2 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
index 180d20e793a..2a58847f46e 100644
--- a/drivers/net/ixgb/ixgb_ids.h
+++ b/drivers/net/ixgb/ixgb_ids.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -38,11 +38,11 @@
#define SUN_VENDOR_ID 0x108E
#define SUN_SUBVENDOR_ID 0x108E
-#define IXGB_DEVICE_ID_82597EX 0x1048
-#define IXGB_DEVICE_ID_82597EX_SR 0x1A48
+#define IXGB_DEVICE_ID_82597EX 0x1048
+#define IXGB_DEVICE_ID_82597EX_SR 0x1A48
#define IXGB_DEVICE_ID_82597EX_LR 0x1B48
-#define IXGB_SUBDEVICE_ID_A11F 0xA11F
-#define IXGB_SUBDEVICE_ID_A01F 0xA01F
+#define IXGB_SUBDEVICE_ID_A11F 0xA11F
+#define IXGB_SUBDEVICE_ID_A01F 0xA01F
#define IXGB_DEVICE_ID_82597EX_CX4 0x109E
#define IXGB_SUBDEVICE_ID_A00C 0xA00C
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index cb8daddafa2..aa75385cd6c 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -31,14 +31,16 @@
char ixgb_driver_name[] = "ixgb";
static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
-#ifndef CONFIG_IXGB_NAPI
-#define DRIVERNAPI
-#else
#define DRIVERNAPI "-NAPI"
-#endif
-#define DRV_VERSION "1.0.126-k4"DRIVERNAPI
+#define DRV_VERSION "1.0.135-k2" DRIVERNAPI
const char ixgb_driver_version[] = DRV_VERSION;
-static const char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
+static const char ixgb_copyright[] = "Copyright (c) 1999-2008 Intel Corporation.";
+
+#define IXGB_CB_LENGTH 256
+static unsigned int copybreak __read_mostly = IXGB_CB_LENGTH;
+module_param(copybreak, uint, 0644);
+MODULE_PARM_DESC(copybreak,
+ "Maximum size of packet that is copied to a new buffer on receive");
/* ixgb_pci_tbl - PCI Device ID Table
*
@@ -55,7 +57,7 @@ static struct pci_device_id ixgb_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR,
+ {INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
/* required last entry */
@@ -65,16 +67,6 @@ static struct pci_device_id ixgb_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl);
/* Local Function Prototypes */
-
-int ixgb_up(struct ixgb_adapter *adapter);
-void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog);
-void ixgb_reset(struct ixgb_adapter *adapter);
-int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
-int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
-void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
-void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
-void ixgb_update_stats(struct ixgb_adapter *adapter);
-
static int ixgb_init_module(void);
static void ixgb_exit_module(void);
static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -96,18 +88,15 @@ static int ixgb_set_mac(struct net_device *netdev, void *p);
static irqreturn_t ixgb_intr(int irq, void *data);
static bool ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
-#ifdef CONFIG_IXGB_NAPI
-static int ixgb_clean(struct napi_struct *napi, int budget);
-static bool ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
- int *work_done, int work_to_do);
-#else
-static bool ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
-#endif
-static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
+static int ixgb_clean(struct napi_struct *, int);
+static bool ixgb_clean_rx_irq(struct ixgb_adapter *, int *, int);
+static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int);
+
static void ixgb_tx_timeout(struct net_device *dev);
static void ixgb_tx_timeout_task(struct work_struct *work);
+
static void ixgb_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp);
+ struct vlan_group *grp);
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
@@ -118,7 +107,7 @@ static void ixgb_netpoll(struct net_device *dev);
#endif
static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
- enum pci_channel_state state);
+ enum pci_channel_state state);
static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev);
static void ixgb_io_resume (struct pci_dev *pdev);
@@ -146,14 +135,6 @@ static int debug = DEFAULT_DEBUG_LEVEL_SHIFT;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-/* some defines for controlling descriptor fetches in h/w */
-#define RXDCTL_WTHRESH_DEFAULT 15 /* chip writes back at this many or RXT0 */
-#define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below
- * this */
-#define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail
- * is pushed this many descriptors
- * from head */
-
/**
* ixgb_init_module - Driver Registration Routine
*
@@ -236,7 +217,7 @@ ixgb_up(struct ixgb_adapter *adapter)
ixgb_configure_tx(adapter);
ixgb_setup_rctl(adapter);
ixgb_configure_rx(adapter);
- ixgb_alloc_rx_buffers(adapter);
+ ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring));
/* disable interrupts and get the hardware into a known state */
IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
@@ -261,7 +242,7 @@ ixgb_up(struct ixgb_adapter *adapter)
return err;
}
- if((hw->max_frame_size != max_frame) ||
+ if ((hw->max_frame_size != max_frame) ||
(hw->max_frame_size !=
(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
@@ -269,11 +250,11 @@ ixgb_up(struct ixgb_adapter *adapter)
IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
- if(hw->max_frame_size >
+ if (hw->max_frame_size >
IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
u32 ctrl0 = IXGB_READ_REG(hw, CTRL0);
- if(!(ctrl0 & IXGB_CTRL0_JFE)) {
+ if (!(ctrl0 & IXGB_CTRL0_JFE)) {
ctrl0 |= IXGB_CTRL0_JFE;
IXGB_WRITE_REG(hw, CTRL0, ctrl0);
}
@@ -282,9 +263,7 @@ ixgb_up(struct ixgb_adapter *adapter)
clear_bit(__IXGB_DOWN, &adapter->flags);
-#ifdef CONFIG_IXGB_NAPI
napi_enable(&adapter->napi);
-#endif
ixgb_irq_enable(adapter);
mod_timer(&adapter->watchdog_timer, jiffies);
@@ -300,9 +279,7 @@ ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog)
/* prevent the interrupt handler from restarting watchdog */
set_bit(__IXGB_DOWN, &adapter->flags);
-#ifdef CONFIG_IXGB_NAPI
napi_disable(&adapter->napi);
-#endif
/* waiting for NAPI to complete can re-enable interrupts */
ixgb_irq_disable(adapter);
free_irq(adapter->pdev->irq, netdev);
@@ -310,7 +287,7 @@ ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog)
if (adapter->have_msi)
pci_disable_msi(adapter->pdev);
- if(kill_watchdog)
+ if (kill_watchdog)
del_timer_sync(&adapter->watchdog_timer);
adapter->link_speed = 0;
@@ -357,27 +334,25 @@ ixgb_reset(struct ixgb_adapter *adapter)
**/
static int __devinit
-ixgb_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *netdev = NULL;
struct ixgb_adapter *adapter;
static int cards_found = 0;
- unsigned long mmio_start;
- int mmio_len;
int pci_using_dac;
int i;
int err;
- if((err = pci_enable_device(pdev)))
+ err = pci_enable_device(pdev);
+ if (err)
return err;
- if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
- !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+ if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
+ !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
pci_using_dac = 1;
} else {
- if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
- (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
+ if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
+ (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
printk(KERN_ERR
"ixgb: No usable DMA configuration, aborting\n");
goto err_dma_mask;
@@ -385,13 +360,14 @@ ixgb_probe(struct pci_dev *pdev,
pci_using_dac = 0;
}
- if((err = pci_request_regions(pdev, ixgb_driver_name)))
+ err = pci_request_regions(pdev, ixgb_driver_name);
+ if (err)
goto err_request_regions;
pci_set_master(pdev);
netdev = alloc_etherdev(sizeof(struct ixgb_adapter));
- if(!netdev) {
+ if (!netdev) {
err = -ENOMEM;
goto err_alloc_etherdev;
}
@@ -405,19 +381,17 @@ ixgb_probe(struct pci_dev *pdev,
adapter->hw.back = adapter;
adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT);
- mmio_start = pci_resource_start(pdev, BAR_0);
- mmio_len = pci_resource_len(pdev, BAR_0);
-
- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
- if(!adapter->hw.hw_addr) {
+ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
+ pci_resource_len(pdev, BAR_0));
+ if (!adapter->hw.hw_addr) {
err = -EIO;
goto err_ioremap;
}
- for(i = BAR_1; i <= BAR_5; i++) {
- if(pci_resource_len(pdev, i) == 0)
+ for (i = BAR_1; i <= BAR_5; i++) {
+ if (pci_resource_len(pdev, i) == 0)
continue;
- if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
adapter->hw.io_base = pci_resource_start(pdev, i);
break;
}
@@ -433,9 +407,7 @@ ixgb_probe(struct pci_dev *pdev,
ixgb_set_ethtool_ops(netdev);
netdev->tx_timeout = &ixgb_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
-#ifdef CONFIG_IXGB_NAPI
netif_napi_add(netdev, &adapter->napi, ixgb_clean, 64);
-#endif
netdev->vlan_rx_register = ixgb_vlan_rx_register;
netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid;
netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid;
@@ -444,9 +416,6 @@ ixgb_probe(struct pci_dev *pdev,
#endif
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
- netdev->mem_start = mmio_start;
- netdev->mem_end = mmio_start + mmio_len;
- netdev->base_addr = adapter->hw.io_base;
adapter->bd_number = cards_found;
adapter->link_speed = 0;
@@ -454,7 +423,8 @@ ixgb_probe(struct pci_dev *pdev,
/* setup the private structure */
- if((err = ixgb_sw_init(adapter)))
+ err = ixgb_sw_init(adapter);
+ if (err)
goto err_sw_init;
netdev->features = NETIF_F_SG |
@@ -463,16 +433,13 @@ ixgb_probe(struct pci_dev *pdev,
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
netdev->features |= NETIF_F_TSO;
-#ifdef NETIF_F_LLTX
- netdev->features |= NETIF_F_LLTX;
-#endif
- if(pci_using_dac)
+ if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
/* make sure the EEPROM is good */
- if(!ixgb_validate_eeprom_checksum(&adapter->hw)) {
+ if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
err = -EIO;
goto err_eeprom;
@@ -481,7 +448,7 @@ ixgb_probe(struct pci_dev *pdev,
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->perm_addr)) {
+ if (!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
err = -EIO;
goto err_eeprom;
@@ -496,7 +463,8 @@ ixgb_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task);
strcpy(netdev->name, "eth%d");
- if((err = register_netdev(netdev)))
+ err = register_netdev(netdev);
+ if (err)
goto err_register;
/* we're going to reset, so assume we have no link for now */
@@ -543,6 +511,8 @@ ixgb_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev_priv(netdev);
+ flush_scheduled_work();
+
unregister_netdev(netdev);
iounmap(adapter->hw.hw_addr);
@@ -575,13 +545,13 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
hw->subsystem_id = pdev->subsystem_device;
hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
- adapter->rx_buffer_len = hw->max_frame_size;
+ adapter->rx_buffer_len = hw->max_frame_size + 8; /* + 8 for errata */
- if((hw->device_id == IXGB_DEVICE_ID_82597EX)
+ if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
|| (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4)
|| (hw->device_id == IXGB_DEVICE_ID_82597EX_LR)
|| (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
- hw->mac_type = ixgb_82597;
+ hw->mac_type = ixgb_82597;
else {
/* should never have loaded on this device */
DPRINTK(PROBE, ERR, "unsupported device id\n");
@@ -590,8 +560,6 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
/* enable flow control to be programmed */
hw->fc.send_xon = 1;
- spin_lock_init(&adapter->tx_lock);
-
set_bit(__IXGB_DOWN, &adapter->flags);
return 0;
}
@@ -616,16 +584,18 @@ ixgb_open(struct net_device *netdev)
int err;
/* allocate transmit descriptors */
-
- if((err = ixgb_setup_tx_resources(adapter)))
+ err = ixgb_setup_tx_resources(adapter);
+ if (err)
goto err_setup_tx;
/* allocate receive descriptors */
- if((err = ixgb_setup_rx_resources(adapter)))
+ err = ixgb_setup_rx_resources(adapter);
+ if (err)
goto err_setup_rx;
- if((err = ixgb_up(adapter)))
+ err = ixgb_up(adapter);
+ if (err)
goto err_up;
return 0;
@@ -681,7 +651,7 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
size = sizeof(struct ixgb_buffer) * txdr->count;
txdr->buffer_info = vmalloc(size);
- if(!txdr->buffer_info) {
+ if (!txdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate transmit descriptor ring memory\n");
return -ENOMEM;
@@ -694,7 +664,7 @@ ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
txdr->size = ALIGN(txdr->size, 4096);
txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
- if(!txdr->desc) {
+ if (!txdr->desc) {
vfree(txdr->buffer_info);
DPRINTK(PROBE, ERR,
"Unable to allocate transmit descriptor memory\n");
@@ -723,8 +693,8 @@ ixgb_configure_tx(struct ixgb_adapter *adapter)
u32 tctl;
struct ixgb_hw *hw = &adapter->hw;
- /* Setup the Base and Length of the Tx Descriptor Ring
- * tx_ring.dma can be either a 32 or 64 bit value
+ /* Setup the Base and Length of the Tx Descriptor Ring
+ * tx_ring.dma can be either a 32 or 64 bit value
*/
IXGB_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
@@ -750,8 +720,8 @@ ixgb_configure_tx(struct ixgb_adapter *adapter)
/* Setup Transmit Descriptor Settings for this adapter */
adapter->tx_cmd_type =
- IXGB_TX_DESC_TYPE
- | (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
+ IXGB_TX_DESC_TYPE |
+ (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
}
/**
@@ -770,7 +740,7 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
size = sizeof(struct ixgb_buffer) * rxdr->count;
rxdr->buffer_info = vmalloc(size);
- if(!rxdr->buffer_info) {
+ if (!rxdr->buffer_info) {
DPRINTK(PROBE, ERR,
"Unable to allocate receive descriptor ring\n");
return -ENOMEM;
@@ -784,7 +754,7 @@ ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
- if(!rxdr->desc) {
+ if (!rxdr->desc) {
vfree(rxdr->buffer_info);
DPRINTK(PROBE, ERR,
"Unable to allocate receive descriptors\n");
@@ -813,8 +783,8 @@ ixgb_setup_rctl(struct ixgb_adapter *adapter)
rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
rctl |=
- IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 |
- IXGB_RCTL_RXEN | IXGB_RCTL_CFF |
+ IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 |
+ IXGB_RCTL_RXEN | IXGB_RCTL_CFF |
(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
rctl |= IXGB_RCTL_SECRC;
@@ -846,7 +816,6 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
struct ixgb_hw *hw = &adapter->hw;
u32 rctl;
u32 rxcsum;
- u32 rxdctl;
/* make sure receives are disabled while setting up the descriptors */
@@ -868,18 +837,12 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
IXGB_WRITE_REG(hw, RDH, 0);
IXGB_WRITE_REG(hw, RDT, 0);
- /* set up pre-fetching of receive buffers so we get some before we
- * run out (default hardware behavior is to run out before fetching
- * more). This sets up to fetch if HTHRESH rx descriptors are avail
- * and the descriptors in hw cache are below PTHRESH. This avoids
- * the hardware behavior of fetching <=512 descriptors in a single
- * burst that pre-empts all other activity, usually causing fifo
- * overflows. */
- /* use WTHRESH to burst write 16 descriptors or burst when RXT0 */
- rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT |
- RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT |
- RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
- IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
+ /* due to the hardware errata with RXDCTL, we are unable to use any of
+ * the performance enhancing features of it without causing other
+ * subtle bugs, some of the bugs could include receive length
+ * corruption at high data rates (WTHRESH > 0) and/or receive
+ * descriptor ring irregularites (particularly in hardware cache) */
+ IXGB_WRITE_REG(hw, RXDCTL, 0);
/* Enable Receive Checksum Offload for TCP and UDP */
if (adapter->rx_csum) {
@@ -918,7 +881,7 @@ ixgb_free_tx_resources(struct ixgb_adapter *adapter)
static void
ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
- struct ixgb_buffer *buffer_info)
+ struct ixgb_buffer *buffer_info)
{
struct pci_dev *pdev = adapter->pdev;
@@ -926,8 +889,10 @@ ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
PCI_DMA_TODEVICE);
+ /* okay to call kfree_skb here instead of kfree_skb_any because
+ * this is never called in interrupt context */
if (buffer_info->skb)
- dev_kfree_skb_any(buffer_info->skb);
+ dev_kfree_skb(buffer_info->skb);
buffer_info->skb = NULL;
buffer_info->dma = 0;
@@ -952,7 +917,7 @@ ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
/* Free all the Tx ring sk_buffs */
- for(i = 0; i < tx_ring->count; i++) {
+ for (i = 0; i < tx_ring->count; i++) {
buffer_info = &tx_ring->buffer_info[i];
ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
}
@@ -1010,9 +975,9 @@ ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
/* Free all the Rx ring sk_buffs */
- for(i = 0; i < rx_ring->count; i++) {
+ for (i = 0; i < rx_ring->count; i++) {
buffer_info = &rx_ring->buffer_info[i];
- if(buffer_info->skb) {
+ if (buffer_info->skb) {
pci_unmap_single(pdev,
buffer_info->dma,
@@ -1053,7 +1018,7 @@ ixgb_set_mac(struct net_device *netdev, void *p)
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct sockaddr *addr = p;
- if(!is_valid_ether_addr(addr->sa_data))
+ if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
@@ -1086,16 +1051,20 @@ ixgb_set_multi(struct net_device *netdev)
rctl = IXGB_READ_REG(hw, RCTL);
- if(netdev->flags & IFF_PROMISC) {
+ if (netdev->flags & IFF_PROMISC) {
rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
- } else if(netdev->flags & IFF_ALLMULTI) {
- rctl |= IXGB_RCTL_MPE;
- rctl &= ~IXGB_RCTL_UPE;
+ rctl &= ~IXGB_RCTL_VFE;
} else {
- rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE);
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= IXGB_RCTL_MPE;
+ rctl &= ~IXGB_RCTL_UPE;
+ } else {
+ rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE);
+ }
+ rctl |= IXGB_RCTL_VFE;
}
- if(netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
+ if (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
rctl |= IXGB_RCTL_MPE;
IXGB_WRITE_REG(hw, RCTL, rctl);
} else {
@@ -1104,10 +1073,11 @@ ixgb_set_multi(struct net_device *netdev)
IXGB_WRITE_REG(hw, RCTL, rctl);
- for(i = 0, mc_ptr = netdev->mc_list; mc_ptr;
- i++, mc_ptr = mc_ptr->next)
+ for (i = 0, mc_ptr = netdev->mc_list;
+ mc_ptr;
+ i++, mc_ptr = mc_ptr->next)
memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS],
- mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
+ mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
ixgb_mc_addr_list_update(hw, mta, netdev->mc_count, 0);
}
@@ -1132,8 +1102,8 @@ ixgb_watchdog(unsigned long data)
netif_stop_queue(netdev);
}
- if(adapter->hw.link_up) {
- if(!netif_carrier_ok(netdev)) {
+ if (adapter->hw.link_up) {
+ if (!netif_carrier_ok(netdev)) {
DPRINTK(LINK, INFO,
"NIC Link is Up 10000 Mbps Full Duplex\n");
adapter->link_speed = 10000;
@@ -1142,7 +1112,7 @@ ixgb_watchdog(unsigned long data)
netif_wake_queue(netdev);
}
} else {
- if(netif_carrier_ok(netdev)) {
+ if (netif_carrier_ok(netdev)) {
adapter->link_speed = 0;
adapter->link_duplex = 0;
DPRINTK(LINK, INFO, "NIC Link is Down\n");
@@ -1154,8 +1124,8 @@ ixgb_watchdog(unsigned long data)
ixgb_update_stats(adapter);
- if(!netif_carrier_ok(netdev)) {
- if(IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
+ if (!netif_carrier_ok(netdev)) {
+ if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
@@ -1227,7 +1197,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
context_desc->hdr_len = hdr_len;
context_desc->status = 0;
context_desc->cmd_type_len = cpu_to_le32(
- IXGB_CONTEXT_DESC_TYPE
+ IXGB_CONTEXT_DESC_TYPE
| IXGB_CONTEXT_DESC_CMD_TSE
| IXGB_CONTEXT_DESC_CMD_IP
| IXGB_CONTEXT_DESC_CMD_TCP
@@ -1235,7 +1205,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
| (skb->len - (hdr_len)));
- if(++i == adapter->tx_ring.count) i = 0;
+ if (++i == adapter->tx_ring.count) i = 0;
adapter->tx_ring.next_to_use = i;
return 1;
@@ -1251,7 +1221,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
unsigned int i;
u8 css, cso;
- if(likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
struct ixgb_buffer *buffer_info;
css = skb_transport_offset(skb);
cso = css + skb->csum_offset;
@@ -1273,7 +1243,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
| IXGB_TX_DESC_CMD_IDE);
- if(++i == adapter->tx_ring.count) i = 0;
+ if (++i == adapter->tx_ring.count) i = 0;
adapter->tx_ring.next_to_use = i;
return true;
@@ -1302,7 +1272,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
i = tx_ring->next_to_use;
- while(len) {
+ while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
/* Workaround for premature desc write-backs
@@ -1312,28 +1282,28 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
buffer_info->length = size;
WARN_ON(buffer_info->dma != 0);
+ buffer_info->time_stamp = jiffies;
buffer_info->dma =
pci_map_single(adapter->pdev,
skb->data + offset,
size,
PCI_DMA_TODEVICE);
- buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = 0;
len -= size;
offset += size;
count++;
- if(++i == tx_ring->count) i = 0;
+ if (++i == tx_ring->count) i = 0;
}
- for(f = 0; f < nr_frags; f++) {
+ for (f = 0; f < nr_frags; f++) {
struct skb_frag_struct *frag;
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
offset = 0;
- while(len) {
+ while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1344,19 +1314,19 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
size -= 4;
buffer_info->length = size;
+ buffer_info->time_stamp = jiffies;
buffer_info->dma =
pci_map_page(adapter->pdev,
frag->page,
frag->page_offset + offset,
size,
PCI_DMA_TODEVICE);
- buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = 0;
len -= size;
offset += size;
count++;
- if(++i == tx_ring->count) i = 0;
+ if (++i == tx_ring->count) i = 0;
}
}
i = (i == 0) ? tx_ring->count - 1 : i - 1;
@@ -1377,21 +1347,20 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
u8 popts = 0;
unsigned int i;
- if(tx_flags & IXGB_TX_FLAGS_TSO) {
+ if (tx_flags & IXGB_TX_FLAGS_TSO) {
cmd_type_len |= IXGB_TX_DESC_CMD_TSE;
popts |= (IXGB_TX_DESC_POPTS_IXSM | IXGB_TX_DESC_POPTS_TXSM);
}
- if(tx_flags & IXGB_TX_FLAGS_CSUM)
+ if (tx_flags & IXGB_TX_FLAGS_CSUM)
popts |= IXGB_TX_DESC_POPTS_TXSM;
- if(tx_flags & IXGB_TX_FLAGS_VLAN) {
+ if (tx_flags & IXGB_TX_FLAGS_VLAN)
cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
- }
i = tx_ring->next_to_use;
- while(count--) {
+ while (count--) {
buffer_info = &tx_ring->buffer_info[i];
tx_desc = IXGB_TX_DESC(*tx_ring, i);
tx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
@@ -1401,11 +1370,11 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
tx_desc->popts = popts;
tx_desc->vlan = cpu_to_le16(vlan_id);
- if(++i == tx_ring->count) i = 0;
+ if (++i == tx_ring->count) i = 0;
}
- tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP
- | IXGB_TX_DESC_CMD_RS );
+ tx_desc->cmd_type_len |=
+ cpu_to_le32(IXGB_TX_DESC_CMD_EOP | IXGB_TX_DESC_CMD_RS);
/* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only
@@ -1461,7 +1430,6 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct ixgb_adapter *adapter = netdev_priv(netdev);
unsigned int first;
unsigned int tx_flags = 0;
- unsigned long flags;
int vlan_id = 0;
int tso;
@@ -1470,51 +1438,31 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
- if(skb->len <= 0) {
- dev_kfree_skb_any(skb);
+ if (skb->len <= 0) {
+ dev_kfree_skb(skb);
return 0;
}
-#ifdef NETIF_F_LLTX
- if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
- /* Collision - tell upper layer to requeue */
- local_irq_restore(flags);
- return NETDEV_TX_LOCKED;
- }
-#else
- spin_lock_irqsave(&adapter->tx_lock, flags);
-#endif
-
if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring,
- DESC_NEEDED))) {
- netif_stop_queue(netdev);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ DESC_NEEDED)))
return NETDEV_TX_BUSY;
- }
-
-#ifndef NETIF_F_LLTX
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
-#endif
- if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IXGB_TX_FLAGS_VLAN;
vlan_id = vlan_tx_tag_get(skb);
}
first = adapter->tx_ring.next_to_use;
-
+
tso = ixgb_tso(adapter, skb);
if (tso < 0) {
- dev_kfree_skb_any(skb);
-#ifdef NETIF_F_LLTX
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
-#endif
+ dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
if (likely(tso))
tx_flags |= IXGB_TX_FLAGS_TSO;
- else if(ixgb_tx_csum(adapter, skb))
+ else if (ixgb_tx_csum(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_CSUM;
ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
@@ -1522,13 +1470,9 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
netdev->trans_start = jiffies;
-#ifdef NETIF_F_LLTX
/* Make sure there is space in the ring for the next send. */
ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
- spin_unlock_irqrestore(&adapter->tx_lock, flags);
-
-#endif
return NETDEV_TX_OK;
}
@@ -1588,21 +1532,25 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu)
int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
-
- if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
- || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
+ /* MTU < 68 is an error for IPv4 traffic, just don't allow it */
+ if ((new_mtu < 68) ||
+ (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
DPRINTK(PROBE, ERR, "Invalid MTU setting %d\n", new_mtu);
return -EINVAL;
}
- adapter->rx_buffer_len = max_frame;
+ if (old_max_frame == max_frame)
+ return 0;
+
+ if (netif_running(netdev))
+ ixgb_down(adapter, true);
+
+ adapter->rx_buffer_len = max_frame + 8; /* + 8 for errata */
netdev->mtu = new_mtu;
- if ((old_max_frame != max_frame) && netif_running(netdev)) {
- ixgb_down(adapter, true);
+ if (netif_running(netdev))
ixgb_up(adapter);
- }
return 0;
}
@@ -1622,21 +1570,21 @@ ixgb_update_stats(struct ixgb_adapter *adapter)
if (pci_channel_offline(pdev))
return;
- if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) ||
+ if ((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) ||
(netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) {
u64 multi = IXGB_READ_REG(&adapter->hw, MPRCL);
u32 bcast_l = IXGB_READ_REG(&adapter->hw, BPRCL);
u32 bcast_h = IXGB_READ_REG(&adapter->hw, BPRCH);
- u64 bcast = ((u64)bcast_h << 32) | bcast_l;
+ u64 bcast = ((u64)bcast_h << 32) | bcast_l;
multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32);
/* fix up multicast stats by removing broadcasts */
- if(multi >= bcast)
+ if (multi >= bcast)
multi -= bcast;
-
+
adapter->stats.mprcl += (multi & 0xFFFFFFFF);
adapter->stats.mprch += (multi >> 32);
- adapter->stats.bprcl += bcast_l;
+ adapter->stats.bprcl += bcast_l;
adapter->stats.bprch += bcast_h;
} else {
adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL);
@@ -1751,41 +1699,26 @@ ixgb_intr(int irq, void *data)
struct ixgb_adapter *adapter = netdev_priv(netdev);
struct ixgb_hw *hw = &adapter->hw;
u32 icr = IXGB_READ_REG(hw, ICR);
-#ifndef CONFIG_IXGB_NAPI
- unsigned int i;
-#endif
- if(unlikely(!icr))
+ if (unlikely(!icr))
return IRQ_NONE; /* Not our interrupt */
if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)))
if (!test_bit(__IXGB_DOWN, &adapter->flags))
mod_timer(&adapter->watchdog_timer, jiffies);
-#ifdef CONFIG_IXGB_NAPI
if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
- /* Disable interrupts and register for poll. The flush
+ /* Disable interrupts and register for poll. The flush
of the posted write is intentionally left out.
*/
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
__netif_rx_schedule(netdev, &adapter->napi);
}
-#else
- /* yes, that is actually a & and it is meant to make sure that
- * every pass through this for loop checks both receive and
- * transmit queues for completed descriptors, intended to
- * avoid starvation issues and assist tx/rx fairness. */
- for(i = 0; i < IXGB_MAX_INTR; i++)
- if(!ixgb_clean_rx_irq(adapter) &
- !ixgb_clean_tx_irq(adapter))
- break;
-#endif
return IRQ_HANDLED;
}
-#ifdef CONFIG_IXGB_NAPI
/**
* ixgb_clean - NAPI Rx polling callback
* @adapter: board private structure
@@ -1804,12 +1737,12 @@ ixgb_clean(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
netif_rx_complete(netdev, napi);
- ixgb_irq_enable(adapter);
+ if (!test_bit(__IXGB_DOWN, &adapter->flags))
+ ixgb_irq_enable(adapter);
}
return work_done;
}
-#endif
/**
* ixgb_clean_tx_irq - Reclaim resources after transmit completes
@@ -1830,15 +1763,15 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = IXGB_TX_DESC(*tx_ring, eop);
- while(eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
+ while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
for (cleaned = false; !cleaned; ) {
tx_desc = IXGB_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
- if (tx_desc->popts
- & (IXGB_TX_DESC_POPTS_TXSM |
- IXGB_TX_DESC_POPTS_IXSM))
+ if (tx_desc->popts &
+ (IXGB_TX_DESC_POPTS_TXSM |
+ IXGB_TX_DESC_POPTS_IXSM))
adapter->hw_csum_tx_good++;
ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1846,7 +1779,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
*(u32 *)&(tx_desc->status) = 0;
cleaned = (i == eop);
- if(++i == tx_ring->count) i = 0;
+ if (++i == tx_ring->count) i = 0;
}
eop = tx_ring->buffer_info[i].next_to_watch;
@@ -1855,15 +1788,20 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
tx_ring->next_to_clean = i;
- if (unlikely(netif_queue_stopped(netdev))) {
- spin_lock(&adapter->tx_lock);
- if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
- (IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED))
+ if (unlikely(cleaned && netif_carrier_ok(netdev) &&
+ IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED)) {
+ /* Make sure that anybody stopping the queue after this
+ * sees the new next_to_clean. */
+ smp_mb();
+
+ if (netif_queue_stopped(netdev) &&
+ !(test_bit(__IXGB_DOWN, &adapter->flags))) {
netif_wake_queue(netdev);
- spin_unlock(&adapter->tx_lock);
+ ++adapter->restart_queue;
+ }
}
- if(adapter->detect_tx_hung) {
+ if (adapter->detect_tx_hung) {
/* detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = false;
@@ -1906,13 +1844,13 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
static void
ixgb_rx_checksum(struct ixgb_adapter *adapter,
- struct ixgb_rx_desc *rx_desc,
- struct sk_buff *skb)
+ struct ixgb_rx_desc *rx_desc,
+ struct sk_buff *skb)
{
/* Ignore Checksum bit is set OR
* TCP Checksum has not been calculated
*/
- if((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
+ if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
(!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
skb->ip_summed = CHECKSUM_NONE;
return;
@@ -1920,7 +1858,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
/* At this point we know the hardware did the TCP checksum */
/* now look at the TCP checksum error bit */
- if(rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
+ if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
/* let the stack verify checksum errors */
skb->ip_summed = CHECKSUM_NONE;
adapter->hw_csum_rx_error++;
@@ -1937,11 +1875,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
**/
static bool
-#ifdef CONFIG_IXGB_NAPI
ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
-#else
-ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
-#endif
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
@@ -1950,50 +1884,50 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
u32 length;
unsigned int i, j;
+ int cleaned_count = 0;
bool cleaned = false;
i = rx_ring->next_to_clean;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
buffer_info = &rx_ring->buffer_info[i];
- while(rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
- struct sk_buff *skb, *next_skb;
+ while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
+ struct sk_buff *skb;
u8 status;
-#ifdef CONFIG_IXGB_NAPI
- if(*work_done >= work_to_do)
+ if (*work_done >= work_to_do)
break;
(*work_done)++;
-#endif
status = rx_desc->status;
skb = buffer_info->skb;
buffer_info->skb = NULL;
- prefetch(skb->data);
+ prefetch(skb->data - NET_IP_ALIGN);
- if(++i == rx_ring->count) i = 0;
+ if (++i == rx_ring->count) i = 0;
next_rxd = IXGB_RX_DESC(*rx_ring, i);
prefetch(next_rxd);
- if((j = i + 1) == rx_ring->count) j = 0;
+ if ((j = i + 1) == rx_ring->count) j = 0;
next2_buffer = &rx_ring->buffer_info[j];
prefetch(next2_buffer);
next_buffer = &rx_ring->buffer_info[i];
- next_skb = next_buffer->skb;
- prefetch(next_skb);
cleaned = true;
+ cleaned_count++;
pci_unmap_single(pdev,
buffer_info->dma,
buffer_info->length,
PCI_DMA_FROMDEVICE);
+ buffer_info->dma = 0;
length = le16_to_cpu(rx_desc->length);
+ rx_desc->length = 0;
- if(unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) {
+ if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) {
/* All receives must fit into a single buffer */
@@ -2004,11 +1938,9 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
goto rxdesc_done;
}
- if (unlikely(rx_desc->errors
- & (IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE
- | IXGB_RX_DESC_ERRORS_P |
- IXGB_RX_DESC_ERRORS_RXE))) {
-
+ if (unlikely(rx_desc->errors &
+ (IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE |
+ IXGB_RX_DESC_ERRORS_P | IXGB_RX_DESC_ERRORS_RXE))) {
dev_kfree_skb_irq(skb);
goto rxdesc_done;
}
@@ -2016,8 +1948,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
/* code added for copybreak, this should improve
* performance for small packets with large amounts
* of reassembly being done in the stack */
-#define IXGB_CB_LENGTH 256
- if (length < IXGB_CB_LENGTH) {
+ if (length < copybreak) {
struct sk_buff *new_skb =
netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
if (new_skb) {
@@ -2042,29 +1973,24 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
ixgb_rx_checksum(adapter, rx_desc, skb);
skb->protocol = eth_type_trans(skb, netdev);
-#ifdef CONFIG_IXGB_NAPI
- if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
+ if (adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->special) &
- IXGB_RX_DESC_SPECIAL_VLAN_MASK);
+ le16_to_cpu(rx_desc->special));
} else {
netif_receive_skb(skb);
}
-#else /* CONFIG_IXGB_NAPI */
- if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
- vlan_hwaccel_rx(skb, adapter->vlgrp,
- le16_to_cpu(rx_desc->special) &
- IXGB_RX_DESC_SPECIAL_VLAN_MASK);
- } else {
- netif_rx(skb);
- }
-#endif /* CONFIG_IXGB_NAPI */
netdev->last_rx = jiffies;
rxdesc_done:
/* clean up descriptor, might be written over by hw */
rx_desc->status = 0;
+ /* return some buffers to hardware, one at a time is too slow */
+ if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) {
+ ixgb_alloc_rx_buffers(adapter, cleaned_count);
+ cleaned_count = 0;
+ }
+
/* use prefetched values */
rx_desc = next_rxd;
buffer_info = next_buffer;
@@ -2072,7 +1998,9 @@ rxdesc_done:
rx_ring->next_to_clean = i;
- ixgb_alloc_rx_buffers(adapter);
+ cleaned_count = IXGB_DESC_UNUSED(rx_ring);
+ if (cleaned_count)
+ ixgb_alloc_rx_buffers(adapter, cleaned_count);
return cleaned;
}
@@ -2083,7 +2011,7 @@ rxdesc_done:
**/
static void
-ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
+ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count)
{
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
struct net_device *netdev = adapter->netdev;
@@ -2100,7 +2028,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
/* leave three descriptors unused */
- while(--cleancount > 2) {
+ while (--cleancount > 2 && cleaned_count--) {
/* recycle! its good for you */
skb = buffer_info->skb;
if (skb) {
@@ -2133,12 +2061,12 @@ map_skb:
rx_desc = IXGB_RX_DESC(*rx_ring, i);
rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
/* guarantee DD bit not set now before h/w gets descriptor
- * this is the rest of the workaround for h/w double
+ * this is the rest of the workaround for h/w double
* writeback. */
rx_desc->status = 0;
- if(++i == rx_ring->count) i = 0;
+ if (++i == rx_ring->count) i = 0;
buffer_info = &rx_ring->buffer_info[i];
}
@@ -2158,7 +2086,7 @@ map_skb:
/**
* ixgb_vlan_rx_register - enables or disables vlan tagging/stripping.
- *
+ *
* @param netdev network interface device structure
* @param grp indicates to enable or disable tagging/stripping
**/
@@ -2171,7 +2099,7 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
ixgb_irq_disable(adapter);
adapter->vlgrp = grp;
- if(grp) {
+ if (grp) {
/* enable VLAN tag insert/strip */
ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
ctrl |= IXGB_CTRL0_VME;
@@ -2180,7 +2108,6 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
/* enable VLAN receive filtering */
rctl = IXGB_READ_REG(&adapter->hw, RCTL);
- rctl |= IXGB_RCTL_VFE;
rctl &= ~IXGB_RCTL_CFIEN;
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
} else {
@@ -2189,12 +2116,6 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
ctrl &= ~IXGB_CTRL0_VME;
IXGB_WRITE_REG(&adapter->hw, CTRL0, ctrl);
-
- /* disable VLAN filtering */
-
- rctl = IXGB_READ_REG(&adapter->hw, RCTL);
- rctl &= ~IXGB_RCTL_VFE;
- IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
}
/* don't enable interrupts unless we are UP */
@@ -2243,10 +2164,10 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
{
ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
- if(adapter->vlgrp) {
+ if (adapter->vlgrp) {
u16 vid;
- for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
- if(!vlan_group_get_device(adapter->vlgrp, vid))
+ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
ixgb_vlan_rx_add_vid(adapter->netdev, vid);
}
@@ -2278,13 +2199,13 @@ static void ixgb_netpoll(struct net_device *dev)
* This callback is called by the PCI subsystem whenever
* a PCI bus error is detected.
*/
-static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
- enum pci_channel_state state)
+static pci_ers_result_t ixgb_io_error_detected(struct pci_dev *pdev,
+ enum pci_channel_state state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev_priv(netdev);
- if(netif_running(netdev))
+ if (netif_running(netdev))
ixgb_down(adapter, true);
pci_disable_device(pdev);
@@ -2297,17 +2218,17 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
* ixgb_io_slot_reset - called after the pci bus has been reset.
* @pdev pointer to pci device with error
*
- * This callback is called after the PCI buss has been reset.
+ * This callback is called after the PCI bus has been reset.
* Basically, this tries to restart the card from scratch.
* This is a shortened version of the device probe/discovery code,
* it resembles the first-half of the ixgb_probe() routine.
*/
-static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
+static pci_ers_result_t ixgb_io_slot_reset(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev_priv(netdev);
- if(pci_enable_device(pdev)) {
+ if (pci_enable_device(pdev)) {
DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
@@ -2323,14 +2244,14 @@ static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
ixgb_reset(adapter);
/* Make sure the EEPROM is good */
- if(!ixgb_validate_eeprom_checksum(&adapter->hw)) {
+ if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
DPRINTK(PROBE, ERR, "After reset, the EEPROM checksum is not valid.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
- if(!is_valid_ether_addr(netdev->perm_addr)) {
+ if (!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "After reset, invalid MAC address.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
@@ -2346,15 +2267,15 @@ static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
* normal operation. Implementation resembles the second-half
* of the ixgb_probe() routine.
*/
-static void ixgb_io_resume (struct pci_dev *pdev)
+static void ixgb_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgb_adapter *adapter = netdev_priv(netdev);
pci_set_master(pdev);
- if(netif_running(netdev)) {
- if(ixgb_up(adapter)) {
+ if (netif_running(netdev)) {
+ if (ixgb_up(adapter)) {
printk ("ixgb: can't bring device back up after reset\n");
return;
}
diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
index 4be1b273e1b..d92e72bd627 100644
--- a/drivers/net/ixgb/ixgb_osdep.h
+++ b/drivers/net/ixgb/ixgb_osdep.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -40,7 +40,7 @@
#include <linux/sched.h>
#undef ASSERT
-#define ASSERT(x) if(!(x)) BUG()
+#define ASSERT(x) if (!(x)) BUG()
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
#ifdef DBG
diff --git a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
index 865d14d6e5a..af35e1ddadd 100644
--- a/drivers/net/ixgb/ixgb_param.c
+++ b/drivers/net/ixgb/ixgb_param.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel PRO/10GbE Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
+ Copyright(c) 1999 - 2008 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -136,7 +136,7 @@ IXGB_PARAM(RxFCLowThresh, "Receive Flow Control Low Threshold");
/* Flow control request timeout (how long to pause the link partner's tx)
* (PAP 15:0)
*
- * Valid Range: 1 - 65535
+ * Valid Range: 1 - 65535
*
* Default Value: 65535 (0xffff) (we'll send an xon if we recover)
*/
@@ -200,7 +200,7 @@ struct ixgb_option {
static int __devinit
ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt)
{
- if(*value == OPTION_UNSET) {
+ if (*value == OPTION_UNSET) {
*value = opt->def;
return 0;
}
@@ -217,7 +217,7 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt)
}
break;
case range_option:
- if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
printk(KERN_INFO "%s set to %i\n", opt->name, *value);
return 0;
}
@@ -226,10 +226,10 @@ ixgb_validate_option(unsigned int *value, const struct ixgb_option *opt)
int i;
struct ixgb_opt_list *ent;
- for(i = 0; i < opt->arg.l.nr; i++) {
+ for (i = 0; i < opt->arg.l.nr; i++) {
ent = &opt->arg.l.p[i];
- if(*value == ent->i) {
- if(ent->str[0] != '\0')
+ if (*value == ent->i) {
+ if (ent->str[0] != '\0')
printk(KERN_INFO "%s\n", ent->str);
return 0;
}
@@ -260,7 +260,7 @@ void __devinit
ixgb_check_options(struct ixgb_adapter *adapter)
{
int bd = adapter->bd_number;
- if(bd >= IXGB_MAX_NIC) {
+ if (bd >= IXGB_MAX_NIC) {
printk(KERN_NOTICE
"Warning: no configuration for board #%i\n", bd);
printk(KERN_NOTICE "Using defaults for all values\n");
@@ -277,7 +277,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
};
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
- if(num_TxDescriptors > bd) {
+ if (num_TxDescriptors > bd) {
tx_ring->count = TxDescriptors[bd];
ixgb_validate_option(&tx_ring->count, &opt);
} else {
@@ -296,7 +296,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
};
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
- if(num_RxDescriptors > bd) {
+ if (num_RxDescriptors > bd) {
rx_ring->count = RxDescriptors[bd];
ixgb_validate_option(&rx_ring->count, &opt);
} else {
@@ -312,7 +312,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.def = OPTION_ENABLED
};
- if(num_XsumRX > bd) {
+ if (num_XsumRX > bd) {
unsigned int rx_csum = XsumRX[bd];
ixgb_validate_option(&rx_csum, &opt);
adapter->rx_csum = rx_csum;
@@ -338,7 +338,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.p = fc_list }}
};
- if(num_FlowControl > bd) {
+ if (num_FlowControl > bd) {
unsigned int fc = FlowControl[bd];
ixgb_validate_option(&fc, &opt);
adapter->hw.fc.type = fc;
@@ -356,14 +356,14 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.max = MAX_FCRTH}}
};
- if(num_RxFCHighThresh > bd) {
+ if (num_RxFCHighThresh > bd) {
adapter->hw.fc.high_water = RxFCHighThresh[bd];
ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
} else {
adapter->hw.fc.high_water = opt.def;
}
if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
- printk (KERN_INFO
+ printk(KERN_INFO
"Ignoring RxFCHighThresh when no RxFC\n");
}
{ /* Receive Flow Control Low Threshold */
@@ -376,14 +376,14 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.max = MAX_FCRTL}}
};
- if(num_RxFCLowThresh > bd) {
+ if (num_RxFCLowThresh > bd) {
adapter->hw.fc.low_water = RxFCLowThresh[bd];
ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
} else {
adapter->hw.fc.low_water = opt.def;
}
if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
- printk (KERN_INFO
+ printk(KERN_INFO
"Ignoring RxFCLowThresh when no RxFC\n");
}
{ /* Flow Control Pause Time Request*/
@@ -396,7 +396,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.max = MAX_FCPAUSE}}
};
- if(num_FCReqTimeout > bd) {
+ if (num_FCReqTimeout > bd) {
unsigned int pause_time = FCReqTimeout[bd];
ixgb_validate_option(&pause_time, &opt);
adapter->hw.fc.pause_time = pause_time;
@@ -404,7 +404,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
adapter->hw.fc.pause_time = opt.def;
}
if (!(adapter->hw.fc.type & ixgb_fc_tx_pause) )
- printk (KERN_INFO
+ printk(KERN_INFO
"Ignoring FCReqTimeout when no RxFC\n");
}
/* high low and spacing check for rx flow control thresholds */
@@ -412,7 +412,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
/* high must be greater than low */
if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
/* set defaults */
- printk (KERN_INFO
+ printk(KERN_INFO
"RxFCHighThresh must be >= (RxFCLowThresh + 8), "
"Using Defaults\n");
adapter->hw.fc.high_water = DEFAULT_FCRTH;
@@ -429,7 +429,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.max = MAX_RDTR}}
};
- if(num_RxIntDelay > bd) {
+ if (num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
ixgb_validate_option(&adapter->rx_int_delay, &opt);
} else {
@@ -446,7 +446,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.max = MAX_TIDV}}
};
- if(num_TxIntDelay > bd) {
+ if (num_TxIntDelay > bd) {
adapter->tx_int_delay = TxIntDelay[bd];
ixgb_validate_option(&adapter->tx_int_delay, &opt);
} else {
@@ -462,7 +462,7 @@ ixgb_check_options(struct ixgb_adapter *adapter)
.def = OPTION_ENABLED
};
- if(num_IntDelayEnable > bd) {
+ if (num_IntDelayEnable > bd) {
unsigned int ide = IntDelayEnable[bd];
ixgb_validate_option(&ide, &opt);
adapter->tx_int_delay_enable = ide;
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index d98113472a8..956914a5028 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -32,6 +32,7 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
+#include <linux/inet_lro.h>
#include "ixgbe_type.h"
#include "ixgbe_common.h"
@@ -100,6 +101,9 @@
#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
+#define IXGBE_MAX_LRO_DESCRIPTORS 8
+#define IXGBE_MAX_LRO_AGGREGATE 32
+
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer {
@@ -150,6 +154,8 @@ struct ixgbe_ring {
/* cpu for tx queue */
int cpu;
#endif
+ struct net_lro_mgr lro_mgr;
+ bool lro_used;
struct ixgbe_queue_stats stats;
u8 v_idx; /* maps directly to the index for this ring in the hardware
* vector array, can also be used for finding the bit in EICR
@@ -287,6 +293,9 @@ struct ixgbe_adapter {
unsigned long state;
u64 tx_busy;
+ u64 lro_aggregated;
+ u64 lro_flushed;
+ u64 lro_no_desc;
};
enum ixbge_state_t {
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 4e463778bcf..3efe5dda10a 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -90,6 +90,8 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_header_split", IXGBE_STAT(rx_hdr_split)},
{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
+ {"lro_aggregated", IXGBE_STAT(lro_aggregated)},
+ {"lro_flushed", IXGBE_STAT(lro_flushed)},
};
#define IXGBE_QUEUE_STATS_LEN \
@@ -250,22 +252,10 @@ static int ixgbe_set_tso(struct net_device *netdev, u32 data)
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
} else {
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
- int i;
-#endif
- netif_stop_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_stop_subqueue(netdev, i);
-#endif
+ netif_tx_stop_all_queues(netdev);
netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_start_subqueue(netdev, i);
-#endif
- netif_start_queue(netdev);
+ netif_tx_start_all_queues(netdev);
}
return 0;
}
@@ -787,6 +777,7 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
int j, k;
int i;
+ u64 aggregated = 0, flushed = 0, no_desc = 0;
ixgbe_update_stats(adapter);
for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
@@ -801,11 +792,17 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
i += k;
}
for (j = 0; j < adapter->num_rx_queues; j++) {
+ aggregated += adapter->rx_ring[j].lro_mgr.stats.aggregated;
+ flushed += adapter->rx_ring[j].lro_mgr.stats.flushed;
+ no_desc += adapter->rx_ring[j].lro_mgr.stats.no_desc;
queue_stat = (u64 *)&adapter->rx_ring[j].stats;
for (k = 0; k < stat_count; k++)
data[i + k] = queue_stat[k];
i += k;
}
+ adapter->lro_aggregated = aggregated;
+ adapter->lro_flushed = flushed;
+ adapter->lro_no_desc = no_desc;
}
static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
@@ -973,6 +970,8 @@ static struct ethtool_ops ixgbe_ethtool_ops = {
.get_ethtool_stats = ixgbe_get_ethtool_stats,
.get_coalesce = ixgbe_get_coalesce,
.set_coalesce = ixgbe_set_coalesce,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = ethtool_op_set_flags,
};
void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 8f046090115..be7b723c924 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -266,28 +266,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
* sees the new next_to_clean.
*/
smp_mb();
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!test_bit(__IXGBE_DOWN, &adapter->state)) {
netif_wake_subqueue(netdev, tx_ring->queue_index);
adapter->restart_queue++;
}
-#else
- if (netif_queue_stopped(netdev) &&
- !test_bit(__IXGBE_DOWN, &adapter->state)) {
- netif_wake_queue(netdev);
- adapter->restart_queue++;
- }
-#endif
}
if (adapter->detect_tx_hung)
if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc))
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(netdev, tx_ring->queue_index);
-#else
- netif_stop_queue(netdev);
-#endif
if (total_tx_packets >= tx_ring->work_limit)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
@@ -389,24 +377,39 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* ixgbe_receive_skb - Send a completed packet up the stack
* @adapter: board private structure
* @skb: packet to send up
- * @is_vlan: packet has a VLAN tag
- * @tag: VLAN tag from descriptor
+ * @status: hardware indication of status of receive
+ * @rx_ring: rx descriptor ring (for a specific queue) to setup
+ * @rx_desc: rx descriptor
**/
static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
- struct sk_buff *skb, bool is_vlan,
- u16 tag)
+ struct sk_buff *skb, u8 status,
+ struct ixgbe_ring *ring,
+ union ixgbe_adv_rx_desc *rx_desc)
{
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
- if (adapter->vlgrp && is_vlan)
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
- else
- netif_receive_skb(skb);
- } else {
+ bool is_vlan = (status & IXGBE_RXD_STAT_VP);
+ u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
+ if (adapter->netdev->features & NETIF_F_LRO &&
+ skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (adapter->vlgrp && is_vlan)
- vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
+ lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
+ adapter->vlgrp, tag,
+ rx_desc);
else
- netif_rx(skb);
+ lro_receive_skb(&ring->lro_mgr, skb, rx_desc);
+ ring->lro_used = true;
+ } else {
+ if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
+ if (adapter->vlgrp && is_vlan)
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
+ else
+ netif_receive_skb(skb);
+ } else {
+ if (adapter->vlgrp && is_vlan)
+ vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
+ else
+ netif_rx(skb);
+ }
}
}
@@ -546,8 +549,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
struct sk_buff *skb;
unsigned int i;
u32 upper_len, len, staterr;
- u16 hdr_info, vlan_tag;
- bool is_vlan, cleaned = false;
+ u16 hdr_info;
+ bool cleaned = false;
int cleaned_count = 0;
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
@@ -556,8 +559,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
rx_buffer_info = &rx_ring->rx_buffer_info[i];
- is_vlan = (staterr & IXGBE_RXD_STAT_VP);
- vlan_tag = le16_to_cpu(rx_desc->wb.upper.vlan);
while (staterr & IXGBE_RXD_STAT_DD) {
if (*work_done >= work_to_do)
@@ -635,7 +636,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
total_rx_packets++;
skb->protocol = eth_type_trans(skb, netdev);
- ixgbe_receive_skb(adapter, skb, is_vlan, vlan_tag);
+ ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
netdev->last_rx = jiffies;
next_desc:
@@ -652,8 +653,11 @@ next_desc:
rx_buffer_info = next_buffer;
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
- is_vlan = (staterr & IXGBE_RXD_STAT_VP);
- vlan_tag = le16_to_cpu(rx_desc->wb.upper.vlan);
+ }
+
+ if (rx_ring->lro_used) {
+ lro_flush_all(&rx_ring->lro_mgr);
+ rx_ring->lro_used = false;
}
rx_ring->next_to_clean = i;
@@ -1382,6 +1386,33 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
/**
+ * ixgbe_get_skb_hdr - helper function for LRO header processing
+ * @skb: pointer to sk_buff to be added to LRO packet
+ * @iphdr: pointer to tcp header structure
+ * @tcph: pointer to tcp header structure
+ * @hdr_flags: pointer to header flags
+ * @priv: private data
+ **/
+static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
+ u64 *hdr_flags, void *priv)
+{
+ union ixgbe_adv_rx_desc *rx_desc = priv;
+
+ /* Verify that this is a valid IPv4 TCP packet */
+ if (!(rx_desc->wb.lower.lo_dword.pkt_info &
+ (IXGBE_RXDADV_PKTTYPE_IPV4 | IXGBE_RXDADV_PKTTYPE_TCP)))
+ return -1;
+
+ /* Set network headers */
+ skb_reset_network_header(skb);
+ skb_set_transport_header(skb, ip_hdrlen(skb));
+ *iphdr = ip_hdr(skb);
+ *tcph = tcp_hdr(skb);
+ *hdr_flags = LRO_IPV4 | LRO_TCP;
+ return 0;
+}
+
+/**
* ixgbe_configure_rx - Configure 8254x Receive Unit after Reset
* @adapter: board private structure
*
@@ -1470,6 +1501,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
adapter->rx_ring[i].tail = IXGBE_RDT(i);
}
+ /* Intitial LRO Settings */
+ adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
+ adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
+ adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
+ adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
+ if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
+ adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
+ adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
+ adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+ adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
/* Fill out redirection table */
for (i = 0, j = 0; i < 128; i++, j++) {
@@ -1532,7 +1574,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
if (grp) {
/* enable VLAN tag insert/strip */
ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
- ctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
+ ctrl |= IXGBE_VLNCTRL_VME;
ctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
}
@@ -1603,11 +1645,15 @@ static void ixgbe_set_multi(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- } else if (netdev->flags & IFF_ALLMULTI) {
- fctrl |= IXGBE_FCTRL_MPE;
- fctrl &= ~IXGBE_FCTRL_UPE;
+ fctrl &= ~IXGBE_VLNCTRL_VFE;
} else {
- fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+ if (netdev->flags & IFF_ALLMULTI) {
+ fctrl |= IXGBE_FCTRL_MPE;
+ fctrl &= ~IXGBE_FCTRL_UPE;
+ } else {
+ fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
+ }
+ fctrl |= IXGBE_VLNCTRL_VFE;
}
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
@@ -1967,7 +2013,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
del_timer_sync(&adapter->watchdog_timer);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter);
@@ -2138,11 +2184,7 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
case (IXGBE_FLAG_RSS_ENABLED):
rss_m = 0xF;
nrq = rss_i;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
ntq = rss_i;
-#else
- ntq = 1;
-#endif
break;
case 0:
default:
@@ -2316,10 +2358,8 @@ try_msi:
}
out:
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
/* Notify the stack of the (possibly) reduced Tx Queue count. */
- adapter->netdev->egress_subqueue_count = adapter->num_tx_queues;
-#endif
+ adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
return err;
}
@@ -2490,12 +2530,18 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
struct pci_dev *pdev = adapter->pdev;
int size;
+ size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
+ rxdr->lro_mgr.lro_arr = vmalloc(size);
+ if (!rxdr->lro_mgr.lro_arr)
+ return -ENOMEM;
+ memset(rxdr->lro_mgr.lro_arr, 0, size);
+
size = sizeof(struct ixgbe_rx_buffer) * rxdr->count;
rxdr->rx_buffer_info = vmalloc(size);
if (!rxdr->rx_buffer_info) {
DPRINTK(PROBE, ERR,
"vmalloc allocation failed for the rx desc ring\n");
- return -ENOMEM;
+ goto alloc_failed;
}
memset(rxdr->rx_buffer_info, 0, size);
@@ -2509,13 +2555,18 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
DPRINTK(PROBE, ERR,
"Memory allocation failed for the rx desc ring\n");
vfree(rxdr->rx_buffer_info);
- return -ENOMEM;
+ goto alloc_failed;
}
rxdr->next_to_clean = 0;
rxdr->next_to_use = 0;
return 0;
+
+alloc_failed:
+ vfree(rxdr->lro_mgr.lro_arr);
+ rxdr->lro_mgr.lro_arr = NULL;
+ return -ENOMEM;
}
/**
@@ -2566,6 +2617,9 @@ static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
{
struct pci_dev *pdev = adapter->pdev;
+ vfree(rx_ring->lro_mgr.lro_arr);
+ rx_ring->lro_mgr.lro_arr = NULL;
+
ixgbe_clean_rx_ring(adapter, rx_ring);
vfree(rx_ring->rx_buffer_info);
@@ -2711,6 +2765,8 @@ static int ixgbe_open(struct net_device *netdev)
if (err)
goto err_up;
+ netif_tx_start_all_queues(netdev);
+
return 0;
err_up:
@@ -2842,9 +2898,6 @@ static void ixgbe_watchdog(unsigned long data)
struct net_device *netdev = adapter->netdev;
bool link_up;
u32 link_speed = 0;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- int i;
-#endif
adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
@@ -2865,11 +2918,7 @@ static void ixgbe_watchdog(unsigned long data)
(FLOW_TX ? "TX" : "None"))));
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_wake_subqueue(netdev, i);
-#endif
+ netif_tx_wake_all_queues(netdev);
} else {
/* Force detection of hung controller */
adapter->detect_tx_hung = true;
@@ -2878,7 +2927,7 @@ static void ixgbe_watchdog(unsigned long data)
if (netif_carrier_ok(netdev)) {
DPRINTK(LINK, INFO, "NIC Link is Down\n");
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
}
}
@@ -3196,11 +3245,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(netdev, tx_ring->queue_index);
-#else
- netif_stop_queue(netdev);
-#endif
/* Herbert's original patch had:
* smp_mb__after_netif_stop_queue();
* but since that doesn't exist yet, just open code it. */
@@ -3212,11 +3257,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
return -EBUSY;
/* A reprieve! - use start_queue because it doesn't call schedule */
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_wake_subqueue(netdev, tx_ring->queue_index);
-#else
- netif_wake_queue(netdev);
-#endif
++adapter->restart_queue;
return 0;
}
@@ -3244,9 +3285,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int f;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
len -= skb->data_len;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
-#endif
tx_ring = &adapter->tx_ring[r_idx];
@@ -3434,11 +3473,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
pci_set_master(pdev);
pci_save_state(pdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
-#else
- netdev = alloc_etherdev(sizeof(struct ixgbe_adapter));
-#endif
if (!netdev) {
err = -ENOMEM;
goto err_alloc_etherdev;
@@ -3518,16 +3553,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
+ netdev->features |= NETIF_F_LRO;
netdev->features |= NETIF_F_TSO;
-
netdev->features |= NETIF_F_TSO6;
+
+ netdev->vlan_features |= NETIF_F_TSO;
+ netdev->vlan_features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_SG;
+
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- netdev->features |= NETIF_F_MULTI_QUEUE;
-#endif
-
/* make sure the EEPROM is good */
if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
@@ -3593,11 +3630,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
ixgbe_start_hw(hw);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_stop_subqueue(netdev, i);
-#endif
+ netif_tx_stop_all_queues(netdev);
ixgbe_napi_add_all(adapter);
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 484cb2ba717..7111c65f0b3 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -108,14 +108,14 @@ static int ixpdev_rx(struct net_device *dev, int processed, int budget)
if (unlikely(!netif_running(nds[desc->channel])))
goto err;
- skb = dev_alloc_skb(desc->pkt_length + 2);
+ skb = netdev_alloc_skb(dev, desc->pkt_length + 2);
if (likely(skb != NULL)) {
skb_reserve(skb, 2);
skb_copy_to_linear_data(skb, buf, desc->pkt_length);
skb_put(skb, desc->pkt_length);
skb->protocol = eth_type_trans(skb, nds[desc->channel]);
- skb->dev->last_rx = jiffies;
+ dev->last_rx = jiffies;
netif_receive_skb(skb);
}
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index 0c5447dac03..00d59ab2f8a 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -150,19 +150,19 @@ static void __NS8390_init(struct net_device *dev, int startp);
* card means that approach caused horrible problems like losing serial data
* at 38400 baud on some chips. Remember many 8390 nics on PCI were ISA
* chips with FPGA front ends.
- *
+ *
* Ok the logic behind the 8390 is very simple:
- *
+ *
* Things to know
* - IRQ delivery is asynchronous to the PCI bus
* - Blocking the local CPU IRQ via spin locks was too slow
* - The chip has register windows needing locking work
- *
+ *
* So the path was once (I say once as people appear to have changed it
* in the mean time and it now looks rather bogus if the changes to use
* disable_irq_nosync_irqsave are disabling the local IRQ)
- *
- *
+ *
+ *
* Take the page lock
* Mask the IRQ on chip
* Disable the IRQ (but not mask locally- someone seems to have
@@ -170,22 +170,22 @@ static void __NS8390_init(struct net_device *dev, int startp);
* [This must be _nosync as the page lock may otherwise
* deadlock us]
* Drop the page lock and turn IRQs back on
- *
+ *
* At this point an existing IRQ may still be running but we can't
* get a new one
- *
+ *
* Take the lock (so we know the IRQ has terminated) but don't mask
* the IRQs on the processor
* Set irqlock [for debug]
- *
+ *
* Transmit (slow as ****)
- *
+ *
* re-enable the IRQ
- *
- *
+ *
+ *
* We have to use disable_irq because otherwise you will get delayed
* interrupts on the APIC bus deadlocking the transmit path.
- *
+ *
* Quite hairy but the chip simply wasn't designed for SMP and you can't
* even ACK an interrupt without risking corrupting other parallel
* activities on the chip." [lkml, 25 Jul 2007]
@@ -265,7 +265,7 @@ static void ei_tx_timeout(struct net_device *dev)
int txsr, isr, tickssofar = jiffies - dev->trans_start;
unsigned long flags;
- ei_local->stat.tx_errors++;
+ dev->stats.tx_errors++;
spin_lock_irqsave(&ei_local->page_lock, flags);
txsr = ei_inb(e8390_base+EN0_TSR);
@@ -276,7 +276,7 @@ static void ei_tx_timeout(struct net_device *dev)
dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
(isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
- if (!isr && !ei_local->stat.tx_packets)
+ if (!isr && !dev->stats.tx_packets)
{
/* The 8390 probably hasn't gotten on the cable yet. */
ei_local->interface_num ^= 1; /* Try a different xcvr. */
@@ -374,7 +374,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock);
enable_irq_lockdep_irqrestore(dev->irq, &flags);
- ei_local->stat.tx_errors++;
+ dev->stats.tx_errors++;
return 1;
}
@@ -417,7 +417,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
enable_irq_lockdep_irqrestore(dev->irq, &flags);
dev_kfree_skb (skb);
- ei_local->stat.tx_bytes += send_length;
+ dev->stats.tx_bytes += send_length;
return 0;
}
@@ -493,9 +493,9 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id)
if (interrupts & ENISR_COUNTERS)
{
- ei_local->stat.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0);
- ei_local->stat.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1);
- ei_local->stat.rx_missed_errors+= ei_inb_p(e8390_base + EN0_COUNTER2);
+ dev->stats.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0);
+ dev->stats.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1);
+ dev->stats.rx_missed_errors+= ei_inb_p(e8390_base + EN0_COUNTER2);
ei_outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */
}
@@ -553,7 +553,8 @@ static void __ei_poll(struct net_device *dev)
static void ei_tx_err(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ /* ei_local is used on some platforms via the EI_SHIFT macro */
+ struct ei_device *ei_local __maybe_unused = netdev_priv(dev);
unsigned char txsr = ei_inb_p(e8390_base+EN0_TSR);
unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
@@ -578,10 +579,10 @@ static void ei_tx_err(struct net_device *dev)
ei_tx_intr(dev);
else
{
- ei_local->stat.tx_errors++;
- if (txsr & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
- if (txsr & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
- if (txsr & ENTSR_OWC) ei_local->stat.tx_window_errors++;
+ dev->stats.tx_errors++;
+ if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++;
+ if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++;
+ if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++;
}
}
@@ -645,25 +646,25 @@ static void ei_tx_intr(struct net_device *dev)
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
- ei_local->stat.collisions++;
+ dev->stats.collisions++;
if (status & ENTSR_PTX)
- ei_local->stat.tx_packets++;
+ dev->stats.tx_packets++;
else
{
- ei_local->stat.tx_errors++;
+ dev->stats.tx_errors++;
if (status & ENTSR_ABT)
{
- ei_local->stat.tx_aborted_errors++;
- ei_local->stat.collisions += 16;
+ dev->stats.tx_aborted_errors++;
+ dev->stats.collisions += 16;
}
if (status & ENTSR_CRS)
- ei_local->stat.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (status & ENTSR_FU)
- ei_local->stat.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (status & ENTSR_CDH)
- ei_local->stat.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
if (status & ENTSR_OWC)
- ei_local->stat.tx_window_errors++;
+ dev->stats.tx_window_errors++;
}
netif_wake_queue(dev);
}
@@ -730,7 +731,7 @@ static void ei_receive(struct net_device *dev)
&& rx_frame.next != next_frame + 1 - num_rx_pages) {
ei_local->current_page = rxing_page;
ei_outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY);
- ei_local->stat.rx_errors++;
+ dev->stats.rx_errors++;
continue;
}
@@ -740,8 +741,8 @@ static void ei_receive(struct net_device *dev)
printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
dev->name, rx_frame.count, rx_frame.status,
rx_frame.next);
- ei_local->stat.rx_errors++;
- ei_local->stat.rx_length_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
}
else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
{
@@ -753,7 +754,7 @@ static void ei_receive(struct net_device *dev)
if (ei_debug > 1)
printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, pkt_len);
- ei_local->stat.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
else
@@ -764,10 +765,10 @@ static void ei_receive(struct net_device *dev)
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
dev->last_rx = jiffies;
- ei_local->stat.rx_packets++;
- ei_local->stat.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
if (pkt_stat & ENRSR_PHY)
- ei_local->stat.multicast++;
+ dev->stats.multicast++;
}
}
else
@@ -776,10 +777,10 @@ static void ei_receive(struct net_device *dev)
printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
dev->name, rx_frame.status, rx_frame.next,
rx_frame.count);
- ei_local->stat.rx_errors++;
+ dev->stats.rx_errors++;
/* NB: The NIC counts CRC, frame and missed errors. */
if (pkt_stat & ENRSR_FO)
- ei_local->stat.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
}
next_frame = rx_frame.next;
@@ -816,7 +817,8 @@ static void ei_rx_overrun(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
unsigned char was_txing, must_resend = 0;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ /* ei_local is used on some platforms via the EI_SHIFT macro */
+ struct ei_device *ei_local __maybe_unused = netdev_priv(dev);
/*
* Record whether a Tx was in progress and then issue the
@@ -827,7 +829,7 @@ static void ei_rx_overrun(struct net_device *dev)
if (ei_debug > 1)
printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);
- ei_local->stat.rx_over_errors++;
+ dev->stats.rx_over_errors++;
/*
* Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total.
@@ -889,16 +891,16 @@ static struct net_device_stats *get_stats(struct net_device *dev)
/* If the card is stopped, just return the present stats. */
if (!netif_running(dev))
- return &ei_local->stat;
+ return &dev->stats;
spin_lock_irqsave(&ei_local->page_lock,flags);
/* Read the counter registers, assuming we are in page 0. */
- ei_local->stat.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0);
- ei_local->stat.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1);
- ei_local->stat.rx_missed_errors+= ei_inb_p(ioaddr + EN0_COUNTER2);
+ dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0);
+ dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1);
+ dev->stats.rx_missed_errors+= ei_inb_p(ioaddr + EN0_COUNTER2);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- return &ei_local->stat;
+ return &dev->stats;
}
/*
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 41b774baac4..49f6bc036a9 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -153,7 +153,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
dev->last_rx = jiffies;
/* it's OK to use per_cpu_ptr() because BHs are off */
- pcpu_lstats = netdev_priv(dev);
+ pcpu_lstats = dev->ml_priv;
lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
lb_stats->bytes += skb->len;
lb_stats->packets++;
@@ -171,7 +171,7 @@ static struct net_device_stats *get_stats(struct net_device *dev)
unsigned long packets = 0;
int i;
- pcpu_lstats = netdev_priv(dev);
+ pcpu_lstats = dev->ml_priv;
for_each_possible_cpu(i) {
const struct pcpu_lstats *lb_stats;
@@ -207,13 +207,13 @@ static int loopback_dev_init(struct net_device *dev)
if (!lstats)
return -ENOMEM;
- dev->priv = lstats;
+ dev->ml_priv = lstats;
return 0;
}
static void loopback_dev_free(struct net_device *dev)
{
- struct pcpu_lstats *lstats = netdev_priv(dev);
+ struct pcpu_lstats *lstats = dev->ml_priv;
free_percpu(lstats);
free_netdev(dev);
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index 9e700749bb3..98e3eb2697c 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -117,8 +117,6 @@ enum mac8390_access {
ACCESS_16,
};
-extern enum mac8390_type mac8390_ident(struct nubus_dev * dev);
-extern int mac8390_memsize(unsigned long membase);
extern int mac8390_memtest(struct net_device * dev);
static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,
enum mac8390_type type);
@@ -163,7 +161,7 @@ static void slow_sane_block_output(struct net_device *dev, int count,
static void word_memcpy_tocard(void *tp, const void *fp, int count);
static void word_memcpy_fromcard(void *tp, const void *fp, int count);
-enum mac8390_type __init mac8390_ident(struct nubus_dev * dev)
+static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
{
switch (dev->dr_sw) {
case NUBUS_DRSW_3COM:
@@ -234,7 +232,7 @@ enum mac8390_type __init mac8390_ident(struct nubus_dev * dev)
return MAC8390_NONE;
}
-enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
+static enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
{
unsigned long outdata = 0xA5A0B5B0;
unsigned long indata = 0x00000000;
@@ -252,7 +250,7 @@ enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
return ACCESS_UNKNOWN;
}
-int __init mac8390_memsize(unsigned long membase)
+static int __init mac8390_memsize(unsigned long membase)
{
unsigned long flags;
int i, j;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 0a5745a854c..0496d16f9de 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -80,8 +80,12 @@ static void __init macb_get_hwaddr(struct macb *bp)
addr[4] = top & 0xff;
addr[5] = (top >> 8) & 0xff;
- if (is_valid_ether_addr(addr))
+ if (is_valid_ether_addr(addr)) {
memcpy(bp->dev->dev_addr, addr, sizeof(addr));
+ } else {
+ dev_info(&bp->pdev->dev, "invalid hw address, using random\n");
+ random_ether_addr(bp->dev->dev_addr);
+ }
}
static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
@@ -161,7 +165,7 @@ static void macb_handle_link_change(struct net_device *dev)
if (phydev->link != bp->link) {
if (phydev->link)
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
else {
bp->speed = 0;
bp->duplex = -1;
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index b267161418e..e64c2086d33 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -83,9 +83,6 @@ static unsigned int sonic_debug = 1;
static int sonic_version_printed;
-extern int mac_onboard_sonic_probe(struct net_device* dev);
-extern int mac_nubus_sonic_probe(struct net_device* dev);
-
/* For onboard SONIC */
#define ONBOARD_SONIC_REGISTERS 0x50F0A000
#define ONBOARD_SONIC_PROM_BASE 0x50f08000
@@ -170,7 +167,7 @@ static int macsonic_close(struct net_device* dev)
return err;
}
-int __init macsonic_init(struct net_device* dev)
+static int __init macsonic_init(struct net_device *dev)
{
struct sonic_local* lp = netdev_priv(dev);
@@ -218,7 +215,7 @@ int __init macsonic_init(struct net_device* dev)
return 0;
}
-int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev)
+static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev)
{
struct sonic_local *lp = netdev_priv(dev);
const int prom_addr = ONBOARD_SONIC_PROM_BASE;
@@ -284,7 +281,7 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev)
} else return 0;
}
-int __init mac_onboard_sonic_probe(struct net_device* dev)
+static int __init mac_onboard_sonic_probe(struct net_device *dev)
{
/* Bwahahaha */
static int once_is_more_than_enough;
@@ -405,9 +402,9 @@ int __init mac_onboard_sonic_probe(struct net_device* dev)
return macsonic_init(dev);
}
-int __init mac_nubus_sonic_ethernet_addr(struct net_device* dev,
- unsigned long prom_addr,
- int id)
+static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev,
+ unsigned long prom_addr,
+ int id)
{
int i;
for(i = 0; i < 6; i++)
@@ -420,7 +417,7 @@ int __init mac_nubus_sonic_ethernet_addr(struct net_device* dev,
return 0;
}
-int __init macsonic_ident(struct nubus_dev* ndev)
+static int __init macsonic_ident(struct nubus_dev *ndev)
{
if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC &&
ndev->dr_sw == NUBUS_DRSW_SONIC_LC)
@@ -445,7 +442,7 @@ int __init macsonic_ident(struct nubus_dev* ndev)
return -1;
}
-int __init mac_nubus_sonic_probe(struct net_device* dev)
+static int __init mac_nubus_sonic_probe(struct net_device *dev)
{
static int slots;
struct nubus_dev* ndev = NULL;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 860d75d81f8..efbc15567dd 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -189,12 +189,20 @@ static int macvlan_open(struct net_device *dev)
err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN);
if (err < 0)
- return err;
- if (dev->flags & IFF_ALLMULTI)
- dev_set_allmulti(lowerdev, 1);
+ goto out;
+ if (dev->flags & IFF_ALLMULTI) {
+ err = dev_set_allmulti(lowerdev, 1);
+ if (err < 0)
+ goto del_unicast;
+ }
hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[dev->dev_addr[5]]);
return 0;
+
+del_unicast:
+ dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+out:
+ return err;
}
static int macvlan_stop(struct net_device *dev)
@@ -277,6 +285,19 @@ static struct lock_class_key macvlan_netdev_xmit_lock_key;
#define MACVLAN_STATE_MASK \
((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
+static void macvlan_set_lockdep_class_one(struct net_device *dev,
+ struct netdev_queue *txq,
+ void *_unused)
+{
+ lockdep_set_class(&txq->_xmit_lock,
+ &macvlan_netdev_xmit_lock_key);
+}
+
+static void macvlan_set_lockdep_class(struct net_device *dev)
+{
+ netdev_for_each_tx_queue(dev, macvlan_set_lockdep_class_one, NULL);
+}
+
static int macvlan_init(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
@@ -287,7 +308,8 @@ static int macvlan_init(struct net_device *dev)
dev->features = lowerdev->features & MACVLAN_FEATURES;
dev->iflink = lowerdev->ifindex;
- lockdep_set_class(&dev->_xmit_lock, &macvlan_netdev_xmit_lock_key);
+ macvlan_set_lockdep_class(dev);
+
return 0;
}
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index b7915cdcc6a..83a877f3a55 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -34,406 +34,145 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/in.h>
-#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/etherdevice.h>
-
-#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/platform_device.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
-
#include <linux/mv643xx_eth.h>
-
#include <asm/io.h>
#include <asm/types.h>
-#include <asm/pgtable.h>
#include <asm/system.h>
-#include <asm/delay.h>
-#include <asm/dma-mapping.h>
-#define MV643XX_CHECKSUM_OFFLOAD_TX
-#define MV643XX_NAPI
-#define MV643XX_TX_FAST_REFILL
-#undef MV643XX_COAL
+static char mv643xx_eth_driver_name[] = "mv643xx_eth";
+static char mv643xx_eth_driver_version[] = "1.1";
-#define MV643XX_TX_COAL 100
-#ifdef MV643XX_COAL
-#define MV643XX_RX_COAL 100
-#endif
+#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX
+#define MV643XX_ETH_NAPI
+#define MV643XX_ETH_TX_FAST_REFILL
-#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX
#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)
#else
#define MAX_DESCS_PER_SKB 1
#endif
-#define ETH_VLAN_HLEN 4
-#define ETH_FCS_LEN 4
-#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */
-#define ETH_WRAPPER_LEN (ETH_HW_IP_ALIGN + ETH_HLEN + \
- ETH_VLAN_HLEN + ETH_FCS_LEN)
-#define ETH_RX_SKB_SIZE (dev->mtu + ETH_WRAPPER_LEN + \
- dma_get_cache_alignment())
-
/*
* Registers shared between all ports.
*/
-#define PHY_ADDR_REG 0x0000
-#define SMI_REG 0x0004
-#define WINDOW_BASE(i) (0x0200 + ((i) << 3))
-#define WINDOW_SIZE(i) (0x0204 + ((i) << 3))
-#define WINDOW_REMAP_HIGH(i) (0x0280 + ((i) << 2))
-#define WINDOW_BAR_ENABLE 0x0290
-#define WINDOW_PROTECT(i) (0x0294 + ((i) << 4))
+#define PHY_ADDR 0x0000
+#define SMI_REG 0x0004
+#define WINDOW_BASE(w) (0x0200 + ((w) << 3))
+#define WINDOW_SIZE(w) (0x0204 + ((w) << 3))
+#define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2))
+#define WINDOW_BAR_ENABLE 0x0290
+#define WINDOW_PROTECT(w) (0x0294 + ((w) << 4))
/*
* Per-port registers.
*/
-#define PORT_CONFIG_REG(p) (0x0400 + ((p) << 10))
-#define PORT_CONFIG_EXTEND_REG(p) (0x0404 + ((p) << 10))
-#define MAC_ADDR_LOW(p) (0x0414 + ((p) << 10))
-#define MAC_ADDR_HIGH(p) (0x0418 + ((p) << 10))
-#define SDMA_CONFIG_REG(p) (0x041c + ((p) << 10))
-#define PORT_SERIAL_CONTROL_REG(p) (0x043c + ((p) << 10))
-#define PORT_STATUS_REG(p) (0x0444 + ((p) << 10))
-#define TRANSMIT_QUEUE_COMMAND_REG(p) (0x0448 + ((p) << 10))
-#define MAXIMUM_TRANSMIT_UNIT(p) (0x0458 + ((p) << 10))
-#define INTERRUPT_CAUSE_REG(p) (0x0460 + ((p) << 10))
-#define INTERRUPT_CAUSE_EXTEND_REG(p) (0x0464 + ((p) << 10))
-#define INTERRUPT_MASK_REG(p) (0x0468 + ((p) << 10))
-#define INTERRUPT_EXTEND_MASK_REG(p) (0x046c + ((p) << 10))
-#define TX_FIFO_URGENT_THRESHOLD_REG(p) (0x0474 + ((p) << 10))
-#define RX_CURRENT_QUEUE_DESC_PTR_0(p) (0x060c + ((p) << 10))
-#define RECEIVE_QUEUE_COMMAND_REG(p) (0x0680 + ((p) << 10))
-#define TX_CURRENT_QUEUE_DESC_PTR_0(p) (0x06c0 + ((p) << 10))
-#define MIB_COUNTERS_BASE(p) (0x1000 + ((p) << 7))
-#define DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(p) (0x1400 + ((p) << 10))
-#define DA_FILTER_OTHER_MULTICAST_TABLE_BASE(p) (0x1500 + ((p) << 10))
-#define DA_FILTER_UNICAST_TABLE_BASE(p) (0x1600 + ((p) << 10))
-
-/* These macros describe Ethernet Port configuration reg (Px_cR) bits */
-#define UNICAST_NORMAL_MODE (0 << 0)
-#define UNICAST_PROMISCUOUS_MODE (1 << 0)
-#define DEFAULT_RX_QUEUE(queue) ((queue) << 1)
-#define DEFAULT_RX_ARP_QUEUE(queue) ((queue) << 4)
-#define RECEIVE_BC_IF_NOT_IP_OR_ARP (0 << 7)
-#define REJECT_BC_IF_NOT_IP_OR_ARP (1 << 7)
-#define RECEIVE_BC_IF_IP (0 << 8)
-#define REJECT_BC_IF_IP (1 << 8)
-#define RECEIVE_BC_IF_ARP (0 << 9)
-#define REJECT_BC_IF_ARP (1 << 9)
-#define TX_AM_NO_UPDATE_ERROR_SUMMARY (1 << 12)
-#define CAPTURE_TCP_FRAMES_DIS (0 << 14)
-#define CAPTURE_TCP_FRAMES_EN (1 << 14)
-#define CAPTURE_UDP_FRAMES_DIS (0 << 15)
-#define CAPTURE_UDP_FRAMES_EN (1 << 15)
-#define DEFAULT_RX_TCP_QUEUE(queue) ((queue) << 16)
-#define DEFAULT_RX_UDP_QUEUE(queue) ((queue) << 19)
-#define DEFAULT_RX_BPDU_QUEUE(queue) ((queue) << 22)
-
-#define PORT_CONFIG_DEFAULT_VALUE \
- UNICAST_NORMAL_MODE | \
- DEFAULT_RX_QUEUE(0) | \
- DEFAULT_RX_ARP_QUEUE(0) | \
- RECEIVE_BC_IF_NOT_IP_OR_ARP | \
- RECEIVE_BC_IF_IP | \
- RECEIVE_BC_IF_ARP | \
- CAPTURE_TCP_FRAMES_DIS | \
- CAPTURE_UDP_FRAMES_DIS | \
- DEFAULT_RX_TCP_QUEUE(0) | \
- DEFAULT_RX_UDP_QUEUE(0) | \
- DEFAULT_RX_BPDU_QUEUE(0)
-
-/* These macros describe Ethernet Port configuration extend reg (Px_cXR) bits*/
-#define CLASSIFY_EN (1 << 0)
-#define SPAN_BPDU_PACKETS_AS_NORMAL (0 << 1)
-#define SPAN_BPDU_PACKETS_TO_RX_QUEUE_7 (1 << 1)
-#define PARTITION_DISABLE (0 << 2)
-#define PARTITION_ENABLE (1 << 2)
-
-#define PORT_CONFIG_EXTEND_DEFAULT_VALUE \
- SPAN_BPDU_PACKETS_AS_NORMAL | \
- PARTITION_DISABLE
-
-/* These macros describe Ethernet Port Sdma configuration reg (SDCR) bits */
-#define RIFB (1 << 0)
-#define RX_BURST_SIZE_1_64BIT (0 << 1)
-#define RX_BURST_SIZE_2_64BIT (1 << 1)
+#define PORT_CONFIG(p) (0x0400 + ((p) << 10))
+#define UNICAST_PROMISCUOUS_MODE 0x00000001
+#define PORT_CONFIG_EXT(p) (0x0404 + ((p) << 10))
+#define MAC_ADDR_LOW(p) (0x0414 + ((p) << 10))
+#define MAC_ADDR_HIGH(p) (0x0418 + ((p) << 10))
+#define SDMA_CONFIG(p) (0x041c + ((p) << 10))
+#define PORT_SERIAL_CONTROL(p) (0x043c + ((p) << 10))
+#define PORT_STATUS(p) (0x0444 + ((p) << 10))
+#define TX_FIFO_EMPTY 0x00000400
+#define TXQ_COMMAND(p) (0x0448 + ((p) << 10))
+#define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10))
+#define TX_BW_RATE(p) (0x0450 + ((p) << 10))
+#define TX_BW_MTU(p) (0x0458 + ((p) << 10))
+#define TX_BW_BURST(p) (0x045c + ((p) << 10))
+#define INT_CAUSE(p) (0x0460 + ((p) << 10))
+#define INT_TX_END 0x07f80000
+#define INT_RX 0x0007fbfc
+#define INT_EXT 0x00000002
+#define INT_CAUSE_EXT(p) (0x0464 + ((p) << 10))
+#define INT_EXT_LINK 0x00100000
+#define INT_EXT_PHY 0x00010000
+#define INT_EXT_TX_ERROR_0 0x00000100
+#define INT_EXT_TX_0 0x00000001
+#define INT_EXT_TX 0x0000ffff
+#define INT_MASK(p) (0x0468 + ((p) << 10))
+#define INT_MASK_EXT(p) (0x046c + ((p) << 10))
+#define TX_FIFO_URGENT_THRESHOLD(p) (0x0474 + ((p) << 10))
+#define TXQ_FIX_PRIO_CONF_MOVED(p) (0x04dc + ((p) << 10))
+#define TX_BW_RATE_MOVED(p) (0x04e0 + ((p) << 10))
+#define TX_BW_MTU_MOVED(p) (0x04e8 + ((p) << 10))
+#define TX_BW_BURST_MOVED(p) (0x04ec + ((p) << 10))
+#define RXQ_CURRENT_DESC_PTR(p, q) (0x060c + ((p) << 10) + ((q) << 4))
+#define RXQ_COMMAND(p) (0x0680 + ((p) << 10))
+#define TXQ_CURRENT_DESC_PTR(p, q) (0x06c0 + ((p) << 10) + ((q) << 2))
+#define TXQ_BW_TOKENS(p, q) (0x0700 + ((p) << 10) + ((q) << 4))
+#define TXQ_BW_CONF(p, q) (0x0704 + ((p) << 10) + ((q) << 4))
+#define TXQ_BW_WRR_CONF(p, q) (0x0708 + ((p) << 10) + ((q) << 4))
+#define MIB_COUNTERS(p) (0x1000 + ((p) << 7))
+#define SPECIAL_MCAST_TABLE(p) (0x1400 + ((p) << 10))
+#define OTHER_MCAST_TABLE(p) (0x1500 + ((p) << 10))
+#define UNICAST_TABLE(p) (0x1600 + ((p) << 10))
+
+
+/*
+ * SDMA configuration register.
+ */
#define RX_BURST_SIZE_4_64BIT (2 << 1)
-#define RX_BURST_SIZE_8_64BIT (3 << 1)
-#define RX_BURST_SIZE_16_64BIT (4 << 1)
#define BLM_RX_NO_SWAP (1 << 4)
-#define BLM_RX_BYTE_SWAP (0 << 4)
#define BLM_TX_NO_SWAP (1 << 5)
-#define BLM_TX_BYTE_SWAP (0 << 5)
-#define DESCRIPTORS_BYTE_SWAP (1 << 6)
-#define DESCRIPTORS_NO_SWAP (0 << 6)
-#define IPG_INT_RX(value) (((value) & 0x3fff) << 8)
-#define TX_BURST_SIZE_1_64BIT (0 << 22)
-#define TX_BURST_SIZE_2_64BIT (1 << 22)
#define TX_BURST_SIZE_4_64BIT (2 << 22)
-#define TX_BURST_SIZE_8_64BIT (3 << 22)
-#define TX_BURST_SIZE_16_64BIT (4 << 22)
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
RX_BURST_SIZE_4_64BIT | \
- IPG_INT_RX(0) | \
TX_BURST_SIZE_4_64BIT
#elif defined(__LITTLE_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
RX_BURST_SIZE_4_64BIT | \
BLM_RX_NO_SWAP | \
BLM_TX_NO_SWAP | \
- IPG_INT_RX(0) | \
TX_BURST_SIZE_4_64BIT
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif
-/* These macros describe Ethernet Port serial control reg (PSCR) bits */
-#define SERIAL_PORT_DISABLE (0 << 0)
-#define SERIAL_PORT_ENABLE (1 << 0)
-#define DO_NOT_FORCE_LINK_PASS (0 << 1)
-#define FORCE_LINK_PASS (1 << 1)
-#define ENABLE_AUTO_NEG_FOR_DUPLX (0 << 2)
-#define DISABLE_AUTO_NEG_FOR_DUPLX (1 << 2)
-#define ENABLE_AUTO_NEG_FOR_FLOW_CTRL (0 << 3)
-#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL (1 << 3)
-#define ADV_NO_FLOW_CTRL (0 << 4)
-#define ADV_SYMMETRIC_FLOW_CTRL (1 << 4)
-#define FORCE_FC_MODE_NO_PAUSE_DIS_TX (0 << 5)
-#define FORCE_FC_MODE_TX_PAUSE_DIS (1 << 5)
-#define FORCE_BP_MODE_NO_JAM (0 << 7)
-#define FORCE_BP_MODE_JAM_TX (1 << 7)
-#define FORCE_BP_MODE_JAM_TX_ON_RX_ERR (2 << 7)
-#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
-#define FORCE_LINK_FAIL (0 << 10)
-#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
-#define RETRANSMIT_16_ATTEMPTS (0 << 11)
-#define RETRANSMIT_FOREVER (1 << 11)
-#define ENABLE_AUTO_NEG_SPEED_GMII (0 << 13)
-#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
-#define DTE_ADV_0 (0 << 14)
-#define DTE_ADV_1 (1 << 14)
-#define DISABLE_AUTO_NEG_BYPASS (0 << 15)
-#define ENABLE_AUTO_NEG_BYPASS (1 << 15)
-#define AUTO_NEG_NO_CHANGE (0 << 16)
-#define RESTART_AUTO_NEG (1 << 16)
-#define MAX_RX_PACKET_1518BYTE (0 << 17)
+
+/*
+ * Port serial control register.
+ */
+#define SET_MII_SPEED_TO_100 (1 << 24)
+#define SET_GMII_SPEED_TO_1000 (1 << 23)
+#define SET_FULL_DUPLEX_MODE (1 << 21)
#define MAX_RX_PACKET_1522BYTE (1 << 17)
-#define MAX_RX_PACKET_1552BYTE (2 << 17)
-#define MAX_RX_PACKET_9022BYTE (3 << 17)
-#define MAX_RX_PACKET_9192BYTE (4 << 17)
#define MAX_RX_PACKET_9700BYTE (5 << 17)
#define MAX_RX_PACKET_MASK (7 << 17)
-#define CLR_EXT_LOOPBACK (0 << 20)
-#define SET_EXT_LOOPBACK (1 << 20)
-#define SET_HALF_DUPLEX_MODE (0 << 21)
-#define SET_FULL_DUPLEX_MODE (1 << 21)
-#define DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (0 << 22)
-#define ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1 << 22)
-#define SET_GMII_SPEED_TO_10_100 (0 << 23)
-#define SET_GMII_SPEED_TO_1000 (1 << 23)
-#define SET_MII_SPEED_TO_10 (0 << 24)
-#define SET_MII_SPEED_TO_100 (1 << 24)
+#define DISABLE_AUTO_NEG_SPEED_GMII (1 << 13)
+#define DO_NOT_FORCE_LINK_FAIL (1 << 10)
+#define SERIAL_PORT_CONTROL_RESERVED (1 << 9)
+#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL (1 << 3)
+#define DISABLE_AUTO_NEG_FOR_DUPLEX (1 << 2)
+#define FORCE_LINK_PASS (1 << 1)
+#define SERIAL_PORT_ENABLE (1 << 0)
-#define PORT_SERIAL_CONTROL_DEFAULT_VALUE \
- DO_NOT_FORCE_LINK_PASS | \
- ENABLE_AUTO_NEG_FOR_DUPLX | \
- DISABLE_AUTO_NEG_FOR_FLOW_CTRL | \
- ADV_SYMMETRIC_FLOW_CTRL | \
- FORCE_FC_MODE_NO_PAUSE_DIS_TX | \
- FORCE_BP_MODE_NO_JAM | \
- (1 << 9) /* reserved */ | \
- DO_NOT_FORCE_LINK_FAIL | \
- RETRANSMIT_16_ATTEMPTS | \
- ENABLE_AUTO_NEG_SPEED_GMII | \
- DTE_ADV_0 | \
- DISABLE_AUTO_NEG_BYPASS | \
- AUTO_NEG_NO_CHANGE | \
- MAX_RX_PACKET_9700BYTE | \
- CLR_EXT_LOOPBACK | \
- SET_FULL_DUPLEX_MODE | \
- ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
-
-/* These macros describe Ethernet Serial Status reg (PSR) bits */
-#define PORT_STATUS_MODE_10_BIT (1 << 0)
-#define PORT_STATUS_LINK_UP (1 << 1)
-#define PORT_STATUS_FULL_DUPLEX (1 << 2)
-#define PORT_STATUS_FLOW_CONTROL (1 << 3)
-#define PORT_STATUS_GMII_1000 (1 << 4)
-#define PORT_STATUS_MII_100 (1 << 5)
-/* PSR bit 6 is undocumented */
-#define PORT_STATUS_TX_IN_PROGRESS (1 << 7)
-#define PORT_STATUS_AUTONEG_BYPASSED (1 << 8)
-#define PORT_STATUS_PARTITION (1 << 9)
-#define PORT_STATUS_TX_FIFO_EMPTY (1 << 10)
-/* PSR bits 11-31 are reserved */
-
-#define PORT_DEFAULT_TRANSMIT_QUEUE_SIZE 800
-#define PORT_DEFAULT_RECEIVE_QUEUE_SIZE 400
-
-#define DESC_SIZE 64
-
-#define ETH_RX_QUEUES_ENABLED (1 << 0) /* use only Q0 for receive */
-#define ETH_TX_QUEUES_ENABLED (1 << 0) /* use only Q0 for transmit */
-
-#define ETH_INT_CAUSE_RX_DONE (ETH_RX_QUEUES_ENABLED << 2)
-#define ETH_INT_CAUSE_RX_ERROR (ETH_RX_QUEUES_ENABLED << 9)
-#define ETH_INT_CAUSE_RX (ETH_INT_CAUSE_RX_DONE | ETH_INT_CAUSE_RX_ERROR)
-#define ETH_INT_CAUSE_EXT 0x00000002
-#define ETH_INT_UNMASK_ALL (ETH_INT_CAUSE_RX | ETH_INT_CAUSE_EXT)
-
-#define ETH_INT_CAUSE_TX_DONE (ETH_TX_QUEUES_ENABLED << 0)
-#define ETH_INT_CAUSE_TX_ERROR (ETH_TX_QUEUES_ENABLED << 8)
-#define ETH_INT_CAUSE_TX (ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR)
-#define ETH_INT_CAUSE_PHY 0x00010000
-#define ETH_INT_CAUSE_STATE 0x00100000
-#define ETH_INT_UNMASK_ALL_EXT (ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY | \
- ETH_INT_CAUSE_STATE)
-
-#define ETH_INT_MASK_ALL 0x00000000
-#define ETH_INT_MASK_ALL_EXT 0x00000000
-
-#define PHY_WAIT_ITERATIONS 1000 /* 1000 iterations * 10uS = 10mS max */
-#define PHY_WAIT_MICRO_SECONDS 10
-
-/* Buffer offset from buffer pointer */
-#define RX_BUF_OFFSET 0x2
-
-/* Gigabit Ethernet Unit Global Registers */
-
-/* MIB Counters register definitions */
-#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
-#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
-#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
-#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
-#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
-#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
-#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
-#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
-#define ETH_MIB_FRAMES_64_OCTETS 0x20
-#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
-#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
-#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
-#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
-#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
-#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
-#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
-#define ETH_MIB_GOOD_FRAMES_SENT 0x40
-#define ETH_MIB_EXCESSIVE_COLLISION 0x44
-#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
-#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
-#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
-#define ETH_MIB_FC_SENT 0x54
-#define ETH_MIB_GOOD_FC_RECEIVED 0x58
-#define ETH_MIB_BAD_FC_RECEIVED 0x5c
-#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
-#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
-#define ETH_MIB_OVERSIZE_RECEIVED 0x68
-#define ETH_MIB_JABBER_RECEIVED 0x6c
-#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
-#define ETH_MIB_BAD_CRC_EVENT 0x74
-#define ETH_MIB_COLLISION 0x78
-#define ETH_MIB_LATE_COLLISION 0x7c
-
-/* Port serial status reg (PSR) */
-#define ETH_INTERFACE_PCM 0x00000001
-#define ETH_LINK_IS_UP 0x00000002
-#define ETH_PORT_AT_FULL_DUPLEX 0x00000004
-#define ETH_RX_FLOW_CTRL_ENABLED 0x00000008
-#define ETH_GMII_SPEED_1000 0x00000010
-#define ETH_MII_SPEED_100 0x00000020
-#define ETH_TX_IN_PROGRESS 0x00000080
-#define ETH_BYPASS_ACTIVE 0x00000100
-#define ETH_PORT_AT_PARTITION_STATE 0x00000200
-#define ETH_PORT_TX_FIFO_EMPTY 0x00000400
-
-/* SMI reg */
-#define ETH_SMI_BUSY 0x10000000 /* 0 - Write, 1 - Read */
-#define ETH_SMI_READ_VALID 0x08000000 /* 0 - Write, 1 - Read */
-#define ETH_SMI_OPCODE_WRITE 0 /* Completion of Read */
-#define ETH_SMI_OPCODE_READ 0x04000000 /* Operation is in progress */
-
-/* Interrupt Cause Register Bit Definitions */
-
-/* SDMA command status fields macros */
-
-/* Tx & Rx descriptors status */
-#define ETH_ERROR_SUMMARY 0x00000001
-
-/* Tx & Rx descriptors command */
-#define ETH_BUFFER_OWNED_BY_DMA 0x80000000
-
-/* Tx descriptors status */
-#define ETH_LC_ERROR 0
-#define ETH_UR_ERROR 0x00000002
-#define ETH_RL_ERROR 0x00000004
-#define ETH_LLC_SNAP_FORMAT 0x00000200
-
-/* Rx descriptors status */
-#define ETH_OVERRUN_ERROR 0x00000002
-#define ETH_MAX_FRAME_LENGTH_ERROR 0x00000004
-#define ETH_RESOURCE_ERROR 0x00000006
-#define ETH_VLAN_TAGGED 0x00080000
-#define ETH_BPDU_FRAME 0x00100000
-#define ETH_UDP_FRAME_OVER_IP_V_4 0x00200000
-#define ETH_OTHER_FRAME_TYPE 0x00400000
-#define ETH_LAYER_2_IS_ETH_V_2 0x00800000
-#define ETH_FRAME_TYPE_IP_V_4 0x01000000
-#define ETH_FRAME_HEADER_OK 0x02000000
-#define ETH_RX_LAST_DESC 0x04000000
-#define ETH_RX_FIRST_DESC 0x08000000
-#define ETH_UNKNOWN_DESTINATION_ADDR 0x10000000
-#define ETH_RX_ENABLE_INTERRUPT 0x20000000
-#define ETH_LAYER_4_CHECKSUM_OK 0x40000000
-
-/* Rx descriptors byte count */
-#define ETH_FRAME_FRAGMENTED 0x00000004
-
-/* Tx descriptors command */
-#define ETH_LAYER_4_CHECKSUM_FIRST_DESC 0x00000400
-#define ETH_FRAME_SET_TO_VLAN 0x00008000
-#define ETH_UDP_FRAME 0x00010000
-#define ETH_GEN_TCP_UDP_CHECKSUM 0x00020000
-#define ETH_GEN_IP_V_4_CHECKSUM 0x00040000
-#define ETH_ZERO_PADDING 0x00080000
-#define ETH_TX_LAST_DESC 0x00100000
-#define ETH_TX_FIRST_DESC 0x00200000
-#define ETH_GEN_CRC 0x00400000
-#define ETH_TX_ENABLE_INTERRUPT 0x00800000
-#define ETH_AUTO_MODE 0x40000000
-
-#define ETH_TX_IHL_SHIFT 11
-
-/* typedefs */
-
-typedef enum _eth_func_ret_status {
- ETH_OK, /* Returned as expected. */
- ETH_ERROR, /* Fundamental error. */
- ETH_RETRY, /* Could not process request. Try later.*/
- ETH_END_OF_JOB, /* Ring has nothing to process. */
- ETH_QUEUE_FULL, /* Ring resource error. */
- ETH_QUEUE_LAST_RESOURCE /* Ring resources about to exhaust. */
-} ETH_FUNC_RET_STATUS;
-
-/* These are for big-endian machines. Little endian needs different
- * definitions.
+#define DEFAULT_RX_QUEUE_SIZE 400
+#define DEFAULT_TX_QUEUE_SIZE 800
+
+
+/*
+ * RX/TX descriptors.
*/
#if defined(__BIG_ENDIAN)
-struct eth_rx_desc {
+struct rx_desc {
u16 byte_cnt; /* Descriptor buffer byte count */
u16 buf_size; /* Buffer size */
u32 cmd_sts; /* Descriptor command status */
@@ -441,7 +180,7 @@ struct eth_rx_desc {
u32 buf_ptr; /* Descriptor buffer pointer */
};
-struct eth_tx_desc {
+struct tx_desc {
u16 byte_cnt; /* buffer byte count */
u16 l4i_chk; /* CPU provided TCP checksum */
u32 cmd_sts; /* Command/status field */
@@ -449,7 +188,7 @@ struct eth_tx_desc {
u32 buf_ptr; /* pointer to buffer for this descriptor*/
};
#elif defined(__LITTLE_ENDIAN)
-struct eth_rx_desc {
+struct rx_desc {
u32 cmd_sts; /* Descriptor command status */
u16 buf_size; /* Buffer size */
u16 byte_cnt; /* Descriptor buffer byte count */
@@ -457,7 +196,7 @@ struct eth_rx_desc {
u32 next_desc_ptr; /* Next descriptor pointer */
};
-struct eth_tx_desc {
+struct tx_desc {
u32 cmd_sts; /* Command/status field */
u16 l4i_chk; /* CPU provided TCP checksum */
u16 byte_cnt; /* buffer byte count */
@@ -468,18 +207,59 @@ struct eth_tx_desc {
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif
-/* Unified struct for Rx and Tx operations. The user is not required to */
-/* be familier with neither Tx nor Rx descriptors. */
-struct pkt_info {
- unsigned short byte_cnt; /* Descriptor buffer byte count */
- unsigned short l4i_chk; /* Tx CPU provided TCP Checksum */
- unsigned int cmd_sts; /* Descriptor command status */
- dma_addr_t buf_ptr; /* Descriptor buffer pointer */
- struct sk_buff *return_info; /* User resource return information */
+/* RX & TX descriptor command */
+#define BUFFER_OWNED_BY_DMA 0x80000000
+
+/* RX & TX descriptor status */
+#define ERROR_SUMMARY 0x00000001
+
+/* RX descriptor status */
+#define LAYER_4_CHECKSUM_OK 0x40000000
+#define RX_ENABLE_INTERRUPT 0x20000000
+#define RX_FIRST_DESC 0x08000000
+#define RX_LAST_DESC 0x04000000
+
+/* TX descriptor command */
+#define TX_ENABLE_INTERRUPT 0x00800000
+#define GEN_CRC 0x00400000
+#define TX_FIRST_DESC 0x00200000
+#define TX_LAST_DESC 0x00100000
+#define ZERO_PADDING 0x00080000
+#define GEN_IP_V4_CHECKSUM 0x00040000
+#define GEN_TCP_UDP_CHECKSUM 0x00020000
+#define UDP_FRAME 0x00010000
+
+#define TX_IHL_SHIFT 11
+
+
+/* global *******************************************************************/
+struct mv643xx_eth_shared_private {
+ /*
+ * Ethernet controller base address.
+ */
+ void __iomem *base;
+
+ /*
+ * Protects access to SMI_REG, which is shared between ports.
+ */
+ spinlock_t phy_lock;
+
+ /*
+ * Per-port MBUS window access register value.
+ */
+ u32 win_protect;
+
+ /*
+ * Hardware-specific parameters.
+ */
+ unsigned int t_clk;
+ int extended_rx_coal_limit;
+ int tx_bw_control_moved;
};
-/* Ethernet port specific information */
-struct mv643xx_mib_counters {
+
+/* per-port *****************************************************************/
+struct mib_counters {
u64 good_octets_received;
u32 bad_octets_received;
u32 internal_mac_transmit_err;
@@ -512,461 +292,282 @@ struct mv643xx_mib_counters {
u32 late_collision;
};
-struct mv643xx_shared_private {
- void __iomem *eth_base;
-
- /* used to protect SMI_REG, which is shared across ports */
- spinlock_t phy_lock;
+struct rx_queue {
+ int index;
- u32 win_protect;
-
- unsigned int t_clk;
-};
-
-struct mv643xx_private {
- struct mv643xx_shared_private *shared;
- int port_num; /* User Ethernet port number */
-
- struct mv643xx_shared_private *shared_smi;
-
- u32 rx_sram_addr; /* Base address of rx sram area */
- u32 rx_sram_size; /* Size of rx sram area */
- u32 tx_sram_addr; /* Base address of tx sram area */
- u32 tx_sram_size; /* Size of tx sram area */
+ int rx_ring_size;
- int rx_resource_err; /* Rx ring resource error flag */
+ int rx_desc_count;
+ int rx_curr_desc;
+ int rx_used_desc;
- /* Tx/Rx rings managment indexes fields. For driver use */
+ struct rx_desc *rx_desc_area;
+ dma_addr_t rx_desc_dma;
+ int rx_desc_area_size;
+ struct sk_buff **rx_skb;
- /* Next available and first returning Rx resource */
- int rx_curr_desc_q, rx_used_desc_q;
+ struct timer_list rx_oom;
+};
- /* Next available and first returning Tx resource */
- int tx_curr_desc_q, tx_used_desc_q;
+struct tx_queue {
+ int index;
-#ifdef MV643XX_TX_FAST_REFILL
- u32 tx_clean_threshold;
-#endif
+ int tx_ring_size;
- struct eth_rx_desc *p_rx_desc_area;
- dma_addr_t rx_desc_dma;
- int rx_desc_area_size;
- struct sk_buff **rx_skb;
+ int tx_desc_count;
+ int tx_curr_desc;
+ int tx_used_desc;
- struct eth_tx_desc *p_tx_desc_area;
+ struct tx_desc *tx_desc_area;
dma_addr_t tx_desc_dma;
int tx_desc_area_size;
struct sk_buff **tx_skb;
+};
- struct work_struct tx_timeout_task;
+struct mv643xx_eth_private {
+ struct mv643xx_eth_shared_private *shared;
+ int port_num;
struct net_device *dev;
- struct napi_struct napi;
- struct net_device_stats stats;
- struct mv643xx_mib_counters mib_counters;
+
+ struct mv643xx_eth_shared_private *shared_smi;
+ int phy_addr;
+
spinlock_t lock;
- /* Size of Tx Ring per queue */
- int tx_ring_size;
- /* Number of tx descriptors in use */
- int tx_desc_count;
- /* Size of Rx Ring per queue */
- int rx_ring_size;
- /* Number of rx descriptors in use */
- int rx_desc_count;
+
+ struct mib_counters mib_counters;
+ struct work_struct tx_timeout_task;
+ struct mii_if_info mii;
/*
- * Used in case RX Ring is empty, which can be caused when
- * system does not have resources (skb's)
+ * RX state.
*/
- struct timer_list timeout;
-
- u32 rx_int_coal;
- u32 tx_int_coal;
- struct mii_if_info mii;
-};
+ int default_rx_ring_size;
+ unsigned long rx_desc_sram_addr;
+ int rx_desc_sram_size;
+ u8 rxq_mask;
+ int rxq_primary;
+ struct napi_struct napi;
+ struct rx_queue rxq[8];
-/* Static function declarations */
-static void eth_port_init(struct mv643xx_private *mp);
-static void eth_port_reset(struct mv643xx_private *mp);
-static void eth_port_start(struct net_device *dev);
-
-static void ethernet_phy_reset(struct mv643xx_private *mp);
-
-static void eth_port_write_smi_reg(struct mv643xx_private *mp,
- unsigned int phy_reg, unsigned int value);
-
-static void eth_port_read_smi_reg(struct mv643xx_private *mp,
- unsigned int phy_reg, unsigned int *value);
-
-static void eth_clear_mib_counters(struct mv643xx_private *mp);
-
-static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
- struct pkt_info *p_pkt_info);
-static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
- struct pkt_info *p_pkt_info);
-
-static void eth_port_uc_addr_get(struct mv643xx_private *mp,
- unsigned char *p_addr);
-static void eth_port_uc_addr_set(struct mv643xx_private *mp,
- unsigned char *p_addr);
-static void eth_port_set_multicast_list(struct net_device *);
-static void mv643xx_eth_port_enable_tx(struct mv643xx_private *mp,
- unsigned int queues);
-static void mv643xx_eth_port_enable_rx(struct mv643xx_private *mp,
- unsigned int queues);
-static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_private *mp);
-static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_private *mp);
-static int mv643xx_eth_open(struct net_device *);
-static int mv643xx_eth_stop(struct net_device *);
-static void eth_port_init_mac_tables(struct mv643xx_private *mp);
-#ifdef MV643XX_NAPI
-static int mv643xx_poll(struct napi_struct *napi, int budget);
+ /*
+ * TX state.
+ */
+ int default_tx_ring_size;
+ unsigned long tx_desc_sram_addr;
+ int tx_desc_sram_size;
+ u8 txq_mask;
+ int txq_primary;
+ struct tx_queue txq[8];
+#ifdef MV643XX_ETH_TX_FAST_REFILL
+ int tx_clean_threshold;
#endif
-static int ethernet_phy_get(struct mv643xx_private *mp);
-static void ethernet_phy_set(struct mv643xx_private *mp, int phy_addr);
-static int ethernet_phy_detect(struct mv643xx_private *mp);
-static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
-static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val);
-static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static const struct ethtool_ops mv643xx_ethtool_ops;
+};
-static char mv643xx_driver_name[] = "mv643xx_eth";
-static char mv643xx_driver_version[] = "1.0";
-static inline u32 rdl(struct mv643xx_private *mp, int offset)
+/* port register accessors **************************************************/
+static inline u32 rdl(struct mv643xx_eth_private *mp, int offset)
{
- return readl(mp->shared->eth_base + offset);
+ return readl(mp->shared->base + offset);
}
-static inline void wrl(struct mv643xx_private *mp, int offset, u32 data)
+static inline void wrl(struct mv643xx_eth_private *mp, int offset, u32 data)
{
- writel(data, mp->shared->eth_base + offset);
+ writel(data, mp->shared->base + offset);
}
-/*
- * Changes MTU (maximum transfer unit) of the gigabit ethenret port
- *
- * Input : pointer to ethernet interface network device structure
- * new mtu size
- * Output : 0 upon success, -EINVAL upon failure
- */
-static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu > 9500) || (new_mtu < 64))
- return -EINVAL;
- dev->mtu = new_mtu;
- if (!netif_running(dev))
- return 0;
-
- /*
- * Stop and then re-open the interface. This will allocate RX
- * skbs of the new MTU.
- * There is a possible danger that the open will not succeed,
- * due to memory being full, which might fail the open function.
- */
- mv643xx_eth_stop(dev);
- if (mv643xx_eth_open(dev)) {
- printk(KERN_ERR "%s: Fatal error on opening device\n",
- dev->name);
- }
-
- return 0;
-}
-
-/*
- * mv643xx_eth_rx_refill_descs
- *
- * Fills / refills RX queue on a certain gigabit ethernet port
- *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
- */
-static void mv643xx_eth_rx_refill_descs(struct net_device *dev)
+/* rxq/txq helper functions *************************************************/
+static struct mv643xx_eth_private *rxq_to_mp(struct rx_queue *rxq)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- struct pkt_info pkt_info;
- struct sk_buff *skb;
- int unaligned;
-
- while (mp->rx_desc_count < mp->rx_ring_size) {
- skb = dev_alloc_skb(ETH_RX_SKB_SIZE + dma_get_cache_alignment());
- if (!skb)
- break;
- mp->rx_desc_count++;
- unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
- if (unaligned)
- skb_reserve(skb, dma_get_cache_alignment() - unaligned);
- pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
- pkt_info.byte_cnt = ETH_RX_SKB_SIZE;
- pkt_info.buf_ptr = dma_map_single(NULL, skb->data,
- ETH_RX_SKB_SIZE, DMA_FROM_DEVICE);
- pkt_info.return_info = skb;
- if (eth_rx_return_buff(mp, &pkt_info) != ETH_OK) {
- printk(KERN_ERR
- "%s: Error allocating RX Ring\n", dev->name);
- break;
- }
- skb_reserve(skb, ETH_HW_IP_ALIGN);
- }
- /*
- * If RX ring is empty of SKB, set a timer to try allocating
- * again at a later time.
- */
- if (mp->rx_desc_count == 0) {
- printk(KERN_INFO "%s: Rx ring is empty\n", dev->name);
- mp->timeout.expires = jiffies + (HZ / 10); /* 100 mSec */
- add_timer(&mp->timeout);
- }
+ return container_of(rxq, struct mv643xx_eth_private, rxq[rxq->index]);
}
-/*
- * mv643xx_eth_rx_refill_descs_timer_wrapper
- *
- * Timer routine to wake up RX queue filling task. This function is
- * used only in case the RX queue is empty, and all alloc_skb has
- * failed (due to out of memory event).
- *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
- */
-static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data)
+static struct mv643xx_eth_private *txq_to_mp(struct tx_queue *txq)
{
- mv643xx_eth_rx_refill_descs((struct net_device *)data);
+ return container_of(txq, struct mv643xx_eth_private, txq[txq->index]);
}
-/*
- * mv643xx_eth_update_mac_address
- *
- * Update the MAC address of the port in the address table
- *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
- */
-static void mv643xx_eth_update_mac_address(struct net_device *dev)
+static void rxq_enable(struct rx_queue *rxq)
{
- struct mv643xx_private *mp = netdev_priv(dev);
-
- eth_port_init_mac_tables(mp);
- eth_port_uc_addr_set(mp, dev->dev_addr);
+ struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
+ wrl(mp, RXQ_COMMAND(mp->port_num), 1 << rxq->index);
}
-/*
- * mv643xx_eth_set_rx_mode
- *
- * Change from promiscuos to regular rx mode
- *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
- */
-static void mv643xx_eth_set_rx_mode(struct net_device *dev)
+static void rxq_disable(struct rx_queue *rxq)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- u32 config_reg;
+ struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
+ u8 mask = 1 << rxq->index;
- config_reg = rdl(mp, PORT_CONFIG_REG(mp->port_num));
- if (dev->flags & IFF_PROMISC)
- config_reg |= (u32) UNICAST_PROMISCUOUS_MODE;
- else
- config_reg &= ~(u32) UNICAST_PROMISCUOUS_MODE;
- wrl(mp, PORT_CONFIG_REG(mp->port_num), config_reg);
-
- eth_port_set_multicast_list(dev);
+ wrl(mp, RXQ_COMMAND(mp->port_num), mask << 8);
+ while (rdl(mp, RXQ_COMMAND(mp->port_num)) & mask)
+ udelay(10);
}
-/*
- * mv643xx_eth_set_mac_address
- *
- * Change the interface's mac address.
- * No special hardware thing should be done because interface is always
- * put in promiscuous mode.
- *
- * Input : pointer to ethernet interface network device structure and
- * a pointer to the designated entry to be added to the cache.
- * Output : zero upon success, negative upon failure
- */
-static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
+static void txq_enable(struct tx_queue *txq)
{
- int i;
-
- for (i = 0; i < 6; i++)
- /* +2 is for the offset of the HW addr type */
- dev->dev_addr[i] = ((unsigned char *)addr)[i + 2];
- mv643xx_eth_update_mac_address(dev);
- return 0;
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ wrl(mp, TXQ_COMMAND(mp->port_num), 1 << txq->index);
}
-/*
- * mv643xx_eth_tx_timeout
- *
- * Called upon a timeout on transmitting a packet
- *
- * Input : pointer to ethernet interface network device structure.
- * Output : N/A
- */
-static void mv643xx_eth_tx_timeout(struct net_device *dev)
+static void txq_disable(struct tx_queue *txq)
{
- struct mv643xx_private *mp = netdev_priv(dev);
-
- printk(KERN_INFO "%s: TX timeout ", dev->name);
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ u8 mask = 1 << txq->index;
- /* Do the reset outside of interrupt context */
- schedule_work(&mp->tx_timeout_task);
+ wrl(mp, TXQ_COMMAND(mp->port_num), mask << 8);
+ while (rdl(mp, TXQ_COMMAND(mp->port_num)) & mask)
+ udelay(10);
}
-/*
- * mv643xx_eth_tx_timeout_task
- *
- * Actual routine to reset the adapter when a timeout on Tx has occurred
- */
-static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly)
+static void __txq_maybe_wake(struct tx_queue *txq)
{
- struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private,
- tx_timeout_task);
- struct net_device *dev = mp->dev;
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
- if (!netif_running(dev))
- return;
+ /*
+ * netif_{stop,wake}_queue() flow control only applies to
+ * the primary queue.
+ */
+ BUG_ON(txq->index != mp->txq_primary);
- netif_stop_queue(dev);
+ if (txq->tx_ring_size - txq->tx_desc_count >= MAX_DESCS_PER_SKB)
+ netif_wake_queue(mp->dev);
+}
- eth_port_reset(mp);
- eth_port_start(dev);
- if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB)
- netif_wake_queue(dev);
-}
+/* rx ***********************************************************************/
+static void txq_reclaim(struct tx_queue *txq, int force);
-/**
- * mv643xx_eth_free_tx_descs - Free the tx desc data for completed descriptors
- *
- * If force is non-zero, frees uncompleted descriptors as well
- */
-static int mv643xx_eth_free_tx_descs(struct net_device *dev, int force)
+static void rxq_refill(struct rx_queue *rxq)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- struct eth_tx_desc *desc;
- u32 cmd_sts;
- struct sk_buff *skb;
+ struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
unsigned long flags;
- int tx_index;
- dma_addr_t addr;
- int count;
- int released = 0;
- while (mp->tx_desc_count > 0) {
- spin_lock_irqsave(&mp->lock, flags);
-
- /* tx_desc_count might have changed before acquiring the lock */
- if (mp->tx_desc_count <= 0) {
- spin_unlock_irqrestore(&mp->lock, flags);
- return released;
- }
-
- tx_index = mp->tx_used_desc_q;
- desc = &mp->p_tx_desc_area[tx_index];
- cmd_sts = desc->cmd_sts;
+ spin_lock_irqsave(&mp->lock, flags);
- if (!force && (cmd_sts & ETH_BUFFER_OWNED_BY_DMA)) {
- spin_unlock_irqrestore(&mp->lock, flags);
- return released;
- }
+ while (rxq->rx_desc_count < rxq->rx_ring_size) {
+ int skb_size;
+ struct sk_buff *skb;
+ int unaligned;
+ int rx;
- mp->tx_used_desc_q = (tx_index + 1) % mp->tx_ring_size;
- mp->tx_desc_count--;
+ /*
+ * Reserve 2+14 bytes for an ethernet header (the
+ * hardware automatically prepends 2 bytes of dummy
+ * data to each received packet), 4 bytes for a VLAN
+ * header, and 4 bytes for the trailing FCS -- 24
+ * bytes total.
+ */
+ skb_size = mp->dev->mtu + 24;
- addr = desc->buf_ptr;
- count = desc->byte_cnt;
- skb = mp->tx_skb[tx_index];
- if (skb)
- mp->tx_skb[tx_index] = NULL;
+ skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1);
+ if (skb == NULL)
+ break;
- if (cmd_sts & ETH_ERROR_SUMMARY) {
- printk("%s: Error in TX\n", dev->name);
- dev->stats.tx_errors++;
- }
+ unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
+ if (unaligned)
+ skb_reserve(skb, dma_get_cache_alignment() - unaligned);
- spin_unlock_irqrestore(&mp->lock, flags);
+ rxq->rx_desc_count++;
+ rx = rxq->rx_used_desc;
+ rxq->rx_used_desc = (rx + 1) % rxq->rx_ring_size;
- if (cmd_sts & ETH_TX_FIRST_DESC)
- dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
- else
- dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE);
+ rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data,
+ skb_size, DMA_FROM_DEVICE);
+ rxq->rx_desc_area[rx].buf_size = skb_size;
+ rxq->rx_skb[rx] = skb;
+ wmb();
+ rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA |
+ RX_ENABLE_INTERRUPT;
+ wmb();
- if (skb)
- dev_kfree_skb_irq(skb);
+ /*
+ * The hardware automatically prepends 2 bytes of
+ * dummy data to each received packet, so that the
+ * IP header ends up 16-byte aligned.
+ */
+ skb_reserve(skb, 2);
+ }
- released = 1;
+ if (rxq->rx_desc_count != rxq->rx_ring_size) {
+ rxq->rx_oom.expires = jiffies + (HZ / 10);
+ add_timer(&rxq->rx_oom);
}
- return released;
+ spin_unlock_irqrestore(&mp->lock, flags);
}
-static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev)
+static inline void rxq_refill_timer_wrapper(unsigned long data)
{
- struct mv643xx_private *mp = netdev_priv(dev);
-
- if (mv643xx_eth_free_tx_descs(dev, 0) &&
- mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB)
- netif_wake_queue(dev);
+ rxq_refill((struct rx_queue *)data);
}
-static void mv643xx_eth_free_all_tx_descs(struct net_device *dev)
+static int rxq_process(struct rx_queue *rxq, int budget)
{
- mv643xx_eth_free_tx_descs(dev, 1);
-}
+ struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
+ struct net_device_stats *stats = &mp->dev->stats;
+ int rx;
-/*
- * mv643xx_eth_receive
- *
- * This function is forward packets that are received from the port's
- * queues toward kernel core or FastRoute them to another interface.
- *
- * Input : dev - a pointer to the required interface
- * max - maximum number to receive (0 means unlimted)
- *
- * Output : number of served packets
- */
-static int mv643xx_eth_receive_queue(struct net_device *dev, int budget)
-{
- struct mv643xx_private *mp = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- unsigned int received_packets = 0;
- struct sk_buff *skb;
- struct pkt_info pkt_info;
+ rx = 0;
+ while (rx < budget) {
+ struct rx_desc *rx_desc;
+ unsigned int cmd_sts;
+ struct sk_buff *skb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mp->lock, flags);
+
+ rx_desc = &rxq->rx_desc_area[rxq->rx_curr_desc];
+
+ cmd_sts = rx_desc->cmd_sts;
+ if (cmd_sts & BUFFER_OWNED_BY_DMA) {
+ spin_unlock_irqrestore(&mp->lock, flags);
+ break;
+ }
+ rmb();
+
+ skb = rxq->rx_skb[rxq->rx_curr_desc];
+ rxq->rx_skb[rxq->rx_curr_desc] = NULL;
- while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
- dma_unmap_single(NULL, pkt_info.buf_ptr, ETH_RX_SKB_SIZE,
- DMA_FROM_DEVICE);
- mp->rx_desc_count--;
- received_packets++;
+ rxq->rx_curr_desc = (rxq->rx_curr_desc + 1) % rxq->rx_ring_size;
+
+ spin_unlock_irqrestore(&mp->lock, flags);
+
+ dma_unmap_single(NULL, rx_desc->buf_ptr + 2,
+ mp->dev->mtu + 24, DMA_FROM_DEVICE);
+ rxq->rx_desc_count--;
+ rx++;
/*
* Update statistics.
- * Note byte count includes 4 byte CRC count
+ *
+ * Note that the descriptor byte count includes 2 dummy
+ * bytes automatically inserted by the hardware at the
+ * start of the packet (which we don't count), and a 4
+ * byte CRC at the end of the packet (which we do count).
*/
stats->rx_packets++;
- stats->rx_bytes += pkt_info.byte_cnt;
- skb = pkt_info.return_info;
+ stats->rx_bytes += rx_desc->byte_cnt - 2;
+
/*
- * In case received a packet without first / last bits on OR
- * the error summary bit is on, the packets needs to be dropeed.
+ * In case we received a packet without first / last bits
+ * on, or the error summary bit is set, the packet needs
+ * to be dropped.
*/
- if (((pkt_info.cmd_sts
- & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
- (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
- || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
+ if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+ (RX_FIRST_DESC | RX_LAST_DESC))
+ || (cmd_sts & ERROR_SUMMARY)) {
stats->rx_dropped++;
- if ((pkt_info.cmd_sts & (ETH_RX_FIRST_DESC |
- ETH_RX_LAST_DESC)) !=
- (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) {
+
+ if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+ (RX_FIRST_DESC | RX_LAST_DESC)) {
if (net_ratelimit())
- printk(KERN_ERR
- "%s: Received packet spread "
- "on multiple descriptors\n",
- dev->name);
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "received packet spanning "
+ "multiple descriptors\n");
}
- if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)
+
+ if (cmd_sts & ERROR_SUMMARY)
stats->rx_errors++;
dev_kfree_skb_irq(skb);
@@ -975,2391 +576,2003 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget)
* The -4 is for the CRC in the trailer of the
* received packet
*/
- skb_put(skb, pkt_info.byte_cnt - 4);
+ skb_put(skb, rx_desc->byte_cnt - 2 - 4);
- if (pkt_info.cmd_sts & ETH_LAYER_4_CHECKSUM_OK) {
+ if (cmd_sts & LAYER_4_CHECKSUM_OK) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->csum = htons(
- (pkt_info.cmd_sts & 0x0007fff8) >> 3);
+ (cmd_sts & 0x0007fff8) >> 3);
}
- skb->protocol = eth_type_trans(skb, dev);
-#ifdef MV643XX_NAPI
+ skb->protocol = eth_type_trans(skb, mp->dev);
+#ifdef MV643XX_ETH_NAPI
netif_receive_skb(skb);
#else
netif_rx(skb);
#endif
}
- dev->last_rx = jiffies;
+
+ mp->dev->last_rx = jiffies;
}
- mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */
- return received_packets;
+ rxq_refill(rxq);
+
+ return rx;
}
-/* Set the mv643xx port configuration register for the speed/duplex mode. */
-static void mv643xx_eth_update_pscr(struct net_device *dev,
- struct ethtool_cmd *ecmd)
+#ifdef MV643XX_ETH_NAPI
+static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- int port_num = mp->port_num;
- u32 o_pscr, n_pscr;
- unsigned int queues;
+ struct mv643xx_eth_private *mp;
+ int rx;
+ int i;
- o_pscr = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num));
- n_pscr = o_pscr;
+ mp = container_of(napi, struct mv643xx_eth_private, napi);
- /* clear speed, duplex and rx buffer size fields */
- n_pscr &= ~(SET_MII_SPEED_TO_100 |
- SET_GMII_SPEED_TO_1000 |
- SET_FULL_DUPLEX_MODE |
- MAX_RX_PACKET_MASK);
-
- if (ecmd->duplex == DUPLEX_FULL)
- n_pscr |= SET_FULL_DUPLEX_MODE;
-
- if (ecmd->speed == SPEED_1000)
- n_pscr |= SET_GMII_SPEED_TO_1000 |
- MAX_RX_PACKET_9700BYTE;
- else {
- if (ecmd->speed == SPEED_100)
- n_pscr |= SET_MII_SPEED_TO_100;
- n_pscr |= MAX_RX_PACKET_1522BYTE;
+#ifdef MV643XX_ETH_TX_FAST_REFILL
+ if (++mp->tx_clean_threshold > 5) {
+ mp->tx_clean_threshold = 0;
+ for (i = 0; i < 8; i++)
+ if (mp->txq_mask & (1 << i))
+ txq_reclaim(mp->txq + i, 0);
}
+#endif
- if (n_pscr != o_pscr) {
- if ((o_pscr & SERIAL_PORT_ENABLE) == 0)
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
- else {
- queues = mv643xx_eth_port_disable_tx(mp);
-
- o_pscr &= ~SERIAL_PORT_ENABLE;
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), o_pscr);
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
- if (queues)
- mv643xx_eth_port_enable_tx(mp, queues);
- }
+ rx = 0;
+ for (i = 7; rx < budget && i >= 0; i--)
+ if (mp->rxq_mask & (1 << i))
+ rx += rxq_process(mp->rxq + i, budget - rx);
+
+ if (rx < budget) {
+ netif_rx_complete(mp->dev, napi);
+ wrl(mp, INT_CAUSE(mp->port_num), 0);
+ wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
+ wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
}
+
+ return rx;
}
+#endif
-/*
- * mv643xx_eth_int_handler
- *
- * Main interrupt handler for the gigbit ethernet ports
- *
- * Input : irq - irq number (not used)
- * dev_id - a pointer to the required interface's data structure
- * regs - not used
- * Output : N/A
- */
-static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
+/* tx ***********************************************************************/
+static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
{
- struct net_device *dev = (struct net_device *)dev_id;
- struct mv643xx_private *mp = netdev_priv(dev);
- u32 eth_int_cause, eth_int_cause_ext = 0;
- unsigned int port_num = mp->port_num;
-
- /* Read interrupt cause registers */
- eth_int_cause = rdl(mp, INTERRUPT_CAUSE_REG(port_num)) &
- ETH_INT_UNMASK_ALL;
- if (eth_int_cause & ETH_INT_CAUSE_EXT) {
- eth_int_cause_ext = rdl(mp,
- INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
- ETH_INT_UNMASK_ALL_EXT;
- wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num),
- ~eth_int_cause_ext);
- }
-
- /* PHY status changed */
- if (eth_int_cause_ext & (ETH_INT_CAUSE_PHY | ETH_INT_CAUSE_STATE)) {
- struct ethtool_cmd cmd;
+ int frag;
- if (mii_link_ok(&mp->mii)) {
- mii_ethtool_gset(&mp->mii, &cmd);
- mv643xx_eth_update_pscr(dev, &cmd);
- mv643xx_eth_port_enable_tx(mp, ETH_TX_QUEUES_ENABLED);
- if (!netif_carrier_ok(dev)) {
- netif_carrier_on(dev);
- if (mp->tx_ring_size - mp->tx_desc_count >=
- MAX_DESCS_PER_SKB)
- netif_wake_queue(dev);
- }
- } else if (netif_carrier_ok(dev)) {
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- }
+ for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+ skb_frag_t *fragp = &skb_shinfo(skb)->frags[frag];
+ if (fragp->size <= 8 && fragp->page_offset & 7)
+ return 1;
}
-#ifdef MV643XX_NAPI
- if (eth_int_cause & ETH_INT_CAUSE_RX) {
- /* schedule the NAPI poll routine to maintain port */
- wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
+ return 0;
+}
- /* wait for previous write to complete */
- rdl(mp, INTERRUPT_MASK_REG(port_num));
+static int txq_alloc_desc_index(struct tx_queue *txq)
+{
+ int tx_desc_curr;
- netif_rx_schedule(dev, &mp->napi);
- }
-#else
- if (eth_int_cause & ETH_INT_CAUSE_RX)
- mv643xx_eth_receive_queue(dev, INT_MAX);
-#endif
- if (eth_int_cause_ext & ETH_INT_CAUSE_TX)
- mv643xx_eth_free_completed_tx_descs(dev);
+ BUG_ON(txq->tx_desc_count >= txq->tx_ring_size);
- /*
- * If no real interrupt occured, exit.
- * This can happen when using gigE interrupt coalescing mechanism.
- */
- if ((eth_int_cause == 0x0) && (eth_int_cause_ext == 0x0))
- return IRQ_NONE;
+ tx_desc_curr = txq->tx_curr_desc;
+ txq->tx_curr_desc = (tx_desc_curr + 1) % txq->tx_ring_size;
- return IRQ_HANDLED;
-}
+ BUG_ON(txq->tx_curr_desc == txq->tx_used_desc);
-#ifdef MV643XX_COAL
+ return tx_desc_curr;
+}
-/*
- * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
- *
- * DESCRIPTION:
- * This routine sets the RX coalescing interrupt mechanism parameter.
- * This parameter is a timeout counter, that counts in 64 t_clk
- * chunks ; that when timeout event occurs a maskable interrupt
- * occurs.
- * The parameter is calculated using the tClk of the MV-643xx chip
- * , and the required delay of the interrupt in usec.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet port
- * unsigned int delay Delay in usec
- *
- * OUTPUT:
- * Interrupt coalescing mechanism value is set in MV-643xx chip.
- *
- * RETURN:
- * The interrupt coalescing value set in the gigE port.
- *
- */
-static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp,
- unsigned int delay)
+static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
{
- unsigned int port_num = mp->port_num;
- unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ int frag;
- /* Set RX Coalescing mechanism */
- wrl(mp, SDMA_CONFIG_REG(port_num),
- ((coal & 0x3fff) << 8) |
- (rdl(mp, SDMA_CONFIG_REG(port_num))
- & 0xffc000ff));
+ for (frag = 0; frag < nr_frags; frag++) {
+ skb_frag_t *this_frag;
+ int tx_index;
+ struct tx_desc *desc;
- return coal;
-}
-#endif
+ this_frag = &skb_shinfo(skb)->frags[frag];
+ tx_index = txq_alloc_desc_index(txq);
+ desc = &txq->tx_desc_area[tx_index];
-/*
- * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path
- *
- * DESCRIPTION:
- * This routine sets the TX coalescing interrupt mechanism parameter.
- * This parameter is a timeout counter, that counts in 64 t_clk
- * chunks ; that when timeout event occurs a maskable interrupt
- * occurs.
- * The parameter is calculated using the t_cLK frequency of the
- * MV-643xx chip and the required delay in the interrupt in uSec
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet port
- * unsigned int delay Delay in uSeconds
- *
- * OUTPUT:
- * Interrupt coalescing mechanism value is set in MV-643xx chip.
- *
- * RETURN:
- * The interrupt coalescing value set in the gigE port.
- *
- */
-static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp,
- unsigned int delay)
-{
- unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
+ /*
+ * The last fragment will generate an interrupt
+ * which will free the skb on TX completion.
+ */
+ if (frag == nr_frags - 1) {
+ desc->cmd_sts = BUFFER_OWNED_BY_DMA |
+ ZERO_PADDING | TX_LAST_DESC |
+ TX_ENABLE_INTERRUPT;
+ txq->tx_skb[tx_index] = skb;
+ } else {
+ desc->cmd_sts = BUFFER_OWNED_BY_DMA;
+ txq->tx_skb[tx_index] = NULL;
+ }
- /* Set TX Coalescing mechanism */
- wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4);
+ desc->l4i_chk = 0;
+ desc->byte_cnt = this_frag->size;
+ desc->buf_ptr = dma_map_page(NULL, this_frag->page,
+ this_frag->page_offset,
+ this_frag->size,
+ DMA_TO_DEVICE);
+ }
+}
- return coal;
+static inline __be16 sum16_as_be(__sum16 sum)
+{
+ return (__force __be16)sum;
}
-/*
- * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
- *
- * DESCRIPTION:
- * This function prepares a Rx chained list of descriptors and packet
- * buffers in a form of a ring. The routine must be called after port
- * initialization routine and before port start routine.
- * The Ethernet SDMA engine uses CPU bus addresses to access the various
- * devices in the system (i.e. DRAM). This function uses the ethernet
- * struct 'virtual to physical' routine (set by the user) to set the ring
- * with physical addresses.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port Control srtuct.
- *
- * OUTPUT:
- * The routine updates the Ethernet port control struct with information
- * regarding the Rx descriptors and buffers.
- *
- * RETURN:
- * None.
- */
-static void ether_init_rx_desc_ring(struct mv643xx_private *mp)
+static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
{
- volatile struct eth_rx_desc *p_rx_desc;
- int rx_desc_num = mp->rx_ring_size;
- int i;
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ int tx_index;
+ struct tx_desc *desc;
+ u32 cmd_sts;
+ int length;
- /* initialize the next_desc_ptr links in the Rx descriptors ring */
- p_rx_desc = (struct eth_rx_desc *)mp->p_rx_desc_area;
- for (i = 0; i < rx_desc_num; i++) {
- p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma +
- ((i + 1) % rx_desc_num) * sizeof(struct eth_rx_desc);
+ cmd_sts = TX_FIRST_DESC | GEN_CRC | BUFFER_OWNED_BY_DMA;
+
+ tx_index = txq_alloc_desc_index(txq);
+ desc = &txq->tx_desc_area[tx_index];
+
+ if (nr_frags) {
+ txq_submit_frag_skb(txq, skb);
+
+ length = skb_headlen(skb);
+ txq->tx_skb[tx_index] = NULL;
+ } else {
+ cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;
+ length = skb->len;
+ txq->tx_skb[tx_index] = skb;
}
- /* Save Rx desc pointer to driver struct. */
- mp->rx_curr_desc_q = 0;
- mp->rx_used_desc_q = 0;
+ desc->byte_cnt = length;
+ desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
- mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc);
-}
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ BUG_ON(skb->protocol != htons(ETH_P_IP));
-/*
- * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
- *
- * DESCRIPTION:
- * This function prepares a Tx chained list of descriptors and packet
- * buffers in a form of a ring. The routine must be called after port
- * initialization routine and before port start routine.
- * The Ethernet SDMA engine uses CPU bus addresses to access the various
- * devices in the system (i.e. DRAM). This function uses the ethernet
- * struct 'virtual to physical' routine (set by the user) to set the ring
- * with physical addresses.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port Control srtuct.
- *
- * OUTPUT:
- * The routine updates the Ethernet port control struct with information
- * regarding the Tx descriptors and buffers.
- *
- * RETURN:
- * None.
- */
-static void ether_init_tx_desc_ring(struct mv643xx_private *mp)
-{
- int tx_desc_num = mp->tx_ring_size;
- struct eth_tx_desc *p_tx_desc;
- int i;
+ cmd_sts |= GEN_TCP_UDP_CHECKSUM |
+ GEN_IP_V4_CHECKSUM |
+ ip_hdr(skb)->ihl << TX_IHL_SHIFT;
- /* Initialize the next_desc_ptr links in the Tx descriptors ring */
- p_tx_desc = (struct eth_tx_desc *)mp->p_tx_desc_area;
- for (i = 0; i < tx_desc_num; i++) {
- p_tx_desc[i].next_desc_ptr = mp->tx_desc_dma +
- ((i + 1) % tx_desc_num) * sizeof(struct eth_tx_desc);
+ switch (ip_hdr(skb)->protocol) {
+ case IPPROTO_UDP:
+ cmd_sts |= UDP_FRAME;
+ desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
+ break;
+ case IPPROTO_TCP:
+ desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
+ break;
+ default:
+ BUG();
+ }
+ } else {
+ /* Errata BTS #50, IHL must be 5 if no HW checksum */
+ cmd_sts |= 5 << TX_IHL_SHIFT;
+ desc->l4i_chk = 0;
}
- mp->tx_curr_desc_q = 0;
- mp->tx_used_desc_q = 0;
+ /* ensure all other descriptors are written before first cmd_sts */
+ wmb();
+ desc->cmd_sts = cmd_sts;
+
+ /* ensure all descriptors are written before poking hardware */
+ wmb();
+ txq_enable(txq);
- mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc);
+ txq->tx_desc_count += nr_frags + 1;
}
-static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- int err;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct tx_queue *txq;
+ unsigned long flags;
- spin_lock_irq(&mp->lock);
- err = mii_ethtool_sset(&mp->mii, cmd);
- spin_unlock_irq(&mp->lock);
+ if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) {
+ stats->tx_dropped++;
+ dev_printk(KERN_DEBUG, &dev->dev,
+ "failed to linearize skb with tiny "
+ "unaligned fragment\n");
+ return NETDEV_TX_BUSY;
+ }
- return err;
-}
+ spin_lock_irqsave(&mp->lock, flags);
-static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct mv643xx_private *mp = netdev_priv(dev);
- int err;
+ txq = mp->txq + mp->txq_primary;
- spin_lock_irq(&mp->lock);
- err = mii_ethtool_gset(&mp->mii, cmd);
- spin_unlock_irq(&mp->lock);
+ if (txq->tx_ring_size - txq->tx_desc_count < MAX_DESCS_PER_SKB) {
+ spin_unlock_irqrestore(&mp->lock, flags);
+ if (txq->index == mp->txq_primary && net_ratelimit())
+ dev_printk(KERN_ERR, &dev->dev,
+ "primary tx queue full?!\n");
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
- /* The PHY may support 1000baseT_Half, but the mv643xx does not */
- cmd->supported &= ~SUPPORTED_1000baseT_Half;
- cmd->advertising &= ~ADVERTISED_1000baseT_Half;
+ txq_submit_skb(txq, skb);
+ stats->tx_bytes += skb->len;
+ stats->tx_packets++;
+ dev->trans_start = jiffies;
- return err;
+ if (txq->index == mp->txq_primary) {
+ int entries_left;
+
+ entries_left = txq->tx_ring_size - txq->tx_desc_count;
+ if (entries_left < MAX_DESCS_PER_SKB)
+ netif_stop_queue(dev);
+ }
+
+ spin_unlock_irqrestore(&mp->lock, flags);
+
+ return NETDEV_TX_OK;
}
+
+/* tx rate control **********************************************************/
/*
- * mv643xx_eth_open
- *
- * This function is called when openning the network device. The function
- * should initialize all the hardware, initialize cyclic Rx/Tx
- * descriptors chain and buffers and allocate an IRQ to the network
- * device.
- *
- * Input : a pointer to the network device structure
- *
- * Output : zero of success , nonzero if fails.
+ * Set total maximum TX rate (shared by all TX queues for this port)
+ * to 'rate' bits per second, with a maximum burst of 'burst' bytes.
*/
-
-static int mv643xx_eth_open(struct net_device *dev)
+static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- unsigned int port_num = mp->port_num;
- unsigned int size;
- int err;
+ int token_rate;
+ int mtu;
+ int bucket_size;
- /* Clear any pending ethernet port interrupts */
- wrl(mp, INTERRUPT_CAUSE_REG(port_num), 0);
- wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
- /* wait for previous write to complete */
- rdl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num));
+ token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000);
+ if (token_rate > 1023)
+ token_rate = 1023;
- err = request_irq(dev->irq, mv643xx_eth_int_handler,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
- if (err) {
- printk(KERN_ERR "%s: Can not assign IRQ\n", dev->name);
- return -EAGAIN;
- }
+ mtu = (mp->dev->mtu + 255) >> 8;
+ if (mtu > 63)
+ mtu = 63;
- eth_port_init(mp);
+ bucket_size = (burst + 255) >> 8;
+ if (bucket_size > 65535)
+ bucket_size = 65535;
- memset(&mp->timeout, 0, sizeof(struct timer_list));
- mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper;
- mp->timeout.data = (unsigned long)dev;
-
- /* Allocate RX and TX skb rings */
- mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size,
- GFP_KERNEL);
- if (!mp->rx_skb) {
- printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name);
- err = -ENOMEM;
- goto out_free_irq;
- }
- mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size,
- GFP_KERNEL);
- if (!mp->tx_skb) {
- printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name);
- err = -ENOMEM;
- goto out_free_rx_skb;
+ if (mp->shared->tx_bw_control_moved) {
+ wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate);
+ wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu);
+ wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size);
+ } else {
+ wrl(mp, TX_BW_RATE(mp->port_num), token_rate);
+ wrl(mp, TX_BW_MTU(mp->port_num), mtu);
+ wrl(mp, TX_BW_BURST(mp->port_num), bucket_size);
}
+}
- /* Allocate TX ring */
- mp->tx_desc_count = 0;
- size = mp->tx_ring_size * sizeof(struct eth_tx_desc);
- mp->tx_desc_area_size = size;
-
- if (mp->tx_sram_size) {
- mp->p_tx_desc_area = ioremap(mp->tx_sram_addr,
- mp->tx_sram_size);
- mp->tx_desc_dma = mp->tx_sram_addr;
- } else
- mp->p_tx_desc_area = dma_alloc_coherent(NULL, size,
- &mp->tx_desc_dma,
- GFP_KERNEL);
+static void txq_set_rate(struct tx_queue *txq, int rate, int burst)
+{
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ int token_rate;
+ int bucket_size;
- if (!mp->p_tx_desc_area) {
- printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
- dev->name, size);
- err = -ENOMEM;
- goto out_free_tx_skb;
- }
- BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */
- memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size);
-
- ether_init_tx_desc_ring(mp);
-
- /* Allocate RX ring */
- mp->rx_desc_count = 0;
- size = mp->rx_ring_size * sizeof(struct eth_rx_desc);
- mp->rx_desc_area_size = size;
-
- if (mp->rx_sram_size) {
- mp->p_rx_desc_area = ioremap(mp->rx_sram_addr,
- mp->rx_sram_size);
- mp->rx_desc_dma = mp->rx_sram_addr;
- } else
- mp->p_rx_desc_area = dma_alloc_coherent(NULL, size,
- &mp->rx_desc_dma,
- GFP_KERNEL);
+ token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000);
+ if (token_rate > 1023)
+ token_rate = 1023;
- if (!mp->p_rx_desc_area) {
- printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n",
- dev->name, size);
- printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
- dev->name);
- if (mp->rx_sram_size)
- iounmap(mp->p_tx_desc_area);
- else
- dma_free_coherent(NULL, mp->tx_desc_area_size,
- mp->p_tx_desc_area, mp->tx_desc_dma);
- err = -ENOMEM;
- goto out_free_tx_skb;
- }
- memset((void *)mp->p_rx_desc_area, 0, size);
+ bucket_size = (burst + 255) >> 8;
+ if (bucket_size > 65535)
+ bucket_size = 65535;
- ether_init_rx_desc_ring(mp);
-
- mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */
+ wrl(mp, TXQ_BW_TOKENS(mp->port_num, txq->index), token_rate << 14);
+ wrl(mp, TXQ_BW_CONF(mp->port_num, txq->index),
+ (bucket_size << 10) | token_rate);
+}
-#ifdef MV643XX_NAPI
- napi_enable(&mp->napi);
-#endif
+static void txq_set_fixed_prio_mode(struct tx_queue *txq)
+{
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ int off;
+ u32 val;
- eth_port_start(dev);
+ /*
+ * Turn on fixed priority mode.
+ */
+ if (mp->shared->tx_bw_control_moved)
+ off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
+ else
+ off = TXQ_FIX_PRIO_CONF(mp->port_num);
- /* Interrupt Coalescing */
+ val = rdl(mp, off);
+ val |= 1 << txq->index;
+ wrl(mp, off, val);
+}
-#ifdef MV643XX_COAL
- mp->rx_int_coal =
- eth_port_set_rx_coal(mp, MV643XX_RX_COAL);
-#endif
+static void txq_set_wrr(struct tx_queue *txq, int weight)
+{
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ int off;
+ u32 val;
- mp->tx_int_coal =
- eth_port_set_tx_coal(mp, MV643XX_TX_COAL);
+ /*
+ * Turn off fixed priority mode.
+ */
+ if (mp->shared->tx_bw_control_moved)
+ off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
+ else
+ off = TXQ_FIX_PRIO_CONF(mp->port_num);
- /* Unmask phy and link status changes interrupts */
- wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT);
+ val = rdl(mp, off);
+ val &= ~(1 << txq->index);
+ wrl(mp, off, val);
- /* Unmask RX buffer and TX end interrupt */
- wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
+ /*
+ * Configure WRR weight for this queue.
+ */
+ off = TXQ_BW_WRR_CONF(mp->port_num, txq->index);
- return 0;
+ val = rdl(mp, off);
+ val = (val & ~0xff) | (weight & 0xff);
+ wrl(mp, off, val);
+}
-out_free_tx_skb:
- kfree(mp->tx_skb);
-out_free_rx_skb:
- kfree(mp->rx_skb);
-out_free_irq:
- free_irq(dev->irq, dev);
- return err;
-}
+/* mii management interface *************************************************/
+#define SMI_BUSY 0x10000000
+#define SMI_READ_VALID 0x08000000
+#define SMI_OPCODE_READ 0x04000000
+#define SMI_OPCODE_WRITE 0x00000000
-static void mv643xx_eth_free_tx_rings(struct net_device *dev)
+static void smi_reg_read(struct mv643xx_eth_private *mp, unsigned int addr,
+ unsigned int reg, unsigned int *value)
{
- struct mv643xx_private *mp = netdev_priv(dev);
+ void __iomem *smi_reg = mp->shared_smi->base + SMI_REG;
+ unsigned long flags;
+ int i;
- /* Stop Tx Queues */
- mv643xx_eth_port_disable_tx(mp);
+ /* the SMI register is a shared resource */
+ spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
- /* Free outstanding skb's on TX ring */
- mv643xx_eth_free_all_tx_descs(dev);
+ /* wait for the SMI register to become available */
+ for (i = 0; readl(smi_reg) & SMI_BUSY; i++) {
+ if (i == 1000) {
+ printk("%s: PHY busy timeout\n", mp->dev->name);
+ goto out;
+ }
+ udelay(10);
+ }
- BUG_ON(mp->tx_used_desc_q != mp->tx_curr_desc_q);
+ writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
- /* Free TX ring */
- if (mp->tx_sram_size)
- iounmap(mp->p_tx_desc_area);
- else
- dma_free_coherent(NULL, mp->tx_desc_area_size,
- mp->p_tx_desc_area, mp->tx_desc_dma);
+ /* now wait for the data to be valid */
+ for (i = 0; !(readl(smi_reg) & SMI_READ_VALID); i++) {
+ if (i == 1000) {
+ printk("%s: PHY read timeout\n", mp->dev->name);
+ goto out;
+ }
+ udelay(10);
+ }
+
+ *value = readl(smi_reg) & 0xffff;
+out:
+ spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
}
-static void mv643xx_eth_free_rx_rings(struct net_device *dev)
+static void smi_reg_write(struct mv643xx_eth_private *mp,
+ unsigned int addr,
+ unsigned int reg, unsigned int value)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- int curr;
+ void __iomem *smi_reg = mp->shared_smi->base + SMI_REG;
+ unsigned long flags;
+ int i;
- /* Stop RX Queues */
- mv643xx_eth_port_disable_rx(mp);
+ /* the SMI register is a shared resource */
+ spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
- /* Free preallocated skb's on RX rings */
- for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) {
- if (mp->rx_skb[curr]) {
- dev_kfree_skb(mp->rx_skb[curr]);
- mp->rx_desc_count--;
+ /* wait for the SMI register to become available */
+ for (i = 0; readl(smi_reg) & SMI_BUSY; i++) {
+ if (i == 1000) {
+ printk("%s: PHY busy timeout\n", mp->dev->name);
+ goto out;
}
+ udelay(10);
}
- if (mp->rx_desc_count)
- printk(KERN_ERR
- "%s: Error in freeing Rx Ring. %d skb's still"
- " stuck in RX Ring - ignoring them\n", dev->name,
- mp->rx_desc_count);
- /* Free RX ring */
- if (mp->rx_sram_size)
- iounmap(mp->p_rx_desc_area);
- else
- dma_free_coherent(NULL, mp->rx_desc_area_size,
- mp->p_rx_desc_area, mp->rx_desc_dma);
+ writel(SMI_OPCODE_WRITE | (reg << 21) |
+ (addr << 16) | (value & 0xffff), smi_reg);
+out:
+ spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
}
-/*
- * mv643xx_eth_stop
- *
- * This function is used when closing the network device.
- * It updates the hardware,
- * release all memory that holds buffers and descriptors and release the IRQ.
- * Input : a pointer to the device structure
- * Output : zero if success , nonzero if fails
- */
-static int mv643xx_eth_stop(struct net_device *dev)
+/* mib counters *************************************************************/
+static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- unsigned int port_num = mp->port_num;
+ return rdl(mp, MIB_COUNTERS(mp->port_num) + offset);
+}
- /* Mask all interrupts on ethernet port */
- wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
- /* wait for previous write to complete */
- rdl(mp, INTERRUPT_MASK_REG(port_num));
+static void mib_counters_clear(struct mv643xx_eth_private *mp)
+{
+ int i;
-#ifdef MV643XX_NAPI
- napi_disable(&mp->napi);
-#endif
- netif_carrier_off(dev);
- netif_stop_queue(dev);
+ for (i = 0; i < 0x80; i += 4)
+ mib_read(mp, i);
+}
+
+static void mib_counters_update(struct mv643xx_eth_private *mp)
+{
+ struct mib_counters *p = &mp->mib_counters;
+
+ p->good_octets_received += mib_read(mp, 0x00);
+ p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
+ p->bad_octets_received += mib_read(mp, 0x08);
+ p->internal_mac_transmit_err += mib_read(mp, 0x0c);
+ p->good_frames_received += mib_read(mp, 0x10);
+ p->bad_frames_received += mib_read(mp, 0x14);
+ p->broadcast_frames_received += mib_read(mp, 0x18);
+ p->multicast_frames_received += mib_read(mp, 0x1c);
+ p->frames_64_octets += mib_read(mp, 0x20);
+ p->frames_65_to_127_octets += mib_read(mp, 0x24);
+ p->frames_128_to_255_octets += mib_read(mp, 0x28);
+ p->frames_256_to_511_octets += mib_read(mp, 0x2c);
+ p->frames_512_to_1023_octets += mib_read(mp, 0x30);
+ p->frames_1024_to_max_octets += mib_read(mp, 0x34);
+ p->good_octets_sent += mib_read(mp, 0x38);
+ p->good_octets_sent += (u64)mib_read(mp, 0x3c) << 32;
+ p->good_frames_sent += mib_read(mp, 0x40);
+ p->excessive_collision += mib_read(mp, 0x44);
+ p->multicast_frames_sent += mib_read(mp, 0x48);
+ p->broadcast_frames_sent += mib_read(mp, 0x4c);
+ p->unrec_mac_control_received += mib_read(mp, 0x50);
+ p->fc_sent += mib_read(mp, 0x54);
+ p->good_fc_received += mib_read(mp, 0x58);
+ p->bad_fc_received += mib_read(mp, 0x5c);
+ p->undersize_received += mib_read(mp, 0x60);
+ p->fragments_received += mib_read(mp, 0x64);
+ p->oversize_received += mib_read(mp, 0x68);
+ p->jabber_received += mib_read(mp, 0x6c);
+ p->mac_receive_error += mib_read(mp, 0x70);
+ p->bad_crc_event += mib_read(mp, 0x74);
+ p->collision += mib_read(mp, 0x78);
+ p->late_collision += mib_read(mp, 0x7c);
+}
+
+
+/* ethtool ******************************************************************/
+struct mv643xx_eth_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int netdev_off;
+ int mp_off;
+};
+
+#define SSTAT(m) \
+ { #m, FIELD_SIZEOF(struct net_device_stats, m), \
+ offsetof(struct net_device, stats.m), -1 }
+
+#define MIBSTAT(m) \
+ { #m, FIELD_SIZEOF(struct mib_counters, m), \
+ -1, offsetof(struct mv643xx_eth_private, mib_counters.m) }
+
+static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
+ SSTAT(rx_packets),
+ SSTAT(tx_packets),
+ SSTAT(rx_bytes),
+ SSTAT(tx_bytes),
+ SSTAT(rx_errors),
+ SSTAT(tx_errors),
+ SSTAT(rx_dropped),
+ SSTAT(tx_dropped),
+ MIBSTAT(good_octets_received),
+ MIBSTAT(bad_octets_received),
+ MIBSTAT(internal_mac_transmit_err),
+ MIBSTAT(good_frames_received),
+ MIBSTAT(bad_frames_received),
+ MIBSTAT(broadcast_frames_received),
+ MIBSTAT(multicast_frames_received),
+ MIBSTAT(frames_64_octets),
+ MIBSTAT(frames_65_to_127_octets),
+ MIBSTAT(frames_128_to_255_octets),
+ MIBSTAT(frames_256_to_511_octets),
+ MIBSTAT(frames_512_to_1023_octets),
+ MIBSTAT(frames_1024_to_max_octets),
+ MIBSTAT(good_octets_sent),
+ MIBSTAT(good_frames_sent),
+ MIBSTAT(excessive_collision),
+ MIBSTAT(multicast_frames_sent),
+ MIBSTAT(broadcast_frames_sent),
+ MIBSTAT(unrec_mac_control_received),
+ MIBSTAT(fc_sent),
+ MIBSTAT(good_fc_received),
+ MIBSTAT(bad_fc_received),
+ MIBSTAT(undersize_received),
+ MIBSTAT(fragments_received),
+ MIBSTAT(oversize_received),
+ MIBSTAT(jabber_received),
+ MIBSTAT(mac_receive_error),
+ MIBSTAT(bad_crc_event),
+ MIBSTAT(collision),
+ MIBSTAT(late_collision),
+};
- eth_port_reset(mp);
+static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ int err;
- mv643xx_eth_free_tx_rings(dev);
- mv643xx_eth_free_rx_rings(dev);
+ spin_lock_irq(&mp->lock);
+ err = mii_ethtool_gset(&mp->mii, cmd);
+ spin_unlock_irq(&mp->lock);
- free_irq(dev->irq, dev);
+ /*
+ * The MAC does not support 1000baseT_Half.
+ */
+ cmd->supported &= ~SUPPORTED_1000baseT_Half;
+ cmd->advertising &= ~ADVERTISED_1000baseT_Half;
+
+ return err;
+}
+
+static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ cmd->supported = SUPPORTED_MII;
+ cmd->advertising = ADVERTISED_MII;
+ cmd->speed = SPEED_1000;
+ cmd->duplex = DUPLEX_FULL;
+ cmd->port = PORT_MII;
+ cmd->phy_address = 0;
+ cmd->transceiver = XCVR_INTERNAL;
+ cmd->autoneg = AUTONEG_DISABLE;
+ cmd->maxtxpkt = 1;
+ cmd->maxrxpkt = 1;
return 0;
}
-#ifdef MV643XX_NAPI
-/*
- * mv643xx_poll
- *
- * This function is used in case of NAPI
- */
-static int mv643xx_poll(struct napi_struct *napi, int budget)
+static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct mv643xx_private *mp = container_of(napi, struct mv643xx_private, napi);
- struct net_device *dev = mp->dev;
- unsigned int port_num = mp->port_num;
- int work_done;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ int err;
-#ifdef MV643XX_TX_FAST_REFILL
- if (++mp->tx_clean_threshold > 5) {
- mv643xx_eth_free_completed_tx_descs(dev);
- mp->tx_clean_threshold = 0;
- }
-#endif
+ /*
+ * The MAC does not support 1000baseT_Half.
+ */
+ cmd->advertising &= ~ADVERTISED_1000baseT_Half;
- work_done = 0;
- if ((rdl(mp, RX_CURRENT_QUEUE_DESC_PTR_0(port_num)))
- != (u32) mp->rx_used_desc_q)
- work_done = mv643xx_eth_receive_queue(dev, budget);
+ spin_lock_irq(&mp->lock);
+ err = mii_ethtool_sset(&mp->mii, cmd);
+ spin_unlock_irq(&mp->lock);
- if (work_done < budget) {
- netif_rx_complete(dev, napi);
- wrl(mp, INTERRUPT_CAUSE_REG(port_num), 0);
- wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
- wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
- }
+ return err;
+}
- return work_done;
+static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ return -EINVAL;
}
-#endif
-/**
- * has_tiny_unaligned_frags - check if skb has any small, unaligned fragments
- *
- * Hardware can't handle unaligned fragments smaller than 9 bytes.
- * This helper function detects that case.
- */
+static void mv643xx_eth_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strncpy(drvinfo->driver, mv643xx_eth_driver_name, 32);
+ strncpy(drvinfo->version, mv643xx_eth_driver_version, 32);
+ strncpy(drvinfo->fw_version, "N/A", 32);
+ strncpy(drvinfo->bus_info, "platform", 32);
+ drvinfo->n_stats = ARRAY_SIZE(mv643xx_eth_stats);
+}
-static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
+static int mv643xx_eth_nway_reset(struct net_device *dev)
{
- unsigned int frag;
- skb_frag_t *fragp;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
- for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
- fragp = &skb_shinfo(skb)->frags[frag];
- if (fragp->size <= 8 && fragp->page_offset & 0x7)
- return 1;
- }
- return 0;
+ return mii_nway_restart(&mp->mii);
}
-/**
- * eth_alloc_tx_desc_index - return the index of the next available tx desc
- */
-static int eth_alloc_tx_desc_index(struct mv643xx_private *mp)
+static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
{
- int tx_desc_curr;
-
- BUG_ON(mp->tx_desc_count >= mp->tx_ring_size);
+ return -EINVAL;
+}
- tx_desc_curr = mp->tx_curr_desc_q;
- mp->tx_curr_desc_q = (tx_desc_curr + 1) % mp->tx_ring_size;
+static u32 mv643xx_eth_get_link(struct net_device *dev)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
- BUG_ON(mp->tx_curr_desc_q == mp->tx_used_desc_q);
+ return mii_link_ok(&mp->mii);
+}
- return tx_desc_curr;
+static u32 mv643xx_eth_get_link_phyless(struct net_device *dev)
+{
+ return 1;
}
-/**
- * eth_tx_fill_frag_descs - fill tx hw descriptors for an skb's fragments.
- *
- * Ensure the data for each fragment to be transmitted is mapped properly,
- * then fill in descriptors in the tx hw queue.
- */
-static void eth_tx_fill_frag_descs(struct mv643xx_private *mp,
- struct sk_buff *skb)
+static void mv643xx_eth_get_strings(struct net_device *dev,
+ uint32_t stringset, uint8_t *data)
{
- int frag;
- int tx_index;
- struct eth_tx_desc *desc;
+ int i;
- for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
- skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
-
- tx_index = eth_alloc_tx_desc_index(mp);
- desc = &mp->p_tx_desc_area[tx_index];
-
- desc->cmd_sts = ETH_BUFFER_OWNED_BY_DMA;
- /* Last Frag enables interrupt and frees the skb */
- if (frag == (skb_shinfo(skb)->nr_frags - 1)) {
- desc->cmd_sts |= ETH_ZERO_PADDING |
- ETH_TX_LAST_DESC |
- ETH_TX_ENABLE_INTERRUPT;
- mp->tx_skb[tx_index] = skb;
- } else
- mp->tx_skb[tx_index] = NULL;
-
- desc = &mp->p_tx_desc_area[tx_index];
- desc->l4i_chk = 0;
- desc->byte_cnt = this_frag->size;
- desc->buf_ptr = dma_map_page(NULL, this_frag->page,
- this_frag->page_offset,
- this_frag->size,
- DMA_TO_DEVICE);
+ if (stringset == ETH_SS_STATS) {
+ for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
+ mv643xx_eth_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ }
}
}
-static inline __be16 sum16_as_be(__sum16 sum)
+static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats,
+ uint64_t *data)
{
- return (__force __be16)sum;
-}
+ struct mv643xx_eth_private *mp = dev->priv;
+ int i;
-/**
- * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw
- *
- * Ensure the data for an skb to be transmitted is mapped properly,
- * then fill in descriptors in the tx hw queue and start the hardware.
- */
-static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
- struct sk_buff *skb)
-{
- int tx_index;
- struct eth_tx_desc *desc;
- u32 cmd_sts;
- int length;
- int nr_frags = skb_shinfo(skb)->nr_frags;
+ mib_counters_update(mp);
- cmd_sts = ETH_TX_FIRST_DESC | ETH_GEN_CRC | ETH_BUFFER_OWNED_BY_DMA;
+ for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {
+ const struct mv643xx_eth_stats *stat;
+ void *p;
- tx_index = eth_alloc_tx_desc_index(mp);
- desc = &mp->p_tx_desc_area[tx_index];
+ stat = mv643xx_eth_stats + i;
- if (nr_frags) {
- eth_tx_fill_frag_descs(mp, skb);
+ if (stat->netdev_off >= 0)
+ p = ((void *)mp->dev) + stat->netdev_off;
+ else
+ p = ((void *)mp) + stat->mp_off;
- length = skb_headlen(skb);
- mp->tx_skb[tx_index] = NULL;
- } else {
- cmd_sts |= ETH_ZERO_PADDING |
- ETH_TX_LAST_DESC |
- ETH_TX_ENABLE_INTERRUPT;
- length = skb->len;
- mp->tx_skb[tx_index] = skb;
+ data[i] = (stat->sizeof_stat == 8) ?
+ *(uint64_t *)p : *(uint32_t *)p;
}
+}
- desc->byte_cnt = length;
- desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+static int mv643xx_eth_get_sset_count(struct net_device *dev, int sset)
+{
+ if (sset == ETH_SS_STATS)
+ return ARRAY_SIZE(mv643xx_eth_stats);
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- BUG_ON(skb->protocol != htons(ETH_P_IP));
+ return -EOPNOTSUPP;
+}
- cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
- ETH_GEN_IP_V_4_CHECKSUM |
- ip_hdr(skb)->ihl << ETH_TX_IHL_SHIFT;
+static const struct ethtool_ops mv643xx_eth_ethtool_ops = {
+ .get_settings = mv643xx_eth_get_settings,
+ .set_settings = mv643xx_eth_set_settings,
+ .get_drvinfo = mv643xx_eth_get_drvinfo,
+ .nway_reset = mv643xx_eth_nway_reset,
+ .get_link = mv643xx_eth_get_link,
+ .set_sg = ethtool_op_set_sg,
+ .get_strings = mv643xx_eth_get_strings,
+ .get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
+ .get_sset_count = mv643xx_eth_get_sset_count,
+};
- switch (ip_hdr(skb)->protocol) {
- case IPPROTO_UDP:
- cmd_sts |= ETH_UDP_FRAME;
- desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
- break;
- case IPPROTO_TCP:
- desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
- break;
- default:
- BUG();
- }
- } else {
- /* Errata BTS #50, IHL must be 5 if no HW checksum */
- cmd_sts |= 5 << ETH_TX_IHL_SHIFT;
- desc->l4i_chk = 0;
- }
+static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
+ .get_settings = mv643xx_eth_get_settings_phyless,
+ .set_settings = mv643xx_eth_set_settings_phyless,
+ .get_drvinfo = mv643xx_eth_get_drvinfo,
+ .nway_reset = mv643xx_eth_nway_reset_phyless,
+ .get_link = mv643xx_eth_get_link_phyless,
+ .set_sg = ethtool_op_set_sg,
+ .get_strings = mv643xx_eth_get_strings,
+ .get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
+ .get_sset_count = mv643xx_eth_get_sset_count,
+};
- /* ensure all other descriptors are written before first cmd_sts */
- wmb();
- desc->cmd_sts = cmd_sts;
- /* ensure all descriptors are written before poking hardware */
- wmb();
- mv643xx_eth_port_enable_tx(mp, ETH_TX_QUEUES_ENABLED);
+/* address handling *********************************************************/
+static void uc_addr_get(struct mv643xx_eth_private *mp, unsigned char *addr)
+{
+ unsigned int mac_h;
+ unsigned int mac_l;
+
+ mac_h = rdl(mp, MAC_ADDR_HIGH(mp->port_num));
+ mac_l = rdl(mp, MAC_ADDR_LOW(mp->port_num));
- mp->tx_desc_count += nr_frags + 1;
+ addr[0] = (mac_h >> 24) & 0xff;
+ addr[1] = (mac_h >> 16) & 0xff;
+ addr[2] = (mac_h >> 8) & 0xff;
+ addr[3] = mac_h & 0xff;
+ addr[4] = (mac_l >> 8) & 0xff;
+ addr[5] = mac_l & 0xff;
}
-/**
- * mv643xx_eth_start_xmit - queue an skb to the hardware for transmission
- *
- */
-static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static void init_mac_tables(struct mv643xx_eth_private *mp)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- struct net_device_stats *stats = &dev->stats;
- unsigned long flags;
-
- BUG_ON(netif_queue_stopped(dev));
+ int i;
- if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) {
- stats->tx_dropped++;
- printk(KERN_DEBUG "%s: failed to linearize tiny "
- "unaligned fragment\n", dev->name);
- return NETDEV_TX_BUSY;
+ for (i = 0; i < 0x100; i += 4) {
+ wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i, 0);
+ wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i, 0);
}
- spin_lock_irqsave(&mp->lock, flags);
+ for (i = 0; i < 0x10; i += 4)
+ wrl(mp, UNICAST_TABLE(mp->port_num) + i, 0);
+}
- if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) {
- printk(KERN_ERR "%s: transmit with queue full\n", dev->name);
- netif_stop_queue(dev);
- spin_unlock_irqrestore(&mp->lock, flags);
- return NETDEV_TX_BUSY;
- }
+static void set_filter_table_entry(struct mv643xx_eth_private *mp,
+ int table, unsigned char entry)
+{
+ unsigned int table_reg;
- eth_tx_submit_descs_for_skb(mp, skb);
- stats->tx_bytes += skb->len;
- stats->tx_packets++;
- dev->trans_start = jiffies;
+ /* Set "accepts frame bit" at specified table entry */
+ table_reg = rdl(mp, table + (entry & 0xfc));
+ table_reg |= 0x01 << (8 * (entry & 3));
+ wrl(mp, table + (entry & 0xfc), table_reg);
+}
- if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB)
- netif_stop_queue(dev);
+static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr)
+{
+ unsigned int mac_h;
+ unsigned int mac_l;
+ int table;
- spin_unlock_irqrestore(&mp->lock, flags);
+ mac_l = (addr[4] << 8) | addr[5];
+ mac_h = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
- return NETDEV_TX_OK;
+ wrl(mp, MAC_ADDR_LOW(mp->port_num), mac_l);
+ wrl(mp, MAC_ADDR_HIGH(mp->port_num), mac_h);
+
+ table = UNICAST_TABLE(mp->port_num);
+ set_filter_table_entry(mp, table, addr[5] & 0x0f);
}
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void mv643xx_netpoll(struct net_device *netdev)
+static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
{
- struct mv643xx_private *mp = netdev_priv(netdev);
- int port_num = mp->port_num;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
- wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
- /* wait for previous write to complete */
- rdl(mp, INTERRUPT_MASK_REG(port_num));
+ /* +2 is for the offset of the HW addr type */
+ memcpy(dev->dev_addr, addr + 2, 6);
- mv643xx_eth_int_handler(netdev->irq, netdev);
+ init_mac_tables(mp);
+ uc_addr_set(mp, dev->dev_addr);
- wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
+ return 0;
}
-#endif
-static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address,
- int speed, int duplex,
- struct ethtool_cmd *cmd)
+static int addr_crc(unsigned char *addr)
{
- struct mv643xx_private *mp = netdev_priv(dev);
+ int crc = 0;
+ int i;
- memset(cmd, 0, sizeof(*cmd));
+ for (i = 0; i < 6; i++) {
+ int j;
- cmd->port = PORT_MII;
- cmd->transceiver = XCVR_INTERNAL;
- cmd->phy_address = phy_address;
-
- if (speed == 0) {
- cmd->autoneg = AUTONEG_ENABLE;
- /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */
- cmd->speed = SPEED_100;
- cmd->advertising = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full;
- if (mp->mii.supports_gmii)
- cmd->advertising |= ADVERTISED_1000baseT_Full;
- } else {
- cmd->autoneg = AUTONEG_DISABLE;
- cmd->speed = speed;
- cmd->duplex = duplex;
+ crc = (crc ^ addr[i]) << 8;
+ for (j = 7; j >= 0; j--) {
+ if (crc & (0x100 << j))
+ crc ^= 0x107 << j;
+ }
}
+
+ return crc;
}
-/*/
- * mv643xx_eth_probe
- *
- * First function called after registering the network device.
- * It's purpose is to initialize the device as an ethernet device,
- * fill the ethernet device structure with pointers * to functions,
- * and set the MAC address of the interface
- *
- * Input : struct device *
- * Output : -ENOMEM if failed , 0 if success
- */
-static int mv643xx_eth_probe(struct platform_device *pdev)
+static void mv643xx_eth_set_rx_mode(struct net_device *dev)
{
- struct mv643xx_eth_platform_data *pd;
- int port_num;
- struct mv643xx_private *mp;
- struct net_device *dev;
- u8 *p;
- struct resource *res;
- int err;
- struct ethtool_cmd cmd;
- int duplex = DUPLEX_HALF;
- int speed = 0; /* default to auto-negotiation */
- DECLARE_MAC_BUF(mac);
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ u32 port_config;
+ struct dev_addr_list *addr;
+ int i;
- pd = pdev->dev.platform_data;
- if (pd == NULL) {
- printk(KERN_ERR "No mv643xx_eth_platform_data\n");
- return -ENODEV;
+ port_config = rdl(mp, PORT_CONFIG(mp->port_num));
+ if (dev->flags & IFF_PROMISC)
+ port_config |= UNICAST_PROMISCUOUS_MODE;
+ else
+ port_config &= ~UNICAST_PROMISCUOUS_MODE;
+ wrl(mp, PORT_CONFIG(mp->port_num), port_config);
+
+ if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+ int port_num = mp->port_num;
+ u32 accept = 0x01010101;
+
+ for (i = 0; i < 0x100; i += 4) {
+ wrl(mp, SPECIAL_MCAST_TABLE(port_num) + i, accept);
+ wrl(mp, OTHER_MCAST_TABLE(port_num) + i, accept);
+ }
+ return;
}
- if (pd->shared == NULL) {
- printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n");
- return -ENODEV;
+ for (i = 0; i < 0x100; i += 4) {
+ wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i, 0);
+ wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i, 0);
}
- dev = alloc_etherdev(sizeof(struct mv643xx_private));
- if (!dev)
- return -ENOMEM;
+ for (addr = dev->mc_list; addr != NULL; addr = addr->next) {
+ u8 *a = addr->da_addr;
+ int table;
- platform_set_drvdata(pdev, dev);
+ if (addr->da_addrlen != 6)
+ continue;
- mp = netdev_priv(dev);
- mp->dev = dev;
-#ifdef MV643XX_NAPI
- netif_napi_add(dev, &mp->napi, mv643xx_poll, 64);
-#endif
+ if (memcmp(a, "\x01\x00\x5e\x00\x00", 5) == 0) {
+ table = SPECIAL_MCAST_TABLE(mp->port_num);
+ set_filter_table_entry(mp, table, a[5]);
+ } else {
+ int crc = addr_crc(a);
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- BUG_ON(!res);
- dev->irq = res->start;
+ table = OTHER_MCAST_TABLE(mp->port_num);
+ set_filter_table_entry(mp, table, crc);
+ }
+ }
+}
- dev->open = mv643xx_eth_open;
- dev->stop = mv643xx_eth_stop;
- dev->hard_start_xmit = mv643xx_eth_start_xmit;
- dev->set_mac_address = mv643xx_eth_set_mac_address;
- dev->set_multicast_list = mv643xx_eth_set_rx_mode;
- /* No need to Tx Timeout */
- dev->tx_timeout = mv643xx_eth_tx_timeout;
+/* rx/tx queue initialisation ***********************************************/
+static int rxq_init(struct mv643xx_eth_private *mp, int index)
+{
+ struct rx_queue *rxq = mp->rxq + index;
+ struct rx_desc *rx_desc;
+ int size;
+ int i;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = mv643xx_netpoll;
-#endif
+ rxq->index = index;
- dev->watchdog_timeo = 2 * HZ;
- dev->base_addr = 0;
- dev->change_mtu = mv643xx_eth_change_mtu;
- dev->do_ioctl = mv643xx_eth_do_ioctl;
- SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops);
+ rxq->rx_ring_size = mp->default_rx_ring_size;
-#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
-#ifdef MAX_SKB_FRAGS
- /*
- * Zero copy can only work if we use Discovery II memory. Else, we will
- * have to map the buffers to ISA memory which is only 16 MB
- */
- dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
-#endif
-#endif
+ rxq->rx_desc_count = 0;
+ rxq->rx_curr_desc = 0;
+ rxq->rx_used_desc = 0;
- /* Configure the timeout task */
- INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task);
+ size = rxq->rx_ring_size * sizeof(struct rx_desc);
- spin_lock_init(&mp->lock);
+ if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size) {
+ rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr,
+ mp->rx_desc_sram_size);
+ rxq->rx_desc_dma = mp->rx_desc_sram_addr;
+ } else {
+ rxq->rx_desc_area = dma_alloc_coherent(NULL, size,
+ &rxq->rx_desc_dma,
+ GFP_KERNEL);
+ }
- mp->shared = platform_get_drvdata(pd->shared);
- port_num = mp->port_num = pd->port_number;
+ if (rxq->rx_desc_area == NULL) {
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "can't allocate rx ring (%d bytes)\n", size);
+ goto out;
+ }
+ memset(rxq->rx_desc_area, 0, size);
- if (mp->shared->win_protect)
- wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect);
+ rxq->rx_desc_area_size = size;
+ rxq->rx_skb = kmalloc(rxq->rx_ring_size * sizeof(*rxq->rx_skb),
+ GFP_KERNEL);
+ if (rxq->rx_skb == NULL) {
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "can't allocate rx skb ring\n");
+ goto out_free;
+ }
- mp->shared_smi = mp->shared;
- if (pd->shared_smi != NULL)
- mp->shared_smi = platform_get_drvdata(pd->shared_smi);
+ rx_desc = (struct rx_desc *)rxq->rx_desc_area;
+ for (i = 0; i < rxq->rx_ring_size; i++) {
+ int nexti = (i + 1) % rxq->rx_ring_size;
+ rx_desc[i].next_desc_ptr = rxq->rx_desc_dma +
+ nexti * sizeof(struct rx_desc);
+ }
- /* set default config values */
- eth_port_uc_addr_get(mp, dev->dev_addr);
- mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
- mp->tx_ring_size = PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
+ init_timer(&rxq->rx_oom);
+ rxq->rx_oom.data = (unsigned long)rxq;
+ rxq->rx_oom.function = rxq_refill_timer_wrapper;
- if (is_valid_ether_addr(pd->mac_addr))
- memcpy(dev->dev_addr, pd->mac_addr, 6);
+ return 0;
- if (pd->phy_addr || pd->force_phy_addr)
- ethernet_phy_set(mp, pd->phy_addr);
- if (pd->rx_queue_size)
- mp->rx_ring_size = pd->rx_queue_size;
+out_free:
+ if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size)
+ iounmap(rxq->rx_desc_area);
+ else
+ dma_free_coherent(NULL, size,
+ rxq->rx_desc_area,
+ rxq->rx_desc_dma);
- if (pd->tx_queue_size)
- mp->tx_ring_size = pd->tx_queue_size;
+out:
+ return -ENOMEM;
+}
- if (pd->tx_sram_size) {
- mp->tx_sram_size = pd->tx_sram_size;
- mp->tx_sram_addr = pd->tx_sram_addr;
- }
+static void rxq_deinit(struct rx_queue *rxq)
+{
+ struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
+ int i;
- if (pd->rx_sram_size) {
- mp->rx_sram_size = pd->rx_sram_size;
- mp->rx_sram_addr = pd->rx_sram_addr;
- }
+ rxq_disable(rxq);
- duplex = pd->duplex;
- speed = pd->speed;
+ del_timer_sync(&rxq->rx_oom);
- /* Hook up MII support for ethtool */
- mp->mii.dev = dev;
- mp->mii.mdio_read = mv643xx_mdio_read;
- mp->mii.mdio_write = mv643xx_mdio_write;
- mp->mii.phy_id = ethernet_phy_get(mp);
- mp->mii.phy_id_mask = 0x3f;
- mp->mii.reg_num_mask = 0x1f;
+ for (i = 0; i < rxq->rx_ring_size; i++) {
+ if (rxq->rx_skb[i]) {
+ dev_kfree_skb(rxq->rx_skb[i]);
+ rxq->rx_desc_count--;
+ }
+ }
- err = ethernet_phy_detect(mp);
- if (err) {
- pr_debug("%s: No PHY detected at addr %d\n",
- dev->name, ethernet_phy_get(mp));
- goto out;
+ if (rxq->rx_desc_count) {
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "error freeing rx ring -- %d skbs stuck\n",
+ rxq->rx_desc_count);
}
- ethernet_phy_reset(mp);
- mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
- mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd);
- mv643xx_eth_update_pscr(dev, &cmd);
- mv643xx_set_settings(dev, &cmd);
+ if (rxq->index == mp->rxq_primary &&
+ rxq->rx_desc_area_size <= mp->rx_desc_sram_size)
+ iounmap(rxq->rx_desc_area);
+ else
+ dma_free_coherent(NULL, rxq->rx_desc_area_size,
+ rxq->rx_desc_area, rxq->rx_desc_dma);
- SET_NETDEV_DEV(dev, &pdev->dev);
- err = register_netdev(dev);
- if (err)
- goto out;
+ kfree(rxq->rx_skb);
+}
- p = dev->dev_addr;
- printk(KERN_NOTICE
- "%s: port %d with MAC address %s\n",
- dev->name, port_num, print_mac(mac, p));
+static int txq_init(struct mv643xx_eth_private *mp, int index)
+{
+ struct tx_queue *txq = mp->txq + index;
+ struct tx_desc *tx_desc;
+ int size;
+ int i;
- if (dev->features & NETIF_F_SG)
- printk(KERN_NOTICE "%s: Scatter Gather Enabled\n", dev->name);
+ txq->index = index;
- if (dev->features & NETIF_F_IP_CSUM)
- printk(KERN_NOTICE "%s: TX TCP/IP Checksumming Supported\n",
- dev->name);
+ txq->tx_ring_size = mp->default_tx_ring_size;
-#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
- printk(KERN_NOTICE "%s: RX TCP/UDP Checksum Offload ON \n", dev->name);
-#endif
+ txq->tx_desc_count = 0;
+ txq->tx_curr_desc = 0;
+ txq->tx_used_desc = 0;
-#ifdef MV643XX_COAL
- printk(KERN_NOTICE "%s: TX and RX Interrupt Coalescing ON \n",
- dev->name);
-#endif
+ size = txq->tx_ring_size * sizeof(struct tx_desc);
-#ifdef MV643XX_NAPI
- printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
-#endif
+ if (index == mp->txq_primary && size <= mp->tx_desc_sram_size) {
+ txq->tx_desc_area = ioremap(mp->tx_desc_sram_addr,
+ mp->tx_desc_sram_size);
+ txq->tx_desc_dma = mp->tx_desc_sram_addr;
+ } else {
+ txq->tx_desc_area = dma_alloc_coherent(NULL, size,
+ &txq->tx_desc_dma,
+ GFP_KERNEL);
+ }
+
+ if (txq->tx_desc_area == NULL) {
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "can't allocate tx ring (%d bytes)\n", size);
+ goto out;
+ }
+ memset(txq->tx_desc_area, 0, size);
- if (mp->tx_sram_size > 0)
- printk(KERN_NOTICE "%s: Using SRAM\n", dev->name);
+ txq->tx_desc_area_size = size;
+ txq->tx_skb = kmalloc(txq->tx_ring_size * sizeof(*txq->tx_skb),
+ GFP_KERNEL);
+ if (txq->tx_skb == NULL) {
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "can't allocate tx skb ring\n");
+ goto out_free;
+ }
+
+ tx_desc = (struct tx_desc *)txq->tx_desc_area;
+ for (i = 0; i < txq->tx_ring_size; i++) {
+ int nexti = (i + 1) % txq->tx_ring_size;
+ tx_desc[i].next_desc_ptr = txq->tx_desc_dma +
+ nexti * sizeof(struct tx_desc);
+ }
return 0;
-out:
- free_netdev(dev);
- return err;
+out_free:
+ if (index == mp->txq_primary && size <= mp->tx_desc_sram_size)
+ iounmap(txq->tx_desc_area);
+ else
+ dma_free_coherent(NULL, size,
+ txq->tx_desc_area,
+ txq->tx_desc_dma);
+
+out:
+ return -ENOMEM;
}
-static int mv643xx_eth_remove(struct platform_device *pdev)
+static void txq_reclaim(struct tx_queue *txq, int force)
{
- struct net_device *dev = platform_get_drvdata(pdev);
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
+ unsigned long flags;
- unregister_netdev(dev);
- flush_scheduled_work();
+ spin_lock_irqsave(&mp->lock, flags);
+ while (txq->tx_desc_count > 0) {
+ int tx_index;
+ struct tx_desc *desc;
+ u32 cmd_sts;
+ struct sk_buff *skb;
+ dma_addr_t addr;
+ int count;
+
+ tx_index = txq->tx_used_desc;
+ desc = &txq->tx_desc_area[tx_index];
+ cmd_sts = desc->cmd_sts;
- free_netdev(dev);
- platform_set_drvdata(pdev, NULL);
- return 0;
-}
+ if (!force && (cmd_sts & BUFFER_OWNED_BY_DMA))
+ break;
-static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp,
- struct mbus_dram_target_info *dram)
-{
- void __iomem *base = msp->eth_base;
- u32 win_enable;
- u32 win_protect;
- int i;
+ txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size;
+ txq->tx_desc_count--;
- for (i = 0; i < 6; i++) {
- writel(0, base + WINDOW_BASE(i));
- writel(0, base + WINDOW_SIZE(i));
- if (i < 4)
- writel(0, base + WINDOW_REMAP_HIGH(i));
- }
+ addr = desc->buf_ptr;
+ count = desc->byte_cnt;
+ skb = txq->tx_skb[tx_index];
+ txq->tx_skb[tx_index] = NULL;
- win_enable = 0x3f;
- win_protect = 0;
+ if (cmd_sts & ERROR_SUMMARY) {
+ dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n");
+ mp->dev->stats.tx_errors++;
+ }
- for (i = 0; i < dram->num_cs; i++) {
- struct mbus_dram_window *cs = dram->cs + i;
+ /*
+ * Drop mp->lock while we free the skb.
+ */
+ spin_unlock_irqrestore(&mp->lock, flags);
- writel((cs->base & 0xffff0000) |
- (cs->mbus_attr << 8) |
- dram->mbus_dram_target_id, base + WINDOW_BASE(i));
- writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i));
+ if (cmd_sts & TX_FIRST_DESC)
+ dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
+ else
+ dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE);
- win_enable &= ~(1 << i);
- win_protect |= 3 << (2 * i);
- }
+ if (skb)
+ dev_kfree_skb_irq(skb);
- writel(win_enable, base + WINDOW_BAR_ENABLE);
- msp->win_protect = win_protect;
+ spin_lock_irqsave(&mp->lock, flags);
+ }
+ spin_unlock_irqrestore(&mp->lock, flags);
}
-static int mv643xx_eth_shared_probe(struct platform_device *pdev)
+static void txq_deinit(struct tx_queue *txq)
{
- static int mv643xx_version_printed = 0;
- struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
- struct mv643xx_shared_private *msp;
- struct resource *res;
- int ret;
+ struct mv643xx_eth_private *mp = txq_to_mp(txq);
- if (!mv643xx_version_printed++)
- printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
+ txq_disable(txq);
+ txq_reclaim(txq, 1);
- ret = -EINVAL;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL)
- goto out;
+ BUG_ON(txq->tx_used_desc != txq->tx_curr_desc);
- ret = -ENOMEM;
- msp = kmalloc(sizeof(*msp), GFP_KERNEL);
- if (msp == NULL)
- goto out;
- memset(msp, 0, sizeof(*msp));
+ if (txq->index == mp->txq_primary &&
+ txq->tx_desc_area_size <= mp->tx_desc_sram_size)
+ iounmap(txq->tx_desc_area);
+ else
+ dma_free_coherent(NULL, txq->tx_desc_area_size,
+ txq->tx_desc_area, txq->tx_desc_dma);
- msp->eth_base = ioremap(res->start, res->end - res->start + 1);
- if (msp->eth_base == NULL)
- goto out_free;
+ kfree(txq->tx_skb);
+}
- spin_lock_init(&msp->phy_lock);
- msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000;
- platform_set_drvdata(pdev, msp);
+/* netdev ops and related ***************************************************/
+static void update_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
+{
+ u32 pscr_o;
+ u32 pscr_n;
- /*
- * (Re-)program MBUS remapping windows if we are asked to.
- */
- if (pd != NULL && pd->dram != NULL)
- mv643xx_eth_conf_mbus_windows(msp, pd->dram);
+ pscr_o = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
- return 0;
+ /* clear speed, duplex and rx buffer size fields */
+ pscr_n = pscr_o & ~(SET_MII_SPEED_TO_100 |
+ SET_GMII_SPEED_TO_1000 |
+ SET_FULL_DUPLEX_MODE |
+ MAX_RX_PACKET_MASK);
-out_free:
- kfree(msp);
-out:
- return ret;
-}
+ if (speed == SPEED_1000) {
+ pscr_n |= SET_GMII_SPEED_TO_1000 | MAX_RX_PACKET_9700BYTE;
+ } else {
+ if (speed == SPEED_100)
+ pscr_n |= SET_MII_SPEED_TO_100;
+ pscr_n |= MAX_RX_PACKET_1522BYTE;
+ }
-static int mv643xx_eth_shared_remove(struct platform_device *pdev)
-{
- struct mv643xx_shared_private *msp = platform_get_drvdata(pdev);
+ if (duplex == DUPLEX_FULL)
+ pscr_n |= SET_FULL_DUPLEX_MODE;
- iounmap(msp->eth_base);
- kfree(msp);
+ if (pscr_n != pscr_o) {
+ if ((pscr_o & SERIAL_PORT_ENABLE) == 0)
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
+ else {
+ int i;
- return 0;
+ for (i = 0; i < 8; i++)
+ if (mp->txq_mask & (1 << i))
+ txq_disable(mp->txq + i);
+
+ pscr_o &= ~SERIAL_PORT_ENABLE;
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_o);
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
+
+ for (i = 0; i < 8; i++)
+ if (mp->txq_mask & (1 << i))
+ txq_enable(mp->txq + i);
+ }
+ }
}
-static void mv643xx_eth_shutdown(struct platform_device *pdev)
+static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct mv643xx_private *mp = netdev_priv(dev);
- unsigned int port_num = mp->port_num;
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ u32 int_cause;
+ u32 int_cause_ext;
+ u32 txq_active;
+
+ int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
+ (INT_TX_END | INT_RX | INT_EXT);
+ if (int_cause == 0)
+ return IRQ_NONE;
- /* Mask all interrupts on ethernet port */
- wrl(mp, INTERRUPT_MASK_REG(port_num), 0);
- rdl(mp, INTERRUPT_MASK_REG(port_num));
+ int_cause_ext = 0;
+ if (int_cause & INT_EXT) {
+ int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num))
+ & (INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);
+ wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
+ }
- eth_port_reset(mp);
-}
+ if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) {
+ if (mp->phy_addr == -1 || mii_link_ok(&mp->mii)) {
+ int i;
-static struct platform_driver mv643xx_eth_driver = {
- .probe = mv643xx_eth_probe,
- .remove = mv643xx_eth_remove,
- .shutdown = mv643xx_eth_shutdown,
- .driver = {
- .name = MV643XX_ETH_NAME,
- .owner = THIS_MODULE,
- },
-};
+ if (mp->phy_addr != -1) {
+ struct ethtool_cmd cmd;
-static struct platform_driver mv643xx_eth_shared_driver = {
- .probe = mv643xx_eth_shared_probe,
- .remove = mv643xx_eth_shared_remove,
- .driver = {
- .name = MV643XX_ETH_SHARED_NAME,
- .owner = THIS_MODULE,
- },
-};
+ mii_ethtool_gset(&mp->mii, &cmd);
+ update_pscr(mp, cmd.speed, cmd.duplex);
+ }
-/*
- * mv643xx_init_module
- *
- * Registers the network drivers into the Linux kernel
- *
- * Input : N/A
- *
- * Output : N/A
- */
-static int __init mv643xx_init_module(void)
-{
- int rc;
+ for (i = 0; i < 8; i++)
+ if (mp->txq_mask & (1 << i))
+ txq_enable(mp->txq + i);
- rc = platform_driver_register(&mv643xx_eth_shared_driver);
- if (!rc) {
- rc = platform_driver_register(&mv643xx_eth_driver);
- if (rc)
- platform_driver_unregister(&mv643xx_eth_shared_driver);
+ if (!netif_carrier_ok(dev)) {
+ netif_carrier_on(dev);
+ __txq_maybe_wake(mp->txq + mp->txq_primary);
+ }
+ } else if (netif_carrier_ok(dev)) {
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+ }
}
- return rc;
-}
-/*
- * mv643xx_cleanup_module
- *
- * Registers the network drivers into the Linux kernel
- *
- * Input : N/A
- *
- * Output : N/A
- */
-static void __exit mv643xx_cleanup_module(void)
-{
- platform_driver_unregister(&mv643xx_eth_driver);
- platform_driver_unregister(&mv643xx_eth_shared_driver);
-}
+ /*
+ * RxBuffer or RxError set for any of the 8 queues?
+ */
+#ifdef MV643XX_ETH_NAPI
+ if (int_cause & INT_RX) {
+ wrl(mp, INT_MASK(mp->port_num), 0x00000000);
+ rdl(mp, INT_MASK(mp->port_num));
-module_init(mv643xx_init_module);
-module_exit(mv643xx_cleanup_module);
+ netif_rx_schedule(dev, &mp->napi);
+ }
+#else
+ if (int_cause & INT_RX) {
+ int i;
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani"
- " and Dale Farnsworth");
-MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
-MODULE_ALIAS("platform:" MV643XX_ETH_NAME);
-MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME);
+ for (i = 7; i >= 0; i--)
+ if (mp->rxq_mask & (1 << i))
+ rxq_process(mp->rxq + i, INT_MAX);
+ }
+#endif
-/*
- * The second part is the low level driver of the gigE ethernet ports.
- */
+ txq_active = rdl(mp, TXQ_COMMAND(mp->port_num));
-/*
- * Marvell's Gigabit Ethernet controller low level driver
- *
- * DESCRIPTION:
- * This file introduce low level API to Marvell's Gigabit Ethernet
- * controller. This Gigabit Ethernet Controller driver API controls
- * 1) Operations (i.e. port init, start, reset etc').
- * 2) Data flow (i.e. port send, receive etc').
- * Each Gigabit Ethernet port is controlled via
- * struct mv643xx_private.
- * This struct includes user configuration information as well as
- * driver internal data needed for its operations.
- *
- * Supported Features:
- * - This low level driver is OS independent. Allocating memory for
- * the descriptor rings and buffers are not within the scope of
- * this driver.
- * - The user is free from Rx/Tx queue managing.
- * - This low level driver introduce functionality API that enable
- * the to operate Marvell's Gigabit Ethernet Controller in a
- * convenient way.
- * - Simple Gigabit Ethernet port operation API.
- * - Simple Gigabit Ethernet port data flow API.
- * - Data flow and operation API support per queue functionality.
- * - Support cached descriptors for better performance.
- * - Enable access to all four DRAM banks and internal SRAM memory
- * spaces.
- * - PHY access and control API.
- * - Port control register configuration API.
- * - Full control over Unicast and Multicast MAC configurations.
- *
- * Operation flow:
- *
- * Initialization phase
- * This phase complete the initialization of the the
- * mv643xx_private struct.
- * User information regarding port configuration has to be set
- * prior to calling the port initialization routine.
- *
- * In this phase any port Tx/Rx activity is halted, MIB counters
- * are cleared, PHY address is set according to user parameter and
- * access to DRAM and internal SRAM memory spaces.
- *
- * Driver ring initialization
- * Allocating memory for the descriptor rings and buffers is not
- * within the scope of this driver. Thus, the user is required to
- * allocate memory for the descriptors ring and buffers. Those
- * memory parameters are used by the Rx and Tx ring initialization
- * routines in order to curve the descriptor linked list in a form
- * of a ring.
- * Note: Pay special attention to alignment issues when using
- * cached descriptors/buffers. In this phase the driver store
- * information in the mv643xx_private struct regarding each queue
- * ring.
- *
- * Driver start
- * This phase prepares the Ethernet port for Rx and Tx activity.
- * It uses the information stored in the mv643xx_private struct to
- * initialize the various port registers.
- *
- * Data flow:
- * All packet references to/from the driver are done using
- * struct pkt_info.
- * This struct is a unified struct used with Rx and Tx operations.
- * This way the user is not required to be familiar with neither
- * Tx nor Rx descriptors structures.
- * The driver's descriptors rings are management by indexes.
- * Those indexes controls the ring resources and used to indicate
- * a SW resource error:
- * 'current'
- * This index points to the current available resource for use. For
- * example in Rx process this index will point to the descriptor
- * that will be passed to the user upon calling the receive
- * routine. In Tx process, this index will point to the descriptor
- * that will be assigned with the user packet info and transmitted.
- * 'used'
- * This index points to the descriptor that need to restore its
- * resources. For example in Rx process, using the Rx buffer return
- * API will attach the buffer returned in packet info to the
- * descriptor pointed by 'used'. In Tx process, using the Tx
- * descriptor return will merely return the user packet info with
- * the command status of the transmitted buffer pointed by the
- * 'used' index. Nevertheless, it is essential to use this routine
- * to update the 'used' index.
- * 'first'
- * This index supports Tx Scatter-Gather. It points to the first
- * descriptor of a packet assembled of multiple buffers. For
- * example when in middle of Such packet we have a Tx resource
- * error the 'curr' index get the value of 'first' to indicate
- * that the ring returned to its state before trying to transmit
- * this packet.
- *
- * Receive operation:
- * The eth_port_receive API set the packet information struct,
- * passed by the caller, with received information from the
- * 'current' SDMA descriptor.
- * It is the user responsibility to return this resource back
- * to the Rx descriptor ring to enable the reuse of this source.
- * Return Rx resource is done using the eth_rx_return_buff API.
- *
- * Prior to calling the initialization routine eth_port_init() the user
- * must set the following fields under mv643xx_private struct:
- * port_num User Ethernet port number.
- * port_config User port configuration value.
- * port_config_extend User port config extend value.
- * port_sdma_config User port SDMA config value.
- * port_serial_control User port serial control value.
- *
- * This driver data flow is done using the struct pkt_info which
- * is a unified struct for Rx and Tx operations:
- *
- * byte_cnt Tx/Rx descriptor buffer byte count.
- * l4i_chk CPU provided TCP Checksum. For Tx operation
- * only.
- * cmd_sts Tx/Rx descriptor command status.
- * buf_ptr Tx/Rx descriptor buffer pointer.
- * return_info Tx/Rx user resource return information.
- */
+ /*
+ * TxBuffer or TxError set for any of the 8 queues?
+ */
+ if (int_cause_ext & INT_EXT_TX) {
+ int i;
-/* Ethernet Port routines */
-static void eth_port_set_filter_table_entry(struct mv643xx_private *mp,
- int table, unsigned char entry);
+ for (i = 0; i < 8; i++)
+ if (mp->txq_mask & (1 << i))
+ txq_reclaim(mp->txq + i, 0);
+ }
-/*
- * eth_port_init - Initialize the Ethernet port driver
- *
- * DESCRIPTION:
- * This function prepares the ethernet port to start its activity:
- * 1) Completes the ethernet port driver struct initialization toward port
- * start routine.
- * 2) Resets the device to a quiescent state in case of warm reboot.
- * 3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
- * 4) Clean MAC tables. The reset status of those tables is unknown.
- * 5) Set PHY address.
- * Note: Call this routine prior to eth_port_start routine and after
- * setting user values in the user fields of Ethernet port control
- * struct.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet port control struct
- *
- * OUTPUT:
- * See description.
- *
- * RETURN:
- * None.
- */
-static void eth_port_init(struct mv643xx_private *mp)
-{
- mp->rx_resource_err = 0;
+ /*
+ * Any TxEnd interrupts?
+ */
+ if (int_cause & INT_TX_END) {
+ int i;
+
+ wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END));
+ for (i = 0; i < 8; i++) {
+ struct tx_queue *txq = mp->txq + i;
+ if (txq->tx_desc_count && !((txq_active >> i) & 1))
+ txq_enable(txq);
+ }
+ }
- eth_port_reset(mp);
+ /*
+ * Enough space again in the primary TX queue for a full packet?
+ */
+ if (int_cause_ext & INT_EXT_TX) {
+ struct tx_queue *txq = mp->txq + mp->txq_primary;
+ __txq_maybe_wake(txq);
+ }
- eth_port_init_mac_tables(mp);
+ return IRQ_HANDLED;
}
-/*
- * eth_port_start - Start the Ethernet port activity.
- *
- * DESCRIPTION:
- * This routine prepares the Ethernet port for Rx and Tx activity:
- * 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
- * has been initialized a descriptor's ring (using
- * ether_init_tx_desc_ring for Tx and ether_init_rx_desc_ring for Rx)
- * 2. Initialize and enable the Ethernet configuration port by writing to
- * the port's configuration and command registers.
- * 3. Initialize and enable the SDMA by writing to the SDMA's
- * configuration and command registers. After completing these steps,
- * the ethernet port SDMA can starts to perform Rx and Tx activities.
- *
- * Note: Each Rx and Tx queue descriptor's list must be initialized prior
- * to calling this function (use ether_init_tx_desc_ring for Tx queues
- * and ether_init_rx_desc_ring for Rx queues).
- *
- * INPUT:
- * dev - a pointer to the required interface
- *
- * OUTPUT:
- * Ethernet port is ready to receive and transmit.
- *
- * RETURN:
- * None.
- */
-static void eth_port_start(struct net_device *dev)
+static void phy_reset(struct mv643xx_eth_private *mp)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- unsigned int port_num = mp->port_num;
- int tx_curr_desc, rx_curr_desc;
- u32 pscr;
- struct ethtool_cmd ethtool_cmd;
-
- /* Assignment of Tx CTRP of given queue */
- tx_curr_desc = mp->tx_curr_desc_q;
- wrl(mp, TX_CURRENT_QUEUE_DESC_PTR_0(port_num),
- (u32)((struct eth_tx_desc *)mp->tx_desc_dma + tx_curr_desc));
-
- /* Assignment of Rx CRDP of given queue */
- rx_curr_desc = mp->rx_curr_desc_q;
- wrl(mp, RX_CURRENT_QUEUE_DESC_PTR_0(port_num),
- (u32)((struct eth_rx_desc *)mp->rx_desc_dma + rx_curr_desc));
+ unsigned int data;
- /* Add the assigned Ethernet address to the port's address table */
- eth_port_uc_addr_set(mp, dev->dev_addr);
+ smi_reg_read(mp, mp->phy_addr, 0, &data);
+ data |= 0x8000;
+ smi_reg_write(mp, mp->phy_addr, 0, data);
- /* Assign port configuration and command. */
- wrl(mp, PORT_CONFIG_REG(port_num),
- PORT_CONFIG_DEFAULT_VALUE);
-
- wrl(mp, PORT_CONFIG_EXTEND_REG(port_num),
- PORT_CONFIG_EXTEND_DEFAULT_VALUE);
+ do {
+ udelay(1);
+ smi_reg_read(mp, mp->phy_addr, 0, &data);
+ } while (data & 0x8000);
+}
- pscr = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num));
+static void port_start(struct mv643xx_eth_private *mp)
+{
+ u32 pscr;
+ int i;
+ /*
+ * Configure basic link parameters.
+ */
+ pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS);
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), pscr);
-
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
DISABLE_AUTO_NEG_SPEED_GMII |
- DISABLE_AUTO_NEG_FOR_DUPLX |
- DO_NOT_FORCE_LINK_FAIL |
+ DISABLE_AUTO_NEG_FOR_DUPLEX |
+ DO_NOT_FORCE_LINK_FAIL |
SERIAL_PORT_CONTROL_RESERVED;
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+ pscr |= SERIAL_PORT_ENABLE;
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), pscr);
+ wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE);
- pscr |= SERIAL_PORT_ENABLE;
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), pscr);
+ /*
+ * Perform PHY reset, if there is a PHY.
+ */
+ if (mp->phy_addr != -1) {
+ struct ethtool_cmd cmd;
- /* Assign port SDMA configuration */
- wrl(mp, SDMA_CONFIG_REG(port_num),
- PORT_SDMA_CONFIG_DEFAULT_VALUE);
+ mv643xx_eth_get_settings(mp->dev, &cmd);
+ phy_reset(mp);
+ mv643xx_eth_set_settings(mp->dev, &cmd);
+ }
- /* Enable port Rx. */
- mv643xx_eth_port_enable_rx(mp, ETH_RX_QUEUES_ENABLED);
+ /*
+ * Configure TX path and queues.
+ */
+ tx_set_rate(mp, 1000000000, 16777216);
+ for (i = 0; i < 8; i++) {
+ struct tx_queue *txq = mp->txq + i;
+ int off = TXQ_CURRENT_DESC_PTR(mp->port_num, i);
+ u32 addr;
- /* Disable port bandwidth limits by clearing MTU register */
- wrl(mp, MAXIMUM_TRANSMIT_UNIT(port_num), 0);
+ if ((mp->txq_mask & (1 << i)) == 0)
+ continue;
- /* save phy settings across reset */
- mv643xx_get_settings(dev, &ethtool_cmd);
- ethernet_phy_reset(mp);
- mv643xx_set_settings(dev, &ethtool_cmd);
-}
+ addr = (u32)txq->tx_desc_dma;
+ addr += txq->tx_curr_desc * sizeof(struct tx_desc);
+ wrl(mp, off, addr);
-/*
- * eth_port_uc_addr_set - Write a MAC address into the port's hw registers
- */
-static void eth_port_uc_addr_set(struct mv643xx_private *mp,
- unsigned char *p_addr)
-{
- unsigned int port_num = mp->port_num;
- unsigned int mac_h;
- unsigned int mac_l;
- int table;
+ txq_set_rate(txq, 1000000000, 16777216);
+ txq_set_fixed_prio_mode(txq);
+ }
- mac_l = (p_addr[4] << 8) | (p_addr[5]);
- mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
- (p_addr[3] << 0);
+ /*
+ * Add configured unicast address to address filter table.
+ */
+ uc_addr_set(mp, mp->dev->dev_addr);
- wrl(mp, MAC_ADDR_LOW(port_num), mac_l);
- wrl(mp, MAC_ADDR_HIGH(port_num), mac_h);
+ /*
+ * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast
+ * frames to RX queue #0.
+ */
+ wrl(mp, PORT_CONFIG(mp->port_num), 0x00000000);
- /* Accept frames with this address */
- table = DA_FILTER_UNICAST_TABLE_BASE(port_num);
- eth_port_set_filter_table_entry(mp, table, p_addr[5] & 0x0f);
-}
+ /*
+ * Treat BPDUs as normal multicasts, and disable partition mode.
+ */
+ wrl(mp, PORT_CONFIG_EXT(mp->port_num), 0x00000000);
-/*
- * eth_port_uc_addr_get - Read the MAC address from the port's hw registers
- */
-static void eth_port_uc_addr_get(struct mv643xx_private *mp,
- unsigned char *p_addr)
-{
- unsigned int port_num = mp->port_num;
- unsigned int mac_h;
- unsigned int mac_l;
+ /*
+ * Enable the receive queues.
+ */
+ for (i = 0; i < 8; i++) {
+ struct rx_queue *rxq = mp->rxq + i;
+ int off = RXQ_CURRENT_DESC_PTR(mp->port_num, i);
+ u32 addr;
+
+ if ((mp->rxq_mask & (1 << i)) == 0)
+ continue;
- mac_h = rdl(mp, MAC_ADDR_HIGH(port_num));
- mac_l = rdl(mp, MAC_ADDR_LOW(port_num));
+ addr = (u32)rxq->rx_desc_dma;
+ addr += rxq->rx_curr_desc * sizeof(struct rx_desc);
+ wrl(mp, off, addr);
- p_addr[0] = (mac_h >> 24) & 0xff;
- p_addr[1] = (mac_h >> 16) & 0xff;
- p_addr[2] = (mac_h >> 8) & 0xff;
- p_addr[3] = mac_h & 0xff;
- p_addr[4] = (mac_l >> 8) & 0xff;
- p_addr[5] = mac_l & 0xff;
+ rxq_enable(rxq);
+ }
}
-/*
- * The entries in each table are indexed by a hash of a packet's MAC
- * address. One bit in each entry determines whether the packet is
- * accepted. There are 4 entries (each 8 bits wide) in each register
- * of the table. The bits in each entry are defined as follows:
- * 0 Accept=1, Drop=0
- * 3-1 Queue (ETH_Q0=0)
- * 7-4 Reserved = 0;
- */
-static void eth_port_set_filter_table_entry(struct mv643xx_private *mp,
- int table, unsigned char entry)
+static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
{
- unsigned int table_reg;
- unsigned int tbl_offset;
- unsigned int reg_offset;
+ unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
+ u32 val;
+
+ val = rdl(mp, SDMA_CONFIG(mp->port_num));
+ if (mp->shared->extended_rx_coal_limit) {
+ if (coal > 0xffff)
+ coal = 0xffff;
+ val &= ~0x023fff80;
+ val |= (coal & 0x8000) << 10;
+ val |= (coal & 0x7fff) << 7;
+ } else {
+ if (coal > 0x3fff)
+ coal = 0x3fff;
+ val &= ~0x003fff00;
+ val |= (coal & 0x3fff) << 8;
+ }
+ wrl(mp, SDMA_CONFIG(mp->port_num), val);
+}
- tbl_offset = (entry / 4) * 4; /* Register offset of DA table entry */
- reg_offset = entry % 4; /* Entry offset within the register */
+static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
+{
+ unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
- /* Set "accepts frame bit" at specified table entry */
- table_reg = rdl(mp, table + tbl_offset);
- table_reg |= 0x01 << (8 * reg_offset);
- wrl(mp, table + tbl_offset, table_reg);
+ if (coal > 0x3fff)
+ coal = 0x3fff;
+ wrl(mp, TX_FIFO_URGENT_THRESHOLD(mp->port_num), (coal & 0x3fff) << 4);
}
-/*
- * eth_port_mc_addr - Multicast address settings.
- *
- * The MV device supports multicast using two tables:
- * 1) Special Multicast Table for MAC addresses of the form
- * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF).
- * The MAC DA[7:0] bits are used as a pointer to the Special Multicast
- * Table entries in the DA-Filter table.
- * 2) Other Multicast Table for multicast of another type. A CRC-8bit
- * is used as an index to the Other Multicast Table entries in the
- * DA-Filter table. This function calculates the CRC-8bit value.
- * In either case, eth_port_set_filter_table_entry() is then called
- * to set to set the actual table entry.
- */
-static void eth_port_mc_addr(struct mv643xx_private *mp, unsigned char *p_addr)
+static int mv643xx_eth_open(struct net_device *dev)
{
- unsigned int port_num = mp->port_num;
- unsigned int mac_h;
- unsigned int mac_l;
- unsigned char crc_result = 0;
- int table;
- int mac_array[48];
- int crc[8];
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ int err;
int i;
- if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) &&
- (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
- table = DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port_num);
- eth_port_set_filter_table_entry(mp, table, p_addr[5]);
- return;
+ wrl(mp, INT_CAUSE(mp->port_num), 0);
+ wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
+ rdl(mp, INT_CAUSE_EXT(mp->port_num));
+
+ err = request_irq(dev->irq, mv643xx_eth_irq,
+ IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+ dev->name, dev);
+ if (err) {
+ dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n");
+ return -EAGAIN;
}
- /* Calculate CRC-8 out of the given address */
- mac_h = (p_addr[0] << 8) | (p_addr[1]);
- mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
- (p_addr[4] << 8) | (p_addr[5] << 0);
-
- for (i = 0; i < 32; i++)
- mac_array[i] = (mac_l >> i) & 0x1;
- for (i = 32; i < 48; i++)
- mac_array[i] = (mac_h >> (i - 32)) & 0x1;
-
- crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^
- mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^
- mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
- mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^
- mac_array[8] ^ mac_array[7] ^ mac_array[6] ^ mac_array[0];
-
- crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
- mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^
- mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
- mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^
- mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^
- mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
- mac_array[9] ^ mac_array[6] ^ mac_array[1] ^ mac_array[0];
-
- crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^
- mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^
- mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
- mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^
- mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8] ^
- mac_array[6] ^ mac_array[2] ^ mac_array[1] ^ mac_array[0];
-
- crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^
- mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^
- mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
- mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
- mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[7] ^
- mac_array[3] ^ mac_array[2] ^ mac_array[1];
-
- crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^
- mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^
- mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
- mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^
- mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ mac_array[4] ^
- mac_array[3] ^ mac_array[2];
-
- crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^
- mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^
- mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
- mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^
- mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[5] ^
- mac_array[4] ^ mac_array[3];
-
- crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^
- mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^
- mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
- mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^
- mac_array[12] ^ mac_array[10] ^ mac_array[6] ^ mac_array[5] ^
- mac_array[4];
-
- crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^
- mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^
- mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
- mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^
- mac_array[11] ^ mac_array[7] ^ mac_array[6] ^ mac_array[5];
+ init_mac_tables(mp);
- for (i = 0; i < 8; i++)
- crc_result = crc_result | (crc[i] << i);
+ for (i = 0; i < 8; i++) {
+ if ((mp->rxq_mask & (1 << i)) == 0)
+ continue;
- table = DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port_num);
- eth_port_set_filter_table_entry(mp, table, crc_result);
-}
+ err = rxq_init(mp, i);
+ if (err) {
+ while (--i >= 0)
+ if (mp->rxq_mask & (1 << i))
+ rxq_deinit(mp->rxq + i);
+ goto out;
+ }
-/*
- * Set the entire multicast list based on dev->mc_list.
- */
-static void eth_port_set_multicast_list(struct net_device *dev)
-{
+ rxq_refill(mp->rxq + i);
+ }
- struct dev_mc_list *mc_list;
- int i;
- int table_index;
- struct mv643xx_private *mp = netdev_priv(dev);
- unsigned int eth_port_num = mp->port_num;
+ for (i = 0; i < 8; i++) {
+ if ((mp->txq_mask & (1 << i)) == 0)
+ continue;
- /* If the device is in promiscuous mode or in all multicast mode,
- * we will fully populate both multicast tables with accept.
- * This is guaranteed to yield a match on all multicast addresses...
- */
- if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) {
- for (table_index = 0; table_index <= 0xFC; table_index += 4) {
- /* Set all entries in DA filter special multicast
- * table (Ex_dFSMT)
- * Set for ETH_Q0 for now
- * Bits
- * 0 Accept=1, Drop=0
- * 3-1 Queue ETH_Q0=0
- * 7-4 Reserved = 0;
- */
- wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
-
- /* Set all entries in DA filter other multicast
- * table (Ex_dFOMT)
- * Set for ETH_Q0 for now
- * Bits
- * 0 Accept=1, Drop=0
- * 3-1 Queue ETH_Q0=0
- * 7-4 Reserved = 0;
- */
- wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+ err = txq_init(mp, i);
+ if (err) {
+ while (--i >= 0)
+ if (mp->txq_mask & (1 << i))
+ txq_deinit(mp->txq + i);
+ goto out_free;
}
- return;
}
- /* We will clear out multicast tables every time we get the list.
- * Then add the entire new list...
- */
- for (table_index = 0; table_index <= 0xFC; table_index += 4) {
- /* Clear DA filter special multicast table (Ex_dFSMT) */
- wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
- (eth_port_num) + table_index, 0);
-
- /* Clear DA filter other multicast table (Ex_dFOMT) */
- wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE
- (eth_port_num) + table_index, 0);
- }
+#ifdef MV643XX_ETH_NAPI
+ napi_enable(&mp->napi);
+#endif
+
+ port_start(mp);
- /* Get pointer to net_device multicast list and add each one... */
- for (i = 0, mc_list = dev->mc_list;
- (i < 256) && (mc_list != NULL) && (i < dev->mc_count);
- i++, mc_list = mc_list->next)
- if (mc_list->dmi_addrlen == 6)
- eth_port_mc_addr(mp, mc_list->dmi_addr);
+ set_rx_coal(mp, 0);
+ set_tx_coal(mp, 0);
+
+ wrl(mp, INT_MASK_EXT(mp->port_num),
+ INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);
+
+ wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
+
+ return 0;
+
+
+out_free:
+ for (i = 0; i < 8; i++)
+ if (mp->rxq_mask & (1 << i))
+ rxq_deinit(mp->rxq + i);
+out:
+ free_irq(dev->irq, dev);
+
+ return err;
}
-/*
- * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
- *
- * DESCRIPTION:
- * Go through all the DA filter tables (Unicast, Special Multicast &
- * Other Multicast) and set each entry to 0.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- *
- * OUTPUT:
- * Multicast and Unicast packets are rejected.
- *
- * RETURN:
- * None.
- */
-static void eth_port_init_mac_tables(struct mv643xx_private *mp)
-{
- unsigned int port_num = mp->port_num;
- int table_index;
-
- /* Clear DA filter unicast table (Ex_dFUT) */
- for (table_index = 0; table_index <= 0xC; table_index += 4)
- wrl(mp, DA_FILTER_UNICAST_TABLE_BASE(port_num) +
- table_index, 0);
-
- for (table_index = 0; table_index <= 0xFC; table_index += 4) {
- /* Clear DA filter special multicast table (Ex_dFSMT) */
- wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port_num) +
- table_index, 0);
- /* Clear DA filter other multicast table (Ex_dFOMT) */
- wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port_num) +
- table_index, 0);
+static void port_reset(struct mv643xx_eth_private *mp)
+{
+ unsigned int data;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (mp->rxq_mask & (1 << i))
+ rxq_disable(mp->rxq + i);
+ if (mp->txq_mask & (1 << i))
+ txq_disable(mp->txq + i);
}
+ while (!(rdl(mp, PORT_STATUS(mp->port_num)) & TX_FIFO_EMPTY))
+ udelay(10);
+
+ /* Reset the Enable bit in the Configuration Register */
+ data = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+ data &= ~(SERIAL_PORT_ENABLE |
+ DO_NOT_FORCE_LINK_FAIL |
+ FORCE_LINK_PASS);
+ wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), data);
}
-/*
- * eth_clear_mib_counters - Clear all MIB counters
- *
- * DESCRIPTION:
- * This function clears all MIB counters of a specific ethernet port.
- * A read from the MIB counter will reset the counter.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- *
- * OUTPUT:
- * After reading all MIB counters, the counters resets.
- *
- * RETURN:
- * MIB counter value.
- *
- */
-static void eth_clear_mib_counters(struct mv643xx_private *mp)
+static int mv643xx_eth_stop(struct net_device *dev)
{
- unsigned int port_num = mp->port_num;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
int i;
- /* Perform dummy reads from MIB counters */
- for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
- i += 4)
- rdl(mp, MIB_COUNTERS_BASE(port_num) + i);
+ wrl(mp, INT_MASK(mp->port_num), 0x00000000);
+ rdl(mp, INT_MASK(mp->port_num));
+
+#ifdef MV643XX_ETH_NAPI
+ napi_disable(&mp->napi);
+#endif
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
+
+ free_irq(dev->irq, dev);
+
+ port_reset(mp);
+ mib_counters_update(mp);
+
+ for (i = 0; i < 8; i++) {
+ if (mp->rxq_mask & (1 << i))
+ rxq_deinit(mp->rxq + i);
+ if (mp->txq_mask & (1 << i))
+ txq_deinit(mp->txq + i);
+ }
+
+ return 0;
}
-static inline u32 read_mib(struct mv643xx_private *mp, int offset)
+static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- return rdl(mp, MIB_COUNTERS_BASE(mp->port_num) + offset);
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ if (mp->phy_addr != -1)
+ return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);
+
+ return -EOPNOTSUPP;
}
-static void eth_update_mib_counters(struct mv643xx_private *mp)
+static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
{
- struct mv643xx_mib_counters *p = &mp->mib_counters;
- int offset;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
- p->good_octets_received +=
- read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
- p->good_octets_received +=
- (u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32;
+ if (new_mtu < 64 || new_mtu > 9500)
+ return -EINVAL;
- for (offset = ETH_MIB_BAD_OCTETS_RECEIVED;
- offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS;
- offset += 4)
- *(u32 *)((char *)p + offset) += read_mib(mp, offset);
+ dev->mtu = new_mtu;
+ tx_set_rate(mp, 1000000000, 16777216);
- p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW);
- p->good_octets_sent +=
- (u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_HIGH) << 32;
+ if (!netif_running(dev))
+ return 0;
- for (offset = ETH_MIB_GOOD_FRAMES_SENT;
- offset <= ETH_MIB_LATE_COLLISION;
- offset += 4)
- *(u32 *)((char *)p + offset) += read_mib(mp, offset);
+ /*
+ * Stop and then re-open the interface. This will allocate RX
+ * skbs of the new MTU.
+ * There is a possible danger that the open will not succeed,
+ * due to memory being full.
+ */
+ mv643xx_eth_stop(dev);
+ if (mv643xx_eth_open(dev)) {
+ dev_printk(KERN_ERR, &dev->dev,
+ "fatal error on re-opening device after "
+ "MTU change\n");
+ }
+
+ return 0;
}
-/*
- * ethernet_phy_detect - Detect whether a phy is present
- *
- * DESCRIPTION:
- * This function tests whether there is a PHY present on
- * the specified port.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- *
- * OUTPUT:
- * None
- *
- * RETURN:
- * 0 on success
- * -ENODEV on failure
- *
- */
-static int ethernet_phy_detect(struct mv643xx_private *mp)
+static void tx_timeout_task(struct work_struct *ugly)
{
- unsigned int phy_reg_data0;
- int auto_neg;
+ struct mv643xx_eth_private *mp;
- eth_port_read_smi_reg(mp, 0, &phy_reg_data0);
- auto_neg = phy_reg_data0 & 0x1000;
- phy_reg_data0 ^= 0x1000; /* invert auto_neg */
- eth_port_write_smi_reg(mp, 0, phy_reg_data0);
+ mp = container_of(ugly, struct mv643xx_eth_private, tx_timeout_task);
+ if (netif_running(mp->dev)) {
+ netif_stop_queue(mp->dev);
- eth_port_read_smi_reg(mp, 0, &phy_reg_data0);
- if ((phy_reg_data0 & 0x1000) == auto_neg)
- return -ENODEV; /* change didn't take */
+ port_reset(mp);
+ port_start(mp);
- phy_reg_data0 ^= 0x1000;
- eth_port_write_smi_reg(mp, 0, phy_reg_data0);
- return 0;
+ __txq_maybe_wake(mp->txq + mp->txq_primary);
+ }
}
-/*
- * ethernet_phy_get - Get the ethernet port PHY address.
- *
- * DESCRIPTION:
- * This routine returns the given ethernet port PHY address.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- *
- * OUTPUT:
- * None.
- *
- * RETURN:
- * PHY address.
- *
- */
-static int ethernet_phy_get(struct mv643xx_private *mp)
+static void mv643xx_eth_tx_timeout(struct net_device *dev)
{
- unsigned int reg_data;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
- reg_data = rdl(mp, PHY_ADDR_REG);
+ dev_printk(KERN_INFO, &dev->dev, "tx timeout\n");
- return ((reg_data >> (5 * mp->port_num)) & 0x1f);
+ schedule_work(&mp->tx_timeout_task);
}
-/*
- * ethernet_phy_set - Set the ethernet port PHY address.
- *
- * DESCRIPTION:
- * This routine sets the given ethernet port PHY address.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- * int phy_addr PHY address.
- *
- * OUTPUT:
- * None.
- *
- * RETURN:
- * None.
- *
- */
-static void ethernet_phy_set(struct mv643xx_private *mp, int phy_addr)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void mv643xx_eth_netpoll(struct net_device *dev)
{
- u32 reg_data;
- int addr_shift = 5 * mp->port_num;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ wrl(mp, INT_MASK(mp->port_num), 0x00000000);
+ rdl(mp, INT_MASK(mp->port_num));
+
+ mv643xx_eth_irq(dev->irq, dev);
- reg_data = rdl(mp, PHY_ADDR_REG);
- reg_data &= ~(0x1f << addr_shift);
- reg_data |= (phy_addr & 0x1f) << addr_shift;
- wrl(mp, PHY_ADDR_REG, reg_data);
+ wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_CAUSE_EXT);
}
+#endif
-/*
- * ethernet_phy_reset - Reset Ethernet port PHY.
- *
- * DESCRIPTION:
- * This routine utilizes the SMI interface to reset the ethernet port PHY.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- *
- * OUTPUT:
- * The PHY is reset.
- *
- * RETURN:
- * None.
- *
- */
-static void ethernet_phy_reset(struct mv643xx_private *mp)
+static int mv643xx_eth_mdio_read(struct net_device *dev, int addr, int reg)
{
- unsigned int phy_reg_data;
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ int val;
- /* Reset the PHY */
- eth_port_read_smi_reg(mp, 0, &phy_reg_data);
- phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
- eth_port_write_smi_reg(mp, 0, phy_reg_data);
+ smi_reg_read(mp, addr, reg, &val);
- /* wait for PHY to come out of reset */
- do {
- udelay(1);
- eth_port_read_smi_reg(mp, 0, &phy_reg_data);
- } while (phy_reg_data & 0x8000);
+ return val;
}
-static void mv643xx_eth_port_enable_tx(struct mv643xx_private *mp,
- unsigned int queues)
+static void mv643xx_eth_mdio_write(struct net_device *dev, int addr, int reg, int val)
{
- wrl(mp, TRANSMIT_QUEUE_COMMAND_REG(mp->port_num), queues);
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+ smi_reg_write(mp, addr, reg, val);
}
-static void mv643xx_eth_port_enable_rx(struct mv643xx_private *mp,
- unsigned int queues)
-{
- wrl(mp, RECEIVE_QUEUE_COMMAND_REG(mp->port_num), queues);
-}
-static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_private *mp)
+/* platform glue ************************************************************/
+static void
+mv643xx_eth_conf_mbus_windows(struct mv643xx_eth_shared_private *msp,
+ struct mbus_dram_target_info *dram)
{
- unsigned int port_num = mp->port_num;
- u32 queues;
+ void __iomem *base = msp->base;
+ u32 win_enable;
+ u32 win_protect;
+ int i;
- /* Stop Tx port activity. Check port Tx activity. */
- queues = rdl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF;
- if (queues) {
- /* Issue stop command for active queues only */
- wrl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num), (queues << 8));
+ for (i = 0; i < 6; i++) {
+ writel(0, base + WINDOW_BASE(i));
+ writel(0, base + WINDOW_SIZE(i));
+ if (i < 4)
+ writel(0, base + WINDOW_REMAP_HIGH(i));
+ }
- /* Wait for all Tx activity to terminate. */
- /* Check port cause register that all Tx queues are stopped */
- while (rdl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF)
- udelay(PHY_WAIT_MICRO_SECONDS);
+ win_enable = 0x3f;
+ win_protect = 0;
- /* Wait for Tx FIFO to empty */
- while (rdl(mp, PORT_STATUS_REG(port_num)) &
- ETH_PORT_TX_FIFO_EMPTY)
- udelay(PHY_WAIT_MICRO_SECONDS);
+ for (i = 0; i < dram->num_cs; i++) {
+ struct mbus_dram_window *cs = dram->cs + i;
+
+ writel((cs->base & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ dram->mbus_dram_target_id, base + WINDOW_BASE(i));
+ writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i));
+
+ win_enable &= ~(1 << i);
+ win_protect |= 3 << (2 * i);
}
- return queues;
+ writel(win_enable, base + WINDOW_BAR_ENABLE);
+ msp->win_protect = win_protect;
}
-static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_private *mp)
+static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
{
- unsigned int port_num = mp->port_num;
- u32 queues;
-
- /* Stop Rx port activity. Check port Rx activity. */
- queues = rdl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF;
- if (queues) {
- /* Issue stop command for active queues only */
- wrl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num), (queues << 8));
-
- /* Wait for all Rx activity to terminate. */
- /* Check port cause register that all Rx queues are stopped */
- while (rdl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF)
- udelay(PHY_WAIT_MICRO_SECONDS);
- }
+ /*
+ * Check whether we have a 14-bit coal limit field in bits
+ * [21:8], or a 16-bit coal limit in bits [25,21:7] of the
+ * SDMA config register.
+ */
+ writel(0x02000000, msp->base + SDMA_CONFIG(0));
+ if (readl(msp->base + SDMA_CONFIG(0)) & 0x02000000)
+ msp->extended_rx_coal_limit = 1;
+ else
+ msp->extended_rx_coal_limit = 0;
- return queues;
+ /*
+ * Check whether the TX rate control registers are in the
+ * old or the new place.
+ */
+ writel(1, msp->base + TX_BW_MTU_MOVED(0));
+ if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1)
+ msp->tx_bw_control_moved = 1;
+ else
+ msp->tx_bw_control_moved = 0;
}
-/*
- * eth_port_reset - Reset Ethernet port
- *
- * DESCRIPTION:
- * This routine resets the chip by aborting any SDMA engine activity and
- * clearing the MIB counters. The Receiver and the Transmit unit are in
- * idle state after this command is performed and the port is disabled.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- *
- * OUTPUT:
- * Channel activity is halted.
- *
- * RETURN:
- * None.
- *
- */
-static void eth_port_reset(struct mv643xx_private *mp)
+static int mv643xx_eth_shared_probe(struct platform_device *pdev)
{
- unsigned int port_num = mp->port_num;
- unsigned int reg_data;
+ static int mv643xx_eth_version_printed = 0;
+ struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
+ struct mv643xx_eth_shared_private *msp;
+ struct resource *res;
+ int ret;
- mv643xx_eth_port_disable_tx(mp);
- mv643xx_eth_port_disable_rx(mp);
+ if (!mv643xx_eth_version_printed++)
+ printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
- /* Clear all MIB counters */
- eth_clear_mib_counters(mp);
+ ret = -EINVAL;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL)
+ goto out;
- /* Reset the Enable bit in the Configuration Register */
- reg_data = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num));
- reg_data &= ~(SERIAL_PORT_ENABLE |
- DO_NOT_FORCE_LINK_FAIL |
- FORCE_LINK_PASS);
- wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), reg_data);
-}
+ ret = -ENOMEM;
+ msp = kmalloc(sizeof(*msp), GFP_KERNEL);
+ if (msp == NULL)
+ goto out;
+ memset(msp, 0, sizeof(*msp));
+ msp->base = ioremap(res->start, res->end - res->start + 1);
+ if (msp->base == NULL)
+ goto out_free;
-/*
- * eth_port_read_smi_reg - Read PHY registers
- *
- * DESCRIPTION:
- * This routine utilize the SMI interface to interact with the PHY in
- * order to perform PHY register read.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- * unsigned int phy_reg PHY register address offset.
- * unsigned int *value Register value buffer.
- *
- * OUTPUT:
- * Write the value of a specified PHY register into given buffer.
- *
- * RETURN:
- * false if the PHY is busy or read data is not in valid state.
- * true otherwise.
- *
- */
-static void eth_port_read_smi_reg(struct mv643xx_private *mp,
- unsigned int phy_reg, unsigned int *value)
-{
- void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG;
- int phy_addr = ethernet_phy_get(mp);
- unsigned long flags;
- int i;
+ spin_lock_init(&msp->phy_lock);
- /* the SMI register is a shared resource */
- spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
+ /*
+ * (Re-)program MBUS remapping windows if we are asked to.
+ */
+ if (pd != NULL && pd->dram != NULL)
+ mv643xx_eth_conf_mbus_windows(msp, pd->dram);
- /* wait for the SMI register to become available */
- for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) {
- if (i == PHY_WAIT_ITERATIONS) {
- printk("%s: PHY busy timeout\n", mp->dev->name);
- goto out;
- }
- udelay(PHY_WAIT_MICRO_SECONDS);
- }
+ /*
+ * Detect hardware parameters.
+ */
+ msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000;
+ infer_hw_params(msp);
- writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ,
- smi_reg);
+ platform_set_drvdata(pdev, msp);
- /* now wait for the data to be valid */
- for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) {
- if (i == PHY_WAIT_ITERATIONS) {
- printk("%s: PHY read timeout\n", mp->dev->name);
- goto out;
- }
- udelay(PHY_WAIT_MICRO_SECONDS);
- }
+ return 0;
- *value = readl(smi_reg) & 0xffff;
+out_free:
+ kfree(msp);
out:
- spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
+ return ret;
}
-/*
- * eth_port_write_smi_reg - Write to PHY registers
- *
- * DESCRIPTION:
- * This routine utilize the SMI interface to interact with the PHY in
- * order to perform writes to PHY registers.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port.
- * unsigned int phy_reg PHY register address offset.
- * unsigned int value Register value.
- *
- * OUTPUT:
- * Write the given value to the specified PHY register.
- *
- * RETURN:
- * false if the PHY is busy.
- * true otherwise.
- *
- */
-static void eth_port_write_smi_reg(struct mv643xx_private *mp,
- unsigned int phy_reg, unsigned int value)
+static int mv643xx_eth_shared_remove(struct platform_device *pdev)
{
- void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG;
- int phy_addr = ethernet_phy_get(mp);
- unsigned long flags;
- int i;
-
- /* the SMI register is a shared resource */
- spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
+ struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
- /* wait for the SMI register to become available */
- for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) {
- if (i == PHY_WAIT_ITERATIONS) {
- printk("%s: PHY busy timeout\n", mp->dev->name);
- goto out;
- }
- udelay(PHY_WAIT_MICRO_SECONDS);
- }
+ iounmap(msp->base);
+ kfree(msp);
- writel((phy_addr << 16) | (phy_reg << 21) |
- ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg);
-out:
- spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
+ return 0;
}
-/*
- * Wrappers for MII support library.
- */
-static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location)
+static struct platform_driver mv643xx_eth_shared_driver = {
+ .probe = mv643xx_eth_shared_probe,
+ .remove = mv643xx_eth_shared_remove,
+ .driver = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static void phy_addr_set(struct mv643xx_eth_private *mp, int phy_addr)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- int val;
+ int addr_shift = 5 * mp->port_num;
+ u32 data;
- eth_port_read_smi_reg(mp, location, &val);
- return val;
+ data = rdl(mp, PHY_ADDR);
+ data &= ~(0x1f << addr_shift);
+ data |= (phy_addr & 0x1f) << addr_shift;
+ wrl(mp, PHY_ADDR, data);
}
-static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val)
+static int phy_addr_get(struct mv643xx_eth_private *mp)
{
- struct mv643xx_private *mp = netdev_priv(dev);
- eth_port_write_smi_reg(mp, location, val);
+ unsigned int data;
+
+ data = rdl(mp, PHY_ADDR);
+
+ return (data >> (5 * mp->port_num)) & 0x1f;
}
-/*
- * eth_port_receive - Get received information from Rx ring.
- *
- * DESCRIPTION:
- * This routine returns the received data to the caller. There is no
- * data copying during routine operation. All information is returned
- * using pointer to packet information struct passed from the caller.
- * If the routine exhausts Rx ring resources then the resource error flag
- * is set.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port Control srtuct.
- * struct pkt_info *p_pkt_info User packet buffer.
- *
- * OUTPUT:
- * Rx ring current and used indexes are updated.
- *
- * RETURN:
- * ETH_ERROR in case the routine can not access Rx desc ring.
- * ETH_QUEUE_FULL if Rx ring resources are exhausted.
- * ETH_END_OF_JOB if there is no received data.
- * ETH_OK otherwise.
- */
-static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
- struct pkt_info *p_pkt_info)
+static void set_params(struct mv643xx_eth_private *mp,
+ struct mv643xx_eth_platform_data *pd)
{
- int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
- volatile struct eth_rx_desc *p_rx_desc;
- unsigned int command_status;
- unsigned long flags;
+ struct net_device *dev = mp->dev;
- /* Do not process Rx ring in case of Rx ring resource error */
- if (mp->rx_resource_err)
- return ETH_QUEUE_FULL;
+ if (is_valid_ether_addr(pd->mac_addr))
+ memcpy(dev->dev_addr, pd->mac_addr, 6);
+ else
+ uc_addr_get(mp, dev->dev_addr);
- spin_lock_irqsave(&mp->lock, flags);
+ if (pd->phy_addr == -1) {
+ mp->shared_smi = NULL;
+ mp->phy_addr = -1;
+ } else {
+ mp->shared_smi = mp->shared;
+ if (pd->shared_smi != NULL)
+ mp->shared_smi = platform_get_drvdata(pd->shared_smi);
- /* Get the Rx Desc ring 'curr and 'used' indexes */
- rx_curr_desc = mp->rx_curr_desc_q;
- rx_used_desc = mp->rx_used_desc_q;
+ if (pd->force_phy_addr || pd->phy_addr) {
+ mp->phy_addr = pd->phy_addr & 0x3f;
+ phy_addr_set(mp, mp->phy_addr);
+ } else {
+ mp->phy_addr = phy_addr_get(mp);
+ }
+ }
- p_rx_desc = &mp->p_rx_desc_area[rx_curr_desc];
+ mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
+ if (pd->rx_queue_size)
+ mp->default_rx_ring_size = pd->rx_queue_size;
+ mp->rx_desc_sram_addr = pd->rx_sram_addr;
+ mp->rx_desc_sram_size = pd->rx_sram_size;
- /* The following parameters are used to save readings from memory */
- command_status = p_rx_desc->cmd_sts;
- rmb();
+ if (pd->rx_queue_mask)
+ mp->rxq_mask = pd->rx_queue_mask;
+ else
+ mp->rxq_mask = 0x01;
+ mp->rxq_primary = fls(mp->rxq_mask) - 1;
- /* Nothing to receive... */
- if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) {
- spin_unlock_irqrestore(&mp->lock, flags);
- return ETH_END_OF_JOB;
- }
+ mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
+ if (pd->tx_queue_size)
+ mp->default_tx_ring_size = pd->tx_queue_size;
+ mp->tx_desc_sram_addr = pd->tx_sram_addr;
+ mp->tx_desc_sram_size = pd->tx_sram_size;
- p_pkt_info->byte_cnt = (p_rx_desc->byte_cnt) - RX_BUF_OFFSET;
- p_pkt_info->cmd_sts = command_status;
- p_pkt_info->buf_ptr = (p_rx_desc->buf_ptr) + RX_BUF_OFFSET;
- p_pkt_info->return_info = mp->rx_skb[rx_curr_desc];
- p_pkt_info->l4i_chk = p_rx_desc->buf_size;
+ if (pd->tx_queue_mask)
+ mp->txq_mask = pd->tx_queue_mask;
+ else
+ mp->txq_mask = 0x01;
+ mp->txq_primary = fls(mp->txq_mask) - 1;
+}
- /*
- * Clean the return info field to indicate that the
- * packet has been moved to the upper layers
- */
- mp->rx_skb[rx_curr_desc] = NULL;
+static int phy_detect(struct mv643xx_eth_private *mp)
+{
+ unsigned int data;
+ unsigned int data2;
- /* Update current index in data structure */
- rx_next_curr_desc = (rx_curr_desc + 1) % mp->rx_ring_size;
- mp->rx_curr_desc_q = rx_next_curr_desc;
+ smi_reg_read(mp, mp->phy_addr, 0, &data);
+ smi_reg_write(mp, mp->phy_addr, 0, data ^ 0x1000);
- /* Rx descriptors exhausted. Set the Rx ring resource error flag */
- if (rx_next_curr_desc == rx_used_desc)
- mp->rx_resource_err = 1;
+ smi_reg_read(mp, mp->phy_addr, 0, &data2);
+ if (((data ^ data2) & 0x1000) == 0)
+ return -ENODEV;
- spin_unlock_irqrestore(&mp->lock, flags);
+ smi_reg_write(mp, mp->phy_addr, 0, data);
- return ETH_OK;
+ return 0;
}
-/*
- * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
- *
- * DESCRIPTION:
- * This routine returns a Rx buffer back to the Rx ring. It retrieves the
- * next 'used' descriptor and attached the returned buffer to it.
- * In case the Rx ring was in "resource error" condition, where there are
- * no available Rx resources, the function resets the resource error flag.
- *
- * INPUT:
- * struct mv643xx_private *mp Ethernet Port Control srtuct.
- * struct pkt_info *p_pkt_info Information on returned buffer.
- *
- * OUTPUT:
- * New available Rx resource in Rx descriptor ring.
- *
- * RETURN:
- * ETH_ERROR in case the routine can not access Rx desc ring.
- * ETH_OK otherwise.
- */
-static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
- struct pkt_info *p_pkt_info)
+static int phy_init(struct mv643xx_eth_private *mp,
+ struct mv643xx_eth_platform_data *pd)
{
- int used_rx_desc; /* Where to return Rx resource */
- volatile struct eth_rx_desc *p_used_rx_desc;
- unsigned long flags;
+ struct ethtool_cmd cmd;
+ int err;
- spin_lock_irqsave(&mp->lock, flags);
+ err = phy_detect(mp);
+ if (err) {
+ dev_printk(KERN_INFO, &mp->dev->dev,
+ "no PHY detected at addr %d\n", mp->phy_addr);
+ return err;
+ }
+ phy_reset(mp);
- /* Get 'used' Rx descriptor */
- used_rx_desc = mp->rx_used_desc_q;
- p_used_rx_desc = &mp->p_rx_desc_area[used_rx_desc];
+ mp->mii.phy_id = mp->phy_addr;
+ mp->mii.phy_id_mask = 0x3f;
+ mp->mii.reg_num_mask = 0x1f;
+ mp->mii.dev = mp->dev;
+ mp->mii.mdio_read = mv643xx_eth_mdio_read;
+ mp->mii.mdio_write = mv643xx_eth_mdio_write;
- p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr;
- p_used_rx_desc->buf_size = p_pkt_info->byte_cnt;
- mp->rx_skb[used_rx_desc] = p_pkt_info->return_info;
+ mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
- /* Flush the write pipe */
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.port = PORT_MII;
+ cmd.transceiver = XCVR_INTERNAL;
+ cmd.phy_address = mp->phy_addr;
+ if (pd->speed == 0) {
+ cmd.autoneg = AUTONEG_ENABLE;
+ cmd.speed = SPEED_100;
+ cmd.advertising = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full;
+ if (mp->mii.supports_gmii)
+ cmd.advertising |= ADVERTISED_1000baseT_Full;
+ } else {
+ cmd.autoneg = AUTONEG_DISABLE;
+ cmd.speed = pd->speed;
+ cmd.duplex = pd->duplex;
+ }
- /* Return the descriptor to DMA ownership */
- wmb();
- p_used_rx_desc->cmd_sts =
- ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
- wmb();
+ update_pscr(mp, cmd.speed, cmd.duplex);
+ mv643xx_eth_set_settings(mp->dev, &cmd);
- /* Move the used descriptor pointer to the next descriptor */
- mp->rx_used_desc_q = (used_rx_desc + 1) % mp->rx_ring_size;
+ return 0;
+}
- /* Any Rx return cancels the Rx resource error status */
- mp->rx_resource_err = 0;
+static int mv643xx_eth_probe(struct platform_device *pdev)
+{
+ struct mv643xx_eth_platform_data *pd;
+ struct mv643xx_eth_private *mp;
+ struct net_device *dev;
+ struct resource *res;
+ DECLARE_MAC_BUF(mac);
+ int err;
- spin_unlock_irqrestore(&mp->lock, flags);
+ pd = pdev->dev.platform_data;
+ if (pd == NULL) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "no mv643xx_eth_platform_data\n");
+ return -ENODEV;
+ }
- return ETH_OK;
-}
+ if (pd->shared == NULL) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "no mv643xx_eth_platform_data->shared\n");
+ return -ENODEV;
+ }
-/************* Begin ethtool support *************************/
+ dev = alloc_etherdev(sizeof(struct mv643xx_eth_private));
+ if (!dev)
+ return -ENOMEM;
-struct mv643xx_stats {
- char stat_string[ETH_GSTRING_LEN];
- int sizeof_stat;
- int stat_offset;
-};
+ mp = netdev_priv(dev);
+ platform_set_drvdata(pdev, mp);
-#define MV643XX_STAT(m) FIELD_SIZEOF(struct mv643xx_private, m), \
- offsetof(struct mv643xx_private, m)
-
-static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
- { "rx_packets", MV643XX_STAT(stats.rx_packets) },
- { "tx_packets", MV643XX_STAT(stats.tx_packets) },
- { "rx_bytes", MV643XX_STAT(stats.rx_bytes) },
- { "tx_bytes", MV643XX_STAT(stats.tx_bytes) },
- { "rx_errors", MV643XX_STAT(stats.rx_errors) },
- { "tx_errors", MV643XX_STAT(stats.tx_errors) },
- { "rx_dropped", MV643XX_STAT(stats.rx_dropped) },
- { "tx_dropped", MV643XX_STAT(stats.tx_dropped) },
- { "good_octets_received", MV643XX_STAT(mib_counters.good_octets_received) },
- { "bad_octets_received", MV643XX_STAT(mib_counters.bad_octets_received) },
- { "internal_mac_transmit_err", MV643XX_STAT(mib_counters.internal_mac_transmit_err) },
- { "good_frames_received", MV643XX_STAT(mib_counters.good_frames_received) },
- { "bad_frames_received", MV643XX_STAT(mib_counters.bad_frames_received) },
- { "broadcast_frames_received", MV643XX_STAT(mib_counters.broadcast_frames_received) },
- { "multicast_frames_received", MV643XX_STAT(mib_counters.multicast_frames_received) },
- { "frames_64_octets", MV643XX_STAT(mib_counters.frames_64_octets) },
- { "frames_65_to_127_octets", MV643XX_STAT(mib_counters.frames_65_to_127_octets) },
- { "frames_128_to_255_octets", MV643XX_STAT(mib_counters.frames_128_to_255_octets) },
- { "frames_256_to_511_octets", MV643XX_STAT(mib_counters.frames_256_to_511_octets) },
- { "frames_512_to_1023_octets", MV643XX_STAT(mib_counters.frames_512_to_1023_octets) },
- { "frames_1024_to_max_octets", MV643XX_STAT(mib_counters.frames_1024_to_max_octets) },
- { "good_octets_sent", MV643XX_STAT(mib_counters.good_octets_sent) },
- { "good_frames_sent", MV643XX_STAT(mib_counters.good_frames_sent) },
- { "excessive_collision", MV643XX_STAT(mib_counters.excessive_collision) },
- { "multicast_frames_sent", MV643XX_STAT(mib_counters.multicast_frames_sent) },
- { "broadcast_frames_sent", MV643XX_STAT(mib_counters.broadcast_frames_sent) },
- { "unrec_mac_control_received", MV643XX_STAT(mib_counters.unrec_mac_control_received) },
- { "fc_sent", MV643XX_STAT(mib_counters.fc_sent) },
- { "good_fc_received", MV643XX_STAT(mib_counters.good_fc_received) },
- { "bad_fc_received", MV643XX_STAT(mib_counters.bad_fc_received) },
- { "undersize_received", MV643XX_STAT(mib_counters.undersize_received) },
- { "fragments_received", MV643XX_STAT(mib_counters.fragments_received) },
- { "oversize_received", MV643XX_STAT(mib_counters.oversize_received) },
- { "jabber_received", MV643XX_STAT(mib_counters.jabber_received) },
- { "mac_receive_error", MV643XX_STAT(mib_counters.mac_receive_error) },
- { "bad_crc_event", MV643XX_STAT(mib_counters.bad_crc_event) },
- { "collision", MV643XX_STAT(mib_counters.collision) },
- { "late_collision", MV643XX_STAT(mib_counters.late_collision) },
-};
+ mp->shared = platform_get_drvdata(pd->shared);
+ mp->port_num = pd->port_number;
-#define MV643XX_STATS_LEN ARRAY_SIZE(mv643xx_gstrings_stats)
+ mp->dev = dev;
+#ifdef MV643XX_ETH_NAPI
+ netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 64);
+#endif
-static void mv643xx_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
-{
- strncpy(drvinfo->driver, mv643xx_driver_name, 32);
- strncpy(drvinfo->version, mv643xx_driver_version, 32);
- strncpy(drvinfo->fw_version, "N/A", 32);
- strncpy(drvinfo->bus_info, "mv643xx", 32);
- drvinfo->n_stats = MV643XX_STATS_LEN;
-}
+ set_params(mp, pd);
-static int mv643xx_get_sset_count(struct net_device *netdev, int sset)
-{
- switch (sset) {
- case ETH_SS_STATS:
- return MV643XX_STATS_LEN;
- default:
- return -EOPNOTSUPP;
- }
-}
+ spin_lock_init(&mp->lock);
-static void mv643xx_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, uint64_t *data)
-{
- struct mv643xx_private *mp = netdev->priv;
- int i;
+ mib_counters_clear(mp);
+ INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);
- eth_update_mib_counters(mp);
+ if (mp->phy_addr != -1) {
+ err = phy_init(mp, pd);
+ if (err)
+ goto out;
- for (i = 0; i < MV643XX_STATS_LEN; i++) {
- char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;
- data[i] = (mv643xx_gstrings_stats[i].sizeof_stat ==
- sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
+ SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
+ } else {
+ SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
}
-}
-static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
- uint8_t *data)
-{
- int i;
- switch(stringset) {
- case ETH_SS_STATS:
- for (i=0; i < MV643XX_STATS_LEN; i++) {
- memcpy(data + i * ETH_GSTRING_LEN,
- mv643xx_gstrings_stats[i].stat_string,
- ETH_GSTRING_LEN);
- }
- break;
- }
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ BUG_ON(!res);
+ dev->irq = res->start;
+
+ dev->hard_start_xmit = mv643xx_eth_xmit;
+ dev->open = mv643xx_eth_open;
+ dev->stop = mv643xx_eth_stop;
+ dev->set_multicast_list = mv643xx_eth_set_rx_mode;
+ dev->set_mac_address = mv643xx_eth_set_mac_address;
+ dev->do_ioctl = mv643xx_eth_ioctl;
+ dev->change_mtu = mv643xx_eth_change_mtu;
+ dev->tx_timeout = mv643xx_eth_tx_timeout;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = mv643xx_eth_netpoll;
+#endif
+ dev->watchdog_timeo = 2 * HZ;
+ dev->base_addr = 0;
+
+#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX
+ /*
+ * Zero copy can only work if we use Discovery II memory. Else, we will
+ * have to map the buffers to ISA memory which is only 16 MB
+ */
+ dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
+#endif
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ if (mp->shared->win_protect)
+ wrl(mp, WINDOW_PROTECT(mp->port_num), mp->shared->win_protect);
+
+ err = register_netdev(dev);
+ if (err)
+ goto out;
+
+ dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %s\n",
+ mp->port_num, print_mac(mac, dev->dev_addr));
+
+ if (dev->features & NETIF_F_SG)
+ dev_printk(KERN_NOTICE, &dev->dev, "scatter/gather enabled\n");
+
+ if (dev->features & NETIF_F_IP_CSUM)
+ dev_printk(KERN_NOTICE, &dev->dev, "tx checksum offload\n");
+
+#ifdef MV643XX_ETH_NAPI
+ dev_printk(KERN_NOTICE, &dev->dev, "napi enabled\n");
+#endif
+
+ if (mp->tx_desc_sram_size > 0)
+ dev_printk(KERN_NOTICE, &dev->dev, "configured with sram\n");
+
+ return 0;
+
+out:
+ free_netdev(dev);
+
+ return err;
}
-static u32 mv643xx_eth_get_link(struct net_device *dev)
+static int mv643xx_eth_remove(struct platform_device *pdev)
{
- struct mv643xx_private *mp = netdev_priv(dev);
+ struct mv643xx_eth_private *mp = platform_get_drvdata(pdev);
- return mii_link_ok(&mp->mii);
+ unregister_netdev(mp->dev);
+ flush_scheduled_work();
+ free_netdev(mp->dev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
}
-static int mv643xx_eth_nway_restart(struct net_device *dev)
+static void mv643xx_eth_shutdown(struct platform_device *pdev)
{
- struct mv643xx_private *mp = netdev_priv(dev);
+ struct mv643xx_eth_private *mp = platform_get_drvdata(pdev);
- return mii_nway_restart(&mp->mii);
+ /* Mask all interrupts on ethernet port */
+ wrl(mp, INT_MASK(mp->port_num), 0);
+ rdl(mp, INT_MASK(mp->port_num));
+
+ if (netif_running(mp->dev))
+ port_reset(mp);
}
-static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static struct platform_driver mv643xx_eth_driver = {
+ .probe = mv643xx_eth_probe,
+ .remove = mv643xx_eth_remove,
+ .shutdown = mv643xx_eth_shutdown,
+ .driver = {
+ .name = MV643XX_ETH_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mv643xx_eth_init_module(void)
{
- struct mv643xx_private *mp = netdev_priv(dev);
+ int rc;
+
+ rc = platform_driver_register(&mv643xx_eth_shared_driver);
+ if (!rc) {
+ rc = platform_driver_register(&mv643xx_eth_driver);
+ if (rc)
+ platform_driver_unregister(&mv643xx_eth_shared_driver);
+ }
- return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);
+ return rc;
}
+module_init(mv643xx_eth_init_module);
-static const struct ethtool_ops mv643xx_ethtool_ops = {
- .get_settings = mv643xx_get_settings,
- .set_settings = mv643xx_set_settings,
- .get_drvinfo = mv643xx_get_drvinfo,
- .get_link = mv643xx_eth_get_link,
- .set_sg = ethtool_op_set_sg,
- .get_sset_count = mv643xx_get_sset_count,
- .get_ethtool_stats = mv643xx_get_ethtool_stats,
- .get_strings = mv643xx_get_strings,
- .nway_reset = mv643xx_eth_nway_restart,
-};
+static void __exit mv643xx_eth_cleanup_module(void)
+{
+ platform_driver_unregister(&mv643xx_eth_driver);
+ platform_driver_unregister(&mv643xx_eth_shared_driver);
+}
+module_exit(mv643xx_eth_cleanup_module);
-/************* End ethtool support *************************/
+MODULE_AUTHOR("Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, "
+ "Manish Lachwani, Dale Farnsworth and Lennert Buytenhek");
+MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME);
+MODULE_ALIAS("platform:" MV643XX_ETH_NAME);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 823bb6d3533..b3981ed972b 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -49,6 +49,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/inet_lro.h>
+#include <linux/dca.h>
#include <linux/ip.h>
#include <linux/inet.h>
#include <linux/in.h>
@@ -185,11 +186,18 @@ struct myri10ge_slice_state {
dma_addr_t fw_stats_bus;
int watchdog_tx_done;
int watchdog_tx_req;
+#ifdef CONFIG_DCA
+ int cached_dca_tag;
+ int cpu;
+ __be32 __iomem *dca_tag;
+#endif
+ char irq_desc[32];
};
struct myri10ge_priv {
- struct myri10ge_slice_state ss;
+ struct myri10ge_slice_state *ss;
int tx_boundary; /* boundary transmits cannot cross */
+ int num_slices;
int running; /* running? */
int csum_flag; /* rx_csums? */
int small_bytes;
@@ -208,6 +216,11 @@ struct myri10ge_priv {
dma_addr_t cmd_bus;
struct pci_dev *pdev;
int msi_enabled;
+ int msix_enabled;
+ struct msix_entry *msix_vectors;
+#ifdef CONFIG_DCA
+ int dca_enabled;
+#endif
u32 link_state;
unsigned int rdma_tags_available;
int intr_coal_delay;
@@ -244,6 +257,8 @@ struct myri10ge_priv {
static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
static char *myri10ge_fw_aligned = "myri10ge_eth_z8e.dat";
+static char *myri10ge_fw_rss_unaligned = "myri10ge_rss_ethp_z8e.dat";
+static char *myri10ge_fw_rss_aligned = "myri10ge_rss_eth_z8e.dat";
static char *myri10ge_fw_name = NULL;
module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
@@ -321,6 +336,18 @@ static int myri10ge_wcfifo = 0;
module_param(myri10ge_wcfifo, int, S_IRUGO);
MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled");
+static int myri10ge_max_slices = 1;
+module_param(myri10ge_max_slices, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_max_slices, "Max tx/rx queues");
+
+static int myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
+module_param(myri10ge_rss_hash, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_rss_hash, "Type of RSS hashing to do");
+
+static int myri10ge_dca = 1;
+module_param(myri10ge_dca, int, S_IRUGO);
+MODULE_PARM_DESC(myri10ge_dca, "Enable DCA if possible");
+
#define MYRI10GE_FW_OFFSET 1024*1024
#define MYRI10GE_HIGHPART_TO_U32(X) \
(sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0)
@@ -664,7 +691,7 @@ static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp)
return 0;
}
-static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
+static int myri10ge_load_firmware(struct myri10ge_priv *mgp, int adopt)
{
char __iomem *submit;
__be32 buf[16] __attribute__ ((__aligned__(8)));
@@ -674,6 +701,8 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
size = 0;
status = myri10ge_load_hotplug_firmware(mgp, &size);
if (status) {
+ if (!adopt)
+ return status;
dev_warn(&mgp->pdev->dev, "hotplug firmware loading failed\n");
/* Do not attempt to adopt firmware if there
@@ -866,8 +895,12 @@ abort:
static int myri10ge_reset(struct myri10ge_priv *mgp)
{
struct myri10ge_cmd cmd;
- int status;
+ struct myri10ge_slice_state *ss;
+ int i, status;
size_t bytes;
+#ifdef CONFIG_DCA
+ unsigned long dca_tag_off;
+#endif
/* try to send a reset command to the card to see if it
* is alive */
@@ -879,20 +912,74 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
(void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST);
+ /*
+ * Use non-ndis mcp_slot (eg, 4 bytes total,
+ * no toeplitz hash value returned. Older firmware will
+ * not understand this command, but will use the correct
+ * sized mcp_slot, so we ignore error returns
+ */
+ cmd.data0 = MXGEFW_RSS_MCP_SLOT_TYPE_MIN;
+ (void)myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_RSS_MCP_SLOT_TYPE, &cmd, 0);
/* Now exchange information about interrupts */
- bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
- memset(mgp->ss.rx_done.entry, 0, bytes);
+ bytes = mgp->max_intr_slots * sizeof(*mgp->ss[0].rx_done.entry);
cmd.data0 = (u32) bytes;
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0);
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.rx_done.bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.rx_done.bus);
- status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA, &cmd, 0);
+
+ /*
+ * Even though we already know how many slices are supported
+ * via myri10ge_probe_slices() MXGEFW_CMD_GET_MAX_RSS_QUEUES
+ * has magic side effects, and must be called after a reset.
+ * It must be called prior to calling any RSS related cmds,
+ * including assigning an interrupt queue for anything but
+ * slice 0. It must also be called *after*
+ * MXGEFW_CMD_SET_INTRQ_SIZE, since the intrq size is used by
+ * the firmware to compute offsets.
+ */
+
+ if (mgp->num_slices > 1) {
+
+ /* ask the maximum number of slices it supports */
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_RSS_QUEUES,
+ &cmd, 0);
+ if (status != 0) {
+ dev_err(&mgp->pdev->dev,
+ "failed to get number of slices\n");
+ }
+
+ /*
+ * MXGEFW_CMD_ENABLE_RSS_QUEUES must be called prior
+ * to setting up the interrupt queue DMA
+ */
+
+ cmd.data0 = mgp->num_slices;
+ cmd.data1 = 1; /* use MSI-X */
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ENABLE_RSS_QUEUES,
+ &cmd, 0);
+ if (status != 0) {
+ dev_err(&mgp->pdev->dev,
+ "failed to set number of slices\n");
+
+ return status;
+ }
+ }
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(ss->rx_done.bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(ss->rx_done.bus);
+ cmd.data2 = i;
+ status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_DMA,
+ &cmd, 0);
+ };
status |=
myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd, 0);
- mgp->ss.irq_claim = (__iomem __be32 *) (mgp->sram + cmd.data0);
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+ ss->irq_claim =
+ (__iomem __be32 *) (mgp->sram + cmd.data0 + 8 * i);
+ }
status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
&cmd, 0);
mgp->irq_deassert = (__iomem __be32 *) (mgp->sram + cmd.data0);
@@ -906,24 +993,116 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
- memset(mgp->ss.rx_done.entry, 0, bytes);
+#ifdef CONFIG_DCA
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0);
+ dca_tag_off = cmd.data0;
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+ if (status == 0) {
+ ss->dca_tag = (__iomem __be32 *)
+ (mgp->sram + dca_tag_off + 4 * i);
+ } else {
+ ss->dca_tag = NULL;
+ }
+ }
+#endif /* CONFIG_DCA */
/* reset mcp/driver shared state back to 0 */
- mgp->ss.tx.req = 0;
- mgp->ss.tx.done = 0;
- mgp->ss.tx.pkt_start = 0;
- mgp->ss.tx.pkt_done = 0;
- mgp->ss.rx_big.cnt = 0;
- mgp->ss.rx_small.cnt = 0;
- mgp->ss.rx_done.idx = 0;
- mgp->ss.rx_done.cnt = 0;
+
mgp->link_changes = 0;
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+
+ memset(ss->rx_done.entry, 0, bytes);
+ ss->tx.req = 0;
+ ss->tx.done = 0;
+ ss->tx.pkt_start = 0;
+ ss->tx.pkt_done = 0;
+ ss->rx_big.cnt = 0;
+ ss->rx_small.cnt = 0;
+ ss->rx_done.idx = 0;
+ ss->rx_done.cnt = 0;
+ ss->tx.wake_queue = 0;
+ ss->tx.stop_queue = 0;
+ }
+
status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
myri10ge_change_pause(mgp, mgp->pause);
myri10ge_set_multicast_list(mgp->dev);
return status;
}
+#ifdef CONFIG_DCA
+static void
+myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
+{
+ ss->cpu = cpu;
+ ss->cached_dca_tag = tag;
+ put_be32(htonl(tag), ss->dca_tag);
+}
+
+static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss)
+{
+ int cpu = get_cpu();
+ int tag;
+
+ if (cpu != ss->cpu) {
+ tag = dca_get_tag(cpu);
+ if (ss->cached_dca_tag != tag)
+ myri10ge_write_dca(ss, cpu, tag);
+ }
+ put_cpu();
+}
+
+static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
+{
+ int err, i;
+ struct pci_dev *pdev = mgp->pdev;
+
+ if (mgp->ss[0].dca_tag == NULL || mgp->dca_enabled)
+ return;
+ if (!myri10ge_dca) {
+ dev_err(&pdev->dev, "dca disabled by administrator\n");
+ return;
+ }
+ err = dca_add_requester(&pdev->dev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "dca_add_requester() failed, err=%d\n", err);
+ return;
+ }
+ mgp->dca_enabled = 1;
+ for (i = 0; i < mgp->num_slices; i++)
+ myri10ge_write_dca(&mgp->ss[i], -1, 0);
+}
+
+static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
+{
+ struct pci_dev *pdev = mgp->pdev;
+ int err;
+
+ if (!mgp->dca_enabled)
+ return;
+ mgp->dca_enabled = 0;
+ err = dca_remove_requester(&pdev->dev);
+}
+
+static int myri10ge_notify_dca_device(struct device *dev, void *data)
+{
+ struct myri10ge_priv *mgp;
+ unsigned long event;
+
+ mgp = dev_get_drvdata(dev);
+ event = *(unsigned long *)data;
+
+ if (event == DCA_PROVIDER_ADD)
+ myri10ge_setup_dca(mgp);
+ else if (event == DCA_PROVIDER_REMOVE)
+ myri10ge_teardown_dca(mgp);
+ return 0;
+}
+#endif /* CONFIG_DCA */
+
static inline void
myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
struct mcp_kreq_ether_recv *src)
@@ -1102,9 +1281,10 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
rx_frags[0].size -= MXGEFW_PAD;
len -= MXGEFW_PAD;
lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags,
- len, len,
/* opaque, will come back in get_frag_header */
+ len, len,
(void *)(__force unsigned long)csum, csum);
+
return 1;
}
@@ -1243,7 +1423,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
{
- struct mcp_irq_data *stats = mgp->ss.fw_stats;
+ struct mcp_irq_data *stats = mgp->ss[0].fw_stats;
if (unlikely(stats->stats_updated)) {
unsigned link_up = ntohl(stats->link_up);
@@ -1290,6 +1470,11 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
struct net_device *netdev = ss->mgp->dev;
int work_done;
+#ifdef CONFIG_DCA
+ if (ss->mgp->dca_enabled)
+ myri10ge_update_dca(ss);
+#endif
+
/* process as many rx events as NAPI will allow */
work_done = myri10ge_clean_rx_done(ss, budget);
@@ -1309,6 +1494,13 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
u32 send_done_count;
int i;
+ /* an interrupt on a non-zero slice is implicitly valid
+ * since MSI-X irqs are not shared */
+ if (ss != mgp->ss) {
+ netif_rx_schedule(ss->dev, &ss->napi);
+ return (IRQ_HANDLED);
+ }
+
/* make sure it is our IRQ, and that the DMA has finished */
if (unlikely(!stats->valid))
return (IRQ_NONE);
@@ -1318,7 +1510,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
if (stats->valid & 1)
netif_rx_schedule(ss->dev, &ss->napi);
- if (!mgp->msi_enabled) {
+ if (!mgp->msi_enabled && !mgp->msix_enabled) {
put_be32(0, mgp->irq_deassert);
if (!myri10ge_deassert_wait)
stats->valid = 0;
@@ -1453,10 +1645,10 @@ myri10ge_get_ringparam(struct net_device *netdev,
{
struct myri10ge_priv *mgp = netdev_priv(netdev);
- ring->rx_mini_max_pending = mgp->ss.rx_small.mask + 1;
- ring->rx_max_pending = mgp->ss.rx_big.mask + 1;
+ ring->rx_mini_max_pending = mgp->ss[0].rx_small.mask + 1;
+ ring->rx_max_pending = mgp->ss[0].rx_big.mask + 1;
ring->rx_jumbo_max_pending = 0;
- ring->tx_max_pending = mgp->ss.rx_small.mask + 1;
+ ring->tx_max_pending = mgp->ss[0].rx_small.mask + 1;
ring->rx_mini_pending = ring->rx_mini_max_pending;
ring->rx_pending = ring->rx_max_pending;
ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
@@ -1504,9 +1696,12 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
"tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
"tx_heartbeat_errors", "tx_window_errors",
/* device-specific stats */
- "tx_boundary", "WC", "irq", "MSI",
+ "tx_boundary", "WC", "irq", "MSI", "MSIX",
"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
"serial_number", "watchdog_resets",
+#ifdef CONFIG_DCA
+ "dca_capable", "dca_enabled",
+#endif
"link_changes", "link_up", "dropped_link_overflow",
"dropped_link_error_or_filtered",
"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
@@ -1531,23 +1726,31 @@ static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = {
static void
myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
{
+ struct myri10ge_priv *mgp = netdev_priv(netdev);
+ int i;
+
switch (stringset) {
case ETH_SS_STATS:
memcpy(data, *myri10ge_gstrings_main_stats,
sizeof(myri10ge_gstrings_main_stats));
data += sizeof(myri10ge_gstrings_main_stats);
- memcpy(data, *myri10ge_gstrings_slice_stats,
- sizeof(myri10ge_gstrings_slice_stats));
- data += sizeof(myri10ge_gstrings_slice_stats);
+ for (i = 0; i < mgp->num_slices; i++) {
+ memcpy(data, *myri10ge_gstrings_slice_stats,
+ sizeof(myri10ge_gstrings_slice_stats));
+ data += sizeof(myri10ge_gstrings_slice_stats);
+ }
break;
}
}
static int myri10ge_get_sset_count(struct net_device *netdev, int sset)
{
+ struct myri10ge_priv *mgp = netdev_priv(netdev);
+
switch (sset) {
case ETH_SS_STATS:
- return MYRI10GE_MAIN_STATS_LEN + MYRI10GE_SLICE_STATS_LEN;
+ return MYRI10GE_MAIN_STATS_LEN +
+ mgp->num_slices * MYRI10GE_SLICE_STATS_LEN;
default:
return -EOPNOTSUPP;
}
@@ -1559,6 +1762,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
{
struct myri10ge_priv *mgp = netdev_priv(netdev);
struct myri10ge_slice_state *ss;
+ int slice;
int i;
for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
@@ -1568,15 +1772,20 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)mgp->wc_enabled;
data[i++] = (unsigned int)mgp->pdev->irq;
data[i++] = (unsigned int)mgp->msi_enabled;
+ data[i++] = (unsigned int)mgp->msix_enabled;
data[i++] = (unsigned int)mgp->read_dma;
data[i++] = (unsigned int)mgp->write_dma;
data[i++] = (unsigned int)mgp->read_write_dma;
data[i++] = (unsigned int)mgp->serial_number;
data[i++] = (unsigned int)mgp->watchdog_resets;
+#ifdef CONFIG_DCA
+ data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL);
+ data[i++] = (unsigned int)(mgp->dca_enabled);
+#endif
data[i++] = (unsigned int)mgp->link_changes;
/* firmware stats are useful only in the first slice */
- ss = &mgp->ss;
+ ss = &mgp->ss[0];
data[i++] = (unsigned int)ntohl(ss->fw_stats->link_up);
data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_link_overflow);
data[i++] =
@@ -1592,24 +1801,27 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_small_buffer);
data[i++] = (unsigned int)ntohl(ss->fw_stats->dropped_no_big_buffer);
- data[i++] = 0;
- data[i++] = (unsigned int)ss->tx.pkt_start;
- data[i++] = (unsigned int)ss->tx.pkt_done;
- data[i++] = (unsigned int)ss->tx.req;
- data[i++] = (unsigned int)ss->tx.done;
- data[i++] = (unsigned int)ss->rx_small.cnt;
- data[i++] = (unsigned int)ss->rx_big.cnt;
- data[i++] = (unsigned int)ss->tx.wake_queue;
- data[i++] = (unsigned int)ss->tx.stop_queue;
- data[i++] = (unsigned int)ss->tx.linearized;
- data[i++] = ss->rx_done.lro_mgr.stats.aggregated;
- data[i++] = ss->rx_done.lro_mgr.stats.flushed;
- if (ss->rx_done.lro_mgr.stats.flushed)
- data[i++] = ss->rx_done.lro_mgr.stats.aggregated /
- ss->rx_done.lro_mgr.stats.flushed;
- else
- data[i++] = 0;
- data[i++] = ss->rx_done.lro_mgr.stats.no_desc;
+ for (slice = 0; slice < mgp->num_slices; slice++) {
+ ss = &mgp->ss[slice];
+ data[i++] = slice;
+ data[i++] = (unsigned int)ss->tx.pkt_start;
+ data[i++] = (unsigned int)ss->tx.pkt_done;
+ data[i++] = (unsigned int)ss->tx.req;
+ data[i++] = (unsigned int)ss->tx.done;
+ data[i++] = (unsigned int)ss->rx_small.cnt;
+ data[i++] = (unsigned int)ss->rx_big.cnt;
+ data[i++] = (unsigned int)ss->tx.wake_queue;
+ data[i++] = (unsigned int)ss->tx.stop_queue;
+ data[i++] = (unsigned int)ss->tx.linearized;
+ data[i++] = ss->rx_done.lro_mgr.stats.aggregated;
+ data[i++] = ss->rx_done.lro_mgr.stats.flushed;
+ if (ss->rx_done.lro_mgr.stats.flushed)
+ data[i++] = ss->rx_done.lro_mgr.stats.aggregated /
+ ss->rx_done.lro_mgr.stats.flushed;
+ else
+ data[i++] = 0;
+ data[i++] = ss->rx_done.lro_mgr.stats.no_desc;
+ }
}
static void myri10ge_set_msglevel(struct net_device *netdev, u32 value)
@@ -1652,12 +1864,15 @@ static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
struct net_device *dev = mgp->dev;
int tx_ring_size, rx_ring_size;
int tx_ring_entries, rx_ring_entries;
- int i, status;
+ int i, slice, status;
size_t bytes;
/* get ring sizes */
+ slice = ss - mgp->ss;
+ cmd.data0 = slice;
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
tx_ring_size = cmd.data0;
+ cmd.data0 = slice;
status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
if (status != 0)
return status;
@@ -1722,15 +1937,17 @@ static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
mgp->small_bytes + MXGEFW_PAD, 0);
if (ss->rx_small.fill_cnt < ss->rx_small.mask + 1) {
- printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n",
- dev->name, ss->rx_small.fill_cnt);
+ printk(KERN_ERR
+ "myri10ge: %s:slice-%d: alloced only %d small bufs\n",
+ dev->name, slice, ss->rx_small.fill_cnt);
goto abort_with_rx_small_ring;
}
myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 0);
if (ss->rx_big.fill_cnt < ss->rx_big.mask + 1) {
- printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n",
- dev->name, ss->rx_big.fill_cnt);
+ printk(KERN_ERR
+ "myri10ge: %s:slice-%d: alloced only %d big bufs\n",
+ dev->name, slice, ss->rx_big.fill_cnt);
goto abort_with_rx_big_ring;
}
@@ -1782,6 +1999,10 @@ static void myri10ge_free_rings(struct myri10ge_slice_state *ss)
struct myri10ge_tx_buf *tx;
int i, len, idx;
+ /* If not allocated, skip it */
+ if (ss->tx.req_list == NULL)
+ return;
+
for (i = ss->rx_big.cnt; i < ss->rx_big.fill_cnt; i++) {
idx = i & ss->rx_big.mask;
if (i == ss->rx_big.fill_cnt - 1)
@@ -1844,25 +2065,67 @@ static void myri10ge_free_rings(struct myri10ge_slice_state *ss)
static int myri10ge_request_irq(struct myri10ge_priv *mgp)
{
struct pci_dev *pdev = mgp->pdev;
+ struct myri10ge_slice_state *ss;
+ struct net_device *netdev = mgp->dev;
+ int i;
int status;
+ mgp->msi_enabled = 0;
+ mgp->msix_enabled = 0;
+ status = 0;
if (myri10ge_msi) {
- status = pci_enable_msi(pdev);
- if (status != 0)
- dev_err(&pdev->dev,
- "Error %d setting up MSI; falling back to xPIC\n",
- status);
- else
- mgp->msi_enabled = 1;
- } else {
- mgp->msi_enabled = 0;
+ if (mgp->num_slices > 1) {
+ status =
+ pci_enable_msix(pdev, mgp->msix_vectors,
+ mgp->num_slices);
+ if (status == 0) {
+ mgp->msix_enabled = 1;
+ } else {
+ dev_err(&pdev->dev,
+ "Error %d setting up MSI-X\n", status);
+ return status;
+ }
+ }
+ if (mgp->msix_enabled == 0) {
+ status = pci_enable_msi(pdev);
+ if (status != 0) {
+ dev_err(&pdev->dev,
+ "Error %d setting up MSI; falling back to xPIC\n",
+ status);
+ } else {
+ mgp->msi_enabled = 1;
+ }
+ }
}
- status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
- mgp->dev->name, mgp);
- if (status != 0) {
- dev_err(&pdev->dev, "failed to allocate IRQ\n");
- if (mgp->msi_enabled)
- pci_disable_msi(pdev);
+ if (mgp->msix_enabled) {
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+ snprintf(ss->irq_desc, sizeof(ss->irq_desc),
+ "%s:slice-%d", netdev->name, i);
+ status = request_irq(mgp->msix_vectors[i].vector,
+ myri10ge_intr, 0, ss->irq_desc,
+ ss);
+ if (status != 0) {
+ dev_err(&pdev->dev,
+ "slice %d failed to allocate IRQ\n", i);
+ i--;
+ while (i >= 0) {
+ free_irq(mgp->msix_vectors[i].vector,
+ &mgp->ss[i]);
+ i--;
+ }
+ pci_disable_msix(pdev);
+ return status;
+ }
+ }
+ } else {
+ status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED,
+ mgp->dev->name, &mgp->ss[0]);
+ if (status != 0) {
+ dev_err(&pdev->dev, "failed to allocate IRQ\n");
+ if (mgp->msi_enabled)
+ pci_disable_msi(pdev);
+ }
}
return status;
}
@@ -1870,10 +2133,18 @@ static int myri10ge_request_irq(struct myri10ge_priv *mgp)
static void myri10ge_free_irq(struct myri10ge_priv *mgp)
{
struct pci_dev *pdev = mgp->pdev;
+ int i;
- free_irq(pdev->irq, mgp);
+ if (mgp->msix_enabled) {
+ for (i = 0; i < mgp->num_slices; i++)
+ free_irq(mgp->msix_vectors[i].vector, &mgp->ss[i]);
+ } else {
+ free_irq(pdev->irq, &mgp->ss[0]);
+ }
if (mgp->msi_enabled)
pci_disable_msi(pdev);
+ if (mgp->msix_enabled)
+ pci_disable_msix(pdev);
}
static int
@@ -1935,12 +2206,82 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
return 0;
}
+static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
+{
+ struct myri10ge_cmd cmd;
+ struct myri10ge_slice_state *ss;
+ int status;
+
+ ss = &mgp->ss[slice];
+ cmd.data0 = 0; /* single slice for now */
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
+ ss->tx.lanai = (struct mcp_kreq_ether_send __iomem *)
+ (mgp->sram + cmd.data0);
+
+ cmd.data0 = slice;
+ status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET,
+ &cmd, 0);
+ ss->rx_small.lanai = (struct mcp_kreq_ether_recv __iomem *)
+ (mgp->sram + cmd.data0);
+
+ cmd.data0 = slice;
+ status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0);
+ ss->rx_big.lanai = (struct mcp_kreq_ether_recv __iomem *)
+ (mgp->sram + cmd.data0);
+
+ if (myri10ge_wcfifo && mgp->wc_enabled) {
+ ss->tx.wc_fifo = (u8 __iomem *)
+ mgp->sram + MXGEFW_ETH_SEND_4 + 64 * slice;
+ ss->rx_small.wc_fifo = (u8 __iomem *)
+ mgp->sram + MXGEFW_ETH_RECV_SMALL + 64 * slice;
+ ss->rx_big.wc_fifo = (u8 __iomem *)
+ mgp->sram + MXGEFW_ETH_RECV_BIG + 64 * slice;
+ } else {
+ ss->tx.wc_fifo = NULL;
+ ss->rx_small.wc_fifo = NULL;
+ ss->rx_big.wc_fifo = NULL;
+ }
+ return status;
+
+}
+
+static int myri10ge_set_stats(struct myri10ge_priv *mgp, int slice)
+{
+ struct myri10ge_cmd cmd;
+ struct myri10ge_slice_state *ss;
+ int status;
+
+ ss = &mgp->ss[slice];
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(ss->fw_stats_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(ss->fw_stats_bus);
+ cmd.data2 = sizeof(struct mcp_irq_data);
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0);
+ if (status == -ENOSYS) {
+ dma_addr_t bus = ss->fw_stats_bus;
+ if (slice != 0)
+ return -EINVAL;
+ bus += offsetof(struct mcp_irq_data, send_done_count);
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus);
+ status = myri10ge_send_cmd(mgp,
+ MXGEFW_CMD_SET_STATS_DMA_OBSOLETE,
+ &cmd, 0);
+ /* Firmware cannot support multicast without STATS_DMA_V2 */
+ mgp->fw_multicast_support = 0;
+ } else {
+ mgp->fw_multicast_support = 1;
+ }
+ return 0;
+}
+
static int myri10ge_open(struct net_device *dev)
{
+ struct myri10ge_slice_state *ss;
struct myri10ge_priv *mgp = netdev_priv(dev);
struct myri10ge_cmd cmd;
+ int i, status, big_pow2, slice;
+ u8 *itable;
struct net_lro_mgr *lro_mgr;
- int status, big_pow2;
if (mgp->running != MYRI10GE_ETH_STOPPED)
return -EBUSY;
@@ -1952,6 +2293,48 @@ static int myri10ge_open(struct net_device *dev)
goto abort_with_nothing;
}
+ if (mgp->num_slices > 1) {
+ cmd.data0 = mgp->num_slices;
+ cmd.data1 = 1; /* use MSI-X */
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ENABLE_RSS_QUEUES,
+ &cmd, 0);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to set number of slices\n",
+ dev->name);
+ goto abort_with_nothing;
+ }
+ /* setup the indirection table */
+ cmd.data0 = mgp->num_slices;
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_RSS_TABLE_SIZE,
+ &cmd, 0);
+
+ status |= myri10ge_send_cmd(mgp,
+ MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
+ &cmd, 0);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to setup rss tables\n",
+ dev->name);
+ }
+
+ /* just enable an identity mapping */
+ itable = mgp->sram + cmd.data0;
+ for (i = 0; i < mgp->num_slices; i++)
+ __raw_writeb(i, &itable[i]);
+
+ cmd.data0 = 1;
+ cmd.data1 = myri10ge_rss_hash;
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_RSS_ENABLE,
+ &cmd, 0);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to enable slices\n",
+ dev->name);
+ goto abort_with_nothing;
+ }
+ }
+
status = myri10ge_request_irq(mgp);
if (status != 0)
goto abort_with_nothing;
@@ -1975,41 +2358,6 @@ static int myri10ge_open(struct net_device *dev)
if (myri10ge_small_bytes > 0)
mgp->small_bytes = myri10ge_small_bytes;
- /* get the lanai pointers to the send and receive rings */
-
- status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
- mgp->ss.tx.lanai =
- (struct mcp_kreq_ether_send __iomem *)(mgp->sram + cmd.data0);
-
- status |=
- myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd, 0);
- mgp->ss.rx_small.lanai =
- (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
-
- status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd, 0);
- mgp->ss.rx_big.lanai =
- (struct mcp_kreq_ether_recv __iomem *)(mgp->sram + cmd.data0);
-
- if (status != 0) {
- printk(KERN_ERR
- "myri10ge: %s: failed to get ring sizes or locations\n",
- dev->name);
- mgp->running = MYRI10GE_ETH_STOPPED;
- goto abort_with_irq;
- }
-
- if (myri10ge_wcfifo && mgp->wc_enabled) {
- mgp->ss.tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
- mgp->ss.rx_small.wc_fifo =
- (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
- mgp->ss.rx_big.wc_fifo =
- (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_BIG;
- } else {
- mgp->ss.tx.wc_fifo = NULL;
- mgp->ss.rx_small.wc_fifo = NULL;
- mgp->ss.rx_big.wc_fifo = NULL;
- }
-
/* Firmware needs the big buff size as a power of 2. Lie and
* tell him the buffer is larger, because we only use 1
* buffer/pkt, and the mtu will prevent overruns.
@@ -2024,9 +2372,44 @@ static int myri10ge_open(struct net_device *dev)
mgp->big_bytes = big_pow2;
}
- status = myri10ge_allocate_rings(&mgp->ss);
- if (status != 0)
- goto abort_with_irq;
+ /* setup the per-slice data structures */
+ for (slice = 0; slice < mgp->num_slices; slice++) {
+ ss = &mgp->ss[slice];
+
+ status = myri10ge_get_txrx(mgp, slice);
+ if (status != 0) {
+ printk(KERN_ERR
+ "myri10ge: %s: failed to get ring sizes or locations\n",
+ dev->name);
+ goto abort_with_rings;
+ }
+ status = myri10ge_allocate_rings(ss);
+ if (status != 0)
+ goto abort_with_rings;
+ if (slice == 0)
+ status = myri10ge_set_stats(mgp, slice);
+ if (status) {
+ printk(KERN_ERR
+ "myri10ge: %s: Couldn't set stats DMA\n",
+ dev->name);
+ goto abort_with_rings;
+ }
+
+ lro_mgr = &ss->rx_done.lro_mgr;
+ lro_mgr->dev = dev;
+ lro_mgr->features = LRO_F_NAPI;
+ lro_mgr->ip_summed = CHECKSUM_COMPLETE;
+ lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
+ lro_mgr->lro_arr = ss->rx_done.lro_desc;
+ lro_mgr->get_frag_header = myri10ge_get_frag_header;
+ lro_mgr->max_aggr = myri10ge_lro_max_pkts;
+ if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
+ lro_mgr->max_aggr = MAX_SKB_FRAGS;
+
+ /* must happen prior to any irq */
+ napi_enable(&(ss)->napi);
+ }
/* now give firmware buffers sizes, and MTU */
cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN;
@@ -2043,25 +2426,15 @@ static int myri10ge_open(struct net_device *dev)
goto abort_with_rings;
}
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->ss.fw_stats_bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->ss.fw_stats_bus);
- cmd.data2 = sizeof(struct mcp_irq_data);
- status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd, 0);
- if (status == -ENOSYS) {
- dma_addr_t bus = mgp->ss.fw_stats_bus;
- bus += offsetof(struct mcp_irq_data, send_done_count);
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(bus);
- status = myri10ge_send_cmd(mgp,
- MXGEFW_CMD_SET_STATS_DMA_OBSOLETE,
- &cmd, 0);
- /* Firmware cannot support multicast without STATS_DMA_V2 */
- mgp->fw_multicast_support = 0;
- } else {
- mgp->fw_multicast_support = 1;
- }
- if (status) {
- printk(KERN_ERR "myri10ge: %s: Couldn't set stats DMA\n",
+ /*
+ * Set Linux style TSO mode; this is needed only on newer
+ * firmware versions. Older versions default to Linux
+ * style TSO
+ */
+ cmd.data0 = 0;
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_TSO_MODE, &cmd, 0);
+ if (status && status != -ENOSYS) {
+ printk(KERN_ERR "myri10ge: %s: Couldn't set TSO mode\n",
dev->name);
goto abort_with_rings;
}
@@ -2069,21 +2442,6 @@ static int myri10ge_open(struct net_device *dev)
mgp->link_state = ~0U;
mgp->rdma_tags_available = 15;
- lro_mgr = &mgp->ss.rx_done.lro_mgr;
- lro_mgr->dev = dev;
- lro_mgr->features = LRO_F_NAPI;
- lro_mgr->ip_summed = CHECKSUM_COMPLETE;
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
- lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS;
- lro_mgr->lro_arr = mgp->ss.rx_done.lro_desc;
- lro_mgr->get_frag_header = myri10ge_get_frag_header;
- lro_mgr->max_aggr = myri10ge_lro_max_pkts;
- lro_mgr->frag_align_pad = 2;
- if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
- lro_mgr->max_aggr = MAX_SKB_FRAGS;
-
- napi_enable(&mgp->ss.napi); /* must happen prior to any irq */
-
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_UP, &cmd, 0);
if (status) {
printk(KERN_ERR "myri10ge: %s: Couldn't bring up link\n",
@@ -2091,8 +2449,6 @@ static int myri10ge_open(struct net_device *dev)
goto abort_with_rings;
}
- mgp->ss.tx.wake_queue = 0;
- mgp->ss.tx.stop_queue = 0;
mgp->running = MYRI10GE_ETH_RUNNING;
mgp->watchdog_timer.expires = jiffies + myri10ge_watchdog_timeout * HZ;
add_timer(&mgp->watchdog_timer);
@@ -2100,9 +2456,9 @@ static int myri10ge_open(struct net_device *dev)
return 0;
abort_with_rings:
- myri10ge_free_rings(&mgp->ss);
+ for (i = 0; i < mgp->num_slices; i++)
+ myri10ge_free_rings(&mgp->ss[i]);
-abort_with_irq:
myri10ge_free_irq(mgp);
abort_with_nothing:
@@ -2115,16 +2471,19 @@ static int myri10ge_close(struct net_device *dev)
struct myri10ge_priv *mgp = netdev_priv(dev);
struct myri10ge_cmd cmd;
int status, old_down_cnt;
+ int i;
if (mgp->running != MYRI10GE_ETH_RUNNING)
return 0;
- if (mgp->ss.tx.req_bytes == NULL)
+ if (mgp->ss[0].tx.req_bytes == NULL)
return 0;
del_timer_sync(&mgp->watchdog_timer);
mgp->running = MYRI10GE_ETH_STOPPING;
- napi_disable(&mgp->ss.napi);
+ for (i = 0; i < mgp->num_slices; i++) {
+ napi_disable(&mgp->ss[i].napi);
+ }
netif_carrier_off(dev);
netif_stop_queue(dev);
old_down_cnt = mgp->down_cnt;
@@ -2140,7 +2499,8 @@ static int myri10ge_close(struct net_device *dev)
netif_tx_disable(dev);
myri10ge_free_irq(mgp);
- myri10ge_free_rings(&mgp->ss);
+ for (i = 0; i < mgp->num_slices; i++)
+ myri10ge_free_rings(&mgp->ss[i]);
mgp->running = MYRI10GE_ETH_STOPPED;
return 0;
@@ -2261,7 +2621,7 @@ static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
u8 flags, odd_flag;
/* always transmit through slot 0 */
- ss = &mgp->ss;
+ ss = mgp->ss;
tx = &ss->tx;
again:
req = tx->req_list;
@@ -2566,7 +2926,21 @@ drop:
static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
{
struct myri10ge_priv *mgp = netdev_priv(dev);
- return &mgp->stats;
+ struct myri10ge_slice_netstats *slice_stats;
+ struct net_device_stats *stats = &mgp->stats;
+ int i;
+
+ memset(stats, 0, sizeof(*stats));
+ for (i = 0; i < mgp->num_slices; i++) {
+ slice_stats = &mgp->ss[i].stats;
+ stats->rx_packets += slice_stats->rx_packets;
+ stats->tx_packets += slice_stats->tx_packets;
+ stats->rx_bytes += slice_stats->rx_bytes;
+ stats->tx_bytes += slice_stats->tx_bytes;
+ stats->rx_dropped += slice_stats->rx_dropped;
+ stats->tx_dropped += slice_stats->tx_dropped;
+ }
+ return stats;
}
static void myri10ge_set_multicast_list(struct net_device *dev)
@@ -2777,10 +3151,10 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
*
* If the driver can neither enable ECRC nor verify that it has
* already been enabled, then it must use a firmware image which works
- * around unaligned completion packets (myri10ge_ethp_z8e.dat), and it
+ * around unaligned completion packets (myri10ge_rss_ethp_z8e.dat), and it
* should also ensure that it never gives the device a Read-DMA which is
* larger than 2KB by setting the tx_boundary to 2KB. If ECRC is
- * enabled, then the driver should use the aligned (myri10ge_eth_z8e.dat)
+ * enabled, then the driver should use the aligned (myri10ge_rss_eth_z8e.dat)
* firmware image, and set tx_boundary to 4KB.
*/
@@ -2809,7 +3183,7 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
* completions) in order to see if it works on this host.
*/
mgp->fw_name = myri10ge_fw_aligned;
- status = myri10ge_load_firmware(mgp);
+ status = myri10ge_load_firmware(mgp, 1);
if (status != 0) {
goto abort;
}
@@ -2990,6 +3364,7 @@ static void myri10ge_watchdog(struct work_struct *work)
struct myri10ge_tx_buf *tx;
u32 reboot;
int status;
+ int i;
u16 cmd, vendor;
mgp->watchdog_resets++;
@@ -3037,20 +3412,26 @@ static void myri10ge_watchdog(struct work_struct *work)
printk(KERN_ERR "myri10ge: %s: device timeout, resetting\n",
mgp->dev->name);
- tx = &mgp->ss.tx;
- printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
- mgp->dev->name, tx->req, tx->done,
- tx->pkt_start, tx->pkt_done,
- (int)ntohl(mgp->ss.fw_stats->send_done_count));
- msleep(2000);
- printk(KERN_INFO "myri10ge: %s: %d %d %d %d %d\n",
- mgp->dev->name, tx->req, tx->done,
- tx->pkt_start, tx->pkt_done,
- (int)ntohl(mgp->ss.fw_stats->send_done_count));
+ for (i = 0; i < mgp->num_slices; i++) {
+ tx = &mgp->ss[i].tx;
+ printk(KERN_INFO
+ "myri10ge: %s: (%d): %d %d %d %d %d\n",
+ mgp->dev->name, i, tx->req, tx->done,
+ tx->pkt_start, tx->pkt_done,
+ (int)ntohl(mgp->ss[i].fw_stats->
+ send_done_count));
+ msleep(2000);
+ printk(KERN_INFO
+ "myri10ge: %s: (%d): %d %d %d %d %d\n",
+ mgp->dev->name, i, tx->req, tx->done,
+ tx->pkt_start, tx->pkt_done,
+ (int)ntohl(mgp->ss[i].fw_stats->
+ send_done_count));
+ }
}
rtnl_lock();
myri10ge_close(mgp->dev);
- status = myri10ge_load_firmware(mgp);
+ status = myri10ge_load_firmware(mgp, 1);
if (status != 0)
printk(KERN_ERR "myri10ge: %s: failed to load firmware\n",
mgp->dev->name);
@@ -3070,47 +3451,241 @@ static void myri10ge_watchdog_timer(unsigned long arg)
{
struct myri10ge_priv *mgp;
struct myri10ge_slice_state *ss;
+ int i, reset_needed;
u32 rx_pause_cnt;
mgp = (struct myri10ge_priv *)arg;
- rx_pause_cnt = ntohl(mgp->ss.fw_stats->dropped_pause);
+ rx_pause_cnt = ntohl(mgp->ss[0].fw_stats->dropped_pause);
+ for (i = 0, reset_needed = 0;
+ i < mgp->num_slices && reset_needed == 0; ++i) {
+
+ ss = &mgp->ss[i];
+ if (ss->rx_small.watchdog_needed) {
+ myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
+ mgp->small_bytes + MXGEFW_PAD,
+ 1);
+ if (ss->rx_small.fill_cnt - ss->rx_small.cnt >=
+ myri10ge_fill_thresh)
+ ss->rx_small.watchdog_needed = 0;
+ }
+ if (ss->rx_big.watchdog_needed) {
+ myri10ge_alloc_rx_pages(mgp, &ss->rx_big,
+ mgp->big_bytes, 1);
+ if (ss->rx_big.fill_cnt - ss->rx_big.cnt >=
+ myri10ge_fill_thresh)
+ ss->rx_big.watchdog_needed = 0;
+ }
- ss = &mgp->ss;
- if (ss->rx_small.watchdog_needed) {
- myri10ge_alloc_rx_pages(mgp, &ss->rx_small,
- mgp->small_bytes + MXGEFW_PAD, 1);
- if (ss->rx_small.fill_cnt - ss->rx_small.cnt >=
- myri10ge_fill_thresh)
- ss->rx_small.watchdog_needed = 0;
- }
- if (ss->rx_big.watchdog_needed) {
- myri10ge_alloc_rx_pages(mgp, &ss->rx_big, mgp->big_bytes, 1);
- if (ss->rx_big.fill_cnt - ss->rx_big.cnt >=
- myri10ge_fill_thresh)
- ss->rx_big.watchdog_needed = 0;
- }
-
- if (ss->tx.req != ss->tx.done &&
- ss->tx.done == ss->watchdog_tx_done &&
- ss->watchdog_tx_req != ss->watchdog_tx_done) {
- /* nic seems like it might be stuck.. */
- if (rx_pause_cnt != mgp->watchdog_pause) {
- if (net_ratelimit())
- printk(KERN_WARNING "myri10ge %s:"
- "TX paused, check link partner\n",
- mgp->dev->name);
- } else {
- schedule_work(&mgp->watchdog_work);
- return;
+ if (ss->tx.req != ss->tx.done &&
+ ss->tx.done == ss->watchdog_tx_done &&
+ ss->watchdog_tx_req != ss->watchdog_tx_done) {
+ /* nic seems like it might be stuck.. */
+ if (rx_pause_cnt != mgp->watchdog_pause) {
+ if (net_ratelimit())
+ printk(KERN_WARNING "myri10ge %s:"
+ "TX paused, check link partner\n",
+ mgp->dev->name);
+ } else {
+ reset_needed = 1;
+ }
}
+ ss->watchdog_tx_done = ss->tx.done;
+ ss->watchdog_tx_req = ss->tx.req;
}
- /* rearm timer */
- mod_timer(&mgp->watchdog_timer,
- jiffies + myri10ge_watchdog_timeout * HZ);
- ss->watchdog_tx_done = ss->tx.done;
- ss->watchdog_tx_req = ss->tx.req;
mgp->watchdog_pause = rx_pause_cnt;
+
+ if (reset_needed) {
+ schedule_work(&mgp->watchdog_work);
+ } else {
+ /* rearm timer */
+ mod_timer(&mgp->watchdog_timer,
+ jiffies + myri10ge_watchdog_timeout * HZ);
+ }
+}
+
+static void myri10ge_free_slices(struct myri10ge_priv *mgp)
+{
+ struct myri10ge_slice_state *ss;
+ struct pci_dev *pdev = mgp->pdev;
+ size_t bytes;
+ int i;
+
+ if (mgp->ss == NULL)
+ return;
+
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+ if (ss->rx_done.entry != NULL) {
+ bytes = mgp->max_intr_slots *
+ sizeof(*ss->rx_done.entry);
+ dma_free_coherent(&pdev->dev, bytes,
+ ss->rx_done.entry, ss->rx_done.bus);
+ ss->rx_done.entry = NULL;
+ }
+ if (ss->fw_stats != NULL) {
+ bytes = sizeof(*ss->fw_stats);
+ dma_free_coherent(&pdev->dev, bytes,
+ ss->fw_stats, ss->fw_stats_bus);
+ ss->fw_stats = NULL;
+ }
+ }
+ kfree(mgp->ss);
+ mgp->ss = NULL;
+}
+
+static int myri10ge_alloc_slices(struct myri10ge_priv *mgp)
+{
+ struct myri10ge_slice_state *ss;
+ struct pci_dev *pdev = mgp->pdev;
+ size_t bytes;
+ int i;
+
+ bytes = sizeof(*mgp->ss) * mgp->num_slices;
+ mgp->ss = kzalloc(bytes, GFP_KERNEL);
+ if (mgp->ss == NULL) {
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < mgp->num_slices; i++) {
+ ss = &mgp->ss[i];
+ bytes = mgp->max_intr_slots * sizeof(*ss->rx_done.entry);
+ ss->rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
+ &ss->rx_done.bus,
+ GFP_KERNEL);
+ if (ss->rx_done.entry == NULL)
+ goto abort;
+ memset(ss->rx_done.entry, 0, bytes);
+ bytes = sizeof(*ss->fw_stats);
+ ss->fw_stats = dma_alloc_coherent(&pdev->dev, bytes,
+ &ss->fw_stats_bus,
+ GFP_KERNEL);
+ if (ss->fw_stats == NULL)
+ goto abort;
+ ss->mgp = mgp;
+ ss->dev = mgp->dev;
+ netif_napi_add(ss->dev, &ss->napi, myri10ge_poll,
+ myri10ge_napi_weight);
+ }
+ return 0;
+abort:
+ myri10ge_free_slices(mgp);
+ return -ENOMEM;
+}
+
+/*
+ * This function determines the number of slices supported.
+ * The number slices is the minumum of the number of CPUS,
+ * the number of MSI-X irqs supported, the number of slices
+ * supported by the firmware
+ */
+static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
+{
+ struct myri10ge_cmd cmd;
+ struct pci_dev *pdev = mgp->pdev;
+ char *old_fw;
+ int i, status, ncpus, msix_cap;
+
+ mgp->num_slices = 1;
+ msix_cap = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
+ ncpus = num_online_cpus();
+
+ if (myri10ge_max_slices == 1 || msix_cap == 0 ||
+ (myri10ge_max_slices == -1 && ncpus < 2))
+ return;
+
+ /* try to load the slice aware rss firmware */
+ old_fw = mgp->fw_name;
+ if (old_fw == myri10ge_fw_aligned)
+ mgp->fw_name = myri10ge_fw_rss_aligned;
+ else
+ mgp->fw_name = myri10ge_fw_rss_unaligned;
+ status = myri10ge_load_firmware(mgp, 0);
+ if (status != 0) {
+ dev_info(&pdev->dev, "Rss firmware not found\n");
+ return;
+ }
+
+ /* hit the board with a reset to ensure it is alive */
+ memset(&cmd, 0, sizeof(cmd));
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_RESET, &cmd, 0);
+ if (status != 0) {
+ dev_err(&mgp->pdev->dev, "failed reset\n");
+ goto abort_with_fw;
+ return;
+ }
+
+ mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot);
+
+ /* tell it the size of the interrupt queues */
+ cmd.data0 = mgp->max_intr_slots * sizeof(struct mcp_slot);
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd, 0);
+ if (status != 0) {
+ dev_err(&mgp->pdev->dev, "failed MXGEFW_CMD_SET_INTRQ_SIZE\n");
+ goto abort_with_fw;
+ }
+
+ /* ask the maximum number of slices it supports */
+ status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_RSS_QUEUES, &cmd, 0);
+ if (status != 0)
+ goto abort_with_fw;
+ else
+ mgp->num_slices = cmd.data0;
+
+ /* Only allow multiple slices if MSI-X is usable */
+ if (!myri10ge_msi) {
+ goto abort_with_fw;
+ }
+
+ /* if the admin did not specify a limit to how many
+ * slices we should use, cap it automatically to the
+ * number of CPUs currently online */
+ if (myri10ge_max_slices == -1)
+ myri10ge_max_slices = ncpus;
+
+ if (mgp->num_slices > myri10ge_max_slices)
+ mgp->num_slices = myri10ge_max_slices;
+
+ /* Now try to allocate as many MSI-X vectors as we have
+ * slices. We give up on MSI-X if we can only get a single
+ * vector. */
+
+ mgp->msix_vectors = kzalloc(mgp->num_slices *
+ sizeof(*mgp->msix_vectors), GFP_KERNEL);
+ if (mgp->msix_vectors == NULL)
+ goto disable_msix;
+ for (i = 0; i < mgp->num_slices; i++) {
+ mgp->msix_vectors[i].entry = i;
+ }
+
+ while (mgp->num_slices > 1) {
+ /* make sure it is a power of two */
+ while (!is_power_of_2(mgp->num_slices))
+ mgp->num_slices--;
+ if (mgp->num_slices == 1)
+ goto disable_msix;
+ status = pci_enable_msix(pdev, mgp->msix_vectors,
+ mgp->num_slices);
+ if (status == 0) {
+ pci_disable_msix(pdev);
+ return;
+ }
+ if (status > 0)
+ mgp->num_slices = status;
+ else
+ goto disable_msix;
+ }
+
+disable_msix:
+ if (mgp->msix_vectors != NULL) {
+ kfree(mgp->msix_vectors);
+ mgp->msix_vectors = NULL;
+ }
+
+abort_with_fw:
+ mgp->num_slices = 1;
+ mgp->fw_name = old_fw;
+ myri10ge_load_firmware(mgp, 0);
}
static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -3118,7 +3693,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct net_device *netdev;
struct myri10ge_priv *mgp;
struct device *dev = &pdev->dev;
- size_t bytes;
int i;
int status = -ENXIO;
int dac_enabled;
@@ -3133,7 +3707,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp = netdev_priv(netdev);
mgp->dev = netdev;
- netif_napi_add(netdev, &mgp->ss.napi, myri10ge_poll, myri10ge_napi_weight);
mgp->pdev = pdev;
mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
mgp->pause = myri10ge_flow_control;
@@ -3179,11 +3752,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (mgp->cmd == NULL)
goto abort_with_netdev;
- mgp->ss.fw_stats = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
- &mgp->ss.fw_stats_bus, GFP_KERNEL);
- if (mgp->ss.fw_stats == NULL)
- goto abort_with_cmd;
-
mgp->board_span = pci_resource_len(pdev, 0);
mgp->iomem_base = pci_resource_start(pdev, 0);
mgp->mtrr = -1;
@@ -3220,28 +3788,28 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < ETH_ALEN; i++)
netdev->dev_addr[i] = mgp->mac_addr[i];
- /* allocate rx done ring */
- bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
- mgp->ss.rx_done.entry = dma_alloc_coherent(&pdev->dev, bytes,
- &mgp->ss.rx_done.bus, GFP_KERNEL);
- if (mgp->ss.rx_done.entry == NULL)
- goto abort_with_ioremap;
- memset(mgp->ss.rx_done.entry, 0, bytes);
-
myri10ge_select_firmware(mgp);
- status = myri10ge_load_firmware(mgp);
+ status = myri10ge_load_firmware(mgp, 1);
if (status != 0) {
dev_err(&pdev->dev, "failed to load firmware\n");
- goto abort_with_rx_done;
+ goto abort_with_ioremap;
+ }
+ myri10ge_probe_slices(mgp);
+ status = myri10ge_alloc_slices(mgp);
+ if (status != 0) {
+ dev_err(&pdev->dev, "failed to alloc slice state\n");
+ goto abort_with_firmware;
}
status = myri10ge_reset(mgp);
if (status != 0) {
dev_err(&pdev->dev, "failed reset\n");
- goto abort_with_firmware;
+ goto abort_with_slices;
}
-
+#ifdef CONFIG_DCA
+ myri10ge_setup_dca(mgp);
+#endif
pci_set_drvdata(pdev, mgp);
if ((myri10ge_initial_mtu + ETH_HLEN) > MYRI10GE_MAX_ETHER_MTU)
myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
@@ -3284,24 +3852,27 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(&pdev->dev, "register_netdev failed: %d\n", status);
goto abort_with_state;
}
- dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
- (mgp->msi_enabled ? "MSI" : "xPIC"),
- netdev->irq, mgp->tx_boundary, mgp->fw_name,
- (mgp->wc_enabled ? "Enabled" : "Disabled"));
+ if (mgp->msix_enabled)
+ dev_info(dev, "%d MSI-X IRQs, tx bndry %d, fw %s, WC %s\n",
+ mgp->num_slices, mgp->tx_boundary, mgp->fw_name,
+ (mgp->wc_enabled ? "Enabled" : "Disabled"));
+ else
+ dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
+ mgp->msi_enabled ? "MSI" : "xPIC",
+ netdev->irq, mgp->tx_boundary, mgp->fw_name,
+ (mgp->wc_enabled ? "Enabled" : "Disabled"));
return 0;
abort_with_state:
pci_restore_state(pdev);
+abort_with_slices:
+ myri10ge_free_slices(mgp);
+
abort_with_firmware:
myri10ge_dummy_rdma(mgp, 0);
-abort_with_rx_done:
- bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
- dma_free_coherent(&pdev->dev, bytes,
- mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
-
abort_with_ioremap:
iounmap(mgp->sram);
@@ -3310,10 +3881,6 @@ abort_with_wc:
if (mgp->mtrr >= 0)
mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
#endif
- dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
- mgp->ss.fw_stats, mgp->ss.fw_stats_bus);
-
-abort_with_cmd:
dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
mgp->cmd, mgp->cmd_bus);
@@ -3334,7 +3901,6 @@ static void myri10ge_remove(struct pci_dev *pdev)
{
struct myri10ge_priv *mgp;
struct net_device *netdev;
- size_t bytes;
mgp = pci_get_drvdata(pdev);
if (mgp == NULL)
@@ -3344,24 +3910,23 @@ static void myri10ge_remove(struct pci_dev *pdev)
netdev = mgp->dev;
unregister_netdev(netdev);
+#ifdef CONFIG_DCA
+ myri10ge_teardown_dca(mgp);
+#endif
myri10ge_dummy_rdma(mgp, 0);
/* avoid a memory leak */
pci_restore_state(pdev);
- bytes = mgp->max_intr_slots * sizeof(*mgp->ss.rx_done.entry);
- dma_free_coherent(&pdev->dev, bytes,
- mgp->ss.rx_done.entry, mgp->ss.rx_done.bus);
-
iounmap(mgp->sram);
#ifdef CONFIG_MTRR
if (mgp->mtrr >= 0)
mtrr_del(mgp->mtrr, mgp->iomem_base, mgp->board_span);
#endif
- dma_free_coherent(&pdev->dev, sizeof(*mgp->ss.fw_stats),
- mgp->ss.fw_stats, mgp->ss.fw_stats_bus);
-
+ myri10ge_free_slices(mgp);
+ if (mgp->msix_vectors != NULL)
+ kfree(mgp->msix_vectors);
dma_free_coherent(&pdev->dev, sizeof(*mgp->cmd),
mgp->cmd, mgp->cmd_bus);
@@ -3390,10 +3955,42 @@ static struct pci_driver myri10ge_driver = {
#endif
};
+#ifdef CONFIG_DCA
+static int
+myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
+{
+ int err = driver_for_each_device(&myri10ge_driver.driver,
+ NULL, &event,
+ myri10ge_notify_dca_device);
+
+ if (err)
+ return NOTIFY_BAD;
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block myri10ge_dca_notifier = {
+ .notifier_call = myri10ge_notify_dca,
+ .next = NULL,
+ .priority = 0,
+};
+#endif /* CONFIG_DCA */
+
static __init int myri10ge_init_module(void)
{
printk(KERN_INFO "%s: Version %s\n", myri10ge_driver.name,
MYRI10GE_VERSION_STR);
+
+ if (myri10ge_rss_hash > MXGEFW_RSS_HASH_TYPE_SRC_PORT ||
+ myri10ge_rss_hash < MXGEFW_RSS_HASH_TYPE_IPV4) {
+ printk(KERN_ERR
+ "%s: Illegal rssh hash type %d, defaulting to source port\n",
+ myri10ge_driver.name, myri10ge_rss_hash);
+ myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
+ }
+#ifdef CONFIG_DCA
+ dca_register_notify(&myri10ge_dca_notifier);
+#endif
+
return pci_register_driver(&myri10ge_driver);
}
@@ -3401,6 +3998,9 @@ module_init(myri10ge_init_module);
static __exit void myri10ge_cleanup_module(void)
{
+#ifdef CONFIG_DCA
+ dca_unregister_notify(&myri10ge_dca_notifier);
+#endif
pci_unregister_driver(&myri10ge_driver);
}
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 46119bb3770..b238ed0e8ac 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -664,7 +664,7 @@ static ssize_t natsemi_show_##_name(struct device *dev, \
NATSEMI_ATTR(dspcfg_workaround);
static ssize_t natsemi_show_dspcfg_workaround(struct device *dev,
- struct device_attribute *attr,
+ struct device_attribute *attr,
char *buf)
{
struct netdev_private *np = netdev_priv(to_net_dev(dev));
@@ -687,7 +687,7 @@ static ssize_t natsemi_set_dspcfg_workaround(struct device *dev,
|| !strncmp("0", buf, count - 1))
new_setting = 0;
else
- return count;
+ return count;
spin_lock_irqsave(&np->lock, flags);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 874d291cbae..14126973bd1 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -217,7 +217,7 @@ static int __init do_ne_probe(struct net_device *dev)
#ifndef MODULE
struct net_device * __init ne_probe(int unit)
{
- struct net_device *dev = alloc_ei_netdev();
+ struct net_device *dev = alloc_eip_netdev();
int err;
if (!dev)
@@ -490,7 +490,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
- ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
+ ret = request_irq(dev->irq, eip_interrupt, 0, name, dev);
if (ret) {
printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
goto err_out;
@@ -534,7 +534,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
dev->open = &ne_open;
dev->stop = &ne_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
+ dev->poll_controller = eip_poll;
#endif
NS8390_init(dev, 0);
@@ -554,7 +554,7 @@ err_out:
static int ne_open(struct net_device *dev)
{
- ei_open(dev);
+ eip_open(dev);
return 0;
}
@@ -562,7 +562,7 @@ static int ne_close(struct net_device *dev)
{
if (ei_debug > 1)
printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
- ei_close(dev);
+ eip_close(dev);
return 0;
}
@@ -814,7 +814,7 @@ static int __init ne_drv_probe(struct platform_device *pdev)
if (!res || irq < 0)
return -ENODEV;
- dev = alloc_ei_netdev();
+ dev = alloc_eip_netdev();
if (!dev)
return -ENOMEM;
dev->irq = irq;
@@ -912,7 +912,7 @@ int __init init_module(void)
int plat_found = !ne_init();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- struct net_device *dev = alloc_ei_netdev();
+ struct net_device *dev = alloc_eip_netdev();
if (!dev)
break;
dev->irq = irq[this_dev];
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index f4cd8c7e81b..8f725634692 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -280,7 +280,7 @@ static int __init do_ne2_probe(struct net_device *dev)
#ifndef MODULE
struct net_device * __init ne2_probe(int unit)
{
- struct net_device *dev = alloc_ei_netdev();
+ struct net_device *dev = alloc_eip_netdev();
int err;
if (!dev)
@@ -457,7 +457,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
- retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
+ retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev);
if (retval) {
printk (" unable to get IRQ %d (irqval=%d).\n",
dev->irq, retval);
@@ -497,9 +497,9 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
dev->open = &ne_open;
dev->stop = &ne_close;
#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
+ dev->poll_controller = eip_poll;
#endif
- NS8390_init(dev, 0);
+ NS8390p_init(dev, 0);
retval = register_netdev(dev);
if (retval)
@@ -515,7 +515,7 @@ out:
static int ne_open(struct net_device *dev)
{
- ei_open(dev);
+ eip_open(dev);
return 0;
}
@@ -523,7 +523,7 @@ static int ne_close(struct net_device *dev)
{
if (ei_debug > 1)
printk("%s: Shutting down ethercard.\n", dev->name);
- ei_close(dev);
+ eip_close(dev);
return 0;
}
@@ -748,7 +748,7 @@ retry:
if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
printk("%s: timeout waiting for Tx RDC.\n", dev->name);
ne_reset_8390(dev);
- NS8390_init(dev,1);
+ NS8390p_init(dev, 1);
break;
}
@@ -781,7 +781,7 @@ int __init init_module(void)
int this_dev, found = 0;
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- dev = alloc_ei_netdev();
+ dev = alloc_eip_netdev();
if (!dev)
break;
dev->irq = irq[this_dev];
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 387a1339501..e13966bb5f7 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -585,9 +585,8 @@ static struct config_item_type netconsole_target_type = {
* Group operations and type for netconsole_subsys.
*/
-static int make_netconsole_target(struct config_group *group,
- const char *name,
- struct config_item **new_item)
+static struct config_item *make_netconsole_target(struct config_group *group,
+ const char *name)
{
unsigned long flags;
struct netconsole_target *nt;
@@ -599,7 +598,7 @@ static int make_netconsole_target(struct config_group *group,
nt = kzalloc(sizeof(*nt), GFP_KERNEL);
if (!nt) {
printk(KERN_ERR "netconsole: failed to allocate memory\n");
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
nt->np.name = "netconsole";
@@ -616,8 +615,7 @@ static int make_netconsole_target(struct config_group *group,
list_add(&nt->list, &target_list);
spin_unlock_irqrestore(&target_list_lock, flags);
- *new_item = &nt->item;
- return 0;
+ return &nt->item;
}
static void drop_netconsole_target(struct config_group *group,
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 918f802fe08..8ee7d7bb951 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -3236,10 +3236,14 @@ static int release_tx_packet(struct niu *np, struct tx_ring_info *rp, int idx)
static void niu_tx_work(struct niu *np, struct tx_ring_info *rp)
{
+ struct netdev_queue *txq;
u16 pkt_cnt, tmp;
- int cons;
+ int cons, index;
u64 cs;
+ index = (rp - np->tx_rings);
+ txq = netdev_get_tx_queue(np->dev, index);
+
cs = rp->tx_cs;
if (unlikely(!(cs & (TX_CS_MK | TX_CS_MMK))))
goto out;
@@ -3262,13 +3266,13 @@ static void niu_tx_work(struct niu *np, struct tx_ring_info *rp)
smp_mb();
out:
- if (unlikely(netif_queue_stopped(np->dev) &&
+ if (unlikely(netif_tx_queue_stopped(txq) &&
(niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)))) {
- netif_tx_lock(np->dev);
- if (netif_queue_stopped(np->dev) &&
+ __netif_tx_lock(txq, smp_processor_id());
+ if (netif_tx_queue_stopped(txq) &&
(niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)))
- netif_wake_queue(np->dev);
- netif_tx_unlock(np->dev);
+ netif_tx_wake_queue(txq);
+ __netif_tx_unlock(txq);
}
}
@@ -4061,6 +4065,8 @@ static int niu_alloc_channels(struct niu *np)
np->num_rx_rings = parent->rxchan_per_port[port];
np->num_tx_rings = parent->txchan_per_port[port];
+ np->dev->real_num_tx_queues = np->num_tx_rings;
+
np->rx_rings = kzalloc(np->num_rx_rings * sizeof(struct rx_ring_info),
GFP_KERNEL);
err = -ENOMEM;
@@ -5686,7 +5692,7 @@ static int niu_open(struct net_device *dev)
goto out_free_irq;
}
- netif_start_queue(dev);
+ netif_tx_start_all_queues(dev);
if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
netif_carrier_on(dev);
@@ -5710,7 +5716,7 @@ static void niu_full_shutdown(struct niu *np, struct net_device *dev)
cancel_work_sync(&np->reset_task);
niu_disable_napi(np);
- netif_stop_queue(dev);
+ netif_tx_stop_all_queues(dev);
del_timer_sync(&np->timer);
@@ -5971,7 +5977,7 @@ static void niu_netif_start(struct niu *np)
* so long as all callers are assured to have free tx slots
* (such as after niu_init_hw).
*/
- netif_wake_queue(np->dev);
+ netif_tx_wake_all_queues(np->dev);
niu_enable_napi(np);
@@ -6097,15 +6103,11 @@ static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr,
return ret;
}
-static struct tx_ring_info *tx_ring_select(struct niu *np, struct sk_buff *skb)
-{
- return &np->tx_rings[0];
-}
-
static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct niu *np = netdev_priv(dev);
unsigned long align, headroom;
+ struct netdev_queue *txq;
struct tx_ring_info *rp;
struct tx_pkt_hdr *tp;
unsigned int len, nfg;
@@ -6113,10 +6115,12 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
int prod, i, tlen;
u64 mapping, mrk;
- rp = tx_ring_select(np, skb);
+ i = skb_get_queue_mapping(skb);
+ rp = &np->tx_rings[i];
+ txq = netdev_get_tx_queue(dev, i);
if (niu_tx_avail(rp) <= (skb_shinfo(skb)->nr_frags + 1)) {
- netif_stop_queue(dev);
+ netif_tx_stop_queue(txq);
dev_err(np->device, PFX "%s: BUG! Tx ring full when "
"queue awake!\n", dev->name);
rp->tx_errors++;
@@ -6215,9 +6219,9 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
nw64(TX_RING_KICK(rp->tx_channel), rp->wrap_bit | (prod << 3));
if (unlikely(niu_tx_avail(rp) <= (MAX_SKB_FRAGS + 1))) {
- netif_stop_queue(dev);
+ netif_tx_stop_queue(txq);
if (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp))
- netif_wake_queue(dev);
+ netif_tx_wake_queue(txq);
}
dev->trans_start = jiffies;
@@ -6275,7 +6279,7 @@ static int niu_change_mtu(struct net_device *dev, int new_mtu)
spin_unlock_irq(&np->lock);
if (!err) {
- netif_start_queue(dev);
+ netif_tx_start_all_queues(dev);
if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
netif_carrier_on(dev);
@@ -6385,6 +6389,162 @@ static int niu_get_eeprom(struct net_device *dev,
return 0;
}
+static int niu_ethflow_to_class(int flow_type, u64 *class)
+{
+ switch (flow_type) {
+ case TCP_V4_FLOW:
+ *class = CLASS_CODE_TCP_IPV4;
+ break;
+ case UDP_V4_FLOW:
+ *class = CLASS_CODE_UDP_IPV4;
+ break;
+ case AH_ESP_V4_FLOW:
+ *class = CLASS_CODE_AH_ESP_IPV4;
+ break;
+ case SCTP_V4_FLOW:
+ *class = CLASS_CODE_SCTP_IPV4;
+ break;
+ case TCP_V6_FLOW:
+ *class = CLASS_CODE_TCP_IPV6;
+ break;
+ case UDP_V6_FLOW:
+ *class = CLASS_CODE_UDP_IPV6;
+ break;
+ case AH_ESP_V6_FLOW:
+ *class = CLASS_CODE_AH_ESP_IPV6;
+ break;
+ case SCTP_V6_FLOW:
+ *class = CLASS_CODE_SCTP_IPV6;
+ break;
+ default:
+ return -1;
+ }
+
+ return 1;
+}
+
+static u64 niu_flowkey_to_ethflow(u64 flow_key)
+{
+ u64 ethflow = 0;
+
+ if (flow_key & FLOW_KEY_PORT)
+ ethflow |= RXH_DEV_PORT;
+ if (flow_key & FLOW_KEY_L2DA)
+ ethflow |= RXH_L2DA;
+ if (flow_key & FLOW_KEY_VLAN)
+ ethflow |= RXH_VLAN;
+ if (flow_key & FLOW_KEY_IPSA)
+ ethflow |= RXH_IP_SRC;
+ if (flow_key & FLOW_KEY_IPDA)
+ ethflow |= RXH_IP_DST;
+ if (flow_key & FLOW_KEY_PROTO)
+ ethflow |= RXH_L3_PROTO;
+ if (flow_key & (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_0_SHIFT))
+ ethflow |= RXH_L4_B_0_1;
+ if (flow_key & (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_1_SHIFT))
+ ethflow |= RXH_L4_B_2_3;
+
+ return ethflow;
+
+}
+
+static int niu_ethflow_to_flowkey(u64 ethflow, u64 *flow_key)
+{
+ u64 key = 0;
+
+ if (ethflow & RXH_DEV_PORT)
+ key |= FLOW_KEY_PORT;
+ if (ethflow & RXH_L2DA)
+ key |= FLOW_KEY_L2DA;
+ if (ethflow & RXH_VLAN)
+ key |= FLOW_KEY_VLAN;
+ if (ethflow & RXH_IP_SRC)
+ key |= FLOW_KEY_IPSA;
+ if (ethflow & RXH_IP_DST)
+ key |= FLOW_KEY_IPDA;
+ if (ethflow & RXH_L3_PROTO)
+ key |= FLOW_KEY_PROTO;
+ if (ethflow & RXH_L4_B_0_1)
+ key |= (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_0_SHIFT);
+ if (ethflow & RXH_L4_B_2_3)
+ key |= (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_1_SHIFT);
+
+ *flow_key = key;
+
+ return 1;
+
+}
+
+static int niu_get_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ struct niu *np = netdev_priv(dev);
+ u64 class;
+
+ cmd->data = 0;
+
+ if (!niu_ethflow_to_class(cmd->flow_type, &class))
+ return -EINVAL;
+
+ if (np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] &
+ TCAM_KEY_DISC)
+ cmd->data = RXH_DISCARD;
+ else
+
+ cmd->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
+ CLASS_CODE_USER_PROG1]);
+ return 0;
+}
+
+static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ struct niu *np = netdev_priv(dev);
+ u64 class;
+ u64 flow_key = 0;
+ unsigned long flags;
+
+ if (!niu_ethflow_to_class(cmd->flow_type, &class))
+ return -EINVAL;
+
+ if (class < CLASS_CODE_USER_PROG1 ||
+ class > CLASS_CODE_SCTP_IPV6)
+ return -EINVAL;
+
+ if (cmd->data & RXH_DISCARD) {
+ niu_lock_parent(np, flags);
+ flow_key = np->parent->tcam_key[class -
+ CLASS_CODE_USER_PROG1];
+ flow_key |= TCAM_KEY_DISC;
+ nw64(TCAM_KEY(class - CLASS_CODE_USER_PROG1), flow_key);
+ np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] = flow_key;
+ niu_unlock_parent(np, flags);
+ return 0;
+ } else {
+ /* Discard was set before, but is not set now */
+ if (np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] &
+ TCAM_KEY_DISC) {
+ niu_lock_parent(np, flags);
+ flow_key = np->parent->tcam_key[class -
+ CLASS_CODE_USER_PROG1];
+ flow_key &= ~TCAM_KEY_DISC;
+ nw64(TCAM_KEY(class - CLASS_CODE_USER_PROG1),
+ flow_key);
+ np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] =
+ flow_key;
+ niu_unlock_parent(np, flags);
+ }
+ }
+
+ if (!niu_ethflow_to_flowkey(cmd->data, &flow_key))
+ return -EINVAL;
+
+ niu_lock_parent(np, flags);
+ nw64(FLOW_KEY(class - CLASS_CODE_USER_PROG1), flow_key);
+ np->parent->flow_key[class - CLASS_CODE_USER_PROG1] = flow_key;
+ niu_unlock_parent(np, flags);
+
+ return 0;
+}
+
static const struct {
const char string[ETH_GSTRING_LEN];
} niu_xmac_stat_keys[] = {
@@ -6615,6 +6775,8 @@ static const struct ethtool_ops niu_ethtool_ops = {
.get_stats_count = niu_get_stats_count,
.get_ethtool_stats = niu_get_ethtool_stats,
.phys_id = niu_phys_id,
+ .get_rxhash = niu_get_hash_opts,
+ .set_rxhash = niu_set_hash_opts,
};
static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -8374,9 +8536,10 @@ static struct net_device * __devinit niu_alloc_and_init(
struct of_device *op, const struct niu_ops *ops,
u8 port)
{
- struct net_device *dev = alloc_etherdev(sizeof(struct niu));
+ struct net_device *dev;
struct niu *np;
+ dev = alloc_etherdev_mq(sizeof(struct niu), NIU_NUM_TXCHAN);
if (!dev) {
dev_err(gen_dev, PFX "Etherdev alloc failed, aborting.\n");
return NULL;
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 12fd570b942..c6fa883daa2 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -281,7 +281,7 @@
#define XMAC_ADDR1 0x000a8UL
#define XMAC_ADDR1_ADDR1 0x000000000000ffffULL
-#define XMAC_ADDR2 0x000b0UL
+#define XMAC_ADDR2 0x000b0UL
#define XMAC_ADDR2_ADDR2 0x000000000000ffffULL
#define XMAC_ADDR_CMPEN 0x00208UL
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index b42c05f84be..ff449619f04 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -585,16 +585,13 @@ static inline int rx_refill(struct net_device *ndev, gfp_t gfp)
for (i=0; i<NR_RX_DESC; i++) {
struct sk_buff *skb;
long res;
+
/* extra 16 bytes for alignment */
- skb = __dev_alloc_skb(REAL_RX_BUF_SIZE+16, gfp);
+ skb = __netdev_alloc_skb(ndev, REAL_RX_BUF_SIZE+16, gfp);
if (unlikely(!skb))
break;
- res = (long)skb->data & 0xf;
- res = 0x10 - res;
- res &= 0xf;
- skb_reserve(skb, res);
-
+ skb_reserve(skb, skb->data - PTR_ALIGN(skb->data, 16));
if (gfp != GFP_ATOMIC)
spin_lock_irqsave(&dev->rx_info.lock, flags);
res = ns83820_add_rx_skb(dev, skb);
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index fffc49befe0..53451c3b2c0 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -1739,7 +1739,6 @@ static int netdrv_close (struct net_device *dev)
spin_unlock_irqrestore (&tp->lock, flags);
- synchronize_irq (dev->irq);
free_irq (dev->irq, dev);
netdrv_tx_clear (dev);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 3b78a3819bb..7112fd5e0e1 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -208,7 +208,6 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
struct el3_private {
struct pcmcia_device *p_dev;
dev_node_t node;
- struct net_device_stats stats;
u16 advertising, partner; /* NWay media advertisement */
unsigned char phys; /* MII device address */
unsigned int autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */
@@ -741,12 +740,11 @@ static int el3_open(struct net_device *dev)
static void el3_tx_timeout(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
dump_status(dev);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev->trans_start = jiffies;
/* Issue TX_RESET and TX_START commands. */
tc574_wait_for_completion(dev, TxReset);
@@ -756,7 +754,6 @@ static void el3_tx_timeout(struct net_device *dev)
static void pop_tx_status(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int i;
@@ -772,7 +769,7 @@ static void pop_tx_status(struct net_device *dev)
DEBUG(1, "%s: transmit error: status 0x%02x\n",
dev->name, tx_status);
outw(TxEnable, ioaddr + EL3_CMD);
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
}
outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
}
@@ -987,7 +984,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
update_stats(dev);
spin_unlock_irqrestore(&lp->window_lock, flags);
}
- return &lp->stats;
+ return &dev->stats;
}
/* Update statistics.
@@ -996,7 +993,6 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
*/
static void update_stats(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
u8 rx, tx, up;
@@ -1008,15 +1004,15 @@ static void update_stats(struct net_device *dev)
/* Unlike the 3c509 we need not turn off stats updates while reading. */
/* Switch to the stats window, and read everything. */
EL3WINDOW(6);
- lp->stats.tx_carrier_errors += inb(ioaddr + 0);
- lp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
+ dev->stats.tx_carrier_errors += inb(ioaddr + 0);
+ dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
/* Multiple collisions. */ inb(ioaddr + 2);
- lp->stats.collisions += inb(ioaddr + 3);
- lp->stats.tx_window_errors += inb(ioaddr + 4);
- lp->stats.rx_fifo_errors += inb(ioaddr + 5);
- lp->stats.tx_packets += inb(ioaddr + 6);
+ dev->stats.collisions += inb(ioaddr + 3);
+ dev->stats.tx_window_errors += inb(ioaddr + 4);
+ dev->stats.rx_fifo_errors += inb(ioaddr + 5);
+ dev->stats.tx_packets += inb(ioaddr + 6);
up = inb(ioaddr + 9);
- lp->stats.tx_packets += (up&0x30) << 4;
+ dev->stats.tx_packets += (up&0x30) << 4;
/* Rx packets */ inb(ioaddr + 7);
/* Tx deferrals */ inb(ioaddr + 8);
rx = inw(ioaddr + 10);
@@ -1026,14 +1022,13 @@ static void update_stats(struct net_device *dev)
/* BadSSD */ inb(ioaddr + 12);
up = inb(ioaddr + 13);
- lp->stats.tx_bytes += tx + ((up & 0xf0) << 12);
+ dev->stats.tx_bytes += tx + ((up & 0xf0) << 12);
EL3WINDOW(1);
}
static int el3_rx(struct net_device *dev, int worklimit)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
short rx_status;
@@ -1043,14 +1038,14 @@ static int el3_rx(struct net_device *dev, int worklimit)
(--worklimit >= 0)) {
if (rx_status & 0x4000) { /* Error, update stats. */
short error = rx_status & 0x3800;
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
switch (error) {
- case 0x0000: lp->stats.rx_over_errors++; break;
- case 0x0800: lp->stats.rx_length_errors++; break;
- case 0x1000: lp->stats.rx_frame_errors++; break;
- case 0x1800: lp->stats.rx_length_errors++; break;
- case 0x2000: lp->stats.rx_frame_errors++; break;
- case 0x2800: lp->stats.rx_crc_errors++; break;
+ case 0x0000: dev->stats.rx_over_errors++; break;
+ case 0x0800: dev->stats.rx_length_errors++; break;
+ case 0x1000: dev->stats.rx_frame_errors++; break;
+ case 0x1800: dev->stats.rx_length_errors++; break;
+ case 0x2000: dev->stats.rx_frame_errors++; break;
+ case 0x2800: dev->stats.rx_crc_errors++; break;
}
} else {
short pkt_len = rx_status & 0x7ff;
@@ -1067,12 +1062,12 @@ static int el3_rx(struct net_device *dev, int worklimit)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
} else {
DEBUG(1, "%s: couldn't allocate a sk_buff of"
" size %d.\n", dev->name, pkt_len);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
tc574_wait_for_completion(dev, RxDiscard);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 1b1abb19c91..549a6455842 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -107,7 +107,6 @@ enum RxFilter {
struct el3_private {
struct pcmcia_device *p_dev;
dev_node_t node;
- struct net_device_stats stats;
/* For transceiver monitoring */
struct timer_list media;
u16 media_status;
@@ -566,12 +565,11 @@ static int el3_open(struct net_device *dev)
static void el3_tx_timeout(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
printk(KERN_WARNING "%s: Transmit timed out!\n", dev->name);
dump_status(dev);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev->trans_start = jiffies;
/* Issue TX_RESET and TX_START commands. */
tc589_wait_for_completion(dev, TxReset);
@@ -581,7 +579,6 @@ static void el3_tx_timeout(struct net_device *dev)
static void pop_tx_status(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int i;
@@ -596,7 +593,7 @@ static void pop_tx_status(struct net_device *dev)
DEBUG(1, "%s: transmit error: status 0x%02x\n",
dev->name, tx_status);
outw(TxEnable, ioaddr + EL3_CMD);
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
}
outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
}
@@ -614,7 +611,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&priv->lock, flags);
- priv->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* Put out the doubleword header... */
outw(skb->len, ioaddr + TX_FIFO);
@@ -764,7 +761,7 @@ static void media_check(unsigned long arg)
outw(StatsDisable, ioaddr + EL3_CMD);
errs = inb(ioaddr + 0);
outw(StatsEnable, ioaddr + EL3_CMD);
- lp->stats.tx_carrier_errors += errs;
+ dev->stats.tx_carrier_errors += errs;
if (errs || (lp->media_status & 0x0010)) media |= 0x0010;
}
@@ -814,7 +811,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
update_stats(dev);
spin_unlock_irqrestore(&lp->lock, flags);
}
- return &lp->stats;
+ return &dev->stats;
}
/*
@@ -827,7 +824,6 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
*/
static void update_stats(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
DEBUG(2, "%s: updating the statistics.\n", dev->name);
@@ -835,13 +831,13 @@ static void update_stats(struct net_device *dev)
outw(StatsDisable, ioaddr + EL3_CMD);
/* Switch to the stats window, and read everything. */
EL3WINDOW(6);
- lp->stats.tx_carrier_errors += inb(ioaddr + 0);
- lp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
+ dev->stats.tx_carrier_errors += inb(ioaddr + 0);
+ dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
/* Multiple collisions. */ inb(ioaddr + 2);
- lp->stats.collisions += inb(ioaddr + 3);
- lp->stats.tx_window_errors += inb(ioaddr + 4);
- lp->stats.rx_fifo_errors += inb(ioaddr + 5);
- lp->stats.tx_packets += inb(ioaddr + 6);
+ dev->stats.collisions += inb(ioaddr + 3);
+ dev->stats.tx_window_errors += inb(ioaddr + 4);
+ dev->stats.rx_fifo_errors += inb(ioaddr + 5);
+ dev->stats.tx_packets += inb(ioaddr + 6);
/* Rx packets */ inb(ioaddr + 7);
/* Tx deferrals */ inb(ioaddr + 8);
/* Rx octets */ inw(ioaddr + 10);
@@ -854,7 +850,6 @@ static void update_stats(struct net_device *dev)
static int el3_rx(struct net_device *dev)
{
- struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int worklimit = 32;
short rx_status;
@@ -865,14 +860,14 @@ static int el3_rx(struct net_device *dev)
(--worklimit >= 0)) {
if (rx_status & 0x4000) { /* Error, update stats. */
short error = rx_status & 0x3800;
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
switch (error) {
- case 0x0000: lp->stats.rx_over_errors++; break;
- case 0x0800: lp->stats.rx_length_errors++; break;
- case 0x1000: lp->stats.rx_frame_errors++; break;
- case 0x1800: lp->stats.rx_length_errors++; break;
- case 0x2000: lp->stats.rx_frame_errors++; break;
- case 0x2800: lp->stats.rx_crc_errors++; break;
+ case 0x0000: dev->stats.rx_over_errors++; break;
+ case 0x0800: dev->stats.rx_length_errors++; break;
+ case 0x1000: dev->stats.rx_frame_errors++; break;
+ case 0x1800: dev->stats.rx_length_errors++; break;
+ case 0x2000: dev->stats.rx_frame_errors++; break;
+ case 0x2800: dev->stats.rx_crc_errors++; break;
}
} else {
short pkt_len = rx_status & 0x7ff;
@@ -889,12 +884,12 @@ static int el3_rx(struct net_device *dev)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
} else {
DEBUG(1, "%s: couldn't allocate a sk_buff of"
" size %d.\n", dev->name, pkt_len);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
/* Pop the top of the Rx FIFO */
@@ -929,7 +924,7 @@ static int el3_close(struct net_device *dev)
DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
if (pcmcia_dev_present(link)) {
- /* Turn off statistics ASAP. We update lp->stats below. */
+ /* Turn off statistics ASAP. We update dev->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);
/* Disable the receiver and transmitter. */
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 70d012e90dc..3f682d49a4e 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -1023,7 +1023,7 @@ static void ei_tx_timeout(struct net_device *dev)
int txsr, isr, tickssofar = jiffies - dev->trans_start;
unsigned long flags;
- ei_local->stat.tx_errors++;
+ dev->stats.tx_errors++;
spin_lock_irqsave(&ei_local->page_lock, flags);
txsr = inb(e8390_base+EN0_TSR);
@@ -1034,7 +1034,7 @@ static void ei_tx_timeout(struct net_device *dev)
dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
(isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
- if (!isr && !ei_local->stat.tx_packets)
+ if (!isr && !dev->stats.tx_packets)
{
/* The 8390 probably hasn't gotten on the cable yet. */
ei_local->interface_num ^= 1; /* Try a different xcvr. */
@@ -1124,7 +1124,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- ei_local->stat.tx_errors++;
+ dev->stats.tx_errors++;
return 1;
}
@@ -1172,7 +1172,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&ei_local->page_lock, flags);
dev_kfree_skb (skb);
- ei_local->stat.tx_bytes += send_length;
+ dev->stats.tx_bytes += send_length;
return 0;
}
@@ -1264,9 +1264,9 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
if (interrupts & ENISR_COUNTERS)
{
- ei_local->stat.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0);
- ei_local->stat.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1);
- ei_local->stat.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2);
+ dev->stats.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0);
+ dev->stats.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1);
+ dev->stats.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2);
}
}
@@ -1311,7 +1311,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
static void ei_tx_err(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
unsigned char txsr = inb_p(e8390_base+EN0_TSR);
unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
@@ -1334,10 +1333,10 @@ static void ei_tx_err(struct net_device *dev)
ei_tx_intr(dev);
else
{
- ei_local->stat.tx_errors++;
- if (txsr & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
- if (txsr & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
- if (txsr & ENTSR_OWC) ei_local->stat.tx_window_errors++;
+ dev->stats.tx_errors++;
+ if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++;
+ if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++;
+ if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++;
}
}
@@ -1399,25 +1398,25 @@ static void ei_tx_intr(struct net_device *dev)
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
- ei_local->stat.collisions++;
+ dev->stats.collisions++;
if (status & ENTSR_PTX)
- ei_local->stat.tx_packets++;
+ dev->stats.tx_packets++;
else
{
- ei_local->stat.tx_errors++;
+ dev->stats.tx_errors++;
if (status & ENTSR_ABT)
{
- ei_local->stat.tx_aborted_errors++;
- ei_local->stat.collisions += 16;
+ dev->stats.tx_aborted_errors++;
+ dev->stats.collisions += 16;
}
if (status & ENTSR_CRS)
- ei_local->stat.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if (status & ENTSR_FU)
- ei_local->stat.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if (status & ENTSR_CDH)
- ei_local->stat.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
if (status & ENTSR_OWC)
- ei_local->stat.tx_window_errors++;
+ dev->stats.tx_window_errors++;
}
netif_wake_queue(dev);
}
@@ -1478,8 +1477,8 @@ static void ei_receive(struct net_device *dev)
printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
dev->name, rx_frame.count, rx_frame.status,
rx_frame.next);
- ei_local->stat.rx_errors++;
- ei_local->stat.rx_length_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
}
else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
{
@@ -1491,7 +1490,7 @@ static void ei_receive(struct net_device *dev)
if (ei_debug > 1)
printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, pkt_len);
- ei_local->stat.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
else
@@ -1502,10 +1501,10 @@ static void ei_receive(struct net_device *dev)
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
dev->last_rx = jiffies;
- ei_local->stat.rx_packets++;
- ei_local->stat.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
if (pkt_stat & ENRSR_PHY)
- ei_local->stat.multicast++;
+ dev->stats.multicast++;
}
}
else
@@ -1514,10 +1513,10 @@ static void ei_receive(struct net_device *dev)
printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
dev->name, rx_frame.status, rx_frame.next,
rx_frame.count);
- ei_local->stat.rx_errors++;
+ dev->stats.rx_errors++;
/* NB: The NIC counts CRC, frame and missed errors. */
if (pkt_stat & ENRSR_FO)
- ei_local->stat.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
}
next_frame = rx_frame.next;
@@ -1552,7 +1551,6 @@ static void ei_rx_overrun(struct net_device *dev)
axnet_dev_t *info = PRIV(dev);
long e8390_base = dev->base_addr;
unsigned char was_txing, must_resend = 0;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
/*
* Record whether a Tx was in progress and then issue the
@@ -1563,7 +1561,7 @@ static void ei_rx_overrun(struct net_device *dev)
if (ei_debug > 1)
printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);
- ei_local->stat.rx_over_errors++;
+ dev->stats.rx_over_errors++;
/*
* Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total.
@@ -1624,16 +1622,16 @@ static struct net_device_stats *get_stats(struct net_device *dev)
/* If the card is stopped, just return the present stats. */
if (!netif_running(dev))
- return &ei_local->stat;
+ return &dev->stats;
spin_lock_irqsave(&ei_local->page_lock,flags);
/* Read the counter registers, assuming we are in page 0. */
- ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0);
- ei_local->stat.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1);
- ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2);
+ dev->stats.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0);
+ dev->stats.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1);
+ dev->stats.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- return &ei_local->stat;
+ return &dev->stats;
}
/*
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 1c89b97f4e0..ca8c0e03740 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1973,7 +1973,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
err_free_ring:
pcnet32_free_ring(dev);
err_free_consistent:
- pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
+ pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
lp->init_block, lp->init_dma_addr);
err_free_netdev:
free_netdev(dev);
@@ -2953,7 +2953,7 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
unregister_netdev(dev);
pcnet32_free_ring(dev);
release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
- pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
+ pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
lp->init_block, lp->init_dma_addr);
free_netdev(dev);
pci_disable_device(pdev);
@@ -3036,7 +3036,7 @@ static void __exit pcnet32_cleanup_module(void)
unregister_netdev(pcnet32_dev);
pcnet32_free_ring(pcnet32_dev);
release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
- pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
+ pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
lp->init_block, lp->init_dma_addr);
free_netdev(pcnet32_dev);
pcnet32_dev = next_dev;
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 6eb2d31d1e3..d55932acd88 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -53,7 +53,8 @@ config SMSC_PHY
config BROADCOM_PHY
tristate "Drivers for Broadcom PHYs"
---help---
- Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
+ Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481
+ and BCM5482 PHYs.
config ICPLUS_PHY
tristate "Drivers for ICPlus PHYs"
@@ -83,4 +84,10 @@ config MDIO_BITBANG
If in doubt, say N.
+config MDIO_OF_GPIO
+ tristate "Support for GPIO lib-based bitbanged MDIO buses"
+ depends on MDIO_BITBANG && OF_GPIO
+ ---help---
+ Supports GPIO lib-based MDIO busses.
+
endif # PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 5997d6ef702..eee329fa6f5 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
+obj-$(CONFIG_MDIO_OF_GPIO) += mdio-ofgpio.o
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 60c5cfe9691..4b4dc98ad16 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -24,6 +24,12 @@
#define MII_BCM54XX_ESR 0x11 /* BCM54xx extended status register */
#define MII_BCM54XX_ESR_IS 0x1000 /* Interrupt status */
+#define MII_BCM54XX_EXP_DATA 0x15 /* Expansion register data */
+#define MII_BCM54XX_EXP_SEL 0x17 /* Expansion register select */
+#define MII_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */
+#define MII_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */
+
+#define MII_BCM54XX_AUX_CTL 0x18 /* Auxiliary control register */
#define MII_BCM54XX_ISR 0x1a /* BCM54xx interrupt status register */
#define MII_BCM54XX_IMR 0x1b /* BCM54xx interrupt mask register */
#define MII_BCM54XX_INT_CRCERR 0x0001 /* CRC error */
@@ -42,10 +48,120 @@
#define MII_BCM54XX_INT_MDIX 0x2000 /* MDIX status change */
#define MII_BCM54XX_INT_PSERR 0x4000 /* Pair swap error */
+#define MII_BCM54XX_SHD 0x1c /* 0x1c shadow registers */
+#define MII_BCM54XX_SHD_WRITE 0x8000
+#define MII_BCM54XX_SHD_VAL(x) ((x & 0x1f) << 10)
+#define MII_BCM54XX_SHD_DATA(x) ((x & 0x3ff) << 0)
+
+/*
+ * Broadcom LED source encodings. These are used in BCM5461, BCM5481,
+ * BCM5482, and possibly some others.
+ */
+#define BCM_LED_SRC_LINKSPD1 0x0
+#define BCM_LED_SRC_LINKSPD2 0x1
+#define BCM_LED_SRC_XMITLED 0x2
+#define BCM_LED_SRC_ACTIVITYLED 0x3
+#define BCM_LED_SRC_FDXLED 0x4
+#define BCM_LED_SRC_SLAVE 0x5
+#define BCM_LED_SRC_INTR 0x6
+#define BCM_LED_SRC_QUALITY 0x7
+#define BCM_LED_SRC_RCVLED 0x8
+#define BCM_LED_SRC_MULTICOLOR1 0xa
+#define BCM_LED_SRC_OPENSHORT 0xb
+#define BCM_LED_SRC_OFF 0xe /* Tied high */
+#define BCM_LED_SRC_ON 0xf /* Tied low */
+
+/*
+ * BCM5482: Shadow registers
+ * Shadow values go into bits [14:10] of register 0x1c to select a shadow
+ * register to access.
+ */
+#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */
+ /* LED3 / ~LINKSPD[2] selector */
+#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4)
+ /* LED1 / ~LINKSPD[1] selector */
+#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
+#define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */
+#define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */
+#define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */
+#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
+#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
+
+/*
+ * BCM5482: Secondary SerDes registers
+ */
+#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */
+#define BCM5482_SSD_1000BX_CTL_PWRDOWN 0x0800 /* Power-down SSD */
+#define BCM5482_SSD_SGMII_SLAVE 0x15 /* SGMII Slave Register */
+#define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
+#define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
+
+/*
+ * Device flags for PHYs that can be configured for different operating
+ * modes.
+ */
+#define PHY_BCM_FLAGS_VALID 0x80000000
+#define PHY_BCM_FLAGS_INTF_XAUI 0x00000020
+#define PHY_BCM_FLAGS_INTF_SGMII 0x00000010
+#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
+#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
+
MODULE_DESCRIPTION("Broadcom PHY driver");
MODULE_AUTHOR("Maciej W. Rozycki");
MODULE_LICENSE("GPL");
+/*
+ * Indirect register access functions for the 1000BASE-T/100BASE-TX/10BASE-T
+ * 0x1c shadow registers.
+ */
+static int bcm54xx_shadow_read(struct phy_device *phydev, u16 shadow)
+{
+ phy_write(phydev, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow));
+ return MII_BCM54XX_SHD_DATA(phy_read(phydev, MII_BCM54XX_SHD));
+}
+
+static int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow, u16 val)
+{
+ return phy_write(phydev, MII_BCM54XX_SHD,
+ MII_BCM54XX_SHD_WRITE |
+ MII_BCM54XX_SHD_VAL(shadow) |
+ MII_BCM54XX_SHD_DATA(val));
+}
+
+/*
+ * Indirect register access functions for the Expansion Registers
+ * and Secondary SerDes registers (when sec_serdes=1).
+ */
+static int bcm54xx_exp_read(struct phy_device *phydev,
+ int sec_serdes, u8 regnum)
+{
+ int val;
+
+ phy_write(phydev, MII_BCM54XX_EXP_SEL,
+ (sec_serdes ? MII_BCM54XX_EXP_SEL_SSD :
+ MII_BCM54XX_EXP_SEL_ER) |
+ regnum);
+ val = phy_read(phydev, MII_BCM54XX_EXP_DATA);
+ phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum);
+
+ return val;
+}
+
+static int bcm54xx_exp_write(struct phy_device *phydev,
+ int sec_serdes, u8 regnum, u16 val)
+{
+ int ret;
+
+ phy_write(phydev, MII_BCM54XX_EXP_SEL,
+ (sec_serdes ? MII_BCM54XX_EXP_SEL_SSD :
+ MII_BCM54XX_EXP_SEL_ER) |
+ regnum);
+ ret = phy_write(phydev, MII_BCM54XX_EXP_DATA, val);
+ phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum);
+
+ return ret;
+}
+
static int bcm54xx_config_init(struct phy_device *phydev)
{
int reg, err;
@@ -70,6 +186,87 @@ static int bcm54xx_config_init(struct phy_device *phydev)
return 0;
}
+static int bcm5482_config_init(struct phy_device *phydev)
+{
+ int err, reg;
+
+ err = bcm54xx_config_init(phydev);
+
+ if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
+ /*
+ * Enable secondary SerDes and its use as an LED source
+ */
+ reg = bcm54xx_shadow_read(phydev, BCM5482_SHD_SSD);
+ bcm54xx_shadow_write(phydev, BCM5482_SHD_SSD,
+ reg |
+ BCM5482_SHD_SSD_LEDM |
+ BCM5482_SHD_SSD_EN);
+
+ /*
+ * Enable SGMII slave mode and auto-detection
+ */
+ reg = bcm54xx_exp_read(phydev, 1, BCM5482_SSD_SGMII_SLAVE);
+ bcm54xx_exp_write(phydev, 1, BCM5482_SSD_SGMII_SLAVE,
+ reg |
+ BCM5482_SSD_SGMII_SLAVE_EN |
+ BCM5482_SSD_SGMII_SLAVE_AD);
+
+ /*
+ * Disable secondary SerDes powerdown
+ */
+ reg = bcm54xx_exp_read(phydev, 1, BCM5482_SSD_1000BX_CTL);
+ bcm54xx_exp_write(phydev, 1, BCM5482_SSD_1000BX_CTL,
+ reg & ~BCM5482_SSD_1000BX_CTL_PWRDOWN);
+
+ /*
+ * Select 1000BASE-X register set (primary SerDes)
+ */
+ reg = bcm54xx_shadow_read(phydev, BCM5482_SHD_MODE);
+ bcm54xx_shadow_write(phydev, BCM5482_SHD_MODE,
+ reg | BCM5482_SHD_MODE_1000BX);
+
+ /*
+ * LED1=ACTIVITYLED, LED3=LINKSPD[2]
+ * (Use LED1 as secondary SerDes ACTIVITY LED)
+ */
+ bcm54xx_shadow_write(phydev, BCM5482_SHD_LEDS1,
+ BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) |
+ BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD2));
+
+ /*
+ * Auto-negotiation doesn't seem to work quite right
+ * in this mode, so we disable it and force it to the
+ * right speed/duplex setting. Only 'link status'
+ * is important.
+ */
+ phydev->autoneg = AUTONEG_DISABLE;
+ phydev->speed = SPEED_1000;
+ phydev->duplex = DUPLEX_FULL;
+ }
+
+ return err;
+}
+
+static int bcm5482_read_status(struct phy_device *phydev)
+{
+ int err;
+
+ err = genphy_read_status(phydev);
+
+ if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
+ /*
+ * Only link status matters for 1000Base-X mode, so force
+ * 1000 Mbit/s full-duplex status
+ */
+ if (phydev->link) {
+ phydev->speed = SPEED_1000;
+ phydev->duplex = DUPLEX_FULL;
+ }
+ }
+
+ return err;
+}
+
static int bcm54xx_ack_interrupt(struct phy_device *phydev)
{
int reg;
@@ -210,9 +407,9 @@ static struct phy_driver bcm5482_driver = {
.name = "Broadcom BCM5482",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
- .config_init = bcm54xx_config_init,
+ .config_init = bcm5482_config_init,
.config_aneg = genphy_config_aneg,
- .read_status = genphy_read_status,
+ .read_status = bcm5482_read_status,
.ack_interrupt = bcm54xx_ack_interrupt,
.config_intr = bcm54xx_config_intr,
.driver = { .owner = THIS_MODULE },
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 2747b1f89ff..c01b78013dd 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -177,6 +177,7 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
return bus;
}
+EXPORT_SYMBOL(alloc_mdio_bitbang);
void free_mdio_bitbang(struct mii_bus *bus)
{
@@ -185,5 +186,6 @@ void free_mdio_bitbang(struct mii_bus *bus)
module_put(ctrl->ops->owner);
kfree(bus);
}
+EXPORT_SYMBOL(free_mdio_bitbang);
MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/mdio-ofgpio.c b/drivers/net/phy/mdio-ofgpio.c
new file mode 100644
index 00000000000..7edfc0c3483
--- /dev/null
+++ b/drivers/net/phy/mdio-ofgpio.c
@@ -0,0 +1,205 @@
+/*
+ * OpenFirmware GPIO based MDIO bitbang driver.
+ *
+ * Copyright (c) 2008 CSE Semaphore Belgium.
+ * by Laurent Pinchart <laurentp@cse-semaphore.com>
+ *
+ * Based on earlier work by
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ * by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+
+struct mdio_gpio_info {
+ struct mdiobb_ctrl ctrl;
+ int mdc, mdio;
+};
+
+static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
+{
+ struct mdio_gpio_info *bitbang =
+ container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+ if (dir)
+ gpio_direction_output(bitbang->mdio, 1);
+ else
+ gpio_direction_input(bitbang->mdio);
+}
+
+static int mdio_read(struct mdiobb_ctrl *ctrl)
+{
+ struct mdio_gpio_info *bitbang =
+ container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+ return gpio_get_value(bitbang->mdio);
+}
+
+static void mdio(struct mdiobb_ctrl *ctrl, int what)
+{
+ struct mdio_gpio_info *bitbang =
+ container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+ gpio_set_value(bitbang->mdio, what);
+}
+
+static void mdc(struct mdiobb_ctrl *ctrl, int what)
+{
+ struct mdio_gpio_info *bitbang =
+ container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+ gpio_set_value(bitbang->mdc, what);
+}
+
+static struct mdiobb_ops mdio_gpio_ops = {
+ .owner = THIS_MODULE,
+ .set_mdc = mdc,
+ .set_mdio_dir = mdio_dir,
+ .set_mdio_data = mdio,
+ .get_mdio_data = mdio_read,
+};
+
+static int __devinit mdio_ofgpio_bitbang_init(struct mii_bus *bus,
+ struct device_node *np)
+{
+ struct mdio_gpio_info *bitbang = bus->priv;
+
+ bitbang->mdc = of_get_gpio(np, 0);
+ bitbang->mdio = of_get_gpio(np, 1);
+
+ if (bitbang->mdc < 0 || bitbang->mdio < 0)
+ return -ENODEV;
+
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%x", bitbang->mdc);
+ return 0;
+}
+
+static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
+{
+ const u32 *data;
+ int len, id, irq;
+
+ data = of_get_property(np, "reg", &len);
+ if (!data || len != 4)
+ return;
+
+ id = *data;
+ bus->phy_mask &= ~(1 << id);
+
+ irq = of_irq_to_resource(np, 0, NULL);
+ if (irq != NO_IRQ)
+ bus->irq[id] = irq;
+}
+
+static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = NULL;
+ struct mii_bus *new_bus;
+ struct mdio_gpio_info *bitbang;
+ int ret = -ENOMEM;
+ int i;
+
+ bitbang = kzalloc(sizeof(struct mdio_gpio_info), GFP_KERNEL);
+ if (!bitbang)
+ goto out;
+
+ bitbang->ctrl.ops = &mdio_gpio_ops;
+
+ new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+ if (!new_bus)
+ goto out_free_priv;
+
+ new_bus->name = "GPIO Bitbanged MII",
+
+ ret = mdio_ofgpio_bitbang_init(new_bus, ofdev->node);
+ if (ret)
+ goto out_free_bus;
+
+ new_bus->phy_mask = ~0;
+ new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!new_bus->irq)
+ goto out_free_bus;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ new_bus->irq[i] = -1;
+
+ while ((np = of_get_next_child(ofdev->node, np)))
+ if (!strcmp(np->type, "ethernet-phy"))
+ add_phy(new_bus, np);
+
+ new_bus->dev = &ofdev->dev;
+ dev_set_drvdata(&ofdev->dev, new_bus);
+
+ ret = mdiobus_register(new_bus);
+ if (ret)
+ goto out_free_irqs;
+
+ return 0;
+
+out_free_irqs:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(new_bus->irq);
+out_free_bus:
+ kfree(new_bus);
+out_free_priv:
+ free_mdio_bitbang(new_bus);
+out:
+ return ret;
+}
+
+static int mdio_ofgpio_remove(struct of_device *ofdev)
+{
+ struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+ struct mdio_gpio_info *bitbang = bus->priv;
+
+ mdiobus_unregister(bus);
+ free_mdio_bitbang(bus);
+ dev_set_drvdata(&ofdev->dev, NULL);
+ kfree(bus->irq);
+ kfree(bitbang);
+ kfree(bus);
+
+ return 0;
+}
+
+static struct of_device_id mdio_ofgpio_match[] = {
+ {
+ .compatible = "virtual,mdio-gpio",
+ },
+ {},
+};
+
+static struct of_platform_driver mdio_ofgpio_driver = {
+ .name = "mdio-gpio",
+ .match_table = mdio_ofgpio_match,
+ .probe = mdio_ofgpio_probe,
+ .remove = mdio_ofgpio_remove,
+};
+
+static int mdio_ofgpio_init(void)
+{
+ return of_register_platform_driver(&mdio_ofgpio_driver);
+}
+
+static void mdio_ofgpio_exit(void)
+{
+ of_unregister_platform_driver(&mdio_ofgpio_driver);
+}
+
+module_init(mdio_ofgpio_init);
+module_exit(mdio_ofgpio_exit);
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index f1a52def124..451bdb57d6f 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -378,7 +378,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
}
-static struct tty_ldisc ppp_ldisc = {
+static struct tty_ldisc_ops ppp_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "ppp",
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 83625fdff3d..6b1d7a8edf1 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -363,7 +363,7 @@ static int ppp_open(struct inode *inode, struct file *file)
return 0;
}
-static int ppp_release(struct inode *inode, struct file *file)
+static int ppp_release(struct inode *unused, struct file *file)
{
struct ppp_file *pf = file->private_data;
struct ppp *ppp;
@@ -547,8 +547,7 @@ static int get_filter(void __user *arg, struct sock_filter **p)
}
#endif /* CONFIG_PPP_FILTER */
-static int ppp_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct ppp_file *pf = file->private_data;
struct ppp *ppp;
@@ -576,24 +575,29 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
* this fd and reopening /dev/ppp.
*/
err = -EINVAL;
+ lock_kernel();
if (pf->kind == INTERFACE) {
ppp = PF_TO_PPP(pf);
if (file == ppp->owner)
ppp_shutdown_interface(ppp);
}
if (atomic_read(&file->f_count) <= 2) {
- ppp_release(inode, file);
+ ppp_release(NULL, file);
err = 0;
} else
printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n",
atomic_read(&file->f_count));
+ unlock_kernel();
return err;
}
if (pf->kind == CHANNEL) {
- struct channel *pch = PF_TO_CHANNEL(pf);
+ struct channel *pch;
struct ppp_channel *chan;
+ lock_kernel();
+ pch = PF_TO_CHANNEL(pf);
+
switch (cmd) {
case PPPIOCCONNECT:
if (get_user(unit, p))
@@ -613,6 +617,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
err = chan->ops->ioctl(chan, cmd, arg);
up_read(&pch->chan_sem);
}
+ unlock_kernel();
return err;
}
@@ -622,6 +627,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
+ lock_kernel();
ppp = PF_TO_PPP(pf);
switch (cmd) {
case PPPIOCSMRU:
@@ -769,7 +775,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
default:
err = -ENOTTY;
}
-
+ unlock_kernel();
return err;
}
@@ -781,6 +787,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
struct channel *chan;
int __user *p = (int __user *)arg;
+ lock_kernel();
switch (cmd) {
case PPPIOCNEWUNIT:
/* Create a new ppp unit */
@@ -829,6 +836,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
default:
err = -ENOTTY;
}
+ unlock_kernel();
return err;
}
@@ -837,7 +845,7 @@ static const struct file_operations ppp_device_fops = {
.read = ppp_read,
.write = ppp_write,
.poll = ppp_poll,
- .ioctl = ppp_ioctl,
+ .unlocked_ioctl = ppp_ioctl,
.open = ppp_open,
.release = ppp_release
};
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index b8f0369a71e..801d8f99d47 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -418,7 +418,7 @@ ppp_sync_wakeup(struct tty_struct *tty)
}
-static struct tty_ldisc ppp_sync_ldisc = {
+static struct tty_ldisc_ops ppp_sync_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "pppsync",
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index e365efb3c62..2eb54fd7bed 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -110,7 +110,7 @@ static void gelic_card_get_ether_port_status(struct gelic_card *card,
void gelic_card_up(struct gelic_card *card)
{
pr_debug("%s: called\n", __func__);
- down(&card->updown_lock);
+ mutex_lock(&card->updown_lock);
if (atomic_inc_return(&card->users) == 1) {
pr_debug("%s: real do\n", __func__);
/* enable irq */
@@ -120,7 +120,7 @@ void gelic_card_up(struct gelic_card *card)
napi_enable(&card->napi);
}
- up(&card->updown_lock);
+ mutex_unlock(&card->updown_lock);
pr_debug("%s: done\n", __func__);
}
@@ -128,7 +128,7 @@ void gelic_card_down(struct gelic_card *card)
{
u64 mask;
pr_debug("%s: called\n", __func__);
- down(&card->updown_lock);
+ mutex_lock(&card->updown_lock);
if (atomic_dec_if_positive(&card->users) == 0) {
pr_debug("%s: real do\n", __func__);
napi_disable(&card->napi);
@@ -146,7 +146,7 @@ void gelic_card_down(struct gelic_card *card)
/* stop tx */
gelic_card_disable_txdmac(card);
}
- up(&card->updown_lock);
+ mutex_unlock(&card->updown_lock);
pr_debug("%s: done\n", __func__);
}
@@ -1534,7 +1534,7 @@ static struct gelic_card *gelic_alloc_card_net(struct net_device **netdev)
INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
init_waitqueue_head(&card->waitq);
atomic_set(&card->tx_timeout_task_counter, 0);
- init_MUTEX(&card->updown_lock);
+ mutex_init(&card->updown_lock);
atomic_set(&card->users, 0);
return card;
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index 520f143c2c0..8b413868bbe 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -298,7 +298,7 @@ struct gelic_card {
wait_queue_head_t waitq;
/* only first user should up the card */
- struct semaphore updown_lock;
+ struct mutex updown_lock;
atomic_t users;
u64 ether_port_status;
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 1dae1f2ed81..6b2dee0cf3a 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -45,7 +45,8 @@
#include "ps3_gelic_wireless.h"
-static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan);
+static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan,
+ u8 *essid, size_t essid_len);
static int gelic_wl_try_associate(struct net_device *netdev);
/*
@@ -105,6 +106,7 @@ static const struct eurus_cmd_arg_info cmd_info[GELIC_EURUS_CMD_MAX_INDEX] = {
[GELIC_EURUS_CMD_GET_WEP_CFG] = { .post_arg = 1},
[GELIC_EURUS_CMD_GET_WPA_CFG] = { .post_arg = 1},
[GELIC_EURUS_CMD_GET_RSSI_CFG] = { .post_arg = 1},
+ [GELIC_EURUS_CMD_START_SCAN] = { .pre_arg = 1},
[GELIC_EURUS_CMD_GET_SCAN] = { .post_arg = 1},
};
@@ -163,7 +165,9 @@ static void gelic_eurus_sync_cmd_worker(struct work_struct *work)
card = port_to_card(wl_port(wl));
if (cmd_info[cmd->cmd].pre_arg) {
- arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer));
+ arg1 = (cmd->buffer) ?
+ ps3_mm_phys_to_lpar(__pa(cmd->buffer)) :
+ 0;
arg2 = cmd->buf_size;
} else {
arg1 = 0;
@@ -240,12 +244,12 @@ static u32 gelic_wl_get_link(struct net_device *netdev)
u32 ret;
pr_debug("%s: <-\n", __func__);
- down(&wl->assoc_stat_lock);
+ mutex_lock(&wl->assoc_stat_lock);
if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
ret = 1;
else
ret = 0;
- up(&wl->assoc_stat_lock);
+ mutex_unlock(&wl->assoc_stat_lock);
pr_debug("%s: ->\n", __func__);
return ret;
}
@@ -350,7 +354,8 @@ static int gelic_wl_get_range(struct net_device *netdev,
/* encryption capability */
range->enc_capa = IW_ENC_CAPA_WPA |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP |
+ IW_ENC_CAPA_4WAY_HANDSHAKE;
if (wpa2_capable())
range->enc_capa |= IW_ENC_CAPA_WPA2;
range->encoding_size[0] = 5; /* 40bit WEP */
@@ -359,6 +364,9 @@ static int gelic_wl_get_range(struct net_device *netdev,
range->num_encoding_sizes = 3;
range->max_encoding_tokens = GELIC_WEP_KEYS;
+ /* scan capability */
+ range->scan_capa = IW_SCAN_CAPA_ESSID;
+
pr_debug("%s: ->\n", __func__);
return 0;
@@ -370,8 +378,18 @@ static int gelic_wl_set_scan(struct net_device *netdev,
union iwreq_data *wrqu, char *extra)
{
struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
-
- return gelic_wl_start_scan(wl, 1);
+ struct iw_scan_req *req;
+ u8 *essid = NULL;
+ size_t essid_len = 0;
+
+ if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+ wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+ req = (struct iw_scan_req*)extra;
+ essid = req->essid;
+ essid_len = req->essid_len;
+ pr_debug("%s: ESSID scan =%s\n", __func__, essid);
+ }
+ return gelic_wl_start_scan(wl, 1, essid, essid_len);
}
#define OUI_LEN 3
@@ -553,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
* independent format
*/
static char *gelic_wl_translate_scan(struct net_device *netdev,
+ struct iw_request_info *info,
char *ev,
char *stop,
struct gelic_wl_scan_info *network)
@@ -570,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
- ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN);
+ ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_ADDR_LEN);
/* ESSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = strnlen(scan->essid, 32);
- ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
+ ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
/* FREQUENCY */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = be16_to_cpu(scan->channel);
iwe.u.freq.e = 0; /* table value in MHz */
iwe.u.freq.i = 0;
- ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN);
+ ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_FREQ_LEN);
/* RATES */
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
/* to stuff multiple values in one event */
- tmp = ev + IW_EV_LCP_LEN;
+ tmp = ev + iwe_stream_lcp_len(info);
/* put them in ascendant order (older is first) */
i = 0;
j = 0;
@@ -602,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
else
rate = scan->rate[i++] & 0x7f;
iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
- tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
+ tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
IW_EV_PARAM_LEN);
}
while (j < network->rate_ext_len) {
iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
- tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
+ tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
IW_EV_PARAM_LEN);
}
/* Check if we added any rate */
- if (IW_EV_LCP_LEN < (tmp - ev))
+ if (iwe_stream_lcp_len(info) < (tmp - ev))
ev = tmp;
/* ENCODE */
@@ -621,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
+ ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
/* MODE */
iwe.cmd = SIOCGIWMODE;
@@ -631,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN);
+ ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_UINT_LEN);
}
/* QUAL */
@@ -641,7 +660,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
iwe.u.qual.level = be16_to_cpu(scan->rssi);
iwe.u.qual.qual = be16_to_cpu(scan->rssi);
iwe.u.qual.noise = 0;
- ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN);
+ ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_QUAL_LEN);
/* RSN */
memset(&iwe, 0, sizeof(iwe));
@@ -651,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
if (len) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = len;
- ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+ ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
}
} else {
/* this scan info has IE data */
@@ -666,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = ie_info.wpa.len;
- ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+ ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
}
if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
@@ -674,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = ie_info.rsn.len;
- ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+ ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
}
}
@@ -695,7 +714,7 @@ static int gelic_wl_get_scan(struct net_device *netdev,
unsigned long this_time = jiffies;
pr_debug("%s: <-\n", __func__);
- if (down_interruptible(&wl->scan_lock))
+ if (mutex_lock_interruptible(&wl->scan_lock))
return -EAGAIN;
switch (wl->scan_stat) {
@@ -719,7 +738,8 @@ static int gelic_wl_get_scan(struct net_device *netdev,
if (wl->scan_age == 0 ||
time_after(scan_info->last_scanned + wl->scan_age,
this_time))
- ev = gelic_wl_translate_scan(netdev, ev, stop,
+ ev = gelic_wl_translate_scan(netdev, info,
+ ev, stop,
scan_info);
else
pr_debug("%s:entry too old\n", __func__);
@@ -733,7 +753,7 @@ static int gelic_wl_get_scan(struct net_device *netdev,
wrqu->data.length = ev - extra;
wrqu->data.flags = 0;
out:
- up(&wl->scan_lock);
+ mutex_unlock(&wl->scan_lock);
pr_debug("%s: -> %d %d\n", __func__, ret, wrqu->data.length);
return ret;
}
@@ -979,7 +999,7 @@ static int gelic_wl_get_essid(struct net_device *netdev,
unsigned long irqflag;
pr_debug("%s: <- \n", __func__);
- down(&wl->assoc_stat_lock);
+ mutex_lock(&wl->assoc_stat_lock);
spin_lock_irqsave(&wl->lock, irqflag);
if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat) ||
wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) {
@@ -989,7 +1009,7 @@ static int gelic_wl_get_essid(struct net_device *netdev,
} else
data->essid.flags = 0;
- up(&wl->assoc_stat_lock);
+ mutex_unlock(&wl->assoc_stat_lock);
spin_unlock_irqrestore(&wl->lock, irqflag);
pr_debug("%s: -> len=%d \n", __func__, data->essid.length);
@@ -1170,7 +1190,7 @@ static int gelic_wl_get_ap(struct net_device *netdev,
unsigned long irqflag;
pr_debug("%s: <-\n", __func__);
- down(&wl->assoc_stat_lock);
+ mutex_lock(&wl->assoc_stat_lock);
spin_lock_irqsave(&wl->lock, irqflag);
if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) {
data->ap_addr.sa_family = ARPHRD_ETHER;
@@ -1180,7 +1200,7 @@ static int gelic_wl_get_ap(struct net_device *netdev,
memset(data->ap_addr.sa_data, 0, ETH_ALEN);
spin_unlock_irqrestore(&wl->lock, irqflag);
- up(&wl->assoc_stat_lock);
+ mutex_unlock(&wl->assoc_stat_lock);
pr_debug("%s: ->\n", __func__);
return 0;
}
@@ -1256,42 +1276,19 @@ static int gelic_wl_set_encodeext(struct net_device *netdev,
set_bit(key_index, &wl->key_enabled);
/* remember wep info changed */
set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
- } else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
- pr_debug("%s: TKIP/CCMP requested alg=%d\n", __func__, alg);
- /* check key length */
- if (IW_ENCODING_TOKEN_MAX < ext->key_len) {
- pr_info("%s: key is too long %d\n", __func__,
- ext->key_len);
+ } else if (alg == IW_ENCODE_ALG_PMK) {
+ if (ext->key_len != WPA_PSK_LEN) {
+ pr_err("%s: PSK length wrong %d\n", __func__,
+ ext->key_len);
ret = -EINVAL;
goto done;
}
- if (alg == IW_ENCODE_ALG_CCMP) {
- pr_debug("%s: AES selected\n", __func__);
- wl->group_cipher_method = GELIC_WL_CIPHER_AES;
- wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES;
- wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2;
- } else {
- pr_debug("%s: TKIP selected, WPA forced\n", __func__);
- wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
- wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
- /* FIXME: how do we do if WPA2 + TKIP? */
- wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
- }
- if (flags & IW_ENCODE_RESTRICTED)
- BUG();
- wl->auth_method = GELIC_EURUS_AUTH_OPEN;
- /* We should use same key for both and unicast */
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
- pr_debug("%s: group key \n", __func__);
- else
- pr_debug("%s: unicast key \n", __func__);
- /* OK, update the key */
- wl->key_len[key_index] = ext->key_len;
- memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX);
- memcpy(wl->key[key_index], ext->key, ext->key_len);
- set_bit(key_index, &wl->key_enabled);
- /* remember info changed */
- set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+ memset(wl->psk, 0, sizeof(wl->psk));
+ memcpy(wl->psk, ext->key, ext->key_len);
+ wl->psk_len = ext->key_len;
+ wl->psk_type = GELIC_EURUS_WPA_PSK_BIN;
+ /* remember PSK configured */
+ set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat);
}
done:
spin_unlock_irqrestore(&wl->lock, irqflag);
@@ -1397,6 +1394,7 @@ static int gelic_wl_get_mode(struct net_device *netdev,
return 0;
}
+#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
/* SIOCIWFIRSTPRIV */
static int hex2bin(u8 *str, u8 *bin, unsigned int len)
{
@@ -1501,6 +1499,7 @@ static int gelic_wl_priv_get_psk(struct net_device *net_dev,
pr_debug("%s:-> %d\n", __func__, data->data.length);
return 0;
}
+#endif
/* SIOCGIWNICKN */
static int gelic_wl_get_nick(struct net_device *net_dev,
@@ -1524,15 +1523,20 @@ static struct iw_statistics *gelic_wl_get_wireless_stats(
struct gelic_eurus_cmd *cmd;
struct iw_statistics *is;
struct gelic_eurus_rssi_info *rssi;
+ void *buf;
pr_debug("%s: <-\n", __func__);
+ buf = (void *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return NULL;
+
is = &wl->iwstat;
memset(is, 0, sizeof(*is));
cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_RSSI_CFG,
- wl->buf, sizeof(*rssi));
+ buf, sizeof(*rssi));
if (cmd && !cmd->status && !cmd->cmd_status) {
- rssi = wl->buf;
+ rssi = buf;
is->qual.level = be16_to_cpu(rssi->rssi);
is->qual.updated = IW_QUAL_LEVEL_UPDATED |
IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
@@ -1541,6 +1545,7 @@ static struct iw_statistics *gelic_wl_get_wireless_stats(
is->qual.updated = IW_QUAL_ALL_INVALID;
kfree(cmd);
+ free_page((unsigned long)buf);
pr_debug("%s: ->\n", __func__);
return is;
}
@@ -1548,13 +1553,16 @@ static struct iw_statistics *gelic_wl_get_wireless_stats(
/*
* scanning helpers
*/
-static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
+static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan,
+ u8 *essid, size_t essid_len)
{
struct gelic_eurus_cmd *cmd;
int ret = 0;
+ void *buf = NULL;
+ size_t len;
pr_debug("%s: <- always=%d\n", __func__, always_scan);
- if (down_interruptible(&wl->scan_lock))
+ if (mutex_lock_interruptible(&wl->scan_lock))
return -ERESTARTSYS;
/*
@@ -1574,12 +1582,27 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
complete(&wl->scan_done);
goto out;
}
+
+ /* ESSID scan ? */
+ if (essid_len && essid) {
+ buf = (void *)__get_free_page(GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ len = IW_ESSID_MAX_SIZE; /* hypervisor always requires 32 */
+ memset(buf, 0, len);
+ memcpy(buf, essid, essid_len);
+ pr_debug("%s: essid scan='%s'\n", __func__, (char *)buf);
+ } else
+ len = 0;
+
/*
* issue start scan request
*/
wl->scan_stat = GELIC_WL_SCAN_STAT_SCANNING;
cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_START_SCAN,
- NULL, 0);
+ buf, len);
if (!cmd || cmd->status || cmd->cmd_status) {
wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
complete(&wl->scan_done);
@@ -1588,7 +1611,8 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
}
kfree(cmd);
out:
- up(&wl->scan_lock);
+ free_page((unsigned long)buf);
+ mutex_unlock(&wl->scan_lock);
pr_debug("%s: ->\n", __func__);
return ret;
}
@@ -1607,10 +1631,17 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
union iwreq_data data;
unsigned long this_time = jiffies;
unsigned int data_len, i, found, r;
+ void *buf;
DECLARE_MAC_BUF(mac);
pr_debug("%s:start\n", __func__);
- down(&wl->scan_lock);
+ mutex_lock(&wl->scan_lock);
+
+ buf = (void *)__get_free_page(GFP_KERNEL);
+ if (!buf) {
+ pr_info("%s: scan buffer alloc failed\n", __func__);
+ goto out;
+ }
if (wl->scan_stat != GELIC_WL_SCAN_STAT_SCANNING) {
/*
@@ -1622,7 +1653,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
}
cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_SCAN,
- wl->buf, PAGE_SIZE);
+ buf, PAGE_SIZE);
if (!cmd || cmd->status || cmd->cmd_status) {
wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
pr_info("%s:cmd failed\n", __func__);
@@ -1649,7 +1680,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
}
/* put them in the newtork_list */
- for (i = 0, scan_info_size = 0, scan_info = wl->buf;
+ for (i = 0, scan_info_size = 0, scan_info = buf;
scan_info_size < data_len;
i++, scan_info_size += be16_to_cpu(scan_info->size),
scan_info = (void *)scan_info + be16_to_cpu(scan_info->size)) {
@@ -1726,8 +1757,9 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data,
NULL);
out:
+ free_page((unsigned long)buf);
complete(&wl->scan_done);
- up(&wl->scan_lock);
+ mutex_unlock(&wl->scan_lock);
pr_debug("%s:end\n", __func__);
}
@@ -1848,7 +1880,10 @@ static int gelic_wl_do_wep_setup(struct gelic_wl_info *wl)
pr_debug("%s: <-\n", __func__);
/* we can assume no one should uses the buffer */
- wep = wl->buf;
+ wep = (struct gelic_eurus_wep_cfg *)__get_free_page(GFP_KERNEL);
+ if (!wep)
+ return -ENOMEM;
+
memset(wep, 0, sizeof(*wep));
if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
@@ -1898,6 +1933,7 @@ static int gelic_wl_do_wep_setup(struct gelic_wl_info *wl)
kfree(cmd);
out:
+ free_page((unsigned long)wep);
pr_debug("%s: ->\n", __func__);
return ret;
}
@@ -1941,7 +1977,10 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
pr_debug("%s: <-\n", __func__);
/* we can assume no one should uses the buffer */
- wpa = wl->buf;
+ wpa = (struct gelic_eurus_wpa_cfg *)__get_free_page(GFP_KERNEL);
+ if (!wpa)
+ return -ENOMEM;
+
memset(wpa, 0, sizeof(*wpa));
if (!test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat))
@@ -2000,6 +2039,7 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
else if (cmd->status || cmd->cmd_status)
ret = -ENXIO;
kfree(cmd);
+ free_page((unsigned long)wpa);
pr_debug("%s: --> %d\n", __func__, ret);
return ret;
}
@@ -2018,7 +2058,10 @@ static int gelic_wl_associate_bss(struct gelic_wl_info *wl,
pr_debug("%s: <-\n", __func__);
/* do common config */
- common = wl->buf;
+ common = (struct gelic_eurus_common_cfg *)__get_free_page(GFP_KERNEL);
+ if (!common)
+ return -ENOMEM;
+
memset(common, 0, sizeof(*common));
common->bss_type = cpu_to_be16(GELIC_EURUS_BSS_INFRA);
common->op_mode = cpu_to_be16(GELIC_EURUS_OPMODE_11BG);
@@ -2104,6 +2147,7 @@ static int gelic_wl_associate_bss(struct gelic_wl_info *wl,
pr_info("%s: connected\n", __func__);
}
out:
+ free_page((unsigned long)common);
pr_debug("%s: ->\n", __func__);
return ret;
}
@@ -2151,7 +2195,7 @@ static void gelic_wl_disconnect_event(struct gelic_wl_info *wl,
* As it waits with timeout, just leave assoc_done
* uncompleted, then it terminates with timeout
*/
- if (down_trylock(&wl->assoc_stat_lock)) {
+ if (!mutex_trylock(&wl->assoc_stat_lock)) {
pr_debug("%s: already locked\n", __func__);
lock = 0;
} else {
@@ -2170,7 +2214,7 @@ static void gelic_wl_disconnect_event(struct gelic_wl_info *wl,
netif_carrier_off(port_to_netdev(wl_port(wl)));
if (lock)
- up(&wl->assoc_stat_lock);
+ mutex_unlock(&wl->assoc_stat_lock);
}
/*
* event worker
@@ -2255,15 +2299,30 @@ static void gelic_wl_assoc_worker(struct work_struct *work)
struct gelic_wl_scan_info *best_bss;
int ret;
+ unsigned long irqflag;
+ u8 *essid;
+ size_t essid_len;
wl = container_of(work, struct gelic_wl_info, assoc_work.work);
- down(&wl->assoc_stat_lock);
+ mutex_lock(&wl->assoc_stat_lock);
if (wl->assoc_stat != GELIC_WL_ASSOC_STAT_DISCONN)
goto out;
- ret = gelic_wl_start_scan(wl, 0);
+ spin_lock_irqsave(&wl->lock, irqflag);
+ if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat)) {
+ pr_debug("%s: assoc ESSID configured %s\n", __func__,
+ wl->essid);
+ essid = wl->essid;
+ essid_len = wl->essid_len;
+ } else {
+ essid = NULL;
+ essid_len = 0;
+ }
+ spin_unlock_irqrestore(&wl->lock, irqflag);
+
+ ret = gelic_wl_start_scan(wl, 0, essid, essid_len);
if (ret == -ERESTARTSYS) {
pr_debug("%s: scan start failed association\n", __func__);
schedule_delayed_work(&wl->assoc_work, HZ/10); /*FIXME*/
@@ -2282,7 +2341,7 @@ static void gelic_wl_assoc_worker(struct work_struct *work)
wait_for_completion(&wl->scan_done);
pr_debug("%s: scan done\n", __func__);
- down(&wl->scan_lock);
+ mutex_lock(&wl->scan_lock);
if (wl->scan_stat != GELIC_WL_SCAN_STAT_GOT_LIST) {
gelic_wl_send_iwap_event(wl, NULL);
pr_info("%s: no scan list. association failed\n", __func__);
@@ -2302,9 +2361,9 @@ static void gelic_wl_assoc_worker(struct work_struct *work)
if (ret)
pr_info("%s: association failed %d\n", __func__, ret);
scan_lock_out:
- up(&wl->scan_lock);
+ mutex_unlock(&wl->scan_lock);
out:
- up(&wl->assoc_stat_lock);
+ mutex_unlock(&wl->assoc_stat_lock);
}
/*
* Interrupt handler
@@ -2351,6 +2410,7 @@ static const iw_handler gelic_wl_wext_handler[] =
IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick,
};
+#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
static struct iw_priv_args gelic_wl_private_args[] =
{
{
@@ -2372,15 +2432,18 @@ static const iw_handler gelic_wl_private_handler[] =
gelic_wl_priv_set_psk,
gelic_wl_priv_get_psk,
};
+#endif
static const struct iw_handler_def gelic_wl_wext_handler_def = {
.num_standard = ARRAY_SIZE(gelic_wl_wext_handler),
.standard = gelic_wl_wext_handler,
.get_wireless_stats = gelic_wl_get_wireless_stats,
+#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE
.num_private = ARRAY_SIZE(gelic_wl_private_handler),
.num_private_args = ARRAY_SIZE(gelic_wl_private_args),
.private = gelic_wl_private_handler,
.private_args = gelic_wl_private_args,
+#endif
};
static struct net_device *gelic_wl_alloc(struct gelic_card *card)
@@ -2431,8 +2494,8 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card)
INIT_DELAYED_WORK(&wl->event_work, gelic_wl_event_worker);
INIT_DELAYED_WORK(&wl->assoc_work, gelic_wl_assoc_worker);
- init_MUTEX(&wl->scan_lock);
- init_MUTEX(&wl->assoc_stat_lock);
+ mutex_init(&wl->scan_lock);
+ mutex_init(&wl->assoc_stat_lock);
init_completion(&wl->scan_done);
/* for the case that no scan request is issued and stop() is called */
@@ -2446,16 +2509,9 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card)
BUILD_BUG_ON(PAGE_SIZE <
sizeof(struct gelic_eurus_scan_info) *
GELIC_EURUS_MAX_SCAN);
- wl->buf = (void *)get_zeroed_page(GFP_KERNEL);
- if (!wl->buf) {
- pr_info("%s:buffer allocation failed\n", __func__);
- goto fail_getpage;
- }
pr_debug("%s:end\n", __func__);
return netdev;
-fail_getpage:
- destroy_workqueue(wl->event_queue);
fail_event_workqueue:
destroy_workqueue(wl->eurus_cmd_queue);
fail_cmd_workqueue:
@@ -2474,8 +2530,6 @@ static void gelic_wl_free(struct gelic_wl_info *wl)
pr_debug("%s: <-\n", __func__);
- free_page((unsigned long)wl->buf);
-
pr_debug("%s: destroy queues\n", __func__);
destroy_workqueue(wl->eurus_cmd_queue);
destroy_workqueue(wl->event_queue);
diff --git a/drivers/net/ps3_gelic_wireless.h b/drivers/net/ps3_gelic_wireless.h
index 10369716672..5339e0078d1 100644
--- a/drivers/net/ps3_gelic_wireless.h
+++ b/drivers/net/ps3_gelic_wireless.h
@@ -241,7 +241,7 @@ enum gelic_wl_assoc_state {
#define GELIC_WEP_KEYS 4
struct gelic_wl_info {
/* bss list */
- struct semaphore scan_lock;
+ struct mutex scan_lock;
struct list_head network_list;
struct list_head network_free_list;
struct gelic_wl_scan_info *networks;
@@ -266,7 +266,7 @@ struct gelic_wl_info {
enum gelic_wl_wpa_level wpa_level; /* wpa/wpa2 */
/* association handling */
- struct semaphore assoc_stat_lock;
+ struct mutex assoc_stat_lock;
struct delayed_work assoc_work;
enum gelic_wl_assoc_state assoc_stat;
struct completion assoc_done;
@@ -288,9 +288,6 @@ struct gelic_wl_info {
u8 active_bssid[ETH_ALEN]; /* associated bssid */
unsigned int essid_len;
- /* buffer for hypervisor IO */
- void *buf;
-
struct iw_public_data wireless_data;
struct iw_statistics iwstat;
};
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index bccee68bd48..e7d48a352be 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1437,9 +1437,9 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
reg &= ~PHY_GIG_ALL_PARAMS;
if(portConfiguration & PORT_CONFIG_1000MB_SPEED) {
- if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED)
+ if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED)
reg |= PHY_GIG_ADV_1000F;
- else
+ else
reg |= PHY_GIG_ADV_1000H;
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 65724250462..cfe8829ed31 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -28,13 +28,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-#ifdef CONFIG_R8169_NAPI
-#define NAPI_SUFFIX "-NAPI"
-#else
-#define NAPI_SUFFIX ""
-#endif
-
-#define RTL8169_VERSION "2.2LK" NAPI_SUFFIX
+#define RTL8169_VERSION "2.3LK-NAPI"
#define MODULENAME "r8169"
#define PFX MODULENAME ": "
@@ -57,16 +51,6 @@
#define TX_BUFFS_AVAIL(tp) \
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
-#ifdef CONFIG_R8169_NAPI
-#define rtl8169_rx_skb netif_receive_skb
-#define rtl8169_rx_hwaccel_skb vlan_hwaccel_receive_skb
-#define rtl8169_rx_quota(count, quota) min(count, quota)
-#else
-#define rtl8169_rx_skb netif_rx
-#define rtl8169_rx_hwaccel_skb vlan_hwaccel_rx
-#define rtl8169_rx_quota(count, quota) count
-#endif
-
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static const int max_interrupt_work = 20;
@@ -394,9 +378,7 @@ struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
struct net_device *dev;
-#ifdef CONFIG_R8169_NAPI
struct napi_struct napi;
-#endif
spinlock_t lock; /* spin lock flag */
u32 msg_enable;
int chipset;
@@ -458,10 +440,7 @@ static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8169_down(struct net_device *dev);
static void rtl8169_rx_clear(struct rtl8169_private *tp);
-
-#ifdef CONFIG_R8169_NAPI
static int rtl8169_poll(struct napi_struct *napi, int budget);
-#endif
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
@@ -843,10 +822,11 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
struct sk_buff *skb)
{
u32 opts2 = le32_to_cpu(desc->opts2);
+ struct vlan_group *vlgrp = tp->vlgrp;
int ret;
- if (tp->vlgrp && (opts2 & RxVlanTag)) {
- rtl8169_rx_hwaccel_skb(skb, tp->vlgrp, swab16(opts2 & 0xffff));
+ if (vlgrp && (opts2 & RxVlanTag)) {
+ vlan_hwaccel_receive_skb(skb, vlgrp, swab16(opts2 & 0xffff));
ret = 0;
} else
ret = -1;
@@ -1764,9 +1744,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->change_mtu = rtl8169_change_mtu;
dev->set_mac_address = rtl_set_mac_address;
-#ifdef CONFIG_R8169_NAPI
netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
-#endif
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
@@ -1887,9 +1865,7 @@ static int rtl8169_open(struct net_device *dev)
if (retval < 0)
goto err_release_ring_2;
-#ifdef CONFIG_R8169_NAPI
napi_enable(&tp->napi);
-#endif
rtl_hw_start(dev);
@@ -2197,9 +2173,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
if (ret < 0)
goto out;
-#ifdef CONFIG_R8169_NAPI
napi_enable(&tp->napi);
-#endif
rtl_hw_start(dev);
@@ -2391,17 +2365,13 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
synchronize_irq(dev->irq);
/* Wait for any pending NAPI task to complete */
-#ifdef CONFIG_R8169_NAPI
napi_disable(&tp->napi);
-#endif
rtl8169_irq_mask_and_ack(ioaddr);
-#ifdef CONFIG_R8169_NAPI
tp->intr_mask = 0xffff;
RTL_W16(IntrMask, tp->intr_event);
napi_enable(&tp->napi);
-#endif
}
static void rtl8169_reinit_task(struct work_struct *work)
@@ -2767,7 +2737,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
cur_rx = tp->cur_rx;
rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
- rx_left = rtl8169_rx_quota(rx_left, budget);
+ rx_left = min(rx_left, budget);
for (; rx_left > 0; rx_left--, cur_rx++) {
unsigned int entry = cur_rx % NUM_RX_DESC;
@@ -2829,7 +2799,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
skb->protocol = eth_type_trans(skb, dev);
if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
- rtl8169_rx_skb(skb);
+ netif_receive_skb(skb);
dev->last_rx = jiffies;
dev->stats.rx_bytes += pkt_size;
@@ -2869,87 +2839,61 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
{
struct net_device *dev = dev_instance;
struct rtl8169_private *tp = netdev_priv(dev);
- int boguscnt = max_interrupt_work;
void __iomem *ioaddr = tp->mmio_addr;
- int status;
int handled = 0;
+ int status;
- do {
- status = RTL_R16(IntrStatus);
+ status = RTL_R16(IntrStatus);
- /* hotplug/major error/no more work/shared irq */
- if ((status == 0xFFFF) || !status)
- break;
+ /* hotplug/major error/no more work/shared irq */
+ if ((status == 0xffff) || !status)
+ goto out;
- handled = 1;
+ handled = 1;
- if (unlikely(!netif_running(dev))) {
- rtl8169_asic_down(ioaddr);
- goto out;
- }
+ if (unlikely(!netif_running(dev))) {
+ rtl8169_asic_down(ioaddr);
+ goto out;
+ }
- status &= tp->intr_mask;
- RTL_W16(IntrStatus,
- (status & RxFIFOOver) ? (status | RxOverflow) : status);
+ status &= tp->intr_mask;
+ RTL_W16(IntrStatus,
+ (status & RxFIFOOver) ? (status | RxOverflow) : status);
- if (!(status & tp->intr_event))
- break;
+ if (!(status & tp->intr_event))
+ goto out;
- /* Work around for rx fifo overflow */
- if (unlikely(status & RxFIFOOver) &&
- (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
- netif_stop_queue(dev);
- rtl8169_tx_timeout(dev);
- break;
- }
+ /* Work around for rx fifo overflow */
+ if (unlikely(status & RxFIFOOver) &&
+ (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+ netif_stop_queue(dev);
+ rtl8169_tx_timeout(dev);
+ goto out;
+ }
- if (unlikely(status & SYSErr)) {
- rtl8169_pcierr_interrupt(dev);
- break;
- }
+ if (unlikely(status & SYSErr)) {
+ rtl8169_pcierr_interrupt(dev);
+ goto out;
+ }
- if (status & LinkChg)
- rtl8169_check_link_status(dev, tp, ioaddr);
+ if (status & LinkChg)
+ rtl8169_check_link_status(dev, tp, ioaddr);
-#ifdef CONFIG_R8169_NAPI
- if (status & tp->napi_event) {
- RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
- tp->intr_mask = ~tp->napi_event;
+ if (status & tp->napi_event) {
+ RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+ tp->intr_mask = ~tp->napi_event;
if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
__netif_rx_schedule(dev, &tp->napi);
- else if (netif_msg_intr(tp)) {
- printk(KERN_INFO "%s: interrupt %04x in poll\n",
- dev->name, status);
- }
+ else if (netif_msg_intr(tp)) {
+ printk(KERN_INFO "%s: interrupt %04x in poll\n",
+ dev->name, status);
}
- break;
-#else
- /* Rx interrupt */
- if (status & (RxOK | RxOverflow | RxFIFOOver))
- rtl8169_rx_interrupt(dev, tp, ioaddr, ~(u32)0);
-
- /* Tx interrupt */
- if (status & (TxOK | TxErr))
- rtl8169_tx_interrupt(dev, tp, ioaddr);
-#endif
-
- boguscnt--;
- } while (boguscnt > 0);
-
- if (boguscnt <= 0) {
- if (netif_msg_intr(tp) && net_ratelimit() ) {
- printk(KERN_WARNING
- "%s: Too much work at interrupt!\n", dev->name);
- }
- /* Clear all interrupt sources. */
- RTL_W16(IntrStatus, 0xffff);
}
out:
return IRQ_RETVAL(handled);
}
-#ifdef CONFIG_R8169_NAPI
static int rtl8169_poll(struct napi_struct *napi, int budget)
{
struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
@@ -2975,7 +2919,6 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
return work_done;
}
-#endif
static void rtl8169_down(struct net_device *dev)
{
@@ -2987,9 +2930,7 @@ static void rtl8169_down(struct net_device *dev)
netif_stop_queue(dev);
-#ifdef CONFIG_R8169_NAPI
napi_disable(&tp->napi);
-#endif
core_down:
spin_lock_irq(&tp->lock);
@@ -3098,8 +3039,10 @@ static void rtl_set_rx_mode(struct net_device *dev)
(tp->mac_version == RTL_GIGA_MAC_VER_15) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16) ||
(tp->mac_version == RTL_GIGA_MAC_VER_17)) {
- mc_filter[0] = 0xffffffff;
- mc_filter[1] = 0xffffffff;
+ u32 data = mc_filter[0];
+
+ mc_filter[0] = swab32(mc_filter[1]);
+ mc_filter[1] = swab32(data);
}
RTL_W32(MAR0 + 0, mc_filter[0]);
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index ae7b697456b..9dae40ccf04 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -86,7 +86,7 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.24"
+#define DRV_VERSION "2.0.26.25"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
@@ -545,91 +545,63 @@ static struct pci_driver s2io_driver = {
/* netqueue manipulation helper functions */
static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp)
{
- int i;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (sp->config.multiq) {
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- netif_stop_subqueue(sp->dev, i);
- } else
-#endif
- {
+ if (!sp->config.multiq) {
+ int i;
+
for (i = 0; i < sp->config.tx_fifo_num; i++)
sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP;
- netif_stop_queue(sp->dev);
}
+ netif_tx_stop_all_queues(sp->dev);
}
static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no)
{
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (sp->config.multiq)
- netif_stop_subqueue(sp->dev, fifo_no);
- else
-#endif
- {
+ if (!sp->config.multiq)
sp->mac_control.fifos[fifo_no].queue_state =
FIFO_QUEUE_STOP;
- netif_stop_queue(sp->dev);
- }
+
+ netif_tx_stop_all_queues(sp->dev);
}
static inline void s2io_start_all_tx_queue(struct s2io_nic *sp)
{
- int i;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (sp->config.multiq) {
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- netif_start_subqueue(sp->dev, i);
- } else
-#endif
- {
+ if (!sp->config.multiq) {
+ int i;
+
for (i = 0; i < sp->config.tx_fifo_num; i++)
sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
- netif_start_queue(sp->dev);
}
+ netif_tx_start_all_queues(sp->dev);
}
static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no)
{
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (sp->config.multiq)
- netif_start_subqueue(sp->dev, fifo_no);
- else
-#endif
- {
+ if (!sp->config.multiq)
sp->mac_control.fifos[fifo_no].queue_state =
FIFO_QUEUE_START;
- netif_start_queue(sp->dev);
- }
+
+ netif_tx_start_all_queues(sp->dev);
}
static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
{
- int i;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (sp->config.multiq) {
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- netif_wake_subqueue(sp->dev, i);
- } else
-#endif
- {
+ if (!sp->config.multiq) {
+ int i;
+
for (i = 0; i < sp->config.tx_fifo_num; i++)
sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
- netif_wake_queue(sp->dev);
}
+ netif_tx_wake_all_queues(sp->dev);
}
static inline void s2io_wake_tx_queue(
struct fifo_info *fifo, int cnt, u8 multiq)
{
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (multiq) {
if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no))
netif_wake_subqueue(fifo->dev, fifo->fifo_no);
- } else
-#endif
- if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) {
+ } else if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) {
if (netif_queue_stopped(fifo->dev)) {
fifo->queue_state = FIFO_QUEUE_START;
netif_wake_queue(fifo->dev);
@@ -1909,8 +1881,6 @@ static int init_nic(struct s2io_nic *nic)
static int s2io_link_fault_indication(struct s2io_nic *nic)
{
- if (nic->config.intr_type != INTA)
- return MAC_RMAC_ERR_TIMER;
if (nic->device_type == XFRAME_II_DEVICE)
return LINK_UP_DOWN_INTERRUPT;
else
@@ -1943,7 +1913,9 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
{
struct XENA_dev_config __iomem *bar0 = nic->bar0;
register u64 gen_int_mask = 0;
+ u64 interruptible;
+ writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask);
if (mask & TX_DMA_INTR) {
gen_int_mask |= TXDMA_INT_M;
@@ -2033,10 +2005,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
gen_int_mask |= RXMAC_INT_M;
do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
&bar0->mac_int_mask);
- do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
+ interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
- RMAC_DOUBLE_ECC_ERR |
- RMAC_LINK_STATE_CHANGE_INT,
+ RMAC_DOUBLE_ECC_ERR;
+ if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER)
+ interruptible |= RMAC_LINK_STATE_CHANGE_INT;
+ do_s2io_write_bits(interruptible,
flag, &bar0->mac_rmac_err_mask);
}
@@ -2519,6 +2493,9 @@ static void stop_nic(struct s2io_nic *nic)
/**
* fill_rx_buffers - Allocates the Rx side skbs
* @ring_info: per ring structure
+ * @from_card_up: If this is true, we will map the buffer to get
+ * the dma address for buf0 and buf1 to give it to the card.
+ * Else we will sync the already mapped buffer to give it to the card.
* Description:
* The function allocates Rx side skbs and puts the physical
* address of these buffers into the RxD buffer pointers, so that the NIC
@@ -2536,7 +2513,7 @@ static void stop_nic(struct s2io_nic *nic)
* SUCCESS on success or an appropriate -ve value on failure.
*/
-static int fill_rx_buffers(struct ring_info *ring)
+static int fill_rx_buffers(struct ring_info *ring, int from_card_up)
{
struct sk_buff *skb;
struct RxD_t *rxdp;
@@ -2566,7 +2543,7 @@ static int fill_rx_buffers(struct ring_info *ring)
if (block_no)
rxd_index += (block_no * ring->rxd_count);
- if ((block_no == block_no1) &&
+ if ((block_no == block_no1) &&
(off == ring->rx_curr_get_info.offset) &&
(rxdp->Host_Control)) {
DBG_PRINT(INTR_DBG, "%s: Get and Put",
@@ -2612,7 +2589,7 @@ static int fill_rx_buffers(struct ring_info *ring)
first_rxdp->Control_1 |= RXD_OWN_XENA;
}
stats->mem_alloc_fail_cnt++;
-
+
return -ENOMEM ;
}
stats->mem_allocated += skb->truesize;
@@ -2655,17 +2632,16 @@ static int fill_rx_buffers(struct ring_info *ring)
skb->data = (void *) (unsigned long)tmp;
skb_reset_tail_pointer(skb);
- /* AK: check is wrong. 0 can be valid dma address */
- if (!(rxdp3->Buffer0_ptr))
+ if (from_card_up) {
rxdp3->Buffer0_ptr =
pci_map_single(ring->pdev, ba->ba_0,
BUF0_LEN, PCI_DMA_FROMDEVICE);
- else
+ if (pci_dma_mapping_error(rxdp3->Buffer0_ptr))
+ goto pci_map_failed;
+ } else
pci_dma_sync_single_for_device(ring->pdev,
(dma_addr_t) rxdp3->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(rxdp3->Buffer0_ptr))
- goto pci_map_failed;
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (ring->rxd_mode == RXD_MODE_3B) {
@@ -2682,21 +2658,22 @@ static int fill_rx_buffers(struct ring_info *ring)
if (pci_dma_mapping_error(rxdp3->Buffer2_ptr))
goto pci_map_failed;
- /* AK: check is wrong */
- if (!rxdp3->Buffer1_ptr)
+ if (from_card_up) {
rxdp3->Buffer1_ptr =
pci_map_single(ring->pdev,
ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) {
- pci_unmap_single
- (ring->pdev,
- (dma_addr_t)(unsigned long)
- skb->data,
- ring->mtu + 4,
- PCI_DMA_FROMDEVICE);
- goto pci_map_failed;
+ if (pci_dma_mapping_error
+ (rxdp3->Buffer1_ptr)) {
+ pci_unmap_single
+ (ring->pdev,
+ (dma_addr_t)(unsigned long)
+ skb->data,
+ ring->mtu + 4,
+ PCI_DMA_FROMDEVICE);
+ goto pci_map_failed;
+ }
}
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
@@ -2831,7 +2808,7 @@ static void free_rx_buffers(struct s2io_nic *sp)
static int s2io_chk_rx_buffers(struct ring_info *ring)
{
- if (fill_rx_buffers(ring) == -ENOMEM) {
+ if (fill_rx_buffers(ring, 0) == -ENOMEM) {
DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name);
DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
}
@@ -2962,7 +2939,7 @@ static void s2io_netpoll(struct net_device *dev)
rx_intr_handler(&mac_control->rings[i], 0);
for (i = 0; i < config->rx_ring_num; i++) {
- if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) {
+ if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) {
DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n");
break;
@@ -4189,15 +4166,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_LOCKED;
}
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (sp->config.multiq) {
if (__netif_subqueue_stopped(dev, fifo->fifo_no)) {
spin_unlock_irqrestore(&fifo->tx_lock, flags);
return NETDEV_TX_BUSY;
}
- } else
-#endif
- if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) {
+ } else if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) {
if (netif_queue_stopped(dev)) {
spin_unlock_irqrestore(&fifo->tx_lock, flags);
return NETDEV_TX_BUSY;
@@ -4394,18 +4368,24 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
/* Nothing much can be done. Get out */
return IRQ_HANDLED;
- writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
+ if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) {
+ writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
- if (reason & GEN_INTR_TXTRAFFIC)
- writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
+ if (reason & GEN_INTR_TXPIC)
+ s2io_txpic_intr_handle(sp);
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&fifos[i]);
+ if (reason & GEN_INTR_TXTRAFFIC)
+ writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
- writeq(sp->general_int_mask, &bar0->general_int_mask);
- readl(&bar0->general_int_status);
+ for (i = 0; i < config->tx_fifo_num; i++)
+ tx_intr_handler(&fifos[i]);
- return IRQ_HANDLED;
+ writeq(sp->general_int_mask, &bar0->general_int_mask);
+ readl(&bar0->general_int_status);
+ return IRQ_HANDLED;
+ }
+ /* The interrupt was not raised by us */
+ return IRQ_NONE;
}
static void s2io_txpic_intr_handle(struct s2io_nic *sp)
@@ -6988,7 +6968,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp)
&skb,(u64 *)&temp0_64,
(u64 *)&temp1_64,
(u64 *)&temp2_64,
- size) == ENOMEM) {
+ size) == -ENOMEM) {
return 0;
}
@@ -7133,6 +7113,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
s2io_rem_isr(sp);
+ /* stop the tx queue, indicate link down */
+ s2io_link(sp, LINK_DOWN);
+
/* Check if the device is Quiescent and then Reset the NIC */
while(do_io) {
/* As per the HW requirement we need to replenish the
@@ -7204,7 +7187,7 @@ static int s2io_card_up(struct s2io_nic * sp)
for (i = 0; i < config->rx_ring_num; i++) {
mac_control->rings[i].mtu = dev->mtu;
- ret = fill_rx_buffers(&mac_control->rings[i]);
+ ret = fill_rx_buffers(&mac_control->rings[i], 1);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
dev->name);
@@ -7265,17 +7248,19 @@ static int s2io_card_up(struct s2io_nic * sp)
S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2));
+ set_bit(__S2IO_STATE_CARD_UP, &sp->state);
+
/* Enable select interrupts */
en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
- if (sp->config.intr_type != INTA)
- en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS);
- else {
+ if (sp->config.intr_type != INTA) {
+ interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR;
+ en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
+ } else {
interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
interruptible |= TX_PIC_INTR;
en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
}
- set_bit(__S2IO_STATE_CARD_UP, &sp->state);
return 0;
}
@@ -7633,12 +7618,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
DBG_PRINT(ERR_DBG, "tx fifos\n");
}
-#ifndef CONFIG_NETDEVICES_MULTIQUEUE
- if (multiq) {
- DBG_PRINT(ERR_DBG, "s2io: Multiqueue support not enabled\n");
- multiq = 0;
- }
-#endif
if (multiq)
*dev_multiq = multiq;
@@ -7783,12 +7762,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
pci_disable_device(pdev);
return -ENODEV;
}
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (dev_multiq)
dev = alloc_etherdev_mq(sizeof(struct s2io_nic), tx_fifo_num);
else
-#endif
- dev = alloc_etherdev(sizeof(struct s2io_nic));
+ dev = alloc_etherdev(sizeof(struct s2io_nic));
if (dev == NULL) {
DBG_PRINT(ERR_DBG, "Device allocation failed\n");
pci_disable_device(pdev);
@@ -7979,10 +7956,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
dev->features |= NETIF_F_UFO;
dev->features |= NETIF_F_HW_CSUM;
}
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- if (config->multiq)
- dev->features |= NETIF_F_MULTI_QUEUE;
-#endif
dev->tx_timeout = &s2io_tx_watchdog;
dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
@@ -8708,5 +8681,5 @@ static void s2io_io_resume(struct pci_dev *pdev)
}
netif_device_attach(netdev);
- netif_wake_queue(netdev);
+ netif_tx_wake_all_queues(netdev);
}
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 1827b6686c9..6722a2f7d09 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -748,7 +748,7 @@ struct ring_info {
/* interface MTU value */
unsigned mtu;
-
+
/* Buffer Address store. */
struct buffAdd **ba;
@@ -1107,6 +1107,7 @@ static int init_shared_mem(struct s2io_nic *sp);
static void free_shared_mem(struct s2io_nic *sp);
static int init_nic(struct s2io_nic *nic);
static int rx_intr_handler(struct ring_info *ring_data, int budget);
+static void s2io_txpic_intr_handle(struct s2io_nic *sp);
static void tx_intr_handler(struct fifo_info *fifo_data);
static void s2io_handle_errors(void * dev_id);
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
deleted file mode 100644
index c65199df8a7..00000000000
--- a/drivers/net/saa9730.c
+++ /dev/null
@@ -1,1139 +0,0 @@
-/*
- * Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
- * Authors: Carsten Langgaard <carstenl@mips.com>
- * Maciej W. Rozycki <macro@mips.com>
- * Copyright (C) 2004 Ralf Baechle <ralf@linux-mips.org>
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * SAA9730 ethernet driver.
- *
- * Changes:
- * Angelo Dell'Aera <buffer@antifork.org> : Conversion to the new PCI API
- * (pci_driver).
- * Conversion to spinlocks.
- * Error handling fixes.
- */
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-#include <asm/mips-boards/prom.h>
-
-#include "saa9730.h"
-
-#ifdef LAN_SAA9730_DEBUG
-int lan_saa9730_debug = LAN_SAA9730_DEBUG;
-#else
-int lan_saa9730_debug;
-#endif
-
-#define DRV_MODULE_NAME "saa9730"
-
-static struct pci_device_id saa9730_pci_tbl[] = {
- { PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, saa9730_pci_tbl);
-
-/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
-static unsigned int pci_irq_line;
-
-static void evm_saa9730_enable_lan_int(struct lan_saa9730_private *lp)
-{
- writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
- writel(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptStatus1);
- writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
- EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1);
-}
-
-static void evm_saa9730_disable_lan_int(struct lan_saa9730_private *lp)
-{
- writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
- writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptEnable1);
-}
-
-static void evm_saa9730_clear_lan_int(struct lan_saa9730_private *lp)
-{
- writel(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
-}
-
-static void evm_saa9730_block_lan_int(struct lan_saa9730_private *lp)
-{
- writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
-}
-
-static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
-{
- writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
- &lp->evm_saa9730_regs->InterruptBlock1);
-}
-
-static void __used show_saa9730_regs(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
- int i, j;
-
- printk("TxmBufferA = %p\n", lp->TxmBuffer[0][0]);
- printk("TxmBufferB = %p\n", lp->TxmBuffer[1][0]);
- printk("RcvBufferA = %p\n", lp->RcvBuffer[0][0]);
- printk("RcvBufferB = %p\n", lp->RcvBuffer[1][0]);
-
- for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
- for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
- printk("TxmBuffer[%d][%d] = %x\n", i, j,
- le32_to_cpu(*(unsigned int *)
- lp->TxmBuffer[i][j]));
- }
- }
- for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
- for (j = 0; j < LAN_SAA9730_RCV_Q_SIZE; j++) {
- printk("RcvBuffer[%d][%d] = %x\n", i, j,
- le32_to_cpu(*(unsigned int *)
- lp->RcvBuffer[i][j]));
- }
- }
- printk("lp->evm_saa9730_regs->InterruptBlock1 = %x\n",
- readl(&lp->evm_saa9730_regs->InterruptBlock1));
- printk("lp->evm_saa9730_regs->InterruptStatus1 = %x\n",
- readl(&lp->evm_saa9730_regs->InterruptStatus1));
- printk("lp->evm_saa9730_regs->InterruptEnable1 = %x\n",
- readl(&lp->evm_saa9730_regs->InterruptEnable1));
- printk("lp->lan_saa9730_regs->Ok2Use = %x\n",
- readl(&lp->lan_saa9730_regs->Ok2Use));
- printk("lp->NextTxmBufferIndex = %x\n", lp->NextTxmBufferIndex);
- printk("lp->NextTxmPacketIndex = %x\n", lp->NextTxmPacketIndex);
- printk("lp->PendingTxmBufferIndex = %x\n",
- lp->PendingTxmBufferIndex);
- printk("lp->PendingTxmPacketIndex = %x\n",
- lp->PendingTxmPacketIndex);
- printk("lp->lan_saa9730_regs->LanDmaCtl = %x\n",
- readl(&lp->lan_saa9730_regs->LanDmaCtl));
- printk("lp->lan_saa9730_regs->DmaStatus = %x\n",
- readl(&lp->lan_saa9730_regs->DmaStatus));
- printk("lp->lan_saa9730_regs->CamCtl = %x\n",
- readl(&lp->lan_saa9730_regs->CamCtl));
- printk("lp->lan_saa9730_regs->TxCtl = %x\n",
- readl(&lp->lan_saa9730_regs->TxCtl));
- printk("lp->lan_saa9730_regs->TxStatus = %x\n",
- readl(&lp->lan_saa9730_regs->TxStatus));
- printk("lp->lan_saa9730_regs->RxCtl = %x\n",
- readl(&lp->lan_saa9730_regs->RxCtl));
- printk("lp->lan_saa9730_regs->RxStatus = %x\n",
- readl(&lp->lan_saa9730_regs->RxStatus));
-
- for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
- writel(i, &lp->lan_saa9730_regs->CamAddress);
- printk("lp->lan_saa9730_regs->CamData = %x\n",
- readl(&lp->lan_saa9730_regs->CamData));
- }
-
- printk("dev->stats.tx_packets = %lx\n", dev->stats.tx_packets);
- printk("dev->stats.tx_errors = %lx\n", dev->stats.tx_errors);
- printk("dev->stats.tx_aborted_errors = %lx\n",
- dev->stats.tx_aborted_errors);
- printk("dev->stats.tx_window_errors = %lx\n",
- dev->stats.tx_window_errors);
- printk("dev->stats.tx_carrier_errors = %lx\n",
- dev->stats.tx_carrier_errors);
- printk("dev->stats.tx_fifo_errors = %lx\n",
- dev->stats.tx_fifo_errors);
- printk("dev->stats.tx_heartbeat_errors = %lx\n",
- dev->stats.tx_heartbeat_errors);
- printk("dev->stats.collisions = %lx\n", dev->stats.collisions);
-
- printk("dev->stats.rx_packets = %lx\n", dev->stats.rx_packets);
- printk("dev->stats.rx_errors = %lx\n", dev->stats.rx_errors);
- printk("dev->stats.rx_dropped = %lx\n", dev->stats.rx_dropped);
- printk("dev->stats.rx_crc_errors = %lx\n", dev->stats.rx_crc_errors);
- printk("dev->stats.rx_frame_errors = %lx\n",
- dev->stats.rx_frame_errors);
- printk("dev->stats.rx_fifo_errors = %lx\n",
- dev->stats.rx_fifo_errors);
- printk("dev->stats.rx_length_errors = %lx\n",
- dev->stats.rx_length_errors);
-
- printk("lp->lan_saa9730_regs->DebugPCIMasterAddr = %x\n",
- readl(&lp->lan_saa9730_regs->DebugPCIMasterAddr));
- printk("lp->lan_saa9730_regs->DebugLanTxStateMachine = %x\n",
- readl(&lp->lan_saa9730_regs->DebugLanTxStateMachine));
- printk("lp->lan_saa9730_regs->DebugLanRxStateMachine = %x\n",
- readl(&lp->lan_saa9730_regs->DebugLanRxStateMachine));
- printk("lp->lan_saa9730_regs->DebugLanTxFifoPointers = %x\n",
- readl(&lp->lan_saa9730_regs->DebugLanTxFifoPointers));
- printk("lp->lan_saa9730_regs->DebugLanRxFifoPointers = %x\n",
- readl(&lp->lan_saa9730_regs->DebugLanRxFifoPointers));
- printk("lp->lan_saa9730_regs->DebugLanCtlStateMachine = %x\n",
- readl(&lp->lan_saa9730_regs->DebugLanCtlStateMachine));
-}
-
-static void lan_saa9730_buffer_init(struct lan_saa9730_private *lp)
-{
- int i, j;
-
- /* Init RX buffers */
- for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
- for (j = 0; j < LAN_SAA9730_RCV_Q_SIZE; j++) {
- *(unsigned int *) lp->RcvBuffer[i][j] =
- cpu_to_le32(RXSF_READY <<
- RX_STAT_CTL_OWNER_SHF);
- }
- }
-
- /* Init TX buffers */
- for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
- for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
- *(unsigned int *) lp->TxmBuffer[i][j] =
- cpu_to_le32(TXSF_EMPTY <<
- TX_STAT_CTL_OWNER_SHF);
- }
- }
-}
-
-static void lan_saa9730_free_buffers(struct pci_dev *pdev,
- struct lan_saa9730_private *lp)
-{
- pci_free_consistent(pdev, lp->buffer_size, lp->buffer_start,
- lp->dma_addr);
-}
-
-static int lan_saa9730_allocate_buffers(struct pci_dev *pdev,
- struct lan_saa9730_private *lp)
-{
- void *Pa;
- unsigned int i, j, rxoffset, txoffset;
- int ret;
-
- /* Initialize buffer space */
- lp->DmaRcvPackets = LAN_SAA9730_RCV_Q_SIZE;
- lp->DmaTxmPackets = LAN_SAA9730_TXM_Q_SIZE;
-
- /* Initialize Rx Buffer Index */
- lp->NextRcvPacketIndex = 0;
- lp->NextRcvBufferIndex = 0;
-
- /* Set current buffer index & next available packet index */
- lp->NextTxmPacketIndex = 0;
- lp->NextTxmBufferIndex = 0;
- lp->PendingTxmPacketIndex = 0;
- lp->PendingTxmBufferIndex = 0;
-
- /*
- * Allocate all RX and TX packets in one chunk.
- * The Rx and Tx packets must be PACKET_SIZE aligned.
- */
- lp->buffer_size = ((LAN_SAA9730_RCV_Q_SIZE + LAN_SAA9730_TXM_Q_SIZE) *
- LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_BUFFERS) +
- LAN_SAA9730_PACKET_SIZE;
- lp->buffer_start = pci_alloc_consistent(pdev, lp->buffer_size,
- &lp->dma_addr);
- if (!lp->buffer_start) {
- ret = -ENOMEM;
- goto out;
- }
-
- Pa = (void *)ALIGN((unsigned long)lp->buffer_start,
- LAN_SAA9730_PACKET_SIZE);
-
- rxoffset = Pa - lp->buffer_start;
-
- /* Init RX buffers */
- for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
- for (j = 0; j < LAN_SAA9730_RCV_Q_SIZE; j++) {
- *(unsigned int *) Pa =
- cpu_to_le32(RXSF_READY <<
- RX_STAT_CTL_OWNER_SHF);
- lp->RcvBuffer[i][j] = Pa;
- Pa += LAN_SAA9730_PACKET_SIZE;
- }
- }
-
- txoffset = Pa - lp->buffer_start;
-
- /* Init TX buffers */
- for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
- for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
- *(unsigned int *) Pa =
- cpu_to_le32(TXSF_EMPTY <<
- TX_STAT_CTL_OWNER_SHF);
- lp->TxmBuffer[i][j] = Pa;
- Pa += LAN_SAA9730_PACKET_SIZE;
- }
- }
-
- /*
- * Set rx buffer A and rx buffer B to point to the first two buffer
- * spaces.
- */
- writel(lp->dma_addr + rxoffset, &lp->lan_saa9730_regs->RxBuffA);
- writel(lp->dma_addr + rxoffset +
- LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE,
- &lp->lan_saa9730_regs->RxBuffB);
-
- /*
- * Set txm_buf_a and txm_buf_b to point to the first two buffer
- * space
- */
- writel(lp->dma_addr + txoffset,
- &lp->lan_saa9730_regs->TxBuffA);
- writel(lp->dma_addr + txoffset +
- LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE,
- &lp->lan_saa9730_regs->TxBuffB);
-
- /* Set packet number */
- writel((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
- (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) |
- (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) |
- (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF),
- &lp->lan_saa9730_regs->PacketCount);
-
- return 0;
-
-out:
- return ret;
-}
-
-static int lan_saa9730_cam_load(struct lan_saa9730_private *lp)
-{
- unsigned int i;
- unsigned char *NetworkAddress;
-
- NetworkAddress = (unsigned char *) &lp->PhysicalAddress[0][0];
-
- for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
- /* First set address to where data is written */
- writel(i, &lp->lan_saa9730_regs->CamAddress);
- writel((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16) |
- (NetworkAddress[2] << 8) | NetworkAddress[3],
- &lp->lan_saa9730_regs->CamData);
- NetworkAddress += 4;
- }
- return 0;
-}
-
-static int lan_saa9730_cam_init(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
- unsigned int i;
-
- /* Copy MAC-address into all entries. */
- for (i = 0; i < LAN_SAA9730_CAM_ENTRIES; i++) {
- memcpy((unsigned char *) lp->PhysicalAddress[i],
- (unsigned char *) dev->dev_addr, 6);
- }
-
- return 0;
-}
-
-static int lan_saa9730_mii_init(struct lan_saa9730_private *lp)
-{
- int i, l;
-
- /* Check link status, spin here till station is not busy. */
- i = 0;
- while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) & MD_CA_BUSY) {
- i++;
- if (i > 100) {
- printk("Error: lan_saa9730_mii_init: timeout\n");
- return -1;
- }
- mdelay(1); /* wait 1 ms. */
- }
-
- /* Now set the control and address register. */
- writel(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
- &lp->lan_saa9730_regs->StationMgmtCtl);
-
- /* check link status, spin here till station is not busy */
- i = 0;
- while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) & MD_CA_BUSY) {
- i++;
- if (i > 100) {
- printk("Error: lan_saa9730_mii_init: timeout\n");
- return -1;
- }
- mdelay(1); /* wait 1 ms. */
- }
-
- /* Wait for 1 ms. */
- mdelay(1);
-
- /* Check the link status. */
- if (readl(&lp->lan_saa9730_regs->StationMgmtData) &
- PHY_STATUS_LINK_UP) {
- /* Link is up. */
- return 0;
- } else {
- /* Link is down, reset the PHY first. */
-
- /* set PHY address = 'CONTROL' */
- writel(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
- &lp->lan_saa9730_regs->StationMgmtCtl);
-
- /* Wait for 1 ms. */
- mdelay(1);
-
- /* set 'CONTROL' = force reset and renegotiate */
- writel(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
- PHY_CONTROL_RESTART_AUTO_NEG,
- &lp->lan_saa9730_regs->StationMgmtData);
-
- /* Wait for 50 ms. */
- mdelay(50);
-
- /* set 'BUSY' to start operation */
- writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
- PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl);
-
- /* await completion */
- i = 0;
- while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) &
- MD_CA_BUSY) {
- i++;
- if (i > 100) {
- printk
- ("Error: lan_saa9730_mii_init: timeout\n");
- return -1;
- }
- mdelay(1); /* wait 1 ms. */
- }
-
- /* Wait for 1 ms. */
- mdelay(1);
-
- for (l = 0; l < 2; l++) {
- /* set PHY address = 'STATUS' */
- writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
- PHY_STATUS,
- &lp->lan_saa9730_regs->StationMgmtCtl);
-
- /* await completion */
- i = 0;
- while (readl(&lp->lan_saa9730_regs->StationMgmtCtl) &
- MD_CA_BUSY) {
- i++;
- if (i > 100) {
- printk
- ("Error: lan_saa9730_mii_init: timeout\n");
- return -1;
- }
- mdelay(1); /* wait 1 ms. */
- }
-
- /* wait for 3 sec. */
- mdelay(3000);
-
- /* check the link status */
- if (readl(&lp->lan_saa9730_regs->StationMgmtData) &
- PHY_STATUS_LINK_UP) {
- /* link is up */
- break;
- }
- }
- }
-
- return 0;
-}
-
-static int lan_saa9730_control_init(struct lan_saa9730_private *lp)
-{
- /* Initialize DMA control register. */
- writel((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
- (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) |
- (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF)
- | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN |
- DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN,
- &lp->lan_saa9730_regs->LanDmaCtl);
-
- /* Initial MAC control register. */
- writel((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
- &lp->lan_saa9730_regs->MacCtl);
-
- /* Initialize CAM control register. */
- writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
- &lp->lan_saa9730_regs->CamCtl);
-
- /*
- * Initialize CAM enable register, only turn on first entry, should
- * contain own addr.
- */
- writel(0x0001, &lp->lan_saa9730_regs->CamEnable);
-
- /* Initialize Tx control register */
- writel(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
-
- /* Initialize Rcv control register */
- writel(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
-
- /* Reset DMA engine */
- writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
-
- return 0;
-}
-
-static int lan_saa9730_stop(struct lan_saa9730_private *lp)
-{
- int i;
-
- /* Stop DMA first */
- writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) &
- ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA),
- &lp->lan_saa9730_regs->LanDmaCtl);
-
- /* Set the SW Reset bits in DMA and MAC control registers */
- writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
- writel(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
- &lp->lan_saa9730_regs->MacCtl);
-
- /*
- * Wait for MAC reset to have finished. The reset bit is auto cleared
- * when the reset is done.
- */
- i = 0;
- while (readl(&lp->lan_saa9730_regs->MacCtl) & MAC_CONTROL_RESET) {
- i++;
- if (i > 100) {
- printk
- ("Error: lan_sa9730_stop: MAC reset timeout\n");
- return -1;
- }
- mdelay(1); /* wait 1 ms. */
- }
-
- return 0;
-}
-
-static int lan_saa9730_dma_init(struct lan_saa9730_private *lp)
-{
- /* Stop lan controller. */
- lan_saa9730_stop(lp);
-
- writel(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
- &lp->lan_saa9730_regs->Timeout);
-
- return 0;
-}
-
-static int lan_saa9730_start(struct lan_saa9730_private *lp)
-{
- lan_saa9730_buffer_init(lp);
-
- /* Initialize Rx Buffer Index */
- lp->NextRcvPacketIndex = 0;
- lp->NextRcvBufferIndex = 0;
-
- /* Set current buffer index & next available packet index */
- lp->NextTxmPacketIndex = 0;
- lp->NextTxmBufferIndex = 0;
- lp->PendingTxmPacketIndex = 0;
- lp->PendingTxmBufferIndex = 0;
-
- writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
- DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl);
-
- /* For Tx, turn on MAC then DMA */
- writel(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
- &lp->lan_saa9730_regs->TxCtl);
-
- /* For Rx, turn on DMA then MAC */
- writel(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
- &lp->lan_saa9730_regs->RxCtl);
-
- /* Set Ok2Use to let hardware own the buffers. */
- writel(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
-
- return 0;
-}
-
-static int lan_saa9730_restart(struct lan_saa9730_private *lp)
-{
- lan_saa9730_stop(lp);
- lan_saa9730_start(lp);
-
- return 0;
-}
-
-static int lan_saa9730_tx(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
- unsigned int *pPacket;
- unsigned int tx_status;
-
- if (lan_saa9730_debug > 5)
- printk("lan_saa9730_tx interrupt\n");
-
- /* Clear interrupt. */
- writel(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
-
- while (1) {
- pPacket = lp->TxmBuffer[lp->PendingTxmBufferIndex]
- [lp->PendingTxmPacketIndex];
-
- /* Get status of first packet transmitted. */
- tx_status = le32_to_cpu(*pPacket);
-
- /* Check ownership. */
- if ((tx_status & TX_STAT_CTL_OWNER_MSK) !=
- (TXSF_HWDONE << TX_STAT_CTL_OWNER_SHF)) break;
-
- /* Check for error. */
- if (tx_status & TX_STAT_CTL_ERROR_MSK) {
- if (lan_saa9730_debug > 1)
- printk("lan_saa9730_tx: tx error = %x\n",
- tx_status);
-
- dev->stats.tx_errors++;
- if (tx_status &
- (TX_STATUS_EX_COLL << TX_STAT_CTL_STATUS_SHF))
- dev->stats.tx_aborted_errors++;
- if (tx_status &
- (TX_STATUS_LATE_COLL << TX_STAT_CTL_STATUS_SHF))
- dev->stats.tx_window_errors++;
- if (tx_status &
- (TX_STATUS_L_CARR << TX_STAT_CTL_STATUS_SHF))
- dev->stats.tx_carrier_errors++;
- if (tx_status &
- (TX_STATUS_UNDER << TX_STAT_CTL_STATUS_SHF))
- dev->stats.tx_fifo_errors++;
- if (tx_status &
- (TX_STATUS_SQ_ERR << TX_STAT_CTL_STATUS_SHF))
- dev->stats.tx_heartbeat_errors++;
-
- dev->stats.collisions +=
- tx_status & TX_STATUS_TX_COLL_MSK;
- }
-
- /* Free buffer. */
- *pPacket =
- cpu_to_le32(TXSF_EMPTY << TX_STAT_CTL_OWNER_SHF);
-
- /* Update pending index pointer. */
- lp->PendingTxmPacketIndex++;
- if (lp->PendingTxmPacketIndex >= LAN_SAA9730_TXM_Q_SIZE) {
- lp->PendingTxmPacketIndex = 0;
- lp->PendingTxmBufferIndex ^= 1;
- }
- }
-
- /* The tx buffer is no longer full. */
- netif_wake_queue(dev);
-
- return 0;
-}
-
-static int lan_saa9730_rx(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
- int len = 0;
- struct sk_buff *skb = 0;
- unsigned int rx_status;
- int BufferIndex;
- int PacketIndex;
- unsigned int *pPacket;
- unsigned char *pData;
-
- if (lan_saa9730_debug > 5)
- printk("lan_saa9730_rx interrupt\n");
-
- /* Clear receive interrupts. */
- writel(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
- DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);
-
- /* Address next packet */
- BufferIndex = lp->NextRcvBufferIndex;
- PacketIndex = lp->NextRcvPacketIndex;
- pPacket = lp->RcvBuffer[BufferIndex][PacketIndex];
- rx_status = le32_to_cpu(*pPacket);
-
- /* Process each packet. */
- while ((rx_status & RX_STAT_CTL_OWNER_MSK) ==
- (RXSF_HWDONE << RX_STAT_CTL_OWNER_SHF)) {
- /* Check the rx status. */
- if (rx_status & (RX_STATUS_GOOD << RX_STAT_CTL_STATUS_SHF)) {
- /* Received packet is good. */
- len = (rx_status & RX_STAT_CTL_LENGTH_MSK) >>
- RX_STAT_CTL_LENGTH_SHF;
-
- pData = (unsigned char *) pPacket;
- pData += 4;
- skb = dev_alloc_skb(len + 2);
- if (skb == 0) {
- printk
- ("%s: Memory squeeze, deferring packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- } else {
- dev->stats.rx_bytes += len;
- dev->stats.rx_packets++;
- skb_reserve(skb, 2); /* 16 byte align */
- skb_put(skb, len); /* make room */
- skb_copy_to_linear_data(skb,
- (unsigned char *) pData,
- len);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- }
- } else {
- /* We got an error packet. */
- if (lan_saa9730_debug > 2)
- printk
- ("lan_saa9730_rx: We got an error packet = %x\n",
- rx_status);
-
- dev->stats.rx_errors++;
- if (rx_status &
- (RX_STATUS_CRC_ERR << RX_STAT_CTL_STATUS_SHF))
- dev->stats.rx_crc_errors++;
- if (rx_status &
- (RX_STATUS_ALIGN_ERR << RX_STAT_CTL_STATUS_SHF))
- dev->stats.rx_frame_errors++;
- if (rx_status &
- (RX_STATUS_OVERFLOW << RX_STAT_CTL_STATUS_SHF))
- dev->stats.rx_fifo_errors++;
- if (rx_status &
- (RX_STATUS_LONG_ERR << RX_STAT_CTL_STATUS_SHF))
- dev->stats.rx_length_errors++;
- }
-
- /* Indicate we have processed the buffer. */
- *pPacket = cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF);
-
- /* Make sure A or B is available to hardware as appropriate. */
- writel(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A,
- &lp->lan_saa9730_regs->Ok2Use);
-
- /* Go to next packet in sequence. */
- lp->NextRcvPacketIndex++;
- if (lp->NextRcvPacketIndex >= LAN_SAA9730_RCV_Q_SIZE) {
- lp->NextRcvPacketIndex = 0;
- lp->NextRcvBufferIndex ^= 1;
- }
-
- /* Address next packet */
- BufferIndex = lp->NextRcvBufferIndex;
- PacketIndex = lp->NextRcvPacketIndex;
- pPacket = lp->RcvBuffer[BufferIndex][PacketIndex];
- rx_status = le32_to_cpu(*pPacket);
- }
-
- return 0;
-}
-
-static irqreturn_t lan_saa9730_interrupt(const int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct lan_saa9730_private *lp = netdev_priv(dev);
-
- if (lan_saa9730_debug > 5)
- printk("lan_saa9730_interrupt\n");
-
- /* Disable the EVM LAN interrupt. */
- evm_saa9730_block_lan_int(lp);
-
- /* Clear the EVM LAN interrupt. */
- evm_saa9730_clear_lan_int(lp);
-
- /* Service pending transmit interrupts. */
- if (readl(&lp->lan_saa9730_regs->DmaStatus) & DMA_STATUS_MAC_TX_INT)
- lan_saa9730_tx(dev);
-
- /* Service pending receive interrupts. */
- if (readl(&lp->lan_saa9730_regs->DmaStatus) &
- (DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
- DMA_STATUS_RX_TO_INT)) lan_saa9730_rx(dev);
-
- /* Enable the EVM LAN interrupt. */
- evm_saa9730_unblock_lan_int(lp);
-
- return IRQ_HANDLED;
-}
-
-static int lan_saa9730_open(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
-
- /* Associate IRQ with lan_saa9730_interrupt */
- if (request_irq(dev->irq, &lan_saa9730_interrupt, 0, "SAA9730 Eth",
- dev)) {
- printk("lan_saa9730_open: Can't get irq %d\n", dev->irq);
- return -EAGAIN;
- }
-
- /* Enable the Lan interrupt in the event manager. */
- evm_saa9730_enable_lan_int(lp);
-
- /* Start the LAN controller */
- if (lan_saa9730_start(lp))
- return -1;
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-static int lan_saa9730_write(struct lan_saa9730_private *lp,
- struct sk_buff *skb, int skblen)
-{
- unsigned char *pbData = skb->data;
- unsigned int len = skblen;
- unsigned char *pbPacketData;
- unsigned int tx_status;
- int BufferIndex;
- int PacketIndex;
-
- if (lan_saa9730_debug > 5)
- printk("lan_saa9730_write: skb=%p\n", skb);
-
- BufferIndex = lp->NextTxmBufferIndex;
- PacketIndex = lp->NextTxmPacketIndex;
-
- tx_status = le32_to_cpu(*(unsigned int *)lp->TxmBuffer[BufferIndex]
- [PacketIndex]);
- if ((tx_status & TX_STAT_CTL_OWNER_MSK) !=
- (TXSF_EMPTY << TX_STAT_CTL_OWNER_SHF)) {
- if (lan_saa9730_debug > 4)
- printk
- ("lan_saa9730_write: Tx buffer not available: tx_status = %x\n",
- tx_status);
- return -1;
- }
-
- lp->NextTxmPacketIndex++;
- if (lp->NextTxmPacketIndex >= LAN_SAA9730_TXM_Q_SIZE) {
- lp->NextTxmPacketIndex = 0;
- lp->NextTxmBufferIndex ^= 1;
- }
-
- pbPacketData = lp->TxmBuffer[BufferIndex][PacketIndex];
- pbPacketData += 4;
-
- /* copy the bits */
- memcpy(pbPacketData, pbData, len);
-
- /* Set transmit status for hardware */
- *(unsigned int *)lp->TxmBuffer[BufferIndex][PacketIndex] =
- cpu_to_le32((TXSF_READY << TX_STAT_CTL_OWNER_SHF) |
- (TX_STAT_CTL_INT_AFTER_TX <<
- TX_STAT_CTL_FRAME_SHF) |
- (len << TX_STAT_CTL_LENGTH_SHF));
-
- /* Make sure A or B is available to hardware as appropriate. */
- writel(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A,
- &lp->lan_saa9730_regs->Ok2Use);
-
- return 0;
-}
-
-static void lan_saa9730_tx_timeout(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
-
- /* Transmitter timeout, serious problems */
- dev->stats.tx_errors++;
- printk("%s: transmit timed out, reset\n", dev->name);
- /*show_saa9730_regs(dev); */
- lan_saa9730_restart(lp);
-
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
-}
-
-static int lan_saa9730_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
- unsigned long flags;
- int skblen;
- int len;
-
- if (lan_saa9730_debug > 4)
- printk("Send packet: skb=%p\n", skb);
-
- skblen = skb->len;
-
- spin_lock_irqsave(&lp->lock, flags);
-
- len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
-
- if (lan_saa9730_write(lp, skb, skblen)) {
- spin_unlock_irqrestore(&lp->lock, flags);
- printk("Error when writing packet to controller: skb=%p\n", skb);
- netif_stop_queue(dev);
- return -1;
- }
-
- dev->stats.tx_bytes += len;
- dev->stats.tx_packets++;
-
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
- dev_kfree_skb(skb);
-
- spin_unlock_irqrestore(&lp->lock, flags);
-
- return 0;
-}
-
-static int lan_saa9730_close(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
-
- if (lan_saa9730_debug > 1)
- printk("lan_saa9730_close:\n");
-
- netif_stop_queue(dev);
-
- /* Disable the Lan interrupt in the event manager. */
- evm_saa9730_disable_lan_int(lp);
-
- /* Stop the controller */
- if (lan_saa9730_stop(lp))
- return -1;
-
- free_irq(dev->irq, (void *) dev);
-
- return 0;
-}
-
-static void lan_saa9730_set_multicast(struct net_device *dev)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
-
- /* Stop the controller */
- lan_saa9730_stop(lp);
-
- if (dev->flags & IFF_PROMISC) {
- /* accept all packets */
- writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
- CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
- &lp->lan_saa9730_regs->CamCtl);
- } else {
- if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
- /* accept all multicast packets */
- /*
- * Will handle the multicast stuff later. -carstenl
- */
- writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
- CAM_CONTROL_BROAD_ACC,
- &lp->lan_saa9730_regs->CamCtl);
- }
- }
-
- lan_saa9730_restart(lp);
-}
-
-
-static void __devexit saa9730_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct lan_saa9730_private *lp = netdev_priv(dev);
-
- if (dev) {
- unregister_netdev(dev);
- lan_saa9730_free_buffers(pdev, lp);
- iounmap(lp->lan_saa9730_regs);
- iounmap(lp->evm_saa9730_regs);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- }
-}
-
-
-static int lan_saa9730_init(struct net_device *dev, struct pci_dev *pdev,
- unsigned long ioaddr, int irq)
-{
- struct lan_saa9730_private *lp = netdev_priv(dev);
- unsigned char ethernet_addr[6];
- int ret;
-
- if (get_ethernet_addr(ethernet_addr)) {
- ret = -ENODEV;
- goto out;
- }
-
- memcpy(dev->dev_addr, ethernet_addr, 6);
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
- lp->pci_dev = pdev;
-
- /* Set SAA9730 LAN base address. */
- lp->lan_saa9730_regs = ioremap(ioaddr + SAA9730_LAN_REGS_ADDR,
- SAA9730_LAN_REGS_SIZE);
- if (!lp->lan_saa9730_regs) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* Set SAA9730 EVM base address. */
- lp->evm_saa9730_regs = ioremap(ioaddr + SAA9730_EVM_REGS_ADDR,
- SAA9730_EVM_REGS_SIZE);
- if (!lp->evm_saa9730_regs) {
- ret = -ENOMEM;
- goto out_iounmap_lan;
- }
-
- /* Allocate LAN RX/TX frame buffer space. */
- if ((ret = lan_saa9730_allocate_buffers(pdev, lp)))
- goto out_iounmap;
-
- /* Stop LAN controller. */
- if ((ret = lan_saa9730_stop(lp)))
- goto out_free_consistent;
-
- /* Initialize CAM registers. */
- if ((ret = lan_saa9730_cam_init(dev)))
- goto out_free_consistent;
-
- /* Initialize MII registers. */
- if ((ret = lan_saa9730_mii_init(lp)))
- goto out_free_consistent;
-
- /* Initialize control registers. */
- if ((ret = lan_saa9730_control_init(lp)))
- goto out_free_consistent;
-
- /* Load CAM registers. */
- if ((ret = lan_saa9730_cam_load(lp)))
- goto out_free_consistent;
-
- /* Initialize DMA context registers. */
- if ((ret = lan_saa9730_dma_init(lp)))
- goto out_free_consistent;
-
- spin_lock_init(&lp->lock);
-
- dev->open = lan_saa9730_open;
- dev->hard_start_xmit = lan_saa9730_start_xmit;
- dev->stop = lan_saa9730_close;
- dev->set_multicast_list = lan_saa9730_set_multicast;
- dev->tx_timeout = lan_saa9730_tx_timeout;
- dev->watchdog_timeo = (HZ >> 1);
- dev->dma = 0;
-
- ret = register_netdev (dev);
- if (ret)
- goto out_free_consistent;
-
- return 0;
-
-out_free_consistent:
- lan_saa9730_free_buffers(pdev, lp);
-out_iounmap:
- iounmap(lp->evm_saa9730_regs);
-out_iounmap_lan:
- iounmap(lp->lan_saa9730_regs);
-out:
- return ret;
-}
-
-
-static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct net_device *dev = NULL;
- unsigned long pci_ioaddr;
- int err;
-
- if (lan_saa9730_debug > 1)
- printk("saa9730.c: PCI bios is present, checking for devices...\n");
-
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
- goto out;
- }
-
- err = pci_request_regions(pdev, DRV_MODULE_NAME);
- if (err) {
- printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
- goto out_disable_pdev;
- }
-
- pci_irq_line = pdev->irq;
- /* LAN base address in located at BAR 1. */
-
- pci_ioaddr = pci_resource_start(pdev, 1);
- pci_set_master(pdev);
-
- printk("Found SAA9730 (PCI) at %lx, irq %d.\n",
- pci_ioaddr, pci_irq_line);
-
- dev = alloc_etherdev(sizeof(struct lan_saa9730_private));
- if (!dev)
- goto out_disable_pdev;
-
- err = lan_saa9730_init(dev, pdev, pci_ioaddr, pci_irq_line);
- if (err) {
- printk("LAN init failed");
- goto out_free_netdev;
- }
-
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
- return 0;
-
-out_free_netdev:
- free_netdev(dev);
-out_disable_pdev:
- pci_disable_device(pdev);
-out:
- pci_set_drvdata(pdev, NULL);
- return err;
-}
-
-
-static struct pci_driver saa9730_driver = {
- .name = DRV_MODULE_NAME,
- .id_table = saa9730_pci_tbl,
- .probe = saa9730_init_one,
- .remove = __devexit_p(saa9730_remove_one),
-};
-
-
-static int __init saa9730_init(void)
-{
- return pci_register_driver(&saa9730_driver);
-}
-
-static void __exit saa9730_cleanup(void)
-{
- pci_unregister_driver(&saa9730_driver);
-}
-
-module_init(saa9730_init);
-module_exit(saa9730_cleanup);
-
-MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
-MODULE_DESCRIPTION("Philips SAA9730 ethernet driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/saa9730.h b/drivers/net/saa9730.h
deleted file mode 100644
index 010a120ea93..00000000000
--- a/drivers/net/saa9730.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
- * Authors: Carsten Langgaard <carstenl@mips.com>
- * Maciej W. Rozycki <macro@mips.com>
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- * ########################################################################
- *
- * SAA9730 ethernet driver description.
- *
- */
-#ifndef _SAA9730_H
-#define _SAA9730_H
-
-
-/* Number of 6-byte entries in the CAM. */
-#define LAN_SAA9730_CAM_ENTRIES 10
-#define LAN_SAA9730_CAM_DWORDS ((LAN_SAA9730_CAM_ENTRIES*6)/4)
-
-/* TX and RX packet size: fixed to 2048 bytes, according to HW requirements. */
-#define LAN_SAA9730_PACKET_SIZE 2048
-
-/*
- * Number of TX buffers = number of RX buffers = 2, which is fixed according
- * to HW requirements.
- */
-#define LAN_SAA9730_BUFFERS 2
-
-/* Number of RX packets per RX buffer. */
-#define LAN_SAA9730_RCV_Q_SIZE 15
-
-/* Number of TX packets per TX buffer. */
-#define LAN_SAA9730_TXM_Q_SIZE 15
-
-/*
- * We get an interrupt for each LAN_SAA9730_DEFAULT_RCV_Q_INT_THRESHOLD
- * packets received.
- * If however we receive less than LAN_SAA9730_DEFAULT_RCV_Q_INT_THRESHOLD
- * packets, the hardware can timeout after a certain time and still tell
- * us packets have arrived.
- * The timeout value in unit of 32 PCI clocks (33Mhz).
- * The value 200 approximates 0.0002 seconds.
- */
-#define LAN_SAA9730_RCV_Q_INT_THRESHOLD 1
-#define LAN_SAA9730_DEFAULT_TIME_OUT_CNT 10
-
-#define RXSF_NDIS 0
-#define RXSF_READY 2
-#define RXSF_HWDONE 3
-
-#define TXSF_EMPTY 0
-#define TXSF_READY 2
-#define TXSF_HWDONE 3
-
-#define LANEND_LITTLE 0
-#define LANEND_BIG_2143 1
-#define LANEND_BIG_4321 2
-
-#define LANMB_ANY 0
-#define LANMB_8 1
-#define LANMB_32 2
-#define LANMB_64 3
-
-#define MACCM_AUTOMATIC 0
-#define MACCM_10MB 1
-#define MACCM_MII 2
-
-/*
- * PHY definitions for Basic registers of QS6612 (used on MIPS ATLAS board)
- */
-#define PHY_CONTROL 0x0
-#define PHY_STATUS 0x1
-#define PHY_STATUS_LINK_UP 0x4
-#define PHY_CONTROL_RESET 0x8000
-#define PHY_CONTROL_AUTO_NEG 0x1000
-#define PHY_CONTROL_RESTART_AUTO_NEG 0x0200
-#define PHY_ADDRESS 0x0
-
-/* PK_COUNT register. */
-#define PK_COUNT_TX_A_SHF 24
-#define PK_COUNT_TX_A_MSK (0xff << PK_COUNT_TX_A_SHF)
-#define PK_COUNT_TX_B_SHF 16
-#define PK_COUNT_TX_B_MSK (0xff << PK_COUNT_TX_B_SHF)
-#define PK_COUNT_RX_A_SHF 8
-#define PK_COUNT_RX_A_MSK (0xff << PK_COUNT_RX_A_SHF)
-#define PK_COUNT_RX_B_SHF 0
-#define PK_COUNT_RX_B_MSK (0xff << PK_COUNT_RX_B_SHF)
-
-/* OK2USE register. */
-#define OK2USE_TX_A 0x8
-#define OK2USE_TX_B 0x4
-#define OK2USE_RX_A 0x2
-#define OK2USE_RX_B 0x1
-
-/* LAN DMA CONTROL register. */
-#define DMA_CTL_BLK_INT 0x80000000
-#define DMA_CTL_MAX_XFER_SHF 18
-#define DMA_CTL_MAX_XFER_MSK (0x3 << LAN_DMA_CTL_MAX_XFER_SHF)
-#define DMA_CTL_ENDIAN_SHF 16
-#define DMA_CTL_ENDIAN_MSK (0x3 << LAN_DMA_CTL_ENDIAN_SHF)
-#define DMA_CTL_RX_INT_COUNT_SHF 8
-#define DMA_CTL_RX_INT_COUNT_MSK (0xff << LAN_DMA_CTL_RX_INT_COUNT_SHF)
-#define DMA_CTL_EN_TX_DMA 0x00000080
-#define DMA_CTL_EN_RX_DMA 0x00000040
-#define DMA_CTL_RX_INT_BUFFUL_EN 0x00000020
-#define DMA_CTL_RX_INT_TO_EN 0x00000010
-#define DMA_CTL_RX_INT_EN 0x00000008
-#define DMA_CTL_TX_INT_EN 0x00000004
-#define DMA_CTL_MAC_TX_INT_EN 0x00000002
-#define DMA_CTL_MAC_RX_INT_EN 0x00000001
-
-/* DMA STATUS register. */
-#define DMA_STATUS_BAD_ADDR_SHF 16
-#define DMA_STATUS_BAD_ADDR_MSK (0xf << DMA_STATUS_BAD_ADDR_SHF)
-#define DMA_STATUS_RX_PKTS_RECEIVED_SHF 8
-#define DMA_STATUS_RX_PKTS_RECEIVED_MSK (0xff << DMA_STATUS_RX_PKTS_RECEIVED_SHF)
-#define DMA_STATUS_TX_EN_SYNC 0x00000080
-#define DMA_STATUS_RX_BUF_A_FUL 0x00000040
-#define DMA_STATUS_RX_BUF_B_FUL 0x00000020
-#define DMA_STATUS_RX_TO_INT 0x00000010
-#define DMA_STATUS_RX_INT 0x00000008
-#define DMA_STATUS_TX_INT 0x00000004
-#define DMA_STATUS_MAC_TX_INT 0x00000002
-#define DMA_STATUS_MAC_RX_INT 0x00000001
-
-/* DMA TEST/PANIC SWITHES register. */
-#define DMA_TEST_LOOPBACK 0x01000000
-#define DMA_TEST_SW_RESET 0x00000001
-
-/* MAC CONTROL register. */
-#define MAC_CONTROL_EN_MISS_ROLL 0x00002000
-#define MAC_CONTROL_MISS_ROLL 0x00000400
-#define MAC_CONTROL_LOOP10 0x00000080
-#define MAC_CONTROL_CONN_SHF 5
-#define MAC_CONTROL_CONN_MSK (0x3 << MAC_CONTROL_CONN_SHF)
-#define MAC_CONTROL_MAC_LOOP 0x00000010
-#define MAC_CONTROL_FULL_DUP 0x00000008
-#define MAC_CONTROL_RESET 0x00000004
-#define MAC_CONTROL_HALT_IMM 0x00000002
-#define MAC_CONTROL_HALT_REQ 0x00000001
-
-/* CAM CONTROL register. */
-#define CAM_CONTROL_COMP_EN 0x00000010
-#define CAM_CONTROL_NEG_CAM 0x00000008
-#define CAM_CONTROL_BROAD_ACC 0x00000004
-#define CAM_CONTROL_GROUP_ACC 0x00000002
-#define CAM_CONTROL_STATION_ACC 0x00000001
-
-/* TRANSMIT CONTROL register. */
-#define TX_CTL_EN_COMP 0x00004000
-#define TX_CTL_EN_TX_PAR 0x00002000
-#define TX_CTL_EN_LATE_COLL 0x00001000
-#define TX_CTL_EN_EX_COLL 0x00000800
-#define TX_CTL_EN_L_CARR 0x00000400
-#define TX_CTL_EN_EX_DEFER 0x00000200
-#define TX_CTL_EN_UNDER 0x00000100
-#define TX_CTL_MII10 0x00000080
-#define TX_CTL_SD_PAUSE 0x00000040
-#define TX_CTL_NO_EX_DEF0 0x00000020
-#define TX_CTL_F_BACK 0x00000010
-#define TX_CTL_NO_CRC 0x00000008
-#define TX_CTL_NO_PAD 0x00000004
-#define TX_CTL_TX_HALT 0x00000002
-#define TX_CTL_TX_EN 0x00000001
-
-/* TRANSMIT STATUS register. */
-#define TX_STATUS_SQ_ERR 0x00010000
-#define TX_STATUS_TX_HALTED 0x00008000
-#define TX_STATUS_COMP 0x00004000
-#define TX_STATUS_TX_PAR 0x00002000
-#define TX_STATUS_LATE_COLL 0x00001000
-#define TX_STATUS_TX10_STAT 0x00000800
-#define TX_STATUS_L_CARR 0x00000400
-#define TX_STATUS_EX_DEFER 0x00000200
-#define TX_STATUS_UNDER 0x00000100
-#define TX_STATUS_IN_TX 0x00000080
-#define TX_STATUS_PAUSED 0x00000040
-#define TX_STATUS_TX_DEFERRED 0x00000020
-#define TX_STATUS_EX_COLL 0x00000010
-#define TX_STATUS_TX_COLL_SHF 0
-#define TX_STATUS_TX_COLL_MSK (0xf << TX_STATUS_TX_COLL_SHF)
-
-/* RECEIVE CONTROL register. */
-#define RX_CTL_EN_GOOD 0x00004000
-#define RX_CTL_EN_RX_PAR 0x00002000
-#define RX_CTL_EN_LONG_ERR 0x00000800
-#define RX_CTL_EN_OVER 0x00000400
-#define RX_CTL_EN_CRC_ERR 0x00000200
-#define RX_CTL_EN_ALIGN 0x00000100
-#define RX_CTL_IGNORE_CRC 0x00000040
-#define RX_CTL_PASS_CTL 0x00000020
-#define RX_CTL_STRIP_CRC 0x00000010
-#define RX_CTL_SHORT_EN 0x00000008
-#define RX_CTL_LONG_EN 0x00000004
-#define RX_CTL_RX_HALT 0x00000002
-#define RX_CTL_RX_EN 0x00000001
-
-/* RECEIVE STATUS register. */
-#define RX_STATUS_RX_HALTED 0x00008000
-#define RX_STATUS_GOOD 0x00004000
-#define RX_STATUS_RX_PAR 0x00002000
-#define RX_STATUS_LONG_ERR 0x00000800
-#define RX_STATUS_OVERFLOW 0x00000400
-#define RX_STATUS_CRC_ERR 0x00000200
-#define RX_STATUS_ALIGN_ERR 0x00000100
-#define RX_STATUS_RX10_STAT 0x00000080
-#define RX_STATUS_INT_RX 0x00000040
-#define RX_STATUS_CTL_RECD 0x00000020
-
-/* MD_CA register. */
-#define MD_CA_PRE_SUP 0x00001000
-#define MD_CA_BUSY 0x00000800
-#define MD_CA_WR 0x00000400
-#define MD_CA_PHY_SHF 5
-#define MD_CA_PHY_MSK (0x1f << MD_CA_PHY_SHF)
-#define MD_CA_ADDR_SHF 0
-#define MD_CA_ADDR_MSK (0x1f << MD_CA_ADDR_SHF)
-
-/* Tx Status/Control. */
-#define TX_STAT_CTL_OWNER_SHF 30
-#define TX_STAT_CTL_OWNER_MSK (0x3 << TX_STAT_CTL_OWNER_SHF)
-#define TX_STAT_CTL_FRAME_SHF 27
-#define TX_STAT_CTL_FRAME_MSK (0x7 << TX_STAT_CTL_FRAME_SHF)
-#define TX_STAT_CTL_STATUS_SHF 11
-#define TX_STAT_CTL_STATUS_MSK (0x1ffff << TX_STAT_CTL_STATUS_SHF)
-#define TX_STAT_CTL_LENGTH_SHF 0
-#define TX_STAT_CTL_LENGTH_MSK (0x7ff << TX_STAT_CTL_LENGTH_SHF)
-
-#define TX_STAT_CTL_ERROR_MSK ((TX_STATUS_SQ_ERR | \
- TX_STATUS_TX_HALTED | \
- TX_STATUS_TX_PAR | \
- TX_STATUS_LATE_COLL | \
- TX_STATUS_L_CARR | \
- TX_STATUS_EX_DEFER | \
- TX_STATUS_UNDER | \
- TX_STATUS_PAUSED | \
- TX_STATUS_TX_DEFERRED | \
- TX_STATUS_EX_COLL | \
- TX_STATUS_TX_COLL_MSK) \
- << TX_STAT_CTL_STATUS_SHF)
-#define TX_STAT_CTL_INT_AFTER_TX 0x4
-
-/* Rx Status/Control. */
-#define RX_STAT_CTL_OWNER_SHF 30
-#define RX_STAT_CTL_OWNER_MSK (0x3 << RX_STAT_CTL_OWNER_SHF)
-#define RX_STAT_CTL_STATUS_SHF 11
-#define RX_STAT_CTL_STATUS_MSK (0xffff << RX_STAT_CTL_STATUS_SHF)
-#define RX_STAT_CTL_LENGTH_SHF 0
-#define RX_STAT_CTL_LENGTH_MSK (0x7ff << RX_STAT_CTL_LENGTH_SHF)
-
-
-
-/* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
-#define SAA9730_LAN_REGS_ADDR 0x20400
-#define SAA9730_LAN_REGS_SIZE 0x00400
-
-struct lan_saa9730_regmap {
- volatile unsigned int TxBuffA; /* 0x20400 */
- volatile unsigned int TxBuffB; /* 0x20404 */
- volatile unsigned int RxBuffA; /* 0x20408 */
- volatile unsigned int RxBuffB; /* 0x2040c */
- volatile unsigned int PacketCount; /* 0x20410 */
- volatile unsigned int Ok2Use; /* 0x20414 */
- volatile unsigned int LanDmaCtl; /* 0x20418 */
- volatile unsigned int Timeout; /* 0x2041c */
- volatile unsigned int DmaStatus; /* 0x20420 */
- volatile unsigned int DmaTest; /* 0x20424 */
- volatile unsigned char filler20428[0x20430 - 0x20428];
- volatile unsigned int PauseCount; /* 0x20430 */
- volatile unsigned int RemotePauseCount; /* 0x20434 */
- volatile unsigned char filler20438[0x20440 - 0x20438];
- volatile unsigned int MacCtl; /* 0x20440 */
- volatile unsigned int CamCtl; /* 0x20444 */
- volatile unsigned int TxCtl; /* 0x20448 */
- volatile unsigned int TxStatus; /* 0x2044c */
- volatile unsigned int RxCtl; /* 0x20450 */
- volatile unsigned int RxStatus; /* 0x20454 */
- volatile unsigned int StationMgmtData; /* 0x20458 */
- volatile unsigned int StationMgmtCtl; /* 0x2045c */
- volatile unsigned int CamAddress; /* 0x20460 */
- volatile unsigned int CamData; /* 0x20464 */
- volatile unsigned int CamEnable; /* 0x20468 */
- volatile unsigned char filler2046c[0x20500 - 0x2046c];
- volatile unsigned int DebugPCIMasterAddr; /* 0x20500 */
- volatile unsigned int DebugLanTxStateMachine; /* 0x20504 */
- volatile unsigned int DebugLanRxStateMachine; /* 0x20508 */
- volatile unsigned int DebugLanTxFifoPointers; /* 0x2050c */
- volatile unsigned int DebugLanRxFifoPointers; /* 0x20510 */
- volatile unsigned int DebugLanCtlStateMachine; /* 0x20514 */
-};
-typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
-
-
-/* EVM interrupt control registers. */
-#define EVM_LAN_INT 0x00010000
-#define EVM_MASTER_EN 0x00000001
-
-/* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
-#define SAA9730_EVM_REGS_ADDR 0x02000
-#define SAA9730_EVM_REGS_SIZE 0x00400
-
-struct evm_saa9730_regmap {
- volatile unsigned int InterruptStatus1; /* 0x2000 */
- volatile unsigned int InterruptEnable1; /* 0x2004 */
- volatile unsigned int InterruptMonitor1; /* 0x2008 */
- volatile unsigned int Counter; /* 0x200c */
- volatile unsigned int CounterThreshold; /* 0x2010 */
- volatile unsigned int CounterControl; /* 0x2014 */
- volatile unsigned int GpioControl1; /* 0x2018 */
- volatile unsigned int InterruptStatus2; /* 0x201c */
- volatile unsigned int InterruptEnable2; /* 0x2020 */
- volatile unsigned int InterruptMonitor2; /* 0x2024 */
- volatile unsigned int GpioControl2; /* 0x2028 */
- volatile unsigned int InterruptBlock1; /* 0x202c */
- volatile unsigned int InterruptBlock2; /* 0x2030 */
-};
-typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
-
-
-struct lan_saa9730_private {
- /*
- * Rx/Tx packet buffers.
- * The Rx and Tx packets must be PACKET_SIZE aligned.
- */
- void *buffer_start;
- unsigned int buffer_size;
-
- /*
- * DMA address of beginning of this object, returned
- * by pci_alloc_consistent().
- */
- dma_addr_t dma_addr;
-
- /* Pointer to the associated pci device structure */
- struct pci_dev *pci_dev;
-
- /* Pointer for the SAA9730 LAN controller register set. */
- t_lan_saa9730_regmap *lan_saa9730_regs;
-
- /* Pointer to the SAA9730 EVM register. */
- t_evm_saa9730_regmap *evm_saa9730_regs;
-
- /* Rcv buffer Index. */
- unsigned char NextRcvPacketIndex;
- /* Next buffer index. */
- unsigned char NextRcvBufferIndex;
-
- /* Index of next packet to use in that buffer. */
- unsigned char NextTxmPacketIndex;
- /* Next buffer index. */
- unsigned char NextTxmBufferIndex;
-
- /* Index of first pending packet ready to send. */
- unsigned char PendingTxmPacketIndex;
- /* Pending buffer index. */
- unsigned char PendingTxmBufferIndex;
-
- unsigned char DmaRcvPackets;
- unsigned char DmaTxmPackets;
-
- void *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
- void *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
- unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
-
- unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
-
- spinlock_t lock;
-};
-
-#endif /* _SAA9730_H */
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 33bb18f810f..fe41e4ec21e 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -1064,7 +1064,7 @@ static void sbmac_netpoll(struct net_device *netdev)
((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0),
sc->sbm_imr);
#else
- __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+ __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
(M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr);
#endif
}
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index dbad95c295b..3be13b592b4 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -4,6 +4,8 @@ config SFC
select MII
select INET_LRO
select CRC32
+ select I2C
+ select I2C_ALGOBIT
help
This driver supports 10-gigabit Ethernet cards based on
the Solarflare Communications Solarstorm SFC4000 controller.
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index 1d2daeec7ac..c8f5704c8fb 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -1,5 +1,5 @@
sfc-y += efx.o falcon.o tx.o rx.o falcon_xmac.o \
- i2c-direct.o selftest.o ethtool.o xfp_phy.o \
+ selftest.o ethtool.o xfp_phy.o \
mdio_10g.o tenxpress.o boards.o sfe4001.o
obj-$(CONFIG_SFC) += sfc.o
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 7fc0328dc05..d3d3dd0a117 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -109,7 +109,7 @@ static struct efx_board_data board_data[] = {
[EFX_BOARD_INVALID] =
{NULL, NULL, dummy_init},
[EFX_BOARD_SFE4001] =
- {"SFE4001", "10GBASE-T adapter", sfe4001_poweron},
+ {"SFE4001", "10GBASE-T adapter", sfe4001_init},
[EFX_BOARD_SFE4002] =
{"SFE4002", "XFP adapter", sfe4002_init},
};
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index 695764dc2e6..e5e844359ce 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -20,8 +20,7 @@ enum efx_board_type {
};
extern int efx_set_board_info(struct efx_nic *efx, u16 revision_info);
-extern int sfe4001_poweron(struct efx_nic *efx);
-extern void sfe4001_poweroff(struct efx_nic *efx);
+extern int sfe4001_init(struct efx_nic *efx);
/* Are we putting the PHY into flash config mode */
extern unsigned int sfe4001_phy_flash_cfg;
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 449760642e3..7b2015f9e46 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -696,8 +696,8 @@ static void efx_stop_port(struct efx_nic *efx)
/* Serialise against efx_set_multicast_list() */
if (efx_dev_registered(efx)) {
- netif_tx_lock_bh(efx->net_dev);
- netif_tx_unlock_bh(efx->net_dev);
+ netif_addr_lock_bh(efx->net_dev);
+ netif_addr_unlock_bh(efx->net_dev);
}
}
@@ -1815,6 +1815,7 @@ static struct efx_board efx_dummy_board_info = {
.init = efx_nic_dummy_op_int,
.init_leds = efx_port_dummy_op_int,
.set_fault_led = efx_port_dummy_op_blink,
+ .fini = efx_port_dummy_op_void,
};
/**************************************************************************
@@ -1941,6 +1942,7 @@ static void efx_pci_remove_main(struct efx_nic *efx)
efx_fini_port(efx);
/* Shutdown the board, then the NIC and board state */
+ efx->board_info.fini(efx);
falcon_fini_interrupt(efx);
efx_fini_napi(efx);
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 790db89db34..630406e142e 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -13,6 +13,8 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/seq_file.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
#include "net_driver.h"
#include "bitfield.h"
#include "efx.h"
@@ -36,10 +38,12 @@
* struct falcon_nic_data - Falcon NIC state
* @next_buffer_table: First available buffer table id
* @pci_dev2: The secondary PCI device if present
+ * @i2c_data: Operations and state for I2C bit-bashing algorithm
*/
struct falcon_nic_data {
unsigned next_buffer_table;
struct pci_dev *pci_dev2;
+ struct i2c_algo_bit_data i2c_data;
};
/**************************************************************************
@@ -175,39 +179,57 @@ static inline int falcon_event_present(efx_qword_t *event)
*
**************************************************************************
*/
-static void falcon_setsdascl(struct efx_i2c_interface *i2c)
+static void falcon_setsda(void *data, int state)
{
+ struct efx_nic *efx = (struct efx_nic *)data;
efx_oword_t reg;
- falcon_read(i2c->efx, &reg, GPIO_CTL_REG_KER);
- EFX_SET_OWORD_FIELD(reg, GPIO0_OEN, (i2c->scl ? 0 : 1));
- EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, (i2c->sda ? 0 : 1));
- falcon_write(i2c->efx, &reg, GPIO_CTL_REG_KER);
+ falcon_read(efx, &reg, GPIO_CTL_REG_KER);
+ EFX_SET_OWORD_FIELD(reg, GPIO3_OEN, !state);
+ falcon_write(efx, &reg, GPIO_CTL_REG_KER);
}
-static int falcon_getsda(struct efx_i2c_interface *i2c)
+static void falcon_setscl(void *data, int state)
{
+ struct efx_nic *efx = (struct efx_nic *)data;
efx_oword_t reg;
- falcon_read(i2c->efx, &reg, GPIO_CTL_REG_KER);
+ falcon_read(efx, &reg, GPIO_CTL_REG_KER);
+ EFX_SET_OWORD_FIELD(reg, GPIO0_OEN, !state);
+ falcon_write(efx, &reg, GPIO_CTL_REG_KER);
+}
+
+static int falcon_getsda(void *data)
+{
+ struct efx_nic *efx = (struct efx_nic *)data;
+ efx_oword_t reg;
+
+ falcon_read(efx, &reg, GPIO_CTL_REG_KER);
return EFX_OWORD_FIELD(reg, GPIO3_IN);
}
-static int falcon_getscl(struct efx_i2c_interface *i2c)
+static int falcon_getscl(void *data)
{
+ struct efx_nic *efx = (struct efx_nic *)data;
efx_oword_t reg;
- falcon_read(i2c->efx, &reg, GPIO_CTL_REG_KER);
- return EFX_DWORD_FIELD(reg, GPIO0_IN);
+ falcon_read(efx, &reg, GPIO_CTL_REG_KER);
+ return EFX_OWORD_FIELD(reg, GPIO0_IN);
}
-static struct efx_i2c_bit_operations falcon_i2c_bit_operations = {
- .setsda = falcon_setsdascl,
- .setscl = falcon_setsdascl,
+static struct i2c_algo_bit_data falcon_i2c_bit_operations = {
+ .setsda = falcon_setsda,
+ .setscl = falcon_setscl,
.getsda = falcon_getsda,
.getscl = falcon_getscl,
- .udelay = 100,
- .mdelay = 10,
+ .udelay = 5,
+ /*
+ * This is the number of system clock ticks after which
+ * i2c-algo-bit gives up waiting for SCL to become high.
+ * It must be at least 2 since the first tick can happen
+ * immediately after it starts waiting.
+ */
+ .timeout = 2,
};
/**************************************************************************
@@ -2405,12 +2427,6 @@ int falcon_probe_nic(struct efx_nic *efx)
struct falcon_nic_data *nic_data;
int rc;
- /* Initialise I2C interface state */
- efx->i2c.efx = efx;
- efx->i2c.op = &falcon_i2c_bit_operations;
- efx->i2c.sda = 1;
- efx->i2c.scl = 1;
-
/* Allocate storage for hardware specific data */
nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
efx->nic_data = nic_data;
@@ -2461,6 +2477,18 @@ int falcon_probe_nic(struct efx_nic *efx)
if (rc)
goto fail5;
+ /* Initialise I2C adapter */
+ efx->i2c_adap.owner = THIS_MODULE;
+ efx->i2c_adap.class = I2C_CLASS_HWMON;
+ nic_data->i2c_data = falcon_i2c_bit_operations;
+ nic_data->i2c_data.data = efx;
+ efx->i2c_adap.algo_data = &nic_data->i2c_data;
+ efx->i2c_adap.dev.parent = &efx->pci_dev->dev;
+ strcpy(efx->i2c_adap.name, "SFC4000 GPIO");
+ rc = i2c_bit_add_bus(&efx->i2c_adap);
+ if (rc)
+ goto fail5;
+
return 0;
fail5:
@@ -2635,6 +2663,10 @@ int falcon_init_nic(struct efx_nic *efx)
void falcon_remove_nic(struct efx_nic *efx)
{
struct falcon_nic_data *nic_data = efx->nic_data;
+ int rc;
+
+ rc = i2c_del_adapter(&efx->i2c_adap);
+ BUG_ON(rc);
falcon_free_buffer(efx, &efx->irq_status);
diff --git a/drivers/net/sfc/i2c-direct.c b/drivers/net/sfc/i2c-direct.c
deleted file mode 100644
index b6c62d0ed9c..00000000000
--- a/drivers/net/sfc/i2c-direct.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005 Fen Systems Ltd.
- * Copyright 2006-2008 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#include <linux/delay.h>
-#include "net_driver.h"
-#include "i2c-direct.h"
-
-/*
- * I2C data (SDA) and clock (SCL) line read/writes with appropriate
- * delays.
- */
-
-static inline void setsda(struct efx_i2c_interface *i2c, int state)
-{
- udelay(i2c->op->udelay);
- i2c->sda = state;
- i2c->op->setsda(i2c);
- udelay(i2c->op->udelay);
-}
-
-static inline void setscl(struct efx_i2c_interface *i2c, int state)
-{
- udelay(i2c->op->udelay);
- i2c->scl = state;
- i2c->op->setscl(i2c);
- udelay(i2c->op->udelay);
-}
-
-static inline int getsda(struct efx_i2c_interface *i2c)
-{
- int sda;
-
- udelay(i2c->op->udelay);
- sda = i2c->op->getsda(i2c);
- udelay(i2c->op->udelay);
- return sda;
-}
-
-static inline int getscl(struct efx_i2c_interface *i2c)
-{
- int scl;
-
- udelay(i2c->op->udelay);
- scl = i2c->op->getscl(i2c);
- udelay(i2c->op->udelay);
- return scl;
-}
-
-/*
- * I2C low-level protocol operations
- *
- */
-
-static inline void i2c_release(struct efx_i2c_interface *i2c)
-{
- EFX_WARN_ON_PARANOID(!i2c->scl);
- EFX_WARN_ON_PARANOID(!i2c->sda);
- /* Devices may time out if operations do not end */
- setscl(i2c, 1);
- setsda(i2c, 1);
- EFX_BUG_ON_PARANOID(getsda(i2c) != 1);
- EFX_BUG_ON_PARANOID(getscl(i2c) != 1);
-}
-
-static inline void i2c_start(struct efx_i2c_interface *i2c)
-{
- /* We may be restarting immediately after a {send,recv}_bit,
- * so SCL will not necessarily already be high.
- */
- EFX_WARN_ON_PARANOID(!i2c->sda);
- setscl(i2c, 1);
- setsda(i2c, 0);
- setscl(i2c, 0);
- setsda(i2c, 1);
-}
-
-static inline void i2c_send_bit(struct efx_i2c_interface *i2c, int bit)
-{
- EFX_WARN_ON_PARANOID(i2c->scl != 0);
- setsda(i2c, bit);
- setscl(i2c, 1);
- setscl(i2c, 0);
- setsda(i2c, 1);
-}
-
-static inline int i2c_recv_bit(struct efx_i2c_interface *i2c)
-{
- int bit;
-
- EFX_WARN_ON_PARANOID(i2c->scl != 0);
- EFX_WARN_ON_PARANOID(!i2c->sda);
- setscl(i2c, 1);
- bit = getsda(i2c);
- setscl(i2c, 0);
- return bit;
-}
-
-static inline void i2c_stop(struct efx_i2c_interface *i2c)
-{
- EFX_WARN_ON_PARANOID(i2c->scl != 0);
- setsda(i2c, 0);
- setscl(i2c, 1);
- setsda(i2c, 1);
-}
-
-/*
- * I2C mid-level protocol operations
- *
- */
-
-/* Sends a byte via the I2C bus and checks for an acknowledgement from
- * the slave device.
- */
-static int i2c_send_byte(struct efx_i2c_interface *i2c, u8 byte)
-{
- int i;
-
- /* Send byte */
- for (i = 0; i < 8; i++) {
- i2c_send_bit(i2c, !!(byte & 0x80));
- byte <<= 1;
- }
-
- /* Check for acknowledgement from slave */
- return (i2c_recv_bit(i2c) == 0 ? 0 : -EIO);
-}
-
-/* Receives a byte via the I2C bus and sends ACK/NACK to the slave device. */
-static u8 i2c_recv_byte(struct efx_i2c_interface *i2c, int ack)
-{
- u8 value = 0;
- int i;
-
- /* Receive byte */
- for (i = 0; i < 8; i++)
- value = (value << 1) | i2c_recv_bit(i2c);
-
- /* Send ACK/NACK */
- i2c_send_bit(i2c, (ack ? 0 : 1));
-
- return value;
-}
-
-/* Calculate command byte for a read operation */
-static inline u8 i2c_read_cmd(u8 device_id)
-{
- return ((device_id << 1) | 1);
-}
-
-/* Calculate command byte for a write operation */
-static inline u8 i2c_write_cmd(u8 device_id)
-{
- return ((device_id << 1) | 0);
-}
-
-int efx_i2c_check_presence(struct efx_i2c_interface *i2c, u8 device_id)
-{
- int rc;
-
- /* If someone is driving the bus low we just give up. */
- if (getsda(i2c) == 0 || getscl(i2c) == 0) {
- EFX_ERR(i2c->efx, "%s someone is holding the I2C bus low."
- " Giving up.\n", __func__);
- return -EFAULT;
- }
-
- /* Pretend to initiate a device write */
- i2c_start(i2c);
- rc = i2c_send_byte(i2c, i2c_write_cmd(device_id));
- if (rc)
- goto out;
-
- out:
- i2c_stop(i2c);
- i2c_release(i2c);
-
- return rc;
-}
-
-/* This performs a fast read of one or more consecutive bytes from an
- * I2C device. Not all devices support consecutive reads of more than
- * one byte; for these devices use efx_i2c_read() instead.
- */
-int efx_i2c_fast_read(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, u8 *data, unsigned int len)
-{
- int i;
- int rc;
-
- EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
- EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
- EFX_WARN_ON_PARANOID(data == NULL);
- EFX_WARN_ON_PARANOID(len < 1);
-
- /* Select device and starting offset */
- i2c_start(i2c);
- rc = i2c_send_byte(i2c, i2c_write_cmd(device_id));
- if (rc)
- goto out;
- rc = i2c_send_byte(i2c, offset);
- if (rc)
- goto out;
-
- /* Read data from device */
- i2c_start(i2c);
- rc = i2c_send_byte(i2c, i2c_read_cmd(device_id));
- if (rc)
- goto out;
- for (i = 0; i < (len - 1); i++)
- /* Read and acknowledge all but the last byte */
- data[i] = i2c_recv_byte(i2c, 1);
- /* Read last byte with no acknowledgement */
- data[i] = i2c_recv_byte(i2c, 0);
-
- out:
- i2c_stop(i2c);
- i2c_release(i2c);
-
- return rc;
-}
-
-/* This performs a fast write of one or more consecutive bytes to an
- * I2C device. Not all devices support consecutive writes of more
- * than one byte; for these devices use efx_i2c_write() instead.
- */
-int efx_i2c_fast_write(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset,
- const u8 *data, unsigned int len)
-{
- int i;
- int rc;
-
- EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
- EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
- EFX_WARN_ON_PARANOID(len < 1);
-
- /* Select device and starting offset */
- i2c_start(i2c);
- rc = i2c_send_byte(i2c, i2c_write_cmd(device_id));
- if (rc)
- goto out;
- rc = i2c_send_byte(i2c, offset);
- if (rc)
- goto out;
-
- /* Write data to device */
- for (i = 0; i < len; i++) {
- rc = i2c_send_byte(i2c, data[i]);
- if (rc)
- goto out;
- }
-
- out:
- i2c_stop(i2c);
- i2c_release(i2c);
-
- return rc;
-}
-
-/* I2C byte-by-byte read */
-int efx_i2c_read(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, u8 *data, unsigned int len)
-{
- int rc;
-
- /* i2c_fast_read with length 1 is a single byte read */
- for (; len > 0; offset++, data++, len--) {
- rc = efx_i2c_fast_read(i2c, device_id, offset, data, 1);
- if (rc)
- return rc;
- }
-
- return 0;
-}
-
-/* I2C byte-by-byte write */
-int efx_i2c_write(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, const u8 *data, unsigned int len)
-{
- int rc;
-
- /* i2c_fast_write with length 1 is a single byte write */
- for (; len > 0; offset++, data++, len--) {
- rc = efx_i2c_fast_write(i2c, device_id, offset, data, 1);
- if (rc)
- return rc;
- mdelay(i2c->op->mdelay);
- }
-
- return 0;
-}
-
-
-/* This is just a slightly neater wrapper round efx_i2c_fast_write
- * in the case where the target doesn't take an offset
- */
-int efx_i2c_send_bytes(struct efx_i2c_interface *i2c,
- u8 device_id, const u8 *data, unsigned int len)
-{
- return efx_i2c_fast_write(i2c, device_id, data[0], data + 1, len - 1);
-}
-
-/* I2C receiving of bytes - does not send an offset byte */
-int efx_i2c_recv_bytes(struct efx_i2c_interface *i2c, u8 device_id,
- u8 *bytes, unsigned int len)
-{
- int i;
- int rc;
-
- EFX_WARN_ON_PARANOID(getsda(i2c) != 1);
- EFX_WARN_ON_PARANOID(getscl(i2c) != 1);
- EFX_WARN_ON_PARANOID(len < 1);
-
- /* Select device */
- i2c_start(i2c);
-
- /* Read data from device */
- rc = i2c_send_byte(i2c, i2c_read_cmd(device_id));
- if (rc)
- goto out;
-
- for (i = 0; i < (len - 1); i++)
- /* Read and acknowledge all but the last byte */
- bytes[i] = i2c_recv_byte(i2c, 1);
- /* Read last byte with no acknowledgement */
- bytes[i] = i2c_recv_byte(i2c, 0);
-
- out:
- i2c_stop(i2c);
- i2c_release(i2c);
-
- return rc;
-}
-
-/* SMBus and some I2C devices will time out if the I2C clock is
- * held low for too long. This is most likely to happen in virtualised
- * systems (when the entire domain is descheduled) but could in
- * principle happen due to preemption on any busy system (and given the
- * potential length of an I2C operation turning preemption off is not
- * a sensible option). The following functions deal with the failure by
- * retrying up to a fixed number of times.
- */
-
-#define I2C_MAX_RETRIES (10)
-
-/* The timeout problem will result in -EIO. If the wrapped function
- * returns any other error, pass this up and do not retry. */
-#define RETRY_WRAPPER(_f) \
- int retries = I2C_MAX_RETRIES; \
- int rc; \
- while (retries) { \
- rc = _f; \
- if (rc != -EIO) \
- return rc; \
- retries--; \
- } \
- return rc; \
-
-int efx_i2c_check_presence_retry(struct efx_i2c_interface *i2c, u8 device_id)
-{
- RETRY_WRAPPER(efx_i2c_check_presence(i2c, device_id))
-}
-
-int efx_i2c_read_retry(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, u8 *data, unsigned int len)
-{
- RETRY_WRAPPER(efx_i2c_read(i2c, device_id, offset, data, len))
-}
-
-int efx_i2c_write_retry(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, const u8 *data, unsigned int len)
-{
- RETRY_WRAPPER(efx_i2c_write(i2c, device_id, offset, data, len))
-}
diff --git a/drivers/net/sfc/i2c-direct.h b/drivers/net/sfc/i2c-direct.h
deleted file mode 100644
index 291e561071f..00000000000
--- a/drivers/net/sfc/i2c-direct.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005 Fen Systems Ltd.
- * Copyright 2006 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#ifndef EFX_I2C_DIRECT_H
-#define EFX_I2C_DIRECT_H
-
-#include "net_driver.h"
-
-/*
- * Direct control of an I2C bus
- */
-
-struct efx_i2c_interface;
-
-/**
- * struct efx_i2c_bit_operations - I2C bus direct control methods
- *
- * I2C bus direct control methods.
- *
- * @setsda: Set state of SDA line
- * @setscl: Set state of SCL line
- * @getsda: Get state of SDA line
- * @getscl: Get state of SCL line
- * @udelay: Delay between each bit operation
- * @mdelay: Delay between each byte write
- */
-struct efx_i2c_bit_operations {
- void (*setsda) (struct efx_i2c_interface *i2c);
- void (*setscl) (struct efx_i2c_interface *i2c);
- int (*getsda) (struct efx_i2c_interface *i2c);
- int (*getscl) (struct efx_i2c_interface *i2c);
- unsigned int udelay;
- unsigned int mdelay;
-};
-
-/**
- * struct efx_i2c_interface - an I2C interface
- *
- * An I2C interface.
- *
- * @efx: Attached Efx NIC
- * @op: I2C bus control methods
- * @sda: Current output state of SDA line
- * @scl: Current output state of SCL line
- */
-struct efx_i2c_interface {
- struct efx_nic *efx;
- struct efx_i2c_bit_operations *op;
- unsigned int sda:1;
- unsigned int scl:1;
-};
-
-extern int efx_i2c_check_presence(struct efx_i2c_interface *i2c, u8 device_id);
-extern int efx_i2c_fast_read(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset,
- u8 *data, unsigned int len);
-extern int efx_i2c_fast_write(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset,
- const u8 *data, unsigned int len);
-extern int efx_i2c_read(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, u8 *data, unsigned int len);
-extern int efx_i2c_write(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset,
- const u8 *data, unsigned int len);
-
-extern int efx_i2c_send_bytes(struct efx_i2c_interface *i2c, u8 device_id,
- const u8 *bytes, unsigned int len);
-
-extern int efx_i2c_recv_bytes(struct efx_i2c_interface *i2c, u8 device_id,
- u8 *bytes, unsigned int len);
-
-
-/* Versions of the API that retry on failure. */
-extern int efx_i2c_check_presence_retry(struct efx_i2c_interface *i2c,
- u8 device_id);
-
-extern int efx_i2c_read_retry(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset, u8 *data, unsigned int len);
-
-extern int efx_i2c_write_retry(struct efx_i2c_interface *i2c,
- u8 device_id, u8 offset,
- const u8 *data, unsigned int len);
-
-#endif /* EFX_I2C_DIRECT_H */
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5e20e7551da..d803b86c647 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -26,10 +26,10 @@
#include <linux/highmem.h>
#include <linux/workqueue.h>
#include <linux/inet_lro.h>
+#include <linux/i2c.h>
#include "enum.h"
#include "bitfield.h"
-#include "i2c-direct.h"
#define EFX_MAX_LRO_DESCRIPTORS 8
#define EFX_MAX_LRO_AGGR MAX_SKB_FRAGS
@@ -418,7 +418,10 @@ struct efx_blinker {
* @init_leds: Sets up board LEDs
* @set_fault_led: Turns the fault LED on or off
* @blink: Starts/stops blinking
+ * @fini: Cleanup function
* @blinker: used to blink LEDs in software
+ * @hwmon_client: I2C client for hardware monitor
+ * @ioexp_client: I2C client for power/port control
*/
struct efx_board {
int type;
@@ -431,7 +434,9 @@ struct efx_board {
int (*init_leds)(struct efx_nic *efx);
void (*set_fault_led) (struct efx_nic *efx, int state);
void (*blink) (struct efx_nic *efx, int start);
+ void (*fini) (struct efx_nic *nic);
struct efx_blinker blinker;
+ struct i2c_client *hwmon_client, *ioexp_client;
};
#define STRING_TABLE_LOOKUP(val, member) \
@@ -618,7 +623,7 @@ union efx_multicast_hash {
* @membase: Memory BAR value
* @biu_lock: BIU (bus interface unit) lock
* @interrupt_mode: Interrupt mode
- * @i2c: I2C interface
+ * @i2c_adap: I2C adapter
* @board_info: Board-level information
* @state: Device state flag. Serialised by the rtnl_lock.
* @reset_pending: Pending reset method (normally RESET_TYPE_NONE)
@@ -686,7 +691,7 @@ struct efx_nic {
spinlock_t biu_lock;
enum efx_int_mode interrupt_mode;
- struct efx_i2c_interface i2c;
+ struct i2c_adapter i2c_adap;
struct efx_board board_info;
enum nic_state state;
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index 66a0d1442ab..b2784952399 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -106,28 +106,27 @@
static const u8 xgphy_max_temperature = 90;
-void sfe4001_poweroff(struct efx_nic *efx)
+static void sfe4001_poweroff(struct efx_nic *efx)
{
- struct efx_i2c_interface *i2c = &efx->i2c;
+ struct i2c_client *ioexp_client = efx->board_info.ioexp_client;
+ struct i2c_client *hwmon_client = efx->board_info.hwmon_client;
- u8 cfg, out, in;
+ /* Turn off all power rails and disable outputs */
+ i2c_smbus_write_byte_data(ioexp_client, P0_OUT, 0xff);
+ i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG, 0xff);
+ i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff);
- EFX_INFO(efx, "%s\n", __func__);
-
- /* Turn off all power rails */
- out = 0xff;
- efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
-
- /* Disable port 1 outputs on IO expander */
- cfg = 0xff;
- efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1);
+ /* Clear any over-temperature alert */
+ i2c_smbus_read_byte_data(hwmon_client, RSL);
+}
- /* Disable port 0 outputs on IO expander */
- cfg = 0xff;
- efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1);
+static void sfe4001_fini(struct efx_nic *efx)
+{
+ EFX_INFO(efx, "%s\n", __func__);
- /* Clear any over-temperature alert */
- efx_i2c_read(i2c, MAX6647, RSL, &in, 1);
+ sfe4001_poweroff(efx);
+ i2c_unregister_device(efx->board_info.ioexp_client);
+ i2c_unregister_device(efx->board_info.hwmon_client);
}
/* The P0_EN_3V3X line on SFE4001 boards (from A2 onward) is connected
@@ -143,14 +142,26 @@ MODULE_PARM_DESC(phy_flash_cfg,
* be turned on before the PHY can be used.
* Context: Process context, rtnl lock held
*/
-int sfe4001_poweron(struct efx_nic *efx)
+int sfe4001_init(struct efx_nic *efx)
{
- struct efx_i2c_interface *i2c = &efx->i2c;
+ struct i2c_client *hwmon_client, *ioexp_client;
unsigned int count;
int rc;
- u8 out, in, cfg;
+ u8 out;
efx_dword_t reg;
+ hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647);
+ if (!hwmon_client)
+ return -EIO;
+ efx->board_info.hwmon_client = hwmon_client;
+
+ ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
+ if (!ioexp_client) {
+ rc = -EIO;
+ goto fail_hwmon;
+ }
+ efx->board_info.ioexp_client = ioexp_client;
+
/* 10Xpress has fixed-function LED pins, so there is no board-specific
* blink code. */
efx->board_info.blink = tenxpress_phy_blink;
@@ -166,44 +177,45 @@ int sfe4001_poweron(struct efx_nic *efx)
falcon_xmac_writel(efx, &reg, XX_PWR_RST_REG_MAC);
udelay(10);
+ efx->board_info.fini = sfe4001_fini;
+
/* Set DSP over-temperature alert threshold */
EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature);
- rc = efx_i2c_write(i2c, MAX6647, WLHO,
- &xgphy_max_temperature, 1);
+ rc = i2c_smbus_write_byte_data(hwmon_client, WLHO,
+ xgphy_max_temperature);
if (rc)
- goto fail1;
+ goto fail_ioexp;
/* Read it back and verify */
- rc = efx_i2c_read(i2c, MAX6647, RLHN, &in, 1);
- if (rc)
- goto fail1;
- if (in != xgphy_max_temperature) {
+ rc = i2c_smbus_read_byte_data(hwmon_client, RLHN);
+ if (rc < 0)
+ goto fail_ioexp;
+ if (rc != xgphy_max_temperature) {
rc = -EFAULT;
- goto fail1;
+ goto fail_ioexp;
}
/* Clear any previous over-temperature alert */
- rc = efx_i2c_read(i2c, MAX6647, RSL, &in, 1);
- if (rc)
- goto fail1;
+ rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
+ if (rc < 0)
+ goto fail_ioexp;
/* Enable port 0 and port 1 outputs on IO expander */
- cfg = 0x00;
- rc = efx_i2c_write(i2c, PCA9539, P0_CONFIG, &cfg, 1);
+ rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
if (rc)
- goto fail1;
- cfg = 0xff & ~(1 << P1_SPARE_LBN);
- rc = efx_i2c_write(i2c, PCA9539, P1_CONFIG, &cfg, 1);
+ goto fail_ioexp;
+ rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
+ 0xff & ~(1 << P1_SPARE_LBN));
if (rc)
- goto fail2;
+ goto fail_on;
/* 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 = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
+ rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
if (rc)
- goto fail3;
+ goto fail_on;
schedule_timeout_uninterruptible(HZ);
count = 0;
@@ -215,26 +227,26 @@ int sfe4001_poweron(struct efx_nic *efx)
if (sfe4001_phy_flash_cfg)
out |= 1 << P0_EN_3V3X_LBN;
- rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
+ rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
if (rc)
- goto fail3;
+ goto fail_on;
msleep(10);
/* Turn on 1V power rail */
out &= ~(1 << P0_EN_1V0X_LBN);
- rc = efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
+ rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
if (rc)
- goto fail3;
+ goto fail_on;
EFX_INFO(efx, "waiting for power (attempt %d)...\n", count);
schedule_timeout_uninterruptible(HZ);
/* Check DSP is powered */
- rc = efx_i2c_read(i2c, PCA9539, P1_IN, &in, 1);
- if (rc)
- goto fail3;
- if (in & (1 << P1_AFE_PWD_LBN))
+ rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
+ if (rc < 0)
+ goto fail_on;
+ if (rc & (1 << P1_AFE_PWD_LBN))
goto done;
/* DSP doesn't look powered in flash config mode */
@@ -244,23 +256,17 @@ int sfe4001_poweron(struct efx_nic *efx)
EFX_INFO(efx, "timed out waiting for power\n");
rc = -ETIMEDOUT;
- goto fail3;
+ goto fail_on;
done:
EFX_INFO(efx, "PHY is powered on\n");
return 0;
-fail3:
- /* Turn off all power rails */
- out = 0xff;
- efx_i2c_write(i2c, PCA9539, P0_OUT, &out, 1);
- /* Disable port 1 outputs on IO expander */
- out = 0xff;
- efx_i2c_write(i2c, PCA9539, P1_CONFIG, &out, 1);
-fail2:
- /* Disable port 0 outputs on IO expander */
- out = 0xff;
- efx_i2c_write(i2c, PCA9539, P0_CONFIG, &out, 1);
-fail1:
+fail_on:
+ sfe4001_poweroff(efx);
+fail_ioexp:
+ i2c_unregister_device(ioexp_client);
+fail_hwmon:
+ i2c_unregister_device(hwmon_client);
return rc;
}
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
new file mode 100644
index 00000000000..a4bc812aa99
--- /dev/null
+++ b/drivers/net/sh_eth.c
@@ -0,0 +1,1174 @@
+/*
+ * SuperH Ethernet device driver
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/cache.h>
+#include <linux/io.h>
+
+#include "sh_eth.h"
+
+/*
+ * Program the hardware MAC address from dev->dev_addr.
+ */
+static void update_mac_address(struct net_device *ndev)
+{
+ u32 ioaddr = ndev->base_addr;
+
+ ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
+ (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]),
+ ioaddr + MAHR);
+ ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]),
+ ioaddr + MALR);
+}
+
+/*
+ * Get MAC address from SuperH MAC address register
+ *
+ * SuperH's Ethernet device doesn't have 'ROM' to MAC address.
+ * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g).
+ * When you want use this device, you must set MAC address in bootloader.
+ *
+ */
+static void read_mac_address(struct net_device *ndev)
+{
+ u32 ioaddr = ndev->base_addr;
+
+ ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
+ ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
+ ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
+ ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
+ ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
+ ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
+}
+
+struct bb_info {
+ struct mdiobb_ctrl ctrl;
+ u32 addr;
+ u32 mmd_msk;/* MMD */
+ u32 mdo_msk;
+ u32 mdi_msk;
+ u32 mdc_msk;
+};
+
+/* PHY bit set */
+static void bb_set(u32 addr, u32 msk)
+{
+ ctrl_outl(ctrl_inl(addr) | msk, addr);
+}
+
+/* PHY bit clear */
+static void bb_clr(u32 addr, u32 msk)
+{
+ ctrl_outl((ctrl_inl(addr) & ~msk), addr);
+}
+
+/* PHY bit read */
+static int bb_read(u32 addr, u32 msk)
+{
+ return (ctrl_inl(addr) & msk) != 0;
+}
+
+/* Data I/O pin control */
+static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
+{
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+ if (bit)
+ bb_set(bitbang->addr, bitbang->mmd_msk);
+ else
+ bb_clr(bitbang->addr, bitbang->mmd_msk);
+}
+
+/* Set bit data*/
+static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
+{
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+ if (bit)
+ bb_set(bitbang->addr, bitbang->mdo_msk);
+ else
+ bb_clr(bitbang->addr, bitbang->mdo_msk);
+}
+
+/* Get bit data*/
+static int sh_get_mdio(struct mdiobb_ctrl *ctrl)
+{
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+ return bb_read(bitbang->addr, bitbang->mdi_msk);
+}
+
+/* MDC pin control */
+static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
+{
+ struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+ if (bit)
+ bb_set(bitbang->addr, bitbang->mdc_msk);
+ else
+ bb_clr(bitbang->addr, bitbang->mdc_msk);
+}
+
+/* mdio bus control struct */
+static struct mdiobb_ops bb_ops = {
+ .owner = THIS_MODULE,
+ .set_mdc = sh_mdc_ctrl,
+ .set_mdio_dir = sh_mmd_ctrl,
+ .set_mdio_data = sh_set_mdio,
+ .get_mdio_data = sh_get_mdio,
+};
+
+static void sh_eth_reset(struct net_device *ndev)
+{
+ u32 ioaddr = ndev->base_addr;
+
+ ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ mdelay(3);
+ ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+}
+
+/* free skb and descriptor buffer */
+static void sh_eth_ring_free(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int i;
+
+ /* Free Rx skb ringbuffer */
+ if (mdp->rx_skbuff) {
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ if (mdp->rx_skbuff[i])
+ dev_kfree_skb(mdp->rx_skbuff[i]);
+ }
+ }
+ kfree(mdp->rx_skbuff);
+
+ /* Free Tx skb ringbuffer */
+ if (mdp->tx_skbuff) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ if (mdp->tx_skbuff[i])
+ dev_kfree_skb(mdp->tx_skbuff[i]);
+ }
+ }
+ kfree(mdp->tx_skbuff);
+}
+
+/* format skb and descriptor buffer */
+static void sh_eth_ring_format(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int i;
+ struct sk_buff *skb;
+ struct sh_eth_rxdesc *rxdesc = NULL;
+ struct sh_eth_txdesc *txdesc = NULL;
+ int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE;
+ int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE;
+
+ mdp->cur_rx = mdp->cur_tx = 0;
+ mdp->dirty_rx = mdp->dirty_tx = 0;
+
+ memset(mdp->rx_ring, 0, rx_ringsize);
+
+ /* build Rx ring buffer */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ /* skb */
+ mdp->rx_skbuff[i] = NULL;
+ skb = dev_alloc_skb(mdp->rx_buf_sz);
+ mdp->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break;
+ skb->dev = ndev; /* Mark as being used by this device. */
+ skb_reserve(skb, RX_OFFSET);
+
+ /* RX descriptor */
+ rxdesc = &mdp->rx_ring[i];
+ rxdesc->addr = (u32)skb->data & ~0x3UL;
+ rxdesc->status = cpu_to_le32(RD_RACT | RD_RFP);
+
+ /* The size of the buffer is 16 byte boundary. */
+ rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+ }
+
+ mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
+
+ /* Mark the last entry as wrapping the ring. */
+ rxdesc->status |= cpu_to_le32(RC_RDEL);
+
+ memset(mdp->tx_ring, 0, tx_ringsize);
+
+ /* build Tx ring buffer */
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ mdp->tx_skbuff[i] = NULL;
+ txdesc = &mdp->tx_ring[i];
+ txdesc->status = cpu_to_le32(TD_TFP);
+ txdesc->buffer_length = 0;
+ }
+
+ txdesc->status |= cpu_to_le32(TD_TDLE);
+}
+
+/* Get skb and descriptor buffer */
+static int sh_eth_ring_init(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int rx_ringsize, tx_ringsize, ret = 0;
+
+ /*
+ * +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
+ * card needs room to do 8 byte alignment, +2 so we can reserve
+ * the first 2 bytes, and +16 gets room for the status word from the
+ * card.
+ */
+ mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
+ (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
+
+ /* Allocate RX and TX skb rings */
+ mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
+ GFP_KERNEL);
+ if (!mdp->rx_skbuff) {
+ printk(KERN_ERR "%s: Cannot allocate Rx skb\n", ndev->name);
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
+ GFP_KERNEL);
+ if (!mdp->tx_skbuff) {
+ printk(KERN_ERR "%s: Cannot allocate Tx skb\n", ndev->name);
+ ret = -ENOMEM;
+ goto skb_ring_free;
+ }
+
+ /* Allocate all Rx descriptors. */
+ rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
+ GFP_KERNEL);
+
+ if (!mdp->rx_ring) {
+ printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
+ ndev->name, rx_ringsize);
+ ret = -ENOMEM;
+ goto desc_ring_free;
+ }
+
+ mdp->dirty_rx = 0;
+
+ /* Allocate all Tx descriptors. */
+ tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
+ GFP_KERNEL);
+ if (!mdp->tx_ring) {
+ printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
+ ndev->name, tx_ringsize);
+ ret = -ENOMEM;
+ goto desc_ring_free;
+ }
+ return ret;
+
+desc_ring_free:
+ /* free DMA buffer */
+ dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
+
+skb_ring_free:
+ /* Free Rx and Tx skb ring buffer */
+ sh_eth_ring_free(ndev);
+
+ return ret;
+}
+
+static int sh_eth_dev_init(struct net_device *ndev)
+{
+ int ret = 0;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+ u_int32_t rx_int_var, tx_int_var;
+ u32 val;
+
+ /* Soft Reset */
+ sh_eth_reset(ndev);
+
+ ctrl_outl(RPADIR_PADS1, ioaddr + RPADIR); /* SH7712-DMA-RX-PAD2 */
+
+ /* all sh_eth int mask */
+ ctrl_outl(0, ioaddr + EESIPR);
+
+ /* FIFO size set */
+ ctrl_outl(0, ioaddr + EDMR); /* Endian change */
+
+ ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR);
+ ctrl_outl(0, ioaddr + TFTR);
+
+ ctrl_outl(0, ioaddr + RMCR);
+
+ rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
+ tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
+ ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
+
+ ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR);
+ ctrl_outl(0, ioaddr + TRIMD);
+
+ /* Descriptor format */
+ sh_eth_ring_format(ndev);
+
+ ctrl_outl((u32)mdp->rx_ring, ioaddr + RDLAR);
+ ctrl_outl((u32)mdp->tx_ring, ioaddr + TDLAR);
+
+ ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
+ ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR);
+
+ /* PAUSE Prohibition */
+ val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) |
+ ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
+
+ ctrl_outl(val, ioaddr + ECMR);
+ ctrl_outl(ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD |
+ ECSIPR_MPDIP, ioaddr + ECSR);
+ ctrl_outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP |
+ ECSIPR_ICDIP | ECSIPR_MPDIP, ioaddr + ECSIPR);
+
+ /* Set MAC address */
+ update_mac_address(ndev);
+
+ /* mask reset */
+#if defined(CONFIG_CPU_SUBTYPE_SH7710)
+ ctrl_outl(APR_AP, ioaddr + APR);
+ ctrl_outl(MPR_MP, ioaddr + MPR);
+ ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
+ ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR);
+#endif
+ /* Setting the Rx mode will start the Rx process. */
+ ctrl_outl(EDRRR_R, ioaddr + EDRRR);
+
+ netif_start_queue(ndev);
+
+ return ret;
+}
+
+/* free Tx skb function */
+static int sh_eth_txfree(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct sh_eth_txdesc *txdesc;
+ int freeNum = 0;
+ int entry = 0;
+
+ for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
+ entry = mdp->dirty_tx % TX_RING_SIZE;
+ txdesc = &mdp->tx_ring[entry];
+ if (txdesc->status & cpu_to_le32(TD_TACT))
+ break;
+ /* Free the original skb. */
+ if (mdp->tx_skbuff[entry]) {
+ dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
+ mdp->tx_skbuff[entry] = NULL;
+ freeNum++;
+ }
+ txdesc->status = cpu_to_le32(TD_TFP);
+ if (entry >= TX_RING_SIZE - 1)
+ txdesc->status |= cpu_to_le32(TD_TDLE);
+
+ mdp->stats.tx_packets++;
+ mdp->stats.tx_bytes += txdesc->buffer_length;
+ }
+ return freeNum;
+}
+
+/* Packet receive function */
+static int sh_eth_rx(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct sh_eth_rxdesc *rxdesc;
+
+ int entry = mdp->cur_rx % RX_RING_SIZE;
+ int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
+ struct sk_buff *skb;
+ u16 pkt_len = 0;
+ u32 desc_status;
+
+ rxdesc = &mdp->rx_ring[entry];
+ while (!(rxdesc->status & cpu_to_le32(RD_RACT))) {
+ desc_status = le32_to_cpu(rxdesc->status);
+ pkt_len = rxdesc->frame_length;
+
+ if (--boguscnt < 0)
+ break;
+
+ if (!(desc_status & RDFEND))
+ mdp->stats.rx_length_errors++;
+
+ if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
+ RD_RFS5 | RD_RFS6 | RD_RFS10)) {
+ mdp->stats.rx_errors++;
+ if (desc_status & RD_RFS1)
+ mdp->stats.rx_crc_errors++;
+ if (desc_status & RD_RFS2)
+ mdp->stats.rx_frame_errors++;
+ if (desc_status & RD_RFS3)
+ mdp->stats.rx_length_errors++;
+ if (desc_status & RD_RFS4)
+ mdp->stats.rx_length_errors++;
+ if (desc_status & RD_RFS6)
+ mdp->stats.rx_missed_errors++;
+ if (desc_status & RD_RFS10)
+ mdp->stats.rx_over_errors++;
+ } else {
+ swaps((char *)(rxdesc->addr & ~0x3), pkt_len + 2);
+ skb = mdp->rx_skbuff[entry];
+ mdp->rx_skbuff[entry] = NULL;
+ skb_put(skb, pkt_len);
+ skb->protocol = eth_type_trans(skb, ndev);
+ netif_rx(skb);
+ ndev->last_rx = jiffies;
+ mdp->stats.rx_packets++;
+ mdp->stats.rx_bytes += pkt_len;
+ }
+ rxdesc->status |= cpu_to_le32(RD_RACT);
+ entry = (++mdp->cur_rx) % RX_RING_SIZE;
+ }
+
+ /* Refill the Rx ring buffers. */
+ for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
+ entry = mdp->dirty_rx % RX_RING_SIZE;
+ rxdesc = &mdp->rx_ring[entry];
+ if (mdp->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(mdp->rx_buf_sz);
+ mdp->rx_skbuff[entry] = skb;
+ if (skb == NULL)
+ break; /* Better luck next round. */
+ skb->dev = ndev;
+ skb_reserve(skb, RX_OFFSET);
+ rxdesc->addr = (u32)skb->data & ~0x3UL;
+ }
+ /* The size of the buffer is 16 byte boundary. */
+ rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+ if (entry >= RX_RING_SIZE - 1)
+ rxdesc->status |=
+ cpu_to_le32(RD_RACT | RD_RFP | RC_RDEL);
+ else
+ rxdesc->status |=
+ cpu_to_le32(RD_RACT | RD_RFP);
+ }
+
+ /* Restart Rx engine if stopped. */
+ /* If we don't need to check status, don't. -KDU */
+ ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);
+
+ return 0;
+}
+
+/* error control function */
+static void sh_eth_error(struct net_device *ndev, int intr_status)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+ u32 felic_stat;
+
+ if (intr_status & EESR_ECI) {
+ felic_stat = ctrl_inl(ioaddr + ECSR);
+ ctrl_outl(felic_stat, ioaddr + ECSR); /* clear int */
+ if (felic_stat & ECSR_ICD)
+ mdp->stats.tx_carrier_errors++;
+ if (felic_stat & ECSR_LCHNG) {
+ /* Link Changed */
+ u32 link_stat = (ctrl_inl(ioaddr + PSR));
+ if (!(link_stat & PHY_ST_LINK)) {
+ /* Link Down : disable tx and rx */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) &
+ ~(ECMR_RE | ECMR_TE), ioaddr + ECMR);
+ } else {
+ /* Link Up */
+ ctrl_outl(ctrl_inl(ioaddr + EESIPR) &
+ ~DMAC_M_ECI, ioaddr + EESIPR);
+ /*clear int */
+ ctrl_outl(ctrl_inl(ioaddr + ECSR),
+ ioaddr + ECSR);
+ ctrl_outl(ctrl_inl(ioaddr + EESIPR) |
+ DMAC_M_ECI, ioaddr + EESIPR);
+ /* enable tx and rx */
+ ctrl_outl(ctrl_inl(ioaddr + ECMR) |
+ (ECMR_RE | ECMR_TE), ioaddr + ECMR);
+ }
+ }
+ }
+
+ if (intr_status & EESR_TWB) {
+ /* Write buck end. unused write back interrupt */
+ if (intr_status & EESR_TABT) /* Transmit Abort int */
+ mdp->stats.tx_aborted_errors++;
+ }
+
+ if (intr_status & EESR_RABT) {
+ /* Receive Abort int */
+ if (intr_status & EESR_RFRMER) {
+ /* Receive Frame Overflow int */
+ mdp->stats.rx_frame_errors++;
+ printk(KERN_ERR "Receive Frame Overflow\n");
+ }
+ }
+
+ if (intr_status & EESR_ADE) {
+ if (intr_status & EESR_TDE) {
+ if (intr_status & EESR_TFE)
+ mdp->stats.tx_fifo_errors++;
+ }
+ }
+
+ if (intr_status & EESR_RDE) {
+ /* Receive Descriptor Empty int */
+ mdp->stats.rx_over_errors++;
+
+ if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R)
+ ctrl_outl(EDRRR_R, ioaddr + EDRRR);
+ printk(KERN_ERR "Receive Descriptor Empty\n");
+ }
+ if (intr_status & EESR_RFE) {
+ /* Receive FIFO Overflow int */
+ mdp->stats.rx_fifo_errors++;
+ printk(KERN_ERR "Receive FIFO Overflow\n");
+ }
+ if (intr_status &
+ (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)) {
+ /* Tx error */
+ u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
+ /* dmesg */
+ printk(KERN_ERR "%s:TX error. status=%8.8x cur_tx=%8.8x ",
+ ndev->name, intr_status, mdp->cur_tx);
+ printk(KERN_ERR "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
+ mdp->dirty_tx, (u32) ndev->state, edtrr);
+ /* dirty buffer free */
+ sh_eth_txfree(ndev);
+
+ /* SH7712 BUG */
+ if (edtrr ^ EDTRR_TRNS) {
+ /* tx dma start */
+ ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
+ }
+ /* wakeup */
+ netif_wake_queue(ndev);
+ }
+}
+
+static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
+{
+ struct net_device *ndev = netdev;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr, boguscnt = RX_RING_SIZE;
+ u32 intr_status = 0;
+
+ ioaddr = ndev->base_addr;
+ spin_lock(&mdp->lock);
+
+ intr_status = ctrl_inl(ioaddr + EESR);
+ /* Clear interrupt */
+ ctrl_outl(intr_status, ioaddr + EESR);
+
+ if (intr_status & (EESR_FRC | EESR_RINT8 |
+ EESR_RINT5 | EESR_RINT4 | EESR_RINT3 | EESR_RINT2 |
+ EESR_RINT1))
+ sh_eth_rx(ndev);
+ if (intr_status & (EESR_FTC |
+ EESR_TINT4 | EESR_TINT3 | EESR_TINT2 | EESR_TINT1)) {
+
+ sh_eth_txfree(ndev);
+ netif_wake_queue(ndev);
+ }
+
+ if (intr_status & EESR_ERR_CHECK)
+ sh_eth_error(ndev, intr_status);
+
+ if (--boguscnt < 0) {
+ printk(KERN_WARNING
+ "%s: Too much work at interrupt, status=0x%4.4x.\n",
+ ndev->name, intr_status);
+ }
+
+ spin_unlock(&mdp->lock);
+
+ return IRQ_HANDLED;
+}
+
+static void sh_eth_timer(unsigned long data)
+{
+ struct net_device *ndev = (struct net_device *)data;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ mod_timer(&mdp->timer, jiffies + (10 * HZ));
+}
+
+/* PHY state control function */
+static void sh_eth_adjust_link(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct phy_device *phydev = mdp->phydev;
+ u32 ioaddr = ndev->base_addr;
+ int new_state = 0;
+
+ if (phydev->link != PHY_DOWN) {
+ if (phydev->duplex != mdp->duplex) {
+ new_state = 1;
+ mdp->duplex = phydev->duplex;
+ }
+
+ if (phydev->speed != mdp->speed) {
+ new_state = 1;
+ mdp->speed = phydev->speed;
+ }
+ if (mdp->link == PHY_DOWN) {
+ ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
+ | ECMR_DM, ioaddr + ECMR);
+ new_state = 1;
+ mdp->link = phydev->link;
+ netif_tx_schedule_all(ndev);
+ netif_carrier_on(ndev);
+ netif_start_queue(ndev);
+ }
+ } else if (mdp->link) {
+ new_state = 1;
+ mdp->link = PHY_DOWN;
+ mdp->speed = 0;
+ mdp->duplex = -1;
+ netif_stop_queue(ndev);
+ netif_carrier_off(ndev);
+ }
+
+ if (new_state)
+ phy_print_status(phydev);
+}
+
+/* PHY init function */
+static int sh_eth_phy_init(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ char phy_id[BUS_ID_SIZE];
+ struct phy_device *phydev = NULL;
+
+ snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT,
+ mdp->mii_bus->id , mdp->phy_id);
+
+ mdp->link = PHY_DOWN;
+ mdp->speed = 0;
+ mdp->duplex = -1;
+
+ /* Try connect to PHY */
+ phydev = phy_connect(ndev, phy_id, &sh_eth_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phydev)) {
+ dev_err(&ndev->dev, "phy_connect failed\n");
+ return PTR_ERR(phydev);
+ }
+ dev_info(&ndev->dev, "attached phy %i to driver %s\n",
+ phydev->addr, phydev->drv->name);
+
+ mdp->phydev = phydev;
+
+ return 0;
+}
+
+/* PHY control start function */
+static int sh_eth_phy_start(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int ret;
+
+ ret = sh_eth_phy_init(ndev);
+ if (ret)
+ return ret;
+
+ /* reset phy - this also wakes it from PDOWN */
+ phy_write(mdp->phydev, MII_BMCR, BMCR_RESET);
+ phy_start(mdp->phydev);
+
+ return 0;
+}
+
+/* network device open function */
+static int sh_eth_open(struct net_device *ndev)
+{
+ int ret = 0;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ ret = request_irq(ndev->irq, &sh_eth_interrupt, 0, ndev->name, ndev);
+ if (ret) {
+ printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME);
+ return ret;
+ }
+
+ /* Descriptor set */
+ ret = sh_eth_ring_init(ndev);
+ if (ret)
+ goto out_free_irq;
+
+ /* device init */
+ ret = sh_eth_dev_init(ndev);
+ if (ret)
+ goto out_free_irq;
+
+ /* PHY control start*/
+ ret = sh_eth_phy_start(ndev);
+ if (ret)
+ goto out_free_irq;
+
+ /* Set the timer to check for link beat. */
+ init_timer(&mdp->timer);
+ mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
+ setup_timer(&mdp->timer, sh_eth_timer, ndev);
+
+ return ret;
+
+out_free_irq:
+ free_irq(ndev->irq, ndev);
+ return ret;
+}
+
+/* Timeout function */
+static void sh_eth_tx_timeout(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+ struct sh_eth_rxdesc *rxdesc;
+ int i;
+
+ netif_stop_queue(ndev);
+
+ /* worning message out. */
+ printk(KERN_WARNING "%s: transmit timed out, status %8.8x,"
+ " resetting...\n", ndev->name, (int)ctrl_inl(ioaddr + EESR));
+
+ /* tx_errors count up */
+ mdp->stats.tx_errors++;
+
+ /* timer off */
+ del_timer_sync(&mdp->timer);
+
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ rxdesc = &mdp->rx_ring[i];
+ rxdesc->status = 0;
+ rxdesc->addr = 0xBADF00D0;
+ if (mdp->rx_skbuff[i])
+ dev_kfree_skb(mdp->rx_skbuff[i]);
+ mdp->rx_skbuff[i] = NULL;
+ }
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ if (mdp->tx_skbuff[i])
+ dev_kfree_skb(mdp->tx_skbuff[i]);
+ mdp->tx_skbuff[i] = NULL;
+ }
+
+ /* device init */
+ sh_eth_dev_init(ndev);
+
+ /* timer on */
+ mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
+ add_timer(&mdp->timer);
+}
+
+/* Packet transmit function */
+static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct sh_eth_txdesc *txdesc;
+ u32 entry;
+ int flags;
+
+ spin_lock_irqsave(&mdp->lock, flags);
+ if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) {
+ if (!sh_eth_txfree(ndev)) {
+ netif_stop_queue(ndev);
+ spin_unlock_irqrestore(&mdp->lock, flags);
+ return 1;
+ }
+ }
+ spin_unlock_irqrestore(&mdp->lock, flags);
+
+ entry = mdp->cur_tx % TX_RING_SIZE;
+ mdp->tx_skbuff[entry] = skb;
+ txdesc = &mdp->tx_ring[entry];
+ txdesc->addr = (u32)(skb->data);
+ /* soft swap. */
+ swaps((char *)(txdesc->addr & ~0x3), skb->len + 2);
+ /* write back */
+ __flush_purge_region(skb->data, skb->len);
+ if (skb->len < ETHERSMALL)
+ txdesc->buffer_length = ETHERSMALL;
+ else
+ txdesc->buffer_length = skb->len;
+
+ if (entry >= TX_RING_SIZE - 1)
+ txdesc->status |= cpu_to_le32(TD_TACT | TD_TDLE);
+ else
+ txdesc->status |= cpu_to_le32(TD_TACT);
+
+ mdp->cur_tx++;
+
+ ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
+ ndev->trans_start = jiffies;
+
+ return 0;
+}
+
+/* device close function */
+static int sh_eth_close(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+ int ringsize;
+
+ netif_stop_queue(ndev);
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ ctrl_outl(0x0000, ioaddr + EESIPR);
+
+ /* Stop the chip's Tx and Rx processes. */
+ ctrl_outl(0, ioaddr + EDTRR);
+ ctrl_outl(0, ioaddr + EDRRR);
+
+ /* PHY Disconnect */
+ if (mdp->phydev) {
+ phy_stop(mdp->phydev);
+ phy_disconnect(mdp->phydev);
+ }
+
+ free_irq(ndev->irq, ndev);
+
+ del_timer_sync(&mdp->timer);
+
+ /* Free all the skbuffs in the Rx queue. */
+ sh_eth_ring_free(ndev);
+
+ /* free DMA buffer */
+ ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+ dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma);
+
+ /* free DMA buffer */
+ ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+ dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
+
+ return 0;
+}
+
+static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ u32 ioaddr = ndev->base_addr;
+
+ mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR);
+ ctrl_outl(0, ioaddr + TROCR); /* (write clear) */
+ mdp->stats.collisions += ctrl_inl(ioaddr + CDCR);
+ ctrl_outl(0, ioaddr + CDCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR);
+ ctrl_outl(0, ioaddr + LCCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
+ ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */
+
+ return &mdp->stats;
+}
+
+/* ioctl to device funciotn*/
+static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
+ int cmd)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct phy_device *phydev = mdp->phydev;
+
+ if (!netif_running(ndev))
+ return -EINVAL;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(phydev, if_mii(rq), cmd);
+}
+
+
+/* Multicast reception directions set */
+static void sh_eth_set_multicast_list(struct net_device *ndev)
+{
+ u32 ioaddr = ndev->base_addr;
+
+ if (ndev->flags & IFF_PROMISC) {
+ /* Set promiscuous. */
+ ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM,
+ ioaddr + ECMR);
+ } else {
+ /* Normal, unicast/broadcast-only mode. */
+ ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT,
+ ioaddr + ECMR);
+ }
+}
+
+/* SuperH's TSU register init function */
+static void sh_eth_tsu_init(u32 ioaddr)
+{
+ ctrl_outl(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */
+ ctrl_outl(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */
+ ctrl_outl(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */
+ ctrl_outl(0xc, ioaddr + TSU_BSYSL0);
+ ctrl_outl(0xc, ioaddr + TSU_BSYSL1);
+ ctrl_outl(0, ioaddr + TSU_PRISL0);
+ ctrl_outl(0, ioaddr + TSU_PRISL1);
+ ctrl_outl(0, ioaddr + TSU_FWSL0);
+ ctrl_outl(0, ioaddr + TSU_FWSL1);
+ ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
+ ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */
+ ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */
+ ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */
+ ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */
+ ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */
+ ctrl_outl(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */
+ ctrl_outl(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */
+ ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */
+ ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */
+}
+
+/* MDIO bus release function */
+static int sh_mdio_release(struct net_device *ndev)
+{
+ struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
+
+ /* unregister mdio bus */
+ mdiobus_unregister(bus);
+
+ /* remove mdio bus info from net_device */
+ dev_set_drvdata(&ndev->dev, NULL);
+
+ /* free bitbang info */
+ free_mdio_bitbang(bus);
+
+ return 0;
+}
+
+/* MDIO bus init function */
+static int sh_mdio_init(struct net_device *ndev, int id)
+{
+ int ret, i;
+ struct bb_info *bitbang;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ /* create bit control struct for PHY */
+ bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
+ if (!bitbang) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* bitbang init */
+ bitbang->addr = ndev->base_addr + PIR;
+ bitbang->mdi_msk = 0x08;
+ bitbang->mdo_msk = 0x04;
+ bitbang->mmd_msk = 0x02;/* MMD */
+ bitbang->mdc_msk = 0x01;
+ bitbang->ctrl.ops = &bb_ops;
+
+ /* MII contorller setting */
+ mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+ if (!mdp->mii_bus) {
+ ret = -ENOMEM;
+ goto out_free_bitbang;
+ }
+
+ /* Hook up MII support for ethtool */
+ mdp->mii_bus->name = "sh_mii";
+ mdp->mii_bus->dev = &ndev->dev;
+ mdp->mii_bus->id[0] = id;
+
+ /* PHY IRQ */
+ mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ if (!mdp->mii_bus->irq) {
+ ret = -ENOMEM;
+ goto out_free_bus;
+ }
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ mdp->mii_bus->irq[i] = PHY_POLL;
+
+ /* regist mdio bus */
+ ret = mdiobus_register(mdp->mii_bus);
+ if (ret)
+ goto out_free_irq;
+
+ dev_set_drvdata(&ndev->dev, mdp->mii_bus);
+
+ return 0;
+
+out_free_irq:
+ kfree(mdp->mii_bus->irq);
+
+out_free_bus:
+ kfree(mdp->mii_bus);
+
+out_free_bitbang:
+ kfree(bitbang);
+
+out:
+ return ret;
+}
+
+static int sh_eth_drv_probe(struct platform_device *pdev)
+{
+ int ret, i, devno = 0;
+ struct resource *res;
+ struct net_device *ndev = NULL;
+ struct sh_eth_private *mdp;
+
+ /* get base addr */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(res == NULL)) {
+ dev_err(&pdev->dev, "invalid resource\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ndev = alloc_etherdev(sizeof(struct sh_eth_private));
+ if (!ndev) {
+ printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME);
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* The sh Ether-specific entries in the device structure. */
+ ndev->base_addr = res->start;
+ devno = pdev->id;
+ if (devno < 0)
+ devno = 0;
+
+ ndev->dma = -1;
+ ndev->irq = platform_get_irq(pdev, 0);
+ if (ndev->irq < 0) {
+ ret = -ENODEV;
+ goto out_release;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ /* Fill in the fields of the device structure with ethernet values. */
+ ether_setup(ndev);
+
+ mdp = netdev_priv(ndev);
+ spin_lock_init(&mdp->lock);
+
+ /* get PHY ID */
+ mdp->phy_id = (int)pdev->dev.platform_data;
+
+ /* set function */
+ ndev->open = sh_eth_open;
+ ndev->hard_start_xmit = sh_eth_start_xmit;
+ ndev->stop = sh_eth_close;
+ ndev->get_stats = sh_eth_get_stats;
+ ndev->set_multicast_list = sh_eth_set_multicast_list;
+ ndev->do_ioctl = sh_eth_do_ioctl;
+ ndev->tx_timeout = sh_eth_tx_timeout;
+ ndev->watchdog_timeo = TX_TIMEOUT;
+
+ mdp->post_rx = POST_RX >> (devno << 1);
+ mdp->post_fw = POST_FW >> (devno << 1);
+
+ /* read and set MAC address */
+ read_mac_address(ndev);
+
+ /* First device only init */
+ if (!devno) {
+ /* reset device */
+ ctrl_outl(ARSTR_ARSTR, ndev->base_addr + ARSTR);
+ mdelay(1);
+
+ /* TSU init (Init only)*/
+ sh_eth_tsu_init(SH_TSU_ADDR);
+ }
+
+ /* network device register */
+ ret = register_netdev(ndev);
+ if (ret)
+ goto out_release;
+
+ /* mdio bus init */
+ ret = sh_mdio_init(ndev, pdev->id);
+ if (ret)
+ goto out_unregister;
+
+ /* pritnt device infomation */
+ printk(KERN_INFO "%s: %s at 0x%x, ",
+ ndev->name, CARDNAME, (u32) ndev->base_addr);
+
+ for (i = 0; i < 5; i++)
+ printk(KERN_INFO "%2.2x:", ndev->dev_addr[i]);
+ printk(KERN_INFO "%2.2x, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
+
+ platform_set_drvdata(pdev, ndev);
+
+ return ret;
+
+out_unregister:
+ unregister_netdev(ndev);
+
+out_release:
+ /* net_dev free */
+ if (ndev)
+ free_netdev(ndev);
+
+out:
+ return ret;
+}
+
+static int sh_eth_drv_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+
+ sh_mdio_release(ndev);
+ unregister_netdev(ndev);
+ flush_scheduled_work();
+
+ free_netdev(ndev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver sh_eth_driver = {
+ .probe = sh_eth_drv_probe,
+ .remove = sh_eth_drv_remove,
+ .driver = {
+ .name = CARDNAME,
+ },
+};
+
+static int __init sh_eth_init(void)
+{
+ return platform_driver_register(&sh_eth_driver);
+}
+
+static void __exit sh_eth_cleanup(void)
+{
+ platform_driver_unregister(&sh_eth_driver);
+}
+
+module_init(sh_eth_init);
+module_exit(sh_eth_cleanup);
+
+MODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda");
+MODULE_DESCRIPTION("Renesas SuperH Ethernet driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
new file mode 100644
index 00000000000..e01e1c34771
--- /dev/null
+++ b/drivers/net/sh_eth.h
@@ -0,0 +1,464 @@
+/*
+ * SuperH Ethernet device driver
+ *
+ * Copyright (C) 2006-2008 Nobuhiro Iwamatsu
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __SH_ETH_H__
+#define __SH_ETH_H__
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+
+#define CARDNAME "sh-eth"
+#define TX_TIMEOUT (5*HZ)
+
+#define TX_RING_SIZE 128 /* Tx ring size */
+#define RX_RING_SIZE 128 /* Rx ring size */
+#define RX_OFFSET 2 /* skb offset */
+#define ETHERSMALL 60
+#define PKT_BUF_SZ 1538
+
+/* Chip Base Address */
+#define SH_TSU_ADDR 0xA7000804
+
+/* Chip Registers */
+/* E-DMAC */
+#define EDMR 0x0000
+#define EDTRR 0x0004
+#define EDRRR 0x0008
+#define TDLAR 0x000C
+#define RDLAR 0x0010
+#define EESR 0x0014
+#define EESIPR 0x0018
+#define TRSCER 0x001C
+#define RMFCR 0x0020
+#define TFTR 0x0024
+#define FDR 0x0028
+#define RMCR 0x002C
+#define EDOCR 0x0030
+#define FCFTR 0x0034
+#define RPADIR 0x0038
+#define TRIMD 0x003C
+#define RBWAR 0x0040
+#define RDFAR 0x0044
+#define TBRAR 0x004C
+#define TDFAR 0x0050
+/* Ether Register */
+#define ECMR 0x0160
+#define ECSR 0x0164
+#define ECSIPR 0x0168
+#define PIR 0x016C
+#define MAHR 0x0170
+#define MALR 0x0174
+#define RFLR 0x0178
+#define PSR 0x017C
+#define TROCR 0x0180
+#define CDCR 0x0184
+#define LCCR 0x0188
+#define CNDCR 0x018C
+#define CEFCR 0x0194
+#define FRECR 0x0198
+#define TSFRCR 0x019C
+#define TLFRCR 0x01A0
+#define RFCR 0x01A4
+#define MAFCR 0x01A8
+#define IPGR 0x01B4
+#if defined(CONFIG_CPU_SUBTYPE_SH7710)
+#define APR 0x01B8
+#define MPR 0x01BC
+#define TPAUSER 0x1C4
+#define BCFR 0x1CC
+#endif /* CONFIG_CPU_SH7710 */
+
+#define ARSTR 0x0800
+
+/* TSU */
+#define TSU_CTRST 0x004
+#define TSU_FWEN0 0x010
+#define TSU_FWEN1 0x014
+#define TSU_FCM 0x018
+#define TSU_BSYSL0 0x020
+#define TSU_BSYSL1 0x024
+#define TSU_PRISL0 0x028
+#define TSU_PRISL1 0x02C
+#define TSU_FWSL0 0x030
+#define TSU_FWSL1 0x034
+#define TSU_FWSLC 0x038
+#define TSU_QTAGM0 0x040
+#define TSU_QTAGM1 0x044
+#define TSU_ADQT0 0x048
+#define TSU_ADQT1 0x04C
+#define TSU_FWSR 0x050
+#define TSU_FWINMK 0x054
+#define TSU_ADSBSY 0x060
+#define TSU_TEN 0x064
+#define TSU_POST1 0x070
+#define TSU_POST2 0x074
+#define TSU_POST3 0x078
+#define TSU_POST4 0x07C
+#define TXNLCR0 0x080
+#define TXALCR0 0x084
+#define RXNLCR0 0x088
+#define RXALCR0 0x08C
+#define FWNLCR0 0x090
+#define FWALCR0 0x094
+#define TXNLCR1 0x0A0
+#define TXALCR1 0x0A4
+#define RXNLCR1 0x0A8
+#define RXALCR1 0x0AC
+#define FWNLCR1 0x0B0
+#define FWALCR1 0x0B4
+
+#define TSU_ADRH0 0x0100
+#define TSU_ADRL0 0x0104
+#define TSU_ADRL31 0x01FC
+
+/* Register's bits */
+
+/* EDMR */
+enum DMAC_M_BIT {
+ EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, EDMR_SRST = 0x01,
+};
+
+/* EDTRR */
+enum DMAC_T_BIT {
+ EDTRR_TRNS = 0x01,
+};
+
+/* EDRRR*/
+enum EDRRR_R_BIT {
+ EDRRR_R = 0x01,
+};
+
+/* TPAUSER */
+enum TPAUSER_BIT {
+ TPAUSER_TPAUSE = 0x0000ffff,
+ TPAUSER_UNLIMITED = 0,
+};
+
+/* BCFR */
+enum BCFR_BIT {
+ BCFR_RPAUSE = 0x0000ffff,
+ BCFR_UNLIMITED = 0,
+};
+
+/* PIR */
+enum PIR_BIT {
+ PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01,
+};
+
+/* PSR */
+enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
+
+/* EESR */
+enum EESR_BIT {
+ EESR_TWB = 0x40000000, EESR_TABT = 0x04000000,
+ EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000,
+ EESR_ADE = 0x00800000, EESR_ECI = 0x00400000,
+ EESR_FTC = 0x00200000, EESR_TDE = 0x00100000,
+ EESR_TFE = 0x00080000, EESR_FRC = 0x00040000,
+ EESR_RDE = 0x00020000, EESR_RFE = 0x00010000,
+ EESR_TINT4 = 0x00000800, EESR_TINT3 = 0x00000400,
+ EESR_TINT2 = 0x00000200, EESR_TINT1 = 0x00000100,
+ EESR_RINT8 = 0x00000080, EESR_RINT5 = 0x00000010,
+ EESR_RINT4 = 0x00000008, EESR_RINT3 = 0x00000004,
+ EESR_RINT2 = 0x00000002, EESR_RINT1 = 0x00000001,
+};
+
+#define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
+ | EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI)
+
+/* EESIPR */
+enum DMAC_IM_BIT {
+ DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000,
+ DMAC_M_RABT = 0x02000000,
+ DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000,
+ DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000,
+ DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000,
+ DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000,
+ DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800,
+ DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200,
+ DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080,
+ DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008,
+ DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002,
+ DMAC_M_RINT1 = 0x00000001,
+};
+
+/* Receive descriptor bit */
+enum RD_STS_BIT {
+ RD_RACT = 0x80000000, RC_RDEL = 0x40000000,
+ RC_RFP1 = 0x20000000, RC_RFP0 = 0x10000000,
+ RD_RFE = 0x08000000, RD_RFS10 = 0x00000200,
+ RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080,
+ RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020,
+ RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008,
+ RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002,
+ RD_RFS1 = 0x00000001,
+};
+#define RDF1ST RC_RFP1
+#define RDFEND RC_RFP0
+#define RD_RFP (RC_RFP1|RC_RFP0)
+
+/* FCFTR */
+enum FCFTR_BIT {
+ FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000,
+ FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
+ FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
+};
+#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0)
+#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
+
+/* Transfer descriptor bit */
+enum TD_STS_BIT {
+ TD_TACT = 0x80000000, TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
+ TD_TFP0 = 0x10000000,
+};
+#define TDF1ST TD_TFP1
+#define TDFEND TD_TFP0
+#define TD_TFP (TD_TFP1|TD_TFP0)
+
+/* RMCR */
+enum RECV_RST_BIT { RMCR_RST = 0x01, };
+/* ECMR */
+enum FELIC_MODE_BIT {
+ ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
+ ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
+ ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
+ ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002,
+ ECMR_PRM = 0x00000001,
+};
+
+/* ECSR */
+enum ECSR_STATUS_BIT {
+ ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, ECSR_LCHNG = 0x04,
+ ECSR_MPD = 0x02, ECSR_ICD = 0x01,
+};
+
+/* ECSIPR */
+enum ECSIPR_STATUS_MASK_BIT {
+ ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10, ECSIPR_LCHNGIP = 0x04,
+ ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
+};
+
+/* APR */
+enum APR_BIT {
+ APR_AP = 0x00000001,
+};
+
+/* MPR */
+enum MPR_BIT {
+ MPR_MP = 0x00000001,
+};
+
+/* TRSCER */
+enum DESC_I_BIT {
+ DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200,
+ DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010,
+ DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002,
+ DESC_I_RINT1 = 0x0001,
+};
+
+/* RPADIR */
+enum RPADIR_BIT {
+ RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000,
+ RPADIR_PADR = 0x0003f,
+};
+
+/* FDR */
+enum FIFO_SIZE_BIT {
+ FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
+};
+enum phy_offsets {
+ PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
+ PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
+ PHY_16 = 16,
+};
+
+/* PHY_CTRL */
+enum PHY_CTRL_BIT {
+ PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000,
+ PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400,
+ PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080,
+};
+#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */
+
+/* PHY_STAT */
+enum PHY_STAT_BIT {
+ PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000,
+ PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020,
+ PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004,
+ PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001,
+};
+
+/* PHY_ANA */
+enum PHY_ANA_BIT {
+ PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
+ PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
+ PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
+ PHY_A_SEL = 0x001f,
+};
+/* PHY_ANL */
+enum PHY_ANL_BIT {
+ PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000,
+ PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100,
+ PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020,
+ PHY_L_SEL = 0x001f,
+};
+
+/* PHY_ANE */
+enum PHY_ANE_BIT {
+ PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004,
+ PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001,
+};
+
+/* DM9161 */
+enum PHY_16_BIT {
+ PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000,
+ PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800,
+ PHY_16_TXselect = 0x0400,
+ PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100,
+ PHY_16_Force100LNK = 0x0080,
+ PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020,
+ PHY_16_RPDCTR_EN = 0x0010,
+ PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004,
+ PHY_16_Sleepmode = 0x0002,
+ PHY_16_RemoteLoopOut = 0x0001,
+};
+
+#define POST_RX 0x08
+#define POST_FW 0x04
+#define POST0_RX (POST_RX)
+#define POST0_FW (POST_FW)
+#define POST1_RX (POST_RX >> 2)
+#define POST1_FW (POST_FW >> 2)
+#define POST_ALL (POST0_RX | POST0_FW | POST1_RX | POST1_FW)
+
+/* ARSTR */
+enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, };
+
+/* TSU_FWEN0 */
+enum TSU_FWEN0_BIT {
+ TSU_FWEN0_0 = 0x00000001,
+};
+
+/* TSU_ADSBSY */
+enum TSU_ADSBSY_BIT {
+ TSU_ADSBSY_0 = 0x00000001,
+};
+
+/* TSU_TEN */
+enum TSU_TEN_BIT {
+ TSU_TEN_0 = 0x80000000,
+};
+
+/* TSU_FWSL0 */
+enum TSU_FWSL0_BIT {
+ TSU_FWSL0_FW50 = 0x1000, TSU_FWSL0_FW40 = 0x0800,
+ TSU_FWSL0_FW30 = 0x0400, TSU_FWSL0_FW20 = 0x0200,
+ TSU_FWSL0_FW10 = 0x0100, TSU_FWSL0_RMSA0 = 0x0010,
+};
+
+/* TSU_FWSLC */
+enum TSU_FWSLC_BIT {
+ TSU_FWSLC_POSTENU = 0x2000, TSU_FWSLC_POSTENL = 0x1000,
+ TSU_FWSLC_CAMSEL03 = 0x0080, TSU_FWSLC_CAMSEL02 = 0x0040,
+ TSU_FWSLC_CAMSEL01 = 0x0020, TSU_FWSLC_CAMSEL00 = 0x0010,
+ TSU_FWSLC_CAMSEL13 = 0x0008, TSU_FWSLC_CAMSEL12 = 0x0004,
+ TSU_FWSLC_CAMSEL11 = 0x0002, TSU_FWSLC_CAMSEL10 = 0x0001,
+};
+
+/*
+ * The sh ether Tx buffer descriptors.
+ * This structure should be 20 bytes.
+ */
+struct sh_eth_txdesc {
+ u32 status; /* TD0 */
+#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+ u16 pad0; /* TD1 */
+ u16 buffer_length; /* TD1 */
+#else
+ u16 buffer_length; /* TD1 */
+ u16 pad0; /* TD1 */
+#endif
+ u32 addr; /* TD2 */
+ u32 pad1; /* padding data */
+};
+
+/*
+ * The sh ether Rx buffer descriptors.
+ * This structure should be 20 bytes.
+ */
+struct sh_eth_rxdesc {
+ u32 status; /* RD0 */
+#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+ u16 frame_length; /* RD1 */
+ u16 buffer_length; /* RD1 */
+#else
+ u16 buffer_length; /* RD1 */
+ u16 frame_length; /* RD1 */
+#endif
+ u32 addr; /* RD2 */
+ u32 pad0; /* padding data */
+};
+
+struct sh_eth_private {
+ dma_addr_t rx_desc_dma;
+ dma_addr_t tx_desc_dma;
+ struct sh_eth_rxdesc *rx_ring;
+ struct sh_eth_txdesc *tx_ring;
+ struct sk_buff **rx_skbuff;
+ struct sk_buff **tx_skbuff;
+ struct net_device_stats stats;
+ struct timer_list timer;
+ spinlock_t lock;
+ u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */
+ u32 cur_tx, dirty_tx;
+ u32 rx_buf_sz; /* Based on MTU+slack. */
+ /* MII transceiver section. */
+ u32 phy_id; /* PHY ID */
+ struct mii_bus *mii_bus; /* MDIO bus control */
+ struct phy_device *phydev; /* PHY device control */
+ enum phy_state link;
+ int msg_enable;
+ int speed;
+ int duplex;
+ u32 rx_int_var, tx_int_var; /* interrupt control variables */
+ char post_rx; /* POST receive */
+ char post_fw; /* POST forward */
+ struct net_device_stats tsu_stats; /* TSU forward status */
+};
+
+static void swaps(char *src, int len)
+{
+#ifdef __LITTLE_ENDIAN__
+ u32 *p = (u32 *)src;
+ u32 *maxp;
+ maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32));
+
+ for (; p < maxp; p++)
+ *p = swab32(*p);
+#endif
+}
+
+#endif
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index abc63b0663b..3fe01763760 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1656,7 +1656,7 @@ static inline void sis190_init_rxfilter(struct net_device *dev)
SIS_PCI_COMMIT();
}
-static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
+static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
struct net_device *dev)
{
int rc;
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index ec95e493ac1..fa3a460f8e2 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1766,7 +1766,7 @@ static int sis900_rx(struct net_device *net_dev)
skb = sis_priv->rx_skbuff[entry];
net_dev->stats.rx_dropped++;
goto refill_rx_ring;
- }
+ }
/* This situation should never happen, but due to
some unknow bugs, it is possible that
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index c8a5ef2d75f..711e4a8948e 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.21"
+#define DRV_VERSION "1.22"
#define PFX DRV_NAME " "
/*
@@ -98,7 +98,7 @@ static int disable_msi = 0;
module_param(disable_msi, int, 0);
MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
-static const struct pci_device_id sky2_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(sky2_id_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
@@ -137,6 +137,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */
{ 0 }
};
@@ -147,17 +148,6 @@ static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 };
-/* This driver supports yukon2 chipset only */
-static const char *yukon2_name[] = {
- "XL", /* 0xb3 */
- "EC Ultra", /* 0xb4 */
- "Extreme", /* 0xb5 */
- "EC", /* 0xb6 */
- "FE", /* 0xb7 */
- "FE+", /* 0xb8 */
- "Supreme", /* 0xb9 */
-};
-
static void sky2_set_multicast(struct net_device *dev);
/* Access to PHY via serial interconnect */
@@ -285,6 +275,86 @@ static void sky2_power_aux(struct sky2_hw *hw)
PC_VAUX_ON | PC_VCC_OFF));
}
+static void sky2_power_state(struct sky2_hw *hw, pci_power_t state)
+{
+ u16 power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL);
+ int pex = pci_find_capability(hw->pdev, PCI_CAP_ID_EXP);
+ u32 reg;
+
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+ switch (state) {
+ case PCI_D0:
+ break;
+
+ case PCI_D1:
+ power_control |= 1;
+ break;
+
+ case PCI_D2:
+ power_control |= 2;
+ break;
+
+ case PCI_D3hot:
+ case PCI_D3cold:
+ power_control |= 3;
+ if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
+ /* additional power saving measurements */
+ reg = sky2_pci_read32(hw, PCI_DEV_REG4);
+
+ /* set gating core clock for LTSSM in L1 state */
+ reg |= P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) |
+ /* auto clock gated scheme controlled by CLKREQ */
+ P_ASPM_A1_MODE_SELECT |
+ /* enable Gate Root Core Clock */
+ P_CLK_GATE_ROOT_COR_ENA;
+
+ if (pex && (hw->flags & SKY2_HW_CLK_POWER)) {
+ /* enable Clock Power Management (CLKREQ) */
+ u16 ctrl = sky2_pci_read16(hw, pex + PCI_EXP_DEVCTL);
+
+ ctrl |= PCI_EXP_DEVCTL_AUX_PME;
+ sky2_pci_write16(hw, pex + PCI_EXP_DEVCTL, ctrl);
+ } else
+ /* force CLKREQ Enable in Our4 (A1b only) */
+ reg |= P_ASPM_FORCE_CLKREQ_ENA;
+
+ /* set Mask Register for Release/Gate Clock */
+ sky2_pci_write32(hw, PCI_DEV_REG5,
+ P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST |
+ P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE |
+ P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN);
+ } else
+ sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT);
+
+ /* put CPU into reset state */
+ sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_RESET);
+ if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev == CHIP_REV_YU_SU_A0)
+ /* put CPU into halt state */
+ sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_HALTED);
+
+ if (pex && !(hw->flags & SKY2_HW_RAM_BUFFER)) {
+ reg = sky2_pci_read32(hw, PCI_DEV_REG1);
+ /* force to PCIe L1 */
+ reg |= PCI_FORCE_PEX_L1;
+ sky2_pci_write32(hw, PCI_DEV_REG1, reg);
+ }
+ break;
+
+ default:
+ dev_warn(&hw->pdev->dev, PFX "Invalid power state (%d) ",
+ state);
+ return;
+ }
+
+ power_control |= PCI_PM_CTRL_PME_ENABLE;
+ /* Finally, set the new power state. */
+ sky2_pci_write32(hw, hw->pm_cap + PCI_PM_CTRL, power_control);
+
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+ sky2_pci_read32(hw, B0_CTST);
+}
+
static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
{
u16 reg;
@@ -579,8 +649,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
}
- if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
- hw->chip_rev == CHIP_REV_YU_EC_U_A1) {
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_UL_2) {
/* apply fixes in PHY AFE */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
@@ -588,9 +657,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
gm_phy_write(hw, port, 0x18, 0xaa99);
gm_phy_write(hw, port, 0x17, 0x2011);
- /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
- gm_phy_write(hw, port, 0x18, 0xa204);
- gm_phy_write(hw, port, 0x17, 0x2002);
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+ /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
+ gm_phy_write(hw, port, 0x18, 0xa204);
+ gm_phy_write(hw, port, 0x17, 0x2002);
+ }
/* set page register to 0 */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
@@ -599,7 +670,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
/* apply workaround for integrated resistors calibration */
gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
- } else if (hw->chip_id != CHIP_ID_YUKON_EX) {
+ } else if (hw->chip_id != CHIP_ID_YUKON_EX &&
+ hw->chip_id < CHIP_ID_YUKON_SUPR) {
/* no effect on Yukon-XL */
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
@@ -620,28 +692,71 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
}
-static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff)
+static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
+static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
+
+static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
{
u32 reg1;
- static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
- static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA };
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
- /* Turn on/off phy power saving */
- if (onoff)
- reg1 &= ~phy_power[port];
- else
- reg1 |= phy_power[port];
+ reg1 &= ~phy_power[port];
- if (onoff && hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+ if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
reg1 |= coma_mode[port];
sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
sky2_pci_read32(hw, PCI_DEV_REG1);
+}
+
+static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
+{
+ u32 reg1;
+ u16 ctrl;
+
+ /* release GPHY Control reset */
+ sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
+
+ /* release GMAC reset */
+ sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+
+ if (hw->flags & SKY2_HW_NEWER_PHY) {
+ /* select page 2 to access MAC control register */
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
- udelay(100);
+ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+ /* allow GMII Power Down */
+ ctrl &= ~PHY_M_MAC_GMIF_PUP;
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+ /* set page register back to 0 */
+ gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+ }
+
+ /* setup General Purpose Control Register */
+ gma_write16(hw, port, GM_GP_CTRL,
+ GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
+
+ if (hw->chip_id != CHIP_ID_YUKON_EC) {
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+
+ /* enable Power Down */
+ ctrl |= PHY_M_PC_POW_D_ENA;
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+ }
+
+ /* set IEEE compatible Power Down Mode (dev. #4.99) */
+ gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN);
+ }
+
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+ reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+ reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */
+ sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+ sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
/* Force a renegotiation */
@@ -676,8 +791,11 @@ static void sky2_wol_init(struct sky2_port *sky2)
sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
sky2->flow_mode = FC_NONE;
- sky2_phy_power(hw, port, 1);
- sky2_phy_reinit(sky2);
+
+ spin_lock_bh(&sky2->phy_lock);
+ sky2_phy_power_up(hw, port);
+ sky2_phy_init(hw, port);
+ spin_unlock_bh(&sky2->phy_lock);
sky2->flow_mode = save_mode;
sky2->advertising = ctrl;
@@ -782,6 +900,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
spin_lock_bh(&sky2->phy_lock);
+ sky2_phy_power_up(hw, port);
sky2_phy_init(hw, port);
spin_unlock_bh(&sky2->phy_lock);
@@ -1386,8 +1505,6 @@ static int sky2_up(struct net_device *dev)
if (!sky2->rx_ring)
goto err_out;
- sky2_phy_power(hw, port, 1);
-
sky2_mac_init(hw, port);
/* Register is number of 4K blocks on internal RAM buffer. */
@@ -1768,7 +1885,7 @@ static int sky2_down(struct net_device *dev)
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
- sky2_phy_power(hw, port, 0);
+ sky2_phy_power_down(hw, port);
netif_carrier_off(dev);
@@ -2694,6 +2811,7 @@ static u32 sky2_mhz(const struct sky2_hw *hw)
case CHIP_ID_YUKON_EC_U:
case CHIP_ID_YUKON_EX:
case CHIP_ID_YUKON_SUPR:
+ case CHIP_ID_YUKON_UL_2:
return 125;
case CHIP_ID_YUKON_FE:
@@ -2742,6 +2860,10 @@ static int __devinit sky2_init(struct sky2_hw *hw)
hw->flags = SKY2_HW_GIGABIT
| SKY2_HW_NEWER_PHY
| SKY2_HW_ADV_POWER_CTL;
+
+ /* check for Rev. A1 dev 4200 */
+ if (sky2_read16(hw, Q_ADDR(Q_XA1, Q_WM)) == 0)
+ hw->flags |= SKY2_HW_CLK_POWER;
break;
case CHIP_ID_YUKON_EX:
@@ -2782,6 +2904,11 @@ static int __devinit sky2_init(struct sky2_hw *hw)
| SKY2_HW_ADV_POWER_CTL;
break;
+ case CHIP_ID_YUKON_UL_2:
+ hw->flags = SKY2_HW_GIGABIT
+ | SKY2_HW_ADV_POWER_CTL;
+ break;
+
default:
dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
hw->chip_id);
@@ -2792,6 +2919,11 @@ static int __devinit sky2_init(struct sky2_hw *hw)
if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
hw->flags |= SKY2_HW_FIBRE_PHY;
+ hw->pm_cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PM);
+ if (hw->pm_cap == 0) {
+ dev_err(&hw->pdev->dev, "cannot find PowerManagement capability\n");
+ return -EIO;
+ }
hw->ports = 1;
t8 = sky2_read8(hw, B2_Y2_HW_RES);
@@ -3379,7 +3511,7 @@ static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
} else
- gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+ gm_phy_write(hw, port, PHY_MARV_LED_OVER,
PHY_M_LED_MO_DUP(mode) |
PHY_M_LED_MO_10(mode) |
PHY_M_LED_MO_100(mode) |
@@ -4132,12 +4264,34 @@ static int __devinit pci_wake_enabled(struct pci_dev *dev)
return value & PCI_PM_CTRL_PME_ENABLE;
}
+/* This driver supports yukon2 chipset only */
+static const char *sky2_name(u8 chipid, char *buf, int sz)
+{
+ const char *name[] = {
+ "XL", /* 0xb3 */
+ "EC Ultra", /* 0xb4 */
+ "Extreme", /* 0xb5 */
+ "EC", /* 0xb6 */
+ "FE", /* 0xb7 */
+ "FE+", /* 0xb8 */
+ "Supreme", /* 0xb9 */
+ "UL 2", /* 0xba */
+ };
+
+ if (chipid >= CHIP_ID_YUKON_XL && chipid < CHIP_ID_YUKON_UL_2)
+ strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
+ else
+ snprintf(buf, sz, "(chip %#x)", chipid);
+ return buf;
+}
+
static int __devinit sky2_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct net_device *dev;
struct sky2_hw *hw;
int err, using_dac = 0, wol_default;
+ char buf1[16];
err = pci_enable_device(pdev);
if (err) {
@@ -4208,10 +4362,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
if (err)
goto err_out_iounmap;
- dev_info(&pdev->dev, "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n",
- DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0),
- pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
- hw->chip_id, hw->chip_rev);
+ dev_info(&pdev->dev, "v%s addr 0x%llx irq %d Yukon-2 %s rev %d\n",
+ DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0),
+ pdev->irq, sky2_name(hw->chip_id, buf1, sizeof(buf1)),
+ hw->chip_rev);
sky2_reset(hw);
@@ -4363,7 +4517,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ sky2_power_state(hw, pci_choose_state(pdev, state));
return 0;
}
@@ -4376,9 +4530,7 @@ static int sky2_resume(struct pci_dev *pdev)
if (!hw)
return 0;
- err = pci_set_power_state(pdev, PCI_D0);
- if (err)
- goto out;
+ sky2_power_state(hw, PCI_D0);
err = pci_restore_state(pdev);
if (err)
@@ -4448,8 +4600,7 @@ static void sky2_shutdown(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3cold, wol);
pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
+ sky2_power_state(hw, PCI_D3hot);
}
static struct pci_driver sky2_driver = {
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index c0a5eea2000..4d9c4a19bb8 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -28,6 +28,11 @@ enum pci_dev_reg_1 {
PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */
PCI_Y2_PME_LEGACY= 1<<15, /* PCI Express legacy power management mode */
+
+ PCI_PHY_LNK_TIM_MSK= 3L<<8,/* Bit 9.. 8: GPHY Link Trigger Timer */
+ PCI_ENA_L1_EVENT = 1<<7, /* Enable PEX L1 Event */
+ PCI_ENA_GPHY_LNK = 1<<6, /* Enable PEX L1 on GPHY Link down */
+ PCI_FORCE_PEX_L1 = 1<<5, /* Force to PEX L1 */
};
enum pci_dev_reg_2 {
@@ -45,7 +50,11 @@ enum pci_dev_reg_2 {
/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */
enum pci_dev_reg_4 {
- /* (Link Training & Status State Machine) */
+ /* (Link Training & Status State Machine) */
+ P_PEX_LTSSM_STAT_MSK = 0x7fL<<25, /* Bit 31..25: PEX LTSSM Mask */
+#define P_PEX_LTSSM_STAT(x) ((x << 25) & P_PEX_LTSSM_STAT_MSK)
+ P_PEX_LTSSM_L1_STAT = 0x34,
+ P_PEX_LTSSM_DET_STAT = 0x01,
P_TIMER_VALUE_MSK = 0xffL<<16, /* Bit 23..16: Timer Value Mask */
/* (Active State Power Management) */
P_FORCE_ASPM_REQUEST = 1<<15, /* Force ASPM Request (A1 only) */
@@ -432,6 +441,7 @@ enum {
CHIP_ID_YUKON_FE = 0xb7, /* YUKON-2 FE */
CHIP_ID_YUKON_FE_P = 0xb8, /* YUKON-2 FE+ */
CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */
+ CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */
};
enum yukon_ec_rev {
CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */
@@ -454,6 +464,9 @@ enum yukon_ex_rev {
CHIP_REV_YU_EX_A0 = 1,
CHIP_REV_YU_EX_B0 = 2,
};
+enum yukon_supr_rev {
+ CHIP_REV_YU_SU_A0 = 0,
+};
/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */
@@ -1143,6 +1156,12 @@ enum {
PHY_M_PC_ENA_AUTO = 3, /* 11 = Enable Automatic Crossover */
};
+/* for Yukon-EC Ultra Gigabit Ethernet PHY (88E1149 only) */
+enum {
+ PHY_M_PC_COP_TX_DIS = 1<<3, /* Copper Transmitter Disable */
+ PHY_M_PC_POW_D_ENA = 1<<2, /* Power Down Enable */
+};
+
/* for 10/100 Fast Ethernet PHY (88E3082 only) */
enum {
PHY_M_PC_ENA_DTE_DT = 1<<15, /* Enable Data Terminal Equ. (DTE) Detect */
@@ -1411,6 +1430,7 @@ enum {
/***** PHY_MARV_PHY_CTRL (page 2) 16 bit r/w MAC Specific Ctrl *****/
enum {
PHY_M_MAC_MD_MSK = 7<<7, /* Bit 9.. 7: Mode Select Mask */
+ PHY_M_MAC_GMIF_PUP = 1<<3, /* GMII Power Up (88E1149 only) */
PHY_M_MAC_MD_AUTO = 3,/* Auto Copper/1000Base-X */
PHY_M_MAC_MD_COPPER = 5,/* Copper only */
PHY_M_MAC_MD_1000BX = 7,/* 1000Base-X only */
@@ -2052,7 +2072,9 @@ struct sky2_hw {
#define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */
#define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */
#define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */
+#define SKY2_HW_CLK_POWER 0x00000100 /* clock power management */
+ int pm_cap;
u8 chip_id;
u8 chip_rev;
u8 pmd_type;
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 84af68fdb6c..1d58991d395 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -1301,7 +1301,7 @@ static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
#endif
/* VSV changes end */
-static struct tty_ldisc sl_ldisc = {
+static struct tty_ldisc_ops sl_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "slip",
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index e2ee91a6ae7..c5871624f97 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -106,55 +106,6 @@ MODULE_ALIAS("platform:smc911x");
*/
#define POWER_DOWN 1
-
-/* store this information for the driver.. */
-struct smc911x_local {
- /*
- * If I have to wait until the DMA is finished and ready to reload a
- * packet, I will store the skbuff here. Then, the DMA will send it
- * out and free it.
- */
- struct sk_buff *pending_tx_skb;
-
- /* version/revision of the SMC911x chip */
- u16 version;
- u16 revision;
-
- /* FIFO sizes */
- int tx_fifo_kb;
- int tx_fifo_size;
- int rx_fifo_size;
- int afc_cfg;
-
- /* Contains the current active receive/phy mode */
- int ctl_rfduplx;
- int ctl_rspeed;
-
- u32 msg_enable;
- u32 phy_type;
- struct mii_if_info mii;
-
- /* work queue */
- struct work_struct phy_configure;
-
- int tx_throttle;
- spinlock_t lock;
-
- struct net_device *netdev;
-
-#ifdef SMC_USE_DMA
- /* DMA needs the physical address of the chip */
- u_long physaddr;
- int rxdma;
- int txdma;
- int rxdma_active;
- int txdma_active;
- struct sk_buff *current_rx_skb;
- struct sk_buff *current_tx_skb;
- struct device *dev;
-#endif
-};
-
#if SMC_DEBUG > 0
#define DBG(n, args...) \
do { \
@@ -202,24 +153,24 @@ static void PRINT_PKT(u_char *buf, int length)
/* this enables an interrupt in the interrupt mask register */
-#define SMC_ENABLE_INT(x) do { \
+#define SMC_ENABLE_INT(lp, x) do { \
unsigned int __mask; \
unsigned long __flags; \
spin_lock_irqsave(&lp->lock, __flags); \
- __mask = SMC_GET_INT_EN(); \
+ __mask = SMC_GET_INT_EN((lp)); \
__mask |= (x); \
- SMC_SET_INT_EN(__mask); \
+ SMC_SET_INT_EN((lp), __mask); \
spin_unlock_irqrestore(&lp->lock, __flags); \
} while (0)
/* this disables an interrupt from the interrupt mask register */
-#define SMC_DISABLE_INT(x) do { \
+#define SMC_DISABLE_INT(lp, x) do { \
unsigned int __mask; \
unsigned long __flags; \
spin_lock_irqsave(&lp->lock, __flags); \
- __mask = SMC_GET_INT_EN(); \
+ __mask = SMC_GET_INT_EN((lp)); \
__mask &= ~(x); \
- SMC_SET_INT_EN(__mask); \
+ SMC_SET_INT_EN((lp), __mask); \
spin_unlock_irqrestore(&lp->lock, __flags); \
} while (0)
@@ -228,7 +179,6 @@ static void PRINT_PKT(u_char *buf, int length)
*/
static void smc911x_reset(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
unsigned int reg, timeout=0, resets=1;
unsigned long flags;
@@ -236,13 +186,13 @@ static void smc911x_reset(struct net_device *dev)
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
/* Take out of PM setting first */
- if ((SMC_GET_PMT_CTRL() & PMT_CTRL_READY_) == 0) {
+ if ((SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_) == 0) {
/* Write to the bytetest will take out of powerdown */
- SMC_SET_BYTE_TEST(0);
+ SMC_SET_BYTE_TEST(lp, 0);
timeout=10;
do {
udelay(10);
- reg = SMC_GET_PMT_CTRL() & PMT_CTRL_READY_;
+ reg = SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_;
} while (--timeout && !reg);
if (timeout == 0) {
PRINTK("%s: smc911x_reset timeout waiting for PM restore\n", dev->name);
@@ -252,15 +202,15 @@ static void smc911x_reset(struct net_device *dev)
/* Disable all interrupts */
spin_lock_irqsave(&lp->lock, flags);
- SMC_SET_INT_EN(0);
+ SMC_SET_INT_EN(lp, 0);
spin_unlock_irqrestore(&lp->lock, flags);
while (resets--) {
- SMC_SET_HW_CFG(HW_CFG_SRST_);
+ SMC_SET_HW_CFG(lp, HW_CFG_SRST_);
timeout=10;
do {
udelay(10);
- reg = SMC_GET_HW_CFG();
+ reg = SMC_GET_HW_CFG(lp);
/* If chip indicates reset timeout then try again */
if (reg & HW_CFG_SRST_TO_) {
PRINTK("%s: chip reset timeout, retrying...\n", dev->name);
@@ -276,7 +226,7 @@ static void smc911x_reset(struct net_device *dev)
/* make sure EEPROM has finished loading before setting GPIO_CFG */
timeout=1000;
- while ( timeout-- && (SMC_GET_E2P_CMD() & E2P_CMD_EPC_BUSY_)) {
+ while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) {
udelay(10);
}
if (timeout == 0){
@@ -285,24 +235,24 @@ static void smc911x_reset(struct net_device *dev)
}
/* Initialize interrupts */
- SMC_SET_INT_EN(0);
- SMC_ACK_INT(-1);
+ SMC_SET_INT_EN(lp, 0);
+ SMC_ACK_INT(lp, -1);
/* Reset the FIFO level and flow control settings */
- SMC_SET_HW_CFG((lp->tx_fifo_kb & 0xF) << 16);
+ SMC_SET_HW_CFG(lp, (lp->tx_fifo_kb & 0xF) << 16);
//TODO: Figure out what appropriate pause time is
- SMC_SET_FLOW(FLOW_FCPT_ | FLOW_FCEN_);
- SMC_SET_AFC_CFG(lp->afc_cfg);
+ SMC_SET_FLOW(lp, FLOW_FCPT_ | FLOW_FCEN_);
+ SMC_SET_AFC_CFG(lp, lp->afc_cfg);
/* Set to LED outputs */
- SMC_SET_GPIO_CFG(0x70070000);
+ SMC_SET_GPIO_CFG(lp, 0x70070000);
/*
* Deassert IRQ for 1*10us for edge type interrupts
* and drive IRQ pin push-pull
*/
- SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
+ SMC_SET_IRQ_CFG(lp, (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_);
/* clear anything saved */
if (lp->pending_tx_skb != NULL) {
@@ -318,46 +268,45 @@ static void smc911x_reset(struct net_device *dev)
*/
static void smc911x_enable(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
unsigned mask, cfg, cr;
unsigned long flags;
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
- SMC_SET_MAC_ADDR(dev->dev_addr);
+ SMC_SET_MAC_ADDR(lp, dev->dev_addr);
/* Enable TX */
- cfg = SMC_GET_HW_CFG();
+ cfg = SMC_GET_HW_CFG(lp);
cfg &= HW_CFG_TX_FIF_SZ_ | 0xFFF;
cfg |= HW_CFG_SF_;
- SMC_SET_HW_CFG(cfg);
- SMC_SET_FIFO_TDA(0xFF);
+ SMC_SET_HW_CFG(lp, cfg);
+ SMC_SET_FIFO_TDA(lp, 0xFF);
/* Update TX stats on every 64 packets received or every 1 sec */
- SMC_SET_FIFO_TSL(64);
- SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000);
+ SMC_SET_FIFO_TSL(lp, 64);
+ SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000);
spin_lock_irqsave(&lp->lock, flags);
- SMC_GET_MAC_CR(cr);
+ SMC_GET_MAC_CR(lp, cr);
cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_;
- SMC_SET_MAC_CR(cr);
- SMC_SET_TX_CFG(TX_CFG_TX_ON_);
+ SMC_SET_MAC_CR(lp, cr);
+ SMC_SET_TX_CFG(lp, TX_CFG_TX_ON_);
spin_unlock_irqrestore(&lp->lock, flags);
/* Add 2 byte padding to start of packets */
- SMC_SET_RX_CFG((2<<8) & RX_CFG_RXDOFF_);
+ SMC_SET_RX_CFG(lp, (2<<8) & RX_CFG_RXDOFF_);
/* Turn on receiver and enable RX */
if (cr & MAC_CR_RXEN_)
DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name);
spin_lock_irqsave(&lp->lock, flags);
- SMC_SET_MAC_CR( cr | MAC_CR_RXEN_ );
+ SMC_SET_MAC_CR(lp, cr | MAC_CR_RXEN_);
spin_unlock_irqrestore(&lp->lock, flags);
/* Interrupt on every received packet */
- SMC_SET_FIFO_RSA(0x01);
- SMC_SET_FIFO_RSL(0x00);
+ SMC_SET_FIFO_RSA(lp, 0x01);
+ SMC_SET_FIFO_RSL(lp, 0x00);
/* now, enable interrupts */
mask = INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_ | INT_EN_RSFL_EN_ |
@@ -368,7 +317,7 @@ static void smc911x_enable(struct net_device *dev)
else {
mask|=INT_EN_RDFO_EN_;
}
- SMC_ENABLE_INT(mask);
+ SMC_ENABLE_INT(lp, mask);
}
/*
@@ -376,7 +325,6 @@ static void smc911x_enable(struct net_device *dev)
*/
static void smc911x_shutdown(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
unsigned cr;
unsigned long flags;
@@ -384,35 +332,35 @@ static void smc911x_shutdown(struct net_device *dev)
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__);
/* Disable IRQ's */
- SMC_SET_INT_EN(0);
+ SMC_SET_INT_EN(lp, 0);
/* Turn of Rx and TX */
spin_lock_irqsave(&lp->lock, flags);
- SMC_GET_MAC_CR(cr);
+ SMC_GET_MAC_CR(lp, cr);
cr &= ~(MAC_CR_TXEN_ | MAC_CR_RXEN_ | MAC_CR_HBDIS_);
- SMC_SET_MAC_CR(cr);
- SMC_SET_TX_CFG(TX_CFG_STOP_TX_);
+ SMC_SET_MAC_CR(lp, cr);
+ SMC_SET_TX_CFG(lp, TX_CFG_STOP_TX_);
spin_unlock_irqrestore(&lp->lock, flags);
}
static inline void smc911x_drop_pkt(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
unsigned int fifo_count, timeout, reg;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__);
- fifo_count = SMC_GET_RX_FIFO_INF() & 0xFFFF;
+ fifo_count = SMC_GET_RX_FIFO_INF(lp) & 0xFFFF;
if (fifo_count <= 4) {
/* Manually dump the packet data */
while (fifo_count--)
- SMC_GET_RX_FIFO();
+ SMC_GET_RX_FIFO(lp);
} else {
/* Fast forward through the bad packet */
- SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_);
+ SMC_SET_RX_DP_CTRL(lp, RX_DP_CTRL_FFWD_BUSY_);
timeout=50;
do {
udelay(10);
- reg = SMC_GET_RX_DP_CTRL() & RX_DP_CTRL_FFWD_BUSY_;
+ reg = SMC_GET_RX_DP_CTRL(lp) & RX_DP_CTRL_FFWD_BUSY_;
} while (--timeout && reg);
if (timeout == 0) {
PRINTK("%s: timeout waiting for RX fast forward\n", dev->name);
@@ -428,14 +376,14 @@ static inline void smc911x_drop_pkt(struct net_device *dev)
*/
static inline void smc911x_rcv(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
unsigned int pkt_len, status;
struct sk_buff *skb;
unsigned char *data;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n",
dev->name, __FUNCTION__);
- status = SMC_GET_RX_STS_FIFO();
+ status = SMC_GET_RX_STS_FIFO(lp);
DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n",
dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff);
pkt_len = (status & RX_STS_PKT_LEN_) >> 16;
@@ -472,24 +420,23 @@ static inline void smc911x_rcv(struct net_device *dev)
skb_put(skb,pkt_len-4);
#ifdef SMC_USE_DMA
{
- struct smc911x_local *lp = netdev_priv(dev);
unsigned int fifo;
/* Lower the FIFO threshold if possible */
- fifo = SMC_GET_FIFO_INT();
+ fifo = SMC_GET_FIFO_INT(lp);
if (fifo & 0xFF) fifo--;
DBG(SMC_DEBUG_RX, "%s: Setting RX stat FIFO threshold to %d\n",
dev->name, fifo & 0xff);
- SMC_SET_FIFO_INT(fifo);
+ SMC_SET_FIFO_INT(lp, fifo);
/* Setup RX DMA */
- SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN16_ | ((2<<8) & RX_CFG_RXDOFF_));
+ SMC_SET_RX_CFG(lp, RX_CFG_RX_END_ALGN16_ | ((2<<8) & RX_CFG_RXDOFF_));
lp->rxdma_active = 1;
lp->current_rx_skb = skb;
- SMC_PULL_DATA(data, (pkt_len+2+15) & ~15);
+ SMC_PULL_DATA(lp, data, (pkt_len+2+15) & ~15);
/* Packet processing deferred to DMA RX interrupt */
}
#else
- SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_));
- SMC_PULL_DATA(data, pkt_len+2+3);
+ SMC_SET_RX_CFG(lp, RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_));
+ SMC_PULL_DATA(lp, data, pkt_len+2+3);
DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name);
PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64);
@@ -508,7 +455,6 @@ static inline void smc911x_rcv(struct net_device *dev)
static void smc911x_hardware_send_pkt(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
struct sk_buff *skb;
unsigned int cmdA, cmdB, len;
unsigned char *buf;
@@ -541,8 +487,8 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
DBG(SMC_DEBUG_TX, "%s: TX PKT LENGTH 0x%04x (%d) BUF 0x%p CMDA 0x%08x CMDB 0x%08x\n",
dev->name, len, len, buf, cmdA, cmdB);
- SMC_SET_TX_FIFO(cmdA);
- SMC_SET_TX_FIFO(cmdB);
+ SMC_SET_TX_FIFO(lp, cmdA);
+ SMC_SET_TX_FIFO(lp, cmdB);
DBG(SMC_DEBUG_PKTS, "%s: Transmitted packet\n", dev->name);
PRINT_PKT(buf, len <= 64 ? len : 64);
@@ -550,10 +496,10 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
/* Send pkt via PIO or DMA */
#ifdef SMC_USE_DMA
lp->current_tx_skb = skb;
- SMC_PUSH_DATA(buf, len);
+ SMC_PUSH_DATA(lp, buf, len);
/* DMA complete IRQ will free buffer and set jiffies */
#else
- SMC_PUSH_DATA(buf, len);
+ SMC_PUSH_DATA(lp, buf, len);
dev->trans_start = jiffies;
dev_kfree_skb(skb);
#endif
@@ -562,7 +508,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
netif_wake_queue(dev);
}
spin_unlock_irqrestore(&lp->lock, flags);
- SMC_ENABLE_INT(INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_);
+ SMC_ENABLE_INT(lp, INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_);
}
/*
@@ -574,7 +520,6 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
unsigned int free;
unsigned long flags;
@@ -583,7 +528,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
BUG_ON(lp->pending_tx_skb != NULL);
- free = SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TDFREE_;
+ free = SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TDFREE_;
DBG(SMC_DEBUG_TX, "%s: TX free space %d\n", dev->name, free);
/* Turn off the flow when running out of space in FIFO */
@@ -592,7 +537,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->name, free);
spin_lock_irqsave(&lp->lock, flags);
/* Reenable when at least 1 packet of size MTU present */
- SMC_SET_FIFO_TDA((SMC911X_TX_FIFO_LOW_THRESHOLD)/64);
+ SMC_SET_FIFO_TDA(lp, (SMC911X_TX_FIFO_LOW_THRESHOLD)/64);
lp->tx_throttle = 1;
netif_stop_queue(dev);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -647,7 +592,6 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
static void smc911x_tx(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
unsigned int tx_status;
@@ -655,11 +599,11 @@ static void smc911x_tx(struct net_device *dev)
dev->name, __FUNCTION__);
/* Collect the TX status */
- while (((SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16) != 0) {
+ while (((SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16) != 0) {
DBG(SMC_DEBUG_TX, "%s: Tx stat FIFO used 0x%04x\n",
dev->name,
- (SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16);
- tx_status = SMC_GET_TX_STS_FIFO();
+ (SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16);
+ tx_status = SMC_GET_TX_STS_FIFO(lp);
dev->stats.tx_packets++;
dev->stats.tx_bytes+=tx_status>>16;
DBG(SMC_DEBUG_TX, "%s: Tx FIFO tag 0x%04x status 0x%04x\n",
@@ -697,10 +641,10 @@ static void smc911x_tx(struct net_device *dev)
static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
unsigned int phydata;
- SMC_GET_MII(phyreg, phyaddr, phydata);
+ SMC_GET_MII(lp, phyreg, phyaddr, phydata);
DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n",
__FUNCTION__, phyaddr, phyreg, phydata);
@@ -714,12 +658,12 @@ static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg)
static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg,
int phydata)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
__FUNCTION__, phyaddr, phyreg, phydata);
- SMC_SET_MII(phyreg, phyaddr, phydata);
+ SMC_SET_MII(lp, phyreg, phyaddr, phydata);
}
/*
@@ -728,7 +672,6 @@ static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg,
*/
static void smc911x_phy_detect(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
int phyaddr;
unsigned int cfg, id1, id2;
@@ -744,30 +687,30 @@ static void smc911x_phy_detect(struct net_device *dev)
switch(lp->version) {
case 0x115:
case 0x117:
- cfg = SMC_GET_HW_CFG();
+ cfg = SMC_GET_HW_CFG(lp);
if (cfg & HW_CFG_EXT_PHY_DET_) {
cfg &= ~HW_CFG_PHY_CLK_SEL_;
cfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
- SMC_SET_HW_CFG(cfg);
+ SMC_SET_HW_CFG(lp, cfg);
udelay(10); /* Wait for clocks to stop */
cfg |= HW_CFG_EXT_PHY_EN_;
- SMC_SET_HW_CFG(cfg);
+ SMC_SET_HW_CFG(lp, cfg);
udelay(10); /* Wait for clocks to stop */
cfg &= ~HW_CFG_PHY_CLK_SEL_;
cfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
- SMC_SET_HW_CFG(cfg);
+ SMC_SET_HW_CFG(lp, cfg);
udelay(10); /* Wait for clocks to stop */
cfg |= HW_CFG_SMI_SEL_;
- SMC_SET_HW_CFG(cfg);
+ SMC_SET_HW_CFG(lp, cfg);
for (phyaddr = 1; phyaddr < 32; ++phyaddr) {
/* Read the PHY identifiers */
- SMC_GET_PHY_ID1(phyaddr & 31, id1);
- SMC_GET_PHY_ID2(phyaddr & 31, id2);
+ SMC_GET_PHY_ID1(lp, phyaddr & 31, id1);
+ SMC_GET_PHY_ID2(lp, phyaddr & 31, id2);
/* Make sure it is a valid identifier */
if (id1 != 0x0000 && id1 != 0xffff &&
@@ -782,8 +725,8 @@ static void smc911x_phy_detect(struct net_device *dev)
}
default:
/* Internal media only */
- SMC_GET_PHY_ID1(1, id1);
- SMC_GET_PHY_ID2(1, id2);
+ SMC_GET_PHY_ID1(lp, 1, id1);
+ SMC_GET_PHY_ID2(lp, 1, id2);
/* Save the PHY's address */
lp->mii.phy_id = 1;
lp->phy_type = id1 << 16 | id2;
@@ -800,16 +743,15 @@ static void smc911x_phy_detect(struct net_device *dev)
static int smc911x_phy_fixed(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int phyaddr = lp->mii.phy_id;
int bmcr;
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
/* Enter Link Disable state */
- SMC_GET_PHY_BMCR(phyaddr, bmcr);
+ SMC_GET_PHY_BMCR(lp, phyaddr, bmcr);
bmcr |= BMCR_PDOWN;
- SMC_SET_PHY_BMCR(phyaddr, bmcr);
+ SMC_SET_PHY_BMCR(lp, phyaddr, bmcr);
/*
* Set our fixed capabilities
@@ -823,11 +765,11 @@ static int smc911x_phy_fixed(struct net_device *dev)
bmcr |= BMCR_SPEED100;
/* Write our capabilities to the phy control register */
- SMC_SET_PHY_BMCR(phyaddr, bmcr);
+ SMC_SET_PHY_BMCR(lp, phyaddr, bmcr);
/* Re-Configure the Receive/Phy Control register */
bmcr &= ~BMCR_PDOWN;
- SMC_SET_PHY_BMCR(phyaddr, bmcr);
+ SMC_SET_PHY_BMCR(lp, phyaddr, bmcr);
return 1;
}
@@ -847,7 +789,6 @@ static int smc911x_phy_fixed(struct net_device *dev)
static int smc911x_phy_reset(struct net_device *dev, int phy)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int timeout;
unsigned long flags;
unsigned int reg;
@@ -855,15 +796,15 @@ static int smc911x_phy_reset(struct net_device *dev, int phy)
DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
spin_lock_irqsave(&lp->lock, flags);
- reg = SMC_GET_PMT_CTRL();
+ reg = SMC_GET_PMT_CTRL(lp);
reg &= ~0xfffff030;
reg |= PMT_CTRL_PHY_RST_;
- SMC_SET_PMT_CTRL(reg);
+ SMC_SET_PMT_CTRL(lp, reg);
spin_unlock_irqrestore(&lp->lock, flags);
for (timeout = 2; timeout; timeout--) {
msleep(50);
spin_lock_irqsave(&lp->lock, flags);
- reg = SMC_GET_PMT_CTRL();
+ reg = SMC_GET_PMT_CTRL(lp);
spin_unlock_irqrestore(&lp->lock, flags);
if (!(reg & PMT_CTRL_PHY_RST_)) {
/* extra delay required because the phy may
@@ -888,13 +829,13 @@ static int smc911x_phy_reset(struct net_device *dev, int phy)
*/
static void smc911x_phy_powerdown(struct net_device *dev, int phy)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
unsigned int bmcr;
/* Enter Link Disable state */
- SMC_GET_PHY_BMCR(phy, bmcr);
+ SMC_GET_PHY_BMCR(lp, phy, bmcr);
bmcr |= BMCR_PDOWN;
- SMC_SET_PHY_BMCR(phy, bmcr);
+ SMC_SET_PHY_BMCR(lp, phy, bmcr);
}
/*
@@ -908,7 +849,6 @@ static void smc911x_phy_powerdown(struct net_device *dev, int phy)
static void smc911x_phy_check_media(struct net_device *dev, int init)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int phyaddr = lp->mii.phy_id;
unsigned int bmcr, cr;
@@ -916,8 +856,8 @@ static void smc911x_phy_check_media(struct net_device *dev, int init)
if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
/* duplex state has changed */
- SMC_GET_PHY_BMCR(phyaddr, bmcr);
- SMC_GET_MAC_CR(cr);
+ SMC_GET_PHY_BMCR(lp, phyaddr, bmcr);
+ SMC_GET_MAC_CR(lp, cr);
if (lp->mii.full_duplex) {
DBG(SMC_DEBUG_MISC, "%s: Configuring for full-duplex mode\n", dev->name);
bmcr |= BMCR_FULLDPLX;
@@ -927,8 +867,8 @@ static void smc911x_phy_check_media(struct net_device *dev, int init)
bmcr &= ~BMCR_FULLDPLX;
cr &= ~MAC_CR_RCVOWN_;
}
- SMC_SET_PHY_BMCR(phyaddr, bmcr);
- SMC_SET_MAC_CR(cr);
+ SMC_SET_PHY_BMCR(lp, phyaddr, bmcr);
+ SMC_SET_MAC_CR(lp, cr);
}
}
@@ -946,7 +886,6 @@ static void smc911x_phy_configure(struct work_struct *work)
struct smc911x_local *lp = container_of(work, struct smc911x_local,
phy_configure);
struct net_device *dev = lp->netdev;
- unsigned long ioaddr = dev->base_addr;
int phyaddr = lp->mii.phy_id;
int my_phy_caps; /* My PHY capabilities */
int my_ad_caps; /* My Advertised capabilities */
@@ -971,7 +910,7 @@ static void smc911x_phy_configure(struct work_struct *work)
* Enable PHY Interrupts (for register 18)
* Interrupts listed here are enabled
*/
- SMC_SET_PHY_INT_MASK(phyaddr, PHY_INT_MASK_ENERGY_ON_ |
+ SMC_SET_PHY_INT_MASK(lp, phyaddr, PHY_INT_MASK_ENERGY_ON_ |
PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_REMOTE_FAULT_ |
PHY_INT_MASK_LINK_DOWN_);
@@ -982,7 +921,7 @@ static void smc911x_phy_configure(struct work_struct *work)
}
/* Copy our capabilities from MII_BMSR to MII_ADVERTISE */
- SMC_GET_PHY_BMSR(phyaddr, my_phy_caps);
+ SMC_GET_PHY_BMSR(lp, phyaddr, my_phy_caps);
if (!(my_phy_caps & BMSR_ANEGCAPABLE)) {
printk(KERN_INFO "Auto negotiation NOT supported\n");
smc911x_phy_fixed(dev);
@@ -1011,7 +950,7 @@ static void smc911x_phy_configure(struct work_struct *work)
my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
/* Update our Auto-Neg Advertisement Register */
- SMC_SET_PHY_MII_ADV(phyaddr, my_ad_caps);
+ SMC_SET_PHY_MII_ADV(lp, phyaddr, my_ad_caps);
lp->mii.advertising = my_ad_caps;
/*
@@ -1020,13 +959,13 @@ static void smc911x_phy_configure(struct work_struct *work)
* the link does not come up.
*/
udelay(10);
- SMC_GET_PHY_MII_ADV(phyaddr, status);
+ SMC_GET_PHY_MII_ADV(lp, phyaddr, status);
DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps);
DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps);
/* Restart auto-negotiation process in order to advertise my caps */
- SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART);
+ SMC_SET_PHY_BMCR(lp, phyaddr, BMCR_ANENABLE | BMCR_ANRESTART);
smc911x_phy_check_media(dev, 1);
@@ -1043,7 +982,6 @@ smc911x_phy_configure_exit:
static void smc911x_phy_interrupt(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int phyaddr = lp->mii.phy_id;
int status;
@@ -1054,11 +992,11 @@ static void smc911x_phy_interrupt(struct net_device *dev)
smc911x_phy_check_media(dev, 0);
/* read to clear status bits */
- SMC_GET_PHY_INT_SRC(phyaddr,status);
+ SMC_GET_PHY_INT_SRC(lp, phyaddr,status);
DBG(SMC_DEBUG_MISC, "%s: PHY interrupt status 0x%04x\n",
dev->name, status & 0xffff);
DBG(SMC_DEBUG_MISC, "%s: AFC_CFG 0x%08x\n",
- dev->name, SMC_GET_AFC_CFG());
+ dev->name, SMC_GET_AFC_CFG(lp));
}
/*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/
@@ -1070,7 +1008,6 @@ static void smc911x_phy_interrupt(struct net_device *dev)
static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
unsigned int status, mask, timeout;
unsigned int rx_overrun=0, cr, pkts;
@@ -1081,21 +1018,21 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
spin_lock_irqsave(&lp->lock, flags);
/* Spurious interrupt check */
- if ((SMC_GET_IRQ_CFG() & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) !=
+ if ((SMC_GET_IRQ_CFG(lp) & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) !=
(INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) {
spin_unlock_irqrestore(&lp->lock, flags);
return IRQ_NONE;
}
- mask = SMC_GET_INT_EN();
- SMC_SET_INT_EN(0);
+ mask = SMC_GET_INT_EN(lp);
+ SMC_SET_INT_EN(lp, 0);
/* set a timeout value, so I don't stay here forever */
timeout = 8;
do {
- status = SMC_GET_INT();
+ status = SMC_GET_INT(lp);
DBG(SMC_DEBUG_MISC, "%s: INT 0x%08x MASK 0x%08x OUTSIDE MASK 0x%08x\n",
dev->name, status, mask, status & ~mask);
@@ -1106,53 +1043,53 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
/* Handle SW interrupt condition */
if (status & INT_STS_SW_INT_) {
- SMC_ACK_INT(INT_STS_SW_INT_);
+ SMC_ACK_INT(lp, INT_STS_SW_INT_);
mask &= ~INT_EN_SW_INT_EN_;
}
/* Handle various error conditions */
if (status & INT_STS_RXE_) {
- SMC_ACK_INT(INT_STS_RXE_);
+ SMC_ACK_INT(lp, INT_STS_RXE_);
dev->stats.rx_errors++;
}
if (status & INT_STS_RXDFH_INT_) {
- SMC_ACK_INT(INT_STS_RXDFH_INT_);
- dev->stats.rx_dropped+=SMC_GET_RX_DROP();
+ SMC_ACK_INT(lp, INT_STS_RXDFH_INT_);
+ dev->stats.rx_dropped+=SMC_GET_RX_DROP(lp);
}
/* Undocumented interrupt-what is the right thing to do here? */
if (status & INT_STS_RXDF_INT_) {
- SMC_ACK_INT(INT_STS_RXDF_INT_);
+ SMC_ACK_INT(lp, INT_STS_RXDF_INT_);
}
/* Rx Data FIFO exceeds set level */
if (status & INT_STS_RDFL_) {
if (IS_REV_A(lp->revision)) {
rx_overrun=1;
- SMC_GET_MAC_CR(cr);
+ SMC_GET_MAC_CR(lp, cr);
cr &= ~MAC_CR_RXEN_;
- SMC_SET_MAC_CR(cr);
+ SMC_SET_MAC_CR(lp, cr);
DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name);
dev->stats.rx_errors++;
dev->stats.rx_fifo_errors++;
}
- SMC_ACK_INT(INT_STS_RDFL_);
+ SMC_ACK_INT(lp, INT_STS_RDFL_);
}
if (status & INT_STS_RDFO_) {
if (!IS_REV_A(lp->revision)) {
- SMC_GET_MAC_CR(cr);
+ SMC_GET_MAC_CR(lp, cr);
cr &= ~MAC_CR_RXEN_;
- SMC_SET_MAC_CR(cr);
+ SMC_SET_MAC_CR(lp, cr);
rx_overrun=1;
DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name);
dev->stats.rx_errors++;
dev->stats.rx_fifo_errors++;
}
- SMC_ACK_INT(INT_STS_RDFO_);
+ SMC_ACK_INT(lp, INT_STS_RDFO_);
}
/* Handle receive condition */
if ((status & INT_STS_RSFL_) || rx_overrun) {
unsigned int fifo;
DBG(SMC_DEBUG_RX, "%s: RX irq\n", dev->name);
- fifo = SMC_GET_RX_FIFO_INF();
+ fifo = SMC_GET_RX_FIFO_INF(lp);
pkts = (fifo & RX_FIFO_INF_RXSUSED_) >> 16;
DBG(SMC_DEBUG_RX, "%s: Rx FIFO pkts %d, bytes %d\n",
dev->name, pkts, fifo & 0xFFFF );
@@ -1163,61 +1100,61 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA,
"%s: RX DMA active\n", dev->name);
/* The DMA is already running so up the IRQ threshold */
- fifo = SMC_GET_FIFO_INT() & ~0xFF;
+ fifo = SMC_GET_FIFO_INT(lp) & ~0xFF;
fifo |= pkts & 0xFF;
DBG(SMC_DEBUG_RX,
"%s: Setting RX stat FIFO threshold to %d\n",
dev->name, fifo & 0xff);
- SMC_SET_FIFO_INT(fifo);
+ SMC_SET_FIFO_INT(lp, fifo);
} else
#endif
smc911x_rcv(dev);
}
- SMC_ACK_INT(INT_STS_RSFL_);
+ SMC_ACK_INT(lp, INT_STS_RSFL_);
}
/* Handle transmit FIFO available */
if (status & INT_STS_TDFA_) {
DBG(SMC_DEBUG_TX, "%s: TX data FIFO space available irq\n", dev->name);
- SMC_SET_FIFO_TDA(0xFF);
+ SMC_SET_FIFO_TDA(lp, 0xFF);
lp->tx_throttle = 0;
#ifdef SMC_USE_DMA
if (!lp->txdma_active)
#endif
netif_wake_queue(dev);
- SMC_ACK_INT(INT_STS_TDFA_);
+ SMC_ACK_INT(lp, INT_STS_TDFA_);
}
/* Handle transmit done condition */
#if 1
if (status & (INT_STS_TSFL_ | INT_STS_GPT_INT_)) {
DBG(SMC_DEBUG_TX | SMC_DEBUG_MISC,
"%s: Tx stat FIFO limit (%d) /GPT irq\n",
- dev->name, (SMC_GET_FIFO_INT() & 0x00ff0000) >> 16);
+ dev->name, (SMC_GET_FIFO_INT(lp) & 0x00ff0000) >> 16);
smc911x_tx(dev);
- SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000);
- SMC_ACK_INT(INT_STS_TSFL_);
- SMC_ACK_INT(INT_STS_TSFL_ | INT_STS_GPT_INT_);
+ SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000);
+ SMC_ACK_INT(lp, INT_STS_TSFL_);
+ SMC_ACK_INT(lp, INT_STS_TSFL_ | INT_STS_GPT_INT_);
}
#else
if (status & INT_STS_TSFL_) {
DBG(SMC_DEBUG_TX, "%s: TX status FIFO limit (%d) irq \n", dev->name, );
smc911x_tx(dev);
- SMC_ACK_INT(INT_STS_TSFL_);
+ SMC_ACK_INT(lp, INT_STS_TSFL_);
}
if (status & INT_STS_GPT_INT_) {
DBG(SMC_DEBUG_RX, "%s: IRQ_CFG 0x%08x FIFO_INT 0x%08x RX_CFG 0x%08x\n",
dev->name,
- SMC_GET_IRQ_CFG(),
- SMC_GET_FIFO_INT(),
- SMC_GET_RX_CFG());
+ SMC_GET_IRQ_CFG(lp),
+ SMC_GET_FIFO_INT(lp),
+ SMC_GET_RX_CFG(lp));
DBG(SMC_DEBUG_RX, "%s: Rx Stat FIFO Used 0x%02x "
"Data FIFO Used 0x%04x Stat FIFO 0x%08x\n",
dev->name,
- (SMC_GET_RX_FIFO_INF() & 0x00ff0000) >> 16,
- SMC_GET_RX_FIFO_INF() & 0xffff,
- SMC_GET_RX_STS_FIFO_PEEK());
- SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000);
- SMC_ACK_INT(INT_STS_GPT_INT_);
+ (SMC_GET_RX_FIFO_INF(lp) & 0x00ff0000) >> 16,
+ SMC_GET_RX_FIFO_INF(lp) & 0xffff,
+ SMC_GET_RX_STS_FIFO_PEEK(lp));
+ SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000);
+ SMC_ACK_INT(lp, INT_STS_GPT_INT_);
}
#endif
@@ -1225,12 +1162,12 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
if (status & INT_STS_PHY_INT_) {
DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name);
smc911x_phy_interrupt(dev);
- SMC_ACK_INT(INT_STS_PHY_INT_);
+ SMC_ACK_INT(lp, INT_STS_PHY_INT_);
}
} while (--timeout);
/* restore mask state */
- SMC_SET_INT_EN(mask);
+ SMC_SET_INT_EN(lp, mask);
DBG(SMC_DEBUG_MISC, "%s: Interrupt done (%d loops)\n",
dev->name, 8-timeout);
@@ -1332,22 +1269,21 @@ static void smc911x_poll_controller(struct net_device *dev)
static void smc911x_timeout(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int status, mask;
unsigned long flags;
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
spin_lock_irqsave(&lp->lock, flags);
- status = SMC_GET_INT();
- mask = SMC_GET_INT_EN();
+ status = SMC_GET_INT(lp);
+ mask = SMC_GET_INT_EN(lp);
spin_unlock_irqrestore(&lp->lock, flags);
DBG(SMC_DEBUG_MISC, "%s: INT 0x%02x MASK 0x%02x \n",
dev->name, status, mask);
/* Dump the current TX FIFO contents and restart */
- mask = SMC_GET_TX_CFG();
- SMC_SET_TX_CFG(mask | TX_CFG_TXS_DUMP_ | TX_CFG_TXD_DUMP_);
+ mask = SMC_GET_TX_CFG(lp);
+ SMC_SET_TX_CFG(lp, mask | TX_CFG_TXS_DUMP_ | TX_CFG_TXD_DUMP_);
/*
* Reconfiguring the PHY doesn't seem like a bad idea here, but
* smc911x_phy_configure() calls msleep() which calls schedule_timeout()
@@ -1370,7 +1306,6 @@ static void smc911x_timeout(struct net_device *dev)
static void smc911x_set_multicast_list(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
unsigned int multicast_table[2];
unsigned int mcr, update_multicast = 0;
unsigned long flags;
@@ -1378,7 +1313,7 @@ static void smc911x_set_multicast_list(struct net_device *dev)
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
spin_lock_irqsave(&lp->lock, flags);
- SMC_GET_MAC_CR(mcr);
+ SMC_GET_MAC_CR(lp, mcr);
spin_unlock_irqrestore(&lp->lock, flags);
if (dev->flags & IFF_PROMISC) {
@@ -1455,13 +1390,13 @@ static void smc911x_set_multicast_list(struct net_device *dev)
}
spin_lock_irqsave(&lp->lock, flags);
- SMC_SET_MAC_CR(mcr);
+ SMC_SET_MAC_CR(lp, mcr);
if (update_multicast) {
DBG(SMC_DEBUG_MISC,
"%s: update mcast hash table 0x%08x 0x%08x\n",
dev->name, multicast_table[0], multicast_table[1]);
- SMC_SET_HASHL(multicast_table[0]);
- SMC_SET_HASHH(multicast_table[1]);
+ SMC_SET_HASHL(lp, multicast_table[0]);
+ SMC_SET_HASHH(lp, multicast_table[1]);
}
spin_unlock_irqrestore(&lp->lock, flags);
}
@@ -1545,7 +1480,6 @@ static int
smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct smc911x_local *lp = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
int ret, status;
unsigned long flags;
@@ -1573,7 +1507,7 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
else
cmd->transceiver = XCVR_EXTERNAL;
cmd->port = 0;
- SMC_GET_PHY_SPECIAL(lp->mii.phy_id, status);
+ SMC_GET_PHY_SPECIAL(lp, lp->mii.phy_id, status);
cmd->duplex =
(status & (PHY_SPECIAL_SPD_10FULL_ | PHY_SPECIAL_SPD_100FULL_)) ?
DUPLEX_FULL : DUPLEX_HALF;
@@ -1654,7 +1588,6 @@ static int smc911x_ethtool_getregslen(struct net_device *dev)
static void smc911x_ethtool_getregs(struct net_device *dev,
struct ethtool_regs* regs, void *buf)
{
- unsigned long ioaddr = dev->base_addr;
struct smc911x_local *lp = netdev_priv(dev);
unsigned long flags;
u32 reg,i,j=0;
@@ -1662,17 +1595,17 @@ static void smc911x_ethtool_getregs(struct net_device *dev,
regs->version = lp->version;
for(i=ID_REV;i<=E2P_CMD;i+=4) {
- data[j++] = SMC_inl(ioaddr,i);
+ data[j++] = SMC_inl(lp, i);
}
for(i=MAC_CR;i<=WUCSR;i++) {
spin_lock_irqsave(&lp->lock, flags);
- SMC_GET_MAC_CSR(i, reg);
+ SMC_GET_MAC_CSR(lp, i, reg);
spin_unlock_irqrestore(&lp->lock, flags);
data[j++] = reg;
}
for(i=0;i<=31;i++) {
spin_lock_irqsave(&lp->lock, flags);
- SMC_GET_MII(i, lp->mii.phy_id, reg);
+ SMC_GET_MII(lp, i, lp->mii.phy_id, reg);
spin_unlock_irqrestore(&lp->lock, flags);
data[j++] = reg & 0xFFFF;
}
@@ -1680,11 +1613,11 @@ static void smc911x_ethtool_getregs(struct net_device *dev,
static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
unsigned int timeout;
int e2p_cmd;
- e2p_cmd = SMC_GET_E2P_CMD();
+ e2p_cmd = SMC_GET_E2P_CMD(lp);
for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) {
if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) {
PRINTK("%s: %s timeout waiting for EEPROM to respond\n",
@@ -1692,7 +1625,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
return -EFAULT;
}
mdelay(1);
- e2p_cmd = SMC_GET_E2P_CMD();
+ e2p_cmd = SMC_GET_E2P_CMD(lp);
}
if (timeout == 0) {
PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n",
@@ -1705,12 +1638,12 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
static inline int smc911x_ethtool_write_eeprom_cmd(struct net_device *dev,
int cmd, int addr)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
int ret;
if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0)
return ret;
- SMC_SET_E2P_CMD(E2P_CMD_EPC_BUSY_ |
+ SMC_SET_E2P_CMD(lp, E2P_CMD_EPC_BUSY_ |
((cmd) & (0x7<<28)) |
((addr) & 0xFF));
return 0;
@@ -1719,24 +1652,24 @@ static inline int smc911x_ethtool_write_eeprom_cmd(struct net_device *dev,
static inline int smc911x_ethtool_read_eeprom_byte(struct net_device *dev,
u8 *data)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
int ret;
if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0)
return ret;
- *data = SMC_GET_E2P_DATA();
+ *data = SMC_GET_E2P_DATA(lp);
return 0;
}
static inline int smc911x_ethtool_write_eeprom_byte(struct net_device *dev,
u8 data)
{
- unsigned long ioaddr = dev->base_addr;
+ struct smc911x_local *lp = netdev_priv(dev);
int ret;
if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0)
return ret;
- SMC_SET_E2P_DATA(data);
+ SMC_SET_E2P_DATA(lp, data);
return 0;
}
@@ -1803,8 +1736,9 @@ static const struct ethtool_ops smc911x_ethtool_ops = {
* This routine has a simple purpose -- make the SMC chip generate an
* interrupt, so an auto-detect routine can detect it, and find the IRQ,
*/
-static int __init smc911x_findirq(unsigned long ioaddr)
+static int __init smc911x_findirq(struct net_device *dev)
{
+ struct smc911x_local *lp = netdev_priv(dev);
int timeout = 20;
unsigned long cookie;
@@ -1816,7 +1750,7 @@ static int __init smc911x_findirq(unsigned long ioaddr)
* Force a SW interrupt
*/
- SMC_SET_INT_EN(INT_EN_SW_INT_EN_);
+ SMC_SET_INT_EN(lp, INT_EN_SW_INT_EN_);
/*
* Wait until positive that the interrupt has been generated
@@ -1824,7 +1758,7 @@ static int __init smc911x_findirq(unsigned long ioaddr)
do {
int int_status;
udelay(10);
- int_status = SMC_GET_INT_EN();
+ int_status = SMC_GET_INT_EN(lp);
if (int_status & INT_EN_SW_INT_EN_)
break; /* got the interrupt */
} while (--timeout);
@@ -1837,7 +1771,7 @@ static int __init smc911x_findirq(unsigned long ioaddr)
*/
/* and disable all interrupts again */
- SMC_SET_INT_EN(0);
+ SMC_SET_INT_EN(lp, 0);
/* and return what I found */
return probe_irq_off(cookie);
@@ -1866,17 +1800,18 @@ static int __init smc911x_findirq(unsigned long ioaddr)
* o actually GRAB the irq.
* o GRAB the region
*/
-static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
+static int __init smc911x_probe(struct net_device *dev)
{
struct smc911x_local *lp = netdev_priv(dev);
int i, retval;
unsigned int val, chip_id, revision;
const char *version_string;
+ unsigned long irq_flags;
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
/* First, see if the endian word is recognized */
- val = SMC_GET_BYTE_TEST();
+ val = SMC_GET_BYTE_TEST(lp);
DBG(SMC_DEBUG_MISC, "%s: endian probe returned 0x%04x\n", CARDNAME, val);
if (val != 0x87654321) {
printk(KERN_ERR "Invalid chip endian 0x08%x\n",val);
@@ -1889,7 +1824,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
* recognize. These might need to be added to later,
* as future revisions could be added.
*/
- chip_id = SMC_GET_PN();
+ chip_id = SMC_GET_PN(lp);
DBG(SMC_DEBUG_MISC, "%s: id probe returned 0x%04x\n", CARDNAME, chip_id);
for(i=0;chip_ids[i].id != 0; i++) {
if (chip_ids[i].id == chip_id) break;
@@ -1901,7 +1836,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
}
version_string = chip_ids[i].name;
- revision = SMC_GET_REV();
+ revision = SMC_GET_REV(lp);
DBG(SMC_DEBUG_MISC, "%s: revision = 0x%04x\n", CARDNAME, revision);
/* At this point I'll assume that the chip is an SMC911x. */
@@ -1915,7 +1850,6 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
}
/* fill in some of the fields */
- dev->base_addr = ioaddr;
lp->version = chip_ids[i].id;
lp->revision = revision;
lp->tx_fifo_kb = tx_fifo_kb;
@@ -1974,7 +1908,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
spin_lock_init(&lp->lock);
/* Get the MAC address */
- SMC_GET_MAC_ADDR(dev->dev_addr);
+ SMC_GET_MAC_ADDR(lp, dev->dev_addr);
/* now, reset the chip, and put it into a known state */
smc911x_reset(dev);
@@ -1991,7 +1925,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
trials = 3;
while (trials--) {
- dev->irq = smc911x_findirq(ioaddr);
+ dev->irq = smc911x_findirq(dev);
if (dev->irq)
break;
/* kick the card and try again */
@@ -2039,9 +1973,15 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
lp->ctl_rfduplx = 1;
lp->ctl_rspeed = 100;
+#ifdef SMC_DYNAMIC_BUS_CONFIG
+ irq_flags = lp->cfg.irq_flags;
+#else
+ irq_flags = IRQF_SHARED | SMC_IRQ_SENSE;
+#endif
+
/* Grab the IRQ */
retval = request_irq(dev->irq, &smc911x_interrupt,
- IRQF_SHARED | SMC_IRQ_SENSE, dev->name, dev);
+ irq_flags, dev->name, dev);
if (retval)
goto err_out;
@@ -2111,6 +2051,7 @@ err_out:
*/
static int smc911x_drv_probe(struct platform_device *pdev)
{
+ struct smc91x_platdata *pd = pdev->dev.platform_data;
struct net_device *ndev;
struct resource *res;
struct smc911x_local *lp;
@@ -2144,6 +2085,13 @@ static int smc911x_drv_probe(struct platform_device *pdev)
ndev->irq = platform_get_irq(pdev, 0);
lp = netdev_priv(ndev);
lp->netdev = ndev;
+#ifdef SMC_DYNAMIC_BUS_CONFIG
+ if (!pd) {
+ ret = -EINVAL;
+ goto release_both;
+ }
+ memcpy(&lp->cfg, pd, sizeof(lp->cfg));
+#endif
addr = ioremap(res->start, SMC911X_IO_EXTENT);
if (!addr) {
@@ -2152,7 +2100,9 @@ static int smc911x_drv_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, ndev);
- ret = smc911x_probe(ndev, (unsigned long)addr);
+ lp->base = addr;
+ ndev->base_addr = res->start;
+ ret = smc911x_probe(ndev);
if (ret != 0) {
platform_set_drvdata(pdev, NULL);
iounmap(addr);
@@ -2176,6 +2126,7 @@ out:
static int smc911x_drv_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
+ struct smc911x_local *lp = netdev_priv(ndev);
struct resource *res;
DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
@@ -2187,7 +2138,6 @@ static int smc911x_drv_remove(struct platform_device *pdev)
#ifdef SMC_USE_DMA
{
- struct smc911x_local *lp = netdev_priv(ndev);
if (lp->rxdma != -1) {
SMC_DMA_FREE(dev, lp->rxdma);
}
@@ -2196,7 +2146,7 @@ static int smc911x_drv_remove(struct platform_device *pdev)
}
}
#endif
- iounmap((void *)ndev->base_addr);
+ iounmap(lp->base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, SMC911X_IO_EXTENT);
@@ -2207,7 +2157,7 @@ static int smc911x_drv_remove(struct platform_device *pdev)
static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state)
{
struct net_device *ndev = platform_get_drvdata(dev);
- unsigned long ioaddr = ndev->base_addr;
+ struct smc911x_local *lp = netdev_priv(ndev);
DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
if (ndev) {
@@ -2216,7 +2166,7 @@ static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state)
smc911x_shutdown(ndev);
#if POWER_DOWN
/* Set D2 - Energy detect only setting */
- SMC_SET_PMT_CTRL(2<<12);
+ SMC_SET_PMT_CTRL(lp, 2<<12);
#endif
}
}
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 7defa63b9c7..76c17c28fab 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -29,6 +29,7 @@
#ifndef _SMC911X_H_
#define _SMC911X_H_
+#include <linux/smc911x.h>
/*
* Use the DMA feature on PXA chips
*/
@@ -38,42 +39,160 @@
#define SMC_USE_32BIT 1
#define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING
#elif defined(CONFIG_SH_MAGIC_PANEL_R2)
- #define SMC_USE_SH_DMA 0
#define SMC_USE_16BIT 0
#define SMC_USE_32BIT 1
#define SMC_IRQ_SENSE IRQF_TRIGGER_LOW
+#else
+/*
+ * Default configuration
+ */
+
+#define SMC_DYNAMIC_BUS_CONFIG
#endif
+/* store this information for the driver.. */
+struct smc911x_local {
+ /*
+ * If I have to wait until the DMA is finished and ready to reload a
+ * packet, I will store the skbuff here. Then, the DMA will send it
+ * out and free it.
+ */
+ struct sk_buff *pending_tx_skb;
+
+ /* version/revision of the SMC911x chip */
+ u16 version;
+ u16 revision;
+
+ /* FIFO sizes */
+ int tx_fifo_kb;
+ int tx_fifo_size;
+ int rx_fifo_size;
+ int afc_cfg;
+
+ /* Contains the current active receive/phy mode */
+ int ctl_rfduplx;
+ int ctl_rspeed;
+
+ u32 msg_enable;
+ u32 phy_type;
+ struct mii_if_info mii;
+
+ /* work queue */
+ struct work_struct phy_configure;
+
+ int tx_throttle;
+ spinlock_t lock;
+
+ struct net_device *netdev;
+
+#ifdef SMC_USE_DMA
+ /* DMA needs the physical address of the chip */
+ u_long physaddr;
+ int rxdma;
+ int txdma;
+ int rxdma_active;
+ int txdma_active;
+ struct sk_buff *current_rx_skb;
+ struct sk_buff *current_tx_skb;
+ struct device *dev;
+#endif
+ void __iomem *base;
+#ifdef SMC_DYNAMIC_BUS_CONFIG
+ struct smc911x_platdata cfg;
+#endif
+};
/*
* Define the bus width specific IO macros
*/
+#ifdef SMC_DYNAMIC_BUS_CONFIG
+static inline unsigned int SMC_inl(struct smc911x_local *lp, int reg)
+{
+ void __iomem *ioaddr = lp->base + reg;
+
+ if (lp->cfg.flags & SMC911X_USE_32BIT)
+ return readl(ioaddr);
+
+ if (lp->cfg.flags & SMC911X_USE_16BIT)
+ return readw(ioaddr) | (readw(ioaddr + 2) << 16);
+
+ BUG();
+}
+
+static inline void SMC_outl(unsigned int value, struct smc911x_local *lp,
+ int reg)
+{
+ void __iomem *ioaddr = lp->base + reg;
+
+ if (lp->cfg.flags & SMC911X_USE_32BIT) {
+ writel(value, ioaddr);
+ return;
+ }
+
+ if (lp->cfg.flags & SMC911X_USE_16BIT) {
+ writew(value & 0xffff, ioaddr);
+ writew(value >> 16, ioaddr + 2);
+ return;
+ }
+
+ BUG();
+}
+
+static inline void SMC_insl(struct smc911x_local *lp, int reg,
+ void *addr, unsigned int count)
+{
+ void __iomem *ioaddr = lp->base + reg;
+
+ if (lp->cfg.flags & SMC911X_USE_32BIT) {
+ readsl(ioaddr, addr, count);
+ return;
+ }
+
+ if (lp->cfg.flags & SMC911X_USE_16BIT) {
+ readsw(ioaddr, addr, count * 2);
+ return;
+ }
+
+ BUG();
+}
+
+static inline void SMC_outsl(struct smc911x_local *lp, int reg,
+ void *addr, unsigned int count)
+{
+ void __iomem *ioaddr = lp->base + reg;
+
+ if (lp->cfg.flags & SMC911X_USE_32BIT) {
+ writesl(ioaddr, addr, count);
+ return;
+ }
+
+ if (lp->cfg.flags & SMC911X_USE_16BIT) {
+ writesw(ioaddr, addr, count * 2);
+ return;
+ }
+
+ BUG();
+}
+#else
#if SMC_USE_16BIT
-#define SMC_inb(a, r) readb((a) + (r))
-#define SMC_inw(a, r) readw((a) + (r))
-#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16))
-#define SMC_outb(v, a, r) writeb(v, (a) + (r))
-#define SMC_outw(v, a, r) writew(v, (a) + (r))
-#define SMC_outl(v, a, r) \
+#define SMC_inl(lp, r) ((readw((lp)->base + (r)) & 0xFFFF) + (readw((lp)->base + (r) + 2) << 16))
+#define SMC_outl(v, lp, r) \
do{ \
- writel(v & 0xFFFF, (a) + (r)); \
- writel(v >> 16, (a) + (r) + 2); \
+ writew(v & 0xFFFF, (lp)->base + (r)); \
+ writew(v >> 16, (lp)->base + (r) + 2); \
} while (0)
-#define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2)
-#define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2)
+#define SMC_insl(lp, r, p, l) readsw((short*)((lp)->base + (r)), p, l*2)
+#define SMC_outsl(lp, r, p, l) writesw((short*)((lp)->base + (r)), p, l*2)
#elif SMC_USE_32BIT
-#define SMC_inb(a, r) readb((a) + (r))
-#define SMC_inw(a, r) readw((a) + (r))
-#define SMC_inl(a, r) readl((a) + (r))
-#define SMC_outb(v, a, r) writeb(v, (a) + (r))
-#define SMC_outl(v, a, r) writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l) readsl((int*)((a) + (r)), p, l)
-#define SMC_outsl(a, r, p, l) writesl((int*)((a) + (r)), p, l)
+#define SMC_inl(lp, r) readl((lp)->base + (r))
+#define SMC_outl(v, lp, r) writel(v, (lp)->base + (r))
+#define SMC_insl(lp, r, p, l) readsl((int*)((lp)->base + (r)), p, l)
+#define SMC_outsl(lp, r, p, l) writesl((int*)((lp)->base + (r)), p, l)
#endif /* SMC_USE_16BIT */
-
+#endif /* SMC_DYNAMIC_BUS_CONFIG */
#ifdef SMC_USE_PXA_DMA
@@ -110,22 +229,22 @@ static int rx_dmalen, tx_dmalen;
#ifdef SMC_insl
#undef SMC_insl
-#define SMC_insl(a, r, p, l) \
- smc_pxa_dma_insl(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l)
+#define SMC_insl(lp, r, p, l) \
+ smc_pxa_dma_insl(lp, lp->physaddr, r, lp->rxdma, p, l)
static inline void
-smc_pxa_dma_insl(struct device *dev, u_long ioaddr, u_long physaddr,
+smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
int reg, int dma, u_char *buf, int len)
{
/* 64 bit alignment is required for memory to memory DMA */
if ((long)buf & 4) {
- *((u32 *)buf) = SMC_inl(ioaddr, reg);
+ *((u32 *)buf) = SMC_inl(lp, reg);
buf += 4;
len--;
}
len *= 4;
- rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
+ rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE);
rx_dmalen = len;
DCSR(dma) = DCSR_NODESC;
DTADR(dma) = rx_dmabuf;
@@ -136,52 +255,24 @@ smc_pxa_dma_insl(struct device *dev, u_long ioaddr, u_long physaddr,
}
#endif
-#ifdef SMC_insw
-#undef SMC_insw
-#define SMC_insw(a, r, p, l) \
- smc_pxa_dma_insw(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l)
-
-static inline void
-smc_pxa_dma_insw(struct device *dev, u_long ioaddr, u_long physaddr,
- int reg, int dma, u_char *buf, int len)
-{
- /* 64 bit alignment is required for memory to memory DMA */
- while ((long)buf & 6) {
- *((u16 *)buf) = SMC_inw(ioaddr, reg);
- buf += 2;
- len--;
- }
-
- len *= 2;
- rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
- rx_dmalen = len;
- DCSR(dma) = DCSR_NODESC;
- DTADR(dma) = rx_dmabuf;
- DSADR(dma) = physaddr + reg;
- DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
- DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
- DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-}
-#endif
-
#ifdef SMC_outsl
#undef SMC_outsl
-#define SMC_outsl(a, r, p, l) \
- smc_pxa_dma_outsl(lp->dev, a, lp->physaddr, r, lp->txdma, p, l)
+#define SMC_outsl(lp, r, p, l) \
+ smc_pxa_dma_outsl(lp, lp->physaddr, r, lp->txdma, p, l)
static inline void
-smc_pxa_dma_outsl(struct device *dev, u_long ioaddr, u_long physaddr,
+smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
int reg, int dma, u_char *buf, int len)
{
/* 64 bit alignment is required for memory to memory DMA */
if ((long)buf & 4) {
- SMC_outl(*((u32 *)buf), ioaddr, reg);
+ SMC_outl(*((u32 *)buf), lp, reg);
buf += 4;
len--;
}
len *= 4;
- tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE);
+ tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE);
tx_dmalen = len;
DCSR(dma) = DCSR_NODESC;
DSADR(dma) = tx_dmabuf;
@@ -191,35 +282,6 @@ smc_pxa_dma_outsl(struct device *dev, u_long ioaddr, u_long physaddr,
DCSR(dma) = DCSR_NODESC | DCSR_RUN;
}
#endif
-
-#ifdef SMC_outsw
-#undef SMC_outsw
-#define SMC_outsw(a, r, p, l) \
- smc_pxa_dma_outsw(lp->dev, a, lp->physaddr, r, lp->txdma, p, l)
-
-static inline void
-smc_pxa_dma_outsw(struct device *dev, u_long ioaddr, u_long physaddr,
- int reg, int dma, u_char *buf, int len)
-{
- /* 64 bit alignment is required for memory to memory DMA */
- while ((long)buf & 6) {
- SMC_outw(*((u16 *)buf), ioaddr, reg);
- buf += 2;
- len--;
- }
-
- len *= 2;
- tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE);
- tx_dmalen = len;
- DCSR(dma) = DCSR_NODESC;
- DSADR(dma) = tx_dmabuf;
- DTADR(dma) = physaddr + reg;
- DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
- DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
- DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-}
-#endif
-
#endif /* SMC_USE_PXA_DMA */
@@ -629,213 +691,213 @@ static const struct chip_id chip_ids[] = {
* capabilities. Please use those and not the in/out primitives.
*/
/* FIFO read/write macros */
-#define SMC_PUSH_DATA(p, l) SMC_outsl( ioaddr, TX_DATA_FIFO, p, (l) >> 2 )
-#define SMC_PULL_DATA(p, l) SMC_insl ( ioaddr, RX_DATA_FIFO, p, (l) >> 2 )
-#define SMC_SET_TX_FIFO(x) SMC_outl( x, ioaddr, TX_DATA_FIFO )
-#define SMC_GET_RX_FIFO() SMC_inl( ioaddr, RX_DATA_FIFO )
+#define SMC_PUSH_DATA(lp, p, l) SMC_outsl( lp, TX_DATA_FIFO, p, (l) >> 2 )
+#define SMC_PULL_DATA(lp, p, l) SMC_insl ( lp, RX_DATA_FIFO, p, (l) >> 2 )
+#define SMC_SET_TX_FIFO(lp, x) SMC_outl( x, lp, TX_DATA_FIFO )
+#define SMC_GET_RX_FIFO(lp) SMC_inl( lp, RX_DATA_FIFO )
/* I/O mapped register read/write macros */
-#define SMC_GET_TX_STS_FIFO() SMC_inl( ioaddr, TX_STATUS_FIFO )
-#define SMC_GET_RX_STS_FIFO() SMC_inl( ioaddr, RX_STATUS_FIFO )
-#define SMC_GET_RX_STS_FIFO_PEEK() SMC_inl( ioaddr, RX_STATUS_FIFO_PEEK )
-#define SMC_GET_PN() (SMC_inl( ioaddr, ID_REV ) >> 16)
-#define SMC_GET_REV() (SMC_inl( ioaddr, ID_REV ) & 0xFFFF)
-#define SMC_GET_IRQ_CFG() SMC_inl( ioaddr, INT_CFG )
-#define SMC_SET_IRQ_CFG(x) SMC_outl( x, ioaddr, INT_CFG )
-#define SMC_GET_INT() SMC_inl( ioaddr, INT_STS )
-#define SMC_ACK_INT(x) SMC_outl( x, ioaddr, INT_STS )
-#define SMC_GET_INT_EN() SMC_inl( ioaddr, INT_EN )
-#define SMC_SET_INT_EN(x) SMC_outl( x, ioaddr, INT_EN )
-#define SMC_GET_BYTE_TEST() SMC_inl( ioaddr, BYTE_TEST )
-#define SMC_SET_BYTE_TEST(x) SMC_outl( x, ioaddr, BYTE_TEST )
-#define SMC_GET_FIFO_INT() SMC_inl( ioaddr, FIFO_INT )
-#define SMC_SET_FIFO_INT(x) SMC_outl( x, ioaddr, FIFO_INT )
-#define SMC_SET_FIFO_TDA(x) \
+#define SMC_GET_TX_STS_FIFO(lp) SMC_inl( lp, TX_STATUS_FIFO )
+#define SMC_GET_RX_STS_FIFO(lp) SMC_inl( lp, RX_STATUS_FIFO )
+#define SMC_GET_RX_STS_FIFO_PEEK(lp) SMC_inl( lp, RX_STATUS_FIFO_PEEK )
+#define SMC_GET_PN(lp) (SMC_inl( lp, ID_REV ) >> 16)
+#define SMC_GET_REV(lp) (SMC_inl( lp, ID_REV ) & 0xFFFF)
+#define SMC_GET_IRQ_CFG(lp) SMC_inl( lp, INT_CFG )
+#define SMC_SET_IRQ_CFG(lp, x) SMC_outl( x, lp, INT_CFG )
+#define SMC_GET_INT(lp) SMC_inl( lp, INT_STS )
+#define SMC_ACK_INT(lp, x) SMC_outl( x, lp, INT_STS )
+#define SMC_GET_INT_EN(lp) SMC_inl( lp, INT_EN )
+#define SMC_SET_INT_EN(lp, x) SMC_outl( x, lp, INT_EN )
+#define SMC_GET_BYTE_TEST(lp) SMC_inl( lp, BYTE_TEST )
+#define SMC_SET_BYTE_TEST(lp, x) SMC_outl( x, lp, BYTE_TEST )
+#define SMC_GET_FIFO_INT(lp) SMC_inl( lp, FIFO_INT )
+#define SMC_SET_FIFO_INT(lp, x) SMC_outl( x, lp, FIFO_INT )
+#define SMC_SET_FIFO_TDA(lp, x) \
do { \
unsigned long __flags; \
int __mask; \
local_irq_save(__flags); \
- __mask = SMC_GET_FIFO_INT() & ~(0xFF<<24); \
- SMC_SET_FIFO_INT( __mask | (x)<<24 ); \
+ __mask = SMC_GET_FIFO_INT((lp)) & ~(0xFF<<24); \
+ SMC_SET_FIFO_INT( (lp), __mask | (x)<<24 ); \
local_irq_restore(__flags); \
} while (0)
-#define SMC_SET_FIFO_TSL(x) \
+#define SMC_SET_FIFO_TSL(lp, x) \
do { \
unsigned long __flags; \
int __mask; \
local_irq_save(__flags); \
- __mask = SMC_GET_FIFO_INT() & ~(0xFF<<16); \
- SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<16)); \
+ __mask = SMC_GET_FIFO_INT((lp)) & ~(0xFF<<16); \
+ SMC_SET_FIFO_INT( (lp), __mask | (((x) & 0xFF)<<16)); \
local_irq_restore(__flags); \
} while (0)
-#define SMC_SET_FIFO_RSA(x) \
+#define SMC_SET_FIFO_RSA(lp, x) \
do { \
unsigned long __flags; \
int __mask; \
local_irq_save(__flags); \
- __mask = SMC_GET_FIFO_INT() & ~(0xFF<<8); \
- SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<8)); \
+ __mask = SMC_GET_FIFO_INT((lp)) & ~(0xFF<<8); \
+ SMC_SET_FIFO_INT( (lp), __mask | (((x) & 0xFF)<<8)); \
local_irq_restore(__flags); \
} while (0)
-#define SMC_SET_FIFO_RSL(x) \
+#define SMC_SET_FIFO_RSL(lp, x) \
do { \
unsigned long __flags; \
int __mask; \
local_irq_save(__flags); \
- __mask = SMC_GET_FIFO_INT() & ~0xFF; \
- SMC_SET_FIFO_INT( __mask | ((x) & 0xFF)); \
+ __mask = SMC_GET_FIFO_INT((lp)) & ~0xFF; \
+ SMC_SET_FIFO_INT( (lp),__mask | ((x) & 0xFF)); \
local_irq_restore(__flags); \
} while (0)
-#define SMC_GET_RX_CFG() SMC_inl( ioaddr, RX_CFG )
-#define SMC_SET_RX_CFG(x) SMC_outl( x, ioaddr, RX_CFG )
-#define SMC_GET_TX_CFG() SMC_inl( ioaddr, TX_CFG )
-#define SMC_SET_TX_CFG(x) SMC_outl( x, ioaddr, TX_CFG )
-#define SMC_GET_HW_CFG() SMC_inl( ioaddr, HW_CFG )
-#define SMC_SET_HW_CFG(x) SMC_outl( x, ioaddr, HW_CFG )
-#define SMC_GET_RX_DP_CTRL() SMC_inl( ioaddr, RX_DP_CTRL )
-#define SMC_SET_RX_DP_CTRL(x) SMC_outl( x, ioaddr, RX_DP_CTRL )
-#define SMC_GET_PMT_CTRL() SMC_inl( ioaddr, PMT_CTRL )
-#define SMC_SET_PMT_CTRL(x) SMC_outl( x, ioaddr, PMT_CTRL )
-#define SMC_GET_GPIO_CFG() SMC_inl( ioaddr, GPIO_CFG )
-#define SMC_SET_GPIO_CFG(x) SMC_outl( x, ioaddr, GPIO_CFG )
-#define SMC_GET_RX_FIFO_INF() SMC_inl( ioaddr, RX_FIFO_INF )
-#define SMC_SET_RX_FIFO_INF(x) SMC_outl( x, ioaddr, RX_FIFO_INF )
-#define SMC_GET_TX_FIFO_INF() SMC_inl( ioaddr, TX_FIFO_INF )
-#define SMC_SET_TX_FIFO_INF(x) SMC_outl( x, ioaddr, TX_FIFO_INF )
-#define SMC_GET_GPT_CFG() SMC_inl( ioaddr, GPT_CFG )
-#define SMC_SET_GPT_CFG(x) SMC_outl( x, ioaddr, GPT_CFG )
-#define SMC_GET_RX_DROP() SMC_inl( ioaddr, RX_DROP )
-#define SMC_SET_RX_DROP(x) SMC_outl( x, ioaddr, RX_DROP )
-#define SMC_GET_MAC_CMD() SMC_inl( ioaddr, MAC_CSR_CMD )
-#define SMC_SET_MAC_CMD(x) SMC_outl( x, ioaddr, MAC_CSR_CMD )
-#define SMC_GET_MAC_DATA() SMC_inl( ioaddr, MAC_CSR_DATA )
-#define SMC_SET_MAC_DATA(x) SMC_outl( x, ioaddr, MAC_CSR_DATA )
-#define SMC_GET_AFC_CFG() SMC_inl( ioaddr, AFC_CFG )
-#define SMC_SET_AFC_CFG(x) SMC_outl( x, ioaddr, AFC_CFG )
-#define SMC_GET_E2P_CMD() SMC_inl( ioaddr, E2P_CMD )
-#define SMC_SET_E2P_CMD(x) SMC_outl( x, ioaddr, E2P_CMD )
-#define SMC_GET_E2P_DATA() SMC_inl( ioaddr, E2P_DATA )
-#define SMC_SET_E2P_DATA(x) SMC_outl( x, ioaddr, E2P_DATA )
+#define SMC_GET_RX_CFG(lp) SMC_inl( lp, RX_CFG )
+#define SMC_SET_RX_CFG(lp, x) SMC_outl( x, lp, RX_CFG )
+#define SMC_GET_TX_CFG(lp) SMC_inl( lp, TX_CFG )
+#define SMC_SET_TX_CFG(lp, x) SMC_outl( x, lp, TX_CFG )
+#define SMC_GET_HW_CFG(lp) SMC_inl( lp, HW_CFG )
+#define SMC_SET_HW_CFG(lp, x) SMC_outl( x, lp, HW_CFG )
+#define SMC_GET_RX_DP_CTRL(lp) SMC_inl( lp, RX_DP_CTRL )
+#define SMC_SET_RX_DP_CTRL(lp, x) SMC_outl( x, lp, RX_DP_CTRL )
+#define SMC_GET_PMT_CTRL(lp) SMC_inl( lp, PMT_CTRL )
+#define SMC_SET_PMT_CTRL(lp, x) SMC_outl( x, lp, PMT_CTRL )
+#define SMC_GET_GPIO_CFG(lp) SMC_inl( lp, GPIO_CFG )
+#define SMC_SET_GPIO_CFG(lp, x) SMC_outl( x, lp, GPIO_CFG )
+#define SMC_GET_RX_FIFO_INF(lp) SMC_inl( lp, RX_FIFO_INF )
+#define SMC_SET_RX_FIFO_INF(lp, x) SMC_outl( x, lp, RX_FIFO_INF )
+#define SMC_GET_TX_FIFO_INF(lp) SMC_inl( lp, TX_FIFO_INF )
+#define SMC_SET_TX_FIFO_INF(lp, x) SMC_outl( x, lp, TX_FIFO_INF )
+#define SMC_GET_GPT_CFG(lp) SMC_inl( lp, GPT_CFG )
+#define SMC_SET_GPT_CFG(lp, x) SMC_outl( x, lp, GPT_CFG )
+#define SMC_GET_RX_DROP(lp) SMC_inl( lp, RX_DROP )
+#define SMC_SET_RX_DROP(lp, x) SMC_outl( x, lp, RX_DROP )
+#define SMC_GET_MAC_CMD(lp) SMC_inl( lp, MAC_CSR_CMD )
+#define SMC_SET_MAC_CMD(lp, x) SMC_outl( x, lp, MAC_CSR_CMD )
+#define SMC_GET_MAC_DATA(lp) SMC_inl( lp, MAC_CSR_DATA )
+#define SMC_SET_MAC_DATA(lp, x) SMC_outl( x, lp, MAC_CSR_DATA )
+#define SMC_GET_AFC_CFG(lp) SMC_inl( lp, AFC_CFG )
+#define SMC_SET_AFC_CFG(lp, x) SMC_outl( x, lp, AFC_CFG )
+#define SMC_GET_E2P_CMD(lp) SMC_inl( lp, E2P_CMD )
+#define SMC_SET_E2P_CMD(lp, x) SMC_outl( x, lp, E2P_CMD )
+#define SMC_GET_E2P_DATA(lp) SMC_inl( lp, E2P_DATA )
+#define SMC_SET_E2P_DATA(lp, x) SMC_outl( x, lp, E2P_DATA )
/* MAC register read/write macros */
-#define SMC_GET_MAC_CSR(a,v) \
+#define SMC_GET_MAC_CSR(lp,a,v) \
do { \
- while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \
- SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | \
+ while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \
+ SMC_SET_MAC_CMD((lp),MAC_CSR_CMD_CSR_BUSY_ | \
MAC_CSR_CMD_R_NOT_W_ | (a) ); \
- while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \
- v = SMC_GET_MAC_DATA(); \
+ while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \
+ v = SMC_GET_MAC_DATA((lp)); \
} while (0)
-#define SMC_SET_MAC_CSR(a,v) \
+#define SMC_SET_MAC_CSR(lp,a,v) \
do { \
- while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \
- SMC_SET_MAC_DATA(v); \
- SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | (a) ); \
- while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \
+ while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \
+ SMC_SET_MAC_DATA((lp), v); \
+ SMC_SET_MAC_CMD((lp), MAC_CSR_CMD_CSR_BUSY_ | (a) ); \
+ while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \
} while (0)
-#define SMC_GET_MAC_CR(x) SMC_GET_MAC_CSR( MAC_CR, x )
-#define SMC_SET_MAC_CR(x) SMC_SET_MAC_CSR( MAC_CR, x )
-#define SMC_GET_ADDRH(x) SMC_GET_MAC_CSR( ADDRH, x )
-#define SMC_SET_ADDRH(x) SMC_SET_MAC_CSR( ADDRH, x )
-#define SMC_GET_ADDRL(x) SMC_GET_MAC_CSR( ADDRL, x )
-#define SMC_SET_ADDRL(x) SMC_SET_MAC_CSR( ADDRL, x )
-#define SMC_GET_HASHH(x) SMC_GET_MAC_CSR( HASHH, x )
-#define SMC_SET_HASHH(x) SMC_SET_MAC_CSR( HASHH, x )
-#define SMC_GET_HASHL(x) SMC_GET_MAC_CSR( HASHL, x )
-#define SMC_SET_HASHL(x) SMC_SET_MAC_CSR( HASHL, x )
-#define SMC_GET_MII_ACC(x) SMC_GET_MAC_CSR( MII_ACC, x )
-#define SMC_SET_MII_ACC(x) SMC_SET_MAC_CSR( MII_ACC, x )
-#define SMC_GET_MII_DATA(x) SMC_GET_MAC_CSR( MII_DATA, x )
-#define SMC_SET_MII_DATA(x) SMC_SET_MAC_CSR( MII_DATA, x )
-#define SMC_GET_FLOW(x) SMC_GET_MAC_CSR( FLOW, x )
-#define SMC_SET_FLOW(x) SMC_SET_MAC_CSR( FLOW, x )
-#define SMC_GET_VLAN1(x) SMC_GET_MAC_CSR( VLAN1, x )
-#define SMC_SET_VLAN1(x) SMC_SET_MAC_CSR( VLAN1, x )
-#define SMC_GET_VLAN2(x) SMC_GET_MAC_CSR( VLAN2, x )
-#define SMC_SET_VLAN2(x) SMC_SET_MAC_CSR( VLAN2, x )
-#define SMC_SET_WUFF(x) SMC_SET_MAC_CSR( WUFF, x )
-#define SMC_GET_WUCSR(x) SMC_GET_MAC_CSR( WUCSR, x )
-#define SMC_SET_WUCSR(x) SMC_SET_MAC_CSR( WUCSR, x )
+#define SMC_GET_MAC_CR(lp, x) SMC_GET_MAC_CSR( (lp), MAC_CR, x )
+#define SMC_SET_MAC_CR(lp, x) SMC_SET_MAC_CSR( (lp), MAC_CR, x )
+#define SMC_GET_ADDRH(lp, x) SMC_GET_MAC_CSR( (lp), ADDRH, x )
+#define SMC_SET_ADDRH(lp, x) SMC_SET_MAC_CSR( (lp), ADDRH, x )
+#define SMC_GET_ADDRL(lp, x) SMC_GET_MAC_CSR( (lp), ADDRL, x )
+#define SMC_SET_ADDRL(lp, x) SMC_SET_MAC_CSR( (lp), ADDRL, x )
+#define SMC_GET_HASHH(lp, x) SMC_GET_MAC_CSR( (lp), HASHH, x )
+#define SMC_SET_HASHH(lp, x) SMC_SET_MAC_CSR( (lp), HASHH, x )
+#define SMC_GET_HASHL(lp, x) SMC_GET_MAC_CSR( (lp), HASHL, x )
+#define SMC_SET_HASHL(lp, x) SMC_SET_MAC_CSR( (lp), HASHL, x )
+#define SMC_GET_MII_ACC(lp, x) SMC_GET_MAC_CSR( (lp), MII_ACC, x )
+#define SMC_SET_MII_ACC(lp, x) SMC_SET_MAC_CSR( (lp), MII_ACC, x )
+#define SMC_GET_MII_DATA(lp, x) SMC_GET_MAC_CSR( (lp), MII_DATA, x )
+#define SMC_SET_MII_DATA(lp, x) SMC_SET_MAC_CSR( (lp), MII_DATA, x )
+#define SMC_GET_FLOW(lp, x) SMC_GET_MAC_CSR( (lp), FLOW, x )
+#define SMC_SET_FLOW(lp, x) SMC_SET_MAC_CSR( (lp), FLOW, x )
+#define SMC_GET_VLAN1(lp, x) SMC_GET_MAC_CSR( (lp), VLAN1, x )
+#define SMC_SET_VLAN1(lp, x) SMC_SET_MAC_CSR( (lp), VLAN1, x )
+#define SMC_GET_VLAN2(lp, x) SMC_GET_MAC_CSR( (lp), VLAN2, x )
+#define SMC_SET_VLAN2(lp, x) SMC_SET_MAC_CSR( (lp), VLAN2, x )
+#define SMC_SET_WUFF(lp, x) SMC_SET_MAC_CSR( (lp), WUFF, x )
+#define SMC_GET_WUCSR(lp, x) SMC_GET_MAC_CSR( (lp), WUCSR, x )
+#define SMC_SET_WUCSR(lp, x) SMC_SET_MAC_CSR( (lp), WUCSR, x )
/* PHY register read/write macros */
-#define SMC_GET_MII(a,phy,v) \
+#define SMC_GET_MII(lp,a,phy,v) \
do { \
u32 __v; \
do { \
- SMC_GET_MII_ACC(__v); \
+ SMC_GET_MII_ACC((lp), __v); \
} while ( __v & MII_ACC_MII_BUSY_ ); \
- SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) | \
+ SMC_SET_MII_ACC( (lp), ((phy)<<11) | ((a)<<6) | \
MII_ACC_MII_BUSY_); \
do { \
- SMC_GET_MII_ACC(__v); \
+ SMC_GET_MII_ACC( (lp), __v); \
} while ( __v & MII_ACC_MII_BUSY_ ); \
- SMC_GET_MII_DATA(v); \
+ SMC_GET_MII_DATA((lp), v); \
} while (0)
-#define SMC_SET_MII(a,phy,v) \
+#define SMC_SET_MII(lp,a,phy,v) \
do { \
u32 __v; \
do { \
- SMC_GET_MII_ACC(__v); \
+ SMC_GET_MII_ACC((lp), __v); \
} while ( __v & MII_ACC_MII_BUSY_ ); \
- SMC_SET_MII_DATA(v); \
- SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) | \
+ SMC_SET_MII_DATA((lp), v); \
+ SMC_SET_MII_ACC( (lp), ((phy)<<11) | ((a)<<6) | \
MII_ACC_MII_BUSY_ | \
MII_ACC_MII_WRITE_ ); \
do { \
- SMC_GET_MII_ACC(__v); \
+ SMC_GET_MII_ACC((lp), __v); \
} while ( __v & MII_ACC_MII_BUSY_ ); \
} while (0)
-#define SMC_GET_PHY_BMCR(phy,x) SMC_GET_MII( MII_BMCR, phy, x )
-#define SMC_SET_PHY_BMCR(phy,x) SMC_SET_MII( MII_BMCR, phy, x )
-#define SMC_GET_PHY_BMSR(phy,x) SMC_GET_MII( MII_BMSR, phy, x )
-#define SMC_GET_PHY_ID1(phy,x) SMC_GET_MII( MII_PHYSID1, phy, x )
-#define SMC_GET_PHY_ID2(phy,x) SMC_GET_MII( MII_PHYSID2, phy, x )
-#define SMC_GET_PHY_MII_ADV(phy,x) SMC_GET_MII( MII_ADVERTISE, phy, x )
-#define SMC_SET_PHY_MII_ADV(phy,x) SMC_SET_MII( MII_ADVERTISE, phy, x )
-#define SMC_GET_PHY_MII_LPA(phy,x) SMC_GET_MII( MII_LPA, phy, x )
-#define SMC_SET_PHY_MII_LPA(phy,x) SMC_SET_MII( MII_LPA, phy, x )
-#define SMC_GET_PHY_CTRL_STS(phy,x) SMC_GET_MII( PHY_MODE_CTRL_STS, phy, x )
-#define SMC_SET_PHY_CTRL_STS(phy,x) SMC_SET_MII( PHY_MODE_CTRL_STS, phy, x )
-#define SMC_GET_PHY_INT_SRC(phy,x) SMC_GET_MII( PHY_INT_SRC, phy, x )
-#define SMC_SET_PHY_INT_SRC(phy,x) SMC_SET_MII( PHY_INT_SRC, phy, x )
-#define SMC_GET_PHY_INT_MASK(phy,x) SMC_GET_MII( PHY_INT_MASK, phy, x )
-#define SMC_SET_PHY_INT_MASK(phy,x) SMC_SET_MII( PHY_INT_MASK, phy, x )
-#define SMC_GET_PHY_SPECIAL(phy,x) SMC_GET_MII( PHY_SPECIAL, phy, x )
+#define SMC_GET_PHY_BMCR(lp,phy,x) SMC_GET_MII( (lp), MII_BMCR, phy, x )
+#define SMC_SET_PHY_BMCR(lp,phy,x) SMC_SET_MII( (lp), MII_BMCR, phy, x )
+#define SMC_GET_PHY_BMSR(lp,phy,x) SMC_GET_MII( (lp), MII_BMSR, phy, x )
+#define SMC_GET_PHY_ID1(lp,phy,x) SMC_GET_MII( (lp), MII_PHYSID1, phy, x )
+#define SMC_GET_PHY_ID2(lp,phy,x) SMC_GET_MII( (lp), MII_PHYSID2, phy, x )
+#define SMC_GET_PHY_MII_ADV(lp,phy,x) SMC_GET_MII( (lp), MII_ADVERTISE, phy, x )
+#define SMC_SET_PHY_MII_ADV(lp,phy,x) SMC_SET_MII( (lp), MII_ADVERTISE, phy, x )
+#define SMC_GET_PHY_MII_LPA(lp,phy,x) SMC_GET_MII( (lp), MII_LPA, phy, x )
+#define SMC_SET_PHY_MII_LPA(lp,phy,x) SMC_SET_MII( (lp), MII_LPA, phy, x )
+#define SMC_GET_PHY_CTRL_STS(lp,phy,x) SMC_GET_MII( (lp), PHY_MODE_CTRL_STS, phy, x )
+#define SMC_SET_PHY_CTRL_STS(lp,phy,x) SMC_SET_MII( (lp), PHY_MODE_CTRL_STS, phy, x )
+#define SMC_GET_PHY_INT_SRC(lp,phy,x) SMC_GET_MII( (lp), PHY_INT_SRC, phy, x )
+#define SMC_SET_PHY_INT_SRC(lp,phy,x) SMC_SET_MII( (lp), PHY_INT_SRC, phy, x )
+#define SMC_GET_PHY_INT_MASK(lp,phy,x) SMC_GET_MII( (lp), PHY_INT_MASK, phy, x )
+#define SMC_SET_PHY_INT_MASK(lp,phy,x) SMC_SET_MII( (lp), PHY_INT_MASK, phy, x )
+#define SMC_GET_PHY_SPECIAL(lp,phy,x) SMC_GET_MII( (lp), PHY_SPECIAL, phy, x )
/* Misc read/write macros */
#ifndef SMC_GET_MAC_ADDR
-#define SMC_GET_MAC_ADDR(addr) \
+#define SMC_GET_MAC_ADDR(lp, addr) \
do { \
unsigned int __v; \
\
- SMC_GET_MAC_CSR(ADDRL, __v); \
+ SMC_GET_MAC_CSR((lp), ADDRL, __v); \
addr[0] = __v; addr[1] = __v >> 8; \
addr[2] = __v >> 16; addr[3] = __v >> 24; \
- SMC_GET_MAC_CSR(ADDRH, __v); \
+ SMC_GET_MAC_CSR((lp), ADDRH, __v); \
addr[4] = __v; addr[5] = __v >> 8; \
} while (0)
#endif
-#define SMC_SET_MAC_ADDR(addr) \
+#define SMC_SET_MAC_ADDR(lp, addr) \
do { \
- SMC_SET_MAC_CSR(ADDRL, \
+ SMC_SET_MAC_CSR((lp), ADDRL, \
addr[0] | \
(addr[1] << 8) | \
(addr[2] << 16) | \
(addr[3] << 24)); \
- SMC_SET_MAC_CSR(ADDRH, addr[4]|(addr[5] << 8));\
+ SMC_SET_MAC_CSR((lp), ADDRH, addr[4]|(addr[5] << 8));\
} while (0)
-#define SMC_WRITE_EEPROM_CMD(cmd, addr) \
+#define SMC_WRITE_EEPROM_CMD(lp, cmd, addr) \
do { \
- while (SMC_GET_E2P_CMD() & MAC_CSR_CMD_CSR_BUSY_); \
- SMC_SET_MAC_CMD(MAC_CSR_CMD_R_NOT_W_ | a ); \
- while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \
+ while (SMC_GET_E2P_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \
+ SMC_SET_MAC_CMD((lp), MAC_CSR_CMD_R_NOT_W_ | a ); \
+ while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \
} while (0)
#endif /* _SMC911X_H_ */
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 47767160627..00aa0b108cb 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1704,7 +1704,7 @@ spider_net_poll_controller(struct net_device *netdev)
*
* spider_net_enable_interrupt enables several interrupts
*/
-static void
+static void
spider_net_enable_interrupts(struct spider_net_card *card)
{
spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
@@ -1721,7 +1721,7 @@ spider_net_enable_interrupts(struct spider_net_card *card)
*
* spider_net_disable_interrupts disables all the interrupts
*/
-static void
+static void
spider_net_disable_interrupts(struct spider_net_card *card)
{
spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 7b7b1717b0d..1d2ef8f4778 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -27,8 +27,8 @@
*/
#define DRV_NAME "starfire"
-#define DRV_VERSION "2.0"
-#define DRV_RELDATE "June 27, 2006"
+#define DRV_VERSION "2.1"
+#define DRV_RELDATE "July 6, 2008"
#include <linux/module.h>
#include <linux/kernel.h>
@@ -69,10 +69,6 @@
#define VLAN_SUPPORT
#endif
-#ifndef CONFIG_ADAPTEC_STARFIRE_NAPI
-#undef HAVE_NETDEV_POLL
-#endif
-
/* The user-configurable values.
These may be modified when a driver module is loaded.*/
@@ -177,44 +173,6 @@ static int full_duplex[MAX_UNITS] = {0, };
#define skb_first_frag_len(skb) skb_headlen(skb)
#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
-#ifdef HAVE_NETDEV_POLL
-#define init_poll(dev, np) \
- netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work)
-#define netdev_rx(dev, np, ioaddr) \
-do { \
- u32 intr_enable; \
- if (netif_rx_schedule_prep(dev, &np->napi)) { \
- __netif_rx_schedule(dev, &np->napi); \
- intr_enable = readl(ioaddr + IntrEnable); \
- intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
- writel(intr_enable, ioaddr + IntrEnable); \
- readl(ioaddr + IntrEnable); /* flush PCI posting buffers */ \
- } else { \
- /* Paranoia check */ \
- intr_enable = readl(ioaddr + IntrEnable); \
- if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \
- printk(KERN_INFO "%s: interrupt while in polling mode!\n", dev->name); \
- intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
- writel(intr_enable, ioaddr + IntrEnable); \
- } \
- } \
-} while (0)
-#define netdev_receive_skb(skb) netif_receive_skb(skb)
-#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid)
-static int netdev_poll(struct napi_struct *napi, int budget);
-#else /* not HAVE_NETDEV_POLL */
-#define init_poll(dev, np)
-#define netdev_receive_skb(skb) netif_rx(skb)
-#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid)
-#define netdev_rx(dev, np, ioaddr) \
-do { \
- int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \
- __netdev_rx(dev, &quota);\
-} while (0)
-#endif /* not HAVE_NETDEV_POLL */
-/* end of compatibility code */
-
-
/* These identify the driver base version and may not be removed. */
static char version[] =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
@@ -635,6 +593,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t intr_handler(int irq, void *dev_instance);
static void netdev_error(struct net_device *dev, int intr_status);
static int __netdev_rx(struct net_device *dev, int *quota);
+static int netdev_poll(struct napi_struct *napi, int budget);
static void refill_rx_ring(struct net_device *dev);
static void netdev_error(struct net_device *dev, int intr_status);
static void set_rx_mode(struct net_device *dev);
@@ -851,7 +810,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
dev->hard_start_xmit = &start_tx;
dev->tx_timeout = tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- init_poll(dev, np);
+ netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work);
dev->stop = &netdev_close;
dev->get_stats = &get_stats;
dev->set_multicast_list = &set_rx_mode;
@@ -1054,9 +1013,8 @@ static int netdev_open(struct net_device *dev)
writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
-#ifdef HAVE_NETDEV_POLL
napi_enable(&np->napi);
-#endif
+
netif_start_queue(dev);
if (debug > 1)
@@ -1330,8 +1288,28 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
handled = 1;
- if (intr_status & (IntrRxDone | IntrRxEmpty))
- netdev_rx(dev, np, ioaddr);
+ if (intr_status & (IntrRxDone | IntrRxEmpty)) {
+ u32 enable;
+
+ if (likely(netif_rx_schedule_prep(dev, &np->napi))) {
+ __netif_rx_schedule(dev, &np->napi);
+ enable = readl(ioaddr + IntrEnable);
+ enable &= ~(IntrRxDone | IntrRxEmpty);
+ writel(enable, ioaddr + IntrEnable);
+ /* flush PCI posting buffers */
+ readl(ioaddr + IntrEnable);
+ } else {
+ /* Paranoia check */
+ enable = readl(ioaddr + IntrEnable);
+ if (enable & (IntrRxDone | IntrRxEmpty)) {
+ printk(KERN_INFO
+ "%s: interrupt while in poll!\n",
+ dev->name);
+ enable &= ~(IntrRxDone | IntrRxEmpty);
+ writel(enable, ioaddr + IntrEnable);
+ }
+ }
+ }
/* Scavenge the skbuff list based on the Tx-done queue.
There are redundant checks here that may be cleaned up
@@ -1411,8 +1389,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
}
-/* This routine is logically part of the interrupt/poll handler, but separated
- for clarity, code sharing between NAPI/non-NAPI, and better register allocation. */
+/*
+ * This routine is logically part of the interrupt/poll handler, but separated
+ * for clarity and better register allocation.
+ */
static int __netdev_rx(struct net_device *dev, int *quota)
{
struct netdev_private *np = netdev_priv(dev);
@@ -1507,13 +1487,20 @@ static int __netdev_rx(struct net_device *dev, int *quota)
}
#ifdef VLAN_SUPPORT
if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
- if (debug > 4)
- printk(KERN_DEBUG " netdev_rx() vlanid = %d\n", le16_to_cpu(desc->vlanid));
- /* vlan_netdev_receive_skb() expects a packet with the VLAN tag stripped out */
- vlan_netdev_receive_skb(skb, np->vlgrp, le16_to_cpu(desc->vlanid) & VLAN_VID_MASK);
+ u16 vlid = le16_to_cpu(desc->vlanid);
+
+ if (debug > 4) {
+ printk(KERN_DEBUG " netdev_rx() vlanid = %d\n",
+ vlid);
+ }
+ /*
+ * vlan_hwaccel_rx expects a packet with the VLAN tag
+ * stripped out.
+ */
+ vlan_hwaccel_rx(skb, np->vlgrp, vlid);
} else
#endif /* VLAN_SUPPORT */
- netdev_receive_skb(skb);
+ netif_receive_skb(skb);
dev->last_rx = jiffies;
np->stats.rx_packets++;
@@ -1532,8 +1519,6 @@ static int __netdev_rx(struct net_device *dev, int *quota)
return retcode;
}
-
-#ifdef HAVE_NETDEV_POLL
static int netdev_poll(struct napi_struct *napi, int budget)
{
struct netdev_private *np = container_of(napi, struct netdev_private, napi);
@@ -1564,8 +1549,6 @@ static int netdev_poll(struct napi_struct *napi, int budget)
/* Restart Rx engine if stopped. */
return budget - quota;
}
-#endif /* HAVE_NETDEV_POLL */
-
static void refill_rx_ring(struct net_device *dev)
{
@@ -1906,9 +1889,8 @@ static int netdev_close(struct net_device *dev)
int i;
netif_stop_queue(dev);
-#ifdef HAVE_NETDEV_POLL
+
napi_disable(&np->napi);
-#endif
if (debug > 1) {
printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
@@ -2044,11 +2026,8 @@ static int __init starfire_init (void)
/* when a module, this is printed whether or not devices are found in probe */
#ifdef MODULE
printk(version);
-#ifdef HAVE_NETDEV_POLL
+
printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
-#else
- printk(KERN_INFO DRV_NAME ": polling (NAPI) disabled\n");
-#endif
#endif
/* we can do this test only at run-time... sigh */
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 26ade68aeab..4e994f87469 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -915,15 +915,11 @@ static void build_fake_packet(struct lance_private *lp)
lp->tx_new = TX_NEXT(entry);
}
-struct net_device *last_dev;
-
static int lance_open(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
int status = 0;
- last_dev = dev;
-
STOP_LANCE(lp);
if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED,
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index b07b8cbadea..41d3ac45685 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -672,7 +672,7 @@ static void tc_handle_link_change(struct net_device *dev)
if (dev->flags & IFF_PROMISC)
tc35815_set_multicast_list(dev);
#endif
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
} else {
lp->speed = 0;
lp->duplex = -1;
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 432e837a176..91f9054a1d9 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -1165,7 +1165,7 @@ NETIF_RX_MUX(struct bdx_priv *priv, u32 rxd_val1, u16 rxd_vlan,
GET_RXD_VLAN_ID(rxd_vlan))->name);
/* NAPI variant of receive functions */
vlan_hwaccel_receive_skb(skb, priv->vlgrp,
- GET_RXD_VLAN_ID(rxd_vlan));
+ GET_RXD_VLAN_TCI(rxd_vlan));
} else {
netif_receive_skb(skb);
}
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index efd170f451b..c66dfc9ec1e 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -309,6 +309,7 @@ struct rxf_desc {
#define GET_RXD_PKT_ID(x) GET_BITS_SHIFT((x), 3, 28)
#define GET_RXD_VTAG(x) GET_BITS_SHIFT((x), 1, 31)
#define GET_RXD_VLAN_ID(x) GET_BITS_SHIFT((x), 12, 0)
+#define GET_RXD_VLAN_TCI(x) GET_BITS_SHIFT((x), 16, 0)
#define GET_RXD_CFI(x) GET_BITS_SHIFT((x), 1, 12)
#define GET_RXD_PRIO(x) GET_BITS_SHIFT((x), 3, 13)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index cc4bde85254..633c128a622 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -32,6 +32,8 @@
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/brcmphy.h>
#include <linux/if_vlan.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -64,8 +66,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.92.1"
-#define DRV_MODULE_RELDATE "June 9, 2008"
+#define DRV_MODULE_VERSION "3.93"
+#define DRV_MODULE_RELDATE "May 22, 2008"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -203,6 +205,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -804,6 +807,569 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
return ret;
}
+static int tg3_bmcr_reset(struct tg3 *tp)
+{
+ u32 phy_control;
+ int limit, err;
+
+ /* OK, reset it, and poll the BMCR_RESET bit until it
+ * clears or we time out.
+ */
+ phy_control = BMCR_RESET;
+ err = tg3_writephy(tp, MII_BMCR, phy_control);
+ if (err != 0)
+ return -EBUSY;
+
+ limit = 5000;
+ while (limit--) {
+ err = tg3_readphy(tp, MII_BMCR, &phy_control);
+ if (err != 0)
+ return -EBUSY;
+
+ if ((phy_control & BMCR_RESET) == 0) {
+ udelay(40);
+ break;
+ }
+ udelay(10);
+ }
+ if (limit <= 0)
+ return -EBUSY;
+
+ return 0;
+}
+
+static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
+{
+ struct tg3 *tp = (struct tg3 *)bp->priv;
+ u32 val;
+
+ if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
+ return -EAGAIN;
+
+ if (tg3_readphy(tp, reg, &val))
+ return -EIO;
+
+ return val;
+}
+
+static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
+{
+ struct tg3 *tp = (struct tg3 *)bp->priv;
+
+ if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
+ return -EAGAIN;
+
+ if (tg3_writephy(tp, reg, val))
+ return -EIO;
+
+ return 0;
+}
+
+static int tg3_mdio_reset(struct mii_bus *bp)
+{
+ return 0;
+}
+
+static void tg3_mdio_config(struct tg3 *tp)
+{
+ u32 val;
+
+ if (tp->mdio_bus.phy_map[PHY_ADDR]->interface !=
+ PHY_INTERFACE_MODE_RGMII)
+ return;
+
+ val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
+ MAC_PHYCFG1_RGMII_SND_STAT_EN);
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+ val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+ val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
+ }
+ tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV);
+
+ val = tr32(MAC_PHYCFG2) & ~(MAC_PHYCFG2_INBAND_ENABLE);
+ if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
+ val |= MAC_PHYCFG2_INBAND_ENABLE;
+ tw32(MAC_PHYCFG2, val);
+
+ val = tr32(MAC_EXT_RGMII_MODE);
+ val &= ~(MAC_RGMII_MODE_RX_INT_B |
+ MAC_RGMII_MODE_RX_QUALITY |
+ MAC_RGMII_MODE_RX_ACTIVITY |
+ MAC_RGMII_MODE_RX_ENG_DET |
+ MAC_RGMII_MODE_TX_ENABLE |
+ MAC_RGMII_MODE_TX_LOWPWR |
+ MAC_RGMII_MODE_TX_RESET);
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+ val |= MAC_RGMII_MODE_RX_INT_B |
+ MAC_RGMII_MODE_RX_QUALITY |
+ MAC_RGMII_MODE_RX_ACTIVITY |
+ MAC_RGMII_MODE_RX_ENG_DET;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+ val |= MAC_RGMII_MODE_TX_ENABLE |
+ MAC_RGMII_MODE_TX_LOWPWR |
+ MAC_RGMII_MODE_TX_RESET;
+ }
+ tw32(MAC_EXT_RGMII_MODE, val);
+}
+
+static void tg3_mdio_start(struct tg3 *tp)
+{
+ if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
+ mutex_lock(&tp->mdio_bus.mdio_lock);
+ tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
+ mutex_unlock(&tp->mdio_bus.mdio_lock);
+ }
+
+ tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
+ tw32_f(MAC_MI_MODE, tp->mi_mode);
+ udelay(80);
+
+ if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)
+ tg3_mdio_config(tp);
+}
+
+static void tg3_mdio_stop(struct tg3 *tp)
+{
+ if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
+ mutex_lock(&tp->mdio_bus.mdio_lock);
+ tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
+ mutex_unlock(&tp->mdio_bus.mdio_lock);
+ }
+}
+
+static int tg3_mdio_init(struct tg3 *tp)
+{
+ int i;
+ u32 reg;
+ struct phy_device *phydev;
+ struct mii_bus *mdio_bus = &tp->mdio_bus;
+
+ tg3_mdio_start(tp);
+
+ if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
+ (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
+ return 0;
+
+ memset(mdio_bus, 0, sizeof(*mdio_bus));
+
+ mdio_bus->name = "tg3 mdio bus";
+ snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%x",
+ (tp->pdev->bus->number << 8) | tp->pdev->devfn);
+ mdio_bus->priv = tp;
+ mdio_bus->dev = &tp->pdev->dev;
+ mdio_bus->read = &tg3_mdio_read;
+ mdio_bus->write = &tg3_mdio_write;
+ mdio_bus->reset = &tg3_mdio_reset;
+ mdio_bus->phy_mask = ~(1 << PHY_ADDR);
+ mdio_bus->irq = &tp->mdio_irq[0];
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ mdio_bus->irq[i] = PHY_POLL;
+
+ /* The bus registration will look for all the PHYs on the mdio bus.
+ * Unfortunately, it does not ensure the PHY is powered up before
+ * accessing the PHY ID registers. A chip reset is the
+ * quickest way to bring the device back to an operational state..
+ */
+ if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN))
+ tg3_bmcr_reset(tp);
+
+ i = mdiobus_register(mdio_bus);
+ if (i) {
+ printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
+ tp->dev->name, i);
+ return i;
+ }
+
+ tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
+
+ phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+
+ switch (phydev->phy_id) {
+ case TG3_PHY_ID_BCM50610:
+ phydev->interface = PHY_INTERFACE_MODE_RGMII;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
+ phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+ phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+ phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
+ break;
+ case TG3_PHY_ID_BCMAC131:
+ phydev->interface = PHY_INTERFACE_MODE_MII;
+ break;
+ }
+
+ tg3_mdio_config(tp);
+
+ return 0;
+}
+
+static void tg3_mdio_fini(struct tg3 *tp)
+{
+ if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
+ tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
+ mdiobus_unregister(&tp->mdio_bus);
+ tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_wait_for_event_ack(struct tg3 *tp)
+{
+ int i;
+
+ /* Wait for up to 2.5 milliseconds */
+ for (i = 0; i < 250000; i++) {
+ if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
+ break;
+ udelay(10);
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_ump_link_report(struct tg3 *tp)
+{
+ u32 reg;
+ u32 val;
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ return;
+
+ tg3_wait_for_event_ack(tp);
+
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
+
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
+
+ val = 0;
+ if (!tg3_readphy(tp, MII_BMCR, &reg))
+ val = reg << 16;
+ if (!tg3_readphy(tp, MII_BMSR, &reg))
+ val |= (reg & 0xffff);
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
+
+ val = 0;
+ if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
+ val = reg << 16;
+ if (!tg3_readphy(tp, MII_LPA, &reg))
+ val |= (reg & 0xffff);
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
+
+ val = 0;
+ if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) {
+ if (!tg3_readphy(tp, MII_CTRL1000, &reg))
+ val = reg << 16;
+ if (!tg3_readphy(tp, MII_STAT1000, &reg))
+ val |= (reg & 0xffff);
+ }
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
+
+ if (!tg3_readphy(tp, MII_PHYADDR, &reg))
+ val = reg << 16;
+ else
+ val = 0;
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
+
+ val = tr32(GRC_RX_CPU_EVENT);
+ val |= GRC_RX_CPU_DRIVER_EVENT;
+ tw32_f(GRC_RX_CPU_EVENT, val);
+}
+
+static void tg3_link_report(struct tg3 *tp)
+{
+ if (!netif_carrier_ok(tp->dev)) {
+ if (netif_msg_link(tp))
+ printk(KERN_INFO PFX "%s: Link is down.\n",
+ tp->dev->name);
+ tg3_ump_link_report(tp);
+ } else if (netif_msg_link(tp)) {
+ printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
+ tp->dev->name,
+ (tp->link_config.active_speed == SPEED_1000 ?
+ 1000 :
+ (tp->link_config.active_speed == SPEED_100 ?
+ 100 : 10)),
+ (tp->link_config.active_duplex == DUPLEX_FULL ?
+ "full" : "half"));
+
+ printk(KERN_INFO PFX
+ "%s: Flow control is %s for TX and %s for RX.\n",
+ tp->dev->name,
+ (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
+ "on" : "off",
+ (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
+ "on" : "off");
+ tg3_ump_link_report(tp);
+ }
+}
+
+static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
+{
+ u16 miireg;
+
+ if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+ miireg = ADVERTISE_PAUSE_CAP;
+ else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+ miireg = ADVERTISE_PAUSE_ASYM;
+ else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+ miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ else
+ miireg = 0;
+
+ return miireg;
+}
+
+static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
+{
+ u16 miireg;
+
+ if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+ miireg = ADVERTISE_1000XPAUSE;
+ else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+ miireg = ADVERTISE_1000XPSE_ASYM;
+ else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+ miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
+ else
+ miireg = 0;
+
+ return miireg;
+}
+
+static u8 tg3_resolve_flowctrl_1000T(u16 lcladv, u16 rmtadv)
+{
+ u8 cap = 0;
+
+ if (lcladv & ADVERTISE_PAUSE_CAP) {
+ if (lcladv & ADVERTISE_PAUSE_ASYM) {
+ if (rmtadv & LPA_PAUSE_CAP)
+ cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+ else if (rmtadv & LPA_PAUSE_ASYM)
+ cap = TG3_FLOW_CTRL_RX;
+ } else {
+ if (rmtadv & LPA_PAUSE_CAP)
+ cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+ }
+ } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
+ if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
+ cap = TG3_FLOW_CTRL_TX;
+ }
+
+ return cap;
+}
+
+static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
+{
+ u8 cap = 0;
+
+ if (lcladv & ADVERTISE_1000XPAUSE) {
+ if (lcladv & ADVERTISE_1000XPSE_ASYM) {
+ if (rmtadv & LPA_1000XPAUSE)
+ cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+ else if (rmtadv & LPA_1000XPAUSE_ASYM)
+ cap = TG3_FLOW_CTRL_RX;
+ } else {
+ if (rmtadv & LPA_1000XPAUSE)
+ cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+ }
+ } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
+ if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
+ cap = TG3_FLOW_CTRL_TX;
+ }
+
+ return cap;
+}
+
+static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
+{
+ u8 autoneg;
+ u8 flowctrl = 0;
+ u32 old_rx_mode = tp->rx_mode;
+ u32 old_tx_mode = tp->tx_mode;
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+ autoneg = tp->mdio_bus.phy_map[PHY_ADDR]->autoneg;
+ else
+ autoneg = tp->link_config.autoneg;
+
+ if (autoneg == AUTONEG_ENABLE &&
+ (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
+ if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
+ flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
+ else
+ flowctrl = tg3_resolve_flowctrl_1000T(lcladv, rmtadv);
+ } else
+ flowctrl = tp->link_config.flowctrl;
+
+ tp->link_config.active_flowctrl = flowctrl;
+
+ if (flowctrl & TG3_FLOW_CTRL_RX)
+ tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
+ else
+ tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
+
+ if (old_rx_mode != tp->rx_mode)
+ tw32_f(MAC_RX_MODE, tp->rx_mode);
+
+ if (flowctrl & TG3_FLOW_CTRL_TX)
+ tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
+ else
+ tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
+
+ if (old_tx_mode != tp->tx_mode)
+ tw32_f(MAC_TX_MODE, tp->tx_mode);
+}
+
+static void tg3_adjust_link(struct net_device *dev)
+{
+ u8 oldflowctrl, linkmesg = 0;
+ u32 mac_mode, lcl_adv, rmt_adv;
+ struct tg3 *tp = netdev_priv(dev);
+ struct phy_device *phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+
+ spin_lock(&tp->lock);
+
+ mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
+ MAC_MODE_HALF_DUPLEX);
+
+ oldflowctrl = tp->link_config.active_flowctrl;
+
+ if (phydev->link) {
+ lcl_adv = 0;
+ rmt_adv = 0;
+
+ if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
+ mac_mode |= MAC_MODE_PORT_MODE_MII;
+ else
+ mac_mode |= MAC_MODE_PORT_MODE_GMII;
+
+ if (phydev->duplex == DUPLEX_HALF)
+ mac_mode |= MAC_MODE_HALF_DUPLEX;
+ else {
+ lcl_adv = tg3_advert_flowctrl_1000T(
+ tp->link_config.flowctrl);
+
+ if (phydev->pause)
+ rmt_adv = LPA_PAUSE_CAP;
+ if (phydev->asym_pause)
+ rmt_adv |= LPA_PAUSE_ASYM;
+ }
+
+ tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
+ } else
+ mac_mode |= MAC_MODE_PORT_MODE_GMII;
+
+ if (mac_mode != tp->mac_mode) {
+ tp->mac_mode = mac_mode;
+ tw32_f(MAC_MODE, tp->mac_mode);
+ udelay(40);
+ }
+
+ if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF)
+ tw32(MAC_TX_LENGTHS,
+ ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+ (6 << TX_LENGTHS_IPG_SHIFT) |
+ (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
+ else
+ tw32(MAC_TX_LENGTHS,
+ ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+ (6 << TX_LENGTHS_IPG_SHIFT) |
+ (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+
+ if ((phydev->link && tp->link_config.active_speed == SPEED_INVALID) ||
+ (!phydev->link && tp->link_config.active_speed != SPEED_INVALID) ||
+ phydev->speed != tp->link_config.active_speed ||
+ phydev->duplex != tp->link_config.active_duplex ||
+ oldflowctrl != tp->link_config.active_flowctrl)
+ linkmesg = 1;
+
+ tp->link_config.active_speed = phydev->speed;
+ tp->link_config.active_duplex = phydev->duplex;
+
+ spin_unlock(&tp->lock);
+
+ if (linkmesg)
+ tg3_link_report(tp);
+}
+
+static int tg3_phy_init(struct tg3 *tp)
+{
+ struct phy_device *phydev;
+
+ if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+ return 0;
+
+ /* Bring the PHY back to a known state. */
+ tg3_bmcr_reset(tp);
+
+ phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+
+ /* Attach the MAC to the PHY. */
+ phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link,
+ phydev->dev_flags, phydev->interface);
+ if (IS_ERR(phydev)) {
+ printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
+ return PTR_ERR(phydev);
+ }
+
+ tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
+
+ /* Mask with MAC supported features. */
+ phydev->supported &= (PHY_GBIT_FEATURES |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+
+ phydev->advertising = phydev->supported;
+
+ printk(KERN_INFO
+ "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+ tp->dev->name, phydev->drv->name, phydev->dev.bus_id);
+
+ return 0;
+}
+
+static void tg3_phy_start(struct tg3 *tp)
+{
+ struct phy_device *phydev;
+
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return;
+
+ phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+
+ if (tp->link_config.phy_is_low_power) {
+ tp->link_config.phy_is_low_power = 0;
+ phydev->speed = tp->link_config.orig_speed;
+ phydev->duplex = tp->link_config.orig_duplex;
+ phydev->autoneg = tp->link_config.orig_autoneg;
+ phydev->advertising = tp->link_config.orig_advertising;
+ }
+
+ phy_start(phydev);
+
+ phy_start_aneg(phydev);
+}
+
+static void tg3_phy_stop(struct tg3 *tp)
+{
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return;
+
+ phy_stop(tp->mdio_bus.phy_map[PHY_ADDR]);
+}
+
+static void tg3_phy_fini(struct tg3 *tp)
+{
+ if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+ phy_disconnect(tp->mdio_bus.phy_map[PHY_ADDR]);
+ tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
+ }
+}
+
static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
{
tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
@@ -861,37 +1427,6 @@ static void tg3_phy_set_wirespeed(struct tg3 *tp)
(val | (1 << 15) | (1 << 4)));
}
-static int tg3_bmcr_reset(struct tg3 *tp)
-{
- u32 phy_control;
- int limit, err;
-
- /* OK, reset it, and poll the BMCR_RESET bit until it
- * clears or we time out.
- */
- phy_control = BMCR_RESET;
- err = tg3_writephy(tp, MII_BMCR, phy_control);
- if (err != 0)
- return -EBUSY;
-
- limit = 5000;
- while (limit--) {
- err = tg3_readphy(tp, MII_BMCR, &phy_control);
- if (err != 0)
- return -EBUSY;
-
- if ((phy_control & BMCR_RESET) == 0) {
- udelay(40);
- break;
- }
- udelay(10);
- }
- if (limit <= 0)
- return -EBUSY;
-
- return 0;
-}
-
static void tg3_phy_apply_otp(struct tg3 *tp)
{
u32 otp, phy;
@@ -1115,8 +1650,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
return err;
}
-static void tg3_link_report(struct tg3 *);
-
/* This will reset the tigon3 PHY if there is no valid
* link unless the FORCE argument is non-zero.
*/
@@ -1421,7 +1954,7 @@ static void tg3_power_down_phy(struct tg3 *tp)
tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
udelay(40);
return;
- } else {
+ } else if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
tg3_writephy(tp, MII_TG3_EXT_CTRL,
MII_TG3_EXT_CTRL_FORCE_LED_OFF);
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
@@ -1495,7 +2028,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
"requested.\n",
tp->dev->name, state);
return -EINVAL;
- };
+ }
power_control |= PCI_PM_CTRL_PME_ENABLE;
@@ -1503,18 +2036,55 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
tw32(TG3PCI_MISC_HOST_CTRL,
misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
- if (tp->link_config.phy_is_low_power == 0) {
- tp->link_config.phy_is_low_power = 1;
- tp->link_config.orig_speed = tp->link_config.speed;
- tp->link_config.orig_duplex = tp->link_config.duplex;
- tp->link_config.orig_autoneg = tp->link_config.autoneg;
- }
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
+ !tp->link_config.phy_is_low_power) {
+ struct phy_device *phydev;
+ u32 advertising;
+
+ phydev = tp->mdio_bus.phy_map[PHY_ADDR];
+
+ tp->link_config.phy_is_low_power = 1;
+
+ tp->link_config.orig_speed = phydev->speed;
+ tp->link_config.orig_duplex = phydev->duplex;
+ tp->link_config.orig_autoneg = phydev->autoneg;
+ tp->link_config.orig_advertising = phydev->advertising;
+
+ advertising = ADVERTISED_TP |
+ ADVERTISED_Pause |
+ ADVERTISED_Autoneg |
+ ADVERTISED_10baseT_Half;
+
+ if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+ (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+ if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
+ advertising |=
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_10baseT_Full;
+ else
+ advertising |= ADVERTISED_10baseT_Full;
+ }
- if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
- tp->link_config.speed = SPEED_10;
- tp->link_config.duplex = DUPLEX_HALF;
- tp->link_config.autoneg = AUTONEG_ENABLE;
- tg3_setup_phy(tp, 0);
+ phydev->advertising = advertising;
+
+ phy_start_aneg(phydev);
+ }
+ } else {
+ if (tp->link_config.phy_is_low_power == 0) {
+ tp->link_config.phy_is_low_power = 1;
+ tp->link_config.orig_speed = tp->link_config.speed;
+ tp->link_config.orig_duplex = tp->link_config.duplex;
+ tp->link_config.orig_autoneg = tp->link_config.autoneg;
+ }
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
+ tp->link_config.speed = SPEED_10;
+ tp->link_config.duplex = DUPLEX_HALF;
+ tp->link_config.autoneg = AUTONEG_ENABLE;
+ tg3_setup_phy(tp, 0);
+ }
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
@@ -1545,8 +2115,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
u32 mac_mode;
if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
- udelay(40);
+ if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+ udelay(40);
+ }
if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
mac_mode = MAC_MODE_PORT_MODE_GMII;
@@ -1671,212 +2243,6 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
return 0;
}
-/* tp->lock is held. */
-static void tg3_wait_for_event_ack(struct tg3 *tp)
-{
- int i;
-
- /* Wait for up to 2.5 milliseconds */
- for (i = 0; i < 250000; i++) {
- if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
- break;
- udelay(10);
- }
-}
-
-/* tp->lock is held. */
-static void tg3_ump_link_report(struct tg3 *tp)
-{
- u32 reg;
- u32 val;
-
- if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
- !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
- return;
-
- tg3_wait_for_event_ack(tp);
-
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
-
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
-
- val = 0;
- if (!tg3_readphy(tp, MII_BMCR, &reg))
- val = reg << 16;
- if (!tg3_readphy(tp, MII_BMSR, &reg))
- val |= (reg & 0xffff);
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
-
- val = 0;
- if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
- val = reg << 16;
- if (!tg3_readphy(tp, MII_LPA, &reg))
- val |= (reg & 0xffff);
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
-
- val = 0;
- if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) {
- if (!tg3_readphy(tp, MII_CTRL1000, &reg))
- val = reg << 16;
- if (!tg3_readphy(tp, MII_STAT1000, &reg))
- val |= (reg & 0xffff);
- }
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
-
- if (!tg3_readphy(tp, MII_PHYADDR, &reg))
- val = reg << 16;
- else
- val = 0;
- tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
-
- val = tr32(GRC_RX_CPU_EVENT);
- val |= GRC_RX_CPU_DRIVER_EVENT;
- tw32_f(GRC_RX_CPU_EVENT, val);
-}
-
-static void tg3_link_report(struct tg3 *tp)
-{
- if (!netif_carrier_ok(tp->dev)) {
- if (netif_msg_link(tp))
- printk(KERN_INFO PFX "%s: Link is down.\n",
- tp->dev->name);
- tg3_ump_link_report(tp);
- } else if (netif_msg_link(tp)) {
- printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
- tp->dev->name,
- (tp->link_config.active_speed == SPEED_1000 ?
- 1000 :
- (tp->link_config.active_speed == SPEED_100 ?
- 100 : 10)),
- (tp->link_config.active_duplex == DUPLEX_FULL ?
- "full" : "half"));
-
- printk(KERN_INFO PFX
- "%s: Flow control is %s for TX and %s for RX.\n",
- tp->dev->name,
- (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
- "on" : "off",
- (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
- "on" : "off");
- tg3_ump_link_report(tp);
- }
-}
-
-static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
-{
- u16 miireg;
-
- if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
- miireg = ADVERTISE_PAUSE_CAP;
- else if (flow_ctrl & TG3_FLOW_CTRL_TX)
- miireg = ADVERTISE_PAUSE_ASYM;
- else if (flow_ctrl & TG3_FLOW_CTRL_RX)
- miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
- else
- miireg = 0;
-
- return miireg;
-}
-
-static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
-{
- u16 miireg;
-
- if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
- miireg = ADVERTISE_1000XPAUSE;
- else if (flow_ctrl & TG3_FLOW_CTRL_TX)
- miireg = ADVERTISE_1000XPSE_ASYM;
- else if (flow_ctrl & TG3_FLOW_CTRL_RX)
- miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
- else
- miireg = 0;
-
- return miireg;
-}
-
-static u8 tg3_resolve_flowctrl_1000T(u16 lcladv, u16 rmtadv)
-{
- u8 cap = 0;
-
- if (lcladv & ADVERTISE_PAUSE_CAP) {
- if (lcladv & ADVERTISE_PAUSE_ASYM) {
- if (rmtadv & LPA_PAUSE_CAP)
- cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
- else if (rmtadv & LPA_PAUSE_ASYM)
- cap = TG3_FLOW_CTRL_RX;
- } else {
- if (rmtadv & LPA_PAUSE_CAP)
- cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
- }
- } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
- if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
- cap = TG3_FLOW_CTRL_TX;
- }
-
- return cap;
-}
-
-static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
-{
- u8 cap = 0;
-
- if (lcladv & ADVERTISE_1000XPAUSE) {
- if (lcladv & ADVERTISE_1000XPSE_ASYM) {
- if (rmtadv & LPA_1000XPAUSE)
- cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
- else if (rmtadv & LPA_1000XPAUSE_ASYM)
- cap = TG3_FLOW_CTRL_RX;
- } else {
- if (rmtadv & LPA_1000XPAUSE)
- cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
- }
- } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
- if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
- cap = TG3_FLOW_CTRL_TX;
- }
-
- return cap;
-}
-
-static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv)
-{
- u8 new_tg3_flags = 0;
- u32 old_rx_mode = tp->rx_mode;
- u32 old_tx_mode = tp->tx_mode;
-
- if (tp->link_config.autoneg == AUTONEG_ENABLE &&
- (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
- if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
- new_tg3_flags = tg3_resolve_flowctrl_1000X(local_adv,
- remote_adv);
- else
- new_tg3_flags = tg3_resolve_flowctrl_1000T(local_adv,
- remote_adv);
- } else {
- new_tg3_flags = tp->link_config.flowctrl;
- }
-
- tp->link_config.active_flowctrl = new_tg3_flags;
-
- if (new_tg3_flags & TG3_FLOW_CTRL_RX)
- tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
- else
- tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
-
- if (old_rx_mode != tp->rx_mode) {
- tw32_f(MAC_RX_MODE, tp->rx_mode);
- }
-
- if (new_tg3_flags & TG3_FLOW_CTRL_TX)
- tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
- else
- tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
-
- if (old_tx_mode != tp->tx_mode) {
- tw32_f(MAC_TX_MODE, tp->tx_mode);
- }
-}
-
static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
{
switch (val & MII_TG3_AUX_STAT_SPDMASK) {
@@ -1921,7 +2287,7 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
*speed = SPEED_INVALID;
*duplex = DUPLEX_INVALID;
break;
- };
+ }
}
static void tg3_phy_copper_begin(struct tg3 *tp)
@@ -2033,7 +2399,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
case SPEED_1000:
bmcr |= TG3_BMCR_SPEED1000;
break;
- };
+ }
if (tp->link_config.duplex == DUPLEX_FULL)
bmcr |= BMCR_FULLDPLX;
@@ -2731,7 +3097,7 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,
default:
ret = ANEG_FAILED;
break;
- };
+ }
return ret;
}
@@ -3572,7 +3938,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
default:
return -EINVAL;
- };
+ }
/* Do not overwrite any of the map or rp information
* until we are sure we can commit to a new buffer.
@@ -3632,7 +3998,7 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
default:
return;
- };
+ }
dest_map->skb = src_map->skb;
pci_unmap_addr_set(dest_map, mapping,
@@ -3842,7 +4208,15 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
sblk->status = SD_STATUS_UPDATED |
(sblk->status & ~SD_STATUS_LINK_CHG);
spin_lock(&tp->lock);
- tg3_setup_phy(tp, 0);
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ tw32_f(MAC_STATUS,
+ (MAC_STATUS_SYNC_CHANGED |
+ MAC_STATUS_CFG_CHANGED |
+ MAC_STATUS_MI_COMPLETION |
+ MAC_STATUS_LNKSTATE_CHANGED));
+ udelay(40);
+ } else
+ tg3_setup_phy(tp, 0);
spin_unlock(&tp->lock);
}
}
@@ -4130,6 +4504,7 @@ static void tg3_poll_controller(struct net_device *dev)
static void tg3_reset_task(struct work_struct *work)
{
struct tg3 *tp = container_of(work, struct tg3, reset_task);
+ int err;
unsigned int restart_timer;
tg3_full_lock(tp, 0);
@@ -4141,6 +4516,8 @@ static void tg3_reset_task(struct work_struct *work)
tg3_full_unlock(tp);
+ tg3_phy_stop(tp);
+
tg3_netif_stop(tp);
tg3_full_lock(tp, 1);
@@ -4156,7 +4533,8 @@ static void tg3_reset_task(struct work_struct *work)
}
tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
- if (tg3_init_hw(tp, 1))
+ err = tg3_init_hw(tp, 1);
+ if (err)
goto out;
tg3_netif_start(tp);
@@ -4166,6 +4544,9 @@ static void tg3_reset_task(struct work_struct *work)
out:
tg3_full_unlock(tp);
+
+ if (!err)
+ tg3_phy_start(tp);
}
static void tg3_dump_short_state(struct tg3 *tp)
@@ -4669,6 +5050,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+ tg3_phy_stop(tp);
+
tg3_netif_stop(tp);
tg3_full_lock(tp, 1);
@@ -4684,6 +5067,9 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
tg3_full_unlock(tp);
+ if (!err)
+ tg3_phy_start(tp);
+
return err;
}
@@ -4975,7 +5361,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int
default:
break;
- };
+ }
}
val = tr32(ofs);
@@ -5217,7 +5603,7 @@ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind)
default:
break;
- };
+ }
}
if (kind == RESET_KIND_INIT ||
@@ -5242,7 +5628,7 @@ static void tg3_write_sig_post_reset(struct tg3 *tp, int kind)
default:
break;
- };
+ }
}
if (kind == RESET_KIND_SHUTDOWN)
@@ -5271,7 +5657,7 @@ static void tg3_write_sig_legacy(struct tg3 *tp, int kind)
default:
break;
- };
+ }
}
}
@@ -5393,6 +5779,8 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_nvram_lock(tp);
+ tg3_mdio_stop(tp);
+
/* No matching tg3_nvram_unlock() after this because
* chip reset below will undo the nvram lock.
*/
@@ -5408,7 +5796,8 @@ static int tg3_chip_reset(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
tw32(GRC_FASTBOOT_PC, 0);
/*
@@ -5544,6 +5933,8 @@ static int tg3_chip_reset(struct tg3 *tp)
tw32_f(MAC_MODE, 0);
udelay(40);
+ tg3_mdio_start(tp);
+
err = tg3_poll_fw(tp);
if (err)
return err;
@@ -6623,7 +7014,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tg3_abort_hw(tp, 1);
}
- if (reset_phy)
+ if (reset_phy &&
+ !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB))
tg3_phy_reset(tp);
err = tg3_chip_reset(tp);
@@ -6699,7 +7091,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
return err;
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
/* This value is determined during the probe time DMA
* engine test, tg3_test_dma.
*/
@@ -6938,7 +7331,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
RDMAC_MODE_LNGREAD_ENAB);
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB |
RDMAC_MODE_MBUF_RBD_CRPT_ENAB |
RDMAC_MODE_MBUF_SBD_CRPT_ENAB;
@@ -7106,8 +7500,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) ||
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) ||
- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761))
- val |= (1 << 29);
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785))
+ val |= WDMAC_MODE_STATUS_TAG_FIX;
tw32_f(WDMAC_MODE, val);
udelay(40);
@@ -7168,23 +7563,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tp->rx_mode = RX_MODE_ENABLE;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
tw32_f(MAC_RX_MODE, tp->rx_mode);
udelay(10);
- if (tp->link_config.phy_is_low_power) {
- tp->link_config.phy_is_low_power = 0;
- tp->link_config.speed = tp->link_config.orig_speed;
- tp->link_config.duplex = tp->link_config.orig_duplex;
- tp->link_config.autoneg = tp->link_config.orig_autoneg;
- }
-
- tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
- tw32_f(MAC_MI_MODE, tp->mi_mode);
- udelay(80);
-
tw32(MAC_LED_CTRL, tp->led_ctrl);
tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
@@ -7231,19 +7617,28 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
}
- err = tg3_setup_phy(tp, 0);
- if (err)
- return err;
+ if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+ if (tp->link_config.phy_is_low_power) {
+ tp->link_config.phy_is_low_power = 0;
+ tp->link_config.speed = tp->link_config.orig_speed;
+ tp->link_config.duplex = tp->link_config.orig_duplex;
+ tp->link_config.autoneg = tp->link_config.orig_autoneg;
+ }
- if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
- u32 tmp;
+ err = tg3_setup_phy(tp, 0);
+ if (err)
+ return err;
- /* Clear CRC stats. */
- if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
- tg3_writephy(tp, MII_TG3_TEST1,
- tmp | MII_TG3_TEST1_CRC_EN);
- tg3_readphy(tp, 0x14, &tmp);
+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+ u32 tmp;
+
+ /* Clear CRC stats. */
+ if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
+ tg3_writephy(tp, MII_TG3_TEST1,
+ tmp | MII_TG3_TEST1_CRC_EN);
+ tg3_readphy(tp, 0x14, &tmp);
+ }
}
}
@@ -7296,7 +7691,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
default:
break;
- };
+ }
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
/* Write our heartbeat update interval to APE. */
@@ -7758,6 +8153,8 @@ static int tg3_open(struct net_device *dev)
}
}
+ tg3_phy_start(tp);
+
tg3_full_lock(tp, 0);
add_timer(&tp->timer);
@@ -8559,7 +8956,13 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- struct tg3 *tp = netdev_priv(dev);
+ struct tg3 *tp = netdev_priv(dev);
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+ return phy_ethtool_gset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
+ }
cmd->supported = (SUPPORTED_Autoneg);
@@ -8596,6 +8999,12 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct tg3 *tp = netdev_priv(dev);
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+ return phy_ethtool_sset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
+ }
+
if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
/* These are the only valid advertisement bits allowed. */
if (cmd->autoneg == AUTONEG_ENABLE &&
@@ -8628,7 +9037,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->link_config.advertising = 0;
tp->link_config.speed = cmd->speed;
tp->link_config.duplex = cmd->duplex;
- }
+ }
tp->link_config.orig_speed = tp->link_config.speed;
tp->link_config.orig_duplex = tp->link_config.duplex;
@@ -8711,7 +9120,10 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) {
if (value) {
dev->features |= NETIF_F_TSO6;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+ GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
dev->features |= NETIF_F_TSO_ECN;
} else
dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
@@ -8722,7 +9134,6 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
static int tg3_nway_reset(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
- u32 bmcr;
int r;
if (!netif_running(dev))
@@ -8731,17 +9142,25 @@ static int tg3_nway_reset(struct net_device *dev)
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
return -EINVAL;
- spin_lock_bh(&tp->lock);
- r = -EINVAL;
- tg3_readphy(tp, MII_BMCR, &bmcr);
- if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
- ((bmcr & BMCR_ANENABLE) ||
- (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
- tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
- BMCR_ANENABLE);
- r = 0;
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+ r = phy_start_aneg(tp->mdio_bus.phy_map[PHY_ADDR]);
+ } else {
+ u32 bmcr;
+
+ spin_lock_bh(&tp->lock);
+ r = -EINVAL;
+ tg3_readphy(tp, MII_BMCR, &bmcr);
+ if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
+ ((bmcr & BMCR_ANENABLE) ||
+ (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
+ tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
+ BMCR_ANENABLE);
+ r = 0;
+ }
+ spin_unlock_bh(&tp->lock);
}
- spin_unlock_bh(&tp->lock);
return r;
}
@@ -8783,6 +9202,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
return -EINVAL;
if (netif_running(dev)) {
+ tg3_phy_stop(tp);
tg3_netif_stop(tp);
irq_sync = 1;
}
@@ -8806,6 +9226,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tg3_full_unlock(tp);
+ if (irq_sync && !err)
+ tg3_phy_start(tp);
+
return err;
}
@@ -8829,36 +9252,92 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
{
struct tg3 *tp = netdev_priv(dev);
- int irq_sync = 0, err = 0;
+ int err = 0;
- if (netif_running(dev)) {
- tg3_netif_stop(tp);
- irq_sync = 1;
- }
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
- tg3_full_lock(tp, irq_sync);
+ if (epause->autoneg) {
+ u32 newadv;
+ struct phy_device *phydev;
- if (epause->autoneg)
- tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
- else
- tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
- if (epause->rx_pause)
- tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
- else
- tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
- if (epause->tx_pause)
- tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
- else
- tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+ phydev = tp->mdio_bus.phy_map[PHY_ADDR];
- if (netif_running(dev)) {
- tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- err = tg3_restart_hw(tp, 1);
- if (!err)
- tg3_netif_start(tp);
- }
+ if (epause->rx_pause) {
+ if (epause->tx_pause)
+ newadv = ADVERTISED_Pause;
+ else
+ newadv = ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause;
+ } else if (epause->tx_pause) {
+ newadv = ADVERTISED_Asym_Pause;
+ } else
+ newadv = 0;
+
+ if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+ u32 oldadv = phydev->advertising &
+ (ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ if (oldadv != newadv) {
+ phydev->advertising &=
+ ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ phydev->advertising |= newadv;
+ err = phy_start_aneg(phydev);
+ }
+ } else {
+ tp->link_config.advertising &=
+ ~(ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause);
+ tp->link_config.advertising |= newadv;
+ }
+ } else {
+ if (epause->rx_pause)
+ tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+ else
+ tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
- tg3_full_unlock(tp);
+ if (epause->tx_pause)
+ tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+ else
+ tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+
+ if (netif_running(dev))
+ tg3_setup_flow_control(tp, 0, 0);
+ }
+ } else {
+ int irq_sync = 0;
+
+ if (netif_running(dev)) {
+ tg3_netif_stop(tp);
+ irq_sync = 1;
+ }
+
+ tg3_full_lock(tp, irq_sync);
+
+ if (epause->autoneg)
+ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ else
+ tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+ if (epause->rx_pause)
+ tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
+ else
+ tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
+ if (epause->tx_pause)
+ tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
+ else
+ tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
+
+ if (netif_running(dev)) {
+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ err = tg3_restart_hw(tp, 1);
+ if (!err)
+ tg3_netif_start(tp);
+ }
+
+ tg3_full_unlock(tp);
+ }
return err;
}
@@ -8902,7 +9381,8 @@ static int tg3_set_tx_csum(struct net_device *dev, u32 data)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
ethtool_op_set_tx_ipv6_csum(dev, data);
else
ethtool_op_set_tx_csum(dev, data);
@@ -9423,7 +9903,8 @@ static int tg3_test_memory(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
mem_tbl = mem_tbl_5755;
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
mem_tbl = mem_tbl_5906;
@@ -9630,7 +10111,8 @@ static int tg3_test_loopback(struct tg3 *tp)
return TG3_LOOPBACK_FAILED;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
int i;
u32 status;
@@ -9658,14 +10140,16 @@ static int tg3_test_loopback(struct tg3 *tp)
err |= TG3_MAC_LOOPBACK_FAILED;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
tw32(TG3_CPMU_CTRL, cpmuctrl);
/* Release the mutex */
tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER);
}
- if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+ if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+ !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK))
err |= TG3_PHY_LOOPBACK_FAILED;
}
@@ -9692,9 +10176,10 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
data[1] = 1;
}
if (etest->flags & ETH_TEST_FL_OFFLINE) {
- int err, irq_sync = 0;
+ int err, err2 = 0, irq_sync = 0;
if (netif_running(dev)) {
+ tg3_phy_stop(tp);
tg3_netif_stop(tp);
irq_sync = 1;
}
@@ -9735,11 +10220,15 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
- if (!tg3_restart_hw(tp, 1))
+ err2 = tg3_restart_hw(tp, 1);
+ if (!err2)
tg3_netif_start(tp);
}
tg3_full_unlock(tp);
+
+ if (irq_sync && !err2)
+ tg3_phy_start(tp);
}
if (tp->link_config.phy_is_low_power)
tg3_set_power_state(tp, PCI_D3hot);
@@ -9752,6 +10241,12 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct tg3 *tp = netdev_priv(dev);
int err;
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+ return phy_mii_ioctl(tp->mdio_bus.phy_map[PHY_ADDR], data, cmd);
+ }
+
switch(cmd) {
case SIOCGMIIPHY:
data->phy_id = PHY_ADDR;
@@ -10294,7 +10789,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
tg3_get_5755_nvram_info(tp);
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
tg3_get_5787_nvram_info(tp);
else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
tg3_get_5761_nvram_info(tp);
@@ -10625,6 +11121,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) &&
+ (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) &&
(tp->nvram_jedecnum == JEDEC_ST) &&
(nvram_cmd & NVRAM_CMD_FIRST)) {
@@ -10807,7 +11304,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
if (val == NIC_SRAM_DATA_SIG_MAGIC) {
u32 nic_cfg, led_cfg;
- u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id;
+ u32 nic_phy_id, ver, cfg2 = 0, cfg4 = 0, eeprom_phy_id;
int eeprom_phy_serdes = 0;
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
@@ -10821,6 +11318,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
(ver > 0) && (ver < 0x100))
tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_4, &cfg4);
+
if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER)
eeprom_phy_serdes = 1;
@@ -10893,7 +11393,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
LED_CTRL_MODE_PHY_2);
break;
- };
+ }
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) &&
@@ -10945,6 +11445,13 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
}
+
+ if (cfg4 & NIC_SRAM_RGMII_STD_IBND_DISABLE)
+ tp->tg3_flags3 |= TG3_FLG3_RGMII_STD_IBND_DISABLE;
+ if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
+ tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
+ if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
+ tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
}
}
@@ -11003,6 +11510,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
u32 hw_phy_id, hw_phy_id_masked;
int err;
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+ return tg3_phy_init(tp);
+
/* Reading the PHY ID register can conflict with ASF
* firwmare access to the PHY hardware.
*/
@@ -11525,6 +12035,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
@@ -11546,6 +12057,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
@@ -11558,14 +12070,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
}
- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
@@ -11754,7 +12260,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
@@ -11847,7 +12354,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM;
- } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
}
@@ -11858,8 +12366,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->phy_otp = TG3_OTP_DEFAULT;
}
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)
tp->mi_mode = MAC_MI_MODE_500KHZ_CONST;
else
tp->mi_mode = MAC_MI_MODE_BASE;
@@ -11869,9 +12376,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
- /* Initialize MAC MI mode, polling disabled. */
- tw32_f(MAC_MI_MODE, tp->mi_mode);
- udelay(80);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+ tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
+
+ err = tg3_mdio_init(tp);
+ if (err)
+ return err;
/* Initialize data/descriptor byte/word swapping. */
val = tr32(GRC_MODE);
@@ -11952,6 +12462,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n",
pci_name(tp->pdev), err);
/* ... but do not return immediately ... */
+ tg3_mdio_fini(tp);
}
tg3_read_partno(tp);
@@ -11999,6 +12510,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
tp->dev->hard_start_xmit = tg3_start_xmit;
else
@@ -12201,7 +12713,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX |
DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
break;
- };
+ }
} else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
switch (cacheline_size) {
case 16:
@@ -12218,7 +12730,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE;
val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE;
break;
- };
+ }
} else {
switch (cacheline_size) {
case 16:
@@ -12262,7 +12774,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val)
val |= (DMA_RWCTRL_READ_BNDRY_1024 |
DMA_RWCTRL_WRITE_BNDRY_1024);
break;
- };
+ }
}
out:
@@ -12622,7 +13134,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
case PHY_ID_BCM8002: return "8002/serdes";
case 0: return "serdes";
default: return "unknown";
- };
+ }
}
static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
@@ -12923,7 +13435,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906))
dev->features |= NETIF_F_TSO6;
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+ GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
dev->features |= NETIF_F_TSO_ECN;
}
@@ -12989,7 +13504,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
dev->features |= NETIF_F_IPV6_CSUM;
tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
@@ -13071,6 +13587,12 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
struct tg3 *tp = netdev_priv(dev);
flush_scheduled_work();
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ tg3_phy_fini(tp);
+ tg3_mdio_fini(tp);
+ }
+
unregister_netdev(dev);
if (tp->aperegs) {
iounmap(tp->aperegs);
@@ -13103,6 +13625,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
flush_scheduled_work();
+ tg3_phy_stop(tp);
tg3_netif_stop(tp);
del_timer_sync(&tp->timer);
@@ -13120,10 +13643,13 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) {
+ int err2;
+
tg3_full_lock(tp, 0);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
- if (tg3_restart_hw(tp, 1))
+ err2 = tg3_restart_hw(tp, 1);
+ if (err2)
goto out;
tp->timer.expires = jiffies + tp->timer_offset;
@@ -13134,6 +13660,9 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
out:
tg3_full_unlock(tp);
+
+ if (!err2)
+ tg3_phy_start(tp);
}
return err;
@@ -13171,6 +13700,9 @@ static int tg3_resume(struct pci_dev *pdev)
out:
tg3_full_unlock(tp);
+ if (!err)
+ tg3_phy_start(tp);
+
return err;
}
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 0404f93baa2..df07842172b 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -128,6 +128,7 @@
#define ASIC_REV_USE_PROD_ID_REG 0x0f
#define ASIC_REV_5784 0x5784
#define ASIC_REV_5761 0x5761
+#define ASIC_REV_5785 0x5785
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
@@ -528,7 +529,23 @@
#define MAC_SERDES_CFG 0x00000590
#define MAC_SERDES_CFG_EDGE_SELECT 0x00001000
#define MAC_SERDES_STAT 0x00000594
-/* 0x598 --> 0x5b0 unused */
+/* 0x598 --> 0x5a0 unused */
+#define MAC_PHYCFG1 0x000005a0
+#define MAC_PHYCFG1_RGMII_INT 0x00000001
+#define MAC_PHYCFG1_RGMII_EXT_RX_DEC 0x02000000
+#define MAC_PHYCFG1_RGMII_SND_STAT_EN 0x04000000
+#define MAC_PHYCFG1_TXC_DRV 0x20000000
+#define MAC_PHYCFG2 0x000005a4
+#define MAC_PHYCFG2_INBAND_ENABLE 0x00000001
+#define MAC_EXT_RGMII_MODE 0x000005a8
+#define MAC_RGMII_MODE_TX_ENABLE 0x00000001
+#define MAC_RGMII_MODE_TX_LOWPWR 0x00000002
+#define MAC_RGMII_MODE_TX_RESET 0x00000004
+#define MAC_RGMII_MODE_RX_INT_B 0x00000100
+#define MAC_RGMII_MODE_RX_QUALITY 0x00000200
+#define MAC_RGMII_MODE_RX_ACTIVITY 0x00000400
+#define MAC_RGMII_MODE_RX_ENG_DET 0x00000800
+/* 0x5ac --> 0x5b0 unused */
#define SERDES_RX_CTRL 0x000005b0 /* 5780/5714 only */
#define SERDES_RX_SIG_DETECT 0x00000400
#define SG_DIG_CTRL 0x000005b0
@@ -1109,6 +1126,7 @@
#define WDMAC_MODE_FIFOOREAD_ENAB 0x00000100
#define WDMAC_MODE_LNGREAD_ENAB 0x00000200
#define WDMAC_MODE_RX_ACCEL 0x00000400
+#define WDMAC_MODE_STATUS_TAG_FIX 0x20000000
#define WDMAC_STATUS 0x00004c04
#define WDMAC_STATUS_TGTABORT 0x00000004
#define WDMAC_STATUS_MSTABORT 0x00000008
@@ -1713,6 +1731,12 @@
#define NIC_SRAM_DATA_CFG_3 0x00000d3c
#define NIC_SRAM_ASPM_DEBOUNCE 0x00000002
+#define NIC_SRAM_DATA_CFG_4 0x00000d60
+#define NIC_SRAM_GMII_MODE 0x00000002
+#define NIC_SRAM_RGMII_STD_IBND_DISABLE 0x00000004
+#define NIC_SRAM_RGMII_EXT_IBND_RX_EN 0x00000008
+#define NIC_SRAM_RGMII_EXT_IBND_TX_EN 0x00000010
+
#define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000
#define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000
@@ -2204,6 +2228,7 @@ struct tg3_link_config {
u16 orig_speed;
u8 orig_duplex;
u8 orig_autoneg;
+ u32 orig_advertising;
};
struct tg3_bufmgr_config {
@@ -2479,6 +2504,13 @@ struct tg3 {
#define TG3_FLG3_ENABLE_APE 0x00000002
#define TG3_FLG3_5761_5784_AX_FIXES 0x00000004
#define TG3_FLG3_5701_DMA_BUG 0x00000008
+#define TG3_FLG3_USE_PHYLIB 0x00000010
+#define TG3_FLG3_MDIOBUS_INITED 0x00000020
+#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
+#define TG3_FLG3_PHY_CONNECTED 0x00000080
+#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
+#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
+#define TG3_FLG3_RGMII_EXT_IBND_TX_EN 0x00000400
struct timer_list timer;
u16 timer_counter;
@@ -2519,6 +2551,9 @@ struct tg3 {
int msi_cap;
int pcix_cap;
+ struct mii_bus mdio_bus;
+ int mdio_irq[PHY_MAX_ADDR];
+
/* PHY info */
u32 phy_id;
#define PHY_ID_MASK 0xfffffff0
@@ -2546,6 +2581,9 @@ struct tg3 {
#define PHY_REV_BCM5401_B2 0x3
#define PHY_REV_BCM5401_C0 0x6
#define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */
+#define TG3_PHY_ID_BCM50610 0x143bd60
+#define TG3_PHY_ID_BCMAC131 0x143bc70
+
u32 led_ctrl;
u32 phy_otp;
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 0166407d706..85246ed7cb9 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -13,8 +13,6 @@
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
- ** This file is best viewed/edited with columns>=132.
- *
** Useful (if not required) reading:
*
* Texas Instruments, ThunderLAN Programmer's Guide,
@@ -218,9 +216,7 @@ static int bbuf;
module_param(bbuf, int, 0);
MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
-static u8 *TLanPadBuffer;
-static dma_addr_t TLanPadBufferDMA;
-static char TLanSignature[] = "TLAN";
+static const char TLanSignature[] = "TLAN";
static const char tlan_banner[] = "ThunderLAN driver v1.15\n";
static int tlan_have_pci;
static int tlan_have_eisa;
@@ -238,9 +234,11 @@ static struct board {
{ "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
{ "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
{ "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
- { "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
+ { "Compaq NetFlex-3/P",
+ TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
{ "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
- { "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
+ { "Compaq Netelligent Integrated 10/100 TX UTP",
+ TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
{ "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },
{ "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },
{ "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
@@ -248,8 +246,9 @@ static struct board {
{ "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },
{ "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
{ "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },
- { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
- TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
+ { "Compaq NetFlex-3/E",
+ TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
+ TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
{ "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
};
@@ -294,12 +293,12 @@ static int TLan_Close( struct net_device *);
static struct net_device_stats *TLan_GetStats( struct net_device *);
static void TLan_SetMulticastList( struct net_device *);
static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
-static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
+static int TLan_probe1( struct pci_dev *pdev, long ioaddr,
+ int irq, int rev, const struct pci_device_id *ent);
static void TLan_tx_timeout( struct net_device *dev);
static void TLan_tx_timeout_work(struct work_struct *work);
static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
-static u32 TLan_HandleInvalid( struct net_device *, u16 );
static u32 TLan_HandleTxEOF( struct net_device *, u16 );
static u32 TLan_HandleStatOverflow( struct net_device *, u16 );
static u32 TLan_HandleRxEOF( struct net_device *, u16 );
@@ -348,29 +347,27 @@ static void TLan_EeReceiveByte( u16, u8 *, int );
static int TLan_EeReadByte( struct net_device *, u8, u8 * );
-static void
+static inline void
TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb)
{
unsigned long addr = (unsigned long)skb;
- tag->buffer[9].address = (u32)addr;
- addr >>= 31; /* >>= 32 is undefined for 32bit arch, stupid C */
- addr >>= 1;
- tag->buffer[8].address = (u32)addr;
+ tag->buffer[9].address = addr;
+ tag->buffer[8].address = upper_32_bits(addr);
}
-static struct sk_buff *
-TLan_GetSKB( struct tlan_list_tag *tag)
+static inline struct sk_buff *
+TLan_GetSKB( const struct tlan_list_tag *tag)
{
- unsigned long addr = tag->buffer[8].address;
- addr <<= 31;
- addr <<= 1;
- addr |= tag->buffer[9].address;
+ unsigned long addr;
+
+ addr = tag->buffer[8].address;
+ addr |= (tag->buffer[9].address << 16) << 16;
return (struct sk_buff *) addr;
}
static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
- TLan_HandleInvalid,
+ NULL,
TLan_HandleTxEOF,
TLan_HandleStatOverflow,
TLan_HandleRxEOF,
@@ -444,7 +441,9 @@ static void __devexit tlan_remove_one( struct pci_dev *pdev)
unregister_netdev( dev );
if ( priv->dmaStorage ) {
- pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
+ pci_free_consistent(priv->pciDev,
+ priv->dmaSize, priv->dmaStorage,
+ priv->dmaStorageDMA );
}
#ifdef CONFIG_PCI
@@ -469,16 +468,6 @@ static int __init tlan_probe(void)
printk(KERN_INFO "%s", tlan_banner);
- TLanPadBuffer = (u8 *) pci_alloc_consistent(NULL, TLAN_MIN_FRAME_SIZE, &TLanPadBufferDMA);
-
- if (TLanPadBuffer == NULL) {
- printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
- rc = -ENOMEM;
- goto err_out;
- }
-
- memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
-
TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
/* Use new style PCI probing. Now the kernel will
@@ -506,8 +495,6 @@ static int __init tlan_probe(void)
err_out_pci_unreg:
pci_unregister_driver(&tlan_driver);
err_out_pci_free:
- pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA);
-err_out:
return rc;
}
@@ -539,7 +526,8 @@ static int __devinit tlan_init_one( struct pci_dev *pdev,
**************************************************************/
static int __devinit TLan_probe1(struct pci_dev *pdev,
- long ioaddr, int irq, int rev, const struct pci_device_id *ent )
+ long ioaddr, int irq, int rev,
+ const struct pci_device_id *ent )
{
struct net_device *dev;
@@ -625,8 +613,10 @@ static int __devinit TLan_probe1(struct pci_dev *pdev,
/* Kernel parameters */
if (dev->mem_start) {
priv->aui = dev->mem_start & 0x01;
- priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;
- priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;
+ priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
+ : (dev->mem_start & 0x06) >> 1;
+ priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
+ : (dev->mem_start & 0x18) >> 3;
if (priv->speed == 0x1) {
priv->speed = TLAN_SPEED_10;
@@ -706,7 +696,8 @@ static void TLan_Eisa_Cleanup(void)
dev = TLan_Eisa_Devices;
priv = netdev_priv(dev);
if (priv->dmaStorage) {
- pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
+ pci_free_consistent(priv->pciDev, priv->dmaSize,
+ priv->dmaStorage, priv->dmaStorageDMA );
}
release_region( dev->base_addr, 0x10);
unregister_netdev( dev );
@@ -724,8 +715,6 @@ static void __exit tlan_exit(void)
if (tlan_have_eisa)
TLan_Eisa_Cleanup();
- pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA);
-
}
@@ -763,8 +752,10 @@ static void __init TLan_EisaProbe (void)
/* Loop through all slots of the EISA bus */
for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));
- TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
+ TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n",
+ (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));
+ TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n",
+ (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
@@ -874,7 +865,8 @@ static int TLan_Init( struct net_device *dev )
dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
* ( sizeof(TLanList) );
}
- priv->dmaStorage = pci_alloc_consistent(priv->pciDev, dma_size, &priv->dmaStorageDMA);
+ priv->dmaStorage = pci_alloc_consistent(priv->pciDev,
+ dma_size, &priv->dmaStorageDMA);
priv->dmaSize = dma_size;
if ( priv->dmaStorage == NULL ) {
@@ -883,16 +875,19 @@ static int TLan_Init( struct net_device *dev )
return -ENOMEM;
}
memset( priv->dmaStorage, 0, dma_size );
- priv->rxList = (TLanList *)
- ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );
- priv->rxListDMA = ( ( ( (u32) priv->dmaStorageDMA ) + 7 ) & 0xFFFFFFF8 );
+ priv->rxList = (TLanList *) ALIGN((unsigned long)priv->dmaStorage, 8);
+ priv->rxListDMA = ALIGN(priv->dmaStorageDMA, 8);
priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS;
+
if ( bbuf ) {
priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
- priv->rxBufferDMA =priv->txListDMA + sizeof(TLanList) * TLAN_NUM_TX_LISTS;
- priv->txBuffer = priv->rxBuffer + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
- priv->txBufferDMA = priv->rxBufferDMA + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
+ priv->rxBufferDMA =priv->txListDMA
+ + sizeof(TLanList) * TLAN_NUM_TX_LISTS;
+ priv->txBuffer = priv->rxBuffer
+ + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
+ priv->txBufferDMA = priv->rxBufferDMA
+ + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
}
err = 0;
@@ -952,10 +947,12 @@ static int TLan_Open( struct net_device *dev )
int err;
priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
- err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED, TLanSignature, dev );
+ err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED,
+ dev->name, dev );
if ( err ) {
- printk(KERN_ERR "TLAN: Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
+ pr_err("TLAN: Cannot open %s because IRQ %d is already in use.\n",
+ dev->name, dev->irq );
return err;
}
@@ -969,7 +966,8 @@ static int TLan_Open( struct net_device *dev )
TLan_ReadAndClearStats( dev, TLAN_IGNORE );
TLan_ResetAdapter( dev );
- TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );
+ TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
+ dev->name, priv->tlanRev );
return 0;
@@ -1007,14 +1005,16 @@ static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case SIOCGMIIREG: /* Read MII PHY register. */
- TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out);
+ TLan_MiiReadReg(dev, data->phy_id & 0x1f,
+ data->reg_num & 0x1f, &data->val_out);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
+ TLan_MiiWriteReg(dev, data->phy_id & 0x1f,
+ data->reg_num & 0x1f, data->val_in);
return 0;
default:
return -EOPNOTSUPP;
@@ -1096,20 +1096,25 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
TLanList *tail_list;
dma_addr_t tail_list_phys;
u8 *tail_buffer;
- int pad;
unsigned long flags;
if ( ! priv->phyOnline ) {
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", dev->name );
+ TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
+ dev->name );
dev_kfree_skb_any(skb);
return 0;
}
+ if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
+ return 0;
+
tail_list = priv->txList + priv->txTail;
tail_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txTail;
if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) {
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", dev->name, priv->txHead, priv->txTail );
+ TLAN_DBG( TLAN_DEBUG_TX,
+ "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
+ dev->name, priv->txHead, priv->txTail );
netif_stop_queue(dev);
priv->txBusyCount++;
return 1;
@@ -1121,37 +1126,34 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
skb_copy_from_linear_data(skb, tail_buffer, skb->len);
} else {
- tail_list->buffer[0].address = pci_map_single(priv->pciDev, skb->data, skb->len, PCI_DMA_TODEVICE);
+ tail_list->buffer[0].address = pci_map_single(priv->pciDev,
+ skb->data, skb->len,
+ PCI_DMA_TODEVICE);
TLan_StoreSKB(tail_list, skb);
}
- pad = TLAN_MIN_FRAME_SIZE - skb->len;
-
- if ( pad > 0 ) {
- tail_list->frameSize = (u16) skb->len + pad;
- tail_list->buffer[0].count = (u32) skb->len;
- tail_list->buffer[1].count = TLAN_LAST_BUFFER | (u32) pad;
- tail_list->buffer[1].address = TLanPadBufferDMA;
- } else {
- tail_list->frameSize = (u16) skb->len;
- tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;
- tail_list->buffer[1].count = 0;
- tail_list->buffer[1].address = 0;
- }
+ tail_list->frameSize = (u16) skb->len;
+ tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;
+ tail_list->buffer[1].count = 0;
+ tail_list->buffer[1].address = 0;
spin_lock_irqsave(&priv->lock, flags);
tail_list->cStat = TLAN_CSTAT_READY;
if ( ! priv->txInProgress ) {
priv->txInProgress = 1;
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
+ TLAN_DBG( TLAN_DEBUG_TX,
+ "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
outl( tail_list_phys, dev->base_addr + TLAN_CH_PARM );
outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
} else {
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", priv->txTail );
+ TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n",
+ priv->txTail );
if ( priv->txTail == 0 ) {
- ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = tail_list_phys;
+ ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward
+ = tail_list_phys;
} else {
- ( priv->txList + ( priv->txTail - 1 ) )->forward = tail_list_phys;
+ ( priv->txList + ( priv->txTail - 1 ) )->forward
+ = tail_list_phys;
}
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1191,33 +1193,31 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id)
{
- u32 ack;
- struct net_device *dev;
- u32 host_cmd;
+ struct net_device *dev = dev_id;
+ TLanPrivateInfo *priv = netdev_priv(dev);
u16 host_int;
- int type;
- TLanPrivateInfo *priv;
-
- dev = dev_id;
- priv = netdev_priv(dev);
+ u16 type;
spin_lock(&priv->lock);
host_int = inw( dev->base_addr + TLAN_HOST_INT );
- outw( host_int, dev->base_addr + TLAN_HOST_INT );
-
type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
+ if ( type ) {
+ u32 ack;
+ u32 host_cmd;
- ack = TLanIntVector[type]( dev, host_int );
+ outw( host_int, dev->base_addr + TLAN_HOST_INT );
+ ack = TLanIntVector[type]( dev, host_int );
- if ( ack ) {
- host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
- outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
+ if ( ack ) {
+ host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
+ outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
+ }
}
spin_unlock(&priv->lock);
- return IRQ_HANDLED;
+ return IRQ_RETVAL(type);
} /* TLan_HandleInterrupts */
@@ -1286,8 +1286,10 @@ static struct net_device_stats *TLan_GetStats( struct net_device *dev )
/* Should only read stats if open ? */
TLan_ReadAndClearStats( dev, TLAN_RECORD );
- TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, priv->rxEocCount );
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, priv->txBusyCount );
+ TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
+ priv->rxEocCount );
+ TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
+ priv->txBusyCount );
if ( debug & TLAN_DEBUG_GNRL ) {
TLan_PrintDio( dev->base_addr );
TLan_PhyPrint( dev );
@@ -1299,7 +1301,7 @@ static struct net_device_stats *TLan_GetStats( struct net_device *dev )
TLan_PrintList( priv->txList + i, "TX", i );
}
- return ( &( (TLanPrivateInfo *) netdev_priv(dev) )->stats );
+ return &dev->stats;
} /* TLan_GetStats */
@@ -1337,10 +1339,12 @@ static void TLan_SetMulticastList( struct net_device *dev )
if ( dev->flags & IFF_PROMISC ) {
tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
- TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
} else {
tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
- TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
if ( dev->flags & IFF_ALLMULTI ) {
for ( i = 0; i < 3; i++ )
TLan_SetMac( dev, i + 1, NULL );
@@ -1349,7 +1353,8 @@ static void TLan_SetMulticastList( struct net_device *dev )
} else {
for ( i = 0; i < dev->mc_count; i++ ) {
if ( i < 3 ) {
- TLan_SetMac( dev, i + 1, (char *) &dmi->dmi_addr );
+ TLan_SetMac( dev, i + 1,
+ (char *) &dmi->dmi_addr );
} else {
offset = TLan_HashFunc( (u8 *) &dmi->dmi_addr );
if ( offset < 32 )
@@ -1383,31 +1388,6 @@ static void TLan_SetMulticastList( struct net_device *dev )
*****************************************************************************/
- /***************************************************************
- * TLan_HandleInvalid
- *
- * Returns:
- * 0
- * Parms:
- * dev Device assigned the IRQ that was
- * raised.
- * host_int The contents of the HOST_INT
- * port.
- *
- * This function handles invalid interrupts. This should
- * never happen unless some other adapter is trying to use
- * the IRQ line assigned to the device.
- *
- **************************************************************/
-
-static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
-{
- /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */
- return 0;
-
-} /* TLan_HandleInvalid */
-
-
/***************************************************************
@@ -1441,14 +1421,16 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
u32 ack = 0;
u16 tmpCStat;
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
+ TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
+ priv->txHead, priv->txTail );
head_list = priv->txList + priv->txHead;
while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
ack++;
if ( ! bbuf ) {
struct sk_buff *skb = TLan_GetSKB(head_list);
- pci_unmap_single(priv->pciDev, head_list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single(priv->pciDev, head_list->buffer[0].address,
+ skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(skb);
head_list->buffer[8].address = 0;
head_list->buffer[9].address = 0;
@@ -1457,7 +1439,7 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
if ( tmpCStat & TLAN_CSTAT_EOC )
eoc = 1;
- priv->stats.tx_bytes += head_list->frameSize;
+ dev->stats.tx_bytes += head_list->frameSize;
head_list->cStat = TLAN_CSTAT_UNUSED;
netif_start_queue(dev);
@@ -1469,7 +1451,9 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
if ( eoc ) {
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
+ TLAN_DBG( TLAN_DEBUG_TX,
+ "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n",
+ priv->txHead, priv->txTail );
head_list = priv->txList + priv->txHead;
head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
@@ -1481,7 +1465,8 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
}
if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
- TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
if ( priv->timer.function == NULL ) {
priv->timer.function = &TLan_Timer;
priv->timer.data = (unsigned long) dev;
@@ -1563,66 +1548,65 @@ static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
TLanList *head_list;
struct sk_buff *skb;
TLanList *tail_list;
- void *t;
- u32 frameSize;
u16 tmpCStat;
dma_addr_t head_list_phys;
- TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
+ TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n",
+ priv->rxHead, priv->rxTail );
head_list = priv->rxList + priv->rxHead;
head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
- frameSize = head_list->frameSize;
+ dma_addr_t frameDma = head_list->buffer[0].address;
+ u32 frameSize = head_list->frameSize;
ack++;
if (tmpCStat & TLAN_CSTAT_EOC)
eoc = 1;
if (bbuf) {
- skb = dev_alloc_skb(frameSize + 7);
- if (skb == NULL)
- printk(KERN_INFO "TLAN: Couldn't allocate memory for received data.\n");
- else {
- head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
- skb_reserve(skb, 2);
- t = (void *) skb_put(skb, frameSize);
-
- priv->stats.rx_bytes += head_list->frameSize;
-
- memcpy( t, head_buffer, frameSize );
- skb->protocol = eth_type_trans( skb, dev );
- netif_rx( skb );
- }
+ skb = netdev_alloc_skb(dev, frameSize + 7);
+ if ( !skb )
+ goto drop_and_reuse;
+
+ head_buffer = priv->rxBuffer
+ + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
+ skb_reserve(skb, 2);
+ pci_dma_sync_single_for_cpu(priv->pciDev,
+ frameDma, frameSize,
+ PCI_DMA_FROMDEVICE);
+ skb_copy_from_linear_data(skb, head_buffer, frameSize);
+ skb_put(skb, frameSize);
+ dev->stats.rx_bytes += frameSize;
+
+ skb->protocol = eth_type_trans( skb, dev );
+ netif_rx( skb );
} else {
struct sk_buff *new_skb;
- /*
- * I changed the algorithm here. What we now do
- * is allocate the new frame. If this fails we
- * simply recycle the frame.
- */
+ new_skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
+ if ( !new_skb )
+ goto drop_and_reuse;
- new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
+ skb = TLan_GetSKB(head_list);
+ pci_unmap_single(priv->pciDev, frameDma,
+ TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+ skb_put( skb, frameSize );
- if ( new_skb != NULL ) {
- skb = TLan_GetSKB(head_list);
- pci_unmap_single(priv->pciDev, head_list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
- skb_trim( skb, frameSize );
+ dev->stats.rx_bytes += frameSize;
- priv->stats.rx_bytes += frameSize;
+ skb->protocol = eth_type_trans( skb, dev );
+ netif_rx( skb );
- skb->protocol = eth_type_trans( skb, dev );
- netif_rx( skb );
+ skb_reserve( new_skb, NET_IP_ALIGN );
+ head_list->buffer[0].address = pci_map_single(priv->pciDev,
+ new_skb->data,
+ TLAN_MAX_FRAME_SIZE,
+ PCI_DMA_FROMDEVICE);
- skb_reserve( new_skb, 2 );
- t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE );
- head_list->buffer[0].address = pci_map_single(priv->pciDev, new_skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
- head_list->buffer[8].address = (u32) t;
- TLan_StoreSKB(head_list, new_skb);
- } else
- printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" );
- }
+ TLan_StoreSKB(head_list, new_skb);
+ }
+drop_and_reuse:
head_list->forward = 0;
head_list->cStat = 0;
tail_list = priv->rxList + priv->rxTail;
@@ -1638,10 +1622,10 @@ static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
-
-
if ( eoc ) {
- TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
+ TLAN_DBG( TLAN_DEBUG_RX,
+ "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n",
+ priv->rxHead, priv->rxTail );
head_list = priv->rxList + priv->rxHead;
head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
@@ -1650,7 +1634,8 @@ static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
}
if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
- TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
if ( priv->timer.function == NULL ) {
priv->timer.function = &TLan_Timer;
priv->timer.data = (unsigned long) dev;
@@ -1728,7 +1713,9 @@ static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
host_int = 0;
if ( priv->tlanRev < 0x30 ) {
- TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail );
+ TLAN_DBG( TLAN_DEBUG_TX,
+ "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
+ priv->txHead, priv->txTail );
head_list = priv->txList + priv->txHead;
head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
@@ -1796,15 +1783,18 @@ static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
if ( net_sts ) {
TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
- TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", dev->name, (unsigned) net_sts );
+ TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
+ dev->name, (unsigned) net_sts );
}
if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) {
TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
- if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
+ if ( ! ( tlphy_sts & TLAN_TS_POLOK ) &&
+ ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
tlphy_ctl |= TLAN_TC_SWAPOL;
TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
- } else if ( ( tlphy_sts & TLAN_TS_POLOK ) && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
+ } else if ( ( tlphy_sts & TLAN_TS_POLOK )
+ && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
tlphy_ctl &= ~TLAN_TC_SWAPOL;
TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
}
@@ -1849,7 +1839,9 @@ static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
u32 ack = 1;
if ( priv->tlanRev < 0x30 ) {
- TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
+ TLAN_DBG( TLAN_DEBUG_RX,
+ "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n",
+ priv->rxHead, priv->rxTail );
head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
ack |= TLAN_HC_GO | TLAN_HC_RT;
@@ -1940,10 +1932,12 @@ static void TLan_Timer( unsigned long data )
if ( priv->timer.function == NULL ) {
elapsed = jiffies - priv->timerSetAt;
if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
- TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_LED_REG, TLAN_LED_LINK );
} else {
priv->timer.function = &TLan_Timer;
- priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
+ priv->timer.expires = priv->timerSetAt
+ + TLAN_TIMER_ACT_DELAY;
spin_unlock_irqrestore(&priv->lock, flags);
add_timer( &priv->timer );
break;
@@ -1998,7 +1992,8 @@ static void TLan_ResetLists( struct net_device *dev )
list = priv->txList + i;
list->cStat = TLAN_CSTAT_UNUSED;
if ( bbuf ) {
- list->buffer[0].address = priv->txBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
+ list->buffer[0].address = priv->txBufferDMA
+ + ( i * TLAN_MAX_FRAME_SIZE );
} else {
list->buffer[0].address = 0;
}
@@ -2017,28 +2012,32 @@ static void TLan_ResetLists( struct net_device *dev )
list->frameSize = TLAN_MAX_FRAME_SIZE;
list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
if ( bbuf ) {
- list->buffer[0].address = priv->rxBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
+ list->buffer[0].address = priv->rxBufferDMA
+ + ( i * TLAN_MAX_FRAME_SIZE );
} else {
- skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
- if ( skb == NULL ) {
- printk( "TLAN: Couldn't allocate memory for received data.\n" );
- /* If this ever happened it would be a problem */
- } else {
- skb->dev = dev;
- skb_reserve( skb, 2 );
- t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE );
+ skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
+ if ( !skb ) {
+ pr_err("TLAN: out of memory for received data.\n" );
+ break;
}
- list->buffer[0].address = pci_map_single(priv->pciDev, t, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
- list->buffer[8].address = (u32) t;
+
+ skb_reserve( skb, NET_IP_ALIGN );
+ list->buffer[0].address = pci_map_single(priv->pciDev, t,
+ TLAN_MAX_FRAME_SIZE,
+ PCI_DMA_FROMDEVICE);
TLan_StoreSKB(list, skb);
}
list->buffer[1].count = 0;
list->buffer[1].address = 0;
- if ( i < TLAN_NUM_RX_LISTS - 1 )
- list->forward = list_phys + sizeof(TLanList);
- else
- list->forward = 0;
+ list->forward = list_phys + sizeof(TLanList);
+ }
+
+ /* in case ran out of memory early, clear bits */
+ while (i < TLAN_NUM_RX_LISTS) {
+ TLan_StoreSKB(priv->rxList + i, NULL);
+ ++i;
}
+ list->forward = 0;
} /* TLan_ResetLists */
@@ -2055,7 +2054,9 @@ static void TLan_FreeLists( struct net_device *dev )
list = priv->txList + i;
skb = TLan_GetSKB(list);
if ( skb ) {
- pci_unmap_single(priv->pciDev, list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single(priv->pciDev,
+ list->buffer[0].address, skb->len,
+ PCI_DMA_TODEVICE);
dev_kfree_skb_any( skb );
list->buffer[8].address = 0;
list->buffer[9].address = 0;
@@ -2066,7 +2067,10 @@ static void TLan_FreeLists( struct net_device *dev )
list = priv->rxList + i;
skb = TLan_GetSKB(list);
if ( skb ) {
- pci_unmap_single(priv->pciDev, list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pciDev,
+ list->buffer[0].address,
+ TLAN_MAX_FRAME_SIZE,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb_any( skb );
list->buffer[8].address = 0;
list->buffer[9].address = 0;
@@ -2097,7 +2101,8 @@ static void TLan_PrintDio( u16 io_base )
u32 data0, data1;
int i;
- printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n", io_base );
+ printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n",
+ io_base );
printk( "TLAN: Off. +0 +4\n" );
for ( i = 0; i < 0x4C; i+= 8 ) {
data0 = TLan_DioRead32( io_base, i );
@@ -2131,13 +2136,14 @@ static void TLan_PrintList( TLanList *list, char *type, int num)
{
int i;
- printk( "TLAN: %s List %d at 0x%08x\n", type, num, (u32) list );
+ printk( "TLAN: %s List %d at %p\n", type, num, list );
printk( "TLAN: Forward = 0x%08x\n", list->forward );
printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat );
printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize );
/* for ( i = 0; i < 10; i++ ) { */
for ( i = 0; i < 2; i++ ) {
- printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", i, list->buffer[i].count, list->buffer[i].address );
+ printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
+ i, list->buffer[i].count, list->buffer[i].address );
}
} /* TLan_PrintList */
@@ -2165,7 +2171,6 @@ static void TLan_PrintList( TLanList *list, char *type, int num)
static void TLan_ReadAndClearStats( struct net_device *dev, int record )
{
- TLanPrivateInfo *priv = netdev_priv(dev);
u32 tx_good, tx_under;
u32 rx_good, rx_over;
u32 def_tx, crc, code;
@@ -2202,18 +2207,18 @@ static void TLan_ReadAndClearStats( struct net_device *dev, int record )
loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
if ( record ) {
- priv->stats.rx_packets += rx_good;
- priv->stats.rx_errors += rx_over + crc + code;
- priv->stats.tx_packets += tx_good;
- priv->stats.tx_errors += tx_under + loss;
- priv->stats.collisions += multi_col + single_col + excess_col + late_col;
+ dev->stats.rx_packets += rx_good;
+ dev->stats.rx_errors += rx_over + crc + code;
+ dev->stats.tx_packets += tx_good;
+ dev->stats.tx_errors += tx_under + loss;
+ dev->stats.collisions += multi_col + single_col + excess_col + late_col;
- priv->stats.rx_over_errors += rx_over;
- priv->stats.rx_crc_errors += crc;
- priv->stats.rx_frame_errors += code;
+ dev->stats.rx_over_errors += rx_over;
+ dev->stats.rx_crc_errors += crc;
+ dev->stats.rx_frame_errors += code;
- priv->stats.tx_aborted_errors += tx_under;
- priv->stats.tx_carrier_errors += loss;
+ dev->stats.tx_aborted_errors += tx_under;
+ dev->stats.tx_carrier_errors += loss;
}
} /* TLan_ReadAndClearStats */
@@ -2354,14 +2359,16 @@ TLan_FinishReset( struct net_device *dev )
TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
- if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
+ if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) ||
+ ( priv->aui ) ) {
status = MII_GS_LINK;
printk( "TLAN: %s: Link forced.\n", dev->name );
} else {
TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
udelay( 1000 );
TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
- if ( (status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */
+ if ( (status & MII_GS_LINK) &&
+ /* We only support link info on Nat.Sem. PHY's */
(tlphy_id1 == NAT_SEM_ID1) &&
(tlphy_id2 == NAT_SEM_ID2) ) {
TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
@@ -2370,12 +2377,12 @@ TLan_FinishReset( struct net_device *dev )
printk( "TLAN: %s: Link active with ", dev->name );
if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
printk( "forced 10%sMbps %s-Duplex\n",
- tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
- tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
+ tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
+ tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
} else {
printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
- tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
- tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
+ tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
+ tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
printk("TLAN: Partner capability: ");
for (i = 5; i <= 10; i++)
if (partner & (1<<i))
@@ -2416,7 +2423,8 @@ TLan_FinishReset( struct net_device *dev )
outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
netif_carrier_on(dev);
} else {
- printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
+ printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n",
+ dev->name );
TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
return;
}
@@ -2456,10 +2464,12 @@ static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
if ( mac != NULL ) {
for ( i = 0; i < 6; i++ )
- TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, mac[i] );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_AREG_0 + areg + i, mac[i] );
} else {
for ( i = 0; i < 6; i++ )
- TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, 0 );
+ TLan_DioWrite8( dev->base_addr,
+ TLAN_AREG_0 + areg + i, 0 );
}
} /* TLan_SetMac */
@@ -2565,9 +2575,13 @@ static void TLan_PhyDetect( struct net_device *dev )
TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
- if ( ( control != 0xFFFF ) || ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
- TLAN_DBG( TLAN_DEBUG_GNRL, "PHY found at %02x %04x %04x %04x\n", phy, control, hi, lo );
- if ( ( priv->phy[1] == TLAN_PHY_NONE ) && ( phy != TLAN_PHY_MAX_ADDR ) ) {
+ if ( ( control != 0xFFFF ) ||
+ ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
+ TLAN_DBG( TLAN_DEBUG_GNRL,
+ "PHY found at %02x %04x %04x %04x\n",
+ phy, control, hi, lo );
+ if ( ( priv->phy[1] == TLAN_PHY_NONE ) &&
+ ( phy != TLAN_PHY_MAX_ADDR ) ) {
priv->phy[1] = phy;
}
}
@@ -2595,7 +2609,9 @@ static void TLan_PhyPowerDown( struct net_device *dev )
value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
TLan_MiiSync( dev->base_addr );
TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
- if ( ( priv->phyNum == 0 ) && ( priv->phy[1] != TLAN_PHY_NONE ) && ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
+ if ( ( priv->phyNum == 0 ) &&
+ ( priv->phy[1] != TLAN_PHY_NONE ) &&
+ ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
TLan_MiiSync( dev->base_addr );
TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
}
@@ -2768,10 +2784,10 @@ static void TLan_PhyFinishAutoNeg( struct net_device *dev )
* more time. Perhaps we should fail after a while.
*/
if (!priv->neg_be_verbose++) {
- printk(KERN_INFO "TLAN: Giving autonegotiation more time.\n");
- printk(KERN_INFO "TLAN: Please check that your adapter has\n");
- printk(KERN_INFO "TLAN: been properly connected to a HUB or Switch.\n");
- printk(KERN_INFO "TLAN: Trying to establish link in the background...\n");
+ pr_info("TLAN: Giving autonegotiation more time.\n");
+ pr_info("TLAN: Please check that your adapter has\n");
+ pr_info("TLAN: been properly connected to a HUB or Switch.\n");
+ pr_info("TLAN: Trying to establish link in the background...\n");
}
TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
return;
@@ -2787,7 +2803,9 @@ static void TLan_PhyFinishAutoNeg( struct net_device *dev )
priv->tlanFullDuplex = TRUE;
}
- if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
+ if ( ( ! ( mode & 0x0180 ) ) &&
+ ( priv->adapter->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( dev->base_addr, TLAN_NET_CONFIG, data );
@@ -2796,12 +2814,14 @@ static void TLan_PhyFinishAutoNeg( struct net_device *dev )
}
if ( priv->phyNum == 0 ) {
- if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
- TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
- printk( "TLAN: Starting internal PHY with FULL-DUPLEX\n" );
+ if ( ( priv->duplex == TLAN_DUPLEX_FULL ) ||
+ ( an_adv & an_lpa & 0x0040 ) ) {
+ TLan_MiiWriteReg( dev, phy, MII_GEN_CTL,
+ MII_GC_AUTOENB | MII_GC_DUPLEX );
+ pr_info("TLAN: Starting internal PHY with FULL-DUPLEX\n" );
} else {
TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
- printk( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
+ pr_info( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
}
}
@@ -3209,7 +3229,8 @@ static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
if ( ( ! err ) && stop ) {
- TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
+ /* STOP, raise data while clock is high */
+ TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
}
@@ -3272,7 +3293,8 @@ static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
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 */
+ /* STOP, raise data while clock is high */
+ TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
}
diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h
index 41ce0b66593..4b82f283e98 100644
--- a/drivers/net/tlan.h
+++ b/drivers/net/tlan.h
@@ -13,8 +13,6 @@
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
- ** This file is best viewed/edited with tabstop=4, colums>=132
- *
*
* Dec 10, 1999 Torben Mathiasen <torben.mathiasen@compaq.com>
* New Maintainer
@@ -45,7 +43,9 @@
#define TLAN_IGNORE 0
#define TLAN_RECORD 1
-#define TLAN_DBG(lvl, format, args...) if (debug&lvl) printk(KERN_DEBUG "TLAN: " format, ##args );
+#define TLAN_DBG(lvl, format, args...) \
+ do { if (debug&lvl) printk(KERN_DEBUG "TLAN: " format, ##args ); } while(0)
+
#define TLAN_DEBUG_GNRL 0x0001
#define TLAN_DEBUG_TX 0x0002
#define TLAN_DEBUG_RX 0x0004
@@ -194,7 +194,6 @@ typedef struct tlan_private_tag {
u32 timerSetAt;
u32 timerType;
struct timer_list timer;
- struct net_device_stats stats;
struct board *adapter;
u32 adapterRev;
u32 aui;
@@ -205,7 +204,6 @@ typedef struct tlan_private_tag {
u32 speed;
u8 tlanRev;
u8 tlanFullDuplex;
- char devName[8];
spinlock_t lock;
u8 link;
u8 is_eisa;
@@ -517,12 +515,18 @@ static inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data)
* 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 ) ) )
*
- * 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;
+ * 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;
*
*/
static inline u32 TLan_HashFunc( const u8 *a )
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 45208a0e69a..7766cde0d63 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -132,7 +132,6 @@ static void xl_dn_comp(struct net_device *dev);
static int xl_close(struct net_device *dev);
static void xl_set_rx_mode(struct net_device *dev);
static irqreturn_t xl_interrupt(int irq, void *dev_id);
-static struct net_device_stats * xl_get_stats(struct net_device *dev);
static int xl_set_mac_address(struct net_device *dev, void *addr) ;
static void xl_arb_cmd(struct net_device *dev);
static void xl_asb_cmd(struct net_device *dev) ;
@@ -343,7 +342,6 @@ static int __devinit xl_probe(struct pci_dev *pdev,
dev->stop=&xl_close;
dev->do_ioctl=NULL;
dev->set_multicast_list=&xl_set_rx_mode;
- dev->get_stats=&xl_get_stats ;
dev->set_mac_address=&xl_set_mac_address ;
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -921,7 +919,7 @@ static void xl_rx(struct net_device *dev)
adv_rx_ring(dev) ;
adv_rx_ring(dev) ; /* One more time just for luck :) */
- xl_priv->xl_stats.rx_dropped++ ;
+ dev->stats.rx_dropped++ ;
writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
return ;
@@ -957,7 +955,7 @@ static void xl_rx(struct net_device *dev)
if (skb==NULL) { /* Still need to fix the rx ring */
printk(KERN_WARNING "%s: dev_alloc_skb failed in rx, single buffer \n",dev->name) ;
adv_rx_ring(dev) ;
- xl_priv->xl_stats.rx_dropped++ ;
+ dev->stats.rx_dropped++ ;
writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
return ;
}
@@ -971,8 +969,8 @@ static void xl_rx(struct net_device *dev)
xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG;
adv_rx_ring(dev) ;
- xl_priv->xl_stats.rx_packets++ ;
- xl_priv->xl_stats.rx_bytes += frame_length ;
+ dev->stats.rx_packets++ ;
+ dev->stats.rx_bytes += frame_length ;
netif_rx(skb2) ;
} /* if multiple buffers */
@@ -1182,8 +1180,8 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev)
txd->buffer = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
txd->buffer_length = cpu_to_le32(skb->len) | TXDNFRAGLAST;
xl_priv->tx_ring_skb[tx_head] = skb ;
- xl_priv->xl_stats.tx_packets++ ;
- xl_priv->xl_stats.tx_bytes += skb->len ;
+ dev->stats.tx_packets++ ;
+ dev->stats.tx_bytes += skb->len ;
/*
* Set the nextptr of the previous descriptor equal to this descriptor, add XL_TX_RING_SIZE -1
@@ -1463,12 +1461,6 @@ static void xl_srb_bh(struct net_device *dev)
return ;
}
-static struct net_device_stats * xl_get_stats(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- return (struct net_device_stats *) &xl_priv->xl_stats;
-}
-
static int xl_set_mac_address (struct net_device *dev, void *addr)
{
struct sockaddr *saddr = addr ;
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
index 74cf8e1a181..66b1ff60323 100644
--- a/drivers/net/tokenring/3c359.h
+++ b/drivers/net/tokenring/3c359.h
@@ -273,8 +273,6 @@ struct xl_private {
struct wait_queue *srb_wait;
volatile int asb_queued;
- struct net_device_stats xl_stats ;
-
u16 mac_buffer ;
u16 xl_lan_status ;
u8 xl_ring_speed ;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 6017d5267d0..43fde99b24a 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -803,7 +803,8 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
int rx = data->rxhead;
struct sk_buff *skb;
- data->rxskbs[rx] = skb = dev_alloc_skb(TSI108_RXBUF_SIZE + 2);
+ data->rxskbs[rx] = skb = netdev_alloc_skb(dev,
+ TSI108_RXBUF_SIZE + 2);
if (!skb)
break;
@@ -1352,8 +1353,9 @@ static int tsi108_open(struct net_device *dev)
data->rxhead = 0;
for (i = 0; i < TSI108_RXRING_LEN; i++) {
- struct sk_buff *skb = dev_alloc_skb(TSI108_RXBUF_SIZE + NET_IP_ALIGN);
+ struct sk_buff *skb;
+ skb = netdev_alloc_skb(dev, TSI108_RXBUF_SIZE + NET_IP_ALIGN);
if (!skb) {
/* Bah. No memory for now, but maybe we'll get
* some more later.
@@ -1435,7 +1437,6 @@ static int tsi108_close(struct net_device *dev)
dev_kfree_skb(skb);
}
- synchronize_irq(data->irq_num);
free_irq(data->irq_num, dev);
/* Discard the RX ring. */
@@ -1526,7 +1527,7 @@ static int tsi108_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
struct tsi108_prv_data *data = netdev_priv(dev);
unsigned long flags;
int rc;
-
+
spin_lock_irqsave(&data->txlock, flags);
rc = mii_ethtool_gset(&data->mii_if, cmd);
spin_unlock_irqrestore(&data->txlock, flags);
@@ -1543,7 +1544,7 @@ static int tsi108_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
spin_lock_irqsave(&data->txlock, flags);
rc = mii_ethtool_sset(&data->mii_if, cmd);
spin_unlock_irqrestore(&data->txlock, flags);
-
+
return rc;
}
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
index 6c400ccd38b..1210fb3748a 100644
--- a/drivers/net/tulip/21142.c
+++ b/drivers/net/tulip/21142.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/21142.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,9 +8,8 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
-
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
#include <linux/delay.h>
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 1b5edd646a8..9281d06d5aa 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -124,8 +124,6 @@ MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copi
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (6*HZ)
-#define DE_UNALIGNED_16(a) (u16)(get_unaligned((u16 *)(a)))
-
/* 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
@@ -1811,7 +1809,7 @@ static void __devinit de21041_get_srom_info (struct de_private *de)
goto bad_srom;
/* get default media type */
- switch (DE_UNALIGNED_16(&il->default_media)) {
+ switch (get_unaligned(&il->default_media)) {
case 0x0001: de->media_type = DE_MEDIA_BNC; break;
case 0x0002: de->media_type = DE_MEDIA_AUI; break;
case 0x0204: de->media_type = DE_MEDIA_TP_FD; break;
@@ -1875,9 +1873,9 @@ static void __devinit de21041_get_srom_info (struct de_private *de)
bufp += sizeof (ib->opts);
if (ib->opts & MediaCustomCSRs) {
- de->media[idx].csr13 = DE_UNALIGNED_16(&ib->csr13);
- de->media[idx].csr14 = DE_UNALIGNED_16(&ib->csr14);
- de->media[idx].csr15 = DE_UNALIGNED_16(&ib->csr15);
+ de->media[idx].csr13 = get_unaligned(&ib->csr13);
+ de->media[idx].csr14 = get_unaligned(&ib->csr14);
+ de->media[idx].csr15 = get_unaligned(&ib->csr15);
bufp += sizeof(ib->csr13) + sizeof(ib->csr14) +
sizeof(ib->csr15);
diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
index da2206f6021..0dcced1263b 100644
--- a/drivers/net/tulip/eeprom.c
+++ b/drivers/net/tulip/eeprom.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/eeprom.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,9 +8,8 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
-
+ for more information on this driver.
+ Please submit bug reports to http://bugzilla.kernel.org/.
*/
#include <linux/pci.h>
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 6284afd14bb..c6bad987d63 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/interrupt.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,8 +8,8 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index b5625663654..91cf9c86391 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/media.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,9 +8,9 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
#include <linux/kernel.h>
diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c
index be82a2effee..d3253ed09df 100644
--- a/drivers/net/tulip/pnic.c
+++ b/drivers/net/tulip/pnic.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/pnic.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,9 +8,9 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
#include <linux/kernel.h>
diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c
index 4e4a879c3fa..f49579128fb 100644
--- a/drivers/net/tulip/pnic2.c
+++ b/drivers/net/tulip/pnic2.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/pnic2.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
Modified to hep support PNIC_II by Kevin B. Hendricks
@@ -10,9 +9,9 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
index d2c1f42109b..a0e08422308 100644
--- a/drivers/net/tulip/timer.c
+++ b/drivers/net/tulip/timer.c
@@ -1,7 +1,6 @@
/*
drivers/net/tulip/timer.c
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,11 +8,12 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
+
#include "tulip.h"
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 92c68a22f16..19abbc36b60 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -8,9 +8,9 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
#ifndef __NET_TULIP_H__
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index af8d2c436ef..cafa89e6016 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1,7 +1,5 @@
-/* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux. */
+/* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux.
-/*
- Maintained by Valerie Henson <val_henson@linux.intel.com>
Copyright 2000,2001 The Linux Kernel Team
Written/copyright 1994-2001 by Donald Becker.
@@ -9,9 +7,9 @@
of the GNU General Public License, incorporated herein by reference.
Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
- for more information on this driver, or visit the project
- Web page at http://sourceforge.net/projects/tulip/
+ for more information on this driver.
+ Please submit bugs to http://bugzilla.kernel.org/ .
*/
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index eba1271b973..a82b32b4013 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -18,15 +18,11 @@
/*
* Changes:
*
- * Brian Braunstein <linuxkernel@bristyle.com> 2007/03/23
- * Fixed hw address handling. Now net_device.dev_addr is kept consistent
- * with tun.dev_addr when the address is set by this module.
- *
* Mike Kershaw <dragorn@kismetwireless.net> 2005/08/14
* Add TUNSETLINK ioctl to set the link encapsulation
*
* Mark Smith <markzzzsmith@yahoo.com.au>
- * Use random_ether_addr() for tap MAC address.
+ * Use random_ether_addr() for tap MAC address.
*
* Harald Roelle <harald.roelle@ifi.lmu.de> 2004/04/20
* Fixes in packet dropping, queue length setting and queue wakeup.
@@ -64,6 +60,7 @@
#include <linux/if_tun.h>
#include <linux/crc32.h>
#include <linux/nsproxy.h>
+#include <linux/virtio_net.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -83,9 +80,16 @@ static int debug;
#define DBG1( a... )
#endif
+#define FLT_EXACT_COUNT 8
+struct tap_filter {
+ unsigned int count; /* Number of addrs. Zero means disabled */
+ u32 mask[2]; /* Mask of the hashed addrs */
+ unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN];
+};
+
struct tun_struct {
struct list_head list;
- unsigned long flags;
+ unsigned int flags;
int attached;
uid_t owner;
gid_t group;
@@ -94,19 +98,119 @@ struct tun_struct {
struct sk_buff_head readq;
struct net_device *dev;
+ struct fasync_struct *fasync;
- struct fasync_struct *fasync;
-
- unsigned long if_flags;
- u8 dev_addr[ETH_ALEN];
- u32 chr_filter[2];
- u32 net_filter[2];
+ struct tap_filter txflt;
#ifdef TUN_DEBUG
int debug;
#endif
};
+/* TAP filterting */
+static void addr_hash_set(u32 *mask, const u8 *addr)
+{
+ int n = ether_crc(ETH_ALEN, addr) >> 26;
+ mask[n >> 5] |= (1 << (n & 31));
+}
+
+static unsigned int addr_hash_test(const u32 *mask, const u8 *addr)
+{
+ int n = ether_crc(ETH_ALEN, addr) >> 26;
+ return mask[n >> 5] & (1 << (n & 31));
+}
+
+static int update_filter(struct tap_filter *filter, void __user *arg)
+{
+ struct { u8 u[ETH_ALEN]; } *addr;
+ struct tun_filter uf;
+ int err, alen, n, nexact;
+
+ if (copy_from_user(&uf, arg, sizeof(uf)))
+ return -EFAULT;
+
+ if (!uf.count) {
+ /* Disabled */
+ filter->count = 0;
+ return 0;
+ }
+
+ alen = ETH_ALEN * uf.count;
+ addr = kmalloc(alen, GFP_KERNEL);
+ if (!addr)
+ return -ENOMEM;
+
+ if (copy_from_user(addr, arg + sizeof(uf), alen)) {
+ err = -EFAULT;
+ goto done;
+ }
+
+ /* The filter is updated without holding any locks. Which is
+ * perfectly safe. We disable it first and in the worst
+ * case we'll accept a few undesired packets. */
+ filter->count = 0;
+ wmb();
+
+ /* Use first set of addresses as an exact filter */
+ for (n = 0; n < uf.count && n < FLT_EXACT_COUNT; n++)
+ memcpy(filter->addr[n], addr[n].u, ETH_ALEN);
+
+ nexact = n;
+
+ /* The rest is hashed */
+ memset(filter->mask, 0, sizeof(filter->mask));
+ for (; n < uf.count; n++)
+ addr_hash_set(filter->mask, addr[n].u);
+
+ /* For ALLMULTI just set the mask to all ones.
+ * This overrides the mask populated above. */
+ if ((uf.flags & TUN_FLT_ALLMULTI))
+ memset(filter->mask, ~0, sizeof(filter->mask));
+
+ /* Now enable the filter */
+ wmb();
+ filter->count = nexact;
+
+ /* Return the number of exact filters */
+ err = nexact;
+
+done:
+ kfree(addr);
+ return err;
+}
+
+/* Returns: 0 - drop, !=0 - accept */
+static int run_filter(struct tap_filter *filter, const struct sk_buff *skb)
+{
+ /* Cannot use eth_hdr(skb) here because skb_mac_hdr() is incorrect
+ * at this point. */
+ struct ethhdr *eh = (struct ethhdr *) skb->data;
+ int i;
+
+ /* Exact match */
+ for (i = 0; i < filter->count; i++)
+ if (!compare_ether_addr(eh->h_dest, filter->addr[i]))
+ return 1;
+
+ /* Inexact match (multicast only) */
+ if (is_multicast_ether_addr(eh->h_dest))
+ return addr_hash_test(filter->mask, eh->h_dest);
+
+ return 0;
+}
+
+/*
+ * Checks whether the packet is accepted or not.
+ * Returns: 0 - drop, !=0 - accept
+ */
+static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
+{
+ if (!filter->count)
+ return 1;
+
+ return run_filter(filter, skb);
+}
+
/* Network device part of the driver */
static unsigned int tun_net_id;
@@ -141,7 +245,12 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
if (!tun->attached)
goto drop;
- /* Packet dropping */
+ /* Drop if the filter does not like it.
+ * This is a noop if the filter is disabled.
+ * Filter can be enabled only for the TAP devices. */
+ if (!check_filter(&tun->txflt, skb))
+ goto drop;
+
if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
if (!(tun->flags & TUN_ONE_QUEUE)) {
/* Normal queueing mode. */
@@ -158,7 +267,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- /* Queue packet */
+ /* Enqueue packet */
skb_queue_tail(&tun->readq, skb);
dev->trans_start = jiffies;
@@ -174,41 +283,14 @@ drop:
return 0;
}
-/** Add the specified Ethernet address to this multicast filter. */
-static void
-add_multi(u32* filter, const u8* addr)
+static void tun_net_mclist(struct net_device *dev)
{
- int bit_nr = ether_crc(ETH_ALEN, addr) >> 26;
- filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-}
-
-/** Remove the specified Ethernet addres from this multicast filter. */
-static void
-del_multi(u32* filter, const u8* addr)
-{
- int bit_nr = ether_crc(ETH_ALEN, addr) >> 26;
- filter[bit_nr >> 5] &= ~(1 << (bit_nr & 31));
-}
-
-/** Update the list of multicast groups to which the network device belongs.
- * This list is used to filter packets being sent from the character device to
- * the network device. */
-static void
-tun_net_mclist(struct net_device *dev)
-{
- struct tun_struct *tun = netdev_priv(dev);
- const struct dev_mc_list *mclist;
- int i;
- DECLARE_MAC_BUF(mac);
- DBG(KERN_DEBUG "%s: tun_net_mclist: mc_count %d\n",
- dev->name, dev->mc_count);
- memset(tun->chr_filter, 0, sizeof tun->chr_filter);
- for (i = 0, mclist = dev->mc_list; i < dev->mc_count && mclist != NULL;
- i++, mclist = mclist->next) {
- add_multi(tun->net_filter, mclist->dmi_addr);
- DBG(KERN_DEBUG "%s: tun_net_mclist: %s\n",
- dev->name, print_mac(mac, mclist->dmi_addr));
- }
+ /*
+ * This callback is supposed to deal with mc filter in
+ * _rx_ path and has nothing to do with the _tx_ path.
+ * In rx path we always accept everything userspace gives us.
+ */
+ return;
}
#define MIN_MTU 68
@@ -244,13 +326,11 @@ static void tun_net_init(struct net_device *dev)
case TUN_TAP_DEV:
/* Ethernet TAP Device */
- dev->set_multicast_list = tun_net_mclist;
-
ether_setup(dev);
- dev->change_mtu = tun_net_change_mtu;
+ dev->change_mtu = tun_net_change_mtu;
+ dev->set_multicast_list = tun_net_mclist;
- /* random address already created for us by tun_set_iff, use it */
- memcpy(dev->dev_addr, tun->dev_addr, min(sizeof(tun->dev_addr), sizeof(dev->dev_addr)) );
+ random_ether_addr(dev->dev_addr);
dev->tx_queue_len = TUN_READQ_SIZE; /* We prefer our own queue length */
break;
@@ -284,6 +364,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
struct sk_buff *skb;
size_t len = count, align = 0;
+ struct virtio_net_hdr gso = { 0 };
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) > count)
@@ -293,6 +374,17 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
return -EFAULT;
}
+ if (tun->flags & TUN_VNET_HDR) {
+ if ((len -= sizeof(gso)) > count)
+ return -EINVAL;
+
+ if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso)))
+ return -EFAULT;
+
+ if (gso.hdr_len > len)
+ return -EINVAL;
+ }
+
if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
align = NET_IP_ALIGN;
if (unlikely(len < ETH_HLEN))
@@ -312,6 +404,16 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
return -EFAULT;
}
+ if (gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+ if (!skb_partial_csum_set(skb, gso.csum_start,
+ gso.csum_offset)) {
+ tun->dev->stats.rx_frame_errors++;
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+ } else if (tun->flags & TUN_NOCHECKSUM)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
if (tun->flags & TUN_NO_PI) {
@@ -338,8 +440,35 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
break;
};
- if (tun->flags & TUN_NOCHECKSUM)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ pr_debug("GSO!\n");
+ switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+ case VIRTIO_NET_HDR_GSO_TCPV4:
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+ break;
+ case VIRTIO_NET_HDR_GSO_TCPV6:
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+ break;
+ default:
+ tun->dev->stats.rx_frame_errors++;
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+
+ if (gso.gso_type & VIRTIO_NET_HDR_GSO_ECN)
+ skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
+
+ skb_shinfo(skb)->gso_size = gso.gso_size;
+ if (skb_shinfo(skb)->gso_size == 0) {
+ tun->dev->stats.rx_frame_errors++;
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+
+ /* Header must be checked, and gso_segs computed. */
+ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+ skb_shinfo(skb)->gso_segs = 0;
+ }
netif_rx_ni(skb);
tun->dev->last_rx = jiffies;
@@ -385,6 +514,39 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
total += sizeof(pi);
}
+ if (tun->flags & TUN_VNET_HDR) {
+ struct virtio_net_hdr gso = { 0 }; /* no info leak */
+ if ((len -= sizeof(gso)) < 0)
+ return -EINVAL;
+
+ if (skb_is_gso(skb)) {
+ struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+ /* This is a hint as to how much should be linear. */
+ gso.hdr_len = skb_headlen(skb);
+ gso.gso_size = sinfo->gso_size;
+ if (sinfo->gso_type & SKB_GSO_TCPV4)
+ gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+ else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+ else
+ BUG();
+ if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+ gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN;
+ } else
+ gso.gso_type = VIRTIO_NET_HDR_GSO_NONE;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+ gso.csum_start = skb->csum_start - skb_headroom(skb);
+ gso.csum_offset = skb->csum_offset;
+ } /* else everything is zero */
+
+ if (unlikely(memcpy_toiovec(iv, (void *)&gso, sizeof(gso))))
+ return -EFAULT;
+ total += sizeof(gso);
+ }
+
len = min_t(int, skb->len, len);
skb_copy_datagram_iovec(skb, 0, iv, len);
@@ -404,7 +566,6 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
DECLARE_WAITQUEUE(wait, current);
struct sk_buff *skb;
ssize_t len, ret = 0;
- DECLARE_MAC_BUF(mac);
if (!tun)
return -EBADFD;
@@ -417,10 +578,6 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
add_wait_queue(&tun->read_wait, &wait);
while (len) {
- const u8 ones[ ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- u8 addr[ ETH_ALEN];
- int bit_nr;
-
current->state = TASK_INTERRUPTIBLE;
/* Read frames from the queue */
@@ -440,36 +597,9 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
}
netif_wake_queue(tun->dev);
- /** Decide whether to accept this packet. This code is designed to
- * behave identically to an Ethernet interface. Accept the packet if
- * - we are promiscuous.
- * - the packet is addressed to us.
- * - the packet is broadcast.
- * - the packet is multicast and
- * - we are multicast promiscous.
- * - we belong to the multicast group.
- */
- skb_copy_from_linear_data(skb, addr, min_t(size_t, sizeof addr,
- skb->len));
- bit_nr = ether_crc(sizeof addr, addr) >> 26;
- if ((tun->if_flags & IFF_PROMISC) ||
- memcmp(addr, tun->dev_addr, sizeof addr) == 0 ||
- memcmp(addr, ones, sizeof addr) == 0 ||
- (((addr[0] == 1 && addr[1] == 0 && addr[2] == 0x5e) ||
- (addr[0] == 0x33 && addr[1] == 0x33)) &&
- ((tun->if_flags & IFF_ALLMULTI) ||
- (tun->chr_filter[bit_nr >> 5] & (1 << (bit_nr & 31)))))) {
- DBG(KERN_DEBUG "%s: tun_chr_readv: accepted: %s\n",
- tun->dev->name, print_mac(mac, addr));
- ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
- kfree_skb(skb);
- break;
- } else {
- DBG(KERN_DEBUG "%s: tun_chr_readv: rejected: %s\n",
- tun->dev->name, print_mac(mac, addr));
- kfree_skb(skb);
- continue;
- }
+ ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
+ kfree_skb(skb);
+ break;
}
current->state = TASK_RUNNING;
@@ -565,12 +695,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun = netdev_priv(dev);
tun->dev = dev;
tun->flags = flags;
- /* Be promiscuous by default to maintain previous behaviour. */
- tun->if_flags = IFF_PROMISC;
- /* Generate random Ethernet address. */
- *(__be16 *)tun->dev_addr = htons(0x00FF);
- get_random_bytes(tun->dev_addr + sizeof(u16), 4);
- memset(tun->chr_filter, 0, sizeof tun->chr_filter);
+ tun->txflt.count = 0;
tun_net_init(dev);
@@ -599,6 +724,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
else
tun->flags &= ~TUN_ONE_QUEUE;
+ if (ifr->ifr_flags & IFF_VNET_HDR)
+ tun->flags |= TUN_VNET_HDR;
+ else
+ tun->flags &= ~TUN_VNET_HDR;
+
file->private_data = tun;
tun->attached = 1;
get_net(dev_net(tun->dev));
@@ -618,12 +748,53 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return err;
}
+/* This is like a cut-down ethtool ops, except done via tun fd so no
+ * privs required. */
+static int set_offload(struct net_device *dev, unsigned long arg)
+{
+ unsigned int old_features, features;
+
+ old_features = dev->features;
+ /* Unset features, set them as we chew on the arg. */
+ features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
+ |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6));
+
+ if (arg & TUN_F_CSUM) {
+ features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+ arg &= ~TUN_F_CSUM;
+
+ if (arg & (TUN_F_TSO4|TUN_F_TSO6)) {
+ if (arg & TUN_F_TSO_ECN) {
+ features |= NETIF_F_TSO_ECN;
+ arg &= ~TUN_F_TSO_ECN;
+ }
+ if (arg & TUN_F_TSO4)
+ features |= NETIF_F_TSO;
+ if (arg & TUN_F_TSO6)
+ features |= NETIF_F_TSO6;
+ arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
+ }
+ }
+
+ /* This gives the user a way to test for new features in future by
+ * trying to set them. */
+ if (arg)
+ return -EINVAL;
+
+ dev->features = features;
+ if (old_features != dev->features)
+ netdev_features_change(dev);
+
+ return 0;
+}
+
static int tun_chr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct tun_struct *tun = file->private_data;
void __user* argp = (void __user*)arg;
struct ifreq ifr;
+ int ret;
DECLARE_MAC_BUF(mac);
if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
@@ -647,6 +818,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
return 0;
}
+ if (cmd == TUNGETFEATURES) {
+ /* Currently this just means: "what IFF flags are valid?".
+ * This is needed because we never checked for invalid flags on
+ * TUNSETIFF. */
+ return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
+ IFF_VNET_HDR,
+ (unsigned int __user*)argp);
+ }
+
if (!tun)
return -EBADFD;
@@ -690,9 +870,6 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
break;
case TUNSETLINK:
- {
- int ret;
-
/* Only allow setting the type when the interface is down */
rtnl_lock();
if (tun->dev->flags & IFF_UP) {
@@ -706,85 +883,44 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
}
rtnl_unlock();
return ret;
- }
#ifdef TUN_DEBUG
case TUNSETDEBUG:
tun->debug = arg;
break;
#endif
+ case TUNSETOFFLOAD:
+ rtnl_lock();
+ ret = set_offload(tun->dev, arg);
+ rtnl_unlock();
+ return ret;
- case SIOCGIFFLAGS:
- ifr.ifr_flags = tun->if_flags;
- if (copy_to_user( argp, &ifr, sizeof ifr))
- return -EFAULT;
- return 0;
-
- case SIOCSIFFLAGS:
- /** Set the character device's interface flags. Currently only
- * IFF_PROMISC and IFF_ALLMULTI are used. */
- tun->if_flags = ifr.ifr_flags;
- DBG(KERN_INFO "%s: interface flags 0x%lx\n",
- tun->dev->name, tun->if_flags);
- return 0;
+ case TUNSETTXFILTER:
+ /* Can be set only for TAPs */
+ if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
+ return -EINVAL;
+ rtnl_lock();
+ ret = update_filter(&tun->txflt, (void *) __user arg);
+ rtnl_unlock();
+ return ret;
case SIOCGIFHWADDR:
- /* Note: the actual net device's address may be different */
- memcpy(ifr.ifr_hwaddr.sa_data, tun->dev_addr,
- min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
- if (copy_to_user( argp, &ifr, sizeof ifr))
+ /* Get hw addres */
+ memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
+ ifr.ifr_hwaddr.sa_family = tun->dev->type;
+ if (copy_to_user(argp, &ifr, sizeof ifr))
return -EFAULT;
return 0;
case SIOCSIFHWADDR:
- {
- /* try to set the actual net device's hw address */
- int ret;
+ /* Set hw address */
+ DBG(KERN_DEBUG "%s: set hw address: %s\n",
+ tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
rtnl_lock();
ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
rtnl_unlock();
-
- if (ret == 0) {
- /** Set the character device's hardware address. This is used when
- * filtering packets being sent from the network device to the character
- * device. */
- memcpy(tun->dev_addr, ifr.ifr_hwaddr.sa_data,
- min(sizeof ifr.ifr_hwaddr.sa_data, sizeof tun->dev_addr));
- DBG(KERN_DEBUG "%s: set hardware address: %x:%x:%x:%x:%x:%x\n",
- tun->dev->name,
- tun->dev_addr[0], tun->dev_addr[1], tun->dev_addr[2],
- tun->dev_addr[3], tun->dev_addr[4], tun->dev_addr[5]);
- }
-
- return ret;
- }
-
- case SIOCADDMULTI:
- /** Add the specified group to the character device's multicast filter
- * list. */
- rtnl_lock();
- netif_tx_lock_bh(tun->dev);
- add_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
- netif_tx_unlock_bh(tun->dev);
- rtnl_unlock();
-
- DBG(KERN_DEBUG "%s: add multi: %s\n",
- tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
- return 0;
-
- case SIOCDELMULTI:
- /** Remove the specified group from the character device's multicast
- * filter list. */
- rtnl_lock();
- netif_tx_lock_bh(tun->dev);
- del_multi(tun->chr_filter, ifr.ifr_hwaddr.sa_data);
- netif_tx_unlock_bh(tun->dev);
- rtnl_unlock();
-
- DBG(KERN_DEBUG "%s: del multi: %s\n",
- tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
- return 0;
+ return ret;
default:
return -EINVAL;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index c0dd25ba7a1..8549f1159a3 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -334,8 +334,6 @@ enum state_values {
#define TYPHOON_RESET_TIMEOUT_NOSLEEP ((6 * 1000000) / TYPHOON_UDELAY)
#define TYPHOON_WAIT_TIMEOUT ((1000000 / 2) / TYPHOON_UDELAY)
-#define typhoon_synchronize_irq(x) synchronize_irq(x)
-
#if defined(NETIF_F_TSO)
#define skb_tso_size(x) (skb_shinfo(x)->gso_size)
#define TSO_NUM_DESCRIPTORS 2
@@ -2143,7 +2141,6 @@ typhoon_close(struct net_device *dev)
printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
/* Make sure there is no irq handler running on a different CPU. */
- typhoon_synchronize_irq(dev->irq);
free_irq(dev->irq, dev);
typhoon_free_rx_rings(tp);
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 402e81020fb..756ba10b79d 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1588,7 +1588,7 @@ static void adjust_link(struct net_device *dev)
if (!ugeth->oldlink) {
new_state = 1;
ugeth->oldlink = 1;
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
}
} else if (ugeth->oldlink) {
new_state = 1;
@@ -3372,7 +3372,7 @@ static void ucc_geth_timeout(struct net_device *dev)
ucc_geth_startup(ugeth);
}
- netif_schedule(dev);
+ netif_tx_schedule_all(dev);
}
/* This is called by the kernel when a frame is ready for transmission. */
@@ -3500,11 +3500,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
dev->stats.rx_bytes += length;
/* Send the packet up the stack */
-#ifdef CONFIG_UGETH_NAPI
netif_receive_skb(skb);
-#else
- netif_rx(skb);
-#endif /* CONFIG_UGETH_NAPI */
}
ugeth->dev->last_rx = jiffies;
@@ -3580,7 +3576,6 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
return 0;
}
-#ifdef CONFIG_UGETH_NAPI
static int ucc_geth_poll(struct napi_struct *napi, int budget)
{
struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi);
@@ -3607,7 +3602,6 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
return howmany;
}
-#endif /* CONFIG_UGETH_NAPI */
static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
{
@@ -3617,9 +3611,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
struct ucc_geth_info *ug_info;
register u32 ucce;
register u32 uccm;
-#ifndef CONFIG_UGETH_NAPI
- register u32 rx_mask;
-#endif
register u32 tx_mask;
u8 i;
@@ -3636,21 +3627,11 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* check for receive events that require processing */
if (ucce & UCCE_RX_EVENTS) {
-#ifdef CONFIG_UGETH_NAPI
if (netif_rx_schedule_prep(dev, &ugeth->napi)) {
uccm &= ~UCCE_RX_EVENTS;
out_be32(uccf->p_uccm, uccm);
__netif_rx_schedule(dev, &ugeth->napi);
}
-#else
- rx_mask = UCCE_RXBF_SINGLE_MASK;
- for (i = 0; i < ug_info->numQueuesRx; i++) {
- if (ucce & rx_mask)
- ucc_geth_rx(ugeth, i, (int)ugeth->ug_info->bdRingLenRx[i]);
- ucce &= ~rx_mask;
- rx_mask <<= 1;
- }
-#endif /* CONFIG_UGETH_NAPI */
}
/* Tx event processing */
@@ -3720,9 +3701,8 @@ static int ucc_geth_open(struct net_device *dev)
return err;
}
-#ifdef CONFIG_UGETH_NAPI
napi_enable(&ugeth->napi);
-#endif
+
err = ucc_geth_startup(ugeth);
if (err) {
if (netif_msg_ifup(ugeth))
@@ -3783,9 +3763,8 @@ static int ucc_geth_open(struct net_device *dev)
return err;
out_err:
-#ifdef CONFIG_UGETH_NAPI
napi_disable(&ugeth->napi);
-#endif
+
return err;
}
@@ -3796,9 +3775,7 @@ static int ucc_geth_close(struct net_device *dev)
ugeth_vdbg("%s: IN", __FUNCTION__);
-#ifdef CONFIG_UGETH_NAPI
napi_disable(&ugeth->napi);
-#endif
ucc_geth_stop(ugeth);
@@ -4050,9 +4027,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
dev->hard_start_xmit = ucc_geth_start_xmit;
dev->tx_timeout = ucc_geth_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_UGETH_NAPI
netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
-#endif /* CONFIG_UGETH_NAPI */
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ucc_netpoll;
#endif
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index f5839c4a5cb..cfbbfee5583 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -5,7 +5,7 @@
*
* Author: Li Yang <leoli@freescale.com>
*
- * Limitation:
+ * Limitation:
* Can only get/set setttings of the first queue.
* Need to re-open the interface manually after changing some paramters.
*
@@ -160,7 +160,7 @@ uec_set_pauseparam(struct net_device *netdev,
ugeth->ug_info->receiveFlowControl = pause->rx_pause;
ugeth->ug_info->transmitFlowControl = pause->tx_pause;
-
+
if (ugeth->phydev->autoneg) {
if (netif_running(netdev)) {
/* FIXME: automatically restart */
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 0604f3faf04..68e198bd538 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -154,6 +154,16 @@ config USB_NET_AX8817X
This driver creates an interface named "ethX", where X depends on
what other networking devices you have in use.
+config USB_HSO
+ tristate "Option USB High Speed Mobile Devices"
+ depends on USB && RFKILL
+ default n
+ help
+ Choose this option if you have an Option HSDPA/HSUPA card.
+ These cards support downlink speeds of 7.2Mbps or greater.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hso.
config USB_NET_CDCETHER
tristate "CDC Ethernet support (smart devices such as cable modems)"
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 595a539f838..24800c157f9 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC) += catc.o
obj-$(CONFIG_USB_KAWETH) += kaweth.o
obj-$(CONFIG_USB_PEGASUS) += pegasus.o
obj-$(CONFIG_USB_RTL8150) += rtl8150.o
+obj-$(CONFIG_USB_HSO) += hso.o
obj-$(CONFIG_USB_NET_AX8817X) += asix.o
obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
new file mode 100644
index 00000000000..031d07b105a
--- /dev/null
+++ b/drivers/net/usb/hso.c
@@ -0,0 +1,2836 @@
+/******************************************************************************
+ *
+ * Driver for Option High Speed Mobile Devices.
+ *
+ * Copyright (C) 2008 Option International
+ * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd)
+ * <ajb@spheresystems.co.uk>
+ * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA
+ *
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * Description of the device:
+ *
+ * Interface 0: Contains the IP network interface on the bulk end points.
+ * The multiplexed serial ports are using the interrupt and
+ * control endpoints.
+ * Interrupt contains a bitmap telling which multiplexed
+ * serialport needs servicing.
+ *
+ * Interface 1: Diagnostics port, uses bulk only, do not submit urbs until the
+ * port is opened, as this have a huge impact on the network port
+ * throughput.
+ *
+ * Interface 2: Standard modem interface - circuit switched interface, should
+ * not be used.
+ *
+ *****************************************************************************/
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/module.h>
+#include <linux/ethtool.h>
+#include <linux/usb.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/kmod.h>
+#include <linux/rfkill.h>
+#include <linux/ip.h>
+#include <linux/uaccess.h>
+#include <linux/usb/cdc.h>
+#include <net/arp.h>
+#include <asm/byteorder.h>
+
+
+#define DRIVER_VERSION "1.2"
+#define MOD_AUTHOR "Option Wireless"
+#define MOD_DESCRIPTION "USB High Speed Option driver"
+#define MOD_LICENSE "GPL"
+
+#define HSO_MAX_NET_DEVICES 10
+#define HSO__MAX_MTU 2048
+#define DEFAULT_MTU 1500
+#define DEFAULT_MRU 1500
+
+#define CTRL_URB_RX_SIZE 1024
+#define CTRL_URB_TX_SIZE 64
+
+#define BULK_URB_RX_SIZE 4096
+#define BULK_URB_TX_SIZE 8192
+
+#define MUX_BULK_RX_BUF_SIZE HSO__MAX_MTU
+#define MUX_BULK_TX_BUF_SIZE HSO__MAX_MTU
+#define MUX_BULK_RX_BUF_COUNT 4
+#define USB_TYPE_OPTION_VENDOR 0x20
+
+/* These definitions are used with the struct hso_net flags element */
+/* - use *_bit operations on it. (bit indices not values.) */
+#define HSO_NET_RUNNING 0
+
+#define HSO_NET_TX_TIMEOUT (HZ*10)
+
+/* Serial port defines and structs. */
+#define HSO_SERIAL_FLAG_RX_SENT 0
+
+#define HSO_SERIAL_MAGIC 0x48534f31
+
+/* Number of ttys to handle */
+#define HSO_SERIAL_TTY_MINORS 256
+
+#define MAX_RX_URBS 2
+
+#define get_serial_by_tty(x) \
+ (x ? (struct hso_serial *)x->driver_data : NULL)
+
+/*****************************************************************************/
+/* Debugging functions */
+/*****************************************************************************/
+#define D__(lvl_, fmt, arg...) \
+ do { \
+ printk(lvl_ "[%d:%s]: " fmt "\n", \
+ __LINE__, __func__, ## arg); \
+ } while (0)
+
+#define D_(lvl, args...) \
+ do { \
+ if (lvl & debug) \
+ D__(KERN_INFO, args); \
+ } while (0)
+
+#define D1(args...) D_(0x01, ##args)
+#define D2(args...) D_(0x02, ##args)
+#define D3(args...) D_(0x04, ##args)
+#define D4(args...) D_(0x08, ##args)
+#define D5(args...) D_(0x10, ##args)
+
+/*****************************************************************************/
+/* Enumerators */
+/*****************************************************************************/
+enum pkt_parse_state {
+ WAIT_IP,
+ WAIT_DATA,
+ WAIT_SYNC
+};
+
+/*****************************************************************************/
+/* Structs */
+/*****************************************************************************/
+
+struct hso_shared_int {
+ struct usb_endpoint_descriptor *intr_endp;
+ void *shared_intr_buf;
+ struct urb *shared_intr_urb;
+ struct usb_device *usb;
+ int use_count;
+ int ref_count;
+ struct mutex shared_int_lock;
+};
+
+struct hso_net {
+ struct hso_device *parent;
+ struct net_device *net;
+ struct rfkill *rfkill;
+
+ struct usb_endpoint_descriptor *in_endp;
+ struct usb_endpoint_descriptor *out_endp;
+
+ struct urb *mux_bulk_rx_urb_pool[MUX_BULK_RX_BUF_COUNT];
+ struct urb *mux_bulk_tx_urb;
+ void *mux_bulk_rx_buf_pool[MUX_BULK_RX_BUF_COUNT];
+ void *mux_bulk_tx_buf;
+
+ struct sk_buff *skb_rx_buf;
+ struct sk_buff *skb_tx_buf;
+
+ enum pkt_parse_state rx_parse_state;
+ spinlock_t net_lock;
+
+ unsigned short rx_buf_size;
+ unsigned short rx_buf_missing;
+ struct iphdr rx_ip_hdr;
+
+ unsigned long flags;
+};
+
+struct hso_serial {
+ struct hso_device *parent;
+ int magic;
+ u8 minor;
+
+ struct hso_shared_int *shared_int;
+
+ /* rx/tx urb could be either a bulk urb or a control urb depending
+ on which serial port it is used on. */
+ struct urb *rx_urb[MAX_RX_URBS];
+ u8 num_rx_urbs;
+ u8 *rx_data[MAX_RX_URBS];
+ u16 rx_data_length; /* should contain allocated length */
+
+ struct urb *tx_urb;
+ u8 *tx_data;
+ u8 *tx_buffer;
+ u16 tx_data_length; /* should contain allocated length */
+ u16 tx_data_count;
+ u16 tx_buffer_count;
+ struct usb_ctrlrequest ctrl_req_tx;
+ struct usb_ctrlrequest ctrl_req_rx;
+
+ struct usb_endpoint_descriptor *in_endp;
+ struct usb_endpoint_descriptor *out_endp;
+
+ unsigned long flags;
+ u8 rts_state;
+ u8 dtr_state;
+ unsigned tx_urb_used:1;
+
+ /* from usb_serial_port */
+ struct tty_struct *tty;
+ int open_count;
+ spinlock_t serial_lock;
+
+ int (*write_data) (struct hso_serial *serial);
+};
+
+struct hso_device {
+ union {
+ struct hso_serial *dev_serial;
+ struct hso_net *dev_net;
+ } port_data;
+
+ u32 port_spec;
+
+ u8 is_active;
+ u8 usb_gone;
+ struct work_struct async_get_intf;
+ struct work_struct async_put_intf;
+
+ struct usb_device *usb;
+ struct usb_interface *interface;
+
+ struct device *dev;
+ struct kref ref;
+ struct mutex mutex;
+};
+
+/* Type of interface */
+#define HSO_INTF_MASK 0xFF00
+#define HSO_INTF_MUX 0x0100
+#define HSO_INTF_BULK 0x0200
+
+/* Type of port */
+#define HSO_PORT_MASK 0xFF
+#define HSO_PORT_NO_PORT 0x0
+#define HSO_PORT_CONTROL 0x1
+#define HSO_PORT_APP 0x2
+#define HSO_PORT_GPS 0x3
+#define HSO_PORT_PCSC 0x4
+#define HSO_PORT_APP2 0x5
+#define HSO_PORT_GPS_CONTROL 0x6
+#define HSO_PORT_MSD 0x7
+#define HSO_PORT_VOICE 0x8
+#define HSO_PORT_DIAG2 0x9
+#define HSO_PORT_DIAG 0x10
+#define HSO_PORT_MODEM 0x11
+#define HSO_PORT_NETWORK 0x12
+
+/* Additional device info */
+#define HSO_INFO_MASK 0xFF000000
+#define HSO_INFO_CRC_BUG 0x01000000
+
+/*****************************************************************************/
+/* Prototypes */
+/*****************************************************************************/
+/* Serial driver functions */
+static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static void ctrl_callback(struct urb *urb);
+static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
+static void hso_kick_transmit(struct hso_serial *serial);
+/* Helper functions */
+static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
+ struct usb_device *usb, gfp_t gfp);
+static void log_usb_status(int status, const char *function);
+static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
+ int type, int dir);
+static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
+static void hso_free_interface(struct usb_interface *intf);
+static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags);
+static int hso_stop_serial_device(struct hso_device *hso_dev);
+static int hso_start_net_device(struct hso_device *hso_dev);
+static void hso_free_shared_int(struct hso_shared_int *shared_int);
+static int hso_stop_net_device(struct hso_device *hso_dev);
+static void hso_serial_ref_free(struct kref *ref);
+static void async_get_intf(struct work_struct *data);
+static void async_put_intf(struct work_struct *data);
+static int hso_put_activity(struct hso_device *hso_dev);
+static int hso_get_activity(struct hso_device *hso_dev);
+
+/*****************************************************************************/
+/* Helping functions */
+/*****************************************************************************/
+
+/* #define DEBUG */
+
+#define dev2net(x) (x->port_data.dev_net)
+#define dev2ser(x) (x->port_data.dev_serial)
+
+/* Debugging functions */
+#ifdef DEBUG
+static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
+ unsigned int len)
+{
+ u8 i = 0;
+
+ printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len);
+
+ for (i = 0; i < len; i++) {
+ if (!(i % 16))
+ printk("\n 0x%03x: ", i);
+ printk("%02x ", (unsigned char)buf[i]);
+ }
+ printk("\n");
+}
+
+#define DUMP(buf_, len_) \
+ dbg_dump(__LINE__, __func__, buf_, len_)
+
+#define DUMP1(buf_, len_) \
+ do { \
+ if (0x01 & debug) \
+ DUMP(buf_, len_); \
+ } while (0)
+#else
+#define DUMP(buf_, len_)
+#define DUMP1(buf_, len_)
+#endif
+
+/* module parameters */
+static int debug;
+static int tty_major;
+static int disable_net;
+
+/* driver info */
+static const char driver_name[] = "hso";
+static const char tty_filename[] = "ttyHS";
+static const char *version = __FILE__ ": " DRIVER_VERSION " " MOD_AUTHOR;
+/* the usb driver itself (registered in hso_init) */
+static struct usb_driver hso_driver;
+/* serial structures */
+static struct tty_driver *tty_drv;
+static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS];
+static struct hso_device *network_table[HSO_MAX_NET_DEVICES];
+static spinlock_t serial_table_lock;
+static struct ktermios *hso_serial_termios[HSO_SERIAL_TTY_MINORS];
+static struct ktermios *hso_serial_termios_locked[HSO_SERIAL_TTY_MINORS];
+
+static const s32 default_port_spec[] = {
+ HSO_INTF_MUX | HSO_PORT_NETWORK,
+ HSO_INTF_BULK | HSO_PORT_DIAG,
+ HSO_INTF_BULK | HSO_PORT_MODEM,
+ 0
+};
+
+static const s32 icon321_port_spec[] = {
+ HSO_INTF_MUX | HSO_PORT_NETWORK,
+ HSO_INTF_BULK | HSO_PORT_DIAG2,
+ HSO_INTF_BULK | HSO_PORT_MODEM,
+ HSO_INTF_BULK | HSO_PORT_DIAG,
+ 0
+};
+
+#define default_port_device(vendor, product) \
+ USB_DEVICE(vendor, product), \
+ .driver_info = (kernel_ulong_t)default_port_spec
+
+#define icon321_port_device(vendor, product) \
+ USB_DEVICE(vendor, product), \
+ .driver_info = (kernel_ulong_t)icon321_port_spec
+
+/* list of devices we support */
+static const struct usb_device_id hso_ids[] = {
+ {default_port_device(0x0af0, 0x6711)},
+ {default_port_device(0x0af0, 0x6731)},
+ {default_port_device(0x0af0, 0x6751)},
+ {default_port_device(0x0af0, 0x6771)},
+ {default_port_device(0x0af0, 0x6791)},
+ {default_port_device(0x0af0, 0x6811)},
+ {default_port_device(0x0af0, 0x6911)},
+ {default_port_device(0x0af0, 0x6951)},
+ {default_port_device(0x0af0, 0x6971)},
+ {default_port_device(0x0af0, 0x7011)},
+ {default_port_device(0x0af0, 0x7031)},
+ {default_port_device(0x0af0, 0x7051)},
+ {default_port_device(0x0af0, 0x7071)},
+ {default_port_device(0x0af0, 0x7111)},
+ {default_port_device(0x0af0, 0x7211)},
+ {default_port_device(0x0af0, 0x7251)},
+ {default_port_device(0x0af0, 0x7271)},
+ {default_port_device(0x0af0, 0x7311)},
+ {default_port_device(0x0af0, 0xc031)}, /* Icon-Edge */
+ {icon321_port_device(0x0af0, 0xd013)}, /* Module HSxPA */
+ {icon321_port_device(0x0af0, 0xd031)}, /* Icon-321 */
+ {default_port_device(0x0af0, 0xd033)}, /* Icon-322 */
+ {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */
+ {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */
+ {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */
+ {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */
+ {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */
+ {}
+};
+MODULE_DEVICE_TABLE(usb, hso_ids);
+
+/* Sysfs attribute */
+static ssize_t hso_sysfs_show_porttype(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct hso_device *hso_dev = dev->driver_data;
+ char *port_name;
+
+ if (!hso_dev)
+ return 0;
+
+ switch (hso_dev->port_spec & HSO_PORT_MASK) {
+ case HSO_PORT_CONTROL:
+ port_name = "Control";
+ break;
+ case HSO_PORT_APP:
+ port_name = "Application";
+ break;
+ case HSO_PORT_APP2:
+ port_name = "Application2";
+ break;
+ case HSO_PORT_GPS:
+ port_name = "GPS";
+ break;
+ case HSO_PORT_GPS_CONTROL:
+ port_name = "GPS Control";
+ break;
+ case HSO_PORT_PCSC:
+ port_name = "PCSC";
+ break;
+ case HSO_PORT_DIAG:
+ port_name = "Diagnostic";
+ break;
+ case HSO_PORT_DIAG2:
+ port_name = "Diagnostic2";
+ break;
+ case HSO_PORT_MODEM:
+ port_name = "Modem";
+ break;
+ case HSO_PORT_NETWORK:
+ port_name = "Network";
+ break;
+ default:
+ port_name = "Unknown";
+ break;
+ }
+
+ return sprintf(buf, "%s\n", port_name);
+}
+static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
+
+/* converts mux value to a port spec value */
+static u32 hso_mux_to_port(int mux)
+{
+ u32 result;
+
+ switch (mux) {
+ case 0x1:
+ result = HSO_PORT_CONTROL;
+ break;
+ case 0x2:
+ result = HSO_PORT_APP;
+ break;
+ case 0x4:
+ result = HSO_PORT_PCSC;
+ break;
+ case 0x8:
+ result = HSO_PORT_GPS;
+ break;
+ case 0x10:
+ result = HSO_PORT_APP2;
+ break;
+ default:
+ result = HSO_PORT_NO_PORT;
+ }
+ return result;
+}
+
+/* converts port spec value to a mux value */
+static u32 hso_port_to_mux(int port)
+{
+ u32 result;
+
+ switch (port & HSO_PORT_MASK) {
+ case HSO_PORT_CONTROL:
+ result = 0x0;
+ break;
+ case HSO_PORT_APP:
+ result = 0x1;
+ break;
+ case HSO_PORT_PCSC:
+ result = 0x2;
+ break;
+ case HSO_PORT_GPS:
+ result = 0x3;
+ break;
+ case HSO_PORT_APP2:
+ result = 0x4;
+ break;
+ default:
+ result = 0x0;
+ }
+ return result;
+}
+
+static struct hso_serial *get_serial_by_shared_int_and_type(
+ struct hso_shared_int *shared_int,
+ int mux)
+{
+ int i, port;
+
+ port = hso_mux_to_port(mux);
+
+ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
+ if (serial_table[i]
+ && (dev2ser(serial_table[i])->shared_int == shared_int)
+ && ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) {
+ return dev2ser(serial_table[i]);
+ }
+ }
+
+ return NULL;
+}
+
+static struct hso_serial *get_serial_by_index(unsigned index)
+{
+ struct hso_serial *serial;
+ unsigned long flags;
+
+ if (!serial_table[index])
+ return NULL;
+ spin_lock_irqsave(&serial_table_lock, flags);
+ serial = dev2ser(serial_table[index]);
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+
+ return serial;
+}
+
+static int get_free_serial_index(void)
+{
+ int index;
+ unsigned long flags;
+
+ spin_lock_irqsave(&serial_table_lock, flags);
+ for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) {
+ if (serial_table[index] == NULL) {
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+ return index;
+ }
+ }
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+
+ printk(KERN_ERR "%s: no free serial devices in table\n", __func__);
+ return -1;
+}
+
+static void set_serial_by_index(unsigned index, struct hso_serial *serial)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&serial_table_lock, flags);
+ if (serial)
+ serial_table[index] = serial->parent;
+ else
+ serial_table[index] = NULL;
+ spin_unlock_irqrestore(&serial_table_lock, flags);
+}
+
+/* log a meaningfull explanation of an USB status */
+static void log_usb_status(int status, const char *function)
+{
+ char *explanation;
+
+ switch (status) {
+ case -ENODEV:
+ explanation = "no device";
+ break;
+ case -ENOENT:
+ explanation = "endpoint not enabled";
+ break;
+ case -EPIPE:
+ explanation = "endpoint stalled";
+ break;
+ case -ENOSPC:
+ explanation = "not enough bandwidth";
+ break;
+ case -ESHUTDOWN:
+ explanation = "device disabled";
+ break;
+ case -EHOSTUNREACH:
+ explanation = "device suspended";
+ break;
+ case -EINVAL:
+ case -EAGAIN:
+ case -EFBIG:
+ case -EMSGSIZE:
+ explanation = "internal error";
+ break;
+ default:
+ explanation = "unknown status";
+ break;
+ }
+ D1("%s: received USB status - %s (%d)", function, explanation, status);
+}
+
+/* Network interface functions */
+
+/* called when net interface is brought up by ifconfig */
+static int hso_net_open(struct net_device *net)
+{
+ struct hso_net *odev = netdev_priv(net);
+ unsigned long flags = 0;
+
+ if (!odev) {
+ dev_err(&net->dev, "No net device !\n");
+ return -ENODEV;
+ }
+
+ odev->skb_tx_buf = NULL;
+
+ /* setup environment */
+ spin_lock_irqsave(&odev->net_lock, flags);
+ odev->rx_parse_state = WAIT_IP;
+ odev->rx_buf_size = 0;
+ odev->rx_buf_missing = sizeof(struct iphdr);
+ spin_unlock_irqrestore(&odev->net_lock, flags);
+
+ hso_start_net_device(odev->parent);
+
+ /* We are up and running. */
+ set_bit(HSO_NET_RUNNING, &odev->flags);
+
+ /* Tell the kernel we are ready to start receiving from it */
+ netif_start_queue(net);
+
+ return 0;
+}
+
+/* called when interface is brought down by ifconfig */
+static int hso_net_close(struct net_device *net)
+{
+ struct hso_net *odev = netdev_priv(net);
+
+ /* we don't need the queue anymore */
+ netif_stop_queue(net);
+ /* no longer running */
+ clear_bit(HSO_NET_RUNNING, &odev->flags);
+
+ hso_stop_net_device(odev->parent);
+
+ /* done */
+ return 0;
+}
+
+/* USB tells is xmit done, we should start the netqueue again */
+static void write_bulk_callback(struct urb *urb)
+{
+ struct hso_net *odev = urb->context;
+ int status = urb->status;
+
+ /* Sanity check */
+ if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) {
+ dev_err(&urb->dev->dev, "%s: device not running\n", __func__);
+ return;
+ }
+
+ /* Do we still have a valid kernel network device? */
+ if (!netif_device_present(odev->net)) {
+ dev_err(&urb->dev->dev, "%s: net device not present\n",
+ __func__);
+ return;
+ }
+
+ /* log status, but don't act on it, we don't need to resubmit anything
+ * anyhow */
+ if (status)
+ log_usb_status(status, __func__);
+
+ hso_put_activity(odev->parent);
+
+ /* Tell the network interface we are ready for another frame */
+ netif_wake_queue(odev->net);
+}
+
+/* called by kernel when we need to transmit a packet */
+static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
+{
+ struct hso_net *odev = netdev_priv(net);
+ int result;
+
+ /* Tell the kernel, "No more frames 'til we are done with this one." */
+ netif_stop_queue(net);
+ if (hso_get_activity(odev->parent) == -EAGAIN) {
+ odev->skb_tx_buf = skb;
+ return 0;
+ }
+
+ /* log if asked */
+ DUMP1(skb->data, skb->len);
+ /* Copy it from kernel memory to OUR memory */
+ memcpy(odev->mux_bulk_tx_buf, skb->data, skb->len);
+ D1("len: %d/%d", skb->len, MUX_BULK_TX_BUF_SIZE);
+
+ /* Fill in the URB for shipping it out. */
+ usb_fill_bulk_urb(odev->mux_bulk_tx_urb,
+ odev->parent->usb,
+ usb_sndbulkpipe(odev->parent->usb,
+ odev->out_endp->
+ bEndpointAddress & 0x7F),
+ odev->mux_bulk_tx_buf, skb->len, write_bulk_callback,
+ odev);
+
+ /* Deal with the Zero Length packet problem, I hope */
+ odev->mux_bulk_tx_urb->transfer_flags |= URB_ZERO_PACKET;
+
+ /* Send the URB on its merry way. */
+ result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC);
+ if (result) {
+ dev_warn(&odev->parent->interface->dev,
+ "failed mux_bulk_tx_urb %d", result);
+ net->stats.tx_errors++;
+ netif_start_queue(net);
+ } else {
+ net->stats.tx_packets++;
+ net->stats.tx_bytes += skb->len;
+ /* And tell the kernel when the last transmit started. */
+ net->trans_start = jiffies;
+ }
+ dev_kfree_skb(skb);
+ /* we're done */
+ return result;
+}
+
+static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+ struct hso_net *odev = netdev_priv(net);
+
+ strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
+ strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+ usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
+}
+
+static struct ethtool_ops ops = {
+ .get_drvinfo = hso_get_drvinfo,
+ .get_link = ethtool_op_get_link
+};
+
+/* called when a packet did not ack after watchdogtimeout */
+static void hso_net_tx_timeout(struct net_device *net)
+{
+ struct hso_net *odev = netdev_priv(net);
+
+ if (!odev)
+ return;
+
+ /* Tell syslog we are hosed. */
+ dev_warn(&net->dev, "Tx timed out.\n");
+
+ /* Tear the waiting frame off the list */
+ if (odev->mux_bulk_tx_urb
+ && (odev->mux_bulk_tx_urb->status == -EINPROGRESS))
+ usb_unlink_urb(odev->mux_bulk_tx_urb);
+
+ /* Update statistics */
+ net->stats.tx_errors++;
+}
+
+/* make a real packet from the received USB buffer */
+static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
+ unsigned int count, unsigned char is_eop)
+{
+ unsigned short temp_bytes;
+ unsigned short buffer_offset = 0;
+ unsigned short frame_len;
+ unsigned char *tmp_rx_buf;
+
+ /* log if needed */
+ D1("Rx %d bytes", count);
+ DUMP(ip_pkt, min(128, (int)count));
+
+ while (count) {
+ switch (odev->rx_parse_state) {
+ case WAIT_IP:
+ /* waiting for IP header. */
+ /* wanted bytes - size of ip header */
+ temp_bytes =
+ (count <
+ odev->rx_buf_missing) ? count : odev->
+ rx_buf_missing;
+
+ memcpy(((unsigned char *)(&odev->rx_ip_hdr)) +
+ odev->rx_buf_size, ip_pkt + buffer_offset,
+ temp_bytes);
+
+ odev->rx_buf_size += temp_bytes;
+ buffer_offset += temp_bytes;
+ odev->rx_buf_missing -= temp_bytes;
+ count -= temp_bytes;
+
+ if (!odev->rx_buf_missing) {
+ /* header is complete allocate an sk_buffer and
+ * continue to WAIT_DATA */
+ frame_len = ntohs(odev->rx_ip_hdr.tot_len);
+
+ if ((frame_len > DEFAULT_MRU) ||
+ (frame_len < sizeof(struct iphdr))) {
+ dev_err(&odev->net->dev,
+ "Invalid frame (%d) length\n",
+ frame_len);
+ odev->rx_parse_state = WAIT_SYNC;
+ continue;
+ }
+ /* Allocate an sk_buff */
+ odev->skb_rx_buf = dev_alloc_skb(frame_len);
+ if (!odev->skb_rx_buf) {
+ /* We got no receive buffer. */
+ D1("could not allocate memory");
+ odev->rx_parse_state = WAIT_SYNC;
+ return;
+ }
+ /* Here's where it came from */
+ odev->skb_rx_buf->dev = odev->net;
+
+ /* Copy what we got so far. make room for iphdr
+ * after tail. */
+ tmp_rx_buf =
+ skb_put(odev->skb_rx_buf,
+ sizeof(struct iphdr));
+ memcpy(tmp_rx_buf, (char *)&(odev->rx_ip_hdr),
+ sizeof(struct iphdr));
+
+ /* ETH_HLEN */
+ odev->rx_buf_size = sizeof(struct iphdr);
+
+ /* Filip actually use .tot_len */
+ odev->rx_buf_missing =
+ frame_len - sizeof(struct iphdr);
+ odev->rx_parse_state = WAIT_DATA;
+ }
+ break;
+
+ case WAIT_DATA:
+ temp_bytes = (count < odev->rx_buf_missing)
+ ? count : odev->rx_buf_missing;
+
+ /* Copy the rest of the bytes that are left in the
+ * buffer into the waiting sk_buf. */
+ /* Make room for temp_bytes after tail. */
+ tmp_rx_buf = skb_put(odev->skb_rx_buf, temp_bytes);
+ memcpy(tmp_rx_buf, ip_pkt + buffer_offset, temp_bytes);
+
+ odev->rx_buf_missing -= temp_bytes;
+ count -= temp_bytes;
+ buffer_offset += temp_bytes;
+ odev->rx_buf_size += temp_bytes;
+ if (!odev->rx_buf_missing) {
+ /* Packet is complete. Inject into stack. */
+ /* We have IP packet here */
+ odev->skb_rx_buf->protocol =
+ __constant_htons(ETH_P_IP);
+ /* don't check it */
+ odev->skb_rx_buf->ip_summed =
+ CHECKSUM_UNNECESSARY;
+
+ skb_reset_mac_header(odev->skb_rx_buf);
+
+ /* Ship it off to the kernel */
+ netif_rx(odev->skb_rx_buf);
+ /* No longer our buffer. */
+ odev->skb_rx_buf = NULL;
+
+ /* update out statistics */
+ odev->net->stats.rx_packets++;
+
+ odev->net->stats.rx_bytes += odev->rx_buf_size;
+
+ odev->rx_buf_size = 0;
+ odev->rx_buf_missing = sizeof(struct iphdr);
+ odev->rx_parse_state = WAIT_IP;
+ }
+ break;
+
+ case WAIT_SYNC:
+ D1(" W_S");
+ count = 0;
+ break;
+ default:
+ D1(" ");
+ count--;
+ break;
+ }
+ }
+
+ /* Recovery mechanism for WAIT_SYNC state. */
+ if (is_eop) {
+ if (odev->rx_parse_state == WAIT_SYNC) {
+ odev->rx_parse_state = WAIT_IP;
+ odev->rx_buf_size = 0;
+ odev->rx_buf_missing = sizeof(struct iphdr);
+ }
+ }
+}
+
+/* Moving data from usb to kernel (in interrupt state) */
+static void read_bulk_callback(struct urb *urb)
+{
+ struct hso_net *odev = urb->context;
+ struct net_device *net;
+ int result;
+ int status = urb->status;
+
+ /* is al ok? (Filip: Who's Al ?) */
+ if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+
+ /* Sanity check */
+ if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) {
+ D1("BULK IN callback but driver is not active!");
+ return;
+ }
+ usb_mark_last_busy(urb->dev);
+
+ net = odev->net;
+
+ if (!netif_device_present(net)) {
+ /* Somebody killed our network interface... */
+ return;
+ }
+
+ if (odev->parent->port_spec & HSO_INFO_CRC_BUG) {
+ u32 rest;
+ u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
+ rest = urb->actual_length % odev->in_endp->wMaxPacketSize;
+ if (((rest == 5) || (rest == 6))
+ && !memcmp(((u8 *) urb->transfer_buffer) +
+ urb->actual_length - 4, crc_check, 4)) {
+ urb->actual_length -= 4;
+ }
+ }
+
+ /* do we even have a packet? */
+ if (urb->actual_length) {
+ /* Handle the IP stream, add header and push it onto network
+ * stack if the packet is complete. */
+ spin_lock(&odev->net_lock);
+ packetizeRx(odev, urb->transfer_buffer, urb->actual_length,
+ (urb->transfer_buffer_length >
+ urb->actual_length) ? 1 : 0);
+ spin_unlock(&odev->net_lock);
+ }
+
+ /* We are done with this URB, resubmit it. Prep the USB to wait for
+ * another frame. Reuse same as received. */
+ usb_fill_bulk_urb(urb,
+ odev->parent->usb,
+ usb_rcvbulkpipe(odev->parent->usb,
+ odev->in_endp->
+ bEndpointAddress & 0x7F),
+ urb->transfer_buffer, MUX_BULK_RX_BUF_SIZE,
+ read_bulk_callback, odev);
+
+ /* Give this to the USB subsystem so it can tell us when more data
+ * arrives. */
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result)
+ dev_warn(&odev->parent->interface->dev,
+ "%s failed submit mux_bulk_rx_urb %d", __func__,
+ result);
+}
+
+/* Serial driver functions */
+
+static void _hso_serial_set_termios(struct tty_struct *tty,
+ struct ktermios *old)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+ struct ktermios *termios;
+
+ if ((!tty) || (!tty->termios) || (!serial)) {
+ printk(KERN_ERR "%s: no tty structures", __func__);
+ return;
+ }
+
+ D4("port %d", serial->minor);
+
+ /*
+ * The default requirements for this device are:
+ */
+ termios = tty->termios;
+ termios->c_iflag &=
+ ~(IGNBRK /* disable ignore break */
+ | BRKINT /* disable break causes interrupt */
+ | PARMRK /* disable mark parity errors */
+ | ISTRIP /* disable clear high bit of input characters */
+ | INLCR /* disable translate NL to CR */
+ | IGNCR /* disable ignore CR */
+ | ICRNL /* disable translate CR to NL */
+ | IXON); /* disable enable XON/XOFF flow control */
+
+ /* disable postprocess output characters */
+ termios->c_oflag &= ~OPOST;
+
+ termios->c_lflag &=
+ ~(ECHO /* disable echo input characters */
+ | ECHONL /* disable echo new line */
+ | ICANON /* disable erase, kill, werase, and rprnt
+ special characters */
+ | ISIG /* disable interrupt, quit, and suspend special
+ characters */
+ | IEXTEN); /* disable non-POSIX special characters */
+
+ termios->c_cflag &=
+ ~(CSIZE /* no size */
+ | PARENB /* disable parity bit */
+ | CBAUD /* clear current baud rate */
+ | CBAUDEX); /* clear current buad rate */
+
+ termios->c_cflag |= CS8; /* character size 8 bits */
+
+ /* baud rate 115200 */
+ tty_encode_baud_rate(serial->tty, 115200, 115200);
+
+ /*
+ * Force low_latency on; otherwise the pushes are scheduled;
+ * this is bad as it opens up the possibility of dropping bytes
+ * on the floor. We don't want to drop bytes on the floor. :)
+ */
+ serial->tty->low_latency = 1;
+ return;
+}
+
+/* open the requested serial port */
+static int hso_serial_open(struct tty_struct *tty, struct file *filp)
+{
+ struct hso_serial *serial = get_serial_by_index(tty->index);
+ int result;
+
+ /* sanity check */
+ if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) {
+ tty->driver_data = NULL;
+ D1("Failed to open port");
+ return -ENODEV;
+ }
+
+ mutex_lock(&serial->parent->mutex);
+ result = usb_autopm_get_interface(serial->parent->interface);
+ if (result < 0)
+ goto err_out;
+
+ D1("Opening %d", serial->minor);
+ kref_get(&serial->parent->ref);
+
+ /* setup */
+ tty->driver_data = serial;
+ serial->tty = tty;
+
+ /* check for port allready opened, if not set the termios */
+ serial->open_count++;
+ if (serial->open_count == 1) {
+ tty->low_latency = 1;
+ serial->flags = 0;
+ /* Force default termio settings */
+ _hso_serial_set_termios(tty, NULL);
+ result = hso_start_serial_device(serial->parent, GFP_KERNEL);
+ if (result) {
+ hso_stop_serial_device(serial->parent);
+ serial->open_count--;
+ kref_put(&serial->parent->ref, hso_serial_ref_free);
+ }
+ } else {
+ D1("Port was already open");
+ }
+
+ usb_autopm_put_interface(serial->parent->interface);
+
+ /* done */
+ if (result)
+ hso_serial_tiocmset(tty, NULL, TIOCM_RTS | TIOCM_DTR, 0);
+err_out:
+ mutex_unlock(&serial->parent->mutex);
+ return result;
+}
+
+/* close the requested serial port */
+static void hso_serial_close(struct tty_struct *tty, struct file *filp)
+{
+ struct hso_serial *serial = tty->driver_data;
+ u8 usb_gone;
+
+ D1("Closing serial port");
+
+ mutex_lock(&serial->parent->mutex);
+ usb_gone = serial->parent->usb_gone;
+
+ if (!usb_gone)
+ usb_autopm_get_interface(serial->parent->interface);
+
+ /* reset the rts and dtr */
+ /* do the actual close */
+ serial->open_count--;
+ if (serial->open_count <= 0) {
+ kref_put(&serial->parent->ref, hso_serial_ref_free);
+ serial->open_count = 0;
+ if (serial->tty) {
+ serial->tty->driver_data = NULL;
+ serial->tty = NULL;
+ }
+ if (!usb_gone)
+ hso_stop_serial_device(serial->parent);
+ }
+ if (!usb_gone)
+ usb_autopm_put_interface(serial->parent->interface);
+ mutex_unlock(&serial->parent->mutex);
+}
+
+/* close the requested serial port */
+static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf,
+ int count)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+ int space, tx_bytes;
+ unsigned long flags;
+
+ /* sanity check */
+ if (serial == NULL) {
+ printk(KERN_ERR "%s: serial is NULL\n", __func__);
+ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+
+ space = serial->tx_data_length - serial->tx_buffer_count;
+ tx_bytes = (count < space) ? count : space;
+
+ if (!tx_bytes)
+ goto out;
+
+ memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, tx_bytes);
+ serial->tx_buffer_count += tx_bytes;
+
+out:
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+
+ hso_kick_transmit(serial);
+ /* done */
+ return tx_bytes;
+}
+
+/* how much room is there for writing */
+static int hso_serial_write_room(struct tty_struct *tty)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+ int room;
+ unsigned long flags;
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ room = serial->tx_data_length - serial->tx_buffer_count;
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+
+ /* return free room */
+ return room;
+}
+
+/* setup the term */
+static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+ unsigned long flags;
+
+ if (old)
+ D5("Termios called with: cflags new[%d] - old[%d]",
+ tty->termios->c_cflag, old->c_cflag);
+
+ /* the actual setup */
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ if (serial->open_count)
+ _hso_serial_set_termios(tty, old);
+ else
+ tty->termios = old;
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+
+ /* done */
+ return;
+}
+
+/* how many characters in the buffer */
+static int hso_serial_chars_in_buffer(struct tty_struct *tty)
+{
+ struct hso_serial *serial = get_serial_by_tty(tty);
+ int chars;
+ unsigned long flags;
+
+ /* sanity check */
+ if (serial == NULL)
+ return 0;
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ chars = serial->tx_buffer_count;
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+
+ return chars;
+}
+
+static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ unsigned int value;
+ struct hso_serial *serial = get_serial_by_tty(tty);
+ unsigned long flags;
+
+ /* sanity check */
+ if (!serial) {
+ D1("no tty structures");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ value = ((serial->rts_state) ? TIOCM_RTS : 0) |
+ ((serial->dtr_state) ? TIOCM_DTR : 0);
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+
+ return value;
+}
+
+static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ int val = 0;
+ unsigned long flags;
+ int if_num;
+ struct hso_serial *serial = get_serial_by_tty(tty);
+
+ /* sanity check */
+ if (!serial) {
+ D1("no tty structures");
+ return -EINVAL;
+ }
+ if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber;
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ if (set & TIOCM_RTS)
+ serial->rts_state = 1;
+ if (set & TIOCM_DTR)
+ serial->dtr_state = 1;
+
+ if (clear & TIOCM_RTS)
+ serial->rts_state = 0;
+ if (clear & TIOCM_DTR)
+ serial->dtr_state = 0;
+
+ if (serial->dtr_state)
+ val |= 0x01;
+ if (serial->rts_state)
+ val |= 0x02;
+
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+
+ return usb_control_msg(serial->parent->usb,
+ usb_rcvctrlpipe(serial->parent->usb, 0), 0x22,
+ 0x21, val, if_num, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+}
+
+/* starts a transmit */
+static void hso_kick_transmit(struct hso_serial *serial)
+{
+ u8 *temp;
+ unsigned long flags;
+ int res;
+
+ spin_lock_irqsave(&serial->serial_lock, flags);
+ if (!serial->tx_buffer_count)
+ goto out;
+
+ if (serial->tx_urb_used)
+ goto out;
+
+ /* Wakeup USB interface if necessary */
+ if (hso_get_activity(serial->parent) == -EAGAIN)
+ goto out;
+
+ /* Switch pointers around to avoid memcpy */
+ temp = serial->tx_buffer;
+ serial->tx_buffer = serial->tx_data;
+ serial->tx_data = temp;
+ serial->tx_data_count = serial->tx_buffer_count;
+ serial->tx_buffer_count = 0;
+
+ /* If temp is set, it means we switched buffers */
+ if (temp && serial->write_data) {
+ res = serial->write_data(serial);
+ if (res >= 0)
+ serial->tx_urb_used = 1;
+ }
+out:
+ spin_unlock_irqrestore(&serial->serial_lock, flags);
+}
+
+/* make a request (for reading and writing data to muxed serial port) */
+static int mux_device_request(struct hso_serial *serial, u8 type, u16 port,
+ struct urb *ctrl_urb,
+ struct usb_ctrlrequest *ctrl_req,
+ u8 *ctrl_urb_data, u32 size)
+{
+ int result;
+ int pipe;
+
+ /* Sanity check */
+ if (!serial || !ctrl_urb || !ctrl_req) {
+ printk(KERN_ERR "%s: Wrong arguments\n", __func__);
+ return -EINVAL;
+ }
+
+ /* initialize */
+ ctrl_req->wValue = 0;
+ ctrl_req->wIndex = hso_port_to_mux(port);
+ ctrl_req->wLength = size;
+
+ if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) {
+ /* Reading command */
+ ctrl_req->bRequestType = USB_DIR_IN |
+ USB_TYPE_OPTION_VENDOR |
+ USB_RECIP_INTERFACE;
+ ctrl_req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
+ pipe = usb_rcvctrlpipe(serial->parent->usb, 0);
+ } else {
+ /* Writing command */
+ ctrl_req->bRequestType = USB_DIR_OUT |
+ USB_TYPE_OPTION_VENDOR |
+ USB_RECIP_INTERFACE;
+ ctrl_req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
+ pipe = usb_sndctrlpipe(serial->parent->usb, 0);
+ }
+ /* syslog */
+ D2("%s command (%02x) len: %d, port: %d",
+ type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write",
+ ctrl_req->bRequestType, ctrl_req->wLength, port);
+
+ /* Load ctrl urb */
+ ctrl_urb->transfer_flags = 0;
+ usb_fill_control_urb(ctrl_urb,
+ serial->parent->usb,
+ pipe,
+ (u8 *) ctrl_req,
+ ctrl_urb_data, size, ctrl_callback, serial);
+ /* Send it on merry way */
+ result = usb_submit_urb(ctrl_urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&ctrl_urb->dev->dev,
+ "%s failed submit ctrl_urb %d type %d", __func__,
+ result, type);
+ return result;
+ }
+
+ /* done */
+ return size;
+}
+
+/* called by intr_callback when read occurs */
+static int hso_mux_serial_read(struct hso_serial *serial)
+{
+ if (!serial)
+ return -EINVAL;
+
+ /* clean data */
+ memset(serial->rx_data[0], 0, CTRL_URB_RX_SIZE);
+ /* make the request */
+
+ if (serial->num_rx_urbs != 1) {
+ dev_err(&serial->parent->interface->dev,
+ "ERROR: mux'd reads with multiple buffers "
+ "not possible\n");
+ return 0;
+ }
+ return mux_device_request(serial,
+ USB_CDC_GET_ENCAPSULATED_RESPONSE,
+ serial->parent->port_spec & HSO_PORT_MASK,
+ serial->rx_urb[0],
+ &serial->ctrl_req_rx,
+ serial->rx_data[0], serial->rx_data_length);
+}
+
+/* used for muxed serial port callback (muxed serial read) */
+static void intr_callback(struct urb *urb)
+{
+ struct hso_shared_int *shared_int = urb->context;
+ struct hso_serial *serial;
+ unsigned char *port_req;
+ int status = urb->status;
+ int i;
+
+ usb_mark_last_busy(urb->dev);
+
+ /* sanity check */
+ if (!shared_int)
+ return;
+
+ /* status check */
+ if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+ D4("\n--- Got intr callback 0x%02X ---", status);
+
+ /* what request? */
+ port_req = urb->transfer_buffer;
+ D4(" port_req = 0x%.2X\n", *port_req);
+ /* loop over all muxed ports to find the one sending this */
+ for (i = 0; i < 8; i++) {
+ /* max 8 channels on MUX */
+ if (*port_req & (1 << i)) {
+ serial = get_serial_by_shared_int_and_type(shared_int,
+ (1 << i));
+ if (serial != NULL) {
+ D1("Pending read interrupt on port %d\n", i);
+ if (!test_and_set_bit(HSO_SERIAL_FLAG_RX_SENT,
+ &serial->flags)) {
+ /* Setup and send a ctrl req read on
+ * port i */
+ hso_mux_serial_read(serial);
+ } else {
+ D1("Already pending a read on "
+ "port %d\n", i);
+ }
+ }
+ }
+ }
+ /* Resubmit interrupt urb */
+ hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_ATOMIC);
+}
+
+/* called for writing to muxed serial port */
+static int hso_mux_serial_write_data(struct hso_serial *serial)
+{
+ if (NULL == serial)
+ return -EINVAL;
+
+ return mux_device_request(serial,
+ USB_CDC_SEND_ENCAPSULATED_COMMAND,
+ serial->parent->port_spec & HSO_PORT_MASK,
+ serial->tx_urb,
+ &serial->ctrl_req_tx,
+ serial->tx_data, serial->tx_data_count);
+}
+
+/* write callback for Diag and CS port */
+static void hso_std_serial_write_bulk_callback(struct urb *urb)
+{
+ struct hso_serial *serial = urb->context;
+ int status = urb->status;
+
+ /* sanity check */
+ if (!serial) {
+ D1("serial == NULL");
+ return;
+ }
+
+ spin_lock(&serial->serial_lock);
+ serial->tx_urb_used = 0;
+ spin_unlock(&serial->serial_lock);
+ if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+ hso_put_activity(serial->parent);
+ tty_wakeup(serial->tty);
+ hso_kick_transmit(serial);
+
+ D1(" ");
+ return;
+}
+
+/* called for writing diag or CS serial port */
+static int hso_std_serial_write_data(struct hso_serial *serial)
+{
+ int count = serial->tx_data_count;
+ int result;
+
+ usb_fill_bulk_urb(serial->tx_urb,
+ serial->parent->usb,
+ usb_sndbulkpipe(serial->parent->usb,
+ serial->out_endp->
+ bEndpointAddress & 0x7F),
+ serial->tx_data, serial->tx_data_count,
+ hso_std_serial_write_bulk_callback, serial);
+
+ result = usb_submit_urb(serial->tx_urb, GFP_ATOMIC);
+ if (result) {
+ dev_warn(&serial->parent->usb->dev,
+ "Failed to submit urb - res %d\n", result);
+ return result;
+ }
+
+ return count;
+}
+
+/* callback after read or write on muxed serial port */
+static void ctrl_callback(struct urb *urb)
+{
+ struct hso_serial *serial = urb->context;
+ struct usb_ctrlrequest *req;
+ int status = urb->status;
+
+ /* sanity check */
+ if (!serial)
+ return;
+
+ spin_lock(&serial->serial_lock);
+ serial->tx_urb_used = 0;
+ spin_unlock(&serial->serial_lock);
+ if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+
+ /* what request? */
+ req = (struct usb_ctrlrequest *)(urb->setup_packet);
+ D4("\n--- Got muxed ctrl callback 0x%02X ---", status);
+ D4("Actual length of urb = %d\n", urb->actual_length);
+ DUMP1(urb->transfer_buffer, urb->actual_length);
+
+ if (req->bRequestType ==
+ (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) {
+ /* response to a read command */
+ if (serial->open_count > 0) {
+ /* handle RX data the normal way */
+ put_rxbuf_data(urb, serial);
+ }
+
+ /* Re issue a read as long as we receive data. */
+ if (urb->actual_length != 0)
+ hso_mux_serial_read(serial);
+ else
+ clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
+ } else {
+ hso_put_activity(serial->parent);
+ tty_wakeup(serial->tty);
+ /* response to a write command */
+ hso_kick_transmit(serial);
+ }
+}
+
+/* handle RX data for serial port */
+static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
+{
+ struct tty_struct *tty = serial->tty;
+
+ /* Sanity check */
+ if (urb == NULL || serial == NULL) {
+ D1("serial = NULL");
+ return;
+ }
+
+ /* Push data to tty */
+ if (tty && urb->actual_length) {
+ D1("data to push to tty");
+ tty_insert_flip_string(tty, urb->transfer_buffer,
+ urb->actual_length);
+ tty_flip_buffer_push(tty);
+ }
+}
+
+/* read callback for Diag and CS port */
+static void hso_std_serial_read_bulk_callback(struct urb *urb)
+{
+ struct hso_serial *serial = urb->context;
+ int result;
+ int status = urb->status;
+
+ /* sanity check */
+ if (!serial) {
+ D1("serial == NULL");
+ return;
+ } else if (status) {
+ log_usb_status(status, __func__);
+ return;
+ }
+
+ D4("\n--- Got serial_read_bulk callback %02x ---", status);
+ D1("Actual length = %d\n", urb->actual_length);
+ DUMP1(urb->transfer_buffer, urb->actual_length);
+
+ /* Anyone listening? */
+ if (serial->open_count == 0)
+ return;
+
+ if (status == 0) {
+ if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
+ u32 rest;
+ u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
+ rest =
+ urb->actual_length %
+ serial->in_endp->wMaxPacketSize;
+ if (((rest == 5) || (rest == 6))
+ && !memcmp(((u8 *) urb->transfer_buffer) +
+ urb->actual_length - 4, crc_check, 4)) {
+ urb->actual_length -= 4;
+ }
+ }
+ /* Valid data, handle RX data */
+ put_rxbuf_data(urb, serial);
+ } else if (status == -ENOENT || status == -ECONNRESET) {
+ /* Unlinked - check for throttled port. */
+ D2("Port %d, successfully unlinked urb", serial->minor);
+ } else {
+ D2("Port %d, status = %d for read urb", serial->minor, status);
+ return;
+ }
+
+ usb_mark_last_busy(urb->dev);
+
+ /* We are done with this URB, resubmit it. Prep the USB to wait for
+ * another frame */
+ usb_fill_bulk_urb(urb, serial->parent->usb,
+ usb_rcvbulkpipe(serial->parent->usb,
+ serial->in_endp->
+ bEndpointAddress & 0x7F),
+ urb->transfer_buffer, serial->rx_data_length,
+ hso_std_serial_read_bulk_callback, serial);
+ /* Give this to the USB subsystem so it can tell us when more data
+ * arrives. */
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d",
+ __func__, result);
+ }
+}
+
+/* Base driver functions */
+
+static void hso_log_port(struct hso_device *hso_dev)
+{
+ char *port_type;
+ char port_dev[20];
+
+ switch (hso_dev->port_spec & HSO_PORT_MASK) {
+ case HSO_PORT_CONTROL:
+ port_type = "Control";
+ break;
+ case HSO_PORT_APP:
+ port_type = "Application";
+ break;
+ case HSO_PORT_GPS:
+ port_type = "GPS";
+ break;
+ case HSO_PORT_GPS_CONTROL:
+ port_type = "GPS control";
+ break;
+ case HSO_PORT_APP2:
+ port_type = "Application2";
+ break;
+ case HSO_PORT_PCSC:
+ port_type = "PCSC";
+ break;
+ case HSO_PORT_DIAG:
+ port_type = "Diagnostic";
+ break;
+ case HSO_PORT_DIAG2:
+ port_type = "Diagnostic2";
+ break;
+ case HSO_PORT_MODEM:
+ port_type = "Modem";
+ break;
+ case HSO_PORT_NETWORK:
+ port_type = "Network";
+ break;
+ default:
+ port_type = "Unknown";
+ break;
+ }
+ if ((hso_dev->port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
+ sprintf(port_dev, "%s", dev2net(hso_dev)->net->name);
+ } else
+ sprintf(port_dev, "/dev/%s%d", tty_filename,
+ dev2ser(hso_dev)->minor);
+
+ dev_dbg(&hso_dev->interface->dev, "HSO: Found %s port %s\n",
+ port_type, port_dev);
+}
+
+static int hso_start_net_device(struct hso_device *hso_dev)
+{
+ int i, result = 0;
+ struct hso_net *hso_net = dev2net(hso_dev);
+
+ if (!hso_net)
+ return -ENODEV;
+
+ /* send URBs for all read buffers */
+ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
+
+ /* Prep a receive URB */
+ usb_fill_bulk_urb(hso_net->mux_bulk_rx_urb_pool[i],
+ hso_dev->usb,
+ usb_rcvbulkpipe(hso_dev->usb,
+ hso_net->in_endp->
+ bEndpointAddress & 0x7F),
+ hso_net->mux_bulk_rx_buf_pool[i],
+ MUX_BULK_RX_BUF_SIZE, read_bulk_callback,
+ hso_net);
+
+ /* Put it out there so the device can send us stuff */
+ result = usb_submit_urb(hso_net->mux_bulk_rx_urb_pool[i],
+ GFP_NOIO);
+ if (result)
+ dev_warn(&hso_dev->usb->dev,
+ "%s failed mux_bulk_rx_urb[%d] %d\n", __func__,
+ i, result);
+ }
+
+ return result;
+}
+
+static int hso_stop_net_device(struct hso_device *hso_dev)
+{
+ int i;
+ struct hso_net *hso_net = dev2net(hso_dev);
+
+ if (!hso_net)
+ return -ENODEV;
+
+ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
+ if (hso_net->mux_bulk_rx_urb_pool[i])
+ usb_kill_urb(hso_net->mux_bulk_rx_urb_pool[i]);
+
+ }
+ if (hso_net->mux_bulk_tx_urb)
+ usb_kill_urb(hso_net->mux_bulk_tx_urb);
+
+ return 0;
+}
+
+static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags)
+{
+ int i, result = 0;
+ struct hso_serial *serial = dev2ser(hso_dev);
+
+ if (!serial)
+ return -ENODEV;
+
+ /* If it is not the MUX port fill in and submit a bulk urb (already
+ * allocated in hso_serial_start) */
+ if (!(serial->parent->port_spec & HSO_INTF_MUX)) {
+ for (i = 0; i < serial->num_rx_urbs; i++) {
+ usb_fill_bulk_urb(serial->rx_urb[i],
+ serial->parent->usb,
+ usb_rcvbulkpipe(serial->parent->usb,
+ serial->in_endp->
+ bEndpointAddress &
+ 0x7F),
+ serial->rx_data[i],
+ serial->rx_data_length,
+ hso_std_serial_read_bulk_callback,
+ serial);
+ result = usb_submit_urb(serial->rx_urb[i], flags);
+ if (result) {
+ dev_warn(&serial->parent->usb->dev,
+ "Failed to submit urb - res %d\n",
+ result);
+ break;
+ }
+ }
+ } else {
+ mutex_lock(&serial->shared_int->shared_int_lock);
+ if (!serial->shared_int->use_count) {
+ result =
+ hso_mux_submit_intr_urb(serial->shared_int,
+ hso_dev->usb, flags);
+ }
+ serial->shared_int->use_count++;
+ mutex_unlock(&serial->shared_int->shared_int_lock);
+ }
+
+ return result;
+}
+
+static int hso_stop_serial_device(struct hso_device *hso_dev)
+{
+ int i;
+ struct hso_serial *serial = dev2ser(hso_dev);
+
+ if (!serial)
+ return -ENODEV;
+
+ for (i = 0; i < serial->num_rx_urbs; i++) {
+ if (serial->rx_urb[i])
+ usb_kill_urb(serial->rx_urb[i]);
+ }
+
+ if (serial->tx_urb)
+ usb_kill_urb(serial->tx_urb);
+
+ if (serial->shared_int) {
+ mutex_lock(&serial->shared_int->shared_int_lock);
+ if (serial->shared_int->use_count &&
+ (--serial->shared_int->use_count == 0)) {
+ struct urb *urb;
+
+ urb = serial->shared_int->shared_intr_urb;
+ if (urb)
+ usb_kill_urb(urb);
+ }
+ mutex_unlock(&serial->shared_int->shared_int_lock);
+ }
+
+ return 0;
+}
+
+static void hso_serial_common_free(struct hso_serial *serial)
+{
+ int i;
+
+ if (serial->parent->dev)
+ device_remove_file(serial->parent->dev, &dev_attr_hsotype);
+
+ tty_unregister_device(tty_drv, serial->minor);
+
+ for (i = 0; i < serial->num_rx_urbs; i++) {
+ /* unlink and free RX URB */
+ usb_free_urb(serial->rx_urb[i]);
+ /* free the RX buffer */
+ kfree(serial->rx_data[i]);
+ }
+
+ /* unlink and free TX URB */
+ usb_free_urb(serial->tx_urb);
+ kfree(serial->tx_data);
+}
+
+static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
+ int rx_size, int tx_size)
+{
+ struct device *dev;
+ int minor;
+ int i;
+
+ minor = get_free_serial_index();
+ if (minor < 0)
+ goto exit;
+
+ /* register our minor number */
+ serial->parent->dev = tty_register_device(tty_drv, minor,
+ &serial->parent->interface->dev);
+ dev = serial->parent->dev;
+ dev->driver_data = serial->parent;
+ i = device_create_file(dev, &dev_attr_hsotype);
+
+ /* fill in specific data for later use */
+ serial->minor = minor;
+ serial->magic = HSO_SERIAL_MAGIC;
+ spin_lock_init(&serial->serial_lock);
+ serial->num_rx_urbs = num_urbs;
+
+ /* RX, allocate urb and initialize */
+
+ /* prepare our RX buffer */
+ serial->rx_data_length = rx_size;
+ for (i = 0; i < serial->num_rx_urbs; i++) {
+ serial->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
+ if (!serial->rx_urb[i]) {
+ dev_err(dev, "Could not allocate urb?\n");
+ goto exit;
+ }
+ serial->rx_urb[i]->transfer_buffer = NULL;
+ serial->rx_urb[i]->transfer_buffer_length = 0;
+ serial->rx_data[i] = kzalloc(serial->rx_data_length,
+ GFP_KERNEL);
+ if (!serial->rx_data[i]) {
+ dev_err(dev, "%s - Out of memory\n", __func__);
+ goto exit;
+ }
+ }
+
+ /* TX, allocate urb and initialize */
+ serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!serial->tx_urb) {
+ dev_err(dev, "Could not allocate urb?\n");
+ goto exit;
+ }
+ serial->tx_urb->transfer_buffer = NULL;
+ serial->tx_urb->transfer_buffer_length = 0;
+ /* prepare our TX buffer */
+ serial->tx_data_count = 0;
+ serial->tx_buffer_count = 0;
+ serial->tx_data_length = tx_size;
+ serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL);
+ if (!serial->tx_data) {
+ dev_err(dev, "%s - Out of memory", __func__);
+ goto exit;
+ }
+ serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL);
+ if (!serial->tx_buffer) {
+ dev_err(dev, "%s - Out of memory", __func__);
+ goto exit;
+ }
+
+ return 0;
+exit:
+ hso_serial_common_free(serial);
+ return -1;
+}
+
+/* Frees a general hso device */
+static void hso_free_device(struct hso_device *hso_dev)
+{
+ kfree(hso_dev);
+}
+
+/* Creates a general hso device */
+static struct hso_device *hso_create_device(struct usb_interface *intf,
+ int port_spec)
+{
+ struct hso_device *hso_dev;
+
+ hso_dev = kzalloc(sizeof(*hso_dev), GFP_ATOMIC);
+ if (!hso_dev)
+ return NULL;
+
+ hso_dev->port_spec = port_spec;
+ hso_dev->usb = interface_to_usbdev(intf);
+ hso_dev->interface = intf;
+ kref_init(&hso_dev->ref);
+ mutex_init(&hso_dev->mutex);
+
+ INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
+ INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
+
+ return hso_dev;
+}
+
+/* Removes a network device in the network device table */
+static int remove_net_device(struct hso_device *hso_dev)
+{
+ int i;
+
+ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
+ if (network_table[i] == hso_dev) {
+ network_table[i] = NULL;
+ break;
+ }
+ }
+ if (i == HSO_MAX_NET_DEVICES)
+ return -1;
+ return 0;
+}
+
+/* Frees our network device */
+static void hso_free_net_device(struct hso_device *hso_dev)
+{
+ int i;
+ struct hso_net *hso_net = dev2net(hso_dev);
+
+ if (!hso_net)
+ return;
+
+ /* start freeing */
+ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
+ usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]);
+ kfree(hso_net->mux_bulk_rx_buf_pool[i]);
+ }
+ usb_free_urb(hso_net->mux_bulk_tx_urb);
+ kfree(hso_net->mux_bulk_tx_buf);
+
+ remove_net_device(hso_net->parent);
+
+ if (hso_net->net) {
+ unregister_netdev(hso_net->net);
+ free_netdev(hso_net->net);
+ }
+
+ hso_free_device(hso_dev);
+}
+
+/* initialize the network interface */
+static void hso_net_init(struct net_device *net)
+{
+ struct hso_net *hso_net = netdev_priv(net);
+
+ D1("sizeof hso_net is %d", (int)sizeof(*hso_net));
+
+ /* fill in the other fields */
+ net->open = hso_net_open;
+ net->stop = hso_net_close;
+ net->hard_start_xmit = hso_net_start_xmit;
+ net->tx_timeout = hso_net_tx_timeout;
+ net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
+ net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+ net->type = ARPHRD_NONE;
+ net->mtu = DEFAULT_MTU - 14;
+ net->tx_queue_len = 10;
+ SET_ETHTOOL_OPS(net, &ops);
+
+ /* and initialize the semaphore */
+ spin_lock_init(&hso_net->net_lock);
+}
+
+/* Adds a network device in the network device table */
+static int add_net_device(struct hso_device *hso_dev)
+{
+ int i;
+
+ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
+ if (network_table[i] == NULL) {
+ network_table[i] = hso_dev;
+ break;
+ }
+ }
+ if (i == HSO_MAX_NET_DEVICES)
+ return -1;
+ return 0;
+}
+
+static int hso_radio_toggle(void *data, enum rfkill_state state)
+{
+ struct hso_device *hso_dev = data;
+ int enabled = (state == RFKILL_STATE_ON);
+ int rv;
+
+ mutex_lock(&hso_dev->mutex);
+ if (hso_dev->usb_gone)
+ rv = 0;
+ else
+ rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0),
+ enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+ mutex_unlock(&hso_dev->mutex);
+ return rv;
+}
+
+/* Creates and sets up everything for rfkill */
+static void hso_create_rfkill(struct hso_device *hso_dev,
+ struct usb_interface *interface)
+{
+ struct hso_net *hso_net = dev2net(hso_dev);
+ struct device *dev = hso_dev->dev;
+ char *rfkn;
+
+ hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
+ RFKILL_TYPE_WLAN);
+ if (!hso_net->rfkill) {
+ dev_err(dev, "%s - Out of memory", __func__);
+ return;
+ }
+ rfkn = kzalloc(20, GFP_KERNEL);
+ if (!rfkn) {
+ rfkill_free(hso_net->rfkill);
+ dev_err(dev, "%s - Out of memory", __func__);
+ return;
+ }
+ snprintf(rfkn, 20, "hso-%d",
+ interface->altsetting->desc.bInterfaceNumber);
+ hso_net->rfkill->name = rfkn;
+ hso_net->rfkill->state = RFKILL_STATE_ON;
+ hso_net->rfkill->data = hso_dev;
+ hso_net->rfkill->toggle_radio = hso_radio_toggle;
+ if (rfkill_register(hso_net->rfkill) < 0) {
+ kfree(rfkn);
+ hso_net->rfkill->name = NULL;
+ rfkill_free(hso_net->rfkill);
+ dev_err(dev, "%s - Failed to register rfkill", __func__);
+ return;
+ }
+}
+
+/* Creates our network device */
+static struct hso_device *hso_create_net_device(struct usb_interface *interface)
+{
+ int result, i;
+ struct net_device *net;
+ struct hso_net *hso_net;
+ struct hso_device *hso_dev;
+
+ hso_dev = hso_create_device(interface, HSO_INTF_MUX | HSO_PORT_NETWORK);
+ if (!hso_dev)
+ return NULL;
+
+ /* allocate our network device, then we can put in our private data */
+ /* call hso_net_init to do the basic initialization */
+ net = alloc_netdev(sizeof(struct hso_net), "hso%d", hso_net_init);
+ if (!net) {
+ dev_err(&interface->dev, "Unable to create ethernet device\n");
+ goto exit;
+ }
+
+ hso_net = netdev_priv(net);
+
+ hso_dev->port_data.dev_net = hso_net;
+ hso_net->net = net;
+ hso_net->parent = hso_dev;
+
+ hso_net->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
+ USB_DIR_IN);
+ if (!hso_net->in_endp) {
+ dev_err(&interface->dev, "Can't find BULK IN endpoint\n");
+ goto exit;
+ }
+ hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
+ USB_DIR_OUT);
+ if (!hso_net->out_endp) {
+ dev_err(&interface->dev, "Can't find BULK OUT endpoint\n");
+ goto exit;
+ }
+ SET_NETDEV_DEV(net, &interface->dev);
+
+ /* registering our net device */
+ result = register_netdev(net);
+ if (result) {
+ dev_err(&interface->dev, "Failed to register device\n");
+ goto exit;
+ }
+
+ /* start allocating */
+ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
+ hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL);
+ if (!hso_net->mux_bulk_rx_urb_pool[i]) {
+ dev_err(&interface->dev, "Could not allocate rx urb\n");
+ goto exit;
+ }
+ hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE,
+ GFP_KERNEL);
+ if (!hso_net->mux_bulk_rx_buf_pool[i]) {
+ dev_err(&interface->dev, "Could not allocate rx buf\n");
+ goto exit;
+ }
+ }
+ hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!hso_net->mux_bulk_tx_urb) {
+ dev_err(&interface->dev, "Could not allocate tx urb\n");
+ goto exit;
+ }
+ hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL);
+ if (!hso_net->mux_bulk_tx_buf) {
+ dev_err(&interface->dev, "Could not allocate tx buf\n");
+ goto exit;
+ }
+
+ add_net_device(hso_dev);
+
+ hso_log_port(hso_dev);
+
+ hso_create_rfkill(hso_dev, interface);
+
+ return hso_dev;
+exit:
+ hso_free_net_device(hso_dev);
+ return NULL;
+}
+
+/* Frees an AT channel ( goes for both mux and non-mux ) */
+static void hso_free_serial_device(struct hso_device *hso_dev)
+{
+ struct hso_serial *serial = dev2ser(hso_dev);
+
+ if (!serial)
+ return;
+ set_serial_by_index(serial->minor, NULL);
+
+ hso_serial_common_free(serial);
+
+ if (serial->shared_int) {
+ mutex_lock(&serial->shared_int->shared_int_lock);
+ if (--serial->shared_int->ref_count == 0)
+ hso_free_shared_int(serial->shared_int);
+ else
+ mutex_unlock(&serial->shared_int->shared_int_lock);
+ }
+ kfree(serial);
+ hso_free_device(hso_dev);
+}
+
+/* Creates a bulk AT channel */
+static struct hso_device *hso_create_bulk_serial_device(
+ struct usb_interface *interface, int port)
+{
+ struct hso_device *hso_dev;
+ struct hso_serial *serial;
+ int num_urbs;
+
+ hso_dev = hso_create_device(interface, port);
+ if (!hso_dev)
+ return NULL;
+
+ serial = kzalloc(sizeof(*serial), GFP_KERNEL);
+ if (!serial)
+ goto exit;
+
+ serial->parent = hso_dev;
+ hso_dev->port_data.dev_serial = serial;
+
+ if (port & HSO_PORT_MODEM)
+ num_urbs = 2;
+ else
+ num_urbs = 1;
+
+ if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE,
+ BULK_URB_TX_SIZE))
+ goto exit;
+
+ serial->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
+ USB_DIR_IN);
+ if (!serial->in_endp) {
+ dev_err(&interface->dev, "Failed to find BULK IN ep\n");
+ goto exit;
+ }
+
+ if (!
+ (serial->out_endp =
+ hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) {
+ dev_err(&interface->dev, "Failed to find BULK IN ep\n");
+ goto exit;
+ }
+
+ serial->write_data = hso_std_serial_write_data;
+
+ /* and record this serial */
+ set_serial_by_index(serial->minor, serial);
+
+ /* setup the proc dirs and files if needed */
+ hso_log_port(hso_dev);
+
+ /* done, return it */
+ return hso_dev;
+exit:
+ if (hso_dev && serial)
+ hso_serial_common_free(serial);
+ kfree(serial);
+ hso_free_device(hso_dev);
+ return NULL;
+}
+
+/* Creates a multiplexed AT channel */
+static
+struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface,
+ int port,
+ struct hso_shared_int *mux)
+{
+ struct hso_device *hso_dev;
+ struct hso_serial *serial;
+ int port_spec;
+
+ port_spec = HSO_INTF_MUX;
+ port_spec &= ~HSO_PORT_MASK;
+
+ port_spec |= hso_mux_to_port(port);
+ if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NO_PORT)
+ return NULL;
+
+ hso_dev = hso_create_device(interface, port_spec);
+ if (!hso_dev)
+ return NULL;
+
+ serial = kzalloc(sizeof(*serial), GFP_KERNEL);
+ if (!serial)
+ goto exit;
+
+ hso_dev->port_data.dev_serial = serial;
+ serial->parent = hso_dev;
+
+ if (hso_serial_common_create
+ (serial, 1, CTRL_URB_RX_SIZE, CTRL_URB_TX_SIZE))
+ goto exit;
+
+ serial->tx_data_length--;
+ serial->write_data = hso_mux_serial_write_data;
+
+ serial->shared_int = mux;
+ mutex_lock(&serial->shared_int->shared_int_lock);
+ serial->shared_int->ref_count++;
+ mutex_unlock(&serial->shared_int->shared_int_lock);
+
+ /* and record this serial */
+ set_serial_by_index(serial->minor, serial);
+
+ /* setup the proc dirs and files if needed */
+ hso_log_port(hso_dev);
+
+ /* done, return it */
+ return hso_dev;
+
+exit:
+ if (serial) {
+ tty_unregister_device(tty_drv, serial->minor);
+ kfree(serial);
+ }
+ if (hso_dev)
+ hso_free_device(hso_dev);
+ return NULL;
+
+}
+
+static void hso_free_shared_int(struct hso_shared_int *mux)
+{
+ usb_free_urb(mux->shared_intr_urb);
+ kfree(mux->shared_intr_buf);
+ mutex_unlock(&mux->shared_int_lock);
+ kfree(mux);
+}
+
+static
+struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface)
+{
+ struct hso_shared_int *mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+
+ if (!mux)
+ return NULL;
+
+ mux->intr_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_INT,
+ USB_DIR_IN);
+ if (!mux->intr_endp) {
+ dev_err(&interface->dev, "Can't find INT IN endpoint\n");
+ goto exit;
+ }
+
+ mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!mux->shared_intr_urb) {
+ dev_err(&interface->dev, "Could not allocate intr urb?");
+ goto exit;
+ }
+ mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize,
+ GFP_KERNEL);
+ if (!mux->shared_intr_buf) {
+ dev_err(&interface->dev, "Could not allocate intr buf?");
+ goto exit;
+ }
+
+ mutex_init(&mux->shared_int_lock);
+
+ return mux;
+
+exit:
+ kfree(mux->shared_intr_buf);
+ usb_free_urb(mux->shared_intr_urb);
+ kfree(mux);
+ return NULL;
+}
+
+/* Gets the port spec for a certain interface */
+static int hso_get_config_data(struct usb_interface *interface)
+{
+ struct usb_device *usbdev = interface_to_usbdev(interface);
+ u8 config_data[17];
+ u32 if_num = interface->altsetting->desc.bInterfaceNumber;
+ s32 result;
+
+ if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
+ 0x86, 0xC0, 0, 0, config_data, 17,
+ USB_CTRL_SET_TIMEOUT) != 0x11) {
+ return -EIO;
+ }
+
+ switch (config_data[if_num]) {
+ case 0x0:
+ result = 0;
+ break;
+ case 0x1:
+ result = HSO_PORT_DIAG;
+ break;
+ case 0x2:
+ result = HSO_PORT_GPS;
+ break;
+ case 0x3:
+ result = HSO_PORT_GPS_CONTROL;
+ break;
+ case 0x4:
+ result = HSO_PORT_APP;
+ break;
+ case 0x5:
+ result = HSO_PORT_APP2;
+ break;
+ case 0x6:
+ result = HSO_PORT_CONTROL;
+ break;
+ case 0x7:
+ result = HSO_PORT_NETWORK;
+ break;
+ case 0x8:
+ result = HSO_PORT_MODEM;
+ break;
+ case 0x9:
+ result = HSO_PORT_MSD;
+ break;
+ case 0xa:
+ result = HSO_PORT_PCSC;
+ break;
+ case 0xb:
+ result = HSO_PORT_VOICE;
+ break;
+ default:
+ result = 0;
+ }
+
+ if (result)
+ result |= HSO_INTF_BULK;
+
+ if (config_data[16] & 0x1)
+ result |= HSO_INFO_CRC_BUG;
+
+ return result;
+}
+
+/* called once for each interface upon device insertion */
+static int hso_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ int mux, i, if_num, port_spec;
+ unsigned char port_mask;
+ struct hso_device *hso_dev = NULL;
+ struct hso_shared_int *shared_int;
+ struct hso_device *tmp_dev = NULL;
+
+ if_num = interface->altsetting->desc.bInterfaceNumber;
+
+ /* Get the interface/port specification from either driver_info or from
+ * the device itself */
+ if (id->driver_info)
+ port_spec = ((u32 *)(id->driver_info))[if_num];
+ else
+ port_spec = hso_get_config_data(interface);
+
+ if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
+ dev_err(&interface->dev, "Not our interface\n");
+ return -ENODEV;
+ }
+ /* Check if we need to switch to alt interfaces prior to port
+ * configuration */
+ if (interface->num_altsetting > 1)
+ usb_set_interface(interface_to_usbdev(interface), if_num, 1);
+ interface->needs_remote_wakeup = 1;
+
+ /* Allocate new hso device(s) */
+ switch (port_spec & HSO_INTF_MASK) {
+ case HSO_INTF_MUX:
+ if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
+ /* Create the network device */
+ if (!disable_net) {
+ hso_dev = hso_create_net_device(interface);
+ if (!hso_dev)
+ goto exit;
+ tmp_dev = hso_dev;
+ }
+ }
+
+ if (hso_get_mux_ports(interface, &port_mask))
+ /* TODO: de-allocate everything */
+ goto exit;
+
+ shared_int = hso_create_shared_int(interface);
+ if (!shared_int)
+ goto exit;
+
+ for (i = 1, mux = 0; i < 0x100; i = i << 1, mux++) {
+ if (port_mask & i) {
+ hso_dev = hso_create_mux_serial_device(
+ interface, i, shared_int);
+ if (!hso_dev)
+ goto exit;
+ }
+ }
+
+ if (tmp_dev)
+ hso_dev = tmp_dev;
+ break;
+
+ case HSO_INTF_BULK:
+ /* It's a regular bulk interface */
+ if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK)
+ && !disable_net)
+ hso_dev = hso_create_net_device(interface);
+ else
+ hso_dev =
+ hso_create_bulk_serial_device(interface, port_spec);
+ if (!hso_dev)
+ goto exit;
+ break;
+ default:
+ goto exit;
+ }
+
+ usb_driver_claim_interface(&hso_driver, interface, hso_dev);
+
+ /* save our data pointer in this device */
+ usb_set_intfdata(interface, hso_dev);
+
+ /* done */
+ return 0;
+exit:
+ hso_free_interface(interface);
+ return -ENODEV;
+}
+
+/* device removed, cleaning up */
+static void hso_disconnect(struct usb_interface *interface)
+{
+ hso_free_interface(interface);
+
+ /* remove reference of our private data */
+ usb_set_intfdata(interface, NULL);
+
+ usb_driver_release_interface(&hso_driver, interface);
+}
+
+static void async_get_intf(struct work_struct *data)
+{
+ struct hso_device *hso_dev =
+ container_of(data, struct hso_device, async_get_intf);
+ usb_autopm_get_interface(hso_dev->interface);
+}
+
+static void async_put_intf(struct work_struct *data)
+{
+ struct hso_device *hso_dev =
+ container_of(data, struct hso_device, async_put_intf);
+ usb_autopm_put_interface(hso_dev->interface);
+}
+
+static int hso_get_activity(struct hso_device *hso_dev)
+{
+ if (hso_dev->usb->state == USB_STATE_SUSPENDED) {
+ if (!hso_dev->is_active) {
+ hso_dev->is_active = 1;
+ schedule_work(&hso_dev->async_get_intf);
+ }
+ }
+
+ if (hso_dev->usb->state != USB_STATE_CONFIGURED)
+ return -EAGAIN;
+
+ usb_mark_last_busy(hso_dev->usb);
+
+ return 0;
+}
+
+static int hso_put_activity(struct hso_device *hso_dev)
+{
+ if (hso_dev->usb->state != USB_STATE_SUSPENDED) {
+ if (hso_dev->is_active) {
+ hso_dev->is_active = 0;
+ schedule_work(&hso_dev->async_put_intf);
+ return -EAGAIN;
+ }
+ }
+ hso_dev->is_active = 0;
+ return 0;
+}
+
+/* called by kernel when we need to suspend device */
+static int hso_suspend(struct usb_interface *iface, pm_message_t message)
+{
+ int i, result;
+
+ /* Stop all serial ports */
+ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
+ if (serial_table[i] && (serial_table[i]->interface == iface)) {
+ result = hso_stop_serial_device(serial_table[i]);
+ if (result)
+ goto out;
+ }
+ }
+
+ /* Stop all network ports */
+ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
+ if (network_table[i] &&
+ (network_table[i]->interface == iface)) {
+ result = hso_stop_net_device(network_table[i]);
+ if (result)
+ goto out;
+ }
+ }
+
+out:
+ return 0;
+}
+
+/* called by kernel when we need to resume device */
+static int hso_resume(struct usb_interface *iface)
+{
+ int i, result = 0;
+ struct hso_net *hso_net;
+
+ /* Start all serial ports */
+ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
+ if (serial_table[i] && (serial_table[i]->interface == iface)) {
+ if (dev2ser(serial_table[i])->open_count) {
+ result =
+ hso_start_serial_device(serial_table[i], GFP_NOIO);
+ hso_kick_transmit(dev2ser(serial_table[i]));
+ if (result)
+ goto out;
+ }
+ }
+ }
+
+ /* Start all network ports */
+ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
+ if (network_table[i] &&
+ (network_table[i]->interface == iface)) {
+ hso_net = dev2net(network_table[i]);
+ /* First transmit any lingering data, then restart the
+ * device. */
+ if (hso_net->skb_tx_buf) {
+ dev_dbg(&iface->dev,
+ "Transmitting lingering data\n");
+ hso_net_start_xmit(hso_net->skb_tx_buf,
+ hso_net->net);
+ }
+ result = hso_start_net_device(network_table[i]);
+ if (result)
+ goto out;
+ }
+ }
+
+out:
+ return result;
+}
+
+static void hso_serial_ref_free(struct kref *ref)
+{
+ struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
+
+ hso_free_serial_device(hso_dev);
+}
+
+static void hso_free_interface(struct usb_interface *interface)
+{
+ struct hso_serial *hso_dev;
+ int i;
+
+ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
+ if (serial_table[i]
+ && (serial_table[i]->interface == interface)) {
+ hso_dev = dev2ser(serial_table[i]);
+ if (hso_dev->tty)
+ tty_hangup(hso_dev->tty);
+ mutex_lock(&hso_dev->parent->mutex);
+ hso_dev->parent->usb_gone = 1;
+ mutex_unlock(&hso_dev->parent->mutex);
+ kref_put(&serial_table[i]->ref, hso_serial_ref_free);
+ }
+ }
+
+ for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
+ if (network_table[i]
+ && (network_table[i]->interface == interface)) {
+ struct rfkill *rfk = dev2net(network_table[i])->rfkill;
+ /* hso_stop_net_device doesn't stop the net queue since
+ * traffic needs to start it again when suspended */
+ netif_stop_queue(dev2net(network_table[i])->net);
+ hso_stop_net_device(network_table[i]);
+ cancel_work_sync(&network_table[i]->async_put_intf);
+ cancel_work_sync(&network_table[i]->async_get_intf);
+ if(rfk)
+ rfkill_unregister(rfk);
+ hso_free_net_device(network_table[i]);
+ }
+ }
+}
+
+/* Helper functions */
+
+/* Get the endpoint ! */
+static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
+ int type, int dir)
+{
+ int i;
+ struct usb_host_interface *iface = intf->cur_altsetting;
+ struct usb_endpoint_descriptor *endp;
+
+ for (i = 0; i < iface->desc.bNumEndpoints; i++) {
+ endp = &iface->endpoint[i].desc;
+ if (((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir) &&
+ ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == type))
+ return endp;
+ }
+
+ return NULL;
+}
+
+/* Get the byte that describes which ports are enabled */
+static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports)
+{
+ int i;
+ struct usb_host_interface *iface = intf->cur_altsetting;
+
+ if (iface->extralen == 3) {
+ *ports = iface->extra[2];
+ return 0;
+ }
+
+ for (i = 0; i < iface->desc.bNumEndpoints; i++) {
+ if (iface->endpoint[i].extralen == 3) {
+ *ports = iface->endpoint[i].extra[2];
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/* interrupt urb needs to be submitted, used for serial read of muxed port */
+static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
+ struct usb_device *usb, gfp_t gfp)
+{
+ int result;
+
+ usb_fill_int_urb(shared_int->shared_intr_urb, usb,
+ usb_rcvintpipe(usb,
+ shared_int->intr_endp->bEndpointAddress & 0x7F),
+ shared_int->shared_intr_buf,
+ shared_int->intr_endp->wMaxPacketSize,
+ intr_callback, shared_int,
+ shared_int->intr_endp->bInterval);
+
+ result = usb_submit_urb(shared_int->shared_intr_urb, gfp);
+ if (result)
+ dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__,
+ result);
+
+ return result;
+}
+
+/* operations setup of the serial interface */
+static struct tty_operations hso_serial_ops = {
+ .open = hso_serial_open,
+ .close = hso_serial_close,
+ .write = hso_serial_write,
+ .write_room = hso_serial_write_room,
+ .set_termios = hso_serial_set_termios,
+ .chars_in_buffer = hso_serial_chars_in_buffer,
+ .tiocmget = hso_serial_tiocmget,
+ .tiocmset = hso_serial_tiocmset,
+};
+
+static struct usb_driver hso_driver = {
+ .name = driver_name,
+ .probe = hso_probe,
+ .disconnect = hso_disconnect,
+ .id_table = hso_ids,
+ .suspend = hso_suspend,
+ .resume = hso_resume,
+ .supports_autosuspend = 1,
+};
+
+static int __init hso_init(void)
+{
+ int i;
+ int result;
+
+ /* put it in the log */
+ printk(KERN_INFO "hso: %s\n", version);
+
+ /* Initialise the serial table semaphore and table */
+ spin_lock_init(&serial_table_lock);
+ for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++)
+ serial_table[i] = NULL;
+
+ /* allocate our driver using the proper amount of supported minors */
+ tty_drv = alloc_tty_driver(HSO_SERIAL_TTY_MINORS);
+ if (!tty_drv)
+ return -ENOMEM;
+
+ /* fill in all needed values */
+ tty_drv->magic = TTY_DRIVER_MAGIC;
+ tty_drv->owner = THIS_MODULE;
+ tty_drv->driver_name = driver_name;
+ tty_drv->name = tty_filename;
+
+ /* if major number is provided as parameter, use that one */
+ if (tty_major)
+ tty_drv->major = tty_major;
+
+ tty_drv->minor_start = 0;
+ tty_drv->num = HSO_SERIAL_TTY_MINORS;
+ tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
+ tty_drv->subtype = SERIAL_TYPE_NORMAL;
+ tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ tty_drv->init_termios = tty_std_termios;
+ tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ tty_drv->termios = hso_serial_termios;
+ tty_drv->termios_locked = hso_serial_termios_locked;
+ tty_set_operations(tty_drv, &hso_serial_ops);
+
+ /* register the tty driver */
+ result = tty_register_driver(tty_drv);
+ if (result) {
+ printk(KERN_ERR "%s - tty_register_driver failed(%d)\n",
+ __func__, result);
+ return result;
+ }
+
+ /* register this module as an usb driver */
+ result = usb_register(&hso_driver);
+ if (result) {
+ printk(KERN_ERR "Could not register hso driver? error: %d\n",
+ result);
+ /* cleanup serial interface */
+ tty_unregister_driver(tty_drv);
+ return result;
+ }
+
+ /* done */
+ return 0;
+}
+
+static void __exit hso_exit(void)
+{
+ printk(KERN_INFO "hso: unloaded\n");
+
+ tty_unregister_driver(tty_drv);
+ /* deregister the usb driver */
+ usb_deregister(&hso_driver);
+}
+
+/* Module definitions */
+module_init(hso_init);
+module_exit(hso_exit);
+
+MODULE_AUTHOR(MOD_AUTHOR);
+MODULE_DESCRIPTION(MOD_DESCRIPTION);
+MODULE_LICENSE(MOD_LICENSE);
+MODULE_INFO(Version, DRIVER_VERSION);
+
+/* change the debug level (eg: insmod hso.ko debug=0x04) */
+MODULE_PARM_DESC(debug, "Level of debug [0x01 | 0x02 | 0x04 | 0x08 | 0x10]");
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+/* set the major tty number (eg: insmod hso.ko tty_major=245) */
+MODULE_PARM_DESC(tty_major, "Set the major tty number");
+module_param(tty_major, int, S_IRUGO | S_IWUSR);
+
+/* disable network interface (eg: insmod hso.ko disable_net=1) */
+MODULE_PARM_DESC(disable_net, "Disable the network interface");
+module_param(disable_net, int, S_IRUGO | S_IWUSR);
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index ae467f182c4..61c98beb4d1 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(rndis_status);
* Call context is likely probe(), before interface name is known,
* which is why we won't try to use it in the diagnostics.
*/
-int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
+int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
{
struct cdc_state *info = (void *) &dev->data;
int master_ifnum;
@@ -121,7 +121,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf)
USB_CDC_GET_ENCAPSULATED_RESPONSE,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0, master_ifnum,
- buf, CONTROL_BUFFER_SIZE,
+ buf, buflen,
RNDIS_CONTROL_TIMEOUT_MS);
if (likely(retval >= 8)) {
msg_len = le32_to_cpu(buf->msg_len);
@@ -239,7 +239,7 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
u.get->len = cpu_to_le32(in_len);
u.get->offset = ccpu2(20);
- retval = rndis_command(dev, u.header);
+ retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n",
oid, retval);
@@ -328,7 +328,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
net->change_mtu = NULL;
- retval = rndis_command(dev, u.header);
+ retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
/* it might not even be an RNDIS device!! */
dev_err(&intf->dev, "RNDIS init failed, %d\n", retval);
@@ -409,7 +409,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
u.set->offset = ccpu2((sizeof *u.set) - 8);
*(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
- retval = rndis_command(dev, u.header);
+ retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
goto halt_fail_and_release;
@@ -424,7 +424,7 @@ halt_fail_and_release:
memset(u.halt, 0, sizeof *u.halt);
u.halt->msg_type = RNDIS_MSG_HALT;
u.halt->msg_len = ccpu2(sizeof *u.halt);
- (void) rndis_command(dev, (void *)u.halt);
+ (void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
fail_and_release:
usb_set_intfdata(info->data, NULL);
usb_driver_release_interface(driver_of(intf), info->data);
@@ -449,7 +449,7 @@ void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
if (halt) {
halt->msg_type = RNDIS_MSG_HALT;
halt->msg_len = ccpu2(sizeof *halt);
- (void) rndis_command(dev, (void *)halt);
+ (void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
kfree(halt);
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 8c9d6ae2bb3..96dff04334b 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -73,12 +73,7 @@ static const int multicast_filter_limit = 32;
There are no ill effects from too-large receive rings. */
#define TX_RING_SIZE 16
#define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */
-#ifdef CONFIG_VIA_RHINE_NAPI
#define RX_RING_SIZE 64
-#else
-#define RX_RING_SIZE 16
-#endif
-
/* Operational parameters that usually are not changed. */
@@ -583,7 +578,6 @@ static void rhine_poll(struct net_device *dev)
}
#endif
-#ifdef CONFIG_VIA_RHINE_NAPI
static int rhine_napipoll(struct napi_struct *napi, int budget)
{
struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
@@ -604,7 +598,6 @@ static int rhine_napipoll(struct napi_struct *napi, int budget)
}
return work_done;
}
-#endif
static void __devinit rhine_hw_init(struct net_device *dev, long pioaddr)
{
@@ -784,9 +777,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = rhine_poll;
#endif
-#ifdef CONFIG_VIA_RHINE_NAPI
netif_napi_add(dev, &rp->napi, rhine_napipoll, 64);
-#endif
+
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
@@ -1056,9 +1048,7 @@ static void init_registers(struct net_device *dev)
rhine_set_rx_mode(dev);
-#ifdef CONFIG_VIA_RHINE_NAPI
napi_enable(&rp->napi);
-#endif
/* Enable interrupts by setting the interrupt mask. */
iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
@@ -1193,9 +1183,7 @@ static void rhine_tx_timeout(struct net_device *dev)
/* protect against concurrent rx interrupts */
disable_irq(rp->pdev->irq);
-#ifdef CONFIG_VIA_RHINE_NAPI
napi_disable(&rp->napi);
-#endif
spin_lock(&rp->lock);
@@ -1319,16 +1307,12 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) {
-#ifdef CONFIG_VIA_RHINE_NAPI
iowrite16(IntrTxAborted |
IntrTxDone | IntrTxError | IntrTxUnderrun |
IntrPCIErr | IntrStatsMax | IntrLinkChange,
ioaddr + IntrEnable);
netif_rx_schedule(dev, &rp->napi);
-#else
- rhine_rx(dev, RX_RING_SIZE);
-#endif
}
if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
@@ -1520,11 +1504,7 @@ static int rhine_rx(struct net_device *dev, int limit)
PCI_DMA_FROMDEVICE);
}
skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_VIA_RHINE_NAPI
netif_receive_skb(skb);
-#else
- netif_rx(skb);
-#endif
dev->last_rx = jiffies;
rp->stats.rx_bytes += pkt_len;
rp->stats.rx_packets++;
@@ -1836,9 +1816,7 @@ static int rhine_close(struct net_device *dev)
spin_lock_irq(&rp->lock);
netif_stop_queue(dev);
-#ifdef CONFIG_VIA_RHINE_NAPI
napi_disable(&rp->napi);
-#endif
if (debug > 1)
printk(KERN_DEBUG "%s: Shutting down ethercard, "
@@ -1937,9 +1915,8 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
if (!netif_running(dev))
return 0;
-#ifdef CONFIG_VIA_RHINE_NAPI
napi_disable(&rp->napi);
-#endif
+
netif_device_detach(dev);
pci_save_state(pdev);
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 6b8d882d197..370ce30f2f4 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1102,61 +1102,41 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc
static int velocity_init_rings(struct velocity_info *vptr)
{
- int i;
- unsigned int psize;
- unsigned int tsize;
+ struct velocity_opt *opt = &vptr->options;
+ const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
+ const unsigned int tx_ring_size = opt->numtx * sizeof(struct tx_desc);
+ struct pci_dev *pdev = vptr->pdev;
dma_addr_t pool_dma;
- u8 *pool;
-
- /*
- * Allocate all RD/TD rings a single pool
- */
-
- psize = vptr->options.numrx * sizeof(struct rx_desc) +
- vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+ void *pool;
+ unsigned int i;
/*
+ * Allocate all RD/TD rings a single pool.
+ *
* pci_alloc_consistent() fulfills the requirement for 64 bytes
* alignment
*/
- pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
-
- if (pool == NULL) {
- printk(KERN_ERR "%s : DMA memory allocation failed.\n",
- vptr->dev->name);
+ pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->num_txq +
+ rx_ring_size, &pool_dma);
+ if (!pool) {
+ dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
+ vptr->dev->name);
return -ENOMEM;
}
- memset(pool, 0, psize);
-
- vptr->rd_ring = (struct rx_desc *) pool;
-
+ vptr->rd_ring = pool;
vptr->rd_pool_dma = pool_dma;
- tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
- vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
- &vptr->tx_bufs_dma);
+ pool += rx_ring_size;
+ pool_dma += rx_ring_size;
- if (vptr->tx_bufs == NULL) {
- printk(KERN_ERR "%s: DMA memory allocation failed.\n",
- vptr->dev->name);
- pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
- return -ENOMEM;
- }
-
- memset(vptr->tx_bufs, 0, vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq);
-
- i = vptr->options.numrx * sizeof(struct rx_desc);
- pool += i;
- pool_dma += i;
for (i = 0; i < vptr->num_txq; i++) {
- int offset = vptr->options.numtx * sizeof(struct tx_desc);
-
+ vptr->td_rings[i] = pool;
vptr->td_pool_dma[i] = pool_dma;
- vptr->td_rings[i] = (struct tx_desc *) pool;
- pool += offset;
- pool_dma += offset;
+ pool += tx_ring_size;
+ pool_dma += tx_ring_size;
}
+
return 0;
}
@@ -1169,19 +1149,13 @@ static int velocity_init_rings(struct velocity_info *vptr)
static void velocity_free_rings(struct velocity_info *vptr)
{
- int size;
-
- size = vptr->options.numrx * sizeof(struct rx_desc) +
- vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+ const int size = vptr->options.numrx * sizeof(struct rx_desc) +
+ vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
-
- size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
-
- pci_free_consistent(vptr->pdev, size, vptr->tx_bufs, vptr->tx_bufs_dma);
}
-static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
+static void velocity_give_many_rx_descs(struct velocity_info *vptr)
{
struct mac_regs __iomem *regs = vptr->mac_regs;
int avail, dirty, unusable;
@@ -1208,7 +1182,7 @@ static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
static int velocity_rx_refill(struct velocity_info *vptr)
{
- int dirty = vptr->rd_dirty, done = 0, ret = 0;
+ int dirty = vptr->rd_dirty, done = 0;
do {
struct rx_desc *rd = vptr->rd_ring + dirty;
@@ -1218,8 +1192,7 @@ static int velocity_rx_refill(struct velocity_info *vptr)
break;
if (!vptr->rd_info[dirty].skb) {
- ret = velocity_alloc_rx_buf(vptr, dirty);
- if (ret < 0)
+ if (velocity_alloc_rx_buf(vptr, dirty) < 0)
break;
}
done++;
@@ -1229,10 +1202,14 @@ static int velocity_rx_refill(struct velocity_info *vptr)
if (done) {
vptr->rd_dirty = dirty;
vptr->rd_filled += done;
- velocity_give_many_rx_descs(vptr);
}
- return ret;
+ return done;
+}
+
+static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
+{
+ vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
}
/**
@@ -1245,25 +1222,24 @@ static int velocity_rx_refill(struct velocity_info *vptr)
static int velocity_init_rd_ring(struct velocity_info *vptr)
{
- int ret;
- int mtu = vptr->dev->mtu;
-
- vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
+ int ret = -ENOMEM;
vptr->rd_info = kcalloc(vptr->options.numrx,
sizeof(struct velocity_rd_info), GFP_KERNEL);
if (!vptr->rd_info)
- return -ENOMEM;
+ goto out;
vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0;
- ret = velocity_rx_refill(vptr);
- if (ret < 0) {
+ if (velocity_rx_refill(vptr) != vptr->options.numrx) {
VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
"%s: failed to allocate RX buffer.\n", vptr->dev->name);
velocity_free_rd_ring(vptr);
+ goto out;
}
+ ret = 0;
+out:
return ret;
}
@@ -1313,10 +1289,8 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
static int velocity_init_td_ring(struct velocity_info *vptr)
{
- int i, j;
dma_addr_t curr;
- struct tx_desc *td;
- struct velocity_td_info *td_info;
+ unsigned int j;
/* Init the TD ring entries */
for (j = 0; j < vptr->num_txq; j++) {
@@ -1331,14 +1305,6 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
return -ENOMEM;
}
- for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
- td = &(vptr->td_rings[j][i]);
- td_info = &(vptr->td_infos[j][i]);
- td_info->buf = vptr->tx_bufs +
- (j * vptr->options.numtx + i) * PKT_BUF_SZ;
- td_info->buf_dma = vptr->tx_bufs_dma +
- (j * vptr->options.numtx + i) * PKT_BUF_SZ;
- }
vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0;
}
return 0;
@@ -1448,10 +1414,8 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
vptr->rd_curr = rd_curr;
- if (works > 0 && velocity_rx_refill(vptr) < 0) {
- VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
- "%s: rx buf allocation failure\n", vptr->dev->name);
- }
+ if ((works > 0) && (velocity_rx_refill(vptr) > 0))
+ velocity_give_many_rx_descs(vptr);
VAR_USED(stats);
return works;
@@ -1495,24 +1459,18 @@ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
* enough. This function returns a negative value if the received
* packet is too big or if memory is exhausted.
*/
-static inline int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
- struct velocity_info *vptr)
+static int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
+ struct velocity_info *vptr)
{
int ret = -1;
-
if (pkt_size < rx_copybreak) {
struct sk_buff *new_skb;
- new_skb = dev_alloc_skb(pkt_size + 2);
+ new_skb = netdev_alloc_skb(vptr->dev, pkt_size + 2);
if (new_skb) {
- new_skb->dev = vptr->dev;
new_skb->ip_summed = rx_skb[0]->ip_summed;
-
- if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
- skb_reserve(new_skb, 2);
-
- skb_copy_from_linear_data(rx_skb[0], new_skb->data,
- pkt_size);
+ skb_reserve(new_skb, 2);
+ skb_copy_from_linear_data(*rx_skb, new_skb->data, pkt_size);
*rx_skb = new_skb;
ret = 0;
}
@@ -1533,12 +1491,8 @@ static inline int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
static inline void velocity_iph_realign(struct velocity_info *vptr,
struct sk_buff *skb, int pkt_size)
{
- /* FIXME - memmove ? */
if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
- int i;
-
- for (i = pkt_size; i >= 0; i--)
- *(skb->data + i + 2) = *(skb->data + i);
+ memmove(skb->data + 2, skb->data, pkt_size);
skb_reserve(skb, 2);
}
}
@@ -1629,7 +1583,7 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
struct rx_desc *rd = &(vptr->rd_ring[idx]);
struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
- rd_info->skb = dev_alloc_skb(vptr->rx_buf_sz + 64);
+ rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx_buf_sz + 64);
if (rd_info->skb == NULL)
return -ENOMEM;
@@ -1638,7 +1592,6 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
* 64byte alignment.
*/
skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
- rd_info->skb->dev = vptr->dev;
rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
/*
@@ -1878,7 +1831,7 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_
/*
* Don't unmap the pre-allocated tx_bufs
*/
- if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
+ if (tdinfo->skb_dma) {
for (i = 0; i < tdinfo->nskb_dma; i++) {
#ifdef VELOCITY_ZERO_COPY_SUPPORT
@@ -1909,6 +1862,8 @@ static int velocity_open(struct net_device *dev)
struct velocity_info *vptr = netdev_priv(dev);
int ret;
+ velocity_set_rxbufsize(vptr, dev->mtu);
+
ret = velocity_init_rings(vptr);
if (ret < 0)
goto out;
@@ -1924,6 +1879,8 @@ static int velocity_open(struct net_device *dev)
/* Ensure chip is running */
pci_set_power_state(vptr->pdev, PCI_D0);
+ velocity_give_many_rx_descs(vptr);
+
velocity_init_registers(vptr, VELOCITY_INIT_COLD);
ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
@@ -1988,6 +1945,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
dev->mtu = new_mtu;
+ velocity_set_rxbufsize(vptr, new_mtu);
+
ret = velocity_init_rd_ring(vptr);
if (ret < 0)
goto out_unlock;
@@ -2074,9 +2033,19 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
struct tx_desc *td_ptr;
struct velocity_td_info *tdinfo;
unsigned long flags;
- int index;
int pktlen = skb->len;
- __le16 len = cpu_to_le16(pktlen);
+ __le16 len;
+ int index;
+
+
+
+ if (skb->len < ETH_ZLEN) {
+ if (skb_padto(skb, ETH_ZLEN))
+ goto out;
+ pktlen = ETH_ZLEN;
+ }
+
+ len = cpu_to_le16(pktlen);
#ifdef VELOCITY_ZERO_COPY_SUPPORT
if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
@@ -2094,23 +2063,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
td_ptr->tdesc1.TCR = TCR0_TIC;
td_ptr->td_buf[0].size &= ~TD_QUEUE;
- /*
- * Pad short frames.
- */
- if (pktlen < ETH_ZLEN) {
- /* Cannot occur until ZC support */
- pktlen = ETH_ZLEN;
- len = cpu_to_le16(ETH_ZLEN);
- skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
- memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
- tdinfo->skb = skb;
- tdinfo->skb_dma[0] = tdinfo->buf_dma;
- td_ptr->tdesc0.len = len;
- td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
- td_ptr->td_buf[0].pa_high = 0;
- td_ptr->td_buf[0].size = len; /* queue is 0 anyway */
- tdinfo->nskb_dma = 1;
- } else
#ifdef VELOCITY_ZERO_COPY_SUPPORT
if (skb_shinfo(skb)->nr_frags > 0) {
int nfrags = skb_shinfo(skb)->nr_frags;
@@ -2202,7 +2154,8 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->trans_start = jiffies;
spin_unlock_irqrestore(&vptr->lock, flags);
- return 0;
+out:
+ return NETDEV_TX_OK;
}
/**
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 7387be4f428..86446147284 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -236,10 +236,8 @@ struct velocity_rd_info {
struct velocity_td_info {
struct sk_buff *skb;
- u8 *buf;
int nskb_dma;
dma_addr_t skb_dma[7];
- dma_addr_t buf_dma;
};
enum velocity_owner {
@@ -1506,9 +1504,6 @@ struct velocity_info {
dma_addr_t rd_pool_dma;
dma_addr_t td_pool_dma[TX_QUEUE_NO];
- dma_addr_t tx_bufs_dma;
- u8 *tx_bufs;
-
struct vlan_group *vlgrp;
u8 ip_addr[4];
enum chip_type chip_id;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4452306d532..c28d7cb2035 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -550,7 +550,8 @@ static struct virtio_device_id id_table[] = {
};
static unsigned int features[] = {
- VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
+ VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
+ VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY,
};
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index d5140aed7b7..846be60e782 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -390,8 +390,7 @@ config WAN_ROUTER_DRIVERS
Select driver your card and remember to say Y to "Wan Router."
You will need the wan-tools package which is available from
- <ftp://ftp.sangoma.com/>. For more information read:
- <file:Documentation/networking/wan-router.txt>.
+ <ftp://ftp.sangoma.com/>.
Note that the answer to this question won't directly affect the
kernel except for how subordinate drivers may be built:
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index c2cc42f723d..c8e563106a4 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -133,9 +133,9 @@ static void sca_msci_intr(port_t *port)
sca_out(stat & (ST1_UDRN | ST1_CDCD), MSCI0_OFFSET + ST1, port);
if (stat & ST1_UDRN) {
- struct net_device_stats *stats = hdlc_stats(port_to_dev(port));
- stats->tx_errors++; /* TX Underrun error detected */
- stats->tx_fifo_errors++;
+ /* TX Underrun error detected */
+ port_to_dev(port)->stats.tx_errors++;
+ port_to_dev(port)->stats.tx_fifo_errors++;
}
stat = sca_in(MSCI1_OFFSET + ST1, port); /* read MSCI1 ST1 status */
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index c6f26e28e37..50ef5b4efd6 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -642,7 +642,6 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
struct net_device *dev)
{
struct RxFD *rx_fd = dpriv->rx_fd + dpriv->rx_current%RX_RING_SIZE;
- struct net_device_stats *stats = hdlc_stats(dev);
struct pci_dev *pdev = dpriv->pci_priv->pdev;
struct sk_buff *skb;
int pkt_len;
@@ -656,8 +655,8 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
pci_unmap_single(pdev, le32_to_cpu(rx_fd->data),
RX_MAX(HDLC_MAX_MRU), PCI_DMA_FROMDEVICE);
if ((skb->data[--pkt_len] & FrameOk) == FrameOk) {
- stats->rx_packets++;
- stats->rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
skb_put(skb, pkt_len);
if (netif_running(dev))
skb->protocol = hdlc_type_trans(skb, dev);
@@ -665,13 +664,13 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
netif_rx(skb);
} else {
if (skb->data[pkt_len] & FrameRdo)
- stats->rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
else if (!(skb->data[pkt_len] | ~FrameCrc))
- stats->rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
else if (!(skb->data[pkt_len] | ~(FrameVfr | FrameRab)))
- stats->rx_length_errors++;
+ dev->stats.rx_length_errors++;
else
- stats->rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb_irq(skb);
}
refill:
@@ -1569,7 +1568,6 @@ try:
if (state & SccEvt) {
if (state & Alls) {
- struct net_device_stats *stats = hdlc_stats(dev);
struct sk_buff *skb;
struct TxFD *tx_fd;
@@ -1586,8 +1584,8 @@ try:
pci_unmap_single(ppriv->pdev, le32_to_cpu(tx_fd->data),
skb->len, PCI_DMA_TODEVICE);
if (tx_fd->state & FrameEnd) {
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
}
dev_kfree_skb_irq(skb);
dpriv->tx_skbuff[cur] = NULL;
@@ -1698,7 +1696,7 @@ try:
}
if (state & Err) {
printk(KERN_INFO "%s: Tx ERR\n", dev->name);
- hdlc_stats(dev)->tx_errors++;
+ dev->stats.tx_errors++;
state &= ~Err;
}
}
@@ -1834,7 +1832,7 @@ try:
if (!(rx_fd->state2 & DataComplete))
break;
if (rx_fd->state2 & FrameAborted) {
- hdlc_stats(dev)->rx_over_errors++;
+ dev->stats.rx_over_errors++;
rx_fd->state1 |= Hold;
rx_fd->state2 = 0x00000000;
rx_fd->end = cpu_to_le32(0xbabeface);
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 547368e9633..754f00809e3 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -845,7 +845,6 @@ fst_tx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
int len, int txpos)
{
struct net_device *dev = port_to_dev(port);
- struct net_device_stats *stats = hdlc_stats(dev);
/*
* Everything is now set, just tell the card to go
@@ -853,8 +852,8 @@ fst_tx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
dbg(DBG_TX, "fst_tx_dma_complete\n");
FST_WRB(card, txDescrRing[port->index][txpos].bits,
DMA_OWN | TX_STP | TX_ENP);
- stats->tx_packets++;
- stats->tx_bytes += len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += len;
dev->trans_start = jiffies;
}
@@ -876,7 +875,6 @@ fst_rx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
int len, struct sk_buff *skb, int rxp)
{
struct net_device *dev = port_to_dev(port);
- struct net_device_stats *stats = hdlc_stats(dev);
int pi;
int rx_status;
@@ -888,8 +886,8 @@ fst_rx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN);
/* Update stats */
- stats->rx_packets++;
- stats->rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
/* Push upstream */
dbg(DBG_RX, "Pushing the frame up the stack\n");
@@ -900,7 +898,7 @@ fst_rx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
rx_status = netif_rx(skb);
fst_process_rx_status(rx_status, port_to_dev(port)->name);
if (rx_status == NET_RX_DROP)
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
dev->last_rx = jiffies;
}
@@ -1163,29 +1161,28 @@ fst_log_rx_error(struct fst_card_info *card, struct fst_port_info *port,
unsigned char dmabits, int rxp, unsigned short len)
{
struct net_device *dev = port_to_dev(port);
- struct net_device_stats *stats = hdlc_stats(dev);
- /*
+ /*
* Increment the appropriate error counter
*/
- stats->rx_errors++;
+ dev->stats.rx_errors++;
if (dmabits & RX_OFLO) {
- stats->rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
dbg(DBG_ASS, "Rx fifo error on card %d port %d buffer %d\n",
card->card_no, port->index, rxp);
}
if (dmabits & RX_CRC) {
- stats->rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
dbg(DBG_ASS, "Rx crc error on card %d port %d\n",
card->card_no, port->index);
}
if (dmabits & RX_FRAM) {
- stats->rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
dbg(DBG_ASS, "Rx frame error on card %d port %d\n",
card->card_no, port->index);
}
if (dmabits == (RX_STP | RX_ENP)) {
- stats->rx_length_errors++;
+ dev->stats.rx_length_errors++;
dbg(DBG_ASS, "Rx length error (%d) on card %d port %d\n",
len, card->card_no, port->index);
}
@@ -1242,7 +1239,6 @@ fst_intr_rx(struct fst_card_info *card, struct fst_port_info *port)
unsigned short len;
struct sk_buff *skb;
struct net_device *dev = port_to_dev(port);
- struct net_device_stats *stats = hdlc_stats(dev);
/* Check we have a buffer to process */
pi = port->index;
@@ -1291,7 +1287,7 @@ fst_intr_rx(struct fst_card_info *card, struct fst_port_info *port)
if ((skb = dev_alloc_skb(len)) == NULL) {
dbg(DBG_RX, "intr_rx: can't allocate buffer\n");
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
/* Return descriptor to card */
FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN);
@@ -1316,8 +1312,8 @@ fst_intr_rx(struct fst_card_info *card, struct fst_port_info *port)
FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN);
/* Update stats */
- stats->rx_packets++;
- stats->rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
/* Push upstream */
dbg(DBG_RX, "Pushing frame up the stack\n");
@@ -1327,9 +1323,8 @@ fst_intr_rx(struct fst_card_info *card, struct fst_port_info *port)
skb->protocol = hdlc_type_trans(skb, dev);
rx_status = netif_rx(skb);
fst_process_rx_status(rx_status, port_to_dev(port)->name);
- if (rx_status == NET_RX_DROP) {
- stats->rx_dropped++;
- }
+ if (rx_status == NET_RX_DROP)
+ dev->stats.rx_dropped++;
dev->last_rx = jiffies;
} else {
card->dma_skb_rx = skb;
@@ -1361,7 +1356,6 @@ do_bottom_half_tx(struct fst_card_info *card)
struct sk_buff *skb;
unsigned long flags;
struct net_device *dev;
- struct net_device_stats *stats;
/*
* Find a free buffer for the transmit
@@ -1373,12 +1367,10 @@ do_bottom_half_tx(struct fst_card_info *card)
if (!port->run)
continue;
- dev = port_to_dev(port);
- stats = hdlc_stats(dev);
- while (!
- (FST_RDB(card, txDescrRing[pi][port->txpos].bits) &
- DMA_OWN)
- && !(card->dmatx_in_progress)) {
+ dev = port_to_dev(port);
+ while (!(FST_RDB(card, txDescrRing[pi][port->txpos].bits) &
+ DMA_OWN)
+ && !(card->dmatx_in_progress)) {
/*
* There doesn't seem to be a txdone event per-se
* We seem to have to deduce it, by checking the DMA_OWN
@@ -1422,8 +1414,8 @@ do_bottom_half_tx(struct fst_card_info *card)
txDescrRing[pi][port->txpos].
bits,
DMA_OWN | TX_STP | TX_ENP);
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
} else {
/* Or do it through dma */
@@ -1628,8 +1620,8 @@ fst_intr(int dummy, void *dev_id)
* always load up the entire packet for DMA.
*/
dbg(DBG_TX, "Tx underflow port %d\n", port->index);
- hdlc_stats(port_to_dev(port))->tx_errors++;
- hdlc_stats(port_to_dev(port))->tx_fifo_errors++;
+ port_to_dev(port)->stats.tx_errors++;
+ port_to_dev(port)->stats.tx_fifo_errors++;
dbg(DBG_ASS, "Tx underflow on card %d port %d\n",
card->card_no, port->index);
break;
@@ -2292,12 +2284,11 @@ fst_tx_timeout(struct net_device *dev)
{
struct fst_port_info *port;
struct fst_card_info *card;
- struct net_device_stats *stats = hdlc_stats(dev);
port = dev_to_port(dev);
card = port->card;
- stats->tx_errors++;
- stats->tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
dbg(DBG_ASS, "Tx timeout card %d port %d\n",
card->card_no, port->index);
fst_issue_cmd(port, ABORTTX);
@@ -2312,7 +2303,6 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct fst_card_info *card;
struct fst_port_info *port;
- struct net_device_stats *stats = hdlc_stats(dev);
unsigned long flags;
int txq_length;
@@ -2323,8 +2313,8 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Drop packet with error if we don't have carrier */
if (!netif_carrier_ok(dev)) {
dev_kfree_skb(skb);
- stats->tx_errors++;
- stats->tx_carrier_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
dbg(DBG_ASS,
"Tried to transmit but no carrier on card %d port %d\n",
card->card_no, port->index);
@@ -2336,7 +2326,7 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
dbg(DBG_ASS, "Packet too large %d vs %d\n", skb->len,
LEN_TX_BUFFER);
dev_kfree_skb(skb);
- stats->tx_errors++;
+ dev->stats.tx_errors++;
return 0;
}
@@ -2368,7 +2358,7 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
* This shouldn't have happened but such is life
*/
dev_kfree_skb(skb);
- stats->tx_errors++;
+ dev->stats.tx_errors++;
dbg(DBG_ASS, "Tx queue overflow card %d port %d\n",
card->card_no, port->index);
return 0;
diff --git a/drivers/net/wan/hd6457x.c b/drivers/net/wan/hd6457x.c
index 8d0a1f2f00e..591fb45a7c6 100644
--- a/drivers/net/wan/hd6457x.c
+++ b/drivers/net/wan/hd6457x.c
@@ -271,9 +271,9 @@ static inline void sca_msci_intr(port_t *port)
sca_out(stat & (ST1_UDRN | ST1_CDCD), msci + ST1, card);
if (stat & ST1_UDRN) {
- struct net_device_stats *stats = hdlc_stats(port_to_dev(port));
- stats->tx_errors++; /* TX Underrun error detected */
- stats->tx_fifo_errors++;
+ /* TX Underrun error detected */
+ port_to_dev(port)->stats.tx_errors++;
+ port_to_dev(port)->stats.tx_fifo_errors++;
}
if (stat & ST1_CDCD)
@@ -286,7 +286,6 @@ static inline void sca_msci_intr(port_t *port)
static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u16 rxin)
{
struct net_device *dev = port_to_dev(port);
- struct net_device_stats *stats = hdlc_stats(dev);
struct sk_buff *skb;
u16 len;
u32 buff;
@@ -298,7 +297,7 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
len = readw(&desc->len);
skb = dev_alloc_skb(len);
if (!skb) {
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
@@ -327,8 +326,8 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
printk(KERN_DEBUG "%s RX(%i):", dev->name, skb->len);
debug_frame(skb);
#endif
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
dev->last_rx = jiffies;
skb->protocol = hdlc_type_trans(skb, dev);
netif_rx(skb);
@@ -339,17 +338,18 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
/* Receive DMA interrupt service */
static inline void sca_rx_intr(port_t *port)
{
+ struct net_device *dev = port_to_dev(port);
u16 dmac = get_dmac_rx(port);
card_t *card = port_to_card(port);
u8 stat = sca_in(DSR_RX(phy_node(port)), card); /* read DMA Status */
- struct net_device_stats *stats = hdlc_stats(port_to_dev(port));
/* Reset DSR status bits */
sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE,
DSR_RX(phy_node(port)), card);
if (stat & DSR_BOF)
- stats->rx_over_errors++; /* Dropped one or more frames */
+ /* Dropped one or more frames */
+ dev->stats.rx_over_errors++;
while (1) {
u32 desc_off = desc_offset(port, port->rxin, 0);
@@ -364,12 +364,14 @@ static inline void sca_rx_intr(port_t *port)
if (!(stat & ST_RX_EOM))
port->rxpart = 1; /* partial frame received */
else if ((stat & ST_ERROR_MASK) || port->rxpart) {
- stats->rx_errors++;
- if (stat & ST_RX_OVERRUN) stats->rx_fifo_errors++;
+ dev->stats.rx_errors++;
+ if (stat & ST_RX_OVERRUN)
+ dev->stats.rx_fifo_errors++;
else if ((stat & (ST_RX_SHORT | ST_RX_ABORT |
ST_RX_RESBIT)) || port->rxpart)
- stats->rx_frame_errors++;
- else if (stat & ST_RX_CRC) stats->rx_crc_errors++;
+ dev->stats.rx_frame_errors++;
+ else if (stat & ST_RX_CRC)
+ dev->stats.rx_crc_errors++;
if (stat & ST_RX_EOM)
port->rxpart = 0; /* received last fragment */
} else
@@ -390,7 +392,6 @@ static inline void sca_rx_intr(port_t *port)
static inline void sca_tx_intr(port_t *port)
{
struct net_device *dev = port_to_dev(port);
- struct net_device_stats *stats = hdlc_stats(dev);
u16 dmac = get_dmac_tx(port);
card_t* card = port_to_card(port);
u8 stat;
@@ -412,8 +413,8 @@ static inline void sca_tx_intr(port_t *port)
break; /* Transmitter is/will_be sending this frame */
desc = desc_address(port, port->txlast, 1);
- stats->tx_packets++;
- stats->tx_bytes += readw(&desc->len);
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += readw(&desc->len);
writeb(0, &desc->stat); /* Free descriptor */
port->txlast = next_desc(port, port->txlast, 1);
}
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 7f984895b0d..e3a536477c7 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -57,7 +57,7 @@ static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
{
- return hdlc_stats(dev);
+ return &dev->stats;
}
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 762d21c1c70..849819c2552 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -252,8 +252,8 @@ static int cisco_rx(struct sk_buff *skb)
dev_kfree_skb_any(skb);
return NET_RX_DROP;
- rx_error:
- dev_to_hdlc(dev)->stats.rx_errors++; /* Mark error */
+rx_error:
+ dev->stats.rx_errors++; /* Mark error */
dev_kfree_skb_any(skb);
return NET_RX_DROP;
}
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 6d35155c714..62e93dac6b1 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -135,11 +135,6 @@ typedef struct pvc_device_struct {
}state;
}pvc_device;
-struct pvc_desc {
- struct net_device_stats stats;
- pvc_device *pvc;
-};
-
struct frad_state {
fr_proto settings;
pvc_device *first_pvc;
@@ -179,15 +174,6 @@ static inline struct frad_state* state(hdlc_device *hdlc)
return(struct frad_state *)(hdlc->state);
}
-static inline struct pvc_desc* pvcdev_to_desc(struct net_device *dev)
-{
- return dev->priv;
-}
-
-static inline struct net_device_stats* pvc_get_stats(struct net_device *dev)
-{
- return &pvcdev_to_desc(dev)->stats;
-}
static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
{
@@ -357,7 +343,7 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
static int pvc_open(struct net_device *dev)
{
- pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
+ pvc_device *pvc = dev->priv;
if ((pvc->frad->flags & IFF_UP) == 0)
return -EIO; /* Frad must be UP in order to activate PVC */
@@ -377,7 +363,7 @@ static int pvc_open(struct net_device *dev)
static int pvc_close(struct net_device *dev)
{
- pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
+ pvc_device *pvc = dev->priv;
if (--pvc->open_count == 0) {
hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
@@ -396,7 +382,7 @@ static int pvc_close(struct net_device *dev)
static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
+ pvc_device *pvc = dev->priv;
fr_proto_pvc_info info;
if (ifr->ifr_settings.type == IF_GET_PROTO) {
@@ -424,8 +410,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
{
- pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
- struct net_device_stats *stats = pvc_get_stats(dev);
+ pvc_device *pvc = dev->priv;
if (pvc->state.active) {
if (dev->type == ARPHRD_ETHER) {
@@ -435,7 +420,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb_tailroom(skb) < pad)
if (pskb_expand_head(skb, 0, pad,
GFP_ATOMIC)) {
- stats->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return 0;
}
@@ -445,17 +430,17 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
skb->protocol = __constant_htons(ETH_P_802_3);
}
if (!fr_hard_header(&skb, pvc->dlci)) {
- stats->tx_bytes += skb->len;
- stats->tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
if (pvc->state.fecn) /* TX Congestion counter */
- stats->tx_compressed++;
+ dev->stats.tx_compressed++;
skb->dev = pvc->frad;
dev_queue_xmit(skb);
return 0;
}
}
- stats->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return 0;
}
@@ -955,7 +940,7 @@ static int fr_rx(struct sk_buff *skb)
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
- dev_to_hdlc(frad)->stats.rx_dropped++;
+ frad->stats.rx_dropped++;
return NET_RX_DROP;
}
@@ -1003,11 +988,10 @@ static int fr_rx(struct sk_buff *skb)
}
if (dev) {
- struct net_device_stats *stats = pvc_get_stats(dev);
- stats->rx_packets++; /* PVC traffic */
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++; /* PVC traffic */
+ dev->stats.rx_bytes += skb->len;
if (pvc->state.becn)
- stats->rx_compressed++;
+ dev->stats.rx_compressed++;
skb->dev = dev;
netif_rx(skb);
return NET_RX_SUCCESS;
@@ -1017,7 +1001,7 @@ static int fr_rx(struct sk_buff *skb)
}
rx_error:
- dev_to_hdlc(frad)->stats.rx_errors++; /* Mark error */
+ frad->stats.rx_errors++; /* Mark error */
dev_kfree_skb_any(skb);
return NET_RX_DROP;
}
@@ -1088,7 +1072,7 @@ static void pvc_setup(struct net_device *dev)
static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
{
hdlc_device *hdlc = dev_to_hdlc(frad);
- pvc_device *pvc = NULL;
+ pvc_device *pvc;
struct net_device *dev;
int result, used;
@@ -1104,10 +1088,9 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
used = pvc_is_used(pvc);
if (type == ARPHRD_ETHER)
- dev = alloc_netdev(sizeof(struct pvc_desc), "pvceth%d",
- ether_setup);
+ dev = alloc_netdev(0, "pvceth%d", ether_setup);
else
- dev = alloc_netdev(sizeof(struct pvc_desc), "pvc%d", pvc_setup);
+ dev = alloc_netdev(0, "pvc%d", pvc_setup);
if (!dev) {
printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
@@ -1123,14 +1106,13 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
dlci_to_q922(dev->broadcast, dlci);
}
dev->hard_start_xmit = pvc_xmit;
- dev->get_stats = pvc_get_stats;
dev->open = pvc_open;
dev->stop = pvc_close;
dev->do_ioctl = pvc_ioctl;
dev->change_mtu = pvc_change_mtu;
dev->mtu = HDLC_MAX_MTU;
dev->tx_queue_len = 0;
- pvcdev_to_desc(dev)->pvc = pvc;
+ dev->priv = pvc;
result = dev_alloc_name(dev, dev->name);
if (result < 0) {
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index d20c685f671..26dee600506 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -33,7 +33,7 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev)
int len = skb->len;
if (skb_tailroom(skb) < pad)
if (pskb_expand_head(skb, 0, pad, GFP_ATOMIC)) {
- hdlc_stats(dev)->tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return 0;
}
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index c15cc11e399..e808720030e 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -164,17 +164,15 @@ static void x25_close(struct net_device *dev)
static int x25_rx(struct sk_buff *skb)
{
- struct hdlc_device *hdlc = dev_to_hdlc(skb->dev);
-
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
- hdlc->stats.rx_dropped++;
+ skb->dev->stats.rx_dropped++;
return NET_RX_DROP;
}
if (lapb_data_received(skb->dev, skb) == LAPB_OK)
return NET_RX_SUCCESS;
- hdlc->stats.rx_errors++;
+ skb->dev->stats.rx_errors++;
dev_kfree_skb_any(skb);
return NET_RX_DROP;
}
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 57914fbd41d..33417052775 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -285,7 +285,6 @@ static void rx_dma_buf_init(pc300_t *, int);
static void tx_dma_buf_check(pc300_t *, int);
static void rx_dma_buf_check(pc300_t *, int);
static irqreturn_t cpc_intr(int, void *);
-static struct net_device_stats *cpc_get_stats(struct net_device *);
static int clock_rate_calc(uclong, uclong, int *);
static uclong detect_ram(pc300_t *);
static void plx_init(pc300_t *);
@@ -1775,13 +1774,12 @@ static void cpc_tx_timeout(struct net_device *dev)
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
- struct net_device_stats *stats = hdlc_stats(dev);
int ch = chan->channel;
unsigned long flags;
ucchar ilar;
- stats->tx_errors++;
- stats->tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
CPC_LOCK(card, flags);
if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) {
printk("%s: ILAR=0x%x\n", dev->name, ilar);
@@ -1803,7 +1801,6 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
- struct net_device_stats *stats = hdlc_stats(dev);
int ch = chan->channel;
unsigned long flags;
#ifdef PC300_DEBUG_TX
@@ -1817,13 +1814,13 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
} else if (!netif_carrier_ok(dev)) {
/* DCD must be OFF: drop packet */
dev_kfree_skb(skb);
- stats->tx_errors++;
- stats->tx_carrier_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
return 0;
} else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) {
printk("%s: DCD is OFF. Going administrative down.\n", dev->name);
- stats->tx_errors++;
- stats->tx_carrier_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
dev_kfree_skb(skb);
netif_carrier_off(dev);
CPC_LOCK(card, flags);
@@ -1843,8 +1840,8 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
// printk("%s: write error. Dropping TX packet.\n", dev->name);
netif_stop_queue(dev);
dev_kfree_skb(skb);
- stats->tx_errors++;
- stats->tx_dropped++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
return 0;
}
#ifdef PC300_DEBUG_TX
@@ -1886,7 +1883,6 @@ static void cpc_net_rx(struct net_device *dev)
pc300dev_t *d = (pc300dev_t *) dev->priv;
pc300ch_t *chan = (pc300ch_t *) d->chan;
pc300_t *card = (pc300_t *) chan->card;
- struct net_device_stats *stats = hdlc_stats(dev);
int ch = chan->channel;
#ifdef PC300_DEBUG_RX
int i;
@@ -1922,24 +1918,24 @@ static void cpc_net_rx(struct net_device *dev)
#endif
if ((skb == NULL) && (rxb > 0)) {
/* rxb > dev->mtu */
- stats->rx_errors++;
- stats->rx_length_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
continue;
}
if (rxb < 0) { /* Invalid frame */
rxb = -rxb;
if (rxb & DST_OVR) {
- stats->rx_errors++;
- stats->rx_fifo_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_fifo_errors++;
}
if (rxb & DST_CRC) {
- stats->rx_errors++;
- stats->rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
}
if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) {
- stats->rx_errors++;
- stats->rx_frame_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
}
}
if (skb) {
@@ -1948,7 +1944,7 @@ static void cpc_net_rx(struct net_device *dev)
continue;
}
- stats->rx_bytes += rxb;
+ dev->stats.rx_bytes += rxb;
#ifdef PC300_DEBUG_RX
printk("%s R:", dev->name);
@@ -1959,7 +1955,7 @@ static void cpc_net_rx(struct net_device *dev)
if (d->trace_on) {
cpc_trace(dev, skb, 'R');
}
- stats->rx_packets++;
+ dev->stats.rx_packets++;
skb->protocol = hdlc_type_trans(skb, dev);
netif_rx(skb);
}
@@ -1974,16 +1970,15 @@ static void sca_tx_intr(pc300dev_t *dev)
pc300_t *card = (pc300_t *)chan->card;
int ch = chan->channel;
volatile pcsca_bd_t __iomem * ptdescr;
- struct net_device_stats *stats = hdlc_stats(dev->dev);
/* Clean up descriptors from previous transmission */
ptdescr = (card->hw.rambase +
TX_BD_ADDR(ch,chan->tx_first_bd));
- while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) !=
- TX_BD_ADDR(ch,chan->tx_first_bd)) &&
- (cpc_readb(&ptdescr->status) & DST_OSB)) {
- stats->tx_packets++;
- stats->tx_bytes += cpc_readw(&ptdescr->len);
+ while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) !=
+ TX_BD_ADDR(ch,chan->tx_first_bd)) &&
+ (cpc_readb(&ptdescr->status) & DST_OSB)) {
+ dev->dev->stats.tx_packets++;
+ dev->dev->stats.tx_bytes += cpc_readw(&ptdescr->len);
cpc_writeb(&ptdescr->status, DST_OSB);
cpc_writew(&ptdescr->len, 0);
chan->nfree_tx_bd++;
@@ -2048,8 +2043,8 @@ static void sca_intr(pc300_t * card)
}
cpc_net_rx(dev);
/* Discard invalid frames */
- hdlc_stats(dev)->rx_errors++;
- hdlc_stats(dev)->rx_over_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_over_errors++;
chan->rx_first_bd = 0;
chan->rx_last_bd = N_DMA_RX_BUF - 1;
rx_dma_start(card, ch);
@@ -2115,8 +2110,8 @@ static void sca_intr(pc300_t * card)
card->hw.cpld_reg2) &
~ (CPLD_REG2_FALC_LED1 << (2 * ch)));
}
- hdlc_stats(dev)->tx_errors++;
- hdlc_stats(dev)->tx_fifo_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_fifo_errors++;
sca_tx_intr(d);
}
}
@@ -2604,7 +2599,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case SIOCGPC300UTILSTATS:
{
if (!arg) { /* clear statistics */
- memset(hdlc_stats(dev), 0, sizeof(struct net_device_stats));
+ memset(&dev->stats, 0, sizeof(dev->stats));
if (card->hw.type == PC300_TE) {
memset(&chan->falc, 0, sizeof(falc_t));
}
@@ -2615,8 +2610,8 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
pc300stats.hw_type = card->hw.type;
pc300stats.line_on = card->chan[ch].d.line_on;
pc300stats.line_off = card->chan[ch].d.line_off;
- memcpy(&pc300stats.gen_stats, hdlc_stats(dev),
- sizeof(struct net_device_stats));
+ memcpy(&pc300stats.gen_stats, &dev->stats,
+ sizeof(dev->stats));
if (card->hw.type == PC300_TE)
memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t));
if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t)))
@@ -2823,11 +2818,6 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
}
-static struct net_device_stats *cpc_get_stats(struct net_device *dev)
-{
- return hdlc_stats(dev);
-}
-
static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
{
int br, tc;
@@ -3394,7 +3384,6 @@ static void cpc_init_card(pc300_t * card)
dev->stop = cpc_close;
dev->tx_timeout = cpc_tx_timeout;
dev->watchdog_timeo = PC300_TX_TIMEOUT;
- dev->get_stats = cpc_get_stats;
dev->set_multicast_list = NULL;
dev->set_mac_address = NULL;
dev->change_mtu = cpc_change_mtu;
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index e03eef2f228..4518d0aa248 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -458,7 +458,7 @@ static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count);
pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan;
- stats = hdlc_stats(((pc300dev_t*)cpc_tty->pc300dev)->dev);
+ stats = &cpc_tty->pc300dev->dev->stats;
card = (pc300_t *) pc300chan->card;
ch = pc300chan->channel;
@@ -688,9 +688,9 @@ static void cpc_tty_rx_work(struct work_struct *work)
if (cpc_tty->tty) {
ld = tty_ldisc_ref(cpc_tty->tty);
if (ld) {
- if (ld->receive_buf) {
+ if (ld->ops->receive_buf) {
CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
- ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
+ ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
}
tty_ldisc_deref(ld);
}
@@ -743,7 +743,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
pc300_t *card = (pc300_t *)pc300chan->card;
int ch = pc300chan->channel;
volatile pcsca_bd_t __iomem * ptdescr;
- struct net_device_stats *stats = hdlc_stats(pc300dev->dev);
+ struct net_device_stats *stats = &pc300dev->dev->stats;
int rx_len, rx_aux;
volatile unsigned char status;
unsigned short first_bd = pc300chan->rx_first_bd;
@@ -917,7 +917,7 @@ static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
pc300ch_t *chan = (pc300ch_t *)dev->chan;
pc300_t *card = (pc300_t *)chan->card;
int ch = chan->channel;
- struct net_device_stats *stats = hdlc_stats(dev->dev);
+ struct net_device_stats *stats = &dev->dev->stats;
unsigned long flags;
volatile pcsca_bd_t __iomem *ptdescr;
int i, nchar;
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index d4aab8a28b6..a8a5ca0ee6c 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -161,7 +161,6 @@ static inline void wanxl_cable_intr(port_t *port)
static inline void wanxl_tx_intr(port_t *port)
{
struct net_device *dev = port->dev;
- struct net_device_stats *stats = hdlc_stats(dev);
while (1) {
desc_t *desc = &get_status(port)->tx_descs[port->tx_in];
struct sk_buff *skb = port->tx_skbs[port->tx_in];
@@ -173,13 +172,13 @@ static inline void wanxl_tx_intr(port_t *port)
return;
case PACKET_UNDERRUN:
- stats->tx_errors++;
- stats->tx_fifo_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_fifo_errors++;
break;
default:
- stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
}
desc->stat = PACKET_EMPTY; /* Free descriptor */
pci_unmap_single(port->card->pdev, desc->address, skb->len,
@@ -205,10 +204,9 @@ static inline void wanxl_rx_intr(card_t *card)
port_t *port = &card->ports[desc->stat &
PACKET_PORT_MASK];
struct net_device *dev = port->dev;
- struct net_device_stats *stats = hdlc_stats(dev);
if (!skb)
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
else {
pci_unmap_single(card->pdev, desc->address,
BUFFER_LENGTH,
@@ -220,8 +218,8 @@ static inline void wanxl_rx_intr(card_t *card)
skb->len);
debug_frame(skb);
#endif
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
dev->last_rx = jiffies;
skb->protocol = hdlc_type_trans(skb, dev);
netif_rx(skb);
@@ -468,13 +466,13 @@ static int wanxl_close(struct net_device *dev)
static struct net_device_stats *wanxl_get_stats(struct net_device *dev)
{
- struct net_device_stats *stats = hdlc_stats(dev);
port_t *port = dev_to_port(dev);
- stats->rx_over_errors = get_status(port)->rx_overruns;
- stats->rx_frame_errors = get_status(port)->rx_frame_errors;
- stats->rx_errors = stats->rx_over_errors + stats->rx_frame_errors;
- return stats;
+ dev->stats.rx_over_errors = get_status(port)->rx_overruns;
+ dev->stats.rx_frame_errors = get_status(port)->rx_frame_errors;
+ dev->stats.rx_errors = dev->stats.rx_over_errors +
+ dev->stats.rx_frame_errors;
+ return &dev->stats;
}
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 069f8bb0a99..2a6c7a60756 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -754,7 +754,7 @@ static void x25_asy_setup(struct net_device *dev)
dev->flags = IFF_NOARP;
}
-static struct tty_ldisc x25_ldisc = {
+static struct tty_ldisc_ops x25_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "X.25",
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index fdf5aa8b842..91fc2c765d9 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -635,14 +635,20 @@ config RTL8180
Thanks to Realtek for their support!
config RTL8187
- tristate "Realtek 8187 USB support"
+ tristate "Realtek 8187 and 8187B USB support"
depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
select EEPROM_93CX6
---help---
- This is a driver for RTL8187 based cards.
- These are USB based chips found in cards such as:
+ This is a driver for RTL8187 and RTL8187B based cards.
+ These are USB based chips found in devices such as:
Netgear WG111v2
+ Level 1 WNC-0301USB
+ Micronet SP907GK V5
+ Encore ENUWI-G2
+ Trendnet TEW-424UB
+ ASUS P5B Deluxe
+ Toshiba Satellite Pro series of laptops
Thanks to Realtek for their support!
@@ -673,6 +679,19 @@ config ADM8211
Thanks to Infineon-ADMtek for their support of this driver.
+config MAC80211_HWSIM
+ tristate "Simulated radio testing tool for mac80211"
+ depends on MAC80211 && WLAN_80211
+ ---help---
+ This driver is a developer testing tool that can be used to test
+ IEEE 802.11 networking stack (mac80211) functionality. This is not
+ needed for normal wireless LAN usage and is only for testing. See
+ Documentation/networking/mac80211_hwsim for more information on how
+ to use this tool.
+
+ To compile this driver as a module, choose M here: the module will be
+ called mac80211_hwsim. If unsure, say N.
+
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 2c343aae38d..54a4f6f1db6 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -62,3 +62,5 @@ obj-$(CONFIG_RT2X00) += rt2x00/
obj-$(CONFIG_P54_COMMON) += p54/
obj-$(CONFIG_ATH5K) += ath5k/
+
+obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 5c0d2b08275..3333d4596b8 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -306,11 +306,10 @@ static int adm8211_get_tx_stats(struct ieee80211_hw *dev,
struct ieee80211_tx_queue_stats *stats)
{
struct adm8211_priv *priv = dev->priv;
- struct ieee80211_tx_queue_stats_data *data = &stats->data[0];
- data->len = priv->cur_tx - priv->dirty_tx;
- data->limit = priv->tx_ring_size - 2;
- data->count = priv->dirty_tx;
+ stats[0].len = priv->cur_tx - priv->dirty_tx;
+ stats[0].limit = priv->tx_ring_size - 2;
+ stats[0].count = priv->dirty_tx;
return 0;
}
@@ -325,7 +324,7 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) {
unsigned int entry = dirty_tx % priv->tx_ring_size;
u32 status = le32_to_cpu(priv->tx_ring[entry].status);
- struct ieee80211_tx_status tx_status;
+ struct ieee80211_tx_info *txi;
struct adm8211_tx_ring_info *info;
struct sk_buff *skb;
@@ -335,24 +334,23 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
info = &priv->tx_buffers[entry];
skb = info->skb;
+ txi = IEEE80211_SKB_CB(skb);
/* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */
pci_unmap_single(priv->pdev, info->mapping,
info->skb->len, PCI_DMA_TODEVICE);
- memset(&tx_status, 0, sizeof(tx_status));
+ memset(&txi->status, 0, sizeof(txi->status));
skb_pull(skb, sizeof(struct adm8211_tx_hdr));
memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen);
- memcpy(&tx_status.control, &info->tx_control,
- sizeof(tx_status.control));
- if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+ if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (status & TDES0_STATUS_ES)
- tx_status.excessive_retries = 1;
+ txi->status.excessive_retries = 1;
else
- tx_status.flags |= IEEE80211_TX_STATUS_ACK;
+ txi->flags |= IEEE80211_TX_STAT_ACK;
}
- ieee80211_tx_status_irqsafe(dev, skb, &tx_status);
+ ieee80211_tx_status_irqsafe(dev, skb);
info->skb = NULL;
}
@@ -446,9 +444,9 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
struct ieee80211_rx_status rx_status = {0};
if (priv->pdev->revision < ADM8211_REV_CA)
- rx_status.ssi = rssi;
+ rx_status.signal = rssi;
else
- rx_status.ssi = 100 - rssi;
+ rx_status.signal = 100 - rssi;
rx_status.rate_idx = rate;
@@ -1639,7 +1637,6 @@ static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int
/* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */
static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
u16 plcp_signal,
- struct ieee80211_tx_control *control,
size_t hdrlen)
{
struct adm8211_priv *priv = dev->priv;
@@ -1665,7 +1662,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
priv->tx_buffers[entry].skb = skb;
priv->tx_buffers[entry].mapping = mapping;
- memcpy(&priv->tx_buffers[entry].tx_control, control, sizeof(*control));
priv->tx_buffers[entry].hdrlen = hdrlen;
priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
@@ -1686,22 +1682,20 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
}
/* Put adm8211_tx_hdr on skb and transmit */
-static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct adm8211_tx_hdr *txhdr;
- u16 fc;
size_t payload_len, hdrlen;
int plcp, dur, len, plcp_signal, short_preamble;
struct ieee80211_hdr *hdr;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info);
- short_preamble = !!(control->tx_rate->flags &
- IEEE80211_TXCTL_SHORT_PREAMBLE);
- plcp_signal = control->tx_rate->bitrate;
+ short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE);
+ plcp_signal = txrate->bitrate;
hdr = (struct ieee80211_hdr *)skb->data;
- fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED;
- hdrlen = ieee80211_get_hdrlen(fc);
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
memcpy(skb->cb, skb->data, hdrlen);
hdr = (struct ieee80211_hdr *)skb->cb;
skb_pull(skb, hdrlen);
@@ -1715,8 +1709,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
txhdr->frame_control = hdr->frame_control;
len = hdrlen + payload_len + FCS_LEN;
- if (fc & IEEE80211_FCTL_PROTECTED)
- len += 8;
txhdr->frag = cpu_to_le16(0x0FFF);
adm8211_calc_durations(&dur, &plcp, payload_len,
@@ -1731,15 +1723,12 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
if (short_preamble)
txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE);
- if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
- if (fc & IEEE80211_FCTL_PROTECTED)
- txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE);
+ txhdr->retry_limit = info->control.retry_limit;
- txhdr->retry_limit = control->retry_limit;
-
- adm8211_tx_raw(dev, skb, plcp_signal, control, hdrlen);
+ adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
return NETDEV_TX_OK;
}
@@ -1894,9 +1883,10 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
/* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
+ dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
dev->channel_change_time = 1000;
- dev->max_rssi = 100; /* FIXME: find better value */
+ dev->max_signal = 100; /* FIXME: find better value */
dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
@@ -2015,7 +2005,7 @@ static int adm8211_resume(struct pci_dev *pdev)
if (priv->mode != IEEE80211_IF_TYPE_INVALID) {
adm8211_start(dev);
- ieee80211_start_queues(dev);
+ ieee80211_wake_queues(dev);
}
return 0;
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h
index 8d7c564b3b0..9b190ee26e9 100644
--- a/drivers/net/wireless/adm8211.h
+++ b/drivers/net/wireless/adm8211.h
@@ -443,7 +443,6 @@ struct adm8211_rx_ring_info {
struct adm8211_tx_ring_info {
struct sk_buff *skb;
dma_addr_t mapping;
- struct ieee80211_tx_control tx_control;
size_t hdrlen;
};
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 32019fb878d..b5cd850a4a5 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -85,10 +85,10 @@ static struct pci_driver airo_driver = {
/* Include Wireless Extension definition and check version - Jean II */
#include <linux/wireless.h>
-#define WIRELESS_SPY // enable iwspy support
-#include <net/iw_handler.h> // New driver API
+#define WIRELESS_SPY /* enable iwspy support */
+#include <net/iw_handler.h> /* New driver API */
-#define CISCO_EXT // enable Cisco extensions
+#define CISCO_EXT /* enable Cisco extensions */
#ifdef CISCO_EXT
#include <linux/delay.h>
#endif
@@ -281,7 +281,7 @@ MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
/* This is a kind of sloppy hack to get this information to OUT4500 and
IN4500. I would be extremely interested in the situation where this
doesn't work though!!! */
-static int do8bitIO = 0;
+static int do8bitIO /* = 0 */;
/* Return codes */
#define SUCCESS 0
@@ -398,8 +398,8 @@ static int do8bitIO = 0;
#define MAXTXQ 64
/* BAP selectors */
-#define BAP0 0 // Used for receiving packets
-#define BAP1 2 // Used for xmiting packets and working with RIDS
+#define BAP0 0 /* Used for receiving packets */
+#define BAP1 2 /* Used for xmiting packets and working with RIDS */
/* Flags */
#define COMMAND_BUSY 0x8000
@@ -1148,7 +1148,6 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
static void airo_networks_free(struct airo_info *ai);
struct airo_info {
- struct net_device_stats stats;
struct net_device *dev;
struct list_head dev_list;
/* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we
@@ -1924,7 +1923,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
if (npacks >= MAXTXQ - 1) {
netif_stop_queue (dev);
if (npacks > MAXTXQ) {
- ai->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
return 1;
}
skb_queue_tail (&ai->txq, skb);
@@ -2044,13 +2043,13 @@ static void get_tx_error(struct airo_info *ai, s32 fid)
bap_read(ai, &status, 2, BAP0);
}
if (le16_to_cpu(status) & 2) /* Too many retries */
- ai->stats.tx_aborted_errors++;
+ ai->dev->stats.tx_aborted_errors++;
if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
- ai->stats.tx_heartbeat_errors++;
+ ai->dev->stats.tx_heartbeat_errors++;
if (le16_to_cpu(status) & 8) /* Aid fail */
{ }
if (le16_to_cpu(status) & 0x10) /* MAC disabled */
- ai->stats.tx_carrier_errors++;
+ ai->dev->stats.tx_carrier_errors++;
if (le16_to_cpu(status) & 0x20) /* Association lost */
{ }
/* We produce a TXDROP event only for retry or lifetime
@@ -2102,7 +2101,7 @@ static void airo_end_xmit(struct net_device *dev) {
for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
} else {
priv->fids[fid] &= 0xffff;
- priv->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
}
if (i < MAX_FIDS / 2)
netif_wake_queue(dev);
@@ -2128,7 +2127,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
netif_stop_queue(dev);
if (i == MAX_FIDS / 2) {
- priv->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
return 1;
}
}
@@ -2167,7 +2166,7 @@ static void airo_end_xmit11(struct net_device *dev) {
for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
} else {
priv->fids[fid] &= 0xffff;
- priv->stats.tx_window_errors++;
+ dev->stats.tx_window_errors++;
}
if (i < MAX_FIDS)
netif_wake_queue(dev);
@@ -2199,7 +2198,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
netif_stop_queue(dev);
if (i == MAX_FIDS) {
- priv->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
return 1;
}
}
@@ -2219,8 +2218,9 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
return 0;
}
-static void airo_read_stats(struct airo_info *ai)
+static void airo_read_stats(struct net_device *dev)
{
+ struct airo_info *ai = dev->priv;
StatsRid stats_rid;
__le32 *vals = stats_rid.vals;
@@ -2232,23 +2232,24 @@ static void airo_read_stats(struct airo_info *ai)
readStatsRid(ai, &stats_rid, RID_STATS, 0);
up(&ai->sem);
- ai->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
+ dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
le32_to_cpu(vals[45]);
- ai->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
+ dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
le32_to_cpu(vals[41]);
- ai->stats.rx_bytes = le32_to_cpu(vals[92]);
- ai->stats.tx_bytes = le32_to_cpu(vals[91]);
- ai->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
+ dev->stats.rx_bytes = le32_to_cpu(vals[92]);
+ dev->stats.tx_bytes = le32_to_cpu(vals[91]);
+ dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
- ai->stats.tx_errors = le32_to_cpu(vals[42]) + ai->stats.tx_fifo_errors;
- ai->stats.multicast = le32_to_cpu(vals[43]);
- ai->stats.collisions = le32_to_cpu(vals[89]);
+ dev->stats.tx_errors = le32_to_cpu(vals[42]) +
+ dev->stats.tx_fifo_errors;
+ dev->stats.multicast = le32_to_cpu(vals[43]);
+ dev->stats.collisions = le32_to_cpu(vals[89]);
/* detailed rx_errors: */
- ai->stats.rx_length_errors = le32_to_cpu(vals[3]);
- ai->stats.rx_crc_errors = le32_to_cpu(vals[4]);
- ai->stats.rx_frame_errors = le32_to_cpu(vals[2]);
- ai->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
+ dev->stats.rx_length_errors = le32_to_cpu(vals[3]);
+ dev->stats.rx_crc_errors = le32_to_cpu(vals[4]);
+ dev->stats.rx_frame_errors = le32_to_cpu(vals[2]);
+ dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
}
static struct net_device_stats *airo_get_stats(struct net_device *dev)
@@ -2261,10 +2262,10 @@ static struct net_device_stats *airo_get_stats(struct net_device *dev)
set_bit(JOB_STATS, &local->jobs);
wake_up_interruptible(&local->thr_wait);
} else
- airo_read_stats(local);
+ airo_read_stats(dev);
}
- return &local->stats;
+ return &dev->stats;
}
static void airo_set_promisc(struct airo_info *ai) {
@@ -3093,7 +3094,7 @@ static int airo_thread(void *data) {
else if (test_bit(JOB_XMIT11, &ai->jobs))
airo_end_xmit11(dev);
else if (test_bit(JOB_STATS, &ai->jobs))
- airo_read_stats(ai);
+ airo_read_stats(dev);
else if (test_bit(JOB_WSTATS, &ai->jobs))
airo_read_wireless_stats(ai);
else if (test_bit(JOB_PROMISC, &ai->jobs))
@@ -3289,7 +3290,7 @@ static irqreturn_t airo_interrupt(int irq, void *dev_id)
skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
if ( !skb ) {
- apriv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
goto badrx;
}
skb_reserve(skb, 2); /* This way the IP header is aligned */
@@ -3557,7 +3558,7 @@ static void mpi_receive_802_3(struct airo_info *ai)
skb = dev_alloc_skb(len);
if (!skb) {
- ai->stats.rx_dropped++;
+ ai->dev->stats.rx_dropped++;
goto badrx;
}
buffer = skb_put(skb,len);
@@ -3650,7 +3651,7 @@ void mpi_receive_802_11 (struct airo_info *ai)
skb = dev_alloc_skb( len + hdrlen + 2 );
if ( !skb ) {
- ai->stats.rx_dropped++;
+ ai->dev->stats.rx_dropped++;
goto badrx;
}
buffer = (u16*)skb_put (skb, len + hdrlen);
@@ -4560,22 +4561,13 @@ static ssize_t proc_read( struct file *file,
size_t len,
loff_t *offset )
{
- loff_t pos = *offset;
- struct proc_data *priv = (struct proc_data*)file->private_data;
+ struct proc_data *priv = file->private_data;
if (!priv->rbuffer)
return -EINVAL;
- if (pos < 0)
- return -EINVAL;
- if (pos >= priv->readlen)
- return 0;
- if (len > priv->readlen - pos)
- len = priv->readlen - pos;
- if (copy_to_user(buffer, priv->rbuffer + pos, len))
- return -EFAULT;
- *offset = pos + len;
- return len;
+ return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
+ priv->readlen);
}
/*
@@ -5530,11 +5522,13 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
Cmd cmd;
Resp rsp;
- if ((ai->APList == NULL) &&
- (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
+ if (!ai->APList)
+ ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL);
+ if (!ai->APList)
return -ENOMEM;
- if ((ai->SSID == NULL) &&
- (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
+ if (!ai->SSID)
+ ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL);
+ if (!ai->SSID)
return -ENOMEM;
readAPListRid(ai, ai->APList);
readSsidRid(ai, ai->SSID);
@@ -5545,7 +5539,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
disable_MAC(ai, 0);
netif_device_detach(dev);
ai->power = state;
- cmd.cmd=HOSTSLEEP;
+ cmd.cmd = HOSTSLEEP;
issuecommand(ai, &cmd, &rsp);
pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
@@ -5575,7 +5569,7 @@ static int airo_pci_resume(struct pci_dev *pdev)
msleep(100);
}
- set_bit (FLAG_COMMIT, &ai->flags);
+ set_bit(FLAG_COMMIT, &ai->flags);
disable_MAC(ai, 0);
msleep(200);
if (ai->SSID) {
@@ -5602,9 +5596,6 @@ static int airo_pci_resume(struct pci_dev *pdev)
static int __init airo_init_module( void )
{
int i;
-#if 0
- int have_isa_dev = 0;
-#endif
airo_entry = create_proc_entry("driver/aironet",
S_IFDIR | airo_perm,
@@ -5615,15 +5606,11 @@ static int __init airo_init_module( void )
airo_entry->gid = proc_gid;
}
- for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
+ for (i = 0; i < 4 && io[i] && irq[i]; i++) {
airo_print_info("", "Trying to configure ISA adapter at irq=%d "
"io=0x%x", irq[i], io[i] );
if (init_airo_card( irq[i], io[i], 0, NULL ))
-#if 0
- have_isa_dev = 1;
-#else
/* do nothing */ ;
-#endif
}
#ifdef CONFIG_PCI
@@ -5669,7 +5656,7 @@ static void __exit airo_cleanup_module( void )
static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi)
{
- if( !rssi_rid )
+ if (!rssi_rid)
return 0;
return (0x100 - rssi_rid[rssi].rssidBm);
@@ -5679,10 +5666,10 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
{
int i;
- if( !rssi_rid )
+ if (!rssi_rid)
return 0;
- for( i = 0; i < 256; i++ )
+ for (i = 0; i < 256; i++)
if (rssi_rid[i].rssidBm == dbm)
return rssi_rid[i].rssipct;
@@ -7164,6 +7151,7 @@ out:
* format that the Wireless Tools will understand - Jean II
*/
static inline char *airo_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *current_ev,
char *end_buf,
BSSListRid *bss)
@@ -7180,7 +7168,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -7190,7 +7179,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -7200,7 +7190,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add frequency */
@@ -7211,7 +7202,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
*/
iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
dBm = le16_to_cpu(bss->dBm);
@@ -7231,7 +7223,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
| IW_QUAL_DBM;
}
iwe.u.qual.noise = ai->wstats.qual.noise;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -7240,11 +7233,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
- current_val = current_ev + IW_EV_LCP_LEN;
+ current_val = current_ev + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */
@@ -7257,10 +7251,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
- if((current_val - current_ev) > IW_EV_LCP_LEN)
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val;
/* Beacon interval */
@@ -7269,7 +7265,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
}
@@ -7303,8 +7300,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev,
+ end_buf, &iwe,
+ (char *) info_element);
}
break;
@@ -7312,8 +7311,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev, end_buf,
+ &iwe, (char *) info_element);
break;
default:
@@ -7352,7 +7352,7 @@ static int airo_get_scan(struct net_device *dev,
list_for_each_entry (net, &ai->network_list, list) {
/* Translate to WE format this entry */
- current_ev = airo_translate_scan(dev, current_ev,
+ current_ev = airo_translate_scan(dev, info, current_ev,
extra + dwrq->length,
&net->bss);
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index dbdfc9e39d2..dec5e874a54 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -125,7 +125,7 @@ static inline int arlan_drop_tx(struct net_device *dev)
{
struct arlan_private *priv = netdev_priv(dev);
- priv->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (priv->Conf->tx_delay_ms)
{
priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1;
@@ -1269,7 +1269,7 @@ static void arlan_tx_done_interrupt(struct net_device *dev, int status)
{
IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
printk("arlan intr: transmit OK\n");
- priv->stats.tx_packets++;
+ dev->stats.tx_packets++;
priv->bad = 0;
priv->reset = 0;
priv->retransmissions = 0;
@@ -1496,7 +1496,7 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short
if (skb == NULL)
{
printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);
- priv->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
skb_reserve(skb, 2);
@@ -1536,14 +1536,14 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short
}
netif_rx(skb);
dev->last_rx = jiffies;
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
break;
default:
printk(KERN_ERR "arlan intr: received unknown status\n");
- priv->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
break;
}
ARLAN_DEBUG_EXIT("arlan_rx_interrupt");
@@ -1719,23 +1719,23 @@ static struct net_device_stats *arlan_statistics(struct net_device *dev)
/* Update the statistics from the device registers. */
- READSHM(priv->stats.collisions, arlan->numReTransmissions, u_int);
- READSHM(priv->stats.rx_crc_errors, arlan->numCRCErrors, u_int);
- READSHM(priv->stats.rx_dropped, arlan->numFramesDiscarded, u_int);
- READSHM(priv->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int);
- READSHM(priv->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int);
- READSHM(priv->stats.rx_over_errors, arlan->numRXOverruns, u_int);
- READSHM(priv->stats.rx_packets, arlan->numDatagramsReceived, u_int);
- READSHM(priv->stats.tx_aborted_errors, arlan->numAbortErrors, u_int);
- READSHM(priv->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int);
- READSHM(priv->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int);
- READSHM(priv->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int);
- READSHM(priv->stats.tx_packets, arlan->numDatagramsTransmitted, u_int);
- READSHM(priv->stats.tx_window_errors, arlan->numHoldOffs, u_int);
+ READSHM(dev->stats.collisions, arlan->numReTransmissions, u_int);
+ READSHM(dev->stats.rx_crc_errors, arlan->numCRCErrors, u_int);
+ READSHM(dev->stats.rx_dropped, arlan->numFramesDiscarded, u_int);
+ READSHM(dev->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int);
+ READSHM(dev->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int);
+ READSHM(dev->stats.rx_over_errors, arlan->numRXOverruns, u_int);
+ READSHM(dev->stats.rx_packets, arlan->numDatagramsReceived, u_int);
+ READSHM(dev->stats.tx_aborted_errors, arlan->numAbortErrors, u_int);
+ READSHM(dev->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int);
+ READSHM(dev->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int);
+ READSHM(dev->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int);
+ READSHM(dev->stats.tx_packets, arlan->numDatagramsTransmitted, u_int);
+ READSHM(dev->stats.tx_window_errors, arlan->numHoldOffs, u_int);
ARLAN_DEBUG_EXIT("arlan_statistics");
- return &priv->stats;
+ return &dev->stats;
}
diff --git a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h
index 3ed1df75900..fb3ad51a1ca 100644
--- a/drivers/net/wireless/arlan.h
+++ b/drivers/net/wireless/arlan.h
@@ -330,7 +330,6 @@ struct TxParam
#define TX_RING_SIZE 2
/* Information that need to be kept for each board. */
struct arlan_private {
- struct net_device_stats stats;
struct arlan_shmem __iomem * card;
struct arlan_shmem * conf;
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig
index f1f2aea2eab..75383a5df99 100644
--- a/drivers/net/wireless/ath5k/Kconfig
+++ b/drivers/net/wireless/ath5k/Kconfig
@@ -1,6 +1,9 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ select MAC80211_LEDS
+ select LEDS_CLASS
+ select NEW_LEDS
---help---
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 635b9ac9aaa..217d506527a 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -58,11 +58,6 @@
#include "reg.h"
#include "debug.h"
-enum {
- ATH_LED_TX,
- ATH_LED_RX,
-};
-
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
@@ -167,8 +162,7 @@ static struct pci_driver ath5k_pci_driver = {
/*
* Prototypes - MAC 802.11 stack related functions
*/
-static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *ctl);
+static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
static int ath5k_reset(struct ieee80211_hw *hw);
static int ath5k_start(struct ieee80211_hw *hw);
static void ath5k_stop(struct ieee80211_hw *hw);
@@ -196,8 +190,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
static void ath5k_reset_tsf(struct ieee80211_hw *hw);
static int ath5k_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl);
+ struct sk_buff *skb);
static struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx,
@@ -214,7 +207,6 @@ static struct ieee80211_ops ath5k_hw_ops = {
.get_tx_stats = ath5k_get_tx_stats,
.get_tsf = ath5k_get_tsf,
.reset_tsf = ath5k_reset_tsf,
- .beacon_update = ath5k_beacon_update,
};
/*
@@ -251,9 +243,7 @@ static void ath5k_desc_free(struct ath5k_softc *sc,
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,
- struct ieee80211_tx_control *ctl);
-
+ struct ath5k_buf *bf);
static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
struct ath5k_buf *bf)
{
@@ -289,8 +279,7 @@ static void ath5k_tx_processq(struct ath5k_softc *sc,
static void ath5k_tasklet_tx(unsigned long data);
/* Beacon handling */
static int ath5k_beacon_setup(struct ath5k_softc *sc,
- struct ath5k_buf *bf,
- struct ieee80211_tx_control *ctl);
+ struct ath5k_buf *bf);
static void ath5k_beacon_send(struct ath5k_softc *sc);
static void ath5k_beacon_config(struct ath5k_softc *sc);
static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
@@ -314,13 +303,10 @@ static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data);
/* LED functions */
-static void ath5k_led_off(unsigned long data);
-static void ath5k_led_blink(struct ath5k_softc *sc,
- unsigned int on,
- unsigned int off);
-static void ath5k_led_event(struct ath5k_softc *sc,
- int event);
-
+static int ath5k_init_leds(struct ath5k_softc *sc);
+static void ath5k_led_enable(struct ath5k_softc *sc);
+static void ath5k_led_off(struct ath5k_softc *sc);
+static void ath5k_unregister_leds(struct ath5k_softc *sc);
/*
* Module init/exit functions
@@ -458,13 +444,11 @@ ath5k_pci_probe(struct pci_dev *pdev,
/* Initialize driver private data */
SET_IEEE80211_DEV(hw, &pdev->dev);
- hw->flags = IEEE80211_HW_RX_INCLUDES_FCS;
+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
hw->extra_tx_headroom = 2;
hw->channel_change_time = 5000;
- /* these names are misleading */
- hw->max_rssi = -110; /* signal in dBm */
- hw->max_noise = -110; /* noise in dBm */
- hw->max_signal = 100; /* we will provide a percentage based on rssi */
sc = hw->priv;
sc->hw = hw;
sc->pdev = pdev;
@@ -603,8 +587,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath5k_softc *sc = hw->priv;
- if (test_bit(ATH_STAT_LEDSOFT, sc->status))
- ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1);
+ ath5k_led_off(sc);
ath5k_stop_hw(sc);
pci_save_state(pdev);
@@ -639,10 +622,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, 0);
ath5k_init(sc);
- if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
- ath5k_hw_set_gpio_output(ah, sc->led_pin);
- ath5k_hw_set_gpio(ah, sc->led_pin, 0);
- }
+ ath5k_led_enable(sc);
/*
* Reset the key cache since some parts do not
@@ -749,27 +729,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
- setup_timer(&sc->led_tim, ath5k_led_off, (unsigned long)sc);
-
- sc->led_on = 0; /* low true */
- /*
- * Auto-enable soft led processing for IBM cards and for
- * 5211 minipci cards.
- */
- if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
- pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
- __set_bit(ATH_STAT_LEDSOFT, sc->status);
- sc->led_pin = 0;
- }
- /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
- if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
- __set_bit(ATH_STAT_LEDSOFT, sc->status);
- sc->led_pin = 0;
- }
- if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
- ath5k_hw_set_gpio_output(ah, sc->led_pin);
- ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
- }
ath5k_hw_get_lladdr(ah, mac);
SET_IEEE80211_PERM_ADDR(hw, mac);
@@ -783,6 +742,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
goto err_queues;
}
+ ath5k_init_leds(sc);
+
return 0;
err_queues:
ath5k_txq_release(sc);
@@ -816,6 +777,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ath5k_desc_free(sc, pdev);
ath5k_txq_release(sc);
ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
+ ath5k_unregister_leds(sc);
/*
* NB: can't reclaim these until after ieee80211_ifdetach
@@ -1067,65 +1029,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
return 0;
}
-/*
- * TODO: CLEAN THIS !!!
- */
static void
ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
{
- if (unlikely(test_bit(ATH_STAT_LEDSOFT, sc->status))) {
- /* from Atheros NDIS driver, w/ permission */
- static const struct {
- u16 rate; /* tx/rx 802.11 rate */
- u16 timeOn; /* LED on time (ms) */
- u16 timeOff; /* LED off time (ms) */
- } blinkrates[] = {
- { 108, 40, 10 },
- { 96, 44, 11 },
- { 72, 50, 13 },
- { 48, 57, 14 },
- { 36, 67, 16 },
- { 24, 80, 20 },
- { 22, 100, 25 },
- { 18, 133, 34 },
- { 12, 160, 40 },
- { 10, 200, 50 },
- { 6, 240, 58 },
- { 4, 267, 66 },
- { 2, 400, 100 },
- { 0, 500, 130 }
- };
- const struct ath5k_rate_table *rt =
- ath5k_hw_get_rate_table(sc->ah, mode);
- unsigned int i, j;
-
- BUG_ON(rt == NULL);
-
- memset(sc->hwmap, 0, sizeof(sc->hwmap));
- for (i = 0; i < 32; i++) {
- u8 ix = rt->rate_code_to_index[i];
- if (ix == 0xff) {
- sc->hwmap[i].ledon = msecs_to_jiffies(500);
- sc->hwmap[i].ledoff = msecs_to_jiffies(130);
- continue;
- }
- sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
- /* receive frames include FCS */
- sc->hwmap[i].rxflags = sc->hwmap[i].txflags |
- IEEE80211_RADIOTAP_F_FCS;
- /* setup blink rate table to avoid per-packet lookup */
- for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++)
- if (blinkrates[j].rate == /* XXX why 7f? */
- (rt->rates[ix].dot11_rate&0x7f))
- break;
-
- sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j].
- timeOn);
- sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j].
- timeOff);
- }
- }
-
sc->curmode = mode;
if (mode == AR5K_MODE_11A) {
@@ -1297,36 +1203,36 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
}
static int
-ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
- struct ieee80211_tx_control *ctl)
+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 sk_buff *skb = bf->skb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
int ret;
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
- bf->ctl = *ctl;
+
/* XXX endianness */
bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE);
- if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= AR5K_TXDESC_NOACK;
pktlen = skb->len;
- if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
- keyidx = ctl->key_idx;
- pktlen += ctl->icv_len;
+ if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) {
+ keyidx = info->control.hw_key->hw_key_idx;
+ pktlen += info->control.icv_len;
}
-
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
- (sc->power_level * 2), ctl->tx_rate->hw_value,
- ctl->retry_limit, keyidx, 0, flags, 0, 0);
+ (sc->power_level * 2),
+ ieee80211_get_tx_rate(sc->hw, info)->hw_value,
+ info->control.retry_limit, keyidx, 0, flags, 0, 0);
if (ret)
goto err_unmap;
@@ -1335,7 +1241,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
spin_lock_bh(&txq->lock);
list_add_tail(&bf->list, &txq->q);
- sc->tx_stats.data[txq->qnum].len++;
+ sc->tx_stats[txq->qnum].len++;
if (txq->link == NULL) /* is this first packet? */
ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr);
else /* no, so only link it */
@@ -1566,7 +1472,7 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
ath5k_txbuf_free(sc, bf);
spin_lock_bh(&sc->txbuflock);
- sc->tx_stats.data[txq->qnum].len--;
+ sc->tx_stats[txq->qnum].len--;
list_move_tail(&bf->list, &sc->txbuf);
sc->txbuf_len++;
spin_unlock_bh(&sc->txbuflock);
@@ -1601,7 +1507,7 @@ ath5k_txq_cleanup(struct ath5k_softc *sc)
sc->txqs[i].link);
}
}
- ieee80211_start_queues(sc->hw); /* XXX move to callers */
+ ieee80211_wake_queues(sc->hw); /* XXX move to callers */
for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
if (sc->txqs[i].setup)
@@ -1698,9 +1604,9 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
/* Apparently when a default key is used to decrypt the packet
the hw does not set the index used to decrypt. In such cases
get the index from the packet. */
- if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) &&
- !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
- skb->len >= hlen + 4) {
+ if (ieee80211_has_protected(hdr->frame_control) &&
+ !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
+ skb->len >= hlen + 4) {
keyix = skb->data[hlen + 3] >> 6;
if (test_bit(keyix, sc->keymap))
@@ -1719,10 +1625,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
- if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) ==
- IEEE80211_FTYPE_MGMT &&
- (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) ==
- IEEE80211_STYPE_BEACON &&
+ if (ieee80211_is_beacon(mgmt->frame_control) &&
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
/*
@@ -1895,20 +1798,9 @@ accept:
rxs.freq = sc->curchan->center_freq;
rxs.band = sc->curband->band;
- /*
- * signal quality:
- * the names here are misleading and the usage of these
- * values by iwconfig makes it even worse
- */
- /* noise floor in dBm, from the last noise calibration */
rxs.noise = sc->ah->ah_noise_floor;
- /* signal level in dBm */
- rxs.ssi = rxs.noise + rs.rs_rssi;
- /*
- * "signal" is actually displayed as Link Quality by iwconfig
- * we provide a percentage based on rssi (assuming max rssi 64)
- */
- rxs.signal = rs.rs_rssi * 100 / 64;
+ rxs.signal = rxs.noise + rs.rs_rssi;
+ rxs.qual = rs.rs_rssi * 100 / 64;
rxs.antenna = rs.rs_antenna;
rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
@@ -1921,8 +1813,6 @@ accept:
ath5k_check_ibss_tsf(sc, skb, &rxs);
__ieee80211_rx(sc->hw, skb, &rxs);
- sc->led_rxrate = rs.rs_rate;
- ath5k_led_event(sc, ATH_LED_RX);
next:
list_move_tail(&bf->list, &sc->rxbuf);
} while (ath5k_rxbuf_setup(sc, bf) == 0);
@@ -1939,11 +1829,11 @@ next:
static void
ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
{
- struct ieee80211_tx_status txs = {};
struct ath5k_tx_status ts = {};
struct ath5k_buf *bf, *bf0;
struct ath5k_desc *ds;
struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
int ret;
spin_lock(&txq->lock);
@@ -1963,28 +1853,29 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
}
skb = bf->skb;
+ info = IEEE80211_SKB_CB(skb);
bf->skb = NULL;
+
pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
PCI_DMA_TODEVICE);
- txs.control = bf->ctl;
- txs.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
+ info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6;
if (unlikely(ts.ts_status)) {
sc->ll_stats.dot11ACKFailureCount++;
if (ts.ts_status & AR5K_TXERR_XRETRY)
- txs.excessive_retries = 1;
+ info->status.excessive_retries = 1;
else if (ts.ts_status & AR5K_TXERR_FILT)
- txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED;
+ info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
} else {
- txs.flags |= IEEE80211_TX_STATUS_ACK;
- txs.ack_signal = ts.ts_rssi;
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = ts.ts_rssi;
}
- ieee80211_tx_status(sc->hw, skb, &txs);
- sc->tx_stats.data[txq->qnum].count++;
+ ieee80211_tx_status(sc->hw, skb);
+ sc->tx_stats[txq->qnum].count++;
spin_lock(&sc->txbuflock);
- sc->tx_stats.data[txq->qnum].len--;
+ sc->tx_stats[txq->qnum].len--;
list_move_tail(&bf->list, &sc->txbuf);
sc->txbuf_len++;
spin_unlock(&sc->txbuflock);
@@ -2002,13 +1893,9 @@ ath5k_tasklet_tx(unsigned long data)
struct ath5k_softc *sc = (void *)data;
ath5k_tx_processq(sc, sc->txq);
-
- ath5k_led_event(sc, ATH_LED_TX);
}
-
-
/*****************\
* Beacon handling *
\*****************/
@@ -2017,10 +1904,10 @@ ath5k_tasklet_tx(unsigned long data)
* Setup the beacon frame for transmit.
*/
static int
-ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
- struct ieee80211_tx_control *ctl)
+ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
{
struct sk_buff *skb = bf->skb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ath5k_hw *ah = sc->ah;
struct ath5k_desc *ds;
int ret, antenna = 0;
@@ -2059,7 +1946,8 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
ieee80211_get_hdrlen_from_skb(skb),
AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
- ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID,
+ ieee80211_get_tx_rate(sc->hw, info)->hw_value,
+ 1, AR5K_TXKEYIX_INVALID,
antenna, flags, 0, 0);
if (ret)
goto err_unmap;
@@ -2382,11 +2270,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
ieee80211_stop_queues(sc->hw);
if (!test_bit(ATH_STAT_INVALID, sc->status)) {
- if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
- del_timer_sync(&sc->led_tim);
- ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
- __clear_bit(ATH_STAT_LEDBLINKING, sc->status);
- }
+ ath5k_led_off(sc);
ath5k_hw_set_intr(ah, 0);
}
ath5k_txq_cleanup(sc);
@@ -2582,54 +2466,123 @@ ath5k_calibrate(unsigned long data)
\***************/
static void
-ath5k_led_off(unsigned long data)
+ath5k_led_enable(struct ath5k_softc *sc)
{
- struct ath5k_softc *sc = (void *)data;
-
- if (test_bit(ATH_STAT_LEDENDBLINK, sc->status))
- __clear_bit(ATH_STAT_LEDBLINKING, sc->status);
- else {
- __set_bit(ATH_STAT_LEDENDBLINK, sc->status);
- ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
- mod_timer(&sc->led_tim, jiffies + sc->led_off);
+ if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+ ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
+ ath5k_led_off(sc);
}
}
-/*
- * Blink the LED according to the specified on/off times.
- */
static void
-ath5k_led_blink(struct ath5k_softc *sc, unsigned int on,
- unsigned int off)
+ath5k_led_on(struct ath5k_softc *sc)
{
- ATH5K_DBG(sc, ATH5K_DEBUG_LED, "on %u off %u\n", on, off);
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ return;
ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
- __set_bit(ATH_STAT_LEDBLINKING, sc->status);
- __clear_bit(ATH_STAT_LEDENDBLINK, sc->status);
- sc->led_off = off;
- mod_timer(&sc->led_tim, jiffies + on);
}
static void
-ath5k_led_event(struct ath5k_softc *sc, int event)
+ath5k_led_off(struct ath5k_softc *sc)
{
- if (likely(!test_bit(ATH_STAT_LEDSOFT, sc->status)))
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
return;
- if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status)))
- return; /* don't interrupt active blink */
- switch (event) {
- case ATH_LED_TX:
- ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon,
- sc->hwmap[sc->led_txrate].ledoff);
- break;
- case ATH_LED_RX:
- ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon,
- sc->hwmap[sc->led_rxrate].ledoff);
- break;
+ ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+}
+
+static void
+ath5k_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
+ led_dev);
+
+ if (brightness == LED_OFF)
+ ath5k_led_off(led->sc);
+ else
+ ath5k_led_on(led->sc);
+}
+
+static int
+ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+ const char *name, char *trigger)
+{
+ int err;
+
+ led->sc = sc;
+ strncpy(led->name, name, sizeof(led->name));
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = trigger;
+ led->led_dev.brightness_set = ath5k_led_brightness_set;
+
+ err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+ if (err)
+ {
+ ATH5K_WARN(sc, "could not register LED %s\n", name);
+ led->sc = NULL;
}
+ return err;
}
+static void
+ath5k_unregister_led(struct ath5k_led *led)
+{
+ if (!led->sc)
+ return;
+ led_classdev_unregister(&led->led_dev);
+ ath5k_led_off(led->sc);
+ led->sc = NULL;
+}
+
+static void
+ath5k_unregister_leds(struct ath5k_softc *sc)
+{
+ ath5k_unregister_led(&sc->rx_led);
+ ath5k_unregister_led(&sc->tx_led);
+}
+
+
+static int
+ath5k_init_leds(struct ath5k_softc *sc)
+{
+ int ret = 0;
+ struct ieee80211_hw *hw = sc->hw;
+ struct pci_dev *pdev = sc->pdev;
+ char name[ATH5K_LED_MAX_NAME_LEN + 1];
+
+ sc->led_on = 0; /* active low */
+ /*
+ * Auto-enable soft led processing for IBM cards and for
+ * 5211 minipci cards.
+ */
+ if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
+ pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
+ __set_bit(ATH_STAT_LEDSOFT, sc->status);
+ sc->led_pin = 0;
+ }
+ /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
+ __set_bit(ATH_STAT_LEDSOFT, sc->status);
+ sc->led_pin = 1;
+ }
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ goto out;
+
+ ath5k_led_enable(sc);
+
+ snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
+ ret = ath5k_register_led(sc, &sc->rx_led, name,
+ ieee80211_get_rx_led_name(hw));
+ if (ret)
+ goto out;
+
+ snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
+ ret = ath5k_register_led(sc, &sc->tx_led, name,
+ ieee80211_get_tx_led_name(hw));
+out:
+ return ret;
+}
/********************\
@@ -2637,8 +2590,7 @@ ath5k_led_event(struct ath5k_softc *sc, int event)
\********************/
static int
-ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_buf *bf;
@@ -2667,13 +2619,11 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
memmove(skb->data, skb->data+pad, hdrlen);
}
- sc->led_txrate = ctl->tx_rate->hw_value;
-
spin_lock_irqsave(&sc->txbuflock, flags);
if (list_empty(&sc->txbuf)) {
ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
spin_unlock_irqrestore(&sc->txbuflock, flags);
- ieee80211_stop_queue(hw, ctl->queue);
+ ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
return -1;
}
bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
@@ -2685,7 +2635,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
bf->skb = skb;
- if (ath5k_txbuf_setup(sc, bf, ctl)) {
+ if (ath5k_txbuf_setup(sc, bf)) {
bf->skb = NULL;
spin_lock_irqsave(&sc->txbuflock, flags);
list_add_tail(&bf->list, &sc->txbuf);
@@ -2834,6 +2784,18 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
* a clean way of letting us retrieve this yet. */
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
}
+
+ if (conf->changed & IEEE80211_IFCC_BEACON &&
+ vif->type == IEEE80211_IF_TYPE_IBSS) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+ if (!beacon) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
+ /* call old handler for now */
+ ath5k_beacon_update(hw, beacon);
+ }
+
mutex_unlock(&sc->lock);
return ath5k_reset(hw);
@@ -3063,8 +3025,7 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
}
static int
-ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath5k_softc *sc = hw->priv;
int ret;
@@ -3080,7 +3041,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
ath5k_txbuf_free(sc, sc->bbuf);
sc->bbuf->skb = skb;
- ret = ath5k_beacon_setup(sc, sc->bbuf, ctl);
+ ret = ath5k_beacon_setup(sc, sc->bbuf);
if (ret)
sc->bbuf->skb = NULL;
else
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index 3a975589301..47f414b09e6 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -45,6 +45,7 @@
#include <linux/list.h>
#include <linux/wireless.h>
#include <linux/if_ether.h>
+#include <linux/leds.h>
#include "ath5k.h"
#include "debug.h"
@@ -60,7 +61,6 @@ struct ath5k_buf {
dma_addr_t daddr; /* physical addr of desc */
struct sk_buff *skb; /* skbuff for buf */
dma_addr_t skbaddr;/* physical addr of skb data */
- struct ieee80211_tx_control ctl;
};
/*
@@ -80,6 +80,19 @@ struct ath5k_txq {
bool setup;
};
+#define ATH5K_LED_MAX_NAME_LEN 31
+
+/*
+ * State for LED triggers
+ */
+struct ath5k_led
+{
+ char name[ATH5K_LED_MAX_NAME_LEN + 1]; /* name of the LED in sysfs */
+ struct ath5k_softc *sc; /* driver state */
+ struct led_classdev led_dev; /* led classdev */
+};
+
+
#if CHAN_DEBUG
#define ATH_CHAN_MAX (26+26+26+200+200)
#else
@@ -92,7 +105,8 @@ struct ath5k_softc {
struct pci_dev *pdev; /* for dma mapping */
void __iomem *iobase; /* address of the device */
struct mutex lock; /* dev-level lock */
- struct ieee80211_tx_queue_stats tx_stats;
+ /* FIXME: how many does it really need? */
+ struct ieee80211_tx_queue_stats tx_stats[16];
struct ieee80211_low_level_stats ll_stats;
struct ieee80211_hw *hw; /* IEEE 802.11 common */
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
@@ -118,13 +132,11 @@ struct ath5k_softc {
size_t desc_len; /* size of TX/RX descriptors */
u16 cachelsz; /* cache line size */
- DECLARE_BITMAP(status, 6);
+ DECLARE_BITMAP(status, 4);
#define ATH_STAT_INVALID 0 /* disable hardware accesses */
#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
#define ATH_STAT_PROMISC 2
-#define ATH_STAT_LEDBLINKING 3 /* LED blink operation active */
-#define ATH_STAT_LEDENDBLINK 4 /* finish LED blink operation */
-#define ATH_STAT_LEDSOFT 5 /* enable LED gpio status */
+#define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
unsigned int curmode; /* current phy mode */
@@ -132,13 +144,6 @@ struct ath5k_softc {
struct ieee80211_vif *vif;
- struct {
- u8 rxflags; /* radiotap rx flags */
- u8 txflags; /* radiotap tx flags */
- u16 ledon; /* softled on time */
- u16 ledoff; /* softled off time */
- } hwmap[32]; /* h/w rate ix mappings */
-
enum ath5k_int imask; /* interrupt mask copy */
DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
@@ -148,9 +153,6 @@ struct ath5k_softc {
unsigned int led_pin, /* GPIO pin for driving LED */
led_on, /* pin setting for LED on */
led_off; /* off time for current blink */
- struct timer_list led_tim; /* led off timer */
- u8 led_rxrate; /* current rx rate for LED */
- u8 led_txrate; /* current tx rate for LED */
struct tasklet_struct restq; /* reset tasklet */
@@ -159,6 +161,7 @@ struct ath5k_softc {
spinlock_t rxbuflock;
u32 *rxlink; /* link ptr in last RX desc */
struct tasklet_struct rxtq; /* rx intr tasklet */
+ struct ath5k_led rx_led; /* rx led */
struct list_head txbuf; /* transmit buffer */
spinlock_t txbuflock;
@@ -167,6 +170,7 @@ struct ath5k_softc {
struct ath5k_txq *txq; /* beacon and tx*/
struct tasklet_struct txtq; /* tx intr tasklet */
+ struct ath5k_led tx_led; /* tx led */
struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index 77990b56860..c6d12c53bda 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -31,14 +31,14 @@
#include "base.h"
#include "debug.h"
-/*Rate tables*/
+/* Rate tables */
static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B;
static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G;
static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO;
static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR;
-/*Prototypes*/
+/* Prototypes */
static int ath5k_hw_nic_reset(struct ath5k_hw *, u32);
static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool);
static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index d1acef7e0b1..bd35bb0a148 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -433,7 +433,6 @@ struct atmel_private {
struct net_device *dev;
struct device *sys_dev;
struct iw_statistics wstats;
- struct net_device_stats stats; // device stats
spinlock_t irqlock, timerlock; // spinlocks
enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
enum {
@@ -694,9 +693,9 @@ static void tx_done_irq(struct atmel_private *priv)
if (type == TX_PACKET_TYPE_DATA) {
if (status == TX_STATUS_SUCCESS)
- priv->stats.tx_packets++;
+ priv->dev->stats.tx_packets++;
else
- priv->stats.tx_errors++;
+ priv->dev->stats.tx_errors++;
netif_wake_queue(priv->dev);
}
}
@@ -792,13 +791,13 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
if (priv->card && priv->present_callback &&
!(*priv->present_callback)(priv->card)) {
- priv->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return 0;
}
if (priv->station_state != STATION_STATE_READY) {
- priv->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb(skb);
return 0;
}
@@ -815,7 +814,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
initial + 18 (+30-12) */
if (!(buff = find_tx_buff(priv, len + 18))) {
- priv->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
spin_unlock_irqrestore(&priv->irqlock, flags);
spin_unlock_bh(&priv->timerlock);
netif_stop_queue(dev);
@@ -851,7 +850,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
/* low bit of first byte of destination tells us if broadcast */
tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
dev->trans_start = jiffies;
- priv->stats.tx_bytes += len;
+ dev->stats.tx_bytes += len;
spin_unlock_irqrestore(&priv->irqlock, flags);
spin_unlock_bh(&priv->timerlock);
@@ -895,7 +894,7 @@ static void fast_rx_path(struct atmel_private *priv,
}
if (!(skb = dev_alloc_skb(msdu_size + 14))) {
- priv->stats.rx_dropped++;
+ priv->dev->stats.rx_dropped++;
return;
}
@@ -908,7 +907,7 @@ static void fast_rx_path(struct atmel_private *priv,
crc = crc32_le(crc, skbp + 12, msdu_size);
atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
if ((crc ^ 0xffffffff) != netcrc) {
- priv->stats.rx_crc_errors++;
+ priv->dev->stats.rx_crc_errors++;
dev_kfree_skb(skb);
return;
}
@@ -924,8 +923,8 @@ static void fast_rx_path(struct atmel_private *priv,
skb->protocol = eth_type_trans(skb, priv->dev);
skb->ip_summed = CHECKSUM_NONE;
netif_rx(skb);
- priv->stats.rx_bytes += 12 + msdu_size;
- priv->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += 12 + msdu_size;
+ priv->dev->stats.rx_packets++;
}
/* Test to see if the packet in card memory at packet_loc has a valid CRC
@@ -991,7 +990,7 @@ static void frag_rx_path(struct atmel_private *priv,
crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
if ((crc ^ 0xffffffff) != netcrc) {
- priv->stats.rx_crc_errors++;
+ priv->dev->stats.rx_crc_errors++;
memset(priv->frag_source, 0xff, 6);
}
}
@@ -1009,7 +1008,7 @@ static void frag_rx_path(struct atmel_private *priv,
msdu_size);
atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
if ((crc ^ 0xffffffff) != netcrc) {
- priv->stats.rx_crc_errors++;
+ priv->dev->stats.rx_crc_errors++;
memset(priv->frag_source, 0xff, 6);
more_frags = 1; /* don't send broken assembly */
}
@@ -1021,7 +1020,7 @@ static void frag_rx_path(struct atmel_private *priv,
if (!more_frags) { /* last one */
memset(priv->frag_source, 0xff, 6);
if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
- priv->stats.rx_dropped++;
+ priv->dev->stats.rx_dropped++;
} else {
skb_reserve(skb, 2);
memcpy(skb_put(skb, priv->frag_len + 12),
@@ -1031,8 +1030,8 @@ static void frag_rx_path(struct atmel_private *priv,
skb->protocol = eth_type_trans(skb, priv->dev);
skb->ip_summed = CHECKSUM_NONE;
netif_rx(skb);
- priv->stats.rx_bytes += priv->frag_len + 12;
- priv->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += priv->frag_len + 12;
+ priv->dev->stats.rx_packets++;
}
}
} else
@@ -1057,7 +1056,7 @@ static void rx_done_irq(struct atmel_private *priv)
if (status == 0xc1) /* determined by experiment */
priv->wstats.discard.nwid++;
else
- priv->stats.rx_errors++;
+ priv->dev->stats.rx_errors++;
goto next;
}
@@ -1065,7 +1064,7 @@ static void rx_done_irq(struct atmel_private *priv)
rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
if (msdu_size < 30) {
- priv->stats.rx_errors++;
+ priv->dev->stats.rx_errors++;
goto next;
}
@@ -1123,7 +1122,7 @@ static void rx_done_irq(struct atmel_private *priv)
msdu_size -= 4;
crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
- priv->stats.rx_crc_errors++;
+ priv->dev->stats.rx_crc_errors++;
goto next;
}
}
@@ -1250,12 +1249,6 @@ static irqreturn_t service_interrupt(int irq, void *dev_id)
}
}
-static struct net_device_stats *atmel_get_stats(struct net_device *dev)
-{
- struct atmel_private *priv = netdev_priv(dev);
- return &priv->stats;
-}
-
static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
{
struct atmel_private *priv = netdev_priv(dev);
@@ -1518,8 +1511,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
} else
priv->probe_crc = 0;
- memset(&priv->stats, 0, sizeof(priv->stats));
- memset(&priv->wstats, 0, sizeof(priv->wstats));
priv->last_qual = jiffies;
priv->last_beacon_timestamp = 0;
memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
@@ -1568,7 +1559,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
dev->change_mtu = atmel_change_mtu;
dev->set_mac_address = atmel_set_mac_address;
dev->hard_start_xmit = start_tx;
- dev->get_stats = atmel_get_stats;
dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
dev->do_ioctl = atmel_ioctl;
dev->irq = irq;
@@ -2320,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_ADDR_LEN);
iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
if (iwe.u.data.length > 32)
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, priv->BSSinfo[i].SSID);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = priv->BSSinfo[i].BSStype;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = priv->BSSinfo[i].channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
iwe.u.qual.qual = iwe.u.qual.level;
/* iwe.u.qual.noise = SOMETHING */
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_QUAL_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -2352,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, NULL);
}
/* Length of data */
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index d3db298c05f..edcdfa36645 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -410,8 +410,7 @@ enum {
#define B43_IRQ_TIMEOUT 0x80000000
#define B43_IRQ_ALL 0xFFFFFFFF
-#define B43_IRQ_MASKTEMPLATE (B43_IRQ_MAC_SUSPENDED | \
- B43_IRQ_TBTT_INDI | \
+#define B43_IRQ_MASKTEMPLATE (B43_IRQ_TBTT_INDI | \
B43_IRQ_ATIM_END | \
B43_IRQ_PMQ | \
B43_IRQ_MAC_TXERR | \
@@ -423,6 +422,28 @@ enum {
B43_IRQ_RFKILL | \
B43_IRQ_TX_OK)
+/* The firmware register to fetch the debug-IRQ reason from. */
+#define B43_DEBUGIRQ_REASON_REG 63
+/* Debug-IRQ reasons. */
+#define B43_DEBUGIRQ_PANIC 0 /* The firmware panic'ed */
+#define B43_DEBUGIRQ_DUMP_SHM 1 /* Dump shared SHM */
+#define B43_DEBUGIRQ_DUMP_REGS 2 /* Dump the microcode registers */
+#define B43_DEBUGIRQ_MARKER 3 /* A "marker" was thrown by the firmware. */
+#define B43_DEBUGIRQ_ACK 0xFFFF /* The host writes that to ACK the IRQ */
+
+/* The firmware register that contains the "marker" line. */
+#define B43_MARKER_ID_REG 2
+#define B43_MARKER_LINE_REG 3
+
+/* The firmware register to fetch the panic reason from. */
+#define B43_FWPANIC_REASON_REG 3
+/* Firmware panic reason codes */
+#define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */
+#define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */
+
+/* The firmware register that contains the watchdog counter. */
+#define B43_WATCHDOG_REG 1
+
/* Device specific rate values.
* The actual values defined here are (rate_in_mbps * 2).
* Some code depends on this. Don't change it. */
@@ -733,7 +754,6 @@ struct b43_wl {
/* The beacon we are currently using (AP or IBSS mode).
* This beacon stuff is protected by the irq_lock. */
struct sk_buff *current_beacon;
- struct ieee80211_tx_control beacon_txctl;
bool beacon0_uploaded;
bool beacon1_uploaded;
bool beacon_templates_virgin; /* Never wrote the templates? */
@@ -767,6 +787,13 @@ struct b43_firmware {
u16 rev;
/* Firmware patchlevel */
u16 patch;
+
+ /* Set to true, if we are using an opensource firmware. */
+ bool opensource;
+ /* Set to true, if the core needs a PCM firmware, but
+ * we failed to load one. This is always false for
+ * core rev > 10, as these don't need PCM firmware. */
+ bool pcm_request_failed;
};
/* Device (802.11 core) initialization status. */
@@ -940,22 +967,6 @@ static inline bool __b43_warn_on_dummy(bool x) { return x; }
# define B43_WARN_ON(x) __b43_warn_on_dummy(unlikely(!!(x)))
#endif
-/** Limit a value between two limits */
-#ifdef limit_value
-# undef limit_value
-#endif
-#define limit_value(value, min, max) \
- ({ \
- typeof(value) __value = (value); \
- typeof(value) __min = (min); \
- typeof(value) __max = (max); \
- if (__value < __min) \
- __value = __min; \
- else if (__value > __max) \
- __value = __max; \
- __value; \
- })
-
/* Convert an integer to a Q5.2 value */
#define INT_TO_Q52(i) ((i) << 2)
/* Convert a Q5.2 value to an integer (precision loss!) */
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 7fca2ebc747..29851bc1101 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -74,70 +74,327 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
} while (0)
-/* wl->irq_lock is locked */
-static ssize_t tsf_read_file(struct b43_wldev *dev,
- char *buf, size_t bufsize)
+/* The biggest address values for SHM access from the debugfs files. */
+#define B43_MAX_SHM_ROUTING 4
+#define B43_MAX_SHM_ADDR 0xFFFF
+
+static ssize_t shm16read__read_file(struct b43_wldev *dev,
+ char *buf, size_t bufsize)
{
ssize_t count = 0;
- u64 tsf;
+ unsigned int routing, addr;
+ u16 val;
- b43_tsf_read(dev, &tsf);
- fappend("0x%08x%08x\n",
- (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
- (unsigned int)(tsf & 0xFFFFFFFFULL));
+ routing = dev->dfsentry->shm16read_routing_next;
+ addr = dev->dfsentry->shm16read_addr_next;
+ if ((routing > B43_MAX_SHM_ROUTING) ||
+ (addr > B43_MAX_SHM_ADDR))
+ return -EDESTADDRREQ;
+
+ val = b43_shm_read16(dev, routing, addr);
+ fappend("0x%04X\n", val);
return count;
}
-/* wl->irq_lock is locked */
-static int tsf_write_file(struct b43_wldev *dev,
- const char *buf, size_t count)
+static int shm16read__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
{
- u64 tsf;
+ unsigned int routing, addr;
+ int res;
- if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
+ res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
+ if (res != 2)
return -EINVAL;
- b43_tsf_write(dev, tsf);
+ if (routing > B43_MAX_SHM_ROUTING)
+ return -EADDRNOTAVAIL;
+ if (addr > B43_MAX_SHM_ADDR)
+ return -EADDRNOTAVAIL;
+ if (routing == B43_SHM_SHARED) {
+ if ((addr % 2) != 0)
+ return -EADDRNOTAVAIL;
+ }
+
+ dev->dfsentry->shm16read_routing_next = routing;
+ dev->dfsentry->shm16read_addr_next = addr;
return 0;
}
-/* wl->irq_lock is locked */
-static ssize_t ucode_regs_read_file(struct b43_wldev *dev,
+static int shm16write__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int routing, addr, mask, set;
+ u16 val;
+ int res;
+ unsigned long flags;
+
+ res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
+ &routing, &addr, &mask, &set);
+ if (res != 4)
+ return -EINVAL;
+ if (routing > B43_MAX_SHM_ROUTING)
+ return -EADDRNOTAVAIL;
+ if (addr > B43_MAX_SHM_ADDR)
+ return -EADDRNOTAVAIL;
+ if (routing == B43_SHM_SHARED) {
+ if ((addr % 2) != 0)
+ return -EADDRNOTAVAIL;
+ }
+ if ((mask > 0xFFFF) || (set > 0xFFFF))
+ return -E2BIG;
+
+ spin_lock_irqsave(&dev->wl->shm_lock, flags);
+ if (mask == 0)
+ val = 0;
+ else
+ val = __b43_shm_read16(dev, routing, addr);
+ val &= mask;
+ val |= set;
+ __b43_shm_write16(dev, routing, addr, val);
+ spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
+
+ return 0;
+}
+
+static ssize_t shm32read__read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
- int i;
+ unsigned int routing, addr;
+ u32 val;
+
+ routing = dev->dfsentry->shm32read_routing_next;
+ addr = dev->dfsentry->shm32read_addr_next;
+ if ((routing > B43_MAX_SHM_ROUTING) ||
+ (addr > B43_MAX_SHM_ADDR))
+ return -EDESTADDRREQ;
+
+ val = b43_shm_read32(dev, routing, addr);
+ fappend("0x%08X\n", val);
- for (i = 0; i < 64; i++) {
- fappend("r%d = 0x%04x\n", i,
- b43_shm_read16(dev, B43_SHM_SCRATCH, i));
+ return count;
+}
+
+static int shm32read__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int routing, addr;
+ int res;
+
+ res = sscanf(buf, "0x%X 0x%X", &routing, &addr);
+ if (res != 2)
+ return -EINVAL;
+ if (routing > B43_MAX_SHM_ROUTING)
+ return -EADDRNOTAVAIL;
+ if (addr > B43_MAX_SHM_ADDR)
+ return -EADDRNOTAVAIL;
+ if (routing == B43_SHM_SHARED) {
+ if ((addr % 2) != 0)
+ return -EADDRNOTAVAIL;
}
+ dev->dfsentry->shm32read_routing_next = routing;
+ dev->dfsentry->shm32read_addr_next = addr;
+
+ return 0;
+}
+
+static int shm32write__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int routing, addr, mask, set;
+ u32 val;
+ int res;
+ unsigned long flags;
+
+ res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
+ &routing, &addr, &mask, &set);
+ if (res != 4)
+ return -EINVAL;
+ if (routing > B43_MAX_SHM_ROUTING)
+ return -EADDRNOTAVAIL;
+ if (addr > B43_MAX_SHM_ADDR)
+ return -EADDRNOTAVAIL;
+ if (routing == B43_SHM_SHARED) {
+ if ((addr % 2) != 0)
+ return -EADDRNOTAVAIL;
+ }
+ if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
+ return -E2BIG;
+
+ spin_lock_irqsave(&dev->wl->shm_lock, flags);
+ if (mask == 0)
+ val = 0;
+ else
+ val = __b43_shm_read32(dev, routing, addr);
+ val &= mask;
+ val |= set;
+ __b43_shm_write32(dev, routing, addr, val);
+ spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
+
+ return 0;
+}
+
+/* The biggest MMIO address that we allow access to from the debugfs files. */
+#define B43_MAX_MMIO_ACCESS (0xF00 - 1)
+
+static ssize_t mmio16read__read_file(struct b43_wldev *dev,
+ char *buf, size_t bufsize)
+{
+ ssize_t count = 0;
+ unsigned int addr;
+ u16 val;
+
+ addr = dev->dfsentry->mmio16read_next;
+ if (addr > B43_MAX_MMIO_ACCESS)
+ return -EDESTADDRREQ;
+
+ val = b43_read16(dev, addr);
+ fappend("0x%04X\n", val);
+
+ return count;
+}
+
+static int mmio16read__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int addr;
+ int res;
+
+ res = sscanf(buf, "0x%X", &addr);
+ if (res != 1)
+ return -EINVAL;
+ if (addr > B43_MAX_MMIO_ACCESS)
+ return -EADDRNOTAVAIL;
+ if ((addr % 2) != 0)
+ return -EINVAL;
+
+ dev->dfsentry->mmio16read_next = addr;
+
+ return 0;
+}
+
+static int mmio16write__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int addr, mask, set;
+ int res;
+ u16 val;
+
+ res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
+ if (res != 3)
+ return -EINVAL;
+ if (addr > B43_MAX_MMIO_ACCESS)
+ return -EADDRNOTAVAIL;
+ if ((mask > 0xFFFF) || (set > 0xFFFF))
+ return -E2BIG;
+ if ((addr % 2) != 0)
+ return -EINVAL;
+
+ if (mask == 0)
+ val = 0;
+ else
+ val = b43_read16(dev, addr);
+ val &= mask;
+ val |= set;
+ b43_write16(dev, addr, val);
+
+ return 0;
+}
+
+static ssize_t mmio32read__read_file(struct b43_wldev *dev,
+ char *buf, size_t bufsize)
+{
+ ssize_t count = 0;
+ unsigned int addr;
+ u32 val;
+
+ addr = dev->dfsentry->mmio32read_next;
+ if (addr > B43_MAX_MMIO_ACCESS)
+ return -EDESTADDRREQ;
+
+ val = b43_read32(dev, addr);
+ fappend("0x%08X\n", val);
+
return count;
}
+static int mmio32read__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int addr;
+ int res;
+
+ res = sscanf(buf, "0x%X", &addr);
+ if (res != 1)
+ return -EINVAL;
+ if (addr > B43_MAX_MMIO_ACCESS)
+ return -EADDRNOTAVAIL;
+ if ((addr % 4) != 0)
+ return -EINVAL;
+
+ dev->dfsentry->mmio32read_next = addr;
+
+ return 0;
+}
+
+static int mmio32write__write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ unsigned int addr, mask, set;
+ int res;
+ u32 val;
+
+ res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set);
+ if (res != 3)
+ return -EINVAL;
+ if (addr > B43_MAX_MMIO_ACCESS)
+ return -EADDRNOTAVAIL;
+ if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
+ return -E2BIG;
+ if ((addr % 4) != 0)
+ return -EINVAL;
+
+ if (mask == 0)
+ val = 0;
+ else
+ val = b43_read32(dev, addr);
+ val &= mask;
+ val |= set;
+ b43_write32(dev, addr, val);
+
+ return 0;
+}
+
/* wl->irq_lock is locked */
-static ssize_t shm_read_file(struct b43_wldev *dev,
+static ssize_t tsf_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
ssize_t count = 0;
- int i;
- u16 tmp;
- __le16 *le16buf = (__le16 *)buf;
+ u64 tsf;
- for (i = 0; i < 0x1000; i++) {
- if (bufsize < sizeof(tmp))
- break;
- tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i);
- le16buf[i] = cpu_to_le16(tmp);
- count += sizeof(tmp);
- bufsize -= sizeof(tmp);
- }
+ b43_tsf_read(dev, &tsf);
+ fappend("0x%08x%08x\n",
+ (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
+ (unsigned int)(tsf & 0xFFFFFFFFULL));
return count;
}
+/* wl->irq_lock is locked */
+static int tsf_write_file(struct b43_wldev *dev,
+ const char *buf, size_t count)
+{
+ u64 tsf;
+
+ if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
+ return -EINVAL;
+ b43_tsf_write(dev, tsf);
+
+ return 0;
+}
+
static ssize_t txstat_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
@@ -270,24 +527,22 @@ static int restart_write_file(struct b43_wldev *dev,
return err;
}
-static ssize_t append_lo_table(ssize_t count, char *buf, const size_t bufsize,
- struct b43_loctl table[B43_NR_BB][B43_NR_RF])
+static unsigned long calc_expire_secs(unsigned long now,
+ unsigned long time,
+ unsigned long expire)
{
- unsigned int i, j;
- struct b43_loctl *ctl;
-
- for (i = 0; i < B43_NR_BB; i++) {
- for (j = 0; j < B43_NR_RF; j++) {
- ctl = &(table[i][j]);
- fappend("(bbatt %2u, rfatt %2u) -> "
- "(I %+3d, Q %+3d, Used: %d, Calibrated: %d)\n",
- i, j, ctl->i, ctl->q,
- ctl->used,
- b43_loctl_is_calibrated(ctl));
- }
+ expire = time + expire;
+
+ if (time_after(now, expire))
+ return 0; /* expired */
+ if (expire < now) {
+ /* jiffies wrapped */
+ expire -= MAX_JIFFY_OFFSET;
+ now -= MAX_JIFFY_OFFSET;
}
+ B43_WARN_ON(expire < now);
- return count;
+ return (expire - now) / HZ;
}
static ssize_t loctls_read_file(struct b43_wldev *dev,
@@ -296,27 +551,45 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
ssize_t count = 0;
struct b43_txpower_lo_control *lo;
int i, err = 0;
+ struct b43_lo_calib *cal;
+ unsigned long now = jiffies;
+ struct b43_phy *phy = &dev->phy;
- if (dev->phy.type != B43_PHYTYPE_G) {
+ if (phy->type != B43_PHYTYPE_G) {
fappend("Device is not a G-PHY\n");
err = -ENODEV;
goto out;
}
- lo = dev->phy.lo_control;
+ lo = phy->lo_control;
fappend("-- Local Oscillator calibration data --\n\n");
- fappend("Measured: %d, Rebuild: %d, HW-power-control: %d\n",
- lo->lo_measured,
- lo->rebuild,
+ fappend("HW-power-control enabled: %d\n",
dev->phy.hardware_power_control);
- fappend("TX Bias: 0x%02X, TX Magn: 0x%02X\n",
- lo->tx_bias, lo->tx_magn);
- fappend("Power Vector: 0x%08X%08X\n",
+ fappend("TX Bias: 0x%02X, TX Magn: 0x%02X (expire in %lu sec)\n",
+ lo->tx_bias, lo->tx_magn,
+ calc_expire_secs(now, lo->txctl_measured_time,
+ B43_LO_TXCTL_EXPIRE));
+ fappend("Power Vector: 0x%08X%08X (expires in %lu sec)\n",
(unsigned int)((lo->power_vector & 0xFFFFFFFF00000000ULL) >> 32),
- (unsigned int)(lo->power_vector & 0x00000000FFFFFFFFULL));
- fappend("\nControl table WITH PADMIX:\n");
- count = append_lo_table(count, buf, bufsize, lo->with_padmix);
- fappend("\nControl table WITHOUT PADMIX:\n");
- count = append_lo_table(count, buf, bufsize, lo->no_padmix);
+ (unsigned int)(lo->power_vector & 0x00000000FFFFFFFFULL),
+ calc_expire_secs(now, lo->pwr_vec_read_time,
+ B43_LO_PWRVEC_EXPIRE));
+
+ fappend("\nCalibrated settings:\n");
+ list_for_each_entry(cal, &lo->calib_list, list) {
+ bool active;
+
+ active = (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) &&
+ b43_compare_rfatt(&cal->rfatt, &phy->rfatt));
+ fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d "
+ "(expires in %lu sec)%s\n",
+ cal->bbatt.att,
+ cal->rfatt.att, cal->rfatt.with_padmix,
+ cal->ctl.i, cal->ctl.q,
+ calc_expire_secs(now, cal->calib_time,
+ B43_LO_CALIB_EXPIRE),
+ active ? " ACTIVE" : "");
+ }
+
fappend("\nUsed RF attenuation values: Value(WithPadmix flag)\n");
for (i = 0; i < lo->rfatt_list.len; i++) {
fappend("%u(%d), ",
@@ -351,7 +624,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
struct b43_dfs_file *dfile;
ssize_t uninitialized_var(ret);
char *buf;
- const size_t bufsize = 1024 * 128;
+ const size_t bufsize = 1024 * 16; /* 16 kiB buffer */
const size_t buforder = get_order(bufsize);
int err = 0;
@@ -380,8 +653,6 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
err = -ENOMEM;
goto out_unlock;
}
- /* Sparse warns about the following memset, because it has a big
- * size value. That warning is bogus, so I will ignore it. --mb */
memset(buf, 0, bufsize);
if (dfops->take_irqlock) {
spin_lock_irq(&dev->wl->irq_lock);
@@ -482,9 +753,15 @@ out_unlock:
.take_irqlock = _take_irqlock, \
}
+B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
+B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
+B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
+B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
+B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
+B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
+B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
+B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
-B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1);
-B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
@@ -523,6 +800,8 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
add_dyn_dbg("debug_dmaverbose", B43_DBG_DMAVERBOSE, 0);
add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0);
add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0);
+ add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
+ add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
#undef add_dyn_dbg
}
@@ -569,6 +848,13 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
return;
}
+ e->mmio16read_next = 0xFFFF; /* invalid address */
+ e->mmio32read_next = 0xFFFF; /* invalid address */
+ e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */
+ e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */
+ e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */
+ e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */
+
#define ADD_FILE(name, mode) \
do { \
struct dentry *d; \
@@ -581,9 +867,15 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
} while (0)
+ ADD_FILE(shm16read, 0600);
+ ADD_FILE(shm16write, 0200);
+ ADD_FILE(shm32read, 0600);
+ ADD_FILE(shm32write, 0200);
+ ADD_FILE(mmio16read, 0600);
+ ADD_FILE(mmio16write, 0200);
+ ADD_FILE(mmio32read, 0600);
+ ADD_FILE(mmio32write, 0200);
ADD_FILE(tsf, 0600);
- ADD_FILE(ucode_regs, 0400);
- ADD_FILE(shm, 0400);
ADD_FILE(txstat, 0400);
ADD_FILE(txpower_g, 0600);
ADD_FILE(restart, 0200);
@@ -605,9 +897,15 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
return;
b43_remove_dynamic_debug(dev);
+ debugfs_remove(e->file_shm16read.dentry);
+ debugfs_remove(e->file_shm16write.dentry);
+ debugfs_remove(e->file_shm32read.dentry);
+ debugfs_remove(e->file_shm32write.dentry);
+ debugfs_remove(e->file_mmio16read.dentry);
+ debugfs_remove(e->file_mmio16write.dentry);
+ debugfs_remove(e->file_mmio32read.dentry);
+ debugfs_remove(e->file_mmio32write.dentry);
debugfs_remove(e->file_tsf.dentry);
- debugfs_remove(e->file_ucode_regs.dentry);
- debugfs_remove(e->file_shm.dentry);
debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_txpower_g.dentry);
debugfs_remove(e->file_restart.dentry);
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index 6eebe858db5..22ffd02ba55 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -10,6 +10,8 @@ enum b43_dyndbg { /* Dynamic debugging features */
B43_DBG_DMAVERBOSE,
B43_DBG_PWORK_FAST,
B43_DBG_PWORK_STOP,
+ B43_DBG_LO,
+ B43_DBG_FIRMWARE,
__B43_NR_DYNDBG,
};
@@ -35,9 +37,15 @@ struct b43_dfsentry {
struct b43_wldev *dev;
struct dentry *subdir;
+ struct b43_dfs_file file_shm16read;
+ struct b43_dfs_file file_shm16write;
+ struct b43_dfs_file file_shm32read;
+ struct b43_dfs_file file_shm32write;
+ struct b43_dfs_file file_mmio16read;
+ struct b43_dfs_file file_mmio16write;
+ struct b43_dfs_file file_mmio32read;
+ struct b43_dfs_file file_mmio32write;
struct b43_dfs_file file_tsf;
- struct b43_dfs_file file_ucode_regs;
- struct b43_dfs_file file_shm;
struct b43_dfs_file file_txstat;
struct b43_dfs_file file_txpower_g;
struct b43_dfs_file file_restart;
@@ -45,6 +53,18 @@ struct b43_dfsentry {
struct b43_txstatus_log txstatlog;
+ /* The cached address for the next mmio16read file read */
+ u16 mmio16read_next;
+ /* The cached address for the next mmio32read file read */
+ u16 mmio32read_next;
+
+ /* The cached address for the next shm16read file read */
+ u32 shm16read_routing_next;
+ u32 shm16read_addr_next;
+ /* The cached address for the next shm32read file read */
+ u32 shm32read_routing_next;
+ u32 shm32read_addr_next;
+
/* Enabled/Disabled list for the dynamic debugging features. */
u32 dyn_debug[__B43_NR_DYNDBG];
/* Dentries for the dynamic debugging entries. */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index e23f2f172bd..098f886976f 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -328,11 +328,11 @@ static inline
dma_addr_t dmaaddr;
if (tx) {
- dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
- buf, len, DMA_TO_DEVICE);
+ dmaaddr = ssb_dma_map_single(ring->dev->dev,
+ buf, len, DMA_TO_DEVICE);
} else {
- dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
- buf, len, DMA_FROM_DEVICE);
+ dmaaddr = ssb_dma_map_single(ring->dev->dev,
+ buf, len, DMA_FROM_DEVICE);
}
return dmaaddr;
@@ -343,11 +343,11 @@ static inline
dma_addr_t addr, size_t len, int tx)
{
if (tx) {
- dma_unmap_single(ring->dev->dev->dma_dev,
- addr, len, DMA_TO_DEVICE);
+ ssb_dma_unmap_single(ring->dev->dev,
+ addr, len, DMA_TO_DEVICE);
} else {
- dma_unmap_single(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ ssb_dma_unmap_single(ring->dev->dev,
+ addr, len, DMA_FROM_DEVICE);
}
}
@@ -356,8 +356,8 @@ static inline
dma_addr_t addr, size_t len)
{
B43_WARN_ON(ring->tx);
- dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ ssb_dma_sync_single_for_cpu(ring->dev->dev,
+ addr, len, DMA_FROM_DEVICE);
}
static inline
@@ -365,8 +365,8 @@ static inline
dma_addr_t addr, size_t len)
{
B43_WARN_ON(ring->tx);
- dma_sync_single_for_device(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ ssb_dma_sync_single_for_device(ring->dev->dev,
+ addr, len, DMA_FROM_DEVICE);
}
static inline
@@ -381,7 +381,6 @@ static inline
static int alloc_ringmemory(struct b43_dmaring *ring)
{
- struct device *dma_dev = ring->dev->dev->dma_dev;
gfp_t flags = GFP_KERNEL;
/* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
* For unknown reasons - possibly a hardware error - the BCM4311 rev
* 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
* which accounts for the GFP_DMA flag below.
+ *
+ * The flags here must match the flags in free_ringmemory below!
*/
if (ring->type == B43_DMA_64BIT)
flags |= GFP_DMA;
- ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
- &(ring->dmabase), flags);
+ ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
+ B43_DMA_RINGMEMSIZE,
+ &(ring->dmabase), flags);
if (!ring->descbase) {
b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
return -ENOMEM;
@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
static void free_ringmemory(struct b43_dmaring *ring)
{
- struct device *dma_dev = ring->dev->dev->dma_dev;
+ gfp_t flags = GFP_KERNEL;
+
+ if (ring->type == B43_DMA_64BIT)
+ flags |= GFP_DMA;
- dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
- ring->descbase, ring->dmabase);
+ ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE,
+ ring->descbase, ring->dmabase, flags);
}
/* Reset the RX DMA channel */
@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
dma_addr_t addr,
size_t buffersize, bool dma_to_device)
{
- if (unlikely(dma_mapping_error(addr)))
+ if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1;
switch (ring->type) {
@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */
- dma_test = dma_map_single(dev->dev->dma_dev,
- ring->txhdr_cache,
- b43_txhdr_size(dev),
- DMA_TO_DEVICE);
+ dma_test = ssb_dma_map_single(dev->dev,
+ ring->txhdr_cache,
+ b43_txhdr_size(dev),
+ DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) {
@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (!ring->txhdr_cache)
goto err_kfree_meta;
- dma_test = dma_map_single(dev->dev->dma_dev,
- ring->txhdr_cache,
- b43_txhdr_size(dev),
- DMA_TO_DEVICE);
+ dma_test = ssb_dma_map_single(dev->dev,
+ ring->txhdr_cache,
+ b43_txhdr_size(dev),
+ DMA_TO_DEVICE);
if (b43_dma_mapping_error(ring, dma_test,
b43_txhdr_size(dev), 1)) {
@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
}
}
- dma_unmap_single(dev->dev->dma_dev,
- dma_test, b43_txhdr_size(dev),
- DMA_TO_DEVICE);
+ ssb_dma_unmap_single(dev->dev,
+ dma_test, b43_txhdr_size(dev),
+ DMA_TO_DEVICE);
}
err = alloc_ringmemory(ring);
@@ -1130,10 +1135,10 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
}
static int dma_tx_fragment(struct b43_dmaring *ring,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
const struct b43_dma_ops *ops = ring->ops;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 *header;
int slot, old_top_slot, old_used_slots;
int err;
@@ -1157,7 +1162,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
header = &(ring->txhdr_cache[slot * hdrsize]);
cookie = generate_cookie(ring, slot);
err = b43_generate_txhdr(ring->dev, header,
- skb->data, skb->len, ctl, cookie);
+ skb->data, skb->len, info, cookie);
if (unlikely(err)) {
ring->current_slot = old_top_slot;
ring->used_slots = old_used_slots;
@@ -1179,7 +1184,6 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
desc = ops->idx2desc(ring, slot, &meta);
memset(meta, 0, sizeof(*meta));
- memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
meta->skb = skb;
meta->is_last_fragment = 1;
@@ -1209,7 +1213,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
ops->fill_descriptor(ring, desc, meta->dmaaddr, skb->len, 0, 1, 1);
- if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/* Tell the firmware about the cookie of the last
* mcast frame, so it can clear the more-data bit in it. */
b43_shm_write16(ring->dev, B43_SHM_SHARED,
@@ -1280,16 +1284,16 @@ static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
return ring;
}
-int b43_dma_tx(struct b43_wldev *dev,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
{
struct b43_dmaring *ring;
struct ieee80211_hdr *hdr;
int err = 0;
unsigned long flags;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
hdr = (struct ieee80211_hdr *)skb->data;
- if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/* The multicast ring will be sent after the DTIM */
ring = dev->dma.tx_ring_mcast;
/* Set the more-data bit. Ucode will clear it on
@@ -1297,7 +1301,8 @@ int b43_dma_tx(struct b43_wldev *dev,
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
} else {
/* Decide by priority where to put this frame. */
- ring = select_ring_by_priority(dev, ctl->queue);
+ ring = select_ring_by_priority(
+ dev, skb_get_queue_mapping(skb));
}
spin_lock_irqsave(&ring->lock, flags);
@@ -1315,9 +1320,9 @@ int b43_dma_tx(struct b43_wldev *dev,
/* Assign the queue number to the ring (if not already done before)
* so TX status handling can use it. The queue to ring mapping is
* static, so we don't need to store it per frame. */
- ring->queue_prio = ctl->queue;
+ ring->queue_prio = skb_get_queue_mapping(skb);
- err = dma_tx_fragment(ring, skb, ctl);
+ err = dma_tx_fragment(ring, skb);
if (unlikely(err == -ENOKEY)) {
/* Drop this packet, as we don't have the encryption key
* anymore and must not transmit it unencrypted. */
@@ -1333,7 +1338,7 @@ int b43_dma_tx(struct b43_wldev *dev,
if ((free_slots(ring) < SLOTS_PER_PACKET) ||
should_inject_overflow(ring)) {
/* This TX ring is full. */
- ieee80211_stop_queue(dev->wl->hw, ctl->queue);
+ ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
ring->stopped = 1;
if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
@@ -1376,13 +1381,19 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
b43_txhdr_size(dev), 1);
if (meta->is_last_fragment) {
- B43_WARN_ON(!meta->skb);
- /* Call back to inform the ieee80211 subsystem about the
- * status of the transmission.
- * Some fields of txstat are already filled in dma_tx().
+ struct ieee80211_tx_info *info;
+
+ BUG_ON(!meta->skb);
+
+ info = IEEE80211_SKB_CB(meta->skb);
+
+ memset(&info->status, 0, sizeof(info->status));
+
+ /*
+ * Call back to inform the ieee80211 subsystem about
+ * the status of the transmission.
*/
- frame_succeed = b43_fill_txstatus_report(
- &(meta->txstat), status);
+ frame_succeed = b43_fill_txstatus_report(info, status);
#ifdef CONFIG_B43_DEBUG
if (frame_succeed)
ring->nr_succeed_tx_packets++;
@@ -1390,8 +1401,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
ring->nr_failed_tx_packets++;
ring->nr_total_packet_tries += status->frame_count;
#endif /* DEBUG */
- ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
- &(meta->txstat));
+ ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
+
/* skb is freed by ieee80211_tx_status_irqsafe() */
meta->skb = NULL;
} else {
@@ -1426,18 +1437,16 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
{
const int nr_queues = dev->wl->hw->queues;
struct b43_dmaring *ring;
- struct ieee80211_tx_queue_stats_data *data;
unsigned long flags;
int i;
for (i = 0; i < nr_queues; i++) {
- data = &(stats->data[i]);
ring = select_ring_by_priority(dev, i);
spin_lock_irqsave(&ring->lock, flags);
- data->len = ring->used_slots / SLOTS_PER_PACKET;
- data->limit = ring->nr_slots / SLOTS_PER_PACKET;
- data->count = ring->nr_tx_packets;
+ stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
+ stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
+ stats[i].count = ring->nr_tx_packets;
spin_unlock_irqrestore(&ring->lock, flags);
}
}
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index 20acf885dba..d1eb5c0848a 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -181,7 +181,6 @@ struct b43_dmadesc_meta {
dma_addr_t dmaaddr;
/* ieee80211 TX status. Only used once per 802.11 frag. */
bool is_last_fragment;
- struct ieee80211_tx_status txstat;
};
struct b43_dmaring;
@@ -285,7 +284,7 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
struct ieee80211_tx_queue_stats *stats);
int b43_dma_tx(struct b43_wldev *dev,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl);
+ struct sk_buff *skb);
void b43_dma_handle_txstatus(struct b43_wldev *dev,
const struct b43_txstatus *status);
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index d890f366a23..9c854d6aae3 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -36,17 +36,28 @@
#include <linux/sched.h>
-/* Define to 1 to always calibrate all possible LO control pairs.
- * This is a workaround until we fix the partial LO calibration optimization. */
-#define B43_CALIB_ALL_LOCTLS 1
+static struct b43_lo_calib * b43_find_lo_calib(struct b43_txpower_lo_control *lo,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
+{
+ struct b43_lo_calib *c;
+
+ list_for_each_entry(c, &lo->calib_list, list) {
+ if (!b43_compare_bbatt(&c->bbatt, bbatt))
+ continue;
+ if (!b43_compare_rfatt(&c->rfatt, rfatt))
+ continue;
+ return c;
+ }
+ return NULL;
+}
/* Write the LocalOscillator Control (adjust) value-pair. */
static void b43_lo_write(struct b43_wldev *dev, struct b43_loctl *control)
{
struct b43_phy *phy = &dev->phy;
u16 value;
- u16 reg;
if (B43_DEBUG) {
if (unlikely(abs(control->i) > 16 || abs(control->q) > 16)) {
@@ -56,189 +67,11 @@ static void b43_lo_write(struct b43_wldev *dev, struct b43_loctl *control)
return;
}
}
+ B43_WARN_ON(phy->type != B43_PHYTYPE_G);
value = (u8) (control->q);
value |= ((u8) (control->i)) << 8;
-
- reg = (phy->type == B43_PHYTYPE_B) ? 0x002F : B43_PHY_LO_CTL;
- b43_phy_write(dev, reg, value);
-}
-
-static int assert_rfatt_and_bbatt(const struct b43_rfatt *rfatt,
- const struct b43_bbatt *bbatt,
- struct b43_wldev *dev)
-{
- int err = 0;
-
- /* Check the attenuation values against the LO control array sizes. */
- if (unlikely(rfatt->att >= B43_NR_RF)) {
- b43err(dev->wl, "rfatt(%u) >= size of LO array\n", rfatt->att);
- err = -EINVAL;
- }
- if (unlikely(bbatt->att >= B43_NR_BB)) {
- b43err(dev->wl, "bbatt(%u) >= size of LO array\n", bbatt->att);
- err = -EINVAL;
- }
-
- return err;
-}
-
-#if !B43_CALIB_ALL_LOCTLS
-static
-struct b43_loctl *b43_get_lo_g_ctl_nopadmix(struct b43_wldev *dev,
- const struct b43_rfatt *rfatt,
- const struct b43_bbatt *bbatt)
-{
- struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
-
- if (assert_rfatt_and_bbatt(rfatt, bbatt, dev))
- return &(lo->no_padmix[0][0]); /* Just prevent a crash */
- return &(lo->no_padmix[bbatt->att][rfatt->att]);
-}
-#endif /* !B43_CALIB_ALL_LOCTLS */
-
-struct b43_loctl *b43_get_lo_g_ctl(struct b43_wldev *dev,
- const struct b43_rfatt *rfatt,
- const struct b43_bbatt *bbatt)
-{
- struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
-
- if (assert_rfatt_and_bbatt(rfatt, bbatt, dev))
- return &(lo->no_padmix[0][0]); /* Just prevent a crash */
- if (rfatt->with_padmix)
- return &(lo->with_padmix[bbatt->att][rfatt->att]);
- return &(lo->no_padmix[bbatt->att][rfatt->att]);
-}
-
-/* Call a function for every possible LO control value-pair. */
-static void b43_call_for_each_loctl(struct b43_wldev *dev,
- void (*func) (struct b43_wldev *,
- struct b43_loctl *))
-{
- struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *ctl = phy->lo_control;
- int i, j;
-
- for (i = 0; i < B43_NR_BB; i++) {
- for (j = 0; j < B43_NR_RF; j++)
- func(dev, &(ctl->with_padmix[i][j]));
- }
- for (i = 0; i < B43_NR_BB; i++) {
- for (j = 0; j < B43_NR_RF; j++)
- func(dev, &(ctl->no_padmix[i][j]));
- }
-}
-
-static u16 lo_b_r15_loop(struct b43_wldev *dev)
-{
- int i;
- u16 ret = 0;
-
- for (i = 0; i < 10; i++) {
- b43_phy_write(dev, 0x0015, 0xAFA0);
- udelay(1);
- b43_phy_write(dev, 0x0015, 0xEFA0);
- udelay(10);
- b43_phy_write(dev, 0x0015, 0xFFA0);
- udelay(40);
- ret += b43_phy_read(dev, 0x002C);
- }
-
- return ret;
-}
-
-void b43_lo_b_measure(struct b43_wldev *dev)
-{
- struct b43_phy *phy = &dev->phy;
- u16 regstack[12] = { 0 };
- u16 mls;
- u16 fval;
- int i, j;
-
- regstack[0] = b43_phy_read(dev, 0x0015);
- regstack[1] = b43_radio_read16(dev, 0x0052) & 0xFFF0;
-
- if (phy->radio_ver == 0x2053) {
- regstack[2] = b43_phy_read(dev, 0x000A);
- regstack[3] = b43_phy_read(dev, 0x002A);
- regstack[4] = b43_phy_read(dev, 0x0035);
- regstack[5] = b43_phy_read(dev, 0x0003);
- regstack[6] = b43_phy_read(dev, 0x0001);
- regstack[7] = b43_phy_read(dev, 0x0030);
-
- regstack[8] = b43_radio_read16(dev, 0x0043);
- regstack[9] = b43_radio_read16(dev, 0x007A);
- regstack[10] = b43_read16(dev, 0x03EC);
- regstack[11] = b43_radio_read16(dev, 0x0052) & 0x00F0;
-
- b43_phy_write(dev, 0x0030, 0x00FF);
- b43_write16(dev, 0x03EC, 0x3F3F);
- b43_phy_write(dev, 0x0035, regstack[4] & 0xFF7F);
- b43_radio_write16(dev, 0x007A, regstack[9] & 0xFFF0);
- }
- b43_phy_write(dev, 0x0015, 0xB000);
- b43_phy_write(dev, 0x002B, 0x0004);
-
- if (phy->radio_ver == 0x2053) {
- b43_phy_write(dev, 0x002B, 0x0203);
- b43_phy_write(dev, 0x002A, 0x08A3);
- }
-
- phy->minlowsig[0] = 0xFFFF;
-
- for (i = 0; i < 4; i++) {
- b43_radio_write16(dev, 0x0052, regstack[1] | i);
- lo_b_r15_loop(dev);
- }
- for (i = 0; i < 10; i++) {
- b43_radio_write16(dev, 0x0052, regstack[1] | i);
- mls = lo_b_r15_loop(dev) / 10;
- if (mls < phy->minlowsig[0]) {
- phy->minlowsig[0] = mls;
- phy->minlowsigpos[0] = i;
- }
- }
- b43_radio_write16(dev, 0x0052, regstack[1] | phy->minlowsigpos[0]);
-
- phy->minlowsig[1] = 0xFFFF;
-
- for (i = -4; i < 5; i += 2) {
- for (j = -4; j < 5; j += 2) {
- if (j < 0)
- fval = (0x0100 * i) + j + 0x0100;
- else
- fval = (0x0100 * i) + j;
- b43_phy_write(dev, 0x002F, fval);
- mls = lo_b_r15_loop(dev) / 10;
- if (mls < phy->minlowsig[1]) {
- phy->minlowsig[1] = mls;
- phy->minlowsigpos[1] = fval;
- }
- }
- }
- phy->minlowsigpos[1] += 0x0101;
-
- b43_phy_write(dev, 0x002F, phy->minlowsigpos[1]);
- if (phy->radio_ver == 0x2053) {
- b43_phy_write(dev, 0x000A, regstack[2]);
- b43_phy_write(dev, 0x002A, regstack[3]);
- b43_phy_write(dev, 0x0035, regstack[4]);
- b43_phy_write(dev, 0x0003, regstack[5]);
- b43_phy_write(dev, 0x0001, regstack[6]);
- b43_phy_write(dev, 0x0030, regstack[7]);
-
- b43_radio_write16(dev, 0x0043, regstack[8]);
- b43_radio_write16(dev, 0x007A, regstack[9]);
-
- b43_radio_write16(dev, 0x0052,
- (b43_radio_read16(dev, 0x0052) & 0x000F)
- | regstack[11]);
-
- b43_write16(dev, 0x03EC, regstack[10]);
- }
- b43_phy_write(dev, 0x0015, regstack[0]);
+ b43_phy_write(dev, B43_PHY_LO_CTL, value);
}
static u16 lo_measure_feedthrough(struct b43_wldev *dev,
@@ -366,7 +199,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
if (lb_gain > 10) {
radio_pctl_reg = 0;
pga = abs(10 - lb_gain) / 6;
- pga = limit_value(pga, 0, 15);
+ pga = clamp_val(pga, 0, 15);
} else {
int cmp_val;
int tmp;
@@ -438,48 +271,26 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
b43_radio_write16(dev, 0x52, b43_radio_read16(dev, 0x52)
& 0xFFF0); /* TX bias == 0 */
}
+ lo->txctl_measured_time = jiffies;
}
static void lo_read_power_vector(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
struct b43_txpower_lo_control *lo = phy->lo_control;
- u16 i;
+ int i;
u64 tmp;
u64 power_vector = 0;
- int rf_offset, bb_offset;
- struct b43_loctl *loctl;
for (i = 0; i < 8; i += 2) {
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x310 + i);
- /* Clear the top byte. We get holes in the bitmap... */
- tmp &= 0xFF;
power_vector |= (tmp << (i * 8));
/* Clear the vector on the device. */
b43_shm_write16(dev, B43_SHM_SHARED, 0x310 + i, 0);
}
-
if (power_vector)
lo->power_vector = power_vector;
- power_vector = lo->power_vector;
-
- for (i = 0; i < 64; i++) {
- if (power_vector & ((u64) 1ULL << i)) {
- /* Now figure out which b43_loctl corresponds
- * to this bit.
- */
- rf_offset = i / lo->rfatt_list.len;
- bb_offset = i % lo->rfatt_list.len; //FIXME?
- loctl =
- b43_get_lo_g_ctl(dev,
- &lo->rfatt_list.list[rf_offset],
- &lo->bbatt_list.list[bb_offset]);
- /* And mark it as "used", as the device told us
- * through the bitmap it is using it.
- */
- loctl->used = 1;
- }
- }
+ lo->pwr_vec_read_time = jiffies;
}
/* 802.11/LO/GPHY/MeasuringGains */
@@ -510,7 +321,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
phy->lna_lod_gain = 1;
trsw_rx_gain -= 8;
}
- trsw_rx_gain = limit_value(trsw_rx_gain, 0, 0x2D);
+ trsw_rx_gain = clamp_val(trsw_rx_gain, 0, 0x2D);
phy->pga_gain = trsw_rx_gain / 3;
if (phy->pga_gain >= 5) {
phy->pga_gain -= 5;
@@ -609,8 +420,6 @@ static void lo_measure_setup(struct b43_wldev *dev,
b43_phy_write(dev, B43_PHY_CCK(0x16), 0x410);
b43_phy_write(dev, B43_PHY_CCK(0x17), 0x820);
}
- if (!lo->rebuild && b43_has_hardware_pctl(phy))
- lo_read_power_vector(dev);
if (phy->rev >= 2) {
sav->phy_analogover = b43_phy_read(dev, B43_PHY_ANALOGOVER);
sav->phy_analogoverval =
@@ -691,8 +500,12 @@ static void lo_measure_setup(struct b43_wldev *dev,
b43_radio_read16(dev, 0x51); /* dummy read */
if (phy->type == B43_PHYTYPE_G)
b43_phy_write(dev, B43_PHY_CCK(0x2F), 0);
- if (lo->rebuild)
+
+ /* Re-measure the txctl values, if needed. */
+ if (time_before(lo->txctl_measured_time,
+ jiffies - B43_LO_TXCTL_EXPIRE))
lo_measure_txctl_values(dev);
+
if (phy->type == B43_PHYTYPE_G && phy->rev >= 3) {
b43_phy_write(dev, B43_PHY_LO_MASK, 0xC078);
} else {
@@ -707,7 +520,6 @@ static void lo_measure_restore(struct b43_wldev *dev,
struct lo_g_saved_values *sav)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
u16 tmp;
if (phy->rev >= 2) {
@@ -722,14 +534,6 @@ static void lo_measure_restore(struct b43_wldev *dev,
tmp = (phy->pga_gain | 0xEFA0);
b43_phy_write(dev, B43_PHY_PGACTL, tmp);
}
- if (b43_has_hardware_pctl(phy)) {
- b43_gphy_dc_lt_init(dev);
- } else {
- if (lo->rebuild)
- b43_lo_g_adjust_to(dev, 3, 2, 0);
- else
- b43_lo_g_adjust(dev);
- }
if (phy->type == B43_PHYTYPE_G) {
if (phy->rev >= 3)
b43_phy_write(dev, B43_PHY_CCK(0x2E), 0xC078);
@@ -793,7 +597,6 @@ static int lo_probe_possible_loctls(struct b43_wldev *dev,
struct b43_lo_g_statemachine *d)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
struct b43_loctl test_loctl;
struct b43_loctl orig_loctl;
struct b43_loctl prev_loctl = {
@@ -852,7 +655,7 @@ static int lo_probe_possible_loctls(struct b43_wldev *dev,
found_lower = 1;
d->lowest_feedth = feedth;
if ((d->nr_measured < 2) &&
- (!has_loopback_gain(phy) || lo->rebuild))
+ !has_loopback_gain(phy))
break;
}
}
@@ -874,7 +677,6 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
int *max_rx_gain)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
struct b43_lo_g_statemachine d;
u16 feedth;
int found_lower;
@@ -883,18 +685,18 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
d.nr_measured = 0;
d.state_val_multiplier = 1;
- if (has_loopback_gain(phy) && !lo->rebuild)
+ if (has_loopback_gain(phy))
d.state_val_multiplier = 3;
memcpy(&d.min_loctl, loctl, sizeof(struct b43_loctl));
- if (has_loopback_gain(phy) && lo->rebuild)
+ if (has_loopback_gain(phy))
max_repeat = 4;
do {
b43_lo_write(dev, &d.min_loctl);
feedth = lo_measure_feedthrough(dev, phy->lna_gain,
phy->pga_gain,
phy->trsw_rx_gain);
- if (!lo->rebuild && feedth < 0x258) {
+ if (feedth < 0x258) {
if (feedth >= 0x12C)
*max_rx_gain += 6;
else
@@ -944,278 +746,188 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
} while (++repeat_cnt < max_repeat);
}
-#if B43_CALIB_ALL_LOCTLS
-static const struct b43_rfatt b43_full_rfatt_list_items[] = {
- { .att = 0, .with_padmix = 0, },
- { .att = 1, .with_padmix = 0, },
- { .att = 2, .with_padmix = 0, },
- { .att = 3, .with_padmix = 0, },
- { .att = 4, .with_padmix = 0, },
- { .att = 5, .with_padmix = 0, },
- { .att = 6, .with_padmix = 0, },
- { .att = 7, .with_padmix = 0, },
- { .att = 8, .with_padmix = 0, },
- { .att = 9, .with_padmix = 0, },
- { .att = 10, .with_padmix = 0, },
- { .att = 11, .with_padmix = 0, },
- { .att = 12, .with_padmix = 0, },
- { .att = 13, .with_padmix = 0, },
- { .att = 14, .with_padmix = 0, },
- { .att = 15, .with_padmix = 0, },
- { .att = 0, .with_padmix = 1, },
- { .att = 1, .with_padmix = 1, },
- { .att = 2, .with_padmix = 1, },
- { .att = 3, .with_padmix = 1, },
- { .att = 4, .with_padmix = 1, },
- { .att = 5, .with_padmix = 1, },
- { .att = 6, .with_padmix = 1, },
- { .att = 7, .with_padmix = 1, },
- { .att = 8, .with_padmix = 1, },
- { .att = 9, .with_padmix = 1, },
- { .att = 10, .with_padmix = 1, },
- { .att = 11, .with_padmix = 1, },
- { .att = 12, .with_padmix = 1, },
- { .att = 13, .with_padmix = 1, },
- { .att = 14, .with_padmix = 1, },
- { .att = 15, .with_padmix = 1, },
-};
-static const struct b43_rfatt_list b43_full_rfatt_list = {
- .list = b43_full_rfatt_list_items,
- .len = ARRAY_SIZE(b43_full_rfatt_list_items),
-};
-
-static const struct b43_bbatt b43_full_bbatt_list_items[] = {
- { .att = 0, },
- { .att = 1, },
- { .att = 2, },
- { .att = 3, },
- { .att = 4, },
- { .att = 5, },
- { .att = 6, },
- { .att = 7, },
- { .att = 8, },
- { .att = 9, },
- { .att = 10, },
- { .att = 11, },
-};
-static const struct b43_bbatt_list b43_full_bbatt_list = {
- .list = b43_full_bbatt_list_items,
- .len = ARRAY_SIZE(b43_full_bbatt_list_items),
-};
-#endif /* B43_CALIB_ALL_LOCTLS */
-
-static void lo_measure(struct b43_wldev *dev)
+static
+struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
struct b43_loctl loctl = {
.i = 0,
.q = 0,
};
- struct b43_loctl *ploctl;
int max_rx_gain;
- int rfidx, bbidx;
- const struct b43_bbatt_list *bbatt_list;
- const struct b43_rfatt_list *rfatt_list;
-
+ struct b43_lo_calib *cal;
+ struct lo_g_saved_values uninitialized_var(saved_regs);
/* Values from the "TXCTL Register and Value Table" */
u16 txctl_reg;
u16 txctl_value;
u16 pad_mix_gain;
- bbatt_list = &lo->bbatt_list;
- rfatt_list = &lo->rfatt_list;
-#if B43_CALIB_ALL_LOCTLS
- bbatt_list = &b43_full_bbatt_list;
- rfatt_list = &b43_full_rfatt_list;
-#endif
+ saved_regs.old_channel = phy->channel;
+ b43_mac_suspend(dev);
+ lo_measure_setup(dev, &saved_regs);
txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);
- for (rfidx = 0; rfidx < rfatt_list->len; rfidx++) {
-
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) |
- rfatt_list->list[rfidx].att);
- b43_radio_write16(dev, txctl_reg,
- (b43_radio_read16(dev, txctl_reg)
- & ~txctl_value)
- | (rfatt_list->list[rfidx].with_padmix ?
- txctl_value : 0));
-
- for (bbidx = 0; bbidx < bbatt_list->len; bbidx++) {
- if (lo->rebuild) {
-#if B43_CALIB_ALL_LOCTLS
- ploctl = b43_get_lo_g_ctl(dev,
- &rfatt_list->list[rfidx],
- &bbatt_list->list[bbidx]);
-#else
- ploctl = b43_get_lo_g_ctl_nopadmix(dev,
- &rfatt_list->
- list[rfidx],
- &bbatt_list->
- list[bbidx]);
-#endif
- } else {
- ploctl = b43_get_lo_g_ctl(dev,
- &rfatt_list->list[rfidx],
- &bbatt_list->list[bbidx]);
- if (!ploctl->used)
- continue;
- }
- memcpy(&loctl, ploctl, sizeof(loctl));
- loctl.i = 0;
- loctl.q = 0;
-
- max_rx_gain = rfatt_list->list[rfidx].att * 2;
- max_rx_gain += bbatt_list->list[bbidx].att / 2;
- if (rfatt_list->list[rfidx].with_padmix)
- max_rx_gain -= pad_mix_gain;
- if (has_loopback_gain(phy))
- max_rx_gain += phy->max_lb_gain;
- lo_measure_gain_values(dev, max_rx_gain,
- has_loopback_gain(phy));
-
- b43_phy_set_baseband_attenuation(dev,
- bbatt_list->list[bbidx].att);
- lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain);
- if (phy->type == B43_PHYTYPE_B) {
- loctl.i++;
- loctl.q++;
- }
- b43_loctl_set_calibrated(&loctl, 1);
- memcpy(ploctl, &loctl, sizeof(loctl));
- }
- }
-}
-
-#if B43_DEBUG
-static void do_validate_loctl(struct b43_wldev *dev, struct b43_loctl *control)
-{
- const int is_initializing = (b43_status(dev) == B43_STAT_UNINIT);
- int i = control->i;
- int q = control->q;
+ b43_radio_write16(dev, 0x43,
+ (b43_radio_read16(dev, 0x43) & 0xFFF0)
+ | rfatt->att);
+ b43_radio_write16(dev, txctl_reg,
+ (b43_radio_read16(dev, txctl_reg) & ~txctl_value)
+ | (rfatt->with_padmix) ? txctl_value : 0);
- if (b43_loctl_is_calibrated(control)) {
- if ((abs(i) > 16) || (abs(q) > 16))
- goto error;
- } else {
- if (control->used)
- goto error;
- if (dev->phy.lo_control->rebuild) {
- control->i = 0;
- control->q = 0;
- if ((i != B43_LOCTL_POISON) ||
- (q != B43_LOCTL_POISON))
- goto error;
- }
+ max_rx_gain = rfatt->att * 2;
+ max_rx_gain += bbatt->att / 2;
+ if (rfatt->with_padmix)
+ max_rx_gain -= pad_mix_gain;
+ if (has_loopback_gain(phy))
+ max_rx_gain += phy->max_lb_gain;
+ lo_measure_gain_values(dev, max_rx_gain,
+ has_loopback_gain(phy));
+
+ b43_phy_set_baseband_attenuation(dev, bbatt->att);
+ lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain);
+
+ lo_measure_restore(dev, &saved_regs);
+ b43_mac_enable(dev);
+
+ if (b43_debug(dev, B43_DBG_LO)) {
+ b43dbg(dev->wl, "LO: Calibrated for BB(%u), RF(%u,%u) "
+ "=> I=%d Q=%d\n",
+ bbatt->att, rfatt->att, rfatt->with_padmix,
+ loctl.i, loctl.q);
}
- if (is_initializing && control->used)
- goto error;
-
- return;
-error:
- b43err(dev->wl, "LO control pair validation failed "
- "(I: %d, Q: %d, used %u, calib: %u, initing: %d)\n",
- i, q, control->used,
- b43_loctl_is_calibrated(control),
- is_initializing);
-}
-static void validate_all_loctls(struct b43_wldev *dev)
-{
- b43_call_for_each_loctl(dev, do_validate_loctl);
-}
-
-static void do_reset_calib(struct b43_wldev *dev, struct b43_loctl *control)
-{
- if (dev->phy.lo_control->rebuild ||
- control->used) {
- b43_loctl_set_calibrated(control, 0);
- control->i = B43_LOCTL_POISON;
- control->q = B43_LOCTL_POISON;
+ cal = kmalloc(sizeof(*cal), GFP_KERNEL);
+ if (!cal) {
+ b43warn(dev->wl, "LO calib: out of memory\n");
+ return NULL;
}
+ memcpy(&cal->bbatt, bbatt, sizeof(*bbatt));
+ memcpy(&cal->rfatt, rfatt, sizeof(*rfatt));
+ memcpy(&cal->ctl, &loctl, sizeof(loctl));
+ cal->calib_time = jiffies;
+ INIT_LIST_HEAD(&cal->list);
+
+ return cal;
}
-static void reset_all_loctl_calibration_states(struct b43_wldev *dev)
+/* Get a calibrated LO setting for the given attenuation values.
+ * Might return a NULL pointer under OOM! */
+static
+struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
- b43_call_for_each_loctl(dev, do_reset_calib);
+ struct b43_txpower_lo_control *lo = dev->phy.lo_control;
+ struct b43_lo_calib *c;
+
+ c = b43_find_lo_calib(lo, bbatt, rfatt);
+ if (c)
+ return c;
+ /* Not in the list of calibrated LO settings.
+ * Calibrate it now. */
+ c = b43_calibrate_lo_setting(dev, bbatt, rfatt);
+ if (!c)
+ return NULL;
+ list_add(&c->list, &lo->calib_list);
+
+ return c;
}
-#else /* B43_DEBUG */
-static inline void validate_all_loctls(struct b43_wldev *dev) { }
-static inline void reset_all_loctl_calibration_states(struct b43_wldev *dev) { }
-#endif /* B43_DEBUG */
-
-void b43_lo_g_measure(struct b43_wldev *dev)
+void b43_gphy_dc_lt_init(struct b43_wldev *dev, bool update_all)
{
struct b43_phy *phy = &dev->phy;
- struct lo_g_saved_values uninitialized_var(sav);
-
- B43_WARN_ON((phy->type != B43_PHYTYPE_B) &&
- (phy->type != B43_PHYTYPE_G));
-
- sav.old_channel = phy->channel;
- lo_measure_setup(dev, &sav);
- reset_all_loctl_calibration_states(dev);
- lo_measure(dev);
- lo_measure_restore(dev, &sav);
-
- validate_all_loctls(dev);
+ struct b43_txpower_lo_control *lo = phy->lo_control;
+ int i;
+ int rf_offset, bb_offset;
+ const struct b43_rfatt *rfatt;
+ const struct b43_bbatt *bbatt;
+ u64 power_vector;
+ bool table_changed = 0;
- phy->lo_control->lo_measured = 1;
- phy->lo_control->rebuild = 0;
-}
+ BUILD_BUG_ON(B43_DC_LT_SIZE != 32);
+ B43_WARN_ON(lo->rfatt_list.len * lo->bbatt_list.len > 64);
-#if B43_DEBUG
-static void validate_loctl_calibration(struct b43_wldev *dev,
- struct b43_loctl *loctl,
- struct b43_rfatt *rfatt,
- struct b43_bbatt *bbatt)
-{
- if (b43_loctl_is_calibrated(loctl))
- return;
- if (!dev->phy.lo_control->lo_measured) {
- /* On init we set the attenuation values before we
- * calibrated the LO. I guess that's OK. */
- return;
+ power_vector = lo->power_vector;
+ if (!update_all && !power_vector)
+ return; /* Nothing to do. */
+
+ /* Suspend the MAC now to avoid continuous suspend/enable
+ * cycles in the loop. */
+ b43_mac_suspend(dev);
+
+ for (i = 0; i < B43_DC_LT_SIZE * 2; i++) {
+ struct b43_lo_calib *cal;
+ int idx;
+ u16 val;
+
+ if (!update_all && !(power_vector & (((u64)1ULL) << i)))
+ continue;
+ /* Update the table entry for this power_vector bit.
+ * The table rows are RFatt entries and columns are BBatt. */
+ bb_offset = i / lo->rfatt_list.len;
+ rf_offset = i % lo->rfatt_list.len;
+ bbatt = &(lo->bbatt_list.list[bb_offset]);
+ rfatt = &(lo->rfatt_list.list[rf_offset]);
+
+ cal = b43_calibrate_lo_setting(dev, bbatt, rfatt);
+ if (!cal) {
+ b43warn(dev->wl, "LO: Could not "
+ "calibrate DC table entry\n");
+ continue;
+ }
+ /*FIXME: Is Q really in the low nibble? */
+ val = (u8)(cal->ctl.q);
+ val |= ((u8)(cal->ctl.i)) << 4;
+ kfree(cal);
+
+ /* Get the index into the hardware DC LT. */
+ idx = i / 2;
+ /* Change the table in memory. */
+ if (i % 2) {
+ /* Change the high byte. */
+ lo->dc_lt[idx] = (lo->dc_lt[idx] & 0x00FF)
+ | ((val & 0x00FF) << 8);
+ } else {
+ /* Change the low byte. */
+ lo->dc_lt[idx] = (lo->dc_lt[idx] & 0xFF00)
+ | (val & 0x00FF);
+ }
+ table_changed = 1;
}
- b43err(dev->wl, "Adjusting Local Oscillator to an uncalibrated "
- "control pair: rfatt=%u,%spadmix bbatt=%u\n",
- rfatt->att,
- (rfatt->with_padmix) ? "" : "no-",
- bbatt->att);
-}
-#else
-static inline void validate_loctl_calibration(struct b43_wldev *dev,
- struct b43_loctl *loctl,
- struct b43_rfatt *rfatt,
- struct b43_bbatt *bbatt)
-{
+ if (table_changed) {
+ /* The table changed in memory. Update the hardware table. */
+ for (i = 0; i < B43_DC_LT_SIZE; i++)
+ b43_phy_write(dev, 0x3A0 + i, lo->dc_lt[i]);
+ }
+ b43_mac_enable(dev);
}
-#endif
-static inline void fixup_rfatt_for_txcontrol(struct b43_rfatt *rf,
- u8 tx_control)
+/* Fixup the RF attenuation value for the case where we are
+ * using the PAD mixer. */
+static inline void b43_lo_fixup_rfatt(struct b43_rfatt *rf)
{
- if (tx_control & B43_TXCTL_TXMIX) {
- if (rf->att < 5)
- rf->att = 4;
- }
+ if (!rf->with_padmix)
+ return;
+ if ((rf->att != 1) && (rf->att != 2) && (rf->att != 3))
+ rf->att = 4;
}
void b43_lo_g_adjust(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
+ struct b43_lo_calib *cal;
struct b43_rfatt rf;
- struct b43_loctl *loctl;
memcpy(&rf, &phy->rfatt, sizeof(rf));
- fixup_rfatt_for_txcontrol(&rf, phy->tx_control);
+ b43_lo_fixup_rfatt(&rf);
- loctl = b43_get_lo_g_ctl(dev, &rf, &phy->bbatt);
- validate_loctl_calibration(dev, loctl, &rf, &phy->bbatt);
- b43_lo_write(dev, loctl);
+ cal = b43_get_calib_lo_settings(dev, &phy->bbatt, &rf);
+ if (!cal)
+ return;
+ b43_lo_write(dev, &cal->ctl);
}
void b43_lo_g_adjust_to(struct b43_wldev *dev,
@@ -1223,39 +935,102 @@ void b43_lo_g_adjust_to(struct b43_wldev *dev,
{
struct b43_rfatt rf;
struct b43_bbatt bb;
- struct b43_loctl *loctl;
+ struct b43_lo_calib *cal;
memset(&rf, 0, sizeof(rf));
memset(&bb, 0, sizeof(bb));
rf.att = rfatt;
bb.att = bbatt;
- fixup_rfatt_for_txcontrol(&rf, tx_control);
- loctl = b43_get_lo_g_ctl(dev, &rf, &bb);
- validate_loctl_calibration(dev, loctl, &rf, &bb);
- b43_lo_write(dev, loctl);
+ b43_lo_fixup_rfatt(&rf);
+ cal = b43_get_calib_lo_settings(dev, &bb, &rf);
+ if (!cal)
+ return;
+ b43_lo_write(dev, &cal->ctl);
}
-static void do_mark_unused(struct b43_wldev *dev, struct b43_loctl *control)
+/* Periodic LO maintanance work */
+void b43_lo_g_maintanance_work(struct b43_wldev *dev)
{
- control->used = 0;
+ struct b43_phy *phy = &dev->phy;
+ struct b43_txpower_lo_control *lo = phy->lo_control;
+ unsigned long now;
+ unsigned long expire;
+ struct b43_lo_calib *cal, *tmp;
+ bool current_item_expired = 0;
+ bool hwpctl;
+
+ if (!lo)
+ return;
+ now = jiffies;
+ hwpctl = b43_has_hardware_pctl(phy);
+
+ if (hwpctl) {
+ /* Read the power vector and update it, if needed. */
+ expire = now - B43_LO_PWRVEC_EXPIRE;
+ if (time_before(lo->pwr_vec_read_time, expire)) {
+ lo_read_power_vector(dev);
+ b43_gphy_dc_lt_init(dev, 0);
+ }
+ //FIXME Recalc the whole DC table from time to time?
+ }
+
+ if (hwpctl)
+ return;
+ /* Search for expired LO settings. Remove them.
+ * Recalibrate the current setting, if expired. */
+ expire = now - B43_LO_CALIB_EXPIRE;
+ list_for_each_entry_safe(cal, tmp, &lo->calib_list, list) {
+ if (!time_before(cal->calib_time, expire))
+ continue;
+ /* This item expired. */
+ if (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) &&
+ b43_compare_rfatt(&cal->rfatt, &phy->rfatt)) {
+ B43_WARN_ON(current_item_expired);
+ current_item_expired = 1;
+ }
+ if (b43_debug(dev, B43_DBG_LO)) {
+ b43dbg(dev->wl, "LO: Item BB(%u), RF(%u,%u), "
+ "I=%d, Q=%d expired\n",
+ cal->bbatt.att, cal->rfatt.att,
+ cal->rfatt.with_padmix,
+ cal->ctl.i, cal->ctl.q);
+ }
+ list_del(&cal->list);
+ kfree(cal);
+ }
+ if (current_item_expired || unlikely(list_empty(&lo->calib_list))) {
+ /* Recalibrate currently used LO setting. */
+ if (b43_debug(dev, B43_DBG_LO))
+ b43dbg(dev->wl, "LO: Recalibrating current LO setting\n");
+ cal = b43_calibrate_lo_setting(dev, &phy->bbatt, &phy->rfatt);
+ if (cal) {
+ list_add(&cal->list, &lo->calib_list);
+ b43_lo_write(dev, &cal->ctl);
+ } else
+ b43warn(dev->wl, "Failed to recalibrate current LO setting\n");
+ }
}
-void b43_lo_g_ctl_mark_all_unused(struct b43_wldev *dev)
+void b43_lo_g_cleanup(struct b43_wldev *dev)
{
- struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
+ struct b43_txpower_lo_control *lo = dev->phy.lo_control;
+ struct b43_lo_calib *cal, *tmp;
- b43_call_for_each_loctl(dev, do_mark_unused);
- lo->rebuild = 1;
+ if (!lo)
+ return;
+ list_for_each_entry_safe(cal, tmp, &lo->calib_list, list) {
+ list_del(&cal->list);
+ kfree(cal);
+ }
}
-void b43_lo_g_ctl_mark_cur_used(struct b43_wldev *dev)
+/* LO Initialization */
+void b43_lo_g_init(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
- struct b43_rfatt rf;
- memcpy(&rf, &phy->rfatt, sizeof(rf));
- fixup_rfatt_for_txcontrol(&rf, phy->tx_control);
-
- b43_get_lo_g_ctl(dev, &rf, &phy->bbatt)->used = 1;
+ if (b43_has_hardware_pctl(phy)) {
+ lo_read_power_vector(dev);
+ b43_gphy_dc_lt_init(dev, 1);
+ }
}
diff --git a/drivers/net/wireless/b43/lo.h b/drivers/net/wireless/b43/lo.h
index 455615d1f8c..1da321cabc1 100644
--- a/drivers/net/wireless/b43/lo.h
+++ b/drivers/net/wireless/b43/lo.h
@@ -10,82 +10,63 @@ struct b43_loctl {
/* Control values. */
s8 i;
s8 q;
- /* "Used by hardware" flag. */
- bool used;
-#ifdef CONFIG_B43_DEBUG
- /* Is this lo-control-array entry calibrated? */
- bool calibrated;
-#endif
};
-
/* Debugging: Poison value for i and q values. */
#define B43_LOCTL_POISON 111
-/* loctl->calibrated debugging mechanism */
-#ifdef CONFIG_B43_DEBUG
-static inline void b43_loctl_set_calibrated(struct b43_loctl *loctl,
- bool calibrated)
-{
- loctl->calibrated = calibrated;
-}
-static inline bool b43_loctl_is_calibrated(struct b43_loctl *loctl)
-{
- return loctl->calibrated;
-}
-#else
-static inline void b43_loctl_set_calibrated(struct b43_loctl *loctl,
- bool calibrated)
-{
-}
-static inline bool b43_loctl_is_calibrated(struct b43_loctl *loctl)
-{
- return 1;
-}
-#endif
-
-/* TX Power LO Control Array.
- * Value-pairs to adjust the LocalOscillator are stored
- * in this structure.
- * There are two different set of values. One for "Flag is Set"
- * and one for "Flag is Unset".
- * By "Flag" the flag in struct b43_rfatt is meant.
- * The Value arrays are two-dimensional. The first index
- * is the baseband attenuation and the second index
- * is the radio attenuation.
- * Use b43_get_lo_g_ctl() to retrieve a value from the lists.
- */
+/* This struct holds calibrated LO settings for a set of
+ * Baseband and RF attenuation settings. */
+struct b43_lo_calib {
+ /* The set of attenuation values this set of LO
+ * control values is calibrated for. */
+ struct b43_bbatt bbatt;
+ struct b43_rfatt rfatt;
+ /* The set of control values for the LO. */
+ struct b43_loctl ctl;
+ /* The time when these settings were calibrated (in jiffies) */
+ unsigned long calib_time;
+ /* List. */
+ struct list_head list;
+};
+
+/* Size of the DC Lookup Table in 16bit words. */
+#define B43_DC_LT_SIZE 32
+
+/* Local Oscillator calibration information */
struct b43_txpower_lo_control {
-#define B43_NR_BB 12
-#define B43_NR_RF 16
- /* LO Control values, with PAD Mixer */
- struct b43_loctl with_padmix[B43_NR_BB][B43_NR_RF];
- /* LO Control values, without PAD Mixer */
- struct b43_loctl no_padmix[B43_NR_BB][B43_NR_RF];
-
- /* Flag to indicate a complete rebuild of the two tables above
- * to the LO measuring code. */
- bool rebuild;
-
- /* Lists of valid RF and BB attenuation values for this device. */
+ /* Lists of RF and BB attenuation values for this device.
+ * Used for building hardware power control tables. */
struct b43_rfatt_list rfatt_list;
struct b43_bbatt_list bbatt_list;
+ /* The DC Lookup Table is cached in memory here.
+ * Note that this is only used for Hardware Power Control. */
+ u16 dc_lt[B43_DC_LT_SIZE];
+
+ /* List of calibrated control values (struct b43_lo_calib). */
+ struct list_head calib_list;
+ /* Last time the power vector was read (jiffies). */
+ unsigned long pwr_vec_read_time;
+ /* Last time the txctl values were measured (jiffies). */
+ unsigned long txctl_measured_time;
+
/* Current TX Bias value */
u8 tx_bias;
/* Current TX Magnification Value (if used by the device) */
u8 tx_magn;
- /* GPHY LO is measured. */
- bool lo_measured;
-
/* Saved device PowerVector */
u64 power_vector;
};
-/* Measure the BPHY Local Oscillator. */
-void b43_lo_b_measure(struct b43_wldev *dev);
-/* Measure the BPHY/GPHY Local Oscillator. */
-void b43_lo_g_measure(struct b43_wldev *dev);
+/* Calibration expire timeouts.
+ * Timeouts must be multiple of 15 seconds. To make sure
+ * the item really expired when the 15 second timer hits, we
+ * subtract two additional seconds from the timeout. */
+#define B43_LO_CALIB_EXPIRE (HZ * (30 - 2))
+#define B43_LO_PWRVEC_EXPIRE (HZ * (30 - 2))
+#define B43_LO_TXCTL_EXPIRE (HZ * (180 - 4))
+
/* Adjust the Local Oscillator to the saved attenuation
* and txctl values.
@@ -95,18 +76,10 @@ void b43_lo_g_adjust(struct b43_wldev *dev);
void b43_lo_g_adjust_to(struct b43_wldev *dev,
u16 rfatt, u16 bbatt, u16 tx_control);
-/* Mark all possible b43_lo_g_ctl as "unused" */
-void b43_lo_g_ctl_mark_all_unused(struct b43_wldev *dev);
-/* Mark the b43_lo_g_ctl corresponding to the current
- * attenuation values as used.
- */
-void b43_lo_g_ctl_mark_cur_used(struct b43_wldev *dev);
+void b43_gphy_dc_lt_init(struct b43_wldev *dev, bool update_all);
-/* Get a reference to a LO Control value pair in the
- * TX Power LO Control Array.
- */
-struct b43_loctl *b43_get_lo_g_ctl(struct b43_wldev *dev,
- const struct b43_rfatt *rfatt,
- const struct b43_bbatt *bbatt);
+void b43_lo_g_maintanance_work(struct b43_wldev *dev);
+void b43_lo_g_cleanup(struct b43_wldev *dev);
+void b43_lo_g_init(struct b43_wldev *dev);
#endif /* B43_LO_H_ */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a7082779308..e78319aa47c 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
}
-u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
+u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{
- struct b43_wl *wl = dev->wl;
- unsigned long flags;
u32 ret;
- spin_lock_irqsave(&wl->shm_lock, flags);
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, offset);
ret = b43_read32(dev, B43_MMIO_SHM_DATA);
out:
- spin_unlock_irqrestore(&wl->shm_lock, flags);
-
return ret;
}
-u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
+u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
- u16 ret;
+ u32 ret;
spin_lock_irqsave(&wl->shm_lock, flags);
+ ret = __b43_shm_read32(dev, routing, offset);
+ spin_unlock_irqrestore(&wl->shm_lock, flags);
+
+ return ret;
+}
+
+u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
+{
+ u16 ret;
+
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
b43_shm_control_word(dev, routing, offset);
ret = b43_read16(dev, B43_MMIO_SHM_DATA);
out:
- spin_unlock_irqrestore(&wl->shm_lock, flags);
-
return ret;
}
-void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
+u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
+ u16 ret;
spin_lock_irqsave(&wl->shm_lock, flags);
+ ret = __b43_shm_read16(dev, routing, offset);
+ spin_unlock_irqrestore(&wl->shm_lock, flags);
+
+ return ret;
+}
+
+void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
+{
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
(value >> 16) & 0xffff);
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
- goto out;
+ return;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
b43_write32(dev, B43_MMIO_SHM_DATA, value);
-out:
- spin_unlock_irqrestore(&wl->shm_lock, flags);
}
-void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
+void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
{
struct b43_wl *wl = dev->wl;
unsigned long flags;
spin_lock_irqsave(&wl->shm_lock, flags);
+ __b43_shm_write32(dev, routing, offset, value);
+ spin_unlock_irqrestore(&wl->shm_lock, flags);
+}
+
+void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
+{
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
/* Unaligned access */
b43_shm_control_word(dev, routing, offset >> 2);
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
- goto out;
+ return;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
b43_write16(dev, B43_MMIO_SHM_DATA, value);
-out:
+}
+
+void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
+{
+ struct b43_wl *wl = dev->wl;
+ unsigned long flags;
+
+ spin_lock_irqsave(&wl->shm_lock, flags);
+ __b43_shm_write16(dev, routing, offset, value);
spin_unlock_irqrestore(&wl->shm_lock, flags);
}
@@ -1187,10 +1211,10 @@ static void handle_irq_noise(struct b43_wldev *dev)
/* Get the noise samples. */
B43_WARN_ON(dev->noisecalc.nr_samples >= 8);
i = dev->noisecalc.nr_samples;
- noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
- noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
- noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
- noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]];
dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]];
dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]];
@@ -1372,18 +1396,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
unsigned int rate;
u16 ctl;
int antenna;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
len = min((size_t) dev->wl->current_beacon->len,
0x200 - sizeof(struct b43_plcp_hdr6));
- rate = dev->wl->beacon_txctl.tx_rate->hw_value;
+ rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
b43_write_template_common(dev, (const u8 *)bcn,
len, ram_offset, shm_size_offset, rate);
/* Write the PHY TX control parameters. */
- antenna = b43_antenna_from_ieee80211(dev,
- dev->wl->beacon_txctl.antenna_sel_tx);
+ antenna = b43_antenna_from_ieee80211(dev, info->antenna_sel_tx);
antenna = b43_antenna_to_phyctl(antenna);
ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
/* We can't send beacons with short preamble. Would get PHY errors. */
@@ -1434,11 +1458,17 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
i += ie_len + 2;
}
if (!tim_found) {
- b43warn(dev->wl, "Did not find a valid TIM IE in "
- "the beacon template packet. AP or IBSS operation "
- "may be broken.\n");
- } else
- b43dbg(dev->wl, "Updated beacon template\n");
+ /*
+ * If ucode wants to modify TIM do it behind the beacon, this
+ * will happen, for example, when doing mesh networking.
+ */
+ b43_shm_write16(dev, B43_SHM_SHARED,
+ B43_SHM_SH_TIMBPOS,
+ len + sizeof(struct b43_plcp_hdr6));
+ b43_shm_write16(dev, B43_SHM_SHARED,
+ B43_SHM_SH_DTIMPER, 0);
+ }
+ b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset);
}
static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
@@ -1577,7 +1607,8 @@ static void handle_irq_beacon(struct b43_wldev *dev)
struct b43_wl *wl = dev->wl;
u32 cmd, beacon0_valid, beacon1_valid;
- if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
+ if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP) &&
+ !b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT))
return;
/* This is the bottom half of the asynchronous beacon update. */
@@ -1644,19 +1675,27 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
/* Asynchronously update the packet templates in template RAM.
* Locking: Requires wl->irq_lock to be locked. */
-static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon,
- const struct ieee80211_tx_control *txctl)
+static void b43_update_templates(struct b43_wl *wl)
{
+ struct sk_buff *beacon;
+
/* This is the top half of the ansynchronous beacon update.
* The bottom half is the beacon IRQ.
* Beacon update must be asynchronous to avoid sending an
* invalid beacon. This can happen for example, if the firmware
* transmits a beacon while we are updating it. */
+ /* We could modify the existing beacon and set the aid bit in
+ * the TIM field, but that would probably require resizing and
+ * moving of data within the beacon template.
+ * Simply request a new beacon and let mac80211 do the hard work. */
+ beacon = ieee80211_beacon_get(wl->hw, wl->vif);
+ if (unlikely(!beacon))
+ return;
+
if (wl->current_beacon)
dev_kfree_skb_any(wl->current_beacon);
wl->current_beacon = beacon;
- memcpy(&wl->beacon_txctl, txctl, sizeof(wl->beacon_txctl));
wl->beacon0_uploaded = 0;
wl->beacon1_uploaded = 0;
queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
@@ -1695,9 +1734,100 @@ static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
}
+static void b43_handle_firmware_panic(struct b43_wldev *dev)
+{
+ u16 reason;
+
+ /* Read the register that contains the reason code for the panic. */
+ reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_FWPANIC_REASON_REG);
+ b43err(dev->wl, "Whoopsy, firmware panic! Reason: %u\n", reason);
+
+ switch (reason) {
+ default:
+ b43dbg(dev->wl, "The panic reason is unknown.\n");
+ /* fallthrough */
+ case B43_FWPANIC_DIE:
+ /* Do not restart the controller or firmware.
+ * The device is nonfunctional from now on.
+ * Restarting would result in this panic to trigger again,
+ * so we avoid that recursion. */
+ break;
+ case B43_FWPANIC_RESTART:
+ b43_controller_restart(dev, "Microcode panic");
+ break;
+ }
+}
+
static void handle_irq_ucode_debug(struct b43_wldev *dev)
{
- //TODO
+ unsigned int i, cnt;
+ u16 reason, marker_id, marker_line;
+ __le16 *buf;
+
+ /* The proprietary firmware doesn't have this IRQ. */
+ if (!dev->fw.opensource)
+ return;
+
+ /* Read the register that contains the reason code for this IRQ. */
+ reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_DEBUGIRQ_REASON_REG);
+
+ switch (reason) {
+ case B43_DEBUGIRQ_PANIC:
+ b43_handle_firmware_panic(dev);
+ break;
+ case B43_DEBUGIRQ_DUMP_SHM:
+ if (!B43_DEBUG)
+ break; /* Only with driver debugging enabled. */
+ buf = kmalloc(4096, GFP_ATOMIC);
+ if (!buf) {
+ b43dbg(dev->wl, "SHM-dump: Failed to allocate memory\n");
+ goto out;
+ }
+ for (i = 0; i < 4096; i += 2) {
+ u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, i);
+ buf[i / 2] = cpu_to_le16(tmp);
+ }
+ b43info(dev->wl, "Shared memory dump:\n");
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET,
+ 16, 2, buf, 4096, 1);
+ kfree(buf);
+ break;
+ case B43_DEBUGIRQ_DUMP_REGS:
+ if (!B43_DEBUG)
+ break; /* Only with driver debugging enabled. */
+ b43info(dev->wl, "Microcode register dump:\n");
+ for (i = 0, cnt = 0; i < 64; i++) {
+ u16 tmp = b43_shm_read16(dev, B43_SHM_SCRATCH, i);
+ if (cnt == 0)
+ printk(KERN_INFO);
+ printk("r%02u: 0x%04X ", i, tmp);
+ cnt++;
+ if (cnt == 6) {
+ printk("\n");
+ cnt = 0;
+ }
+ }
+ printk("\n");
+ break;
+ case B43_DEBUGIRQ_MARKER:
+ if (!B43_DEBUG)
+ break; /* Only with driver debugging enabled. */
+ marker_id = b43_shm_read16(dev, B43_SHM_SCRATCH,
+ B43_MARKER_ID_REG);
+ marker_line = b43_shm_read16(dev, B43_SHM_SCRATCH,
+ B43_MARKER_LINE_REG);
+ b43info(dev->wl, "The firmware just executed the MARKER(%u) "
+ "at line number %u\n",
+ marker_id, marker_line);
+ break;
+ default:
+ b43dbg(dev->wl, "Debug-IRQ triggered for unknown reason: %u\n",
+ reason);
+ }
+out:
+ /* Acknowledge the debug-IRQ, so the firmware can continue. */
+ b43_shm_write16(dev, B43_SHM_SCRATCH,
+ B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
}
/* Interrupt handler bottom-half */
@@ -1884,7 +2014,8 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
static int do_request_fw(struct b43_wldev *dev,
const char *name,
- struct b43_firmware_file *fw)
+ struct b43_firmware_file *fw,
+ bool silent)
{
char path[sizeof(modparam_fwpostfix) + 32];
const struct firmware *blob;
@@ -1908,9 +2039,15 @@ static int do_request_fw(struct b43_wldev *dev,
"b43%s/%s.fw",
modparam_fwpostfix, name);
err = request_firmware(&blob, path, dev->dev->dev);
- if (err) {
- b43err(dev->wl, "Firmware file \"%s\" not found "
- "or load failed.\n", path);
+ if (err == -ENOENT) {
+ if (!silent) {
+ b43err(dev->wl, "Firmware file \"%s\" not found\n",
+ path);
+ }
+ return err;
+ } else if (err) {
+ b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n",
+ path, err);
return err;
}
if (blob->size < sizeof(struct b43_fw_header))
@@ -1961,7 +2098,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
filename = "ucode13";
else
goto err_no_ucode;
- err = do_request_fw(dev, filename, &fw->ucode);
+ err = do_request_fw(dev, filename, &fw->ucode, 0);
if (err)
goto err_load;
@@ -1972,8 +2109,13 @@ static int b43_request_firmware(struct b43_wldev *dev)
filename = NULL;
else
goto err_no_pcm;
- err = do_request_fw(dev, filename, &fw->pcm);
- if (err)
+ fw->pcm_request_failed = 0;
+ err = do_request_fw(dev, filename, &fw->pcm, 1);
+ if (err == -ENOENT) {
+ /* We did not find a PCM file? Not fatal, but
+ * core rev <= 10 must do without hwcrypto then. */
+ fw->pcm_request_failed = 1;
+ } else if (err)
goto err_load;
/* Get initvals */
@@ -1991,7 +2133,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
if ((rev >= 5) && (rev <= 10))
filename = "b0g0initvals5";
else if (rev >= 13)
- filename = "lp0initvals13";
+ filename = "b0g0initvals13";
else
goto err_no_initvals;
break;
@@ -2004,7 +2146,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals);
+ err = do_request_fw(dev, filename, &fw->initvals, 0);
if (err)
goto err_load;
@@ -2038,7 +2180,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals_band);
+ err = do_request_fw(dev, filename, &fw->initvals_band, 0);
if (err)
goto err_load;
@@ -2155,14 +2297,28 @@ static int b43_upload_microcode(struct b43_wldev *dev)
err = -EOPNOTSUPP;
goto error;
}
- b43info(dev->wl, "Loading firmware version %u.%u "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
- fwrev, fwpatch,
- (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
- (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
-
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
+ dev->fw.opensource = (fwdate == 0xFFFF);
+
+ if (dev->fw.opensource) {
+ /* Patchlevel info is encoded in the "time" field. */
+ dev->fw.patch = fwtime;
+ b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n",
+ dev->fw.rev, dev->fw.patch,
+ dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : "");
+ } else {
+ b43info(dev->wl, "Loading firmware version %u.%u "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+ fwrev, fwpatch,
+ (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
+ (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
+ if (dev->fw.pcm_request_failed) {
+ b43warn(dev->wl, "No \"pcm5.fw\" firmware file found. "
+ "Hardware accelerated cryptography is disabled.\n");
+ b43_print_fw_helptext(dev->wl, 0);
+ }
+ }
if (b43_is_old_txhdr_format(dev)) {
b43warn(dev->wl, "You are using an old firmware image. "
@@ -2339,8 +2495,21 @@ static void b43_gpio_cleanup(struct b43_wldev *dev)
}
/* http://bcm-specs.sipsolutions.net/EnableMac */
-static void b43_mac_enable(struct b43_wldev *dev)
-{
+void b43_mac_enable(struct b43_wldev *dev)
+{
+ if (b43_debug(dev, B43_DBG_FIRMWARE)) {
+ u16 fwstate;
+
+ fwstate = b43_shm_read16(dev, B43_SHM_SHARED,
+ B43_SHM_SH_UCODESTAT);
+ if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) &&
+ (fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) {
+ b43err(dev->wl, "b43_mac_enable(): The firmware "
+ "should be suspended, but current state is %u\n",
+ fwstate);
+ }
+ }
+
dev->mac_suspended--;
B43_WARN_ON(dev->mac_suspended < 0);
if (dev->mac_suspended == 0) {
@@ -2353,16 +2522,11 @@ static void b43_mac_enable(struct b43_wldev *dev)
b43_read32(dev, B43_MMIO_MACCTL);
b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
b43_power_saving_ctl_bits(dev, 0);
-
- /* Re-enable IRQs. */
- spin_lock_irq(&dev->wl->irq_lock);
- b43_interrupt_enable(dev, dev->irq_savedstate);
- spin_unlock_irq(&dev->wl->irq_lock);
}
}
/* http://bcm-specs.sipsolutions.net/SuspendMAC */
-static void b43_mac_suspend(struct b43_wldev *dev)
+void b43_mac_suspend(struct b43_wldev *dev)
{
int i;
u32 tmp;
@@ -2371,14 +2535,6 @@ static void b43_mac_suspend(struct b43_wldev *dev)
B43_WARN_ON(dev->mac_suspended < 0);
if (dev->mac_suspended == 0) {
- /* Mask IRQs before suspending MAC. Otherwise
- * the MAC stays busy and won't suspend. */
- spin_lock_irq(&dev->wl->irq_lock);
- tmp = b43_interrupt_disable(dev, B43_IRQ_ALL);
- spin_unlock_irq(&dev->wl->irq_lock);
- b43_synchronize_irq(dev);
- dev->irq_savedstate = tmp;
-
b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
b43_write32(dev, B43_MMIO_MACCTL,
b43_read32(dev, B43_MMIO_MACCTL)
@@ -2420,7 +2576,8 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
ctl &= ~B43_MACCTL_BEACPROMISC;
ctl |= B43_MACCTL_INFRA;
- if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
+ if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
+ b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT))
ctl |= B43_MACCTL_AP;
else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS))
ctl &= ~B43_MACCTL_INFRA;
@@ -2534,6 +2691,7 @@ static void b43_chip_exit(struct b43_wldev *dev)
{
b43_radio_turn_off(dev, 1);
b43_gpio_cleanup(dev);
+ b43_lo_g_cleanup(dev);
/* firmware is released later */
}
@@ -2640,28 +2798,12 @@ err_gpio_clean:
return err;
}
-static void b43_periodic_every120sec(struct b43_wldev *dev)
-{
- struct b43_phy *phy = &dev->phy;
-
- if (phy->type != B43_PHYTYPE_G || phy->rev < 2)
- return;
-
- b43_mac_suspend(dev);
- b43_lo_g_measure(dev);
- b43_mac_enable(dev);
- if (b43_has_hardware_pctl(phy))
- b43_lo_g_ctl_mark_all_unused(dev);
-}
-
static void b43_periodic_every60sec(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
if (phy->type != B43_PHYTYPE_G)
return;
- if (!b43_has_hardware_pctl(phy))
- b43_lo_g_ctl_mark_all_unused(dev);
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
b43_mac_suspend(dev);
b43_calc_nrssi_slope(dev);
@@ -2688,6 +2830,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev)
static void b43_periodic_every15sec(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
+ u16 wdr;
+
+ if (dev->fw.opensource) {
+ /* Check if the firmware is still alive.
+ * It will reset the watchdog counter to 0 in its idle loop. */
+ wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG);
+ if (unlikely(wdr)) {
+ b43err(dev->wl, "Firmware watchdog: The firmware died!\n");
+ b43_controller_restart(dev, "Firmware watchdog");
+ return;
+ } else {
+ b43_shm_write16(dev, B43_SHM_SCRATCH,
+ B43_WATCHDOG_REG, 1);
+ }
+ }
if (phy->type == B43_PHYTYPE_G) {
//TODO: update_aci_moving_average
@@ -2713,6 +2870,7 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
}
}
b43_phy_xmitpower(dev); //FIXME: unless scanning?
+ b43_lo_g_maintanance_work(dev);
//TODO for APHY (temperature?)
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
@@ -2724,8 +2882,6 @@ static void do_periodic_work(struct b43_wldev *dev)
unsigned int state;
state = dev->periodic_state;
- if (state % 8 == 0)
- b43_periodic_every120sec(dev);
if (state % 4 == 0)
b43_periodic_every60sec(dev);
if (state % 2 == 0)
@@ -2873,8 +3029,7 @@ static int b43_rng_init(struct b43_wl *wl)
}
static int b43_op_tx(struct ieee80211_hw *hw,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
@@ -2895,9 +3050,9 @@ static int b43_op_tx(struct ieee80211_hw *hw,
err = -ENODEV;
if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
if (b43_using_pio_transfers(dev))
- err = b43_pio_tx(dev, skb, ctl);
+ err = b43_pio_tx(dev, skb);
else
- err = b43_dma_tx(dev, skb, ctl);
+ err = b43_dma_tx(dev, skb);
}
read_unlock_irqrestore(&wl->tx_lock, flags);
@@ -2918,53 +3073,20 @@ static void b43_qos_params_upload(struct b43_wldev *dev,
u16 shm_offset)
{
u16 params[B43_NR_QOSPARAMS];
- int cw_min, cw_max, aifs, bslots, tmp;
+ int bslots, tmp;
unsigned int i;
- const u16 aCWmin = 0x0001;
- const u16 aCWmax = 0x03FF;
-
- /* Calculate the default values for the parameters, if needed. */
- switch (shm_offset) {
- case B43_QOS_VOICE:
- aifs = (p->aifs == -1) ? 2 : p->aifs;
- cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 4 - 1) : p->cw_min;
- cw_max = (p->cw_max == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_max;
- break;
- case B43_QOS_VIDEO:
- aifs = (p->aifs == -1) ? 2 : p->aifs;
- cw_min = (p->cw_min == 0) ? ((aCWmin + 1) / 2 - 1) : p->cw_min;
- cw_max = (p->cw_max == 0) ? aCWmin : p->cw_max;
- break;
- case B43_QOS_BESTEFFORT:
- aifs = (p->aifs == -1) ? 3 : p->aifs;
- cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
- cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
- break;
- case B43_QOS_BACKGROUND:
- aifs = (p->aifs == -1) ? 7 : p->aifs;
- cw_min = (p->cw_min == 0) ? aCWmin : p->cw_min;
- cw_max = (p->cw_max == 0) ? aCWmax : p->cw_max;
- break;
- default:
- B43_WARN_ON(1);
- return;
- }
- if (cw_min <= 0)
- cw_min = aCWmin;
- if (cw_max <= 0)
- cw_max = aCWmin;
- bslots = b43_read16(dev, B43_MMIO_RNG) % cw_min;
+ bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min;
memset(&params, 0, sizeof(params));
params[B43_QOSPARAM_TXOP] = p->txop * 32;
- params[B43_QOSPARAM_CWMIN] = cw_min;
- params[B43_QOSPARAM_CWMAX] = cw_max;
- params[B43_QOSPARAM_CWCUR] = cw_min;
- params[B43_QOSPARAM_AIFS] = aifs;
+ params[B43_QOSPARAM_CWMIN] = p->cw_min;
+ params[B43_QOSPARAM_CWMAX] = p->cw_max;
+ params[B43_QOSPARAM_CWCUR] = p->cw_min;
+ params[B43_QOSPARAM_AIFS] = p->aifs;
params[B43_QOSPARAM_BSLOTS] = bslots;
- params[B43_QOSPARAM_REGGAP] = bslots + aifs;
+ params[B43_QOSPARAM_REGGAP] = bslots + p->aifs;
for (i = 0; i < ARRAY_SIZE(params); i++) {
if (i == B43_QOSPARAM_STATUS) {
@@ -3060,8 +3182,7 @@ static void b43_qos_update_work(struct work_struct *work)
mutex_unlock(&wl->mutex);
}
-static int b43_op_conf_tx(struct ieee80211_hw *hw,
- int _queue,
+static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
const struct ieee80211_tx_queue_params *params)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
@@ -3309,8 +3430,9 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
b43_set_rx_antenna(dev, antenna);
- /* Update templates for AP mode. */
- if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
+ /* Update templates for AP/mesh mode. */
+ if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
+ b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT))
b43_set_beacon_int(dev, conf->beacon_int);
if (!!conf->radio_enabled != phy->radio_on) {
@@ -3361,6 +3483,13 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
goto out_unlock;
+ if (dev->fw.pcm_request_failed) {
+ /* We don't have firmware for the crypto engine.
+ * Must use software-crypto. */
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+
err = -EINVAL;
switch (key->alg) {
case ALG_WEP:
@@ -3491,13 +3620,16 @@ static int b43_op_config_interface(struct ieee80211_hw *hw,
else
memset(wl->bssid, 0, ETH_ALEN);
if (b43_status(dev) >= B43_STAT_INITIALIZED) {
- if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP)) {
- B43_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
- b43_set_ssid(dev, conf->ssid, conf->ssid_len);
- if (conf->beacon) {
- b43_update_templates(wl, conf->beacon,
- conf->beacon_control);
- }
+ if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
+ b43_is_mode(wl, IEEE80211_IF_TYPE_MESH_POINT)) {
+ B43_WARN_ON(vif->type != wl->if_type);
+ if (conf->changed & IEEE80211_IFCC_SSID)
+ b43_set_ssid(dev, conf->ssid, conf->ssid_len);
+ if (conf->changed & IEEE80211_IFCC_BEACON)
+ b43_update_templates(wl);
+ } else if (b43_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) {
+ if (conf->changed & IEEE80211_IFCC_BEACON)
+ b43_update_templates(wl);
}
b43_write_mac_bssid_templates(dev);
}
@@ -3562,7 +3694,6 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
/* Start data flow (TX/RX). */
b43_mac_enable(dev);
b43_interrupt_enable(dev, dev->irq_savedstate);
- ieee80211_start_queues(dev->wl->hw);
/* Start maintainance work */
b43_periodic_tasks_setup(dev);
@@ -3703,8 +3834,8 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev,
lo = phy->lo_control;
if (lo) {
memset(lo, 0, sizeof(*(phy->lo_control)));
- lo->rebuild = 1;
lo->tx_bias = 0xFF;
+ INIT_LIST_HEAD(&lo->calib_list);
}
phy->max_lb_gain = 0;
phy->trsw_rx_gain = 0;
@@ -4035,6 +4166,7 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
/* TODO: allow WDS/AP devices to coexist */
if (conf->type != IEEE80211_IF_TYPE_AP &&
+ conf->type != IEEE80211_IF_TYPE_MESH_POINT &&
conf->type != IEEE80211_IF_TYPE_STA &&
conf->type != IEEE80211_IF_TYPE_WDS &&
conf->type != IEEE80211_IF_TYPE_IBSS)
@@ -4185,33 +4317,10 @@ out_unlock:
static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
- struct sk_buff *beacon;
- unsigned long flags;
- struct ieee80211_tx_control txctl;
-
- /* We could modify the existing beacon and set the aid bit in
- * the TIM field, but that would probably require resizing and
- * moving of data within the beacon template.
- * Simply request a new beacon and let mac80211 do the hard work. */
- beacon = ieee80211_beacon_get(hw, wl->vif, &txctl);
- if (unlikely(!beacon))
- return -ENOMEM;
- spin_lock_irqsave(&wl->irq_lock, flags);
- b43_update_templates(wl, beacon, &txctl);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
-
- return 0;
-}
-
-static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *beacon,
- struct ieee80211_tx_control *ctl)
-{
- struct b43_wl *wl = hw_to_b43_wl(hw);
unsigned long flags;
spin_lock_irqsave(&wl->irq_lock, flags);
- b43_update_templates(wl, beacon, ctl);
+ b43_update_templates(wl);
spin_unlock_irqrestore(&wl->irq_lock, flags);
return 0;
@@ -4242,7 +4351,6 @@ static const struct ieee80211_ops b43_hw_ops = {
.stop = b43_op_stop,
.set_retry_limit = b43_op_set_retry_limit,
.set_tim = b43_op_beacon_set_tim,
- .beacon_update = b43_op_ibss_beacon_update,
.sta_notify = b43_op_sta_notify,
};
@@ -4538,10 +4646,10 @@ static int b43_wireless_init(struct ssb_device *dev)
/* fill hw info */
hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_RX_INCLUDES_FCS;
- hw->max_signal = 100;
- hw->max_rssi = -110;
- hw->max_noise = -110;
+ IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+
hw->queues = b43_modparam_qos ? 4 : 1;
SET_IEEE80211_DEV(hw, dev->dev);
if (is_valid_ether_addr(sprom->et1mac))
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 5230aeca78b..f871a252cb5 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
+u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
+u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
+void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
+void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
u64 b43_hf_read(struct b43_wldev *dev);
void b43_hf_write(struct b43_wldev *dev, u64 value);
@@ -114,4 +118,7 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason);
#define B43_PS_ASLEEP (1 << 3) /* Force device asleep */
void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
+void b43_mac_suspend(struct b43_wldev *dev);
+void b43_mac_enable(struct b43_wldev *dev);
+
#endif /* B43_MAIN_H_ */
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c
index 8695eb22347..644eed993be 100644
--- a/drivers/net/wireless/b43/nphy.c
+++ b/drivers/net/wireless/b43/nphy.c
@@ -29,8 +29,6 @@
#include "nphy.h"
#include "tables_nphy.h"
-#include <linux/delay.h>
-
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
{//TODO
diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c
index de024dc0371..305d4cd6fd0 100644
--- a/drivers/net/wireless/b43/phy.c
+++ b/drivers/net/wireless/b43/phy.c
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/types.h>
+#include <linux/bitrev.h>
#include "b43.h"
#include "phy.h"
@@ -83,25 +84,9 @@ const u8 b43_radio_channel_codes_bg[] = {
72, 84,
};
+#define bitrev4(tmp) (bitrev8(tmp) >> 4)
static void b43_phy_initg(struct b43_wldev *dev);
-/* Reverse the bits of a 4bit value.
- * Example: 1101 is flipped 1011
- */
-static u16 flip_4bit(u16 value)
-{
- u16 flipped = 0x0000;
-
- B43_WARN_ON(value & ~0x000F);
-
- flipped |= (value & 0x0001) << 3;
- flipped |= (value & 0x0002) << 1;
- flipped |= (value & 0x0004) >> 1;
- flipped |= (value & 0x0008) >> 3;
-
- return flipped;
-}
-
static void generate_rfatt_list(struct b43_wldev *dev,
struct b43_rfatt_list *list)
{
@@ -145,8 +130,7 @@ static void generate_rfatt_list(struct b43_wldev *dev,
{.att = 9,.with_padmix = 1,},
};
- if ((phy->type == B43_PHYTYPE_A && phy->rev < 5) ||
- (phy->type == B43_PHYTYPE_G && phy->rev < 6)) {
+ if (!b43_has_hardware_pctl(phy)) {
/* Software pctl */
list->list = rfatt_0;
list->len = ARRAY_SIZE(rfatt_0);
@@ -158,7 +142,7 @@ static void generate_rfatt_list(struct b43_wldev *dev,
/* Hardware pctl */
list->list = rfatt_1;
list->len = ARRAY_SIZE(rfatt_1);
- list->min_val = 2;
+ list->min_val = 0;
list->max_val = 14;
return;
}
@@ -346,6 +330,7 @@ void b43_set_txpower_g(struct b43_wldev *dev,
/* Save the values for later */
phy->tx_control = tx_control;
memcpy(&phy->rfatt, rfatt, sizeof(*rfatt));
+ phy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX);
memcpy(&phy->bbatt, bbatt, sizeof(*bbatt));
if (b43_debug(dev, B43_DBG_XMITPOWER)) {
@@ -559,11 +544,6 @@ static void b43_gphy_gain_lt_init(struct b43_wldev *dev)
u16 tmp;
u8 rf, bb;
- if (!lo->lo_measured) {
- b43_phy_write(dev, 0x3FF, 0);
- return;
- }
-
for (rf = 0; rf < lo->rfatt_list.len; rf++) {
for (bb = 0; bb < lo->bbatt_list.len; bb++) {
if (nr_written >= 0x40)
@@ -581,42 +561,6 @@ static void b43_gphy_gain_lt_init(struct b43_wldev *dev)
}
}
-/* GPHY_DC_Lookup_Table */
-void b43_gphy_dc_lt_init(struct b43_wldev *dev)
-{
- struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
- struct b43_loctl *loctl0;
- struct b43_loctl *loctl1;
- int i;
- int rf_offset, bb_offset;
- u16 tmp;
-
- for (i = 0; i < lo->rfatt_list.len + lo->bbatt_list.len; i += 2) {
- rf_offset = i / lo->rfatt_list.len;
- bb_offset = i % lo->rfatt_list.len;
-
- loctl0 = b43_get_lo_g_ctl(dev, &lo->rfatt_list.list[rf_offset],
- &lo->bbatt_list.list[bb_offset]);
- if (i + 1 < lo->rfatt_list.len * lo->bbatt_list.len) {
- rf_offset = (i + 1) / lo->rfatt_list.len;
- bb_offset = (i + 1) % lo->rfatt_list.len;
-
- loctl1 =
- b43_get_lo_g_ctl(dev,
- &lo->rfatt_list.list[rf_offset],
- &lo->bbatt_list.list[bb_offset]);
- } else
- loctl1 = loctl0;
-
- tmp = ((u16) loctl0->q & 0xF);
- tmp |= ((u16) loctl0->i & 0xF) << 4;
- tmp |= ((u16) loctl1->q & 0xF) << 8;
- tmp |= ((u16) loctl1->i & 0xF) << 12; //FIXME?
- b43_phy_write(dev, 0x3A0 + (i / 2), tmp);
- }
-}
-
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
{
//TODO
@@ -643,7 +587,7 @@ static void hardware_pctl_init_gphy(struct b43_wldev *dev)
b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
& 0xFFBF);
- b43_gphy_dc_lt_init(dev);
+ b43_gphy_dc_lt_init(dev, 1);
}
/* HardwarePowerControl init for A and G PHY */
@@ -931,109 +875,6 @@ static void b43_phy_inita(struct b43_wldev *dev)
}
}
-static void b43_phy_initb2(struct b43_wldev *dev)
-{
- struct b43_phy *phy = &dev->phy;
- u16 offset, val;
-
- b43_write16(dev, 0x03EC, 0x3F22);
- b43_phy_write(dev, 0x0020, 0x301C);
- b43_phy_write(dev, 0x0026, 0x0000);
- b43_phy_write(dev, 0x0030, 0x00C6);
- b43_phy_write(dev, 0x0088, 0x3E00);
- val = 0x3C3D;
- for (offset = 0x0089; offset < 0x00A7; offset++) {
- b43_phy_write(dev, offset, val);
- val -= 0x0202;
- }
- b43_phy_write(dev, 0x03E4, 0x3000);
- b43_radio_selectchannel(dev, phy->channel, 0);
- if (phy->radio_ver != 0x2050) {
- b43_radio_write16(dev, 0x0075, 0x0080);
- b43_radio_write16(dev, 0x0079, 0x0081);
- }
- b43_radio_write16(dev, 0x0050, 0x0020);
- b43_radio_write16(dev, 0x0050, 0x0023);
- if (phy->radio_ver == 0x2050) {
- b43_radio_write16(dev, 0x0050, 0x0020);
- b43_radio_write16(dev, 0x005A, 0x0070);
- b43_radio_write16(dev, 0x005B, 0x007B);
- b43_radio_write16(dev, 0x005C, 0x00B0);
- b43_radio_write16(dev, 0x007A, 0x000F);
- b43_phy_write(dev, 0x0038, 0x0677);
- b43_radio_init2050(dev);
- }
- b43_phy_write(dev, 0x0014, 0x0080);
- b43_phy_write(dev, 0x0032, 0x00CA);
- b43_phy_write(dev, 0x0032, 0x00CC);
- b43_phy_write(dev, 0x0035, 0x07C2);
- b43_lo_b_measure(dev);
- b43_phy_write(dev, 0x0026, 0xCC00);
- if (phy->radio_ver != 0x2050)
- b43_phy_write(dev, 0x0026, 0xCE00);
- b43_write16(dev, B43_MMIO_CHANNEL_EXT, 0x1000);
- b43_phy_write(dev, 0x002A, 0x88A3);
- if (phy->radio_ver != 0x2050)
- b43_phy_write(dev, 0x002A, 0x88C2);
- b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control);
- b43_phy_init_pctl(dev);
-}
-
-static void b43_phy_initb4(struct b43_wldev *dev)
-{
- struct b43_phy *phy = &dev->phy;
- u16 offset, val;
-
- b43_write16(dev, 0x03EC, 0x3F22);
- b43_phy_write(dev, 0x0020, 0x301C);
- b43_phy_write(dev, 0x0026, 0x0000);
- b43_phy_write(dev, 0x0030, 0x00C6);
- b43_phy_write(dev, 0x0088, 0x3E00);
- val = 0x3C3D;
- for (offset = 0x0089; offset < 0x00A7; offset++) {
- b43_phy_write(dev, offset, val);
- val -= 0x0202;
- }
- b43_phy_write(dev, 0x03E4, 0x3000);
- b43_radio_selectchannel(dev, phy->channel, 0);
- if (phy->radio_ver != 0x2050) {
- b43_radio_write16(dev, 0x0075, 0x0080);
- b43_radio_write16(dev, 0x0079, 0x0081);
- }
- b43_radio_write16(dev, 0x0050, 0x0020);
- b43_radio_write16(dev, 0x0050, 0x0023);
- if (phy->radio_ver == 0x2050) {
- b43_radio_write16(dev, 0x0050, 0x0020);
- b43_radio_write16(dev, 0x005A, 0x0070);
- b43_radio_write16(dev, 0x005B, 0x007B);
- b43_radio_write16(dev, 0x005C, 0x00B0);
- b43_radio_write16(dev, 0x007A, 0x000F);
- b43_phy_write(dev, 0x0038, 0x0677);
- b43_radio_init2050(dev);
- }
- b43_phy_write(dev, 0x0014, 0x0080);
- b43_phy_write(dev, 0x0032, 0x00CA);
- if (phy->radio_ver == 0x2050)
- b43_phy_write(dev, 0x0032, 0x00E0);
- b43_phy_write(dev, 0x0035, 0x07C2);
-
- b43_lo_b_measure(dev);
-
- b43_phy_write(dev, 0x0026, 0xCC00);
- if (phy->radio_ver == 0x2050)
- b43_phy_write(dev, 0x0026, 0xCE00);
- b43_write16(dev, B43_MMIO_CHANNEL_EXT, 0x1100);
- b43_phy_write(dev, 0x002A, 0x88A3);
- if (phy->radio_ver == 0x2050)
- b43_phy_write(dev, 0x002A, 0x88C2);
- b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control);
- if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
- b43_calc_nrssi_slope(dev);
- b43_calc_nrssi_threshold(dev);
- }
- b43_phy_init_pctl(dev);
-}
-
static void b43_phy_initb5(struct b43_wldev *dev)
{
struct ssb_bus *bus = dev->dev->bus;
@@ -1259,19 +1100,9 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
| 0x0004);
}
- if (phy->type == B43_PHYTYPE_B) {
- b43_write16(dev, 0x03E6, 0x8140);
- b43_phy_write(dev, 0x0016, 0x0410);
- b43_phy_write(dev, 0x0017, 0x0820);
- b43_phy_write(dev, 0x0062, 0x0007);
- b43_radio_init2050(dev);
- b43_lo_g_measure(dev);
- if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
- b43_calc_nrssi_slope(dev);
- b43_calc_nrssi_threshold(dev);
- }
- b43_phy_init_pctl(dev);
- } else if (phy->type == B43_PHYTYPE_G)
+ if (phy->type == B43_PHYTYPE_B)
+ B43_WARN_ON(1);
+ else if (phy->type == B43_PHYTYPE_G)
b43_write16(dev, 0x03E6, 0x0);
}
@@ -1534,34 +1365,31 @@ static void b43_phy_initg(struct b43_wldev *dev)
else
b43_radio_write16(dev, 0x0078, phy->initval);
}
- if (phy->lo_control->tx_bias == 0xFF) {
- b43_lo_g_measure(dev);
+ b43_lo_g_init(dev);
+ if (has_tx_magnification(phy)) {
+ b43_radio_write16(dev, 0x52,
+ (b43_radio_read16(dev, 0x52) & 0xFF00)
+ | phy->lo_control->tx_bias | phy->
+ lo_control->tx_magn);
} else {
- if (has_tx_magnification(phy)) {
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52) & 0xFF00)
- | phy->lo_control->tx_bias | phy->
- lo_control->tx_magn);
- } else {
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52) & 0xFFF0)
- | phy->lo_control->tx_bias);
- }
- if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_CCK(0x36),
- (b43_phy_read(dev, B43_PHY_CCK(0x36))
- & 0x0FFF) | (phy->lo_control->
- tx_bias << 12));
- }
- if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
- b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
- else
- b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
- if (phy->rev < 2)
- b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101);
- else
- b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202);
+ b43_radio_write16(dev, 0x52,
+ (b43_radio_read16(dev, 0x52) & 0xFFF0)
+ | phy->lo_control->tx_bias);
}
+ if (phy->rev >= 6) {
+ b43_phy_write(dev, B43_PHY_CCK(0x36),
+ (b43_phy_read(dev, B43_PHY_CCK(0x36))
+ & 0x0FFF) | (phy->lo_control->
+ tx_bias << 12));
+ }
+ if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
+ b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
+ else
+ b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
+ if (phy->rev < 2)
+ b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101);
+ else
+ b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202);
if (phy->gmode || phy->rev >= 2) {
b43_lo_g_adjust(dev);
b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
@@ -1572,7 +1400,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
* the value 0x7FFFFFFF here. I think that is some weird
* compiler optimization in the original driver.
* Essentially, what we do here is resetting all NRSSI LT
- * entries to -32 (see the limit_value() in nrssi_hw_update())
+ * entries to -32 (see the clamp_val() in nrssi_hw_update())
*/
b43_nrssi_hw_update(dev, 0xFFFF); //FIXME?
b43_calc_nrssi_threshold(dev);
@@ -1634,13 +1462,13 @@ static s8 b43_phy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
switch (phy->type) {
case B43_PHYTYPE_A:
tmp += 0x80;
- tmp = limit_value(tmp, 0x00, 0xFF);
+ tmp = clamp_val(tmp, 0x00, 0xFF);
dbm = phy->tssi2dbm[tmp];
//TODO: There's a FIXME on the specs
break;
case B43_PHYTYPE_B:
case B43_PHYTYPE_G:
- tmp = limit_value(tmp, 0x00, 0x3F);
+ tmp = clamp_val(tmp, 0x00, 0x3F);
dbm = phy->tssi2dbm[tmp];
break;
default:
@@ -1699,8 +1527,8 @@ void b43_put_attenuation_into_ranges(struct b43_wldev *dev,
break;
}
- *_rfatt = limit_value(rfatt, rf_min, rf_max);
- *_bbatt = limit_value(bbatt, bb_min, bb_max);
+ *_rfatt = clamp_val(rfatt, rf_min, rf_max);
+ *_bbatt = clamp_val(bbatt, bb_min, bb_max);
}
/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
@@ -1795,7 +1623,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
/* Get desired power (in Q5.2) */
desired_pwr = INT_TO_Q52(phy->power_level);
/* And limit it. max_pwr already is Q5.2 */
- desired_pwr = limit_value(desired_pwr, 0, max_pwr);
+ desired_pwr = clamp_val(desired_pwr, 0, max_pwr);
if (b43_debug(dev, B43_DBG_XMITPOWER)) {
b43dbg(dev->wl,
"Current TX power output: " Q52_FMT
@@ -1821,10 +1649,8 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
bbatt_delta -= 4 * rfatt_delta;
/* So do we finally need to adjust something? */
- if ((rfatt_delta == 0) && (bbatt_delta == 0)) {
- b43_lo_g_ctl_mark_cur_used(dev);
+ if ((rfatt_delta == 0) && (bbatt_delta == 0))
return;
- }
/* Calculate the new attenuation values. */
bbatt = phy->bbatt.att;
@@ -1870,7 +1696,6 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
b43_radio_lock(dev);
b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt,
phy->tx_control);
- b43_lo_g_ctl_mark_cur_used(dev);
b43_radio_unlock(dev);
b43_phy_unlock(dev);
break;
@@ -1908,7 +1733,7 @@ static inline
f = q;
i++;
} while (delta >= 2);
- entry[index] = limit_value(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128);
+ entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128);
return 0;
}
@@ -2007,24 +1832,6 @@ int b43_phy_init(struct b43_wldev *dev)
else
unsupported = 1;
break;
- case B43_PHYTYPE_B:
- switch (phy->rev) {
- case 2:
- b43_phy_initb2(dev);
- break;
- case 4:
- b43_phy_initb4(dev);
- break;
- case 5:
- b43_phy_initb5(dev);
- break;
- case 6:
- b43_phy_initb6(dev);
- break;
- default:
- unsupported = 1;
- }
- break;
case B43_PHYTYPE_G:
b43_phy_initg(dev);
break;
@@ -2452,7 +2259,7 @@ void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val)
for (i = 0; i < 64; i++) {
tmp = b43_nrssi_hw_read(dev, i);
tmp -= val;
- tmp = limit_value(tmp, -32, 31);
+ tmp = clamp_val(tmp, -32, 31);
b43_nrssi_hw_write(dev, i, tmp);
}
}
@@ -2469,7 +2276,7 @@ void b43_nrssi_mem_update(struct b43_wldev *dev)
tmp = (i - delta) * phy->nrssislope;
tmp /= 0x10000;
tmp += 0x3A;
- tmp = limit_value(tmp, 0, 0x3F);
+ tmp = clamp_val(tmp, 0, 0x3F);
phy->nrssi_lt[i] = tmp;
}
}
@@ -2906,7 +2713,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev)
} else
threshold = phy->nrssi[1] - 5;
- threshold = limit_value(threshold, 0, 0x3E);
+ threshold = clamp_val(threshold, 0, 0x3E);
b43_phy_read(dev, 0x0020); /* dummy read */
b43_phy_write(dev, 0x0020,
(((u16) threshold) << 8) | 0x001C);
@@ -2957,7 +2764,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev)
else
a += 32;
a = a >> 6;
- a = limit_value(a, -31, 31);
+ a = clamp_val(a, -31, 31);
b = b * (phy->nrssi[1] - phy->nrssi[0]);
b += (phy->nrssi[0] << 6);
@@ -2966,7 +2773,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev)
else
b += 32;
b = b >> 6;
- b = limit_value(b, -31, 31);
+ b = clamp_val(b, -31, 31);
tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000;
tmp_u16 |= ((u32) b & 0x0000003F);
@@ -3069,13 +2876,13 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
}
radio_stacksave(0x0078);
tmp = (b43_radio_read16(dev, 0x0078) & 0x001E);
- flipped = flip_4bit(tmp);
+ B43_WARN_ON(tmp > 15);
+ flipped = bitrev4(tmp);
if (flipped < 10 && flipped >= 8)
flipped = 7;
else if (flipped >= 10)
flipped -= 3;
- flipped = flip_4bit(flipped);
- flipped = (flipped << 1) | 0x0020;
+ flipped = (bitrev4(flipped) << 1) | 0x0020;
b43_radio_write16(dev, 0x0078, flipped);
b43_calc_nrssi_threshold(dev);
@@ -3708,7 +3515,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
tmp1 >>= 9;
for (i = 0; i < 16; i++) {
- radio78 = ((flip_4bit(i) << 1) | 0x20);
+ radio78 = (bitrev4(i) << 1) | 0x0020;
b43_radio_write16(dev, 0x78, radio78);
udelay(10);
for (j = 0; j < 16; j++) {
diff --git a/drivers/net/wireless/b43/phy.h b/drivers/net/wireless/b43/phy.h
index 6d165d82217..4aab1090352 100644
--- a/drivers/net/wireless/b43/phy.h
+++ b/drivers/net/wireless/b43/phy.h
@@ -225,7 +225,6 @@ int b43_phy_init(struct b43_wldev *dev);
void b43_set_rx_antenna(struct b43_wldev *dev, int antenna);
void b43_phy_xmitpower(struct b43_wldev *dev);
-void b43_gphy_dc_lt_init(struct b43_wldev *dev);
/* Returns the boolean whether the board has HardwarePowerControl */
bool b43_has_hardware_pctl(struct b43_phy *phy);
@@ -252,6 +251,14 @@ struct b43_rfatt_list {
u8 max_val;
};
+/* Returns true, if the values are the same. */
+static inline bool b43_compare_rfatt(const struct b43_rfatt *a,
+ const struct b43_rfatt *b)
+{
+ return ((a->att == b->att) &&
+ (a->with_padmix == b->with_padmix));
+}
+
/* Baseband Attenuation */
struct b43_bbatt {
u8 att; /* Attenuation value */
@@ -265,6 +272,13 @@ struct b43_bbatt_list {
u8 max_val;
};
+/* Returns true, if the values are the same. */
+static inline bool b43_compare_bbatt(const struct b43_bbatt *a,
+ const struct b43_bbatt *b)
+{
+ return (a->att == b->att);
+}
+
/* tx_control bits. */
#define B43_TXCTL_PA3DB 0x40 /* PA Gain 3dB */
#define B43_TXCTL_PA2DB 0x20 /* PA Gain 2dB */
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index fcacafb0434..40159126759 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -446,29 +446,27 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
}
static int pio_tx_frame(struct b43_pio_txqueue *q,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
struct b43_pio_txpacket *pack;
struct b43_txhdr txhdr;
u16 cookie;
int err;
unsigned int hdrlen;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
B43_WARN_ON(list_empty(&q->packets_list));
pack = list_entry(q->packets_list.next,
struct b43_pio_txpacket, list);
- memset(&pack->txstat, 0, sizeof(pack->txstat));
- memcpy(&pack->txstat.control, ctl, sizeof(*ctl));
cookie = generate_cookie(q, pack);
hdrlen = b43_txhdr_size(q->dev);
err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb->data,
- skb->len, ctl, cookie);
+ skb->len, info, cookie);
if (err)
return err;
- if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/* Tell the firmware about the cookie of the last
* mcast frame, so it can clear the more-data bit in it. */
b43_shm_write16(q->dev, B43_SHM_SHARED,
@@ -492,17 +490,18 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
return 0;
}
-int b43_pio_tx(struct b43_wldev *dev,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
{
struct b43_pio_txqueue *q;
struct ieee80211_hdr *hdr;
unsigned long flags;
unsigned int hdrlen, total_len;
int err = 0;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
hdr = (struct ieee80211_hdr *)skb->data;
- if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+
+ if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
/* The multicast queue will be sent after the DTIM. */
q = dev->pio.tx_queue_mcast;
/* Set the frame More-Data bit. Ucode will clear it
@@ -510,7 +509,7 @@ int b43_pio_tx(struct b43_wldev *dev,
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
} else {
/* Decide by priority where to put this frame. */
- q = select_queue_by_priority(dev, ctl->queue);
+ q = select_queue_by_priority(dev, skb_get_queue_mapping(skb));
}
spin_lock_irqsave(&q->lock, flags);
@@ -533,7 +532,7 @@ int b43_pio_tx(struct b43_wldev *dev,
if (total_len > (q->buffer_size - q->buffer_used)) {
/* Not enough memory on the queue. */
err = -EBUSY;
- ieee80211_stop_queue(dev->wl->hw, ctl->queue);
+ ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
q->stopped = 1;
goto out_unlock;
}
@@ -541,9 +540,9 @@ int b43_pio_tx(struct b43_wldev *dev,
/* Assign the queue number to the ring (if not already done before)
* so TX status handling can use it. The mac80211-queue to b43-queue
* mapping is static, so we don't need to store it per frame. */
- q->queue_prio = ctl->queue;
+ q->queue_prio = skb_get_queue_mapping(skb);
- err = pio_tx_frame(q, skb, ctl);
+ err = pio_tx_frame(q, skb);
if (unlikely(err == -ENOKEY)) {
/* Drop this packet, as we don't have the encryption key
* anymore and must not transmit it unencrypted. */
@@ -561,7 +560,7 @@ int b43_pio_tx(struct b43_wldev *dev,
if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) ||
(q->free_packet_slots == 0)) {
/* The queue is full. */
- ieee80211_stop_queue(dev->wl->hw, ctl->queue);
+ ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
q->stopped = 1;
}
@@ -578,6 +577,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
struct b43_pio_txqueue *q;
struct b43_pio_txpacket *pack = NULL;
unsigned int total_len;
+ struct ieee80211_tx_info *info;
q = parse_cookie(dev, status->cookie, &pack);
if (unlikely(!q))
@@ -586,15 +586,17 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
spin_lock(&q->lock); /* IRQs are already disabled. */
- b43_fill_txstatus_report(&(pack->txstat), status);
+ info = IEEE80211_SKB_CB(pack->skb);
+ memset(&info->status, 0, sizeof(info->status));
+
+ b43_fill_txstatus_report(info, status);
total_len = pack->skb->len + b43_txhdr_size(dev);
total_len = roundup(total_len, 4);
q->buffer_used -= total_len;
q->free_packet_slots += 1;
- ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb,
- &(pack->txstat));
+ ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb);
pack->skb = NULL;
list_add(&pack->list, &q->packets_list);
@@ -611,18 +613,16 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
{
const int nr_queues = dev->wl->hw->queues;
struct b43_pio_txqueue *q;
- struct ieee80211_tx_queue_stats_data *data;
unsigned long flags;
int i;
for (i = 0; i < nr_queues; i++) {
- data = &(stats->data[i]);
q = select_queue_by_priority(dev, i);
spin_lock_irqsave(&q->lock, flags);
- data->len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
- data->limit = B43_PIO_MAX_NR_TXPACKETS;
- data->count = q->nr_tx_packets;
+ stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
+ stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
+ stats[i].count = q->nr_tx_packets;
spin_unlock_irqrestore(&q->lock, flags);
}
}
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
index e2ec676cc9e..6c174c91ca2 100644
--- a/drivers/net/wireless/b43/pio.h
+++ b/drivers/net/wireless/b43/pio.h
@@ -62,8 +62,6 @@ struct b43_pio_txpacket {
struct b43_pio_txqueue *queue;
/* The TX data packet. */
struct sk_buff *skb;
- /* The status meta data. */
- struct ieee80211_tx_status txstat;
/* Index in the (struct b43_pio_txqueue)->packets array. */
u8 index;
@@ -167,8 +165,7 @@ int b43_pio_init(struct b43_wldev *dev);
void b43_pio_stop(struct b43_wldev *dev);
void b43_pio_free(struct b43_wldev *dev);
-int b43_pio_tx(struct b43_wldev *dev,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl);
+int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
void b43_pio_handle_txstatus(struct b43_wldev *dev,
const struct b43_txstatus *status);
void b43_pio_get_tx_stats(struct b43_wldev *dev,
@@ -193,8 +190,7 @@ static inline void b43_pio_stop(struct b43_wldev *dev)
{
}
static inline int b43_pio_tx(struct b43_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
return 0;
}
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 11f53cb1139..fec5645944a 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -43,6 +43,23 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
return 0;
}
+/* Update the rfkill state */
+static void b43_rfkill_update_state(struct b43_wldev *dev)
+{
+ struct b43_rfkill *rfk = &(dev->wl->rfkill);
+
+ if (!dev->radio_hw_enable) {
+ rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
+ return;
+ }
+
+ if (!dev->phy.radio_on)
+ rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
+ else
+ rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
+
+}
+
/* The poll callback for the hardware button. */
static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
{
@@ -60,6 +77,7 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
if (unlikely(enabled != dev->radio_hw_enable)) {
dev->radio_hw_enable = enabled;
report_change = 1;
+ b43_rfkill_update_state(dev);
b43info(wl, "Radio hardware status changed to %s\n",
enabled ? "ENABLED" : "DISABLED");
}
@@ -88,7 +106,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock;
err = 0;
switch (state) {
- case RFKILL_STATE_ON:
+ case RFKILL_STATE_UNBLOCKED:
if (!dev->radio_hw_enable) {
/* No luck. We can't toggle the hardware RF-kill
* button from software. */
@@ -98,10 +116,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
if (!dev->phy.radio_on)
b43_radio_turn_on(dev);
break;
- case RFKILL_STATE_OFF:
+ case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on)
b43_radio_turn_off(dev, 0);
break;
+ default:
+ b43warn(wl, "Received unexpected rfkill state %d.\n", state);
+ break;
}
out_unlock:
mutex_unlock(&wl->mutex);
@@ -132,7 +153,7 @@ void b43_rfkill_init(struct b43_wldev *dev)
snprintf(rfk->name, sizeof(rfk->name),
"b43-%s", wiphy_name(wl->hw->wiphy));
rfk->rfkill->name = rfk->name;
- rfk->rfkill->state = RFKILL_STATE_ON;
+ rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
rfk->rfkill->data = dev;
rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle;
rfk->rfkill->user_claim_unsupported = 1;
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 19aefbfb2c9..8d54502222a 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -185,15 +185,15 @@ int b43_generate_txhdr(struct b43_wldev *dev,
u8 *_txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
+ const struct ieee80211_tx_info *info,
u16 cookie)
{
struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
const struct b43_phy *phy = &dev->phy;
const struct ieee80211_hdr *wlhdr =
(const struct ieee80211_hdr *)fragment_data;
- int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
- u16 fctl = le16_to_cpu(wlhdr->frame_control);
+ int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
+ __le16 fctl = wlhdr->frame_control;
struct ieee80211_rate *fbrate;
u8 rate, rate_fb;
int rate_ofdm, rate_fb_ofdm;
@@ -201,13 +201,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
u32 mac_ctl = 0;
u16 phy_ctl = 0;
u8 extra_ft = 0;
+ struct ieee80211_rate *txrate;
memset(txhdr, 0, sizeof(*txhdr));
- WARN_ON(!txctl->tx_rate);
- rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
+ txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
+ rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
rate_ofdm = b43_is_ofdm_rate(rate);
- fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
+ fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : txrate;
rate_fb = fbrate->hw_value;
rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
@@ -227,15 +228,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
* use the original dur_id field. */
txhdr->dur_fb = wlhdr->duration_id;
} else {
- txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
- txctl->vif,
- fragment_len,
- fbrate);
+ txhdr->dur_fb = ieee80211_generic_frame_duration(
+ dev->wl->hw, info->control.vif, fragment_len, fbrate);
}
plcp_fragment_len = fragment_len + FCS_LEN;
if (use_encryption) {
- u8 key_idx = (u16) (txctl->key_idx);
+ u8 key_idx = info->control.hw_key->hw_key_idx;
struct b43_key *key;
int wlhdr_len;
size_t iv_len;
@@ -253,15 +252,15 @@ int b43_generate_txhdr(struct b43_wldev *dev,
}
/* Hardware appends ICV. */
- plcp_fragment_len += txctl->icv_len;
+ plcp_fragment_len += info->control.icv_len;
key_idx = b43_kidx_to_fw(dev, key_idx);
mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
B43_TXH_MAC_KEYIDX;
mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
B43_TXH_MAC_KEYALG;
- wlhdr_len = ieee80211_get_hdrlen(fctl);
- iv_len = min((size_t) txctl->iv_len,
+ wlhdr_len = ieee80211_hdrlen(fctl);
+ iv_len = min((size_t) info->control.iv_len,
ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
}
@@ -292,10 +291,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
phy_ctl |= B43_TXH_PHY_ENC_OFDM;
else
phy_ctl |= B43_TXH_PHY_ENC_CCK;
- if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
+ if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
- switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
+ switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
case 0: /* Default */
phy_ctl |= B43_TXH_PHY_ANT01AUTO;
break;
@@ -316,34 +315,36 @@ int b43_generate_txhdr(struct b43_wldev *dev,
}
/* MAC control */
- if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43_TXH_MAC_ACK;
- if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
+ /* use hardware sequence counter as the non-TID counter */
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
mac_ctl |= B43_TXH_MAC_HWSEQ;
- if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
mac_ctl |= B43_TXH_MAC_STMSDU;
if (phy->type == B43_PHYTYPE_A)
mac_ctl |= B43_TXH_MAC_5GHZ;
- if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+ if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
mac_ctl |= B43_TXH_MAC_LONGFRAME;
/* Generate the RTS or CTS-to-self frame */
- if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
- (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+ if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+ (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
unsigned int len;
struct ieee80211_hdr *hdr;
int rts_rate, rts_rate_fb;
int rts_rate_ofdm, rts_rate_fb_ofdm;
struct b43_plcp_hdr6 *plcp;
+ struct ieee80211_rate *rts_cts_rate;
- WARN_ON(!txctl->rts_cts_rate);
- rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
+ rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info);
+
+ rts_rate = rts_cts_rate ? rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
rts_rate_fb = b43_calc_fallback_rate(rts_rate);
rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
- if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+ if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
struct ieee80211_cts *cts;
if (b43_is_old_txhdr_format(dev)) {
@@ -353,9 +354,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
cts = (struct ieee80211_cts *)
(txhdr->new_format.rts_frame);
}
- ieee80211_ctstoself_get(dev->wl->hw, txctl->vif,
+ ieee80211_ctstoself_get(dev->wl->hw, info->control.vif,
fragment_data, fragment_len,
- txctl, cts);
+ info, cts);
mac_ctl |= B43_TXH_MAC_SENDCTS;
len = sizeof(struct ieee80211_cts);
} else {
@@ -368,9 +369,9 @@ int b43_generate_txhdr(struct b43_wldev *dev,
rts = (struct ieee80211_rts *)
(txhdr->new_format.rts_frame);
}
- ieee80211_rts_get(dev->wl->hw, txctl->vif,
+ ieee80211_rts_get(dev->wl->hw, info->control.vif,
fragment_data, fragment_len,
- txctl, rts);
+ info, rts);
mac_ctl |= B43_TXH_MAC_SENDRTS;
len = sizeof(struct ieee80211_rts);
}
@@ -508,7 +509,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
struct b43_plcp_hdr6 *plcp;
struct ieee80211_hdr *wlhdr;
const struct b43_rxhdr_fw4 *rxhdr = _rxhdr;
- u16 fctl;
+ __le16 fctl;
u16 phystat0, phystat3, chanstat, mactime;
u32 macstat;
u16 chanid;
@@ -548,7 +549,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
goto drop;
}
wlhdr = (struct ieee80211_hdr *)(skb->data);
- fctl = le16_to_cpu(wlhdr->frame_control);
+ fctl = wlhdr->frame_control;
if (macstat & B43_RX_MAC_DEC) {
unsigned int keyidx;
@@ -563,7 +564,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
B43_WARN_ON(keyidx >= dev->max_nr_keys);
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
- wlhdr_len = ieee80211_get_hdrlen(fctl);
+ wlhdr_len = ieee80211_hdrlen(fctl);
if (unlikely(skb->len < (wlhdr_len + 3))) {
b43dbg(dev->wl,
"RX: Packet size underrun (3)\n");
@@ -581,12 +582,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
// and also find out what the maximum possible value is.
// Fill status.ssi and status.signal fields.
} else {
- status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi,
+ status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
(phystat0 & B43_RX_PHYST0_OFDM),
(phystat0 & B43_RX_PHYST0_GAINCTL),
(phystat3 & B43_RX_PHYST3_TRSTATE));
- /* the next line looks wrong, but is what mac80211 wants */
- status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
+ status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI;
}
if (phystat0 & B43_RX_PHYST0_OFDM)
@@ -604,9 +604,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
* of timestamp, i.e. about 65 milliseconds after the PHY received
* the first symbol.
*/
- if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
- == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
- dev->wl->radiotap_enabled) {
+ if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
u16 low_mactime_now;
b43_tsf_read(dev, &status.mactime);
@@ -685,27 +683,27 @@ void b43_handle_txstatus(struct b43_wldev *dev,
/* Fill out the mac80211 TXstatus report based on the b43-specific
* txstatus report data. This returns a boolean whether the frame was
* successfully transmitted. */
-bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
+bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
const struct b43_txstatus *status)
{
bool frame_success = 1;
if (status->acked) {
/* The frame was ACKed. */
- report->flags |= IEEE80211_TX_STATUS_ACK;
+ report->flags |= IEEE80211_TX_STAT_ACK;
} else {
/* The frame was not ACKed... */
- if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
+ if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
/* ...but we expected an ACK. */
frame_success = 0;
- report->excessive_retries = 1;
+ report->status.excessive_retries = 1;
}
}
if (status->frame_count == 0) {
/* The frame was not transmitted at all. */
- report->retry_count = 0;
+ report->status.retry_count = 0;
} else
- report->retry_count = status->frame_count - 1;
+ report->status.retry_count = status->frame_count - 1;
return frame_success;
}
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index b05f44e0d62..0215faf4754 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -178,7 +178,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
u8 * txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl, u16 cookie);
+ const struct ieee80211_tx_info *txctl, u16 cookie);
/* Transmit Status */
struct b43_txstatus {
@@ -294,7 +294,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr);
void b43_handle_txstatus(struct b43_wldev *dev,
const struct b43_txstatus *status);
-bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
+bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
const struct b43_txstatus *status);
void b43_tx_suspend(struct b43_wldev *dev);
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index ded3cd31b3d..c40078e1fff 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -823,23 +823,6 @@ void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...)
# define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0)
#endif /* DEBUG */
-
-/** Limit a value between two limits */
-#ifdef limit_value
-# undef limit_value
-#endif
-#define limit_value(value, min, max) \
- ({ \
- typeof(value) __value = (value); \
- typeof(value) __min = (min); \
- typeof(value) __max = (max); \
- if (__value < __min) \
- __value = __min; \
- else if (__value > __max) \
- __value = __max; \
- __value; \
- })
-
/* Macros for printing a value in Q5.2 format */
#define Q52_FMT "%u.%u"
#define Q52_ARG(q52) ((q52) / 4), (((q52) & 3) * 100 / 4)
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 93ddc1cbcc8..fb6819e40f3 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring,
dma_addr_t dmaaddr;
if (tx)
- dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
- buf, len,
- DMA_TO_DEVICE);
+ dmaaddr = ssb_dma_map_single(ring->dev->dev,
+ buf, len,
+ DMA_TO_DEVICE);
else
- dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
- buf, len,
- DMA_FROM_DEVICE);
+ dmaaddr = ssb_dma_map_single(ring->dev->dev,
+ buf, len,
+ DMA_FROM_DEVICE);
return dmaaddr;
}
@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring,
int tx)
{
if (tx)
- dma_unmap_single(ring->dev->dev->dma_dev,
- addr, len,
- DMA_TO_DEVICE);
+ ssb_dma_unmap_single(ring->dev->dev,
+ addr, len,
+ DMA_TO_DEVICE);
else
- dma_unmap_single(ring->dev->dev->dma_dev,
- addr, len,
- DMA_FROM_DEVICE);
+ ssb_dma_unmap_single(ring->dev->dev,
+ addr, len,
+ DMA_FROM_DEVICE);
}
static inline
@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
{
B43legacy_WARN_ON(ring->tx);
- dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ ssb_dma_sync_single_for_cpu(ring->dev->dev,
+ addr, len, DMA_FROM_DEVICE);
}
static inline
@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
{
B43legacy_WARN_ON(ring->tx);
- dma_sync_single_for_device(ring->dev->dev->dma_dev,
- addr, len, DMA_FROM_DEVICE);
+ ssb_dma_sync_single_for_device(ring->dev->dev,
+ addr, len, DMA_FROM_DEVICE);
}
static inline
@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring,
static int alloc_ringmemory(struct b43legacy_dmaring *ring)
{
- struct device *dma_dev = ring->dev->dev->dma_dev;
-
- ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
- &(ring->dmabase), GFP_KERNEL);
+ /* GFP flags must match the flags in free_ringmemory()! */
+ ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev,
+ B43legacy_DMA_RINGMEMSIZE,
+ &(ring->dmabase),
+ GFP_KERNEL);
if (!ring->descbase) {
b43legacyerr(ring->dev->wl, "DMA ringmemory allocation"
" failed\n");
@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring)
static void free_ringmemory(struct b43legacy_dmaring *ring)
{
- struct device *dma_dev = ring->dev->dev->dma_dev;
-
- dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
- ring->descbase, ring->dmabase);
+ ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE,
+ ring->descbase, ring->dmabase, GFP_KERNEL);
}
/* Reset the RX DMA channel */
@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
size_t buffersize,
bool dma_to_device)
{
- if (unlikely(dma_mapping_error(addr)))
+ if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr)))
return 1;
switch (ring->type) {
@@ -860,6 +859,18 @@ static u64 supported_dma_mask(struct b43legacy_wldev *dev)
return DMA_30BIT_MASK;
}
+static enum b43legacy_dmatype dma_mask_to_engine_type(u64 dmamask)
+{
+ if (dmamask == DMA_30BIT_MASK)
+ return B43legacy_DMA_30BIT;
+ if (dmamask == DMA_32BIT_MASK)
+ return B43legacy_DMA_32BIT;
+ if (dmamask == DMA_64BIT_MASK)
+ return B43legacy_DMA_64BIT;
+ B43legacy_WARN_ON(1);
+ return B43legacy_DMA_30BIT;
+}
+
/* Main initialization function. */
static
struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
@@ -894,9 +905,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_meta;
/* test for ability to dma to txhdr_cache */
- dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache,
- sizeof(struct b43legacy_txhdr_fw3),
- DMA_TO_DEVICE);
+ dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache,
+ sizeof(struct b43legacy_txhdr_fw3),
+ DMA_TO_DEVICE);
if (b43legacy_dma_mapping_error(ring, dma_test,
sizeof(struct b43legacy_txhdr_fw3), 1)) {
@@ -908,7 +919,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
if (!ring->txhdr_cache)
goto err_kfree_meta;
- dma_test = dma_map_single(dev->dev->dma_dev,
+ dma_test = ssb_dma_map_single(dev->dev,
ring->txhdr_cache,
sizeof(struct b43legacy_txhdr_fw3),
DMA_TO_DEVICE);
@@ -918,9 +929,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
goto err_kfree_txhdr_cache;
}
- dma_unmap_single(dev->dev->dma_dev,
- dma_test, sizeof(struct b43legacy_txhdr_fw3),
- DMA_TO_DEVICE);
+ ssb_dma_unmap_single(dev->dev, dma_test,
+ sizeof(struct b43legacy_txhdr_fw3),
+ DMA_TO_DEVICE);
}
ring->nr_slots = nr_slots;
@@ -1019,6 +1030,43 @@ void b43legacy_dma_free(struct b43legacy_wldev *dev)
dma->tx_ring0 = NULL;
}
+static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask)
+{
+ u64 orig_mask = mask;
+ bool fallback = 0;
+ int err;
+
+ /* Try to set the DMA mask. If it fails, try falling back to a
+ * lower mask, as we can always also support a lower one. */
+ while (1) {
+ err = ssb_dma_set_mask(dev->dev, mask);
+ if (!err)
+ break;
+ if (mask == DMA_64BIT_MASK) {
+ mask = DMA_32BIT_MASK;
+ fallback = 1;
+ continue;
+ }
+ if (mask == DMA_32BIT_MASK) {
+ mask = DMA_30BIT_MASK;
+ fallback = 1;
+ continue;
+ }
+ b43legacyerr(dev->wl, "The machine/kernel does not support "
+ "the required %u-bit DMA mask\n",
+ (unsigned int)dma_mask_to_engine_type(orig_mask));
+ return -EOPNOTSUPP;
+ }
+ if (fallback) {
+ b43legacyinfo(dev->wl, "DMA mask fallback from %u-bit to %u-"
+ "bit\n",
+ (unsigned int)dma_mask_to_engine_type(orig_mask),
+ (unsigned int)dma_mask_to_engine_type(mask));
+ }
+
+ return 0;
+}
+
int b43legacy_dma_init(struct b43legacy_wldev *dev)
{
struct b43legacy_dma *dma = &dev->dma;
@@ -1028,21 +1076,8 @@ int b43legacy_dma_init(struct b43legacy_wldev *dev)
enum b43legacy_dmatype type;
dmamask = supported_dma_mask(dev);
- switch (dmamask) {
- default:
- B43legacy_WARN_ON(1);
- case DMA_30BIT_MASK:
- type = B43legacy_DMA_30BIT;
- break;
- case DMA_32BIT_MASK:
- type = B43legacy_DMA_32BIT;
- break;
- case DMA_64BIT_MASK:
- type = B43legacy_DMA_64BIT;
- break;
- }
-
- err = ssb_dma_set_mask(dev->dev, dmamask);
+ type = dma_mask_to_engine_type(dmamask);
+ err = b43legacy_dma_set_mask(dev, dmamask);
if (err) {
#ifdef CONFIG_B43LEGACY_PIO
b43legacywarn(dev->wl, "DMA for this device not supported. "
@@ -1205,10 +1240,10 @@ struct b43legacy_dmaring *parse_cookie(struct b43legacy_wldev *dev,
}
static int dma_tx_fragment(struct b43legacy_dmaring *ring,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
const struct b43legacy_dma_ops *ops = ring->ops;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
u8 *header;
int slot, old_top_slot, old_used_slots;
int err;
@@ -1231,7 +1266,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
header = &(ring->txhdr_cache[slot * sizeof(
struct b43legacy_txhdr_fw3)]);
err = b43legacy_generate_txhdr(ring->dev, header,
- skb->data, skb->len, ctl,
+ skb->data, skb->len, info,
generate_cookie(ring, slot));
if (unlikely(err)) {
ring->current_slot = old_top_slot;
@@ -1255,7 +1290,6 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
desc = ops->idx2desc(ring, slot, &meta);
memset(meta, 0, sizeof(*meta));
- memcpy(&meta->txstat.control, ctl, sizeof(*ctl));
meta->skb = skb;
meta->is_last_fragment = 1;
@@ -1323,14 +1357,13 @@ int should_inject_overflow(struct b43legacy_dmaring *ring)
}
int b43legacy_dma_tx(struct b43legacy_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
struct b43legacy_dmaring *ring;
int err = 0;
unsigned long flags;
- ring = priority_to_txring(dev, ctl->queue);
+ ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
spin_lock_irqsave(&ring->lock, flags);
B43legacy_WARN_ON(!ring->tx);
if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
@@ -1343,7 +1376,7 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
* That would be a mac80211 bug. */
B43legacy_BUG_ON(ring->stopped);
- err = dma_tx_fragment(ring, skb, ctl);
+ err = dma_tx_fragment(ring, skb);
if (unlikely(err == -ENOKEY)) {
/* Drop this packet, as we don't have the encryption key
* anymore and must not transmit it unencrypted. */
@@ -1401,26 +1434,29 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
1);
if (meta->is_last_fragment) {
- B43legacy_WARN_ON(!meta->skb);
+ struct ieee80211_tx_info *info;
+ BUG_ON(!meta->skb);
+ info = IEEE80211_SKB_CB(meta->skb);
/* Call back to inform the ieee80211 subsystem about the
* status of the transmission.
* Some fields of txstat are already filled in dma_tx().
*/
+
+ memset(&info->status, 0, sizeof(info->status));
+
if (status->acked) {
- meta->txstat.flags |= IEEE80211_TX_STATUS_ACK;
+ info->flags |= IEEE80211_TX_STAT_ACK;
} else {
- if (!(meta->txstat.control.flags
- & IEEE80211_TXCTL_NO_ACK))
- meta->txstat.excessive_retries = 1;
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
+ info->status.excessive_retries = 1;
}
if (status->frame_count == 0) {
/* The frame was not transmitted at all. */
- meta->txstat.retry_count = 0;
+ info->status.retry_count = 0;
} else
- meta->txstat.retry_count = status->frame_count
+ info->status.retry_count = status->frame_count
- 1;
- ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb,
- &(meta->txstat));
+ ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
/* skb is freed by ieee80211_tx_status_irqsafe() */
meta->skb = NULL;
} else {
@@ -1455,18 +1491,16 @@ void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
{
const int nr_queues = dev->wl->hw->queues;
struct b43legacy_dmaring *ring;
- struct ieee80211_tx_queue_stats_data *data;
unsigned long flags;
int i;
for (i = 0; i < nr_queues; i++) {
- data = &(stats->data[i]);
ring = priority_to_txring(dev, i);
spin_lock_irqsave(&ring->lock, flags);
- data->len = ring->used_slots / SLOTS_PER_PACKET;
- data->limit = ring->nr_slots / SLOTS_PER_PACKET;
- data->count = ring->nr_tx_packets;
+ stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
+ stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
+ stats[i].count = ring->nr_tx_packets;
spin_unlock_irqrestore(&ring->lock, flags);
}
}
diff --git a/drivers/net/wireless/b43legacy/dma.h b/drivers/net/wireless/b43legacy/dma.h
index 2dd488c5be2..2f186003c31 100644
--- a/drivers/net/wireless/b43legacy/dma.h
+++ b/drivers/net/wireless/b43legacy/dma.h
@@ -195,7 +195,6 @@ struct b43legacy_dmadesc_meta {
dma_addr_t dmaaddr;
/* ieee80211 TX status. Only used once per 802.11 frag. */
bool is_last_fragment;
- struct ieee80211_tx_status txstat;
};
struct b43legacy_dmaring;
@@ -297,8 +296,7 @@ void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
struct ieee80211_tx_queue_stats *stats);
int b43legacy_dma_tx(struct b43legacy_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl);
+ struct sk_buff *skb);
void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
const struct b43legacy_txstatus *status);
@@ -323,8 +321,7 @@ void b43legacy_dma_get_tx_stats(struct b43legacy_wldev *dev,
}
static inline
int b43legacy_dma_tx(struct b43legacy_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
return 0;
}
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 3e612d0a13e..a1b8bf3ee73 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -846,10 +846,10 @@ static void handle_irq_noise(struct b43legacy_wldev *dev)
/* Get the noise samples. */
B43legacy_WARN_ON(dev->noisecalc.nr_samples >= 8);
i = dev->noisecalc.nr_samples;
- noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
- noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
- noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
- noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
+ noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]];
dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]];
dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]];
@@ -1138,14 +1138,22 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
/* Asynchronously update the packet templates in template RAM.
* Locking: Requires wl->irq_lock to be locked. */
-static void b43legacy_update_templates(struct b43legacy_wl *wl,
- struct sk_buff *beacon)
+static void b43legacy_update_templates(struct b43legacy_wl *wl)
{
+ struct sk_buff *beacon;
/* This is the top half of the ansynchronous beacon update. The bottom
* half is the beacon IRQ. Beacon update must be asynchronous to avoid
* sending an invalid beacon. This can happen for example, if the
* firmware transmits a beacon while we are updating it. */
+ /* We could modify the existing beacon and set the aid bit in the TIM
+ * field, but that would probably require resizing and moving of data
+ * within the beacon template. Simply request a new beacon and let
+ * mac80211 do the hard work. */
+ beacon = ieee80211_beacon_get(wl->hw, wl->vif);
+ if (unlikely(!beacon))
+ return;
+
if (wl->current_beacon)
dev_kfree_skb_any(wl->current_beacon);
wl->current_beacon = beacon;
@@ -2358,8 +2366,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
}
static int b43legacy_op_tx(struct ieee80211_hw *hw,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev = wl->current_dev;
@@ -2373,10 +2380,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
/* DMA-TX is done without a global lock. */
if (b43legacy_using_pio(dev)) {
spin_lock_irqsave(&wl->irq_lock, flags);
- err = b43legacy_pio_tx(dev, skb, ctl);
+ err = b43legacy_pio_tx(dev, skb);
spin_unlock_irqrestore(&wl->irq_lock, flags);
} else
- err = b43legacy_dma_tx(dev, skb, ctl);
+ err = b43legacy_dma_tx(dev, skb);
out:
if (unlikely(err)) {
/* Drop the packet. */
@@ -2385,8 +2392,7 @@ out:
return NETDEV_TX_OK;
}
-static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,
- int queue,
+static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
return 0;
@@ -2729,10 +2735,13 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
memset(wl->bssid, 0, ETH_ALEN);
if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) {
- B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
+ B43legacy_WARN_ON(vif->type != IEEE80211_IF_TYPE_AP);
b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len);
- if (conf->beacon)
- b43legacy_update_templates(wl, conf->beacon);
+ if (conf->changed & IEEE80211_IFCC_BEACON)
+ b43legacy_update_templates(wl);
+ } else if (b43legacy_is_mode(wl, IEEE80211_IF_TYPE_IBSS)) {
+ if (conf->changed & IEEE80211_IFCC_BEACON)
+ b43legacy_update_templates(wl);
}
b43legacy_write_mac_bssid_templates(dev);
}
@@ -2797,7 +2806,6 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
/* Start data flow (TX/RX) */
b43legacy_mac_enable(dev);
b43legacy_interrupt_enable(dev, dev->irq_savedstate);
- ieee80211_start_queues(dev->wl->hw);
/* Start maintenance work */
b43legacy_periodic_tasks_setup(dev);
@@ -3399,32 +3407,10 @@ static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
int aid, int set)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
- struct sk_buff *beacon;
- unsigned long flags;
-
- /* We could modify the existing beacon and set the aid bit in the TIM
- * field, but that would probably require resizing and moving of data
- * within the beacon template. Simply request a new beacon and let
- * mac80211 do the hard work. */
- beacon = ieee80211_beacon_get(hw, wl->vif, NULL);
- if (unlikely(!beacon))
- return -ENOMEM;
- spin_lock_irqsave(&wl->irq_lock, flags);
- b43legacy_update_templates(wl, beacon);
- spin_unlock_irqrestore(&wl->irq_lock, flags);
-
- return 0;
-}
-
-static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *beacon,
- struct ieee80211_tx_control *ctl)
-{
- struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
unsigned long flags;
spin_lock_irqsave(&wl->irq_lock, flags);
- b43legacy_update_templates(wl, beacon);
+ b43legacy_update_templates(wl);
spin_unlock_irqrestore(&wl->irq_lock, flags);
return 0;
@@ -3444,7 +3430,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
.stop = b43legacy_op_stop,
.set_retry_limit = b43legacy_op_set_retry_limit,
.set_tim = b43legacy_op_beacon_set_tim,
- .beacon_update = b43legacy_op_ibss_beacon_update,
};
/* Hard-reset the chip. Do not call this directly.
@@ -3718,10 +3703,9 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
/* fill hw info */
hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_RX_INCLUDES_FCS;
- hw->max_signal = 100;
- hw->max_rssi = -110;
- hw->max_noise = -110;
+ IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
hw->queues = 1; /* FIXME: hardware has more queues */
SET_IEEE80211_DEV(hw, dev->dev);
if (is_valid_ether_addr(sprom->et1mac))
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 8e5c09b8187..768cccb9b1b 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -1088,7 +1088,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev)
* the value 0x7FFFFFFF here. I think that is some weird
* compiler optimization in the original driver.
* Essentially, what we do here is resetting all NRSSI LT
- * entries to -32 (see the limit_value() in nrssi_hw_update())
+ * entries to -32 (see the clamp_val() in nrssi_hw_update())
*/
b43legacy_nrssi_hw_update(dev, 0xFFFF);
b43legacy_calc_nrssi_threshold(dev);
@@ -1756,7 +1756,7 @@ static s8 b43legacy_phy_estimate_power_out(struct b43legacy_wldev *dev, s8 tssi)
switch (phy->type) {
case B43legacy_PHYTYPE_B:
case B43legacy_PHYTYPE_G:
- tmp = limit_value(tmp, 0x00, 0x3F);
+ tmp = clamp_val(tmp, 0x00, 0x3F);
dbm = phy->tssi2dbm[tmp];
break;
default:
@@ -1859,7 +1859,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
/* find the desired power in Q5.2 - power_level is in dBm
* and limit it - max_pwr is already in Q5.2 */
- desired_pwr = limit_value(phy->power_level << 2, 0, max_pwr);
+ desired_pwr = clamp_val(phy->power_level << 2, 0, max_pwr);
if (b43legacy_debug(dev, B43legacy_DBG_XMITPOWER))
b43legacydbg(dev->wl, "Current TX power output: " Q52_FMT
" dBm, Desired TX power output: " Q52_FMT
@@ -1905,7 +1905,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
radio_attenuation++;
}
}
- baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
+ baseband_attenuation = clamp_val(baseband_attenuation, 0, 11);
txpower = phy->txctl1;
if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) {
@@ -1933,8 +1933,8 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
}
/* Save the control values */
phy->txctl1 = txpower;
- baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
- radio_attenuation = limit_value(radio_attenuation, 0, 9);
+ baseband_attenuation = clamp_val(baseband_attenuation, 0, 11);
+ radio_attenuation = clamp_val(radio_attenuation, 0, 9);
phy->rfatt = radio_attenuation;
phy->bbatt = baseband_attenuation;
@@ -1979,7 +1979,7 @@ s8 b43legacy_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2)
f = q;
i++;
} while (delta >= 2);
- entry[index] = limit_value(b43legacy_tssi2dbm_ad(m1 * f, 8192),
+ entry[index] = clamp_val(b43legacy_tssi2dbm_ad(m1 * f, 8192),
-127, 128);
return 0;
}
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index bcdd54eb2ed..a86c7647fa2 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -196,7 +196,7 @@ static int pio_tx_write_fragment(struct b43legacy_pioqueue *queue,
B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags != 0);
err = b43legacy_generate_txhdr(queue->dev,
txhdr, skb->data, skb->len,
- &packet->txstat.control,
+ IEEE80211_SKB_CB(skb),
generate_cookie(queue, packet));
if (err)
return err;
@@ -463,8 +463,7 @@ err_destroy0:
}
int b43legacy_pio_tx(struct b43legacy_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
struct b43legacy_pioqueue *queue = dev->pio.queue1;
struct b43legacy_pio_txpacket *packet;
@@ -476,9 +475,6 @@ int b43legacy_pio_tx(struct b43legacy_wldev *dev,
list);
packet->skb = skb;
- memset(&packet->txstat, 0, sizeof(packet->txstat));
- memcpy(&packet->txstat.control, ctl, sizeof(*ctl));
-
list_move_tail(&packet->list, &queue->txqueue);
queue->nr_txfree--;
queue->nr_tx_packets++;
@@ -494,6 +490,7 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
{
struct b43legacy_pioqueue *queue;
struct b43legacy_pio_txpacket *packet;
+ struct ieee80211_tx_info *info;
queue = parse_cookie(dev, status->cookie, &packet);
B43legacy_WARN_ON(!queue);
@@ -505,11 +502,13 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
queue->tx_devq_used -= (packet->skb->len +
sizeof(struct b43legacy_txhdr_fw3));
+ info = IEEE80211_SKB_CB(packet->skb);
+ memset(&info->status, 0, sizeof(info->status));
+
if (status->acked)
- packet->txstat.flags |= IEEE80211_TX_STATUS_ACK;
- packet->txstat.retry_count = status->frame_count - 1;
- ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb,
- &(packet->txstat));
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.retry_count = status->frame_count - 1;
+ ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb);
packet->skb = NULL;
free_txpacket(packet, 1);
@@ -525,13 +524,11 @@ void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
{
struct b43legacy_pio *pio = &dev->pio;
struct b43legacy_pioqueue *queue;
- struct ieee80211_tx_queue_stats_data *data;
queue = pio->queue1;
- data = &(stats->data[0]);
- data->len = B43legacy_PIO_MAXTXPACKETS - queue->nr_txfree;
- data->limit = B43legacy_PIO_MAXTXPACKETS;
- data->count = queue->nr_tx_packets;
+ stats[0].len = B43legacy_PIO_MAXTXPACKETS - queue->nr_txfree;
+ stats[0].limit = B43legacy_PIO_MAXTXPACKETS;
+ stats[0].count = queue->nr_tx_packets;
}
static void pio_rx_error(struct b43legacy_pioqueue *queue,
diff --git a/drivers/net/wireless/b43legacy/pio.h b/drivers/net/wireless/b43legacy/pio.h
index 5bfed0c4003..464fec05a06 100644
--- a/drivers/net/wireless/b43legacy/pio.h
+++ b/drivers/net/wireless/b43legacy/pio.h
@@ -41,7 +41,6 @@ struct b43legacy_xmitstatus;
struct b43legacy_pio_txpacket {
struct b43legacy_pioqueue *queue;
struct sk_buff *skb;
- struct ieee80211_tx_status txstat;
struct list_head list;
};
@@ -104,8 +103,7 @@ int b43legacy_pio_init(struct b43legacy_wldev *dev);
void b43legacy_pio_free(struct b43legacy_wldev *dev);
int b43legacy_pio_tx(struct b43legacy_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl);
+ struct sk_buff *skb);
void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
const struct b43legacy_txstatus *status);
void b43legacy_pio_get_tx_stats(struct b43legacy_wldev *dev,
@@ -132,8 +130,7 @@ void b43legacy_pio_free(struct b43legacy_wldev *dev)
}
static inline
int b43legacy_pio_tx(struct b43legacy_wldev *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+ struct sk_buff *skb)
{
return 0;
}
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index 955832e8654..2df545cfad1 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -357,7 +357,7 @@ void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val)
for (i = 0; i < 64; i++) {
tmp = b43legacy_nrssi_hw_read(dev, i);
tmp -= val;
- tmp = limit_value(tmp, -32, 31);
+ tmp = clamp_val(tmp, -32, 31);
b43legacy_nrssi_hw_write(dev, i, tmp);
}
}
@@ -375,7 +375,7 @@ void b43legacy_nrssi_mem_update(struct b43legacy_wldev *dev)
tmp = (i - delta) * phy->nrssislope;
tmp /= 0x10000;
tmp += 0x3A;
- tmp = limit_value(tmp, 0, 0x3F);
+ tmp = clamp_val(tmp, 0, 0x3F);
phy->nrssi_lt[i] = tmp;
}
}
@@ -839,7 +839,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev)
} else
threshold = phy->nrssi[1] - 5;
- threshold = limit_value(threshold, 0, 0x3E);
+ threshold = clamp_val(threshold, 0, 0x3E);
b43legacy_phy_read(dev, 0x0020); /* dummy read */
b43legacy_phy_write(dev, 0x0020, (((u16)threshold) << 8)
| 0x001C);
@@ -892,7 +892,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev)
else
a += 32;
a = a >> 6;
- a = limit_value(a, -31, 31);
+ a = clamp_val(a, -31, 31);
b = b * (phy->nrssi[1] - phy->nrssi[0]);
b += (phy->nrssi[0] << 6);
@@ -901,7 +901,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev)
else
b += 32;
b = b >> 6;
- b = limit_value(b, -31, 31);
+ b = clamp_val(b, -31, 31);
tmp_u16 = b43legacy_phy_read(dev, 0x048A) & 0xF000;
tmp_u16 |= ((u32)b & 0x0000003F);
@@ -1905,7 +1905,7 @@ void b43legacy_radio_set_txpower_a(struct b43legacy_wldev *dev, u16 txpower)
u16 dac;
u16 ilt;
- txpower = limit_value(txpower, 0, 63);
+ txpower = clamp_val(txpower, 0, 63);
pamp = b43legacy_get_txgain_freq_power_amp(txpower);
pamp <<= 5;
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index d178dfbb1c9..476add97e97 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -44,6 +44,23 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
return 0;
}
+/* Update the rfkill state */
+static void b43legacy_rfkill_update_state(struct b43legacy_wldev *dev)
+{
+ struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
+
+ if (!dev->radio_hw_enable) {
+ rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
+ return;
+ }
+
+ if (!dev->phy.radio_on)
+ rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
+ else
+ rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
+
+}
+
/* The poll callback for the hardware button. */
static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
{
@@ -61,6 +78,7 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
if (unlikely(enabled != dev->radio_hw_enable)) {
dev->radio_hw_enable = enabled;
report_change = 1;
+ b43legacy_rfkill_update_state(dev);
b43legacyinfo(wl, "Radio hardware status changed to %s\n",
enabled ? "ENABLED" : "DISABLED");
}
@@ -90,7 +108,7 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
goto out_unlock;
err = 0;
switch (state) {
- case RFKILL_STATE_ON:
+ case RFKILL_STATE_UNBLOCKED:
if (!dev->radio_hw_enable) {
/* No luck. We can't toggle the hardware RF-kill
* button from software. */
@@ -100,10 +118,14 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
if (!dev->phy.radio_on)
b43legacy_radio_turn_on(dev);
break;
- case RFKILL_STATE_OFF:
+ case RFKILL_STATE_SOFT_BLOCKED:
if (dev->phy.radio_on)
b43legacy_radio_turn_off(dev, 0);
break;
+ default:
+ b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
+ state);
+ break;
}
out_unlock:
@@ -135,7 +157,7 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
snprintf(rfk->name, sizeof(rfk->name),
"b43legacy-%s", wiphy_name(wl->hw->wiphy));
rfk->rfkill->name = rfk->name;
- rfk->rfkill->state = RFKILL_STATE_ON;
+ rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
rfk->rfkill->data = dev;
rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle;
rfk->rfkill->user_claim_unsupported = 1;
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index dcad2491a60..e969ed8d412 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -188,11 +188,11 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
struct b43legacy_txhdr_fw3 *txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
+ const struct ieee80211_tx_info *info,
u16 cookie)
{
const struct ieee80211_hdr *wlhdr;
- int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
+ int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT));
u16 fctl;
u8 rate;
struct ieee80211_rate *rate_fb;
@@ -201,15 +201,18 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
unsigned int plcp_fragment_len;
u32 mac_ctl = 0;
u16 phy_ctl = 0;
+ struct ieee80211_rate *tx_rate;
wlhdr = (const struct ieee80211_hdr *)fragment_data;
fctl = le16_to_cpu(wlhdr->frame_control);
memset(txhdr, 0, sizeof(*txhdr));
- rate = txctl->tx_rate->hw_value;
+ tx_rate = ieee80211_get_tx_rate(dev->wl->hw, info);
+
+ rate = tx_rate->hw_value;
rate_ofdm = b43legacy_is_ofdm_rate(rate);
- rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate;
+ rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : tx_rate;
rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
txhdr->mac_frame_ctl = wlhdr->frame_control;
@@ -225,14 +228,14 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
txhdr->dur_fb = wlhdr->duration_id;
} else {
txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
- txctl->vif,
+ info->control.vif,
fragment_len,
rate_fb);
}
plcp_fragment_len = fragment_len + FCS_LEN;
if (use_encryption) {
- u8 key_idx = (u16)(txctl->key_idx);
+ u8 key_idx = info->control.hw_key->hw_key_idx;
struct b43legacy_key *key;
int wlhdr_len;
size_t iv_len;
@@ -242,7 +245,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
if (key->enabled) {
/* Hardware appends ICV. */
- plcp_fragment_len += txctl->icv_len;
+ plcp_fragment_len += info->control.icv_len;
key_idx = b43legacy_kidx_to_fw(dev, key_idx);
mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
@@ -251,7 +254,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
B43legacy_TX4_MAC_KEYALG_SHIFT) &
B43legacy_TX4_MAC_KEYALG;
wlhdr_len = ieee80211_get_hdrlen(fctl);
- iv_len = min((size_t)txctl->iv_len,
+ iv_len = min((size_t)info->control.iv_len,
ARRAY_SIZE(txhdr->iv));
memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
} else {
@@ -275,7 +278,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
phy_ctl |= B43legacy_TX4_PHY_OFDM;
if (dev->short_preamble)
phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
- switch (txctl->antenna_sel_tx) {
+ switch (info->antenna_sel_tx) {
case 0:
phy_ctl |= B43legacy_TX4_PHY_ANTLAST;
break;
@@ -290,21 +293,20 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
}
/* MAC control */
- if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43legacy_TX4_MAC_ACK;
- if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
mac_ctl |= B43legacy_TX4_MAC_HWSEQ;
- if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
mac_ctl |= B43legacy_TX4_MAC_STMSDU;
if (rate_fb_ofdm)
mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM;
- if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+ if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
/* Generate the RTS or CTS-to-self frame */
- if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
- (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) {
+ if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+ (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
unsigned int len;
struct ieee80211_hdr *hdr;
int rts_rate;
@@ -312,26 +314,26 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
int rts_rate_ofdm;
int rts_rate_fb_ofdm;
- rts_rate = txctl->rts_cts_rate->hw_value;
+ rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value;
rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
if (rts_rate_fb_ofdm)
mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM;
- if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+ if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
ieee80211_ctstoself_get(dev->wl->hw,
- txctl->vif,
+ info->control.vif,
fragment_data,
- fragment_len, txctl,
+ fragment_len, info,
(struct ieee80211_cts *)
(txhdr->rts_frame));
mac_ctl |= B43legacy_TX4_MAC_SENDCTS;
len = sizeof(struct ieee80211_cts);
} else {
ieee80211_rts_get(dev->wl->hw,
- txctl->vif,
- fragment_data, fragment_len, txctl,
+ info->control.vif,
+ fragment_data, fragment_len, info,
(struct ieee80211_rts *)
(txhdr->rts_frame));
mac_ctl |= B43legacy_TX4_MAC_SENDRTS;
@@ -362,12 +364,12 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
u8 *txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
+ const struct ieee80211_tx_info *info,
u16 cookie)
{
return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
fragment_data, fragment_len,
- txctl, cookie);
+ info, cookie);
}
static s8 b43legacy_rssi_postprocess(struct b43legacy_wldev *dev,
@@ -439,7 +441,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
struct b43legacy_plcp_hdr6 *plcp;
struct ieee80211_hdr *wlhdr;
const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr;
- u16 fctl;
+ __le16 fctl;
u16 phystat0;
u16 phystat3;
u16 chanstat;
@@ -477,7 +479,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
goto drop;
}
wlhdr = (struct ieee80211_hdr *)(skb->data);
- fctl = le16_to_cpu(wlhdr->frame_control);
+ fctl = wlhdr->frame_control;
if ((macstat & B43legacy_RX_MAC_DEC) &&
!(macstat & B43legacy_RX_MAC_DECERR)) {
@@ -496,11 +498,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) {
/* Remove PROTECTED flag to mark it as decrypted. */
- B43legacy_WARN_ON(!(fctl & IEEE80211_FCTL_PROTECTED));
- fctl &= ~IEEE80211_FCTL_PROTECTED;
- wlhdr->frame_control = cpu_to_le16(fctl);
+ B43legacy_WARN_ON(!ieee80211_has_protected(fctl));
+ fctl &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ wlhdr->frame_control = fctl;
- wlhdr_len = ieee80211_get_hdrlen(fctl);
+ wlhdr_len = ieee80211_hdrlen(fctl);
if (unlikely(skb->len < (wlhdr_len + 3))) {
b43legacydbg(dev->wl, "RX: Packet size"
" underrun3\n");
@@ -532,12 +534,12 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
}
}
- status.ssi = b43legacy_rssi_postprocess(dev, jssi,
+ status.signal = b43legacy_rssi_postprocess(dev, jssi,
(phystat0 & B43legacy_RX_PHYST0_OFDM),
(phystat0 & B43legacy_RX_PHYST0_GAINCTL),
(phystat3 & B43legacy_RX_PHYST3_TRSTATE));
status.noise = dev->stats.link_noise;
- status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI;
+ status.qual = (jssi * 100) / B43legacy_RX_MAX_SSI;
/* change to support A PHY */
if (phystat0 & B43legacy_RX_PHYST0_OFDM)
status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
@@ -553,9 +555,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
* of timestamp, i.e. about 65 milliseconds after the PHY received
* the first symbol.
*/
- if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
- == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) ||
- dev->wl->radiotap_enabled) {
+ if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
u16 low_mactime_now;
b43legacy_tsf_read(dev, &status.mactime);
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h
index bab47928a0c..e56777e0fea 100644
--- a/drivers/net/wireless/b43legacy/xmit.h
+++ b/drivers/net/wireless/b43legacy/xmit.h
@@ -80,7 +80,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
u8 *txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_control *txctl,
+ const struct ieee80211_tx_info *info,
u16 cookie);
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 547ba84dc79..3a386a636cc 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 020f450e9db..f106bc1585a 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -78,6 +78,9 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
prism_header = 2;
phdrlen = sizeof(struct linux_wlan_ng_cap_hdr);
}
+ } else if (dev->type == ARPHRD_IEEE80211_RADIOTAP) {
+ prism_header = 3;
+ phdrlen = sizeof(struct hostap_radiotap_rx);
} else {
prism_header = 0;
phdrlen = 0;
@@ -165,6 +168,24 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
hdr->ssi_noise = htonl(rx_stats->noise);
hdr->preamble = htonl(0); /* unknown */
hdr->encoding = htonl(1); /* cck */
+ } else if (prism_header == 3) {
+ struct hostap_radiotap_rx *hdr;
+ hdr = (struct hostap_radiotap_rx *)skb_push(skb, phdrlen);
+ memset(hdr, 0, phdrlen);
+ hdr->hdr.it_len = cpu_to_le16(phdrlen);
+ hdr->hdr.it_present =
+ cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
+ (1 << IEEE80211_RADIOTAP_CHANNEL) |
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE));
+ hdr->tsft = cpu_to_le64(rx_stats->mac_time);
+ hdr->chan_freq = cpu_to_le16(freq_list[local->channel - 1]);
+ hdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_CCK |
+ IEEE80211_CHAN_2GHZ);
+ hdr->rate = rx_stats->rate / 5;
+ hdr->dbm_antsignal = rx_stats->signal;
+ hdr->dbm_antnoise = rx_stats->noise;
}
ret = skb->len - phdrlen;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index ab981afd481..af3d4ef2a80 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
/* Translate our list of Access Points & Stations to a card independant
* format that the Wireless Tools will understand - Jean II */
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer)
{
struct hostap_interface *iface;
local_info_t *local;
@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Use the mode to indicate if it's a station or
* an Access Point */
@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
else
iwe.u.mode = IW_MODE_INFRA;
iwe.len = IW_EV_UINT_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Some quality */
memset(&iwe, 0, sizeof(iwe));
@@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
iwe.u.qual.updated = sta->last_rx_updated;
iwe.len = IW_EV_QUAL_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (sta->ap) {
@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = sta->u.ap.ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
sta->u.ap.ssid);
memset(&iwe, 0, sizeof(iwe));
@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
- sta->u.ap.ssid
- /* 0 byte memcpy */);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
+ sta->u.ap.ssid);
if (sta->u.ap.channel > 0 &&
sta->u.ap.channel <= FREQ_COUNT) {
@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
* 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(
- current_ev, end_buf, &iwe,
+ info, current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
sprintf(buf, "beacon_interval=%d",
sta->listen_interval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 936f52e3d95..13d5882f1f2 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3102,6 +3102,18 @@ static void prism2_clear_set_tim_queue(local_info_t *local)
*/
static struct lock_class_key hostap_netdev_xmit_lock_key;
+static void prism2_set_lockdep_class_one(struct net_device *dev,
+ struct netdev_queue *txq,
+ void *_unused)
+{
+ lockdep_set_class(&txq->_xmit_lock,
+ &hostap_netdev_xmit_lock_key);
+}
+
+static void prism2_set_lockdep_class(struct net_device *dev)
+{
+ netdev_for_each_tx_queue(dev, prism2_set_lockdep_class_one, NULL);
+}
static struct net_device *
prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
@@ -3204,6 +3216,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY;
local->sram_type = -1;
local->scan_channel_mask = 0xffff;
+ local->monitor_type = PRISM2_MONITOR_RADIOTAP;
/* Initialize task queue structures */
INIT_WORK(&local->reset_queue, handle_reset_queue);
@@ -3267,7 +3280,7 @@ while (0)
if (ret >= 0)
ret = register_netdevice(dev);
- lockdep_set_class(&dev->_xmit_lock, &hostap_netdev_xmit_lock_key);
+ prism2_set_lockdep_class(dev);
rtnl_unlock();
if (ret < 0) {
printk(KERN_WARNING "%s: register netdevice failed!\n",
@@ -3416,7 +3429,7 @@ static void prism2_free_local_data(struct net_device *dev)
}
-#ifndef PRISM2_PLX
+#if (defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
static void prism2_suspend(struct net_device *dev)
{
struct hostap_interface *iface;
@@ -3435,7 +3448,7 @@ static void prism2_suspend(struct net_device *dev)
/* Disable hardware and firmware */
prism2_hw_shutdown(dev, 0);
}
-#endif /* PRISM2_PLX */
+#endif /* (PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD */
/* These might at some point be compiled separately and used as separate
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 0ca0bfeb0ad..3f8b1d7036e 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -897,6 +897,8 @@ static void hostap_monitor_set_type(local_info_t *local)
if (local->monitor_type == PRISM2_MONITOR_PRISM ||
local->monitor_type == PRISM2_MONITOR_CAPHDR) {
dev->type = ARPHRD_IEEE80211_PRISM;
+ } else if (local->monitor_type == PRISM2_MONITOR_RADIOTAP) {
+ dev->type = ARPHRD_IEEE80211_RADIOTAP;
} else {
dev->type = ARPHRD_IEEE80211;
}
@@ -1793,6 +1795,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
#ifndef PRISM2_NO_STATION_MODES
static char * __prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
struct hfa384x_hostscan_result *scan,
struct hostap_bss_info *bss,
char *current_ev, char *end_buf)
@@ -1823,7 +1826,7 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -1832,7 +1835,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE;
@@ -1847,8 +1851,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1864,8 +1868,8 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[chan - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
}
if (scan) {
@@ -1884,8 +1888,8 @@ static char * __prism2_translate_scan(local_info_t *local,
| IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1895,13 +1899,13 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
if (scan) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWRATE;
- current_val = current_ev + IW_EV_LCP_LEN;
+ current_val = current_ev + iwe_stream_lcp_len(info);
pos = scan->sup_rates;
for (i = 0; i < sizeof(scan->sup_rates); i++) {
if (pos[i] == 0)
@@ -1909,11 +1913,11 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
current_val = iwe_stream_add_value(
- current_ev, current_val, end_buf, &iwe,
+ info, current_ev, current_val, end_buf, &iwe,
IW_EV_PARAM_LEN);
}
/* Check if we added any event */
- if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val;
}
@@ -1924,15 +1928,15 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
if (local->last_scan_type == PRISM2_HOSTSCAN &&
(capabilities & WLAN_CAPABILITY_IBSS)) {
@@ -1940,8 +1944,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
}
kfree(buf);
@@ -1950,16 +1954,16 @@ static char * __prism2_translate_scan(local_info_t *local,
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
return current_ev;
@@ -1969,6 +1973,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Translate scan data returned from the card to a card independant
* format that the Wireless Tools will understand - Jean II */
static inline int prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
char *buffer, int buflen)
{
struct hfa384x_hostscan_result *scan;
@@ -1999,13 +2004,14 @@ static inline int prism2_translate_scan(local_info_t *local,
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
bss->included = 1;
current_ev = __prism2_translate_scan(
- local, scan, bss, current_ev, end_buf);
+ local, info, scan, bss, current_ev,
+ end_buf);
found++;
}
}
if (!found) {
current_ev = __prism2_translate_scan(
- local, scan, NULL, current_ev, end_buf);
+ local, info, scan, NULL, current_ev, end_buf);
}
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2023,7 +2029,7 @@ static inline int prism2_translate_scan(local_info_t *local,
bss = list_entry(ptr, struct hostap_bss_info, list);
if (bss->included)
continue;
- current_ev = __prism2_translate_scan(local, NULL, bss,
+ current_ev = __prism2_translate_scan(local, info, NULL, bss,
current_ev, end_buf);
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2070,7 +2076,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
}
local->scan_timestamp = 0;
- res = prism2_translate_scan(local, extra, data->length);
+ res = prism2_translate_scan(local, info, extra, data->length);
if (res >= 0) {
data->length = res;
@@ -2103,7 +2109,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
* Jean II */
/* Translate to WE format */
- res = prism2_ap_translate_scan(dev, extra);
+ res = prism2_ap_translate_scan(dev, info, extra);
if (res >= 0) {
printk(KERN_DEBUG "Scan result translation succeeded "
"(length=%d)\n", res);
@@ -2516,7 +2522,8 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
case PRISM2_PARAM_MONITOR_TYPE:
if (value != PRISM2_MONITOR_80211 &&
value != PRISM2_MONITOR_CAPHDR &&
- value != PRISM2_MONITOR_PRISM) {
+ value != PRISM2_MONITOR_PRISM &&
+ value != PRISM2_MONITOR_RADIOTAP) {
ret = -EINVAL;
break;
}
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index a38e85f334d..756ab56c1f4 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -597,25 +597,7 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
static int hostap_80211_header_parse(const struct sk_buff *skb,
unsigned char *haddr)
{
- struct hostap_interface *iface = netdev_priv(skb->dev);
- local_info_t *local = iface->local;
-
- if (local->monitor_type == PRISM2_MONITOR_PRISM ||
- local->monitor_type == PRISM2_MONITOR_CAPHDR) {
- const unsigned char *mac = skb_mac_header(skb);
-
- if (*(u32 *)mac == LWNG_CAP_DID_BASE) {
- memcpy(haddr,
- mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10,
- ETH_ALEN); /* addr2 */
- } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */
- memcpy(haddr,
- mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10,
- ETH_ALEN); /* addr2 */
- }
- } else
- memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
-
+ memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
return ETH_ALEN;
}
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index 15445bce2ac..ffdf4876121 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -5,6 +5,7 @@
#include <linux/netdevice.h>
#include <linux/mutex.h>
#include <net/iw_handler.h>
+#include <net/ieee80211_radiotap.h>
#include "hostap_config.h"
#include "hostap_common.h"
@@ -55,6 +56,17 @@ struct linux_wlan_ng_cap_hdr {
__be32 encoding;
} __attribute__ ((packed));
+struct hostap_radiotap_rx {
+ struct ieee80211_radiotap_header hdr;
+ __le64 tsft;
+ u8 rate;
+ u8 padding;
+ __le16 chan_freq;
+ __le16 chan_flags;
+ s8 dbm_antsignal;
+ s8 dbm_antnoise;
+} __attribute__ ((packed));
+
#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */
#define LWNG_CAPHDR_VERSION 0x80211001
@@ -734,7 +746,7 @@ struct local_info {
unsigned long scan_timestamp; /* Time started to scan */
enum {
PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
- PRISM2_MONITOR_CAPHDR = 2
+ PRISM2_MONITOR_CAPHDR = 2, PRISM2_MONITOR_RADIOTAP = 3
} monitor_type;
int monitor_allow_fcserr;
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 62fb89d8231..82b66a3d3a5 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -8,7 +8,6 @@ config IWLCORE
select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS
select RFKILL if IWLWIFI_RFKILL
- select RFKILL_INPUT if IWLWIFI_RFKILL
config IWLWIFI_LEDS
bool
@@ -45,14 +44,6 @@ config IWL4965
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl4965.ko.
-config IWL4965_HT
- bool "Enable 802.11n HT features in iwl4965 driver"
- depends on EXPERIMENTAL
- depends on IWL4965
- ---help---
- This option enables IEEE 802.11n High Throughput features
- for the iwl4965 driver.
-
config IWL4965_LEDS
bool "Enable LEDS features in iwl4965 driver"
depends on IWL4965
@@ -67,13 +58,6 @@ config IWL4965_SPECTRUM_MEASUREMENT
---help---
This option will enable spectrum measurement for the iwl4965 driver.
-config IWL4965_SENSITIVITY
- bool "Enable Sensitivity Calibration in iwl4965 driver"
- depends on IWL4965
- ---help---
- This option will enable sensitivity calibration for the iwl4965
- driver.
-
config IWLWIFI_DEBUG
bool "Enable full debugging output in iwl4965 driver"
depends on IWL4965
@@ -85,13 +69,13 @@ config IWLWIFI_DEBUG
control which debug output is sent to the kernel log by setting the
value in
- /sys/bus/pci/drivers/${DRIVER}/debug_level
+ /sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
- % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
+ % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlwifi/iwl-4965-debug.h
@@ -100,6 +84,13 @@ config IWLWIFI_DEBUG
as the debug information can assist others in helping you resolve
any problems you may encounter.
+config IWL5000
+ bool "Intel Wireless WiFi 5000AGN"
+ depends on IWL4965
+ ---help---
+ This option enables support for Intel Wireless WiFi Link 5000AGN Family
+ Dependency on 4965 is temporary
+
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
@@ -113,6 +104,7 @@ config IWL3945
select IWLWIFI
select MAC80211_LEDS if IWL3945_LEDS
select LEDS_CLASS if IWL3945_LEDS
+ select RFKILL if IWL3945_RFKILL
---help---
Select to build the driver supporting the:
@@ -135,6 +127,10 @@ config IWL3945
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.ko.
+config IWL3945_RFKILL
+ bool "Enable RF kill support in iwl3945 drivers"
+ depends on IWL3945
+
config IWL3945_SPECTRUM_MEASUREMENT
bool "Enable Spectrum Measurement in iwl3945 drivers"
depends on IWL3945
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index ec6187b75c3..1f52b92f08b 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,5 +1,7 @@
obj-$(CONFIG_IWLCORE) += iwlcore.o
-iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o
+iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
+iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
+iwlcore-objs += iwl-scan.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
@@ -9,5 +11,10 @@ iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
obj-$(CONFIG_IWL4965) += iwl4965.o
-iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o
+iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o
+
+ifeq ($(CONFIG_IWL5000),y)
+ iwl4965-objs += iwl-5000.o
+endif
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index ad612a8719f..644bd9e0805 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -126,7 +126,7 @@ enum {
EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
- EEPROM_CHANNEL_NARROW = (1 << 6), /* 10 MHz channel (not used) */
+ /* Bit 6 Reserved (was Narrow Channel) */
EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
};
@@ -289,17 +289,6 @@ struct iwl3945_eeprom {
#define PCI_REG_WUM8 0x0E8
#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
-/* SCD (3945 Tx Frame Scheduler) */
-#define SCD_BASE (CSR_BASE + 0x2E00)
-
-#define SCD_MODE_REG (SCD_BASE + 0x000)
-#define SCD_ARASTAT_REG (SCD_BASE + 0x004)
-#define SCD_TXFACT_REG (SCD_BASE + 0x010)
-#define SCD_TXF4MF_REG (SCD_BASE + 0x014)
-#define SCD_TXF5MF_REG (SCD_BASE + 0x020)
-#define SCD_SBYP_MODE_1_REG (SCD_BASE + 0x02C)
-#define SCD_SBYP_MODE_2_REG (SCD_BASE + 0x030)
-
/*=== FH (data Flow Handler) ===*/
#define FH_BASE (0x800)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 8b1528e52d4..6be1fe13fa5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -42,14 +42,11 @@
#include "iwl-3945.h"
#include "iwl-helpers.h"
-#define IWL_1MB_RATE (128 * 1024)
-#define IWL_LED_THRESHOLD (16)
-#define IWL_MAX_BLINK_TBL (10)
static const struct {
u16 brightness;
u8 on_time;
- u8 of_time;
+ u8 off_time;
} blink_tbl[] =
{
{300, 25, 25},
@@ -61,9 +58,16 @@ static const struct {
{15, 95, 95 },
{10, 110, 110},
{5, 130, 130},
- {0, 167, 167}
+ {0, 167, 167},
+ /*SOLID_ON*/
+ {-1, IWL_LED_SOLID, 0}
};
+#define IWL_1MB_RATE (128 * 1024)
+#define IWL_LED_THRESHOLD (16)
+#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
+#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
+
static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv,
struct iwl3945_cmd *cmd,
struct sk_buff *skb)
@@ -71,6 +75,10 @@ static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv,
return 1;
}
+static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
+{
+ return fls(0x000000FF & (u32)brightness);
+}
/* Send led command */
static int iwl_send_led_cmd(struct iwl3945_priv *priv,
@@ -81,49 +89,45 @@ static int iwl_send_led_cmd(struct iwl3945_priv *priv,
.len = sizeof(struct iwl3945_led_cmd),
.data = led_cmd,
.meta.flags = CMD_ASYNC,
- .meta.u.callback = iwl3945_led_cmd_callback
+ .meta.u.callback = iwl3945_led_cmd_callback,
};
return iwl3945_send_cmd(priv, &cmd);
}
+
/* Set led on command */
-static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
+ unsigned int idx)
{
struct iwl3945_led_cmd led_cmd = {
.id = led_id,
- .on = IWL_LED_SOLID,
- .off = 0,
.interval = IWL_DEF_LED_INTRVL
};
+
+ BUG_ON(idx > IWL_MAX_BLINK_TBL);
+
+ led_cmd.on = blink_tbl[idx].on_time;
+ led_cmd.off = blink_tbl[idx].off_time;
+
return iwl_send_led_cmd(priv, &led_cmd);
}
+
+#if 1
/* Set led on command */
-static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
- enum led_brightness brightness)
+static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
{
struct iwl3945_led_cmd led_cmd = {
.id = led_id,
- .on = brightness,
- .off = brightness,
+ .on = IWL_LED_SOLID,
+ .off = 0,
.interval = IWL_DEF_LED_INTRVL
};
- if (brightness == LED_FULL) {
- led_cmd.on = IWL_LED_SOLID;
- led_cmd.off = 0;
- }
return iwl_send_led_cmd(priv, &led_cmd);
}
-/* Set led register off */
-static int iwl3945_led_on_reg(struct iwl3945_priv *priv, int led_id)
-{
- IWL_DEBUG_LED("led on %d\n", led_id);
- return iwl3945_led_on(priv, led_id);
-}
-
/* Set led off command */
static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
{
@@ -136,27 +140,7 @@ static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
IWL_DEBUG_LED("led off %d\n", led_id);
return iwl_send_led_cmd(priv, &led_cmd);
}
-
-/* Set led register off */
-static int iwl3945_led_off_reg(struct iwl3945_priv *priv, int led_id)
-{
- iwl3945_led_off(priv, led_id);
- return 0;
-}
-
-/* Set led blink command */
-static int iwl3945_led_not_solid(struct iwl3945_priv *priv, int led_id,
- u8 brightness)
-{
- struct iwl3945_led_cmd led_cmd = {
- .id = led_id,
- .on = brightness,
- .off = brightness,
- .interval = IWL_DEF_LED_INTRVL
- };
-
- return iwl_send_led_cmd(priv, &led_cmd);
-}
+#endif
/*
@@ -206,8 +190,10 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
led->led_off(priv, IWL_LED_LINK);
break;
default:
- if (led->led_pattern)
- led->led_pattern(priv, IWL_LED_LINK, brightness);
+ if (led->led_pattern) {
+ int idx = iwl3945_brightness_to_idx(brightness);
+ led->led_pattern(priv, IWL_LED_LINK, idx);
+ }
break;
}
}
@@ -252,24 +238,20 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
static inline u8 get_blink_rate(struct iwl3945_priv *priv)
{
int index;
- u8 blink_rate;
-
- if (priv->rxtxpackets < IWL_LED_THRESHOLD)
- index = 10;
- else {
- for (index = 0; index < IWL_MAX_BLINK_TBL; index++) {
- if (priv->rxtxpackets > (blink_tbl[index].brightness *
- IWL_1MB_RATE))
- break;
- }
- }
- /* if 0 frame is transfered */
- if ((index == IWL_MAX_BLINK_TBL) || !priv->allow_blinking)
- blink_rate = IWL_LED_SOLID;
- else
- blink_rate = blink_tbl[index].on_time;
+ u64 current_tpt = priv->rxtxpackets;
+ s64 tpt = current_tpt - priv->led_tpt;
- return blink_rate;
+ if (tpt < 0)
+ tpt = -tpt;
+ priv->led_tpt = current_tpt;
+
+ if (!priv->allow_blinking)
+ index = IWL_MAX_BLINK_TBL;
+ else
+ for (index = 0; index < IWL_MAX_BLINK_TBL; index++)
+ if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE))
+ break;
+ return index;
}
static inline int is_rf_kill(struct iwl3945_priv *priv)
@@ -285,7 +267,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv)
*/
void iwl3945_led_background(struct iwl3945_priv *priv)
{
- u8 blink_rate;
+ u8 blink_idx;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
priv->last_blink_time = 0;
@@ -298,9 +280,10 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
if (!priv->allow_blinking) {
priv->last_blink_time = 0;
- if (priv->last_blink_rate != IWL_LED_SOLID) {
- priv->last_blink_rate = IWL_LED_SOLID;
- iwl3945_led_on(priv, IWL_LED_LINK);
+ if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
+ priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
+ iwl3945_led_pattern(priv, IWL_LED_LINK,
+ IWL_SOLID_BLINK_IDX);
}
return;
}
@@ -309,21 +292,14 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
msecs_to_jiffies(1000)))
return;
- blink_rate = get_blink_rate(priv);
+ blink_idx = get_blink_rate(priv);
/* call only if blink rate change */
- if (blink_rate != priv->last_blink_rate) {
- if (blink_rate != IWL_LED_SOLID) {
- priv->last_blink_time = jiffies +
- msecs_to_jiffies(1000);
- iwl3945_led_not_solid(priv, IWL_LED_LINK, blink_rate);
- } else {
- priv->last_blink_time = 0;
- iwl3945_led_on(priv, IWL_LED_LINK);
- }
- }
+ if (blink_idx != priv->last_blink_rate)
+ iwl3945_led_pattern(priv, IWL_LED_LINK, blink_idx);
- priv->last_blink_rate = blink_rate;
+ priv->last_blink_time = jiffies;
+ priv->last_blink_rate = blink_idx;
priv->rxtxpackets = 0;
}
@@ -337,6 +313,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
priv->last_blink_rate = 0;
priv->rxtxpackets = 0;
+ priv->led_tpt = 0;
priv->last_blink_time = 0;
priv->allow_blinking = 0;
@@ -344,8 +321,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
snprintf(name, sizeof(name), "iwl-%s:radio",
wiphy_name(priv->hw->wiphy));
- priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on_reg;
- priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off_reg;
+ priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
+ priv->led[IWL_LED_TRG_RADIO].led_off = iwl3945_led_off;
priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
ret = iwl3945_led_register_led(priv,
@@ -364,8 +341,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
IWL_LED_TRG_ASSOC, 0,
name, trigger);
/* for assoc always turn led on */
- priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on_reg;
- priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on_reg;
+ priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
+ priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
if (ret)
@@ -391,6 +368,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(name, sizeof(name), "iwl-%s:TX",
wiphy_name(priv->hw->wiphy));
+
ret = iwl3945_led_register_led(priv,
&priv->led[IWL_LED_TRG_TX],
IWL_LED_TRG_TX, 0,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index b1d2f6b8b25..47b7e0bac80 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -54,7 +54,7 @@ struct iwl3945_led {
int (*led_on) (struct iwl3945_priv *priv, int led_id);
int (*led_off) (struct iwl3945_priv *priv, int led_id);
int (*led_pattern) (struct iwl3945_priv *priv, int led_id,
- enum led_brightness brightness);
+ unsigned int idx);
enum led_type type;
unsigned int registered;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 85c22641542..10c64bdb314 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -29,7 +29,6 @@
#include <linux/skbuff.h>
#include <linux/wireless.h>
#include <net/mac80211.h>
-#include <net/ieee80211.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -446,8 +445,7 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
*/
static void rs_tx_status(void *priv_rate,
struct net_device *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_status *tx_resp)
+ struct sk_buff *skb)
{
u8 retries, current_count;
int scale_rate_index, first_index, last_index;
@@ -458,14 +456,15 @@ static void rs_tx_status(void *priv_rate,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct iwl3945_rs_sta *rs_sta;
struct ieee80211_supported_band *sband;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
IWL_DEBUG_RATE("enter\n");
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
- retries = tx_resp->retry_count;
- first_index = tx_resp->control.tx_rate->hw_value;
+ retries = info->status.retry_count;
+ first_index = sband->bitrates[info->tx_rate_idx].hw_value;
if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
return;
@@ -526,11 +525,11 @@ static void rs_tx_status(void *priv_rate,
/* Update the last index window with success/failure based on ACK */
IWL_DEBUG_RATE("Update rate %d with %s.\n",
last_index,
- (tx_resp->flags & IEEE80211_TX_STATUS_ACK) ?
+ (info->flags & IEEE80211_TX_STAT_ACK) ?
"success" : "failure");
iwl3945_collect_tx_data(rs_sta,
&rs_sta->win[last_index],
- tx_resp->flags & IEEE80211_TX_STATUS_ACK, 1);
+ info->flags & IEEE80211_TX_STAT_ACK, 1);
/* We updated the rate scale window -- if its been more than
* flush_time since the last run, schedule the flush
@@ -670,7 +669,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
is_multicast_ether_addr(hdr->addr1) ||
!sta || !sta->rate_ctrl_priv) {
IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
- sel->rate = rate_lowest(local, sband, sta);
+ sel->rate_idx = rate_lowest_index(local, sband, sta);
rcu_read_unlock();
return;
}
@@ -814,7 +813,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
IWL_DEBUG_RATE("leave: %d\n", index);
- sel->rate = &sband->bitrates[sta->txrate_idx];
+ sel->rate_idx = sta->txrate_idx;
}
static struct rate_control_ops rs_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 55ac850744b..c2a76785b66 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -283,8 +283,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
tx_info = &txq->txb[txq->q.read_ptr];
- ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0],
- &tx_info->status);
+ ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
tx_info->skb[0] = NULL;
iwl3945_hw_txq_free_tfd(priv, txq);
}
@@ -306,7 +305,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct ieee80211_tx_status *tx_status;
+ struct ieee80211_tx_info *info;
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status);
int rate_idx;
@@ -319,19 +318,22 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
return;
}
- tx_status = &(txq->txb[txq->q.read_ptr].status);
+ info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
+ memset(&info->status, 0, sizeof(info->status));
- tx_status->retry_count = tx_resp->failure_frame;
+ info->status.retry_count = tx_resp->failure_frame;
/* tx_status->rts_retry_count = tx_resp->failure_rts; */
- tx_status->flags = ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
- IEEE80211_TX_STATUS_ACK : 0;
+ info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
+ IEEE80211_TX_STAT_ACK : 0;
IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
txq_id, iwl3945_get_tx_fail_reason(status), status,
tx_resp->rate, tx_resp->failure_frame);
rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
- tx_status->control.tx_rate = &priv->ieee_rates[rate_idx];
+ if (info->band == IEEE80211_BAND_5GHZ)
+ rate_idx -= IWL_FIRST_OFDM_RATE;
+ info->tx_rate_idx = rate_idx;
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
iwl3945_tx_queue_reclaim(priv, txq_id, index);
@@ -386,7 +388,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
u32 print_dump = 0; /* set to 1 to dump all frames' contents */
u32 hundred = 0;
u32 dataframe = 0;
- u16 fc;
+ __le16 fc;
u16 seq_ctl;
u16 channel;
u16 phy_flags;
@@ -405,7 +407,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
u8 *data = IWL_RX_DATA(pkt);
/* MAC header */
- fc = le16_to_cpu(header->frame_control);
+ fc = header->frame_control;
seq_ctl = le16_to_cpu(header->seq_ctrl);
/* metadata */
@@ -429,8 +431,8 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
/* if data frame is to us and all is good,
* (optionally) print summary for only 1 out of every 100 */
- if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
- (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
+ if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
+ cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
dataframe = 1;
if (!group100)
print_summary = 1; /* print each frame */
@@ -453,13 +455,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
if (hundred)
title = "100Frames";
- else if (fc & IEEE80211_FCTL_RETRY)
+ else if (ieee80211_has_retry(fc))
title = "Retry";
- else if (ieee80211_is_assoc_response(fc))
+ else if (ieee80211_is_assoc_resp(fc))
title = "AscRsp";
- else if (ieee80211_is_reassoc_response(fc))
+ else if (ieee80211_is_reassoc_resp(fc))
title = "RasRsp";
- else if (ieee80211_is_probe_response(fc)) {
+ else if (ieee80211_is_probe_resp(fc)) {
title = "PrbRsp";
print_dump = 1; /* dump frame contents */
} else if (ieee80211_is_beacon(fc)) {
@@ -488,14 +490,14 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
if (dataframe)
IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
"len=%u, rssi=%d, chnl=%d, rate=%d, \n",
- title, fc, header->addr1[5],
+ title, le16_to_cpu(fc), header->addr1[5],
length, rssi, channel, rate);
else {
/* src/dst addresses assume managed mode */
IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
"src=0x%02x, rssi=%u, tim=%lu usec, "
"phy=0x%02x, chnl=%d\n",
- title, fc, header->addr1[5],
+ title, le16_to_cpu(fc), header->addr1[5],
header->addr3[5], rssi,
tsf_low - priv->scan_start_tsf,
phy_flags, channel);
@@ -512,6 +514,23 @@ static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
}
#endif
+/* This is necessary only for a number of statistics, see the caller. */
+static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
+ struct ieee80211_hdr *header)
+{
+ /* Filter incoming packets to determine if they are targeted toward
+ * this network, discarding packets coming from ourselves */
+ switch (priv->iw_mode) {
+ case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
+ /* packets to our IBSS update information */
+ return !compare_ether_addr(header->addr3, priv->bssid);
+ case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
+ /* packets to our IBSS update information */
+ return !compare_ether_addr(header->addr2, priv->bssid);
+ default:
+ return 1;
+ }
+}
static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
struct sk_buff *skb,
@@ -520,7 +539,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
{
/* First cache any information we need before we overwrite
* the information provided in the skb from the hardware */
- s8 signal = stats->ssi;
+ s8 signal = stats->signal;
s8 noise = 0;
int rate = stats->rate_idx;
u64 tsf = stats->mactime;
@@ -606,12 +625,12 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
stats->flag |= RX_FLAG_RADIOTAP;
}
-static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
+static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
struct iwl3945_rx_mem_buffer *rxb,
struct ieee80211_rx_status *stats)
{
- struct ieee80211_hdr *hdr;
struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
short len = le16_to_cpu(rx_hdr->len);
@@ -633,8 +652,6 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
/* Set the size of the skb to the size of the frame */
skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
- hdr = (void *)rxb->skb->data;
-
if (iwl3945_param_hwcrypto)
iwl3945_set_decrypted_flag(priv, rxb->skb,
le32_to_cpu(rx_end->status), stats);
@@ -643,7 +660,7 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
iwl3945_add_radiotap(priv, rxb->skb, rx_hdr, stats);
#ifdef CONFIG_IWL3945_LEDS
- if (is_data)
+ if (ieee80211_is_data(hdr->frame_control))
priv->rxtxpackets += len;
#endif
ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
@@ -692,12 +709,12 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
}
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
- iwl3945_handle_data_packet(priv, 1, rxb, &rx_status);
+ iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
return;
}
/* Convert 3945's rssi indicator to dBm */
- rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET;
+ rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
/* Set default noise value to -127 */
if (priv->last_rx_noise == 0)
@@ -716,21 +733,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
* Calculate rx_status.signal (quality indicator in %) based on SNR. */
if (rx_stats_noise_diff) {
snr = rx_stats_sig_avg / rx_stats_noise_diff;
- rx_status.noise = rx_status.ssi -
+ rx_status.noise = rx_status.signal -
iwl3945_calc_db_from_ratio(snr);
- rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi,
+ rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal,
rx_status.noise);
/* If noise info not available, calculate signal quality indicator (%)
* using just the dBm signal level. */
} else {
rx_status.noise = priv->last_rx_noise;
- rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0);
+ rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0);
}
IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
- rx_status.ssi, rx_status.noise, rx_status.signal,
+ rx_status.signal, rx_status.noise, rx_status.qual,
rx_stats_sig_avg, rx_stats_noise_diff);
header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
@@ -740,8 +757,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
network_packet ? '*' : ' ',
le16_to_cpu(rx_hdr->channel),
- rx_status.ssi, rx_status.ssi,
- rx_status.ssi, rx_status.rate_idx);
+ rx_status.signal, rx_status.signal,
+ rx_status.noise, rx_status.rate_idx);
#ifdef CONFIG_IWL3945_DEBUG
if (iwl3945_debug_level & (IWL_DL_RX))
@@ -752,7 +769,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
priv->last_tsf = le64_to_cpu(rx_end->timestamp);
- priv->last_rx_rssi = rx_status.ssi;
+ priv->last_rx_rssi = rx_status.signal;
priv->last_rx_noise = rx_status.noise;
}
@@ -840,27 +857,12 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
}
}
- iwl3945_handle_data_packet(priv, 0, rxb, &rx_status);
- break;
-
- case IEEE80211_FTYPE_CTL:
- break;
-
- case IEEE80211_FTYPE_DATA: {
- DECLARE_MAC_BUF(mac1);
- DECLARE_MAC_BUF(mac2);
- DECLARE_MAC_BUF(mac3);
-
- if (unlikely(iwl3945_is_duplicate_packet(priv, header)))
- IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
- print_mac(mac1, header->addr1),
- print_mac(mac2, header->addr2),
- print_mac(mac3, header->addr3));
- else
- iwl3945_handle_data_packet(priv, 1, rxb, &rx_status);
+ case IEEE80211_FTYPE_DATA:
+ /* fall through */
+ default:
+ iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
break;
}
- }
}
int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
@@ -962,23 +964,24 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
*/
void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
struct iwl3945_cmd *cmd,
- struct ieee80211_tx_control *ctrl,
+ struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr, int sta_id, int tx_id)
{
unsigned long flags;
- u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);
+ u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
+ u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
u16 rate_mask;
int rate;
u8 rts_retry_limit;
u8 data_retry_limit;
__le32 tx_flags;
- u16 fc = le16_to_cpu(hdr->frame_control);
+ __le16 fc = hdr->frame_control;
rate = iwl3945_rates[rate_index].plcp;
tx_flags = cmd->cmd.tx.tx_flags;
/* We need to figure out how to get the sta->supp_rates while
- * in this running context; perhaps encoding into ctrl->tx_rate? */
+ * in this running context */
rate_mask = IWL_RATES_MASK;
spin_lock_irqsave(&priv->sta_lock, flags);
@@ -997,7 +1000,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
else
rts_retry_limit = 7;
- if (ieee80211_is_probe_response(fc)) {
+ if (ieee80211_is_probe_resp(fc)) {
data_retry_limit = 3;
if (data_retry_limit < rts_retry_limit)
rts_retry_limit = data_retry_limit;
@@ -1007,12 +1010,12 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
if (priv->data_retry_limit != -1)
data_retry_limit = priv->data_retry_limit;
- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
- switch (fc & IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_AUTH:
- case IEEE80211_STYPE_DEAUTH:
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
+ if (ieee80211_is_mgmt(fc)) {
+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+ case cpu_to_le16(IEEE80211_STYPE_AUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
if (tx_flags & TX_CMD_FLG_RTS_MSK) {
tx_flags &= ~TX_CMD_FLG_RTS_MSK;
tx_flags |= TX_CMD_FLG_CTS_MSK;
@@ -1233,7 +1236,7 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
iwl3945_power_init_handle(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24));
+ iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index c7695a215a3..fa81ba1af3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -36,6 +36,10 @@
#include <linux/kernel.h>
#include <net/ieee80211_radiotap.h>
+/*used for rfkill*/
+#include <linux/rfkill.h>
+#include <linux/input.h>
+
/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl3945_hw_card_ids[];
@@ -124,7 +128,6 @@ int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
/* One for each TFD */
struct iwl3945_tx_info {
- struct ieee80211_tx_status status;
struct sk_buff *skb[MAX_NUM_OF_TBS];
};
@@ -507,8 +510,6 @@ struct iwl3945_ucode {
u8 data[0]; /* data in same order as "size" elements */
};
-#define IWL_IBSS_MAC_HASH_SIZE 32
-
struct iwl3945_ibss_seq {
u8 mac[ETH_ALEN];
u16 seq_num;
@@ -566,17 +567,8 @@ extern int iwl3945_send_add_station(struct iwl3945_priv *priv,
struct iwl3945_addsta_cmd *sta, u8 flags);
extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid,
int is_ap, u8 flags);
-extern int iwl3945_is_network_packet(struct iwl3945_priv *priv,
- struct ieee80211_hdr *header);
extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
-extern void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb,
- void *data, short len,
- struct ieee80211_rx_status *stats,
- u16 phy_flags);
-extern int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv,
- struct ieee80211_hdr *header);
extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv);
extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv,
struct iwl3945_rx_queue *rxq);
@@ -645,7 +637,7 @@ extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
struct iwl3945_cmd *cmd,
- struct ieee80211_tx_control *ctrl,
+ struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int sta_id, int tx_id);
extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
@@ -687,6 +679,18 @@ enum {
#endif
+#ifdef CONFIG_IWL3945_RFKILL
+struct iwl3945_priv;
+
+void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
+void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
+int iwl3945_rfkill_init(struct iwl3945_priv *priv);
+#else
+static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {}
+static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {}
+static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; }
+#endif
+
#define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES
struct iwl3945_priv {
@@ -780,12 +784,17 @@ struct iwl3945_priv {
struct iwl3945_init_alive_resp card_alive_init;
struct iwl3945_alive_resp card_alive;
+#ifdef CONFIG_IWL3945_RFKILL
+ struct rfkill *rfkill;
+#endif
+
#ifdef CONFIG_IWL3945_LEDS
struct iwl3945_led led[IWL_LED_TRG_MAX];
unsigned long last_blink_time;
u8 last_blink_rate;
u8 allow_blinking;
unsigned int rxtxpackets;
+ u64 led_tpt;
#endif
@@ -836,20 +845,10 @@ struct iwl3945_priv {
u8 mac80211_registered;
- u32 notif_missed_beacons;
-
/* Rx'd packet timing information */
u32 last_beacon_time;
u64 last_tsf;
- /* Duplicate packet detection */
- u16 last_seq_num;
- u16 last_frag_num;
- unsigned long last_packet_time;
-
- /* Hash table for finding stations in IBSS network */
- struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
-
/* eeprom */
struct iwl3945_eeprom eeprom;
@@ -886,6 +885,7 @@ struct iwl3945_priv {
struct work_struct report_work;
struct work_struct request_scan;
struct work_struct beacon_update;
+ struct work_struct set_monitor;
struct tasklet_struct irq_tasklet;
@@ -924,11 +924,6 @@ static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info)
return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
}
-static inline int is_channel_narrow(const struct iwl3945_channel_info *ch_info)
-{
- return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0;
-}
-
static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
{
return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 1a66b508a8e..fce950f4163 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -62,13 +62,18 @@
*****************************************************************************/
/*
* Please use this file (iwl-4965-hw.h) only for hardware-related definitions.
- * Use iwl-4965-commands.h for uCode API definitions.
- * Use iwl-4965.h for driver implementation definitions.
+ * Use iwl-commands.h for uCode API definitions.
+ * Use iwl-dev.h for driver implementation definitions.
*/
#ifndef __iwl_4965_hw_h__
#define __iwl_4965_hw_h__
+#include "iwl-fh.h"
+
+/* EERPROM */
+#define IWL4965_EEPROM_IMG_SIZE 1024
+
/*
* uCode queue management definitions ...
* Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4.
@@ -77,7 +82,7 @@
*/
#define IWL_CMD_QUEUE_NUM 4
#define IWL_CMD_FIFO_NUM 4
-#define IWL_BACK_QUEUE_FIRST_ID 7
+#define IWL49_FIRST_AMPDU_QUEUE 7
/* Tx rates */
#define IWL_CCK_RATES 4
@@ -93,11 +98,16 @@
#define IWL_RSSI_OFFSET 44
-#include "iwl-4965-commands.h"
+#include "iwl-commands.h"
-#define PCI_LINK_CTRL 0x0F0
+/* PCI registers */
+#define PCI_LINK_CTRL 0x0F0 /* 1 byte */
#define PCI_POWER_SOURCE 0x0C8
#define PCI_REG_WUM8 0x0E8
+
+/* PCI register values */
+#define PCI_LINK_VAL_L0S_EN 0x01
+#define PCI_LINK_VAL_L1_EN 0x02
#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
#define TFD_QUEUE_SIZE_MAX (256)
@@ -131,10 +141,8 @@
#define RTC_DATA_LOWER_BOUND (0x800000)
#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000)
-#define IWL49_RTC_INST_SIZE \
- (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL49_RTC_DATA_SIZE \
- (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
+#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
#define IWL_MAX_INST_SIZE IWL49_RTC_INST_SIZE
#define IWL_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
@@ -785,585 +793,6 @@ enum {
/********************* END TXPOWER *****************************************/
-/****************************/
-/* Flow Handler Definitions */
-/****************************/
-
-/**
- * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
- * Addresses are offsets from device's PCI hardware base address.
- */
-#define FH_MEM_LOWER_BOUND (0x1000)
-#define FH_MEM_UPPER_BOUND (0x1EF0)
-
-/**
- * Keep-Warm (KW) buffer base address.
- *
- * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the
- * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency
- * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host
- * from going into a power-savings mode that would cause higher DRAM latency,
- * and possible data over/under-runs, before all Tx/Rx is complete.
- *
- * Driver loads IWL_FH_KW_MEM_ADDR_REG with the physical address (bits 35:4)
- * of the buffer, which must be 4K aligned. Once this is set up, the 4965
- * automatically invokes keep-warm accesses when normal accesses might not
- * be sufficient to maintain fast DRAM response.
- *
- * Bit fields:
- * 31-0: Keep-warm buffer physical base address [35:4], must be 4K aligned
- */
-#define IWL_FH_KW_MEM_ADDR_REG (FH_MEM_LOWER_BOUND + 0x97C)
-
-
-/**
- * TFD Circular Buffers Base (CBBC) addresses
- *
- * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident
- * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs)
- * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04
- * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte
- * aligned (address bits 0-7 must be 0).
- *
- * Bit fields in each pointer register:
- * 27-0: TFD CB physical base address [35:8], must be 256-byte aligned
- */
-#define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0)
-#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10)
-
-/* Find TFD CB base pointer for given queue (range 0-15). */
-#define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4)
-
-
-/**
- * Rx SRAM Control and Status Registers (RSCSR)
- *
- * These registers provide handshake between driver and 4965 for the Rx queue
- * (this queue handles *all* command responses, notifications, Rx data, etc.
- * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx
- * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can
- * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer
- * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1
- * mapping between RBDs and RBs.
- *
- * Driver must allocate host DRAM memory for the following, and set the
- * physical address of each into 4965 registers:
- *
- * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256
- * entries (although any power of 2, up to 4096, is selectable by driver).
- * Each entry (1 dword) points to a receive buffer (RB) of consistent size
- * (typically 4K, although 8K or 16K are also selectable by driver).
- * Driver sets up RB size and number of RBDs in the CB via Rx config
- * register FH_MEM_RCSR_CHNL0_CONFIG_REG.
- *
- * Bit fields within one RBD:
- * 27-0: Receive Buffer physical address bits [35:8], 256-byte aligned
- *
- * Driver sets physical address [35:8] of base of RBD circular buffer
- * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0].
- *
- * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers
- * (RBs) have been filled, via a "write pointer", actually the index of
- * the RB's corresponding RBD within the circular buffer. Driver sets
- * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0].
- *
- * Bit fields in lower dword of Rx status buffer (upper dword not used
- * by driver; see struct iwl4965_shared, val0):
- * 31-12: Not used by driver
- * 11- 0: Index of last filled Rx buffer descriptor
- * (4965 writes, driver reads this value)
- *
- * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must
- * enter pointers to these RBs into contiguous RBD circular buffer entries,
- * and update the 4965's "write" index register, FH_RSCSR_CHNL0_RBDCB_WPTR_REG.
- *
- * This "write" index corresponds to the *next* RBD that the driver will make
- * available, i.e. one RBD past the tail of the ready-to-fill RBDs within
- * the circular buffer. This value should initially be 0 (before preparing any
- * RBs), should be 8 after preparing the first 8 RBs (for example), and must
- * wrap back to 0 at the end of the circular buffer (but don't wrap before
- * "read" index has advanced past 1! See below).
- * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
- *
- * As the 4965 fills RBs (referenced from contiguous RBDs within the circular
- * buffer), it updates the Rx status buffer in host DRAM, 2) described above,
- * to tell the driver the index of the latest filled RBD. The driver must
- * read this "read" index from DRAM after receiving an Rx interrupt from 4965.
- *
- * The driver must also internally keep track of a third index, which is the
- * next RBD to process. When receiving an Rx interrupt, driver should process
- * all filled but unprocessed RBs up to, but not including, the RB
- * corresponding to the "read" index. For example, if "read" index becomes "1",
- * driver may process the RB pointed to by RBD 0. Depending on volume of
- * traffic, there may be many RBs to process.
- *
- * If read index == write index, 4965 thinks there is no room to put new data.
- * Due to this, the maximum number of filled RBs is 255, instead of 256. To
- * be safe, make sure that there is a gap of at least 2 RBDs between "write"
- * and "read" indexes; that is, make sure that there are no more than 254
- * buffers waiting to be filled.
- */
-#define FH_MEM_RSCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBC0)
-#define FH_MEM_RSCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)
-#define FH_MEM_RSCSR_CHNL0 (FH_MEM_RSCSR_LOWER_BOUND)
-
-/**
- * Physical base address of 8-byte Rx Status buffer.
- * Bit fields:
- * 31-0: Rx status buffer physical base address [35:4], must 16-byte aligned.
- */
-#define FH_RSCSR_CHNL0_STTS_WPTR_REG (FH_MEM_RSCSR_CHNL0)
-
-/**
- * Physical base address of Rx Buffer Descriptor Circular Buffer.
- * Bit fields:
- * 27-0: RBD CD physical base address [35:8], must be 256-byte aligned.
- */
-#define FH_RSCSR_CHNL0_RBDCB_BASE_REG (FH_MEM_RSCSR_CHNL0 + 0x004)
-
-/**
- * Rx write pointer (index, really!).
- * Bit fields:
- * 11-0: Index of driver's most recent prepared-to-be-filled RBD, + 1.
- * NOTE: For 256-entry circular buffer, use only bits [7:0].
- */
-#define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008)
-#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)
-
-
-/**
- * Rx Config/Status Registers (RCSR)
- * Rx Config Reg for channel 0 (only channel used)
- *
- * Driver must initialize FH_MEM_RCSR_CHNL0_CONFIG_REG as follows for
- * normal operation (see bit fields).
- *
- * Clearing FH_MEM_RCSR_CHNL0_CONFIG_REG to 0 turns off Rx DMA.
- * Driver should poll FH_MEM_RSSR_RX_STATUS_REG for
- * FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (bit 24) before continuing.
- *
- * Bit fields:
- * 31-30: Rx DMA channel enable: '00' off/pause, '01' pause at end of frame,
- * '10' operate normally
- * 29-24: reserved
- * 23-20: # RBDs in circular buffer = 2^value; use "8" for 256 RBDs (normal),
- * min "5" for 32 RBDs, max "12" for 4096 RBDs.
- * 19-18: reserved
- * 17-16: size of each receive buffer; '00' 4K (normal), '01' 8K,
- * '10' 12K, '11' 16K.
- * 15-14: reserved
- * 13-12: IRQ destination; '00' none, '01' host driver (normal operation)
- * 11- 4: timeout for closing Rx buffer and interrupting host (units 32 usec)
- * typical value 0x10 (about 1/2 msec)
- * 3- 0: reserved
- */
-#define FH_MEM_RCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)
-#define FH_MEM_RCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xCC0)
-#define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND)
-
-#define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0)
-
-#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK (0x00000FF0) /* bit 4-11 */
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK (0x00001000) /* bit 12 */
-#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000) /* bit 15 */
-#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK (0x00030000) /* bits 16-17 */
-#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK (0x00F00000) /* bits 20-23 */
-#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK (0xC0000000) /* bits 30-31 */
-
-#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20)
-#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT (4)
-#define RX_RB_TIMEOUT (0x10)
-
-#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000)
-#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000)
-#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000)
-
-#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000)
-#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K (0x00010000)
-#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K (0x00020000)
-#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K (0x00030000)
-
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
-
-
-/**
- * Rx Shared Status Registers (RSSR)
- *
- * After stopping Rx DMA channel (writing 0 to FH_MEM_RCSR_CHNL0_CONFIG_REG),
- * driver must poll FH_MEM_RSSR_RX_STATUS_REG until Rx channel is idle.
- *
- * Bit fields:
- * 24: 1 = Channel 0 is idle
- *
- * FH_MEM_RSSR_SHARED_CTRL_REG and FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV contain
- * default values that should not be altered by the driver.
- */
-#define FH_MEM_RSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC40)
-#define FH_MEM_RSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xD00)
-
-#define FH_MEM_RSSR_SHARED_CTRL_REG (FH_MEM_RSSR_LOWER_BOUND)
-#define FH_MEM_RSSR_RX_STATUS_REG (FH_MEM_RSSR_LOWER_BOUND + 0x004)
-#define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV (FH_MEM_RSSR_LOWER_BOUND + 0x008)
-
-#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
-
-
-/**
- * Transmit DMA Channel Control/Status Registers (TCSR)
- *
- * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels
- * supported in hardware (don't confuse these with the 16 Tx queues in DRAM,
- * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes.
- *
- * To use a Tx DMA channel, driver must initialize its
- * IWL_FH_TCSR_CHNL_TX_CONFIG_REG(chnl) with:
- *
- * IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
- * IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL
- *
- * All other bits should be 0.
- *
- * Bit fields:
- * 31-30: Tx DMA channel enable: '00' off/pause, '01' pause at end of frame,
- * '10' operate normally
- * 29- 4: Reserved, set to "0"
- * 3: Enable internal DMA requests (1, normal operation), disable (0)
- * 2- 0: Reserved, set to "0"
- */
-#define IWL_FH_TCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xD00)
-#define IWL_FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60)
-
-/* Find Control/Status reg for given Tx DMA/FIFO channel */
-#define IWL_FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \
- (IWL_FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
-
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
-
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF (0x40000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
-
-/**
- * Tx Shared Status Registers (TSSR)
- *
- * After stopping Tx DMA channel (writing 0 to
- * IWL_FH_TCSR_CHNL_TX_CONFIG_REG(chnl)), driver must poll
- * IWL_FH_TSSR_TX_STATUS_REG until selected Tx channel is idle
- * (channel's buffers empty | no pending requests).
- *
- * Bit fields:
- * 31-24: 1 = Channel buffers empty (channel 7:0)
- * 23-16: 1 = No pending requests (channel 7:0)
- */
-#define IWL_FH_TSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xEA0)
-#define IWL_FH_TSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xEC0)
-
-#define IWL_FH_TSSR_TX_STATUS_REG (IWL_FH_TSSR_LOWER_BOUND + 0x010)
-
-#define IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) \
- ((1 << (_chnl)) << 24)
-#define IWL_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) \
- ((1 << (_chnl)) << 16)
-
-#define IWL_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) \
- (IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) | \
- IWL_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl))
-
-
-/********************* START TX SCHEDULER *************************************/
-
-/**
- * 4965 Tx Scheduler
- *
- * The Tx Scheduler selects the next frame to be transmitted, chosing TFDs
- * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in
- * host DRAM. It steers each frame's Tx command (which contains the frame
- * data) into one of up to 7 prioritized Tx DMA FIFO channels within the
- * device. A queue maps to only one (selectable by driver) Tx DMA channel,
- * but one DMA channel may take input from several queues.
- *
- * Tx DMA channels have dedicated purposes. For 4965, they are used as follows:
- *
- * 0 -- EDCA BK (background) frames, lowest priority
- * 1 -- EDCA BE (best effort) frames, normal priority
- * 2 -- EDCA VI (video) frames, higher priority
- * 3 -- EDCA VO (voice) and management frames, highest priority
- * 4 -- Commands (e.g. RXON, etc.)
- * 5 -- HCCA short frames
- * 6 -- HCCA long frames
- * 7 -- not used by driver (device-internal only)
- *
- * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
- * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to
- * support 11n aggregation via EDCA DMA channels.
- *
- * The driver sets up each queue to work in one of two modes:
- *
- * 1) Scheduler-Ack, in which the scheduler automatically supports a
- * block-ack (BA) window of up to 64 TFDs. In this mode, each queue
- * contains TFDs for a unique combination of Recipient Address (RA)
- * and Traffic Identifier (TID), that is, traffic of a given
- * Quality-Of-Service (QOS) priority, destined for a single station.
- *
- * In scheduler-ack mode, the scheduler keeps track of the Tx status of
- * each frame within the BA window, including whether it's been transmitted,
- * and whether it's been acknowledged by the receiving station. The device
- * automatically processes block-acks received from the receiving STA,
- * and reschedules un-acked frames to be retransmitted (successful
- * Tx completion may end up being out-of-order).
- *
- * The driver must maintain the queue's Byte Count table in host DRAM
- * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode.
- * This mode does not support fragmentation.
- *
- * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order.
- * The device may automatically retry Tx, but will retry only one frame
- * at a time, until receiving ACK from receiving station, or reaching
- * retry limit and giving up.
- *
- * The command queue (#4) must use this mode!
- * This mode does not require use of the Byte Count table in host DRAM.
- *
- * Driver controls scheduler operation via 3 means:
- * 1) Scheduler registers
- * 2) Shared scheduler data base in internal 4956 SRAM
- * 3) Shared data in host DRAM
- *
- * Initialization:
- *
- * When loading, driver should allocate memory for:
- * 1) 16 TFD circular buffers, each with space for (typically) 256 TFDs.
- * 2) 16 Byte Count circular buffers in 16 KBytes contiguous memory
- * (1024 bytes for each queue).
- *
- * After receiving "Alive" response from uCode, driver must initialize
- * the scheduler (especially for queue #4, the command queue, otherwise
- * the driver can't issue commands!):
- */
-
-/**
- * Max Tx window size is the max number of contiguous TFDs that the scheduler
- * can keep track of at one time when creating block-ack chains of frames.
- * Note that "64" matches the number of ack bits in a block-ack packet.
- * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize
- * SCD_CONTEXT_QUEUE_OFFSET(x) values.
- */
-#define SCD_WIN_SIZE 64
-#define SCD_FRAME_LIMIT 64
-
-/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
-#define SCD_START_OFFSET 0xa02c00
-
-/*
- * 4965 tells driver SRAM address for internal scheduler structs via this reg.
- * Value is valid only after "Alive" response from uCode.
- */
-#define SCD_SRAM_BASE_ADDR (SCD_START_OFFSET + 0x0)
-
-/*
- * Driver may need to update queue-empty bits after changing queue's
- * write and read pointers (indexes) during (re-)initialization (i.e. when
- * scheduler is not tracking what's happening).
- * Bit fields:
- * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit
- * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty
- * NOTE: This register is not used by Linux driver.
- */
-#define SCD_EMPTY_BITS (SCD_START_OFFSET + 0x4)
-
-/*
- * Physical base address of array of byte count (BC) circular buffers (CBs).
- * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode.
- * This register points to BC CB for queue 0, must be on 1024-byte boundary.
- * Others are spaced by 1024 bytes.
- * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad.
- * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff).
- * Bit fields:
- * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned.
- */
-#define SCD_DRAM_BASE_ADDR (SCD_START_OFFSET + 0x10)
-
-/*
- * Enables any/all Tx DMA/FIFO channels.
- * Scheduler generates requests for only the active channels.
- * Set this to 0xff to enable all 8 channels (normal usage).
- * Bit fields:
- * 7- 0: Enable (1), disable (0), one bit for each channel 0-7
- */
-#define SCD_TXFACT (SCD_START_OFFSET + 0x1c)
-
-/* Mask to enable contiguous Tx DMA/FIFO channels between "lo" and "hi". */
-#define SCD_TXFACT_REG_TXFIFO_MASK(lo, hi) \
- ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
-
-/*
- * Queue (x) Write Pointers (indexes, really!), one for each Tx queue.
- * Initialized and updated by driver as new TFDs are added to queue.
- * NOTE: If using Block Ack, index must correspond to frame's
- * Start Sequence Number; index = (SSN & 0xff)
- * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses?
- */
-#define SCD_QUEUE_WRPTR(x) (SCD_START_OFFSET + 0x24 + (x) * 4)
-
-/*
- * Queue (x) Read Pointers (indexes, really!), one for each Tx queue.
- * For FIFO mode, index indicates next frame to transmit.
- * For Scheduler-ACK mode, index indicates first frame in Tx window.
- * Initialized by driver, updated by scheduler.
- */
-#define SCD_QUEUE_RDPTR(x) (SCD_START_OFFSET + 0x64 + (x) * 4)
-
-/*
- * Select which queues work in chain mode (1) vs. not (0).
- * Use chain mode to build chains of aggregated frames.
- * Bit fields:
- * 31-16: Reserved
- * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time
- * NOTE: If driver sets up queue for chain mode, it should be also set up
- * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x).
- */
-#define SCD_QUEUECHAIN_SEL (SCD_START_OFFSET + 0xd0)
-
-/*
- * Select which queues interrupt driver when scheduler increments
- * a queue's read pointer (index).
- * Bit fields:
- * 31-16: Reserved
- * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled
- * NOTE: This functionality is apparently a no-op; driver relies on interrupts
- * from Rx queue to read Tx command responses and update Tx queues.
- */
-#define SCD_INTERRUPT_MASK (SCD_START_OFFSET + 0xe4)
-
-/*
- * Queue search status registers. One for each queue.
- * Sets up queue mode and assigns queue to Tx DMA channel.
- * Bit fields:
- * 19-10: Write mask/enable bits for bits 0-9
- * 9: Driver should init to "0"
- * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0).
- * Driver should init to "1" for aggregation mode, or "0" otherwise.
- * 7-6: Driver should init to "0"
- * 5: Window Size Left; indicates whether scheduler can request
- * another TFD, based on window size, etc. Driver should init
- * this bit to "1" for aggregation mode, or "0" for non-agg.
- * 4-1: Tx FIFO to use (range 0-7).
- * 0: Queue is active (1), not active (0).
- * Other bits should be written as "0"
- *
- * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled
- * via SCD_QUEUECHAIN_SEL.
- */
-#define SCD_QUEUE_STATUS_BITS(x) (SCD_START_OFFSET + 0x104 + (x) * 4)
-
-/* Bit field positions */
-#define SCD_QUEUE_STTS_REG_POS_ACTIVE (0)
-#define SCD_QUEUE_STTS_REG_POS_TXF (1)
-#define SCD_QUEUE_STTS_REG_POS_WSL (5)
-#define SCD_QUEUE_STTS_REG_POS_SCD_ACK (8)
-
-/* Write masks */
-#define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)
-#define SCD_QUEUE_STTS_REG_MSK (0x0007FC00)
-
-/**
- * 4965 internal SRAM structures for scheduler, shared with driver ...
- *
- * Driver should clear and initialize the following areas after receiving
- * "Alive" response from 4965 uCode, i.e. after initial
- * uCode load, or after a uCode load done for error recovery:
- *
- * SCD_CONTEXT_DATA_OFFSET (size 128 bytes)
- * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes)
- * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes)
- *
- * Driver accesses SRAM via HBUS_TARG_MEM_* registers.
- * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR.
- * All OFFSET values must be added to this base address.
- */
-
-/*
- * Queue context. One 8-byte entry for each of 16 queues.
- *
- * Driver should clear this entire area (size 0x80) to 0 after receiving
- * "Alive" notification from uCode. Additionally, driver should init
- * each queue's entry as follows:
- *
- * LS Dword bit fields:
- * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64.
- *
- * MS Dword bit fields:
- * 16-22: Frame limit. Driver should init to 10 (0xa).
- *
- * Driver should init all other bits to 0.
- *
- * Init must be done after driver receives "Alive" response from 4965 uCode,
- * and when setting up queue for aggregation.
- */
-#define SCD_CONTEXT_DATA_OFFSET 0x380
-#define SCD_CONTEXT_QUEUE_OFFSET(x) (SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
-
-#define SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)
-#define SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F)
-#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
-#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
-
-/*
- * Tx Status Bitmap
- *
- * Driver should clear this entire area (size 0x100) to 0 after receiving
- * "Alive" notification from uCode. Area is used only by device itself;
- * no other support (besides clearing) is required from driver.
- */
-#define SCD_TX_STTS_BITMAP_OFFSET 0x400
-
-/*
- * RAxTID to queue translation mapping.
- *
- * When queue is in Scheduler-ACK mode, frames placed in a that queue must be
- * for only one combination of receiver address (RA) and traffic ID (TID), i.e.
- * one QOS priority level destined for one station (for this wireless link,
- * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit
- * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK
- * mode, the device ignores the mapping value.
- *
- * Bit fields, for each 16-bit map:
- * 15-9: Reserved, set to 0
- * 8-4: Index into device's station table for recipient station
- * 3-0: Traffic ID (tid), range 0-15
- *
- * Driver should clear this entire area (size 32 bytes) to 0 after receiving
- * "Alive" notification from uCode. To update a 16-bit map value, driver
- * must read a dword-aligned value from device SRAM, replace the 16-bit map
- * value of interest, and write the dword value back into device SRAM.
- */
-#define SCD_TRANSLATE_TBL_OFFSET 0x500
-
-/* Find translation table dword to read/write for given queue */
-#define SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
- ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
-
-#define SCD_TXFIFO_POS_TID (0)
-#define SCD_TXFIFO_POS_RA (4)
-#define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
-
-/*********************** END TX SCHEDULER *************************************/
-
-static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags)
-{
- return le32_to_cpu(rate_n_flags) & 0xFF;
-}
-static inline u16 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags)
-{
- return le32_to_cpu(rate_n_flags) & 0xFFFF;
-}
-static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
-{
- return cpu_to_le32(flags|(u16)rate);
-}
-
/**
* Tx/Rx Queues
@@ -1385,14 +814,15 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
* up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array
* in DRAM containing 256 Transmit Frame Descriptors (TFDs).
*/
-#define IWL4965_MAX_WIN_SIZE 64
-#define IWL4965_QUEUE_SIZE 256
-#define IWL4965_NUM_FIFOS 7
-#define IWL4965_MAX_NUM_QUEUES 16
-
+#define IWL49_MAX_WIN_SIZE 64
+#define IWL49_QUEUE_SIZE 256
+#define IWL49_NUM_FIFOS 7
+#define IWL49_CMD_FIFO_NUM 4
+#define IWL49_NUM_QUEUES 16
+#define IWL49_NUM_AMPDU_QUEUES 8
/**
- * struct iwl4965_tfd_frame_data
+ * struct iwl_tfd_frame_data
*
* Describes up to 2 buffers containing (contiguous) portions of a Tx frame.
* Each buffer must be on dword boundary.
@@ -1411,7 +841,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
* 31-20: Tx buffer 2 length (bytes)
* 19- 0: Tx buffer 2 address bits [35:16]
*/
-struct iwl4965_tfd_frame_data {
+struct iwl_tfd_frame_data {
__le32 tb1_addr;
__le32 val1;
@@ -1441,7 +871,7 @@ struct iwl4965_tfd_frame_data {
/**
- * struct iwl4965_tfd_frame
+ * struct iwl_tfd_frame
*
* Transmit Frame Descriptor (TFD)
*
@@ -1468,7 +898,7 @@ struct iwl4965_tfd_frame_data {
*
* A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
*/
-struct iwl4965_tfd_frame {
+struct iwl_tfd_frame {
__le32 val0;
/* __le32 rsvd1:24; */
/* __le32 num_tbs:5; */
@@ -1477,7 +907,7 @@ struct iwl4965_tfd_frame {
#define IWL_num_tbs_SYM val0
/* __le32 rsvd2:1; */
/* __le32 padding:2; */
- struct iwl4965_tfd_frame_data pa[10];
+ struct iwl_tfd_frame_data pa[10];
__le32 reserved;
} __attribute__ ((packed));
@@ -1520,10 +950,10 @@ struct iwl4965_queue_byte_cnt_entry {
* 4965 assumes tables are separated by 1024 bytes.
*/
struct iwl4965_sched_queue_byte_cnt_tbl {
- struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL4965_QUEUE_SIZE +
- IWL4965_MAX_WIN_SIZE];
+ struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL49_QUEUE_SIZE +
+ IWL49_MAX_WIN_SIZE];
u8 dont_care[1024 -
- (IWL4965_QUEUE_SIZE + IWL4965_MAX_WIN_SIZE) *
+ (IWL49_QUEUE_SIZE + IWL49_MAX_WIN_SIZE) *
sizeof(__le16)];
} __attribute__ ((packed));
@@ -1553,7 +983,7 @@ struct iwl4965_sched_queue_byte_cnt_tbl {
*/
struct iwl4965_shared {
struct iwl4965_sched_queue_byte_cnt_tbl
- queues_byte_cnt_tbls[IWL4965_MAX_NUM_QUEUES];
+ queues_byte_cnt_tbls[IWL49_NUM_QUEUES];
__le32 rb_closed;
/* __le32 rb_closed_stts_rb_num:12; */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 3a7f0cb710e..3ccb84aa5db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -28,7 +28,6 @@
#include <linux/skbuff.h>
#include <linux/wireless.h>
#include <net/mac80211.h>
-#include <net/ieee80211.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -38,13 +37,14 @@
#include "../net/mac80211/rate.h"
-#include "iwl-4965.h"
+#include "iwl-dev.h"
+#include "iwl-sta.h"
#include "iwl-core.h"
#include "iwl-helpers.h"
#define RS_NAME "iwl-4965-rs"
-#define NUM_TRY_BEFORE_ANTENNA_TOGGLE 1
+#define NUM_TRY_BEFORE_ANT_TOGGLE 1
#define IWL_NUMBER_TRY 1
#define IWL_HT_NUMBER_TRY 3
@@ -65,9 +65,16 @@ static u8 rs_ht_to_legacy[] = {
IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
};
-struct iwl4965_rate {
- u32 rate_n_flags;
-} __attribute__ ((packed));
+static const u8 ant_toggle_lookup[] = {
+ /*ANT_NONE -> */ ANT_NONE,
+ /*ANT_A -> */ ANT_B,
+ /*ANT_B -> */ ANT_C,
+ /*ANT_AB -> */ ANT_BC,
+ /*ANT_C -> */ ANT_A,
+ /*ANT_AC -> */ ANT_AB,
+ /*ANT_BC -> */ ANT_AC,
+ /*ANT_ABC -> */ ANT_ABC,
+};
/**
* struct iwl4965_rate_scale_data -- tx success history for one rate
@@ -88,19 +95,17 @@ struct iwl4965_rate_scale_data {
* one for "active", and one for "search".
*/
struct iwl4965_scale_tbl_info {
- enum iwl4965_table_type lq_type;
- enum iwl4965_antenna_type antenna_type;
+ enum iwl_table_type lq_type;
+ u8 ant_type;
u8 is_SGI; /* 1 = short guard interval */
u8 is_fat; /* 1 = 40 MHz channel width */
u8 is_dup; /* 1 = duplicated data streams */
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
- struct iwl4965_rate current_rate; /* rate_n_flags, uCode API format */
+ u32 current_rate; /* rate_n_flags, uCode API format */
struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
};
-#ifdef CONFIG_IWL4965_HT
-
struct iwl4965_traffic_load {
unsigned long time_stamp; /* age of the oldest statistics */
u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
@@ -112,8 +117,6 @@ struct iwl4965_traffic_load {
u8 head; /* start of the circular buffer */
};
-#endif /* CONFIG_IWL4965_HT */
-
/**
* struct iwl4965_lq_sta -- driver's rate scaling private structure
*
@@ -136,8 +139,6 @@ struct iwl4965_lq_sta {
u32 flush_timer; /* time staying in mode before new search */
u8 action_counter; /* # mode-switch actions tried */
- u8 antenna;
- u8 valid_antenna;
u8 is_green;
u8 is_dup;
enum ieee80211_band band;
@@ -145,24 +146,21 @@ struct iwl4965_lq_sta {
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
u32 supp_rates;
- u16 active_rate;
+ u16 active_legacy_rate;
u16 active_siso_rate;
- u16 active_mimo_rate;
+ u16 active_mimo2_rate;
+ u16 active_mimo3_rate;
u16 active_rate_basic;
struct iwl_link_quality_cmd lq;
struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
-#ifdef CONFIG_IWL4965_HT
struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];
u8 tx_agg_tid_en;
-#endif
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file;
struct dentry *rs_sta_dbgfs_stats_table_file;
-#ifdef CONFIG_IWL4965_HT
struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
-#endif
- struct iwl4965_rate dbg_fixed;
+ u32 dbg_fixed_rate;
#endif
struct iwl_priv *drv;
};
@@ -171,17 +169,17 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
struct net_device *dev,
struct ieee80211_hdr *hdr,
struct sta_info *sta);
-static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
- struct iwl4965_rate *tx_mcs,
- struct iwl_link_quality_cmd *tbl);
+static void rs_fill_link_cmd(const struct iwl_priv *priv,
+ struct iwl4965_lq_sta *lq_sta,
+ u32 rate_n_flags);
#ifdef CONFIG_MAC80211_DEBUGFS
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
- struct iwl4965_rate *mcs, int index);
+ u32 *rate_n_flags, int index);
#else
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
- struct iwl4965_rate *mcs, int index)
+ u32 *rate_n_flags, int index)
{}
#endif
@@ -190,6 +188,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
* "G" is the only table that supports CCK (the first 4 rates).
*/
+/*FIXME:RS:need to spearate tables for MIMO2/MIMO3*/
static s32 expected_tpt_A[IWL_RATE_COUNT] = {
0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
};
@@ -230,7 +229,7 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
};
-static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags)
+static inline u8 rs_extract_rate(u32 rate_n_flags)
{
return (u8)(rate_n_flags & 0xFF);
}
@@ -245,7 +244,11 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
window->stamp = 0;
}
-#ifdef CONFIG_IWL4965_HT
+static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
+{
+ return ((ant_type & valid_antenna) == ant_type);
+}
+
/*
* removes the old data from the statistics. All data that is older than
* TID_MAX_TIME_DIFF, will be deleted.
@@ -271,15 +274,21 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
* increment traffic load value for tid and also remove
* any old values if passed the certain time period
*/
-static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid)
+static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
+ struct ieee80211_hdr *hdr)
{
u32 curr_time = jiffies_to_msecs(jiffies);
u32 time_diff;
s32 index;
struct iwl4965_traffic_load *tl = NULL;
+ __le16 fc = hdr->frame_control;
+ u8 tid;
- if (tid >= TID_MAX_LOAD_COUNT)
- return;
+ if (ieee80211_is_data_qos(fc)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ } else
+ return MAX_TID_COUNT;
tl = &lq_data->load[tid];
@@ -292,7 +301,7 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid)
tl->queue_count = 1;
tl->head = 0;
tl->packet_count[0] = 1;
- return;
+ return MAX_TID_COUNT;
}
time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
@@ -309,6 +318,8 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid)
if ((index + 1) > tl->queue_count)
tl->queue_count = index + 1;
+
+ return tid;
}
/*
@@ -349,9 +360,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
unsigned long state;
DECLARE_MAC_BUF(mac);
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
state = sta->ampdu_mlme.tid_state_tx[tid];
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
if (state == HT_AGG_STATE_IDLE &&
rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
@@ -372,7 +383,12 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
}
-#endif /* CONFIG_IWLWIFI_HT */
+static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
+{
+ return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
+ !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
+ !!(rate_n_flags & RATE_MCS_ANT_C_MSK));
+}
/**
* rs_collect_tx_data - Update the success/failure sliding window
@@ -386,8 +402,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
int successes)
{
struct iwl4965_rate_scale_data *window = NULL;
- u64 mask;
- u8 win_size = IWL_RATE_MAX_WINDOW;
+ static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
s32 fail_count;
if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
@@ -405,14 +420,14 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
* we keep these bitmaps!).
*/
while (retries > 0) {
- if (window->counter >= win_size) {
- window->counter = win_size - 1;
- mask = 1;
- mask = (mask << (win_size - 1));
+ if (window->counter >= IWL_RATE_MAX_WINDOW) {
+
+ /* remove earliest */
+ window->counter = IWL_RATE_MAX_WINDOW - 1;
+
if (window->data & mask) {
window->data &= ~mask;
- window->success_counter =
- window->success_counter - 1;
+ window->success_counter--;
}
}
@@ -422,10 +437,9 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
/* Shift bitmap by one frame (throw away oldest history),
* OR in "1", and increment "success" if this
* frame was successful. */
- mask = window->data;
- window->data = (mask << 1);
+ window->data <<= 1;;
if (successes > 0) {
- window->success_counter = window->success_counter + 1;
+ window->success_counter++;
window->data |= 0x1;
successes--;
}
@@ -458,168 +472,162 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
/*
* Fill uCode API rate_n_flags field, based on "search" or "active" table.
*/
-static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
- struct iwl4965_scale_tbl_info *tbl,
- int index, u8 use_green)
+/* FIXME:RS:remove this function and put the flags statically in the table */
+static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
+ int index, u8 use_green)
{
+ u32 rate_n_flags = 0;
+
if (is_legacy(tbl->lq_type)) {
- mcs_rate->rate_n_flags = iwl4965_rates[index].plcp;
+ rate_n_flags = iwl_rates[index].plcp;
if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
- mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK;
+ rate_n_flags |= RATE_MCS_CCK_MSK;
- } else if (is_siso(tbl->lq_type)) {
- if (index > IWL_LAST_OFDM_RATE)
+ } else if (is_Ht(tbl->lq_type)) {
+ if (index > IWL_LAST_OFDM_RATE) {
+ IWL_ERROR("invalid HT rate index %d\n", index);
index = IWL_LAST_OFDM_RATE;
- mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_siso |
- RATE_MCS_HT_MSK;
- } else {
- if (index > IWL_LAST_OFDM_RATE)
- index = IWL_LAST_OFDM_RATE;
- mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_mimo |
- RATE_MCS_HT_MSK;
- }
-
- switch (tbl->antenna_type) {
- case ANT_BOTH:
- mcs_rate->rate_n_flags |= RATE_MCS_ANT_AB_MSK;
- break;
- case ANT_MAIN:
- mcs_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
- break;
- case ANT_AUX:
- mcs_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
- break;
- case ANT_NONE:
- break;
- }
-
- if (is_legacy(tbl->lq_type))
- return;
+ }
+ rate_n_flags = RATE_MCS_HT_MSK;
- if (tbl->is_fat) {
- if (tbl->is_dup)
- mcs_rate->rate_n_flags |= RATE_MCS_DUP_MSK;
+ if (is_siso(tbl->lq_type))
+ rate_n_flags |= iwl_rates[index].plcp_siso;
+ else if (is_mimo2(tbl->lq_type))
+ rate_n_flags |= iwl_rates[index].plcp_mimo2;
else
- mcs_rate->rate_n_flags |= RATE_MCS_FAT_MSK;
+ rate_n_flags |= iwl_rates[index].plcp_mimo3;
+ } else {
+ IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
}
- if (tbl->is_SGI)
- mcs_rate->rate_n_flags |= RATE_MCS_SGI_MSK;
- if (use_green) {
- mcs_rate->rate_n_flags |= RATE_MCS_GF_MSK;
- if (is_siso(tbl->lq_type))
- mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK;
+ rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
+ RATE_MCS_ANT_ABC_MSK);
+
+ if (is_Ht(tbl->lq_type)) {
+ if (tbl->is_fat) {
+ if (tbl->is_dup)
+ rate_n_flags |= RATE_MCS_DUP_MSK;
+ else
+ rate_n_flags |= RATE_MCS_FAT_MSK;
+ }
+ if (tbl->is_SGI)
+ rate_n_flags |= RATE_MCS_SGI_MSK;
+
+ if (use_green) {
+ rate_n_flags |= RATE_MCS_GF_MSK;
+ if (is_siso(tbl->lq_type) && tbl->is_SGI) {
+ rate_n_flags &= ~RATE_MCS_SGI_MSK;
+ IWL_ERROR("GF was set with SGI:SISO\n");
+ }
+ }
}
+ return rate_n_flags;
}
/*
* Interpret uCode API's rate_n_flags format,
* fill "search" or "active" tx mode table.
*/
-static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
+static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
enum ieee80211_band band,
struct iwl4965_scale_tbl_info *tbl,
int *rate_idx)
{
- int index;
- u32 ant_msk;
+ u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
+ u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
+ u8 mcs;
- index = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags);
+ *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
- if (index == IWL_RATE_INVALID) {
+ if (*rate_idx == IWL_RATE_INVALID) {
*rate_idx = -1;
return -EINVAL;
}
tbl->is_SGI = 0; /* default legacy setup */
tbl->is_fat = 0;
tbl->is_dup = 0;
- tbl->antenna_type = ANT_BOTH; /* default MIMO setup */
+ tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
+ tbl->lq_type = LQ_NONE;
/* legacy rate format */
- if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) {
- ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
-
- if (ant_msk == RATE_MCS_ANT_AB_MSK)
- tbl->lq_type = LQ_NONE;
- else {
-
+ if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
+ if (num_of_ant == 1) {
if (band == IEEE80211_BAND_5GHZ)
tbl->lq_type = LQ_A;
else
tbl->lq_type = LQ_G;
-
- if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
- tbl->antenna_type = ANT_MAIN;
- else
- tbl->antenna_type = ANT_AUX;
- }
- *rate_idx = index;
-
- /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */
- } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
- <= IWL_RATE_SISO_60M_PLCP) {
- tbl->lq_type = LQ_SISO;
-
- ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
- if (ant_msk == RATE_MCS_ANT_AB_MSK)
- tbl->lq_type = LQ_NONE;
- else {
- if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
- tbl->antenna_type = ANT_MAIN;
- else
- tbl->antenna_type = ANT_AUX;
}
- if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
- tbl->is_SGI = 1;
-
- if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
- (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
- tbl->is_fat = 1;
-
- if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
- tbl->is_dup = 1;
-
- *rate_idx = index;
-
- /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */
+ /* HT rate format */
} else {
- tbl->lq_type = LQ_MIMO;
- if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
+ if (rate_n_flags & RATE_MCS_SGI_MSK)
tbl->is_SGI = 1;
- if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
- (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
+ if ((rate_n_flags & RATE_MCS_FAT_MSK) ||
+ (rate_n_flags & RATE_MCS_DUP_MSK))
tbl->is_fat = 1;
- if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
+ if (rate_n_flags & RATE_MCS_DUP_MSK)
tbl->is_dup = 1;
- *rate_idx = index;
+
+ mcs = rs_extract_rate(rate_n_flags);
+
+ /* SISO */
+ if (mcs <= IWL_RATE_SISO_60M_PLCP) {
+ if (num_of_ant == 1)
+ tbl->lq_type = LQ_SISO; /*else NONE*/
+ /* MIMO2 */
+ } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {
+ if (num_of_ant == 2)
+ tbl->lq_type = LQ_MIMO2;
+ /* MIMO3 */
+ } else {
+ if (num_of_ant == 3)
+ tbl->lq_type = LQ_MIMO3;
+ }
}
return 0;
}
-static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate,
- struct iwl4965_scale_tbl_info *tbl)
+/* switch to another antenna/antennas and return 1 */
+/* if no other valid antenna found, return 0 */
+static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
+ struct iwl4965_scale_tbl_info *tbl)
{
- if (tbl->antenna_type == ANT_AUX) {
- tbl->antenna_type = ANT_MAIN;
- new_rate->rate_n_flags &= ~RATE_MCS_ANT_B_MSK;
- new_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
- } else {
- tbl->antenna_type = ANT_AUX;
- new_rate->rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
- new_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
- }
+ u8 new_ant_type;
+
+ if (!tbl->ant_type || tbl->ant_type > ANT_ABC)
+ return 0;
+
+ if (!rs_is_valid_ant(valid_ant, tbl->ant_type))
+ return 0;
+
+ new_ant_type = ant_toggle_lookup[tbl->ant_type];
+
+ while ((new_ant_type != tbl->ant_type) &&
+ !rs_is_valid_ant(valid_ant, new_ant_type))
+ new_ant_type = ant_toggle_lookup[new_ant_type];
+
+ if (new_ant_type == tbl->ant_type)
+ return 0;
+
+ tbl->ant_type = new_ant_type;
+ *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK;
+ *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;
+ return 1;
}
-static inline u8 rs_use_green(struct iwl_priv *priv,
- struct ieee80211_conf *conf)
+/* FIXME:RS: in 4965 we don't use greenfield at all */
+/* FIXME:RS: don't use greenfield for now in TX */
+#if 0
+static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
{
-#ifdef CONFIG_IWL4965_HT
return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
priv->current_ht_config.is_green_field &&
!priv->current_ht_config.non_GF_STA_present);
-#endif /* CONFIG_IWL4965_HT */
+}
+#endif
+static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
+{
return 0;
}
@@ -630,27 +638,28 @@ static inline u8 rs_use_green(struct iwl_priv *priv,
* basic available rates.
*
*/
-static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
+static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
struct ieee80211_hdr *hdr,
- enum iwl4965_table_type rate_type,
- u16 *data_rate)
+ enum iwl_table_type rate_type)
{
- if (is_legacy(rate_type))
- *data_rate = lq_sta->active_rate;
- else {
+ if (hdr && is_multicast_ether_addr(hdr->addr1) &&
+ lq_sta->active_rate_basic)
+ return lq_sta->active_rate_basic;
+
+ if (is_legacy(rate_type)) {
+ return lq_sta->active_legacy_rate;
+ } else {
if (is_siso(rate_type))
- *data_rate = lq_sta->active_siso_rate;
+ return lq_sta->active_siso_rate;
+ else if (is_mimo2(rate_type))
+ return lq_sta->active_mimo2_rate;
else
- *data_rate = lq_sta->active_mimo_rate;
- }
-
- if (hdr && is_multicast_ether_addr(hdr->addr1) &&
- lq_sta->active_rate_basic) {
- *data_rate = lq_sta->active_rate_basic;
+ return lq_sta->active_mimo3_rate;
}
}
-static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
+static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
+ int rate_type)
{
u8 high = IWL_RATE_INVALID;
u8 low = IWL_RATE_INVALID;
@@ -684,7 +693,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
low = index;
while (low != IWL_RATE_INVALID) {
- low = iwl4965_rates[low].prev_rs;
+ low = iwl_rates[low].prev_rs;
if (low == IWL_RATE_INVALID)
break;
if (rate_mask & (1 << low))
@@ -694,7 +703,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
high = index;
while (high != IWL_RATE_INVALID) {
- high = iwl4965_rates[high].next_rs;
+ high = iwl_rates[high].next_rs;
if (high == IWL_RATE_INVALID)
break;
if (rate_mask & (1 << high))
@@ -705,9 +714,9 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
return (high << 8) | low;
}
-static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
+static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
- u8 ht_possible, struct iwl4965_rate *mcs_rate)
+ u8 ht_possible)
{
s32 low;
u16 rate_mask;
@@ -726,15 +735,14 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
else
tbl->lq_type = LQ_G;
- if ((tbl->antenna_type == ANT_BOTH) ||
- (tbl->antenna_type == ANT_NONE))
- tbl->antenna_type = ANT_MAIN;
+ if (num_of_ant(tbl->ant_type) > 1)
+ tbl->ant_type = ANT_A;/*FIXME:RS*/
tbl->is_fat = 0;
tbl->is_SGI = 0;
}
- rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, &rate_mask);
+ rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
/* Mask with station rate restriction */
if (is_legacy(tbl->lq_type)) {
@@ -748,25 +756,26 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
/* If we switched from HT to legacy, check current rate */
if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
- rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
- return;
+ low = scale_index;
+ goto out;
}
- high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type);
+ high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
+ tbl->lq_type);
low = high_low & 0xff;
- if (low != IWL_RATE_INVALID)
- rs_mcs_from_tbl(mcs_rate, tbl, low, is_green);
- else
- rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
+ if (low == IWL_RATE_INVALID)
+ low = scale_index;
+
+out:
+ return rate_n_flags_from_tbl(tbl, low, is_green);
}
/*
* mac80211 sends us Tx status
*/
static void rs_tx_status(void *priv_rate, struct net_device *dev,
- struct sk_buff *skb,
- struct ieee80211_tx_status *tx_resp)
+ struct sk_buff *skb)
{
int status;
u8 retries;
@@ -778,13 +787,14 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_hw *hw = local_to_hw(local);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl4965_rate_scale_data *window = NULL;
struct iwl4965_rate_scale_data *search_win = NULL;
- struct iwl4965_rate tx_mcs;
+ u32 tx_rate;
struct iwl4965_scale_tbl_info tbl_type;
struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
u8 active_index = 0;
- u16 fc = le16_to_cpu(hdr->frame_control);
+ __le16 fc = hdr->frame_control;
s32 tpt = 0;
IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
@@ -793,11 +803,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
return;
/* This packet was aggregated but doesn't carry rate scale info */
- if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) &&
- !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU))
+ if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
+ !(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
- retries = tx_resp->retry_count;
+ retries = info->status.retry_count;
if (retries > 15)
retries = 15;
@@ -812,9 +822,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
- if (!priv->lq_mngr.lq_ready)
- goto out;
-
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
!lq_sta->ibss_sta_added)
goto out;
@@ -822,15 +829,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
table = &lq_sta->lq;
active_index = lq_sta->active_tbl;
- /* Get mac80211 antenna info */
- lq_sta->antenna =
- (lq_sta->valid_antenna & local->hw.conf.antenna_sel_tx);
- if (!lq_sta->antenna)
- lq_sta->antenna = lq_sta->valid_antenna;
-
- /* Ignore mac80211 antenna info for now */
- lq_sta->antenna = lq_sta->valid_antenna;
-
curr_tbl = &(lq_sta->lq_info[active_index]);
search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
window = (struct iwl4965_rate_scale_data *)
@@ -846,28 +844,26 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
* to check "search" mode, or a prior "search" mode after we've moved
* to a new "search" mode (which might become the new "active" mode).
*/
- tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags);
- rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index);
+ tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
+ rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
if (priv->band == IEEE80211_BAND_5GHZ)
rs_index -= IWL_FIRST_OFDM_RATE;
- if ((tx_resp->control.tx_rate == NULL) ||
+ if ((info->tx_rate_idx < 0) ||
(tbl_type.is_SGI ^
- !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) ||
+ !!(info->flags & IEEE80211_TX_CTL_SHORT_GI)) ||
(tbl_type.is_fat ^
- !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) ||
+ !!(info->flags & IEEE80211_TX_CTL_40_MHZ_WIDTH)) ||
(tbl_type.is_dup ^
- !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) ||
- (tbl_type.antenna_type ^
- tx_resp->control.antenna_sel_tx) ||
- (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^
- !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) ||
- (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^
- !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) ||
+ !!(info->flags & IEEE80211_TX_CTL_DUP_DATA)) ||
+ (tbl_type.ant_type ^ info->antenna_sel_tx) ||
+ (!!(tx_rate & RATE_MCS_HT_MSK) ^
+ !!(info->flags & IEEE80211_TX_CTL_OFDM_HT)) ||
+ (!!(tx_rate & RATE_MCS_GF_MSK) ^
+ !!(info->flags & IEEE80211_TX_CTL_GREEN_FIELD)) ||
(hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
- tx_resp->control.tx_rate->bitrate)) {
- IWL_DEBUG_RATE("initial rate does not match 0x%x\n",
- tx_mcs.rate_n_flags);
+ hw->wiphy->bands[info->band]->bitrates[info->tx_rate_idx].bitrate)) {
+ IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
goto out;
}
@@ -875,15 +871,14 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
while (retries) {
/* Look up the rate and other info used for each tx attempt.
* Each tx attempt steps one entry deeper in the rate table. */
- tx_mcs.rate_n_flags =
- le32_to_cpu(table->rs_table[index].rate_n_flags);
- rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
+ tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
+ rs_get_tbl_info_from_mcs(tx_rate, priv->band,
&tbl_type, &rs_index);
/* If type matches "search" table,
* add failure to "search" history */
if ((tbl_type.lq_type == search_tbl->lq_type) &&
- (tbl_type.antenna_type == search_tbl->antenna_type) &&
+ (tbl_type.ant_type == search_tbl->ant_type) &&
(tbl_type.is_SGI == search_tbl->is_SGI)) {
if (search_tbl->expected_tpt)
tpt = search_tbl->expected_tpt[rs_index];
@@ -894,7 +889,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
/* Else if type matches "current/active" table,
* add failure to "current/active" history */
} else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
- (tbl_type.antenna_type == curr_tbl->antenna_type) &&
+ (tbl_type.ant_type == curr_tbl->ant_type) &&
(tbl_type.is_SGI == curr_tbl->is_SGI)) {
if (curr_tbl->expected_tpt)
tpt = curr_tbl->expected_tpt[rs_index];
@@ -917,44 +912,41 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
* if Tx was successful first try, use original rate,
* else look up the rate that was, finally, successful.
*/
- tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags);
- rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index);
+ tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
+ rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
/* Update frame history window with "success" if Tx got ACKed ... */
- if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
- status = 1;
- else
- status = 0;
+ status = !!(info->flags & IEEE80211_TX_STAT_ACK);
/* If type matches "search" table,
* add final tx status to "search" history */
if ((tbl_type.lq_type == search_tbl->lq_type) &&
- (tbl_type.antenna_type == search_tbl->antenna_type) &&
+ (tbl_type.ant_type == search_tbl->ant_type) &&
(tbl_type.is_SGI == search_tbl->is_SGI)) {
if (search_tbl->expected_tpt)
tpt = search_tbl->expected_tpt[rs_index];
else
tpt = 0;
- if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU)
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
rs_collect_tx_data(search_win, rs_index, tpt,
- tx_resp->ampdu_ack_len,
- tx_resp->ampdu_ack_map);
+ info->status.ampdu_ack_len,
+ info->status.ampdu_ack_map);
else
rs_collect_tx_data(search_win, rs_index, tpt,
1, status);
/* Else if type matches "current/active" table,
* add final tx status to "current/active" history */
} else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
- (tbl_type.antenna_type == curr_tbl->antenna_type) &&
+ (tbl_type.ant_type == curr_tbl->ant_type) &&
(tbl_type.is_SGI == curr_tbl->is_SGI)) {
if (curr_tbl->expected_tpt)
tpt = curr_tbl->expected_tpt[rs_index];
else
tpt = 0;
- if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU)
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
rs_collect_tx_data(window, rs_index, tpt,
- tx_resp->ampdu_ack_len,
- tx_resp->ampdu_ack_map);
+ info->status.ampdu_ack_len,
+ info->status.ampdu_ack_map);
else
rs_collect_tx_data(window, rs_index, tpt,
1, status);
@@ -963,10 +955,10 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
/* If not searching for new mode, increment success/failed counter
* ... these help determine when to start searching again */
if (lq_sta->stay_in_tbl) {
- if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) {
- lq_sta->total_success += tx_resp->ampdu_ack_map;
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ lq_sta->total_success += info->status.ampdu_ack_map;
lq_sta->total_failed +=
- (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map);
+ (info->status.ampdu_ack_len - info->status.ampdu_ack_map);
} else {
if (status)
lq_sta->total_success++;
@@ -982,30 +974,6 @@ out:
return;
}
-static u8 rs_is_ant_connected(u8 valid_antenna,
- enum iwl4965_antenna_type antenna_type)
-{
- if (antenna_type == ANT_AUX)
- return ((valid_antenna & 0x2) ? 1:0);
- else if (antenna_type == ANT_MAIN)
- return ((valid_antenna & 0x1) ? 1:0);
- else if (antenna_type == ANT_BOTH)
- return ((valid_antenna & 0x3) == 0x3);
-
- return 1;
-}
-
-static u8 rs_is_other_ant_connected(u8 valid_antenna,
- enum iwl4965_antenna_type antenna_type)
-{
- if (antenna_type == ANT_AUX)
- return rs_is_ant_connected(valid_antenna, ANT_MAIN);
- else
- return rs_is_ant_connected(valid_antenna, ANT_AUX);
-
- return 0;
-}
-
/*
* Begin a period of staying with a selected modulation mode.
* Set "stay_in_tbl" flag to prevent any mode switches.
@@ -1014,10 +982,10 @@ static u8 rs_is_other_ant_connected(u8 valid_antenna,
* These control how long we stay using same modulation mode before
* searching for a new mode.
*/
-static void rs_set_stay_in_table(u8 is_legacy,
+static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
struct iwl4965_lq_sta *lq_sta)
{
- IWL_DEBUG_HT("we are staying in the same table\n");
+ IWL_DEBUG_RATE("we are staying in the same table\n");
lq_sta->stay_in_tbl = 1; /* only place this gets set */
if (is_legacy) {
lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
@@ -1036,7 +1004,7 @@ static void rs_set_stay_in_table(u8 is_legacy,
/*
* Find correct throughput table for given mode of modulation
*/
-static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
+static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
struct iwl4965_scale_tbl_info *tbl)
{
if (is_legacy(tbl->lq_type)) {
@@ -1055,7 +1023,7 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
else
tbl->expected_tpt = expected_tpt_siso20MHz;
- } else if (is_mimo(tbl->lq_type)) {
+ } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */
if (tbl->is_fat && !lq_sta->is_dup)
if (tbl->is_SGI)
tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
@@ -1069,7 +1037,6 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
tbl->expected_tpt = expected_tpt_G;
}
-#ifdef CONFIG_IWL4965_HT
/*
* Find starting rate for new "search" high-throughput mode of modulation.
* Goal is to find lowest expected rate (under perfect conditions) that is
@@ -1085,7 +1052,7 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
static s32 rs_get_best_rate(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta,
struct iwl4965_scale_tbl_info *tbl, /* "search" */
- u16 rate_mask, s8 index, s8 rate)
+ u16 rate_mask, s8 index)
{
/* "active" values */
struct iwl4965_scale_tbl_info *active_tbl =
@@ -1098,11 +1065,13 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
s32 new_rate, high, low, start_hi;
u16 high_low;
+ s8 rate = index;
new_rate = high = low = start_hi = IWL_RATE_INVALID;
for (; ;) {
- high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type);
+ high_low = rs_get_adjacent_rate(priv, rate, rate_mask,
+ tbl->lq_type);
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
@@ -1169,23 +1138,16 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
return new_rate;
}
-#endif /* CONFIG_IWL4965_HT */
-
-static inline u8 rs_is_both_ant_supp(u8 valid_antenna)
-{
- return (rs_is_ant_connected(valid_antenna, ANT_BOTH));
-}
/*
* Set up search table for MIMO
*/
-static int rs_switch_to_mimo(struct iwl_priv *priv,
+static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta,
struct ieee80211_conf *conf,
struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index)
{
-#ifdef CONFIG_IWL4965_HT
u16 rate_mask;
s32 rate;
s8 is_green = lq_sta->is_green;
@@ -1194,26 +1156,27 @@ static int rs_switch_to_mimo(struct iwl_priv *priv,
!sta->ht_info.ht_supported)
return -1;
- IWL_DEBUG_HT("LQ: try to switch to MIMO\n");
- tbl->lq_type = LQ_MIMO;
- rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
- &rate_mask);
-
if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
return -1;
/* Need both Tx chains/antennas to support MIMO */
- if (!rs_is_both_ant_supp(lq_sta->antenna))
+ if (priv->hw_params.tx_chains_num < 2)
return -1;
+ IWL_DEBUG_RATE("LQ: try to switch to MIMO2\n");
+
+ tbl->lq_type = LQ_MIMO2;
tbl->is_dup = lq_sta->is_dup;
tbl->action = 0;
+ rate_mask = lq_sta->active_mimo2_rate;
+
if (priv->current_ht_config.supported_chan_width
- == IWL_CHANNEL_WIDTH_40MHZ)
+ == IWL_CHANNEL_WIDTH_40MHZ)
tbl->is_fat = 1;
else
tbl->is_fat = 0;
+ /* FIXME: - don't toggle SGI here
if (tbl->is_fat) {
if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
tbl->is_SGI = 1;
@@ -1223,22 +1186,24 @@ static int rs_switch_to_mimo(struct iwl_priv *priv,
tbl->is_SGI = 1;
else
tbl->is_SGI = 0;
+ */
+
+ rs_set_expected_tpt_table(lq_sta, tbl);
- rs_get_expected_tpt_table(lq_sta, tbl);
+ rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
- rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
+ IWL_DEBUG_RATE("LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
- IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask);
- if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask))
+ if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
+ IWL_DEBUG_RATE("Can't switch with index %d rate mask %x\n",
+ rate, rate_mask);
return -1;
- rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
+ }
+ tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
- IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
- tbl->current_rate.rate_n_flags, is_green);
+ IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+ tbl->current_rate, is_green);
return 0;
-#else
- return -1;
-#endif /*CONFIG_IWL4965_HT */
}
/*
@@ -1250,21 +1215,20 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index)
{
-#ifdef CONFIG_IWL4965_HT
u16 rate_mask;
u8 is_green = lq_sta->is_green;
s32 rate;
- IWL_DEBUG_HT("LQ: try to switch to SISO\n");
if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
!sta->ht_info.ht_supported)
return -1;
+ IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
+
tbl->is_dup = lq_sta->is_dup;
tbl->lq_type = LQ_SISO;
tbl->action = 0;
- rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
- &rate_mask);
+ rate_mask = lq_sta->active_siso_rate;
if (priv->current_ht_config.supported_chan_width
== IWL_CHANNEL_WIDTH_40MHZ)
@@ -1272,6 +1236,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
else
tbl->is_fat = 0;
+ /* FIXME: - don't toggle SGI here
if (tbl->is_fat) {
if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
tbl->is_SGI = 1;
@@ -1281,27 +1246,24 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
tbl->is_SGI = 1;
else
tbl->is_SGI = 0;
+ */
if (is_green)
- tbl->is_SGI = 0;
+ tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
- rs_get_expected_tpt_table(lq_sta, tbl);
- rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
+ rs_set_expected_tpt_table(lq_sta, tbl);
+ rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
- IWL_DEBUG_HT("LQ: get best rate %d mask %X\n", rate, rate_mask);
+ IWL_DEBUG_RATE("LQ: get best rate %d mask %X\n", rate, rate_mask);
if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
- IWL_DEBUG_HT("can not switch with index %d rate mask %x\n",
+ IWL_DEBUG_RATE("can not switch with index %d rate mask %x\n",
rate, rate_mask);
return -1;
}
- rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
- IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
- tbl->current_rate.rate_n_flags, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
+ IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+ tbl->current_rate, is_green);
return 0;
-#else
- return -1;
-
-#endif /*CONFIG_IWL4965_HT */
}
/*
@@ -1313,7 +1275,6 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
struct sta_info *sta,
int index)
{
- int ret = 0;
struct iwl4965_scale_tbl_info *tbl =
&(lq_sta->lq_info[lq_sta->active_tbl]);
struct iwl4965_scale_tbl_info *search_tbl =
@@ -1322,41 +1283,35 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action;
+ u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
+ int ret = 0;
for (; ;) {
switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA:
- IWL_DEBUG_HT("LQ Legacy switch Antenna\n");
+ IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
- search_tbl->lq_type = LQ_NONE;
lq_sta->action_counter++;
/* Don't change antenna if success has been great */
if (window->success_ratio >= IWL_RS_GOOD_RATIO)
break;
- /* Don't change antenna if other one is not connected */
- if (!rs_is_other_ant_connected(lq_sta->antenna,
- tbl->antenna_type))
- break;
-
/* Set up search table to try other antenna */
memcpy(search_tbl, tbl, sz);
- rs_toggle_antenna(&(search_tbl->current_rate),
- search_tbl);
- rs_get_expected_tpt_table(lq_sta, search_tbl);
- lq_sta->search_better_tbl = 1;
- goto out;
-
+ if (rs_toggle_antenna(valid_tx_ant,
+ &search_tbl->current_rate, search_tbl)) {
+ lq_sta->search_better_tbl = 1;
+ goto out;
+ }
+ break;
case IWL_LEGACY_SWITCH_SISO:
- IWL_DEBUG_HT("LQ: Legacy switch to SISO\n");
+ IWL_DEBUG_RATE("LQ: Legacy switch to SISO\n");
/* Set up search table to try SISO */
memcpy(search_tbl, tbl, sz);
- search_tbl->lq_type = LQ_SISO;
search_tbl->is_SGI = 0;
- search_tbl->is_fat = 0;
ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
search_tbl, index);
if (!ret) {
@@ -1366,16 +1321,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
}
break;
- case IWL_LEGACY_SWITCH_MIMO:
- IWL_DEBUG_HT("LQ: Legacy switch MIMO\n");
+ case IWL_LEGACY_SWITCH_MIMO2:
+ IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
/* Set up search table to try MIMO */
memcpy(search_tbl, tbl, sz);
- search_tbl->lq_type = LQ_MIMO;
search_tbl->is_SGI = 0;
- search_tbl->is_fat = 0;
- search_tbl->antenna_type = ANT_BOTH;
- ret = rs_switch_to_mimo(priv, lq_sta, conf, sta,
+ search_tbl->ant_type = ANT_AB;/*FIXME:RS*/
+ /*FIXME:RS:need to check ant validity*/
+ ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
search_tbl, index);
if (!ret) {
lq_sta->search_better_tbl = 1;
@@ -1385,7 +1339,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
break;
}
tbl->action++;
- if (tbl->action > IWL_LEGACY_SWITCH_MIMO)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
if (tbl->action == start_action)
@@ -1396,7 +1350,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
out:
tbl->action++;
- if (tbl->action > IWL_LEGACY_SWITCH_MIMO)
+ if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
return 0;
@@ -1411,7 +1365,6 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
struct sta_info *sta,
int index)
{
- int ret;
u8 is_green = lq_sta->is_green;
struct iwl4965_scale_tbl_info *tbl =
&(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1421,35 +1374,30 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action;
+ u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
+ int ret;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
case IWL_SISO_SWITCH_ANTENNA:
- IWL_DEBUG_HT("LQ: SISO SWITCH ANTENNA SISO\n");
- search_tbl->lq_type = LQ_NONE;
+ IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
if (window->success_ratio >= IWL_RS_GOOD_RATIO)
break;
- if (!rs_is_other_ant_connected(lq_sta->antenna,
- tbl->antenna_type))
- break;
memcpy(search_tbl, tbl, sz);
- search_tbl->action = IWL_SISO_SWITCH_MIMO;
- rs_toggle_antenna(&(search_tbl->current_rate),
- search_tbl);
- lq_sta->search_better_tbl = 1;
-
- goto out;
-
- case IWL_SISO_SWITCH_MIMO:
- IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO FROM SISO\n");
+ if (rs_toggle_antenna(valid_tx_ant,
+ &search_tbl->current_rate, search_tbl)) {
+ lq_sta->search_better_tbl = 1;
+ goto out;
+ }
+ break;
+ case IWL_SISO_SWITCH_MIMO2:
+ IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
memcpy(search_tbl, tbl, sz);
- search_tbl->lq_type = LQ_MIMO;
search_tbl->is_SGI = 0;
- search_tbl->is_fat = 0;
- search_tbl->antenna_type = ANT_BOTH;
- ret = rs_switch_to_mimo(priv, lq_sta, conf, sta,
+ search_tbl->ant_type = ANT_AB; /*FIXME:RS*/
+ ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
search_tbl, index);
if (!ret) {
lq_sta->search_better_tbl = 1;
@@ -1457,29 +1405,34 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
}
break;
case IWL_SISO_SWITCH_GI:
- IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n");
+ if (!tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_20MHZ))
+ break;
+ if (tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_40MHZ))
+ break;
+
+ IWL_DEBUG_RATE("LQ: SISO toggle SGI/NGI\n");
memcpy(search_tbl, tbl, sz);
- search_tbl->action = 0;
- if (search_tbl->is_SGI)
- search_tbl->is_SGI = 0;
- else if (!is_green)
- search_tbl->is_SGI = 1;
- else
- break;
- lq_sta->search_better_tbl = 1;
- if ((tbl->lq_type == LQ_SISO) &&
- (tbl->is_SGI)) {
+ if (is_green) {
+ if (!tbl->is_SGI)
+ break;
+ else
+ IWL_ERROR("SGI was set in GF+SISO\n");
+ }
+ search_tbl->is_SGI = !tbl->is_SGI;
+ rs_set_expected_tpt_table(lq_sta, search_tbl);
+ if (tbl->is_SGI) {
s32 tpt = lq_sta->last_tpt / 100;
- if (((!tbl->is_fat) &&
- (tpt >= expected_tpt_siso20MHz[index])) ||
- ((tbl->is_fat) &&
- (tpt >= expected_tpt_siso40MHz[index])))
- lq_sta->search_better_tbl = 0;
+ if (tpt >= search_tbl->expected_tpt[index])
+ break;
}
- rs_get_expected_tpt_table(lq_sta, search_tbl);
- rs_mcs_from_tbl(&search_tbl->current_rate,
- search_tbl, index, is_green);
+ search_tbl->current_rate = rate_n_flags_from_tbl(
+ search_tbl, index, is_green);
+ lq_sta->search_better_tbl = 1;
goto out;
}
tbl->action++;
@@ -1507,7 +1460,6 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
struct sta_info *sta,
int index)
{
- int ret;
s8 is_green = lq_sta->is_green;
struct iwl4965_scale_tbl_info *tbl =
&(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1516,24 +1468,24 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action;
+ /*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/
+ int ret;
for (;;) {
lq_sta->action_counter++;
switch (tbl->action) {
case IWL_MIMO_SWITCH_ANTENNA_A:
case IWL_MIMO_SWITCH_ANTENNA_B:
- IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n");
-
+ IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
/* Set up new search table for SISO */
memcpy(search_tbl, tbl, sz);
- search_tbl->lq_type = LQ_SISO;
- search_tbl->is_SGI = 0;
- search_tbl->is_fat = 0;
+
+ /*FIXME:RS:need to check ant validity + C*/
if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
- search_tbl->antenna_type = ANT_MAIN;
+ search_tbl->ant_type = ANT_A;
else
- search_tbl->antenna_type = ANT_AUX;
+ search_tbl->ant_type = ANT_B;
ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
search_tbl, index);
@@ -1544,37 +1496,35 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
break;
case IWL_MIMO_SWITCH_GI:
- IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n");
+ if (!tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_20MHZ))
+ break;
+ if (tbl->is_fat &&
+ !(priv->current_ht_config.sgf &
+ HT_SHORT_GI_40MHZ))
+ break;
+
+ IWL_DEBUG_RATE("LQ: MIMO toggle SGI/NGI\n");
/* Set up new search table for MIMO */
memcpy(search_tbl, tbl, sz);
- search_tbl->lq_type = LQ_MIMO;
- search_tbl->antenna_type = ANT_BOTH;
- search_tbl->action = 0;
- if (search_tbl->is_SGI)
- search_tbl->is_SGI = 0;
- else
- search_tbl->is_SGI = 1;
- lq_sta->search_better_tbl = 1;
-
+ search_tbl->is_SGI = !tbl->is_SGI;
+ rs_set_expected_tpt_table(lq_sta, search_tbl);
/*
* If active table already uses the fastest possible
* modulation (dual stream with short guard interval),
* and it's working well, there's no need to look
* for a better type of modulation!
*/
- if ((tbl->lq_type == LQ_MIMO) &&
- (tbl->is_SGI)) {
+ if (tbl->is_SGI) {
s32 tpt = lq_sta->last_tpt / 100;
- if (((!tbl->is_fat) &&
- (tpt >= expected_tpt_mimo20MHz[index])) ||
- ((tbl->is_fat) &&
- (tpt >= expected_tpt_mimo40MHz[index])))
- lq_sta->search_better_tbl = 0;
+ if (tpt >= search_tbl->expected_tpt[index])
+ break;
}
- rs_get_expected_tpt_table(lq_sta, search_tbl);
- rs_mcs_from_tbl(&search_tbl->current_rate,
- search_tbl, index, is_green);
+ search_tbl->current_rate = rate_n_flags_from_tbl(
+ search_tbl, index, is_green);
+ lq_sta->search_better_tbl = 1;
goto out;
}
@@ -1608,7 +1558,9 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
int i;
int active_tbl;
int flush_interval_passed = 0;
+ struct iwl_priv *priv;
+ priv = lq_sta->drv;
active_tbl = lq_sta->active_tbl;
tbl = &(lq_sta->lq_info[active_tbl]);
@@ -1623,9 +1575,6 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
(unsigned long)(lq_sta->flush_timer +
IWL_RATE_SCALE_FLUSH_INTVL));
- /* For now, disable the elapsed time criterion */
- flush_interval_passed = 0;
-
/*
* Check if we should allow search for new modulation mode.
* If many frames have failed or succeeded, or we've used
@@ -1638,7 +1587,7 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
(lq_sta->total_success > lq_sta->max_success_limit) ||
((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
&& (flush_interval_passed))) {
- IWL_DEBUG_HT("LQ: stay is expired %d %d %d\n:",
+ IWL_DEBUG_RATE("LQ: stay is expired %d %d %d\n:",
lq_sta->total_failed,
lq_sta->total_success,
flush_interval_passed);
@@ -1661,7 +1610,7 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
lq_sta->table_count_limit) {
lq_sta->table_count = 0;
- IWL_DEBUG_HT("LQ: stay in table clear win\n");
+ IWL_DEBUG_RATE("LQ: stay in table clear win\n");
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(
&(tbl->win[i]));
@@ -1699,24 +1648,23 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
int high_tpt = IWL_INVALID_VALUE;
u32 fail_count;
s8 scale_action = 0;
- u16 fc, rate_mask;
+ __le16 fc;
+ u16 rate_mask;
u8 update_lq = 0;
struct iwl4965_lq_sta *lq_sta;
struct iwl4965_scale_tbl_info *tbl, *tbl1;
u16 rate_scale_index_msk = 0;
- struct iwl4965_rate mcs_rate;
+ u32 rate;
u8 is_green = 0;
u8 active_tbl = 0;
u8 done_search = 0;
u16 high_low;
-#ifdef CONFIG_IWL4965_HT
+ s32 sr;
u8 tid = MAX_TID_COUNT;
- __le16 *qc;
-#endif
IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
- fc = le16_to_cpu(hdr->frame_control);
+ fc = hdr->frame_control;
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
/* Send management frames and broadcast/multicast data using
* lowest rate. */
@@ -1727,19 +1675,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (!sta || !sta->rate_ctrl_priv)
return;
- if (!priv->lq_mngr.lq_ready) {
- IWL_DEBUG_RATE("still rate scaling not ready\n");
- return;
- }
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
-#ifdef CONFIG_IWL4965_HT
- qc = ieee80211_get_qos_ctrl(hdr);
- if (qc) {
- tid = (u8)(le16_to_cpu(*qc) & 0xf);
- rs_tl_add_packet(lq_sta, tid);
- }
-#endif
+ tid = rs_tl_add_packet(lq_sta, hdr);
+
/*
* Select rate-scale / modulation-mode table to work with in
* the rest of this function: "search" if searching for better
@@ -1760,8 +1699,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl->lq_type);
/* rates available for this association, and for modulation mode */
- rs_get_supported_rates(lq_sta, hdr, tbl->lq_type,
- &rate_mask);
+ rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
@@ -1781,27 +1719,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (!rate_scale_index_msk)
rate_scale_index_msk = rate_mask;
- /* If current rate is no longer supported on current association,
- * or user changed preferences for rates, find a new supported rate. */
- if (index < 0 || !((1 << index) & rate_scale_index_msk)) {
- index = IWL_INVALID_VALUE;
- update_lq = 1;
-
- /* get the highest available rate */
- for (i = 0; i <= IWL_RATE_COUNT; i++) {
- if ((1 << i) & rate_scale_index_msk)
- index = i;
- }
-
- if (index == IWL_INVALID_VALUE) {
- IWL_WARNING("Can not find a suitable rate\n");
- return;
- }
+ if (!((1 << index) & rate_scale_index_msk)) {
+ IWL_ERROR("Current Rate is not valid\n");
+ return;
}
/* Get expected throughput table and history window for current rate */
- if (!tbl->expected_tpt)
- rs_get_expected_tpt_table(lq_sta, tbl);
+ if (!tbl->expected_tpt) {
+ IWL_ERROR("tbl->expected_tpt is NULL\n");
+ return;
+ }
window = &(tbl->win[index]);
@@ -1813,10 +1740,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* in current association (use new rate found above).
*/
fail_count = window->counter - window->success_counter;
- if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
- (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))
- || (tbl->expected_tpt == NULL)) {
- IWL_DEBUG_RATE("LQ: still below TH succ %d total %d "
+ if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
+ (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
+ IWL_DEBUG_RATE("LQ: still below TH. succ=%d total=%d "
"for index %d\n",
window->success_counter, window->counter, index);
@@ -1827,44 +1753,51 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* or search for a new one? */
rs_stay_in_table(lq_sta);
- /* Set up new rate table in uCode, if needed */
- if (update_lq) {
- rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
- rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
- }
goto out;
/* Else we have enough samples; calculate estimate of
* actual average throughput */
- } else
- window->average_tpt = ((window->success_ratio *
+ } else {
+ /*FIXME:RS remove this else if we don't get this error*/
+ if (window->average_tpt != ((window->success_ratio *
+ tbl->expected_tpt[index] + 64) / 128)) {
+ IWL_ERROR("expected_tpt should have been calculated"
+ " by now\n");
+ window->average_tpt = ((window->success_ratio *
tbl->expected_tpt[index] + 64) / 128);
+ }
+ }
/* If we are searching for better modulation mode, check success. */
if (lq_sta->search_better_tbl) {
- int success_limit = IWL_RATE_SCALE_SWITCH;
/* If good success, continue using the "search" mode;
* no need to send new link quality command, since we're
* continuing to use the setup that we've been trying. */
- if ((window->success_ratio > success_limit) ||
- (window->average_tpt > lq_sta->last_tpt)) {
- if (!is_legacy(tbl->lq_type)) {
- IWL_DEBUG_HT("LQ: we are switching to HT"
- " rate suc %d current tpt %d"
- " old tpt %d\n",
- window->success_ratio,
- window->average_tpt,
- lq_sta->last_tpt);
+ if (window->average_tpt > lq_sta->last_tpt) {
+
+ IWL_DEBUG_RATE("LQ: SWITCHING TO CURRENT TABLE "
+ "suc=%d cur-tpt=%d old-tpt=%d\n",
+ window->success_ratio,
+ window->average_tpt,
+ lq_sta->last_tpt);
+
+ if (!is_legacy(tbl->lq_type))
lq_sta->enable_counter = 1;
- }
+
/* Swap tables; "search" becomes "active" */
lq_sta->active_tbl = active_tbl;
current_tpt = window->average_tpt;
/* Else poor success; go back to mode in "active" table */
} else {
+
+ IWL_DEBUG_RATE("LQ: GOING BACK TO THE OLD TABLE "
+ "suc=%d cur-tpt=%d old-tpt=%d\n",
+ window->success_ratio,
+ window->average_tpt,
+ lq_sta->last_tpt);
+
/* Nullify "search" table */
tbl->lq_type = LQ_NONE;
@@ -1873,13 +1806,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl = &(lq_sta->lq_info[active_tbl]);
/* Revert to "active" rate and throughput info */
- index = iwl4965_hwrate_to_plcp_idx(
- tbl->current_rate.rate_n_flags);
+ index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
current_tpt = lq_sta->last_tpt;
/* Need to set up a new rate table in uCode */
update_lq = 1;
- IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n");
}
/* Either way, we've made a decision; modulation mode
@@ -1891,11 +1822,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* (Else) not in search of better modulation mode, try for better
* starting rate, while staying in this mode. */
- high_low = rs_get_adjacent_rate(index, rate_scale_index_msk,
+ high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk,
tbl->lq_type);
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ sr = window->success_ratio;
+
/* Collect measured throughputs for current and adjacent rates */
current_tpt = window->average_tpt;
if (low != IWL_RATE_INVALID)
@@ -1903,19 +1836,22 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (high != IWL_RATE_INVALID)
high_tpt = tbl->win[high].average_tpt;
- /* Assume rate increase */
- scale_action = 1;
+ scale_action = 0;
/* Too many failures, decrease rate */
- if ((window->success_ratio <= IWL_RATE_DECREASE_TH) ||
- (current_tpt == 0)) {
+ if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
scale_action = -1;
/* No throughput measured yet for adjacent rates; try increase. */
} else if ((low_tpt == IWL_INVALID_VALUE) &&
- (high_tpt == IWL_INVALID_VALUE))
- scale_action = 1;
+ (high_tpt == IWL_INVALID_VALUE)) {
+
+ if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
+ scale_action = 1;
+ else if (low != IWL_RATE_INVALID)
+ scale_action = -1;
+ }
/* Both adjacent throughputs are measured, but neither one has better
* throughput; we're using the best rate, don't change it! */
@@ -1931,9 +1867,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Higher adjacent rate's throughput is measured */
if (high_tpt != IWL_INVALID_VALUE) {
/* Higher rate has better throughput */
- if (high_tpt > current_tpt)
+ if (high_tpt > current_tpt &&
+ sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
- else {
+ } else {
IWL_DEBUG_RATE
("decrease rate because of high tpt\n");
scale_action = -1;
@@ -1946,23 +1883,17 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
IWL_DEBUG_RATE
("decrease rate because of low tpt\n");
scale_action = -1;
- } else
+ } else if (sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
+ }
}
}
/* Sanity check; asked for decrease, but success rate or throughput
* has been good at old rate. Don't change it. */
- if (scale_action == -1) {
- if ((low != IWL_RATE_INVALID) &&
- ((window->success_ratio > IWL_RATE_HIGH_TH) ||
+ if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
+ ((sr > IWL_RATE_HIGH_TH) ||
(current_tpt > (100 * tbl->expected_tpt[low]))))
- scale_action = 0;
-
- /* Sanity check; asked for increase, but success rate has not been great
- * even at old rate, higher rate will be worse. Don't change it. */
- } else if ((scale_action == 1) &&
- (window->success_ratio < IWL_RATE_INCREASE_TH))
scale_action = 0;
switch (scale_action) {
@@ -1987,15 +1918,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
break;
}
- IWL_DEBUG_HT("choose rate scale index %d action %d low %d "
+ IWL_DEBUG_RATE("choose rate scale index %d action %d low %d "
"high %d type %d\n",
index, scale_action, low, high, tbl->lq_type);
- lq_update:
+lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq) {
- rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
- rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
+ rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ rs_fill_link_cmd(priv, lq_sta, rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
}
@@ -2029,13 +1960,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rs_rate_scale_clear_window(&(tbl->win[i]));
/* Use new "search" start rate */
- index = iwl4965_hwrate_to_plcp_idx(
- tbl->current_rate.rate_n_flags);
+ index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
- IWL_DEBUG_HT("Switch current mcs: %X index: %d\n",
- tbl->current_rate.rate_n_flags, index);
- rs_fill_link_cmd(lq_sta, &tbl->current_rate,
- &lq_sta->lq);
+ IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",
+ tbl->current_rate, index);
+ rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
}
@@ -2046,13 +1975,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(tbl1->lq_type) &&
-#ifdef CONFIG_IWL4965_HT
(!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&
-#endif
(lq_sta->action_counter >= 1)) {
lq_sta->action_counter = 0;
- IWL_DEBUG_HT("LQ: STAY in legacy table\n");
- rs_set_stay_in_table(1, lq_sta);
+ IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
+ rs_set_stay_in_table(priv, 1, lq_sta);
}
/* If we're in an HT mode, and all 3 mode switch actions
@@ -2060,16 +1987,14 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter &&
(lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
-#ifdef CONFIG_IWL4965_HT
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
- IWL_DEBUG_HT("try to aggregate tid %d\n", tid);
+ IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);
rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
}
-#endif /*CONFIG_IWL4965_HT */
lq_sta->action_counter = 0;
- rs_set_stay_in_table(0, lq_sta);
+ rs_set_stay_in_table(priv, 0, lq_sta);
}
/*
@@ -2085,7 +2010,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
}
out:
- rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green);
i = index;
sta->last_txrate_idx = i;
@@ -2105,13 +2030,14 @@ static void rs_initialize_lq(struct iwl_priv *priv,
struct ieee80211_conf *conf,
struct sta_info *sta)
{
- int i;
struct iwl4965_lq_sta *lq_sta;
struct iwl4965_scale_tbl_info *tbl;
- u8 active_tbl = 0;
int rate_idx;
+ int i;
+ u32 rate;
u8 use_green = rs_use_green(priv, conf);
- struct iwl4965_rate mcs_rate;
+ u8 active_tbl = 0;
+ u8 valid_tx_ant;
if (!sta || !sta->rate_ctrl_priv)
goto out;
@@ -2123,6 +2049,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
(priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
goto out;
+ valid_tx_ant = priv->hw_params.valid_tx_ant;
+
if (!lq_sta->search_better_tbl)
active_tbl = lq_sta->active_tbl;
else
@@ -2133,22 +2061,23 @@ static void rs_initialize_lq(struct iwl_priv *priv,
if ((i < 0) || (i >= IWL_RATE_COUNT))
i = 0;
- mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ;
- mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK;
- mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
+ /* FIXME:RS: This is also wrong in 4965 */
+ rate = iwl_rates[i].plcp;
+ rate |= RATE_MCS_ANT_B_MSK;
+ rate &= ~RATE_MCS_ANT_A_MSK;
if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
- mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK;
+ rate |= RATE_MCS_CCK_MSK;
- tbl->antenna_type = ANT_AUX;
- rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx);
- if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type))
- rs_toggle_antenna(&mcs_rate, tbl);
+ tbl->ant_type = ANT_B;
+ rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx);
+ if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
+ rs_toggle_antenna(valid_tx_ant, &rate, tbl);
- rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
- tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
- rs_get_expected_tpt_table(lq_sta, tbl);
- rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
+ rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
+ tbl->current_rate = rate;
+ rs_set_expected_tpt_table(lq_sta, tbl);
+ rs_fill_link_cmd(NULL, lq_sta, rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
out:
return;
@@ -2165,7 +2094,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
struct ieee80211_conf *conf = &local->hw.conf;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct sta_info *sta;
- u16 fc;
+ __le16 fc;
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl4965_lq_sta *lq_sta;
@@ -2177,10 +2106,10 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
/* Send management frames and broadcast/multicast data using lowest
* rate. */
- fc = le16_to_cpu(hdr->frame_control);
+ fc = hdr->frame_control;
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
!sta || !sta->rate_ctrl_priv) {
- sel->rate = rate_lowest(local, sband, sta);
+ sel->rate_idx = rate_lowest_index(local, sband, sta);
goto out;
}
@@ -2189,13 +2118,13 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
!lq_sta->ibss_sta_added) {
- u8 sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
+ u8 sta_id = iwl_find_station(priv, hdr->addr1);
DECLARE_MAC_BUF(mac);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE("LQ: ADD station %s\n",
print_mac(mac, hdr->addr1));
- sta_id = iwl4965_add_station_flags(priv, hdr->addr1,
+ sta_id = iwl_add_station_flags(priv, hdr->addr1,
0, CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
@@ -2204,26 +2133,27 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
lq_sta->ibss_sta_added = 1;
rs_initialize_lq(priv, conf, sta);
}
- if (!lq_sta->ibss_sta_added)
- goto done;
}
-done:
if ((i < 0) || (i > IWL_RATE_COUNT)) {
- sel->rate = rate_lowest(local, sband, sta);
+ sel->rate_idx = rate_lowest_index(local, sband, sta);
goto out;
}
- sel->rate = &priv->ieee_rates[i];
+ if (sband->band == IEEE80211_BAND_5GHZ)
+ i -= IWL_FIRST_OFDM_RATE;
+ sel->rate_idx = i;
out:
rcu_read_unlock();
}
-static void *rs_alloc_sta(void *priv, gfp_t gfp)
+static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
{
struct iwl4965_lq_sta *lq_sta;
+ struct iwl_priv *priv;
int i, j;
+ priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE("create station rate scale window\n");
lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp);
@@ -2259,7 +2189,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
- IWL_DEBUG_RATE("rate scale global init\n");
+ IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from
* previous packets? Need to have IEEE 802.1X auth succeed immediately
@@ -2267,17 +2197,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta->ibss_sta_added = 0;
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
- u8 sta_id = iwl4965_hw_find_station(priv, sta->addr);
+ u8 sta_id = iwl_find_station(priv, sta->addr);
DECLARE_MAC_BUF(mac);
/* for IBSS the call are from tasklet */
- IWL_DEBUG_HT("LQ: ADD station %s\n",
+ IWL_DEBUG_RATE("LQ: ADD station %s\n",
print_mac(mac, sta->addr));
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE("LQ: ADD station %s\n",
print_mac(mac, sta->addr));
- sta_id = iwl4965_add_station_flags(priv, sta->addr,
+ sta_id = iwl_add_station_flags(priv, sta->addr,
0, CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
@@ -2300,92 +2230,95 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
lq_sta->is_dup = 0;
- lq_sta->valid_antenna = priv->valid_antenna;
- lq_sta->antenna = priv->antenna;
lq_sta->is_green = rs_use_green(priv, conf);
- lq_sta->active_rate = priv->active_rate;
- lq_sta->active_rate &= ~(0x1000);
+ lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic;
lq_sta->band = priv->band;
-#ifdef CONFIG_IWL4965_HT
/*
* active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
* supp_rates[] does not; shift to convert format, force 9 MBits off.
*/
- lq_sta->active_siso_rate = (priv->current_ht_config.supp_mcs_set[0] << 1);
- lq_sta->active_siso_rate |=
- (priv->current_ht_config.supp_mcs_set[0] & 0x1);
+ lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1;
+ lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1;
lq_sta->active_siso_rate &= ~((u16)0x2);
- lq_sta->active_siso_rate =
- lq_sta->active_siso_rate << IWL_FIRST_OFDM_RATE;
+ lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
/* Same here */
- lq_sta->active_mimo_rate = (priv->current_ht_config.supp_mcs_set[1] << 1);
- lq_sta->active_mimo_rate |=
- (priv->current_ht_config.supp_mcs_set[1] & 0x1);
- lq_sta->active_mimo_rate &= ~((u16)0x2);
- lq_sta->active_mimo_rate =
- lq_sta->active_mimo_rate << IWL_FIRST_OFDM_RATE;
- IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n",
+ lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1;
+ lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1;
+ lq_sta->active_mimo2_rate &= ~((u16)0x2);
+ lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
+
+ lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1;
+ lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1;
+ lq_sta->active_mimo3_rate &= ~((u16)0x2);
+ lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
+
+ IWL_DEBUG_RATE("SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
lq_sta->active_siso_rate,
- lq_sta->active_mimo_rate);
+ lq_sta->active_mimo2_rate,
+ lq_sta->active_mimo3_rate);
+
+ /* These values will be overriden later */
+ lq_sta->lq.general_params.single_stream_ant_msk = ANT_A;
+ lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
+
/* as default allow aggregation for all tids */
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
-#endif /*CONFIG_IWL4965_HT*/
-#ifdef CONFIG_MAC80211_DEBUGFS
lq_sta->drv = priv;
-#endif
-
- if (priv->assoc_station_added)
- priv->lq_mngr.lq_ready = 1;
rs_initialize_lq(priv, conf, sta);
}
-static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
- struct iwl4965_rate *tx_mcs,
- struct iwl_link_quality_cmd *lq_cmd)
+static void rs_fill_link_cmd(const struct iwl_priv *priv,
+ struct iwl4965_lq_sta *lq_sta,
+ u32 new_rate)
{
+ struct iwl4965_scale_tbl_info tbl_type;
int index = 0;
int rate_idx;
int repeat_rate = 0;
- u8 ant_toggle_count = 0;
+ u8 ant_toggle_cnt = 0;
u8 use_ht_possible = 1;
- struct iwl4965_rate new_rate;
- struct iwl4965_scale_tbl_info tbl_type = { 0 };
+ u8 valid_tx_ant = 0;
+ struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
/* Override starting rate (index 0) if needed for debug purposes */
- rs_dbgfs_set_mcs(lq_sta, tx_mcs, index);
+ rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
- /* Interpret rate_n_flags */
- rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band,
+ /* Interpret new_rate (rate_n_flags) */
+ memset(&tbl_type, 0, sizeof(tbl_type));
+ rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
&tbl_type, &rate_idx);
/* How many times should we repeat the initial rate? */
if (is_legacy(tbl_type.lq_type)) {
- ant_toggle_count = 1;
+ ant_toggle_cnt = 1;
repeat_rate = IWL_NUMBER_TRY;
- } else
+ } else {
repeat_rate = IWL_HT_NUMBER_TRY;
+ }
lq_cmd->general_params.mimo_delimiter =
is_mimo(tbl_type.lq_type) ? 1 : 0;
/* Fill 1st table entry (index 0) */
- lq_cmd->rs_table[index].rate_n_flags =
- cpu_to_le32(tx_mcs->rate_n_flags);
- new_rate.rate_n_flags = tx_mcs->rate_n_flags;
+ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
- if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN))
- lq_cmd->general_params.single_stream_ant_msk
- = LINK_QUAL_ANT_A_MSK;
- else
- lq_cmd->general_params.single_stream_ant_msk
- = LINK_QUAL_ANT_B_MSK;
+ if (num_of_ant(tbl_type.ant_type) == 1) {
+ lq_cmd->general_params.single_stream_ant_msk =
+ tbl_type.ant_type;
+ } else if (num_of_ant(tbl_type.ant_type) == 2) {
+ lq_cmd->general_params.dual_stream_ant_msk =
+ tbl_type.ant_type;
+ } /* otherwise we don't modify the existing value */
index++;
repeat_rate--;
+ if (priv)
+ valid_tx_ant = priv->hw_params.valid_tx_ant;
+
/* Fill rest of rate table */
while (index < LINK_QUAL_MAX_RETRY_NUM) {
/* Repeat initial/next rate.
@@ -2393,26 +2326,25 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
* For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
if (is_legacy(tbl_type.lq_type)) {
- if (ant_toggle_count <
- NUM_TRY_BEFORE_ANTENNA_TOGGLE)
- ant_toggle_count++;
- else {
- rs_toggle_antenna(&new_rate, &tbl_type);
- ant_toggle_count = 1;
- }
- }
+ if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
+ ant_toggle_cnt++;
+ else if (priv &&
+ rs_toggle_antenna(valid_tx_ant,
+ &new_rate, &tbl_type))
+ ant_toggle_cnt = 1;
+}
/* Override next rate if needed for debug purposes */
rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
/* Fill next table entry */
lq_cmd->rs_table[index].rate_n_flags =
- cpu_to_le32(new_rate.rate_n_flags);
+ cpu_to_le32(new_rate);
repeat_rate--;
index++;
}
- rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type,
+ rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
&rate_idx);
/* Indicate to uCode which entries might be MIMO.
@@ -2422,20 +2354,22 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
lq_cmd->general_params.mimo_delimiter = index;
/* Get next rate */
- rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
- use_ht_possible, &new_rate);
+ new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
+ use_ht_possible);
/* How many times should we repeat the next rate? */
if (is_legacy(tbl_type.lq_type)) {
- if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
- ant_toggle_count++;
- else {
- rs_toggle_antenna(&new_rate, &tbl_type);
- ant_toggle_count = 1;
- }
+ if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
+ ant_toggle_cnt++;
+ else if (priv &&
+ rs_toggle_antenna(valid_tx_ant,
+ &new_rate, &tbl_type))
+ ant_toggle_cnt = 1;
+
repeat_rate = IWL_NUMBER_TRY;
- } else
+ } else {
repeat_rate = IWL_HT_NUMBER_TRY;
+ }
/* Don't allow HT rates after next pass.
* rs_get_lower_rate() will change type to LQ_A or LQ_G. */
@@ -2445,14 +2379,13 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
/* Fill next table entry */
- lq_cmd->rs_table[index].rate_n_flags =
- cpu_to_le32(new_rate.rate_n_flags);
+ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
index++;
repeat_rate--;
}
- lq_cmd->general_params.dual_stream_ant_msk = 3;
+ lq_cmd->agg_params.agg_frame_cnt_limit = 64;
lq_cmd->agg_params.agg_dis_start_th = 3;
lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
}
@@ -2473,15 +2406,17 @@ static void rs_clear(void *priv_rate)
IWL_DEBUG_RATE("enter\n");
- priv->lq_mngr.lq_ready = 0;
+ /* TODO - add rate scale state reset */
IWL_DEBUG_RATE("leave\n");
}
-static void rs_free_sta(void *priv, void *priv_sta)
+static void rs_free_sta(void *priv_rate, void *priv_sta)
{
struct iwl4965_lq_sta *lq_sta = priv_sta;
+ struct iwl_priv *priv;
+ priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE("enter\n");
kfree(lq_sta);
IWL_DEBUG_RATE("leave\n");
@@ -2495,54 +2430,56 @@ static int open_file_generic(struct inode *inode, struct file *file)
return 0;
}
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
- struct iwl4965_rate *mcs, int index)
+ u32 *rate_n_flags, int index)
{
- u32 base_rate;
+ struct iwl_priv *priv;
- if (lq_sta->band == IEEE80211_BAND_5GHZ)
- base_rate = 0x800D;
- else
- base_rate = 0x820A;
-
- if (lq_sta->dbg_fixed.rate_n_flags) {
- if (index < 12)
- mcs->rate_n_flags = lq_sta->dbg_fixed.rate_n_flags;
- else
- mcs->rate_n_flags = base_rate;
+ priv = lq_sta->drv;
+ if (lq_sta->dbg_fixed_rate) {
+ if (index < 12) {
+ *rate_n_flags = lq_sta->dbg_fixed_rate;
+ } else {
+ if (lq_sta->band == IEEE80211_BAND_5GHZ)
+ *rate_n_flags = 0x800D;
+ else
+ *rate_n_flags = 0x820A;
+ }
IWL_DEBUG_RATE("Fixed rate ON\n");
- return;
+ } else {
+ IWL_DEBUG_RATE("Fixed rate OFF\n");
}
-
- IWL_DEBUG_RATE("Fixed rate OFF\n");
}
static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
struct iwl4965_lq_sta *lq_sta = file->private_data;
+ struct iwl_priv *priv;
char buf[64];
int buf_size;
u32 parsed_rate;
+ priv = lq_sta->drv;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%x", &parsed_rate) == 1)
- lq_sta->dbg_fixed.rate_n_flags = parsed_rate;
+ lq_sta->dbg_fixed_rate = parsed_rate;
else
- lq_sta->dbg_fixed.rate_n_flags = 0;
+ lq_sta->dbg_fixed_rate = 0;
- lq_sta->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
- lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
- lq_sta->active_mimo_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
+ lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
+ lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
+ lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
+ lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
- lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags);
+ lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
- if (lq_sta->dbg_fixed.rate_n_flags) {
- rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq);
+ if (lq_sta->dbg_fixed_rate) {
+ rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
}
@@ -2561,9 +2498,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
lq_sta->total_failed, lq_sta->total_success,
- lq_sta->active_rate);
+ lq_sta->active_legacy_rate);
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
- lq_sta->dbg_fixed.rate_n_flags);
+ lq_sta->dbg_fixed_rate);
desc += sprintf(buff+desc, "general:"
"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
lq_sta->lq.general_params.flags,
@@ -2613,7 +2550,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
lq_sta->lq_info[i].is_SGI,
lq_sta->lq_info[i].is_fat,
lq_sta->lq_info[i].is_dup,
- lq_sta->lq_info[i].current_rate.rate_n_flags);
+ lq_sta->lq_info[i].current_rate);
for (j = 0; j < IWL_RATE_COUNT; j++) {
desc += sprintf(buff+desc,
"counter=%d success=%d %%=%d\n",
@@ -2640,11 +2577,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
-#ifdef CONFIG_IWL4965_HT
lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
&lq_sta->tx_agg_tid_en);
-#endif
}
@@ -2653,9 +2588,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
struct iwl4965_lq_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
-#ifdef CONFIG_IWL4965_HT
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
-#endif
}
#endif
@@ -2703,7 +2636,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
lq_sta = (void *)sta->rate_ctrl_priv;
lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
- antenna = lq_sta->lq_info[lq_sta->active_tbl].antenna_type;
+ antenna = lq_sta->lq_info[lq_sta->active_tbl].ant_type;
if (is_legacy(lq_type))
i = IWL_RATE_54M_INDEX;
@@ -2715,7 +2648,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
int active = lq_sta->active_tbl;
cnt +=
- sprintf(&buf[cnt], " %2dMbs: ", iwl4965_rates[i].ieee / 2);
+ sprintf(&buf[cnt], " %2dMbs: ", iwl_rates[i].ieee / 2);
mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
@@ -2726,7 +2659,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
samples += lq_sta->lq_info[active].win[i].counter;
good += lq_sta->lq_info[active].win[i].success_counter;
success += lq_sta->lq_info[active].win[i].success_counter *
- iwl4965_rates[i].ieee;
+ iwl_rates[i].ieee;
if (lq_sta->lq_info[active].win[i].stamp) {
int delta =
@@ -2746,10 +2679,11 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
i = j;
}
- /* Display the average rate of all samples taken.
- *
- * NOTE: We multiply # of samples by 2 since the IEEE measurement
- * added from iwl4965_rates is actually 2X the rate */
+ /*
+ * Display the average rate of all samples taken.
+ * NOTE: We multiply # of samples by 2 since the IEEE measurement
+ * added from iwl_rates is actually 2X the rate.
+ */
if (samples)
cnt += sprintf(&buf[cnt],
"\nAverage rate is %3d.%02dMbs over last %4dms\n"
@@ -2767,13 +2701,6 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
return cnt;
}
-void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
-{
- struct iwl_priv *priv = hw->priv;
-
- priv->lq_mngr.lq_ready = 1;
-}
-
int iwl4965_rate_control_register(void)
{
return ieee80211_rate_control_register(&rs_ops);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
index 866e378aa38..9b9972885aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
@@ -27,12 +27,13 @@
#ifndef __iwl_4965_rs_h__
#define __iwl_4965_rs_h__
-#include "iwl-4965.h"
+#include "iwl-dev.h"
-struct iwl4965_rate_info {
+struct iwl_rate_info {
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
- u8 plcp_mimo; /* uCode API: IWL_RATE_MIMO_6M_PLCP, etc. */
+ u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
+ u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
u8 prev_ieee; /* previous rate in IEEE speeds */
u8 next_ieee; /* next rate in IEEE speeds */
@@ -44,7 +45,7 @@ struct iwl4965_rate_info {
/*
* These serve as indexes into
- * struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
+ * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
*/
enum {
IWL_RATE_1M_INDEX = 0,
@@ -60,9 +61,9 @@ enum {
IWL_RATE_48M_INDEX,
IWL_RATE_54M_INDEX,
IWL_RATE_60M_INDEX,
- IWL_RATE_COUNT,
+ IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
- IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
+ IWL_RATE_INVALID = IWL_RATE_COUNT,
};
enum {
@@ -97,11 +98,13 @@ enum {
IWL_RATE_36M_PLCP = 11,
IWL_RATE_48M_PLCP = 1,
IWL_RATE_54M_PLCP = 3,
- IWL_RATE_60M_PLCP = 3,
+ IWL_RATE_60M_PLCP = 3,/*FIXME:RS:should be removed*/
IWL_RATE_1M_PLCP = 10,
IWL_RATE_2M_PLCP = 20,
IWL_RATE_5M_PLCP = 55,
IWL_RATE_11M_PLCP = 110,
+ /*FIXME:RS:change to IWL_RATE_LEGACY_??M_PLCP */
+ /*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
};
/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
@@ -114,16 +117,25 @@ enum {
IWL_RATE_SISO_48M_PLCP = 5,
IWL_RATE_SISO_54M_PLCP = 6,
IWL_RATE_SISO_60M_PLCP = 7,
- IWL_RATE_MIMO_6M_PLCP = 0x8,
- IWL_RATE_MIMO_12M_PLCP = 0x9,
- IWL_RATE_MIMO_18M_PLCP = 0xa,
- IWL_RATE_MIMO_24M_PLCP = 0xb,
- IWL_RATE_MIMO_36M_PLCP = 0xc,
- IWL_RATE_MIMO_48M_PLCP = 0xd,
- IWL_RATE_MIMO_54M_PLCP = 0xe,
- IWL_RATE_MIMO_60M_PLCP = 0xf,
+ IWL_RATE_MIMO2_6M_PLCP = 0x8,
+ IWL_RATE_MIMO2_12M_PLCP = 0x9,
+ IWL_RATE_MIMO2_18M_PLCP = 0xa,
+ IWL_RATE_MIMO2_24M_PLCP = 0xb,
+ IWL_RATE_MIMO2_36M_PLCP = 0xc,
+ IWL_RATE_MIMO2_48M_PLCP = 0xd,
+ IWL_RATE_MIMO2_54M_PLCP = 0xe,
+ IWL_RATE_MIMO2_60M_PLCP = 0xf,
+ IWL_RATE_MIMO3_6M_PLCP = 0x10,
+ IWL_RATE_MIMO3_12M_PLCP = 0x11,
+ IWL_RATE_MIMO3_18M_PLCP = 0x12,
+ IWL_RATE_MIMO3_24M_PLCP = 0x13,
+ IWL_RATE_MIMO3_36M_PLCP = 0x14,
+ IWL_RATE_MIMO3_48M_PLCP = 0x15,
+ IWL_RATE_MIMO3_54M_PLCP = 0x16,
+ IWL_RATE_MIMO3_60M_PLCP = 0x17,
IWL_RATE_SISO_INVM_PLCP,
- IWL_RATE_MIMO_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
+ IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
+ IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
};
/* MAC header values for bit rates */
@@ -196,11 +208,11 @@ enum {
/* possible actions when in legacy mode */
#define IWL_LEGACY_SWITCH_ANTENNA 0
#define IWL_LEGACY_SWITCH_SISO 1
-#define IWL_LEGACY_SWITCH_MIMO 2
+#define IWL_LEGACY_SWITCH_MIMO2 2
/* possible actions when in siso mode */
#define IWL_SISO_SWITCH_ANTENNA 0
-#define IWL_SISO_SWITCH_MIMO 1
+#define IWL_SISO_SWITCH_MIMO2 1
#define IWL_SISO_SWITCH_GI 2
/* possible actions when in mimo mode */
@@ -208,6 +220,10 @@ enum {
#define IWL_MIMO_SWITCH_ANTENNA_B 1
#define IWL_MIMO_SWITCH_GI 2
+/*FIXME:RS:separate MIMO2/3 transitions*/
+
+/*FIXME:RS:add posible acctions for MIMO3*/
+
#define IWL_ACTION_LIMIT 3 /* # possible actions */
#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */
@@ -224,43 +240,52 @@ enum {
#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
-extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
+extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
-enum iwl4965_table_type {
+enum iwl_table_type {
LQ_NONE,
LQ_G, /* legacy types */
LQ_A,
LQ_SISO, /* high-throughput types */
- LQ_MIMO,
+ LQ_MIMO2,
+ LQ_MIMO3,
LQ_MAX,
};
#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
-#define is_siso(tbl) (((tbl) == LQ_SISO))
-#define is_mimo(tbl) (((tbl) == LQ_MIMO))
+#define is_siso(tbl) ((tbl) == LQ_SISO)
+#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
+#define is_mimo3(tbl) ((tbl) == LQ_MIMO3)
+#define is_mimo(tbl) (is_mimo2(tbl) || is_mimo3(tbl))
#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
-#define is_a_band(tbl) (((tbl) == LQ_A))
-#define is_g_and(tbl) (((tbl) == LQ_G))
-
-/* 4965 has 2 antennas/chains for Tx (but 3 for Rx) */
-enum iwl4965_antenna_type {
- ANT_NONE,
- ANT_MAIN,
- ANT_AUX,
- ANT_BOTH,
-};
+#define is_a_band(tbl) ((tbl) == LQ_A)
+#define is_g_and(tbl) ((tbl) == LQ_G)
+
+#define ANT_NONE 0x0
+#define ANT_A BIT(0)
+#define ANT_B BIT(1)
+#define ANT_AB (ANT_A | ANT_B)
+#define ANT_C BIT(2)
+#define ANT_AC (ANT_A | ANT_C)
+#define ANT_BC (ANT_B | ANT_C)
+#define ANT_ABC (ANT_AB | ANT_C)
+
+static inline u8 num_of_ant(u8 mask)
+{
+ return !!((mask) & ANT_A) +
+ !!((mask) & ANT_B) +
+ !!((mask) & ANT_C);
+}
static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
{
- u8 rate = iwl4965_rates[rate_index].prev_ieee;
+ u8 rate = iwl_rates[rate_index].prev_ieee;
if (rate == IWL_RATE_INVALID)
rate = rate_index;
return rate;
}
-extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags);
-
/**
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
*
@@ -271,14 +296,6 @@ extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags);
extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
/**
- * iwl4965_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
-/**
* iwl4965_rate_control_register - Register the rate control algorithm callbacks
*
* Since the rate control algorithm is hardware specific, there is no need
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index de330ae0ca9..9afecb81371 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -39,81 +39,33 @@
#include <asm/unaligned.h>
#include "iwl-eeprom.h"
-#include "iwl-4965.h"
+#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
+#include "iwl-calib.h"
+#include "iwl-sta.h"
+
+static int iwl4965_send_tx_power(struct iwl_priv *priv);
+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
+
+/* Change firmware file name, using "-" and incrementing number,
+ * *only* when uCode interface or architecture changes so that it
+ * is not compatible with earlier drivers.
+ * This number will also appear in << 8 position of 1st dword of uCode file */
+#define IWL4965_UCODE_API "-2"
+
/* module parameters */
static struct iwl_mod_params iwl4965_mod_params = {
- .num_of_queues = IWL4965_MAX_NUM_QUEUES,
+ .num_of_queues = IWL49_NUM_QUEUES,
+ .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
.enable_qos = 1,
.amsdu_size_8K = 1,
+ .restart_fw = 1,
/* the rest are 0 by default */
};
-static void iwl4965_hw_card_show_info(struct iwl_priv *priv);
-
-#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
- [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
- IWL_RATE_SISO_##s##M_PLCP, \
- IWL_RATE_MIMO_##s##M_PLCP, \
- IWL_RATE_##r##M_IEEE, \
- IWL_RATE_##ip##M_INDEX, \
- IWL_RATE_##in##M_INDEX, \
- IWL_RATE_##rp##M_INDEX, \
- IWL_RATE_##rn##M_INDEX, \
- IWL_RATE_##pp##M_INDEX, \
- IWL_RATE_##np##M_INDEX }
-
-/*
- * Parameter order:
- * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
- *
- * If there isn't a valid next or previous rate then INV is used which
- * maps to IWL_RATE_INVALID
- *
- */
-const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = {
- IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
- IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
- IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
- IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
- IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
- IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
- IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
- IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
- IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
- IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
- IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
- IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
- IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
-};
-
-#ifdef CONFIG_IWL4965_HT
-
-static const u16 default_tid_to_tx_fifo[] = {
- IWL_TX_FIFO_AC1,
- IWL_TX_FIFO_AC0,
- IWL_TX_FIFO_AC0,
- IWL_TX_FIFO_AC1,
- IWL_TX_FIFO_AC2,
- IWL_TX_FIFO_AC2,
- IWL_TX_FIFO_AC3,
- IWL_TX_FIFO_AC3,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_NONE,
- IWL_TX_FIFO_AC3
-};
-
-#endif /*CONFIG_IWL4965_HT */
-
/* check contents of special bootstrap uCode SRAM */
static int iwl4965_verify_bsm(struct iwl_priv *priv)
{
@@ -192,15 +144,18 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
IWL_DEBUG_INFO("Begin load bsm\n");
+ priv->ucode_type = UCODE_RT;
+
/* make sure bootstrap program is no larger than BSM's SRAM size */
if (len > IWL_MAX_BSM_SIZE)
return -EINVAL;
/* Tell bootstrap uCode where to find the "Initialize" uCode
* in host DRAM ... host DRAM physical address bits 35:4 for 4965.
- * NOTE: iwl4965_initialize_alive_start() will replace these values,
+ * NOTE: iwl_init_alive_start() will replace these values,
* after the "initialize" uCode has run, to point to
- * runtime/protocol instructions and backup data cache. */
+ * runtime/protocol instructions and backup data cache.
+ */
pinst = priv->ucode_init.p_addr >> 4;
pdata = priv->ucode_init_data.p_addr >> 4;
inst_len = priv->ucode_init.len;
@@ -259,271 +214,134 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
return 0;
}
-static int iwl4965_init_drv(struct iwl_priv *priv)
+/**
+ * iwl4965_set_ucode_ptrs - Set uCode address location
+ *
+ * Tell initialization uCode where to find runtime uCode.
+ *
+ * BSM registers initially contain pointers to initialization uCode.
+ * We need to replace them to load runtime uCode inst and data,
+ * and to save runtime data when powering down.
+ */
+static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
{
- int ret;
- int i;
-
- priv->antenna = (enum iwl4965_antenna)priv->cfg->mod_params->antenna;
- priv->retry_rate = 1;
- priv->ibss_beacon = NULL;
-
- spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
- spin_lock_init(&priv->sta_lock);
- spin_lock_init(&priv->hcmd_lock);
- spin_lock_init(&priv->lq_mngr.lock);
-
- priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
- sizeof(struct iwl4965_shared),
- &priv->shared_phys);
-
- if (!priv->shared_virt) {
- ret = -ENOMEM;
- goto err;
- }
-
- memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
-
-
- for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
-
- INIT_LIST_HEAD(&priv->free_frames);
-
- mutex_init(&priv->mutex);
-
- /* Clear the driver's (not device's) station table */
- iwlcore_clear_stations_table(priv);
-
- priv->data_retry_limit = -1;
- priv->ieee_channels = NULL;
- priv->ieee_rates = NULL;
- priv->band = IEEE80211_BAND_2GHZ;
-
- priv->iw_mode = IEEE80211_IF_TYPE_STA;
-
- priv->use_ant_b_for_management_frame = 1; /* start with ant B */
- priv->valid_antenna = 0x7; /* assume all 3 connected */
- priv->ps_mode = IWL_MIMO_PS_NONE;
-
- /* Choose which receivers/antennas to use */
- iwl4965_set_rxon_chain(priv);
-
- iwlcore_reset_qos(priv);
-
- priv->qos_data.qos_active = 0;
- priv->qos_data.qos_cap.val = 0;
-
- iwlcore_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+ dma_addr_t pinst;
+ dma_addr_t pdata;
+ unsigned long flags;
+ int ret = 0;
- priv->rates_mask = IWL_RATES_MASK;
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IWL_POWER_AC;
- priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
+ /* bits 35:4 for 4965 */
+ pinst = priv->ucode_code.p_addr >> 4;
+ pdata = priv->ucode_data_backup.p_addr >> 4;
- ret = iwl_init_channel_map(priv);
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_ERROR("initializing regulatory failed: %d\n", ret);
- goto err;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
}
- ret = iwl4965_init_geos(priv);
- if (ret) {
- IWL_ERROR("initializing geos failed: %d\n", ret);
- goto err_free_channel_map;
- }
+ /* Tell bootstrap uCode where to find image to load */
+ iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+ iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+ priv->ucode_data.len);
- ret = ieee80211_register_hw(priv->hw);
- if (ret) {
- IWL_ERROR("Failed to register network device (error %d)\n",
- ret);
- goto err_free_geos;
- }
+ /* Inst bytecount must be last to set up, bit 31 signals uCode
+ * that all new ptr/size info is in place */
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+ priv->ucode_code.len | BSM_DRAM_INST_LOAD);
+ iwl_release_nic_access(priv);
- priv->hw->conf.beacon_int = 100;
- priv->mac80211_registered = 1;
+ spin_unlock_irqrestore(&priv->lock, flags);
- return 0;
+ IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
-err_free_geos:
- iwl4965_free_geos(priv);
-err_free_channel_map:
- iwl_free_channel_map(priv);
-err:
return ret;
}
-static int is_fat_channel(__le32 rxon_flags)
-{
- return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||
- (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
-}
-
-static u8 is_single_stream(struct iwl_priv *priv)
-{
-#ifdef CONFIG_IWL4965_HT
- if (!priv->current_ht_config.is_ht ||
- (priv->current_ht_config.supp_mcs_set[1] == 0) ||
- (priv->ps_mode == IWL_MIMO_PS_STATIC))
- return 1;
-#else
- return 1;
-#endif /*CONFIG_IWL4965_HT */
- return 0;
-}
-
-int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
-{
- int idx = 0;
-
- /* 4965 HT rate format */
- if (rate_n_flags & RATE_MCS_HT_MSK) {
- idx = (rate_n_flags & 0xff);
-
- if (idx >= IWL_RATE_MIMO_6M_PLCP)
- idx = idx - IWL_RATE_MIMO_6M_PLCP;
-
- idx += IWL_FIRST_OFDM_RATE;
- /* skip 9M not supported in ht*/
- if (idx >= IWL_RATE_9M_INDEX)
- idx += 1;
- if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
- return idx;
-
- /* 4965 legacy rate format, search for match in table */
- } else {
- for (idx = 0; idx < ARRAY_SIZE(iwl4965_rates); idx++)
- if (iwl4965_rates[idx].plcp == (rate_n_flags & 0xFF))
- return idx;
+/**
+ * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received
+ *
+ * Called after REPLY_ALIVE notification received from "initialize" uCode.
+ *
+ * The 4965 "initialize" ALIVE reply contains calibration data for:
+ * Voltage, temperature, and MIMO tx gain correction, now stored in priv
+ * (3945 does not contain this data).
+ *
+ * Tell "initialize" uCode to go ahead and load the runtime uCode.
+*/
+static void iwl4965_init_alive_start(struct iwl_priv *priv)
+{
+ /* Check alive response for "valid" sign from uCode */
+ if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
+ /* We had an error bringing up the hardware, so take it
+ * all the way back down so we can try again */
+ IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ goto restart;
+ }
+
+ /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
+ * This is a paranoid check, because we would not have gotten the
+ * "initialize" alive if code weren't properly loaded. */
+ if (iwl_verify_ucode(priv)) {
+ /* Runtime instruction load was bad;
+ * take it all the way back down so we can try again */
+ IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ goto restart;
+ }
+
+ /* Calculate temperature */
+ priv->temperature = iwl4965_hw_get_temperature(priv);
+
+ /* Send pointers to protocol/runtime uCode image ... init code will
+ * load and launch runtime uCode, which will send us another "Alive"
+ * notification. */
+ IWL_DEBUG_INFO("Initialization Alive received.\n");
+ if (iwl4965_set_ucode_ptrs(priv)) {
+ /* Runtime instruction load won't happen;
+ * take it all the way back down so we can try again */
+ IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+ goto restart;
}
+ return;
- return -1;
+restart:
+ queue_work(priv->workqueue, &priv->restart);
}
-/**
- * translate ucode response to mac80211 tx status control values
- */
-void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
- struct ieee80211_tx_control *control)
+static int is_fat_channel(__le32 rxon_flags)
{
- int rate_index;
-
- control->antenna_sel_tx =
- ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS);
- if (rate_n_flags & RATE_MCS_HT_MSK)
- control->flags |= IEEE80211_TXCTL_OFDM_HT;
- if (rate_n_flags & RATE_MCS_GF_MSK)
- control->flags |= IEEE80211_TXCTL_GREEN_FIELD;
- if (rate_n_flags & RATE_MCS_FAT_MSK)
- control->flags |= IEEE80211_TXCTL_40_MHZ_WIDTH;
- if (rate_n_flags & RATE_MCS_DUP_MSK)
- control->flags |= IEEE80211_TXCTL_DUP_DATA;
- if (rate_n_flags & RATE_MCS_SGI_MSK)
- control->flags |= IEEE80211_TXCTL_SHORT_GI;
- /* since iwl4965_hwrate_to_plcp_idx is band indifferent, we always use
- * IEEE80211_BAND_2GHZ band as it contains all the rates */
- rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
- if (rate_index == -1)
- control->tx_rate = NULL;
- else
- control->tx_rate =
- &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index];
+ return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||
+ (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
}
/*
- * Determine how many receiver/antenna chains to use.
- * More provides better reception via diversity. Fewer saves power.
- * MIMO (dual stream) requires at least 2, but works better with 3.
- * This does not determine *which* chains to use, just how many.
+ * EEPROM handlers
*/
-static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv,
- u8 *idle_state, u8 *rx_state)
-{
- u8 is_single = is_single_stream(priv);
- u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1;
-
- /* # of Rx chains to use when expecting MIMO. */
- if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC)))
- *rx_state = 2;
- else
- *rx_state = 3;
-
- /* # Rx chains when idling and maybe trying to save power */
- switch (priv->ps_mode) {
- case IWL_MIMO_PS_STATIC:
- case IWL_MIMO_PS_DYNAMIC:
- *idle_state = (is_cam) ? 2 : 1;
- break;
- case IWL_MIMO_PS_NONE:
- *idle_state = (is_cam) ? *rx_state : 1;
- break;
- default:
- *idle_state = 1;
- break;
- }
- return 0;
-}
-
-int iwl4965_hw_rxq_stop(struct iwl_priv *priv)
+static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
{
- int rc;
- unsigned long flags;
+ u16 eeprom_ver;
+ u16 calib_ver;
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
+ eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- /* stop Rx DMA */
- iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
- rc = iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
- (1 << 24), 1000);
- if (rc < 0)
- IWL_ERROR("Can't stop Rx DMA.\n");
+ calib_ver = iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
+ if (eeprom_ver < EEPROM_4965_EEPROM_VERSION ||
+ calib_ver < EEPROM_4965_TX_POWER_VERSION)
+ goto err;
return 0;
-}
-
-u8 iwl4965_hw_find_station(struct iwl_priv *priv, const u8 *addr)
-{
- int i;
- int start = 0;
- int ret = IWL_INVALID_STATION;
- unsigned long flags;
- DECLARE_MAC_BUF(mac);
-
- if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) ||
- (priv->iw_mode == IEEE80211_IF_TYPE_AP))
- start = IWL_STA_ID;
-
- if (is_broadcast_ether_addr(addr))
- return priv->hw_params.bcast_sta_id;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = start; i < priv->hw_params.max_stations; i++)
- if ((priv->stations[i].used) &&
- (!compare_ether_addr
- (priv->stations[i].sta.sta.addr, addr))) {
- ret = i;
- goto out;
- }
-
- IWL_DEBUG_ASSOC_LIMIT("can not find STA %s total %d\n",
- print_mac(mac, addr), priv->num_stations);
+err:
+ IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ eeprom_ver, EEPROM_4965_EEPROM_VERSION,
+ calib_ver, EEPROM_4965_TX_POWER_VERSION);
+ return -EINVAL;
- out:
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return ret;
}
-
-static int iwl4965_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max)
+int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int ret;
unsigned long flags;
@@ -535,340 +353,130 @@ static int iwl4965_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max)
return ret;
}
- if (!pwr_max) {
+ if (src == IWL_PWR_SRC_VAUX) {
u32 val;
-
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
- &val);
+ &val);
- if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
+ if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
- APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
- ~APMG_PS_CTRL_MSK_PWR_SRC);
- } else
+ APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
+ ~APMG_PS_CTRL_MSK_PWR_SRC);
+ }
+ } else {
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
- APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
- ~APMG_PS_CTRL_MSK_PWR_SRC);
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return ret;
-}
-
-static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq)
-{
- int ret;
- unsigned long flags;
- unsigned int rb_size;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
+ APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
+ ~APMG_PS_CTRL_MSK_PWR_SRC);
}
- if (priv->cfg->mod_params->amsdu_size_8K)
- rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
- else
- rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
-
- /* Stop Rx DMA */
- iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-
- /* Reset driver's Rx queue write index */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
-
- /* Tell device where to find RBD circular buffer in DRAM */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
- rxq->dma_addr >> 8);
-
- /* Tell device where in DRAM to update its Rx status */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
- (priv->shared_phys +
- offsetof(struct iwl4965_shared, rb_closed)) >> 4);
-
- /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */
- iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
- FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
- FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
- rb_size |
- /* 0x10 << 4 | */
- (RX_QUEUE_SIZE_LOG <<
- FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT));
-
- /*
- * iwl_write32(priv,CSR_INT_COAL_REG,0);
- */
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-/* Tell 4965 where to find the "keep warm" buffer */
-static int iwl4965_kw_init(struct iwl_priv *priv)
-{
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc)
- goto out;
-
- iwl_write_direct32(priv, IWL_FH_KW_MEM_ADDR_REG,
- priv->kw.dma_addr >> 4);
iwl_release_nic_access(priv);
-out:
spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
-}
-
-static int iwl4965_kw_alloc(struct iwl_priv *priv)
-{
- struct pci_dev *dev = priv->pci_dev;
- struct iwl4965_kw *kw = &priv->kw;
-
- kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */
- kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
- if (!kw->v_addr)
- return -ENOMEM;
- return 0;
+ return ret;
}
-/**
- * iwl4965_kw_free - Free the "keep warm" buffer
+/*
+ * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
+ * must be called under priv->lock and mac access
*/
-static void iwl4965_kw_free(struct iwl_priv *priv)
+static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
{
- struct pci_dev *dev = priv->pci_dev;
- struct iwl4965_kw *kw = &priv->kw;
-
- if (kw->v_addr) {
- pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
- memset(kw, 0, sizeof(*kw));
- }
+ iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
}
-/**
- * iwl4965_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialise them again
- *
- * @param priv
- * @return error code
- */
-static int iwl4965_txq_ctx_reset(struct iwl_priv *priv)
+static int iwl4965_apm_init(struct iwl_priv *priv)
{
- int rc = 0;
- int txq_id, slots_num;
- unsigned long flags;
-
- iwl4965_kw_free(priv);
-
- /* Free all tx/cmd queues and keep-warm buffer */
- iwl4965_hw_txq_ctx_free(priv);
-
- /* Alloc keep-warm buffer */
- rc = iwl4965_kw_alloc(priv);
- if (rc) {
- IWL_ERROR("Keep Warm allocation failed");
- goto error_kw;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- rc = iwl_grab_nic_access(priv);
- if (unlikely(rc)) {
- IWL_ERROR("TX reset failed");
- spin_unlock_irqrestore(&priv->lock, flags);
- goto error_reset;
- }
-
- /* Turn off all Tx DMA channels */
- iwl_write_prph(priv, IWL49_SCD_TXFACT, 0);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Tell 4965 where to find the keep-warm buffer */
- rc = iwl4965_kw_init(priv);
- if (rc) {
- IWL_ERROR("kw_init failed\n");
- goto error_reset;
- }
-
- /* Alloc and init all (default 16) Tx queues,
- * including the command queue (#4) */
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
- TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
- txq_id);
- if (rc) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
- goto error;
- }
- }
-
- return rc;
-
- error:
- iwl4965_hw_txq_ctx_free(priv);
- error_reset:
- iwl4965_kw_free(priv);
- error_kw:
- return rc;
-}
-
-int iwl4965_hw_nic_init(struct iwl_priv *priv)
-{
- int rc;
- unsigned long flags;
- struct iwl4965_rx_queue *rxq = &priv->rxq;
- u8 rev_id;
- u32 val;
- u8 val_link;
-
- iwl4965_power_init_handle(priv);
+ int ret = 0;
- /* nic_init */
- spin_lock_irqsave(&priv->lock, flags);
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+ /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+ CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+ /* set "initialization complete" bit to move adapter
+ * D0U* --> D0A* state */
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- rc = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Failed to init the card\n");
- return rc;
- }
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ /* wait for clock stabilization */
+ ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0) {
+ IWL_DEBUG_INFO("Failed to init the card\n");
+ goto out;
}
- iwl_read_prph(priv, APMG_CLK_CTRL_REG);
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto out;
- iwl_write_prph(priv, APMG_CLK_CTRL_REG,
- APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
- iwl_read_prph(priv, APMG_CLK_CTRL_REG);
+ /* enable DMA */
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
+ APMG_CLK_VAL_BSM_CLK_RQT);
udelay(20);
+ /* disable L1-Active */
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
- APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
iwl_release_nic_access(priv);
- iwl_write32(priv, CSR_INT_COALESCING, 512 / 32);
- spin_unlock_irqrestore(&priv->lock, flags);
+out:
+ return ret;
+}
- /* Determine HW type */
- rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
- if (rc)
- return rc;
- IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id);
+static void iwl4965_nic_config(struct iwl_priv *priv)
+{
+ unsigned long flags;
+ u32 val;
+ u16 radio_cfg;
+ u8 val_link;
- iwl4965_nic_set_pwr_src(priv, 1);
spin_lock_irqsave(&priv->lock, flags);
- if ((rev_id & 0x80) == 0x80 && (rev_id & 0x7f) < 8) {
+ if ((priv->rev_id & 0x80) == 0x80 && (priv->rev_id & 0x7f) < 8) {
pci_read_config_dword(priv->pci_dev, PCI_REG_WUM8, &val);
/* Enable No Snoop field */
pci_write_config_dword(priv->pci_dev, PCI_REG_WUM8,
val & ~(1 << 11));
}
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (priv->eeprom.calib_version < EEPROM_TX_POWER_VERSION_NEW) {
- IWL_ERROR("Older EEPROM detected! Aborting.\n");
- return -EINVAL;
- }
-
pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link);
- /* disable L1 entry -- workaround for pre-B1 */
- pci_write_config_byte(priv->pci_dev, PCI_LINK_CTRL, val_link & ~0x02);
+ /* L1 is enabled by BIOS */
+ if ((val_link & PCI_LINK_VAL_L1_EN) == PCI_LINK_VAL_L1_EN)
+ /* diable L0S disabled L1A enabled */
+ iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+ else
+ /* L0S enabled L1A disabled */
+ iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
- spin_lock_irqsave(&priv->lock, flags);
+ radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
- /* set CSR_HW_CONFIG_REG for uCode use */
+ /* write radio config values to register */
+ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX)
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
+ EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
+ EEPROM_RF_CFG_DASH_MSK(radio_cfg));
+ /* set CSR_HW_CONFIG_REG for uCode use */
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR49_HW_IF_CONFIG_REG_BIT_4965_R |
- CSR49_HW_IF_CONFIG_REG_BIT_RADIO_SI |
- CSR49_HW_IF_CONFIG_REG_BIT_MAC_SI);
+ CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
+ CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
- rc = iwl_grab_nic_access(priv);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Failed to init the card\n");
- return rc;
- }
+ priv->calib_info = (struct iwl_eeprom_calib_info *)
+ iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET);
- iwl_read_prph(priv, APMG_PS_CTRL_REG);
- iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
- udelay(5);
- iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
-
- iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl4965_hw_card_show_info(priv);
-
- /* end nic_init */
-
- /* Allocate the RX queue, or reset if it is already allocated */
- if (!rxq->bd) {
- rc = iwl4965_rx_queue_alloc(priv);
- if (rc) {
- IWL_ERROR("Unable to initialize Rx queue\n");
- return -ENOMEM;
- }
- } else
- iwl4965_rx_queue_reset(priv, rxq);
-
- iwl4965_rx_replenish(priv);
-
- iwl4965_rx_init(priv, rxq);
-
- spin_lock_irqsave(&priv->lock, flags);
-
- rxq->need_update = 1;
- iwl4965_rx_queue_update_write_ptr(priv, rxq);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Allocate and init all Tx and Command queues */
- rc = iwl4965_txq_ctx_reset(priv);
- if (rc)
- return rc;
-
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
- IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
-
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
- IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
-
- set_bit(STATUS_INIT, &priv->status);
-
- return 0;
}
-int iwl4965_hw_nic_stop_master(struct iwl_priv *priv)
+static int iwl4965_apm_stop_master(struct iwl_priv *priv)
{
- int rc = 0;
- u32 reg_val;
+ int ret = 0;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
@@ -876,64 +484,24 @@ int iwl4965_hw_nic_stop_master(struct iwl_priv *priv)
/* set stop master bit */
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
- reg_val = iwl_read32(priv, CSR_GP_CNTRL);
-
- if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
- (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
- IWL_DEBUG_INFO("Card in power save, master is already "
- "stopped\n");
- else {
- rc = iwl_poll_bit(priv, CSR_RESET,
+ ret = iwl_poll_bit(priv, CSR_RESET,
CSR_RESET_REG_FLAG_MASTER_DISABLED,
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
- }
+ if (ret < 0)
+ goto out;
+out:
spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_INFO("stop master\n");
- return rc;
-}
-
-/**
- * iwl4965_hw_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
- */
-void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv)
-{
-
- int txq_id;
- unsigned long flags;
-
- /* Stop each Tx DMA channel, and wait for it to be idle */
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- spin_lock_irqsave(&priv->lock, flags);
- if (iwl_grab_nic_access(priv)) {
- spin_unlock_irqrestore(&priv->lock, flags);
- continue;
- }
-
- iwl_write_direct32(priv,
- IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0);
- iwl_poll_direct_bit(priv, IWL_FH_TSSR_TX_STATUS_REG,
- IWL_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE
- (txq_id), 200);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- }
-
- /* Deallocate memory for all Tx queues */
- iwl4965_hw_txq_ctx_free(priv);
+ return ret;
}
-int iwl4965_hw_nic_reset(struct iwl_priv *priv)
+static void iwl4965_apm_stop(struct iwl_priv *priv)
{
- int rc = 0;
unsigned long flags;
- iwl4965_hw_nic_stop_master(priv);
+ iwl4965_apm_stop_master(priv);
spin_lock_irqsave(&priv->lock, flags);
@@ -942,508 +510,66 @@ int iwl4965_hw_nic_reset(struct iwl_priv *priv)
udelay(10);
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- rc = iwl_poll_bit(priv, CSR_RESET,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);
-
- udelay(10);
-
- rc = iwl_grab_nic_access(priv);
- if (!rc) {
- iwl_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT |
- APMG_CLK_VAL_BSM_CLK_RQT);
-
- udelay(10);
-
- iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
- APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
- iwl_release_nic_access(priv);
- }
-
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- wake_up_interruptible(&priv->wait_command_queue);
-
spin_unlock_irqrestore(&priv->lock, flags);
-
- return rc;
-
}
-#define REG_RECALIB_PERIOD (60)
-
-/**
- * iwl4965_bg_statistics_periodic - Timer callback to queue statistics
- *
- * This callback is provided in order to send a statistics request.
- *
- * This timer function is continually reset to execute within
- * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
- * was received. We need to ensure we receive the statistics in order
- * to update the temperature used for calibrating the TXPOWER.
- */
-static void iwl4965_bg_statistics_periodic(unsigned long data)
+static int iwl4965_apm_reset(struct iwl_priv *priv)
{
- struct iwl_priv *priv = (struct iwl_priv *)data;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- iwl_send_statistics_request(priv, CMD_ASYNC);
-}
-
-#define CT_LIMIT_CONST 259
-#define TM_CT_KILL_THRESHOLD 110
-
-void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
-{
- struct iwl4965_ct_kill_config cmd;
- u32 R1, R2, R3;
- u32 temp_th;
- u32 crit_temperature;
- unsigned long flags;
int ret = 0;
+ unsigned long flags;
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK) {
- R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
- R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
- R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
- } else {
- R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]);
- R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]);
- R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]);
- }
-
- temp_th = CELSIUS_TO_KELVIN(TM_CT_KILL_THRESHOLD);
-
- crit_temperature = ((temp_th * (R3-R1))/CT_LIMIT_CONST) + R2;
- cmd.critical_temperature_R = cpu_to_le32(crit_temperature);
- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
- sizeof(cmd), &cmd);
- if (ret)
- IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
- else
- IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded\n");
-}
-
-#ifdef CONFIG_IWL4965_SENSITIVITY
-
-/* "false alarms" are signals that our DSP tries to lock onto,
- * but then determines that they are either noise, or transmissions
- * from a distant wireless network (also "noise", really) that get
- * "stepped on" by stronger transmissions within our own network.
- * This algorithm attempts to set a sensitivity level that is high
- * enough to receive all of our own network traffic, but not so
- * high that our DSP gets too busy trying to lock onto non-network
- * activity/noise. */
-static int iwl4965_sens_energy_cck(struct iwl_priv *priv,
- u32 norm_fa,
- u32 rx_enable_time,
- struct statistics_general_data *rx_info)
-{
- u32 max_nrg_cck = 0;
- int i = 0;
- u8 max_silence_rssi = 0;
- u32 silence_ref = 0;
- u8 silence_rssi_a = 0;
- u8 silence_rssi_b = 0;
- u8 silence_rssi_c = 0;
- u32 val;
-
- /* "false_alarms" values below are cross-multiplications to assess the
- * numbers of false alarms within the measured period of actual Rx
- * (Rx is off when we're txing), vs the min/max expected false alarms
- * (some should be expected if rx is sensitive enough) in a
- * hypothetical listening period of 200 time units (TU), 204.8 msec:
- *
- * MIN_FA/fixed-time < false_alarms/actual-rx-time < MAX_FA/beacon-time
- *
- * */
- u32 false_alarms = norm_fa * 200 * 1024;
- u32 max_false_alarms = MAX_FA_CCK * rx_enable_time;
- u32 min_false_alarms = MIN_FA_CCK * rx_enable_time;
- struct iwl4965_sensitivity_data *data = NULL;
-
- data = &(priv->sensitivity_data);
-
- data->nrg_auto_corr_silence_diff = 0;
-
- /* Find max silence rssi among all 3 receivers.
- * This is background noise, which may include transmissions from other
- * networks, measured during silence before our network's beacon */
- silence_rssi_a = (u8)((rx_info->beacon_silence_rssi_a &
- ALL_BAND_FILTER) >> 8);
- silence_rssi_b = (u8)((rx_info->beacon_silence_rssi_b &
- ALL_BAND_FILTER) >> 8);
- silence_rssi_c = (u8)((rx_info->beacon_silence_rssi_c &
- ALL_BAND_FILTER) >> 8);
-
- val = max(silence_rssi_b, silence_rssi_c);
- max_silence_rssi = max(silence_rssi_a, (u8) val);
-
- /* Store silence rssi in 20-beacon history table */
- data->nrg_silence_rssi[data->nrg_silence_idx] = max_silence_rssi;
- data->nrg_silence_idx++;
- if (data->nrg_silence_idx >= NRG_NUM_PREV_STAT_L)
- data->nrg_silence_idx = 0;
-
- /* Find max silence rssi across 20 beacon history */
- for (i = 0; i < NRG_NUM_PREV_STAT_L; i++) {
- val = data->nrg_silence_rssi[i];
- silence_ref = max(silence_ref, val);
- }
- IWL_DEBUG_CALIB("silence a %u, b %u, c %u, 20-bcn max %u\n",
- silence_rssi_a, silence_rssi_b, silence_rssi_c,
- silence_ref);
-
- /* Find max rx energy (min value!) among all 3 receivers,
- * measured during beacon frame.
- * Save it in 10-beacon history table. */
- i = data->nrg_energy_idx;
- val = min(rx_info->beacon_energy_b, rx_info->beacon_energy_c);
- data->nrg_value[i] = min(rx_info->beacon_energy_a, val);
-
- data->nrg_energy_idx++;
- if (data->nrg_energy_idx >= 10)
- data->nrg_energy_idx = 0;
-
- /* Find min rx energy (max value) across 10 beacon history.
- * This is the minimum signal level that we want to receive well.
- * Add backoff (margin so we don't miss slightly lower energy frames).
- * This establishes an upper bound (min value) for energy threshold. */
- max_nrg_cck = data->nrg_value[0];
- for (i = 1; i < 10; i++)
- max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i]));
- max_nrg_cck += 6;
-
- IWL_DEBUG_CALIB("rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
- rx_info->beacon_energy_a, rx_info->beacon_energy_b,
- rx_info->beacon_energy_c, max_nrg_cck - 6);
-
- /* Count number of consecutive beacons with fewer-than-desired
- * false alarms. */
- if (false_alarms < min_false_alarms)
- data->num_in_cck_no_fa++;
- else
- data->num_in_cck_no_fa = 0;
- IWL_DEBUG_CALIB("consecutive bcns with few false alarms = %u\n",
- data->num_in_cck_no_fa);
-
- /* If we got too many false alarms this time, reduce sensitivity */
- if (false_alarms > max_false_alarms) {
- IWL_DEBUG_CALIB("norm FA %u > max FA %u\n",
- false_alarms, max_false_alarms);
- IWL_DEBUG_CALIB("... reducing sensitivity\n");
- data->nrg_curr_state = IWL_FA_TOO_MANY;
-
- if (data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK) {
- /* Store for "fewer than desired" on later beacon */
- data->nrg_silence_ref = silence_ref;
-
- /* increase energy threshold (reduce nrg value)
- * to decrease sensitivity */
- if (data->nrg_th_cck > (NRG_MAX_CCK + NRG_STEP_CCK))
- data->nrg_th_cck = data->nrg_th_cck
- - NRG_STEP_CCK;
- }
-
- /* increase auto_corr values to decrease sensitivity */
- if (data->auto_corr_cck < AUTO_CORR_MAX_TH_CCK)
- data->auto_corr_cck = AUTO_CORR_MAX_TH_CCK + 1;
- else {
- val = data->auto_corr_cck + AUTO_CORR_STEP_CCK;
- data->auto_corr_cck = min((u32)AUTO_CORR_MAX_CCK, val);
- }
- val = data->auto_corr_cck_mrc + AUTO_CORR_STEP_CCK;
- data->auto_corr_cck_mrc = min((u32)AUTO_CORR_MAX_CCK_MRC, val);
-
- /* Else if we got fewer than desired, increase sensitivity */
- } else if (false_alarms < min_false_alarms) {
- data->nrg_curr_state = IWL_FA_TOO_FEW;
-
- /* Compare silence level with silence level for most recent
- * healthy number or too many false alarms */
- data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref -
- (s32)silence_ref;
-
- IWL_DEBUG_CALIB("norm FA %u < min FA %u, silence diff %d\n",
- false_alarms, min_false_alarms,
- data->nrg_auto_corr_silence_diff);
-
- /* Increase value to increase sensitivity, but only if:
- * 1a) previous beacon did *not* have *too many* false alarms
- * 1b) AND there's a significant difference in Rx levels
- * from a previous beacon with too many, or healthy # FAs
- * OR 2) We've seen a lot of beacons (100) with too few
- * false alarms */
- if ((data->nrg_prev_state != IWL_FA_TOO_MANY) &&
- ((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
- (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
-
- IWL_DEBUG_CALIB("... increasing sensitivity\n");
- /* Increase nrg value to increase sensitivity */
- val = data->nrg_th_cck + NRG_STEP_CCK;
- data->nrg_th_cck = min((u32)NRG_MIN_CCK, val);
-
- /* Decrease auto_corr values to increase sensitivity */
- val = data->auto_corr_cck - AUTO_CORR_STEP_CCK;
- data->auto_corr_cck = max((u32)AUTO_CORR_MIN_CCK, val);
-
- val = data->auto_corr_cck_mrc - AUTO_CORR_STEP_CCK;
- data->auto_corr_cck_mrc =
- max((u32)AUTO_CORR_MIN_CCK_MRC, val);
-
- } else
- IWL_DEBUG_CALIB("... but not changing sensitivity\n");
-
- /* Else we got a healthy number of false alarms, keep status quo */
- } else {
- IWL_DEBUG_CALIB(" FA in safe zone\n");
- data->nrg_curr_state = IWL_FA_GOOD_RANGE;
-
- /* Store for use in "fewer than desired" with later beacon */
- data->nrg_silence_ref = silence_ref;
-
- /* If previous beacon had too many false alarms,
- * give it some extra margin by reducing sensitivity again
- * (but don't go below measured energy of desired Rx) */
- if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
- IWL_DEBUG_CALIB("... increasing margin\n");
- data->nrg_th_cck -= NRG_MARGIN;
- }
- }
-
- /* Make sure the energy threshold does not go above the measured
- * energy of the desired Rx signals (reduced by backoff margin),
- * or else we might start missing Rx frames.
- * Lower value is higher energy, so we use max()!
- */
- data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck);
- IWL_DEBUG_CALIB("new nrg_th_cck %u\n", data->nrg_th_cck);
-
- data->nrg_prev_state = data->nrg_curr_state;
-
- return 0;
-}
-
-
-static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv,
- u32 norm_fa,
- u32 rx_enable_time)
-{
- u32 val;
- u32 false_alarms = norm_fa * 200 * 1024;
- u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time;
- u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time;
- struct iwl4965_sensitivity_data *data = NULL;
-
- data = &(priv->sensitivity_data);
-
- /* If we got too many false alarms this time, reduce sensitivity */
- if (false_alarms > max_false_alarms) {
-
- IWL_DEBUG_CALIB("norm FA %u > max FA %u)\n",
- false_alarms, max_false_alarms);
-
- val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm =
- min((u32)AUTO_CORR_MAX_OFDM, val);
-
- val = data->auto_corr_ofdm_mrc + AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm_mrc =
- min((u32)AUTO_CORR_MAX_OFDM_MRC, val);
-
- val = data->auto_corr_ofdm_x1 + AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm_x1 =
- min((u32)AUTO_CORR_MAX_OFDM_X1, val);
-
- val = data->auto_corr_ofdm_mrc_x1 + AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm_mrc_x1 =
- min((u32)AUTO_CORR_MAX_OFDM_MRC_X1, val);
- }
-
- /* Else if we got fewer than desired, increase sensitivity */
- else if (false_alarms < min_false_alarms) {
-
- IWL_DEBUG_CALIB("norm FA %u < min FA %u\n",
- false_alarms, min_false_alarms);
-
- val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm =
- max((u32)AUTO_CORR_MIN_OFDM, val);
-
- val = data->auto_corr_ofdm_mrc - AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm_mrc =
- max((u32)AUTO_CORR_MIN_OFDM_MRC, val);
-
- val = data->auto_corr_ofdm_x1 - AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm_x1 =
- max((u32)AUTO_CORR_MIN_OFDM_X1, val);
-
- val = data->auto_corr_ofdm_mrc_x1 - AUTO_CORR_STEP_OFDM;
- data->auto_corr_ofdm_mrc_x1 =
- max((u32)AUTO_CORR_MIN_OFDM_MRC_X1, val);
- }
+ iwl4965_apm_stop_master(priv);
- else
- IWL_DEBUG_CALIB("min FA %u < norm FA %u < max FA %u OK\n",
- min_false_alarms, false_alarms, max_false_alarms);
+ spin_lock_irqsave(&priv->lock, flags);
- return 0;
-}
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-static int iwl4965_sensitivity_callback(struct iwl_priv *priv,
- struct iwl_cmd *cmd, struct sk_buff *skb)
-{
- /* We didn't cache the SKB; let the caller free it */
- return 1;
-}
+ udelay(10);
-/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
-static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
-{
- struct iwl4965_sensitivity_cmd cmd ;
- struct iwl4965_sensitivity_data *data = NULL;
- struct iwl_host_cmd cmd_out = {
- .id = SENSITIVITY_CMD,
- .len = sizeof(struct iwl4965_sensitivity_cmd),
- .meta.flags = flags,
- .data = &cmd,
- };
- int ret;
+ /* FIXME: put here L1A -L0S w/a */
- data = &(priv->sensitivity_data);
-
- memset(&cmd, 0, sizeof(cmd));
-
- cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
- cpu_to_le16((u16)data->auto_corr_ofdm);
- cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
- cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
- cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
- cpu_to_le16((u16)data->auto_corr_ofdm_x1);
- cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
- cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
-
- cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
- cpu_to_le16((u16)data->auto_corr_cck);
- cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
- cpu_to_le16((u16)data->auto_corr_cck_mrc);
-
- cmd.table[HD_MIN_ENERGY_CCK_DET_INDEX] =
- cpu_to_le16((u16)data->nrg_th_cck);
- cmd.table[HD_MIN_ENERGY_OFDM_DET_INDEX] =
- cpu_to_le16((u16)data->nrg_th_ofdm);
-
- cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
- __constant_cpu_to_le16(190);
- cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
- __constant_cpu_to_le16(390);
- cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
- __constant_cpu_to_le16(62);
-
- IWL_DEBUG_CALIB("ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
- data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
- data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
- data->nrg_th_ofdm);
-
- IWL_DEBUG_CALIB("cck: ac %u mrc %u thresh %u\n",
- data->auto_corr_cck, data->auto_corr_cck_mrc,
- data->nrg_th_cck);
-
- /* Update uCode's "work" table, and copy it to DSP */
- cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
-
- if (flags & CMD_ASYNC)
- cmd_out.meta.u.callback = iwl4965_sensitivity_callback;
-
- /* Don't send command to uCode if nothing has changed */
- if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
- sizeof(u16)*HD_TABLE_SIZE)) {
- IWL_DEBUG_CALIB("No change in SENSITIVITY_CMD\n");
- return 0;
- }
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- /* Copy table for comparison next time */
- memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
- sizeof(u16)*HD_TABLE_SIZE);
+ ret = iwl_poll_bit(priv, CSR_RESET,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);
- ret = iwl_send_cmd(priv, &cmd_out);
if (ret)
- IWL_ERROR("SENSITIVITY_CMD failed\n");
-
- return ret;
-}
-
-void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
-{
- struct iwl4965_sensitivity_data *data = NULL;
- int i;
- int ret = 0;
-
- IWL_DEBUG_CALIB("Start iwl4965_init_sensitivity\n");
-
- if (force)
- memset(&(priv->sensitivity_tbl[0]), 0,
- sizeof(u16)*HD_TABLE_SIZE);
-
- /* Clear driver's sensitivity algo data */
- data = &(priv->sensitivity_data);
- memset(data, 0, sizeof(struct iwl4965_sensitivity_data));
+ goto out;
- data->num_in_cck_no_fa = 0;
- data->nrg_curr_state = IWL_FA_TOO_MANY;
- data->nrg_prev_state = IWL_FA_TOO_MANY;
- data->nrg_silence_ref = 0;
- data->nrg_silence_idx = 0;
- data->nrg_energy_idx = 0;
+ udelay(10);
- for (i = 0; i < 10; i++)
- data->nrg_value[i] = 0;
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto out;
+ /* Enable DMA and BSM Clock */
+ iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
+ APMG_CLK_VAL_BSM_CLK_RQT);
- for (i = 0; i < NRG_NUM_PREV_STAT_L; i++)
- data->nrg_silence_rssi[i] = 0;
+ udelay(10);
- data->auto_corr_ofdm = 90;
- data->auto_corr_ofdm_mrc = 170;
- data->auto_corr_ofdm_x1 = 105;
- data->auto_corr_ofdm_mrc_x1 = 220;
- data->auto_corr_cck = AUTO_CORR_CCK_MIN_VAL_DEF;
- data->auto_corr_cck_mrc = 200;
- data->nrg_th_cck = 100;
- data->nrg_th_ofdm = 100;
+ /* disable L1A */
+ iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- data->last_bad_plcp_cnt_ofdm = 0;
- data->last_fa_cnt_ofdm = 0;
- data->last_bad_plcp_cnt_cck = 0;
- data->last_fa_cnt_cck = 0;
+ iwl_release_nic_access(priv);
- /* Clear prior Sensitivity command data to force send to uCode */
- if (force)
- memset(&(priv->sensitivity_tbl[0]), 0,
- sizeof(u16)*HD_TABLE_SIZE);
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ wake_up_interruptible(&priv->wait_command_queue);
- ret |= iwl4965_sensitivity_write(priv, flags);
- IWL_DEBUG_CALIB("<<return 0x%X\n", ret);
+out:
+ spin_unlock_irqrestore(&priv->lock, flags);
- return;
+ return ret;
}
-
/* Reset differential Rx gains in NIC to prepare for chain noise calibration.
* Called after every association, but this runs only once!
* ... once chain noise is calibrated the first time, it's good forever. */
-void iwl4965_chain_noise_reset(struct iwl_priv *priv)
+static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
{
- struct iwl4965_chain_noise_data *data = NULL;
+ struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
- data = &(priv->chain_noise_data);
if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
struct iwl4965_calibration_cmd cmd;
@@ -1452,388 +578,89 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv)
cmd.diff_gain_a = 0;
cmd.diff_gain_b = 0;
cmd.diff_gain_c = 0;
- iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
- sizeof(cmd), &cmd, NULL);
- msleep(4);
+ if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+ sizeof(cmd), &cmd))
+ IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
}
- return;
}
-/*
- * Accumulate 20 beacons of signal and noise statistics for each of
- * 3 receivers/antennas/rx-chains, then figure out:
- * 1) Which antennas are connected.
- * 2) Differential rx gain settings to balance the 3 receivers.
- */
-static void iwl4965_noise_calibration(struct iwl_priv *priv,
- struct iwl4965_notif_statistics *stat_resp)
+static void iwl4965_gain_computation(struct iwl_priv *priv,
+ u32 *average_noise,
+ u16 min_average_noise_antenna_i,
+ u32 min_average_noise)
{
- struct iwl4965_chain_noise_data *data = NULL;
- int ret = 0;
-
- u32 chain_noise_a;
- u32 chain_noise_b;
- u32 chain_noise_c;
- u32 chain_sig_a;
- u32 chain_sig_b;
- u32 chain_sig_c;
- u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
- u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
- u32 max_average_sig;
- u16 max_average_sig_antenna_i;
- u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE;
- u16 min_average_noise_antenna_i = INITIALIZATION_VALUE;
- u16 i = 0;
- u16 chan_num = INITIALIZATION_VALUE;
- u32 band = INITIALIZATION_VALUE;
- u32 active_chains = 0;
- unsigned long flags;
- struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general);
-
- data = &(priv->chain_noise_data);
-
- /* Accumulate just the first 20 beacons after the first association,
- * then we're done forever. */
- if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) {
- if (data->state == IWL_CHAIN_NOISE_ALIVE)
- IWL_DEBUG_CALIB("Wait for noise calib reset\n");
- return;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
- IWL_DEBUG_CALIB(" << Interference data unavailable\n");
- spin_unlock_irqrestore(&priv->lock, flags);
- return;
- }
-
- band = (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) ? 0 : 1;
- chan_num = le16_to_cpu(priv->staging_rxon.channel);
-
- /* Make sure we accumulate data for just the associated channel
- * (even if scanning). */
- if ((chan_num != (le32_to_cpu(stat_resp->flag) >> 16)) ||
- ((STATISTICS_REPLY_FLG_BAND_24G_MSK ==
- (stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK)) && band)) {
- IWL_DEBUG_CALIB("Stats not from chan=%d, band=%d\n",
- chan_num, band);
- spin_unlock_irqrestore(&priv->lock, flags);
- return;
- }
-
- /* Accumulate beacon statistics values across 20 beacons */
- chain_noise_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) &
- IN_BAND_FILTER;
- chain_noise_b = le32_to_cpu(rx_info->beacon_silence_rssi_b) &
- IN_BAND_FILTER;
- chain_noise_c = le32_to_cpu(rx_info->beacon_silence_rssi_c) &
- IN_BAND_FILTER;
-
- chain_sig_a = le32_to_cpu(rx_info->beacon_rssi_a) & IN_BAND_FILTER;
- chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER;
- chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- data->beacon_count++;
-
- data->chain_noise_a = (chain_noise_a + data->chain_noise_a);
- data->chain_noise_b = (chain_noise_b + data->chain_noise_b);
- data->chain_noise_c = (chain_noise_c + data->chain_noise_c);
-
- data->chain_signal_a = (chain_sig_a + data->chain_signal_a);
- data->chain_signal_b = (chain_sig_b + data->chain_signal_b);
- data->chain_signal_c = (chain_sig_c + data->chain_signal_c);
-
- IWL_DEBUG_CALIB("chan=%d, band=%d, beacon=%d\n", chan_num, band,
- data->beacon_count);
- IWL_DEBUG_CALIB("chain_sig: a %d b %d c %d\n",
- chain_sig_a, chain_sig_b, chain_sig_c);
- IWL_DEBUG_CALIB("chain_noise: a %d b %d c %d\n",
- chain_noise_a, chain_noise_b, chain_noise_c);
-
- /* If this is the 20th beacon, determine:
- * 1) Disconnected antennas (using signal strengths)
- * 2) Differential gain (using silence noise) to balance receivers */
- if (data->beacon_count == CAL_NUM_OF_BEACONS) {
-
- /* Analyze signal for disconnected antenna */
- average_sig[0] = (data->chain_signal_a) / CAL_NUM_OF_BEACONS;
- average_sig[1] = (data->chain_signal_b) / CAL_NUM_OF_BEACONS;
- average_sig[2] = (data->chain_signal_c) / CAL_NUM_OF_BEACONS;
-
- if (average_sig[0] >= average_sig[1]) {
- max_average_sig = average_sig[0];
- max_average_sig_antenna_i = 0;
- active_chains = (1 << max_average_sig_antenna_i);
- } else {
- max_average_sig = average_sig[1];
- max_average_sig_antenna_i = 1;
- active_chains = (1 << max_average_sig_antenna_i);
- }
-
- if (average_sig[2] >= max_average_sig) {
- max_average_sig = average_sig[2];
- max_average_sig_antenna_i = 2;
- active_chains = (1 << max_average_sig_antenna_i);
- }
-
- IWL_DEBUG_CALIB("average_sig: a %d b %d c %d\n",
- average_sig[0], average_sig[1], average_sig[2]);
- IWL_DEBUG_CALIB("max_average_sig = %d, antenna %d\n",
- max_average_sig, max_average_sig_antenna_i);
-
- /* Compare signal strengths for all 3 receivers. */
- for (i = 0; i < NUM_RX_CHAINS; i++) {
- if (i != max_average_sig_antenna_i) {
- s32 rssi_delta = (max_average_sig -
- average_sig[i]);
-
- /* If signal is very weak, compared with
- * strongest, mark it as disconnected. */
- if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
- data->disconn_array[i] = 1;
- else
- active_chains |= (1 << i);
- IWL_DEBUG_CALIB("i = %d rssiDelta = %d "
- "disconn_array[i] = %d\n",
- i, rssi_delta, data->disconn_array[i]);
- }
- }
-
- /*If both chains A & B are disconnected -
- * connect B and leave A as is */
- if (data->disconn_array[CHAIN_A] &&
- data->disconn_array[CHAIN_B]) {
- data->disconn_array[CHAIN_B] = 0;
- active_chains |= (1 << CHAIN_B);
- IWL_DEBUG_CALIB("both A & B chains are disconnected! "
- "W/A - declare B as connected\n");
- }
+ int i, ret;
+ struct iwl_chain_noise_data *data = &priv->chain_noise_data;
- IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
- active_chains);
+ data->delta_gain_code[min_average_noise_antenna_i] = 0;
- /* Save for use within RXON, TX, SCAN commands, etc. */
- priv->valid_antenna = active_chains;
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ s32 delta_g = 0;
- /* Analyze noise for rx balance */
- average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
- average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS);
- average_noise[2] = ((data->chain_noise_c)/CAL_NUM_OF_BEACONS);
-
- for (i = 0; i < NUM_RX_CHAINS; i++) {
- if (!(data->disconn_array[i]) &&
- (average_noise[i] <= min_average_noise)) {
- /* This means that chain i is active and has
- * lower noise values so far: */
- min_average_noise = average_noise[i];
- min_average_noise_antenna_i = i;
- }
- }
-
- data->delta_gain_code[min_average_noise_antenna_i] = 0;
-
- IWL_DEBUG_CALIB("average_noise: a %d b %d c %d\n",
- average_noise[0], average_noise[1],
- average_noise[2]);
-
- IWL_DEBUG_CALIB("min_average_noise = %d, antenna %d\n",
- min_average_noise, min_average_noise_antenna_i);
-
- for (i = 0; i < NUM_RX_CHAINS; i++) {
- s32 delta_g = 0;
-
- if (!(data->disconn_array[i]) &&
- (data->delta_gain_code[i] ==
+ if (!(data->disconn_array[i]) &&
+ (data->delta_gain_code[i] ==
CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) {
- delta_g = average_noise[i] - min_average_noise;
- data->delta_gain_code[i] = (u8)((delta_g *
- 10) / 15);
- if (CHAIN_NOISE_MAX_DELTA_GAIN_CODE <
- data->delta_gain_code[i])
- data->delta_gain_code[i] =
- CHAIN_NOISE_MAX_DELTA_GAIN_CODE;
-
- data->delta_gain_code[i] =
- (data->delta_gain_code[i] | (1 << 2));
- } else
- data->delta_gain_code[i] = 0;
- }
- IWL_DEBUG_CALIB("delta_gain_codes: a %d b %d c %d\n",
- data->delta_gain_code[0],
- data->delta_gain_code[1],
- data->delta_gain_code[2]);
-
- /* Differential gain gets sent to uCode only once */
- if (!data->radio_write) {
- struct iwl4965_calibration_cmd cmd;
- data->radio_write = 1;
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
- cmd.diff_gain_a = data->delta_gain_code[0];
- cmd.diff_gain_b = data->delta_gain_code[1];
- cmd.diff_gain_c = data->delta_gain_code[2];
- ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
- sizeof(cmd), &cmd);
- if (ret)
- IWL_DEBUG_CALIB("fail sending cmd "
- "REPLY_PHY_CALIBRATION_CMD \n");
-
- /* TODO we might want recalculate
- * rx_chain in rxon cmd */
-
- /* Mark so we run this algo only once! */
- data->state = IWL_CHAIN_NOISE_CALIBRATED;
+ delta_g = average_noise[i] - min_average_noise;
+ data->delta_gain_code[i] = (u8)((delta_g * 10) / 15);
+ data->delta_gain_code[i] =
+ min(data->delta_gain_code[i],
+ (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+
+ data->delta_gain_code[i] =
+ (data->delta_gain_code[i] | (1 << 2));
+ } else {
+ data->delta_gain_code[i] = 0;
}
- data->chain_noise_a = 0;
- data->chain_noise_b = 0;
- data->chain_noise_c = 0;
- data->chain_signal_a = 0;
- data->chain_signal_b = 0;
- data->chain_signal_c = 0;
- data->beacon_count = 0;
- }
- return;
-}
-
-static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
- struct iwl4965_notif_statistics *resp)
-{
- u32 rx_enable_time;
- u32 fa_cck;
- u32 fa_ofdm;
- u32 bad_plcp_cck;
- u32 bad_plcp_ofdm;
- u32 norm_fa_ofdm;
- u32 norm_fa_cck;
- struct iwl4965_sensitivity_data *data = NULL;
- struct statistics_rx_non_phy *rx_info = &(resp->rx.general);
- struct statistics_rx *statistics = &(resp->rx);
- unsigned long flags;
- struct statistics_general_data statis;
- int ret;
-
- data = &(priv->sensitivity_data);
-
- if (!iwl_is_associated(priv)) {
- IWL_DEBUG_CALIB("<< - not associated\n");
- return;
}
+ IWL_DEBUG_CALIB("delta_gain_codes: a %d b %d c %d\n",
+ data->delta_gain_code[0],
+ data->delta_gain_code[1],
+ data->delta_gain_code[2]);
- spin_lock_irqsave(&priv->lock, flags);
- if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
- IWL_DEBUG_CALIB("<< invalid data.\n");
- spin_unlock_irqrestore(&priv->lock, flags);
- return;
- }
-
- /* Extract Statistics: */
- rx_enable_time = le32_to_cpu(rx_info->channel_load);
- fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt);
- fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt);
- bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err);
- bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err);
-
- statis.beacon_silence_rssi_a =
- le32_to_cpu(statistics->general.beacon_silence_rssi_a);
- statis.beacon_silence_rssi_b =
- le32_to_cpu(statistics->general.beacon_silence_rssi_b);
- statis.beacon_silence_rssi_c =
- le32_to_cpu(statistics->general.beacon_silence_rssi_c);
- statis.beacon_energy_a =
- le32_to_cpu(statistics->general.beacon_energy_a);
- statis.beacon_energy_b =
- le32_to_cpu(statistics->general.beacon_energy_b);
- statis.beacon_energy_c =
- le32_to_cpu(statistics->general.beacon_energy_c);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_CALIB("rx_enable_time = %u usecs\n", rx_enable_time);
-
- if (!rx_enable_time) {
- IWL_DEBUG_CALIB("<< RX Enable Time == 0! \n");
- return;
- }
-
- /* These statistics increase monotonically, and do not reset
- * at each beacon. Calculate difference from last value, or just
- * use the new statistics value if it has reset or wrapped around. */
- if (data->last_bad_plcp_cnt_cck > bad_plcp_cck)
- data->last_bad_plcp_cnt_cck = bad_plcp_cck;
- else {
- bad_plcp_cck -= data->last_bad_plcp_cnt_cck;
- data->last_bad_plcp_cnt_cck += bad_plcp_cck;
- }
+ /* Differential gain gets sent to uCode only once */
+ if (!data->radio_write) {
+ struct iwl4965_calibration_cmd cmd;
+ data->radio_write = 1;
- if (data->last_bad_plcp_cnt_ofdm > bad_plcp_ofdm)
- data->last_bad_plcp_cnt_ofdm = bad_plcp_ofdm;
- else {
- bad_plcp_ofdm -= data->last_bad_plcp_cnt_ofdm;
- data->last_bad_plcp_cnt_ofdm += bad_plcp_ofdm;
- }
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
+ cmd.diff_gain_a = data->delta_gain_code[0];
+ cmd.diff_gain_b = data->delta_gain_code[1];
+ cmd.diff_gain_c = data->delta_gain_code[2];
+ ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_DEBUG_CALIB("fail sending cmd "
+ "REPLY_PHY_CALIBRATION_CMD \n");
- if (data->last_fa_cnt_ofdm > fa_ofdm)
- data->last_fa_cnt_ofdm = fa_ofdm;
- else {
- fa_ofdm -= data->last_fa_cnt_ofdm;
- data->last_fa_cnt_ofdm += fa_ofdm;
- }
+ /* TODO we might want recalculate
+ * rx_chain in rxon cmd */
- if (data->last_fa_cnt_cck > fa_cck)
- data->last_fa_cnt_cck = fa_cck;
- else {
- fa_cck -= data->last_fa_cnt_cck;
- data->last_fa_cnt_cck += fa_cck;
+ /* Mark so we run this algo only once! */
+ data->state = IWL_CHAIN_NOISE_CALIBRATED;
}
-
- /* Total aborted signal locks */
- norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm;
- norm_fa_cck = fa_cck + bad_plcp_cck;
-
- IWL_DEBUG_CALIB("cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck,
- bad_plcp_cck, fa_ofdm, bad_plcp_ofdm);
-
- iwl4965_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
- iwl4965_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
- ret = iwl4965_sensitivity_write(priv, CMD_ASYNC);
-
- return;
+ data->chain_noise_a = 0;
+ data->chain_noise_b = 0;
+ data->chain_noise_c = 0;
+ data->chain_signal_a = 0;
+ data->chain_signal_b = 0;
+ data->chain_signal_c = 0;
+ data->beacon_count = 0;
}
-static void iwl4965_bg_sensitivity_work(struct work_struct *work)
+static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+ __le32 *tx_flags)
{
- struct iwl_priv *priv = container_of(work, struct iwl_priv,
- sensitivity_work);
-
- mutex_lock(&priv->mutex);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
- test_bit(STATUS_SCANNING, &priv->status)) {
- mutex_unlock(&priv->mutex);
- return;
- }
-
- if (priv->start_calib) {
- iwl4965_noise_calibration(priv, &priv->statistics);
-
- if (priv->sensitivity_data.state ==
- IWL_SENS_CALIB_NEED_REINIT) {
- iwl4965_init_sensitivity(priv, CMD_ASYNC, 0);
- priv->sensitivity_data.state = IWL_SENS_CALIB_ALLOWED;
- } else
- iwl4965_sensitivity_calibration(priv,
- &priv->statistics);
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+ *tx_flags |= TX_CMD_FLG_RTS_MSK;
+ *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
+ } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+ *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+ *tx_flags |= TX_CMD_FLG_CTS_MSK;
}
-
- mutex_unlock(&priv->mutex);
- return;
}
-#endif /*CONFIG_IWL4965_SENSITIVITY*/
static void iwl4965_bg_txpower_work(struct work_struct *work)
{
@@ -1853,7 +680,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work)
/* Regardless of if we are assocaited, we must reconfigure the
* TX power since frames can be sent on non-radar channels while
* not associated */
- iwl4965_hw_reg_send_txpower(priv);
+ iwl4965_send_tx_power(priv);
/* Update last_temperature to keep is_calib_needed from running
* when it isn't needed... */
@@ -1880,7 +707,7 @@ static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index)
* NOTE: Acquire priv->lock before calling this function !
*/
static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq,
+ struct iwl_tx_queue *txq,
int tx_fifo_id, int scd_retry)
{
int txq_id = txq->q.id;
@@ -1890,11 +717,11 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
/* Set up and activate */
iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
- (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
- (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
- (scd_retry << SCD_QUEUE_STTS_REG_POS_WSL) |
- (scd_retry << SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
- SCD_QUEUE_STTS_REG_MSK);
+ (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
+ (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) |
+ (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) |
+ (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
+ IWL49_SCD_QUEUE_STTS_REG_MSK);
txq->sched_retry = scd_retry;
@@ -1908,22 +735,12 @@ static const u16 default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_AC2,
IWL_TX_FIFO_AC1,
IWL_TX_FIFO_AC0,
- IWL_CMD_FIFO_NUM,
+ IWL49_CMD_FIFO_NUM,
IWL_TX_FIFO_HCCA_1,
IWL_TX_FIFO_HCCA_2
};
-static inline void iwl4965_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
-{
- set_bit(txq_id, &priv->txq_ctx_active_msk);
-}
-
-static inline void iwl4965_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
-{
- clear_bit(txq_id, &priv->txq_ctx_active_msk);
-}
-
-int iwl4965_alive_notify(struct iwl_priv *priv)
+static int iwl4965_alive_notify(struct iwl_priv *priv)
{
u32 a;
int i = 0;
@@ -1932,15 +749,6 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
spin_lock_irqsave(&priv->lock, flags);
-#ifdef CONFIG_IWL4965_SENSITIVITY
- memset(&(priv->sensitivity_data), 0,
- sizeof(struct iwl4965_sensitivity_data));
- memset(&(priv->chain_noise_data), 0,
- sizeof(struct iwl4965_chain_noise_data));
- for (i = 0; i < NUM_RX_CHAINS; i++)
- priv->chain_noise_data.delta_gain_code[i] =
- CHAIN_NOISE_DELTA_GAIN_INIT_VAL;
-#endif /* CONFIG_IWL4965_SENSITIVITY*/
ret = iwl_grab_nic_access(priv);
if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1949,10 +757,10 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
/* Clear 4965's internal Tx Scheduler data base */
priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR);
- a = priv->scd_base_addr + SCD_CONTEXT_DATA_OFFSET;
- for (; a < priv->scd_base_addr + SCD_TX_STTS_BITMAP_OFFSET; a += 4)
+ a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET;
+ for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
iwl_write_targ_mem(priv, a, 0);
- for (; a < priv->scd_base_addr + SCD_TRANSLATE_TBL_OFFSET; a += 4)
+ for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
iwl_write_targ_mem(priv, a, 0);
for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
iwl_write_targ_mem(priv, a, 0);
@@ -1974,160 +782,109 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
/* Max Tx Window size for Scheduler-ACK mode */
iwl_write_targ_mem(priv, priv->scd_base_addr +
- SCD_CONTEXT_QUEUE_OFFSET(i),
- (SCD_WIN_SIZE <<
- SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
- SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
+ IWL49_SCD_CONTEXT_QUEUE_OFFSET(i),
+ (SCD_WIN_SIZE <<
+ IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
+ IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
/* Frame limit */
iwl_write_targ_mem(priv, priv->scd_base_addr +
- SCD_CONTEXT_QUEUE_OFFSET(i) +
- sizeof(u32),
- (SCD_FRAME_LIMIT <<
- SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
- SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
+ IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
+ sizeof(u32),
+ (SCD_FRAME_LIMIT <<
+ IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+ IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
}
iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK,
(1 << priv->hw_params.max_txq_num) - 1);
/* Activate all Tx DMA/FIFO channels */
- iwl_write_prph(priv, IWL49_SCD_TXFACT,
- SCD_TXFACT_REG_TXFIFO_MASK(0, 7));
+ priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
/* Map each Tx/cmd queue to its corresponding fifo */
for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
int ac = default_queue_to_tx_fifo[i];
- iwl4965_txq_ctx_activate(priv, i);
+ iwl_txq_ctx_activate(priv, i);
iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
}
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- /* Ask for statistics now, the uCode will send statistics notification
- * periodically after association */
- iwl_send_statistics_request(priv, CMD_ASYNC);
return ret;
}
+static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
+ .min_nrg_cck = 97,
+ .max_nrg_cck = 0,
+
+ .auto_corr_min_ofdm = 85,
+ .auto_corr_min_ofdm_mrc = 170,
+ .auto_corr_min_ofdm_x1 = 105,
+ .auto_corr_min_ofdm_mrc_x1 = 220,
+
+ .auto_corr_max_ofdm = 120,
+ .auto_corr_max_ofdm_mrc = 210,
+ .auto_corr_max_ofdm_x1 = 140,
+ .auto_corr_max_ofdm_mrc_x1 = 270,
+
+ .auto_corr_min_cck = 125,
+ .auto_corr_max_cck = 200,
+ .auto_corr_min_cck_mrc = 200,
+ .auto_corr_max_cck_mrc = 400,
+
+ .nrg_th_cck = 100,
+ .nrg_th_ofdm = 100,
+};
+
/**
* iwl4965_hw_set_hw_params
*
* Called when initializing driver
*/
-int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
+static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
{
- if ((priv->cfg->mod_params->num_of_queues > IWL4965_MAX_NUM_QUEUES) ||
+ if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL4965_MAX_NUM_QUEUES);
+ IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
return -EINVAL;
}
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
- priv->hw_params.tx_cmd_len = sizeof(struct iwl4965_tx_cmd);
- priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
- priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
- if (priv->cfg->mod_params->amsdu_size_8K)
- priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K;
- else
- priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K;
- priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256;
+ priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE;
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
+ priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
+ priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
+ priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
+ priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.tx_chains_num = 2;
priv->hw_params.rx_chains_num = 2;
- priv->hw_params.valid_tx_ant = (IWL_ANTENNA_MAIN | IWL_ANTENNA_AUX);
- priv->hw_params.valid_rx_ant = (IWL_ANTENNA_MAIN | IWL_ANTENNA_AUX);
-
- return 0;
-}
-
-/**
- * iwl4965_hw_txq_ctx_free - Free TXQ Context
- *
- * Destroy all TX DMA queues and structures
- */
-void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv)
-{
- int txq_id;
-
- /* Tx queues */
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
- iwl4965_tx_queue_free(priv, &priv->txq[txq_id]);
-
- /* Keep-warm buffer */
- iwl4965_kw_free(priv);
-}
-
-/**
- * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq)
-{
- struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0];
- struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
- struct pci_dev *dev = priv->pci_dev;
- int i;
- int counter = 0;
- int index, is_odd;
+ priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
+ priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
+ priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
- /* Host command buffers stay mapped in memory, nothing to clean */
- if (txq->q.id == IWL_CMD_QUEUE_NUM)
- return 0;
-
- /* Sanity check on number of chunks */
- counter = IWL_GET_BITS(*bd, num_tbs);
- if (counter > MAX_NUM_OF_TBS) {
- IWL_ERROR("Too many chunks: %i\n", counter);
- /* @todo issue fatal error, it is quite serious situation */
- return 0;
- }
+ priv->hw_params.sens = &iwl4965_sensitivity;
- /* Unmap chunks, if any.
- * TFD info for odd chunks is different format than for even chunks. */
- for (i = 0; i < counter; i++) {
- index = i / 2;
- is_odd = i & 0x1;
-
- if (is_odd)
- pci_unmap_single(
- dev,
- IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
- (IWL_GET_BITS(bd->pa[index],
- tb2_addr_hi20) << 16),
- IWL_GET_BITS(bd->pa[index], tb2_len),
- PCI_DMA_TODEVICE);
-
- else if (i > 0)
- pci_unmap_single(dev,
- le32_to_cpu(bd->pa[index].tb1_addr),
- IWL_GET_BITS(bd->pa[index], tb1_len),
- PCI_DMA_TODEVICE);
-
- /* Free SKB, if any, for this chunk */
- if (txq->txb[txq->q.read_ptr].skb[i]) {
- struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i];
-
- dev_kfree_skb(skb);
- txq->txb[txq->q.read_ptr].skb[i] = NULL;
- }
- }
return 0;
}
-int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
+/* set card power command */
+static int iwl4965_set_power(struct iwl_priv *priv,
+ void *cmd)
{
- IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n");
- return -EINVAL;
+ int ret = 0;
+
+ ret = iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
+ sizeof(struct iwl4965_powertable_cmd),
+ cmd, NULL);
+ return ret;
}
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
@@ -2179,20 +936,6 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
return comp;
}
-static const struct iwl_channel_info *
-iwl4965_get_channel_txpower_info(struct iwl_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv, band, channel);
-
- if (!is_channel_valid(ch_info))
- return NULL;
-
- return ch_info;
-}
-
static s32 iwl4965_get_tx_atten_grp(u16 channel)
{
if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH &&
@@ -2224,11 +967,11 @@ static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
s32 b = -1;
for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {
- if (priv->eeprom.calib_info.band_info[b].ch_from == 0)
+ if (priv->calib_info->band_info[b].ch_from == 0)
continue;
- if ((channel >= priv->eeprom.calib_info.band_info[b].ch_from)
- && (channel <= priv->eeprom.calib_info.band_info[b].ch_to))
+ if ((channel >= priv->calib_info->band_info[b].ch_from)
+ && (channel <= priv->calib_info->band_info[b].ch_to))
break;
}
@@ -2256,14 +999,14 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
* in channel number.
*/
static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
- struct iwl4965_eeprom_calib_ch_info *chan_info)
+ struct iwl_eeprom_calib_ch_info *chan_info)
{
s32 s = -1;
u32 c;
u32 m;
- const struct iwl4965_eeprom_calib_measure *m1;
- const struct iwl4965_eeprom_calib_measure *m2;
- struct iwl4965_eeprom_calib_measure *omeas;
+ const struct iwl_eeprom_calib_measure *m1;
+ const struct iwl_eeprom_calib_measure *m2;
+ struct iwl_eeprom_calib_measure *omeas;
u32 ch_i1;
u32 ch_i2;
@@ -2273,8 +1016,8 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
return -1;
}
- ch_i1 = priv->eeprom.calib_info.band_info[s].ch1.ch_num;
- ch_i2 = priv->eeprom.calib_info.band_info[s].ch2.ch_num;
+ ch_i1 = priv->calib_info->band_info[s].ch1.ch_num;
+ ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
chan_info->ch_num = (u8) channel;
IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
@@ -2282,9 +1025,9 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {
- m1 = &(priv->eeprom.calib_info.band_info[s].ch1.
+ m1 = &(priv->calib_info->band_info[s].ch1.
measurements[c][m]);
- m2 = &(priv->eeprom.calib_info.band_info[s].ch2.
+ m2 = &(priv->calib_info->band_info[s].ch2.
measurements[c][m]);
omeas = &(chan_info->measurements[c][m]);
@@ -2603,8 +1346,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
int i;
int c;
const struct iwl_channel_info *ch_info = NULL;
- struct iwl4965_eeprom_calib_ch_info ch_eeprom_info;
- const struct iwl4965_eeprom_calib_measure *measurement;
+ struct iwl_eeprom_calib_ch_info ch_eeprom_info;
+ const struct iwl_eeprom_calib_measure *measurement;
s16 voltage;
s32 init_voltage;
s32 voltage_compensation;
@@ -2616,30 +1359,17 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
s32 factory_actual_pwr[2];
s32 power_index;
- /* Sanity check requested level (dBm) */
- if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) {
- IWL_WARNING("Requested user TXPOWER %d below limit.\n",
- priv->user_txpower_limit);
- return -EINVAL;
- }
- if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) {
- IWL_WARNING("Requested user TXPOWER %d above limit.\n",
- priv->user_txpower_limit);
- return -EINVAL;
- }
-
/* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
* are used for indexing into txpower table) */
- user_target_power = 2 * priv->user_txpower_limit;
+ user_target_power = 2 * priv->tx_power_user_lmt;
/* Get current (RXON) channel, band, width */
- ch_info =
- iwl4965_get_channel_txpower_info(priv, priv->band, channel);
-
IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
is_fat);
- if (!ch_info)
+ ch_info = iwl_get_channel_info(priv, priv->band, channel);
+
+ if (!is_channel_valid(ch_info))
return -EINVAL;
/* get txatten group, used to select 1) thermal txpower adjustment
@@ -2661,9 +1391,9 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* hardware txpower limits ...
* saturation (clipping distortion) txpowers are in half-dBm */
if (band)
- saturation_power = priv->eeprom.calib_info.saturation_power24;
+ saturation_power = priv->calib_info->saturation_power24;
else
- saturation_power = priv->eeprom.calib_info.saturation_power52;
+ saturation_power = priv->calib_info->saturation_power52;
if (saturation_power < IWL_TX_POWER_SATURATION_MIN ||
saturation_power > IWL_TX_POWER_SATURATION_MAX) {
@@ -2693,7 +1423,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
/* calculate tx gain adjustment based on power supply voltage */
- voltage = priv->eeprom.calib_info.voltage;
+ voltage = priv->calib_info->voltage;
init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
voltage_compensation =
iwl4965_get_voltage_compensation(voltage, init_voltage);
@@ -2840,12 +1570,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
}
/**
- * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit
+ * iwl4965_send_tx_power - Configure the TXPOWER level user limit
*
* Uses the active RXON for channel, band, and characteristics (fat, high)
- * The power limit is taken from priv->user_txpower_limit.
+ * The power limit is taken from priv->tx_power_user_lmt.
*/
-int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv)
+static int iwl4965_send_tx_power(struct iwl_priv *priv)
{
struct iwl4965_txpowertable_cmd cmd = { 0 };
int ret;
@@ -2888,8 +1618,8 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
{
int ret = 0;
struct iwl4965_rxon_assoc_cmd rxon_assoc;
- const struct iwl4965_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl4965_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+ const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
if ((rxon1->flags == rxon2->flags) &&
(rxon1->filter_flags == rxon2->filter_flags) &&
@@ -2965,89 +1695,14 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
return rc;
}
-#define RTS_HCCA_RETRY_LIMIT 3
-#define RTS_DFAULT_RETRY_LIMIT 60
-
-void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
- struct iwl_cmd *cmd,
- struct ieee80211_tx_control *ctrl,
- struct ieee80211_hdr *hdr, int sta_id,
- int is_hcca)
-{
- struct iwl4965_tx_cmd *tx = &cmd->cmd.tx;
- u8 rts_retry_limit = 0;
- u8 data_retry_limit = 0;
- u16 fc = le16_to_cpu(hdr->frame_control);
- u8 rate_plcp;
- u16 rate_flags = 0;
- int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);
-
- rate_plcp = iwl4965_rates[rate_idx].plcp;
-
- rts_retry_limit = (is_hcca) ?
- RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;
-
- if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
- rate_flags |= RATE_MCS_CCK_MSK;
-
-
- if (ieee80211_is_probe_response(fc)) {
- data_retry_limit = 3;
- if (data_retry_limit < rts_retry_limit)
- rts_retry_limit = data_retry_limit;
- } else
- data_retry_limit = IWL_DEFAULT_TX_RETRY;
-
- if (priv->data_retry_limit != -1)
- data_retry_limit = priv->data_retry_limit;
-
-
- if (ieee80211_is_data(fc)) {
- tx->initial_rate_index = 0;
- tx->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
- } else {
- switch (fc & IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_AUTH:
- case IEEE80211_STYPE_DEAUTH:
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
- if (tx->tx_flags & TX_CMD_FLG_RTS_MSK) {
- tx->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
- tx->tx_flags |= TX_CMD_FLG_CTS_MSK;
- }
- break;
- default:
- break;
- }
-
- /* Alternate between antenna A and B for successive frames */
- if (priv->use_ant_b_for_management_frame) {
- priv->use_ant_b_for_management_frame = 0;
- rate_flags |= RATE_MCS_ANT_B_MSK;
- } else {
- priv->use_ant_b_for_management_frame = 1;
- rate_flags |= RATE_MCS_ANT_A_MSK;
- }
- }
-
- tx->rts_retry_limit = rts_retry_limit;
- tx->data_retry_limit = data_retry_limit;
- tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
-}
-
-int iwl4965_hw_get_rx_read(struct iwl_priv *priv)
+static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
{
struct iwl4965_shared *s = priv->shared_virt;
return le32_to_cpu(s->rb_closed) & 0xFFF;
}
-int iwl4965_hw_get_temperature(struct iwl_priv *priv)
-{
- return priv->temperature;
-}
-
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
- struct iwl4965_frame *frame, u8 rate)
+ struct iwl_frame *frame, u8 rate)
{
struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
unsigned int frame_size;
@@ -3060,7 +1715,7 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
frame_size = iwl4965_fill_beacon_frame(priv,
tx_beacon_cmd->frame,
- iwl4965_broadcast_addr,
+ iwl_bcast_addr,
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
BUG_ON(frame_size > MAX_MPDU_SIZE);
@@ -3068,105 +1723,45 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
+ iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(rate, 0);
+ iwl_hw_set_rate_n_flags(rate, 0);
tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
return (sizeof(*tx_beacon_cmd) + frame_size);
}
-/*
- * Tell 4965 where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq)
-{
- int rc;
- unsigned long flags;
- int txq_id = txq->q.id;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
-
- /* Circular buffer (TFD queue in DRAM) physical base address */
- iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
- txq->q.dma_addr >> 8);
-
- /* Enable DMA channel, using same id as for TFD queue */
- iwl_write_direct32(
- priv, IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
- IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
- IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
- dma_addr_t addr, u16 len)
+static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
{
- int index, is_odd;
- struct iwl4965_tfd_frame *tfd = ptr;
- u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);
-
- /* Each TFD can point to a maximum 20 Tx buffers */
- if ((num_tbs >= MAX_NUM_OF_TBS) || (num_tbs < 0)) {
- IWL_ERROR("Error can not send more than %d chunks\n",
- MAX_NUM_OF_TBS);
- return -EINVAL;
- }
-
- index = num_tbs / 2;
- is_odd = num_tbs & 0x1;
+ priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
+ sizeof(struct iwl4965_shared),
+ &priv->shared_phys);
+ if (!priv->shared_virt)
+ return -ENOMEM;
- if (!is_odd) {
- tfd->pa[index].tb1_addr = cpu_to_le32(addr);
- IWL_SET_BITS(tfd->pa[index], tb1_addr_hi,
- iwl_get_dma_hi_address(addr));
- IWL_SET_BITS(tfd->pa[index], tb1_len, len);
- } else {
- IWL_SET_BITS(tfd->pa[index], tb2_addr_lo16,
- (u32) (addr & 0xffff));
- IWL_SET_BITS(tfd->pa[index], tb2_addr_hi20, addr >> 16);
- IWL_SET_BITS(tfd->pa[index], tb2_len, len);
- }
+ memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
- IWL_SET_BITS(*tfd, num_tbs, num_tbs + 1);
+ priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
return 0;
}
-static void iwl4965_hw_card_show_info(struct iwl_priv *priv)
+static void iwl4965_free_shared_mem(struct iwl_priv *priv)
{
- u16 hw_version = priv->eeprom.board_revision_4965;
-
- IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n",
- ((hw_version >> 8) & 0x0F),
- ((hw_version >> 8) >> 4), (hw_version & 0x00FF));
-
- IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n",
- priv->eeprom.board_pba_number_4965);
+ if (priv->shared_virt)
+ pci_free_consistent(priv->pci_dev,
+ sizeof(struct iwl4965_shared),
+ priv->shared_virt,
+ priv->shared_phys);
}
-#define IWL_TX_CRC_SIZE 4
-#define IWL_TX_DELIMITER_SIZE 4
-
/**
* iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
*/
static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq,
+ struct iwl_tx_queue *txq,
u16 byte_cnt)
{
int len;
@@ -3180,50 +1775,13 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
tfd_offset[txq->q.write_ptr], byte_cnt, len);
/* If within first 64 entries, duplicate at end */
- if (txq->q.write_ptr < IWL4965_MAX_WIN_SIZE)
+ if (txq->q.write_ptr < IWL49_MAX_WIN_SIZE)
IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
- tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr],
+ tfd_offset[IWL49_QUEUE_SIZE + txq->q.write_ptr],
byte_cnt, len);
}
/**
- * iwl4965_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
- *
- * Selects how many and which Rx receivers/antennas/chains to use.
- * This should not be used for scan command ... it puts data in wrong place.
- */
-void iwl4965_set_rxon_chain(struct iwl_priv *priv)
-{
- u8 is_single = is_single_stream(priv);
- u8 idle_state, rx_state;
-
- priv->staging_rxon.rx_chain = 0;
- rx_state = idle_state = 3;
-
- /* Tell uCode which antennas are actually connected.
- * Before first association, we assume all antennas are connected.
- * Just after first association, iwl4965_noise_calibration()
- * checks which antennas actually *are* connected. */
- priv->staging_rxon.rx_chain |=
- cpu_to_le16(priv->valid_antenna << RXON_RX_CHAIN_VALID_POS);
-
- /* How many receivers should we use? */
- iwl4965_get_rx_chain_counter(priv, &idle_state, &rx_state);
- priv->staging_rxon.rx_chain |=
- cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS);
- priv->staging_rxon.rx_chain |=
- cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS);
-
- if (!is_single && (rx_state >= 2) &&
- !test_bit(STATUS_POWER_PMI, &priv->status))
- priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
- else
- priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
-
- IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain);
-}
-
-/**
* sign_extend - Sign extend a value using specified bit as sign-bit
*
* Example: sign_extend(9, 3) would return -7 as bit3 of 1001b is 1
@@ -3240,12 +1798,12 @@ static s32 sign_extend(u32 oper, int index)
}
/**
- * iwl4965_get_temperature - return the calibrated temperature (in Kelvin)
+ * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
* @statistics: Provides the temperature reading from the uCode
*
* A return of <0 indicates bogus data in the statistics
*/
-int iwl4965_get_temperature(const struct iwl_priv *priv)
+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
{
s32 temperature;
s32 vt;
@@ -3280,8 +1838,7 @@ int iwl4965_get_temperature(const struct iwl_priv *priv)
vt = sign_extend(
le32_to_cpu(priv->statistics.general.temperature), 23);
- IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n",
- R1, R2, R3, vt);
+ IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
if (R3 == R1) {
IWL_ERROR("Calibration conflict R1 == R3\n");
@@ -3292,11 +1849,10 @@ int iwl4965_get_temperature(const struct iwl_priv *priv)
* Add offset to center the adjustment around 0 degrees Centigrade. */
temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
temperature /= (R3 - R1);
- temperature = (temperature * 97) / 100 +
- TEMPERATURE_CALIB_KELVIN_OFFSET;
+ temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
- IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", temperature,
- KELVIN_TO_CELSIUS(temperature));
+ IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
+ temperature, KELVIN_TO_CELSIUS(temperature));
return temperature;
}
@@ -3343,89 +1899,11 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
return 1;
}
-/* Calculate noise level, based on measurements during network silence just
- * before arriving beacon. This measurement can be done only if we know
- * exactly when to expect beacons, therefore only when we're associated. */
-static void iwl4965_rx_calc_noise(struct iwl_priv *priv)
-{
- struct statistics_rx_non_phy *rx_info
- = &(priv->statistics.rx.general);
- int num_active_rx = 0;
- int total_silence = 0;
- int bcn_silence_a =
- le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
- int bcn_silence_b =
- le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
- int bcn_silence_c =
- le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
-
- if (bcn_silence_a) {
- total_silence += bcn_silence_a;
- num_active_rx++;
- }
- if (bcn_silence_b) {
- total_silence += bcn_silence_b;
- num_active_rx++;
- }
- if (bcn_silence_c) {
- total_silence += bcn_silence_c;
- num_active_rx++;
- }
-
- /* Average among active antennas */
- if (num_active_rx)
- priv->last_rx_noise = (total_silence / num_active_rx) - 107;
- else
- priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-
- IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
- bcn_silence_a, bcn_silence_b, bcn_silence_c,
- priv->last_rx_noise);
-}
-
-void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb)
+static void iwl4965_temperature_calib(struct iwl_priv *priv)
{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- int change;
s32 temp;
- IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
- (int)sizeof(priv->statistics), pkt->len);
-
- change = ((priv->statistics.general.temperature !=
- pkt->u.stats.general.temperature) ||
- ((priv->statistics.flag &
- STATISTICS_REPLY_FLG_FAT_MODE_MSK) !=
- (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)));
-
- memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
-
- set_bit(STATUS_STATISTICS, &priv->status);
-
- /* Reschedule the statistics timer to occur in
- * REG_RECALIB_PERIOD seconds to ensure we get a
- * thermal update even if the uCode doesn't give
- * us one */
- mod_timer(&priv->statistics_periodic, jiffies +
- msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
-
- if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
- (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
- iwl4965_rx_calc_noise(priv);
-#ifdef CONFIG_IWL4965_SENSITIVITY
- queue_work(priv->workqueue, &priv->sensitivity_work);
-#endif
- }
-
- iwl_leds_background(priv);
-
- /* If the hardware hasn't reported a change in
- * temperature then don't bother computing a
- * calibrated temperature value */
- if (!change)
- return;
-
- temp = iwl4965_get_temperature(priv);
+ temp = iwl4965_hw_get_temperature(priv);
if (temp < 0)
return;
@@ -3444,810 +1922,12 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl4965_rx_mem_buffe
priv->temperature = temp;
set_bit(STATUS_TEMPERATURE, &priv->status);
- if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
- iwl4965_is_temp_calib_needed(priv))
+ if (!priv->disable_tx_power_cal &&
+ unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
+ iwl4965_is_temp_calib_needed(priv))
queue_work(priv->workqueue, &priv->txpower_work);
}
-static void iwl4965_add_radiotap(struct iwl_priv *priv,
- struct sk_buff *skb,
- struct iwl4965_rx_phy_res *rx_start,
- struct ieee80211_rx_status *stats,
- u32 ampdu_status)
-{
- s8 signal = stats->ssi;
- s8 noise = 0;
- int rate = stats->rate_idx;
- u64 tsf = stats->mactime;
- __le16 antenna;
- __le16 phy_flags_hw = rx_start->phy_flags;
- struct iwl4965_rt_rx_hdr {
- struct ieee80211_radiotap_header rt_hdr;
- __le64 rt_tsf; /* TSF */
- u8 rt_flags; /* radiotap packet flags */
- u8 rt_rate; /* rate in 500kb/s */
- __le16 rt_channelMHz; /* channel in MHz */
- __le16 rt_chbitmask; /* channel bitfield */
- s8 rt_dbmsignal; /* signal in dBm, kluged to signed */
- s8 rt_dbmnoise;
- u8 rt_antenna; /* antenna number */
- } __attribute__ ((packed)) *iwl4965_rt;
-
- /* TODO: We won't have enough headroom for HT frames. Fix it later. */
- if (skb_headroom(skb) < sizeof(*iwl4965_rt)) {
- if (net_ratelimit())
- printk(KERN_ERR "not enough headroom [%d] for "
- "radiotap head [%zd]\n",
- skb_headroom(skb), sizeof(*iwl4965_rt));
- return;
- }
-
- /* put radiotap header in front of 802.11 header and data */
- iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt));
-
- /* initialise radiotap header */
- iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
- iwl4965_rt->rt_hdr.it_pad = 0;
-
- /* total header + data */
- put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)),
- &iwl4965_rt->rt_hdr.it_len);
-
- /* Indicate all the fields we add to the radiotap header */
- put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
- (1 << IEEE80211_RADIOTAP_FLAGS) |
- (1 << IEEE80211_RADIOTAP_RATE) |
- (1 << IEEE80211_RADIOTAP_CHANNEL) |
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
- (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
- (1 << IEEE80211_RADIOTAP_ANTENNA)),
- &iwl4965_rt->rt_hdr.it_present);
-
- /* Zero the flags, we'll add to them as we go */
- iwl4965_rt->rt_flags = 0;
-
- put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf);
-
- iwl4965_rt->rt_dbmsignal = signal;
- iwl4965_rt->rt_dbmnoise = noise;
-
- /* Convert the channel frequency and set the flags */
- put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz);
- if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
- put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
- IEEE80211_CHAN_5GHZ),
- &iwl4965_rt->rt_chbitmask);
- else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
- put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK |
- IEEE80211_CHAN_2GHZ),
- &iwl4965_rt->rt_chbitmask);
- else /* 802.11g */
- put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
- IEEE80211_CHAN_2GHZ),
- &iwl4965_rt->rt_chbitmask);
-
- if (rate == -1)
- iwl4965_rt->rt_rate = 0;
- else {
- if (stats->band == IEEE80211_BAND_5GHZ)
- rate += IWL_FIRST_OFDM_RATE;
-
- iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee;
- }
-
- /*
- * "antenna number"
- *
- * It seems that the antenna field in the phy flags value
- * is actually a bitfield. This is undefined by radiotap,
- * it wants an actual antenna number but I always get "7"
- * for most legacy frames I receive indicating that the
- * same frame was received on all three RX chains.
- *
- * I think this field should be removed in favour of a
- * new 802.11n radiotap field "RX chains" that is defined
- * as a bitmask.
- */
- antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
- iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4;
-
- /* set the preamble flag if appropriate */
- if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
- iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-
- stats->flag |= RX_FLAG_RADIOTAP;
-}
-
-static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
-{
- /* 0 - mgmt, 1 - cnt, 2 - data */
- int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
- priv->rx_stats[idx].cnt++;
- priv->rx_stats[idx].bytes += len;
-}
-
-static u32 iwl4965_translate_rx_status(u32 decrypt_in)
-{
- u32 decrypt_out = 0;
-
- if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
- RX_RES_STATUS_STATION_FOUND)
- decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
- RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
-
- decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
-
- /* packet was not encrypted */
- if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
- RX_RES_STATUS_SEC_TYPE_NONE)
- return decrypt_out;
-
- /* packet was encrypted with unknown alg */
- if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
- RX_RES_STATUS_SEC_TYPE_ERR)
- return decrypt_out;
-
- /* decryption was not done in HW */
- if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
- RX_MPDU_RES_STATUS_DEC_DONE_MSK)
- return decrypt_out;
-
- switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
-
- case RX_RES_STATUS_SEC_TYPE_CCMP:
- /* alg is CCM: check MIC only */
- if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
- /* Bad MIC */
- decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
- else
- decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
-
- break;
-
- case RX_RES_STATUS_SEC_TYPE_TKIP:
- if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
- /* Bad TTAK */
- decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
- break;
- }
- /* fall through if TTAK OK */
- default:
- if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
- decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
- else
- decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
- break;
- };
-
- IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
- decrypt_in, decrypt_out);
-
- return decrypt_out;
-}
-
-static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
- int include_phy,
- struct iwl4965_rx_mem_buffer *rxb,
- struct ieee80211_rx_status *stats)
-{
- struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data;
- struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
- (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
- struct ieee80211_hdr *hdr;
- u16 len;
- __le32 *rx_end;
- unsigned int skblen;
- u32 ampdu_status;
- u32 ampdu_status_legacy;
-
- if (!include_phy && priv->last_phy_res[0])
- rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
-
- if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
- return;
- }
- if (include_phy) {
- hdr = (struct ieee80211_hdr *)((u8 *) & rx_start[1] +
- rx_start->cfg_phy_cnt);
-
- len = le16_to_cpu(rx_start->byte_count);
-
- rx_end = (__le32 *) ((u8 *) & pkt->u.raw[0] +
- sizeof(struct iwl4965_rx_phy_res) +
- rx_start->cfg_phy_cnt + len);
-
- } else {
- struct iwl4965_rx_mpdu_res_start *amsdu =
- (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
-
- hdr = (struct ieee80211_hdr *)(pkt->u.raw +
- sizeof(struct iwl4965_rx_mpdu_res_start));
- len = le16_to_cpu(amsdu->byte_count);
- rx_start->byte_count = amsdu->byte_count;
- rx_end = (__le32 *) (((u8 *) hdr) + len);
- }
- if (len > priv->hw_params.max_pkt_size || len < 16) {
- IWL_WARNING("byte count out of range [16,4K] : %d\n", len);
- return;
- }
-
- ampdu_status = le32_to_cpu(*rx_end);
- skblen = ((u8 *) rx_end - (u8 *) & pkt->u.raw[0]) + sizeof(u32);
-
- if (!include_phy) {
- /* New status scheme, need to translate */
- ampdu_status_legacy = ampdu_status;
- ampdu_status = iwl4965_translate_rx_status(ampdu_status);
- }
-
- /* start from MAC */
- skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
- skb_put(rxb->skb, len); /* end where data ends */
-
- /* We only process data packets if the interface is open */
- if (unlikely(!priv->is_open)) {
- IWL_DEBUG_DROP_LIMIT
- ("Dropping packet while interface is not open.\n");
- return;
- }
-
- stats->flag = 0;
- hdr = (struct ieee80211_hdr *)rxb->skb->data;
-
- if (!priv->cfg->mod_params->sw_crypto)
- iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats);
-
- if (priv->add_radiotap)
- iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
-
- iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
- ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
- priv->alloc_rxb_skb--;
- rxb->skb = NULL;
-}
-
-/* Calc max signal level (dBm) among 3 possible receivers */
-static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp)
-{
- /* data from PHY/DSP regarding signal strength, etc.,
- * contents are always there, not configurable by host. */
- struct iwl4965_rx_non_cfg_phy *ncphy =
- (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
- u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
- >> IWL_AGC_DB_POS;
-
- u32 valid_antennae =
- (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
- >> RX_PHY_FLAGS_ANTENNAE_OFFSET;
- u8 max_rssi = 0;
- u32 i;
-
- /* Find max rssi among 3 possible receivers.
- * These values are measured by the digital signal processor (DSP).
- * They should stay fairly constant even as the signal strength varies,
- * if the radio's automatic gain control (AGC) is working right.
- * AGC value (see below) will provide the "interesting" info. */
- for (i = 0; i < 3; i++)
- if (valid_antennae & (1 << i))
- max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
-
- IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
- ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
- max_rssi, agc);
-
- /* dBm = max_rssi dB - agc dB - constant.
- * Higher AGC (higher radio gain) means lower signal. */
- return (max_rssi - agc - IWL_RSSI_OFFSET);
-}
-
-#ifdef CONFIG_IWL4965_HT
-
-void iwl4965_init_ht_hw_capab(struct iwl_priv *priv,
- struct ieee80211_ht_info *ht_info,
- enum ieee80211_band band)
-{
- ht_info->cap = 0;
- memset(ht_info->supp_mcs_set, 0, 16);
-
- ht_info->ht_supported = 1;
-
- if (band == IEEE80211_BAND_5GHZ) {
- ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH;
- ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40;
- ht_info->supp_mcs_set[4] = 0x01;
- }
- ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
- ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
- ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS &
- (IWL_MIMO_PS_NONE << 2));
-
- if (priv->cfg->mod_params->amsdu_size_8K)
- ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU;
-
- ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
- ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
-
- ht_info->supp_mcs_set[0] = 0xFF;
- ht_info->supp_mcs_set[1] = 0xFF;
-}
-#endif /* CONFIG_IWL4965_HT */
-
-static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
- priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
- priv->stations[sta_id].sta.sta.modify_mask = 0;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-}
-
-static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
-{
- /* FIXME: need locking over ps_status ??? */
- u8 sta_id = iwl4965_hw_find_station(priv, addr);
-
- if (sta_id != IWL_INVALID_STATION) {
- u8 sta_awake = priv->stations[sta_id].
- ps_status == STA_PS_STATUS_WAKE;
-
- if (sta_awake && ps_bit)
- priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP;
- else if (!sta_awake && !ps_bit) {
- iwl4965_sta_modify_ps_wake(priv, sta_id);
- priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE;
- }
- }
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-
-/**
- * iwl4965_dbg_report_frame - dump frame to syslog during debug sessions
- *
- * You may hack this function to show different aspects of received frames,
- * including selective frame dumps.
- * group100 parameter selects whether to show 1 out of 100 good frames.
- *
- * TODO: This was originally written for 3945, need to audit for
- * proper operation with 4965.
- */
-static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
- struct iwl4965_rx_packet *pkt,
- struct ieee80211_hdr *header, int group100)
-{
- u32 to_us;
- u32 print_summary = 0;
- u32 print_dump = 0; /* set to 1 to dump all frames' contents */
- u32 hundred = 0;
- u32 dataframe = 0;
- u16 fc;
- u16 seq_ctl;
- u16 channel;
- u16 phy_flags;
- int rate_sym;
- u16 length;
- u16 status;
- u16 bcn_tmr;
- u32 tsf_low;
- u64 tsf;
- u8 rssi;
- u8 agc;
- u16 sig_avg;
- u16 noise_diff;
- struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
- struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
- struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
- u8 *data = IWL_RX_DATA(pkt);
-
- if (likely(!(iwl_debug_level & IWL_DL_RX)))
- return;
-
- /* MAC header */
- fc = le16_to_cpu(header->frame_control);
- seq_ctl = le16_to_cpu(header->seq_ctrl);
-
- /* metadata */
- channel = le16_to_cpu(rx_hdr->channel);
- phy_flags = le16_to_cpu(rx_hdr->phy_flags);
- rate_sym = rx_hdr->rate;
- length = le16_to_cpu(rx_hdr->len);
-
- /* end-of-frame status and timestamp */
- status = le32_to_cpu(rx_end->status);
- bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
- tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
- tsf = le64_to_cpu(rx_end->timestamp);
-
- /* signal statistics */
- rssi = rx_stats->rssi;
- agc = rx_stats->agc;
- sig_avg = le16_to_cpu(rx_stats->sig_avg);
- noise_diff = le16_to_cpu(rx_stats->noise_diff);
-
- to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
-
- /* if data frame is to us and all is good,
- * (optionally) print summary for only 1 out of every 100 */
- if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
- (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
- dataframe = 1;
- if (!group100)
- print_summary = 1; /* print each frame */
- else if (priv->framecnt_to_us < 100) {
- priv->framecnt_to_us++;
- print_summary = 0;
- } else {
- priv->framecnt_to_us = 0;
- print_summary = 1;
- hundred = 1;
- }
- } else {
- /* print summary for all other frames */
- print_summary = 1;
- }
-
- if (print_summary) {
- char *title;
- int rate_idx;
- u32 bitrate;
-
- if (hundred)
- title = "100Frames";
- else if (fc & IEEE80211_FCTL_RETRY)
- title = "Retry";
- else if (ieee80211_is_assoc_response(fc))
- title = "AscRsp";
- else if (ieee80211_is_reassoc_response(fc))
- title = "RasRsp";
- else if (ieee80211_is_probe_response(fc)) {
- title = "PrbRsp";
- print_dump = 1; /* dump frame contents */
- } else if (ieee80211_is_beacon(fc)) {
- title = "Beacon";
- print_dump = 1; /* dump frame contents */
- } else if (ieee80211_is_atim(fc))
- title = "ATIM";
- else if (ieee80211_is_auth(fc))
- title = "Auth";
- else if (ieee80211_is_deauth(fc))
- title = "DeAuth";
- else if (ieee80211_is_disassoc(fc))
- title = "DisAssoc";
- else
- title = "Frame";
-
- rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym);
- if (unlikely(rate_idx == -1))
- bitrate = 0;
- else
- bitrate = iwl4965_rates[rate_idx].ieee / 2;
-
- /* print frame summary.
- * MAC addresses show just the last byte (for brevity),
- * but you can hack it to show more, if you'd like to. */
- if (dataframe)
- IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
- "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
- title, fc, header->addr1[5],
- length, rssi, channel, bitrate);
- else {
- /* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
- "src=0x%02x, rssi=%u, tim=%lu usec, "
- "phy=0x%02x, chnl=%d\n",
- title, fc, header->addr1[5],
- header->addr3[5], rssi,
- tsf_low - priv->scan_start_tsf,
- phy_flags, channel);
- }
- }
- if (print_dump)
- iwl_print_hex_dump(IWL_DL_RX, data, length);
-}
-#else
-static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv,
- struct iwl4965_rx_packet *pkt,
- struct ieee80211_hdr *header,
- int group100)
-{
-}
-#endif
-
-
-
-/* Called for REPLY_RX (legacy ABG frames), or
- * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
-static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct ieee80211_hdr *header;
- struct ieee80211_rx_status rx_status;
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- /* Use phy data (Rx signal strength, etc.) contained within
- * this rx packet for legacy frames,
- * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
- int include_phy = (pkt->hdr.cmd == REPLY_RX);
- struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
- (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
- (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
- __le32 *rx_end;
- unsigned int len = 0;
- u16 fc;
- u8 network_packet;
-
- rx_status.mactime = le64_to_cpu(rx_start->timestamp);
- rx_status.freq =
- ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
- rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
- IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
- rx_status.rate_idx =
- iwl4965_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
- if (rx_status.band == IEEE80211_BAND_5GHZ)
- rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
-
- rx_status.antenna = 0;
- rx_status.flag = 0;
-
- if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
- IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
- rx_start->cfg_phy_cnt);
- return;
- }
-
- if (!include_phy) {
- if (priv->last_phy_res[0])
- rx_start = (struct iwl4965_rx_phy_res *)
- &priv->last_phy_res[1];
- else
- rx_start = NULL;
- }
-
- if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
- return;
- }
-
- if (include_phy) {
- header = (struct ieee80211_hdr *)((u8 *) & rx_start[1]
- + rx_start->cfg_phy_cnt);
-
- len = le16_to_cpu(rx_start->byte_count);
- rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
- sizeof(struct iwl4965_rx_phy_res) + len);
- } else {
- struct iwl4965_rx_mpdu_res_start *amsdu =
- (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
-
- header = (void *)(pkt->u.raw +
- sizeof(struct iwl4965_rx_mpdu_res_start));
- len = le16_to_cpu(amsdu->byte_count);
- rx_end = (__le32 *) (pkt->u.raw +
- sizeof(struct iwl4965_rx_mpdu_res_start) + len);
- }
-
- if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
- !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
- IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
- le32_to_cpu(*rx_end));
- return;
- }
-
- priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
-
- /* Find max signal strength (dBm) among 3 antenna/receiver chains */
- rx_status.ssi = iwl4965_calc_rssi(rx_start);
-
- /* Meaningful noise values are available only from beacon statistics,
- * which are gathered only when associated, and indicate noise
- * only for the associated network channel ...
- * Ignore these noise values while scanning (other channels) */
- if (iwl_is_associated(priv) &&
- !test_bit(STATUS_SCANNING, &priv->status)) {
- rx_status.noise = priv->last_rx_noise;
- rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi,
- rx_status.noise);
- } else {
- rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
- rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0);
- }
-
- /* Reset beacon noise level if not associated. */
- if (!iwl_is_associated(priv))
- priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-
- /* Set "1" to report good data frames in groups of 100 */
- /* FIXME: need to optimze the call: */
- iwl4965_dbg_report_frame(priv, pkt, header, 1);
-
- IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
- rx_status.ssi, rx_status.noise, rx_status.signal,
- (unsigned long long)rx_status.mactime);
-
- network_packet = iwl4965_is_network_packet(priv, header);
- if (network_packet) {
- priv->last_rx_rssi = rx_status.ssi;
- priv->last_beacon_time = priv->ucode_beacon_time;
- priv->last_tsf = le64_to_cpu(rx_start->timestamp);
- }
-
- fc = le16_to_cpu(header->frame_control);
- switch (fc & IEEE80211_FCTL_FTYPE) {
- case IEEE80211_FTYPE_MGMT:
- if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
- iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
- header->addr2);
- iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &rx_status);
- break;
-
- case IEEE80211_FTYPE_CTL:
-#ifdef CONFIG_IWL4965_HT
- switch (fc & IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_BACK_REQ:
- IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
- iwl4965_handle_data_packet(priv, 0, include_phy,
- rxb, &rx_status);
- break;
- default:
- break;
- }
-#endif
- break;
-
- case IEEE80211_FTYPE_DATA: {
- DECLARE_MAC_BUF(mac1);
- DECLARE_MAC_BUF(mac2);
- DECLARE_MAC_BUF(mac3);
-
- if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
- iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
- header->addr2);
-
- if (unlikely(!network_packet))
- IWL_DEBUG_DROP("Dropping (non network): "
- "%s, %s, %s\n",
- print_mac(mac1, header->addr1),
- print_mac(mac2, header->addr2),
- print_mac(mac3, header->addr3));
- else if (unlikely(iwl4965_is_duplicate_packet(priv, header)))
- IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
- print_mac(mac1, header->addr1),
- print_mac(mac2, header->addr2),
- print_mac(mac3, header->addr3));
- else
- iwl4965_handle_data_packet(priv, 1, include_phy, rxb,
- &rx_status);
- break;
- }
- default:
- break;
-
- }
-}
-
-/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
- * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
-static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- priv->last_phy_res[0] = 1;
- memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
- sizeof(struct iwl4965_rx_phy_res));
-}
-static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-
-{
-#ifdef CONFIG_IWL4965_SENSITIVITY
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_missed_beacon_notif *missed_beacon;
-
- missed_beacon = &pkt->u.missed_beacon;
- if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
- IWL_DEBUG_CALIB("missed bcn cnsq %d totl %d rcd %d expctd %d\n",
- le32_to_cpu(missed_beacon->consequtive_missed_beacons),
- le32_to_cpu(missed_beacon->total_missed_becons),
- le32_to_cpu(missed_beacon->num_recvd_beacons),
- le32_to_cpu(missed_beacon->num_expected_beacons));
- priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT;
- if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)))
- queue_work(priv->workqueue, &priv->sensitivity_work);
- }
-#endif /*CONFIG_IWL4965_SENSITIVITY*/
-}
-#ifdef CONFIG_IWL4965_HT
-
-/**
- * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table
- */
-static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv,
- int sta_id, int tid)
-{
- unsigned long flags;
-
- /* Remove "disable" flag, to enable Tx for this TID */
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
- priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-}
-
-/**
- * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack
- *
- * Go through block-ack's bitmap of ACK'd frames, update driver's record of
- * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
- */
-static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
- struct iwl4965_ht_agg *agg,
- struct iwl4965_compressed_ba_resp*
- ba_resp)
-
-{
- int i, sh, ack;
- u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
- u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
- u64 bitmap;
- int successes = 0;
- struct ieee80211_tx_status *tx_status;
-
- if (unlikely(!agg->wait_for_ba)) {
- IWL_ERROR("Received BA when not expected\n");
- return -EINVAL;
- }
-
- /* Mark that the expected block-ack response arrived */
- agg->wait_for_ba = 0;
- IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
-
- /* Calculate shift to align block-ack bits with our Tx window bits */
- sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4);
- if (sh < 0) /* tbw something is wrong with indices */
- sh += 0x100;
-
- /* don't use 64-bit values for now */
- bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
-
- if (agg->frame_count > (64 - sh)) {
- IWL_DEBUG_TX_REPLY("more frames than bitmap size");
- return -1;
- }
-
- /* check for success or failure according to the
- * transmitted bitmap and block-ack bitmap */
- bitmap &= agg->bitmap;
-
- /* For each frame attempted in aggregation,
- * update driver's record of tx frame's status. */
- for (i = 0; i < agg->frame_count ; i++) {
- ack = bitmap & (1 << i);
- successes += !!ack;
- IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
- ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,
- agg->start_idx + i);
- }
-
- tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status;
- tx_status->flags = IEEE80211_TX_STATUS_ACK;
- tx_status->flags |= IEEE80211_TX_STATUS_AMPDU;
- tx_status->ampdu_ack_map = successes;
- tx_status->ampdu_ack_len = agg->frame_count;
- iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags,
- &tx_status->control);
-
- IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
-
- return 0;
-}
-
/**
* iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration
*/
@@ -4258,22 +1938,24 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
* the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
iwl_write_prph(priv,
IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
- (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
- (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+ (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
+ (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
}
/**
- * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
+ * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE
* priv->lock must be held by the caller
*/
-static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id,
- u16 ssn_idx, u8 tx_fifo)
+static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+ u16 ssn_idx, u8 tx_fifo)
{
int ret = 0;
- if (IWL_BACK_QUEUE_FIRST_ID > txq_id) {
- IWL_WARNING("queue number too small: %d, must be > %d\n",
- txq_id, IWL_BACK_QUEUE_FIRST_ID);
+ if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
+ (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
+ IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ txq_id, IWL49_FIRST_AMPDU_QUEUE,
+ IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
}
@@ -4291,7 +1973,7 @@ static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id,
iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
iwl_clear_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id));
- iwl4965_txq_ctx_deactivate(priv, txq_id);
+ iwl_txq_ctx_deactivate(priv, txq_id);
iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
iwl_release_nic_access(priv);
@@ -4299,121 +1981,6 @@ static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id,
return 0;
}
-int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
- u8 tid, int txq_id)
-{
- struct iwl4965_queue *q = &priv->txq[txq_id].q;
- u8 *addr = priv->stations[sta_id].sta.sta.addr;
- struct iwl4965_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
-
- switch (priv->stations[sta_id].tid[tid].agg.state) {
- case IWL_EMPTYING_HW_QUEUE_DELBA:
- /* We are reclaiming the last packet of the */
- /* aggregated HW queue */
- if (txq_id == tid_data->agg.txq_id &&
- q->read_ptr == q->write_ptr) {
- u16 ssn = SEQ_TO_SN(tid_data->seq_number);
- int tx_fifo = default_tid_to_tx_fifo[tid];
- IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
- iwl4965_tx_queue_agg_disable(priv, txq_id,
- ssn, tx_fifo);
- tid_data->agg.state = IWL_AGG_OFF;
- ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid);
- }
- break;
- case IWL_EMPTYING_HW_QUEUE_ADDBA:
- /* We are reclaiming the last packet of the queue */
- if (tid_data->tfds_in_queue == 0) {
- IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n");
- tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid);
- }
- break;
- }
- return 0;
-}
-
-/**
- * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed
- * @index -- current index
- * @n_bd -- total number of entries in queue (s/b power of 2)
- */
-static inline int iwl4965_queue_dec_wrap(int index, int n_bd)
-{
- return (index == 0) ? n_bd - 1 : index - 1;
-}
-
-/**
- * iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
- *
- * Handles block-acknowledge notification from device, which reports success
- * of frames sent via aggregation.
- */
-static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
- int index;
- struct iwl4965_tx_queue *txq = NULL;
- struct iwl4965_ht_agg *agg;
- DECLARE_MAC_BUF(mac);
-
- /* "flow" corresponds to Tx queue */
- u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
-
- /* "ssn" is start of block-ack Tx window, corresponds to index
- * (in Tx queue's circular buffer) of first TFD/frame in window */
- u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
-
- if (scd_flow >= priv->hw_params.max_txq_num) {
- IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
- return;
- }
-
- txq = &priv->txq[scd_flow];
- agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg;
-
- /* Find index just before block-ack window */
- index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
-
- /* TODO: Need to get this copy more safely - now good for debug */
-
- IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, "
- "sta_id = %d\n",
- agg->wait_for_ba,
- print_mac(mac, (u8*) &ba_resp->sta_addr_lo32),
- ba_resp->sta_id);
- IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
- "%d, scd_ssn = %d\n",
- ba_resp->tid,
- ba_resp->seq_ctl,
- (unsigned long long)le64_to_cpu(ba_resp->bitmap),
- ba_resp->scd_flow,
- ba_resp->scd_ssn);
- IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
- agg->start_idx,
- (unsigned long long)agg->bitmap);
-
- /* Update driver's record of ACK vs. not for each frame in window */
- iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp);
-
- /* Release all TFDs before the SSN, i.e. all TFDs in front of
- * block-ack window (we assume that they've been successfully
- * transmitted ... if not, it's too late anyway). */
- if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
- int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index);
- priv->stations[ba_resp->sta_id].
- tid[ba_resp->tid].tfds_in_queue -= freed;
- if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
- priv->mac80211_registered &&
- agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
- ieee80211_wake_queue(priv->hw, scd_flow);
- iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id,
- ba_resp->tid, scd_flow);
- }
-}
-
/**
* iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue
*/
@@ -4424,10 +1991,10 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
u32 tbl_dw;
u16 scd_q2ratid;
- scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK;
+ scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
tbl_dw_addr = priv->scd_base_addr +
- SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
+ IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
@@ -4445,31 +2012,34 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
/**
* iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue
*
- * NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID,
+ * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE,
* i.e. it must be one of the higher queues used for aggregation
*/
-static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id,
- int tx_fifo, int sta_id, int tid,
- u16 ssn_idx)
+static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
+ int tx_fifo, int sta_id, int tid, u16 ssn_idx)
{
unsigned long flags;
- int rc;
+ int ret;
u16 ra_tid;
- if (IWL_BACK_QUEUE_FIRST_ID > txq_id)
- IWL_WARNING("queue number too small: %d, must be > %d\n",
- txq_id, IWL_BACK_QUEUE_FIRST_ID);
+ if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
+ (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
+ IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ txq_id, IWL49_FIRST_AMPDU_QUEUE,
+ IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
+ return -EINVAL;
+ }
ra_tid = BUILD_RAxTID(sta_id, tid);
/* Modify device's station table to Tx this TID */
- iwl4965_sta_modify_enable_tid_tx(priv, sta_id, tid);
+ iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ return ret;
}
/* Stop this Tx queue before configuring it */
@@ -4489,14 +2059,14 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id,
/* Set up Tx window size and frame limit for this queue */
iwl_write_targ_mem(priv,
- priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id),
- (SCD_WIN_SIZE << SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
- SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
+ priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id),
+ (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
+ IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
iwl_write_targ_mem(priv, priv->scd_base_addr +
- SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
- (SCD_FRAME_LIMIT << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS)
- & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
+ IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
+ (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS)
+ & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
iwl_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id));
@@ -4509,444 +2079,313 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id,
return 0;
}
-#endif /* CONFIG_IWL4965_HT */
-
-/**
- * iwl4965_add_station - Initialize a station's hardware rate table
- *
- * The uCode's station table contains a table of fallback rates
- * for automatic fallback during transmission.
- *
- * NOTE: This sets up a default set of values. These will be replaced later
- * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of
- * rc80211_simple.
- *
- * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
- * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
- * which requires station table entry to exist).
- */
-void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
-{
- int i, r;
- struct iwl_link_quality_cmd link_cmd = {
- .reserved1 = 0,
- };
- u16 rate_flags;
-
- /* Set up the rate scaling to start at selected rate, fall back
- * all the way down to 1M in IEEE order, and then spin on 1M */
- if (is_ap)
- r = IWL_RATE_54M_INDEX;
- else if (priv->band == IEEE80211_BAND_5GHZ)
- r = IWL_RATE_6M_INDEX;
- else
- r = IWL_RATE_1M_INDEX;
-
- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
- rate_flags = 0;
- if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
- rate_flags |= RATE_MCS_CCK_MSK;
-
- /* Use Tx antenna B only */
- rate_flags |= RATE_MCS_ANT_B_MSK;
- rate_flags &= ~RATE_MCS_ANT_A_MSK;
-
- link_cmd.rs_table[i].rate_n_flags =
- iwl4965_hw_set_rate_n_flags(iwl4965_rates[r].plcp, rate_flags);
- r = iwl4965_get_prev_ieee_rate(r);
- }
-
- link_cmd.general_params.single_stream_ant_msk = 2;
- link_cmd.general_params.dual_stream_ant_msk = 3;
- link_cmd.agg_params.agg_dis_start_th = 3;
- link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
-
- /* Update the rate scaling for control frame Tx to AP */
- link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
-
- iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
- sizeof(link_cmd), &link_cmd, NULL);
-}
-
-#ifdef CONFIG_IWL4965_HT
-
-static u8 iwl4965_is_channel_extension(struct iwl_priv *priv,
- enum ieee80211_band band,
- u16 channel, u8 extension_chan_offset)
-{
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv, band, channel);
- if (!is_channel_valid(ch_info))
- return 0;
-
- if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)
- return 0;
-
- if ((ch_info->fat_extension_channel == extension_chan_offset) ||
- (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX))
- return 1;
-
- return 0;
-}
-
-static u8 iwl4965_is_fat_tx_allowed(struct iwl_priv *priv,
- struct ieee80211_ht_info *sta_ht_inf)
-{
- struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
-
- if ((!iwl_ht_conf->is_ht) ||
- (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
- (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE))
- return 0;
-
- if (sta_ht_inf) {
- if ((!sta_ht_inf->ht_supported) ||
- (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)))
- return 0;
- }
-
- return (iwl4965_is_channel_extension(priv, priv->band,
- iwl_ht_conf->control_channel,
- iwl_ht_conf->extension_chan_offset));
-}
-
-void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
+int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
+ enum ieee80211_ampdu_mlme_action action,
+ const u8 *addr, u16 tid, u16 *ssn)
{
- struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon;
- u32 val;
+ struct iwl_priv *priv = hw->priv;
+ DECLARE_MAC_BUF(mac);
- if (!ht_info->is_ht)
- return;
+ IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
+ print_mac(mac, addr), tid);
- /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
- if (iwl4965_is_fat_tx_allowed(priv, NULL))
- rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK;
- else
- rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
- RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
-
- if (le16_to_cpu(rxon->channel) != ht_info->control_channel) {
- IWL_DEBUG_ASSOC("control diff than current %d %d\n",
- le16_to_cpu(rxon->channel),
- ht_info->control_channel);
- rxon->channel = cpu_to_le16(ht_info->control_channel);
- return;
- }
+ if (!(priv->cfg->sku & IWL_SKU_N))
+ return -EACCES;
- /* Note: control channel is opposite of extension channel */
- switch (ht_info->extension_chan_offset) {
- case IWL_EXT_CHANNEL_OFFSET_ABOVE:
- rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
- break;
- case IWL_EXT_CHANNEL_OFFSET_BELOW:
- rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
- break;
- case IWL_EXT_CHANNEL_OFFSET_NONE:
+ switch (action) {
+ case IEEE80211_AMPDU_RX_START:
+ IWL_DEBUG_HT("start Rx\n");
+ return iwl_rx_agg_start(priv, addr, tid, *ssn);
+ case IEEE80211_AMPDU_RX_STOP:
+ IWL_DEBUG_HT("stop Rx\n");
+ return iwl_rx_agg_stop(priv, addr, tid);
+ case IEEE80211_AMPDU_TX_START:
+ IWL_DEBUG_HT("start Tx\n");
+ return iwl_tx_agg_start(priv, addr, tid, ssn);
+ case IEEE80211_AMPDU_TX_STOP:
+ IWL_DEBUG_HT("stop Tx\n");
+ return iwl_tx_agg_stop(priv, addr, tid);
default:
- rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
+ IWL_DEBUG_HT("unknown\n");
+ return -EINVAL;
break;
}
-
- val = ht_info->ht_protection;
-
- rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS);
-
- iwl4965_set_rxon_chain(priv);
-
- IWL_DEBUG_ASSOC("supported HT rate 0x%X %X "
- "rxon flags 0x%X operation mode :0x%X "
- "extension channel offset 0x%x "
- "control chan %d\n",
- ht_info->supp_mcs_set[0], ht_info->supp_mcs_set[1],
- le32_to_cpu(rxon->flags), ht_info->ht_protection,
- ht_info->extension_chan_offset,
- ht_info->control_channel);
- return;
+ return 0;
}
-void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index,
- struct ieee80211_ht_info *sta_ht_inf)
+static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
{
- __le32 sta_flags;
- u8 mimo_ps_mode;
-
- if (!sta_ht_inf || !sta_ht_inf->ht_supported)
- goto done;
-
- mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2;
-
- sta_flags = priv->stations[index].sta.station_flags;
-
- sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
-
- switch (mimo_ps_mode) {
- case WLAN_HT_CAP_MIMO_PS_STATIC:
- sta_flags |= STA_FLG_MIMO_DIS_MSK;
- break;
- case WLAN_HT_CAP_MIMO_PS_DYNAMIC:
- sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
- break;
- case WLAN_HT_CAP_MIMO_PS_DISABLED:
- break;
+ switch (cmd_id) {
+ case REPLY_RXON:
+ return (u16) sizeof(struct iwl4965_rxon_cmd);
default:
- IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode);
- break;
+ return len;
}
-
- sta_flags |= cpu_to_le32(
- (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
-
- sta_flags |= cpu_to_le32(
- (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
-
- if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf))
- sta_flags |= STA_FLG_FAT_EN_MSK;
- else
- sta_flags &= ~STA_FLG_FAT_EN_MSK;
-
- priv->stations[index].sta.station_flags = sta_flags;
- done:
- return;
}
-static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv,
- int sta_id, int tid, u16 ssn)
+static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags_msk = 0;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
- priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
- priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
+ struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data;
+ addsta->mode = cmd->mode;
+ memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
+ memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
+ addsta->station_flags = cmd->station_flags;
+ addsta->station_flags_msk = cmd->station_flags_msk;
+ addsta->tid_disable_tx = cmd->tid_disable_tx;
+ addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
+ addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
+ addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
+ addsta->reserved1 = __constant_cpu_to_le16(0);
+ addsta->reserved2 = __constant_cpu_to_le32(0);
- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ return (u16)sizeof(struct iwl4965_addsta_cmd);
}
-static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv,
- int sta_id, int tid)
+static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].sta.station_flags_msk = 0;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
- priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
}
-/*
- * Find first available (lowest unused) Tx Queue, mark it "active".
- * Called only when finding queue for aggregation.
- * Should never return anything < 7, because they should already
- * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6).
+/**
+ * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue
*/
-static int iwl4965_txq_ctx_activate_free(struct iwl_priv *priv)
-{
- int txq_id;
-
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
- if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk))
- return txq_id;
- return -1;
-}
-
-static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
- u16 tid, u16 *start_seq_num)
+static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
+ struct iwl_ht_agg *agg,
+ struct iwl4965_tx_resp *tx_resp,
+ int txq_id, u16 start_idx)
{
- struct iwl_priv *priv = hw->priv;
- int sta_id;
- int tx_fifo;
- int txq_id;
- int ssn = -1;
- int ret = 0;
- unsigned long flags;
- struct iwl4965_tid_data *tid_data;
- DECLARE_MAC_BUF(mac);
-
- if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
- tx_fifo = default_tid_to_tx_fifo[tid];
- else
- return -EINVAL;
-
- IWL_WARNING("%s on da = %s tid = %d\n",
- __func__, print_mac(mac, da), tid);
-
- sta_id = iwl4965_hw_find_station(priv, da);
- if (sta_id == IWL_INVALID_STATION)
- return -ENXIO;
-
- if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
- IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n");
- return -ENXIO;
- }
-
- txq_id = iwl4965_txq_ctx_activate_free(priv);
- if (txq_id == -1)
- return -ENXIO;
+ u16 status;
+ struct agg_tx_status *frame_status = tx_resp->u.agg_status;
+ struct ieee80211_tx_info *info = NULL;
+ struct ieee80211_hdr *hdr = NULL;
+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
+ int i, sh, idx;
+ u16 seq;
+ if (agg->wait_for_ba)
+ IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+
+ agg->frame_count = tx_resp->frame_count;
+ agg->start_idx = start_idx;
+ agg->rate_n_flags = rate_n_flags;
+ agg->bitmap = 0;
+
+ /* # frames attempted by Tx command */
+ if (agg->frame_count == 1) {
+ /* Only one frame was attempted; no block-ack will arrive */
+ status = le16_to_cpu(frame_status[0].status);
+ idx = start_idx;
+
+ /* FIXME: code repetition */
+ IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ agg->frame_count, agg->start_idx, idx);
+
+ info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
+ info->status.retry_count = tx_resp->failure_frame;
+ info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+ info->flags |= iwl_is_tx_success(status)?
+ IEEE80211_TX_STAT_ACK : 0;
+ iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
+ /* FIXME: code repetition end */
+
+ IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+ status & 0xff, tx_resp->failure_frame);
+ IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+
+ agg->wait_for_ba = 0;
+ } else {
+ /* Two or more frames were attempted; expect block-ack */
+ u64 bitmap = 0;
+ int start = agg->start_idx;
+
+ /* Construct bit-map of pending frames within Tx window */
+ for (i = 0; i < agg->frame_count; i++) {
+ u16 sc;
+ status = le16_to_cpu(frame_status[i].status);
+ seq = le16_to_cpu(frame_status[i].sequence);
+ idx = SEQ_TO_INDEX(seq);
+ txq_id = SEQ_TO_QUEUE(seq);
+
+ if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
+ AGG_TX_STATE_ABORT_MSK))
+ continue;
+
+ IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ agg->frame_count, txq_id, idx);
+
+ hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
+
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ if (idx != (SEQ_TO_SN(sc) & 0xff)) {
+ IWL_ERROR("BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
+ idx, SEQ_TO_SN(sc),
+ hdr->seq_ctrl);
+ return -1;
+ }
- spin_lock_irqsave(&priv->sta_lock, flags);
- tid_data = &priv->stations[sta_id].tid[tid];
- ssn = SEQ_TO_SN(tid_data->seq_number);
- tid_data->agg.txq_id = txq_id;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
+ IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+ i, idx, SEQ_TO_SN(sc));
+
+ sh = idx - start;
+ if (sh > 64) {
+ sh = (start - idx) + 0xff;
+ bitmap = bitmap << sh;
+ sh = 0;
+ start = idx;
+ } else if (sh < -64)
+ sh = 0xff - (start - idx);
+ else if (sh < 0) {
+ sh = start - idx;
+ start = idx;
+ bitmap = bitmap << sh;
+ sh = 0;
+ }
+ bitmap |= (1 << sh);
+ IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
+ start, (u32)(bitmap & 0xFFFFFFFF));
+ }
- *start_seq_num = ssn;
- ret = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo,
- sta_id, tid, ssn);
- if (ret)
- return ret;
+ agg->bitmap = bitmap;
+ agg->start_idx = start;
+ IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ agg->frame_count, agg->start_idx,
+ (unsigned long long)agg->bitmap);
- ret = 0;
- if (tid_data->tfds_in_queue == 0) {
- printk(KERN_ERR "HW queue is empty\n");
- tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(hw, da, tid);
- } else {
- IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n",
- tid_data->tfds_in_queue);
- tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
+ if (bitmap)
+ agg->wait_for_ba = 1;
}
- return ret;
+ return 0;
}
-static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
- u16 tid)
-{
-
- struct iwl_priv *priv = hw->priv;
- int tx_fifo_id, txq_id, sta_id, ssn = -1;
- struct iwl4965_tid_data *tid_data;
- int ret, write_ptr, read_ptr;
- unsigned long flags;
- DECLARE_MAC_BUF(mac);
+/**
+ * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
+ */
+static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ u16 sequence = le16_to_cpu(pkt->hdr.sequence);
+ int txq_id = SEQ_TO_QUEUE(sequence);
+ int index = SEQ_TO_INDEX(sequence);
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct ieee80211_tx_info *info;
+ struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+ u32 status = le32_to_cpu(tx_resp->u.status);
+ int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
+ __le16 fc;
+ struct ieee80211_hdr *hdr;
+ u8 *qc = NULL;
- if (!da) {
- IWL_ERROR("da = NULL\n");
- return -EINVAL;
+ if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+ IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ "is out of range [0-%d] %d %d\n", txq_id,
+ index, txq->q.n_bd, txq->q.write_ptr,
+ txq->q.read_ptr);
+ return;
}
- if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
- tx_fifo_id = default_tid_to_tx_fifo[tid];
- else
- return -EINVAL;
-
- sta_id = iwl4965_hw_find_station(priv, da);
-
- if (sta_id == IWL_INVALID_STATION)
- return -ENXIO;
-
- if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n");
+ info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
+ memset(&info->status, 0, sizeof(info->status));
- tid_data = &priv->stations[sta_id].tid[tid];
- ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
- txq_id = tid_data->agg.txq_id;
- write_ptr = priv->txq[txq_id].q.write_ptr;
- read_ptr = priv->txq[txq_id].q.read_ptr;
+ hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
+ fc = hdr->frame_control;
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ }
- /* The queue is not empty */
- if (write_ptr != read_ptr) {
- IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n");
- priv->stations[sta_id].tid[tid].agg.state =
- IWL_EMPTYING_HW_QUEUE_DELBA;
- return 0;
+ sta_id = iwl_get_ra_sta_id(priv, hdr);
+ if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
+ IWL_ERROR("Station not known\n");
+ return;
}
- IWL_DEBUG_HT("HW queue empty\n");;
- priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
+ if (txq->sched_retry) {
+ const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
+ struct iwl_ht_agg *agg = NULL;
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
- spin_unlock_irqrestore(&priv->lock, flags);
+ if (!qc)
+ return;
- if (ret)
- return ret;
+ agg = &priv->stations[sta_id].tid[tid].agg;
- ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid);
+ iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
- IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n",
- print_mac(mac, da), tid);
+ /* check if BAR is needed */
+ if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
+ info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
- return 0;
-}
+ if (txq->q.read_ptr != (scd_ssn & 0xff)) {
+ int freed, ampdu_q;
+ index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
+ IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
+ "%d index %d\n", scd_ssn , index);
+ freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
-int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
- enum ieee80211_ampdu_mlme_action action,
- const u8 *addr, u16 tid, u16 *ssn)
-{
- struct iwl_priv *priv = hw->priv;
- int sta_id;
- DECLARE_MAC_BUF(mac);
-
- IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ",
- print_mac(mac, addr), tid);
- sta_id = iwl4965_hw_find_station(priv, addr);
- switch (action) {
- case IEEE80211_AMPDU_RX_START:
- IWL_DEBUG_HT("start Rx\n");
- iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, *ssn);
- break;
- case IEEE80211_AMPDU_RX_STOP:
- IWL_DEBUG_HT("stop Rx\n");
- iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid);
- break;
- case IEEE80211_AMPDU_TX_START:
- IWL_DEBUG_HT("start Tx\n");
- return iwl4965_mac_ht_tx_agg_start(hw, addr, tid, ssn);
- case IEEE80211_AMPDU_TX_STOP:
- IWL_DEBUG_HT("stop Tx\n");
- return iwl4965_mac_ht_tx_agg_stop(hw, addr, tid);
- default:
- IWL_DEBUG_HT("unknown\n");
- return -EINVAL;
- break;
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ txq_id >= 0 && priv->mac80211_registered &&
+ agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
+ /* calculate mac80211 ampdu sw queue to wake */
+ ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +
+ priv->hw->queues;
+ if (agg->state == IWL_AGG_OFF)
+ ieee80211_wake_queue(priv->hw, txq_id);
+ else
+ ieee80211_wake_queue(priv->hw, ampdu_q);
+ }
+ iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+ }
+ } else {
+ info->status.retry_count = tx_resp->failure_frame;
+ info->flags |=
+ iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
+ iwl_hwrate_to_tx_control(priv,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+
+ IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
+ "0x%x retries %d\n", txq_id,
+ iwl_get_tx_fail_reason(status),
+ status, le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+
+ IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+
+ if (index != -1) {
+ int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+ if (tid != MAX_TID_COUNT)
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ (txq_id >= 0) && priv->mac80211_registered)
+ ieee80211_wake_queue(priv->hw, txq_id);
+ if (tid != MAX_TID_COUNT)
+ iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+ }
}
- return 0;
+
+ if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
+ IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
}
-#endif /* CONFIG_IWL4965_HT */
/* Set up 4965-specific Rx frame reply handlers */
-void iwl4965_hw_rx_handler_setup(struct iwl_priv *priv)
+static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
{
/* Legacy Rx frames */
- priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx;
-
- /* High-throughput (HT) Rx frames */
- priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy;
- priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl4965_rx_reply_rx;
-
- priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
- iwl4965_rx_missed_beacon_notif;
-
-#ifdef CONFIG_IWL4965_HT
- priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;
-#endif /* CONFIG_IWL4965_HT */
+ priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx;
+ /* Tx response */
+ priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
}
-void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv)
+static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
{
INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);
-#ifdef CONFIG_IWL4965_SENSITIVITY
- INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work);
-#endif
- init_timer(&priv->statistics_periodic);
- priv->statistics_periodic.data = (unsigned long)priv;
- priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;
}
-void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv)
+static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
{
- del_timer_sync(&priv->statistics_periodic);
-
- cancel_delayed_work(&priv->init_alive_start);
+ cancel_work_sync(&priv->txpower_work);
}
@@ -4955,23 +2394,56 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
};
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
- .enqueue_hcmd = iwl4965_enqueue_hcmd,
+ .get_hcmd_size = iwl4965_get_hcmd_size,
+ .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
+ .chain_noise_reset = iwl4965_chain_noise_reset,
+ .gain_computation = iwl4965_gain_computation,
+ .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
};
static struct iwl_lib_ops iwl4965_lib = {
- .init_drv = iwl4965_init_drv,
.set_hw_params = iwl4965_hw_set_hw_params,
+ .alloc_shared_mem = iwl4965_alloc_shared_mem,
+ .free_shared_mem = iwl4965_free_shared_mem,
+ .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
.txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
- .hw_nic_init = iwl4965_hw_nic_init,
+ .txq_set_sched = iwl4965_txq_set_sched,
+ .txq_agg_enable = iwl4965_txq_agg_enable,
+ .txq_agg_disable = iwl4965_txq_agg_disable,
+ .rx_handler_setup = iwl4965_rx_handler_setup,
+ .setup_deferred_work = iwl4965_setup_deferred_work,
+ .cancel_deferred_work = iwl4965_cancel_deferred_work,
.is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr,
.alive_notify = iwl4965_alive_notify,
+ .init_alive_start = iwl4965_init_alive_start,
.load_ucode = iwl4965_load_bsm,
+ .apm_ops = {
+ .init = iwl4965_apm_init,
+ .reset = iwl4965_apm_reset,
+ .stop = iwl4965_apm_stop,
+ .config = iwl4965_nic_config,
+ .set_pwr_src = iwl4965_set_pwr_src,
+ },
.eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS,
+ EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS
+ },
.verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
+ .check_version = iwl4965_eeprom_check_version,
+ .query_addr = iwlcore_eeprom_query_addr,
},
- .radio_kill_sw = iwl4965_radio_kill_sw,
+ .set_power = iwl4965_set_power,
+ .send_tx_power = iwl4965_send_tx_power,
+ .update_chain_flags = iwl4965_update_chain_flags,
+ .temperature = iwl4965_temperature_calib,
};
static struct iwl_ops iwl4965_ops = {
@@ -4984,10 +2456,14 @@ struct iwl_cfg iwl4965_agn_cfg = {
.name = "4965AGN",
.fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
.ops = &iwl4965_ops,
.mod_params = &iwl4965_mod_params,
};
+/* Module firmware */
+MODULE_FIRMWARE("iwlwifi-4965" IWL4965_UCODE_API ".ucode");
+
module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
@@ -5002,10 +2478,14 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
-
/* QoS */
module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444);
MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
+/* 11n */
+module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
+MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
+module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
new file mode 100644
index 00000000000..17d4f31c593
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -0,0 +1,134 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * 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.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ *****************************************************************************/
+/*
+ * Please use this file (iwl-5000-hw.h) only for hardware-related definitions.
+ * Use iwl-5000-commands.h for uCode API definitions.
+ */
+
+#ifndef __iwl_5000_hw_h__
+#define __iwl_5000_hw_h__
+
+#define IWL50_RTC_INST_UPPER_BOUND (0x020000)
+#define IWL50_RTC_DATA_UPPER_BOUND (0x80C000)
+#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
+#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+
+/* EERPROM */
+#define IWL_5000_EEPROM_IMG_SIZE 2048
+
+
+#define IWL50_MAX_WIN_SIZE 64
+#define IWL50_QUEUE_SIZE 256
+#define IWL50_CMD_FIFO_NUM 7
+#define IWL50_NUM_QUEUES 20
+#define IWL50_NUM_AMPDU_QUEUES 10
+#define IWL50_FIRST_AMPDU_QUEUE 10
+
+#define IWL_sta_id_POS 12
+#define IWL_sta_id_LEN 4
+#define IWL_sta_id_SYM val
+
+/* Fixed (non-configurable) rx data from phy */
+
+/* Base physical address of iwl5000_shared is provided to SCD_DRAM_BASE_ADDR
+ * and &iwl5000_shared.val0 is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG */
+struct iwl5000_sched_queue_byte_cnt_tbl {
+ struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL50_QUEUE_SIZE +
+ IWL50_MAX_WIN_SIZE];
+} __attribute__ ((packed));
+
+struct iwl5000_shared {
+ struct iwl5000_sched_queue_byte_cnt_tbl
+ queues_byte_cnt_tbls[IWL50_NUM_QUEUES];
+ __le32 rb_closed;
+
+ /* __le32 rb_closed_stts_rb_num:12; */
+#define IWL_rb_closed_stts_rb_num_POS 0
+#define IWL_rb_closed_stts_rb_num_LEN 12
+#define IWL_rb_closed_stts_rb_num_SYM rb_closed
+ /* __le32 rsrv1:4; */
+ /* __le32 rb_closed_stts_rx_frame_num:12; */
+#define IWL_rb_closed_stts_rx_frame_num_POS 16
+#define IWL_rb_closed_stts_rx_frame_num_LEN 12
+#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
+ /* __le32 rsrv2:4; */
+
+ __le32 frm_finished;
+ /* __le32 frame_finished_stts_rb_num:12; */
+#define IWL_frame_finished_stts_rb_num_POS 0
+#define IWL_frame_finished_stts_rb_num_LEN 12
+#define IWL_frame_finished_stts_rb_num_SYM frm_finished
+ /* __le32 rsrv3:4; */
+ /* __le32 frame_finished_stts_rx_frame_num:12; */
+#define IWL_frame_finished_stts_rx_frame_num_POS 16
+#define IWL_frame_finished_stts_rx_frame_num_LEN 12
+#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
+ /* __le32 rsrv4:4; */
+
+ __le32 padding1; /* so that allocation will be aligned to 16B */
+ __le32 padding2;
+} __attribute__ ((packed));
+
+
+#endif /* __iwl_5000_hw_h__ */
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
new file mode 100644
index 00000000000..878d6193b23
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -0,0 +1,1580 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+#define IWL5000_UCODE_API "-1"
+
+static const u16 iwl5000_default_queue_to_tx_fifo[] = {
+ IWL_TX_FIFO_AC3,
+ IWL_TX_FIFO_AC2,
+ IWL_TX_FIFO_AC1,
+ IWL_TX_FIFO_AC0,
+ IWL50_CMD_FIFO_NUM,
+ IWL_TX_FIFO_HCCA_1,
+ IWL_TX_FIFO_HCCA_2
+};
+
+/* FIXME: same implementation as 4965 */
+static int iwl5000_apm_stop_master(struct iwl_priv *priv)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* set stop master bit */
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+
+ ret = iwl_poll_bit(priv, CSR_RESET,
+ CSR_RESET_REG_FLAG_MASTER_DISABLED,
+ CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+ if (ret < 0)
+ goto out;
+
+out:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ IWL_DEBUG_INFO("stop master\n");
+
+ return ret;
+}
+
+
+static int iwl5000_apm_init(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+ /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+
+ /* set "initialization complete" bit to move adapter
+ * D0U* --> D0A* state */
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ /* wait for clock stabilization */
+ ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0) {
+ IWL_DEBUG_INFO("Failed to init the card\n");
+ return ret;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+
+ /* enable DMA */
+ iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+
+ udelay(20);
+
+ /* disable L1-Active */
+ iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+ iwl_release_nic_access(priv);
+
+ return ret;
+}
+
+/* FIXME: this is indentical to 4965 */
+static void iwl5000_apm_stop(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ iwl5000_apm_stop_master(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+ udelay(10);
+
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+
+static int iwl5000_apm_reset(struct iwl_priv *priv)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ iwl5000_apm_stop_master(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+ udelay(10);
+
+
+ /* FIXME: put here L1A -L0S w/a */
+
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+
+ /* set "initialization complete" bit to move adapter
+ * D0U* --> D0A* state */
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ /* wait for clock stabilization */
+ ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0) {
+ IWL_DEBUG_INFO("Failed to init the card\n");
+ goto out;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto out;
+
+ /* enable DMA */
+ iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+
+ udelay(20);
+
+ /* disable L1-Active */
+ iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+ iwl_release_nic_access(priv);
+
+out:
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return ret;
+}
+
+
+static void iwl5000_nic_config(struct iwl_priv *priv)
+{
+ unsigned long flags;
+ u16 radio_cfg;
+ u8 val_link;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link);
+
+ /* L1 is enabled by BIOS */
+ if ((val_link & PCI_LINK_VAL_L1_EN) == PCI_LINK_VAL_L1_EN)
+ /* diable L0S disabled L1A enabled */
+ iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+ else
+ /* L0S enabled L1A disabled */
+ iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+
+ radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
+
+ /* write radio config values to register */
+ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_5000_RF_CFG_TYPE_MAX)
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
+ EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
+ EEPROM_RF_CFG_DASH_MSK(radio_cfg));
+
+ /* set CSR_HW_CONFIG_REG for uCode use */
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
+ CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+
+
+/*
+ * EEPROM
+ */
+static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
+{
+ u16 offset = 0;
+
+ if ((address & INDIRECT_ADDRESS) == 0)
+ return address;
+
+ switch (address & INDIRECT_TYPE_MSK) {
+ case INDIRECT_HOST:
+ offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_HOST);
+ break;
+ case INDIRECT_GENERAL:
+ offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_GENERAL);
+ break;
+ case INDIRECT_REGULATORY:
+ offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_REGULATORY);
+ break;
+ case INDIRECT_CALIBRATION:
+ offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_CALIBRATION);
+ break;
+ case INDIRECT_PROCESS_ADJST:
+ offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_PROCESS_ADJST);
+ break;
+ case INDIRECT_OTHERS:
+ offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
+ break;
+ default:
+ IWL_ERROR("illegal indirect type: 0x%X\n",
+ address & INDIRECT_TYPE_MSK);
+ break;
+ }
+
+ /* translate the offset from words to byte */
+ return (address & ADDRESS_MSK) + (offset << 1);
+}
+
+static int iwl5000_eeprom_check_version(struct iwl_priv *priv)
+{
+ u16 eeprom_ver;
+ struct iwl_eeprom_calib_hdr {
+ u8 version;
+ u8 pa_type;
+ u16 voltage;
+ } *hdr;
+
+ eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+
+ hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
+ EEPROM_5000_CALIB_ALL);
+
+ if (eeprom_ver < EEPROM_5000_EEPROM_VERSION ||
+ hdr->version < EEPROM_5000_TX_POWER_VERSION)
+ goto err;
+
+ return 0;
+err:
+ IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ eeprom_ver, EEPROM_5000_EEPROM_VERSION,
+ hdr->version, EEPROM_5000_TX_POWER_VERSION);
+ return -EINVAL;
+
+}
+
+static void iwl5000_gain_computation(struct iwl_priv *priv,
+ u32 average_noise[NUM_RX_CHAINS],
+ u16 min_average_noise_antenna_i,
+ u32 min_average_noise)
+{
+ int i;
+ s32 delta_g;
+ struct iwl_chain_noise_data *data = &priv->chain_noise_data;
+
+ /* Find Gain Code for the antennas B and C */
+ for (i = 1; i < NUM_RX_CHAINS; i++) {
+ if ((data->disconn_array[i])) {
+ data->delta_gain_code[i] = 0;
+ continue;
+ }
+ delta_g = (1000 * ((s32)average_noise[0] -
+ (s32)average_noise[i])) / 1500;
+ /* bound gain by 2 bits value max, 3rd bit is sign */
+ data->delta_gain_code[i] =
+ min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
+
+ if (delta_g < 0)
+ /* set negative sign */
+ data->delta_gain_code[i] |= (1 << 2);
+ }
+
+ IWL_DEBUG_CALIB("Delta gains: ANT_B = %d ANT_C = %d\n",
+ data->delta_gain_code[1], data->delta_gain_code[2]);
+
+ if (!data->radio_write) {
+ struct iwl5000_calibration_chain_noise_gain_cmd cmd;
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
+ cmd.delta_gain_1 = data->delta_gain_code[1];
+ cmd.delta_gain_2 = data->delta_gain_code[2];
+ iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
+ sizeof(cmd), &cmd, NULL);
+
+ data->radio_write = 1;
+ data->state = IWL_CHAIN_NOISE_CALIBRATED;
+ }
+
+ data->chain_noise_a = 0;
+ data->chain_noise_b = 0;
+ data->chain_noise_c = 0;
+ data->chain_signal_a = 0;
+ data->chain_signal_b = 0;
+ data->chain_signal_c = 0;
+ data->beacon_count = 0;
+}
+
+static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
+{
+ struct iwl_chain_noise_data *data = &priv->chain_noise_data;
+
+ if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
+ struct iwl5000_calibration_chain_noise_reset_cmd cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
+ if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+ sizeof(cmd), &cmd))
+ IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ data->state = IWL_CHAIN_NOISE_ACCUMULATE;
+ IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+ }
+}
+
+static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+ __le32 *tx_flags)
+{
+ if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
+ (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
+ *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
+ else
+ *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
+}
+
+static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
+ .min_nrg_cck = 95,
+ .max_nrg_cck = 0,
+ .auto_corr_min_ofdm = 90,
+ .auto_corr_min_ofdm_mrc = 170,
+ .auto_corr_min_ofdm_x1 = 120,
+ .auto_corr_min_ofdm_mrc_x1 = 240,
+
+ .auto_corr_max_ofdm = 120,
+ .auto_corr_max_ofdm_mrc = 210,
+ .auto_corr_max_ofdm_x1 = 155,
+ .auto_corr_max_ofdm_mrc_x1 = 290,
+
+ .auto_corr_min_cck = 125,
+ .auto_corr_max_cck = 200,
+ .auto_corr_min_cck_mrc = 170,
+ .auto_corr_max_cck_mrc = 400,
+ .nrg_th_cck = 95,
+ .nrg_th_ofdm = 95,
+};
+
+static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
+ size_t offset)
+{
+ u32 address = eeprom_indirect_address(priv, offset);
+ BUG_ON(address >= priv->cfg->eeprom_size);
+ return &priv->eeprom[address];
+}
+
+/*
+ * Calibration
+ */
+static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
+{
+ u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
+
+ struct iwl5000_calibration cal_cmd = {
+ .op_code = IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD,
+ .data = {
+ (u8)xtal_calib[0],
+ (u8)xtal_calib[1],
+ }
+ };
+
+ return iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+ sizeof(cal_cmd), &cal_cmd);
+}
+
+static int iwl5000_send_calib_results(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ struct iwl_host_cmd hcmd = {
+ .id = REPLY_PHY_CALIBRATION_CMD,
+ .meta.flags = CMD_SIZE_HUGE,
+ };
+
+ if (priv->calib_results.lo_res) {
+ hcmd.len = priv->calib_results.lo_res_len;
+ hcmd.data = priv->calib_results.lo_res;
+ ret = iwl_send_cmd_sync(priv, &hcmd);
+
+ if (ret)
+ goto err;
+ }
+
+ if (priv->calib_results.tx_iq_res) {
+ hcmd.len = priv->calib_results.tx_iq_res_len;
+ hcmd.data = priv->calib_results.tx_iq_res;
+ ret = iwl_send_cmd_sync(priv, &hcmd);
+
+ if (ret)
+ goto err;
+ }
+
+ if (priv->calib_results.tx_iq_perd_res) {
+ hcmd.len = priv->calib_results.tx_iq_perd_res_len;
+ hcmd.data = priv->calib_results.tx_iq_perd_res;
+ ret = iwl_send_cmd_sync(priv, &hcmd);
+
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ IWL_ERROR("Error %d\n", ret);
+ return ret;
+}
+
+static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
+{
+ struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
+ struct iwl_host_cmd cmd = {
+ .id = CALIBRATION_CFG_CMD,
+ .len = sizeof(struct iwl5000_calib_cfg_cmd),
+ .data = &calib_cfg_cmd,
+ };
+
+ memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
+ calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL;
+ calib_cfg_cmd.ucd_calib_cfg.once.start = IWL_CALIB_INIT_CFG_ALL;
+ calib_cfg_cmd.ucd_calib_cfg.once.send_res = IWL_CALIB_INIT_CFG_ALL;
+ calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_INIT_CFG_ALL;
+
+ return iwl_send_cmd(priv, &cmd);
+}
+
+static void iwl5000_rx_calib_result(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
+ int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
+
+ iwl_free_calib_results(priv);
+
+ /* reduce the size of the length field itself */
+ len -= 4;
+
+ switch (hdr->op_code) {
+ case IWL5000_PHY_CALIBRATE_LO_CMD:
+ priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC);
+ priv->calib_results.lo_res_len = len;
+ memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
+ break;
+ case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
+ priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC);
+ priv->calib_results.tx_iq_res_len = len;
+ memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
+ break;
+ case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
+ priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC);
+ priv->calib_results.tx_iq_perd_res_len = len;
+ memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
+ break;
+ default:
+ IWL_ERROR("Unknown calibration notification %d\n",
+ hdr->op_code);
+ return;
+ }
+}
+
+static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ IWL_DEBUG_INFO("Init. calibration is completed, restarting fw.\n");
+ queue_work(priv->workqueue, &priv->restart);
+}
+
+/*
+ * ucode
+ */
+static int iwl5000_load_section(struct iwl_priv *priv,
+ struct fw_desc *image,
+ u32 dst_addr)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ dma_addr_t phy_addr = image->p_addr;
+ u32 byte_cnt = image->len;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ iwl_write_direct32(priv,
+ FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
+ FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
+
+ iwl_write_direct32(priv,
+ FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
+
+ iwl_write_direct32(priv,
+ FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
+ phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
+
+ /* FIME: write the MSB of the phy_addr in CTRL1
+ * iwl_write_direct32(priv,
+ IWL_FH_TFDIB_CTRL1_REG(IWL_FH_SRVC_CHNL),
+ ((phy_addr & MSB_MSK)
+ << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_count);
+ */
+ iwl_write_direct32(priv,
+ FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), byte_cnt);
+ iwl_write_direct32(priv,
+ FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
+ 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
+ 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
+ FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
+
+ iwl_write_direct32(priv,
+ FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
+ FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
+ FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL |
+ FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return 0;
+}
+
+static int iwl5000_load_given_ucode(struct iwl_priv *priv,
+ struct fw_desc *inst_image,
+ struct fw_desc *data_image)
+{
+ int ret = 0;
+
+ ret = iwl5000_load_section(
+ priv, inst_image, RTC_INST_LOWER_BOUND);
+ if (ret)
+ return ret;
+
+ IWL_DEBUG_INFO("INST uCode section being loaded...\n");
+ ret = wait_event_interruptible_timeout(priv->wait_command_queue,
+ priv->ucode_write_complete, 5 * HZ);
+ if (ret == -ERESTARTSYS) {
+ IWL_ERROR("Could not load the INST uCode section due "
+ "to interrupt\n");
+ return ret;
+ }
+ if (!ret) {
+ IWL_ERROR("Could not load the INST uCode section\n");
+ return -ETIMEDOUT;
+ }
+
+ priv->ucode_write_complete = 0;
+
+ ret = iwl5000_load_section(
+ priv, data_image, RTC_DATA_LOWER_BOUND);
+ if (ret)
+ return ret;
+
+ IWL_DEBUG_INFO("DATA uCode section being loaded...\n");
+
+ ret = wait_event_interruptible_timeout(priv->wait_command_queue,
+ priv->ucode_write_complete, 5 * HZ);
+ if (ret == -ERESTARTSYS) {
+ IWL_ERROR("Could not load the INST uCode section due "
+ "to interrupt\n");
+ return ret;
+ } else if (!ret) {
+ IWL_ERROR("Could not load the DATA uCode section\n");
+ return -ETIMEDOUT;
+ } else
+ ret = 0;
+
+ priv->ucode_write_complete = 0;
+
+ return ret;
+}
+
+static int iwl5000_load_ucode(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ /* check whether init ucode should be loaded, or rather runtime ucode */
+ if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
+ IWL_DEBUG_INFO("Init ucode found. Loading init ucode...\n");
+ ret = iwl5000_load_given_ucode(priv,
+ &priv->ucode_init, &priv->ucode_init_data);
+ if (!ret) {
+ IWL_DEBUG_INFO("Init ucode load complete.\n");
+ priv->ucode_type = UCODE_INIT;
+ }
+ } else {
+ IWL_DEBUG_INFO("Init ucode not found, or already loaded. "
+ "Loading runtime ucode...\n");
+ ret = iwl5000_load_given_ucode(priv,
+ &priv->ucode_code, &priv->ucode_data);
+ if (!ret) {
+ IWL_DEBUG_INFO("Runtime ucode load complete.\n");
+ priv->ucode_type = UCODE_RT;
+ }
+ }
+
+ return ret;
+}
+
+static void iwl5000_init_alive_start(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ /* Check alive response for "valid" sign from uCode */
+ if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
+ /* We had an error bringing up the hardware, so take it
+ * all the way back down so we can try again */
+ IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ goto restart;
+ }
+
+ /* initialize uCode was loaded... verify inst image.
+ * This is a paranoid check, because we would not have gotten the
+ * "initialize" alive if code weren't properly loaded. */
+ if (iwl_verify_ucode(priv)) {
+ /* Runtime instruction load was bad;
+ * take it all the way back down so we can try again */
+ IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ goto restart;
+ }
+
+ iwl_clear_stations_table(priv);
+ ret = priv->cfg->ops->lib->alive_notify(priv);
+ if (ret) {
+ IWL_WARNING("Could not complete ALIVE transition: %d\n", ret);
+ goto restart;
+ }
+
+ iwl5000_send_calib_cfg(priv);
+ return;
+
+restart:
+ /* real restart (first load init_ucode) */
+ queue_work(priv->workqueue, &priv->restart);
+}
+
+static void iwl5000_set_wr_ptrs(struct iwl_priv *priv,
+ int txq_id, u32 index)
+{
+ iwl_write_direct32(priv, HBUS_TARG_WRPTR,
+ (index & 0xff) | (txq_id << 8));
+ iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(txq_id), index);
+}
+
+static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ int tx_fifo_id, int scd_retry)
+{
+ int txq_id = txq->q.id;
+ int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0;
+
+ iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
+ (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
+ (tx_fifo_id << IWL50_SCD_QUEUE_STTS_REG_POS_TXF) |
+ (1 << IWL50_SCD_QUEUE_STTS_REG_POS_WSL) |
+ IWL50_SCD_QUEUE_STTS_REG_MSK);
+
+ txq->sched_retry = scd_retry;
+
+ IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+ active ? "Activate" : "Deactivate",
+ scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
+}
+
+static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
+{
+ struct iwl_wimax_coex_cmd coex_cmd;
+
+ memset(&coex_cmd, 0, sizeof(coex_cmd));
+
+ return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
+ sizeof(coex_cmd), &coex_cmd);
+}
+
+static int iwl5000_alive_notify(struct iwl_priv *priv)
+{
+ u32 a;
+ int i = 0;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
+ a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
+ for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
+ a += 4)
+ iwl_write_targ_mem(priv, a, 0);
+ for (; a < priv->scd_base_addr + IWL50_SCD_TRANSLATE_TBL_OFFSET;
+ a += 4)
+ iwl_write_targ_mem(priv, a, 0);
+ for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
+ iwl_write_targ_mem(priv, a, 0);
+
+ iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
+ (priv->shared_phys +
+ offsetof(struct iwl5000_shared, queues_byte_cnt_tbls)) >> 10);
+ iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
+ IWL50_SCD_QUEUECHAIN_SEL_ALL(
+ priv->hw_params.max_txq_num));
+ iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
+
+ /* initiate the queues */
+ for (i = 0; i < priv->hw_params.max_txq_num; i++) {
+ iwl_write_prph(priv, IWL50_SCD_QUEUE_RDPTR(i), 0);
+ iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
+ iwl_write_targ_mem(priv, priv->scd_base_addr +
+ IWL50_SCD_CONTEXT_QUEUE_OFFSET(i), 0);
+ iwl_write_targ_mem(priv, priv->scd_base_addr +
+ IWL50_SCD_CONTEXT_QUEUE_OFFSET(i) +
+ sizeof(u32),
+ ((SCD_WIN_SIZE <<
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+ ((SCD_FRAME_LIMIT <<
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+ }
+
+ iwl_write_prph(priv, IWL50_SCD_INTERRUPT_MASK,
+ IWL_MASK(0, priv->hw_params.max_txq_num));
+
+ /* Activate all Tx DMA/FIFO channels */
+ priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
+
+ iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
+ /* map qos queues to fifos one-to-one */
+ for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
+ int ac = iwl5000_default_queue_to_tx_fifo[i];
+ iwl_txq_ctx_activate(priv, i);
+ iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
+ }
+ /* TODO - need to initialize those FIFOs inside the loop above,
+ * not only mark them as active */
+ iwl_txq_ctx_activate(priv, 4);
+ iwl_txq_ctx_activate(priv, 7);
+ iwl_txq_ctx_activate(priv, 8);
+ iwl_txq_ctx_activate(priv, 9);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+
+ iwl5000_send_wimax_coex(priv);
+
+ iwl5000_send_Xtal_calib(priv);
+
+ if (priv->ucode_type == UCODE_RT)
+ iwl5000_send_calib_results(priv);
+
+ return 0;
+}
+
+static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
+{
+ if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
+ (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
+ IWL_ERROR("invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
+ return -EINVAL;
+ }
+
+ priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+ priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE;
+ priv->hw_params.max_stations = IWL5000_STATION_COUNT;
+ priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
+ priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
+ priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+ priv->hw_params.max_bsm_size = 0;
+ priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
+ BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.sens = &iwl5000_sensitivity;
+
+ switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ case CSR_HW_REV_TYPE_5100:
+ case CSR_HW_REV_TYPE_5150:
+ priv->hw_params.tx_chains_num = 1;
+ priv->hw_params.rx_chains_num = 2;
+ /* FIXME: move to ANT_A, ANT_B, ANT_C enum */
+ priv->hw_params.valid_tx_ant = ANT_A;
+ priv->hw_params.valid_rx_ant = ANT_AB;
+ break;
+ case CSR_HW_REV_TYPE_5300:
+ case CSR_HW_REV_TYPE_5350:
+ priv->hw_params.tx_chains_num = 3;
+ priv->hw_params.rx_chains_num = 3;
+ priv->hw_params.valid_tx_ant = ANT_ABC;
+ priv->hw_params.valid_rx_ant = ANT_ABC;
+ break;
+ }
+
+ switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ case CSR_HW_REV_TYPE_5100:
+ case CSR_HW_REV_TYPE_5300:
+ /* 5X00 wants in Celsius */
+ priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
+ break;
+ case CSR_HW_REV_TYPE_5150:
+ case CSR_HW_REV_TYPE_5350:
+ /* 5X50 wants in Kelvin */
+ priv->hw_params.ct_kill_threshold =
+ CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
+ break;
+ }
+
+ return 0;
+}
+
+static int iwl5000_alloc_shared_mem(struct iwl_priv *priv)
+{
+ priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
+ sizeof(struct iwl5000_shared),
+ &priv->shared_phys);
+ if (!priv->shared_virt)
+ return -ENOMEM;
+
+ memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared));
+
+ priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed);
+
+ return 0;
+}
+
+static void iwl5000_free_shared_mem(struct iwl_priv *priv)
+{
+ if (priv->shared_virt)
+ pci_free_consistent(priv->pci_dev,
+ sizeof(struct iwl5000_shared),
+ priv->shared_virt,
+ priv->shared_phys);
+}
+
+static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv)
+{
+ struct iwl5000_shared *s = priv->shared_virt;
+ return le32_to_cpu(s->rb_closed) & 0xFFF;
+}
+
+/**
+ * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
+ */
+static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ u16 byte_cnt)
+{
+ struct iwl5000_shared *shared_data = priv->shared_virt;
+ int txq_id = txq->q.id;
+ u8 sec_ctl = 0;
+ u8 sta = 0;
+ int len;
+
+ len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
+
+ if (txq_id != IWL_CMD_QUEUE_NUM) {
+ sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id;
+ sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl;
+
+ switch (sec_ctl & TX_CMD_SEC_MSK) {
+ case TX_CMD_SEC_CCM:
+ len += CCMP_MIC_LEN;
+ break;
+ case TX_CMD_SEC_TKIP:
+ len += TKIP_ICV_LEN;
+ break;
+ case TX_CMD_SEC_WEP:
+ len += WEP_IV_LEN + WEP_ICV_LEN;
+ break;
+ }
+ }
+
+ IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
+ tfd_offset[txq->q.write_ptr], byte_cnt, len);
+
+ IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
+ tfd_offset[txq->q.write_ptr], sta_id, sta);
+
+ if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) {
+ IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
+ tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr],
+ byte_cnt, len);
+ IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
+ tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr],
+ sta_id, sta);
+ }
+}
+
+static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
+{
+ int txq_id = txq->q.id;
+ struct iwl5000_shared *shared_data = priv->shared_virt;
+ u8 sta = 0;
+
+ if (txq_id != IWL_CMD_QUEUE_NUM)
+ sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id;
+
+ shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
+ val = cpu_to_le16(1 | (sta << 12));
+
+ if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) {
+ shared_data->queues_byte_cnt_tbls[txq_id].
+ tfd_offset[IWL50_QUEUE_SIZE + txq->q.read_ptr].
+ val = cpu_to_le16(1 | (sta << 12));
+ }
+}
+
+static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
+ u16 txq_id)
+{
+ u32 tbl_dw_addr;
+ u32 tbl_dw;
+ u16 scd_q2ratid;
+
+ scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
+
+ tbl_dw_addr = priv->scd_base_addr +
+ IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
+
+ tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
+
+ if (txq_id & 0x1)
+ tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
+ else
+ tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
+
+ iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
+
+ return 0;
+}
+static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
+{
+ /* Simply stop the queue, but don't change any configuration;
+ * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
+ iwl_write_prph(priv,
+ IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
+ (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
+ (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+}
+
+static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
+ int tx_fifo, int sta_id, int tid, u16 ssn_idx)
+{
+ unsigned long flags;
+ int ret;
+ u16 ra_tid;
+
+ if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
+ (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
+ IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ txq_id, IWL50_FIRST_AMPDU_QUEUE,
+ IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
+ return -EINVAL;
+ }
+
+ ra_tid = BUILD_RAxTID(sta_id, tid);
+
+ /* Modify device's station table to Tx this TID */
+ iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Stop this Tx queue before configuring it */
+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);
+
+ /* Map receiver-address / traffic-ID to this queue */
+ iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
+
+ /* Set this queue as a chain-building queue */
+ iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
+
+ /* enable aggregations for the queue */
+ iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
+
+ /* Place first TFD at index corresponding to start sequence number.
+ * Assumes that ssn_idx is valid (!= 0xFFF) */
+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+ /* Set up Tx window size and frame limit for this queue */
+ iwl_write_targ_mem(priv, priv->scd_base_addr +
+ IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
+ sizeof(u32),
+ ((SCD_WIN_SIZE <<
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+ ((SCD_FRAME_LIMIT <<
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+
+ iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+
+ /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+ u16 ssn_idx, u8 tx_fifo)
+{
+ int ret;
+
+ if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
+ (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
+ IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ txq_id, IWL50_FIRST_AMPDU_QUEUE,
+ IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
+ return -EINVAL;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+
+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);
+
+ iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
+
+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+ /* supposes that ssn_idx is valid (!= 0xFFF) */
+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+ iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+ iwl_txq_ctx_deactivate(priv, txq_id);
+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
+
+ iwl_release_nic_access(priv);
+
+ return 0;
+}
+
+static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+{
+ u16 size = (u16)sizeof(struct iwl_addsta_cmd);
+ memcpy(data, cmd, size);
+ return size;
+}
+
+
+/*
+ * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
+ * must be called under priv->lock and mac access
+ */
+static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
+{
+ iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
+}
+
+
+static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
+{
+ return le32_to_cpup((__le32*)&tx_resp->status +
+ tx_resp->frame_count) & MAX_SN;
+}
+
+static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
+ struct iwl_ht_agg *agg,
+ struct iwl5000_tx_resp *tx_resp,
+ int txq_id, u16 start_idx)
+{
+ u16 status;
+ struct agg_tx_status *frame_status = &tx_resp->status;
+ struct ieee80211_tx_info *info = NULL;
+ struct ieee80211_hdr *hdr = NULL;
+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
+ int i, sh, idx;
+ u16 seq;
+
+ if (agg->wait_for_ba)
+ IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+
+ agg->frame_count = tx_resp->frame_count;
+ agg->start_idx = start_idx;
+ agg->rate_n_flags = rate_n_flags;
+ agg->bitmap = 0;
+
+ /* # frames attempted by Tx command */
+ if (agg->frame_count == 1) {
+ /* Only one frame was attempted; no block-ack will arrive */
+ status = le16_to_cpu(frame_status[0].status);
+ idx = start_idx;
+
+ /* FIXME: code repetition */
+ IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ agg->frame_count, agg->start_idx, idx);
+
+ info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
+ info->status.retry_count = tx_resp->failure_frame;
+ info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+ info->flags |= iwl_is_tx_success(status)?
+ IEEE80211_TX_STAT_ACK : 0;
+ iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
+
+ /* FIXME: code repetition end */
+
+ IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+ status & 0xff, tx_resp->failure_frame);
+ IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+
+ agg->wait_for_ba = 0;
+ } else {
+ /* Two or more frames were attempted; expect block-ack */
+ u64 bitmap = 0;
+ int start = agg->start_idx;
+
+ /* Construct bit-map of pending frames within Tx window */
+ for (i = 0; i < agg->frame_count; i++) {
+ u16 sc;
+ status = le16_to_cpu(frame_status[i].status);
+ seq = le16_to_cpu(frame_status[i].sequence);
+ idx = SEQ_TO_INDEX(seq);
+ txq_id = SEQ_TO_QUEUE(seq);
+
+ if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
+ AGG_TX_STATE_ABORT_MSK))
+ continue;
+
+ IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ agg->frame_count, txq_id, idx);
+
+ hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
+
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ if (idx != (SEQ_TO_SN(sc) & 0xff)) {
+ IWL_ERROR("BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
+ idx, SEQ_TO_SN(sc),
+ hdr->seq_ctrl);
+ return -1;
+ }
+
+ IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+ i, idx, SEQ_TO_SN(sc));
+
+ sh = idx - start;
+ if (sh > 64) {
+ sh = (start - idx) + 0xff;
+ bitmap = bitmap << sh;
+ sh = 0;
+ start = idx;
+ } else if (sh < -64)
+ sh = 0xff - (start - idx);
+ else if (sh < 0) {
+ sh = start - idx;
+ start = idx;
+ bitmap = bitmap << sh;
+ sh = 0;
+ }
+ bitmap |= (1 << sh);
+ IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
+ start, (u32)(bitmap & 0xFFFFFFFF));
+ }
+
+ agg->bitmap = bitmap;
+ agg->start_idx = start;
+ IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ agg->frame_count, agg->start_idx,
+ (unsigned long long)agg->bitmap);
+
+ if (bitmap)
+ agg->wait_for_ba = 1;
+ }
+ return 0;
+}
+
+static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ u16 sequence = le16_to_cpu(pkt->hdr.sequence);
+ int txq_id = SEQ_TO_QUEUE(sequence);
+ int index = SEQ_TO_INDEX(sequence);
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct ieee80211_tx_info *info;
+ struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+ u32 status = le16_to_cpu(tx_resp->status.status);
+ int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
+ struct ieee80211_hdr *hdr;
+ u8 *qc = NULL;
+
+ if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+ IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ "is out of range [0-%d] %d %d\n", txq_id,
+ index, txq->q.n_bd, txq->q.write_ptr,
+ txq->q.read_ptr);
+ return;
+ }
+
+ info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
+ memset(&info->status, 0, sizeof(info->status));
+
+ hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ }
+
+ sta_id = iwl_get_ra_sta_id(priv, hdr);
+ if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
+ IWL_ERROR("Station not known\n");
+ return;
+ }
+
+ if (txq->sched_retry) {
+ const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp);
+ struct iwl_ht_agg *agg = NULL;
+
+ if (!qc)
+ return;
+
+ agg = &priv->stations[sta_id].tid[tid].agg;
+
+ iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
+
+ /* check if BAR is needed */
+ if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
+ info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+ if (txq->q.read_ptr != (scd_ssn & 0xff)) {
+ int freed, ampdu_q;
+ index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
+ IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
+ "%d index %d\n", scd_ssn , index);
+ freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ txq_id >= 0 && priv->mac80211_registered &&
+ agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
+ /* calculate mac80211 ampdu sw queue to wake */
+ ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE +
+ priv->hw->queues;
+ if (agg->state == IWL_AGG_OFF)
+ ieee80211_wake_queue(priv->hw, txq_id);
+ else
+ ieee80211_wake_queue(priv->hw, ampdu_q);
+ }
+ iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+ }
+ } else {
+ info->status.retry_count = tx_resp->failure_frame;
+ info->flags =
+ iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
+ iwl_hwrate_to_tx_control(priv,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+
+ IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
+ "0x%x retries %d\n", txq_id,
+ iwl_get_tx_fail_reason(status),
+ status, le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+
+ IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+ if (index != -1) {
+ int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+ if (tid != MAX_TID_COUNT)
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ (txq_id >= 0) && priv->mac80211_registered)
+ ieee80211_wake_queue(priv->hw, txq_id);
+ if (tid != MAX_TID_COUNT)
+ iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+ }
+ }
+
+ if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
+ IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+}
+
+/* Currently 5000 is the supperset of everything */
+static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
+{
+ return len;
+}
+
+static void iwl5000_setup_deferred_work(struct iwl_priv *priv)
+{
+ /* in 5000 the tx power calibration is done in uCode */
+ priv->disable_tx_power_cal = 1;
+}
+
+static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
+{
+ /* init calibration handlers */
+ priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
+ iwl5000_rx_calib_result;
+ priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
+ iwl5000_rx_calib_complete;
+ priv->rx_handlers[REPLY_TX] = iwl5000_rx_reply_tx;
+}
+
+
+static int iwl5000_hw_valid_rtc_data_addr(u32 addr)
+{
+ return (addr >= RTC_DATA_LOWER_BOUND) &&
+ (addr < IWL50_RTC_DATA_UPPER_BOUND);
+}
+
+static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
+{
+ int ret = 0;
+ struct iwl5000_rxon_assoc_cmd rxon_assoc;
+ const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+ const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+
+ if ((rxon1->flags == rxon2->flags) &&
+ (rxon1->filter_flags == rxon2->filter_flags) &&
+ (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+ (rxon1->ofdm_ht_single_stream_basic_rates ==
+ rxon2->ofdm_ht_single_stream_basic_rates) &&
+ (rxon1->ofdm_ht_dual_stream_basic_rates ==
+ rxon2->ofdm_ht_dual_stream_basic_rates) &&
+ (rxon1->ofdm_ht_triple_stream_basic_rates ==
+ rxon2->ofdm_ht_triple_stream_basic_rates) &&
+ (rxon1->acquisition_data == rxon2->acquisition_data) &&
+ (rxon1->rx_chain == rxon2->rx_chain) &&
+ (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+ IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
+ return 0;
+ }
+
+ rxon_assoc.flags = priv->staging_rxon.flags;
+ rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
+ rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+ rxon_assoc.reserved1 = 0;
+ rxon_assoc.reserved2 = 0;
+ rxon_assoc.reserved3 = 0;
+ rxon_assoc.ofdm_ht_single_stream_basic_rates =
+ priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
+ rxon_assoc.ofdm_ht_dual_stream_basic_rates =
+ priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
+ rxon_assoc.ofdm_ht_triple_stream_basic_rates =
+ priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
+ rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
+
+ ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
+ sizeof(rxon_assoc), &rxon_assoc, NULL);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+static int iwl5000_send_tx_power(struct iwl_priv *priv)
+{
+ struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
+
+ /* half dBm need to multiply */
+ tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
+ tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
+ tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
+ return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,
+ sizeof(tx_power_cmd), &tx_power_cmd,
+ NULL);
+}
+
+static void iwl5000_temperature(struct iwl_priv *priv)
+{
+ /* store temperature from statistics (in Celsius) */
+ priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
+}
+
+static struct iwl_hcmd_ops iwl5000_hcmd = {
+ .rxon_assoc = iwl5000_send_rxon_assoc,
+};
+
+static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
+ .get_hcmd_size = iwl5000_get_hcmd_size,
+ .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
+ .gain_computation = iwl5000_gain_computation,
+ .chain_noise_reset = iwl5000_chain_noise_reset,
+ .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
+};
+
+static struct iwl_lib_ops iwl5000_lib = {
+ .set_hw_params = iwl5000_hw_set_hw_params,
+ .alloc_shared_mem = iwl5000_alloc_shared_mem,
+ .free_shared_mem = iwl5000_free_shared_mem,
+ .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx,
+ .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+ .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
+ .txq_set_sched = iwl5000_txq_set_sched,
+ .txq_agg_enable = iwl5000_txq_agg_enable,
+ .txq_agg_disable = iwl5000_txq_agg_disable,
+ .rx_handler_setup = iwl5000_rx_handler_setup,
+ .setup_deferred_work = iwl5000_setup_deferred_work,
+ .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
+ .load_ucode = iwl5000_load_ucode,
+ .init_alive_start = iwl5000_init_alive_start,
+ .alive_notify = iwl5000_alive_notify,
+ .send_tx_power = iwl5000_send_tx_power,
+ .temperature = iwl5000_temperature,
+ .apm_ops = {
+ .init = iwl5000_apm_init,
+ .reset = iwl5000_apm_reset,
+ .stop = iwl5000_apm_stop,
+ .config = iwl5000_nic_config,
+ .set_pwr_src = iwl4965_set_pwr_src,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_5000_REG_BAND_1_CHANNELS,
+ EEPROM_5000_REG_BAND_2_CHANNELS,
+ EEPROM_5000_REG_BAND_3_CHANNELS,
+ EEPROM_5000_REG_BAND_4_CHANNELS,
+ EEPROM_5000_REG_BAND_5_CHANNELS,
+ EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
+ EEPROM_5000_REG_BAND_52_FAT_CHANNELS
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+ .release_semaphore = iwlcore_eeprom_release_semaphore,
+ .check_version = iwl5000_eeprom_check_version,
+ .query_addr = iwl5000_eeprom_query_addr,
+ },
+};
+
+static struct iwl_ops iwl5000_ops = {
+ .lib = &iwl5000_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl5000_hcmd_utils,
+};
+
+static struct iwl_mod_params iwl50_mod_params = {
+ .num_of_queues = IWL50_NUM_QUEUES,
+ .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
+ .enable_qos = 1,
+ .amsdu_size_8K = 1,
+ .restart_fw = 1,
+ /* the rest are 0 by default */
+};
+
+
+struct iwl_cfg iwl5300_agn_cfg = {
+ .name = "5300AGN",
+ .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl5100_bg_cfg = {
+ .name = "5100BG",
+ .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+ .sku = IWL_SKU_G,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl5100_abg_cfg = {
+ .name = "5100ABG",
+ .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+ .sku = IWL_SKU_A|IWL_SKU_G,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl5100_agn_cfg = {
+ .name = "5100AGN",
+ .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .mod_params = &iwl50_mod_params,
+};
+
+struct iwl_cfg iwl5350_agn_cfg = {
+ .name = "5350AGN",
+ .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .mod_params = &iwl50_mod_params,
+};
+
+module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
+MODULE_PARM_DESC(disable50,
+ "manually disable the 50XX radio (default 0 [radio on])");
+module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
+MODULE_PARM_DESC(swcrypto50,
+ "using software crypto engine (default 0 [hardware])\n");
+module_param_named(debug50, iwl50_mod_params.debug, int, 0444);
+MODULE_PARM_DESC(debug50, "50XX debug output mask");
+module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
+MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
+module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444);
+MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality");
+module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
+MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality");
+module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444);
+MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series");
+module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
new file mode 100644
index 00000000000..ef49440bd7f
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -0,0 +1,802 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * 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.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *****************************************************************************/
+
+#include <net/mac80211.h>
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-calib.h"
+
+/* "false alarms" are signals that our DSP tries to lock onto,
+ * but then determines that they are either noise, or transmissions
+ * from a distant wireless network (also "noise", really) that get
+ * "stepped on" by stronger transmissions within our own network.
+ * This algorithm attempts to set a sensitivity level that is high
+ * enough to receive all of our own network traffic, but not so
+ * high that our DSP gets too busy trying to lock onto non-network
+ * activity/noise. */
+static int iwl_sens_energy_cck(struct iwl_priv *priv,
+ u32 norm_fa,
+ u32 rx_enable_time,
+ struct statistics_general_data *rx_info)
+{
+ u32 max_nrg_cck = 0;
+ int i = 0;
+ u8 max_silence_rssi = 0;
+ u32 silence_ref = 0;
+ u8 silence_rssi_a = 0;
+ u8 silence_rssi_b = 0;
+ u8 silence_rssi_c = 0;
+ u32 val;
+
+ /* "false_alarms" values below are cross-multiplications to assess the
+ * numbers of false alarms within the measured period of actual Rx
+ * (Rx is off when we're txing), vs the min/max expected false alarms
+ * (some should be expected if rx is sensitive enough) in a
+ * hypothetical listening period of 200 time units (TU), 204.8 msec:
+ *
+ * MIN_FA/fixed-time < false_alarms/actual-rx-time < MAX_FA/beacon-time
+ *
+ * */
+ u32 false_alarms = norm_fa * 200 * 1024;
+ u32 max_false_alarms = MAX_FA_CCK * rx_enable_time;
+ u32 min_false_alarms = MIN_FA_CCK * rx_enable_time;
+ struct iwl_sensitivity_data *data = NULL;
+ const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
+
+ data = &(priv->sensitivity_data);
+
+ data->nrg_auto_corr_silence_diff = 0;
+
+ /* Find max silence rssi among all 3 receivers.
+ * This is background noise, which may include transmissions from other
+ * networks, measured during silence before our network's beacon */
+ silence_rssi_a = (u8)((rx_info->beacon_silence_rssi_a &
+ ALL_BAND_FILTER) >> 8);
+ silence_rssi_b = (u8)((rx_info->beacon_silence_rssi_b &
+ ALL_BAND_FILTER) >> 8);
+ silence_rssi_c = (u8)((rx_info->beacon_silence_rssi_c &
+ ALL_BAND_FILTER) >> 8);
+
+ val = max(silence_rssi_b, silence_rssi_c);
+ max_silence_rssi = max(silence_rssi_a, (u8) val);
+
+ /* Store silence rssi in 20-beacon history table */
+ data->nrg_silence_rssi[data->nrg_silence_idx] = max_silence_rssi;
+ data->nrg_silence_idx++;
+ if (data->nrg_silence_idx >= NRG_NUM_PREV_STAT_L)
+ data->nrg_silence_idx = 0;
+
+ /* Find max silence rssi across 20 beacon history */
+ for (i = 0; i < NRG_NUM_PREV_STAT_L; i++) {
+ val = data->nrg_silence_rssi[i];
+ silence_ref = max(silence_ref, val);
+ }
+ IWL_DEBUG_CALIB("silence a %u, b %u, c %u, 20-bcn max %u\n",
+ silence_rssi_a, silence_rssi_b, silence_rssi_c,
+ silence_ref);
+
+ /* Find max rx energy (min value!) among all 3 receivers,
+ * measured during beacon frame.
+ * Save it in 10-beacon history table. */
+ i = data->nrg_energy_idx;
+ val = min(rx_info->beacon_energy_b, rx_info->beacon_energy_c);
+ data->nrg_value[i] = min(rx_info->beacon_energy_a, val);
+
+ data->nrg_energy_idx++;
+ if (data->nrg_energy_idx >= 10)
+ data->nrg_energy_idx = 0;
+
+ /* Find min rx energy (max value) across 10 beacon history.
+ * This is the minimum signal level that we want to receive well.
+ * Add backoff (margin so we don't miss slightly lower energy frames).
+ * This establishes an upper bound (min value) for energy threshold. */
+ max_nrg_cck = data->nrg_value[0];
+ for (i = 1; i < 10; i++)
+ max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i]));
+ max_nrg_cck += 6;
+
+ IWL_DEBUG_CALIB("rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
+ rx_info->beacon_energy_a, rx_info->beacon_energy_b,
+ rx_info->beacon_energy_c, max_nrg_cck - 6);
+
+ /* Count number of consecutive beacons with fewer-than-desired
+ * false alarms. */
+ if (false_alarms < min_false_alarms)
+ data->num_in_cck_no_fa++;
+ else
+ data->num_in_cck_no_fa = 0;
+ IWL_DEBUG_CALIB("consecutive bcns with few false alarms = %u\n",
+ data->num_in_cck_no_fa);
+
+ /* If we got too many false alarms this time, reduce sensitivity */
+ if ((false_alarms > max_false_alarms) &&
+ (data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK)) {
+ IWL_DEBUG_CALIB("norm FA %u > max FA %u\n",
+ false_alarms, max_false_alarms);
+ IWL_DEBUG_CALIB("... reducing sensitivity\n");
+ data->nrg_curr_state = IWL_FA_TOO_MANY;
+ /* Store for "fewer than desired" on later beacon */
+ data->nrg_silence_ref = silence_ref;
+
+ /* increase energy threshold (reduce nrg value)
+ * to decrease sensitivity */
+ if (data->nrg_th_cck >
+ (ranges->max_nrg_cck + NRG_STEP_CCK))
+ data->nrg_th_cck = data->nrg_th_cck
+ - NRG_STEP_CCK;
+ else
+ data->nrg_th_cck = ranges->max_nrg_cck;
+ /* Else if we got fewer than desired, increase sensitivity */
+ } else if (false_alarms < min_false_alarms) {
+ data->nrg_curr_state = IWL_FA_TOO_FEW;
+
+ /* Compare silence level with silence level for most recent
+ * healthy number or too many false alarms */
+ data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref -
+ (s32)silence_ref;
+
+ IWL_DEBUG_CALIB("norm FA %u < min FA %u, silence diff %d\n",
+ false_alarms, min_false_alarms,
+ data->nrg_auto_corr_silence_diff);
+
+ /* Increase value to increase sensitivity, but only if:
+ * 1a) previous beacon did *not* have *too many* false alarms
+ * 1b) AND there's a significant difference in Rx levels
+ * from a previous beacon with too many, or healthy # FAs
+ * OR 2) We've seen a lot of beacons (100) with too few
+ * false alarms */
+ if ((data->nrg_prev_state != IWL_FA_TOO_MANY) &&
+ ((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
+ (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
+
+ IWL_DEBUG_CALIB("... increasing sensitivity\n");
+ /* Increase nrg value to increase sensitivity */
+ val = data->nrg_th_cck + NRG_STEP_CCK;
+ data->nrg_th_cck = min((u32)ranges->min_nrg_cck, val);
+ } else {
+ IWL_DEBUG_CALIB("... but not changing sensitivity\n");
+ }
+
+ /* Else we got a healthy number of false alarms, keep status quo */
+ } else {
+ IWL_DEBUG_CALIB(" FA in safe zone\n");
+ data->nrg_curr_state = IWL_FA_GOOD_RANGE;
+
+ /* Store for use in "fewer than desired" with later beacon */
+ data->nrg_silence_ref = silence_ref;
+
+ /* If previous beacon had too many false alarms,
+ * give it some extra margin by reducing sensitivity again
+ * (but don't go below measured energy of desired Rx) */
+ if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
+ IWL_DEBUG_CALIB("... increasing margin\n");
+ if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN))
+ data->nrg_th_cck -= NRG_MARGIN;
+ else
+ data->nrg_th_cck = max_nrg_cck;
+ }
+ }
+
+ /* Make sure the energy threshold does not go above the measured
+ * energy of the desired Rx signals (reduced by backoff margin),
+ * or else we might start missing Rx frames.
+ * Lower value is higher energy, so we use max()!
+ */
+ data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck);
+ IWL_DEBUG_CALIB("new nrg_th_cck %u\n", data->nrg_th_cck);
+
+ data->nrg_prev_state = data->nrg_curr_state;
+
+ /* Auto-correlation CCK algorithm */
+ if (false_alarms > min_false_alarms) {
+
+ /* increase auto_corr values to decrease sensitivity
+ * so the DSP won't be disturbed by the noise
+ */
+ if (data->auto_corr_cck < AUTO_CORR_MAX_TH_CCK)
+ data->auto_corr_cck = AUTO_CORR_MAX_TH_CCK + 1;
+ else {
+ val = data->auto_corr_cck + AUTO_CORR_STEP_CCK;
+ data->auto_corr_cck =
+ min((u32)ranges->auto_corr_max_cck, val);
+ }
+ val = data->auto_corr_cck_mrc + AUTO_CORR_STEP_CCK;
+ data->auto_corr_cck_mrc =
+ min((u32)ranges->auto_corr_max_cck_mrc, val);
+ } else if ((false_alarms < min_false_alarms) &&
+ ((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
+ (data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
+
+ /* Decrease auto_corr values to increase sensitivity */
+ val = data->auto_corr_cck - AUTO_CORR_STEP_CCK;
+ data->auto_corr_cck =
+ max((u32)ranges->auto_corr_min_cck, val);
+ val = data->auto_corr_cck_mrc - AUTO_CORR_STEP_CCK;
+ data->auto_corr_cck_mrc =
+ max((u32)ranges->auto_corr_min_cck_mrc, val);
+ }
+
+ return 0;
+}
+
+
+static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
+ u32 norm_fa,
+ u32 rx_enable_time)
+{
+ u32 val;
+ u32 false_alarms = norm_fa * 200 * 1024;
+ u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time;
+ u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time;
+ struct iwl_sensitivity_data *data = NULL;
+ const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
+
+ data = &(priv->sensitivity_data);
+
+ /* If we got too many false alarms this time, reduce sensitivity */
+ if (false_alarms > max_false_alarms) {
+
+ IWL_DEBUG_CALIB("norm FA %u > max FA %u)\n",
+ false_alarms, max_false_alarms);
+
+ val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm =
+ min((u32)ranges->auto_corr_max_ofdm, val);
+
+ val = data->auto_corr_ofdm_mrc + AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm_mrc =
+ min((u32)ranges->auto_corr_max_ofdm_mrc, val);
+
+ val = data->auto_corr_ofdm_x1 + AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm_x1 =
+ min((u32)ranges->auto_corr_max_ofdm_x1, val);
+
+ val = data->auto_corr_ofdm_mrc_x1 + AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm_mrc_x1 =
+ min((u32)ranges->auto_corr_max_ofdm_mrc_x1, val);
+ }
+
+ /* Else if we got fewer than desired, increase sensitivity */
+ else if (false_alarms < min_false_alarms) {
+
+ IWL_DEBUG_CALIB("norm FA %u < min FA %u\n",
+ false_alarms, min_false_alarms);
+
+ val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm =
+ max((u32)ranges->auto_corr_min_ofdm, val);
+
+ val = data->auto_corr_ofdm_mrc - AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm_mrc =
+ max((u32)ranges->auto_corr_min_ofdm_mrc, val);
+
+ val = data->auto_corr_ofdm_x1 - AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm_x1 =
+ max((u32)ranges->auto_corr_min_ofdm_x1, val);
+
+ val = data->auto_corr_ofdm_mrc_x1 - AUTO_CORR_STEP_OFDM;
+ data->auto_corr_ofdm_mrc_x1 =
+ max((u32)ranges->auto_corr_min_ofdm_mrc_x1, val);
+ } else {
+ IWL_DEBUG_CALIB("min FA %u < norm FA %u < max FA %u OK\n",
+ min_false_alarms, false_alarms, max_false_alarms);
+ }
+ return 0;
+}
+
+/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
+static int iwl_sensitivity_write(struct iwl_priv *priv)
+{
+ int ret = 0;
+ struct iwl_sensitivity_cmd cmd ;
+ struct iwl_sensitivity_data *data = NULL;
+ struct iwl_host_cmd cmd_out = {
+ .id = SENSITIVITY_CMD,
+ .len = sizeof(struct iwl_sensitivity_cmd),
+ .meta.flags = CMD_ASYNC,
+ .data = &cmd,
+ };
+
+ data = &(priv->sensitivity_data);
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
+ cpu_to_le16((u16)data->auto_corr_ofdm);
+ cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
+ cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
+ cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
+ cpu_to_le16((u16)data->auto_corr_ofdm_x1);
+ cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
+ cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
+
+ cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
+ cpu_to_le16((u16)data->auto_corr_cck);
+ cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
+ cpu_to_le16((u16)data->auto_corr_cck_mrc);
+
+ cmd.table[HD_MIN_ENERGY_CCK_DET_INDEX] =
+ cpu_to_le16((u16)data->nrg_th_cck);
+ cmd.table[HD_MIN_ENERGY_OFDM_DET_INDEX] =
+ cpu_to_le16((u16)data->nrg_th_ofdm);
+
+ cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
+ __constant_cpu_to_le16(190);
+ cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
+ __constant_cpu_to_le16(390);
+ cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
+ __constant_cpu_to_le16(62);
+
+ IWL_DEBUG_CALIB("ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
+ data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
+ data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
+ data->nrg_th_ofdm);
+
+ IWL_DEBUG_CALIB("cck: ac %u mrc %u thresh %u\n",
+ data->auto_corr_cck, data->auto_corr_cck_mrc,
+ data->nrg_th_cck);
+
+ /* Update uCode's "work" table, and copy it to DSP */
+ cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
+
+ /* Don't send command to uCode if nothing has changed */
+ if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
+ sizeof(u16)*HD_TABLE_SIZE)) {
+ IWL_DEBUG_CALIB("No change in SENSITIVITY_CMD\n");
+ return 0;
+ }
+
+ /* Copy table for comparison next time */
+ memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
+ sizeof(u16)*HD_TABLE_SIZE);
+
+ ret = iwl_send_cmd(priv, &cmd_out);
+ if (ret)
+ IWL_ERROR("SENSITIVITY_CMD failed\n");
+
+ return ret;
+}
+
+void iwl_init_sensitivity(struct iwl_priv *priv)
+{
+ int ret = 0;
+ int i;
+ struct iwl_sensitivity_data *data = NULL;
+ const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens;
+
+ if (priv->disable_sens_cal)
+ return;
+
+ IWL_DEBUG_CALIB("Start iwl_init_sensitivity\n");
+
+ /* Clear driver's sensitivity algo data */
+ data = &(priv->sensitivity_data);
+
+ if (ranges == NULL)
+ return;
+
+ memset(data, 0, sizeof(struct iwl_sensitivity_data));
+
+ data->num_in_cck_no_fa = 0;
+ data->nrg_curr_state = IWL_FA_TOO_MANY;
+ data->nrg_prev_state = IWL_FA_TOO_MANY;
+ data->nrg_silence_ref = 0;
+ data->nrg_silence_idx = 0;
+ data->nrg_energy_idx = 0;
+
+ for (i = 0; i < 10; i++)
+ data->nrg_value[i] = 0;
+
+ for (i = 0; i < NRG_NUM_PREV_STAT_L; i++)
+ data->nrg_silence_rssi[i] = 0;
+
+ data->auto_corr_ofdm = 90;
+ data->auto_corr_ofdm_mrc = ranges->auto_corr_min_ofdm_mrc;
+ data->auto_corr_ofdm_x1 = ranges->auto_corr_min_ofdm_x1;
+ data->auto_corr_ofdm_mrc_x1 = ranges->auto_corr_min_ofdm_mrc_x1;
+ data->auto_corr_cck = AUTO_CORR_CCK_MIN_VAL_DEF;
+ data->auto_corr_cck_mrc = ranges->auto_corr_min_cck_mrc;
+ data->nrg_th_cck = ranges->nrg_th_cck;
+ data->nrg_th_ofdm = ranges->nrg_th_ofdm;
+
+ data->last_bad_plcp_cnt_ofdm = 0;
+ data->last_fa_cnt_ofdm = 0;
+ data->last_bad_plcp_cnt_cck = 0;
+ data->last_fa_cnt_cck = 0;
+
+ ret |= iwl_sensitivity_write(priv);
+ IWL_DEBUG_CALIB("<<return 0x%X\n", ret);
+}
+EXPORT_SYMBOL(iwl_init_sensitivity);
+
+void iwl_sensitivity_calibration(struct iwl_priv *priv,
+ struct iwl_notif_statistics *resp)
+{
+ u32 rx_enable_time;
+ u32 fa_cck;
+ u32 fa_ofdm;
+ u32 bad_plcp_cck;
+ u32 bad_plcp_ofdm;
+ u32 norm_fa_ofdm;
+ u32 norm_fa_cck;
+ struct iwl_sensitivity_data *data = NULL;
+ struct statistics_rx_non_phy *rx_info = &(resp->rx.general);
+ struct statistics_rx *statistics = &(resp->rx);
+ unsigned long flags;
+ struct statistics_general_data statis;
+
+ if (priv->disable_sens_cal)
+ return;
+
+ data = &(priv->sensitivity_data);
+
+ if (!iwl_is_associated(priv)) {
+ IWL_DEBUG_CALIB("<< - not associated\n");
+ return;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
+ IWL_DEBUG_CALIB("<< invalid data.\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
+ }
+
+ /* Extract Statistics: */
+ rx_enable_time = le32_to_cpu(rx_info->channel_load);
+ fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt);
+ fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt);
+ bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err);
+ bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err);
+
+ statis.beacon_silence_rssi_a =
+ le32_to_cpu(statistics->general.beacon_silence_rssi_a);
+ statis.beacon_silence_rssi_b =
+ le32_to_cpu(statistics->general.beacon_silence_rssi_b);
+ statis.beacon_silence_rssi_c =
+ le32_to_cpu(statistics->general.beacon_silence_rssi_c);
+ statis.beacon_energy_a =
+ le32_to_cpu(statistics->general.beacon_energy_a);
+ statis.beacon_energy_b =
+ le32_to_cpu(statistics->general.beacon_energy_b);
+ statis.beacon_energy_c =
+ le32_to_cpu(statistics->general.beacon_energy_c);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ IWL_DEBUG_CALIB("rx_enable_time = %u usecs\n", rx_enable_time);
+
+ if (!rx_enable_time) {
+ IWL_DEBUG_CALIB("<< RX Enable Time == 0! \n");
+ return;
+ }
+
+ /* These statistics increase monotonically, and do not reset
+ * at each beacon. Calculate difference from last value, or just
+ * use the new statistics value if it has reset or wrapped around. */
+ if (data->last_bad_plcp_cnt_cck > bad_plcp_cck)
+ data->last_bad_plcp_cnt_cck = bad_plcp_cck;
+ else {
+ bad_plcp_cck -= data->last_bad_plcp_cnt_cck;
+ data->last_bad_plcp_cnt_cck += bad_plcp_cck;
+ }
+
+ if (data->last_bad_plcp_cnt_ofdm > bad_plcp_ofdm)
+ data->last_bad_plcp_cnt_ofdm = bad_plcp_ofdm;
+ else {
+ bad_plcp_ofdm -= data->last_bad_plcp_cnt_ofdm;
+ data->last_bad_plcp_cnt_ofdm += bad_plcp_ofdm;
+ }
+
+ if (data->last_fa_cnt_ofdm > fa_ofdm)
+ data->last_fa_cnt_ofdm = fa_ofdm;
+ else {
+ fa_ofdm -= data->last_fa_cnt_ofdm;
+ data->last_fa_cnt_ofdm += fa_ofdm;
+ }
+
+ if (data->last_fa_cnt_cck > fa_cck)
+ data->last_fa_cnt_cck = fa_cck;
+ else {
+ fa_cck -= data->last_fa_cnt_cck;
+ data->last_fa_cnt_cck += fa_cck;
+ }
+
+ /* Total aborted signal locks */
+ norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm;
+ norm_fa_cck = fa_cck + bad_plcp_cck;
+
+ IWL_DEBUG_CALIB("cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck,
+ bad_plcp_cck, fa_ofdm, bad_plcp_ofdm);
+
+ iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
+ iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
+ iwl_sensitivity_write(priv);
+
+ return;
+}
+EXPORT_SYMBOL(iwl_sensitivity_calibration);
+
+/*
+ * Accumulate 20 beacons of signal and noise statistics for each of
+ * 3 receivers/antennas/rx-chains, then figure out:
+ * 1) Which antennas are connected.
+ * 2) Differential rx gain settings to balance the 3 receivers.
+ */
+void iwl_chain_noise_calibration(struct iwl_priv *priv,
+ struct iwl_notif_statistics *stat_resp)
+{
+ struct iwl_chain_noise_data *data = NULL;
+
+ u32 chain_noise_a;
+ u32 chain_noise_b;
+ u32 chain_noise_c;
+ u32 chain_sig_a;
+ u32 chain_sig_b;
+ u32 chain_sig_c;
+ u32 average_sig[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
+ u32 average_noise[NUM_RX_CHAINS] = {INITIALIZATION_VALUE};
+ u32 max_average_sig;
+ u16 max_average_sig_antenna_i;
+ u32 min_average_noise = MIN_AVERAGE_NOISE_MAX_VALUE;
+ u16 min_average_noise_antenna_i = INITIALIZATION_VALUE;
+ u16 i = 0;
+ u16 rxon_chnum = INITIALIZATION_VALUE;
+ u16 stat_chnum = INITIALIZATION_VALUE;
+ u8 rxon_band24;
+ u8 stat_band24;
+ u32 active_chains = 0;
+ u8 num_tx_chains;
+ unsigned long flags;
+ struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general);
+
+ if (priv->disable_chain_noise_cal)
+ return;
+
+ data = &(priv->chain_noise_data);
+
+ /* Accumulate just the first 20 beacons after the first association,
+ * then we're done forever. */
+ if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) {
+ if (data->state == IWL_CHAIN_NOISE_ALIVE)
+ IWL_DEBUG_CALIB("Wait for noise calib reset\n");
+ return;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
+ IWL_DEBUG_CALIB(" << Interference data unavailable\n");
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
+ }
+
+ rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
+ rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
+ stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
+ stat_chnum = le32_to_cpu(stat_resp->flag) >> 16;
+
+ /* Make sure we accumulate data for just the associated channel
+ * (even if scanning). */
+ if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) {
+ IWL_DEBUG_CALIB("Stats not from chan=%d, band24=%d\n",
+ rxon_chnum, rxon_band24);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
+ }
+
+ /* Accumulate beacon statistics values across 20 beacons */
+ chain_noise_a = le32_to_cpu(rx_info->beacon_silence_rssi_a) &
+ IN_BAND_FILTER;
+ chain_noise_b = le32_to_cpu(rx_info->beacon_silence_rssi_b) &
+ IN_BAND_FILTER;
+ chain_noise_c = le32_to_cpu(rx_info->beacon_silence_rssi_c) &
+ IN_BAND_FILTER;
+
+ chain_sig_a = le32_to_cpu(rx_info->beacon_rssi_a) & IN_BAND_FILTER;
+ chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER;
+ chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ data->beacon_count++;
+
+ data->chain_noise_a = (chain_noise_a + data->chain_noise_a);
+ data->chain_noise_b = (chain_noise_b + data->chain_noise_b);
+ data->chain_noise_c = (chain_noise_c + data->chain_noise_c);
+
+ data->chain_signal_a = (chain_sig_a + data->chain_signal_a);
+ data->chain_signal_b = (chain_sig_b + data->chain_signal_b);
+ data->chain_signal_c = (chain_sig_c + data->chain_signal_c);
+
+ IWL_DEBUG_CALIB("chan=%d, band24=%d, beacon=%d\n",
+ rxon_chnum, rxon_band24, data->beacon_count);
+ IWL_DEBUG_CALIB("chain_sig: a %d b %d c %d\n",
+ chain_sig_a, chain_sig_b, chain_sig_c);
+ IWL_DEBUG_CALIB("chain_noise: a %d b %d c %d\n",
+ chain_noise_a, chain_noise_b, chain_noise_c);
+
+ /* If this is the 20th beacon, determine:
+ * 1) Disconnected antennas (using signal strengths)
+ * 2) Differential gain (using silence noise) to balance receivers */
+ if (data->beacon_count != CAL_NUM_OF_BEACONS)
+ return;
+
+ /* Analyze signal for disconnected antenna */
+ average_sig[0] = (data->chain_signal_a) / CAL_NUM_OF_BEACONS;
+ average_sig[1] = (data->chain_signal_b) / CAL_NUM_OF_BEACONS;
+ average_sig[2] = (data->chain_signal_c) / CAL_NUM_OF_BEACONS;
+
+ if (average_sig[0] >= average_sig[1]) {
+ max_average_sig = average_sig[0];
+ max_average_sig_antenna_i = 0;
+ active_chains = (1 << max_average_sig_antenna_i);
+ } else {
+ max_average_sig = average_sig[1];
+ max_average_sig_antenna_i = 1;
+ active_chains = (1 << max_average_sig_antenna_i);
+ }
+
+ if (average_sig[2] >= max_average_sig) {
+ max_average_sig = average_sig[2];
+ max_average_sig_antenna_i = 2;
+ active_chains = (1 << max_average_sig_antenna_i);
+ }
+
+ IWL_DEBUG_CALIB("average_sig: a %d b %d c %d\n",
+ average_sig[0], average_sig[1], average_sig[2]);
+ IWL_DEBUG_CALIB("max_average_sig = %d, antenna %d\n",
+ max_average_sig, max_average_sig_antenna_i);
+
+ /* Compare signal strengths for all 3 receivers. */
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ if (i != max_average_sig_antenna_i) {
+ s32 rssi_delta = (max_average_sig - average_sig[i]);
+
+ /* If signal is very weak, compared with
+ * strongest, mark it as disconnected. */
+ if (rssi_delta > MAXIMUM_ALLOWED_PATHLOSS)
+ data->disconn_array[i] = 1;
+ else
+ active_chains |= (1 << i);
+ IWL_DEBUG_CALIB("i = %d rssiDelta = %d "
+ "disconn_array[i] = %d\n",
+ i, rssi_delta, data->disconn_array[i]);
+ }
+ }
+
+ num_tx_chains = 0;
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ /* loops on all the bits of
+ * priv->hw_setting.valid_tx_ant */
+ u8 ant_msk = (1 << i);
+ if (!(priv->hw_params.valid_tx_ant & ant_msk))
+ continue;
+
+ num_tx_chains++;
+ if (data->disconn_array[i] == 0)
+ /* there is a Tx antenna connected */
+ break;
+ if (num_tx_chains == priv->hw_params.tx_chains_num &&
+ data->disconn_array[i]) {
+ /* This is the last TX antenna and is also
+ * disconnected connect it anyway */
+ data->disconn_array[i] = 0;
+ active_chains |= ant_msk;
+ IWL_DEBUG_CALIB("All Tx chains are disconnected W/A - "
+ "declare %d as connected\n", i);
+ break;
+ }
+ }
+
+ IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
+ active_chains);
+
+ /* Save for use within RXON, TX, SCAN commands, etc. */
+ /*priv->valid_antenna = active_chains;*/
+ /*FIXME: should be reflected in RX chains in RXON */
+
+ /* Analyze noise for rx balance */
+ average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
+ average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS);
+ average_noise[2] = ((data->chain_noise_c)/CAL_NUM_OF_BEACONS);
+
+ for (i = 0; i < NUM_RX_CHAINS; i++) {
+ if (!(data->disconn_array[i]) &&
+ (average_noise[i] <= min_average_noise)) {
+ /* This means that chain i is active and has
+ * lower noise values so far: */
+ min_average_noise = average_noise[i];
+ min_average_noise_antenna_i = i;
+ }
+ }
+
+ IWL_DEBUG_CALIB("average_noise: a %d b %d c %d\n",
+ average_noise[0], average_noise[1],
+ average_noise[2]);
+
+ IWL_DEBUG_CALIB("min_average_noise = %d, antenna %d\n",
+ min_average_noise, min_average_noise_antenna_i);
+
+ priv->cfg->ops->utils->gain_computation(priv, average_noise,
+ min_average_noise_antenna_i, min_average_noise);
+}
+EXPORT_SYMBOL(iwl_chain_noise_calibration);
+
+
+void iwl_reset_run_time_calib(struct iwl_priv *priv)
+{
+ int i;
+ memset(&(priv->sensitivity_data), 0,
+ sizeof(struct iwl_sensitivity_data));
+ memset(&(priv->chain_noise_data), 0,
+ sizeof(struct iwl_chain_noise_data));
+ for (i = 0; i < NUM_RX_CHAINS; i++)
+ priv->chain_noise_data.delta_gain_code[i] =
+ CHAIN_NOISE_DELTA_GAIN_INIT_VAL;
+
+ /* Ask for statistics now, the uCode will send notification
+ * periodically after association */
+ iwl_send_statistics_request(priv, CMD_ASYNC);
+}
+EXPORT_SYMBOL(iwl_reset_run_time_calib);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
new file mode 100644
index 00000000000..94c8e316382
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * 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.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *****************************************************************************/
+#ifndef __iwl_calib_h__
+#define __iwl_calib_h__
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-commands.h"
+
+void iwl_chain_noise_calibration(struct iwl_priv *priv,
+ struct iwl_notif_statistics *stat_resp);
+void iwl_sensitivity_calibration(struct iwl_priv *priv,
+ struct iwl_notif_statistics *resp);
+
+void iwl_init_sensitivity(struct iwl_priv *priv);
+void iwl_reset_run_time_calib(struct iwl_priv *priv);
+static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
+{
+
+ if (!priv->disable_chain_noise_cal &&
+ priv->cfg->ops->utils->chain_noise_reset)
+ priv->cfg->ops->utils->chain_noise_reset(priv);
+}
+
+#endif /* __iwl_calib_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 3bcd107e2d7..e9bb1de0ce3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -61,9 +61,9 @@
*
*****************************************************************************/
/*
- * Please use this file (iwl-4965-commands.h) only for uCode API definitions.
+ * Please use this file (iwl-commands.h) only for uCode API definitions.
* Please use iwl-4965-hw.h for hardware-related definitions.
- * Please use iwl-4965.h for driver implementation definitions.
+ * Please use iwl-dev.h for driver implementation definitions.
*/
#ifndef __iwl4965_commands_h__
@@ -93,6 +93,11 @@ enum {
REPLY_LEDS_CMD = 0x48,
REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
+ /* WiMAX coexistence */
+ COEX_PRIORITY_TABLE_CMD = 0x5a, /*5000 only */
+ COEX_MEDIUM_NOTIFICATION = 0x5b,
+ COEX_EVENT_CMD = 0x5c,
+
/* 802.11h related */
RADAR_NOTIFICATION = 0x70, /* not used */
REPLY_QUIET_CMD = 0x71, /* not used */
@@ -121,6 +126,7 @@ enum {
/* Miscellaneous commands */
QUIET_NOTIFICATION = 0x96, /* not used */
REPLY_TX_PWR_TABLE_CMD = 0x97,
+ REPLY_TX_POWER_DBM_CMD = 0x98,
MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
/* Bluetooth device coexistance config command */
@@ -269,21 +275,13 @@ struct iwl_cmd_header {
* 10 B active, A inactive
* 11 Both active
*/
-#define RATE_MCS_ANT_POS 14
-#define RATE_MCS_ANT_A_MSK 0x04000
-#define RATE_MCS_ANT_B_MSK 0x08000
-#define RATE_MCS_ANT_AB_MSK 0x0C000
+#define RATE_MCS_ANT_POS 14
+#define RATE_MCS_ANT_A_MSK 0x04000
+#define RATE_MCS_ANT_B_MSK 0x08000
+#define RATE_MCS_ANT_C_MSK 0x10000
+#define RATE_MCS_ANT_ABC_MSK 0x1C000
-
-/**
- * struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD
- *
- * Scan uses only one transmitter, so only one analog/dsp gain pair is needed.
- */
-struct iwl4965_tx_power {
- u8 tx_gain; /* gain for analog radio */
- u8 dsp_atten; /* gain for DSP */
-} __attribute__ ((packed));
+#define RATE_MCS_ANT_INIT_IND 1
#define POWER_TABLE_NUM_ENTRIES 33
#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32
@@ -333,6 +331,19 @@ struct iwl4965_tx_power_db {
struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
} __attribute__ ((packed));
+/**
+ * Commad REPLY_TX_POWER_DBM_CMD = 0x98
+ * struct iwl5000_tx_power_dbm_cmd
+ */
+#define IWL50_TX_POWER_AUTO 0x7f
+#define IWL50_TX_POWER_NO_CLOSED (0x1 << 6)
+
+struct iwl5000_tx_power_dbm_cmd {
+ s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
+ u8 flags;
+ s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
+ u8 reserved;
+} __attribute__ ((packed));
/******************************************************************************
* (0a)
@@ -367,7 +378,7 @@ struct iwl4965_tx_power_db {
* 3) Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation,
* for each of 5 frequency ranges.
*/
-struct iwl4965_init_alive_resp {
+struct iwl_init_alive_resp {
u8 ucode_minor;
u8 ucode_major;
__le16 reserved1;
@@ -443,7 +454,7 @@ struct iwl4965_init_alive_resp {
* The Linux driver can print both logs to the system log when a uCode error
* occurs.
*/
-struct iwl4965_alive_resp {
+struct iwl_alive_resp {
u8 ucode_minor;
u8 ucode_major;
__le16 reserved1;
@@ -467,7 +478,7 @@ union tsf {
/*
* REPLY_ERROR = 0x2 (response only, not a command)
*/
-struct iwl4965_error_resp {
+struct iwl_error_resp {
__le32 error_type;
u8 cmd_id;
u8 reserved1;
@@ -545,6 +556,8 @@ enum {
#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3 << 25)
#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1 << 25)
#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2 << 25)
+/* CTS to self (if spec allows) flag */
+#define RXON_FLG_SELF_CTS_EN __constant_cpu_to_le32(0x1<<30)
/* rx_config filter flags */
/* accept all data frames */
@@ -599,6 +612,46 @@ struct iwl4965_rxon_cmd {
u8 ofdm_ht_dual_stream_basic_rates;
} __attribute__ ((packed));
+/* 5000 HW just extend this cmmand */
+struct iwl_rxon_cmd {
+ u8 node_addr[6];
+ __le16 reserved1;
+ u8 bssid_addr[6];
+ __le16 reserved2;
+ u8 wlap_bssid_addr[6];
+ __le16 reserved3;
+ u8 dev_type;
+ u8 air_propagation;
+ __le16 rx_chain;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 assoc_id;
+ __le32 flags;
+ __le32 filter_flags;
+ __le16 channel;
+ u8 ofdm_ht_single_stream_basic_rates;
+ u8 ofdm_ht_dual_stream_basic_rates;
+ u8 ofdm_ht_triple_stream_basic_rates;
+ u8 reserved5;
+ __le16 acquisition_data;
+ __le16 reserved6;
+} __attribute__ ((packed));
+
+struct iwl5000_rxon_assoc_cmd {
+ __le32 flags;
+ __le32 filter_flags;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 reserved1;
+ u8 ofdm_ht_single_stream_basic_rates;
+ u8 ofdm_ht_dual_stream_basic_rates;
+ u8 ofdm_ht_triple_stream_basic_rates;
+ u8 reserved2;
+ __le16 rx_chain_select_flags;
+ __le16 acquisition_data;
+ __le32 reserved3;
+} __attribute__ ((packed));
+
/*
* REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
*/
@@ -613,6 +666,9 @@ struct iwl4965_rxon_assoc_cmd {
__le16 reserved;
} __attribute__ ((packed));
+
+
+
/*
* REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
*/
@@ -669,7 +725,7 @@ struct iwl4965_csa_notification {
* transmission retry. Device uses cw_max as a bit mask, ANDed with new CW
* value, to cap the CW value.
*/
-struct iwl4965_ac_qos {
+struct iwl_ac_qos {
__le16 cw_min;
__le16 cw_max;
u8 aifsn;
@@ -691,9 +747,9 @@ struct iwl4965_ac_qos {
* This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
* 0: Background, 1: Best Effort, 2: Video, 3: Voice.
*/
-struct iwl4965_qosparam_cmd {
+struct iwl_qosparam_cmd {
__le32 qos_flags;
- struct iwl4965_ac_qos ac[AC_NUM];
+ struct iwl_ac_qos ac[AC_NUM];
} __attribute__ ((packed));
/******************************************************************************
@@ -711,6 +767,8 @@ struct iwl4965_qosparam_cmd {
#define IWL_STA_ID 2
#define IWL4965_BROADCAST_ID 31
#define IWL4965_STATION_COUNT 32
+#define IWL5000_BROADCAST_ID 15
+#define IWL5000_STATION_COUNT 16
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255
@@ -766,6 +824,20 @@ struct iwl4965_keyinfo {
u8 key[16]; /* 16-byte unicast decryption key */
} __attribute__ ((packed));
+/* 5000 */
+struct iwl_keyinfo {
+ __le16 key_flags;
+ u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
+ u8 reserved1;
+ __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
+ u8 key_offset;
+ u8 reserved2;
+ u8 key[16]; /* 16-byte unicast decryption key */
+ __le64 tx_secur_seq_cnt;
+ __le64 hw_tkip_mic_rx_key;
+ __le64 hw_tkip_mic_tx_key;
+} __attribute__ ((packed));
+
/**
* struct sta_id_modify
* @addr[ETH_ALEN]: station's MAC address
@@ -841,6 +913,38 @@ struct iwl4965_addsta_cmd {
__le32 reserved2;
} __attribute__ ((packed));
+/* 5000 */
+struct iwl_addsta_cmd {
+ u8 mode; /* 1: modify existing, 0: add new station */
+ u8 reserved[3];
+ struct sta_id_modify sta;
+ struct iwl_keyinfo key;
+ __le32 station_flags; /* STA_FLG_* */
+ __le32 station_flags_msk; /* STA_FLG_* */
+
+ /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+ * corresponding to bit (e.g. bit 5 controls TID 5).
+ * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+ __le16 tid_disable_tx;
+
+ __le16 reserved1;
+
+ /* TID for which to add block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ u8 add_immediate_ba_tid;
+
+ /* TID for which to remove block-ack support.
+ * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+ u8 remove_immediate_ba_tid;
+
+ /* Starting Sequence Number for added block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ __le16 add_immediate_ba_ssn;
+
+ __le32 reserved2;
+} __attribute__ ((packed));
+
+
#define ADD_STA_SUCCESS_MSK 0x1
#define ADD_STA_NO_ROOM_IN_TABLE 0x2
#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4
@@ -848,10 +952,28 @@ struct iwl4965_addsta_cmd {
/*
* REPLY_ADD_STA = 0x18 (response)
*/
-struct iwl4965_add_sta_resp {
+struct iwl_add_sta_resp {
u8 status; /* ADD_STA_* */
} __attribute__ ((packed));
+#define REM_STA_SUCCESS_MSK 0x1
+/*
+ * REPLY_REM_STA = 0x19 (response)
+ */
+struct iwl_rem_sta_resp {
+ u8 status;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_REM_STA = 0x19 (command)
+ */
+struct iwl_rem_sta_cmd {
+ u8 num_sta; /* number of removed stations */
+ u8 reserved[3];
+ u8 addr[ETH_ALEN]; /* MAC addr of the first station */
+ u8 reserved2[2];
+} __attribute__ ((packed));
+
/*
* REPLY_WEP_KEY = 0x20
*/
@@ -875,6 +997,7 @@ struct iwl_wep_cmd {
#define WEP_KEY_WEP_TYPE 1
#define WEP_KEYS_MAX 4
#define WEP_INVALID_OFFSET 0xff
+#define WEP_KEY_LEN_64 5
#define WEP_KEY_LEN_128 13
/******************************************************************************
@@ -1018,6 +1141,11 @@ struct iwl4965_rx_mpdu_res_start {
/* REPLY_TX Tx flags field */
+/* 1: Use RTS/CTS protocol or CTS-to-self if spec alows it
+ * before this frame. if CTS-to-self required check
+ * RXON_FLG_SELF_CTS_EN status. */
+#define TX_CMD_FLG_RTS_CTS_MSK __constant_cpu_to_le32(1 << 0)
+
/* 1: Use Request-To-Send protocol before this frame.
* Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1)
@@ -1100,6 +1228,14 @@ struct iwl4965_rx_mpdu_res_start {
#define TX_CMD_SEC_KEY128 0x08
/*
+ * security overhead sizes
+ */
+#define WEP_IV_LEN 4
+#define WEP_ICV_LEN 4
+#define CCMP_MIC_LEN 8
+#define TKIP_ICV_LEN 4
+
+/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
* Driver should set these fields to 0.
@@ -1113,7 +1249,7 @@ struct iwl4965_dram_scratch {
/*
* REPLY_TX = 0x1c (command)
*/
-struct iwl4965_tx_cmd {
+struct iwl_tx_cmd {
/*
* MPDU byte count:
* MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
@@ -1259,6 +1395,15 @@ enum {
TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */
};
+static inline int iwl_is_tx_success(u32 status)
+{
+ status &= TX_STATUS_MSK;
+ return (status == TX_STATUS_SUCCESS)
+ || (status == TX_STATUS_DIRECT_DONE);
+}
+
+
+
/* *******************************
* TX aggregation status
******************************* */
@@ -1313,6 +1458,11 @@ enum {
* within the sending station (this 4965), rather than whether it was
* received successfully by the destination station.
*/
+struct agg_tx_status {
+ __le16 status;
+ __le16 sequence;
+} __attribute__ ((packed));
+
struct iwl4965_tx_resp {
u8 frame_count; /* 1 no aggregation, >1 aggregation */
u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
@@ -1344,34 +1494,56 @@ struct iwl4965_tx_resp {
* table entry used for all frames in the new agg.
* 31-16: Sequence # for this frame's Tx cmd (not SSN!)
*/
- __le32 status; /* TX status (for aggregation status of 1st frame) */
+ union {
+ __le32 status;
+ struct agg_tx_status agg_status[0]; /* for each agg frame */
+ } u;
} __attribute__ ((packed));
-struct agg_tx_status {
- __le16 status;
- __le16 sequence;
-} __attribute__ ((packed));
+struct iwl5000_tx_resp {
+ u8 frame_count; /* 1 no aggregation, >1 aggregation */
+ u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */
+ u8 failure_rts; /* # failures due to unsuccessful RTS */
+ u8 failure_frame; /* # failures due to no ACK (unused for agg) */
-struct iwl4965_tx_resp_agg {
- u8 frame_count; /* 1 no aggregation, >1 aggregation */
- u8 reserved1;
- u8 failure_rts;
- u8 failure_frame;
- __le32 rate_n_flags;
- __le16 wireless_media_time;
- __le16 reserved3;
- __le32 pa_power1;
+ /* For non-agg: Rate at which frame was successful.
+ * For agg: Rate at which all frames were transmitted. */
+ __le32 rate_n_flags; /* RATE_MCS_* */
+
+ /* For non-agg: RTS + CTS + frame tx attempts time + ACK.
+ * For agg: RTS + CTS + aggregation tx time + block-ack time. */
+ __le16 wireless_media_time; /* uSecs */
+
+ __le16 reserved;
+ __le32 pa_power1; /* RF power amplifier measurement (not used) */
__le32 pa_power2;
- struct agg_tx_status status; /* TX status (for aggregation status */
- /* of 1st frame) */
-} __attribute__ ((packed));
+ __le32 tfd_info;
+ __le16 seq_ctl;
+ __le16 byte_cnt;
+ __le32 tlc_info;
+ /*
+ * For non-agg: frame status TX_STATUS_*
+ * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status
+ * fields follow this one, up to frame_count.
+ * Bit fields:
+ * 11- 0: AGG_TX_STATE_* status code
+ * 15-12: Retry count for 1st frame in aggregation (retries
+ * occur if tx failed for this frame when it was a
+ * member of a previous aggregation block). If rate
+ * scaling is used, retry count indicates the rate
+ * table entry used for all frames in the new agg.
+ * 31-16: Sequence # for this frame's Tx cmd (not SSN!)
+ */
+ struct agg_tx_status status; /* TX status (in aggregation -
+ * status of 1st frame) */
+} __attribute__ ((packed));
/*
* REPLY_COMPRESSED_BA = 0xc5 (response only, not a command)
*
* Reports Block-Acknowledge from recipient station
*/
-struct iwl4965_compressed_ba_resp {
+struct iwl_compressed_ba_resp {
__le32 sta_addr_lo32;
__le16 sta_addr_hi16;
__le16 reserved;
@@ -1853,6 +2025,7 @@ struct iwl4965_spectrum_notification {
#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le16(1 << 0)
#define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le16(1 << 2)
#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3)
+#define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4)
struct iwl4965_powertable_cmd {
__le16 flags;
@@ -1914,7 +2087,7 @@ struct iwl4965_card_state_notif {
#define RF_CARD_DISABLED 0x04
#define RXON_CARD_DISABLED 0x10
-struct iwl4965_ct_kill_config {
+struct iwl_ct_kill_config {
__le32 reserved;
__le32 critical_temperature_M;
__le32 critical_temperature_R;
@@ -1926,8 +2099,11 @@ struct iwl4965_ct_kill_config {
*
*****************************************************************************/
+#define SCAN_CHANNEL_TYPE_PASSIVE __constant_cpu_to_le32(0)
+#define SCAN_CHANNEL_TYPE_ACTIVE __constant_cpu_to_le32(1)
+
/**
- * struct iwl4965_scan_channel - entry in REPLY_SCAN_CMD channel table
+ * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
*
* One for each channel in the scan list.
* Each channel can independently select:
@@ -1937,7 +2113,7 @@ struct iwl4965_ct_kill_config {
* quiet_plcp_th, good_CRC_th)
*
* To avoid uCode errors, make sure the following are true (see comments
- * under struct iwl4965_scan_cmd about max_out_time and quiet_time):
+ * under struct iwl_scan_cmd about max_out_time and quiet_time):
* 1) If using passive_dwell (i.e. passive_dwell != 0):
* active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
* 2) quiet_time <= active_dwell
@@ -1945,37 +2121,38 @@ struct iwl4965_ct_kill_config {
* passive_dwell < max_out_time
* active_dwell < max_out_time
*/
-struct iwl4965_scan_channel {
+struct iwl_scan_channel {
/*
* type is defined as:
* 0:0 1 = active, 0 = passive
- * 1:4 SSID direct bit map; if a bit is set, then corresponding
+ * 1:20 SSID direct bit map; if a bit is set, then corresponding
* SSID IE is transmitted in probe request.
- * 5:7 reserved
+ * 21:31 reserved
*/
- u8 type;
- u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */
- struct iwl4965_tx_power tpc;
+ __le32 type;
+ __le16 channel; /* band is selected by iwl_scan_cmd "flags" field */
+ u8 tx_gain; /* gain for analog radio */
+ u8 dsp_atten; /* gain for DSP */
__le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));
/**
- * struct iwl4965_ssid_ie - directed scan network information element
+ * struct iwl_ssid_ie - directed scan network information element
*
* Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
* in struct iwl4965_scan_channel; each channel may select different ssids from
* among the 4 entries. SSID IEs get transmitted in reverse order of entry.
*/
-struct iwl4965_ssid_ie {
+struct iwl_ssid_ie {
u8 id;
u8 len;
u8 ssid[32];
} __attribute__ ((packed));
-#define PROBE_OPTION_MAX 0x4
+#define PROBE_OPTION_MAX 0x14
#define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1)
#define IWL_MAX_SCAN_SIZE 1024
/*
@@ -2028,9 +2205,9 @@ struct iwl4965_ssid_ie {
* Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
*
* To avoid uCode errors, see timing restrictions described under
- * struct iwl4965_scan_channel.
+ * struct iwl_scan_channel.
*/
-struct iwl4965_scan_cmd {
+struct iwl_scan_cmd {
__le16 len;
u8 reserved0;
u8 channel_count; /* # channels in channel list */
@@ -2051,10 +2228,10 @@ struct iwl4965_scan_cmd {
/* For active scans (set to all-0s for passive scans).
* Does not include payload. Must specify Tx rate; no rate scaling. */
- struct iwl4965_tx_cmd tx_cmd;
+ struct iwl_tx_cmd tx_cmd;
/* For directed active scans (set to all-0s otherwise) */
- struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX];
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
/*
* Probe request frame, followed by channel list.
@@ -2082,14 +2259,14 @@ struct iwl4965_scan_cmd {
/*
* REPLY_SCAN_CMD = 0x80 (response)
*/
-struct iwl4965_scanreq_notification {
+struct iwl_scanreq_notification {
__le32 status; /* 1: okay, 2: cannot fulfill request */
} __attribute__ ((packed));
/*
* SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
*/
-struct iwl4965_scanstart_notification {
+struct iwl_scanstart_notification {
__le32 tsf_low;
__le32 tsf_high;
__le32 beacon_timer;
@@ -2106,7 +2283,7 @@ struct iwl4965_scanstart_notification {
/*
* SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
*/
-struct iwl4965_scanresults_notification {
+struct iwl_scanresults_notification {
u8 channel;
u8 band;
u8 reserved[2];
@@ -2118,7 +2295,7 @@ struct iwl4965_scanresults_notification {
/*
* SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
*/
-struct iwl4965_scancomplete_notification {
+struct iwl_scancomplete_notification {
u8 scanned_channels;
u8 status;
u8 reserved;
@@ -2148,7 +2325,7 @@ struct iwl4965_beacon_notif {
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/
struct iwl4965_tx_beacon_cmd {
- struct iwl4965_tx_cmd tx;
+ struct iwl_tx_cmd tx;
__le16 tim_idx;
u8 tim_size;
u8 reserved1;
@@ -2339,7 +2516,7 @@ struct statistics_general {
*/
#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */
#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */
-struct iwl4965_statistics_cmd {
+struct iwl_statistics_cmd {
__le32 configuration_flags; /* IWL_STATS_CONF_* */
} __attribute__ ((packed));
@@ -2360,7 +2537,7 @@ struct iwl4965_statistics_cmd {
*/
#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8)
-struct iwl4965_notif_statistics {
+struct iwl_notif_statistics {
__le32 flag;
struct statistics_rx rx;
struct statistics_tx tx;
@@ -2559,7 +2736,7 @@ struct iwl4965_missed_beacon_notif {
*/
/*
- * Table entries in SENSITIVITY_CMD (struct iwl4965_sensitivity_cmd)
+ * Table entries in SENSITIVITY_CMD (struct iwl_sensitivity_cmd)
*/
#define HD_TABLE_SIZE (11) /* number of entries */
#define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */
@@ -2574,18 +2751,18 @@ struct iwl4965_missed_beacon_notif {
#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9)
#define HD_OFDM_ENERGY_TH_IN_INDEX (10)
-/* Control field in struct iwl4965_sensitivity_cmd */
+/* Control field in struct iwl_sensitivity_cmd */
#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0)
#define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1)
/**
- * struct iwl4965_sensitivity_cmd
+ * struct iwl_sensitivity_cmd
* @control: (1) updates working table, (0) updates default table
* @table: energy threshold values, use HD_* as index into table
*
* Always use "1" in "control" to update uCode's working table and DSP.
*/
-struct iwl4965_sensitivity_cmd {
+struct iwl_sensitivity_cmd {
__le16 control; /* always use "1" */
__le16 table[HD_TABLE_SIZE]; /* use HD_* as index */
} __attribute__ ((packed));
@@ -2659,6 +2836,86 @@ struct iwl4965_calibration_cmd {
u8 reserved1;
} __attribute__ ((packed));
+/* Phy calibration command for 5000 series */
+
+enum {
+ IWL5000_PHY_CALIBRATE_DC_CMD = 8,
+ IWL5000_PHY_CALIBRATE_LO_CMD = 9,
+ IWL5000_PHY_CALIBRATE_RX_BB_CMD = 10,
+ IWL5000_PHY_CALIBRATE_TX_IQ_CMD = 11,
+ IWL5000_PHY_CALIBRATE_RX_IQ_CMD = 12,
+ IWL5000_PHY_CALIBRATION_NOISE_CMD = 13,
+ IWL5000_PHY_CALIBRATE_AGC_TABLE_CMD = 14,
+ IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15,
+ IWL5000_PHY_CALIBRATE_BASE_BAND_CMD = 16,
+ IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17,
+ IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD = 18,
+ IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19,
+};
+
+enum {
+ CALIBRATION_CFG_CMD = 0x65,
+ CALIBRATION_RES_NOTIFICATION = 0x66,
+ CALIBRATION_COMPLETE_NOTIFICATION = 0x67
+};
+
+struct iwl_cal_crystal_freq_cmd {
+ u8 cap_pin1;
+ u8 cap_pin2;
+} __attribute__ ((packed));
+
+struct iwl5000_calibration {
+ u8 op_code;
+ u8 first_group;
+ u8 num_groups;
+ u8 all_data_valid;
+ struct iwl_cal_crystal_freq_cmd data;
+} __attribute__ ((packed));
+
+#define IWL_CALIB_INIT_CFG_ALL __constant_cpu_to_le32(0xffffffff)
+
+struct iwl_calib_cfg_elmnt_s {
+ __le32 is_enable;
+ __le32 start;
+ __le32 send_res;
+ __le32 apply_res;
+ __le32 reserved;
+} __attribute__ ((packed));
+
+struct iwl_calib_cfg_status_s {
+ struct iwl_calib_cfg_elmnt_s once;
+ struct iwl_calib_cfg_elmnt_s perd;
+ __le32 flags;
+} __attribute__ ((packed));
+
+struct iwl5000_calib_cfg_cmd {
+ struct iwl_calib_cfg_status_s ucd_calib_cfg;
+ struct iwl_calib_cfg_status_s drv_calib_cfg;
+ __le32 reserved1;
+} __attribute__ ((packed));
+
+struct iwl5000_calib_hdr {
+ u8 op_code;
+ u8 first_group;
+ u8 groups_num;
+ u8 data_valid;
+} __attribute__ ((packed));
+
+struct iwl5000_calibration_chain_noise_reset_cmd {
+ u8 op_code; /* IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
+ u8 flags; /* not used */
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl5000_calibration_chain_noise_gain_cmd {
+ u8 op_code; /* IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */
+ u8 flags; /* not used */
+ __le16 reserved;
+ u8 delta_gain_1;
+ u8 delta_gain_2;
+ __le16 reserved1;
+} __attribute__ ((packed));
+
/******************************************************************************
* (12)
* Miscellaneous Commands:
@@ -2672,7 +2929,7 @@ struct iwl4965_calibration_cmd {
* For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
* this command turns it on or off, or sets up a periodic blinking cycle.
*/
-struct iwl4965_led_cmd {
+struct iwl_led_cmd {
__le32 interval; /* "interval" in uSec */
u8 id; /* 1: Activity, 2: Link, 3: Tech */
u8 off; /* # intervals off while blinking;
@@ -2682,30 +2939,81 @@ struct iwl4965_led_cmd {
u8 reserved;
} __attribute__ ((packed));
+/*
+ * Coexistence WIFI/WIMAX Command
+ * COEX_PRIORITY_TABLE_CMD = 0x5a
+ *
+ */
+enum {
+ COEX_UNASSOC_IDLE = 0,
+ COEX_UNASSOC_MANUAL_SCAN = 1,
+ COEX_UNASSOC_AUTO_SCAN = 2,
+ COEX_CALIBRATION = 3,
+ COEX_PERIODIC_CALIBRATION = 4,
+ COEX_CONNECTION_ESTAB = 5,
+ COEX_ASSOCIATED_IDLE = 6,
+ COEX_ASSOC_MANUAL_SCAN = 7,
+ COEX_ASSOC_AUTO_SCAN = 8,
+ COEX_ASSOC_ACTIVE_LEVEL = 9,
+ COEX_RF_ON = 10,
+ COEX_RF_OFF = 11,
+ COEX_STAND_ALONE_DEBUG = 12,
+ COEX_IPAN_ASSOC_LEVEL = 13,
+ COEX_RSRVD1 = 14,
+ COEX_RSRVD2 = 15,
+ COEX_NUM_OF_EVENTS = 16
+};
+
+struct iwl_wimax_coex_event_entry {
+ u8 request_prio;
+ u8 win_medium_prio;
+ u8 reserved;
+ u8 flags;
+} __attribute__ ((packed));
+
+/* COEX flag masks */
+
+/* Staion table is valid */
+#define COEX_FLAGS_STA_TABLE_VALID_MSK (0x1)
+/* UnMask wakeup src at unassociated sleep */
+#define COEX_FLAGS_UNASSOC_WA_UNMASK_MSK (0x4)
+/* UnMask wakeup src at associated sleep */
+#define COEX_FLAGS_ASSOC_WA_UNMASK_MSK (0x8)
+/* Enable CoEx feature. */
+#define COEX_FLAGS_COEX_ENABLE_MSK (0x80)
+
+struct iwl_wimax_coex_cmd {
+ u8 flags;
+ u8 reserved[3];
+ struct iwl_wimax_coex_event_entry sta_prio[COEX_NUM_OF_EVENTS];
+} __attribute__ ((packed));
+
/******************************************************************************
* (13)
* Union of all expected notifications/responses:
*
*****************************************************************************/
-struct iwl4965_rx_packet {
+struct iwl_rx_packet {
__le32 len;
struct iwl_cmd_header hdr;
union {
- struct iwl4965_alive_resp alive_frame;
+ struct iwl_alive_resp alive_frame;
struct iwl4965_rx_frame rx_frame;
struct iwl4965_tx_resp tx_resp;
struct iwl4965_spectrum_notification spectrum_notif;
struct iwl4965_csa_notification csa_notif;
- struct iwl4965_error_resp err_resp;
+ struct iwl_error_resp err_resp;
struct iwl4965_card_state_notif card_state_notif;
struct iwl4965_beacon_notif beacon_status;
- struct iwl4965_add_sta_resp add_sta;
+ struct iwl_add_sta_resp add_sta;
+ struct iwl_rem_sta_resp rem_sta;
struct iwl4965_sleep_notification sleep_notif;
struct iwl4965_spectrum_resp spectrum;
- struct iwl4965_notif_statistics stats;
- struct iwl4965_compressed_ba_resp compressed_ba;
+ struct iwl_notif_statistics stats;
+ struct iwl_compressed_ba_resp compressed_ba;
struct iwl4965_missed_beacon_notif missed_beacon;
+ struct iwl5000_calibration calib;
__le32 status;
u8 raw[0];
} u;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 2dfd982d7d1..a44188bf445 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -34,9 +34,11 @@
struct iwl_priv; /* FIXME: remove */
#include "iwl-debug.h"
#include "iwl-eeprom.h"
-#include "iwl-4965.h" /* FIXME: remove */
+#include "iwl-dev.h" /* FIXME: remove */
#include "iwl-core.h"
+#include "iwl-io.h"
#include "iwl-rfkill.h"
+#include "iwl-power.h"
MODULE_DESCRIPTION("iwl core");
@@ -44,10 +46,106 @@ MODULE_VERSION(IWLWIFI_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
-#ifdef CONFIG_IWLWIFI_DEBUG
-u32 iwl_debug_level;
-EXPORT_SYMBOL(iwl_debug_level);
-#endif
+#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
+ [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
+ IWL_RATE_SISO_##s##M_PLCP, \
+ IWL_RATE_MIMO2_##s##M_PLCP,\
+ IWL_RATE_MIMO3_##s##M_PLCP,\
+ IWL_RATE_##r##M_IEEE, \
+ IWL_RATE_##ip##M_INDEX, \
+ IWL_RATE_##in##M_INDEX, \
+ IWL_RATE_##rp##M_INDEX, \
+ IWL_RATE_##rn##M_INDEX, \
+ IWL_RATE_##pp##M_INDEX, \
+ IWL_RATE_##np##M_INDEX }
+
+/*
+ * Parameter order:
+ * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
+ *
+ * If there isn't a valid next or previous rate then INV is used which
+ * maps to IWL_RATE_INVALID
+ *
+ */
+const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+ IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
+ IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
+ IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
+ IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
+ IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
+ IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
+ IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
+ IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
+ IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
+ IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
+ IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
+ IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
+ IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
+ /* FIXME:RS: ^^ should be INV (legacy) */
+};
+EXPORT_SYMBOL(iwl_rates);
+
+/**
+ * translate ucode response to mac80211 tx status control values
+ */
+void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
+ struct ieee80211_tx_info *control)
+{
+ int rate_index;
+
+ control->antenna_sel_tx =
+ ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
+ if (rate_n_flags & RATE_MCS_HT_MSK)
+ control->flags |= IEEE80211_TX_CTL_OFDM_HT;
+ if (rate_n_flags & RATE_MCS_GF_MSK)
+ control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;
+ if (rate_n_flags & RATE_MCS_FAT_MSK)
+ control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;
+ if (rate_n_flags & RATE_MCS_DUP_MSK)
+ control->flags |= IEEE80211_TX_CTL_DUP_DATA;
+ if (rate_n_flags & RATE_MCS_SGI_MSK)
+ control->flags |= IEEE80211_TX_CTL_SHORT_GI;
+ rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags);
+ if (control->band == IEEE80211_BAND_5GHZ)
+ rate_index -= IWL_FIRST_OFDM_RATE;
+ control->tx_rate_idx = rate_index;
+}
+EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
+
+int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+{
+ int idx = 0;
+
+ /* HT rate format */
+ if (rate_n_flags & RATE_MCS_HT_MSK) {
+ idx = (rate_n_flags & 0xff);
+
+ if (idx >= IWL_RATE_MIMO2_6M_PLCP)
+ idx = idx - IWL_RATE_MIMO2_6M_PLCP;
+
+ idx += IWL_FIRST_OFDM_RATE;
+ /* skip 9M not supported in ht*/
+ if (idx >= IWL_RATE_9M_INDEX)
+ idx += 1;
+ if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
+ return idx;
+
+ /* legacy rate format, search for match in table */
+ } else {
+ for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
+ if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+ return idx;
+ }
+
+ return -1;
+}
+EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
+
+
+
+const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+EXPORT_SYMBOL(iwl_bcast_addr);
+
/* This function both allocates and initializes hw and priv. */
struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
@@ -72,25 +170,132 @@ out:
}
EXPORT_SYMBOL(iwl_alloc_all);
+void iwl_hw_detect(struct iwl_priv *priv)
+{
+ priv->hw_rev = _iwl_read32(priv, CSR_HW_REV);
+ priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG);
+ pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
+}
+EXPORT_SYMBOL(iwl_hw_detect);
+
+/* Tell nic where to find the "keep warm" buffer */
+int iwl_kw_init(struct iwl_priv *priv)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto out;
+
+ iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
+ priv->kw.dma_addr >> 4);
+ iwl_release_nic_access(priv);
+out:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+}
+
+int iwl_kw_alloc(struct iwl_priv *priv)
+{
+ struct pci_dev *dev = priv->pci_dev;
+ struct iwl_kw *kw = &priv->kw;
+
+ kw->size = IWL_KW_SIZE;
+ kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
+ if (!kw->v_addr)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/**
+ * iwl_kw_free - Free the "keep warm" buffer
+ */
+void iwl_kw_free(struct iwl_priv *priv)
+{
+ struct pci_dev *dev = priv->pci_dev;
+ struct iwl_kw *kw = &priv->kw;
+
+ if (kw->v_addr) {
+ pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
+ memset(kw, 0, sizeof(*kw));
+ }
+}
+
+int iwl_hw_nic_init(struct iwl_priv *priv)
+{
+ unsigned long flags;
+ struct iwl_rx_queue *rxq = &priv->rxq;
+ int ret;
+
+ /* nic_init */
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->cfg->ops->lib->apm_ops.init(priv);
+ iwl_write32(priv, CSR_INT_COALESCING, 512 / 32);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+
+ priv->cfg->ops->lib->apm_ops.config(priv);
+
+ /* Allocate the RX queue, or reset if it is already allocated */
+ if (!rxq->bd) {
+ ret = iwl_rx_queue_alloc(priv);
+ if (ret) {
+ IWL_ERROR("Unable to initialize Rx queue\n");
+ return -ENOMEM;
+ }
+ } else
+ iwl_rx_queue_reset(priv, rxq);
+
+ iwl_rx_replenish(priv);
+
+ iwl_rx_init(priv, rxq);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ rxq->need_update = 1;
+ iwl_rx_queue_update_write_ptr(priv, rxq);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Allocate and init all Tx and Command queues */
+ ret = iwl_txq_ctx_reset(priv);
+ if (ret)
+ return ret;
+
+ set_bit(STATUS_INIT, &priv->status);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_hw_nic_init);
+
/**
- * iwlcore_clear_stations_table - Clear the driver's station table
+ * iwl_clear_stations_table - Clear the driver's station table
*
* NOTE: This does not clear or otherwise alter the device's station table.
*/
-void iwlcore_clear_stations_table(struct iwl_priv *priv)
+void iwl_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
spin_lock_irqsave(&priv->sta_lock, flags);
+ if (iwl_is_alive(priv) &&
+ !test_bit(STATUS_EXIT_PENDING, &priv->status) &&
+ iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL))
+ IWL_ERROR("Couldn't clear the station table\n");
+
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
-EXPORT_SYMBOL(iwlcore_clear_stations_table);
+EXPORT_SYMBOL(iwl_clear_stations_table);
-void iwlcore_reset_qos(struct iwl_priv *priv)
+void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
u16 cw_max = 1023;
@@ -176,7 +381,397 @@ void iwlcore_reset_qos(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-EXPORT_SYMBOL(iwlcore_reset_qos);
+EXPORT_SYMBOL(iwl_reset_qos);
+
+#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */
+#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */
+static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
+ struct ieee80211_ht_info *ht_info,
+ enum ieee80211_band band)
+{
+ u16 max_bit_rate = 0;
+ u8 rx_chains_num = priv->hw_params.rx_chains_num;
+ u8 tx_chains_num = priv->hw_params.tx_chains_num;
+
+ ht_info->cap = 0;
+ memset(ht_info->supp_mcs_set, 0, 16);
+
+ ht_info->ht_supported = 1;
+
+ ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
+ ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
+ ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS &
+ (IWL_MIMO_PS_NONE << 2));
+
+ max_bit_rate = MAX_BIT_RATE_20_MHZ;
+ if (priv->hw_params.fat_channel & BIT(band)) {
+ ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH;
+ ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40;
+ ht_info->supp_mcs_set[4] = 0x01;
+ max_bit_rate = MAX_BIT_RATE_40_MHZ;
+ }
+
+ if (priv->cfg->mod_params->amsdu_size_8K)
+ ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU;
+
+ ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
+ ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
+
+ ht_info->supp_mcs_set[0] = 0xFF;
+ if (rx_chains_num >= 2)
+ ht_info->supp_mcs_set[1] = 0xFF;
+ if (rx_chains_num >= 3)
+ ht_info->supp_mcs_set[2] = 0xFF;
+
+ /* Highest supported Rx data rate */
+ max_bit_rate *= rx_chains_num;
+ ht_info->supp_mcs_set[10] = (u8)(max_bit_rate & 0x00FF);
+ ht_info->supp_mcs_set[11] = (u8)((max_bit_rate & 0xFF00) >> 8);
+
+ /* Tx MCS capabilities */
+ ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED;
+ if (tx_chains_num != rx_chains_num) {
+ ht_info->supp_mcs_set[12] |= IEEE80211_HT_CAP_MCS_TX_RX_DIFF;
+ ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2);
+ }
+}
+
+static void iwlcore_init_hw_rates(struct iwl_priv *priv,
+ struct ieee80211_rate *rates)
+{
+ int i;
+
+ for (i = 0; i < IWL_RATE_COUNT; i++) {
+ rates[i].bitrate = iwl_rates[i].ieee * 5;
+ rates[i].hw_value = i; /* Rate scaling will work on indexes */
+ rates[i].hw_value_short = i;
+ rates[i].flags = 0;
+ if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
+ /*
+ * If CCK != 1M then set short preamble rate flag.
+ */
+ rates[i].flags |=
+ (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ?
+ 0 : IEEE80211_RATE_SHORT_PREAMBLE;
+ }
+ }
+}
+
+/**
+ * iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
+ */
+static int iwlcore_init_geos(struct iwl_priv *priv)
+{
+ struct iwl_channel_info *ch;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *channels;
+ struct ieee80211_channel *geo_ch;
+ struct ieee80211_rate *rates;
+ int i = 0;
+
+ if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
+ priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
+ IWL_DEBUG_INFO("Geography modes already initialized.\n");
+ set_bit(STATUS_GEO_CONFIGURED, &priv->status);
+ return 0;
+ }
+
+ channels = kzalloc(sizeof(struct ieee80211_channel) *
+ priv->channel_count, GFP_KERNEL);
+ if (!channels)
+ return -ENOMEM;
+
+ rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
+ GFP_KERNEL);
+ if (!rates) {
+ kfree(channels);
+ return -ENOMEM;
+ }
+
+ /* 5.2GHz channels start after the 2.4GHz channels */
+ sband = &priv->bands[IEEE80211_BAND_5GHZ];
+ sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
+ /* just OFDM */
+ sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
+ sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
+
+ if (priv->cfg->sku & IWL_SKU_N)
+ iwlcore_init_ht_hw_capab(priv, &sband->ht_info,
+ IEEE80211_BAND_5GHZ);
+
+ sband = &priv->bands[IEEE80211_BAND_2GHZ];
+ sband->channels = channels;
+ /* OFDM & CCK */
+ sband->bitrates = rates;
+ sband->n_bitrates = IWL_RATE_COUNT;
+
+ if (priv->cfg->sku & IWL_SKU_N)
+ iwlcore_init_ht_hw_capab(priv, &sband->ht_info,
+ IEEE80211_BAND_2GHZ);
+
+ priv->ieee_channels = channels;
+ priv->ieee_rates = rates;
+
+ iwlcore_init_hw_rates(priv, rates);
+
+ for (i = 0; i < priv->channel_count; i++) {
+ ch = &priv->channel_info[i];
+
+ /* FIXME: might be removed if scan is OK */
+ if (!is_channel_valid(ch))
+ continue;
+
+ if (is_channel_a_band(ch))
+ sband = &priv->bands[IEEE80211_BAND_5GHZ];
+ else
+ sband = &priv->bands[IEEE80211_BAND_2GHZ];
+
+ geo_ch = &sband->channels[sband->n_channels++];
+
+ geo_ch->center_freq =
+ ieee80211_channel_to_frequency(ch->channel);
+ geo_ch->max_power = ch->max_power_avg;
+ geo_ch->max_antenna_gain = 0xff;
+ geo_ch->hw_value = ch->channel;
+
+ if (is_channel_valid(ch)) {
+ if (!(ch->flags & EEPROM_CHANNEL_IBSS))
+ geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
+
+ if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
+ geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+
+ if (ch->flags & EEPROM_CHANNEL_RADAR)
+ geo_ch->flags |= IEEE80211_CHAN_RADAR;
+
+ geo_ch->flags |= ch->fat_extension_channel;
+
+ if (ch->max_power_avg > priv->tx_power_channel_lmt)
+ priv->tx_power_channel_lmt = ch->max_power_avg;
+ } else {
+ geo_ch->flags |= IEEE80211_CHAN_DISABLED;
+ }
+
+ /* Save flags for reg domain usage */
+ geo_ch->orig_flags = geo_ch->flags;
+
+ IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
+ ch->channel, geo_ch->center_freq,
+ is_channel_a_band(ch) ? "5.2" : "2.4",
+ geo_ch->flags & IEEE80211_CHAN_DISABLED ?
+ "restricted" : "valid",
+ geo_ch->flags);
+ }
+
+ if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
+ priv->cfg->sku & IWL_SKU_A) {
+ printk(KERN_INFO DRV_NAME
+ ": Incorrectly detected BG card as ABG. Please send "
+ "your PCI ID 0x%04X:0x%04X to maintainer.\n",
+ priv->pci_dev->device, priv->pci_dev->subsystem_device);
+ priv->cfg->sku &= ~IWL_SKU_A;
+ }
+
+ printk(KERN_INFO DRV_NAME
+ ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
+ priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+ priv->bands[IEEE80211_BAND_5GHZ].n_channels);
+
+
+ set_bit(STATUS_GEO_CONFIGURED, &priv->status);
+
+ return 0;
+}
+
+/*
+ * iwlcore_free_geos - undo allocations in iwlcore_init_geos
+ */
+static void iwlcore_free_geos(struct iwl_priv *priv)
+{
+ kfree(priv->ieee_channels);
+ kfree(priv->ieee_rates);
+ clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
+}
+
+static u8 is_single_rx_stream(struct iwl_priv *priv)
+{
+ return !priv->current_ht_config.is_ht ||
+ ((priv->current_ht_config.supp_mcs_set[1] == 0) &&
+ (priv->current_ht_config.supp_mcs_set[2] == 0)) ||
+ priv->ps_mode == IWL_MIMO_PS_STATIC;
+}
+
+static u8 iwl_is_channel_extension(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u16 channel, u8 extension_chan_offset)
+{
+ const struct iwl_channel_info *ch_info;
+
+ ch_info = iwl_get_channel_info(priv, band, channel);
+ if (!is_channel_valid(ch_info))
+ return 0;
+
+ if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE)
+ return !(ch_info->fat_extension_channel &
+ IEEE80211_CHAN_NO_FAT_ABOVE);
+ else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW)
+ return !(ch_info->fat_extension_channel &
+ IEEE80211_CHAN_NO_FAT_BELOW);
+
+ return 0;
+}
+
+u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
+ struct ieee80211_ht_info *sta_ht_inf)
+{
+ struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
+
+ if ((!iwl_ht_conf->is_ht) ||
+ (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
+ (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE))
+ return 0;
+
+ if (sta_ht_inf) {
+ if ((!sta_ht_inf->ht_supported) ||
+ (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)))
+ return 0;
+ }
+
+ return iwl_is_channel_extension(priv, priv->band,
+ iwl_ht_conf->control_channel,
+ iwl_ht_conf->extension_chan_offset);
+}
+EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
+
+void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
+{
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+ u32 val;
+
+ if (!ht_info->is_ht)
+ return;
+
+ /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */
+ if (iwl_is_fat_tx_allowed(priv, NULL))
+ rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK;
+ else
+ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
+ RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
+
+ if (le16_to_cpu(rxon->channel) != ht_info->control_channel) {
+ IWL_DEBUG_ASSOC("control diff than current %d %d\n",
+ le16_to_cpu(rxon->channel),
+ ht_info->control_channel);
+ return;
+ }
+
+ /* Note: control channel is opposite of extension channel */
+ switch (ht_info->extension_chan_offset) {
+ case IEEE80211_HT_IE_CHA_SEC_ABOVE:
+ rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
+ break;
+ case IEEE80211_HT_IE_CHA_SEC_BELOW:
+ rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
+ break;
+ case IEEE80211_HT_IE_CHA_SEC_NONE:
+ default:
+ rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
+ break;
+ }
+
+ val = ht_info->ht_protection;
+
+ rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS);
+
+ iwl_set_rxon_chain(priv);
+
+ IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X "
+ "rxon flags 0x%X operation mode :0x%X "
+ "extension channel offset 0x%x "
+ "control chan %d\n",
+ ht_info->supp_mcs_set[0],
+ ht_info->supp_mcs_set[1],
+ ht_info->supp_mcs_set[2],
+ le32_to_cpu(rxon->flags), ht_info->ht_protection,
+ ht_info->extension_chan_offset,
+ ht_info->control_channel);
+ return;
+}
+EXPORT_SYMBOL(iwl_set_rxon_ht);
+
+/*
+ * Determine how many receiver/antenna chains to use.
+ * More provides better reception via diversity. Fewer saves power.
+ * MIMO (dual stream) requires at least 2, but works better with 3.
+ * This does not determine *which* chains to use, just how many.
+ */
+static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv,
+ u8 *idle_state, u8 *rx_state)
+{
+ u8 is_single = is_single_rx_stream(priv);
+ u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1;
+
+ /* # of Rx chains to use when expecting MIMO. */
+ if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC)))
+ *rx_state = 2;
+ else
+ *rx_state = 3;
+
+ /* # Rx chains when idling and maybe trying to save power */
+ switch (priv->ps_mode) {
+ case IWL_MIMO_PS_STATIC:
+ case IWL_MIMO_PS_DYNAMIC:
+ *idle_state = (is_cam) ? 2 : 1;
+ break;
+ case IWL_MIMO_PS_NONE:
+ *idle_state = (is_cam) ? *rx_state : 1;
+ break;
+ default:
+ *idle_state = 1;
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
+ *
+ * Selects how many and which Rx receivers/antennas/chains to use.
+ * This should not be used for scan command ... it puts data in wrong place.
+ */
+void iwl_set_rxon_chain(struct iwl_priv *priv)
+{
+ u8 is_single = is_single_rx_stream(priv);
+ u8 idle_state, rx_state;
+
+ priv->staging_rxon.rx_chain = 0;
+ rx_state = idle_state = 3;
+
+ /* Tell uCode which antennas are actually connected.
+ * Before first association, we assume all antennas are connected.
+ * Just after first association, iwl_chain_noise_calibration()
+ * checks which antennas actually *are* connected. */
+ priv->staging_rxon.rx_chain |=
+ cpu_to_le16(priv->hw_params.valid_rx_ant <<
+ RXON_RX_CHAIN_VALID_POS);
+
+ /* How many receivers should we use? */
+ iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state);
+ priv->staging_rxon.rx_chain |=
+ cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS);
+ priv->staging_rxon.rx_chain |=
+ cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS);
+
+ if (!is_single && (rx_state >= 2) &&
+ !test_bit(STATUS_POWER_PMI, &priv->status))
+ priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ else
+ priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+
+ IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain);
+}
+EXPORT_SYMBOL(iwl_set_rxon_chain);
/**
* iwlcore_set_rxon_channel - Set the phymode and channel values in staging RXON
@@ -188,7 +783,7 @@ EXPORT_SYMBOL(iwlcore_reset_qos);
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
* in the staging RXON flag structure based on the phymode
*/
-int iwlcore_set_rxon_channel(struct iwl_priv *priv,
+int iwl_set_rxon_channel(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel)
{
@@ -214,68 +809,185 @@ int iwlcore_set_rxon_channel(struct iwl_priv *priv,
return 0;
}
-EXPORT_SYMBOL(iwlcore_set_rxon_channel);
+EXPORT_SYMBOL(iwl_set_rxon_channel);
-static void iwlcore_init_hw(struct iwl_priv *priv)
+int iwl_setup_mac(struct iwl_priv *priv)
{
+ int ret;
struct ieee80211_hw *hw = priv->hw;
hw->rate_control_algorithm = "iwl-4965-rs";
- /* Tell mac80211 and its clients (e.g. Wireless Extensions)
- * the range of signal quality values that we'll provide.
- * Negative values for level/noise indicate that we'll provide dBm.
- * For WE, at least, non-0 values here *enable* display of values
- * in app (iwconfig). */
- hw->max_rssi = -20; /* signal level, negative indicates dBm */
- hw->max_noise = -20; /* noise level, negative indicates dBm */
- hw->max_signal = 100; /* link quality indication (%) */
-
- /* Tell mac80211 our Tx characteristics */
- hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
-
+ /* Tell mac80211 our characteristics */
+ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
-#ifdef CONFIG_IWL4965_HT
- /* Enhanced value; more queues, to support 11n aggregation */
- hw->queues = 16;
-#endif /* CONFIG_IWL4965_HT */
+ /* queues to support 11n aggregation */
+ if (priv->cfg->sku & IWL_SKU_N)
+ hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
+
+ hw->conf.beacon_int = 100;
+
+ if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &priv->bands[IEEE80211_BAND_2GHZ];
+ if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &priv->bands[IEEE80211_BAND_5GHZ];
+
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ IWL_ERROR("Failed to register hw (error %d)\n", ret);
+ return ret;
+ }
+ priv->mac80211_registered = 1;
+
+ return 0;
}
+EXPORT_SYMBOL(iwl_setup_mac);
-int iwl_setup(struct iwl_priv *priv)
+int iwl_set_hw_params(struct iwl_priv *priv)
{
- int ret = 0;
- iwlcore_init_hw(priv);
- ret = priv->cfg->ops->lib->init_drv(priv);
- return ret;
+ priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;
+ priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
+ priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
+ if (priv->cfg->mod_params->amsdu_size_8K)
+ priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_8K;
+ else
+ priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K;
+ priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256;
+
+ if (priv->cfg->mod_params->disable_11n)
+ priv->cfg->sku &= ~IWL_SKU_N;
+
+ /* Device-specific setup */
+ return priv->cfg->ops->lib->set_hw_params(priv);
}
-EXPORT_SYMBOL(iwl_setup);
+EXPORT_SYMBOL(iwl_set_hw_params);
-/* Low level driver call this function to update iwlcore with
- * driver status.
- */
-int iwlcore_low_level_notify(struct iwl_priv *priv,
- enum iwlcore_card_notify notify)
+int iwl_init_drv(struct iwl_priv *priv)
{
int ret;
- switch (notify) {
- case IWLCORE_INIT_EVT:
- ret = iwl_rfkill_init(priv);
- if (ret)
- IWL_ERROR("Unable to initialize RFKILL system. "
- "Ignoring error: %d\n", ret);
- break;
- case IWLCORE_START_EVT:
- break;
- case IWLCORE_STOP_EVT:
- break;
- case IWLCORE_REMOVE_EVT:
- iwl_rfkill_unregister(priv);
- break;
+
+ priv->retry_rate = 1;
+ priv->ibss_beacon = NULL;
+
+ spin_lock_init(&priv->lock);
+ spin_lock_init(&priv->power_data.lock);
+ spin_lock_init(&priv->sta_lock);
+ spin_lock_init(&priv->hcmd_lock);
+ spin_lock_init(&priv->lq_mngr.lock);
+
+ INIT_LIST_HEAD(&priv->free_frames);
+
+ mutex_init(&priv->mutex);
+
+ /* Clear the driver's (not device's) station table */
+ iwl_clear_stations_table(priv);
+
+ priv->data_retry_limit = -1;
+ priv->ieee_channels = NULL;
+ priv->ieee_rates = NULL;
+ priv->band = IEEE80211_BAND_2GHZ;
+
+ priv->iw_mode = IEEE80211_IF_TYPE_STA;
+
+ priv->use_ant_b_for_management_frame = 1; /* start with ant B */
+ priv->ps_mode = IWL_MIMO_PS_NONE;
+
+ /* Choose which receivers/antennas to use */
+ iwl_set_rxon_chain(priv);
+ iwl_init_scan_params(priv);
+
+ if (priv->cfg->mod_params->enable_qos)
+ priv->qos_data.qos_enable = 1;
+
+ iwl_reset_qos(priv);
+
+ priv->qos_data.qos_active = 0;
+ priv->qos_data.qos_cap.val = 0;
+
+ iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+
+ priv->rates_mask = IWL_RATES_MASK;
+ /* If power management is turned on, default to AC mode */
+ priv->power_mode = IWL_POWER_AC;
+ priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
+
+ ret = iwl_init_channel_map(priv);
+ if (ret) {
+ IWL_ERROR("initializing regulatory failed: %d\n", ret);
+ goto err;
+ }
+
+ ret = iwlcore_init_geos(priv);
+ if (ret) {
+ IWL_ERROR("initializing geos failed: %d\n", ret);
+ goto err_free_channel_map;
}
return 0;
+
+err_free_channel_map:
+ iwl_free_channel_map(priv);
+err:
+ return ret;
+}
+EXPORT_SYMBOL(iwl_init_drv);
+
+void iwl_free_calib_results(struct iwl_priv *priv)
+{
+ kfree(priv->calib_results.lo_res);
+ priv->calib_results.lo_res = NULL;
+ priv->calib_results.lo_res_len = 0;
+
+ kfree(priv->calib_results.tx_iq_res);
+ priv->calib_results.tx_iq_res = NULL;
+ priv->calib_results.tx_iq_res_len = 0;
+
+ kfree(priv->calib_results.tx_iq_perd_res);
+ priv->calib_results.tx_iq_perd_res = NULL;
+ priv->calib_results.tx_iq_perd_res_len = 0;
+}
+EXPORT_SYMBOL(iwl_free_calib_results);
+
+int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
+{
+ int ret = 0;
+ if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
+ IWL_WARNING("Requested user TXPOWER %d below limit.\n",
+ priv->tx_power_user_lmt);
+ return -EINVAL;
+ }
+
+ if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
+ IWL_WARNING("Requested user TXPOWER %d above limit.\n",
+ priv->tx_power_user_lmt);
+ return -EINVAL;
+ }
+
+ if (priv->tx_power_user_lmt != tx_power)
+ force = true;
+
+ priv->tx_power_user_lmt = tx_power;
+
+ if (force && priv->cfg->ops->lib->send_tx_power)
+ ret = priv->cfg->ops->lib->send_tx_power(priv);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_set_tx_power);
+
+
+void iwl_uninit_drv(struct iwl_priv *priv)
+{
+ iwl_free_calib_results(priv);
+ iwlcore_free_geos(priv);
+ iwl_free_channel_map(priv);
+ kfree(priv->scan);
}
-EXPORT_SYMBOL(iwlcore_low_level_notify);
+EXPORT_SYMBOL(iwl_uninit_drv);
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
@@ -290,3 +1002,440 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
}
EXPORT_SYMBOL(iwl_send_statistics_request);
+/**
+ * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
+ * using sample data 100 bytes apart. If these sample points are good,
+ * it's a pretty good bet that everything between them is good, too.
+ */
+static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
+{
+ u32 val;
+ int ret = 0;
+ u32 errcnt = 0;
+ u32 i;
+
+ IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
+ /* read data comes through single port, auto-incr addr */
+ /* NOTE: Use the debugless read so we don't flood kernel log
+ * if IWL_DL_IO is set */
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ i + RTC_INST_LOWER_BOUND);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ if (val != le32_to_cpu(*image)) {
+ ret = -EIO;
+ errcnt++;
+ if (errcnt >= 3)
+ break;
+ }
+ }
+
+ iwl_release_nic_access(priv);
+
+ return ret;
+}
+
+/**
+ * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
+ * looking at all data.
+ */
+static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
+ u32 len)
+{
+ u32 val;
+ u32 save_len = len;
+ int ret = 0;
+ u32 errcnt;
+
+ IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+
+ errcnt = 0;
+ for (; len > 0; len -= sizeof(u32), image++) {
+ /* read data comes through single port, auto-incr addr */
+ /* NOTE: Use the debugless read so we don't flood kernel log
+ * if IWL_DL_IO is set */
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ if (val != le32_to_cpu(*image)) {
+ IWL_ERROR("uCode INST section is invalid at "
+ "offset 0x%x, is 0x%x, s/b 0x%x\n",
+ save_len - len, val, le32_to_cpu(*image));
+ ret = -EIO;
+ errcnt++;
+ if (errcnt >= 20)
+ break;
+ }
+ }
+
+ iwl_release_nic_access(priv);
+
+ if (!errcnt)
+ IWL_DEBUG_INFO
+ ("ucode image in INSTRUCTION memory is good\n");
+
+ return ret;
+}
+
+/**
+ * iwl_verify_ucode - determine which instruction image is in SRAM,
+ * and verify its contents
+ */
+int iwl_verify_ucode(struct iwl_priv *priv)
+{
+ __le32 *image;
+ u32 len;
+ int ret;
+
+ /* Try bootstrap */
+ image = (__le32 *)priv->ucode_boot.v_addr;
+ len = priv->ucode_boot.len;
+ ret = iwlcore_verify_inst_sparse(priv, image, len);
+ if (!ret) {
+ IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+ return 0;
+ }
+
+ /* Try initialize */
+ image = (__le32 *)priv->ucode_init.v_addr;
+ len = priv->ucode_init.len;
+ ret = iwlcore_verify_inst_sparse(priv, image, len);
+ if (!ret) {
+ IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+ return 0;
+ }
+
+ /* Try runtime/protocol */
+ image = (__le32 *)priv->ucode_code.v_addr;
+ len = priv->ucode_code.len;
+ ret = iwlcore_verify_inst_sparse(priv, image, len);
+ if (!ret) {
+ IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+ return 0;
+ }
+
+ IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+
+ /* Since nothing seems to match, show first several data entries in
+ * instruction SRAM, so maybe visual inspection will give a clue.
+ * Selection of bootstrap image (vs. other images) is arbitrary. */
+ image = (__le32 *)priv->ucode_boot.v_addr;
+ len = priv->ucode_boot.len;
+ ret = iwl_verify_inst_full(priv, image, len);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_verify_ucode);
+
+
+static const char *desc_lookup(int i)
+{
+ switch (i) {
+ case 1:
+ return "FAIL";
+ case 2:
+ return "BAD_PARAM";
+ case 3:
+ return "BAD_CHECKSUM";
+ case 4:
+ return "NMI_INTERRUPT";
+ case 5:
+ return "SYSASSERT";
+ case 6:
+ return "FATAL_ERROR";
+ }
+
+ return "UNKNOWN";
+}
+
+#define ERROR_START_OFFSET (1 * sizeof(u32))
+#define ERROR_ELEM_SIZE (7 * sizeof(u32))
+
+void iwl_dump_nic_error_log(struct iwl_priv *priv)
+{
+ u32 data2, line;
+ u32 desc, time, count, base, data1;
+ u32 blink1, blink2, ilink1, ilink2;
+ int ret;
+
+ if (priv->ucode_type == UCODE_INIT)
+ base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+ else
+ base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
+
+ if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+ IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ return;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ IWL_WARNING("Can not read from adapter at this time.\n");
+ return;
+ }
+
+ count = iwl_read_targ_mem(priv, base);
+
+ if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
+ IWL_ERROR("Start IWL Error Log Dump:\n");
+ IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ }
+
+ desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+ blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
+ blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
+ ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
+ ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
+ data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
+ data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
+ line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
+ time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
+
+ IWL_ERROR("Desc Time "
+ "data1 data2 line\n");
+ IWL_ERROR("%-13s (#%d) %010u 0x%08X 0x%08X %u\n",
+ desc_lookup(desc), desc, time, data1, data2, line);
+ IWL_ERROR("blink1 blink2 ilink1 ilink2\n");
+ IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+ ilink1, ilink2);
+
+ iwl_release_nic_access(priv);
+}
+EXPORT_SYMBOL(iwl_dump_nic_error_log);
+
+#define EVENT_START_OFFSET (4 * sizeof(u32))
+
+/**
+ * iwl_print_event_log - Dump error event log to syslog
+ *
+ * NOTE: Must be called with iwl4965_grab_nic_access() already obtained!
+ */
+void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+ u32 num_events, u32 mode)
+{
+ u32 i;
+ u32 base; /* SRAM byte address of event log header */
+ u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
+ u32 ptr; /* SRAM byte address of log data */
+ u32 ev, time, data; /* event log data */
+
+ if (num_events == 0)
+ return;
+ if (priv->ucode_type == UCODE_INIT)
+ base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+ else
+ base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+
+ if (mode == 0)
+ event_size = 2 * sizeof(u32);
+ else
+ event_size = 3 * sizeof(u32);
+
+ ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
+
+ /* "time" is actually "data" for mode 0 (no timestamp).
+ * place event id # at far right for easier visual parsing. */
+ for (i = 0; i < num_events; i++) {
+ ev = iwl_read_targ_mem(priv, ptr);
+ ptr += sizeof(u32);
+ time = iwl_read_targ_mem(priv, ptr);
+ ptr += sizeof(u32);
+ if (mode == 0) {
+ /* data, ev */
+ IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
+ } else {
+ data = iwl_read_targ_mem(priv, ptr);
+ ptr += sizeof(u32);
+ IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
+ time, data, ev);
+ }
+ }
+}
+EXPORT_SYMBOL(iwl_print_event_log);
+
+
+void iwl_dump_nic_event_log(struct iwl_priv *priv)
+{
+ int ret;
+ u32 base; /* SRAM byte address of event log header */
+ u32 capacity; /* event log capacity in # entries */
+ u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
+ u32 num_wraps; /* # times uCode wrapped to top of log */
+ u32 next_entry; /* index of next entry to be written by uCode */
+ u32 size; /* # entries that we'll print */
+
+ if (priv->ucode_type == UCODE_INIT)
+ base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+ else
+ base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+
+ if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+ IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ return;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ IWL_WARNING("Can not read from adapter at this time.\n");
+ return;
+ }
+
+ /* event log header */
+ capacity = iwl_read_targ_mem(priv, base);
+ mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+ num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+ next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
+
+ size = num_wraps ? capacity : next_entry;
+
+ /* bail out if nothing in log */
+ if (size == 0) {
+ IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
+ iwl_release_nic_access(priv);
+ return;
+ }
+
+ IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ size, num_wraps);
+
+ /* if uCode has wrapped back to top of log, start at the oldest entry,
+ * i.e the next one that uCode would fill. */
+ if (num_wraps)
+ iwl_print_event_log(priv, next_entry,
+ capacity - next_entry, mode);
+ /* (then/else) start at top of log */
+ iwl_print_event_log(priv, 0, next_entry, mode);
+
+ iwl_release_nic_access(priv);
+}
+EXPORT_SYMBOL(iwl_dump_nic_event_log);
+
+void iwl_rf_kill_ct_config(struct iwl_priv *priv)
+{
+ struct iwl_ct_kill_config cmd;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ cmd.critical_temperature_R =
+ cpu_to_le32(priv->hw_params.ct_kill_threshold);
+
+ ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
+ else
+ IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
+ "critical temperature is %d\n",
+ cmd.critical_temperature_R);
+}
+EXPORT_SYMBOL(iwl_rf_kill_ct_config);
+
+/*
+ * CARD_STATE_CMD
+ *
+ * Use: Sets the device's internal card state to enable, disable, or halt
+ *
+ * When in the 'enable' state the card operates as normal.
+ * When in the 'disable' state, the card enters into a low power mode.
+ * When in the 'halt' state, the card is shut down and must be fully
+ * restarted to come back on.
+ */
+static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+{
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_CARD_STATE_CMD,
+ .len = sizeof(u32),
+ .data = &flags,
+ .meta.flags = meta_flag,
+ };
+
+ return iwl_send_cmd(priv, &cmd);
+}
+
+void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ if (test_bit(STATUS_RF_KILL_SW, &priv->status))
+ return;
+
+ IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n");
+
+ iwl_scan_cancel(priv);
+ /* FIXME: This is a workaround for AP */
+ if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ CSR_UCODE_SW_BIT_RFKILL);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /* call the host command only if no hw rf-kill set */
+ if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&
+ iwl_is_ready(priv))
+ iwl_send_card_state(priv,
+ CARD_STATE_CMD_DISABLE, 0);
+ set_bit(STATUS_RF_KILL_SW, &priv->status);
+ /* make sure mac80211 stop sending Tx frame */
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
+ }
+}
+EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio);
+
+int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
+ return 0;
+
+ IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+
+ /* If the driver is up it will receive CARD_STATE_NOTIFICATION
+ * notification where it will clear SW rfkill status.
+ * Setting it here would break the handler. Only if the
+ * interface is down we can set here since we don't
+ * receive any further notification.
+ */
+ if (!priv->is_open)
+ clear_bit(STATUS_RF_KILL_SW, &priv->status);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* wake up ucode */
+ msleep(10);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_read32(priv, CSR_UCODE_DRV_GP1);
+ if (!iwl_grab_nic_access(priv))
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
+ IWL_DEBUG_RF_KILL("Can not turn radio back on - "
+ "disabled by HW switch\n");
+ return 0;
+ }
+
+ /* If the driver is already loaded, it will receive
+ * CARD_STATE_NOTIFICATION notifications and the handler will
+ * call restart to reload the driver.
+ */
+ return 1;
+}
+EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7193d97630d..db66114f1e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -70,7 +70,7 @@ struct iwl_host_cmd;
struct iwl_cmd;
-#define IWLWIFI_VERSION "1.2.26k"
+#define IWLWIFI_VERSION "1.3.27k"
#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -86,28 +86,63 @@ struct iwl_hcmd_ops {
int (*rxon_assoc)(struct iwl_priv *priv);
};
struct iwl_hcmd_utils_ops {
- int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+ u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
+ u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
+ void (*gain_computation)(struct iwl_priv *priv,
+ u32 *average_noise,
+ u16 min_average_noise_antennat_i,
+ u32 min_average_noise);
+ void (*chain_noise_reset)(struct iwl_priv *priv);
+ void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
+ __le32 *tx_flags);
};
struct iwl_lib_ops {
- /* iwlwifi driver (priv) init */
- int (*init_drv)(struct iwl_priv *priv);
/* set hw dependant perameters */
int (*set_hw_params)(struct iwl_priv *priv);
-
+ /* ucode shared memory */
+ int (*alloc_shared_mem)(struct iwl_priv *priv);
+ void (*free_shared_mem)(struct iwl_priv *priv);
+ int (*shared_mem_rx_idx)(struct iwl_priv *priv);
+ /* Handling TX */
void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq,
+ struct iwl_tx_queue *txq,
u16 byte_cnt);
- /* nic init */
- int (*hw_nic_init)(struct iwl_priv *priv);
+ void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+ void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
+ /* aggregations */
+ int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
+ int sta_id, int tid, u16 ssn_idx);
+ int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
+ u8 tx_fifo);
+ /* setup Rx handler */
+ void (*rx_handler_setup)(struct iwl_priv *priv);
+ /* setup deferred work */
+ void (*setup_deferred_work)(struct iwl_priv *priv);
+ /* cancel deferred work */
+ void (*cancel_deferred_work)(struct iwl_priv *priv);
+ /* alive notification after init uCode load */
+ void (*init_alive_start)(struct iwl_priv *priv);
/* alive notification */
int (*alive_notify)(struct iwl_priv *priv);
/* check validity of rtc data address */
int (*is_valid_rtc_data_addr)(u32 addr);
/* 1st ucode load */
int (*load_ucode)(struct iwl_priv *priv);
- /* rfkill */
- void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio);
+ /* power management */
+ struct {
+ int (*init)(struct iwl_priv *priv);
+ int (*reset)(struct iwl_priv *priv);
+ void (*stop)(struct iwl_priv *priv);
+ void (*config)(struct iwl_priv *priv);
+ int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
+ } apm_ops;
+ /* power */
+ int (*set_power)(struct iwl_priv *priv, void *cmd);
+ int (*send_tx_power) (struct iwl_priv *priv);
+ void (*update_chain_flags)(struct iwl_priv *priv);
+ void (*temperature) (struct iwl_priv *priv);
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
};
@@ -124,15 +159,19 @@ struct iwl_mod_params {
int debug; /* def: 0 = minimal debug log messages */
int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
+ int num_of_ampdu_queues;/* def: HW dependent */
int enable_qos; /* def: 1 = use quality of service */
+ int disable_11n; /* def: 0 = disable 11n capabilities */
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
+ int restart_fw; /* def: 1 = restart firmware */
};
struct iwl_cfg {
const char *name;
const char *fw_name;
unsigned int sku;
+ int eeprom_size;
const struct iwl_ops *ops;
const struct iwl_mod_params *mod_params;
};
@@ -143,14 +182,113 @@ struct iwl_cfg {
struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
+void iwl_hw_detect(struct iwl_priv *priv);
-void iwlcore_clear_stations_table(struct iwl_priv *priv);
-void iwlcore_reset_qos(struct iwl_priv *priv);
-int iwlcore_set_rxon_channel(struct iwl_priv *priv,
+void iwl_clear_stations_table(struct iwl_priv *priv);
+void iwl_free_calib_results(struct iwl_priv *priv);
+void iwl_reset_qos(struct iwl_priv *priv);
+void iwl_set_rxon_chain(struct iwl_priv *priv);
+int iwl_set_rxon_channel(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel);
+void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
+u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
+ struct ieee80211_ht_info *sta_ht_inf);
+int iwl_hw_nic_init(struct iwl_priv *priv);
+int iwl_setup_mac(struct iwl_priv *priv);
+int iwl_set_hw_params(struct iwl_priv *priv);
+int iwl_init_drv(struct iwl_priv *priv);
+void iwl_uninit_drv(struct iwl_priv *priv);
+/* "keep warm" functions */
+int iwl_kw_init(struct iwl_priv *priv);
+int iwl_kw_alloc(struct iwl_priv *priv);
+void iwl_kw_free(struct iwl_priv *priv);
+
+/*****************************************************
+* RX
+******************************************************/
+void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
+int iwl_rx_queue_alloc(struct iwl_priv *priv);
+void iwl_rx_handle(struct iwl_priv *priv);
+int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
+ struct iwl_rx_queue *q);
+void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
+void iwl_rx_replenish(struct iwl_priv *priv);
+int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
+int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn);
+int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
+/* FIXME: remove when TX is moved to iwl core */
+int iwl_rx_queue_restock(struct iwl_priv *priv);
+int iwl_rx_queue_space(const struct iwl_rx_queue *q);
+void iwl_rx_allocate(struct iwl_priv *priv);
+void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
+int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
+/* Handlers */
+void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+
+/* TX helpers */
+
+/*****************************************************
+* TX
+******************************************************/
+int iwl_txq_ctx_reset(struct iwl_priv *priv);
+int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
+/* FIXME: remove when free Tx is fully merged into iwlcore */
+int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
+ dma_addr_t addr, u16 len);
+int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
+int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
+int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
+
+/*****************************************************
+ * TX power
+ ****************************************************/
+int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
+
+/*****************************************************
+ * RF -Kill - here and not in iwl-rfkill.h to be available when
+ * RF-kill subsystem is not compiled.
+ ****************************************************/
+void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
+int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
+
+/*******************************************************************************
+ * Rate
+ ******************************************************************************/
+
+void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
+ struct ieee80211_tx_info *info);
+int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
+
+static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
+{
+ return le32_to_cpu(rate_n_flags) & 0xFF;
+}
+static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
+{
+ return le32_to_cpu(rate_n_flags) & 0x1FFFF;
+}
+static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
+{
+ return cpu_to_le32(flags|(u32)rate);
+}
-int iwl_setup(struct iwl_priv *priv);
+/*******************************************************************************
+ * Scanning
+ ******************************************************************************/
+void iwl_init_scan_params(struct iwl_priv *priv);
+int iwl_scan_cancel(struct iwl_priv *priv);
+int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
+const char *iwl_escape_essid(const char *essid, u8 essid_len);
+int iwl_scan_initiate(struct iwl_priv *priv);
+void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
@@ -167,6 +305,17 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
int (*callback)(struct iwl_priv *priv,
struct iwl_cmd *cmd,
struct sk_buff *skb));
+
+int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+
+/*****************************************************
+* Error Handling Debugging
+******************************************************/
+void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+ u32 num_events, u32 mode);
+void iwl_dump_nic_error_log(struct iwl_priv *priv);
+void iwl_dump_nic_event_log(struct iwl_priv *priv);
+
/*************** DRIVER STATUS FUNCTIONS *****/
#define STATUS_HCMD_ACTIVE 0 /* host command in progress */
@@ -188,6 +337,7 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
#define STATUS_CONF_PENDING 18
+#define STATUS_MODE_PENDING 19
static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -209,10 +359,19 @@ static inline int iwl_is_init(struct iwl_priv *priv)
return test_bit(STATUS_INIT, &priv->status);
}
+static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
+{
+ return test_bit(STATUS_RF_KILL_SW, &priv->status);
+}
+
+static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
+{
+ return test_bit(STATUS_RF_KILL_HW, &priv->status);
+}
+
static inline int iwl_is_rfkill(struct iwl_priv *priv)
{
- return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status);
+ return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
}
static inline int iwl_is_ready_rf(struct iwl_priv *priv)
@@ -224,23 +383,27 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
return iwl_is_ready(priv);
}
-
-enum iwlcore_card_notify {
- IWLCORE_INIT_EVT = 0,
- IWLCORE_START_EVT = 1,
- IWLCORE_STOP_EVT = 2,
- IWLCORE_REMOVE_EVT = 3,
-};
-
-int iwlcore_low_level_notify(struct iwl_priv *priv,
- enum iwlcore_card_notify notify);
+extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
-int iwl_send_lq_cmd(struct iwl_priv *priv,
- struct iwl_link_quality_cmd *lq, u8 flags);
+extern int iwl_verify_ucode(struct iwl_priv *priv);
+extern int iwl_send_lq_cmd(struct iwl_priv *priv,
+ struct iwl_link_quality_cmd *lq, u8 flags);
+extern void iwl_rx_reply_rx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->rxon_assoc(priv);
}
+static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
+ struct iwl_priv *priv, enum ieee80211_band band)
+{
+ return priv->hw->wiphy->bands[band];
+}
+
#endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 12725796ea5..545ed692d88 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -87,16 +87,16 @@
/* EEPROM reads */
#define CSR_EEPROM_REG (CSR_BASE+0x02c)
#define CSR_EEPROM_GP (CSR_BASE+0x030)
+#define CSR_GIO_REG (CSR_BASE+0x03C)
#define CSR_GP_UCODE (CSR_BASE+0x044)
#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060)
-#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
#define CSR_LED_REG (CSR_BASE+0x094)
+#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
-/* Analog phase-lock-loop configuration (3945 only)
- * Set bit 24. */
+/* Analog phase-lock-loop configuration */
#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
/*
* Indicates hardware rev, to determine CCK backoff for txpower calculation.
@@ -107,9 +107,9 @@
/* Bits for CSR_HW_IF_CONFIG_REG */
#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
-#define CSR49_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)
-#define CSR49_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
-#define CSR49_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
+#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00)
+#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
+#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100)
#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200)
@@ -170,6 +170,10 @@
#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \
CSR_FH_INT_BIT_TX_CHNL0)
+/* GPIO */
+#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
+#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000)
+#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC (0x00000200)
/* RESET */
#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001)
@@ -191,6 +195,16 @@
#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000)
+/* HW REV */
+#define CSR_HW_REV_TYPE_MSK (0x00000F0)
+#define CSR_HW_REV_TYPE_3945 (0x00000D0)
+#define CSR_HW_REV_TYPE_4965 (0x0000000)
+#define CSR_HW_REV_TYPE_5300 (0x0000020)
+#define CSR_HW_REV_TYPE_5350 (0x0000030)
+#define CSR_HW_REV_TYPE_5100 (0x0000050)
+#define CSR_HW_REV_TYPE_5150 (0x0000040)
+#define CSR_HW_REV_TYPE_NONE (0x00000F0)
+
/* EEPROM REG */
#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001)
#define CSR_EEPROM_REG_BIT_CMD (0x00000002)
@@ -200,17 +214,15 @@
#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000)
#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180)
+/* CSR GIO */
+#define CSR_GIO_REG_VAL_L0S_ENABLED (0x00000002)
+
/* UCODE DRV GP */
#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001)
#define CSR_UCODE_SW_BIT_RFKILL (0x00000002)
#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
-/* GPIO */
-#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200)
-#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000)
-#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER
-
/* GI Chicken Bits */
#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
@@ -220,6 +232,10 @@
#define CSR_LED_REG_TRUN_ON (0x78)
#define CSR_LED_REG_TRUN_OFF (0x38)
+/* ANA_PLL */
+#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
+#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
+
/*=== HBUS (Host-side Bus) ===*/
#define HBUS_BASE (0x400)
/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index c60724c21db..58384805a49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -30,37 +30,35 @@
#define __iwl_debug_h__
#ifdef CONFIG_IWLWIFI_DEBUG
-extern u32 iwl_debug_level;
#define IWL_DEBUG(level, fmt, args...) \
-do { if (iwl_debug_level & (level)) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
+do { if (priv->debug_level & (level)) \
+ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((iwl_debug_level & (level)) && net_ratelimit()) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
+do { if ((priv->debug_level & (level)) && net_ratelimit()) \
+ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
-static inline void iwl_print_hex_dump(int level, void *p, u32 len)
-{
- if (!(iwl_debug_level & level))
- return;
-
- print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
- p, len, 1);
-}
-
#ifdef CONFIG_IWLWIFI_DEBUGFS
struct iwl_debugfs {
const char *name;
struct dentry *dir_drv;
struct dentry *dir_data;
- struct dir_data_files{
+ struct dentry *dir_rf;
+ struct dir_data_files {
struct dentry *file_sram;
+ struct dentry *file_eeprom;
struct dentry *file_stations;
struct dentry *file_rx_statistics;
struct dentry *file_tx_statistics;
+ struct dentry *file_log_event;
} dbgfs_data_files;
+ struct dir_rf_files {
+ struct dentry *file_disable_sensitivity;
+ struct dentry *file_disable_chain_noise;
+ struct dentry *file_disable_tx_power;
+ } dbgfs_rf_files;
u32 sram_offset;
u32 sram_len;
};
@@ -76,9 +74,6 @@ static inline void IWL_DEBUG(int level, const char *fmt, ...)
static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
{
}
-static inline void iwl_print_hex_dump(int level, void *p, u32 len)
-{
-}
#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 9a30e1df311..ed948dc59b3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -34,7 +34,7 @@
#include <net/mac80211.h>
-#include "iwl-4965.h"
+#include "iwl-dev.h"
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
@@ -55,6 +55,13 @@
goto err; \
} while (0)
+#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
+ dbgfs->dbgfs_##parent##_files.file_##name = \
+ debugfs_create_bool(#name, 0644, dbgfs->dir_##parent, ptr); \
+ if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)) \
+ goto err; \
+} while (0)
+
#define DEBUGFS_REMOVE(name) do { \
debugfs_remove(name); \
name = NULL; \
@@ -85,6 +92,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.open = iwl_dbgfs_open_file_generic, \
};
+#define DEBUGFS_WRITE_FILE_OPS(name) \
+ DEBUGFS_WRITE_FUNC(name); \
+static const struct file_operations iwl_dbgfs_##name##_ops = { \
+ .write = iwl_dbgfs_##name##_write, \
+ .open = iwl_dbgfs_open_file_generic, \
+};
+
+
#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
DEBUGFS_READ_FUNC(name); \
DEBUGFS_WRITE_FUNC(name); \
@@ -206,7 +221,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
- struct iwl4965_station_entry *station;
+ struct iwl_station_entry *station;
int max_sta = priv->hw_params.max_stations;
char *buf;
int i, j, pos = 0;
@@ -240,21 +255,18 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
pos += scnprintf(buf + pos, bufsz - pos,
"seq_num\t\ttxq_id");
-#ifdef CONFIG_IWL4965_HT
pos += scnprintf(buf + pos, bufsz - pos,
"\tframe_count\twait_for_ba\t");
pos += scnprintf(buf + pos, bufsz - pos,
"start_idx\tbitmap0\t");
pos += scnprintf(buf + pos, bufsz - pos,
"bitmap1\trate_n_flags");
-#endif
pos += scnprintf(buf + pos, bufsz - pos, "\n");
for (j = 0; j < MAX_TID_COUNT; j++) {
pos += scnprintf(buf + pos, bufsz - pos,
"[%d]:\t\t%u", j,
station->tid[j].seq_number);
-#ifdef CONFIG_IWL4965_HT
pos += scnprintf(buf + pos, bufsz - pos,
"\t%u\t\t%u\t\t%u\t\t",
station->tid[j].agg.txq_id,
@@ -265,7 +277,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
station->tid[j].agg.start_idx,
(unsigned long long)station->tid[j].agg.bitmap,
station->tid[j].agg.rate_n_flags);
-#endif
pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
pos += scnprintf(buf + pos, bufsz - pos, "\n");
@@ -277,8 +288,70 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
return ret;
}
+static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
+ char __user *user_buf,
+ size_t count,
+ loff_t *ppos)
+{
+ ssize_t ret;
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ int pos = 0, ofs = 0, buf_size = 0;
+ const u8 *ptr;
+ char *buf;
+ size_t eeprom_len = priv->cfg->eeprom_size;
+ buf_size = 4 * eeprom_len + 256;
+
+ if (eeprom_len % 16) {
+ IWL_ERROR("EEPROM size is not multiple of 16.\n");
+ return -ENODATA;
+ }
+
+ /* 4 characters for byte 0xYY */
+ buf = kzalloc(buf_size, GFP_KERNEL);
+ if (!buf) {
+ IWL_ERROR("Can not allocate Buffer\n");
+ return -ENOMEM;
+ }
+
+ ptr = priv->eeprom;
+ for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
+ pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
+ hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
+ buf_size - pos, 0);
+ pos += strlen(buf);
+ if (buf_size - pos > 0)
+ buf[pos++] = '\n';
+ }
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+ kfree(buf);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_log_event_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_priv *priv = file->private_data;
+ u32 event_log_flag;
+ char buf[8];
+ int buf_size;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+ if (sscanf(buf, "%d", &event_log_flag) != 1)
+ return -EFAULT;
+ if (event_log_flag == 1)
+ iwl_dump_nic_event_log(priv);
+
+ return count;
+}
DEBUGFS_READ_WRITE_FILE_OPS(sram);
+DEBUGFS_WRITE_FILE_OPS(log_event);
+DEBUGFS_READ_FILE_OPS(eeprom);
DEBUGFS_READ_FILE_OPS(stations);
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
@@ -290,6 +363,7 @@ DEBUGFS_READ_FILE_OPS(tx_statistics);
int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
{
struct iwl_debugfs *dbgfs;
+ struct dentry *phyd = priv->hw->wiphy->debugfsdir;
dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
if (!dbgfs) {
@@ -298,17 +372,23 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
priv->dbgfs = dbgfs;
dbgfs->name = name;
- dbgfs->dir_drv = debugfs_create_dir(name, NULL);
+ dbgfs->dir_drv = debugfs_create_dir(name, phyd);
if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){
goto err;
}
DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
+ DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
+ DEBUGFS_ADD_FILE(eeprom, data);
DEBUGFS_ADD_FILE(sram, data);
+ DEBUGFS_ADD_FILE(log_event, data);
DEBUGFS_ADD_FILE(stations, data);
DEBUGFS_ADD_FILE(rx_statistics, data);
DEBUGFS_ADD_FILE(tx_statistics, data);
-
+ DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
+ DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
+ &priv->disable_chain_noise_cal);
+ DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal);
return 0;
err:
@@ -327,11 +407,17 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
if (!(priv->dbgfs))
return;
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
+ DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
kfree(priv->dbgfs);
priv->dbgfs = NULL;
@@ -339,3 +425,4 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
EXPORT_SYMBOL(iwl_dbgfs_unregister);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 581b98556c8..4d789e353e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -24,13 +24,13 @@
*
*****************************************************************************/
/*
- * Please use this file (iwl-4965.h) for driver implementation definitions.
- * Please use iwl-4965-commands.h for uCode API definitions.
+ * Please use this file (iwl-dev.h) for driver implementation definitions.
+ * Please use iwl-commands.h for uCode API definitions.
* Please use iwl-4965-hw.h for hardware-related definitions.
*/
-#ifndef __iwl_4965_h__
-#define __iwl_4965_h__
+#ifndef __iwl_dev_h__
+#define __iwl_dev_h__
#include <linux/pci.h> /* for struct pci_device_id */
#include <linux/kernel.h>
@@ -44,16 +44,18 @@
#include "iwl-prph.h"
#include "iwl-debug.h"
#include "iwl-led.h"
+#include "iwl-power.h"
/* configuration for the iwl4965 */
extern struct iwl_cfg iwl4965_agn_cfg;
+extern struct iwl_cfg iwl5300_agn_cfg;
+extern struct iwl_cfg iwl5100_agn_cfg;
+extern struct iwl_cfg iwl5350_agn_cfg;
+extern struct iwl_cfg iwl5100_bg_cfg;
+extern struct iwl_cfg iwl5100_abg_cfg;
-/* Change firmware file name, using "-" and incrementing number,
- * *only* when uCode interface or architecture changes so that it
- * is not compatible with earlier drivers.
- * This number will also appear in << 8 position of 1st dword of uCode file */
-#define IWL4965_UCODE_API "-1"
-
+/* CT-KILL constants */
+#define CT_KILL_THRESHOLD 110 /* in Celsius */
/* Default noise level to report when noise measurement is not available.
* This may be because we're:
@@ -68,12 +70,6 @@ extern struct iwl_cfg iwl4965_agn_cfg;
* averages within an s8's (used in some apps) range of negative values. */
#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
-enum iwl4965_antenna {
- IWL_ANTENNA_DIVERSITY,
- IWL_ANTENNA_MAIN,
- IWL_ANTENNA_AUX
-};
-
/*
* RTS threshold here is total size [2347] minus 4 FCS bytes
* Per spec:
@@ -91,7 +87,7 @@ enum iwl4965_antenna {
#define DEFAULT_SHORT_RETRY_LIMIT 7U
#define DEFAULT_LONG_RETRY_LIMIT 4U
-struct iwl4965_rx_mem_buffer {
+struct iwl_rx_mem_buffer {
dma_addr_t dma_addr;
struct sk_buff *skb;
struct list_head list;
@@ -102,7 +98,7 @@ struct iwl4965_rx_mem_buffer {
*
* Contains common data for Rx and Tx queues
*/
-struct iwl4965_queue {
+struct iwl_queue {
int n_bd; /* number of BDs in this queue */
int write_ptr; /* 1-st empty entry (index) host_w*/
int read_ptr; /* last used entry (index) host_r*/
@@ -118,13 +114,12 @@ struct iwl4965_queue {
#define MAX_NUM_OF_TBS (20)
/* One for each TFD */
-struct iwl4965_tx_info {
- struct ieee80211_tx_status status;
+struct iwl_tx_info {
struct sk_buff *skb[MAX_NUM_OF_TBS];
};
/**
- * struct iwl4965_tx_queue - Tx Queue for DMA
+ * struct iwl_tx_queue - Tx Queue for DMA
* @q: generic Rx/Tx queue descriptor
* @bd: base of circular buffer of TFDs
* @cmd: array of command/Tx buffers
@@ -136,12 +131,12 @@ struct iwl4965_tx_info {
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
* descriptors) and required locking structures.
*/
-struct iwl4965_tx_queue {
- struct iwl4965_queue q;
- struct iwl4965_tfd_frame *bd;
+struct iwl_tx_queue {
+ struct iwl_queue q;
+ struct iwl_tfd_frame *bd;
struct iwl_cmd *cmd;
dma_addr_t dma_addr_cmd;
- struct iwl4965_tx_info *txb;
+ struct iwl_tx_info *txb;
int need_update;
int sched_retry;
int active;
@@ -158,50 +153,17 @@ struct iwl4965_channel_tgh_info {
s64 last_radar_time;
};
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl4965_channel_power_info {
- struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 base_power_index; /* gain index for power at factory temp. */
- s8 requested_power; /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl4965_scan_power_info {
- struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
-};
-
-/* For fat_extension_channel */
-enum {
- HT_IE_EXT_CHANNEL_NONE = 0,
- HT_IE_EXT_CHANNEL_ABOVE,
- HT_IE_EXT_CHANNEL_INVALID,
- HT_IE_EXT_CHANNEL_BELOW,
- HT_IE_EXT_CHANNEL_MAX
-};
-
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
* with one another!
*/
-#define IWL4965_MAX_RATE (33)
-
struct iwl_channel_info {
struct iwl4965_channel_tgd_info tgd;
struct iwl4965_channel_tgh_info tgh;
- struct iwl4965_eeprom_channel eeprom; /* EEPROM regulatory limit */
- struct iwl4965_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
- * FAT channel */
+ struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */
+ struct iwl_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
+ * FAT channel */
u8 channel; /* channel number */
u8 flags; /* flags copied from EEPROM */
@@ -214,11 +176,6 @@ struct iwl_channel_info {
u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
enum ieee80211_band band;
- /* Radio/DSP gain settings for each "normal" data Tx rate.
- * These include, in addition to RF and DSP gain, a few fields for
- * remembering/modifying gain settings (indexes). */
- struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE];
-
/* FAT channel info */
s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */
@@ -226,9 +183,6 @@ struct iwl_channel_info {
s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */
u8 fat_flags; /* flags copied from EEPROM */
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-
- /* Radio/DSP gain settings for each scan rate, for directed scans. */
- struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
};
struct iwl4965_clip_group {
@@ -252,29 +206,9 @@ struct iwl4965_clip_group {
/* Power management (not Tx power) structures */
-struct iwl4965_power_vec_entry {
- struct iwl4965_powertable_cmd cmd;
- u8 no_dtim;
-};
-#define IWL_POWER_RANGE_0 (0)
-#define IWL_POWER_RANGE_1 (1)
-
-#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3 0x03
-#define IWL_POWER_INDEX_5 0x05
-#define IWL_POWER_AC 0x06
-#define IWL_POWER_BATTERY 0x07
-#define IWL_POWER_LIMIT 0x07
-#define IWL_POWER_MASK 0x0F
-#define IWL_POWER_ENABLED 0x10
-#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK)
-
-struct iwl4965_power_mgr {
- spinlock_t lock;
- struct iwl4965_power_vec_entry pwr_range_0[IWL_POWER_AC];
- struct iwl4965_power_vec_entry pwr_range_1[IWL_POWER_AC];
- u8 active_index;
- u32 dtim_val;
+enum iwl_pwr_src {
+ IWL_PWR_SRC_VMAIN,
+ IWL_PWR_SRC_VAUX,
};
#define IEEE80211_DATA_LEN 2304
@@ -282,7 +216,7 @@ struct iwl4965_power_mgr {
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-struct iwl4965_frame {
+struct iwl_frame {
union {
struct ieee80211_hdr frame;
struct iwl4965_tx_beacon_cmd beacon;
@@ -328,6 +262,8 @@ struct iwl_cmd_meta {
} __attribute__ ((packed));
+#define IWL_CMD_MAX_PAYLOAD 320
+
/**
* struct iwl_cmd
*
@@ -339,8 +275,8 @@ struct iwl_cmd {
struct iwl_cmd_meta meta; /* driver data */
struct iwl_cmd_header hdr; /* uCode API */
union {
- struct iwl4965_addsta_cmd addsta;
- struct iwl4965_led_cmd led;
+ struct iwl_addsta_cmd addsta;
+ struct iwl_led_cmd led;
u32 flags;
u8 val8;
u16 val16;
@@ -348,12 +284,13 @@ struct iwl_cmd {
struct iwl4965_bt_cmd bt;
struct iwl4965_rxon_time_cmd rxon_time;
struct iwl4965_powertable_cmd powertable;
- struct iwl4965_qosparam_cmd qosparam;
- struct iwl4965_tx_cmd tx;
+ struct iwl_qosparam_cmd qosparam;
+ struct iwl_tx_cmd tx;
struct iwl4965_tx_beacon_cmd tx_beacon;
struct iwl4965_rxon_assoc_cmd rxon_assoc;
+ struct iwl_rem_sta_cmd rm_sta;
u8 *indirect;
- u8 payload[360];
+ u8 payload[IWL_CMD_MAX_PAYLOAD];
} __attribute__ ((packed)) cmd;
} __attribute__ ((packed));
@@ -378,7 +315,7 @@ struct iwl_host_cmd {
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
/**
- * struct iwl4965_rx_queue - Rx queue
+ * struct iwl_rx_queue - Rx queue
* @processed: Internal index to last handled Rx packet
* @read: Shared index to newest available Rx buffer
* @write: Shared index to oldest written Rx packet
@@ -387,13 +324,13 @@ struct iwl_host_cmd {
* @rx_used: List of Rx buffers with no SKB
* @need_update: flag to indicate we need to update read/write index
*
- * NOTE: rx_free and rx_used are used as a FIFO for iwl4965_rx_mem_buffers
+ * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
*/
-struct iwl4965_rx_queue {
+struct iwl_rx_queue {
__le32 *bd;
dma_addr_t dma_addr;
- struct iwl4965_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
- struct iwl4965_rx_mem_buffer *queue[RX_QUEUE_SIZE];
+ struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
+ struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
u32 processed;
u32 read;
u32 write;
@@ -419,9 +356,8 @@ struct iwl4965_rx_queue {
#define IWL_INVALID_RATE 0xFF
#define IWL_INVALID_VALUE -1
-#ifdef CONFIG_IWL4965_HT
/**
- * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack
+ * struct iwl_ht_agg -- aggregation status while waiting for block-ack
* @txq_id: Tx queue used for Tx attempt
* @frame_count: # frames attempted by Tx command
* @wait_for_ba: Expect block-ack before next Tx reply
@@ -434,7 +370,7 @@ struct iwl4965_rx_queue {
* for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info
* until block ack arrives.
*/
-struct iwl4965_ht_agg {
+struct iwl_ht_agg {
u16 txq_id;
u16 frame_count;
u16 wait_for_ba;
@@ -448,21 +384,17 @@ struct iwl4965_ht_agg {
u8 state;
};
-#endif /* CONFIG_IWL4965_HT */
-struct iwl4965_tid_data {
+struct iwl_tid_data {
u16 seq_number;
u16 tfds_in_queue;
-#ifdef CONFIG_IWL4965_HT
- struct iwl4965_ht_agg agg;
-#endif /* CONFIG_IWL4965_HT */
+ struct iwl_ht_agg agg;
};
-struct iwl4965_hw_key {
+struct iwl_hw_key {
enum ieee80211_key_alg alg;
int keylen;
u8 keyidx;
- struct ieee80211_key_conf *conf;
u8 key[32];
};
@@ -474,7 +406,6 @@ union iwl4965_ht_rate_supp {
};
};
-#ifdef CONFIG_IWL4965_HT
#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3)
#define CFG_HT_MPDU_DENSITY_2USEC (0x5)
#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC
@@ -497,9 +428,8 @@ struct iwl_ht_info {
u8 ht_protection;
u8 non_GF_STA_present;
};
-#endif /*CONFIG_IWL4965_HT */
-union iwl4965_qos_capabity {
+union iwl_qos_capabity {
struct {
u8 edca_count:4; /* bit 0-3 */
u8 q_ack:1; /* bit 4 */
@@ -520,22 +450,22 @@ union iwl4965_qos_capabity {
};
/* QoS structures */
-struct iwl4965_qos_info {
+struct iwl_qos_info {
int qos_enable;
int qos_active;
- union iwl4965_qos_capabity qos_cap;
- struct iwl4965_qosparam_cmd def_qos_parm;
+ union iwl_qos_capabity qos_cap;
+ struct iwl_qosparam_cmd def_qos_parm;
};
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
-struct iwl4965_station_entry {
- struct iwl4965_addsta_cmd sta;
- struct iwl4965_tid_data tid[MAX_TID_COUNT];
+struct iwl_station_entry {
+ struct iwl_addsta_cmd sta;
+ struct iwl_tid_data tid[MAX_TID_COUNT];
u8 used;
u8 ps_status;
- struct iwl4965_hw_key keyinfo;
+ struct iwl_hw_key keyinfo;
};
/* one for each uCode image (inst/data, boot/init/runtime) */
@@ -546,7 +476,7 @@ struct fw_desc {
};
/* uCode file layout */
-struct iwl4965_ucode {
+struct iwl_ucode {
__le32 ver; /* major/minor/subminor */
__le32 inst_size; /* bytes of runtime instructions */
__le32 data_size; /* bytes of runtime data */
@@ -556,8 +486,6 @@ struct iwl4965_ucode {
u8 data[0]; /* data in same order as "size" elements */
};
-#define IWL_IBSS_MAC_HASH_SIZE 32
-
struct iwl4965_ibss_seq {
u8 mac[ETH_ALEN];
u16 seq_num;
@@ -566,20 +494,52 @@ struct iwl4965_ibss_seq {
struct list_head list;
};
+struct iwl_sensitivity_ranges {
+ u16 min_nrg_cck;
+ u16 max_nrg_cck;
+
+ u16 nrg_th_cck;
+ u16 nrg_th_ofdm;
+
+ u16 auto_corr_min_ofdm;
+ u16 auto_corr_min_ofdm_mrc;
+ u16 auto_corr_min_ofdm_x1;
+ u16 auto_corr_min_ofdm_mrc_x1;
+
+ u16 auto_corr_max_ofdm;
+ u16 auto_corr_max_ofdm_mrc;
+ u16 auto_corr_max_ofdm_x1;
+ u16 auto_corr_max_ofdm_mrc_x1;
+
+ u16 auto_corr_max_cck;
+ u16 auto_corr_max_cck_mrc;
+ u16 auto_corr_min_cck;
+ u16 auto_corr_min_cck_mrc;
+};
+
+
+#define IWL_FAT_CHANNEL_52 BIT(IEEE80211_BAND_5GHZ)
+
/**
* struct iwl_hw_params
* @max_txq_num: Max # Tx queues supported
- * @tx_cmd_len: Size of Tx command (but not including frame itself)
- * @tx_ant_num: Number of TX antennas
+ * @tx/rx_chains_num: Number of TX/RX chains
+ * @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
- * @rx_buffer_size:
* @max_rxq_log: Log-base-2 of max_rxq_size
+ * @rx_buf_size: Rx buffer size
* @max_stations:
* @bcast_sta_id:
+ * @fat_channel: is 40MHz width possible in band 2.4
+ * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ)
+ * @sw_crypto: 0 for hw, 1 for sw
+ * @max_xxx_size: for ucode uses
+ * @ct_kill_threshold: temperature threshold
+ * @struct iwl_sensitivity_ranges: range of sensitivity values
+ * @first_ampdu_q: first HW queue available for ampdu
*/
struct iwl_hw_params {
u16 max_txq_num;
- u16 tx_cmd_len;
u8 tx_chains_num;
u8 rx_chains_num;
u8 valid_tx_ant;
@@ -590,10 +550,18 @@ struct iwl_hw_params {
u32 max_pkt_size;
u8 max_stations;
u8 bcast_sta_id;
+ u8 fat_channel;
+ u8 sw_crypto;
+ u32 max_inst_size;
+ u32 max_data_size;
+ u32 max_bsm_size;
+ u32 ct_kill_threshold; /* value in hw-dependent units */
+ const struct iwl_sensitivity_ranges *sens;
+ u8 first_ampdu_q;
};
-#define HT_SHORT_GI_20MHZ_ONLY (1 << 0)
-#define HT_SHORT_GI_40MHZ_ONLY (1 << 1)
+#define HT_SHORT_GI_20MHZ (1 << 0)
+#define HT_SHORT_GI_40MHZ (1 << 1)
#define IWL_RX_HDR(x) ((struct iwl4965_rx_frame_hdr *)(\
@@ -612,51 +580,18 @@ struct iwl_hw_params {
* for use by iwl-*.c
*
*****************************************************************************/
-struct iwl4965_addsta_cmd;
-extern int iwl4965_send_add_station(struct iwl_priv *priv,
- struct iwl4965_addsta_cmd *sta, u8 flags);
-extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr,
- int is_ap, u8 flags, void *ht_data);
-extern int iwl4965_is_network_packet(struct iwl_priv *priv,
- struct ieee80211_hdr *header);
-extern int iwl4965_power_init_handle(struct iwl_priv *priv);
-extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb,
- void *data, short len,
- struct ieee80211_rx_status *stats,
- u16 phy_flags);
-extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv,
- struct ieee80211_hdr *header);
-extern int iwl4965_rx_queue_alloc(struct iwl_priv *priv);
-extern void iwl4965_rx_queue_reset(struct iwl_priv *priv,
- struct iwl4965_rx_queue *rxq);
-extern int iwl4965_calc_db_from_ratio(int sig_ratio);
-extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);
-extern int iwl4965_tx_queue_init(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq, int count, u32 id);
-extern void iwl4965_rx_replenish(void *data);
-extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq);
+struct iwl_addsta_cmd;
+extern int iwl_send_add_sta(struct iwl_priv *priv,
+ struct iwl_addsta_cmd *sta, u8 flags);
+u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
+ u8 flags, struct ieee80211_ht_info *ht_info);
extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
const u8 *dest, int left);
-extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv,
- struct iwl4965_rx_queue *q);
-extern void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
- u32 decrypt_res,
- struct ieee80211_rx_status *stats);
-extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr);
-int iwl4965_init_geos(struct iwl_priv *priv);
-void iwl4965_free_geos(struct iwl_priv *priv);
-
-extern const u8 iwl4965_broadcast_addr[ETH_ALEN];
-int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
+int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
-/*
- * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
- * call this... todo... fix that.
-*/
-extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,
- u16 tx_rate, u8 flags);
+extern const u8 iwl_bcast_addr[ETH_ALEN];
/******************************************************************************
*
@@ -674,96 +609,51 @@ extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,
* iwl4965_mac_ <-- mac80211 callback
*
****************************************************************************/
-extern void iwl4965_hw_rx_handler_setup(struct iwl_priv *priv);
-extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv);
-extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv);
-extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv);
-extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);
-extern int iwl4965_hw_nic_init(struct iwl_priv *priv);
-extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv);
-extern void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv);
-extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv);
-extern int iwl4965_hw_nic_reset(struct iwl_priv *priv);
-extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
- dma_addr_t addr, u16 len);
-extern int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq);
-extern int iwl4965_hw_get_temperature(struct iwl_priv *priv);
-extern int iwl4965_hw_tx_queue_init(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq);
+extern int iwl_rxq_stop(struct iwl_priv *priv);
+extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
- struct iwl4965_frame *frame, u8 rate);
-extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv);
-extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
- struct iwl_cmd *cmd,
- struct ieee80211_tx_control *ctrl,
- struct ieee80211_hdr *hdr,
- int sta_id, int tx_id);
-extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv);
-extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
-extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb);
+ struct iwl_frame *frame, u8 rate);
extern void iwl4965_disable_events(struct iwl_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl_priv *priv);
-
-/**
- * iwl4965_hw_find_station - Find station id for a given BSSID
- * @bssid: MAC address of station ID to find
- *
- * NOTE: This should not be hardware specific but the code has
- * not yet been merged into a single common layer for managing the
- * station tables.
- */
-extern u8 iwl4965_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);
-extern int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
-extern int iwl4965_queue_space(const struct iwl4965_queue *q);
+extern int iwl_queue_space(const struct iwl_queue *q);
+static inline int iwl_queue_used(const struct iwl_queue *q, int i)
+{
+ return q->write_ptr > q->read_ptr ?
+ (i >= q->read_ptr && i < q->write_ptr) :
+ !(i < q->read_ptr && i >= q->write_ptr);
+}
+
+
+static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
+{
+ /* This is for scan command, the big buffer at end of command array */
+ if (is_huge)
+ return q->n_window; /* must be power of 2 */
+
+ /* Otherwise, use normal size buffers */
+ return index & (q->n_window - 1);
+}
+
+
struct iwl_priv;
-extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);
/*
* Forward declare iwl-4965.c functions for iwl-base.c
*/
-extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq,
- u16 byte_cnt);
-extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr,
- int is_ap);
-extern void iwl4965_set_rxon_chain(struct iwl_priv *priv);
-extern int iwl4965_alive_notify(struct iwl_priv *priv);
-extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
-extern void iwl4965_chain_noise_reset(struct iwl_priv *priv);
-extern void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags,
- u8 force);
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
-extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
- u32 rate_n_flags,
- struct ieee80211_tx_control *control);
-
-#ifdef CONFIG_IWL4965_HT
-void iwl4965_init_ht_hw_capab(struct iwl_priv *priv,
- struct ieee80211_ht_info *ht_info,
- enum ieee80211_band band);
-void iwl4965_set_rxon_ht(struct iwl_priv *priv,
- struct iwl_ht_info *ht_info);
-void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index,
- struct ieee80211_ht_info *sta_ht_inf);
+
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn);
int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
u8 tid, int txq_id);
-#else
-static inline void iwl4965_init_ht_hw_capab(struct iwl_priv *priv,
- struct ieee80211_ht_info *ht_info,
- enum ieee80211_band band) {}
-#endif /*CONFIG_IWL4965_HT */
/* Structures, enum, and defines specific to the 4965 */
-#define IWL4965_KW_SIZE 0x1000 /*4k */
+#define IWL_KW_SIZE 0x1000 /*4k */
-struct iwl4965_kw {
+struct iwl_kw {
dma_addr_t dma_addr;
void *v_addr;
size_t size;
@@ -782,13 +672,8 @@ struct iwl4965_kw {
#define IWL_OPERATION_MODE_MIXED 2
#define IWL_OPERATION_MODE_20MHZ 3
-#define IWL_EXT_CHANNEL_OFFSET_NONE 0
-#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1
-#define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2
-#define IWL_EXT_CHANNEL_OFFSET_BELOW 3
-
-#define NRG_NUM_PREV_STAT_L 20
-#define NUM_RX_CHAINS (3)
+#define IWL_TX_CRC_SIZE 4
+#define IWL_TX_DELIMITER_SIZE 4
#define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000
@@ -802,7 +687,6 @@ struct iwl4965_lq_mngr {
unsigned long stamp_last;
u32 flush_time;
u32 tx_packets;
- u8 lq_ready;
};
/* Sensitivity and chain noise calibration */
@@ -818,23 +702,8 @@ struct iwl4965_lq_mngr {
#define MAX_FA_CCK 50
#define MIN_FA_CCK 5
-#define NRG_MIN_CCK 97
-#define NRG_MAX_CCK 0
-
-#define AUTO_CORR_MIN_OFDM 85
-#define AUTO_CORR_MIN_OFDM_MRC 170
-#define AUTO_CORR_MIN_OFDM_X1 105
-#define AUTO_CORR_MIN_OFDM_MRC_X1 220
-#define AUTO_CORR_MAX_OFDM 120
-#define AUTO_CORR_MAX_OFDM_MRC 210
-#define AUTO_CORR_MAX_OFDM_X1 140
-#define AUTO_CORR_MAX_OFDM_MRC_X1 270
#define AUTO_CORR_STEP_OFDM 1
-#define AUTO_CORR_MIN_CCK (125)
-#define AUTO_CORR_MAX_CCK (200)
-#define AUTO_CORR_MIN_CCK_MRC 200
-#define AUTO_CORR_MAX_CCK_MRC 400
#define AUTO_CORR_STEP_CCK 3
#define AUTO_CORR_MAX_TH_CCK 160
@@ -853,6 +722,9 @@ struct iwl4965_lq_mngr {
#define IN_BAND_FILTER 0xFF
#define MIN_AVERAGE_NOISE_MAX_VALUE 0xFFFFFFFF
+#define NRG_NUM_PREV_STAT_L 20
+#define NUM_RX_CHAINS 3
+
enum iwl4965_false_alarm_state {
IWL_FA_TOO_MANY = 0,
IWL_FA_TOO_FEW = 1,
@@ -865,11 +737,6 @@ enum iwl4965_chain_noise_state {
IWL_CHAIN_NOISE_CALIBRATED = 2,
};
-enum iwl4965_sensitivity_state {
- IWL_SENS_CALIB_ALLOWED = 0,
- IWL_SENS_CALIB_NEED_REINIT = 1,
-};
-
enum iwl4965_calib_enabled_state {
IWL_CALIB_DISABLED = 0, /* must be 0 */
IWL_CALIB_ENABLED = 1,
@@ -884,8 +751,23 @@ struct statistics_general_data {
u32 beacon_energy_c;
};
+struct iwl_calib_results {
+ void *tx_iq_res;
+ void *tx_iq_perd_res;
+ void *lo_res;
+ u32 tx_iq_res_len;
+ u32 tx_iq_perd_res_len;
+ u32 lo_res_len;
+};
+
+enum ucode_type {
+ UCODE_NONE = 0,
+ UCODE_INIT,
+ UCODE_RT
+};
+
/* Sensitivity calib data */
-struct iwl4965_sensitivity_data {
+struct iwl_sensitivity_data {
u32 auto_corr_ofdm;
u32 auto_corr_ofdm_mrc;
u32 auto_corr_ofdm_x1;
@@ -909,12 +791,10 @@ struct iwl4965_sensitivity_data {
s32 nrg_auto_corr_silence_diff;
u32 num_in_cck_no_fa;
u32 nrg_th_ofdm;
-
- u8 state;
};
/* Chain noise (differential Rx gain) calib data */
-struct iwl4965_chain_noise_data {
+struct iwl_chain_noise_data {
u8 state;
u16 beacon_count;
u32 chain_noise_a;
@@ -960,7 +840,7 @@ struct iwl_priv {
bool add_radiotap;
void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb);
+ struct iwl_rx_mem_buffer *rxb);
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
@@ -985,6 +865,9 @@ struct iwl_priv {
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
+ /* init calibration results */
+ struct iwl_calib_results calib_results;
+
/* Scan related variables */
unsigned long last_scan_jiffies;
unsigned long next_scan_jiffies;
@@ -995,7 +878,8 @@ struct iwl_priv {
int one_direct_scan;
u8 direct_ssid_len;
u8 direct_ssid[IW_ESSID_MAX_SIZE];
- struct iwl4965_scan_cmd *scan;
+ struct iwl_scan_cmd *scan;
+ u32 scan_tx_ant[IEEE80211_NUM_BANDS];
/* spinlock */
spinlock_t lock; /* protect general shared data */
@@ -1007,6 +891,9 @@ struct iwl_priv {
/* pci hardware address support */
void __iomem *hw_base;
+ u32 hw_rev;
+ u32 hw_wa_rev;
+ u8 rev_id;
/* uCode images, save to reload in case of failure */
struct fw_desc ucode_code; /* runtime inst */
@@ -1015,6 +902,8 @@ struct iwl_priv {
struct fw_desc ucode_init; /* initialization inst */
struct fw_desc ucode_init_data; /* initialization data */
struct fw_desc ucode_boot; /* bootstrap inst */
+ enum ucode_type ucode_type;
+ u8 ucode_write_complete; /* the image write is complete */
struct iwl4965_rxon_time_cmd rxon_timing;
@@ -1023,22 +912,22 @@ struct iwl_priv {
* changed via explicit cast within the
* routines that actually update the physical
* hardware */
- const struct iwl4965_rxon_cmd active_rxon;
- struct iwl4965_rxon_cmd staging_rxon;
+ const struct iwl_rxon_cmd active_rxon;
+ struct iwl_rxon_cmd staging_rxon;
int error_recovering;
- struct iwl4965_rxon_cmd recovery_rxon;
+ struct iwl_rxon_cmd recovery_rxon;
/* 1st responses from initialize and runtime uCode images.
* 4965's initialize alive response contains some calibration data. */
- struct iwl4965_init_alive_resp card_alive_init;
- struct iwl4965_alive_resp card_alive;
+ struct iwl_init_alive_resp card_alive_init;
+ struct iwl_alive_resp card_alive;
#ifdef CONFIG_IWLWIFI_RFKILL
- struct iwl_rfkill_mngr rfkill_mngr;
+ struct rfkill *rfkill;
#endif
#ifdef CONFIG_IWLWIFI_LEDS
- struct iwl4965_led led[IWL_LED_TRG_MAX];
+ struct iwl_led led[IWL_LED_TRG_MAX];
unsigned long last_blink_time;
u8 last_blink_rate;
u8 allow_blinking;
@@ -1050,17 +939,12 @@ struct iwl_priv {
u8 assoc_station_added;
u8 use_ant_b_for_management_frame; /* Tx antenna selection */
- u8 valid_antenna; /* Bit mask of antennas actually connected */
-#ifdef CONFIG_IWL4965_SENSITIVITY
- struct iwl4965_sensitivity_data sensitivity_data;
- struct iwl4965_chain_noise_data chain_noise_data;
u8 start_calib;
+ struct iwl_sensitivity_data sensitivity_data;
+ struct iwl_chain_noise_data chain_noise_data;
__le16 sensitivity_tbl[HD_TABLE_SIZE];
-#endif /*CONFIG_IWL4965_SENSITIVITY*/
-#ifdef CONFIG_IWL4965_HT
struct iwl_ht_info current_ht_config;
-#endif
u8 last_phy_res[100];
/* Rate scaling data */
@@ -1075,10 +959,10 @@ struct iwl_priv {
int activity_timer_active;
/* Rx and Tx DMA processing queues */
- struct iwl4965_rx_queue rxq;
- struct iwl4965_tx_queue txq[IWL_MAX_NUM_QUEUES];
+ struct iwl_rx_queue rxq;
+ struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
unsigned long txq_ctx_active_msk;
- struct iwl4965_kw kw; /* keep warm address */
+ struct iwl_kw kw; /* keep warm address */
u32 scd_base_addr; /* scheduler sram base address */
unsigned long status;
@@ -1092,9 +976,9 @@ struct iwl_priv {
u64 bytes;
} tx_stats[3], rx_stats[3];
- struct iwl4965_power_mgr power_data;
+ struct iwl_power_mgr power_data;
- struct iwl4965_notif_statistics statistics;
+ struct iwl_notif_statistics statistics;
unsigned long last_statistics_time;
/* context information */
@@ -1111,7 +995,7 @@ struct iwl_priv {
/*station table variables */
spinlock_t sta_lock;
int num_stations;
- struct iwl4965_station_entry stations[IWL_STATION_COUNT];
+ struct iwl_station_entry stations[IWL_STATION_COUNT];
struct iwl_wep_key wep_keys[WEP_KEYS_MAX];
u8 default_wep_key;
u8 key_mapping_key;
@@ -1122,22 +1006,13 @@ struct iwl_priv {
u8 mac80211_registered;
- u32 notif_missed_beacons;
-
/* Rx'd packet timing information */
u32 last_beacon_time;
u64 last_tsf;
- /* Duplicate packet detection */
- u16 last_seq_num;
- u16 last_frag_num;
- unsigned long last_packet_time;
-
- /* Hash table for finding stations in IBSS network */
- struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
-
/* eeprom */
- struct iwl4965_eeprom eeprom;
+ u8 *eeprom;
+ struct iwl_eeprom_calib_info *calib_info;
enum ieee80211_if_types iw_mode;
@@ -1151,6 +1026,7 @@ struct iwl_priv {
struct iwl_hw_params hw_params;
/* driver/uCode shared Tx Byte Counts and Rx status */
void *shared_virt;
+ int rb_closed_offset;
/* Physical Pointer to Tx Byte Counts and Rx status */
dma_addr_t shared_phys;
@@ -1160,7 +1036,7 @@ struct iwl_priv {
u16 assoc_capability;
u8 ps_mode;
- struct iwl4965_qos_info qos_data;
+ struct iwl_qos_info qos_data;
struct workqueue_struct *workqueue;
@@ -1176,20 +1052,16 @@ struct iwl_priv {
struct work_struct report_work;
struct work_struct request_scan;
struct work_struct beacon_update;
+ struct work_struct set_monitor;
struct tasklet_struct irq_tasklet;
struct delayed_work init_alive_start;
struct delayed_work alive_start;
- struct delayed_work activity_timer;
- struct delayed_work thermal_periodic;
- struct delayed_work gather_stats;
struct delayed_work scan_check;
- struct delayed_work post_associate;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
- s8 user_txpower_limit;
- s8 max_channel_txpower_limit;
+ /* TX Power */
+ s8 tx_power_user_lmt;
+ s8 tx_power_channel_lmt;
#ifdef CONFIG_PM
u32 pm_state[16];
@@ -1197,6 +1069,7 @@ struct iwl_priv {
#ifdef CONFIG_IWLWIFI_DEBUG
/* debugging info */
+ u32 debug_level;
u32 framecnt_to_us;
atomic_t restrict_refcnt;
#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -1206,12 +1079,40 @@ struct iwl_priv {
#endif /* CONFIG_IWLWIFI_DEBUG */
struct work_struct txpower_work;
-#ifdef CONFIG_IWL4965_SENSITIVITY
- struct work_struct sensitivity_work;
-#endif
+ u32 disable_sens_cal;
+ u32 disable_chain_noise_cal;
+ u32 disable_tx_power_cal;
+ struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
}; /*iwl_priv */
+static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
+{
+ set_bit(txq_id, &priv->txq_ctx_active_msk);
+}
+
+static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
+{
+ clear_bit(txq_id, &priv->txq_ctx_active_msk);
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+const char *iwl_get_tx_fail_reason(u32 status);
+#else
+static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
+#endif
+
+
+static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
+ int txq_id, int idx)
+{
+ if (priv->txq[txq_id].txb[idx].skb[0])
+ return (struct ieee80211_hdr *)priv->txq[txq_id].
+ txb[idx].skb[0]->data;
+ return NULL;
+}
+
+
static inline int iwl_is_associated(struct iwl_priv *priv)
{
return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
@@ -1224,11 +1125,6 @@ static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
}
-static inline int is_channel_narrow(const struct iwl_channel_info *ch_info)
-{
- return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0;
-}
-
static inline int is_channel_radar(const struct iwl_channel_info *ch_info)
{
return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
@@ -1254,9 +1150,26 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
}
+#ifdef CONFIG_IWLWIFI_DEBUG
+static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
+ void *p, u32 len)
+{
+ if (!(priv->debug_level & level))
+ return;
+
+ print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
+ p, len, 1);
+}
+#else
+static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
+ void *p, u32 len)
+{
+}
+#endif
+
extern const struct iwl_channel_info *iwl_get_channel_info(
const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
/* Requires full declaration of iwl_priv before including */
-#endif /* __iwl4965_4965_h__ */
+#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index a07d5dcb7ab..4a08a1b5097 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -68,8 +68,8 @@
#include <net/mac80211.h>
-#include "iwl-4965-commands.h"
-#include "iwl-4965.h"
+#include "iwl-commands.h"
+#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-debug.h"
#include "iwl-eeprom.h"
@@ -193,6 +193,12 @@ void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
+const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
+{
+ BUG_ON(offset >= priv->cfg->eeprom_size);
+ return &priv->eeprom[offset];
+}
+EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
/**
* iwl_eeprom_init - read EEPROM contents
@@ -203,30 +209,35 @@ EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
*/
int iwl_eeprom_init(struct iwl_priv *priv)
{
- u16 *e = (u16 *)&priv->eeprom;
+ u16 *e;
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
u32 r;
- int sz = sizeof(priv->eeprom);
+ int sz = priv->cfg->eeprom_size;
int ret;
int i;
u16 addr;
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
+ /* allocate eeprom */
+ priv->eeprom = kzalloc(sz, GFP_KERNEL);
+ if (!priv->eeprom) {
+ ret = -ENOMEM;
+ goto alloc_err;
+ }
+ e = (u16 *)priv->eeprom;
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
+ ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
+ if (ret < 0) {
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
- return -ENOENT;
+ ret = -ENOENT;
+ goto err;
}
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
if (ret < 0) {
IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
+ ret = -ENOENT;
+ goto err;
}
/* eeprom is an array of 16bit values */
@@ -250,61 +261,98 @@ int iwl_eeprom_init(struct iwl_priv *priv)
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
}
ret = 0;
-
done:
priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
+err:
+ if (ret)
+ kfree(priv->eeprom);
+alloc_err:
return ret;
}
EXPORT_SYMBOL(iwl_eeprom_init);
+void iwl_eeprom_free(struct iwl_priv *priv)
+{
+ if(priv->eeprom)
+ kfree(priv->eeprom);
+ priv->eeprom = NULL;
+}
+EXPORT_SYMBOL(iwl_eeprom_free);
+
+int iwl_eeprom_check_version(struct iwl_priv *priv)
+{
+ return priv->cfg->ops->lib->eeprom_ops.check_version(priv);
+}
+EXPORT_SYMBOL(iwl_eeprom_check_version);
+
+const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
+{
+ return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
+}
+EXPORT_SYMBOL(iwl_eeprom_query_addr);
+
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
+{
+ return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
+}
+EXPORT_SYMBOL(iwl_eeprom_query16);
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
{
- memcpy(mac, priv->eeprom.mac_address, 6);
+ const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
+ EEPROM_MAC_ADDRESS);
+ memcpy(mac, addr, ETH_ALEN);
}
EXPORT_SYMBOL(iwl_eeprom_get_mac);
static void iwl_init_band_reference(const struct iwl_priv *priv,
- int band,
- int *eeprom_ch_count,
- const struct iwl4965_eeprom_channel
- **eeprom_ch_info,
- const u8 **eeprom_ch_index)
+ int eep_band, int *eeprom_ch_count,
+ const struct iwl_eeprom_channel **eeprom_ch_info,
+ const u8 **eeprom_ch_index)
{
- switch (band) {
+ u32 offset = priv->cfg->ops->lib->
+ eeprom_ops.regulatory_bands[eep_band - 1];
+ switch (eep_band) {
case 1: /* 2.4GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
- *eeprom_ch_info = priv->eeprom.band_1_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_1;
break;
case 2: /* 4.9GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
- *eeprom_ch_info = priv->eeprom.band_2_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_2;
break;
case 3: /* 5.2GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
- *eeprom_ch_info = priv->eeprom.band_3_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_3;
break;
case 4: /* 5.5GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
- *eeprom_ch_info = priv->eeprom.band_4_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_4;
break;
case 5: /* 5.7GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
- *eeprom_ch_info = priv->eeprom.band_5_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_5;
break;
case 6: /* 2.4GHz FAT channels */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
- *eeprom_ch_info = priv->eeprom.band_24_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_6;
break;
case 7: /* 5 GHz FAT channels */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
- *eeprom_ch_info = priv->eeprom.band_52_channels;
+ *eeprom_ch_info = (struct iwl_eeprom_channel *)
+ iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_7;
break;
default:
@@ -317,13 +365,13 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
? # x " " : "")
/**
- * iwl4965_set_fat_chan_info - Copy fat channel info into driver's priv.
+ * iwl_set_fat_chan_info - Copy fat channel info into driver's priv.
*
* Does not set up a command, or touch hardware.
*/
-static int iwl4965_set_fat_chan_info(struct iwl_priv *priv,
+static int iwl_set_fat_chan_info(struct iwl_priv *priv,
enum ieee80211_band band, u16 channel,
- const struct iwl4965_eeprom_channel *eeprom_ch,
+ const struct iwl_eeprom_channel *eeprom_ch,
u8 fat_extension_channel)
{
struct iwl_channel_info *ch_info;
@@ -334,8 +382,8 @@ static int iwl4965_set_fat_chan_info(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return -1;
- IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
+ IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+ " Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
"5.2" : "2.4",
@@ -343,7 +391,6 @@ static int iwl4965_set_fat_chan_info(struct iwl_priv *priv,
CHECK_AND_PRINT(ACTIVE),
CHECK_AND_PRINT(RADAR),
CHECK_AND_PRINT(WIDE),
- CHECK_AND_PRINT(NARROW),
CHECK_AND_PRINT(DFS),
eeprom_ch->flags,
eeprom_ch->max_power_avg,
@@ -372,7 +419,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
{
int eeprom_ch_count = 0;
const u8 *eeprom_ch_index = NULL;
- const struct iwl4965_eeprom_channel *eeprom_ch_info = NULL;
+ const struct iwl_eeprom_channel *eeprom_ch_info = NULL;
int band, ch;
struct iwl_channel_info *ch_info;
@@ -381,12 +428,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
return 0;
}
- if (priv->eeprom.version < 0x2f) {
- IWL_WARNING("Unsupported EEPROM version: 0x%04X\n",
- priv->eeprom.version);
- return -EINVAL;
- }
-
IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
priv->channel_count =
@@ -429,6 +470,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* Copy the run-time flags so they are there even on
* invalid channels */
ch_info->flags = eeprom_ch_info[ch].flags;
+ /* First write that fat is not enabled, and then enable
+ * one by one */
+ ch_info->fat_extension_channel =
+ (IEEE80211_CHAN_NO_FAT_ABOVE |
+ IEEE80211_CHAN_NO_FAT_BELOW);
if (!(is_channel_valid(ch_info))) {
IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
@@ -447,8 +493,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
+ IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
+ " Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
"5.2" : "2.4",
@@ -457,7 +503,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
CHECK_AND_PRINT_I(ACTIVE),
CHECK_AND_PRINT_I(RADAR),
CHECK_AND_PRINT_I(WIDE),
- CHECK_AND_PRINT_I(NARROW),
CHECK_AND_PRINT_I(DFS),
eeprom_ch_info[ch].flags,
eeprom_ch_info[ch].max_power_avg,
@@ -470,8 +515,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* Set the user_txpower_limit to the highest power
* supported by any channel */
if (eeprom_ch_info[ch].max_power_avg >
- priv->user_txpower_limit)
- priv->user_txpower_limit =
+ priv->tx_power_user_lmt)
+ priv->tx_power_user_lmt =
eeprom_ch_info[ch].max_power_avg;
ch_info++;
@@ -494,24 +539,26 @@ int iwl_init_channel_map(struct iwl_priv *priv)
for (ch = 0; ch < eeprom_ch_count; ch++) {
if ((band == 6) &&
- ((eeprom_ch_index[ch] == 5) ||
- (eeprom_ch_index[ch] == 6) ||
- (eeprom_ch_index[ch] == 7)))
- fat_extension_chan = HT_IE_EXT_CHANNEL_MAX;
+ ((eeprom_ch_index[ch] == 5) ||
+ (eeprom_ch_index[ch] == 6) ||
+ (eeprom_ch_index[ch] == 7)))
+ /* both are allowed: above and below */
+ fat_extension_chan = 0;
else
- fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE;
+ fat_extension_chan =
+ IEEE80211_CHAN_NO_FAT_BELOW;
/* Set up driver's info for lower half */
- iwl4965_set_fat_chan_info(priv, ieeeband,
- eeprom_ch_index[ch],
- &(eeprom_ch_info[ch]),
- fat_extension_chan);
+ iwl_set_fat_chan_info(priv, ieeeband,
+ eeprom_ch_index[ch],
+ &(eeprom_ch_info[ch]),
+ fat_extension_chan);
/* Set up driver's info for upper half */
- iwl4965_set_fat_chan_info(priv, ieeeband,
- (eeprom_ch_index[ch] + 4),
- &(eeprom_ch_info[ch]),
- HT_IE_EXT_CHANNEL_BELOW);
+ iwl_set_fat_chan_info(priv, ieeeband,
+ (eeprom_ch_index[ch] + 4),
+ &(eeprom_ch_info[ch]),
+ IEEE80211_CHAN_NO_FAT_ABOVE);
}
}
@@ -520,23 +567,21 @@ int iwl_init_channel_map(struct iwl_priv *priv)
EXPORT_SYMBOL(iwl_init_channel_map);
/*
- * iwl_free_channel_map - undo allocations in iwl4965_init_channel_map
+ * iwl_free_channel_map - undo allocations in iwl_init_channel_map
*/
void iwl_free_channel_map(struct iwl_priv *priv)
{
kfree(priv->channel_info);
priv->channel_count = 0;
}
-EXPORT_SYMBOL(iwl_free_channel_map);
/**
* iwl_get_channel_info - Find driver's private channel info
*
* Based on band and channel number.
*/
-const struct iwl_channel_info *iwl_get_channel_info(
- const struct iwl_priv *priv,
- enum ieee80211_band band, u16 channel)
+const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
+ enum ieee80211_band band, u16 channel)
{
int i;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index bd0a042ca77..d3a2a5b4ac5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -106,7 +106,7 @@ enum {
EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
- EEPROM_CHANNEL_NARROW = (1 << 6), /* 10 MHz channel (not used) */
+ /* Bit 6 Reserved (was Narrow Channel) */
EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
};
@@ -116,7 +116,7 @@ enum {
/* *regulatory* channel data format in eeprom, one for each channel.
* There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */
-struct iwl4965_eeprom_channel {
+struct iwl_eeprom_channel {
u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */
s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
} __attribute__ ((packed));
@@ -131,17 +131,55 @@ struct iwl4965_eeprom_channel {
* each of 3 target output levels */
#define EEPROM_TX_POWER_MEASUREMENTS (3)
-#define EEPROM_4965_TX_POWER_VERSION (2)
+/* 4965 Specific */
+/* 4965 driver does not work with txpower calibration version < 5 */
+#define EEPROM_4965_TX_POWER_VERSION (5)
+#define EEPROM_4965_EEPROM_VERSION (0x2f)
+#define EEPROM_4965_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */
+#define EEPROM_4965_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */
+#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */
+#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */
+
+/* 5000 Specific */
+#define EEPROM_5000_TX_POWER_VERSION (4)
+#define EEPROM_5000_EEPROM_VERSION (0x11A)
+
+/*5000 calibrations */
+#define EEPROM_5000_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION)
+#define EEPROM_5000_XTAL ((2*0x128) | EEPROM_5000_CALIB_ALL)
+
+/* 5000 links */
+#define EEPROM_5000_LINK_HOST (2*0x64)
+#define EEPROM_5000_LINK_GENERAL (2*0x65)
+#define EEPROM_5000_LINK_REGULATORY (2*0x66)
+#define EEPROM_5000_LINK_CALIBRATION (2*0x67)
+#define EEPROM_5000_LINK_PROCESS_ADJST (2*0x68)
+#define EEPROM_5000_LINK_OTHERS (2*0x69)
+
+/* 5000 regulatory - indirect access */
+#define EEPROM_5000_REG_SKU_ID ((0x02)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 4 bytes */
+#define EEPROM_5000_REG_BAND_1_CHANNELS ((0x08)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */
+#define EEPROM_5000_REG_BAND_2_CHANNELS ((0x26)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */
+#define EEPROM_5000_REG_BAND_3_CHANNELS ((0x42)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
+#define EEPROM_5000_REG_BAND_4_CHANNELS ((0x5C)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
+#define EEPROM_5000_REG_BAND_5_CHANNELS ((0x74)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */
+#define EEPROM_5000_REG_BAND_24_FAT_CHANNELS ((0x82)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
+#define EEPROM_5000_REG_BAND_52_FAT_CHANNELS ((0x92)\
+ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */
-/* 4965 driver does not work with txpower calibration version < 5.
- * Look for this in calib_version member of struct iwl4965_eeprom. */
-#define EEPROM_TX_POWER_VERSION_NEW (5)
/* 2.4 GHz */
extern const u8 iwl_eeprom_band_1[14];
/*
- * 4965 factory calibration data for one txpower level, on one channel,
+ * factory calibration data for one txpower level, on one channel,
* measured on one of the 2 tx chains (radio transmitter and associated
* antenna). EEPROM contains:
*
@@ -154,7 +192,7 @@ extern const u8 iwl_eeprom_band_1[14];
*
* 4) RF power amplifier detector level measurement (not used).
*/
-struct iwl4965_eeprom_calib_measure {
+struct iwl_eeprom_calib_measure {
u8 temperature; /* Device temperature (Celsius) */
u8 gain_idx; /* Index into gain table */
u8 actual_pow; /* Measured RF output power, half-dBm */
@@ -163,22 +201,22 @@ struct iwl4965_eeprom_calib_measure {
/*
- * 4965 measurement set for one channel. EEPROM contains:
+ * measurement set for one channel. EEPROM contains:
*
* 1) Channel number measured
*
* 2) Measurements for each of 3 power levels for each of 2 radio transmitters
* (a.k.a. "tx chains") (6 measurements altogether)
*/
-struct iwl4965_eeprom_calib_ch_info {
+struct iwl_eeprom_calib_ch_info {
u8 ch_num;
- struct iwl4965_eeprom_calib_measure
+ struct iwl_eeprom_calib_measure
measurements[EEPROM_TX_POWER_TX_CHAINS]
[EEPROM_TX_POWER_MEASUREMENTS];
} __attribute__ ((packed));
/*
- * 4965 txpower subband info.
+ * txpower subband info.
*
* For each frequency subband, EEPROM contains the following:
*
@@ -187,16 +225,16 @@ struct iwl4965_eeprom_calib_ch_info {
*
* 2) Sample measurement sets for 2 channels close to the range endpoints.
*/
-struct iwl4965_eeprom_calib_subband_info {
+struct iwl_eeprom_calib_subband_info {
u8 ch_from; /* channel number of lowest channel in subband */
u8 ch_to; /* channel number of highest channel in subband */
- struct iwl4965_eeprom_calib_ch_info ch1;
- struct iwl4965_eeprom_calib_ch_info ch2;
+ struct iwl_eeprom_calib_ch_info ch1;
+ struct iwl_eeprom_calib_ch_info ch2;
} __attribute__ ((packed));
/*
- * 4965 txpower calibration info. EEPROM contains:
+ * txpower calibration info. EEPROM contains:
*
* 1) Factory-measured saturation power levels (maximum levels at which
* tx power amplifier can output a signal without too much distortion).
@@ -212,55 +250,58 @@ struct iwl4965_eeprom_calib_subband_info {
* characteristics of the analog radio circuitry vary with frequency.
*
* Not all sets need to be filled with data;
- * struct iwl4965_eeprom_calib_subband_info contains range of channels
+ * struct iwl_eeprom_calib_subband_info contains range of channels
* (0 if unused) for each set of data.
*/
-struct iwl4965_eeprom_calib_info {
+struct iwl_eeprom_calib_info {
u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */
u8 saturation_power52; /* half-dBm */
s16 voltage; /* signed */
- struct iwl4965_eeprom_calib_subband_info
+ struct iwl_eeprom_calib_subband_info
band_info[EEPROM_TX_POWER_BANDS];
} __attribute__ ((packed));
-
-/*
- * 4965 EEPROM map
- */
-struct iwl4965_eeprom {
- u8 reserved0[16];
- u16 device_id; /* abs.ofs: 16 */
- u8 reserved1[2];
- u16 pmc; /* abs.ofs: 20 */
- u8 reserved2[20];
- u8 mac_address[6]; /* abs.ofs: 42 */
- u8 reserved3[58];
- u16 board_revision; /* abs.ofs: 106 */
- u8 reserved4[11];
- u8 board_pba_number[9]; /* abs.ofs: 119 */
- u8 reserved5[8];
- u16 version; /* abs.ofs: 136 */
- u8 sku_cap; /* abs.ofs: 138 */
- u8 leds_mode; /* abs.ofs: 139 */
- u16 oem_mode;
- u16 wowlan_mode; /* abs.ofs: 142 */
- u16 leds_time_interval; /* abs.ofs: 144 */
- u8 leds_off_time; /* abs.ofs: 146 */
- u8 leds_on_time; /* abs.ofs: 147 */
- u8 almgor_m_version; /* abs.ofs: 148 */
- u8 antenna_switch_type; /* abs.ofs: 149 */
- u8 reserved6[8];
- u16 board_revision_4965; /* abs.ofs: 158 */
- u8 reserved7[13];
- u8 board_pba_number_4965[9]; /* abs.ofs: 173 */
- u8 reserved8[10];
- u8 sku_id[4]; /* abs.ofs: 192 */
+#define ADDRESS_MSK 0x0000FFFF
+#define INDIRECT_TYPE_MSK 0x000F0000
+#define INDIRECT_HOST 0x00010000
+#define INDIRECT_GENERAL 0x00020000
+#define INDIRECT_REGULATORY 0x00030000
+#define INDIRECT_CALIBRATION 0x00040000
+#define INDIRECT_PROCESS_ADJST 0x00050000
+#define INDIRECT_OTHERS 0x00060000
+#define INDIRECT_ADDRESS 0x00100000
+
+/* General */
+#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */
+#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */
+#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */
+#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */
+#define EEPROM_VERSION (2*0x44) /* 2 bytes */
+#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */
+#define EEPROM_LEDS_MODE (2*0x45+1) /* 1 bytes */
+#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */
+#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
+#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */
+#define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */
+#define EEPROM_ANTENNA_SWITCH_TYPE (2*0x4A+1) /* 1 bytes */
+
+/* The following masks are to be applied on EEPROM_RADIO_CONFIG */
+#define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */
+#define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
+#define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
+#define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
+#define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
+#define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
+
+#define EEPROM_3945_RF_CFG_TYPE_MAX 0x0
+#define EEPROM_4965_RF_CFG_TYPE_MAX 0x1
+#define EEPROM_5000_RF_CFG_TYPE_MAX 0x3
/*
* Per-channel regulatory data.
*
- * Each channel that *might* be supported by 3945 or 4965 has a fixed location
+ * Each channel that *might* be supported by iwl has a fixed location
* in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
* txpower (MSB).
*
@@ -269,40 +310,38 @@ struct iwl4965_eeprom {
*
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
*/
- u16 band_1_count; /* abs.ofs: 196 */
- struct iwl4965_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
+#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */
+#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */
+#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */
/*
* 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
* 5.0 GHz channels 7, 8, 11, 12, 16
* (4915-5080MHz) (none of these is ever supported)
*/
- u16 band_2_count; /* abs.ofs: 226 */
- struct iwl4965_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
+#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */
+#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */
/*
* 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
* (5170-5320MHz)
*/
- u16 band_3_count; /* abs.ofs: 254 */
- struct iwl4965_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
+#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */
+#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */
/*
* 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
* (5500-5700MHz)
*/
- u16 band_4_count; /* abs.ofs: 280 */
- struct iwl4965_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
+#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */
+#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */
/*
* 5.7 GHz channels 145, 149, 153, 157, 161, 165
* (5725-5825MHz)
*/
- u16 band_5_count; /* abs.ofs: 304 */
- struct iwl4965_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
-
- u8 reserved10[2];
-
+#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */
+#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */
/*
* 2.4 GHz FAT channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
@@ -319,52 +358,35 @@ struct iwl4965_eeprom {
*
* NOTE: 4965 does not support FAT channels on 2.4 GHz.
*/
- struct iwl4965_eeprom_channel band_24_channels[7]; /* abs.ofs: 320 */
- u8 reserved11[2];
+#define EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0) /* 14 bytes */
/*
* 5.2 GHz FAT channels 36 (40), 44 (48), 52 (56), 60 (64),
* 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
*/
- struct iwl4965_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */
- u8 reserved12[6];
-
-/*
- * 4965 driver requires txpower calibration format version 5 or greater.
- * Driver does not work with txpower calibration version < 5.
- * This value is simply a 16-bit number, no major/minor versions here.
- */
- u16 calib_version; /* abs.ofs: 364 */
- u8 reserved13[2];
- u8 reserved14[96]; /* abs.ofs: 368 */
-
-/*
- * 4965 Txpower calibration data.
- */
- struct iwl4965_eeprom_calib_info calib_info; /* abs.ofs: 464 */
-
- u8 reserved16[140]; /* fill out to full 1024 byte block */
-
-
-} __attribute__ ((packed));
-
-#define IWL_EEPROM_IMAGE_SIZE 1024
-
-/* End of EEPROM */
+#define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */
struct iwl_eeprom_ops {
+ const u32 regulatory_bands[7];
int (*verify_signature) (struct iwl_priv *priv);
int (*acquire_semaphore) (struct iwl_priv *priv);
void (*release_semaphore) (struct iwl_priv *priv);
+ int (*check_version) (struct iwl_priv *priv);
+ const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
};
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
int iwl_eeprom_init(struct iwl_priv *priv);
+void iwl_eeprom_free(struct iwl_priv *priv);
+int iwl_eeprom_check_version(struct iwl_priv *priv);
+const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
+u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
+const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
int iwl_init_channel_map(struct iwl_priv *priv);
void iwl_free_channel_map(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
new file mode 100644
index 00000000000..944642450d3
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -0,0 +1,391 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * 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.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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.
+ *
+ *****************************************************************************/
+
+/****************************/
+/* Flow Handler Definitions */
+/****************************/
+
+/**
+ * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
+ * Addresses are offsets from device's PCI hardware base address.
+ */
+#define FH_MEM_LOWER_BOUND (0x1000)
+#define FH_MEM_UPPER_BOUND (0x1EF0)
+
+/**
+ * Keep-Warm (KW) buffer base address.
+ *
+ * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the
+ * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency
+ * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host
+ * from going into a power-savings mode that would cause higher DRAM latency,
+ * and possible data over/under-runs, before all Tx/Rx is complete.
+ *
+ * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4)
+ * of the buffer, which must be 4K aligned. Once this is set up, the 4965
+ * automatically invokes keep-warm accesses when normal accesses might not
+ * be sufficient to maintain fast DRAM response.
+ *
+ * Bit fields:
+ * 31-0: Keep-warm buffer physical base address [35:4], must be 4K aligned
+ */
+#define FH_KW_MEM_ADDR_REG (FH_MEM_LOWER_BOUND + 0x97C)
+
+
+/**
+ * TFD Circular Buffers Base (CBBC) addresses
+ *
+ * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident
+ * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs)
+ * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04
+ * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte
+ * aligned (address bits 0-7 must be 0).
+ *
+ * Bit fields in each pointer register:
+ * 27-0: TFD CB physical base address [35:8], must be 256-byte aligned
+ */
+#define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0)
+#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10)
+
+/* Find TFD CB base pointer for given queue (range 0-15). */
+#define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4)
+
+
+/**
+ * Rx SRAM Control and Status Registers (RSCSR)
+ *
+ * These registers provide handshake between driver and 4965 for the Rx queue
+ * (this queue handles *all* command responses, notifications, Rx data, etc.
+ * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx
+ * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can
+ * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer
+ * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1
+ * mapping between RBDs and RBs.
+ *
+ * Driver must allocate host DRAM memory for the following, and set the
+ * physical address of each into 4965 registers:
+ *
+ * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256
+ * entries (although any power of 2, up to 4096, is selectable by driver).
+ * Each entry (1 dword) points to a receive buffer (RB) of consistent size
+ * (typically 4K, although 8K or 16K are also selectable by driver).
+ * Driver sets up RB size and number of RBDs in the CB via Rx config
+ * register FH_MEM_RCSR_CHNL0_CONFIG_REG.
+ *
+ * Bit fields within one RBD:
+ * 27-0: Receive Buffer physical address bits [35:8], 256-byte aligned
+ *
+ * Driver sets physical address [35:8] of base of RBD circular buffer
+ * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0].
+ *
+ * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers
+ * (RBs) have been filled, via a "write pointer", actually the index of
+ * the RB's corresponding RBD within the circular buffer. Driver sets
+ * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0].
+ *
+ * Bit fields in lower dword of Rx status buffer (upper dword not used
+ * by driver; see struct iwl4965_shared, val0):
+ * 31-12: Not used by driver
+ * 11- 0: Index of last filled Rx buffer descriptor
+ * (4965 writes, driver reads this value)
+ *
+ * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must
+ * enter pointers to these RBs into contiguous RBD circular buffer entries,
+ * and update the 4965's "write" index register,
+ * FH_RSCSR_CHNL0_RBDCB_WPTR_REG.
+ *
+ * This "write" index corresponds to the *next* RBD that the driver will make
+ * available, i.e. one RBD past the tail of the ready-to-fill RBDs within
+ * the circular buffer. This value should initially be 0 (before preparing any
+ * RBs), should be 8 after preparing the first 8 RBs (for example), and must
+ * wrap back to 0 at the end of the circular buffer (but don't wrap before
+ * "read" index has advanced past 1! See below).
+ * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
+ *
+ * As the 4965 fills RBs (referenced from contiguous RBDs within the circular
+ * buffer), it updates the Rx status buffer in host DRAM, 2) described above,
+ * to tell the driver the index of the latest filled RBD. The driver must
+ * read this "read" index from DRAM after receiving an Rx interrupt from 4965.
+ *
+ * The driver must also internally keep track of a third index, which is the
+ * next RBD to process. When receiving an Rx interrupt, driver should process
+ * all filled but unprocessed RBs up to, but not including, the RB
+ * corresponding to the "read" index. For example, if "read" index becomes "1",
+ * driver may process the RB pointed to by RBD 0. Depending on volume of
+ * traffic, there may be many RBs to process.
+ *
+ * If read index == write index, 4965 thinks there is no room to put new data.
+ * Due to this, the maximum number of filled RBs is 255, instead of 256. To
+ * be safe, make sure that there is a gap of at least 2 RBDs between "write"
+ * and "read" indexes; that is, make sure that there are no more than 254
+ * buffers waiting to be filled.
+ */
+#define FH_MEM_RSCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBC0)
+#define FH_MEM_RSCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)
+#define FH_MEM_RSCSR_CHNL0 (FH_MEM_RSCSR_LOWER_BOUND)
+
+/**
+ * Physical base address of 8-byte Rx Status buffer.
+ * Bit fields:
+ * 31-0: Rx status buffer physical base address [35:4], must 16-byte aligned.
+ */
+#define FH_RSCSR_CHNL0_STTS_WPTR_REG (FH_MEM_RSCSR_CHNL0)
+
+/**
+ * Physical base address of Rx Buffer Descriptor Circular Buffer.
+ * Bit fields:
+ * 27-0: RBD CD physical base address [35:8], must be 256-byte aligned.
+ */
+#define FH_RSCSR_CHNL0_RBDCB_BASE_REG (FH_MEM_RSCSR_CHNL0 + 0x004)
+
+/**
+ * Rx write pointer (index, really!).
+ * Bit fields:
+ * 11-0: Index of driver's most recent prepared-to-be-filled RBD, + 1.
+ * NOTE: For 256-entry circular buffer, use only bits [7:0].
+ */
+#define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008)
+#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)
+
+
+/**
+ * Rx Config/Status Registers (RCSR)
+ * Rx Config Reg for channel 0 (only channel used)
+ *
+ * Driver must initialize FH_MEM_RCSR_CHNL0_CONFIG_REG as follows for
+ * normal operation (see bit fields).
+ *
+ * Clearing FH_MEM_RCSR_CHNL0_CONFIG_REG to 0 turns off Rx DMA.
+ * Driver should poll FH_MEM_RSSR_RX_STATUS_REG for
+ * FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (bit 24) before continuing.
+ *
+ * Bit fields:
+ * 31-30: Rx DMA channel enable: '00' off/pause, '01' pause at end of frame,
+ * '10' operate normally
+ * 29-24: reserved
+ * 23-20: # RBDs in circular buffer = 2^value; use "8" for 256 RBDs (normal),
+ * min "5" for 32 RBDs, max "12" for 4096 RBDs.
+ * 19-18: reserved
+ * 17-16: size of each receive buffer; '00' 4K (normal), '01' 8K,
+ * '10' 12K, '11' 16K.
+ * 15-14: reserved
+ * 13-12: IRQ destination; '00' none, '01' host driver (normal operation)
+ * 11- 4: timeout for closing Rx buffer and interrupting host (units 32 usec)
+ * typical value 0x10 (about 1/2 msec)
+ * 3- 0: reserved
+ */
+#define FH_MEM_RCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC00)
+#define FH_MEM_RCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xCC0)
+#define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND)
+
+#define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0)
+
+#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */
+#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK (0x00008000) /* bit 15 */
+#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MSK (0x00030000) /* bits 16-17 */
+#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MSK (0x00F00000) /* bits 20-23 */
+#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MSK (0xC0000000) /* bits 30-31*/
+
+#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20)
+#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT (4)
+#define RX_RB_TIMEOUT (0x10)
+
+#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000)
+#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000)
+#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000)
+
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000)
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K (0x00010000)
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K (0x00020000)
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K (0x00030000)
+
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
+
+
+/**
+ * Rx Shared Status Registers (RSSR)
+ *
+ * After stopping Rx DMA channel (writing 0 to
+ * FH_MEM_RCSR_CHNL0_CONFIG_REG), driver must poll
+ * FH_MEM_RSSR_RX_STATUS_REG until Rx channel is idle.
+ *
+ * Bit fields:
+ * 24: 1 = Channel 0 is idle
+ *
+ * FH_MEM_RSSR_SHARED_CTRL_REG and FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV
+ * contain default values that should not be altered by the driver.
+ */
+#define FH_MEM_RSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC40)
+#define FH_MEM_RSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xD00)
+
+#define FH_MEM_RSSR_SHARED_CTRL_REG (FH_MEM_RSSR_LOWER_BOUND)
+#define FH_MEM_RSSR_RX_STATUS_REG (FH_MEM_RSSR_LOWER_BOUND + 0x004)
+#define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV\
+ (FH_MEM_RSSR_LOWER_BOUND + 0x008)
+
+#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
+
+
+/**
+ * Transmit DMA Channel Control/Status Registers (TCSR)
+ *
+ * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels
+ * supported in hardware (don't confuse these with the 16 Tx queues in DRAM,
+ * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes.
+ *
+ * To use a Tx DMA channel, driver must initialize its
+ * FH_TCSR_CHNL_TX_CONFIG_REG(chnl) with:
+ *
+ * FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
+ * FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL
+ *
+ * All other bits should be 0.
+ *
+ * Bit fields:
+ * 31-30: Tx DMA channel enable: '00' off/pause, '01' pause at end of frame,
+ * '10' operate normally
+ * 29- 4: Reserved, set to "0"
+ * 3: Enable internal DMA requests (1, normal operation), disable (0)
+ * 2- 0: Reserved, set to "0"
+ */
+#define FH_TCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xD00)
+#define FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60)
+
+/* Find Control/Status reg for given Tx DMA/FIFO channel */
+#define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \
+ (FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
+
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
+
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF (0x40000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
+
+#define FH_TCSR_CHNL_NUM (7)
+
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY (0x00000000)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT (0x00002000)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00000003)
+
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD (0x00100000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
+
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM (20)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX (12)
+#define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \
+ (FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
+#define FH_TCSR_CHNL_TX_CREDIT_REG(_chnl) \
+ (FH_TCSR_LOWER_BOUND + 0x20 * _chnl + 0x4)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG(_chnl) \
+ (FH_TCSR_LOWER_BOUND + 0x20 * _chnl + 0x8)
+
+/**
+ * Tx Shared Status Registers (TSSR)
+ *
+ * After stopping Tx DMA channel (writing 0 to
+ * FH_TCSR_CHNL_TX_CONFIG_REG(chnl)), driver must poll
+ * FH_TSSR_TX_STATUS_REG until selected Tx channel is idle
+ * (channel's buffers empty | no pending requests).
+ *
+ * Bit fields:
+ * 31-24: 1 = Channel buffers empty (channel 7:0)
+ * 23-16: 1 = No pending requests (channel 7:0)
+ */
+#define FH_TSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xEA0)
+#define FH_TSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xEC0)
+
+#define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010)
+
+#define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
+#define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
+
+#define FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_chnl) \
+ (FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) | \
+ FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl))
+
+
+
+#define FH_REGS_LOWER_BOUND (0x1000)
+#define FH_REGS_UPPER_BOUND (0x2000)
+
+/* Tx service channels */
+#define FH_SRVC_CHNL (9)
+#define FH_SRVC_LOWER_BOUND (FH_REGS_LOWER_BOUND + 0x9C8)
+#define FH_SRVC_UPPER_BOUND (FH_REGS_LOWER_BOUND + 0x9D0)
+#define FH_SRVC_CHNL_SRAM_ADDR_REG(_chnl) \
+ (FH_SRVC_LOWER_BOUND + ((_chnl) - 9) * 0x4)
+
+/* TFDB Area - TFDs buffer table */
+#define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF)
+#define FH_TFDIB_LOWER_BOUND (FH_REGS_LOWER_BOUND + 0x900)
+#define FH_TFDIB_UPPER_BOUND (FH_REGS_LOWER_BOUND + 0x958)
+#define FH_TFDIB_CTRL0_REG(_chnl) (FH_TFDIB_LOWER_BOUND + 0x8 * (_chnl))
+#define FH_TFDIB_CTRL1_REG(_chnl) (FH_TFDIB_LOWER_BOUND + 0x8 * (_chnl) + 0x4)
+
+/* TCSR: tx_config register values */
+#define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index fdb27f1cdc0..8fa991b7202 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -31,7 +31,7 @@
#include <linux/version.h>
#include <net/mac80211.h>
-#include "iwl-4965.h" /* FIXME: remove */
+#include "iwl-dev.h" /* FIXME: remove */
#include "iwl-debug.h"
#include "iwl-eeprom.h"
#include "iwl-core.h"
@@ -56,6 +56,7 @@ const char *get_cmd_string(u8 cmd)
IWL_CMD(REPLY_RATE_SCALE);
IWL_CMD(REPLY_LEDS_CMD);
IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
+ IWL_CMD(COEX_PRIORITY_TABLE_CMD);
IWL_CMD(RADAR_NOTIFICATION);
IWL_CMD(REPLY_QUIET_CMD);
IWL_CMD(REPLY_CHANNEL_SWITCH);
@@ -89,6 +90,10 @@ const char *get_cmd_string(u8 cmd)
IWL_CMD(REPLY_RX_MPDU_CMD);
IWL_CMD(REPLY_RX);
IWL_CMD(REPLY_COMPRESSED_BA);
+ IWL_CMD(CALIBRATION_CFG_CMD);
+ IWL_CMD(CALIBRATION_RES_NOTIFICATION);
+ IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
+ IWL_CMD(REPLY_TX_POWER_DBM_CMD);
default:
return "UNKNOWN";
@@ -101,7 +106,7 @@ EXPORT_SYMBOL(get_cmd_string);
static int iwl_generic_cmd_callback(struct iwl_priv *priv,
struct iwl_cmd *cmd, struct sk_buff *skb)
{
- struct iwl4965_rx_packet *pkt = NULL;
+ struct iwl_rx_packet *pkt = NULL;
if (!skb) {
IWL_ERROR("Error: Response NULL in %s.\n",
@@ -109,7 +114,7 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
return 1;
}
- pkt = (struct iwl4965_rx_packet *)skb->data;
+ pkt = (struct iwl_rx_packet *)skb->data;
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
IWL_ERROR("Bad return from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
@@ -139,7 +144,7 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return -EBUSY;
- ret = priv->cfg->ops->utils->enqueue_hcmd(priv, cmd);
+ ret = iwl_enqueue_hcmd(priv, cmd);
if (ret < 0) {
IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
@@ -170,7 +175,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
if (cmd->meta.flags & CMD_WANT_SKB)
cmd->meta.source = &cmd->meta;
- cmd_idx = priv->cfg->ops->utils->enqueue_hcmd(priv, cmd);
+ cmd_idx = iwl_enqueue_hcmd(priv, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index a443472bea6..41eed679332 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -136,8 +136,8 @@ static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val)
#define KELVIN_TO_CELSIUS(x) ((x)-273)
#define CELSIUS_TO_KELVIN(x) ((x)+273)
+#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
-#define IEEE80211_CHAN_W_RADAR_DETECT 0x00000010
static inline struct ieee80211_conf *ieee80211_get_hw_conf(
struct ieee80211_hw *hw)
@@ -145,96 +145,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf(
return &hw->conf;
}
-#define QOS_CONTROL_LEN 2
-
-
-static inline int ieee80211_is_management(u16 fc)
-{
- return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT;
-}
-
-static inline int ieee80211_is_control(u16 fc)
-{
- return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL;
-}
-
-static inline int ieee80211_is_data(u16 fc)
-{
- return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA;
-}
-
-static inline int ieee80211_is_back_request(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ);
-}
-
-static inline int ieee80211_is_probe_response(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP);
-}
-
-static inline int ieee80211_is_probe_request(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_REQ);
-}
-
-static inline int ieee80211_is_beacon(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON);
-}
-
-static inline int ieee80211_is_atim(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ATIM);
-}
-
-static inline int ieee80211_is_assoc_request(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
-}
-
-static inline int ieee80211_is_assoc_response(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_RESP);
-}
-
-static inline int ieee80211_is_auth(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
-}
-
-static inline int ieee80211_is_deauth(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
-}
-
-static inline int ieee80211_is_disassoc(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
-}
-
-static inline int ieee80211_is_reassoc_request(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ);
-}
-
-static inline int ieee80211_is_reassoc_response(u16 fc)
-{
- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP);
-}
-
static inline int iwl_check_bits(unsigned long field, unsigned long mask)
{
return ((field & mask) == mask) ? 1 : 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 03fdf5b434a..899d7a2567a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -39,19 +39,26 @@
#include <linux/etherdevice.h>
#include <asm/unaligned.h>
-#include "iwl-4965.h"
+#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
-#define IWL_1MB_RATE (128 * 1024)
-#define IWL_LED_THRESHOLD (16)
-#define IWL_MAX_BLINK_TBL (10)
+#ifdef CONFIG_IWLWIFI_DEBUG
+static const char *led_type_str[] = {
+ __stringify(IWL_LED_TRG_TX),
+ __stringify(IWL_LED_TRG_RX),
+ __stringify(IWL_LED_TRG_ASSOC),
+ __stringify(IWL_LED_TRG_RADIO),
+ NULL
+};
+#endif /* CONFIG_IWLWIFI_DEBUG */
+
static const struct {
u16 tpt;
u8 on_time;
- u8 of_time;
+ u8 off_time;
} blink_tbl[] =
{
{300, 25, 25},
@@ -63,26 +70,31 @@ static const struct {
{15, 95, 95 },
{10, 110, 110},
{5, 130, 130},
- {0, 167, 167}
+ {0, 167, 167},
+/* SOLID_ON */
+ {-1, IWL_LED_SOLID, 0}
};
-static int iwl_led_cmd_callback(struct iwl_priv *priv,
- struct iwl_cmd *cmd, struct sk_buff *skb)
+#define IWL_1MB_RATE (128 * 1024)
+#define IWL_LED_THRESHOLD (16)
+#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /* exclude SOLID_ON */
+#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
+
+/* [0-256] -> [0..8] FIXME: we need [0..10] */
+static inline int iwl_brightness_to_idx(enum led_brightness brightness)
{
- return 1;
+ return fls(0x000000FF & (u32)brightness);
}
-
/* Send led command */
-static int iwl_send_led_cmd(struct iwl_priv *priv,
- struct iwl4965_led_cmd *led_cmd)
+static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
{
struct iwl_host_cmd cmd = {
.id = REPLY_LEDS_CMD,
- .len = sizeof(struct iwl4965_led_cmd),
+ .len = sizeof(struct iwl_led_cmd),
.data = led_cmd,
.meta.flags = CMD_ASYNC,
- .meta.u.callback = iwl_led_cmd_callback
+ .meta.u.callback = NULL,
};
u32 reg;
@@ -93,33 +105,20 @@ static int iwl_send_led_cmd(struct iwl_priv *priv,
return iwl_send_cmd(priv, &cmd);
}
-
-/* Set led on command */
-static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
-{
- struct iwl4965_led_cmd led_cmd = {
- .id = led_id,
- .on = IWL_LED_SOLID,
- .off = 0,
- .interval = IWL_DEF_LED_INTRVL
- };
- return iwl_send_led_cmd(priv, &led_cmd);
-}
-
-/* Set led on command */
+/* Set led pattern command */
static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id,
- enum led_brightness brightness)
+ unsigned int idx)
{
- struct iwl4965_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
- .on = brightness,
- .off = brightness,
.interval = IWL_DEF_LED_INTRVL
};
- if (brightness == LED_FULL) {
- led_cmd.on = IWL_LED_SOLID;
- led_cmd.off = 0;
- }
+
+ BUG_ON(idx > IWL_MAX_BLINK_TBL);
+
+ led_cmd.on = blink_tbl[idx].on_time;
+ led_cmd.off = blink_tbl[idx].off_time;
+
return iwl_send_led_cmd(priv, &led_cmd);
}
@@ -132,10 +131,22 @@ static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
}
#if 0
+/* Set led on command */
+static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
+{
+ struct iwl_led_cmd led_cmd = {
+ .id = led_id,
+ .on = IWL_LED_SOLID,
+ .off = 0,
+ .interval = IWL_DEF_LED_INTRVL
+ };
+ return iwl_send_led_cmd(priv, &led_cmd);
+}
+
/* Set led off command */
int iwl4965_led_off(struct iwl_priv *priv, int led_id)
{
- struct iwl4965_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = 0,
.off = 0,
@@ -155,25 +166,10 @@ static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
return 0;
}
-/* Set led blink command */
-static int iwl4965_led_not_solid(struct iwl_priv *priv, int led_id,
- u8 brightness)
-{
- struct iwl4965_led_cmd led_cmd = {
- .id = led_id,
- .on = brightness,
- .off = brightness,
- .interval = IWL_DEF_LED_INTRVL
- };
-
- return iwl_send_led_cmd(priv, &led_cmd);
-}
-
-
/*
* brightness call back function for Tx/Rx LED
*/
-static int iwl4965_led_associated(struct iwl_priv *priv, int led_id)
+static int iwl_led_associated(struct iwl_priv *priv, int led_id)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!test_bit(STATUS_READY, &priv->status))
@@ -189,16 +185,18 @@ static int iwl4965_led_associated(struct iwl_priv *priv, int led_id)
/*
* brightness call back for association and radio
*/
-static void iwl4965_led_brightness_set(struct led_classdev *led_cdev,
+static void iwl_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
- struct iwl4965_led *led = container_of(led_cdev,
- struct iwl4965_led, led_dev);
+ struct iwl_led *led = container_of(led_cdev, struct iwl_led, led_dev);
struct iwl_priv *priv = led->priv;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+
+ IWL_DEBUG_LED("Led type = %s brightness = %d\n",
+ led_type_str[led->type], brightness);
switch (brightness) {
case LED_FULL:
if (led->type == IWL_LED_TRG_ASSOC)
@@ -215,8 +213,10 @@ static void iwl4965_led_brightness_set(struct led_classdev *led_cdev,
led->led_off(priv, IWL_LED_LINK);
break;
default:
- if (led->led_pattern)
- led->led_pattern(priv, IWL_LED_LINK, brightness);
+ if (led->led_pattern) {
+ int idx = iwl_brightness_to_idx(brightness);
+ led->led_pattern(priv, IWL_LED_LINK, idx);
+ }
break;
}
}
@@ -226,8 +226,7 @@ static void iwl4965_led_brightness_set(struct led_classdev *led_cdev,
/*
* Register led class with the system
*/
-static int iwl_leds_register_led(struct iwl_priv *priv,
- struct iwl4965_led *led,
+static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
enum led_type type, u8 set_led,
const char *name, char *trigger)
{
@@ -235,7 +234,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv,
int ret;
led->led_dev.name = name;
- led->led_dev.brightness_set = iwl4965_led_brightness_set;
+ led->led_dev.brightness_set = iwl_led_brightness_set;
led->led_dev.default_trigger = trigger;
led->priv = priv;
@@ -259,32 +258,28 @@ static int iwl_leds_register_led(struct iwl_priv *priv,
/*
* calculate blink rate according to last 2 sec Tx/Rx activities
*/
-static inline u8 get_blink_rate(struct iwl_priv *priv)
+static int iwl_get_blink_rate(struct iwl_priv *priv)
{
int i;
- u8 blink_rate;
- u64 current_tpt = priv->tx_stats[2].bytes + priv->rx_stats[2].bytes;
+ u64 current_tpt = priv->tx_stats[2].bytes;
+ /* FIXME: + priv->rx_stats[2].bytes; */
s64 tpt = current_tpt - priv->led_tpt;
if (tpt < 0) /* wrapparound */
tpt = -tpt;
+ IWL_DEBUG_LED("tpt %lld current_tpt %lld\n", tpt, current_tpt);
priv->led_tpt = current_tpt;
- if (tpt < IWL_LED_THRESHOLD) {
+ if (!priv->allow_blinking)
i = IWL_MAX_BLINK_TBL;
- } else {
+ else
for (i = 0; i < IWL_MAX_BLINK_TBL; i++)
if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
break;
- }
- /* if 0 frame is transfered */
- if ((i == IWL_MAX_BLINK_TBL) || !priv->allow_blinking)
- blink_rate = IWL_LED_SOLID;
- else
- blink_rate = blink_tbl[i].on_time;
- return blink_rate;
+ IWL_DEBUG_LED("LED BLINK IDX=%d", i);
+ return i;
}
static inline int is_rf_kill(struct iwl_priv *priv)
@@ -300,7 +295,7 @@ static inline int is_rf_kill(struct iwl_priv *priv)
*/
void iwl_leds_background(struct iwl_priv *priv)
{
- u8 blink_rate;
+ u8 blink_idx;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
priv->last_blink_time = 0;
@@ -313,9 +308,10 @@ void iwl_leds_background(struct iwl_priv *priv)
if (!priv->allow_blinking) {
priv->last_blink_time = 0;
- if (priv->last_blink_rate != IWL_LED_SOLID) {
- priv->last_blink_rate = IWL_LED_SOLID;
- iwl4965_led_on(priv, IWL_LED_LINK);
+ if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
+ priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
+ iwl4965_led_pattern(priv, IWL_LED_LINK,
+ IWL_SOLID_BLINK_IDX);
}
return;
}
@@ -324,21 +320,14 @@ void iwl_leds_background(struct iwl_priv *priv)
msecs_to_jiffies(1000)))
return;
- blink_rate = get_blink_rate(priv);
+ blink_idx = iwl_get_blink_rate(priv);
/* call only if blink rate change */
- if (blink_rate != priv->last_blink_rate) {
- if (blink_rate != IWL_LED_SOLID) {
- priv->last_blink_time = jiffies +
- msecs_to_jiffies(1000);
- iwl4965_led_not_solid(priv, IWL_LED_LINK, blink_rate);
- } else {
- priv->last_blink_time = 0;
- iwl4965_led_on(priv, IWL_LED_LINK);
- }
- }
+ if (blink_idx != priv->last_blink_rate)
+ iwl4965_led_pattern(priv, IWL_LED_LINK, blink_idx);
- priv->last_blink_rate = blink_rate;
+ priv->last_blink_time = jiffies;
+ priv->last_blink_rate = blink_idx;
}
EXPORT_SYMBOL(iwl_leds_background);
@@ -362,10 +351,8 @@ int iwl_leds_register(struct iwl_priv *priv)
priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg;
priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
- ret = iwl_leds_register_led(priv,
- &priv->led[IWL_LED_TRG_RADIO],
- IWL_LED_TRG_RADIO, 1,
- name, trigger);
+ ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
+ IWL_LED_TRG_RADIO, 1, name, trigger);
if (ret)
goto exit_fail;
@@ -373,10 +360,9 @@ int iwl_leds_register(struct iwl_priv *priv)
snprintf(name, sizeof(name), "iwl-%s:assoc",
wiphy_name(priv->hw->wiphy));
- ret = iwl_leds_register_led(priv,
- &priv->led[IWL_LED_TRG_ASSOC],
- IWL_LED_TRG_ASSOC, 0,
- name, trigger);
+ ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
+ IWL_LED_TRG_ASSOC, 0, name, trigger);
+
/* for assoc always turn led on */
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg;
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg;
@@ -386,31 +372,26 @@ int iwl_leds_register(struct iwl_priv *priv)
goto exit_fail;
trigger = ieee80211_get_rx_led_name(priv->hw);
- snprintf(name, sizeof(name), "iwl-%s:RX",
- wiphy_name(priv->hw->wiphy));
+ snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy));
- ret = iwl_leds_register_led(priv,
- &priv->led[IWL_LED_TRG_RX],
- IWL_LED_TRG_RX, 0,
- name, trigger);
+ ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
+ IWL_LED_TRG_RX, 0, name, trigger);
- priv->led[IWL_LED_TRG_RX].led_on = iwl4965_led_associated;
- priv->led[IWL_LED_TRG_RX].led_off = iwl4965_led_associated;
+ priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
+ priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern;
if (ret)
goto exit_fail;
trigger = ieee80211_get_tx_led_name(priv->hw);
- snprintf(name, sizeof(name), "iwl-%s:TX",
- wiphy_name(priv->hw->wiphy));
- ret = iwl_leds_register_led(priv,
- &priv->led[IWL_LED_TRG_TX],
- IWL_LED_TRG_TX, 0,
- name, trigger);
- priv->led[IWL_LED_TRG_TX].led_on = iwl4965_led_associated;
- priv->led[IWL_LED_TRG_TX].led_off = iwl4965_led_associated;
+ snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy));
+ ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
+ IWL_LED_TRG_TX, 0, name, trigger);
+
+ priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
+ priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern;
if (ret)
@@ -425,7 +406,7 @@ exit_fail:
EXPORT_SYMBOL(iwl_leds_register);
/* unregister led class */
-static void iwl_leds_unregister_led(struct iwl4965_led *led, u8 set_led)
+static void iwl_leds_unregister_led(struct iwl_led *led, u8 set_led)
{
if (!led->registered)
return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 5bb04128cd6..1980ae5a7e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -49,14 +49,13 @@ enum led_type {
};
-struct iwl4965_led {
+struct iwl_led {
struct iwl_priv *priv;
struct led_classdev led_dev;
int (*led_on) (struct iwl_priv *priv, int led_id);
int (*led_off) (struct iwl_priv *priv, int led_id);
- int (*led_pattern) (struct iwl_priv *priv, int led_id,
- enum led_brightness brightness);
+ int (*led_pattern) (struct iwl_priv *priv, int led_id, unsigned int idx);
enum led_type type;
unsigned int registered;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
new file mode 100644
index 00000000000..2e71803e09b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -0,0 +1,423 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+
+#include <net/mac80211.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-commands.h"
+#include "iwl-debug.h"
+#include "iwl-power.h"
+#include "iwl-helpers.h"
+
+/*
+ * Setting power level allow the card to go to sleep when not busy
+ * there are three factor that decide the power level to go to, they
+ * are list here with its priority
+ * 1- critical_power_setting this will be set according to card temperature.
+ * 2- system_power_setting this will be set by system PM manager.
+ * 3- user_power_setting this will be set by user either by writing to sys or
+ * mac80211
+ *
+ * if system_power_setting and user_power_setting is set to auto
+ * the power level will be decided according to association status and battery
+ * status.
+ *
+ */
+
+#define MSEC_TO_USEC 1024
+#define IWL_POWER_RANGE_0_MAX (2)
+#define IWL_POWER_RANGE_1_MAX (10)
+
+
+#define NOSLP __constant_cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
+ __constant_cpu_to_le32(X1), \
+ __constant_cpu_to_le32(X2), \
+ __constant_cpu_to_le32(X3), \
+ __constant_cpu_to_le32(X4)}
+
+#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
+#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
+#define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM
+
+
+#define IWL_CT_KILL_TEMPERATURE 110
+#define IWL_MIN_POWER_TEMPERATURE 100
+#define IWL_REDUCED_POWER_TEMPERATURE 95
+
+/* default power management (not Tx power) table values */
+/* for tim 0-10 */
+static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
+ {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 2, 4, 4, 0xFF)}, 1},
+ {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 2, 4, 6, 0xFF)}, 2}
+};
+
+
+/* for tim = 3-10 */
+static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
+ {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 4, 6, 9, 10)}, 1},
+ {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
+};
+
+/* for tim > 11 */
+static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = {
+ {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(50), SLP_TOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
+ {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
+};
+
+/* decide the right power level according to association status
+ * and battery status
+ */
+static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
+{
+ u16 mode = priv->power_data.user_power_setting;
+
+ switch (priv->power_data.user_power_setting) {
+ case IWL_POWER_AUTO:
+ /* if running on battery */
+ if (priv->power_data.is_battery_active)
+ mode = IWL_POWER_ON_BATTERY;
+ else if (iwl_is_associated(priv))
+ mode = IWL_POWER_ON_AC_ASSOC;
+ else
+ mode = IWL_POWER_ON_AC_DISASSOC;
+ break;
+ case IWL_POWER_BATTERY:
+ mode = IWL_POWER_INDEX_3;
+ break;
+ case IWL_POWER_AC:
+ mode = IWL_POWER_MODE_CAM;
+ break;
+ }
+ return mode;
+}
+
+/* initialize to default */
+static int iwl_power_init_handle(struct iwl_priv *priv)
+{
+ int ret = 0, i;
+ struct iwl_power_mgr *pow_data;
+ int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC;
+ u16 pci_pm;
+
+ IWL_DEBUG_POWER("Initialize power \n");
+
+ pow_data = &(priv->power_data);
+
+ memset(pow_data, 0, sizeof(*pow_data));
+
+ memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
+ memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
+ memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
+
+ ret = pci_read_config_word(priv->pci_dev,
+ PCI_LINK_CTRL, &pci_pm);
+ if (ret != 0)
+ return 0;
+ else {
+ struct iwl4965_powertable_cmd *cmd;
+
+ IWL_DEBUG_POWER("adjust power command flags\n");
+
+ for (i = 0; i < IWL_POWER_AC; i++) {
+ cmd = &pow_data->pwr_range_0[i].cmd;
+
+ if (pci_pm & 0x1)
+ cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
+ else
+ cmd->flags |= IWL_POWER_PCI_PM_MSK;
+ }
+ }
+ return ret;
+}
+
+/* adjust power command according to dtim period and power level*/
+static int iwl_update_power_command(struct iwl_priv *priv,
+ struct iwl4965_powertable_cmd *cmd,
+ u16 mode)
+{
+ int ret = 0, i;
+ u8 skip;
+ u32 max_sleep = 0;
+ struct iwl_power_vec_entry *range;
+ u8 period = 0;
+ struct iwl_power_mgr *pow_data;
+
+ if (mode > IWL_POWER_INDEX_5) {
+ IWL_DEBUG_POWER("Error invalid power mode \n");
+ return -1;
+ }
+ pow_data = &(priv->power_data);
+
+ if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
+ range = &pow_data->pwr_range_0[0];
+ else if (pow_data->dtim_period <= IWL_POWER_RANGE_1_MAX)
+ range = &pow_data->pwr_range_1[0];
+ else
+ range = &pow_data->pwr_range_2[0];
+
+ period = pow_data->dtim_period;
+ memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd));
+
+ if (period == 0) {
+ period = 1;
+ skip = 0;
+ } else
+ skip = range[mode].no_dtim;
+
+ if (skip == 0) {
+ max_sleep = period;
+ cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ } else {
+ __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
+ max_sleep = le32_to_cpu(slp_itrvl);
+ if (max_sleep == 0xFF)
+ max_sleep = period * (skip + 1);
+ else if (max_sleep > period)
+ max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
+ cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ }
+
+ for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
+ if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
+ cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
+ }
+
+ IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
+ IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
+ IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
+ IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
+ le32_to_cpu(cmd->sleep_interval[0]),
+ le32_to_cpu(cmd->sleep_interval[1]),
+ le32_to_cpu(cmd->sleep_interval[2]),
+ le32_to_cpu(cmd->sleep_interval[3]),
+ le32_to_cpu(cmd->sleep_interval[4]));
+
+ return ret;
+}
+
+
+/*
+ * calucaute the final power mode index
+ */
+int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
+{
+ struct iwl_power_mgr *setting = &(priv->power_data);
+ int ret = 0;
+ u16 uninitialized_var(final_mode);
+
+ /* If on battery, set to 3,
+ * if plugged into AC power, set to CAM ("continuously aware mode"),
+ * else user level */
+
+ switch (setting->system_power_setting) {
+ case IWL_POWER_AUTO:
+ final_mode = iwl_get_auto_power_mode(priv);
+ break;
+ case IWL_POWER_BATTERY:
+ final_mode = IWL_POWER_INDEX_3;
+ break;
+ case IWL_POWER_AC:
+ final_mode = IWL_POWER_MODE_CAM;
+ break;
+ default:
+ final_mode = setting->system_power_setting;
+ }
+
+ if (setting->critical_power_setting > final_mode)
+ final_mode = setting->critical_power_setting;
+
+ /* driver only support CAM for non STA network */
+ if (priv->iw_mode != IEEE80211_IF_TYPE_STA)
+ final_mode = IWL_POWER_MODE_CAM;
+
+ if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
+ ((setting->power_mode != final_mode) || refresh)) {
+ struct iwl4965_powertable_cmd cmd;
+
+ if (final_mode != IWL_POWER_MODE_CAM)
+ set_bit(STATUS_POWER_PMI, &priv->status);
+
+ iwl_update_power_command(priv, &cmd, final_mode);
+ cmd.keep_alive_beacons = 0;
+
+ if (final_mode == IWL_POWER_INDEX_5)
+ cmd.flags |= IWL_POWER_FAST_PD;
+
+ if (priv->cfg->ops->lib->set_power)
+ ret = priv->cfg->ops->lib->set_power(priv, &cmd);
+
+ if (final_mode == IWL_POWER_MODE_CAM)
+ clear_bit(STATUS_POWER_PMI, &priv->status);
+ else
+ set_bit(STATUS_POWER_PMI, &priv->status);
+
+ if (priv->cfg->ops->lib->update_chain_flags)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+
+ if (!ret)
+ setting->power_mode = final_mode;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_power_update_mode);
+
+/* Allow other iwl code to disable/enable power management active
+ * this will be usefull for rate scale to disable PM during heavy
+ * Tx/Rx activities
+ */
+int iwl_power_disable_management(struct iwl_priv *priv)
+{
+ u16 prev_mode;
+ int ret = 0;
+
+ if (priv->power_data.power_disabled)
+ return -EBUSY;
+
+ prev_mode = priv->power_data.user_power_setting;
+ priv->power_data.user_power_setting = IWL_POWER_MODE_CAM;
+ ret = iwl_power_update_mode(priv, 0);
+ priv->power_data.power_disabled = 1;
+ priv->power_data.user_power_setting = prev_mode;
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_power_disable_management);
+
+/* Allow other iwl code to disable/enable power management active
+ * this will be usefull for rate scale to disable PM during hight
+ * valume activities
+ */
+int iwl_power_enable_management(struct iwl_priv *priv)
+{
+ int ret = 0;
+
+ priv->power_data.power_disabled = 0;
+ ret = iwl_power_update_mode(priv, 0);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_power_enable_management);
+
+/* set user_power_setting */
+int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
+{
+ int ret = 0;
+
+ if (mode > IWL_POWER_LIMIT)
+ return -EINVAL;
+
+ priv->power_data.user_power_setting = mode;
+
+ ret = iwl_power_update_mode(priv, 0);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_power_set_user_mode);
+
+
+/* set system_power_setting. This should be set by over all
+ * PM application.
+ */
+int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
+{
+ int ret = 0;
+
+ if (mode > IWL_POWER_LIMIT)
+ return -EINVAL;
+
+ priv->power_data.system_power_setting = mode;
+
+ ret = iwl_power_update_mode(priv, 0);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_power_set_system_mode);
+
+/* initilize to default */
+void iwl_power_initialize(struct iwl_priv *priv)
+{
+
+ iwl_power_init_handle(priv);
+ priv->power_data.user_power_setting = IWL_POWER_AUTO;
+ priv->power_data.power_disabled = 0;
+ priv->power_data.system_power_setting = IWL_POWER_AUTO;
+ priv->power_data.is_battery_active = 0;
+ priv->power_data.power_disabled = 0;
+ priv->power_data.critical_power_setting = 0;
+}
+EXPORT_SYMBOL(iwl_power_initialize);
+
+/* set critical_power_setting according to temperature value */
+int iwl_power_temperature_change(struct iwl_priv *priv)
+{
+ int ret = 0;
+ u16 new_critical = priv->power_data.critical_power_setting;
+ s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
+
+ if (temperature > IWL_CT_KILL_TEMPERATURE)
+ return 0;
+ else if (temperature > IWL_MIN_POWER_TEMPERATURE)
+ new_critical = IWL_POWER_INDEX_5;
+ else if (temperature > IWL_REDUCED_POWER_TEMPERATURE)
+ new_critical = IWL_POWER_INDEX_3;
+ else
+ new_critical = IWL_POWER_MODE_CAM;
+
+ if (new_critical != priv->power_data.critical_power_setting)
+ priv->power_data.critical_power_setting = new_critical;
+
+ if (priv->power_data.critical_power_setting >
+ priv->power_data.power_mode)
+ ret = iwl_power_update_mode(priv, 0);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_power_temperature_change);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
new file mode 100644
index 00000000000..b066724a1c2
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -0,0 +1,76 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+#ifndef __iwl_power_setting_h__
+#define __iwl_power_setting_h__
+
+#include <net/mac80211.h>
+#include "iwl-commands.h"
+
+struct iwl_priv;
+
+#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
+#define IWL_POWER_INDEX_3 0x03
+#define IWL_POWER_INDEX_5 0x05
+#define IWL_POWER_AC 0x06
+#define IWL_POWER_BATTERY 0x07
+#define IWL_POWER_AUTO 0x08
+#define IWL_POWER_LIMIT 0x08
+#define IWL_POWER_MASK 0x0F
+#define IWL_POWER_ENABLED 0x10
+
+/* Power management (not Tx power) structures */
+
+struct iwl_power_vec_entry {
+ struct iwl4965_powertable_cmd cmd;
+ u8 no_dtim;
+};
+
+struct iwl_power_mgr {
+ spinlock_t lock;
+ struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC];
+ struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC];
+ struct iwl_power_vec_entry pwr_range_2[IWL_POWER_AC];
+ u32 dtim_period;
+ /* final power level that used to calculate final power command */
+ u8 power_mode;
+ u8 user_power_setting; /* set by user through mac80211 or sysfs */
+ u8 system_power_setting; /* set by kernel syatem tools */
+ u8 critical_power_setting; /* set if driver over heated */
+ u8 is_battery_active; /* DC/AC power */
+ u8 power_disabled; /* flag to disable using power saving level */
+};
+
+int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
+int iwl_power_disable_management(struct iwl_priv *priv);
+int iwl_power_enable_management(struct iwl_priv *priv);
+int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
+int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
+void iwl_power_initialize(struct iwl_priv *priv);
+int iwl_power_temperature_change(struct iwl_priv *priv);
+
+#endif /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index c9cf8eef1a9..70d9c7568b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -239,40 +239,307 @@
#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C)
#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030)
+/**
+ * Tx Scheduler
+ *
+ * The Tx Scheduler selects the next frame to be transmitted, chosing TFDs
+ * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in
+ * host DRAM. It steers each frame's Tx command (which contains the frame
+ * data) into one of up to 7 prioritized Tx DMA FIFO channels within the
+ * device. A queue maps to only one (selectable by driver) Tx DMA channel,
+ * but one DMA channel may take input from several queues.
+ *
+ * Tx DMA channels have dedicated purposes. For 4965, they are used as follows:
+ *
+ * 0 -- EDCA BK (background) frames, lowest priority
+ * 1 -- EDCA BE (best effort) frames, normal priority
+ * 2 -- EDCA VI (video) frames, higher priority
+ * 3 -- EDCA VO (voice) and management frames, highest priority
+ * 4 -- Commands (e.g. RXON, etc.)
+ * 5 -- HCCA short frames
+ * 6 -- HCCA long frames
+ * 7 -- not used by driver (device-internal only)
+ *
+ * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
+ * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to
+ * support 11n aggregation via EDCA DMA channels.
+ *
+ * The driver sets up each queue to work in one of two modes:
+ *
+ * 1) Scheduler-Ack, in which the scheduler automatically supports a
+ * block-ack (BA) window of up to 64 TFDs. In this mode, each queue
+ * contains TFDs for a unique combination of Recipient Address (RA)
+ * and Traffic Identifier (TID), that is, traffic of a given
+ * Quality-Of-Service (QOS) priority, destined for a single station.
+ *
+ * In scheduler-ack mode, the scheduler keeps track of the Tx status of
+ * each frame within the BA window, including whether it's been transmitted,
+ * and whether it's been acknowledged by the receiving station. The device
+ * automatically processes block-acks received from the receiving STA,
+ * and reschedules un-acked frames to be retransmitted (successful
+ * Tx completion may end up being out-of-order).
+ *
+ * The driver must maintain the queue's Byte Count table in host DRAM
+ * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode.
+ * This mode does not support fragmentation.
+ *
+ * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order.
+ * The device may automatically retry Tx, but will retry only one frame
+ * at a time, until receiving ACK from receiving station, or reaching
+ * retry limit and giving up.
+ *
+ * The command queue (#4) must use this mode!
+ * This mode does not require use of the Byte Count table in host DRAM.
+ *
+ * Driver controls scheduler operation via 3 means:
+ * 1) Scheduler registers
+ * 2) Shared scheduler data base in internal 4956 SRAM
+ * 3) Shared data in host DRAM
+ *
+ * Initialization:
+ *
+ * When loading, driver should allocate memory for:
+ * 1) 16 TFD circular buffers, each with space for (typically) 256 TFDs.
+ * 2) 16 Byte Count circular buffers in 16 KBytes contiguous memory
+ * (1024 bytes for each queue).
+ *
+ * After receiving "Alive" response from uCode, driver must initialize
+ * the scheduler (especially for queue #4, the command queue, otherwise
+ * the driver can't issue commands!):
+ */
+
+/**
+ * Max Tx window size is the max number of contiguous TFDs that the scheduler
+ * can keep track of at one time when creating block-ack chains of frames.
+ * Note that "64" matches the number of ack bits in a block-ack packet.
+ * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize
+ * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values.
+ */
+#define SCD_WIN_SIZE 64
+#define SCD_FRAME_LIMIT 64
+
+/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
+#define IWL49_SCD_START_OFFSET 0xa02c00
+
+/*
+ * 4965 tells driver SRAM address for internal scheduler structs via this reg.
+ * Value is valid only after "Alive" response from uCode.
+ */
+#define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x0)
+
+/*
+ * Driver may need to update queue-empty bits after changing queue's
+ * write and read pointers (indexes) during (re-)initialization (i.e. when
+ * scheduler is not tracking what's happening).
+ * Bit fields:
+ * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit
+ * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty
+ * NOTE: This register is not used by Linux driver.
+ */
+#define IWL49_SCD_EMPTY_BITS (IWL49_SCD_START_OFFSET + 0x4)
+
+/*
+ * Physical base address of array of byte count (BC) circular buffers (CBs).
+ * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode.
+ * This register points to BC CB for queue 0, must be on 1024-byte boundary.
+ * Others are spaced by 1024 bytes.
+ * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad.
+ * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff).
+ * Bit fields:
+ * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned.
+ */
+#define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10)
+
+/*
+ * Enables any/all Tx DMA/FIFO channels.
+ * Scheduler generates requests for only the active channels.
+ * Set this to 0xff to enable all 8 channels (normal usage).
+ * Bit fields:
+ * 7- 0: Enable (1), disable (0), one bit for each channel 0-7
+ */
+#define IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c)
+/*
+ * Queue (x) Write Pointers (indexes, really!), one for each Tx queue.
+ * Initialized and updated by driver as new TFDs are added to queue.
+ * NOTE: If using Block Ack, index must correspond to frame's
+ * Start Sequence Number; index = (SSN & 0xff)
+ * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses?
+ */
+#define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4)
+
+/*
+ * Queue (x) Read Pointers (indexes, really!), one for each Tx queue.
+ * For FIFO mode, index indicates next frame to transmit.
+ * For Scheduler-ACK mode, index indicates first frame in Tx window.
+ * Initialized by driver, updated by scheduler.
+ */
+#define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4)
+
+/*
+ * Select which queues work in chain mode (1) vs. not (0).
+ * Use chain mode to build chains of aggregated frames.
+ * Bit fields:
+ * 31-16: Reserved
+ * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time
+ * NOTE: If driver sets up queue for chain mode, it should be also set up
+ * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x).
+ */
+#define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_START_OFFSET + 0xd0)
+
+/*
+ * Select which queues interrupt driver when scheduler increments
+ * a queue's read pointer (index).
+ * Bit fields:
+ * 31-16: Reserved
+ * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled
+ * NOTE: This functionality is apparently a no-op; driver relies on interrupts
+ * from Rx queue to read Tx command responses and update Tx queues.
+ */
+#define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4)
+
+/*
+ * Queue search status registers. One for each queue.
+ * Sets up queue mode and assigns queue to Tx DMA channel.
+ * Bit fields:
+ * 19-10: Write mask/enable bits for bits 0-9
+ * 9: Driver should init to "0"
+ * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0).
+ * Driver should init to "1" for aggregation mode, or "0" otherwise.
+ * 7-6: Driver should init to "0"
+ * 5: Window Size Left; indicates whether scheduler can request
+ * another TFD, based on window size, etc. Driver should init
+ * this bit to "1" for aggregation mode, or "0" for non-agg.
+ * 4-1: Tx FIFO to use (range 0-7).
+ * 0: Queue is active (1), not active (0).
+ * Other bits should be written as "0"
+ *
+ * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled
+ * via SCD_QUEUECHAIN_SEL.
+ */
+#define IWL49_SCD_QUEUE_STATUS_BITS(x)\
+ (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4)
+
+/* Bit field positions */
+#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0)
+#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1)
+#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5)
+#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8)
+
+/* Write masks */
+#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10)
+#define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00)
+
+/**
+ * 4965 internal SRAM structures for scheduler, shared with driver ...
+ *
+ * Driver should clear and initialize the following areas after receiving
+ * "Alive" response from 4965 uCode, i.e. after initial
+ * uCode load, or after a uCode load done for error recovery:
+ *
+ * SCD_CONTEXT_DATA_OFFSET (size 128 bytes)
+ * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes)
+ * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes)
+ *
+ * Driver accesses SRAM via HBUS_TARG_MEM_* registers.
+ * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR.
+ * All OFFSET values must be added to this base address.
+ */
+
+/*
+ * Queue context. One 8-byte entry for each of 16 queues.
+ *
+ * Driver should clear this entire area (size 0x80) to 0 after receiving
+ * "Alive" notification from uCode. Additionally, driver should init
+ * each queue's entry as follows:
+ *
+ * LS Dword bit fields:
+ * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64.
+ *
+ * MS Dword bit fields:
+ * 16-22: Frame limit. Driver should init to 10 (0xa).
+ *
+ * Driver should init all other bits to 0.
+ *
+ * Init must be done after driver receives "Alive" response from 4965 uCode,
+ * and when setting up queue for aggregation.
+ */
+#define IWL49_SCD_CONTEXT_DATA_OFFSET 0x380
+#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \
+ (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
+
+#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0)
+#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F)
+#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
+#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
+
+/*
+ * Tx Status Bitmap
+ *
+ * Driver should clear this entire area (size 0x100) to 0 after receiving
+ * "Alive" notification from uCode. Area is used only by device itself;
+ * no other support (besides clearing) is required from driver.
+ */
+#define IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400
+
/*
- * 4965 Tx Scheduler registers.
- * Details are documented in iwl-4965-hw.h
+ * RAxTID to queue translation mapping.
+ *
+ * When queue is in Scheduler-ACK mode, frames placed in a that queue must be
+ * for only one combination of receiver address (RA) and traffic ID (TID), i.e.
+ * one QOS priority level destined for one station (for this wireless link,
+ * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit
+ * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK
+ * mode, the device ignores the mapping value.
+ *
+ * Bit fields, for each 16-bit map:
+ * 15-9: Reserved, set to 0
+ * 8-4: Index into device's station table for recipient station
+ * 3-0: Traffic ID (tid), range 0-15
+ *
+ * Driver should clear this entire area (size 32 bytes) to 0 after receiving
+ * "Alive" notification from uCode. To update a 16-bit map value, driver
+ * must read a dword-aligned value from device SRAM, replace the 16-bit map
+ * value of interest, and write the dword value back into device SRAM.
*/
-#define IWL49_SCD_BASE (PRPH_BASE + 0xa02c00)
-
-#define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_BASE + 0x0)
-#define IWL49_SCD_EMPTY_BITS (IWL49_SCD_BASE + 0x4)
-#define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_BASE + 0x10)
-#define IWL49_SCD_AIT (IWL49_SCD_BASE + 0x18)
-#define IWL49_SCD_TXFACT (IWL49_SCD_BASE + 0x1c)
-#define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_BASE + 0x24 + (x) * 4)
-#define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_BASE + 0x64 + (x) * 4)
-#define IWL49_SCD_SETQUEUENUM (IWL49_SCD_BASE + 0xa4)
-#define IWL49_SCD_SET_TXSTAT_TXED (IWL49_SCD_BASE + 0xa8)
-#define IWL49_SCD_SET_TXSTAT_DONE (IWL49_SCD_BASE + 0xac)
-#define IWL49_SCD_SET_TXSTAT_NOT_SCHD (IWL49_SCD_BASE + 0xb0)
-#define IWL49_SCD_DECREASE_CREDIT (IWL49_SCD_BASE + 0xb4)
-#define IWL49_SCD_DECREASE_SCREDIT (IWL49_SCD_BASE + 0xb8)
-#define IWL49_SCD_LOAD_CREDIT (IWL49_SCD_BASE + 0xbc)
-#define IWL49_SCD_LOAD_SCREDIT (IWL49_SCD_BASE + 0xc0)
-#define IWL49_SCD_BAR (IWL49_SCD_BASE + 0xc4)
-#define IWL49_SCD_BAR_DW0 (IWL49_SCD_BASE + 0xc8)
-#define IWL49_SCD_BAR_DW1 (IWL49_SCD_BASE + 0xcc)
-#define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_BASE + 0xd0)
-#define IWL49_SCD_QUERY_REQ (IWL49_SCD_BASE + 0xd8)
-#define IWL49_SCD_QUERY_RES (IWL49_SCD_BASE + 0xdc)
-#define IWL49_SCD_PENDING_FRAMES (IWL49_SCD_BASE + 0xe0)
-#define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_BASE + 0xe4)
-#define IWL49_SCD_INTERRUPT_THRESHOLD (IWL49_SCD_BASE + 0xe8)
-#define IWL49_SCD_QUERY_MIN_FRAME_SIZE (IWL49_SCD_BASE + 0x100)
-#define IWL49_SCD_QUEUE_STATUS_BITS(x) (IWL49_SCD_BASE + 0x104 + (x) * 4)
-
-/* SP SCD */
+#define IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500
+
+/* Find translation table dword to read/write for given queue */
+#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
+ ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
+
+#define IWL_SCD_TXFIFO_POS_TID (0)
+#define IWL_SCD_TXFIFO_POS_RA (4)
+#define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF)
+
+/* 5000 SCD */
+#define IWL50_SCD_QUEUE_STTS_REG_POS_TXF (0)
+#define IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE (3)
+#define IWL50_SCD_QUEUE_STTS_REG_POS_WSL (4)
+#define IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19)
+#define IWL50_SCD_QUEUE_STTS_REG_MSK (0x00FF0000)
+
+#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_POS (8)
+#define IWL50_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00)
+#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24)
+#define IWL50_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000)
+#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0)
+#define IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
+#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
+#define IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
+
+#define IWL50_SCD_CONTEXT_DATA_OFFSET (0x600)
+#define IWL50_SCD_TX_STTS_BITMAP_OFFSET (0x7B1)
+#define IWL50_SCD_TRANSLATE_TBL_OFFSET (0x7E0)
+
+#define IWL50_SCD_CONTEXT_QUEUE_OFFSET(x)\
+ (IWL50_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
+
+#define IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
+ ((IWL50_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc)
+
+#define IWL50_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\
+ (~(1<<IWL_CMD_QUEUE_NUM)))
+
#define IWL50_SCD_BASE (PRPH_BASE + 0xa02c00)
#define IWL50_SCD_SRAM_BASE_ADDR (IWL50_SCD_BASE + 0x0)
@@ -287,4 +554,6 @@
#define IWL50_SCD_INTERRUPT_MASK (IWL50_SCD_BASE + 0x108)
#define IWL50_SCD_QUEUE_STATUS_BITS(x) (IWL50_SCD_BASE + 0x10c + (x) * 4)
+/*********************** END TX SCHEDULER *************************************/
+
#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 5980a5621cb..e5e5846e9f2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -33,7 +33,7 @@
#include <net/mac80211.h>
#include "iwl-eeprom.h"
-#include "iwl-4965.h"
+#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-helpers.h"
@@ -44,28 +44,31 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
struct iwl_priv *priv = data;
int err = 0;
- if (!priv->rfkill_mngr.rfkill)
+ if (!priv->rfkill)
return 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return 0;
- IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state);
+ IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
mutex_lock(&priv->mutex);
switch (state) {
- case RFKILL_STATE_ON:
- priv->cfg->ops->lib->radio_kill_sw(priv, 0);
- /* if HW rf-kill is set dont allow ON state */
- if (iwl_is_rfkill(priv))
+ case RFKILL_STATE_UNBLOCKED:
+ if (iwl_is_rfkill_hw(priv)) {
err = -EBUSY;
+ goto out_unlock;
+ }
+ iwl_radio_kill_sw_enable_radio(priv);
break;
- case RFKILL_STATE_OFF:
- priv->cfg->ops->lib->radio_kill_sw(priv, 1);
- if (!iwl_is_rfkill(priv))
- err = -EBUSY;
+ case RFKILL_STATE_SOFT_BLOCKED:
+ iwl_radio_kill_sw_disable_radio(priv);
+ break;
+ default:
+ IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
break;
}
+out_unlock:
mutex_unlock(&priv->mutex);
return err;
@@ -79,64 +82,35 @@ int iwl_rfkill_init(struct iwl_priv *priv)
BUG_ON(device == NULL);
IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
- priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
- if (!priv->rfkill_mngr.rfkill) {
+ priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
+ if (!priv->rfkill) {
IWL_ERROR("Unable to allocate rfkill device.\n");
ret = -ENOMEM;
goto error;
}
- priv->rfkill_mngr.rfkill->name = priv->cfg->name;
- priv->rfkill_mngr.rfkill->data = priv;
- priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
- priv->rfkill_mngr.rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
- priv->rfkill_mngr.rfkill->user_claim_unsupported = 1;
+ priv->rfkill->name = priv->cfg->name;
+ priv->rfkill->data = priv;
+ priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
+ priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
+ priv->rfkill->user_claim_unsupported = 1;
- priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
- priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
+ priv->rfkill->dev.class->suspend = NULL;
+ priv->rfkill->dev.class->resume = NULL;
- priv->rfkill_mngr.input_dev = input_allocate_device();
- if (!priv->rfkill_mngr.input_dev) {
- IWL_ERROR("Unable to allocate rfkill input device.\n");
- ret = -ENOMEM;
- goto freed_rfkill;
- }
-
- priv->rfkill_mngr.input_dev->name = priv->cfg->name;
- priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy);
- priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST;
- priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor;
- priv->rfkill_mngr.input_dev->dev.parent = device;
- priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
-
- ret = rfkill_register(priv->rfkill_mngr.rfkill);
+ ret = rfkill_register(priv->rfkill);
if (ret) {
IWL_ERROR("Unable to register rfkill: %d\n", ret);
- goto free_input_dev;
- }
-
- ret = input_register_device(priv->rfkill_mngr.input_dev);
- if (ret) {
- IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
- goto unregister_rfkill;
+ goto free_rfkill;
}
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;
-unregister_rfkill:
- rfkill_unregister(priv->rfkill_mngr.rfkill);
- priv->rfkill_mngr.rfkill = NULL;
-
-free_input_dev:
- input_free_device(priv->rfkill_mngr.input_dev);
- priv->rfkill_mngr.input_dev = NULL;
-
-freed_rfkill:
- if (priv->rfkill_mngr.rfkill != NULL)
- rfkill_free(priv->rfkill_mngr.rfkill);
- priv->rfkill_mngr.rfkill = NULL;
+free_rfkill:
+ if (priv->rfkill != NULL)
+ rfkill_free(priv->rfkill);
+ priv->rfkill = NULL;
error:
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
@@ -147,27 +121,27 @@ EXPORT_SYMBOL(iwl_rfkill_init);
void iwl_rfkill_unregister(struct iwl_priv *priv)
{
- if (priv->rfkill_mngr.input_dev)
- input_unregister_device(priv->rfkill_mngr.input_dev);
+ if (priv->rfkill)
+ rfkill_unregister(priv->rfkill);
- if (priv->rfkill_mngr.rfkill)
- rfkill_unregister(priv->rfkill_mngr.rfkill);
-
- priv->rfkill_mngr.input_dev = NULL;
- priv->rfkill_mngr.rfkill = NULL;
+ priv->rfkill = NULL;
}
EXPORT_SYMBOL(iwl_rfkill_unregister);
/* set rf-kill to the right state. */
void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
{
+ if (!priv->rfkill)
+ return;
- if (!priv->rfkill_mngr.rfkill)
+ if (iwl_is_rfkill_hw(priv)) {
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
return;
+ }
- if (!iwl_is_rfkill(priv))
- priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
+ if (!iwl_is_rfkill_sw(priv))
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
else
- priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF;
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
}
EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index a7f04b85540..402fd4c781d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -31,14 +31,8 @@
struct iwl_priv;
#include <linux/rfkill.h>
-#include <linux/input.h>
-
#ifdef CONFIG_IWLWIFI_RFKILL
-struct iwl_rfkill_mngr {
- struct rfkill *rfkill;
- struct input_dev *input_dev;
-};
void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
void iwl_rfkill_unregister(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
new file mode 100644
index 00000000000..e2d9afba38a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -0,0 +1,1321 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include <asm/unaligned.h>
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-io.h"
+#include "iwl-calib.h"
+#include "iwl-helpers.h"
+/************************** RX-FUNCTIONS ****************************/
+/*
+ * Rx theory of operation
+ *
+ * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs),
+ * each of which point to Receive Buffers to be filled by the NIC. These get
+ * used not only for Rx frames, but for any command response or notification
+ * from the NIC. The driver and NIC manage the Rx buffers by means
+ * of indexes into the circular buffer.
+ *
+ * Rx Queue Indexes
+ * The host/firmware share two index registers for managing the Rx buffers.
+ *
+ * The READ index maps to the first position that the firmware may be writing
+ * to -- the driver can read up to (but not including) this position and get
+ * good data.
+ * The READ index is managed by the firmware once the card is enabled.
+ *
+ * The WRITE index maps to the last position the driver has read from -- the
+ * position preceding WRITE is the last slot the firmware can place a packet.
+ *
+ * The queue is empty (no good data) if WRITE = READ - 1, and is full if
+ * WRITE = READ.
+ *
+ * During initialization, the host sets up the READ queue position to the first
+ * INDEX position, and WRITE to the last (READ - 1 wrapped)
+ *
+ * When the firmware places a packet in a buffer, it will advance the READ index
+ * and fire the RX interrupt. The driver can then query the READ index and
+ * process as many packets as possible, moving the WRITE index forward as it
+ * resets the Rx queue buffers with new memory.
+ *
+ * The management in the driver is as follows:
+ * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When
+ * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
+ * to replenish the iwl->rxq->rx_free.
+ * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
+ * iwl->rxq is replenished and the READ INDEX is updated (updating the
+ * 'processed' and 'read' driver indexes as well)
+ * + A received packet is processed and handed to the kernel network stack,
+ * detached from the iwl->rxq. The driver 'processed' index is updated.
+ * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
+ * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
+ * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there
+ * were enough free buffers and RX_STALLED is set it is cleared.
+ *
+ *
+ * Driver sequence:
+ *
+ * iwl_rx_queue_alloc() Allocates rx_free
+ * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls
+ * iwl_rx_queue_restock
+ * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx
+ * queue, updates firmware pointers, and updates
+ * the WRITE index. If insufficient rx_free buffers
+ * are available, schedules iwl_rx_replenish
+ *
+ * -- enable interrupts --
+ * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the
+ * READ INDEX, detaching the SKB from the pool.
+ * Moves the packet buffer from queue to rx_used.
+ * Calls iwl_rx_queue_restock to refill any empty
+ * slots.
+ * ...
+ *
+ */
+
+/**
+ * iwl_rx_queue_space - Return number of free slots available in queue.
+ */
+int iwl_rx_queue_space(const struct iwl_rx_queue *q)
+{
+ int s = q->read - q->write;
+ if (s <= 0)
+ s += RX_QUEUE_SIZE;
+ /* keep some buffer to not confuse full and empty queue */
+ s -= 2;
+ if (s < 0)
+ s = 0;
+ return s;
+}
+EXPORT_SYMBOL(iwl_rx_queue_space);
+
+/**
+ * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
+ */
+int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
+{
+ u32 reg = 0;
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
+
+ if (q->need_update == 0)
+ goto exit_unlock;
+
+ /* If power-saving is in use, make sure device is awake */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+ if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ iwl_set_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ goto exit_unlock;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto exit_unlock;
+
+ /* Device expects a multiple of 8 */
+ iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
+ q->write & ~0x7);
+ iwl_release_nic_access(priv);
+
+ /* Else device is assumed to be awake */
+ } else
+ /* Device expects a multiple of 8 */
+ iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
+
+
+ q->need_update = 0;
+
+ exit_unlock:
+ spin_unlock_irqrestore(&q->lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr);
+/**
+ * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
+ */
+static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
+ dma_addr_t dma_addr)
+{
+ return cpu_to_le32((u32)(dma_addr >> 8));
+}
+
+/**
+ * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
+ *
+ * If there are slots in the RX queue that need to be restocked,
+ * and we have free pre-allocated buffers, fill the ranks as much
+ * as we can, pulling from rx_free.
+ *
+ * This moves the 'write' index forward to catch up with 'processed', and
+ * also updates the memory address in the firmware to reference the new
+ * target buffer.
+ */
+int iwl_rx_queue_restock(struct iwl_priv *priv)
+{
+ struct iwl_rx_queue *rxq = &priv->rxq;
+ struct list_head *element;
+ struct iwl_rx_mem_buffer *rxb;
+ unsigned long flags;
+ int write;
+ int ret = 0;
+
+ spin_lock_irqsave(&rxq->lock, flags);
+ write = rxq->write & ~0x7;
+ while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+ /* Get next free Rx buffer, remove from free list */
+ element = rxq->rx_free.next;
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+ list_del(element);
+
+ /* Point to Rx buffer via next RBD in circular buffer */
+ rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+ rxq->queue[rxq->write] = rxb;
+ rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
+ rxq->free_count--;
+ }
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ /* If the pre-allocated buffer pool is dropping low, schedule to
+ * refill it */
+ if (rxq->free_count <= RX_LOW_WATERMARK)
+ queue_work(priv->workqueue, &priv->rx_replenish);
+
+
+ /* If we've added more space for the firmware to place data, tell it.
+ * Increment device's write pointer in multiples of 8. */
+ if ((write != (rxq->write & ~0x7))
+ || (abs(rxq->write - rxq->read) > 7)) {
+ spin_lock_irqsave(&rxq->lock, flags);
+ rxq->need_update = 1;
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ ret = iwl_rx_queue_update_write_ptr(priv, rxq);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_rx_queue_restock);
+
+
+/**
+ * iwl_rx_replenish - Move all used packet from rx_used to rx_free
+ *
+ * When moving to rx_free an SKB is allocated for the slot.
+ *
+ * Also restock the Rx queue via iwl_rx_queue_restock.
+ * This is called as a scheduled work item (except for during initialization)
+ */
+void iwl_rx_allocate(struct iwl_priv *priv)
+{
+ struct iwl_rx_queue *rxq = &priv->rxq;
+ struct list_head *element;
+ struct iwl_rx_mem_buffer *rxb;
+ unsigned long flags;
+ spin_lock_irqsave(&rxq->lock, flags);
+ while (!list_empty(&rxq->rx_used)) {
+ element = rxq->rx_used.next;
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+
+ /* Alloc a new receive buffer */
+ rxb->skb = alloc_skb(priv->hw_params.rx_buf_size,
+ __GFP_NOWARN | GFP_ATOMIC);
+ if (!rxb->skb) {
+ if (net_ratelimit())
+ printk(KERN_CRIT DRV_NAME
+ ": Can not allocate SKB buffers\n");
+ /* We don't reschedule replenish work here -- we will
+ * call the restock method and if it still needs
+ * more buffers it will schedule replenish */
+ break;
+ }
+ priv->alloc_rxb_skb++;
+ list_del(element);
+
+ /* Get physical address of RB/SKB */
+ rxb->dma_addr =
+ pci_map_single(priv->pci_dev, rxb->skb->data,
+ priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE);
+ list_add_tail(&rxb->list, &rxq->rx_free);
+ rxq->free_count++;
+ }
+ spin_unlock_irqrestore(&rxq->lock, flags);
+}
+EXPORT_SYMBOL(iwl_rx_allocate);
+
+void iwl_rx_replenish(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ iwl_rx_allocate(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_rx_queue_restock(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+EXPORT_SYMBOL(iwl_rx_replenish);
+
+
+/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
+ * If an SKB has been detached, the POOL needs to have its SKB set to NULL
+ * This free routine walks the list of POOL entries and if SKB is set to
+ * non NULL it is unmapped and freed
+ */
+void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+ int i;
+ for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
+ if (rxq->pool[i].skb != NULL) {
+ pci_unmap_single(priv->pci_dev,
+ rxq->pool[i].dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(rxq->pool[i].skb);
+ }
+ }
+
+ pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
+ rxq->dma_addr);
+ rxq->bd = NULL;
+}
+EXPORT_SYMBOL(iwl_rx_queue_free);
+
+int iwl_rx_queue_alloc(struct iwl_priv *priv)
+{
+ struct iwl_rx_queue *rxq = &priv->rxq;
+ struct pci_dev *dev = priv->pci_dev;
+ int i;
+
+ spin_lock_init(&rxq->lock);
+ INIT_LIST_HEAD(&rxq->rx_free);
+ INIT_LIST_HEAD(&rxq->rx_used);
+
+ /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
+ rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
+ if (!rxq->bd)
+ return -ENOMEM;
+
+ /* Fill the rx_used queue with _all_ of the Rx buffers */
+ for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
+ list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+
+ /* Set us so that we have processed and used all buffers, but have
+ * not restocked the Rx queue with fresh buffers */
+ rxq->read = rxq->write = 0;
+ rxq->free_count = 0;
+ rxq->need_update = 0;
+ return 0;
+}
+EXPORT_SYMBOL(iwl_rx_queue_alloc);
+
+void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+ unsigned long flags;
+ int i;
+ spin_lock_irqsave(&rxq->lock, flags);
+ INIT_LIST_HEAD(&rxq->rx_free);
+ INIT_LIST_HEAD(&rxq->rx_used);
+ /* Fill the rx_used queue with _all_ of the Rx buffers */
+ for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
+ /* In the reset function, these buffers may have been allocated
+ * to an SKB, so we need to unmap and free potential storage */
+ if (rxq->pool[i].skb != NULL) {
+ pci_unmap_single(priv->pci_dev,
+ rxq->pool[i].dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
+ priv->alloc_rxb_skb--;
+ dev_kfree_skb(rxq->pool[i].skb);
+ rxq->pool[i].skb = NULL;
+ }
+ list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+ }
+
+ /* Set us so that we have processed and used all buffers, but have
+ * not restocked the Rx queue with fresh buffers */
+ rxq->read = rxq->write = 0;
+ rxq->free_count = 0;
+ spin_unlock_irqrestore(&rxq->lock, flags);
+}
+EXPORT_SYMBOL(iwl_rx_queue_reset);
+
+int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+{
+ int ret;
+ unsigned long flags;
+ unsigned int rb_size;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ if (priv->cfg->mod_params->amsdu_size_8K)
+ rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
+ else
+ rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
+
+ /* Stop Rx DMA */
+ iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+
+ /* Reset driver's Rx queue write index */
+ iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
+
+ /* Tell device where to find RBD circular buffer in DRAM */
+ iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+ rxq->dma_addr >> 8);
+
+ /* Tell device where in DRAM to update its Rx status */
+ iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
+ (priv->shared_phys + priv->rb_closed_offset) >> 4);
+
+ /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */
+ iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
+ FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
+ FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
+ rb_size |
+ /* 0x10 << 4 | */
+ (RX_QUEUE_SIZE_LOG <<
+ FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT));
+
+ /*
+ * iwl_write32(priv,CSR_INT_COAL_REG,0);
+ */
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+int iwl_rxq_stop(struct iwl_priv *priv)
+{
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (unlikely(ret)) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* stop Rx DMA */
+ iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+ ret = iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
+ (1 << 24), 1000);
+ if (ret < 0)
+ IWL_ERROR("Can't stop Rx DMA.\n");
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_rxq_stop);
+
+void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl4965_missed_beacon_notif *missed_beacon;
+
+ missed_beacon = &pkt->u.missed_beacon;
+ if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
+ IWL_DEBUG_CALIB("missed bcn cnsq %d totl %d rcd %d expctd %d\n",
+ le32_to_cpu(missed_beacon->consequtive_missed_beacons),
+ le32_to_cpu(missed_beacon->total_missed_becons),
+ le32_to_cpu(missed_beacon->num_recvd_beacons),
+ le32_to_cpu(missed_beacon->num_expected_beacons));
+ if (!test_bit(STATUS_SCANNING, &priv->status))
+ iwl_init_sensitivity(priv);
+ }
+}
+EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
+
+int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn)
+{
+ unsigned long flags;
+ int sta_id;
+
+ sta_id = iwl_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags_msk = 0;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
+ priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
+ priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
+ CMD_ASYNC);
+}
+EXPORT_SYMBOL(iwl_rx_agg_start);
+
+int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
+{
+ unsigned long flags;
+ int sta_id;
+
+ sta_id = iwl_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags_msk = 0;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
+ priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
+ CMD_ASYNC);
+}
+EXPORT_SYMBOL(iwl_rx_agg_stop);
+
+
+/* Calculate noise level, based on measurements during network silence just
+ * before arriving beacon. This measurement can be done only if we know
+ * exactly when to expect beacons, therefore only when we're associated. */
+static void iwl_rx_calc_noise(struct iwl_priv *priv)
+{
+ struct statistics_rx_non_phy *rx_info
+ = &(priv->statistics.rx.general);
+ int num_active_rx = 0;
+ int total_silence = 0;
+ int bcn_silence_a =
+ le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
+ int bcn_silence_b =
+ le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
+ int bcn_silence_c =
+ le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
+
+ if (bcn_silence_a) {
+ total_silence += bcn_silence_a;
+ num_active_rx++;
+ }
+ if (bcn_silence_b) {
+ total_silence += bcn_silence_b;
+ num_active_rx++;
+ }
+ if (bcn_silence_c) {
+ total_silence += bcn_silence_c;
+ num_active_rx++;
+ }
+
+ /* Average among active antennas */
+ if (num_active_rx)
+ priv->last_rx_noise = (total_silence / num_active_rx) - 107;
+ else
+ priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
+
+ IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
+ bcn_silence_a, bcn_silence_b, bcn_silence_c,
+ priv->last_rx_noise);
+}
+
+#define REG_RECALIB_PERIOD (60)
+
+void iwl_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ int change;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+
+ IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+ (int)sizeof(priv->statistics), pkt->len);
+
+ change = ((priv->statistics.general.temperature !=
+ pkt->u.stats.general.temperature) ||
+ ((priv->statistics.flag &
+ STATISTICS_REPLY_FLG_FAT_MODE_MSK) !=
+ (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)));
+
+ memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
+
+ set_bit(STATUS_STATISTICS, &priv->status);
+
+ /* Reschedule the statistics timer to occur in
+ * REG_RECALIB_PERIOD seconds to ensure we get a
+ * thermal update even if the uCode doesn't give
+ * us one */
+ mod_timer(&priv->statistics_periodic, jiffies +
+ msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
+
+ if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
+ (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
+ iwl_rx_calc_noise(priv);
+ queue_work(priv->workqueue, &priv->run_time_calib_work);
+ }
+
+ iwl_leds_background(priv);
+
+ if (priv->cfg->ops->lib->temperature && change)
+ priv->cfg->ops->lib->temperature(priv);
+}
+EXPORT_SYMBOL(iwl_rx_statistics);
+
+#define PERFECT_RSSI (-20) /* dBm */
+#define WORST_RSSI (-95) /* dBm */
+#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
+
+/* Calculate an indication of rx signal quality (a percentage, not dBm!).
+ * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
+ * about formulas used below. */
+static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
+{
+ int sig_qual;
+ int degradation = PERFECT_RSSI - rssi_dbm;
+
+ /* If we get a noise measurement, use signal-to-noise ratio (SNR)
+ * as indicator; formula is (signal dbm - noise dbm).
+ * SNR at or above 40 is a great signal (100%).
+ * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
+ * Weakest usable signal is usually 10 - 15 dB SNR. */
+ if (noise_dbm) {
+ if (rssi_dbm - noise_dbm >= 40)
+ return 100;
+ else if (rssi_dbm < noise_dbm)
+ return 0;
+ sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
+
+ /* Else use just the signal level.
+ * This formula is a least squares fit of data points collected and
+ * compared with a reference system that had a percentage (%) display
+ * for signal quality. */
+ } else
+ sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
+ (15 * RSSI_RANGE + 62 * degradation)) /
+ (RSSI_RANGE * RSSI_RANGE);
+
+ if (sig_qual > 100)
+ sig_qual = 100;
+ else if (sig_qual < 1)
+ sig_qual = 0;
+
+ return sig_qual;
+}
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+
+/**
+ * iwl_dbg_report_frame - dump frame to syslog during debug sessions
+ *
+ * You may hack this function to show different aspects of received frames,
+ * including selective frame dumps.
+ * group100 parameter selects whether to show 1 out of 100 good frames.
+ *
+ * TODO: This was originally written for 3945, need to audit for
+ * proper operation with 4965.
+ */
+static void iwl_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ struct ieee80211_hdr *header, int group100)
+{
+ u32 to_us;
+ u32 print_summary = 0;
+ u32 print_dump = 0; /* set to 1 to dump all frames' contents */
+ u32 hundred = 0;
+ u32 dataframe = 0;
+ __le16 fc;
+ u16 seq_ctl;
+ u16 channel;
+ u16 phy_flags;
+ int rate_sym;
+ u16 length;
+ u16 status;
+ u16 bcn_tmr;
+ u32 tsf_low;
+ u64 tsf;
+ u8 rssi;
+ u8 agc;
+ u16 sig_avg;
+ u16 noise_diff;
+ struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
+ struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
+ struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
+ u8 *data = IWL_RX_DATA(pkt);
+
+ if (likely(!(priv->debug_level & IWL_DL_RX)))
+ return;
+
+ /* MAC header */
+ fc = header->frame_control;
+ seq_ctl = le16_to_cpu(header->seq_ctrl);
+
+ /* metadata */
+ channel = le16_to_cpu(rx_hdr->channel);
+ phy_flags = le16_to_cpu(rx_hdr->phy_flags);
+ rate_sym = rx_hdr->rate;
+ length = le16_to_cpu(rx_hdr->len);
+
+ /* end-of-frame status and timestamp */
+ status = le32_to_cpu(rx_end->status);
+ bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
+ tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
+ tsf = le64_to_cpu(rx_end->timestamp);
+
+ /* signal statistics */
+ rssi = rx_stats->rssi;
+ agc = rx_stats->agc;
+ sig_avg = le16_to_cpu(rx_stats->sig_avg);
+ noise_diff = le16_to_cpu(rx_stats->noise_diff);
+
+ to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
+
+ /* if data frame is to us and all is good,
+ * (optionally) print summary for only 1 out of every 100 */
+ if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
+ cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
+ dataframe = 1;
+ if (!group100)
+ print_summary = 1; /* print each frame */
+ else if (priv->framecnt_to_us < 100) {
+ priv->framecnt_to_us++;
+ print_summary = 0;
+ } else {
+ priv->framecnt_to_us = 0;
+ print_summary = 1;
+ hundred = 1;
+ }
+ } else {
+ /* print summary for all other frames */
+ print_summary = 1;
+ }
+
+ if (print_summary) {
+ char *title;
+ int rate_idx;
+ u32 bitrate;
+
+ if (hundred)
+ title = "100Frames";
+ else if (ieee80211_has_retry(fc))
+ title = "Retry";
+ else if (ieee80211_is_assoc_resp(fc))
+ title = "AscRsp";
+ else if (ieee80211_is_reassoc_resp(fc))
+ title = "RasRsp";
+ else if (ieee80211_is_probe_resp(fc)) {
+ title = "PrbRsp";
+ print_dump = 1; /* dump frame contents */
+ } else if (ieee80211_is_beacon(fc)) {
+ title = "Beacon";
+ print_dump = 1; /* dump frame contents */
+ } else if (ieee80211_is_atim(fc))
+ title = "ATIM";
+ else if (ieee80211_is_auth(fc))
+ title = "Auth";
+ else if (ieee80211_is_deauth(fc))
+ title = "DeAuth";
+ else if (ieee80211_is_disassoc(fc))
+ title = "DisAssoc";
+ else
+ title = "Frame";
+
+ rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
+ if (unlikely(rate_idx == -1))
+ bitrate = 0;
+ else
+ bitrate = iwl_rates[rate_idx].ieee / 2;
+
+ /* print frame summary.
+ * MAC addresses show just the last byte (for brevity),
+ * but you can hack it to show more, if you'd like to. */
+ if (dataframe)
+ IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+ "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
+ title, le16_to_cpu(fc), header->addr1[5],
+ length, rssi, channel, bitrate);
+ else {
+ /* src/dst addresses assume managed mode */
+ IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
+ "src=0x%02x, rssi=%u, tim=%lu usec, "
+ "phy=0x%02x, chnl=%d\n",
+ title, le16_to_cpu(fc), header->addr1[5],
+ header->addr3[5], rssi,
+ tsf_low - priv->scan_start_tsf,
+ phy_flags, channel);
+ }
+ }
+ if (print_dump)
+ iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
+}
+#else
+static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ struct ieee80211_hdr *header,
+ int group100)
+{
+}
+#endif
+
+static void iwl_add_radiotap(struct iwl_priv *priv,
+ struct sk_buff *skb,
+ struct iwl4965_rx_phy_res *rx_start,
+ struct ieee80211_rx_status *stats,
+ u32 ampdu_status)
+{
+ s8 signal = stats->signal;
+ s8 noise = 0;
+ int rate = stats->rate_idx;
+ u64 tsf = stats->mactime;
+ __le16 antenna;
+ __le16 phy_flags_hw = rx_start->phy_flags;
+ struct iwl4965_rt_rx_hdr {
+ struct ieee80211_radiotap_header rt_hdr;
+ __le64 rt_tsf; /* TSF */
+ u8 rt_flags; /* radiotap packet flags */
+ u8 rt_rate; /* rate in 500kb/s */
+ __le16 rt_channelMHz; /* channel in MHz */
+ __le16 rt_chbitmask; /* channel bitfield */
+ s8 rt_dbmsignal; /* signal in dBm, kluged to signed */
+ s8 rt_dbmnoise;
+ u8 rt_antenna; /* antenna number */
+ } __attribute__ ((packed)) *iwl4965_rt;
+
+ /* TODO: We won't have enough headroom for HT frames. Fix it later. */
+ if (skb_headroom(skb) < sizeof(*iwl4965_rt)) {
+ if (net_ratelimit())
+ printk(KERN_ERR "not enough headroom [%d] for "
+ "radiotap head [%zd]\n",
+ skb_headroom(skb), sizeof(*iwl4965_rt));
+ return;
+ }
+
+ /* put radiotap header in front of 802.11 header and data */
+ iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt));
+
+ /* initialise radiotap header */
+ iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+ iwl4965_rt->rt_hdr.it_pad = 0;
+
+ /* total header + data */
+ put_unaligned_le16(sizeof(*iwl4965_rt), &iwl4965_rt->rt_hdr.it_len);
+
+ /* Indicate all the fields we add to the radiotap header */
+ put_unaligned_le32((1 << IEEE80211_RADIOTAP_TSFT) |
+ (1 << IEEE80211_RADIOTAP_FLAGS) |
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_CHANNEL) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
+ (1 << IEEE80211_RADIOTAP_ANTENNA),
+ &(iwl4965_rt->rt_hdr.it_present));
+
+ /* Zero the flags, we'll add to them as we go */
+ iwl4965_rt->rt_flags = 0;
+
+ put_unaligned_le64(tsf, &iwl4965_rt->rt_tsf);
+
+ iwl4965_rt->rt_dbmsignal = signal;
+ iwl4965_rt->rt_dbmnoise = noise;
+
+ /* Convert the channel frequency and set the flags */
+ put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz);
+ if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
+ put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
+ &iwl4965_rt->rt_chbitmask);
+ else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
+ put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
+ &iwl4965_rt->rt_chbitmask);
+ else /* 802.11g */
+ put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
+ &iwl4965_rt->rt_chbitmask);
+
+ if (rate == -1)
+ iwl4965_rt->rt_rate = 0;
+ else
+ iwl4965_rt->rt_rate = iwl_rates[rate].ieee;
+
+ /*
+ * "antenna number"
+ *
+ * It seems that the antenna field in the phy flags value
+ * is actually a bitfield. This is undefined by radiotap,
+ * it wants an actual antenna number but I always get "7"
+ * for most legacy frames I receive indicating that the
+ * same frame was received on all three RX chains.
+ *
+ * I think this field should be removed in favour of a
+ * new 802.11n radiotap field "RX chains" that is defined
+ * as a bitmask.
+ */
+ antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
+ iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4;
+
+ /* set the preamble flag if appropriate */
+ if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
+ iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+ stats->flag |= RX_FLAG_RADIOTAP;
+}
+
+static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
+{
+ /* 0 - mgmt, 1 - cnt, 2 - data */
+ int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
+ priv->rx_stats[idx].cnt++;
+ priv->rx_stats[idx].bytes += len;
+}
+
+/*
+ * returns non-zero if packet should be dropped
+ */
+static int iwl_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats)
+{
+ u16 fc = le16_to_cpu(hdr->frame_control);
+
+ if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+ return 0;
+
+ if (!(fc & IEEE80211_FCTL_PROTECTED))
+ return 0;
+
+ IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
+ switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
+ case RX_RES_STATUS_SEC_TYPE_TKIP:
+ /* The uCode has got a bad phase 1 Key, pushes the packet.
+ * Decryption will be done in SW. */
+ if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
+ RX_RES_STATUS_BAD_KEY_TTAK)
+ break;
+
+ case RX_RES_STATUS_SEC_TYPE_WEP:
+ if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
+ RX_RES_STATUS_BAD_ICV_MIC) {
+ /* bad ICV, the packet is destroyed since the
+ * decryption is inplace, drop it */
+ IWL_DEBUG_RX("Packet destroyed\n");
+ return -1;
+ }
+ case RX_RES_STATUS_SEC_TYPE_CCMP:
+ if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
+ RX_RES_STATUS_DECRYPT_OK) {
+ IWL_DEBUG_RX("hw decrypt successfully!!!\n");
+ stats->flag |= RX_FLAG_DECRYPTED;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
+{
+ u32 decrypt_out = 0;
+
+ if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
+ RX_RES_STATUS_STATION_FOUND)
+ decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
+ RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
+
+ decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
+
+ /* packet was not encrypted */
+ if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
+ RX_RES_STATUS_SEC_TYPE_NONE)
+ return decrypt_out;
+
+ /* packet was encrypted with unknown alg */
+ if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
+ RX_RES_STATUS_SEC_TYPE_ERR)
+ return decrypt_out;
+
+ /* decryption was not done in HW */
+ if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
+ RX_MPDU_RES_STATUS_DEC_DONE_MSK)
+ return decrypt_out;
+
+ switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
+
+ case RX_RES_STATUS_SEC_TYPE_CCMP:
+ /* alg is CCM: check MIC only */
+ if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
+ /* Bad MIC */
+ decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
+ else
+ decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
+
+ break;
+
+ case RX_RES_STATUS_SEC_TYPE_TKIP:
+ if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
+ /* Bad TTAK */
+ decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
+ break;
+ }
+ /* fall through if TTAK OK */
+ default:
+ if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
+ decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
+ else
+ decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
+ break;
+ };
+
+ IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
+ decrypt_in, decrypt_out);
+
+ return decrypt_out;
+}
+
+static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
+ int include_phy,
+ struct iwl_rx_mem_buffer *rxb,
+ struct ieee80211_rx_status *stats)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
+ (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
+ struct ieee80211_hdr *hdr;
+ u16 len;
+ __le32 *rx_end;
+ unsigned int skblen;
+ u32 ampdu_status;
+ u32 ampdu_status_legacy;
+
+ if (!include_phy && priv->last_phy_res[0])
+ rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
+
+ if (!rx_start) {
+ IWL_ERROR("MPDU frame without a PHY data\n");
+ return;
+ }
+ if (include_phy) {
+ hdr = (struct ieee80211_hdr *)((u8 *) &rx_start[1] +
+ rx_start->cfg_phy_cnt);
+
+ len = le16_to_cpu(rx_start->byte_count);
+
+ rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] +
+ sizeof(struct iwl4965_rx_phy_res) +
+ rx_start->cfg_phy_cnt + len);
+
+ } else {
+ struct iwl4965_rx_mpdu_res_start *amsdu =
+ (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
+
+ hdr = (struct ieee80211_hdr *)(pkt->u.raw +
+ sizeof(struct iwl4965_rx_mpdu_res_start));
+ len = le16_to_cpu(amsdu->byte_count);
+ rx_start->byte_count = amsdu->byte_count;
+ rx_end = (__le32 *) (((u8 *) hdr) + len);
+ }
+
+ ampdu_status = le32_to_cpu(*rx_end);
+ skblen = ((u8 *) rx_end - (u8 *) &pkt->u.raw[0]) + sizeof(u32);
+
+ if (!include_phy) {
+ /* New status scheme, need to translate */
+ ampdu_status_legacy = ampdu_status;
+ ampdu_status = iwl_translate_rx_status(priv, ampdu_status);
+ }
+
+ /* start from MAC */
+ skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
+ skb_put(rxb->skb, len); /* end where data ends */
+
+ /* We only process data packets if the interface is open */
+ if (unlikely(!priv->is_open)) {
+ IWL_DEBUG_DROP_LIMIT
+ ("Dropping packet while interface is not open.\n");
+ return;
+ }
+
+ hdr = (struct ieee80211_hdr *)rxb->skb->data;
+
+ /* in case of HW accelerated crypto and bad decryption, drop */
+ if (!priv->hw_params.sw_crypto &&
+ iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
+ return;
+
+ if (priv->add_radiotap)
+ iwl_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
+
+ iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
+ ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
+ priv->alloc_rxb_skb--;
+ rxb->skb = NULL;
+}
+
+/* Calc max signal level (dBm) among 3 possible receivers */
+static int iwl_calc_rssi(struct iwl_priv *priv,
+ struct iwl4965_rx_phy_res *rx_resp)
+{
+ /* data from PHY/DSP regarding signal strength, etc.,
+ * contents are always there, not configurable by host. */
+ struct iwl4965_rx_non_cfg_phy *ncphy =
+ (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
+ u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
+ >> IWL_AGC_DB_POS;
+
+ u32 valid_antennae =
+ (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
+ >> RX_PHY_FLAGS_ANTENNAE_OFFSET;
+ u8 max_rssi = 0;
+ u32 i;
+
+ /* Find max rssi among 3 possible receivers.
+ * These values are measured by the digital signal processor (DSP).
+ * They should stay fairly constant even as the signal strength varies,
+ * if the radio's automatic gain control (AGC) is working right.
+ * AGC value (see below) will provide the "interesting" info. */
+ for (i = 0; i < 3; i++)
+ if (valid_antennae & (1 << i))
+ max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
+
+ IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+ ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
+ max_rssi, agc);
+
+ /* dBm = max_rssi dB - agc dB - constant.
+ * Higher AGC (higher radio gain) means lower signal. */
+ return max_rssi - agc - IWL_RSSI_OFFSET;
+}
+
+static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
+ priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
+ priv->stations[sta_id].sta.sta.modify_mask = 0;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+}
+
+static void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
+{
+ /* FIXME: need locking over ps_status ??? */
+ u8 sta_id = iwl_find_station(priv, addr);
+
+ if (sta_id != IWL_INVALID_STATION) {
+ u8 sta_awake = priv->stations[sta_id].
+ ps_status == STA_PS_STATUS_WAKE;
+
+ if (sta_awake && ps_bit)
+ priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP;
+ else if (!sta_awake && !ps_bit) {
+ iwl_sta_modify_ps_wake(priv, sta_id);
+ priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE;
+ }
+ }
+}
+
+/* This is necessary only for a number of statistics, see the caller. */
+static int iwl_is_network_packet(struct iwl_priv *priv,
+ struct ieee80211_hdr *header)
+{
+ /* Filter incoming packets to determine if they are targeted toward
+ * this network, discarding packets coming from ourselves */
+ switch (priv->iw_mode) {
+ case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
+ /* packets to our IBSS update information */
+ return !compare_ether_addr(header->addr3, priv->bssid);
+ case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
+ /* packets to our IBSS update information */
+ return !compare_ether_addr(header->addr2, priv->bssid);
+ default:
+ return 1;
+ }
+}
+
+/* Called for REPLY_RX (legacy ABG frames), or
+ * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
+void iwl_rx_reply_rx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct ieee80211_hdr *header;
+ struct ieee80211_rx_status rx_status;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ /* Use phy data (Rx signal strength, etc.) contained within
+ * this rx packet for legacy frames,
+ * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
+ int include_phy = (pkt->hdr.cmd == REPLY_RX);
+ struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
+ (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
+ (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
+ __le32 *rx_end;
+ unsigned int len = 0;
+ u16 fc;
+ u8 network_packet;
+
+ rx_status.mactime = le64_to_cpu(rx_start->timestamp);
+ rx_status.freq =
+ ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
+ rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
+ IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+ rx_status.rate_idx =
+ iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
+ if (rx_status.band == IEEE80211_BAND_5GHZ)
+ rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
+
+ rx_status.antenna = 0;
+ rx_status.flag = 0;
+ rx_status.flag |= RX_FLAG_TSFT;
+
+ if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
+ IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
+ rx_start->cfg_phy_cnt);
+ return;
+ }
+
+ if (!include_phy) {
+ if (priv->last_phy_res[0])
+ rx_start = (struct iwl4965_rx_phy_res *)
+ &priv->last_phy_res[1];
+ else
+ rx_start = NULL;
+ }
+
+ if (!rx_start) {
+ IWL_ERROR("MPDU frame without a PHY data\n");
+ return;
+ }
+
+ if (include_phy) {
+ header = (struct ieee80211_hdr *)((u8 *) &rx_start[1]
+ + rx_start->cfg_phy_cnt);
+
+ len = le16_to_cpu(rx_start->byte_count);
+ rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
+ sizeof(struct iwl4965_rx_phy_res) + len);
+ } else {
+ struct iwl4965_rx_mpdu_res_start *amsdu =
+ (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
+
+ header = (void *)(pkt->u.raw +
+ sizeof(struct iwl4965_rx_mpdu_res_start));
+ len = le16_to_cpu(amsdu->byte_count);
+ rx_end = (__le32 *) (pkt->u.raw +
+ sizeof(struct iwl4965_rx_mpdu_res_start) + len);
+ }
+
+ if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
+ !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
+ IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
+ le32_to_cpu(*rx_end));
+ return;
+ }
+
+ priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
+
+ /* Find max signal strength (dBm) among 3 antenna/receiver chains */
+ rx_status.signal = iwl_calc_rssi(priv, rx_start);
+
+ /* Meaningful noise values are available only from beacon statistics,
+ * which are gathered only when associated, and indicate noise
+ * only for the associated network channel ...
+ * Ignore these noise values while scanning (other channels) */
+ if (iwl_is_associated(priv) &&
+ !test_bit(STATUS_SCANNING, &priv->status)) {
+ rx_status.noise = priv->last_rx_noise;
+ rx_status.qual = iwl_calc_sig_qual(rx_status.signal,
+ rx_status.noise);
+ } else {
+ rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
+ rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0);
+ }
+
+ /* Reset beacon noise level if not associated. */
+ if (!iwl_is_associated(priv))
+ priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
+
+ /* Set "1" to report good data frames in groups of 100 */
+ /* FIXME: need to optimze the call: */
+ iwl_dbg_report_frame(priv, pkt, header, 1);
+
+ IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
+ rx_status.signal, rx_status.noise, rx_status.signal,
+ (unsigned long long)rx_status.mactime);
+
+ /* Take shortcut when only in monitor mode */
+ if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
+ iwl_pass_packet_to_mac80211(priv, include_phy,
+ rxb, &rx_status);
+ return;
+ }
+
+ network_packet = iwl_is_network_packet(priv, header);
+ if (network_packet) {
+ priv->last_rx_rssi = rx_status.signal;
+ priv->last_beacon_time = priv->ucode_beacon_time;
+ priv->last_tsf = le64_to_cpu(rx_start->timestamp);
+ }
+
+ fc = le16_to_cpu(header->frame_control);
+ switch (fc & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_MGMT:
+ case IEEE80211_FTYPE_DATA:
+ if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
+ iwl_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
+ header->addr2);
+ /* fall through */
+ default:
+ iwl_pass_packet_to_mac80211(priv, include_phy, rxb,
+ &rx_status);
+ break;
+
+ }
+}
+EXPORT_SYMBOL(iwl_rx_reply_rx);
+
+/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
+ * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
+void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ priv->last_phy_res[0] = 1;
+ memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
+ sizeof(struct iwl4965_rx_phy_res));
+}
+EXPORT_SYMBOL(iwl_rx_reply_rx_phy);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
new file mode 100644
index 00000000000..efc750d2fc5
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -0,0 +1,931 @@
+/******************************************************************************
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-io.h"
+#include "iwl-helpers.h"
+
+/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
+ * sending probe req. This should be set long enough to hear probe responses
+ * from more than one AP. */
+#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
+#define IWL_ACTIVE_DWELL_TIME_52 (20)
+
+#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
+#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
+#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
+
+/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
+ * Must be set longer than active dwell time.
+ * For the most reliable scan, set > AP beacon interval (typically 100msec). */
+#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
+#define IWL_PASSIVE_DWELL_TIME_52 (10)
+#define IWL_PASSIVE_DWELL_BASE (100)
+#define IWL_CHANNEL_TUNE_TIME 5
+
+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
+
+static int scan_tx_ant[3] = {
+ RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK
+};
+
+
+
+static int iwl_is_empty_essid(const char *essid, int essid_len)
+{
+ /* Single white space is for Linksys APs */
+ if (essid_len == 1 && essid[0] == ' ')
+ return 1;
+
+ /* Otherwise, if the entire essid is 0, we assume it is hidden */
+ while (essid_len) {
+ essid_len--;
+ if (essid[essid_len] != '\0')
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+const char *iwl_escape_essid(const char *essid, u8 essid_len)
+{
+ static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+ const char *s = essid;
+ char *d = escaped;
+
+ if (iwl_is_empty_essid(essid, essid_len)) {
+ memcpy(escaped, "<hidden>", sizeof("<hidden>"));
+ return escaped;
+ }
+
+ essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
+ while (essid_len--) {
+ if (*s == '\0') {
+ *d++ = '\\';
+ *d++ = '0';
+ s++;
+ } else
+ *d++ = *s++;
+ }
+ *d = '\0';
+ return escaped;
+}
+EXPORT_SYMBOL(iwl_escape_essid);
+
+/**
+ * iwl_scan_cancel - Cancel any currently executing HW scan
+ *
+ * NOTE: priv->mutex is not required before calling this function
+ */
+int iwl_scan_cancel(struct iwl_priv *priv)
+{
+ if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
+ clear_bit(STATUS_SCANNING, &priv->status);
+ return 0;
+ }
+
+ if (test_bit(STATUS_SCANNING, &priv->status)) {
+ if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN("Queuing scan abort.\n");
+ set_bit(STATUS_SCAN_ABORTING, &priv->status);
+ queue_work(priv->workqueue, &priv->abort_scan);
+
+ } else
+ IWL_DEBUG_SCAN("Scan abort already in progress.\n");
+
+ return test_bit(STATUS_SCANNING, &priv->status);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_scan_cancel);
+/**
+ * iwl_scan_cancel_timeout - Cancel any currently executing HW scan
+ * @ms: amount of time to wait (in milliseconds) for scan to abort
+ *
+ * NOTE: priv->mutex must be held before calling this function
+ */
+int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
+{
+ unsigned long now = jiffies;
+ int ret;
+
+ ret = iwl_scan_cancel(priv);
+ if (ret && ms) {
+ mutex_unlock(&priv->mutex);
+ while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
+ test_bit(STATUS_SCANNING, &priv->status))
+ msleep(1);
+ mutex_lock(&priv->mutex);
+
+ return test_bit(STATUS_SCANNING, &priv->status);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_scan_cancel_timeout);
+
+static int iwl_send_scan_abort(struct iwl_priv *priv)
+{
+ int ret = 0;
+ struct iwl_rx_packet *res;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_ABORT_CMD,
+ .meta.flags = CMD_WANT_SKB,
+ };
+
+ /* If there isn't a scan actively going on in the hardware
+ * then we are in between scan bands and not actually
+ * actively scanning, so don't send the abort command */
+ if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ return 0;
+ }
+
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret) {
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ return ret;
+ }
+
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+ if (res->u.status != CAN_ABORT_STATUS) {
+ /* The scan abort will return 1 for success or
+ * 2 for "failure". A failure condition can be
+ * due to simply not being in an active scan which
+ * can occur if we send the scan abort before we
+ * the microcode has notified us that a scan is
+ * completed. */
+ IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ }
+
+ dev_kfree_skb_any(cmd.meta.u.skb);
+
+ return ret;
+}
+
+
+/* Service response to REPLY_SCAN_CMD (0x80) */
+static void iwl_rx_reply_scan(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scanreq_notification *notif =
+ (struct iwl_scanreq_notification *)pkt->u.raw;
+
+ IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
+#endif
+}
+
+/* Service SCAN_START_NOTIFICATION (0x82) */
+static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scanstart_notification *notif =
+ (struct iwl_scanstart_notification *)pkt->u.raw;
+ priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
+ IWL_DEBUG_SCAN("Scan start: "
+ "%d [802.11%s] "
+ "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
+ notif->channel,
+ notif->band ? "bg" : "a",
+ le32_to_cpu(notif->tsf_high),
+ le32_to_cpu(notif->tsf_low),
+ notif->status, notif->beacon_timer);
+}
+
+/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
+static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scanresults_notification *notif =
+ (struct iwl_scanresults_notification *)pkt->u.raw;
+
+ IWL_DEBUG_SCAN("Scan ch.res: "
+ "%d [802.11%s] "
+ "(TSF: 0x%08X:%08X) - %d "
+ "elapsed=%lu usec (%dms since last)\n",
+ notif->channel,
+ notif->band ? "bg" : "a",
+ le32_to_cpu(notif->tsf_high),
+ le32_to_cpu(notif->tsf_low),
+ le32_to_cpu(notif->statistics[0]),
+ le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
+ jiffies_to_msecs(elapsed_jiffies
+ (priv->last_scan_jiffies, jiffies)));
+#endif
+
+ priv->last_scan_jiffies = jiffies;
+ priv->next_scan_jiffies = 0;
+}
+
+/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
+static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+
+ IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
+ scan_notif->scanned_channels,
+ scan_notif->tsf_low,
+ scan_notif->tsf_high, scan_notif->status);
+
+ /* The HW is no longer scanning */
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+
+ /* The scan completion notification came in, so kill that timer... */
+ cancel_delayed_work(&priv->scan_check);
+
+ IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
+ (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
+ "2.4" : "5.2",
+ jiffies_to_msecs(elapsed_jiffies
+ (priv->scan_pass_start, jiffies)));
+
+ /* Remove this scanned band from the list of pending
+ * bands to scan, band G precedes A in order of scanning
+ * as seen in iwl_bg_request_scan */
+ if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
+ priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
+ else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
+ priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
+
+ /* If a request to abort was given, or the scan did not succeed
+ * then we reset the scan state machine and terminate,
+ * re-queuing another scan if one has been requested */
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_INFO("Aborted scan completed.\n");
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ } else {
+ /* If there are more bands on this scan pass reschedule */
+ if (priv->scan_bands)
+ goto reschedule;
+ }
+
+ priv->last_scan_jiffies = jiffies;
+ priv->next_scan_jiffies = 0;
+ IWL_DEBUG_INFO("Setting scan to off\n");
+
+ clear_bit(STATUS_SCANNING, &priv->status);
+
+ IWL_DEBUG_INFO("Scan took %dms\n",
+ jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
+
+ queue_work(priv->workqueue, &priv->scan_completed);
+
+ return;
+
+reschedule:
+ priv->scan_pass_start = jiffies;
+ queue_work(priv->workqueue, &priv->request_scan);
+}
+
+void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
+{
+ /* scan handlers */
+ priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan;
+ priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif;
+ priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
+ iwl_rx_scan_results_notif;
+ priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
+ iwl_rx_scan_complete_notif;
+}
+EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);
+
+static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes)
+{
+ if (band == IEEE80211_BAND_5GHZ)
+ return IWL_ACTIVE_DWELL_TIME_52 +
+ IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
+ else
+ return IWL_ACTIVE_DWELL_TIME_24 +
+ IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
+}
+
+static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
+{
+ u16 passive = (band == IEEE80211_BAND_2GHZ) ?
+ IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
+ IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
+
+ if (iwl_is_associated(priv)) {
+ /* If we're associated, we clamp the maximum passive
+ * dwell time to be 98% of the beacon interval (minus
+ * 2 * channel tune time) */
+ passive = priv->beacon_int;
+ if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
+ passive = IWL_PASSIVE_DWELL_BASE;
+ passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ }
+
+ return passive;
+}
+
+static int iwl_get_channels_for_scan(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 is_active, u8 n_probes,
+ struct iwl_scan_channel *scan_ch)
+{
+ const struct ieee80211_channel *channels = NULL;
+ const struct ieee80211_supported_band *sband;
+ const struct iwl_channel_info *ch_info;
+ u16 passive_dwell = 0;
+ u16 active_dwell = 0;
+ int added, i;
+ u16 channel;
+
+ sband = iwl_get_hw_mode(priv, band);
+ if (!sband)
+ return 0;
+
+ channels = sband->channels;
+
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+ if (passive_dwell <= active_dwell)
+ passive_dwell = active_dwell + 1;
+
+ for (i = 0, added = 0; i < sband->n_channels; i++) {
+ if (channels[i].flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ channel =
+ ieee80211_frequency_to_channel(channels[i].center_freq);
+ scan_ch->channel = cpu_to_le16(channel);
+
+ ch_info = iwl_get_channel_info(priv, band, channel);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+ channel);
+ continue;
+ }
+
+ if (!is_active || is_channel_passive(ch_info) ||
+ (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
+ scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+ else
+ scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
+
+ if ((scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) && n_probes)
+ scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+
+ scan_ch->active_dwell = cpu_to_le16(active_dwell);
+ scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+
+ /* Set txpower levels to defaults */
+ scan_ch->dsp_atten = 110;
+
+ /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+ * power level:
+ * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
+ */
+ if (band == IEEE80211_BAND_5GHZ)
+ scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+ else
+ scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+
+ IWL_DEBUG_SCAN("Scanning ch=%d prob=0x%X [%s %d]\n",
+ channel, le32_to_cpu(scan_ch->type),
+ (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+ "ACTIVE" : "PASSIVE",
+ (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+ active_dwell : passive_dwell);
+
+ scan_ch++;
+ added++;
+ }
+
+ IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+ return added;
+}
+
+void iwl_init_scan_params(struct iwl_priv *priv)
+{
+ if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ])
+ priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND;
+ if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
+ priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND;
+}
+
+int iwl_scan_initiate(struct iwl_priv *priv)
+{
+ if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+ IWL_ERROR("APs don't scan.\n");
+ return 0;
+ }
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+ return -EIO;
+ }
+
+ if (test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN("Scan already in progress.\n");
+ return -EAGAIN;
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN("Scan request while abort pending. "
+ "Queuing.\n");
+ return -EAGAIN;
+ }
+
+ IWL_DEBUG_INFO("Starting scan...\n");
+ if (priv->cfg->sku & IWL_SKU_G)
+ priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+ if (priv->cfg->sku & IWL_SKU_A)
+ priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
+ set_bit(STATUS_SCANNING, &priv->status);
+ priv->scan_start = jiffies;
+ priv->scan_pass_start = priv->scan_start;
+
+ queue_work(priv->workqueue, &priv->request_scan);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_scan_initiate);
+
+#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
+
+static void iwl_bg_scan_check(struct work_struct *data)
+{
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, scan_check.work);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+ if (test_bit(STATUS_SCANNING, &priv->status) ||
+ test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "
+ "adapter (%dms)\n",
+ jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
+ iwl_send_scan_abort(priv);
+ }
+ mutex_unlock(&priv->mutex);
+}
+/**
+ * iwl_supported_rate_to_ie - fill in the supported rate in IE field
+ *
+ * return : set the bit for each supported rate insert in ie
+ */
+static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
+ u16 basic_rate, int *left)
+{
+ u16 ret_rates = 0, bit;
+ int i;
+ u8 *cnt = ie;
+ u8 *rates = ie + 1;
+
+ for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
+ if (bit & supported_rate) {
+ ret_rates |= bit;
+ rates[*cnt] = iwl_rates[i].ieee |
+ ((bit & basic_rate) ? 0x80 : 0x00);
+ (*cnt)++;
+ (*left)--;
+ if ((*left <= 0) ||
+ (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
+ break;
+ }
+ }
+
+ return ret_rates;
+}
+
+
+static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
+ u8 *pos, int *left)
+{
+ struct ieee80211_ht_cap *ht_cap;
+
+ if (!sband || !sband->ht_info.ht_supported)
+ return;
+
+ if (*left < sizeof(struct ieee80211_ht_cap))
+ return;
+
+ *pos++ = sizeof(struct ieee80211_ht_cap);
+ ht_cap = (struct ieee80211_ht_cap *) pos;
+
+ ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);
+ memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);
+ ht_cap->ampdu_params_info =
+ (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |
+ ((sband->ht_info.ampdu_density << 2) &
+ IEEE80211_HT_CAP_AMPDU_DENSITY);
+ *left -= sizeof(struct ieee80211_ht_cap);
+}
+
+/**
+ * iwl_fill_probe_req - fill in all required fields and IE for probe request
+ */
+
+static u16 iwl_fill_probe_req(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left)
+{
+ int len = 0;
+ u8 *pos = NULL;
+ u16 active_rates, ret_rates, cck_rates, active_rate_basic;
+ const struct ieee80211_supported_band *sband =
+ iwl_get_hw_mode(priv, band);
+
+
+ /* Make sure there is enough space for the probe request,
+ * two mandatory IEs and the data */
+ left -= 24;
+ if (left < 0)
+ return 0;
+
+ frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+ memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
+ memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
+ memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
+ frame->seq_ctrl = 0;
+
+ len += 24;
+
+ /* ...next IE... */
+ pos = &frame->u.probe_req.variable[0];
+
+ /* fill in our indirect SSID IE */
+ left -= 2;
+ if (left < 0)
+ return 0;
+ *pos++ = WLAN_EID_SSID;
+ *pos++ = 0;
+
+ len += 2;
+
+ /* fill in supported rate */
+ left -= 2;
+ if (left < 0)
+ return 0;
+
+ *pos++ = WLAN_EID_SUPP_RATES;
+ *pos = 0;
+
+ /* exclude 60M rate */
+ active_rates = priv->rates_mask;
+ active_rates &= ~IWL_RATE_60M_MASK;
+
+ active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
+
+ cck_rates = IWL_CCK_RATES_MASK & active_rates;
+ ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+ active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
+ ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+ active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
+ len += 2 + *pos;
+ pos += (*pos) + 1;
+
+ if (active_rates == 0)
+ goto fill_end;
+
+ /* fill in supported extended rate */
+ /* ...next IE... */
+ left -= 2;
+ if (left < 0)
+ return 0;
+ /* ... fill it in... */
+ *pos++ = WLAN_EID_EXT_SUPP_RATES;
+ *pos = 0;
+ iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left);
+ if (*pos > 0) {
+ len += 2 + *pos;
+ pos += (*pos) + 1;
+ } else {
+ pos--;
+ }
+
+ fill_end:
+
+ left -= 2;
+ if (left < 0)
+ return 0;
+
+ *pos++ = WLAN_EID_HT_CAPABILITY;
+ *pos = 0;
+ iwl_ht_cap_to_ie(sband, pos, &left);
+ if (*pos > 0)
+ len += 2 + *pos;
+
+ return (u16)len;
+}
+
+static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band)
+{
+ int i, ind;
+
+ ind = priv->scan_tx_ant[band];
+ for (i = 0; i < priv->hw_params.tx_chains_num; i++) {
+ ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1;
+ if (priv->hw_params.valid_tx_ant & (1 << ind)) {
+ priv->scan_tx_ant[band] = ind;
+ break;
+ }
+ }
+ IWL_DEBUG_SCAN("select TX ANT = %c\n", 'A' + ind);
+ return scan_tx_ant[ind];
+}
+
+
+static void iwl_bg_request_scan(struct work_struct *data)
+{
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, request_scan);
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_CMD,
+ .len = sizeof(struct iwl_scan_cmd),
+ .meta.flags = CMD_SIZE_HUGE,
+ };
+ struct iwl_scan_cmd *scan;
+ struct ieee80211_conf *conf = NULL;
+ int ret = 0;
+ u32 tx_ant;
+ u16 cmd_len;
+ enum ieee80211_band band;
+ u8 n_probes = 2;
+ u8 rx_chain = 0x7; /* bitmap: ABC chains */
+
+ conf = ieee80211_get_hw_conf(priv->hw);
+
+ mutex_lock(&priv->mutex);
+
+ if (!iwl_is_ready(priv)) {
+ IWL_WARNING("request scan called when driver not ready.\n");
+ goto done;
+ }
+
+ /* Make sure the scan wasn't cancelled before this queued work
+ * was given the chance to run... */
+ if (!test_bit(STATUS_SCANNING, &priv->status))
+ goto done;
+
+ /* This should never be called or scheduled if there is currently
+ * a scan active in the hardware. */
+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+ IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
+ "Ignoring second request.\n");
+ ret = -EIO;
+ goto done;
+ }
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+ goto done;
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ goto done;
+ }
+
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ goto done;
+ }
+
+ if (!test_bit(STATUS_READY, &priv->status)) {
+ IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
+ goto done;
+ }
+
+ if (!priv->scan_bands) {
+ IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+ goto done;
+ }
+
+ if (!priv->scan) {
+ priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
+ IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+ if (!priv->scan) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ }
+ scan = priv->scan;
+ memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+
+ scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
+ scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
+
+ if (iwl_is_associated(priv)) {
+ u16 interval = 0;
+ u32 extra;
+ u32 suspend_time = 100;
+ u32 scan_suspend_time = 100;
+ unsigned long flags;
+
+ IWL_DEBUG_INFO("Scanning while associated...\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ interval = priv->beacon_int;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ scan->suspend_time = 0;
+ scan->max_out_time = cpu_to_le32(200 * 1024);
+ if (!interval)
+ interval = suspend_time;
+
+ extra = (suspend_time / interval) << 22;
+ scan_suspend_time = (extra |
+ ((suspend_time % interval) * 1024));
+ scan->suspend_time = cpu_to_le32(scan_suspend_time);
+ IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+ scan_suspend_time, interval);
+ }
+
+ /* We should add the ability for user to lock to PASSIVE ONLY */
+ if (priv->one_direct_scan) {
+ IWL_DEBUG_SCAN("Start direct scan for '%s'\n",
+ iwl_escape_essid(priv->direct_ssid,
+ priv->direct_ssid_len));
+ scan->direct_scan[0].id = WLAN_EID_SSID;
+ scan->direct_scan[0].len = priv->direct_ssid_len;
+ memcpy(scan->direct_scan[0].ssid,
+ priv->direct_ssid, priv->direct_ssid_len);
+ n_probes++;
+ } else if (!iwl_is_associated(priv) && priv->essid_len) {
+ IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n",
+ iwl_escape_essid(priv->essid, priv->essid_len));
+ scan->direct_scan[0].id = WLAN_EID_SSID;
+ scan->direct_scan[0].len = priv->essid_len;
+ memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
+ n_probes++;
+ } else {
+ IWL_DEBUG_SCAN("Start indirect scan.\n");
+ }
+
+ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
+ scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+ scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+
+
+ if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
+ band = IEEE80211_BAND_2GHZ;
+ scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
+ tx_ant = iwl_scan_tx_ant(priv, band);
+ if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK)
+ scan->tx_cmd.rate_n_flags =
+ iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
+ tx_ant);
+ else
+ scan->tx_cmd.rate_n_flags =
+ iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
+ tx_ant |
+ RATE_MCS_CCK_MSK);
+ scan->good_CRC_th = 0;
+ } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
+ band = IEEE80211_BAND_5GHZ;
+ tx_ant = iwl_scan_tx_ant(priv, band);
+ scan->tx_cmd.rate_n_flags =
+ iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
+ tx_ant);
+ scan->good_CRC_th = IWL_GOOD_CRC_TH;
+
+ /* Force use of chains B and C (0x6) for scan Rx for 4965
+ * Avoid A (0x1) because of its off-channel reception on A-band.
+ * MIMO is not used here, but value is required */
+ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
+ rx_chain = 0x6;
+ } else {
+ IWL_WARNING("Invalid scan band count\n");
+ goto done;
+ }
+
+ scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
+ cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
+ (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |
+ (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
+
+ cmd_len = iwl_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan));
+
+ scan->tx_cmd.len = cpu_to_le16(cmd_len);
+
+ if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
+ scan->filter_flags = RXON_FILTER_PROMISC_MSK;
+
+ scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
+ RXON_FILTER_BCON_AWARE_MSK);
+
+ scan->channel_count =
+ iwl_get_channels_for_scan(priv, band, 1, /* active */
+ n_probes,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+
+ if (scan->channel_count == 0) {
+ IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ goto done;
+ }
+
+ cmd.len += le16_to_cpu(scan->tx_cmd.len) +
+ scan->channel_count * sizeof(struct iwl_scan_channel);
+ cmd.data = scan;
+ scan->len = cpu_to_le16(cmd.len);
+
+ set_bit(STATUS_SCAN_HW, &priv->status);
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret)
+ goto done;
+
+ queue_delayed_work(priv->workqueue, &priv->scan_check,
+ IWL_SCAN_CHECK_WATCHDOG);
+
+ mutex_unlock(&priv->mutex);
+ return;
+
+ done:
+ /* inform mac80211 scan aborted */
+ queue_work(priv->workqueue, &priv->scan_completed);
+ mutex_unlock(&priv->mutex);
+}
+
+static void iwl_bg_abort_scan(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
+
+ if (!iwl_is_ready(priv))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ set_bit(STATUS_SCAN_ABORTING, &priv->status);
+ iwl_send_scan_abort(priv);
+
+ mutex_unlock(&priv->mutex);
+}
+
+void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
+{
+ /* FIXME: move here when resolved PENDING
+ * INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); */
+ INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
+}
+EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index e4fdfaa2b9b..6d1467d0bd9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -28,17 +28,446 @@
*****************************************************************************/
#include <net/mac80211.h>
+#include <linux/etherdevice.h>
-#include "iwl-eeprom.h"
-#include "iwl-4965.h"
+#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-sta.h"
-#include "iwl-io.h"
#include "iwl-helpers.h"
-#include "iwl-4965.h"
-#include "iwl-sta.h"
-int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+
+#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
+#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
+
+u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
+{
+ int i;
+ int start = 0;
+ int ret = IWL_INVALID_STATION;
+ unsigned long flags;
+ DECLARE_MAC_BUF(mac);
+
+ if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) ||
+ (priv->iw_mode == IEEE80211_IF_TYPE_AP))
+ start = IWL_STA_ID;
+
+ if (is_broadcast_ether_addr(addr))
+ return priv->hw_params.bcast_sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ for (i = start; i < priv->hw_params.max_stations; i++)
+ if (priv->stations[i].used &&
+ (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+ addr))) {
+ ret = i;
+ goto out;
+ }
+
+ IWL_DEBUG_ASSOC_LIMIT("can not find STA %s total %d\n",
+ print_mac(mac, addr), priv->num_stations);
+
+ out:
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_find_station);
+
+int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
+{
+ if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
+ return IWL_AP_ID;
+ } else {
+ u8 *da = ieee80211_get_DA(hdr);
+ return iwl_find_station(priv, da);
+ }
+}
+EXPORT_SYMBOL(iwl_get_ra_sta_id);
+
+static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
+{
+ unsigned long flags;
+ DECLARE_MAC_BUF(mac);
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+ IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id);
+
+ priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
+ IWL_DEBUG_ASSOC("Added STA to Ucode: %s\n",
+ print_mac(mac, priv->stations[sta_id].sta.sta.addr));
+
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+}
+
+static int iwl_add_sta_callback(struct iwl_priv *priv,
+ struct iwl_cmd *cmd, struct sk_buff *skb)
+{
+ struct iwl_rx_packet *res = NULL;
+ u8 sta_id = cmd->cmd.addsta.sta.sta_id;
+
+ if (!skb) {
+ IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
+ return 1;
+ }
+
+ res = (struct iwl_rx_packet *)skb->data;
+ if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ res->hdr.flags);
+ return 1;
+ }
+
+ switch (res->u.add_sta.status) {
+ case ADD_STA_SUCCESS_MSK:
+ iwl_sta_ucode_activate(priv, sta_id);
+ /* fall through */
+ default:
+ IWL_DEBUG_HC("Received REPLY_ADD_STA:(0x%08X)\n",
+ res->u.add_sta.status);
+ break;
+ }
+
+ /* We didn't cache the SKB; let the caller free it */
+ return 1;
+}
+
+int iwl_send_add_sta(struct iwl_priv *priv,
+ struct iwl_addsta_cmd *sta, u8 flags)
+{
+ struct iwl_rx_packet *res = NULL;
+ int ret = 0;
+ u8 data[sizeof(*sta)];
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_ADD_STA,
+ .meta.flags = flags,
+ .data = data,
+ };
+
+ if (flags & CMD_ASYNC)
+ cmd.meta.u.callback = iwl_add_sta_callback;
+ else
+ cmd.meta.flags |= CMD_WANT_SKB;
+
+ cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
+ ret = iwl_send_cmd(priv, &cmd);
+
+ if (ret || (flags & CMD_ASYNC))
+ return ret;
+
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+ if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ res->hdr.flags);
+ ret = -EIO;
+ }
+
+ if (ret == 0) {
+ switch (res->u.add_sta.status) {
+ case ADD_STA_SUCCESS_MSK:
+ iwl_sta_ucode_activate(priv, sta->sta.sta_id);
+ IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
+ break;
+ default:
+ ret = -EIO;
+ IWL_WARNING("REPLY_ADD_STA failed\n");
+ break;
+ }
+ }
+
+ priv->alloc_rxb_skb--;
+ dev_kfree_skb_any(cmd.meta.u.skb);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_send_add_sta);
+
+static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
+ struct ieee80211_ht_info *sta_ht_inf)
+{
+ __le32 sta_flags;
+ u8 mimo_ps_mode;
+
+ if (!sta_ht_inf || !sta_ht_inf->ht_supported)
+ goto done;
+
+ mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2;
+
+ sta_flags = priv->stations[index].sta.station_flags;
+
+ sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
+
+ switch (mimo_ps_mode) {
+ case WLAN_HT_CAP_MIMO_PS_STATIC:
+ sta_flags |= STA_FLG_MIMO_DIS_MSK;
+ break;
+ case WLAN_HT_CAP_MIMO_PS_DYNAMIC:
+ sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
+ break;
+ case WLAN_HT_CAP_MIMO_PS_DISABLED:
+ break;
+ default:
+ IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode);
+ break;
+ }
+
+ sta_flags |= cpu_to_le32(
+ (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
+
+ sta_flags |= cpu_to_le32(
+ (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
+
+ if (iwl_is_fat_tx_allowed(priv, sta_ht_inf))
+ sta_flags |= STA_FLG_FAT_EN_MSK;
+ else
+ sta_flags &= ~STA_FLG_FAT_EN_MSK;
+
+ priv->stations[index].sta.station_flags = sta_flags;
+ done:
+ return;
+}
+
+/**
+ * iwl_add_station_flags - Add station to tables in driver and device
+ */
+u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
+ u8 flags, struct ieee80211_ht_info *ht_info)
+{
+ int i;
+ int sta_id = IWL_INVALID_STATION;
+ struct iwl_station_entry *station;
+ unsigned long flags_spin;
+ DECLARE_MAC_BUF(mac);
+
+ spin_lock_irqsave(&priv->sta_lock, flags_spin);
+ if (is_ap)
+ sta_id = IWL_AP_ID;
+ else if (is_broadcast_ether_addr(addr))
+ sta_id = priv->hw_params.bcast_sta_id;
+ else
+ for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
+ if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+ addr)) {
+ sta_id = i;
+ break;
+ }
+
+ if (!priv->stations[i].used &&
+ sta_id == IWL_INVALID_STATION)
+ sta_id = i;
+ }
+
+ /* These two conditions have the same outcome, but keep them separate
+ since they have different meanings */
+ if (unlikely(sta_id == IWL_INVALID_STATION)) {
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ return sta_id;
+ }
+
+ if (priv->stations[sta_id].used &&
+ !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+ return sta_id;
+ }
+
+
+ station = &priv->stations[sta_id];
+ station->used = IWL_STA_DRIVER_ACTIVE;
+ IWL_DEBUG_ASSOC("Add STA to driver ID %d: %s\n",
+ sta_id, print_mac(mac, addr));
+ priv->num_stations++;
+
+ /* Set up the REPLY_ADD_STA command to send to device */
+ memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
+ memcpy(station->sta.sta.addr, addr, ETH_ALEN);
+ station->sta.mode = 0;
+ station->sta.sta.sta_id = sta_id;
+ station->sta.station_flags = 0;
+
+ /* BCAST station and IBSS stations do not work in HT mode */
+ if (sta_id != priv->hw_params.bcast_sta_id &&
+ priv->iw_mode != IEEE80211_IF_TYPE_IBSS)
+ iwl_set_ht_add_station(priv, sta_id, ht_info);
+
+ spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
+
+ /* Add station to device's station table */
+ iwl_send_add_sta(priv, &station->sta, flags);
+ return sta_id;
+
+}
+EXPORT_SYMBOL(iwl_add_station_flags);
+
+static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
+{
+ unsigned long flags;
+ DECLARE_MAC_BUF(mac);
+
+ u8 sta_id = iwl_find_station(priv, addr);
+
+ BUG_ON(sta_id == IWL_INVALID_STATION);
+
+ IWL_DEBUG_ASSOC("Removed STA from Ucode: %s\n",
+ print_mac(mac, addr));
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+
+ /* Ucode must be active and driver must be non active */
+ if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
+ IWL_ERROR("removed non active STA %d\n", sta_id);
+
+ priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
+
+ memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+}
+
+static int iwl_remove_sta_callback(struct iwl_priv *priv,
+ struct iwl_cmd *cmd, struct sk_buff *skb)
+{
+ struct iwl_rx_packet *res = NULL;
+ const char *addr = cmd->cmd.rm_sta.addr;
+
+ if (!skb) {
+ IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n");
+ return 1;
+ }
+
+ res = (struct iwl_rx_packet *)skb->data;
+ if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ res->hdr.flags);
+ return 1;
+ }
+
+ switch (res->u.rem_sta.status) {
+ case REM_STA_SUCCESS_MSK:
+ iwl_sta_ucode_deactivate(priv, addr);
+ break;
+ default:
+ IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ break;
+ }
+
+ /* We didn't cache the SKB; let the caller free it */
+ return 1;
+}
+
+static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
+ u8 flags)
+{
+ struct iwl_rx_packet *res = NULL;
+ int ret;
+
+ struct iwl_rem_sta_cmd rm_sta_cmd;
+
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_REMOVE_STA,
+ .len = sizeof(struct iwl_rem_sta_cmd),
+ .meta.flags = flags,
+ .data = &rm_sta_cmd,
+ };
+
+ memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
+ rm_sta_cmd.num_sta = 1;
+ memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN);
+
+ if (flags & CMD_ASYNC)
+ cmd.meta.u.callback = iwl_remove_sta_callback;
+ else
+ cmd.meta.flags |= CMD_WANT_SKB;
+ ret = iwl_send_cmd(priv, &cmd);
+
+ if (ret || (flags & CMD_ASYNC))
+ return ret;
+
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+ if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+ IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ res->hdr.flags);
+ ret = -EIO;
+ }
+
+ if (!ret) {
+ switch (res->u.rem_sta.status) {
+ case REM_STA_SUCCESS_MSK:
+ iwl_sta_ucode_deactivate(priv, addr);
+ IWL_DEBUG_ASSOC("REPLY_REMOVE_STA PASSED\n");
+ break;
+ default:
+ ret = -EIO;
+ IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ break;
+ }
+ }
+
+ priv->alloc_rxb_skb--;
+ dev_kfree_skb_any(cmd.meta.u.skb);
+
+ return ret;
+}
+
+/**
+ * iwl_remove_station - Remove driver's knowledge of station.
+ */
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+{
+ int sta_id = IWL_INVALID_STATION;
+ int i, ret = -EINVAL;
+ unsigned long flags;
+ DECLARE_MAC_BUF(mac);
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+
+ if (is_ap)
+ sta_id = IWL_AP_ID;
+ else if (is_broadcast_ether_addr(addr))
+ sta_id = priv->hw_params.bcast_sta_id;
+ else
+ for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
+ if (priv->stations[i].used &&
+ !compare_ether_addr(priv->stations[i].sta.sta.addr,
+ addr)) {
+ sta_id = i;
+ break;
+ }
+
+ if (unlikely(sta_id == IWL_INVALID_STATION))
+ goto out;
+
+ IWL_DEBUG_ASSOC("Removing STA from driver:%d %s\n",
+ sta_id, print_mac(mac, addr));
+
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
+ IWL_ERROR("Removing %s but non DRIVER active\n",
+ print_mac(mac, addr));
+ goto out;
+ }
+
+ if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
+ IWL_ERROR("Removing %s but non UCODE active\n",
+ print_mac(mac, addr));
+ goto out;
+ }
+
+
+ priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
+
+ priv->num_stations--;
+
+ BUG_ON(priv->num_stations < 0);
+
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ ret = iwl_send_remove_station(priv, addr, CMD_ASYNC);
+ return ret;
+out:
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_remove_station);
+
+static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
@@ -91,6 +520,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
else
return 0;
}
+EXPORT_SYMBOL(iwl_send_static_wepkey_cmd);
int iwl_remove_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf)
@@ -107,10 +537,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
priv->default_wep_key--;
memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
ret = iwl_send_static_wepkey_cmd(priv, 1);
+ IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
+ keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
}
+EXPORT_SYMBOL(iwl_remove_default_wep_key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf)
@@ -118,8 +551,14 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
int ret;
unsigned long flags;
+ if (keyconf->keylen != WEP_KEY_LEN_128 &&
+ keyconf->keylen != WEP_KEY_LEN_64) {
+ IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
+ return -EINVAL;
+ }
+
keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
- keyconf->hw_key_idx = keyconf->keyidx;
+ keyconf->hw_key_idx = HW_KEY_DEFAULT;
priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
spin_lock_irqsave(&priv->sta_lock, flags);
@@ -134,10 +573,13 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
keyconf->keylen);
ret = iwl_send_static_wepkey_cmd(priv, 0);
+ IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
+ keyconf->keylen, keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
}
+EXPORT_SYMBOL(iwl_set_default_wep_key);
static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
@@ -148,7 +590,6 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
int ret;
keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
- keyconf->hw_key_idx = keyconf->keyidx;
key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
@@ -172,15 +613,18 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
memcpy(&priv->stations[sta_id].sta.key.key[3],
keyconf->key, keyconf->keylen);
- priv->stations[sta_id].sta.key.key_offset =
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
- priv->stations[sta_id].sta.key.key_flags = key_flags;
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- ret = iwl4965_send_add_station(priv,
- &priv->stations[sta_id].sta, CMD_ASYNC);
+ ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -202,7 +646,6 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- keyconf->hw_key_idx = keyconf->keyidx;
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].keyinfo.alg = keyconf->alg;
@@ -214,8 +657,13 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
keyconf->keylen);
- priv->stations[sta_id].sta.key.key_offset =
- iwl_get_free_ucode_key_index(priv);
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
+
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
@@ -223,8 +671,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
spin_unlock_irqrestore(&priv->sta_lock, flags);
IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
- return iwl4965_send_add_station(priv,
- &priv->stations[sta_id].sta, CMD_ASYNC);
+ return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
}
static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
@@ -236,15 +683,18 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- keyconf->hw_key_idx = keyconf->keyidx;
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.conf = keyconf;
priv->stations[sta_id].keyinfo.keylen = 16;
- priv->stations[sta_id].sta.key.key_offset =
+
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
/* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -256,54 +706,84 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
return ret;
}
-int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id)
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
unsigned long flags;
+ int ret = 0;
+ u16 key_flags;
+ u8 keyidx;
- priv->key_mapping_key = 0;
+ priv->key_mapping_key--;
spin_lock_irqsave(&priv->sta_lock, flags);
+ key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
+ keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
+
+ IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
+ keyconf->keyidx, sta_id);
+
+ if (keyconf->keyidx != keyidx) {
+ /* We need to remove a key with index different that the one
+ * in the uCode. This means that the key we need to remove has
+ * been replaced by another one with different index.
+ * Don't do anything and return ok
+ */
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return 0;
+ }
+
if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
&priv->ucode_key_table))
IWL_ERROR("index %d not used in uCode key table.\n",
priv->stations[sta_id].sta.key.key_offset);
memset(&priv->stations[sta_id].keyinfo, 0,
- sizeof(struct iwl4965_hw_key));
+ sizeof(struct iwl_hw_key));
memset(&priv->stations[sta_id].sta.key, 0,
sizeof(struct iwl4965_keyinfo));
- priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+ priv->stations[sta_id].sta.key.key_flags =
+ STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+ priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
- return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+ ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
}
+EXPORT_SYMBOL(iwl_remove_dynamic_key);
int iwl_set_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key, u8 sta_id)
+ struct ieee80211_key_conf *keyconf, u8 sta_id)
{
int ret;
- priv->key_mapping_key = 1;
+ priv->key_mapping_key++;
+ keyconf->hw_key_idx = HW_KEY_DYNAMIC;
- switch (key->alg) {
+ switch (keyconf->alg) {
case ALG_CCMP:
- ret = iwl_set_ccmp_dynamic_key_info(priv, key, sta_id);
+ ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
break;
case ALG_TKIP:
- ret = iwl_set_tkip_dynamic_key_info(priv, key, sta_id);
+ ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
break;
case ALG_WEP:
- ret = iwl_set_wep_dynamic_key_info(priv, key, sta_id);
+ ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
break;
default:
- IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, key->alg);
+ IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
ret = -EINVAL;
}
+ IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ sta_id, ret);
+
return ret;
}
+EXPORT_SYMBOL(iwl_set_dynamic_key);
#ifdef CONFIG_IWLWIFI_DEBUG
static void iwl_dump_lq_cmd(struct iwl_priv *priv,
@@ -345,11 +825,171 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
iwl_dump_lq_cmd(priv,lq);
- if (iwl_is_associated(priv) && priv->assoc_station_added &&
- priv->lq_mngr.lq_ready)
+ if (iwl_is_associated(priv) && priv->assoc_station_added)
return iwl_send_cmd(priv, &cmd);
return 0;
}
EXPORT_SYMBOL(iwl_send_lq_cmd);
+/**
+ * iwl_sta_init_lq - Initialize a station's hardware rate table
+ *
+ * The uCode's station table contains a table of fallback rates
+ * for automatic fallback during transmission.
+ *
+ * NOTE: This sets up a default set of values. These will be replaced later
+ * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of
+ * rc80211_simple.
+ *
+ * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
+ * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
+ * which requires station table entry to exist).
+ */
+static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
+{
+ int i, r;
+ struct iwl_link_quality_cmd link_cmd = {
+ .reserved1 = 0,
+ };
+ u16 rate_flags;
+
+ /* Set up the rate scaling to start at selected rate, fall back
+ * all the way down to 1M in IEEE order, and then spin on 1M */
+ if (is_ap)
+ r = IWL_RATE_54M_INDEX;
+ else if (priv->band == IEEE80211_BAND_5GHZ)
+ r = IWL_RATE_6M_INDEX;
+ else
+ r = IWL_RATE_1M_INDEX;
+
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+ rate_flags = 0;
+ if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
+ rate_flags |= RATE_MCS_CCK_MSK;
+
+ /* Use Tx antenna B only */
+ rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
+
+ link_cmd.rs_table[i].rate_n_flags =
+ iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
+ r = iwl4965_get_prev_ieee_rate(r);
+ }
+
+ link_cmd.general_params.single_stream_ant_msk = 2;
+ link_cmd.general_params.dual_stream_ant_msk = 3;
+ link_cmd.agg_params.agg_dis_start_th = 3;
+ link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
+
+ /* Update the rate scaling for control frame Tx to AP */
+ link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
+
+ iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
+ sizeof(link_cmd), &link_cmd, NULL);
+}
+
+/**
+ * iwl_rxon_add_station - add station into station table.
+ *
+ * there is only one AP station with id= IWL_AP_ID
+ * NOTE: mutex must be held before calling this fnction
+ */
+int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+{
+ u8 sta_id;
+
+ /* Add station to device's station table */
+ struct ieee80211_conf *conf = &priv->hw->conf;
+ struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;
+
+ if ((is_ap) &&
+ (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
+ (priv->iw_mode == IEEE80211_IF_TYPE_STA))
+ sta_id = iwl_add_station_flags(priv, addr, is_ap,
+ 0, cur_ht_config);
+ else
+ sta_id = iwl_add_station_flags(priv, addr, is_ap,
+ 0, NULL);
+
+ /* Set up default rate scaling table in device's station table */
+ iwl_sta_init_lq(priv, addr, is_ap);
+
+ return sta_id;
+}
+EXPORT_SYMBOL(iwl_rxon_add_station);
+
+/**
+ * iwl_get_sta_id - Find station's index within station table
+ *
+ * If new IBSS station, create new entry in station table
+ */
+int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
+{
+ int sta_id;
+ u16 fc = le16_to_cpu(hdr->frame_control);
+ DECLARE_MAC_BUF(mac);
+
+ /* If this frame is broadcast or management, use broadcast station id */
+ if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
+ is_multicast_ether_addr(hdr->addr1))
+ return priv->hw_params.bcast_sta_id;
+
+ switch (priv->iw_mode) {
+
+ /* If we are a client station in a BSS network, use the special
+ * AP station entry (that's the only station we communicate with) */
+ case IEEE80211_IF_TYPE_STA:
+ return IWL_AP_ID;
+
+ /* If we are an AP, then find the station, or use BCAST */
+ case IEEE80211_IF_TYPE_AP:
+ sta_id = iwl_find_station(priv, hdr->addr1);
+ if (sta_id != IWL_INVALID_STATION)
+ return sta_id;
+ return priv->hw_params.bcast_sta_id;
+
+ /* If this frame is going out to an IBSS network, find the station,
+ * or create a new station table entry */
+ case IEEE80211_IF_TYPE_IBSS:
+ sta_id = iwl_find_station(priv, hdr->addr1);
+ if (sta_id != IWL_INVALID_STATION)
+ return sta_id;
+
+ /* Create new station table entry */
+ sta_id = iwl_add_station_flags(priv, hdr->addr1,
+ 0, CMD_ASYNC, NULL);
+
+ if (sta_id != IWL_INVALID_STATION)
+ return sta_id;
+
+ IWL_DEBUG_DROP("Station %s not in station map. "
+ "Defaulting to broadcast...\n",
+ print_mac(mac, hdr->addr1));
+ iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
+ return priv->hw_params.bcast_sta_id;
+
+ default:
+ IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
+ return priv->hw_params.bcast_sta_id;
+ }
+}
+EXPORT_SYMBOL(iwl_get_sta_id);
+
+/**
+ * iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table
+ */
+void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid)
+{
+ unsigned long flags;
+
+ /* Remove "disable" flag, to enable Tx for this TID */
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
+ priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+}
+EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 44f272ecc82..221b93e670a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -29,21 +29,27 @@
#ifndef __iwl_sta_h__
#define __iwl_sta_h__
-#include <net/mac80211.h>
+#define HW_KEY_DYNAMIC 0
+#define HW_KEY_DEFAULT 1
-#include "iwl-eeprom.h"
-#include "iwl-core.h"
-#include "iwl-4965.h"
-#include "iwl-io.h"
-#include "iwl-helpers.h"
+/**
+ * iwl_find_station - Find station id for a given BSSID
+ * @bssid: MAC address of station ID to find
+ */
+u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
-int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty);
int iwl_remove_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key);
+ struct ieee80211_key_conf *key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key);
-int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id);
+ struct ieee80211_key_conf *key);
int iwl_set_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key, u8 sta_id);
+ struct ieee80211_key_conf *key, u8 sta_id);
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *key, u8 sta_id);
+int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
+int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
+void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid);
+int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
new file mode 100644
index 00000000000..9b50b1052b0
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -0,0 +1,1519 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project, as well
+ * as portions of the ieee80211 subsystem header files.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-io.h"
+#include "iwl-helpers.h"
+
+static const u16 default_tid_to_tx_fifo[] = {
+ IWL_TX_FIFO_AC1,
+ IWL_TX_FIFO_AC0,
+ IWL_TX_FIFO_AC0,
+ IWL_TX_FIFO_AC1,
+ IWL_TX_FIFO_AC2,
+ IWL_TX_FIFO_AC2,
+ IWL_TX_FIFO_AC3,
+ IWL_TX_FIFO_AC3,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_NONE,
+ IWL_TX_FIFO_AC3
+};
+
+
+/**
+ * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ *
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
+ */
+int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+ struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
+ struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
+ struct pci_dev *dev = priv->pci_dev;
+ int i;
+ int counter = 0;
+ int index, is_odd;
+
+ /* Host command buffers stay mapped in memory, nothing to clean */
+ if (txq->q.id == IWL_CMD_QUEUE_NUM)
+ return 0;
+
+ /* Sanity check on number of chunks */
+ counter = IWL_GET_BITS(*bd, num_tbs);
+ if (counter > MAX_NUM_OF_TBS) {
+ IWL_ERROR("Too many chunks: %i\n", counter);
+ /* @todo issue fatal error, it is quite serious situation */
+ return 0;
+ }
+
+ /* Unmap chunks, if any.
+ * TFD info for odd chunks is different format than for even chunks. */
+ for (i = 0; i < counter; i++) {
+ index = i / 2;
+ is_odd = i & 0x1;
+
+ if (is_odd)
+ pci_unmap_single(
+ dev,
+ IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
+ (IWL_GET_BITS(bd->pa[index],
+ tb2_addr_hi20) << 16),
+ IWL_GET_BITS(bd->pa[index], tb2_len),
+ PCI_DMA_TODEVICE);
+
+ else if (i > 0)
+ pci_unmap_single(dev,
+ le32_to_cpu(bd->pa[index].tb1_addr),
+ IWL_GET_BITS(bd->pa[index], tb1_len),
+ PCI_DMA_TODEVICE);
+
+ /* Free SKB, if any, for this chunk */
+ if (txq->txb[txq->q.read_ptr].skb[i]) {
+ struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i];
+
+ dev_kfree_skb(skb);
+ txq->txb[txq->q.read_ptr].skb[i] = NULL;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(iwl_hw_txq_free_tfd);
+
+
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
+ dma_addr_t addr, u16 len)
+{
+ int index, is_odd;
+ struct iwl_tfd_frame *tfd = ptr;
+ u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);
+
+ /* Each TFD can point to a maximum 20 Tx buffers */
+ if ((num_tbs >= MAX_NUM_OF_TBS) || (num_tbs < 0)) {
+ IWL_ERROR("Error can not send more than %d chunks\n",
+ MAX_NUM_OF_TBS);
+ return -EINVAL;
+ }
+
+ index = num_tbs / 2;
+ is_odd = num_tbs & 0x1;
+
+ if (!is_odd) {
+ tfd->pa[index].tb1_addr = cpu_to_le32(addr);
+ IWL_SET_BITS(tfd->pa[index], tb1_addr_hi,
+ iwl_get_dma_hi_address(addr));
+ IWL_SET_BITS(tfd->pa[index], tb1_len, len);
+ } else {
+ IWL_SET_BITS(tfd->pa[index], tb2_addr_lo16,
+ (u32) (addr & 0xffff));
+ IWL_SET_BITS(tfd->pa[index], tb2_addr_hi20, addr >> 16);
+ IWL_SET_BITS(tfd->pa[index], tb2_len, len);
+ }
+
+ IWL_SET_BITS(*tfd, num_tbs, num_tbs + 1);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_hw_txq_attach_buf_to_tfd);
+
+/**
+ * iwl_txq_update_write_ptr - Send new write index to hardware
+ */
+int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+ u32 reg = 0;
+ int ret = 0;
+ int txq_id = txq->q.id;
+
+ if (txq->need_update == 0)
+ return ret;
+
+ /* if we're trying to save power */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ /* wake up nic if it's powered down ...
+ * uCode will wake up, and interrupt us again, so next
+ * time we'll skip this part. */
+ reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+
+ if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
+ iwl_set_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ return ret;
+ }
+
+ /* restore this queue's parameters in nic hardware. */
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+ iwl_write_direct32(priv, HBUS_TARG_WRPTR,
+ txq->q.write_ptr | (txq_id << 8));
+ iwl_release_nic_access(priv);
+
+ /* else not in power-save mode, uCode will never sleep when we're
+ * trying to tx (during RFKILL, we're not trying to tx). */
+ } else
+ iwl_write32(priv, HBUS_TARG_WRPTR,
+ txq->q.write_ptr | (txq_id << 8));
+
+ txq->need_update = 0;
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_txq_update_write_ptr);
+
+
+/**
+ * iwl_tx_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+ struct iwl_queue *q = &txq->q;
+ struct pci_dev *dev = priv->pci_dev;
+ int len;
+
+ if (q->n_bd == 0)
+ return;
+
+ /* first, empty all BD's */
+ for (; q->write_ptr != q->read_ptr;
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
+ iwl_hw_txq_free_tfd(priv, txq);
+
+ len = sizeof(struct iwl_cmd) * q->n_window;
+ if (q->id == IWL_CMD_QUEUE_NUM)
+ len += IWL_MAX_SCAN_SIZE;
+
+ /* De-alloc array of command/tx buffers */
+ pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
+
+ /* De-alloc circular buffer of TFDs */
+ if (txq->q.n_bd)
+ pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) *
+ txq->q.n_bd, txq->bd, txq->q.dma_addr);
+
+ /* De-alloc array of per-TFD driver data */
+ kfree(txq->txb);
+ txq->txb = NULL;
+
+ /* 0-fill queue descriptor structure */
+ memset(txq, 0, sizeof(*txq));
+}
+
+/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
+ * DMA services
+ *
+ * Theory of operation
+ *
+ * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
+ * of buffer descriptors, each of which points to one or more data buffers for
+ * the device to read from or fill. Driver and device exchange status of each
+ * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
+ * entries in each circular buffer, to protect against confusing empty and full
+ * queue states.
+ *
+ * The device reads or writes the data in the queues via the device's several
+ * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
+ *
+ * For Tx queue, there are low mark and high mark limits. If, after queuing
+ * the packet for Tx, free space become < low mark, Tx queue stopped. When
+ * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
+ * Tx queue resumed.
+ *
+ * See more detailed info in iwl-4965-hw.h.
+ ***************************************************/
+
+int iwl_queue_space(const struct iwl_queue *q)
+{
+ int s = q->read_ptr - q->write_ptr;
+
+ if (q->read_ptr > q->write_ptr)
+ s -= q->n_bd;
+
+ if (s <= 0)
+ s += q->n_window;
+ /* keep some reserve to not confuse empty and full situations */
+ s -= 2;
+ if (s < 0)
+ s = 0;
+ return s;
+}
+EXPORT_SYMBOL(iwl_queue_space);
+
+
+/**
+ * iwl_queue_init - Initialize queue's high/low-water and read/write indexes
+ */
+static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
+ int count, int slots_num, u32 id)
+{
+ q->n_bd = count;
+ q->n_window = slots_num;
+ q->id = id;
+
+ /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
+ * and iwl_queue_dec_wrap are broken. */
+ BUG_ON(!is_power_of_2(count));
+
+ /* slots_num must be power-of-two size, otherwise
+ * get_cmd_index is broken. */
+ BUG_ON(!is_power_of_2(slots_num));
+
+ q->low_mark = q->n_window / 4;
+ if (q->low_mark < 4)
+ q->low_mark = 4;
+
+ q->high_mark = q->n_window / 8;
+ if (q->high_mark < 2)
+ q->high_mark = 2;
+
+ q->write_ptr = q->read_ptr = 0;
+
+ return 0;
+}
+
+/**
+ * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
+ */
+static int iwl_tx_queue_alloc(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq, u32 id)
+{
+ struct pci_dev *dev = priv->pci_dev;
+
+ /* Driver private data, only for Tx (not command) queues,
+ * not shared with device. */
+ if (id != IWL_CMD_QUEUE_NUM) {
+ txq->txb = kmalloc(sizeof(txq->txb[0]) *
+ TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
+ if (!txq->txb) {
+ IWL_ERROR("kmalloc for auxiliary BD "
+ "structures failed\n");
+ goto error;
+ }
+ } else
+ txq->txb = NULL;
+
+ /* Circular buffer of transmit frame descriptors (TFDs),
+ * shared with device */
+ txq->bd = pci_alloc_consistent(dev,
+ sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
+ &txq->q.dma_addr);
+
+ if (!txq->bd) {
+ IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
+ sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
+ goto error;
+ }
+ txq->q.id = id;
+
+ return 0;
+
+ error:
+ kfree(txq->txb);
+ txq->txb = NULL;
+
+ return -ENOMEM;
+}
+
+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
+{
+ int rc;
+ unsigned long flags;
+ int txq_id = txq->q.id;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ rc = iwl_grab_nic_access(priv);
+ if (rc) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return rc;
+ }
+
+ /* Circular buffer (TFD queue in DRAM) physical base address */
+ iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
+ txq->q.dma_addr >> 8);
+
+ /* Enable DMA channel, using same id as for TFD queue */
+ iwl_write_direct32(
+ priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
+ FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
+ FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL);
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+/**
+ * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
+ */
+static int iwl_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id)
+{
+ struct pci_dev *dev = priv->pci_dev;
+ int len;
+ int rc = 0;
+
+ /*
+ * Alloc buffer array for commands (Tx or other types of commands).
+ * For the command queue (#4), allocate command space + one big
+ * command for scan, since scan command is very huge; the system will
+ * not have two scans at the same time, so only one is needed.
+ * For normal Tx queues (all other queues), no super-size command
+ * space is needed.
+ */
+ len = sizeof(struct iwl_cmd) * slots_num;
+ if (txq_id == IWL_CMD_QUEUE_NUM)
+ len += IWL_MAX_SCAN_SIZE;
+ txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
+ if (!txq->cmd)
+ return -ENOMEM;
+
+ /* Alloc driver data array and TFD circular buffer */
+ rc = iwl_tx_queue_alloc(priv, txq, txq_id);
+ if (rc) {
+ pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
+
+ return -ENOMEM;
+ }
+ txq->need_update = 0;
+
+ /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
+ * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
+ BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
+
+ /* Initialize queue's high/low-water marks, and head/tail indexes */
+ iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+ /* Tell device where to find queue */
+ iwl_hw_tx_queue_init(priv, txq);
+
+ return 0;
+}
+/**
+ * iwl_hw_txq_ctx_free - Free TXQ Context
+ *
+ * Destroy all TX DMA queues and structures
+ */
+void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
+{
+ int txq_id;
+
+ /* Tx queues */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+ iwl_tx_queue_free(priv, &priv->txq[txq_id]);
+
+ /* Keep-warm buffer */
+ iwl_kw_free(priv);
+}
+EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
+
+
+/**
+ * iwl_txq_ctx_reset - Reset TX queue context
+ * Destroys all DMA structures and initialise them again
+ *
+ * @param priv
+ * @return error code
+ */
+int iwl_txq_ctx_reset(struct iwl_priv *priv)
+{
+ int ret = 0;
+ int txq_id, slots_num;
+ unsigned long flags;
+
+ iwl_kw_free(priv);
+
+ /* Free all tx/cmd queues and keep-warm buffer */
+ iwl_hw_txq_ctx_free(priv);
+
+ /* Alloc keep-warm buffer */
+ ret = iwl_kw_alloc(priv);
+ if (ret) {
+ IWL_ERROR("Keep Warm allocation failed");
+ goto error_kw;
+ }
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (unlikely(ret)) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ goto error_reset;
+ }
+
+ /* Turn off all Tx DMA fifos */
+ priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+
+ /* Tell nic where to find the keep-warm buffer */
+ ret = iwl_kw_init(priv);
+ if (ret) {
+ IWL_ERROR("kw_init failed\n");
+ goto error_reset;
+ }
+
+ /* Alloc and init all Tx queues, including the command queue (#4) */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
+ slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
+ TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+ ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+ txq_id);
+ if (ret) {
+ IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ goto error;
+ }
+ }
+
+ return ret;
+
+ error:
+ iwl_hw_txq_ctx_free(priv);
+ error_reset:
+ iwl_kw_free(priv);
+ error_kw:
+ return ret;
+}
+/**
+ * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ */
+void iwl_txq_ctx_stop(struct iwl_priv *priv)
+{
+
+ int txq_id;
+ unsigned long flags;
+
+
+ /* Turn off all Tx DMA fifos */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (iwl_grab_nic_access(priv)) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return;
+ }
+
+ priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+ /* Stop each Tx DMA channel, and wait for it to be idle */
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
+ iwl_write_direct32(priv,
+ FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0);
+ iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG,
+ FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE
+ (txq_id), 200);
+ }
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Deallocate memory for all Tx queues */
+ iwl_hw_txq_ctx_free(priv);
+}
+EXPORT_SYMBOL(iwl_txq_ctx_stop);
+
+/*
+ * handle build REPLY_TX command notification.
+ */
+static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
+ struct iwl_tx_cmd *tx_cmd,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_hdr *hdr,
+ int is_unicast, u8 std_id)
+{
+ __le16 fc = hdr->frame_control;
+ __le32 tx_flags = tx_cmd->tx_flags;
+
+ tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ tx_flags |= TX_CMD_FLG_ACK_MSK;
+ if (ieee80211_is_mgmt(fc))
+ tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+ if (ieee80211_is_probe_resp(fc) &&
+ !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
+ tx_flags |= TX_CMD_FLG_TSF_MSK;
+ } else {
+ tx_flags &= (~TX_CMD_FLG_ACK_MSK);
+ tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+ }
+
+ if (ieee80211_is_back_req(fc))
+ tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
+
+
+ tx_cmd->sta_id = std_id;
+ if (ieee80211_has_morefrags(fc))
+ tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
+
+ if (ieee80211_is_data_qos(fc)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ tx_cmd->tid_tspec = qc[0] & 0xf;
+ tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
+ } else {
+ tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+ }
+
+ priv->cfg->ops->utils->rts_tx_cmd_flag(info, &tx_flags);
+
+ if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
+ tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
+
+ tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
+ if (ieee80211_is_mgmt(fc)) {
+ if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
+ tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
+ else
+ tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
+ } else {
+ tx_cmd->timeout.pm_frame_timeout = 0;
+ }
+
+ tx_cmd->driver_txop = 0;
+ tx_cmd->tx_flags = tx_flags;
+ tx_cmd->next_frame_len = 0;
+}
+
+#define RTS_HCCA_RETRY_LIMIT 3
+#define RTS_DFAULT_RETRY_LIMIT 60
+
+static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
+ struct iwl_tx_cmd *tx_cmd,
+ struct ieee80211_tx_info *info,
+ __le16 fc, int sta_id,
+ int is_hcca)
+{
+ u8 rts_retry_limit = 0;
+ u8 data_retry_limit = 0;
+ u8 rate_plcp;
+ u16 rate_flags = 0;
+ int rate_idx;
+
+ rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff,
+ IWL_RATE_COUNT - 1);
+
+ rate_plcp = iwl_rates[rate_idx].plcp;
+
+ rts_retry_limit = (is_hcca) ?
+ RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;
+
+ if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
+ rate_flags |= RATE_MCS_CCK_MSK;
+
+
+ if (ieee80211_is_probe_resp(fc)) {
+ data_retry_limit = 3;
+ if (data_retry_limit < rts_retry_limit)
+ rts_retry_limit = data_retry_limit;
+ } else
+ data_retry_limit = IWL_DEFAULT_TX_RETRY;
+
+ if (priv->data_retry_limit != -1)
+ data_retry_limit = priv->data_retry_limit;
+
+
+ if (ieee80211_is_data(fc)) {
+ tx_cmd->initial_rate_index = 0;
+ tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
+ } else {
+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+ case cpu_to_le16(IEEE80211_STYPE_AUTH):
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+ if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
+ tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+ tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Alternate between antenna A and B for successive frames */
+ if (priv->use_ant_b_for_management_frame) {
+ priv->use_ant_b_for_management_frame = 0;
+ rate_flags |= RATE_MCS_ANT_B_MSK;
+ } else {
+ priv->use_ant_b_for_management_frame = 1;
+ rate_flags |= RATE_MCS_ANT_A_MSK;
+ }
+ }
+
+ tx_cmd->rts_retry_limit = rts_retry_limit;
+ tx_cmd->data_retry_limit = data_retry_limit;
+ tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
+}
+
+static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
+ struct ieee80211_tx_info *info,
+ struct iwl_tx_cmd *tx_cmd,
+ struct sk_buff *skb_frag,
+ int sta_id)
+{
+ struct ieee80211_key_conf *keyconf = info->control.hw_key;
+
+ switch (keyconf->alg) {
+ case ALG_CCMP:
+ tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
+ memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
+ IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
+ break;
+
+ case ALG_TKIP:
+ tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
+ ieee80211_get_tkip_key(keyconf, skb_frag,
+ IEEE80211_TKIP_P2_KEY, tx_cmd->key);
+ IWL_DEBUG_TX("tx_cmd with tkip hwcrypto\n");
+ break;
+
+ case ALG_WEP:
+ tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
+ (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
+
+ if (keyconf->keylen == WEP_KEY_LEN_128)
+ tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
+
+ memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
+
+ IWL_DEBUG_TX("Configuring packet for WEP encryption "
+ "with key %d\n", keyconf->keyidx);
+ break;
+
+ default:
+ printk(KERN_ERR "Unknown encode alg %d\n", keyconf->alg);
+ break;
+ }
+}
+
+static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len)
+{
+ /* 0 - mgmt, 1 - cnt, 2 - data */
+ int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
+ priv->tx_stats[idx].cnt++;
+ priv->tx_stats[idx].bytes += len;
+}
+
+/*
+ * start REPLY_TX command process
+ */
+int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct iwl_tfd_frame *tfd;
+ u32 *control_flags;
+ int txq_id = skb_get_queue_mapping(skb);
+ struct iwl_tx_queue *txq = NULL;
+ struct iwl_queue *q = NULL;
+ dma_addr_t phys_addr;
+ dma_addr_t txcmd_phys;
+ dma_addr_t scratch_phys;
+ struct iwl_cmd *out_cmd = NULL;
+ struct iwl_tx_cmd *tx_cmd;
+ u16 len, idx, len_org;
+ u16 seq_number = 0;
+ u8 id, hdr_len, unicast;
+ u8 sta_id;
+ __le16 fc;
+ u8 wait_write_ptr = 0;
+ u8 tid = 0;
+ u8 *qc = NULL;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_DROP("Dropping - RF KILL\n");
+ goto drop_unlock;
+ }
+
+ if (!priv->vif) {
+ IWL_DEBUG_DROP("Dropping - !priv->vif\n");
+ goto drop_unlock;
+ }
+
+ if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
+ IWL_INVALID_RATE) {
+ IWL_ERROR("ERROR: No TX rate available.\n");
+ goto drop_unlock;
+ }
+
+ unicast = !is_multicast_ether_addr(hdr->addr1);
+ id = 0;
+
+ fc = hdr->frame_control;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (ieee80211_is_auth(fc))
+ IWL_DEBUG_TX("Sending AUTH frame\n");
+ else if (ieee80211_is_assoc_req(fc))
+ IWL_DEBUG_TX("Sending ASSOC frame\n");
+ else if (ieee80211_is_reassoc_req(fc))
+ IWL_DEBUG_TX("Sending REASSOC frame\n");
+#endif
+
+ /* drop all data frame if we are not associated */
+ if (ieee80211_is_data(fc) &&
+ (!iwl_is_associated(priv) ||
+ ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
+ !priv->assoc_station_added)) {
+ IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
+ goto drop_unlock;
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
+
+ /* Find (or create) index into station table for destination station */
+ sta_id = iwl_get_sta_id(priv, hdr);
+ if (sta_id == IWL_INVALID_STATION) {
+ DECLARE_MAC_BUF(mac);
+
+ IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n",
+ print_mac(mac, hdr->addr1));
+ goto drop;
+ }
+
+ IWL_DEBUG_TX("station Id %d\n", sta_id);
+
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ seq_number = priv->stations[sta_id].tid[tid].seq_number &
+ IEEE80211_SCTL_SEQ;
+ hdr->seq_ctrl = cpu_to_le16(seq_number) |
+ (hdr->seq_ctrl &
+ __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
+ seq_number += 0x10;
+ /* aggregation is on for this <sta,tid> */
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
+ priv->stations[sta_id].tid[tid].tfds_in_queue++;
+ }
+
+ /* Descriptor for chosen Tx queue */
+ txq = &priv->txq[txq_id];
+ q = &txq->q;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Set up first empty TFD within this queue's circular TFD buffer */
+ tfd = &txq->bd[q->write_ptr];
+ memset(tfd, 0, sizeof(*tfd));
+ control_flags = (u32 *) tfd;
+ idx = get_cmd_index(q, q->write_ptr, 0);
+
+ /* Set up driver data for this TFD */
+ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
+ txq->txb[q->write_ptr].skb[0] = skb;
+
+ /* Set up first empty entry in queue's array of Tx/cmd buffers */
+ out_cmd = &txq->cmd[idx];
+ tx_cmd = &out_cmd->cmd.tx;
+ memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
+ memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
+
+ /*
+ * Set up the Tx-command (not MAC!) header.
+ * Store the chosen Tx queue and TFD index within the sequence field;
+ * after Tx, uCode's Tx response will return this value so driver can
+ * locate the frame within the tx queue and do post-tx processing.
+ */
+ out_cmd->hdr.cmd = REPLY_TX;
+ out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
+ INDEX_TO_SEQ(q->write_ptr)));
+
+ /* Copy MAC header from skb into command buffer */
+ memcpy(tx_cmd->hdr, hdr, hdr_len);
+
+ /*
+ * Use the first empty entry in this queue's command buffer array
+ * to contain the Tx command and MAC header concatenated together
+ * (payload data will be in another buffer).
+ * Size of this varies, due to varying MAC header length.
+ * If end is not dword aligned, we'll have 2 extra bytes at the end
+ * of the MAC header (device reads on dword boundaries).
+ * We'll tell device about this padding later.
+ */
+ len = sizeof(struct iwl_tx_cmd) +
+ sizeof(struct iwl_cmd_header) + hdr_len;
+
+ len_org = len;
+ len = (len + 3) & ~3;
+
+ if (len_org != len)
+ len_org = 1;
+ else
+ len_org = 0;
+
+ /* Physical address of this Tx command's header (not MAC header!),
+ * within command buffer array. */
+ txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
+ offsetof(struct iwl_cmd, hdr);
+
+ /* Add buffer containing Tx command and MAC(!) header to TFD's
+ * first entry */
+ iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+
+ if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
+ iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
+
+ /* Set up TFD's 2nd entry to point directly to remainder of skb,
+ * if any (802.11 null frames have no payload). */
+ len = skb->len - hdr_len;
+ if (len) {
+ phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
+ len, PCI_DMA_TODEVICE);
+ iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ }
+
+ /* Tell NIC about any 2-byte padding after MAC header */
+ if (len_org)
+ tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
+
+ /* Total # bytes to be transmitted */
+ len = (u16)skb->len;
+ tx_cmd->len = cpu_to_le16(len);
+ /* TODO need this for burst mode later on */
+ iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, unicast, sta_id);
+
+ /* set is_hcca to 0; it probably will never be implemented */
+ iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
+
+ iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
+
+ scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
+ offsetof(struct iwl_tx_cmd, scratch);
+ tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
+ tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);
+
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
+ txq->need_update = 1;
+ if (qc)
+ priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
+ }
+
+ iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
+
+ iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
+
+ /* Set up entry for this TFD in Tx byte-count array */
+ priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len);
+
+ /* Tell device the write index *just past* this latest filled TFD */
+ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
+ ret = iwl_txq_update_write_ptr(priv, txq);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (ret)
+ return ret;
+
+ if ((iwl_queue_space(q) < q->high_mark)
+ && priv->mac80211_registered) {
+ if (wait_write_ptr) {
+ spin_lock_irqsave(&priv->lock, flags);
+ txq->need_update = 1;
+ iwl_txq_update_write_ptr(priv, txq);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
+ }
+
+ return 0;
+
+drop_unlock:
+ spin_unlock_irqrestore(&priv->lock, flags);
+drop:
+ return -1;
+}
+EXPORT_SYMBOL(iwl_tx_skb);
+
+/*************** HOST COMMAND QUEUE FUNCTIONS *****/
+
+/**
+ * iwl_enqueue_hcmd - enqueue a uCode command
+ * @priv: device private data point
+ * @cmd: a point to the ucode command structure
+ *
+ * The function returns < 0 values to indicate the operation is
+ * failed. On success, it turns the index (> 0) of command in the
+ * command queue.
+ */
+int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+{
+ struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+ struct iwl_queue *q = &txq->q;
+ struct iwl_tfd_frame *tfd;
+ u32 *control_flags;
+ struct iwl_cmd *out_cmd;
+ u32 idx;
+ u16 fix_size;
+ dma_addr_t phys_addr;
+ int ret;
+ unsigned long flags;
+
+ cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
+ fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
+
+ /* If any of the command structures end up being larger than
+ * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
+ * we will need to increase the size of the TFD entries */
+ BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
+ !(cmd->meta.flags & CMD_SIZE_HUGE));
+
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_INFO("Not sending command - RF KILL");
+ return -EIO;
+ }
+
+ if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
+ IWL_ERROR("No space for Tx\n");
+ return -ENOSPC;
+ }
+
+ spin_lock_irqsave(&priv->hcmd_lock, flags);
+
+ tfd = &txq->bd[q->write_ptr];
+ memset(tfd, 0, sizeof(*tfd));
+
+ control_flags = (u32 *) tfd;
+
+ idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
+ out_cmd = &txq->cmd[idx];
+
+ out_cmd->hdr.cmd = cmd->id;
+ memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
+ memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
+
+ /* At this point, the out_cmd now has all of the incoming cmd
+ * information */
+
+ out_cmd->hdr.flags = 0;
+ out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
+ INDEX_TO_SEQ(q->write_ptr));
+ if (out_cmd->meta.flags & CMD_SIZE_HUGE)
+ out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
+
+ phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
+ offsetof(struct iwl_cmd, hdr);
+ iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
+
+ IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
+ "%d bytes at %d[%d]:%d\n",
+ get_cmd_string(out_cmd->hdr.cmd),
+ out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
+ fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
+
+ txq->need_update = 1;
+
+ /* Set up entry in queue's byte count circular buffer */
+ priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+
+ /* Increment and update queue's write index */
+ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
+ ret = iwl_txq_update_write_ptr(priv, txq);
+
+ spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+ return ret ? ret : idx;
+}
+
+int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
+{
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+ struct iwl_tx_info *tx_info;
+ int nfreed = 0;
+
+ if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
+ IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ "is out of range [0-%d] %d %d.\n", txq_id,
+ index, q->n_bd, q->write_ptr, q->read_ptr);
+ return 0;
+ }
+
+ for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+
+ tx_info = &txq->txb[txq->q.read_ptr];
+ ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
+ tx_info->skb[0] = NULL;
+
+ if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
+ priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
+
+ iwl_hw_txq_free_tfd(priv, txq);
+ nfreed++;
+ }
+ return nfreed;
+}
+EXPORT_SYMBOL(iwl_tx_queue_reclaim);
+
+
+/**
+ * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd
+ *
+ * When FW advances 'R' index, all entries between old and new 'R' index
+ * need to be reclaimed. As result, some free space forms. If there is
+ * enough free space (> low mark), wake the stack that feeds us.
+ */
+static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
+{
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+ int nfreed = 0;
+
+ if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
+ IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ "is out of range [0-%d] %d %d.\n", txq_id,
+ index, q->n_bd, q->write_ptr, q->read_ptr);
+ return;
+ }
+
+ for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+
+ if (nfreed > 1) {
+ IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
+ q->write_ptr, q->read_ptr);
+ queue_work(priv->workqueue, &priv->restart);
+ }
+ nfreed++;
+ }
+}
+
+/**
+ * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
+ * @rxb: Rx buffer to reclaim
+ *
+ * If an Rx buffer has an async callback associated with it the callback
+ * will be executed. The attached skb (if present) will only be freed
+ * if the callback returns 1
+ */
+void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ u16 sequence = le16_to_cpu(pkt->hdr.sequence);
+ int txq_id = SEQ_TO_QUEUE(sequence);
+ int index = SEQ_TO_INDEX(sequence);
+ int huge = sequence & SEQ_HUGE_FRAME;
+ int cmd_index;
+ struct iwl_cmd *cmd;
+
+ /* If a Tx command is being handled and it isn't in the actual
+ * command queue then there a command routing bug has been introduced
+ * in the queue management code. */
+ if (txq_id != IWL_CMD_QUEUE_NUM)
+ IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
+ txq_id, pkt->hdr.cmd);
+ BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
+
+ cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
+ cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
+
+ /* Input error checking is done when commands are added to queue. */
+ if (cmd->meta.flags & CMD_WANT_SKB) {
+ cmd->meta.source->u.skb = rxb->skb;
+ rxb->skb = NULL;
+ } else if (cmd->meta.u.callback &&
+ !cmd->meta.u.callback(priv, cmd, rxb->skb))
+ rxb->skb = NULL;
+
+ iwl_hcmd_queue_reclaim(priv, txq_id, index);
+
+ if (!(cmd->meta.flags & CMD_ASYNC)) {
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ wake_up_interruptible(&priv->wait_command_queue);
+ }
+}
+EXPORT_SYMBOL(iwl_tx_cmd_complete);
+
+/*
+ * Find first available (lowest unused) Tx Queue, mark it "active".
+ * Called only when finding queue for aggregation.
+ * Should never return anything < 7, because they should already
+ * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6).
+ */
+static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
+{
+ int txq_id;
+
+ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
+ if (!test_and_set_bit(txq_id, &priv->txq_ctx_active_msk))
+ return txq_id;
+ return -1;
+}
+
+int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
+{
+ int sta_id;
+ int tx_fifo;
+ int txq_id;
+ int ret;
+ unsigned long flags;
+ struct iwl_tid_data *tid_data;
+ DECLARE_MAC_BUF(mac);
+
+ if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
+ tx_fifo = default_tid_to_tx_fifo[tid];
+ else
+ return -EINVAL;
+
+ IWL_WARNING("%s on ra = %s tid = %d\n",
+ __func__, print_mac(mac, ra), tid);
+
+ sta_id = iwl_find_station(priv, ra);
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;
+
+ if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
+ IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n");
+ return -ENXIO;
+ }
+
+ txq_id = iwl_txq_ctx_activate_free(priv);
+ if (txq_id == -1)
+ return -ENXIO;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ tid_data = &priv->stations[sta_id].tid[tid];
+ *ssn = SEQ_TO_SN(tid_data->seq_number);
+ tid_data->agg.txq_id = txq_id;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
+ sta_id, tid, *ssn);
+ if (ret)
+ return ret;
+
+ if (tid_data->tfds_in_queue == 0) {
+ printk(KERN_ERR "HW queue is empty\n");
+ tid_data->agg.state = IWL_AGG_ON;
+ ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+ } else {
+ IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n",
+ tid_data->tfds_in_queue);
+ tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(iwl_tx_agg_start);
+
+int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
+{
+ int tx_fifo_id, txq_id, sta_id, ssn = -1;
+ struct iwl_tid_data *tid_data;
+ int ret, write_ptr, read_ptr;
+ unsigned long flags;
+ DECLARE_MAC_BUF(mac);
+
+ if (!ra) {
+ IWL_ERROR("ra = NULL\n");
+ return -EINVAL;
+ }
+
+ if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
+ tx_fifo_id = default_tid_to_tx_fifo[tid];
+ else
+ return -EINVAL;
+
+ sta_id = iwl_find_station(priv, ra);
+
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;
+
+ if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
+ IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n");
+
+ tid_data = &priv->stations[sta_id].tid[tid];
+ ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
+ txq_id = tid_data->agg.txq_id;
+ write_ptr = priv->txq[txq_id].q.write_ptr;
+ read_ptr = priv->txq[txq_id].q.read_ptr;
+
+ /* The queue is not empty */
+ if (write_ptr != read_ptr) {
+ IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n");
+ priv->stations[sta_id].tid[tid].agg.state =
+ IWL_EMPTYING_HW_QUEUE_DELBA;
+ return 0;
+ }
+
+ IWL_DEBUG_HT("HW queue is empty\n");
+ priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,
+ tx_fifo_id);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (ret)
+ return ret;
+
+ ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_tx_agg_stop);
+
+int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
+{
+ struct iwl_queue *q = &priv->txq[txq_id].q;
+ u8 *addr = priv->stations[sta_id].sta.sta.addr;
+ struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
+
+ switch (priv->stations[sta_id].tid[tid].agg.state) {
+ case IWL_EMPTYING_HW_QUEUE_DELBA:
+ /* We are reclaiming the last packet of the */
+ /* aggregated HW queue */
+ if (txq_id == tid_data->agg.txq_id &&
+ q->read_ptr == q->write_ptr) {
+ u16 ssn = SEQ_TO_SN(tid_data->seq_number);
+ int tx_fifo = default_tid_to_tx_fifo[tid];
+ IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
+ priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
+ ssn, tx_fifo);
+ tid_data->agg.state = IWL_AGG_OFF;
+ ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid);
+ }
+ break;
+ case IWL_EMPTYING_HW_QUEUE_ADDBA:
+ /* We are reclaiming the last packet of the queue */
+ if (tid_data->tfds_in_queue == 0) {
+ IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n");
+ tid_data->agg.state = IWL_AGG_ON;
+ ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid);
+ }
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(iwl_txq_check_empty);
+
+/**
+ * iwl_tx_status_reply_compressed_ba - Update tx status from block-ack
+ *
+ * Go through block-ack's bitmap of ACK'd frames, update driver's record of
+ * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
+ */
+static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
+ struct iwl_ht_agg *agg,
+ struct iwl_compressed_ba_resp *ba_resp)
+
+{
+ int i, sh, ack;
+ u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
+ u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
+ u64 bitmap;
+ int successes = 0;
+ struct ieee80211_tx_info *info;
+
+ if (unlikely(!agg->wait_for_ba)) {
+ IWL_ERROR("Received BA when not expected\n");
+ return -EINVAL;
+ }
+
+ /* Mark that the expected block-ack response arrived */
+ agg->wait_for_ba = 0;
+ IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
+
+ /* Calculate shift to align block-ack bits with our Tx window bits */
+ sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4);
+ if (sh < 0) /* tbw something is wrong with indices */
+ sh += 0x100;
+
+ /* don't use 64-bit values for now */
+ bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
+
+ if (agg->frame_count > (64 - sh)) {
+ IWL_DEBUG_TX_REPLY("more frames than bitmap size");
+ return -1;
+ }
+
+ /* check for success or failure according to the
+ * transmitted bitmap and block-ack bitmap */
+ bitmap &= agg->bitmap;
+
+ /* For each frame attempted in aggregation,
+ * update driver's record of tx frame's status. */
+ for (i = 0; i < agg->frame_count ; i++) {
+ ack = bitmap & (1 << i);
+ successes += !!ack;
+ IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
+ ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,
+ agg->start_idx + i);
+ }
+
+ info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb[0]);
+ memset(&info->status, 0, sizeof(info->status));
+ info->flags = IEEE80211_TX_STAT_ACK;
+ info->flags |= IEEE80211_TX_STAT_AMPDU;
+ info->status.ampdu_ack_map = successes;
+ info->status.ampdu_ack_len = agg->frame_count;
+ iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
+
+ IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
+
+ return 0;
+}
+
+/**
+ * iwl_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
+ *
+ * Handles block-acknowledge notification from device, which reports success
+ * of frames sent via aggregation.
+ */
+void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
+ int index;
+ struct iwl_tx_queue *txq = NULL;
+ struct iwl_ht_agg *agg;
+ DECLARE_MAC_BUF(mac);
+
+ /* "flow" corresponds to Tx queue */
+ u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
+
+ /* "ssn" is start of block-ack Tx window, corresponds to index
+ * (in Tx queue's circular buffer) of first TFD/frame in window */
+ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
+
+ if (scd_flow >= priv->hw_params.max_txq_num) {
+ IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
+ return;
+ }
+
+ txq = &priv->txq[scd_flow];
+ agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg;
+
+ /* Find index just before block-ack window */
+ index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
+
+ /* TODO: Need to get this copy more safely - now good for debug */
+
+ IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, "
+ "sta_id = %d\n",
+ agg->wait_for_ba,
+ print_mac(mac, (u8 *) &ba_resp->sta_addr_lo32),
+ ba_resp->sta_id);
+ IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
+ "%d, scd_ssn = %d\n",
+ ba_resp->tid,
+ ba_resp->seq_ctl,
+ (unsigned long long)le64_to_cpu(ba_resp->bitmap),
+ ba_resp->scd_flow,
+ ba_resp->scd_ssn);
+ IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
+ agg->start_idx,
+ (unsigned long long)agg->bitmap);
+
+ /* Update driver's record of ACK vs. not for each frame in window */
+ iwl_tx_status_reply_compressed_ba(priv, agg, ba_resp);
+
+ /* Release all TFDs before the SSN, i.e. all TFDs in front of
+ * block-ack window (we assume that they've been successfully
+ * transmitted ... if not, it's too late anyway). */
+ if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
+ /* calculate mac80211 ampdu sw queue to wake */
+ int ampdu_q =
+ scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
+ int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
+ priv->stations[ba_resp->sta_id].
+ tid[ba_resp->tid].tfds_in_queue -= freed;
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ priv->mac80211_registered &&
+ agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
+ ieee80211_wake_queue(priv->hw, ampdu_q);
+
+ iwl_txq_check_empty(priv, ba_resp->sta_id,
+ ba_resp->tid, scd_flow);
+ }
+}
+EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
+
+const char *iwl_get_tx_fail_reason(u32 status)
+{
+ switch (status & TX_STATUS_MSK) {
+ case TX_STATUS_SUCCESS:
+ return "SUCCESS";
+ TX_STATUS_ENTRY(SHORT_LIMIT);
+ TX_STATUS_ENTRY(LONG_LIMIT);
+ TX_STATUS_ENTRY(FIFO_UNDERRUN);
+ TX_STATUS_ENTRY(MGMNT_ABORT);
+ TX_STATUS_ENTRY(NEXT_FRAG);
+ TX_STATUS_ENTRY(LIFE_EXPIRE);
+ TX_STATUS_ENTRY(DEST_PS);
+ TX_STATUS_ENTRY(ABORTED);
+ TX_STATUS_ENTRY(BT_RETRY);
+ TX_STATUS_ENTRY(STA_INVALID);
+ TX_STATUS_ENTRY(FRAG_DROPPED);
+ TX_STATUS_ENTRY(TID_DISABLE);
+ TX_STATUS_ENTRY(FRAME_FLUSHED);
+ TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
+ TX_STATUS_ENTRY(TX_LOCKED);
+ TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
+ }
+
+ return "UNKNOWN";
+}
+EXPORT_SYMBOL(iwl_get_tx_fail_reason);
+#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6027e1119c3..4a22d3fba75 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -102,16 +102,6 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
-static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
-{
- u16 fc = le16_to_cpu(hdr->frame_control);
- int hdr_len = ieee80211_get_hdrlen(fc);
-
- if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
- return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
- return NULL;
-}
-
static const struct ieee80211_supported_band *iwl3945_get_band(
struct iwl3945_priv *priv, enum ieee80211_band band)
{
@@ -547,10 +537,20 @@ static inline int iwl3945_is_init(struct iwl3945_priv *priv)
return test_bit(STATUS_INIT, &priv->status);
}
+static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
+{
+ return test_bit(STATUS_RF_KILL_SW, &priv->status);
+}
+
+static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
+{
+ return test_bit(STATUS_RF_KILL_HW, &priv->status);
+}
+
static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
{
- return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status);
+ return iwl3945_is_rfkill_hw(priv) ||
+ iwl3945_is_rfkill_sw(priv);
}
static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
@@ -980,7 +980,7 @@ static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
{
/* These items are only settable from the full RXON command */
- if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ||
+ if (!(iwl3945_is_associated(priv)) ||
compare_ether_addr(priv->staging_rxon.bssid_addr,
priv->active_rxon.bssid_addr) ||
compare_ether_addr(priv->staging_rxon.node_addr,
@@ -2035,36 +2035,6 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
return rc;
}
-int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
-{
- /* Filter incoming packets to determine if they are targeted toward
- * this network, discarding packets coming from ourselves */
- switch (priv->iw_mode) {
- case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
- /* packets from our adapter are dropped (echo) */
- if (!compare_ether_addr(header->addr2, priv->mac_addr))
- return 0;
- /* {broad,multi}cast packets to our IBSS go through */
- if (is_multicast_ether_addr(header->addr1))
- return !compare_ether_addr(header->addr3, priv->bssid);
- /* packets to our adapter go through */
- return !compare_ether_addr(header->addr1, priv->mac_addr);
- case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
- /* packets from our adapter are dropped (echo) */
- if (!compare_ether_addr(header->addr3, priv->mac_addr))
- return 0;
- /* {broad,multi}cast packets to our BSS go through */
- if (is_multicast_ether_addr(header->addr1))
- return !compare_ether_addr(header->addr2, priv->bssid);
- /* packets to our adapter go through */
- return !compare_ether_addr(header->addr1, priv->mac_addr);
- default:
- return 1;
- }
-
- return 1;
-}
-
/**
* iwl3945_scan_cancel - Cancel any currently executing HW scan
*
@@ -2117,20 +2087,6 @@ static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long
return ret;
}
-static void iwl3945_sequence_reset(struct iwl3945_priv *priv)
-{
- /* Reset ieee stats */
-
- /* We don't reset the net_device_stats (ieee->stats) on
- * re-association */
-
- priv->last_seq_num = -1;
- priv->last_frag_num = -1;
- priv->last_packet_time = 0;
-
- iwl3945_scan_cancel(priv);
-}
-
#define MAX_UCODE_BEACON_INTERVAL 1024
#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
@@ -2322,7 +2278,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
#endif
ch_info = iwl3945_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
+ le16_to_cpu(priv->active_rxon.channel));
if (!ch_info)
ch_info = &priv->channel_info[0];
@@ -2389,12 +2345,13 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
}
static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
- struct ieee80211_tx_control *ctl,
+ struct ieee80211_tx_info *info,
struct iwl3945_cmd *cmd,
struct sk_buff *skb_frag,
int last_frag)
{
- struct iwl3945_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo;
+ struct iwl3945_hw_key *keyinfo =
+ &priv->stations[info->control.hw_key->hw_key_idx].keyinfo;
switch (keyinfo->alg) {
case ALG_CCMP:
@@ -2417,7 +2374,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
case ALG_WEP:
cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
- (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
+ (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
if (keyinfo->keylen == 13)
cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
@@ -2425,7 +2382,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
IWL_DEBUG_TX("Configuring packet for WEP encryption "
- "with key %d\n", ctl->key_idx);
+ "with key %d\n", info->control.hw_key->hw_key_idx);
break;
default:
@@ -2439,20 +2396,19 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
*/
static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
struct iwl3945_cmd *cmd,
- struct ieee80211_tx_control *ctrl,
+ struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int is_unicast, u8 std_id)
{
- __le16 *qc;
- u16 fc = le16_to_cpu(hdr->frame_control);
+ __le16 fc = hdr->frame_control;
__le32 tx_flags = cmd->cmd.tx.tx_flags;
cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
- if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) {
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
tx_flags |= TX_CMD_FLG_ACK_MSK;
- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
+ if (ieee80211_is_mgmt(fc))
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
- if (ieee80211_is_probe_response(fc) &&
+ if (ieee80211_is_probe_resp(fc) &&
!(le16_to_cpu(hdr->seq_ctrl) & 0xf))
tx_flags |= TX_CMD_FLG_TSF_MSK;
} else {
@@ -2461,20 +2417,21 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
}
cmd->cmd.tx.sta_id = std_id;
- if (ieee80211_get_morefrag(hdr))
+ if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
- qc = ieee80211_get_qos_ctrl(hdr);
- if (qc) {
- cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf);
+ if (ieee80211_is_data_qos(fc)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
- } else
+ } else {
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+ }
- if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
tx_flags |= TX_CMD_FLG_RTS_MSK;
tx_flags &= ~TX_CMD_FLG_CTS_MSK;
- } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
+ } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
tx_flags &= ~TX_CMD_FLG_RTS_MSK;
tx_flags |= TX_CMD_FLG_CTS_MSK;
}
@@ -2483,9 +2440,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
- if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
- (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
+ if (ieee80211_is_mgmt(fc)) {
+ if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
else
cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
@@ -2549,6 +2505,11 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
return priv->hw_setting.bcast_sta_id;
}
+ /* If we are in monitor mode, use BCAST. This is required for
+ * packet injection. */
+ case IEEE80211_IF_TYPE_MNTR:
+ return priv->hw_setting.bcast_sta_id;
+
default:
IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
return priv->hw_setting.bcast_sta_id;
@@ -2558,25 +2519,27 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
/*
* start REPLY_TX command process
*/
-static int iwl3945_tx_skb(struct iwl3945_priv *priv,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl3945_tfd_frame *tfd;
u32 *control_flags;
- int txq_id = ctl->queue;
+ int txq_id = skb_get_queue_mapping(skb);
struct iwl3945_tx_queue *txq = NULL;
struct iwl3945_queue *q = NULL;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
struct iwl3945_cmd *out_cmd = NULL;
- u16 len, idx, len_org;
- u8 id, hdr_len, unicast;
+ u16 len, idx, len_org, hdr_len;
+ u8 id;
+ u8 unicast;
u8 sta_id;
+ u8 tid = 0;
u16 seq_number = 0;
- u16 fc;
- __le16 *qc;
+ __le16 fc;
u8 wait_write_ptr = 0;
+ u8 *qc = NULL;
unsigned long flags;
int rc;
@@ -2586,12 +2549,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
goto drop_unlock;
}
- if (!priv->vif) {
- IWL_DEBUG_DROP("Dropping - !priv->vif\n");
- goto drop_unlock;
- }
-
- if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) {
+ if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
IWL_ERROR("ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -2599,28 +2557,29 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
unicast = !is_multicast_ether_addr(hdr->addr1);
id = 0;
- fc = le16_to_cpu(hdr->frame_control);
+ fc = hdr->frame_control;
#ifdef CONFIG_IWL3945_DEBUG
if (ieee80211_is_auth(fc))
IWL_DEBUG_TX("Sending AUTH frame\n");
- else if (ieee80211_is_assoc_request(fc))
+ else if (ieee80211_is_assoc_req(fc))
IWL_DEBUG_TX("Sending ASSOC frame\n");
- else if (ieee80211_is_reassoc_request(fc))
+ else if (ieee80211_is_reassoc_req(fc))
IWL_DEBUG_TX("Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
- if ((!iwl3945_is_associated(priv) ||
- ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
- ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+ if (ieee80211_is_data(fc) &&
+ (priv->iw_mode != IEEE80211_IF_TYPE_MNTR) && /* packet injection */
+ (!iwl3945_is_associated(priv) ||
+ ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id))) {
IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
goto drop_unlock;
}
spin_unlock_irqrestore(&priv->lock, flags);
- hdr_len = ieee80211_get_hdrlen(fc);
+ hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
/* Find (or create) index into station table for destination station */
sta_id = iwl3945_get_sta_id(priv, hdr);
@@ -2634,9 +2593,9 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
IWL_DEBUG_RATE("station Id %d\n", sta_id);
- qc = ieee80211_get_qos_ctrl(hdr);
- if (qc) {
- u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
seq_number = priv->stations[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
@@ -2660,8 +2619,6 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
- memcpy(&(txq->txb[q->write_ptr].status.control),
- ctl, sizeof(struct ieee80211_tx_control));
/* Init first empty entry in queue's array of Tx/cmd buffers */
out_cmd = &txq->cmd[idx];
@@ -2710,8 +2667,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
* first entry */
iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
- if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
- iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
+ if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
+ iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -2736,18 +2693,17 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
out_cmd->cmd.tx.len = cpu_to_le16(len);
/* TODO need this for burst mode later on */
- iwl3945_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
+ iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id);
/* set is_hcca to 0; it probably will never be implemented */
- iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
+ iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
- if (!ieee80211_get_morefrag(hdr)) {
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc) {
- u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
priv->stations[sta_id].tid[tid].seq_number = seq_number;
}
} else {
@@ -2759,7 +2715,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
sizeof(out_cmd->cmd.tx));
iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
- ieee80211_get_hdrlen(fc));
+ ieee80211_get_hdrlen(le16_to_cpu(fc)));
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -2778,7 +2734,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
spin_unlock_irqrestore(&priv->lock, flags);
}
- ieee80211_stop_queue(priv->hw, ctl->queue);
+ ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
}
return 0;
@@ -2888,7 +2844,8 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
return;
}
- queue_work(priv->workqueue, &priv->restart);
+ if (priv->is_open)
+ queue_work(priv->workqueue, &priv->restart);
return;
}
@@ -2924,72 +2881,6 @@ void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
}
}
-#define IWL_PACKET_RETRY_TIME HZ
-
-int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
-{
- u16 sc = le16_to_cpu(header->seq_ctrl);
- u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
- u16 frag = sc & IEEE80211_SCTL_FRAG;
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
-
- switch (priv->iw_mode) {
- case IEEE80211_IF_TYPE_IBSS:{
- struct list_head *p;
- struct iwl3945_ibss_seq *entry = NULL;
- u8 *mac = header->addr2;
- int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
-
- __list_for_each(p, &priv->ibss_mac_hash[index]) {
- entry = list_entry(p, struct iwl3945_ibss_seq, list);
- if (!compare_ether_addr(entry->mac, mac))
- break;
- }
- if (p == &priv->ibss_mac_hash[index]) {
- entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry) {
- IWL_ERROR("Cannot malloc new mac entry\n");
- return 0;
- }
- memcpy(entry->mac, mac, ETH_ALEN);
- entry->seq_num = seq;
- entry->frag_num = frag;
- entry->packet_time = jiffies;
- list_add(&entry->list, &priv->ibss_mac_hash[index]);
- return 0;
- }
- last_seq = &entry->seq_num;
- last_frag = &entry->frag_num;
- last_time = &entry->packet_time;
- break;
- }
- case IEEE80211_IF_TYPE_STA:
- last_seq = &priv->last_seq_num;
- last_frag = &priv->last_frag_num;
- last_time = &priv->last_packet_time;
- break;
- default:
- return 0;
- }
- if ((*last_seq == seq) &&
- time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag)
- goto drop;
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- goto drop;
- } else
- *last_seq = seq;
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
- drop:
- return 1;
-}
-
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h"
@@ -3241,7 +3132,7 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
+ beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
IWL_ERROR("update beacon failed\n");
@@ -4848,7 +4739,7 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x"
+ IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
" %ddBm): Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
@@ -4858,7 +4749,6 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
CHECK_AND_PRINT(ACTIVE),
CHECK_AND_PRINT(RADAR),
CHECK_AND_PRINT(WIDE),
- CHECK_AND_PRINT(NARROW),
CHECK_AND_PRINT(DFS),
eeprom_ch_info[ch].flags,
eeprom_ch_info[ch].max_power_avg,
@@ -4994,9 +4884,6 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
if (scan_ch->type & 1)
scan_ch->type |= (direct_mask << 1);
- if (is_channel_narrow(ch_info))
- scan_ch->type |= (1 << 7);
-
scan_ch->active_dwell = cpu_to_le16(active_dwell);
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
@@ -5843,7 +5730,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
if (iwl3945_is_rfkill(priv))
return;
- ieee80211_start_queues(priv->hw);
+ ieee80211_wake_queues(priv->hw);
priv->active_rate = priv->rates_mask;
priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
@@ -5869,9 +5756,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
/* Configure the adapter for unassociated operation */
iwl3945_commit_rxon(priv);
- /* At this point, the NIC is initialized and operational */
- priv->notif_missed_beacons = 0;
-
iwl3945_reg_txpower_periodic(priv);
iwl3945_led_register(priv);
@@ -5938,7 +5822,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND;
+ STATUS_IN_SUSPEND |
+ test_bit(STATUS_EXIT_PENDING, &priv->status) <<
+ STATUS_EXIT_PENDING;
goto exit;
}
@@ -5953,7 +5839,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
- STATUS_FW_ERROR;
+ STATUS_FW_ERROR |
+ test_bit(STATUS_EXIT_PENDING, &priv->status) <<
+ STATUS_EXIT_PENDING;
spin_lock_irqsave(&priv->lock, flags);
iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -6085,6 +5973,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl3945_down(priv);
+ clear_bit(STATUS_EXIT_PENDING, &priv->status);
/* tried to restart and config the device for as long as our
* patience could withstand */
@@ -6152,6 +6041,26 @@ static void iwl3945_bg_rf_kill(struct work_struct *work)
"Kill switch must be turned off for "
"wireless networking to work.\n");
}
+
+ mutex_unlock(&priv->mutex);
+ iwl3945_rfkill_set_hw_state(priv);
+}
+
+static void iwl3945_bg_set_monitor(struct work_struct *work)
+{
+ struct iwl3945_priv *priv = container_of(work,
+ struct iwl3945_priv, set_monitor);
+
+ IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");
+
+ mutex_lock(&priv->mutex);
+
+ if (!iwl3945_is_ready(priv))
+ IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
+ else
+ if (iwl3945_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0)
+ IWL_ERROR("iwl3945_set_mode() failed\n");
+
mutex_unlock(&priv->mutex);
}
@@ -6388,6 +6297,7 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
+ iwl3945_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
@@ -6511,8 +6421,6 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
break;
}
- iwl3945_sequence_reset(priv);
-
iwl3945_activate_qos(priv, 0);
/* we have just associated, don't start scan too early */
@@ -6608,6 +6516,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
+ iwl3945_rfkill_set_hw_state(priv);
+
if (ret)
goto out_release_irq;
@@ -6678,8 +6588,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211("leave\n");
}
-static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl3945_priv *priv = hw->priv;
@@ -6692,9 +6601,9 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
}
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
- ctl->tx_rate->bitrate);
+ ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
- if (iwl3945_tx_skb(priv, skb, ctl))
+ if (iwl3945_tx_skb(priv, skb))
dev_kfree_skb_any(skb);
IWL_DEBUG_MAC80211("leave\n");
@@ -6837,7 +6746,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
return;
/* The following should be done only at AP bring up */
- if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) {
+ if (!(iwl3945_is_associated(priv))) {
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -6886,6 +6795,9 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
* clear sta table, add BCAST sta... */
}
+/* temporary */
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
@@ -6903,10 +6815,21 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
return 0;
}
+ /* handle this temporarily here */
+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+ conf->changed & IEEE80211_IFCC_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+ if (!beacon)
+ return -ENOMEM;
+ rc = iwl3945_mac_beacon_update(hw, beacon);
+ if (rc)
+ return rc;
+ }
+
/* XXX: this MUST use conf->mac_addr */
if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
- (!conf->beacon || !conf->ssid_len)) {
+ (!conf->ssid_len)) {
IWL_DEBUG_MAC80211
("Leaving in AP mode because HostAPD is not ready.\n");
return 0;
@@ -6938,7 +6861,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
- priv->ibss_beacon = conf->beacon;
+ priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
if (iwl3945_is_rfkill(priv))
@@ -6999,11 +6922,18 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags,
int mc_count, struct dev_addr_list *mc_list)
{
- /*
- * XXX: dummy
- * see also iwl3945_connection_init_rx_config
- */
- *total_flags = 0;
+ struct iwl3945_priv *priv = hw->priv;
+
+ if (changed_flags & (*total_flags) & FIF_OTHER_BSS) {
+ IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n",
+ IEEE80211_IF_TYPE_MNTR,
+ changed_flags, *total_flags);
+ /* queue work 'cuz mac80211 is holding a lock which
+ * prevents us from issuing (synchronous) f/w cmds */
+ queue_work(priv->workqueue, &priv->set_monitor);
+ }
+ *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI |
+ FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
}
static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
@@ -7061,9 +6991,10 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
rc = -EAGAIN;
goto out_unlock;
}
- /* if we just finished scan ask for delay */
- if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
- IWL_DELAY_NEXT_SCAN, jiffies)) {
+ /* if we just finished scan ask for delay for a broadcast scan */
+ if ((len == 0) && priv->last_scan_jiffies &&
+ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN,
+ jiffies)) {
rc = -EAGAIN;
goto out_unlock;
}
@@ -7150,7 +7081,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return rc;
}
-static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
+static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct iwl3945_priv *priv = hw->priv;
@@ -7224,9 +7155,9 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
q = &txq->q;
avail = iwl3945_queue_space(q);
- stats->data[i].len = q->n_window - avail;
- stats->data[i].limit = q->n_window - q->high_mark;
- stats->data[i].count = q->n_window;
+ stats[i].len = q->n_window - avail;
+ stats[i].limit = q->n_window - q->high_mark;
+ stats[i].count = q->n_window;
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -7315,8 +7246,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
}
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl3945_priv *priv = hw->priv;
unsigned long flags;
@@ -7398,37 +7328,6 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
#endif /* CONFIG_IWL3945_DEBUG */
-static ssize_t show_rf_kill(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- /*
- * 0 - RF kill not enabled
- * 1 - SW based RF kill active (sysfs)
- * 2 - HW based RF kill active
- * 3 - Both HW and SW based RF kill active
- */
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) |
- (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0);
-
- return sprintf(buf, "%i\n", val);
-}
-
-static ssize_t store_rf_kill(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
-
- mutex_lock(&priv->mutex);
- iwl3945_radio_kill_sw(priv, buf[0] == '1');
- mutex_unlock(&priv->mutex);
-
- return count;
-}
-
-static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
-
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -7879,6 +7778,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
+ INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor);
INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
@@ -7913,7 +7813,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
#endif
&dev_attr_power_level.attr,
&dev_attr_retry_rate.attr,
- &dev_attr_rf_kill.attr,
&dev_attr_rs_window.attr,
&dev_attr_statistics.attr,
&dev_attr_status.attr,
@@ -7943,7 +7842,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.conf_tx = iwl3945_mac_conf_tx,
.get_tsf = iwl3945_mac_get_tsf,
.reset_tsf = iwl3945_mac_reset_tsf,
- .beacon_update = iwl3945_mac_beacon_update,
.hw_scan = iwl3945_mac_hw_scan
};
@@ -7953,7 +7851,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
struct iwl3945_priv *priv;
struct ieee80211_hw *hw;
struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
- int i;
unsigned long flags;
DECLARE_MAC_BUF(mac);
@@ -8001,17 +7898,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->ibss_beacon = NULL;
- /* Tell mac80211 and its clients (e.g. Wireless Extensions)
- * the range of signal quality values that we'll provide.
- * Negative values for level/noise indicate that we'll provide dBm.
- * For WE, at least, non-0 values here *enable* display of values
- * in app (iwconfig). */
- hw->max_rssi = -20; /* signal level, negative indicates dBm */
- hw->max_noise = -20; /* noise level, negative indicates dBm */
- hw->max_signal = 100; /* link quality indication (%) */
-
- /* Tell mac80211 our Tx characteristics */
- hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
+ /* Tell mac80211 our characteristics */
+ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
/* 4 EDCA QOS priorities */
hw->queues = 4;
@@ -8021,9 +7911,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
- for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
-
INIT_LIST_HEAD(&priv->free_frames);
mutex_init(&priv->mutex);
@@ -8161,6 +8048,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_save_state(pdev);
pci_disable_device(pdev);
+ err = iwl3945_rfkill_init(priv);
+ if (err)
+ IWL_ERROR("Unable to initialize RFKILL system. "
+ "Ignoring error: %d\n", err);
+
return 0;
out_free_geos:
@@ -8191,8 +8083,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
{
struct iwl3945_priv *priv = pci_get_drvdata(pdev);
- struct list_head *p, *q;
- int i;
unsigned long flags;
if (!priv)
@@ -8213,16 +8103,9 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl_synchronize_irq(priv);
- /* Free MAC hash list for ADHOC */
- for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
- list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
- list_del(p);
- kfree(list_entry(p, struct iwl3945_ibss_seq, list));
- }
- }
-
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
+ iwl3945_rfkill_unregister(priv);
iwl3945_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
@@ -8252,7 +8135,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl3945_free_channel_map(priv);
iwl3945_free_geos(priv);
-
+ kfree(priv->scan);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -8291,6 +8174,114 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
+/*************** RFKILL FUNCTIONS **********/
+#ifdef CONFIG_IWL3945_RFKILL
+/* software rf-kill from user */
+static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
+{
+ struct iwl3945_priv *priv = data;
+ int err = 0;
+
+ if (!priv->rfkill)
+ return 0;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return 0;
+
+ IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state);
+ mutex_lock(&priv->mutex);
+
+ switch (state) {
+ case RFKILL_STATE_UNBLOCKED:
+ if (iwl3945_is_rfkill_hw(priv)) {
+ err = -EBUSY;
+ goto out_unlock;
+ }
+ iwl3945_radio_kill_sw(priv, 0);
+ break;
+ case RFKILL_STATE_SOFT_BLOCKED:
+ iwl3945_radio_kill_sw(priv, 1);
+ break;
+ default:
+ IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
+ break;
+ }
+out_unlock:
+ mutex_unlock(&priv->mutex);
+
+ return err;
+}
+
+int iwl3945_rfkill_init(struct iwl3945_priv *priv)
+{
+ struct device *device = wiphy_dev(priv->hw->wiphy);
+ int ret = 0;
+
+ BUG_ON(device == NULL);
+
+ IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
+ priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
+ if (!priv->rfkill) {
+ IWL_ERROR("Unable to allocate rfkill device.\n");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ priv->rfkill->name = priv->cfg->name;
+ priv->rfkill->data = priv;
+ priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
+ priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
+ priv->rfkill->user_claim_unsupported = 1;
+
+ priv->rfkill->dev.class->suspend = NULL;
+ priv->rfkill->dev.class->resume = NULL;
+
+ ret = rfkill_register(priv->rfkill);
+ if (ret) {
+ IWL_ERROR("Unable to register rfkill: %d\n", ret);
+ goto freed_rfkill;
+ }
+
+ IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+ return ret;
+
+freed_rfkill:
+ if (priv->rfkill != NULL)
+ rfkill_free(priv->rfkill);
+ priv->rfkill = NULL;
+
+error:
+ IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+ return ret;
+}
+
+void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
+{
+ if (priv->rfkill)
+ rfkill_unregister(priv->rfkill);
+
+ priv->rfkill = NULL;
+}
+
+/* set rf-kill to the right state. */
+void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
+{
+
+ if (!priv->rfkill)
+ return;
+
+ if (iwl3945_is_rfkill_hw(priv)) {
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
+ return;
+ }
+
+ if (!iwl3945_is_rfkill_sw(priv))
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
+ else
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+}
+#endif
+
/*****************************************************************************
*
* driver and module entry point
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 0bd55bb1973..71f5da3fe5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -46,14 +46,13 @@
#include <asm/div64.h>
#include "iwl-eeprom.h"
-#include "iwl-4965.h"
+#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
#include "iwl-sta.h"
+#include "iwl-calib.h"
-static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq);
/******************************************************************************
*
@@ -88,292 +87,6 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");
-__le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
-{
- u16 fc = le16_to_cpu(hdr->frame_control);
- int hdr_len = ieee80211_get_hdrlen(fc);
-
- if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
- return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
- return NULL;
-}
-
-static const struct ieee80211_supported_band *iwl4965_get_hw_mode(
- struct iwl_priv *priv, enum ieee80211_band band)
-{
- return priv->hw->wiphy->bands[band];
-}
-
-static int iwl4965_is_empty_essid(const char *essid, int essid_len)
-{
- /* Single white space is for Linksys APs */
- if (essid_len == 1 && essid[0] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
-static const char *iwl4965_escape_essid(const char *essid, u8 essid_len)
-{
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- const char *s = essid;
- char *d = escaped;
-
- if (iwl4965_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
- while (essid_len--) {
- if (*s == '\0') {
- *d++ = '\\';
- *d++ = '0';
- s++;
- } else
- *d++ = *s++;
- }
- *d = '\0';
- return escaped;
-}
-
-/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill. Driver and device exchange status of each
- * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 4965 operates with up to 17 queues: One receive queue, one transmit
- * queue (#4) for sending commands to the device firmware, and 15 other
- * Tx queues that may be mapped to prioritized Tx DMA/FIFO channels.
- *
- * See more detailed info in iwl-4965-hw.h.
- ***************************************************/
-
-int iwl4965_queue_space(const struct iwl4965_queue *q)
-{
- int s = q->read_ptr - q->write_ptr;
-
- if (q->read_ptr > q->write_ptr)
- s -= q->n_bd;
-
- if (s <= 0)
- s += q->n_window;
- /* keep some reserve to not confuse empty and full situations */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-
-static inline int x2_queue_used(const struct iwl4965_queue *q, int i)
-{
- return q->write_ptr > q->read_ptr ?
- (i >= q->read_ptr && i < q->write_ptr) :
- !(i < q->read_ptr && i >= q->write_ptr);
-}
-
-static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge)
-{
- /* This is for scan command, the big buffer at end of command array */
- if (is_huge)
- return q->n_window; /* must be power of 2 */
-
- /* Otherwise, use normal size buffers */
- return index & (q->n_window - 1);
-}
-
-/**
- * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl4965_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q,
- int count, int slots_num, u32 id)
-{
- q->n_bd = count;
- q->n_window = slots_num;
- q->id = id;
-
- /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
- * and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
-
- /* slots_num must be power-of-two size, otherwise
- * get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
-
- q->low_mark = q->n_window / 4;
- if (q->low_mark < 4)
- q->low_mark = 4;
-
- q->high_mark = q->n_window / 8;
- if (q->high_mark < 2)
- q->high_mark = 2;
-
- q->write_ptr = q->read_ptr = 0;
-
- return 0;
-}
-
-/**
- * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl4965_tx_queue_alloc(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq, u32 id)
-{
- struct pci_dev *dev = priv->pci_dev;
-
- /* Driver private data, only for Tx (not command) queues,
- * not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
- txq->txb = kmalloc(sizeof(txq->txb[0]) *
- TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
- if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
- "structures failed\n");
- goto error;
- }
- } else
- txq->txb = NULL;
-
- /* Circular buffer of transmit frame descriptors (TFDs),
- * shared with device */
- txq->bd = pci_alloc_consistent(dev,
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
-
- if (!txq->bd) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
- goto error;
- }
- txq->q.id = id;
-
- return 0;
-
- error:
- if (txq->txb) {
- kfree(txq->txb);
- txq->txb = NULL;
- }
-
- return -ENOMEM;
-}
-
-/**
- * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl4965_tx_queue_init(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id)
-{
- struct pci_dev *dev = priv->pci_dev;
- int len;
- int rc = 0;
-
- /*
- * Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
- * command for scan, since scan command is very huge; the system will
- * not have two scans at the same time, so only one is needed.
- * For normal Tx queues (all other queues), no super-size command
- * space is needed.
- */
- len = sizeof(struct iwl_cmd) * slots_num;
- if (txq_id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
- txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
- if (!txq->cmd)
- return -ENOMEM;
-
- /* Alloc driver data array and TFD circular buffer */
- rc = iwl4965_tx_queue_alloc(priv, txq, txq_id);
- if (rc) {
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- return -ENOMEM;
- }
- txq->need_update = 0;
-
- /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
- BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
- /* Initialize queue's high/low-water marks, and head/tail indexes */
- iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
- /* Tell device where to find queue */
- iwl4965_hw_tx_queue_init(priv, txq);
-
- return 0;
-}
-
-/**
- * iwl4965_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq)
-{
- struct iwl4965_queue *q = &txq->q;
- struct pci_dev *dev = priv->pci_dev;
- int len;
-
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl4965_hw_txq_free_tfd(priv, txq);
-
- len = sizeof(struct iwl_cmd) * q->n_window;
- if (q->id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
-
- /* De-alloc array of command/tx buffers */
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- /* De-alloc circular buffer of TFDs */
- if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) *
- txq->q.n_bd, txq->bd, txq->q.dma_addr);
-
- /* De-alloc array of per-TFD driver data */
- if (txq->txb) {
- kfree(txq->txb);
- txq->txb = NULL;
- }
-
- /* 0-fill queue descriptor structure */
- memset(txq, 0, sizeof(*txq));
-}
-
-const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-
/*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating
* the functionality provided here
@@ -381,213 +94,11 @@ const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
/**************************************************************/
-#if 0 /* temporary disable till we add real remove station */
-/**
- * iwl4965_remove_station - Remove driver's knowledge of station.
- *
- * NOTE: This does not remove station from device's station table.
- */
-static u8 iwl4965_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
-{
- int index = IWL_INVALID_STATION;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- if (is_ap)
- index = IWL_AP_ID;
- else if (is_broadcast_ether_addr(addr))
- index = priv->hw_params.bcast_sta_id;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
- if (priv->stations[i].used &&
- !compare_ether_addr(priv->stations[i].sta.sta.addr,
- addr)) {
- index = i;
- break;
- }
-
- if (unlikely(index == IWL_INVALID_STATION))
- goto out;
-
- if (priv->stations[index].used) {
- priv->stations[index].used = 0;
- priv->num_stations--;
- }
-
- BUG_ON(priv->num_stations < 0);
-
-out:
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
-}
-#endif
-
-/**
- * iwl4965_add_station_flags - Add station to tables in driver and device
- */
-u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr,
- int is_ap, u8 flags, void *ht_data)
-{
- int i;
- int index = IWL_INVALID_STATION;
- struct iwl4965_station_entry *station;
- unsigned long flags_spin;
- DECLARE_MAC_BUF(mac);
-
- spin_lock_irqsave(&priv->sta_lock, flags_spin);
- if (is_ap)
- index = IWL_AP_ID;
- else if (is_broadcast_ether_addr(addr))
- index = priv->hw_params.bcast_sta_id;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
- if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
- addr)) {
- index = i;
- break;
- }
-
- if (!priv->stations[i].used &&
- index == IWL_INVALID_STATION)
- index = i;
- }
-
-
- /* These two conditions have the same outcome, but keep them separate
- since they have different meanings */
- if (unlikely(index == IWL_INVALID_STATION)) {
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- return index;
- }
-
- if (priv->stations[index].used &&
- !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- return index;
- }
-
-
- IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr));
- station = &priv->stations[index];
- station->used = 1;
- priv->num_stations++;
-
- /* Set up the REPLY_ADD_STA command to send to device */
- memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd));
- memcpy(station->sta.sta.addr, addr, ETH_ALEN);
- station->sta.mode = 0;
- station->sta.sta.sta_id = index;
- station->sta.station_flags = 0;
-
-#ifdef CONFIG_IWL4965_HT
- /* BCAST station and IBSS stations do not work in HT mode */
- if (index != priv->hw_params.bcast_sta_id &&
- priv->iw_mode != IEEE80211_IF_TYPE_IBSS)
- iwl4965_set_ht_add_station(priv, index,
- (struct ieee80211_ht_info *) ht_data);
-#endif /*CONFIG_IWL4965_HT*/
-
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-
- /* Add station to device's station table */
- iwl4965_send_add_station(priv, &station->sta, flags);
- return index;
-
-}
-
-
-
-/*************** HOST COMMAND QUEUE FUNCTIONS *****/
-
-/**
- * iwl4965_enqueue_hcmd - enqueue a uCode command
- * @priv: device private data point
- * @cmd: a point to the ucode command structure
- *
- * The function returns < 0 values to indicate the operation is
- * failed. On success, it turns the index (> 0) of command in the
- * command queue.
- */
-int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
-{
- struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
- struct iwl4965_queue *q = &txq->q;
- struct iwl4965_tfd_frame *tfd;
- u32 *control_flags;
- struct iwl_cmd *out_cmd;
- u32 idx;
- u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
- dma_addr_t phys_addr;
- int ret;
- unsigned long flags;
-
- /* If any of the command structures end up being larger than
- * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
- * we will need to increase the size of the TFD entries */
- BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
- !(cmd->meta.flags & CMD_SIZE_HUGE));
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_INFO("Not sending command - RF KILL");
- return -EIO;
- }
-
- if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
- return -ENOSPC;
- }
-
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
- control_flags = (u32 *) tfd;
- idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
- out_cmd = &txq->cmd[idx];
-
- out_cmd->hdr.cmd = cmd->id;
- memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
- memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
-
- /* At this point, the out_cmd now has all of the incoming cmd
- * information */
-
- out_cmd->hdr.flags = 0;
- out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
- INDEX_TO_SEQ(q->write_ptr));
- if (out_cmd->meta.flags & CMD_SIZE_HUGE)
- out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
-
- phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
- offsetof(struct iwl_cmd, hdr);
- iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
-
- IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
- "%d bytes at %d[%d]:%d\n",
- get_cmd_string(out_cmd->hdr.cmd),
- out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
- fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
-
- txq->need_update = 1;
-
- /* Set up entry in queue's byte count circular buffer */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
-
- /* Increment and update queue's write index */
- q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- ret = iwl4965_tx_queue_update_write_ptr(priv, txq);
-
- spin_unlock_irqrestore(&priv->hcmd_lock, flags);
- return ret ? ret : idx;
-}
static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
{
- struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon;
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
if (hw_decrypt)
rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -597,45 +108,13 @@ static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
}
/**
- * iwl4965_rxon_add_station - add station into station table.
- *
- * there is only one AP station with id= IWL_AP_ID
- * NOTE: mutex must be held before calling this fnction
- */
-static int iwl4965_rxon_add_station(struct iwl_priv *priv,
- const u8 *addr, int is_ap)
-{
- u8 sta_id;
-
- /* Add station to device's station table */
-#ifdef CONFIG_IWL4965_HT
- struct ieee80211_conf *conf = &priv->hw->conf;
- struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;
-
- if ((is_ap) &&
- (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
- (priv->iw_mode == IEEE80211_IF_TYPE_STA))
- sta_id = iwl4965_add_station_flags(priv, addr, is_ap,
- 0, cur_ht_config);
- else
-#endif /* CONFIG_IWL4965_HT */
- sta_id = iwl4965_add_station_flags(priv, addr, is_ap,
- 0, NULL);
-
- /* Set up default rate scaling table in device's station table */
- iwl4965_add_station(priv, addr, is_ap);
-
- return sta_id;
-}
-
-/**
* iwl4965_check_rxon_cmd - validate RXON structure is valid
*
* NOTE: This is really only useful during development and can eventually
* be #ifdef'd out once the driver is stable and folks aren't actively
* making changes
*/
-static int iwl4965_check_rxon_cmd(struct iwl4965_rxon_cmd *rxon)
+static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
{
int error = 0;
int counter = 1;
@@ -713,7 +192,7 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv)
{
/* These items are only settable from the full RXON command */
- if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ||
+ if (!(iwl_is_associated(priv)) ||
compare_ether_addr(priv->staging_rxon.bssid_addr,
priv->active_rxon.bssid_addr) ||
compare_ether_addr(priv->staging_rxon.node_addr,
@@ -760,18 +239,23 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv)
static int iwl4965_commit_rxon(struct iwl_priv *priv)
{
/* cast away the const for active_rxon in this function */
- struct iwl4965_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
DECLARE_MAC_BUF(mac);
- int rc = 0;
+ int ret;
+ bool new_assoc =
+ !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
- return -1;
+ return -EBUSY;
/* always get timestamp with Rx frame */
priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+ /* allow CTS-to-self if possible. this is relevant only for
+ * 5000, but will not damage 4965 */
+ priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
- rc = iwl4965_check_rxon_cmd(&priv->staging_rxon);
- if (rc) {
+ ret = iwl4965_check_rxon_cmd(&priv->staging_rxon);
+ if (ret) {
IWL_ERROR("Invalid RXON configuration. Not committing.\n");
return -EINVAL;
}
@@ -780,49 +264,37 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
* iwl4965_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
if (!iwl4965_full_rxon_required(priv)) {
- rc = iwl_send_rxon_assoc(priv);
- if (rc) {
- IWL_ERROR("Error setting RXON_ASSOC "
- "configuration (%d).\n", rc);
- return rc;
+ ret = iwl_send_rxon_assoc(priv);
+ if (ret) {
+ IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
+ return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
-
return 0;
}
/* station table will be cleared */
priv->assoc_station_added = 0;
-#ifdef CONFIG_IWL4965_SENSITIVITY
- priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT;
- if (!priv->error_recovering)
- priv->start_calib = 0;
-
- iwl4965_init_sensitivity(priv, CMD_ASYNC, 1);
-#endif /* CONFIG_IWL4965_SENSITIVITY */
-
/* If we are currently associated and the new config requires
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl_is_associated(priv) &&
- (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
+ if (iwl_is_associated(priv) && new_assoc) {
IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl4965_rxon_cmd),
+ ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl_rxon_cmd),
&priv->active_rxon);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
- if (rc) {
+ if (ret) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK on current "
- "configuration (%d).\n", rc);
- return rc;
+ IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret);
+ return ret;
}
}
@@ -830,65 +302,87 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %s\n",
- ((priv->staging_rxon.filter_flags &
- RXON_FILTER_ASSOC_MSK) ? "" : "out"),
+ (new_assoc ? "" : "out"),
le16_to_cpu(priv->staging_rxon.channel),
print_mac(mac, priv->staging_rxon.bssid_addr));
- iwl4965_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
- /* Apply the new configuration */
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl4965_rxon_cmd), &priv->staging_rxon);
- if (rc) {
- IWL_ERROR("Error setting new configuration (%d).\n", rc);
- return rc;
+ iwl4965_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+
+ /* Apply the new configuration
+ * RXON unassoc clears the station table in uCode, send it before
+ * we add the bcast station. If assoc bit is set, we will send RXON
+ * after having added the bcast and bssid station.
+ */
+ if (!new_assoc) {
+ ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+ if (ret) {
+ IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
}
- iwlcore_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
-#ifdef CONFIG_IWL4965_SENSITIVITY
if (!priv->error_recovering)
priv->start_calib = 0;
- priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT;
- iwl4965_init_sensitivity(priv, CMD_ASYNC, 1);
-#endif /* CONFIG_IWL4965_SENSITIVITY */
-
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
-
- /* If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames */
- rc = iwl4965_hw_reg_send_txpower(priv);
- if (rc) {
- IWL_ERROR("Error setting Tx power (%d).\n", rc);
- return rc;
- }
-
/* Add the broadcast address so we can send broadcast frames */
- if (iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0) ==
- IWL_INVALID_STATION) {
+ if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
+ IWL_INVALID_STATION) {
IWL_ERROR("Error adding BROADCAST address for transmit.\n");
return -EIO;
}
/* If we have set the ASSOC_MSK and we are in BSS mode then
* add the IWL_AP_ID to the station rate table */
- if (iwl_is_associated(priv) &&
- (priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
- if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
- == IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for transmit.\n");
- return -EIO;
+ if (new_assoc) {
+ if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
+ ret = iwl_rxon_add_station(priv,
+ priv->active_rxon.bssid_addr, 1);
+ if (ret == IWL_INVALID_STATION) {
+ IWL_ERROR("Error adding AP address for TX.\n");
+ return -EIO;
+ }
+ priv->assoc_station_added = 1;
+ if (priv->default_wep_key &&
+ iwl_send_static_wepkey_cmd(priv, 0))
+ IWL_ERROR("Could not send WEP static key.\n");
}
- priv->assoc_station_added = 1;
- if (priv->default_wep_key &&
- iwl_send_static_wepkey_cmd(priv, 0))
- IWL_ERROR("Could not send WEP static key.\n");
+
+ /* Apply the new configuration
+ * RXON assoc doesn't clear the station table in uCode,
+ */
+ ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+ if (ret) {
+ IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ return ret;
+ }
+ memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ }
+
+ iwl_init_sensitivity(priv);
+
+ /* If we issue a new RXON command which required a tune then we must
+ * send a new TXPOWER command or we won't be able to Tx any frames */
+ ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ if (ret) {
+ IWL_ERROR("Error sending TX power (%d)\n", ret);
+ return ret;
}
return 0;
}
+void iwl4965_update_chain_flags(struct iwl_priv *priv)
+{
+
+ iwl_set_rxon_chain(priv);
+ iwl4965_commit_rxon(priv);
+}
+
static int iwl4965_send_bt_config(struct iwl_priv *priv)
{
struct iwl4965_bt_cmd bt_cmd = {
@@ -903,155 +397,7 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv)
sizeof(struct iwl4965_bt_cmd), &bt_cmd);
}
-static int iwl4965_send_scan_abort(struct iwl_priv *priv)
-{
- int rc = 0;
- struct iwl4965_rx_packet *res;
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .meta.flags = CMD_WANT_SKB,
- };
-
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
-
- rc = iwl_send_cmd_sync(priv, &cmd);
- if (rc) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return rc;
- }
-
- res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
- if (res->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
-
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
-static int iwl4965_card_state_sync_callback(struct iwl_priv *priv,
- struct iwl_cmd *cmd,
- struct sk_buff *skb)
-{
- return 1;
-}
-
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
-{
- struct iwl_host_cmd cmd = {
- .id = REPLY_CARD_STATE_CMD,
- .len = sizeof(u32),
- .data = &flags,
- .meta.flags = meta_flag,
- };
-
- if (meta_flag & CMD_ASYNC)
- cmd.meta.u.callback = iwl4965_card_state_sync_callback;
-
- return iwl_send_cmd(priv, &cmd);
-}
-
-static int iwl4965_add_sta_sync_callback(struct iwl_priv *priv,
- struct iwl_cmd *cmd, struct sk_buff *skb)
-{
- struct iwl4965_rx_packet *res = NULL;
-
- if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
- return 1;
- }
-
- res = (struct iwl4965_rx_packet *)skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- return 1;
- }
-
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- break;
- default:
- break;
- }
-
- /* We didn't cache the SKB; let the caller free it */
- return 1;
-}
-
-int iwl4965_send_add_station(struct iwl_priv *priv,
- struct iwl4965_addsta_cmd *sta, u8 flags)
-{
- struct iwl4965_rx_packet *res = NULL;
- int rc = 0;
- struct iwl_host_cmd cmd = {
- .id = REPLY_ADD_STA,
- .len = sizeof(struct iwl4965_addsta_cmd),
- .meta.flags = flags,
- .data = sta,
- };
-
- if (flags & CMD_ASYNC)
- cmd.meta.u.callback = iwl4965_add_sta_sync_callback;
- else
- cmd.meta.flags |= CMD_WANT_SKB;
-
- rc = iwl_send_cmd(priv, &cmd);
-
- if (rc || (flags & CMD_ASYNC))
- return rc;
-
- res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- rc = -EIO;
- }
-
- if (rc == 0) {
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
- break;
- default:
- rc = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
- break;
- }
- }
-
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
-static void iwl4965_clear_free_frames(struct iwl_priv *priv)
+static void iwl_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
@@ -1061,7 +407,7 @@ static void iwl4965_clear_free_frames(struct iwl_priv *priv)
while (!list_empty(&priv->free_frames)) {
element = priv->free_frames.next;
list_del(element);
- kfree(list_entry(element, struct iwl4965_frame, list));
+ kfree(list_entry(element, struct iwl_frame, list));
priv->frames_count--;
}
@@ -1072,9 +418,9 @@ static void iwl4965_clear_free_frames(struct iwl_priv *priv)
}
}
-static struct iwl4965_frame *iwl4965_get_free_frame(struct iwl_priv *priv)
+static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
{
- struct iwl4965_frame *frame;
+ struct iwl_frame *frame;
struct list_head *element;
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
@@ -1089,10 +435,10 @@ static struct iwl4965_frame *iwl4965_get_free_frame(struct iwl_priv *priv)
element = priv->free_frames.next;
list_del(element);
- return list_entry(element, struct iwl4965_frame, list);
+ return list_entry(element, struct iwl_frame, list);
}
-static void iwl4965_free_frame(struct iwl_priv *priv, struct iwl4965_frame *frame)
+static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
{
memset(frame, 0, sizeof(*frame));
list_add(&frame->list, &priv->free_frames);
@@ -1116,27 +462,39 @@ unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
return priv->ibss_beacon->len;
}
-static u8 iwl4965_rate_get_lowest_plcp(int rate_mask)
+static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
{
- u8 i;
+ int i;
+ int rate_mask;
+
+ /* Set rate mask*/
+ if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ rate_mask = priv->active_rate_basic & 0xF;
+ else
+ rate_mask = priv->active_rate_basic & 0xFF0;
+ /* Find lowest valid rate */
for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
- i = iwl4965_rates[i].next_ieee) {
+ i = iwl_rates[i].next_ieee) {
if (rate_mask & (1 << i))
- return iwl4965_rates[i].plcp;
+ return iwl_rates[i].plcp;
}
- return IWL_RATE_INVALID;
+ /* No valid rate was found. Assign the lowest one */
+ if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ return IWL_RATE_1M_PLCP;
+ else
+ return IWL_RATE_6M_PLCP;
}
static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
{
- struct iwl4965_frame *frame;
+ struct iwl_frame *frame;
unsigned int frame_size;
int rc;
u8 rate;
- frame = iwl4965_get_free_frame(priv);
+ frame = iwl_get_free_frame(priv);
if (!frame) {
IWL_ERROR("Could not obtain free frame buffer for beacon "
@@ -1144,23 +502,14 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
return -ENOMEM;
}
- if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
- rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic &
- 0xFF0);
- if (rate == IWL_INVALID_RATE)
- rate = IWL_RATE_6M_PLCP;
- } else {
- rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
- if (rate == IWL_INVALID_RATE)
- rate = IWL_RATE_1M_PLCP;
- }
+ rate = iwl4965_rate_get_lowest_plcp(priv);
frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate);
rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
&frame->u.cmd[0]);
- iwl4965_free_frame(priv, frame);
+ iwl_free_frame(priv, frame);
return rc;
}
@@ -1171,184 +520,69 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
*
******************************************************************************/
-static void iwl4965_unset_hw_params(struct iwl_priv *priv)
-{
- if (priv->shared_virt)
- pci_free_consistent(priv->pci_dev,
- sizeof(struct iwl4965_shared),
- priv->shared_virt,
- priv->shared_phys);
-}
-
-/**
- * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl4965_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-/**
- * iwl4965_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl4965_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left, int is_direct)
+static void iwl4965_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_bss_conf *bss_conf)
{
- int len = 0;
- u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates, active_rate_basic;
-#ifdef CONFIG_IWL4965_HT
- const struct ieee80211_supported_band *sband =
- iwl4965_get_hw_mode(priv, band);
-#endif /* CONFIG_IWL4965_HT */
-
- /* Make sure there is enough space for the probe request,
- * two mandatory IEs and the data */
- left -= 24;
- if (left < 0)
- return 0;
- len += 24;
+ struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf;
+ struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf;
+ struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, iwl4965_broadcast_addr, ETH_ALEN);
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
- memcpy(frame->bssid, iwl4965_broadcast_addr, ETH_ALEN);
- frame->seq_ctrl = 0;
+ IWL_DEBUG_MAC80211("enter: \n");
- /* fill in our indirect SSID IE */
- /* ...next IE... */
+ iwl_conf->is_ht = bss_conf->assoc_ht;
- left -= 2;
- if (left < 0)
- return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
- *pos++ = WLAN_EID_SSID;
- *pos++ = 0;
-
- /* fill in our direct SSID IE... */
- if (is_direct) {
- /* ...next IE... */
- left -= 2 + priv->essid_len;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_SSID;
- *pos++ = priv->essid_len;
- memcpy(pos, priv->essid, priv->essid_len);
- pos += priv->essid_len;
- len += 2 + priv->essid_len;
- }
-
- /* fill in supported rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
+ if (!iwl_conf->is_ht)
+ return;
- /* ... fill it in... */
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
+ priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
- /* exclude 60M rate */
- active_rates = priv->rates_mask;
- active_rates &= ~IWL_RATE_60M_MASK;
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+ iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+ iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
- active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
+ iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
+ iwl_conf->max_amsdu_size =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
+ iwl_conf->supported_chan_width =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
+ iwl_conf->extension_chan_offset =
+ ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
+ /* If no above or below channel supplied disable FAT channel */
+ if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE &&
+ iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) {
+ iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE;
+ iwl_conf->supported_chan_width = 0;
+ }
- ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
+ iwl_conf->tx_mimo_ps_mode =
+ (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+ memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
- len += 2 + *pos;
- pos += (*pos) + 1;
- if (active_rates == 0)
- goto fill_end;
+ iwl_conf->control_channel = ht_bss_conf->primary_channel;
+ iwl_conf->tx_chan_width =
+ !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
+ iwl_conf->ht_protection =
+ ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
+ iwl_conf->non_GF_STA_present =
+ !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl4965_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- if (*pos > 0)
- len += 2 + *pos;
-
-#ifdef CONFIG_IWL4965_HT
- if (sband && sband->ht_info.ht_supported) {
- struct ieee80211_ht_cap *ht_cap;
- pos += (*pos) + 1;
- *pos++ = WLAN_EID_HT_CAPABILITY;
- *pos++ = sizeof(struct ieee80211_ht_cap);
- ht_cap = (struct ieee80211_ht_cap *)pos;
- ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);
- memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);
- ht_cap->ampdu_params_info =(sband->ht_info.ampdu_factor &
- IEEE80211_HT_CAP_AMPDU_FACTOR) |
- ((sband->ht_info.ampdu_density << 2) &
- IEEE80211_HT_CAP_AMPDU_DENSITY);
- len += 2 + sizeof(struct ieee80211_ht_cap);
- }
-#endif /*CONFIG_IWL4965_HT */
-
- fill_end:
- return (u16)len;
+ IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel);
+ IWL_DEBUG_MAC80211("leave\n");
}
/*
* QoS support
*/
-static int iwl4965_send_qos_params_command(struct iwl_priv *priv,
- struct iwl4965_qosparam_cmd *qos)
-{
-
- return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl4965_qosparam_cmd), qos);
-}
-
-static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
+static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
{
- unsigned long flags;
-
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
if (!priv->qos_data.qos_enable)
return;
- spin_lock_irqsave(&priv->lock, flags);
priv->qos_data.def_qos_parm.qos_flags = 0;
if (priv->qos_data.qos_cap.q_AP.queue_request &&
@@ -1359,323 +593,18 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
priv->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-#ifdef CONFIG_IWL4965_HT
if (priv->current_ht_config.is_ht)
priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-#endif /* CONFIG_IWL4965_HT */
-
- spin_unlock_irqrestore(&priv->lock, flags);
if (force || iwl_is_associated(priv)) {
IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
priv->qos_data.qos_active,
priv->qos_data.def_qos_parm.qos_flags);
- iwl4965_send_qos_params_command(priv,
- &(priv->qos_data.def_qos_parm));
- }
-}
-
-/*
- * Power management (not Tx power!) functions
- */
-#define MSEC_TO_USEC 1024
-
-#define NOSLP __constant_cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
-
-
-/* default power management (not Tx power) table values */
-/* for tim 0-10 */
-static struct iwl4965_power_vec_entry range_0[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
-};
-
-/* for tim > 10 */
-static struct iwl4965_power_vec_entry range_1[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
- SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),
- SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),
- SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),
- SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
-};
-
-int iwl4965_power_init_handle(struct iwl_priv *priv)
-{
- int rc = 0, i;
- struct iwl4965_power_mgr *pow_data;
- int size = sizeof(struct iwl4965_power_vec_entry) * IWL_POWER_AC;
- u16 pci_pm;
-
- IWL_DEBUG_POWER("Initialize power \n");
-
- pow_data = &(priv->power_data);
-
- memset(pow_data, 0, sizeof(*pow_data));
-
- pow_data->active_index = IWL_POWER_RANGE_0;
- pow_data->dtim_val = 0xffff;
-
- memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
- memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
-
- rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);
- if (rc != 0)
- return 0;
- else {
- struct iwl4965_powertable_cmd *cmd;
-
- IWL_DEBUG_POWER("adjust power command flags\n");
-
- for (i = 0; i < IWL_POWER_AC; i++) {
- cmd = &pow_data->pwr_range_0[i].cmd;
-
- if (pci_pm & 0x1)
- cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
- else
- cmd->flags |= IWL_POWER_PCI_PM_MSK;
- }
+ iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ sizeof(struct iwl_qosparam_cmd),
+ &priv->qos_data.def_qos_parm, NULL);
}
- return rc;
-}
-
-static int iwl4965_update_power_cmd(struct iwl_priv *priv,
- struct iwl4965_powertable_cmd *cmd, u32 mode)
-{
- int rc = 0, i;
- u8 skip;
- u32 max_sleep = 0;
- struct iwl4965_power_vec_entry *range;
- u8 period = 0;
- struct iwl4965_power_mgr *pow_data;
-
- if (mode > IWL_POWER_INDEX_5) {
- IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
- }
- pow_data = &(priv->power_data);
-
- if (pow_data->active_index == IWL_POWER_RANGE_0)
- range = &pow_data->pwr_range_0[0];
- else
- range = &pow_data->pwr_range_1[1];
-
- memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd));
-
-#ifdef IWL_MAC80211_DISABLE
- if (priv->assoc_network != NULL) {
- unsigned long flags;
-
- period = priv->assoc_network->tim.tim_period;
- }
-#endif /*IWL_MAC80211_DISABLE */
- skip = range[mode].no_dtim;
-
- if (period == 0) {
- period = 1;
- skip = 0;
- }
-
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
- } else {
- __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
- max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
- cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
- }
-
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
- if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
- cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
-
- IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
- IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
- IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
- IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
- le32_to_cpu(cmd->sleep_interval[0]),
- le32_to_cpu(cmd->sleep_interval[1]),
- le32_to_cpu(cmd->sleep_interval[2]),
- le32_to_cpu(cmd->sleep_interval[3]),
- le32_to_cpu(cmd->sleep_interval[4]));
-
- return rc;
-}
-
-static int iwl4965_send_power_mode(struct iwl_priv *priv, u32 mode)
-{
- u32 uninitialized_var(final_mode);
- int rc;
- struct iwl4965_powertable_cmd cmd;
-
- /* If on battery, set to 3,
- * if plugged into AC power, set to CAM ("continuously aware mode"),
- * else user level */
- switch (mode) {
- case IWL_POWER_BATTERY:
- final_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_AC:
- final_mode = IWL_POWER_MODE_CAM;
- break;
- default:
- final_mode = mode;
- break;
- }
-
- cmd.keep_alive_beacons = 0;
-
- iwl4965_update_power_cmd(priv, &cmd, final_mode);
-
- rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
-
- if (final_mode == IWL_POWER_MODE_CAM)
- clear_bit(STATUS_POWER_PMI, &priv->status);
- else
- set_bit(STATUS_POWER_PMI, &priv->status);
-
- return rc;
-}
-
-int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
-{
- /* Filter incoming packets to determine if they are targeted toward
- * this network, discarding packets coming from ourselves */
- switch (priv->iw_mode) {
- case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
- /* packets from our adapter are dropped (echo) */
- if (!compare_ether_addr(header->addr2, priv->mac_addr))
- return 0;
- /* {broad,multi}cast packets to our IBSS go through */
- if (is_multicast_ether_addr(header->addr1))
- return !compare_ether_addr(header->addr3, priv->bssid);
- /* packets to our adapter go through */
- return !compare_ether_addr(header->addr1, priv->mac_addr);
- case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
- /* packets from our adapter are dropped (echo) */
- if (!compare_ether_addr(header->addr3, priv->mac_addr))
- return 0;
- /* {broad,multi}cast packets to our BSS go through */
- if (is_multicast_ether_addr(header->addr1))
- return !compare_ether_addr(header->addr2, priv->bssid);
- /* packets to our adapter go through */
- return !compare_ether_addr(header->addr1, priv->mac_addr);
- default:
- break;
- }
-
- return 1;
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static const char *iwl4965_get_tx_fail_reason(u32 status)
-{
- switch (status & TX_STATUS_MSK) {
- case TX_STATUS_SUCCESS:
- return "SUCCESS";
- TX_STATUS_ENTRY(SHORT_LIMIT);
- TX_STATUS_ENTRY(LONG_LIMIT);
- TX_STATUS_ENTRY(FIFO_UNDERRUN);
- TX_STATUS_ENTRY(MGMNT_ABORT);
- TX_STATUS_ENTRY(NEXT_FRAG);
- TX_STATUS_ENTRY(LIFE_EXPIRE);
- TX_STATUS_ENTRY(DEST_PS);
- TX_STATUS_ENTRY(ABORTED);
- TX_STATUS_ENTRY(BT_RETRY);
- TX_STATUS_ENTRY(STA_INVALID);
- TX_STATUS_ENTRY(FRAG_DROPPED);
- TX_STATUS_ENTRY(TID_DISABLE);
- TX_STATUS_ENTRY(FRAME_FLUSHED);
- TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
- TX_STATUS_ENTRY(TX_LOCKED);
- TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
- }
-
- return "UNKNOWN";
-}
-
-/**
- * iwl4965_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-static int iwl4965_scan_cancel(struct iwl_priv *priv)
-{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- queue_work(priv->workqueue, &priv->abort_scan);
-
- } else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return 0;
-}
-
-/**
- * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan
- * @ms: amount of time to wait (in milliseconds) for scan to abort
- *
- * NOTE: priv->mutex must be held before calling this function
- */
-static int iwl4965_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
-{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl4965_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return ret;
-}
-
-static void iwl4965_sequence_reset(struct iwl_priv *priv)
-{
- /* Reset ieee stats */
-
- /* We don't reset the net_device_stats (ieee->stats) on
- * re-association */
-
- priv->last_seq_num = -1;
- priv->last_frag_num = -1;
- priv->last_packet_time = 0;
-
- iwl4965_scan_cancel(priv);
}
#define MAX_UCODE_BEACON_INTERVAL 4096
@@ -1750,46 +679,8 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl4965_scan_initiate(struct iwl_priv *priv)
-{
- if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
- IWL_ERROR("APs don't scan.\n");
- return 0;
- }
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
- return -EIO;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan already in progress.\n");
- return -EAGAIN;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending. "
- "Queuing.\n");
- return -EAGAIN;
- }
-
- IWL_DEBUG_INFO("Starting scan...\n");
- if (priv->cfg->sku & IWL_SKU_G)
- priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
- if (priv->cfg->sku & IWL_SKU_A)
- priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
- set_bit(STATUS_SCANNING, &priv->status);
- priv->scan_start = jiffies;
- priv->scan_pass_start = priv->scan_start;
-
- queue_work(priv->workqueue, &priv->request_scan);
-
- return 0;
-}
-
-
-static void iwl4965_set_flags_for_phymode(struct iwl_priv *priv,
- enum ieee80211_band band)
+static void iwl_set_flags_for_band(struct iwl_priv *priv,
+ enum ieee80211_band band)
{
if (band == IEEE80211_BAND_5GHZ) {
priv->staging_rxon.flags &=
@@ -1858,7 +749,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
#endif
ch_info = iwl_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
+ le16_to_cpu(priv->active_rxon.channel));
if (!ch_info)
ch_info = &priv->channel_info[0];
@@ -1874,7 +765,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
priv->band = ch_info->band;
- iwl4965_set_flags_for_phymode(priv, priv->band);
+ iwl_set_flags_for_band(priv, priv->band);
priv->staging_rxon.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -1887,38 +778,24 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
- iwl4965_set_rxon_chain(priv);
+ iwl_set_rxon_chain(priv);
}
static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
{
- if (mode == IEEE80211_IF_TYPE_IBSS) {
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
-
- if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d not IBSS channel\n",
- le16_to_cpu(priv->staging_rxon.channel));
- return -EINVAL;
- }
- }
-
priv->iw_mode = mode;
iwl4965_connection_init_rx_config(priv);
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
- iwlcore_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* dont commit rxon if rf-kill is on*/
if (!iwl_is_ready_rf(priv))
return -EAGAIN;
cancel_delayed_work(&priv->scan_check);
- if (iwl4965_scan_cancel_timeout(priv, 100)) {
+ if (iwl_scan_cancel_timeout(priv, 100)) {
IWL_WARNING("Aborted scan still in progress after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
return -EAGAIN;
@@ -1929,448 +806,13 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
return 0;
}
-static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
- struct ieee80211_tx_control *ctl,
- struct iwl_cmd *cmd,
- struct sk_buff *skb_frag,
- int sta_id)
-{
- struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
- struct iwl_wep_key *wepkey;
- int keyidx = 0;
-
- BUG_ON(ctl->key_idx > 3);
-
- switch (keyinfo->alg) {
- case ALG_CCMP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
- memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
- if (ctl->flags & IEEE80211_TXCTL_AMPDU)
- cmd->cmd.tx.tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
- IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
- break;
-
- case ALG_TKIP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
- ieee80211_get_tkip_key(keyinfo->conf, skb_frag,
- IEEE80211_TKIP_P2_KEY, cmd->cmd.tx.key);
- IWL_DEBUG_TX("tx_cmd with tkip hwcrypto\n");
- break;
-
- case ALG_WEP:
- wepkey = &priv->wep_keys[ctl->key_idx];
- cmd->cmd.tx.sec_ctl = 0;
- if (priv->default_wep_key) {
- /* the WEP key was sent as static */
- keyidx = ctl->key_idx;
- memcpy(&cmd->cmd.tx.key[3], wepkey->key,
- wepkey->key_size);
- if (wepkey->key_size == WEP_KEY_LEN_128)
- cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
- } else {
- /* the WEP key was sent as dynamic */
- keyidx = keyinfo->keyidx;
- memcpy(&cmd->cmd.tx.key[3], keyinfo->key,
- keyinfo->keylen);
- if (keyinfo->keylen == WEP_KEY_LEN_128)
- cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
- }
-
- cmd->cmd.tx.sec_ctl |= (TX_CMD_SEC_WEP |
- (keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
-
- IWL_DEBUG_TX("Configuring packet for WEP encryption "
- "with key %d\n", keyidx);
- break;
-
- default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
- break;
- }
-}
-
-/*
- * handle build REPLY_TX command notification.
- */
-static void iwl4965_build_tx_cmd_basic(struct iwl_priv *priv,
- struct iwl_cmd *cmd,
- struct ieee80211_tx_control *ctrl,
- struct ieee80211_hdr *hdr,
- int is_unicast, u8 std_id)
-{
- __le16 *qc;
- u16 fc = le16_to_cpu(hdr->frame_control);
- __le32 tx_flags = cmd->cmd.tx.tx_flags;
-
- cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
- if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) {
- tx_flags |= TX_CMD_FLG_ACK_MSK;
- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
- tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
- if (ieee80211_is_probe_response(fc) &&
- !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
- tx_flags |= TX_CMD_FLG_TSF_MSK;
- } else {
- tx_flags &= (~TX_CMD_FLG_ACK_MSK);
- tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
- }
-
- if (ieee80211_is_back_request(fc))
- tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
-
-
- cmd->cmd.tx.sta_id = std_id;
- if (ieee80211_get_morefrag(hdr))
- tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
-
- qc = ieee80211_get_qos_ctrl(hdr);
- if (qc) {
- cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf);
- tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
- } else
- tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
-
- if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- tx_flags |= TX_CMD_FLG_RTS_MSK;
- tx_flags &= ~TX_CMD_FLG_CTS_MSK;
- } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
- tx_flags &= ~TX_CMD_FLG_RTS_MSK;
- tx_flags |= TX_CMD_FLG_CTS_MSK;
- }
-
- if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
- tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
-
- tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
- if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
- (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
- else
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
- } else {
- cmd->cmd.tx.timeout.pm_frame_timeout = 0;
- }
-
- cmd->cmd.tx.driver_txop = 0;
- cmd->cmd.tx.tx_flags = tx_flags;
- cmd->cmd.tx.next_frame_len = 0;
-}
-static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len)
-{
- /* 0 - mgmt, 1 - cnt, 2 - data */
- int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
- priv->tx_stats[idx].cnt++;
- priv->tx_stats[idx].bytes += len;
-}
-/**
- * iwl4965_get_sta_id - Find station's index within station table
- *
- * If new IBSS station, create new entry in station table
- */
-static int iwl4965_get_sta_id(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr)
-{
- int sta_id;
- u16 fc = le16_to_cpu(hdr->frame_control);
- DECLARE_MAC_BUF(mac);
-
- /* If this frame is broadcast or management, use broadcast station id */
- if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
- is_multicast_ether_addr(hdr->addr1))
- return priv->hw_params.bcast_sta_id;
-
- switch (priv->iw_mode) {
-
- /* If we are a client station in a BSS network, use the special
- * AP station entry (that's the only station we communicate with) */
- case IEEE80211_IF_TYPE_STA:
- return IWL_AP_ID;
-
- /* If we are an AP, then find the station, or use BCAST */
- case IEEE80211_IF_TYPE_AP:
- sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
- return priv->hw_params.bcast_sta_id;
-
- /* If this frame is going out to an IBSS network, find the station,
- * or create a new station table entry */
- case IEEE80211_IF_TYPE_IBSS:
- sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- /* Create new station table entry */
- sta_id = iwl4965_add_station_flags(priv, hdr->addr1,
- 0, CMD_ASYNC, NULL);
-
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- IWL_DEBUG_DROP("Station %s not in station map. "
- "Defaulting to broadcast...\n",
- print_mac(mac, hdr->addr1));
- iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_params.bcast_sta_id;
-
- default:
- IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
- return priv->hw_params.bcast_sta_id;
- }
-}
-
-/*
- * start REPLY_TX command process
- */
-static int iwl4965_tx_skb(struct iwl_priv *priv,
- struct sk_buff *skb, struct ieee80211_tx_control *ctl)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct iwl4965_tfd_frame *tfd;
- u32 *control_flags;
- int txq_id = ctl->queue;
- struct iwl4965_tx_queue *txq = NULL;
- struct iwl4965_queue *q = NULL;
- dma_addr_t phys_addr;
- dma_addr_t txcmd_phys;
- dma_addr_t scratch_phys;
- struct iwl_cmd *out_cmd = NULL;
- u16 len, idx, len_org;
- u8 id, hdr_len, unicast;
- u8 sta_id;
- u16 seq_number = 0;
- u16 fc;
- __le16 *qc;
- u8 wait_write_ptr = 0;
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_DROP("Dropping - RF KILL\n");
- goto drop_unlock;
- }
-
- if (!priv->vif) {
- IWL_DEBUG_DROP("Dropping - !priv->vif\n");
- goto drop_unlock;
- }
-
- if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
- goto drop_unlock;
- }
-
- unicast = !is_multicast_ether_addr(hdr->addr1);
- id = 0;
-
- fc = le16_to_cpu(hdr->frame_control);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (ieee80211_is_auth(fc))
- IWL_DEBUG_TX("Sending AUTH frame\n");
- else if (ieee80211_is_assoc_request(fc))
- IWL_DEBUG_TX("Sending ASSOC frame\n");
- else if (ieee80211_is_reassoc_request(fc))
- IWL_DEBUG_TX("Sending REASSOC frame\n");
-#endif
-
- /* drop all data frame if we are not associated */
- if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
- (!iwl_is_associated(priv) ||
- ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
- !priv->assoc_station_added)) {
- IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
- goto drop_unlock;
- }
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- hdr_len = ieee80211_get_hdrlen(fc);
-
- /* Find (or create) index into station table for destination station */
- sta_id = iwl4965_get_sta_id(priv, hdr);
- if (sta_id == IWL_INVALID_STATION) {
- DECLARE_MAC_BUF(mac);
-
- IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n",
- print_mac(mac, hdr->addr1));
- goto drop;
- }
-
- IWL_DEBUG_RATE("station Id %d\n", sta_id);
-
- qc = ieee80211_get_qos_ctrl(hdr);
- if (qc) {
- u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
- seq_number = priv->stations[sta_id].tid[tid].seq_number &
- IEEE80211_SCTL_SEQ;
- hdr->seq_ctrl = cpu_to_le16(seq_number) |
- (hdr->seq_ctrl &
- __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
- seq_number += 0x10;
-#ifdef CONFIG_IWL4965_HT
- /* aggregation is on for this <sta,tid> */
- if (ctl->flags & IEEE80211_TXCTL_AMPDU)
- txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
- priv->stations[sta_id].tid[tid].tfds_in_queue++;
-#endif /* CONFIG_IWL4965_HT */
- }
-
- /* Descriptor for chosen Tx queue */
- txq = &priv->txq[txq_id];
- q = &txq->q;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
- control_flags = (u32 *) tfd;
- idx = get_cmd_index(q, q->write_ptr, 0);
-
- /* Set up driver data for this TFD */
- memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl4965_tx_info));
- txq->txb[q->write_ptr].skb[0] = skb;
- memcpy(&(txq->txb[q->write_ptr].status.control),
- ctl, sizeof(struct ieee80211_tx_control));
-
- /* Set up first empty entry in queue's array of Tx/cmd buffers */
- out_cmd = &txq->cmd[idx];
- memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
- memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
-
- /*
- * Set up the Tx-command (not MAC!) header.
- * Store the chosen Tx queue and TFD index within the sequence field;
- * after Tx, uCode's Tx response will return this value so driver can
- * locate the frame within the tx queue and do post-tx processing.
- */
- out_cmd->hdr.cmd = REPLY_TX;
- out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
- INDEX_TO_SEQ(q->write_ptr)));
-
- /* Copy MAC header from skb into command buffer */
- memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
-
- /*
- * Use the first empty entry in this queue's command buffer array
- * to contain the Tx command and MAC header concatenated together
- * (payload data will be in another buffer).
- * Size of this varies, due to varying MAC header length.
- * If end is not dword aligned, we'll have 2 extra bytes at the end
- * of the MAC header (device reads on dword boundaries).
- * We'll tell device about this padding later.
- */
- len = priv->hw_params.tx_cmd_len +
- sizeof(struct iwl_cmd_header) + hdr_len;
-
- len_org = len;
- len = (len + 3) & ~3;
-
- if (len_org != len)
- len_org = 1;
- else
- len_org = 0;
-
- /* Physical address of this Tx command's header (not MAC header!),
- * within command buffer array. */
- txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
- offsetof(struct iwl_cmd, hdr);
-
- /* Add buffer containing Tx command and MAC(!) header to TFD's
- * first entry */
- iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
-
- if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
- iwl4965_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, sta_id);
-
- /* Set up TFD's 2nd entry to point directly to remainder of skb,
- * if any (802.11 null frames have no payload). */
- len = skb->len - hdr_len;
- if (len) {
- phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
- len, PCI_DMA_TODEVICE);
- iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
- }
-
- /* Tell 4965 about any 2-byte padding after MAC header */
- if (len_org)
- out_cmd->cmd.tx.tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
-
- /* Total # bytes to be transmitted */
- len = (u16)skb->len;
- out_cmd->cmd.tx.len = cpu_to_le16(len);
-
- /* TODO need this for burst mode later on */
- iwl4965_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
-
- /* set is_hcca to 0; it probably will never be implemented */
- iwl4965_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
-
- iwl_update_tx_stats(priv, fc, len);
-
- scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
- offsetof(struct iwl4965_tx_cmd, scratch);
- out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys);
- out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);
-
- if (!ieee80211_get_morefrag(hdr)) {
- txq->need_update = 1;
- if (qc) {
- u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
- }
- } else {
- wait_write_ptr = 1;
- txq->need_update = 0;
- }
-
- iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
- sizeof(out_cmd->cmd.tx));
-
- iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
- ieee80211_get_hdrlen(fc));
-
- /* Set up entry for this TFD in Tx byte-count array */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len);
-
- /* Tell device the write index *just past* this latest filled TFD */
- q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- rc = iwl4965_tx_queue_update_write_ptr(priv, txq);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (rc)
- return rc;
-
- if ((iwl4965_queue_space(q) < q->high_mark)
- && priv->mac80211_registered) {
- if (wait_write_ptr) {
- spin_lock_irqsave(&priv->lock, flags);
- txq->need_update = 1;
- iwl4965_tx_queue_update_write_ptr(priv, txq);
- spin_unlock_irqrestore(&priv->lock, flags);
- }
-
- ieee80211_stop_queue(priv->hw, ctl->queue);
- }
-
- return 0;
-
-drop_unlock:
- spin_unlock_irqrestore(&priv->lock, flags);
-drop:
- return -1;
-}
-
static void iwl4965_set_rate(struct iwl_priv *priv)
{
const struct ieee80211_supported_band *hw = NULL;
struct ieee80211_rate *rate;
int i;
- hw = iwl4965_get_hw_mode(priv, priv->band);
+ hw = iwl_get_hw_mode(priv, priv->band);
if (!hw) {
IWL_ERROR("Failed to set rate: unable to get hw mode\n");
return;
@@ -2411,169 +853,6 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}
-void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
-{
- unsigned long flags;
-
- if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
- return;
-
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
- disable_radio ? "OFF" : "ON");
-
- if (disable_radio) {
- iwl4965_scan_cancel(priv);
- /* FIXME: This is a workaround for AP */
- if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
- CSR_UCODE_SW_BIT_RFKILL);
- spin_unlock_irqrestore(&priv->lock, flags);
- /* call the host command only if no hw rf-kill set */
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&
- iwl_is_ready(priv))
- iwl4965_send_card_state(priv,
- CARD_STATE_CMD_DISABLE,
- 0);
- set_bit(STATUS_RF_KILL_SW, &priv->status);
-
- /* make sure mac80211 stop sending Tx frame */
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
- }
- return;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* wake up ucode */
- msleep(10);
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl_read32(priv, CSR_UCODE_DRV_GP1);
- if (!iwl_grab_nic_access(priv))
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by HW switch\n");
- return;
- }
-
- queue_work(priv->workqueue, &priv->restart);
- return;
-}
-
-void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
- u32 decrypt_res, struct ieee80211_rx_status *stats)
-{
- u16 fc =
- le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
-
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
- return;
-
- if (!(fc & IEEE80211_FCTL_PROTECTED))
- return;
-
- IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
- switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
- case RX_RES_STATUS_SEC_TYPE_TKIP:
- /* The uCode has got a bad phase 1 Key, pushes the packet.
- * Decryption will be done in SW. */
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_BAD_KEY_TTAK)
- break;
-
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_BAD_ICV_MIC)
- stats->flag |= RX_FLAG_MMIC_ERROR;
- case RX_RES_STATUS_SEC_TYPE_WEP:
- case RX_RES_STATUS_SEC_TYPE_CCMP:
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_DECRYPT_OK) {
- IWL_DEBUG_RX("hw decrypt successfully!!!\n");
- stats->flag |= RX_FLAG_DECRYPTED;
- }
- break;
-
- default:
- break;
- }
-}
-
-
-#define IWL_PACKET_RETRY_TIME HZ
-
-int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
-{
- u16 sc = le16_to_cpu(header->seq_ctrl);
- u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
- u16 frag = sc & IEEE80211_SCTL_FRAG;
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
-
- switch (priv->iw_mode) {
- case IEEE80211_IF_TYPE_IBSS:{
- struct list_head *p;
- struct iwl4965_ibss_seq *entry = NULL;
- u8 *mac = header->addr2;
- int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
-
- __list_for_each(p, &priv->ibss_mac_hash[index]) {
- entry = list_entry(p, struct iwl4965_ibss_seq, list);
- if (!compare_ether_addr(entry->mac, mac))
- break;
- }
- if (p == &priv->ibss_mac_hash[index]) {
- entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry) {
- IWL_ERROR("Cannot malloc new mac entry\n");
- return 0;
- }
- memcpy(entry->mac, mac, ETH_ALEN);
- entry->seq_num = seq;
- entry->frag_num = frag;
- entry->packet_time = jiffies;
- list_add(&entry->list, &priv->ibss_mac_hash[index]);
- return 0;
- }
- last_seq = &entry->seq_num;
- last_frag = &entry->frag_num;
- last_time = &entry->packet_time;
- break;
- }
- case IEEE80211_IF_TYPE_STA:
- last_seq = &priv->last_seq_num;
- last_frag = &priv->last_frag_num;
- last_time = &priv->last_packet_time;
- break;
- default:
- return 0;
- }
- if ((*last_seq == seq) &&
- time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag)
- goto drop;
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- goto drop;
- } else
- *last_seq = seq;
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
- drop:
- return 1;
-}
-
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h"
@@ -2632,7 +911,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
u8 type)
{
struct iwl4965_spectrum_cmd spectrum;
- struct iwl4965_rx_packet *res;
+ struct iwl_rx_packet *res;
struct iwl_host_cmd cmd = {
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
.data = (void *)&spectrum,
@@ -2677,7 +956,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
if (rc)
return rc;
- res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
@@ -2707,352 +986,16 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
}
#endif
-static void iwl4965_txstatus_to_ieee(struct iwl_priv *priv,
- struct iwl4965_tx_info *tx_sta)
-{
-
- tx_sta->status.ack_signal = 0;
- tx_sta->status.excessive_retries = 0;
- tx_sta->status.queue_length = 0;
- tx_sta->status.queue_number = 0;
-
- if (in_interrupt())
- ieee80211_tx_status_irqsafe(priv->hw,
- tx_sta->skb[0], &(tx_sta->status));
- else
- ieee80211_tx_status(priv->hw,
- tx_sta->skb[0], &(tx_sta->status));
-
- tx_sta->skb[0] = NULL;
-}
-
-/**
- * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
- *
- * When FW advances 'R' index, all entries between old and new 'R' index
- * need to be reclaimed. As result, some free space forms. If there is
- * enough free space (> low mark), wake the stack that feeds us.
- */
-int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
-{
- struct iwl4965_tx_queue *txq = &priv->txq[txq_id];
- struct iwl4965_queue *q = &txq->q;
- int nfreed = 0;
-
- if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
- "is out of range [0-%d] %d %d.\n", txq_id,
- index, q->n_bd, q->write_ptr, q->read_ptr);
- return 0;
- }
-
- for (index = iwl_queue_inc_wrap(index, q->n_bd);
- q->read_ptr != index;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
- if (txq_id != IWL_CMD_QUEUE_NUM) {
- iwl4965_txstatus_to_ieee(priv,
- &(txq->txb[txq->q.read_ptr]));
- iwl4965_hw_txq_free_tfd(priv, txq);
- } else if (nfreed > 1) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
- q->write_ptr, q->read_ptr);
- queue_work(priv->workqueue, &priv->restart);
- }
- nfreed++;
- }
-
-/* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) &&
- (txq_id != IWL_CMD_QUEUE_NUM) &&
- priv->mac80211_registered)
- ieee80211_wake_queue(priv->hw, txq_id); */
-
-
- return nfreed;
-}
-
-static int iwl4965_is_tx_success(u32 status)
-{
- status &= TX_STATUS_MSK;
- return (status == TX_STATUS_SUCCESS)
- || (status == TX_STATUS_DIRECT_DONE);
-}
-
/******************************************************************************
*
* Generic RX handler implementations
*
******************************************************************************/
-#ifdef CONFIG_IWL4965_HT
-
-static inline int iwl4965_get_ra_sta_id(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr)
+static void iwl_rx_reply_alive(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- if (priv->iw_mode == IEEE80211_IF_TYPE_STA)
- return IWL_AP_ID;
- else {
- u8 *da = ieee80211_get_DA(hdr);
- return iwl4965_hw_find_station(priv, da);
- }
-}
-
-static struct ieee80211_hdr *iwl4965_tx_queue_get_hdr(
- struct iwl_priv *priv, int txq_id, int idx)
-{
- if (priv->txq[txq_id].txb[idx].skb[0])
- return (struct ieee80211_hdr *)priv->txq[txq_id].
- txb[idx].skb[0]->data;
- return NULL;
-}
-
-static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
-{
- __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
- tx_resp->frame_count);
- return le32_to_cpu(*scd_ssn) & MAX_SN;
-
-}
-
-/**
- * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue
- */
-static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
- struct iwl4965_ht_agg *agg,
- struct iwl4965_tx_resp_agg *tx_resp,
- u16 start_idx)
-{
- u16 status;
- struct agg_tx_status *frame_status = &tx_resp->status;
- struct ieee80211_tx_status *tx_status = NULL;
- struct ieee80211_hdr *hdr = NULL;
- int i, sh;
- int txq_id, idx;
- u16 seq;
-
- if (agg->wait_for_ba)
- IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
-
- agg->frame_count = tx_resp->frame_count;
- agg->start_idx = start_idx;
- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
- agg->bitmap = 0;
-
- /* # frames attempted by Tx command */
- if (agg->frame_count == 1) {
- /* Only one frame was attempted; no block-ack will arrive */
- status = le16_to_cpu(frame_status[0].status);
- seq = le16_to_cpu(frame_status[0].sequence);
- idx = SEQ_TO_INDEX(seq);
- txq_id = SEQ_TO_QUEUE(seq);
-
- /* FIXME: code repetition */
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
- agg->frame_count, agg->start_idx, idx);
-
- tx_status = &(priv->txq[txq_id].txb[idx].status);
- tx_status->retry_count = tx_resp->failure_frame;
- tx_status->queue_number = status & 0xff;
- tx_status->queue_length = tx_resp->failure_rts;
- tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU;
- tx_status->flags = iwl4965_is_tx_success(status)?
- IEEE80211_TX_STATUS_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv,
- le32_to_cpu(tx_resp->rate_n_flags),
- &tx_status->control);
- /* FIXME: code repetition end */
-
- IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
- status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
-
- agg->wait_for_ba = 0;
- } else {
- /* Two or more frames were attempted; expect block-ack */
- u64 bitmap = 0;
- int start = agg->start_idx;
-
- /* Construct bit-map of pending frames within Tx window */
- for (i = 0; i < agg->frame_count; i++) {
- u16 sc;
- status = le16_to_cpu(frame_status[i].status);
- seq = le16_to_cpu(frame_status[i].sequence);
- idx = SEQ_TO_INDEX(seq);
- txq_id = SEQ_TO_QUEUE(seq);
-
- if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
- AGG_TX_STATE_ABORT_MSK))
- continue;
-
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
- agg->frame_count, txq_id, idx);
-
- hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, idx);
-
- sc = le16_to_cpu(hdr->seq_ctrl);
- if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
- idx, SEQ_TO_SN(sc),
- hdr->seq_ctrl);
- return -1;
- }
-
- IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
- i, idx, SEQ_TO_SN(sc));
-
- sh = idx - start;
- if (sh > 64) {
- sh = (start - idx) + 0xff;
- bitmap = bitmap << sh;
- sh = 0;
- start = idx;
- } else if (sh < -64)
- sh = 0xff - (start - idx);
- else if (sh < 0) {
- sh = start - idx;
- start = idx;
- bitmap = bitmap << sh;
- sh = 0;
- }
- bitmap |= (1 << sh);
- IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
- start, (u32)(bitmap & 0xFFFFFFFF));
- }
-
- agg->bitmap = bitmap;
- agg->start_idx = start;
- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
- IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
- agg->frame_count, agg->start_idx,
- (unsigned long long)agg->bitmap);
-
- if (bitmap)
- agg->wait_for_ba = 1;
- }
- return 0;
-}
-#endif
-
-/**
- * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
- */
-static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- u16 sequence = le16_to_cpu(pkt->hdr.sequence);
- int txq_id = SEQ_TO_QUEUE(sequence);
- int index = SEQ_TO_INDEX(sequence);
- struct iwl4965_tx_queue *txq = &priv->txq[txq_id];
- struct ieee80211_tx_status *tx_status;
- struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
- u32 status = le32_to_cpu(tx_resp->status);
-#ifdef CONFIG_IWL4965_HT
- int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
- struct ieee80211_hdr *hdr;
- __le16 *qc;
-#endif
-
- if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
- "is out of range [0-%d] %d %d\n", txq_id,
- index, txq->q.n_bd, txq->q.write_ptr,
- txq->q.read_ptr);
- return;
- }
-
-#ifdef CONFIG_IWL4965_HT
- hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index);
- qc = ieee80211_get_qos_ctrl(hdr);
-
- if (qc)
- tid = le16_to_cpu(*qc) & 0xf;
-
- sta_id = iwl4965_get_ra_sta_id(priv, hdr);
- if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
- IWL_ERROR("Station not known\n");
- return;
- }
-
- if (txq->sched_retry) {
- const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
- struct iwl4965_ht_agg *agg = NULL;
-
- if (!qc)
- return;
-
- agg = &priv->stations[sta_id].tid[tid].agg;
-
- iwl4965_tx_status_reply_tx(priv, agg,
- (struct iwl4965_tx_resp_agg *)tx_resp, index);
-
- if ((tx_resp->frame_count == 1) &&
- !iwl4965_is_tx_success(status)) {
- /* TODO: send BAR */
- }
-
- if (txq->q.read_ptr != (scd_ssn & 0xff)) {
- int freed;
- index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
- IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
- "%d index %d\n", scd_ssn , index);
- freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
- priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
-
- if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
- txq_id >= 0 && priv->mac80211_registered &&
- agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
- ieee80211_wake_queue(priv->hw, txq_id);
-
- iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
- }
- } else {
-#endif /* CONFIG_IWL4965_HT */
- tx_status = &(txq->txb[txq->q.read_ptr].status);
-
- tx_status->retry_count = tx_resp->failure_frame;
- tx_status->queue_number = status;
- tx_status->queue_length = tx_resp->bt_kill_count;
- tx_status->queue_length |= tx_resp->failure_rts;
- tx_status->flags =
- iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
- &tx_status->control);
-
- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
- "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status),
- status, le32_to_cpu(tx_resp->rate_n_flags),
- tx_resp->failure_frame);
-
- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
- if (index != -1) {
-#ifdef CONFIG_IWL4965_HT
- int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
-
- if (tid != MAX_TID_COUNT)
- priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
- if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
- (txq_id >= 0) &&
- priv->mac80211_registered)
- ieee80211_wake_queue(priv->hw, txq_id);
- if (tid != MAX_TID_COUNT)
- iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
-#endif
- }
-#ifdef CONFIG_IWL4965_HT
- }
-#endif /* CONFIG_IWL4965_HT */
-
- if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
-}
-
-
-static void iwl4965_rx_reply_alive(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_alive_resp *palive;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_alive_resp *palive;
struct delayed_work *pwork;
palive = &pkt->u.alive_frame;
@@ -3066,12 +1009,12 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv,
IWL_DEBUG_INFO("Initialization Alive received.\n");
memcpy(&priv->card_alive_init,
&pkt->u.alive_frame,
- sizeof(struct iwl4965_init_alive_resp));
+ sizeof(struct iwl_init_alive_resp));
pwork = &priv->init_alive_start;
} else {
IWL_DEBUG_INFO("Runtime Alive received.\n");
memcpy(&priv->card_alive, &pkt->u.alive_frame,
- sizeof(struct iwl4965_alive_resp));
+ sizeof(struct iwl_alive_resp));
pwork = &priv->alive_start;
}
@@ -3084,19 +1027,10 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv,
IWL_WARNING("uCode did not respond OK.\n");
}
-static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
-
- IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
- return;
-}
-
static void iwl4965_rx_reply_error(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
"seq 0x%04X ser 0x%08X\n",
@@ -3109,10 +1043,10 @@ static void iwl4965_rx_reply_error(struct iwl_priv *priv,
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb)
+static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif);
IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
@@ -3121,15 +1055,15 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *
}
static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
if (!report->state) {
- IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
- "Spectrum Measure Notification: Start\n");
+ IWL_DEBUG(IWL_DL_11H,
+ "Spectrum Measure Notification: Start\n");
return;
}
@@ -3139,10 +1073,10 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
}
static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_DEBUG
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif);
IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
sleep->pm_sleep_mode, sleep->pm_wakeup_src);
@@ -3150,13 +1084,13 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv,
}
static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
"notification for %s:\n",
le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
}
static void iwl4965_bg_beacon_update(struct work_struct *work)
@@ -3166,7 +1100,7 @@ static void iwl4965_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
- beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
+ beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
IWL_ERROR("update beacon failed\n");
@@ -3184,17 +1118,37 @@ static void iwl4965_bg_beacon_update(struct work_struct *work)
iwl4965_send_beacon_cmd(priv);
}
+/**
+ * iwl4965_bg_statistics_periodic - Timer callback to queue statistics
+ *
+ * This callback is provided in order to send a statistics request.
+ *
+ * This timer function is continually reset to execute within
+ * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
+ * was received. We need to ensure we receive the statistics in order
+ * to update the temperature used for calibrating the TXPOWER.
+ */
+static void iwl4965_bg_statistics_periodic(unsigned long data)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)data;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ iwl_send_statistics_request(priv, CMD_ASYNC);
+}
+
static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
+ struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_DEBUG
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status);
- u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
+ u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
IWL_DEBUG_RX("beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
- le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
+ le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame,
le32_to_cpu(beacon->ibss_mgr_status),
le32_to_cpu(beacon->high_tsf),
@@ -3206,129 +1160,12 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
queue_work(priv->workqueue, &priv->beacon_update);
}
-/* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl4965_rx_reply_scan(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWLWIFI_DEBUG
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_scanreq_notification *notif =
- (struct iwl4965_scanreq_notification *)pkt->u.raw;
-
- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
-#endif
-}
-
-/* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_scanstart_notification *notif =
- (struct iwl4965_scanstart_notification *)pkt->u.raw;
- priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
- IWL_DEBUG_SCAN("Scan start: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- notif->tsf_high,
- notif->tsf_low, notif->status, notif->beacon_timer);
-}
-
-/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_scanresults_notification *notif =
- (struct iwl4965_scanresults_notification *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan ch.res: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d "
- "elapsed=%lu usec (%dms since last)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- le32_to_cpu(notif->tsf_high),
- le32_to_cpu(notif->tsf_low),
- le32_to_cpu(notif->statistics[0]),
- le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
- jiffies_to_msecs(elapsed_jiffies
- (priv->last_scan_jiffies, jiffies)));
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
-}
-
-/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
- scan_notif->scanned_channels,
- scan_notif->tsf_low,
- scan_notif->tsf_high, scan_notif->status);
-
- /* The HW is no longer scanning */
- clear_bit(STATUS_SCAN_HW, &priv->status);
-
- /* The scan completion notification came in, so kill that timer... */
- cancel_delayed_work(&priv->scan_check);
-
- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
- (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
- "2.4" : "5.2",
- jiffies_to_msecs(elapsed_jiffies
- (priv->scan_pass_start, jiffies)));
-
- /* Remove this scanned band from the list of pending
- * bands to scan, band G precedes A in order of scanning
- * as seen in iwl_bg_request_scan */
- if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
- priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
- else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
- priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
-
- /* If a request to abort was given, or the scan did not succeed
- * then we reset the scan state machine and terminate,
- * re-queuing another scan if one has been requested */
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_INFO("Aborted scan completed.\n");
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- } else {
- /* If there are more bands on this scan pass reschedule */
- if (priv->scan_bands)
- goto reschedule;
- }
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
- IWL_DEBUG_INFO("Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
- IWL_DEBUG_INFO("Scan took %dms\n",
- jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
-
- queue_work(priv->workqueue, &priv->scan_completed);
-
- return;
-
-reschedule:
- priv->scan_pass_start = jiffies;
- queue_work(priv->workqueue, &priv->request_scan);
-}
-
/* Handle notification from uCode that card's power state is changing
* due to software, hardware, or critical temperature RFKILL */
static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
@@ -3383,7 +1220,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
clear_bit(STATUS_RF_KILL_SW, &priv->status);
if (!(flags & RXON_CARD_DISABLED))
- iwl4965_scan_cancel(priv);
+ iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -3403,10 +1240,9 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
* This function chains into the hardware specific files for them to setup
* any hardware specific handlers as well.
*/
-static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
+static void iwl_setup_rx_handlers(struct iwl_priv *priv)
{
- priv->rx_handlers[REPLY_ALIVE] = iwl4965_rx_reply_alive;
- priv->rx_handlers[REPLY_ADD_STA] = iwl4965_rx_reply_add_sta;
+ priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error;
priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl4965_rx_csa;
priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
@@ -3421,500 +1257,47 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
* statistics request from the host as well as for the periodic
* statistics notifications (after received beacons) from the uCode.
*/
- priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics;
- priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics;
-
- priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan;
- priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif;
- priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
- iwl4965_rx_scan_results_notif;
- priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
- iwl4965_rx_scan_complete_notif;
- priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;
- priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
-
- /* Set up hardware specific Rx handlers */
- iwl4965_hw_rx_handler_setup(priv);
-}
-
-/**
- * iwl4965_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
- * @rxb: Rx buffer to reclaim
- *
- * If an Rx buffer has an async callback associated with it the callback
- * will be executed. The attached skb (if present) will only be freed
- * if the callback returns 1
- */
-static void iwl4965_tx_cmd_complete(struct iwl_priv *priv,
- struct iwl4965_rx_mem_buffer *rxb)
-{
- struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data;
- u16 sequence = le16_to_cpu(pkt->hdr.sequence);
- int txq_id = SEQ_TO_QUEUE(sequence);
- int index = SEQ_TO_INDEX(sequence);
- int huge = sequence & SEQ_HUGE_FRAME;
- int cmd_index;
- struct iwl_cmd *cmd;
-
- /* If a Tx command is being handled and it isn't in the actual
- * command queue then there a command routing bug has been introduced
- * in the queue management code. */
- if (txq_id != IWL_CMD_QUEUE_NUM)
- IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
- txq_id, pkt->hdr.cmd);
- BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
-
- cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
- cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-
- /* Input error checking is done when commands are added to queue. */
- if (cmd->meta.flags & CMD_WANT_SKB) {
- cmd->meta.source->u.skb = rxb->skb;
- rxb->skb = NULL;
- } else if (cmd->meta.u.callback &&
- !cmd->meta.u.callback(priv, cmd, rxb->skb))
- rxb->skb = NULL;
-
- iwl4965_tx_queue_reclaim(priv, txq_id, index);
-
- if (!(cmd->meta.flags & CMD_ASYNC)) {
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- wake_up_interruptible(&priv->wait_command_queue);
- }
-}
-
-/************************** RX-FUNCTIONS ****************************/
-/*
- * Rx theory of operation
- *
- * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs),
- * each of which point to Receive Buffers to be filled by 4965. These get
- * used not only for Rx frames, but for any command response or notification
- * from the 4965. The driver and 4965 manage the Rx buffers by means
- * of indexes into the circular buffer.
- *
- * Rx Queue Indexes
- * The host/firmware share two index registers for managing the Rx buffers.
- *
- * The READ index maps to the first position that the firmware may be writing
- * to -- the driver can read up to (but not including) this position and get
- * good data.
- * The READ index is managed by the firmware once the card is enabled.
- *
- * The WRITE index maps to the last position the driver has read from -- the
- * position preceding WRITE is the last slot the firmware can place a packet.
- *
- * The queue is empty (no good data) if WRITE = READ - 1, and is full if
- * WRITE = READ.
- *
- * During initialization, the host sets up the READ queue position to the first
- * INDEX position, and WRITE to the last (READ - 1 wrapped)
- *
- * When the firmware places a packet in a buffer, it will advance the READ index
- * and fire the RX interrupt. The driver can then query the READ index and
- * process as many packets as possible, moving the WRITE index forward as it
- * resets the Rx queue buffers with new memory.
- *
- * The management in the driver is as follows:
- * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When
- * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
- * to replenish the iwl->rxq->rx_free.
- * + In iwl4965_rx_replenish (scheduled) if 'processed' != 'read' then the
- * iwl->rxq is replenished and the READ INDEX is updated (updating the
- * 'processed' and 'read' driver indexes as well)
- * + A received packet is processed and handed to the kernel network stack,
- * detached from the iwl->rxq. The driver 'processed' index is updated.
- * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free
- * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ
- * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there
- * were enough free buffers and RX_STALLED is set it is cleared.
- *
- *
- * Driver sequence:
- *
- * iwl4965_rx_queue_alloc() Allocates rx_free
- * iwl4965_rx_replenish() Replenishes rx_free list from rx_used, and calls
- * iwl4965_rx_queue_restock
- * iwl4965_rx_queue_restock() Moves available buffers from rx_free into Rx
- * queue, updates firmware pointers, and updates
- * the WRITE index. If insufficient rx_free buffers
- * are available, schedules iwl4965_rx_replenish
- *
- * -- enable interrupts --
- * ISR - iwl4965_rx() Detach iwl4965_rx_mem_buffers from pool up to the
- * READ INDEX, detaching the SKB from the pool.
- * Moves the packet buffer from queue to rx_used.
- * Calls iwl4965_rx_queue_restock to refill any empty
- * slots.
- * ...
- *
- */
-
-/**
- * iwl4965_rx_queue_space - Return number of free slots available in queue.
- */
-static int iwl4965_rx_queue_space(const struct iwl4965_rx_queue *q)
-{
- int s = q->read - q->write;
- if (s <= 0)
- s += RX_QUEUE_SIZE;
- /* keep some buffer to not confuse full and empty queue */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-/**
- * iwl4965_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- */
-int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl4965_rx_queue *q)
-{
- u32 reg = 0;
- int rc = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if (q->need_update == 0)
- goto exit_unlock;
-
- /* If power-saving is in use, make sure device is awake */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- iwl_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- goto exit_unlock;
- }
-
- rc = iwl_grab_nic_access(priv);
- if (rc)
- goto exit_unlock;
-
- /* Device expects a multiple of 8 */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
- iwl_release_nic_access(priv);
-
- /* Else device is assumed to be awake */
- } else
- /* Device expects a multiple of 8 */
- iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
+ priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
+ priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
+ iwl_setup_rx_scan_handlers(priv);
- q->need_update = 0;
-
- exit_unlock:
- spin_unlock_irqrestore(&q->lock, flags);
- return rc;
-}
-
-/**
- * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
- */
-static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl_priv *priv,
- dma_addr_t dma_addr)
-{
- return cpu_to_le32((u32)(dma_addr >> 8));
-}
-
-
-/**
- * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool
- *
- * If there are slots in the RX queue that need to be restocked,
- * and we have free pre-allocated buffers, fill the ranks as much
- * as we can, pulling from rx_free.
- *
- * This moves the 'write' index forward to catch up with 'processed', and
- * also updates the memory address in the firmware to reference the new
- * target buffer.
- */
-static int iwl4965_rx_queue_restock(struct iwl_priv *priv)
-{
- struct iwl4965_rx_queue *rxq = &priv->rxq;
- struct list_head *element;
- struct iwl4965_rx_mem_buffer *rxb;
- unsigned long flags;
- int write, rc;
-
- spin_lock_irqsave(&rxq->lock, flags);
- write = rxq->write & ~0x7;
- while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
- /* Get next free Rx buffer, remove from free list */
- element = rxq->rx_free.next;
- rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list);
- list_del(element);
-
- /* Point to Rx buffer via next RBD in circular buffer */
- rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr);
- rxq->queue[rxq->write] = rxb;
- rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
- rxq->free_count--;
- }
- spin_unlock_irqrestore(&rxq->lock, flags);
- /* If the pre-allocated buffer pool is dropping low, schedule to
- * refill it */
- if (rxq->free_count <= RX_LOW_WATERMARK)
- queue_work(priv->workqueue, &priv->rx_replenish);
-
-
- /* If we've added more space for the firmware to place data, tell it.
- * Increment device's write pointer in multiples of 8. */
- if ((write != (rxq->write & ~0x7))
- || (abs(rxq->write - rxq->read) > 7)) {
- spin_lock_irqsave(&rxq->lock, flags);
- rxq->need_update = 1;
- spin_unlock_irqrestore(&rxq->lock, flags);
- rc = iwl4965_rx_queue_update_write_ptr(priv, rxq);
- if (rc)
- return rc;
- }
-
- return 0;
-}
-
-/**
- * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free
- *
- * When moving to rx_free an SKB is allocated for the slot.
- *
- * Also restock the Rx queue via iwl4965_rx_queue_restock.
- * This is called as a scheduled work item (except for during initialization)
- */
-static void iwl4965_rx_allocate(struct iwl_priv *priv)
-{
- struct iwl4965_rx_queue *rxq = &priv->rxq;
- struct list_head *element;
- struct iwl4965_rx_mem_buffer *rxb;
- unsigned long flags;
- spin_lock_irqsave(&rxq->lock, flags);
- while (!list_empty(&rxq->rx_used)) {
- element = rxq->rx_used.next;
- rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list);
-
- /* Alloc a new receive buffer */
- rxb->skb =
- alloc_skb(priv->hw_params.rx_buf_size,
- __GFP_NOWARN | GFP_ATOMIC);
- if (!rxb->skb) {
- if (net_ratelimit())
- printk(KERN_CRIT DRV_NAME
- ": Can not allocate SKB buffers\n");
- /* We don't reschedule replenish work here -- we will
- * call the restock method and if it still needs
- * more buffers it will schedule replenish */
- break;
- }
- priv->alloc_rxb_skb++;
- list_del(element);
+ /* status change handler */
+ priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;
- /* Get physical address of RB/SKB */
- rxb->dma_addr =
- pci_map_single(priv->pci_dev, rxb->skb->data,
- priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE);
- list_add_tail(&rxb->list, &rxq->rx_free);
- rxq->free_count++;
- }
- spin_unlock_irqrestore(&rxq->lock, flags);
+ priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
+ iwl_rx_missed_beacon_notif;
+ /* Rx handlers */
+ priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
+ priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
+ /* block ack */
+ priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl_rx_reply_compressed_ba;
+ /* Set up hardware specific Rx handlers */
+ priv->cfg->ops->lib->rx_handler_setup(priv);
}
/*
* this should be called while priv->lock is locked
*/
-static void __iwl4965_rx_replenish(void *data)
+static void __iwl_rx_replenish(struct iwl_priv *priv)
{
- struct iwl_priv *priv = data;
-
- iwl4965_rx_allocate(priv);
- iwl4965_rx_queue_restock(priv);
+ iwl_rx_allocate(priv);
+ iwl_rx_queue_restock(priv);
}
-void iwl4965_rx_replenish(void *data)
-{
- struct iwl_priv *priv = data;
- unsigned long flags;
-
- iwl4965_rx_allocate(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl4965_rx_queue_restock(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have its SKB set to NULL
- * This free routine walks the list of POOL entries and if SKB is set to
- * non NULL it is unmapped and freed
- */
-static void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq)
-{
- int i;
- for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- priv->hw_params.rx_buf_size,
- PCI_DMA_FROMDEVICE);
- dev_kfree_skb(rxq->pool[i].skb);
- }
- }
-
- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
- rxq->dma_addr);
- rxq->bd = NULL;
-}
-
-int iwl4965_rx_queue_alloc(struct iwl_priv *priv)
-{
- struct iwl4965_rx_queue *rxq = &priv->rxq;
- struct pci_dev *dev = priv->pci_dev;
- int i;
-
- spin_lock_init(&rxq->lock);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
-
- /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
- rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
- if (!rxq->bd)
- return -ENOMEM;
-
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- rxq->need_update = 0;
- return 0;
-}
-
-void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq)
-{
- unsigned long flags;
- int i;
- spin_lock_irqsave(&rxq->lock, flags);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
- /* In the reset function, these buffers may have been allocated
- * to an SKB, so we need to unmap and free potential storage */
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- priv->hw_params.rx_buf_size,
- PCI_DMA_FROMDEVICE);
- priv->alloc_rxb_skb--;
- dev_kfree_skb(rxq->pool[i].skb);
- rxq->pool[i].skb = NULL;
- }
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
- }
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- spin_unlock_irqrestore(&rxq->lock, flags);
-}
-
-/* Convert linear signal-to-noise ratio into dB */
-static u8 ratio2dB[100] = {
-/* 0 1 2 3 4 5 6 7 8 9 */
- 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */
- 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */
- 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */
- 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */
- 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */
- 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */
- 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */
- 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */
- 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */
- 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */
-};
-
-/* Calculates a relative dB value from a ratio of linear
- * (i.e. not dB) signal levels.
- * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
-int iwl4965_calc_db_from_ratio(int sig_ratio)
-{
- /* 1000:1 or higher just report as 60 dB */
- if (sig_ratio >= 1000)
- return 60;
-
- /* 100:1 or higher, divide by 10 and use table,
- * add 20 dB to make up for divide by 10 */
- if (sig_ratio >= 100)
- return (20 + (int)ratio2dB[sig_ratio/10]);
-
- /* We shouldn't see this */
- if (sig_ratio < 1)
- return 0;
-
- /* Use table for ratios 1:1 - 99:1 */
- return (int)ratio2dB[sig_ratio];
-}
-
-#define PERFECT_RSSI (-20) /* dBm */
-#define WORST_RSSI (-95) /* dBm */
-#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
-
-/* Calculate an indication of rx signal quality (a percentage, not dBm!).
- * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
- * about formulas used below. */
-int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm)
-{
- int sig_qual;
- int degradation = PERFECT_RSSI - rssi_dbm;
-
- /* If we get a noise measurement, use signal-to-noise ratio (SNR)
- * as indicator; formula is (signal dbm - noise dbm).
- * SNR at or above 40 is a great signal (100%).
- * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
- * Weakest usable signal is usually 10 - 15 dB SNR. */
- if (noise_dbm) {
- if (rssi_dbm - noise_dbm >= 40)
- return 100;
- else if (rssi_dbm < noise_dbm)
- return 0;
- sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
-
- /* Else use just the signal level.
- * This formula is a least squares fit of data points collected and
- * compared with a reference system that had a percentage (%) display
- * for signal quality. */
- } else
- sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
- (15 * RSSI_RANGE + 62 * degradation)) /
- (RSSI_RANGE * RSSI_RANGE);
-
- if (sig_qual > 100)
- sig_qual = 100;
- else if (sig_qual < 1)
- sig_qual = 0;
-
- return sig_qual;
-}
-
/**
- * iwl4965_rx_handle - Main entry function for receiving responses from uCode
+ * iwl_rx_handle - Main entry function for receiving responses from uCode
*
* Uses the priv->rx_handlers callback function array to invoke
* the appropriate handlers, including command responses,
* frame-received notifications, and other notifications.
*/
-static void iwl4965_rx_handle(struct iwl_priv *priv)
+void iwl_rx_handle(struct iwl_priv *priv)
{
- struct iwl4965_rx_mem_buffer *rxb;
- struct iwl4965_rx_packet *pkt;
- struct iwl4965_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_mem_buffer *rxb;
+ struct iwl_rx_packet *pkt;
+ struct iwl_rx_queue *rxq = &priv->rxq;
u32 r, i;
int reclaim;
unsigned long flags;
@@ -3923,14 +1306,14 @@ static void iwl4965_rx_handle(struct iwl_priv *priv)
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
- r = iwl4965_hw_get_rx_read(priv);
+ r = priv->cfg->ops->lib->shared_mem_rx_idx(priv);
i = rxq->read;
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
- IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
+ IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i);
- if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
while (i != r) {
@@ -3946,7 +1329,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv)
pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
- pkt = (struct iwl4965_rx_packet *)rxb->skb->data;
+ pkt = (struct iwl_rx_packet *)rxb->skb->data;
/* Reclaim a command buffer only if this packet is a response
* to a (driver-originated) command.
@@ -3965,13 +1348,12 @@ static void iwl4965_rx_handle(struct iwl_priv *priv)
* handle those that need handling via function in
* rx_handlers table. See iwl4965_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
- "r = %d, i = %d, %s, 0x%02x\n", r, i,
- get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+ IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r,
+ i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(IWL_DL_RX,
"r %d i %d No handler needed for %s, 0x%02x\n",
r, i, get_cmd_string(pkt->hdr.cmd),
pkt->hdr.cmd);
@@ -3982,7 +1364,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv)
* fire off the (possibly) blocking iwl_send_cmd()
* as we reclaim the driver command queue */
if (rxb && rxb->skb)
- iwl4965_tx_cmd_complete(priv, rxb);
+ iwl_tx_cmd_complete(priv, rxb);
else
IWL_WARNING("Claim null rxb?\n");
}
@@ -4009,7 +1391,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv)
count++;
if (count >= 8) {
priv->rxq.read = i;
- __iwl4965_rx_replenish(priv);
+ __iwl_rx_replenish(priv);
count = 0;
}
}
@@ -4017,62 +1399,17 @@ static void iwl4965_rx_handle(struct iwl_priv *priv)
/* Backtrack one entry */
priv->rxq.read = i;
- iwl4965_rx_queue_restock(priv);
-}
-
-/**
- * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware
- */
-static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq)
-{
- u32 reg = 0;
- int rc = 0;
- int txq_id = txq->q.id;
-
- if (txq->need_update == 0)
- return rc;
-
- /* if we're trying to save power */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- /* wake up nic if it's powered down ...
- * uCode will wake up, and interrupt us again, so next
- * time we'll skip this part. */
- reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
- iwl_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- return rc;
- }
-
- /* restore this queue's parameters in nic hardware. */
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
- iwl_write_direct32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
- iwl_release_nic_access(priv);
-
- /* else not in power-save mode, uCode will never sleep when we're
- * trying to tx (during RFKILL, we're not trying to tx). */
- } else
- iwl_write32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
-
- txq->need_update = 0;
-
- return rc;
+ iwl_rx_queue_restock(priv);
}
#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl4965_print_rx_config_cmd(struct iwl4965_rxon_cmd *rxon)
+static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv)
{
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
DECLARE_MAC_BUF(mac);
IWL_DEBUG_RADIO("RX CONFIG:\n");
- iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
@@ -4118,173 +1455,6 @@ static inline void iwl4965_disable_interrupts(struct iwl_priv *priv)
IWL_DEBUG_ISR("Disabled interrupts\n");
}
-static const char *desc_lookup(int i)
-{
- switch (i) {
- case 1:
- return "FAIL";
- case 2:
- return "BAD_PARAM";
- case 3:
- return "BAD_CHECKSUM";
- case 4:
- return "NMI_INTERRUPT";
- case 5:
- return "SYSASSERT";
- case 6:
- return "FATAL_ERROR";
- }
-
- return "UNKNOWN";
-}
-
-#define ERROR_START_OFFSET (1 * sizeof(u32))
-#define ERROR_ELEM_SIZE (7 * sizeof(u32))
-
-static void iwl4965_dump_nic_error_log(struct iwl_priv *priv)
-{
- u32 data2, line;
- u32 desc, time, count, base, data1;
- u32 blink1, blink2, ilink1, ilink2;
- int rc;
-
- base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
-
- if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
- return;
- }
-
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
- return;
- }
-
- count = iwl_read_targ_mem(priv, base);
-
- if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
- }
-
- desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
- blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
- blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
- ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
- ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
- data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
- data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
- line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
- time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
-
- IWL_ERROR("Desc Time "
- "data1 data2 line\n");
- IWL_ERROR("%-13s (#%d) %010u 0x%08X 0x%08X %u\n",
- desc_lookup(desc), desc, time, data1, data2, line);
- IWL_ERROR("blink1 blink2 ilink1 ilink2\n");
- IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
- ilink1, ilink2);
-
- iwl_release_nic_access(priv);
-}
-
-#define EVENT_START_OFFSET (4 * sizeof(u32))
-
-/**
- * iwl4965_print_event_log - Dump error event log to syslog
- *
- * NOTE: Must be called with iwl_grab_nic_access() already obtained!
- */
-static void iwl4965_print_event_log(struct iwl_priv *priv, u32 start_idx,
- u32 num_events, u32 mode)
-{
- u32 i;
- u32 base; /* SRAM byte address of event log header */
- u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
- u32 ptr; /* SRAM byte address of log data */
- u32 ev, time, data; /* event log data */
-
- if (num_events == 0)
- return;
-
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-
- if (mode == 0)
- event_size = 2 * sizeof(u32);
- else
- event_size = 3 * sizeof(u32);
-
- ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
-
- /* "time" is actually "data" for mode 0 (no timestamp).
- * place event id # at far right for easier visual parsing. */
- for (i = 0; i < num_events; i++) {
- ev = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
- time = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
- if (mode == 0)
- IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
- else {
- data = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
- IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
- }
- }
-}
-
-static void iwl4965_dump_nic_event_log(struct iwl_priv *priv)
-{
- int rc;
- u32 base; /* SRAM byte address of event log header */
- u32 capacity; /* event log capacity in # entries */
- u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
- u32 num_wraps; /* # times uCode wrapped to top of log */
- u32 next_entry; /* index of next entry to be written by uCode */
- u32 size; /* # entries that we'll print */
-
- base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
- if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
- return;
- }
-
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
- return;
- }
-
- /* event log header */
- capacity = iwl_read_targ_mem(priv, base);
- mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
- num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
- next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
-
- size = num_wraps ? capacity : next_entry;
-
- /* bail out if nothing in log */
- if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
- iwl_release_nic_access(priv);
- return;
- }
-
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
- size, num_wraps);
-
- /* if uCode has wrapped back to top of log, start at the oldest entry,
- * i.e the next one that uCode would fill. */
- if (num_wraps)
- iwl4965_print_event_log(priv, next_entry,
- capacity - next_entry, mode);
-
- /* (then/else) start at top of log */
- iwl4965_print_event_log(priv, 0, next_entry, mode);
-
- iwl_release_nic_access(priv);
-}
/**
* iwl4965_irq_handle_error - called for HW or SW error interrupt from card
@@ -4298,10 +1468,10 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv)
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_debug_level & IWL_DL_FW_ERRORS) {
- iwl4965_dump_nic_error_log(priv);
- iwl4965_dump_nic_event_log(priv);
- iwl4965_print_rx_config_cmd(&priv->staging_rxon);
+ if (priv->debug_level & IWL_DL_FW_ERRORS) {
+ iwl_dump_nic_error_log(priv);
+ iwl_dump_nic_event_log(priv);
+ iwl4965_print_rx_config_cmd(priv);
}
#endif
@@ -4312,7 +1482,7 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv)
clear_bit(STATUS_READY, &priv->status);
if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
+ IWL_DEBUG(IWL_DL_FW_ERRORS,
"Restarting adapter due to uCode error.\n");
if (iwl_is_associated(priv)) {
@@ -4320,7 +1490,8 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv)
sizeof(priv->recovery_rxon));
priv->error_recovering = 1;
}
- queue_work(priv->workqueue, &priv->restart);
+ if (priv->cfg->mod_params->restart_fw)
+ queue_work(priv->workqueue, &priv->restart);
}
}
@@ -4333,7 +1504,7 @@ static void iwl4965_error_recovery(struct iwl_priv *priv)
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
- iwl4965_rxon_add_station(priv, priv->bssid, 1);
+ iwl_rxon_add_station(priv, priv->bssid, 1);
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
@@ -4365,7 +1536,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_debug_level & IWL_DL_ISR) {
+ if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
inta_mask = iwl_read32(priv, CSR_INT_MASK);
IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -4399,7 +1570,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
}
#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_debug_level & (IWL_DL_ISR)) {
+ if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
if (inta & CSR_INT_BIT_SCD)
IWL_DEBUG_ISR("Scheduler finished to transmit "
@@ -4420,18 +1591,15 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
hw_rf_kill = 1;
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR,
- "RF_KILL bit toggled to %s.\n",
+ IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio":"enable radio");
- /* Queue restart only if RF_KILL switch was set to "kill"
- * when we loaded driver, and is now set to "enable".
- * After we're Alive, RF_KILL gets handled by
- * iwl4965_rx_card_state_notif() */
- if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
+ /* driver only loads ucode once setting the interface up.
+ * the driver as well won't allow loading if RFKILL is set
+ * therefore no need to restart the driver from this handler
+ */
+ if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status))
clear_bit(STATUS_RF_KILL_HW, &priv->status);
- queue_work(priv->workqueue, &priv->restart);
- }
handled |= CSR_INT_BIT_RF_KILL;
}
@@ -4453,13 +1621,13 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
/* uCode wakes up after power-down sleep */
if (inta & CSR_INT_BIT_WAKEUP) {
IWL_DEBUG_ISR("Wakeup interrupt\n");
- iwl4965_rx_queue_update_write_ptr(priv, &priv->rxq);
- iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]);
- iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]);
- iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]);
- iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[3]);
- iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[4]);
- iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+ iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+ iwl_txq_update_write_ptr(priv, &priv->txq[0]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[1]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[2]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[3]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[4]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[5]);
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -4468,13 +1636,16 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
* Rx "responses" (frame-received notification), and other
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
- iwl4965_rx_handle(priv);
+ iwl_rx_handle(priv);
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR("Tx interrupt\n");
handled |= CSR_INT_BIT_FH_TX;
+ /* FH finished to write, send event */
+ priv->ucode_write_complete = 1;
+ wake_up_interruptible(&priv->wait_command_queue);
}
if (inta & ~handled)
@@ -4492,7 +1663,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
iwl4965_enable_interrupts(priv);
#ifdef CONFIG_IWLWIFI_DEBUG
- if (iwl_debug_level & (IWL_DL_ISR)) {
+ if (priv->debug_level & (IWL_DL_ISR)) {
inta = iwl_read32(priv, CSR_INT);
inta_mask = iwl_read32(priv, CSR_INT_MASK);
inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
@@ -4561,297 +1732,6 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
return IRQ_NONE;
}
-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
- * sending probe req. This should be set long enough to hear probe responses
- * from more than one AP. */
-#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52 (10)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
-#define IWL_PASSIVE_DWELL_BASE (100)
-#define IWL_CHANNEL_TUNE_TIME 5
-
-static inline u16 iwl4965_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52;
- else
- return IWL_ACTIVE_DWELL_TIME_24;
-}
-
-static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- u16 active = iwl4965_get_active_dwell_time(priv, band);
- u16 passive = (band != IEEE80211_BAND_5GHZ) ?
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
- if (iwl_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = priv->beacon_int;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- }
-
- if (passive <= active)
- passive = active + 1;
-
- return passive;
-}
-
-static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 is_active, u8 direct_mask,
- struct iwl4965_scan_channel *scan_ch)
-{
- const struct ieee80211_channel *channels = NULL;
- const struct ieee80211_supported_band *sband;
- const struct iwl_channel_info *ch_info;
- u16 passive_dwell = 0;
- u16 active_dwell = 0;
- int added, i;
-
- sband = iwl4965_get_hw_mode(priv, band);
- if (!sband)
- return 0;
-
- channels = sband->channels;
-
- active_dwell = iwl4965_get_active_dwell_time(priv, band);
- passive_dwell = iwl4965_get_passive_dwell_time(priv, band);
-
- for (i = 0, added = 0; i < sband->n_channels; i++) {
- if (channels[i].flags & IEEE80211_CHAN_DISABLED)
- continue;
-
- scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq);
-
- ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
- scan_ch->channel);
- continue;
- }
-
- if (!is_active || is_channel_passive(ch_info) ||
- (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
- scan_ch->type = 0; /* passive */
- else
- scan_ch->type = 1; /* active */
-
- if (scan_ch->type & 1)
- scan_ch->type |= (direct_mask << 1);
-
- if (is_channel_narrow(ch_info))
- scan_ch->type |= (1 << 7);
-
- scan_ch->active_dwell = cpu_to_le16(active_dwell);
- scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-
- /* Set txpower levels to defaults */
- scan_ch->tpc.dsp_atten = 110;
- /* scan_pwr_info->tpc.dsp_atten; */
-
- /*scan_pwr_info->tpc.tx_gain; */
- if (band == IEEE80211_BAND_5GHZ)
- scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
- else {
- scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
- /* NOTE: if we were doing 6Mb OFDM for scans we'd use
- * power level:
- * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;
- */
- }
-
- IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",
- scan_ch->channel,
- (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",
- (scan_ch->type & 1) ?
- active_dwell : passive_dwell);
-
- scan_ch++;
- added++;
- }
-
- IWL_DEBUG_SCAN("total channels to scan %d \n", added);
- return added;
-}
-
-static void iwl4965_init_hw_rates(struct iwl_priv *priv,
- struct ieee80211_rate *rates)
-{
- int i;
-
- for (i = 0; i < IWL_RATE_COUNT; i++) {
- rates[i].bitrate = iwl4965_rates[i].ieee * 5;
- rates[i].hw_value = i; /* Rate scaling will work on indexes */
- rates[i].hw_value_short = i;
- rates[i].flags = 0;
- if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
- /*
- * If CCK != 1M then set short preamble rate flag.
- */
- rates[i].flags |=
- (iwl4965_rates[i].plcp == IWL_RATE_1M_PLCP) ?
- 0 : IEEE80211_RATE_SHORT_PREAMBLE;
- }
- }
-}
-
-/**
- * iwl4965_init_geos - Initialize mac80211's geo/channel info based from eeprom
- */
-int iwl4965_init_geos(struct iwl_priv *priv)
-{
- struct iwl_channel_info *ch;
- struct ieee80211_supported_band *sband;
- struct ieee80211_channel *channels;
- struct ieee80211_channel *geo_ch;
- struct ieee80211_rate *rates;
- int i = 0;
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
- priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
- return 0;
- }
-
- channels = kzalloc(sizeof(struct ieee80211_channel) *
- priv->channel_count, GFP_KERNEL);
- if (!channels)
- return -ENOMEM;
-
- rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
- GFP_KERNEL);
- if (!rates) {
- kfree(channels);
- return -ENOMEM;
- }
-
- /* 5.2GHz channels start after the 2.4GHz channels */
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
- /* just OFDM */
- sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
- sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
-
- iwl4965_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_5GHZ);
-
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
- sband->channels = channels;
- /* OFDM & CCK */
- sband->bitrates = rates;
- sband->n_bitrates = IWL_RATE_COUNT;
-
- iwl4965_init_ht_hw_capab(priv, &sband->ht_info, IEEE80211_BAND_2GHZ);
-
- priv->ieee_channels = channels;
- priv->ieee_rates = rates;
-
- iwl4965_init_hw_rates(priv, rates);
-
- for (i = 0; i < priv->channel_count; i++) {
- ch = &priv->channel_info[i];
-
- /* FIXME: might be removed if scan is OK */
- if (!is_channel_valid(ch))
- continue;
-
- if (is_channel_a_band(ch))
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- else
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
-
- geo_ch = &sband->channels[sband->n_channels++];
-
- geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
- geo_ch->max_power = ch->max_power_avg;
- geo_ch->max_antenna_gain = 0xff;
- geo_ch->hw_value = ch->channel;
-
- if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
-
- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- if (ch->flags & EEPROM_CHANNEL_RADAR)
- geo_ch->flags |= IEEE80211_CHAN_RADAR;
-
- if (ch->max_power_avg > priv->max_channel_txpower_limit)
- priv->max_channel_txpower_limit =
- ch->max_power_avg;
- } else {
- geo_ch->flags |= IEEE80211_CHAN_DISABLED;
- }
-
- /* Save flags for reg domain usage */
- geo_ch->orig_flags = geo_ch->flags;
-
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
- ch->channel, geo_ch->center_freq,
- is_channel_a_band(ch) ? "5.2" : "2.4",
- geo_ch->flags & IEEE80211_CHAN_DISABLED ?
- "restricted" : "valid",
- geo_ch->flags);
- }
-
- if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
- priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
- priv->cfg->sku &= ~IWL_SKU_A;
- }
-
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
- &priv->bands[IEEE80211_BAND_2GHZ];
- if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
- &priv->bands[IEEE80211_BAND_5GHZ];
-
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-
- return 0;
-}
-
-/*
- * iwl4965_free_geos - undo allocations in iwl4965_init_geos
- */
-void iwl4965_free_geos(struct iwl_priv *priv)
-{
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
- clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
-}
-
/******************************************************************************
*
* uCode download functions
@@ -4868,146 +1748,6 @@ static void iwl4965_dealloc_ucode_pci(struct iwl_priv *priv)
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
}
-/**
- * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host,
- * looking at all data.
- */
-static int iwl4965_verify_inst_full(struct iwl_priv *priv, __le32 *image,
- u32 len)
-{
- u32 val;
- u32 save_len = len;
- int rc = 0;
- u32 errcnt;
-
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
-
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
- iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
-
- errcnt = 0;
- for (; len > 0; len -= sizeof(u32), image++) {
- /* read data comes through single port, auto-incr addr */
- /* NOTE: Use the debugless read so we don't flood kernel log
- * if IWL_DL_IO is set */
- val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
- "offset 0x%x, is 0x%x, s/b 0x%x\n",
- save_len - len, val, le32_to_cpu(*image));
- rc = -EIO;
- errcnt++;
- if (errcnt >= 20)
- break;
- }
- }
-
- iwl_release_nic_access(priv);
-
- if (!errcnt)
- IWL_DEBUG_INFO
- ("ucode image in INSTRUCTION memory is good\n");
-
- return rc;
-}
-
-
-/**
- * iwl4965_verify_inst_sparse - verify runtime uCode image in card vs. host,
- * using sample data 100 bytes apart. If these sample points are good,
- * it's a pretty good bet that everything between them is good, too.
- */
-static int iwl4965_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
-{
- u32 val;
- int rc = 0;
- u32 errcnt = 0;
- u32 i;
-
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
-
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
- for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
- /* read data comes through single port, auto-incr addr */
- /* NOTE: Use the debugless read so we don't flood kernel log
- * if IWL_DL_IO is set */
- iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
- val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
- if (val != le32_to_cpu(*image)) {
-#if 0 /* Enable this if you want to see details */
- IWL_ERROR("uCode INST section is invalid at "
- "offset 0x%x, is 0x%x, s/b 0x%x\n",
- i, val, *image);
-#endif
- rc = -EIO;
- errcnt++;
- if (errcnt >= 3)
- break;
- }
- }
-
- iwl_release_nic_access(priv);
-
- return rc;
-}
-
-
-/**
- * iwl4965_verify_ucode - determine which instruction image is in SRAM,
- * and verify its contents
- */
-static int iwl4965_verify_ucode(struct iwl_priv *priv)
-{
- __le32 *image;
- u32 len;
- int rc = 0;
-
- /* Try bootstrap */
- image = (__le32 *)priv->ucode_boot.v_addr;
- len = priv->ucode_boot.len;
- rc = iwl4965_verify_inst_sparse(priv, image, len);
- if (rc == 0) {
- IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
- return 0;
- }
-
- /* Try initialize */
- image = (__le32 *)priv->ucode_init.v_addr;
- len = priv->ucode_init.len;
- rc = iwl4965_verify_inst_sparse(priv, image, len);
- if (rc == 0) {
- IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
- return 0;
- }
-
- /* Try runtime/protocol */
- image = (__le32 *)priv->ucode_code.v_addr;
- len = priv->ucode_code.len;
- rc = iwl4965_verify_inst_sparse(priv, image, len);
- if (rc == 0) {
- IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
- return 0;
- }
-
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
-
- /* Since nothing seems to match, show first several data entries in
- * instruction SRAM, so maybe visual inspection will give a clue.
- * Selection of bootstrap image (vs. other images) is arbitrary. */
- image = (__le32 *)priv->ucode_boot.v_addr;
- len = priv->ucode_boot.len;
- rc = iwl4965_verify_inst_full(priv, image, len);
-
- return rc;
-}
-
static void iwl4965_nic_start(struct iwl_priv *priv)
{
/* Remove all resets to allow NIC to operate */
@@ -5022,7 +1762,7 @@ static void iwl4965_nic_start(struct iwl_priv *priv)
*/
static int iwl4965_read_ucode(struct iwl_priv *priv)
{
- struct iwl4965_ucode *ucode;
+ struct iwl_ucode *ucode;
int ret;
const struct firmware *ucode_raw;
const char *name = priv->cfg->fw_name;
@@ -5083,34 +1823,34 @@ static int iwl4965_read_ucode(struct iwl_priv *priv)
}
/* Verify that uCode images will fit in card's SRAM */
- if (inst_size > IWL_MAX_INST_SIZE) {
+ if (inst_size > priv->hw_params.max_inst_size) {
IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
inst_size);
ret = -EINVAL;
goto err_release;
}
- if (data_size > IWL_MAX_DATA_SIZE) {
+ if (data_size > priv->hw_params.max_data_size) {
IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
data_size);
ret = -EINVAL;
goto err_release;
}
- if (init_size > IWL_MAX_INST_SIZE) {
+ if (init_size > priv->hw_params.max_inst_size) {
IWL_DEBUG_INFO
("uCode init instr len %d too large to fit in\n",
init_size);
ret = -EINVAL;
goto err_release;
}
- if (init_data_size > IWL_MAX_DATA_SIZE) {
+ if (init_data_size > priv->hw_params.max_data_size) {
IWL_DEBUG_INFO
("uCode init data len %d too large to fit in\n",
init_data_size);
ret = -EINVAL;
goto err_release;
}
- if (boot_size > IWL_MAX_BSM_SIZE) {
+ if (boot_size > priv->hw_params.max_bsm_size) {
IWL_DEBUG_INFO
("uCode boot instr len %d too large to fit in\n",
boot_size);
@@ -5211,111 +1951,12 @@ static int iwl4965_read_ucode(struct iwl_priv *priv)
return ret;
}
-
-/**
- * iwl4965_set_ucode_ptrs - Set uCode address location
- *
- * Tell initialization uCode where to find runtime uCode.
- *
- * BSM registers initially contain pointers to initialization uCode.
- * We need to replace them to load runtime uCode inst and data,
- * and to save runtime data when powering down.
- */
-static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
-{
- dma_addr_t pinst;
- dma_addr_t pdata;
- int rc = 0;
- unsigned long flags;
-
- /* bits 35:4 for 4965 */
- pinst = priv->ucode_code.p_addr >> 4;
- pdata = priv->ucode_data_backup.p_addr >> 4;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
-
- /* Tell bootstrap uCode where to find image to load */
- iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
- priv->ucode_data.len);
-
- /* Inst bytecount must be last to set up, bit 31 signals uCode
- * that all new ptr/size info is in place */
- iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
- priv->ucode_code.len | BSM_DRAM_INST_LOAD);
-
- iwl_release_nic_access(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
-
- return rc;
-}
-
-/**
- * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received
- *
- * Called after REPLY_ALIVE notification received from "initialize" uCode.
- *
- * The 4965 "initialize" ALIVE reply contains calibration data for:
- * Voltage, temperature, and MIMO tx gain correction, now stored in priv
- * (3945 does not contain this data).
- *
- * Tell "initialize" uCode to go ahead and load the runtime uCode.
-*/
-static void iwl4965_init_alive_start(struct iwl_priv *priv)
-{
- /* Check alive response for "valid" sign from uCode */
- if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
- /* We had an error bringing up the hardware, so take it
- * all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
- goto restart;
- }
-
- /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
- * This is a paranoid check, because we would not have gotten the
- * "initialize" alive if code weren't properly loaded. */
- if (iwl4965_verify_ucode(priv)) {
- /* Runtime instruction load was bad;
- * take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
- goto restart;
- }
-
- /* Calculate temperature */
- priv->temperature = iwl4965_get_temperature(priv);
-
- /* Send pointers to protocol/runtime uCode image ... init code will
- * load and launch runtime uCode, which will send us another "Alive"
- * notification. */
- IWL_DEBUG_INFO("Initialization Alive received.\n");
- if (iwl4965_set_ucode_ptrs(priv)) {
- /* Runtime instruction load won't happen;
- * take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
- goto restart;
- }
- return;
-
- restart:
- queue_work(priv->workqueue, &priv->restart);
-}
-
-
/**
- * iwl4965_alive_start - called after REPLY_ALIVE notification received
+ * iwl_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
- * Alive gets handled by iwl4965_init_alive_start()).
+ * Alive gets handled by iwl_init_alive_start()).
*/
-static void iwl4965_alive_start(struct iwl_priv *priv)
+static void iwl_alive_start(struct iwl_priv *priv)
{
int ret = 0;
@@ -5331,15 +1972,14 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
/* Initialize uCode has loaded Runtime uCode ... verify inst image.
* This is a paranoid check, because we would not have gotten the
* "runtime" alive if code weren't properly loaded. */
- if (iwl4965_verify_ucode(priv)) {
+ if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
IWL_DEBUG_INFO("Bad runtime uCode load.\n");
goto restart;
}
- iwlcore_clear_stations_table(priv);
-
+ iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n",
@@ -5350,22 +1990,17 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send host commands to 4965 uCode */
set_bit(STATUS_ALIVE, &priv->status);
- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
if (iwl_is_rfkill(priv))
return;
- ieee80211_start_queues(priv->hw);
+ ieee80211_wake_queues(priv->hw);
priv->active_rate = priv->rates_mask;
priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
- iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
-
if (iwl_is_associated(priv)) {
- struct iwl4965_rxon_cmd *active_rxon =
- (struct iwl4965_rxon_cmd *)(&priv->active_rxon);
+ struct iwl_rxon_cmd *active_rxon =
+ (struct iwl_rxon_cmd *)&priv->active_rxon;
memcpy(&priv->staging_rxon, &priv->active_rxon,
sizeof(priv->staging_rxon));
@@ -5379,13 +2014,13 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
/* Configure Bluetooth device coexistence support */
iwl4965_send_bt_config(priv);
+ iwl_reset_run_time_calib(priv);
+
/* Configure the adapter for unassociated operation */
iwl4965_commit_rxon(priv);
/* At this point, the NIC is initialized and operational */
- priv->notif_missed_beacons = 0;
-
- iwl4965_rf_kill_ct_config(priv);
+ iwl_rf_kill_ct_config(priv);
iwl_leds_register(priv);
@@ -5396,34 +2031,33 @@ static void iwl4965_alive_start(struct iwl_priv *priv)
if (priv->error_recovering)
iwl4965_error_recovery(priv);
- iwlcore_low_level_notify(priv, IWLCORE_START_EVT);
+ iwl_power_update_mode(priv, 1);
ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl4965_set_mode(priv, priv->iw_mode);
+
return;
restart:
queue_work(priv->workqueue, &priv->restart);
}
-static void iwl4965_cancel_deferred_work(struct iwl_priv *priv);
+static void iwl_cancel_deferred_work(struct iwl_priv *priv);
static void __iwl4965_down(struct iwl_priv *priv)
{
unsigned long flags;
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
- struct ieee80211_conf *conf = NULL;
IWL_DEBUG_INFO(DRV_NAME " is going down\n");
- conf = ieee80211_get_hw_conf(priv->hw);
-
if (!exit_pending)
set_bit(STATUS_EXIT_PENDING, &priv->status);
iwl_leds_unregister(priv);
- iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT);
-
- iwlcore_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -5455,7 +2089,9 @@ static void __iwl4965_down(struct iwl_priv *priv)
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND;
+ STATUS_IN_SUSPEND |
+ test_bit(STATUS_EXIT_PENDING, &priv->status) <<
+ STATUS_EXIT_PENDING;
goto exit;
}
@@ -5470,15 +2106,17 @@ static void __iwl4965_down(struct iwl_priv *priv)
test_bit(STATUS_IN_SUSPEND, &priv->status) <<
STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
- STATUS_FW_ERROR;
+ STATUS_FW_ERROR |
+ test_bit(STATUS_EXIT_PENDING, &priv->status) <<
+ STATUS_EXIT_PENDING;
spin_lock_irqsave(&priv->lock, flags);
iwl_clear_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
spin_unlock_irqrestore(&priv->lock, flags);
- iwl4965_hw_txq_ctx_stop(priv);
- iwl4965_hw_rxq_stop(priv);
+ iwl_txq_ctx_stop(priv);
+ iwl_rxq_stop(priv);
spin_lock_irqsave(&priv->lock, flags);
if (!iwl_grab_nic_access(priv)) {
@@ -5490,19 +2128,19 @@ static void __iwl4965_down(struct iwl_priv *priv)
udelay(5);
- iwl4965_hw_nic_stop_master(priv);
- iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
- iwl4965_hw_nic_reset(priv);
+ /* FIXME: apm_ops.suspend(priv) */
+ priv->cfg->ops->lib->apm_ops.reset(priv);
+ priv->cfg->ops->lib->free_shared_mem(priv);
exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl4965_alive_resp));
+ memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
priv->ibss_beacon = NULL;
/* clear out any free frames */
- iwl4965_clear_free_frames(priv);
+ iwl_clear_free_frames(priv);
}
static void iwl4965_down(struct iwl_priv *priv)
@@ -5511,7 +2149,7 @@ static void iwl4965_down(struct iwl_priv *priv)
__iwl4965_down(priv);
mutex_unlock(&priv->mutex);
- iwl4965_cancel_deferred_work(priv);
+ iwl_cancel_deferred_work(priv);
}
#define MAX_HW_RESTARTS 5
@@ -5526,13 +2164,6 @@ static int __iwl4965_up(struct iwl_priv *priv)
return -EIO;
}
- if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("Radio disabled by SW RF kill (module "
- "parameter)\n");
- iwl_rfkill_set_hw_state(priv);
- return -ENODEV;
- }
-
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
IWL_ERROR("ucode not available for device bringup\n");
return -EIO;
@@ -5542,19 +2173,25 @@ static int __iwl4965_up(struct iwl_priv *priv)
if (iwl_read32(priv, CSR_GP_CNTRL) &
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
- else {
+ else
set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- iwl_rfkill_set_hw_state(priv);
- IWL_WARNING("Radio disabled by HW RF Kill switch\n");
- return -ENODEV;
- }
+
+ if (!test_bit(STATUS_IN_SUSPEND, &priv->status) &&
+ iwl_is_rfkill(priv)) {
+ IWL_WARNING("Radio disabled by %s RF Kill switch\n",
+ test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
+ return -ENODEV;
}
- iwl_rfkill_set_hw_state(priv);
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
- ret = priv->cfg->ops->lib->hw_nic_init(priv);
+ ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
+ if (ret) {
+ IWL_ERROR("Unable to allocate shared memory\n");
+ return ret;
+ }
+
+ ret = iwl_hw_nic_init(priv);
if (ret) {
IWL_ERROR("Unable to init nic\n");
return ret;
@@ -5580,12 +2217,13 @@ static int __iwl4965_up(struct iwl_priv *priv)
priv->ucode_data.len);
/* We return success when we resume from suspend and rf_kill is on. */
- if (test_bit(STATUS_RF_KILL_HW, &priv->status))
+ if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
+ test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;
for (i = 0; i < MAX_HW_RESTARTS; i++) {
- iwlcore_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
@@ -5597,6 +2235,9 @@ static int __iwl4965_up(struct iwl_priv *priv)
continue;
}
+ /* Clear out the uCode error bit if it is set */
+ clear_bit(STATUS_FW_ERROR, &priv->status);
+
/* start card; "initialize" will load runtime ucode */
iwl4965_nic_start(priv);
@@ -5607,6 +2248,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl4965_down(priv);
+ clear_bit(STATUS_EXIT_PENDING, &priv->status);
/* tried to restart and config the device for as long as our
* patience could withstand */
@@ -5621,7 +2263,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
*
*****************************************************************************/
-static void iwl4965_bg_init_alive_start(struct work_struct *data)
+static void iwl_bg_init_alive_start(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, init_alive_start.work);
@@ -5630,11 +2272,11 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data)
return;
mutex_lock(&priv->mutex);
- iwl4965_init_alive_start(priv);
+ priv->cfg->ops->lib->init_alive_start(priv);
mutex_unlock(&priv->mutex);
}
-static void iwl4965_bg_alive_start(struct work_struct *data)
+static void iwl_bg_alive_start(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, alive_start.work);
@@ -5643,7 +2285,7 @@ static void iwl4965_bg_alive_start(struct work_struct *data)
return;
mutex_lock(&priv->mutex);
- iwl4965_alive_start(priv);
+ iwl_alive_start(priv);
mutex_unlock(&priv->mutex);
}
@@ -5659,7 +2301,7 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
mutex_lock(&priv->mutex);
if (!iwl_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
+ IWL_DEBUG(IWL_DL_RF_KILL,
"HW and/or SW RF Kill no longer active, restarting "
"device\n");
if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -5677,239 +2319,53 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
"Kill switch must be turned off for "
"wireless networking to work.\n");
}
- iwl_rfkill_set_hw_state(priv);
-
mutex_unlock(&priv->mutex);
+ iwl_rfkill_set_hw_state(priv);
}
-#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl4965_bg_scan_check(struct work_struct *data)
+static void iwl4965_bg_set_monitor(struct work_struct *work)
{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, scan_check.work);
+ struct iwl_priv *priv = container_of(work,
+ struct iwl_priv, set_monitor);
+ int ret;
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");
mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
- "Scan completion watchdog resetting adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl4965_send_scan_abort(priv);
+ ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR);
+
+ if (ret) {
+ if (ret == -EAGAIN)
+ IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
+ else
+ IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret);
}
+
mutex_unlock(&priv->mutex);
}
-static void iwl4965_bg_request_scan(struct work_struct *data)
+static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, request_scan);
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_CMD,
- .len = sizeof(struct iwl4965_scan_cmd),
- .meta.flags = CMD_SIZE_HUGE,
- };
- struct iwl4965_scan_cmd *scan;
- struct ieee80211_conf *conf = NULL;
- u16 cmd_len;
- enum ieee80211_band band;
- u8 direct_mask;
- int ret = 0;
-
- conf = ieee80211_get_hw_conf(priv->hw);
+ struct iwl_priv *priv = container_of(work, struct iwl_priv,
+ run_time_calib_work);
mutex_lock(&priv->mutex);
- if (!iwl_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
- goto done;
- }
-
- /* Make sure the scan wasn't cancelled before this queued work
- * was given the chance to run... */
- if (!test_bit(STATUS_SCANNING, &priv->status))
- goto done;
-
- /* This should never be called or scheduled if there is currently
- * a scan active in the hardware. */
- if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
- "Ignoring second request.\n");
- ret = -EIO;
- goto done;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
- goto done;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
- goto done;
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
- goto done;
- }
-
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
- goto done;
- }
-
- if (!priv->scan_bands) {
- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
- goto done;
- }
-
- if (!priv->scan) {
- priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) +
- IWL_MAX_SCAN_SIZE, GFP_KERNEL);
- if (!priv->scan) {
- ret = -ENOMEM;
- goto done;
- }
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+ test_bit(STATUS_SCANNING, &priv->status)) {
+ mutex_unlock(&priv->mutex);
+ return;
}
- scan = priv->scan;
- memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE);
- scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
- scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
+ if (priv->start_calib) {
+ iwl_chain_noise_calibration(priv, &priv->statistics);
- if (iwl_is_associated(priv)) {
- u16 interval = 0;
- u32 extra;
- u32 suspend_time = 100;
- u32 scan_suspend_time = 100;
- unsigned long flags;
-
- IWL_DEBUG_INFO("Scanning while associated...\n");
-
- spin_lock_irqsave(&priv->lock, flags);
- interval = priv->beacon_int;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- scan->suspend_time = 0;
- scan->max_out_time = cpu_to_le32(200 * 1024);
- if (!interval)
- interval = suspend_time;
-
- extra = (suspend_time / interval) << 22;
- scan_suspend_time = (extra |
- ((suspend_time % interval) * 1024));
- scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
- scan_suspend_time, interval);
- }
-
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s'\n",
- iwl4965_escape_essid(priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->direct_ssid_len;
- memcpy(scan->direct_scan[0].ssid,
- priv->direct_ssid, priv->direct_ssid_len);
- direct_mask = 1;
- } else if (!iwl_is_associated(priv) && priv->essid_len) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s' when not associated\n",
- iwl4965_escape_essid(priv->essid, priv->essid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->essid_len;
- memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
- direct_mask = 1;
- } else {
- IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
- direct_mask = 0;
+ iwl_sensitivity_calibration(priv, &priv->statistics);
}
- scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
- scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
-
- if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
- scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- scan->tx_cmd.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
- RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);
-
- scan->good_CRC_th = 0;
- band = IEEE80211_BAND_2GHZ;
- } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
- scan->tx_cmd.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
- RATE_MCS_ANT_B_MSK);
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
- band = IEEE80211_BAND_5GHZ;
- } else {
- IWL_WARNING("Invalid scan band count\n");
- goto done;
- }
-
- /* We don't build a direct scan probe request; the uCode will do
- * that based on the direct_mask added to each channel entry */
- cmd_len = iwl4965_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan), 0);
-
- scan->tx_cmd.len = cpu_to_le16(cmd_len);
- /* select Rx chains */
-
- /* Force use of chains B and C (0x6) for scan Rx.
- * Avoid A (0x1) because of its off-channel reception on A-band.
- * MIMO is not used here, but value is required to make uCode happy. */
- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
- (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) |
- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
-
- if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
- scan->filter_flags = RXON_FILTER_PROMISC_MSK;
-
- if (direct_mask)
- scan->channel_count =
- iwl4965_get_channels_for_scan(
- priv, band, 1, /* active */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
- else
- scan->channel_count =
- iwl4965_get_channels_for_scan(
- priv, band, 0, /* passive */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
-
- cmd.len += le16_to_cpu(scan->tx_cmd.len) +
- scan->channel_count * sizeof(struct iwl4965_scan_channel);
- cmd.data = scan;
- scan->len = cpu_to_le16(cmd.len);
-
- set_bit(STATUS_SCAN_HW, &priv->status);
- ret = iwl_send_cmd_sync(priv, &cmd);
- if (ret)
- goto done;
-
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IWL_SCAN_CHECK_WATCHDOG);
-
mutex_unlock(&priv->mutex);
return;
-
- done:
- /* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
- mutex_unlock(&priv->mutex);
}
static void iwl4965_bg_up(struct work_struct *data)
@@ -5922,6 +2378,7 @@ static void iwl4965_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl4965_up(priv);
mutex_unlock(&priv->mutex);
+ iwl_rfkill_set_hw_state(priv);
}
static void iwl4965_bg_restart(struct work_struct *data)
@@ -5944,7 +2401,7 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data)
return;
mutex_lock(&priv->mutex);
- iwl4965_rx_replenish(priv);
+ iwl_rx_replenish(priv);
mutex_unlock(&priv->mutex);
}
@@ -5955,6 +2412,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
struct ieee80211_conf *conf = NULL;
int ret = 0;
DECLARE_MAC_BUF(mac);
+ unsigned long flags;
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
@@ -5973,7 +2431,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
if (!priv->vif || !priv->is_open)
return;
- iwl4965_scan_cancel_timeout(priv, 200);
+ iwl_scan_cancel_timeout(priv, 200);
conf = ieee80211_get_hw_conf(priv->hw);
@@ -5990,11 +2448,10 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
-#ifdef CONFIG_IWL4965_HT
if (priv->current_ht_config.is_ht)
- iwl4965_set_rxon_ht(priv, &priv->current_ht_config);
-#endif /* CONFIG_IWL4965_HT*/
- iwl4965_set_rxon_chain(priv);
+ iwl_set_rxon_ht(priv, &priv->current_ht_config);
+
+ iwl_set_rxon_chain(priv);
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
@@ -6020,17 +2477,14 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
switch (priv->iw_mode) {
case IEEE80211_IF_TYPE_STA:
- iwl4965_rate_scale_init(priv->hw, IWL_AP_ID);
break;
case IEEE80211_IF_TYPE_IBSS:
- /* clear out the station table */
- iwlcore_clear_stations_table(priv);
+ /* assume default assoc id */
+ priv->assoc_id = 1;
- iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0);
- iwl4965_rxon_add_station(priv, priv->bssid, 0);
- iwl4965_rate_scale_init(priv->hw, IWL_STA_ID);
+ iwl_rxon_add_station(priv, priv->bssid, 0);
iwl4965_send_beacon_cmd(priv);
break;
@@ -6041,58 +2495,30 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
break;
}
- iwl4965_sequence_reset(priv);
-
-#ifdef CONFIG_IWL4965_SENSITIVITY
/* Enable Rx differential gain and sensitivity calibrations */
- iwl4965_chain_noise_reset(priv);
+ iwl_chain_noise_reset(priv);
priv->start_calib = 1;
-#endif /* CONFIG_IWL4965_SENSITIVITY */
if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
priv->assoc_station_added = 1;
- iwl4965_activate_qos(priv, 0);
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_activate_qos(priv, 0);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_power_update_mode(priv, 0);
/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-
-static void iwl4965_bg_post_associate(struct work_struct *data)
-{
- struct iwl_priv *priv = container_of(data, struct iwl_priv,
- post_associate.work);
-
- mutex_lock(&priv->mutex);
- iwl4965_post_associate(priv);
- mutex_unlock(&priv->mutex);
-
-}
-
-static void iwl4965_bg_abort_scan(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
-
- if (!iwl_is_ready(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl4965_send_scan_abort(priv);
-
- mutex_unlock(&priv->mutex);
-}
-
static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
-static void iwl4965_bg_scan_completed(struct work_struct *work)
+static void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
+ IWL_DEBUG_SCAN("SCAN complete scan\n");
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6105,7 +2531,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work)
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
mutex_lock(&priv->mutex);
- iwl4965_hw_reg_send_txpower(priv);
+ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
mutex_unlock(&priv->mutex);
}
@@ -6115,7 +2541,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work)
*
*****************************************************************************/
-#define UCODE_READY_TIMEOUT (2 * HZ)
+#define UCODE_READY_TIMEOUT (4 * HZ)
static int iwl4965_mac_start(struct ieee80211_hw *hw)
{
@@ -6141,7 +2567,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
- memset(&priv->staging_rxon, 0, sizeof(struct iwl4965_rxon_cmd));
+ memset(&priv->staging_rxon, 0, sizeof(struct iwl_rxon_cmd));
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
@@ -6158,6 +2584,8 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
+ iwl_rfkill_set_hw_state(priv);
+
if (ret)
goto out_release_irq;
@@ -6166,15 +2594,15 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
if (test_bit(STATUS_IN_SUSPEND, &priv->status))
return 0;
- /* Wait for START_ALIVE from ucode. Otherwise callbacks from
+ /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
test_bit(STATUS_READY, &priv->status),
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
- jiffies_to_msecs(UCODE_READY_TIMEOUT));
+ IWL_ERROR("START_ALIVE timeout after %dms.\n",
+ jiffies_to_msecs(UCODE_READY_TIMEOUT));
ret = -ETIMEDOUT;
goto out_release_irq;
}
@@ -6212,8 +2640,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
* RXON_FILTER_ASSOC_MSK BIT
*/
mutex_lock(&priv->mutex);
- iwl4965_scan_cancel_timeout(priv, 100);
- cancel_delayed_work(&priv->post_associate);
+ iwl_scan_cancel_timeout(priv, 100);
mutex_unlock(&priv->mutex);
}
@@ -6228,8 +2655,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211("leave\n");
}
-static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *ctl)
+static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
@@ -6242,9 +2668,9 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
}
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
- ctl->tx_rate->bitrate);
+ ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
- if (iwl4965_tx_skb(priv, skb, ctl))
+ if (iwl_tx_skb(priv, skb))
dev_kfree_skb_any(skb);
IWL_DEBUG_MAC80211("leave\n");
@@ -6277,8 +2703,9 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
- if (iwl_is_ready(priv))
- iwl4965_set_mode(priv, conf->type);
+ if (iwl4965_set_mode(priv, conf->type) == -EAGAIN)
+ /* we are not ready, will run again when ready */
+ set_bit(STATUS_MODE_PENDING, &priv->status);
mutex_unlock(&priv->mutex);
@@ -6299,12 +2726,21 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
const struct iwl_channel_info *ch_info;
unsigned long flags;
int ret = 0;
+ u16 channel;
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+ if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
+ IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
+ goto out;
+ }
+
+ if (!conf->radio_enabled)
+ iwl_radio_kill_sw_disable_radio(priv);
+
if (!iwl_is_ready(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
ret = -EIO;
@@ -6319,33 +2755,37 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
return 0;
}
- spin_lock_irqsave(&priv->lock, flags);
-
- ch_info = iwl_get_channel_info(priv, conf->channel->band,
- ieee80211_frequency_to_channel(conf->channel->center_freq));
+ channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band, channel);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_MAC80211("leave - invalid channel\n");
- spin_unlock_irqrestore(&priv->lock, flags);
ret = -EINVAL;
goto out;
}
-#ifdef CONFIG_IWL4965_HT
+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+ !is_channel_ibss(ch_info)) {
+ IWL_ERROR("channel %d in band %d not IBSS channel\n",
+ conf->channel->hw_value, conf->channel->band);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ spin_lock_irqsave(&priv->lock, flags);
+
/* if we are switching from ht to 2.4 clear flags
* from any ht related info since 2.4 does not
* support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel->hw_value)
+ if ((le16_to_cpu(priv->staging_rxon.channel) != channel)
#ifdef IEEE80211_CONF_CHANNEL_SWITCH
&& !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH)
#endif
)
priv->staging_rxon.flags = 0;
-#endif /* CONFIG_IWL4965_HT */
- iwlcore_set_rxon_channel(priv, conf->channel->band,
- ieee80211_frequency_to_channel(conf->channel->center_freq));
+ iwl_set_rxon_channel(priv, conf->channel->band, channel);
- iwl4965_set_flags_for_phymode(priv, conf->channel->band);
+ iwl_set_flags_for_band(priv, conf->channel->band);
/* The list of supported rates and rate mask can be different
* for each band; since the band may have changed, reset
@@ -6361,9 +2801,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
}
#endif
- if (priv->cfg->ops->lib->radio_kill_sw)
- priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled);
-
if (!conf->radio_enabled) {
IWL_DEBUG_MAC80211("leave - radio disabled\n");
goto out;
@@ -6375,6 +2812,11 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
goto out;
}
+ IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+
iwl4965_set_rate(priv);
if (memcmp(&priv->active_rxon,
@@ -6394,12 +2836,13 @@ out:
static void iwl4965_config_ap(struct iwl_priv *priv)
{
int ret = 0;
+ unsigned long flags;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
/* The following should be done only at AP bring up */
- if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) {
+ if (!(iwl_is_associated(priv))) {
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -6414,7 +2857,7 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
IWL_WARNING("REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
- iwl4965_set_rxon_chain(priv);
+ iwl_set_rxon_chain(priv);
/* FIXME: what should be the assoc_id for AP? */
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -6441,8 +2884,10 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
- iwl4965_activate_qos(priv, 1);
- iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0);
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_activate_qos(priv, 1);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
}
iwl4965_send_beacon_cmd(priv);
@@ -6451,6 +2896,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
+/* temporary */
+static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+
static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
@@ -6468,8 +2916,18 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
return 0;
}
+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+ conf->changed & IEEE80211_IFCC_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+ if (!beacon)
+ return -ENOMEM;
+ rc = iwl4965_mac_beacon_update(hw, beacon);
+ if (rc)
+ return rc;
+ }
+
if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
- (!conf->beacon || !conf->ssid_len)) {
+ (!conf->ssid_len)) {
IWL_DEBUG_MAC80211
("Leaving in AP mode because HostAPD is not ready.\n");
return 0;
@@ -6501,7 +2959,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
- priv->ibss_beacon = conf->beacon;
+ priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
if (iwl_is_rfkill(priv))
@@ -6511,7 +2969,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
!is_multicast_ether_addr(conf->bssid)) {
/* If there is currently a HW scan going on in the background
* then we need to cancel it else the RXON below will fail. */
- if (iwl4965_scan_cancel_timeout(priv, 100)) {
+ if (iwl_scan_cancel_timeout(priv, 100)) {
IWL_WARNING("Aborted scan still in progress "
"after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
@@ -6531,12 +2989,12 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
else {
rc = iwl4965_commit_rxon(priv);
if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
- iwl4965_rxon_add_station(
+ iwl_rxon_add_station(
priv, priv->active_rxon.bssid_addr, 1);
}
} else {
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
}
@@ -6562,11 +3020,18 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags,
int mc_count, struct dev_addr_list *mc_list)
{
- /*
- * XXX: dummy
- * see also iwl4965_connection_init_rx_config
- */
- *total_flags = 0;
+ struct iwl_priv *priv = hw->priv;
+
+ if (changed_flags & (*total_flags) & FIF_OTHER_BSS) {
+ IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n",
+ IEEE80211_IF_TYPE_MNTR,
+ changed_flags, *total_flags);
+ /* queue work 'cuz mac80211 is holding a lock which
+ * prevents us from issuing (synchronous) f/w cmds */
+ queue_work(priv->workqueue, &priv->set_monitor);
+ }
+ *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI |
+ FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
}
static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
@@ -6579,8 +3044,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (iwl_is_ready_rf(priv)) {
- iwl4965_scan_cancel_timeout(priv, 100);
- cancel_delayed_work(&priv->post_associate);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
}
@@ -6596,64 +3060,6 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
}
-
-#ifdef CONFIG_IWL4965_HT
-static void iwl4965_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
-{
- struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf;
- struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf;
- struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
-
- IWL_DEBUG_MAC80211("enter: \n");
-
- iwl_conf->is_ht = bss_conf->assoc_ht;
-
- if (!iwl_conf->is_ht)
- return;
-
- priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
-
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
- iwl_conf->sgf |= 0x1;
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
- iwl_conf->sgf |= 0x2;
-
- iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
- iwl_conf->max_amsdu_size =
- !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
- iwl_conf->supported_chan_width =
- !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
- iwl_conf->extension_chan_offset =
- ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
- /* If no above or below channel supplied disable FAT channel */
- if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
- iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
- iwl_conf->supported_chan_width = 0;
-
- iwl_conf->tx_mimo_ps_mode =
- (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
- memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
-
- iwl_conf->control_channel = ht_bss_conf->primary_channel;
- iwl_conf->tx_chan_width =
- !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
- iwl_conf->ht_protection =
- ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
- iwl_conf->non_GF_STA_present =
- !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
-
- IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel);
- IWL_DEBUG_MAC80211("leave\n");
-}
-#else
-static inline void iwl4965_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
-{
-}
-#endif
-
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
@@ -6684,7 +3090,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
if (changes & BSS_CHANGED_HT) {
IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht);
iwl4965_ht_conf(priv, bss_conf);
- iwl4965_set_rxon_chain(priv);
+ iwl_set_rxon_chain(priv);
}
if (changes & BSS_CHANGED_ASSOC) {
@@ -6751,7 +3157,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
}
if (len) {
IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
- iwl4965_escape_essid(ssid, len), (int)len);
+ iwl_escape_essid(ssid, len), (int)len);
priv->one_direct_scan = 1;
priv->direct_ssid_len = (u8)
@@ -6760,7 +3166,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
} else
priv->one_direct_scan = 0;
- rc = iwl4965_scan_initiate(priv);
+ rc = iwl_scan_initiate(priv);
IWL_DEBUG_MAC80211("leave\n");
@@ -6784,14 +3190,14 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211("enter\n");
- sta_id = iwl4965_hw_find_station(priv, addr);
+ sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
print_mac(mac, addr));
return;
}
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
@@ -6812,7 +3218,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -6831,7 +3237,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
IWL_DEBUG_MAC80211("enter\n");
- if (priv->cfg->mod_params->sw_crypto) {
+ if (priv->hw_params.sw_crypto) {
IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
@@ -6840,7 +3246,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
/* only support pairwise keys */
return -EOPNOTSUPP;
- sta_id = iwl4965_hw_find_station(priv, addr);
+ sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
print_mac(mac, addr));
@@ -6849,7 +3255,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}
mutex_lock(&priv->mutex);
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
mutex_unlock(&priv->mutex);
/* If we are getting WEP group key and we didn't receive any key mapping
@@ -6861,7 +3267,8 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (cmd == SET_KEY)
is_default_wep_key = !priv->key_mapping_key;
else
- is_default_wep_key = priv->default_wep_key;
+ is_default_wep_key =
+ (key->hw_key_idx == HW_KEY_DEFAULT);
}
switch (cmd) {
@@ -6877,7 +3284,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (is_default_wep_key)
ret = iwl_remove_default_wep_key(priv, key);
else
- ret = iwl_remove_dynamic_key(priv, sta_id);
+ ret = iwl_remove_dynamic_key(priv, key, sta_id);
IWL_DEBUG_MAC80211("disable hwcrypto key\n");
break;
@@ -6890,7 +3297,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
+static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct iwl_priv *priv = hw->priv;
@@ -6927,15 +3334,12 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
priv->qos_data.qos_active = 1;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
- iwl4965_activate_qos(priv, 1);
+ iwl_activate_qos(priv, 1);
else if (priv->assoc_id && iwl_is_associated(priv))
- iwl4965_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 0);
- mutex_unlock(&priv->mutex);
+ spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_MAC80211("leave\n");
return 0;
@@ -6946,8 +3350,8 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
int i, avail;
- struct iwl4965_tx_queue *txq;
- struct iwl4965_queue *q;
+ struct iwl_tx_queue *txq;
+ struct iwl_queue *q;
unsigned long flags;
IWL_DEBUG_MAC80211("enter\n");
@@ -6962,11 +3366,11 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
for (i = 0; i < AC_NUM; i++) {
txq = &priv->txq[i];
q = &txq->q;
- avail = iwl4965_queue_space(q);
+ avail = iwl_queue_space(q);
- stats->data[i].len = q->n_window - avail;
- stats->data[i].limit = q->n_window - q->high_mark;
- stats->data[i].count = q->n_window;
+ stats[i].len = q->n_window - avail;
+ stats[i].limit = q->n_window - q->high_mark;
+ stats[i].count = q->n_window;
}
spin_unlock_irqrestore(&priv->lock, flags);
@@ -6979,14 +3383,9 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
static int iwl4965_mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
- IWL_DEBUG_MAC80211("enter\n");
- IWL_DEBUG_MAC80211("leave\n");
-
- return 0;
-}
+ struct iwl_priv *priv = hw->priv;
-static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw)
-{
+ priv = hw->priv;
IWL_DEBUG_MAC80211("enter\n");
IWL_DEBUG_MAC80211("leave\n");
@@ -7001,16 +3400,11 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter\n");
- priv->lq_mngr.lq_ready = 0;
-#ifdef CONFIG_IWL4965_HT
spin_lock_irqsave(&priv->lock, flags);
memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
spin_unlock_irqrestore(&priv->lock, flags);
-#endif /* CONFIG_IWL4965_HT */
-
- iwlcore_reset_qos(priv);
- cancel_delayed_work(&priv->post_associate);
+ iwl_reset_qos(priv);
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
@@ -7040,11 +3434,13 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
* clear RXON_FILTER_ASSOC_MSK bit
*/
if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
}
+ iwl_power_update_mode(priv, 0);
+
/* Per mac80211.h: This is only used in IBSS mode... */
if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
@@ -7060,11 +3456,11 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211("leave\n");
}
-static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ __le64 timestamp;
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter\n");
@@ -7089,13 +3485,15 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
priv->ibss_beacon = skb;
priv->assoc_id = 0;
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000);
IWL_DEBUG_MAC80211("leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
- iwlcore_reset_qos(priv);
+ iwl_reset_qos(priv);
- queue_work(priv->workqueue, &priv->post_associate.work);
+ iwl4965_post_associate(priv);
mutex_unlock(&priv->mutex);
@@ -7118,13 +3516,18 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
* See the level definitions in iwl for details.
*/
-static ssize_t show_debug_level(struct device_driver *d, char *buf)
+static ssize_t show_debug_level(struct device *d,
+ struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "0x%08X\n", iwl_debug_level);
+ struct iwl_priv *priv = d->driver_data;
+
+ return sprintf(buf, "0x%08X\n", priv->debug_level);
}
-static ssize_t store_debug_level(struct device_driver *d,
+static ssize_t store_debug_level(struct device *d,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = d->driver_data;
char *p = (char *)buf;
u32 val;
@@ -7133,17 +3536,49 @@ static ssize_t store_debug_level(struct device_driver *d,
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else
- iwl_debug_level = val;
+ priv->debug_level = val;
return strnlen(buf, count);
}
-static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
- show_debug_level, store_debug_level);
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+ show_debug_level, store_debug_level);
+
#endif /* CONFIG_IWLWIFI_DEBUG */
+static ssize_t show_version(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct iwl_priv *priv = d->driver_data;
+ struct iwl_alive_resp *palive = &priv->card_alive;
+ ssize_t pos = 0;
+ u16 eeprom_ver;
+
+ if (palive->is_valid)
+ pos += sprintf(buf + pos,
+ "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n"
+ "fw type: 0x%01X 0x%01X\n",
+ palive->ucode_major, palive->ucode_minor,
+ palive->sw_rev[0], palive->sw_rev[1],
+ palive->ver_type, palive->ver_subtype);
+ else
+ pos += sprintf(buf + pos, "fw not loaded\n");
+
+ if (priv->eeprom) {
+ eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+ pos += sprintf(buf + pos, "EEPROM version: 0x%x\n",
+ eeprom_ver);
+ } else {
+ pos += sprintf(buf + pos, "EEPROM not initialzed\n");
+ }
+
+ return pos;
+}
+
+static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
+
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -7152,7 +3587,7 @@ static ssize_t show_temperature(struct device *d,
if (!iwl_is_alive(priv))
return -EAGAIN;
- return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv));
+ return sprintf(buf, "%d\n", priv->temperature);
}
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
@@ -7170,7 +3605,7 @@ static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- return sprintf(buf, "%d\n", priv->user_txpower_limit);
+ return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
static ssize_t store_tx_power(struct device *d,
@@ -7186,7 +3621,7 @@ static ssize_t store_tx_power(struct device *d,
printk(KERN_INFO DRV_NAME
": %s is not in decimal form.\n", buf);
else
- iwl4965_hw_reg_set_txpower(priv, val);
+ iwl_set_tx_power(priv, val, false);
return count;
}
@@ -7211,7 +3646,7 @@ static ssize_t store_flags(struct device *d,
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
- if (iwl4965_scan_cancel_timeout(priv, 100))
+ if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARNING("Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
@@ -7246,7 +3681,7 @@ static ssize_t store_filter_flags(struct device *d,
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
- if (iwl4965_scan_cancel_timeout(priv, 100))
+ if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARNING("Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.filter_flags = "
@@ -7376,20 +3811,11 @@ static ssize_t store_power_level(struct device *d,
goto out;
}
- if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC))
- mode = IWL_POWER_AC;
- else
- mode |= IWL_POWER_ENABLED;
-
- if (mode != priv->power_mode) {
- rc = iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(mode));
- if (rc) {
- IWL_DEBUG_MAC80211("failed setting power mode.\n");
- goto out;
- }
- priv->power_mode = mode;
+ rc = iwl_power_set_user_mode(priv, mode);
+ if (rc) {
+ IWL_DEBUG_MAC80211("failed setting power mode.\n");
+ goto out;
}
-
rc = count;
out:
@@ -7419,7 +3845,7 @@ static ssize_t show_power_level(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = dev_get_drvdata(d);
- int level = IWL_POWER_LEVEL(priv->power_mode);
+ int level = priv->power_data.power_mode;
char *p = buf;
p += sprintf(p, "%d ", level);
@@ -7437,14 +3863,14 @@ static ssize_t show_power_level(struct device *d,
timeout_duration[level - 1] / 1000,
period_duration[level - 1] / 1000);
}
-
+/*
if (!(priv->power_mode & IWL_POWER_ENABLED))
p += sprintf(p, " OFF\n");
else
p += sprintf(p, " \n");
-
+*/
+ p += sprintf(p, " \n");
return (p - buf + 1);
-
}
static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
@@ -7453,8 +3879,62 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
static ssize_t show_channels(struct device *d,
struct device_attribute *attr, char *buf)
{
- /* all this shit doesn't belong into sysfs anyway */
- return 0;
+
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ struct ieee80211_channel *channels = NULL;
+ const struct ieee80211_supported_band *supp_band = NULL;
+ int len = 0, i;
+ int count = 0;
+
+ if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
+ return -EAGAIN;
+
+ supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
+ channels = supp_band->channels;
+ count = supp_band->n_channels;
+
+ len += sprintf(&buf[len],
+ "Displaying %d channels in 2.4GHz band "
+ "(802.11bg):\n", count);
+
+ for (i = 0; i < count; i++)
+ len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",
+ ieee80211_frequency_to_channel(
+ channels[i].center_freq),
+ channels[i].max_power,
+ channels[i].flags & IEEE80211_CHAN_RADAR ?
+ " (IEEE 802.11h required)" : "",
+ (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+ || (channels[i].flags &
+ IEEE80211_CHAN_RADAR)) ? "" :
+ ", IBSS",
+ channels[i].flags &
+ IEEE80211_CHAN_PASSIVE_SCAN ?
+ "passive only" : "active/passive");
+
+ supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
+ channels = supp_band->channels;
+ count = supp_band->n_channels;
+
+ len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band "
+ "(802.11a):\n", count);
+
+ for (i = 0; i < count; i++)
+ len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",
+ ieee80211_frequency_to_channel(
+ channels[i].center_freq),
+ channels[i].max_power,
+ channels[i].flags & IEEE80211_CHAN_RADAR ?
+ " (IEEE 802.11h required)" : "",
+ ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+ || (channels[i].flags &
+ IEEE80211_CHAN_RADAR)) ? "" :
+ ", IBSS",
+ channels[i].flags &
+ IEEE80211_CHAN_PASSIVE_SCAN ?
+ "passive only" : "active/passive");
+
+ return len;
}
static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
@@ -7463,7 +3943,7 @@ static ssize_t show_statistics(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = dev_get_drvdata(d);
- u32 size = sizeof(struct iwl4965_notif_statistics);
+ u32 size = sizeof(struct iwl_notif_statistics);
u32 len = 0, ofs = 0;
u8 *data = (u8 *) & priv->statistics;
int rc = 0;
@@ -7497,44 +3977,6 @@ static ssize_t show_statistics(struct device *d,
static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
-static ssize_t show_antenna(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- return sprintf(buf, "%d\n", priv->antenna);
-}
-
-static ssize_t store_antenna(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int ant;
- struct iwl_priv *priv = dev_get_drvdata(d);
-
- if (count == 0)
- return 0;
-
- if (sscanf(buf, "%1i", &ant) != 1) {
- IWL_DEBUG_INFO("not in hex or decimal form.\n");
- return count;
- }
-
- if ((ant >= 0) && (ant <= 2)) {
- IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
- priv->antenna = (enum iwl4965_antenna)ant;
- } else
- IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
-
-
- return count;
-}
-
-static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
-
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -7546,41 +3988,13 @@ static ssize_t show_status(struct device *d,
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
-static ssize_t dump_error_log(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- char *p = (char *)buf;
-
- if (p[0] == '1')
- iwl4965_dump_nic_error_log((struct iwl_priv *)d->driver_data);
-
- return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
-
-static ssize_t dump_event_log(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- char *p = (char *)buf;
-
- if (p[0] == '1')
- iwl4965_dump_nic_event_log((struct iwl_priv *)d->driver_data);
-
- return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
-
/*****************************************************************************
*
* driver setup and teardown
*
*****************************************************************************/
-static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
+static void iwl_setup_deferred_work(struct iwl_priv *priv)
{
priv->workqueue = create_workqueue(DRV_NAME);
@@ -7589,38 +4003,42 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl4965_bg_up);
INIT_WORK(&priv->restart, iwl4965_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish);
- INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed);
- INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan);
- INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan);
INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update);
- INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate);
- INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start);
- INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start);
- INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check);
+ INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor);
+ INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
+ INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
+ INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
+
+ /* FIXME : remove when resolved PENDING */
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ iwl_setup_scan_deferred_work(priv);
+
+ if (priv->cfg->ops->lib->setup_deferred_work)
+ priv->cfg->ops->lib->setup_deferred_work(priv);
- iwl4965_hw_setup_deferred_work(priv);
+ init_timer(&priv->statistics_periodic);
+ priv->statistics_periodic.data = (unsigned long)priv;
+ priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
iwl4965_irq_tasklet, (unsigned long)priv);
}
-static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
+static void iwl_cancel_deferred_work(struct iwl_priv *priv)
{
- iwl4965_hw_cancel_deferred_work(priv);
+ if (priv->cfg->ops->lib->cancel_deferred_work)
+ priv->cfg->ops->lib->cancel_deferred_work(priv);
cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
cancel_delayed_work(&priv->alive_start);
- cancel_delayed_work(&priv->post_associate);
cancel_work_sync(&priv->beacon_update);
+ del_timer_sync(&priv->statistics_periodic);
}
static struct attribute *iwl4965_sysfs_entries[] = {
- &dev_attr_antenna.attr,
&dev_attr_channels.attr,
- &dev_attr_dump_errors.attr,
- &dev_attr_dump_events.attr,
&dev_attr_flags.attr,
&dev_attr_filter_flags.attr,
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
@@ -7633,6 +4051,10 @@ static struct attribute *iwl4965_sysfs_entries[] = {
&dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
+#ifdef CONFIG_IWLWIFI_DEBUG
+ &dev_attr_debug_level.attr,
+#endif
+ &dev_attr_version.attr,
NULL
};
@@ -7656,13 +4078,9 @@ static struct ieee80211_ops iwl4965_hw_ops = {
.get_stats = iwl4965_mac_get_stats,
.get_tx_stats = iwl4965_mac_get_tx_stats,
.conf_tx = iwl4965_mac_conf_tx,
- .get_tsf = iwl4965_mac_get_tsf,
.reset_tsf = iwl4965_mac_reset_tsf,
- .beacon_update = iwl4965_mac_beacon_update,
.bss_info_changed = iwl4965_bss_info_changed,
-#ifdef CONFIG_IWL4965_HT
.ampdu_action = iwl4965_mac_ampdu_action,
-#endif /* CONFIG_IWL4965_HT */
.hw_scan = iwl4965_mac_hw_scan
};
@@ -7682,7 +4100,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Disabling hardware scan means that mac80211 will perform scans
* "the hard way", rather than using device's scan. */
if (cfg->mod_params->disable_hw_scan) {
- IWL_DEBUG_INFO("Disabling hw_scan\n");
+ if (cfg->mod_params->debug & IWL_DL_INFO)
+ dev_printk(KERN_DEBUG, &(pdev->dev),
+ "Disabling hw_scan\n");
iwl4965_hw_ops.hw_scan = NULL;
}
@@ -7701,7 +4121,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->pci_dev = pdev;
#ifdef CONFIG_IWLWIFI_DEBUG
- iwl_debug_level = priv->cfg->mod_params->debug;
+ priv->debug_level = priv->cfg->mod_params->debug;
atomic_set(&priv->restrict_refcnt, 0);
#endif
@@ -7715,13 +4135,19 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_set_master(pdev);
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (err) {
+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (!err)
+ err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ /* both attempts failed: */
if (err) {
- printk(KERN_WARNING DRV_NAME
- ": No suitable DMA available.\n");
+ printk(KERN_WARNING "%s: No suitable DMA available.\n",
+ DRV_NAME);
goto out_pci_disable_device;
+ }
}
err = pci_request_regions(pdev, DRV_NAME);
@@ -7747,31 +4173,31 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
(unsigned long long) pci_resource_len(pdev, 0));
IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+ iwl_hw_detect(priv);
printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+ ": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
+ priv->cfg->name, priv->hw_rev);
- /*****************
- * 4. Read EEPROM
- *****************/
- /* nic init */
- iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
- iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- err = iwl_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ /* amp init */
+ err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO("Failed to init APMG\n");
goto out_iounmap;
}
+ /*****************
+ * 4. Read EEPROM
+ *****************/
/* Read the EEPROM */
err = iwl_eeprom_init(priv);
if (err) {
IWL_ERROR("Unable to init EEPROM\n");
goto out_iounmap;
}
- /* MAC Address location in EEPROM same for 3945/4965 */
+ err = iwl_eeprom_check_version(priv);
+ if (err)
+ goto out_iounmap;
+
+ /* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->mac_addr);
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
@@ -7779,19 +4205,18 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/************************
* 5. Setup HW constants
************************/
- /* Device-specific setup */
- if (priv->cfg->ops->lib->set_hw_params(priv)) {
+ if (iwl_set_hw_params(priv)) {
IWL_ERROR("failed to set hw parameters\n");
- goto out_iounmap;
+ goto out_free_eeprom;
}
/*******************
- * 6. Setup hw/priv
+ * 6. Setup priv
*******************/
- err = iwl_setup(priv);
+ err = iwl_init_drv(priv);
if (err)
- goto out_unset_hw_params;
+ goto out_free_eeprom;
/* At this point both hw and priv are initialized. */
/**********************************
@@ -7804,9 +4229,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("Radio disabled.\n");
}
- if (priv->cfg->mod_params->enable_qos)
- priv->qos_data.qos_enable = 1;
-
/********************
* 8. Setup services
********************/
@@ -7817,17 +4239,12 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group);
if (err) {
IWL_ERROR("failed to create sysfs device attributes\n");
- goto out_unset_hw_params;
+ goto out_uninit_drv;
}
- err = iwl_dbgfs_register(priv, DRV_NAME);
- if (err) {
- IWL_ERROR("failed to create debugfs files\n");
- goto out_remove_sysfs;
- }
- iwl4965_setup_deferred_work(priv);
- iwl4965_setup_rx_handlers(priv);
+ iwl_setup_deferred_work(priv);
+ iwl_setup_rx_handlers(priv);
/********************
* 9. Conclude
@@ -7835,14 +4252,31 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_save_state(pdev);
pci_disable_device(pdev);
- /* notify iwlcore to init */
- iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT);
+ /**********************************
+ * 10. Setup and register mac80211
+ **********************************/
+
+ err = iwl_setup_mac(priv);
+ if (err)
+ goto out_remove_sysfs;
+
+ err = iwl_dbgfs_register(priv, DRV_NAME);
+ if (err)
+ IWL_ERROR("failed to create debugfs files\n");
+
+ err = iwl_rfkill_init(priv);
+ if (err)
+ IWL_ERROR("Unable to initialize RFKILL system. "
+ "Ignoring error: %d\n", err);
+ iwl_power_initialize(priv);
return 0;
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
- out_unset_hw_params:
- iwl4965_unset_hw_params(priv);
+ out_uninit_drv:
+ iwl_uninit_drv(priv);
+ out_free_eeprom:
+ iwl_eeprom_free(priv);
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
@@ -7859,8 +4293,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
{
struct iwl_priv *priv = pci_get_drvdata(pdev);
- struct list_head *p, *q;
- int i;
unsigned long flags;
if (!priv)
@@ -7868,6 +4300,9 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+ iwl_dbgfs_unregister(priv);
+ sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
+
if (priv->mac80211_registered) {
ieee80211_unregister_hw(priv->hw);
priv->mac80211_registered = 0;
@@ -7886,26 +4321,15 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
iwl_synchronize_irq(priv);
- /* Free MAC hash list for ADHOC */
- for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
- list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
- list_del(p);
- kfree(list_entry(p, struct iwl4965_ibss_seq, list));
- }
- }
-
- iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT);
- iwl_dbgfs_unregister(priv);
- sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
-
+ iwl_rfkill_unregister(priv);
iwl4965_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
- iwl4965_rx_queue_free(priv, &priv->rxq);
- iwl4965_hw_txq_ctx_free(priv);
+ iwl_rx_queue_free(priv, &priv->rxq);
+ iwl_hw_txq_ctx_free(priv);
- iwl4965_unset_hw_params(priv);
- iwlcore_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
+ iwl_eeprom_free(priv);
/*netif_stop_queue(dev); */
@@ -7922,8 +4346,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- iwl_free_channel_map(priv);
- iwl4965_free_geos(priv);
+ iwl_uninit_drv(priv);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -7973,6 +4396,19 @@ static int iwl4965_pci_resume(struct pci_dev *pdev)
static struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
+#ifdef CONFIG_IWL5000
+ {IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
+ {IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
+ {IWL_PCI_DEVICE(0x4232, 0x1206, iwl5100_abg_cfg)},
+ {IWL_PCI_DEVICE(0x4232, 0x1306, iwl5100_abg_cfg)},
+ {IWL_PCI_DEVICE(0x4232, 0x1326, iwl5100_abg_cfg)},
+ {IWL_PCI_DEVICE(0x4237, 0x1216, iwl5100_abg_cfg)},
+ {IWL_PCI_DEVICE(0x4232, PCI_ANY_ID, iwl5100_agn_cfg)},
+ {IWL_PCI_DEVICE(0x4235, PCI_ANY_ID, iwl5300_agn_cfg)},
+ {IWL_PCI_DEVICE(0x4236, PCI_ANY_ID, iwl5300_agn_cfg)},
+ {IWL_PCI_DEVICE(0x4237, PCI_ANY_ID, iwl5100_agn_cfg)},
+ {IWL_PCI_DEVICE(0x423A, PCI_ANY_ID, iwl5350_agn_cfg)},
+#endif /* CONFIG_IWL5000 */
{0}
};
MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
@@ -8006,20 +4442,9 @@ static int __init iwl4965_init(void)
IWL_ERROR("Unable to initialize PCI module\n");
goto error_register;
}
-#ifdef CONFIG_IWLWIFI_DEBUG
- ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level);
- if (ret) {
- IWL_ERROR("Unable to create driver sysfs file\n");
- goto error_debug;
- }
-#endif
return ret;
-#ifdef CONFIG_IWLWIFI_DEBUG
-error_debug:
- pci_unregister_driver(&iwl_driver);
-#endif
error_register:
iwl4965_rate_control_unregister();
return ret;
@@ -8027,9 +4452,6 @@ error_register:
static void __exit iwl4965_exit(void)
{
-#ifdef CONFIG_IWLWIFI_DEBUG
- driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level);
-#endif
pci_unregister_driver(&iwl_driver);
iwl4965_rate_control_unregister();
}
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index f0724e31adf..02080a3682a 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -1,9 +1,5 @@
-libertas-objs := main.o wext.o \
- rx.o tx.o cmd.o \
- cmdresp.o scan.o \
- 11d.o \
- debugfs.o \
- ethtool.o assoc.o
+libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o \
+ debugfs.o persistcfg.o ethtool.o assoc.o
usb8xxx-objs += if_usb.o
libertas_cs-objs += if_cs.o
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index c9c3640ce9f..a267d6e65f0 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -603,7 +603,8 @@ static int assoc_helper_channel(struct lbs_private *priv,
/* Change mesh channel first; 21.p21 firmware won't let
you change channel otherwise (even though it'll return
an error to this */
- lbs_mesh_config(priv, 0, assoc_req->channel);
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
+ assoc_req->channel);
}
lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
@@ -642,7 +643,8 @@ static int assoc_helper_channel(struct lbs_private *priv,
restore_mesh:
if (priv->mesh_dev)
- lbs_mesh_config(priv, 1, priv->curbssparams.channel);
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->curbssparams.channel);
done:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -1248,7 +1250,7 @@ static int get_common_rates(struct lbs_private *priv,
lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
- if (!priv->auto_rate) {
+ if (!priv->enablehwauto) {
for (i = 0; i < tmp_size; i++) {
if (tmp[i] == priv->cur_rate)
goto done;
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 8124fd9b135..75427e61898 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -4,6 +4,7 @@
*/
#include <net/iw_handler.h>
+#include <net/ieee80211.h>
#include <linux/kfifo.h>
#include "host.h"
#include "hostcmd.h"
@@ -109,7 +110,7 @@ int lbs_update_hw_spec(struct lbs_private *priv)
* CF card firmware 5.0.16p0: cap 0x00000303
* USB dongle firmware 5.110.17p2: cap 0x00000303
*/
- printk("libertas: %s, fw %u.%u.%up%u, cap 0x%08x\n",
+ lbs_pr_info("%s, fw %u.%u.%up%u, cap 0x%08x\n",
print_mac(mac, cmd.permanentaddr),
priv->fwrelease >> 24 & 0xff,
priv->fwrelease >> 16 & 0xff,
@@ -675,58 +676,60 @@ static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
return 0;
}
-static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
- struct cmd_ds_command *cmd,
- u16 cmd_action)
+static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok)
{
- struct cmd_ds_802_11_rate_adapt_rateset
- *rateadapt = &cmd->params.rateset;
-
- lbs_deb_enter(LBS_DEB_CMD);
- cmd->size =
- cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset)
- + S_DS_GEN);
- cmd->command = cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET);
-
- rateadapt->action = cpu_to_le16(cmd_action);
- rateadapt->enablehwauto = cpu_to_le16(priv->enablehwauto);
- rateadapt->bitmap = cpu_to_le16(priv->ratebitmap);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
+/* Bit Rate
+* 15:13 Reserved
+* 12 54 Mbps
+* 11 48 Mbps
+* 10 36 Mbps
+* 9 24 Mbps
+* 8 18 Mbps
+* 7 12 Mbps
+* 6 9 Mbps
+* 5 6 Mbps
+* 4 Reserved
+* 3 11 Mbps
+* 2 5.5 Mbps
+* 1 2 Mbps
+* 0 1 Mbps
+**/
+
+ uint16_t ratemask;
+ int i = lbs_data_rate_to_fw_index(rate);
+ if (lower_rates_ok)
+ ratemask = (0x1fef >> (12 - i));
+ else
+ ratemask = (1 << i);
+ return cpu_to_le16(ratemask);
}
-/**
- * @brief Get the current data rate
- *
- * @param priv A pointer to struct lbs_private structure
- *
- * @return The data rate on success, error on failure
- */
-int lbs_get_data_rate(struct lbs_private *priv)
+int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
+ uint16_t cmd_action)
{
- struct cmd_ds_802_11_data_rate cmd;
- int ret = -1;
+ struct cmd_ds_802_11_rate_adapt_rateset cmd;
+ int ret;
lbs_deb_enter(LBS_DEB_CMD);
- memset(&cmd, 0, sizeof(cmd));
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE);
-
- ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
- if (ret)
- goto out;
+ if (!priv->cur_rate && !priv->enablehwauto)
+ return -EINVAL;
- lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
+ cmd.hdr.size = cpu_to_le16(sizeof(cmd));
- ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]);
- lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret);
+ cmd.action = cpu_to_le16(cmd_action);
+ cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
+ cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
+ ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
+ if (!ret && cmd_action == CMD_ACT_GET) {
+ priv->ratebitmap = le16_to_cpu(cmd.bitmap);
+ priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
+ }
-out:
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
+EXPORT_SYMBOL_GPL(lbs_cmd_802_11_rate_adapt_rateset);
/**
* @brief Set the data rate
@@ -778,28 +781,6 @@ out:
return ret;
}
-static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv,
- struct cmd_ds_command *cmd,
- u16 cmd_action)
-{
- struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
-
- lbs_deb_enter(LBS_DEB_CMD);
- cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
- S_DS_GEN);
- cmd->command = cpu_to_le16(CMD_MAC_MULTICAST_ADR);
-
- lbs_deb_cmd("MULTICAST_ADR: setting %d addresses\n", pMCastAdr->nr_of_adrs);
- pMCastAdr->action = cpu_to_le16(cmd_action);
- pMCastAdr->nr_of_adrs =
- cpu_to_le16((u16) priv->nr_of_multicastmacaddr);
- memcpy(pMCastAdr->maclist, priv->multicastlist,
- priv->nr_of_multicastmacaddr * ETH_ALEN);
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
/**
* @brief Get the radio channel
*
@@ -1052,24 +1033,69 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
return ret;
}
-int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
+int lbs_mesh_config_send(struct lbs_private *priv,
+ struct cmd_ds_mesh_config *cmd,
+ uint16_t action, uint16_t type)
+{
+ int ret;
+
+ lbs_deb_enter(LBS_DEB_CMD);
+
+ cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
+ cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
+ cmd->hdr.result = 0;
+
+ cmd->type = cpu_to_le16(type);
+ cmd->action = cpu_to_le16(action);
+
+ ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+
+ lbs_deb_leave(LBS_DEB_CMD);
+ return ret;
+}
+
+/* This function is the CMD_MESH_CONFIG legacy function. It only handles the
+ * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG
+ * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
+ * lbs_mesh_config_send.
+ */
+int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
{
struct cmd_ds_mesh_config cmd;
+ struct mrvl_meshie *ie;
memset(&cmd, 0, sizeof(cmd));
- cmd.action = cpu_to_le16(enable);
cmd.channel = cpu_to_le16(chan);
- cmd.type = cpu_to_le16(priv->mesh_tlv);
- cmd.hdr.size = cpu_to_le16(sizeof(cmd));
-
- if (enable) {
- cmd.length = cpu_to_le16(priv->mesh_ssid_len);
- memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
+ ie = (struct mrvl_meshie *)cmd.data;
+
+ switch (action) {
+ case CMD_ACT_MESH_CONFIG_START:
+ ie->hdr.id = MFIE_TYPE_GENERIC;
+ ie->val.oui[0] = 0x00;
+ ie->val.oui[1] = 0x50;
+ ie->val.oui[2] = 0x43;
+ ie->val.type = MARVELL_MESH_IE_TYPE;
+ ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
+ ie->val.version = MARVELL_MESH_IE_VERSION;
+ ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
+ ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
+ ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
+ ie->val.mesh_id_len = priv->mesh_ssid_len;
+ memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
+ ie->hdr.len = sizeof(struct mrvl_meshie_val) -
+ IW_ESSID_MAX_SIZE + priv->mesh_ssid_len;
+ cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
+ break;
+ case CMD_ACT_MESH_CONFIG_STOP:
+ break;
+ default:
+ return -1;
}
- lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
- enable, priv->mesh_tlv, chan,
+ lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
+ action, priv->mesh_tlv, chan,
escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
- return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
+
+ return lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
}
static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
@@ -1144,7 +1170,7 @@ static void lbs_submit_command(struct lbs_private *priv,
struct cmd_header *cmd;
uint16_t cmdsize;
uint16_t command;
- int timeo = 5 * HZ;
+ int timeo = 3 * HZ;
int ret;
lbs_deb_enter(LBS_DEB_HOST);
@@ -1162,7 +1188,7 @@ static void lbs_submit_command(struct lbs_private *priv,
/* These commands take longer */
if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
command == CMD_802_11_AUTHENTICATE)
- timeo = 10 * HZ;
+ timeo = 5 * HZ;
lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
command, le16_to_cpu(cmd->seqnum), cmdsize);
@@ -1174,7 +1200,7 @@ static void lbs_submit_command(struct lbs_private *priv,
lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
/* Let the timer kick in and retry, and potentially reset
the whole thing if the condition persists */
- timeo = HZ;
+ timeo = HZ/4;
}
/* Setup the timer after transmit command */
@@ -1279,8 +1305,7 @@ void lbs_set_mac_control(struct lbs_private *priv)
cmd.action = cpu_to_le16(priv->mac_control);
cmd.reserved = 0;
- lbs_cmd_async(priv, CMD_MAC_CONTROL,
- &cmd.hdr, sizeof(cmd));
+ lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
lbs_deb_leave(LBS_DEB_CMD);
}
@@ -1387,15 +1412,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
cmd_action, pdata_buf);
break;
- case CMD_802_11_RATE_ADAPT_RATESET:
- ret = lbs_cmd_802_11_rate_adapt_rateset(priv,
- cmdptr, cmd_action);
- break;
-
- case CMD_MAC_MULTICAST_ADR:
- ret = lbs_cmd_mac_multicast_adr(priv, cmdptr, cmd_action);
- break;
-
case CMD_802_11_MONITOR_MODE:
ret = lbs_cmd_802_11_monitor_mode(cmdptr,
cmd_action, pdata_buf);
@@ -1484,7 +1500,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
break;
default:
- lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no);
+ lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no);
ret = -1;
break;
}
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 3dfc2d43c22..a53b51f8bdb 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -34,18 +34,22 @@ int lbs_update_hw_spec(struct lbs_private *priv);
int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
struct cmd_ds_mesh_access *cmd);
-int lbs_get_data_rate(struct lbs_private *priv);
int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
int lbs_get_channel(struct lbs_private *priv);
int lbs_set_channel(struct lbs_private *priv, u8 channel);
+int lbs_mesh_config_send(struct lbs_private *priv,
+ struct cmd_ds_mesh_config *cmd,
+ uint16_t action, uint16_t type);
int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
int lbs_suspend(struct lbs_private *priv);
-int lbs_resume(struct lbs_private *priv);
+void lbs_resume(struct lbs_private *priv);
+int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
+ uint16_t cmd_action);
int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
uint16_t cmd_action, uint16_t *timeout);
int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 5abecb7673e..24de3c3cf87 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -203,22 +203,6 @@ static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv,
return 0;
}
-static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv,
- struct cmd_ds_command *resp)
-{
- struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;
-
- lbs_deb_enter(LBS_DEB_CMD);
-
- if (rates->action == CMD_ACT_GET) {
- priv->enablehwauto = le16_to_cpu(rates->enablehwauto);
- priv->ratebitmap = le16_to_cpu(rates->bitmap);
- }
-
- lbs_deb_leave(LBS_DEB_CMD);
- return 0;
-}
-
static int lbs_ret_802_11_rssi(struct lbs_private *priv,
struct cmd_ds_command *resp)
{
@@ -316,16 +300,11 @@ static inline int handle_cmd_response(struct lbs_private *priv,
break;
- case CMD_RET(CMD_MAC_MULTICAST_ADR):
case CMD_RET(CMD_802_11_RESET):
case CMD_RET(CMD_802_11_AUTHENTICATE):
case CMD_RET(CMD_802_11_BEACON_STOP):
break;
- case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
- ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
- break;
-
case CMD_RET(CMD_802_11_RSSI):
ret = lbs_ret_802_11_rssi(priv, resp);
break;
@@ -376,8 +355,8 @@ static inline int handle_cmd_response(struct lbs_private *priv,
break;
default:
- lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n",
- le16_to_cpu(resp->command));
+ lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n",
+ le16_to_cpu(resp->command));
break;
}
lbs_deb_leave(LBS_DEB_HOST);
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index b652fa301e1..a8ac974daca 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -60,13 +60,17 @@ void lbs_mac_event_disconnected(struct lbs_private *priv);
void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str);
+/* persistcfg.c */
+void lbs_persist_config_init(struct net_device *net);
+void lbs_persist_config_remove(struct net_device *net);
+
/* main.c */
struct chan_freq_power *lbs_get_region_cfp_table(u8 region,
int *cfp_no);
struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
-int lbs_remove_card(struct lbs_private *priv);
+void lbs_remove_card(struct lbs_private *priv);
int lbs_start_card(struct lbs_private *priv);
-int lbs_stop_card(struct lbs_private *priv);
+void lbs_stop_card(struct lbs_private *priv);
void lbs_host_to_card_done(struct lbs_private *priv);
int lbs_update_channel(struct lbs_private *priv);
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index d3952011106..12e687550bc 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -40,6 +40,7 @@
#define LBS_DEB_THREAD 0x00100000
#define LBS_DEB_HEX 0x00200000
#define LBS_DEB_SDIO 0x00400000
+#define LBS_DEB_SYSFS 0x00800000
extern unsigned int lbs_debug;
@@ -81,7 +82,8 @@ do { if ((lbs_debug & (grp)) == (grp)) \
#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, (dev)->bus_id, ##args)
#define lbs_deb_cs(fmt, args...) LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args)
#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
-#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " thread", fmt, ##args)
+#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
+#define lbs_deb_sysfs(fmt, args...) LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args)
#define lbs_pr_info(format, args...) \
printk(KERN_INFO DRV_NAME": " format, ## args)
@@ -170,6 +172,16 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define MARVELL_MESH_IE_LENGTH 9
+/* Values used to populate the struct mrvl_mesh_ie. The only time you need this
+ * is when enabling the mesh using CMD_MESH_CONFIG.
+ */
+#define MARVELL_MESH_IE_TYPE 4
+#define MARVELL_MESH_IE_SUBTYPE 0
+#define MARVELL_MESH_IE_VERSION 0
+#define MARVELL_MESH_PROTO_ID_HWMP 0
+#define MARVELL_MESH_METRIC_ID 0
+#define MARVELL_MESH_CAPABILITY 0
+
/** INT status Bit Definition*/
#define MRVDRV_TX_DNLD_RDY 0x0001
#define MRVDRV_RX_UPLD_RDY 0x0002
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 0d9edb9b11f..f5bb40c54d8 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -140,6 +140,8 @@ struct lbs_private {
wait_queue_head_t waitq;
struct workqueue_struct *work_thread;
+ struct work_struct mcast_work;
+
/** Scanning */
struct delayed_work scan_work;
struct delayed_work assoc_work;
@@ -151,6 +153,7 @@ struct lbs_private {
/** Hardware access */
int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
+ void (*reset_card) (struct lbs_private *priv);
/* Wake On LAN */
uint32_t wol_criteria;
@@ -234,8 +237,8 @@ struct lbs_private {
/** 802.11 statistics */
// struct cmd_DS_802_11_GET_STAT wlan802_11Stat;
- u16 enablehwauto;
- u16 ratebitmap;
+ uint16_t enablehwauto;
+ uint16_t ratebitmap;
u32 fragthsd;
u32 rtsthsd;
@@ -293,7 +296,6 @@ struct lbs_private {
/** data rate stuff */
u8 cur_rate;
- u8 auto_rate;
/** RF calibration data */
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 3915c3144fa..c92e41b4faf 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -256,6 +256,23 @@ enum cmd_mesh_access_opts {
CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
};
+/* Define actions and types for CMD_MESH_CONFIG */
+enum cmd_mesh_config_actions {
+ CMD_ACT_MESH_CONFIG_STOP = 0,
+ CMD_ACT_MESH_CONFIG_START,
+ CMD_ACT_MESH_CONFIG_SET,
+ CMD_ACT_MESH_CONFIG_GET,
+};
+
+enum cmd_mesh_config_types {
+ CMD_TYPE_MESH_SET_BOOTFLAG = 1,
+ CMD_TYPE_MESH_SET_BOOTTIME,
+ CMD_TYPE_MESH_SET_DEF_CHANNEL,
+ CMD_TYPE_MESH_SET_MESH_IE,
+ CMD_TYPE_MESH_GET_DEFAULTS,
+ CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */
+};
+
/** Card Event definition */
#define MACREG_INT_CODE_TX_PPA_FREE 0
#define MACREG_INT_CODE_TX_DMA_DONE 1
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index f29bc5bbda3..913b480211a 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -219,6 +219,7 @@ struct cmd_ds_mac_control {
};
struct cmd_ds_mac_multicast_adr {
+ struct cmd_header hdr;
__le16 action;
__le16 nr_of_adrs;
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
@@ -499,6 +500,7 @@ struct cmd_ds_802_11_data_rate {
};
struct cmd_ds_802_11_rate_adapt_rateset {
+ struct cmd_header hdr;
__le16 action;
__le16 enablehwauto;
__le16 bitmap;
@@ -702,8 +704,6 @@ struct cmd_ds_command {
struct cmd_ds_802_11_rf_tx_power txp;
struct cmd_ds_802_11_rf_antenna rant;
struct cmd_ds_802_11_monitor_mode monitor;
- struct cmd_ds_802_11_rate_adapt_rateset rateset;
- struct cmd_ds_mac_multicast_adr madr;
struct cmd_ds_802_11_ad_hoc_join adj;
struct cmd_ds_802_11_rssi rssi;
struct cmd_ds_802_11_rssi_rsp rssirsp;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index d075b448da9..04d7a251e3f 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -148,76 +148,149 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
{
int i;
- for (i = 0; i < 1000; i++) {
+ for (i = 0; i < 100000; i++) {
u8 val = if_cs_read8(card, addr);
if (val == reg)
return i;
- udelay(500);
+ udelay(5);
}
return -ETIME;
}
-/* Host control registers and their bit definitions */
-
-#define IF_CS_H_STATUS 0x00000000
-#define IF_CS_H_STATUS_TX_OVER 0x0001
-#define IF_CS_H_STATUS_RX_OVER 0x0002
-#define IF_CS_H_STATUS_DNLD_OVER 0x0004
-
-#define IF_CS_H_INT_CAUSE 0x00000002
-#define IF_CS_H_IC_TX_OVER 0x0001
-#define IF_CS_H_IC_RX_OVER 0x0002
-#define IF_CS_H_IC_DNLD_OVER 0x0004
-#define IF_CS_H_IC_POWER_DOWN 0x0008
-#define IF_CS_H_IC_HOST_EVENT 0x0010
-#define IF_CS_H_IC_MASK 0x001f
-
-#define IF_CS_H_INT_MASK 0x00000004
-#define IF_CS_H_IM_MASK 0x001f
-
-#define IF_CS_H_WRITE_LEN 0x00000014
-
-#define IF_CS_H_WRITE 0x00000016
+/*
+ * First the bitmasks for the host/card interrupt/status registers:
+ */
+#define IF_CS_BIT_TX 0x0001
+#define IF_CS_BIT_RX 0x0002
+#define IF_CS_BIT_COMMAND 0x0004
+#define IF_CS_BIT_RESP 0x0008
+#define IF_CS_BIT_EVENT 0x0010
+#define IF_CS_BIT_MASK 0x001f
-#define IF_CS_H_CMD_LEN 0x00000018
-#define IF_CS_H_CMD 0x0000001A
-#define IF_CS_C_READ_LEN 0x00000024
+/*
+ * It's not really clear to me what the host status register is for. It
+ * needs to be set almost in union with "host int cause". The following
+ * bits from above are used:
+ *
+ * IF_CS_BIT_TX driver downloaded a data packet
+ * IF_CS_BIT_RX driver got a data packet
+ * IF_CS_BIT_COMMAND driver downloaded a command
+ * IF_CS_BIT_RESP not used (has some meaning with powerdown)
+ * IF_CS_BIT_EVENT driver read a host event
+ */
+#define IF_CS_HOST_STATUS 0x00000000
-#define IF_CS_H_READ 0x00000010
+/*
+ * With the host int cause register can the host (that is, Linux) cause
+ * an interrupt in the firmware, to tell the firmware about those events:
+ *
+ * IF_CS_BIT_TX a data packet has been downloaded
+ * IF_CS_BIT_RX a received data packet has retrieved
+ * IF_CS_BIT_COMMAND a firmware block or a command has been downloaded
+ * IF_CS_BIT_RESP not used (has some meaning with powerdown)
+ * IF_CS_BIT_EVENT a host event (link lost etc) has been retrieved
+ */
+#define IF_CS_HOST_INT_CAUSE 0x00000002
-/* Card control registers and their bit definitions */
+/*
+ * The host int mask register is used to enable/disable interrupt. However,
+ * I have the suspicion that disabled interrupts are lost.
+ */
+#define IF_CS_HOST_INT_MASK 0x00000004
-#define IF_CS_C_STATUS 0x00000020
-#define IF_CS_C_S_TX_DNLD_RDY 0x0001
-#define IF_CS_C_S_RX_UPLD_RDY 0x0002
-#define IF_CS_C_S_CMD_DNLD_RDY 0x0004
-#define IF_CS_C_S_CMD_UPLD_RDY 0x0008
-#define IF_CS_C_S_CARDEVENT 0x0010
-#define IF_CS_C_S_MASK 0x001f
-#define IF_CS_C_S_STATUS_MASK 0x7f00
+/*
+ * Used to send or receive data packets:
+ */
+#define IF_CS_WRITE 0x00000016
+#define IF_CS_WRITE_LEN 0x00000014
+#define IF_CS_READ 0x00000010
+#define IF_CS_READ_LEN 0x00000024
-#define IF_CS_C_INT_CAUSE 0x00000022
-#define IF_CS_C_IC_MASK 0x001f
+/*
+ * Used to send commands (and to send firmware block) and to
+ * receive command responses:
+ */
+#define IF_CS_CMD 0x0000001A
+#define IF_CS_CMD_LEN 0x00000018
+#define IF_CS_RESP 0x00000012
+#define IF_CS_RESP_LEN 0x00000030
-#define IF_CS_C_SQ_READ_LOW 0x00000028
-#define IF_CS_C_SQ_HELPER_OK 0x10
+/*
+ * The card status registers shows what the card/firmware actually
+ * accepts:
+ *
+ * IF_CS_BIT_TX you may send a data packet
+ * IF_CS_BIT_RX you may retrieve a data packet
+ * IF_CS_BIT_COMMAND you may send a command
+ * IF_CS_BIT_RESP you may retrieve a command response
+ * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc)
+ *
+ * When reading this register several times, you will get back the same
+ * results --- with one exception: the IF_CS_BIT_EVENT clear itself
+ * automatically.
+ *
+ * Not that we don't rely on BIT_RX,_BIT_RESP or BIT_EVENT because
+ * we handle this via the card int cause register.
+ */
+#define IF_CS_CARD_STATUS 0x00000020
+#define IF_CS_CARD_STATUS_MASK 0x7f00
-#define IF_CS_C_CMD_LEN 0x00000030
+/*
+ * The card int cause register is used by the card/firmware to notify us
+ * about the following events:
+ *
+ * IF_CS_BIT_TX a data packet has successfully been sentx
+ * IF_CS_BIT_RX a data packet has been received and can be retrieved
+ * IF_CS_BIT_COMMAND not used
+ * IF_CS_BIT_RESP the firmware has a command response for us
+ * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc)
+ */
+#define IF_CS_CARD_INT_CAUSE 0x00000022
-#define IF_CS_C_CMD 0x00000012
+/*
+ * This is used to for handshaking with the card's bootloader/helper image
+ * to synchronize downloading of firmware blocks.
+ */
+#define IF_CS_SQ_READ_LOW 0x00000028
+#define IF_CS_SQ_HELPER_OK 0x10
+/*
+ * The scratch register tells us ...
+ *
+ * IF_CS_SCRATCH_BOOT_OK the bootloader runs
+ * IF_CS_SCRATCH_HELPER_OK the helper firmware already runs
+ */
#define IF_CS_SCRATCH 0x0000003F
+#define IF_CS_SCRATCH_BOOT_OK 0x00
+#define IF_CS_SCRATCH_HELPER_OK 0x5a
+/*
+ * Used to detect ancient chips:
+ */
+#define IF_CS_PRODUCT_ID 0x0000001C
+#define IF_CS_CF8385_B1_REV 0x12
/********************************************************************/
-/* I/O */
+/* I/O and interrupt handling */
/********************************************************************/
+static inline void if_cs_enable_ints(struct if_cs_card *card)
+{
+ lbs_deb_enter(LBS_DEB_CS);
+ if_cs_write16(card, IF_CS_HOST_INT_MASK, 0);
+}
+
+static inline void if_cs_disable_ints(struct if_cs_card *card)
+{
+ lbs_deb_enter(LBS_DEB_CS);
+ if_cs_write16(card, IF_CS_HOST_INT_MASK, IF_CS_BIT_MASK);
+}
+
/*
* Called from if_cs_host_to_card to send a command to the hardware
*/
@@ -228,11 +301,12 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
int loops = 0;
lbs_deb_enter(LBS_DEB_CS);
+ if_cs_disable_ints(card);
/* Is hardware ready? */
while (1) {
- u16 val = if_cs_read16(card, IF_CS_C_STATUS);
- if (val & IF_CS_C_S_CMD_DNLD_RDY)
+ u16 status = if_cs_read16(card, IF_CS_CARD_STATUS);
+ if (status & IF_CS_BIT_COMMAND)
break;
if (++loops > 100) {
lbs_pr_err("card not ready for commands\n");
@@ -241,51 +315,56 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
mdelay(1);
}
- if_cs_write16(card, IF_CS_H_CMD_LEN, nb);
+ if_cs_write16(card, IF_CS_CMD_LEN, nb);
- if_cs_write16_rep(card, IF_CS_H_CMD, buf, nb / 2);
+ if_cs_write16_rep(card, IF_CS_CMD, buf, nb / 2);
/* Are we supposed to transfer an odd amount of bytes? */
if (nb & 1)
- if_cs_write8(card, IF_CS_H_CMD, buf[nb-1]);
+ if_cs_write8(card, IF_CS_CMD, buf[nb-1]);
/* "Assert the download over interrupt command in the Host
* status register" */
- if_cs_write16(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER);
+ if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
/* "Assert the download over interrupt command in the Card
* interrupt case register" */
- if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER);
+ if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
ret = 0;
done:
+ if_cs_enable_ints(card);
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
}
-
/*
* Called from if_cs_host_to_card to send a data to the hardware
*/
static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb)
{
struct if_cs_card *card = (struct if_cs_card *)priv->card;
+ u16 status;
lbs_deb_enter(LBS_DEB_CS);
+ if_cs_disable_ints(card);
+
+ status = if_cs_read16(card, IF_CS_CARD_STATUS);
+ BUG_ON((status & IF_CS_BIT_TX) == 0);
- if_cs_write16(card, IF_CS_H_WRITE_LEN, nb);
+ if_cs_write16(card, IF_CS_WRITE_LEN, nb);
/* write even number of bytes, then odd byte if necessary */
- if_cs_write16_rep(card, IF_CS_H_WRITE, buf, nb / 2);
+ if_cs_write16_rep(card, IF_CS_WRITE, buf, nb / 2);
if (nb & 1)
- if_cs_write8(card, IF_CS_H_WRITE, buf[nb-1]);
+ if_cs_write8(card, IF_CS_WRITE, buf[nb-1]);
- if_cs_write16(card, IF_CS_H_STATUS, IF_CS_H_STATUS_TX_OVER);
- if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_STATUS_TX_OVER);
+ if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX);
+ if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX);
+ if_cs_enable_ints(card);
lbs_deb_leave(LBS_DEB_CS);
}
-
/*
* Get the command result out of the card.
*/
@@ -293,27 +372,28 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
{
unsigned long flags;
int ret = -1;
- u16 val;
+ u16 status;
lbs_deb_enter(LBS_DEB_CS);
/* is hardware ready? */
- val = if_cs_read16(priv->card, IF_CS_C_STATUS);
- if ((val & IF_CS_C_S_CMD_UPLD_RDY) == 0) {
- lbs_pr_err("card not ready for CMD\n");
+ status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
+ if ((status & IF_CS_BIT_RESP) == 0) {
+ lbs_pr_err("no cmd response in card\n");
+ *len = 0;
goto out;
}
- *len = if_cs_read16(priv->card, IF_CS_C_CMD_LEN);
+ *len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
goto out;
}
/* read even number of bytes, then odd byte if necessary */
- if_cs_read16_rep(priv->card, IF_CS_C_CMD, data, *len/sizeof(u16));
+ if_cs_read16_rep(priv->card, IF_CS_RESP, data, *len/sizeof(u16));
if (*len & 1)
- data[*len-1] = if_cs_read8(priv->card, IF_CS_C_CMD);
+ data[*len-1] = if_cs_read8(priv->card, IF_CS_RESP);
/* This is a workaround for a firmware that reports too much
* bytes */
@@ -330,7 +410,6 @@ out:
return ret;
}
-
static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
{
struct sk_buff *skb = NULL;
@@ -339,7 +418,7 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
lbs_deb_enter(LBS_DEB_CS);
- len = if_cs_read16(priv->card, IF_CS_C_READ_LEN);
+ len = if_cs_read16(priv->card, IF_CS_READ_LEN);
if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
priv->stats.rx_dropped++;
@@ -354,38 +433,19 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
data = skb->data;
/* read even number of bytes, then odd byte if necessary */
- if_cs_read16_rep(priv->card, IF_CS_H_READ, data, len/sizeof(u16));
+ if_cs_read16_rep(priv->card, IF_CS_READ, data, len/sizeof(u16));
if (len & 1)
- data[len-1] = if_cs_read8(priv->card, IF_CS_H_READ);
+ data[len-1] = if_cs_read8(priv->card, IF_CS_READ);
dat_err:
- if_cs_write16(priv->card, IF_CS_H_STATUS, IF_CS_H_STATUS_RX_OVER);
- if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_RX_OVER);
+ if_cs_write16(priv->card, IF_CS_HOST_STATUS, IF_CS_BIT_RX);
+ if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_RX);
out:
lbs_deb_leave_args(LBS_DEB_CS, "ret %p", skb);
return skb;
}
-
-
-/********************************************************************/
-/* Interrupts */
-/********************************************************************/
-
-static inline void if_cs_enable_ints(struct if_cs_card *card)
-{
- lbs_deb_enter(LBS_DEB_CS);
- if_cs_write16(card, IF_CS_H_INT_MASK, 0);
-}
-
-static inline void if_cs_disable_ints(struct if_cs_card *card)
-{
- lbs_deb_enter(LBS_DEB_CS);
- if_cs_write16(card, IF_CS_H_INT_MASK, IF_CS_H_IM_MASK);
-}
-
-
static irqreturn_t if_cs_interrupt(int irq, void *data)
{
struct if_cs_card *card = data;
@@ -394,10 +454,10 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
lbs_deb_enter(LBS_DEB_CS);
- cause = if_cs_read16(card, IF_CS_C_INT_CAUSE);
- if_cs_write16(card, IF_CS_C_INT_CAUSE, cause & IF_CS_C_IC_MASK);
-
+ /* Ask card interrupt cause register if there is something for us */
+ cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE);
lbs_deb_cs("cause 0x%04x\n", cause);
+
if (cause == 0) {
/* Not for us */
return IRQ_NONE;
@@ -409,11 +469,7 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
return IRQ_HANDLED;
}
- /* TODO: I'm not sure what the best ordering is */
-
- cause = if_cs_read16(card, IF_CS_C_STATUS) & IF_CS_C_S_MASK;
-
- if (cause & IF_CS_C_S_RX_UPLD_RDY) {
+ if (cause & IF_CS_BIT_RX) {
struct sk_buff *skb;
lbs_deb_cs("rx packet\n");
skb = if_cs_receive_data(priv);
@@ -421,16 +477,16 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
lbs_process_rxed_packet(priv, skb);
}
- if (cause & IF_CS_H_IC_TX_OVER) {
- lbs_deb_cs("tx over\n");
+ if (cause & IF_CS_BIT_TX) {
+ lbs_deb_cs("tx done\n");
lbs_host_to_card_done(priv);
}
- if (cause & IF_CS_C_S_CMD_UPLD_RDY) {
+ if (cause & IF_CS_BIT_RESP) {
unsigned long flags;
u8 i;
- lbs_deb_cs("cmd upload ready\n");
+ lbs_deb_cs("cmd resp\n");
spin_lock_irqsave(&priv->driver_lock, flags);
i = (priv->resp_idx == 0) ? 1 : 0;
spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -444,15 +500,17 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
spin_unlock_irqrestore(&priv->driver_lock, flags);
}
- if (cause & IF_CS_H_IC_HOST_EVENT) {
- u16 event = if_cs_read16(priv->card, IF_CS_C_STATUS)
- & IF_CS_C_S_STATUS_MASK;
- if_cs_write16(priv->card, IF_CS_H_INT_CAUSE,
- IF_CS_H_IC_HOST_EVENT);
- lbs_deb_cs("eventcause 0x%04x\n", event);
- lbs_queue_event(priv, event >> 8 & 0xff);
+ if (cause & IF_CS_BIT_EVENT) {
+ u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
+ if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE,
+ IF_CS_BIT_EVENT);
+ lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8);
}
+ /* Clear interrupt cause */
+ if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK);
+
+ lbs_deb_leave(LBS_DEB_CS);
return IRQ_HANDLED;
}
@@ -482,11 +540,11 @@ static int if_cs_prog_helper(struct if_cs_card *card)
/* "If the value is 0x5a, the firmware is already
* downloaded successfully"
*/
- if (scratch == 0x5a)
+ if (scratch == IF_CS_SCRATCH_HELPER_OK)
goto done;
/* "If the value is != 00, it is invalid value of register */
- if (scratch != 0x00) {
+ if (scratch != IF_CS_SCRATCH_BOOT_OK) {
ret = -ENODEV;
goto done;
}
@@ -514,26 +572,26 @@ static int if_cs_prog_helper(struct if_cs_card *card)
/* "write the number of bytes to be sent to the I/O Command
* write length register" */
- if_cs_write16(card, IF_CS_H_CMD_LEN, count);
+ if_cs_write16(card, IF_CS_CMD_LEN, count);
/* "write this to I/O Command port register as 16 bit writes */
if (count)
- if_cs_write16_rep(card, IF_CS_H_CMD,
+ if_cs_write16_rep(card, IF_CS_CMD,
&fw->data[sent],
count >> 1);
/* "Assert the download over interrupt command in the Host
* status register" */
- if_cs_write8(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER);
+ if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
/* "Assert the download over interrupt command in the Card
* interrupt case register" */
- if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER);
+ if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
/* "The host polls the Card Status register ... for 50 ms before
declaring a failure */
- ret = if_cs_poll_while_fw_download(card, IF_CS_C_STATUS,
- IF_CS_C_S_CMD_DNLD_RDY);
+ ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
+ IF_CS_BIT_COMMAND);
if (ret < 0) {
lbs_pr_err("can't download helper at 0x%x, ret %d\n",
sent, ret);
@@ -575,14 +633,15 @@ static int if_cs_prog_real(struct if_cs_card *card)
}
lbs_deb_cs("fw size %td\n", fw->size);
- ret = if_cs_poll_while_fw_download(card, IF_CS_C_SQ_READ_LOW, IF_CS_C_SQ_HELPER_OK);
+ ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
+ IF_CS_SQ_HELPER_OK);
if (ret < 0) {
lbs_pr_err("helper firmware doesn't answer\n");
goto err_release;
}
for (sent = 0; sent < fw->size; sent += len) {
- len = if_cs_read16(card, IF_CS_C_SQ_READ_LOW);
+ len = if_cs_read16(card, IF_CS_SQ_READ_LOW);
if (len & 1) {
retry++;
lbs_pr_info("odd, need to retry this firmware block\n");
@@ -600,16 +659,16 @@ static int if_cs_prog_real(struct if_cs_card *card)
}
- if_cs_write16(card, IF_CS_H_CMD_LEN, len);
+ if_cs_write16(card, IF_CS_CMD_LEN, len);
- if_cs_write16_rep(card, IF_CS_H_CMD,
+ if_cs_write16_rep(card, IF_CS_CMD,
&fw->data[sent],
(len+1) >> 1);
- if_cs_write8(card, IF_CS_H_STATUS, IF_CS_H_STATUS_DNLD_OVER);
- if_cs_write16(card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_DNLD_OVER);
+ if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
+ if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
- ret = if_cs_poll_while_fw_download(card, IF_CS_C_STATUS,
- IF_CS_C_S_CMD_DNLD_RDY);
+ ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
+ IF_CS_BIT_COMMAND);
if (ret < 0) {
lbs_pr_err("can't download firmware at 0x%x\n", sent);
goto err_release;
@@ -806,6 +865,12 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->irq.AssignedIRQ, p_dev->io.BasePort1,
p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
+ /* Check if we have a current silicon */
+ if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) {
+ lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");
+ ret = -ENODEV;
+ goto out2;
+ }
/* Load the firmware early, before calling into libertas.ko */
ret = if_cs_prog_helper(card);
@@ -837,7 +902,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
/* Clear any interrupt cause that happend while sending
* firmware/initializing card */
- if_cs_write16(card, IF_CS_C_INT_CAUSE, IF_CS_C_IC_MASK);
+ if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
if_cs_enable_ints(card);
/* And finally bring the card up */
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 4dcd4092e0f..632c291404a 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -7,6 +7,10 @@
#include <linux/netdevice.h>
#include <linux/usb.h>
+#ifdef CONFIG_OLPC
+#include <asm/olpc.h>
+#endif
+
#define DRV_NAME "usb8xxx"
#include "host.h"
@@ -146,6 +150,14 @@ static void if_usb_fw_timeo(unsigned long priv)
wake_up(&cardp->fw_wq);
}
+#ifdef CONFIG_OLPC
+static void if_usb_reset_olpc_card(struct lbs_private *priv)
+{
+ printk(KERN_CRIT "Resetting OLPC wireless via EC...\n");
+ olpc_ec_cmd(0x25, NULL, 0, NULL, 0);
+}
+#endif
+
/**
* @brief sets the configuration values
* @param ifnum interface number
@@ -231,6 +243,11 @@ static int if_usb_probe(struct usb_interface *intf,
cardp->priv->fw_ready = 1;
priv->hw_host_to_card = if_usb_host_to_card;
+#ifdef CONFIG_OLPC
+ if (machine_is_olpc())
+ priv->reset_card = if_usb_reset_olpc_card;
+#endif
+
cardp->boot2_version = udev->descriptor.bcdDevice;
if_usb_submit_rx_urb(cardp);
@@ -364,6 +381,11 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
ret = usb_reset_device(cardp->udev);
msleep(100);
+#ifdef CONFIG_OLPC
+ if (ret && machine_is_olpc())
+ if_usb_reset_olpc_card(NULL);
+#endif
+
lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
return ret;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index acfc4bfcc26..14d5d61cec4 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -11,6 +11,7 @@
#include <linux/if_arp.h>
#include <linux/kthread.h>
#include <linux/kfifo.h>
+#include <linux/stddef.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
@@ -343,14 +344,15 @@ static ssize_t lbs_mesh_set(struct device *dev,
{
struct lbs_private *priv = to_net_dev(dev)->priv;
int enable;
- int ret;
+ int ret, action = CMD_ACT_MESH_CONFIG_STOP;
sscanf(buf, "%x", &enable);
enable = !!enable;
if (enable == !!priv->mesh_dev)
return count;
-
- ret = lbs_mesh_config(priv, enable, priv->curbssparams.channel);
+ if (enable)
+ action = CMD_ACT_MESH_CONFIG_START;
+ ret = lbs_mesh_config(priv, action, priv->curbssparams.channel);
if (ret)
return ret;
@@ -446,6 +448,8 @@ static int lbs_mesh_stop(struct net_device *dev)
spin_unlock_irq(&priv->driver_lock);
+ schedule_work(&priv->mcast_work);
+
lbs_deb_leave(LBS_DEB_MESH);
return 0;
}
@@ -467,6 +471,8 @@ static int lbs_eth_stop(struct net_device *dev)
netif_stop_queue(dev);
spin_unlock_irq(&priv->driver_lock);
+ schedule_work(&priv->mcast_work);
+
lbs_deb_leave(LBS_DEB_NET);
return 0;
}
@@ -563,89 +569,116 @@ done:
return ret;
}
-static int lbs_copy_multicast_address(struct lbs_private *priv,
- struct net_device *dev)
+
+static inline int mac_in_list(unsigned char *list, int list_len,
+ unsigned char *mac)
{
- int i = 0;
- struct dev_mc_list *mcptr = dev->mc_list;
+ while (list_len) {
+ if (!memcmp(list, mac, ETH_ALEN))
+ return 1;
+ list += ETH_ALEN;
+ list_len--;
+ }
+ return 0;
+}
+
+
+static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
+ struct net_device *dev, int nr_addrs)
+{
+ int i = nr_addrs;
+ struct dev_mc_list *mc_list;
+ DECLARE_MAC_BUF(mac);
+
+ if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
+ return nr_addrs;
+
+ netif_addr_lock_bh(dev);
+ for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
+ if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
+ lbs_deb_net("mcast address %s:%s skipped\n", dev->name,
+ print_mac(mac, mc_list->dmi_addr));
+ continue;
+ }
- for (i = 0; i < dev->mc_count; i++) {
- memcpy(&priv->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
- mcptr = mcptr->next;
+ if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
+ break;
+ memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN);
+ lbs_deb_net("mcast address %s:%s added to filter\n", dev->name,
+ print_mac(mac, mc_list->dmi_addr));
+ i++;
}
+ netif_addr_unlock_bh(dev);
+ if (mc_list)
+ return -EOVERFLOW;
+
return i;
}
-static void lbs_set_multicast_list(struct net_device *dev)
+static void lbs_set_mcast_worker(struct work_struct *work)
{
- struct lbs_private *priv = dev->priv;
- int old_mac_control;
- DECLARE_MAC_BUF(mac);
+ struct lbs_private *priv = container_of(work, struct lbs_private, mcast_work);
+ struct cmd_ds_mac_multicast_adr mcast_cmd;
+ int dev_flags;
+ int nr_addrs;
+ int old_mac_control = priv->mac_control;
lbs_deb_enter(LBS_DEB_NET);
- old_mac_control = priv->mac_control;
-
- if (dev->flags & IFF_PROMISC) {
- lbs_deb_net("enable promiscuous mode\n");
- priv->mac_control |=
- CMD_ACT_MAC_PROMISCUOUS_ENABLE;
- priv->mac_control &=
- ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
- CMD_ACT_MAC_MULTICAST_ENABLE);
- } else {
- /* Multicast */
- priv->mac_control &=
- ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
-
- if (dev->flags & IFF_ALLMULTI || dev->mc_count >
- MRVDRV_MAX_MULTICAST_LIST_SIZE) {
- lbs_deb_net( "enabling all multicast\n");
- priv->mac_control |=
- CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
- priv->mac_control &=
- ~CMD_ACT_MAC_MULTICAST_ENABLE;
- } else {
- priv->mac_control &=
- ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
-
- if (!dev->mc_count) {
- lbs_deb_net("no multicast addresses, "
- "disabling multicast\n");
- priv->mac_control &=
- ~CMD_ACT_MAC_MULTICAST_ENABLE;
- } else {
- int i;
-
- priv->mac_control |=
- CMD_ACT_MAC_MULTICAST_ENABLE;
-
- priv->nr_of_multicastmacaddr =
- lbs_copy_multicast_address(priv, dev);
-
- lbs_deb_net("multicast addresses: %d\n",
- dev->mc_count);
-
- for (i = 0; i < dev->mc_count; i++) {
- lbs_deb_net("Multicast address %d: %s\n",
- i, print_mac(mac,
- priv->multicastlist[i]));
- }
- /* send multicast addresses to firmware */
- lbs_prepare_and_send_command(priv,
- CMD_MAC_MULTICAST_ADR,
- CMD_ACT_SET, 0, 0,
- NULL);
- }
- }
+ dev_flags = priv->dev->flags;
+ if (priv->mesh_dev)
+ dev_flags |= priv->mesh_dev->flags;
+
+ if (dev_flags & IFF_PROMISC) {
+ priv->mac_control |= CMD_ACT_MAC_PROMISCUOUS_ENABLE;
+ priv->mac_control &= ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
+ CMD_ACT_MAC_MULTICAST_ENABLE);
+ goto out_set_mac_control;
+ } else if (dev_flags & IFF_ALLMULTI) {
+ do_allmulti:
+ priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
+ priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
+ CMD_ACT_MAC_MULTICAST_ENABLE);
+ goto out_set_mac_control;
}
+ /* Once for priv->dev, again for priv->mesh_dev if it exists */
+ nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->dev, 0);
+ if (nr_addrs >= 0 && priv->mesh_dev)
+ nr_addrs = lbs_add_mcast_addrs(&mcast_cmd, priv->mesh_dev, nr_addrs);
+ if (nr_addrs < 0)
+ goto do_allmulti;
+
+ if (nr_addrs) {
+ int size = offsetof(struct cmd_ds_mac_multicast_adr,
+ maclist[6*nr_addrs]);
+
+ mcast_cmd.action = cpu_to_le16(CMD_ACT_SET);
+ mcast_cmd.hdr.size = cpu_to_le16(size);
+ mcast_cmd.nr_of_adrs = cpu_to_le16(nr_addrs);
+
+ lbs_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &mcast_cmd.hdr, size);
+
+ priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
+ } else
+ priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
+
+ priv->mac_control &= ~(CMD_ACT_MAC_PROMISCUOUS_ENABLE |
+ CMD_ACT_MAC_ALL_MULTICAST_ENABLE);
+ out_set_mac_control:
if (priv->mac_control != old_mac_control)
lbs_set_mac_control(priv);
lbs_deb_leave(LBS_DEB_NET);
}
+static void lbs_set_multicast_list(struct net_device *dev)
+{
+ struct lbs_private *priv = dev->priv;
+
+ schedule_work(&priv->mcast_work);
+}
+
/**
* @brief This function handles the major jobs in the LBS driver.
* It handles all events generated by firmware, RX data received
@@ -689,20 +722,20 @@ static int lbs_thread(void *data)
shouldsleep = 1; /* Something is en route to the device already */
else if (priv->tx_pending_len > 0)
shouldsleep = 0; /* We've a packet to send */
+ else if (priv->resp_len[priv->resp_idx])
+ shouldsleep = 0; /* We have a command response */
else if (priv->cur_cmd)
shouldsleep = 1; /* Can't send a command; one already running */
else if (!list_empty(&priv->cmdpendingq))
shouldsleep = 0; /* We have a command to send */
else if (__kfifo_len(priv->event_fifo))
shouldsleep = 0; /* We have an event to process */
- else if (priv->resp_len[priv->resp_idx])
- shouldsleep = 0; /* We have a command response */
else
shouldsleep = 1; /* No command */
if (shouldsleep) {
lbs_deb_thread("sleeping, connect_status %d, "
- "ps_mode %d, ps_state %d\n",
+ "psmode %d, psstate %d\n",
priv->connect_status,
priv->psmode, priv->psstate);
spin_unlock_irq(&priv->driver_lock);
@@ -749,16 +782,21 @@ static int lbs_thread(void *data)
if (priv->cmd_timed_out && priv->cur_cmd) {
struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
- if (++priv->nr_retries > 10) {
- lbs_pr_info("Excessive timeouts submitting command %x\n",
- le16_to_cpu(cmdnode->cmdbuf->command));
+ if (++priv->nr_retries > 3) {
+ lbs_pr_info("Excessive timeouts submitting "
+ "command 0x%04x\n",
+ le16_to_cpu(cmdnode->cmdbuf->command));
lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
priv->nr_retries = 0;
+ if (priv->reset_card)
+ priv->reset_card(priv);
} else {
priv->cur_cmd = NULL;
priv->dnld_sent = DNLD_RES_RECEIVED;
- lbs_pr_info("requeueing command %x due to timeout (#%d)\n",
- le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries);
+ lbs_pr_info("requeueing command 0x%04x due "
+ "to timeout (#%d)\n",
+ le16_to_cpu(cmdnode->cmdbuf->command),
+ priv->nr_retries);
/* Stick it back at the _top_ of the pending queue
for immediate resubmission */
@@ -890,7 +928,7 @@ int lbs_suspend(struct lbs_private *priv)
}
EXPORT_SYMBOL_GPL(lbs_suspend);
-int lbs_resume(struct lbs_private *priv)
+void lbs_resume(struct lbs_private *priv)
{
lbs_deb_enter(LBS_DEB_FW);
@@ -906,7 +944,6 @@ int lbs_resume(struct lbs_private *priv)
netif_device_attach(priv->mesh_dev);
lbs_deb_leave(LBS_DEB_FW);
- return 0;
}
EXPORT_SYMBOL_GPL(lbs_resume);
@@ -929,20 +966,10 @@ static int lbs_setup_firmware(struct lbs_private *priv)
*/
memset(priv->current_addr, 0xff, ETH_ALEN);
ret = lbs_update_hw_spec(priv);
- if (ret) {
- ret = -1;
+ if (ret)
goto done;
- }
lbs_set_mac_control(priv);
-
- ret = lbs_get_data_rate(priv);
- if (ret < 0) {
- ret = -1;
- goto done;
- }
-
- ret = 0;
done:
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
return ret;
@@ -960,12 +987,11 @@ static void command_timer_fn(unsigned long data)
lbs_deb_enter(LBS_DEB_CMD);
spin_lock_irqsave(&priv->driver_lock, flags);
- if (!priv->cur_cmd) {
- lbs_pr_info("Command timer expired; no pending command\n");
+ if (!priv->cur_cmd)
goto out;
- }
- lbs_pr_info("Command %x timed out\n", le16_to_cpu(priv->cur_cmd->cmdbuf->command));
+ lbs_pr_info("command 0x%04x timed out\n",
+ le16_to_cpu(priv->cur_cmd->cmdbuf->command));
priv->cmd_timed_out = 1;
wake_up_interruptible(&priv->waitq);
@@ -1019,7 +1045,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
priv->radioon = RADIO_ON;
- priv->auto_rate = 1;
+ priv->enablehwauto = 1;
priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
priv->psmode = LBS802_11POWERMODECAM;
priv->psstate = PS_STATE_FULL_POWER;
@@ -1134,6 +1160,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->work_thread = create_singlethread_workqueue("lbs_worker");
INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
+ INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
sprintf(priv->mesh_ssid, "mesh");
@@ -1156,7 +1183,7 @@ done:
EXPORT_SYMBOL_GPL(lbs_add_card);
-int lbs_remove_card(struct lbs_private *priv)
+void lbs_remove_card(struct lbs_private *priv)
{
struct net_device *dev = priv->dev;
union iwreq_data wrqu;
@@ -1168,8 +1195,9 @@ int lbs_remove_card(struct lbs_private *priv)
dev = priv->dev;
- cancel_delayed_work(&priv->scan_work);
- cancel_delayed_work(&priv->assoc_work);
+ cancel_delayed_work_sync(&priv->scan_work);
+ cancel_delayed_work_sync(&priv->assoc_work);
+ cancel_work_sync(&priv->mcast_work);
destroy_workqueue(priv->work_thread);
if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
@@ -1191,7 +1219,6 @@ int lbs_remove_card(struct lbs_private *priv)
free_netdev(dev);
lbs_deb_leave(LBS_DEB_MAIN);
- return 0;
}
EXPORT_SYMBOL_GPL(lbs_remove_card);
@@ -1236,9 +1263,11 @@ int lbs_start_card(struct lbs_private *priv)
useful */
priv->mesh_tlv = 0x100 + 291;
- if (lbs_mesh_config(priv, 1, priv->curbssparams.channel)) {
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->curbssparams.channel)) {
priv->mesh_tlv = 0x100 + 37;
- if (lbs_mesh_config(priv, 1, priv->curbssparams.channel))
+ if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->curbssparams.channel))
priv->mesh_tlv = 0;
}
if (priv->mesh_tlv) {
@@ -1262,24 +1291,28 @@ done:
EXPORT_SYMBOL_GPL(lbs_start_card);
-int lbs_stop_card(struct lbs_private *priv)
+void lbs_stop_card(struct lbs_private *priv)
{
struct net_device *dev = priv->dev;
- int ret = -1;
struct cmd_ctrl_node *cmdnode;
unsigned long flags;
lbs_deb_enter(LBS_DEB_MAIN);
+ if (!priv)
+ goto out;
+
netif_stop_queue(priv->dev);
netif_carrier_off(priv->dev);
lbs_debugfs_remove_one(priv);
device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
- if (priv->mesh_tlv)
+ if (priv->mesh_tlv) {
device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+ }
/* Flush pending command nodes */
+ del_timer_sync(&priv->command_timer);
spin_lock_irqsave(&priv->driver_lock, flags);
list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
cmdnode->result = -ENOENT;
@@ -1290,8 +1323,8 @@ int lbs_stop_card(struct lbs_private *priv)
unregister_netdev(dev);
- lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
- return ret;
+out:
+ lbs_deb_leave(LBS_DEB_MAIN);
}
EXPORT_SYMBOL_GPL(lbs_stop_card);
@@ -1332,6 +1365,8 @@ static int lbs_add_mesh(struct lbs_private *priv)
#ifdef WIRELESS_EXT
mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
#endif
+ mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+ mesh_dev->set_multicast_list = lbs_set_multicast_list;
/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
@@ -1343,6 +1378,8 @@ static int lbs_add_mesh(struct lbs_private *priv)
if (ret)
goto err_unregister;
+ lbs_persist_config_init(mesh_dev);
+
/* Everything successful */
ret = 0;
goto done;
@@ -1369,8 +1406,9 @@ static void lbs_remove_mesh(struct lbs_private *priv)
lbs_deb_enter(LBS_DEB_MESH);
netif_stop_queue(mesh_dev);
- netif_carrier_off(priv->mesh_dev);
+ netif_carrier_off(mesh_dev);
sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
+ lbs_persist_config_remove(mesh_dev);
unregister_netdev(mesh_dev);
priv->mesh_dev = NULL;
free_netdev(mesh_dev);
@@ -1533,10 +1571,11 @@ static void lbs_remove_rtap(struct lbs_private *priv)
{
lbs_deb_enter(LBS_DEB_MAIN);
if (priv->rtap_net_dev == NULL)
- return;
+ goto out;
unregister_netdev(priv->rtap_net_dev);
free_netdev(priv->rtap_net_dev);
priv->rtap_net_dev = NULL;
+out:
lbs_deb_leave(LBS_DEB_MAIN);
}
@@ -1563,7 +1602,6 @@ static int lbs_add_rtap(struct lbs_private *priv)
rtap_dev->stop = lbs_rtap_stop;
rtap_dev->get_stats = lbs_rtap_get_stats;
rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
- rtap_dev->set_multicast_list = lbs_set_multicast_list;
rtap_dev->priv = priv;
SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
diff --git a/drivers/net/wireless/libertas/persistcfg.c b/drivers/net/wireless/libertas/persistcfg.c
new file mode 100644
index 00000000000..6d0ff8decaf
--- /dev/null
+++ b/drivers/net/wireless/libertas/persistcfg.c
@@ -0,0 +1,453 @@
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/kthread.h>
+#include <linux/kfifo.h>
+
+#include "host.h"
+#include "decl.h"
+#include "dev.h"
+#include "wext.h"
+#include "debugfs.h"
+#include "scan.h"
+#include "assoc.h"
+#include "cmd.h"
+
+static int mesh_get_default_parameters(struct device *dev,
+ struct mrvl_mesh_defaults *defs)
+{
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ struct cmd_ds_mesh_config cmd;
+ int ret;
+
+ memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
+ CMD_TYPE_MESH_GET_DEFAULTS);
+
+ if (ret)
+ return -EOPNOTSUPP;
+
+ memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
+
+ return 0;
+}
+
+/**
+ * @brief Get function for sysfs attribute bootflag
+ */
+static ssize_t bootflag_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 12, "0x%x\n", le32_to_cpu(defs.bootflag));
+}
+
+/**
+ * @brief Set function for sysfs attribute bootflag
+ */
+static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ struct cmd_ds_mesh_config cmd;
+ uint32_t datum;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+ ret = sscanf(buf, "%x", &datum);
+ if (ret != 1)
+ return -EINVAL;
+
+ *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
+ cmd.length = cpu_to_le16(sizeof(uint32_t));
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_BOOTFLAG);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute boottime
+ */
+static ssize_t boottime_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 12, "0x%x\n", defs.boottime);
+}
+
+/**
+ * @brief Set function for sysfs attribute boottime
+ */
+static ssize_t boottime_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ struct cmd_ds_mesh_config cmd;
+ uint32_t datum;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+ ret = sscanf(buf, "%x", &datum);
+ if (ret != 1)
+ return -EINVAL;
+
+ /* A too small boot time will result in the device booting into
+ * standalone (no-host) mode before the host can take control of it,
+ * so the change will be hard to revert. This may be a desired
+ * feature (e.g to configure a very fast boot time for devices that
+ * will not be attached to a host), but dangerous. So I'm enforcing a
+ * lower limit of 20 seconds: remove and recompile the driver if this
+ * does not work for you.
+ */
+ datum = (datum < 20) ? 20 : datum;
+ cmd.data[0] = datum;
+ cmd.length = cpu_to_le16(sizeof(uint8_t));
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_BOOTTIME);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute channel
+ */
+static ssize_t channel_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 12, "0x%x\n", le16_to_cpu(defs.channel));
+}
+
+/**
+ * @brief Set function for sysfs attribute channel
+ */
+static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ struct cmd_ds_mesh_config cmd;
+ uint16_t datum;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+ ret = sscanf(buf, "%hx", &datum);
+ if (ret != 1 || datum < 1 || datum > 11)
+ return -EINVAL;
+
+ *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
+ cmd.length = cpu_to_le16(sizeof(uint16_t));
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_DEF_CHANNEL);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute mesh_id
+ */
+static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int maxlen;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ if (defs.meshie.val.mesh_id_len > IW_ESSID_MAX_SIZE) {
+ lbs_pr_err("inconsistent mesh ID length");
+ defs.meshie.val.mesh_id_len = IW_ESSID_MAX_SIZE;
+ }
+
+ /* SSID not null terminated: reserve room for \0 + \n */
+ maxlen = defs.meshie.val.mesh_id_len + 2;
+ maxlen = (PAGE_SIZE > maxlen) ? maxlen : PAGE_SIZE;
+
+ defs.meshie.val.mesh_id[defs.meshie.val.mesh_id_len] = '\0';
+
+ return snprintf(buf, maxlen, "%s\n", defs.meshie.val.mesh_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute mesh_id
+ */
+static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct cmd_ds_mesh_config cmd;
+ struct mrvl_mesh_defaults defs;
+ struct mrvl_meshie *ie;
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ int len;
+ int ret;
+
+ if (count < 2 || count > IW_ESSID_MAX_SIZE + 1)
+ return -EINVAL;
+
+ memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
+ ie = (struct mrvl_meshie *) &cmd.data[0];
+
+ /* fetch all other Information Element parameters */
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+ /* transfer IE elements */
+ memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+
+ len = count - 1;
+ memcpy(ie->val.mesh_id, buf, len);
+ /* SSID len */
+ ie->val.mesh_id_len = len;
+ /* IE len */
+ ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
+
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_MESH_IE);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute protocol_id
+ */
+static ssize_t protocol_id_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute protocol_id
+ */
+static ssize_t protocol_id_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct cmd_ds_mesh_config cmd;
+ struct mrvl_mesh_defaults defs;
+ struct mrvl_meshie *ie;
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ uint32_t datum;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+ ret = sscanf(buf, "%x", &datum);
+ if (ret != 1)
+ return -EINVAL;
+
+ /* fetch all other Information Element parameters */
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+ /* transfer IE elements */
+ ie = (struct mrvl_meshie *) &cmd.data[0];
+ memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+ /* update protocol id */
+ ie->val.active_protocol_id = datum;
+
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_MESH_IE);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute metric_id
+ */
+static ssize_t metric_id_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
+}
+
+/**
+ * @brief Set function for sysfs attribute metric_id
+ */
+static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct cmd_ds_mesh_config cmd;
+ struct mrvl_mesh_defaults defs;
+ struct mrvl_meshie *ie;
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ uint32_t datum;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+ ret = sscanf(buf, "%x", &datum);
+ if (ret != 1)
+ return -EINVAL;
+
+ /* fetch all other Information Element parameters */
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+ /* transfer IE elements */
+ ie = (struct mrvl_meshie *) &cmd.data[0];
+ memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+ /* update metric id */
+ ie->val.active_metric_id = datum;
+
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_MESH_IE);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+/**
+ * @brief Get function for sysfs attribute capability
+ */
+static ssize_t capability_get(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mrvl_mesh_defaults defs;
+ int ret;
+
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ if (ret)
+ return ret;
+
+ return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
+}
+
+/**
+ * @brief Set function for sysfs attribute capability
+ */
+static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct cmd_ds_mesh_config cmd;
+ struct mrvl_mesh_defaults defs;
+ struct mrvl_meshie *ie;
+ struct lbs_private *priv = to_net_dev(dev)->priv;
+ uint32_t datum;
+ int ret;
+
+ memset(&cmd, 0, sizeof(cmd));
+ ret = sscanf(buf, "%x", &datum);
+ if (ret != 1)
+ return -EINVAL;
+
+ /* fetch all other Information Element parameters */
+ ret = mesh_get_default_parameters(dev, &defs);
+
+ cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
+
+ /* transfer IE elements */
+ ie = (struct mrvl_meshie *) &cmd.data[0];
+ memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
+ /* update value */
+ ie->val.mesh_capability = datum;
+
+ ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
+ CMD_TYPE_MESH_SET_MESH_IE);
+ if (ret)
+ return ret;
+
+ return strlen(buf);
+}
+
+
+static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
+static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
+static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
+static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
+static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
+static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
+static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
+
+static struct attribute *boot_opts_attrs[] = {
+ &dev_attr_bootflag.attr,
+ &dev_attr_boottime.attr,
+ &dev_attr_channel.attr,
+ NULL
+};
+
+static struct attribute_group boot_opts_group = {
+ .name = "boot_options",
+ .attrs = boot_opts_attrs,
+};
+
+static struct attribute *mesh_ie_attrs[] = {
+ &dev_attr_mesh_id.attr,
+ &dev_attr_protocol_id.attr,
+ &dev_attr_metric_id.attr,
+ &dev_attr_capability.attr,
+ NULL
+};
+
+static struct attribute_group mesh_ie_group = {
+ .name = "mesh_ie",
+ .attrs = mesh_ie_attrs,
+};
+
+void lbs_persist_config_init(struct net_device *dev)
+{
+ int ret;
+ ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
+ ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
+}
+
+void lbs_persist_config_remove(struct net_device *dev)
+{
+ sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
+ sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
+}
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 05af7316f69..5749f22b296 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -237,7 +237,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
/* Take the data rate from the rxpd structure
* only if the rate is auto
*/
- if (priv->auto_rate)
+ if (priv->enablehwauto)
priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
lbs_compute_rssi(priv, p_rx_pd);
@@ -383,7 +383,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
/* Take the data rate from the rxpd structure
* only if the rate is auto
*/
- if (priv->auto_rate)
+ if (priv->enablehwauto)
priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
lbs_compute_rssi(priv, prxpd);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 387d4878af2..4b274562f96 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -776,8 +776,9 @@ out:
#define MAX_CUSTOM_LEN 64
static inline char *lbs_translate_scan(struct lbs_private *priv,
- char *start, char *stop,
- struct bss_descriptor *bss)
+ struct iw_request_info *info,
+ char *start, char *stop,
+ struct bss_descriptor *bss)
{
struct chan_freq_power *cfp;
char *current_val; /* For rates */
@@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
/* Mode */
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = bss->mode;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
/* Frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000;
iwe.u.freq.e = 1;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
iwe.u.qual.level = CAL_RSSI(snr, nf);
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
- current_val = start + IW_EV_LCP_LEN;
+ current_val = start + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
@@ -874,19 +875,19 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
/* Bit rate given in 500 kb/s units */
iwe.u.bitrate.value = bss->rates[j] * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
&& !lbs_ssid_cmp(priv->curbssparams.ssid,
priv->curbssparams.ssid_len,
bss->ssid, bss->ssid_len)) {
iwe.u.bitrate.value = 22 * 500000;
- current_val = iwe_stream_add_value(start, current_val,
+ current_val = iwe_stream_add_value(info, start, current_val,
stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
- if((current_val - start) > IW_EV_LCP_LEN)
+ if ((current_val - start) > iwe_stream_lcp_len(info))
start = current_val;
memset(&iwe, 0, sizeof(iwe));
@@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
if (bss->mesh) {
@@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, custom);
}
out:
@@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
}
/* Translate to WE format this entry */
- next_ev = lbs_translate_scan(priv, ev, stop, iter_bss);
+ next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss);
if (next_ev == NULL)
continue;
ev = next_ev;
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index 4031be42086..e0c2599da92 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -6,6 +6,8 @@
#include <linux/if_ether.h>
#include <asm/byteorder.h>
+#include <linux/wireless.h>
+#include <net/ieee80211.h>
struct ieeetypes_cfparamset {
u8 elementid;
@@ -252,4 +254,32 @@ struct mrvlietypes_ledbhv {
struct led_bhv ledbhv[1];
} __attribute__ ((packed));
+/* Meant to be packed as the value member of a struct ieee80211_info_element.
+ * Note that the len member of the ieee80211_info_element varies depending on
+ * the mesh_id_len */
+struct mrvl_meshie_val {
+ uint8_t oui[P80211_OUI_LEN];
+ uint8_t type;
+ uint8_t subtype;
+ uint8_t version;
+ uint8_t active_protocol_id;
+ uint8_t active_metric_id;
+ uint8_t mesh_capability;
+ uint8_t mesh_id_len;
+ uint8_t mesh_id[IW_ESSID_MAX_SIZE];
+} __attribute__ ((packed));
+
+struct mrvl_meshie {
+ struct ieee80211_info_element hdr;
+ struct mrvl_meshie_val val;
+} __attribute__ ((packed));
+
+struct mrvl_mesh_defaults {
+ __le32 bootflag;
+ uint8_t boottime;
+ uint8_t reserved;
+ __le16 channel;
+ struct mrvl_meshie meshie;
+} __attribute__ ((packed));
+
#endif
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 0973d015a52..8b3ed77860b 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1002,7 +1002,7 @@ static int lbs_mesh_set_freq(struct net_device *dev,
else if (priv->mode == IW_MODE_ADHOC)
lbs_stop_adhoc_network(priv);
}
- lbs_mesh_config(priv, 1, fwrq->m);
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, fwrq->m);
lbs_update_channel(priv);
ret = 0;
@@ -1021,29 +1021,38 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
lbs_deb_enter(LBS_DEB_WEXT);
lbs_deb_wext("vwrq->value %d\n", vwrq->value);
+ lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed);
+
+ if (vwrq->fixed && vwrq->value == -1)
+ goto out;
/* Auto rate? */
- if (vwrq->value == -1) {
- priv->auto_rate = 1;
+ priv->enablehwauto = !vwrq->fixed;
+
+ if (vwrq->value == -1)
priv->cur_rate = 0;
- } else {
+ else {
if (vwrq->value % 100000)
goto out;
+ new_rate = vwrq->value / 500000;
+ priv->cur_rate = new_rate;
+ /* the rest is only needed for lbs_set_data_rate() */
memset(rates, 0, sizeof(rates));
copy_active_data_rates(priv, rates);
- new_rate = vwrq->value / 500000;
if (!memchr(rates, new_rate, sizeof(rates))) {
lbs_pr_alert("fixed data rate 0x%X out of range\n",
new_rate);
goto out;
}
-
- priv->cur_rate = new_rate;
- priv->auto_rate = 0;
}
- ret = lbs_set_data_rate(priv, new_rate);
+ /* Try the newer command first (Firmware Spec 5.1 and above) */
+ ret = lbs_cmd_802_11_rate_adapt_rateset(priv, CMD_ACT_SET);
+
+ /* Fallback to older version */
+ if (ret)
+ ret = lbs_set_data_rate(priv, new_rate);
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
@@ -1060,7 +1069,7 @@ static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
if (priv->connect_status == LBS_CONNECTED) {
vwrq->value = priv->cur_rate * 500000;
- if (priv->auto_rate)
+ if (priv->enablehwauto)
vwrq->fixed = 0;
else
vwrq->fixed = 1;
@@ -2011,7 +2020,8 @@ static int lbs_mesh_set_essid(struct net_device *dev,
priv->mesh_ssid_len = dwrq->length;
}
- lbs_mesh_config(priv, 1, priv->curbssparams.channel);
+ lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
+ priv->curbssparams.channel);
out:
lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
return ret;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
new file mode 100644
index 00000000000..913dc9fe08f
--- /dev/null
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -0,0 +1,515 @@
+/*
+ * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
+ * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * TODO:
+ * - IBSS mode simulation (Beacon transmission with competition for "air time")
+ * - IEEE 802.11a and 802.11n modes
+ * - RX filtering based on filter configuration (data->rx_filter)
+ */
+
+#include <net/mac80211.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/if_arp.h>
+#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
+
+MODULE_AUTHOR("Jouni Malinen");
+MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
+MODULE_LICENSE("GPL");
+
+static int radios = 2;
+module_param(radios, int, 0444);
+MODULE_PARM_DESC(radios, "Number of simulated radios");
+
+
+static struct class *hwsim_class;
+
+static struct ieee80211_hw **hwsim_radios;
+static int hwsim_radio_count;
+static struct net_device *hwsim_mon; /* global monitor netdev */
+
+
+static const struct ieee80211_channel hwsim_channels[] = {
+ { .center_freq = 2412 },
+ { .center_freq = 2417 },
+ { .center_freq = 2422 },
+ { .center_freq = 2427 },
+ { .center_freq = 2432 },
+ { .center_freq = 2437 },
+ { .center_freq = 2442 },
+ { .center_freq = 2447 },
+ { .center_freq = 2452 },
+ { .center_freq = 2457 },
+ { .center_freq = 2462 },
+ { .center_freq = 2467 },
+ { .center_freq = 2472 },
+ { .center_freq = 2484 },
+};
+
+static const struct ieee80211_rate hwsim_rates[] = {
+ { .bitrate = 10 },
+ { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+ { .bitrate = 60 },
+ { .bitrate = 90 },
+ { .bitrate = 120 },
+ { .bitrate = 180 },
+ { .bitrate = 240 },
+ { .bitrate = 360 },
+ { .bitrate = 480 },
+ { .bitrate = 540 }
+};
+
+struct mac80211_hwsim_data {
+ struct device *dev;
+ struct ieee80211_supported_band band;
+ struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)];
+ struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
+
+ struct ieee80211_channel *channel;
+ int radio_enabled;
+ unsigned long beacon_int; /* in jiffies unit */
+ unsigned int rx_filter;
+ int started;
+ struct timer_list beacon_timer;
+};
+
+
+struct hwsim_radiotap_hdr {
+ struct ieee80211_radiotap_header hdr;
+ u8 rt_flags;
+ u8 rt_rate;
+ __le16 rt_channel;
+ __le16 rt_chbitmask;
+} __attribute__ ((packed));
+
+
+static int hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ /* TODO: allow packet injection */
+ dev_kfree_skb(skb);
+ return 0;
+}
+
+
+static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
+ struct sk_buff *tx_skb)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ struct sk_buff *skb;
+ struct hwsim_radiotap_hdr *hdr;
+ u16 flags;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb);
+ struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info);
+
+ if (!netif_running(hwsim_mon))
+ return;
+
+ skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC);
+ if (skb == NULL)
+ return;
+
+ hdr = (struct hwsim_radiotap_hdr *) skb_push(skb, sizeof(*hdr));
+ hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+ hdr->hdr.it_pad = 0;
+ hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr));
+ hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_CHANNEL));
+ hdr->rt_flags = 0;
+ hdr->rt_rate = txrate->bitrate / 5;
+ hdr->rt_channel = cpu_to_le16(data->channel->center_freq);
+ flags = IEEE80211_CHAN_2GHZ;
+ if (txrate->flags & IEEE80211_RATE_ERP_G)
+ flags |= IEEE80211_CHAN_OFDM;
+ else
+ flags |= IEEE80211_CHAN_CCK;
+ hdr->rt_chbitmask = cpu_to_le16(flags);
+
+ skb->dev = hwsim_mon;
+ skb_set_mac_header(skb, 0);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+ memset(skb->cb, 0, sizeof(skb->cb));
+ netif_rx(skb);
+}
+
+
+static int mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
+ struct sk_buff *skb)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ int i, ack = 0;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_rx_status rx_status;
+
+ memset(&rx_status, 0, sizeof(rx_status));
+ /* TODO: set mactime */
+ rx_status.freq = data->channel->center_freq;
+ rx_status.band = data->channel->band;
+ rx_status.rate_idx = info->tx_rate_idx;
+ /* TODO: simulate signal strength (and optional packet drop) */
+
+ /* Copy skb to all enabled radios that are on the current frequency */
+ for (i = 0; i < hwsim_radio_count; i++) {
+ struct mac80211_hwsim_data *data2;
+ struct sk_buff *nskb;
+
+ if (hwsim_radios[i] == NULL || hwsim_radios[i] == hw)
+ continue;
+ data2 = hwsim_radios[i]->priv;
+ if (!data2->started || !data2->radio_enabled ||
+ data->channel->center_freq != data2->channel->center_freq)
+ continue;
+
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ if (nskb == NULL)
+ continue;
+
+ if (memcmp(hdr->addr1, hwsim_radios[i]->wiphy->perm_addr,
+ ETH_ALEN) == 0)
+ ack = 1;
+ ieee80211_rx_irqsafe(hwsim_radios[i], nskb, &rx_status);
+ }
+
+ return ack;
+}
+
+
+static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ int ack;
+ struct ieee80211_tx_info *txi;
+
+ mac80211_hwsim_monitor_rx(hw, skb);
+
+ if (skb->len < 10) {
+ /* Should not happen; just a sanity check for addr1 use */
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (!data->radio_enabled) {
+ printk(KERN_DEBUG "%s: dropped TX frame since radio "
+ "disabled\n", wiphy_name(hw->wiphy));
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ ack = mac80211_hwsim_tx_frame(hw, skb);
+
+ txi = IEEE80211_SKB_CB(skb);
+ memset(&txi->status, 0, sizeof(txi->status));
+ if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ if (ack)
+ txi->flags |= IEEE80211_TX_STAT_ACK;
+ else
+ txi->status.excessive_retries = 1;
+ }
+ ieee80211_tx_status_irqsafe(hw, skb);
+ return NETDEV_TX_OK;
+}
+
+
+static int mac80211_hwsim_start(struct ieee80211_hw *hw)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
+ data->started = 1;
+ return 0;
+}
+
+
+static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+ data->started = 0;
+ printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
+}
+
+
+static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ DECLARE_MAC_BUF(mac);
+ printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n",
+ wiphy_name(hw->wiphy), __func__, conf->type,
+ print_mac(mac, conf->mac_addr));
+ return 0;
+}
+
+
+static void mac80211_hwsim_remove_interface(
+ struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)
+{
+ DECLARE_MAC_BUF(mac);
+ printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n",
+ wiphy_name(hw->wiphy), __func__, conf->type,
+ print_mac(mac, conf->mac_addr));
+}
+
+
+static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct ieee80211_hw *hw = arg;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+
+ if (vif->type != IEEE80211_IF_TYPE_AP)
+ return;
+
+ skb = ieee80211_beacon_get(hw, vif);
+ if (skb == NULL)
+ return;
+ info = IEEE80211_SKB_CB(skb);
+
+ mac80211_hwsim_monitor_rx(hw, skb);
+ mac80211_hwsim_tx_frame(hw, skb);
+ dev_kfree_skb(skb);
+}
+
+
+static void mac80211_hwsim_beacon(unsigned long arg)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
+ struct mac80211_hwsim_data *data = hw->priv;
+
+ if (!data->started || !data->radio_enabled)
+ return;
+
+ ieee80211_iterate_active_interfaces_atomic(
+ hw, mac80211_hwsim_beacon_tx, hw);
+
+ data->beacon_timer.expires = jiffies + data->beacon_int;
+ add_timer(&data->beacon_timer);
+}
+
+
+static int mac80211_hwsim_config(struct ieee80211_hw *hw,
+ struct ieee80211_conf *conf)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+
+ printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
+ wiphy_name(hw->wiphy), __func__,
+ conf->channel->center_freq, conf->radio_enabled,
+ conf->beacon_int);
+
+ data->channel = conf->channel;
+ data->radio_enabled = conf->radio_enabled;
+ data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000;
+ if (data->beacon_int < 1)
+ data->beacon_int = 1;
+
+ if (!data->started || !data->radio_enabled)
+ del_timer(&data->beacon_timer);
+ else
+ mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
+
+ return 0;
+}
+
+
+static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct mac80211_hwsim_data *data = hw->priv;
+
+ printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
+
+ data->rx_filter = 0;
+ if (*total_flags & FIF_PROMISC_IN_BSS)
+ data->rx_filter |= FIF_PROMISC_IN_BSS;
+ if (*total_flags & FIF_ALLMULTI)
+ data->rx_filter |= FIF_ALLMULTI;
+
+ *total_flags = data->rx_filter;
+}
+
+
+
+static const struct ieee80211_ops mac80211_hwsim_ops =
+{
+ .tx = mac80211_hwsim_tx,
+ .start = mac80211_hwsim_start,
+ .stop = mac80211_hwsim_stop,
+ .add_interface = mac80211_hwsim_add_interface,
+ .remove_interface = mac80211_hwsim_remove_interface,
+ .config = mac80211_hwsim_config,
+ .configure_filter = mac80211_hwsim_configure_filter,
+};
+
+
+static void mac80211_hwsim_free(void)
+{
+ int i;
+
+ for (i = 0; i < hwsim_radio_count; i++) {
+ if (hwsim_radios[i]) {
+ struct mac80211_hwsim_data *data;
+ data = hwsim_radios[i]->priv;
+ ieee80211_unregister_hw(hwsim_radios[i]);
+ if (!IS_ERR(data->dev))
+ device_unregister(data->dev);
+ ieee80211_free_hw(hwsim_radios[i]);
+ }
+ }
+ kfree(hwsim_radios);
+ class_destroy(hwsim_class);
+}
+
+
+static struct device_driver mac80211_hwsim_driver = {
+ .name = "mac80211_hwsim"
+};
+
+
+static void hwsim_mon_setup(struct net_device *dev)
+{
+ dev->hard_start_xmit = hwsim_mon_xmit;
+ dev->destructor = free_netdev;
+ ether_setup(dev);
+ dev->tx_queue_len = 0;
+ dev->type = ARPHRD_IEEE80211_RADIOTAP;
+ memset(dev->dev_addr, 0, ETH_ALEN);
+ dev->dev_addr[0] = 0x12;
+}
+
+
+static int __init init_mac80211_hwsim(void)
+{
+ int i, err = 0;
+ u8 addr[ETH_ALEN];
+ struct mac80211_hwsim_data *data;
+ struct ieee80211_hw *hw;
+ DECLARE_MAC_BUF(mac);
+
+ if (radios < 1 || radios > 65535)
+ return -EINVAL;
+
+ hwsim_radio_count = radios;
+ hwsim_radios = kcalloc(hwsim_radio_count,
+ sizeof(struct ieee80211_hw *), GFP_KERNEL);
+ if (hwsim_radios == NULL)
+ return -ENOMEM;
+
+ hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
+ if (IS_ERR(hwsim_class)) {
+ kfree(hwsim_radios);
+ return PTR_ERR(hwsim_class);
+ }
+
+ memset(addr, 0, ETH_ALEN);
+ addr[0] = 0x02;
+
+ for (i = 0; i < hwsim_radio_count; i++) {
+ printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n",
+ i);
+ hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops);
+ if (hw == NULL) {
+ printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
+ "failed\n");
+ err = -ENOMEM;
+ goto failed;
+ }
+ hwsim_radios[i] = hw;
+
+ data = hw->priv;
+ data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw,
+ "hwsim%d", i);
+ if (IS_ERR(data->dev)) {
+ printk(KERN_DEBUG
+ "mac80211_hwsim: device_create_drvdata "
+ "failed (%ld)\n", PTR_ERR(data->dev));
+ err = -ENOMEM;
+ goto failed;
+ }
+ data->dev->driver = &mac80211_hwsim_driver;
+
+ SET_IEEE80211_DEV(hw, data->dev);
+ addr[3] = i >> 8;
+ addr[4] = i;
+ SET_IEEE80211_PERM_ADDR(hw, addr);
+
+ hw->channel_change_time = 1;
+ hw->queues = 1;
+
+ memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
+ memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
+ data->band.channels = data->channels;
+ data->band.n_channels = ARRAY_SIZE(hwsim_channels);
+ data->band.bitrates = data->rates;
+ data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
+
+ err = ieee80211_register_hw(hw);
+ if (err < 0) {
+ printk(KERN_DEBUG "mac80211_hwsim: "
+ "ieee80211_register_hw failed (%d)\n", err);
+ goto failed;
+ }
+
+ printk(KERN_DEBUG "%s: hwaddr %s registered\n",
+ wiphy_name(hw->wiphy),
+ print_mac(mac, hw->wiphy->perm_addr));
+
+ setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
+ (unsigned long) hw);
+ }
+
+ hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
+ if (hwsim_mon == NULL)
+ goto failed;
+
+ rtnl_lock();
+
+ err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
+ if (err < 0) {
+ goto failed_mon;
+ }
+
+ err = register_netdevice(hwsim_mon);
+ if (err < 0)
+ goto failed_mon;
+
+ rtnl_unlock();
+
+ return 0;
+
+failed_mon:
+ rtnl_unlock();
+ free_netdev(hwsim_mon);
+
+failed:
+ mac80211_hwsim_free();
+ return err;
+}
+
+
+static void __exit exit_mac80211_hwsim(void)
+{
+ printk(KERN_DEBUG "mac80211_hwsim: unregister %d radios\n",
+ hwsim_radio_count);
+
+ unregister_netdev(hwsim_mon);
+ mac80211_hwsim_free();
+}
+
+
+module_init(init_mac80211_hwsim);
+module_exit(exit_mac80211_hwsim);
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 6d13a0d15a0..b047306bf38 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II
* Return message length or -errno for fatal errors */
static inline char *orinoco_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *current_ev,
char *end_buf,
union hermes_scan_info *bss,
@@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->a.essid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
channel = bss->s.channel;
@@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf,
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_FREQ_LEN);
}
@@ -4106,7 +4110,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
else
iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->a.essid);
/* Add EXTRA: Age to display seconds since last beacon/probe response
* for given network. */
@@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
jiffies_to_msecs(jiffies - last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
/* Bit rate is not available in Lucent/Agere firmwares */
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
- char *current_val = current_ev + IW_EV_LCP_LEN;
+ char *current_val = current_ev + iwe_stream_lcp_len(info);
int i;
int step;
@@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
break;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val,
end_buf, &iwe,
IW_EV_PARAM_LEN);
}
/* Check if we added any event */
- if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val;
}
@@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
list_for_each_entry(bss, &priv->bss_list, list) {
/* Translate to WE format this entry */
- current_ev = orinoco_translate_scan(dev, current_ev,
+ current_ev = orinoco_translate_scan(dev, info, current_ev,
extra + srq->length,
&bss->bss,
bss->last_scanned);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 06d2c67f4c8..c6f27b9022f 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -64,7 +64,7 @@ struct p54_common {
unsigned int tx_hdr_len;
void *cached_vdcf;
unsigned int fw_var;
- struct ieee80211_tx_queue_stats tx_stats;
+ struct ieee80211_tx_queue_stats tx_stats[4];
};
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 63f9badf3f5..ffaf7a6b681 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -146,10 +146,10 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
if (priv->fw_var >= 0x300) {
/* Firmware supports QoS, use it! */
- priv->tx_stats.data[0].limit = 3;
- priv->tx_stats.data[1].limit = 4;
- priv->tx_stats.data[2].limit = 3;
- priv->tx_stats.data[3].limit = 1;
+ priv->tx_stats[0].limit = 3;
+ priv->tx_stats[1].limit = 4;
+ priv->tx_stats[2].limit = 3;
+ priv->tx_stats[3].limit = 1;
dev->queues = 4;
}
}
@@ -355,8 +355,9 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
struct ieee80211_rx_status rx_status = {0};
u16 freq = le16_to_cpu(hdr->freq);
- rx_status.ssi = hdr->rssi;
+ rx_status.signal = hdr->rssi;
/* XX correct? */
+ rx_status.qual = (100 * hdr->rssi) / 127;
rx_status.rate_idx = hdr->rate & 0xf;
rx_status.freq = freq;
rx_status.band = IEEE80211_BAND_2GHZ;
@@ -375,11 +376,8 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
struct p54_common *priv = dev->priv;
int i;
- /* ieee80211_start_queues is great if all queues are really empty.
- * But, what if some are full? */
-
for (i = 0; i < dev->queues; i++)
- if (priv->tx_stats.data[i].len < priv->tx_stats.data[i].limit)
+ if (priv->tx_stats[i].len < priv->tx_stats[i].limit)
ieee80211_wake_queue(dev, i);
}
@@ -395,45 +393,42 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
u32 last_addr = priv->rx_start;
while (entry != (struct sk_buff *)&priv->tx_queue) {
- range = (struct memrecord *)&entry->cb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
+ range = (void *)info->driver_data;
if (range->start_addr == addr) {
- struct ieee80211_tx_status status;
struct p54_control_hdr *entry_hdr;
struct p54_tx_control_allocdata *entry_data;
int pad = 0;
- if (entry->next != (struct sk_buff *)&priv->tx_queue)
- freed = ((struct memrecord *)&entry->next->cb)->start_addr - last_addr;
- else
+ if (entry->next != (struct sk_buff *)&priv->tx_queue) {
+ struct ieee80211_tx_info *ni;
+ struct memrecord *mr;
+
+ ni = IEEE80211_SKB_CB(entry->next);
+ mr = (struct memrecord *)ni->driver_data;
+ freed = mr->start_addr - last_addr;
+ } else
freed = priv->rx_end - last_addr;
last_addr = range->end_addr;
__skb_unlink(entry, &priv->tx_queue);
- if (!range->control) {
- kfree_skb(entry);
- break;
- }
- memset(&status, 0, sizeof(status));
- memcpy(&status.control, range->control,
- sizeof(status.control));
- kfree(range->control);
- priv->tx_stats.data[status.control.queue].len--;
-
+ memset(&info->status, 0, sizeof(info->status));
+ priv->tx_stats[skb_get_queue_mapping(skb)].len--;
entry_hdr = (struct p54_control_hdr *) entry->data;
entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
pad = entry_data->align[0];
- if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (!(payload->status & 0x01))
- status.flags |= IEEE80211_TX_STATUS_ACK;
+ info->flags |= IEEE80211_TX_STAT_ACK;
else
- status.excessive_retries = 1;
+ info->status.excessive_retries = 1;
}
- status.retry_count = payload->retries - 1;
- status.ack_signal = le16_to_cpu(payload->ack_rssi);
+ info->status.retry_count = payload->retries - 1;
+ info->status.ack_signal = le16_to_cpu(payload->ack_rssi);
skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
- ieee80211_tx_status_irqsafe(dev, entry, &status);
+ ieee80211_tx_status_irqsafe(dev, entry);
break;
} else
last_addr = range->end_addr;
@@ -498,13 +493,11 @@ EXPORT_SYMBOL_GPL(p54_rx);
* allocated areas.
*/
static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
- struct p54_control_hdr *data, u32 len,
- struct ieee80211_tx_control *control)
+ struct p54_control_hdr *data, u32 len)
{
struct p54_common *priv = dev->priv;
struct sk_buff *entry = priv->tx_queue.next;
struct sk_buff *target_skb = NULL;
- struct memrecord *range;
u32 last_addr = priv->rx_start;
u32 largest_hole = 0;
u32 target_addr = priv->rx_start;
@@ -516,7 +509,8 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
left = skb_queue_len(&priv->tx_queue);
while (left--) {
u32 hole_size;
- range = (struct memrecord *)&entry->cb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
+ struct memrecord *range = (void *)info->driver_data;
hole_size = range->start_addr - last_addr;
if (!target_skb && hole_size >= len) {
target_skb = entry->prev;
@@ -531,17 +525,18 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
target_skb = priv->tx_queue.prev;
largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
if (!skb_queue_empty(&priv->tx_queue)) {
- range = (struct memrecord *)&target_skb->cb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb);
+ struct memrecord *range = (void *)info->driver_data;
target_addr = range->end_addr;
}
} else
largest_hole = max(largest_hole, priv->rx_end - last_addr);
if (skb) {
- range = (struct memrecord *)&skb->cb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct memrecord *range = (void *)info->driver_data;
range->start_addr = target_addr;
range->end_addr = target_addr + len;
- range->control = control;
__skb_queue_after(&priv->tx_queue, target_skb, skb);
if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
sizeof(struct p54_control_hdr))
@@ -552,32 +547,27 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
data->req_id = cpu_to_le32(target_addr + 0x70);
}
-static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
- struct ieee80211_tx_queue_stats_data *current_queue;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_queue_stats *current_queue;
struct p54_common *priv = dev->priv;
struct p54_control_hdr *hdr;
struct p54_tx_control_allocdata *txhdr;
- struct ieee80211_tx_control *control_copy;
size_t padding, len;
u8 rate;
- current_queue = &priv->tx_stats.data[control->queue];
+ current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
if (unlikely(current_queue->len > current_queue->limit))
return NETDEV_TX_BUSY;
current_queue->len++;
current_queue->count++;
if (current_queue->len == current_queue->limit)
- ieee80211_stop_queue(dev, control->queue);
+ ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
len = skb->len;
- control_copy = kmalloc(sizeof(*control), GFP_ATOMIC);
- if (control_copy)
- memcpy(control_copy, control, sizeof(*control));
-
txhdr = (struct p54_tx_control_allocdata *)
skb_push(skb, sizeof(*txhdr) + padding);
hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr));
@@ -587,35 +577,37 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
else
hdr->magic1 = cpu_to_le16(0x0010);
hdr->len = cpu_to_le16(len);
- hdr->type = (control->flags & IEEE80211_TXCTL_NO_ACK) ? 0 : cpu_to_le16(1);
- hdr->retry1 = hdr->retry2 = control->retry_limit;
- p54_assign_address(dev, skb, hdr, skb->len, control_copy);
+ hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
+ hdr->retry1 = hdr->retry2 = info->control.retry_limit;
memset(txhdr->wep_key, 0x0, 16);
txhdr->padding = 0;
txhdr->padding2 = 0;
/* TODO: add support for alternate retry TX rates */
- rate = control->tx_rate->hw_value;
- if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
+ rate = ieee80211_get_tx_rate(dev, info)->hw_value;
+ if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
rate |= 0x10;
- if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
rate |= 0x40;
- else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+ else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
rate |= 0x20;
memset(txhdr->rateset, rate, 8);
txhdr->wep_key_present = 0;
txhdr->wep_key_len = 0;
- txhdr->frame_type = cpu_to_le32(control->queue + 4);
+ txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4);
txhdr->magic4 = 0;
- txhdr->antenna = (control->antenna_sel_tx == 0) ?
- 2 : control->antenna_sel_tx - 1;
+ txhdr->antenna = (info->antenna_sel_tx == 0) ?
+ 2 : info->antenna_sel_tx - 1;
txhdr->output_power = 0x7f; // HW Maximum
- txhdr->magic5 = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
+ txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
if (padding)
txhdr->align[0] = padding;
+ /* modifies skb->cb and with it info, so must be last! */
+ p54_assign_address(dev, skb, hdr, skb->len);
+
priv->tx(dev, hdr, skb->len, 0);
return 0;
}
@@ -638,7 +630,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
filter = (struct p54_tx_control_filter *) hdr->data;
hdr->magic1 = cpu_to_le16(0x8001);
hdr->len = cpu_to_le16(sizeof(*filter));
- p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter), NULL);
+ p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter));
hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
filter->filter_type = cpu_to_le16(filter_type);
@@ -682,7 +674,7 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
hdr->magic1 = cpu_to_le16(0x8001);
hdr->len = cpu_to_le16(sizeof(*chan));
hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
- p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len, NULL);
+ p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len);
chan->magic1 = cpu_to_le16(0x1);
chan->magic2 = cpu_to_le16(0x0);
@@ -755,7 +747,7 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
hdr->magic1 = cpu_to_le16(0x8001);
hdr->len = cpu_to_le16(sizeof(*led));
hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
- p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led), NULL);
+ p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led));
led = (struct p54_tx_control_led *) hdr->data;
led->mode = cpu_to_le16(mode);
@@ -805,7 +797,7 @@ static void p54_set_vdcf(struct ieee80211_hw *dev)
hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
- p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf), NULL);
+ p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf));
vdcf = (struct p54_tx_control_vdcf *) hdr->data;
@@ -841,12 +833,8 @@ static void p54_stop(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
- while ((skb = skb_dequeue(&priv->tx_queue))) {
- struct memrecord *range = (struct memrecord *)&skb->cb;
- if (range->control)
- kfree(range->control);
+ while ((skb = skb_dequeue(&priv->tx_queue)))
kfree_skb(skb);
- }
priv->stop(dev);
priv->mode = IEEE80211_IF_TYPE_INVALID;
}
@@ -936,7 +924,7 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
}
}
-static int p54_conf_tx(struct ieee80211_hw *dev, int queue,
+static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct p54_common *priv = dev->priv;
@@ -945,7 +933,7 @@ static int p54_conf_tx(struct ieee80211_hw *dev, int queue,
vdcf = (struct p54_tx_control_vdcf *)(((struct p54_control_hdr *)
((void *)priv->cached_vdcf + priv->tx_hdr_len))->data);
- if ((params) && !((queue < 0) || (queue > 4))) {
+ if ((params) && !(queue > 4)) {
P54_SET_QUEUE(vdcf->queue[queue], params->aifs,
params->cw_min, params->cw_max, params->txop);
} else
@@ -967,11 +955,8 @@ static int p54_get_tx_stats(struct ieee80211_hw *dev,
struct ieee80211_tx_queue_stats *stats)
{
struct p54_common *priv = dev->priv;
- unsigned int i;
- for (i = 0; i < dev->queues; i++)
- memcpy(&stats->data[i], &priv->tx_stats.data[i],
- sizeof(stats->data[i]));
+ memcpy(stats, &priv->tx_stats, sizeof(stats[0]) * dev->queues);
return 0;
}
@@ -1004,11 +989,12 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
skb_queue_head_init(&priv->tx_queue);
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
- IEEE80211_HW_RX_INCLUDES_FCS;
+ IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_UNSPEC;
dev->channel_change_time = 1000; /* TODO: find actual value */
- dev->max_rssi = 127;
+ dev->max_signal = 127;
- priv->tx_stats.data[0].limit = 5;
+ priv->tx_stats[0].limit = 5;
dev->queues = 1;
dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index c15b56e1d75..2245fcce92d 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -152,7 +152,6 @@ struct pda_pa_curve_data {
struct memrecord {
u32 start_addr;
u32 end_addr;
- struct ieee80211_tx_control *control;
};
struct p54_eeprom_lm86 {
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index fa527723fbe..7dd4add4bf4 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -665,7 +665,7 @@ static int p54p_resume(struct pci_dev *pdev)
if (priv->common.mode != IEEE80211_IF_TYPE_INVALID) {
p54p_open(dev);
- ieee80211_start_queues(dev);
+ ieee80211_wake_queues(dev);
}
return 0;
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 5b375b28903..97fa14e0a47 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
*/
static char *
-prism54_translate_bss(struct net_device *ndev, char *current_ev,
- char *end_buf, struct obj_bss *bss, char noise)
+prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
+ char *current_ev, char *end_buf, struct obj_bss *bss,
+ char noise)
{
struct iw_event iwe; /* Temporary buffer */
short cap;
@@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
@@ -593,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid.octets);
/* Capabilities */
@@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Encryption capability */
if (cap & CAP_CRYPT)
@@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->rssi;
@@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
/* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add WPA/RSN Information Element, if any */
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
if (wpa_ie_len > 0) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, wpa_ie);
}
/* Do the bitrates */
{
- char * current_val = current_ev + IW_EV_LCP_LEN;
+ char *current_val = current_ev + iwe_stream_lcp_len(info);
int i;
int mask;
@@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
for(i = 0; i < sizeof(scan_rate_list); i++) {
if(bss->rates & mask) {
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
mask <<= 1;
}
/* Check if we added any event */
- if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
current_ev = current_val;
}
@@ -710,7 +711,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
/* ok now, scan the list and translate its info */
for (i = 0; i < (int) bsslist->nr; i++) {
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, info, current_ev,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
@@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
struct prism2_hostapd_param *param)
{
islpci_private *priv = netdev_priv(ndev);
+ struct iw_request_info info;
int i, rvalue;
struct obj_bsslist *bsslist;
u32 noise = 0;
@@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
+ info.cmd = PRISM54_HOSTAPD;
+ info.flags = 0;
+
/* ok now, scan the list and translate its info */
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, &info, current_ev,
extra + IW_SCAN_MAX_DATA,
&(bsslist->bsslist[i]),
noise);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 18c9931e326..00e965b9da7 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -310,8 +310,11 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
#define CAP_MODE_MASK 7
#define CAP_SUPPORT_TXPOWER 8
-#define WORK_CONNECTION_EVENT (1<<0)
-#define WORK_SET_MULTICAST_LIST (1<<1)
+#define WORK_LINK_UP (1<<0)
+#define WORK_LINK_DOWN (1<<1)
+#define WORK_SET_MULTICAST_LIST (1<<2)
+
+#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
/* RNDIS device private data */
struct rndis_wext_private {
@@ -361,6 +364,8 @@ struct rndis_wext_private {
u8 *wpa_ie;
int wpa_cipher_pair;
int wpa_cipher_group;
+
+ u8 command_buffer[COMMAND_BUFFER_SIZE];
};
@@ -427,18 +432,23 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
buflen = *len + sizeof(*u.get);
if (buflen < CONTROL_BUFFER_SIZE)
buflen = CONTROL_BUFFER_SIZE;
- u.buf = kmalloc(buflen, GFP_KERNEL);
- if (!u.buf)
- return -ENOMEM;
+
+ if (buflen > COMMAND_BUFFER_SIZE) {
+ u.buf = kmalloc(buflen, GFP_KERNEL);
+ if (!u.buf)
+ return -ENOMEM;
+ } else {
+ u.buf = priv->command_buffer;
+ }
+
+ mutex_lock(&priv->command_lock);
+
memset(u.get, 0, sizeof *u.get);
u.get->msg_type = RNDIS_MSG_QUERY;
u.get->msg_len = ccpu2(sizeof *u.get);
u.get->oid = oid;
- mutex_lock(&priv->command_lock);
- ret = rndis_command(dev, u.header);
- mutex_unlock(&priv->command_lock);
-
+ ret = rndis_command(dev, u.header, buflen);
if (ret == 0) {
ret = le32_to_cpu(u.get_c->len);
*len = (*len > ret) ? ret : *len;
@@ -446,7 +456,10 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
ret = rndis_error_status(u.get_c->status);
}
- kfree(u.buf);
+ mutex_unlock(&priv->command_lock);
+
+ if (u.buf != priv->command_buffer)
+ kfree(u.buf);
return ret;
}
@@ -465,9 +478,16 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
buflen = len + sizeof(*u.set);
if (buflen < CONTROL_BUFFER_SIZE)
buflen = CONTROL_BUFFER_SIZE;
- u.buf = kmalloc(buflen, GFP_KERNEL);
- if (!u.buf)
- return -ENOMEM;
+
+ if (buflen > COMMAND_BUFFER_SIZE) {
+ u.buf = kmalloc(buflen, GFP_KERNEL);
+ if (!u.buf)
+ return -ENOMEM;
+ } else {
+ u.buf = priv->command_buffer;
+ }
+
+ mutex_lock(&priv->command_lock);
memset(u.set, 0, sizeof *u.set);
u.set->msg_type = RNDIS_MSG_SET;
@@ -478,14 +498,14 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
u.set->handle = ccpu2(0);
memcpy(u.buf + sizeof(*u.set), data, len);
- mutex_lock(&priv->command_lock);
- ret = rndis_command(dev, u.header);
- mutex_unlock(&priv->command_lock);
-
+ ret = rndis_command(dev, u.header, buflen);
if (ret == 0)
ret = rndis_error_status(u.set_c->status);
- kfree(u.buf);
+ mutex_unlock(&priv->command_lock);
+
+ if (u.buf != priv->command_buffer)
+ kfree(u.buf);
return ret;
}
@@ -620,8 +640,7 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
{
if (freq->m < 1000 && freq->e == 0) {
- if (freq->m >= 1 &&
- freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0])))
+ if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan))
*dsconfig = freq_chan[freq->m - 1] * 1000;
else
return -1;
@@ -1135,7 +1154,7 @@ static int rndis_iw_get_range(struct net_device *dev,
/* fill in 802.11g rates */
if (has_80211g_rates) {
num = range->num_bitrates;
- for (i = 0; i < sizeof(rates_80211g); i++) {
+ for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) {
for (j = 0; j < num; j++) {
if (range->bitrate[j] ==
rates_80211g[i] * 1000000)
@@ -1159,10 +1178,9 @@ static int rndis_iw_get_range(struct net_device *dev,
range->throughput = 11 * 1000 * 1000 / 2;
}
- range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0]));
+ range->num_channels = ARRAY_SIZE(freq_chan);
- for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) &&
- i < IW_MAX_FREQUENCIES; i++) {
+ for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) {
range->freq[i].i = i + 1;
range->freq[i].m = freq_chan[i] * 100000;
range->freq[i].e = 1;
@@ -1630,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev,
static char *rndis_translate_scan(struct net_device *dev,
- char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid)
+ struct iw_request_info *info, char *cev,
+ char *end_buf,
+ struct ndis_80211_bssid_ex *bssid)
{
#ifdef DEBUG
struct usbnet *usbdev = dev->priv;
@@ -1649,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
bssid->ssid.essid);
iwe.cmd = SIOCGIWESSID;
iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
iwe.u.essid.flags = 1;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
iwe.cmd = SIOCGIWMODE;
@@ -1672,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_AUTO;
break;
}
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
iwe.cmd = SIOCGIWFREQ;
dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
iwe.cmd = IWEVQUAL;
@@ -1686,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
| IW_QUAL_LEVEL_UPDATED
| IW_QUAL_NOISE_INVALID;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
iwe.cmd = SIOCGIWENCODE;
@@ -1696,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
devdbg(usbdev, "RATES:");
- current_val = cev + IW_EV_LCP_LEN;
+ current_val = cev + iwe_stream_lcp_len(info);
iwe.cmd = SIOCGIWRATE;
for (i = 0; i < sizeof(bssid->rates); i++) {
if (bssid->rates[i] & 0x7f) {
@@ -1707,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev,
((bssid->rates[i] & 0x7f) *
500000);
devdbg(usbdev, " %d", iwe.u.bitrate.value);
- current_val = iwe_stream_add_value(cev,
+ current_val = iwe_stream_add_value(info, cev,
current_val, end_buf, &iwe,
IW_EV_PARAM_LEN);
}
}
- if ((current_val - cev) > IW_EV_LCP_LEN)
+ if ((current_val - cev) > iwe_stream_lcp_len(info))
cev = current_val;
beacon = le32_to_cpu(bssid->config.beacon_period);
@@ -1721,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
iwe.u.data.length = strlen(sbuf);
- cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
atim = le32_to_cpu(bssid->config.atim_window);
devdbg(usbdev, "ATIM %d", atim);
iwe.cmd = IWEVCUSTOM;
snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
iwe.u.data.length = strlen(sbuf);
- cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
ie_len = min(bssid_len - (int)sizeof(*bssid),
@@ -1742,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev,
(ie->id == MFIE_TYPE_RSN) ? 2 : 1);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
- cev = iwe_stream_add_point(cev, end_buf, &iwe,
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe,
(u8 *)ie);
}
@@ -1785,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev,
devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
- cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
- bssid);
+ cev = rndis_translate_scan(dev, info, cev,
+ extra + IW_SCAN_MAX_DATA, bssid);
bssid = (void *)bssid + bssid_len;
bssid_len = le32_to_cpu(bssid->length);
count--;
@@ -2213,7 +2233,9 @@ static void rndis_wext_worker(struct work_struct *work)
int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32;
int ret, offset;
- if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) {
+ if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) {
+ netif_carrier_on(usbdev->net);
+
info = kzalloc(assoc_size, GFP_KERNEL);
if (!info)
goto get_bssid;
@@ -2251,6 +2273,15 @@ get_bssid:
}
}
+ if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) {
+ netif_carrier_off(usbdev->net);
+
+ evt.data.flags = 0;
+ evt.data.length = 0;
+ memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
+ wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
+ }
+
if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
set_multicast_list(usbdev);
}
@@ -2260,29 +2291,24 @@ static void rndis_wext_set_multicast_list(struct net_device *dev)
struct usbnet *usbdev = dev->priv;
struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+ if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
+ return;
+
set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
queue_work(priv->workqueue, &priv->work);
}
-static void rndis_wext_link_change(struct usbnet *dev, int state)
+static void rndis_wext_link_change(struct usbnet *usbdev, int state)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
- union iwreq_data evt;
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
- if (state) {
- /* queue work to avoid recursive calls into rndis_command */
- set_bit(WORK_CONNECTION_EVENT, &priv->work_pending);
- queue_work(priv->workqueue, &priv->work);
- } else {
- evt.data.flags = 0;
- evt.data.length = 0;
- memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
- wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL);
- }
+ /* queue work to avoid recursive calls into rndis_command */
+ set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending);
+ queue_work(priv->workqueue, &priv->work);
}
-static int rndis_wext_get_caps(struct usbnet *dev)
+static int rndis_wext_get_caps(struct usbnet *usbdev)
{
struct {
__le32 num_items;
@@ -2290,18 +2316,18 @@ static int rndis_wext_get_caps(struct usbnet *dev)
} networks_supported;
int len, retval, i, n;
__le32 tx_power;
- struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
/* determine if supports setting txpower */
len = sizeof(tx_power);
- retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power,
- &len);
+ retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power,
+ &len);
if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
priv->caps |= CAP_SUPPORT_TXPOWER;
/* determine supported modes */
len = sizeof(networks_supported);
- retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED,
+ retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED,
&networks_supported, &len);
if (retval >= 0) {
n = le32_to_cpu(networks_supported.num_items);
@@ -2440,9 +2466,9 @@ end:
}
-static int bcm4320_early_init(struct usbnet *dev)
+static int bcm4320_early_init(struct usbnet *usbdev)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
char buf[8];
/* Early initialization settings, setting these won't have effect
@@ -2490,51 +2516,48 @@ static int bcm4320_early_init(struct usbnet *dev)
else
priv->param_workaround_interval = modparam_workaround_interval;
- rndis_set_config_parameter_str(dev, "Country", priv->param_country);
- rndis_set_config_parameter_str(dev, "FrameBursting",
+ rndis_set_config_parameter_str(usbdev, "Country", priv->param_country);
+ rndis_set_config_parameter_str(usbdev, "FrameBursting",
priv->param_frameburst ? "1" : "0");
- rndis_set_config_parameter_str(dev, "Afterburner",
+ rndis_set_config_parameter_str(usbdev, "Afterburner",
priv->param_afterburner ? "1" : "0");
sprintf(buf, "%d", priv->param_power_save);
- rndis_set_config_parameter_str(dev, "PowerSaveMode", buf);
+ rndis_set_config_parameter_str(usbdev, "PowerSaveMode", buf);
sprintf(buf, "%d", priv->param_power_output);
- rndis_set_config_parameter_str(dev, "PwrOut", buf);
+ rndis_set_config_parameter_str(usbdev, "PwrOut", buf);
sprintf(buf, "%d", priv->param_roamtrigger);
- rndis_set_config_parameter_str(dev, "RoamTrigger", buf);
+ rndis_set_config_parameter_str(usbdev, "RoamTrigger", buf);
sprintf(buf, "%d", priv->param_roamdelta);
- rndis_set_config_parameter_str(dev, "RoamDelta", buf);
+ rndis_set_config_parameter_str(usbdev, "RoamDelta", buf);
return 0;
}
-static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf)
+static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
{
- struct net_device *net = dev->net;
struct rndis_wext_private *priv;
int retval, len;
__le32 tmp;
/* allocate rndis private data */
- priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
+ priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* These have to be initialized before calling generic_rndis_bind().
* Otherwise we'll be in big trouble in rndis_wext_early_init().
*/
- dev->driver_priv = priv;
- memset(priv, 0, sizeof(*priv));
- memset(priv->name, 0, sizeof(priv->name));
+ usbdev->driver_priv = priv;
strcpy(priv->name, "IEEE802.11");
- net->wireless_handlers = &rndis_iw_handlers;
- priv->usbdev = dev;
+ usbdev->net->wireless_handlers = &rndis_iw_handlers;
+ priv->usbdev = usbdev;
mutex_init(&priv->command_lock);
spin_lock_init(&priv->stats_lock);
/* try bind rndis_host */
- retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS);
+ retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
if (retval < 0)
goto fail;
@@ -2545,20 +2568,21 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf)
* rndis_host wants to avoid all OID as much as possible
* so do promisc/multicast handling in rndis_wext.
*/
- dev->net->set_multicast_list = rndis_wext_set_multicast_list;
+ usbdev->net->set_multicast_list = rndis_wext_set_multicast_list;
tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
- retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
+ retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
sizeof(tmp));
len = sizeof(tmp);
- retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len);
+ retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp,
+ &len);
priv->multicast_size = le32_to_cpu(tmp);
if (retval < 0 || priv->multicast_size < 0)
priv->multicast_size = 0;
if (priv->multicast_size > 0)
- dev->net->flags |= IFF_MULTICAST;
+ usbdev->net->flags |= IFF_MULTICAST;
else
- dev->net->flags &= ~IFF_MULTICAST;
+ usbdev->net->flags &= ~IFF_MULTICAST;
priv->iwstats.qual.qual = 0;
priv->iwstats.qual.level = 0;
@@ -2568,12 +2592,13 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf)
| IW_QUAL_QUAL_INVALID
| IW_QUAL_LEVEL_INVALID;
- rndis_wext_get_caps(dev);
- set_default_iw_params(dev);
+ rndis_wext_get_caps(usbdev);
+ set_default_iw_params(usbdev);
/* turn radio on */
priv->radio_on = 1;
- disassociate(dev, 1);
+ disassociate(usbdev, 1);
+ netif_carrier_off(usbdev->net);
/* because rndis_command() sleeps we need to use workqueue */
priv->workqueue = create_singlethread_workqueue("rndis_wlan");
@@ -2590,12 +2615,12 @@ fail:
}
-static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf)
+static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf)
{
- struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+ struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
/* turn radio off */
- disassociate(dev, 0);
+ disassociate(usbdev, 0);
cancel_delayed_work_sync(&priv->stats_work);
cancel_work_sync(&priv->work);
@@ -2606,13 +2631,13 @@ static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf)
kfree(priv->wpa_ie);
kfree(priv);
- rndis_unbind(dev, intf);
+ rndis_unbind(usbdev, intf);
}
-static int rndis_wext_reset(struct usbnet *dev)
+static int rndis_wext_reset(struct usbnet *usbdev)
{
- return deauthenticate(dev);
+ return deauthenticate(usbdev);
}
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 2d611876bbe..d485a86bba7 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -5,12 +5,16 @@ config RT2X00
This will enable the experimental support for the Ralink drivers,
developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
- These drivers will make use of the mac80211 stack.
+ These drivers make use of the mac80211 stack.
When building one of the individual drivers, the rt2x00 library
will also be created. That library (when the driver is built as
a module) will be called "rt2x00lib.ko".
+ Additionally PCI and USB libraries will also be build depending
+ on the types of drivers being selected, these libraries will be
+ called "rt2x00pci.ko" and "rt2x00usb.ko".
+
if RT2X00
config RT2X00_LIB
@@ -32,35 +36,34 @@ config RT2X00_LIB_FIRMWARE
config RT2X00_LIB_RFKILL
boolean
depends on RT2X00_LIB
- depends on INPUT
select RFKILL
- select INPUT_POLLDEV
config RT2X00_LIB_LEDS
boolean
depends on RT2X00_LIB && NEW_LEDS
config RT2400PCI
- tristate "Ralink rt2400 pci/pcmcia support"
+ tristate "Ralink rt2400 (PCI/PCMCIA) support"
depends on PCI
select RT2X00_LIB_PCI
select EEPROM_93CX6
---help---
- This is an experimental driver for the Ralink rt2400 wireless chip.
+ This adds support for rt2400 wireless chipset family.
+ Supported chips: RT2460.
When compiled as a module, this driver will be called "rt2400pci.ko".
config RT2400PCI_RFKILL
- bool "RT2400 rfkill support"
- depends on RT2400PCI && INPUT
+ bool "Ralink rt2400 rfkill support"
+ depends on RT2400PCI
select RT2X00_LIB_RFKILL
---help---
- This adds support for integrated rt2400 devices that feature a
+ This adds support for integrated rt2400 hardware that features a
hardware button to control the radio state.
This feature depends on the RF switch subsystem rfkill.
config RT2400PCI_LEDS
- bool "RT2400 leds support"
+ bool "Ralink rt2400 leds support"
depends on RT2400PCI && NEW_LEDS
select LEDS_CLASS
select RT2X00_LIB_LEDS
@@ -68,26 +71,27 @@ config RT2400PCI_LEDS
This adds support for led triggers provided my mac80211.
config RT2500PCI
- tristate "Ralink rt2500 pci/pcmcia support"
+ tristate "Ralink rt2500 (PCI/PCMCIA) support"
depends on PCI
select RT2X00_LIB_PCI
select EEPROM_93CX6
---help---
- This is an experimental driver for the Ralink rt2500 wireless chip.
+ This adds support for rt2500 wireless chipset family.
+ Supported chips: RT2560.
When compiled as a module, this driver will be called "rt2500pci.ko".
config RT2500PCI_RFKILL
- bool "RT2500 rfkill support"
- depends on RT2500PCI && INPUT
+ bool "Ralink rt2500 rfkill support"
+ depends on RT2500PCI
select RT2X00_LIB_RFKILL
---help---
- This adds support for integrated rt2500 devices that feature a
+ This adds support for integrated rt2500 hardware that features a
hardware button to control the radio state.
This feature depends on the RF switch subsystem rfkill.
config RT2500PCI_LEDS
- bool "RT2500 leds support"
+ bool "Ralink rt2500 leds support"
depends on RT2500PCI && NEW_LEDS
select LEDS_CLASS
select RT2X00_LIB_LEDS
@@ -95,28 +99,29 @@ config RT2500PCI_LEDS
This adds support for led triggers provided my mac80211.
config RT61PCI
- tristate "Ralink rt61 pci/pcmcia support"
+ tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
depends on PCI
select RT2X00_LIB_PCI
select RT2X00_LIB_FIRMWARE
select CRC_ITU_T
select EEPROM_93CX6
---help---
- This is an experimental driver for the Ralink rt61 wireless chip.
+ This adds support for rt2501 wireless chipset family.
+ Supported chips: RT2561, RT2561S & RT2661.
When compiled as a module, this driver will be called "rt61pci.ko".
config RT61PCI_RFKILL
- bool "RT61 rfkill support"
- depends on RT61PCI && INPUT
+ bool "Ralink rt2501/rt61 rfkill support"
+ depends on RT61PCI
select RT2X00_LIB_RFKILL
---help---
- This adds support for integrated rt61 devices that feature a
+ This adds support for integrated rt61 hardware that features a
hardware button to control the radio state.
This feature depends on the RF switch subsystem rfkill.
config RT61PCI_LEDS
- bool "RT61 leds support"
+ bool "Ralink rt2501/rt61 leds support"
depends on RT61PCI && NEW_LEDS
select LEDS_CLASS
select RT2X00_LIB_LEDS
@@ -124,16 +129,17 @@ config RT61PCI_LEDS
This adds support for led triggers provided my mac80211.
config RT2500USB
- tristate "Ralink rt2500 usb support"
+ tristate "Ralink rt2500 (USB) support"
depends on USB
select RT2X00_LIB_USB
---help---
- This is an experimental driver for the Ralink rt2500 wireless chip.
+ This adds support for rt2500 wireless chipset family.
+ Supported chips: RT2571 & RT2572.
When compiled as a module, this driver will be called "rt2500usb.ko".
config RT2500USB_LEDS
- bool "RT2500 leds support"
+ bool "Ralink rt2500 leds support"
depends on RT2500USB && NEW_LEDS
select LEDS_CLASS
select RT2X00_LIB_LEDS
@@ -141,18 +147,19 @@ config RT2500USB_LEDS
This adds support for led triggers provided my mac80211.
config RT73USB
- tristate "Ralink rt73 usb support"
+ tristate "Ralink rt2501/rt73 (USB) support"
depends on USB
select RT2X00_LIB_USB
select RT2X00_LIB_FIRMWARE
select CRC_ITU_T
---help---
- This is an experimental driver for the Ralink rt73 wireless chip.
+ This adds support for rt2501 wireless chipset family.
+ Supported chips: RT2571W, RT2573 & RT2671.
When compiled as a module, this driver will be called "rt73usb.ko".
config RT73USB_LEDS
- bool "RT73 leds support"
+ bool "Ralink rt2501/rt73 leds support"
depends on RT73USB && NEW_LEDS
select LEDS_CLASS
select RT2X00_LIB_LEDS
@@ -165,7 +172,7 @@ config RT2X00_LIB_DEBUGFS
---help---
Enable creation of debugfs files for the rt2x00 drivers.
These debugfs files support both reading and writing of the
- most important register types of the rt2x00 devices.
+ most important register types of the rt2x00 hardware.
config RT2X00_DEBUG
bool "Ralink debug output"
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index b36ed1c6c74..4c0538d6099 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -277,6 +277,17 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev,
return 0;
}
+
+static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt2400pci_brightness_set;
+ led->led_dev.blink_set = rt2400pci_blink_set;
+ led->flags = LED_INITIALIZED;
+}
#endif /* CONFIG_RT2400PCI_LEDS */
/*
@@ -620,48 +631,38 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 word;
- rt2x00_desc_read(priv_rx->desc, 2, &word);
- rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH,
- entry->queue->data_size);
- rt2x00_desc_write(priv_rx->desc, 2, word);
+ rt2x00_desc_read(entry_priv->desc, 2, &word);
+ rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
+ rt2x00_desc_write(entry_priv->desc, 2, word);
- rt2x00_desc_read(priv_rx->desc, 1, &word);
- rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma);
- rt2x00_desc_write(priv_rx->desc, 1, word);
+ rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
- rt2x00_desc_read(priv_rx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
- rt2x00_desc_write(priv_rx->desc, 0, word);
+ rt2x00_desc_write(entry_priv->desc, 0, word);
}
static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
u32 word;
- rt2x00_desc_read(priv_tx->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma);
- rt2x00_desc_write(priv_tx->desc, 1, word);
-
- rt2x00_desc_read(priv_tx->desc, 2, &word);
- rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH,
- entry->queue->data_size);
- rt2x00_desc_write(priv_tx->desc, 2, word);
-
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
- rt2x00_desc_write(priv_tx->desc, 0, word);
+ rt2x00_desc_write(entry_priv->desc, 0, word);
}
static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
{
- struct queue_entry_priv_pci_rx *priv_rx;
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
u32 reg;
/*
@@ -674,28 +675,28 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit);
rt2x00pci_register_write(rt2x00dev, TXCSR2, reg);
- priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR3, &reg);
rt2x00_set_field32(&reg, TXCSR3_TX_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR3, reg);
- priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR5, &reg);
rt2x00_set_field32(&reg, TXCSR5_PRIO_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR5, reg);
- priv_tx = rt2x00dev->bcn[1].entries[0].priv_data;
+ entry_priv = rt2x00dev->bcn[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR4, &reg);
rt2x00_set_field32(&reg, TXCSR4_ATIM_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR4, reg);
- priv_tx = rt2x00dev->bcn[0].entries[0].priv_data;
+ entry_priv = rt2x00dev->bcn[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR6, &reg);
rt2x00_set_field32(&reg, TXCSR6_BEACON_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR6, reg);
rt2x00pci_register_read(rt2x00dev, RXCSR1, &reg);
@@ -703,9 +704,10 @@ static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, RXCSR1_NUM_RXD, rt2x00dev->rx->limit);
rt2x00pci_register_write(rt2x00dev, RXCSR1, reg);
- priv_rx = rt2x00dev->rx->entries[0].priv_data;
+ entry_priv = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RXCSR2, &reg);
- rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma);
+ rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER,
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
return 0;
@@ -801,25 +803,32 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
- u16 eeprom;
- u8 reg_id;
u8 value;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2400pci_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
- goto continue_csr_init;
- NOTICE(rt2x00dev, "Waiting for BBP register.\n");
+ return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
+}
+
+static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 reg_id;
+ u8 value;
+
+ if (unlikely(rt2400pci_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
-continue_csr_init:
rt2400pci_bbp_write(rt2x00dev, 1, 0x00);
rt2400pci_bbp_write(rt2x00dev, 3, 0x27);
rt2400pci_bbp_write(rt2x00dev, 4, 0x08);
@@ -858,7 +867,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
- state == STATE_RADIO_RX_OFF);
+ (state == STATE_RADIO_RX_OFF) ||
+ (state == STATE_RADIO_RX_OFF_LINK));
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
@@ -895,17 +905,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all registers.
*/
- if (rt2400pci_init_queues(rt2x00dev) ||
- rt2400pci_init_registers(rt2x00dev) ||
- rt2400pci_init_bbp(rt2x00dev)) {
- ERROR(rt2x00dev, "Register initialization failed.\n");
+ if (unlikely(rt2400pci_init_queues(rt2x00dev) ||
+ rt2400pci_init_registers(rt2x00dev) ||
+ rt2400pci_init_bbp(rt2x00dev)))
return -EIO;
- }
-
- /*
- * Enable interrupts.
- */
- rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
return 0;
}
@@ -927,11 +930,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-
- /*
- * Disable interrupts.
- */
- rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);
}
static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -966,10 +964,6 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
msleep(10);
}
- NOTICE(rt2x00dev, "Device failed to enter state %d, "
- "current device state: bbp %d and rf %d.\n",
- state, bbp_state, rf_state);
-
return -EBUSY;
}
@@ -987,11 +981,13 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
case STATE_RADIO_RX_ON:
case STATE_RADIO_RX_ON_LINK:
- rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
- break;
case STATE_RADIO_RX_OFF:
case STATE_RADIO_RX_OFF_LINK:
- rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2400pci_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ rt2400pci_toggle_irq(rt2x00dev, state);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
@@ -1004,6 +1000,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
}
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
return retval;
}
@@ -1012,18 +1012,23 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
- struct txentry_desc *txdesc,
- struct ieee80211_tx_control *control)
+ struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
__le32 *txd = skbdesc->desc;
u32 word;
/*
* Start writing the descriptor words.
*/
+ rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
+
rt2x00_desc_read(txd, 2, &word);
- rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len);
+ rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
@@ -1057,20 +1062,53 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
- !!(control->flags &
- IEEE80211_TXCTL_LONG_RETRY_LIMIT));
+ test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_desc_write(txd, 0, word);
}
/*
* TX data initialization
*/
+static void rt2400pci_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ u32 word;
+ u32 reg;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+ /*
+ * Replace rt2x00lib allocated descriptor with the
+ * pointer to the _real_ hardware descriptor.
+ * After that, map the beacon to DMA and update the
+ * descriptor.
+ */
+ memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
+ skbdesc->desc = entry_priv->desc;
+
+ rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+
+ rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
+}
+
static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue)
+ const enum data_queue_qid queue)
{
u32 reg;
- if (queue == RT2X00_BCN_QUEUE_BEACON) {
+ if (queue == QID_BEACON) {
rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
@@ -1082,12 +1120,9 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO,
- (queue == IEEE80211_TX_QUEUE_DATA0));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX,
- (queue == IEEE80211_TX_QUEUE_DATA1));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM,
- (queue == RT2X00_BCN_QUEUE_ATIM));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
@@ -1097,32 +1132,54 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
static void rt2400pci_fill_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc)
{
- struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
u32 word0;
u32 word2;
u32 word3;
+ u32 word4;
+ u64 tsf;
+ u32 rx_low;
+ u32 rx_high;
- rt2x00_desc_read(priv_rx->desc, 0, &word0);
- rt2x00_desc_read(priv_rx->desc, 2, &word2);
- rt2x00_desc_read(priv_rx->desc, 3, &word3);
+ rt2x00_desc_read(entry_priv->desc, 0, &word0);
+ rt2x00_desc_read(entry_priv->desc, 2, &word2);
+ rt2x00_desc_read(entry_priv->desc, 3, &word3);
+ rt2x00_desc_read(entry_priv->desc, 4, &word4);
- rxdesc->flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC;
/*
+ * We only get the lower 32bits from the timestamp,
+ * to get the full 64bits we must complement it with
+ * the timestamp from get_tsf().
+ * Note that when a wraparound of the lower 32bits
+ * has occurred between the frame arrival and the get_tsf()
+ * call, we must decrease the higher 32bits with 1 to get
+ * to correct value.
+ */
+ tsf = rt2x00dev->ops->hw->get_tsf(rt2x00dev->hw);
+ rx_low = rt2x00_get_field32(word4, RXD_W4_RX_END_TIME);
+ rx_high = upper_32_bits(tsf);
+
+ if ((u32)tsf <= rx_low)
+ rx_high--;
+
+ /*
* Obtain the status about this packet.
* The signal is the PLCP value, and needs to be stripped
* of the preamble bit (0x08).
*/
+ rxdesc->timestamp = ((u64)rx_high << 32) | rx_low;
rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08;
rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) -
entry->queue->rt2x00dev->rssi_offset;
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- rxdesc->dev_flags = RXDONE_SIGNAL_PLCP;
+ rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
rxdesc->dev_flags |= RXDONE_MY_BSS;
}
@@ -1131,18 +1188,18 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry,
* Interrupt functions.
*/
static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
- const enum ieee80211_tx_queue queue_idx)
+ const enum data_queue_qid queue_idx)
{
struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
struct queue_entry *entry;
struct txdone_entry_desc txdesc;
u32 word;
while (!rt2x00queue_empty(queue)) {
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- priv_tx = entry->priv_data;
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ entry_priv = entry->priv_data;
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
!rt2x00_get_field32(word, TXD_W0_VALID))
@@ -1151,10 +1208,21 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev,
/*
* Obtain the status about this packet.
*/
- txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT);
+ txdesc.flags = 0;
+ switch (rt2x00_get_field32(word, TXD_W0_RESULT)) {
+ case 0: /* Success */
+ case 1: /* Success with retry */
+ __set_bit(TXDONE_SUCCESS, &txdesc.flags);
+ break;
+ case 2: /* Failure, excessive retries */
+ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+ /* Don't break, this is a failed frame! */
+ default: /* Failure */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ }
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
- rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
+ rt2x00lib_txdone(entry, &txdesc);
}
}
@@ -1198,19 +1266,19 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
* 3 - Atim ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING))
- rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM);
+ rt2400pci_txdone(rt2x00dev, QID_ATIM);
/*
* 4 - Priority ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
- rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
+ rt2400pci_txdone(rt2x00dev, QID_AC_BE);
/*
* 5 - Tx ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
- rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
+ rt2400pci_txdone(rt2x00dev, QID_AC_BK);
return IRQ_HANDLED;
}
@@ -1309,23 +1377,10 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_RT2400PCI_LEDS
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
- rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
- rt2x00dev->led_radio.type = LED_TYPE_RADIO;
- rt2x00dev->led_radio.led_dev.brightness_set =
- rt2400pci_brightness_set;
- rt2x00dev->led_radio.led_dev.blink_set =
- rt2400pci_blink_set;
- rt2x00dev->led_radio.flags = LED_INITIALIZED;
-
- if (value == LED_MODE_TXRX_ACTIVITY) {
- rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
- rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY;
- rt2x00dev->led_qual.led_dev.brightness_set =
- rt2400pci_brightness_set;
- rt2x00dev->led_qual.led_dev.blink_set =
- rt2400pci_blink_set;
- rt2x00dev->led_qual.flags = LED_INITIALIZED;
- }
+ rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ if (value == LED_MODE_TXRX_ACTIVITY)
+ rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
+ LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2400PCI_LEDS */
/*
@@ -1375,13 +1430,11 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all hw fields.
*/
- rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+ rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM;
rt2x00dev->hw->extra_tx_headroom = 0;
- rt2x00dev->hw->max_signal = MAX_SIGNAL;
- rt2x00dev->hw->max_rssi = MAX_RX_SSI;
- rt2x00dev->hw->queues = 2;
- SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
@@ -1427,9 +1480,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
rt2400pci_probe_hw_mode(rt2x00dev);
/*
- * This device requires the atim queue
+ * This device requires the atim queue and DMA-mapped skbs.
*/
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
/*
* Set the rssi offset.
@@ -1456,8 +1510,7 @@ static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
return 0;
}
-static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
- int queue,
+static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1467,7 +1520,7 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw,
* per queue. So by default we only configure the TX queue,
* and ignore all other configurations.
*/
- if (queue != IEEE80211_TX_QUEUE_DATA0)
+ if (queue != 0)
return -EINVAL;
if (rt2x00mac_conf_tx(hw, queue, params))
@@ -1496,60 +1549,6 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw)
return tsf;
}
-static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(control->vif);
- struct queue_entry_priv_pci_tx *priv_tx;
- struct skb_frame_desc *skbdesc;
- u32 reg;
-
- if (unlikely(!intf->beacon))
- return -ENOBUFS;
- priv_tx = intf->beacon->priv_data;
-
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
- skbdesc->desc = priv_tx->desc;
- skbdesc->desc_len = intf->beacon->queue->desc_size;
- skbdesc->entry = intf->beacon;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
- rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
- rt2x00_set_field32(&reg, CSR14_TBCN, 0);
- rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
- rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-
- /*
- * mac80211 doesn't provide the control->queue variable
- * for beacons. Set our own queue identification so
- * it can be used during descriptor initialization.
- */
- control->queue = RT2X00_BCN_QUEUE_BEACON;
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
- /*
- * Enable beacon generation.
- * Write entire beacon with descriptor to register,
- * and kick the beacon generator.
- */
- memcpy(priv_tx->data, skb->data, skb->len);
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
-
- return 0;
-}
-
static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1574,7 +1573,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.conf_tx = rt2400pci_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt2400pci_get_tsf,
- .beacon_update = rt2400pci_beacon_update,
.tx_last_beacon = rt2400pci_tx_last_beacon,
};
@@ -1592,6 +1590,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.link_tuner = rt2400pci_link_tuner,
.write_tx_desc = rt2400pci_write_tx_desc,
.write_tx_data = rt2x00pci_write_tx_data,
+ .write_beacon = rt2400pci_write_beacon,
.kick_tx_queue = rt2400pci_kick_tx_queue,
.fill_rxdone = rt2400pci_fill_rxdone,
.config_filter = rt2400pci_config_filter,
@@ -1604,28 +1603,28 @@ static const struct data_queue_desc rt2400pci_queue_rx = {
.entry_num = RX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_rx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_tx = {
.entry_num = TX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_bcn = {
.entry_num = BEACON_ENTRIES,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2400pci_queue_atim = {
.entry_num = ATIM_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct rt2x00_ops rt2400pci_ops = {
@@ -1634,6 +1633,7 @@ static const struct rt2x00_ops rt2400pci_ops = {
.max_ap_intf = 1,
.eeprom_size = EEPROM_SIZE,
.rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
.rx = &rt2400pci_queue_rx,
.tx = &rt2400pci_queue_tx,
.bcn = &rt2400pci_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index a5210f9a336..bc556425822 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -37,8 +37,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 100
/*
@@ -52,6 +50,11 @@
#define RF_SIZE 0x0010
/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 2
+
+/*
* Control/Status Registers(CSR).
* Some values are set in TU, whereas 1 TU == 1024 us.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index f7731fb8255..aa6dfb811c7 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -277,6 +277,17 @@ static int rt2500pci_blink_set(struct led_classdev *led_cdev,
return 0;
}
+
+static void rt2500pci_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt2500pci_brightness_set;
+ led->led_dev.blink_set = rt2500pci_blink_set;
+ led->flags = LED_INITIALIZED;
+}
#endif /* CONFIG_RT2500PCI_LEDS */
/*
@@ -317,8 +328,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00intf_conf *conf,
const unsigned int flags)
{
- struct data_queue *queue =
- rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON);
+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON);
unsigned int bcn_preload;
u32 reg;
@@ -716,38 +726,34 @@ dynamic_cca_tune:
static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 word;
- rt2x00_desc_read(priv_rx->desc, 1, &word);
- rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma);
- rt2x00_desc_write(priv_rx->desc, 1, word);
+ rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
- rt2x00_desc_read(priv_rx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
- rt2x00_desc_write(priv_rx->desc, 0, word);
+ rt2x00_desc_write(entry_priv->desc, 0, word);
}
static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
u32 word;
- rt2x00_desc_read(priv_tx->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma);
- rt2x00_desc_write(priv_tx->desc, 1, word);
-
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
- rt2x00_desc_write(priv_tx->desc, 0, word);
+ rt2x00_desc_write(entry_priv->desc, 0, word);
}
static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
{
- struct queue_entry_priv_pci_rx *priv_rx;
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
u32 reg;
/*
@@ -760,28 +766,28 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit);
rt2x00pci_register_write(rt2x00dev, TXCSR2, reg);
- priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR3, &reg);
rt2x00_set_field32(&reg, TXCSR3_TX_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR3, reg);
- priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR5, &reg);
rt2x00_set_field32(&reg, TXCSR5_PRIO_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR5, reg);
- priv_tx = rt2x00dev->bcn[1].entries[0].priv_data;
+ entry_priv = rt2x00dev->bcn[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR4, &reg);
rt2x00_set_field32(&reg, TXCSR4_ATIM_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR4, reg);
- priv_tx = rt2x00dev->bcn[0].entries[0].priv_data;
+ entry_priv = rt2x00dev->bcn[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, TXCSR6, &reg);
rt2x00_set_field32(&reg, TXCSR6_BEACON_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, TXCSR6, reg);
rt2x00pci_register_read(rt2x00dev, RXCSR1, &reg);
@@ -789,9 +795,10 @@ static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, RXCSR1_NUM_RXD, rt2x00dev->rx->limit);
rt2x00pci_register_write(rt2x00dev, RXCSR1, reg);
- priv_rx = rt2x00dev->rx->entries[0].priv_data;
+ entry_priv = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RXCSR2, &reg);
- rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER, priv_rx->desc_dma);
+ rt2x00_set_field32(&reg, RXCSR2_RX_RING_REGISTER,
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, RXCSR2, reg);
return 0;
@@ -940,25 +947,32 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
- u16 eeprom;
- u8 reg_id;
u8 value;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2500pci_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
- goto continue_csr_init;
- NOTICE(rt2x00dev, "Waiting for BBP register.\n");
+ return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
+}
+
+static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 reg_id;
+ u8 value;
+
+ if (unlikely(rt2500pci_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
-continue_csr_init:
rt2500pci_bbp_write(rt2x00dev, 3, 0x02);
rt2500pci_bbp_write(rt2x00dev, 4, 0x19);
rt2500pci_bbp_write(rt2x00dev, 14, 0x1c);
@@ -1013,7 +1027,8 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
- state == STATE_RADIO_RX_OFF);
+ (state == STATE_RADIO_RX_OFF) ||
+ (state == STATE_RADIO_RX_OFF_LINK));
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
@@ -1050,17 +1065,10 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all registers.
*/
- if (rt2500pci_init_queues(rt2x00dev) ||
- rt2500pci_init_registers(rt2x00dev) ||
- rt2500pci_init_bbp(rt2x00dev)) {
- ERROR(rt2x00dev, "Register initialization failed.\n");
+ if (unlikely(rt2500pci_init_queues(rt2x00dev) ||
+ rt2500pci_init_registers(rt2x00dev) ||
+ rt2500pci_init_bbp(rt2x00dev)))
return -EIO;
- }
-
- /*
- * Enable interrupts.
- */
- rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
return 0;
}
@@ -1082,11 +1090,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
-
- /*
- * Disable interrupts.
- */
- rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);
}
static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1121,10 +1124,6 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
msleep(10);
}
- NOTICE(rt2x00dev, "Device failed to enter state %d, "
- "current device state: bbp %d and rf %d.\n",
- state, bbp_state, rf_state);
-
return -EBUSY;
}
@@ -1142,11 +1141,13 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
case STATE_RADIO_RX_ON:
case STATE_RADIO_RX_ON_LINK:
- rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
- break;
case STATE_RADIO_RX_OFF:
case STATE_RADIO_RX_OFF_LINK:
- rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2500pci_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ rt2500pci_toggle_irq(rt2x00dev, state);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
@@ -1159,6 +1160,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
}
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
return retval;
}
@@ -1167,16 +1172,20 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
- struct txentry_desc *txdesc,
- struct ieee80211_tx_control *control)
+ struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+ struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
__le32 *txd = skbdesc->desc;
u32 word;
/*
* Start writing the descriptor words.
*/
+ rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
+
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs);
@@ -1210,9 +1219,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
- !!(control->flags &
- IEEE80211_TXCTL_LONG_RETRY_LIMIT));
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
rt2x00_desc_write(txd, 0, word);
}
@@ -1220,12 +1227,46 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* TX data initialization
*/
+static void rt2500pci_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ u32 word;
+ u32 reg;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+ rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+ rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+ rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
+ /*
+ * Replace rt2x00lib allocated descriptor with the
+ * pointer to the _real_ hardware descriptor.
+ * After that, map the beacon to DMA and update the
+ * descriptor.
+ */
+ memcpy(entry_priv->desc, skbdesc->desc, skbdesc->desc_len);
+ skbdesc->desc = entry_priv->desc;
+
+ rt2x00queue_map_txskb(rt2x00dev, entry->skb);
+
+ rt2x00_desc_read(entry_priv->desc, 1, &word);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 1, word);
+}
+
static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue)
+ const enum data_queue_qid queue)
{
u32 reg;
- if (queue == RT2X00_BCN_QUEUE_BEACON) {
+ if (queue == QID_BEACON) {
rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) {
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
@@ -1237,12 +1278,9 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO,
- (queue == IEEE80211_TX_QUEUE_DATA0));
- rt2x00_set_field32(&reg, TXCSR0_KICK_TX,
- (queue == IEEE80211_TX_QUEUE_DATA1));
- rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM,
- (queue == RT2X00_BCN_QUEUE_ATIM));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, (queue == QID_AC_BE));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_TX, (queue == QID_AC_BK));
+ rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, (queue == QID_ATIM));
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
@@ -1252,14 +1290,13 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
static void rt2500pci_fill_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc)
{
- struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
u32 word0;
u32 word2;
- rt2x00_desc_read(priv_rx->desc, 0, &word0);
- rt2x00_desc_read(priv_rx->desc, 2, &word2);
+ rt2x00_desc_read(entry_priv->desc, 0, &word0);
+ rt2x00_desc_read(entry_priv->desc, 2, &word2);
- rxdesc->flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
@@ -1276,7 +1313,6 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,
entry->queue->rt2x00dev->rssi_offset;
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- rxdesc->dev_flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_OFDM))
rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
@@ -1287,18 +1323,18 @@ static void rt2500pci_fill_rxdone(struct queue_entry *entry,
* Interrupt functions.
*/
static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
- const enum ieee80211_tx_queue queue_idx)
+ const enum data_queue_qid queue_idx)
{
struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
struct queue_entry *entry;
struct txdone_entry_desc txdesc;
u32 word;
while (!rt2x00queue_empty(queue)) {
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
- priv_tx = entry->priv_data;
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ entry_priv = entry->priv_data;
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
!rt2x00_get_field32(word, TXD_W0_VALID))
@@ -1307,10 +1343,21 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev,
/*
* Obtain the status about this packet.
*/
- txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT);
+ txdesc.flags = 0;
+ switch (rt2x00_get_field32(word, TXD_W0_RESULT)) {
+ case 0: /* Success */
+ case 1: /* Success with retry */
+ __set_bit(TXDONE_SUCCESS, &txdesc.flags);
+ break;
+ case 2: /* Failure, excessive retries */
+ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+ /* Don't break, this is a failed frame! */
+ default: /* Failure */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ }
txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
- rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
+ rt2x00lib_txdone(entry, &txdesc);
}
}
@@ -1354,19 +1401,19 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
* 3 - Atim ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING))
- rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM);
+ rt2500pci_txdone(rt2x00dev, QID_ATIM);
/*
* 4 - Priority ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_PRIORING))
- rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
+ rt2500pci_txdone(rt2x00dev, QID_AC_BE);
/*
* 5 - Tx ring transmit done interrupt.
*/
if (rt2x00_get_field32(reg, CSR7_TXDONE_TXRING))
- rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
+ rt2500pci_txdone(rt2x00dev, QID_AC_BK);
return IRQ_HANDLED;
}
@@ -1486,23 +1533,10 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_RT2500PCI_LEDS
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
- rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
- rt2x00dev->led_radio.type = LED_TYPE_RADIO;
- rt2x00dev->led_radio.led_dev.brightness_set =
- rt2500pci_brightness_set;
- rt2x00dev->led_radio.led_dev.blink_set =
- rt2500pci_blink_set;
- rt2x00dev->led_radio.flags = LED_INITIALIZED;
-
- if (value == LED_MODE_TXRX_ACTIVITY) {
- rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
- rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY;
- rt2x00dev->led_qual.led_dev.brightness_set =
- rt2500pci_brightness_set;
- rt2x00dev->led_qual.led_dev.blink_set =
- rt2500pci_blink_set;
- rt2x00dev->led_qual.flags = LED_INITIALIZED;
- }
+ rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ if (value == LED_MODE_TXRX_ACTIVITY)
+ rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
+ LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2500PCI_LEDS */
/*
@@ -1695,13 +1729,12 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all hw fields.
*/
- rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+ rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM;
+
rt2x00dev->hw->extra_tx_headroom = 0;
- rt2x00dev->hw->max_signal = MAX_SIGNAL;
- rt2x00dev->hw->max_rssi = MAX_RX_SSI;
- rt2x00dev->hw->queues = 2;
- SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
@@ -1765,9 +1798,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
rt2500pci_probe_hw_mode(rt2x00dev);
/*
- * This device requires the atim queue
+ * This device requires the atim queue and DMA-mapped skbs.
*/
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
/*
* Set the rssi offset.
@@ -1808,61 +1842,6 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw)
return tsf;
}
-static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(control->vif);
- struct queue_entry_priv_pci_tx *priv_tx;
- struct skb_frame_desc *skbdesc;
- u32 reg;
-
- if (unlikely(!intf->beacon))
- return -ENOBUFS;
-
- priv_tx = intf->beacon->priv_data;
-
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
- skbdesc->desc = priv_tx->desc;
- skbdesc->desc_len = intf->beacon->queue->desc_size;
- skbdesc->entry = intf->beacon;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
- rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
- rt2x00_set_field32(&reg, CSR14_TBCN, 0);
- rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
- rt2x00pci_register_write(rt2x00dev, CSR14, reg);
-
- /*
- * mac80211 doesn't provide the control->queue variable
- * for beacons. Set our own queue identification so
- * it can be used during descriptor initialization.
- */
- control->queue = RT2X00_BCN_QUEUE_BEACON;
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
- /*
- * Enable beacon generation.
- * Write entire beacon with descriptor to register,
- * and kick the beacon generator.
- */
- memcpy(priv_tx->data, skb->data, skb->len);
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
-
- return 0;
-}
-
static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1887,7 +1866,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt2500pci_get_tsf,
- .beacon_update = rt2500pci_beacon_update,
.tx_last_beacon = rt2500pci_tx_last_beacon,
};
@@ -1905,6 +1883,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.link_tuner = rt2500pci_link_tuner,
.write_tx_desc = rt2500pci_write_tx_desc,
.write_tx_data = rt2x00pci_write_tx_data,
+ .write_beacon = rt2500pci_write_beacon,
.kick_tx_queue = rt2500pci_kick_tx_queue,
.fill_rxdone = rt2500pci_fill_rxdone,
.config_filter = rt2500pci_config_filter,
@@ -1917,28 +1896,28 @@ static const struct data_queue_desc rt2500pci_queue_rx = {
.entry_num = RX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_rx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_tx = {
.entry_num = TX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_bcn = {
.entry_num = BEACON_ENTRIES,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt2500pci_queue_atim = {
.entry_num = ATIM_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct rt2x00_ops rt2500pci_ops = {
@@ -1947,6 +1926,7 @@ static const struct rt2x00_ops rt2500pci_ops = {
.max_ap_intf = 1,
.eeprom_size = EEPROM_SIZE,
.rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
.rx = &rt2500pci_queue_rx,
.tx = &rt2500pci_queue_tx,
.bcn = &rt2500pci_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 13899550465..42f376929ea 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -48,8 +48,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 121
/*
@@ -63,6 +61,11 @@
#define RF_SIZE 0x0014
/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 2
+
+/*
* Control/Status Registers(CSR).
* Some values are set in TU, whereas 1 TU == 1024 us.
*/
@@ -748,7 +751,7 @@
#define LEDCSR_LED_DEFAULT FIELD32(0x00100000)
/*
- * AES control register.
+ * SECCSR3: AES control register.
*/
#define SECCSR3 0x00fc
@@ -892,7 +895,7 @@
#define ARTCSR2_ACK_CTS_54MBS FIELD32(0xff000000)
/*
- * SECCSR1_RT2509: WEP control register.
+ * SECCSR1: WEP control register.
* KICK_ENCRYPT: Kick encryption engine, self-clear.
* ONE_SHOT: 0: ring mode, 1: One shot only mode.
* DESC_ADDRESS: Descriptor physical address of frame.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index d90512f97b3..3558cb21074 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -76,10 +76,10 @@ static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u16 length)
{
- int timeout = REGISTER_TIMEOUT * (length / sizeof(u16));
rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
USB_VENDOR_REQUEST_IN, offset,
- value, length, timeout);
+ value, length,
+ REGISTER_TIMEOUT16(length));
}
static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
@@ -106,10 +106,10 @@ static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u16 length)
{
- int timeout = REGISTER_TIMEOUT * (length / sizeof(u16));
rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
USB_VENDOR_REQUEST_OUT, offset,
- value, length, timeout);
+ value, length,
+ REGISTER_TIMEOUT16(length));
}
static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev)
@@ -322,6 +322,17 @@ static int rt2500usb_blink_set(struct led_classdev *led_cdev,
return 0;
}
+
+static void rt2500usb_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt2500usb_brightness_set;
+ led->led_dev.blink_set = rt2500usb_blink_set;
+ led->flags = LED_INITIALIZED;
+}
#endif /* CONFIG_RT2500USB_LEDS */
/*
@@ -860,25 +871,32 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt2500usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
- u16 eeprom;
u8 value;
- u8 reg_id;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2500usb_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
- goto continue_csr_init;
- NOTICE(rt2x00dev, "Waiting for BBP register.\n");
+ return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
+}
+
+static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 value;
+ u8 reg_id;
+
+ if (unlikely(rt2500usb_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
-continue_csr_init:
rt2500usb_bbp_write(rt2x00dev, 3, 0x02);
rt2500usb_bbp_write(rt2x00dev, 4, 0x19);
rt2500usb_bbp_write(rt2x00dev, 14, 0x1c);
@@ -934,7 +952,8 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
rt2x00_set_field16(&reg, TXRX_CSR2_DISABLE_RX,
- state == STATE_RADIO_RX_OFF);
+ (state == STATE_RADIO_RX_OFF) ||
+ (state == STATE_RADIO_RX_OFF_LINK));
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
}
@@ -943,11 +962,9 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all registers.
*/
- if (rt2500usb_init_registers(rt2x00dev) ||
- rt2500usb_init_bbp(rt2x00dev)) {
- ERROR(rt2x00dev, "Register initialization failed.\n");
+ if (unlikely(rt2500usb_init_registers(rt2x00dev) ||
+ rt2500usb_init_bbp(rt2x00dev)))
return -EIO;
- }
return 0;
}
@@ -1000,10 +1017,6 @@ static int rt2500usb_set_state(struct rt2x00_dev *rt2x00dev,
msleep(30);
}
- NOTICE(rt2x00dev, "Device failed to enter state %d, "
- "current device state: bbp %d and rf %d.\n",
- state, bbp_state, rf_state);
-
return -EBUSY;
}
@@ -1021,11 +1034,13 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
case STATE_RADIO_RX_ON:
case STATE_RADIO_RX_ON_LINK:
- rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
- break;
case STATE_RADIO_RX_OFF:
case STATE_RADIO_RX_OFF_LINK:
- rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt2500usb_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ /* No support, but no error either */
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
@@ -1038,6 +1053,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
}
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
return retval;
}
@@ -1046,8 +1065,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
- struct txentry_desc *txdesc,
- struct ieee80211_tx_control *control)
+ struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = skbdesc->desc;
@@ -1071,7 +1089,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 0, &word);
- rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit);
+ rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, txdesc->retry_limit);
rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_ACK,
@@ -1081,13 +1099,73 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_OFDM,
test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
- !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT));
+ test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT,
+ skb->len - skbdesc->desc_len);
rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE);
rt2x00_desc_write(txd, 0, word);
}
+/*
+ * TX data initialization
+ */
+static void rt2500usb_beacondone(struct urb *urb);
+
+static void rt2500usb_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ int pipe = usb_sndbulkpipe(usb_dev, 1);
+ int length;
+ u16 reg;
+
+ /*
+ * Add the descriptor in front of the skb.
+ */
+ skb_push(entry->skb, entry->queue->desc_size);
+ memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
+ skbdesc->desc = entry->skb->data;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
+ rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
+ rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+
+ /*
+ * USB devices cannot blindly pass the skb->len as the
+ * length of the data to usb_fill_bulk_urb. Pass the skb
+ * to the driver to determine what the length should be.
+ */
+ length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);
+
+ usb_fill_bulk_urb(bcn_priv->urb, usb_dev, pipe,
+ entry->skb->data, length, rt2500usb_beacondone,
+ entry);
+
+ /*
+ * Second we need to create the guardian byte.
+ * We only need a single byte, so lets recycle
+ * the 'flags' field we are not using for beacons.
+ */
+ bcn_priv->guardian_data = 0;
+ usb_fill_bulk_urb(bcn_priv->guardian_urb, usb_dev, pipe,
+ &bcn_priv->guardian_data, 1, rt2500usb_beacondone,
+ entry);
+
+ /*
+ * Send out the guardian byte.
+ */
+ usb_submit_urb(bcn_priv->guardian_urb, GFP_ATOMIC);
+}
+
static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb)
{
@@ -1103,16 +1181,15 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
return length;
}
-/*
- * TX data initialization
- */
static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue)
+ const enum data_queue_qid queue)
{
u16 reg;
- if (queue != RT2X00_BCN_QUEUE_BEACON)
+ if (queue != QID_BEACON) {
+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);
return;
+ }
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
@@ -1138,30 +1215,28 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
static void rt2500usb_fill_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc)
{
- struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data;
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
__le32 *rxd =
(__le32 *)(entry->skb->data +
- (priv_rx->urb->actual_length - entry->queue->desc_size));
- unsigned int offset = entry->queue->desc_size + 2;
+ (entry_priv->urb->actual_length -
+ entry->queue->desc_size));
u32 word0;
u32 word1;
/*
- * Copy descriptor to the available headroom inside the skbuffer.
+ * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of
+ * frame data in rt2x00usb.
*/
- skb_push(entry->skb, offset);
- memcpy(entry->skb->data, rxd, entry->queue->desc_size);
- rxd = (__le32 *)entry->skb->data;
+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
+ rxd = (__le32 *)skbdesc->desc;
/*
- * The descriptor is now aligned to 4 bytes and thus it is
- * now safe to read it on all architectures.
+ * It is now safe to read the descriptor on all architectures.
*/
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
- rxdesc->flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
@@ -1178,7 +1253,6 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
entry->queue->rt2x00dev->rssi_offset;
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- rxdesc->dev_flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_OFDM))
rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
@@ -1187,16 +1261,7 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
/*
* Adjust the skb memory window to the frame boundaries.
*/
- skb_pull(entry->skb, offset);
skb_trim(entry->skb, rxdesc->size);
-
- /*
- * Set descriptor and data pointer.
- */
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = rxdesc->size;
- skbdesc->desc = rxd;
- skbdesc->desc_len = entry->queue->desc_size;
}
/*
@@ -1205,7 +1270,7 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
static void rt2500usb_beacondone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
- struct queue_entry_priv_usb_bcn *priv_bcn = entry->priv_data;
+ struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags))
return;
@@ -1216,9 +1281,9 @@ static void rt2500usb_beacondone(struct urb *urb)
* Otherwise we should free the sk_buffer, the device
* should be doing the rest of the work now.
*/
- if (priv_bcn->guardian_urb == urb) {
- usb_submit_urb(priv_bcn->urb, GFP_ATOMIC);
- } else if (priv_bcn->urb == urb) {
+ if (bcn_priv->guardian_urb == urb) {
+ usb_submit_urb(bcn_priv->urb, GFP_ATOMIC);
+ } else if (bcn_priv->urb == urb) {
dev_kfree_skb(entry->skb);
entry->skb = NULL;
}
@@ -1397,23 +1462,10 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_RT2500USB_LEDS
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
- rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
- rt2x00dev->led_radio.type = LED_TYPE_RADIO;
- rt2x00dev->led_radio.led_dev.brightness_set =
- rt2500usb_brightness_set;
- rt2x00dev->led_radio.led_dev.blink_set =
- rt2500usb_blink_set;
- rt2x00dev->led_radio.flags = LED_INITIALIZED;
-
- if (value == LED_MODE_TXRX_ACTIVITY) {
- rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
- rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY;
- rt2x00dev->led_qual.led_dev.brightness_set =
- rt2500usb_brightness_set;
- rt2x00dev->led_qual.led_dev.blink_set =
- rt2500usb_blink_set;
- rt2x00dev->led_qual.flags = LED_INITIALIZED;
- }
+ rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ if (value == LED_MODE_TXRX_ACTIVITY)
+ rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual,
+ LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2500USB_LEDS */
/*
@@ -1600,13 +1652,12 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM;
+
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
- rt2x00dev->hw->max_signal = MAX_SIGNAL;
- rt2x00dev->hw->max_rssi = MAX_RX_SSI;
- rt2x00dev->hw->queues = 2;
- SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
@@ -1684,97 +1735,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
return 0;
}
-/*
- * IEEE80211 stack callback functions.
- */
-static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
- struct rt2x00_intf *intf = vif_to_intf(control->vif);
- struct queue_entry_priv_usb_bcn *priv_bcn;
- struct skb_frame_desc *skbdesc;
- int pipe = usb_sndbulkpipe(usb_dev, 1);
- int length;
- u16 reg;
-
- if (unlikely(!intf->beacon))
- return -ENOBUFS;
-
- priv_bcn = intf->beacon->priv_data;
-
- /*
- * Add the descriptor in front of the skb.
- */
- skb_push(skb, intf->beacon->queue->desc_size);
- memset(skb->data, 0, intf->beacon->queue->desc_size);
-
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
- skbdesc->data = skb->data + intf->beacon->queue->desc_size;
- skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
- skbdesc->desc = skb->data;
- skbdesc->desc_len = intf->beacon->queue->desc_size;
- skbdesc->entry = intf->beacon;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
- rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
- rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
- rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-
- /*
- * mac80211 doesn't provide the control->queue variable
- * for beacons. Set our own queue identification so
- * it can be used during descriptor initialization.
- */
- control->queue = RT2X00_BCN_QUEUE_BEACON;
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
- /*
- * USB devices cannot blindly pass the skb->len as the
- * length of the data to usb_fill_bulk_urb. Pass the skb
- * to the driver to determine what the length should be.
- */
- length = rt2500usb_get_tx_data_len(rt2x00dev, skb);
-
- usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe,
- skb->data, length, rt2500usb_beacondone,
- intf->beacon);
-
- /*
- * Second we need to create the guardian byte.
- * We only need a single byte, so lets recycle
- * the 'flags' field we are not using for beacons.
- */
- priv_bcn->guardian_data = 0;
- usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe,
- &priv_bcn->guardian_data, 1, rt2500usb_beacondone,
- intf->beacon);
-
- /*
- * Send out the guardian byte.
- */
- usb_submit_urb(priv_bcn->guardian_urb, GFP_ATOMIC);
-
- /*
- * Enable beacon generation.
- */
- rt2500usb_kick_tx_queue(rt2x00dev, control->queue);
-
- return 0;
-}
-
static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.tx = rt2x00mac_tx,
.start = rt2x00mac_start,
@@ -1788,7 +1748,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
- .beacon_update = rt2500usb_beacon_update,
};
static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1803,6 +1762,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.link_tuner = rt2500usb_link_tuner,
.write_tx_desc = rt2500usb_write_tx_desc,
.write_tx_data = rt2x00usb_write_tx_data,
+ .write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2500usb_kick_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
@@ -1816,14 +1776,14 @@ static const struct data_queue_desc rt2500usb_queue_rx = {
.entry_num = RX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_usb_rx),
+ .priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2500usb_queue_tx = {
.entry_num = TX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_usb_tx),
+ .priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt2500usb_queue_bcn = {
@@ -1837,7 +1797,7 @@ static const struct data_queue_desc rt2500usb_queue_atim = {
.entry_num = ATIM_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_usb_tx),
+ .priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct rt2x00_ops rt2500usb_ops = {
@@ -1846,6 +1806,7 @@ static const struct rt2x00_ops rt2500usb_ops = {
.max_ap_intf = 1,
.eeprom_size = EEPROM_SIZE,
.rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
.rx = &rt2500usb_queue_rx,
.tx = &rt2500usb_queue_tx,
.bcn = &rt2500usb_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index a37a068d0c7..4769ffeb4cc 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -48,8 +48,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
@@ -63,6 +61,11 @@
#define RF_SIZE 0x0014
/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 2
+
+/*
* Control/Status Registers(CSR).
* Some values are set in TU, whereas 1 TU == 1024 us.
*/
@@ -206,7 +209,7 @@
#define MAC_CSR21_OFF_PERIOD FIELD16(0xff00)
/*
- * Collision window control register.
+ * MAC_CSR22: Collision window control register.
*/
#define MAC_CSR22 0x042c
@@ -293,7 +296,7 @@
#define TXRX_CSR7_BBP_ID1_VALID FIELD16(0x8000)
/*
- * TXRX_CSR5: OFDM TX BBP ID1.
+ * TXRX_CSR8: OFDM TX BBP ID1.
*/
#define TXRX_CSR8 0x0450
#define TXRX_CSR8_BBP_ID0 FIELD16(0x007f)
@@ -367,7 +370,14 @@
*/
/*
- * SEC_CSR0-SEC_CSR7: Shared key 0, word 0-7
+ * SEC_CSR0: Shared key 0, word 0
+ * SEC_CSR1: Shared key 0, word 1
+ * SEC_CSR2: Shared key 0, word 2
+ * SEC_CSR3: Shared key 0, word 3
+ * SEC_CSR4: Shared key 0, word 4
+ * SEC_CSR5: Shared key 0, word 5
+ * SEC_CSR6: Shared key 0, word 6
+ * SEC_CSR7: Shared key 0, word 7
*/
#define SEC_CSR0 0x0480
#define SEC_CSR1 0x0482
@@ -379,7 +389,14 @@
#define SEC_CSR7 0x048e
/*
- * SEC_CSR8-SEC_CSR15: Shared key 1, word 0-7
+ * SEC_CSR8: Shared key 1, word 0
+ * SEC_CSR9: Shared key 1, word 1
+ * SEC_CSR10: Shared key 1, word 2
+ * SEC_CSR11: Shared key 1, word 3
+ * SEC_CSR12: Shared key 1, word 4
+ * SEC_CSR13: Shared key 1, word 5
+ * SEC_CSR14: Shared key 1, word 6
+ * SEC_CSR15: Shared key 1, word 7
*/
#define SEC_CSR8 0x0490
#define SEC_CSR9 0x0492
@@ -391,7 +408,14 @@
#define SEC_CSR15 0x049e
/*
- * SEC_CSR16-SEC_CSR23: Shared key 2, word 0-7
+ * SEC_CSR16: Shared key 2, word 0
+ * SEC_CSR17: Shared key 2, word 1
+ * SEC_CSR18: Shared key 2, word 2
+ * SEC_CSR19: Shared key 2, word 3
+ * SEC_CSR20: Shared key 2, word 4
+ * SEC_CSR21: Shared key 2, word 5
+ * SEC_CSR22: Shared key 2, word 6
+ * SEC_CSR23: Shared key 2, word 7
*/
#define SEC_CSR16 0x04a0
#define SEC_CSR17 0x04a2
@@ -403,7 +427,14 @@
#define SEC_CSR23 0x04ae
/*
- * SEC_CSR24-SEC_CSR31: Shared key 3, word 0-7
+ * SEC_CSR24: Shared key 3, word 0
+ * SEC_CSR25: Shared key 3, word 1
+ * SEC_CSR26: Shared key 3, word 2
+ * SEC_CSR27: Shared key 3, word 3
+ * SEC_CSR28: Shared key 3, word 4
+ * SEC_CSR29: Shared key 3, word 5
+ * SEC_CSR30: Shared key 3, word 6
+ * SEC_CSR31: Shared key 3, word 7
*/
#define SEC_CSR24 0x04b0
#define SEC_CSR25 0x04b2
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index a74e1a5c56f..07b03b3c7ef 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -44,7 +44,7 @@
/*
* Module information.
*/
-#define DRV_VERSION "2.1.4"
+#define DRV_VERSION "2.1.8"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
@@ -111,33 +111,6 @@
#define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) )
/*
- * IEEE802.11 header defines
- */
-static inline int is_rts_frame(u16 fc)
-{
- return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS));
-}
-
-static inline int is_cts_frame(u16 fc)
-{
- return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS));
-}
-
-static inline int is_probe_resp(u16 fc)
-{
- return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP));
-}
-
-static inline int is_beacon(u16 fc)
-{
- return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON));
-}
-
-/*
* Chipset identification
* The chipset on the device is composed of a RT and RF chip.
* The chipset combination is important for determining device capabilities.
@@ -391,6 +364,8 @@ struct rt2x00_intf {
#define DELAYED_UPDATE_BEACON 0x00000001
#define DELAYED_CONFIG_ERP 0x00000002
#define DELAYED_LED_ASSOC 0x00000004
+
+ u16 seqno;
};
static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
@@ -409,7 +384,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
* @supported_rates: Rate types which are supported (CCK, OFDM).
* @num_channels: Number of supported channels. This is used as array size
* for @tx_power_a, @tx_power_bg and @channels.
- * channels: Device/chipset specific channel values (See &struct rf_channel).
+ * @channels: Device/chipset specific channel values (See &struct rf_channel).
* @tx_power_a: TX power values for all 5.2GHz channels (may be NULL).
* @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL).
* @tx_power_default: Default TX power value to use when either
@@ -461,6 +436,7 @@ struct rt2x00lib_conf {
*/
struct rt2x00lib_erp {
int short_preamble;
+ int cts_protection;
int ack_timeout;
int ack_consume_time;
@@ -545,15 +521,13 @@ struct rt2x00lib_ops {
*/
void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
- struct txentry_desc *txdesc,
- struct ieee80211_tx_control *control);
- int (*write_tx_data) (struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb,
- struct ieee80211_tx_control *control);
+ struct txentry_desc *txdesc);
+ int (*write_tx_data) (struct queue_entry *entry);
+ void (*write_beacon) (struct queue_entry *entry);
int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb);
void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
- const unsigned int queue);
+ const enum data_queue_qid queue);
/*
* RX control handlers
@@ -597,6 +571,7 @@ struct rt2x00_ops {
const unsigned int max_ap_intf;
const unsigned int eeprom_size;
const unsigned int rf_size;
+ const unsigned int tx_queues;
const struct data_queue_desc *rx;
const struct data_queue_desc *tx;
const struct data_queue_desc *bcn;
@@ -626,11 +601,11 @@ enum rt2x00_flags {
/*
* Driver features
*/
- DRIVER_SUPPORT_MIXED_INTERFACES,
DRIVER_REQUIRE_FIRMWARE,
DRIVER_REQUIRE_BEACON_GUARD,
DRIVER_REQUIRE_ATIM_QUEUE,
DRIVER_REQUIRE_SCHEDULED,
+ DRIVER_REQUIRE_DMA,
/*
* Driver configuration
@@ -655,11 +630,7 @@ struct rt2x00_dev {
* When accessing this variable, the rt2x00dev_{pci,usb}
* macro's should be used for correct typecasting.
*/
- void *dev;
-#define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev )
-#define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev )
-#define rt2x00dev_usb_dev(__dev)\
- ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) )
+ struct device *dev;
/*
* Callback functions.
@@ -682,7 +653,7 @@ struct rt2x00_dev {
#define RFKILL_STATE_ALLOCATED 1
#define RFKILL_STATE_REGISTERED 2
struct rfkill *rfkill;
- struct input_polled_dev *poll_dev;
+ struct delayed_work rfkill_work;
#endif /* CONFIG_RT2X00_LIB_RFKILL */
/*
@@ -820,8 +791,10 @@ struct rt2x00_dev {
/*
* Scheduled work.
+ * NOTE: intf_work will use ieee80211_iterate_active_interfaces()
+ * which means it cannot be placed on the hw->workqueue
+ * due to RTNL locking requirements.
*/
- struct workqueue_struct *workqueue;
struct work_struct intf_work;
struct work_struct filter_work;
@@ -830,7 +803,7 @@ struct rt2x00_dev {
* The Beacon array also contains the Atim queue
* if that is supported by the device.
*/
- int data_queues;
+ unsigned int data_queues;
struct data_queue *rx;
struct data_queue *tx;
struct data_queue *bcn;
@@ -934,55 +907,41 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
}
/**
- * rt2x00queue_get_queue - Convert mac80211 queue index to rt2x00 queue
+ * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
* @rt2x00dev: Pointer to &struct rt2x00_dev.
- * @queue: mac80211/rt2x00 queue index
- * (see &enum ieee80211_tx_queue and &enum rt2x00_bcn_queue).
+ * @skb: The skb to map.
+ */
+void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_get_queue - Convert queue index to queue pointer
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @queue: rt2x00 queue index (see &enum data_queue_qid).
*/
struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue);
+ const enum data_queue_qid queue);
/**
* rt2x00queue_get_entry - Get queue entry where the given index points to.
- * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @queue: Pointer to &struct data_queue from where we obtain the entry.
* @index: Index identifier for obtaining the correct index.
*/
struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
enum queue_index index);
-/**
- * rt2x00queue_index_inc - Index incrementation function
- * @queue: Queue (&struct data_queue) to perform the action on.
- * @action: Index type (&enum queue_index) to perform the action on.
- *
- * This function will increase the requested index on the queue,
- * it will grab the appropriate locks and handle queue overflow events by
- * resetting the index to the start of the queue.
- */
-void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
-
-
/*
* Interrupt context handlers.
*/
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc);
-void rt2x00lib_rxdone(struct queue_entry *entry,
- struct rxdone_entry_desc *rxdesc);
-
-/*
- * TX descriptor initializer
- */
-void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *control);
+void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
+ struct queue_entry *entry);
/*
* mac80211 handlers.
*/
-int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control);
+int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
int rt2x00mac_start(struct ieee80211_hw *hw);
void rt2x00mac_stop(struct ieee80211_hw *hw);
int rt2x00mac_add_interface(struct ieee80211_hw *hw,
@@ -1005,7 +964,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
-int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
+int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params);
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 48608e8cc8b..f20ca712504 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -84,6 +84,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
memset(&erp, 0, sizeof(erp));
erp.short_preamble = bss_conf->use_short_preamble;
+ erp.cts_protection = bss_conf->use_cts_prot;
+
erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10);
erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index bfab3b8780d..300cf061035 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -115,7 +115,7 @@ struct rt2x00debug_intf {
};
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb)
+ enum rt2x00_dump_type type, struct sk_buff *skb)
{
struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
struct skb_frame_desc *desc = get_skb_frame_desc(skb);
@@ -133,7 +133,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
return;
}
- skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len,
+ skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len,
GFP_ATOMIC);
if (!skbcopy) {
DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
@@ -144,18 +144,18 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
dump_hdr->desc_length = cpu_to_le32(desc->desc_len);
- dump_hdr->data_length = cpu_to_le32(desc->data_len);
+ dump_hdr->data_length = cpu_to_le32(skb->len);
dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev);
- dump_hdr->type = cpu_to_le16(desc->frame_type);
+ dump_hdr->type = cpu_to_le16(type);
dump_hdr->queue_index = desc->entry->queue->qid;
dump_hdr->entry_index = desc->entry->entry_idx;
dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len);
- memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len);
+ memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len);
skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
wake_up_interruptible(&intf->frame_dump_waitqueue);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c997d4f28ab..8c93eb8353b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -28,7 +28,6 @@
#include "rt2x00.h"
#include "rt2x00lib.h"
-#include "rt2x00dump.h"
/*
* Link tuning handlers
@@ -75,7 +74,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
rt2x00lib_reset_link_tuner(rt2x00dev);
- queue_delayed_work(rt2x00dev->workqueue,
+ queue_delayed_work(rt2x00dev->hw->workqueue,
&rt2x00dev->link.work, LINK_TUNE_INTERVAL);
}
@@ -113,6 +112,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
if (status)
return status;
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_ON);
+
rt2x00leds_led_radio(rt2x00dev, true);
rt2x00led_led_activity(rt2x00dev, true);
@@ -126,7 +127,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Start the TX queues.
*/
- ieee80211_start_queues(rt2x00dev->hw);
+ ieee80211_wake_queues(rt2x00dev->hw);
return 0;
}
@@ -150,6 +151,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
* Disable radio.
*/
rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF);
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF);
rt2x00led_led_activity(rt2x00dev, false);
rt2x00leds_led_radio(rt2x00dev, false);
}
@@ -390,7 +392,7 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
* Increase tuner counter, and reschedule the next link tuner run.
*/
rt2x00dev->link.count++;
- queue_delayed_work(rt2x00dev->workqueue,
+ queue_delayed_work(rt2x00dev->hw->workqueue,
&rt2x00dev->link.work, LINK_TUNE_INTERVAL);
}
@@ -407,8 +409,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
{
struct rt2x00_dev *rt2x00dev = data;
struct rt2x00_intf *intf = vif_to_intf(vif);
- struct sk_buff *skb;
- struct ieee80211_tx_control control;
struct ieee80211_bss_conf conf;
int delayed_flags;
@@ -434,12 +434,8 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
return;
- if (delayed_flags & DELAYED_UPDATE_BEACON) {
- skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control);
- if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
- skb, &control))
- dev_kfree_skb(skb);
- }
+ if (delayed_flags & DELAYED_UPDATE_BEACON)
+ rt2x00queue_update_beacon(rt2x00dev, vif);
if (delayed_flags & DELAYED_CONFIG_ERP)
rt2x00lib_config_erp(rt2x00dev, intf, &conf);
@@ -468,12 +464,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
struct ieee80211_vif *vif)
{
+ struct rt2x00_dev *rt2x00dev = data;
struct rt2x00_intf *intf = vif_to_intf(vif);
if (vif->type != IEEE80211_IF_TYPE_AP &&
vif->type != IEEE80211_IF_TYPE_IBSS)
return;
+ /*
+ * Clean up the beacon skb.
+ */
+ rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
+ intf->beacon->skb = NULL;
+
spin_lock(&intf->lock);
intf->delayed_flags |= DELAYED_UPDATE_BEACON;
spin_unlock(&intf->lock);
@@ -488,7 +491,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
rt2x00lib_beacondone_iter,
rt2x00dev);
- queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
+ schedule_work(&rt2x00dev->intf_work);
}
EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
@@ -496,79 +499,132 @@ void rt2x00lib_txdone(struct queue_entry *entry,
struct txdone_entry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct skb_frame_desc *skbdesc;
- struct ieee80211_tx_status tx_status;
- int success = !!(txdesc->status == TX_SUCCESS ||
- txdesc->status == TX_SUCCESS_RETRY);
- int fail = !!(txdesc->status == TX_FAIL_RETRY ||
- txdesc->status == TX_FAIL_INVALID ||
- txdesc->status == TX_FAIL_OTHER);
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
+
+ /*
+ * Unmap the skb.
+ */
+ rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+
+ /*
+ * Send frame to debugfs immediately, after this call is completed
+ * we are going to overwrite the skb->cb array.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
/*
* Update TX statistics.
*/
- rt2x00dev->link.qual.tx_success += success;
- rt2x00dev->link.qual.tx_failed += fail;
+ rt2x00dev->link.qual.tx_success +=
+ test_bit(TXDONE_SUCCESS, &txdesc->flags);
+ rt2x00dev->link.qual.tx_failed +=
+ test_bit(TXDONE_FAILURE, &txdesc->flags);
/*
* Initialize TX status
*/
- tx_status.flags = 0;
- tx_status.ack_signal = 0;
- tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY);
- tx_status.retry_count = txdesc->retry;
- memcpy(&tx_status.control, txdesc->control, sizeof(*txdesc->control));
+ memset(&tx_info->status, 0, sizeof(tx_info->status));
+ tx_info->status.ack_signal = 0;
+ tx_info->status.excessive_retries =
+ test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags);
+ tx_info->status.retry_count = txdesc->retry;
- if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
- if (success)
- tx_status.flags |= IEEE80211_TX_STATUS_ACK;
- else
+ if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+ else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev->low_level_stats.dot11ACKFailureCount++;
}
- tx_status.queue_length = entry->queue->limit;
- tx_status.queue_number = tx_status.control.queue;
-
- if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- if (success)
+ if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+ if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
- else
+ else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
rt2x00dev->low_level_stats.dot11RTSFailureCount++;
}
/*
- * Send the tx_status to debugfs. Only send the status report
- * to mac80211 when the frame originated from there. If this was
- * a extra frame coming through a mac80211 library call (RTS/CTS)
- * then we should not send the status report back.
- * If send to mac80211, mac80211 will clean up the skb structure,
- * otherwise we have to do it ourself.
+ * Only send the status report to mac80211 when TX status was
+ * requested by it. If this was a extra frame coming through
+ * a mac80211 library call (RTS/CTS) then we should not send the
+ * status report back.
*/
- skbdesc = get_skb_frame_desc(entry->skb);
- skbdesc->frame_type = DUMP_FRAME_TXDONE;
-
- rt2x00debug_dump_frame(rt2x00dev, entry->skb);
-
- if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))
- ieee80211_tx_status_irqsafe(rt2x00dev->hw,
- entry->skb, &tx_status);
+ if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)
+ ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
else
- dev_kfree_skb(entry->skb);
+ dev_kfree_skb_irq(entry->skb);
+
+ /*
+ * Make this entry available for reuse.
+ */
entry->skb = NULL;
+ entry->flags = 0;
+
+ rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry);
+
+ __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+
+ /*
+ * If the data queue was below the threshold before the txdone
+ * handler we must make sure the packet queue in the mac80211 stack
+ * is reenabled when the txdone handler has finished.
+ */
+ if (!rt2x00queue_threshold(entry->queue))
+ ieee80211_wake_queue(rt2x00dev->hw, qid);
}
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
-void rt2x00lib_rxdone(struct queue_entry *entry,
- struct rxdone_entry_desc *rxdesc)
+void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
+ struct queue_entry *entry)
{
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct rxdone_entry_desc rxdesc;
+ struct sk_buff *skb;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
const struct rt2x00_rate *rate;
+ unsigned int header_size;
+ unsigned int align;
unsigned int i;
int idx = -1;
- u16 fc;
+
+ /*
+ * Allocate a new sk_buffer. If no new buffer available, drop the
+ * received frame and reuse the existing buffer.
+ */
+ skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry);
+ if (!skb)
+ return;
+
+ /*
+ * Unmap the skb.
+ */
+ rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
+
+ /*
+ * Extract the RXD details.
+ */
+ memset(&rxdesc, 0, sizeof(rxdesc));
+ rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
+
+ /*
+ * The data behind the ieee80211 header must be
+ * aligned on a 4 byte boundary.
+ */
+ header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
+ align = ((unsigned long)(entry->skb->data + header_size)) & 3;
+
+ if (align) {
+ skb_push(entry->skb, align);
+ /* Move entire frame in 1 command */
+ memmove(entry->skb->data, entry->skb->data + align,
+ rxdesc.size);
+ }
+
+ /* Update data pointers, trim buffer to correct size */
+ skb_trim(entry->skb, rxdesc.size);
/*
* Update RX statistics.
@@ -577,10 +633,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
for (i = 0; i < sband->n_bitrates; i++) {
rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
- if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) &&
- (rate->plcp == rxdesc->signal)) ||
- (!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) &&
- (rate->bitrate == rxdesc->signal))) {
+ if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
+ (rate->plcp == rxdesc.signal)) ||
+ (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
+ (rate->bitrate == rxdesc.signal))) {
idx = i;
break;
}
@@ -588,8 +644,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
if (idx < 0) {
WARNING(rt2x00dev, "Frame received with unrecognized signal,"
- "signal=0x%.2x, plcp=%d.\n", rxdesc->signal,
- !!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP));
+ "signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
+ !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
idx = 0;
}
@@ -597,170 +653,38 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
* Only update link status if this is a beacon frame carrying our bssid.
*/
hdr = (struct ieee80211_hdr *)entry->skb->data;
- fc = le16_to_cpu(hdr->frame_control);
- if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS))
- rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi);
+ if (ieee80211_is_beacon(hdr->frame_control) &&
+ (rxdesc.dev_flags & RXDONE_MY_BSS))
+ rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
rt2x00dev->link.qual.rx_success++;
+ rx_status->mactime = rxdesc.timestamp;
rx_status->rate_idx = idx;
- rx_status->signal =
- rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi);
- rx_status->ssi = rxdesc->rssi;
- rx_status->flag = rxdesc->flags;
+ rx_status->qual =
+ rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
+ rx_status->signal = rxdesc.rssi;
+ rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
/*
* Send frame to mac80211 & debugfs.
* mac80211 will clean up the skb structure.
*/
- get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE;
- rt2x00debug_dump_frame(rt2x00dev, entry->skb);
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
- entry->skb = NULL;
-}
-EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
-
-/*
- * TX descriptor initializer
- */
-void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
- struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct txentry_desc txdesc;
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skbdesc->data;
- const struct rt2x00_rate *rate;
- int tx_rate;
- int length;
- int duration;
- int residual;
- u16 frame_control;
- u16 seq_ctrl;
-
- memset(&txdesc, 0, sizeof(txdesc));
-
- txdesc.queue = skbdesc->entry->queue->qid;
- txdesc.cw_min = skbdesc->entry->queue->cw_min;
- txdesc.cw_max = skbdesc->entry->queue->cw_max;
- txdesc.aifs = skbdesc->entry->queue->aifs;
-
- /*
- * Read required fields from ieee80211 header.
- */
- frame_control = le16_to_cpu(hdr->frame_control);
- seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
-
- tx_rate = control->tx_rate->hw_value;
/*
- * Check whether this frame is to be acked
+ * Replace the skb with the freshly allocated one.
*/
- if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
- __set_bit(ENTRY_TXD_ACK, &txdesc.flags);
-
- /*
- * Check if this is a RTS/CTS frame
- */
- if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
- __set_bit(ENTRY_TXD_BURST, &txdesc.flags);
- if (is_rts_frame(frame_control)) {
- __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags);
- __set_bit(ENTRY_TXD_ACK, &txdesc.flags);
- } else
- __clear_bit(ENTRY_TXD_ACK, &txdesc.flags);
- if (control->rts_cts_rate)
- tx_rate = control->rts_cts_rate->hw_value;
- }
-
- rate = rt2x00_get_rate(tx_rate);
-
- /*
- * Check if more fragments are pending
- */
- if (ieee80211_get_morefrag(hdr)) {
- __set_bit(ENTRY_TXD_BURST, &txdesc.flags);
- __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags);
- }
-
- /*
- * Beacons and probe responses require the tsf timestamp
- * to be inserted into the frame.
- */
- if (control->queue == RT2X00_BCN_QUEUE_BEACON ||
- is_probe_resp(frame_control))
- __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags);
-
- /*
- * Determine with what IFS priority this frame should be send.
- * Set ifs to IFS_SIFS when the this is not the first fragment,
- * or this fragment came after RTS/CTS.
- */
- if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 ||
- test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags))
- txdesc.ifs = IFS_SIFS;
- else
- txdesc.ifs = IFS_BACKOFF;
-
- /*
- * PLCP setup
- * Length calculation depends on OFDM/CCK rate.
- */
- txdesc.signal = rate->plcp;
- txdesc.service = 0x04;
-
- length = skbdesc->data_len + FCS_LEN;
- if (rate->flags & DEV_RATE_OFDM) {
- __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags);
-
- txdesc.length_high = (length >> 6) & 0x3f;
- txdesc.length_low = length & 0x3f;
- } else {
- /*
- * Convert length to microseconds.
- */
- residual = get_duration_res(length, rate->bitrate);
- duration = get_duration(length, rate->bitrate);
-
- if (residual != 0) {
- duration++;
-
- /*
- * Check if we need to set the Length Extension
- */
- if (rate->bitrate == 110 && residual <= 30)
- txdesc.service |= 0x80;
- }
-
- txdesc.length_high = (duration >> 8) & 0xff;
- txdesc.length_low = duration & 0xff;
-
- /*
- * When preamble is enabled we should set the
- * preamble bit for the signal.
- */
- if (rt2x00_get_rate_preamble(tx_rate))
- txdesc.signal |= 0x08;
- }
-
- rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control);
+ entry->skb = skb;
+ entry->flags = 0;
- /*
- * Update queue entry.
- */
- skbdesc->entry->skb = skb;
+ rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry);
- /*
- * The frame has been completely initialized and ready
- * for sending to the device. The caller will push the
- * frame to the device, but we are going to push the
- * frame to debugfs here.
- */
- skbdesc->frame_type = DUMP_FRAME_TX;
- rt2x00debug_dump_frame(rt2x00dev, skb);
+ rt2x00queue_index_inc(entry->queue, Q_INDEX);
}
-EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
+EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
/*
* Driver initialization handlers.
@@ -978,6 +902,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
return status;
/*
+ * Initialize HW fields.
+ */
+ rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;
+
+ /*
* Register HW.
*/
status = ieee80211_register_hw(rt2x00dev->hw);
@@ -1131,10 +1060,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
/*
* Initialize configuration work.
*/
- rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib");
- if (!rt2x00dev->workqueue)
- goto exit;
-
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
@@ -1195,13 +1120,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
rt2x00leds_unregister(rt2x00dev);
/*
- * Stop all queued work. Note that most tasks will already be halted
- * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize().
- */
- flush_workqueue(rt2x00dev->workqueue);
- destroy_workqueue(rt2x00dev->workqueue);
-
- /*
* Free ieee80211_hw memory.
*/
rt2x00lib_remove_hw(rt2x00dev);
@@ -1246,7 +1164,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
* Suspend/disable extra components.
*/
rt2x00leds_suspend(rt2x00dev);
- rt2x00rfkill_suspend(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
exit:
@@ -1302,7 +1219,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
* Restore/enable extra components.
*/
rt2x00debug_register(rt2x00dev);
- rt2x00rfkill_resume(rt2x00dev);
rt2x00leds_resume(rt2x00dev);
/*
@@ -1343,7 +1259,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
* In that case we have disabled the TX queue and should
* now enable it again
*/
- ieee80211_start_queues(rt2x00dev->hw);
+ ieee80211_wake_queues(rt2x00dev->hw);
/*
* During interface iteration we might have changed the
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index b971bc6e7ee..bab05a56e7a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -100,6 +100,14 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev,
rt2x00dev->fw->data,
rt2x00dev->fw->size);
+
+ /*
+ * When the firmware is uploaded to the hardware the LED
+ * association status might have been triggered, for correct
+ * LED handling it should now be reset.
+ */
+ rt2x00leds_led_assoc(rt2x00dev, false);
+
return retval;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 41ee02cd282..f2c9b0e79b5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -26,12 +26,14 @@
#ifndef RT2X00LIB_H
#define RT2X00LIB_H
+#include "rt2x00dump.h"
+
/*
* Interval defines
* Both the link tuner as the rfkill will be called once per second.
*/
#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
-#define RFKILL_POLL_INTERVAL ( 1000 )
+#define RFKILL_POLL_INTERVAL ( round_jiffies_relative(HZ) )
/*
* rt2x00_rate: Per rate device information
@@ -96,9 +98,65 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config);
-/*
- * Queue handlers.
+/**
+ * DOC: Queue handlers
+ */
+
+/**
+ * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @queue: The queue for which the skb will be applicable.
+ */
+struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
+ struct queue_entry *entry);
+
+/**
+ * rt2x00queue_unmap_skb - Unmap a skb from DMA.
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to unmap.
+ */
+void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_free_skb - free a skb
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to free.
+ */
+void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_free_skb - free a skb
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: The skb to free.
+ */
+void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_write_tx_frame - Write TX frame to hardware
+ * @queue: Queue over which the frame should be send
+ * @skb: The skb to send
+ */
+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
+
+/**
+ * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @vif: Interface for which the beacon should be updated.
*/
+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_vif *vif);
+
+/**
+ * rt2x00queue_index_inc - Index incrementation function
+ * @queue: Queue (&struct data_queue) to perform the action on.
+ * @index: Index type (&enum queue_index) to perform the action on.
+ *
+ * This function will increase the requested index on the queue,
+ * it will grab the appropriate locks and handle queue overflow events by
+ * resetting the index to the start of the queue.
+ */
+void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
+
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
@@ -128,7 +186,8 @@ static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_RT2X00_LIB_DEBUGFS
void rt2x00debug_register(struct rt2x00_dev *rt2x00dev);
void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
-void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
+void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+ enum rt2x00_dump_type type, struct sk_buff *skb);
#else
static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
{
@@ -139,6 +198,7 @@ static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
}
static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+ enum rt2x00_dump_type type,
struct sk_buff *skb)
{
}
@@ -152,8 +212,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev);
void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev);
-void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev);
-void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev);
#else
static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
{
@@ -170,14 +228,6 @@ static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
{
}
-
-static inline void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
-{
-}
-
-static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
-{
-}
#endif /* CONFIG_RT2X00_LIB_RFKILL */
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 9cb023edd2e..f1dcbaa80c3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -31,14 +31,14 @@
static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue,
- struct sk_buff *frag_skb,
- struct ieee80211_tx_control *control)
+ struct sk_buff *frag_skb)
{
- struct skb_frame_desc *skbdesc;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
+ struct ieee80211_tx_info *rts_info;
struct sk_buff *skb;
int size;
- if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+ if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
size = sizeof(struct ieee80211_cts);
else
size = sizeof(struct ieee80211_rts);
@@ -52,23 +52,37 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom);
skb_put(skb, size);
- if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
- ieee80211_ctstoself_get(rt2x00dev->hw, control->vif,
- frag_skb->data, frag_skb->len, control,
+ /*
+ * Copy TX information over from original frame to
+ * RTS/CTS frame. Note that we set the no encryption flag
+ * since we don't want this frame to be encrypted.
+ * RTS frames should be acked, while CTS-to-self frames
+ * should not. The ready for TX flag is cleared to prevent
+ * it being automatically send when the descriptor is
+ * written to the hardware.
+ */
+ memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
+ rts_info = IEEE80211_SKB_CB(skb);
+ rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;
+ rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
+ rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
+ rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
+
+ if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+ rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
+ else
+ rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
+
+ if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+ ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
+ frag_skb->data, size, tx_info,
(struct ieee80211_cts *)(skb->data));
else
- ieee80211_rts_get(rt2x00dev->hw, control->vif,
- frag_skb->data, frag_skb->len, control,
+ ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif,
+ frag_skb->data, size, tx_info,
(struct ieee80211_rts *)(skb->data));
- /*
- * Initialize skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
-
- if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
+ if (rt2x00queue_write_tx_frame(queue, skb)) {
WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
return NETDEV_TX_BUSY;
}
@@ -76,13 +90,14 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
return NETDEV_TX_OK;
}
-int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
+ enum data_queue_qid qid = skb_get_queue_mapping(skb);
+ struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
struct data_queue *queue;
- struct skb_frame_desc *skbdesc;
u16 frame_control;
/*
@@ -100,57 +115,62 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
/*
* Determine which queue to put packet on.
*/
- if (control->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM &&
+ if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
- queue = rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_ATIM);
+ queue = rt2x00queue_get_queue(rt2x00dev, QID_ATIM);
else
- queue = rt2x00queue_get_queue(rt2x00dev, control->queue);
+ queue = rt2x00queue_get_queue(rt2x00dev, qid);
if (unlikely(!queue)) {
ERROR(rt2x00dev,
"Attempt to send packet over invalid queue %d.\n"
- "Please file bug report to %s.\n",
- control->queue, DRV_PROJECT);
+ "Please file bug report to %s.\n", qid, DRV_PROJECT);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
/*
- * If CTS/RTS is required. and this frame is not CTS or RTS,
- * create and queue that frame first. But make sure we have
- * at least enough entries available to send this CTS/RTS
- * frame as well as the data frame.
+ * If CTS/RTS is required. create and queue that frame first.
+ * Make sure we have at least enough entries available to send
+ * this CTS/RTS frame as well as the data frame.
+ * Note that when the driver has set the set_rts_threshold()
+ * callback function it doesn't need software generation of
+ * either RTS or CTS-to-self frame and handles everything
+ * inside the hardware.
*/
frame_control = le16_to_cpu(ieee80211hdr->frame_control);
- if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
- (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS |
- IEEE80211_TXCTL_USE_CTS_PROTECT))) {
+ if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
+ IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
+ !rt2x00dev->ops->hw->set_rts_threshold) {
if (rt2x00queue_available(queue) <= 1) {
- ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+ ieee80211_stop_queue(rt2x00dev->hw, qid);
return NETDEV_TX_BUSY;
}
- if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) {
- ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+ if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb)) {
+ ieee80211_stop_queue(rt2x00dev->hw, qid);
return NETDEV_TX_BUSY;
}
}
/*
- * Initialize skb descriptor
+ * XXX: This is as wrong as the old mac80211 code was,
+ * due to beacons not getting sequence numbers assigned
+ * properly.
*/
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
+ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ intf->seqno += 0x10;
+ ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
+ }
- if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) {
- ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+ if (rt2x00queue_write_tx_frame(queue, skb)) {
+ ieee80211_stop_queue(rt2x00dev->hw, qid);
return NETDEV_TX_BUSY;
}
- if (rt2x00queue_full(queue))
- ieee80211_stop_queue(rt2x00dev->hw, control->queue);
-
- if (rt2x00dev->ops->lib->kick_tx_queue)
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
+ if (rt2x00queue_threshold(queue))
+ ieee80211_stop_queue(rt2x00dev->hw, qid);
return NETDEV_TX_OK;
}
@@ -183,8 +203,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
{
struct rt2x00_dev *rt2x00dev = hw->priv;
struct rt2x00_intf *intf = vif_to_intf(conf->vif);
- struct data_queue *queue =
- rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON);
+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, QID_BEACON);
struct queue_entry *entry = NULL;
unsigned int i;
@@ -197,13 +216,12 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
return -ENODEV;
/*
- * When we don't support mixed interfaces (a combination
- * of sta and ap virtual interfaces) then we can only
- * add this interface when the rival interface count is 0.
+ * We don't support mixed combinations of sta and ap virtual
+ * interfaces. We can only add this interface when the rival
+ * interface count is 0.
*/
- if (!test_bit(DRIVER_SUPPORT_MIXED_INTERFACES, &rt2x00dev->flags) &&
- ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) ||
- (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count)))
+ if ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) ||
+ (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count))
return -ENOBUFS;
/*
@@ -343,7 +361,8 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
{
struct rt2x00_dev *rt2x00dev = hw->priv;
struct rt2x00_intf *intf = vif_to_intf(vif);
- int status;
+ int update_bssid = 0;
+ int status = 0;
/*
* Mac80211 might be calling this function while we are trying
@@ -355,12 +374,13 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
spin_lock(&intf->lock);
/*
- * If the interface does not work in master mode,
- * then the bssid value in the interface structure
- * should now be set.
+ * conf->bssid can be NULL if coming from the internal
+ * beacon update routine.
*/
- if (conf->type != IEEE80211_IF_TYPE_AP)
+ if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
+ update_bssid = 1;
memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
+ }
spin_unlock(&intf->lock);
@@ -370,19 +390,14 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
* values as arguments we make keep access to rt2x00_intf thread safe
* even without the lock.
*/
- rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid);
+ rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
+ update_bssid ? conf->bssid : NULL);
/*
- * We only need to initialize the beacon when master mode is enabled.
+ * Update the beacon.
*/
- if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon)
- return 0;
-
- status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
- conf->beacon,
- conf->beacon_control);
- if (status)
- dev_kfree_skb(conf->beacon);
+ if (conf->changed & IEEE80211_IFCC_BEACON)
+ status = rt2x00queue_update_beacon(rt2x00dev, vif);
return status;
}
@@ -428,7 +443,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
else
- queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work);
+ queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
}
EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
@@ -454,10 +469,10 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
struct rt2x00_dev *rt2x00dev = hw->priv;
unsigned int i;
- for (i = 0; i < hw->queues; i++) {
- stats->data[i].len = rt2x00dev->tx[i].length;
- stats->data[i].limit = rt2x00dev->tx[i].limit;
- stats->data[i].count = rt2x00dev->tx[i].count;
+ for (i = 0; i < rt2x00dev->ops->tx_queues; i++) {
+ stats[i].len = rt2x00dev->tx[i].length;
+ stats[i].limit = rt2x00dev->tx[i].limit;
+ stats[i].count = rt2x00dev->tx[i].count;
}
return 0;
@@ -498,7 +513,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* When the erp information has changed, we should perform
* additional configuration steps. For all other changes we are done.
*/
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ if (changes & (BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_CTS_PROT)) {
if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
else
@@ -509,13 +524,13 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
if (delayed) {
intf->delayed_flags |= delayed;
- queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
+ schedule_work(&rt2x00dev->intf_work);
}
spin_unlock(&intf->lock);
}
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
-int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx,
+int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
const struct ieee80211_tx_queue_params *params)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -539,10 +554,7 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx,
else
queue->cw_max = 10; /* cw_min: 2^10 = 1024. */
- if (params->aifs >= 0)
- queue->aifs = params->aifs;
- else
- queue->aifs = 2;
+ queue->aifs = params->aifs;
INFO(rt2x00dev,
"Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 60893de3bf8..adf2876ed8a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -34,44 +34,34 @@
/*
* TX data handlers.
*/
-int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+int rt2x00pci_write_tx_data(struct queue_entry *entry)
{
- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
- struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc;
u32 word;
- if (rt2x00queue_full(queue))
- return -EINVAL;
-
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
- if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
- rt2x00_get_field32(word, TXD_ENTRY_VALID)) {
- ERROR(rt2x00dev,
- "Arrived at non-free entry in the non-full queue %d.\n"
+ /*
+ * This should not happen, we already checked the entry
+ * was ours. When the hardware disagrees there has been
+ * a queue corruption!
+ */
+ if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||
+ rt2x00_get_field32(word, TXD_ENTRY_VALID))) {
+ ERROR(entry->queue->rt2x00dev,
+ "Corrupt queue %d, accessing entry which is not ours.\n"
"Please file bug report to %s.\n",
- control->queue, DRV_PROJECT);
+ entry->queue->qid, DRV_PROJECT);
return -EINVAL;
}
/*
* Fill in skb descriptor
*/
- skbdesc = get_skb_frame_desc(skb);
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
- skbdesc->desc = priv_tx->desc;
- skbdesc->desc_len = queue->desc_size;
- skbdesc->entry = entry;
-
- memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
- memcpy(priv_tx->data, skb->data, skb->len);
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
- rt2x00queue_index_inc(queue, Q_INDEX);
+ skbdesc = get_skb_frame_desc(entry->skb);
+ skbdesc->desc = entry_priv->desc;
+ skbdesc->desc_len = entry->queue->desc_size;
return 0;
}
@@ -84,180 +74,62 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue = rt2x00dev->rx;
struct queue_entry *entry;
- struct queue_entry_priv_pci_rx *priv_rx;
- struct ieee80211_hdr *hdr;
+ struct queue_entry_priv_pci *entry_priv;
struct skb_frame_desc *skbdesc;
- struct rxdone_entry_desc rxdesc;
- int header_size;
- int align;
u32 word;
while (1) {
entry = rt2x00queue_get_entry(queue, Q_INDEX);
- priv_rx = entry->priv_data;
- rt2x00_desc_read(priv_rx->desc, 0, &word);
+ entry_priv = entry->priv_data;
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
break;
- memset(&rxdesc, 0, sizeof(rxdesc));
- rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
-
- hdr = (struct ieee80211_hdr *)priv_rx->data;
- header_size =
- ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
-
/*
- * The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary.
- */
- align = header_size % 4;
-
- /*
- * Allocate the sk_buffer, initialize it and copy
- * all data into it.
- */
- entry->skb = dev_alloc_skb(rxdesc.size + align);
- if (!entry->skb)
- return;
-
- skb_reserve(entry->skb, align);
- memcpy(skb_put(entry->skb, rxdesc.size),
- priv_rx->data, rxdesc.size);
-
- /*
- * Fill in skb descriptor
+ * Fill in desc fields of the skb descriptor
*/
skbdesc = get_skb_frame_desc(entry->skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = entry->skb->len;
- skbdesc->desc = priv_rx->desc;
- skbdesc->desc_len = queue->desc_size;
- skbdesc->entry = entry;
+ skbdesc->desc = entry_priv->desc;
+ skbdesc->desc_len = entry->queue->desc_size;
/*
* Send the frame to rt2x00lib for further processing.
*/
- rt2x00lib_rxdone(entry, &rxdesc);
-
- if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) {
- rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1);
- rt2x00_desc_write(priv_rx->desc, 0, word);
- }
-
- rt2x00queue_index_inc(queue, Q_INDEX);
+ rt2x00lib_rxdone(rt2x00dev, entry);
}
}
EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
-void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
- struct txdone_entry_desc *txdesc)
-{
- struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
- u32 word;
-
- txdesc->control = &priv_tx->control;
- rt2x00lib_txdone(entry, txdesc);
-
- /*
- * Make this entry available for reuse.
- */
- entry->flags = 0;
-
- rt2x00_desc_read(priv_tx->desc, 0, &word);
- rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0);
- rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);
- rt2x00_desc_write(priv_tx->desc, 0, word);
-
- rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
-
- /*
- * If the data queue was full before the txdone handler
- * we must make sure the packet queue in the mac80211 stack
- * is reenabled when the txdone handler has finished.
- */
- if (!rt2x00queue_full(entry->queue))
- ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue);
-
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
-
/*
* Device initialization handlers.
*/
-#define desc_size(__queue) \
-({ \
- ((__queue)->limit * (__queue)->desc_size);\
-})
-
-#define data_size(__queue) \
-({ \
- ((__queue)->limit * (__queue)->data_size);\
-})
-
-#define dma_size(__queue) \
-({ \
- data_size(__queue) + desc_size(__queue);\
-})
-
-#define desc_offset(__queue, __base, __i) \
-({ \
- (__base) + data_size(__queue) + \
- ((__i) * (__queue)->desc_size); \
-})
-
-#define data_offset(__queue, __base, __i) \
-({ \
- (__base) + \
- ((__i) * (__queue)->data_size); \
-})
-
static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
- struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
- struct queue_entry_priv_pci_rx *priv_rx;
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
void *addr;
dma_addr_t dma;
- void *desc_addr;
- dma_addr_t desc_dma;
- void *data_addr;
- dma_addr_t data_dma;
unsigned int i;
/*
* Allocate DMA memory for descriptor and buffer.
*/
- addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma);
+ addr = dma_alloc_coherent(rt2x00dev->dev,
+ queue->limit * queue->desc_size,
+ &dma, GFP_KERNEL | GFP_DMA);
if (!addr)
return -ENOMEM;
- memset(addr, 0, dma_size(queue));
+ memset(addr, 0, queue->limit * queue->desc_size);
/*
* Initialize all queue entries to contain valid addresses.
*/
for (i = 0; i < queue->limit; i++) {
- desc_addr = desc_offset(queue, addr, i);
- desc_dma = desc_offset(queue, dma, i);
- data_addr = data_offset(queue, addr, i);
- data_dma = data_offset(queue, dma, i);
-
- if (queue->qid == QID_RX) {
- priv_rx = queue->entries[i].priv_data;
- priv_rx->desc = desc_addr;
- priv_rx->desc_dma = desc_dma;
- priv_rx->data = data_addr;
- priv_rx->data_dma = data_dma;
- } else {
- priv_tx = queue->entries[i].priv_data;
- priv_tx->desc = desc_addr;
- priv_tx->desc_dma = desc_dma;
- priv_tx->data = data_addr;
- priv_tx->data_dma = data_dma;
- }
+ entry_priv = queue->entries[i].priv_data;
+ entry_priv->desc = addr + i * queue->desc_size;
+ entry_priv->desc_dma = dma + i * queue->desc_size;
}
return 0;
@@ -266,34 +138,19 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
- struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
- struct queue_entry_priv_pci_rx *priv_rx;
- struct queue_entry_priv_pci_tx *priv_tx;
- void *data_addr;
- dma_addr_t data_dma;
-
- if (queue->qid == QID_RX) {
- priv_rx = queue->entries[0].priv_data;
- data_addr = priv_rx->data;
- data_dma = priv_rx->data_dma;
-
- priv_rx->data = NULL;
- } else {
- priv_tx = queue->entries[0].priv_data;
- data_addr = priv_tx->data;
- data_dma = priv_tx->data_dma;
-
- priv_tx->data = NULL;
- }
-
- if (data_addr)
- pci_free_consistent(pci_dev, dma_size(queue),
- data_addr, data_dma);
+ struct queue_entry_priv_pci *entry_priv =
+ queue->entries[0].priv_data;
+
+ if (entry_priv->desc)
+ dma_free_coherent(rt2x00dev->dev,
+ queue->limit * queue->desc_size,
+ entry_priv->desc, entry_priv->desc_dma);
+ entry_priv->desc = NULL;
}
int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
{
- struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
+ struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
struct data_queue *queue;
int status;
@@ -334,7 +191,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
/*
* Free irq line.
*/
- free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev);
+ free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev);
/*
* Free DMA
@@ -363,7 +220,7 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
{
- struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
+ struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0),
pci_resource_len(pci_dev, 0));
@@ -412,7 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (pci_set_mwi(pci_dev))
ERROR_PROBE("MWI not available.\n");
- if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) {
+ if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) {
ERROR_PROBE("PCI DMA not supported.\n");
retval = -EIO;
goto exit_disable_device;
@@ -428,7 +285,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
pci_set_drvdata(pci_dev, hw);
rt2x00dev = hw->priv;
- rt2x00dev->dev = pci_dev;
+ rt2x00dev->dev = &pci_dev->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index b41967ecbf6..80bf97c03e2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -87,44 +87,26 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
memcpy_toio(rt2x00dev->csr.base + offset, value, length);
}
-/*
- * TX data handlers.
- */
-int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb,
- struct ieee80211_tx_control *control);
-
/**
- * struct queue_entry_priv_pci_rx: Per RX entry PCI specific information
+ * rt2x00pci_write_tx_data - Initialize data for TX operation
+ * @entry: The entry where the frame is located
*
- * @desc: Pointer to device descriptor.
- * @data: Pointer to device's entry memory.
- * @dma: DMA pointer to &data.
+ * This function will initialize the DMA and skb descriptor
+ * to prepare the entry for the actual TX operation.
*/
-struct queue_entry_priv_pci_rx {
- __le32 *desc;
- dma_addr_t desc_dma;
-
- void *data;
- dma_addr_t data_dma;
-};
+int rt2x00pci_write_tx_data(struct queue_entry *entry);
/**
- * struct queue_entry_priv_pci_tx: Per TX entry PCI specific information
+ * struct queue_entry_priv_pci: Per entry PCI specific information
*
* @desc: Pointer to device descriptor
+ * @desc_dma: DMA pointer to &desc.
* @data: Pointer to device's entry memory.
- * @dma: DMA pointer to &data.
- * @control: mac80211 control structure used to transmit data.
+ * @data_dma: DMA pointer to &data.
*/
-struct queue_entry_priv_pci_tx {
+struct queue_entry_priv_pci {
__le32 *desc;
dma_addr_t desc_dma;
-
- void *data;
- dma_addr_t data_dma;
-
- struct ieee80211_tx_control control;
};
/**
@@ -133,15 +115,6 @@ struct queue_entry_priv_pci_tx {
*/
void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
-/**
- * rt2x00pci_txdone - Handle TX done events
- * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
- * @entry: Entry which has completed the transmission of a frame.
- * @desc: TX done descriptor
- */
-void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry,
- struct txdone_entry_desc *desc);
-
/*
* Device initialization handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 659e9f44c40..7f442030f5a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -25,24 +25,370 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/dma-mapping.h>
#include "rt2x00.h"
#include "rt2x00lib.h"
+struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev,
+ struct queue_entry *entry)
+{
+ unsigned int frame_size;
+ unsigned int reserved_size;
+ struct sk_buff *skb;
+ struct skb_frame_desc *skbdesc;
+
+ /*
+ * The frame size includes descriptor size, because the
+ * hardware directly receive the frame into the skbuffer.
+ */
+ frame_size = entry->queue->data_size + entry->queue->desc_size;
+
+ /*
+ * The payload should be aligned to a 4-byte boundary,
+ * this means we need at least 3 bytes for moving the frame
+ * into the correct offset.
+ */
+ reserved_size = 4;
+
+ /*
+ * Allocate skbuffer.
+ */
+ skb = dev_alloc_skb(frame_size + reserved_size);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, reserved_size);
+ skb_put(skb, frame_size);
+
+ /*
+ * Populate skbdesc.
+ */
+ skbdesc = get_skb_frame_desc(skb);
+ memset(skbdesc, 0, sizeof(*skbdesc));
+ skbdesc->entry = entry;
+
+ if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) {
+ skbdesc->skb_dma = dma_map_single(rt2x00dev->dev,
+ skb->data,
+ skb->len,
+ DMA_FROM_DEVICE);
+ skbdesc->flags |= SKBDESC_DMA_MAPPED_RX;
+ }
+
+ return skb;
+}
+
+void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+{
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+
+ skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb);
+
+void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+{
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+
+ if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) {
+ dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+ DMA_FROM_DEVICE);
+ skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX;
+ }
+
+ if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) {
+ dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len,
+ DMA_TO_DEVICE);
+ skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
+ }
+}
+
+void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
+{
+ if (!skb)
+ return;
+
+ rt2x00queue_unmap_skb(rt2x00dev, skb);
+ dev_kfree_skb_any(skb);
+}
+
+static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+ struct ieee80211_rate *rate =
+ ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
+ const struct rt2x00_rate *hwrate;
+ unsigned int data_length;
+ unsigned int duration;
+ unsigned int residual;
+
+ memset(txdesc, 0, sizeof(*txdesc));
+
+ /*
+ * Initialize information from queue
+ */
+ txdesc->queue = entry->queue->qid;
+ txdesc->cw_min = entry->queue->cw_min;
+ txdesc->cw_max = entry->queue->cw_max;
+ txdesc->aifs = entry->queue->aifs;
+
+ /* Data length should be extended with 4 bytes for CRC */
+ data_length = entry->skb->len + 4;
+
+ /*
+ * Check whether this frame is to be acked.
+ */
+ if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
+ __set_bit(ENTRY_TXD_ACK, &txdesc->flags);
+
+ /*
+ * Check if this is a RTS/CTS frame
+ */
+ if (ieee80211_is_rts(hdr->frame_control) ||
+ ieee80211_is_cts(hdr->frame_control)) {
+ __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
+ if (ieee80211_is_rts(hdr->frame_control))
+ __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags);
+ else
+ __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags);
+ if (tx_info->control.rts_cts_rate_idx >= 0)
+ rate =
+ ieee80211_get_rts_cts_rate(rt2x00dev->hw, tx_info);
+ }
+
+ /*
+ * Determine retry information.
+ */
+ txdesc->retry_limit = tx_info->control.retry_limit;
+ if (tx_info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
+ __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags);
+
+ /*
+ * Check if more fragments are pending
+ */
+ if (ieee80211_has_morefrags(hdr->frame_control)) {
+ __set_bit(ENTRY_TXD_BURST, &txdesc->flags);
+ __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags);
+ }
+
+ /*
+ * Beacons and probe responses require the tsf timestamp
+ * to be inserted into the frame.
+ */
+ if (ieee80211_is_beacon(hdr->frame_control) ||
+ ieee80211_is_probe_resp(hdr->frame_control))
+ __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags);
+
+ /*
+ * Determine with what IFS priority this frame should be send.
+ * Set ifs to IFS_SIFS when the this is not the first fragment,
+ * or this fragment came after RTS/CTS.
+ */
+ if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
+ txdesc->ifs = IFS_SIFS;
+ } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+ __set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
+ txdesc->ifs = IFS_BACKOFF;
+ } else {
+ txdesc->ifs = IFS_SIFS;
+ }
+
+ /*
+ * PLCP setup
+ * Length calculation depends on OFDM/CCK rate.
+ */
+ hwrate = rt2x00_get_rate(rate->hw_value);
+ txdesc->signal = hwrate->plcp;
+ txdesc->service = 0x04;
+
+ if (hwrate->flags & DEV_RATE_OFDM) {
+ __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
+
+ txdesc->length_high = (data_length >> 6) & 0x3f;
+ txdesc->length_low = data_length & 0x3f;
+ } else {
+ /*
+ * Convert length to microseconds.
+ */
+ residual = get_duration_res(data_length, hwrate->bitrate);
+ duration = get_duration(data_length, hwrate->bitrate);
+
+ if (residual != 0) {
+ duration++;
+
+ /*
+ * Check if we need to set the Length Extension
+ */
+ if (hwrate->bitrate == 110 && residual <= 30)
+ txdesc->service |= 0x80;
+ }
+
+ txdesc->length_high = (duration >> 8) & 0xff;
+ txdesc->length_low = duration & 0xff;
+
+ /*
+ * When preamble is enabled we should set the
+ * preamble bit for the signal.
+ */
+ if (rt2x00_get_rate_preamble(rate->hw_value))
+ txdesc->signal |= 0x08;
+ }
+}
+
+static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
+{
+ struct data_queue *queue = entry->queue;
+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+
+ rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
+
+ /*
+ * All processing on the frame has been completed, this means
+ * it is now ready to be dumped to userspace through debugfs.
+ */
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
+
+ /*
+ * Check if we need to kick the queue, there are however a few rules
+ * 1) Don't kick beacon queue
+ * 2) Don't kick unless this is the last in frame in a burst.
+ * When the burst flag is set, this frame is always followed
+ * by another frame which in some way are related to eachother.
+ * This is true for fragments, RTS or CTS-to-self frames.
+ * 3) Rule 2 can be broken when the available entries
+ * in the queue are less then a certain threshold.
+ */
+ if (entry->queue->qid == QID_BEACON)
+ return;
+
+ if (rt2x00queue_threshold(queue) ||
+ !test_bit(ENTRY_TXD_BURST, &txdesc->flags))
+ rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
+}
+
+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
+{
+ struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ struct txentry_desc txdesc;
+ struct skb_frame_desc *skbdesc;
+
+ if (unlikely(rt2x00queue_full(queue)))
+ return -EINVAL;
+
+ if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
+ ERROR(queue->rt2x00dev,
+ "Arrived at non-free entry in the non-full queue %d.\n"
+ "Please file bug report to %s.\n",
+ queue->qid, DRV_PROJECT);
+ return -EINVAL;
+ }
+
+ /*
+ * Copy all TX descriptor information into txdesc,
+ * after that we are free to use the skb->cb array
+ * for our information.
+ */
+ entry->skb = skb;
+ rt2x00queue_create_tx_descriptor(entry, &txdesc);
+
+ /*
+ * skb->cb array is now ours and we are free to use it.
+ */
+ skbdesc = get_skb_frame_desc(entry->skb);
+ memset(skbdesc, 0, sizeof(*skbdesc));
+ skbdesc->entry = entry;
+
+ if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {
+ __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ return -EIO;
+ }
+
+ if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
+ rt2x00queue_map_txskb(queue->rt2x00dev, skb);
+
+ __set_bit(ENTRY_DATA_PENDING, &entry->flags);
+
+ rt2x00queue_index_inc(queue, Q_INDEX);
+ rt2x00queue_write_tx_descriptor(entry, &txdesc);
+
+ return 0;
+}
+
+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_vif *vif)
+{
+ struct rt2x00_intf *intf = vif_to_intf(vif);
+ struct skb_frame_desc *skbdesc;
+ struct txentry_desc txdesc;
+ __le32 desc[16];
+
+ if (unlikely(!intf->beacon))
+ return -ENOBUFS;
+
+ intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
+ if (!intf->beacon->skb)
+ return -ENOMEM;
+
+ /*
+ * Copy all TX descriptor information into txdesc,
+ * after that we are free to use the skb->cb array
+ * for our information.
+ */
+ rt2x00queue_create_tx_descriptor(intf->beacon, &txdesc);
+
+ /*
+ * For the descriptor we use a local array from where the
+ * driver can move it to the correct location required for
+ * the hardware.
+ */
+ memset(desc, 0, sizeof(desc));
+
+ /*
+ * Fill in skb descriptor
+ */
+ skbdesc = get_skb_frame_desc(intf->beacon->skb);
+ memset(skbdesc, 0, sizeof(*skbdesc));
+ skbdesc->desc = desc;
+ skbdesc->desc_len = intf->beacon->queue->desc_size;
+ skbdesc->entry = intf->beacon;
+
+ /*
+ * Write TX descriptor into reserved room in front of the beacon.
+ */
+ rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc);
+
+ /*
+ * Send beacon to hardware.
+ * Also enable beacon generation, which might have been disabled
+ * by the driver during the config_beacon() callback function.
+ */
+ rt2x00dev->ops->lib->write_beacon(intf->beacon);
+ rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
+
+ return 0;
+}
+
struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue)
+ const enum data_queue_qid queue)
{
int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
- if (queue < rt2x00dev->hw->queues && rt2x00dev->tx)
+ if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx)
return &rt2x00dev->tx[queue];
if (!rt2x00dev->bcn)
return NULL;
- if (queue == RT2X00_BCN_QUEUE_BEACON)
+ if (queue == QID_BEACON)
return &rt2x00dev->bcn[0];
- else if (queue == RT2X00_BCN_QUEUE_ATIM && atim)
+ else if (queue == QID_ATIM && atim)
return &rt2x00dev->bcn[1];
return NULL;
@@ -96,7 +442,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
spin_unlock_irqrestore(&queue->lock, irqflags);
}
-EXPORT_SYMBOL_GPL(rt2x00queue_index_inc);
static void rt2x00queue_reset(struct data_queue *queue)
{
@@ -153,6 +498,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
rt2x00queue_reset(queue);
queue->limit = qdesc->entry_num;
+ queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
queue->data_size = qdesc->data_size;
queue->desc_size = qdesc->desc_size;
@@ -185,12 +531,41 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
return 0;
}
+static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev,
+ struct data_queue *queue)
+{
+ unsigned int i;
+
+ if (!queue->entries)
+ return;
+
+ for (i = 0; i < queue->limit; i++) {
+ if (queue->entries[i].skb)
+ rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb);
+ }
+}
+
+static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev,
+ struct data_queue *queue)
+{
+ unsigned int i;
+ struct sk_buff *skb;
+
+ for (i = 0; i < queue->limit; i++) {
+ skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]);
+ if (!skb)
+ return -ENOMEM;
+ queue->entries[i].skb = skb;
+ }
+
+ return 0;
+}
+
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
int status;
-
status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx);
if (status)
goto exit;
@@ -205,11 +580,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
if (status)
goto exit;
- if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
- return 0;
+ if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) {
+ status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1],
+ rt2x00dev->ops->atim);
+ if (status)
+ goto exit;
+ }
- status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1],
- rt2x00dev->ops->atim);
+ status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx);
if (status)
goto exit;
@@ -227,6 +605,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
+ rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx);
+
queue_for_each(rt2x00dev, queue) {
kfree(queue->entries);
queue->entries = NULL;
@@ -255,11 +635,11 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
/*
* We need the following queues:
* RX: 1
- * TX: hw->queues
+ * TX: ops->tx_queues
* Beacon: 1
* Atim: 1 (if required)
*/
- rt2x00dev->data_queues = 2 + rt2x00dev->hw->queues + req_atim;
+ rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim;
queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL);
if (!queue) {
@@ -272,7 +652,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->rx = queue;
rt2x00dev->tx = &queue[1];
- rt2x00dev->bcn = &queue[1 + rt2x00dev->hw->queues];
+ rt2x00dev->bcn = &queue[1 + rt2x00dev->ops->tx_queues];
/*
* Initialize queue parameters.
@@ -280,7 +660,8 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
* TX: qid = QID_AC_BE + index
* TX: cw_min: 2^5 = 32.
* TX: cw_max: 2^10 = 1024.
- * BCN & Atim: qid = QID_MGMT
+ * BCN: qid = QID_BEACON
+ * ATIM: qid = QID_ATIM
*/
rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);
@@ -288,9 +669,9 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
tx_queue_for_each(rt2x00dev, queue)
rt2x00queue_init(rt2x00dev, queue, qid++);
- rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT);
+ rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON);
if (req_atim)
- rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT);
+ rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM);
return 0;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 7027c9f47d3..8945945c892 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -42,18 +42,32 @@
/**
* DOC: Number of entries per queue
*
- * After research it was concluded that 12 entries in a RX and TX
- * queue would be sufficient. Although this is almost one third of
- * the amount the legacy driver allocated, the queues aren't getting
- * filled to the maximum even when working with the maximum rate.
+ * Under normal load without fragmentation 12 entries are sufficient
+ * without the queue being filled up to the maximum. When using fragmentation
+ * and the queue threshold code we need to add some additional margins to
+ * make sure the queue will never (or only under extreme load) fill up
+ * completely.
+ * Since we don't use preallocated DMA having a large number of queue entries
+ * will have only minimal impact on the memory requirements for the queue.
*/
-#define RX_ENTRIES 12
-#define TX_ENTRIES 12
+#define RX_ENTRIES 24
+#define TX_ENTRIES 24
#define BEACON_ENTRIES 1
-#define ATIM_ENTRIES 1
+#define ATIM_ENTRIES 8
/**
* enum data_queue_qid: Queue identification
+ *
+ * @QID_AC_BE: AC BE queue
+ * @QID_AC_BK: AC BK queue
+ * @QID_AC_VI: AC VI queue
+ * @QID_AC_VO: AC VO queue
+ * @QID_HCCA: HCCA queue
+ * @QID_MGMT: MGMT queue (prio queue)
+ * @QID_RX: RX queue
+ * @QID_OTHER: None of the above (don't use, only present for completeness)
+ * @QID_BEACON: Beacon queue (value unspecified, don't send it to device)
+ * @QID_ATIM: Atim queue (value unspeficied, don't send it to device)
*/
enum data_queue_qid {
QID_AC_BE = 0,
@@ -64,68 +78,55 @@ enum data_queue_qid {
QID_MGMT = 13,
QID_RX = 14,
QID_OTHER = 15,
-};
-
-/**
- * enum rt2x00_bcn_queue: Beacon queue index
- *
- * Start counting with a high offset, this because this enumeration
- * supplements &enum ieee80211_tx_queue and we should prevent value
- * conflicts.
- *
- * @RT2X00_BCN_QUEUE_BEACON: Beacon queue
- * @RT2X00_BCN_QUEUE_ATIM: Atim queue (sends frame after beacon)
- */
-enum rt2x00_bcn_queue {
- RT2X00_BCN_QUEUE_BEACON = 100,
- RT2X00_BCN_QUEUE_ATIM = 101,
+ QID_BEACON,
+ QID_ATIM,
};
/**
* enum skb_frame_desc_flags: Flags for &struct skb_frame_desc
*
- * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver
- * and should not be reported back to mac80211 during txdone.
+ * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
+ * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
*/
enum skb_frame_desc_flags {
- FRAME_DESC_DRIVER_GENERATED = 1 << 0,
+ SKBDESC_DMA_MAPPED_RX = (1 << 0),
+ SKBDESC_DMA_MAPPED_TX = (1 << 1),
};
/**
* struct skb_frame_desc: Descriptor information for the skb buffer
*
- * This structure is placed over the skb->cb array, this means that
- * this structure should not exceed the size of that array (48 bytes).
+ * This structure is placed over the driver_data array, this means that
+ * this structure should not exceed the size of that array (40 bytes).
*
* @flags: Frame flags, see &enum skb_frame_desc_flags.
- * @frame_type: Frame type, see &enum rt2x00_dump_type.
- * @data: Pointer to data part of frame (Start of ieee80211 header).
+ * @desc_len: Length of the frame descriptor.
* @desc: Pointer to descriptor part of the frame.
* Note that this pointer could point to something outside
* of the scope of the skb->data pointer.
- * @data_len: Length of the frame data.
- * @desc_len: Length of the frame descriptor.
-
+ * @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
* @entry: The entry to which this sk buffer belongs.
*/
struct skb_frame_desc {
unsigned int flags;
- unsigned int frame_type;
-
- void *data;
+ unsigned int desc_len;
void *desc;
- unsigned int data_len;
- unsigned int desc_len;
+ dma_addr_t skb_dma;
struct queue_entry *entry;
};
+/**
+ * get_skb_frame_desc - Obtain the rt2x00 frame descriptor from a sk_buff.
+ * @skb: &struct sk_buff from where we obtain the &struct skb_frame_desc
+ */
static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
{
- BUILD_BUG_ON(sizeof(struct skb_frame_desc) > sizeof(skb->cb));
- return (struct skb_frame_desc *)&skb->cb[0];
+ BUILD_BUG_ON(sizeof(struct skb_frame_desc) >
+ IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
+ return (struct skb_frame_desc *)&IEEE80211_SKB_CB(skb)->driver_data;
}
/**
@@ -145,6 +146,7 @@ enum rxdone_entry_desc_flags {
*
* Summary of information that has been read from the RX frame descriptor.
*
+ * @timestamp: RX Timestamp
* @signal: Signal of the received frame.
* @rssi: RSSI of the received frame.
* @size: Data size of the received frame.
@@ -153,6 +155,7 @@ enum rxdone_entry_desc_flags {
*/
struct rxdone_entry_desc {
+ u64 timestamp;
int signal;
int rssi;
int size;
@@ -161,18 +164,32 @@ struct rxdone_entry_desc {
};
/**
+ * enum txdone_entry_desc_flags: Flags for &struct txdone_entry_desc
+ *
+ * @TXDONE_UNKNOWN: Hardware could not determine success of transmission.
+ * @TXDONE_SUCCESS: Frame was successfully send
+ * @TXDONE_FAILURE: Frame was not successfully send
+ * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the
+ * frame transmission failed due to excessive retries.
+ */
+enum txdone_entry_desc_flags {
+ TXDONE_UNKNOWN = 1 << 0,
+ TXDONE_SUCCESS = 1 << 1,
+ TXDONE_FAILURE = 1 << 2,
+ TXDONE_EXCESSIVE_RETRY = 1 << 3,
+};
+
+/**
* struct txdone_entry_desc: TX done entry descriptor
*
* Summary of information that has been read from the TX frame descriptor
* after the device is done with transmission.
*
- * @control: Control structure which was used to transmit the frame.
- * @status: TX status (See &enum tx_status).
+ * @flags: TX done flags (See &enum txdone_entry_desc_flags).
* @retry: Retry count.
*/
struct txdone_entry_desc {
- struct ieee80211_tx_control *control;
- int status;
+ unsigned long flags;
int retry;
};
@@ -180,19 +197,25 @@ struct txdone_entry_desc {
* enum txentry_desc_flags: Status flags for TX entry descriptor
*
* @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.
+ * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.
* @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.
+ * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.
* @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.
* @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted.
* @ENTRY_TXD_BURST: This frame belongs to the same burst event.
* @ENTRY_TXD_ACK: An ACK is required for this frame.
+ * @ENTRY_TXD_RETRY_MODE: When set, the long retry count is used.
*/
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
+ ENTRY_TXD_CTS_FRAME,
ENTRY_TXD_OFDM_RATE,
+ ENTRY_TXD_FIRST_FRAGMENT,
ENTRY_TXD_MORE_FRAG,
ENTRY_TXD_REQ_TIMESTAMP,
ENTRY_TXD_BURST,
ENTRY_TXD_ACK,
+ ENTRY_TXD_RETRY_MODE,
};
/**
@@ -206,6 +229,7 @@ enum txentry_desc_flags {
* @length_low: PLCP length low word.
* @signal: PLCP signal.
* @service: PLCP service.
+ * @retry_limit: Max number of retries.
* @aifs: AIFS value.
* @ifs: IFS value.
* @cw_min: cwmin value.
@@ -221,10 +245,11 @@ struct txentry_desc {
u16 signal;
u16 service;
- int aifs;
- int ifs;
- int cw_min;
- int cw_max;
+ short retry_limit;
+ short aifs;
+ short ifs;
+ short cw_min;
+ short cw_max;
};
/**
@@ -239,12 +264,14 @@ struct txentry_desc {
* @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data
* encryption or decryption. The entry should only be touched after
* the device has signaled it is done with it.
+ * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting
+ * for the signal to start sending.
*/
-
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
ENTRY_OWNER_DEVICE_DATA,
ENTRY_OWNER_DEVICE_CRYPTO,
+ ENTRY_DATA_PENDING,
};
/**
@@ -302,6 +329,7 @@ enum queue_index {
* index corruption due to concurrency.
* @count: Number of frames handled in the queue.
* @limit: Maximum number of entries in the queue.
+ * @threshold: Minimum number of free entries before queue is kicked by force.
* @length: Number of frames in queue.
* @index: Index pointers to entry positions in the queue,
* use &enum queue_index to get a specific index field.
@@ -320,6 +348,7 @@ struct data_queue {
spinlock_t lock;
unsigned int count;
unsigned short limit;
+ unsigned short threshold;
unsigned short length;
unsigned short index[Q_INDEX_MAX];
@@ -369,7 +398,7 @@ struct data_queue_desc {
* the end of the TX queue array.
*/
#define tx_queue_end(__dev) \
- &(__dev)->tx[(__dev)->hw->queues]
+ &(__dev)->tx[(__dev)->ops->tx_queues]
/**
* queue_loop - Loop through the queues within a specific range (HELPER MACRO).
@@ -444,6 +473,15 @@ static inline int rt2x00queue_available(struct data_queue *queue)
}
/**
+ * rt2x00queue_threshold - Check if the queue is below threshold
+ * @queue: Queue to check.
+ */
+static inline int rt2x00queue_threshold(struct data_queue *queue)
+{
+ return rt2x00queue_available(queue) < queue->threshold;
+}
+
+/**
* rt2x00_desc_read - Read a word from the hardware descriptor.
* @desc: Base descriptor address
* @word: Word index from where the descriptor should be read.
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 0325bed2fbf..7e88ce5651b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -27,17 +27,6 @@
#define RT2X00REG_H
/*
- * TX result flags.
- */
-enum tx_status {
- TX_SUCCESS = 0,
- TX_SUCCESS_RETRY = 1,
- TX_FAIL_RETRY = 2,
- TX_FAIL_INVALID = 3,
- TX_FAIL_OTHER = 4,
-};
-
-/*
* Antenna values
*/
enum antenna {
@@ -141,83 +130,107 @@ struct rt2x00_field32 {
/*
* Power of two check, this will check
- * if the mask that has been given contains
- * and contiguous set of bits.
+ * if the mask that has been given contains and contiguous set of bits.
+ * Note that we cannot use the is_power_of_2() function since this
+ * check must be done at compile-time.
*/
#define is_power_of_two(x) ( !((x) & ((x)-1)) )
#define low_bit_mask(x) ( ((x)-1) & ~(x) )
#define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x))
+/*
+ * Macro's to find first set bit in a variable.
+ * These macro's behaves the same as the __ffs() function with
+ * the most important difference that this is done during
+ * compile-time rather then run-time.
+ */
+#define compile_ffs2(__x) \
+ __builtin_choose_expr(((__x) & 0x1), 0, 1)
+
+#define compile_ffs4(__x) \
+ __builtin_choose_expr(((__x) & 0x3), \
+ (compile_ffs2((__x))), \
+ (compile_ffs2((__x) >> 2) + 2))
+
+#define compile_ffs8(__x) \
+ __builtin_choose_expr(((__x) & 0xf), \
+ (compile_ffs4((__x))), \
+ (compile_ffs4((__x) >> 4) + 4))
+
+#define compile_ffs16(__x) \
+ __builtin_choose_expr(((__x) & 0xff), \
+ (compile_ffs8((__x))), \
+ (compile_ffs8((__x) >> 8) + 8))
+
+#define compile_ffs32(__x) \
+ __builtin_choose_expr(((__x) & 0xffff), \
+ (compile_ffs16((__x))), \
+ (compile_ffs16((__x) >> 16) + 16))
+
+/*
+ * This macro will check the requirements for the FIELD{8,16,32} macros
+ * The mask should be a constant non-zero contiguous set of bits which
+ * does not exceed the given typelimit.
+ */
+#define FIELD_CHECK(__mask, __type) \
+ BUILD_BUG_ON(!__builtin_constant_p(__mask) || \
+ !(__mask) || \
+ !is_valid_mask(__mask) || \
+ (__mask) != (__type)(__mask)) \
+
#define FIELD8(__mask) \
({ \
- BUILD_BUG_ON(!(__mask) || \
- !is_valid_mask(__mask) || \
- (__mask) != (u8)(__mask)); \
+ FIELD_CHECK(__mask, u8); \
(struct rt2x00_field8) { \
- __ffs(__mask), (__mask) \
+ compile_ffs8(__mask), (__mask) \
}; \
})
#define FIELD16(__mask) \
({ \
- BUILD_BUG_ON(!(__mask) || \
- !is_valid_mask(__mask) || \
- (__mask) != (u16)(__mask));\
+ FIELD_CHECK(__mask, u16); \
(struct rt2x00_field16) { \
- __ffs(__mask), (__mask) \
+ compile_ffs16(__mask), (__mask) \
}; \
})
#define FIELD32(__mask) \
({ \
- BUILD_BUG_ON(!(__mask) || \
- !is_valid_mask(__mask) || \
- (__mask) != (u32)(__mask));\
+ FIELD_CHECK(__mask, u32); \
(struct rt2x00_field32) { \
- __ffs(__mask), (__mask) \
+ compile_ffs32(__mask), (__mask) \
}; \
})
-static inline void rt2x00_set_field32(u32 *reg,
- const struct rt2x00_field32 field,
- const u32 value)
-{
- *reg &= ~(field.bit_mask);
- *reg |= (value << field.bit_offset) & field.bit_mask;
-}
-
-static inline u32 rt2x00_get_field32(const u32 reg,
- const struct rt2x00_field32 field)
-{
- return (reg & field.bit_mask) >> field.bit_offset;
-}
-
-static inline void rt2x00_set_field16(u16 *reg,
- const struct rt2x00_field16 field,
- const u16 value)
-{
- *reg &= ~(field.bit_mask);
- *reg |= (value << field.bit_offset) & field.bit_mask;
-}
-
-static inline u16 rt2x00_get_field16(const u16 reg,
- const struct rt2x00_field16 field)
-{
- return (reg & field.bit_mask) >> field.bit_offset;
-}
-
-static inline void rt2x00_set_field8(u8 *reg,
- const struct rt2x00_field8 field,
- const u8 value)
-{
- *reg &= ~(field.bit_mask);
- *reg |= (value << field.bit_offset) & field.bit_mask;
-}
-
-static inline u8 rt2x00_get_field8(const u8 reg,
- const struct rt2x00_field8 field)
-{
- return (reg & field.bit_mask) >> field.bit_offset;
-}
+#define SET_FIELD(__reg, __type, __field, __value)\
+({ \
+ typecheck(__type, __field); \
+ *(__reg) &= ~((__field).bit_mask); \
+ *(__reg) |= ((__value) << \
+ ((__field).bit_offset)) & \
+ ((__field).bit_mask); \
+})
+
+#define GET_FIELD(__reg, __type, __field) \
+({ \
+ typecheck(__type, __field); \
+ ((__reg) & ((__field).bit_mask)) >> \
+ ((__field).bit_offset); \
+})
+
+#define rt2x00_set_field32(__reg, __field, __value) \
+ SET_FIELD(__reg, struct rt2x00_field32, __field, __value)
+#define rt2x00_get_field32(__reg, __field) \
+ GET_FIELD(__reg, struct rt2x00_field32, __field)
+
+#define rt2x00_set_field16(__reg, __field, __value) \
+ SET_FIELD(__reg, struct rt2x00_field16, __field, __value)
+#define rt2x00_get_field16(__reg, __field) \
+ GET_FIELD(__reg, struct rt2x00_field16, __field)
+
+#define rt2x00_set_field8(__reg, __field, __value) \
+ SET_FIELD(__reg, struct rt2x00_field8, __field, __value)
+#define rt2x00_get_field8(__reg, __field) \
+ GET_FIELD(__reg, struct rt2x00_field8, __field)
#endif /* RT2X00REG_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index fcef9885ab5..04b29716d35 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -23,7 +23,6 @@
Abstract: rt2x00 rfkill routines.
*/
-#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/rfkill.h>
@@ -45,28 +44,51 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
return 0;
- if (state == RFKILL_STATE_ON) {
+ if (state == RFKILL_STATE_UNBLOCKED) {
INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n");
__clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
retval = rt2x00lib_enable_radio(rt2x00dev);
- } else if (state == RFKILL_STATE_OFF) {
+ } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n");
__set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags);
rt2x00lib_disable_radio(rt2x00dev);
+ } else {
+ WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n",
+ state);
}
return retval;
}
-static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
+static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
{
- struct rt2x00_dev *rt2x00dev = poll_dev->private;
- int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+ struct rt2x00_dev *rt2x00dev = data;
- if (rt2x00dev->rfkill->state != state) {
- input_report_key(poll_dev->input, KEY_WLAN, 1);
- input_report_key(poll_dev->input, KEY_WLAN, 0);
- }
+ *state = rt2x00dev->rfkill->state;
+
+ return 0;
+}
+
+static void rt2x00rfkill_poll(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, rfkill_work.work);
+ int state;
+
+ if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
+ return;
+
+ /*
+ * rfkill_poll reports 1 when the key has been pressed and the
+ * radio should be blocked.
+ */
+ state = !rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
+ RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+
+ rfkill_force_state(rt2x00dev->rfkill, state);
+
+ queue_delayed_work(rt2x00dev->hw->workqueue,
+ &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
}
void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -80,12 +102,6 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
return;
}
- if (input_register_polled_device(rt2x00dev->poll_dev)) {
- ERROR(rt2x00dev, "Failed to register polled device.\n");
- rfkill_unregister(rt2x00dev->rfkill);
- return;
- }
-
__set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
/*
@@ -93,7 +109,7 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
* and correctly sends the signal to the rfkill layer about this
* state.
*/
- rt2x00rfkill_poll(rt2x00dev->poll_dev);
+ rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work);
}
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
@@ -102,38 +118,13 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
- input_unregister_polled_device(rt2x00dev->poll_dev);
+ cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
+
rfkill_unregister(rt2x00dev->rfkill);
__clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
}
-static struct input_polled_dev *
-rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev)
-{
- struct input_polled_dev *poll_dev;
-
- poll_dev = input_allocate_polled_device();
- if (!poll_dev)
- return NULL;
-
- poll_dev->private = rt2x00dev;
- poll_dev->poll = rt2x00rfkill_poll;
- poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
-
- poll_dev->input->name = rt2x00dev->ops->name;
- poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
- poll_dev->input->id.bustype = BUS_HOST;
- poll_dev->input->id.vendor = 0x1814;
- poll_dev->input->id.product = rt2x00dev->chip.rt;
- poll_dev->input->id.version = rt2x00dev->chip.rev;
- poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
- poll_dev->input->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, poll_dev->input->keybit);
-
- return poll_dev;
-}
-
void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
{
if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
@@ -150,14 +141,9 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
rt2x00dev->rfkill->data = rt2x00dev;
rt2x00dev->rfkill->state = -1;
rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
+ rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
- rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
- if (!rt2x00dev->poll_dev) {
- ERROR(rt2x00dev, "Failed to allocate polled device.\n");
- rfkill_free(rt2x00dev->rfkill);
- rt2x00dev->rfkill = NULL;
- return;
- }
+ INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
return;
}
@@ -168,32 +154,8 @@ void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
return;
- input_free_polled_device(rt2x00dev->poll_dev);
- rt2x00dev->poll_dev = NULL;
+ cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
rfkill_free(rt2x00dev->rfkill);
rt2x00dev->rfkill = NULL;
}
-
-void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev)
-{
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
- !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
- return;
-
- input_free_polled_device(rt2x00dev->poll_dev);
- rt2x00dev->poll_dev = NULL;
-}
-
-void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev)
-{
- if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) ||
- !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
- return;
-
- rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev);
- if (!rt2x00dev->poll_dev) {
- ERROR(rt2x00dev, "Failed to allocate polled device.\n");
- return;
- }
-}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index e5ceae805b5..83862e7f7ae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -40,7 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
void *buffer, const u16 buffer_length,
const int timeout)
{
- struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
int status;
unsigned int i;
unsigned int pipe =
@@ -129,17 +129,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data;
struct txdone_entry_desc txdesc;
- __le32 *txd = (__le32 *)entry->skb->data;
- u32 word;
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
- !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;
- rt2x00_desc_read(txd, 0, &word);
-
/*
* Remove the descriptor data from the buffer.
*/
@@ -147,128 +142,116 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
/*
* Obtain the status about this packet.
+ * Note that when the status is 0 it does not mean the
+ * frame was send out correctly. It only means the frame
+ * was succesfully pushed to the hardware, we have no
+ * way to determine the transmission status right now.
+ * (Only indirectly by looking at the failed TX counters
+ * in the register).
*/
- txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY;
+ if (!urb->status)
+ __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
+ else
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
txdesc.retry = 0;
- txdesc.control = &priv_tx->control;
rt2x00lib_txdone(entry, &txdesc);
-
- /*
- * Make this entry available for reuse.
- */
- entry->flags = 0;
- rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
-
- /*
- * If the data queue was full before the txdone handler
- * we must make sure the packet queue in the mac80211 stack
- * is reenabled when the txdone handler has finished.
- */
- if (!rt2x00queue_full(entry->queue))
- ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue);
}
-int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+int rt2x00usb_write_tx_data(struct queue_entry *entry)
{
- struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
- struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data;
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
struct skb_frame_desc *skbdesc;
u32 length;
- if (rt2x00queue_full(queue))
- return -EINVAL;
-
- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {
- ERROR(rt2x00dev,
- "Arrived at non-free entry in the non-full queue %d.\n"
- "Please file bug report to %s.\n",
- control->queue, DRV_PROJECT);
- return -EINVAL;
- }
-
/*
* Add the descriptor in front of the skb.
*/
- skb_push(skb, queue->desc_size);
- memset(skb->data, 0, queue->desc_size);
+ skb_push(entry->skb, entry->queue->desc_size);
+ memset(entry->skb->data, 0, entry->queue->desc_size);
/*
* Fill in skb descriptor
*/
- skbdesc = get_skb_frame_desc(skb);
- skbdesc->data = skb->data + queue->desc_size;
- skbdesc->data_len = skb->len - queue->desc_size;
- skbdesc->desc = skb->data;
- skbdesc->desc_len = queue->desc_size;
- skbdesc->entry = entry;
-
- memcpy(&priv_tx->control, control, sizeof(priv_tx->control));
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
+ skbdesc = get_skb_frame_desc(entry->skb);
+ skbdesc->desc = entry->skb->data;
+ skbdesc->desc_len = entry->queue->desc_size;
/*
* USB devices cannot blindly pass the skb->len as the
* length of the data to usb_fill_bulk_urb. Pass the skb
* to the driver to determine what the length should be.
*/
- length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb);
-
- /*
- * Initialize URB and send the frame to the device.
- */
- __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- usb_fill_bulk_urb(priv_tx->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1),
- skb->data, length, rt2x00usb_interrupt_txdone, entry);
- usb_submit_urb(priv_tx->urb, GFP_ATOMIC);
+ length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);
- rt2x00queue_index_inc(queue, Q_INDEX);
+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,
+ usb_sndbulkpipe(usb_dev, 1),
+ entry->skb->data, length,
+ rt2x00usb_interrupt_txdone, entry);
return 0;
}
EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
-/*
- * RX data handlers.
- */
-static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
+static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
{
- struct sk_buff *skb;
- unsigned int frame_size;
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
+
+ if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))
+ usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
+}
+
+void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
+ unsigned long irqflags;
+ unsigned int index;
+ unsigned int index_done;
+ unsigned int i;
/*
- * As alignment we use 2 and not NET_IP_ALIGN because we need
- * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN
- * can be 0 on some hardware). We use these 2 bytes for frame
- * alignment later, we assume that the chance that
- * header_size % 4 == 2 is bigger then header_size % 2 == 0
- * and thus optimize alignment by reserving the 2 bytes in
- * advance.
+ * Only protect the range we are going to loop over,
+ * if during our loop a extra entry is set to pending
+ * it should not be kicked during this run, since it
+ * is part of another TX operation.
*/
- frame_size = queue->data_size + queue->desc_size;
- skb = dev_alloc_skb(queue->desc_size + frame_size + 2);
- if (!skb)
- return NULL;
-
- skb_reserve(skb, queue->desc_size + 2);
- skb_put(skb, frame_size);
+ spin_lock_irqsave(&queue->lock, irqflags);
+ index = queue->index[Q_INDEX];
+ index_done = queue->index[Q_INDEX_DONE];
+ spin_unlock_irqrestore(&queue->lock, irqflags);
- return skb;
+ /*
+ * Start from the TX done pointer, this guarentees that we will
+ * send out all frames in the correct order.
+ */
+ if (index_done < index) {
+ for (i = index_done; i < index; i++)
+ rt2x00usb_kick_tx_entry(&queue->entries[i]);
+ } else {
+ for (i = index_done; i < queue->limit; i++)
+ rt2x00usb_kick_tx_entry(&queue->entries[i]);
+
+ for (i = 0; i < index; i++)
+ rt2x00usb_kick_tx_entry(&queue->entries[i]);
+ }
}
+EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
+/*
+ * RX data handlers.
+ */
static void rt2x00usb_interrupt_rxdone(struct urb *urb)
{
struct queue_entry *entry = (struct queue_entry *)urb->context;
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
- struct sk_buff *skb;
- struct skb_frame_desc *skbdesc;
- struct rxdone_entry_desc rxdesc;
- int header_size;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ u8 rxd[32];
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
- !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+ !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
return;
/*
@@ -276,61 +259,22 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* to be actually valid, or if the urb is signaling
* a problem.
*/
- if (urb->actual_length < entry->queue->desc_size || urb->status)
- goto skip_entry;
-
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(entry->skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->entry = entry;
-
- memset(&rxdesc, 0, sizeof(rxdesc));
- rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
-
- /*
- * The data behind the ieee80211 header must be
- * aligned on a 4 byte boundary.
- */
- header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
- if (header_size % 4 == 0) {
- skb_push(entry->skb, 2);
- memmove(entry->skb->data, entry->skb->data + 2,
- entry->skb->len - 2);
- skbdesc->data = entry->skb->data;
- skb_trim(entry->skb,entry->skb->len - 2);
+ if (urb->actual_length < entry->queue->desc_size || urb->status) {
+ __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
+ usb_submit_urb(urb, GFP_ATOMIC);
+ return;
}
/*
- * Allocate a new sk buffer to replace the current one.
- * If allocation fails, we should drop the current frame
- * so we can recycle the existing sk buffer for the new frame.
+ * Fill in desc fields of the skb descriptor
*/
- skb = rt2x00usb_alloc_rxskb(entry->queue);
- if (!skb)
- goto skip_entry;
+ skbdesc->desc = rxd;
+ skbdesc->desc_len = entry->queue->desc_size;
/*
* Send the frame to rt2x00lib for further processing.
*/
- rt2x00lib_rxdone(entry, &rxdesc);
-
- /*
- * Replace current entry's skb with the newly allocated one,
- * and reinitialize the urb.
- */
- entry->skb = skb;
- urb->transfer_buffer = entry->skb->data;
- urb->transfer_buffer_length = entry->skb->len;
-
-skip_entry:
- if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) {
- __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- usb_submit_urb(urb, GFP_ATOMIC);
- }
-
- rt2x00queue_index_inc(entry->queue, Q_INDEX);
+ rt2x00lib_rxdone(rt2x00dev, entry);
}
/*
@@ -338,27 +282,21 @@ skip_entry:
*/
void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- struct queue_entry_priv_usb_rx *priv_rx;
- struct queue_entry_priv_usb_tx *priv_tx;
- struct queue_entry_priv_usb_bcn *priv_bcn;
+ struct queue_entry_priv_usb *entry_priv;
+ struct queue_entry_priv_usb_bcn *bcn_priv;
struct data_queue *queue;
unsigned int i;
- rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000,
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
REGISTER_TIMEOUT);
/*
* Cancel all queues.
*/
- for (i = 0; i < rt2x00dev->rx->limit; i++) {
- priv_rx = rt2x00dev->rx->entries[i].priv_data;
- usb_kill_urb(priv_rx->urb);
- }
-
- tx_queue_for_each(rt2x00dev, queue) {
+ queue_for_each(rt2x00dev, queue) {
for (i = 0; i < queue->limit; i++) {
- priv_tx = queue->entries[i].priv_data;
- usb_kill_urb(priv_tx->urb);
+ entry_priv = queue->entries[i].priv_data;
+ usb_kill_urb(entry_priv->urb);
}
}
@@ -369,19 +307,9 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
return;
for (i = 0; i < rt2x00dev->bcn->limit; i++) {
- priv_bcn = rt2x00dev->bcn->entries[i].priv_data;
- usb_kill_urb(priv_bcn->urb);
-
- if (priv_bcn->guardian_urb)
- usb_kill_urb(priv_bcn->guardian_urb);
- }
-
- if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
- return;
-
- for (i = 0; i < rt2x00dev->bcn[1].limit; i++) {
- priv_tx = rt2x00dev->bcn[1].entries[i].priv_data;
- usb_kill_urb(priv_tx->urb);
+ bcn_priv = rt2x00dev->bcn->entries[i].priv_data;
+ if (bcn_priv->guardian_urb)
+ usb_kill_urb(bcn_priv->guardian_urb);
}
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
@@ -392,16 +320,16 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);
- struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data;
+ struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;
- usb_fill_bulk_urb(priv_rx->urb, usb_dev,
+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,
usb_rcvbulkpipe(usb_dev, 1),
entry->skb->data, entry->skb->len,
rt2x00usb_interrupt_rxdone, entry);
__set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
- usb_submit_urb(priv_rx->urb, GFP_ATOMIC);
+ usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
}
EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
@@ -415,38 +343,31 @@ EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry);
static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
- struct queue_entry_priv_usb_rx *priv_rx;
- struct queue_entry_priv_usb_tx *priv_tx;
- struct queue_entry_priv_usb_bcn *priv_bcn;
- struct urb *urb;
- unsigned int guardian =
- test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
+ struct queue_entry_priv_usb *entry_priv;
+ struct queue_entry_priv_usb_bcn *bcn_priv;
unsigned int i;
+ for (i = 0; i < queue->limit; i++) {
+ entry_priv = queue->entries[i].priv_data;
+ entry_priv->urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!entry_priv->urb)
+ return -ENOMEM;
+ }
+
/*
- * Allocate the URB's
+ * If this is not the beacon queue or
+ * no guardian byte was required for the beacon,
+ * then we are done.
*/
+ if (rt2x00dev->bcn != queue ||
+ !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+ return 0;
+
for (i = 0; i < queue->limit; i++) {
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
+ bcn_priv = queue->entries[i].priv_data;
+ bcn_priv->guardian_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!bcn_priv->guardian_urb)
return -ENOMEM;
-
- if (queue->qid == QID_RX) {
- priv_rx = queue->entries[i].priv_data;
- priv_rx->urb = urb;
- } else if (queue->qid == QID_MGMT && guardian) {
- priv_bcn = queue->entries[i].priv_data;
- priv_bcn->urb = urb;
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
-
- priv_bcn->guardian_urb = urb;
- } else {
- priv_tx = queue->entries[i].priv_data;
- priv_tx->urb = urb;
- }
}
return 0;
@@ -455,47 +376,39 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev,
struct data_queue *queue)
{
- struct queue_entry_priv_usb_rx *priv_rx;
- struct queue_entry_priv_usb_tx *priv_tx;
- struct queue_entry_priv_usb_bcn *priv_bcn;
- struct urb *urb;
- unsigned int guardian =
- test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
+ struct queue_entry_priv_usb *entry_priv;
+ struct queue_entry_priv_usb_bcn *bcn_priv;
unsigned int i;
if (!queue->entries)
return;
for (i = 0; i < queue->limit; i++) {
- if (queue->qid == QID_RX) {
- priv_rx = queue->entries[i].priv_data;
- urb = priv_rx->urb;
- } else if (queue->qid == QID_MGMT && guardian) {
- priv_bcn = queue->entries[i].priv_data;
-
- usb_kill_urb(priv_bcn->guardian_urb);
- usb_free_urb(priv_bcn->guardian_urb);
-
- urb = priv_bcn->urb;
- } else {
- priv_tx = queue->entries[i].priv_data;
- urb = priv_tx->urb;
- }
+ entry_priv = queue->entries[i].priv_data;
+ usb_kill_urb(entry_priv->urb);
+ usb_free_urb(entry_priv->urb);
+ }
- usb_kill_urb(urb);
- usb_free_urb(urb);
- if (queue->entries[i].skb)
- kfree_skb(queue->entries[i].skb);
+ /*
+ * If this is not the beacon queue or
+ * no guardian byte was required for the beacon,
+ * then we are done.
+ */
+ if (rt2x00dev->bcn != queue ||
+ !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+ return;
+
+ for (i = 0; i < queue->limit; i++) {
+ bcn_priv = queue->entries[i].priv_data;
+ usb_kill_urb(bcn_priv->guardian_urb);
+ usb_free_urb(bcn_priv->guardian_urb);
}
}
int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
- struct sk_buff *skb;
- unsigned int entry_size;
- unsigned int i;
- int uninitialized_var(status);
+ int status;
/*
* Allocate DMA
@@ -506,18 +419,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
goto exit;
}
- /*
- * For the RX queue, skb's should be allocated.
- */
- entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;
- for (i = 0; i < rt2x00dev->rx->limit; i++) {
- skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx);
- if (!skb)
- goto exit;
-
- rt2x00dev->rx->entries[i].skb = skb;
- }
-
return 0;
exit:
@@ -596,7 +497,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
usb_set_intfdata(usb_intf, hw);
rt2x00dev = hw->priv;
- rt2x00dev->dev = usb_intf;
+ rt2x00dev->dev = &usb_intf->dev;
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
mutex_init(&rt2x00dev->usb_cache_mutex);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 11e55180cba..aad794adf52 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -26,6 +26,12 @@
#ifndef RT2X00USB_H
#define RT2X00USB_H
+#define to_usb_device_intf(d) \
+({ \
+ struct usb_interface *intf = to_usb_interface(d); \
+ interface_to_usbdev(intf); \
+})
+
/*
* This variable should be used with the
* usb_driver structure initialization.
@@ -47,6 +53,20 @@
#define REGISTER_TIMEOUT 500
#define REGISTER_TIMEOUT_FIRMWARE 1000
+/**
+ * REGISTER_TIMEOUT16 - Determine the timeout for 16bit register access
+ * @__datalen: Data length
+ */
+#define REGISTER_TIMEOUT16(__datalen) \
+ ( REGISTER_TIMEOUT * ((__datalen) / sizeof(u16)) )
+
+/**
+ * REGISTER_TIMEOUT32 - Determine the timeout for 32bit register access
+ * @__datalen: Data length
+ */
+#define REGISTER_TIMEOUT32(__datalen) \
+ ( REGISTER_TIMEOUT * ((__datalen) / sizeof(u32)) )
+
/*
* Cache size
*/
@@ -185,13 +205,12 @@ static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev,
* kmalloc for correct handling inside the kernel USB layer.
*/
static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,
- __le16 *eeprom, const u16 lenght)
+ __le16 *eeprom, const u16 length)
{
- int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16));
-
return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ,
USB_VENDOR_REQUEST_IN, 0, 0,
- eeprom, lenght, timeout);
+ eeprom, length,
+ REGISTER_TIMEOUT16(length));
}
/*
@@ -199,55 +218,53 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,
*/
void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
-/*
- * TX data handlers.
- */
-int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue, struct sk_buff *skb,
- struct ieee80211_tx_control *control);
-
/**
- * struct queue_entry_priv_usb_rx: Per RX entry USB specific information
+ * rt2x00usb_write_tx_data - Initialize URB for TX operation
+ * @entry: The entry where the frame is located
*
- * @urb: Urb structure used for device communication.
+ * This function will initialize the URB and skb descriptor
+ * to prepare the entry for the actual TX operation.
*/
-struct queue_entry_priv_usb_rx {
- struct urb *urb;
-};
+int rt2x00usb_write_tx_data(struct queue_entry *entry);
/**
- * struct queue_entry_priv_usb_tx: Per TX entry USB specific information
+ * struct queue_entry_priv_usb: Per entry USB specific information
*
* @urb: Urb structure used for device communication.
- * @control: mac80211 control structure used to transmit data.
*/
-struct queue_entry_priv_usb_tx {
+struct queue_entry_priv_usb {
struct urb *urb;
-
- struct ieee80211_tx_control control;
};
/**
- * struct queue_entry_priv_usb_tx: Per TX entry USB specific information
+ * struct queue_entry_priv_usb_bcn: Per TX entry USB specific information
*
- * The first section should match &struct queue_entry_priv_usb_tx exactly.
+ * The first section should match &struct queue_entry_priv_usb exactly.
* rt2500usb can use this structure to send a guardian byte when working
* with beacons.
*
* @urb: Urb structure used for device communication.
- * @control: mac80211 control structure used to transmit data.
* @guardian_data: Set to 0, used for sending the guardian data.
* @guardian_urb: Urb structure used to send the guardian data.
*/
struct queue_entry_priv_usb_bcn {
struct urb *urb;
- struct ieee80211_tx_control control;
-
unsigned int guardian_data;
struct urb *guardian_urb;
};
+/**
+ * rt2x00usb_kick_tx_queue - Kick data queue
+ * @rt2x00dev: Pointer to &struct rt2x00_dev
+ * @qid: Data queue to kick
+ *
+ * This will walk through all entries of the queue and push all pending
+ * frames to the hardware as a single burst.
+ */
+void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid);
+
/*
* Device initialization handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 580f90b63de..f7c1f92c144 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -330,6 +330,17 @@ static int rt61pci_blink_set(struct led_classdev *led_cdev,
return 0;
}
+
+static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt61pci_brightness_set;
+ led->led_dev.blink_set = rt61pci_blink_set;
+ led->flags = LED_INITIALIZED;
+}
#endif /* CONFIG_RT61PCI_LEDS */
/*
@@ -1018,49 +1029,35 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
u32 word;
- rt2x00_desc_read(priv_rx->desc, 5, &word);
+ rt2x00_desc_read(entry_priv->desc, 5, &word);
rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
- priv_rx->data_dma);
- rt2x00_desc_write(priv_rx->desc, 5, word);
+ skbdesc->skb_dma);
+ rt2x00_desc_write(entry_priv->desc, 5, word);
- rt2x00_desc_read(priv_rx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
- rt2x00_desc_write(priv_rx->desc, 0, word);
+ rt2x00_desc_write(entry_priv->desc, 0, word);
}
static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
struct queue_entry *entry)
{
- struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
u32 word;
- rt2x00_desc_read(priv_tx->desc, 1, &word);
- rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
- rt2x00_desc_write(priv_tx->desc, 1, word);
-
- rt2x00_desc_read(priv_tx->desc, 5, &word);
- rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid);
- rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx);
- rt2x00_desc_write(priv_tx->desc, 5, word);
-
- rt2x00_desc_read(priv_tx->desc, 6, &word);
- rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
- priv_tx->data_dma);
- rt2x00_desc_write(priv_tx->desc, 6, word);
-
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
rt2x00_set_field32(&word, TXD_W0_VALID, 0);
rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
- rt2x00_desc_write(priv_tx->desc, 0, word);
+ rt2x00_desc_write(entry_priv->desc, 0, word);
}
static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
{
- struct queue_entry_priv_pci_rx *priv_rx;
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
u32 reg;
/*
@@ -1082,28 +1079,28 @@ static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00dev->tx[0].desc_size / 4);
rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg);
- priv_tx = rt2x00dev->tx[0].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, &reg);
rt2x00_set_field32(&reg, AC0_BASE_CSR_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg);
- priv_tx = rt2x00dev->tx[1].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, &reg);
rt2x00_set_field32(&reg, AC1_BASE_CSR_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg);
- priv_tx = rt2x00dev->tx[2].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, &reg);
rt2x00_set_field32(&reg, AC2_BASE_CSR_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg);
- priv_tx = rt2x00dev->tx[3].entries[0].priv_data;
+ entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, &reg);
rt2x00_set_field32(&reg, AC3_BASE_CSR_RING_REGISTER,
- priv_tx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg);
rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, &reg);
@@ -1113,10 +1110,10 @@ static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4);
rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg);
- priv_rx = rt2x00dev->rx->entries[0].priv_data;
+ entry_priv = rt2x00dev->rx->entries[0].priv_data;
rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, &reg);
rt2x00_set_field32(&reg, RX_BASE_CSR_RING_REGISTER,
- priv_rx->desc_dma);
+ entry_priv->desc_dma);
rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg);
rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, &reg);
@@ -1294,25 +1291,32 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
- u16 eeprom;
- u8 reg_id;
u8 value;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt61pci_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
- goto continue_csr_init;
- NOTICE(rt2x00dev, "Waiting for BBP register.\n");
+ return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
+}
+
+static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 reg_id;
+ u8 value;
+
+ if (unlikely(rt61pci_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
-continue_csr_init:
rt61pci_bbp_write(rt2x00dev, 3, 0x00);
rt61pci_bbp_write(rt2x00dev, 15, 0x30);
rt61pci_bbp_write(rt2x00dev, 21, 0xc8);
@@ -1361,7 +1365,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
- state == STATE_RADIO_RX_OFF);
+ (state == STATE_RADIO_RX_OFF) ||
+ (state == STATE_RADIO_RX_OFF_LINK));
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
}
@@ -1413,17 +1418,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all registers.
*/
- if (rt61pci_init_queues(rt2x00dev) ||
- rt61pci_init_registers(rt2x00dev) ||
- rt61pci_init_bbp(rt2x00dev)) {
- ERROR(rt2x00dev, "Register initialization failed.\n");
+ if (unlikely(rt61pci_init_queues(rt2x00dev) ||
+ rt61pci_init_registers(rt2x00dev) ||
+ rt61pci_init_bbp(rt2x00dev)))
return -EIO;
- }
-
- /*
- * Enable interrupts.
- */
- rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
/*
* Enable RX.
@@ -1455,11 +1453,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
-
- /*
- * Disable interrupts.
- */
- rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);
}
static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
@@ -1467,7 +1460,6 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
u32 reg;
unsigned int i;
char put_to_sleep;
- char current_state;
put_to_sleep = (state != STATE_AWAKE);
@@ -1483,16 +1475,12 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
*/
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00pci_register_read(rt2x00dev, MAC_CSR12, &reg);
- current_state =
- rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
- if (current_state == !put_to_sleep)
+ state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+ if (state == !put_to_sleep)
return 0;
msleep(10);
}
- NOTICE(rt2x00dev, "Device failed to enter state %d, "
- "current device state %d.\n", !put_to_sleep, current_state);
-
return -EBUSY;
}
@@ -1510,11 +1498,13 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
case STATE_RADIO_RX_ON:
case STATE_RADIO_RX_ON_LINK:
- rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
- break;
case STATE_RADIO_RX_OFF:
case STATE_RADIO_RX_OFF_LINK:
- rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt61pci_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ rt61pci_toggle_irq(rt2x00dev, state);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
@@ -1527,6 +1517,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
}
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
return retval;
}
@@ -1535,8 +1529,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
- struct txentry_desc *txdesc,
- struct ieee80211_tx_control *control)
+ struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = skbdesc->desc;
@@ -1552,6 +1545,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);
rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);
+ rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
@@ -1562,14 +1556,22 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 5, &word);
+ rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid);
+ rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE,
+ skbdesc->entry->entry_idx);
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
TXPOWER_TO_DEV(rt2x00dev->tx_power));
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word);
+ rt2x00_desc_read(txd, 6, &word);
+ rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
+ skbdesc->skb_dma);
+ rt2x00_desc_write(txd, 6, word);
+
if (skbdesc->desc_len > TXINFO_SIZE) {
rt2x00_desc_read(txd, 11, &word);
- rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len);
rt2x00_desc_write(txd, 11, word);
}
@@ -1586,10 +1588,9 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
- !!(control->flags &
- IEEE80211_TXCTL_LONG_RETRY_LIMIT));
+ test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
rt2x00_set_field32(&word, TXD_W0_BURST,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
@@ -1599,12 +1600,47 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* TX data initialization
*/
+static void rt61pci_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ unsigned int beacon_base;
+ u32 reg;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+ /*
+ * Write entire beacon with descriptor to register.
+ */
+ beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+ rt2x00pci_register_multiwrite(rt2x00dev,
+ beacon_base,
+ skbdesc->desc, skbdesc->desc_len);
+ rt2x00pci_register_multiwrite(rt2x00dev,
+ beacon_base + skbdesc->desc_len,
+ entry->skb->data, entry->skb->len);
+
+ /*
+ * Clean up beacon skb.
+ */
+ dev_kfree_skb_any(entry->skb);
+ entry->skb = NULL;
+}
+
static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue)
+ const enum data_queue_qid queue)
{
u32 reg;
- if (queue == RT2X00_BCN_QUEUE_BEACON) {
+ if (queue == QID_BEACON) {
/*
* For Wi-Fi faily generated beacons between participating
* stations. Set TBTT phase adaptive adjustment step to 8us.
@@ -1622,14 +1658,10 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0,
- (queue == IEEE80211_TX_QUEUE_DATA0));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1,
- (queue == IEEE80211_TX_QUEUE_DATA1));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2,
- (queue == IEEE80211_TX_QUEUE_DATA2));
- rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3,
- (queue == IEEE80211_TX_QUEUE_DATA3));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO));
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
@@ -1680,14 +1712,13 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
static void rt61pci_fill_rxdone(struct queue_entry *entry,
struct rxdone_entry_desc *rxdesc)
{
- struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data;
+ struct queue_entry_priv_pci *entry_priv = entry->priv_data;
u32 word0;
u32 word1;
- rt2x00_desc_read(priv_rx->desc, 0, &word0);
- rt2x00_desc_read(priv_rx->desc, 1, &word1);
+ rt2x00_desc_read(entry_priv->desc, 0, &word0);
+ rt2x00_desc_read(entry_priv->desc, 1, &word1);
- rxdesc->flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
@@ -1701,7 +1732,6 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry,
rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1);
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- rxdesc->dev_flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_OFDM))
rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
@@ -1716,7 +1746,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
struct data_queue *queue;
struct queue_entry *entry;
struct queue_entry *entry_done;
- struct queue_entry_priv_pci_tx *priv_tx;
+ struct queue_entry_priv_pci *entry_priv;
struct txdone_entry_desc txdesc;
u32 word;
u32 reg;
@@ -1761,8 +1791,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
continue;
entry = &queue->entries[index];
- priv_tx = entry->priv_data;
- rt2x00_desc_read(priv_tx->desc, 0, &word);
+ entry_priv = entry->priv_data;
+ rt2x00_desc_read(entry_priv->desc, 0, &word);
if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
!rt2x00_get_field32(word, TXD_W0_VALID))
@@ -1777,20 +1807,31 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
"TX status report missed for entry %d\n",
entry_done->entry_idx);
- txdesc.status = TX_FAIL_OTHER;
+ txdesc.flags = 0;
+ __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
txdesc.retry = 0;
- rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc);
+ rt2x00lib_txdone(entry_done, &txdesc);
entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
}
/*
* Obtain the status about this packet.
*/
- txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT);
+ txdesc.flags = 0;
+ switch (rt2x00_get_field32(reg, STA_CSR4_TX_RESULT)) {
+ case 0: /* Success, maybe with retry */
+ __set_bit(TXDONE_SUCCESS, &txdesc.flags);
+ break;
+ case 6: /* Failure, excessive retries */
+ __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags);
+ /* Don't break, this is a failed frame! */
+ default: /* Failure */
+ __set_bit(TXDONE_FAILURE, &txdesc.flags);
+ }
txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
- rt2x00pci_txdone(rt2x00dev, entry, &txdesc);
+ rt2x00lib_txdone(entry, &txdesc);
}
}
@@ -1976,7 +2017,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* To determine the RT chip we have to read the
* PCI header of the device.
*/
- pci_read_config_word(rt2x00dev_pci(rt2x00dev),
+ pci_read_config_word(to_pci_dev(rt2x00dev->dev),
PCI_CONFIG_HEADER_DEVICE, &device);
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
@@ -2078,31 +2119,11 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE);
- rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
- rt2x00dev->led_radio.type = LED_TYPE_RADIO;
- rt2x00dev->led_radio.led_dev.brightness_set =
- rt61pci_brightness_set;
- rt2x00dev->led_radio.led_dev.blink_set =
- rt61pci_blink_set;
- rt2x00dev->led_radio.flags = LED_INITIALIZED;
-
- rt2x00dev->led_assoc.rt2x00dev = rt2x00dev;
- rt2x00dev->led_assoc.type = LED_TYPE_ASSOC;
- rt2x00dev->led_assoc.led_dev.brightness_set =
- rt61pci_brightness_set;
- rt2x00dev->led_assoc.led_dev.blink_set =
- rt61pci_blink_set;
- rt2x00dev->led_assoc.flags = LED_INITIALIZED;
-
- if (value == LED_MODE_SIGNAL_STRENGTH) {
- rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
- rt2x00dev->led_qual.type = LED_TYPE_QUALITY;
- rt2x00dev->led_qual.led_dev.brightness_set =
- rt61pci_brightness_set;
- rt2x00dev->led_qual.led_dev.blink_set =
- rt61pci_blink_set;
- rt2x00dev->led_qual.flags = LED_INITIALIZED;
- }
+ rt61pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ rt61pci_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+ if (value == LED_MODE_SIGNAL_STRENGTH)
+ rt61pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
+ LED_TYPE_QUALITY);
rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0,
@@ -2258,13 +2279,11 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM;
rt2x00dev->hw->extra_tx_headroom = 0;
- rt2x00dev->hw->max_signal = MAX_SIGNAL;
- rt2x00dev->hw->max_rssi = MAX_RX_SSI;
- rt2x00dev->hw->queues = 4;
- SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev);
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
@@ -2327,9 +2346,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
rt61pci_probe_hw_mode(rt2x00dev);
/*
- * This device requires firmware.
+ * This device requires firmware and DMA mapped skbs.
*/
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
/*
* Set the rssi offset.
@@ -2370,67 +2390,6 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw)
return tsf;
}
-static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(control->vif);
- struct queue_entry_priv_pci_tx *priv_tx;
- struct skb_frame_desc *skbdesc;
- unsigned int beacon_base;
- u32 reg;
-
- if (unlikely(!intf->beacon))
- return -ENOBUFS;
-
- priv_tx = intf->beacon->priv_data;
- memset(priv_tx->desc, 0, intf->beacon->queue->desc_size);
-
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
- skbdesc->data = skb->data;
- skbdesc->data_len = skb->len;
- skbdesc->desc = priv_tx->desc;
- skbdesc->desc_len = intf->beacon->queue->desc_size;
- skbdesc->entry = intf->beacon;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
- rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
-
- /*
- * mac80211 doesn't provide the control->queue variable
- * for beacons. Set our own queue identification so
- * it can be used during descriptor initialization.
- */
- control->queue = RT2X00_BCN_QUEUE_BEACON;
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
- /*
- * Write entire beacon with descriptor to register,
- * and kick the beacon generator.
- */
- beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
- rt2x00pci_register_multiwrite(rt2x00dev, beacon_base,
- skbdesc->desc, skbdesc->desc_len);
- rt2x00pci_register_multiwrite(rt2x00dev,
- beacon_base + skbdesc->desc_len,
- skbdesc->data, skbdesc->data_len);
- rt61pci_kick_tx_queue(rt2x00dev, control->queue);
-
- return 0;
-}
-
static const struct ieee80211_ops rt61pci_mac80211_ops = {
.tx = rt2x00mac_tx,
.start = rt2x00mac_start,
@@ -2446,7 +2405,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt61pci_get_tsf,
- .beacon_update = rt61pci_beacon_update,
};
static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -2466,6 +2424,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.link_tuner = rt61pci_link_tuner,
.write_tx_desc = rt61pci_write_tx_desc,
.write_tx_data = rt2x00pci_write_tx_data,
+ .write_beacon = rt61pci_write_beacon,
.kick_tx_queue = rt61pci_kick_tx_queue,
.fill_rxdone = rt61pci_fill_rxdone,
.config_filter = rt61pci_config_filter,
@@ -2478,21 +2437,21 @@ static const struct data_queue_desc rt61pci_queue_rx = {
.entry_num = RX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_rx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt61pci_queue_tx = {
.entry_num = TX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct data_queue_desc rt61pci_queue_bcn = {
.entry_num = 4 * BEACON_ENTRIES,
.data_size = 0, /* No DMA required for beacons */
.desc_size = TXINFO_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_pci_tx),
+ .priv_size = sizeof(struct queue_entry_priv_pci),
};
static const struct rt2x00_ops rt61pci_ops = {
@@ -2501,6 +2460,7 @@ static const struct rt2x00_ops rt61pci_ops = {
.max_ap_intf = 4,
.eeprom_size = EEPROM_SIZE,
.rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
.rx = &rt61pci_queue_rx,
.tx = &rt61pci_queue_tx,
.bcn = &rt61pci_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 3511bba7ff6..1004d5b899e 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -39,8 +39,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
@@ -54,6 +52,11 @@
#define RF_SIZE 0x0014
/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 4
+
+/*
* PCI registers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 6a62d6bb96f..d383735ab8f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -74,10 +74,10 @@ static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u32 length)
{
- int timeout = REGISTER_TIMEOUT * (length / sizeof(u32));
rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
USB_VENDOR_REQUEST_IN, offset,
- value, length, timeout);
+ value, length,
+ REGISTER_TIMEOUT32(length));
}
static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev,
@@ -102,10 +102,10 @@ static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
const unsigned int offset,
void *value, const u32 length)
{
- int timeout = REGISTER_TIMEOUT * (length / sizeof(u32));
rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
USB_VENDOR_REQUEST_OUT, offset,
- value, length, timeout);
+ value, length,
+ REGISTER_TIMEOUT32(length));
}
static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev)
@@ -341,6 +341,17 @@ static int rt73usb_blink_set(struct led_classdev *led_cdev,
return 0;
}
+
+static void rt73usb_init_led(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00_led *led,
+ enum led_type type)
+{
+ led->rt2x00dev = rt2x00dev;
+ led->type = type;
+ led->led_dev.brightness_set = rt73usb_brightness_set;
+ led->led_dev.blink_set = rt73usb_blink_set;
+ led->flags = LED_INITIALIZED;
+}
#endif /* CONFIG_RT73USB_LEDS */
/*
@@ -882,7 +893,6 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
const char *ptr = data;
char *cache;
int buflen;
- int timeout;
/*
* Wait for stable hardware.
@@ -913,14 +923,14 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) {
buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE);
- timeout = REGISTER_TIMEOUT * (buflen / sizeof(u32));
memcpy(cache, ptr, buflen);
rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
USB_VENDOR_REQUEST_OUT,
FIRMWARE_IMAGE_BASE + i, 0,
- cache, buflen, timeout);
+ cache, buflen,
+ REGISTER_TIMEOUT32(buflen));
ptr += buflen;
}
@@ -1100,25 +1110,32 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
-static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
- u16 eeprom;
- u8 reg_id;
u8 value;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt73usb_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
- goto continue_csr_init;
- NOTICE(rt2x00dev, "Waiting for BBP register.\n");
+ return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
+}
+
+static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+ unsigned int i;
+ u16 eeprom;
+ u8 reg_id;
+ u8 value;
+
+ if (unlikely(rt73usb_wait_bbp_ready(rt2x00dev)))
+ return -EACCES;
-continue_csr_init:
rt73usb_bbp_write(rt2x00dev, 3, 0x80);
rt73usb_bbp_write(rt2x00dev, 15, 0x30);
rt73usb_bbp_write(rt2x00dev, 21, 0xc8);
@@ -1168,7 +1185,8 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DISABLE_RX,
- state == STATE_RADIO_RX_OFF);
+ (state == STATE_RADIO_RX_OFF) ||
+ (state == STATE_RADIO_RX_OFF_LINK));
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
}
@@ -1177,11 +1195,9 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all registers.
*/
- if (rt73usb_init_registers(rt2x00dev) ||
- rt73usb_init_bbp(rt2x00dev)) {
- ERROR(rt2x00dev, "Register initialization failed.\n");
+ if (unlikely(rt73usb_init_registers(rt2x00dev) ||
+ rt73usb_init_bbp(rt2x00dev)))
return -EIO;
- }
return 0;
}
@@ -1203,7 +1219,6 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
u32 reg;
unsigned int i;
char put_to_sleep;
- char current_state;
put_to_sleep = (state != STATE_AWAKE);
@@ -1219,16 +1234,12 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
*/
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt73usb_register_read(rt2x00dev, MAC_CSR12, &reg);
- current_state =
- rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
- if (current_state == !put_to_sleep)
+ state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
+ if (state == !put_to_sleep)
return 0;
msleep(10);
}
- NOTICE(rt2x00dev, "Device failed to enter state %d, "
- "current device state %d.\n", !put_to_sleep, current_state);
-
return -EBUSY;
}
@@ -1246,11 +1257,13 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
case STATE_RADIO_RX_ON:
case STATE_RADIO_RX_ON_LINK:
- rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
- break;
case STATE_RADIO_RX_OFF:
case STATE_RADIO_RX_OFF_LINK:
- rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+ rt73usb_toggle_rx(rt2x00dev, state);
+ break;
+ case STATE_RADIO_IRQ_ON:
+ case STATE_RADIO_IRQ_OFF:
+ /* No support, but no error either */
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
@@ -1263,6 +1276,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
}
+ if (unlikely(retval))
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+ state, retval);
+
return retval;
}
@@ -1271,8 +1288,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
- struct txentry_desc *txdesc,
- struct ieee80211_tx_control *control)
+ struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = skbdesc->desc;
@@ -1317,16 +1333,59 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
- !!(control->flags &
- IEEE80211_TXCTL_LONG_RETRY_LIMIT));
+ test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT,
+ skb->len - skbdesc->desc_len);
rt2x00_set_field32(&word, TXD_W0_BURST2,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
rt2x00_desc_write(txd, 0, word);
}
+/*
+ * TX data initialization
+ */
+static void rt73usb_write_beacon(struct queue_entry *entry)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+ unsigned int beacon_base;
+ u32 reg;
+
+ /*
+ * Add the descriptor in front of the skb.
+ */
+ skb_push(entry->skb, entry->queue->desc_size);
+ memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
+ skbdesc->desc = entry->skb->data;
+
+ /*
+ * Disable beaconing while we are reloading the beacon data,
+ * otherwise we might be sending out invalid data.
+ */
+ rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+ rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+ rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
+ /*
+ * Write entire beacon with descriptor to register.
+ */
+ beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+ rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
+ USB_VENDOR_REQUEST_OUT, beacon_base, 0,
+ entry->skb->data, entry->skb->len,
+ REGISTER_TIMEOUT32(entry->skb->len));
+
+ /*
+ * Clean up the beacon skb.
+ */
+ dev_kfree_skb(entry->skb);
+ entry->skb = NULL;
+}
+
static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb)
{
@@ -1342,16 +1401,15 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev,
return length;
}
-/*
- * TX data initialization
- */
static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
- const unsigned int queue)
+ const enum data_queue_qid queue)
{
u32 reg;
- if (queue != RT2X00_BCN_QUEUE_BEACON)
+ if (queue != QID_BEACON) {
+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);
return;
+ }
/*
* For Wi-Fi faily generated beacons between participating stations.
@@ -1421,25 +1479,22 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
__le32 *rxd = (__le32 *)entry->skb->data;
- unsigned int offset = entry->queue->desc_size + 2;
u32 word0;
u32 word1;
/*
- * Copy descriptor to the available headroom inside the skbuffer.
+ * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of
+ * frame data in rt2x00usb.
*/
- skb_push(entry->skb, offset);
- memcpy(entry->skb->data, rxd, entry->queue->desc_size);
- rxd = (__le32 *)entry->skb->data;
+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
+ rxd = (__le32 *)skbdesc->desc;
/*
- * The descriptor is now aligned to 4 bytes and thus it is
- * now safe to read it on all architectures.
+ * It is now safe to read the descriptor on all architectures.
*/
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
- rxdesc->flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
@@ -1453,25 +1508,16 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1);
rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- rxdesc->dev_flags = 0;
if (rt2x00_get_field32(word0, RXD_W0_OFDM))
rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP;
if (rt2x00_get_field32(word0, RXD_W0_MY_BSS))
rxdesc->dev_flags |= RXDONE_MY_BSS;
/*
- * Adjust the skb memory window to the frame boundaries.
+ * Set skb pointers, and update frame information.
*/
- skb_pull(entry->skb, offset + entry->queue->desc_size);
+ skb_pull(entry->skb, entry->queue->desc_size);
skb_trim(entry->skb, rxdesc->size);
-
- /*
- * Set descriptor and data pointer.
- */
- skbdesc->data = entry->skb->data;
- skbdesc->data_len = rxdesc->size;
- skbdesc->desc = rxd;
- skbdesc->desc_len = entry->queue->desc_size;
}
/*
@@ -1644,31 +1690,11 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_RT73USB_LEDS
rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);
- rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
- rt2x00dev->led_radio.type = LED_TYPE_RADIO;
- rt2x00dev->led_radio.led_dev.brightness_set =
- rt73usb_brightness_set;
- rt2x00dev->led_radio.led_dev.blink_set =
- rt73usb_blink_set;
- rt2x00dev->led_radio.flags = LED_INITIALIZED;
-
- rt2x00dev->led_assoc.rt2x00dev = rt2x00dev;
- rt2x00dev->led_assoc.type = LED_TYPE_ASSOC;
- rt2x00dev->led_assoc.led_dev.brightness_set =
- rt73usb_brightness_set;
- rt2x00dev->led_assoc.led_dev.blink_set =
- rt73usb_blink_set;
- rt2x00dev->led_assoc.flags = LED_INITIALIZED;
-
- if (value == LED_MODE_SIGNAL_STRENGTH) {
- rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
- rt2x00dev->led_qual.type = LED_TYPE_QUALITY;
- rt2x00dev->led_qual.led_dev.brightness_set =
- rt73usb_brightness_set;
- rt2x00dev->led_qual.led_dev.blink_set =
- rt73usb_blink_set;
- rt2x00dev->led_qual.flags = LED_INITIALIZED;
- }
+ rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+ rt73usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+ if (value == LED_MODE_SIGNAL_STRENGTH)
+ rt73usb_init_led(rt2x00dev, &rt2x00dev->led_qual,
+ LED_TYPE_QUALITY);
rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);
rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0,
@@ -1846,13 +1872,11 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
- rt2x00dev->hw->max_signal = MAX_SIGNAL;
- rt2x00dev->hw->max_rssi = MAX_RX_SSI;
- rt2x00dev->hw->queues = 4;
- SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev);
+ SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
rt2x00_eeprom_addr(rt2x00dev,
EEPROM_MAC_ADDR_0));
@@ -1974,69 +1998,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
#define rt73usb_get_tsf NULL
#endif
-static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
- struct rt2x00_intf *intf = vif_to_intf(control->vif);
- struct skb_frame_desc *skbdesc;
- unsigned int beacon_base;
- unsigned int timeout;
- u32 reg;
-
- if (unlikely(!intf->beacon))
- return -ENOBUFS;
-
- /*
- * Add the descriptor in front of the skb.
- */
- skb_push(skb, intf->beacon->queue->desc_size);
- memset(skb->data, 0, intf->beacon->queue->desc_size);
-
- /*
- * Fill in skb descriptor
- */
- skbdesc = get_skb_frame_desc(skb);
- memset(skbdesc, 0, sizeof(*skbdesc));
- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
- skbdesc->data = skb->data + intf->beacon->queue->desc_size;
- skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;
- skbdesc->desc = skb->data;
- skbdesc->desc_len = intf->beacon->queue->desc_size;
- skbdesc->entry = intf->beacon;
-
- /*
- * Disable beaconing while we are reloading the beacon data,
- * otherwise we might be sending out invalid data.
- */
- rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
- rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
- rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
- rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
- rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-
- /*
- * mac80211 doesn't provide the control->queue variable
- * for beacons. Set our own queue identification so
- * it can be used during descriptor initialization.
- */
- control->queue = RT2X00_BCN_QUEUE_BEACON;
- rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
-
- /*
- * Write entire beacon with descriptor to register,
- * and kick the beacon generator.
- */
- beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
- timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32));
- rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
- USB_VENDOR_REQUEST_OUT, beacon_base, 0,
- skb->data, skb->len, timeout);
- rt73usb_kick_tx_queue(rt2x00dev, control->queue);
-
- return 0;
-}
-
static const struct ieee80211_ops rt73usb_mac80211_ops = {
.tx = rt2x00mac_tx,
.start = rt2x00mac_start,
@@ -2052,7 +2013,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
.get_tsf = rt73usb_get_tsf,
- .beacon_update = rt73usb_beacon_update,
};
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2070,6 +2030,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.link_tuner = rt73usb_link_tuner,
.write_tx_desc = rt73usb_write_tx_desc,
.write_tx_data = rt2x00usb_write_tx_data,
+ .write_beacon = rt73usb_write_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
.kick_tx_queue = rt73usb_kick_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
@@ -2083,21 +2044,21 @@ static const struct data_queue_desc rt73usb_queue_rx = {
.entry_num = RX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = RXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_usb_rx),
+ .priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_tx = {
.entry_num = TX_ENTRIES,
.data_size = DATA_FRAME_SIZE,
.desc_size = TXD_DESC_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_usb_tx),
+ .priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct data_queue_desc rt73usb_queue_bcn = {
.entry_num = 4 * BEACON_ENTRIES,
.data_size = MGMT_FRAME_SIZE,
.desc_size = TXINFO_SIZE,
- .priv_size = sizeof(struct queue_entry_priv_usb_tx),
+ .priv_size = sizeof(struct queue_entry_priv_usb),
};
static const struct rt2x00_ops rt73usb_ops = {
@@ -2106,6 +2067,7 @@ static const struct rt2x00_ops rt73usb_ops = {
.max_ap_intf = 4,
.eeprom_size = EEPROM_SIZE,
.rf_size = RF_SIZE,
+ .tx_queues = NUM_TX_QUEUES,
.rx = &rt73usb_queue_rx,
.tx = &rt73usb_queue_tx,
.bcn = &rt73usb_queue_bcn,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 06d687425fe..14849350101 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -39,8 +39,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
-#define MAX_SIGNAL 100
-#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
@@ -54,6 +52,11 @@
#define RF_SIZE 0x0014
/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES 4
+
+/*
* USB registers.
*/
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index c181f23e930..b7172a12c05 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -132,8 +132,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
rx_status.antenna = (flags2 >> 15) & 1;
/* TODO: improve signal/rssi reporting */
- rx_status.signal = flags2 & 0xFF;
- rx_status.ssi = (flags2 >> 8) & 0x7F;
+ rx_status.qual = flags2 & 0xFF;
+ rx_status.signal = (flags2 >> 8) & 0x7F;
/* XXX: is this correct? */
rx_status.rate_idx = (flags >> 20) & 0xF;
rx_status.freq = dev->conf.channel->center_freq;
@@ -170,34 +170,29 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
while (skb_queue_len(&ring->queue)) {
struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
struct sk_buff *skb;
- struct ieee80211_tx_status status;
- struct ieee80211_tx_control *control;
+ struct ieee80211_tx_info *info;
u32 flags = le32_to_cpu(entry->flags);
if (flags & RTL8180_TX_DESC_FLAG_OWN)
return;
- memset(&status, 0, sizeof(status));
-
ring->idx = (ring->idx + 1) % ring->entries;
skb = __skb_dequeue(&ring->queue);
pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
skb->len, PCI_DMA_TODEVICE);
- control = *((struct ieee80211_tx_control **)skb->cb);
- if (control)
- memcpy(&status.control, control, sizeof(*control));
- kfree(control);
+ info = IEEE80211_SKB_CB(skb);
+ memset(&info->status, 0, sizeof(info->status));
- if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+ if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
if (flags & RTL8180_TX_DESC_FLAG_TX_OK)
- status.flags = IEEE80211_TX_STATUS_ACK;
+ info->flags |= IEEE80211_TX_STAT_ACK;
else
- status.excessive_retries = 1;
+ info->status.excessive_retries = 1;
}
- status.retry_count = flags & 0xFF;
+ info->status.retry_count = flags & 0xFF;
- ieee80211_tx_status_irqsafe(dev, skb, &status);
+ ieee80211_tx_status_irqsafe(dev, skb);
if (ring->entries - skb_queue_len(&ring->queue) == 2)
ieee80211_wake_queue(dev, prio);
}
@@ -238,9 +233,9 @@ static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct rtl8180_priv *priv = dev->priv;
struct rtl8180_tx_ring *ring;
struct rtl8180_tx_desc *entry;
@@ -251,46 +246,40 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
u16 plcp_len = 0;
__le16 rts_duration = 0;
- prio = control->queue;
+ prio = skb_get_queue_mapping(skb);
ring = &priv->tx_ring[prio];
mapping = pci_map_single(priv->pdev, skb->data,
skb->len, PCI_DMA_TODEVICE);
- BUG_ON(!control->tx_rate);
-
tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
RTL8180_TX_DESC_FLAG_LS |
- (control->tx_rate->hw_value << 24) | skb->len;
+ (ieee80211_get_tx_rate(dev, info)->hw_value << 24) |
+ skb->len;
if (priv->r8185)
tx_flags |= RTL8180_TX_DESC_FLAG_DMA |
RTL8180_TX_DESC_FLAG_NO_ENC;
- if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- BUG_ON(!control->rts_cts_rate);
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
tx_flags |= RTL8180_TX_DESC_FLAG_RTS;
- tx_flags |= control->rts_cts_rate->hw_value << 19;
- } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
- BUG_ON(!control->rts_cts_rate);
+ tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
+ } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
tx_flags |= RTL8180_TX_DESC_FLAG_CTS;
- tx_flags |= control->rts_cts_rate->hw_value << 19;
+ tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
}
- *((struct ieee80211_tx_control **) skb->cb) =
- kmemdup(control, sizeof(*control), GFP_ATOMIC);
-
- if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len,
- control);
+ info);
if (!priv->r8185) {
unsigned int remainder;
plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
- (control->tx_rate->bitrate * 2) / 10);
+ (ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
remainder = (16 * (skb->len + 4)) %
- ((control->tx_rate->bitrate * 2) / 10);
+ ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
if (remainder > 0 && remainder <= 6)
plcp_len |= 1 << 15;
}
@@ -303,13 +292,13 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
entry->plcp_len = cpu_to_le16(plcp_len);
entry->tx_buf = cpu_to_le32(mapping);
entry->frame_len = cpu_to_le32(skb->len);
- entry->flags2 = control->alt_retry_rate != NULL ?
- control->alt_retry_rate->bitrate << 4 : 0;
- entry->retry_limit = control->retry_limit;
+ entry->flags2 = info->control.alt_retry_rate_idx >= 0 ?
+ ieee80211_get_alt_retry_rate(dev, info)->bitrate << 4 : 0;
+ entry->retry_limit = info->control.retry_limit;
entry->flags = cpu_to_le32(tx_flags);
__skb_queue_tail(&ring->queue, skb);
if (ring->entries - skb_queue_len(&ring->queue) < 2)
- ieee80211_stop_queue(dev, control->queue);
+ ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
spin_unlock_irqrestore(&priv->lock, flags);
rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
@@ -525,7 +514,6 @@ static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio)
pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
skb->len, PCI_DMA_TODEVICE);
- kfree(*((struct ieee80211_tx_control **) skb->cb));
kfree_skb(skb);
ring->idx = (ring->idx + 1) % ring->entries;
}
@@ -894,9 +882,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_RX_INCLUDES_FCS;
+ IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_UNSPEC;
dev->queues = 1;
- dev->max_rssi = 65;
+ dev->max_signal = 65;
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
reg &= RTL818X_TX_CONF_HWVER_MASK;
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index 076d88b6db0..3afb49f8866 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -44,23 +44,48 @@ struct rtl8187_rx_hdr {
__le64 mac_time;
} __attribute__((packed));
-struct rtl8187_tx_info {
- struct ieee80211_tx_control *control;
- struct urb *urb;
- struct ieee80211_hw *dev;
-};
-
-struct rtl8187_tx_hdr {
+struct rtl8187b_rx_hdr {
__le32 flags;
+ __le64 mac_time;
+ u8 noise;
+ u8 signal;
+ u8 agc;
+ u8 reserved;
+ __le32 unused;
+} __attribute__((packed));
+
+/* {rtl8187,rtl8187b}_tx_info is in skb */
+
+/* Tx flags are common between rtl8187 and rtl8187b */
#define RTL8187_TX_FLAG_NO_ENCRYPT (1 << 15)
#define RTL8187_TX_FLAG_MORE_FRAG (1 << 17)
#define RTL8187_TX_FLAG_CTS (1 << 18)
#define RTL8187_TX_FLAG_RTS (1 << 23)
+
+struct rtl8187_tx_hdr {
+ __le32 flags;
+ __le16 rts_duration;
+ __le16 len;
+ __le32 retry;
+} __attribute__((packed));
+
+struct rtl8187b_tx_hdr {
+ __le32 flags;
__le16 rts_duration;
__le16 len;
+ __le32 unused_1;
+ __le16 unused_2;
+ __le16 tx_duration;
+ __le32 unused_3;
__le32 retry;
+ __le32 unused_4[2];
} __attribute__((packed));
+enum {
+ DEVICE_RTL8187,
+ DEVICE_RTL8187B
+};
+
struct rtl8187_priv {
/* common between rtl818x drivers */
struct rtl818x_csr *map;
@@ -76,70 +101,120 @@ struct rtl8187_priv {
u32 rx_conf;
u16 txpwr_base;
u8 asic_rev;
+ u8 is_rtl8187b;
+ enum {
+ RTL8187BvB,
+ RTL8187BvD,
+ RTL8187BvE
+ } hw_rev;
struct sk_buff_head rx_queue;
+ u8 signal;
+ u8 quality;
+ u8 noise;
};
void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
-static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
+static inline u8 rtl818x_ioread8_idx(struct rtl8187_priv *priv,
+ u8 *addr, u8 idx)
{
u8 val;
usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
- (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03, &val,
+ sizeof(val), HZ / 2);
return val;
}
-static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
+static inline u8 rtl818x_ioread8(struct rtl8187_priv *priv, u8 *addr)
+{
+ return rtl818x_ioread8_idx(priv, addr, 0);
+}
+
+static inline u16 rtl818x_ioread16_idx(struct rtl8187_priv *priv,
+ __le16 *addr, u8 idx)
{
__le16 val;
usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
- (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03, &val,
+ sizeof(val), HZ / 2);
return le16_to_cpu(val);
}
-static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
+static inline u16 rtl818x_ioread16(struct rtl8187_priv *priv, __le16 *addr)
+{
+ return rtl818x_ioread16_idx(priv, addr, 0);
+}
+
+static inline u32 rtl818x_ioread32_idx(struct rtl8187_priv *priv,
+ __le32 *addr, u8 idx)
{
__le32 val;
usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0),
RTL8187_REQ_GET_REG, RTL8187_REQT_READ,
- (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03, &val,
+ sizeof(val), HZ / 2);
return le32_to_cpu(val);
}
-static inline void rtl818x_iowrite8(struct rtl8187_priv *priv,
- u8 *addr, u8 val)
+static inline u32 rtl818x_ioread32(struct rtl8187_priv *priv, __le32 *addr)
+{
+ return rtl818x_ioread32_idx(priv, addr, 0);
+}
+
+static inline void rtl818x_iowrite8_idx(struct rtl8187_priv *priv,
+ u8 *addr, u8 val, u8 idx)
{
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- (unsigned long)addr, 0, &val, sizeof(val), HZ / 2);
+ (unsigned long)addr, idx & 0x03, &val,
+ sizeof(val), HZ / 2);
+}
+
+static inline void rtl818x_iowrite8(struct rtl8187_priv *priv, u8 *addr, u8 val)
+{
+ rtl818x_iowrite8_idx(priv, addr, val, 0);
}
-static inline void rtl818x_iowrite16(struct rtl8187_priv *priv,
- __le16 *addr, u16 val)
+static inline void rtl818x_iowrite16_idx(struct rtl8187_priv *priv,
+ __le16 *addr, u16 val, u8 idx)
{
__le16 buf = cpu_to_le16(val);
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
+ (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
+ HZ / 2);
}
-static inline void rtl818x_iowrite32(struct rtl8187_priv *priv,
- __le32 *addr, u32 val)
+static inline void rtl818x_iowrite16(struct rtl8187_priv *priv, __le16 *addr,
+ u16 val)
+{
+ rtl818x_iowrite16_idx(priv, addr, val, 0);
+}
+
+static inline void rtl818x_iowrite32_idx(struct rtl8187_priv *priv,
+ __le32 *addr, u32 val, u8 idx)
{
__le32 buf = cpu_to_le32(val);
usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0),
RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE,
- (unsigned long)addr, 0, &buf, sizeof(buf), HZ / 2);
+ (unsigned long)addr, idx & 0x03, &buf, sizeof(buf),
+ HZ / 2);
+}
+
+static inline void rtl818x_iowrite32(struct rtl8187_priv *priv, __le32 *addr,
+ u32 val)
+{
+ rtl818x_iowrite32_idx(priv, addr, val, 0);
}
#endif /* RTL8187_H */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 9223ada5f00..d3067b1216c 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -27,19 +27,21 @@
MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
-MODULE_DESCRIPTION("RTL8187 USB wireless driver");
+MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
MODULE_LICENSE("GPL");
static struct usb_device_id rtl8187_table[] __devinitdata = {
/* Realtek */
- {USB_DEVICE(0x0bda, 0x8187)},
+ {USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
+ {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
+ {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
/* Netgear */
- {USB_DEVICE(0x0846, 0x6100)},
- {USB_DEVICE(0x0846, 0x6a00)},
+ {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
+ {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
/* HP */
- {USB_DEVICE(0x03f0, 0xca02)},
+ {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
/* Sitecom */
- {USB_DEVICE(0x0df6, 0x000d)},
+ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
{}
};
@@ -150,27 +152,25 @@ void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
static void rtl8187_tx_cb(struct urb *urb)
{
- struct ieee80211_tx_status status;
struct sk_buff *skb = (struct sk_buff *)urb->context;
- struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb;
-
- memset(&status, 0, sizeof(status));
-
- usb_free_urb(info->urb);
- if (info->control)
- memcpy(&status.control, info->control, sizeof(status.control));
- kfree(info->control);
- skb_pull(skb, sizeof(struct rtl8187_tx_hdr));
- status.flags |= IEEE80211_TX_STATUS_ACK;
- ieee80211_tx_status_irqsafe(info->dev, skb, &status);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hw *hw = info->driver_data[0];
+ struct rtl8187_priv *priv = hw->priv;
+
+ usb_free_urb(info->driver_data[1]);
+ skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
+ sizeof(struct rtl8187_tx_hdr));
+ memset(&info->status, 0, sizeof(info->status));
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ ieee80211_tx_status_irqsafe(hw, skb);
}
-static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct rtl8187_priv *priv = dev->priv;
- struct rtl8187_tx_hdr *hdr;
- struct rtl8187_tx_info *info;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ unsigned int ep;
+ void *buf;
struct urb *urb;
__le16 rts_dur = 0;
u32 flags;
@@ -185,35 +185,60 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
flags = skb->len;
flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
- BUG_ON(!control->tx_rate);
-
- flags |= control->tx_rate->hw_value << 24;
- if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
+ flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
+ if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))
flags |= RTL8187_TX_FLAG_MORE_FRAG;
- if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- BUG_ON(!control->rts_cts_rate);
+ if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
flags |= RTL8187_TX_FLAG_RTS;
- flags |= control->rts_cts_rate->hw_value << 19;
+ flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
rts_dur = ieee80211_rts_duration(dev, priv->vif,
- skb->len, control);
- } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
- BUG_ON(!control->rts_cts_rate);
+ skb->len, info);
+ } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
flags |= RTL8187_TX_FLAG_CTS;
- flags |= control->rts_cts_rate->hw_value << 19;
+ flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
}
- hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
- hdr->flags = cpu_to_le32(flags);
- hdr->len = 0;
- hdr->rts_duration = rts_dur;
- hdr->retry = cpu_to_le32(control->retry_limit << 8);
+ if (!priv->is_rtl8187b) {
+ struct rtl8187_tx_hdr *hdr =
+ (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
+ hdr->flags = cpu_to_le32(flags);
+ hdr->len = 0;
+ hdr->rts_duration = rts_dur;
+ hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
+ buf = hdr;
- info = (struct rtl8187_tx_info *)skb->cb;
- info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
- info->urb = urb;
- info->dev = dev;
- usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, 2),
- hdr, skb->len, rtl8187_tx_cb, skb);
+ ep = 2;
+ } else {
+ /* fc needs to be calculated before skb_push() */
+ unsigned int epmap[4] = { 6, 7, 5, 4 };
+ struct ieee80211_hdr *tx_hdr =
+ (struct ieee80211_hdr *)(skb->data);
+ u16 fc = le16_to_cpu(tx_hdr->frame_control);
+
+ struct rtl8187b_tx_hdr *hdr =
+ (struct rtl8187b_tx_hdr *)skb_push(skb, sizeof(*hdr));
+ struct ieee80211_rate *txrate =
+ ieee80211_get_tx_rate(dev, info);
+ memset(hdr, 0, sizeof(*hdr));
+ hdr->flags = cpu_to_le32(flags);
+ hdr->rts_duration = rts_dur;
+ hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
+ hdr->tx_duration =
+ ieee80211_generic_frame_duration(dev, priv->vif,
+ skb->len, txrate);
+ buf = hdr;
+
+ if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
+ ep = 12;
+ else
+ ep = epmap[skb_get_queue_mapping(skb)];
+ }
+
+ info->driver_data[0] = dev;
+ info->driver_data[1] = urb;
+
+ usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
+ buf, skb->len, rtl8187_tx_cb, skb);
rc = usb_submit_urb(urb, GFP_ATOMIC);
if (rc < 0) {
usb_free_urb(urb);
@@ -229,7 +254,6 @@ static void rtl8187_rx_cb(struct urb *urb)
struct rtl8187_rx_info *info = (struct rtl8187_rx_info *)skb->cb;
struct ieee80211_hw *dev = info->dev;
struct rtl8187_priv *priv = dev->priv;
- struct rtl8187_rx_hdr *hdr;
struct ieee80211_rx_status rx_status = { 0 };
int rate, signal;
u32 flags;
@@ -250,11 +274,33 @@ static void rtl8187_rx_cb(struct urb *urb)
}
skb_put(skb, urb->actual_length);
- hdr = (struct rtl8187_rx_hdr *)(skb_tail_pointer(skb) - sizeof(*hdr));
- flags = le32_to_cpu(hdr->flags);
- skb_trim(skb, flags & 0x0FFF);
+ if (!priv->is_rtl8187b) {
+ struct rtl8187_rx_hdr *hdr =
+ (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
+ flags = le32_to_cpu(hdr->flags);
+ signal = hdr->signal & 0x7f;
+ rx_status.antenna = (hdr->signal >> 7) & 1;
+ rx_status.signal = signal;
+ rx_status.noise = hdr->noise;
+ rx_status.mactime = le64_to_cpu(hdr->mac_time);
+ priv->signal = signal;
+ priv->quality = signal;
+ priv->noise = hdr->noise;
+ } else {
+ struct rtl8187b_rx_hdr *hdr =
+ (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));
+ flags = le32_to_cpu(hdr->flags);
+ signal = hdr->agc >> 1;
+ rx_status.antenna = (hdr->signal >> 7) & 1;
+ rx_status.signal = 64 - min(hdr->noise, (u8)64);
+ rx_status.noise = hdr->noise;
+ rx_status.mactime = le64_to_cpu(hdr->mac_time);
+ priv->signal = hdr->signal;
+ priv->quality = hdr->agc >> 1;
+ priv->noise = hdr->noise;
+ }
- signal = hdr->agc >> 1;
+ skb_trim(skb, flags & 0x0FFF);
rate = (flags >> 20) & 0xF;
if (rate > 3) { /* OFDM rate */
if (signal > 90)
@@ -270,13 +316,11 @@ static void rtl8187_rx_cb(struct urb *urb)
signal = 95 - signal;
}
- rx_status.antenna = (hdr->signal >> 7) & 1;
- rx_status.signal = 64 - min(hdr->noise, (u8)64);
- rx_status.ssi = signal;
+ rx_status.qual = priv->quality;
+ rx_status.signal = signal;
rx_status.rate_idx = rate;
rx_status.freq = dev->conf.channel->center_freq;
rx_status.band = dev->conf.channel->band;
- rx_status.mactime = le64_to_cpu(hdr->mac_time);
rx_status.flag |= RX_FLAG_TSFT;
if (flags & (1 << 13))
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -316,7 +360,8 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
break;
}
usb_fill_bulk_urb(entry, priv->udev,
- usb_rcvbulkpipe(priv->udev, 1),
+ usb_rcvbulkpipe(priv->udev,
+ priv->is_rtl8187b ? 3 : 1),
skb_tail_pointer(skb),
RTL8187_MAX_RX, rtl8187_rx_cb, skb);
info = (struct rtl8187_rx_info *)skb->cb;
@@ -329,29 +374,12 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
return 0;
}
-static int rtl8187_init_hw(struct ieee80211_hw *dev)
+static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
u8 reg;
int i;
- /* reset */
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
- reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
-
- rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
-
- msleep(200);
- rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
- rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
- rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
- msleep(200);
-
reg = rtl818x_ioread8(priv, &priv->map->CMD);
reg &= (1 << 1);
reg |= RTL818X_CMD_RESET;
@@ -387,12 +415,52 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
return -ETIMEDOUT;
}
+ return 0;
+}
+
+static int rtl8187_init_hw(struct ieee80211_hw *dev)
+{
+ struct rtl8187_priv *priv = dev->priv;
+ u8 reg;
+ int res;
+
+ /* reset */
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg |
+ RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+ RTL8187_RTL8225_ANAPARAM_ON);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187_RTL8225_ANAPARAM2_ON);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg &
+ ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
+
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
+
+ msleep(200);
+ rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x10);
+ rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x11);
+ rtl818x_iowrite8(priv, (u8 *)0xFE18, 0x00);
+ msleep(200);
+
+ res = rtl8187_cmd_reset(dev);
+ if (res)
+ return res;
+
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_ON);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+ RTL8187_RTL8225_ANAPARAM_ON);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187_RTL8225_ANAPARAM2_ON);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
/* setup card */
@@ -437,9 +505,11 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
- rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
msleep(100);
@@ -456,16 +526,201 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
return 0;
}
+static const u8 rtl8187b_reg_table[][3] = {
+ {0xF0, 0x32, 0}, {0xF1, 0x32, 0}, {0xF2, 0x00, 0}, {0xF3, 0x00, 0},
+ {0xF4, 0x32, 0}, {0xF5, 0x43, 0}, {0xF6, 0x00, 0}, {0xF7, 0x00, 0},
+ {0xF8, 0x46, 0}, {0xF9, 0xA4, 0}, {0xFA, 0x00, 0}, {0xFB, 0x00, 0},
+ {0xFC, 0x96, 0}, {0xFD, 0xA4, 0}, {0xFE, 0x00, 0}, {0xFF, 0x00, 0},
+
+ {0x58, 0x4B, 1}, {0x59, 0x00, 1}, {0x5A, 0x4B, 1}, {0x5B, 0x00, 1},
+ {0x60, 0x4B, 1}, {0x61, 0x09, 1}, {0x62, 0x4B, 1}, {0x63, 0x09, 1},
+ {0xCE, 0x0F, 1}, {0xCF, 0x00, 1}, {0xE0, 0xFF, 1}, {0xE1, 0x0F, 1},
+ {0xE2, 0x00, 1}, {0xF0, 0x4E, 1}, {0xF1, 0x01, 1}, {0xF2, 0x02, 1},
+ {0xF3, 0x03, 1}, {0xF4, 0x04, 1}, {0xF5, 0x05, 1}, {0xF6, 0x06, 1},
+ {0xF7, 0x07, 1}, {0xF8, 0x08, 1},
+
+ {0x4E, 0x00, 2}, {0x0C, 0x04, 2}, {0x21, 0x61, 2}, {0x22, 0x68, 2},
+ {0x23, 0x6F, 2}, {0x24, 0x76, 2}, {0x25, 0x7D, 2}, {0x26, 0x84, 2},
+ {0x27, 0x8D, 2}, {0x4D, 0x08, 2}, {0x50, 0x05, 2}, {0x51, 0xF5, 2},
+ {0x52, 0x04, 2}, {0x53, 0xA0, 2}, {0x54, 0x1F, 2}, {0x55, 0x23, 2},
+ {0x56, 0x45, 2}, {0x57, 0x67, 2}, {0x58, 0x08, 2}, {0x59, 0x08, 2},
+ {0x5A, 0x08, 2}, {0x5B, 0x08, 2}, {0x60, 0x08, 2}, {0x61, 0x08, 2},
+ {0x62, 0x08, 2}, {0x63, 0x08, 2}, {0x64, 0xCF, 2}, {0x72, 0x56, 2},
+ {0x73, 0x9A, 2},
+
+ {0x34, 0xF0, 0}, {0x35, 0x0F, 0}, {0x5B, 0x40, 0}, {0x84, 0x88, 0},
+ {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
+ {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
+ {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
+ {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
+
+ {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
+ {0x8E, 0x08, 0}, {0x8F, 0x00, 0}
+};
+
+static int rtl8187b_init_hw(struct ieee80211_hw *dev)
+{
+ struct rtl8187_priv *priv = dev->priv;
+ int res, i;
+ u8 reg;
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
+
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ reg |= RTL818X_CONFIG3_ANAPARAM_WRITE | RTL818X_CONFIG3_GNT_SELECT;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187B_RTL8225_ANAPARAM2_ON);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+ RTL8187B_RTL8225_ANAPARAM_ON);
+ rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
+ RTL8187B_RTL8225_ANAPARAM3_ON);
+
+ rtl818x_iowrite8(priv, (u8 *)0xFF61, 0x10);
+ reg = rtl818x_ioread8(priv, (u8 *)0xFF62);
+ rtl818x_iowrite8(priv, (u8 *)0xFF62, reg & ~(1 << 5));
+ rtl818x_iowrite8(priv, (u8 *)0xFF62, reg | (1 << 5));
+
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ reg &= ~RTL818X_CONFIG3_ANAPARAM_WRITE;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
+
+ res = rtl8187_cmd_reset(dev);
+ if (res)
+ return res;
+
+ rtl818x_iowrite16(priv, (__le16 *)0xFF2D, 0x0FFF);
+ reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
+ reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
+ rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
+ reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
+ reg |= RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT |
+ RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
+ rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
+ reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
+ reg |= RTL818X_RATE_FALLBACK_ENABLE;
+ rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
+
+ rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
+ rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFFD4, 0xFFFF, 1);
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG1);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG1, (reg & 0x3F) | 0x80);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
+
+ rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
+ for (i = 0; i < ARRAY_SIZE(rtl8187b_reg_table); i++) {
+ rtl818x_iowrite8_idx(priv,
+ (u8 *)(uintptr_t)
+ (rtl8187b_reg_table[i][0] | 0xFF00),
+ rtl8187b_reg_table[i][1],
+ rtl8187b_reg_table[i][2]);
+ }
+
+ rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50);
+ rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0);
+
+ rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF0, 0, 1);
+ rtl818x_iowrite32_idx(priv, (__le32 *)0xFFF4, 0, 1);
+ rtl818x_iowrite8_idx(priv, (u8 *)0xFFF8, 0, 1);
+
+ rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00004001);
+
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x569A, 2);
+
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_CONFIG);
+ reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+ reg |= RTL818X_CONFIG3_ANAPARAM_WRITE;
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
+ RTL818X_EEPROM_CMD_NORMAL);
+
+ rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
+ rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
+ rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+ msleep(1100);
+
+ priv->rf->init(dev);
+
+ reg = RTL818X_CMD_TX_ENABLE | RTL818X_CMD_RX_ENABLE;
+ rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+ rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
+
+ rtl818x_iowrite8(priv, (u8 *)0xFE41, 0xF4);
+ rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x00);
+ rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
+ rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
+ rtl818x_iowrite8(priv, (u8 *)0xFE40, 0x0F);
+ rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x00);
+ rtl818x_iowrite8(priv, (u8 *)0xFE42, 0x01);
+
+ reg = rtl818x_ioread8(priv, (u8 *)0xFFDB);
+ rtl818x_iowrite8(priv, (u8 *)0xFFDB, reg | (1 << 2));
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF72, 0x59FA, 3);
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF74, 0x59D2, 3);
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF76, 0x59D2, 3);
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF78, 0x19FA, 3);
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7A, 0x19FA, 3);
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFF7C, 0x00D0, 3);
+ rtl818x_iowrite8(priv, (u8 *)0xFF61, 0);
+ rtl818x_iowrite8_idx(priv, (u8 *)0xFF80, 0x0F, 1);
+ rtl818x_iowrite8_idx(priv, (u8 *)0xFF83, 0x03, 1);
+ rtl818x_iowrite8(priv, (u8 *)0xFFDA, 0x10);
+ rtl818x_iowrite8_idx(priv, (u8 *)0xFF4D, 0x08, 2);
+
+ rtl818x_iowrite32(priv, &priv->map->HSSI_PARA, 0x0600321B);
+
+ rtl818x_iowrite16_idx(priv, (__le16 *)0xFFEC, 0x0800, 1);
+
+ return 0;
+}
+
static int rtl8187_start(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
u32 reg;
int ret;
- ret = rtl8187_init_hw(dev);
+ ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
+ rtl8187b_init_hw(dev);
if (ret)
return ret;
+ if (priv->is_rtl8187b) {
+ reg = RTL818X_RX_CONF_MGMT |
+ RTL818X_RX_CONF_DATA |
+ RTL818X_RX_CONF_BROADCAST |
+ RTL818X_RX_CONF_NICMAC |
+ RTL818X_RX_CONF_BSSID |
+ (7 << 13 /* RX FIFO threshold NONE */) |
+ (7 << 10 /* MAX RX DMA */) |
+ RTL818X_RX_CONF_RX_AUTORESETPHY |
+ RTL818X_RX_CONF_ONLYERLPKT |
+ RTL818X_RX_CONF_MULTICAST;
+ priv->rx_conf = reg;
+ rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
+
+ rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+ RTL818X_TX_CONF_HW_SEQNUM |
+ RTL818X_TX_CONF_DISREQQSIZE |
+ (7 << 8 /* short retry limit */) |
+ (7 << 0 /* long retry limit */) |
+ (7 << 21 /* MAX TX DMA */));
+ rtl8187_init_urbs(dev);
+ return 0;
+ }
+
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
@@ -592,18 +847,20 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
msleep(10);
rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
- rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
-
- if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
- rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
- rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
- rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
- rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
- } else {
- rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
- rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
- rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
- rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
+ if (!priv->is_rtl8187b) {
+ rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
+
+ if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
+ rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
+ rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
+ rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
+ rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
+ } else {
+ rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
+ rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
+ rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
+ rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
+ }
}
rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -619,14 +876,20 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
{
struct rtl8187_priv *priv = dev->priv;
int i;
+ u8 reg;
for (i = 0; i < ETH_ALEN; i++)
rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
- if (is_valid_ether_addr(conf->bssid))
- rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
- else
- rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
+ if (is_valid_ether_addr(conf->bssid)) {
+ reg = RTL818X_MSR_INFRA;
+ if (priv->is_rtl8187b)
+ reg |= RTL818X_MSR_ENEDCA;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+ } else {
+ reg = RTL818X_MSR_NO_LINK;
+ rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+ }
return 0;
}
@@ -713,6 +976,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
struct rtl8187_priv *priv;
struct eeprom_93cx6 eeprom;
struct ieee80211_channel *channel;
+ const char *chip_name;
u16 txpwr, reg;
int err, i;
DECLARE_MAC_BUF(mac);
@@ -724,6 +988,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
}
priv = dev->priv;
+ priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B);
SET_IEEE80211_DEV(dev, &intf->dev);
usb_set_intfdata(intf, dev);
@@ -750,11 +1015,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
priv->mode = IEEE80211_IF_TYPE_MNTR;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_RX_INCLUDES_FCS;
- dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr);
- dev->queues = 1;
- dev->max_rssi = 65;
- dev->max_signal = 64;
+ IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_UNSPEC;
+ dev->max_signal = 65;
eeprom.data = dev;
eeprom.register_read = rtl8187_eeprom_register_read;
@@ -788,12 +1051,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
(*channel++).hw_value = txpwr & 0xFF;
(*channel++).hw_value = txpwr >> 8;
}
- for (i = 0; i < 2; i++) {
- eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i,
- &txpwr);
- (*channel++).hw_value = txpwr & 0xFF;
- (*channel++).hw_value = txpwr >> 8;
- }
eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
&priv->txpwr_base);
@@ -807,7 +1064,90 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+ if (!priv->is_rtl8187b) {
+ u32 reg32;
+ reg32 = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+ reg32 &= RTL818X_TX_CONF_HWVER_MASK;
+ switch (reg32) {
+ case RTL818X_TX_CONF_R8187vD_B:
+ /* Some RTL8187B devices have a USB ID of 0x8187
+ * detect them here */
+ chip_name = "RTL8187BvB(early)";
+ priv->is_rtl8187b = 1;
+ priv->hw_rev = RTL8187BvB;
+ break;
+ case RTL818X_TX_CONF_R8187vD:
+ chip_name = "RTL8187vD";
+ break;
+ default:
+ chip_name = "RTL8187vB (default)";
+ }
+ } else {
+ /*
+ * Force USB request to write radio registers for 8187B, Realtek
+ * only uses it in their sources
+ */
+ /*if (priv->asic_rev == 0) {
+ printk(KERN_WARNING "rtl8187: Forcing use of USB "
+ "requests to write to radio registers\n");
+ priv->asic_rev = 1;
+ }*/
+ switch (rtl818x_ioread8(priv, (u8 *)0xFFE1)) {
+ case RTL818X_R8187B_B:
+ chip_name = "RTL8187BvB";
+ priv->hw_rev = RTL8187BvB;
+ break;
+ case RTL818X_R8187B_D:
+ chip_name = "RTL8187BvD";
+ priv->hw_rev = RTL8187BvD;
+ break;
+ case RTL818X_R8187B_E:
+ chip_name = "RTL8187BvE";
+ priv->hw_rev = RTL8187BvE;
+ break;
+ default:
+ chip_name = "RTL8187BvB (default)";
+ priv->hw_rev = RTL8187BvB;
+ }
+ }
+
+ if (!priv->is_rtl8187b) {
+ for (i = 0; i < 2; i++) {
+ eeprom_93cx6_read(&eeprom,
+ RTL8187_EEPROM_TXPWR_CHAN_6 + i,
+ &txpwr);
+ (*channel++).hw_value = txpwr & 0xFF;
+ (*channel++).hw_value = txpwr >> 8;
+ }
+ } else {
+ eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
+ &txpwr);
+ (*channel++).hw_value = txpwr & 0xFF;
+
+ eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
+ (*channel++).hw_value = txpwr & 0xFF;
+
+ eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
+ (*channel++).hw_value = txpwr & 0xFF;
+ (*channel++).hw_value = txpwr >> 8;
+ }
+
+ if (priv->is_rtl8187b)
+ printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "
+ "is EXPERIMENTAL, and could damage your\n"
+ " hardware, use at your own risk\n");
+ if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
+ printk(KERN_INFO "rtl8187: inconsistency between id with OEM"
+ " info!\n");
+
priv->rf = rtl8187_detect_rf(dev);
+ dev->extra_tx_headroom = (!priv->is_rtl8187b) ?
+ sizeof(struct rtl8187_tx_hdr) :
+ sizeof(struct rtl8187b_tx_hdr);
+ if (!priv->is_rtl8187b)
+ dev->queues = 1;
+ else
+ dev->queues = 4;
err = ieee80211_register_hw(dev);
if (err) {
@@ -815,9 +1155,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
goto err_free_dev;
}
- printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
+ printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
- priv->asic_rev, priv->rf->name);
+ chip_name, priv->asic_rev, priv->rf->name);
return 0;
@@ -847,7 +1187,7 @@ static struct usb_driver rtl8187_driver = {
.name = KBUILD_MODNAME,
.id_table = rtl8187_table,
.probe = rtl8187_probe,
- .disconnect = rtl8187_disconnect,
+ .disconnect = __devexit_p(rtl8187_disconnect),
};
static int __init rtl8187_init(void)
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index 9146387b4c5..1bae8990341 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -305,9 +305,12 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
/* anaparam2 on */
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187_RTL8225_ANAPARAM2_ON);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
rtl8225_write_phy_ofdm(dev, 2, 0x42);
@@ -471,12 +474,42 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[2]);
}
+static const u8 rtl8225z2_agc[] = {
+ 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x53, 0x51, 0x4f,
+ 0x4d, 0x4b, 0x49, 0x47, 0x45, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x39, 0x37,
+ 0x35, 0x33, 0x31, 0x2f, 0x2d, 0x2b, 0x29, 0x27, 0x25, 0x23, 0x21, 0x1f,
+ 0x1d, 0x1b, 0x19, 0x17, 0x15, 0x13, 0x11, 0x0f, 0x0d, 0x0b, 0x09, 0x07,
+ 0x05, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
+ 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28,
+ 0x28, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c, 0x2c, 0x2d,
+ 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30,
+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31
+};
+static const u8 rtl8225z2_ofdm[] = {
+ 0x10, 0x0d, 0x01, 0x00, 0x14, 0xfb, 0xfb, 0x60,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00,
+ 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xa8, 0x26,
+ 0x32, 0x33, 0x07, 0xa5, 0x6f, 0x55, 0xc8, 0xb3,
+ 0x0a, 0xe1, 0x2C, 0x8a, 0x86, 0x83, 0x34, 0x0f,
+ 0x4f, 0x24, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00,
+ 0xc0, 0xc1, 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e,
+ 0x6d, 0x3c, 0xfb, 0x07
+};
+
static const u8 rtl8225z2_tx_power_cck_ch14[] = {
- 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x2f, 0x29, 0x15, 0x00, 0x00, 0x00, 0x00
};
static const u8 rtl8225z2_tx_power_cck[] = {
- 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04,
+ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03,
+ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03,
+ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03
};
static const u8 rtl8225z2_tx_power_ofdm[] = {
@@ -526,9 +559,12 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
/* anaparam2 on */
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
- rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187_RTL8225_ANAPARAM2_ON);
+ rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+ reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
rtl8225_write_phy_ofdm(dev, 2, 0x42);
@@ -542,6 +578,85 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
msleep(1);
}
+static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
+{
+ struct rtl8187_priv *priv = dev->priv;
+ u8 cck_power, ofdm_power;
+ const u8 *tmp;
+ int i;
+
+ cck_power = priv->channels[channel - 1].hw_value & 0xF;
+ ofdm_power = priv->channels[channel - 1].hw_value >> 4;
+
+ if (cck_power > 15)
+ cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
+ else
+ cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
+ cck_power += priv->txpwr_base & 0xF;
+ cck_power = min(cck_power, (u8)35);
+
+ if (ofdm_power > 15)
+ ofdm_power = (priv->hw_rev == RTL8187BvB) ? 17 : 25;
+ else
+ ofdm_power += (priv->hw_rev == RTL8187BvB) ? 2 : 10;
+ ofdm_power += (priv->txpwr_base >> 4) & 0xF;
+ ofdm_power = min(ofdm_power, (u8)35);
+
+ if (channel == 14)
+ tmp = rtl8225z2_tx_power_cck_ch14;
+ else
+ tmp = rtl8225z2_tx_power_cck;
+
+ if (priv->hw_rev == RTL8187BvB) {
+ if (cck_power <= 6)
+ ; /* do nothing */
+ else if (cck_power <= 11)
+ tmp += 8;
+ else
+ tmp += 16;
+ } else {
+ if (cck_power <= 5)
+ ; /* do nothing */
+ else if (cck_power <= 11)
+ tmp += 8;
+ else if (cck_power <= 17)
+ tmp += 16;
+ else
+ tmp += 24;
+ }
+
+ for (i = 0; i < 8; i++)
+ rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
+
+ rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
+ rtl8225z2_tx_gain_cck_ofdm[cck_power]);
+ msleep(1);
+
+ rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
+ rtl8225z2_tx_gain_cck_ofdm[ofdm_power] << 1);
+ if (priv->hw_rev == RTL8187BvB) {
+ if (ofdm_power <= 11) {
+ rtl8225_write_phy_ofdm(dev, 0x87, 0x60);
+ rtl8225_write_phy_ofdm(dev, 0x89, 0x60);
+ } else {
+ rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
+ rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
+ }
+ } else {
+ if (ofdm_power <= 11) {
+ rtl8225_write_phy_ofdm(dev, 0x87, 0x5c);
+ rtl8225_write_phy_ofdm(dev, 0x89, 0x5c);
+ } else if (ofdm_power <= 17) {
+ rtl8225_write_phy_ofdm(dev, 0x87, 0x54);
+ rtl8225_write_phy_ofdm(dev, 0x89, 0x54);
+ } else {
+ rtl8225_write_phy_ofdm(dev, 0x87, 0x50);
+ rtl8225_write_phy_ofdm(dev, 0x89, 0x50);
+ }
+ }
+ msleep(1);
+}
+
static const u16 rtl8225z2_rxgain[] = {
0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
@@ -715,6 +830,81 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
}
+static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
+{
+ struct rtl8187_priv *priv = dev->priv;
+ int i;
+
+ rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
+ rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
+ rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+ rtl8225_write(dev, 0x3, 0x441); msleep(1);
+ rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
+ rtl8225_write(dev, 0x5, 0xC72); msleep(1);
+ rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
+ rtl8225_write(dev, 0x7, 0x82A); msleep(1);
+ rtl8225_write(dev, 0x8, 0x03F); msleep(1);
+ rtl8225_write(dev, 0x9, 0x335); msleep(1);
+ rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
+ rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
+ rtl8225_write(dev, 0xc, 0x850); msleep(1);
+ rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
+ rtl8225_write(dev, 0xe, 0x02B); msleep(1);
+ rtl8225_write(dev, 0xf, 0x114); msleep(1);
+
+ rtl8225_write(dev, 0x0, 0x1B7); msleep(1);
+
+ for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
+ rtl8225_write(dev, 0x1, i + 1); msleep(1);
+ rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); msleep(1);
+ }
+
+ rtl8225_write(dev, 0x3, 0x080); msleep(1);
+ rtl8225_write(dev, 0x5, 0x004); msleep(1);
+ rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
+ msleep(3000);
+
+ rtl8225_write(dev, 0x2, 0xC4D); msleep(1);
+ msleep(2000);
+
+ rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+ rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
+
+ rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
+ rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
+ rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
+
+ rtl8225_write_phy_ofdm(dev, 0x80, 0x12);
+ for (i = 0; i < ARRAY_SIZE(rtl8225z2_agc); i++) {
+ rtl8225_write_phy_ofdm(dev, 0xF, rtl8225z2_agc[i]);
+ rtl8225_write_phy_ofdm(dev, 0xE, 0x80 + i);
+ rtl8225_write_phy_ofdm(dev, 0xE, 0);
+ }
+ rtl8225_write_phy_ofdm(dev, 0x80, 0x10);
+
+ for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
+ rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
+
+ rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
+ rtl818x_iowrite8(priv, &priv->map->SLOT, 9);
+ rtl818x_iowrite8(priv, (u8 *)0xFFF0, 28);
+ rtl818x_iowrite8(priv, (u8 *)0xFFF4, 28);
+ rtl818x_iowrite8(priv, (u8 *)0xFFF8, 28);
+ rtl818x_iowrite8(priv, (u8 *)0xFFFC, 28);
+ rtl818x_iowrite8(priv, (u8 *)0xFF2D, 0x5B);
+ rtl818x_iowrite8(priv, (u8 *)0xFF79, 0x5B);
+ rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
+ rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
+ rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
+ rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
+ rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
+
+ rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
+ rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); msleep(1);
+ rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); msleep(1);
+ rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
+}
+
static void rtl8225_rf_stop(struct ieee80211_hw *dev)
{
u8 reg;
@@ -725,8 +915,19 @@ static void rtl8225_rf_stop(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
- rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
+ if (!priv->is_rtl8187b) {
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187_RTL8225_ANAPARAM2_OFF);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+ RTL8187_RTL8225_ANAPARAM_OFF);
+ } else {
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM2,
+ RTL8187B_RTL8225_ANAPARAM2_OFF);
+ rtl818x_iowrite32(priv, &priv->map->ANAPARAM,
+ RTL8187B_RTL8225_ANAPARAM_OFF);
+ rtl818x_iowrite8(priv, &priv->map->ANAPARAM3,
+ RTL8187B_RTL8225_ANAPARAM3_OFF);
+ }
rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
}
@@ -739,8 +940,10 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
if (priv->rf->init == rtl8225_rf_init)
rtl8225_rf_set_tx_power(dev, chan);
- else
+ else if (priv->rf->init == rtl8225z2_rf_init)
rtl8225z2_rf_set_tx_power(dev, chan);
+ else
+ rtl8225z2_b_rf_set_tx_power(dev, chan);
rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
msleep(10);
@@ -760,19 +963,30 @@ static const struct rtl818x_rf_ops rtl8225z2_ops = {
.set_chan = rtl8225_rf_set_channel
};
+static const struct rtl818x_rf_ops rtl8225z2_b_ops = {
+ .name = "rtl8225z2",
+ .init = rtl8225z2_b_rf_init,
+ .stop = rtl8225_rf_stop,
+ .set_chan = rtl8225_rf_set_channel
+};
+
const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
{
u16 reg8, reg9;
+ struct rtl8187_priv *priv = dev->priv;
- rtl8225_write(dev, 0, 0x1B7);
+ if (!priv->is_rtl8187b) {
+ rtl8225_write(dev, 0, 0x1B7);
- reg8 = rtl8225_read(dev, 8);
- reg9 = rtl8225_read(dev, 9);
+ reg8 = rtl8225_read(dev, 8);
+ reg9 = rtl8225_read(dev, 9);
- rtl8225_write(dev, 0, 0x0B7);
+ rtl8225_write(dev, 0, 0x0B7);
- if (reg8 != 0x588 || reg9 != 0x700)
- return &rtl8225_ops;
+ if (reg8 != 0x588 || reg9 != 0x700)
+ return &rtl8225_ops;
- return &rtl8225z2_ops;
+ return &rtl8225z2_ops;
+ } else
+ return &rtl8225z2_b_ops;
}
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl8187_rtl8225.h
index d39ed0295b6..20c5b6ead0f 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.h
+++ b/drivers/net/wireless/rtl8187_rtl8225.h
@@ -15,10 +15,17 @@
#ifndef RTL8187_RTL8225_H
#define RTL8187_RTL8225_H
-#define RTL8225_ANAPARAM_ON 0xa0000a59
-#define RTL8225_ANAPARAM2_ON 0x860c7312
-#define RTL8225_ANAPARAM_OFF 0xa00beb59
-#define RTL8225_ANAPARAM2_OFF 0x840dec11
+#define RTL8187_RTL8225_ANAPARAM_ON 0xa0000a59
+#define RTL8187_RTL8225_ANAPARAM2_ON 0x860c7312
+#define RTL8187_RTL8225_ANAPARAM_OFF 0xa00beb59
+#define RTL8187_RTL8225_ANAPARAM2_OFF 0x840dec11
+
+#define RTL8187B_RTL8225_ANAPARAM_ON 0x45090658
+#define RTL8187B_RTL8225_ANAPARAM2_ON 0x727f3f52
+#define RTL8187B_RTL8225_ANAPARAM3_ON 0x00
+#define RTL8187B_RTL8225_ANAPARAM_OFF 0x55480658
+#define RTL8187B_RTL8225_ANAPARAM2_OFF 0x72003f50
+#define RTL8187B_RTL8225_ANAPARAM3_OFF 0x00
const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *);
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h
index 4f7d38f506e..00900fe16fc 100644
--- a/drivers/net/wireless/rtl818x.h
+++ b/drivers/net/wireless/rtl818x.h
@@ -66,7 +66,10 @@ struct rtl818x_csr {
#define RTL818X_TX_CONF_R8180_F (3 << 25)
#define RTL818X_TX_CONF_R8185_ABC (4 << 25)
#define RTL818X_TX_CONF_R8185_D (5 << 25)
+#define RTL818X_TX_CONF_R8187vD (5 << 25)
+#define RTL818X_TX_CONF_R8187vD_B (6 << 25)
#define RTL818X_TX_CONF_HWVER_MASK (7 << 25)
+#define RTL818X_TX_CONF_DISREQQSIZE (1 << 28)
#define RTL818X_TX_CONF_PROBE_DTS (1 << 29)
#define RTL818X_TX_CONF_HW_SEQNUM (1 << 30)
#define RTL818X_TX_CONF_CW_MIN (1 << 31)
@@ -106,8 +109,11 @@ struct rtl818x_csr {
#define RTL818X_MSR_NO_LINK (0 << 2)
#define RTL818X_MSR_ADHOC (1 << 2)
#define RTL818X_MSR_INFRA (2 << 2)
+#define RTL818X_MSR_MASTER (3 << 2)
+#define RTL818X_MSR_ENEDCA (4 << 2)
u8 CONFIG3;
#define RTL818X_CONFIG3_ANAPARAM_WRITE (1 << 6)
+#define RTL818X_CONFIG3_GNT_SELECT (1 << 7)
u8 CONFIG4;
#define RTL818X_CONFIG4_POWEROFF (1 << 6)
#define RTL818X_CONFIG4_VCOOFF (1 << 7)
@@ -133,7 +139,9 @@ struct rtl818x_csr {
__le32 RF_TIMING;
u8 GP_ENABLE;
u8 GPIO;
- u8 reserved_12[10];
+ u8 reserved_12[2];
+ __le32 HSSI_PARA;
+ u8 reserved_13[4];
u8 TX_AGC_CTL;
#define RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT (1 << 0)
#define RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT (1 << 1)
@@ -141,29 +149,39 @@ struct rtl818x_csr {
u8 TX_GAIN_CCK;
u8 TX_GAIN_OFDM;
u8 TX_ANTENNA;
- u8 reserved_13[16];
+ u8 reserved_14[16];
u8 WPA_CONF;
- u8 reserved_14[3];
+ u8 reserved_15[3];
u8 SIFS;
u8 DIFS;
u8 SLOT;
- u8 reserved_15[5];
+ u8 reserved_16[5];
u8 CW_CONF;
#define RTL818X_CW_CONF_PERPACKET_CW_SHIFT (1 << 0)
#define RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT (1 << 1)
u8 CW_VAL;
u8 RATE_FALLBACK;
- u8 reserved_16[25];
+#define RTL818X_RATE_FALLBACK_ENABLE (1 << 7)
+ u8 ACM_CONTROL;
+ u8 reserved_17[24];
u8 CONFIG5;
u8 TX_DMA_POLLING;
- u8 reserved_17[2];
+ u8 reserved_18[2];
__le16 CWR;
u8 RETRY_CTR;
- u8 reserved_18[5];
+ u8 reserved_19[3];
+ __le16 INT_MIG;
+/* RTL818X_R8187B_*: magic numbers from ioregisters */
+#define RTL818X_R8187B_B 0
+#define RTL818X_R8187B_D 1
+#define RTL818X_R8187B_E 2
__le32 RDSAR;
- u8 reserved_19[12];
- __le16 FEMR;
+ __le16 TID_AC_MAP;
u8 reserved_20[4];
+ u8 ANAPARAM3;
+ u8 reserved_21[5];
+ __le16 FEMR;
+ u8 reserved_22[4];
__le16 TALLY_CNT;
u8 TALLY_SEL;
} __attribute__((packed));
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 883af891ebf..417e9e675fa 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2728,7 +2728,7 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
/************************************************************************/
/* Initialization */
-static struct tty_ldisc strip_ldisc = {
+static struct tty_ldisc_ops strip_ldisc = {
.magic = TTY_LDISC_MAGIC,
.name = "strip",
.owner = THIS_MODULE,
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 42a36b3f3ff..377141995e3 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1624,25 +1624,25 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = this->bss_set[i].ssid.el.len;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe,
this->bss_set[i].ssid.essid);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = this->bss_set[i].bss_type;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
}
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 78baa0f7926..b16ec6e5f0e 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = zd->rxdata[i+16];
iwe.u.data.flags = 1;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
+ cev = iwe_stream_add_point(info, cev, end_buf,
+ &iwe, zd->rxdata+i+18);
iwe.cmd = SIOCGIWMODE;
if (zd->rxdata[i+14]&0x01)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = zd->rxdata[i+0];
iwe.u.freq.e = 0;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.disabled = 0;
for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
- cev=iwe_stream_add_event(cev, end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
iwe.cmd = SIOCGIWENCODE;
@@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_device *dev,
iwe.u.data.flags = IW_ENCODE_ENABLED;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = zd->rxdata[i+4];
iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
iwe.u.qual.updated = 7;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
if (!enabled_save)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 694e95d35fd..fcc532bb6a7 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -224,36 +224,6 @@ out:
return r;
}
-/**
- * clear_tx_skb_control_block - clears the control block of tx skbuffs
- * @skb: a &struct sk_buff pointer
- *
- * This clears the control block of skbuff buffers, which were transmitted to
- * the device. Notify that the function is not thread-safe, so prevent
- * multiple calls.
- */
-static void clear_tx_skb_control_block(struct sk_buff *skb)
-{
- struct zd_tx_skb_control_block *cb =
- (struct zd_tx_skb_control_block *)skb->cb;
-
- kfree(cb->control);
- cb->control = NULL;
-}
-
-/**
- * kfree_tx_skb - frees a tx skbuff
- * @skb: a &struct sk_buff pointer
- *
- * Frees the tx skbuff. Frees also the allocated control structure in the
- * control block if necessary.
- */
-static void kfree_tx_skb(struct sk_buff *skb)
-{
- clear_tx_skb_control_block(skb);
- dev_kfree_skb_any(skb);
-}
-
static void zd_op_stop(struct ieee80211_hw *hw)
{
struct zd_mac *mac = zd_hw_mac(hw);
@@ -276,40 +246,15 @@ static void zd_op_stop(struct ieee80211_hw *hw)
while ((skb = skb_dequeue(ack_wait_queue)))
- kfree_tx_skb(skb);
-}
-
-/**
- * init_tx_skb_control_block - initializes skb control block
- * @skb: a &sk_buff pointer
- * @dev: pointer to the mac80221 device
- * @control: mac80211 tx control applying for the frame in @skb
- *
- * Initializes the control block of the skbuff to be transmitted.
- */
-static int init_tx_skb_control_block(struct sk_buff *skb,
- struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control)
-{
- struct zd_tx_skb_control_block *cb =
- (struct zd_tx_skb_control_block *)skb->cb;
-
- ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb));
- memset(cb, 0, sizeof(*cb));
- cb->hw= hw;
- cb->control = kmalloc(sizeof(*control), GFP_ATOMIC);
- if (cb->control == NULL)
- return -ENOMEM;
- memcpy(cb->control, control, sizeof(*control));
-
- return 0;
+ dev_kfree_skb_any(skb);
}
/**
* tx_status - reports tx status of a packet if required
* @hw - a &struct ieee80211_hw pointer
* @skb - a sk-buffer
- * @status - the tx status of the packet without control information
+ * @flags: extra flags to set in the TX status info
+ * @ackssi: ACK signal strength
* @success - True for successfull transmission of the frame
*
* This information calls ieee80211_tx_status_irqsafe() if required by the
@@ -319,18 +264,17 @@ static int init_tx_skb_control_block(struct sk_buff *skb,
* If no status information has been requested, the skb is freed.
*/
static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_status *status,
- bool success)
+ u32 flags, int ackssi, bool success)
{
- struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *)
- skb->cb;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ memset(&info->status, 0, sizeof(info->status));
- ZD_ASSERT(cb->control != NULL);
- memcpy(&status->control, cb->control, sizeof(status->control));
if (!success)
- status->excessive_retries = 1;
- clear_tx_skb_control_block(skb);
- ieee80211_tx_status_irqsafe(hw, skb, status);
+ info->status.excessive_retries = 1;
+ info->flags |= flags;
+ info->status.ack_signal = ackssi;
+ ieee80211_tx_status_irqsafe(hw, skb);
}
/**
@@ -345,15 +289,12 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
{
struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
struct sk_buff *skb;
- struct ieee80211_tx_status status;
skb = skb_dequeue(q);
if (skb == NULL)
return;
- memset(&status, 0, sizeof(status));
-
- tx_status(hw, skb, &status, 0);
+ tx_status(hw, skb, 0, 0, 0);
}
/**
@@ -368,28 +309,20 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
*/
void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
{
- struct zd_tx_skb_control_block *cb =
- (struct zd_tx_skb_control_block *)skb->cb;
- struct ieee80211_hw *hw = cb->hw;
-
- if (likely(cb->control)) {
- skb_pull(skb, sizeof(struct zd_ctrlset));
- if (unlikely(error ||
- (cb->control->flags & IEEE80211_TXCTL_NO_ACK)))
- {
- struct ieee80211_tx_status status;
- memset(&status, 0, sizeof(status));
- tx_status(hw, skb, &status, !error);
- } else {
- struct sk_buff_head *q =
- &zd_hw_mac(hw)->ack_wait_queue;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hw *hw = info->driver_data[0];
- skb_queue_tail(q, skb);
- while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
- zd_mac_tx_failed(hw);
- }
+ skb_pull(skb, sizeof(struct zd_ctrlset));
+ if (unlikely(error ||
+ (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
+ tx_status(hw, skb, 0, 0, !error);
} else {
- kfree_tx_skb(skb);
+ struct sk_buff_head *q =
+ &zd_hw_mac(hw)->ack_wait_queue;
+
+ skb_queue_tail(q, skb);
+ while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
+ zd_mac_tx_failed(hw);
}
}
@@ -443,8 +376,6 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
struct ieee80211_hdr *header, u32 flags)
{
- u16 fctl = le16_to_cpu(header->frame_control);
-
/*
* CONTROL TODO:
* - if backoff needed, enable bit 0
@@ -454,7 +385,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
cs->control = 0;
/* First fragment */
- if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
+ if (flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
/* Multicast */
@@ -462,79 +393,104 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
cs->control |= ZD_CS_MULTICAST;
/* PS-POLL */
- if ((fctl & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE)) ==
- (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL))
+ if (ieee80211_is_pspoll(header->frame_control))
cs->control |= ZD_CS_PS_POLL_FRAME;
- if (flags & IEEE80211_TXCTL_USE_RTS_CTS)
+ if (flags & IEEE80211_TX_CTL_USE_RTS_CTS)
cs->control |= ZD_CS_RTS;
- if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+ if (flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
cs->control |= ZD_CS_SELF_CTS;
/* FIXME: Management frame? */
}
-void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
+static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
{
struct zd_mac *mac = zd_hw_mac(hw);
+ int r;
u32 tmp, j = 0;
/* 4 more bytes for tail CRC */
u32 full_len = beacon->len + 4;
- zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
- zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
+
+ r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
+ if (r < 0)
+ return r;
+ r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
+ if (r < 0)
+ return r;
+
while (tmp & 0x2) {
- zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
+ r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
+ if (r < 0)
+ return r;
if ((++j % 100) == 0) {
printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
if (j >= 500) {
printk(KERN_ERR "Giving up beacon config.\n");
- return;
+ return -ETIMEDOUT;
}
}
msleep(1);
}
- zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
- if (zd_chip_is_zd1211b(&mac->chip))
- zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
+ r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
+ if (r < 0)
+ return r;
+ if (zd_chip_is_zd1211b(&mac->chip)) {
+ r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
+ if (r < 0)
+ return r;
+ }
- for (j = 0 ; j < beacon->len; j++)
- zd_iowrite32(&mac->chip, CR_BCN_FIFO,
+ for (j = 0 ; j < beacon->len; j++) {
+ r = zd_iowrite32(&mac->chip, CR_BCN_FIFO,
*((u8 *)(beacon->data + j)));
+ if (r < 0)
+ return r;
+ }
+
+ for (j = 0; j < 4; j++) {
+ r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
+ if (r < 0)
+ return r;
+ }
- for (j = 0; j < 4; j++)
- zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
+ r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
+ if (r < 0)
+ return r;
- zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
/* 802.11b/g 2.4G CCK 1Mb
* 802.11a, not yet implemented, uses different values (see GPL vendor
* driver)
*/
- zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
+ return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
(full_len << 19));
}
static int fill_ctrlset(struct zd_mac *mac,
- struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+ struct sk_buff *skb)
{
int r;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
unsigned int frag_len = skb->len + FCS_LEN;
unsigned int packet_length;
+ struct ieee80211_rate *txrate;
struct zd_ctrlset *cs = (struct zd_ctrlset *)
skb_push(skb, sizeof(struct zd_ctrlset));
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
ZD_ASSERT(frag_len <= 0xffff);
- cs->modulation = control->tx_rate->hw_value;
- if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
- cs->modulation = control->tx_rate->hw_value_short;
+ txrate = ieee80211_get_tx_rate(mac->hw, info);
+
+ cs->modulation = txrate->hw_value;
+ if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
+ cs->modulation = txrate->hw_value_short;
cs->tx_length = cpu_to_le16(frag_len);
- cs_set_control(mac, cs, hdr, control->flags);
+ cs_set_control(mac, cs, hdr, info->flags);
packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
ZD_ASSERT(packet_length <= 0xffff);
@@ -579,24 +535,21 @@ static int fill_ctrlset(struct zd_mac *mac,
* control block of the skbuff will be initialized. If necessary the incoming
* mac80211 queues will be stopped.
*/
-static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
- struct ieee80211_tx_control *control)
+static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct zd_mac *mac = zd_hw_mac(hw);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int r;
- r = fill_ctrlset(mac, skb, control);
+ r = fill_ctrlset(mac, skb);
if (r)
return r;
- r = init_tx_skb_control_block(skb, hw, control);
- if (r)
- return r;
+ info->driver_data[0] = hw;
+
r = zd_usb_tx(&mac->chip.usb, skb);
- if (r) {
- clear_tx_skb_control_block(skb);
+ if (r)
return r;
- }
return 0;
}
@@ -617,13 +570,11 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
struct ieee80211_rx_status *stats)
{
- u16 fc = le16_to_cpu(rx_hdr->frame_control);
struct sk_buff *skb;
struct sk_buff_head *q;
unsigned long flags;
- if ((fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) !=
- (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK))
+ if (!ieee80211_is_ack(rx_hdr->frame_control))
return 0;
q = &zd_hw_mac(hw)->ack_wait_queue;
@@ -634,13 +585,8 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
tx_hdr = (struct ieee80211_hdr *)skb->data;
if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1)))
{
- struct ieee80211_tx_status status;
-
- memset(&status, 0, sizeof(status));
- status.flags = IEEE80211_TX_STATUS_ACK;
- status.ack_signal = stats->ssi;
__skb_unlink(skb, q);
- tx_status(hw, skb, &status, 1);
+ tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1);
goto out;
}
}
@@ -656,8 +602,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
const struct rx_status *status;
struct sk_buff *skb;
int bad_frame = 0;
- u16 fc;
- bool is_qos, is_4addr, need_padding;
+ __le16 fc;
+ int need_padding;
int i;
u8 rate;
@@ -691,8 +637,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
stats.band = IEEE80211_BAND_2GHZ;
- stats.ssi = status->signal_strength;
- stats.signal = zd_rx_qual_percent(buffer,
+ stats.signal = status->signal_strength;
+ stats.qual = zd_rx_qual_percent(buffer,
length - sizeof(struct rx_status),
status);
@@ -716,13 +662,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
&& !mac->pass_ctrl)
return 0;
- fc = le16_to_cpu(*((__le16 *) buffer));
-
- is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
- (fc & IEEE80211_STYPE_QOS_DATA);
- is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
- need_padding = is_qos ^ is_4addr;
+ fc = *(__le16 *)buffer;
+ need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc);
skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
if (skb == NULL)
@@ -751,6 +692,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
case IEEE80211_IF_TYPE_MNTR:
case IEEE80211_IF_TYPE_MESH_POINT:
case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS:
mac->type = conf->type;
break;
default:
@@ -781,14 +723,24 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
{
struct zd_mac *mac = zd_hw_mac(hw);
int associated;
+ int r;
- if (mac->type == IEEE80211_IF_TYPE_MESH_POINT) {
+ if (mac->type == IEEE80211_IF_TYPE_MESH_POINT ||
+ mac->type == IEEE80211_IF_TYPE_IBSS) {
associated = true;
- if (conf->beacon) {
- zd_mac_config_beacon(hw, conf->beacon);
- kfree_skb(conf->beacon);
- zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
+ if (conf->changed & IEEE80211_IFCC_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+ if (!beacon)
+ return -ENOMEM;
+ r = zd_mac_config_beacon(hw, beacon);
+ if (r < 0)
+ return r;
+ r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
hw->conf.beacon_int);
+ if (r < 0)
+ return r;
+ kfree_skb(beacon);
}
} else
associated = is_valid_ether_addr(conf->bssid);
@@ -983,10 +935,10 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
- hw->max_rssi = 100;
- hw->max_signal = 100;
+ IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+ IEEE80211_HW_SIGNAL_DB;
+ hw->max_signal = 100;
hw->queues = 1;
hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 71170244d2c..18c1d56d3dd 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -149,22 +149,6 @@ struct housekeeping {
struct delayed_work link_led_work;
};
-/**
- * struct zd_tx_skb_control_block - control block for tx skbuffs
- * @control: &struct ieee80211_tx_control pointer
- * @context: context pointer
- *
- * This structure is used to fill the cb field in an &sk_buff to transmit.
- * The control field is NULL, if there is no requirement from the mac80211
- * stack to report about the packet ACK. This is the case if the flag
- * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control.
- */
-struct zd_tx_skb_control_block {
- struct ieee80211_tx_control *control;
- struct ieee80211_hw *hw;
- void *context;
-};
-
#define ZD_MAC_STATS_BUFFER_SIZE 16
#define ZD_MAC_MAX_ACK_WAITERS 10
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 6cdad976460..da8b7433e3a 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -170,10 +170,11 @@ static int upload_code(struct usb_device *udev,
if (flags & REBOOT) {
u8 ret;
+ /* Use "DMA-aware" buffer. */
r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_FIRMWARE_CONFIRM,
USB_DIR_IN | USB_TYPE_VENDOR,
- 0, 0, &ret, sizeof(ret), 5000 /* ms */);
+ 0, 0, p, sizeof(ret), 5000 /* ms */);
if (r != sizeof(ret)) {
dev_err(&udev->dev,
"control request firmeware confirmation failed."
@@ -182,6 +183,7 @@ static int upload_code(struct usb_device *udev,
r = -ENODEV;
goto error;
}
+ ret = p[0];
if (ret & 0x80) {
dev_err(&udev->dev,
"Internal error while downloading."
@@ -313,22 +315,31 @@ int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
{
int r;
struct usb_device *udev = zd_usb_to_usbdev(usb);
+ u8 *buf;
+ /* Use "DMA-aware" buffer. */
+ buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
- data, len, 5000);
+ buf, len, 5000);
if (r < 0) {
dev_err(&udev->dev,
"read over firmware interface failed: %d\n", r);
- return r;
+ goto exit;
} else if (r != len) {
dev_err(&udev->dev,
"incomplete read over firmware interface: %d/%d\n",
r, len);
- return -EIO;
+ r = -EIO;
+ goto exit;
}
-
- return 0;
+ r = 0;
+ memcpy(data, buf, len);
+exit:
+ kfree(buf);
+ return r;
}
#define urb_dev(urb) (&(urb)->dev->dev)
@@ -870,7 +881,7 @@ static void tx_urb_complete(struct urb *urb)
{
int r;
struct sk_buff *skb;
- struct zd_tx_skb_control_block *cb;
+ struct ieee80211_tx_info *info;
struct zd_usb *usb;
switch (urb->status) {
@@ -894,8 +905,8 @@ free_urb:
* grab 'usb' pointer before handing off the skb (since
* it might be freed by zd_mac_tx_to_dev or mac80211)
*/
- cb = (struct zd_tx_skb_control_block *)skb->cb;
- usb = &zd_hw_mac(cb->hw)->chip.usb;
+ info = IEEE80211_SKB_CB(skb);
+ usb = &zd_hw_mac(info->driver_data[0])->chip.usb;
zd_mac_tx_to_dev(skb, urb->status);
free_tx_urb(usb, urb);
tx_dec_submitted_urbs(usb);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 22f64aa6dd1..b29afef5c7f 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2013,7 +2013,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev,
}
}
- if (rc && !(netdev_priv(vlan_dev_info(dev)->real_dev) == (void *)card))
+ if (rc && !(netdev_priv(vlan_dev_real_dev(dev)) == (void *)card))
return 0;
return rc;
@@ -2049,7 +2049,7 @@ static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
if (rc == QETH_REAL_CARD)
card = netdev_priv(dev);
else if (rc == QETH_VLAN_CARD)
- card = netdev_priv(vlan_dev_info(dev)->real_dev);
+ card = netdev_priv(vlan_dev_real_dev(dev));
if (card && card->options.layer2)
card = NULL;
QETH_DBF_TEXT_(TRACE, 4, "%d", rc);
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 0276471cb25..6558a403780 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -4,8 +4,6 @@
* Driver for the serial port on the 21285 StrongArm-110 core logic chip.
*
* Based on drivers/char/serial.c
- *
- * $Id: 21285.c,v 1.37 2002/07/28 10:03:27 rmk Exp $
*/
#include <linux/module.h>
#include <linux/tty.h>
@@ -88,7 +86,7 @@ static void serial21285_enable_ms(struct uart_port *port)
static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int status, ch, flag, rxs, max_count = 256;
status = *CSR_UARTFLG;
@@ -237,8 +235,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
- if (port->info && port->info->tty) {
- struct tty_struct *tty = port->info->tty;
+ if (port->info && port->info->port.tty) {
+ struct tty_struct *tty = port->info->port.tty;
unsigned int b = port->uartclk / (16 * quot);
tty_encode_baud_rate(tty, b, b);
}
@@ -494,7 +492,7 @@ static int __init serial21285_init(void)
{
int ret;
- printk(KERN_INFO "Serial: 21285 driver $Revision: 1.37 $\n");
+ printk(KERN_INFO "Serial: 21285 driver\n");
serial21285_setup_ports();
@@ -515,5 +513,5 @@ module_init(serial21285_init);
module_exit(serial21285_exit);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver $Revision: 1.37 $");
+MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver");
MODULE_ALIAS_CHARDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index bbf5bc5892c..381b12ac20e 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -249,7 +249,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
{
#if 0
if(status & DCD) {
- if((info->tty->termios->c_cflag & CRTSCTS) &&
+ if((info->port.tty->termios->c_cflag & CRTSCTS) &&
((info->curregs[3] & AUTO_ENAB)==0)) {
info->curregs[3] |= AUTO_ENAB;
info->pendregs[3] |= AUTO_ENAB;
@@ -274,7 +274,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status)
static void receive_chars(struct m68k_serial *info, unsigned short rx)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
m68328_uart *uart = &uart_addr[info->line];
unsigned char ch, flag;
@@ -345,7 +345,7 @@ static void transmit_chars(struct m68k_serial *info)
goto clear_and_return;
}
- if((info->xmit_cnt <= 0) || info->tty->stopped) {
+ if((info->xmit_cnt <= 0) || info->port.tty->stopped) {
/* That's peculiar... TX ints off */
uart->ustcnt &= ~USTCNT_TX_INTR_MASK;
goto clear_and_return;
@@ -403,7 +403,7 @@ static void do_softint(struct work_struct *work)
struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue);
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
#if 0
@@ -427,7 +427,7 @@ static void do_serial_hangup(struct work_struct *work)
struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup);
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -471,8 +471,8 @@ static int startup(struct m68k_serial * info)
uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK;
#endif
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/*
@@ -506,8 +506,8 @@ static void shutdown(struct m68k_serial * info)
info->xmit_buf = 0;
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~S_INITIALIZED;
local_irq_restore(flags);
@@ -573,9 +573,9 @@ static void change_speed(struct m68k_serial *info)
unsigned cflag;
int i;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
if (!(port = info->port))
return;
@@ -1131,7 +1131,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
#warning "This is not and has never been valid so fix it"
#if 0
if (tty->ldisc.num != ldiscs[N_TTY].num) {
@@ -1169,7 +1169,7 @@ void rs_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
info->flags &= ~S_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -1286,7 +1286,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
info->count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
@@ -1363,7 +1363,7 @@ rs68328_init(void)
info = &m68k_soft[i];
info->magic = SERIAL_MAGIC;
info->port = (int) &uart_addr[i];
- info->tty = 0;
+ info->port.tty = NULL;
info->irq = uart_irqs[i];
info->custom_divisor = 16;
info->close_delay = 50;
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index d9d4e9552a4..24661cd5e4f 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -393,7 +393,7 @@ static void rs_360_start(struct tty_struct *tty)
static _INLINE_ void receive_chars(ser_info_t *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned char ch, flag, *cp;
/*int ignored = 0;*/
int i;
@@ -514,7 +514,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
static _INLINE_ void receive_break(ser_info_t *info)
{
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
info->state->icount.brk++;
/* Check to see if there is room in the tty buffer for
@@ -528,7 +528,7 @@ static _INLINE_ void transmit_chars(ser_info_t *info)
{
if ((info->flags & TX_WAKEUP) ||
- (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
+ (info->port.tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
schedule_work(&info->tqueue);
}
@@ -584,12 +584,12 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
}
}
if (info->flags & ASYNC_CTS_FLOW) {
- if (info->tty->hw_stopped) {
+ if (info->port.tty->hw_stopped) {
if (status & UART_MSR_CTS) {
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk("CTS tx start...");
#endif
- info->tty->hw_stopped = 0;
+ info->port.tty->hw_stopped = 0;
info->IER |= UART_IER_THRI;
serial_out(info, UART_IER, info->IER);
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
@@ -600,7 +600,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk("CTS tx stop...");
#endif
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
info->IER &= ~UART_IER_THRI;
serial_out(info, UART_IER, info->IER);
}
@@ -670,7 +670,7 @@ static void do_softint(void *private_)
ser_info_t *info = (ser_info_t *) private_;
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -693,7 +693,7 @@ static void do_serial_hangup(void *private_)
struct async_struct *info = (struct async_struct *) private_;
struct tty_struct *tty;
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -721,8 +721,8 @@ static int startup(ser_info_t *info)
#ifdef maybe
if (!state->port || !state->type) {
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
goto errout;
}
#endif
@@ -734,12 +734,12 @@ static int startup(ser_info_t *info)
#ifdef modem_control
info->MCR = 0;
- if (info->tty->termios->c_cflag & CBAUD)
+ if (info->port.tty->termios->c_cflag & CBAUD)
info->MCR = UART_MCR_DTR | UART_MCR_RTS;
#endif
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
/*
* and set the speed of the serial port
@@ -842,8 +842,8 @@ static void shutdown(ser_info_t *info)
smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
local_irq_restore(flags);
@@ -863,9 +863,9 @@ static void change_speed(ser_info_t *info)
volatile struct smc_regs *smcp;
volatile struct scc_regs *sccp;
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
state = info->state;
@@ -936,24 +936,24 @@ static void change_speed(ser_info_t *info)
* Set up parity check flag
*/
info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= BD_SC_FR | BD_SC_PR;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= BD_SC_BR;
/*
* Characters to ignore
*/
info->ignore_status_mask = 0;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= BD_SC_PR | BD_SC_FR;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= BD_SC_BR;
/*
* If we're ignore parity and break indicators, ignore
* overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= BD_SC_OV;
}
/*
@@ -1658,7 +1658,7 @@ static void rs_360_close(struct tty_struct *tty, struct file * filp)
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
if (info->blocked_open) {
if (info->close_delay) {
msleep_interruptible(jiffies_to_msecs(info->close_delay));
@@ -1758,7 +1758,7 @@ static void rs_360_hangup(struct tty_struct *tty)
info->event = 0;
state->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -1919,7 +1919,7 @@ static int rs_360_open(struct tty_struct *tty, struct file * filp)
printk("rs_open %s, count = %d\n", tty->name, info->state->count);
#endif
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
@@ -1976,7 +1976,7 @@ static inline int line_info(char *buf, struct serial_state *state)
info->port = state->port;
info->flags = state->flags;
info->quot = 0;
- info->tty = 0;
+ info->port.tty = NULL;
}
local_irq_disable();
status = serial_in(info, UART_MSR);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index be95e55b228..ce948b66bbd 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -12,8 +12,6 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * $Id: 8250.c,v 1.90 2002/07/28 10:03:27 rmk Exp $
- *
* A note about mapbase / membase
*
* mapbase is the physical address of the IO port.
@@ -1289,7 +1287,7 @@ static void serial8250_enable_ms(struct uart_port *port)
static void
receive_chars(struct uart_8250_port *up, unsigned int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch, lsr = *status;
int max_count = 256;
char flag;
@@ -2934,7 +2932,7 @@ static int __init serial8250_init(void)
if (nr_uarts > UART_NR)
nr_uarts = UART_NR;
- printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
+ printk(KERN_INFO "Serial: 8250/16550 driver"
"%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");
@@ -2995,7 +2993,7 @@ EXPORT_SYMBOL(serial8250_suspend_port);
EXPORT_SYMBOL(serial8250_resume_port);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $");
+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
module_param(share_irqs, uint, 0644);
MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 91bd28f2bb4..78c00162b04 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -11,8 +11,6 @@
* 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.
- *
- * $Id: 8250.h,v 1.8 2002/07/21 21:32:30 rmk Exp $
*/
#include <linux/serial_8250.h>
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 788c3559522..1b36087665a 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -10,8 +10,6 @@
* 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.
- *
- * $Id: 8250_pci.c,v 1.28 2002/11/02 11:14:18 rmk Exp $
*/
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 638b68649e7..fde7f9ccf57 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -12,8 +12,6 @@
* 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.
- *
- * $Id: 8250_pnp.c,v 1.10 2002/07/21 21:32:30 rmk Exp $
*/
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 18ca9075e13..8fc7451c004 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1,8 +1,6 @@
#
# Serial device configuration
#
-# $Id: Kconfig,v 1.11 2004/03/11 18:08:04 lethal Exp $
-#
menu "Serial drivers"
depends on HAS_IOMEM
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 7d85c1fbe7e..3a0bbbe17aa 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -1,8 +1,6 @@
#
# Makefile for the kernel serial device drivers.
#
-# $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
-#
obj-$(CONFIG_SERIAL_CORE) += serial_core.o
obj-$(CONFIG_SERIAL_21285) += 21285.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index e88da72f830..90b56c2c31e 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -22,8 +22,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $
- *
* This is a generic driver for ARM AMBA-type serial ports. They
* have a lot of 16550-like features, but are not register compatible.
* Note that although they do have CTS, DCD and DSR inputs, they do
@@ -119,7 +117,7 @@ static void pl010_enable_ms(struct uart_port *port)
static void pl010_rx_chars(struct uart_amba_port *uap)
{
- struct tty_struct *tty = uap->port.info->tty;
+ struct tty_struct *tty = uap->port.info->port.tty;
unsigned int status, ch, flag, rsr, max_count = 256;
status = readb(uap->port.membase + UART01x_FR);
@@ -791,7 +789,7 @@ static int __init pl010_init(void)
{
int ret;
- printk(KERN_INFO "Serial: AMBA driver $Revision: 1.41 $\n");
+ printk(KERN_INFO "Serial: AMBA driver\n");
ret = uart_register_driver(&amba_reg);
if (ret == 0) {
@@ -812,5 +810,5 @@ module_init(pl010_init);
module_exit(pl010_exit);
MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("ARM AMBA serial port driver $Revision: 1.41 $");
+MODULE_DESCRIPTION("ARM AMBA serial port driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 08adc1de4a7..9d08f27208a 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -22,8 +22,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: amba.c,v 1.41 2002/07/28 10:03:27 rmk Exp $
- *
* This is a generic driver for ARM AMBA-type serial ports. They
* have a lot of 16550-like features, but are not register compatible.
* Note that although they do have CTS, DCD and DSR inputs, they do
@@ -109,7 +107,7 @@ static void pl011_enable_ms(struct uart_port *port)
static void pl011_rx_chars(struct uart_amba_port *uap)
{
- struct tty_struct *tty = uap->port.info->tty;
+ struct tty_struct *tty = uap->port.info->port.tty;
unsigned int status, ch, flag, max_count = 256;
status = readw(uap->port.membase + UART01x_FR);
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 6aeef22bd20..1fee12c1f4f 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -662,14 +662,14 @@ static void atmel_rx_from_ring(struct uart_port *port)
* uart_start(), which takes the lock.
*/
spin_unlock(&port->lock);
- tty_flip_buffer_push(port->info->tty);
+ tty_flip_buffer_push(port->info->port.tty);
spin_lock(&port->lock);
}
static void atmel_rx_from_dma(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct atmel_dma_buffer *pdc;
int rx_idx = atmel_port->pdc_rx_idx;
unsigned int head;
@@ -794,7 +794,7 @@ static void atmel_tasklet_func(unsigned long data)
static int atmel_startup(struct uart_port *port)
{
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
int retval;
/*
@@ -956,6 +956,20 @@ static void atmel_shutdown(struct uart_port *port)
}
/*
+ * Flush any TX data submitted for DMA. Called when the TX circular
+ * buffer is reset.
+ */
+static void atmel_flush_buffer(struct uart_port *port)
+{
+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
+ if (atmel_use_dma_tx(port)) {
+ UART_PUT_TCR(port, 0);
+ atmel_port->pdc_tx.ofs = 0;
+ }
+}
+
+/*
* Power / Clock management.
*/
static void atmel_serial_pm(struct uart_port *port, unsigned int state,
@@ -1189,6 +1203,7 @@ static struct uart_ops atmel_pops = {
.break_ctl = atmel_break_ctl,
.startup = atmel_startup,
.shutdown = atmel_shutdown,
+ .flush_buffer = atmel_flush_buffer,
.set_termios = atmel_set_termios,
.type = atmel_type,
.release_port = atmel_release_port,
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index fd9bb777df2..9d8543762a3 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -175,7 +175,7 @@ int kgdb_get_debug_char(void)
#ifdef CONFIG_SERIAL_BFIN_PIO
static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
{
- struct tty_struct *tty = uart->port.info->tty;
+ struct tty_struct *tty = uart->port.info->port.tty;
unsigned int status, ch, flg;
static struct timeval anomaly_start = { .tv_sec = 0 };
@@ -393,7 +393,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
{
- struct tty_struct *tty = uart->port.info->tty;
+ struct tty_struct *tty = uart->port.info->port.tty;
int i, flg, status;
status = UART_GET_LSR(uart);
@@ -552,7 +552,7 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
unsigned int status;
struct uart_info *info = uart->port.info;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
status = bfin_serial_get_mctrl(&uart->port);
uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
@@ -814,10 +814,10 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
int line = port->line;
unsigned short val;
- if (line >= port->info->tty->driver->num)
+ if (line >= port->info->port.tty->driver->num)
return;
- switch (port->info->tty->ldisc.num) {
+ switch (port->info->port.tty->ldisc.num) {
case N_IRDA:
val = UART_GET_GCTL(&bfin_serial_ports[line]);
val |= (IREN | RPOLC);
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index aca1240ad80..dd8564d2505 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -174,7 +174,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
{
struct sport_uart_port *up = dev_id;
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned int ch;
do {
@@ -201,7 +201,7 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
{
struct sport_uart_port *up = dev_id;
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned int stat = SPORT_GET_STAT(up);
/* Overflow in RX FIFO */
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 23827189ec0..fc1fa9267c5 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -21,9 +21,6 @@
* 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
- *
- * $Id: clps711x.c,v 1.42 2002/07/28 10:03:28 rmk Exp $
- *
*/
#if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -96,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int status, ch, flg;
status = clps_readl(SYSFLG(port));
@@ -551,7 +548,7 @@ static int __init clps711xuart_init(void)
{
int ret, i;
- printk(KERN_INFO "Serial: CLPS711x driver $Revision: 1.42 $\n");
+ printk(KERN_INFO "Serial: CLPS711x driver\n");
ret = uart_register_driver(&clps711x_reg);
if (ret)
@@ -577,6 +574,6 @@ module_init(clps711xuart_init);
module_exit(clps711xuart_exit);
MODULE_AUTHOR("Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("CLPS-711x generic serial driver $Revision: 1.42 $");
+MODULE_DESCRIPTION("CLPS-711x generic serial driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR);
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 3e0366eab41..8249ac49055 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -968,7 +968,7 @@ static DEFINE_MUTEX(tmp_buf_mutex);
/* Calculate the chartime depending on baudrate, numbor of bits etc. */
static void update_char_time(struct e100_serial * info)
{
- tcflag_t cflags = info->tty->termios->c_cflag;
+ tcflag_t cflags = info->port.tty->termios->c_cflag;
int bits;
/* calc. number of bits / data byte */
@@ -1483,7 +1483,8 @@ rs_stop(struct tty_struct *tty)
CIRC_CNT(info->xmit.head,
info->xmit.tail,SERIAL_XMIT_SIZE)));
- xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char,
+ STOP_CHAR(info->port.tty));
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop);
if (tty->termios->c_iflag & IXON ) {
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
@@ -1772,7 +1773,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl
info->icount.rx++;
} else {
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
tty_insert_flip_char(tty, data, flag);
info->icount.rx++;
}
@@ -1838,7 +1839,7 @@ static unsigned int handle_all_descr_data(struct e100_serial *info)
descr->status = 0;
DFLOW( DEBUG_LOG(info->line, "RX %lu\n", recvl);
- if (info->tty->stopped) {
+ if (info->port.tty->stopped) {
unsigned char *buf = phys_to_virt(descr->buf);
DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]);
DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]);
@@ -1872,7 +1873,7 @@ static void receive_chars_dma(struct e100_serial *info)
IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
- tty = info->tty;
+ tty = info->port.tty;
if (!tty) /* Something wrong... */
return;
@@ -2122,7 +2123,7 @@ static void flush_to_flip_buffer(struct e100_serial *info)
unsigned long flags;
local_irq_save(flags);
- tty = info->tty;
+ tty = info->port.tty;
if (!tty) {
local_irq_restore(flags);
@@ -2287,7 +2288,7 @@ static
struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
{
unsigned long data_read;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if (!tty) {
printk("!NO TTY!\n");
@@ -2350,7 +2351,7 @@ more_data:
data_in, data_read);
char flag = TTY_NORMAL;
if (info->errorcode == ERRCODE_INSERT_BREAK) {
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
tty_insert_flip_char(tty, 0, flag);
info->icount.rx++;
}
@@ -2396,7 +2397,7 @@ more_data:
goto more_data;
}
- tty_flip_buffer_push(info->tty);
+ tty_flip_buffer_push(info->port.tty);
return info;
}
@@ -2547,8 +2548,8 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
rstat = info->port[REG_STATUS];
DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
e100_disable_serial_tx_ready_irq(info);
- if (info->tty->stopped)
- rs_stop(info->tty);
+ if (info->port.tty->stopped)
+ rs_stop(info->port.tty);
/* Enable the DMA channel and tell it to continue */
e100_enable_txdma_channel(info);
/* Wait 12 cycles before doing the DMA command */
@@ -2561,9 +2562,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info)
}
/* Normal char-by-char interrupt */
if (info->xmit.head == info->xmit.tail
- || info->tty->stopped
- || info->tty->hw_stopped) {
- DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->tty->stopped));
+ || info->port.tty->stopped
+ || info->port.tty->hw_stopped) {
+ DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n",
+ info->port.tty->stopped));
e100_disable_serial_tx_ready_irq(info);
info->tr_running = 0;
return;
@@ -2725,7 +2727,7 @@ do_softint(struct work_struct *work)
info = container_of(work, struct e100_serial, work);
- tty = info->tty;
+ tty = info->port.tty;
if (!tty)
return;
@@ -2767,8 +2769,8 @@ startup(struct e100_serial * info)
/* Bits and pieces collected from below. Better to have them
in one ifdef:ed clause than to mix in a lot of ifdefs,
right? */
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit.head = info->xmit.tail = 0;
info->first_recv_buffer = info->last_recv_buffer = NULL;
@@ -2825,8 +2827,8 @@ startup(struct e100_serial * info)
e100_disable_txdma_channel(info);
}
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit.head = info->xmit.tail = 0;
info->first_recv_buffer = info->last_recv_buffer = NULL;
@@ -2940,14 +2942,14 @@ shutdown(struct e100_serial * info)
descr[i].buf = 0;
}
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
/* hang up DTR and RTS if HUPCL is enabled */
e100_dtr(info, 0);
e100_rts(info, 0); /* could check CRTSCTS before doing this */
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
local_irq_restore(flags);
@@ -2964,12 +2966,12 @@ change_speed(struct e100_serial *info)
unsigned long flags;
/* first some safety checks */
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
if (!info->port)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
/* possibly, the tx/rx should be disabled first to do this safely */
@@ -3097,10 +3099,11 @@ change_speed(struct e100_serial *info)
info->port[REG_TR_CTRL] = info->tx_ctrl;
info->port[REG_REC_CTRL] = info->rx_ctrl;
- xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
+ xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty));
xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
- if (info->tty->termios->c_iflag & IXON ) {
- DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", STOP_CHAR(info->tty)));
+ if (info->port.tty->termios->c_iflag & IXON ) {
+ DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n",
+ STOP_CHAR(info->port.tty)));
xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
}
@@ -3475,7 +3478,7 @@ set_serial_info(struct e100_serial *info,
info->type = new_serial.type;
info->close_delay = new_serial.close_delay;
info->closing_wait = new_serial.closing_wait;
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
check_and_exit:
if (info->flags & ASYNC_INITIALIZED) {
@@ -3811,7 +3814,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
tty_ldisc_flush(tty);
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
if (info->blocked_open) {
if (info->close_delay)
schedule_timeout_interruptible(info->close_delay);
@@ -3915,7 +3918,7 @@ rs_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -4077,9 +4080,9 @@ rs_open(struct tty_struct *tty, struct file * filp)
info->count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
if (!tmp_buf) {
page = get_zeroed_page(GFP_KERNEL);
@@ -4267,14 +4270,14 @@ static int line_info(char *buf, struct e100_serial *info)
(unsigned long)info->max_recv_cnt);
#if 1
- if (info->tty) {
+ if (info->port.tty) {
- if (info->tty->stopped)
+ if (info->port.tty->stopped)
ret += sprintf(buf+ret, " stopped:%i",
- (int)info->tty->stopped);
- if (info->tty->hw_stopped)
+ (int)info->port.tty->stopped);
+ if (info->port.tty->hw_stopped)
ret += sprintf(buf+ret, " hw_stopped:%i",
- (int)info->tty->hw_stopped);
+ (int)info->port.tty->hw_stopped);
}
{
@@ -4465,7 +4468,7 @@ rs_init(void)
info->uses_dma_in = 0;
info->uses_dma_out = 0;
info->line = i;
- info->tty = 0;
+ info->port.tty = NULL;
info->type = PORT_ETRAX;
info->tr_running = 0;
info->forced_eop = 0;
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 0dddd68b20d..a81d2c2ff8a 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -197,7 +197,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
dport = &mux->dport[LINE(status)];
uport = &dport->port;
- tty = uport->info->tty; /* point to the proper dev */
+ tty = uport->info->port.tty; /* point to the proper dev */
ch = UCHAR(status); /* grab the char */
flag = TTY_NORMAL;
@@ -249,7 +249,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
}
for (i = 0; i < DZ_NB_PORT; i++)
if (lines_rx[i])
- tty_flip_buffer_push(mux->dport[i].port.info->tty);
+ tty_flip_buffer_push(mux->dport[i].port.info->port.tty);
}
/*
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 64acb39a51b..e0da4dc7bbf 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -372,7 +372,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
{
struct imx_port *sport = dev_id;
unsigned int rx,flg,ignored = 0;
- struct tty_struct *tty = sport->port.info->tty;
+ struct tty_struct *tty = sport->port.info->port.tty;
unsigned long flags, temp;
spin_lock_irqsave(&sport->port.lock,flags);
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index 4f1af71e9a1..6dd98f9fb89 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -905,7 +905,7 @@ static void transmit_chars(struct uart_port *the_port)
return;
info = the_port->info;
- tty = info->tty;
+ tty = info->port.tty;
if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
/* Nothing to do or hw stopped */
@@ -997,14 +997,14 @@ ioc3_change_speed(struct uart_port *the_port,
the_port->ignore_status_mask = N_ALL_INPUT;
- info->tty->low_latency = 1;
+ info->port.tty->low_latency = 1;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
the_port->ignore_status_mask &= ~N_BREAK;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
}
if (!(cflag & CREAD)) {
@@ -1399,14 +1399,14 @@ static int receive_chars(struct uart_port *the_port)
/* Make sure all the pointers are "good" ones */
if (!info)
return 0;
- if (!info->tty)
+ if (!info->port.tty)
return 0;
if (!(port->ip_flags & INPUT_ENABLE))
return 0;
spin_lock_irqsave(&the_port->lock, pflags);
- tty = info->tty;
+ tty = info->port.tty;
read_count = do_read(the_port, ch, MAX_CHARS);
if (read_count > 0) {
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 49b8a82b7b9..6bab63cd5b2 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -1635,7 +1635,7 @@ static void transmit_chars(struct uart_port *the_port)
return;
info = the_port->info;
- tty = info->tty;
+ tty = info->port.tty;
if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
/* Nothing to do or hw stopped */
@@ -1738,14 +1738,14 @@ ioc4_change_speed(struct uart_port *the_port,
the_port->ignore_status_mask = N_ALL_INPUT;
- info->tty->low_latency = 1;
+ info->port.tty->low_latency = 1;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~(N_PARITY_ERROR
| N_FRAMING_ERROR);
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
the_port->ignore_status_mask &= ~N_BREAK;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
}
if (!(cflag & CREAD)) {
@@ -1801,7 +1801,8 @@ static inline int ic4_startup_local(struct uart_port *the_port)
ioc4_set_proto(port, the_port->mapbase);
/* set the speed of the serial port */
- ioc4_change_speed(the_port, info->tty->termios, (struct ktermios *)0);
+ ioc4_change_speed(the_port, info->port.tty->termios,
+ (struct ktermios *)0);
return 0;
}
@@ -2346,11 +2347,11 @@ static void receive_chars(struct uart_port *the_port)
/* Make sure all the pointers are "good" ones */
if (!info)
return;
- if (!info->tty)
+ if (!info->port.tty)
return;
spin_lock_irqsave(&the_port->lock, pflags);
- tty = info->tty;
+ tty = info->port.tty;
request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS);
@@ -2440,8 +2441,8 @@ static void ic4_shutdown(struct uart_port *the_port)
wake_up_interruptible(&info->delta_msr_wait);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
spin_lock_irqsave(&the_port->lock, port_flags);
set_notification(port, N_ALL, 0);
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 9c95bc0398a..0d9acbd0bb7 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -257,8 +257,8 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up
tty = NULL;
if (up->port.info != NULL &&
- up->port.info->tty != NULL)
- tty = up->port.info->tty;
+ up->port.info->port.tty != NULL)
+ tty = up->port.info->port.tty;
for (;;) {
ch = readb(&channel->control);
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index b2d6f5b1a7c..b7584ca55ad 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -998,7 +998,7 @@ static void neo_param(struct jsm_channel *ch)
{ 50, B50 },
};
- cflag = C_BAUD(ch->uart_port.info->tty);
+ cflag = C_BAUD(ch->uart_port.info->port.tty);
baud = 9600;
for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
if (baud_rates[i].cflag == cflag) {
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 94ec6637250..a697914ae3d 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -145,7 +145,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
struct ktermios *termios;
spin_lock_irqsave(&port->lock, lock_flags);
- termios = port->info->tty->termios;
+ termios = port->info->port.tty->termios;
if (ch == termios->c_cc[VSTART])
channel->ch_bd->bd_ops->send_start_character(channel);
@@ -239,7 +239,7 @@ static int jsm_tty_open(struct uart_port *port)
channel->ch_cached_lsr = 0;
channel->ch_stops_sent = 0;
- termios = port->info->tty->termios;
+ termios = port->info->port.tty->termios;
channel->ch_c_cflag = termios->c_cflag;
channel->ch_c_iflag = termios->c_iflag;
channel->ch_c_oflag = termios->c_oflag;
@@ -272,7 +272,7 @@ static void jsm_tty_close(struct uart_port *port)
jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
bd = channel->ch_bd;
- ts = channel->uart_port.info->tty->termios;
+ ts = channel->uart_port.info->port.tty->termios;
channel->ch_flags &= ~(CH_STOPI);
@@ -515,7 +515,7 @@ void jsm_input(struct jsm_channel *ch)
if (!ch)
return;
- tp = ch->uart_port.info->tty;
+ tp = ch->uart_port.info->port.tty;
bd = ch->ch_bd;
if(!bd)
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index c2bb11c02bd..23d03051101 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -325,7 +325,7 @@ static void m32r_sio_enable_ms(struct uart_port *port)
static void receive_chars(struct uart_sio_port *up, int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch;
unsigned char flag;
int max_count = 256;
@@ -1160,7 +1160,7 @@ static int __init m32r_sio_init(void)
{
int ret, i;
- printk(KERN_INFO "Serial: M32R SIO driver $Revision: 1.11 $ ");
+ printk(KERN_INFO "Serial: M32R SIO driver\n");
for (i = 0; i < NR_IRQS; i++)
spin_lock_init(&irq_lists[i].lock);
@@ -1189,4 +1189,4 @@ EXPORT_SYMBOL(m32r_sio_suspend_port);
EXPORT_SYMBOL(m32r_sio_resume_port);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic M32R SIO serial driver $Revision: 1.11 $");
+MODULE_DESCRIPTION("Generic M32R SIO serial driver");
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 7e164e0cd21..b2001c5b145 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -312,7 +312,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
}
- tty_flip_buffer_push(port->info->tty);
+ tty_flip_buffer_push(port->info->port.tty);
}
/****************************************************************************/
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index 56007cc8a9b..fbe3835f6b7 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -327,7 +327,7 @@ static void mcfrs_start(struct tty_struct *tty)
static inline void receive_chars(struct mcf_serial *info)
{
volatile unsigned char *uartp;
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
unsigned char status, ch, flag;
if (!tty)
@@ -382,7 +382,7 @@ static inline void transmit_chars(struct mcf_serial *info)
info->stats.tx++;
}
- if ((info->xmit_cnt <= 0) || info->tty->stopped) {
+ if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
info->imr &= ~MCFUART_UIR_TXREADY;
uartp[MCFUART_UIMR] = info->imr;
return;
@@ -428,7 +428,7 @@ irqreturn_t mcfrs_interrupt(int irq, void *dev_id)
static void mcfrs_offintr(struct work_struct *work)
{
struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue);
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if (tty)
tty_wakeup(tty);
@@ -498,7 +498,7 @@ static void mcfrs_timer(void)
static void do_serial_hangup(struct work_struct *work)
{
struct mcf_serial *info = container_of(work, struct mcf_serial, tqueue_hangup);
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
if (tty)
tty_hangup(tty);
@@ -532,8 +532,8 @@ static int startup(struct mcf_serial * info)
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
mcfrs_setsignals(info, 1, 1);
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
/*
@@ -578,7 +578,7 @@ static void shutdown(struct mcf_serial * info)
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
mcfrs_setsignals(info, 0, 0);
if (info->xmit_buf) {
@@ -586,8 +586,8 @@ static void shutdown(struct mcf_serial * info)
info->xmit_buf = 0;
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
info->flags &= ~ASYNC_INITIALIZED;
local_irq_restore(flags);
@@ -609,9 +609,9 @@ static void mcfrs_change_speed(struct mcf_serial *info)
unsigned int fraction;
#endif
- if (!info->tty || !info->tty->termios)
+ if (!info->port.tty || !info->port.tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = info->port.tty->termios->c_cflag;
if (info->addr == 0)
return;
@@ -623,7 +623,7 @@ static void mcfrs_change_speed(struct mcf_serial *info)
if (i & CBAUDEX) {
i &= ~CBAUDEX;
if (i < 1 || i > 4)
- info->tty->termios->c_cflag &= ~CBAUDEX;
+ info->port.tty->termios->c_cflag &= ~CBAUDEX;
else
i += 15;
}
@@ -1216,7 +1216,7 @@ static void mcfrs_close(struct tty_struct *tty, struct file * filp)
tty->closing = 0;
info->event = 0;
- info->tty = 0;
+ info->port.tty = NULL;
#if 0
if (tty->ldisc.num != ldiscs[N_TTY].num) {
if (tty->ldisc.close)
@@ -1325,7 +1325,7 @@ void mcfrs_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
- info->tty = 0;
+ info->port.tty = NULL;
wake_up_interruptible(&info->open_wait);
}
@@ -1452,7 +1452,7 @@ int mcfrs_open(struct tty_struct *tty, struct file * filp)
#endif
info->count++;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
/*
* Start up serial port
@@ -1767,7 +1767,7 @@ mcfrs_init(void)
for (i = 0, info = mcfrs_table; (i < NR_PORTS); i++, info++) {
info->magic = SERIAL_MAGIC;
info->line = i;
- info->tty = 0;
+ info->port.tty = NULL;
info->custom_divisor = 16;
info->close_delay = 50;
info->closing_wait = 3000;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index efc971d9647..36126070d9a 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -732,7 +732,7 @@ static struct uart_ops mpc52xx_uart_ops = {
static inline int
mpc52xx_uart_int_rx_chars(struct uart_port *port)
{
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned char ch, flag;
unsigned short status;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index e8819c43f57..c9f53e71f25 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -932,7 +932,7 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
static int mpsc_rx_intr(struct mpsc_port_info *pi)
{
struct mpsc_rx_desc *rxre;
- struct tty_struct *tty = pi->port.info->tty;
+ struct tty_struct *tty = pi->port.info->port.tty;
u32 cmdstat, bytes_in, i;
int rc = 0;
u8 *bp;
@@ -1972,7 +1972,7 @@ static int __init mpsc_drv_init(void)
{
int rc;
- printk(KERN_INFO "Serial: MPSC driver $Revision: 1.00 $\n");
+ printk(KERN_INFO "Serial: MPSC driver\n");
memset(mpsc_ports, 0, sizeof(mpsc_ports));
memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
@@ -2004,7 +2004,7 @@ module_init(mpsc_drv_init);
module_exit(mpsc_drv_exit);
MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
-MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $");
+MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver");
MODULE_VERSION(MPSC_VERSION);
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR);
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index e94031731a4..953a5ffa9b4 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -243,7 +243,7 @@ static void mux_write(struct uart_port *port)
static void mux_read(struct uart_port *port)
{
int data;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
__u32 start_count = port->icount.rx;
while(1) {
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 81ac9bb4f39..9f8ccb735c1 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -203,7 +203,7 @@ static void netx_txint(struct uart_port *port)
static void netx_rxint(struct uart_port *port)
{
unsigned char rx, flg, status;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
rx = readl(port->membase + UART_DR);
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 794bd0f50d7..317b061f764 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -242,12 +242,12 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
}
/* Sanity check, make sure the old bug is no longer happening */
- if (uap->port.info == NULL || uap->port.info->tty == NULL) {
+ if (uap->port.info == NULL || uap->port.info->port.tty == NULL) {
WARN_ON(1);
(void)read_zsdata(uap);
return NULL;
}
- tty = uap->port.info->tty;
+ tty = uap->port.info->port.tty;
while (1) {
error = 0;
diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c
index d0e5a79ea63..22e30d21225 100644
--- a/drivers/serial/pnx8xxx_uart.c
+++ b/drivers/serial/pnx8xxx_uart.c
@@ -181,7 +181,7 @@ static void pnx8xxx_enable_ms(struct uart_port *port)
static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
{
- struct tty_struct *tty = sport->port.info->tty;
+ struct tty_struct *tty = sport->port.info->port.tty;
unsigned int status, ch, flg;
status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
@@ -824,7 +824,7 @@ static int __init pnx8xxx_serial_init(void)
{
int ret;
- printk(KERN_INFO "Serial: PNX8XXX driver $Revision: 1.2 $\n");
+ printk(KERN_INFO "Serial: PNX8XXX driver\n");
pnx8xxx_init_ports();
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b4f7ffb7688..b9a93f326fb 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -101,7 +101,7 @@ static void serial_pxa_stop_rx(struct uart_port *port)
static inline void receive_chars(struct uart_pxa_port *up, int *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned int ch, flag;
int max_count = 256;
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 62b38582f5e..a5e76cc1807 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -20,9 +20,6 @@
* 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
- *
- * $Id: sa1100.c,v 1.50 2002/07/29 14:41:04 rmk Exp $
- *
*/
#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -192,7 +189,7 @@ static void sa1100_enable_ms(struct uart_port *port)
static void
sa1100_rx_chars(struct sa1100_port *sport)
{
- struct tty_struct *tty = sport->port.info->tty;
+ struct tty_struct *tty = sport->port.info->port.tty;
unsigned int status, ch, flg;
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
@@ -892,7 +889,7 @@ static int __init sa1100_serial_init(void)
{
int ret;
- printk(KERN_INFO "Serial: SA11x0 driver $Revision: 1.50 $\n");
+ printk(KERN_INFO "Serial: SA11x0 driver\n");
sa1100_init_ports();
@@ -915,7 +912,7 @@ module_init(sa1100_serial_init);
module_exit(sa1100_serial_exit);
MODULE_AUTHOR("Deep Blue Solutions Ltd");
-MODULE_DESCRIPTION("SA1100 generic serial port driver $Revision: 1.50 $");
+MODULE_DESCRIPTION("SA1100 generic serial port driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_SA1100_MAJOR);
MODULE_ALIAS("platform:sa11x0-uart");
diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c
index f8e1447a022..a4fb343a08d 100644
--- a/drivers/serial/sb1250-duart.c
+++ b/drivers/serial/sb1250-duart.c
@@ -384,7 +384,7 @@ static void sbd_receive_chars(struct sbd_port *sport)
uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);
}
- tty_flip_buffer_push(uport->info->tty);
+ tty_flip_buffer_push(uport->info->port.tty);
}
static void sbd_transmit_chars(struct sbd_port *sport)
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
index ae2a9e2df77..e0be11ceaa2 100644
--- a/drivers/serial/sc26xx.c
+++ b/drivers/serial/sc26xx.c
@@ -141,7 +141,7 @@ static struct tty_struct *receive_chars(struct uart_port *port)
u8 status;
if (port->info != NULL) /* Unopened serial console */
- tty = port->info->tty;
+ tty = port->info->port.tty;
while (limit-- > 0) {
status = READ_SC_PORT(port, SR);
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 42d2e108b67..0bce1fe2c62 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -50,7 +50,7 @@ static struct lock_class_key port_lock_key;
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
+#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->port.blocked_open : 0))
#ifdef CONFIG_SERIAL_CORE_CONSOLE
#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
@@ -113,7 +113,7 @@ static void uart_start(struct tty_struct *tty)
static void uart_tasklet_action(unsigned long data)
{
struct uart_state *state = (struct uart_state *)data;
- tty_wakeup(state->info->tty);
+ tty_wakeup(state->info->port.tty);
}
static inline void
@@ -135,7 +135,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
/*
* Startup the port. This will be called once per open. All calls
- * will be serialised by the per-port semaphore.
+ * will be serialised by the per-port mutex.
*/
static int uart_startup(struct uart_state *state, int init_hw)
{
@@ -152,7 +152,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* once we have successfully opened the port. Also set
* up the tty->alt_speed kludge
*/
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
if (port->type == PORT_UNKNOWN)
return 0;
@@ -162,6 +162,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
* buffer.
*/
if (!info->xmit.buf) {
+ /* This is protected by the per port mutex */
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
@@ -182,20 +183,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
* Setup the RTS and DTR signals once the
* port is open and ready to respond.
*/
- if (info->tty->termios->c_cflag & CBAUD)
+ if (info->port.tty->termios->c_cflag & CBAUD)
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
}
if (info->flags & UIF_CTS_FLOW) {
spin_lock_irq(&port->lock);
if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
- info->tty->hw_stopped = 1;
+ info->port.tty->hw_stopped = 1;
spin_unlock_irq(&port->lock);
}
info->flags |= UIF_INITIALIZED;
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
}
if (retval && capable(CAP_SYS_ADMIN))
@@ -217,8 +218,8 @@ static void uart_shutdown(struct uart_state *state)
/*
* Set the TTY IO error marker
*/
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
if (info->flags & UIF_INITIALIZED) {
info->flags &= ~UIF_INITIALIZED;
@@ -226,7 +227,7 @@ static void uart_shutdown(struct uart_state *state)
/*
* Turn off DTR and RTS early.
*/
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
/*
@@ -426,7 +427,7 @@ EXPORT_SYMBOL(uart_get_divisor);
static void
uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
{
- struct tty_struct *tty = state->info->tty;
+ struct tty_struct *tty = state->info->port.tty;
struct uart_port *port = state->port;
struct ktermios *termios;
@@ -573,6 +574,8 @@ static void uart_flush_buffer(struct tty_struct *tty)
spin_lock_irqsave(&port->lock, flags);
uart_circ_clear(&state->info->xmit);
+ if (port->ops->flush_buffer)
+ port->ops->flush_buffer(port);
spin_unlock_irqrestore(&port->lock, flags);
tty_wakeup(tty);
}
@@ -834,8 +837,8 @@ static int uart_set_info(struct uart_state *state,
state->closing_wait = closing_wait;
if (new_serial.xmit_fifo_size)
port->fifosize = new_serial.xmit_fifo_size;
- if (state->info->tty)
- state->info->tty->low_latency =
+ if (state->info->port.tty)
+ state->info->port.tty->low_latency =
(port->flags & UPF_LOW_LATENCY) ? 1 : 0;
check_and_exit:
@@ -855,7 +858,7 @@ static int uart_set_info(struct uart_state *state,
printk(KERN_NOTICE
"%s sets custom speed on %s. This "
"is deprecated.\n", current->comm,
- tty_name(state->info->tty, buf));
+ tty_name(state->info->port.tty, buf));
}
uart_change_speed(state, NULL);
}
@@ -887,7 +890,7 @@ static int uart_get_lsr_info(struct uart_state *state,
*/
if (port->x_char ||
((uart_circ_chars_pending(&state->info->xmit) > 0) &&
- !state->info->tty->stopped && !state->info->tty->hw_stopped))
+ !state->info->port.tty->stopped && !state->info->port.tty->hw_stopped))
result &= ~TIOCSER_TEMT;
return put_user(result, value);
@@ -1237,7 +1240,7 @@ static void uart_set_termios(struct tty_struct *tty,
*/
if (!(old_termios->c_cflag & CLOCAL) &&
(tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&state->info->open_wait);
+ wake_up_interruptible(&state->info->port.open_wait);
#endif
}
@@ -1318,9 +1321,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
tty_ldisc_flush(tty);
tty->closing = 0;
- state->info->tty = NULL;
+ state->info->port.tty = NULL;
- if (state->info->blocked_open) {
+ if (state->info->port.blocked_open) {
if (state->close_delay)
msleep_interruptible(state->close_delay);
} else if (!uart_console(port)) {
@@ -1331,7 +1334,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* Wake up anyone trying to open this port.
*/
state->info->flags &= ~UIF_NORMAL_ACTIVE;
- wake_up_interruptible(&state->info->open_wait);
+ wake_up_interruptible(&state->info->port.open_wait);
done:
mutex_unlock(&state->mutex);
@@ -1415,8 +1418,8 @@ static void uart_hangup(struct tty_struct *tty)
uart_shutdown(state);
state->count = 0;
state->info->flags &= ~UIF_NORMAL_ACTIVE;
- state->info->tty = NULL;
- wake_up_interruptible(&state->info->open_wait);
+ state->info->port.tty = NULL;
+ wake_up_interruptible(&state->info->port.open_wait);
wake_up_interruptible(&state->info->delta_msr_wait);
}
mutex_unlock(&state->mutex);
@@ -1430,7 +1433,7 @@ static void uart_hangup(struct tty_struct *tty)
*/
static void uart_update_termios(struct uart_state *state)
{
- struct tty_struct *tty = state->info->tty;
+ struct tty_struct *tty = state->info->port.tty;
struct uart_port *port = state->port;
if (uart_console(port) && port->cons->cflag) {
@@ -1469,17 +1472,17 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
struct uart_port *port = state->port;
unsigned int mctrl;
- info->blocked_open++;
+ info->port.blocked_open++;
state->count--;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
/*
* If we have been hung up, tell userspace/restart open.
*/
- if (tty_hung_up_p(filp) || info->tty == NULL)
+ if (tty_hung_up_p(filp) || info->port.tty == NULL)
break;
/*
@@ -1498,8 +1501,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* have set TTY_IO_ERROR for a non-existant port.
*/
if ((filp->f_flags & O_NONBLOCK) ||
- (info->tty->termios->c_cflag & CLOCAL) ||
- (info->tty->flags & (1 << TTY_IO_ERROR)))
+ (info->port.tty->termios->c_cflag & CLOCAL) ||
+ (info->port.tty->flags & (1 << TTY_IO_ERROR)))
break;
/*
@@ -1507,7 +1510,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* not set RTS here - we want to make sure we catch
* the data from the modem.
*/
- if (info->tty->termios->c_cflag & CBAUD)
+ if (info->port.tty->termios->c_cflag & CBAUD)
uart_set_mctrl(port, TIOCM_DTR);
/*
@@ -1529,15 +1532,15 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
break;
}
set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
state->count++;
- info->blocked_open--;
+ info->port.blocked_open--;
if (signal_pending(current))
return -ERESTARTSYS;
- if (!info->tty || tty_hung_up_p(filp))
+ if (!info->port.tty || tty_hung_up_p(filp))
return -EAGAIN;
return 0;
@@ -1560,10 +1563,13 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
goto err_unlock;
}
+ /* BKL: RACE HERE - LEAK */
+ /* We should move this into the uart_state structure and kill off
+ this whole complexity */
if (!state->info) {
state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL);
if (state->info) {
- init_waitqueue_head(&state->info->open_wait);
+ init_waitqueue_head(&state->info->port.open_wait);
init_waitqueue_head(&state->info->delta_msr_wait);
/*
@@ -1620,7 +1626,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
* be re-entered while allocating the info structure, or while we
* request any IRQs that the driver may need. This also has the nice
* side-effect that it delays the action of uart_hangup, so we can
- * guarantee that info->tty will always contain something reasonable.
+ * guarantee that info->port.tty will always contain something reasonable.
*/
state = uart_get(drv, line);
if (IS_ERR(state)) {
@@ -1636,7 +1642,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = state;
tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
tty->alt_speed = 0;
- state->info->tty = tty;
+ state->info->port.tty = tty;
/*
* If the port is in the middle of closing, bail out now.
@@ -2099,8 +2105,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
/*
* If that's unset, use the tty termios setting.
*/
- if (state->info && state->info->tty && termios.c_cflag == 0)
- termios = *state->info->tty->termios;
+ if (state->info && state->info->port.tty && termios.c_cflag == 0)
+ termios = *state->info->port.tty->termios;
uart_change_pm(state, 0);
port->ops->set_termios(port, &termios, NULL);
@@ -2519,8 +2525,8 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
tty_unregister_device(drv->tty_driver, port->line);
info = state->info;
- if (info && info->tty)
- tty_vhangup(info->tty);
+ if (info && info->port.tty)
+ tty_vhangup(info->port.tty);
/*
* All users of this port should now be disconnected from
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index 8721afe1ae4..0edbc5dd378 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -108,7 +108,7 @@ static void ks8695uart_disable_ms(struct uart_port *port)
static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned int status, ch, lsr, flg, max_count = 256;
status = UART_GET_LSR(port); /* clears pending LSR interrupts */
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index eb18d429752..cb49a5ac022 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -137,7 +137,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port)
static void lh7a40xuart_rx_chars (struct uart_port* port)
{
- struct tty_struct* tty = port->info->tty;
+ struct tty_struct* tty = port->info->port.tty;
int cbRxMax = 256; /* (Gross) limit on receive */
unsigned int data; /* Received data and status */
unsigned int flag;
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index ce6ee92b3a1..208e42ba945 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -521,7 +521,7 @@ static void sci_transmit_chars(struct uart_port *port)
static inline void sci_receive_chars(struct uart_port *port)
{
struct sci_port *sci_port = (struct sci_port *)port;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
int i, count, copied = 0;
unsigned short status;
unsigned char flag;
@@ -642,7 +642,7 @@ static inline int sci_handle_errors(struct uart_port *port)
{
int copied = 0;
unsigned short status = sci_in(port, SCxSR);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
if (status & SCxSR_ORER(port)) {
/* overrun error */
@@ -692,7 +692,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
{
int copied = 0;
unsigned short status = sci_in(port, SCxSR);
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct sci_port *s = &sci_ports[port->line];
if (uart_handle_break(port))
@@ -762,7 +762,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
} else {
#if defined(SCIF_ORER)
if((sci_in(port, SCLSR) & SCIF_ORER) != 0) {
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
sci_out(port, SCLSR, 0);
tty_insert_flip_char(tty, 0, TTY_OVERRUN);
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 019da2e05f0..b73e3c0056c 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -471,7 +471,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
if (port->sc_port.info) {
/* The serial_core stuffs are initilized, use them */
- tty = port->sc_port.info->tty;
+ tty = port->sc_port.info->port.tty;
}
else {
/* Not registered yet - can't pass to tty layer. */
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 2847336742d..aeeec5588af 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -185,7 +185,7 @@ static struct tty_struct *receive_chars(struct uart_port *port)
struct tty_struct *tty = NULL;
if (port->info != NULL) /* Unopened serial console */
- tty = port->info->tty;
+ tty = port->info->port.tty;
if (sunhv_ops->receive_chars(port, tty))
sun_do_break();
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 9ff5b38f3be..15ee497e1c7 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -118,7 +118,7 @@ receive_chars(struct uart_sunsab_port *up,
int i;
if (up->port.info != NULL) /* Unopened serial console */
- tty = up->port.info->tty;
+ tty = up->port.info->port.tty;
/* Read number of BYTES (Character + Status) available. */
if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 03806a93520..e24e6823508 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.55 2002/01/08 16:00:16 davem Exp $
+/*
* su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -311,7 +311,7 @@ static void sunsu_enable_ms(struct uart_port *port)
static struct tty_struct *
receive_chars(struct uart_sunsu_port *up, unsigned char *status)
{
- struct tty_struct *tty = up->port.info->tty;
+ struct tty_struct *tty = up->port.info->port.tty;
unsigned char ch, flag;
int max_count = 256;
int saw_console_brk = 0;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 7e9fa5ef0eb..0f3d69b86d6 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -329,8 +329,8 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
tty = NULL;
if (up->port.info != NULL && /* Unopened serial console */
- up->port.info->tty != NULL) /* Keyboard || mouse */
- tty = up->port.info->tty;
+ up->port.info->port.tty != NULL) /* Keyboard || mouse */
+ tty = up->port.info->port.tty;
for (;;) {
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index b51c24245be..6a3f8fb0c9d 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -75,7 +75,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS];
static int ulite_receive(struct uart_port *port, int stat)
{
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
unsigned char ch = 0;
char flag = TTY_NORMAL;
@@ -162,7 +162,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
busy |= ulite_transmit(port, stat);
} while (busy);
- tty_flip_buffer_push(port->info->tty);
+ tty_flip_buffer_push(port->info->port.tty);
return IRQ_HANDLED;
}
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 566a8b42e05..5c5d18dcb6a 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -466,7 +466,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
int i;
unsigned char ch, *cp;
struct uart_port *port = &qe_port->port;
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = port->info->port.tty;
struct qe_bd *bdp;
u16 status;
unsigned int flg;
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c
index dd98aca6ed0..5acf061b6cd 100644
--- a/drivers/serial/v850e_uart.c
+++ b/drivers/serial/v850e_uart.c
@@ -300,8 +300,8 @@ static irqreturn_t v850e_uart_rx_irq(int irq, void *data)
port->icount.rx++;
- tty_insert_flip_char (port->info->tty, ch, ch_stat);
- tty_schedule_flip (port->info->tty);
+ tty_insert_flip_char (port->info->port.tty, ch, ch_stat);
+ tty_schedule_flip (port->info->port.tty);
return IRQ_HANDLED;
}
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index bb6ce6bba32..0573f3b5175 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -318,7 +318,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status)
char flag;
int max_count = RX_MAX_COUNT;
- tty = port->info->tty;
+ tty = port->info->port.tty;
lsr = *status;
do {
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c
index 65f1294fd27..bd45b6230fd 100644
--- a/drivers/serial/zs.c
+++ b/drivers/serial/zs.c
@@ -602,7 +602,7 @@ static void zs_receive_chars(struct zs_port *zport)
uart_insert_char(uport, status, Rx_OVR, ch, flag);
}
- tty_flip_buffer_push(uport->info->tty);
+ tty_flip_buffer_push(uport->info->port.tty);
}
static void zs_raw_transmit_chars(struct zs_port *zport)
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index cd845b8acd1..307b1f62d94 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -2,7 +2,7 @@ menu "Sonics Silicon Backplane"
config SSB_POSSIBLE
bool
- depends on HAS_IOMEM
+ depends on HAS_IOMEM && HAS_DMA
default y
config SSB
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index d184f2aea78..d831a2beff3 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -462,18 +462,15 @@ static int ssb_devices_register(struct ssb_bus *bus)
#ifdef CONFIG_SSB_PCIHOST
sdev->irq = bus->host_pci->irq;
dev->parent = &bus->host_pci->dev;
- sdev->dma_dev = &bus->host_pci->dev;
#endif
break;
case SSB_BUSTYPE_PCMCIA:
#ifdef CONFIG_SSB_PCMCIAHOST
sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
dev->parent = &bus->host_pcmcia->dev;
- sdev->dma_dev = &bus->host_pcmcia->dev;
#endif
break;
case SSB_BUSTYPE_SSB:
- sdev->dma_dev = dev;
break;
}
@@ -1156,36 +1153,82 @@ u32 ssb_dma_translation(struct ssb_device *dev)
{
switch (dev->bus->bustype) {
case SSB_BUSTYPE_SSB:
- case SSB_BUSTYPE_PCMCIA:
return 0;
case SSB_BUSTYPE_PCI:
return SSB_PCI_DMA;
+ default:
+ __ssb_dma_not_implemented(dev);
}
return 0;
}
EXPORT_SYMBOL(ssb_dma_translation);
-int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask)
+int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
{
- struct device *dma_dev = ssb_dev->dma_dev;
- int err = 0;
+ int err;
-#ifdef CONFIG_SSB_PCIHOST
- if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI) {
- err = pci_set_dma_mask(ssb_dev->bus->host_pci, mask);
+ switch (dev->bus->bustype) {
+ case SSB_BUSTYPE_PCI:
+ err = pci_set_dma_mask(dev->bus->host_pci, mask);
if (err)
return err;
- err = pci_set_consistent_dma_mask(ssb_dev->bus->host_pci, mask);
+ err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
return err;
+ case SSB_BUSTYPE_SSB:
+ return dma_set_mask(dev->dev, mask);
+ default:
+ __ssb_dma_not_implemented(dev);
}
-#endif
- dma_dev->coherent_dma_mask = mask;
- dma_dev->dma_mask = &dma_dev->coherent_dma_mask;
-
- return err;
+ return -ENOSYS;
}
EXPORT_SYMBOL(ssb_dma_set_mask);
+void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp_flags)
+{
+ switch (dev->bus->bustype) {
+ case SSB_BUSTYPE_PCI:
+ if (gfp_flags & GFP_DMA) {
+ /* Workaround: The PCI API does not support passing
+ * a GFP flag. */
+ return dma_alloc_coherent(&dev->bus->host_pci->dev,
+ size, dma_handle, gfp_flags);
+ }
+ return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
+ case SSB_BUSTYPE_SSB:
+ return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
+ default:
+ __ssb_dma_not_implemented(dev);
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(ssb_dma_alloc_consistent);
+
+void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle,
+ gfp_t gfp_flags)
+{
+ switch (dev->bus->bustype) {
+ case SSB_BUSTYPE_PCI:
+ if (gfp_flags & GFP_DMA) {
+ /* Workaround: The PCI API does not support passing
+ * a GFP flag. */
+ dma_free_coherent(&dev->bus->host_pci->dev,
+ size, vaddr, dma_handle);
+ return;
+ }
+ pci_free_consistent(dev->bus->host_pci, size,
+ vaddr, dma_handle);
+ return;
+ case SSB_BUSTYPE_SSB:
+ dma_free_coherent(dev->dev, size, vaddr, dma_handle);
+ return;
+ default:
+ __ssb_dma_not_implemented(dev);
+ }
+}
+EXPORT_SYMBOL(ssb_dma_free_consistent);
+
int ssb_bus_may_powerdown(struct ssb_bus *bus)
{
struct ssb_chipcommon *cc;
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 57c4ccfab1e..f883dcfffe0 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -510,17 +510,15 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
if (err) {
- /* check for rev 4 sprom - has special signature */
- if (buf[32] == 0x5372) {
- kfree(buf);
- buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
- GFP_KERNEL);
- if (!buf)
- goto out;
- bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
- sprom_do_read(bus, buf);
- err = sprom_check_crc(buf, bus->sprom_size);
- }
+ /* try for a 440 byte SPROM - revision 4 and higher */
+ kfree(buf);
+ buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
+ GFP_KERNEL);
+ if (!buf)
+ goto out;
+ bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
+ sprom_do_read(bus, buf);
+ err = sprom_check_crc(buf, bus->sprom_size);
if (err)
ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
" SPROM CRC (corrupt SPROM)\n");
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 05a328c11a8..45c154ade9c 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2383,6 +2383,9 @@ default_chipset:
goto amifb_error;
}
+ fb_videomode_to_modelist(ami_modedb, NUM_TOTAL_MODES,
+ &fb_info.modelist);
+
round_down_bpp = 0;
chipptr = chipalloc(fb_info.fix.smem_len+
SPRITEMEMSIZE+
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index dff35474b85..fa55d356b53 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -3110,7 +3110,7 @@ int __init atafb_init(void)
printk("atafb_init: start\n");
if (!MACH_IS_ATARI)
- return -ENXIO;
+ return -ENODEV;
do {
#ifdef ATAFB_EXT
@@ -3230,6 +3230,9 @@ int __init atafb_init(void)
return -EINVAL;
}
+ fb_videomode_to_modelist(atafb_modedb, NUM_TOTAL_MODES,
+ &fb_info.modelist);
+
atafb_set_disp(&fb_info);
fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);
diff --git a/drivers/video/c2p.c b/drivers/video/c2p.c
index 5c30bbd3305..376bc07ff95 100644
--- a/drivers/video/c2p.c
+++ b/drivers/video/c2p.c
@@ -12,6 +12,7 @@
* for more details.
*/
+#include <linux/module.h>
#include <linux/string.h>
#include "c2p.h"
@@ -226,4 +227,6 @@ void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
dst += dst_nextline;
}
}
+EXPORT_SYMBOL_GPL(c2p);
+MODULE_LICENSE("GPL");
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 099b6fb5b5c..d47c47fc048 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -1,6 +1,4 @@
/*
- * $Id: proc.c,v 1.1.2.1 1998/06/07 23:21:01 geert Exp $
- *
* Procfs interface for the Zorro bus.
*
* Copyright (C) 1998-2003 Geert Uytterhoeven
@@ -160,4 +158,4 @@ static int __init zorro_proc_init(void)
return 0;
}
-__initcall(zorro_proc_init);
+device_initcall(zorro_proc_init);
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 808b4f8675c..3da712cc770 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -15,6 +15,7 @@
#include <linux/zorro.h>
#include <linux/stat.h>
#include <linux/string.h>
+#include <linux/fs.h>
#include "zorro.h"
@@ -56,12 +57,6 @@ static ssize_t zorro_read_config(struct kobject *kobj,
struct zorro_dev *z = to_zorro_dev(container_of(kobj, struct device,
kobj));
struct ConfigDev cd;
- unsigned int size = sizeof(cd);
-
- if (off > size)
- return 0;
- if (off+count > size)
- count = size-off;
/* Construct a ConfigDev */
memset(&cd, 0, sizeof(cd));
@@ -71,8 +66,7 @@ static ssize_t zorro_read_config(struct kobject *kobj,
cd.cd_BoardAddr = (void *)zorro_resource_start(z);
cd.cd_BoardSize = zorro_resource_len(z);
- memcpy(buf, (void *)&cd+off, count);
- return count;
+ return memory_read_from_buffer(buf, count, &off, &cd, sizeof(cd));
}
static struct bin_attribute zorro_config_attr = {
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index 4cc42b64820..dff16d9767d 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -1,6 +1,4 @@
/*
- * $Id: zorro.c,v 1.1.2.1 1998/06/07 23:21:02 geert Exp $
- *
* Zorro Bus Services
*
* Copyright (C) 1995-2003 Geert Uytterhoeven
diff --git a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids
index 560fef2a7b1..0c0f99e2dd6 100644
--- a/drivers/zorro/zorro.ids
+++ b/drivers/zorro/zorro.ids
@@ -4,8 +4,6 @@
# Maintained by Geert Uytterhoeven <zorro@linux-m68k.org>
# If you have any new entries, please send them to the maintainer.
#
-# $Id: zorro.ids,v 1.19 2002/10/14 13:08:58 geert Exp $
-#
# Manufacturers and Products. Please keep sorted.